2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
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.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 static bool displayLicense;
26 void checkForLicense()
28 if (!engine.loadData(_("data/license")))
30 graphics.showLicenseErrorAndExit();
35 Show the GNU Public License the first time the game is played. Waits 4 seconds
36 and then proceeds. THIS MUST NOT BE REMOVED!!!!!
40 SDL_FillRect(graphics.screen, NULL, graphics.black);
43 SDL_FillRect(graphics.screen, NULL, graphics.black);
44 SDL_Surface *pic = graphics.loadImage("gfx/main/licensePic.png");
45 graphics.blit(pic, 0, 0, graphics.screen, false);
53 char *token = strtok((char*)engine.dataBuffer, "\n");
57 sscanf(token, "%d %[^\n\r]", &y, line);
64 graphics.drawString(line, 320, y, true, graphics.screen);
66 token = strtok(NULL, "\n");
76 graphics.drawString(_("Press Space to Continue..."), 320, 440, true, graphics.screen);
83 graphics.updateScreen();
86 if (engine.userAccepts())
91 SDL_FillRect(graphics.screen, NULL, graphics.black);
96 void setupUserHomeDirectory()
98 char *userHome = getenv("HOME");
100 if ((!userHome) || (userHome == NULL))
102 printf("Couldn't determine user home directory! Exitting.\n");
106 debug(("User Home = %s\n", userHome));
111 snprintf(dir, sizeof dir, "%s/.parallelrealities", userHome);
112 if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
114 printf("Couldn't create required directory '%s'", dir);
118 snprintf(dir, sizeof dir, "%s/.parallelrealities/blobwars", userHome);
119 if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
121 printf("Couldn't create required directory '%s'", dir);
125 char gameSavePath[PATH_MAX];
126 snprintf(gameSavePath, sizeof gameSavePath, "%s/.parallelrealities/blobwars/", userHome);
127 engine.setUserHome(gameSavePath);
137 char configPath[PATH_MAX];
139 snprintf(configPath, sizeof configPath, "%sconfig", engine.userHomeDirectory);
141 debug(("Loading Config from %s\n", configPath));
143 FILE *fp = fopen(configPath, "rb");
150 if (fscanf(fp, "%10f %10d", &version, &release) != 2)
155 debug(("Version = %.2f - Expected %.2f\n", version, VERSION));
156 debug(("Release = %d - Expected %d\n", release, RELEASE));
158 if ((version != VERSION) && (release != RELEASE))
163 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)
170 debug(("Extreme Mode = %d\n", engine.extremeAvailable));
171 debug(("Output Type = %d\n", game.output));
173 // Override audio if there is no sound available
174 if ((engine.useAudio) && (game.output))
176 engine.useAudio = game.output;
179 config.loadKeyConfig();
180 config.loadJoystickConfig();
187 char configPath[PATH_MAX];
189 snprintf(configPath, sizeof configPath, "%sconfig", engine.userHomeDirectory);
191 FILE *fp = fopen(configPath, "wb");
195 printf("Error Saving Config to %s\n", configPath);
199 fprintf(fp, "%f %d\n", VERSION, RELEASE);
200 fprintf(fp, "%d %d %d %d %d %d %d\n", engine.fullScreen, game.musicVol, game.soundVol, game.output, game.brightness, engine.extremeAvailable, game.gore);
204 debug(("Output Type = %d\n", game.output));
208 // see if we can load the private keyState
210 int initMedalService(void *data)
214 SDL_mutexP(medalServer.lock);
216 char connectMessage[1024];
217 snprintf(connectMessage, sizeof connectMessage, "Contacting Medal Server - %s:%d", MEDAL_SERVER_HOST, MEDAL_SERVER_PORT);
219 graphics.showMedalMessage(-1, connectMessage);
221 char keyPath[PATH_MAX];
224 snprintf(keyPath, sizeof keyPath, "%smedalKey", engine.userHomeDirectory);
226 debug(("Loading private key from %s\n", keyPath));
228 FILE *fp = fopen(keyPath, "rb");
232 graphics.showMedalMessage(-1, "No Medal Key found - Online functions disabled");
233 SDL_mutexV(medalServer.lock);
237 if (fscanf(fp, "%19s", privateKey) != 1)
239 graphics.showMedalMessage(-1, "Medal Key file corrupt - Online functions disabled");
240 SDL_mutexV(medalServer.lock);
247 if (!medalServer.connect(privateKey))
249 graphics.showMedalMessage(-1, "Medal Server Connection Failed - Online functions disabled");
253 graphics.showMedalMessage(-1, "Connected to Medal Server");
255 SDL_mutexV(medalServer.lock);
263 setupUserHomeDirectory();
266 displayLicense = loadConfig();
270 Chugg chugg chugg.... brrr... chugg chugg chugg...brrrrrr... chugg ch..
271 BRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMM!! Well, hopefully anyway! ;)
275 long flags = SDL_INIT_VIDEO|SDL_INIT_JOYSTICK;
279 flags |= SDL_INIT_AUDIO;
282 /* Initialize the SDL library */
283 if (SDL_Init(flags) < 0)
285 printf("Couldn't initialize SDL: %s\n", SDL_GetError());
289 graphics.screen = SDL_CreateRGBSurface(0, 640, 480, 32, 0xff0000, 0xff00, 0xff, 0xff000000);
291 if (graphics.screen == NULL)
293 printf("Couldn't set 640x480 video mode: %s\n", SDL_GetError());
297 // Increase the size of the window if we have large desktop resolutions
298 SDL_DisplayMode displayMode = {};
299 SDL_GetDesktopDisplayMode(0, &displayMode);
300 int w = graphics.screen->w;
301 int h = graphics.screen->h;
302 while (displayMode.w > w * 2 && displayMode.h > h * 2)
308 graphics.window = SDL_CreateWindow("Blobwars: Metal Blob Solid", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_RESIZABLE);
310 if (graphics.window == NULL)
312 printf("Couldn't create %dx%d window: %s\n", w, h, SDL_GetError());
316 graphics.renderer = SDL_CreateRenderer(graphics.window, -1, SDL_RENDERER_PRESENTVSYNC);
318 if (graphics.renderer == NULL)
320 printf("Couldn't create renderer: %s\n", SDL_GetError());
324 SDL_RenderSetLogicalSize(graphics.renderer, graphics.screen->w, graphics.screen->h);
325 graphics.texture = SDL_CreateTexture(graphics.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, graphics.screen->w, graphics.screen->h);
327 if (graphics.texture == NULL)
329 printf("Could not create %dx%d texture: %s\n", graphics.screen->w, graphics.screen->h, SDL_GetError());
333 SDL_SetWindowFullscreen(graphics.window, engine.fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
335 // This (attempts to) set the gamma correction. We attempt to catch an error here
336 // in case someone has done something really stupid in the config file(!!)
337 if (game.brightness != -1) {
338 Math::limitInt(&game.brightness, 1, 20);
339 float brightness = game.brightness;
342 SDL_CalculateGammaRamp(brightness, ramp);
343 SDL_SetWindowGammaRamp(graphics.window, ramp, ramp, ramp);
348 printf("Couldn't initialize SDL TTF: %s\n", SDL_GetError());
354 if (Mix_OpenAudio(22050, AUDIO_S16, engine.useAudio, 1024) < 0)
356 printf("Warning: Couldn't set 44100 Hz 16-bit audio - Reason: %s\n", Mix_GetError());
357 printf("Sound and Music will be disabled\n");
362 debug(("Found %d Joysticks...\n", SDL_NumJoysticks()));
364 if (SDL_NumJoysticks() > 0)
366 debug(("Opening Joystick - %s...\n", SDL_JoystickName(0)));
367 SDL_JoystickEventState(SDL_ENABLE);
368 config.sdlJoystick = SDL_JoystickOpen(0);
371 SDL_ShowCursor(SDL_DISABLE);
373 graphics.registerEngine(&engine);
374 graphics.mapColors();
376 audio.registerEngine(&engine);
377 audio.setSoundVolume(game.soundVol);
378 audio.setMusicVolume(game.musicVol);
379 audio.output = game.output;
381 debug(("Sound Volume = %d\n", game.soundVol));
382 debug(("Music Volume = %d\n", game.musicVol));
383 debug(("Output Type = %d\n", game.output));
384 debug(("Brightness = %d\n", game.brightness));
385 debug(("tmp dir = %s\n", engine.userHomeDirectory));
386 debug(("Pack Dir = %s\n", PAKLOCATION));
387 debug(("Loading Fonts...\n"));
390 if (!engine.unpack("data/vera.ttf", PAK_FONT))
392 engine.reportFontFailure();
396 graphics.loadFont(0, "data/vera.ttf", 12);
397 graphics.loadFont(1, "data/vera.ttf", 15);
398 graphics.loadFont(2, "data/vera.ttf", 19);
399 graphics.loadFont(3, "data/vera.ttf", 23);
400 graphics.loadFont(4, "data/vera.ttf", 24);
402 debug(("Font sizes all loaded!!\n"));
404 audio.loadSound(SND_CHEAT, "sound/Lock And Load!!!");
405 audio.loadSound(SND_HIGHLIGHT, "sound/menu");
406 audio.loadSound(SND_SELECT, "sound/select");
408 graphics.medal[0] = graphics.loadImage("gfx/main/medal_bronze_1.png");
409 graphics.medal[1] = graphics.loadImage("gfx/main/award_star_silver_3.png");
410 graphics.medal[2] = graphics.loadImage("gfx/main/shield.png");
411 graphics.medal[3] = graphics.loadImage("gfx/main/ruby.png");
413 graphics.license[0] = graphics.loadImage("gfx/main/cc-by.png", true);
414 graphics.license[1] = graphics.loadImage("gfx/main/cc-by-sa.png", true);
416 SDL_Surface *device = graphics.loadImage("gfx/main/alienDevice.png");
417 SDL_SetWindowIcon(graphics.window, device);
418 SDL_FreeSurface(device);
420 if (strstr(engine.userHomeDirectory, "/root"))
422 graphics.showRootWarning();
434 if (SDLNet_Init() < 0)
436 printf("SDLNet_Init: %s\n", SDLNet_GetError());
440 SDL_Thread *thread = SDL_CreateThread(initMedalService, "MedalService", NULL);
444 printf("Unable to create thread: %s\n", SDL_GetError());
445 printf("Calling medal server directly\n");
446 initMedalService(NULL);
451 engine.saveConfig = true;
453 debug(("Init Complete...\n"));
457 Removes [hopefully] all the resources that has been
458 loaded and created during the game. This is called by
463 char tempPath[PATH_MAX];
465 debug(("Cleaning Up...\n"));
467 debug(("Updating Replay Data\n"));
468 replayData.header.score = game.score;
470 debug(("Freeing Audio...\n"));
473 debug(("Removing Music...\n"));
474 snprintf(tempPath, sizeof tempPath, "%smusic.mod", engine.userHomeDirectory);
477 debug(("Freeing Game Info...\n"));
480 debug(("Freeing Map Data...\n"));
483 debug(("Freeing Engine Data...\n"));
486 debug(("Freeing Graphics...\n"));
489 debug(("Saving Config...\n"));
490 if (engine.saveConfig)
495 debug(("Removing Font File...\n"));
496 snprintf(tempPath, sizeof tempPath, "%sfont.ttf", engine.userHomeDirectory);
499 if (SDL_NumJoysticks() > 0)
501 SDL_JoystickEventState(SDL_DISABLE);
502 for (int i = 0 ; i < SDL_NumJoysticks() ; i++)
504 debug(("Closing Joystick #%d\n", i));
505 SDL_JoystickClose(config.sdlJoystick);
509 debug(("Closing Audio...\n"));
515 debug(("Closing TTF...\n"));
518 debug(("Closing NET...\n"));
521 debug(("Closing SDL Sub System...\n"));
524 debug(("All Done.\n"));
526 if (replayData.replayMode == REPLAY_MODE::PLAYBACK)
528 printf("\n==== ACTUAL PLAYBACK DATA ====\n");
529 replayData.printReplayInformation();