From fc3126faf352d467fa213ae97bac73767b44d5de Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Sun, 13 Apr 2008 17:22:14 +0200
Subject: [PATCH] - added --trigger-as-zaxis

---
 TODO        |  4 ----
 uinput.cpp  | 55 +++++++++++++++++++++++++++++++++++------------------
 uinput.hpp  |  2 ++
 xbox360.cpp | 23 +++++++++++++++++++++-
 4 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/TODO b/TODO
index f715e6e..14b9638 100644
--- a/TODO
+++ b/TODO
@@ -28,10 +28,6 @@ New Command Line Options:
   Dpad becomes first and second axis, instead of last, useful for 2D
   jump'n run
 
---dpad-as-buttons
-  Report Dpad motion as regular buttons instead of as axis (conflicts
-  with dpad-first)
-
 --trigger-as-zaxis
   Turn LT,RT into the Z-axis
 
diff --git a/uinput.cpp b/uinput.cpp
index 1843a71..52b5d7c 100644
--- a/uinput.cpp
+++ b/uinput.cpp
@@ -44,16 +44,20 @@ uInput::uInput(GamepadType type, uInputCfg config_)
       ioctl(fd, UI_SET_ABSBIT, ABS_RX);
       ioctl(fd, UI_SET_ABSBIT, ABS_RY);
 
-      if (!config.trigger_as_button)
-        {
-          ioctl(fd, UI_SET_ABSBIT, ABS_GAS);
-          ioctl(fd, UI_SET_ABSBIT, ABS_BRAKE);
-        }
-      else
+      if (config.trigger_as_button)
         {
           ioctl(fd, UI_SET_KEYBIT, BTN_TL2);
           ioctl(fd, UI_SET_KEYBIT, BTN_TR2);
         }
+      else if (config.trigger_as_zaxis)
+        {
+          ioctl(fd, UI_SET_ABSBIT, ABS_Z);
+        }
+      else
+        {
+          ioctl(fd, UI_SET_ABSBIT, ABS_GAS);
+          ioctl(fd, UI_SET_ABSBIT, ABS_BRAKE);
+        }
 
       if (!config.dpad_as_button)
         {
@@ -105,7 +109,12 @@ uInput::uInput(GamepadType type, uInputCfg config_)
       uinp.absmin[ABS_RY] = -32768;
       uinp.absmax[ABS_RY] =  32767;
 
-      if (!config.trigger_as_button)
+      if (config.trigger_as_zaxis)
+        {
+          uinp.absmin[ABS_Z] = -255;
+          uinp.absmax[ABS_Z] =  255;         
+        }
+      else if (!config.trigger_as_button)
         {
           uinp.absmin[ABS_GAS] = 0;
           uinp.absmax[ABS_GAS] = 255;
@@ -113,7 +122,7 @@ uInput::uInput(GamepadType type, uInputCfg config_)
           uinp.absmin[ABS_BRAKE] = 0;
           uinp.absmax[ABS_BRAKE] = 255;
         }
-
+      
       if (!config.dpad_as_button)
         {
           uinp.absmin[ABS_HAT0X] = -1;
@@ -190,17 +199,21 @@ uInput::send(XBox360Msg& msg)
   send_axis(ABS_RX, msg.x2);
   send_axis(ABS_RY, -msg.y2);
 
-  if (!config.trigger_as_button)
+  if (config.trigger_as_zaxis)
+    {
+      send_axis(ABS_Z, (int(msg.rt) - int(msg.lt)));
+    }
+  else if (config.trigger_as_button)
+    {
+      send_button(BTN_TL2, msg.lt);
+      send_button(BTN_TR2, msg.rt);    
+    }
+  else
     {
       send_axis(ABS_BRAKE, msg.lt);
       send_axis(ABS_GAS,   msg.rt);
     }
-  else
-    {
-      send_button(BTN_TL2, msg.lt);
-      send_button(BTN_TR2, msg.rt);
-    }
-
+  
   if (config.dpad_as_button)
     {
       send_button(BTN_BASE,  msg.dpad_up);
@@ -261,16 +274,20 @@ uInput::send(XBoxMsg& msg)
   send_axis(ABS_RX, msg.x2);
   send_axis(ABS_RY, msg.y2);
 
-  if (!config.trigger_as_button)
+  if (config.trigger_as_zaxis)
     {
-      send_axis(ABS_BRAKE, msg.lt);
-      send_axis(ABS_GAS,   msg.rt);
+      send_axis(ABS_Z, (int(msg.rt) - int(msg.lt)));
     }
-  else
+  else if (config.trigger_as_button)
     {
       send_button(BTN_TL2, msg.lt);
       send_button(BTN_TR2, msg.rt);
     }
+  else
+    {
+      send_axis(ABS_BRAKE, msg.lt);
+      send_axis(ABS_GAS,   msg.rt);
+    }
 
   if (config.dpad_as_button)
     {
diff --git a/uinput.hpp b/uinput.hpp
index 9f2c159..453ce65 100644
--- a/uinput.hpp
+++ b/uinput.hpp
@@ -26,10 +26,12 @@ class uInputCfg
 public:
   bool trigger_as_button;
   bool dpad_as_button;
+  bool trigger_as_zaxis;
 
   uInputCfg() {
     trigger_as_button = false;
     dpad_as_button    = false;
+    trigger_as_zaxis  = false;
   }
 };
 
diff --git a/xbox360.cpp b/xbox360.cpp
index 92155ae..4c6027c 100644
--- a/xbox360.cpp
+++ b/xbox360.cpp
@@ -278,6 +278,7 @@ int main(int argc, char** argv)
           std::cout << std::endl;
           std::cout << "Configuration Options: " << std::endl;
           std::cout << "  --trigger-as-button      LT and RT send button instead of axis events" << std::endl;
+          std::cout << "  --trigger-as-zaxis       Combine LT and RT to form a zaxis instead" << std::endl;
           std::cout << "  --dpad-as-button         DPad sends button instead of axis events" << std::endl;
           std::cout << std::endl;
           std::cout << "Report bugs to Ingo Ruhnke <grumbel@gmx.de>" << std::endl;
@@ -347,7 +348,27 @@ int main(int argc, char** argv)
         }
       else if (strcmp("--trigger-as-button", argv[i]) == 0)
         {
-          uinput_config.trigger_as_button = true;
+          if (uinput_config.trigger_as_zaxis)
+            {
+              std::cout << "Error: Can't combine --trigger-as-button and --trigger-as-zaxis" << std::endl;
+              return EXIT_FAILURE;
+            }
+          else
+            {
+              uinput_config.trigger_as_button = true;
+            }
+        }
+      else if (strcmp("--trigger-as-zaxis", argv[i]) == 0)
+        {
+          if (uinput_config.trigger_as_button)
+            {
+              std::cout << "Error: Can't combine --trigger-as-button and --trigger-as-zaxis" << std::endl;
+              return EXIT_FAILURE;
+            }
+          else
+            {
+              uinput_config.trigger_as_zaxis = true;
+            }
         }
       else if (strcmp("--help-led", argv[i]) == 0)
         {