All structures are packed to one-byte alignment and begin with {size, version}.
Both fields are mandatory. New protocol versions must add a handshake strategy;
they must not reinterpret v1 fields in place.
| Operation | Access | Behavior |
|---|---|---|
GET_DRIVER_INFO |
Read | Returns driver semver, ABI version, and capabilities. |
CREATE_DUALSENSE |
Write | Creates one fixed wired DS5 for this handle. |
DESTROY_DEVICE |
Write | Idempotently destroys that handle's DS5. |
SUBMIT_INPUT |
Write | Replaces the full input state and submits report 1. |
READ_OUTPUT |
Read | Overlapped read; returns the next/latest semantic feedback state. |
PING |
Read | Verifies the control path without creating a HID device. |
Input stick coordinates use 0..255 with 128 neutral. D-pad uses 0..7
clockwise from up and 8 for neutral. Touch coordinates are clamped to
1920x1080. Gyroscope and accelerometer values are already quantized signed
DualSense report units; conversion from Moonlight's physical units belongs in
the client mapping layer so the ABI has no floating-point representation issue.
Output provides both semantic fields and the bounded original HID report.
valid identifies which semantic fields the game changed. Adaptive trigger
values preserve the 11-byte DualSense effect payload because its modes are
device-specific. raw_report lets diagnostics and future Sunshine versions
handle consumer-specific commands without changing the driver ABI or silently
discarding evidence.
Backpressure is latest-value-wins. If no output read is pending, one most-recent event is cached. Applications should keep a read pending to avoid coalescing.