2 Copyright (C) 2004 Parallel Realities
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.
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.
13 See the GNU General Public License for more details.
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.
23 void createStatsPanel(int page)
25 SDL_Surface *image = graphics.getSprite("infoPanel", true)->image[0];
27 graphics.drawRect(1, 1, image->w - 2, image->h - 2, graphics.black, graphics.white, image);
35 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
37 graphics.drawString(_("Metal Blob Solid : Statistics"), 200, y, true, image);
40 Sprite *arrows = graphics.getSprite("HubArrows", true);
45 graphics.drawString(_("Skill Level:"), x1, y += 20, false, image);
46 sprintf(string, "%s", _(skill[game.skill]));
47 graphics.drawString(string, x2, y, false, image);
49 graphics.drawString(_("Score:"), x1, y += 20, false, image);
50 sprintf(string, "%d", game.score);
51 graphics.drawString(string, x2, y, false, image);
53 graphics.drawString(_("MIAs Saved:"), x1, y += 20, false, image);
54 sprintf(string, "%d", game.totalMIAsRescued);
55 graphics.drawString(string, x2, y, false, image);
57 graphics.drawString(_("Objectives Completed:"), x1, y += 20, false, image);
58 sprintf(string, "%d", game.totalObjectivesCompleted);
59 graphics.drawString(string, x2, y, false, image);
61 // Don't do this on Extreme or it will always say 100%
64 graphics.drawString(_("Percentage Complete:"), x1, y += 20, false, image);
65 sprintf(string, "%d%%", gameData.getPercentageComplete());
66 graphics.drawString(string, x2, y, false, image);
69 sprintf(string, "%s", _("Total Game Time"));
70 sprintf(string, "%s - %.2d:%.2d:%.2d", string, game.totalHours, game.totalMinutes, game.totalSeconds);
71 graphics.drawString(string, 200, y += 110, true, image);
77 graphics.drawString(_("Enemies Defeated:"), x1, y += 20, false, image);
78 sprintf(string, "%d", game.totalEnemiesDefeated);
79 graphics.drawString(string, x2, y, false, image);
81 graphics.drawString(_("Items Collected:"), x1, y += 20, false, image);
82 sprintf(string, "%d", game.totalItemsCollected);
83 graphics.drawString(string, x2, y, false, image);
85 graphics.drawString(_("Bonuses Picked Up:"), x1, y += 20, false, image);
86 sprintf(string, "%d", game.totalBonusesCollected);
87 graphics.drawString(string, x2, y, false, image);
89 graphics.drawString(_("Best Combo:"), x1, y += 20, false, image);
90 sprintf(string, _("%d Hits"), game.maxComboHits);
91 graphics.drawString(string, x2, y, false, image);
93 graphics.drawString(_("Missions Started:"), x1, y += 20, false, image);
94 sprintf(string, "%d", game.levelsStarted);
95 graphics.drawString(string, x2, y, false, image);
97 graphics.drawString(_("Continues Used:"), x1, y += 20, false, image);
98 sprintf(string, "%d", game.continuesUsed);
99 graphics.drawString(string, x2, y, false, image);
101 if ((game.continuesUsed > 0) && (game.levelsStarted > 0))
103 graphics.drawString(_("Average Continue Usage:"), x1, y += 20, false, image);
104 sprintf(string, "%d", (game.continuesUsed / game.levelsStarted));
105 graphics.drawString(string, x2, y, false, image);
108 graphics.drawString(_("Escapes Used:"), x1, y += 20, false, image);
109 sprintf(string, "%d", game.escapes);
110 graphics.drawString(string, x2, y, false, image);
120 graphics.drawString(_("Weapon"), x1, y += 20, false, image);
121 graphics.drawString(_("Ammo Used"), x2, y, false, image);
122 graphics.drawString(_("Accuracy"), x3, y, false, image);
124 graphics.drawString(_("Pistol"), x1, y += 30, false, image);
125 sprintf(string, "%d", game.bulletsFired[WP_PISTOL]);
126 graphics.drawString(string, x2, y, false, image);
127 sprintf(string, "%d%%", game.getWeaponAccuracy(WP_PISTOL));
128 graphics.drawString(string, x3, y, false, image);
130 graphics.drawString(_("Machine Gun"), x1, y += 20, false, image);
131 sprintf(string, "%d", game.bulletsFired[WP_MACHINEGUN]);
132 graphics.drawString(string, x2, y, false, image);
133 sprintf(string, "%d%%", game.getWeaponAccuracy(WP_MACHINEGUN));
134 graphics.drawString(string, x3, y, false, image);
136 graphics.drawString(_("Laser Cannon"), x1, y += 20, false, image);
137 sprintf(string, "%d", game.bulletsFired[WP_LASER]);
138 graphics.drawString(string, x2, y, false, image);
139 sprintf(string, "%d%%", game.getWeaponAccuracy(WP_LASER));
140 graphics.drawString(string, x3, y, false, image);
142 graphics.drawString(_("Grenades"), x1, y += 20, false, image);
143 sprintf(string, "%d", game.bulletsFired[WP_GRENADES]);
144 graphics.drawString(string, x2, y, false, image);
145 sprintf(string, "%d%%", game.getWeaponAccuracy(WP_GRENADES));
146 graphics.drawString(string, x3, y, false, image);
148 graphics.drawString(_("Spread Gun"), x1, y += 20, false, image);
149 sprintf(string, "%d", game.bulletsFired[WP_SPREAD]);
150 graphics.drawString(string, x2, y, false, image);
151 sprintf(string, "%d%%", game.getWeaponAccuracy(WP_SPREAD));
152 graphics.drawString(string, x3, y, false, image);
154 graphics.drawString(_("Total"), x1, y += 30, false, image);
155 sprintf(string, "%d", game.getTotalBulletsFired());
156 graphics.drawString(string, x2, y, false, image);
157 sprintf(string, "%d%%", game.getTotalAccuracy());
158 graphics.drawString(string, x3, y, false, image);
160 sprintf(string, "%s - %s", _("Most Used Weapon"), _(weapon[game.getMostUsedWeapon()].name));
161 graphics.drawString(string, 200, y += 50, true, image);
166 graphics.blit(arrows->image[0], 150, 260, image, false);
167 graphics.blit(arrows->image[2], 200, 260, image, false);
170 graphics.blit(arrows->image[1], 150, 260, image, false);
173 graphics.blit(arrows->image[3], 200, 260, image, false);
176 void loadLevelBrief(const char *levelName)
178 char briefLine[1024];
180 if (!engine.loadData(_("data/levelBrief")))
182 graphics.showErrorAndExit("Couldn't load mission briefing file (%s)", _("data/levelBrief"));
185 char *line = strtok((char*)engine.dataBuffer, "\n");
186 bool collectData = false;
187 SDL_Surface *image = graphics.getSprite("infoPanel", true)->image[0];
191 graphics.clearChatString();
197 sscanf(line, "%[^\n\r]", briefLine);
199 if (strcmp(briefLine, "@EOF@") == 0)
205 graphics.createChatString(line);
211 sscanf(line, "%*c %[^]]", briefLine);
212 if (strcmp(briefLine, levelName) == 0)
217 line = strtok(NULL, "\n");
228 graphics.drawChatString(image, 40);
231 void createObjectivesPanel(const char *levelName)
233 SDL_Surface *image = graphics.getSprite("infoPanel", true)->image[0];
235 Data *data = (Data*)gameData.dataList.getHead();
239 graphics.drawRect(1, 1, image->w - 2, image->h - 2, graphics.black, graphics.white, image);
242 char levelMIAKey[100];
247 sprintf(levelMIAKey, "%s MIAs", levelName);
249 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
251 sprintf(string, _("Information for %s"), _(levelName));
252 graphics.drawString(string, 200, y, true, image);
255 while (data->next != NULL)
257 data = (Data*)data->next;
259 if ((strcmp(data->key, levelName) == 0) || (strstr(data->key, levelMIAKey)))
263 if (strstr(data->key, "MIAs"))
265 // if it says 0 / 0 don't bother...
266 if (strcmp(data->value, "0 / 0"))
268 graphics.drawString(_("MIAs Rescued"), x1, y += 20, false, image);
269 sprintf(string, "%d / %d", data->current, data->target);
270 (data->isComplete()) ? graphics.setFontColor(0x00, 0xff, 0x00, 0x00, 0x00, 0x00) : graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
271 graphics.drawString(string, x2, y, false, image);
274 else if (!strstr(data->value, "MIA_"))
276 if ((game.skill < 3) && (strstr(data->value, "L.R.T.S.")) && (!gameData.completedWorld))
278 graphics.drawString(_("???? ???????? ????"), x1, y += 20, false, image);
282 strcpy(string, _(data->value));
284 if (strlen(string) >= 25)
287 // don't break unicode characters
288 while (((string[cut_char] >> 6) & 3) == 2)
293 string[cut_char++] = '.';
294 string[cut_char++] = '.';
295 string[cut_char++] = '.';
296 string[cut_char] = '\0';
299 graphics.drawString(string, x1, y += 20, false, image);
302 if (data->target == 1)
304 sprintf(string, "%s", (data->isComplete()) ? _("Completed") : _("Incomplete"));
308 sprintf(string, "%d / %d", data->current, data->target);
311 (data->isComplete()) ? graphics.setFontColor(0x00, 0xff, 0x00, 0x00, 0x00, 0x00) : graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
312 graphics.drawString(string, x2, y, false, image);
316 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
320 loadLevelBrief(levelName);
323 void createMIAPanel(int start, int max)
335 SDL_Surface *image = graphics.getSprite("infoPanel", true)->image[0];
337 Data *data = (Data*)gameData.dataList.getHead();
339 graphics.drawRect(1, 1, image->w - 2, image->h - 2, graphics.black, graphics.white, image);
341 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
343 graphics.drawString(_("MIA Statistics"), 200, y, true, image);
345 graphics.drawString(_("Name"), x1, y += 20, false, image);
346 graphics.drawString(_("Location"), x2, y, false, image);
347 graphics.drawString(_("Status"), x3, y, false, image);
351 while (data->next != NULL)
353 data = (Data*)data->next;
355 if (strstr(data->value, "MIA_"))
363 sprintf(name, "%s", data->value);
366 sprintf(string, "%s", strtok(NULL, "_"));
367 graphics.drawString(string, x1, y += 20, false, image);
369 graphics.drawString(_(data->key), x2, y, false, image);
371 if (data->isComplete())
373 sprintf(string, "%s", _("Found"));
374 graphics.setFontColor(0x00, 0xff, 0x00, 0x00, 0x00, 0x00);
378 sprintf(string, "%s", _("Missing"));
379 graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
382 graphics.drawString(string, x3, y, false, image);
384 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
393 Sprite *arrows = graphics.getSprite("HubArrows", true);
396 graphics.blit(arrows->image[0], 150, 260, image, false);
398 graphics.blit(arrows->image[1], 150, 260, image, false);
400 if ((end == 9) && (current + 9 < max))
401 graphics.blit(arrows->image[2], 200, 260, image, false);
403 graphics.blit(arrows->image[3], 200, 260, image, false);
406 bool requirementMet(const char *requiredLevel)
408 if (strstr(requiredLevel, "Stages"))
411 sscanf(requiredLevel, "%*s %d", &stages);
413 if (game.stagesCleared >= stages)
415 presentPlayerMedal(requiredLevel);
420 if (engine.cheatLevels)
425 if (strcmp(requiredLevel, "@none@") == 0)
430 return gameData.requiredLevelCleared(requiredLevel);
435 SDL_FillRect(graphics.screen, NULL, graphics.black);
436 graphics.delay(1000);
441 graphics.loadBackground("gfx/main/worldMap.jpg");
442 audio.loadMusic("music/forAFriend.mod");
444 // we might want this now, for medals
445 audio.loadSound(SND_ITEM, "sound/item.wav");
447 graphics.quickSprite("cheatHeader", graphics.loadImage("gfx/main/cheats.png"));
448 graphics.quickSprite("optionsHeader", graphics.loadImage("gfx/main/options.png"));
449 graphics.quickSprite("keyHeader", graphics.loadImage("gfx/main/keyConfig.png"));
450 graphics.quickSprite("joystickHeader", graphics.loadImage("gfx/main/joystickConfig.png"));
451 graphics.quickSprite("optionsBackground", graphics.loadImage("gfx/main/optionsBackground.png"));
455 Sprite *cursor = graphics.addSprite("Cursor");
456 for (int i = 0 ; i < 6 ; i++)
458 sprintf(string, "gfx/main/cursor%d.png", i + 1);
459 cursor->setFrame(i, graphics.loadImage(string), 10);
462 Sprite *newTarget = graphics.addSprite("NewTarget");
463 Sprite *visitedTarget = graphics.addSprite("VisitedTarget");
465 for (int i = 0 ; i < 5 ; i++)
467 sprintf(string, "gfx/sprites/miaSignal%d.png", i + 1);
469 newTarget->setFrame(i, graphics.loadImage(string, -60, 0, 0), 15);
470 visitedTarget->setFrame(i, graphics.loadImage(string, 0, 0, 0), 15);
473 Sprite *hubIcons = graphics.addSprite("HubIcons");
474 for (int i = 0 ; i < 6 ; i++)
476 sprintf(string, "gfx/main/hubIcon%d.png", i + 1);
477 hubIcons->setFrame(i, graphics.loadImage(string), 60);
480 SDL_Surface *infoPanel = graphics.quickSprite("infoPanel", graphics.createSurface(400, 300));
482 Sprite *hubArrows = graphics.addSprite("HubArrows");
483 hubArrows->setFrame(0, graphics.loadImage("gfx/main/hubArrowLeft.png"), 60);
484 hubArrows->setFrame(1, graphics.loadImage("gfx/main/hubArrowLeft2.png"), 60);
485 hubArrows->setFrame(2, graphics.loadImage("gfx/main/hubArrowRight.png"), 60);
486 hubArrows->setFrame(3, graphics.loadImage("gfx/main/hubArrowRight2.png"), 60);
491 engine.loadData("data/hub");
493 char *line = strtok((char*)engine.dataBuffer, "\n");
495 char name[50], level[50], requiredLevel[50];
502 graphics.setFontSize(0);
503 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
505 int numberOfHubs = 0;
507 gameData.calculateWorldCompleted();
511 sscanf(line, "%*c %[^\"] %*c %*c %[^\"] %*c %d %d %*c %[^\"] %*c", name, level, &x, &y, requiredLevel);
513 if (strcmp(name, "@EOF@") == 0)
518 // don't show boss levels on Easy (they might be cheating!)
521 if (strstr(name, "BioMech"))
523 line = strtok(NULL, "\n");
528 if (requirementMet(requiredLevel))
530 if (!gameData.levelPrefectlyCleared(name))
532 hubPoint = new HubLevel;
533 hubPoint->set(name, level, x, y);
534 hubPoint->levelNameImage = graphics.getString(_(name), false);
536 (!gameData.stagePreviouslyCleared(name)) ? hubPoint->target = newTarget : hubPoint->target = visitedTarget;
538 hubList.add(hubPoint);
543 line = strtok(NULL, "\n");
548 strcpy(level, "@none@");
549 strcpy(game.stageName, "@none@");
551 bool showData = false;
552 bool showStats = false;
553 bool showMIAs = false;
561 Data *data = (Data*)gameData.dataList.getHead();
563 while (data->next != NULL)
565 data = (Data*)data->next;
567 if (strstr(data->value, "MIA_"))
573 bool validStage = false;
575 if ((numberOfHubs == 0) && (gameData.completedWorld))
577 game.setMapName("data/spaceStation");
578 strcpy(game.stageName, "Space Station");
579 createObjectivesPanel("Space Station");
581 showStats = showMIAs = false;
584 // Wait wait wait... we're in easy mode. Game ends here.
588 return SECTION_EASYOVER;
591 presentPlayerMedal("World_Complete");
597 Uint32 frameLimit = SDL_GetTicks() + 16;
604 graphics.updateScreen();
605 graphics.drawBackground();
606 graphics.animateSprites();
610 graphics.drawRect(10, 400, 620, 20, graphics.black, graphics.white, graphics.screen);
611 sprintf(string, "%s", _("Selected Destination"));
612 sprintf(string, "%s : %s", string, _(game.stageName));
613 graphics.drawString(string, 320, 409, true, graphics.screen);
616 graphics.drawRect(10, 430, 620, 40, graphics.black, graphics.white, graphics.screen);
619 sprintf(pos, "%.3d:%.3d", engine.getMouseX(), engine.getMouseY());
620 graphics.drawString(pos, 320, 15, true, graphics.screen);
626 if (config.isControl(CONTROL::RIGHT))
631 if (config.isControl(CONTROL::LEFT))
636 if (config.isControl(CONTROL::DOWN))
641 if (config.isControl(CONTROL::UP) || config.isControl(CONTROL::JUMP))
646 if ((mouseXDelta != 0) || (mouseYDelta != 0))
648 engine.setMouse(engine.getMouseX() + (int)mouseXDelta, engine.getMouseY() + (int)mouseYDelta);
653 hubPoint = (HubLevel*)hubList.getHead();
655 // Collisions for Hub Points
656 while (hubPoint->next != NULL)
658 hubPoint = (HubLevel*)hubPoint->next;
660 graphics.blit(hubPoint->target->getCurrentFrame(), hubPoint->x, hubPoint->y, graphics.screen, false);
662 if (Collision::collision(engine.getMouseX(), engine.getMouseY(), 1, 1, hubPoint->x, hubPoint->y, 16, 16))
664 labelX = engine.getMouseX();
665 labelY = engine.getMouseY() - 20;
667 labelWidth = hubPoint->levelNameImage->w / 2;
669 Math::limitInt(&labelX, 10 + labelWidth, 630 - labelWidth);
671 graphics.blit(hubPoint->levelNameImage, labelX, labelY, graphics.screen, true);
673 if (engine.mouseLeft || config.isControl(CONTROL::FIRE))
675 game.setMapName(hubPoint->filename);
676 game.setStageName(hubPoint->stageName);
678 engine.mouseLeft = 0;
679 config.resetControl(CONTROL::FIRE);
682 if (engine.mouseRight || config.isControl(CONTROL::MAP))
684 game.setMapName(hubPoint->filename);
685 game.setStageName(hubPoint->stageName);
686 createObjectivesPanel(game.stageName);
689 engine.mouseRight = 0;
690 config.resetControl(CONTROL::MAP);
695 // Collisions for Panel
696 for (int i = ((1 - validStage) * 2) ; i < 6 ; i++)
698 graphics.blit(hubIcons->image[i], 50 + (i * 100), 440, graphics.screen, false);
699 if (Collision::collision(engine.getMouseX(), engine.getMouseY(), 1, 1, 50 + (i * 100), 440, hubIcons->image[i]->w, hubIcons->image[i]->h))
701 if (engine.mouseLeft || config.isControl(CONTROL::FIRE))
709 createObjectivesPanel(game.stageName);
710 showData = !showData;
711 showStats = showMIAs = false;
714 createMIAPanel(miaStart, miaMax);
715 showStats = showData = false;
716 showMIAs = !showMIAs;
719 createStatsPanel(page);
720 showStats = !showStats;
721 showData = showMIAs = false;
725 graphics.setFontSize(0);
726 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
733 engine.mouseLeft = false;
734 config.resetControl(CONTROL::FIRE);
739 // Collisions for Panel Buttons
740 if ((showMIAs) || (showStats))
742 // SDLK_LCTRL is the "fire" button.
743 if (engine.mouseLeft || config.isControl(CONTROL::FIRE))
745 if (Collision::collision(engine.getMouseX(), engine.getMouseY(), 1, 1, 270, 310, 32, 32))
751 Math::limitInt(&(miaStart -= 9), 0, miaMax);
752 createMIAPanel(miaStart, miaMax);
758 Math::limitInt(&(--page), 0, 2);
759 createStatsPanel(page);
762 engine.mouseLeft = 0;
763 config.resetControl(CONTROL::FIRE);
767 if (Collision::collision(engine.getMouseX(), engine.getMouseY(), 1, 1, 320, 310, 32, 32))
771 if (miaStart + 9 < miaMax)
773 Math::limitInt(&(miaStart += 9), 0, miaMax);
774 createMIAPanel(miaStart, miaMax);
780 Math::limitInt(&(++page), 0, 2);
781 createStatsPanel(page);
784 engine.mouseLeft = 0;
785 config.resetControl(CONTROL::FIRE);
790 if ((showData) || (showStats) || (showMIAs))
792 graphics.blit(infoPanel, 320, 200, graphics.screen, true);
793 if (engine.mouseLeft || config.isControl(CONTROL::FIRE))
795 showData = showStats = showMIAs = false;
799 graphics.blit(cursor->getCurrentFrame(), engine.getMouseX(), engine.getMouseY(), graphics.screen, true);
801 engine.delay(frameLimit);
802 frameLimit = SDL_GetTicks() + 16;