| | |
| | | |
| | | #if SDL_JOYSTICK_XINPUT |
| | | |
| | | #include "SDL_assert.h" |
| | | #include "SDL_hints.h" |
| | | #include "SDL_log.h" |
| | | #include "SDL_timer.h" |
| | | #include "SDL_windowsjoystick_c.h" |
| | | #include "SDL_xinputjoystick_c.h" |
| | | #include "SDL_rawinputjoystick_c.h" |
| | | #include "../hidapi/SDL_hidapijoystick_c.h" |
| | | |
| | | /* |
| | |
| | | { |
| | | s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE); |
| | | |
| | | #ifdef SDL_JOYSTICK_RAWINPUT |
| | | if (RAWINPUT_IsEnabled()) { |
| | | /* The raw input driver handles more than 4 controllers, so prefer that when available */ |
| | | s_bXInputEnabled = SDL_FALSE; |
| | | } |
| | | #endif |
| | | |
| | | if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) { |
| | | s_bXInputEnabled = SDL_FALSE; /* oh well. */ |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | static char * |
| | | static const char * |
| | | GetXInputName(const Uint8 userid, BYTE SubType) |
| | | { |
| | | char name[32]; |
| | | static char name[32]; |
| | | |
| | | if (SDL_XInputUseOldJoystickMapping()) { |
| | | SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); |
| | |
| | | break; |
| | | } |
| | | } |
| | | return SDL_strdup(name); |
| | | return name; |
| | | } |
| | | |
| | | /* We can't really tell what device is being used for XInput, but we can guess |
| | |
| | | *pVID = (Uint16)rdi.hid.dwVendorId; |
| | | *pPID = (Uint16)rdi.hid.dwProductId; |
| | | *pVersion = (Uint16)rdi.hid.dwVersionNumber; |
| | | SDL_free(devices); |
| | | return; |
| | | } |
| | | } |
| | |
| | | |
| | | for (i = 0; i < device_count; i++) { |
| | | RID_DEVICE_INFO rdi; |
| | | char devName[128]; |
| | | char devName[MAX_PATH]; |
| | | UINT rdiSize = sizeof(rdi); |
| | | UINT nameSize = SDL_arraysize(devName); |
| | | |
| | |
| | | SDL_free(s_arrXInputDevicePath[userid]); |
| | | } |
| | | s_arrXInputDevicePath[userid] = SDL_strdup(devName); |
| | | SDL_free(devices); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | SDL_free(devices); |
| | | #endif /* ifndef __WINRT__ */ |
| | | #endif /* !__WINRT__ */ |
| | | |
| | | /* The device wasn't in the raw HID device list, it's probably Bluetooth */ |
| | | *pVID = 0x045e; /* Microsoft */ |
| | |
| | | Uint16 vendor = 0; |
| | | Uint16 product = 0; |
| | | Uint16 version = 0; |
| | | const char *name; |
| | | JoyStick_DeviceData *pPrevJoystick = NULL; |
| | | JoyStick_DeviceData *pNewJoystick = *pContext; |
| | | |
| | |
| | | } |
| | | pNewJoystick->SubType = SubType; |
| | | pNewJoystick->XInputUserId = userid; |
| | | |
| | | name = SDL_GetCustomJoystickName(vendor, product); |
| | | if (name) { |
| | | pNewJoystick->joystickname = SDL_strdup(name); |
| | | } else { |
| | | pNewJoystick->joystickname = GetXInputName(userid, SubType); |
| | | } |
| | | pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType)); |
| | | if (!pNewJoystick->joystickname) { |
| | | SDL_free(pNewJoystick); |
| | | return; /* better luck next time? */ |
| | |
| | | } |
| | | |
| | | #ifdef SDL_JOYSTICK_HIDAPI |
| | | if (HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) { |
| | | /* Since we're guessing about the VID/PID, use a hard-coded VID/PID to represent XInput */ |
| | | if (HIDAPI_IsDevicePresent(USB_VENDOR_MICROSOFT, USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER, version, pNewJoystick->joystickname)) { |
| | | /* The HIDAPI driver is taking care of this device */ |
| | | SDL_free(pNewJoystick); |
| | | return; |
| | | } |
| | | #endif |
| | | |
| | | #ifdef SDL_JOYSTICK_RAWINPUT |
| | | if (RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) { |
| | | /* The RAWINPUT driver is taking care of this device */ |
| | | SDL_free(pNewJoystick); |
| | | return; |
| | | } |
| | |
| | | const Uint8 userid = (Uint8)iuserid; |
| | | XINPUT_CAPABILITIES capabilities; |
| | | if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) { |
| | | /* Adding a new device, must handle all removes first, or GuessXInputDevice goes terribly wrong (returns |
| | | a product/vendor ID that is not even attached to the system) when we get a remove and add on the same tick |
| | | (e.g. when disconnecting a device and the OS reassigns which userid an already-attached controller is) |
| | | */ |
| | | int iuserid2; |
| | | for (iuserid2 = iuserid - 1; iuserid2 >= 0; iuserid2--) { |
| | | const Uint8 userid2 = (Uint8)iuserid2; |
| | | XINPUT_CAPABILITIES capabilities2; |
| | | if (XINPUTGETCAPABILITIES(userid2, XINPUT_FLAG_GAMEPAD, &capabilities2) != ERROR_SUCCESS) { |
| | | DelXInputDevice(userid2); |
| | | } |
| | | } |
| | | AddXInputDevice(userid, capabilities.SubType, pContext); |
| | | } else { |
| | | DelXInputDevice(userid); |