diff --git a/README.md b/README.md index 921592f..294ab5d 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ # Usage -`poormansgamepad devicepath scale_axis scale_wheel deadzone` +`./poormansgamepad devicepath sensitivity_horizontal sensitivity_vertical sensitivity_wheel deadzone_horizontal deadzone_vertical deadzone_wheel drop_horizontal drop_vertical drop_wheel` -`devicepath` - Path to mouse device (/dev/input/eventX) - -`scale_axis` - Sensitivity for the virtual thumbstick - -`scale_wheel` - Sensitivity for the virtual trigger - -`deadzone` - Deadzone for the virtual thumbstick +`drop` - How fast axes get back into neutral position. diff --git a/src/gamepad.c b/src/gamepad.c index c934c59..7ed10ef 100644 --- a/src/gamepad.c +++ b/src/gamepad.c @@ -48,7 +48,7 @@ int setupaxis(int uinput, int code) { return ioctl(uinput, UI_ABS_SETUP, &axis); } -int setupgamepad() { +int setupgamepad(void) { struct uinput_setup usetup; int uinput = open("/dev/uinput", O_WRONLY | O_NONBLOCK); diff --git a/src/gamepad.h b/src/gamepad.h index dcde443..b8c11d2 100644 --- a/src/gamepad.h +++ b/src/gamepad.h @@ -1,3 +1,3 @@ void sendkey(int uinput, int code, int val); void sendaxis(int uinput, int code, int val); -int setupgamepad(); +int setupgamepad(void); diff --git a/src/main.c b/src/main.c index c5b4dfd..074be85 100644 --- a/src/main.c +++ b/src/main.c @@ -2,19 +2,29 @@ #include #include +#include +#include #include #include + #include #include "gamepad.h" #include "panic.h" -void waitmouse(int mouse, struct input_event* ie) { +int waitmouse(int mouse, struct input_event* ie) { while (1) { - read(mouse, ie, sizeof(struct input_event)); - if (ie->type != EV_SYN) - return; + struct pollfd fds[1]; + fds[0].fd = mouse; + fds[0].events = POLLIN; + poll(fds, 1, 0); + if (fds[0].revents & POLLIN) { + read(mouse, ie, sizeof(struct input_event)); + if (ie->type != EV_SYN) + return 1; + } else + return 0; } } @@ -46,19 +56,26 @@ int main(int argc, char* argv[]) { fprintf(stderr, "????\n"); return 255; } - if (argc != 5) { - printf("Usage: %s devicepath scale_axis scale_wheel deadzone\n", argv[0]); + if (argc != 11) { + printf("Usage: %s devicepath " + "sensitivity_horizontal sensitivity_vertical sensitivity_wheel " + "deadzone_horizontal deadzone_vertical deadzone_wheel " + "drop_horizontal drop_vertical drop_wheel\n", argv[0]); return 1; } struct input_event ie; int axis_x = 0; int axis_y = 0; int axis_w = 0; - int scale_axis = strtol(argv[2], NULL, 10); - int scale_wheel = strtol(argv[3], NULL, 10); - int deadzone = strtol(argv[3], NULL, 10); - int drop_axis = 0; - int drop_wheel = 0; + int scale_axis_x = strtol(argv[2], NULL, 10); + int scale_axis_y = strtol(argv[3], NULL, 10); + int scale_axis_w = strtol(argv[4], NULL, 10); + int deadzone_axis_x = strtol(argv[5], NULL, 10); + int deadzone_axis_y = strtol(argv[6], NULL, 10); + int deadzone_axis_w = strtol(argv[7], NULL, 10); + int drop_axis_x = strtol(argv[8], NULL, 10); + int drop_axis_y = strtol(argv[9], NULL, 10); + int drop_axis_w = strtol(argv[10], NULL, 10); char* device = argv[1]; int mouse = open(device, 0); @@ -67,20 +84,38 @@ int main(int argc, char* argv[]) { int gamepad = setupgamepad(); + struct timespec prev, current; + clock_gettime(CLOCK_MONOTONIC, &prev); while (1) { - waitmouse(mouse, &ie); - if (ie.type == EV_REL && ie.code == REL_X) - axis_x = drop(axis_x + ie.value * scale_axis, drop_axis); - if (ie.type == EV_REL && ie.code == REL_Y) - axis_y = drop(axis_y + ie.value * scale_axis, drop_axis); - if (ie.type == EV_REL && ie.code == REL_WHEEL) - axis_w = drop(axis_w + ie.value * scale_wheel, drop_wheel); - axis_x = clamp(axis_x); - axis_y = clamp(axis_y); - axis_w = clamp(axis_w); - sendaxis(gamepad, ABS_X, cut(axis_x, deadzone)); - sendaxis(gamepad, ABS_Y, cut(axis_y, deadzone)); - sendaxis(gamepad, ABS_HAT1X, axis_w); + clock_gettime(CLOCK_MONOTONIC, ¤t); + long delta = (current.tv_sec - prev.tv_sec) * 1000000000 + current.tv_nsec - prev.tv_nsec; + if (delta > 10000000) { + axis_x = drop(axis_x, drop_axis_x); + axis_y = drop(axis_y, drop_axis_y); + axis_w = drop(axis_w, drop_axis_w); + prev.tv_nsec = current.tv_nsec; + prev.tv_sec = current.tv_sec; + } + if (waitmouse(mouse, &ie)) { + if (ie.type == EV_REL) + switch (ie.code) { + case REL_X: + axis_x = axis_x + ie.value * scale_axis_x; + break; + case REL_Y: + axis_y = axis_y + ie.value * scale_axis_y; + break; + case REL_WHEEL: + axis_w = axis_w + ie.value * scale_axis_w; + break; + } + axis_x = clamp(axis_x); + axis_y = clamp(axis_y); + axis_w = clamp(axis_w); + } + sendaxis(gamepad, ABS_X, cut(axis_x, deadzone_axis_x)); + sendaxis(gamepad, ABS_Y, cut(axis_y, deadzone_axis_y)); + sendaxis(gamepad, ABS_HAT1X, cut(axis_w, deadzone_axis_w)); if (ie.type == EV_KEY && ie.code == BTN_LEFT) sendkey(gamepad, BTN_TL2, ie.value); if (ie.type == EV_KEY && ie.code == BTN_MIDDLE)