Fixed bug 4583 - PollAllValues appears to use an incorrect index for all axes above 0x18
Noam Preil
In src/joystick/linux/SDL_sysjoystick.c:
The ConfigJoystick function's axes detection starts with a for loop using an index i for Linux's axes names. When i gets to ABS_HAT0X, it's set to ABS_HAT3Y and a continue statement appears, to skip the hats. This makes sense, as SDL handles hats separately from axes.
However, in PollAllValues, *two* indices are used: a and b. Both start out the same, and remain so until the hats are reached. At that point, a becomes identical to the i from ConfigJoystick's loop, but b is equal to a - (ABS_HAT3Y - ABS_HAT0X), or a - 8.
While all the joystick->hwdata->abs_* structures in ConfigJoystick used i - which would here be a - as both the index and the ioctl argument, PollAllValues uses b for the structure index and a as the ioctl argument.
It would appear, however, that no joystick HAS such axes, and that the b index is entirely unnecessary.
I tested three separate joysticks, and while that was far from a complete listing, I was unable to find a joystick with an axis above 0x08.
1.1 --- a/src/joystick/linux/SDL_sysjoystick.c Sat Jun 08 14:36:03 2019 -0700
1.2 +++ b/src/joystick/linux/SDL_sysjoystick.c Sat Jun 08 14:40:27 2019 -0700
1.3 @@ -818,36 +818,26 @@
1.4 PollAllValues(SDL_Joystick * joystick)
1.5 {
1.6 struct input_absinfo absinfo;
1.7 - int a, b = 0;
1.8 + int i;
1.9
1.10 /* Poll all axis */
1.11 - for (a = ABS_X; b < ABS_MAX; a++) {
1.12 - switch (a) {
1.13 - case ABS_HAT0X:
1.14 - case ABS_HAT0Y:
1.15 - case ABS_HAT1X:
1.16 - case ABS_HAT1Y:
1.17 - case ABS_HAT2X:
1.18 - case ABS_HAT2Y:
1.19 - case ABS_HAT3X:
1.20 - case ABS_HAT3Y:
1.21 - /* ingore hats */
1.22 - break;
1.23 - default:
1.24 - if (joystick->hwdata->abs_correct[b].used) {
1.25 - if (ioctl(joystick->hwdata->fd, EVIOCGABS(a), &absinfo) >= 0) {
1.26 - absinfo.value = AxisCorrect(joystick, b, absinfo.value);
1.27 + for (i = ABS_X; i < ABS_MAX; i++) {
1.28 + if (i == ABS_HAT0X) {
1.29 + i = ABS_HAT3Y;
1.30 + continue;
1.31 + }
1.32 + if (joystick->hwdata->abs_correct[i].used) {
1.33 + if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
1.34 + absinfo.value = AxisCorrect(joystick, i, absinfo.value);
1.35
1.36 #ifdef DEBUG_INPUT_EVENTS
1.37 - printf("Joystick : Re-read Axis %d (%d) val= %d\n",
1.38 - joystick->hwdata->abs_map[b], a, absinfo.value);
1.39 + printf("Joystick : Re-read Axis %d (%d) val= %d\n",
1.40 + joystick->hwdata->abs_map[i], i, absinfo.value);
1.41 #endif
1.42 - SDL_PrivateJoystickAxis(joystick,
1.43 - joystick->hwdata->abs_map[b],
1.44 - absinfo.value);
1.45 - }
1.46 + SDL_PrivateJoystickAxis(joystick,
1.47 + joystick->hwdata->abs_map[i],
1.48 + absinfo.value);
1.49 }
1.50 - b++;
1.51 }
1.52 }
1.53 }