21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HIDAPI
31 #include "../SDL_sysjoystick.h"
35 #ifdef SDL_JOYSTICK_HIDAPI_XBOXONE
37 #define USB_PACKET_LENGTH 64
43 static const Uint8 xboxone_fw2015_init[] = {
44 0x05, 0x20, 0x00, 0x01, 0x00
52 static const Uint8 xboxone_hori_init[] = {
53 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
54 0x00, 0x00, 0x00, 0x80, 0x00
62 static const Uint8 xboxone_pdp_init1[] = {
63 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
71 static const Uint8 xboxone_pdp_init2[] = {
72 0x06, 0x20, 0x00, 0x02, 0x01, 0x00
79 static const Uint8 xboxone_rumblebegin_init[] = {
80 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
81 0x1D, 0x1D, 0xFF, 0x00, 0x00
90 static const Uint8 xboxone_rumbleend_init[] = {
91 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00
106 } SDL_DriverXboxOne_InitPacket;
108 static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
109 { 0x0e6f, 0x0165, xboxone_hori_init,
sizeof(xboxone_hori_init) },
110 { 0x0f0d, 0x0067, xboxone_hori_init,
sizeof(xboxone_hori_init) },
111 { 0x0000, 0x0000, xboxone_fw2015_init,
sizeof(xboxone_fw2015_init) },
112 { 0x0e6f, 0x0246, xboxone_pdp_init1,
sizeof(xboxone_pdp_init1) },
113 { 0x0e6f, 0x0246, xboxone_pdp_init2,
sizeof(xboxone_pdp_init2) },
114 { 0x0e6f, 0x02ab, xboxone_pdp_init1,
sizeof(xboxone_pdp_init1) },
115 { 0x0e6f, 0x02ab, xboxone_pdp_init2,
sizeof(xboxone_pdp_init2) },
116 { 0x0e6f, 0x02a4, xboxone_pdp_init1,
sizeof(xboxone_pdp_init1) },
117 { 0x0e6f, 0x02a4, xboxone_pdp_init2,
sizeof(xboxone_pdp_init2) },
118 { 0x24c6, 0x541a, xboxone_rumblebegin_init,
sizeof(xboxone_rumblebegin_init) },
119 { 0x24c6, 0x542a, xboxone_rumblebegin_init,
sizeof(xboxone_rumblebegin_init) },
120 { 0x24c6, 0x543a, xboxone_rumblebegin_init,
sizeof(xboxone_rumblebegin_init) },
121 { 0x24c6, 0x541a, xboxone_rumbleend_init,
sizeof(xboxone_rumbleend_init) },
122 { 0x24c6, 0x542a, xboxone_rumbleend_init,
sizeof(xboxone_rumbleend_init) },
123 { 0x24c6, 0x543a, xboxone_rumbleend_init,
sizeof(xboxone_rumbleend_init) },
128 Uint8 last_state[USB_PACKET_LENGTH];
130 } SDL_DriverXboxOne_Context;
134 HIDAPI_DriverXboxOne_IsSupportedDevice(
Uint16 vendor_id,
Uint16 product_id,
Uint16 version,
int interface_number)
140 HIDAPI_DriverXboxOne_GetDeviceName(
Uint16 vendor_id,
Uint16 product_id)
148 SDL_DriverXboxOne_Context *
ctx;
150 Uint8 init_packet[USB_PACKET_LENGTH];
161 const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[
i];
162 if (!packet->vendor_id || (vendor_id == packet->vendor_id && product_id == packet->product_id)) {
163 SDL_memcpy(init_packet, packet->data, packet->size);
164 init_packet[2] =
ctx->sequence++;
165 if (
hid_write(dev, init_packet, packet->size) != packet->size) {
166 SDL_SetError(
"Couldn't write Xbox One initialization packet");
184 SDL_DriverXboxOne_Context *
ctx = (SDL_DriverXboxOne_Context *)
context;
185 Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
193 rumble_packet[2] =
ctx->sequence++;
194 rumble_packet[8] = (low_frequency_rumble >> 9);
195 rumble_packet[9] = (high_frequency_rumble >> 9);
197 if (
hid_write(dev, rumble_packet,
sizeof(rumble_packet)) !=
sizeof(rumble_packet)) {
201 if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
204 ctx->rumble_expiration = 0;
210 HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick,
hid_device *dev, SDL_DriverXboxOne_Context *
ctx,
Uint8 *
data,
int size)
214 if (
ctx->last_state[4] !=
data[4]) {
223 if (
ctx->last_state[5] !=
data[5]) {
257 HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick,
hid_device *dev, SDL_DriverXboxOne_Context *
ctx,
Uint8 *
data,
int size)
259 if (
data[1] == 0x30) {
262 const Uint8 ack[] = { 0x01, 0x20, seqnum, 0x09, 0x00, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
270 HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick,
hid_device *dev,
void *
context)
272 SDL_DriverXboxOne_Context *
ctx = (SDL_DriverXboxOne_Context *)
context;
279 HIDAPI_DriverXboxOne_HandleStatePacket(joystick, dev,
ctx,
data,
size);
282 HIDAPI_DriverXboxOne_HandleModePacket(joystick, dev,
ctx,
data,
size);
285 #ifdef DEBUG_JOYSTICK
286 SDL_Log(
"Unknown Xbox One packet: 0x%.2x\n",
data[0]);
292 if (
ctx->rumble_expiration) {
295 HIDAPI_DriverXboxOne_Rumble(joystick, dev,
context, 0, 0, 0);
303 HIDAPI_DriverXboxOne_Quit(SDL_Joystick *joystick,
hid_device *dev,
void *
context)
312 HIDAPI_DriverXboxOne_IsSupportedDevice,
313 HIDAPI_DriverXboxOne_GetDeviceName,
314 HIDAPI_DriverXboxOne_Init,
315 HIDAPI_DriverXboxOne_Rumble,
316 HIDAPI_DriverXboxOne_Update,
317 HIDAPI_DriverXboxOne_Quit