Use the correct report format for BLE Steam Controller reports

This commit is contained in:
Sam Lantinga
2026-02-12 16:02:21 -08:00
parent 7b27056ea0
commit 79f5f674bd
2 changed files with 63 additions and 31 deletions

View File

@@ -125,67 +125,67 @@ static bool DisableSteamTritonLizardMode(SDL_hid_device *dev)
static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device, static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
SDL_Joystick *joystick, SDL_Joystick *joystick,
TritonMTUFull_t *pTritonReport) TritonMTUNoQuat_t *pTritonReport)
{ {
float values[3]; float values[3];
SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context; SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context;
Uint64 timestamp = SDL_GetTicksNS(); Uint64 timestamp = SDL_GetTicksNS();
if (pTritonReport->uButtons != ctx->last_button_state) { if (pTritonReport->buttons != ctx->last_button_state) {
Uint8 hat = 0; Uint8 hat = 0;
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH,
((pTritonReport->uButtons & TRITON_LBUTTON_A) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_A) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST,
((pTritonReport->uButtons & TRITON_LBUTTON_B) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_B) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST,
((pTritonReport->uButtons & TRITON_LBUTTON_X) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_X) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH,
((pTritonReport->uButtons & TRITON_LBUTTON_Y) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_Y) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER,
((pTritonReport->uButtons & TRITON_LBUTTON_L) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_L) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER,
((pTritonReport->uButtons & TRITON_LBUTTON_R) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_R) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK,
((pTritonReport->uButtons & TRITON_LBUTTON_MENU) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_MENU) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START,
((pTritonReport->uButtons & TRITON_LBUTTON_VIEW) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_VIEW) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE,
((pTritonReport->uButtons & TRITON_LBUTTON_STEAM) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_STEAM) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_QAM,
((pTritonReport->uButtons & TRITON_HBUTTON_QAM) != 0)); ((pTritonReport->buttons & TRITON_HBUTTON_QAM) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK,
((pTritonReport->uButtons & TRITON_LBUTTON_L3) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_L3) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK,
((pTritonReport->uButtons & TRITON_LBUTTON_R3) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_R3) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE1,
((pTritonReport->uButtons & TRITON_HBUTTON_R4) != 0)); ((pTritonReport->buttons & TRITON_HBUTTON_R4) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE1,
((pTritonReport->uButtons & TRITON_HBUTTON_L4) != 0)); ((pTritonReport->buttons & TRITON_HBUTTON_L4) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_RIGHT_PADDLE2,
((pTritonReport->uButtons & TRITON_LBUTTON_R5) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_R5) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2, SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_DECK_LEFT_PADDLE2,
((pTritonReport->uButtons & TRITON_LBUTTON_L5) != 0)); ((pTritonReport->buttons & TRITON_LBUTTON_L5) != 0));
if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_UP) { if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_UP) {
hat |= SDL_HAT_UP; hat |= SDL_HAT_UP;
} }
if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_DOWN) { if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_DOWN) {
hat |= SDL_HAT_DOWN; hat |= SDL_HAT_DOWN;
} }
if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_LEFT) { if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_LEFT) {
hat |= SDL_HAT_LEFT; hat |= SDL_HAT_LEFT;
} }
if (pTritonReport->uButtons & TRITON_LBUTTON_DPAD_RIGHT) { if (pTritonReport->buttons & TRITON_LBUTTON_DPAD_RIGHT) {
hat |= SDL_HAT_RIGHT; hat |= SDL_HAT_RIGHT;
} }
SDL_SendJoystickHat(timestamp, joystick, 0, hat); SDL_SendJoystickHat(timestamp, joystick, 0, hat);
ctx->last_button_state = pTritonReport->uButtons; ctx->last_button_state = pTritonReport->buttons;
} }
// RKRK There're button bits for this if you so choose. // RKRK There're button bits for this if you so choose.
@@ -203,8 +203,8 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY,
-pTritonReport->sRightStickY); -pTritonReport->sRightStickY);
if (ctx->report_sensors && pTritonReport->imu.uTimestamp != ctx->last_sensor_tick) { if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick) {
Uint32 delta_us = (pTritonReport->imu.uTimestamp - ctx->last_sensor_tick); Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick);
ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us); ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us);
@@ -218,7 +218,7 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
values[2] = (-pTritonReport->imu.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; values[2] = (-pTritonReport->imu.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3); SDL_SendJoystickSensor(timestamp, joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_ns, values, 3);
ctx->last_sensor_tick = pTritonReport->imu.uTimestamp; ctx->last_sensor_tick = pTritonReport->imu.timestamp;
} }
} }
@@ -393,8 +393,8 @@ static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device)
joystick = SDL_GetJoystickFromID(device->joysticks[0]); joystick = SDL_GetJoystickFromID(device->joysticks[0]);
} }
} }
if (joystick && r >= (1 + sizeof(TritonMTUFull_t))) { if (joystick && r >= (1 + sizeof(TritonMTUNoQuat_t))) {
TritonMTUFull_t *pTritonReport = (TritonMTUFull_t *)&data[1]; TritonMTUNoQuat_t *pTritonReport = (TritonMTUNoQuat_t *)&data[1];
HIDAPI_DriverSteamTriton_HandleState(device, joystick, pTritonReport); HIDAPI_DriverSteamTriton_HandleState(device, joystick, pTritonReport);
} }
break; break;

View File

@@ -567,7 +567,7 @@ enum ETritonWirelessState
typedef struct typedef struct
{ {
uint32_t uTimestamp; uint32_t timestamp;
short sAccelX; short sAccelX;
short sAccelY; short sAccelY;
short sAccelZ; short sAccelZ;
@@ -582,10 +582,21 @@ typedef struct
short sGyroQuatZ; short sGyroQuatZ;
} TritonMTUIMU_t; } TritonMTUIMU_t;
typedef struct {
uint32_t timestamp;
short sAccelX;
short sAccelY;
short sAccelZ;
short sGyroX;
short sGyroY;
short sGyroZ;
} TritonMTUIMUNoQuat_t;
typedef struct typedef struct
{ {
uint8_t cSeq_num; uint8_t seq_num;
uint32_t uButtons; uint32_t buttons;
short sTriggerLeft; short sTriggerLeft;
short sTriggerRight; short sTriggerRight;
@@ -604,6 +615,27 @@ typedef struct
TritonMTUIMU_t imu; TritonMTUIMU_t imu;
} TritonMTUFull_t; } TritonMTUFull_t;
typedef struct {
uint8_t seq_num;
uint32_t buttons;
short sTriggerLeft;
short sTriggerRight;
short sLeftStickX;
short sLeftStickY;
short sRightStickX;
short sRightStickY;
short sLeftPadX;
short sLeftPadY;
unsigned short ucPressureLeft;
short sRightPadX;
short sRightPadY;
unsigned short ucPressureRight;
TritonMTUIMUNoQuat_t imu;
} TritonMTUNoQuat_t;
enum EChargeState enum EChargeState
{ {
k_EChargeStateReset, k_EChargeStateReset,