21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HIDAPI
31 #include "../SDL_sysjoystick.h"
36 #ifdef SDL_JOYSTICK_HIDAPI_XBOX360
42 } SDL_DriverXbox360W_Context;
48 const int XB360W_IFACE_PROTOCOL = 129;
50 if ((vendor_id ==
USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719)) ||
58 HIDAPI_DriverXbox360W_GetDeviceName(
Uint16 vendor_id,
Uint16 product_id)
60 return "Xbox 360 Wireless Controller";
66 const Uint8 led_packet[] = { 0x00, 0x00, 0x08, (0x40 + (
mode % 0x0e)), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
68 if (
hid_write(dev, led_packet,
sizeof(led_packet)) !=
sizeof(led_packet)) {
75 UpdatePowerLevel(SDL_Joystick *joystick,
Uint8 level)
77 float normalized_level = (float)
level / 255.0
f;
79 if (normalized_level <= 0.05
f) {
81 }
else if (normalized_level <= 0.20
f) {
83 }
else if (normalized_level <= 0.70
f) {
91 HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *
device)
93 SDL_DriverXbox360W_Context *
ctx;
96 const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
112 if (
hid_write(
device->dev, init_packet,
sizeof(init_packet)) !=
sizeof(init_packet)) {
121 HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *
device,
SDL_JoystickID instance_id)
127 HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *
device,
SDL_JoystickID instance_id,
int player_index)
129 SetSlotLED(
device->dev, (player_index % 4));
133 HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick)
135 SDL_DriverXbox360W_Context *
ctx = (SDL_DriverXbox360W_Context *)
device->context;
148 HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick,
Uint16 low_frequency_rumble,
Uint16 high_frequency_rumble)
150 Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
152 rumble_packet[5] = (low_frequency_rumble >> 8);
153 rumble_packet[6] = (high_frequency_rumble >> 8);
155 if (SDL_HIDAPI_SendRumble(
device, rumble_packet,
sizeof(rumble_packet)) !=
sizeof(rumble_packet)) {
162 HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick,
hid_device *dev, SDL_DriverXbox360W_Context *
ctx,
Uint8 *
data,
int size)
167 if (
ctx->last_state[2] !=
data[2]) {
178 if (
ctx->last_state[3] !=
data[3]) {
188 axis = ((int)
data[4] * 257) - 32768;
190 axis = ((int)
data[5] * 257) - 32768;
211 HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *
device)
213 SDL_DriverXbox360W_Context *
ctx = (SDL_DriverXbox360W_Context *)
device->context;
214 SDL_Joystick *joystick =
NULL;
225 #ifdef DEBUG_JOYSTICK
226 SDL_Log(
"Connected = %s\n", connected ?
"TRUE" :
"FALSE");
228 if (connected !=
ctx->connected) {
229 ctx->connected = connected;
236 }
else if (
device->num_joysticks > 0) {
240 }
else if (
size == 29 &&
data[0] == 0x00 &&
data[1] == 0x0f &&
data[2] == 0x00 &&
data[3] == 0xf0) {
242 #ifdef DEBUG_JOYSTICK
243 SDL_Log(
"Battery status (initial): %d\n",
data[17]);
246 UpdatePowerLevel(joystick,
data[17]);
248 }
else if (
size == 29 &&
data[0] == 0x00 &&
data[1] == 0x00 &&
data[2] == 0x00 &&
data[3] == 0x13) {
249 #ifdef DEBUG_JOYSTICK
253 UpdatePowerLevel(joystick,
data[4]);
255 }
else if (
size == 29 &&
data[0] == 0x00 && (
data[1] & 0x01) == 0x01) {
257 HIDAPI_DriverXbox360W_HandleStatePacket(joystick,
device->dev,
ctx,
data+4,
size-4);
272 HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *
device, SDL_Joystick *joystick)
277 HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *
device)
290 HIDAPI_DriverXbox360W_IsSupportedDevice,
291 HIDAPI_DriverXbox360W_GetDeviceName,
292 HIDAPI_DriverXbox360W_InitDevice,
293 HIDAPI_DriverXbox360W_GetDevicePlayerIndex,
294 HIDAPI_DriverXbox360W_SetDevicePlayerIndex,
295 HIDAPI_DriverXbox360W_UpdateDevice,
296 HIDAPI_DriverXbox360W_OpenJoystick,
297 HIDAPI_DriverXbox360W_RumbleJoystick,
298 HIDAPI_DriverXbox360W_CloseJoystick,
299 HIDAPI_DriverXbox360W_FreeDevice