static void AddXInputDevice(const Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) { JoyStick_DeviceData *pPrevJoystick = NULL; JoyStick_DeviceData *pNewJoystick = *pContext; if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) return; if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN) return; while (pNewJoystick) { if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *pContext) { *pContext = pNewJoystick->pNext; } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; return; /* already in the list. */ } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return; /* better luck next time? */ } SDL_zerop(pNewJoystick); pNewJoystick->joystickname = GetXInputName(userid, SubType); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return; /* better luck next time? */ } pNewJoystick->bXInputDevice = SDL_TRUE; if (SDL_XInputUseOldJoystickMapping()) { SDL_zero(pNewJoystick->guid); } else { pNewJoystick->guid.data[0] = 'x'; pNewJoystick->guid.data[1] = 'i'; pNewJoystick->guid.data[2] = 'n'; pNewJoystick->guid.data[3] = 'p'; pNewJoystick->guid.data[4] = 'u'; pNewJoystick->guid.data[5] = 't'; pNewJoystick->guid.data[6] = SubType; } pNewJoystick->SubType = SubType; pNewJoystick->XInputUserId = userid; SDL_SYS_AddJoystickDevice(pNewJoystick); }
void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) { HRESULT result; XINPUT_STATE_EX XInputState; XINPUT_BATTERY_INFORMATION_EX XBatteryInformation; if (!XINPUTGETSTATE) return; result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState); if (result == ERROR_DEVICE_NOT_CONNECTED) { joystick->hwdata->send_remove_event = SDL_TRUE; joystick->hwdata->removed = SDL_TRUE; return; } SDL_zero( XBatteryInformation ); if ( XINPUTGETBATTERYINFORMATION ) { result = XINPUTGETBATTERYINFORMATION( joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation ); } /* only fire events if the data changed from last time */ if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) { if (SDL_XInputUseOldJoystickMapping()) { UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation); } else { UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation); } joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber; } }
int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) { const Uint8 userId = joystickdevice->XInputUserId; XINPUT_CAPABILITIES capabilities; XINPUT_VIBRATION state; SDL_assert(s_bXInputEnabled); SDL_assert(XINPUTGETCAPABILITIES); SDL_assert(XINPUTSETSTATE); SDL_assert(userId < XUSER_MAX_COUNT); joystick->hwdata->bXInputDevice = SDL_TRUE; if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) { SDL_free(joystick->hwdata); joystick->hwdata = NULL; return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?"); } SDL_zero(state); joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS); joystick->hwdata->userid = userId; /* The XInput API has a hard coded button/axis mapping, so we just match it */ if (SDL_XInputUseOldJoystickMapping()) { joystick->naxes = 6; joystick->nbuttons = 15; } else { joystick->naxes = 6; joystick->nbuttons = 11; joystick->nhats = 1; } return 0; }
static char * GetXInputName(const Uint8 userid, BYTE SubType) { char name[32]; if (SDL_XInputUseOldJoystickMapping()) { SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); } else { switch (SubType) { case XINPUT_DEVSUBTYPE_GAMEPAD: SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_WHEEL: SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_ARCADE_STICK: SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_FLIGHT_STICK: SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_DANCE_PAD: SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_GUITAR: case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE: case XINPUT_DEVSUBTYPE_GUITAR_BASS: SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_DRUM_KIT: SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_ARCADE_PAD: SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid); break; default: SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid); break; } } return SDL_strdup(name); }
void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) { HRESULT result; XINPUT_STATE_EX XInputState; XINPUT_BATTERY_INFORMATION_EX XBatteryInformation; if (!XINPUTGETSTATE) return; result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState); if (result == ERROR_DEVICE_NOT_CONNECTED) { return; } SDL_zero(XBatteryInformation); if (XINPUTGETBATTERYINFORMATION) { result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation); } /* only fire events if the data changed from last time */ if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) { if (SDL_XInputUseOldJoystickMapping()) { UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation); } else { UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation); } joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber; } if (joystick->hwdata->rumble_expiration) { Uint32 now = SDL_GetTicks(); if (SDL_TICKS_PASSED(now, joystick->hwdata->rumble_expiration)) { SDL_XINPUT_JoystickRumble(joystick, 0, 0, 0); } } }
static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) { Uint16 vendor = 0; Uint16 product = 0; Uint16 version = 0; JoyStick_DeviceData *pPrevJoystick = NULL; JoyStick_DeviceData *pNewJoystick = *pContext; if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) return; if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN) return; while (pNewJoystick) { if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *pContext) { *pContext = pNewJoystick->pNext; } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; return; /* already in the list. */ } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return; /* better luck next time? */ } SDL_zerop(pNewJoystick); pNewJoystick->joystickname = GetXInputName(userid, SubType); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return; /* better luck next time? */ } pNewJoystick->bXInputDevice = SDL_TRUE; if (SDL_XInputUseOldJoystickMapping()) { SDL_zero(pNewJoystick->guid); } else { Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data; GuessXInputDevice(userid, &vendor, &product, &version); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = 0; *guid16++ = SDL_SwapLE16(vendor); *guid16++ = 0; *guid16++ = SDL_SwapLE16(product); *guid16++ = 0; *guid16++ = SDL_SwapLE16(version); *guid16++ = 0; /* Note that this is an XInput device and what subtype it is */ pNewJoystick->guid.data[14] = 'x'; pNewJoystick->guid.data[15] = SubType; } pNewJoystick->SubType = SubType; pNewJoystick->XInputUserId = userid; if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { SDL_free(pNewJoystick); return; } #ifdef SDL_JOYSTICK_HIDAPI if (HIDAPI_IsDevicePresent(vendor, product, version)) { /* The HIDAPI driver is taking care of this device */ SDL_free(pNewJoystick); return; } #endif WINDOWS_AddJoystickDevice(pNewJoystick); }