From 27311ed2ce2ab670c83d55e96d35a7f3cffa920d Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Sat, 26 Apr 2008 10:20:09 +0200
Subject: [PATCH] Added JoinAxis and BtnToAbs

---
 SConstruct          |  2 ++
 TODO                |  2 ++
 autofire_button.cpp |  2 +-
 btn_to_abs.cpp      | 68 +++++++++++++++++++++++++++++++++++++++++++++
 btn_to_abs.hpp      | 49 ++++++++++++++++++++++++++++++++
 inputdrv.cpp        | 50 +++++++++++++++++++++++++++++----
 join_axis.cpp       | 56 +++++++++++++++++++++++++++++++++++++
 join_axis.hpp       | 47 +++++++++++++++++++++++++++++++
 8 files changed, 269 insertions(+), 7 deletions(-)
 create mode 100644 btn_to_abs.cpp
 create mode 100644 btn_to_abs.hpp
 create mode 100644 join_axis.cpp
 create mode 100644 join_axis.hpp

diff --git a/SConstruct b/SConstruct
index 573be9c..32c5d9f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -9,8 +9,10 @@ env.Program("inputdrv",
              "control.cpp",
              "abs_to_rel.cpp",
              "abs_to_btn.cpp",
+             "btn_to_abs.cpp",
              "autofire_button.cpp",
              "uinput_driver.cpp",
+             "join_axis.cpp",
              "toggle_button.cpp"],
             LIBS=['boost_signals', 'usb', 'pthread'])
 
diff --git a/TODO b/TODO
index 9829f14..f81949e 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,5 @@
+* Cleanup naming conventions
+
 sending rumble is slow and delayed, gets buffered up
 
 d-feet
diff --git a/autofire_button.cpp b/autofire_button.cpp
index b0e97cf..87ee737 100644
--- a/autofire_button.cpp
+++ b/autofire_button.cpp
@@ -38,7 +38,7 @@ AutofireButton::AutofireButton(int rate)
 void
 AutofireButton::on_btn(BtnPortOut* port)
 {
-  
+  btn_port_out[0]->set_state(port->get_state());
 }
 
 void
diff --git a/btn_to_abs.cpp b/btn_to_abs.cpp
new file mode 100644
index 0000000..0c6c01c
--- /dev/null
+++ b/btn_to_abs.cpp
@@ -0,0 +1,68 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU General Public License
+**  as published by the Free Software Foundation; either version 2
+**  of the License, or (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+** 
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#include <boost/bind.hpp>
+#include "btn_to_abs.hpp"
+
+BtnToAbs::BtnToAbs()
+  : target_value(0)
+{
+  btn_port_in.push_back(new BtnPortIn("BtnToAbs-Out-0",
+                                      boost::bind(&BtnToAbs::on_btn, this, _1)));
+  btn_port_in.push_back(new BtnPortIn("BtnToAbs-Out-1",
+                                      boost::bind(&BtnToAbs::on_btn, this, _1)));
+
+  abs_port_out.push_back(new AbsPortOut("BtnToAbs-In", -32767, 32767));
+}
+
+void
+BtnToAbs::update(float delta)
+{
+  // make this configurable
+  float relax = 0.05f;
+  abs_port_out[0]->set_state(int(abs_port_out[0]->get_state() + 
+                                 relax * (target_value - abs_port_out[0]->get_state())));
+}
+
+void
+BtnToAbs::on_btn(BtnPortOut* port)
+{
+  if (btn_port_in[0]->out_port->get_state() &&
+      !btn_port_in[1]->out_port->get_state())
+    {
+      target_value = abs_port_out[0]->min_value;
+    } 
+  else if (!btn_port_in[0]->out_port->get_state() &&
+           btn_port_in[1]->out_port->get_state())
+    {
+      target_value = abs_port_out[0]->max_value;
+    }
+  else
+    {
+      target_value = 0;
+    }
+}
+
+/* EOF */
diff --git a/btn_to_abs.hpp b/btn_to_abs.hpp
new file mode 100644
index 0000000..3141a4c
--- /dev/null
+++ b/btn_to_abs.hpp
@@ -0,0 +1,49 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU General Public License
+**  as published by the Free Software Foundation; either version 2
+**  of the License, or (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+** 
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#ifndef HEADER_BTN_TO_ABS_HPP
+#define HEADER_BTN_TO_ABS_HPP
+
+#include "control.hpp"
+
+/** */
+class BtnToAbs : public Control
+{
+private:
+  int target_value;
+
+public:
+  BtnToAbs();
+
+  void on_btn(BtnPortOut* port);
+  void update(float delta);
+private:
+  BtnToAbs (const BtnToAbs&);
+  BtnToAbs& operator= (const BtnToAbs&);
+};
+
+#endif
+
+/* EOF */
diff --git a/inputdrv.cpp b/inputdrv.cpp
index 600292d..469f050 100644
--- a/inputdrv.cpp
+++ b/inputdrv.cpp
@@ -31,6 +31,8 @@
 #include "abs_to_rel.hpp"
 #include "toggle_button.hpp"
 #include "autofire_button.hpp"
+#include "join_axis.hpp"
+#include "btn_to_abs.hpp"
 #include "control.hpp"
 #include "inputdrv.hpp"
 
@@ -63,6 +65,10 @@ int main()
   uinput->add_btn(BTN_MIDDLE);
   uinput->add_btn(BTN_Y);
 
+  uinput->add_abs(ABS_X, -32767, 32767);
+  uinput->add_abs(ABS_Y, -32767, 32767);
+  uinput->add_abs(ABS_Z, -255, 255);
+
   uinput->finish();
 
   std::vector<Control*> controls;
@@ -73,7 +79,10 @@ int main()
   AbsToRel*       abs_to_rel_y  = new AbsToRel();
   AbsToRel*       abs_to_rel_x2 = new AbsToRel();
   AbsToRel*       abs_to_rel_y2 = new AbsToRel();
-  AutofireButton* autofire      = new AutofireButton(100);
+  AutofireButton* autofire      = new AutofireButton(50);
+  JoinAxis*       join_axis     = new JoinAxis();
+  BtnToAbs*       btn_to_abs_x  = new BtnToAbs();
+  BtnToAbs*       btn_to_abs_y  = new BtnToAbs();
 
   controls.push_back(xbox360);
   controls.push_back(toggle);
@@ -82,6 +91,9 @@ int main()
   controls.push_back(abs_to_rel_x2);
   controls.push_back(abs_to_rel_y2);
   controls.push_back(autofire);
+  controls.push_back(join_axis);
+  controls.push_back(btn_to_abs_x);
+  controls.push_back(btn_to_abs_y);
 
   // ----------------------------
 
@@ -116,15 +128,41 @@ int main()
   autofire->get_btn_port_out(0)
     ->connect(uinput->get_btn_port_in(3));
   
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT)
+    ->connect(join_axis->get_abs_port_in(0));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
+    ->connect(join_axis->get_abs_port_in(1));
+
+  join_axis->get_abs_port_out(0)
+    ->connect(uinput->get_abs_port_in(2));
+
+
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_DPAD_LEFT)
+    ->connect(btn_to_abs_x->get_btn_port_in(0));
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_DPAD_RIGHT)
+    ->connect(btn_to_abs_x->get_btn_port_in(1));
+  btn_to_abs_x->get_abs_port_out(0)
+    ->connect(uinput->get_abs_port_in(0));
+
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_DPAD_UP)
+    ->connect(btn_to_abs_y->get_btn_port_in(0));
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_DPAD_DOWN)
+    ->connect(btn_to_abs_y->get_btn_port_in(1));  
+  btn_to_abs_y->get_abs_port_out(0)
+    ->connect(uinput->get_abs_port_in(1));
+
   // ----------------------------
 
-  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT) 
-    ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
+  if (0)
+    { // rumble stuff
+      xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT) 
+        ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
 
-  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
-    ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
+      xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
+        ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
 
-  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
+      xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
+    }
 
   bool quit = false;
   while(!quit)
diff --git a/join_axis.cpp b/join_axis.cpp
new file mode 100644
index 0000000..325681d
--- /dev/null
+++ b/join_axis.cpp
@@ -0,0 +1,56 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU General Public License
+**  as published by the Free Software Foundation; either version 2
+**  of the License, or (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+** 
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#include <boost/bind.hpp>
+#include "join_axis.hpp"
+
+JoinAxis::JoinAxis()
+{
+  abs_port_in.push_back(new AbsPortIn("JoinAxis-1", 0, 0, 
+                                      boost::bind(&JoinAxis::on_abs, this, _1)));
+  abs_port_in.push_back(new AbsPortIn("JoinAxis-2", 0, 0, 
+                                      boost::bind(&JoinAxis::on_abs, this, _1)));
+
+  // FIXME: Abs handling must do something proper with the min/max values
+  abs_port_out.push_back(new AbsPortOut("JoinAxis-Out-1", -255, 255));
+}
+
+void
+JoinAxis::on_abs(AbsPortOut* port)
+{
+  int value = 0;
+
+  value -= abs_port_in[0]->out_port->get_state();
+  value += abs_port_in[1]->out_port->get_state();
+  
+  // clamp
+  value = std::max(abs_port_out[0]->min_value, 
+                   std::min(value,
+                            abs_port_out[0]->max_value));
+  
+  abs_port_out[0]->set_state(value);
+}
+
+/* EOF */
diff --git a/join_axis.hpp b/join_axis.hpp
new file mode 100644
index 0000000..b2b49ee
--- /dev/null
+++ b/join_axis.hpp
@@ -0,0 +1,47 @@
+/*  $Id$
+**   __      __ __             ___        __   __ __   __
+**  /  \    /  \__| ____    __| _/_______/  |_|__|  | |  |   ____
+**  \   \/\/   /  |/    \  / __ |/  ___/\   __\  |  | |  | _/ __ \
+**   \        /|  |   |  \/ /_/ |\___ \  |  | |  |  |_|  |_\  ___/
+**    \__/\  / |__|___|  /\____ /____  > |__| |__|____/____/\___  >
+**         \/          \/      \/    \/                         \/
+**  Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
+**
+**  This program is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU General Public License
+**  as published by the Free Software Foundation; either version 2
+**  of the License, or (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+** 
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+**  02111-1307, USA.
+*/
+
+#ifndef HEADER_JOIN_AXIS_HPP
+#define HEADER_JOIN_AXIS_HPP
+
+#include "control.hpp"
+
+/** */
+class JoinAxis : public Control
+{
+private:
+public:
+  JoinAxis();
+
+  void on_abs(AbsPortOut* port);
+  
+private:
+  JoinAxis (const JoinAxis&);
+  JoinAxis& operator= (const JoinAxis&);
+};
+
+#endif
+
+/* EOF */