From 15d30298cf2f2b1fffc112aff984d357cf9e84b6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Dec 2019 15:01:32 -0800 Subject: [PATCH] Added support for wireless Xbox 360 controllers using the HIDAPI driver --- .../java/org/libsdl/app/HIDDeviceManager.java | 15 +++++++-------- src/hidapi/libusb/hid.c | 9 +++++---- src/joystick/controller_type.h | 2 +- src/joystick/hidapi/SDL_hidapijoystick.c | 1 + src/joystick/hidapi/SDL_hidapijoystick_c.h | 1 + 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java index 4a54ef7b33847..bdd14aa17b20f 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -255,17 +255,16 @@ private boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) { return true; } - if (interface_number == 0) { - if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) { - return true; - } + if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) { + return true; } return false; } private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) { final int XB360_IFACE_SUBCLASS = 93; - final int XB360_IFACE_PROTOCOL = 1; // Wired only + final int XB360_IFACE_PROTOCOL = 1; // Wired + final int XB360W_IFACE_PROTOCOL = 129; // Wireless final int[] SUPPORTED_VENDORS = { 0x0079, // GPD Win 2 0x044f, // Thrustmaster @@ -290,10 +289,10 @@ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterfa 0x24c6, // PowerA }; - if (usbInterface.getId() == 0 && - usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && + if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && usbInterface.getInterfaceSubclass() == XB360_IFACE_SUBCLASS && - usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL) { + (usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL || + usbInterface.getInterfaceProtocol() == XB360W_IFACE_PROTOCOL)) { int vendor_id = usbDevice.getVendorId(); for (int supportedVid : SUPPORTED_VENDORS) { if (vendor_id == supportedVid) { diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c index 184e5863fcf7f..ce847bd272136 100644 --- a/src/hidapi/libusb/hid.c +++ b/src/hidapi/libusb/hid.c @@ -481,7 +481,8 @@ int HID_API_EXPORT hid_exit(void) static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) { static const int XB360_IFACE_SUBCLASS = 93; - static const int XB360_IFACE_PROTOCOL = 1; /* Wired only */ + static const int XB360_IFACE_PROTOCOL = 1; /* Wired */ + static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ static const int SUPPORTED_VENDORS[] = { 0x0079, /* GPD Win 2 */ 0x044f, /* Thrustmaster */ @@ -506,10 +507,10 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de 0x24c6, /* PowerA */ }; - if (intf_desc->bInterfaceNumber == 0 && - intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && intf_desc->bInterfaceSubClass == XB360_IFACE_SUBCLASS && - intf_desc->bInterfaceProtocol == XB360_IFACE_PROTOCOL) { + (intf_desc->bInterfaceProtocol == XB360_IFACE_PROTOCOL || + intf_desc->bInterfaceProtocol == XB360W_IFACE_PROTOCOL)) { int i; for (i = 0; i < sizeof(SUPPORTED_VENDORS)/sizeof(SUPPORTED_VENDORS[0]); ++i) { if (vendor_id == SUPPORTED_VENDORS[i]) { diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h index df87229a8cf3d..8b855d242b860 100644 --- a/src/joystick/controller_type.h +++ b/src/joystick/controller_type.h @@ -169,7 +169,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x044f, 0xb326 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster Gamepad GP XID { MAKE_CONTROLLER_ID( 0x045e, 0x028e ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad { MAKE_CONTROLLER_ID( 0x045e, 0x028f ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad v2 - { MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, NULL }, // Xbox 360 Wireless Receiver (XBOX) + { MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (XBOX) { MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Big Button IR { MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 pad { MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 929acbd5f213a..9c7672b656eff 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -69,6 +69,7 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { #endif #ifdef SDL_JOYSTICK_HIDAPI_XBOX360 &SDL_HIDAPI_DriverXbox360, + &SDL_HIDAPI_DriverXbox360W, #endif #ifdef SDL_JOYSTICK_HIDAPI_XBOXONE &SDL_HIDAPI_DriverXboxOne, diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 36d1b256506b4..6c9efe3aee430 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -93,6 +93,7 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; /* Return true if a HID device is present and supported as a joystick */