Separate JoystickConfig out into a separate class that can be stored in the global...
authorIngo Ruhnke <grumbel@gmail.com>
Mon, 18 Aug 2014 02:50:10 +0000 (04:50 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Mon, 18 Aug 2014 02:53:36 +0000 (04:53 +0200)
This should fix joystick/keyboard load/save support which broke in one of the last few commits

src/control/input_manager.cpp
src/control/input_manager.hpp
src/control/joystick_config.cpp [new file with mode: 0644]
src/control/joystick_config.hpp [new file with mode: 0644]
src/control/joystick_manager.cpp
src/control/joystick_manager.hpp
src/supertux/gameconfig.cpp
src/supertux/gameconfig.hpp
src/supertux/main.cpp
src/supertux/menu/joystick_menu.cpp

index 6c7b12c..ce612d4 100644 (file)
 #include "util/log.hpp"
 #include "util/writer.hpp"
 
-InputManager::InputManager(KeyboardConfig& keyboard_config) :
+InputManager::InputManager(KeyboardConfig& keyboard_config,
+                           JoystickConfig& joystick_config) :
   controller(new Controller),
   m_use_game_controller(true),
   keyboard_manager(new KeyboardManager(this, keyboard_config)),
-  joystick_manager(new JoystickManager(this)),
+  joystick_manager(new JoystickManager(this, joystick_config)),
   game_controller_manager(new GameControllerManager(this))
 {
 }
@@ -55,38 +56,6 @@ InputManager::use_game_controller(bool v)
 }
 
 void
-InputManager::read(const Reader& lisp)
-{
-#ifdef GRUMBEL
-  const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
-  if (keymap_lisp)
-  {
-    keyboard_manager->read(keymap_lisp);
-  }
-
-  const lisp::Lisp* joystick_lisp = lisp.get_lisp(_("joystick"));
-  if (joystick_lisp)
-  {
-    joystick_manager->read(joystick_lisp);
-  }
-#endif
-}
-
-void
-InputManager::write(Writer& writer)
-{
-#ifdef GRUMBEL
-  writer.start_list("keymap");
-  keyboard_manager->write(writer);
-  writer.end_list("keymap");
-
-  writer.start_list("joystick");
-  joystick_manager->write(writer);
-  writer.end_list("joystick");
-#endif
-}
-
-void
 InputManager::update()
 {
   controller->update();
index 50e1de6..d047e53 100644 (file)
@@ -37,6 +37,7 @@ class KeyboardManager;
 class KeyboardMenu;
 class Menu;
 class KeyboardConfig;
+class JoystickConfig;
 
 class InputManager final : public Currenton<InputManager>
 {
@@ -47,13 +48,12 @@ private:
   typedef Controller::Control Control;
 
 public:
-  InputManager(KeyboardConfig& keyboard_config);
+  InputManager(KeyboardConfig& keyboard_config,
+               JoystickConfig& joystick_config);
   virtual ~InputManager();
 
   void process_event(const SDL_Event& event);
 
-  void write(Writer& writer);
-  void read(const Reader& lisp);
   void update();
   void reset();
 
diff --git a/src/control/joystick_config.cpp b/src/control/joystick_config.cpp
new file mode 100644 (file)
index 0000000..e155cf1
--- /dev/null
@@ -0,0 +1,243 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "control/joystick_config.hpp"
+
+#include <iostream>
+
+#include "lisp/list_iterator.hpp"
+#include "util/gettext.hpp"
+#include "util/log.hpp"
+
+JoystickConfig::JoystickConfig() :
+  dead_zone(8000),
+  jump_with_up_joy(false),
+  joy_button_map(),
+  joy_axis_map(),
+  joy_hat_map()
+{
+  // Default joystick button configuration
+  bind_joybutton(0, 0, Controller::JUMP);
+  bind_joybutton(0, 0, Controller::MENU_SELECT);
+  bind_joybutton(0, 1, Controller::ACTION);
+  bind_joybutton(0, 4, Controller::PEEK_LEFT);
+  bind_joybutton(0, 5, Controller::PEEK_RIGHT);
+  bind_joybutton(0, 6, Controller::PAUSE_MENU);
+
+  // Default joystick axis configuration
+  bind_joyaxis(0, -1, Controller::LEFT);
+  bind_joyaxis(0, 1, Controller::RIGHT);
+  bind_joyaxis(0, -2, Controller::UP);
+  bind_joyaxis(0, 2, Controller::DOWN);
+}
+
+int
+JoystickConfig::reversemap_joyaxis(Controller::Control c)
+{
+  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
+    if (i->second == c)
+      return i->first.second;
+  }
+
+  return 0;
+}
+
+int
+JoystickConfig::reversemap_joybutton(Controller::Control c)
+{
+  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
+    if (i->second == c)
+      return i->first.second;
+  }
+
+  return -1;
+}
+
+int
+JoystickConfig::reversemap_joyhat(Controller::Control c)
+{
+  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
+    if (i->second == c)
+      return i->first.second;
+  }
+
+  return -1;
+}
+
+void
+JoystickConfig::print_joystick_mappings()
+{
+  std::cout << _("Joystick Mappings") << std::endl;
+  std::cout << "-----------------" << std::endl;
+  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
+    std::cout << "Axis: " << i->first.second << " -> " << i->second << std::endl;
+  }
+
+  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
+    std::cout << "Button: " << i->first.second << " -> " << i->second << std::endl;
+  }
+
+  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
+    std::cout << "Hat: " << i->first.second << " -> " << i->second << std::endl;
+  }
+  std::cout << std::endl;
+}
+
+void
+JoystickConfig::unbind_joystick_control(Controller::Control control)
+{
+  // remove all previous mappings for that control
+  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
+    if (i->second == control)
+      joy_axis_map.erase(i++);
+    else
+      ++i;
+  }
+
+  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
+    if (i->second == control)
+      joy_button_map.erase(i++);
+    else
+      ++i;
+  }
+
+  for(HatMap::iterator i = joy_hat_map.begin();  i != joy_hat_map.end(); /* no ++i */) {
+    if (i->second == control)
+      joy_hat_map.erase(i++);
+    else
+      ++i;
+  }
+}
+
+void
+JoystickConfig::bind_joyaxis(JoyId joy_id, int axis, Controller::Control control)
+{
+  // axis isn't the SDL axis number, but axisnumber + 1 with sign
+  // changed depending on if the positive or negative end is to be
+  // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
+  // etc.)
+
+  unbind_joystick_control(control);
+
+  // add new mapping
+  joy_axis_map[std::make_pair(joy_id, axis)] = control;
+}
+
+void
+JoystickConfig::bind_joyhat(JoyId joy_id, int dir, Controller::Control c)
+{
+  unbind_joystick_control(c);
+
+  // add new mapping
+  joy_hat_map[std::make_pair(joy_id, dir)] = c;
+}
+
+void
+JoystickConfig::bind_joybutton(JoyId joy_id, int button, Controller::Control control)
+{
+  unbind_joystick_control(control);
+
+  // add new mapping
+  joy_button_map[std::make_pair(joy_id, button)] = control;
+}
+
+void
+JoystickConfig::read(const lisp::Lisp* joystick_lisp)
+{
+  joystick_lisp->get("dead-zone", dead_zone);
+  joystick_lisp->get("jump-with-up", jump_with_up_joy);
+
+  lisp::ListIterator iter(joystick_lisp);
+  while(iter.next())
+  {
+    if (iter.item() == "map")
+    {
+      int button = -1;
+      int axis   = 0;
+      int hat    = -1;
+      std::string control;
+      const lisp::Lisp* map = iter.lisp();
+
+      map->get("control", control);
+      int i = 0;
+      for(i = 0; Controller::controlNames[i] != 0; ++i)
+      {
+        if (control == Controller::controlNames[i])
+          break;
+      }
+
+      if (Controller::controlNames[i] == 0)
+      {
+        log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
+      }
+      else
+      {
+        if (map->get("button", button))
+        {
+          bind_joybutton(0, button, Controller::Control(i));
+        }
+        else if (map->get("axis",   axis))
+        {
+          bind_joyaxis(0, axis, Controller::Control(i));
+        }
+        else if (map->get("hat",   hat))
+        {
+          if (hat != SDL_HAT_UP   &&
+              hat != SDL_HAT_DOWN &&
+              hat != SDL_HAT_LEFT &&
+              hat != SDL_HAT_RIGHT) {
+            log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
+          }
+          else
+          {
+            bind_joyhat(0, hat, Controller::Control(i));
+          }
+        }
+      }
+    }
+  }
+}
+
+void
+JoystickConfig::write(Writer& writer)
+{
+  writer.write("dead-zone", dead_zone);
+  writer.write("jump-with-up", jump_with_up_joy);
+
+  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
+      ++i) {
+    writer.start_list("map");
+    writer.write("button", i->first.second);
+    writer.write("control", Controller::controlNames[i->second]);
+    writer.end_list("map");
+  }
+
+  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
+    writer.start_list("map");
+    writer.write("hat", i->first.second);
+    writer.write("control", Controller::controlNames[i->second]);
+    writer.end_list("map");
+  }
+
+  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
+    writer.start_list("map");
+    writer.write("axis", i->first.second);
+    writer.write("control", Controller::controlNames[i->second]);
+    writer.end_list("map");
+  }
+}
+
+/* EOF */
diff --git a/src/control/joystick_config.hpp b/src/control/joystick_config.hpp
new file mode 100644 (file)
index 0000000..80aa275
--- /dev/null
@@ -0,0 +1,68 @@
+//  SuperTux
+//  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+//  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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_CONTROL_JOYSTICK_CONFIG_HPP
+#define HEADER_SUPERTUX_CONTROL_JOYSTICK_CONFIG_HPP
+
+#include <map>
+#include <SDL.h>
+
+#include "control/controller.hpp"
+#include "lisp/lisp.hpp"
+#include "util/writer.hpp"
+
+class JoystickConfig
+{
+public:
+  typedef Uint8 JoyId;
+  typedef std::map<std::pair<JoyId, int>, Controller::Control> ButtonMap;
+  typedef std::map<std::pair<JoyId, int>, Controller::Control> AxisMap;
+  typedef std::map<std::pair<JoyId, int>, Controller::Control> HatMap;
+
+public:
+  int dead_zone;
+  bool jump_with_up_joy;
+
+  ButtonMap joy_button_map;
+  AxisMap joy_axis_map;
+  HatMap joy_hat_map;
+
+public:
+  JoystickConfig();
+
+  void print_joystick_mappings();
+
+  int reversemap_joybutton(Controller::Control c);
+  int reversemap_joyaxis(Controller::Control c);
+  int reversemap_joyhat(Controller::Control c);
+
+  void unbind_joystick_control(Controller::Control c);
+
+  void bind_joybutton(JoyId joy_id, int button, Controller::Control c);
+  void bind_joyaxis(JoyId joy_id, int axis, Controller::Control c);
+  void bind_joyhat(JoyId joy_id, int dir, Controller::Control c);
+
+  void read(const lisp::Lisp* joystick_lisp);
+  void write(Writer& writer);
+
+private:
+  JoystickConfig(const JoystickConfig&) = delete;
+  JoystickConfig& operator=(const JoystickConfig&) = delete;
+};
+
+#endif
+
+/* EOF */
index 5043b60..ebc164c 100644 (file)
 #include <iostream>
 #include <algorithm>
 
-#include "gui/menu_manager.hpp"
 #include "control/input_manager.hpp"
+#include "control/joystick_config.hpp"
+#include "gui/menu_manager.hpp"
 #include "lisp/list_iterator.hpp"
 #include "supertux/menu/joystick_menu.hpp"
 #include "util/gettext.hpp"
 #include "util/log.hpp"
 #include "util/writer.hpp"
 
-JoystickManager::JoystickManager(InputManager* parent_) :
+JoystickManager::JoystickManager(InputManager* parent_,
+                                 JoystickConfig& joystick_config) :
   parent(parent_),
-  joy_button_map(),
-  joy_axis_map(),
-  joy_hat_map(),
-  dead_zone(8000),
+  m_joystick_config(joystick_config),
   min_joybuttons(),
   max_joybuttons(),
   max_joyaxis(),
   max_joyhats(),
   hat_state(0),
-  jump_with_up_joy(false),
   wait_for_joystick(-1),
   joysticks()
 {
-  // Default joystick button configuration
-  bind_joybutton(0, 0, Controller::JUMP);
-  bind_joybutton(0, 1, Controller::ACTION);
-  // 6 or more Buttons
-  if( min_joybuttons > 5 ){
-    bind_joybutton(0, 4, Controller::PEEK_LEFT);
-    bind_joybutton(0, 5, Controller::PEEK_RIGHT);
-    // 8 or more
-    if(min_joybuttons > 7)
-      bind_joybutton(0, min_joybuttons-1, Controller::PAUSE_MENU);
-  } else {
-    // map the last 2 buttons to menu and pause
-    if(min_joybuttons > 2)
-      bind_joybutton(0, min_joybuttons-1, Controller::PAUSE_MENU);
-    // map all remaining joystick buttons to MENU_SELECT
-    for(int i = 2; i < max_joybuttons; ++i) {
-      if(i != min_joybuttons-1)
-        bind_joybutton(0, i, Controller::MENU_SELECT);
-    }
-  }
-
-  // Default joystick axis configuration
-  bind_joyaxis(0, -1, Controller::LEFT);
-  bind_joyaxis(0, 1, Controller::RIGHT);
-  bind_joyaxis(0, -2, Controller::UP);
-  bind_joyaxis(0, 2, Controller::DOWN);
 }
 
 JoystickManager::~JoystickManager()
@@ -132,16 +104,16 @@ JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat)
   if (wait_for_joystick >= 0)
   {
     if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
-      bind_joyhat(jhat.which, SDL_HAT_UP, Controller::Control(wait_for_joystick));
+      m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_UP, Controller::Control(wait_for_joystick));
 
     if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
-      bind_joyhat(jhat.which, SDL_HAT_DOWN, Controller::Control(wait_for_joystick));
+      m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_DOWN, Controller::Control(wait_for_joystick));
 
     if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
-      bind_joyhat(jhat.which, SDL_HAT_LEFT, Controller::Control(wait_for_joystick));
+      m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_LEFT, Controller::Control(wait_for_joystick));
 
     if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
-      bind_joyhat(jhat.which, SDL_HAT_RIGHT, Controller::Control(wait_for_joystick));
+      m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_RIGHT, Controller::Control(wait_for_joystick));
 
     MenuManager::instance().refresh();
     wait_for_joystick = -1;
@@ -150,29 +122,29 @@ JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat)
   {
     if (changed & SDL_HAT_UP)
     {
-      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP));
-      if (it != joy_hat_map.end())
+      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP));
+      if (it != m_joystick_config.joy_hat_map.end())
         set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
     }
 
     if (changed & SDL_HAT_DOWN)
     {
-      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN));
-      if (it != joy_hat_map.end())
+      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN));
+      if (it != m_joystick_config.joy_hat_map.end())
         set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
     }
 
     if (changed & SDL_HAT_LEFT)
     {
-      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT));
-      if (it != joy_hat_map.end())
+      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT));
+      if (it != m_joystick_config.joy_hat_map.end())
         set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
     }
 
     if (changed & SDL_HAT_RIGHT)
     {
-      HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT));
-      if (it != joy_hat_map.end())
+      JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT));
+      if (it != m_joystick_config.joy_hat_map.end())
         set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
     }
   }
@@ -185,11 +157,11 @@ JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis)
 {
   if (wait_for_joystick >= 0)
   {
-    if (abs(jaxis.value) > dead_zone) {
+    if (abs(jaxis.value) > m_joystick_config.dead_zone) {
       if (jaxis.value < 0)
-        bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Controller::Control(wait_for_joystick));
+        m_joystick_config.bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Controller::Control(wait_for_joystick));
       else
-        bind_joyaxis(jaxis.which, jaxis.axis + 1, Controller::Control(wait_for_joystick));
+        m_joystick_config.bind_joyaxis(jaxis.which, jaxis.axis + 1, Controller::Control(wait_for_joystick));
 
       MenuManager::instance().refresh();
       wait_for_joystick = -1;
@@ -201,22 +173,22 @@ JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis)
     // mapped separately (needed for jump/down vs up/down)
     int axis = jaxis.axis + 1;
 
-    AxisMap::iterator left  = joy_axis_map.find(std::make_pair(jaxis.which, -axis));
-    AxisMap::iterator right = joy_axis_map.find(std::make_pair(jaxis.which, axis));
+    auto left = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, -axis));
+    auto right = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, axis));
 
-    if(left == joy_axis_map.end()) {
+    if(left == m_joystick_config.joy_axis_map.end()) {
       // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
     } else {
-      if (jaxis.value < -dead_zone)
+      if (jaxis.value < -m_joystick_config.dead_zone)
         set_joy_controls(left->second,  true);
       else
         set_joy_controls(left->second, false);
     }
 
-    if(right == joy_axis_map.end()) {
+    if(right == m_joystick_config.joy_axis_map.end()) {
       // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
     } else {
-      if (jaxis.value > dead_zone)
+      if (jaxis.value > m_joystick_config.dead_zone)
         set_joy_controls(right->second, true);
       else
         set_joy_controls(right->second, false);
@@ -231,7 +203,7 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
   {
     if(jbutton.state == SDL_PRESSED)
     {
-      bind_joybutton(jbutton.which, jbutton.button, (Controller::Control)wait_for_joystick);
+      m_joystick_config.bind_joybutton(jbutton.which, jbutton.button, (Controller::Control)wait_for_joystick);
       MenuManager::instance().refresh();
       parent->reset();
       wait_for_joystick = -1;
@@ -239,8 +211,8 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
   }
   else
   {
-    ButtonMap::iterator i = joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
-    if(i == joy_button_map.end()) {
+    auto i = m_joystick_config.joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
+    if(i == m_joystick_config.joy_button_map.end()) {
       log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
     } else {
       set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
@@ -248,209 +220,11 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
   }
 }
 
-
-int
-JoystickManager::reversemap_joyaxis(Controller::Control c)
-{
-  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
-    if(i->second == c)
-      return i->first.second;
-  }
-
-  return 0;
-}
-
-int
-JoystickManager::reversemap_joybutton(Controller::Control c)
-{
-  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
-    if(i->second == c)
-      return i->first.second;
-  }
-
-  return -1;
-}
-
-int
-JoystickManager::reversemap_joyhat(Controller::Control c)
-{
-  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
-    if(i->second == c)
-      return i->first.second;
-  }
-
-  return -1;
-}
-
-void
-JoystickManager::print_joystick_mappings()
-{
-  std::cout << _("Joystick Mappings") << std::endl;
-  std::cout << "-----------------" << std::endl;
-  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
-    std::cout << "Axis: " << i->first.second << " -> " << i->second << std::endl;
-  }
-
-  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
-    std::cout << "Button: " << i->first.second << " -> " << i->second << std::endl;
-  }
-
-  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
-    std::cout << "Hat: " << i->first.second << " -> " << i->second << std::endl;
-  }
-  std::cout << std::endl;
-}
-
-void
-JoystickManager::unbind_joystick_control(Controller::Control control)
-{
-  // remove all previous mappings for that control
-  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
-    if(i->second == control)
-      joy_axis_map.erase(i++);
-    else
-      ++i;
-  }
-
-  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
-    if(i->second == control)
-      joy_button_map.erase(i++);
-    else
-      ++i;
-  }
-
-  for(HatMap::iterator i = joy_hat_map.begin();  i != joy_hat_map.end(); /* no ++i */) {
-    if(i->second == control)
-      joy_hat_map.erase(i++);
-    else
-      ++i;
-  }
-}
-
-void
-JoystickManager::bind_joyaxis(JoyId joy_id, int axis, Controller::Control control)
-{
-  // axis isn't the SDL axis number, but axisnumber + 1 with sign
-  // changed depending on if the positive or negative end is to be
-  // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
-  // etc.)
-
-  unbind_joystick_control(control);
-
-  // add new mapping
-  joy_axis_map[std::make_pair(joy_id, axis)] = control;
-}
-
-void
-JoystickManager::bind_joyhat(JoyId joy_id, int dir, Controller::Control c)
-{
-  unbind_joystick_control(c);
-
-  // add new mapping
-  joy_hat_map[std::make_pair(joy_id, dir)] = c;
-}
-
-void
-JoystickManager::bind_joybutton(JoyId joy_id, int button, Controller::Control control)
-{
-  unbind_joystick_control(control);
-
-  // add new mapping
-  joy_button_map[std::make_pair(joy_id, button)] = control;
-}
-
-void
-JoystickManager::read(const lisp::Lisp* joystick_lisp)
-{
-  joystick_lisp->get("dead-zone", dead_zone);
-  joystick_lisp->get("jump-with-up", jump_with_up_joy);
-  lisp::ListIterator iter(joystick_lisp);
-  while(iter.next()) {
-    if(iter.item() == _("map")) {
-      int button = -1;
-      int axis   = 0;
-      int hat    = -1;
-      std::string control;
-      const lisp::Lisp* map = iter.lisp();
-
-      map->get("control", control);
-      int i = 0;
-      for(i = 0; Controller::controlNames[i] != 0; ++i) {
-        if(control == Controller::controlNames[i])
-          break;
-      }
-      if(Controller::controlNames[i] == 0) {
-        log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
-        continue;
-      }
-
-      bool js_available = joysticks.size() > 0;
-
-      if (map->get("button", button)) {
-        if(js_available && (button < 0 || button >= max_joybuttons)) {
-          log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
-          continue;
-        }
-        bind_joybutton(0, button, Controller::Control(i));
-      }
-
-      if (map->get("axis",   axis)) {
-        if (js_available && (axis == 0 || abs(axis) > max_joyaxis)) {
-          log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
-          continue;
-        }
-        bind_joyaxis(0, axis, Controller::Control(i));
-      }
-
-      if (map->get("hat",   hat)) {
-        if (js_available        &&
-            hat != SDL_HAT_UP   &&
-            hat != SDL_HAT_DOWN &&
-            hat != SDL_HAT_LEFT &&
-            hat != SDL_HAT_RIGHT) {
-          log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
-          continue;
-        } else {
-          bind_joyhat(0, hat, Controller::Control(i));
-        }
-      }
-    }
-  }
-}
-
-void
-JoystickManager::write(Writer& writer)
-{
-  writer.write("dead-zone", dead_zone);
-  writer.write("jump-with-up", jump_with_up_joy);
-
-  for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
-      ++i) {
-    writer.start_list("map");
-    writer.write("button", i->first.second);
-    writer.write("control", Controller::controlNames[i->second]);
-    writer.end_list("map");
-  }
-
-  for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
-    writer.start_list("map");
-    writer.write("hat", i->first.second);
-    writer.write("control", Controller::controlNames[i->second]);
-    writer.end_list("map");
-  }
-
-  for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
-    writer.start_list("map");
-    writer.write("axis", i->first.second);
-    writer.write("control", Controller::controlNames[i->second]);
-    writer.end_list("map");
-  }
-}
-
 void
 JoystickManager::set_joy_controls(Controller::Control id, bool value)
 {
-  if (jump_with_up_joy && id == Controller::UP)
+  if (m_joystick_config.jump_with_up_joy && 
+      id == Controller::UP)
   {
     parent->get_controller()->set_control(Controller::JUMP, value);
   }
index 94acba0..898868e 100644 (file)
 #include "util/writer_fwd.hpp"
 
 class InputManager;
+class JoystickConfig;
 
 class JoystickManager final
 {
 private:
-  typedef Uint8 JoyId;
-
-  typedef std::map<std::pair<JoyId, int>, Controller::Control> ButtonMap;
-  typedef std::map<std::pair<JoyId, int>, Controller::Control> AxisMap;
-  typedef std::map<std::pair<JoyId, int>, Controller::Control> HatMap;
-
-private:
   InputManager* parent;
-
-  ButtonMap joy_button_map;
-  AxisMap joy_axis_map;
-  HatMap joy_hat_map;
-
-  int dead_zone;
+  JoystickConfig& m_joystick_config;
 
   /// the number of buttons all joysticks have
   int min_joybuttons;
@@ -59,42 +48,24 @@ private:
   Uint8 hat_state;
 
 public:
-  bool jump_with_up_joy;
-
-public:
   int wait_for_joystick;
 
 public:
   std::vector<SDL_Joystick*> joysticks;
 
 public:
-  JoystickManager(InputManager* parent);
+  JoystickManager(InputManager* parent, JoystickConfig& joystick_config);
   ~JoystickManager();
 
   void process_hat_event(const SDL_JoyHatEvent& jhat);
   void process_axis_event(const SDL_JoyAxisEvent& jaxis);
   void process_button_event(const SDL_JoyButtonEvent& jbutton);
 
-  void print_joystick_mappings();
-
-  int reversemap_joybutton(Controller::Control c);
-  int reversemap_joyaxis(Controller::Control c);
-  int reversemap_joyhat(Controller::Control c);
-
-  void unbind_joystick_control(Controller::Control c);
-
-  void bind_joybutton(JoyId joy_id, int button, Controller::Control c);
-  void bind_joyaxis(JoyId joy_id, int axis, Controller::Control c);
-  void bind_joyhat(JoyId joy_id, int dir, Controller::Control c);
-
   void set_joy_controls(Controller::Control id, bool value);
 
   void on_joystick_added(int joystick_index);
   void on_joystick_removed(int instance_id);
 
-  void read(const lisp::Lisp* joystick_lisp);
-  void write(Writer& writer);
-
 private:
   JoystickManager(const JoystickManager&) = delete;
   JoystickManager& operator=(const JoystickManager&) = delete;
index bc6193b..5dcb1c7 100644 (file)
@@ -45,7 +45,8 @@ Config::Config() :
   start_demo(),
   record_demo(),
   locale(),
-  keyboard_config()
+  keyboard_config(),
+  joystick_config()
 {
 }
 
@@ -101,7 +102,17 @@ Config::load()
   const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
   if (config_control_lisp)
   {
-    keyboard_config.read(*config_control_lisp);
+    const lisp::Lisp* keymap_lisp = config_control_lisp->get_lisp("keymap");
+    if (keymap_lisp)
+    {
+      keyboard_config.read(*config_control_lisp);
+    }
+
+    const lisp::Lisp* joystick_lisp = config_control_lisp->get_lisp("joystick");
+    if (joystick_lisp)
+    {
+      joystick_config.read(joystick_lisp);
+    }
   }
 
   const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons");
@@ -148,7 +159,15 @@ Config::save()
   writer.end_list("audio");
 
   writer.start_list("control");
-  keyboard_config.write(writer);
+  {
+    writer.start_list("keymap");
+    keyboard_config.write(writer);
+    writer.end_list("keymap");
+
+    writer.start_list("joystick");
+    joystick_config.write(writer);
+    writer.end_list("joystick");
+  }
   writer.end_list("control");
 
   if (AddonManager::current())
index 298a221..0bcbf88 100644 (file)
 #ifndef HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP
 #define HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP
 
-#include "video/video_system.hpp"
+#include "control/joystick_config.hpp"
 #include "control/keyboard_config.hpp"
 #include "math/size.hpp"
+#include "video/video_system.hpp"
 
 class Config
 {
@@ -69,6 +70,7 @@ public:
   std::string locale;
 
   KeyboardConfig keyboard_config;
+  JoystickConfig joystick_config;
 };
 
 #endif
index 03f5b78..0e3e32b 100644 (file)
@@ -283,7 +283,7 @@ Main::launch_game()
   ConsoleBuffer console_buffer;
 
   timelog("controller");
-  InputManager input_manager(g_config->keyboard_config);
+  InputManager input_manager(g_config->keyboard_config, g_config->joystick_config);
 
   timelog("commandline");
 
index 48678fa..96f8c70 100644 (file)
@@ -20,6 +20,7 @@
 #include <sstream>
 
 #include "control/joystick_manager.hpp"
+#include "supertux/gameconfig.hpp"
 #include "util/gettext.hpp"
 
 namespace {
@@ -75,7 +76,7 @@ JoystickMenu::recreate_menu()
       add_controlfield(Controller::PEEK_UP,     _("Peek Up"));
       add_controlfield(Controller::PEEK_DOWN,   _("Peek Down"));
 
-      add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), m_input_manager.joystick_manager->jump_with_up_joy);
+      add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), g_config->joystick_config.jump_with_up_joy);
     }
     else
     {
@@ -116,7 +117,7 @@ JoystickMenu::menu_action(MenuItem* item)
   }
   else if (item->id == MNID_JUMP_WITH_UP)
   {
-    m_input_manager.joystick_manager->jump_with_up_joy = item->toggled;
+    g_config->joystick_config.jump_with_up_joy = item->toggled;
   }
   else if (item->id == MNID_AUTO_JOYSTICK_CFG)
   {
@@ -134,9 +135,9 @@ JoystickMenu::menu_action(MenuItem* item)
 void
 JoystickMenu::refresh_menu_item(Controller::Control id)
 {
-  int button  = m_input_manager.joystick_manager->reversemap_joybutton(id);
-  int axis    = m_input_manager.joystick_manager->reversemap_joyaxis(id);
-  int hat_dir = m_input_manager.joystick_manager->reversemap_joyhat(id);
+  int button  = g_config->joystick_config.reversemap_joybutton(id);
+  int axis    = g_config->joystick_config.reversemap_joyaxis(id);
+  int hat_dir = g_config->joystick_config.reversemap_joyhat(id);
 
   if (button != -1)
   {