void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) { #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEREMOVED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = device_instance; SDL_PushEvent(&event); } UpdateEventsForDeviceRemoval(); #endif /* !SDL_EVENTS_DISABLED */ }
/* * Event filter to fire controller events from joystick ones */ static int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) { switch(event->type) { case SDL_JOYAXISMOTION: { SDL_GameController *controllerlist; if (event->jaxis.axis >= k_nMaxReverseEntries) { SDL_SetError("SDL_GameControllerEventWatcher: Axis index %d too large, ignoring motion", (int)event->jaxis.axis); break; } controllerlist = SDL_gamecontrollers; while (controllerlist) { if (controllerlist->joystick->instance_id == event->jaxis.which) { if (controllerlist->mapping.raxes[event->jaxis.axis] >= 0) /* simple axis to axis, send it through */ { SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis]; Sint16 value = event->jaxis.value; switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: value = value / 2 + 16384; break; default: break; } SDL_PrivateGameControllerAxis(controllerlist, axis, value); } else if (controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0) { /* simulate an axis as a button */ SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED); } break; } controllerlist = controllerlist->next; } } break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { SDL_GameController *controllerlist; if (event->jbutton.button >= k_nMaxReverseEntries) { SDL_SetError("SDL_GameControllerEventWatcher: Button index %d too large, ignoring update", (int)event->jbutton.button); break; } controllerlist = SDL_gamecontrollers; while (controllerlist) { if (controllerlist->joystick->instance_id == event->jbutton.which) { if (controllerlist->mapping.rbuttons[event->jbutton.button] >= 0) { /* simple button as button */ SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state); } else if (controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0) { /* an button pretending to be an axis */ SDL_PrivateGameControllerAxis(controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0); } break; } controllerlist = controllerlist->next; } } break; case SDL_JOYHATMOTION: { SDL_GameController *controllerlist; if (event->jhat.hat >= 4) break; controllerlist = SDL_gamecontrollers; while (controllerlist) { if (controllerlist->joystick->instance_id == event->jhat.which) { Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value; /* Get list of removed bits (button release) */ Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame; /* the hat idx in the high nibble */ int bHighHat = event->jhat.hat << 4; if (bChanged & SDL_HAT_DOWN) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED); if (bChanged & SDL_HAT_UP) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED); if (bChanged & SDL_HAT_LEFT) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED); if (bChanged & SDL_HAT_RIGHT) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED); /* Get list of added bits (button press) */ bChanged = event->jhat.value ^ bSame; if (bChanged & SDL_HAT_DOWN) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED); if (bChanged & SDL_HAT_UP) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED); if (bChanged & SDL_HAT_LEFT) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED); if (bChanged & SDL_HAT_RIGHT) SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED); /* update our state cache */ controllerlist->hatState[event->jhat.hat] = event->jhat.value; break; } controllerlist = controllerlist->next; } } break; case SDL_JOYDEVICEADDED: { if (SDL_IsGameController(event->jdevice.which)) { SDL_Event deviceevent; deviceevent.type = SDL_CONTROLLERDEVICEADDED; deviceevent.cdevice.which = event->jdevice.which; SDL_PushEvent(&deviceevent); } } break; case SDL_JOYDEVICEREMOVED: { SDL_GameController *controllerlist = SDL_gamecontrollers; while (controllerlist) { if (controllerlist->joystick->instance_id == event->jdevice.which) { SDL_Event deviceevent; deviceevent.type = SDL_CONTROLLERDEVICEREMOVED; deviceevent.cdevice.which = event->jdevice.which; SDL_PushEvent(&deviceevent); UpdateEventsForDeviceRemoval(); break; } controllerlist = controllerlist->next; } } break; default: break; } return 1; }