#303: Typo fixes from mathnerd314
[supertux.git] / src / control / joystickkeyboardcontroller.cpp
index 2bc549d..3a0b7da 100644 (file)
 #include "console.hpp"
 #include "gameconfig.hpp"
 
+namespace{
+  const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
+}
+
 class JoystickKeyboardController::JoystickMenu : public Menu
 {
 public:
@@ -42,6 +46,8 @@ public:
   void update_menu_item(Control id);
   virtual void menu_action(MenuItem* item);
   JoystickKeyboardController* controller;
+private:
+  void recreateMenu();
 };
 
 class JoystickKeyboardController::KeyboardMenu : public Menu
@@ -76,47 +82,14 @@ JoystickKeyboardController::JoystickKeyboardController()
   keymap[SDLK_KP_ENTER] = MENU_SELECT;
   keymap[SDLK_CARET]    = CONSOLE;
   keymap[SDLK_DELETE]   = PEEK_LEFT;
-  keymap[SDLK_END]      = PEEK_RIGHT;
+  keymap[SDLK_PAGEDOWN] = PEEK_RIGHT;
+  keymap[SDLK_HOME]     = PEEK_UP;
+  keymap[SDLK_END]      = PEEK_DOWN;
 
-  jump_with_up = false;
+  jump_with_up_joy = false;
+  jump_with_up_kbd = false;
 
-  int joystick_count = SDL_NumJoysticks();
-  min_joybuttons = -1;
-  max_joybuttons = -1;
-  max_joyaxis    = -1;
-  max_joyhats    = -1;
-
-  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 << " has less than 2 buttons" << std::endl;
-      good = false;
-    }
-    if(SDL_JoystickNumAxes(joystick) < 2
-       && SDL_JoystickNumHats(joystick) == 0) {
-      log_info << "Joystick " << 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);
-  }
+  updateAvailableJoysticks();
 
   dead_zone = 1000;
 
@@ -146,13 +119,6 @@ JoystickKeyboardController::JoystickKeyboardController()
   joy_axis_map[ 1] = RIGHT;
   joy_axis_map[-2] = UP;
   joy_axis_map[ 2] = DOWN;
-
-  // 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);
-  }
 }
 
 JoystickKeyboardController::~JoystickKeyboardController()
@@ -168,11 +134,73 @@ JoystickKeyboardController::~JoystickKeyboardController()
 }
 
 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_JoystickName(i) << " has less than 2 buttons" << std::endl;
+        good = false;
+      }
+      if(SDL_JoystickNumAxes(joystick) < 2
+         && SDL_JoystickNumHats(joystick) == 0) {
+        log_info << "Joystick " << i << ": " << SDL_JoystickName(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);
+  }
+}
+
+void
 JoystickKeyboardController::read(const lisp::Lisp& lisp)
 {
   const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
   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") {
@@ -196,8 +224,6 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp)
           continue;
         }
         keymap[(SDLKey) key] = (Control)i;
-      } else {
-        log_info << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl;
       }
     }
   }
@@ -205,7 +231,7 @@ JoystickKeyboardController::read(const lisp::Lisp& 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);
+    joystick_lisp->get("jump-with-up", jump_with_up_joy);
     lisp::ListIterator iter(joystick_lisp);
     while(iter.next()) {
       if(iter.item() == "map") {
@@ -262,6 +288,7 @@ void
 JoystickKeyboardController::write(lisp::Writer& writer)
 {
   writer.start_list("keymap");
+  writer.write_bool("jump-with-up", jump_with_up_kbd);
   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
     writer.start_list("map");
     writer.write_int("key", (int) i->first);
@@ -272,7 +299,7 @@ JoystickKeyboardController::write(lisp::Writer& writer)
 
   writer.start_list("joystick");
   writer.write_int("dead-zone", dead_zone);
-  writer.write_bool("jump-with-up", jump_with_up);
+  writer.write_bool("jump-with-up", jump_with_up_joy);
 
   for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
       ++i) {
@@ -308,7 +335,7 @@ JoystickKeyboardController::reset()
 void
 JoystickKeyboardController::set_joy_controls(Control id, bool value)
 {
-  if (jump_with_up && id == Controller::UP)
+  if (jump_with_up_joy && id == Controller::UP)
     controls[Controller::JUMP] = value;
 
   controls[(Control)id] = value;
@@ -383,7 +410,7 @@ JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
   else
     {
       // Split the axis into left and right, so that both can be
-      // mapped seperatly (needed for jump/down vs up/down)
+      // mapped separately (needed for jump/down vs up/down)
       int axis = jaxis.axis + 1;
 
       AxisMap::iterator left  = joy_axis_map.find(-axis);
@@ -487,10 +514,13 @@ JoystickKeyboardController::process_key_event(const SDL_Event& event)
       process_menu_key_event(event);
     } else if(key_mapping == keymap.end()) {
       // default action: update controls
-      log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
+      //log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
     } else {
       Control control = key_mapping->second;
       controls[control] = (event.type == SDL_KEYDOWN);
+      if (jump_with_up_kbd && control == UP){
+        controls[JUMP] = (event.type == SDL_KEYDOWN);
+      }
     }
   }
 }
@@ -783,9 +813,12 @@ JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
     add_controlfield(Controller::ACTION,     _("Action"));
     add_controlfield(Controller::PEEK_LEFT,  _("Peek Left"));
     add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
+    add_controlfield(Controller::PEEK_UP,    _("Peek Up"));
+    add_controlfield(Controller::PEEK_DOWN,  _("Peek Down"));
     if (config->console_enabled) {
       add_controlfield(Controller::CONSOLE, _("Console"));
     }
+    add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
     add_hl();
     add_back(_("Back"));
     update();
@@ -832,9 +865,12 @@ JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
 void
 JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
 {
-  assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
-  item->change_input(_("Press Key"));
-  controller->wait_for_key = item->id;
+  if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
+    item->change_input(_("Press Key"));
+    controller->wait_for_key = item->id;
+  } else if( item->id == Controller::CONTROLCOUNT) {
+    controller->jump_with_up_kbd = item->toggled;
+  } 
 }
 
 void
@@ -857,10 +893,15 @@ JoystickKeyboardController::KeyboardMenu::update()
     controller->reversemap_key(Controller::PEEK_LEFT)));
   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
     controller->reversemap_key(Controller::PEEK_RIGHT)));
+  get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
+    controller->reversemap_key(Controller::PEEK_UP)));
+  get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
+    controller->reversemap_key(Controller::PEEK_DOWN)));
   if (config->console_enabled) {
     get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
       controller->reversemap_key(Controller::CONSOLE)));
   }
+  get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
 }
 
 //---------------------------------------------------------------------------
@@ -869,6 +910,16 @@ JoystickKeyboardController::JoystickMenu::JoystickMenu(
   JoystickKeyboardController* _controller)
   : controller(_controller)
 {
+  recreateMenu();
+}
+
+JoystickKeyboardController::JoystickMenu::~JoystickMenu()
+{}
+
+void
+JoystickKeyboardController::JoystickMenu::recreateMenu()
+{
+  clear();
   add_label(_("Setup Joystick"));
   add_hl();
   if(controller->joysticks.size() > 0) {
@@ -881,19 +932,28 @@ JoystickKeyboardController::JoystickMenu::JoystickMenu(
     add_controlfield(Controller::PAUSE_MENU,  _("Pause/Menu"));
     add_controlfield(Controller::PEEK_LEFT,   _("Peek Left"));
     add_controlfield(Controller::PEEK_RIGHT,  _("Peek Right"));
+    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);
+    add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
   } else {
-    add_deactive(-1, _("No Joysticks found"));
+    add_inactive(-1, _("No Joysticks found"));
+  }
+  add_inactive(-1,"");
+  add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
+
+  //Show Joysticks currently activated:
+  for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
+      i != controller->joysticks.end(); ++i) {
+    if(*i != 0)
+      add_inactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
   }
+
   add_hl();
   add_back(_("Back"));
   update();
 }
 
-JoystickKeyboardController::JoystickMenu::~JoystickMenu()
-{}
-
 std::string
 JoystickKeyboardController::JoystickMenu::get_button_name(int button)
 {
@@ -912,7 +972,10 @@ JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
     item->change_input(_("Press Button"));
     controller->wait_for_joystick = item->id;
   } else if (item->id == Controller::CONTROLCOUNT) {
-    controller->jump_with_up = item->toggled;
+    controller->jump_with_up_joy = item->toggled;
+  } else if( item->id == SCAN_JOYSTICKS) {
+    controller->updateAvailableJoysticks();
+    recreateMenu();
   }
 }
 
@@ -995,6 +1058,8 @@ JoystickKeyboardController::JoystickMenu::update()
   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;
+  get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;
 }