From: Aric Stewart Subject: Re: [PATCH 5/5] xinput: Fix axis scaling arithmetic. Message-Id: <7d3e60aa-ef66-e760-e70c-29d303a8162d@codeweavers.com> Date: Fri, 15 Feb 2019 13:40:39 -0600 In-Reply-To: <20190212060607.16664-5-z.figura12@gmail.com> References: <20190212060607.16664-1-z.figura12@gmail.com> <20190212060607.16664-5-z.figura12@gmail.com> Signed-off-by: Aric Stewart On 2/12/19 12:06 AM, Zebediah Figura wrote: > Cast difference to ULONGLONG to ensure unsigned division, and correct > off-by-one error present when inverting axes (previously hidden by signed > division bug). > > Fixes a regression introduced by bd9e130ee5b569433f2c847c5b2b562f0ae35ac5. > > Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46623 > > Signed-off-by: Zebediah Figura > --- > dlls/xinput1_3/hid.c | 23 +++++++++++++++-------- > 1 file changed, 15 insertions(+), 8 deletions(-) > > diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c > index 7553aaba63..c0c405fbdb 100644 > --- a/dlls/xinput1_3/hid.c > +++ b/dlls/xinput1_3/hid.c > @@ -318,8 +318,15 @@ void HID_destroy_gamepads(xinput_controller *devices) > LeaveCriticalSection(&hid_xinput_crit); > } > > -#define SCALE_SHORT(v,r) (SHORT)((((0xffff)*(v - (r).min))/(r).range)-32767) > -#define SCALE_BYTE(v,r) (BYTE)((((0xff)*(v - (r).min))/(r).range)) > +static SHORT scale_short(LONG value, const struct axis_info *axis) > +{ > + return ((((ULONGLONG)(value - axis->min)) * 0xffff) / axis->range) - 32768; > +} > + > +static BYTE scale_byte(LONG value, const struct axis_info *axis) > +{ > + return (((ULONGLONG)(value - axis->min)) * 0xff) / axis->range; > +} > > void HID_update_state(xinput_controller* device) > { > @@ -382,22 +389,22 @@ void HID_update_state(xinput_controller* device) > } > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.sThumbLX = SCALE_SHORT(value, private->lx); > + device->state.Gamepad.sThumbLX = scale_short(value, &private->lx); > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Y, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.sThumbLY = -SCALE_SHORT(value, private->ly); > + device->state.Gamepad.sThumbLY = -scale_short(value, &private->ly) - 1; > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RX, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.sThumbRX = SCALE_SHORT(value, private->rx); > + device->state.Gamepad.sThumbRX = scale_short(value, &private->rx); > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.sThumbRY = -SCALE_SHORT(value, private->ry); > + device->state.Gamepad.sThumbRY = -scale_short(value, &private->ry) - 1; > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RZ, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.bRightTrigger = SCALE_BYTE(value, private->rtrigger); > + device->state.Gamepad.bRightTrigger = scale_byte(value, &private->rtrigger); > > HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, &value, private->ppd, target_report, private->report_length); > - device->state.Gamepad.bLeftTrigger = SCALE_BYTE(value, private->ltrigger); > + device->state.Gamepad.bLeftTrigger = scale_byte(value, &private->ltrigger); > LeaveCriticalSection(&private->crit); > } > >