21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HIDAPI
30 #include "../SDL_sysjoystick.h"
35 #ifdef SDL_JOYSTICK_HIDAPI_STEAM
53 typedef struct SteamControllerStateInternal_t
56 uint32 eControllerType;
85 unsigned short sTriggerL;
86 unsigned short sTriggerR;
101 short sGyroSteeringAngle;
103 unsigned short sBatteryLevel;
106 unsigned short sPressurePadLeft;
107 unsigned short sPressurePadRight;
109 unsigned short sPressureBumperLeft;
110 unsigned short sPressureBumperRight;
113 short sPrevLeftPad[2];
114 short sPrevLeftStick[2];
115 } SteamControllerStateInternal_t;
119 #define STEAM_RIGHT_TRIGGER_MASK 0x00000001
120 #define STEAM_LEFT_TRIGGER_MASK 0x00000002
121 #define STEAM_RIGHT_BUMPER_MASK 0x00000004
122 #define STEAM_LEFT_BUMPER_MASK 0x00000008
123 #define STEAM_BUTTON_0_MASK 0x00000010
124 #define STEAM_BUTTON_1_MASK 0x00000020
125 #define STEAM_BUTTON_2_MASK 0x00000040
126 #define STEAM_BUTTON_3_MASK 0x00000080
127 #define STEAM_TOUCH_0_MASK 0x00000100
128 #define STEAM_TOUCH_1_MASK 0x00000200
129 #define STEAM_TOUCH_2_MASK 0x00000400
130 #define STEAM_TOUCH_3_MASK 0x00000800
131 #define STEAM_BUTTON_MENU_MASK 0x00001000
132 #define STEAM_BUTTON_STEAM_MASK 0x00002000
133 #define STEAM_BUTTON_ESCAPE_MASK 0x00004000
134 #define STEAM_BUTTON_BACK_LEFT_MASK 0x00008000
135 #define STEAM_BUTTON_BACK_RIGHT_MASK 0x00010000
136 #define STEAM_BUTTON_LEFTPAD_CLICKED_MASK 0x00020000
137 #define STEAM_BUTTON_RIGHTPAD_CLICKED_MASK 0x00040000
138 #define STEAM_LEFTPAD_FINGERDOWN_MASK 0x00080000
139 #define STEAM_RIGHTPAD_FINGERDOWN_MASK 0x00100000
140 #define STEAM_JOYSTICK_BUTTON_MASK 0x00400000
141 #define STEAM_LEFTPAD_AND_JOYSTICK_MASK 0x00800000
145 #define D0G_IS_VALID_WIRELESS_EVENT(data, len) ((len) >= 5 && (data)[0] == 1 && (data)[1] == 0 && (data)[2] == 3 && (data)[3] >= 1)
146 #define D0G_GET_WIRELESS_EVENT_TYPE(data) ((data)[4])
147 #define D0G_WIRELESS_DISCONNECTED 1
148 #define D0G_WIRELESS_ESTABLISHED 2
149 #define D0G_WIRELESS_NEWLYPAIRED 3
151 #define D0G_IS_WIRELESS_DISCONNECT(data, len) ( D0G_IS_VALID_WIRELESS_EVENT(data,len) && D0G_GET_WIRELESS_EVENT_TYPE(data) == D0G_WIRELESS_DISCONNECTED )
153 #define MAX_REPORT_SEGMENT_PAYLOAD_SIZE 18
159 uint8_t uBuffer[ MAX_REPORT_SEGMENT_PAYLOAD_SIZE * 8 + 1 ];
160 int nExpectedSegmentNumber;
162 } SteamControllerPacketAssembler;
166 #define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
169 #define offsetof(s,m) (size_t)&(((s *)0)->m)
171 #ifdef DEBUG_STEAM_CONTROLLER
172 #define DPRINTF(format, ...) printf(format, ##__VA_ARGS__)
173 #define HEXDUMP(ptr, len) hexdump(ptr, len)
175 #define DPRINTF(format, ...)
176 #define HEXDUMP(ptr, len)
178 #define printf SDL_Log
180 #define MAX_REPORT_SEGMENT_SIZE ( MAX_REPORT_SEGMENT_PAYLOAD_SIZE + 2 )
181 #define CALC_REPORT_SEGMENT_NUM(index) ( ( index / MAX_REPORT_SEGMENT_PAYLOAD_SIZE ) & 0x07 )
182 #define REPORT_SEGMENT_DATA_FLAG 0x80
183 #define REPORT_SEGMENT_LAST_FLAG 0x40
184 #define BLE_REPORT_NUMBER 0x03
186 #define STEAMCONTROLLER_TRIGGER_MAX_ANALOG 26000
189 #undef ENABLE_MOUSE_MODE
197 #define RADIO_WORKAROUND_SLEEP_ATTEMPTS 50
198 #define RADIO_WORKAROUND_SLEEP_DURATION_US 500
201 #define CONTROLLER_CONFIGURATION_DELAY_US 3000
203 static uint8_t GetSegmentHeader(
int nSegmentNumber,
bool bLastPacket )
205 uint8_t header = REPORT_SEGMENT_DATA_FLAG;
206 header |= nSegmentNumber;
208 header |= REPORT_SEGMENT_LAST_FLAG;
216 for (
i = 0;
i <
len ; ++
i )
217 printf(
"%02x ",
ptr[
i]);
221 static void ResetSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler )
223 memset( pAssembler->uBuffer, 0,
sizeof( pAssembler->uBuffer ) );
224 pAssembler->nExpectedSegmentNumber = 0;
227 static void InitializeSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler )
230 pAssembler->bIsBle =
true;
231 ResetSteamControllerPacketAssembler( pAssembler );
238 static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler,
const uint8_t *pSegment,
int nSegmentLength )
240 if ( pAssembler->bIsBle )
242 HEXDUMP( pSegment, nSegmentLength );
244 if ( pSegment[ 0 ] != BLE_REPORT_NUMBER )
250 if ( nSegmentLength != MAX_REPORT_SEGMENT_SIZE )
252 printf(
"Bad segment size! %d\n", (
int)nSegmentLength );
253 hexdump( pSegment, nSegmentLength );
254 ResetSteamControllerPacketAssembler( pAssembler );
258 uint8_t uSegmentHeader = pSegment[ 1 ];
259 DPRINTF(
"GOT PACKET HEADER = 0x%x\n", uSegmentHeader);
261 if ( ( uSegmentHeader & REPORT_SEGMENT_DATA_FLAG ) == 0 )
267 int nSegmentNumber = uSegmentHeader & 0x07;
268 if ( nSegmentNumber != pAssembler->nExpectedSegmentNumber )
270 ResetSteamControllerPacketAssembler( pAssembler );
272 if ( nSegmentNumber )
275 DPRINTF(
"Bad segment number, got %d, expected %d\n",
276 nSegmentNumber, pAssembler->nExpectedSegmentNumber );
281 memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE,
283 MAX_REPORT_SEGMENT_PAYLOAD_SIZE );
285 if ( uSegmentHeader & REPORT_SEGMENT_LAST_FLAG )
287 pAssembler->nExpectedSegmentNumber = 0;
288 return ( nSegmentNumber + 1 ) * MAX_REPORT_SEGMENT_PAYLOAD_SIZE;
291 pAssembler->nExpectedSegmentNumber++;
296 memcpy( pAssembler->uBuffer,
299 return nSegmentLength;
305 #define BLE_MAX_READ_RETRIES 8
307 static int SetFeatureReport(
hid_device *dev,
unsigned char uBuffer[65],
int nActualDataLen )
309 DPRINTF(
"SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen);
315 if ( nActualDataLen < 1 )
318 int nSegmentNumber = 0;
319 uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ];
322 unsigned char *pBufferPtr = uBuffer + 1;
325 while ( nActualDataLen > 0 )
327 int nBytesInPacket = nActualDataLen > MAX_REPORT_SEGMENT_PAYLOAD_SIZE ? MAX_REPORT_SEGMENT_PAYLOAD_SIZE : nActualDataLen;
329 nActualDataLen -= nBytesInPacket;
332 memset( uPacketBuffer, 0,
sizeof( uPacketBuffer ) );
333 uPacketBuffer[ 0 ] = BLE_REPORT_NUMBER;
334 uPacketBuffer[ 1 ] = GetSegmentHeader( nSegmentNumber, nActualDataLen == 0 );
335 memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket );
337 pBufferPtr += nBytesInPacket;
341 DPRINTF(
"SetFeatureReport() ret = %d\n", nRet);
348 static int GetFeatureReport(
hid_device *dev,
unsigned char uBuffer[65] )
350 DPRINTF(
"GetFeatureReport( %p %p )\n", dev, uBuffer );
356 SteamControllerPacketAssembler assembler;
357 InitializeSteamControllerPacketAssembler( &assembler );
360 uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ];
361 while( nRetries < BLE_MAX_READ_RETRIES )
363 memset( uSegmentBuffer, 0,
sizeof( uSegmentBuffer ) );
364 uSegmentBuffer[ 0 ] = BLE_REPORT_NUMBER;
366 DPRINTF(
"GetFeatureReport ble ret=%d\n", nRet );
367 HEXDUMP( uSegmentBuffer, nRet );
370 if ( nRet > 2 && ( uSegmentBuffer[ 1 ] & REPORT_SEGMENT_DATA_FLAG ) )
377 int nPacketLength = WriteSegmentToSteamControllerPacketAssembler( &assembler,
381 if ( nPacketLength > 0 && nPacketLength < 65 )
385 memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength );
386 return nPacketLength;
392 printf(
"Could not get a full ble packet after %d retries\n", nRetries );
399 static int ReadResponse(
hid_device *dev,
uint8_t uBuffer[65],
int nExpectedResponse )
401 DPRINTF(
"ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse );
402 int nRet = GetFeatureReport( dev, uBuffer );
407 DPRINTF(
"ReadResponse got %d bytes of data: ", nRet );
408 HEXDUMP( uBuffer, nRet );
410 if ( uBuffer[1] != nExpectedResponse )
419 static bool ResetSteamController(
hid_device *dev,
bool bSuppressErrorSpew )
421 DPRINTF(
"ResetSteamController hid=%p\n", dev );
423 unsigned char buf[65];
428 res = SetFeatureReport( dev,
buf, 2 );
431 if ( !bSuppressErrorSpew )
432 printf(
"GET_ATTRIBUTES_VALUES failed for controller %p\n", dev );
442 if ( !bSuppressErrorSpew )
443 printf(
"Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev );
447 int nAttributesLength =
buf[ 2 ];
448 if ( nAttributesLength >
res )
450 if ( !bSuppressErrorSpew )
451 printf(
"Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev );
458 res = SetFeatureReport( dev,
buf, 2 );
461 if ( !bSuppressErrorSpew )
462 printf(
"CLEAR_DIGITAL_MAPPINGS failed for controller %p\n", dev );
470 res = SetFeatureReport( dev,
buf, 3 );
473 if ( !bSuppressErrorSpew )
474 printf(
"LOAD_DEFAULT_SETTINGS failed for controller %p\n", dev );
480 #define ADD_SETTING(SETTING, VALUE) \
481 buf[3+nSettings*3] = SETTING; \
482 buf[3+nSettings*3+1] = ((uint16_t)VALUE)&0xFF; \
483 buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
490 #ifdef ENABLE_MOUSE_MODE
499 buf[2] = nSettings*3;
501 res = SetFeatureReport( dev,
buf, 3+nSettings*3 );
504 if ( !bSuppressErrorSpew )
505 printf(
"SET_SETTINGS failed for controller %p\n", dev );
509 #ifdef ENABLE_MOUSE_MODE
511 bool bMappingsCleared =
false;
513 for ( iRetry = 0; iRetry < 2; ++iRetry )
519 res = SetFeatureReport( dev,
buf, 4 );
522 printf(
"GET_DIGITAL_MAPPINGS failed for controller %p\n", dev );
529 printf(
"Bad GET_DIGITAL_MAPPINGS response for controller %p\n", dev );
534 if (
buf[2] == 1 &&
buf[3] == 0xFF )
536 bMappingsCleared =
true;
539 usleep( CONTROLLER_CONFIGURATION_DELAY_US );
542 if ( !bMappingsCleared && !bSuppressErrorSpew )
544 printf(
"Warning: CLEAR_DIGITAL_MAPPINGS never completed for controller %p\n", dev );
558 res = SetFeatureReport( dev,
buf, 9 );
561 if ( !bSuppressErrorSpew )
562 printf(
"SET_DIGITAL_MAPPINGS failed for controller %p\n", dev );
576 memset( pData, 0, nDataSize );
577 pData[ 0 ] = BLE_REPORT_NUMBER;
578 return hid_read( dev, pData, nDataSize );
585 static void CloseSteamController(
hid_device *dev )
588 unsigned char buf[65];
594 SetFeatureReport( dev,
buf, 2 );
600 SetFeatureReport( dev,
buf, 3 );
606 buf[2] = nSettings*3;
607 SetFeatureReport( dev,
buf, 3+nSettings*3 );
614 static float RemapValClamped(
float val,
float A,
float B,
float C,
float D)
618 return (
val - B ) >= 0.0f ? D : C;
622 float cVal = (
val - A) / (B - A);
623 cVal =
clamp( cVal, 0.0f, 1.0f );
625 return C + (D - C) * cVal;
633 static void RotatePad(
int *pX,
int *pY,
float flAngleInRad )
635 short int origX = *pX, origY = *pY;
640 static void RotatePadShort(
short *pX,
short *pY,
float flAngleInRad )
642 short int origX = *pX, origY = *pY;
644 *pX = (short)(
SDL_cosf( flAngleInRad ) * origX -
SDL_sinf( flAngleInRad ) * origY );
645 *pY = (short)(
SDL_sinf( flAngleInRad ) * origX +
SDL_cosf( flAngleInRad ) * origY );
654 memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel));
657 pState->eControllerType = 2;
662 pState->ulButtons &= ~0xFFFF000000LL;
668 pState->sLeftPadX = pState->sPrevLeftPad[0] = pStatePacket->
sLeftPadX;
669 pState->sLeftPadY = pState->sPrevLeftPad[1] = pStatePacket->
sLeftPadY;
674 pState->sLeftStickX = pState->sPrevLeftStick[0];
675 pState->sLeftStickY = pState->sPrevLeftStick[1];
680 pState->sPrevLeftStick[0] = 0;
681 pState->sPrevLeftStick[1] = 0;
699 pState->sPrevLeftStick[0] = pState->sLeftStickX = pStatePacket->
sLeftPadX;
700 pState->sPrevLeftStick[1] = pState->sLeftStickY = pStatePacket->
sLeftPadY;
712 pState->sLeftPadX = pState->sPrevLeftPad[0];
713 pState->sLeftPadY = pState->sPrevLeftPad[1];
718 pState->sPrevLeftPad[0] = 0;
719 pState->sPrevLeftPad[1] = 0;
722 if (pState->ulButtons & STEAM_BUTTON_LEFTPAD_CLICKED_MASK)
724 pState->ulButtons &= ~STEAM_BUTTON_LEFTPAD_CLICKED_MASK;
725 pState->ulButtons |= STEAM_JOYSTICK_BUTTON_MASK;
733 pState->ulButtons |= STEAM_LEFTPAD_FINGERDOWN_MASK;
735 pState->sRightPadX = pStatePacket->
sRightPadX;
736 pState->sRightPadY = pStatePacket->
sRightPadY;
738 int nLeftPadX = pState->sLeftPadX;
739 int nLeftPadY = pState->sLeftPadY;
740 int nRightPadX = pState->sRightPadX;
741 int nRightPadY = pState->sRightPadY;
744 const float flRotationAngle = 0.261799f;
746 RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle);
747 RotatePad(&nRightPadX, &nRightPadY, flRotationAngle);
750 if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK)
759 if (pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK)
775 static bool UpdateBLESteamControllerState(
const uint8_t *pData,
int nDataSize, SteamControllerStateInternal_t *pState )
777 const float flRotationAngle = 0.261799f;
780 pState->unPacketNum++;
781 ucOptionDataMask = ( *pData++ & 0xF0 );
782 ucOptionDataMask |= (
uint32_t)(*pData++) << 8;
785 memcpy( &pState->ulButtons, pData, 3 );
791 pState->sTriggerL = (
unsigned short)RemapValClamped( ( pData[ 0 ] << 7 ) | pData[ 0 ], 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0,
SDL_MAX_SINT16 );
792 pState->sTriggerR = (
unsigned short)RemapValClamped( ( pData[ 1 ] << 7 ) | pData[ 1 ], 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0,
SDL_MAX_SINT16 );
798 pButtonByte[ 5 ] = *pData++;
799 pButtonByte[ 6 ] = *pData++;
800 pButtonByte[ 7 ] = *pData++;
806 int nLength =
sizeof( pState->sLeftStickX ) +
sizeof( pState->sLeftStickY );
807 memcpy( &pState->sLeftStickX, pData, nLength );
812 int nLength =
sizeof( pState->sLeftPadX ) +
sizeof( pState->sLeftPadY );
814 memcpy( &pState->sLeftPadX, pData, nLength );
815 if ( pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK )
820 RotatePadShort( &pState->sLeftPadX, &pState->sLeftPadY, -flRotationAngle );
827 int nLength =
sizeof( pState->sRightPadX ) +
sizeof( pState->sRightPadY );
830 memcpy( &pState->sRightPadX, pData, nLength );
832 if ( pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK )
837 RotatePadShort( &pState->sRightPadX, &pState->sRightPadY, flRotationAngle );
844 int nLength =
sizeof( pState->sAccelX ) +
sizeof( pState->sAccelY ) +
sizeof( pState->sAccelZ );
845 memcpy( &pState->sAccelX, pData, nLength );
850 int nLength =
sizeof( pState->sAccelX ) +
sizeof( pState->sAccelY ) +
sizeof( pState->sAccelZ );
851 memcpy( &pState->sGyroX, pData, nLength );
856 int nLength =
sizeof( pState->sGyroQuatW ) +
sizeof( pState->sGyroQuatX ) +
sizeof( pState->sGyroQuatY ) +
sizeof( pState->sGyroQuatZ );
857 memcpy( &pState->sGyroQuatW, pData, nLength );
867 static bool UpdateSteamControllerState(
const uint8_t *pData,
int nDataSize, SteamControllerStateInternal_t *pState )
875 return UpdateBLESteamControllerState( pData, nDataSize, pState );
891 if ( pState->unPacketNum == pStatePacket->
unPacketNum )
894 FormatStatePacketUntilGyro( pState, pStatePacket );
896 pState->sAccelX = pStatePacket->
sAccelX;
897 pState->sAccelY = pStatePacket->
sAccelY;
898 pState->sAccelZ = pStatePacket->
sAccelZ;
900 pState->sGyroQuatW = pStatePacket->
sGyroQuatW;
901 pState->sGyroQuatX = pStatePacket->
sGyroQuatX;
902 pState->sGyroQuatY = pStatePacket->
sGyroQuatY;
903 pState->sGyroQuatZ = pStatePacket->
sGyroQuatZ;
905 pState->sGyroX = pStatePacket->
sGyroX;
906 pState->sGyroY = pStatePacket->
sGyroY;
907 pState->sGyroZ = pStatePacket->
sGyroZ;
916 if ( pState->unPacketNum == pStatePacket->
unPacketNum )
919 FormatStatePacketUntilGyro( pState, pStatePacket );
924 pState->sGyroQuatW = (( float ) pBLEStatePacket->
sGyro[0]);
925 pState->sGyroQuatX = (( float ) pBLEStatePacket->
sGyro[1]);
926 pState->sGyroQuatY = (( float ) pBLEStatePacket->
sGyro[2]);
927 pState->sGyroQuatZ = (( float ) pBLEStatePacket->
sGyro[3]);
931 pState->sAccelX = pBLEStatePacket->
sGyro[0];
932 pState->sAccelY = pBLEStatePacket->
sGyro[1];
933 pState->sAccelZ = pBLEStatePacket->
sGyro[2];
937 pState->sGyroX = pBLEStatePacket->
sGyro[0];
938 pState->sGyroY = pBLEStatePacket->
sGyro[1];
939 pState->sGyroZ = pBLEStatePacket->
sGyro[2];
953 SteamControllerPacketAssembler m_assembler;
954 SteamControllerStateInternal_t m_state;
955 SteamControllerStateInternal_t m_last_state;
956 } SDL_DriverSteam_Context;
966 HIDAPI_DriverSteam_GetDeviceName(
Uint16 vendor_id,
Uint16 product_id)
968 return "Steam Controller";
991 SDL_DriverSteam_Context *
ctx;
1006 if (!ResetSteamController(
device->dev,
false)) {
1010 InitializeSteamControllerPacketAssembler(&
ctx->m_assembler);
1067 SDL_DriverSteam_Context *
ctx = (SDL_DriverSteam_Context *)
device->context;
1080 int r, nPacketLength;
1081 const Uint8 *pPacket;
1091 nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&
ctx->m_assembler,
data,
r);
1094 pPacket =
ctx->m_assembler.uBuffer;
1096 if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &
ctx->m_state)) {
1097 if (
ctx->m_state.ulButtons !=
ctx->m_last_state.ulButtons) {
1134 const int kPadDeadZone = 10000;
1158 ctx->m_last_state =
ctx->m_state;
1173 CloseSteamController(
device->dev);
1190 HIDAPI_DriverSteam_IsSupportedDevice,
1191 HIDAPI_DriverSteam_GetDeviceName,
1192 HIDAPI_DriverSteam_InitDevice,
1193 HIDAPI_DriverSteam_GetDevicePlayerIndex,
1194 HIDAPI_DriverSteam_SetDevicePlayerIndex,
1195 HIDAPI_DriverSteam_UpdateDevice,
1196 HIDAPI_DriverSteam_OpenJoystick,
1197 HIDAPI_DriverSteam_RumbleJoystick,
1198 HIDAPI_DriverSteam_RumbleJoystickTriggers,
1199 HIDAPI_DriverSteam_HasJoystickLED,
1200 HIDAPI_DriverSteam_SetJoystickLED,
1201 HIDAPI_DriverSteam_SetSensorsEnabled,
1202 HIDAPI_DriverSteam_CloseJoystick,
1203 HIDAPI_DriverSteam_FreeDevice,
unsigned long long uint64_t
#define SDL_JoystickFromInstanceID
#define SDL_OutOfMemory()
#define SDL_Unsupported()
@ SDL_CONTROLLER_AXIS_LEFTX
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_RIGHTY
@ SDL_CONTROLLER_AXIS_RIGHTX
@ SDL_CONTROLLER_AXIS_MAX
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
@ SDL_CONTROLLER_AXIS_LEFTY
@ SDL_CONTROLLER_BUTTON_B
@ SDL_CONTROLLER_BUTTON_BACK
@ SDL_CONTROLLER_BUTTON_LEFTSTICK
@ SDL_CONTROLLER_BUTTON_START
@ SDL_CONTROLLER_BUTTON_DPAD_LEFT
@ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
@ SDL_CONTROLLER_BUTTON_DPAD_DOWN
@ SDL_CONTROLLER_BUTTON_DPAD_UP
@ SDL_CONTROLLER_BUTTON_LEFTSHOULDER
@ SDL_CONTROLLER_BUTTON_GUIDE
@ SDL_CONTROLLER_BUTTON_DPAD_RIGHT
@ SDL_CONTROLLER_BUTTON_MISC1
@ SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_Y
@ SDL_CONTROLLER_BUTTON_A
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam
SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
#define SDL_HINT_JOYSTICK_HIDAPI_STEAM
A variable controlling whether the HIDAPI driver for Steam Controllers should be used.
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble r
GLuint GLuint GLsizei GLenum type
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_MAX_SINT16
A signed 16-bit integer type.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
@ IO_DIGITAL_BUTTON_LEFT_TRIGGER
@ IO_DIGITAL_BUTTON_RIGHT_TRIGGER
@ ID_LOAD_DEFAULT_SETTINGS
@ ID_GET_DIGITAL_MAPPINGS
@ ID_CLEAR_DIGITAL_MAPPINGS
@ ID_SET_DEFAULT_DIGITAL_MAPPINGS
@ ID_GET_ATTRIBUTES_VALUES
@ ID_SET_DIGITAL_MAPPINGS
@ SETTING_WIRELESS_PACKET_VERSION
@ SETTING_MOMENTUM_DECAY_AMMOUNT
@ SETTING_RIGHT_TRACKPAD_MODE
@ SETTING_MOMENTUM_MAXIMUM_VELOCITY
@ SETTING_LEFT_TRACKPAD_MODE
@ SETTING_SMOOTH_ABSOLUTE_MOUSE
@ TRACKPAD_ABSOLUTE_MOUSE
@ k_EBLERightTrackpadChunk
@ k_EBLELeftTrackpadChunk
@ k_EBLELeftJoystickChunk
#define k_ValveInReportMsgVersion
@ ID_CONTROLLER_BLE_STATE
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
Read an Input report from a HID device.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
Get a feature report from a HID device.
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path, int bExclusive)
Open a HID device by its path name.
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
Close a HID device.
struct hid_device_ hid_device
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
Send a Feature report to the device.
static SDL_AudioDeviceID device
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
unsigned char ucGyroDataType
union ValveControllerStatePacket_t::@27 ButtonTriggerData
struct ValveControllerStatePacket_t::@27::@28 Triggers
ValveInReportHeader_t header
ValveControllerBLEStatePacket_t controllerBLEState
ValveControllerStatePacket_t controllerState
union ValveInReport_t::@31 payload
static SDL_Joystick * joystick
typedef int(__stdcall *FARPROC)()