feat(clients/steam): M4 — desktop SDL clients capture the rich Steam inputs
The Linux + Windows native clients (clients/{linux,windows}/src/gamepad.rs) now
capture and send the Steam Controller / Steam Deck rich inputs, so a real Deck
(off Steam Input) or a Steam Controller on a desktop client drives the host's
virtual hid-steam pad end-to-end:
- Set SDL's HIDAPI Steam hints (SDL_JOYSTICK_HIDAPI_STEAMDECK / _STEAM) before
init so SDL opens Valve devices directly (paddles + both trackpads + gyro as
first-class SDL gamepad inputs).
- Detect the Deck/SC by VID/PID (0x28DE + 0x1205 / 0x1102 / 0x1142) ->
GamepadPref::SteamDeck (there is no SDL gamepad type for it), so the host
builds the virtual Deck with the right identity.
- Map the SDL paddle + Misc1 buttons -> BTN_PADDLE1..4 / BTN_MISC1 (a free win
for Xbox Elite paddles too).
- Route a SECOND touchpad -> RichInput::TouchpadEx (SDL touchpad 0 = left ->
surface 1, 1 = right -> surface 2, signed coords); a single touchpad keeps the
legacy Touchpad. New forward_touch() helper centralizes the choice.
- Track held touchpad contacts per (surface, finger) and lift them on pad
switch/detach so a contact held at that moment can't stick.
- Sensor (gyro/accel) capture was already generic across pad types.
Linux client builds + clippy clean; the Windows client is a near-verbatim
mirror (windows CI compiles it). On a Deck in Game Mode, Steam Input still holds
the device — the user disables Steam Input for the client (the Decky UX, next);
on a desktop client (or a Deck with Steam Input off) the hints just work.
Remaining M4: Decky Disable-Steam-Input UX, Apple/Android parity, and the C-ABI
PunktfunkRichInputEx + send_rich_input2 (Apple/embedder send path). Not pushed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
# Rich Steam Controller & Steam Deck support
|
||||
|
||||
> **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`), 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.
|
||||
> **Status:** **M0–M3 GREEN + M4 desktop-capture done (2026-06-29).** The host side is complete:
|
||||
> the virtual `hid-steam` Deck binds, is byte-exact, is a wired backend (`PUNKTFUNK_GAMEPAD=
|
||||
> steamdeck`), and the protocol carries the rich Steam inputs. The **Linux + Windows SDL clients now
|
||||
> capture + send** them. Remaining M4: the Decky Disable-Steam-Input UX, Apple/Android parity, and
|
||||
> the C-ABI `PunktfunkRichInputEx`/`send_rich_input2` (Apple/embedder send path).
|
||||
>
|
||||
> **M4 (desktop client capture) result:** `clients/{linux,windows}/src/gamepad.rs` (the SDL services)
|
||||
> now: set the SDL HIDAPI Steam hints (`SDL_JOYSTICK_HIDAPI_STEAMDECK`/`_STEAM`) so SDL opens Valve
|
||||
> devices directly; detect the Deck/SC by VID/PID (`0x28DE` + `0x1205`/`0x1102`/`0x1142`) →
|
||||
> `GamepadPref::SteamDeck`; map the SDL paddle + Misc1 buttons → the `BTN_PADDLE1..4`/`BTN_MISC1`
|
||||
> wire bits; and route a **second** touchpad → `RichInput::TouchpadEx` (SDL touchpad 0 = left →
|
||||
> surface 1, 1 = right → surface 2, signed coords) while a single touchpad keeps the legacy
|
||||
> `Touchpad`. Held touchpad contacts are now tracked per `(surface,finger)` and lifted on pad
|
||||
> switch/detach. Sensor (gyro/accel) capture was already generic. Linux client builds + clippy clean;
|
||||
> Windows is a near-verbatim mirror (windows CI compiles it). **Caveat:** on a Deck in Game Mode,
|
||||
> Steam Input still holds the device — the user must disable Steam Input for the client (the Decky UX,
|
||||
> next); on a desktop client (or a Deck with Steam Input off) the hints just work.
|
||||
>
|
||||
> **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`
|
||||
|
||||
Reference in New Issue
Block a user