Implemented stats display.

This commit is contained in:
Steve 2018-02-19 08:28:42 +00:00
parent cdea5b42fb
commit 098f3df811
10 changed files with 282 additions and 50 deletions

View File

@ -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 += 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 += quadtree.o
_OBJS += radar.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 += 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 += unit.o util.o
_OBJS += weapons.o weaponPickup.o widgets.o world.o worldLoader.o worldSaver.o _OBJS += weapons.o weaponPickup.o widgets.o world.o worldLoader.o worldSaver.o

147
src/game/stats.c Normal file
View File

@ -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();
}

41
src/game/stats.h Normal file
View File

@ -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;

View File

@ -38,6 +38,7 @@ static void options(void);
static void stats(void); static void stats(void);
static void trophies(void); static void trophies(void);
static void quit(void); static void quit(void);
static void returnFromStats(void);
static void doCursor(void); static void doCursor(void);
static void doMissionSelect(void); static void doMissionSelect(void);
static void doMissionInfo(void); static void doMissionInfo(void);
@ -58,7 +59,7 @@ static int unlockedMissions;
static PointF cursor; static PointF cursor;
static float blipSize; static float blipSize;
static float blipValue; static float blipValue;
static int showingWidgets; static int showing;
static PointF cloudPos; static PointF cloudPos;
void initHub(void) void initHub(void)
@ -102,6 +103,8 @@ void initHub(void)
getWidget("trophies", "hub")->action = trophies; getWidget("trophies", "hub")->action = trophies;
getWidget("quit", "hub")->action = quit; getWidget("quit", "hub")->action = quit;
getWidget("ok", "stats")->action = returnFromStats;
loadMissions(); loadMissions();
if (dev.cheatLevels) if (dev.cheatLevels)
@ -119,6 +122,8 @@ void initHub(void)
blipValue = 0; blipValue = 0;
showing = SHOW_NONE;
cursor.x = SCREEN_WIDTH / 2; cursor.x = SCREEN_WIDTH / 2;
cursor.y = SCREEN_HEIGHT / 2; cursor.y = SCREEN_HEIGHT / 2;
SDL_WarpMouseInWindow(app.window, cursor.x, cursor.y); SDL_WarpMouseInWindow(app.window, cursor.x, cursor.y);
@ -206,10 +211,10 @@ static void logic(void)
animateSprites(); animateSprites();
if (!showingWidgets) switch (showing)
{ {
case SHOW_NONE:
doCursor(); doCursor();
if (selectedMission == NULL) if (selectedMission == NULL)
{ {
doMissionSelect(); doMissionSelect();
@ -218,17 +223,31 @@ static void logic(void)
{ {
doMissionInfo(); doMissionInfo();
} }
} break;
else
{
doWidgets();
case SHOW_WIDGETS:
doWidgets();
if (app.keyboard[SDL_SCANCODE_ESCAPE]) if (app.keyboard[SDL_SCANCODE_ESCAPE])
{ {
showingWidgets = 0; showing = SHOW_NONE;
app.keyboard[SDL_SCANCODE_ESCAPE] = 0; 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]) if (app.keyboard[SDL_SCANCODE_ESCAPE])
{ {
showWidgetGroup("hub"); showWidgetGroup("hub");
showingWidgets = 1; showing = SHOW_WIDGETS;
app.keyboard[SDL_SCANCODE_ESCAPE] = 0; app.keyboard[SDL_SCANCODE_ESCAPE] = 0;
} }
else if (isControl(CONTROL_FIRE) || app.mouse.button[SDL_BUTTON_LEFT]) else if (isControl(CONTROL_FIRE) || app.mouse.button[SDL_BUTTON_LEFT])
@ -319,20 +338,27 @@ static void draw(void)
drawInfoBar(); drawInfoBar();
if (!showingWidgets) switch (showing)
{ {
case SHOW_NONE:
if (selectedMission != NULL) if (selectedMission != NULL)
{ {
drawMissionInfo(); drawMissionInfo();
drawWidgets(); drawWidgets();
} }
blitRect(atlasTexture->texture, cursor.x, cursor.y, getCurrentFrame(cursorSpr), 1); blitRect(atlasTexture->texture, cursor.x, cursor.y, getCurrentFrame(cursorSpr), 1);
} break;
else if (showingWidgets)
{ case SHOW_WIDGETS:
drawHudWidgets(); drawHudWidgets();
break;
case SHOW_STATS:
drawStats();
break;
case SHOW_TROPHIES:
break;
} }
} }
@ -590,7 +616,7 @@ static void startMission(void)
static void cancel(void) static void cancel(void)
{ {
hideAllWidgets(); hideAllWidgets();
showingWidgets = 0; showing = SHOW_NONE;
selectedMission = NULL; selectedMission = NULL;
app.keyboard[SDL_SCANCODE_ESCAPE] = 0; app.keyboard[SDL_SCANCODE_ESCAPE] = 0;
} }
@ -602,7 +628,8 @@ static void options(void)
static void stats(void) static void stats(void)
{ {
showing = SHOW_STATS;
showWidgetGroup("stats");
} }
static void trophies(void) 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) static void loadMissions(void)
{ {
cJSON *root, *node; cJSON *root, *node;

View File

@ -23,6 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define CURSOR_SPEED 8 #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 int getDistance(int x1, int y1, int x2, int y2);
extern char *readFile(const char *filename); extern char *readFile(const char *filename);
extern Atlas *getImageFromAtlas(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 void scrollBackground(float x, float y);
extern double randF(void); extern double randF(void);
extern void doWidgets(void); extern void doWidgets(void);
extern void drawStats(void);
extern void doStats(void);
extern App app; extern App app;
extern Colors colors; extern Colors colors;

View File

@ -142,6 +142,7 @@ void initGameSystem(void)
initSounds, initSounds,
initSprites, initSprites,
initEntityFactory, initEntityFactory,
initStats,
initTrophies initTrophies
}; };

View File

@ -38,6 +38,7 @@ extern void initSprites(void);
extern void initWidgets(void); extern void initWidgets(void);
extern void initTrophies(void); extern void initTrophies(void);
extern void initGame(void); extern void initGame(void);
extern void initStats(void);
extern void initEntityFactory(void); extern void initEntityFactory(void);
extern void destroyLookups(void); extern void destroyLookups(void);
extern void destroyFonts(void); extern void destroyFonts(void);

View File

@ -70,11 +70,11 @@ void doWidgets(void)
updateWidgetValue(1); 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(); selectedWidget->action();
app.keyboard[SDL_SCANCODE_RETURN] = 0; app.keyboard[SDL_SCANCODE_SPACE] = app.keyboard[SDL_SCANCODE_RETURN] = 0;
clearControl(CONTROL_FIRE); clearControl(CONTROL_FIRE);
} }
} }

View File

@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "util.h" #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) 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)); 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; minutes = seconds / 60;
seconds = millis / FPS;
minutes = (seconds / FPS) % 60;
hours = seconds / (FPS * FPS); hours = seconds / (FPS * FPS);
seconds %= 60; seconds %= FPS;
if (showHours) if (showHours)
{ {
sprintf(TIME, "%dh %02dm %02ds", hours, minutes, seconds); sprintf(TIME_STRING, "%dh %02dm %02ds", hours, minutes, seconds);
} }
else 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) void *resize(void *array, int oldSize, int newSize)

View File

@ -107,6 +107,8 @@ void initWorld(void)
world.bob->flags |= EF_GONE; world.bob->flags |= EF_GONE;
game.stats[STAT_MISSIONS_PLAYED]++;
app.delegate.logic = logic; app.delegate.logic = logic;
app.delegate.draw = draw; app.delegate.draw = draw;