DEADSOFTWARE

update copyrights
[flatwaifu.git] / src / save.c
1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
18 #include "save.h"
20 #include "dots.h"
21 #include "fx.h"
22 #include "game.h"
23 #include "items.h"
24 #include "monster.h"
25 #include "player.h"
26 #include "smoke.h"
27 #include "switch.h"
28 #include "view.h"
29 #include "weapons.h"
31 #include "render.h"
32 #include "music.h"
34 #include <stdio.h> // FILE
35 #include <string.h>
36 #include <sys/stat.h>
37 #include "files.h"
38 #include "my.h"
40 char savname[SAVE_MAX][SAVE_MAXLEN];
41 char savok[SAVE_MAX];
43 static void DOT_savegame (FILE *h) {
44 int i, n;
45 for (i = n = 0; i < MAXDOT; ++i) {
46 if (dot[i].t) {
47 ++n;
48 }
49 }
50 myfwrite32(n, h);
51 for (i = 0; i < MAXDOT; ++i) {
52 if (dot[i].t) {
53 myfwrite32(dot[i].o.x, h);
54 myfwrite32(dot[i].o.y, h);
55 myfwrite32(dot[i].o.xv, h);
56 myfwrite32(dot[i].o.yv, h);
57 myfwrite32(dot[i].o.vx, h);
58 myfwrite32(dot[i].o.vy, h);
59 myfwrite32(dot[i].o.r, h);
60 myfwrite32(dot[i].o.h, h);
61 myfwrite8(dot[i].c, h);
62 myfwrite8(dot[i].t, h);
63 }
64 }
65 }
67 static void DOT_loadgame (FILE *h) {
68 int i, n;
69 n = myfread32(h);
70 for (i = 0; i < n; i++) {
71 dot[i].o.x = myfread32(h);
72 dot[i].o.y = myfread32(h);
73 dot[i].o.xv = myfread32(h);
74 dot[i].o.yv = myfread32(h);
75 dot[i].o.vx = myfread32(h);
76 dot[i].o.vy = myfread32(h);
77 dot[i].o.r = myfread32(h);
78 dot[i].o.h = myfread32(h);
79 dot[i].c = myfread8(h);
80 dot[i].t = myfread8(h);
81 }
82 }
84 static void FX_savegame (FILE *h) {
85 int i, n;
86 for (i = n = 0; i < MAXFX; ++i) {
87 if (fx[i].t) {
88 ++n;
89 }
90 }
91 myfwrite32(n, h);
92 for (i = 0; i < MAXFX; ++i) {
93 if (fx[i].t) {
94 myfwrite32(fx[i].x, h);
95 myfwrite32(fx[i].y, h);
96 myfwrite32(fx[i].xv, h);
97 myfwrite32(fx[i].yv, h);
98 myfwrite8(fx[i].t, h);
99 myfwrite8(fx[i].s, h);
104 static void FX_loadgame (FILE *h) {
105 int i, n;
106 n = myfread32(h);
107 for (i = 0; i < n; i++) {
108 fx[i].x = myfread32(h);
109 fx[i].y = myfread32(h);
110 fx[i].xv = myfread32(h);
111 fx[i].yv = myfread32(h);
112 fx[i].t = myfread8(h);
113 fx[i].s = myfread8(h);
117 static void G_savegame (FILE *h) {
118 myfwrite8(_2pl, h);
119 myfwrite8(g_dm, h);
120 myfwrite8(g_exit, h);
121 myfwrite8(g_map, h);
122 myfwrite32(g_time, h);
123 myfwrite32(dm_pl1p, h);
124 myfwrite32(dm_pl2p, h);
125 myfwrite32(dm_pnum, h);
126 int i = 0;
127 while (i < dm_pnum) {
128 myfwrite32(dm_pos[i].x, h);
129 myfwrite32(dm_pos[i].y, h);
130 myfwrite8(dm_pos[i].d, h);
131 i += 1;
133 myfwrite8(cheat, h);
134 myfwrite(g_music, 8, 1, h);
137 static void G_loadgame (FILE *h) {
138 _2pl = myfread8(h);
139 g_dm = myfread8(h);
140 g_exit = myfread8(h);
141 g_map = myfread8(h);
142 g_time = myfread32(h);
143 dm_pl1p = myfread32(h);
144 dm_pl2p = myfread32(h);
145 dm_pnum = myfread32(h);
146 int i = 0;
147 while (i < dm_pnum) {
148 dm_pos[i].x = myfread32(h);
149 dm_pos[i].y = myfread32(h);
150 dm_pos[i].d = myfread8(h);
151 i += 1;
153 cheat = myfread8(h);
154 myfread(g_music, 8, 1, h);
155 MUS_load(g_music);
158 static void IT_savegame (FILE *h) {
159 int i, n;
160 for (n = MAXITEM - 1; n >= 0 && it[n].t == 0; n--) {
161 // empty
163 n += 1;
164 myfwrite32(n, h);
165 for (i = 0; i < n; i++) {
166 myfwrite32(it[i].o.x, h);
167 myfwrite32(it[i].o.y, h);
168 myfwrite32(it[i].o.xv, h);
169 myfwrite32(it[i].o.yv, h);
170 myfwrite32(it[i].o.vx, h);
171 myfwrite32(it[i].o.vy, h);
172 myfwrite32(it[i].o.r, h);
173 myfwrite32(it[i].o.h, h);
174 myfwrite32(it[i].t, h);
175 myfwrite32(it[i].s, h);
177 myfwrite32(itm_rtime, h);
180 static void IT_loadgame (FILE *h) {
181 int i, n;
182 n = myfread32(h);
183 for (i = 0; i < n; i++) {
184 it[i].o.x = myfread32(h);
185 it[i].o.y = myfread32(h);
186 it[i].o.xv = myfread32(h);
187 it[i].o.yv = myfread32(h);
188 it[i].o.vx = myfread32(h);
189 it[i].o.vy = myfread32(h);
190 it[i].o.r = myfread32(h);
191 it[i].o.h = myfread32(h);
192 it[i].t = myfread32(h);
193 it[i].s = myfread32(h);
195 itm_rtime = myfread32(h);
198 static void MN_savegame (FILE *h) {
199 int i, n;
200 for (n = MAXMN - 1; n >= 0 && mn[n].t == 0; n--) {
201 // empty
203 n += 1;
204 myfwrite32(n, h);
205 for (i = 0; i < n; i++) {
206 myfwrite32(mn[i].o.x, h);
207 myfwrite32(mn[i].o.y, h);
208 myfwrite32(mn[i].o.xv, h);
209 myfwrite32(mn[i].o.yv, h);
210 myfwrite32(mn[i].o.vx, h);
211 myfwrite32(mn[i].o.vy, h);
212 myfwrite32(mn[i].o.r, h);
213 myfwrite32(mn[i].o.h, h);
214 myfwrite8(mn[i].t, h);
215 myfwrite8(mn[i].d, h);
216 myfwrite8(mn[i].st, h);
217 myfwrite8(mn[i].ftime, h);
218 myfwrite32(mn[i].fobj, h);
219 myfwrite32(mn[i].s, h);
220 myfwrite32(0, h); // mn[i].ap useless, changed after load
221 myfwrite32(mn[i].aim, h);
222 myfwrite32(mn[i].life, h);
223 myfwrite32(mn[i].pain, h);
224 myfwrite32(mn[i].ac, h);
225 myfwrite32(mn[i].tx, h);
226 myfwrite32(mn[i].ty, h);
227 myfwrite32(mn[i].ammo, h);
228 myfwrite16(mn[i].atm, h);
230 myfwrite32(mnum, h);
231 myfwrite32(gsndt, h);
234 static void MN_loadgame (FILE *h) {
235 int i, n, c;
236 n = myfread32(h);
237 for (i = 0; i < n; i++) {
238 mn[i].o.x = myfread32(h);
239 mn[i].o.y = myfread32(h);
240 mn[i].o.xv = myfread32(h);
241 mn[i].o.yv = myfread32(h);
242 mn[i].o.vx = myfread32(h);
243 mn[i].o.vy = myfread32(h);
244 mn[i].o.r = myfread32(h);
245 mn[i].o.h = myfread32(h);
246 mn[i].t = myfread8(h);
247 mn[i].d = myfread8(h);
248 mn[i].st = myfread8(h);
249 mn[i].ftime = myfread8(h);
250 mn[i].fobj = myfread32(h);
251 mn[i].s = myfread32(h);
252 mn[i].ap = NULL; myfread32(h); // useless, changed after loading
253 mn[i].aim = myfread32(h);
254 mn[i].life = myfread32(h);
255 mn[i].pain = myfread32(h);
256 mn[i].ac = myfread32(h);
257 mn[i].tx = myfread32(h);
258 mn[i].ty = myfread32(h);
259 mn[i].ammo = myfread32(h);
260 mn[i].atm = myfread16(h);
262 mnum = myfread32(h);
263 gsndt = myfread32(h);
264 for (n = 0; n < MAXMN; n++) {
265 if (mn[n].t) {
266 c = mn[n].ac;
267 setst(n, mn[n].st);
268 mn[n].ac = c;
273 static void PL_save_player (player_t *p, FILE *h) {
274 myfwrite32(p->o.x, h);
275 myfwrite32(p->o.y, h);
276 myfwrite32(p->o.xv, h);
277 myfwrite32(p->o.yv, h);
278 myfwrite32(p->o.vx, h);
279 myfwrite32(p->o.vy, h);
280 myfwrite32(p->o.r, h);
281 myfwrite32(p->o.h, h);
282 myfwrite32(p->looky, h);
283 myfwrite32(p->st, h);
284 myfwrite32(p->s, h);
285 myfwrite32(p->life, h);
286 myfwrite32(p->armor, h);
287 myfwrite32(p->hit, h);
288 myfwrite32(p->hito, h);
289 myfwrite32(p->pain, h);
290 myfwrite32(p->air, h);
291 myfwrite32(p->invl, h);
292 myfwrite32(p->suit, h);
293 myfwrite8(p->d, h);
294 myfwrite32(p->frag, h);
295 myfwrite32(p->ammo, h);
296 myfwrite32(p->shel, h);
297 myfwrite32(p->rock, h);
298 myfwrite32(p->cell, h);
299 myfwrite32(p->fuel, h);
300 myfwrite32(p->kills, h);
301 myfwrite32(p->secrets, h);
302 myfwrite8(p->fire, h);
303 myfwrite8(p->cwpn, h);
304 myfwrite8(p->csnd, h);
305 myfwrite8(p->amul, h);
306 myfwrite16(p->wpns, h);
307 myfwrite8(p->wpn, h);
308 myfwrite8(p->f, h);
309 myfwrite8(p->drawst, h);
310 myfwrite8(p->color, h);
311 myfwrite32(p->id, h);
312 myfwrite8(p->keys, h);
313 myfwrite8(p->lives, h);
314 // k* not saved
317 static void PL_savegame (FILE *h) {
318 PL_save_player(&pl1, h);
319 if (_2pl) {
320 PL_save_player(&pl2, h);
322 myfwrite32(PL_JUMP, h);
323 myfwrite32(PL_RUN, h);
324 myfwrite8(p_immortal, h);
327 static void PL_load_player (player_t *p, FILE *h) {
328 p->o.x = myfread32(h);
329 p->o.y = myfread32(h);
330 p->o.xv = myfread32(h);
331 p->o.yv = myfread32(h);
332 p->o.vx = myfread32(h);
333 p->o.vy = myfread32(h);
334 p->o.r = myfread32(h);
335 p->o.h = myfread32(h);
336 p->looky = myfread32(h);
337 p->st = myfread32(h);
338 p->s = myfread32(h);
339 p->life = myfread32(h);
340 p->armor = myfread32(h);
341 p->hit = myfread32(h);
342 p->hito = myfread32(h);
343 p->pain = myfread32(h);
344 p->air = myfread32(h);
345 p->invl = myfread32(h);
346 p->suit = myfread32(h);
347 p->d = myfread8(h);
348 p->frag = myfread32(h);
349 p->ammo = myfread32(h);
350 p->shel = myfread32(h);
351 p->rock = myfread32(h);
352 p->cell = myfread32(h);
353 p->fuel = myfread32(h);
354 p->kills = myfread32(h);
355 p->secrets = myfread32(h);
356 p->fire = myfread8(h);
357 p->cwpn = myfread8(h);
358 p->csnd = myfread8(h);
359 p->amul = myfread8(h);
360 p->wpns = myfread16(h);
361 p->wpn = myfread8(h);
362 p->f = myfread8(h);
363 p->drawst = myfread8(h);
364 p->color = myfread8(h);
365 p->id = myfread32(h);
366 p->keys = myfread8(h);
367 p->lives = myfread8(h);
368 // k* not saved
371 static void PL_loadgame (FILE *h) {
372 PL_load_player(&pl1, h);
373 if (_2pl) {
374 PL_load_player(&pl2, h);
376 PL_JUMP = myfread32(h);
377 PL_RUN = myfread32(h);
378 p_immortal = myfread8(h);
381 static void SMK_savegame (FILE *h) {
382 int i, n;
383 for (i = n = 0; i < MAXSMOK; ++i) {
384 if (sm[i].t) {
385 ++n;
388 myfwrite32(n, h);
389 for (i = 0; i < MAXSMOK; ++i) {
390 if (sm[i].t) {
391 myfwrite32(sm[i].x, h);
392 myfwrite32(sm[i].y, h);
393 myfwrite32(sm[i].xv, h);
394 myfwrite32(sm[i].xv, h);
395 myfwrite8(sm[i].t, h);
396 myfwrite8(sm[i].s, h);
397 myfwrite16(sm[i].o, h);
402 static void SMK_loadgame (FILE *h) {
403 int i, n;
404 n = myfread32(h);
405 for (i = 0; i < n; ++i) {
406 sm[i].x = myfread32(h);
407 sm[i].y = myfread32(h);
408 sm[i].xv = myfread32(h);
409 sm[i].xv = myfread32(h);
410 sm[i].t = myfread8(h);
411 sm[i].s = myfread8(h);
412 sm[i].o = myfread16(h);
416 static void SW_savegame (FILE *h) {
417 int i, n;
418 for (n = MAXSW - 1; n >= 0 && sw[n].t == 0; n--) {
419 // empty
421 n += 1;
422 myfwrite32(n, h);
423 for (i = 0; i < n; i++) {
424 myfwrite8(sw[i].x, h);
425 myfwrite8(sw[i].y, h);
426 myfwrite8(sw[i].t, h);
427 myfwrite8(sw[i].tm, h);
428 myfwrite8(sw[i].a, h);
429 myfwrite8(sw[i].b, h);
430 myfwrite8(sw[i].c, h);
431 myfwrite8(sw[i].d, h);
432 myfwrite8(sw[i].f, h);
434 myfwrite32(sw_secrets, h);
437 static void SW_loadgame (FILE *h) {
438 int i, n;
439 n = myfread32(h);
440 for (i = 0; i < n; i++) {
441 sw[i].x = myfread8(h);
442 sw[i].y = myfread8(h);
443 sw[i].t = myfread8(h);
444 sw[i].tm = myfread8(h);
445 sw[i].a = myfread8(h);
446 sw[i].b = myfread8(h);
447 sw[i].c = myfread8(h);
448 sw[i].d = myfread8(h);
449 sw[i].f = myfread8(h);
451 sw_secrets = myfread32(h);
454 static void W_savegame (FILE* h) {
455 char s[8];
456 int i;
457 myfwrite32(sky_type, h);
458 for(i = 1; i < 256; ++i) {
459 R_get_name(i, s);
460 myfwrite(s, 8, 1, h);
462 for (i = 0; i < 256; i++) {
463 myfwrite32(walf[i], h);
465 for (i = 0; i < 256; i++) {
466 myfwrite8(R_get_swp(i), h);
468 myfwrite(fldb, FLDW*FLDH, 1, h);
469 myfwrite(fld, FLDW*FLDH, 1, h);
470 myfwrite(fldf, FLDW*FLDH, 1, h);
473 static void W_loadgame (FILE* h) {
474 int i;
475 char s[8];
476 sky_type = myfread32(h);
477 R_loadsky(sky_type);
478 R_begin_load();
479 for (i = 1; i < 256; ++i) {
480 myfread(s, 8, 1, h);
481 if (s[0]) {
482 R_load(s);
485 R_end_load();
486 for (i = 0; i < 256; i++) {
487 myfread32(h); // useless
489 for (i = 0; i < 256; i++) {
490 walf[i] = myfread8(h);
492 myfread(fldb, FLDW*FLDH, 1, h);
493 myfread(fld, FLDW*FLDH, 1, h);
494 myfread(fldf, FLDW*FLDH, 1, h);
497 static void WP_savegame (FILE *h) {
498 int i, n;
499 for (n = MAXWPN - 1; n >= 0 && wp[n].t == 0; n--) {
500 // empty
502 n += 1;
503 myfwrite32(n, h);
504 for (i = 0; i < n; i++) {
505 myfwrite32(wp[i].o.x, h);
506 myfwrite32(wp[i].o.y, h);
507 myfwrite32(wp[i].o.xv, h);
508 myfwrite32(wp[i].o.yv, h);
509 myfwrite32(wp[i].o.vx, h);
510 myfwrite32(wp[i].o.vy, h);
511 myfwrite32(wp[i].o.r, h);
512 myfwrite32(wp[i].o.h, h);
513 myfwrite8(wp[i].t, h);
514 myfwrite8(wp[i].s, h);
515 myfwrite32(wp[i].own, h);
516 myfwrite16(wp[i].target, h);
520 static void WP_loadgame (FILE *h) {
521 int i, n;
522 n = myfread32(h);
523 for (i = 0; i < n; i++) {
524 wp[i].o.x = myfread32(h);
525 wp[i].o.y = myfread32(h);
526 wp[i].o.xv = myfread32(h);
527 wp[i].o.yv = myfread32(h);
528 wp[i].o.vx = myfread32(h);
529 wp[i].o.vy = myfread32(h);
530 wp[i].o.r = myfread32(h);
531 wp[i].o.h = myfread32(h);
532 wp[i].t = myfread8(h);
533 wp[i].s = myfread8(h);
534 wp[i].own = myfread32(h);
535 wp[i].target = myfread16(h);
539 static char *getsavfpname (int n, int ro) {
540 static char fn[] = "savgame0.dat";
541 fn[7] = n + '0';
542 #ifndef WIN32
543 static char p[100];
544 char *e = getenv("HOME");
545 strncpy(p, e, 60);
546 strcat(p, "/.doom2d-rembo");
547 if (!ro) {
548 mkdir(p, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
550 strcat(p, "/");
551 strcat(p, fn);
552 #else
553 strcpy(p, fn);
554 #endif
555 return p;
558 void F_getsavnames (void) {
559 int i;
560 FILE *h;
561 short ver;
562 char *p;
563 for (i = 0; i < 7; ++i) {
564 p = getsavfpname(i, 1);
565 memset(savname[i], 0, 24);
566 savok[i] = 0;
567 h = fopen(p, "rb");
568 if (h != NULL) {
569 ver = -1;
570 myfread(savname[i], 24, 1, h);
571 ver = myfread16(h);
572 savname[i][23] = 0;
573 savok[i] = (ver == 3) ? 1 : 0;
574 fclose(h);
579 void F_savegame (int n, char *s) {
580 char *p = getsavfpname(n, 0);
581 FILE *h = fopen(p, "wb");
582 if (h != NULL) {
583 myfwrite(s, 24, 1, h); // slot name
584 myfwrite16(3, h); // version
585 G_savegame(h);
586 W_savegame(h);
587 DOT_savegame(h);
588 SMK_savegame(h);
589 FX_savegame(h);
590 IT_savegame(h);
591 MN_savegame(h);
592 PL_savegame(h);
593 SW_savegame(h);
594 WP_savegame(h);
595 fclose(h);
599 void F_loadgame (int n) {
600 short ver;
601 char *p = getsavfpname(n, 1);
602 FILE *h = fopen(p, "rb");
603 if (h != NULL) {
604 fseek(h, 24, SEEK_SET); // skip name
605 ver = myfread16(h); // version
606 if (ver == 3) {
607 G_loadgame(h);
608 W_loadgame(h);
609 DOT_loadgame(h);
610 SMK_loadgame(h);
611 FX_loadgame(h);
612 IT_loadgame(h);
613 MN_loadgame(h);
614 PL_loadgame(h);
615 SW_loadgame(h);
616 WP_loadgame(h);
618 fclose(h);