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