Atlas - SDL_hidapi_steamdeck.c

Home / ext / SDL / src / joystick / hidapi Lines: 1 | Size: 19339 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 2023 Max Maisel <[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_sysjoystick.h" 26#include "SDL_hidapijoystick_c.h" 27 28#ifdef SDL_JOYSTICK_HIDAPI_STEAMDECK 29 30/*****************************************************************************************************/ 31 32#include "steam/controller_constants.h" 33#include "steam/controller_structs.h" 34 35enum 36{ 37 SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM = 11, 38 SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, 39 SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, 40 SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, 41 SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, 42 SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS, 43}; 44 45typedef enum 46{ 47 STEAMDECK_LBUTTON_R2 = 0x00000001, 48 STEAMDECK_LBUTTON_L2 = 0x00000002, 49 STEAMDECK_LBUTTON_R = 0x00000004, 50 STEAMDECK_LBUTTON_L = 0x00000008, 51 STEAMDECK_LBUTTON_Y = 0x00000010, 52 STEAMDECK_LBUTTON_B = 0x00000020, 53 STEAMDECK_LBUTTON_X = 0x00000040, 54 STEAMDECK_LBUTTON_A = 0x00000080, 55 STEAMDECK_LBUTTON_DPAD_UP = 0x00000100, 56 STEAMDECK_LBUTTON_DPAD_RIGHT = 0x00000200, 57 STEAMDECK_LBUTTON_DPAD_LEFT = 0x00000400, 58 STEAMDECK_LBUTTON_DPAD_DOWN = 0x00000800, 59 STEAMDECK_LBUTTON_VIEW = 0x00001000, 60 STEAMDECK_LBUTTON_STEAM = 0x00002000, 61 STEAMDECK_LBUTTON_MENU = 0x00004000, 62 STEAMDECK_LBUTTON_L5 = 0x00008000, 63 STEAMDECK_LBUTTON_R5 = 0x00010000, 64 STEAMDECK_LBUTTON_LEFT_PAD = 0x00020000, 65 STEAMDECK_LBUTTON_RIGHT_PAD = 0x00040000, 66 STEAMDECK_LBUTTON_L3 = 0x00400000, 67 STEAMDECK_LBUTTON_R3 = 0x04000000, 68 69 STEAMDECK_HBUTTON_L4 = 0x00000200, 70 STEAMDECK_HBUTTON_R4 = 0x00000400, 71 STEAMDECK_HBUTTON_QAM = 0x00040000, 72} SteamDeckButtons; 73 74typedef struct 75{ 76 Uint32 update_rate_us; 77 Uint64 sensor_timestamp_ns; 78 Uint64 last_button_state; 79 Uint8 watchdog_counter; 80} SDL_DriverSteamDeck_Context; 81 82static bool DisableDeckLizardMode(SDL_hid_device *dev) 83{ 84 int rc; 85 Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; 86 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 87 88 msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS; 89 90 rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); 91 if (rc != sizeof(buffer)) 92 return false; 93 94 msg->header.type = ID_SET_SETTINGS_VALUES; 95 msg->header.length = 5 * sizeof(ControllerSetting); 96 msg->payload.setSettingsValues.settings[0].settingNum = SETTING_SMOOTH_ABSOLUTE_MOUSE; 97 msg->payload.setSettingsValues.settings[0].settingValue = 0; 98 msg->payload.setSettingsValues.settings[1].settingNum = SETTING_LEFT_TRACKPAD_MODE; 99 msg->payload.setSettingsValues.settings[1].settingValue = TRACKPAD_NONE; 100 msg->payload.setSettingsValues.settings[2].settingNum = SETTING_RIGHT_TRACKPAD_MODE; // disable mouse 101 msg->payload.setSettingsValues.settings[2].settingValue = TRACKPAD_NONE; 102 msg->payload.setSettingsValues.settings[3].settingNum = SETTING_LEFT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad 103 msg->payload.setSettingsValues.settings[3].settingValue = 0xFFFF; 104 msg->payload.setSettingsValues.settings[4].settingNum = SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad 105 msg->payload.setSettingsValues.settings[4].settingValue = 0xFFFF; 106 107 rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); 108 if (rc != sizeof(buffer)) 109 return false; 110 111 // There may be a lingering report read back after changing settings. 112 // Discard it. 113 SDL_hid_get_feature_report(dev, buffer, sizeof(buffer)); 114 115 return true; 116} 117 118static bool FeedDeckLizardWatchdog(SDL_hid_device *dev) 119{ 120 int rc; 121 Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; 122 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 123 124 msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS; 125 126 rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); 127 if (rc != sizeof(buffer)) 128 return false; 129 130 msg->header.type = ID_SET_SETTINGS_VALUES; 131 msg->header.length = 1 * sizeof(ControllerSetting); 132 msg->payload.setSettingsValues.settings[0].settingNum = SETTING_RIGHT_TRACKPAD_MODE; 133 msg->payload.setSettingsValues.settings[0].settingValue = TRACKPAD_NONE; 134 135 rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); 136 if (rc != sizeof(buffer)) 137 return false; 138 139 // There may be a lingering report read back after changing settings. 140 // Discard it. 141 SDL_hid_get_feature_report(dev, buffer, sizeof(buffer)); 142 143 return true; 144} 145 146static void HIDAPI_DriverSteamDeck_HandleState(SDL_HIDAPI_Device *device, 147 SDL_Joystick *joystick, 148 ValveInReport_t *pInReport) 149{ 150 float values[3]; 151 SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; 152 Uint64 timestamp = SDL_GetTicksNS(); 153 154 if (pInReport->payload.deckState.ulButtons != ctx->last_button_state) { 155 Uint8 hat = 0; 156 157 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, 158 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_A) != 0)); 159 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, 160 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_B) != 0)); 161 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, 162 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_X) != 0)); 163 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, 164 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_Y) != 0)); 165 166 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, 167 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L) != 0)); 168 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, 169 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R) != 0)); 170 171 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, 172 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_VIEW) != 0)); 173 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, 174 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_MENU) != 0)); 175 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, 176 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_STEAM) != 0)); 177 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM, 178 ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_QAM) != 0)); 179 180 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, 181 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L3) != 0)); 182 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, 183 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R3) != 0)); 184 185 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, 186 ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_R4) != 0)); 187 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, 188 ((pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_L4) != 0)); 189 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, 190 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R5) != 0)); 191 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, 192 ((pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) != 0)); 193 194 if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) { 195 hat |= SDL_HAT_UP; 196 } 197 if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_DOWN) { 198 hat |= SDL_HAT_DOWN; 199 } 200 if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_LEFT) { 201 hat |= SDL_HAT_LEFT; 202 } 203 if (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_RIGHT) { 204 hat |= SDL_HAT_RIGHT; 205 } 206 SDL_SendJoystickHat(timestamp, joystick, 0, hat); 207 208 ctx->last_button_state = pInReport->payload.deckState.ulButtons; 209 } 210 211 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 212 (int)pInReport->payload.deckState.sTriggerRawL * 2 - 32768); 213 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 214 (int)pInReport->payload.deckState.sTriggerRawR * 2 - 32768); 215 216 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, 217 pInReport->payload.deckState.sLeftStickX); 218 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, 219 -pInReport->payload.deckState.sLeftStickY); 220 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, 221 pInReport->payload.deckState.sRightStickX); 222 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, 223 -pInReport->payload.deckState.sRightStickY); 224 225 ctx->sensor_timestamp_ns += SDL_US_TO_NS(ctx->update_rate_us); 226 227 values[0] = (pInReport->payload.deckState.sGyroX / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 228 values[1] = (pInReport->payload.deckState.sGyroZ / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 229 values[2] = (-pInReport->payload.deckState.sGyroY / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 230 SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_ns, values, 3); 231 232 values[0] = (pInReport->payload.deckState.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 233 values[1] = (pInReport->payload.deckState.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 234 values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 235 SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3); 236 237 SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, 238 pInReport->payload.deckState.sPressurePadLeft > 0, 239 pInReport->payload.deckState.sLeftPadX / 65536.0f + 0.5f, 240 pInReport->payload.deckState.sLeftPadY / 65536.0f + 0.5f, 241 pInReport->payload.deckState.sPressurePadLeft / 32768.0f); 242 243 SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, 244 pInReport->payload.deckState.sPressurePadRight > 0, 245 pInReport->payload.deckState.sRightPadX / 65536.0f + 0.5f, 246 pInReport->payload.deckState.sRightPadY / 65536.0f + 0.5f, 247 pInReport->payload.deckState.sPressurePadRight / 32768.0f); 248} 249 250/*****************************************************************************************************/ 251 252static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata) 253{ 254 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata); 255} 256 257static void HIDAPI_DriverSteamDeck_UnregisterHints(SDL_HintCallback callback, void *userdata) 258{ 259 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata); 260} 261 262static bool HIDAPI_DriverSteamDeck_IsEnabled(void) 263{ 264 return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, 265 SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); 266} 267 268static bool HIDAPI_DriverSteamDeck_IsSupportedDevice( 269 SDL_HIDAPI_Device *device, 270 const char *name, 271 SDL_GamepadType type, 272 Uint16 vendor_id, 273 Uint16 product_id, 274 Uint16 version, 275 int interface_number, 276 int interface_class, 277 int interface_subclass, 278 int interface_protocol) 279{ 280 return SDL_IsJoystickSteamDeck(vendor_id, product_id); 281} 282 283static bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device) 284{ 285 int size; 286 Uint8 data[64]; 287 SDL_DriverSteamDeck_Context *ctx; 288 289 ctx = (SDL_DriverSteamDeck_Context *)SDL_calloc(1, sizeof(*ctx)); 290 if (ctx == NULL) { 291 return false; 292 } 293 294 // Always 1kHz according to USB descriptor, but actually about 4 ms. 295 ctx->update_rate_us = 4000; 296 297 device->context = ctx; 298 299 // Read a report to see if this is the correct endpoint. 300 // Mouse, Keyboard and Controller have the same VID/PID but 301 // only the controller hidraw device receives hid reports. 302 size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); 303 if (size == 0) 304 return false; 305 306 if (!DisableDeckLizardMode(device->dev)) 307 return false; 308 309 HIDAPI_SetDeviceName(device, "Steam Deck"); 310 311 return HIDAPI_JoystickConnected(device, NULL); 312} 313 314static int HIDAPI_DriverSteamDeck_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) 315{ 316 return -1; 317} 318 319static void HIDAPI_DriverSteamDeck_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) 320{ 321} 322 323static bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device) 324{ 325 SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; 326 SDL_Joystick *joystick = NULL; 327 int r; 328 uint8_t data[64]; 329 ValveInReport_t *pInReport = (ValveInReport_t *)data; 330 331 if (device->num_joysticks > 0) { 332 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 333 if (joystick == NULL) { 334 return false; 335 } 336 } else { 337 return false; 338 } 339 340 if (ctx->watchdog_counter++ > 200) { 341 ctx->watchdog_counter = 0; 342 if (!FeedDeckLizardWatchdog(device->dev)) 343 return false; 344 } 345 346 SDL_memset(data, 0, sizeof(data)); 347 348 do { 349 r = SDL_hid_read(device->dev, data, sizeof(data)); 350 351 if (r < 0) { 352 // Failed to read from controller 353 HIDAPI_JoystickDisconnected(device, device->joysticks[0]); 354 return false; 355 } else if (r == 64 && 356 pInReport->header.unReportVersion == k_ValveInReportMsgVersion && 357 pInReport->header.ucType == ID_CONTROLLER_DECK_STATE && 358 pInReport->header.ucLength == 64) { 359 HIDAPI_DriverSteamDeck_HandleState(device, joystick, pInReport); 360 } 361 } while (r > 0); 362 363 return true; 364} 365 366static bool HIDAPI_DriverSteamDeck_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 367{ 368 SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; 369 float update_rate_in_hz = 1.0f / (float)(ctx->update_rate_us) * 1.0e6f; 370 371 SDL_AssertJoysticksLocked(); 372 373 // Initialize the joystick capabilities 374 joystick->nbuttons = SDL_GAMEPAD_NUM_STEAM_DECK_BUTTONS; 375 joystick->naxes = SDL_GAMEPAD_AXIS_COUNT; 376 joystick->nhats = 1; 377 378 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); 379 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); 380 381 SDL_PrivateJoystickAddTouchpad(joystick, 1); 382 SDL_PrivateJoystickAddTouchpad(joystick, 1); 383 384 return true; 385} 386 387static bool HIDAPI_DriverSteamDeck_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) 388{ 389 int rc; 390 Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; 391 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 392 393 msg->header.type = ID_TRIGGER_RUMBLE_CMD; 394 msg->payload.simpleRumble.unRumbleType = 0; 395 msg->payload.simpleRumble.unIntensity = HAPTIC_INTENSITY_SYSTEM; 396 msg->payload.simpleRumble.unLeftMotorSpeed = low_frequency_rumble; 397 msg->payload.simpleRumble.unRightMotorSpeed = high_frequency_rumble; 398 msg->payload.simpleRumble.nLeftGain = 2; 399 msg->payload.simpleRumble.nRightGain = 0; 400 401 rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer)); 402 if (rc != sizeof(buffer)) 403 return false; 404 return true; 405} 406 407static bool HIDAPI_DriverSteamDeck_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) 408{ 409 return SDL_Unsupported(); 410} 411 412static Uint32 HIDAPI_DriverSteamDeck_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 413{ 414 return SDL_JOYSTICK_CAP_RUMBLE; 415} 416 417static bool HIDAPI_DriverSteamDeck_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) 418{ 419 return SDL_Unsupported(); 420} 421 422static bool HIDAPI_DriverSteamDeck_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) 423{ 424 return SDL_Unsupported(); 425} 426 427static bool HIDAPI_DriverSteamDeck_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled) 428{ 429 // On steam deck, sensors are enabled by default. Nothing to do here. 430 return true; 431} 432 433static void HIDAPI_DriverSteamDeck_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 434{ 435 // Lizard mode id automatically re-enabled by watchdog. Nothing to do here. 436} 437 438static void HIDAPI_DriverSteamDeck_FreeDevice(SDL_HIDAPI_Device *device) 439{ 440} 441 442SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamDeck = { 443 SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, 444 true, 445 HIDAPI_DriverSteamDeck_RegisterHints, 446 HIDAPI_DriverSteamDeck_UnregisterHints, 447 HIDAPI_DriverSteamDeck_IsEnabled, 448 HIDAPI_DriverSteamDeck_IsSupportedDevice, 449 HIDAPI_DriverSteamDeck_InitDevice, 450 HIDAPI_DriverSteamDeck_GetDevicePlayerIndex, 451 HIDAPI_DriverSteamDeck_SetDevicePlayerIndex, 452 HIDAPI_DriverSteamDeck_UpdateDevice, 453 HIDAPI_DriverSteamDeck_OpenJoystick, 454 HIDAPI_DriverSteamDeck_RumbleJoystick, 455 HIDAPI_DriverSteamDeck_RumbleJoystickTriggers, 456 HIDAPI_DriverSteamDeck_GetJoystickCapabilities, 457 HIDAPI_DriverSteamDeck_SetJoystickLED, 458 HIDAPI_DriverSteamDeck_SendJoystickEffect, 459 HIDAPI_DriverSteamDeck_SetSensorsEnabled, 460 HIDAPI_DriverSteamDeck_CloseJoystick, 461 HIDAPI_DriverSteamDeck_FreeDevice, 462}; 463 464#endif // SDL_JOYSTICK_HIDAPI_STEAMDECK 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.