1.1 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c Thu Nov 21 13:09:00 2019 -0800
1.2 +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c Thu Nov 21 14:04:48 2019 -0800
1.3 @@ -36,8 +36,11 @@
1.4
1.5 #define USB_PACKET_LENGTH 64
1.6
1.7 +/* The amount of time to wait after hotplug to send controller init sequence */
1.8 +#define CONTROLLER_INIT_DELAY_MS 100
1.9 +
1.10 /*
1.11 - * This packet is required for Xbox One Elite Series 2 pad
1.12 + * This packet is required for Xbox One Elite Series 2 pad, initial firmware version
1.13 */
1.14 static const Uint8 xboxone_elite_series2_init[] = {
1.15 0x04, 0x20, 0x01, 0x00
1.16 @@ -117,12 +120,8 @@
1.17 { 0x0f0d, 0x0067, xboxone_hori_init, sizeof(xboxone_hori_init) },
1.18 { 0x045e, 0x0b00, xboxone_elite_series2_init, sizeof(xboxone_elite_series2_init) },
1.19 { 0x0000, 0x0000, xboxone_fw2015_init, sizeof(xboxone_fw2015_init) },
1.20 - { 0x0e6f, 0x0246, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
1.21 - { 0x0e6f, 0x0246, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
1.22 - { 0x0e6f, 0x02ab, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
1.23 - { 0x0e6f, 0x02ab, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
1.24 - { 0x0e6f, 0x02a4, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
1.25 - { 0x0e6f, 0x02a4, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
1.26 + { 0x0e6f, 0x0000, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
1.27 + { 0x0e6f, 0x0000, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
1.28 { 0x24c6, 0x541a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
1.29 { 0x24c6, 0x542a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
1.30 { 0x24c6, 0x543a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
1.31 @@ -132,6 +131,10 @@
1.32 };
1.33
1.34 typedef struct {
1.35 + Uint16 vendor_id;
1.36 + Uint16 product_id;
1.37 + Uint32 start_time;
1.38 + SDL_bool initialized;
1.39 Uint8 sequence;
1.40 Uint8 last_state[USB_PACKET_LENGTH];
1.41 Uint32 rumble_expiration;
1.42 @@ -153,6 +156,39 @@
1.43 }
1.44
1.45 static SDL_bool
1.46 +SendControllerInit(hid_device *dev, SDL_DriverXboxOne_Context *ctx)
1.47 +{
1.48 + Uint16 vendor_id = ctx->vendor_id;
1.49 + Uint16 product_id = ctx->product_id;
1.50 +
1.51 + if (!IsBluetoothXboxOneController(vendor_id, product_id)) {
1.52 + int i;
1.53 + Uint8 init_packet[USB_PACKET_LENGTH];
1.54 +
1.55 + for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
1.56 + const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
1.57 +
1.58 + if (packet->vendor_id && (vendor_id != packet->vendor_id)) {
1.59 + continue;
1.60 + }
1.61 +
1.62 + if (packet->product_id && (product_id != packet->product_id)) {
1.63 + continue;
1.64 + }
1.65 +
1.66 + SDL_memcpy(init_packet, packet->data, packet->size);
1.67 + init_packet[2] = ctx->sequence++;
1.68 + if (hid_write(dev, init_packet, packet->size) != packet->size) {
1.69 + SDL_SetError("Couldn't write Xbox One initialization packet");
1.70 + return SDL_FALSE;
1.71 + }
1.72 + }
1.73 + }
1.74 + return SDL_TRUE;
1.75 +}
1.76 +
1.77 +
1.78 +static SDL_bool
1.79 HIDAPI_DriverXboxOne_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
1.80 {
1.81 #ifdef __LINUX__
1.82 @@ -174,8 +210,6 @@
1.83 HIDAPI_DriverXboxOne_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context)
1.84 {
1.85 SDL_DriverXboxOne_Context *ctx;
1.86 - int i;
1.87 - Uint8 init_packet[USB_PACKET_LENGTH];
1.88
1.89 ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
1.90 if (!ctx) {
1.91 @@ -184,21 +218,9 @@
1.92 }
1.93 *context = ctx;
1.94
1.95 - if (!IsBluetoothXboxOneController(vendor_id, product_id)) {
1.96 - /* Send the controller init data */
1.97 - for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
1.98 - const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
1.99 - if (!packet->vendor_id || (vendor_id == packet->vendor_id && product_id == packet->product_id)) {
1.100 - SDL_memcpy(init_packet, packet->data, packet->size);
1.101 - init_packet[2] = ctx->sequence++;
1.102 - if (hid_write(dev, init_packet, packet->size) != packet->size) {
1.103 - SDL_SetError("Couldn't write Xbox One initialization packet");
1.104 - SDL_free(ctx);
1.105 - return SDL_FALSE;
1.106 - }
1.107 - }
1.108 - }
1.109 - }
1.110 + ctx->vendor_id = vendor_id;
1.111 + ctx->product_id = product_id;
1.112 + ctx->start_time = SDL_GetTicks();
1.113
1.114 /* Initialize the joystick capabilities */
1.115 joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
1.116 @@ -214,6 +236,10 @@
1.117 SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
1.118 Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
1.119
1.120 + if (!ctx->initialized) {
1.121 + return 0;
1.122 + }
1.123 +
1.124 /* Magnitude is 1..100 so scale the 16-bit input here */
1.125 rumble_packet[2] = ctx->sequence++;
1.126 rumble_packet[8] = low_frequency_rumble / 655;
1.127 @@ -298,6 +324,15 @@
1.128 Uint8 data[USB_PACKET_LENGTH];
1.129 int size;
1.130
1.131 + if (!ctx->initialized) {
1.132 + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
1.133 + if (!SendControllerInit(dev, ctx)) {
1.134 + return SDL_FALSE;
1.135 + }
1.136 + ctx->initialized = SDL_TRUE;
1.137 + }
1.138 + }
1.139 +
1.140 while ((size = hid_read_timeout(dev, data, sizeof(data), 0)) > 0) {
1.141 #ifdef DEBUG_XBOX_PROTOCOL
1.142 SDL_Log("Xbox One packet: size = %d\n"