Moved joystick specific code from JoystickKeyboardController into JoystickManager...
authorIngo Ruhnke <grumbel@gmail.com>
Wed, 6 Aug 2014 02:29:41 +0000 (04:29 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Wed, 6 Aug 2014 02:33:34 +0000 (04:33 +0200)
src/control/joystick_manager.cpp [new file with mode: 0644]
src/control/joystick_manager.hpp [new file with mode: 0644]
src/control/joystickkeyboardcontroller.cpp
src/control/joystickkeyboardcontroller.hpp
src/supertux/menu/joystick_menu.cpp
src/supertux/menu/joystick_menu.hpp

diff --git a/src/control/joystick_manager.cpp b/src/control/joystick_manager.cpp
new file mode 100644 (file)
index 0000000..2c11c96
--- /dev/null
@@ -0,0 +1,513 @@
+//  SuperTux
+//  Copyright (C) 2013 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 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_manager.hpp"
+
+#include <iostream>
+#include <algorithm>
+
+#include "control/joystickkeyboardcontroller.hpp"
+#include "lisp/list_iterator.hpp"
+#include "supertux/menu/joystick_menu.hpp"
+#include "supertux/menu/menu_storage.hpp"
+#include "util/gettext.hpp"
+#include "util/log.hpp"
+#include "util/writer.hpp"
+
+JoystickManager::JoystickManager(JoystickKeyboardController* parent) :
+  parent(parent),
+  m_use_game_controller(true),
+  joy_button_map(),
+  joy_axis_map(),
+  joy_hat_map(),
+  dead_zone(4000),
+  min_joybuttons(),
+  max_joybuttons(),
+  max_joyaxis(),
+  max_joyhats(),
+  hat_state(0),
+  jump_with_up_joy(false),
+  wait_for_joystick(-1),
+  joysticks(),
+  game_controllers()
+{
+  if (!m_use_game_controller)
+  {
+    // 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()
+{
+  for(auto joy : joysticks)
+  {
+    SDL_JoystickClose(joy);
+  }
+
+  for(auto con : game_controllers)
+  {
+    SDL_GameControllerClose(con);
+  }
+}
+
+void
+JoystickManager::on_joystick_added(int joystick_index)
+{
+  std::cout << "joydeviceadded: " << joystick_index << std::endl;
+  if (m_use_game_controller)
+  {
+    if (!SDL_IsGameController(joystick_index))
+    {
+      log_warning << "joystick is not a game controller, ignoring: " << joystick_index << std::endl;
+    }
+    else
+    {
+      SDL_GameController* game_controller = SDL_GameControllerOpen(joystick_index);
+      if (!game_controller)
+      {
+        log_warning << "failed to open game_controller: " << joystick_index 
+                    << ": " << SDL_GetError() << std::endl;
+      }
+      else
+      {
+        game_controllers.push_back(game_controller);
+      }
+    }
+  }
+  else
+  {
+    SDL_Joystick* joystick = SDL_JoystickOpen(joystick_index);
+    if (!joystick)
+    {
+      log_warning << "failed to open joystick: " << joystick_index 
+                  << ": " << SDL_GetError() << std::endl;
+    }
+    else
+    {
+      joysticks.push_back(joystick);
+    }
+
+    if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
+      min_joybuttons = SDL_JoystickNumButtons(joystick);
+
+    if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
+      max_joybuttons = SDL_JoystickNumButtons(joystick);
+
+    if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
+      max_joyaxis = SDL_JoystickNumAxes(joystick);
+
+    if(SDL_JoystickNumHats(joystick) > max_joyhats)
+      max_joyhats = SDL_JoystickNumHats(joystick);
+  }
+}
+
+void
+JoystickManager::on_joystick_removed(int instance_id)
+{
+  if (m_use_game_controller)
+  {
+    for(auto& controller : game_controllers)
+    {
+      SDL_Joystick* joy = SDL_GameControllerGetJoystick(controller);
+      SDL_JoystickID id = SDL_JoystickInstanceID(joy);
+      if (id == instance_id)
+      {
+        SDL_GameControllerClose(controller);
+        controller = nullptr;
+      }
+    }
+
+    game_controllers.erase(std::remove(game_controllers.begin(), game_controllers.end(), nullptr),
+                           game_controllers.end());
+  }
+  else
+  {
+    std::cout << "joydeviceremoved: " << static_cast<int>(instance_id) << std::endl;
+    for(auto& joy : joysticks)
+    {
+      SDL_JoystickID id = SDL_JoystickInstanceID(joy);
+      if (id == instance_id)
+      {
+        SDL_JoystickClose(joy);
+        joy = nullptr;
+      }
+    }
+
+    joysticks.erase(std::remove(joysticks.begin(), joysticks.end(), nullptr),
+                    joysticks.end());
+  }
+}
+
+void
+JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat)
+{
+  Uint8 changed = hat_state ^ jhat.value;
+
+  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));
+
+    if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
+      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));
+
+    if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
+      bind_joyhat(jhat.which, SDL_HAT_RIGHT, Controller::Control(wait_for_joystick));
+
+    MenuStorage::get_joystick_options_menu()->update();
+    wait_for_joystick = -1;
+  }
+  else
+  {
+    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())
+        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())
+        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())
+        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())
+        set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
+    }
+  }
+
+  hat_state = jhat.value;
+}
+
+void
+JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis)
+{
+  if (wait_for_joystick >= 0)
+  {
+    if (abs(jaxis.value) > dead_zone) {
+      if (jaxis.value < 0)
+        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));
+
+      MenuStorage::get_joystick_options_menu()->update();
+      wait_for_joystick = -1;
+    }
+  }
+  else
+  {
+    // Split the axis into left and right, so that both can be
+    // 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));
+
+    if(left == joy_axis_map.end()) {
+      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
+    } else {
+      if (jaxis.value < -dead_zone)
+        set_joy_controls(left->second,  true);
+      else
+        set_joy_controls(left->second, false);
+    }
+
+    if(right == joy_axis_map.end()) {
+      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
+    } else {
+      if (jaxis.value > dead_zone)
+        set_joy_controls(right->second, true);
+      else
+        set_joy_controls(right->second, false);
+    }
+  }
+}
+
+void
+JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
+{
+  if(wait_for_joystick >= 0) 
+  {
+    if(jbutton.state == SDL_PRESSED)
+    {
+      bind_joybutton(jbutton.which, jbutton.button, (Controller::Control)wait_for_joystick);
+      MenuStorage::get_joystick_options_menu()->update();
+      parent->reset();
+      wait_for_joystick = -1;
+    }
+  } 
+  else 
+  {
+    ButtonMap::iterator i = joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
+    if(i == joy_button_map.end()) {
+      log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
+    } else {
+      set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
+    }
+  }
+}
+
+
+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)
+  {
+    parent->get_main_controller()->set_control(Controller::JUMP, value);
+  }
+
+  parent->get_main_controller()->set_control(id, value);
+}
+
+/* EOF */
diff --git a/src/control/joystick_manager.hpp b/src/control/joystick_manager.hpp
new file mode 100644 (file)
index 0000000..c0e11d3
--- /dev/null
@@ -0,0 +1,109 @@
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//                2014 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 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_MANAGER_HPP
+#define HEADER_SUPERTUX_CONTROL_JOYSTICK_MANAGER_HPP
+
+#include <map>
+#include <vector>
+
+#include "SDL.h"
+
+#include "control/controller.hpp"
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
+
+class JoystickKeyboardController;
+
+class JoystickManager
+{
+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:
+  JoystickKeyboardController* parent;
+  bool m_use_game_controller;
+
+  ButtonMap joy_button_map;
+  AxisMap joy_axis_map;
+  HatMap joy_hat_map;
+
+  int dead_zone;
+
+  /// the number of buttons all joysticks have
+  int min_joybuttons;
+
+  /// the max number of buttons a joystick has
+  int max_joybuttons;
+
+  int max_joyaxis;
+  int max_joyhats;
+
+  Uint8 hat_state;
+
+public:
+  bool jump_with_up_joy;
+
+public:
+  int wait_for_joystick;
+
+public:
+  std::vector<SDL_Joystick*> joysticks;
+
+private:
+  std::vector<SDL_GameController*> game_controllers;
+
+public:
+  JoystickManager(JoystickKeyboardController* parent);
+  ~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;
+};
+
+#endif
+
+/* EOF */
index 85c6b8e..f0740e7 100644 (file)
 
 #include <iostream>
 
-#include "lisp/list_iterator.hpp"
+#include "control/joystick_manager.hpp"
 #include "gui/menu_manager.hpp"
+#include "lisp/list_iterator.hpp"
 #include "supertux/console.hpp"
 #include "supertux/gameconfig.hpp"
-#include "supertux/menu/menu_storage.hpp"
 #include "supertux/menu/joystick_menu.hpp"
 #include "supertux/menu/keyboard_menu.hpp"
+#include "supertux/menu/menu_storage.hpp"
 #include "util/gettext.hpp"
 #include "util/writer.hpp"
 
 JoystickKeyboardController::JoystickKeyboardController() :
-  controller(),
+  controller(new Controller),
+  joystick_manager(new JoystickManager(this)),
   keymap(),
-  joy_button_map(),
-  joy_axis_map(),
-  joy_hat_map(),
-  joysticks(),
   name(),
-  dead_zone(),
-  min_joybuttons(),
-  max_joybuttons(),
-  max_joyaxis(),
-  max_joyhats(),
-  hat_state(0),
-  jump_with_up_joy(),
   jump_with_up_kbd(),
-  wait_for_key(-1), 
-  wait_for_joystick(-1)
+  wait_for_key(-1)
 {
-  controller = new Controller;
-
   // initialize default keyboard map
   keymap[SDLK_LEFT]     = Controller::LEFT;
   keymap[SDLK_RIGHT]    = Controller::RIGHT;
@@ -69,144 +57,45 @@ JoystickKeyboardController::JoystickKeyboardController() :
   keymap[SDLK_HOME]     = Controller::PEEK_UP;
   keymap[SDLK_END]      = Controller::PEEK_DOWN;
 
-  jump_with_up_joy = false;
   jump_with_up_kbd = false;
-
-  updateAvailableJoysticks();
-
-  dead_zone = 1000;
-
-  // 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);
 }
 
 JoystickKeyboardController::~JoystickKeyboardController()
 {
-  for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
-      i != joysticks.end(); ++i) {
-    if(*i != 0)
-      SDL_JoystickClose(*i);
-  }
-  delete controller;
-}
-
-void
-JoystickKeyboardController::updateAvailableJoysticks()
-{
-  for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
-      i != joysticks.end(); ++i) {
-    if(*i != 0)
-      SDL_JoystickClose(*i);
-  }
-  joysticks.clear();
-  
-  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-  SDL_InitSubSystem(SDL_INIT_JOYSTICK);
-
-  int joystick_count = SDL_NumJoysticks();
-  min_joybuttons = -1;
-  max_joybuttons = -1;
-  max_joyaxis    = -1;
-  max_joyhats    = -1;
-
-  if( joystick_count > 0 ){
-    for(int i = 0; i < joystick_count; ++i) {
-      SDL_Joystick* joystick = SDL_JoystickOpen(i);
-      bool good = true;
-      if(SDL_JoystickNumButtons(joystick) < 2) {
-        log_info << _("Joystick ") << i << ": " << SDL_JoystickID(i) << _(" has less than 2 buttons") << std::endl;
-        good = false;
-      }
-      if(SDL_JoystickNumAxes(joystick) < 2
-         && SDL_JoystickNumHats(joystick) == 0) {
-        log_info << _("Joystick ") << i << ": " << SDL_JoystickID(i) << _(" has less than 2 axes and no hat") << std::endl;
-        good = false;
-      }
-      if(!good) {
-        SDL_JoystickClose(joystick);
-        continue;
-      }
-
-      if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
-        min_joybuttons = SDL_JoystickNumButtons(joystick);
-
-      if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
-        max_joybuttons = SDL_JoystickNumButtons(joystick);
-
-      if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
-        max_joyaxis = SDL_JoystickNumAxes(joystick);
-
-      if(SDL_JoystickNumHats(joystick) > max_joyhats)
-        max_joyhats = SDL_JoystickNumHats(joystick);
-
-      joysticks.push_back(joystick);
-    }
-  }
-
-  // some joysticks or SDL seem to produce some bogus events after being opened
-  Uint32 ticks = SDL_GetTicks();
-  while(SDL_GetTicks() - ticks < 200) {
-    SDL_Event event;
-    SDL_PollEvent(&event);
-  }
 }
 
 Controller*
 JoystickKeyboardController::get_main_controller()
 {
-  return controller;
+  return controller.get();
 }
 
 void
 JoystickKeyboardController::read(const Reader& lisp)
 {
   const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
-  if(keymap_lisp) {
+  if (keymap_lisp) {
     keymap.clear();
     keymap_lisp->get("jump-with-up", jump_with_up_kbd);
     lisp::ListIterator iter(keymap_lisp);
     while(iter.next()) {
-      if(iter.item() == "map") {
+      if (iter.item() == "map") {
         int key = -1;
         std::string control;
         const lisp::Lisp* map = iter.lisp();
         map->get("key", key);
         map->get("control", control);
-//        if(key < SDLK_FIRST || key >= SDLK_LAST) {
+//        if (key < SDLK_FIRST || key >= SDLK_LAST) {
 //          log_info << "Invalid key '" << key << "' in keymap" << std::endl;
 //          continue;
 //        }
 
         int i = 0;
         for(i = 0; Controller::controlNames[i] != 0; ++i) {
-          if(control == Controller::controlNames[i])
+          if (control == Controller::controlNames[i])
             break;
         }
-        if(Controller::controlNames[i] == 0) {
+        if (Controller::controlNames[i] == 0) {
           log_info << "Invalid control '" << control << "' in keymap" << std::endl;
           continue;
         }
@@ -216,61 +105,9 @@ JoystickKeyboardController::read(const Reader& lisp)
   }
 
   const lisp::Lisp* joystick_lisp = lisp.get_lisp(_("joystick"));
-  if(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, 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, 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, Control(i));
-          }
-        }
-      }
-    }
+  if (joystick_lisp) 
+  {
+    joystick_manager->read(joystick_lisp);
   }
 }
 
@@ -288,31 +125,7 @@ JoystickKeyboardController::write(Writer& writer)
   writer.end_list("keymap");
 
   writer.start_list("joystick");
-  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");
-  }
-
+  joystick_manager->write(writer);
   writer.end_list("joystick");
 }
 
@@ -329,15 +142,6 @@ JoystickKeyboardController::reset()
 }
 
 void
-JoystickKeyboardController::set_joy_controls(Control id, bool value)
-{
-  if (jump_with_up_joy && id == Controller::UP)
-    controller->set_control(Controller::JUMP, value);
-
-  controller->set_control(id, value);
-}
-
-void
 JoystickKeyboardController::process_event(const SDL_Event& event)
 {
   switch(event.type) {
@@ -351,145 +155,51 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
       break;
 
     case SDL_JOYAXISMOTION:
-      process_axis_event(event.jaxis);
+      joystick_manager->process_axis_event(event.jaxis);
       break;
 
     case SDL_JOYHATMOTION:
-      process_hat_event(event.jhat);
+      joystick_manager->process_hat_event(event.jhat);
       break;
 
     case SDL_JOYBUTTONDOWN:
     case SDL_JOYBUTTONUP:
-      process_button_event(event.jbutton);
+      joystick_manager->process_button_event(event.jbutton);
       break;
 
-    default:
+    case SDL_JOYDEVICEADDED:
+      joystick_manager->on_joystick_added(event.jdevice.which);
       break;
-  }
-}
 
-void
-JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
-{
-  if(wait_for_joystick >= 0) 
-  {
-    if(jbutton.state == SDL_PRESSED)
-    {
-      bind_joybutton(jbutton.which, jbutton.button, (Control)wait_for_joystick);
-      MenuStorage::get_joystick_options_menu()->update();
-      reset();
-      wait_for_joystick = -1;
-    }
-  } 
-  else 
-  {
-    ButtonMap::iterator i = joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
-    if(i == joy_button_map.end()) {
-      log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
-    } else {
-      set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
-    }
-  }
-}
-
-void
-JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
-{
-  if (wait_for_joystick >= 0)
-  {
-    if (abs(jaxis.value) > dead_zone) {
-      if (jaxis.value < 0)
-        bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Control(wait_for_joystick));
-      else
-        bind_joyaxis(jaxis.which, jaxis.axis + 1, Control(wait_for_joystick));
-
-      MenuStorage::get_joystick_options_menu()->update();
-      wait_for_joystick = -1;
-    }
-  }
-  else
-  {
-    // Split the axis into left and right, so that both can be
-    // 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));
-
-    if(left == joy_axis_map.end()) {
-      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
-    } else {
-      if (jaxis.value < -dead_zone)
-        set_joy_controls(left->second,  true);
-      else
-        set_joy_controls(left->second, false);
-    }
-
-    if(right == joy_axis_map.end()) {
-      // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
-    } else {
-      if (jaxis.value > dead_zone)
-        set_joy_controls(right->second, true);
-      else
-        set_joy_controls(right->second, false);
-    }
-  }
-}
-
-void
-JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
-{
-  Uint8 changed = hat_state ^ jhat.value;
-
-  if (wait_for_joystick >= 0)
-  {
-    if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
-      bind_joyhat(jhat.which, SDL_HAT_UP, Control(wait_for_joystick));
-
-    if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
-      bind_joyhat(jhat.which, SDL_HAT_DOWN, Control(wait_for_joystick));
+    case SDL_JOYDEVICEREMOVED:
+      joystick_manager->on_joystick_removed(event.jdevice.which);
+      break;
 
-    if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
-      bind_joyhat(jhat.which, SDL_HAT_LEFT, Control(wait_for_joystick));
+    case SDL_CONTROLLERBUTTONDOWN:
+      std::cout << "SDL_CONTROLLERBUTTONDOWN" << std::endl;
+      break;
 
-    if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
-      bind_joyhat(jhat.which, SDL_HAT_RIGHT, Control(wait_for_joystick));
+    case SDL_CONTROLLERBUTTONUP:
+      std::cout << "SDL_CONTROLLERBUTTONUP" << std::endl;
+      break;
 
-    MenuStorage::get_joystick_options_menu()->update();
-    wait_for_joystick = -1;
-  }
-  else
-  {
-    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())
-        set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
-    }
+    case SDL_CONTROLLERDEVICEADDED:
+      // ignored, handled in SDL_JOYDEVICEADDED
+      std::cout << "SDL_CONTROLLERDEVICEADDED" << std::endl;
+      break;
 
-    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())
-        set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
-    }
+    case SDL_CONTROLLERDEVICEREMOVED:
+      // ignored, handled in SDL_JOYDEVICEREMOVED
+      std::cout << "SDL_CONTROLLERDEVICEREMOVED" << std::endl;
+      break;
 
-    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())
-        set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
-    }
+    case SDL_CONTROLLERDEVICEREMAPPED:
+      std::cout << "SDL_CONTROLLERDEVICEREMAPPED" << std::endl;
+      break;
 
-    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())
-        set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
-    }
+    default:
+      break;
   }
-
-  hat_state = jhat.value;
 }
 
 void
@@ -519,7 +229,7 @@ JoystickKeyboardController::process_key_event(const SDL_KeyboardEvent& event)
     } else if (MenuManager::current()) {
       // if menu mode: send key there
       process_menu_key_event(event);
-    } else if(key_mapping == keymap.end()) {
+    } else if (key_mapping == keymap.end()) {
       // default action: update controls
       //log_debug << "Key " << event.key.SDL_Keycode.sym << " is unbound" << std::endl;
     } else {
@@ -581,11 +291,11 @@ void
 JoystickKeyboardController::process_menu_key_event(const SDL_KeyboardEvent& event)
 {
   // wait for key mode?
-  if(wait_for_key >= 0) {
-    if(event.type == SDL_KEYUP)
+  if (wait_for_key >= 0) {
+    if (event.type == SDL_KEYUP)
       return;
 
-    if(event.keysym.sym != SDLK_ESCAPE
+    if (event.keysym.sym != SDLK_ESCAPE
        && event.keysym.sym != SDLK_PAUSE) {
       bind_key(event.keysym.sym, Control(wait_for_key));
     }
@@ -594,11 +304,11 @@ JoystickKeyboardController::process_menu_key_event(const SDL_KeyboardEvent& even
     wait_for_key = -1;
     return;
   }
-  if(wait_for_joystick >= 0) {
-    if(event.keysym.sym == SDLK_ESCAPE) {
+  if (joystick_manager->wait_for_joystick >= 0) {
+    if (event.keysym.sym == SDLK_ESCAPE) {
       reset();
       MenuStorage::get_joystick_options_menu()->update();
-      wait_for_joystick = -1;
+      joystick_manager->wait_for_joystick = -1;
     }
     return;
   }
@@ -638,70 +348,12 @@ JoystickKeyboardController::process_menu_key_event(const SDL_KeyboardEvent& even
 }
 
 void
-JoystickKeyboardController::unbind_joystick_control(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
-JoystickKeyboardController::bind_joyaxis(JoyId joy_id, int axis, 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
-JoystickKeyboardController::bind_joyhat(JoyId joy_id, int dir, Control c)
-{
-  unbind_joystick_control(c);
-
-  // add new mapping
-  joy_hat_map[std::make_pair(joy_id, dir)] = c;
-}
-
-void
-JoystickKeyboardController::bind_joybutton(JoyId joy_id, int button, Control control)
-{
-  unbind_joystick_control(control);
-
-  // add new mapping
-  joy_button_map[std::make_pair(joy_id, button)] = control;
-}
-
-void
 JoystickKeyboardController::bind_key(SDL_Keycode key, Control control)
 {
   // remove all previous mappings for that control and for that key
   for(KeyMap::iterator i = keymap.begin();
       i != keymap.end(); /* no ++i */) {
-    if(i->second == control) {
+    if (i->second == control) {
       KeyMap::iterator e = i;
       ++i;
       keymap.erase(e);
@@ -711,74 +363,22 @@ JoystickKeyboardController::bind_key(SDL_Keycode key, Control control)
   }
 
   KeyMap::iterator i = keymap.find(key);
-  if(i != keymap.end())
+  if (i != keymap.end())
     keymap.erase(i);
 
   // add new mapping
   keymap[key] = control;
 }
 
-void
-JoystickKeyboardController::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;
-}
-
 SDL_Keycode
 JoystickKeyboardController::reversemap_key(Control c)
 {
   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
-    if(i->second == c)
+    if (i->second == c)
       return i->first;
   }
 
   return SDLK_UNKNOWN;
 }
 
-int
-JoystickKeyboardController::reversemap_joyaxis(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
-JoystickKeyboardController::reversemap_joybutton(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
-JoystickKeyboardController::reversemap_joyhat(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;
-}
-
 /* EOF */
index 661ca7f..76798a1 100644 (file)
@@ -23,6 +23,7 @@
 #include <map>
 #include <string>
 #include <vector>
+#include <memory>
 
 #include "util/reader_fwd.hpp"
 #include "util/writer_fwd.hpp"
@@ -31,6 +32,7 @@ class Menu;
 class KeyboardMenu;
 class JoystickMenu;
 class Controller;
+class JoystickManager;
 
 class JoystickKeyboardController
 {
@@ -39,12 +41,8 @@ private:
   friend class JoystickMenu;
 
   typedef Controller::Control Control;
-  typedef Uint8 JoyId;
 
   typedef std::map<SDL_Keycode, Control> KeyMap;
-  typedef std::map<std::pair<JoyId, int>, Control> ButtonMap;
-  typedef std::map<std::pair<JoyId, int>, Control> AxisMap;
-  typedef std::map<std::pair<JoyId, int>, Control> HatMap;
 
 public:
   JoystickKeyboardController();
@@ -66,60 +64,25 @@ public:
 private:
   void process_text_input_event(const SDL_TextInputEvent& event);
   void process_key_event(const SDL_KeyboardEvent& event);
-  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 process_console_key_event(const SDL_KeyboardEvent& event);
   void process_menu_key_event(const SDL_KeyboardEvent& event);
 
-  void print_joystick_mappings();
-
   SDL_Keycode reversemap_key(Control c);
-  int    reversemap_joybutton(Control c);
-  int    reversemap_joyaxis(Control c);
-  int    reversemap_joyhat(Control c);
-
-  void unbind_joystick_control(Control c);
-
-  void bind_joybutton(JoyId joy_id, int button, Control c);
-  void bind_joyaxis(JoyId joy_id, int axis, Control c);
-  void bind_joyhat(JoyId joy_id, int dir, Control c);
   void bind_key(SDL_Keycode key, Control c);
 
-  void set_joy_controls(Control id, bool value); 
-
 private:
-  Controller *controller;
+  std::unique_ptr<Controller> controller;
+public:
+  std::unique_ptr<JoystickManager> joystick_manager;
 
+private:
   KeyMap keymap;
 
-  ButtonMap joy_button_map;
-
-  AxisMap joy_axis_map;
-
-  HatMap joy_hat_map;
-
-  std::vector<SDL_Joystick*> joysticks;
-
   std::string name;
 
-  int dead_zone;
-  /// the number of buttons all joysticks have
-  int min_joybuttons;
-  /// the max number of buttons a joystick has
-  int max_joybuttons;
-
-  int max_joyaxis;
-
-  int max_joyhats;
-
-  Uint8 hat_state;
-
-  bool jump_with_up_joy; // Joystick up jumps
   bool jump_with_up_kbd; // Keyboard up jumps
 
   int wait_for_key;
-  int wait_for_joystick;
 
 private:
   JoystickKeyboardController(const JoystickKeyboardController&);
index e4e1dcb..27fe9f0 100644 (file)
 
 #include <sstream>
 
+#include "control/joystick_manager.hpp"
 #include "util/gettext.hpp"
 
-namespace{
-  const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
-}
-
 JoystickMenu::JoystickMenu(JoystickKeyboardController* _controller) :
-  controller(_controller)
+  controller(_controller),
+  joysticks_available(false)
 {
   recreateMenu();
 }
@@ -40,7 +38,9 @@ JoystickMenu::recreateMenu()
   clear();
   add_label(_("Setup Joystick"));
   add_hl();
-  if(controller->joysticks.size() > 0) {
+  if(controller->joystick_manager->joysticks.size() > 0) {
+    joysticks_available = true;
+
     add_controlfield(Controller::UP,          _("Up"));
     add_controlfield(Controller::DOWN,        _("Down"));
     add_controlfield(Controller::LEFT,        _("Left"));
@@ -53,22 +53,10 @@ JoystickMenu::recreateMenu()
     add_controlfield(Controller::PEEK_UP,     _("Peek Up"));
     add_controlfield(Controller::PEEK_DOWN,   _("Peek Down"));
 
-    add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
+    add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->joystick_manager->jump_with_up_joy);
   } else {
     add_inactive(-1, _("No Joysticks found"));
-  }
-  add_inactive(-1,"");
-  add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
-  //Show Joysticks currently activated: //edit by giby
-  SDL_Joystick *joy;
-  if (SDL_NumJoysticks() > 0) {
-    joy = SDL_JoystickOpen(0);
-  }
-
-  for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
-      i != controller->joysticks.end(); ++i) {
-    if(*i != 0)
-      add_inactive(-1, SDL_JoystickName(joy) );
+    joysticks_available = false;
   }
 
   add_hl();
@@ -92,21 +80,18 @@ JoystickMenu::menu_action(MenuItem* item)
 {
   if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
     item->change_input(_("Press Button"));
-    controller->wait_for_joystick = item->id;
+    controller->joystick_manager->wait_for_joystick = item->id;
   } else if (item->id == Controller::CONTROLCOUNT) {
-    controller->jump_with_up_joy = item->toggled;
-  } else if( item->id == SCAN_JOYSTICKS) {
-    controller->updateAvailableJoysticks();
-    recreateMenu();
+    controller->joystick_manager->jump_with_up_joy = item->toggled;
   }
 }
 
 void
 JoystickMenu::update_menu_item(Controller::Control id)
 {
-  int button  = controller->reversemap_joybutton(id);
-  int axis    = controller->reversemap_joyaxis(id);
-  int hat_dir = controller->reversemap_joyhat(id);
+  int button  = controller->joystick_manager->reversemap_joybutton(id);
+  int axis    = controller->joystick_manager->reversemap_joyaxis(id);
+  int hat_dir = controller->joystick_manager->reversemap_joyhat(id);
 
   if (button != -1) {
     get_item_by_id((int)id).change_input(get_button_name(button));
@@ -167,23 +152,34 @@ JoystickMenu::update_menu_item(Controller::Control id)
 void
 JoystickMenu::update()
 {
-  if(controller->joysticks.size() == 0)
-    return;
-
-  update_menu_item(Controller::UP);
-  update_menu_item(Controller::DOWN);
-  update_menu_item(Controller::LEFT);
-  update_menu_item(Controller::RIGHT);
-
-  update_menu_item(Controller::JUMP);
-  update_menu_item(Controller::ACTION);
-  update_menu_item(Controller::PAUSE_MENU);
-  update_menu_item(Controller::PEEK_LEFT);
-  update_menu_item(Controller::PEEK_RIGHT);
-  update_menu_item(Controller::PEEK_UP);
-  update_menu_item(Controller::PEEK_DOWN);
-
-  get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;
+  log_info << controller->joystick_manager->joysticks.size() << std::endl;
+
+  if(true) //controller->joysticks.size() == 0)
+  {
+    // do nothing
+  }
+  else
+  {
+    if (!joysticks_available)
+    {
+      recreateMenu();
+    }
+
+    update_menu_item(Controller::UP);
+    update_menu_item(Controller::DOWN);
+    update_menu_item(Controller::LEFT);
+    update_menu_item(Controller::RIGHT);
+
+    update_menu_item(Controller::JUMP);
+    update_menu_item(Controller::ACTION);
+    update_menu_item(Controller::PAUSE_MENU);
+    update_menu_item(Controller::PEEK_LEFT);
+    update_menu_item(Controller::PEEK_RIGHT);
+    update_menu_item(Controller::PEEK_UP);
+    update_menu_item(Controller::PEEK_DOWN);
+
+    //get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;
+  }
 }
 
 /* EOF */
index 6529563..8efbda8 100644 (file)
@@ -31,13 +31,16 @@ public:
   std::string get_button_name(int button);
   void update_menu_item(Controller::Control id);
   virtual void menu_action(MenuItem* item);
-  JoystickKeyboardController* controller;
   void check_menu() {}
 
 private:
   void recreateMenu();
 
 private:
+  JoystickKeyboardController* controller;
+  bool joysticks_available;
+
+private:
   JoystickMenu(const JoystickMenu&);
   JoystickMenu& operator=(const JoystickMenu&);
 };