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
43static const Uint8 xboxone_fw2015_init[] = {
44 0x05, 0x20, 0x00, 0x01, 0x00
52static const Uint8 xboxone_hori_init[] = {
53 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
54 0x00, 0x00, 0x00, 0x80, 0x00
62static const Uint8 xboxone_pdp_init1[] = {
63 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
71static const Uint8 xboxone_pdp_init2[] = {
72 0x06, 0x20, 0x00, 0x02, 0x01, 0x00
79static const Uint8 xboxone_rumblebegin_init[] = {
80 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
81 0x1D, 0x1D, 0xFF, 0x00, 0x00
90static const Uint8 xboxone_rumbleend_init[] = {
91 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00
106} SDL_DriverXboxOne_InitPacket;
108static 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;
134HIDAPI_DriverXboxOne_IsSupportedDevice(
Uint16 vendor_id,
Uint16 product_id,
Uint16 version,
int interface_number)
140HIDAPI_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;
210HIDAPI_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]) {
257HIDAPI_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 };
270HIDAPI_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);
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);
312 HIDAPI_DriverXboxOne_IsSupportedDevice,
313 HIDAPI_DriverXboxOne_GetDeviceName,
314 HIDAPI_DriverXboxOne_Init,
315 HIDAPI_DriverXboxOne_Rumble,
316 HIDAPI_DriverXboxOne_Update,
317 HIDAPI_DriverXboxOne_Quit
#define SDL_OutOfMemory()
@ SDL_CONTROLLER_AXIS_LEFTX
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_RIGHTY
@ SDL_CONTROLLER_AXIS_RIGHTX
@ SDL_CONTROLLER_AXIS_MAX
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
@ SDL_CONTROLLER_AXIS_LEFTY
@ SDL_CONTROLLER_BUTTON_B
@ SDL_CONTROLLER_BUTTON_BACK
@ SDL_CONTROLLER_BUTTON_LEFTSTICK
@ SDL_CONTROLLER_BUTTON_START
@ SDL_CONTROLLER_BUTTON_DPAD_LEFT
@ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
@ SDL_CONTROLLER_BUTTON_DPAD_DOWN
@ SDL_CONTROLLER_BUTTON_DPAD_UP
@ SDL_CONTROLLER_BUTTON_MAX
@ SDL_CONTROLLER_BUTTON_LEFTSHOULDER
@ SDL_CONTROLLER_BUTTON_GUIDE
@ SDL_CONTROLLER_BUTTON_DPAD_RIGHT
@ SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_RIGHTSTICK
@ SDL_CONTROLLER_BUTTON_Y
@ SDL_CONTROLLER_BUTTON_A
const char * HIDAPI_XboxControllerName(Uint16 vendor_id, Uint16 product_id)
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne
#define SDL_HINT_JOYSTICK_HIDAPI_XBOX
A variable controlling whether the HIDAPI driver for XBox controllers should be used.
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
@ SDL_JOYSTICK_POWER_WIRED
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define SDL_arraysize(array)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
struct hid_device_ hid_device
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
Write an Output report to a HID device.
static screen_context_t context