| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 2020 Valve Corporation
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #ifndef _CONTROLLER_STRUCTS_
- #define _CONTROLLER_STRUCTS_
- #pragma pack(1)
- #define HID_FEATURE_REPORT_BYTES 64
- // Header for all host <==> target messages
- typedef struct
- {
- unsigned char type;
- unsigned char length;
- } FeatureReportHeader;
- // Generic controller settings structure
- typedef struct
- {
- unsigned char settingNum;
- unsigned short settingValue;
- } ControllerSetting;
- // Generic controller attribute structure
- typedef struct
- {
- unsigned char attributeTag;
- uint32_t attributeValue;
- } ControllerAttribute;
- // Generic controller settings structure
- typedef struct
- {
- ControllerSetting settings[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerSetting ) ];
- } MsgSetSettingsValues, MsgGetSettingsValues, MsgGetSettingsDefaults, MsgGetSettingsMaxs;
- // Generic controller settings structure
- typedef struct
- {
- ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
- } MsgGetAttributes;
- typedef struct
- {
- unsigned char attributeTag;
- char attributeValue[20];
- } MsgGetStringAttribute;
- typedef struct
- {
- unsigned char mode;
- } MsgSetControllerMode;
- // Trigger a haptic pulse
- typedef struct {
- unsigned char which_pad;
- unsigned short pulse_duration;
- unsigned short pulse_interval;
- unsigned short pulse_count;
- short dBgain;
- unsigned char priority;
- } MsgFireHapticPulse;
- typedef struct {
- uint8_t mode;
- } MsgHapticSetMode;
- typedef enum {
- HAPTIC_TYPE_OFF,
- HAPTIC_TYPE_TICK,
- HAPTIC_TYPE_CLICK,
- HAPTIC_TYPE_TONE,
- HAPTIC_TYPE_RUMBLE,
- HAPTIC_TYPE_NOISE,
- HAPTIC_TYPE_SCRIPT,
- HAPTIC_TYPE_LOG_SWEEP,
- } haptic_type_t;
- typedef enum {
- HAPTIC_INTENSITY_SYSTEM,
- HAPTIC_INTENSITY_SHORT,
- HAPTIC_INTENSITY_MEDIUM,
- HAPTIC_INTENSITY_LONG,
- HAPTIC_INTENSITY_INSANE,
- } haptic_intensity_t;
- typedef struct {
- uint8_t side; // 0x01 = L, 0x02 = R, 0x03 = Both
- uint8_t cmd; // 0 = Off, 1 = tick, 2 = click, 3 = tone, 4 = rumble, 5 =
- // rumble_noise, 6 = script, 7 = sweep,
- uint8_t ui_intensity; // 0-4 (0 = default)
- int8_t dBgain; // dB Can be positive (reasonable clipping / limiting will apply)
- uint16_t freq; // Frequency of tone (if applicable)
- int16_t dur_ms; // Duration of tone / rumble (if applicable) (neg = infinite)
- uint16_t noise_intensity;
- uint16_t lfo_freq; // Drives both tone and rumble generators
- uint8_t lfo_depth; // percentage, typically 100
- uint8_t rand_tone_gain; // Randomize each LFO cycle's gain
- uint8_t script_id; // Used w/ dBgain for scripted haptics
- uint16_t lss_start_freq; // Used w/ Log Sine Sweep
- uint16_t lss_end_freq; // Ditto
- } MsgTriggerHaptic;
- typedef struct {
- uint8_t unRumbleType;
- uint16_t unIntensity;
- uint16_t unLeftMotorSpeed;
- uint16_t unRightMotorSpeed;
- int8_t nLeftGain;
- int8_t nRightGain;
- } MsgSimpleRumbleCmd;
- // This is the only message struct that application code should use to interact with feature request messages. Any new
- // messages should be added to the union. The structures defined here should correspond to the ones defined in
- // ValveDeviceCore.cpp.
- //
- typedef struct
- {
- FeatureReportHeader header;
- union
- {
- MsgSetSettingsValues setSettingsValues;
- MsgGetSettingsValues getSettingsValues;
- MsgGetSettingsMaxs getSettingsMaxs;
- MsgGetSettingsDefaults getSettingsDefaults;
- MsgGetAttributes getAttributes;
- MsgSetControllerMode controllerMode;
- MsgFireHapticPulse fireHapticPulse;
- MsgGetStringAttribute getStringAttribute;
- MsgHapticSetMode hapticMode;
- MsgTriggerHaptic triggerHaptic;
- MsgSimpleRumbleCmd simpleRumble;
- } payload;
- } FeatureReportMsg;
- // Triton and derivatives utilize output reports for haptic commands. This is a
- // snapshot from Nov 2024 -- things may change.
- // Triton Output Report Lengths #defs include +1 for the OR ID
- // Output Report Haptic Messages for Triton
- typedef struct
- {
- uint8_t type;
- uint16_t intensity;
- struct
- {
- uint16_t speed;
- int8_t gain;
- } left, right;
- } MsgHapticRumble;
- #define HID_RUMBLE_OUTPUT_REPORT_BYTES 10
- typedef struct
- {
- uint8_t side;
- uint16_t on_us;
- uint16_t off_us;
- uint16_t repeat_count;
- uint16_t gain_db;
- } MsgHapticPulse;
- #define HID_HAPTIC_PULSE_OUTPUT_REPORT_BYTES 10
- typedef struct
- {
- uint8_t side;
- uint8_t command;
- int8_t gain_db;
- } MsgHapticCommand;
- #define HID_HAPTIC_COMMAND_REPORT_BYTES 4
- typedef struct
- {
- uint8_t side;
- int8_t gain_db;
- uint16_t frequency;
- uint16_t duration_ms;
- uint16_t lfo_freq;
- uint8_t lfo_depth;
- } MsgHapticLfoTone;
- #define HID_HAPTIC_LFO_TONE_REPORT_BYTES 10
- typedef struct
- {
- uint8_t side;
- int8_t gain_db;
- uint16_t duration_ms;
- struct
- {
- uint16_t frequency;
- } start, end;
- } MsgHapticLogSweep;
- #define HID_HAPTIC_LOG_SWEEP_REPORT_BYTES 9
- typedef struct m
- {
- uint8_t side;
- uint8_t script_id;
- int8_t gain_db;
- } MsgHapticScript;
- #define HID_HAPTIC_SCRIPT_REPORT_BYTES 4
- typedef enum
- {
- ID_OUT_REPORT_HAPTIC_RUMBLE = 0x80,
- ID_OUT_REPORT_HAPTIC_PULSE = 0x81,
- ID_OUT_REPORT_HAPTIC_COMMAND = 0x82,
- ID_OUT_REPORT_HAPTIC_LFO_TONE = 0x83,
- ID_OUT_REPORT_HAPTIC_LOG_SWEEP = 0x85,
- ID_OUT_REPORT_HAPTIC_SCRIPT = 0x86,
- } ValveTritonOutReportMessageIDs;
- typedef struct
- {
- uint8_t report_id;
- union
- {
- MsgHapticRumble hapticRumble;
- MsgHapticPulse hapticPulse;
- MsgHapticCommand hapticCommand;
- MsgHapticLfoTone hapticLfoTone;
- MsgHapticLogSweep hapticLogSweep;
- MsgHapticScript hapticScript;
- } payload;
- } OutputReportMsg;
- // Roll this version forward anytime that you are breaking compatibility of existing
- // message types within ValveInReport_t or the header itself. Hopefully this should
- // be super rare and instead you should just add new message payloads to the union,
- // or just add fields to the end of existing payload structs which is expected to be
- // safe in all code consuming these as they should just consume/copy up to the prior size
- // they were aware of when processing.
- #define k_ValveInReportMsgVersion 0x01
- typedef enum
- {
- ID_CONTROLLER_STATE = 1,
- ID_CONTROLLER_DEBUG = 2,
- ID_CONTROLLER_WIRELESS = 3,
- ID_CONTROLLER_STATUS = 4,
- ID_CONTROLLER_DEBUG2 = 5,
- ID_CONTROLLER_SECONDARY_STATE = 6,
- ID_CONTROLLER_BLE_STATE = 7,
- ID_CONTROLLER_DECK_STATE = 9,
- ID_CONTROLLER_MSG_COUNT
- } ValveInReportMessageIDs;
- typedef struct
- {
- unsigned short unReportVersion;
-
- unsigned char ucType;
- unsigned char ucLength;
-
- } ValveInReportHeader_t;
- // State payload
- typedef struct
- {
- // If packet num matches that on your prior call, then the controller state hasn't been changed since
- // your last call and there is no need to process it
- Uint32 unPacketNum;
-
- // Button bitmask and trigger data.
- union
- {
- Uint64 ulButtons;
- struct
- {
- unsigned char _pad0[3];
- unsigned char nLeft;
- unsigned char nRight;
- unsigned char _pad1[3];
- } Triggers;
- } ButtonTriggerData;
-
- // Left pad coordinates
- short sLeftPadX;
- short sLeftPadY;
-
- // Right pad coordinates
- short sRightPadX;
- short sRightPadY;
-
- // This is redundant, packed above, but still sent over wired
- unsigned short sTriggerL;
- unsigned short sTriggerR;
- // FIXME figure out a way to grab this stuff over wireless
- short sAccelX;
- short sAccelY;
- short sAccelZ;
-
- short sGyroX;
- short sGyroY;
- short sGyroZ;
-
- short sGyroQuatW;
- short sGyroQuatX;
- short sGyroQuatY;
- short sGyroQuatZ;
- } ValveControllerStatePacket_t;
- // BLE State payload this has to be re-formatted from the normal state because BLE controller shows up as
- //a HID device and we don't want to send all the optional parts of the message. Keep in sync with struct above.
- typedef struct
- {
- // If packet num matches that on your prior call, then the controller state hasn't been changed since
- // your last call and there is no need to process it
- Uint32 unPacketNum;
- // Button bitmask and trigger data.
- union
- {
- Uint64 ulButtons;
- struct
- {
- unsigned char _pad0[3];
- unsigned char nLeft;
- unsigned char nRight;
- unsigned char _pad1[3];
- } Triggers;
- } ButtonTriggerData;
- // Left pad coordinates
- short sLeftPadX;
- short sLeftPadY;
- // Right pad coordinates
- short sRightPadX;
- short sRightPadY;
- //This mimics how the dongle reconstitutes HID packets, there will be 0-4 shorts depending on gyro mode
- unsigned char ucGyroDataType; //TODO could maybe find some unused bits in the button field for this info (is only 2bits)
- short sGyro[4];
- } ValveControllerBLEStatePacket_t;
- // Define a payload for reporting debug information
- typedef struct
- {
- // Left pad coordinates
- short sLeftPadX;
- short sLeftPadY;
- // Right pad coordinates
- short sRightPadX;
- short sRightPadY;
- // Left mouse deltas
- short sLeftPadMouseDX;
- short sLeftPadMouseDY;
- // Right mouse deltas
- short sRightPadMouseDX;
- short sRightPadMouseDY;
-
- // Left mouse filtered deltas
- short sLeftPadMouseFilteredDX;
- short sLeftPadMouseFilteredDY;
- // Right mouse filtered deltas
- short sRightPadMouseFilteredDX;
- short sRightPadMouseFilteredDY;
-
- // Pad Z values
- unsigned char ucLeftZ;
- unsigned char ucRightZ;
-
- // FingerPresent
- unsigned char ucLeftFingerPresent;
- unsigned char ucRightFingerPresent;
-
- // Timestamps
- unsigned char ucLeftTimestamp;
- unsigned char ucRightTimestamp;
-
- // Double tap state
- unsigned char ucLeftTapState;
- unsigned char ucRightTapState;
-
- unsigned int unDigitalIOStates0;
- unsigned int unDigitalIOStates1;
-
- } ValveControllerDebugPacket_t;
- typedef struct
- {
- unsigned char ucPadNum;
- unsigned char ucPad[3]; // need Data to be word aligned
- short Data[20];
- unsigned short unNoise;
- } ValveControllerTrackpadImage_t;
- typedef struct
- {
- unsigned char ucPadNum;
- unsigned char ucOffset;
- unsigned char ucPad[2]; // need Data to be word aligned
- short rgData[28];
- } ValveControllerRawTrackpadImage_t;
- // Payload for wireless metadata
- typedef struct
- {
- unsigned char ucEventType;
- } SteamControllerWirelessEvent_t;
- typedef struct
- {
- // Current packet number.
- unsigned int unPacketNum;
-
- // Event codes and state information.
- unsigned short sEventCode;
- unsigned short unStateFlags;
- // Current battery voltage (mV).
- unsigned short sBatteryVoltage;
-
- // Current battery level (0-100).
- unsigned char ucBatteryLevel;
- } SteamControllerStatusEvent_t;
- // Deck State payload
- typedef struct
- {
- // If packet num matches that on your prior call, then the controller
- // state hasn't been changed since your last call and there is no need to
- // process it
- Uint32 unPacketNum;
- // Button bitmask and trigger data.
- union
- {
- Uint64 ulButtons;
- struct
- {
- Uint32 ulButtonsL;
- Uint32 ulButtonsH;
- };
- };
- // Left pad coordinates
- short sLeftPadX;
- short sLeftPadY;
- // Right pad coordinates
- short sRightPadX;
- short sRightPadY;
- // Accelerometer values
- short sAccelX;
- short sAccelY;
- short sAccelZ;
- // Gyroscope values
- short sGyroX;
- short sGyroY;
- short sGyroZ;
- // Gyro quaternions
- short sGyroQuatW;
- short sGyroQuatX;
- short sGyroQuatY;
- short sGyroQuatZ;
- // Uncalibrated trigger values
- unsigned short sTriggerRawL;
- unsigned short sTriggerRawR;
- // Left stick values
- short sLeftStickX;
- short sLeftStickY;
- // Right stick values
- short sRightStickX;
- short sRightStickY;
- // Touchpad pressures
- unsigned short sPressurePadLeft;
- unsigned short sPressurePadRight;
- } SteamDeckStatePacket_t;
- typedef struct
- {
- ValveInReportHeader_t header;
- union
- {
- ValveControllerStatePacket_t controllerState;
- ValveControllerBLEStatePacket_t controllerBLEState;
- ValveControllerDebugPacket_t debugState;
- ValveControllerTrackpadImage_t padImage;
- ValveControllerRawTrackpadImage_t rawPadImage;
- SteamControllerWirelessEvent_t wirelessEvent;
- SteamControllerStatusEvent_t statusEvent;
- SteamDeckStatePacket_t deckState;
- } payload;
- } ValveInReport_t;
- enum EBLEPacketReportNums
- {
- k_EBLEReportState = 4,
- k_EBLEReportStatus = 5,
- };
- // Enumeration of data chunks in BLE state packets
- enum EBLEOptionDataChunksBitmask
- {
- // First byte upper nibble
- k_EBLEButtonChunk1 = 0x10,
- k_EBLEButtonChunk2 = 0x20,
- k_EBLEButtonChunk3 = 0x40,
- k_EBLELeftJoystickChunk = 0x80,
- // Second full byte
- k_EBLELeftTrackpadChunk = 0x100,
- k_EBLERightTrackpadChunk = 0x200,
- k_EBLEIMUAccelChunk = 0x400,
- k_EBLEIMUGyroChunk = 0x800,
- k_EBLEIMUQuatChunk = 0x1000,
- };
- // Triton and derivatives do not use the ValveInReport_t structure
- enum ETritonReportIDTypes
- {
- ID_TRITON_CONTROLLER_STATE = 0x42,
- ID_TRITON_BATTERY_STATUS = 0x43,
- ID_TRITON_CONTROLLER_STATE_BLE = 0x45,
- ID_TRITON_WIRELESS_STATUS_X = 0x46,
- ID_TRITON_WIRELESS_STATUS = 0x79,
- };
- enum ETritonWirelessState
- {
- k_ETritonWirelessStateDisconnect = 1,
- k_ETritonWirelessStateConnect = 2,
- };
- typedef struct
- {
- uint32_t uTimestamp;
- short sAccelX;
- short sAccelY;
- short sAccelZ;
- short sGyroX;
- short sGyroY;
- short sGyroZ;
- short sGyroQuatW;
- short sGyroQuatX;
- short sGyroQuatY;
- short sGyroQuatZ;
- } TritonMTUIMU_t;
- typedef struct
- {
- uint8_t cSeq_num;
- uint32_t uButtons;
- short sTriggerLeft;
- short sTriggerRight;
- short sLeftStickX;
- short sLeftStickY;
- short sRightStickX;
- short sRightStickY;
- short sLeftPadX;
- short sLeftPadY;
- unsigned short ucPressureLeft;
- short sRightPadX;
- short sRightPadY;
- unsigned short ucPressureRight;
- TritonMTUIMU_t imu;
- } TritonMTUFull_t;
- enum EChargeState
- {
- k_EChargeStateReset,
- k_EChargeStateDischarging,
- k_EChargeStateCharging,
- k_EChargeStateSrcValidate,
- k_EChargeStateChargingDone,
- };
- typedef struct
- {
- unsigned char ucChargeState; // EChargeState
- unsigned char ucBatteryLevel;
- unsigned short sBatteryVoltage;
- unsigned short sSystemVoltage;
- unsigned short sInputVoltage;
- unsigned short sCurrent;
- unsigned short sInputCurrent;
- unsigned short sTemperature;
- } TritonBatteryStatus_t;
- typedef struct
- {
- unsigned char state;
- } TritonWirelessStatus_t;
- #pragma pack()
- #endif // _CONTROLLER_STRUCTS
|