From 51ff37c5622618fd39354a12a80fc82a15c9eeb3 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Mon, 18 Aug 2014 04:08:08 +0200 Subject: [PATCH] Separate KeyboardConfig out into a separate class that can be stored in the global Config object --- src/control/input_manager.cpp | 8 +- src/control/input_manager.hpp | 3 +- src/control/keyboard_config.cpp | 151 ++++++++++++++++++++++++++++++++++++ src/control/keyboard_config.hpp | 46 +++++++++++ src/control/keyboard_manager.cpp | 123 +++-------------------------- src/control/keyboard_manager.hpp | 22 ++---- src/supertux/gameconfig.cpp | 18 ++--- src/supertux/gameconfig.hpp | 5 +- src/supertux/main.cpp | 8 +- src/supertux/menu/keyboard_menu.cpp | 54 ++++++------- 10 files changed, 265 insertions(+), 173 deletions(-) create mode 100644 src/control/keyboard_config.cpp create mode 100644 src/control/keyboard_config.hpp diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp index a4cad707e..6c7b12cc0 100644 --- a/src/control/input_manager.cpp +++ b/src/control/input_manager.cpp @@ -29,10 +29,10 @@ #include "util/log.hpp" #include "util/writer.hpp" -InputManager::InputManager() : +InputManager::InputManager(KeyboardConfig& keyboard_config) : controller(new Controller), m_use_game_controller(true), - keyboard_manager(new KeyboardManager(this)), + keyboard_manager(new KeyboardManager(this, keyboard_config)), joystick_manager(new JoystickManager(this)), game_controller_manager(new GameControllerManager(this)) { @@ -57,6 +57,7 @@ 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) { @@ -68,11 +69,13 @@ InputManager::read(const Reader& 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"); @@ -80,6 +83,7 @@ InputManager::write(Writer& writer) writer.start_list("joystick"); joystick_manager->write(writer); writer.end_list("joystick"); +#endif } void diff --git a/src/control/input_manager.hpp b/src/control/input_manager.hpp index 8b7ec190e..50e1de620 100644 --- a/src/control/input_manager.hpp +++ b/src/control/input_manager.hpp @@ -36,6 +36,7 @@ class JoystickMenu; class KeyboardManager; class KeyboardMenu; class Menu; +class KeyboardConfig; class InputManager final : public Currenton { @@ -46,7 +47,7 @@ private: typedef Controller::Control Control; public: - InputManager(); + InputManager(KeyboardConfig& keyboard_config); virtual ~InputManager(); void process_event(const SDL_Event& event); diff --git a/src/control/keyboard_config.cpp b/src/control/keyboard_config.cpp new file mode 100644 index 000000000..a844e4072 --- /dev/null +++ b/src/control/keyboard_config.cpp @@ -0,0 +1,151 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// 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 . + +#include "control/keyboard_config.hpp" + +#include "lisp/list_iterator.hpp" +#include "util/log.hpp" + +KeyboardConfig::KeyboardConfig() : + keymap(), + jump_with_up_kbd(false) +{ + // initialize default keyboard map + keymap[SDLK_LEFT] = Controller::LEFT; + keymap[SDLK_RIGHT] = Controller::RIGHT; + keymap[SDLK_UP] = Controller::UP; + keymap[SDLK_DOWN] = Controller::DOWN; + keymap[SDLK_SPACE] = Controller::JUMP; + keymap[SDLK_LCTRL] = Controller::ACTION; + keymap[SDLK_LALT] = Controller::ACTION; + keymap[SDLK_ESCAPE] = Controller::PAUSE_MENU; + keymap[SDLK_p] = Controller::PAUSE_MENU; + keymap[SDLK_PAUSE] = Controller::PAUSE_MENU; + keymap[SDLK_RETURN] = Controller::MENU_SELECT; + keymap[SDLK_KP_ENTER] = Controller::MENU_SELECT; + keymap[SDLK_CARET] = Controller::CONSOLE; + keymap[SDLK_DELETE] = Controller::PEEK_LEFT; + keymap[SDLK_PAGEDOWN] = Controller::PEEK_RIGHT; + keymap[SDLK_HOME] = Controller::PEEK_UP; + keymap[SDLK_END] = Controller::PEEK_DOWN; + keymap[SDLK_TAB] = Controller::CHEAT_MENU; +} + +void +KeyboardConfig::read(const lisp::Lisp& keymap_lisp) +{ + // keycode values changed between SDL1 and SDL2, so we skip old SDL1 + // based values and use the defaults instead on the first read of + // the config file + bool config_is_sdl2 = false; + keymap_lisp.get("sdl2", config_is_sdl2); + if (config_is_sdl2) + { + keymap.clear(); + keymap_lisp.get("jump-with-up", jump_with_up_kbd); + lisp::ListIterator iter(&keymap_lisp); + while(iter.next()) + { + if (iter.item() == "map") + { + int key = -1; + std::string control; + const lisp::Lisp* map = iter.lisp(); + map->get("key", key); + + 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 keymap" << std::endl; + continue; + } + keymap[static_cast(key)] = static_cast(i); + } + } + } +} + + +void +KeyboardConfig::bind_key(SDL_Keycode key, Controller::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) + { + KeyMap::iterator e = i; + ++i; + keymap.erase(e); + } + else + { + ++i; + } + } + + KeyMap::iterator i = keymap.find(key); + if (i != keymap.end()) + keymap.erase(i); + + // add new mapping + keymap[key] = control; +} + +SDL_Keycode +KeyboardConfig::reversemap_key(Controller::Control c) +{ + for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) + { + if (i->second == c) + { + return i->first; + } + } + + return SDLK_UNKNOWN; +} + +void +KeyboardConfig::write(Writer& writer) +{ + // this flag handles the transition from SDL1 to SDL2, as keycodes + // are incompatible between the two, if it's not set an old SDL1 + // config file is assumed and controls are reset to default + writer.write("sdl2", true); + + writer.write("jump-with-up", jump_with_up_kbd); + + for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) + { + writer.start_list("map"); + writer.write("key", (int) i->first); + writer.write("control", Controller::controlNames[i->second]); + writer.end_list("map"); + } +} + +/* EOF */ diff --git a/src/control/keyboard_config.hpp b/src/control/keyboard_config.hpp new file mode 100644 index 000000000..e8480670f --- /dev/null +++ b/src/control/keyboard_config.hpp @@ -0,0 +1,46 @@ +// SuperTux +// Copyright (C) 2014 Ingo Ruhnke +// +// 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 . + +#ifndef HEADER_SUPERTUX_CONTROL_KEYBOARD_CONFIG_HPP +#define HEADER_SUPERTUX_CONTROL_KEYBOARD_CONFIG_HPP + +#include +#include + +#include "control/controller.hpp" +#include "lisp/lisp.hpp" + +#include "util/writer.hpp" + +class KeyboardConfig +{ +public: + KeyboardConfig(); + + SDL_Keycode reversemap_key(Controller::Control c); + void bind_key(SDL_Keycode key, Controller::Control c); + + void read(const lisp::Lisp& keymap_lisp); + void write(Writer& writer); + + typedef std::map KeyMap; + KeyMap keymap; + bool jump_with_up_kbd; +}; + +#endif + +/* EOF */ diff --git a/src/control/keyboard_manager.cpp b/src/control/keyboard_manager.cpp index 32c947a43..d088dc0cc 100644 --- a/src/control/keyboard_manager.cpp +++ b/src/control/keyboard_manager.cpp @@ -19,6 +19,7 @@ #include "control/controller.hpp" #include "control/joystick_manager.hpp" +#include "control/keyboard_config.hpp" #include "gui/menu_manager.hpp" #include "lisp/list_iterator.hpp" #include "supertux/console.hpp" @@ -27,31 +28,12 @@ #include "supertux/menu/menu_storage.hpp" #include "util/writer.hpp" -KeyboardManager::KeyboardManager(InputManager* parent) : +KeyboardManager::KeyboardManager(InputManager* parent, + KeyboardConfig& keyboard_config) : m_parent(parent), - keymap(), - jump_with_up_kbd(false), + m_keyboard_config(keyboard_config), wait_for_key(-1) { - // initialize default keyboard map - keymap[SDLK_LEFT] = Controller::LEFT; - keymap[SDLK_RIGHT] = Controller::RIGHT; - keymap[SDLK_UP] = Controller::UP; - keymap[SDLK_DOWN] = Controller::DOWN; - keymap[SDLK_SPACE] = Controller::JUMP; - keymap[SDLK_LCTRL] = Controller::ACTION; - keymap[SDLK_LALT] = Controller::ACTION; - keymap[SDLK_ESCAPE] = Controller::PAUSE_MENU; - keymap[SDLK_p] = Controller::PAUSE_MENU; - keymap[SDLK_PAUSE] = Controller::PAUSE_MENU; - keymap[SDLK_RETURN] = Controller::MENU_SELECT; - keymap[SDLK_KP_ENTER] = Controller::MENU_SELECT; - keymap[SDLK_CARET] = Controller::CONSOLE; - keymap[SDLK_DELETE] = Controller::PEEK_LEFT; - keymap[SDLK_PAGEDOWN] = Controller::PEEK_RIGHT; - keymap[SDLK_HOME] = Controller::PEEK_UP; - keymap[SDLK_END] = Controller::PEEK_DOWN; - keymap[SDLK_TAB] = Controller::CHEAT_MENU; } KeyboardManager::~KeyboardManager() @@ -61,10 +43,10 @@ KeyboardManager::~KeyboardManager() void KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) { - KeyMap::iterator key_mapping = keymap.find(event.keysym.sym); + KeyboardConfig::KeyMap::iterator key_mapping = m_keyboard_config.keymap.find(event.keysym.sym); // if console key was pressed: toggle console - if (key_mapping != keymap.end() && + if (key_mapping != m_keyboard_config.keymap.end() && key_mapping->second == Controller::CONSOLE) { if (event.type == SDL_KEYDOWN) @@ -82,7 +64,7 @@ KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) // if menu mode: send key there process_menu_key_event(event); } - else if (key_mapping == keymap.end()) + else if (key_mapping == m_keyboard_config.keymap.end()) { // default action: update controls //log_debug << "Key " << event.key.SDL_Keycode.sym << " is unbound" << std::endl; @@ -92,7 +74,7 @@ KeyboardManager::process_key_event(const SDL_KeyboardEvent& event) auto control = key_mapping->second; bool value = (event.type == SDL_KEYDOWN); m_parent->get_controller()->set_control(control, value); - if (jump_with_up_kbd && control == Controller::UP) + if (m_keyboard_config.jump_with_up_kbd && control == Controller::UP) { m_parent->get_controller()->set_control(Controller::JUMP, value); } @@ -166,7 +148,7 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) if (event.keysym.sym != SDLK_ESCAPE && event.keysym.sym != SDLK_PAUSE) { - bind_key(event.keysym.sym, static_cast(wait_for_key)); + m_keyboard_config.bind_key(event.keysym.sym, static_cast(wait_for_key)); } m_parent->reset(); MenuManager::instance().refresh(); @@ -219,91 +201,4 @@ KeyboardManager::process_menu_key_event(const SDL_KeyboardEvent& event) m_parent->get_controller()->set_control(control, (event.type == SDL_KEYDOWN)); } -void -KeyboardManager::bind_key(SDL_Keycode key, Controller::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) { - KeyMap::iterator e = i; - ++i; - keymap.erase(e); - } else { - ++i; - } - } - - KeyMap::iterator i = keymap.find(key); - if (i != keymap.end()) - keymap.erase(i); - - // add new mapping - keymap[key] = control; -} - -SDL_Keycode -KeyboardManager::reversemap_key(Controller::Control c) -{ - for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) - { - if (i->second == c) - { - return i->first; - } - } - - return SDLK_UNKNOWN; -} - -void -KeyboardManager::read(const lisp::Lisp* keymap_lisp) -{ - // keycode values changed between SDL1 and SDL2, so we skip old SDL1 - // based values and use the defaults instead on the first read of - // the config file - bool config_is_sdl2 = false; - keymap_lisp->get("sdl2", config_is_sdl2); - if (config_is_sdl2) - { - keymap.clear(); - keymap_lisp->get("jump-with-up", jump_with_up_kbd); - lisp::ListIterator iter(keymap_lisp); - while(iter.next()) { - if (iter.item() == "map") { - int key = -1; - std::string control; - const lisp::Lisp* map = iter.lisp(); - map->get("key", key); - - 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 keymap" << std::endl; - continue; - } - keymap[static_cast(key)] = static_cast(i); - } - } - } -} - -void -KeyboardManager::write(Writer& writer) -{ - writer.write("sdl2", true); - writer.write("jump-with-up", jump_with_up_kbd); - for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) { - writer.start_list("map"); - writer.write("key", (int) i->first); - writer.write("control", Controller::controlNames[i->second]); - writer.end_list("map"); - } -} - /* EOF */ diff --git a/src/control/keyboard_manager.hpp b/src/control/keyboard_manager.hpp index cae55d479..9ddaba308 100644 --- a/src/control/keyboard_manager.hpp +++ b/src/control/keyboard_manager.hpp @@ -27,15 +27,19 @@ #include "util/writer_fwd.hpp" class InputManager; +class KeyboardConfig; class KeyboardManager final { private: - friend class KeyboardMenu; - typedef std::map KeyMap; + InputManager* m_parent; + KeyboardConfig& m_keyboard_config; public: - KeyboardManager(InputManager* parent); + int wait_for_key; + +public: + KeyboardManager(InputManager* parent, KeyboardConfig& keyboard_config); ~KeyboardManager(); void process_key_event(const SDL_KeyboardEvent& event); @@ -43,18 +47,6 @@ public: void process_console_key_event(const SDL_KeyboardEvent& event); void process_menu_key_event(const SDL_KeyboardEvent& event); - SDL_Keycode reversemap_key(Controller::Control c); - void bind_key(SDL_Keycode key, Controller::Control c); - - void read(const lisp::Lisp* keymap_lisp); - void write(Writer& writer); - -private: - InputManager* m_parent; - KeyMap keymap; - bool jump_with_up_kbd; - int wait_for_key; - private: KeyboardManager(const KeyboardManager&) = delete; KeyboardManager& operator=(const KeyboardManager&) = delete; diff --git a/src/supertux/gameconfig.cpp b/src/supertux/gameconfig.cpp index 8df30bba1..bc6193b22 100644 --- a/src/supertux/gameconfig.cpp +++ b/src/supertux/gameconfig.cpp @@ -44,7 +44,8 @@ Config::Config() : enable_script_debugger(false), start_demo(), record_demo(), - locale() + locale(), + keyboard_config() { } @@ -98,13 +99,13 @@ Config::load() } const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control"); - if(config_control_lisp && InputManager::current()) + if (config_control_lisp) { - InputManager::current()->read(*config_control_lisp); + keyboard_config.read(*config_control_lisp); } const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons"); - if(config_addons_lisp && AddonManager::current()) + if (config_addons_lisp && AddonManager::current()) { AddonManager::current()->read(*config_addons_lisp); } @@ -146,12 +147,9 @@ Config::save() writer.write("music_enabled", music_enabled); writer.end_list("audio"); - if (InputManager::current()) - { - writer.start_list("control"); - InputManager::current()->write(writer); - writer.end_list("control"); - } + writer.start_list("control"); + keyboard_config.write(writer); + writer.end_list("control"); if (AddonManager::current()) { diff --git a/src/supertux/gameconfig.hpp b/src/supertux/gameconfig.hpp index ee032d45a..298a2215f 100644 --- a/src/supertux/gameconfig.hpp +++ b/src/supertux/gameconfig.hpp @@ -18,6 +18,7 @@ #define HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP #include "video/video_system.hpp" +#include "control/keyboard_config.hpp" #include "math/size.hpp" class Config @@ -65,7 +66,9 @@ public: /** force SuperTux language to this locale, e.g. "de". A file "data/locale/xx.po" must exist for this to work. An empty string means autodetect. */ - std::string locale; + std::string locale; + + KeyboardConfig keyboard_config; }; #endif diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 5fc1db113..03f5b785f 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -64,8 +64,8 @@ public: g_config.reset(new Config); try { g_config->load(); - } - catch(const std::exception& e) + } + catch(const std::exception& e) { log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl; } @@ -83,7 +83,7 @@ public: { g_config->save(); } - g_config.reset(); + g_config.reset(); } }; @@ -283,7 +283,7 @@ Main::launch_game() ConsoleBuffer console_buffer; timelog("controller"); - InputManager input_manager; + InputManager input_manager(g_config->keyboard_config); timelog("commandline"); diff --git a/src/supertux/menu/keyboard_menu.cpp b/src/supertux/menu/keyboard_menu.cpp index e1c4d28da..3750a6e07 100644 --- a/src/supertux/menu/keyboard_menu.cpp +++ b/src/supertux/menu/keyboard_menu.cpp @@ -40,7 +40,7 @@ KeyboardMenu::KeyboardMenu(InputManager& input_manager) : if (g_config->console_enabled) { add_controlfield(Controller::CONSOLE, _("Console")); } - add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), m_input_manager.keyboard_manager->jump_with_up_kbd); + add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), g_config->keyboard_config.jump_with_up_kbd); add_hl(); add_back(_("Back")); refresh(); @@ -91,40 +91,42 @@ KeyboardMenu::menu_action(MenuItem* item) item->change_input(_("Press Key")); m_input_manager.keyboard_manager->wait_for_key = item->id; } else if( item->id == Controller::CONTROLCOUNT) { - m_input_manager.keyboard_manager->jump_with_up_kbd = item->toggled; + g_config->keyboard_config.jump_with_up_kbd = item->toggled; } } void KeyboardMenu::refresh() { - auto& kbd_mgr = m_input_manager.keyboard_manager; + KeyboardConfig& kbd_cfg = g_config->keyboard_config; - get_item_by_id((int) Controller::UP).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::UP))); - get_item_by_id((int) Controller::DOWN).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::DOWN))); - get_item_by_id((int) Controller::LEFT).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::LEFT))); - get_item_by_id((int) Controller::RIGHT).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::RIGHT))); - get_item_by_id((int) Controller::JUMP).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::JUMP))); - get_item_by_id((int) Controller::ACTION).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::ACTION))); - get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::PEEK_LEFT))); - get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::PEEK_RIGHT))); - get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::PEEK_UP))); - get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::PEEK_DOWN))); - if (g_config->console_enabled) { + get_item_by_id((int) Controller::UP) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::UP))); + get_item_by_id((int) Controller::DOWN) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::DOWN))); + get_item_by_id((int) Controller::LEFT) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::LEFT))); + get_item_by_id((int) Controller::RIGHT) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::RIGHT))); + get_item_by_id((int) Controller::JUMP) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::JUMP))); + get_item_by_id((int) Controller::ACTION) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::ACTION))); + get_item_by_id((int) Controller::PEEK_LEFT) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::PEEK_LEFT))); + get_item_by_id((int) Controller::PEEK_RIGHT) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::PEEK_RIGHT))); + get_item_by_id((int) Controller::PEEK_UP) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::PEEK_UP))); + get_item_by_id((int) Controller::PEEK_DOWN) + .change_input(get_key_name(kbd_cfg.reversemap_key(Controller::PEEK_DOWN))); + + if (g_config->console_enabled) + { get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name( - kbd_mgr->reversemap_key(Controller::CONSOLE))); + kbd_cfg.reversemap_key(Controller::CONSOLE))); } - get_item_by_id(Controller::CONTROLCOUNT).toggled = kbd_mgr->jump_with_up_kbd; + get_item_by_id(Controller::CONTROLCOUNT).toggled = kbd_cfg.jump_with_up_kbd; } /* EOF */ -- 2.11.0