Revert ca83136
[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::ESCAPE;
35   keymap[SDLK_p]        = Controller::START;
36   keymap[SDLK_PAUSE]    = Controller::START;
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_lisp.get("jump-with-up", jump_with_up_kbd);
58     lisp::ListIterator iter(&keymap_lisp);
59     while(iter.next())
60     {
61       if (iter.item() == "map")
62       {
63         int key = -1;
64         std::string control;
65         const lisp::Lisp* map = iter.lisp();
66         map->get("key", key);
67
68         map->get("control", control);
69
70         int i = 0;
71         for(i = 0; Controller::controlNames[i] != 0; ++i)
72         {
73           if (control == Controller::controlNames[i])
74             break;
75         }
76
77         if (Controller::controlNames[i] == 0)
78         {
79           log_info << "Invalid control '" << control << "' in keymap" << std::endl;
80           continue;
81         }
82         keymap[static_cast<SDL_Keycode>(key)] = static_cast<Controller::Control>(i);
83       }
84     }
85   }
86 }
87
88
89 void
90 KeyboardConfig::bind_key(SDL_Keycode key, Controller::Control control)
91 {
92   // remove all previous mappings for that control and for that key
93   for(KeyMap::iterator i = keymap.begin();
94       i != keymap.end();
95       /* no ++i */)
96   {
97     if (i->second == control)
98     {
99       KeyMap::iterator e = i;
100       ++i;
101       keymap.erase(e);
102     }
103     else
104     {
105       ++i;
106     }
107   }
108
109   KeyMap::iterator i = keymap.find(key);
110   if (i != keymap.end())
111     keymap.erase(i);
112
113   // add new mapping
114   keymap[key] = control;
115 }
116
117 SDL_Keycode
118 KeyboardConfig::reversemap_key(Controller::Control c)
119 {
120   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i)
121   {
122     if (i->second == c)
123     {
124       return i->first;
125     }
126   }
127
128   return SDLK_UNKNOWN;
129 }
130
131 void
132 KeyboardConfig::write(Writer& writer)
133 {
134   // this flag handles the transition from SDL1 to SDL2, as keycodes
135   // are incompatible between the two, if it's not set an old SDL1
136   // config file is assumed and controls are reset to default
137   writer.write("sdl2", true);
138
139   writer.write("jump-with-up", jump_with_up_kbd);
140
141   for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i)
142   {
143     writer.start_list("map");
144     writer.write("key", (int) i->first);
145     writer.write("control", Controller::controlNames[i->second]);
146     writer.end_list("map");
147   }
148 }
149
150 /* EOF */