Atlas - SDL_hidapi_steam_triton.c

Home / ext / SDL / src / joystick / hidapi Lines: 1 | Size: 20671 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_STEAM_TRITON 29 30/*****************************************************************************************************/ 31 32#include "steam/controller_constants.h" 33#include "steam/controller_structs.h" 34 35// Always 1kHz according to USB descriptor, but actually about 4 ms. 36#define TRITON_SENSOR_UPDATE_INTERVAL_US 4032 37 38enum 39{ 40 SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM = 11, 41 SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, 42 SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, 43 SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, 44 SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, 45 SDL_GAMEPAD_NUM_TRITON_BUTTONS, 46}; 47 48typedef enum 49{ 50 51 TRITON_LBUTTON_A = 0x00000001, 52 TRITON_LBUTTON_B = 0x00000002, 53 TRITON_LBUTTON_X = 0x00000004, 54 TRITON_LBUTTON_Y = 0x00000008, 55 56 TRITON_HBUTTON_QAM = 0x00000010, 57 TRITON_LBUTTON_R3 = 0x00000020, 58 TRITON_LBUTTON_VIEW = 0x00000040, 59 TRITON_HBUTTON_R4 = 0x00000080, 60 61 TRITON_LBUTTON_R5 = 0x00000100, 62 TRITON_LBUTTON_R = 0x00000200, 63 TRITON_LBUTTON_DPAD_DOWN = 0x00000400, 64 TRITON_LBUTTON_DPAD_RIGHT = 0x00000800, 65 66 TRITON_LBUTTON_DPAD_LEFT = 0x00001000, 67 TRITON_LBUTTON_DPAD_UP = 0x00002000, 68 TRITON_LBUTTON_MENU = 0x00004000, 69 TRITON_LBUTTON_L3 = 0x00008000, 70 71 TRITON_LBUTTON_STEAM = 0x00010000, 72 TRITON_HBUTTON_L4 = 0x00020000, 73 TRITON_LBUTTON_L5 = 0x00040000, 74 TRITON_LBUTTON_L = 0x00080000, 75 76 /* 77 STEAM_RIGHTSTICK_FINGERDOWN_MASK, // Right Stick Touch 0x00100000 78 STEAM_RIGHTPAD_FINGERDOWN_MASK, // Right Pad Touch 0x00200000 79 STEAM_BUTTON_RIGHTPAD_CLICKED_MASK, // Right Pressure Click 0x00400000 80 STEAM_RIGHT_TRIGGER_MASK, // Right Trigger Click 0x00800000 81 82 STEAM_LEFTSTICK_FINGERDOWN_MASK, // Left Stick Touch 0x01000000 83 STEAM_LEFTPAD_FINGERDOWN_MASK, // Left Pad Touch 0x02000000 84 STEAM_BUTTON_LEFTPAD_CLICKED_MASK, // Left Pressure Click 0x04000000 85 STEAM_LEFT_TRIGGER_MASK, // Left Trigger Click 0x08000000 86 STEAM_RIGHT_AUX_MASK, // Right Pinky Touch 0x10000000 87 STEAM_LEFT_AUX_MASK, // Left Pinky Touch 0x20000000 88 */ 89} TritonButtons; 90 91typedef struct 92{ 93 bool connected; 94 bool report_sensors; 95 Uint32 last_sensor_tick; 96 Uint64 sensor_timestamp_ns; 97 Uint64 last_button_state; 98 Uint64 last_lizard_update; 99} SDL_DriverSteamTriton_Context; 100 101static bool IsProteusDongle(Uint16 product_id) 102{ 103 return (product_id == USB_PRODUCT_VALVE_STEAM_PROTEUS_DONGLE || 104 product_id == USB_PRODUCT_VALVE_STEAM_NEREID_DONGLE); 105} 106 107static bool DisableSteamTritonLizardMode(SDL_hid_device *dev) 108{ 109 int rc; 110 Uint8 buffer[HID_FEATURE_REPORT_BYTES] = { 1 }; 111 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 112 113 msg->header.type = ID_SET_SETTINGS_VALUES; 114 msg->header.length = 1 * sizeof(ControllerSetting); 115 msg->payload.setSettingsValues.settings[0].settingNum = SETTING_LIZARD_MODE; 116 msg->payload.setSettingsValues.settings[0].settingValue = LIZARD_MODE_OFF; 117 118 rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); 119 if (rc != sizeof(buffer)) { 120 return false; 121 } 122 123 return true; 124} 125 126static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, 127 SDL_Joystick *joystick, 128 TritonMTUFull_t *pTritonReport) 129{ 130 float values[3]; 131 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 132 Uint64 timestamp = SDL_GetTicksNS(); 133 134 if (pTritonReport->uButtons != ctx->last_button_state) { 135 Uint8 hat = 0; 136 137 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, 138 ((pTritonReport->uButtons & TRITON_LBUTTON_A) != 0)); 139 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, 140 ((pTritonReport->uButtons & TRITON_LBUTTON_B) != 0)); 141 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, 142 ((pTritonReport->uButtons & TRITON_LBUTTON_X) != 0)); 143 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, 144 ((pTritonReport->uButtons & TRITON_LBUTTON_Y) != 0)); 145 146 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, 147 ((pTritonReport->uButtons & TRITON_LBUTTON_L) != 0)); 148 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, 149 ((pTritonReport->uButtons & TRITON_LBUTTON_R) != 0)); 150 151 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, 152 ((pTritonReport->uButtons & TRITON_LBUTTON_MENU) != 0)); 153 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, 154 ((pTritonReport->uButtons & TRITON_LBUTTON_VIEW) != 0)); 155 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, 156 ((pTritonReport->uButtons & TRITON_LBUTTON_STEAM) != 0)); 157 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM, 158 ((pTritonReport->uButtons & TRITON_HBUTTON_QAM) != 0)); 159 160 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, 161 ((pTritonReport->uButtons & TRITON_LBUTTON_L3) != 0)); 162 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, 163 ((pTritonReport->uButtons & TRITON_LBUTTON_R3) != 0)); 164 165 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, 166 ((pTritonReport->uButtons & TRITON_HBUTTON_R4) != 0)); 167 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, 168 ((pTritonReport->uButtons & TRITON_HBUTTON_L4) != 0)); 169 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, 170 ((pTritonReport->uButtons & TRITON_LBUTTON_R5) != 0)); 171 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, 172 ((pTritonReport->uButtons & TRITON_LBUTTON_L5) != 0)); 173 174 if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_UP) { 175 hat |= SDL_HAT_UP; 176 } 177 if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_DOWN) { 178 hat |= SDL_HAT_DOWN; 179 } 180 if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_LEFT) { 181 hat |= SDL_HAT_LEFT; 182 } 183 if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_RIGHT) { 184 hat |= SDL_HAT_RIGHT; 185 } 186 SDL_SendJoystickHat(timestamp, joystick, 0, hat); 187 188 ctx->last_button_state = pTritonReport->uButtons; 189 } 190 191 // RKRK There're button bits for this if you so choose. 192 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 193 (int)pTritonReport->sTriggerLeft * 2 - 32768); 194 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 195 (int)pTritonReport->sTriggerRight * 2 - 32768); 196 197 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, 198 pTritonReport->sLeftStickX); 199 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, 200 -pTritonReport->sLeftStickY); 201 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, 202 pTritonReport->sRightStickX); 203 SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, 204 -pTritonReport->sRightStickY); 205 206 if (ctx->report_sensors && pTritonReport->imu.uTimestamp != ctx->last_sensor_tick) { 207 Uint32 delta_us = (pTritonReport->imu.uTimestamp - ctx->last_sensor_tick); 208 209 ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us); 210 211 values[0] = (pTritonReport->imu.sGyroX / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 212 values[1] = (pTritonReport->imu.sGyroZ / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 213 values[2] = (-pTritonReport->imu.sGyroY / 32768.0f) * (2000.0f * (SDL_PI_F / 180.0f)); 214 SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_ns, values, 3); 215 216 values[0] = (pTritonReport->imu.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 217 values[1] = (pTritonReport->imu.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 218 values[2] = (-pTritonReport->imu.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; 219 SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3); 220 221 ctx->last_sensor_tick = pTritonReport->imu.uTimestamp; 222 } 223} 224 225static void HIDAPI_DriverSteamTriton_HandleBatteryStatus(SDL_HIDAPI_Device *device, 226 SDL_Joystick *joystick, 227 TritonBatteryStatus_t *pTritonBatteryStatus) 228{ 229 SDL_PowerState state; 230 231 if (device->is_bluetooth) { 232 state = SDL_POWERSTATE_ON_BATTERY; 233 } else if (IsProteusDongle(device->product_id)) { 234 state = SDL_POWERSTATE_ON_BATTERY; 235 } else if (pTritonBatteryStatus->ucBatteryLevel == 100) { 236 state = SDL_POWERSTATE_CHARGED; 237 } else { 238 state = SDL_POWERSTATE_CHARGING; 239 } 240 SDL_SendJoystickPowerInfo(joystick, state, pTritonBatteryStatus->ucBatteryLevel); 241} 242 243static bool HIDAPI_DriverSteamTriton_SetControllerConnected(SDL_HIDAPI_Device *device, bool connected) 244{ 245 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 246 247 if (ctx->connected != connected) { 248 ctx->connected = connected; 249 250 if (connected) { 251 SDL_JoystickID joystickID; 252 if (!HIDAPI_JoystickConnected(device, &joystickID)) { 253 return false; 254 } 255 } else { 256 if (device->num_joysticks > 0) { 257 HIDAPI_JoystickDisconnected(device, device->joysticks[0]); 258 } 259 } 260 } 261 return true; 262} 263 264static void HIDAPI_DriverSteamTriton_HandleWirelessStatus(SDL_HIDAPI_Device *device, 265 TritonWirelessStatus_t *pTritonWirelessStatus) 266{ 267 switch (pTritonWirelessStatus->state) { 268 case k_ETritonWirelessStateConnect: 269 HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 270 break; 271 case k_ETritonWirelessStateDisconnect: 272 HIDAPI_DriverSteamTriton_SetControllerConnected(device, false); 273 break; 274 default: 275 break; 276 } 277} 278 279/*****************************************************************************************************/ 280 281static void HIDAPI_DriverSteamTriton_RegisterHints(SDL_HintCallback callback, void *userdata) 282{ 283 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); 284} 285 286static void HIDAPI_DriverSteamTriton_UnregisterHints(SDL_HintCallback callback, void *userdata) 287{ 288 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); 289} 290 291static bool HIDAPI_DriverSteamTriton_IsEnabled(void) 292{ 293 return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, 294 SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); 295} 296 297static bool HIDAPI_DriverSteamTriton_IsSupportedDevice( 298 SDL_HIDAPI_Device *device, 299 const char *name, 300 SDL_GamepadType type, 301 Uint16 vendor_id, 302 Uint16 product_id, 303 Uint16 version, 304 int interface_number, 305 int interface_class, 306 int interface_subclass, 307 int interface_protocol) 308{ 309 310 if (IsProteusDongle(product_id)) { 311 if (interface_number >= 2 && interface_number <= 5) { 312 // The set of controller interfaces for Proteus & Nereid...currently 313 return true; 314 } 315 } else if (SDL_IsJoystickSteamTriton(vendor_id, product_id)) { 316 return true; 317 } 318 return false; 319} 320 321static bool HIDAPI_DriverSteamTriton_InitDevice(SDL_HIDAPI_Device *device) 322{ 323 SDL_DriverSteamTriton_Context *ctx; 324 325 ctx = (SDL_DriverSteamTriton_Context *)SDL_calloc(1, sizeof(*ctx)); 326 if (ctx == NULL) { 327 return false; 328 } 329 330 device->context = ctx; 331 332 HIDAPI_SetDeviceName(device, "Steam Controller"); 333 334 if (IsProteusDongle(device->product_id)) { 335 return true; 336 } 337 338 // Wired controller, connected! 339 return HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 340} 341 342static int HIDAPI_DriverSteamTriton_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) 343{ 344 return -1; 345} 346 347static void HIDAPI_DriverSteamTriton_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) 348{ 349} 350 351static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device) 352{ 353 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 354 SDL_Joystick *joystick = NULL; 355 356 if (device->num_joysticks > 0) { 357 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 358 } 359 360 if (ctx->connected && joystick) { 361 Uint64 now = SDL_GetTicks(); 362 if (!ctx->last_lizard_update || (now - ctx->last_lizard_update) >= 3000) { 363 DisableSteamTritonLizardMode(device->dev); 364 ctx->last_lizard_update = now; 365 } 366 } 367 368 for (;;) { 369 uint8_t data[64]; 370 int r = SDL_hid_read(device->dev, data, sizeof(data)); 371 372 if (r == 0) { 373 return true; 374 } 375 if (r < 0) { 376 // Failed to read from controller 377 HIDAPI_DriverSteamTriton_SetControllerConnected(device, false); 378 return false; 379 } 380 381 switch (data[0]) { 382 case ID_TRITON_CONTROLLER_STATE: 383 if (!joystick) { 384 HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 385 if (device->num_joysticks > 0) { 386 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 387 } 388 } 389 if (joystick && r >= (1 + sizeof(TritonMTUFull_t))) { 390 TritonMTUFull_t *pTritonReport = (TritonMTUFull_t *)&data[1]; 391 HIDAPI_DriverSteamTriton_HandleState(device, joystick, pTritonReport); 392 } 393 break; 394 case ID_TRITON_BATTERY_STATUS: 395 if (joystick && r >= (1 + sizeof(TritonBatteryStatus_t))) { 396 TritonBatteryStatus_t *pTritonBatteryStatus = (TritonBatteryStatus_t *)&data[1]; 397 HIDAPI_DriverSteamTriton_HandleBatteryStatus(device, joystick, pTritonBatteryStatus); 398 } 399 break; 400 case ID_TRITON_WIRELESS_STATUS_X: 401 case ID_TRITON_WIRELESS_STATUS: 402 if (r >= (1 + sizeof(TritonWirelessStatus_t))) { 403 TritonWirelessStatus_t *pTritonWirelessStatus = (TritonWirelessStatus_t *)&data[1]; 404 HIDAPI_DriverSteamTriton_HandleWirelessStatus(device, pTritonWirelessStatus); 405 } 406 break; 407 default: 408 break; 409 } 410 } 411} 412 413static bool HIDAPI_DriverSteamTriton_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 414{ 415 float update_rate_in_hz = 1000000.0f / TRITON_SENSOR_UPDATE_INTERVAL_US; 416 417 SDL_AssertJoysticksLocked(); 418 419 // Initialize the joystick capabilities 420 joystick->nbuttons = SDL_GAMEPAD_NUM_TRITON_BUTTONS; 421 joystick->naxes = SDL_GAMEPAD_AXIS_COUNT; 422 joystick->nhats = 1; 423 424 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); 425 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); 426 427 return true; 428} 429 430static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) 431{ 432 int rc; 433 434 //RKRK Not sure about size. Probalby 64+1 is OK for ORs 435 Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES]; 436 OutputReportMsg *msg = (OutputReportMsg *)(buffer); 437 438 msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE; 439 msg->payload.hapticRumble.type = 0; 440 msg->payload.hapticRumble.intensity = 0; 441 msg->payload.hapticRumble.left.speed = low_frequency_rumble; 442 msg->payload.hapticRumble.left.gain = 0; 443 msg->payload.hapticRumble.right.speed = high_frequency_rumble; 444 msg->payload.hapticRumble.right.gain = 0; 445 446 447 rc = SDL_hid_write(device->dev, buffer, sizeof(buffer)); 448 if (rc != sizeof(buffer)) { 449 return false; 450 } 451 return true; 452} 453 454static bool HIDAPI_DriverSteamTriton_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) 455{ 456 return SDL_Unsupported(); 457} 458 459static Uint32 HIDAPI_DriverSteamTriton_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 460{ 461 return SDL_JOYSTICK_CAP_RUMBLE; 462} 463 464static bool HIDAPI_DriverSteamTriton_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) 465{ 466 return SDL_Unsupported(); 467} 468 469static bool HIDAPI_DriverSteamTriton_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) 470{ 471 return SDL_Unsupported(); 472} 473 474static bool HIDAPI_DriverSteamTriton_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled) 475{ 476 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 477 int rc; 478 Uint8 buffer[HID_FEATURE_REPORT_BYTES] = { 1 }; 479 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 480 481 msg->header.type = ID_SET_SETTINGS_VALUES; 482 msg->header.length = 1 * sizeof(ControllerSetting); 483 msg->payload.setSettingsValues.settings[0].settingNum = SETTING_IMU_MODE; 484 if (enabled) { 485 msg->payload.setSettingsValues.settings[0].settingValue = (SETTING_GYRO_MODE_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO); 486 } else { 487 msg->payload.setSettingsValues.settings[0].settingValue = SETTING_GYRO_MODE_OFF; 488 } 489 490 rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer)); 491 if (rc != sizeof(buffer)) { 492 return false; 493 } 494 495 ctx->report_sensors = enabled; 496 497 return true; 498} 499 500static void HIDAPI_DriverSteamTriton_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 501{ 502 // Lizard mode id automatically re-enabled by watchdog. Nothing to do here. 503} 504 505static void HIDAPI_DriverSteamTriton_FreeDevice(SDL_HIDAPI_Device *device) 506{ 507} 508 509SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamTriton = { 510 SDL_HINT_JOYSTICK_HIDAPI_STEAM, 511 true, 512 HIDAPI_DriverSteamTriton_RegisterHints, 513 HIDAPI_DriverSteamTriton_UnregisterHints, 514 HIDAPI_DriverSteamTriton_IsEnabled, 515 HIDAPI_DriverSteamTriton_IsSupportedDevice, 516 HIDAPI_DriverSteamTriton_InitDevice, 517 HIDAPI_DriverSteamTriton_GetDevicePlayerIndex, 518 HIDAPI_DriverSteamTriton_SetDevicePlayerIndex, 519 HIDAPI_DriverSteamTriton_UpdateDevice, 520 HIDAPI_DriverSteamTriton_OpenJoystick, 521 HIDAPI_DriverSteamTriton_RumbleJoystick, 522 HIDAPI_DriverSteamTriton_RumbleJoystickTriggers, 523 HIDAPI_DriverSteamTriton_GetJoystickCapabilities, 524 HIDAPI_DriverSteamTriton_SetJoystickLED, 525 HIDAPI_DriverSteamTriton_SendJoystickEffect, 526 HIDAPI_DriverSteamTriton_SetSensorsEnabled, 527 HIDAPI_DriverSteamTriton_CloseJoystick, 528 HIDAPI_DriverSteamTriton_FreeDevice, 529}; 530 531#endif // SDL_JOYSTICK_HIDAPI_STEAM_TRITON 532 533#endif // SDL_JOYSTICK_HIDAPI 534
[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.