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.
This commit is contained in:
Sam Lantinga 2013-02-11 16:45:24 -08:00
parent b73214bd02
commit 7b84e779ec
2 changed files with 61 additions and 0 deletions

View file

@ -763,6 +763,9 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
/* Get the number of buttons and axes on the joystick */ /* Get the number of buttons and axes on the joystick */
ConfigJoystick(joystick, fd); ConfigJoystick(joystick, fd);
// mark joystick as fresh and ready
joystick->hwdata->fresh = 1;
return (0); return (0);
} }
@ -833,6 +836,44 @@ AxisCorrect(SDL_Joystick * joystick, int which, int value)
return value; return value;
} }
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 static __inline__ void
HandleInputEvents(SDL_Joystick * joystick) HandleInputEvents(SDL_Joystick * joystick)
{ {
@ -840,6 +881,11 @@ HandleInputEvents(SDL_Joystick * joystick)
int i, len; int i, len;
int code; int code;
if (joystick->hwdata->fresh) {
PollAllValues(joystick);
joystick->hwdata->fresh = 0;
}
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) { while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
len /= sizeof(events[0]); len /= sizeof(events[0]);
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
@ -890,6 +936,17 @@ HandleInputEvents(SDL_Joystick * joystick)
break; break;
} }
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: default:
break; break;
} }

View file

@ -50,4 +50,8 @@ struct joystick_hwdata
int used; int used;
int coef[3]; int coef[3];
} abs_correct[ABS_MAX]; } abs_correct[ABS_MAX];
int fresh;
}; };
/* vi: set ts=4 sw=4 expandtab: */