SDL Changes to support clean reads

CR: saml
This commit is contained in:
Sam Lantinga 2018-02-05 11:40:39 -08:00
parent 35322ed847
commit 2b441ec6c4
1 changed files with 81 additions and 59 deletions

View File

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