From: Christoph Sommer Date: Sat, 8 Apr 2006 22:52:30 +0000 (+0000) Subject: Yet another Console commit / X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=60c295a36ec43b45586c198b88b9d0ded3336a67;p=supertux.git Yet another Console commit / 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 --- diff --git a/src/console.cpp b/src/console.cpp index 62d264cd4..8a330b910 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -88,20 +88,19 @@ Console::autocomplete() std::string cmdList = ""; int cmdListLen = 0; - for (std::map::iterator i = commands.begin(); i != commands.end(); i++) { + for (std::map >::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 >::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 >::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::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 Console::lines; -std::map Console::commands; +std::map > Console::commands; ConsoleStreamBuffer Console::inputBuffer; ConsoleStreamBuffer Console::outputBuffer; std::ostream Console::input(&Console::inputBuffer); diff --git a/src/console.hpp b/src/console.hpp index 4d9ae0d39..53267b34c 100644 --- a/src/console.hpp +++ b/src/console.hpp @@ -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 lines; /**< backbuffer of lines sent to the console */ - static std::map commands; /**< map of console commands and their associated ConsoleCommandReceivers */ + static std::map > 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 */ diff --git a/src/control/controller.cpp b/src/control/controller.cpp index db924af7d..e7fe38368 100644 --- a/src/control/controller.cpp +++ b/src/control/controller.cpp @@ -33,6 +33,7 @@ const char* Controller::controlNames[] = { "action", "pause-menu", "menu-select", + "console", 0 }; diff --git a/src/control/controller.hpp b/src/control/controller.hpp index f320825c8..3e37cf728 100644 --- a/src/control/controller.hpp +++ b/src/control/controller.hpp @@ -35,6 +35,7 @@ public: ACTION, PAUSE_MENU, MENU_SELECT, + CONSOLE, CONTROLCOUNT }; diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp index 8e715f01a..776266b3c 100644 --- a/src/control/joystickkeyboardcontroller.cpp +++ b/src/control/joystickkeyboardcontroller.cpp @@ -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? diff --git a/src/control/joystickkeyboardcontroller.hpp b/src/control/joystickkeyboardcontroller.hpp index 3f3499729..90930ead6 100644 --- a/src/control/joystickkeyboardcontroller.hpp +++ b/src/control/joystickkeyboardcontroller.hpp @@ -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 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);