Atlas - SDL_hidapi_steam_triton.c

Home / ext / SDL / src / joystick / hidapi Lines: 1 | Size: 20789 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 TritonMTUNoQuat_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->buttons != ctx->last_button_state) { 135 Uint8 hat = 0; 136 137 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, 138 ((pTritonReport->buttons & TRITON_LBUTTON_A) != 0)); 139 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, 140 ((pTritonReport->buttons & TRITON_LBUTTON_B) != 0)); 141 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, 142 ((pTritonReport->buttons & TRITON_LBUTTON_X) != 0)); 143 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, 144 ((pTritonReport->buttons & TRITON_LBUTTON_Y) != 0)); 145 146 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, 147 ((pTritonReport->buttons & TRITON_LBUTTON_L) != 0)); 148 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, 149 ((pTritonReport->buttons & TRITON_LBUTTON_R) != 0)); 150 151 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, 152 ((pTritonReport->buttons & TRITON_LBUTTON_MENU) != 0)); 153 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, 154 ((pTritonReport->buttons & TRITON_LBUTTON_VIEW) != 0)); 155 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, 156 ((pTritonReport->buttons & TRITON_LBUTTON_STEAM) != 0)); 157 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM, 158 ((pTritonReport->buttons & TRITON_HBUTTON_QAM) != 0)); 159 160 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, 161 ((pTritonReport->buttons & TRITON_LBUTTON_L3) != 0)); 162 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, 163 ((pTritonReport->buttons & TRITON_LBUTTON_R3) != 0)); 164 165 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, 166 ((pTritonReport->buttons & TRITON_HBUTTON_R4) != 0)); 167 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, 168 ((pTritonReport->buttons & TRITON_HBUTTON_L4) != 0)); 169 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, 170 ((pTritonReport->buttons & TRITON_LBUTTON_R5) != 0)); 171 SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, 172 ((pTritonReport->buttons & TRITON_LBUTTON_L5) != 0)); 173 174 if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_UP) { 175 hat |= SDL_HAT_UP; 176 } 177 if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_DOWN) { 178 hat |= SDL_HAT_DOWN; 179 } 180 if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_LEFT) { 181 hat |= SDL_HAT_LEFT; 182 } 183 if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_RIGHT) { 184 hat |= SDL_HAT_RIGHT; 185 } 186 SDL_SendJoystickHat(timestamp, joystick, 0, hat); 187 188 ctx->last_button_state = pTritonReport->buttons; 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.timestamp != ctx->last_sensor_tick) { 207 Uint32 delta_us = (pTritonReport->imu.timestamp - 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.timestamp; 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 switch (pTritonBatteryStatus->ucChargeState) { 232 case k_EChargeStateDischarging: 233 state = SDL_POWERSTATE_ON_BATTERY; 234 break; 235 case k_EChargeStateCharging: 236 state = SDL_POWERSTATE_CHARGING; 237 break; 238 case k_EChargeStateChargingDone: 239 state = SDL_POWERSTATE_CHARGED; 240 break; 241 default: 242 // Error state? 243 state = SDL_POWERSTATE_UNKNOWN; 244 break; 245 } 246 SDL_SendJoystickPowerInfo(joystick, state, pTritonBatteryStatus->ucBatteryLevel); 247} 248 249static bool HIDAPI_DriverSteamTriton_SetControllerConnected(SDL_HIDAPI_Device *device, bool connected) 250{ 251 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 252 253 if (ctx->connected != connected) { 254 ctx->connected = connected; 255 256 if (connected) { 257 SDL_JoystickID joystickID; 258 if (!HIDAPI_JoystickConnected(device, &joystickID)) { 259 return false; 260 } 261 } else { 262 if (device->num_joysticks > 0) { 263 HIDAPI_JoystickDisconnected(device, device->joysticks[0]); 264 } 265 } 266 } 267 return true; 268} 269 270static void HIDAPI_DriverSteamTriton_HandleWirelessStatus(SDL_HIDAPI_Device *device, 271 TritonWirelessStatus_t *pTritonWirelessStatus) 272{ 273 switch (pTritonWirelessStatus->state) { 274 case k_ETritonWirelessStateConnect: 275 HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 276 break; 277 case k_ETritonWirelessStateDisconnect: 278 HIDAPI_DriverSteamTriton_SetControllerConnected(device, false); 279 break; 280 default: 281 break; 282 } 283} 284 285/*****************************************************************************************************/ 286 287static void HIDAPI_DriverSteamTriton_RegisterHints(SDL_HintCallback callback, void *userdata) 288{ 289 SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); 290} 291 292static void HIDAPI_DriverSteamTriton_UnregisterHints(SDL_HintCallback callback, void *userdata) 293{ 294 SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); 295} 296 297static bool HIDAPI_DriverSteamTriton_IsEnabled(void) 298{ 299 return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, 300 SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); 301} 302 303static bool HIDAPI_DriverSteamTriton_IsSupportedDevice( 304 SDL_HIDAPI_Device *device, 305 const char *name, 306 SDL_GamepadType type, 307 Uint16 vendor_id, 308 Uint16 product_id, 309 Uint16 version, 310 int interface_number, 311 int interface_class, 312 int interface_subclass, 313 int interface_protocol) 314{ 315 316 if (IsProteusDongle(product_id)) { 317 if (interface_number >= 2 && interface_number <= 5) { 318 // The set of controller interfaces for Proteus & Nereid...currently 319 return true; 320 } 321 } else if (SDL_IsJoystickSteamTriton(vendor_id, product_id)) { 322 return true; 323 } 324 return false; 325} 326 327static bool HIDAPI_DriverSteamTriton_InitDevice(SDL_HIDAPI_Device *device) 328{ 329 SDL_DriverSteamTriton_Context *ctx; 330 331 ctx = (SDL_DriverSteamTriton_Context *)SDL_calloc(1, sizeof(*ctx)); 332 if (ctx == NULL) { 333 return false; 334 } 335 336 device->context = ctx; 337 338 HIDAPI_SetDeviceName(device, "Steam Controller"); 339 340 if (IsProteusDongle(device->product_id)) { 341 return true; 342 } 343 344 // Wired controller, connected! 345 return HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 346} 347 348static int HIDAPI_DriverSteamTriton_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) 349{ 350 return -1; 351} 352 353static void HIDAPI_DriverSteamTriton_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) 354{ 355} 356 357static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device) 358{ 359 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 360 SDL_Joystick *joystick = NULL; 361 362 if (device->num_joysticks > 0) { 363 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 364 } 365 366 if (ctx->connected && joystick) { 367 Uint64 now = SDL_GetTicks(); 368 if (!ctx->last_lizard_update || (now - ctx->last_lizard_update) >= 3000) { 369 DisableSteamTritonLizardMode(device->dev); 370 ctx->last_lizard_update = now; 371 } 372 } 373 374 for (;;) { 375 uint8_t data[64]; 376 int r = SDL_hid_read(device->dev, data, sizeof(data)); 377 378 if (r == 0) { 379 return true; 380 } 381 if (r < 0) { 382 // Failed to read from controller 383 HIDAPI_DriverSteamTriton_SetControllerConnected(device, false); 384 return false; 385 } 386 387 switch (data[0]) { 388 case ID_TRITON_CONTROLLER_STATE: 389 case ID_TRITON_CONTROLLER_STATE_BLE: 390 if (!joystick) { 391 HIDAPI_DriverSteamTriton_SetControllerConnected(device, true); 392 if (device->num_joysticks > 0) { 393 joystick = SDL_GetJoystickFromID(device->joysticks[0]); 394 } 395 } 396 if (joystick && r >= (1 + sizeof(TritonMTUNoQuat_t))) { 397 TritonMTUNoQuat_t *pTritonReport = (TritonMTUNoQuat_t *)&data[1]; 398 HIDAPI_DriverSteamTriton_HandleState(device, joystick, pTritonReport); 399 } 400 break; 401 case ID_TRITON_BATTERY_STATUS: 402 if (joystick && r >= (1 + sizeof(TritonBatteryStatus_t))) { 403 TritonBatteryStatus_t *pTritonBatteryStatus = (TritonBatteryStatus_t *)&data[1]; 404 HIDAPI_DriverSteamTriton_HandleBatteryStatus(device, joystick, pTritonBatteryStatus); 405 } 406 break; 407 case ID_TRITON_WIRELESS_STATUS_X: 408 case ID_TRITON_WIRELESS_STATUS: 409 if (r >= (1 + sizeof(TritonWirelessStatus_t))) { 410 TritonWirelessStatus_t *pTritonWirelessStatus = (TritonWirelessStatus_t *)&data[1]; 411 HIDAPI_DriverSteamTriton_HandleWirelessStatus(device, pTritonWirelessStatus); 412 } 413 break; 414 default: 415 break; 416 } 417 } 418} 419 420static bool HIDAPI_DriverSteamTriton_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 421{ 422 float update_rate_in_hz = 1000000.0f / TRITON_SENSOR_UPDATE_INTERVAL_US; 423 424 SDL_AssertJoysticksLocked(); 425 426 // Initialize the joystick capabilities 427 joystick->nbuttons = SDL_GAMEPAD_NUM_TRITON_BUTTONS; 428 joystick->naxes = SDL_GAMEPAD_AXIS_COUNT; 429 joystick->nhats = 1; 430 431 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); 432 SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); 433 434 return true; 435} 436 437static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) 438{ 439 int rc; 440 441 //RKRK Not sure about size. Probably 64+1 is OK for ORs 442 Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES]; 443 OutputReportMsg *msg = (OutputReportMsg *)(buffer); 444 445 msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE; 446 msg->payload.hapticRumble.type = 0; 447 msg->payload.hapticRumble.intensity = 0; 448 msg->payload.hapticRumble.left.speed = low_frequency_rumble; 449 msg->payload.hapticRumble.left.gain = 0; 450 msg->payload.hapticRumble.right.speed = high_frequency_rumble; 451 msg->payload.hapticRumble.right.gain = 0; 452 453 454 rc = SDL_hid_write(device->dev, buffer, sizeof(buffer)); 455 if (rc != sizeof(buffer)) { 456 return false; 457 } 458 return true; 459} 460 461static bool HIDAPI_DriverSteamTriton_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) 462{ 463 return SDL_Unsupported(); 464} 465 466static Uint32 HIDAPI_DriverSteamTriton_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 467{ 468 return SDL_JOYSTICK_CAP_RUMBLE; 469} 470 471static bool HIDAPI_DriverSteamTriton_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) 472{ 473 return SDL_Unsupported(); 474} 475 476static bool HIDAPI_DriverSteamTriton_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) 477{ 478 return SDL_Unsupported(); 479} 480 481static bool HIDAPI_DriverSteamTriton_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled) 482{ 483 SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; 484 int rc; 485 Uint8 buffer[HID_FEATURE_REPORT_BYTES] = { 1 }; 486 FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); 487 488 msg->header.type = ID_SET_SETTINGS_VALUES; 489 msg->header.length = 1 * sizeof(ControllerSetting); 490 msg->payload.setSettingsValues.settings[0].settingNum = SETTING_IMU_MODE; 491 if (enabled) { 492 msg->payload.setSettingsValues.settings[0].settingValue = (SETTING_GYRO_MODE_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO); 493 } else { 494 msg->payload.setSettingsValues.settings[0].settingValue = SETTING_GYRO_MODE_OFF; 495 } 496 497 rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer)); 498 if (rc != sizeof(buffer)) { 499 return false; 500 } 501 502 ctx->report_sensors = enabled; 503 504 return true; 505} 506 507static void HIDAPI_DriverSteamTriton_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) 508{ 509 // Lizard mode id automatically re-enabled by watchdog. Nothing to do here. 510} 511 512static void HIDAPI_DriverSteamTriton_FreeDevice(SDL_HIDAPI_Device *device) 513{ 514} 515 516SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamTriton = { 517 SDL_HINT_JOYSTICK_HIDAPI_STEAM, 518 true, 519 HIDAPI_DriverSteamTriton_RegisterHints, 520 HIDAPI_DriverSteamTriton_UnregisterHints, 521 HIDAPI_DriverSteamTriton_IsEnabled, 522 HIDAPI_DriverSteamTriton_IsSupportedDevice, 523 HIDAPI_DriverSteamTriton_InitDevice, 524 HIDAPI_DriverSteamTriton_GetDevicePlayerIndex, 525 HIDAPI_DriverSteamTriton_SetDevicePlayerIndex, 526 HIDAPI_DriverSteamTriton_UpdateDevice, 527 HIDAPI_DriverSteamTriton_OpenJoystick, 528 HIDAPI_DriverSteamTriton_RumbleJoystick, 529 HIDAPI_DriverSteamTriton_RumbleJoystickTriggers, 530 HIDAPI_DriverSteamTriton_GetJoystickCapabilities, 531 HIDAPI_DriverSteamTriton_SetJoystickLED, 532 HIDAPI_DriverSteamTriton_SendJoystickEffect, 533 HIDAPI_DriverSteamTriton_SetSensorsEnabled, 534 HIDAPI_DriverSteamTriton_CloseJoystick, 535 HIDAPI_DriverSteamTriton_FreeDevice, 536}; 537 538#endif // SDL_JOYSTICK_HIDAPI_STEAM_TRITON 539 540#endif // SDL_JOYSTICK_HIDAPI 541
[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.