summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Hlusiak <saschahlusiak@arcor.de>2012-10-06 16:18:24 +0200
committerSascha Hlusiak <saschahlusiak@arcor.de>2013-01-16 10:50:40 +0100
commit342057bf38e2da46609ed2fa0d3f5fb46c8ed215 (patch)
treecf170f000b6b7c7785618d4c5fcc499485d12885
parent053405f711512959e95d0a882d69b6cba6405e7d (diff)
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
-rw-r--r--src/backend_evdev.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/backend_evdev.c b/src/backend_evdev.c
index d3c12c5..ca0b2e0 100644
--- a/src/backend_evdev.c
+++ b/src/backend_evdev.c
@@ -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) {