Load / continue game updates.

This commit is contained in:
Steve 2018-03-19 22:51:37 +00:00
parent ea5e23d568
commit eae43acc73
9 changed files with 292 additions and 16 deletions

View File

@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PI 3.14159265358979323846 #define PI 3.14159265358979323846
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b))
#define CAROLINE(a,b) MIN(a,b)
#define STRNCPY(dest, src, n) strncpy(dest, src, n); dest[n - 1] = '\0' #define STRNCPY(dest, src, n) strncpy(dest, src, n); dest[n - 1] = '\0'
#define TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0) #define TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0)
#define TO_DEGREES(angleRadians) (angleRadians * 180.0 / PI) #define TO_DEGREES(angleRadians) (angleRadians * 180.0 / PI)
@ -51,8 +52,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define NUM_TEXT_BUCKETS 64 #define NUM_TEXT_BUCKETS 64
#define TEXT_TTL (1000 * 20) #define TEXT_TTL (1000 * 20)
#define MAX_WIDGETS 48
#define MAX_NAME_LENGTH 32 #define MAX_NAME_LENGTH 32
#define MAX_DESCRIPTION_LENGTH 512 #define MAX_DESCRIPTION_LENGTH 512
#define MAX_LINE_LENGTH 1024 #define MAX_LINE_LENGTH 1024

View File

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void loadMetaInfo(void); static void loadMetaInfo(void);
static void addKeyToStash(Item *item); static void addKeyToStash(Item *item);
static int sortItems(const void *a, const void *b); static int sortItems(const void *a, const void *b);
void destroyGame(void);
void initGame(void) void initGame(void)
{ {
@ -37,6 +38,8 @@ void initGame(void)
game.stats[STAT_TIME_PLAYED] = 0; game.stats[STAT_TIME_PLAYED] = 0;
loadMetaInfo(); loadMetaInfo();
loadTrophyData();
} }
int addItem(Item *item, int num) int addItem(Item *item, int num)
@ -270,6 +273,10 @@ void loadGame(void)
Tuple *t; Tuple *t;
Trophy *trophy; Trophy *trophy;
destroyGame();
initGame();
sprintf(filename, "%s/%d/game.json", app.saveDir, game.saveSlot); sprintf(filename, "%s/%d/game.json", app.saveDir, game.saveSlot);
if (fileExists(filename)) if (fileExists(filename))
@ -439,6 +446,72 @@ void restoreGameState(void)
free(text); free(text);
} }
char *getSaveWidgetLabel(char *filename)
{
static char label[MAX_NAME_LENGTH];
cJSON *root, *statsJSON;
char *text, *statName;
int i, gameDone, gameTotal, stats[STAT_MAX];
strcpy(label, "");
sprintf(filename, "%s/%d/game.json", app.saveDir, game.saveSlot);
text = readFile(filename);
root = cJSON_Parse(text);
statsJSON = cJSON_GetObjectItem(root, "stats");
memset(stats, 0, sizeof(int) * STAT_MAX);
for (i = 0 ; i < STAT_MAX ; i++)
{
statName = getLookupName("STAT_", i);
if (cJSON_GetObjectItem(statsJSON, statName))
{
stats[i] = cJSON_GetObjectItem(statsJSON, statName)->valueint;
}
}
cJSON_Delete(root);
free(text);
gameDone = stats[STAT_MISSIONS_COMPLETE] + stats[STAT_MIAS_RESCUED] + stats[STAT_TARGETS_DEFEATED] + stats[STAT_KEYS_FOUND] + stats[STAT_HEARTS_FOUND] + stats[STAT_CELLS_FOUND];
gameTotal = game.totalMissions + game.totalMIAs + game.totalTargets + game.totalKeys + game.totalHearts + game.totalCells;
sprintf(label, "%d%% - %s", getPercent(gameDone, gameTotal), timeToString(stats[STAT_TIME_PLAYED], 1));
return label;
}
void deleteSaveSlot(int slot)
{
int i, numFiles;
char path[MAX_FILENAME_LENGTH], **filenames;
sprintf(path, "%s/%d", app.saveDir, slot);
filenames = getFileList(path, &numFiles);
for (i = 0 ; i < numFiles ; i++)
{
sprintf(path, "%s/%d/%s", app.saveDir, i, filenames[i]);
if (!deleteFile(path))
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Failed to delete save file '%s'", path);
exit(1);
}
free(filenames[i]);
}
free(filenames);
}
static int sortItems(const void *a, const void *b) static int sortItems(const void *a, const void *b)
{ {
Entity *e1 = *((Entity**)a); Entity *e1 = *((Entity**)a);
@ -460,4 +533,26 @@ static int sortItems(const void *a, const void *b)
void destroyGame(void) void destroyGame(void)
{ {
Tuple *t;
Trophy *trophy;
memset(game.keys, 0, sizeof(Tuple) * MAX_KEY_TYPES);
while (game.missionStatusHead.next)
{
t = game.missionStatusHead.next;
game.missionStatusHead.next = t->next;
free(t);
}
while (game.trophyHead.next)
{
trophy = game.trophyHead.next;
game.trophyHead.next = trophy->next;
free(trophy);
}
} }

View File

@ -28,6 +28,11 @@ extern Trophy *getTrophy(char *id);
extern int lookup(char *name); extern int lookup(char *name);
extern char *readFile(const char *filename); extern char *readFile(const char *filename);
extern int writeFile(const char *filename, const char *data); extern int writeFile(const char *filename, const char *data);
extern char *timeToString(int seconds, int showHours);
extern int getPercent(float current, float total);
extern char **getFileList(const char *dir, int *count);
extern int deleteFile(char *path);
extern void loadTrophyData(void);
extern App app; extern App app;
extern Entity *self; extern Entity *self;

View File

@ -23,16 +23,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void logic(void); static void logic(void);
static void draw(void); static void draw(void);
static int getRecentSave(void); static int getRecentSave(void);
static void populateSaveSlotWidgets(void);
static void doNewGame(void);
static void doLoadGame(void);
static void doContinueGame(void);
static void doOptions(void);
static void doCredits(void);
static void doQuit(void);
static void doSaveSlot(void);
static void doLoadCancel(void);
static void doOK(void);
static void doCancel(void);
static Texture *atlasTexture; static Texture *atlasTexture;
static Atlas *title; static Atlas *title;
static int recentSaveSlot; static int recentSaveSlot;
static int saveAction;
static Widget *newGame; static Widget *newGame;
static Widget *loadGame; static Widget *load;
static Widget *continueGame; static Widget *continueGame;
static Widget *options; static Widget *options;
static Widget *credits; static Widget *credits;
static Widget *quit; static Widget *quit;
static Widget *save[MAX_SAVE_SLOTS];
static Widget *loadCancel;
static Widget *ok;
static Widget *cancel;
void initTitle(void) void initTitle(void)
{ {
@ -43,11 +59,33 @@ void initTitle(void)
title = getImageFromAtlas("gfx/main/title.png"); title = getImageFromAtlas("gfx/main/title.png");
newGame = getWidget("new", "title"); newGame = getWidget("new", "title");
loadGame = getWidget("load", "title"); newGame->action = &doNewGame;
load = getWidget("load", "title");
load->action = &doLoadGame;
continueGame = getWidget("continue", "title"); continueGame = getWidget("continue", "title");
continueGame->action = &doContinueGame;
options = getWidget("options", "title"); options = getWidget("options", "title");
options->action = &doOptions;
credits = getWidget("credits", "title"); credits = getWidget("credits", "title");
credits->action = &doCredits;
quit = getWidget("exit", "title"); quit = getWidget("exit", "title");
quit->action = &doQuit;
populateSaveSlotWidgets();
loadCancel = getWidget("cancel", "load");
loadCancel->action = doLoadCancel;
ok = getWidget("ok", "destroy");
ok->action = doOK;
cancel = getWidget("cancel", "destroy");
cancel->action = doCancel;
recentSaveSlot = getRecentSave(); recentSaveSlot = getRecentSave();
@ -59,7 +97,7 @@ void initTitle(void)
} }
else else
{ {
loadGame->disabled = 1; load->disabled = 1;
continueGame->disabled = 1; continueGame->disabled = 1;
} }
@ -78,8 +116,8 @@ static void draw(void)
{ {
blitRect(atlasTexture->texture, SCREEN_WIDTH / 2, 175, &title->rect, 1); blitRect(atlasTexture->texture, SCREEN_WIDTH / 2, 175, &title->rect, 1);
drawText(10, SCREEN_HEIGHT - 30, 18, TA_LEFT, colors.white, "Copyright 2014, 2018 Parallel Realities"); drawText(10, SCREEN_HEIGHT - 30, 16, TA_LEFT, colors.white, "Copyright 2014, 2018 Parallel Realities");
drawText(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 30, 18, TA_RIGHT, colors.white, "Version %.2f.%d", VERSION, REVISION); drawText(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 30, 16, TA_RIGHT, colors.white, "Version %.2f.%d", VERSION, REVISION);
drawWidgets(); drawWidgets();
} }
@ -110,3 +148,108 @@ static int getRecentSave(void)
return slot; return slot;
} }
static void populateSaveSlotWidgets(void)
{
int i;
char name[MAX_NAME_LENGTH], filename[MAX_FILENAME_LENGTH];
for (i = 0 ; i < MAX_SAVE_SLOTS ; i++)
{
sprintf(name, "save%d", i);
save[i] = getWidget(name, "saveSlot");
sprintf(filename, "%s/%d/game.json", app.saveDir, i);
if (fileExists(filename))
{
strcpy(save[i]->label, getSaveWidgetLabel(filename));
save[i]->value[0] = 1;
}
else
{
strcpy(save[i]->label, "(empty)");
save[i]->value[0] = 0;
}
save[i]->value[1] = i;
save[i]->action = &doSaveSlot;
}
}
static void doNewGame(void)
{
saveAction = SA_DELETE;
destroyGame();
}
static void doLoadGame(void)
{
saveAction = SA_LOAD;
showWidgetGroup("saveSlot");
loadCancel->visible = 1;
}
static void doContinueGame(void)
{
game.saveSlot = continueGame->value[1];
loadGame();
initHub();
}
static void doOptions(void)
{
}
static void doCredits(void)
{
}
static void doQuit(void)
{
exit(1);
}
static void doSaveSlot(void)
{
Widget *w;
w = getSelectedWidget();
game.saveSlot = w->value[1];
if (saveAction == SA_LOAD)
{
loadGame();
initHub();
}
else if (saveAction == SA_DELETE)
{
}
}
static void doLoadCancel(void)
{
showWidgetGroup("title");
}
static void doOK(void)
{
}
static void doCancel(void)
{
}

View File

@ -20,6 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../common.h" #include "../common.h"
enum
{
SA_LOAD,
SA_DELETE
};
extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center); extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center);
extern void doWidgets(void); extern void doWidgets(void);
extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...); extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...);
@ -35,6 +41,12 @@ extern void startSectionTransition(void);
extern long getFileModTime(char *filename); extern long getFileModTime(char *filename);
extern int fileExists(const char *filename); extern int fileExists(const char *filename);
extern void setSelectedWidget(char *name, char *group); extern void setSelectedWidget(char *name, char *group);
extern char *getSaveWidgetLabel(char *filename);
extern Widget *getSelectedWidget(void);
extern void loadGame(void);
extern void initHub(void);
extern void destroyGame(void);
extern App app; extern App app;
extern Colors colors; extern Colors colors;
extern Game game;

View File

@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "trophies.h" #include "trophies.h"
static void setSparkleColor(Trophy *t); static void setSparkleColor(Trophy *t);
static void loadTrophyData(void);
static void resetAlert(void); static void resetAlert(void);
static void nextAlert(void); static void nextAlert(void);
@ -68,12 +67,6 @@ void initTrophies(void)
page = 0; page = 0;
loadTrophyData();
maxPages = numTrophies;
maxPages /= TROPHIES_PER_PAGE;
maxPages = ceil(maxPages);
resetAlert(); resetAlert();
} }
@ -351,7 +344,7 @@ void saveTrophyScreenshot(void)
} }
} }
static void loadTrophyData(void) void loadTrophyData(void)
{ {
cJSON *root, *node; cJSON *root, *node;
char *text; char *text;
@ -395,6 +388,10 @@ static void loadTrophyData(void)
cJSON_Delete(root); cJSON_Delete(root);
free(text); free(text);
maxPages = numTrophies;
maxPages /= TROPHIES_PER_PAGE;
maxPages = ceil(maxPages);
} }
static void setSparkleColor(Trophy *t) static void setSparkleColor(Trophy *t)

View File

@ -195,6 +195,11 @@ char **getFileList(const char *dir, int *count)
return filenames; return filenames;
} }
int deleteFile(char *path)
{
return unlink(path);
}
static int stringComparator(const void *a, const void *b) static int stringComparator(const void *a, const void *b)
{ {
char **s1 = (char **)a; char **s1 = (char **)a;

View File

@ -299,7 +299,25 @@ Widget *getWidget(char *name, char *group)
void setSelectedWidget(char *name, char *group) void setSelectedWidget(char *name, char *group)
{ {
selectedWidget = getWidget(name, group); Widget *w;
int i;
for (i = 0 ; i < numWidgets ; i++)
{
w = &widgets[i];
if (strcmp(w->name, name) == 0 && strcmp(w->group, group) == 0)
{
widgetIndex = i;
selectedWidget = w;
return;
}
}
}
Widget *getSelectedWidget(void)
{
return selectedWidget;
} }
Widget *selectWidgetAt(int x, int y) Widget *selectWidgetAt(int x, int y)

View File

@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../common.h" #include "../common.h"
#include "../json/cJSON.h" #include "../json/cJSON.h"
#define MAX_WIDGETS 64
extern void clearControl(int type); extern void clearControl(int type);
extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2); extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);
extern void drawOutlineRect(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);