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) {
44 s_XInputUseOldJoystickMapping = (hint && *hint ==
'1') ? 1 : 0;
46 return (s_XInputUseOldJoystickMapping > 0);
51 return s_bXInputEnabled;
62 if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
69 GetXInputName(
const Uint8 userid, BYTE SubType)
73 if (SDL_XInputUseOldJoystickMapping()) {
74 SDL_snprintf(name,
sizeof(name),
"X360 Controller #%u", 1 + userid);
77 case XINPUT_DEVSUBTYPE_GAMEPAD:
78 SDL_snprintf(name,
sizeof(name),
"XInput Controller #%u", 1 + userid);
80 case XINPUT_DEVSUBTYPE_WHEEL:
81 SDL_snprintf(name,
sizeof(name),
"XInput Wheel #%u", 1 + userid);
83 case XINPUT_DEVSUBTYPE_ARCADE_STICK:
84 SDL_snprintf(name,
sizeof(name),
"XInput ArcadeStick #%u", 1 + userid);
86 case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
87 SDL_snprintf(name,
sizeof(name),
"XInput FlightStick #%u", 1 + userid);
89 case XINPUT_DEVSUBTYPE_DANCE_PAD:
90 SDL_snprintf(name,
sizeof(name),
"XInput DancePad #%u", 1 + userid);
92 case XINPUT_DEVSUBTYPE_GUITAR:
93 case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
94 case XINPUT_DEVSUBTYPE_GUITAR_BASS:
95 SDL_snprintf(name,
sizeof(name),
"XInput Guitar #%u", 1 + userid);
97 case XINPUT_DEVSUBTYPE_DRUM_KIT:
98 SDL_snprintf(name,
sizeof(name),
"XInput DrumKit #%u", 1 + userid);
100 case XINPUT_DEVSUBTYPE_ARCADE_PAD:
101 SDL_snprintf(name,
sizeof(name),
"XInput ArcadePad #%u", 1 + userid);
104 SDL_snprintf(name,
sizeof(name),
"XInput Device #%u", 1 + userid);
117 if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
120 if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
123 while (pNewJoystick) {
126 if (pNewJoystick == *pContext) {
127 *pContext = pNewJoystick->
pNext;
128 }
else if (pPrevJoystick) {
137 pPrevJoystick = pNewJoystick;
138 pNewJoystick = pNewJoystick->
pNext;
147 pNewJoystick->
joystickname = GetXInputName(userid, SubType);
154 if (SDL_XInputUseOldJoystickMapping()) {
163 pNewJoystick->
guid.
data[6] = SubType;
165 pNewJoystick->
SubType = SubType;
175 if (!s_bXInputEnabled) {
180 for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
182 XINPUT_CAPABILITIES capabilities;
183 if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
184 AddXInputDevice(userid, capabilities.SubType, pContext);
193 XINPUT_CAPABILITIES capabilities;
194 XINPUT_VIBRATION
state;
201 joystick->hwdata->bXInputDevice =
SDL_TRUE;
203 if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
205 joystick->hwdata =
NULL;
206 return SDL_SetError(
"Failed to obtain XInput device capabilities. Device disconnected?");
209 joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
210 joystick->hwdata->userid = userId;
213 if (SDL_XInputUseOldJoystickMapping()) {
215 joystick->nbuttons = 15;
218 joystick->nbuttons = 11;
225 UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
227 if ( pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN )
230 if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
233 switch ( pBatteryInformation->BatteryLevel )
235 case BATTERY_LEVEL_EMPTY:
238 case BATTERY_LEVEL_LOW:
241 case BATTERY_LEVEL_MEDIUM:
245 case BATTERY_LEVEL_FULL:
256 UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
258 static WORD s_XInputButtons[] = {
259 XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
260 XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
261 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
262 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
265 WORD wButtons = pXInputState->Gamepad.wButtons;
279 UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
283 UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
285 static WORD s_XInputButtons[] = {
286 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
287 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
288 XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
291 WORD wButtons = pXInputState->Gamepad.wButtons;
306 if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
309 if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
312 if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
315 if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
320 UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
327 XINPUT_STATE_EX XInputState;
328 XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
333 result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
334 if (result == ERROR_DEVICE_NOT_CONNECTED) {
335 joystick->hwdata->send_remove_event =
SDL_TRUE;
336 joystick->hwdata->removed =
SDL_TRUE;
341 if ( XINPUTGETBATTERYINFORMATION )
343 result = XINPUTGETBATTERYINFORMATION( joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation );
347 if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
348 if (SDL_XInputUseOldJoystickMapping()) {
349 UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
351 UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
353 joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
365 if (s_bXInputEnabled) {
366 WIN_UnloadXInputDLL();
371 SDL_SYS_IsXInputGamepad_DeviceIndex(
int device_index)
376 for (index = device_index; index > 0; index--)
377 device = device->
pNext;
379 return (device->
SubType == XINPUT_DEVSUBTYPE_GAMEPAD);
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_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.