From 4b9d82b256a71b25636bee6a4f54142f8a5e757f Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Mon, 18 Aug 2014 04:50:10 +0200 Subject: [PATCH] Separate JoystickConfig out into a separate class that can be stored in the global Config object This should fix joystick/keyboard load/save support which broke in one of the last few commits --- src/control/input_manager.cpp | 37 +---- src/control/input_manager.hpp | 6 +- src/control/joystick_config.cpp | 243 ++++++++++++++++++++++++++++++ src/control/joystick_config.hpp | 68 +++++++++ src/control/joystick_manager.cpp | 288 ++++-------------------------------- src/control/joystick_manager.hpp | 35 +---- src/supertux/gameconfig.cpp | 25 +++- src/supertux/gameconfig.hpp | 4 +- src/supertux/main.cpp | 2 +- src/supertux/menu/joystick_menu.cpp | 11 +- 10 files changed, 383 insertions(+), 336 deletions(-) create mode 100644 src/control/joystick_config.cpp create mode 100644 src/control/joystick_config.hpp diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp index 6c7b12cc0..ce612d400 100644 --- a/src/control/input_manager.cpp +++ b/src/control/input_manager.cpp @@ -29,11 +29,12 @@ #include "util/log.hpp" #include "util/writer.hpp" -InputManager::InputManager(KeyboardConfig& keyboard_config) : +InputManager::InputManager(KeyboardConfig& keyboard_config, + JoystickConfig& joystick_config) : controller(new Controller), m_use_game_controller(true), keyboard_manager(new KeyboardManager(this, keyboard_config)), - joystick_manager(new JoystickManager(this)), + joystick_manager(new JoystickManager(this, joystick_config)), game_controller_manager(new GameControllerManager(this)) { } @@ -55,38 +56,6 @@ 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) - { - keyboard_manager->read(keymap_lisp); - } - - const lisp::Lisp* joystick_lisp = lisp.get_lisp(_("joystick")); - if (joystick_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 InputManager::update() { controller->update(); diff --git a/src/control/input_manager.hpp b/src/control/input_manager.hpp index 50e1de620..d047e537b 100644 --- a/src/control/input_manager.hpp +++ b/src/control/input_manager.hpp @@ -37,6 +37,7 @@ class KeyboardManager; class KeyboardMenu; class Menu; class KeyboardConfig; +class JoystickConfig; class InputManager final : public Currenton { @@ -47,13 +48,12 @@ private: typedef Controller::Control Control; public: - InputManager(KeyboardConfig& keyboard_config); + InputManager(KeyboardConfig& keyboard_config, + JoystickConfig& joystick_config); virtual ~InputManager(); void process_event(const SDL_Event& event); - void write(Writer& writer); - void read(const Reader& lisp); void update(); void reset(); diff --git a/src/control/joystick_config.cpp b/src/control/joystick_config.cpp new file mode 100644 index 000000000..e155cf119 --- /dev/null +++ b/src/control/joystick_config.cpp @@ -0,0 +1,243 @@ +// 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/joystick_config.hpp" + +#include + +#include "lisp/list_iterator.hpp" +#include "util/gettext.hpp" +#include "util/log.hpp" + +JoystickConfig::JoystickConfig() : + dead_zone(8000), + jump_with_up_joy(false), + joy_button_map(), + joy_axis_map(), + joy_hat_map() +{ + // Default joystick button configuration + bind_joybutton(0, 0, Controller::JUMP); + bind_joybutton(0, 0, Controller::MENU_SELECT); + bind_joybutton(0, 1, Controller::ACTION); + bind_joybutton(0, 4, Controller::PEEK_LEFT); + bind_joybutton(0, 5, Controller::PEEK_RIGHT); + bind_joybutton(0, 6, Controller::PAUSE_MENU); + + // Default joystick axis configuration + bind_joyaxis(0, -1, Controller::LEFT); + bind_joyaxis(0, 1, Controller::RIGHT); + bind_joyaxis(0, -2, Controller::UP); + bind_joyaxis(0, 2, Controller::DOWN); +} + +int +JoystickConfig::reversemap_joyaxis(Controller::Control c) +{ + for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { + if (i->second == c) + return i->first.second; + } + + return 0; +} + +int +JoystickConfig::reversemap_joybutton(Controller::Control c) +{ + for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) { + if (i->second == c) + return i->first.second; + } + + return -1; +} + +int +JoystickConfig::reversemap_joyhat(Controller::Control c) +{ + for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { + if (i->second == c) + return i->first.second; + } + + return -1; +} + +void +JoystickConfig::print_joystick_mappings() +{ + std::cout << _("Joystick Mappings") << std::endl; + std::cout << "-----------------" << std::endl; + for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { + std::cout << "Axis: " << i->first.second << " -> " << i->second << std::endl; + } + + for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) { + std::cout << "Button: " << i->first.second << " -> " << i->second << std::endl; + } + + for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { + std::cout << "Hat: " << i->first.second << " -> " << i->second << std::endl; + } + std::cout << std::endl; +} + +void +JoystickConfig::unbind_joystick_control(Controller::Control control) +{ + // remove all previous mappings for that control + for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) { + if (i->second == control) + joy_axis_map.erase(i++); + else + ++i; + } + + for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) { + if (i->second == control) + joy_button_map.erase(i++); + else + ++i; + } + + for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) { + if (i->second == control) + joy_hat_map.erase(i++); + else + ++i; + } +} + +void +JoystickConfig::bind_joyaxis(JoyId joy_id, int axis, Controller::Control control) +{ + // axis isn't the SDL axis number, but axisnumber + 1 with sign + // changed depending on if the positive or negative end is to be + // used (negative axis 0 becomes -1, positive axis 2 becomes +3, + // etc.) + + unbind_joystick_control(control); + + // add new mapping + joy_axis_map[std::make_pair(joy_id, axis)] = control; +} + +void +JoystickConfig::bind_joyhat(JoyId joy_id, int dir, Controller::Control c) +{ + unbind_joystick_control(c); + + // add new mapping + joy_hat_map[std::make_pair(joy_id, dir)] = c; +} + +void +JoystickConfig::bind_joybutton(JoyId joy_id, int button, Controller::Control control) +{ + unbind_joystick_control(control); + + // add new mapping + joy_button_map[std::make_pair(joy_id, button)] = control; +} + +void +JoystickConfig::read(const lisp::Lisp* joystick_lisp) +{ + joystick_lisp->get("dead-zone", dead_zone); + joystick_lisp->get("jump-with-up", jump_with_up_joy); + + lisp::ListIterator iter(joystick_lisp); + while(iter.next()) + { + if (iter.item() == "map") + { + int button = -1; + int axis = 0; + int hat = -1; + std::string control; + const lisp::Lisp* map = iter.lisp(); + + 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 buttonmap" << std::endl; + } + else + { + if (map->get("button", button)) + { + bind_joybutton(0, button, Controller::Control(i)); + } + else if (map->get("axis", axis)) + { + bind_joyaxis(0, axis, Controller::Control(i)); + } + else if (map->get("hat", hat)) + { + if (hat != SDL_HAT_UP && + hat != SDL_HAT_DOWN && + hat != SDL_HAT_LEFT && + hat != SDL_HAT_RIGHT) { + log_info << "Invalid axis '" << axis << "' in axismap" << std::endl; + } + else + { + bind_joyhat(0, hat, Controller::Control(i)); + } + } + } + } + } +} + +void +JoystickConfig::write(Writer& writer) +{ + writer.write("dead-zone", dead_zone); + writer.write("jump-with-up", jump_with_up_joy); + + for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); + ++i) { + writer.start_list("map"); + writer.write("button", i->first.second); + writer.write("control", Controller::controlNames[i->second]); + writer.end_list("map"); + } + + for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { + writer.start_list("map"); + writer.write("hat", i->first.second); + writer.write("control", Controller::controlNames[i->second]); + writer.end_list("map"); + } + + for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { + writer.start_list("map"); + writer.write("axis", i->first.second); + writer.write("control", Controller::controlNames[i->second]); + writer.end_list("map"); + } +} + +/* EOF */ diff --git a/src/control/joystick_config.hpp b/src/control/joystick_config.hpp new file mode 100644 index 000000000..80aa27593 --- /dev/null +++ b/src/control/joystick_config.hpp @@ -0,0 +1,68 @@ +// 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_JOYSTICK_CONFIG_HPP +#define HEADER_SUPERTUX_CONTROL_JOYSTICK_CONFIG_HPP + +#include +#include + +#include "control/controller.hpp" +#include "lisp/lisp.hpp" +#include "util/writer.hpp" + +class JoystickConfig +{ +public: + typedef Uint8 JoyId; + typedef std::map, Controller::Control> ButtonMap; + typedef std::map, Controller::Control> AxisMap; + typedef std::map, Controller::Control> HatMap; + +public: + int dead_zone; + bool jump_with_up_joy; + + ButtonMap joy_button_map; + AxisMap joy_axis_map; + HatMap joy_hat_map; + +public: + JoystickConfig(); + + void print_joystick_mappings(); + + int reversemap_joybutton(Controller::Control c); + int reversemap_joyaxis(Controller::Control c); + int reversemap_joyhat(Controller::Control c); + + void unbind_joystick_control(Controller::Control c); + + void bind_joybutton(JoyId joy_id, int button, Controller::Control c); + void bind_joyaxis(JoyId joy_id, int axis, Controller::Control c); + void bind_joyhat(JoyId joy_id, int dir, Controller::Control c); + + void read(const lisp::Lisp* joystick_lisp); + void write(Writer& writer); + +private: + JoystickConfig(const JoystickConfig&) = delete; + JoystickConfig& operator=(const JoystickConfig&) = delete; +}; + +#endif + +/* EOF */ diff --git a/src/control/joystick_manager.cpp b/src/control/joystick_manager.cpp index 5043b60fd..ebc164c7f 100644 --- a/src/control/joystick_manager.cpp +++ b/src/control/joystick_manager.cpp @@ -19,55 +19,27 @@ #include #include -#include "gui/menu_manager.hpp" #include "control/input_manager.hpp" +#include "control/joystick_config.hpp" +#include "gui/menu_manager.hpp" #include "lisp/list_iterator.hpp" #include "supertux/menu/joystick_menu.hpp" #include "util/gettext.hpp" #include "util/log.hpp" #include "util/writer.hpp" -JoystickManager::JoystickManager(InputManager* parent_) : +JoystickManager::JoystickManager(InputManager* parent_, + JoystickConfig& joystick_config) : parent(parent_), - joy_button_map(), - joy_axis_map(), - joy_hat_map(), - dead_zone(8000), + m_joystick_config(joystick_config), min_joybuttons(), max_joybuttons(), max_joyaxis(), max_joyhats(), hat_state(0), - jump_with_up_joy(false), wait_for_joystick(-1), joysticks() { - // Default joystick button configuration - bind_joybutton(0, 0, Controller::JUMP); - bind_joybutton(0, 1, Controller::ACTION); - // 6 or more Buttons - if( min_joybuttons > 5 ){ - bind_joybutton(0, 4, Controller::PEEK_LEFT); - bind_joybutton(0, 5, Controller::PEEK_RIGHT); - // 8 or more - if(min_joybuttons > 7) - bind_joybutton(0, min_joybuttons-1, Controller::PAUSE_MENU); - } else { - // map the last 2 buttons to menu and pause - if(min_joybuttons > 2) - bind_joybutton(0, min_joybuttons-1, Controller::PAUSE_MENU); - // map all remaining joystick buttons to MENU_SELECT - for(int i = 2; i < max_joybuttons; ++i) { - if(i != min_joybuttons-1) - bind_joybutton(0, i, Controller::MENU_SELECT); - } - } - - // Default joystick axis configuration - bind_joyaxis(0, -1, Controller::LEFT); - bind_joyaxis(0, 1, Controller::RIGHT); - bind_joyaxis(0, -2, Controller::UP); - bind_joyaxis(0, 2, Controller::DOWN); } JoystickManager::~JoystickManager() @@ -132,16 +104,16 @@ JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat) if (wait_for_joystick >= 0) { if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP) - bind_joyhat(jhat.which, SDL_HAT_UP, Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_UP, Controller::Control(wait_for_joystick)); if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN) - bind_joyhat(jhat.which, SDL_HAT_DOWN, Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_DOWN, Controller::Control(wait_for_joystick)); if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT) - bind_joyhat(jhat.which, SDL_HAT_LEFT, Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_LEFT, Controller::Control(wait_for_joystick)); if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT) - bind_joyhat(jhat.which, SDL_HAT_RIGHT, Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyhat(jhat.which, SDL_HAT_RIGHT, Controller::Control(wait_for_joystick)); MenuManager::instance().refresh(); wait_for_joystick = -1; @@ -150,29 +122,29 @@ JoystickManager::process_hat_event(const SDL_JoyHatEvent& jhat) { if (changed & SDL_HAT_UP) { - HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP)); - if (it != joy_hat_map.end()) + JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_UP)); + if (it != m_joystick_config.joy_hat_map.end()) set_joy_controls(it->second, jhat.value & SDL_HAT_UP); } if (changed & SDL_HAT_DOWN) { - HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN)); - if (it != joy_hat_map.end()) + JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_DOWN)); + if (it != m_joystick_config.joy_hat_map.end()) set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN); } if (changed & SDL_HAT_LEFT) { - HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT)); - if (it != joy_hat_map.end()) + JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_LEFT)); + if (it != m_joystick_config.joy_hat_map.end()) set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT); } if (changed & SDL_HAT_RIGHT) { - HatMap::iterator it = joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT)); - if (it != joy_hat_map.end()) + JoystickConfig::HatMap::iterator it = m_joystick_config.joy_hat_map.find(std::make_pair(jhat.which, SDL_HAT_RIGHT)); + if (it != m_joystick_config.joy_hat_map.end()) set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT); } } @@ -185,11 +157,11 @@ JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis) { if (wait_for_joystick >= 0) { - if (abs(jaxis.value) > dead_zone) { + if (abs(jaxis.value) > m_joystick_config.dead_zone) { if (jaxis.value < 0) - bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyaxis(jaxis.which, -(jaxis.axis + 1), Controller::Control(wait_for_joystick)); else - bind_joyaxis(jaxis.which, jaxis.axis + 1, Controller::Control(wait_for_joystick)); + m_joystick_config.bind_joyaxis(jaxis.which, jaxis.axis + 1, Controller::Control(wait_for_joystick)); MenuManager::instance().refresh(); wait_for_joystick = -1; @@ -201,22 +173,22 @@ JoystickManager::process_axis_event(const SDL_JoyAxisEvent& jaxis) // mapped separately (needed for jump/down vs up/down) int axis = jaxis.axis + 1; - AxisMap::iterator left = joy_axis_map.find(std::make_pair(jaxis.which, -axis)); - AxisMap::iterator right = joy_axis_map.find(std::make_pair(jaxis.which, axis)); + auto left = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, -axis)); + auto right = m_joystick_config.joy_axis_map.find(std::make_pair(jaxis.which, axis)); - if(left == joy_axis_map.end()) { + if(left == m_joystick_config.joy_axis_map.end()) { // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl; } else { - if (jaxis.value < -dead_zone) + if (jaxis.value < -m_joystick_config.dead_zone) set_joy_controls(left->second, true); else set_joy_controls(left->second, false); } - if(right == joy_axis_map.end()) { + if(right == m_joystick_config.joy_axis_map.end()) { // std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl; } else { - if (jaxis.value > dead_zone) + if (jaxis.value > m_joystick_config.dead_zone) set_joy_controls(right->second, true); else set_joy_controls(right->second, false); @@ -231,7 +203,7 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton) { if(jbutton.state == SDL_PRESSED) { - bind_joybutton(jbutton.which, jbutton.button, (Controller::Control)wait_for_joystick); + m_joystick_config.bind_joybutton(jbutton.which, jbutton.button, (Controller::Control)wait_for_joystick); MenuManager::instance().refresh(); parent->reset(); wait_for_joystick = -1; @@ -239,8 +211,8 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton) } else { - ButtonMap::iterator i = joy_button_map.find(std::make_pair(jbutton.which, jbutton.button)); - if(i == joy_button_map.end()) { + auto i = m_joystick_config.joy_button_map.find(std::make_pair(jbutton.which, jbutton.button)); + if(i == m_joystick_config.joy_button_map.end()) { log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl; } else { set_joy_controls(i->second, (jbutton.state == SDL_PRESSED)); @@ -248,209 +220,11 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton) } } - -int -JoystickManager::reversemap_joyaxis(Controller::Control c) -{ - for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { - if(i->second == c) - return i->first.second; - } - - return 0; -} - -int -JoystickManager::reversemap_joybutton(Controller::Control c) -{ - for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) { - if(i->second == c) - return i->first.second; - } - - return -1; -} - -int -JoystickManager::reversemap_joyhat(Controller::Control c) -{ - for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { - if(i->second == c) - return i->first.second; - } - - return -1; -} - -void -JoystickManager::print_joystick_mappings() -{ - std::cout << _("Joystick Mappings") << std::endl; - std::cout << "-----------------" << std::endl; - for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { - std::cout << "Axis: " << i->first.second << " -> " << i->second << std::endl; - } - - for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) { - std::cout << "Button: " << i->first.second << " -> " << i->second << std::endl; - } - - for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { - std::cout << "Hat: " << i->first.second << " -> " << i->second << std::endl; - } - std::cout << std::endl; -} - -void -JoystickManager::unbind_joystick_control(Controller::Control control) -{ - // remove all previous mappings for that control - for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) { - if(i->second == control) - joy_axis_map.erase(i++); - else - ++i; - } - - for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) { - if(i->second == control) - joy_button_map.erase(i++); - else - ++i; - } - - for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) { - if(i->second == control) - joy_hat_map.erase(i++); - else - ++i; - } -} - -void -JoystickManager::bind_joyaxis(JoyId joy_id, int axis, Controller::Control control) -{ - // axis isn't the SDL axis number, but axisnumber + 1 with sign - // changed depending on if the positive or negative end is to be - // used (negative axis 0 becomes -1, positive axis 2 becomes +3, - // etc.) - - unbind_joystick_control(control); - - // add new mapping - joy_axis_map[std::make_pair(joy_id, axis)] = control; -} - -void -JoystickManager::bind_joyhat(JoyId joy_id, int dir, Controller::Control c) -{ - unbind_joystick_control(c); - - // add new mapping - joy_hat_map[std::make_pair(joy_id, dir)] = c; -} - -void -JoystickManager::bind_joybutton(JoyId joy_id, int button, Controller::Control control) -{ - unbind_joystick_control(control); - - // add new mapping - joy_button_map[std::make_pair(joy_id, button)] = control; -} - -void -JoystickManager::read(const lisp::Lisp* joystick_lisp) -{ - joystick_lisp->get("dead-zone", dead_zone); - joystick_lisp->get("jump-with-up", jump_with_up_joy); - lisp::ListIterator iter(joystick_lisp); - while(iter.next()) { - if(iter.item() == _("map")) { - int button = -1; - int axis = 0; - int hat = -1; - std::string control; - const lisp::Lisp* map = iter.lisp(); - - 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 buttonmap" << std::endl; - continue; - } - - bool js_available = joysticks.size() > 0; - - if (map->get("button", button)) { - if(js_available && (button < 0 || button >= max_joybuttons)) { - log_info << "Invalid button '" << button << "' in buttonmap" << std::endl; - continue; - } - bind_joybutton(0, button, Controller::Control(i)); - } - - if (map->get("axis", axis)) { - if (js_available && (axis == 0 || abs(axis) > max_joyaxis)) { - log_info << "Invalid axis '" << axis << "' in axismap" << std::endl; - continue; - } - bind_joyaxis(0, axis, Controller::Control(i)); - } - - if (map->get("hat", hat)) { - if (js_available && - hat != SDL_HAT_UP && - hat != SDL_HAT_DOWN && - hat != SDL_HAT_LEFT && - hat != SDL_HAT_RIGHT) { - log_info << "Invalid axis '" << axis << "' in axismap" << std::endl; - continue; - } else { - bind_joyhat(0, hat, Controller::Control(i)); - } - } - } - } -} - -void -JoystickManager::write(Writer& writer) -{ - writer.write("dead-zone", dead_zone); - writer.write("jump-with-up", jump_with_up_joy); - - for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); - ++i) { - writer.start_list("map"); - writer.write("button", i->first.second); - writer.write("control", Controller::controlNames[i->second]); - writer.end_list("map"); - } - - for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) { - writer.start_list("map"); - writer.write("hat", i->first.second); - writer.write("control", Controller::controlNames[i->second]); - writer.end_list("map"); - } - - for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) { - writer.start_list("map"); - writer.write("axis", i->first.second); - writer.write("control", Controller::controlNames[i->second]); - writer.end_list("map"); - } -} - void JoystickManager::set_joy_controls(Controller::Control id, bool value) { - if (jump_with_up_joy && id == Controller::UP) + if (m_joystick_config.jump_with_up_joy && + id == Controller::UP) { parent->get_controller()->set_control(Controller::JUMP, value); } diff --git a/src/control/joystick_manager.hpp b/src/control/joystick_manager.hpp index 94acba089..898868ea2 100644 --- a/src/control/joystick_manager.hpp +++ b/src/control/joystick_manager.hpp @@ -28,24 +28,13 @@ #include "util/writer_fwd.hpp" class InputManager; +class JoystickConfig; class JoystickManager final { private: - typedef Uint8 JoyId; - - typedef std::map, Controller::Control> ButtonMap; - typedef std::map, Controller::Control> AxisMap; - typedef std::map, Controller::Control> HatMap; - -private: InputManager* parent; - - ButtonMap joy_button_map; - AxisMap joy_axis_map; - HatMap joy_hat_map; - - int dead_zone; + JoystickConfig& m_joystick_config; /// the number of buttons all joysticks have int min_joybuttons; @@ -59,42 +48,24 @@ private: Uint8 hat_state; public: - bool jump_with_up_joy; - -public: int wait_for_joystick; public: std::vector joysticks; public: - JoystickManager(InputManager* parent); + JoystickManager(InputManager* parent, JoystickConfig& joystick_config); ~JoystickManager(); void process_hat_event(const SDL_JoyHatEvent& jhat); void process_axis_event(const SDL_JoyAxisEvent& jaxis); void process_button_event(const SDL_JoyButtonEvent& jbutton); - void print_joystick_mappings(); - - int reversemap_joybutton(Controller::Control c); - int reversemap_joyaxis(Controller::Control c); - int reversemap_joyhat(Controller::Control c); - - void unbind_joystick_control(Controller::Control c); - - void bind_joybutton(JoyId joy_id, int button, Controller::Control c); - void bind_joyaxis(JoyId joy_id, int axis, Controller::Control c); - void bind_joyhat(JoyId joy_id, int dir, Controller::Control c); - void set_joy_controls(Controller::Control id, bool value); void on_joystick_added(int joystick_index); void on_joystick_removed(int instance_id); - void read(const lisp::Lisp* joystick_lisp); - void write(Writer& writer); - private: JoystickManager(const JoystickManager&) = delete; JoystickManager& operator=(const JoystickManager&) = delete; diff --git a/src/supertux/gameconfig.cpp b/src/supertux/gameconfig.cpp index bc6193b22..5dcb1c72e 100644 --- a/src/supertux/gameconfig.cpp +++ b/src/supertux/gameconfig.cpp @@ -45,7 +45,8 @@ Config::Config() : start_demo(), record_demo(), locale(), - keyboard_config() + keyboard_config(), + joystick_config() { } @@ -101,7 +102,17 @@ Config::load() const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control"); if (config_control_lisp) { - keyboard_config.read(*config_control_lisp); + const lisp::Lisp* keymap_lisp = config_control_lisp->get_lisp("keymap"); + if (keymap_lisp) + { + keyboard_config.read(*config_control_lisp); + } + + const lisp::Lisp* joystick_lisp = config_control_lisp->get_lisp("joystick"); + if (joystick_lisp) + { + joystick_config.read(joystick_lisp); + } } const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons"); @@ -148,7 +159,15 @@ Config::save() writer.end_list("audio"); writer.start_list("control"); - keyboard_config.write(writer); + { + writer.start_list("keymap"); + keyboard_config.write(writer); + writer.end_list("keymap"); + + writer.start_list("joystick"); + joystick_config.write(writer); + writer.end_list("joystick"); + } writer.end_list("control"); if (AddonManager::current()) diff --git a/src/supertux/gameconfig.hpp b/src/supertux/gameconfig.hpp index 298a2215f..0bcbf8834 100644 --- a/src/supertux/gameconfig.hpp +++ b/src/supertux/gameconfig.hpp @@ -17,9 +17,10 @@ #ifndef HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP #define HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP -#include "video/video_system.hpp" +#include "control/joystick_config.hpp" #include "control/keyboard_config.hpp" #include "math/size.hpp" +#include "video/video_system.hpp" class Config { @@ -69,6 +70,7 @@ public: std::string locale; KeyboardConfig keyboard_config; + JoystickConfig joystick_config; }; #endif diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 03f5b785f..0e3e32bcd 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -283,7 +283,7 @@ Main::launch_game() ConsoleBuffer console_buffer; timelog("controller"); - InputManager input_manager(g_config->keyboard_config); + InputManager input_manager(g_config->keyboard_config, g_config->joystick_config); timelog("commandline"); diff --git a/src/supertux/menu/joystick_menu.cpp b/src/supertux/menu/joystick_menu.cpp index 48678fa2a..96f8c7028 100644 --- a/src/supertux/menu/joystick_menu.cpp +++ b/src/supertux/menu/joystick_menu.cpp @@ -20,6 +20,7 @@ #include #include "control/joystick_manager.hpp" +#include "supertux/gameconfig.hpp" #include "util/gettext.hpp" namespace { @@ -75,7 +76,7 @@ JoystickMenu::recreate_menu() add_controlfield(Controller::PEEK_UP, _("Peek Up")); add_controlfield(Controller::PEEK_DOWN, _("Peek Down")); - add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), m_input_manager.joystick_manager->jump_with_up_joy); + add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), g_config->joystick_config.jump_with_up_joy); } else { @@ -116,7 +117,7 @@ JoystickMenu::menu_action(MenuItem* item) } else if (item->id == MNID_JUMP_WITH_UP) { - m_input_manager.joystick_manager->jump_with_up_joy = item->toggled; + g_config->joystick_config.jump_with_up_joy = item->toggled; } else if (item->id == MNID_AUTO_JOYSTICK_CFG) { @@ -134,9 +135,9 @@ JoystickMenu::menu_action(MenuItem* item) void JoystickMenu::refresh_menu_item(Controller::Control id) { - int button = m_input_manager.joystick_manager->reversemap_joybutton(id); - int axis = m_input_manager.joystick_manager->reversemap_joyaxis(id); - int hat_dir = m_input_manager.joystick_manager->reversemap_joyhat(id); + int button = g_config->joystick_config.reversemap_joybutton(id); + int axis = g_config->joystick_config.reversemap_joyaxis(id); + int hat_dir = g_config->joystick_config.reversemap_joyhat(id); if (button != -1) { -- 2.11.0