1 #include "game.h"
2 #include "map.h"
3 #include "message.h"
4
5 typedef struct ASSOCIATIVE ASSOCIATIVE;
6 struct ASSOCIATIVE
7 {
8 char *str;
9 int val;
10 ASSOCIATIVE *next;
11 };
12 ASSOCIATIVE *ass_linked = NULL;
13
14 static void
ass_add(char * str,int val)15 ass_add (char *str, int val)
16 {
17 ASSOCIATIVE *ass = malloc (sizeof *ass);
18 ass->str = strdup (str);
19 ass->val = val;
20 ass->next = ass_linked;
21 ass_linked = ass;
22 }
23
24 static void
ass_read(PACKFILE * file)25 ass_read (PACKFILE *file)
26 {
27 char str[100];
28 PACKFILE *chunk;
29 chunk = pack_fopen_chunk (file, 0);
30 while (!pack_feof (chunk))
31 {
32 int p;
33 for (p = 0; (str[p] = pack_getc (chunk)); p++);
34 ass_add (str, pack_igetl (chunk));
35 }
36 pack_fclose_chunk (chunk);
37 }
38
39 static void
ass_get(char const * str,int * ptr)40 ass_get (char const *str, int *ptr)
41 {
42 ASSOCIATIVE *ass = ass_linked;
43 for (; ass; ass = ass->next)
44 {
45
46 if (!strcmp (str, ass->str))
47 {
48 *ptr = ass->val;
49 break;
50 }
51 }
52 }
53
54 static void
ass_clear(void)55 ass_clear (void)
56 {
57 ASSOCIATIVE *ass = ass_linked, *next;
58 for (; ass; ass = next)
59 {
60 next = ass->next;
61 free (ass);
62 }
63 ass_linked = NULL;
64 }
65
66 #define save(var) \
67 pack_fwrite (#var, strlen (#var), chunk); \
68 pack_putc ('\0', chunk); \
69 pack_iputl (var, chunk);
70
71 #define load(var) \
72 ass_get (#var, &var);
73
74
75 static void
save_char(PACKFILE * file,int id)76 save_char (PACKFILE *file, int id)
77 {
78 int type = list[id].type;
79 PACKFILE *chunk;
80 chunk = pack_fopen_chunk (file, 0);
81 save (type);
82 save (list[id].subtype);
83 save (list[id].x);
84 save (list[id].y);
85 save (list[id].dx);
86 save (list[id].dy);
87 save (list[id].step);
88 save (list[id].hit);
89 save (list[id].alive);
90 save (list[id].fighting);
91 save (list[id].trapped);
92 save (list[id].attacked);
93 save (list[id].healing_time);
94 save (list[id].delay);
95 save (list[id].exp);
96 save (list[id].next);
97 save (list[id].lev);
98 save (list[id].maxhit);
99 save (list[id].dex);
100 save (list[id].current_level);
101 save (list[id].slain_foes[0]);
102 save (list[id].slain_foes[1]);
103 save (list[id].slain_foes[2]);
104 save (list[id].slain_foes[3]);
105 save (list[id].slain_foes[4]);
106 save (list[id].slain_foes[5]);
107 save (list[id].slain_foes[6]);
108 save (list[id].slain_foes[7]);
109 save (list[id].slain_foes[8]);
110 save (list[id].slain_foes[9]);
111 save (list[id].slain_foes[10]);
112 save (list[id].slain_foes[11]);
113 save (list[id].slain_foes[12]);
114 save (list[id].slain_foes[13]);
115 save (list[id].slain_foes[14]);
116 save (list[id].slain_foes[15]);
117 save (list[id].slain_foes[16]);
118 save (list[id].slain_foes[17]);
119 save (list[id].slain_foes[18]);
120 save (list[id].slain_foes[19]);
121 save (list[id].slain_foes[20]);
122 save (list[id].deepest_level);
123 save (list[id].potions);
124 save (list[id].sacks);
125 save (list[id].beacons);
126 save (list[id].gold);
127 save (list[id].weapon);
128 save (list[id].map);
129 save (list[id].sword);
130 save (list[id].spells[0].amount);
131 save (list[id].spells[0].active);
132 save (list[id].spells[0].max);
133 save (list[id].spells[1].amount);
134 save (list[id].spells[1].active);
135 save (list[id].spells[1].max);
136 save (list[id].spells[2].amount);
137 save (list[id].spells[2].active);
138 save (list[id].spells[2].max);
139 save (list[id].spells[3].amount);
140 save (list[id].spells[3].active);
141 save (list[id].spells[3].max);
142 save (list[id].spells[4].amount);
143 save (list[id].spells[4].active);
144 save (list[id].spells[4].max);
145 save (list[id].spells[5].amount);
146 save (list[id].spells[5].active);
147 save (list[id].spells[5].max);
148 save (list[id].beaconx);
149 save (list[id].beacony);
150 save (list[id].sacrificed_gold);
151 save (list[id].amulets_of_healing);
152 save (list[id].amulets_of_light);
153
154 pack_fclose_chunk (chunk);
155 }
156
157 static void
load_char(PACKFILE * file,int id)158 load_char (PACKFILE *file, int id)
159 {
160 int type;
161
162 memset (&list[id], 0, sizeof list[id]);
163
164 ass_read (file);
165 load (type);
166 list[id].type = type;
167 load (list[id].subtype);
168 load (list[id].x);
169 load (list[id].y);
170 load (list[id].dx);
171 load (list[id].dy);
172 load (list[id].step);
173 load (list[id].hit);
174 load (list[id].alive);
175 load (list[id].fighting);
176 load (list[id].trapped);
177 load (list[id].attacked);
178 load (list[id].healing_time);
179 load (list[id].delay);
180 load (list[id].exp);
181 load (list[id].next);
182 load (list[id].lev);
183 load (list[id].maxhit);
184 load (list[id].dex);
185 load (list[id].current_level);
186 load (list[id].slain_foes[0]);
187 load (list[id].slain_foes[1]);
188 load (list[id].slain_foes[2]);
189 load (list[id].slain_foes[3]);
190 load (list[id].slain_foes[4]);
191 load (list[id].slain_foes[5]);
192 load (list[id].slain_foes[6]);
193 load (list[id].slain_foes[7]);
194 load (list[id].slain_foes[8]);
195 load (list[id].slain_foes[9]);
196 load (list[id].slain_foes[10]);
197 load (list[id].slain_foes[11]);
198 load (list[id].slain_foes[12]);
199 load (list[id].slain_foes[13]);
200 load (list[id].slain_foes[14]);
201 load (list[id].slain_foes[15]);
202 load (list[id].slain_foes[16]);
203 load (list[id].slain_foes[17]);
204 load (list[id].slain_foes[18]);
205 load (list[id].slain_foes[19]);
206 load (list[id].slain_foes[20]);
207 load (list[id].deepest_level);
208 load (list[id].potions);
209 load (list[id].sacks);
210 load (list[id].beacons);
211 load (list[id].gold);
212 load (list[id].weapon);
213 load (list[id].map);
214 load (list[id].sword);
215 load (list[id].spells[0].amount);
216 load (list[id].spells[0].active);
217 load (list[id].spells[0].max);
218 load (list[id].spells[1].amount);
219 load (list[id].spells[1].active);
220 load (list[id].spells[1].max);
221 load (list[id].spells[2].amount);
222 load (list[id].spells[2].active);
223 load (list[id].spells[2].max);
224 load (list[id].spells[3].amount);
225 load (list[id].spells[3].active);
226 load (list[id].spells[3].max);
227 load (list[id].spells[4].amount);
228 load (list[id].spells[4].active);
229 load (list[id].spells[4].max);
230 load (list[id].spells[5].amount);
231 load (list[id].spells[5].active);
232 load (list[id].spells[5].max);
233 load (list[id].beaconx);
234 load (list[id].beacony);
235 load (list[id].sacrificed_gold);
236 load (list[id].amulets_of_healing);
237 load (list[id].amulets_of_light);
238
239 /* Save-file compatibility */
240 {
241 int i = 0;
242 ass_get ("slain_foes", &i);
243 list[id].slain_foes[0] += i;
244 }
245
246 ass_clear ();
247 }
248
249
250 int
game_save(int nr)251 game_save (int nr)
252 {
253 char name[256];
254 PACKFILE *file;
255
256 sprintf (name, "data/save%i.dat", nr);
257 file = pack_fopen (name, "wp");
258
259 if (file)
260 {
261 int i;
262 int monster;
263 PACKFILE *chunk = pack_fopen_chunk (file, 0);
264 save (notrunning);
265 save (won);
266 save (gameover);
267 save (spiral_map);
268 save (swordrun);
269 save (global_steps);
270 save (char_num);
271 monster = monster_count ();
272 save (monster);
273 save (monster_strength);
274 save (monster_max);
275 save (spawnpoints);
276 save (spawnx[0]);
277 save (spawny[0]);
278 save (spawnx[1]);
279 save (spawny[1]);
280 save (spawnx[2]);
281 save (spawny[2]);
282 save (spawnx[3]);
283 save (spawny[3]);
284 save (spawnx[4]);
285 save (spawny[4]);
286 save (temple_x);
287 save (temple_y);
288 save (swordlev);
289 save (mrand_seed);
290 pack_fclose_chunk (chunk);
291 for (i = 0; i < char_num; i++)
292 save_char (file, i);
293
294 chunk = pack_fopen_chunk (file, 0);
295 map_save (chunk);
296 pack_fclose_chunk (chunk);
297
298 pack_fclose (file);
299
300 sprintf (name, "data/save%i.html", nr);
301 messages_exit (name);
302
303 return 1;
304 }
305 return 0;
306 }
307
308 int
game_load(int nr)309 game_load (int nr)
310 {
311 char name[256];
312 PACKFILE *file;
313
314 sprintf (name, "data/save%i.dat", nr);
315 file = pack_fopen (name, "rp");
316
317 if (file)
318 {
319 int i;
320 int monster;
321 PACKFILE *chunk;
322 ass_read (file);
323 load (notrunning);
324 load (won);
325 load (gameover);
326 load (spiral_map);
327 load (swordrun);
328 load (global_steps);
329 load (char_num);
330 load (monster);
331 monster_set_count (monster);
332 load (monster_strength);
333 load (monster_max);
334 load (spawnpoints);
335 load (spawnx[0]);
336 load (spawny[0]);
337 load (spawnx[1]);
338 load (spawny[1]);
339 load (spawnx[2]);
340 load (spawny[2]);
341 load (spawnx[3]);
342 load (spawny[3]);
343 load (spawnx[4]);
344 load (spawny[4]);
345 load (temple_x);
346 load (temple_y);
347 load (swordlev);
348 load (mrand_seed);
349 ass_clear ();
350 for (i = 0; i < char_num; i++)
351 load_char (file, i);
352
353 chunk = pack_fopen_chunk (file, 0);
354 map_load (chunk);
355 pack_fclose_chunk (chunk);
356
357 pack_fclose (file);
358
359 sprintf (name, "data/save%i.html", nr);
360 messages_init (name);
361 return 1;
362 }
363 return 0;
364 }
365
366 int
game_delete(int nr)367 game_delete (int nr)
368 {
369 int ret = 1;
370 char name[256];
371 sprintf (name, "data/save%i.dat", nr);
372 if (remove (name))
373 ret = 0;
374 sprintf (name, "data/save%i.html", nr);
375 if (remove (name))
376 ret = 0;
377 return ret;
378 }
379