mirror of
https://github.com/X11Libre/xf86-input-joystick.git
synced 2026-03-24 01:34:06 +00:00
backend_evdev: fix scaling overflow for high resolution axes
The module scales all axis values from the kernel to the range of -32768 .. 32768, for compatibility with the old joystick kernel module. The current implementation had an integer overflow, if the axis had a high resolution of > 16384, like the popular XBox 360 controller. This commitmakes the scaling use float instead to fix erratic behaviour on high resolution joysticks. The joystick backend was not affected. Fixes bug: https://bugs.freedesktop.org/show_bug.cgi?id=42399
This commit is contained in:
@@ -277,8 +277,30 @@ jstkReadData_evdev(JoystickDevPtr joystick,
|
||||
struct jstk_evdev_axis_data *axis;
|
||||
axis = &data->axis[iev.code];
|
||||
if ((axis->number >= 0) && (axis->number < MAXAXES)) {
|
||||
value = (iev.value - axis->min) * 65535
|
||||
/ (axis->max - axis->min) - 32768;
|
||||
/* NOTE: controllers report totally different ranges:
|
||||
* - 0..256, with a center of 127 (Logitech Dual Action axes)
|
||||
* - 0..256 with a center of 0 (XBox left/right triggers)
|
||||
* - -32768..32768 with a center of 0 (XBox axes)
|
||||
*
|
||||
* These ranges will ALL be scaled to -32768..32768, with
|
||||
* the center value to be assumed 0. This is for compatibility
|
||||
* with the legacy joystick module, which reports values in
|
||||
* the same range.
|
||||
*
|
||||
* The value is also important for the deadzone, which can be
|
||||
* configured by the user and is in -32768..32768 range.
|
||||
*
|
||||
* TODO: how to respect center value, so that that XBox triggers
|
||||
* and logitech axes report idle, when not moved?
|
||||
* TODO: report all values as -1.0f..1.0f, but this would possibly
|
||||
* break config file semantics.
|
||||
*/
|
||||
|
||||
float v = (float) iev.value;
|
||||
v = (v - (float)axis->min) * 65535.0f
|
||||
/ (axis->max - axis->min) - 32768.0f;
|
||||
value = (int) v;
|
||||
|
||||
if (abs(value) < joystick->axis[axis->number].deadzone) {
|
||||
/* We only want one event when in deadzone */
|
||||
if (joystick->axis[axis->number].value != 0) {
|
||||
|
||||
Reference in New Issue
Block a user