blob: 4ca91153215dc36080bbef24ca9288f0a3202f37 [file] [log] [blame]
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
// Purpose: Defines methods and structures used to communicate with Valve controllers.
//
//==================================================================================================
#ifndef _CONTROLLER_STRUCTS_
#define _CONTROLLER_STRUCTS_
#pragma pack(1)
// 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 shoudl 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 upto 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_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 mimcs 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;
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;
} payload;
} ValveInReport_t;
// Enumeration for BLE packet protocol
enum EBLEPacketReportNums
{
// Skipping past 2-3 because they are escape characters in Uart protocol
k_EBLEReportState = 4,
k_EBLEReportStatus = 5,
};
// Enumeration of data chunks in BLE state packets
enum EBLEOptionDataChunksBitmask
{
// First byte uppper 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,
};
#pragma pack()
#endif // _CONTROLLER_STRUCTS