Fixed support for third party Xbox 360 wireless controller dongle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index e3dac2d..406d148 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -1398,114 +1398,114 @@ SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *nam
SDL_GameControllerType
SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
+ static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
+ static const int XB360_IFACE_SUBCLASS = 93;
+ static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
+ static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
+ static const int XBONE_IFACE_SUBCLASS = 71;
+ static const int XBONE_IFACE_PROTOCOL = 208;
+
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
- if (vendor == 0x0000 && product == 0x0000) {
- /* Some devices are only identifiable by their name */
- if (SDL_strcmp(name, "Lic Pro Controller") == 0 ||
- SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
- SDL_strcmp(name, "Wireless Gamepad") == 0) {
- /* HORI or PowerA Switch Pro Controller clone */
- type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
- } else {
- type = SDL_CONTROLLER_TYPE_UNKNOWN;
+ /* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
+ if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
+ interface_subclass == XB360_IFACE_SUBCLASS &&
+ (interface_protocol == XB360_IFACE_PROTOCOL ||
+ interface_protocol == XB360W_IFACE_PROTOCOL)) {
+
+ static const int SUPPORTED_VENDORS[] = {
+ 0x0079, /* GPD Win 2 */
+ 0x044f, /* Thrustmaster */
+ 0x045e, /* Microsoft */
+ 0x046d, /* Logitech */
+ 0x056e, /* Elecom */
+ 0x06a3, /* Saitek */
+ 0x0738, /* Mad Catz */
+ 0x07ff, /* Mad Catz */
+ 0x0e6f, /* PDP */
+ 0x0f0d, /* Hori */
+ 0x1038, /* SteelSeries */
+ 0x11c9, /* Nacon */
+ 0x12ab, /* Unknown */
+ 0x1430, /* RedOctane */
+ 0x146b, /* BigBen */
+ 0x1532, /* Razer Sabertooth */
+ 0x15e4, /* Numark */
+ 0x162e, /* Joytech */
+ 0x1689, /* Razer Onza */
+ 0x1bad, /* Harmonix */
+ 0x24c6, /* PowerA */
+ };
+
+ int i;
+ for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
+ if (vendor == SUPPORTED_VENDORS[i]) {
+ type = SDL_CONTROLLER_TYPE_XBOX360;
+ break;
+ }
}
+ }
- } else if (vendor == 0x0001 && product == 0x0001) {
- type = SDL_CONTROLLER_TYPE_UNKNOWN;
+ if (interface_number == 0 &&
+ interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
+ interface_subclass == XBONE_IFACE_SUBCLASS &&
+ interface_protocol == XBONE_IFACE_PROTOCOL) {
- } else {
- switch (GuessControllerType(vendor, product)) {
- case k_eControllerType_XBox360Controller:
- type = SDL_CONTROLLER_TYPE_XBOX360;
- break;
- case k_eControllerType_XBoxOneController:
- type = SDL_CONTROLLER_TYPE_XBOXONE;
- break;
- case k_eControllerType_PS3Controller:
- type = SDL_CONTROLLER_TYPE_PS3;
- break;
- case k_eControllerType_PS4Controller:
- type = SDL_CONTROLLER_TYPE_PS4;
- break;
- case k_eControllerType_SwitchProController:
- case k_eControllerType_SwitchInputOnlyController:
- type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
- break;
- default:
- type = SDL_CONTROLLER_TYPE_UNKNOWN;
- break;
+ static const int SUPPORTED_VENDORS[] = {
+ 0x045e, /* Microsoft */
+ 0x0738, /* Mad Catz */
+ 0x0e6f, /* PDP */
+ 0x0f0d, /* Hori */
+ 0x1532, /* Razer Wildcat */
+ 0x24c6, /* PowerA */
+ 0x2e24, /* Hyperkin */
+ };
+
+ int i;
+ for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
+ if (vendor == SUPPORTED_VENDORS[i]) {
+ type = SDL_CONTROLLER_TYPE_XBOXONE;
+ break;
+ }
}
}
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
- /* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
- static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
- static const int XB360_IFACE_SUBCLASS = 93;
- static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
- static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
- static const int XBONE_IFACE_SUBCLASS = 71;
- static const int XBONE_IFACE_PROTOCOL = 208;
-
- if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
- interface_subclass == XB360_IFACE_SUBCLASS &&
- (interface_protocol == XB360_IFACE_PROTOCOL ||
- interface_protocol == XB360W_IFACE_PROTOCOL)) {
-
- static const int SUPPORTED_VENDORS[] = {
- 0x0079, /* GPD Win 2 */
- 0x044f, /* Thrustmaster */
- 0x045e, /* Microsoft */
- 0x046d, /* Logitech */
- 0x056e, /* Elecom */
- 0x06a3, /* Saitek */
- 0x0738, /* Mad Catz */
- 0x07ff, /* Mad Catz */
- 0x0e6f, /* PDP */
- 0x0f0d, /* Hori */
- 0x1038, /* SteelSeries */
- 0x11c9, /* Nacon */
- 0x12ab, /* Unknown */
- 0x1430, /* RedOctane */
- 0x146b, /* BigBen */
- 0x1532, /* Razer Sabertooth */
- 0x15e4, /* Numark */
- 0x162e, /* Joytech */
- 0x1689, /* Razer Onza */
- 0x1bad, /* Harmonix */
- 0x24c6, /* PowerA */
- };
-
- int i;
- for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
- if (vendor == SUPPORTED_VENDORS[i]) {
- type = SDL_CONTROLLER_TYPE_XBOX360;
- break;
- }
+ if (vendor == 0x0000 && product == 0x0000) {
+ /* Some devices are only identifiable by their name */
+ if (SDL_strcmp(name, "Lic Pro Controller") == 0 ||
+ SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
+ SDL_strcmp(name, "Wireless Gamepad") == 0) {
+ /* HORI or PowerA Switch Pro Controller clone */
+ type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+ } else {
+ type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
- }
- if (interface_number == 0 &&
- interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
- interface_subclass == XBONE_IFACE_SUBCLASS &&
- interface_protocol == XBONE_IFACE_PROTOCOL) {
-
- static const int SUPPORTED_VENDORS[] = {
- 0x045e, /* Microsoft */
- 0x0738, /* Mad Catz */
- 0x0e6f, /* PDP */
- 0x0f0d, /* Hori */
- 0x1532, /* Razer Wildcat */
- 0x24c6, /* PowerA */
- 0x2e24, /* Hyperkin */
- };
-
- int i;
- for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
- if (vendor == SUPPORTED_VENDORS[i]) {
- type = SDL_CONTROLLER_TYPE_XBOXONE;
- break;
- }
+ } else if (vendor == 0x0001 && product == 0x0001) {
+ type = SDL_CONTROLLER_TYPE_UNKNOWN;
+
+ } else {
+ switch (GuessControllerType(vendor, product)) {
+ case k_eControllerType_XBox360Controller:
+ type = SDL_CONTROLLER_TYPE_XBOX360;
+ break;
+ case k_eControllerType_XBoxOneController:
+ type = SDL_CONTROLLER_TYPE_XBOXONE;
+ break;
+ case k_eControllerType_PS3Controller:
+ type = SDL_CONTROLLER_TYPE_PS3;
+ break;
+ case k_eControllerType_PS4Controller:
+ type = SDL_CONTROLLER_TYPE_PS4;
+ break;
+ case k_eControllerType_SwitchProController:
+ case k_eControllerType_SwitchInputOnlyController:
+ type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+ break;
+ default:
+ type = SDL_CONTROLLER_TYPE_UNKNOWN;
+ break;
}
}
}
diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h
index bcbbdce..f0a4333 100644
--- a/src/joystick/controller_type.h
+++ b/src/joystick/controller_type.h
@@ -172,6 +172,7 @@ static const ControllerDescription_t arrControllers[] = {
{ 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, 0x02a9 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (third party knockoff)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F310
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21e ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F510
@@ -463,7 +464,6 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x2f24, 0x11 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x53 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0xb7 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
- { MAKE_CONTROLLER_ID( 0x45e, 0x2a9 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x1004 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x1008 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c
index af22867..13dca5e 100644
--- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c
+++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c
@@ -47,7 +47,7 @@ HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType
{
const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
- if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x0719)) ||
+ if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719)) ||
(type == SDL_CONTROLLER_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) {
return SDL_TRUE;
}