]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/loadSave.cpp
Capitalize Makefiles.
[quix0rs-blobwars.git] / src / loadSave.cpp
1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
4
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.
9
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.
13
14 See the GNU General Public License for more details.
15
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.
19
20 */
21
22 #include "loadSave.h"
23
24 void initSaveSlots()
25 {
26         char filename[PATH_MAX];
27         char string[100];
28         struct stat fileInfo;
29         int modTime = 0;
30
31         Game tempGame;
32
33         engine.continueSaveSlot = 0;
34
35         FILE *fp;
36
37         //READ SAVE GAME DATA
38         for (int i = 0 ; i < 5 ; i++)
39         {
40                 snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, i);
41
42                 fp = fopen(filename, "rb");
43
44                 if (!fp)
45                 {
46                         strlcpy(string, "%.2d - %s", sizeof string);
47                         snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], string, (i + 1), _("Empty"));
48                 }
49                 else
50                 {
51                         if (fread(&tempGame, sizeof(Game), 1, fp) != 1)
52                         {
53                                 strlcpy(string, "%.2d - %s", sizeof string);
54                                 snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], string, (i + 1), _("Corrupt Save Data"));
55                         }
56                         else
57                         {
58                                 snprintf(engine.saveSlot[i], sizeof engine.saveSlot[i], "%.2d - %s (%.2d:%.2d:%.2d)", (i + 1), _(tempGame.stageName), tempGame.totalHours, tempGame.totalMinutes, tempGame.totalSeconds);
59                         }
60
61                         if (stat(filename, &fileInfo) != -1)
62                         {
63                                 if (fileInfo.st_mtime > modTime)
64                                 {
65                                         modTime = fileInfo.st_mtime;
66                                         engine.continueSaveSlot = (i + 1);
67                                 }
68                         }
69
70                         fclose(fp);
71                 }
72         }
73         
74         debug(("Continue Save Slot = %d\n", engine.continueSaveSlot));
75 }
76
77 /*
78 Fill in later...
79 */
80 bool loadGame(int slot)
81 {
82         debug(("Loading Game #%d...\n", slot));
83         game.clear();
84
85         SDL_Delay(500);
86         char filename[PATH_MAX];
87         
88         char line[1024];
89         char string[2][1024];
90         int param[2];
91         
92         Data *data;
93
94         FILE *fp;
95         
96         int sanity = 0;
97
98         snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, slot);
99
100         fp = fopen(filename, "rb");
101         
102         if (!fp)
103         {
104                 return false;
105         }
106
107         if (fread(&game, sizeof(Game), 1, fp) != 1)
108         {
109                 fclose(fp);
110                 graphics.showErrorAndExit("The save data loaded was not in the format expected", "");
111         }
112         
113         fclose(fp);
114         
115         snprintf(filename, sizeof filename, "%spersistant%d.dat", engine.userHomeDirectory, slot);
116
117         fp = fopen(filename, "rb");
118         
119         if (!fp)
120         {
121                 return false;
122         }
123         
124         while (true)
125         {
126                 if (!fgets(line, 1024, fp)) {
127                         fclose(fp);
128                         graphics.showErrorAndExit("Unexpected end of file reading save data", "");
129                 }
130
131                 sscanf(line, "%*c %[^\"] %*c %*c %[^\"] %*c %d %d", string[0], string[1], &param[0], &param[1]);
132                 
133                 data = new Data();
134                 
135                 data->set(string[0], string[1], param[0], param[1]);
136                 
137                 debug(("Read %s %s %d %d\n", data->key, data->value, data->current, data->target));
138                 
139                 if ((data->current == -1) && (data->target == -1))
140                 {
141                         delete data;
142                         break;
143                 }
144
145                 gameData.addCompletedObjective(data);
146                 
147                 sanity++;
148                 
149                 if (sanity == 10000)
150                 {
151                         debug(("Sanity Check #1 > 10000!\n"));
152                         fclose(fp);
153                         exit(1);
154                 }
155         }
156         
157         sanity = 0;
158         
159         char stageName[50];
160         int numberOfLines = 0;
161         
162         Persistant *persistant;
163         PersistData *persistData;
164         
165         while (true)
166         {
167                 if (!fgets(line, 1024, fp)) {
168                         fclose(fp);
169                         graphics.showErrorAndExit("Unexpected end of file reading save data", "");
170                 }
171
172                 sscanf(line, "%[^\n\r]", string[0]);
173                 strlcpy(stageName, string[0], sizeof stageName);
174                 
175                 if (strcmp(stageName, "@EOF@") == 0)
176                 {
177                         break;
178                 }
179
180                 if (!fgets(line, 1024, fp)) {
181                         fclose(fp);
182                         graphics.showErrorAndExit("Unexpected end of file reading save data", "");
183                 }
184                 sscanf(line, "%d", &numberOfLines);
185                 
186                 debug(("Read %s with %d lines.\n", stageName, numberOfLines));
187                 
188                 persistant = map.createPersistant(stageName);
189                 
190                 for (int i = 0 ; i < numberOfLines ; i++)
191                 {
192                         persistData = new PersistData();
193
194                         if (!fgets(line, 1024, fp)) {
195                                 fclose(fp);
196                                 graphics.showErrorAndExit("Unexpected end of file reading save data", "");
197                         }
198
199                         strlcpy(persistData->data, line, sizeof persistData->data);
200                         
201                         //debug(("Read %d: %s", i, persistData->data));
202                         
203                         persistant->addLine(persistData->data);
204                         
205                         sanity++;
206                 
207                         if (sanity == 100000)
208                         {
209                                 debug(("Sanity Check #2 > 100000!\n"));
210                                 fclose(fp);
211                                 exit(1);
212                         }
213                 }
214         }
215
216         fclose(fp);
217         
218         debug(("Loaded Successfully\n"));
219
220         return true;
221 }
222
223 int confirmSave()
224 {
225         if (game.autoSave)
226         {
227                 return game.autoSaveSlot;
228         }
229         
230         if (!engine.loadWidgets("data/saveWidgets"))
231                 graphics.showErrorAndExit(ERR_FILE, "data/saveWidgets");
232         
233         int slot[6], quitYes, quitNo;
234         slot[0] = slot[1] = slot[2] = slot[3] = slot[4] = slot[5] = 0;
235         quitYes = quitNo = 0;
236         
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]);
243         
244         engine.setWidgetVariable("contyes", &quitYes);
245         engine.setWidgetVariable("contno", &quitNo);
246         
247         char widgetName[10];
248         widgetName[0] = 0;
249         
250         for (int i = 0 ; i < 5 ; i++)
251         {
252                 snprintf(widgetName, sizeof widgetName, "slot%d", i + 1);
253                 strlcpy(engine.getWidgetByName(widgetName)->label, engine.saveSlot[i], sizeof engine.getWidgetByName(widgetName)->label);
254         }
255         
256         engine.highlightWidget("slot1");
257         
258         int menuSound = 0;
259         
260         int rtn = -1;
261         
262         engine.showWidgetGroup("gameSlots", true);
263         engine.showWidgetGroup("continueconf", false);
264         
265         graphics.setFontSize(4);
266         SDL_Surface *title = graphics.quickSprite("savetitle", graphics.getString("Save Game", true));
267         
268         while (true)
269         {
270                 graphics.updateScreen();
271                 SDL_FillRect(graphics.screen, NULL, graphics.black);
272                 engine.getInput();
273                 config.populate();
274
275                 menuSound = engine.processWidgets();
276
277                 if (menuSound)
278                         audio.playMenuSound(menuSound);
279                 
280                 graphics.blit(title, 320, 100, graphics.screen, true);
281                 
282                 drawWidgets();
283                 
284                 if (slot[5])
285                 {
286                         engine.showWidgetGroup("gameSlots", false);
287                         engine.showWidgetGroup("continueconf", true);
288                         engine.highlightWidget("contno");
289                         drawWidgets();
290                         slot[5] = 0;
291                 }
292                 
293                 if (quitYes)
294                 {
295                         break;
296                 }
297                 
298                 if (quitNo)
299                 {
300                         engine.showWidgetGroup("gameSlots", true);
301                         engine.showWidgetGroup("continueconf", false);
302                         engine.highlightWidget("slot1");
303                         drawWidgets();
304                         quitNo = 0;
305                 }
306                 
307                 for (int i = 0 ; i < 5 ; i++)
308                 {
309                         if (slot[i])
310                         {
311                                 rtn = i;
312                         }
313                 }
314                 
315                 if ((slot[0]) || (slot[1]) || (slot[2]) || (slot[3]) || (slot[4]) || (slot[5]))
316                 {
317                         break;
318                 }
319
320                 SDL_Delay(16);
321         }
322         
323         SDL_FillRect(graphics.screen, NULL, graphics.black);
324         graphics.updateScreen();
325         SDL_Delay(250);
326         
327         return rtn;
328 }
329
330 void saveGame()
331 {
332         char message[256];
333
334         SDL_FillRect(graphics.screen, NULL, graphics.black);
335         graphics.updateScreen();
336         SDL_Delay(500);
337         
338         int slot = confirmSave();
339         
340         if (slot == -1)
341                 return;
342
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();
348
349         char filename[PATH_MAX];
350
351         FILE *fp;
352
353         snprintf(filename, sizeof filename, "%ssave%d.dat", engine.userHomeDirectory, slot);
354
355         fp = fopen(filename, "wb");
356         
357         if (!fp)
358         {
359                 graphics.showErrorAndExit("File write error whilst saving game", "");
360         }
361
362         if (fwrite(&game, sizeof(Game), 1, fp) != 1)
363         {
364                 fclose(fp);
365                 graphics.showErrorAndExit("File write error whilst saving game", strerror(errno));
366         }
367         
368         fclose(fp);
369         
370         snprintf(filename, sizeof filename, "%spersistant%d.dat", engine.userHomeDirectory, slot);
371
372         fp = fopen(filename, "wt");
373         
374         if (!fp)
375         {
376                 graphics.showErrorAndExit("File write error whilst saving game", "");
377         }
378         
379         createPersistantMapData();
380         
381         Data *data = (Data*)gameData.dataList.getHead();
382
383         while (data->next != NULL)
384         {
385                 data = (Data*)data->next;
386                 
387                 fprintf(fp, "\"%s\" \"%s\" %d %d\n", data->key, data->value, data->current, data->target);
388         }
389         
390         fprintf(fp, "\"@EOF@\" \"@EOF@\" -1 -1\n");
391         
392         Persistant *persistant = (Persistant*)map.persistantList.getHead();
393         PersistData *persistData;
394         
395         while (persistant->next != NULL)
396         {
397                 persistant = (Persistant*)persistant->next;
398                 
399                 if (strcmp(persistant->stageName, "@none@") == 0)
400                 {
401                         continue;
402                 }
403                 
404                 fprintf(fp, "%s\n", persistant->stageName);
405                 fprintf(fp, "%d\n", persistant->numberOfLines);
406         
407                 persistData = (PersistData*)persistant->dataList.getHead();
408                 
409                 while (persistData->next != NULL)
410                 {
411                         persistData = (PersistData*)persistData->next;
412                         
413                         fprintf(fp, "%s", persistData->data);
414                 }
415         }
416         
417         fprintf(fp, "@EOF@\n");
418         
419         fclose(fp);
420         
421         map.clear();
422         
423         SDL_Delay(500);
424
425         graphics.drawString(_("Save Complete"), 320, 260, true, graphics.screen);
426         graphics.updateScreen();
427
428         SDL_Delay(500);
429 }