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 // Roll this version forward anytime that you are breaking compatibility of existing 27 // message types within ValveInReport_t or the header itself. Hopefully this should 28 // be super rare and instead you shoudl just add new message payloads to the union, 29 // or just add fields to the end of existing payload structs which is expected to be 30 // safe in all code consuming these as they should just consume/copy upto the prior size 31 // they were aware of when processing. 32 #define k_ValveInReportMsgVersion 0x01 33 34 typedef enum 35 { 36 ID_CONTROLLER_STATE = 1, 37 ID_CONTROLLER_DEBUG = 2, 38 ID_CONTROLLER_WIRELESS = 3, 39 ID_CONTROLLER_STATUS = 4, 40 ID_CONTROLLER_DEBUG2 = 5, 41 ID_CONTROLLER_SECONDARY_STATE = 6, 42 ID_CONTROLLER_BLE_STATE = 7, 43 ID_CONTROLLER_MSG_COUNT 44 } ValveInReportMessageIDs; 45 46 typedef struct 47 { 48 unsigned short unReportVersion; 49 50 unsigned char ucType; 51 unsigned char ucLength; 52 53 } ValveInReportHeader_t; 54 55 // State payload 56 typedef struct 57 { 58 // If packet num matches that on your prior call, then the controller state hasn't been changed since 59 // your last call and there is no need to process it 60 uint32 unPacketNum; 61 62 // Button bitmask and trigger data. 63 union 64 { 65 uint64 ulButtons; 66 struct 67 { 68 unsigned char _pad0[3]; 69 unsigned char nLeft; 70 unsigned char nRight; 71 unsigned char _pad1[3]; 72 } Triggers; 73 } ButtonTriggerData; 74 75 // Left pad coordinates 76 short sLeftPadX; 77 short sLeftPadY; 78 79 // Right pad coordinates 80 short sRightPadX; 81 short sRightPadY; 82 83 // This is redundant, packed above, but still sent over wired 84 unsigned short sTriggerL; 85 unsigned short sTriggerR; 86 87 // FIXME figure out a way to grab this stuff over wireless 88 short sAccelX; 89 short sAccelY; 90 short sAccelZ; 91 92 short sGyroX; 93 short sGyroY; 94 short sGyroZ; 95 96 short sGyroQuatW; 97 short sGyroQuatX; 98 short sGyroQuatY; 99 short sGyroQuatZ; 100 101 } ValveControllerStatePacket_t; 102 103 // BLE State payload this has to be re-formatted from the normal state because BLE controller shows up as 104 //a HID device and we don't want to send all the optional parts of the message. Keep in sync with struct above. 105 typedef struct 106 { 107 // If packet num matches that on your prior call, then the controller state hasn't been changed since 108 // your last call and there is no need to process it 109 uint32 unPacketNum; 110 111 // Button bitmask and trigger data. 112 union 113 { 114 uint64 ulButtons; 115 struct 116 { 117 unsigned char _pad0[3]; 118 unsigned char nLeft; 119 unsigned char nRight; 120 unsigned char _pad1[3]; 121 } Triggers; 122 } ButtonTriggerData; 123 124 // Left pad coordinates 125 short sLeftPadX; 126 short sLeftPadY; 127 128 // Right pad coordinates 129 short sRightPadX; 130 short sRightPadY; 131 132 //This mimcs how the dongle reconstitutes HID packets, there will be 0-4 shorts depending on gyro mode 133 unsigned char ucGyroDataType; //TODO could maybe find some unused bits in the button field for this info (is only 2bits) 134 short sGyro[4]; 135 136 } ValveControllerBLEStatePacket_t; 137 138 // Define a payload for reporting debug information 139 typedef struct 140 { 141 // Left pad coordinates 142 short sLeftPadX; 143 short sLeftPadY; 144 145 // Right pad coordinates 146 short sRightPadX; 147 short sRightPadY; 148 149 // Left mouse deltas 150 short sLeftPadMouseDX; 151 short sLeftPadMouseDY; 152 153 // Right mouse deltas 154 short sRightPadMouseDX; 155 short sRightPadMouseDY; 156 157 // Left mouse filtered deltas 158 short sLeftPadMouseFilteredDX; 159 short sLeftPadMouseFilteredDY; 160 161 // Right mouse filtered deltas 162 short sRightPadMouseFilteredDX; 163 short sRightPadMouseFilteredDY; 164 165 // Pad Z values 166 unsigned char ucLeftZ; 167 unsigned char ucRightZ; 168 169 // FingerPresent 170 unsigned char ucLeftFingerPresent; 171 unsigned char ucRightFingerPresent; 172 173 // Timestamps 174 unsigned char ucLeftTimestamp; 175 unsigned char ucRightTimestamp; 176 177 // Double tap state 178 unsigned char ucLeftTapState; 179 unsigned char ucRightTapState; 180 181 unsigned int unDigitalIOStates0; 182 unsigned int unDigitalIOStates1; 183 184 } ValveControllerDebugPacket_t; 185 186 typedef struct 187 { 188 unsigned char ucPadNum; 189 unsigned char ucPad[3]; // need Data to be word aligned 190 short Data[20]; 191 unsigned short unNoise; 192 } ValveControllerTrackpadImage_t; 193 194 typedef struct 195 { 196 unsigned char ucPadNum; 197 unsigned char ucOffset; 198 unsigned char ucPad[2]; // need Data to be word aligned 199 short rgData[28]; 200 } ValveControllerRawTrackpadImage_t; 201 202 // Payload for wireless metadata 203 typedef struct 204 { 205 unsigned char ucEventType; 206 } SteamControllerWirelessEvent_t; 207 208 typedef struct 209 { 210 // Current packet number. 211 unsigned int unPacketNum; 212 213 // Event codes and state information. 214 unsigned short sEventCode; 215 unsigned short unStateFlags; 216 217 // Current battery voltage (mV). 218 unsigned short sBatteryVoltage; 219 220 // Current battery level (0-100). 221 unsigned char ucBatteryLevel; 222 } SteamControllerStatusEvent_t; 223 224 typedef struct 225 { 226 ValveInReportHeader_t header; 227 228 union 229 { 230 ValveControllerStatePacket_t controllerState; 231 ValveControllerBLEStatePacket_t controllerBLEState; 232 ValveControllerDebugPacket_t debugState; 233 ValveControllerTrackpadImage_t padImage; 234 ValveControllerRawTrackpadImage_t rawPadImage; 235 SteamControllerWirelessEvent_t wirelessEvent; 236 SteamControllerStatusEvent_t statusEvent; 237 } payload; 238 239 } ValveInReport_t; 240 241 242 // Enumeration for BLE packet protocol 243 enum EBLEPacketReportNums 244 { 245 // Skipping past 2-3 because they are escape characters in Uart protocol 246 k_EBLEReportState = 4, 247 k_EBLEReportStatus = 5, 248 }; 249 250 251 // Enumeration of data chunks in BLE state packets 252 enum EBLEOptionDataChunksBitmask 253 { 254 // First byte uppper nibble 255 k_EBLEButtonChunk1 = 0x10, 256 k_EBLEButtonChunk2 = 0x20, 257 k_EBLEButtonChunk3 = 0x40, 258 k_EBLELeftJoystickChunk = 0x80, 259 260 // Second full byte 261 k_EBLELeftTrackpadChunk = 0x100, 262 k_EBLERightTrackpadChunk = 0x200, 263 k_EBLEIMUAccelChunk = 0x400, 264 k_EBLEIMUGyroChunk = 0x800, 265 k_EBLEIMUQuatChunk = 0x1000, 266 }; 267 268 #pragma pack() 269 270 #endif // _CONTROLLER_STRUCTS 271