Yet another Console commit /
authorChristoph Sommer <mail@christoph-sommer.de>
Sat, 8 Apr 2006 22:52:30 +0000 (22:52 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Sat, 8 Apr 2006 22:52:30 +0000 (22:52 +0000)
Console toggle key is now read from config (control "console"). Hint: key 94 is the caret character /
Console now accepts multiple ConsoleCommandListeners per command. Will only call the most recently registered one /
Autocomplete only completes unambiguous commands /
"End" key scrolls to backbuffer end

SVN-Revision: 3272

src/console.cpp
src/console.hpp
src/control/controller.cpp
src/control/controller.hpp
src/control/joystickkeyboardcontroller.cpp
src/control/joystickkeyboardcontroller.hpp

index 62d264c..8a330b9 100644 (file)
@@ -88,20 +88,19 @@ Console::autocomplete()
 
   std::string cmdList = "";
   int cmdListLen = 0;
-  for (std::map<std::string, ConsoleCommandReceiver*>::iterator i = commands.begin(); i != commands.end(); i++) {
+  for (std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.begin(); i != commands.end(); i++) {
     std::string cmdKnown = i->first;
     if (cmdKnown.substr(0, cmdPart.length()) == cmdPart) {
-      if (cmdListLen == 0) {
-       inputBuffer.str(cmdKnown);
-       inputBuffer.pubseekoff(0, std::ios_base::end, std::ios_base::out);
-      } else {
-       cmdList = cmdList + ", ";
-      }
+      if (cmdListLen > 0) cmdList = cmdList + ", ";
       cmdList = cmdList + cmdKnown;
       cmdListLen++;
     }
   }
   if (cmdListLen == 0) addLine("No known command starts with \""+cmdPart+"\"");
+  if (cmdListLen == 1) {
+    inputBuffer.str(cmdList);
+    inputBuffer.pubseekoff(0, std::ios_base::end, std::ios_base::out);
+  }
   if (cmdListLen > 1) addLine(cmdList);
 }
 
@@ -109,7 +108,7 @@ void
 Console::addLine(std::string s) 
 {
   lines.push_front(s);
-  if (lines.size() >= 256) lines.pop_back();
+  if (lines.size() >= 65535) lines.pop_back();
   if (height < 64) {
     if (height < 4+9) height=4+9;
     height+=9;
@@ -121,11 +120,14 @@ Console::addLine(std::string s)
 void
 Console::parse(std::string s) 
 {
-  if (commands.find(s) == commands.end()) {
+  std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(s);
+  if ((i == commands.end()) || (i->second.size() == 0)) {
     addLine("unknown command: \"" + s + "\"");
     return;
   }
-  ConsoleCommandReceiver* ccr = commands[s];
+
+  // send command to the most recently registered ccr
+  ConsoleCommandReceiver* ccr = i->second.front();
   if (ccr->consoleCommand(s) != true) msg_warning("Sent command to registered ccr, but command was unhandled");
 }
 
@@ -147,6 +149,20 @@ Console::hide()
 {
   focused = false;
   height = 0;
+
+  // clear input buffer
+  inputBuffer.str(std::string());
+}
+
+void 
+Console::toggle()
+{
+  if (Console::hasFocus()) {
+    Console::hide(); 
+  } 
+  else { 
+    Console::show();
+  }
 }
 
 void 
@@ -185,31 +201,29 @@ Console::draw(DrawingContext& context)
 void 
 Console::registerCommand(std::string command, ConsoleCommandReceiver* ccr)
 {
-  if (commands.find(command) != commands.end()) {
-    msg_warning("Command \"" << command << "\" already associated with a command receiver. Not associated.");
-    return;
-  }
-  commands[command] = ccr;
+  commands[command].push_front(ccr);
 }
 
 void 
 Console::unregisterCommand(std::string command, ConsoleCommandReceiver* ccr)
 {
-  if (commands.find(command) == commands.end()) {
+  std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(command);
+  if ((i == commands.end()) || (i->second.size() == 0)) {
     msg_warning("Command \"" << command << "\" not associated with a command receiver. Not dissociated.");
     return;
   }
-  if (commands[command] != ccr) {
-    msg_warning("Command \"" << command << "\" associated with another command receiver. Not dissociated.");
+  std::list<ConsoleCommandReceiver*>::iterator j = find(i->second.begin(), i->second.end(), ccr);
+  if (j == i->second.end()) {
+    msg_warning("Command \"" << command << "\" not associated with given command receiver. Not dissociated.");
     return;
   }
-  commands.erase(command);
+  i->second.erase(j);
 }
 
 int Console::height = 0;
 bool Console::focused = false;
 std::list<std::string> Console::lines;
-std::map<std::string, ConsoleCommandReceiver*> Console::commands;
+std::map<std::string, std::list<ConsoleCommandReceiver*> > Console::commands;
 ConsoleStreamBuffer Console::inputBuffer;
 ConsoleStreamBuffer Console::outputBuffer;
 std::ostream Console::input(&Console::inputBuffer);
index 4d9ae0d..53267b3 100644 (file)
@@ -48,13 +48,15 @@ class Console
     void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
     static void show(); /**< display the console */
     static void hide(); /**< hide the console */
+    static void toggle(); /**< display the console if hidden, hide otherwise */
+
     static bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
     static void registerCommand(std::string command, ConsoleCommandReceiver* ccr); /**< associate command with the given CCR */
     static void unregisterCommand(std::string command, ConsoleCommandReceiver* ccr); /**< dissociate command and CCR */
 
   protected:
     static std::list<std::string> lines; /**< backbuffer of lines sent to the console */
-    static std::map<std::string, ConsoleCommandReceiver*> commands; /**< map of console commands and their associated ConsoleCommandReceivers */
+    static std::map<std::string, std::list<ConsoleCommandReceiver*> > commands; /**< map of console commands and a list of associated ConsoleCommandReceivers */
     Surface* background; /**< console background image */
     static int height; /**< height of the console in px */
     static int offset; /**< decrease to scroll text up */
index db924af..e7fe383 100644 (file)
@@ -33,6 +33,7 @@ const char* Controller::controlNames[] = {
   "action",
   "pause-menu",
   "menu-select",
+  "console",
   0
 };
 
index f320825..3e37cf7 100644 (file)
@@ -35,6 +35,7 @@ public:
     ACTION,
     PAUSE_MENU,
     MENU_SELECT,
+    CONSOLE,
     
     CONTROLCOUNT
   };
index 8e715f0..776266b 100644 (file)
@@ -70,6 +70,7 @@ JoystickKeyboardController::JoystickKeyboardController()
   keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU));  
   keymap.insert(std::make_pair(SDLK_RETURN, MENU_SELECT));
   keymap.insert(std::make_pair(SDLK_KP_ENTER, MENU_SELECT));
+  keymap.insert(std::make_pair(SDLK_CARET, CONSOLE));
   
   int joystick_count = SDL_NumJoysticks();
   min_joybuttons = -1;
@@ -246,57 +247,7 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
   switch(event.type) {
     case SDL_KEYUP:
     case SDL_KEYDOWN:
-      if (event.key.keysym.scancode == 49) {
-       // console key was pressed - toggle console
-       if (event.type == SDL_KEYDOWN) {
-         if (Console::hasFocus()) {
-           Console::hide();
-         } else {
-           Console::show();
-         }
-       }
-      } else if (Console::hasFocus()) {
-       // console is open - send key there
-       if (event.type == SDL_KEYDOWN) {
-         int c = event.key.keysym.unicode;
-         if ((c >= 32) && (c <= 126)) {
-           Console::input << (char)c;
-         }
-         switch (event.key.keysym.sym) {
-           case SDLK_RETURN:
-             Console::input << std::endl;
-             break;
-           case SDLK_BACKSPACE:
-             Console::backspace();
-             break;
-           case SDLK_TAB:
-             Console::autocomplete();
-             break;
-           case SDLK_PAGEUP:
-             Console::scroll(-1);
-             break;
-           case SDLK_PAGEDOWN:
-             Console::scroll(+1);
-             break;
-           default:
-             break;
-         }
-       }
-      } 
-      else if (Menu::current()) { 
-       // menu mode - send key there
-        process_menu_key_event(event);
-        return;
-      } else {
-        // normal mode - find key in keymap
-        KeyMap::iterator i = keymap.find(event.key.keysym.sym);
-        if(i == keymap.end()) {
-          msg_debug("Pressed key without mapping");
-          return;
-        }
-        Control control = i->second;
-        controls[control] = event.type == SDL_KEYDOWN ? true : false;
-      }
+      process_key_event(event);
       break;
 
     case SDL_JOYAXISMOTION:
@@ -386,6 +337,72 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
 }
 
 void
+JoystickKeyboardController::process_key_event(const SDL_Event& event)
+{
+  KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
+
+  // if console key was pressed: toggle console
+  if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
+    if (event.type != SDL_KEYDOWN) return;
+    Console::toggle();
+    return;
+  }
+
+  // if console is open: send key there
+  if (Console::hasFocus()) {
+    process_console_key_event(event);
+    return;
+  } 
+
+  // if menu mode: send key there
+  if (Menu::current()) { 
+    process_menu_key_event(event);
+    return;
+  }
+
+  // default action: update controls
+  if(key_mapping == keymap.end()) {
+    msg_debug("Key " << event.key.keysym.sym << " is unbound");
+    return;
+  }
+  Control control = key_mapping->second;
+  controls[control] = event.type == SDL_KEYDOWN ? true : false;
+}
+
+void
+JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
+{
+  if (event.type != SDL_KEYDOWN) return;
+
+  switch (event.key.keysym.sym) {
+    case SDLK_RETURN:
+      Console::input << std::endl;
+      break;
+    case SDLK_BACKSPACE:
+      Console::backspace();
+      break;
+    case SDLK_TAB:
+      Console::autocomplete();
+      break;
+    case SDLK_PAGEUP:
+      Console::scroll(-1);
+      break;
+    case SDLK_PAGEDOWN:
+      Console::scroll(+1);
+      break;
+    case SDLK_END:
+      Console::scroll(+65535);
+      break;
+    default:
+      int c = event.key.keysym.unicode;
+      if ((c >= 32) && (c <= 126)) {
+       Console::input << (char)c;
+      }
+      break;
+  }
+}
+
+void
 JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
 {
   // wait for key mode?
index 3f34997..90930ea 100644 (file)
@@ -48,6 +48,8 @@ public:
   Menu* get_joystick_options_menu();
 
 private:
+  void process_key_event(const SDL_Event& event);
+  void process_console_key_event(const SDL_Event& event);
   void process_menu_key_event(const SDL_Event& event);
   
   typedef std::map<SDLKey, Control> KeyMap;
@@ -67,14 +69,15 @@ private:
   int min_joybuttons;
   /// the max number of buttons a joystick has
   int max_joybuttons;
-
+/*
   enum {
     MNID_KEY_UP,
     MNID_KEY_DOWN,
     MNID_KEY_LEFT,
     MNID_KEY_RIGHT,
     MNID_KEY_JUMP,
-    MNID_KEY_ACTION
+    MNID_KEY_ACTION,
+    MNID_KEY_CONSOLE
   };
   enum {
     MNID_JS_JUMP,
@@ -82,6 +85,7 @@ private:
     MNID_JS_MENU,
     MNID_JS_PAUSE
   };
+  */
   SDLKey reversemap_key(Control c);
   int reversemap_joybutton(Control c);
   void reset_joybutton(int button, Control c);