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:
Sascha Hlusiak
2012-10-06 16:18:24 +02:00
parent 053405f711
commit 342057bf38

View File

@@ -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) {