Atlas - controller_structs.h

Home / ext / SDL / src / joystick / hidapi / steam Lines: 1 | Size: 14733 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 2020 Valve Corporation 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#ifndef _CONTROLLER_STRUCTS_ 22#define _CONTROLLER_STRUCTS_ 23 24#pragma pack(1) 25 26#define HID_FEATURE_REPORT_BYTES 64 27 28// Header for all host <==> target messages 29typedef struct 30{ 31 unsigned char type; 32 unsigned char length; 33} FeatureReportHeader; 34 35// Generic controller settings structure 36typedef struct 37{ 38 unsigned char settingNum; 39 unsigned short settingValue; 40} ControllerSetting; 41 42// Generic controller attribute structure 43typedef struct 44{ 45 unsigned char attributeTag; 46 uint32_t attributeValue; 47} ControllerAttribute; 48 49// Generic controller settings structure 50typedef struct 51{ 52 ControllerSetting settings[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerSetting ) ]; 53} MsgSetSettingsValues, MsgGetSettingsValues, MsgGetSettingsDefaults, MsgGetSettingsMaxs; 54 55// Generic controller settings structure 56typedef struct 57{ 58 ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ]; 59} MsgGetAttributes; 60 61typedef struct 62{ 63 unsigned char attributeTag; 64 char attributeValue[20]; 65} MsgGetStringAttribute; 66 67typedef struct 68{ 69 unsigned char mode; 70} MsgSetControllerMode; 71 72// Trigger a haptic pulse 73typedef struct { 74 unsigned char which_pad; 75 unsigned short pulse_duration; 76 unsigned short pulse_interval; 77 unsigned short pulse_count; 78 short dBgain; 79 unsigned char priority; 80} MsgFireHapticPulse; 81 82typedef struct { 83 uint8_t mode; 84} MsgHapticSetMode; 85 86typedef enum { 87 HAPTIC_TYPE_OFF, 88 HAPTIC_TYPE_TICK, 89 HAPTIC_TYPE_CLICK, 90 HAPTIC_TYPE_TONE, 91 HAPTIC_TYPE_RUMBLE, 92 HAPTIC_TYPE_NOISE, 93 HAPTIC_TYPE_SCRIPT, 94 HAPTIC_TYPE_LOG_SWEEP, 95} haptic_type_t; 96 97typedef enum { 98 HAPTIC_INTENSITY_SYSTEM, 99 HAPTIC_INTENSITY_SHORT, 100 HAPTIC_INTENSITY_MEDIUM, 101 HAPTIC_INTENSITY_LONG, 102 HAPTIC_INTENSITY_INSANE, 103} haptic_intensity_t; 104 105typedef struct { 106 uint8_t side; // 0x01 = L, 0x02 = R, 0x03 = Both 107 uint8_t cmd; // 0 = Off, 1 = tick, 2 = click, 3 = tone, 4 = rumble, 5 = 108 // rumble_noise, 6 = script, 7 = sweep, 109 uint8_t ui_intensity; // 0-4 (0 = default) 110 int8_t dBgain; // dB Can be positive (reasonable clipping / limiting will apply) 111 uint16_t freq; // Frequency of tone (if applicable) 112 int16_t dur_ms; // Duration of tone / rumble (if applicable) (neg = infinite) 113 114 uint16_t noise_intensity; 115 uint16_t lfo_freq; // Drives both tone and rumble generators 116 uint8_t lfo_depth; // percentage, typically 100 117 uint8_t rand_tone_gain; // Randomize each LFO cycle's gain 118 uint8_t script_id; // Used w/ dBgain for scripted haptics 119 120 uint16_t lss_start_freq; // Used w/ Log Sine Sweep 121 uint16_t lss_end_freq; // Ditto 122} MsgTriggerHaptic; 123 124typedef struct { 125 uint8_t unRumbleType; 126 uint16_t unIntensity; 127 uint16_t unLeftMotorSpeed; 128 uint16_t unRightMotorSpeed; 129 int8_t nLeftGain; 130 int8_t nRightGain; 131} MsgSimpleRumbleCmd; 132 133// This is the only message struct that application code should use to interact with feature request messages. Any new 134// messages should be added to the union. The structures defined here should correspond to the ones defined in 135// ValveDeviceCore.cpp. 136// 137typedef struct 138{ 139 FeatureReportHeader header; 140 union 141 { 142 MsgSetSettingsValues setSettingsValues; 143 MsgGetSettingsValues getSettingsValues; 144 MsgGetSettingsMaxs getSettingsMaxs; 145 MsgGetSettingsDefaults getSettingsDefaults; 146 MsgGetAttributes getAttributes; 147 MsgSetControllerMode controllerMode; 148 MsgFireHapticPulse fireHapticPulse; 149 MsgGetStringAttribute getStringAttribute; 150 MsgHapticSetMode hapticMode; 151 MsgTriggerHaptic triggerHaptic; 152 MsgSimpleRumbleCmd simpleRumble; 153 } payload; 154 155} FeatureReportMsg; 156 157// Triton and derivatives utilize output reports for haptic commands. This is a 158// snapshot from Nov 2024 -- things may change. 159 160// Triton Output Report Lengths #defs include +1 for the OR ID 161 162// Output Report Haptic Messages for Triton 163typedef struct 164{ 165 uint8_t type; 166 uint16_t intensity; 167 struct 168 { 169 uint16_t speed; 170 int8_t gain; 171 } left, right; 172} MsgHapticRumble; 173#define HID_RUMBLE_OUTPUT_REPORT_BYTES 10 174 175 176typedef struct 177{ 178 uint8_t side; 179 uint16_t on_us; 180 uint16_t off_us; 181 uint16_t repeat_count; 182 uint16_t gain_db; 183} MsgHapticPulse; 184#define HID_HAPTIC_PULSE_OUTPUT_REPORT_BYTES 10 185 186typedef struct 187{ 188 uint8_t side; 189 uint8_t command; 190 int8_t gain_db; 191} MsgHapticCommand; 192#define HID_HAPTIC_COMMAND_REPORT_BYTES 4 193 194typedef struct 195{ 196 uint8_t side; 197 int8_t gain_db; 198 uint16_t frequency; 199 uint16_t duration_ms; 200 uint16_t lfo_freq; 201 uint8_t lfo_depth; 202} MsgHapticLfoTone; 203#define HID_HAPTIC_LFO_TONE_REPORT_BYTES 10 204 205typedef struct 206{ 207 uint8_t side; 208 int8_t gain_db; 209 uint16_t duration_ms; 210 struct 211 { 212 uint16_t frequency; 213 } start, end; 214} MsgHapticLogSweep; 215#define HID_HAPTIC_LOG_SWEEP_REPORT_BYTES 9 216 217typedef struct m 218{ 219 uint8_t side; 220 uint8_t script_id; 221 int8_t gain_db; 222} MsgHapticScript; 223#define HID_HAPTIC_SCRIPT_REPORT_BYTES 4 224 225typedef enum 226{ 227 ID_OUT_REPORT_HAPTIC_RUMBLE = 0x80, 228 ID_OUT_REPORT_HAPTIC_PULSE = 0x81, 229 ID_OUT_REPORT_HAPTIC_COMMAND = 0x82, 230 ID_OUT_REPORT_HAPTIC_LFO_TONE = 0x83, 231 ID_OUT_REPORT_HAPTIC_LOG_SWEEP = 0x85, 232 ID_OUT_REPORT_HAPTIC_SCRIPT = 0x86, 233} ValveTritonOutReportMessageIDs; 234 235typedef struct 236{ 237 uint8_t report_id; 238 union 239 { 240 MsgHapticRumble hapticRumble; 241 MsgHapticPulse hapticPulse; 242 MsgHapticCommand hapticCommand; 243 MsgHapticLfoTone hapticLfoTone; 244 MsgHapticLogSweep hapticLogSweep; 245 MsgHapticScript hapticScript; 246 } payload; 247 248} OutputReportMsg; 249 250 251// Roll this version forward anytime that you are breaking compatibility of existing 252// message types within ValveInReport_t or the header itself. Hopefully this should 253// be super rare and instead you should just add new message payloads to the union, 254// or just add fields to the end of existing payload structs which is expected to be 255// safe in all code consuming these as they should just consume/copy up to the prior size 256// they were aware of when processing. 257#define k_ValveInReportMsgVersion 0x01 258 259typedef enum 260{ 261 ID_CONTROLLER_STATE = 1, 262 ID_CONTROLLER_DEBUG = 2, 263 ID_CONTROLLER_WIRELESS = 3, 264 ID_CONTROLLER_STATUS = 4, 265 ID_CONTROLLER_DEBUG2 = 5, 266 ID_CONTROLLER_SECONDARY_STATE = 6, 267 ID_CONTROLLER_BLE_STATE = 7, 268 ID_CONTROLLER_DECK_STATE = 9, 269 ID_CONTROLLER_MSG_COUNT 270} ValveInReportMessageIDs; 271 272typedef struct 273{ 274 unsigned short unReportVersion; 275 276 unsigned char ucType; 277 unsigned char ucLength; 278 279} ValveInReportHeader_t; 280 281// State payload 282typedef struct 283{ 284 // If packet num matches that on your prior call, then the controller state hasn't been changed since 285 // your last call and there is no need to process it 286 Uint32 unPacketNum; 287 288 // Button bitmask and trigger data. 289 union 290 { 291 Uint64 ulButtons; 292 struct 293 { 294 unsigned char _pad0[3]; 295 unsigned char nLeft; 296 unsigned char nRight; 297 unsigned char _pad1[3]; 298 } Triggers; 299 } ButtonTriggerData; 300 301 // Left pad coordinates 302 short sLeftPadX; 303 short sLeftPadY; 304 305 // Right pad coordinates 306 short sRightPadX; 307 short sRightPadY; 308 309 // This is redundant, packed above, but still sent over wired 310 unsigned short sTriggerL; 311 unsigned short sTriggerR; 312 313 // FIXME figure out a way to grab this stuff over wireless 314 short sAccelX; 315 short sAccelY; 316 short sAccelZ; 317 318 short sGyroX; 319 short sGyroY; 320 short sGyroZ; 321 322 short sGyroQuatW; 323 short sGyroQuatX; 324 short sGyroQuatY; 325 short sGyroQuatZ; 326 327} ValveControllerStatePacket_t; 328 329// BLE State payload this has to be re-formatted from the normal state because BLE controller shows up as 330//a HID device and we don't want to send all the optional parts of the message. Keep in sync with struct above. 331typedef struct 332{ 333 // If packet num matches that on your prior call, then the controller state hasn't been changed since 334 // your last call and there is no need to process it 335 Uint32 unPacketNum; 336 337 // Button bitmask and trigger data. 338 union 339 { 340 Uint64 ulButtons; 341 struct 342 { 343 unsigned char _pad0[3]; 344 unsigned char nLeft; 345 unsigned char nRight; 346 unsigned char _pad1[3]; 347 } Triggers; 348 } ButtonTriggerData; 349 350 // Left pad coordinates 351 short sLeftPadX; 352 short sLeftPadY; 353 354 // Right pad coordinates 355 short sRightPadX; 356 short sRightPadY; 357 358 //This mimics how the dongle reconstitutes HID packets, there will be 0-4 shorts depending on gyro mode 359 unsigned char ucGyroDataType; //TODO could maybe find some unused bits in the button field for this info (is only 2bits) 360 short sGyro[4]; 361 362} ValveControllerBLEStatePacket_t; 363 364// Define a payload for reporting debug information 365typedef struct 366{ 367 // Left pad coordinates 368 short sLeftPadX; 369 short sLeftPadY; 370 371 // Right pad coordinates 372 short sRightPadX; 373 short sRightPadY; 374 375 // Left mouse deltas 376 short sLeftPadMouseDX; 377 short sLeftPadMouseDY; 378 379 // Right mouse deltas 380 short sRightPadMouseDX; 381 short sRightPadMouseDY; 382 383 // Left mouse filtered deltas 384 short sLeftPadMouseFilteredDX; 385 short sLeftPadMouseFilteredDY; 386 387 // Right mouse filtered deltas 388 short sRightPadMouseFilteredDX; 389 short sRightPadMouseFilteredDY; 390 391 // Pad Z values 392 unsigned char ucLeftZ; 393 unsigned char ucRightZ; 394 395 // FingerPresent 396 unsigned char ucLeftFingerPresent; 397 unsigned char ucRightFingerPresent; 398 399 // Timestamps 400 unsigned char ucLeftTimestamp; 401 unsigned char ucRightTimestamp; 402 403 // Double tap state 404 unsigned char ucLeftTapState; 405 unsigned char ucRightTapState; 406 407 unsigned int unDigitalIOStates0; 408 unsigned int unDigitalIOStates1; 409 410} ValveControllerDebugPacket_t; 411 412typedef struct 413{ 414 unsigned char ucPadNum; 415 unsigned char ucPad[3]; // need Data to be word aligned 416 short Data[20]; 417 unsigned short unNoise; 418} ValveControllerTrackpadImage_t; 419 420typedef struct 421{ 422 unsigned char ucPadNum; 423 unsigned char ucOffset; 424 unsigned char ucPad[2]; // need Data to be word aligned 425 short rgData[28]; 426} ValveControllerRawTrackpadImage_t; 427 428// Payload for wireless metadata 429typedef struct 430{ 431 unsigned char ucEventType; 432} SteamControllerWirelessEvent_t; 433 434typedef struct 435{ 436 // Current packet number. 437 unsigned int unPacketNum; 438 439 // Event codes and state information. 440 unsigned short sEventCode; 441 unsigned short unStateFlags; 442 443 // Current battery voltage (mV). 444 unsigned short sBatteryVoltage; 445 446 // Current battery level (0-100). 447 unsigned char ucBatteryLevel; 448} SteamControllerStatusEvent_t; 449 450// Deck State payload 451typedef struct 452{ 453 // If packet num matches that on your prior call, then the controller 454 // state hasn't been changed since your last call and there is no need to 455 // process it 456 Uint32 unPacketNum; 457 458 // Button bitmask and trigger data. 459 union 460 { 461 Uint64 ulButtons; 462 struct 463 { 464 Uint32 ulButtonsL; 465 Uint32 ulButtonsH; 466 }; 467 }; 468 469 // Left pad coordinates 470 short sLeftPadX; 471 short sLeftPadY; 472 473 // Right pad coordinates 474 short sRightPadX; 475 short sRightPadY; 476 477 // Accelerometer values 478 short sAccelX; 479 short sAccelY; 480 short sAccelZ; 481 482 // Gyroscope values 483 short sGyroX; 484 short sGyroY; 485 short sGyroZ; 486 487 // Gyro quaternions 488 short sGyroQuatW; 489 short sGyroQuatX; 490 short sGyroQuatY; 491 short sGyroQuatZ; 492 493 // Uncalibrated trigger values 494 unsigned short sTriggerRawL; 495 unsigned short sTriggerRawR; 496 497 // Left stick values 498 short sLeftStickX; 499 short sLeftStickY; 500 501 // Right stick values 502 short sRightStickX; 503 short sRightStickY; 504 505 // Touchpad pressures 506 unsigned short sPressurePadLeft; 507 unsigned short sPressurePadRight; 508} SteamDeckStatePacket_t; 509 510 511typedef struct 512{ 513 ValveInReportHeader_t header; 514 515 union 516 { 517 ValveControllerStatePacket_t controllerState; 518 ValveControllerBLEStatePacket_t controllerBLEState; 519 ValveControllerDebugPacket_t debugState; 520 ValveControllerTrackpadImage_t padImage; 521 ValveControllerRawTrackpadImage_t rawPadImage; 522 SteamControllerWirelessEvent_t wirelessEvent; 523 SteamControllerStatusEvent_t statusEvent; 524 SteamDeckStatePacket_t deckState; 525 } payload; 526 527} ValveInReport_t; 528 529enum EBLEPacketReportNums 530{ 531 k_EBLEReportState = 4, 532 k_EBLEReportStatus = 5, 533}; 534// Enumeration of data chunks in BLE state packets 535enum EBLEOptionDataChunksBitmask 536{ 537 // First byte upper nibble 538 k_EBLEButtonChunk1 = 0x10, 539 k_EBLEButtonChunk2 = 0x20, 540 k_EBLEButtonChunk3 = 0x40, 541 k_EBLELeftJoystickChunk = 0x80, 542 543 // Second full byte 544 k_EBLELeftTrackpadChunk = 0x100, 545 k_EBLERightTrackpadChunk = 0x200, 546 k_EBLEIMUAccelChunk = 0x400, 547 k_EBLEIMUGyroChunk = 0x800, 548 k_EBLEIMUQuatChunk = 0x1000, 549}; 550 551// Triton and derivatives do not use the ValveInReport_t structure 552 553enum ETritonReportIDTypes 554{ 555 ID_TRITON_CONTROLLER_STATE = 0x42, 556 ID_TRITON_BATTERY_STATUS = 0x43, 557 ID_TRITON_WIRELESS_STATUS_X = 0x46, 558 ID_TRITON_WIRELESS_STATUS = 0x79, 559}; 560 561enum ETritonWirelessState 562{ 563 k_ETritonWirelessStateDisconnect = 1, 564 k_ETritonWirelessStateConnect = 2, 565}; 566 567typedef struct 568{ 569 uint32_t uTimestamp; 570 short sAccelX; 571 short sAccelY; 572 short sAccelZ; 573 574 short sGyroX; 575 short sGyroY; 576 short sGyroZ; 577 578 short sGyroQuatW; 579 short sGyroQuatX; 580 short sGyroQuatY; 581 short sGyroQuatZ; 582} TritonMTUIMU_t; 583 584typedef struct 585{ 586 uint8_t cSeq_num; 587 uint32_t uButtons; 588 short sTriggerLeft; 589 short sTriggerRight; 590 591 short sLeftStickX; 592 short sLeftStickY; 593 short sRightStickX; 594 short sRightStickY; 595 596 short sLeftPadX; 597 short sLeftPadY; 598 unsigned short ucPressureLeft; 599 600 short sRightPadX; 601 short sRightPadY; 602 unsigned short ucPressureRight; 603 TritonMTUIMU_t imu; 604} TritonMTUFull_t; 605 606typedef struct 607{ 608 unsigned char ucBatteryLevel; 609 unsigned short sBatteryVoltage; 610 unsigned short sSystemVoltage; 611 unsigned short sInputVoltage; 612 unsigned short sCurrent; 613 unsigned short sInputCurrent; 614 char cTemperature; 615} TritonBatteryStatus_t; 616 617typedef struct 618{ 619 unsigned char state; 620} TritonWirelessStatus_t; 621 622#pragma pack() 623 624#endif // _CONTROLLER_STRUCTS 625
[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.