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()
46 static int s_XInputUseOldJoystickMapping = -1;
47 if (s_XInputUseOldJoystickMapping < 0) {
50 return (s_XInputUseOldJoystickMapping > 0);
56 return s_bXInputEnabled;
64 if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
71 GetXInputName(
const Uint8 userid, BYTE SubType)
75 if (SDL_XInputUseOldJoystickMapping()) {
76 SDL_snprintf(name,
sizeof(name),
"X360 Controller #%u", 1 + userid);
79 case XINPUT_DEVSUBTYPE_GAMEPAD:
80 SDL_snprintf(name,
sizeof(name),
"XInput Controller #%u", 1 + userid);
82 case XINPUT_DEVSUBTYPE_WHEEL:
83 SDL_snprintf(name,
sizeof(name),
"XInput Wheel #%u", 1 + userid);
85 case XINPUT_DEVSUBTYPE_ARCADE_STICK:
86 SDL_snprintf(name,
sizeof(name),
"XInput ArcadeStick #%u", 1 + userid);
88 case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
89 SDL_snprintf(name,
sizeof(name),
"XInput FlightStick #%u", 1 + userid);
91 case XINPUT_DEVSUBTYPE_DANCE_PAD:
92 SDL_snprintf(name,
sizeof(name),
"XInput DancePad #%u", 1 + userid);
94 case XINPUT_DEVSUBTYPE_GUITAR:
95 case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
96 case XINPUT_DEVSUBTYPE_GUITAR_BASS:
97 SDL_snprintf(name,
sizeof(name),
"XInput Guitar #%u", 1 + userid);
99 case XINPUT_DEVSUBTYPE_DRUM_KIT:
100 SDL_snprintf(name,
sizeof(name),
"XInput DrumKit #%u", 1 + userid);
102 case XINPUT_DEVSUBTYPE_ARCADE_PAD:
103 SDL_snprintf(name,
sizeof(name),
"XInput ArcadePad #%u", 1 + userid);
106 SDL_snprintf(name,
sizeof(name),
"XInput Device #%u", 1 + userid);
122 UINT
i,
j, device_count = 0;
124 if ((GetRawInputDeviceList(
NULL, &device_count,
sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
128 devices = (PRAWINPUTDEVICELIST)
SDL_malloc(
sizeof(RAWINPUTDEVICELIST) * device_count);
129 if (devices ==
NULL) {
133 if (GetRawInputDeviceList(devices, &device_count,
sizeof(RAWINPUTDEVICELIST)) == -1) {
138 for (i = 0; i < device_count; i++) {
141 UINT rdiSize =
sizeof(rdi);
144 rdi.cbSize =
sizeof(rdi);
145 if ((devices[i].dwType == RIM_TYPEHID) &&
146 (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
147 (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
154 if (!s_arrXInputDevicePath[j]) {
157 if (
SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
171 *pVID = (
Uint16)rdi.hid.dwVendorId;
172 *pPID = (
Uint16)rdi.hid.dwProductId;
173 *pVersion = (
Uint16)rdi.hid.dwVersionNumber;
174 if (s_arrXInputDevicePath[userid]) {
175 SDL_free(s_arrXInputDevicePath[userid]);
177 s_arrXInputDevicePath[userid] =
SDL_strdup(devName);
191 if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
194 if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
197 while (pNewJoystick) {
200 if (pNewJoystick == *pContext) {
201 *pContext = pNewJoystick->
pNext;
202 }
else if (pPrevJoystick) {
211 pPrevJoystick = pNewJoystick;
212 pNewJoystick = pNewJoystick->
pNext;
221 pNewJoystick->
joystickname = GetXInputName(userid, SubType);
228 if (SDL_XInputUseOldJoystickMapping()) {
231 const Uint16 BUS_USB = 0x03;
237 GuessXInputDevice(userid, &vendor, &product, &version);
250 pNewJoystick->
guid.
data[15] = SubType;
252 pNewJoystick->
SubType = SubType;
268 if (!s_bXInputEnabled) {
273 for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
275 XINPUT_CAPABILITIES capabilities;
276 if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
277 AddXInputDevice(userid, capabilities.SubType, pContext);
286 XINPUT_CAPABILITIES capabilities;
287 XINPUT_VIBRATION
state;
294 joystick->hwdata->bXInputDevice =
SDL_TRUE;
296 if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
298 joystick->hwdata =
NULL;
299 return SDL_SetError(
"Failed to obtain XInput device capabilities. Device disconnected?");
302 joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
303 joystick->hwdata->userid = userId;
306 if (SDL_XInputUseOldJoystickMapping()) {
308 joystick->nbuttons = 15;
311 joystick->nbuttons = 11;
318 UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
320 if (pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN) {
322 if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
325 switch (pBatteryInformation->BatteryLevel) {
326 case BATTERY_LEVEL_EMPTY:
329 case BATTERY_LEVEL_LOW:
332 case BATTERY_LEVEL_MEDIUM:
336 case BATTERY_LEVEL_FULL:
347 UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
349 static WORD s_XInputButtons[] = {
350 XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
351 XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
352 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
353 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
356 WORD wButtons = pXInputState->Gamepad.wButtons;
370 UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
374 UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
376 static WORD s_XInputButtons[] = {
377 XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
378 XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
379 XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
382 WORD wButtons = pXInputState->Gamepad.wButtons;
397 if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
400 if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
403 if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
406 if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
411 UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
418 XINPUT_STATE_EX XInputState;
419 XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
424 result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
425 if (result == ERROR_DEVICE_NOT_CONNECTED) {
426 Uint8 userid = joystick->hwdata->userid;
428 joystick->hwdata->send_remove_event =
SDL_TRUE;
429 joystick->hwdata->removed =
SDL_TRUE;
430 if (s_arrXInputDevicePath[userid]) {
431 SDL_free(s_arrXInputDevicePath[userid]);
432 s_arrXInputDevicePath[userid] =
NULL;
438 if (XINPUTGETBATTERYINFORMATION) {
439 result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);
443 if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
444 if (SDL_XInputUseOldJoystickMapping()) {
445 UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
447 UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
449 joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
461 if (s_bXInputEnabled) {
462 WIN_UnloadXInputDLL();
467 SDL_SYS_IsXInputGamepad_DeviceIndex(
int device_index)
472 for (index = device_index; index > 0; index--)
473 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
uint8_t Uint8
An unsigned 8-bit integer type.
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)
uint16_t Uint16
An unsigned 16-bit integer type.
#define SDL_arraysize(array)
#define SDL_Unsupported()
int16_t Sint16
A signed 16-bit integer type.