Add support for new Steam Controller input report on mobile devices

(cherry picked from commit f6ffa69890)
This commit is contained in:
Sam Lantinga
2026-05-28 11:18:20 -07:00
parent 8d5ee8b38c
commit 05d140a128
6 changed files with 93 additions and 98 deletions

View File

@@ -100,7 +100,8 @@ typedef struct
{
bool connected;
bool report_sensors;
Uint32 last_sensor_tick;
Uint16 last_sensor_tick16;
Uint32 last_sensor_tick32;
Uint64 sensor_timestamp_ns;
Uint64 last_button_state;
Uint64 last_lizard_update;
@@ -143,7 +144,7 @@ static bool DisableSteamTritonLizardMode(SDL_hid_device *dev)
// Triton newer state MTUs are identical until touchpads. Parse them using this routine.
// Expects report to be a TritonMTUNoQuat_t, so cast as needed
static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context* ctx, SDL_Joystick* joystick, Uint64 timestamp, TritonMTUNoQuat_t* pTritonReport )
static void HIDAPI_DriverSteamTriton_HandleGenericState(SDL_DriverSteamTriton_Context *ctx, SDL_Joystick *joystick, Uint64 timestamp, TritonMTUNoQuat_t *pTritonReport)
{
if (pTritonReport->buttons != ctx->last_button_state) {
Uint8 hat = 0;
@@ -217,11 +218,11 @@ static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context*
ctx->last_button_state = pTritonReport->buttons;
}
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
(int)pTritonReport->sTriggerLeft * 2 - 32768);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,
(int)pTritonReport->sTriggerRight * 2 - 32768);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX,
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX,
pTritonReport->sLeftStickX);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY,
-pTritonReport->sLeftStickY);
@@ -232,19 +233,19 @@ static void Parse_SteamTriton_HandleGenericState( SDL_DriverSteamTriton_Context*
}
static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
SDL_Joystick *joystick,
TritonMTUNoQuat_t *pTritonReport)
SDL_Joystick *joystick,
TritonMTUNoQuat_t *pTritonReport)
{
float values[3];
SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context;
Uint64 timestamp = SDL_GetTicksNS();
Parse_SteamTriton_HandleGenericState(ctx, joystick, timestamp, pTritonReport);
HIDAPI_DriverSteamTriton_HandleGenericState(ctx, joystick, timestamp, pTritonReport);
bool left_touch_down = (pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_TOUCH) ? true : false;
bool right_touch_down = (pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_TOUCH) ? true : false;
if (left_touch_down || ctx->left_touch_down) {
if (left_touch_down || ctx->left_touch_down) {
if (left_touch_down) {
ctx->left_touch_x = pTritonReport->sLeftPadX / 65536.0f + 0.5f;
ctx->left_touch_y = -(float)pTritonReport->sLeftPadY / 65536.0f + 0.5f;
@@ -253,7 +254,7 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
left_touch_down,
ctx->left_touch_x,
ctx->left_touch_y,
pTritonReport->ucPressureLeft / 32768.0f);
pTritonReport->unPressureLeft / 32768.0f);
ctx->left_touch_down = left_touch_down;
}
if (right_touch_down || ctx->right_touch_down) {
@@ -265,12 +266,12 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
right_touch_down,
ctx->right_touch_x,
ctx->right_touch_y,
pTritonReport->ucPressureRight / 32768.0f);
pTritonReport->unPressureRight / 32768.0f);
ctx->right_touch_down = right_touch_down;
}
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick) {
Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick);
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick32) {
Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick32);
ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us);
@@ -284,19 +285,19 @@ static void HIDAPI_DriverSteamTriton_HandleState(SDL_HIDAPI_Device *device,
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);
ctx->last_sensor_tick = pTritonReport->imu.timestamp;
ctx->last_sensor_tick32 = pTritonReport->imu.timestamp;
}
}
// New Ibex MTU has IMU data in
static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *device,
SDL_Joystick *joystick,
SDL_Joystick *joystick,
TritonMTUNoQuat32TS_t *pTritonReport)
{
float values[3];
SDL_DriverSteamTriton_Context *ctx = (SDL_DriverSteamTriton_Context *)device->context;
Uint64 timestamp = SDL_GetTicksNS();
Parse_SteamTriton_HandleGenericState(ctx, joystick, timestamp, (TritonMTUNoQuat_t *) pTritonReport);
HIDAPI_DriverSteamTriton_HandleGenericState(ctx, joystick, timestamp, (TritonMTUNoQuat_t *) pTritonReport);
bool left_touch_down = (pTritonReport->buttons & TRITON_LEFT_TOUCHPAD_TOUCH) ? true : false;
bool right_touch_down = (pTritonReport->buttons & TRITON_RIGHT_TOUCHPAD_TOUCH) ? true : false;
@@ -326,8 +327,9 @@ static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *de
ctx->right_touch_down = right_touch_down;
}
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick) {
Uint32 delta_us = (pTritonReport->imu.timestamp - ctx->last_sensor_tick);
if (ctx->report_sensors && pTritonReport->imu.timestamp != ctx->last_sensor_tick16) {
// The timestamp is in units of 32 microseconds
Uint32 delta_us = (Uint32)(pTritonReport->imu.timestamp - ctx->last_sensor_tick16) * 32;
ctx->sensor_timestamp_ns += SDL_US_TO_NS(delta_us);
@@ -341,7 +343,7 @@ static void HIDAPI_DriverSteamTriton_HandleState_Timestamp(SDL_HIDAPI_Device *de
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);
ctx->last_sensor_tick = pTritonReport->imu.timestamp;
ctx->last_sensor_tick16 = pTritonReport->imu.timestamp;
}
}
@@ -442,8 +444,8 @@ static bool HIDAPI_DriverSteamTriton_IsSupportedDevice(
return true;
}
} else if (SDL_IsJoystickSteamTriton(vendor_id, product_id)) {
return true;
}
return true;
}
return false;
}
@@ -541,7 +543,7 @@ static bool HIDAPI_DriverSteamTriton_UpdateDevice(SDL_HIDAPI_Device *device)
HIDAPI_DriverSteamTriton_HandleState_Timestamp(device, joystick, pTritonReport);
}
break;
case ID_TRITON_BATTERY_STATUS:
case ID_TRITON_BATTERY_STATUS:
if (joystick && r >= (1 + sizeof(TritonBatteryStatus_t))) {
TritonBatteryStatus_t *pTritonBatteryStatus = (TritonBatteryStatus_t *)&data[1];
HIDAPI_DriverSteamTriton_HandleBatteryStatus(device, joystick, pTritonBatteryStatus);
@@ -592,7 +594,7 @@ static bool HIDAPI_DriverSteamTriton_RumbleJoystick(SDL_HIDAPI_Device *device, S
Uint8 buffer[HID_RUMBLE_OUTPUT_REPORT_BYTES] = { 0 };
OutputReportMsg *msg = (OutputReportMsg *)(buffer);
msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE;
msg->report_id = ID_OUT_REPORT_HAPTIC_RUMBLE;
msg->payload.hapticRumble.type = 0;
msg->payload.hapticRumble.intensity = 0;
msg->payload.hapticRumble.left.speed = low_frequency_rumble;

View File

@@ -620,11 +620,11 @@ typedef struct
short sLeftPadX;
short sLeftPadY;
unsigned short ucPressureLeft;
unsigned short unPressureLeft;
short sRightPadX;
short sRightPadY;
unsigned short ucPressureRight;
unsigned short unPressureRight;
TritonMTUIMU_t imu;
} TritonMTUFull_t;
@@ -641,11 +641,11 @@ typedef struct {
short sLeftPadX;
short sLeftPadY;
unsigned short ucPressureLeft;
unsigned short unPressureLeft;
short sRightPadX;
short sRightPadY;
unsigned short ucPressureRight;
unsigned short unPressureRight;
TritonMTUIMUNoQuat_t imu;
} TritonMTUNoQuat_t;