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:
@@ -399,4 +399,27 @@ mod tests {
|
||||
c.fec.fec_percent = 15; // 250 + ceil(250*15/100)=288 > 255
|
||||
assert!(c.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gamepad_pref_steam_roundtrip() {
|
||||
use GamepadPref::*;
|
||||
// Wire-byte round-trip for the Steam additions; an unknown byte still degrades to Auto.
|
||||
for (p, b) in [(SteamController, 5u8), (SteamDeck, 6)] {
|
||||
assert_eq!(p.to_u8(), b);
|
||||
assert_eq!(GamepadPref::from_u8(b), p);
|
||||
}
|
||||
assert_eq!(GamepadPref::from_u8(99), Auto);
|
||||
// Name parsing + canonical-name round-trip.
|
||||
assert_eq!(GamepadPref::from_name("steamdeck"), Some(SteamDeck));
|
||||
assert_eq!(GamepadPref::from_name("deck"), Some(SteamDeck));
|
||||
assert_eq!(
|
||||
GamepadPref::from_name("steamcontroller"),
|
||||
Some(SteamController)
|
||||
);
|
||||
assert_eq!(SteamDeck.as_str(), "steamdeck");
|
||||
assert_eq!(
|
||||
GamepadPref::from_name(SteamController.as_str()),
|
||||
Some(SteamController)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user