1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
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.
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.
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/>.
36 #include "common/streams.h"
37 #include "common/files.h"
39 static void DOT_savegame (Stream
*h
) {
41 for (i
= n
= 0; i
< MAXDOT
; ++i
) {
47 for (i
= 0; i
< MAXDOT
; ++i
) {
49 stream_write32(dot
[i
].o
.x
, h
);
50 stream_write32(dot
[i
].o
.y
, h
);
51 stream_write32(dot
[i
].o
.xv
, h
);
52 stream_write32(dot
[i
].o
.yv
, h
);
53 stream_write32(dot
[i
].o
.vx
, h
);
54 stream_write32(dot
[i
].o
.vy
, h
);
55 stream_write32(dot
[i
].o
.r
, h
);
56 stream_write32(dot
[i
].o
.h
, h
);
57 stream_write8(dot
[i
].c
, h
);
58 stream_write8(dot
[i
].t
, h
);
63 static void DOT_loadgame (Stream
*h
) {
66 for (i
= 0; i
< n
; i
++) {
67 dot
[i
].o
.x
= stream_read32(h
);
68 dot
[i
].o
.y
= stream_read32(h
);
69 dot
[i
].o
.xv
= stream_read32(h
);
70 dot
[i
].o
.yv
= stream_read32(h
);
71 dot
[i
].o
.vx
= stream_read32(h
);
72 dot
[i
].o
.vy
= stream_read32(h
);
73 dot
[i
].o
.r
= stream_read32(h
);
74 dot
[i
].o
.h
= stream_read32(h
);
75 dot
[i
].c
= stream_read8(h
);
76 dot
[i
].t
= stream_read8(h
);
80 static void FX_savegame (Stream
*h
) {
82 for (i
= n
= 0; i
< MAXFX
; ++i
) {
88 for (i
= 0; i
< MAXFX
; ++i
) {
90 stream_write32(fx
[i
].x
, h
);
91 stream_write32(fx
[i
].y
, h
);
92 stream_write32(fx
[i
].xv
, h
);
93 stream_write32(fx
[i
].yv
, h
);
94 stream_write8(fx
[i
].t
, h
);
95 stream_write8(fx
[i
].s
, h
);
100 static void FX_loadgame (Stream
*h
) {
102 n
= stream_read32(h
);
103 for (i
= 0; i
< n
; i
++) {
104 fx
[i
].x
= stream_read32(h
);
105 fx
[i
].y
= stream_read32(h
);
106 fx
[i
].xv
= stream_read32(h
);
107 fx
[i
].yv
= stream_read32(h
);
108 fx
[i
].t
= stream_read8(h
);
109 fx
[i
].s
= stream_read8(h
);
113 static void G_savegame (Stream
*h
) {
114 stream_write8(_2pl
, h
);
115 stream_write8(g_dm
, h
);
116 stream_write8(g_exit
, h
);
117 stream_write8(g_map
, h
);
118 stream_write32(g_time
, h
);
119 stream_write32(dm_pl1p
, h
);
120 stream_write32(dm_pl2p
, h
);
121 stream_write32(dm_pnum
, h
);
123 while (i
< dm_pnum
) {
124 stream_write32(dm_pos
[i
].x
, h
);
125 stream_write32(dm_pos
[i
].y
, h
);
126 stream_write8(dm_pos
[i
].d
, h
);
129 stream_write8(cheat
, h
);
130 stream_write(g_music
, 8, 1, h
);
133 static void G_loadgame (Stream
*h
) {
134 _2pl
= stream_read8(h
);
135 g_dm
= stream_read8(h
);
136 g_exit
= stream_read8(h
);
137 g_map
= stream_read8(h
);
138 g_time
= stream_read32(h
);
139 dm_pl1p
= stream_read32(h
);
140 dm_pl2p
= stream_read32(h
);
141 dm_pnum
= stream_read32(h
);
143 while (i
< dm_pnum
) {
144 dm_pos
[i
].x
= stream_read32(h
);
145 dm_pos
[i
].y
= stream_read32(h
);
146 dm_pos
[i
].d
= stream_read8(h
);
149 cheat
= stream_read8(h
);
150 stream_read(g_music
, 8, 1, h
);
154 static void IT_savegame (Stream
*h
) {
156 for (n
= MAXITEM
- 1; n
>= 0 && it
[n
].t
== 0; n
--) {
160 stream_write32(n
, h
);
161 for (i
= 0; i
< n
; i
++) {
162 stream_write32(it
[i
].o
.x
, h
);
163 stream_write32(it
[i
].o
.y
, h
);
164 stream_write32(it
[i
].o
.xv
, h
);
165 stream_write32(it
[i
].o
.yv
, h
);
166 stream_write32(it
[i
].o
.vx
, h
);
167 stream_write32(it
[i
].o
.vy
, h
);
168 stream_write32(it
[i
].o
.r
, h
);
169 stream_write32(it
[i
].o
.h
, h
);
170 stream_write32(it
[i
].t
, h
);
171 stream_write32(it
[i
].s
, h
);
173 stream_write32(itm_rtime
, h
);
176 static void IT_loadgame (Stream
*h
) {
178 n
= stream_read32(h
);
179 for (i
= 0; i
< n
; i
++) {
180 it
[i
].o
.x
= stream_read32(h
);
181 it
[i
].o
.y
= stream_read32(h
);
182 it
[i
].o
.xv
= stream_read32(h
);
183 it
[i
].o
.yv
= stream_read32(h
);
184 it
[i
].o
.vx
= stream_read32(h
);
185 it
[i
].o
.vy
= stream_read32(h
);
186 it
[i
].o
.r
= stream_read32(h
);
187 it
[i
].o
.h
= stream_read32(h
);
188 it
[i
].t
= stream_read32(h
);
189 it
[i
].s
= stream_read32(h
);
191 itm_rtime
= stream_read32(h
);
194 static void MN_savegame (Stream
*h
) {
196 for (n
= MAXMN
- 1; n
>= 0 && mn
[n
].t
== 0; n
--) {
200 stream_write32(n
, h
);
201 for (i
= 0; i
< n
; i
++) {
202 stream_write32(mn
[i
].o
.x
, h
);
203 stream_write32(mn
[i
].o
.y
, h
);
204 stream_write32(mn
[i
].o
.xv
, h
);
205 stream_write32(mn
[i
].o
.yv
, h
);
206 stream_write32(mn
[i
].o
.vx
, h
);
207 stream_write32(mn
[i
].o
.vy
, h
);
208 stream_write32(mn
[i
].o
.r
, h
);
209 stream_write32(mn
[i
].o
.h
, h
);
210 stream_write8(mn
[i
].t
, h
);
211 stream_write8(mn
[i
].d
, h
);
212 stream_write8(mn
[i
].st
, h
);
213 stream_write8(mn
[i
].ftime
, h
);
214 stream_write32(mn
[i
].fobj
, h
);
215 stream_write32(mn
[i
].s
, h
);
216 stream_write32(0, h
); // mn[i].ap useless, changed after load
217 stream_write32(mn
[i
].aim
, h
);
218 stream_write32(mn
[i
].life
, h
);
219 stream_write32(mn
[i
].pain
, h
);
220 stream_write32(mn
[i
].ac
, h
);
221 stream_write32(mn
[i
].tx
, h
);
222 stream_write32(mn
[i
].ty
, h
);
223 stream_write32(mn
[i
].ammo
, h
);
224 stream_write16(mn
[i
].atm
, h
);
226 stream_write32(mnum
, h
);
227 stream_write32(gsndt
, h
);
230 static void MN_loadgame (Stream
*h
) {
232 n
= stream_read32(h
);
233 for (i
= 0; i
< n
; i
++) {
234 mn
[i
].o
.x
= stream_read32(h
);
235 mn
[i
].o
.y
= stream_read32(h
);
236 mn
[i
].o
.xv
= stream_read32(h
);
237 mn
[i
].o
.yv
= stream_read32(h
);
238 mn
[i
].o
.vx
= stream_read32(h
);
239 mn
[i
].o
.vy
= stream_read32(h
);
240 mn
[i
].o
.r
= stream_read32(h
);
241 mn
[i
].o
.h
= stream_read32(h
);
242 mn
[i
].t
= stream_read8(h
);
243 mn
[i
].d
= stream_read8(h
);
244 mn
[i
].st
= stream_read8(h
);
245 mn
[i
].ftime
= stream_read8(h
);
246 mn
[i
].fobj
= stream_read32(h
);
247 mn
[i
].s
= stream_read32(h
);
248 mn
[i
].ap
= NULL
; stream_read32(h
); // useless, changed after loading
249 mn
[i
].aim
= stream_read32(h
);
250 mn
[i
].life
= stream_read32(h
);
251 mn
[i
].pain
= stream_read32(h
);
252 mn
[i
].ac
= stream_read32(h
);
253 mn
[i
].tx
= stream_read32(h
);
254 mn
[i
].ty
= stream_read32(h
);
255 mn
[i
].ammo
= stream_read32(h
);
256 mn
[i
].atm
= stream_read16(h
);
258 mnum
= stream_read32(h
);
259 gsndt
= stream_read32(h
);
260 for (n
= 0; n
< MAXMN
; n
++) {
269 static void PL_save_player (player_t
*p
, Stream
*h
) {
270 stream_write32(p
->o
.x
, h
);
271 stream_write32(p
->o
.y
, h
);
272 stream_write32(p
->o
.xv
, h
);
273 stream_write32(p
->o
.yv
, h
);
274 stream_write32(p
->o
.vx
, h
);
275 stream_write32(p
->o
.vy
, h
);
276 stream_write32(p
->o
.r
, h
);
277 stream_write32(p
->o
.h
, h
);
278 stream_write32(p
->looky
, h
);
279 stream_write32(p
->st
, h
);
280 stream_write32(p
->s
, h
);
281 stream_write32(p
->life
, h
);
282 stream_write32(p
->armor
, h
);
283 stream_write32(p
->hit
, h
);
284 stream_write32(p
->hito
, h
);
285 stream_write32(p
->pain
, h
);
286 stream_write32(p
->air
, h
);
287 stream_write32(p
->invl
, h
);
288 stream_write32(p
->suit
, h
);
289 stream_write8(p
->d
, h
);
290 stream_write32(p
->frag
, h
);
291 stream_write32(p
->ammo
, h
);
292 stream_write32(p
->shel
, h
);
293 stream_write32(p
->rock
, h
);
294 stream_write32(p
->cell
, h
);
295 stream_write32(p
->fuel
, h
);
296 stream_write32(p
->kills
, h
);
297 stream_write32(p
->secrets
, h
);
298 stream_write8(p
->fire
, h
);
299 stream_write8(p
->cwpn
, h
);
300 stream_write8(p
->csnd
, h
);
301 stream_write8(p
->amul
, h
);
302 stream_write16(p
->wpns
, h
);
303 stream_write8(p
->wpn
, h
);
304 stream_write8(p
->f
, h
);
305 stream_write8(p
->drawst
, h
);
306 stream_write8(p
->color
, h
);
307 stream_write32(p
->id
, h
);
308 stream_write8(p
->keys
, h
);
309 stream_write8(p
->lives
, h
);
313 static void PL_savegame (Stream
*h
) {
314 PL_save_player(&pl1
, h
);
316 PL_save_player(&pl2
, h
);
318 stream_write32(PL_JUMP
, h
);
319 stream_write32(PL_RUN
, h
);
320 stream_write8(p_immortal
, h
);
323 static void PL_load_player (player_t
*p
, Stream
*h
) {
324 p
->o
.x
= stream_read32(h
);
325 p
->o
.y
= stream_read32(h
);
326 p
->o
.xv
= stream_read32(h
);
327 p
->o
.yv
= stream_read32(h
);
328 p
->o
.vx
= stream_read32(h
);
329 p
->o
.vy
= stream_read32(h
);
330 p
->o
.r
= stream_read32(h
);
331 p
->o
.h
= stream_read32(h
);
332 p
->looky
= stream_read32(h
);
333 p
->st
= stream_read32(h
);
334 p
->s
= stream_read32(h
);
335 p
->life
= stream_read32(h
);
336 p
->armor
= stream_read32(h
);
337 p
->hit
= stream_read32(h
);
338 p
->hito
= stream_read32(h
);
339 p
->pain
= stream_read32(h
);
340 p
->air
= stream_read32(h
);
341 p
->invl
= stream_read32(h
);
342 p
->suit
= stream_read32(h
);
343 p
->d
= stream_read8(h
);
344 p
->frag
= stream_read32(h
);
345 p
->ammo
= stream_read32(h
);
346 p
->shel
= stream_read32(h
);
347 p
->rock
= stream_read32(h
);
348 p
->cell
= stream_read32(h
);
349 p
->fuel
= stream_read32(h
);
350 p
->kills
= stream_read32(h
);
351 p
->secrets
= stream_read32(h
);
352 p
->fire
= stream_read8(h
);
353 p
->cwpn
= stream_read8(h
);
354 p
->csnd
= stream_read8(h
);
355 p
->amul
= stream_read8(h
);
356 p
->wpns
= stream_read16(h
);
357 p
->wpn
= stream_read8(h
);
358 p
->f
= stream_read8(h
);
359 p
->drawst
= stream_read8(h
);
360 p
->color
= stream_read8(h
);
361 p
->id
= stream_read32(h
);
362 p
->keys
= stream_read8(h
);
363 p
->lives
= stream_read8(h
);
367 static void PL_loadgame (Stream
*h
) {
368 PL_load_player(&pl1
, h
);
370 PL_load_player(&pl2
, h
);
372 PL_JUMP
= stream_read32(h
);
373 PL_RUN
= stream_read32(h
);
374 p_immortal
= stream_read8(h
);
377 static void SMK_savegame (Stream
*h
) {
379 for (i
= n
= 0; i
< MAXSMOK
; ++i
) {
384 stream_write32(n
, h
);
385 for (i
= 0; i
< MAXSMOK
; ++i
) {
387 stream_write32(sm
[i
].x
, h
);
388 stream_write32(sm
[i
].y
, h
);
389 stream_write32(sm
[i
].xv
, h
);
390 stream_write32(sm
[i
].xv
, h
);
391 stream_write8(sm
[i
].t
, h
);
392 stream_write8(sm
[i
].s
, h
);
393 stream_write16(sm
[i
].o
, h
);
398 static void SMK_loadgame (Stream
*h
) {
400 n
= stream_read32(h
);
401 for (i
= 0; i
< n
; ++i
) {
402 sm
[i
].x
= stream_read32(h
);
403 sm
[i
].y
= stream_read32(h
);
404 sm
[i
].xv
= stream_read32(h
);
405 sm
[i
].xv
= stream_read32(h
);
406 sm
[i
].t
= stream_read8(h
);
407 sm
[i
].s
= stream_read8(h
);
408 sm
[i
].o
= stream_read16(h
);
412 static void SW_savegame (Stream
*h
) {
414 for (n
= MAXSW
- 1; n
>= 0 && sw
[n
].t
== 0; n
--) {
418 stream_write32(n
, h
);
419 for (i
= 0; i
< n
; i
++) {
420 stream_write8(sw
[i
].x
, h
);
421 stream_write8(sw
[i
].y
, h
);
422 stream_write8(sw
[i
].t
, h
);
423 stream_write8(sw
[i
].tm
, h
);
424 stream_write8(sw
[i
].a
, h
);
425 stream_write8(sw
[i
].b
, h
);
426 stream_write8(sw
[i
].c
, h
);
427 stream_write8(sw
[i
].d
, h
);
428 stream_write8(sw
[i
].f
, h
);
430 stream_write32(sw_secrets
, h
);
433 static void SW_loadgame (Stream
*h
) {
435 n
= stream_read32(h
);
436 for (i
= 0; i
< n
; i
++) {
437 sw
[i
].x
= stream_read8(h
);
438 sw
[i
].y
= stream_read8(h
);
439 sw
[i
].t
= stream_read8(h
);
440 sw
[i
].tm
= stream_read8(h
);
441 sw
[i
].a
= stream_read8(h
);
442 sw
[i
].b
= stream_read8(h
);
443 sw
[i
].c
= stream_read8(h
);
444 sw
[i
].d
= stream_read8(h
);
445 sw
[i
].f
= stream_read8(h
);
447 sw_secrets
= stream_read32(h
);
450 static void W_savegame (Stream
* h
) {
453 stream_write32(sky_type
, h
);
454 for(i
= 1; i
< 256; ++i
) {
456 stream_write(s
, 8, 1, h
);
458 for (i
= 0; i
< 256; i
++) {
459 stream_write32(walf
[i
], h
);
461 for (i
= 0; i
< 256; i
++) {
462 stream_write8(R_get_swp(i
), h
);
464 stream_write(fldb
, FLDW
*FLDH
, 1, h
);
465 stream_write(fld
, FLDW
*FLDH
, 1, h
);
466 stream_write(fldf
, FLDW
*FLDH
, 1, h
);
469 static void W_loadgame (Stream
*h
) {
472 sky_type
= stream_read32(h
);
475 for (i
= 1; i
< 256; ++i
) {
476 stream_read(s
, 8, 1, h
);
482 for (i
= 0; i
< 256; i
++) {
483 stream_read32(h
); // useless
485 for (i
= 0; i
< 256; i
++) {
486 walf
[i
] = stream_read8(h
);
488 stream_read(fldb
, FLDW
*FLDH
, 1, h
);
489 stream_read(fld
, FLDW
*FLDH
, 1, h
);
490 stream_read(fldf
, FLDW
*FLDH
, 1, h
);
493 static void WP_savegame (Stream
*h
) {
495 for (n
= MAXWPN
- 1; n
>= 0 && wp
[n
].t
== 0; n
--) {
499 stream_write32(n
, h
);
500 for (i
= 0; i
< n
; i
++) {
501 stream_write32(wp
[i
].o
.x
, h
);
502 stream_write32(wp
[i
].o
.y
, h
);
503 stream_write32(wp
[i
].o
.xv
, h
);
504 stream_write32(wp
[i
].o
.yv
, h
);
505 stream_write32(wp
[i
].o
.vx
, h
);
506 stream_write32(wp
[i
].o
.vy
, h
);
507 stream_write32(wp
[i
].o
.r
, h
);
508 stream_write32(wp
[i
].o
.h
, h
);
509 stream_write8(wp
[i
].t
, h
);
510 stream_write8(wp
[i
].s
, h
);
511 stream_write32(wp
[i
].own
, h
);
512 stream_write16(wp
[i
].target
, h
);
516 static void WP_loadgame (Stream
*h
) {
518 n
= stream_read32(h
);
519 for (i
= 0; i
< n
; i
++) {
520 wp
[i
].o
.x
= stream_read32(h
);
521 wp
[i
].o
.y
= stream_read32(h
);
522 wp
[i
].o
.xv
= stream_read32(h
);
523 wp
[i
].o
.yv
= stream_read32(h
);
524 wp
[i
].o
.vx
= stream_read32(h
);
525 wp
[i
].o
.vy
= stream_read32(h
);
526 wp
[i
].o
.r
= stream_read32(h
);
527 wp
[i
].o
.h
= stream_read32(h
);
528 wp
[i
].t
= stream_read8(h
);
529 wp
[i
].s
= stream_read8(h
);
530 wp
[i
].own
= stream_read32(h
);
531 wp
[i
].target
= stream_read16(h
);
535 void SAVE_save (Stream
*w
, const char name
[24]) {
537 stream_write(name
, 24, 1, w
); // slot name
538 stream_write16(3, w
); // version
551 void SAVE_load (Stream
*h
) {
553 stream_setpos(h
, 24); // skip name
554 version
= stream_read16(h
);
569 int SAVE_getname (Stream
*r
, char name
[24]) {
570 stream_read(name
, 24, 1, r
);
571 int16_t version
= stream_read16(r
);