fix(gamepad/host): map BTN_MISC1 to the DualSense mute button (G6)

DsState::from_gamepad mapped GUIDE→PS and TOUCHPAD→TOUCHPAD into buttons[2] but
never handled BTN_MISC1, so the mic-mute / capture button clients send was inert
on every PlayStation-family virtual pad (DualSense/DualShock4), and btn2::MUTE
was dead code. Map BTN_MISC1 → btn2::MUTE (rebuilt from the wire bit each frame
like PS/TOUCHPAD, so no persistence gap) and drop the #[allow(dead_code)].

Test extended (from_gamepad_maps_touchpad_click); green on Linux (.21).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-13 12:04:59 +02:00
parent 2642ba6ad0
commit 43e52437c0
@@ -96,7 +96,7 @@ pub mod btn1 {
pub mod btn2 {
pub const PS: u8 = 0x01;
pub const TOUCHPAD: u8 = 0x02;
#[allow(dead_code)]
/// Mic-mute / capture button — set from the wire `BTN_MISC1` in `DsState::from_gamepad`.
pub const MUTE: u8 = 0x04;
}
@@ -223,6 +223,12 @@ impl DsState {
if on(gs::BTN_TOUCHPAD) {
s.buttons[2] |= btn2::TOUCHPAD;
}
// The mic-mute / capture button (Deck '…' QAM on the Steam path). Clients send it as
// BTN_MISC1; without this the DualSense mute button was inert on every PlayStation-family
// virtual pad. Rebuilt from the wire bit each frame like PS/TOUCHPAD, so no persistence gap.
if on(gs::BTN_MISC1) {
s.buttons[2] |= btn2::MUTE;
}
s
}
@@ -669,12 +675,16 @@ mod tests {
assert_eq!(r[53], 0x0A);
}
/// The wire touchpad-click bit (Moonlight's extended position) lands in `buttons[2]`.
/// The wire touchpad-click / guide / mute bits (Moonlight's extended positions) land in
/// `buttons[2]`.
#[test]
fn from_gamepad_maps_touchpad_click() {
use punktfunk_core::input::gamepad as gs;
let s = DsState::from_gamepad(gs::BTN_TOUCHPAD | gs::BTN_GUIDE, 0, 0, 0, 0, 0, 0);
assert_eq!(s.buttons[2], btn2::PS | btn2::TOUCHPAD);
// BTN_MISC1 → the mic-mute / capture button (G6: was previously dropped entirely).
let s = DsState::from_gamepad(gs::BTN_MISC1, 0, 0, 0, 0, 0, 0);
assert_eq!(s.buttons[2], btn2::MUTE);
let s = DsState::from_gamepad(gs::BTN_A, 0, 0, 0, 0, 0, 0);
assert_eq!(s.buttons[2], 0);
}