]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/init.cpp
Coalesce printf() statements in main.cpp, make them translatable.
[quix0rs-blobwars.git] / src / init.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (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.
12
13 See the 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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "init.h"
22
23 static bool displayLicense;
24
25 void checkForLicense()
26 {
27         if (!engine.loadData(_("data/license")))
28         {
29                 graphics.showLicenseErrorAndExit();
30         }
31 }
32
33 /*
34 Show the GNU Public License the first time the game is played. Waits 4 seconds
35 and then proceeds. THIS MUST NOT BE REMOVED!!!!!
36 */
37 void showLicense()
38 {
39         SDL_FillRect(graphics.screen, NULL, graphics.black);
40         graphics.delay(1000);
41
42         SDL_FillRect(graphics.screen, NULL, graphics.black);
43         SDL_Surface *pic = graphics.loadImage("gfx/main/licensePic.png");
44         graphics.blit(pic, 0, 0, graphics.screen, false);
45         SDL_FreeSurface(pic);
46
47         checkForLicense();
48
49         char line[255];
50         int y = 0;
51
52         char *token = strtok((char*)engine.dataBuffer, "\n");
53
54         while (true)
55         {
56                 sscanf(token, "%d %[^\n\r]", &y, line);
57                 
58                 if (y == -1)
59                 {
60                         break;
61                 }
62
63                 graphics.drawString(line, 320, y, true, graphics.screen);
64
65                 token = strtok(NULL, "\n");
66
67                 if (token == NULL)
68                 {
69                         break;
70                 }
71         }
72
73         graphics.delay(4000);
74
75         graphics.drawString(_("Press Space to Continue..."), 320, 440, true, graphics.screen);
76
77         engine.flushInput();
78         engine.clearInput();
79
80         while (true)
81         {
82                 graphics.updateScreen();
83                 engine.getInput();
84                 config.populate();
85                 if (engine.keyState[SDL_SCANCODE_SPACE])
86                         break;
87                 SDL_Delay(16);
88         }
89         
90         SDL_FillRect(graphics.screen, NULL, graphics.black);
91         graphics.delay(1000);
92 }
93
94 #if UNIX
95 void setupUserHomeDirectory()
96 {
97         char *userHome = getenv("HOME");
98         
99         if ((!userHome) || (userHome == NULL))
100         {
101                 printf("Couldn't determine user home directory! Exitting.\n");
102                 exit(1);
103         }
104
105         debug(("User Home = %s\n", userHome));
106         
107         char dir[PATH_MAX];
108         dir[0] = 0;
109
110         snprintf(dir, sizeof dir, "%s/.parallelrealities", userHome);
111         if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
112         {
113                 printf("Couldn't create required directory '%s'", dir);
114                 exit(1);
115         }
116
117         snprintf(dir, sizeof dir, "%s/.parallelrealities/blobwars", userHome);
118         if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
119         {
120                 printf("Couldn't create required directory '%s'", dir);
121                 exit(1);
122         }
123
124         char gameSavePath[PATH_MAX];
125         snprintf(gameSavePath, sizeof gameSavePath, "%s/.parallelrealities/blobwars/", userHome);
126         engine.setUserHome(gameSavePath);
127 }
128 #endif
129
130 bool loadConfig()
131 {
132         float version = 0;
133         int release = 0;
134         bool rtn = false;
135
136         char configPath[PATH_MAX];
137
138         snprintf(configPath, sizeof configPath, "%sconfig", engine.userHomeDirectory);
139
140         debug(("Loading Config from %s\n", configPath));
141
142         FILE *fp = fopen(configPath, "rb");
143
144         if (!fp)
145         {
146                 return true;
147         }
148
149         if (fscanf(fp, "%10f %10d", &version, &release) != 2)
150         {
151                 rtn = true;
152         }
153
154         debug(("Version = %.2f - Expected %.2f\n", version, VERSION));
155         debug(("Release = %d - Expected %d\n", release, RELEASE));
156
157         if ((version != VERSION) && (release != RELEASE))
158         {
159                 rtn = true;
160         }
161
162         if (fscanf(fp, "%10d %10d %10d %10d %10d %10d %10d", &engine.fullScreen, &game.musicVol, &game.soundVol, &game.output, &game.brightness, &engine.extremeAvailable, &game.gore) != 7)
163         {
164                 rtn = true;
165         }
166
167         fclose(fp);
168
169         debug(("Extreme Mode = %d\n", engine.extremeAvailable));
170         debug(("Output Type = %d\n", game.output));
171
172         // Override audio if there is no sound available
173         if ((engine.useAudio) && (game.output))
174         {
175                 engine.useAudio = game.output;
176         }
177                 
178         config.loadKeyConfig();
179         config.loadJoystickConfig();
180
181         return rtn;
182 }
183
184 void saveConfig()
185 {
186         char configPath[PATH_MAX];
187
188         snprintf(configPath, sizeof configPath, "%sconfig", engine.userHomeDirectory);
189
190         FILE *fp = fopen(configPath, "wb");
191
192         if (!fp)
193         {
194                 printf("Error Saving Config to %s\n", configPath);
195                 return;
196         }
197
198         fprintf(fp, "%f %d\n", VERSION, RELEASE);
199         fprintf(fp, "%d %d %d %d %d %d %d\n", engine.fullScreen, game.musicVol, game.soundVol, game.output, game.brightness, engine.extremeAvailable, game.gore);
200
201         fclose(fp);
202         
203         debug(("Output Type = %d\n", game.output));
204 }
205
206 //
207 // see if we can load the private keyState
208 //
209 int initMedalService(void *data)
210 {
211         SDL_mutexP(medalServer.lock);
212         
213         char connectMessage[1024];
214         snprintf(connectMessage, sizeof connectMessage, "Contacting Medal Server - %s:%d", MEDAL_SERVER_HOST, MEDAL_SERVER_PORT);
215         
216         graphics.showMedalMessage(-1, connectMessage);
217         
218         char keyPath[PATH_MAX];
219         char privateKey[20];
220
221         snprintf(keyPath, sizeof keyPath, "%smedalKey", engine.userHomeDirectory);
222         
223         debug(("Loading private key from %s\n", keyPath));
224         
225         FILE *fp = fopen(keyPath, "rb");
226         
227         if (!fp)
228         {
229                 graphics.showMedalMessage(-1, "No Medal Key found - Online functions disabled");
230                 SDL_mutexV(medalServer.lock);
231                 return 0;
232         }
233         
234         if (fscanf(fp, "%19s", privateKey) != 1)
235         {
236                 graphics.showMedalMessage(-1, "Medal Key file corrupt - Online functions disabled");
237                 SDL_mutexV(medalServer.lock);
238                 fclose(fp);
239                 return 0;
240         }
241         
242         fclose(fp);
243                 
244         if (!medalServer.connect(privateKey))
245         {
246                 graphics.showMedalMessage(-1, "Medal Server Connection Failed - Online functions disabled");
247                 return 0;
248         }
249         
250         graphics.showMedalMessage(-1, "Connected to Medal Server");
251         
252         SDL_mutexV(medalServer.lock);
253         
254         return 1;
255 }
256
257 void initConfig()
258 {
259         #if UNIX
260         setupUserHomeDirectory();
261         #endif
262
263         displayLicense = loadConfig();
264 }
265
266 /*
267 Chugg chugg chugg.... brrr... chugg chugg chugg...brrrrrr... chugg ch..
268 BRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMM!! Well, hopefully anyway! ;)
269 */
270 void initSystem()
271 {
272         long flags = SDL_INIT_VIDEO|SDL_INIT_JOYSTICK;
273                         
274         if (engine.useAudio)
275         {
276                 flags |= SDL_INIT_AUDIO;
277         }
278
279         /* Initialize the SDL library */
280         if (SDL_Init(flags) < 0)
281         {
282                 printf("Couldn't initialize SDL: %s\n", SDL_GetError());
283                 exit(1);
284         }
285
286         graphics.screen = SDL_CreateRGBSurface(0, 640, 480, 32, 0xff0000, 0xff00, 0xff, 0xff000000);
287
288         graphics.window = SDL_CreateWindow("Blobwars: Metal Blob Solid", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, graphics.screen->w, graphics.screen->h, 0);
289         graphics.renderer = SDL_CreateRenderer(graphics.window, -1, 0);
290         SDL_RenderSetLogicalSize(graphics.renderer, graphics.screen->w, graphics.screen->h);
291         graphics.texture = SDL_CreateTexture(graphics.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, graphics.screen->w, graphics.screen->h);
292
293         if (graphics.window == NULL)
294         {
295                 printf("Couldn't set 640x480 video mode: %s\n", SDL_GetError());
296                 exit(1);
297         }
298
299         SDL_SetWindowFullscreen(graphics.window, engine.fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
300
301         // This (attempts to) set the gamma correction. We attempt to catch an error here
302         // in case someone has done something really stupid in the config file(!!)
303         if (game.brightness != -1) {
304                 Math::limitInt(&game.brightness, 1, 20);
305                 float brightness = game.brightness;
306                 brightness /= 10;
307                 uint16_t ramp[256];
308                 SDL_CalculateGammaRamp(brightness, ramp);
309                 SDL_SetWindowGammaRamp(graphics.window, ramp, ramp, ramp);
310         }
311
312         if (TTF_Init() < 0)
313         {
314                 printf("Couldn't initialize SDL TTF: %s\n", SDL_GetError());
315                 exit(1);
316         }
317
318         if (engine.useAudio)
319         {
320                 if (Mix_OpenAudio(22050, AUDIO_S16, engine.useAudio, 1024) < 0)
321                 {
322                         printf("Warning: Couldn't set 44100 Hz 16-bit audio - Reason: %s\n", Mix_GetError());
323                         printf("Sound and Music will be disabled\n");
324                         engine.useAudio = 0;
325                 }
326         }
327
328         debug(("Found %d Joysticks...\n", SDL_NumJoysticks()));
329
330         if (SDL_NumJoysticks() > 0)
331         {
332                 debug(("Opening Joystick - %s...\n", SDL_JoystickName(0)));
333                 SDL_JoystickEventState(SDL_ENABLE);
334                 config.sdlJoystick = SDL_JoystickOpen(0);
335         }
336
337         SDL_ShowCursor(SDL_DISABLE);
338         SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
339
340         graphics.registerEngine(&engine);
341         graphics.mapColors();
342
343         audio.registerEngine(&engine);
344         audio.setSoundVolume(game.soundVol);
345         audio.setMusicVolume(game.musicVol);
346         audio.output = game.output;
347
348         debug(("Sound Volume = %d\n", game.soundVol));
349         debug(("Music Volume = %d\n", game.musicVol));
350         debug(("Output Type = %d\n", game.output));
351         debug(("Brightness = %d\n", game.brightness));
352         debug(("tmp dir = %s\n", engine.userHomeDirectory));
353         debug(("Pack Dir = %s\n", PAKLOCATION));
354         debug(("Loading Fonts...\n"));
355
356         #if USEPAK
357                         
358                 char tempPath[PATH_MAX];
359                 snprintf(tempPath, sizeof tempPath, "%sfont.ttf", engine.userHomeDirectory);    
360                 remove(tempPath);
361                 
362                 if (!engine.unpack("data/vera.ttf", PAK_FONT))
363                 {
364                         engine.reportFontFailure();
365                 }
366         #endif
367
368         debug(("Trying to load correct font pixel sizes using a really half arsed routine!\n"));
369         debug(("If it crashes then you'll know why!\n"));
370                         
371         graphics.loadFont(0, "data/vera.ttf", 7);
372         graphics.loadFont(1, "data/vera.ttf", 9);
373         graphics.loadFont(2, "data/vera.ttf", 11);
374         graphics.loadFont(3, "data/vera.ttf", 13);
375         graphics.loadFont(4, "data/vera.ttf", 15);
376         
377         debug(("Font sizes all loaded!!\n"));
378
379         audio.loadSound(SND_CHEAT, "sound/Lock And Load!!!");
380         audio.loadSound(SND_HIGHLIGHT, "sound/menu");
381         audio.loadSound(SND_SELECT, "sound/select");
382         
383         graphics.medal[0] = graphics.loadImage("gfx/main/medal_bronze_1.png");
384         graphics.medal[1] = graphics.loadImage("gfx/main/award_star_silver_3.png");
385         graphics.medal[2] = graphics.loadImage("gfx/main/shield.png");
386         graphics.medal[3] = graphics.loadImage("gfx/main/ruby.png");
387
388         graphics.license[0] = graphics.loadImage("gfx/main/cc-by.png", true);
389         graphics.license[1] = graphics.loadImage("gfx/main/cc-by-sa.png", true);
390
391         SDL_Surface *device = graphics.loadImage("gfx/main/alienDevice.png");
392
393         SDL_FreeSurface(device);
394         
395         if (strstr(engine.userHomeDirectory, "/root"))
396         {
397                 graphics.showRootWarning();
398         }
399
400         if (displayLicense)
401         {
402                 showLicense();
403         }
404         else
405         {
406                 checkForLicense();
407         }
408         
409         if (SDLNet_Init() < 0)
410         {
411                 printf("SDLNet_Init: %s\n", SDLNet_GetError());
412         }
413         else
414         {
415                 SDL_Thread *thread = SDL_CreateThread(initMedalService, "MedalService", NULL);
416         
417                 if (thread == NULL)
418                 {
419                         printf("Unable to create thread: %s\n", SDL_GetError());
420                         printf("Calling medal server directly\n");
421                         initMedalService(NULL);
422                         return;
423                 }
424         }
425         
426         engine.saveConfig = true;
427
428         debug(("Init Complete...\n"));
429 }
430
431 /*
432 Removes [hopefully] all the resources that has been
433 loaded and created during the game. This is called by
434 atexit();
435 */
436 void cleanup()
437 {
438         char tempPath[PATH_MAX];
439         
440         debug(("Cleaning Up...\n"));
441         
442         debug(("Updating Replay Data\n"));
443         replayData.header.score = game.score;
444
445         debug(("Freeing Audio...\n"));
446         audio.destroy();
447
448         debug(("Removing Music...\n"));
449         snprintf(tempPath, sizeof tempPath, "%smusic.mod", engine.userHomeDirectory);
450         remove(tempPath);
451
452         debug(("Freeing Game Info...\n"));
453         game.destroy();
454
455         debug(("Freeing Map Data...\n"));
456         map.destroy();
457
458         debug(("Freeing Engine Data...\n"));
459         engine.destroy();
460
461         debug(("Freeing Graphics...\n"));
462         graphics.destroy();
463
464         debug(("Saving Config...\n"));
465         if (engine.saveConfig)
466         {
467                 saveConfig();
468         }
469
470         debug(("Removing Font File...\n"));
471         snprintf(tempPath, sizeof tempPath, "%sfont.ttf", engine.userHomeDirectory);
472         remove(tempPath);
473         
474         if (SDL_NumJoysticks() > 0)
475         {
476                 SDL_JoystickEventState(SDL_DISABLE);
477                 for (int i = 0 ; i < SDL_NumJoysticks() ; i++)
478                 {
479                         debug(("Closing Joystick #%d\n", i));
480                         SDL_JoystickClose(config.sdlJoystick);
481                 }
482         }
483
484         debug(("Closing Audio...\n"));
485         if (engine.useAudio)
486         {
487                 Mix_CloseAudio();
488         }
489
490         debug(("Closing TTF...\n"));
491         TTF_Quit();
492         
493         debug(("Closing NET...\n"));
494         SDLNet_Quit();
495
496         debug(("Closing SDL Sub System...\n"));
497         SDL_Quit();
498
499         debug(("All Done.\n"));
500         
501         if (replayData.replayMode == REPLAY_MODE::PLAYBACK)
502         {
503                 printf("\n==== ACTUAL PLAYBACK DATA ====\n");
504                 replayData.printReplayInformation();
505         }
506 }
507