Fix for dropped joystick events contributed by Simon <simon@mungewell.org>
authorSam Lantinga <slouken@libsdl.org>
Mon, 11 Feb 2013 16:45:24 -0800
changeset 6844e09997fb33cc
parent 6843 a52016007a7e
child 6845 e14535915e3e
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.
src/joystick/linux/SDL_sysjoystick.c
src/joystick/linux/SDL_sysjoystick_c.h
     1.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Mon Feb 11 11:21:54 2013 -0800
     1.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Mon Feb 11 16:45:24 2013 -0800
     1.3 @@ -763,6 +763,9 @@
     1.4      /* Get the number of buttons and axes on the joystick */
     1.5      ConfigJoystick(joystick, fd);
     1.6  
     1.7 +    // mark joystick as fresh and ready
     1.8 +    joystick->hwdata->fresh = 1;
     1.9 +
    1.10      return (0);
    1.11  }
    1.12  
    1.13 @@ -834,12 +837,55 @@
    1.14  }
    1.15  
    1.16  static __inline__ void
    1.17 +PollAllValues(SDL_Joystick * joystick)
    1.18 +{
    1.19 +    struct input_absinfo absinfo;
    1.20 +    int a, b = 0;
    1.21 +
    1.22 +    // Poll all axis
    1.23 +    for (a = ABS_X; b < ABS_MAX; a++) {
    1.24 +        switch (a) {
    1.25 +        case ABS_HAT0X:
    1.26 +        case ABS_HAT0Y:
    1.27 +        case ABS_HAT1X:
    1.28 +        case ABS_HAT1Y:
    1.29 +        case ABS_HAT2X:
    1.30 +        case ABS_HAT2Y:
    1.31 +        case ABS_HAT3X:
    1.32 +        case ABS_HAT3Y:
    1.33 +            // ingore hats
    1.34 +            break;
    1.35 +        default:
    1.36 +            if (joystick->hwdata->abs_correct[b].used) {
    1.37 +                if (ioctl(joystick->hwdata->fd, EVIOCGABS(a), &absinfo) >= 0) {
    1.38 +                    absinfo.value = AxisCorrect(joystick, b, absinfo.value);
    1.39 +
    1.40 +#ifdef DEBUG_INPUT_EVENTS
    1.41 +                    printf("Joystick : Re-read Axis %d (%d) val= %d\n",
    1.42 +                        joystick->hwdata->abs_map[b], a, absinfo.value);
    1.43 +#endif
    1.44 +                    SDL_PrivateJoystickAxis(joystick,
    1.45 +                            joystick->hwdata->abs_map[b],
    1.46 +                            absinfo.value);
    1.47 +                }
    1.48 +            }
    1.49 +            b++;
    1.50 +        }
    1.51 +    }
    1.52 +}
    1.53 +
    1.54 +static __inline__ void
    1.55  HandleInputEvents(SDL_Joystick * joystick)
    1.56  {
    1.57      struct input_event events[32];
    1.58      int i, len;
    1.59      int code;
    1.60  
    1.61 +    if (joystick->hwdata->fresh) {
    1.62 +        PollAllValues(joystick);
    1.63 +        joystick->hwdata->fresh = 0;
    1.64 +    }
    1.65 +
    1.66      while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
    1.67          len /= sizeof(events[0]);
    1.68          for (i = 0; i < len; ++i) {
    1.69 @@ -890,6 +936,17 @@
    1.70                      break;
    1.71                  }
    1.72                  break;
    1.73 +            case EV_SYN:
    1.74 +                switch (code) {
    1.75 +                case SYN_DROPPED :
    1.76 +#ifdef DEBUG_INPUT_EVENTS
    1.77 +                    printf("Event SYN_DROPPED dectected\n");
    1.78 +#endif
    1.79 +                    PollAllValues(joystick);
    1.80 +                    break;
    1.81 +                default:
    1.82 +                    break;
    1.83 +                }
    1.84              default:
    1.85                  break;
    1.86              }
     2.1 --- a/src/joystick/linux/SDL_sysjoystick_c.h	Mon Feb 11 11:21:54 2013 -0800
     2.2 +++ b/src/joystick/linux/SDL_sysjoystick_c.h	Mon Feb 11 16:45:24 2013 -0800
     2.3 @@ -50,4 +50,8 @@
     2.4          int used;
     2.5          int coef[3];
     2.6      } abs_correct[ABS_MAX];
     2.7 +
     2.8 +    int fresh;
     2.9  };
    2.10 +
    2.11 +/* vi: set ts=4 sw=4 expandtab: */