Fixed mapping controllers that have axes that start at -32768 and then snap to 0 at the first input report
authorSam Lantinga <slouken@libsdl.org>
Thu, 28 Nov 2019 11:44:15 -0800
changeset 13302e66b77697cd4
parent 13301 1953486198ee
child 13303 d157196c9c35
Fixed mapping controllers that have axes that start at -32768 and then snap to 0 at the first input report
src/joystick/SDL_joystick.c
src/joystick/SDL_sysjoystick.h
test/controllermap.c
     1.1 --- a/src/joystick/SDL_joystick.c	Thu Nov 28 10:04:05 2019 -0800
     1.2 +++ b/src/joystick/SDL_joystick.c	Thu Nov 28 11:44:15 2019 -0800
     1.3 @@ -833,43 +833,49 @@
     1.4  SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
     1.5  {
     1.6      int posted;
     1.7 +    SDL_JoystickAxisInfo *info;
     1.8  
     1.9      /* Make sure we're not getting garbage or duplicate events */
    1.10      if (axis >= joystick->naxes) {
    1.11          return 0;
    1.12      }
    1.13 -    if (!joystick->axes[axis].has_initial_value) {
    1.14 -        joystick->axes[axis].initial_value = value;
    1.15 -        joystick->axes[axis].value = value;
    1.16 -        joystick->axes[axis].zero = value;
    1.17 -        joystick->axes[axis].has_initial_value = SDL_TRUE;
    1.18 +
    1.19 +    info = &joystick->axes[axis];
    1.20 +    if (!info->has_initial_value ||
    1.21 +        (!info->has_second_value && info->initial_value == -32768 && value == 0)) {
    1.22 +        info->initial_value = value;
    1.23 +        info->value = value;
    1.24 +        info->zero = value;
    1.25 +        info->has_initial_value = SDL_TRUE;
    1.26 +    } else {
    1.27 +        info->has_second_value = SDL_TRUE;
    1.28      }
    1.29 -    if (value == joystick->axes[axis].value) {
    1.30 +    if (value == info->value) {
    1.31          return 0;
    1.32      }
    1.33 -    if (!joystick->axes[axis].sent_initial_value) {
    1.34 +    if (!info->sent_initial_value) {
    1.35          /* Make sure we don't send motion until there's real activity on this axis */
    1.36          const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80;  /* ShanWan PS3 controller needed 96 */
    1.37 -        if (SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) {
    1.38 +        if (SDL_abs(value - info->value) <= MAX_ALLOWED_JITTER) {
    1.39              return 0;
    1.40          }
    1.41 -        joystick->axes[axis].sent_initial_value = SDL_TRUE;
    1.42 -        joystick->axes[axis].value = value; /* Just so we pass the check above */
    1.43 -        SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value);
    1.44 +        info->sent_initial_value = SDL_TRUE;
    1.45 +        info->value = value; /* Just so we pass the check above */
    1.46 +        SDL_PrivateJoystickAxis(joystick, axis, info->initial_value);
    1.47      }
    1.48  
    1.49      /* We ignore events if we don't have keyboard focus, except for centering
    1.50       * events.
    1.51       */
    1.52      if (SDL_PrivateJoystickShouldIgnoreEvent()) {
    1.53 -        if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].value) ||
    1.54 -            (value < joystick->axes[axis].zero && value <= joystick->axes[axis].value)) {
    1.55 +        if ((value > info->zero && value >= info->value) ||
    1.56 +            (value < info->zero && value <= info->value)) {
    1.57              return 0;
    1.58          }
    1.59      }
    1.60  
    1.61      /* Update internal joystick state */
    1.62 -    joystick->axes[axis].value = value;
    1.63 +    info->value = value;
    1.64  
    1.65      /* Post the event, if desired */
    1.66      posted = 0;
     2.1 --- a/src/joystick/SDL_sysjoystick.h	Thu Nov 28 10:04:05 2019 -0800
     2.2 +++ b/src/joystick/SDL_sysjoystick.h	Thu Nov 28 11:44:15 2019 -0800
     2.3 @@ -35,6 +35,7 @@
     2.4      Sint16 value;               /* Current axis state */
     2.5      Sint16 zero;                /* Zero point on the axis (-32768 for triggers) */
     2.6      SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */
     2.7 +    SDL_bool has_second_value;  /* Whether we've seen a second value on the axis yet */
     2.8      SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */
     2.9  } SDL_JoystickAxisInfo;
    2.10  
     3.1 --- a/test/controllermap.c	Thu Nov 28 10:04:05 2019 -0800
     3.2 +++ b/test/controllermap.c	Thu Nov 28 11:44:15 2019 -0800
     3.3 @@ -413,13 +413,6 @@
     3.4  
     3.5      s_nNumAxes = SDL_JoystickNumAxes(joystick);
     3.6      s_arrAxisState = (AxisState *)SDL_calloc(s_nNumAxes, sizeof(*s_arrAxisState));
     3.7 -    for (iIndex = 0; iIndex < s_nNumAxes; ++iIndex) {
     3.8 -        AxisState *pAxisState = &s_arrAxisState[iIndex];
     3.9 -        Sint16 nInitialValue;
    3.10 -        pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, iIndex, &nInitialValue);
    3.11 -        pAxisState->m_nStartingValue = nInitialValue;
    3.12 -        pAxisState->m_nFarthestValue = nInitialValue;
    3.13 -    }
    3.14  
    3.15      /* Loop, getting joystick events! */
    3.16      while (!done && !s_bBindingComplete) {
    3.17 @@ -472,9 +465,10 @@
    3.18                      int nValue = event.jaxis.value;
    3.19                      int nCurrentDistance, nFarthestDistance;
    3.20                      if (!pAxisState->m_bMoving) {
    3.21 -                        pAxisState->m_bMoving = SDL_TRUE;
    3.22 -                        pAxisState->m_nStartingValue = nValue;
    3.23 -                        pAxisState->m_nFarthestValue = nValue;
    3.24 +                        Sint16 nInitialValue;
    3.25 +                        pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, event.jaxis.axis, &nInitialValue);
    3.26 +                        pAxisState->m_nStartingValue = nInitialValue;
    3.27 +                        pAxisState->m_nFarthestValue = nInitialValue;
    3.28                      }
    3.29                      nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue);
    3.30                      nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);