3f370e3329ffa3ef9e71f7df4dfe064a0fa4c84a
[physics.git] / src / config / reader.cpp
1 /*
2  *  Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) 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
18 #include "reader.h"
19
20 #include <pg/debug.h>
21
22 #include <iostream>
23 using std::cerr;
24 using std::cout;
25 using std::endl;
26
27 #include <fstream>
28 #include <string>
29
30 #include "keys.h"
31
32 using std::ifstream;
33 using std::string;
34
35 typedef std::map<string, SDLKey> kMap;
36 kMap keyMap;
37
38 /// ***** Private Method Headers *****
39
40 void processLine(const string& str);
41 bool extractLine(const string& str, string* name, string* value);
42 void createKeyMap();
43
44 /// ***** Private Variables *****
45
46 const char* configDir = "configs/";
47 const char* testFile = "keys.cfg";
48
49 /// ***** Public Methods *****
50
51 void readConfigs()
52 {
53     char fileName[64];
54
55     createKeyMap();
56
57     strcpy(fileName, configDir);
58     strcat(fileName, testFile);
59
60     ifstream file(fileName);
61
62     if( !file.is_open() )
63     {
64         cerr << "Unable to open file " << fileName << "." << endl;
65         exit(1);
66     }
67
68     while(true)
69     {
70         string line;
71         getline(file, line);
72
73         if(file.eof())
74             break;
75
76         processLine(line);
77     }
78
79     file.close();
80 }
81
82 /// ***** Private Methods *****
83
84 void processLine(const string& str)
85 {
86     string name;
87     string value;
88
89     bool extracted;
90
91     extracted = extractLine(str, &name, &value);
92
93     if(extracted)
94     {
95         SDLKey key = keyMap[value];
96
97         if(0 != key)
98         {
99             *(key::sdlMap[name]) = key;
100         }
101     }
102 }
103
104 /*
105  * Return true iff the string str, had a name and value extracted and saved in
106  * name and value. Otherwise return false and leave name and value alone.
107  */
108 bool extractLine(const string& str, string* name, string* value)
109 {
110     /*
111      * state    := 0 if eating leading name whitespace
112      *          := 1 if saving name
113      *          := 2 if eating trailing name whitespace
114      *          := 3 if eating leading value whitespace
115      *          := 4 if saving value
116      *          := 5 if all is done and well
117      */
118     int state = 0;
119
120     int char_pos = 0;
121
122     int name_start = 0;
123     int name_end = 0;
124
125     int value_start = 0;
126     int value_end = 0;
127
128     const char* c_str = str.c_str();
129
130     while(true)
131     {
132         if(c_str[char_pos] == 0 && state != 4)
133             return false;
134
135         switch (state)
136         {
137             case 0:
138                 if(c_str[char_pos] != ' '
139                 && c_str[char_pos] != '\t')
140                 {
141                     state++;
142                     name_start = char_pos;
143                 }
144                 break;
145             case 1:
146                 if(c_str[char_pos] == ' '
147                 || c_str[char_pos] == '\t'
148                 || c_str[char_pos] == '=')
149                 {
150                     state++;
151                     name_end = char_pos;
152                 }
153
154                 if(c_str[char_pos] == '=')
155                     char_pos--; // decrement to stay on this char
156                 break;
157             case 2:
158                 if(c_str[char_pos] != ' '
159                 && c_str[char_pos] != '\t'
160                 && c_str[char_pos] != '=')
161                 {
162                     return false;
163                 }
164
165                 if(c_str[char_pos] == '=')
166                 {
167                     state++;
168                 }
169                 break;
170             case 3:
171                 if(c_str[char_pos] != ' '
172                 && c_str[char_pos] != '\t')
173                 {
174                     state++;
175                     value_start = char_pos;
176                 }
177                 break;
178             case 4:
179                 if(c_str[char_pos] == ' '
180                 || c_str[char_pos] == '\t'
181                 || c_str[char_pos] == 0)
182                 {
183                     state++;
184                     value_end = char_pos;
185                 }
186                 break;
187         }
188
189         if(state == 5)
190             break;
191
192         char_pos++;
193     }
194
195     name->clear();
196     value->clear();
197
198     name->replace   (0, 0, c_str, name_start,   name_end  - name_start);
199     value->replace  (0, 0, c_str, value_start,  value_end - value_start);
200
201     return true;
202 }
203
204 void createKeyMap()
205 {
206     char buf[2] = {0,0};
207
208     // add all the letters
209     for (int i = 'A'; i <= 'Z'; i++)   // uppercase
210     {
211         buf[0] = (char)i;
212         keyMap[buf] = (SDLKey)(i + 'a' - 'A');
213     }
214     for (int i = 'a'; i <= 'z'; i++)   // lowercase
215     {
216         buf[0] = (char)i;
217         keyMap[buf] = (SDLKey)i;
218     }
219
220     // add all the numbers
221     for (int i = '0'; i <= '9'; i++)
222     {
223         buf[0] = (char)i;
224         keyMap[buf] = (SDLKey)i;
225     }
226
227     /*
228     // add the function keys
229     int F1 = (int)Key.F1;
230     for (int i = F1; i <= (int)Key.F15; i++)
231     {
232         keyMap.Add("F" + (i - F1 + 1), (Key)i);
233         keyMap.Add("f" + (i - F1 + 1), (Key)i);
234     }
235     */
236
237     keyMap["LCtrl"]         = SDLK_LCTRL;
238     keyMap["LeftControl"]   = SDLK_LCTRL;
239     keyMap["LAlt"]          = SDLK_LALT;
240     keyMap["LeftAlt"]       = SDLK_LALT;
241     keyMap["LShift"]        = SDLK_LSHIFT;
242     keyMap["LeftShift"]     = SDLK_LSHIFT;
243     keyMap["LWin"]          = SDLK_LSUPER;
244     keyMap["LeftWindows"]   = SDLK_LSUPER;
245     keyMap["LeftMeta"]      = SDLK_LMETA;
246     keyMap["LMeta"]         = SDLK_LMETA;
247
248     keyMap["RCtrl"]         = SDLK_RCTRL;
249     keyMap["RightControl"]  = SDLK_RCTRL;
250     keyMap["RAlt"]          = SDLK_RALT;
251     keyMap["RightAlt"]      = SDLK_RALT;
252     keyMap["RShift"]        = SDLK_RSHIFT;
253     keyMap["RightShift"]    = SDLK_RSHIFT;
254     keyMap["RWin"]          = SDLK_RSUPER;
255     keyMap["RightWindows"]  = SDLK_RSUPER;
256     keyMap["RightMeta"]     = SDLK_RMETA;
257     keyMap["RMeta"]         = SDLK_RMETA;
258
259     keyMap["Esc"]           = SDLK_ESCAPE;
260     keyMap["Escape"]        = SDLK_ESCAPE;
261
262     keyMap["Return"]        = SDLK_RETURN;
263     keyMap["Enter"]         = SDLK_RETURN;
264
265     keyMap["Insert"]        = SDLK_INSERT;
266     keyMap["Home"]          = SDLK_HOME;
267     keyMap["Delete"]        = SDLK_DELETE;
268     keyMap["End"]           = SDLK_END;
269     keyMap["PageUp"]        = SDLK_PAGEUP;
270     keyMap["PageDown"]      = SDLK_PAGEDOWN;
271
272     keyMap["Minus"]         = SDLK_MINUS;
273     keyMap["Equal"]         = SDLK_EQUALS;
274     keyMap["Equals"]        = SDLK_EQUALS;
275     keyMap["LeftBracket"]   = SDLK_LEFTBRACKET;
276     keyMap["LBracket"]      = SDLK_LEFTBRACKET;
277     keyMap["RightBracket"]  = SDLK_RIGHTBRACKET;
278     keyMap["RBracket"]      = SDLK_RIGHTBRACKET;
279     keyMap["Backslash"]     = SDLK_BACKSLASH;
280     keyMap["Slash"]         = SDLK_SLASH;
281     keyMap["Semicolon"]     = SDLK_SEMICOLON;
282     keyMap["Semi"]          = SDLK_SEMICOLON;
283     keyMap["Quote"]         = SDLK_QUOTE;
284     keyMap["Comma"]         = SDLK_COMMA;
285     keyMap["Period"]        = SDLK_PERIOD;
286     keyMap["Space"]         = SDLK_SPACE;
287     keyMap["BSpace"]        = SDLK_BACKSPACE;
288     keyMap["Backspace"]     = SDLK_BACKSPACE;
289     keyMap["BackSpace"]     = SDLK_BACKSPACE;
290
291     keyMap["Tab"]           = SDLK_TAB;
292     keyMap["BackQuote"]     = SDLK_BACKQUOTE;
293     keyMap["BQuote"]        = SDLK_BACKQUOTE;
294     keyMap["CapsLock"]      = SDLK_CAPSLOCK;
295     keyMap["Caps"]          = SDLK_CAPSLOCK;
296
297     keyMap["Up"]            = SDLK_UP;
298     keyMap["Down"]          = SDLK_DOWN;
299     keyMap["Left"]          = SDLK_LEFT;
300     keyMap["Right"]         = SDLK_RIGHT;
301 }