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.
This commit is contained in:
bicarus
2026-04-27 01:41:44 -07:00
committed by GitHub
parent f72313fe45
commit 678e11eade
+18
View File
@@ -605,6 +605,24 @@ void rawinput::RawInputManager::devices_scan_rawinput(RAWINPUTDEVICELIST *device
value_caps.LogicalMax = 255; 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<uint32_t>(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<LONG>(field_max);
}
}
// fix up hat switch to initially report as neutral position // fix up hat switch to initially report as neutral position
if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) { if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) {
value_states[value_cap_num] = -1.f; value_states[value_cap_num] = -1.f;