SDL Changes to support clean reads
authorSam Lantinga <slouken@libsdl.org>
Mon, 05 Feb 2018 11:40:39 -0800
changeset 11843bbe75e4fc57e
parent 11842 9577835e5809
child 11844 8e2ca40e07f3
SDL Changes to support clean reads
CR: saml
src/joystick/darwin/SDL_sysjoystick.c
     1.1 --- a/src/joystick/darwin/SDL_sysjoystick.c	Thu Feb 01 15:46:51 2018 -0800
     1.2 +++ b/src/joystick/darwin/SDL_sysjoystick.c	Mon Feb 05 11:40:39 2018 -0800
     1.3 @@ -105,10 +105,11 @@
     1.4      return pDeviceNext;
     1.5  }
     1.6  
     1.7 -static SInt32
     1.8 -GetHIDElementState(recDevice *pDevice, recElement *pElement)
     1.9 +static SDL_bool
    1.10 +GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue)
    1.11  {
    1.12      SInt32 value = 0;
    1.13 +    int returnValue = SDL_FALSE;
    1.14  
    1.15      if (pDevice && pElement) {
    1.16          IOHIDValueRef valueRef;
    1.17 @@ -122,25 +123,34 @@
    1.18              if (value > pElement->maxReport) {
    1.19                  pElement->maxReport = value;
    1.20              }
    1.21 +            *pValue = value;
    1.22 +
    1.23 +            returnValue = SDL_TRUE;
    1.24          }
    1.25      }
    1.26 -
    1.27 -    return value;
    1.28 +    return returnValue;
    1.29  }
    1.30  
    1.31 -static SInt32
    1.32 -GetHIDScaledCalibratedState(recDevice * pDevice, recElement * pElement, SInt32 min, SInt32 max)
    1.33 +static SDL_bool
    1.34 +GetHIDScaledCalibratedState(recDevice * pDevice, recElement * pElement, SInt32 min, SInt32 max, SInt32 *pValue)
    1.35  {
    1.36      const float deviceScale = max - min;
    1.37      const float readScale = pElement->maxReport - pElement->minReport;
    1.38 -    const SInt32 value = GetHIDElementState(pDevice, pElement);
    1.39 -    if (readScale == 0) {
    1.40 -        return value;           /* no scaling at all */
    1.41 -    }
    1.42 -    return ((value - pElement->minReport) * deviceScale / readScale) + min;
    1.43 +    int returnValue = SDL_FALSE;
    1.44 +    if (GetHIDElementState(pDevice, pElement, pValue))
    1.45 +    {
    1.46 +        if (readScale == 0) {
    1.47 +            returnValue = SDL_TRUE;           /* no scaling at all */
    1.48 +        }
    1.49 +        else
    1.50 +        {
    1.51 +            *pValue = ((*pValue - pElement->minReport) * deviceScale / readScale) + min;
    1.52 +            returnValue = SDL_TRUE;
    1.53 +        }
    1.54 +    } 
    1.55 +    return returnValue;
    1.56  }
    1.57  
    1.58 -
    1.59  static void
    1.60  JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
    1.61  {
    1.62 @@ -698,9 +708,14 @@
    1.63  
    1.64      element = device->firstAxis;
    1.65      i = 0;
    1.66 +
    1.67 +    int goodRead = SDL_FALSE;
    1.68      while (element) {
    1.69 -        value = GetHIDScaledCalibratedState(device, element, -32768, 32767);
    1.70 -        SDL_PrivateJoystickAxis(joystick, i, value);
    1.71 +        goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
    1.72 +        if (goodRead) {
    1.73 +            SDL_PrivateJoystickAxis(joystick, i, value);
    1.74 +        }
    1.75 +
    1.76          element = element->pNext;
    1.77          ++i;
    1.78      }
    1.79 @@ -708,63 +723,70 @@
    1.80      element = device->firstButton;
    1.81      i = 0;
    1.82      while (element) {
    1.83 -        value = GetHIDElementState(device, element);
    1.84 -        if (value > 1) {          /* handle pressure-sensitive buttons */
    1.85 -            value = 1;
    1.86 +        goodRead = GetHIDElementState(device, element, &value);
    1.87 +        if (goodRead) {
    1.88 +            if (value > 1) {          /* handle pressure-sensitive buttons */
    1.89 +                value = 1;
    1.90 +            }
    1.91 +            SDL_PrivateJoystickButton(joystick, i, value);
    1.92          }
    1.93 -        SDL_PrivateJoystickButton(joystick, i, value);
    1.94 +
    1.95          element = element->pNext;
    1.96          ++i;
    1.97      }
    1.98  
    1.99      element = device->firstHat;
   1.100      i = 0;
   1.101 +    
   1.102      while (element) {
   1.103          Uint8 pos = 0;
   1.104  
   1.105          range = (element->max - element->min + 1);
   1.106 -        value = GetHIDElementState(device, element) - element->min;
   1.107 -        if (range == 4) {         /* 4 position hatswitch - scale up value */
   1.108 -            value *= 2;
   1.109 -        } else if (range != 8) {    /* Neither a 4 nor 8 positions - fall back to default position (centered) */
   1.110 -            value = -1;
   1.111 +        goodRead = GetHIDElementState(device, element, &value);
   1.112 +        if (goodRead) {
   1.113 +            value -= element->min;
   1.114 +            if (range == 4) {         /* 4 position hatswitch - scale up value */
   1.115 +                value *= 2;
   1.116 +            } else if (range != 8) {    /* Neither a 4 nor 8 positions - fall back to default position (centered) */
   1.117 +                value = -1;
   1.118 +            }
   1.119 +            switch (value) {
   1.120 +            case 0:
   1.121 +                pos = SDL_HAT_UP;
   1.122 +                break;
   1.123 +            case 1:
   1.124 +                pos = SDL_HAT_RIGHTUP;
   1.125 +                break;
   1.126 +            case 2:
   1.127 +                pos = SDL_HAT_RIGHT;
   1.128 +                break;
   1.129 +            case 3:
   1.130 +                pos = SDL_HAT_RIGHTDOWN;
   1.131 +                break;
   1.132 +            case 4:
   1.133 +                pos = SDL_HAT_DOWN;
   1.134 +                break;
   1.135 +            case 5:
   1.136 +                pos = SDL_HAT_LEFTDOWN;
   1.137 +                break;
   1.138 +            case 6:
   1.139 +                pos = SDL_HAT_LEFT;
   1.140 +                break;
   1.141 +            case 7:
   1.142 +                pos = SDL_HAT_LEFTUP;
   1.143 +                break;
   1.144 +            default:
   1.145 +                /* Every other value is mapped to center. We do that because some
   1.146 +                 * joysticks use 8 and some 15 for this value, and apparently
   1.147 +                 * there are even more variants out there - so we try to be generous.
   1.148 +                 */
   1.149 +                pos = SDL_HAT_CENTERED;
   1.150 +                break;
   1.151 +            }
   1.152 +
   1.153 +            SDL_PrivateJoystickHat(joystick, i, pos);
   1.154          }
   1.155 -        switch (value) {
   1.156 -        case 0:
   1.157 -            pos = SDL_HAT_UP;
   1.158 -            break;
   1.159 -        case 1:
   1.160 -            pos = SDL_HAT_RIGHTUP;
   1.161 -            break;
   1.162 -        case 2:
   1.163 -            pos = SDL_HAT_RIGHT;
   1.164 -            break;
   1.165 -        case 3:
   1.166 -            pos = SDL_HAT_RIGHTDOWN;
   1.167 -            break;
   1.168 -        case 4:
   1.169 -            pos = SDL_HAT_DOWN;
   1.170 -            break;
   1.171 -        case 5:
   1.172 -            pos = SDL_HAT_LEFTDOWN;
   1.173 -            break;
   1.174 -        case 6:
   1.175 -            pos = SDL_HAT_LEFT;
   1.176 -            break;
   1.177 -        case 7:
   1.178 -            pos = SDL_HAT_LEFTUP;
   1.179 -            break;
   1.180 -        default:
   1.181 -            /* Every other value is mapped to center. We do that because some
   1.182 -             * joysticks use 8 and some 15 for this value, and apparently
   1.183 -             * there are even more variants out there - so we try to be generous.
   1.184 -             */
   1.185 -            pos = SDL_HAT_CENTERED;
   1.186 -            break;
   1.187 -        }
   1.188 -
   1.189 -        SDL_PrivateJoystickHat(joystick, i, pos);
   1.190 -
   1.191 +        
   1.192          element = element->pNext;
   1.193          ++i;
   1.194      }