From 2a75719cc229239ed96c75f53fa8933cebcddb28 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Wed, 26 Jan 2011 16:51:18 +0100
Subject: [PATCH] Fixed some remaining force feedback issues, should be working
 properly again

---
 src/command_line_options.cpp      |  4 ++--
 src/controller_slot_config.cpp    |  4 ++--
 src/default_message_processor.cpp |  1 +
 src/linux_uinput.cpp              |  2 +-
 src/linux_uinput.hpp              |  2 +-
 src/message_processor.hpp         |  3 ++-
 src/options.cpp                   |  3 ++-
 src/options.hpp                   |  2 +-
 src/uinput.cpp                    |  5 ++++
 src/uinput_config.cpp             |  2 --
 src/uinput_options.cpp            |  1 -
 src/uinput_options.hpp            |  2 --
 src/xboxdrv_thread.cpp            | 38 +++----------------------------
 13 files changed, 20 insertions(+), 49 deletions(-)

diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index bb97cd9..d79f4f7 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -329,7 +329,7 @@ CommandLineParser::init_ini(Options* opts)
     ("trigger-as-zaxis",  boost::bind(&Options::set_trigger_as_zaxis, boost::ref(opts)),  boost::function<void ()>())
     ("dpad-as-button",    boost::bind(&Options::set_dpad_as_button, boost::ref(opts)),    boost::function<void ()>())
     ("dpad-only",         boost::bind(&Options::set_dpad_only, boost::ref(opts)),         boost::function<void ()>())
-    ("force-feedback",    boost::bind(&Options::set_force_feedback, boost::ref(opts)),    boost::function<void ()>())
+    ("force-feedback",    boost::bind(&Options::set_force_feedback, boost::ref(opts), _1))
     ("mimic-xpad",        boost::bind(&Options::set_mimic_xpad, boost::ref(opts)),        boost::function<void ()>())
 
     ("chatpad",         &opts->chatpad)
@@ -562,7 +562,7 @@ CommandLineParser::parse_args(int argc, char** argv, Options* options)
         break;
 
       case OPTION_FORCE_FEEDBACK:
-        opts.get_controller_options().uinput.force_feedback = true;
+        opts.get_controller_slot().set_force_feedback(true);
         break;
 
       case OPTION_RUMBLE_GAIN:
diff --git a/src/controller_slot_config.cpp b/src/controller_slot_config.cpp
index 04318ce..9649429 100644
--- a/src/controller_slot_config.cpp
+++ b/src/controller_slot_config.cpp
@@ -71,8 +71,8 @@ ControllerSlotConfig::create(UInput& uinput, int slot, bool extra_devices, const
     // |- FF_SAW_UP
     // |- FF_SAW_DOWN
     // '- FF_CUSTOM
-
-    int ff_device = opts.get_ff_device();
+    
+    uint32_t ff_device = (slot<<16) | opts.get_ff_device();
 
     // basic types
     uinput.add_ff(ff_device, FF_RUMBLE);
diff --git a/src/default_message_processor.cpp b/src/default_message_processor.cpp
index d4314c4..e8d9f51 100644
--- a/src/default_message_processor.cpp
+++ b/src/default_message_processor.cpp
@@ -73,6 +73,7 @@ DefaultMessageProcessor::send(const XboxGenericMsg& msg_in, int msec_delta)
       (*i)->update(msec_delta, msg);
     }
 
+    m_uinput.update(msec_delta);
     m_config->get_config()->get_uinput().update(msec_delta);
 
     // send current Xbox state to uinput
diff --git a/src/linux_uinput.cpp b/src/linux_uinput.cpp
index f3c08b6..dac8453 100644
--- a/src/linux_uinput.cpp
+++ b/src/linux_uinput.cpp
@@ -288,7 +288,7 @@ LinuxUinput::sync()
 }
 
 void
-LinuxUinput::update_force_feedback(int msec_delta)
+LinuxUinput::update(int msec_delta)
 {
   if (ff_bit)
   {
diff --git a/src/linux_uinput.hpp b/src/linux_uinput.hpp
index 5b775e0..2e7ea19 100644
--- a/src/linux_uinput.hpp
+++ b/src/linux_uinput.hpp
@@ -82,7 +82,7 @@ public:
   /** Sends out a sync event if there is a need for it. */
   void sync();
 
-  void update_force_feedback(int msec_delta);
+  void update(int msec_delta);
 
 private:
   LinuxUinput (const LinuxUinput&);
diff --git a/src/message_processor.hpp b/src/message_processor.hpp
index 001ed44..1de0f61 100644
--- a/src/message_processor.hpp
+++ b/src/message_processor.hpp
@@ -30,7 +30,8 @@ public:
   virtual ~MessageProcessor() {}
 
   virtual void send(const XboxGenericMsg& msg, int msec_delta) =0;
-  virtual void set_ff_callback(const boost::function<void (uint8_t, uint8_t)>& callback) =0;
+  virtual void set_ff_callback(const boost::function<void (uint8_t, uint8_t)>& callback
+                               = boost::function<void (uint8_t, uint8_t)>()) =0;
 
 private:
   MessageProcessor(const MessageProcessor&);
diff --git a/src/options.cpp b/src/options.cpp
index 6043daf..b17cc41 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -189,8 +189,9 @@ Options::set_dpad_only()
 }
 
 void
-Options::set_force_feedback()
+Options::set_force_feedback(const std::string& value)
 {
+  get_controller_slot().set_force_feedback(boost::lexical_cast<bool>(value));
 }
 
 void
diff --git a/src/options.hpp b/src/options.hpp
index a1d25dd..12e1bba 100644
--- a/src/options.hpp
+++ b/src/options.hpp
@@ -137,7 +137,7 @@ public:
   void set_trigger_as_zaxis();
   void set_dpad_as_button();
   void set_dpad_only();
-  void set_force_feedback();
+  void set_force_feedback(const std::string& value);
   void set_mimic_xpad();
 
   void add_match(const std::string& lhs, const std::string& rhs);
diff --git a/src/uinput.cpp b/src/uinput.cpp
index 4fb4898..37c78f3 100644
--- a/src/uinput.cpp
+++ b/src/uinput.cpp
@@ -152,6 +152,11 @@ UInput::update(int msec_delta)
       i->second.time_count -= i->second.repeat_interval;
     }
   }
+
+  for(UInputDevs::iterator i = uinput_devs.begin(); i != uinput_devs.end(); ++i)
+  {
+    i->second->update(msec_delta);
+  }
 }
 
 void
diff --git a/src/uinput_config.cpp b/src/uinput_config.cpp
index 4e97add..9fbe042 100644
--- a/src/uinput_config.cpp
+++ b/src/uinput_config.cpp
@@ -255,8 +255,6 @@ UInputConfig::send(Playstation3USBMsg& msg)
 void
 UInputConfig::update(int msec_delta)
 {
-  m_uinput.update(msec_delta);
-
   m_btn_map.update(m_uinput, msec_delta);
   m_axis_map.update(m_uinput, msec_delta);
 
diff --git a/src/uinput_options.cpp b/src/uinput_options.cpp
index 9f00ffb..7c23d09 100644
--- a/src/uinput_options.cpp
+++ b/src/uinput_options.cpp
@@ -23,7 +23,6 @@
 
 UInputOptions::UInputOptions() :
   device_name("Xbox Gamepad (userspace driver)"),
-  force_feedback(false),
   m_btn_map(),
   m_axis_map()
 {
diff --git a/src/uinput_options.hpp b/src/uinput_options.hpp
index 4f6656c..ebaf2ed 100644
--- a/src/uinput_options.hpp
+++ b/src/uinput_options.hpp
@@ -27,8 +27,6 @@ class UInputOptions
 public:
   std::string device_name;
 
-  bool force_feedback;
-
 private:
   ButtonMap m_btn_map;
   AxisMap   m_axis_map;
diff --git a/src/xboxdrv_thread.cpp b/src/xboxdrv_thread.cpp
index 1ed15f2..ca44a59 100644
--- a/src/xboxdrv_thread.cpp
+++ b/src/xboxdrv_thread.cpp
@@ -58,21 +58,6 @@ XboxdrvThread::~XboxdrvThread()
   }
 }
 
-// FIXME: duplicate code
-namespace {
-
-void set_rumble(XboxGenericController* controller, int gain, uint8_t lhs, uint8_t rhs)
-{
-  lhs = std::min(lhs * gain / 255, 255);
-  rhs = std::min(rhs * gain / 255, 255);
-  
-  //std::cout << (int)lhs << " " << (int)rhs << std::endl;
-
-  controller->set_rumble(lhs, rhs);
-}
-
-} // namespace
-
 void
 XboxdrvThread::launch_child_process()
 {
@@ -165,28 +150,11 @@ XboxdrvThread::controller_loop(const Options& opts)
 
       m_processor->send(msg, msec_delta);
 
-#ifdef FIXME                 
       if (opts.rumble)
-      { // FIXME: kind of ugly here, should be a filter, but filters
-        // can't talk back to the controller
-        if (type == GAMEPAD_XBOX)
-        {
-          set_rumble(m_controller.get(), opts.rumble_gain, msg.xbox.lt, msg.xbox.rt);
-        }
-        else if (type == GAMEPAD_XBOX360 ||
-                 type == GAMEPAD_XBOX360_WIRELESS)
-        {
-          set_rumble(m_controller.get(), opts.rumble_gain, msg.xbox360.lt, msg.xbox360.rt);
-        }
-        else if (type == GAMEPAD_FIRESTORM ||
-                 type == GAMEPAD_FIRESTORM_VSB)
-        {
-          set_rumble(m_controller.get(), opts.rumble_gain,
-                     std::min(255, abs((msg.xbox360.y1>>8)*2)), 
-                     std::min(255, abs((msg.xbox360.y2>>8)*2)));
-        }
+      {
+        m_controller->set_rumble(get_axis(msg, XBOX_AXIS_LT), 
+                                 get_axis(msg, XBOX_AXIS_RT));
       }
-#endif
         
       watch_chid_process();
     }