diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 9b70172830..92a2db6536 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -745,6 +745,7 @@
+
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index ccdd889694..14ed1f7858 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -92,6 +92,7 @@
+
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index b90a327497..a408b6dd63 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -849,6 +849,7 @@
+
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 94c30d1382..c9b3d5cd19 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -1651,6 +1651,9 @@
joystick\hidapi
+
+ joystick\hidapi
+
joystick\hidapi
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index b81f01393f..20f152555e 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -572,6 +572,7 @@
F3FD042E2C9B755700824C4C /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F3FD042C2C9B755700824C4C /* SDL_hidapi_nintendo.h */; };
F3FD042F2C9B755700824C4C /* SDL_hidapi_steam_hori.c in Sources */ = {isa = PBXBuildFile; fileRef = F3FD042D2C9B755700824C4C /* SDL_hidapi_steam_hori.c */; };
FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); settings = {ATTRIBUTES = (Required, ); }; };
+ 000076D3980E0431F8620000 /* SDL_hidapi_xbox360bb.c in Sources */ = {isa = PBXBuildFile; fileRef = 0000E85E176D78EFBFDC0000 /* SDL_hidapi_xbox360bb.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -1182,6 +1183,7 @@
F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = ""; };
F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; };
FA73671C19A540EF004122E4 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
+ 0000E85E176D78EFBFDC0000 /* SDL_hidapi_xbox360bb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_hidapi_xbox360bb.c; path = SDL_hidapi_xbox360bb.c; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -2058,6 +2060,7 @@
A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */,
F3E6C3912EE9F20000A6B39E /* SDL_report_descriptor.h */,
F3E6C3922EE9F20000A6B39E /* SDL_report_descriptor.c */,
+ 0000E85E176D78EFBFDC0000 /* SDL_hidapi_xbox360bb.c */,
);
path = hidapi;
sourceTree = "";
@@ -3243,6 +3246,7 @@
00009183ED11C92F23FC0000 /* SDL_notification.c in Sources */,
0000FB5C9B8CE5929A250000 /* SDL_cocoanotification.m in Sources */,
0000AF1D2CED20010C2D0000 /* SDL_notificationevents.c in Sources */,
+ 000076D3980E0431F8620000 /* SDL_hidapi_xbox360bb.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index abb8567600..12356305a7 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -861,6 +861,7 @@ static const struct {
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT },
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT },
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_PRO },
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER },
};
static bool RequiresLibUSB(Uint16 vendor, Uint16 product, bool libusb_xbox)
diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c
index 8acc150c48..5a4c7cabe6 100644
--- a/src/hidapi/libusb/hid.c
+++ b/src/hidapi/libusb/hid.c
@@ -943,6 +943,7 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
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 xb360bb_iface_protocol = 4; /* Wireless */
static const int supported_vendors[] = {
0x0079, /* GPD Win 2 */
0x0351, /* CRKD */
@@ -982,7 +983,8 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
intf_desc->bInterfaceSubClass == xb360_iface_subclass &&
(intf_desc->bInterfaceProtocol == xb360_iface_protocol ||
- intf_desc->bInterfaceProtocol == xb360w_iface_protocol)) {
+ intf_desc->bInterfaceProtocol == xb360w_iface_protocol ||
+ intf_desc->bInterfaceProtocol == xb360bb_iface_protocol)) {
size_t i;
for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) {
if (vendor_id == supported_vendors[i]) {
diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index 5065e27726..f3e4686dc0 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ -1244,6 +1244,8 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
Uint8 sub_product = guid.data[15] & 0x1F;
SDL_CreateMappingStringForSInputGamepad(vendor, product, sub_product, version, face_style, mapping_string, sizeof(mapping_string));
+ } else if ((vendor == USB_VENDOR_MICROSOFT) && (product == USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER)) {
+ SDL_strlcat(mapping_string, "dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,a:b0,b:b1,x:b2,y:b3,back:b4,guide:b5,start:b6,misc1:b7", sizeof(mapping_string));
} else {
// All other gamepads have the standard set of 19 buttons and 6 axes
if (SDL_IsJoystickGameCube(vendor, product)) {
diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c
index bb28c79ca2..0d8cc00abc 100644
--- a/src/joystick/hidapi/SDL_hidapi_xbox360.c
+++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c
@@ -200,6 +200,10 @@ static bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device, co
// This is the wireless dongle, which talks a different protocol
return false;
}
+ if ((vendor_id == USB_VENDOR_MICROSOFT) && (product_id == USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER)) {
+ // This is the BigButton wireless receiver, which talks a different protocol
+ return false;
+ }
if (interface_number > 0) {
// This is the chatpad or other input interface, not the Xbox 360 interface
return false;
diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360bb.c b/src/joystick/hidapi/SDL_hidapi_xbox360bb.c
new file mode 100644
index 0000000000..e755c69697
--- /dev/null
+++ b/src/joystick/hidapi/SDL_hidapi_xbox360bb.c
@@ -0,0 +1,280 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2026 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_internal.h"
+
+#ifdef SDL_JOYSTICK_HIDAPI
+
+#include "../../SDL_hints_c.h"
+#include "../SDL_sysjoystick.h"
+#include "SDL_hidapijoystick_c.h"
+#include "SDL_hidapi_rumble.h"
+#include "SDL_hidapi_xbox360.h"
+
+#ifdef SDL_JOYSTICK_HIDAPI_XBOX360
+
+// Define this if you want to log all packets from the controller
+// #define DEBUG_XBOX_PROTOCOL
+
+#define MAX_CONTROLLERS 4
+
+enum
+{
+ SDL_GAMEPAD_BUTTON_XBOX360_BIG_BUTTON = SDL_GAMEPAD_BUTTON_START + 1,
+ SDL_GAMEPAD_NUM_XBOX360BB_BUTTONS,
+};
+
+typedef struct
+{
+ SDL_HIDAPI_Device *device;
+ SDL_JoystickID joysticks[MAX_CONTROLLERS];
+ Uint8 last_state[MAX_CONTROLLERS][USB_PACKET_LENGTH];
+ Uint64 last_packet[MAX_CONTROLLERS];
+} SDL_DriverXbox360BB_Context;
+
+static void HIDAPI_DriverXBOX360BB_RegisterHints(SDL_HintCallback callback, void *userdata)
+{
+ SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata);
+ SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata);
+}
+
+static void HIDAPI_DriverXBOX360BB_UnregisterHints(SDL_HintCallback callback, void *userdata)
+{
+ SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata);
+ SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata);
+}
+
+static bool HIDAPI_DriverXBOX360BB_IsEnabled(void)
+{
+ return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)));
+}
+
+static bool HIDAPI_DriverXBOX360BB_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
+{
+ return (vendor_id == USB_VENDOR_MICROSOFT) && (product_id == USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER);
+}
+
+static bool HIDAPI_DriverXBOX360BB_InitDevice(SDL_HIDAPI_Device *device)
+{
+ SDL_DriverXbox360BB_Context *ctx;
+ Uint8 i;
+
+ HIDAPI_SetDeviceName(device, "Xbox 360 Big Button Controller");
+
+ ctx = (SDL_DriverXbox360BB_Context *)SDL_calloc(1, sizeof(*ctx));
+ if (!ctx) {
+ return false;
+ }
+ ctx->device = device;
+
+ device->context = ctx;
+
+ for (i = 0; i < MAX_CONTROLLERS; ++i) {
+ HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
+ }
+
+ return true;
+}
+
+static int HIDAPI_DriverXBOX360BB_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
+{
+ return -1;
+}
+
+static void HIDAPI_DriverXBOX360BB_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
+{
+}
+
+static bool HIDAPI_DriverXBOX360BB_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
+{
+ SDL_DriverXbox360BB_Context *ctx = (SDL_DriverXbox360BB_Context *)device->context;
+ Uint8 i;
+
+ SDL_AssertJoysticksLocked();
+
+ for (i = 0; i < MAX_CONTROLLERS; ++i) {
+ if (joystick->instance_id == ctx->joysticks[i]) {
+ joystick->nbuttons = SDL_GAMEPAD_NUM_XBOX360BB_BUTTONS;
+ joystick->nhats = 1;
+ joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS;
+ return true;
+ }
+ }
+ return false; // Should never get here!
+}
+
+static bool HIDAPI_DriverXBOX360BB_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
+{
+ return SDL_Unsupported();
+}
+
+static bool HIDAPI_DriverXBOX360BB_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
+{
+ return SDL_Unsupported();
+}
+
+static Uint32 HIDAPI_DriverXBOX360BB_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
+{
+ return 0;
+}
+
+static bool HIDAPI_DriverXBOX360BB_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
+{
+ return SDL_Unsupported();
+}
+
+static bool HIDAPI_DriverXBOX360BB_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
+{
+ return SDL_Unsupported();
+}
+
+static bool HIDAPI_DriverXBOX360BB_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
+{
+ return SDL_Unsupported();
+}
+
+static void HIDAPI_DriverXBOX360BB_HandleStatePacket(SDL_DriverXbox360BB_Context *ctx, Uint8 *data, int size)
+{
+ Uint64 timestamp = SDL_GetTicksNS();
+ SDL_Joystick *joystick;
+ Uint8 i;
+
+ i = data[2];
+ SDL_assert(i < MAX_CONTROLLERS);
+ joystick = SDL_GetJoystickFromID(ctx->joysticks[i]);
+ ctx->last_packet[i] = timestamp;
+
+ if (ctx->last_state[i][3] != data[3]) {
+ Uint8 hat = 0;
+
+ if (data[3] & 0x01) {
+ hat |= SDL_HAT_UP;
+ }
+ if (data[3] & 0x02) {
+ hat |= SDL_HAT_DOWN;
+ }
+ if (data[3] & 0x04) {
+ hat |= SDL_HAT_LEFT;
+ }
+ if (data[3] & 0x08) {
+ hat |= SDL_HAT_RIGHT;
+ }
+ SDL_SendJoystickHat(timestamp, joystick, 0, hat);
+
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[3] & 0x10) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[3] & 0x20) != 0));
+ }
+
+ if (ctx->last_state[i][4] != data[4]) {
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[4] & 0x04) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_XBOX360_BIG_BUTTON, ((data[4] & 0x08) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[4] & 0x10) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[4] & 0x20) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[4] & 0x40) != 0));
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[4] & 0x80) != 0));
+ }
+
+ SDL_memcpy(ctx->last_state[i], data, SDL_min(size, sizeof(ctx->last_state[i])));
+}
+
+static void HIDAPI_DriverXBOX360BB_HandleReleaseEvents(SDL_DriverXbox360BB_Context *ctx)
+{
+ Uint64 timestamp = SDL_GetTicksNS();
+ Uint8 i;
+
+ // The receiver only sends packets when a button is down, handle our own release logic
+ for (i = 0; i < MAX_CONTROLLERS; ++i) {
+ // FIXME: Even when a button is continuously pressed, we get _huge_
+ // delays between packets. This is the smallest number I could get
+ // without erroneous button releases. Yeesh.
+ // -flibit
+ const int XBOXBB_BUTTON_RELEASE_TIMEOUT_MS = 120;
+ if (SDL_NS_TO_MS(timestamp - ctx->last_packet[i]) >= XBOXBB_BUTTON_RELEASE_TIMEOUT_MS) {
+ SDL_Joystick *joystick = SDL_GetJoystickFromID(ctx->joysticks[i]);
+ if (joystick) {
+ SDL_SendJoystickHat(timestamp, joystick, 0, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, 0);
+ SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_XBOX360_BIG_BUTTON, 0);
+ }
+ SDL_zero(ctx->last_state[i]);
+ ctx->last_packet[i] = timestamp;
+ }
+ }
+}
+
+static bool HIDAPI_DriverXBOX360BB_UpdateDevice(SDL_HIDAPI_Device *device)
+{
+ SDL_DriverXbox360BB_Context *ctx = (SDL_DriverXbox360BB_Context *)device->context;
+ Uint8 data[USB_PACKET_LENGTH];
+ int size;
+
+ while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
+#ifdef DEBUG_XBOX_PROTOCOL
+ HIDAPI_DumpPacket("Xbox 360 BigButton packet: size = %d", data, size);
+#endif
+ if (size == 5) {
+ HIDAPI_DriverXBOX360BB_HandleStatePacket(ctx, data, size);
+ }
+ }
+
+ HIDAPI_DriverXBOX360BB_HandleReleaseEvents(ctx);
+
+ return (size >= 0);
+}
+
+static void HIDAPI_DriverXBOX360BB_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
+{
+}
+
+static void HIDAPI_DriverXBOX360BB_FreeDevice(SDL_HIDAPI_Device *device)
+{
+}
+
+SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360BB = {
+ "SDL_JOYSTICK_HIDAPI_XBOX_360_BIGBUTTON",
+ true,
+ HIDAPI_DriverXBOX360BB_RegisterHints,
+ HIDAPI_DriverXBOX360BB_UnregisterHints,
+ HIDAPI_DriverXBOX360BB_IsEnabled,
+ HIDAPI_DriverXBOX360BB_IsSupportedDevice,
+ HIDAPI_DriverXBOX360BB_InitDevice,
+ HIDAPI_DriverXBOX360BB_GetDevicePlayerIndex,
+ HIDAPI_DriverXBOX360BB_SetDevicePlayerIndex,
+ HIDAPI_DriverXBOX360BB_UpdateDevice,
+ HIDAPI_DriverXBOX360BB_OpenJoystick,
+ HIDAPI_DriverXBOX360BB_RumbleJoystick,
+ HIDAPI_DriverXBOX360BB_RumbleJoystickTriggers,
+ HIDAPI_DriverXBOX360BB_GetJoystickCapabilities,
+ HIDAPI_DriverXBOX360BB_SetJoystickLED,
+ HIDAPI_DriverXBOX360BB_SendJoystickEffect,
+ HIDAPI_DriverXBOX360BB_SetJoystickSensorsEnabled,
+ HIDAPI_DriverXBOX360BB_CloseJoystick,
+ HIDAPI_DriverXBOX360BB_FreeDevice,
+};
+
+#endif // SDL_JOYSTICK_HIDAPI_XBOX360
+
+#endif // SDL_JOYSTICK_HIDAPI
diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c
index 81ea01e67c..7dc0fd7ae8 100644
--- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c
+++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c
@@ -67,6 +67,10 @@ static bool HIDAPI_DriverXbox360W_IsSupportedDevice(SDL_HIDAPI_Device *device, c
{
const int XB360W_IFACE_PROTOCOL = 129; // Wireless
+ if ((vendor_id == USB_VENDOR_MICROSOFT) && (product_id == USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER)) {
+ // This is the BigButton wireless receiver, which talks a different protocol
+ return false;
+ }
if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY2 || product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY1 || product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER) && interface_protocol == 0) ||
(type == SDL_GAMEPAD_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) {
return true;
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index d59b962b15..cd63c56c33 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -87,6 +87,7 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
#ifdef SDL_JOYSTICK_HIDAPI_XBOX360
&SDL_HIDAPI_DriverXbox360,
&SDL_HIDAPI_DriverXbox360W,
+ &SDL_HIDAPI_DriverXbox360BB,
#endif
#ifdef SDL_JOYSTICK_HIDAPI_GIP
&SDL_HIDAPI_DriverGIP,
diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h
index 59c62f6fe5..18b05ff95b 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick_c.h
+++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h
@@ -164,6 +164,7 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch2;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverWii;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W;
+extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360BB;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamHori;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamTriton;
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index 4d8f589d43..f81a906823 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -191,6 +191,7 @@
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY1 0x02a9
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY2 0x0291
+#define USB_PRODUCT_XBOX360_BIGBUTTON_RECEIVER 0x02a0
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE 0x0b0a
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH 0x0b0c
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE 0x0b21