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