[x] that I haven't found an existing compatibility report for this game.
[x] that I have checked whether there are updates for my system available.
Symptoms
Joystick analog axes (Logitech Extreme 3D Pro) are stuck at maximum value. Buttons work correctly. Affects any game that reads joystick axes via Raw Input API + HidP_GetUsageValue (Arma Reforger's Enfusion engine does this).
Root cause:dlls/winebus.sys/bus_sdl.c declares joystick axes with a signed HID logical range (-32768 to 32767) because that's SDL's native range. However, HidP_GetUsageValue returns a ULONG (unsigned) per Windows API spec. On real Windows hardware, joystick HID descriptors use unsigned logical ranges (e.g. 0-1023). When a game calls HidP_GetUsageValue on Wine's virtual HID device, small negative values near center (e.g. -97) are returned as large unsigned values (e.g. 0xFFFFFF9F for 32-bit or 0xFF9F
for 16-bit), appearing as max deflection.
Games using DirectInput are unaffected because dinput/joystick_hid.c handles signed→unsigned conversion internally via scale_axis_value(). Only games bypassing DirectInput and parsing HID reports directly (via RegisterRawInputDevices + GetRawInputData + HidP_GetUsageValue) are affected.
Two-line fix:
dlls/winebus.sys/bus_sdl.c (line 371) — change axis logical range to unsigned:
Compatibility Report
System Information
GPU: AMD RX 6800 (Navi 21)
Video driver version: mesa 1:26.0.1-1
Kernel version: 6.19.6-arch1-1
Link to full system information report as Gist: https://gist.github.com/EchoTD/f4be146c2e70a6ab4bd7c9d1b43ddda0
Proton version: GE-Proton10-12
I confirm:
Symptoms
Joystick analog axes (Logitech Extreme 3D Pro) are stuck at maximum value. Buttons work correctly. Affects any game that reads joystick axes via Raw Input API + HidP_GetUsageValue (Arma Reforger's Enfusion engine does this).
Root cause:
dlls/winebus.sys/bus_sdl.cdeclares joystick axes with a signed HID logical range (-32768 to 32767) because that's SDL's native range. However,HidP_GetUsageValuereturns aULONG(unsigned) per Windows API spec. On real Windows hardware, joystick HID descriptors use unsigned logical ranges (e.g. 0-1023). When a game callsHidP_GetUsageValueon Wine's virtual HID device, small negative values near center (e.g. -97) are returned as large unsigned values (e.g. 0xFFFFFF9F for 32-bit or 0xFF9Ffor 16-bit), appearing as max deflection.
Games using DirectInput are unaffected because
dinput/joystick_hid.chandles signed→unsigned conversion internally viascale_axis_value(). Only games bypassing DirectInput and parsing HID reports directly (via RegisterRawInputDevices + GetRawInputData + HidP_GetUsageValue) are affected.Two-line fix:
dlls/winebus.sys/bus_sdl.c(line 371) — change axis logical range to unsigned:dlls/winebus.sys/hid.cinhid_device_set_abs_axis()— offset SDL signed values to unsigned:Reproduction
steam-1874880.log.gz