Attempt to save the game and world data atomically.

This commit is contained in:
Steve 2018-04-24 08:27:42 +01:00
parent 67a6ad5422
commit 73e0e4b17a
11 changed files with 53 additions and 22 deletions

View File

@ -345,7 +345,7 @@ void loadGame(int slot)
free(filename); free(filename);
} }
void saveGame(void) void saveGame(int isTempFile)
{ {
cJSON *root, *statsJSON, *keysJSON, *keyJSON, *missionsJSON, *missionJSON, *trophiesJSON, *trophyJSON; cJSON *root, *statsJSON, *keysJSON, *keyJSON, *missionsJSON, *missionJSON, *trophiesJSON, *trophyJSON;
char *filename, *out; char *filename, *out;
@ -353,7 +353,14 @@ void saveGame(void)
Trophy *trophy; Trophy *trophy;
int i; int i;
filename = buildFormattedString("%s/%d/game.json", app.saveDir, game.saveSlot); if (!isTempFile)
{
filename = buildFormattedString("%s/%d/game.json", app.saveDir, game.saveSlot);
}
else
{
filename = buildFormattedString("%s/%d/game.json.tmp", app.saveDir, game.saveSlot);
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving game to '%s' ...", filename); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving game to '%s' ...", filename);

View File

@ -339,7 +339,7 @@ static void doOK(void)
game.saveSlot = saveSlot; game.saveSlot = saveSlot;
saveGame(); saveGame(0);
} }
static void doCancel(void) static void doCancel(void)

View File

@ -49,7 +49,7 @@ extern void loadGame(int slot);
extern void loadMusic(char *filename); extern void loadMusic(char *filename);
extern void newGame(void); extern void newGame(void);
extern void playMusic(int loop); extern void playMusic(int loop);
extern void saveGame(void); extern void saveGame(int isTempFile);
extern void setSelectedWidget(char *name, char *group); extern void setSelectedWidget(char *name, char *group);
extern void showWidgetGroup(char *group); extern void showWidgetGroup(char *group);
extern void startSectionTransition(void); extern void startSectionTransition(void);

View File

@ -596,7 +596,7 @@ static void startMission(void)
{ {
STRNCPY(game.worldId, selectedMission->id, MAX_NAME_LENGTH); STRNCPY(game.worldId, selectedMission->id, MAX_NAME_LENGTH);
saveGame(); saveGame(0);
stopMusic(); stopMusic();
@ -764,7 +764,7 @@ static void awardMissionTrophies(void)
if (save) if (save)
{ {
saveGame(); saveGame(0);
} }
} }

View File

@ -67,7 +67,7 @@ extern void playMusic(int loop);
extern void playSound(int snd, int ch); extern void playSound(int snd, int ch);
extern double randF(void); extern double randF(void);
extern char *readFile(const char *filename); extern char *readFile(const char *filename);
extern void saveGame(void); extern void saveGame(int isTempFile);
extern void scrollBackground(float x, float y); extern void scrollBackground(float x, float y);
extern Widget *selectWidgetAt(int x, int y); extern Widget *selectWidgetAt(int x, int y);
extern void showWidgetGroup(char *group); extern void showWidgetGroup(char *group);

View File

@ -24,6 +24,7 @@ static void logic(void);
static void draw(void); static void draw(void);
static void updateMissionStatus(void); static void updateMissionStatus(void);
static int getPostMissionStatus(void); static int getPostMissionStatus(void);
static void saveGameAndWorld(void);
static int status; static int status;
static float missionCompleteY; static float missionCompleteY;
@ -43,9 +44,7 @@ void initPostMission(void)
if (world.state == WS_GAME_COMPLETE) if (world.state == WS_GAME_COMPLETE)
{ {
saveGame(); saveGameAndWorld();
saveWorld();
destroyWorld(); destroyWorld();
@ -66,9 +65,7 @@ void initPostMission(void)
app.delegate.logic = &logic; app.delegate.logic = &logic;
app.delegate.draw = &draw; app.delegate.draw = &draw;
saveGame(); saveGameAndWorld();
saveWorld();
endSectionTransition(); endSectionTransition();
} }
@ -76,14 +73,14 @@ void initPostMission(void)
{ {
if (world.isReturnVisit) if (world.isReturnVisit)
{ {
saveWorld(); saveGameAndWorld();
} }
else else
{ {
restoreGameState(); restoreGameState();
}
saveGame(); saveGame(0);
}
destroyWorld(); destroyWorld();
@ -91,11 +88,31 @@ void initPostMission(void)
} }
} }
static void saveGameAndWorld(void)
{
char *src, *dest;
saveGame(1);
saveWorld();
src = buildFormattedString("%s/%d/%s.json.tmp", app.saveDir, game.saveSlot, world.id);
dest = buildFormattedString("%s/%d/%s.json", app.saveDir, game.saveSlot, world.id);
renameFile(src, dest);
src = buildFormattedString("%s/%d/game.json.tmp", app.saveDir, game.saveSlot);
dest = buildFormattedString("%s/%d/game.json", app.saveDir, game.saveSlot, world.id);
renameFile(src, dest);
free(src);
free(dest);
}
void retryMission(void) void retryMission(void)
{ {
restoreGameState(); restoreGameState();
saveGame(); saveGame(0);
initWorld(); initWorld();
} }
@ -104,7 +121,7 @@ void returnToHub(void)
{ {
restoreGameState(); restoreGameState();
saveGame(); saveGame(0);
destroyWorld(); destroyWorld();

View File

@ -34,9 +34,11 @@ extern int isAcceptControl(void);
extern float limit(float i, float low, float high); extern float limit(float i, float low, float high);
extern void playSound(int snd, int ch); extern void playSound(int snd, int ch);
extern void restoreGameState(void); extern void restoreGameState(void);
extern void saveGame(void); extern void saveGame(int isTempFile);
extern void saveWorld(void); extern void saveWorld(void);
extern void startSectionTransition(void); extern void startSectionTransition(void);
extern char *buildFormattedString(const char *format, ...);
extern int renameFile(char *src, char *dest);
extern App app; extern App app;
extern Colors colors; extern Colors colors;

View File

@ -200,6 +200,11 @@ int deleteFile(char *path)
return unlink(path) == 0; return unlink(path) == 0;
} }
int renameFile(char *src, char *dest)
{
return rename(src, dest) == 0;
}
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

@ -24,7 +24,7 @@ void initWorldTest(char *worldId)
{ {
loadGame(0); loadGame(0);
saveGame(); saveGame(0);
if (worldId != NULL) if (worldId != NULL)
{ {

View File

@ -23,6 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern void initHub(void); extern void initHub(void);
extern void initWorld(void); extern void initWorld(void);
extern void loadGame(int slot); extern void loadGame(int slot);
extern void saveGame(void); extern void saveGame(int isTempFile);
extern Game game; extern Game game;

View File

@ -32,7 +32,7 @@ void saveWorld(void)
cJSON *root; cJSON *root;
char *filename, *out; char *filename, *out;
filename = buildFormattedString("%s/%d/%s.json", app.saveDir, game.saveSlot, world.id); filename = buildFormattedString("%s/%d/%s.json.tmp", app.saveDir, game.saveSlot, world.id);
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving world to '%s' ...", filename); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving world to '%s' ...", filename);