#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))
{
void
InputManager::read(const Reader& lisp)
{
+#ifdef GRUMBEL
const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
if (keymap_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");
writer.start_list("joystick");
joystick_manager->write(writer);
writer.end_list("joystick");
+#endif
}
void
class KeyboardManager;
class KeyboardMenu;
class Menu;
+class KeyboardConfig;
class InputManager final : public Currenton<InputManager>
{
typedef Controller::Control Control;
public:
- InputManager();
+ InputManager(KeyboardConfig& keyboard_config);
virtual ~InputManager();
void process_event(const SDL_Event& event);
--- /dev/null
+// SuperTux
+// Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+// 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/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<SDL_Keycode>(key)] = static_cast<Controller::Control>(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 */
--- /dev/null
+// SuperTux
+// Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
+//
+// 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_KEYBOARD_CONFIG_HPP
+#define HEADER_SUPERTUX_CONTROL_KEYBOARD_CONFIG_HPP
+
+#include <SDL.h>
+#include <map>
+
+#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<SDL_Keycode, Controller::Control> KeyMap;
+ KeyMap keymap;
+ bool jump_with_up_kbd;
+};
+
+#endif
+
+/* EOF */
#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"
#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()
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)
// 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;
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);
}
if (event.keysym.sym != SDLK_ESCAPE &&
event.keysym.sym != SDLK_PAUSE)
{
- bind_key(event.keysym.sym, static_cast<Controller::Control>(wait_for_key));
+ m_keyboard_config.bind_key(event.keysym.sym, static_cast<Controller::Control>(wait_for_key));
}
m_parent->reset();
MenuManager::instance().refresh();
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<SDL_Keycode>(key)] = static_cast<Controller::Control>(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 */
#include "util/writer_fwd.hpp"
class InputManager;
+class KeyboardConfig;
class KeyboardManager final
{
private:
- friend class KeyboardMenu;
- typedef std::map<SDL_Keycode, Controller::Control> 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);
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;
enable_script_debugger(false),
start_demo(),
record_demo(),
- locale()
+ locale(),
+ keyboard_config()
{
}
}
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);
}
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())
{
#define HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP
#include "video/video_system.hpp"
+#include "control/keyboard_config.hpp"
#include "math/size.hpp"
class Config
/** 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
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;
}
{
g_config->save();
}
- g_config.reset();
+ g_config.reset();
}
};
ConsoleBuffer console_buffer;
timelog("controller");
- InputManager input_manager;
+ InputManager input_manager(g_config->keyboard_config);
timelog("commandline");
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();
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 */