Commit 2b441ec6c4d3a04462455149644b1f46cf3af3a6

Sam Lantinga 2018-02-05T11:40:39

SDL Changes to support clean reads CR: saml

diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c
index 46f6e8c..abfb1c6 100644
--- a/src/joystick/darwin/SDL_sysjoystick.c
+++ b/src/joystick/darwin/SDL_sysjoystick.c
@@ -105,10 +105,11 @@ FreeDevice(recDevice *removeDevice)
     return pDeviceNext;
 }
 
-static SInt32
-GetHIDElementState(recDevice *pDevice, recElement *pElement)
+static SDL_bool
+GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue)
 {
     SInt32 value = 0;
+    int returnValue = SDL_FALSE;
 
     if (pDevice && pElement) {
         IOHIDValueRef valueRef;
@@ -122,25 +123,34 @@ GetHIDElementState(recDevice *pDevice, recElement *pElement)
             if (value > pElement->maxReport) {
                 pElement->maxReport = value;
             }
+            *pValue = value;
+
+            returnValue = SDL_TRUE;
         }
     }
-
-    return value;
+    return returnValue;
 }
 
-static SInt32
-GetHIDScaledCalibratedState(recDevice * pDevice, recElement * pElement, SInt32 min, SInt32 max)
+static SDL_bool
+GetHIDScaledCalibratedState(recDevice * pDevice, recElement * pElement, SInt32 min, SInt32 max, SInt32 *pValue)
 {
     const float deviceScale = max - min;
     const float readScale = pElement->maxReport - pElement->minReport;
-    const SInt32 value = GetHIDElementState(pDevice, pElement);
-    if (readScale == 0) {
-        return value;           /* no scaling at all */
-    }
-    return ((value - pElement->minReport) * deviceScale / readScale) + min;
+    int returnValue = SDL_FALSE;
+    if (GetHIDElementState(pDevice, pElement, pValue))
+    {
+        if (readScale == 0) {
+            returnValue = SDL_TRUE;           /* no scaling at all */
+        }
+        else
+        {
+            *pValue = ((*pValue - pElement->minReport) * deviceScale / readScale) + min;
+            returnValue = SDL_TRUE;
+        }
+    } 
+    return returnValue;
 }
 
-
 static void
 JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
 {
@@ -698,9 +708,14 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
 
     element = device->firstAxis;
     i = 0;
+
+    int goodRead = SDL_FALSE;
     while (element) {
-        value = GetHIDScaledCalibratedState(device, element, -32768, 32767);
-        SDL_PrivateJoystickAxis(joystick, i, value);
+        goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
+        if (goodRead) {
+            SDL_PrivateJoystickAxis(joystick, i, value);
+        }
+
         element = element->pNext;
         ++i;
     }
@@ -708,63 +723,70 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
     element = device->firstButton;
     i = 0;
     while (element) {
-        value = GetHIDElementState(device, element);
-        if (value > 1) {          /* handle pressure-sensitive buttons */
-            value = 1;
+        goodRead = GetHIDElementState(device, element, &value);
+        if (goodRead) {
+            if (value > 1) {          /* handle pressure-sensitive buttons */
+                value = 1;
+            }
+            SDL_PrivateJoystickButton(joystick, i, value);
         }
-        SDL_PrivateJoystickButton(joystick, i, value);
+
         element = element->pNext;
         ++i;
     }
 
     element = device->firstHat;
     i = 0;
+    
     while (element) {
         Uint8 pos = 0;
 
         range = (element->max - element->min + 1);
-        value = GetHIDElementState(device, element) - element->min;
-        if (range == 4) {         /* 4 position hatswitch - scale up value */
-            value *= 2;
-        } else if (range != 8) {    /* Neither a 4 nor 8 positions - fall back to default position (centered) */
-            value = -1;
-        }
-        switch (value) {
-        case 0:
-            pos = SDL_HAT_UP;
-            break;
-        case 1:
-            pos = SDL_HAT_RIGHTUP;
-            break;
-        case 2:
-            pos = SDL_HAT_RIGHT;
-            break;
-        case 3:
-            pos = SDL_HAT_RIGHTDOWN;
-            break;
-        case 4:
-            pos = SDL_HAT_DOWN;
-            break;
-        case 5:
-            pos = SDL_HAT_LEFTDOWN;
-            break;
-        case 6:
-            pos = SDL_HAT_LEFT;
-            break;
-        case 7:
-            pos = SDL_HAT_LEFTUP;
-            break;
-        default:
-            /* Every other value is mapped to center. We do that because some
-             * joysticks use 8 and some 15 for this value, and apparently
-             * there are even more variants out there - so we try to be generous.
-             */
-            pos = SDL_HAT_CENTERED;
-            break;
-        }
-
-        SDL_PrivateJoystickHat(joystick, i, pos);
+        goodRead = GetHIDElementState(device, element, &value);
+        if (goodRead) {
+            value -= element->min;
+            if (range == 4) {         /* 4 position hatswitch - scale up value */
+                value *= 2;
+            } else if (range != 8) {    /* Neither a 4 nor 8 positions - fall back to default position (centered) */
+                value = -1;
+            }
+            switch (value) {
+            case 0:
+                pos = SDL_HAT_UP;
+                break;
+            case 1:
+                pos = SDL_HAT_RIGHTUP;
+                break;
+            case 2:
+                pos = SDL_HAT_RIGHT;
+                break;
+            case 3:
+                pos = SDL_HAT_RIGHTDOWN;
+                break;
+            case 4:
+                pos = SDL_HAT_DOWN;
+                break;
+            case 5:
+                pos = SDL_HAT_LEFTDOWN;
+                break;
+            case 6:
+                pos = SDL_HAT_LEFT;
+                break;
+            case 7:
+                pos = SDL_HAT_LEFTUP;
+                break;
+            default:
+                /* Every other value is mapped to center. We do that because some
+                 * joysticks use 8 and some 15 for this value, and apparently
+                 * there are even more variants out there - so we try to be generous.
+                 */
+                pos = SDL_HAT_CENTERED;
+                break;
+            }
 
+            SDL_PrivateJoystickHat(joystick, i, pos);
+        }
+        
         element = element->pNext;
         ++i;
     }