Skip to content

Commit e12457d

Browse files
committed
Added support for the Xbox Series X controller to the HIDAPI driver
1 parent 7b5a0a9 commit e12457d

File tree

7 files changed

+49
-8
lines changed

7 files changed

+49
-8
lines changed

src/hidapi/libusb/hid.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -982,9 +982,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
982982
libusb_get_config_descriptor(usb_dev, 0, &conf_desc);
983983
if (!conf_desc)
984984
continue;
985-
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
985+
for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) {
986986
const struct libusb_interface *intf = &conf_desc->interface[j];
987-
for (k = 0; k < intf->num_altsetting; k++) {
987+
for (k = 0; k < intf->num_altsetting && !good_open; k++) {
988988
const struct libusb_interface_descriptor *intf_desc;
989989
intf_desc = &intf->altsetting[k];
990990
if (should_enumerate_interface(desc.idVendor, intf_desc)) {

src/joystick/SDL_gamecontroller.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,10 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
568568
/* All other controllers have the standard set of 19 buttons and 6 axes */
569569
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string));
570570

571-
if (SDL_IsJoystickXboxOneElite(vendor, product)) {
571+
if (SDL_IsJoystickXboxOneSeriesX(vendor, product)) {
572+
/* XBox One Series X Controllers have a share button under the guide button */
573+
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
574+
} else if (SDL_IsJoystickXboxOneElite(vendor, product)) {
572575
/* XBox One Elite Controllers have 4 back paddle buttons */
573576
SDL_strlcat(mapping_string, "paddle1:b15,paddle2:b17,paddle3:b16,paddle4:b18,", sizeof(mapping_string));
574577
} else if (SDL_IsJoystickSteamController(vendor, product)) {

src/joystick/SDL_joystick.c

+12
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,18 @@ SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id)
17931793
return SDL_FALSE;
17941794
}
17951795

1796+
SDL_bool
1797+
SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id)
1798+
{
1799+
if (vendor_id == USB_VENDOR_MICROSOFT) {
1800+
if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X ||
1801+
product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) {
1802+
return SDL_TRUE;
1803+
}
1804+
}
1805+
return SDL_FALSE;
1806+
}
1807+
17961808
SDL_bool
17971809
SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id)
17981810
{

src/joystick/SDL_joystick_c.h

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name
6464
/* Function to return whether a joystick is an Xbox One Elite controller */
6565
extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id);
6666

67+
/* Function to return whether a joystick is an Xbox One Series X controller */
68+
extern SDL_bool SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id);
69+
6770
/* Function to return whether a joystick is a PS4 controller */
6871
extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id);
6972

src/joystick/controller_type.h

+2
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ static const ControllerDescription_t arrControllers[] = {
323323
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with the RAWINPUT driver on Windows
324324
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad
325325
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth)
326+
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad
327+
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Elite Series X pad (Bluetooth)
326328
{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2
327329
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One
328330
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One

src/joystick/hidapi/SDL_hidapi_xboxone.c

+24-5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ typedef struct {
125125
Uint8 sequence;
126126
Uint8 last_state[USB_PACKET_LENGTH];
127127
SDL_bool has_paddles;
128+
SDL_bool has_share_button;
128129
} SDL_DriverXboxOne_Context;
129130

130131

@@ -148,6 +149,12 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
148149
return SDL_IsJoystickXboxOneElite(vendor_id, product_id);
149150
}
150151

152+
static SDL_bool
153+
ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id)
154+
{
155+
return SDL_IsJoystickXboxOneSeriesX(vendor_id, product_id);
156+
}
157+
151158
/* Return true if this controller sends the 0x02 "waiting for init" packet */
152159
static SDL_bool
153160
ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id)
@@ -299,9 +306,16 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
299306
ctx->input_ready = SDL_TRUE;
300307
ctx->sequence = 1;
301308
ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id);
309+
ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id);
302310

303311
/* Initialize the joystick capabilities */
304-
joystick->nbuttons = ctx->has_paddles ? 19 : 15;
312+
joystick->nbuttons = 15;
313+
if (ctx->has_share_button) {
314+
joystick->nbuttons += 1;
315+
}
316+
if (ctx->has_paddles) {
317+
joystick->nbuttons += 4;
318+
}
305319
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
306320
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
307321

@@ -380,6 +394,10 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev,
380394
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
381395
}
382396

397+
if (ctx->has_share_button && ctx->last_state[18] != data[18]) {
398+
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
399+
}
400+
383401
/* Xbox One S report is 18 bytes
384402
Xbox One Elite Series 1 report is 33 bytes, paddles in data[32], mode in data[32] & 0x10, both modes have mapped paddles by default
385403
Paddle bits:
@@ -434,10 +452,11 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev,
434452
}
435453

436454
if (ctx->last_state[paddle_index] != data[paddle_index]) {
437-
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 0, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED);
438-
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 1, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED);
439-
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 2, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED);
440-
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 3, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED);
455+
int nButton = SDL_CONTROLLER_BUTTON_MISC1 + ctx->has_share_button;
456+
SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED);
457+
SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED);
458+
SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED);
459+
SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED);
441460
}
442461
}
443462

src/joystick/usb_ids.h

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#define USB_PRODUCT_XBOX_ONE_S 0x02ea
5151
#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0
5252
#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd
53+
#define USB_PRODUCT_XBOX_ONE_SERIES_X 0x0b12
54+
#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH 0x0b13
5355

5456
#endif /* usb_ids_h_ */
5557

0 commit comments

Comments
 (0)