Attempt to save the game and world data atomically.
This commit is contained in:
parent
67a6ad5422
commit
73e0e4b17a
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -24,7 +24,7 @@ void initWorldTest(char *worldId)
|
||||||
{
|
{
|
||||||
loadGame(0);
|
loadGame(0);
|
||||||
|
|
||||||
saveGame();
|
saveGame(0);
|
||||||
|
|
||||||
if (worldId != NULL)
|
if (worldId != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue