Found on glass, first real streaming session: everything worked except the right stick, and Steam
correctly showed "Xbox One S Controller". `XBOX_RDESC` declared the right stick as `Rx`/`Ry`.
`xinputhid`, which translates our HID collection into XUSB, maps `Z`/`Rz` to the right stick and
does not treat `Rx`/`Ry` as one, so those two axes reached nothing.
Two usage bytes. Left and right were declared identically here — same collection, same globals,
same size and count — so the usages were the entire difference, which is what makes the diagnosis
airtight rather than plausible. Note `DUALSENSE_RDESC`, a real capture, also uses `Z`/`Rz` for its
right stick and puts the TRIGGERS on `Rx`/`Ry`; that is most likely where the original mistake came
from.
⚠️ Byte offsets are unchanged — still 16×2 at bit 5.0 — so `xbox_proto`'s layout tests and the
host-side packing are untouched. This is a pure relabelling.
🛑 THE REAL LESSON IS THE HARNESS, AND IT IS FIXED HERE TOO. This survived every bench measurement
because `dualsense-windows-test` drove LS-X and the A button and left the other five analogue axes
at zero. `XInputGetState` read `RX [0..0]`, which I read as "the devtest doesn't move it" — true,
and useless: a harness that exercises one axis cannot tell "this axis is not mapped" from "nothing
is driving it", and the two are indistinguishable in every consumer. The devtest now sweeps all six
axes on distinct phases and ramps both triggers, so one run shows which axes arrive AND that they
are not crosstalking onto each other's bytes.
MEASURED ON .173, same run shape before and after, devtest sweeping all six axes:
before: LX [-11264..24576] LY [-32768..31744] RX [0..0] RY [-1..-1] LT [0..248] RT [7..255]
after: LX [-8192..26624] LY [-32768..31744] RX [-32768..31744] RY [-24576..10240] LT [0..248] RT [7..255]
VERIFIED
* `cargo test -p pf-inject --lib` 104/104 on Windows; `xbox` subset 11/11 on macOS — the layout
tests still pass because nothing moved.
* Driver rebuilds and signs; the descriptor is still 223 bytes so the `wReportLength` const assert
is undisturbed.
* `cargo fmt --all --check` clean.
NOT VERIFIED
* Not yet re-tested in a real streaming session — that is the next on-glass run.
* ⚠️ A leftover finding from the same session, unrelated to this fix and NOT investigated: the
session's pad devnode SURVIVES client disconnect and keeps the `Global\pfds-boot-0` bootstrap
mailbox, so a devtest run afterwards fails with `Zugriff verweigert (0x80070005)` and silently
measures the stale pad instead. Restarting the service releases it. Worth its own look.