From 678e11eade3125863f1f7bebfecf55aef40c8d52 Mon Sep 17 00:00:00 2001 From: bicarus <202771338+bicarus-dev@users.noreply.github.com> Date: Mon, 27 Apr 2026 01:41:44 -0700 Subject: [PATCH] rawinput: fix up devices that report invalid max values (#658) ## Link to GitHub Issue or related Pull Request, if one exists regression caused by #653 ## Description of change Some controllers - like the Xbox One controller I have - reports 0xffffffff as the max range value for analog, despite reporting 16-bit width. This causes us to consider 0xffffffff as -1 so the range became [0, -1] which is invalid. Our automatic calibration does eventually fix this (-1 will fix itself to become the highest actual value reported, which would be 0xffff). This seems to be a common issue with XInput-based controllers in general: see `Correct_Axis_Max` in https://github.com/argonlefou/DemulShooter/blob/master/DsCore/RawInput/RawInputController.cs #653 removed the fix that was masking this issue. Put in a new fix that fixes these up. ## Testing Tested with Xbox One controller. --- src/spice2x/rawinput/rawinput.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/spice2x/rawinput/rawinput.cpp b/src/spice2x/rawinput/rawinput.cpp index e5bbec9..e13c9e5 100644 --- a/src/spice2x/rawinput/rawinput.cpp +++ b/src/spice2x/rawinput/rawinput.cpp @@ -605,6 +605,24 @@ void rawinput::RawInputManager::devices_scan_rawinput(RAWINPUTDEVICELIST *device value_caps.LogicalMax = 255; } + // fix up invalid max values (seen on xbox controllers where max is 0xffffffff despite being 16-bit) + if (value_caps.LogicalMin == 0 && value_caps.BitSize > 0 && value_caps.BitSize < 32) { + const uint32_t field_max = (1u << value_caps.BitSize) - 1u; + const uint32_t logical_max = static_cast(value_caps.LogicalMax); + + if (logical_max > field_max) { + log_info( + "rawinput", + "value cap {} LogicalMax exceeds bit width, fixing it up: {} -> {}", + value_cap_num, + value_caps.LogicalMax, + field_max + ); + + value_caps.LogicalMax = static_cast(field_max); + } + } + // fix up hat switch to initially report as neutral position if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) { value_states[value_cap_num] = -1.f;