21 #include "../../SDL_internal.h" 23 #include "../SDL_sysjoystick.h" 25 #if SDL_JOYSTICK_XINPUT 39 SDL_XInputUseOldJoystickMapping()
41 static int s_XInputUseOldJoystickMapping = -1;
42 if (s_XInputUseOldJoystickMapping < 0) {
45 return (s_XInputUseOldJoystickMapping > 0);
50 return s_bXInputEnabled;
58 if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
65 GetXInputName(
const Uint8 userid, BYTE SubType)
69 if (SDL_XInputUseOldJoystickMapping()) {
70 SDL_snprintf(name,
sizeof(name),
"X360 Controller #%u", 1 + userid);
73 case XINPUT_DEVSUBTYPE_GAMEPAD:
74 SDL_snprintf(name,
sizeof(name),
"XInput Controller #%u", 1 + userid);
76 case XINPUT_DEVSUBTYPE_WHEEL:
77 SDL_snprintf(name,
sizeof(name),
"XInput Wheel #%u", 1 + userid);
79 case XINPUT_DEVSUBTYPE_ARCADE_STICK:
80 SDL_snprintf(name,
sizeof(name),
"XInput ArcadeStick #%u", 1 + userid);
82 case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
83 SDL_snprintf(name,
sizeof(name),
"XInput FlightStick #%u", 1 + userid);
85 case XINPUT_DEVSUBTYPE_DANCE_PAD:
86 SDL_snprintf(name,
sizeof(name),
"XInput DancePad #%u", 1 + userid);
88 case XINPUT_DEVSUBTYPE_GUITAR:
89 case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
90 case XINPUT_DEVSUBTYPE_GUITAR_BASS:
91 SDL_snprintf(name,
sizeof(name),
"XInput Guitar #%u", 1 + userid);
93 case XINPUT_DEVSUBTYPE_DRUM_KIT:
94 SDL_snprintf(name,
sizeof(name),
"XInput DrumKit #%u", 1 + userid);
96 case XINPUT_DEVSUBTYPE_ARCADE_PAD:
97 SDL_snprintf(name,
sizeof(name),
"XInput ArcadePad #%u", 1 + userid);
100 SDL_snprintf(name,
sizeof(name),
"XInput Device #%u", 1 + userid);
113 if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
116 if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
119 while (pNewJoystick) {
122 if (pNewJoystick == *pContext) {
123 *pContext = pNewJoystick->
pNext;
124 }
else if (pPrevJoystick) {
133 pPrevJoystick = pNewJoystick;
134 pNewJoystick = pNewJoystick->
pNext;
143 pNewJoystick->
joystickname = GetXInputName(userid, SubType);
150 if (SDL_XInputUseOldJoystickMapping()) {
159 pNewJoystick->
guid.
data[6] = SubType;
161 pNewJoystick->
SubType = SubType;
171 if (!s_bXInputEnabled) {
176 for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
178 XINPUT_CAPABILITIES capabilities;
179 if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
180 AddXInputDevice(userid, capabilities.SubType, pContext);
189 XINPUT_CAPABILITIES capabilities;
190 XINPUT_VIBRATION
state;
197 joystick->hwdata->bXInputDevice =
SDL_TRUE;
199 if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
201 joystick->hwdata =
NULL;
202 return SDL_SetError(
"Failed to obtain XInput device capabilities. Device disconnected?");
205 joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
206 joystick->hwdata->userid = userId;
209 if (SDL_XInputUseOldJoystickMapping()) {
211 joystick->nbuttons = 15;
214 joystick->nbuttons = 11;
221 UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
223 if ( pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN )
226 if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
229 switch ( pBatteryInformation->BatteryLevel )
231 case BATTERY_LEVEL_EMPTY:
234 case BATTERY_LEVEL_LOW:
237 case BATTERY_LEVEL_MEDIUM:
241 case BATTERY_LEVEL_FULL:
252 UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
254 static WORD s_XInputButtons[] = {
255 XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
256 XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
257 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
258 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
261 WORD wButtons = pXInputState->Gamepad.wButtons;
275 UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
279 UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
281 static WORD s_XInputButtons[] = {
282 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
283 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
284 XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
287 WORD wButtons = pXInputState->Gamepad.wButtons;
302 if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
305 if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
308 if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
311 if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
316 UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
323 XINPUT_STATE_EX XInputState;
324 XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
329 result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
330 if (result == ERROR_DEVICE_NOT_CONNECTED) {
331 joystick->hwdata->send_remove_event =
SDL_TRUE;
332 joystick->hwdata->removed =
SDL_TRUE;
337 if ( XINPUTGETBATTERYINFORMATION )
339 result = XINPUTGETBATTERYINFORMATION( joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation );
343 if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
344 if (SDL_XInputUseOldJoystickMapping()) {
345 UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
347 UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
349 joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
361 if (s_bXInputEnabled) {
362 WIN_UnloadXInputDLL();
367 SDL_SYS_IsXInputGamepad_DeviceIndex(
int device_index)
372 for (index = device_index; index > 0; index--)
373 device = device->
pNext;
JoyStick_DeviceData * SYS_Joystick
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
struct JoyStick_DeviceData * pNext
void SDL_SYS_AddJoystickDevice(JoyStick_DeviceData *device)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
GLuint const GLchar * name
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
#define SDL_GetHintBoolean
#define SDL_HINT_XINPUT_ENABLED
A variable that lets you disable the detection and use of Xinput gamepad devices. ...
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_assert(condition)
#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING
A variable that causes SDL to use the old axis and button mapping for XInput devices.
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
#define SDL_arraysize(array)
#define SDL_Unsupported()
int16_t Sint16
A signed 16-bit integer type.