fix(host/dualsense): report full battery + log rumble forwarding
Two DualSense (UHID) fixes surfaced live on the Bazzite host: - Battery: serialize_state never set the input report's status byte (struct off 52 → r[53]), so hid-playstation read battery capacity 0 and SteamOS warned "low battery" even on a fully-charged pad. Set it to 0x0A (discharging, low nibble 0xA → 100 %) — a virtual pad has no real cell. (Forwarding the client pad's real charge is a later feature.) Regression assert added to the layout test. - Rumble diagnostic: log the silent→active transition when forwarding a buzz on the 0xCA plane, so a live test can tell "host never receives rumble from the game" (Steam Input / parse) apart from "client doesn't render it". Once per buzz, no spam. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -275,6 +275,11 @@ fn serialize_state(r: &mut [u8; DS_INPUT_REPORT_LEN], st: &DsState, seq: u8, ts:
|
||||
r[28..32].copy_from_slice(&ts.to_le_bytes()); // sensor_timestamp (struct off 27)
|
||||
pack_touch(&mut r[33..37], &st.touch[0]); // touch point 1 (struct off 32)
|
||||
pack_touch(&mut r[37..41], &st.touch[1]); // touch point 2
|
||||
// status byte (struct off 52 → r[53]) — hid-playstation reads battery here: low nibble =
|
||||
// capacity (×10+5 %), high nibble = charging state (0 = discharging). A virtual pad has no
|
||||
// real cell, so report "discharging, full" (0x0A → 100 %); leaving it 0 makes SteamOS / the
|
||||
// kernel see ~5 % and warn "low battery". (We don't forward the client pad's real charge yet.)
|
||||
r[53] = 0x0A;
|
||||
}
|
||||
|
||||
fn pack_touch(dst: &mut [u8], t: &Touch) {
|
||||
@@ -754,6 +759,9 @@ mod tests {
|
||||
assert_eq!(r[35], 0x61); // x_hi nibble 0x1 | (y & 0xF) << 4 (y=0x356 → 0x6 << 4)
|
||||
assert_eq!(r[36], 0x35); // y >> 4
|
||||
assert_eq!(r[37] & 0x80, 0x80); // touch point 2 inactive
|
||||
// status byte (struct off 52): discharging (high nibble 0) + full capacity (low nibble
|
||||
// 0xA → 100 %), so SteamOS/hid-playstation never reports a false "low battery".
|
||||
assert_eq!(r[53], 0x0A);
|
||||
}
|
||||
|
||||
/// The wire touchpad-click bit (Moonlight's extended position) lands in `buttons[2]`.
|
||||
|
||||
@@ -1254,6 +1254,11 @@ fn input_thread(
|
||||
pads.pump(
|
||||
|pad, low, high| {
|
||||
if let Some(s) = rumble_state.get_mut(pad as usize) {
|
||||
// Log the silent→active transition (once per buzz) so a live test can tell
|
||||
// "host never gets rumble from the game" apart from "client doesn't render it".
|
||||
if *s == (0, 0) && (low != 0 || high != 0) {
|
||||
tracing::info!(pad, low, high, "rumble: forwarding to client (0xCA)");
|
||||
}
|
||||
*s = (low, high);
|
||||
rumble_seen[pad as usize] = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user