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: */