From 68d8fc5c7b7c645ba3906e9f67126e35c9955b73 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 Nov 2019 15:46:13 -0800 Subject: [PATCH] Added support for the Xbox One Elite Series 2 controller in wired mode --- src/joystick/hidapi/SDL_hidapi_xboxone.c | 108 ++--------------------- 1 file changed, 8 insertions(+), 100 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index d636762cb0bf4..e8d78b732a428 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -36,6 +36,13 @@ #define USB_PACKET_LENGTH 64 +/* + * This packet is required for Xbox One Elite Series 2 pad + */ +static const Uint8 xboxone_elite_series2_init[] = { + 0x04, 0x20, 0x01, 0x00 +}; + /* * This packet is required for all Xbox One pads with 2015 * or later firmware installed (or present from the factory). @@ -108,6 +115,7 @@ 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_series2_init, sizeof(xboxone_elite_series2_init) }, { 0x0000, 0x0000, xboxone_fw2015_init, sizeof(xboxone_fw2015_init) }, { 0x0e6f, 0x0246, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) }, { 0x0e6f, 0x0246, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) }, @@ -283,100 +291,6 @@ HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, hid_device *dev, S SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED); } -static void -HIDAPI_DriverXboxOne_HandleBluetoothStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) -{ - Sint16 axis; - - if (ctx->last_state[14] != data[14]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED); - } - if (ctx->last_state[15] != data[15]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED); - } - if (ctx->last_state[16] != data[16]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); - } - - if (ctx->last_state[13] != data[13]) { - SDL_bool dpad_up = SDL_FALSE; - SDL_bool dpad_down = SDL_FALSE; - SDL_bool dpad_left = SDL_FALSE; - SDL_bool dpad_right = SDL_FALSE; - - switch (data[13]) { - case 1: - dpad_up = SDL_TRUE; - break; - case 2: - dpad_up = SDL_TRUE; - dpad_right = SDL_TRUE; - break; - case 3: - dpad_right = SDL_TRUE; - break; - case 4: - dpad_right = SDL_TRUE; - dpad_down = SDL_TRUE; - break; - case 5: - dpad_down = SDL_TRUE; - break; - case 6: - dpad_left = SDL_TRUE; - dpad_down = SDL_TRUE; - break; - case 7: - dpad_left = SDL_TRUE; - break; - case 8: - dpad_up = SDL_TRUE; - dpad_left = SDL_TRUE; - break; - default: - break; - } - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); - } - - axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768; - if (axis == 32704) { - axis = 32767; - } - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); - axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768; - if (axis == 32704) { - axis = 32767; - } - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); - axis = *(Uint16*)(&data[1]) - 32768; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); - axis = *(Uint16*)(&data[3]) - 32768; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); - axis = *(Uint16*)(&data[5]) - 32768; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); - axis = *(Uint16*)(&data[7]) - 32768; - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); - - SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); -} - -static void -HIDAPI_DriverXboxOne_HandleBluetoothModePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) -{ - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); -} - static SDL_bool HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *context) { @@ -396,12 +310,6 @@ HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *conte data[16], data[17], data[18], data[19]); #endif switch (data[0]) { - case 0x01: - HIDAPI_DriverXboxOne_HandleBluetoothStatePacket(joystick, dev, ctx, data, size); - break; - case 0x02: - HIDAPI_DriverXboxOne_HandleBluetoothModePacket(joystick, dev, ctx, data, size); - break; case 0x20: HIDAPI_DriverXboxOne_HandleStatePacket(joystick, dev, ctx, data, size); break;