From 098f3df811846d3f3b3a45612be4859680d1adf6 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 19 Feb 2018 08:28:42 +0000 Subject: [PATCH] Implemented stats display. --- common.mk | 2 +- src/game/stats.c | 147 +++++++++++++++++++++++++++++++++++++++++++ src/game/stats.h | 41 ++++++++++++ src/hub/hub.c | 108 ++++++++++++++++++++----------- src/hub/hub.h | 7 +++ src/system/init.c | 1 + src/system/init.h | 1 + src/system/widgets.c | 4 +- src/util/util.c | 19 +++--- src/world/world.c | 2 + 10 files changed, 282 insertions(+), 50 deletions(-) create mode 100644 src/game/stats.c create mode 100644 src/game/stats.h diff --git a/common.mk b/common.mk index 4722617..8c644f1 100644 --- a/common.mk +++ b/common.mk @@ -47,7 +47,7 @@ _OBJS += objectives.o _OBJS += particles.o player.o plasmaBlob.o plasmaDroid.o pistolBlob.o pistolDroid.o postMission.o powerPoint.o powerPool.o pressurePlate.o pushBlock.o _OBJS += quadtree.o _OBJS += radar.o -_OBJS += shotgunBlob.o shotgunDroid.o sound.o spreadGunBlob.o spreadGunDroid.o sprites.o structures.o +_OBJS += shotgunBlob.o shotgunDroid.o sound.o spreadGunBlob.o spreadGunDroid.o sprites.o stats.o structures.o _OBJS += tankCommander.o tankTrack.o teeka.o teleporter.o text.o textures.o title.o transition.o triggers.o trophies.o _OBJS += unit.o util.o _OBJS += weapons.o weaponPickup.o widgets.o world.o worldLoader.o worldSaver.o diff --git a/src/game/stats.c b/src/game/stats.c new file mode 100644 index 0000000..b7f5ef4 --- /dev/null +++ b/src/game/stats.c @@ -0,0 +1,147 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "stats.h" + +static int page; +static float maxPages; +static char *statDescription[STAT_MAX]; +static Texture *atlasTexture; +static Atlas *left; +static Atlas *right; + +void initStats(void) +{ + page = 0; + + maxPages = STAT_TIME_PLAYED; + maxPages /= STATS_PER_PAGE; + maxPages = ceil(maxPages); + + statDescription[STAT_KEYS_FOUND] = _("Keys found"); + statDescription[STAT_CELLS_FOUND] = _("Power cells found"); + statDescription[STAT_HEARTS_FOUND] = _("Hearts found"); + statDescription[STAT_TARGETS_DEFEATED] = _("Targets defeated"); + statDescription[STAT_MIAS_RESCUED] = _("MIAs rescued"); + statDescription[STAT_DEATHS] = _("Deaths"); + statDescription[STAT_SHOTS_FIRED] = _("Shots fired"); + statDescription[STAT_SHOTS_HIT] = _("Shots hit"); + statDescription[STAT_EYE_DROID_EXPLOSION_KILLS] = _("Eyedroid Explosion kills"); + statDescription[STAT_FLY_TIME] = _("Time spent flying"); + statDescription[STAT_SWIM_TIME] = _("Time spent swimming"); + statDescription[STAT_CHERRIES_PICKED_UP] = _("Cherries picked up"); + statDescription[STAT_BATTERIES_PICKED_UP] = _("Batteries picked up"); + statDescription[STAT_WEAPONS_PICKED_UP] = _("Weapons picked up"); + statDescription[STAT_ENEMIES_KILLED] = _("Enemies killed"); + statDescription[STAT_MISSIONS_PLAYED] = _("Missions played"); + statDescription[STAT_TIME_PLAYED] = _("Time played"); + + atlasTexture = getTexture("gfx/atlas/atlas.png"); + left = getImageFromAtlas("gfx/ui/left.png"); + right = getImageFromAtlas("gfx/ui/right.png"); +} + +void doStats(void) +{ + if (isControl(CONTROL_LEFT) || app.keyboard[SDL_SCANCODE_LEFT]) + { + page = limit(page - 1, 0, maxPages - 1); + app.keyboard[SDL_SCANCODE_LEFT] = 0; + clearControl(CONTROL_LEFT); + } + + if (isControl(CONTROL_RIGHT) || app.keyboard[SDL_SCANCODE_RIGHT]) + { + page = limit(page + 1, 0, maxPages - 1); + app.keyboard[SDL_SCANCODE_LEFT] = 0; + clearControl(CONTROL_RIGHT); + } + + doWidgets(); +} + +void drawStats(void) +{ + int i, y, startIndex; + SDL_Rect r; + + SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 128); + SDL_RenderFillRect(app.renderer, NULL); + SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE); + + r.w = 500; + r.h = 600; + r.x = (SCREEN_WIDTH / 2) - r.w / 2; + r.y = (SCREEN_HEIGHT / 2) - r.h / 2; + + SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 0); + SDL_RenderFillRect(app.renderer, &r); + SDL_SetRenderDrawColor(app.renderer, 200, 200, 200, 255); + SDL_RenderDrawRect(app.renderer, &r); + + drawText(SCREEN_WIDTH / 2, 70, 28, TA_CENTER, colors.white, "Stats"); + + drawText(SCREEN_WIDTH / 2, 110, 16, TA_CENTER, colors.lightGrey, "Page %d / %d", page + 1, (int)maxPages); + + if (page > 0) + { + blitRect(atlasTexture->texture, SCREEN_WIDTH / 2 - 100, 110, &left->rect, 1); + } + + if (page < maxPages - 1) + { + blitRect(atlasTexture->texture, SCREEN_WIDTH / 2 + 100, 110, &right->rect, 1); + } + + SDL_SetRenderDrawColor(app.renderer, 128, 128, 128, 255); + SDL_RenderDrawLine(app.renderer, r.x, 150, r.x + r.w, 150); + + y = 170; + + startIndex = (page * STATS_PER_PAGE); + + for (i = startIndex ; i < startIndex + STATS_PER_PAGE ; i++) + { + if (i < STAT_TIME_PLAYED) + { + drawText(r.x + 20, y, 18, TA_LEFT, colors.white, statDescription[i]); + + switch (i) + { + case STAT_SWIM_TIME: + case STAT_FLY_TIME: + drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%s", timeToString(game.stats[i] / FPS, 0)); + break; + + default: + drawText(r.x + r.w - 20, y, 18, TA_RIGHT, colors.white, "%d", game.stats[i]); + break; + } + + y += 40; + } + } + + drawText(r.x + 20, 555, 18, TA_LEFT, colors.white, statDescription[STAT_TIME_PLAYED]); + drawText(r.x + r.w - 20, 555, 18, TA_RIGHT, colors.white, timeToString(game.stats[STAT_TIME_PLAYED], 1)); + + drawWidgets(); +} diff --git a/src/game/stats.h b/src/game/stats.h new file mode 100644 index 0000000..50e6a3b --- /dev/null +++ b/src/game/stats.h @@ -0,0 +1,41 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "../common.h" + +#define STATS_PER_PAGE 9 + +extern void drawWidgets(void); +extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...); +extern void drawRect(int x, int y, int w, int h, int r, int g, int b, int a); +extern void drawOutlineRect(int x, int y, int w, int h, int r, int g, int b, int a); +extern char *timeToString(int seconds, int showHours); +extern float limit(float i, float low, float high); +extern int isControl(int type); +extern void clearControl(int type); +extern Atlas *getImageFromAtlas(char *filename); +extern void blitRectScaled(SDL_Texture *texture, int x, int y, int w, int h, SDL_Rect *srcRect, int center); +extern Texture *getTexture(const char *filename); +extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center); +extern void doWidgets(void); + +extern App app; +extern Colors colors; +extern Game game; diff --git a/src/hub/hub.c b/src/hub/hub.c index d3ec97d..b21a398 100644 --- a/src/hub/hub.c +++ b/src/hub/hub.c @@ -38,6 +38,7 @@ static void options(void); static void stats(void); static void trophies(void); static void quit(void); +static void returnFromStats(void); static void doCursor(void); static void doMissionSelect(void); static void doMissionInfo(void); @@ -58,7 +59,7 @@ static int unlockedMissions; static PointF cursor; static float blipSize; static float blipValue; -static int showingWidgets; +static int showing; static PointF cloudPos; void initHub(void) @@ -102,6 +103,8 @@ void initHub(void) getWidget("trophies", "hub")->action = trophies; getWidget("quit", "hub")->action = quit; + getWidget("ok", "stats")->action = returnFromStats; + loadMissions(); if (dev.cheatLevels) @@ -119,6 +122,8 @@ void initHub(void) blipValue = 0; + showing = SHOW_NONE; + cursor.x = SCREEN_WIDTH / 2; cursor.y = SCREEN_HEIGHT / 2; SDL_WarpMouseInWindow(app.window, cursor.x, cursor.y); @@ -206,29 +211,43 @@ static void logic(void) animateSprites(); - if (!showingWidgets) + switch (showing) { - doCursor(); - - if (selectedMission == NULL) - { - doMissionSelect(); - } - else - { - doMissionInfo(); - } - } - else - { - doWidgets(); - - if (app.keyboard[SDL_SCANCODE_ESCAPE]) - { - showingWidgets = 0; + case SHOW_NONE: + doCursor(); + if (selectedMission == NULL) + { + doMissionSelect(); + } + else + { + doMissionInfo(); + } + break; - app.keyboard[SDL_SCANCODE_ESCAPE] = 0; - } + case SHOW_WIDGETS: + doWidgets(); + if (app.keyboard[SDL_SCANCODE_ESCAPE]) + { + showing = SHOW_NONE; + app.keyboard[SDL_SCANCODE_ESCAPE] = 0; + } + break; + + case SHOW_STATS: + drawStats(); + doStats(); + if (app.keyboard[SDL_SCANCODE_ESCAPE]) + { + returnFromStats(); + } + break; + + case SHOW_TROPHIES: + break; + + default: + break; } } @@ -272,7 +291,7 @@ static void doMissionSelect(void) if (app.keyboard[SDL_SCANCODE_ESCAPE]) { showWidgetGroup("hub"); - showingWidgets = 1; + showing = SHOW_WIDGETS; app.keyboard[SDL_SCANCODE_ESCAPE] = 0; } else if (isControl(CONTROL_FIRE) || app.mouse.button[SDL_BUTTON_LEFT]) @@ -319,20 +338,27 @@ static void draw(void) drawInfoBar(); - if (!showingWidgets) + switch (showing) { - if (selectedMission != NULL) - { - drawMissionInfo(); + case SHOW_NONE: + if (selectedMission != NULL) + { + drawMissionInfo(); + drawWidgets(); + } + blitRect(atlasTexture->texture, cursor.x, cursor.y, getCurrentFrame(cursorSpr), 1); + break; - drawWidgets(); - } - - blitRect(atlasTexture->texture, cursor.x, cursor.y, getCurrentFrame(cursorSpr), 1); - } - else if (showingWidgets) - { - drawHudWidgets(); + case SHOW_WIDGETS: + drawHudWidgets(); + break; + + case SHOW_STATS: + drawStats(); + break; + + case SHOW_TROPHIES: + break; } } @@ -590,7 +616,7 @@ static void startMission(void) static void cancel(void) { hideAllWidgets(); - showingWidgets = 0; + showing = SHOW_NONE; selectedMission = NULL; app.keyboard[SDL_SCANCODE_ESCAPE] = 0; } @@ -602,7 +628,8 @@ static void options(void) static void stats(void) { - + showing = SHOW_STATS; + showWidgetGroup("stats"); } static void trophies(void) @@ -615,6 +642,13 @@ static void quit(void) } +static void returnFromStats(void) +{ + showWidgetGroup("hub"); + showing = SHOW_WIDGETS; + app.keyboard[SDL_SCANCODE_ESCAPE] = 0; +} + static void loadMissions(void) { cJSON *root, *node; diff --git a/src/hub/hub.h b/src/hub/hub.h index 7186573..c414117 100644 --- a/src/hub/hub.h +++ b/src/hub/hub.h @@ -23,6 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define CURSOR_SPEED 8 +#define SHOW_NONE 0 +#define SHOW_WIDGETS 1 +#define SHOW_STATS 2 +#define SHOW_TROPHIES 3 + extern int getDistance(int x1, int y1, int x2, int y2); extern char *readFile(const char *filename); extern Atlas *getImageFromAtlas(char *filename); @@ -54,6 +59,8 @@ extern void drawBackground(SDL_Texture *texture, SDL_Rect *srcRect); extern void scrollBackground(float x, float y); extern double randF(void); extern void doWidgets(void); +extern void drawStats(void); +extern void doStats(void); extern App app; extern Colors colors; diff --git a/src/system/init.c b/src/system/init.c index 72c1cb5..35beca5 100644 --- a/src/system/init.c +++ b/src/system/init.c @@ -142,6 +142,7 @@ void initGameSystem(void) initSounds, initSprites, initEntityFactory, + initStats, initTrophies }; diff --git a/src/system/init.h b/src/system/init.h index 82ceec3..cab81a8 100644 --- a/src/system/init.h +++ b/src/system/init.h @@ -38,6 +38,7 @@ extern void initSprites(void); extern void initWidgets(void); extern void initTrophies(void); extern void initGame(void); +extern void initStats(void); extern void initEntityFactory(void); extern void destroyLookups(void); extern void destroyFonts(void); diff --git a/src/system/widgets.c b/src/system/widgets.c index 07695f9..bc18478 100644 --- a/src/system/widgets.c +++ b/src/system/widgets.c @@ -70,11 +70,11 @@ void doWidgets(void) updateWidgetValue(1); } - if (isControl(CONTROL_FIRE) || app.keyboard[SDL_SCANCODE_RETURN]) + if (isControl(CONTROL_FIRE) || app.keyboard[SDL_SCANCODE_RETURN] || app.keyboard[SDL_SCANCODE_SPACE]) { selectedWidget->action(); - app.keyboard[SDL_SCANCODE_RETURN] = 0; + app.keyboard[SDL_SCANCODE_SPACE] = app.keyboard[SDL_SCANCODE_RETURN] = 0; clearControl(CONTROL_FIRE); } } diff --git a/src/util/util.c b/src/util/util.c index 61923fd..4035822 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "util.h" +static char TIME_STRING[MAX_NAME_LENGTH]; + int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { return (MAX(x1, x2) < MIN(x1 + w1, x2 + w2)) && (MAX(y1, y2) < MIN(y1 + h1, y2 + h2)); @@ -59,27 +61,24 @@ int lineRectIntersection(int x1, int y1, int x2, int y2, SDL_Rect *r) ); } -char *timeToString(long millis, int showHours) +char *timeToString(int seconds, int showHours) { - static char TIME[MAX_NAME_LENGTH]; + int hours, minutes; - int hours, minutes, seconds; - - seconds = millis / FPS; - minutes = (seconds / FPS) % 60; + minutes = seconds / 60; hours = seconds / (FPS * FPS); - seconds %= 60; + seconds %= FPS; if (showHours) { - sprintf(TIME, "%dh %02dm %02ds", hours, minutes, seconds); + sprintf(TIME_STRING, "%dh %02dm %02ds", hours, minutes, seconds); } else { - sprintf(TIME, "%dm %02ds", minutes, seconds); + sprintf(TIME_STRING, "%dm %02ds", minutes, seconds); } - return TIME; + return TIME_STRING; } void *resize(void *array, int oldSize, int newSize) diff --git a/src/world/world.c b/src/world/world.c index 1f04fa0..ab3ef26 100644 --- a/src/world/world.c +++ b/src/world/world.c @@ -107,6 +107,8 @@ void initWorld(void) world.bob->flags |= EF_GONE; + game.stats[STAT_MISSIONS_PLAYED]++; + app.delegate.logic = logic; app.delegate.draw = draw;