Fix for dropped joystick events contributed by Simon <simon@mungewell.org>
In my system SDL2 is dropping a chunk of joystick events, which result in
a 'stuck brake/accelerator' whilst playing a racing simulator. This
basically means SDL2 is unsuitable for use at this point...
The patch below detects this situation and forces a re-read of all
attached joystick axis - thus resync to the correct/current pedal
positions.
--- a/src/joystick/linux/SDL_sysjoystick.c Mon Feb 11 11:21:54 2013 -0800
+++ b/src/joystick/linux/SDL_sysjoystick.c Mon Feb 11 16:45:24 2013 -0800
@@ -763,6 +763,9 @@
/* Get the number of buttons and axes on the joystick */
ConfigJoystick(joystick, fd);
+ // mark joystick as fresh and ready
+ joystick->hwdata->fresh = 1;
+
return (0);
}
@@ -834,12 +837,55 @@
}
static __inline__ void
+PollAllValues(SDL_Joystick * joystick)
+{
+ struct input_absinfo absinfo;
+ int a, b = 0;
+
+ // Poll all axis
+ for (a = ABS_X; b < ABS_MAX; a++) {
+ switch (a) {
+ case ABS_HAT0X:
+ case ABS_HAT0Y:
+ case ABS_HAT1X:
+ case ABS_HAT1Y:
+ case ABS_HAT2X:
+ case ABS_HAT2Y:
+ case ABS_HAT3X:
+ case ABS_HAT3Y:
+ // ingore hats
+ break;
+ default:
+ if (joystick->hwdata->abs_correct[b].used) {
+ if (ioctl(joystick->hwdata->fd, EVIOCGABS(a), &absinfo) >= 0) {
+ absinfo.value = AxisCorrect(joystick, b, absinfo.value);
+
+#ifdef DEBUG_INPUT_EVENTS
+ printf("Joystick : Re-read Axis %d (%d) val= %d\n",
+ joystick->hwdata->abs_map[b], a, absinfo.value);
+#endif
+ SDL_PrivateJoystickAxis(joystick,
+ joystick->hwdata->abs_map[b],
+ absinfo.value);
+ }
+ }
+ b++;
+ }
+ }
+}
+
+static __inline__ void
HandleInputEvents(SDL_Joystick * joystick)
{
struct input_event events[32];
int i, len;
int code;
+ if (joystick->hwdata->fresh) {
+ PollAllValues(joystick);
+ joystick->hwdata->fresh = 0;
+ }
+
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
len /= sizeof(events[0]);
for (i = 0; i < len; ++i) {
@@ -890,6 +936,17 @@
break;
}
break;
+ case EV_SYN:
+ switch (code) {
+ case SYN_DROPPED :
+#ifdef DEBUG_INPUT_EVENTS
+ printf("Event SYN_DROPPED dectected\n");
+#endif
+ PollAllValues(joystick);
+ break;
+ default:
+ break;
+ }
default:
break;
}
--- a/src/joystick/linux/SDL_sysjoystick_c.h Mon Feb 11 11:21:54 2013 -0800
+++ b/src/joystick/linux/SDL_sysjoystick_c.h Mon Feb 11 16:45:24 2013 -0800
@@ -50,4 +50,8 @@
int used;
int coef[3];
} abs_correct[ABS_MAX];
+
+ int fresh;
};
+
+/* vi: set ts=4 sw=4 expandtab: */