/* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) { recDevice *device = joystick->hwdata; recElement *element; SInt32 value; int i; if (device->removed) /* device was unplugged; ignore it. */ { if (device->uncentered) { device->uncentered = 0; /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < device->axes; i++) SDL_PrivateJoystickAxis(joystick, i, 0); for (i = 0; i < device->buttons; i++) SDL_PrivateJoystickButton(joystick, i, 0); for (i = 0; i < device->hats; i++) SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); } return; } element = device->firstAxis; i = 0; while (element) { value = HIDScaledCalibratedValue(device, element, -32768, 32767); if ( value != joystick->axes[i] ) SDL_PrivateJoystickAxis(joystick, i, value); element = element->pNext; ++i; } element = device->firstButton; i = 0; while (element) { value = HIDGetElementValue(device, element); if (value > 1) /* handle pressure-sensitive buttons */ value = 1; if ( value != joystick->buttons[i] ) SDL_PrivateJoystickButton(joystick, i, value); element = element->pNext; ++i; } element = device->firstHat; i = 0; while (element) { Uint8 pos = 0; value = HIDGetElementValue(device, element); if (element->max == 3) /* 4 position hatswitch - scale up value */ value *= 2; else if (element->max != 7) /* 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; } if ( pos != joystick->hats[i] ) SDL_PrivateJoystickHat(joystick, i, pos); element = element->pNext; ++i; } return; }
/* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { recDevice *device = joystick->hwdata; recElement *element; SInt32 value, range; int i; if ( !device ) return; if (device->removed) { /* device was unplugged; ignore it. */ recDevice *devicelist = gpDeviceList; joystick->closed = 1; joystick->uncentered = 1; if ( devicelist == device ) { gpDeviceList = device->pNext; } else { while ( devicelist->pNext != device ) { devicelist = devicelist->pNext; } devicelist->pNext = device->pNext; } DisposePtr((Ptr) device); joystick->hwdata = NULL; #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEREMOVED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = joystick->instance_id; if ((SDL_EventOK == NULL) || (*SDL_EventOK) (SDL_EventOKParam, &event)) { SDL_PushEvent(&event); } } #endif /* !SDL_EVENTS_DISABLED */ return; } element = device->firstAxis; i = 0; while (element) { value = HIDScaledCalibratedValue(device, element, -32768, 32767); if (value != joystick->axes[i]) SDL_PrivateJoystickAxis(joystick, i, value); element = element->pNext; ++i; } element = device->firstButton; i = 0; while (element) { value = HIDGetElementValue(device, element); if (value > 1) /* handle pressure-sensitive buttons */ value = 1; if (value != joystick->buttons[i]) 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 = HIDGetElementValue(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; } if (pos != joystick->hats[i]) SDL_PrivateJoystickHat(joystick, i, pos); element = element->pNext; ++i; } return; }