Expose Steam Controller touchpads in Gamepad API (#15378)

This commit is contained in:
Kuratius
2026-04-25 01:18:57 +02:00
committed by GitHub
parent 1146ea484a
commit 74a746281f

View File

@@ -1011,6 +1011,13 @@ typedef struct
Uint64 sensor_timestamp;
Uint64 pairing_time;
bool left_touch_down;
float left_touch_x;
float left_touch_y;
bool right_touch_down;
float right_touch_x;
float right_touch_y;
SteamControllerPacketAssembler m_assembler;
SteamControllerStateInternal_t m_state;
SteamControllerStateInternal_t m_last_state;
@@ -1269,6 +1276,9 @@ static bool HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joyst
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz);
SDL_PrivateJoystickAddTouchpad(joystick, 1);
SDL_PrivateJoystickAddTouchpad(joystick, 1);
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM_HOME_LED,
SDL_HomeLEDHintChanged, ctx);
@@ -1348,6 +1358,21 @@ static bool ControllerConnected(SDL_HIDAPI_Device *device, SDL_Joystick **joysti
return true;
}
static float FilterTouch(float newValue, float oldValue)
{
const float jitter = 256.0f / (1 << 16);
if (newValue > (oldValue - jitter * 0.5f) && newValue < (oldValue + jitter * 0.5f)) {
return oldValue;
}
if (newValue > (oldValue - jitter) && newValue < (oldValue + jitter)) {
return oldValue * 0.75f + newValue * 0.25f;
}
if (newValue > (oldValue - jitter * 2.0f) && newValue < (oldValue + jitter * 2.0f)) {
return (oldValue + newValue) * 0.5f;
}
return newValue;
}
static void ControllerDisconnected(SDL_HIDAPI_Device *device, SDL_Joystick **joystick)
{
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
@@ -1469,6 +1494,46 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, ctx->m_state.sRightPadX);
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, ~ctx->m_state.sRightPadY);
// Note that the left pad is normally mapped to D-Pad, so you should ignore that input if you use the touchpad instead.
{
const bool down = (ctx->m_state.ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) ? true : false;
if (down || ctx->left_touch_down) {
const bool clicked = (ctx->m_state.ulButtons & STEAM_BUTTON_LEFTPAD_CLICKED_MASK) ? true : false;
const float leftX = (float)ctx->m_state.sLeftPadX / (1 << 16) + 0.5f;
const float leftY = -(float)ctx->m_state.sLeftPadY / (1 << 16) + 0.5f;
float pressure = down ? 0.5f : 0.0f;
if (clicked) {
pressure += 0.5f;
}
if (down) {
ctx->left_touch_x = FilterTouch(leftX, ctx->left_touch_x);
ctx->left_touch_y = FilterTouch(leftY, ctx->left_touch_y);
}
SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, down, ctx->left_touch_x, ctx->left_touch_y, pressure);
ctx->left_touch_down = down;
}
}
// Note that the right pad is normally mapped to right thumbstick, so you should ignore that input if you use the touchpad instead.
{
const bool down = (ctx->m_state.ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK) ? true : false;
if (down || ctx->right_touch_down) {
const bool clicked = (ctx->m_state.ulButtons & STEAM_BUTTON_RIGHTPAD_CLICKED_MASK) ? true : false;
const float rightX = (float)ctx->m_state.sRightPadX / (1 << 16) + 0.5f;
const float rightY = -(float)ctx->m_state.sRightPadY / (1 << 16) + 0.5f;
float pressure = down ? 0.5f : 0.0f;
if (clicked) {
pressure += 0.5f;
}
if (down) {
ctx->right_touch_x = FilterTouch(rightX, ctx->right_touch_x);
ctx->right_touch_y = FilterTouch(rightY, ctx->right_touch_y);
}
SDL_SendJoystickTouchpad(timestamp, joystick, 1, 0, down, ctx->right_touch_x, ctx->right_touch_y, pressure);
ctx->right_touch_down = down;
}
}
if (ctx->report_sensors) {
float values[3];