mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 17:44:25 +02:00
#15 Linux gamepads support
This commit is contained in:
@@ -875,7 +875,7 @@ static void init_get_bits(bitstream_t *s, const uint8_t *buffer, int bit_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static INLINE unsigned int get_bits(bitstream_t *s, int n){
|
static INLINE unsigned int get_bits(bitstream_t *s, int n){
|
||||||
register int tmp;
|
int tmp;
|
||||||
OPEN_READER(re, s)
|
OPEN_READER(re, s)
|
||||||
UPDATE_CACHE(re, s)
|
UPDATE_CACHE(re, s)
|
||||||
tmp= SHOW_UBITS(re, s, n);
|
tmp= SHOW_UBITS(re, s, n);
|
||||||
@@ -2000,8 +2000,8 @@ static void mp3_synth_filter(
|
|||||||
int32_t sb_samples[SBLIMIT]
|
int32_t sb_samples[SBLIMIT]
|
||||||
) {
|
) {
|
||||||
int32_t tmp[32];
|
int32_t tmp[32];
|
||||||
register int16_t *synth_buf;
|
int16_t *synth_buf;
|
||||||
register const int16_t *w, *w2, *p;
|
const int16_t *w, *w2, *p;
|
||||||
int j, offset, v;
|
int j, offset, v;
|
||||||
int16_t *samples2;
|
int16_t *samples2;
|
||||||
int sum, sum2;
|
int sum, sum2;
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <linux/joystick.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@@ -193,14 +195,119 @@ InputKey mouseToInputKey(int btn) {
|
|||||||
return ikNone;
|
return ikNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct JoyDevice {
|
||||||
|
int fd;
|
||||||
|
vec2 L, R;
|
||||||
|
} joyDevice[INPUT_JOY_COUNT];
|
||||||
|
|
||||||
bool osJoyReady(int index) {
|
bool osJoyReady(int index) {
|
||||||
return false;
|
return joyDevice[index].fd != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void osJoyVibrate(int index, float L, float R) {
|
void osJoyVibrate(int index, float L, float R) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void joyInit() {
|
||||||
|
LOG("init gamepads:\n");
|
||||||
|
char name[128];
|
||||||
|
for (int i = 0; i < INPUT_JOY_COUNT; i++) {
|
||||||
|
JoyDevice &joy = joyDevice[i];
|
||||||
|
// open device
|
||||||
|
sprintf(name, "/dev/input/js%d", i);
|
||||||
|
joy.fd = open(name, O_RDONLY | O_NONBLOCK);
|
||||||
|
if (joy.fd == -1)
|
||||||
|
continue;
|
||||||
|
// skip init messages
|
||||||
|
js_event event;
|
||||||
|
while (read(joy.fd, &event, sizeof(event)) != -1 && (event.type & JS_EVENT_INIT));
|
||||||
|
// get gamepad info
|
||||||
|
int8 axes, buttons;
|
||||||
|
ioctl(joy.fd, JSIOCGAXES, &axes);
|
||||||
|
ioctl(joy.fd, JSIOCGBUTTONS, &buttons);
|
||||||
|
|
||||||
|
if (axes < 4 || buttons < 11) { // is it really a gamepad?
|
||||||
|
close(joy.fd);
|
||||||
|
joy.fd = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(joy.fd, JSIOCGNAME(sizeof(name)), name) < 0)
|
||||||
|
strcpy(name, "Unknown");
|
||||||
|
|
||||||
|
LOG("gamepad %d\n", i);
|
||||||
|
LOG(" name : %s\n", name);
|
||||||
|
LOG(" btns : %d\n", int(buttons));
|
||||||
|
LOG(" axes : %d\n", int(axes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JOY_DEAD_ZONE_STICK 8192
|
||||||
|
#define JOY_DEAD_ZONE_TRIGGER 8192
|
||||||
|
|
||||||
|
float joyAxisValue(int value) {
|
||||||
|
if (value > -JOY_DEAD_ZONE_STICK && value < JOY_DEAD_ZONE_STICK)
|
||||||
|
return 0.0f;
|
||||||
|
return value / 32767.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float joyTrigger(int value) {
|
||||||
|
if (value + 32767 < JOY_DEAD_ZONE_TRIGGER)
|
||||||
|
return 0.0f;
|
||||||
|
return min(1.0f, (value + 32767) / 65536.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 joyDir(const vec2 &value) {
|
||||||
|
float dist = min(1.0f, value.length());
|
||||||
|
return value.normal() * dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void joyUpdate() {
|
||||||
|
static const JoyKey keys[] = { jkA, jkB, jkX, jkY, jkLB, jkRB, jkSelect, jkStart, jkNone /*jkHome*/, jkL, jkR };
|
||||||
|
|
||||||
|
for (int i = 0; i < INPUT_JOY_COUNT; i++) {
|
||||||
|
JoyDevice &joy = joyDevice[i];
|
||||||
|
|
||||||
|
if (joy.fd == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
js_event event;
|
||||||
|
while (read(joy.fd, &event, sizeof(event)) != -1) {
|
||||||
|
// buttons
|
||||||
|
if (event.type & JS_EVENT_BUTTON)
|
||||||
|
Input::setJoyDown(i, event.number >= COUNT(keys) ? jkNone : keys[event.number], event.value == 1);
|
||||||
|
// axes
|
||||||
|
if (event.type & JS_EVENT_AXIS) {
|
||||||
|
|
||||||
|
switch (event.number) {
|
||||||
|
// Left stick
|
||||||
|
case 0 : joy.L.x = joyAxisValue(event.value); break;
|
||||||
|
case 1 : joy.L.y = joyAxisValue(event.value); break;
|
||||||
|
// Right stick
|
||||||
|
case 3 : joy.R.x = joyAxisValue(event.value); break;
|
||||||
|
case 4 : joy.R.y = joyAxisValue(event.value); break;
|
||||||
|
// Left trigger
|
||||||
|
case 2 : Input::setJoyPos(i, jkLT, joyTrigger(event.value)); break;
|
||||||
|
// Right trigger
|
||||||
|
case 5 : Input::setJoyPos(i, jkRT, joyTrigger(event.value)); break;
|
||||||
|
// D-PAD
|
||||||
|
case 6 :
|
||||||
|
Input::setJoyDown(i, jkLeft, event.value < -0x4000);
|
||||||
|
Input::setJoyDown(i, jkRight, event.value > 0x4000);
|
||||||
|
break;
|
||||||
|
case 7 :
|
||||||
|
Input::setJoyDown(i, jkUp, event.value < -0x4000);
|
||||||
|
Input::setJoyDown(i, jkDown, event.value > 0x4000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input::setJoyPos(i, jkL, joyDir(joy.L));
|
||||||
|
Input::setJoyPos(i, jkR, joyDir(joy.R));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void toggle_fullscreen(Display* dpy, Window win) {
|
void toggle_fullscreen(Display* dpy, Window win) {
|
||||||
const size_t _NET_WM_STATE_TOGGLE=2;
|
const size_t _NET_WM_STATE_TOGGLE=2;
|
||||||
|
|
||||||
@@ -296,6 +403,8 @@ int main(int argc, char **argv) {
|
|||||||
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", 0);
|
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", 0);
|
||||||
XSetWMProtocols(dpy, wnd, &WM_DELETE_WINDOW, 1);
|
XSetWMProtocols(dpy, wnd, &WM_DELETE_WINDOW, 1);
|
||||||
|
|
||||||
|
joyInit();
|
||||||
|
|
||||||
timeval t;
|
timeval t;
|
||||||
gettimeofday(&t, NULL);
|
gettimeofday(&t, NULL);
|
||||||
startTime = t.tv_sec;
|
startTime = t.tv_sec;
|
||||||
@@ -311,6 +420,7 @@ int main(int argc, char **argv) {
|
|||||||
Core::quit();
|
Core::quit();
|
||||||
WndProc(event,dpy,wnd);
|
WndProc(event,dpy,wnd);
|
||||||
} else {
|
} else {
|
||||||
|
joyUpdate();
|
||||||
bool updated = Game::update();
|
bool updated = Game::update();
|
||||||
if (updated) {
|
if (updated) {
|
||||||
Game::render();
|
Game::render();
|
||||||
|
Reference in New Issue
Block a user