1 /*
2 * Kuklomenos
3 * Copyright (C) 2008-2009 Martin Bays <mbays@sdf.lonestar.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/.
17 */
18
19 #include <iostream>
20 #include <fstream>
21 #include <string>
22 #include <cstdlib>
23 #include <sstream>
24 using namespace std;
25
26 #include "conffile.h"
27 #include "keybindings.h"
28 #include "SDL_gfxPrimitivesDirty.h"
29
powmod(int n,int m,int p)30 int powmod(int n, int m, int p)
31 {
32 int out = 1;
33 while (m > 0)
34 if (m % 2 == 0)
35 {
36 n = (n*n) % p;
37 m /= 2;
38 }
39 else
40 {
41 out = (out*n) % p;
42 m -= 1;
43 }
44 return out;
45
46 }
47
48 /* obfuscate the rating string: if you want to cheat, you at least have to
49 * source-dive...
50 */
obfuscatedRating(double rating)51 int obfuscatedRating(double rating)
52 {
53 int pertinentRating = (int)(round(10*rating));
54 return powmod(pertinentRating, 5, 45953);
55 }
unobfuscatedRating(int obfuscated)56 double unobfuscatedRating(int obfuscated)
57 {
58 double unobf = powmod(obfuscated, 18381, 45953)/10.0;
59 if (unobf < 0 || unobf > 20)
60 return 0.0;
61 return unobf;
62 }
63
Config()64 Config::Config() :
65 useAA(AA_YES), showGrid(true), zoomEnabled(true), rotatingView(true),
66 turnRateFactor(1.0), fps(30), showFPS(true), sound(true), volume(1.0),
67 soundFreq(44100),
68 aaGamma(2.2),
69 shouldUpdateRating(false), uuid(0),
70 rebindings(),
71 bgType(BG_NONE),
72 width(0), height(0), bpp(16), fullscreen(false),
73 confFileVersion(CONFFILE_VERSION_FIRST)
74 {
75 username[0] = '\0';
76 for (int i=0; i<3; i++)
77 rating[i] = highestRating[i] = 5.0;
78 }
79
read()80 void Config::read()
81 {
82 ifstream f;
83 char* home = getenv("HOME");
84
85 if (home != NULL)
86 {
87 string homeStr = home;
88 f.open((home + (string)"/.kuklomenosrc").c_str());
89 }
90 if (!f.is_open())
91 f.open("./kuklomenosrc.txt");
92
93 if (f.is_open())
94 {
95 string line;
96 double val, val2, val3, val4, val5, val6;
97 char buf[31];
98 char buf2[31];
99 unsigned int uint;
100 int i, i2, i3;
101 int n;
102
103 while (!f.eof())
104 {
105 std::getline(f, line);
106 const char* cstr = line.c_str();
107 n = sscanf(cstr, "data: %lf %lf %lf %lf %lf %lf", &val, &val2,
108 &val3, &val4, &val5, &val6);
109 if (n > 0)
110 for (int i=0; i<3; i++)
111 {
112 if (n > 2*i)
113 {
114 rating[i] = unobfuscatedRating( (int)(
115 i==0 ? val : i==1 ? val3 : val5
116 ) );
117 if (n > 2*i+1)
118 highestRating[i] = unobfuscatedRating( ((int)(
119 i==0 ? val2 : i==1 ? val4 : val6
120 )-1337-37*i)/2 );
121 }
122 }
123 else if (sscanf(cstr, "confversion: %lf", &val) == 1)
124 confFileVersion = val;
125 else if (sscanf(cstr, "showGrid: %lf", &val) == 1)
126 showGrid = val;
127 else if (sscanf(cstr, "zoomEnabled: %lf", &val) == 1)
128 zoomEnabled = val;
129 else if (sscanf(cstr, "rotatingView: %lf", &val) == 1)
130 rotatingView = val;
131 else if (sscanf(cstr, "turnRate: %lf", &val) == 1)
132 turnRateFactor = val;
133 else if (sscanf(cstr, "showFPS: %lf", &val) == 1)
134 showFPS = val;
135 else if (sscanf(cstr, "fullscreen: %lf", &val) == 1)
136 fullscreen = val;
137 else if (sscanf(cstr, "speed: %lf", &val) == 1)
138 {
139 speed = (int) val;
140 if (speed < 0) speed = 0;
141 if (speed > 2) speed = 2;
142 }
143 else if (sscanf(cstr, "sound: %lf", &val) == 1)
144 sound = val;
145 else if (sscanf(cstr, "volume: %lf", &val) == 1)
146 volume = val;
147 else if (sscanf(cstr, "freq: %lf", &val) == 1)
148 soundFreq = int(val);
149 else if (sscanf(cstr, "antialiasGamma: %lf", &val) == 1)
150 aaGamma = val;
151 else if (sscanf(cstr, "fps: %lf", &val) == 1)
152 fps = (int) val;
153 else if (sscanf(cstr, "useAA: %lf", &val) == 1)
154 useAA = (val == 0 ? AA_NO :
155 val == 2 ? AA_FORCE :
156 AA_YES);
157 else if (sscanf(cstr,
158 "mode: %dx%dx%d", &i, &i2, &i3) == 3)
159 {
160 width = (int) i;
161 height = (int) i2;
162 bpp = (int) i3;
163 }
164 else if (sscanf(cstr, "username: %16s", buf) == 1)
165 strncpy(username, buf, 17);
166 else if (strcmp(cstr, "username: ") == 0)
167 username[0] = '\0';
168 else if (sscanf(cstr, "uuid: %x", &uint) == 1)
169 uuid = uint;
170 else if (sscanf(cstr, "background: %30s", buf) == 1)
171 {
172 for (BGType bg = BG_FIRST; bg <= BG_LAST; bg = BGType(bg+1))
173 if (bgTypeStrings[bg].compare(buf) == 0)
174 bgType = bg;
175 }
176 else if (sscanf(cstr, "bind %30s %30s", buf, buf2) == 2)
177 {
178 command c = commandOfString(buf);
179 Key k(buf2);
180 if (c == C_NONE)
181 fprintf(stderr, "Unparsable command: %s\n", buf);
182 else if (k == KEY_NONE)
183 fprintf(stderr, "Unparsable key description: %s\n", buf2);
184 else
185 rebindings[c] = k;
186 }
187 else if (*cstr != '\0' && *cstr != '#')
188 fprintf(stderr, "Unparsable line in config file: %s\n", cstr);
189 }
190 }
191 }
192
importSettings(const Settings & settings)193 void Config::importSettings(const Settings& settings)
194 {
195 useAA = settings.useAA;
196 showGrid = settings.showGrid;
197 zoomEnabled = settings.zoomEnabled;
198 rotatingView = settings.rotatingView;
199 turnRateFactor = settings.turnRateFactor;
200 fps = settings.fps;
201 showFPS = settings.showFPS;
202 sound = settings.sound;
203 volume = settings.volume;
204 soundFreq = settings.soundFreq;
205 speed = settings.speed;
206 bgType = settings.bgType;
207
208 width = settings.width;
209 height = settings.height;
210 bpp = settings.bpp;
211 fullscreen = (settings.videoFlags & SDL_FULLSCREEN);
212
213 aaGamma = antialiasGamma;
214
215 rebindings.clear();
216 for (command c=C_FIRST; c <= C_LASTDEBUG; c = command(c+1))
217 {
218 if (settings.keybindings.get(c) != defaultKeybindings().get(c))
219 rebindings[c] = settings.keybindings.get(c);
220 }
221 }
exportSettings(Settings & settings) const222 void Config::exportSettings(Settings& settings) const
223 {
224 settings.useAA = useAA;
225 settings.showGrid = showGrid;
226 settings.zoomEnabled = zoomEnabled;
227 settings.rotatingView = rotatingView;
228 settings.turnRateFactor = turnRateFactor;
229 settings.fps = fps;
230 settings.showFPS = showFPS;
231 settings.sound = sound;
232 settings.volume = volume;
233 settings.soundFreq = soundFreq;
234 settings.speed = speed;
235 settings.bgType = bgType;
236
237 settings.width = width;
238 settings.height = height;
239 settings.bpp = bpp;
240 if (fullscreen)
241 settings.videoFlags |= SDL_FULLSCREEN;
242 else
243 settings.videoFlags &= ~SDL_FULLSCREEN;
244
245 antialiasGamma = aaGamma;
246
247 for ( map<command,Key>::const_iterator it = rebindings.begin();
248 it != rebindings.end(); it++)
249 settings.keybindings[it->first] = it->second;
250 }
251
write() const252 void Config::write() const
253 {
254 ofstream f;
255 char* home = getenv("HOME");
256
257 if (home != NULL)
258 {
259 string homeStr = home;
260 f.open((home + (string)"/.kuklomenosrc").c_str());
261 }
262 if (!f.is_open())
263 f.open("./kuklomenosrc.txt");
264
265 if (!f.is_open())
266 fprintf(stderr, "Couldn't write config file.\n");
267 else
268 {
269 ostringstream s;
270 string bindingsString;
271 int aanum = (useAA == AA_NO ? 0 :
272 useAA == AA_YES ? 1 : 2);
273 if (!rebindings.empty())
274 {
275 bindingsString = '\n';
276 for ( map<command,Key>::const_iterator it = rebindings.begin();
277 it != rebindings.end(); it++)
278 bindingsString += ( string("bind ") + shortCommandNames[it->first] +
279 string(" ") + (it->second).getString() + string("\n"));
280 }
281 s <<
282 "useAA: " << aanum << endl <<
283 "showGrid: " << showGrid << endl <<
284 "zoomEnabled: " << zoomEnabled << endl <<
285 "rotatingView: " << rotatingView << endl <<
286 "turnRate: " << turnRateFactor << endl <<
287 "fps: " << fps << endl <<
288 "showFPS: " << showFPS << endl <<
289 "speed: " << speed << endl <<
290 "sound: " << sound << endl <<
291 "volume: " << volume << endl <<
292 "freq: " << soundFreq << endl <<
293 "antialiasGamma: " << aaGamma << endl << endl <<
294 "mode: " << width << "x" << height << "x" << bpp << endl <<
295 "fullscreen: " << fullscreen << endl << endl <<
296 "background: " << bgTypeStrings[bgType] << endl << endl <<
297 "username: " << username << endl <<
298 "uuid: " << hex << uuid << dec << endl <<
299 bindingsString <<
300 endl << "# Warning: Do not edit following lines" << endl <<
301 "confversion: " << confFileVersion << endl <<
302 "data: " << obfuscatedRating(rating[0]) << " " << (obfuscatedRating(highestRating[0])*2+1337)
303 << " " << obfuscatedRating(rating[1]) << " " << (obfuscatedRating(highestRating[1])*2+1337+37)
304 << " " << obfuscatedRating(rating[2]) << " " << (obfuscatedRating(highestRating[2])*2+1337+37*2)
305 << endl;
306 f << s.str();
307 }
308 }
309
310 Config config;
311