Atlas - SDL_hidapi_xbox360w.c

Home / ext / SDL / src / joystick / hidapi Lines: 1 | Size: 19123 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2026 Sam Lantinga <[email protected]> 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_c.h" 26#include "../SDL_sysjoystick.h" 27#include "SDL_hidapijoystick_c.h" 28#include "SDL_hidapi_rumble.h" 29#include "SDL_hidapi_xbox360.h" 30 31#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 32 33// Define this if you want to log all packets from the controller 34// #define DEBUG_XBOX_PROTOCOL 35 36typedef struct 37{ 38 SDL_HIDAPI_Device *device; 39 bool connected; 40 int player_index; 41 bool player_lights; 42 SDL_xinput_capabilities capabilities; 43 Uint8 last_state[USB_PACKET_LENGTH]; 44} SDL_DriverXbox360W_Context; 45 46static void HIDAPI_DriverXbox360W_RegisterHints(SDL_HintCallback callback, void *userdata) 47{ 48 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); 49 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); 50 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, callback, userdata); 51} 52 53static void HIDAPI_DriverXbox360W_UnregisterHints(SDL_HintCallback callback, void *userdata) 54{ 55 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); 56 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); 57 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, callback, userdata); 58} 59 60static bool HIDAPI_DriverXbox360W_IsEnabled(void) 61{ 62 return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, 63 SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)))); 64} 65 66static bool HIDAPI_DriverXbox360W_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) 67{ 68 const int XB360W_IFACE_PROTOCOL = 129; // Wireless 69 70 if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY2 || product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER_THIRDPARTY1 || product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER) && interface_protocol == 0) || 71 (type == SDL_GAMEPAD_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) { 72 return true; 73 } 74 return false; 75} 76 77static bool SetSlotLED(SDL_hid_device *dev, Uint8 slot, bool on) 78{ 79 const bool blink = false; 80 Uint8 mode = on ? ((blink ? 0x02 : 0x06) + slot) : 0; 81 Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 82 83 led_packet[3] = 0x40 + (mode % 0x0e); 84 if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { 85 return false; 86 } 87 return true; 88} 89 90static void UpdateSlotLED(SDL_DriverXbox360W_Context *ctx) 91{ 92 if (ctx->player_lights && ctx->player_index >= 0) { 93 SetSlotLED(ctx->device->dev, (ctx->player_index % 4), true); 94 } else { 95 SetSlotLED(ctx->device->dev, 0, false); 96 } 97} 98 99static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) 100{ 101 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)userdata; 102 bool player_lights = SDL_GetStringBoolean(hint, true); 103 104 if (player_lights != ctx->player_lights) { 105 ctx->player_lights = player_lights; 106 107 UpdateSlotLED(ctx); 108 HIDAPI_UpdateDeviceProperties(ctx->device); 109 } 110} 111 112static void UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level) 113{ 114 int percent = (int)SDL_roundf((level / 255.0f) * 100.0f); 115 SDL_SendJoystickPowerInfo(joystick, SDL_POWERSTATE_ON_BATTERY, percent); 116} 117 118static bool HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) 119{ 120 SDL_DriverXbox360W_Context *ctx; 121 122 // Requests controller presence information from the wireless dongle 123 const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 124 125 HIDAPI_SetDeviceName(device, "Xbox 360 Wireless Controller"); 126 127 ctx = (SDL_DriverXbox360W_Context *)SDL_calloc(1, sizeof(*ctx)); 128 if (!ctx) { 129 return false; 130 } 131 ctx->device = device; 132 133 device->context = ctx; 134 135 if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { 136 SDL_SetError("Couldn't write init packet"); 137 return false; 138 } 139 140 device->type = SDL_GAMEPAD_TYPE_XBOX360; 141 142 return true; 143} 144 145static int HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) 146{ 147 return -1; 148} 149 150static void HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) 151{ 152 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; 153 154 if (!ctx) { 155 return; 156 } 157 158 ctx->player_index = player_index; 159 160 UpdateSlotLED(ctx); 161} 162 163static bool HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 164{ 165 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; 166 167 SDL_AssertJoysticksLocked(); 168 169 SDL_zeroa(ctx->last_state); 170 171 // Initialize player index (needed for setting LEDs) 172 ctx->player_index = SDL_GetJoystickPlayerIndex(joystick); 173 ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, true); 174 UpdateSlotLED(ctx); 175 176 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, 177 SDL_PlayerLEDHintChanged, ctx); 178 179 // Initialize the joystick capabilities 180 joystick->nbuttons = 11; 181 joystick->naxes = SDL_GAMEPAD_AXIS_COUNT; 182 joystick->nhats = 1; 183 joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS; 184 ctx->capabilities.type = 1; 185 ctx->capabilities.flags = FLAG_WIRELESS; 186 ctx->capabilities.subType = SDL_JOYSTICK_TYPE_GAMEPAD; 187 ctx->capabilities.gamepad.wButtons = 0xFFFF; 188 ctx->capabilities.gamepad.bLeftTrigger = 0xFF; 189 ctx->capabilities.gamepad.bRightTrigger = 0xFF; 190 ctx->capabilities.gamepad.sThumbLX = 0xFFC0; 191 ctx->capabilities.gamepad.sThumbLY = 0xFFC0; 192 ctx->capabilities.gamepad.sThumbRX = 0xFFC0; 193 ctx->capabilities.gamepad.sThumbRY = 0xFFC0; 194 ctx->capabilities.vibration.wLeftMotorSpeed = 0xFFFF; 195 ctx->capabilities.vibration.wRightMotorSpeed = 0xFFFF; 196 197 return true; 198} 199 200static bool HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) 201{ 202 Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 203 204 rumble_packet[5] = (low_frequency_rumble >> 8); 205 rumble_packet[6] = (high_frequency_rumble >> 8); 206 207 if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { 208 return SDL_SetError("Couldn't send rumble packet"); 209 } 210 return true; 211} 212 213static bool HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) 214{ 215 return SDL_Unsupported(); 216} 217 218static Uint32 HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 219{ 220 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; 221 Uint32 result = SDL_JOYSTICK_CAP_RUMBLE; 222 223 if (ctx->player_lights) { 224 result |= SDL_JOYSTICK_CAP_PLAYER_LED; 225 } 226 return result; 227} 228 229static bool HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) 230{ 231 return SDL_Unsupported(); 232} 233 234static bool HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) 235{ 236 return SDL_Unsupported(); 237} 238 239static bool HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled) 240{ 241 return SDL_Unsupported(); 242} 243 244static void HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) 245{ 246 Sint16 axis; 247 const bool invert_y_axes = true; 248 Uint64 timestamp = SDL_GetTicksNS(); 249 250 if (ctx->last_state[2] != data[2]) { 251 Uint8 hat = 0; 252 253 if (data[2] & 0x01) { 254 hat |= SDL_HAT_UP; 255 } 256 if (data[2] & 0x02) { 257 hat |= SDL_HAT_DOWN; 258 } 259 if (data[2] & 0x04) { 260 hat |= SDL_HAT_LEFT; 261 } 262 if (data[2] & 0x08) { 263 hat |= SDL_HAT_RIGHT; 264 } 265 SDL_SendJoystickHat(timestamp, joystick, 0, hat); 266 267 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[2] & 0x10) != 0)); 268 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[2] & 0x20) != 0)); 269 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[2] & 0x40) != 0)); 270 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[2] & 0x80) != 0)); 271 } 272 273 if (ctx->last_state[3] != data[3]) { 274 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[3] & 0x01) != 0)); 275 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[3] & 0x02) != 0)); 276 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[3] & 0x04) != 0)); 277 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x10) != 0)); 278 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x20) != 0)); 279 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x40) != 0)); 280 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x80) != 0)); 281 } 282 283 axis = ((int)data[4] * 257) - 32768; 284 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis); 285 axis = ((int)data[5] * 257) - 32768; 286 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis); 287 axis = SDL_Swap16LE(*(Sint16 *)(&data[6])); 288 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, axis); 289 axis = SDL_Swap16LE(*(Sint16 *)(&data[8])); 290 if (invert_y_axes) { 291 axis = ~axis; 292 } 293 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, axis); 294 axis = SDL_Swap16LE(*(Sint16 *)(&data[10])); 295 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, axis); 296 axis = SDL_Swap16LE(*(Sint16 *)(&data[12])); 297 if (invert_y_axes) { 298 axis = ~axis; 299 } 300 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis); 301 302 SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); 303} 304 305static bool HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) 306{ 307 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; 308 SDL_Joystick *joystick = NULL; 309 Uint8 data[USB_PACKET_LENGTH]; 310 int size; 311 312 if (device->num_joysticks > 0) { 313 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 314 } 315 316 while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { 317#ifdef DEBUG_XBOX_PROTOCOL 318 HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size); 319#endif 320 if (size == 2 && data[0] == 0x08) { 321 bool connected = (data[1] & 0x80) ? true : false; 322#ifdef DEBUG_JOYSTICK 323 SDL_Log("Connected = %s", connected ? "TRUE" : "FALSE"); 324#endif 325 if (connected != ctx->connected) { 326 ctx->connected = connected; 327 328 if (connected) { 329 SDL_JoystickID joystickID; 330 331 HIDAPI_JoystickConnected(device, &joystickID); 332 333 } else if (device->num_joysticks > 0) { 334 HIDAPI_JoystickDisconnected(device, device->joysticks[0]); 335 } 336 } 337 } else if (size == 29 && data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) { 338 // Serial number is data[7-13] 339#ifdef DEBUG_JOYSTICK 340 SDL_Log("Battery status (initial): %d", data[17]); 341#endif 342 if (joystick) { 343 UpdatePowerLevel(joystick, data[17]); 344 } 345 ctx->capabilities.type = 1; 346 ctx->capabilities.subType = data[25] & 0x7f; 347 if ((data[25] & 0x80) != 0) { 348 ctx->capabilities.flags |= FLAG_FORCE_FEEDBACK; 349 } 350 switch (data[25] & 0x7f) { 351 case 0x01: // XINPUT_DEVSUBTYPE_GAMEPAD 352 device->joystick_type = SDL_JOYSTICK_TYPE_GAMEPAD; 353 break; 354 case 0x02: // XINPUT_DEVSUBTYPE_WHEEL 355 device->joystick_type = SDL_JOYSTICK_TYPE_WHEEL; 356 break; 357 case 0x03: // XINPUT_DEVSUBTYPE_ARCADE_STICK 358 device->joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; 359 break; 360 case 0x04: // XINPUT_DEVSUBTYPE_FLIGHT_STICK 361 device->joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK; 362 break; 363 case 0x05: // XINPUT_DEVSUBTYPE_DANCE_PAD 364 device->joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD; 365 break; 366 case 0x06: // XINPUT_DEVSUBTYPE_GUITAR 367 case 0x07: // XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE 368 case 0x0B: // XINPUT_DEVSUBTYPE_GUITAR_BASS 369 device->joystick_type = SDL_JOYSTICK_TYPE_GUITAR; 370 break; 371 case 0x08: // XINPUT_DEVSUBTYPE_DRUM_KIT 372 device->joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT; 373 break; 374 case 0x13: // XINPUT_DEVSUBTYPE_ARCADE_PAD 375 device->joystick_type = SDL_JOYSTICK_TYPE_ARCADE_PAD; 376 break; 377 } 378 device->guid.data[15] = ctx->capabilities.subType; 379 const Uint8 capabilities_packet[] = { 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 380 if (SDL_hid_write(device->dev, capabilities_packet, sizeof(capabilities_packet)) != sizeof(capabilities_packet)) { 381 SDL_SetError("Couldn't write capabilities_packet packet"); 382 } 383 } else if (size == 29 && data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13) { 384#ifdef DEBUG_JOYSTICK 385 SDL_Log("Battery status: %d", data[4]); 386#endif 387 if (joystick) { 388 UpdatePowerLevel(joystick, data[4]); 389 } 390 } else if (data[0] == 0x00 && data[1] == 0x05 && data[5] == 0x12) { 391 ctx->capabilities.gamepad.wButtons = LOAD16(data[6], data[7]); 392 ctx->capabilities.gamepad.bLeftTrigger = data[8]; 393 ctx->capabilities.gamepad.bRightTrigger = data[9]; 394 ctx->capabilities.gamepad.sThumbLX = LOAD16(data[10], data[11]); 395 ctx->capabilities.gamepad.sThumbLY = LOAD16(data[12], data[13]); 396 ctx->capabilities.gamepad.sThumbRX = LOAD16(data[14], data[15]); 397 ctx->capabilities.gamepad.sThumbRY = LOAD16(data[16], data[17]); 398 ctx->capabilities.flags |= data[20]; 399 ctx->capabilities.vibration.wLeftMotorSpeed = data[18] << 8; 400 ctx->capabilities.vibration.wRightMotorSpeed = data[19] << 8; 401#ifdef DEBUG_XBOX_PROTOCOL 402 SDL_Log("Xbox 360 capabilities:"); 403 SDL_Log(" type: %02x", ctx->capabilities.type); 404 SDL_Log(" subType: %02x", ctx->capabilities.subType); 405 SDL_Log(" flags: %02x", ctx->capabilities.flags); 406 SDL_Log(" wButtons: %02x", ctx->capabilities.gamepad.wButtons); 407 SDL_Log(" bLeftTrigger: %02x", ctx->capabilities.gamepad.bLeftTrigger); 408 SDL_Log(" bRightTrigger: %02x", ctx->capabilities.gamepad.bRightTrigger); 409 SDL_Log(" sThumbLX: %02x", ctx->capabilities.gamepad.sThumbLX); 410 SDL_Log(" sThumbLY: %02x", ctx->capabilities.gamepad.sThumbLY); 411 SDL_Log(" sThumbRX: %02x", ctx->capabilities.gamepad.sThumbRX); 412 SDL_Log(" sThumbRY: %02x", ctx->capabilities.gamepad.sThumbRY); 413 SDL_Log(" wLeftMotorSpeed: %02x", ctx->capabilities.vibration.wLeftMotorSpeed); 414 SDL_Log(" wRightMotorSpeed: %02x", ctx->capabilities.vibration.wRightMotorSpeed); 415#endif 416 } else if (size == 29 && data[0] == 0x00 && (data[1] & 0x01) == 0x01) { 417 if (joystick) { 418 HIDAPI_DriverXbox360W_HandleStatePacket(joystick, device->dev, ctx, data + 4, size - 4); 419 } 420 } 421 } 422 423 if (size < 0 && device->num_joysticks > 0) { 424 // Read error, device is disconnected 425 HIDAPI_JoystickDisconnected(device, device->joysticks[0]); 426 } 427 return (size >= 0); 428} 429 430static void HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 431{ 432 SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; 433 434 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, 435 SDL_PlayerLEDHintChanged, ctx); 436} 437 438static void HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device) 439{ 440} 441 442SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = { 443 SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, 444 true, 445 HIDAPI_DriverXbox360W_RegisterHints, 446 HIDAPI_DriverXbox360W_UnregisterHints, 447 HIDAPI_DriverXbox360W_IsEnabled, 448 HIDAPI_DriverXbox360W_IsSupportedDevice, 449 HIDAPI_DriverXbox360W_InitDevice, 450 HIDAPI_DriverXbox360W_GetDevicePlayerIndex, 451 HIDAPI_DriverXbox360W_SetDevicePlayerIndex, 452 HIDAPI_DriverXbox360W_UpdateDevice, 453 HIDAPI_DriverXbox360W_OpenJoystick, 454 HIDAPI_DriverXbox360W_RumbleJoystick, 455 HIDAPI_DriverXbox360W_RumbleJoystickTriggers, 456 HIDAPI_DriverXbox360W_GetJoystickCapabilities, 457 HIDAPI_DriverXbox360W_SetJoystickLED, 458 HIDAPI_DriverXbox360W_SendJoystickEffect, 459 HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled, 460 HIDAPI_DriverXbox360W_CloseJoystick, 461 HIDAPI_DriverXbox360W_FreeDevice, 462}; 463 464#endif // SDL_JOYSTICK_HIDAPI_XBOX360 465 466#endif // SDL_JOYSTICK_HIDAPI 467
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.