From f2557b3cae33d1b17dcebb7274d743c2bb4b8947 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Fri, 28 Jan 2011 20:23:14 +0100
Subject: [PATCH] Fixed some issues with to_float() and out of bounds
 conditions

---
 NEWS                                    |  3 +++
 src/axisfilter/relative_axis_filter.cpp |  8 ++++----
 src/firestorm_dual_controller.cpp       |  8 ++++----
 src/helper.cpp                          | 14 ++++++++++----
 src/helper.hpp                          |  3 ++-
 src/modifier/axismap_modifier.cpp       |  6 +-----
 src/uinput_config.cpp                   |  9 +++++----
 7 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/NEWS b/NEWS
index 42734c3..da04092 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,10 @@ xboxdrv 0.7.1 - (??/???/2011)
 * new match rule usbserial=SERIAL
 * fixed LED not getting switched off on shutdown
 * man-page update and cleanup
+* added --match-group
 * new version of runxboxdrv
+* fixed axis inversion issue in --axismap
+* fixed assertion in relative axis filter
 
 
 xboxdrv 0.7.0 - (28/Jan/2011)
diff --git a/src/axisfilter/relative_axis_filter.cpp b/src/axisfilter/relative_axis_filter.cpp
index 9a1ff92..67ddd34 100644
--- a/src/axisfilter/relative_axis_filter.cpp
+++ b/src/axisfilter/relative_axis_filter.cpp
@@ -22,7 +22,7 @@
 #include <boost/lexical_cast.hpp>
 
 #include "helper.hpp"
-
+
 RelativeAxisFilter*
 RelativeAxisFilter::from_string(const std::string& str)
 {
@@ -42,7 +42,7 @@ RelativeAxisFilter::from_string(const std::string& str)
 
   return new RelativeAxisFilter(speed);
 }
-
+
 RelativeAxisFilter::RelativeAxisFilter(int speed) :
   m_speed(speed),
   m_float_speed(0.0f),
@@ -63,7 +63,7 @@ RelativeAxisFilter::filter(int value, int min, int max)
 {
   m_value = to_float(value, min, max);
 
-  m_float_speed = to_float(m_speed, min, max);
+  m_float_speed = to_float_no_range_check(m_speed, min, max);
 
   return from_float(m_state, min, max);
 }
@@ -75,5 +75,5 @@ RelativeAxisFilter::str() const
   out << "relativeaxis:" << m_speed;
   return out.str();
 }
-
+
 /* EOF */
diff --git a/src/firestorm_dual_controller.cpp b/src/firestorm_dual_controller.cpp
index 5035aed..dbe9b8d 100644
--- a/src/firestorm_dual_controller.cpp
+++ b/src/firestorm_dual_controller.cpp
@@ -207,8 +207,8 @@ FirestormDualController::read_vsb(XboxGenericMsg& msg, int timeout)
     msg.xbox360.y2 = scale_8to16(data.y2 - 128);
 
     // Invert the axis
-    msg.xbox360.y1 = negate_16(msg.xbox360.y1);
-    msg.xbox360.y2 = negate_16(msg.xbox360.y2);
+    msg.xbox360.y1 = s16_invert(msg.xbox360.y1);
+    msg.xbox360.y2 = s16_invert(msg.xbox360.y2);
 
     // data.dpad == 0xf0 -> dpad centered
     // data.dpad == 0xe0 -> dpad-only mode is enabled
@@ -281,8 +281,8 @@ FirestormDualController::read_default(XboxGenericMsg& msg, int timeout)
     msg.xbox360.y2 = scale_8to16(data.y2 - 128);
 
     // Invert the axis
-    msg.xbox360.y1 = negate_16(msg.xbox360.y1);
-    msg.xbox360.y2 = negate_16(msg.xbox360.y2);
+    msg.xbox360.y1 = s16_invert(msg.xbox360.y1);
+    msg.xbox360.y2 = s16_invert(msg.xbox360.y2);
 
     // data.dpad == 0xf0 -> dpad centered
     // data.dpad == 0xe0 -> dpad-only mode is enabled
diff --git a/src/helper.cpp b/src/helper.cpp
index 36e1c94..c4f17de 100644
--- a/src/helper.cpp
+++ b/src/helper.cpp
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
+#include <iostream>
 
 #include "raise_exception.hpp"
 
@@ -132,11 +133,8 @@ uint32_t get_time()
   return tv.tv_sec * 1000 + tv.tv_usec/1000;
 }
 
-float to_float(int value, int min, int max)
+float to_float_no_range_check(int value, int min, int max)
 {
-  assert(value >= min);
-  assert(value <= max);
-
   // FIXME: '+1' is kind of a hack to
   // get the center at 0 for the
   // [-32768, 32767] case
@@ -152,6 +150,14 @@ float to_float(int value, int min, int max)
   }
 }
 
+float to_float(int value, int min, int max)
+{
+  assert(value >= min);
+  assert(value <= max);
+
+  return to_float_no_range_check(value, min, max);
+}
+
 int from_float(float value, int min, int max)
 {
   return (value + 1.0f) / 2.0f * static_cast<float>(max - min) + min;
diff --git a/src/helper.hpp b/src/helper.hpp
index a6192a3..237ba04 100644
--- a/src/helper.hpp
+++ b/src/helper.hpp
@@ -49,7 +49,7 @@ T clamp (const T& low, const T& v, const T& high)
 } // namespace Math
 
 // Change the sign
-inline int16_t negate_16(int16_t v)
+inline int16_t s16_invert(int16_t v)
 {
   if (v)
     return static_cast<int16_t>(~v);
@@ -67,6 +67,7 @@ inline int16_t scale_8to16(int8_t a)
 
 /** converts the arbitary range to [-1,1] */
 float to_float(int value, int min, int max);
+float to_float_no_range_check(int value, int min, int max);
 
 /** converts the range [-1,1] to [min,max] */
 int from_float(float value, int min, int max);
diff --git a/src/modifier/axismap_modifier.cpp b/src/modifier/axismap_modifier.cpp
index 64ba01a..abd68d3 100644
--- a/src/modifier/axismap_modifier.cpp
+++ b/src/modifier/axismap_modifier.cpp
@@ -21,11 +21,7 @@
 #include <boost/tokenizer.hpp>
 #include <sstream>
 
-/** converts the arbitary range to [-1,1] */
-inline float to_float(int value, int min, int max)
-{
-  return static_cast<float>(value - min) / static_cast<float>(max - min) * 2.0f - 1.0f;
-}
+#include "helper.hpp"
 
 AxisMapping
 AxisMapping::from_string(const std::string& lhs_, const std::string& rhs)
diff --git a/src/uinput_config.cpp b/src/uinput_config.cpp
index 7804b38..02c5716 100644
--- a/src/uinput_config.cpp
+++ b/src/uinput_config.cpp
@@ -18,6 +18,7 @@
 
 #include "uinput_config.hpp"
 
+#include "helper.hpp"
 #include "uinput.hpp"
 #include "uinput_options.hpp"
 
@@ -116,10 +117,10 @@ UInputConfig::send(Xbox360Msg& msg)
 
   // analog sticks
   send_axis(XBOX_AXIS_X1,  msg.x1);
-  send_axis(XBOX_AXIS_Y1, ~msg.y1);
+  send_axis(XBOX_AXIS_Y1,  s16_invert(msg.y1));
   
   send_axis(XBOX_AXIS_X2,  msg.x2);
-  send_axis(XBOX_AXIS_Y2, ~msg.y2);
+  send_axis(XBOX_AXIS_Y2,  s16_invert(msg.y2));
 
   // dpad
   if      (msg.dpad_up)    send_axis(XBOX_AXIS_DPAD_Y, -1);
@@ -168,10 +169,10 @@ UInputConfig::send(XboxMsg& msg)
 
   // analog sticks
   send_axis(XBOX_AXIS_X1,  msg.x1);
-  send_axis(XBOX_AXIS_Y1, ~msg.y1);
+  send_axis(XBOX_AXIS_Y1,  s16_invert(msg.y1));
 
   send_axis(XBOX_AXIS_X2,  msg.x2);
-  send_axis(XBOX_AXIS_Y2, ~msg.y2);
+  send_axis(XBOX_AXIS_Y2,  s16_invert(msg.y2));
 
   // dpad as axis
   if      (msg.dpad_up)    send_axis(XBOX_AXIS_DPAD_Y, -1);