src/joystick/hidapi/SDL_hidapi_xboxone.c
author Manuel Alfayate Corchete
Thu, 22 Oct 2020 19:51:57 +0200
changeset 14191 7bb6793cd70f
parent 13767 671d8b2548b3
permissions -rw-r--r--
kmsdrm: Add comment about KMSDRM_VideoQuit() changes.
     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 to log all packets from the controller */
    38 /*#define DEBUG_XBOX_PROTOCOL*/
    39 
    40 /* The amount of time to wait after hotplug to send controller init sequence */
    41 #define CONTROLLER_INIT_DELAY_MS    1500 /* 475 for Xbox One S, 1275 for the PDP Battlefield 1 */
    42 
    43 /* The amount of time to wait after init for valid input */
    44 #define CONTROLLER_INPUT_DELAY_MS   50  /* 42 for Razer Wolverine Ultimate */
    45 
    46 /* Connect controller */
    47 static const Uint8 xboxone_init0[] = {
    48     0x04, 0x20, 0x00, 0x00
    49 };
    50 /* Initial ack */
    51 static const Uint8 xboxone_init1[] = {
    52     0x01, 0x20, 0x01, 0x09, 0x00, 0x04, 0x20, 0x3a,
    53     0x00, 0x00, 0x00, 0x80, 0x00
    54 };
    55 /* Start controller - extended? */
    56 static const Uint8 xboxone_init2[] = {
    57     0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
    58     0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
    59     0x00, 0x00, 0x00
    60 };
    61 /* Start controller with input */
    62 static const Uint8 xboxone_init3[] = {
    63     0x05, 0x20, 0x03, 0x01, 0x00
    64 };
    65 /* Enable LED */
    66 static const Uint8 xboxone_init4[] = {
    67     0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
    68 };
    69 /* Start input reports? */
    70 static const Uint8 xboxone_init5[] = {
    71     0x06, 0x20, 0x00, 0x02, 0x01, 0x00
    72 };
    73 /* Start rumble? */
    74 static const Uint8 xboxone_init6[] = {
    75     0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
    76     0x00, 0x00, 0xFF, 0x00, 0xEB
    77 };
    78 
    79 /*
    80  * This specifies the selection of init packets that a gamepad
    81  * will be sent on init *and* the order in which they will be
    82  * sent. The correct sequence number will be added when the
    83  * packet is going to be sent.
    84  */
    85 typedef struct {
    86     Uint16 vendor_id;
    87     Uint16 product_id;
    88     Uint16 exclude_vendor_id;
    89     Uint16 exclude_product_id;
    90     const Uint8 *data;
    91     int size;
    92     const Uint8 response[2];
    93 } SDL_DriverXboxOne_InitPacket;
    94 
    95 
    96 static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
    97     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xf0 } },
    98     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x04, 0xb0 } },
    99     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
   100     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } },
   101     { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } },
   102 
   103     /* These next packets are required for third party controllers (PowerA, PDP, HORI),
   104        but aren't the correct protocol for Microsoft Xbox controllers.
   105      */
   106     { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } },
   107     { 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init6, sizeof(xboxone_init6), { 0x00, 0x00 } },
   108 };
   109 
   110 typedef enum {
   111     XBOX_ONE_WIRELESS_PROTOCOL_UNKNOWN,
   112     XBOX_ONE_WIRELESS_PROTOCOL_V1,
   113     XBOX_ONE_WIRELESS_PROTOCOL_V2,
   114 } SDL_XboxOneWirelessProtocol;
   115 
   116 typedef struct {
   117     Uint16 vendor_id;
   118     Uint16 product_id;
   119     SDL_bool bluetooth;
   120     SDL_XboxOneWirelessProtocol wireless_protocol;
   121     SDL_bool initialized;
   122     SDL_bool input_ready;
   123     Uint32 start_time;
   124     Uint32 initialized_time;
   125     Uint8 sequence;
   126     Uint8 last_state[USB_PACKET_LENGTH];
   127     SDL_bool has_paddles;
   128 } SDL_DriverXboxOne_Context;
   129 
   130 
   131 #ifdef DEBUG_XBOX_PROTOCOL
   132 static void
   133 DumpPacket(const char *prefix, Uint8 *data, int size)
   134 {
   135     int i;
   136     char *buffer;
   137     size_t length = SDL_strlen(prefix) + 11*(USB_PACKET_LENGTH/8) + (5*USB_PACKET_LENGTH) + 1 + 1;
   138 
   139     buffer = (char *)SDL_malloc(length);
   140     SDL_snprintf(buffer, length, prefix, size);
   141     for (i = 0; i < size; ++i) {
   142         if ((i % 8) == 0) {
   143             SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), "\n%.2d:      ", i);
   144         }
   145         SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), " 0x%.2x", data[i]);
   146     }
   147     SDL_strlcat(buffer, "\n", length);
   148     SDL_Log("%s", buffer);
   149     SDL_free(buffer);
   150 }
   151 #endif /* DEBUG_XBOX_PROTOCOL */
   152 
   153 static SDL_bool
   154 IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id)
   155 {
   156     /* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */
   157     if (vendor_id == USB_VENDOR_MICROSOFT) {
   158         if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
   159             product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
   160             product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) {
   161             return SDL_TRUE;
   162         }
   163     }
   164     return SDL_FALSE;
   165 }
   166 
   167 static SDL_bool
   168 ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
   169 {
   170     if (vendor_id == USB_VENDOR_MICROSOFT) {
   171         if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 ||
   172             product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2) {
   173             return SDL_TRUE;
   174         }
   175     }
   176     return SDL_FALSE;
   177 }
   178 
   179 /* Return true if this controller sends the 0x02 "waiting for init" packet */
   180 static SDL_bool
   181 ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id)
   182 {
   183     if (vendor_id == USB_VENDOR_HYPERKIN) {
   184         /* The Hyperkin controllers always send 0x02 when waiting for init,
   185            and the Hyperkin Duke plays an Xbox startup animation, so we want
   186            to make sure we don't send the init sequence if it isn't needed.
   187         */
   188         return SDL_TRUE;
   189     }
   190     if (vendor_id == USB_VENDOR_PDP) {
   191         /* The PDP Rock Candy (PID 0x0246) doesn't send 0x02 on Linux for some reason */
   192         return SDL_FALSE;
   193     }
   194 
   195     /* It doesn't hurt to reinit, especially if a driver has misconfigured the controller */
   196     /*return SDL_TRUE;*/
   197     return SDL_FALSE;
   198 }
   199 
   200 static SDL_bool
   201 SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
   202 {
   203     Uint16 vendor_id = ctx->vendor_id;
   204     Uint16 product_id = ctx->product_id;
   205     int i;
   206     Uint8 init_packet[USB_PACKET_LENGTH];
   207 
   208     for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
   209         const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
   210 
   211         if (packet->vendor_id && (vendor_id != packet->vendor_id)) {
   212             continue;
   213         }
   214 
   215         if (packet->product_id && (product_id != packet->product_id)) {
   216             continue;
   217         }
   218 
   219         if (packet->exclude_vendor_id && (vendor_id == packet->exclude_vendor_id)) {
   220             continue;
   221         }
   222 
   223         if (packet->exclude_product_id && (product_id == packet->exclude_product_id)) {
   224             continue;
   225         }
   226 
   227         SDL_memcpy(init_packet, packet->data, packet->size);
   228         if (init_packet[0] != 0x01) {
   229             init_packet[2] = ctx->sequence++;
   230         }
   231         if (hid_write(device->dev, init_packet, packet->size) != packet->size) {
   232             SDL_SetError("Couldn't write Xbox One initialization packet");
   233             return SDL_FALSE;
   234         }
   235 
   236         if (packet->response[0]) {
   237             const Uint32 RESPONSE_TIMEOUT_MS = 100;
   238             Uint32 start = SDL_GetTicks();
   239             SDL_bool got_response = SDL_FALSE;
   240 
   241             while (!got_response && !SDL_TICKS_PASSED(SDL_GetTicks(), start + RESPONSE_TIMEOUT_MS)) {
   242                 Uint8 data[USB_PACKET_LENGTH];
   243                 int size;
   244 
   245                 while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
   246 #ifdef DEBUG_XBOX_PROTOCOL
   247                     DumpPacket("Xbox One INIT packet: size = %d", data, size);
   248 #endif
   249                     if (size >= 2 && data[0] == packet->response[0] && data[1] == packet->response[1]) {
   250                         got_response = SDL_TRUE;
   251                     }
   252                 }
   253             }
   254 #ifdef DEBUG_XBOX_PROTOCOL
   255             SDL_Log("Init sequence %d got response after %u ms: %s\n", i, (SDL_GetTicks() - start), got_response ? "TRUE" : "FALSE");
   256 #endif
   257         }
   258     }
   259     return SDL_TRUE;
   260 }
   261 
   262 static SDL_bool
   263 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)
   264 {
   265 #ifdef __LINUX__
   266     if (vendor_id == USB_VENDOR_POWERA && product_id == 0x541a) {
   267         /* The PowerA Mini controller, model 1240245-01, blocks while writing feature reports */
   268         return SDL_FALSE;
   269     }
   270 #endif
   271 #ifdef __MACOSX__
   272     /* Wired Xbox One controllers are handled by the 360Controller driver */
   273     if (!IsBluetoothXboxOneController(vendor_id, product_id)) {
   274         return SDL_FALSE;
   275     }
   276 #endif
   277     return (type == SDL_CONTROLLER_TYPE_XBOXONE);
   278 }
   279 
   280 static const char *
   281 HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
   282 {
   283     return NULL;
   284 }
   285 
   286 static SDL_bool
   287 HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device)
   288 {
   289     return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
   290 }
   291 
   292 static int
   293 HIDAPI_DriverXboxOne_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
   294 {
   295     return -1;
   296 }
   297 
   298 static void
   299 HIDAPI_DriverXboxOne_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
   300 {
   301 }
   302 
   303 static SDL_bool
   304 HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   305 {
   306     SDL_DriverXboxOne_Context *ctx;
   307 
   308     ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
   309     if (!ctx) {
   310         SDL_OutOfMemory();
   311         return SDL_FALSE;
   312     }
   313 
   314     device->dev = hid_open_path(device->path, 0);
   315     if (!device->dev) {
   316         SDL_free(ctx);
   317         SDL_SetError("Couldn't open %s", device->path);
   318         return SDL_FALSE;
   319     }
   320     device->context = ctx;
   321 
   322     ctx->vendor_id = device->vendor_id;
   323     ctx->product_id = device->product_id;
   324     ctx->bluetooth = IsBluetoothXboxOneController(device->vendor_id, device->product_id);
   325     ctx->initialized = ctx->bluetooth ? SDL_TRUE : SDL_FALSE;
   326     ctx->start_time = SDL_GetTicks();
   327     ctx->input_ready = SDL_TRUE;
   328     ctx->sequence = 1;
   329     ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id);
   330 
   331     /* Initialize the joystick capabilities */
   332     joystick->nbuttons = ctx->has_paddles ? SDL_CONTROLLER_BUTTON_MAX : (SDL_CONTROLLER_BUTTON_MAX + 4);
   333     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
   334     joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
   335 
   336     return SDL_TRUE;
   337 }
   338 
   339 static int
   340 HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   341 {
   342     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
   343 
   344     if (ctx->bluetooth) {
   345         Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 };
   346 
   347         rumble_packet[4] = (low_frequency_rumble >> 8);
   348         rumble_packet[5] = (high_frequency_rumble >> 8);
   349 
   350         if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   351             return SDL_SetError("Couldn't send rumble packet");
   352         }
   353     } else {
   354         Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
   355 
   356         /* Magnitude is 1..100 so scale the 16-bit input here */
   357         rumble_packet[8] = low_frequency_rumble / 655;
   358         rumble_packet[9] = high_frequency_rumble / 655;
   359 
   360         if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   361             return SDL_SetError("Couldn't send rumble packet");
   362         }
   363     }
   364     return 0;
   365 }
   366 
   367 static void
   368 HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
   369 {
   370     Sint16 axis;
   371 
   372     if (ctx->last_state[4] != data[4]) {
   373         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[4] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
   374         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[4] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
   375         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[4] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   376         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[4] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
   377         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[4] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
   378         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[4] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
   379     }
   380 
   381     if (ctx->last_state[5] != data[5]) {
   382         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[5] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   383         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[5] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
   384         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[5] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
   385         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[5] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
   386         if (ctx->vendor_id == USB_VENDOR_RAZER && ctx->product_id == USB_PRODUCT_RAZER_ATROX) {
   387             /* The Razer Atrox has the right and left shoulder bits reversed */
   388             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
   389             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   390         } else {
   391             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   392             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
   393         }
   394         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[5] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
   395         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
   396     }
   397 
   398     /* Xbox One S report is 18 bytes
   399        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
   400         Paddle bits:
   401             UL: 0x01 (A)    UR: 0x02 (B)
   402             LL: 0x04 (X)    LR: 0x08 (Y)
   403        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
   404         Paddle bits:
   405             UL: 0x04 (A)    UR: 0x01 (B)
   406             LL: 0x08 (X)    LR: 0x02 (Y)
   407     */
   408     if (ctx->has_paddles && (size == 33 || size == 38)) {
   409         int paddle_index;
   410         int button1_bit;
   411         int button2_bit;
   412         int button3_bit;
   413         int button4_bit;
   414         SDL_bool paddles_mapped;
   415 
   416         if (size == 33) {
   417             /* XBox One Elite Series 1 */
   418             paddle_index = 32;
   419             button1_bit = 0x01;
   420             button2_bit = 0x02;
   421             button3_bit = 0x04;
   422             button4_bit = 0x08;
   423 
   424             /* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */
   425             paddles_mapped = (SDL_memcmp(&data[4], &data[18], 14) != 0);
   426 
   427         } else /* if (size == 38) */ {
   428             /* XBox One Elite Series 2 */
   429             paddle_index = 18;
   430             button1_bit = 0x04;
   431             button2_bit = 0x01;
   432             button3_bit = 0x08;
   433             button4_bit = 0x02;
   434             paddles_mapped = (data[19] != 0);
   435         }
   436 #ifdef DEBUG_XBOX_PROTOCOL
   437         SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n",
   438             (data[paddle_index] & button1_bit) ? 1 : 0,
   439             (data[paddle_index] & button2_bit) ? 1 : 0,
   440             (data[paddle_index] & button3_bit) ? 1 : 0,
   441             (data[paddle_index] & button4_bit) ? 1 : 0,
   442             paddles_mapped ? "TRUE" : "FALSE"
   443         );
   444 #endif
   445 
   446         if (paddles_mapped) {
   447             /* Respect that the paddles are being used for other controls and don't pass them on to the app */
   448             data[paddle_index] = 0;
   449         }
   450 
   451         if (ctx->last_state[paddle_index] != data[paddle_index]) {
   452             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+0, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED);
   453             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+1, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED);
   454             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+2, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED);
   455             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+3, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED);
   456         }
   457     }
   458 
   459     axis = ((int)*(Sint16*)(&data[6]) * 64) - 32768;
   460     if (axis == 32704) {
   461         axis = 32767;
   462     }
   463     if (axis == -32768 && size == 30 && (data[22] & 0x80) != 0) {
   464         axis = 32767;
   465     }
   466     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
   467 
   468     axis = ((int)*(Sint16*)(&data[8]) * 64) - 32768;
   469     if (axis == -32768 && size == 30 && (data[22] & 0x40) != 0) {
   470         axis = 32767;
   471     }
   472     if (axis == 32704) {
   473         axis = 32767;
   474     }
   475     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
   476 
   477     axis = *(Sint16*)(&data[10]);
   478     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
   479     axis = *(Sint16*)(&data[12]);
   480     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis);
   481     axis = *(Sint16*)(&data[14]);
   482     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
   483     axis = *(Sint16*)(&data[16]);
   484     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis);
   485 
   486     SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
   487 }
   488 
   489 static void
   490 HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
   491 {
   492     if (data[1] == 0x30) {
   493         /* The Xbox One S controller needs acks for mode reports */
   494         const Uint8 seqnum = data[2];
   495         const Uint8 ack[] = { 0x01, 0x20, seqnum, 0x09, 0x00, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
   496         hid_write(dev, ack, sizeof(ack));
   497     }
   498 
   499     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   500 }
   501 
   502 static void
   503 HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV1(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
   504 {
   505     Sint16 axis;
   506 
   507     if (ctx->last_state[14] != data[14]) {
   508         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   509         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
   510         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
   511         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
   512         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   513         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
   514         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
   515         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
   516     }
   517 
   518     if (ctx->last_state[15] != data[15]) {
   519         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   520         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
   521     }
   522 
   523     if (ctx->last_state[13] != data[13]) {
   524         SDL_bool dpad_up = SDL_FALSE;
   525         SDL_bool dpad_down = SDL_FALSE;
   526         SDL_bool dpad_left = SDL_FALSE;
   527         SDL_bool dpad_right = SDL_FALSE;
   528 
   529         switch (data[13]) {
   530         case 1:
   531             dpad_up = SDL_TRUE;
   532             break;
   533         case 2:
   534             dpad_up = SDL_TRUE;
   535             dpad_right = SDL_TRUE;
   536             break;
   537         case 3:
   538             dpad_right = SDL_TRUE;
   539             break;
   540         case 4:
   541             dpad_right = SDL_TRUE;
   542             dpad_down = SDL_TRUE;
   543             break;
   544         case 5:
   545             dpad_down = SDL_TRUE;
   546             break;
   547         case 6:
   548             dpad_left = SDL_TRUE;
   549             dpad_down = SDL_TRUE;
   550             break;
   551         case 7:
   552             dpad_left = SDL_TRUE;
   553             break;
   554         case 8:
   555             dpad_up = SDL_TRUE;
   556             dpad_left = SDL_TRUE;
   557             break;
   558         default:
   559             break;
   560         }
   561         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
   562         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
   563         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
   564         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
   565     }
   566 
   567     axis = (int)*(Uint16*)(&data[1]) - 0x8000;
   568     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
   569     axis = (int)*(Uint16*)(&data[3]) - 0x8000;
   570     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
   571     axis = (int)*(Uint16*)(&data[5]) - 0x8000;
   572     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
   573     axis = (int)*(Uint16*)(&data[7]) - 0x8000;
   574     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
   575 
   576     axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768;
   577     if (axis == 32704) {
   578         axis = 32767;
   579     }
   580     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
   581 
   582     axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
   583     if (axis == 32704) {
   584         axis = 32767;
   585     }
   586     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
   587 
   588     SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
   589 }
   590 
   591 static void
   592 HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV2(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
   593 {
   594     Sint16 axis;
   595 
   596     if (ctx->last_state[14] != data[14]) {
   597         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   598         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
   599         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
   600         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   601         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
   602         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
   603     }
   604 
   605     if (ctx->last_state[15] != data[15]) {
   606         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
   607         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
   608         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
   609         if (ctx->wireless_protocol == XBOX_ONE_WIRELESS_PROTOCOL_UNKNOWN)
   610         {
   611             if (data[15] & 0x10) {
   612                 ctx->wireless_protocol = XBOX_ONE_WIRELESS_PROTOCOL_V2;
   613             }
   614         }
   615         if (ctx->wireless_protocol == XBOX_ONE_WIRELESS_PROTOCOL_V2)
   616         {
   617             SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
   618         }
   619     }
   620 
   621     if (ctx->last_state[16] != data[16]) {
   622         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   623     }
   624 
   625     if (ctx->last_state[13] != data[13]) {
   626         SDL_bool dpad_up = SDL_FALSE;
   627         SDL_bool dpad_down = SDL_FALSE;
   628         SDL_bool dpad_left = SDL_FALSE;
   629         SDL_bool dpad_right = SDL_FALSE;
   630 
   631         switch (data[13]) {
   632         case 1:
   633             dpad_up = SDL_TRUE;
   634             break;
   635         case 2:
   636             dpad_up = SDL_TRUE;
   637             dpad_right = SDL_TRUE;
   638             break;
   639         case 3:
   640             dpad_right = SDL_TRUE;
   641             break;
   642         case 4:
   643             dpad_right = SDL_TRUE;
   644             dpad_down = SDL_TRUE;
   645             break;
   646         case 5:
   647             dpad_down = SDL_TRUE;
   648             break;
   649         case 6:
   650             dpad_left = SDL_TRUE;
   651             dpad_down = SDL_TRUE;
   652             break;
   653         case 7:
   654             dpad_left = SDL_TRUE;
   655             break;
   656         case 8:
   657             dpad_up = SDL_TRUE;
   658             dpad_left = SDL_TRUE;
   659             break;
   660         default:
   661             break;
   662         }
   663         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
   664         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
   665         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
   666         SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
   667     }
   668 
   669     axis = (int)*(Uint16*)(&data[1]) - 0x8000;
   670     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
   671     axis = (int)*(Uint16*)(&data[3]) - 0x8000;
   672     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
   673     axis = (int)*(Uint16*)(&data[5]) - 0x8000;
   674     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
   675     axis = (int)*(Uint16*)(&data[7]) - 0x8000;
   676     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
   677 
   678     axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768;
   679     if (axis == 32704) {
   680         axis = 32767;
   681     }
   682     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
   683 
   684     axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
   685     if (axis == 32704) {
   686         axis = 32767;
   687     }
   688     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
   689 
   690     SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
   691 }
   692 
   693 static void
   694 HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
   695 {
   696     ctx->wireless_protocol = XBOX_ONE_WIRELESS_PROTOCOL_V1;
   697     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   698 }
   699 
   700 static SDL_bool
   701 HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
   702 {
   703     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
   704     SDL_Joystick *joystick = NULL;
   705     Uint8 data[USB_PACKET_LENGTH];
   706     int size;
   707 
   708     if (device->num_joysticks > 0) {
   709         joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
   710     }
   711     if (!joystick) {
   712         return SDL_FALSE;
   713     }
   714 
   715     if (!ctx->initialized &&
   716         !ControllerSendsWaitingForInit(device->vendor_id, device->product_id)) {
   717         if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
   718             if (!SendControllerInit(device, ctx)) {
   719                 HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
   720                 return SDL_FALSE;
   721             }
   722             ctx->initialized = SDL_TRUE;
   723             ctx->initialized_time = SDL_GetTicks();
   724             ctx->input_ready = SDL_FALSE;
   725         }
   726     }
   727 
   728     while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
   729 #ifdef DEBUG_XBOX_PROTOCOL
   730         DumpPacket("Xbox One packet: size = %d", data, size);
   731 #endif
   732         if (ctx->bluetooth) {
   733             switch (data[0]) {
   734             case 0x01:
   735                 switch (size) {
   736                 case 16:
   737                     HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV1(joystick, device->dev, ctx, data, size);
   738                     break;
   739                 case 17:
   740                     HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV2(joystick, device->dev, ctx, data, size);
   741                     break;
   742                 default:
   743                     break;
   744                 }
   745                 break;
   746             case 0x02:
   747                 HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(joystick, device->dev, ctx, data, size);
   748                 break;
   749             default:
   750 #ifdef DEBUG_JOYSTICK
   751                 SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
   752 #endif
   753                 break;
   754             }
   755         } else {
   756             switch (data[0]) {
   757             case 0x02:
   758                 /* Controller is connected and waiting for initialization */
   759                 if (!ctx->initialized) {
   760 #ifdef DEBUG_XBOX_PROTOCOL
   761                     SDL_Log("Delay after init: %ums\n", SDL_GetTicks() - ctx->start_time);
   762 #endif
   763                     if (!SendControllerInit(device, ctx)) {
   764                         HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
   765                         return SDL_FALSE;
   766                     }
   767                     ctx->initialized = SDL_TRUE;
   768                     ctx->initialized_time = SDL_GetTicks();
   769                     ctx->input_ready = SDL_FALSE;
   770                 }
   771                 break;
   772             case 0x03:
   773                 /* Controller heartbeat */
   774                 break;
   775             case 0x20:
   776                 if (!ctx->input_ready) {
   777                     if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->initialized_time + CONTROLLER_INPUT_DELAY_MS)) {
   778 #ifdef DEBUG_XBOX_PROTOCOL
   779                         SDL_Log("Spurious input at %ums\n", SDL_GetTicks() - ctx->initialized_time);
   780 #endif
   781                         break;
   782                     }
   783                     ctx->input_ready = SDL_TRUE;
   784                 }
   785                 HIDAPI_DriverXboxOne_HandleStatePacket(joystick, device->dev, ctx, data, size);
   786                 break;
   787             case 0x07:
   788                 HIDAPI_DriverXboxOne_HandleModePacket(joystick, device->dev, ctx, data, size);
   789                 break;
   790             default:
   791 #ifdef DEBUG_JOYSTICK
   792                 SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
   793 #endif
   794                 break;
   795             }
   796         }
   797     }
   798 
   799     if (size < 0) {
   800         /* Read error, device is disconnected */
   801         HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
   802     }
   803     return (size >= 0);
   804 }
   805 
   806 static void
   807 HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   808 {
   809     hid_close(device->dev);
   810     device->dev = NULL;
   811 
   812     SDL_free(device->context);
   813     device->context = NULL;
   814 }
   815 
   816 static void
   817 HIDAPI_DriverXboxOne_FreeDevice(SDL_HIDAPI_Device *device)
   818 {
   819 }
   820 
   821 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
   822 {
   823     SDL_HINT_JOYSTICK_HIDAPI_XBOX,
   824     SDL_TRUE,
   825     HIDAPI_DriverXboxOne_IsSupportedDevice,
   826     HIDAPI_DriverXboxOne_GetDeviceName,
   827     HIDAPI_DriverXboxOne_InitDevice,
   828     HIDAPI_DriverXboxOne_GetDevicePlayerIndex,
   829     HIDAPI_DriverXboxOne_SetDevicePlayerIndex,
   830     HIDAPI_DriverXboxOne_UpdateDevice,
   831     HIDAPI_DriverXboxOne_OpenJoystick,
   832     HIDAPI_DriverXboxOne_RumbleJoystick,
   833     HIDAPI_DriverXboxOne_CloseJoystick,
   834     HIDAPI_DriverXboxOne_FreeDevice,
   835     NULL
   836 };
   837 
   838 #endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */
   839 
   840 #endif /* SDL_JOYSTICK_HIDAPI */
   841 
   842 /* vi: set ts=4 sw=4 expandtab: */