feat(host/steam): M5 — fallback remap, motion rescale, degrade ladder
Keep the rich Steam inputs from silently dropping when the resolved backend
isn't the virtual hid-steam device, and fix a cross-device motion-scale bug.
- inject/proto/steam_remap.rs (new, pure + unit-tested):
* motion_wire_to_deck — the wire carries DualSense-convention units (20 LSB/
deg.s gyro, 10000 LSB/g accel — what every client capture emits), but the
Deck's hid-steam report wants 16 LSB/deg.s + 16384 LSB/g. The Deck backend
now rescales (gyro x16/20, accel x16384/10000): a real Deck<->Deck gyro/
accel correctness fix (the DualSense/DS4 backends consume the wire 1:1).
* fold_paddles + RemapConfig (PUNKTFUNK_STEAM_REMAP=paddles=drop|stickclicks|
shoulders, default drop) — the DualSense + DS4 managers fold a client's back
grips onto standard buttons rather than dropping them (those pads have no
back-button HID slot; the uinput Xbox pad already exposes them as Elite
paddles BTN_TRIGGER_HAPPY5-8).
- resolve_gamepad: a runtime degrade ladder — a UHID backend (DualSense / DS4 /
Steam Deck) on a host where /dev/uhid isn't writable now falls back to the
uinput Xbox 360 pad instead of a dead controller (the device-create would
just fail). Separate from pick_gamepad's compile-time platform check, so the
existing pick_gamepad tests are untouched.
- Delete the throwaway M0/M1 spike (src/bin/steam_uhid_spike.rs) — M2's
#[ignore]d backend test subsumes its validation, and removing it frees
steam_proto to reference steam_remap cleanly.
On-box backend test still green; workspace clippy/fmt/test green (incl. the new
steam_remap tests). Deferred as optional RemapConfig growth: gyro->mouse /
trackpad->stick synthesis on an Xbox target (no slot — documented drop today).
Not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,26 @@
|
||||
# Rich Steam Controller & Steam Deck support
|
||||
|
||||
> **Status:** **M0–M4 GREEN — the full Steam Controller/Deck pipeline is built (2026-06-29).** Host:
|
||||
> the virtual `hid-steam` Deck binds, is byte-exact, is a wired backend (`PUNKTFUNK_GAMEPAD=
|
||||
> steamdeck`), and the protocol carries the rich inputs. Clients: the Linux + Windows SDL clients
|
||||
> capture + send them; the Decky plugin has the Steam Deck mode + Disable-Steam-Input UX; the C-ABI
|
||||
> has the `TouchpadEx` send path; Apple/Android round-trip the type. Remaining is **validation, not
|
||||
> construction** (see below) + the deferred extras (M5 fallback-remap polish, M6 SteamOS-host
|
||||
> conflict check, M7 Windows UMDF Steam driver).
|
||||
> **Status:** **M0–M5 GREEN — full pipeline + fallback polish built (2026-06-29).** Host: the
|
||||
> virtual `hid-steam` Deck binds, is byte-exact, is a wired backend (`PUNKTFUNK_GAMEPAD=steamdeck`),
|
||||
> the protocol carries the rich inputs, and the **fallback remap** keeps them from silently dropping
|
||||
> on a non-Steam backend. Clients: the Linux + Windows SDL clients capture + send them; the Decky
|
||||
> plugin has the Steam Deck mode + Disable-Steam-Input UX; the C-ABI has the `TouchpadEx` send path;
|
||||
> Apple/Android round-trip the type. Remaining is **validation, not construction** (see below) + the
|
||||
> deferred extras (M6 SteamOS-host conflict check, M7 Windows UMDF Steam driver).
|
||||
>
|
||||
> **M5 (fallback remap + degrade ladder) result:** new pure, unit-tested `inject/proto/steam_remap.rs`:
|
||||
> (1) **motion rescale** `motion_wire_to_deck` — the wire carries DualSense-convention units (what
|
||||
> every client capture emits), the Deck's `hid-steam` report wants 16 LSB/°·s + 16384 LSB/g, so the
|
||||
> Deck backend now rescales (gyro ×16/20, accel ×16384/10000) — a real **Deck↔Deck gyro/accel
|
||||
> correctness fix**; (2) **`fold_paddles`** + `RemapConfig` (`PUNKTFUNK_STEAM_REMAP=paddles=drop|
|
||||
> stickclicks|shoulders`, default drop) wired into the DualSense + DS4 managers so a client's back
|
||||
> grips aren't silently lost on a PlayStation fallback (those pads have no back-button HID slot; the
|
||||
> uinput Xbox pad already exposes them as `BTN_TRIGGER_HAPPY5-8`). Plus a **runtime degrade ladder**
|
||||
> in `resolve_gamepad`: a UHID backend (DualSense/DS4/SteamDeck) on a host where `/dev/uhid` isn't
|
||||
> writable now falls back to the uinput Xbox 360 pad instead of a dead controller. The throwaway M0/M1
|
||||
> spike is deleted (M2's `#[ignore]`d backend test subsumes it). On-box backend test still green;
|
||||
> workspace clippy/fmt/test green. *Deferred as optional `RemapConfig` growth: gyro→mouse / trackpad→
|
||||
> stick/mouse synthesis on an Xbox target (no IMU/touchpad slot — currently a documented drop).*
|
||||
>
|
||||
> **M4 (complete) result:** *(desktop capture — see the prior entry.)* Plus: **C-ABI** —
|
||||
> `PunktfunkRichInputEx` (size-prefixed superset) + `punktfunk_connection_send_rich_input2` (the
|
||||
|
||||
Reference in New Issue
Block a user