2 // Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "control/joystick_config.hpp"
21 #include "lisp/list_iterator.hpp"
22 #include "util/gettext.hpp"
23 #include "util/log.hpp"
25 JoystickConfig::JoystickConfig() :
27 jump_with_up_joy(false),
32 // Default joystick button configuration
33 bind_joybutton(0, 0, Controller::JUMP);
34 bind_joybutton(0, 0, Controller::MENU_SELECT);
35 bind_joybutton(0, 1, Controller::ACTION);
36 bind_joybutton(0, 4, Controller::PEEK_LEFT);
37 bind_joybutton(0, 5, Controller::PEEK_RIGHT);
38 bind_joybutton(0, 6, Controller::PAUSE_MENU);
40 // Default joystick axis configuration
41 bind_joyaxis(0, -1, Controller::LEFT);
42 bind_joyaxis(0, 1, Controller::RIGHT);
43 bind_joyaxis(0, -2, Controller::UP);
44 bind_joyaxis(0, 2, Controller::DOWN);
48 JoystickConfig::reversemap_joyaxis(Controller::Control c)
50 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
52 return i->first.second;
59 JoystickConfig::reversemap_joybutton(Controller::Control c)
61 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
63 return i->first.second;
70 JoystickConfig::reversemap_joyhat(Controller::Control c)
72 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
74 return i->first.second;
81 JoystickConfig::print_joystick_mappings()
83 std::cout << _("Joystick Mappings") << std::endl;
84 std::cout << "-----------------" << std::endl;
85 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
86 std::cout << "Axis: " << i->first.second << " -> " << i->second << std::endl;
89 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
90 std::cout << "Button: " << i->first.second << " -> " << i->second << std::endl;
93 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
94 std::cout << "Hat: " << i->first.second << " -> " << i->second << std::endl;
96 std::cout << std::endl;
100 JoystickConfig::unbind_joystick_control(Controller::Control control)
102 // remove all previous mappings for that control
103 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
104 if (i->second == control)
105 joy_axis_map.erase(i++);
110 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
111 if (i->second == control)
112 joy_button_map.erase(i++);
117 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
118 if (i->second == control)
119 joy_hat_map.erase(i++);
126 JoystickConfig::bind_joyaxis(JoyId joy_id, int axis, Controller::Control control)
128 // axis isn't the SDL axis number, but axisnumber + 1 with sign
129 // changed depending on if the positive or negative end is to be
130 // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
133 unbind_joystick_control(control);
136 joy_axis_map[std::make_pair(joy_id, axis)] = control;
140 JoystickConfig::bind_joyhat(JoyId joy_id, int dir, Controller::Control c)
142 unbind_joystick_control(c);
145 joy_hat_map[std::make_pair(joy_id, dir)] = c;
149 JoystickConfig::bind_joybutton(JoyId joy_id, int button, Controller::Control control)
151 unbind_joystick_control(control);
154 joy_button_map[std::make_pair(joy_id, button)] = control;
158 JoystickConfig::read(const lisp::Lisp& joystick_lisp)
160 joystick_lisp.get("dead-zone", dead_zone);
161 joystick_lisp.get("jump-with-up", jump_with_up_joy);
163 lisp::ListIterator iter(&joystick_lisp);
166 if (iter.item() == "map")
172 const lisp::Lisp* map = iter.lisp();
174 map->get("control", control);
176 for(i = 0; Controller::controlNames[i] != 0; ++i)
178 if (control == Controller::controlNames[i])
182 if (Controller::controlNames[i] == 0)
184 log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
188 if (map->get("button", button))
190 bind_joybutton(0, button, Controller::Control(i));
192 else if (map->get("axis", axis))
194 bind_joyaxis(0, axis, Controller::Control(i));
196 else if (map->get("hat", hat))
198 if (hat != SDL_HAT_UP &&
199 hat != SDL_HAT_DOWN &&
200 hat != SDL_HAT_LEFT &&
201 hat != SDL_HAT_RIGHT) {
202 log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
206 bind_joyhat(0, hat, Controller::Control(i));
215 JoystickConfig::write(Writer& writer)
217 writer.write("dead-zone", dead_zone);
218 writer.write("jump-with-up", jump_with_up_joy);
220 for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
222 writer.start_list("map");
223 writer.write("button", i->first.second);
224 writer.write("control", Controller::controlNames[i->second]);
225 writer.end_list("map");
228 for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
229 writer.start_list("map");
230 writer.write("hat", i->first.second);
231 writer.write("control", Controller::controlNames[i->second]);
232 writer.end_list("map");
235 for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
236 writer.start_list("map");
237 writer.write("axis", i->first.second);
238 writer.write("control", Controller::controlNames[i->second]);
239 writer.end_list("map");