Use the correct update rate for Steam Controller sensors

This commit is contained in:
Sam Lantinga 2021-10-02 09:12:57 -07:00
parent eadc8f9355
commit ea1a2b94f2
2 changed files with 77 additions and 6 deletions

View File

@ -421,13 +421,15 @@ static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResp
//---------------------------------------------------------------------------
// Reset steam controller (unmap buttons and pads) and re-fetch capability bits
//---------------------------------------------------------------------------
static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS )
{
// Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer.
unsigned char buf[65];
int res = -1;
int res = -1, i;
int nSettings = 0;
int nAttributesLength;
FeatureReportMsg *msg;
uint32_t unUpdateRateUS = 9000; // Good default rate
DPRINTF( "ResetSteamController hid=%p\n", dev );
@ -459,7 +461,33 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
printf( "Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev );
return false;
}
msg = (FeatureReportMsg *)&buf[1];
for ( i = 0; i < (int)msg->header.length / sizeof( ControllerAttribute ); ++i )
{
uint8_t unAttribute = msg->payload.getAttributes.attributes[i].attributeTag;
uint32_t unValue = msg->payload.getAttributes.attributes[i].attributeValue;
switch ( unAttribute )
{
case ATTRIB_UNIQUE_ID:
break;
case ATTRIB_PRODUCT_ID:
break;
case ATTRIB_CAPABILITIES:
break;
case ATTRIB_CONNECTION_INTERVAL_IN_US:
unUpdateRateUS = unValue;
break;
default:
break;
}
}
if ( punUpdateRateUS )
{
*punUpdateRateUS = unUpdateRateUS;
}
// Clear digital button mappings
buf[0] = 0;
buf[1] = ID_CLEAR_DIGITAL_MAPPINGS;
@ -1002,6 +1030,8 @@ static SDL_bool
HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
SDL_DriverSteam_Context *ctx;
uint32_t update_rate_in_us = 0;
float update_rate_in_hz = 0.0f;
ctx = (SDL_DriverSteam_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
@ -1017,9 +1047,13 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
}
hid_set_nonblocking(device->dev, 1);
if (!ResetSteamController(device->dev, false)) {
if (!ResetSteamController(device->dev, false, &update_rate_in_us)) {
SDL_SetError("Couldn't reset controller");
goto error;
}
if (update_rate_in_us > 0) {
update_rate_in_hz = 1000000.0f / update_rate_in_us;
}
InitializeSteamControllerPacketAssembler(&ctx->m_assembler);
@ -1027,8 +1061,8 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
joystick->nbuttons = 17;
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz);
return SDL_TRUE;

View File

@ -23,6 +23,43 @@
#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 attribute structure
typedef struct
{
unsigned char attributeTag;
uint32_t attributeValue;
} ControllerAttribute;
// Generic controller settings structure
typedef struct
{
ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
} MsgGetAttributes;
// 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
{
MsgGetAttributes getAttributes;
} payload;
} FeatureReportMsg;
// 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,