Send the full Xbox One controller sequence for Microsoft controllers This switches Bluetooth controllers back into USB report mode for the latest Xbox One S and Xbox One Elite Series 2 firmware
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
diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c
index 149ed64..5e8437a 100644
--- a/src/joystick/hidapi/SDL_hidapi_xboxone.c
+++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c
@@ -42,26 +42,26 @@
/* This is the full init sequence for the Xbox One Elite Series 2 controller.
Normally it isn't needed, but this switches the controller back to wired report mode after being in Bluetooth mode.
*/
-static const Uint8 xboxone_elite_init0[] = {
+static const Uint8 xboxone_ms_init0[] = {
0x04, 0x20, 0x01, 0x00
};
-static const Uint8 xboxone_elite_init1[] = {
+static const Uint8 xboxone_ms_init1[] = {
0x01, 0x20, 0x28, 0x09, 0x00, 0x04, 0x20, 0x3A,
0x00, 0x00, 0x00, 0x31, 0x01
};
-static const Uint8 xboxone_elite_init2[] = {
+static const Uint8 xboxone_ms_init2[] = {
0x01, 0x20, 0x28, 0x09, 0x00, 0x04, 0x20, 0x6B,
0x01, 0x00, 0x00, 0x00, 0x00
};
-static const Uint8 xboxone_elite_init3[] = {
+static const Uint8 xboxone_ms_init3[] = {
0x05, 0x20, 0x02, 0x0F, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
-static const Uint8 xboxone_elite_init4[] = {
+static const Uint8 xboxone_ms_init4[] = {
0x05, 0x20, 0x03, 0x01, 0x00
};
-static const Uint8 xboxone_elite_init5[] = {
+static const Uint8 xboxone_ms_init5[] = {
0x0A, 0x20, 0x04, 0x03, 0x00, 0x01, 0x14
};
@@ -145,12 +145,12 @@ typedef struct {
static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
{ 0x0e6f, 0x0165, xboxone_hori_init, sizeof(xboxone_hori_init) },
{ 0x0f0d, 0x0067, xboxone_hori_init, sizeof(xboxone_hori_init) },
- { 0x045e, 0x0b00, xboxone_elite_init0, sizeof(xboxone_elite_init0) },
- { 0x045e, 0x0b00, xboxone_elite_init1, sizeof(xboxone_elite_init1) },
- { 0x045e, 0x0b00, xboxone_elite_init2, sizeof(xboxone_elite_init2) },
- { 0x045e, 0x0b00, xboxone_elite_init3, sizeof(xboxone_elite_init3) },
- { 0x045e, 0x0b00, xboxone_elite_init4, sizeof(xboxone_elite_init4) },
- { 0x045e, 0x0b00, xboxone_elite_init5, sizeof(xboxone_elite_init5) },
+ { 0x045e, 0x0000, xboxone_ms_init0, sizeof(xboxone_ms_init0) },
+ { 0x045e, 0x0000, xboxone_ms_init1, sizeof(xboxone_ms_init1) },
+ { 0x045e, 0x0000, xboxone_ms_init2, sizeof(xboxone_ms_init2) },
+ { 0x045e, 0x0000, xboxone_ms_init3, sizeof(xboxone_ms_init3) },
+ { 0x045e, 0x0000, xboxone_ms_init4, sizeof(xboxone_ms_init4) },
+ { 0x045e, 0x0000, xboxone_ms_init5, sizeof(xboxone_ms_init5) },
{ 0x0000, 0x0000, xboxone_fw2015_init, sizeof(xboxone_fw2015_init) },
{ 0x0000, 0x0000, xboxone_led_enable, sizeof(xboxone_led_enable) },
{ 0x0e6f, 0x0000, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
@@ -175,31 +175,36 @@ IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id)
{
/* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */
const Uint16 USB_VENDOR_MICROSOFT = 0x045e;
- const Uint16 USB_PRODUCT_XBOX_ONE_S_REV1 = 0x02e0;
- const Uint16 USB_PRODUCT_XBOX_ONE_S_REV2 = 0x02fd;
- const Uint16 USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 = 0x0b05;
+ const Uint16 USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH = 0x02e0;
+ const Uint16 USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH = 0x02fd;
+ const Uint16 USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH = 0x0b05;
if (vendor_id == USB_VENDOR_MICROSOFT) {
- if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1 ||
- product_id == USB_PRODUCT_XBOX_ONE_S_REV2 ||
- product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2) {
+ if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
+ product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
+ product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
+/* Return true if this controller sends the 0x02 "waiting for init" packet */
static SDL_bool
-ControllerSilentUntilInit(Uint16 vendor_id, Uint16 product_id)
+ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id)
{
- /* Return true if this controller doesn't send the 0x02 "waiting for init" packet */
- const Uint16 USB_VENDOR_PDP = 0x0e6f;
- const Uint16 USB_VENDOR_POWERA = 0x24c6;
+ const Uint16 USB_VENDOR_HYPERKIN = 0x2e24;
- if (vendor_id == USB_VENDOR_PDP || vendor_id == USB_VENDOR_POWERA) {
+ if (vendor_id == USB_VENDOR_HYPERKIN) {
+ /* The Hyperkin controllers always send 0x02 when waiting for init,
+ and the Hyperkin Duke plays an Xbox startup animation, so we want
+ to make sure we don't send the init sequence if it isn't needed.
+ */
return SDL_TRUE;
+ } else {
+ /* Other controllers may or may not send 0x02, but it doesn't hurt */
+ return SDL_FALSE;
}
- return SDL_FALSE;
}
static SDL_bool
@@ -420,7 +425,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
return SDL_FALSE;
}
- if (!ctx->initialized && ControllerSilentUntilInit(device->vendor_id, device->product_id)) {
+ if (!ctx->initialized && !ControllerSendsWaitingForInit(device->vendor_id, device->product_id)) {
if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
if (!SendControllerInit(device->dev, ctx)) {
HIDAPI_JoystickDisconnected(device, joystick->instance_id);