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 += 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

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 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,10 +211,10 @@ static void logic(void)
animateSprites();
if (!showingWidgets)
switch (showing)
{
case SHOW_NONE:
doCursor();
if (selectedMission == NULL)
{
doMissionSelect();
@ -218,17 +223,31 @@ static void logic(void)
{
doMissionInfo();
}
}
else
{
doWidgets();
break;
case SHOW_WIDGETS:
doWidgets();
if (app.keyboard[SDL_SCANCODE_ESCAPE])
{
showingWidgets = 0;
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)
{
case SHOW_NONE:
if (selectedMission != NULL)
{
drawMissionInfo();
drawWidgets();
}
blitRect(atlasTexture->texture, cursor.x, cursor.y, getCurrentFrame(cursorSpr), 1);
}
else if (showingWidgets)
{
break;
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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