Skip to content

Commit 55c5f7e

Browse files
author
mescon
committed
docs: type-0x0e is the SDK operating-range command - the 90-degree root cause
Live usbmon capture of an AC EVO launch settles the launch-time 90-degree reset: the game's SDK session init sends TrueForce type-0x0e with IEEE float 90.0 on interface 2. Type-0x0e carries the operating range in degrees (the canonical init's packet 50 value '2700.0', previously documented as a frequency/Nyquist config, is exactly the wheel's maximum range). The entire capture contains zero interface-1 HID++ range traffic other than the driver's own polls, whose replies flip 900 -> 90 in the same window - which is why the reset never produced a HID++ broadcast and resisted every interface-1 investigation. Also recorded from the same capture: AC EVO's init adds a type-0x0b packet (float 1.0, unknown) and a type-0x09 with floats 1.0 / 350.0 beyond the canonical G Hub sequence.
1 parent f9289f6 commit 55c5f7e

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

docs/TRUEFORCE_PROTOCOL.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ The sequence counter is rewritten at send time from a session-local counter. Eac
6868
| `0x06` | Effect slot configuration (6 slots) |
6969
| `0x07` | Query / handshake |
7070
| `0x09` | Runtime parameter update |
71-
| `0x0e` | Frequency / sample rate config |
71+
| `0x0b` | Unknown (observed from AC EVO's session init with float `1.0`) |
72+
| `0x0e` | **Operating range, IEEE 754 LE float degrees** (previously misread as a frequency config) |
7273

7374
## Initialisation Sequence (sent twice)
7475

@@ -80,7 +81,7 @@ The 68 packets are stored verbatim in `userspace/libtrueforce/src/tf_init_data.h
8081
|---------|------|---------|
8182
| 1-48 | `0x05` | 48 parameters (indices `0x00`-`0x1d` and `0x2b`-`0x3c`) as IEEE 754 LE floats |
8283
| 49 | `0x01` | Neutral sample (primes the stream) |
83-
| 50 | `0x0e` | Frequency / Nyquist config (IEEE 754 float `2700.0`) |
84+
| 50 | `0x0e` | Operating range = float `2700.0` (the wheel's max range; previously misread as a frequency) |
8485
| 51 | `0x01` | Neutral sample |
8586
| 52 | `0x07` | Handshake / query |
8687
| 53 | `0x01` | Neutral sample |
@@ -142,6 +143,34 @@ byte[60-63]: window[12]
142143

143144
Packet cadence in libtrueforce is 250 Hz (4 new samples * 250 Hz = 1000 sample/s effective). If userspace can't keep up the thread repeats the previous window (Windows does the same under input starvation) and the wheel gradually unwinds. If userspace overruns the ring, `logitf_stream_push_s16()` blocks on `ring_space`.
144145

146+
## Type `0x0e`: Operating Range (root cause of the "90 degrees on game launch" bug)
147+
148+
Decoded 2026-07-02 from a live usbmon capture of an AC EVO launch on
149+
Linux: type-`0x0e` carries the wheel's operating range as an IEEE 754
150+
LE float in degrees at payload bytes 6-9. Evidence:
151+
152+
- The canonical init's packet 50 carries `2700.0` - exactly the
153+
wheel's maximum range, not a plausible sample rate.
154+
- AC EVO's SDK session init appends a second `0x0e` with `90.0`
155+
(`01000000 0e <seq> 0000b442`), and the wheel's physical range
156+
flips 900 -> 90 in the same 20-second window with ZERO HID++
157+
traffic on interface 1 (confirmed: the only interface-1 range
158+
packets in the entire capture are the Linux driver's own polls,
159+
whose replies flip from 900 to 90).
160+
161+
This is `logiWheelSetOperatingRange*()` on the wire, and it explains
162+
why the launch-time range reset never produced a HID++ broadcast: it
163+
does not go through the HID++ range feature at all. Games push their
164+
configured steering rotation here at session start; a game whose
165+
rotation setting is 90 (or defaulted) locks the wheel to 90 degrees.
166+
The kernel driver's 20 s range poll detects the change and updates
167+
`wheel_range`; re-applying the desired range via HID++ afterwards
168+
sticks (the SDK write is one-shot at session init).
169+
170+
AC EVO's init also differs from the canonical G Hub init in two more
171+
packets: a type-`0x0b` with float `1.0` (purpose unknown) and a
172+
type-`0x09` carrying floats `1.0` and `350.0`.
173+
145174
## Device Response (Type `0x02`, endpoint `0x83` -> host)
146175

147176
```

0 commit comments

Comments
 (0)