sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_hidapi_xboxone.c (41546B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 #include "../../SDL_internal.h"
     22 
     23 #ifdef SDL_JOYSTICK_HIDAPI
     24 
     25 #include "SDL_hints.h"
     26 #include "SDL_events.h"
     27 #include "SDL_timer.h"
     28 #include "SDL_joystick.h"
     29 #include "SDL_gamecontroller.h"
     30 #include "../SDL_sysjoystick.h"
     31 #include "SDL_hidapijoystick_c.h"
     32 #include "SDL_hidapi_rumble.h"
     33 
     34 
     35 #ifdef SDL_JOYSTICK_HIDAPI_XBOXONE
     36 
     37 /* Define this if you want verbose logging of the init sequence */
     38 /*#define DEBUG_JOYSTICK*/
     39 
     40 /* Define this if you want to log all packets from the controller */
     41 /*#define DEBUG_XBOX_PROTOCOL*/
     42 
     43 #define CONTROLLER_NEGOTIATION_TIMEOUT_MS   300
     44 #define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50
     45 
     46 
     47 /* Connect controller */
     48 static const Uint8 xboxone_init0[] = {
     49     0x04, 0x20, 0x00, 0x00
     50 };
     51 /* Start controller - extended? */
     52 static const Uint8 xboxone_init1[] = {
     53     0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
     54     0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
     55     0x00, 0x00, 0x00
     56 };
     57 /* Start controller with input */
     58 static const Uint8 xboxone_init2[] = {
     59     0x05, 0x20, 0x03, 0x01, 0x00
     60 };
     61 /* Enable LED */
     62 static const Uint8 xboxone_init3[] = {
     63     0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
     64 };
     65 /* Start input reports? */
     66 static const Uint8 xboxone_init4[] = {
     67     0x06, 0x20, 0x00, 0x02, 0x01, 0x00
     68 };
     69 /* Start rumble? */
     70 static const Uint8 xboxone_init5[] = {
     71     0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
     72     0x00, 0x00, 0xFF, 0x00, 0xEB
     73 };
     74 
     75 /*
     76  * This specifies the selection of init packets that a gamepad
     77  * will be sent on init *and* the order in which they will be
     78  * sent. The correct sequence number will be added when the
     79  * packet is going to be sent.
     80  */
     81 typedef struct {
     82     Uint16 vendor_id;
     83     Uint16 product_id;
     84     Uint16 exclude_vendor_id;
     85     Uint16 exclude_product_id;
     86     const Uint8 *data;
     87     int size;
     88     const Uint8 response[2];
     89 } SDL_DriverXboxOne_InitPacket;
     90 
     91 
     92 static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
     93     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xb0 } },
     94     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } },
     95     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
     96     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } },
     97 
     98     /* These next packets are required for third party controllers (PowerA, PDP, HORI),
     99        but aren't the correct protocol for Microsoft Xbox controllers.
    100      */
    101     { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } },
    102     { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } },
    103 };
    104 
    105 typedef enum {
    106     XBOX_ONE_INIT_STATE_START_NEGOTIATING = 0,
    107     XBOX_ONE_INIT_STATE_NEGOTIATING = 1,
    108     XBOX_ONE_INIT_STATE_PREPARE_INPUT = 2,
    109     XBOX_ONE_INIT_STATE_COMPLETE = 3
    110 } SDL_XboxOneInitState;
    111 
    112 typedef struct {
    113     Uint16 vendor_id;
    114     Uint16 product_id;
    115     SDL_bool bluetooth;
    116     SDL_XboxOneInitState init_state;
    117     int init_packet;
    118     Uint32 start_time;
    119     Uint8 sequence;
    120     Uint32 send_time;
    121     Uint8 last_state[USB_PACKET_LENGTH];
    122     SDL_bool has_guide_packet;
    123     SDL_bool has_paddles;
    124     SDL_bool has_trigger_rumble;
    125     SDL_bool has_share_button;
    126     Uint8 low_frequency_rumble;
    127     Uint8 high_frequency_rumble;
    128     Uint8 left_trigger_rumble;
    129     Uint8 right_trigger_rumble;
    130 } SDL_DriverXboxOne_Context;
    131 
    132 
    133 static SDL_bool
    134 IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id)
    135 {
    136     /* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */
    137     if (vendor_id == USB_VENDOR_MICROSOFT) {
    138         if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
    139             product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
    140             product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH ||
    141             product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) {
    142             return SDL_TRUE;
    143         }
    144     }
    145     return SDL_FALSE;
    146 }
    147 
    148 static SDL_bool
    149 ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
    150 {
    151     return SDL_IsJoystickXboxOneElite(vendor_id, product_id);
    152 }
    153 
    154 static SDL_bool
    155 ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id)
    156 {
    157     return SDL_IsJoystickXboxOneElite(vendor_id, product_id);
    158 }
    159 
    160 static SDL_bool
    161 ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id)
    162 {
    163     return SDL_IsJoystickXboxOneSeriesX(vendor_id, product_id);
    164 }
    165 
    166 static void
    167 SetInitState(SDL_DriverXboxOne_Context *ctx, SDL_XboxOneInitState state)
    168 {
    169 #ifdef DEBUG_JOYSTICK
    170     SDL_Log("Setting init state %d\n", state);
    171 #endif
    172     ctx->init_state = state;
    173 }
    174 
    175 static void
    176 SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size)
    177 {
    178 #ifdef __WIN32__
    179     /* The Windows driver is taking care of acks */
    180 #else
    181     if ((data[1] & 0x30) == 0x30) {
    182         Uint8 ack_packet[] = { 0x01, 0x20, data[2], 0x09, 0x00, data[0], 0x20, data[3], 0x00, 0x00, 0x00, 0x00, 0x00 };
    183 
    184         /* The initial ack needs 0x80 added to the response, for some reason */
    185         if (data[0] == 0x04 && data[1] == 0xF0) {
    186             ack_packet[11] = 0x80;
    187         }
    188 
    189 #ifdef DEBUG_XBOX_PROTOCOL
    190         HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
    191 #endif
    192         hid_write(device->dev, ack_packet, sizeof(ack_packet));
    193     }
    194 #endif /* __WIN32__ */
    195 }
    196 
    197 #if 0
    198 static SDL_bool
    199 SendSerialRequest(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
    200 {
    201     Uint8 serial_packet[] = { 0x1E, 0x30, 0x07, 0x01, 0x04 };
    202 
    203     ctx->send_time = SDL_GetTicks();
    204 
    205     /* Request the serial number
    206      * Sending this should be done only after the negotiation is complete.
    207      * It will cancel the announce packet if sent before that, and will be
    208      * ignored if sent during the negotiation.
    209      */
    210     if (SDL_HIDAPI_LockRumble() < 0 ||
    211         SDL_HIDAPI_SendRumbleAndUnlock(device, serial_packet, sizeof(serial_packet)) != sizeof(serial_packet)) {
    212         SDL_SetError("Couldn't send serial packet");
    213         return SDL_FALSE;
    214     }
    215     return SDL_TRUE;
    216 }
    217 #endif
    218 
    219 static SDL_bool
    220 ControllerNeedsNegotiation(SDL_DriverXboxOne_Context *ctx)
    221 {
    222     if (ctx->vendor_id == USB_VENDOR_PDP && ctx->product_id == 0x0246) {
    223         /* The PDP Rock Candy (PID 0x0246) doesn't send the announce packet on Linux for some reason */
    224         return SDL_TRUE;
    225     }
    226     return SDL_FALSE;
    227 }
    228 
    229 static SDL_bool
    230 SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
    231 {
    232     Uint16 vendor_id = ctx->vendor_id;
    233     Uint16 product_id = ctx->product_id;
    234     Uint8 init_packet[USB_PACKET_LENGTH];
    235 
    236     for ( ; ctx->init_packet < SDL_arraysize(xboxone_init_packets); ++ctx->init_packet) {
    237         const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[ctx->init_packet];
    238 
    239         if (packet->vendor_id && (vendor_id != packet->vendor_id)) {
    240             continue;
    241         }
    242 
    243         if (packet->product_id && (product_id != packet->product_id)) {
    244             continue;
    245         }
    246 
    247         if (packet->exclude_vendor_id && (vendor_id == packet->exclude_vendor_id)) {
    248             continue;
    249         }
    250 
    251         if (packet->exclude_product_id && (product_id == packet->exclude_product_id)) {
    252             continue;
    253         }
    254 
    255         SDL_memcpy(init_packet, packet->data, packet->size);
    256         if (init_packet[0] != 0x01) {
    257             init_packet[2] = ctx->sequence++;
    258         }
    259 #ifdef DEBUG_XBOX_PROTOCOL
    260         HIDAPI_DumpPacket("Xbox One sending INIT packet: size = %d", init_packet, packet->size);
    261 #endif
    262         ctx->send_time = SDL_GetTicks();
    263 
    264         if (SDL_HIDAPI_LockRumble() < 0 ||
    265             SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, packet->size) != packet->size) {
    266             SDL_SetError("Couldn't write Xbox One initialization packet");
    267             return SDL_FALSE;
    268         }
    269 
    270         if (packet->response[0]) {
    271             return SDL_TRUE;
    272         }
    273     }
    274 
    275     /* All done with the negotiation, prepare for input! */
    276     SetInitState(ctx, XBOX_ONE_INIT_STATE_PREPARE_INPUT);
    277 
    278     return SDL_TRUE;
    279 }
    280 
    281 static SDL_bool
    282 HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
    283 {
    284 #ifdef __LINUX__
    285     if (vendor_id == USB_VENDOR_POWERA && product_id == 0x541a) {
    286         /* The PowerA Mini controller, model 1240245-01, blocks while writing feature reports */
    287         return SDL_FALSE;
    288     }
    289 #endif
    290 #ifdef __MACOSX__
    291     /* Wired Xbox One controllers are handled by the 360Controller driver */
    292     if (!IsBluetoothXboxOneController(vendor_id, product_id)) {
    293         return SDL_FALSE;
    294     }
    295 #endif
    296     return (type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE;
    297 }
    298 
    299 static const char *
    300 HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
    301 {
    302     return NULL;
    303 }
    304 
    305 static SDL_bool
    306 HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device)
    307 {
    308     return HIDAPI_JoystickConnected(device, NULL);
    309 }
    310 
    311 static int
    312 HIDAPI_DriverXboxOne_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
    313 {
    314     return -1;
    315 }
    316 
    317 static void
    318 HIDAPI_DriverXboxOne_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
    319 {
    320 }
    321 
    322 static SDL_bool HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
    323 static void HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
    324 
    325 static SDL_bool
    326 HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
    327 {
    328     SDL_DriverXboxOne_Context *ctx;
    329 
    330     ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
    331     if (!ctx) {
    332         SDL_OutOfMemory();
    333         return SDL_FALSE;
    334     }
    335 
    336     device->dev = hid_open_path(device->path, 0);
    337     if (!device->dev) {
    338         SDL_free(ctx);
    339         SDL_SetError("Couldn't open %s", device->path);
    340         return SDL_FALSE;
    341     }
    342     device->context = ctx;
    343 
    344     ctx->vendor_id = device->vendor_id;
    345     ctx->product_id = device->product_id;
    346     ctx->bluetooth = IsBluetoothXboxOneController(device->vendor_id, device->product_id);
    347     ctx->start_time = SDL_GetTicks();
    348     ctx->sequence = 1;
    349     ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id);
    350     ctx->has_trigger_rumble = ControllerHasTriggerRumble(ctx->vendor_id, ctx->product_id);
    351     ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id);
    352 
    353     /* Assume that the controller is correctly initialized when we start */
    354     if (ControllerNeedsNegotiation(ctx)) {
    355         ctx->init_state = XBOX_ONE_INIT_STATE_START_NEGOTIATING;
    356     } else {
    357         ctx->init_state = XBOX_ONE_INIT_STATE_COMPLETE;
    358     }
    359 
    360 #ifdef DEBUG_JOYSTICK
    361     SDL_Log("Controller version: %d (0x%.4x)\n", device->version, device->version);
    362 #endif
    363 
    364     /* Initialize the joystick capabilities */
    365     joystick->nbuttons = 15;
    366     if (ctx->has_share_button) {
    367         joystick->nbuttons += 1;
    368     }
    369     if (ctx->has_paddles) {
    370         joystick->nbuttons += 4;
    371     }
    372     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
    373 
    374     if (!ctx->bluetooth) {
    375         joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
    376     }
    377 
    378     return SDL_TRUE;
    379 }
    380 
    381 static int
    382 HIDAPI_DriverXboxOne_UpdateRumble(SDL_HIDAPI_Device *device)
    383 {
    384     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
    385 
    386     if (ctx->bluetooth) {
    387         Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB };
    388 
    389         rumble_packet[2] = ctx->left_trigger_rumble;
    390         rumble_packet[3] = ctx->right_trigger_rumble;
    391         rumble_packet[4] = ctx->low_frequency_rumble;
    392         rumble_packet[5] = ctx->high_frequency_rumble;
    393 
    394         if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
    395             return SDL_SetError("Couldn't send rumble packet");
    396         }
    397     } else {
    398         Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB };
    399 
    400         rumble_packet[6] = ctx->left_trigger_rumble;
    401         rumble_packet[7] = ctx->right_trigger_rumble;
    402         rumble_packet[8] = ctx->low_frequency_rumble;
    403         rumble_packet[9] = ctx->high_frequency_rumble;
    404 
    405         if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
    406             return SDL_SetError("Couldn't send rumble packet");
    407         }
    408     }
    409     return 0;
    410 }
    411 
    412 static int
    413 HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    414 {
    415     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
    416 
    417     /* Magnitude is 1..100 so scale the 16-bit input here */
    418     ctx->low_frequency_rumble = low_frequency_rumble / 655;
    419     ctx->high_frequency_rumble = high_frequency_rumble / 655;
    420 
    421     return HIDAPI_DriverXboxOne_UpdateRumble(device);
    422 }
    423 
    424 static int
    425 HIDAPI_DriverXboxOne_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
    426 {
    427     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
    428 
    429     if (!ctx->has_trigger_rumble) {
    430         return SDL_Unsupported();
    431     }
    432 
    433     /* Magnitude is 1..100 so scale the 16-bit input here */
    434     ctx->left_trigger_rumble = left_rumble / 655;
    435     ctx->right_trigger_rumble = right_rumble / 655;
    436 
    437     return HIDAPI_DriverXboxOne_UpdateRumble(device);
    438 }
    439 
    440 static SDL_bool
    441 HIDAPI_DriverXboxOne_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
    442 {
    443     /* Doesn't have an RGB LED, so don't return true here */
    444     return SDL_FALSE;
    445 }
    446 
    447 static int
    448 HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
    449 {
    450     return SDL_Unsupported();
    451 }
    452 
    453 static int
    454 HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
    455 {
    456     return SDL_Unsupported();
    457 }
    458 
    459 static void
    460 HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    461 {
    462     Sint16 axis;
    463 
    464     if (ctx->last_state[4] != data[4]) {
    465         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[4] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    466         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[4] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    467         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[4] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    468         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[4] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    469         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[4] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
    470         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[4] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
    471     }
    472 
    473     if (ctx->last_state[5] != data[5]) {
    474         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[5] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    475         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[5] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    476         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[5] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    477         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[5] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    478         if (ctx->vendor_id == USB_VENDOR_RAZER && ctx->product_id == USB_PRODUCT_RAZER_ATROX) {
    479             /* The Razer Atrox has the right and left shoulder bits reversed */
    480             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    481             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    482         } else {
    483             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    484             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    485         }
    486         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[5] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
    487         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
    488     }
    489 
    490     if (ctx->has_share_button) {
    491         /* Version 1 of the firmware for Xbox One Series X */
    492         if (ctx->last_state[18] != data[18]) {
    493             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    494         }
    495 
    496         /* Version 2 of the firmware for Xbox One Series X */
    497         if (ctx->last_state[22] != data[22]) {
    498             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[22] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    499         }
    500     }
    501 
    502     /* Xbox One S report is 18 bytes
    503        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
    504         Paddle bits:
    505             P3: 0x01 (A)    P1: 0x02 (B)
    506             P4: 0x04 (X)    P2: 0x08 (Y)
    507        Xbox One Elite Series 2 report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default
    508         Paddle bits:
    509             P3: 0x04 (A)    P1: 0x01 (B)
    510             P4: 0x08 (X)    P2: 0x02 (Y)
    511     */
    512     if (ctx->has_paddles && (size == 33 || size == 38)) {
    513         int paddle_index;
    514         int button1_bit;
    515         int button2_bit;
    516         int button3_bit;
    517         int button4_bit;
    518         SDL_bool paddles_mapped;
    519 
    520         if (size == 33) {
    521             /* XBox One Elite Series 1 */
    522             paddle_index = 32;
    523             button1_bit = 0x02;
    524             button2_bit = 0x08;
    525             button3_bit = 0x01;
    526             button4_bit = 0x04;
    527 
    528             /* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */
    529             paddles_mapped = (SDL_memcmp(&data[4], &data[18], 14) != 0);
    530 
    531         } else /* if (size == 38) */ {
    532             /* XBox One Elite Series 2 */
    533             paddle_index = 18;
    534             button1_bit = 0x01;
    535             button2_bit = 0x02;
    536             button3_bit = 0x04;
    537             button4_bit = 0x08;
    538             paddles_mapped = (data[19] != 0);
    539         }
    540 #ifdef DEBUG_XBOX_PROTOCOL
    541         SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n",
    542             (data[paddle_index] & button1_bit) ? 1 : 0,
    543             (data[paddle_index] & button2_bit) ? 1 : 0,
    544             (data[paddle_index] & button3_bit) ? 1 : 0,
    545             (data[paddle_index] & button4_bit) ? 1 : 0,
    546             paddles_mapped ? "TRUE" : "FALSE"
    547         );
    548 #endif
    549 
    550         if (paddles_mapped) {
    551             /* Respect that the paddles are being used for other controls and don't pass them on to the app */
    552             data[paddle_index] = 0;
    553         }
    554 
    555         if (ctx->last_state[paddle_index] != data[paddle_index]) {
    556             int nButton = SDL_CONTROLLER_BUTTON_MISC1 + ctx->has_share_button; /* Next available button */
    557             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED);
    558             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED);
    559             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED);
    560             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED);
    561         }
    562     }
    563 
    564     axis = ((int)*(Sint16*)(&data[6]) * 64) - 32768;
    565     if (axis == 32704) {
    566         axis = 32767;
    567     }
    568     if (axis == -32768 && size == 30 && (data[22] & 0x80) != 0) {
    569         axis = 32767;
    570     }
    571     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
    572 
    573     axis = ((int)*(Sint16*)(&data[8]) * 64) - 32768;
    574     if (axis == -32768 && size == 30 && (data[22] & 0x40) != 0) {
    575         axis = 32767;
    576     }
    577     if (axis == 32704) {
    578         axis = 32767;
    579     }
    580     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
    581 
    582     axis = *(Sint16*)(&data[10]);
    583     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
    584     axis = *(Sint16*)(&data[12]);
    585     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis);
    586     axis = *(Sint16*)(&data[14]);
    587     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
    588     axis = *(Sint16*)(&data[16]);
    589     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis);
    590 
    591     SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
    592 }
    593 
    594 static void
    595 HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    596 {
    597     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    598 }
    599 
    600 /*
    601  * Xbox One S with firmware 3.1.1221 uses a 16 byte packet and the GUIDE button in a separate packet
    602  */
    603 static void
    604 HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    605 {
    606     if (ctx->last_state[14] != data[14]) {
    607         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    608         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    609         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    610         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    611         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    612         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    613         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
    614         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
    615     }
    616 
    617     if (ctx->last_state[15] != data[15]) {
    618         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    619         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    620     }
    621 
    622 }
    623 
    624 /*
    625  * Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux)
    626  * Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet
    627  * Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet
    628  * Xbox One Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17
    629  */
    630 static void
    631 HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    632 {
    633     if (ctx->last_state[14] != data[14]) {
    634         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    635         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    636         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    637         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    638         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
    639         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
    640     }
    641 
    642     if (ctx->last_state[15] != data[15]) {
    643         if (ctx->has_share_button) {
    644             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    645             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    646         } else if (!ctx->has_guide_packet) {
    647             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    648         }
    649         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    650         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    651         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
    652     }
    653 
    654     if (ctx->last_state[16] != data[16]) {
    655         if (ctx->has_share_button) {
    656             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    657         } else {
    658             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    659         }
    660     }
    661 
    662     /*
    663         Paddle bits:
    664             P3: 0x04 (A)    P1: 0x01 (B)
    665             P4: 0x08 (X)    P2: 0x02 (Y)
    666     */
    667     if (ctx->has_paddles && (size == 39 || size == 55)) {
    668         int paddle_index;
    669         int button1_bit;
    670         int button2_bit;
    671         int button3_bit;
    672         int button4_bit;
    673         SDL_bool paddles_mapped;
    674 
    675         if (size == 55) {
    676             /* Initial firmware for the Xbox Elite Series 2 controller */
    677             paddle_index = 33;
    678             button1_bit = 0x01;
    679             button2_bit = 0x02;
    680             button3_bit = 0x04;
    681             button4_bit = 0x08;
    682             paddles_mapped = (data[35] != 0);
    683         } else /* if (size == 39) */ {
    684             /* Updated firmware for the Xbox Elite Series 2 controller */
    685             paddle_index = 17;
    686             button1_bit = 0x01;
    687             button2_bit = 0x02;
    688             button3_bit = 0x04;
    689             button4_bit = 0x08;
    690             paddles_mapped = (data[19] != 0);
    691         }
    692 
    693 #ifdef DEBUG_XBOX_PROTOCOL
    694         SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n",
    695             (data[paddle_index] & button1_bit) ? 1 : 0,
    696             (data[paddle_index] & button2_bit) ? 1 : 0,
    697             (data[paddle_index] & button3_bit) ? 1 : 0,
    698             (data[paddle_index] & button4_bit) ? 1 : 0,
    699             paddles_mapped ? "TRUE" : "FALSE"
    700         );
    701 #endif
    702 
    703         if (paddles_mapped) {
    704             /* Respect that the paddles are being used for other controls and don't pass them on to the app */
    705             data[paddle_index] = 0;
    706         }
    707 
    708         if (ctx->last_state[paddle_index] != data[paddle_index]) {
    709             int nButton = SDL_CONTROLLER_BUTTON_MISC1; /* Next available button */
    710             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED);
    711             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED);
    712             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED);
    713             SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED);
    714         }
    715     }
    716 }
    717 
    718 static void
    719 HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    720 {
    721     Sint16 axis;
    722 
    723     if (size == 16) {
    724         /* Original Xbox One S, with separate report for guide button */
    725         HIDAPI_DriverXboxOneBluetooth_HandleButtons16(joystick, ctx, data, size);
    726     } else {
    727         HIDAPI_DriverXboxOneBluetooth_HandleButtons(joystick, ctx, data, size);
    728     }
    729 
    730     if (ctx->last_state[13] != data[13]) {
    731         SDL_bool dpad_up = SDL_FALSE;
    732         SDL_bool dpad_down = SDL_FALSE;
    733         SDL_bool dpad_left = SDL_FALSE;
    734         SDL_bool dpad_right = SDL_FALSE;
    735 
    736         switch (data[13]) {
    737         case 1:
    738             dpad_up = SDL_TRUE;
    739             break;
    740         case 2:
    741             dpad_up = SDL_TRUE;
    742             dpad_right = SDL_TRUE;
    743             break;
    744         case 3:
    745             dpad_right = SDL_TRUE;
    746             break;
    747         case 4:
    748             dpad_right = SDL_TRUE;
    749             dpad_down = SDL_TRUE;
    750             break;
    751         case 5:
    752             dpad_down = SDL_TRUE;
    753             break;
    754         case 6:
    755             dpad_left = SDL_TRUE;
    756             dpad_down = SDL_TRUE;
    757             break;
    758         case 7:
    759             dpad_left = SDL_TRUE;
    760             break;
    761         case 8:
    762             dpad_up = SDL_TRUE;
    763             dpad_left = SDL_TRUE;
    764             break;
    765         default:
    766             break;
    767         }
    768         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
    769         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
    770         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
    771         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
    772     }
    773 
    774     axis = (int)*(Uint16*)(&data[1]) - 0x8000;
    775     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
    776     axis = (int)*(Uint16*)(&data[3]) - 0x8000;
    777     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
    778     axis = (int)*(Uint16*)(&data[5]) - 0x8000;
    779     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
    780     axis = (int)*(Uint16*)(&data[7]) - 0x8000;
    781     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
    782 
    783     axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768;
    784     if (axis == 32704) {
    785         axis = 32767;
    786     }
    787     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
    788 
    789     axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
    790     if (axis == 32704) {
    791         axis = 32767;
    792     }
    793     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
    794 
    795     SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
    796 }
    797 
    798 static void
    799 HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    800 {
    801     ctx->has_guide_packet = SDL_TRUE;
    802     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    803 }
    804 
    805 static void
    806 HIDAPI_DriverXboxOneBluetooth_HandleBatteryPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    807 {
    808     Uint8 flags = data[1];
    809     SDL_bool on_usb = (((flags & 0x0C) >> 2) == 0);
    810 
    811     if (on_usb) {
    812         /* Does this ever happen? */
    813         SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
    814     } else {
    815         switch ((flags & 0x03)) {
    816         case 0:
    817             SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
    818             break;
    819         case 1:
    820             SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
    821             break;
    822         default: /* 2, 3 */
    823             SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
    824             break;
    825         }
    826     }
    827 }
    828 
    829 #ifdef SET_SERIAL_AFTER_OPEN
    830 static void
    831 HIDAPI_DriverXboxOne_HandleSerialIDPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
    832 {
    833     char serial[ 29 ];
    834     int i;
    835 
    836     for (i = 0; i < 14; ++i) {
    837         SDL_uitoa( data[6 + i], &serial[i * 2], 16 );
    838     }
    839     serial[i * 2] = '\0';
    840 
    841     if (!joystick->serial || SDL_strcmp(joystick->serial, serial) != 0) {
    842 #ifdef DEBUG_JOYSTICK
    843         SDL_Log("Setting serial number to %s\n", serial);
    844 #endif
    845         joystick->serial = SDL_strdup(serial);
    846     }
    847 }
    848 #endif /* SET_SERIAL_AFTER_OPEN */
    849 
    850 static SDL_bool
    851 HIDAPI_DriverXboxOne_UpdateInitState(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
    852 {
    853     SDL_XboxOneInitState prev_state;
    854     do
    855     {
    856         prev_state = ctx->init_state;
    857 
    858         switch (ctx->init_state) {
    859         case XBOX_ONE_INIT_STATE_START_NEGOTIATING:
    860 #ifdef __WIN32__
    861             /* The Windows driver is taking care of negotiation */
    862             SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
    863 #else
    864             SetInitState(ctx, XBOX_ONE_INIT_STATE_NEGOTIATING);
    865             ctx->init_packet = 0;
    866             if (!SendControllerInit(device, ctx)) {
    867                 return SDL_FALSE;
    868             }
    869 #endif
    870             break;
    871         case XBOX_ONE_INIT_STATE_NEGOTIATING:
    872             if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_NEGOTIATION_TIMEOUT_MS)) {
    873                 /* We haven't heard anything, let's move on */
    874 #ifdef DEBUG_JOYSTICK
    875                 SDL_Log("Init sequence %d timed out after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time));
    876 #endif
    877                 ++ctx->init_packet;
    878                 if (!SendControllerInit(device, ctx)) {
    879                     return SDL_FALSE;
    880                 }
    881             }
    882             break;
    883         case XBOX_ONE_INIT_STATE_PREPARE_INPUT:
    884             if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_PREPARE_INPUT_TIMEOUT_MS)) {
    885 #ifdef DEBUG_JOYSTICK
    886                 SDL_Log("Prepare input complete after %u ms\n", (SDL_GetTicks() - ctx->send_time));
    887 #endif
    888                 SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
    889             }
    890             break;
    891         case XBOX_ONE_INIT_STATE_COMPLETE:
    892             break;
    893         }
    894 
    895     } while (ctx->init_state != prev_state);
    896 
    897     return SDL_TRUE;
    898 }
    899 
    900 static SDL_bool
    901 HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
    902 {
    903     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
    904     Uint8 data[USB_PACKET_LENGTH];
    905     int size;
    906 
    907     while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
    908 #ifdef DEBUG_XBOX_PROTOCOL
    909         HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size);
    910 #endif
    911         if (ctx->bluetooth) {
    912             switch (data[0]) {
    913             case 0x01:
    914                 if (size >= 16) {
    915                     HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(joystick, ctx, data, size);
    916                 } else {
    917 #ifdef DEBUG_JOYSTICK
    918                     SDL_Log("Unknown Xbox One Bluetooth packet size: %d\n", size);
    919 #endif
    920                 }
    921                 break;
    922             case 0x02:
    923                 HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(joystick, ctx, data, size);
    924                 break;
    925             case 0x04:
    926                 HIDAPI_DriverXboxOneBluetooth_HandleBatteryPacket(joystick, ctx, data, size);
    927                 break;
    928             default:
    929 #ifdef DEBUG_JOYSTICK
    930                 SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
    931 #endif
    932                 break;
    933             }
    934         } else {
    935             switch (data[0]) {
    936             case 0x01:
    937                 /* ACK packet */
    938                 /* The data bytes are:
    939                     0x01 0x20 NN 0x09, where NN is the packet sequence
    940                     then 0x00
    941                     then a byte of the sequence being acked
    942                     then 0x20
    943                     then 16-bit LE value, the size of the previous packet payload when it's a single packet
    944                     then 4 bytes of unknown data, often all zero
    945                  */
    946                 break;
    947             case 0x02:
    948                 /* Controller is connected and waiting for initialization */
    949                 /* The data bytes are:
    950                    0x02 0x20 NN 0x1c, where NN is the packet sequence
    951                    then 6 bytes of wireless MAC address
    952                    then 2 bytes padding
    953                    then 16-bit VID
    954                    then 16-bit PID
    955                    then 16-bit firmware version quartet AA.BB.CC.DD
    956                         e.g. 0x05 0x00 0x05 0x00 0x51 0x0a 0x00 0x00
    957                              is firmware version 5.5.2641.0, and product version 0x0505 = 1285
    958                    then 8 bytes of unknown data
    959                 */
    960 #ifdef DEBUG_JOYSTICK
    961                 SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
    962 #endif
    963                 SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
    964                 break;
    965             case 0x03:
    966                 /* Controller heartbeat */
    967                 if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
    968                     SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
    969                 }
    970                 break;
    971             case 0x04:
    972                 /* Unknown chatty controller information, sent by both sides */
    973                 break;
    974             case 0x06:
    975                 /* Unknown chatty controller information, sent by both sides */
    976                 break;
    977             case 0x07:
    978                 HIDAPI_DriverXboxOne_HandleModePacket(joystick, ctx, data, size);
    979                 break;
    980             case 0x1E:
    981                 /* If the packet starts with this:
    982                     0x1E 0x30 0x07 0x10 0x04 0x00
    983                     then the next 14 bytes are the controller serial number
    984                         e.g. 0x30 0x39 0x37 0x31 0x32 0x33 0x33 0x32 0x33 0x35 0x34 0x30 0x33 0x36
    985                         is serial number "3039373132333332333534303336"
    986 
    987                    The controller sends that in response to this request:
    988                     0x1E 0x30 0x07 0x01 0x04
    989                 */
    990 #ifdef SET_SERIAL_AFTER_OPEN
    991                 if (size == 20 && data[3] == 0x10) {
    992                     HIDAPI_DriverXboxOne_HandleSerialIDPacket(joystick, ctx, data, size);
    993                 }
    994 #endif
    995                 break;
    996             case 0x20:
    997                 if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
    998                     SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
    999 
   1000                     /* Ignore the first input, it may be spurious */
   1001 #ifdef DEBUG_JOYSTICK
   1002                     SDL_Log("Controller ignoring spurious input\n");
   1003 #endif
   1004                     break;
   1005                 }
   1006                 HIDAPI_DriverXboxOne_HandleStatePacket(joystick, ctx, data, size);
   1007                 break;
   1008             default:
   1009 #ifdef DEBUG_JOYSTICK
   1010                 SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
   1011 #endif
   1012                 break;
   1013             }
   1014 
   1015             SendAckIfNeeded(device, data, size);
   1016 
   1017             if (ctx->init_state == XBOX_ONE_INIT_STATE_NEGOTIATING) {
   1018                 const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[ctx->init_packet];
   1019 
   1020                 if (size >= 4 && data[0] == packet->response[0] && data[1] == packet->response[1]) {
   1021 #ifdef DEBUG_JOYSTICK
   1022                     SDL_Log("Init sequence %d got response after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time));
   1023 #endif
   1024                     ++ctx->init_packet;
   1025                     SendControllerInit(device, ctx);
   1026                 }
   1027             }
   1028         }
   1029     }
   1030 
   1031     HIDAPI_DriverXboxOne_UpdateInitState(device, ctx);
   1032 
   1033     if (size < 0) {
   1034         /* Read error, device is disconnected */
   1035         HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   1036     }
   1037     return (size >= 0);
   1038 }
   1039 
   1040 static SDL_bool
   1041 HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
   1042 {
   1043     SDL_Joystick *joystick = NULL;
   1044 
   1045     if (device->num_joysticks > 0) {
   1046         joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
   1047     }
   1048     if (!joystick) {
   1049         return SDL_FALSE;
   1050     }
   1051     return HIDAPI_DriverXboxOne_UpdateJoystick(device, joystick);
   1052 }
   1053 
   1054 static void
   1055 HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   1056 {
   1057     hid_close(device->dev);
   1058     device->dev = NULL;
   1059 
   1060     SDL_free(device->context);
   1061     device->context = NULL;
   1062 }
   1063 
   1064 static void
   1065 HIDAPI_DriverXboxOne_FreeDevice(SDL_HIDAPI_Device *device)
   1066 {
   1067 }
   1068 
   1069 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
   1070 {
   1071     SDL_HINT_JOYSTICK_HIDAPI_XBOX,
   1072     SDL_TRUE,
   1073     HIDAPI_DriverXboxOne_IsSupportedDevice,
   1074     HIDAPI_DriverXboxOne_GetDeviceName,
   1075     HIDAPI_DriverXboxOne_InitDevice,
   1076     HIDAPI_DriverXboxOne_GetDevicePlayerIndex,
   1077     HIDAPI_DriverXboxOne_SetDevicePlayerIndex,
   1078     HIDAPI_DriverXboxOne_UpdateDevice,
   1079     HIDAPI_DriverXboxOne_OpenJoystick,
   1080     HIDAPI_DriverXboxOne_RumbleJoystick,
   1081     HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
   1082     HIDAPI_DriverXboxOne_HasJoystickLED,
   1083     HIDAPI_DriverXboxOne_SetJoystickLED,
   1084     HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
   1085     HIDAPI_DriverXboxOne_CloseJoystick,
   1086     HIDAPI_DriverXboxOne_FreeDevice,
   1087 };
   1088 
   1089 #endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */
   1090 
   1091 #endif /* SDL_JOYSTICK_HIDAPI */
   1092 
   1093 /* vi: set ts=4 sw=4 expandtab: */