controller_structs.h 15 KB

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