]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/title.cpp
ae3e889dd71a40552e135f51d3657953e5c00e19
[quix0rs-blobwars.git] / src / title.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
4
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.
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.
13
14 See the GNU General Public License for more details.
15
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.
19
20 */
21
22 #include "title.h"
23
24 extern void doMusicInfo(unsigned int);
25
26 /**
27 * Displays the skill level widgets and hide the others
28 */
29 void showSkillLevels()
30 {
31         engine.showWidgetGroup("skill", true);
32         engine.showWidgetGroup("mainMenu", false);
33         engine.showWidgetGroup("gameSlots", false);
34
35         engine.showWidget("back", true);
36
37         engine.highlightWidget("normal");
38                   
39         engine.enableWidget("extreme", engine.extremeAvailable);
40 }
41
42 /**
43 * Displays the save game widgets and hide the others
44 */
45 void showGameSlots()
46 {
47         engine.showWidgetGroup("gameSlots", true);
48         engine.showWidgetGroup("mainMenu", false);
49
50         engine.showWidget("back", true);
51
52         engine.highlightWidget("slot1");
53 }
54
55 void showSaves()
56 {
57         engine.showWidgetGroup("saveGames", true);
58         engine.showWidgetGroup("mainMenu", false);
59
60         engine.showWidget("back", true);
61
62         engine.highlightWidget("save1");
63 }
64
65 /**
66 * Displays the manual widgets and hide the others
67 */
68 void showManualHelp()
69 {
70         #ifdef FRAMEWORK_SDL
71         openHelpURL();
72         #else
73         engine.showWidgetGroup("help", true);
74         engine.showWidgetGroup("mainMenu", false);
75         
76         engine.showWidget("back", true);
77
78         engine.highlightWidget("back");
79         #endif
80 }
81
82 /**
83 * Displays the title widgets and hide the others.
84 * Also disables Continue and Load Game if games are not
85 * available to be loaded.
86 */
87 void showTitleWidgets()
88 {
89         engine.showWidgetGroup("skill", false);
90         engine.showWidgetGroup("saveGames", false);
91         engine.showWidgetGroup("gameSlots", false);
92         engine.showWidgetGroup("help", false);
93         engine.showWidget("back", false);
94         
95         engine.showWidgetGroup("mainMenu", true);
96         
97         engine.highlightWidget("newGame");
98
99         if (!engine.continueSaveSlot)
100         {
101                 engine.enableWidget("loadGame", false);
102                 engine.enableWidget("continue", false);
103         }
104         else
105         {
106                 engine.highlightWidget("continue");
107         }
108 }
109
110 /**
111 * Creates the data labels for the save game slots
112 * according to the save game data available
113 */
114 void setupSaveWidgets()
115 {
116         char widgetName[10];
117         widgetName[0] = 0;
118         
119         for (int i = 0 ; i < 5 ; i++)
120         {
121                 snprintf(widgetName, sizeof widgetName, "save%d", i + 1);
122                 strlcpy(engine.getWidgetByName(widgetName)->label, engine.saveSlot[i], sizeof engine.getWidgetByName(widgetName)->label);
123                 
124                 if ((strstr(engine.saveSlot[i], _("Empty"))) || (strstr(engine.saveSlot[i], _("Corrupt"))))
125                 {
126                         engine.enableWidget(widgetName, false);
127                 }
128                 
129                 snprintf(widgetName, sizeof widgetName, "slot%d", i + 1);
130                 strlcpy(engine.getWidgetByName(widgetName)->label, engine.saveSlot[i], sizeof engine.getWidgetByName(widgetName)->label);
131         }
132 }
133
134 /**
135 * Loads the title widgets
136 */
137 void loadTitleWidgets()
138 {
139         if (!engine.loadWidgets(_("data/titleWidgets")))
140         {
141                 graphics.showErrorAndExit(ERR_FILE, _("data/titleWidgets"));
142         }
143
144         initSaveSlots();
145
146         setupSaveWidgets();
147         
148         Widget *widget = engine.getWidgetByName("labelManual");
149         strlcpy(widget->label, GAMEPLAYMANUAL, sizeof widget->label);
150
151         showTitleWidgets();
152 }
153
154 /**
155 * Does the main game title sequence
156 * @return The section to proceed to (see main.cpp)
157 */
158 int title()
159 {
160         audio.free();
161         graphics.free();
162
163         SDL_FillRect(graphics.screen, NULL, graphics.black);
164         graphics.delay(1000);
165
166         newGame();
167
168         loadTitleWidgets();
169
170         float backAlpha = 0;
171         float titleAlpha = 0;
172         bool allFadedOn = false;
173
174         graphics.quickSprite("cheatHeader", graphics.loadImage("gfx/main/cheats.png"));
175         graphics.quickSprite("optionsHeader", graphics.loadImage("gfx/main/options.png"));
176         graphics.quickSprite("keyHeader", graphics.loadImage("gfx/main/keyConfig.png"));
177         graphics.quickSprite("joystickHeader", graphics.loadImage("gfx/main/joystickConfig.png"));
178         graphics.quickSprite("optionsBackground", graphics.loadImage("gfx/main/optionsBackground.png"));
179
180         SDL_Surface *prlogo = graphics.quickSprite("PRLogo", graphics.loadImage("gfx/main/prlogo.gif"));
181         SDL_Surface *title = graphics.quickSprite("Title", graphics.loadImage("gfx/main/title.png"));
182         
183         graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
184
185         graphics.setFontSize(3);
186         SDL_Surface *presents = graphics.quickSprite("Presents", graphics.getString(_("Presents"), true));
187         SDL_Surface *sdl = graphics.quickSprite("SDL", graphics.getString(_("An SDL2 Game"), true));
188
189         graphics.setFontSize(2);
190         SDL_Surface *subTitle = graphics.quickSprite("SubTitle", graphics.getString(_("Blob Wars : Episode I"), true));
191
192         graphics.setFontSize(0);
193         SDL_Surface *copyright[] = {
194                 graphics.quickSprite("Copyright1", graphics.getString(_("Copyright (C) 2011-2015 Perpendicular Dimensions"), true)),
195                 graphics.quickSprite("Copyright2", graphics.getString(_("Copyright (C) 2004-2011 Parallel Realities"), true)),
196                 NULL,
197         };
198
199         char v[50];
200         #define STRINGIFY_VALUE(x) STRINGIFY(x)
201         #define STRINGIFY(x) #x
202         snprintf(v, sizeof v, _("Version %s"), STRINGIFY_VALUE(VERSION));
203         SDL_Surface *version = graphics.quickSprite("Version", graphics.getString(v, true));
204
205         SDL_SetAlpha(title, 0);
206
207         audio.loadMusic("music/title");
208
209         graphics.loadBackground("gfx/main/CircuitBoard.jpg");
210         SDL_SetAlpha(graphics.background, 0);
211
212         int startNewGame, options, quit, help, easy, normal, hard, extreme, back, practice;
213         int load, cont, save[5], slot[6];
214         int autoSaveSlot;
215
216         startNewGame = options = quit = easy = normal = hard = extreme = back = help = practice = 0;
217         load = cont = save[0] = save[1] = save[2] = save[3] = save[4] = 0;
218         slot[0] = slot[1] = slot[2] = slot[3] = slot[4] = slot[5] = 0;
219         autoSaveSlot = 0;
220
221         engine.setWidgetVariable("newGame", &startNewGame);
222         engine.setWidgetVariable("loadGame", &load);
223         engine.setWidgetVariable("continue", &cont);
224         engine.setWidgetVariable("options", &options);
225         engine.setWidgetVariable("help", &help);
226         engine.setWidgetVariable("quit", &quit);
227
228         float offX = 0;
229
230         engine.flushInput();
231         engine.clearInput();
232
233         audio.playMusic();
234
235         Uint32 now = SDL_GetTicks();
236
237         unsigned int frameLimit = SDL_GetTicks() + 16;
238
239         while (true)
240         {
241                 unsigned int ticks = SDL_GetTicks();
242                 graphics.updateScreen();
243
244                 engine.getInput();
245                 config.populate();
246
247                 for (int x = (int)offX ; x < 640 ; x += graphics.background->w)
248                 {
249                         for (int y = 0 ; y < 480 ; y += graphics.background->h)
250                         {
251                                 graphics.blit(graphics.background, x, y, graphics.screen, false);
252                         }
253                 }
254
255                 if (!allFadedOn)
256                 {
257                         if ((ticks >= now + 2000) && (ticks <= now + 10000))
258                         {
259                                 graphics.blit(prlogo, 320, 240, graphics.screen, true);
260                         }
261                         else if ((ticks >= now + 13000) && (ticks <= now + 19000))
262                         {
263                                 graphics.blit(presents, 320, 240, graphics.screen, true);
264                         }
265                         else if ((ticks >= now + 22000) && (ticks <= now + 27000))
266                         {
267                                 graphics.blit(sdl, 320, 240, graphics.screen, true);
268                         }
269
270                         if (engine.userAccepts())
271                         {
272                                 allFadedOn = true;
273                                 engine.flushInput();
274                                 engine.clearInput();
275                                 backAlpha = 255;
276                                 titleAlpha = 255;
277                                 SDL_SetAlpha(graphics.background, backAlpha);
278                                 SDL_SetAlpha(title, titleAlpha);
279                         }
280                 }
281
282                 if ((ticks >= now + 4000) || (allFadedOn))
283                 {
284                         if (backAlpha < 255)
285                         {
286                                 backAlpha++;
287                                 SDL_SetAlpha(graphics.background, backAlpha);
288                         }
289                 }
290
291                 if ((ticks >= now + 29000) || (allFadedOn))
292                 {
293                         if (titleAlpha < 255)
294                         {
295                                 titleAlpha++;
296                                 SDL_SetAlpha(title, titleAlpha);
297                         }
298                         else
299                         {
300                                 graphics.blit(subTitle, 320, 180, graphics.screen, true);
301                                 for (int i = 0; copyright[i]; i++)
302                                         graphics.blit(copyright[i], 10, 460 - i * 18, graphics.screen, false);
303                                 graphics.blit(version, (630 - version->w), 460, graphics.screen, false);
304                                 allFadedOn = true;
305                         }
306
307                         doMusicInfo(ticks - (now + 39000));
308                 }
309
310                 Math::wrapFloat(&(offX -= 0.25), -graphics.background->w, 0);
311
312                 if (backAlpha > 0)
313                 {
314                         graphics.blit(title, 320, 100, graphics.screen, true);
315                 }
316
317                 if (allFadedOn)
318                 {
319                         drawWidgets();
320                         audio.playMenuSound(engine.processWidgets());
321                 }
322
323                 if (options)
324                 {
325                         showOptions();
326                         loadTitleWidgets();
327                         engine.setWidgetVariable("newGame", &startNewGame);
328                         engine.setWidgetVariable("loadGame", &load);
329                         engine.setWidgetVariable("continue", &cont);
330                         engine.setWidgetVariable("options", &options);
331                         engine.setWidgetVariable("help", &help);
332                         engine.setWidgetVariable("quit", &quit);
333                         options = 0;
334                         engine.flushInput();
335                 }
336
337                 if (help)
338                 {
339                         showManualHelp();
340                         engine.setWidgetVariable("back", &back);
341                         help = 0;
342                 }
343
344                 if (startNewGame)
345                 {
346                         showGameSlots();
347                         engine.setWidgetVariable("slot1", &slot[0]);
348                         engine.setWidgetVariable("slot2", &slot[1]);
349                         engine.setWidgetVariable("slot3", &slot[2]);
350                         engine.setWidgetVariable("slot4", &slot[3]);
351                         engine.setWidgetVariable("slot5", &slot[4]);
352                         engine.setWidgetVariable("slot6", &slot[5]);
353                         engine.setWidgetVariable("back", &back);
354                         startNewGame = 0;
355                 }
356
357                 for (int i = 0 ; i < 6 ; i++)
358                 {
359                         if (slot[i])
360                         {
361                                 showSkillLevels();
362                                 engine.setWidgetVariable("practice", &practice);
363                                 engine.setWidgetVariable("easy", &easy);
364                                 engine.setWidgetVariable("normal", &normal);
365                                 engine.setWidgetVariable("hard", &hard);
366                                 engine.setWidgetVariable("extreme", &extreme);
367                                 engine.setWidgetVariable("back", &back);
368                                 autoSaveSlot = i;
369                                 slot[i] = 0;
370                         }
371                 }
372
373                 if (load)
374                 {
375                         showSaves();
376                         engine.setWidgetVariable("save1", &save[0]);
377                         engine.setWidgetVariable("save2", &save[1]);
378                         engine.setWidgetVariable("save3", &save[2]);
379                         engine.setWidgetVariable("save4", &save[3]);
380                         engine.setWidgetVariable("save5", &save[4]);
381                         engine.setWidgetVariable("back", &back);
382                         load = 0;
383                 }
384
385                 if (easy) {engine.skill = 0; break;}
386                 if (normal) {engine.skill = 1; break;}
387                 if (hard) {engine.skill = 2; break;}
388                 if (extreme) {engine.skill = 3; break;}
389                 if (practice) {engine.skill = -1; break;}
390
391                 if (cont) {load = engine.continueSaveSlot; break;}
392
393                 if (save[0]) {load = 1; break;}
394                 if (save[1]) {load = 2; break;}
395                 if (save[2]) {load = 3; break;}
396                 if (save[3]) {load = 4; break;}
397                 if (save[4]) {load = 5; break;}
398
399                 if (engine.keyState[SDL_SCANCODE_ESCAPE])
400                 {
401                         audio.playMenuSound(2);
402                         back = 1;
403                         engine.clearInput();
404                         engine.flushInput();
405                 }
406
407                 if (back)
408                 {
409                         showTitleWidgets();
410                         back = 0;
411                 }
412
413                 if (quit)
414                 {
415                         break;
416                 }
417
418                 engine.delay(frameLimit);
419                 frameLimit = SDL_GetTicks() + 16;
420         }
421
422         engine.deleteWidgets();
423
424         SDL_FillRect(graphics.screen, NULL, graphics.black);
425         graphics.updateScreen();
426         audio.stopMusic();
427         
428         if (quit)
429         {
430                 doQuit();
431                 exit(0);
432         }
433         
434         newGame();
435         
436         (autoSaveSlot < 5) ? game.autoSaveSlot = autoSaveSlot : game.autoSave = false;
437
438         if (load)
439         {
440                 loadGame(load - 1);
441                 
442                 debug(("Map Name = %s", game.mapName))
443         }
444         else if (engine.skill == -1)
445         {
446                 game.setMapName("data/practice");
447                 game.setStageName("Training Mission");
448                 engine.practice = true;
449                 game.skill = 1;
450                 return SECTION_GAME;
451         }
452         else if (engine.skill == 3)
453         {
454                 game.skill = 3;
455                 game.hasAquaLung = game.hasJetPack = true;
456         }
457         
458         if (strcmp(game.mapName, "data/spaceStation") == 0)
459         {
460                 game.setMapName("data/finalBattle");
461                 game.setStageName("Final Battle");
462                 return SECTION_GAME;
463         }
464
465         return SECTION_HUB;
466 }
467
468 /**
469 * Loads and shows the credits at the end of the game.
470 */
471 void doCredits()
472 {
473         map.clear();
474
475         char *line;
476         char string[100];
477         int i = 0;
478         int numberOfCredits = 0;
479         int pos1 = 0, pos2 = 0, size = 0;
480         float *y, deviceY;
481
482         SDL_Surface *backdrop = graphics.quickSprite("CreditsBackGround", graphics.loadImage("gfx/main/creditsBack.png"));
483
484         engine.loadData(_("data/credits"));
485
486         line = strtok((char*)engine.dataBuffer, "\n");
487
488         sscanf(line, "%d", &numberOfCredits);
489
490         y = new float[numberOfCredits];
491          SDL_Surface **credit = new SDL_Surface*[numberOfCredits];
492
493         line = strtok(NULL, "\n");
494
495         pos1 = 520;
496
497         graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
498
499         while (line)
500         {
501                 sscanf(line, "%d %d %[^\n\r]", &pos2, &size, string);
502
503                 pos1 += pos2;
504
505                 y[i] = pos1;
506
507                 if (pos2 == 220)
508                         deviceY = pos1 - 50;
509
510                 graphics.setFontSize(size);
511                 credit[i] = graphics.quickSprite("credit", graphics.getString(string, true));
512
513                 i++;
514
515                 if (i == numberOfCredits)
516                 {
517                         break;
518                 }
519
520                 line = strtok(NULL, "\n");
521         }
522         
523         SDL_Surface *device = graphics.quickSprite("credit", graphics.loadImage("gfx/main/creditsDevice.png"));
524
525         if (!deviceY)
526                 deviceY = y[numberOfCredits - 7] - 50;
527
528         audio.loadMusic("music/credits");
529         audio.playMusic();
530
531         engine.resetTimeDifference();
532         Uint32 now = SDL_GetTicks();
533
534         while (y[numberOfCredits - 1] > 350)
535         {
536                 unsigned int frameLimit = SDL_GetTicks() + 16;
537
538                 graphics.updateScreen();
539                 engine.getInput();
540                 config.populate();
541
542                 engine.doTimeDifference();
543
544                 SDL_FillRect(graphics.screen, NULL, graphics.black);
545                 graphics.blit(backdrop, 0, 365, graphics.screen, false);
546
547                 float speed = 0.25;
548
549                 if (engine.keyState[SDL_SCANCODE_DOWN] || engine.joyY > 25000)
550                         speed = 1.0;
551                 else if (engine.keyState[SDL_SCANCODE_UP] || engine.joyY < -25000)
552                         speed = -1.0;
553                 
554                 deviceY -= (speed* engine.getTimeDifference());
555                 
556                 if ((deviceY > 10) && (deviceY < 470))
557                 {
558                         graphics.blit(device, 320, (int)deviceY, graphics.screen, true);
559                 }
560
561                 for (i = 0 ; i < numberOfCredits ; i++)
562                 {
563                         y[i] -= (speed * engine.getTimeDifference());
564                         
565                         if ((y[i] > 10) && (y[i] < 470))
566                         {
567                                 graphics.blit(credit[i], 320, (int)y[i], graphics.screen, true);
568                         }
569
570                         graphics.drawRect(0, 450, 640, 30, graphics.black, graphics.screen);
571                         graphics.drawRect(0, 0, 640, 30, graphics.black, graphics.screen);
572                 }
573
574                 doMusicInfo(SDL_GetTicks() - (now + 10000));
575
576                 engine.delay(frameLimit);
577         }
578
579         graphics.delay(12000);
580         audio.fadeMusic();
581         graphics.fadeToBlack();
582
583         delete[] y;
584         delete[] credit;
585 }
586
587 /**
588 * Shows the exit screen, mentioning the sequel and the book by Stephen Sweeney
589 */
590 void doQuit()
591 {
592         SDL_FillRect(graphics.screen, NULL, graphics.black);
593         SDL_Surface *sequel = graphics.loadImage("gfx/main/sequel.png");
594         SDL_Surface *book = graphics.loadImage("gfx/main/book.png");
595
596         graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
597         graphics.setFontSize(1);
598         graphics.drawString(_("If you like Blob Wars: Metal Blob Solid, you might also like:"), 320, 20, true, graphics.screen);
599         graphics.blit(sequel, 160, 200, graphics.screen, true);
600         graphics.blit(book, 480, 200, graphics.screen, true);
601         graphics.setFontSize(0);
602         graphics.drawString("http://blobandconquer.sf.net", 160, 380, true, graphics.screen);
603         graphics.drawString("http://www.battleforthesolarsystem.com", 480, 380, true, graphics.screen);
604         graphics.setFontSize(3);
605         graphics.drawString(_("Thank you for playing Blob Wars!"), 320, 430, true, graphics.screen);
606         graphics.setFontSize(0);
607         graphics.drawString(_("Press Space to Exit."), 320, 460, true, graphics.screen);
608
609         graphics.updateScreen();
610
611         do {
612                 SDL_Delay(16);
613                 engine.getInput();
614         } while(!engine.userAccepts());
615 }