From 5c15d743944f0ba68093580474cfbf8d759f6663 Mon Sep 17 00:00:00 2001 From: Aubrey Hesselgren Date: Mon, 19 Jan 2026 14:54:04 -0800 Subject: [PATCH] Fix Horipad bluetooth gyro stutter issues using simulated sensor timing approach (based on packet rate observation) By observation: wired is 250hz/4000ms, and bluetooth is 120hz/8333ms for IMU sensor. --- src/joystick/hidapi/SDL_hidapi_steam_hori.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_steam_hori.c b/src/joystick/hidapi/SDL_hidapi_steam_hori.c index 0519612348..d92634d54a 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_hori.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_hori.c @@ -51,6 +51,8 @@ typedef struct Uint8 last_state[USB_PACKET_LENGTH]; Uint64 sensor_ticks; Uint32 last_tick; + Uint64 simulated_sensor_step_ns; + Uint64 simulated_sensor_time_stamp; bool wireless; bool serial_needs_init; } SDL_DriverSteamHori_Context; @@ -126,9 +128,13 @@ static bool HIDAPI_DriverSteamHori_OpenJoystick(SDL_HIDAPI_Device *device, SDL_J HIDAPI_DriverSteamHori_UpdateDevice(device); } - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); - SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + const float sensorupdaterate = ctx->wireless ? 120.0f : 250.0f; + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, sensorupdaterate); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, sensorupdaterate); + + const Uint64 sensorupdatestep_ms = ctx->wireless ? 8333 : 4000; // Equivalent to 120hz / 250hz respectively + ctx->simulated_sensor_step_ns = SDL_US_TO_NS(sensorupdatestep_ms); return true; } @@ -313,7 +319,11 @@ static void HIDAPI_DriverSteamHori_HandleStatePacket(SDL_Joystick *joystick, SDL ctx->sensor_ticks += delta; /* Sensor timestamp is in 1us units, but there seems to be some issues with the values reported from the device */ - sensor_timestamp = timestamp; // if the values were good we would call SDL_US_TO_NS(ctx->sensor_ticks); + // sensor_timestamp = timestamp; // if the values were good we would call SDL_US_TO_NS(ctx->sensor_ticks); + + /* New approach - simulate a fixed rate of 250hz (from observation). This reduces stutter from dropped/racing bluetooth packets.*/ + ctx->simulated_sensor_time_stamp += ctx->simulated_sensor_step_ns; + sensor_timestamp = ctx->simulated_sensor_time_stamp; const float accelScale = SDL_STANDARD_GRAVITY * 8 / 32768.0f; const float gyroScale = DEG2RAD(2048);