21 #include "../../SDL_internal.h" 23 #include "../SDL_sysjoystick.h" 25 #if SDL_JOYSTICK_XINPUT 36 static char *s_arrXInputDevicePath[XUSER_MAX_COUNT];
40 SDL_XInputUseOldJoystickMapping()
47 static int s_XInputUseOldJoystickMapping = -1;
48 if (s_XInputUseOldJoystickMapping < 0) {
51 return (s_XInputUseOldJoystickMapping > 0);
57 return s_bXInputEnabled;
65 if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
72 GetXInputName(
const Uint8 userid, BYTE SubType)
76 if (SDL_XInputUseOldJoystickMapping()) {
77 SDL_snprintf(name,
sizeof(name),
"X360 Controller #%u", 1 + userid);
80 case XINPUT_DEVSUBTYPE_GAMEPAD:
81 SDL_snprintf(name,
sizeof(name),
"XInput Controller #%u", 1 + userid);
83 case XINPUT_DEVSUBTYPE_WHEEL:
84 SDL_snprintf(name,
sizeof(name),
"XInput Wheel #%u", 1 + userid);
86 case XINPUT_DEVSUBTYPE_ARCADE_STICK:
87 SDL_snprintf(name,
sizeof(name),
"XInput ArcadeStick #%u", 1 + userid);
89 case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
90 SDL_snprintf(name,
sizeof(name),
"XInput FlightStick #%u", 1 + userid);
92 case XINPUT_DEVSUBTYPE_DANCE_PAD:
93 SDL_snprintf(name,
sizeof(name),
"XInput DancePad #%u", 1 + userid);
95 case XINPUT_DEVSUBTYPE_GUITAR:
96 case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
97 case XINPUT_DEVSUBTYPE_GUITAR_BASS:
98 SDL_snprintf(name,
sizeof(name),
"XInput Guitar #%u", 1 + userid);
100 case XINPUT_DEVSUBTYPE_DRUM_KIT:
101 SDL_snprintf(name,
sizeof(name),
"XInput DrumKit #%u", 1 + userid);
103 case XINPUT_DEVSUBTYPE_ARCADE_PAD:
104 SDL_snprintf(name,
sizeof(name),
"XInput ArcadePad #%u", 1 + userid);
107 SDL_snprintf(name,
sizeof(name),
"XInput Device #%u", 1 + userid);
123 UINT
i,
j, device_count = 0;
125 if ((GetRawInputDeviceList(
NULL, &device_count,
sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
129 devices = (PRAWINPUTDEVICELIST)
SDL_malloc(
sizeof(RAWINPUTDEVICELIST) * device_count);
130 if (devices ==
NULL) {
134 if (GetRawInputDeviceList(devices, &device_count,
sizeof(RAWINPUTDEVICELIST)) == -1) {
139 for (i = 0; i < device_count; i++) {
142 UINT rdiSize =
sizeof(rdi);
145 rdi.cbSize =
sizeof(rdi);
146 if ((devices[i].dwType == RIM_TYPEHID) &&
147 (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
148 (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
155 if (!s_arrXInputDevicePath[j]) {
158 if (
SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
172 *pVID = (
Uint16)rdi.hid.dwVendorId;
173 *pPID = (
Uint16)rdi.hid.dwProductId;
174 *pVersion = (
Uint16)rdi.hid.dwVersionNumber;
175 if (s_arrXInputDevicePath[userid]) {
176 SDL_free(s_arrXInputDevicePath[userid]);
178 s_arrXInputDevicePath[userid] =
SDL_strdup(devName);
192 if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
195 if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
198 while (pNewJoystick) {
201 if (pNewJoystick == *pContext) {
202 *pContext = pNewJoystick->
pNext;
203 }
else if (pPrevJoystick) {
212 pPrevJoystick = pNewJoystick;
213 pNewJoystick = pNewJoystick->
pNext;
222 pNewJoystick->
joystickname = GetXInputName(userid, SubType);
229 if (SDL_XInputUseOldJoystickMapping()) {
232 const Uint16 BUS_USB = 0x03;
238 GuessXInputDevice(userid, &vendor, &product, &version);
251 pNewJoystick->
guid.
data[15] = SubType;
253 pNewJoystick->
SubType = SubType;
269 if (!s_bXInputEnabled) {
274 for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
276 XINPUT_CAPABILITIES capabilities;
277 if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
278 AddXInputDevice(userid, capabilities.SubType, pContext);
287 XINPUT_CAPABILITIES capabilities;
288 XINPUT_VIBRATION
state;
295 joystick->hwdata->bXInputDevice =
SDL_TRUE;
297 if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
299 joystick->hwdata =
NULL;
300 return SDL_SetError(
"Failed to obtain XInput device capabilities. Device disconnected?");
303 joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
304 joystick->hwdata->userid = userId;
307 if (SDL_XInputUseOldJoystickMapping()) {
309 joystick->nbuttons = 15;
312 joystick->nbuttons = 11;
319 UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
321 if (pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN) {
323 if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
326 switch (pBatteryInformation->BatteryLevel) {
327 case BATTERY_LEVEL_EMPTY:
330 case BATTERY_LEVEL_LOW:
333 case BATTERY_LEVEL_MEDIUM:
337 case BATTERY_LEVEL_FULL:
348 UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
350 static WORD s_XInputButtons[] = {
351 XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
352 XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
353 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
354 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
357 WORD wButtons = pXInputState->Gamepad.wButtons;
371 UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
375 UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
377 static WORD s_XInputButtons[] = {
378 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
379 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
380 XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
383 WORD wButtons = pXInputState->Gamepad.wButtons;
398 if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
401 if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
404 if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
407 if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
412 UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
419 XINPUT_STATE_EX XInputState;
420 XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
425 result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
426 if (result == ERROR_DEVICE_NOT_CONNECTED) {
427 Uint8 userid = joystick->hwdata->userid;
429 joystick->hwdata->send_remove_event =
SDL_TRUE;
430 joystick->hwdata->removed =
SDL_TRUE;
431 if (s_arrXInputDevicePath[userid]) {
432 SDL_free(s_arrXInputDevicePath[userid]);
433 s_arrXInputDevicePath[userid] =
NULL;
439 if (XINPUTGETBATTERYINFORMATION) {
440 result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);
444 if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
445 if (SDL_XInputUseOldJoystickMapping()) {
446 UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
448 UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
450 joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
462 if (s_bXInputEnabled) {
463 WIN_UnloadXInputDLL();
468 SDL_SYS_IsXInputGamepad_DeviceIndex(
int device_index)
473 for (index = device_index; index > 0; index--)
474 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)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
GLuint const GLchar * name
#define SDL_GetHintBoolean
#define SDL_HINT_XINPUT_ENABLED
A variable that lets you disable the detection and use of Xinput gamepad devices. ...
static SDL_AudioDeviceID device
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#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()