Load / continue game updates.
This commit is contained in:
parent
ea5e23d568
commit
eae43acc73
|
@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PI 3.14159265358979323846
|
||||
#define MIN(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 TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0)
|
||||
#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 TEXT_TTL (1000 * 20)
|
||||
|
||||
#define MAX_WIDGETS 48
|
||||
|
||||
#define MAX_NAME_LENGTH 32
|
||||
#define MAX_DESCRIPTION_LENGTH 512
|
||||
#define MAX_LINE_LENGTH 1024
|
||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static void loadMetaInfo(void);
|
||||
static void addKeyToStash(Item *item);
|
||||
static int sortItems(const void *a, const void *b);
|
||||
void destroyGame(void);
|
||||
|
||||
void initGame(void)
|
||||
{
|
||||
|
@ -37,6 +38,8 @@ void initGame(void)
|
|||
game.stats[STAT_TIME_PLAYED] = 0;
|
||||
|
||||
loadMetaInfo();
|
||||
|
||||
loadTrophyData();
|
||||
}
|
||||
|
||||
int addItem(Item *item, int num)
|
||||
|
@ -270,6 +273,10 @@ void loadGame(void)
|
|||
Tuple *t;
|
||||
Trophy *trophy;
|
||||
|
||||
destroyGame();
|
||||
|
||||
initGame();
|
||||
|
||||
sprintf(filename, "%s/%d/game.json", app.saveDir, game.saveSlot);
|
||||
|
||||
if (fileExists(filename))
|
||||
|
@ -439,6 +446,72 @@ void restoreGameState(void)
|
|||
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)
|
||||
{
|
||||
Entity *e1 = *((Entity**)a);
|
||||
|
@ -460,4 +533,26 @@ static int sortItems(const void *a, const void *b)
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ extern Trophy *getTrophy(char *id);
|
|||
extern int lookup(char *name);
|
||||
extern char *readFile(const char *filename);
|
||||
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 Entity *self;
|
||||
|
|
153
src/game/title.c
153
src/game/title.c
|
@ -23,16 +23,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static void logic(void);
|
||||
static void draw(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 Atlas *title;
|
||||
static int recentSaveSlot;
|
||||
static int saveAction;
|
||||
static Widget *newGame;
|
||||
static Widget *loadGame;
|
||||
static Widget *load;
|
||||
static Widget *continueGame;
|
||||
static Widget *options;
|
||||
static Widget *credits;
|
||||
static Widget *quit;
|
||||
static Widget *save[MAX_SAVE_SLOTS];
|
||||
static Widget *loadCancel;
|
||||
static Widget *ok;
|
||||
static Widget *cancel;
|
||||
|
||||
void initTitle(void)
|
||||
{
|
||||
|
@ -43,11 +59,33 @@ void initTitle(void)
|
|||
title = getImageFromAtlas("gfx/main/title.png");
|
||||
|
||||
newGame = getWidget("new", "title");
|
||||
loadGame = getWidget("load", "title");
|
||||
newGame->action = &doNewGame;
|
||||
|
||||
load = getWidget("load", "title");
|
||||
load->action = &doLoadGame;
|
||||
|
||||
continueGame = getWidget("continue", "title");
|
||||
continueGame->action = &doContinueGame;
|
||||
|
||||
options = getWidget("options", "title");
|
||||
options->action = &doOptions;
|
||||
|
||||
credits = getWidget("credits", "title");
|
||||
credits->action = &doCredits;
|
||||
|
||||
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();
|
||||
|
||||
|
@ -59,7 +97,7 @@ void initTitle(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
loadGame->disabled = 1;
|
||||
load->disabled = 1;
|
||||
continueGame->disabled = 1;
|
||||
}
|
||||
|
||||
|
@ -78,8 +116,8 @@ static void draw(void)
|
|||
{
|
||||
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(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 30, 18, TA_RIGHT, colors.white, "Version %.2f.%d", VERSION, REVISION);
|
||||
drawText(10, SCREEN_HEIGHT - 30, 16, TA_LEFT, colors.white, "Copyright 2014, 2018 Parallel Realities");
|
||||
drawText(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 30, 16, TA_RIGHT, colors.white, "Version %.2f.%d", VERSION, REVISION);
|
||||
|
||||
drawWidgets();
|
||||
}
|
||||
|
@ -110,3 +148,108 @@ static int getRecentSave(void)
|
|||
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#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 doWidgets(void);
|
||||
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 int fileExists(const char *filename);
|
||||
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 Colors colors;
|
||||
extern Game game;
|
||||
|
|
|
@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "trophies.h"
|
||||
|
||||
static void setSparkleColor(Trophy *t);
|
||||
static void loadTrophyData(void);
|
||||
static void resetAlert(void);
|
||||
static void nextAlert(void);
|
||||
|
||||
|
@ -68,12 +67,6 @@ void initTrophies(void)
|
|||
|
||||
page = 0;
|
||||
|
||||
loadTrophyData();
|
||||
|
||||
maxPages = numTrophies;
|
||||
maxPages /= TROPHIES_PER_PAGE;
|
||||
maxPages = ceil(maxPages);
|
||||
|
||||
resetAlert();
|
||||
}
|
||||
|
||||
|
@ -351,7 +344,7 @@ void saveTrophyScreenshot(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void loadTrophyData(void)
|
||||
void loadTrophyData(void)
|
||||
{
|
||||
cJSON *root, *node;
|
||||
char *text;
|
||||
|
@ -395,6 +388,10 @@ static void loadTrophyData(void)
|
|||
|
||||
cJSON_Delete(root);
|
||||
free(text);
|
||||
|
||||
maxPages = numTrophies;
|
||||
maxPages /= TROPHIES_PER_PAGE;
|
||||
maxPages = ceil(maxPages);
|
||||
}
|
||||
|
||||
static void setSparkleColor(Trophy *t)
|
||||
|
|
|
@ -195,6 +195,11 @@ char **getFileList(const char *dir, int *count)
|
|||
return filenames;
|
||||
}
|
||||
|
||||
int deleteFile(char *path)
|
||||
{
|
||||
return unlink(path);
|
||||
}
|
||||
|
||||
static int stringComparator(const void *a, const void *b)
|
||||
{
|
||||
char **s1 = (char **)a;
|
||||
|
|
|
@ -299,7 +299,25 @@ Widget *getWidget(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)
|
||||
|
|
|
@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../common.h"
|
||||
#include "../json/cJSON.h"
|
||||
|
||||
#define MAX_WIDGETS 64
|
||||
|
||||
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 void drawOutlineRect(int x, int y, int w, int h, int r, int g, int b, int a);
|
||||
|
|
Loading…
Reference in New Issue