You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
| 50 |`0x0e`|Operating range = float `2700.0` (the wheel's max range; previously misread as a frequency) |
84
85
| 51 |`0x01`| Neutral sample |
85
86
| 52 |`0x07`| Handshake / query |
86
87
| 53 |`0x01`| Neutral sample |
@@ -142,6 +143,34 @@ byte[60-63]: window[12]
142
143
143
144
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`.
144
145
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
0 commit comments