2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 char filename[PATH_MAX];
33 engine.continueSaveSlot = 0;
38 for (int i = 0 ; i < 5 ; i++)
40 snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, i);
42 fp = fopen(filename, "rb");
46 strlcpy(string, "%.2d - %s", sizeof string);
47 snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], string, (i + 1), _("Empty"));
51 if (fread(&tempGame, sizeof(Game), 1, fp) != 1)
53 strlcpy(string, "%.2d - %s", sizeof string);
54 snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], string, (i + 1), _("Corrupt Save Data"));
58 snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], "%.2d - %s (%.2d:%.2d:%.2d)", (i + 1), _(tempGame.stageName), tempGame.totalHours, tempGame.totalMinutes, tempGame.totalSeconds);
61 if (stat(filename, &fileInfo) != -1)
63 if (fileInfo.st_mtime > modTime)
65 modTime = fileInfo.st_mtime;
66 engine.continueSaveSlot = (i + 1);
74 debug(("Continue Save Slot = %d\n", engine.continueSaveSlot));
80 bool loadGame(int slot)
82 debug(("Loading Game #%d...\n", slot));
86 char filename[PATH_MAX];
98 snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, slot);
100 fp = fopen(filename, "rb");
107 if (fread(&game, sizeof(Game), 1, fp) != 1)
110 graphics.showErrorAndExit("The save data loaded was not in the format expected", "");
115 snprintf(filename, sizeof filename, "%spersistant%d.dat", engine.userHomeDirectory, slot);
117 fp = fopen(filename, "rb");
126 if (!fgets(line, 1024, fp)) {
128 graphics.showErrorAndExit("Unexpected end of file reading save data", "");
131 sscanf(line, "%*c %[^\"] %*c %*c %[^\"] %*c %d %d", string[0], string[1], ¶m[0], ¶m[1]);
135 data->set(string[0], string[1], param[0], param[1]);
137 debug(("Read %s %s %d %d\n", data->key, data->value, data->current, data->target));
139 if ((data->current == -1) && (data->target == -1))
145 gameData.addCompletedObjective(data);
151 debug(("Sanity Check #1 > 10000!\n"));
160 int numberOfLines = 0;
162 Persistant *persistant;
163 PersistData *persistData;
167 if (!fgets(line, 1024, fp)) {
169 graphics.showErrorAndExit("Unexpected end of file reading save data", "");
172 sscanf(line, "%[^\n\r]", string[0]);
173 strlcpy(stageName, string[0], sizeof stageName);
175 if (strcmp(stageName, "@EOF@") == 0)
180 if (!fgets(line, 1024, fp)) {
182 graphics.showErrorAndExit("Unexpected end of file reading save data", "");
184 sscanf(line, "%d", &numberOfLines);
186 debug(("Read %s with %d lines.\n", stageName, numberOfLines));
188 persistant = map.createPersistant(stageName);
190 for (int i = 0 ; i < numberOfLines ; i++)
192 persistData = new PersistData();
194 if (!fgets(line, 1024, fp)) {
196 graphics.showErrorAndExit("Unexpected end of file reading save data", "");
199 strlcpy(persistData->data, line, sizeof persistData->data);
201 //debug(("Read %d: %s", i, persistData->data));
203 persistant->addLine(persistData->data);
207 if (sanity == 100000)
209 debug(("Sanity Check #2 > 100000!\n"));
218 debug(("Loaded Successfully\n"));
227 return game.autoSaveSlot;
230 if (!engine.loadWidgets("data/saveWidgets"))
231 graphics.showErrorAndExit(ERR_FILE, "data/saveWidgets");
233 int slot[6], quitYes, quitNo;
234 slot[0] = slot[1] = slot[2] = slot[3] = slot[4] = slot[5] = 0;
235 quitYes = quitNo = 0;
237 engine.setWidgetVariable("slot1", &slot[0]);
238 engine.setWidgetVariable("slot2", &slot[1]);
239 engine.setWidgetVariable("slot3", &slot[2]);
240 engine.setWidgetVariable("slot4", &slot[3]);
241 engine.setWidgetVariable("slot5", &slot[4]);
242 engine.setWidgetVariable("slot6", &slot[5]);
244 engine.setWidgetVariable("contyes", &quitYes);
245 engine.setWidgetVariable("contno", &quitNo);
250 for (int i = 0 ; i < 5 ; i++)
252 snprintf(widgetName, sizeof widgetName, "slot%d", i + 1);
253 strlcpy(engine.getWidgetByName(widgetName)->label, engine.saveSlot[i], sizeof engine.getWidgetByName(widgetName)->label);
256 engine.highlightWidget("slot1");
262 engine.showWidgetGroup("gameSlots", true);
263 engine.showWidgetGroup("continueconf", false);
265 graphics.setFontSize(4);
266 SDL_Surface *title = graphics.quickSprite("savetitle", graphics.getString("Save Game", true));
270 graphics.updateScreen();
271 SDL_FillRect(graphics.screen, NULL, graphics.black);
275 menuSound = engine.processWidgets();
278 audio.playMenuSound(menuSound);
280 graphics.blit(title, 320, 100, graphics.screen, true);
286 engine.showWidgetGroup("gameSlots", false);
287 engine.showWidgetGroup("continueconf", true);
288 engine.highlightWidget("contno");
300 engine.showWidgetGroup("gameSlots", true);
301 engine.showWidgetGroup("continueconf", false);
302 engine.highlightWidget("slot1");
307 for (int i = 0 ; i < 5 ; i++)
315 if ((slot[0]) || (slot[1]) || (slot[2]) || (slot[3]) || (slot[4]) || (slot[5]))
323 SDL_FillRect(graphics.screen, NULL, graphics.black);
324 graphics.updateScreen();
334 SDL_FillRect(graphics.screen, NULL, graphics.black);
335 graphics.updateScreen();
338 int slot = confirmSave();
343 graphics.setFontSize(1);
344 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
345 snprintf(message, sizeof message, _("Saving Game to Save Slot #%d. Please Wait..."), slot + 1);
346 graphics.drawString(message, 320, 220, true, graphics.screen);
347 graphics.updateScreen();
349 char filename[PATH_MAX];
353 snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, slot);
355 fp = fopen(filename, "wb");
359 graphics.showErrorAndExit("File write error whilst saving game", "");
362 if (fwrite(&game, sizeof(Game), 1, fp) != 1)
365 graphics.showErrorAndExit("File write error whilst saving game", strerror(errno));
370 snprintf(filename, sizeof filename, "%spersistant%d.dat", engine.userHomeDirectory, slot);
372 fp = fopen(filename, "wt");
376 graphics.showErrorAndExit("File write error whilst saving game", "");
379 createPersistantMapData();
381 Data *data = (Data*)gameData.dataList.getHead();
383 while (data->next != NULL)
385 data = (Data*)data->next;
387 fprintf(fp, "\"%s\" \"%s\" %d %d\n", data->key, data->value, data->current, data->target);
390 fprintf(fp, "\"@EOF@\" \"@EOF@\" -1 -1\n");
392 Persistant *persistant = (Persistant*)map.persistantList.getHead();
393 PersistData *persistData;
395 while (persistant->next != NULL)
397 persistant = (Persistant*)persistant->next;
399 if (strcmp(persistant->stageName, "@none@") == 0)
404 fprintf(fp, "%s\n", persistant->stageName);
405 fprintf(fp, "%d\n", persistant->numberOfLines);
407 persistData = (PersistData*)persistant->dataList.getHead();
409 while (persistData->next != NULL)
411 persistData = (PersistData*)persistData->next;
413 fprintf(fp, "%s", persistData->data);
417 fprintf(fp, "@EOF@\n");
425 graphics.drawString(_("Save Complete"), 320, 260, true, graphics.screen);
426 graphics.updateScreen();