From 26cac9ce205739792c7877c0795a098ddf1c9fb7 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 13 Jul 2026 22:05:13 +0200 Subject: [PATCH] fix(gamepad): truncate stick/trigger axes uniformly across clients (G25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple's GamepadCapture rounded axis values (`(v * scale).rounded()`) while SDL-core and Android truncate, so a half-pressed control emitted 128 on Apple vs 127 elsewhere. Drop `.rounded()` so `Int32(Float)` truncates toward zero on Apple too; rails are unchanged (full deflection stays 255 / ±32767). Also clamp SDL-core's LeftX/RightX to a symmetric -32767 like the Y axes and the other clients already do, instead of letting the raw i16 reach -32768. Verified: Apple `swift build` + full PunktfunkKit suite (124 pass); SDL half on Windows .173 `cargo clippy -p pf-client-core -- -D warnings` (green). Co-Authored-By: Claude Opus 4.8 --- .../PunktfunkKit/Gamepad/GamepadCapture.swift | 12 ++++++------ crates/pf-client-core/src/gamepad.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift b/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift index fa251b71..b5224180 100644 --- a/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift +++ b/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift @@ -271,12 +271,12 @@ public final class GamepadCapture { slot.buttons = newButtons } let newAxes: [Int32] = [ - Int32((g.leftThumbstick.xAxis.value * 32767).rounded()), - Int32((g.leftThumbstick.yAxis.value * 32767).rounded()), - Int32((g.rightThumbstick.xAxis.value * 32767).rounded()), - Int32((g.rightThumbstick.yAxis.value * 32767).rounded()), - Int32((g.leftTrigger.value * 255).rounded()), - Int32((g.rightTrigger.value * 255).rounded()), + Int32(g.leftThumbstick.xAxis.value * 32767), + Int32(g.leftThumbstick.yAxis.value * 32767), + Int32(g.rightThumbstick.xAxis.value * 32767), + Int32(g.rightThumbstick.yAxis.value * 32767), + Int32(g.leftTrigger.value * 255), + Int32(g.rightTrigger.value * 255), ] for (i, v) in newAxes.enumerated() where v != slot.axes[i] { connection.send(.gamepadAxis(UInt32(i), value: v, pad: slot.pad)) diff --git a/crates/pf-client-core/src/gamepad.rs b/crates/pf-client-core/src/gamepad.rs index 9ed548dd..3922c7a3 100644 --- a/crates/pf-client-core/src/gamepad.rs +++ b/crates/pf-client-core/src/gamepad.rs @@ -558,9 +558,9 @@ fn button_bit(b: sdl3::gamepad::Button) -> Option { fn axis_value(axis: sdl3::gamepad::Axis, v: i16) -> (u32, i32) { use sdl3::gamepad::Axis; match axis { - Axis::LeftX => (wire::AXIS_LS_X, v as i32), + Axis::LeftX => (wire::AXIS_LS_X, (v as i32).max(-32767)), Axis::LeftY => (wire::AXIS_LS_Y, -(v as i32).max(-32767)), - Axis::RightX => (wire::AXIS_RS_X, v as i32), + Axis::RightX => (wire::AXIS_RS_X, (v as i32).max(-32767)), Axis::RightY => (wire::AXIS_RS_Y, -(v as i32).max(-32767)), Axis::TriggerLeft => (wire::AXIS_LT, (v as i32).clamp(0, 32767) >> 7), Axis::TriggerRight => (wire::AXIS_RT, (v as i32).clamp(0, 32767) >> 7),