feat(proto/steam): M3 — rich Steam wire (back buttons + 2nd trackpad)
Carry the rich Steam Controller / Steam Deck inputs end-to-end on the wire — strictly additive + forward-compatible (unknown kinds/bits drop on old peers). Core (punktfunk-core): - input.rs: BTN_PADDLE1..4 + BTN_MISC1 in Moonlight's buttonFlags2<<16 namespace (so the GameStream paddle path and native grips share one host injector map; Steam L4/L5/R4/R5 reuse the four Xbox-Elite paddle slots). - quic.rs: RichInput::TouchpadEx (kind 0x03 — surface 0/1/2, touch+click, signed coords, pressure; the second trackpad the single Touchpad can't express) and HidOutput::TrackpadHaptic (kind 0x04 — the SC voice-coil pulse). Round-tripped. - abi.rs: PUNKTFUNK_GAMEPAD_STEAMDECK=6 / _STEAMCONTROLLER=5, the paddle bits, RICH_TOUCHPAD_EX / HIDOUT_TRACKPAD_HAPTIC constants. from_hid packs TrackpadHaptic into the existing which + effect[0..6] — the legacy structs do NOT grow (guarded by new size_of==20/19 asserts); GamepadPref lockstep + paddle-bit lockstep asserts extended. include/punktfunk_core.h regenerated. Host (punktfunk-host): - steam_proto::from_gamepad maps the wire paddles -> the four Deck grips + QAM; apply_rich routes TouchpadEx left/right -> the matching pad. - every DualSense/DS4 manager (Linux + Windows) gained a TouchpadEx arm (surface 0/2 -> its one touchpad; surface 1 ignored) so the variant compiles everywhere and a Steam client streaming to a DS host keeps its right pad. - the xpad BUTTON_MAP finally consumes the GameStream paddle bits (BTN_TRIGGER_HAPPY5-8) — Sunshine/Moonlight paddle clients were silently no-op'd before (design §5.6). - Android feedback: drop TrackpadHaptic (no coils; rumble rides 0xCA). Validated on-box: the ignored backend test now drives the full wire path — from_gamepad (BTN_A + the L4 grip) + apply_rich (a left-pad TouchpadEx) reach the evdev as BTN_A + ABS_HAT0X=-8000. Wire round-trips + paddle/TouchpadEx mapping unit-tested. Workspace clippy/fmt/test green. Not pushed. Deferred to M4: the C-ABI PunktfunkRichInputEx + send_rich_input2 (only the Apple/embedder *send* path needs it; the host decodes TouchpadEx today). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
# Rich Steam Controller & Steam Deck support
|
||||
|
||||
> **Status:** **M0–M2 GREEN — Linux virtual Deck binds, is byte-exact, AND is a wired host backend,
|
||||
> **Status:** **M0–M3 GREEN — virtual Deck binds + byte-exact + wired backend + the rich wire,
|
||||
> on-box (2026-06-29).** The greenfield virtual `hid-steam` device works end-to-end as a selectable
|
||||
> host gamepad backend: `PUNKTFUNK_GAMEPAD=steamdeck` builds a per-session `SteamControllerManager`
|
||||
> that creates a `/dev/uhid` `28DE:1205` device, enters `gamepad_mode`, and feeds the byte-exact Deck
|
||||
> report. Next: M3 (the protocol/ABI wire surface — back-button bits, `TouchpadEx`, the C-ABI
|
||||
> `GamepadPref` constants) + M4 (client capture). This remains the design + milestone plan; the Steam
|
||||
> analogue of the shipped virtual DualSense (`design/windows-dualsense-scoping.md`).
|
||||
> host gamepad backend (`PUNKTFUNK_GAMEPAD=steamdeck`), and the protocol now carries the rich Steam
|
||||
> inputs (back buttons + second trackpad). Next: M4 (client capture — SDL Steam hints, paddles, 2nd
|
||||
> touchpad, the Decky Disable-Steam-Input UX, + the C-ABI `PunktfunkRichInputEx`/`send_rich_input2`
|
||||
> for the Apple/embedder send path). The Steam analogue of the shipped virtual DualSense.
|
||||
>
|
||||
> **M3 result (protocol / ABI wire, on-box):** strictly additive + forward-compatible (§5).
|
||||
> Core: back-button bits `BTN_PADDLE1..4` + `BTN_MISC1` (in Moonlight's `buttonFlags2<<16`
|
||||
> namespace, so GameStream paddle + native grips share one map); `RichInput::TouchpadEx` (kind
|
||||
> `0x03` — surface 0/1/2, click, signed coords, pressure); `HidOutput::TrackpadHaptic` (kind `0x04`).
|
||||
> ABI: `PUNKTFUNK_GAMEPAD_STEAMDECK=6`/`_STEAMCONTROLLER=5` + the paddle/`RICH_TOUCHPAD_EX`/
|
||||
> `HIDOUT_TRACKPAD_HAPTIC` constants, `from_hid` packs `TrackpadHaptic` into the existing
|
||||
> `which`+`effect[0..6]` (the legacy structs do **not** grow — guarded by `size_of==20/19` asserts);
|
||||
> regenerated `punktfunk_core.h`. Host: `steam_proto::from_gamepad` maps the paddles → the four Deck
|
||||
> grips + QAM; `apply_rich` routes `TouchpadEx` left/right → the matching pad; every DS manager
|
||||
> (DualSense/DS4, Linux + Windows) gained a `TouchpadEx` arm (surface 0/2 → its one touchpad); the
|
||||
> xpad `BUTTON_MAP` finally consumes the GameStream paddle bits (`BTN_TRIGGER_HAPPY5-8`, previously
|
||||
> dropped). Wire round-trips + mapping unit-tested; the on-box backend test now drives the full path
|
||||
> (`from_gamepad` grip + `apply_rich` left-pad) → evdev `BTN_A` + `ABS_HAT0X`. Workspace
|
||||
> clippy/fmt/test green. **Deferred to M4:** the C-ABI `PunktfunkRichInputEx` + `send_rich_input2`
|
||||
> (only the Apple/C *send* path needs it; the host decodes `TouchpadEx` today).
|
||||
>
|
||||
> **M2 result (backend + wiring, on-box):** `inject/linux/steam_controller.rs`
|
||||
> (`SteamControllerManager`/`SteamDeckPad`, mirroring `dualsense.rs`) is wired into `PadBackend`
|
||||
|
||||
Reference in New Issue
Block a user