Added cheat menu keyboard and joystick bindings, only visible in developer mode
[supertux.git] / src / control / keyboard_config.cpp
1 //  SuperTux
2 //  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
3 //
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.
8 //
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.
13 //
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/>.
16
17 #include "control/keyboard_config.hpp"
18
19 #include "lisp/list_iterator.hpp"
20 #include "util/log.hpp"
21
22 KeyboardConfig::KeyboardConfig() :
23   keymap(),
24   jump_with_up_kbd(false)
25 {
26   // initialize default keyboard map
27   keymap[SDLK_LEFT]     = Controller::LEFT;
28   keymap[SDLK_RIGHT]    = Controller::RIGHT;
29   keymap[SDLK_UP]       = Controller::UP;
30   keymap[SDLK_DOWN]     = Controller::DOWN;
31   keymap[SDLK_SPACE]    = Controller::JUMP;
32   keymap[SDLK_LCTRL]    = Controller::ACTION;
33   keymap[SDLK_LALT]     = Controller::ACTION;
34   keymap[SDLK_ESCAPE]   = Controller::PAUSE_MENU;
35   keymap[SDLK_p]        = Controller::PAUSE_MENU;
36   keymap[SDLK_PAUSE]    = Controller::PAUSE_MENU;
37   keymap[SDLK_RETURN]   = Controller::MENU_SELECT;
38   keymap[SDLK_KP_ENTER] = Controller::MENU_SELECT;
39   keymap[SDLK_CARET]    = Controller::CONSOLE;
40   keymap[SDLK_DELETE]   = Controller::PEEK_LEFT;
41   keymap[SDLK_PAGEDOWN] = Controller::PEEK_RIGHT;
42   keymap[SDLK_HOME]     = Controller::PEEK_UP;
43   keymap[SDLK_END]      = Controller::PEEK_DOWN;
44   keymap[SDLK_F1]       = Controller::CHEAT_MENU;
45 }
46
47 void
48 KeyboardConfig::read(const lisp::Lisp& keymap_lisp)
49 {
50   // keycode values changed between SDL1 and SDL2, so we skip old SDL1
51   // based values and use the defaults instead on the first read of
52   // the config file
53   bool config_is_sdl2 = false;
54   keymap_lisp.get("sdl2", config_is_sdl2);
55   if (config_is_sdl2)
56   {
57     keymap.clear();
58     keymap_lisp.get("jump-with-up", jump_with_up_kbd);
59     lisp::ListIterator iter(&keymap_lisp);
60     while(iter.next())
61     {
62       if (iter.item() == "map")
63       {
64         int key = -1;
65         std::string control;
66         const lisp::Lisp* map = iter.lisp();
67         map->get("key", key);
68
69         map->get("control", control);
70
71         int i = 0;
72         for(i = 0; Controller::controlNames[i] != 0; ++i)
73         {
74           if (control == Controller::controlNames[i])
75             break;
76         }
77
78         if (Controller::controlNames[i] == 0)
79         {
80           log_info << "Invalid control '" << control << "' in keymap" << std::endl;
81           continue;
82         }
83         keymap[static_cast<SDL_Keycode>(key)] = static_cast<Controller::Control>(i);
84       }
85     }
86   }
87 }
88
89
90 void
91 KeyboardConfig::bind_key(SDL_Keycode key, Controller::Control control)
92 {
93   // remove all previous mappings for that control and for that key
94   for(KeyMap::iterator i = keymap.begin();
95       i != keymap.end();
96       /* no ++i */)
97   {
98     if (i->second == control)
99     {
100       KeyMap::iterator e = i;
101       ++i;
102       keymap.erase(e);
103     }
104     else
105     {
106       ++i;
107     }
108   }
109
110   KeyMap::iterator i = keymap.find(key);
111   if (i != keymap.end())
112     keymap.erase(i);
113
114   // add new mapping
115   keymap[key] = control;
116 }
117
118 SDL_Keycode
119 KeyboardConfig::reversemap_key(Controller::Control c)
120 {
121   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i)
122   {
123     if (i->second == c)
124     {
125       return i->first;
126     }
127   }
128
129   return SDLK_UNKNOWN;
130 }
131
132 void
133 KeyboardConfig::write(Writer& writer)
134 {
135   // this flag handles the transition from SDL1 to SDL2, as keycodes
136   // are incompatible between the two, if it's not set an old SDL1
137   // config file is assumed and controls are reset to default
138   writer.write("sdl2", true);
139
140   writer.write("jump-with-up", jump_with_up_kbd);
141
142   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i)
143   {
144     writer.start_list("map");
145     writer.write("key", (int) i->first);
146     writer.write("control", Controller::controlNames[i->second]);
147     writer.end_list("map");
148   }
149 }
150
151 /* EOF */