1 /*
2 Copyright (C) 2004 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 "game.h"
22
medalWorker(void * data)23 int medalWorker(void *data)
24 {
25 char *tname = (char*)data;
26
27 SDL_mutexP(medalServer.lock);
28
29 int type = medalServer.postMedal(tname);
30
31 while (!graphics.canShowMedalMessage())
32 {
33 SDL_Delay(100);
34 }
35
36 SDL_Delay(100);
37
38 if (type >= 1 && type <= 3)
39 {
40 audio.playSound(SND_ITEM, 0);
41 graphics.showMedalMessage(type, medalServer.getMessage());
42
43 if (medalServer.hasRuby())
44 {
45 while (!graphics.canShowMedalMessage())
46 {
47 SDL_Delay(100);
48 }
49
50 SDL_Delay(100);
51
52 audio.playSound(SND_ITEM, 0);
53 graphics.showMedalMessage(4, medalServer.getRubyMessage());
54 }
55 }
56
57 SDL_mutexV(medalServer.lock);
58
59 delete tname;
60
61 return type;
62 }
63
presentPlayerMedal(const char * tname)64 void presentPlayerMedal(const char *tname)
65 {
66 // Copy the input, so that threading
67 // doesn't trip us up!
68 char *data = new char[128];
69 strcpy(data, tname);
70
71 SDL_Thread *thread = SDL_CreateThread(medalWorker, (void*)data);
72
73 if (thread == NULL)
74 {
75 printf("Unable to create thread: %s\n", SDL_GetError());
76 printf("Calling medal server directly\n");
77 medalWorker((void*)data);
78 return;
79 }
80 }
81
addScore(int amount)82 void addScore(int amount)
83 {
84 if (gameData.skill > MODE_EASY && gameData.skill < MODE_NIGHTMARE)
85 {
86 if (gameData.score < 1000000 && gameData.score + amount >= 1000000)
87 {
88 presentPlayerMedal("VK_Score1000000");
89 }
90 else if (gameData.score < 500000 && gameData.score + amount >= 500000)
91 {
92 presentPlayerMedal("VK_Score500000");
93 }
94 else if (gameData.score < 250000 && gameData.score + amount >= 250000)
95 {
96 presentPlayerMedal("VK_Score250000");
97 }
98 }
99
100 gameData.score += amount;
101 }
102
showInGameOptions()103 int showInGameOptions()
104 {
105 float brightness;
106
107 engine.flushInput();
108 engine.clearInput();
109
110 if (!engine.loadWidgets("data/inGameWidgets"))
111 graphics.showErrorAndExit(ERR_FILE, "data/inGameWidgets");
112
113 int cont, options, quit, quitno, quityes, back;
114 cont = options = quit = quitno = quityes = back = 0;
115
116 engine.setWidgetVariable("fullscreen", &engine.fullScreen);
117 engine.setWidgetVariable("sound", &gameData.soundVolume);
118 engine.setWidgetVariable("music", &gameData.musicVolume);
119 engine.setWidgetVariable("gamma", &gameData.gamma);
120 engine.setWidgetVariable("back", &back);
121
122 engine.setWidgetVariable("continue", &cont);
123 engine.setWidgetVariable("options", &options);
124 engine.setWidgetVariable("quit", &quit);
125
126 engine.setWidgetVariable("quitno", &quitno);
127 engine.setWidgetVariable("quityes", &quityes);
128 engine.showWidgetGroup("quitconf", false);
129 engine.showWidgetGroup("gameoptions", true);
130 engine.showWidgetGroup("options", false);
131
132 engine.highlightWidget("continue");
133
134 engine.flushInput();
135 engine.clearInput();
136
137 graphics.fade(210);
138
139 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
140 drawWidgets();
141
142 while (true)
143 {
144 graphics.updateScreen();
145 engine.getInput();
146
147 if (engine.keyState[SDLK_ESCAPE])
148 {
149 engine.keyState[SDLK_ESCAPE] = 0;
150 break;
151 }
152
153 if (engine.processWidgets())
154 {
155 if (engine.widgetChanged("sound"))
156 audio.setSoundVolume(gameData.soundVolume);
157
158 if (engine.widgetChanged("music"))
159 audio.setMusicVolume(gameData.musicVolume);
160
161 if (engine.widgetChanged("fullscreen"))
162 SDL_WM_ToggleFullScreen(graphics.screen);
163
164 if (engine.widgetChanged("gamma"))
165 {
166 brightness = gameData.gamma;
167 brightness /= 10;
168 SDL_SetGamma(brightness, brightness, brightness);
169 }
170
171 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
172 drawWidgets();
173 }
174
175 if (cont)
176 break;
177
178 if (options)
179 {
180 options = 0;
181 engine.highlightWidget("fullscreen");
182 engine.showWidgetGroup("gameoptions", false);
183 engine.showWidgetGroup("options", true);
184 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
185 drawWidgets();
186 }
187
188 if (back)
189 {
190 back = 0;
191 engine.highlightWidget("continue");
192 engine.showWidgetGroup("gameoptions", true);
193 engine.showWidgetGroup("options", false);
194 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
195 drawWidgets();
196 }
197
198 if (quitno)
199 {
200 engine.highlightWidget("continue");
201 engine.showWidgetGroup("gameoptions", true);
202 engine.showWidgetGroup("quitconf", false);
203 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
204 drawWidgets();
205 quitno = 0;
206 }
207
208 if (quityes)
209 return 1;
210
211 if (quit)
212 {
213 engine.showWidgetGroup("options", false);
214 engine.showWidgetGroup("gameoptions", false);
215 engine.showWidgetGroup("quitconf", true);
216 engine.highlightWidget("quitno");
217
218 graphics.drawRect(200, 150, 400, 300, graphics.black, graphics.white, graphics.screen);
219 drawWidgets();
220 quit = 0;
221 }
222 }
223
224 return 0;
225 }
226
GameOver()227 void GameOver()
228 {
229 audio.stopMusic();
230
231 if (engine.useAudio)
232 {
233 for (int i = 0 ; i < 8 ; i++)
234 {
235 Mix_HaltChannel(i);
236 }
237 }
238
239 int x = 0;
240 int y = 0;
241
242 SDL_Rect r;
243
244 for (int i = 0 ; i < 100 ; i++)
245 {
246 r.x = x;
247 r.y = y;
248 r.w = 80;
249 r.h = 60;
250
251 if (SDL_BlitSurface(graphics.screen, &r, graphics.tile[i], NULL))
252 graphics.showErrorAndExit("Game Over section didn't work", "");
253
254 x += 80;
255 if (x == 800)
256 {
257 x = 0;
258 y += 60;
259 }
260 }
261
262 x = y = 0;
263
264 float tx[100];
265 float ty[100];
266 float dx[100];
267 float dy[100];
268
269 for (int i = 0 ; i < 100 ; i++)
270 {
271 tx[i] = x;
272 ty[i] = y;
273
274 x += 80;
275 if (x == 800)
276 {
277 x = 0;
278 y += 60;
279 }
280
281 dx[i] = 0.00 + Math::rrand(-300, 300);
282 if (dx[i])
283 dx[i] /= 100;
284
285 dy[i] = 0.00 + Math::rrand(-300, 300);
286 if (dy[i])
287 dy[i] /= 100;
288 }
289
290 graphics.clearScreen(graphics.black);
291 graphics.drawString(400, 300, TXT_CENTERED, graphics.screen, "Game Over");
292
293 for (int i = 0 ; i < 100 ; i++)
294 {
295 tx[i] += dx[i];
296 ty[i] += dy[i];
297 graphics.blit(graphics.tile[i], (int)tx[i], (int)ty[i], graphics.screen, false);
298 }
299
300 audio.playSound(SND_DIRDESTROYED6, 0);
301
302 graphics.delay(250);
303
304 audio.playSound(SND_GAMEOVER, 0);
305
306 graphics.delay(1000);
307
308 unsigned int then = SDL_GetTicks() + 6000;
309
310 graphics.setFontSize(4);
311 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
312
313 engine.resetTimeDifference();
314
315 audio.playSound(SND_DIRDESTROYED3, 1);
316
317 while (true)
318 {
319 engine.doTimeDifference();
320 graphics.updateScreen();
321 engine.getInput();
322
323 graphics.clearScreen(graphics.black);
324 graphics.drawString(400, 300, TXT_CENTERED, graphics.screen, "Game Over");
325
326 for (int i = 0 ; i < 100 ; i++)
327 {
328 graphics.blit(graphics.tile[i], (int)tx[i], (int)ty[i], graphics.screen, false);
329 tx[i] += (dx[i] * engine.getTimeDifference());
330 ty[i] += (dy[i] * engine.getTimeDifference());
331 }
332
333 if (SDL_GetTicks() > then)
334 break;
335 }
336 }
337
doGameStuff()338 void doGameStuff()
339 {
340 engine.doTimeDifference();
341 graphics.updateScreen();
342 engine.getInput();
343
344 graphics.drawBackground();
345 doDirectories();
346 doItems();
347 doViruses();
348 doParticles();
349
350 if (gameData.skill < 3)
351 for (int i = 0 ; i < 4 ; i++)
352 graphics.blit(gameData.base[i].image, gameData.base[i].x, gameData.base[i].y, graphics.screen, true);
353
354 graphics.blit(graphics.infoBar, 0, 0, graphics.screen, false);
355
356 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
357 graphics.setFontSize(0);
358 graphics.drawString(10, 10, TXT_LEFT, graphics.screen, "Score: %.7d", gameData.score);
359 graphics.drawString(789, 10, TXT_RIGHT, graphics.screen, "Round: %d", gameData.level);
360
361 graphics.drawString(265, 10, TXT_RIGHT, graphics.screen, "Kernel Power");
362 graphics.drawRect(275, 11, 152, 12, graphics.black, graphics.white, graphics.screen);
363 if (gameData.kernelPower > 0)
364 {
365 if (gameData.kernelPower > 150)
366 graphics.drawRect(276, 12, ((int)gameData.kernelPower / 2), 10, graphics.green, graphics.screen);
367 else if (gameData.kernelPower > 50)
368 graphics.drawRect(276, 12, ((int)gameData.kernelPower / 2), 10, graphics.yellow, graphics.screen);
369 else
370 graphics.drawRect(276, 12, ((int)gameData.kernelPower / 2), 10, graphics.red, graphics.screen);
371 }
372
373 graphics.drawString(515, 10, TXT_LEFT, graphics.screen, "Thread Blockers: %d", gameData.threadStops);
374 }
375
doRoundClear()376 void doRoundClear()
377 {
378 if (engine.useAudio)
379 {
380 Mix_HaltChannel(6);
381 Mix_HaltChannel(7);
382 Mix_ResumeMusic();
383 }
384
385 Sprite *targeter = graphics.getSprite("Targeter", true);
386
387 unsigned int now;
388 unsigned int info = 0;
389
390 int bonus = 0;
391
392 bonus = gameData.roundVirusesKilled;
393
394 if (gameData.roundFilesLost)
395 {
396 bonus /= gameData.roundFilesLost;
397 }
398
399 bonus *= (gameData.activeDirs * 10);
400
401 unsigned int then = SDL_GetTicks() + 2000;
402
403 if (gameData.level + 1 == 5)
404 {
405 presentPlayerMedal("VK_Round5");
406 }
407 else if (gameData.level + 1 == 10)
408 {
409 presentPlayerMedal("VK_Round10");
410 }
411 else if (gameData.level + 1 == 15)
412 {
413 presentPlayerMedal("VK_Round15");
414 }
415 else if (gameData.level + 1 == 20)
416 {
417 presentPlayerMedal("VK_Round20");
418 }
419
420 while (true)
421 {
422 doGameStuff();
423
424 now = SDL_GetTicks();
425
426 if (now > then + 500)
427 {
428 graphics.fade(210);
429 }
430
431 if (now > then + 1000)
432 {
433 info = 1;
434 }
435
436 if (now > then + 3000)
437 {
438 info = 2;
439 }
440
441 if (now > then + 4000)
442 {
443 info = 3;
444 }
445
446 if (now > then + 5000)
447 {
448 break;
449 }
450
451 if (info == 1)
452 {
453 graphics.setFontSize(4);
454 graphics.drawString(400, 100, TXT_CENTERED, graphics.screen, "Round #%d Clear", gameData.level);
455 graphics.setFontSize(2);
456
457 graphics.drawString(400, 200, TXT_RIGHT, graphics.screen, "Bonus");
458 graphics.drawString(400, 250, TXT_RIGHT, graphics.screen, "Viruses Destroyed");
459 graphics.drawString(400, 300, TXT_RIGHT, graphics.screen, "Files Lost");
460 graphics.drawString(400, 350, TXT_RIGHT, graphics.screen, "Directories Lost");
461 graphics.drawString(400, 400, TXT_RIGHT, graphics.screen, "Items Collected");
462 graphics.drawString(400, 450, TXT_RIGHT, graphics.screen, "Biggest Chain");
463
464 if (bonus > 0)
465 {
466 graphics.drawString(430, 200, TXT_LEFT, graphics.screen, "%d", bonus);
467 }
468 else
469 {
470 graphics.drawString(430, 200, TXT_LEFT, graphics.screen, "None");
471 }
472
473 graphics.drawString(430, 250, TXT_LEFT, graphics.screen, "%.4d", gameData.roundVirusesKilled);
474 graphics.drawString(430, 300, TXT_LEFT, graphics.screen, "%.4d", gameData.roundFilesLost);
475 graphics.drawString(430, 350, TXT_LEFT, graphics.screen, "%.4d", gameData.roundDirsLost);
476 graphics.drawString(430, 400, TXT_LEFT, graphics.screen, "%.4d", gameData.roundItemsCollected);
477 graphics.drawString(430, 450, TXT_LEFT, graphics.screen, "%.4d", gameData.roundBiggestChain);
478 }
479 else if (info == 3)
480 {
481 graphics.setFontSize(4);
482 graphics.drawString(400, 270, TXT_CENTERED, graphics.screen, "Round #%d", (gameData.level + 1));
483 graphics.drawString(400, 320, TXT_CENTERED, graphics.screen, "READY!");
484 }
485
486 graphics.blit(targeter->getCurrentFrame(), engine.getMouseX(), engine.getMouseY(), graphics.screen, true);
487
488 }
489
490 engine.resetTimeDifference();
491
492 addScore(bonus);
493 }
494
doGame()495 int doGame()
496 {
497 graphics.clearScreen(graphics.black);
498 graphics.delay(500);
499
500 if (gameData.skill != MODE_ULTIMATE)
501 {
502 audio.loadMusic("music/DCC_Psychedhelic.mod");
503 }
504 else
505 {
506 audio.loadMusic("music/DarkAngel.mod");
507 }
508
509 loadRandomBackground();
510
511 Sprite *targeter = graphics.getSprite("Targeter", true);
512
513 gameData.clear();
514
515 setupActiveDirectories(4);
516
517 gameData.activeDirs = 4;
518
519 unsigned int gameOverWait = 0;
520
521 float virusSpawn = 100 * Math::rrand(2, 4);
522 float itemSpawnTime = 100 * Math::rrand(ITEM_MINWAIT, ITEM_MAXWAIT);
523
524 unsigned int roundTime = 15;
525 unsigned int minViruses = 1 + (1 * gameData.skill);
526 unsigned int maxViruses = 2 + (2 * gameData.skill);
527
528 bool addMoreViruses = true;
529
530 audio.playMusic();
531
532 unsigned int green;
533 float time = SDL_GetTicks();
534 unsigned int lastTime = (int)time + (roundTime * 100);
535 unsigned int now;
536
537 bool playingBeamSound = false;
538
539 engine.clearInput();
540 engine.flushInput();
541
542 gameData.resetForNextRound();
543
544 doGameStuff();
545 graphics.fade(210);
546 graphics.setFontSize(4);
547 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
548
549 if (gameData.skill < 3)
550 {
551 graphics.drawString(400, 270, TXT_CENTERED, graphics.screen, "Round #%d", gameData.level);
552 graphics.drawString(400, 320, TXT_CENTERED, graphics.screen, "READY!");
553 }
554 else if (gameData.skill == 3)
555 {
556 graphics.drawString(400, 270, TXT_CENTERED, graphics.screen, "Nightmare Mode");
557 graphics.drawString(400, 320, TXT_CENTERED, graphics.screen, "Survive as long as you can!", gameData.level);
558 }
559 else
560 {
561 graphics.drawString(400, 270, TXT_CENTERED, graphics.screen, "The Ultimate Nightmare");
562 graphics.drawString(400, 320, TXT_CENTERED, graphics.screen, "Good Luck!", gameData.level);
563 }
564
565 graphics.delay(2000);
566
567 addViruses(minViruses);
568
569 engine.resetTimeDifference();
570
571 while (true)
572 {
573 now = SDL_GetTicks();
574
575 if (gameData.threadStopTimer != 0)
576 {
577 gameData.threadStopTimer -= (1 * engine.getTimeDifference());
578
579 if (gameData.threadStopTimer <= 0)
580 {
581 gameData.threadStopTimer = 0;
582
583 if (engine.useAudio)
584 {
585 Mix_HaltChannel(6);
586 Mix_ResumeMusic();
587 }
588 }
589 }
590
591 doGameStuff();
592
593 graphics.blit(targeter->getCurrentFrame(), engine.getMouseX(), engine.getMouseY(), graphics.screen, true);
594
595 if (engine.mouseLeft)
596 {
597 if (gameData.kernelPower > 0)
598 {
599 if (gameData.threadStopTimer == 0)
600 {
601 gameData.kernelPower -= (.4 * engine.getTimeDifference());
602 }
603
604 green = SDL_MapRGB(graphics.screen->format, Math::rrand(0, 100), Math::rrand(0, 255), 0);
605
606 graphics.drawLine(0, 599, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
607 graphics.drawLine(1, 598, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
608 graphics.drawLine(2, 597, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
609 graphics.drawLine(3, 596, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
610
611 graphics.drawLine(799, 599, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
612 graphics.drawLine(798, 598, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
613 graphics.drawLine(797, 597, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
614 graphics.drawLine(796, 596, engine.getMouseX(), engine.getMouseY(), green, graphics.screen);
615
616 doVirusBulletCollisions();
617 doBulletItemCollisions();
618
619 addBulletParticle();
620
621 Math::limitFloat(&gameData.kernelPower, 0, 300);
622
623 if (!playingBeamSound)
624 {
625 audio.playSound(SND_KERNALBEAM, 7, -1);
626 playingBeamSound = true;
627 }
628 }
629 else
630 {
631 if (engine.useAudio)
632 {
633 Mix_HaltChannel(7);
634 }
635 }
636 }
637 else
638 {
639 gameData.kernelPower += (.1 * engine.getTimeDifference());
640 Math::limitFloat(&gameData.kernelPower, 0, 300);
641
642 if (engine.useAudio)
643 {
644 Mix_HaltChannel(7);
645 }
646
647 playingBeamSound = false;
648 }
649
650 if ((engine.mouseRight) && (gameData.threadStops > 0))
651 {
652 if (gameData.threadStopTimer == 0)
653 {
654 gameData.threadStopTimer = 600;
655 engine.mouseRight = 0;
656
657 if (engine.useAudio)
658 {
659 Mix_PauseMusic();
660 }
661
662 audio.playSound(SND_CLOCK, 6, 2);
663 gameData.threadStops--;
664 }
665 }
666
667 if (addMoreViruses)
668 {
669 virusSpawn -= (1 * engine.getTimeDifference());
670
671 if ((virusSpawn <= 0) && (gameData.threadStopTimer == 0))
672 {
673 virusSpawn = 100 * Math::rrand(2, 4);
674 virusSpawn -= (gameData.level * 5);
675 Math::limitFloat(&virusSpawn, 25, 400);
676 addViruses(Math::rrand(minViruses, maxViruses));
677 }
678 }
679 else if ((gameData.activeViruses == 0) && (gameData.activeDirs > 0))
680 {
681 doRoundClear();
682
683 gameData.level++;
684
685 if ((gameData.level % 2) == 0)
686 {
687 roundTime += 5;
688 }
689 else
690 {
691 maxViruses += 2;
692 }
693
694 lastTime = (int)time;
695
696 minViruses += 2;
697
698 time = lastTime = now;
699 lastTime += (roundTime * 100);
700
701 gameData.resetForNextRound();
702 addViruses(minViruses);
703
704 addMoreViruses = true;
705 }
706
707 if (gameData.threadStopTimer == 0)
708 {
709 time += (1 * engine.getTimeDifference());
710 }
711
712 itemSpawnTime -= (1 * engine.getTimeDifference());
713
714 if (itemSpawnTime <= 0)
715 {
716 addItem();
717
718 if (gameData.skill < 3)
719 {
720 itemSpawnTime = 100 * Math::rrand(ITEM_MINWAIT, ITEM_MAXWAIT);
721 }
722 else
723 {
724 itemSpawnTime = 100 * Math::rrand(ITEM_MINWAIT * 2, ITEM_MAXWAIT * 2);
725 }
726 }
727
728 #if !USEPAK
729 //if (time < lastTime)
730 //graphics.drawString(10, 50, TXT_LEFT, graphics.screen, "Round Time: %d ", (lastTime - time) / 100);
731
732 //if (now < gameData.itemSpawnTime)
733 //graphics.drawString(10, 70, TXT_LEFT, graphics.screen, "Item Time: %d ", (gameData.itemSpawnTime - now) / 100);
734 #endif
735
736 if (time >= lastTime)
737 {
738 if (gameData.skill < 3)
739 {
740 addMoreViruses = false;
741 }
742 else
743 {
744 gameData.level++;
745
746 maxViruses += 2 + (2 * gameData.skill);
747
748 lastTime = (int)time;
749
750 if ((gameData.level % 3) == 0)
751 {
752 minViruses += 2 + (2 * gameData.skill);
753 }
754
755 time = lastTime = now;
756 lastTime += (roundTime * 100);
757 }
758 }
759
760 if (gameData.activeDirs > 0)
761 {
762 if (gameData.skill >= 3)
763 {
764 gameData.score += (int)(50 * engine.getTimeDifference());
765 }
766 }
767
768 if (gameData.activeDirs == 0)
769 {
770 if (gameOverWait == 0)
771 gameOverWait = SDL_GetTicks() + 3000;
772
773 if (now > gameOverWait)
774 break;
775 }
776
777 engine.doPause();
778
779 if ((engine.paused) && (gameData.activeDirs > 0))
780 {
781 graphics.fade(210);
782 graphics.setFontSize(4);
783 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
784 graphics.drawString(400, 300, TXT_CENTERED, graphics.screen, "PAUSED");
785 audio.pause();
786 }
787
788 while (engine.paused)
789 {
790 engine.getInput();
791 engine.doPause();
792 graphics.updateScreen();
793
794 if (!engine.paused)
795 {
796 audio.resume();
797 engine.resetTimeDifference();
798 }
799 }
800
801 if (engine.keyState[SDLK_ESCAPE])
802 {
803 if (engine.useAudio)
804 {
805 for (int i = 0 ; i < 8 ; i++)
806 {
807 Mix_HaltChannel(i);
808 }
809 }
810
811 if (showInGameOptions())
812 {
813 if (engine.useAudio)
814 {
815 audio.stopMusic();
816 for (int i = 0 ; i < 8 ; i++)
817 {
818 Mix_HaltChannel(i);
819 }
820 }
821 graphics.clearScreen(graphics.black);
822 graphics.delay(500);
823 gameData.virusList.clear();
824 return SECTION_TITLE;
825 }
826
827 audio.resume();
828 engine.resetTimeDifference();
829 }
830 }
831
832 if (gameData.score <= -100000)
833 {
834 presentPlayerMedal("VK_NegativeScore");
835 }
836
837 GameOver();
838
839 if (gameData.skill == MODE_HARD)
840 {
841 if (gameData.nightmareCount > 0)
842 {
843 if (gameData.nightmareCount > 50)
844 {
845 gameData.nightmareCount -= gameData.level;
846 Math::limitInt(&gameData.nightmareCount, 50, 100);
847 }
848 else
849 {
850 gameData.nightmareCount -= gameData.level;
851 Math::limitInt(&gameData.nightmareCount, 0, 100);
852 }
853
854 debug(("Nightmare Count is now %d\n", gameData.nightmareCount));
855
856 if (gameData.nightmareCount == 50)
857 {
858 presentPlayerMedal("VK_NightmareMode");
859
860 graphics.clearScreen(graphics.black);
861 graphics.delay(500);
862 graphics.setFontSize(4);
863 graphics.setFontColor(0xff, 0xff, 0x00, 0x00, 0x00, 0x00);
864 audio.playSound(SND_POWERUP, 0);
865 graphics.drawString(400, 300, TXT_CENTERED, graphics.screen, "Nightmare Mode is now Available");
866 graphics.delay(3000);
867 }
868 else if (gameData.nightmareCount == 0)
869 {
870 presentPlayerMedal("VK_UltimateNightmareMode");
871
872 graphics.clearScreen(graphics.black);
873 graphics.delay(500);
874 graphics.setFontSize(4);
875 graphics.setFontColor(0x00, 0xff, 0xff, 0x00, 0x00, 0x00);
876 audio.playSound(SND_POWERUP, 0);
877 graphics.drawString(400, 300, TXT_CENTERED, graphics.screen, "Ultimate Nightmare Mode is now Available");
878 graphics.delay(3000);
879 }
880 }
881 }
882
883 graphics.clearScreen(graphics.black);
884 graphics.delay(500);
885
886 gameData.virusList.clear();
887
888 return SECTION_HIGHSCORE;
889 }
890