Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8547 | maxcodehac | 1 | // Emacs style mode select -*- C++ -*- |
2 | //----------------------------------------------------------------------------- |
||
3 | // |
||
4 | // $Id:$ |
||
5 | // |
||
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
||
7 | // |
||
8 | // This source is available for distribution and/or modification |
||
9 | // only under the terms of the DOOM Source Code License as |
||
10 | // published by id Software. All rights reserved. |
||
11 | // |
||
12 | // The source is distributed in the hope that it will be useful, |
||
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License |
||
15 | // for more details. |
||
16 | // |
||
17 | // $Log:$ |
||
18 | // |
||
19 | // DESCRIPTION: |
||
20 | // Archiving: SaveGame I/O. |
||
21 | // |
||
22 | //----------------------------------------------------------------------------- |
||
23 | |||
24 | static const char |
||
25 | rcsid[] = "$Id: p_tick.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; |
||
26 | |||
27 | #include "i_system.h" |
||
28 | #include "z_zone.h" |
||
29 | #include "p_local.h" |
||
30 | |||
31 | // State. |
||
32 | #include "doomstat.h" |
||
33 | #include "r_state.h" |
||
34 | |||
35 | byte* save_p; |
||
36 | |||
37 | |||
38 | // Pads save_p to a 4-byte boundary |
||
39 | // so that the load/save works on SGI&Gecko. |
||
40 | #define PADSAVEP() save_p += (4 - ((int) save_p & 3)) & 3 |
||
41 | |||
42 | |||
43 | |||
44 | // |
||
45 | // P_ArchivePlayers |
||
46 | // |
||
47 | void P_ArchivePlayers (void) |
||
48 | { |
||
49 | int i; |
||
50 | int j; |
||
51 | player_t* dest; |
||
52 | |||
53 | for (i=0 ; i |
||
54 | { |
||
55 | if (!playeringame[i]) |
||
56 | continue; |
||
57 | |||
58 | PADSAVEP(); |
||
59 | |||
60 | dest = (player_t *)save_p; |
||
61 | memcpy (dest,&players[i],sizeof(player_t)); |
||
62 | save_p += sizeof(player_t); |
||
63 | for (j=0 ; j |
||
64 | { |
||
65 | if (dest->psprites[j].state) |
||
66 | { |
||
67 | dest->psprites[j].state |
||
68 | = (state_t *)(dest->psprites[j].state-states); |
||
69 | } |
||
70 | } |
||
71 | } |
||
72 | } |
||
73 | |||
74 | |||
75 | |||
76 | // |
||
77 | // P_UnArchivePlayers |
||
78 | // |
||
79 | void P_UnArchivePlayers (void) |
||
80 | { |
||
81 | int i; |
||
82 | int j; |
||
83 | |||
84 | for (i=0 ; i |
||
85 | { |
||
86 | if (!playeringame[i]) |
||
87 | continue; |
||
88 | |||
89 | PADSAVEP(); |
||
90 | |||
91 | memcpy (&players[i],save_p, sizeof(player_t)); |
||
92 | save_p += sizeof(player_t); |
||
93 | |||
94 | // will be set when unarc thinker |
||
95 | players[i].mo = NULL; |
||
96 | players[i].message = NULL; |
||
97 | players[i].attacker = NULL; |
||
98 | |||
99 | for (j=0 ; j |
||
100 | { |
||
101 | if (players[i]. psprites[j].state) |
||
102 | { |
||
103 | players[i]. psprites[j].state |
||
104 | = &states[ (int)players[i].psprites[j].state ]; |
||
105 | } |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | |||
110 | |||
111 | // |
||
112 | // P_ArchiveWorld |
||
113 | // |
||
114 | void P_ArchiveWorld (void) |
||
115 | { |
||
116 | int i; |
||
117 | int j; |
||
118 | sector_t* sec; |
||
119 | line_t* li; |
||
120 | side_t* si; |
||
121 | short* put; |
||
122 | |||
123 | put = (short *)save_p; |
||
124 | |||
125 | // do sectors |
||
126 | for (i=0, sec = sectors ; i |
||
127 | { |
||
128 | *put++ = sec->floorheight >> FRACBITS; |
||
129 | *put++ = sec->ceilingheight >> FRACBITS; |
||
130 | *put++ = sec->floorpic; |
||
131 | *put++ = sec->ceilingpic; |
||
132 | *put++ = sec->lightlevel; |
||
133 | *put++ = sec->special; // needed? |
||
134 | *put++ = sec->tag; // needed? |
||
135 | } |
||
136 | |||
137 | |||
138 | // do lines |
||
139 | for (i=0, li = lines ; i |
||
140 | { |
||
141 | *put++ = li->flags; |
||
142 | *put++ = li->special; |
||
143 | *put++ = li->tag; |
||
144 | for (j=0 ; j<2 ; j++) |
||
145 | { |
||
146 | if (li->sidenum[j] == -1) |
||
147 | continue; |
||
148 | |||
149 | si = &sides[li->sidenum[j]]; |
||
150 | |||
151 | *put++ = si->textureoffset >> FRACBITS; |
||
152 | *put++ = si->rowoffset >> FRACBITS; |
||
153 | *put++ = si->toptexture; |
||
154 | *put++ = si->bottomtexture; |
||
155 | *put++ = si->midtexture; |
||
156 | } |
||
157 | } |
||
158 | |||
159 | save_p = (byte *)put; |
||
160 | } |
||
161 | |||
162 | |||
163 | |||
164 | // |
||
165 | // P_UnArchiveWorld |
||
166 | // |
||
167 | void P_UnArchiveWorld (void) |
||
168 | { |
||
169 | int i; |
||
170 | int j; |
||
171 | sector_t* sec; |
||
172 | line_t* li; |
||
173 | side_t* si; |
||
174 | short* get; |
||
175 | |||
176 | get = (short *)save_p; |
||
177 | |||
178 | // do sectors |
||
179 | for (i=0, sec = sectors ; i |
||
180 | { |
||
181 | sec->floorheight = *get++ << FRACBITS; |
||
182 | sec->ceilingheight = *get++ << FRACBITS; |
||
183 | sec->floorpic = *get++; |
||
184 | sec->ceilingpic = *get++; |
||
185 | sec->lightlevel = *get++; |
||
186 | sec->special = *get++; // needed? |
||
187 | sec->tag = *get++; // needed? |
||
188 | sec->specialdata = 0; |
||
189 | sec->soundtarget = 0; |
||
190 | } |
||
191 | |||
192 | // do lines |
||
193 | for (i=0, li = lines ; i |
||
194 | { |
||
195 | li->flags = *get++; |
||
196 | li->special = *get++; |
||
197 | li->tag = *get++; |
||
198 | for (j=0 ; j<2 ; j++) |
||
199 | { |
||
200 | if (li->sidenum[j] == -1) |
||
201 | continue; |
||
202 | si = &sides[li->sidenum[j]]; |
||
203 | si->textureoffset = *get++ << FRACBITS; |
||
204 | si->rowoffset = *get++ << FRACBITS; |
||
205 | si->toptexture = *get++; |
||
206 | si->bottomtexture = *get++; |
||
207 | si->midtexture = *get++; |
||
208 | } |
||
209 | } |
||
210 | save_p = (byte *)get; |
||
211 | } |
||
212 | |||
213 | |||
214 | |||
215 | |||
216 | |||
217 | // |
||
218 | // Thinkers |
||
219 | // |
||
220 | typedef enum |
||
221 | { |
||
222 | tc_end, |
||
223 | tc_mobj |
||
224 | |||
225 | } thinkerclass_t; |
||
226 | |||
227 | |||
228 | |||
229 | // |
||
230 | // P_ArchiveThinkers |
||
231 | // |
||
232 | void P_ArchiveThinkers (void) |
||
233 | { |
||
234 | thinker_t* th; |
||
235 | mobj_t* mobj; |
||
236 | |||
237 | // save off the current thinkers |
||
238 | for (th = thinkercap.next ; th != &thinkercap ; th=th->next) |
||
239 | { |
||
240 | if (th->function.acp1 == (actionf_p1)P_MobjThinker) |
||
241 | { |
||
242 | *save_p++ = tc_mobj; |
||
243 | PADSAVEP(); |
||
244 | mobj = (mobj_t *)save_p; |
||
245 | memcpy (mobj, th, sizeof(*mobj)); |
||
246 | save_p += sizeof(*mobj); |
||
247 | mobj->state = (state_t *)(mobj->state - states); |
||
248 | |||
249 | if (mobj->player) |
||
250 | mobj->player = (player_t *)((mobj->player-players) + 1); |
||
251 | continue; |
||
252 | } |
||
253 | |||
254 | // I_Error ("P_ArchiveThinkers: Unknown thinker function"); |
||
255 | } |
||
256 | |||
257 | // add a terminating marker |
||
258 | *save_p++ = tc_end; |
||
259 | } |
||
260 | |||
261 | |||
262 | |||
263 | // |
||
264 | // P_UnArchiveThinkers |
||
265 | // |
||
266 | void P_UnArchiveThinkers (void) |
||
267 | { |
||
268 | byte tclass; |
||
269 | thinker_t* currentthinker; |
||
270 | thinker_t* next; |
||
271 | mobj_t* mobj; |
||
272 | |||
273 | // remove all the current thinkers |
||
274 | currentthinker = thinkercap.next; |
||
275 | while (currentthinker != &thinkercap) |
||
276 | { |
||
277 | next = currentthinker->next; |
||
278 | |||
279 | if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) |
||
280 | P_RemoveMobj ((mobj_t *)currentthinker); |
||
281 | else |
||
282 | Z_Free (currentthinker); |
||
283 | |||
284 | currentthinker = next; |
||
285 | } |
||
286 | P_InitThinkers (); |
||
287 | |||
288 | // read in saved thinkers |
||
289 | while (1) |
||
290 | { |
||
291 | tclass = *save_p++; |
||
292 | switch (tclass) |
||
293 | { |
||
294 | case tc_end: |
||
295 | return; // end of list |
||
296 | |||
297 | case tc_mobj: |
||
298 | PADSAVEP(); |
||
299 | mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); |
||
300 | memcpy (mobj, save_p, sizeof(*mobj)); |
||
301 | save_p += sizeof(*mobj); |
||
302 | mobj->state = &states[(int)mobj->state]; |
||
303 | mobj->target = NULL; |
||
304 | if (mobj->player) |
||
305 | { |
||
306 | mobj->player = &players[(int)mobj->player-1]; |
||
307 | mobj->player->mo = mobj; |
||
308 | } |
||
309 | P_SetThingPosition (mobj); |
||
310 | mobj->info = &mobjinfo[mobj->type]; |
||
311 | mobj->floorz = mobj->subsector->sector->floorheight; |
||
312 | mobj->ceilingz = mobj->subsector->sector->ceilingheight; |
||
313 | mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; |
||
314 | P_AddThinker (&mobj->thinker); |
||
315 | break; |
||
316 | |||
317 | default: |
||
318 | I_Error ("Unknown tclass %i in savegame",tclass); |
||
319 | } |
||
320 | |||
321 | } |
||
322 | |||
323 | } |
||
324 | |||
325 | |||
326 | // |
||
327 | // P_ArchiveSpecials |
||
328 | // |
||
329 | enum |
||
330 | { |
||
331 | tc_ceiling, |
||
332 | tc_door, |
||
333 | tc_floor, |
||
334 | tc_plat, |
||
335 | tc_flash, |
||
336 | tc_strobe, |
||
337 | tc_glow, |
||
338 | tc_endspecials |
||
339 | |||
340 | } specials_e; |
||
341 | |||
342 | |||
343 | |||
344 | // |
||
345 | // Things to handle: |
||
346 | // |
||
347 | // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list |
||
348 | // T_VerticalDoor, (vldoor_t: sector_t * swizzle), |
||
349 | // T_MoveFloor, (floormove_t: sector_t * swizzle), |
||
350 | // T_LightFlash, (lightflash_t: sector_t * swizzle), |
||
351 | // T_StrobeFlash, (strobe_t: sector_t *), |
||
352 | // T_Glow, (glow_t: sector_t *), |
||
353 | // T_PlatRaise, (plat_t: sector_t *), - active list |
||
354 | // |
||
355 | void P_ArchiveSpecials (void) |
||
356 | { |
||
357 | thinker_t* th; |
||
358 | ceiling_t* ceiling; |
||
359 | vldoor_t* door; |
||
360 | floormove_t* floor; |
||
361 | plat_t* plat; |
||
362 | lightflash_t* flash; |
||
363 | strobe_t* strobe; |
||
364 | glow_t* glow; |
||
365 | int i; |
||
366 | |||
367 | // save off the current thinkers |
||
368 | for (th = thinkercap.next ; th != &thinkercap ; th=th->next) |
||
369 | { |
||
370 | if (th->function.acv == (actionf_v)NULL) |
||
371 | { |
||
372 | for (i = 0; i < MAXCEILINGS;i++) |
||
373 | if (activeceilings[i] == (ceiling_t *)th) |
||
374 | break; |
||
375 | |||
376 | if (i |
||
377 | { |
||
378 | *save_p++ = tc_ceiling; |
||
379 | PADSAVEP(); |
||
380 | ceiling = (ceiling_t *)save_p; |
||
381 | memcpy (ceiling, th, sizeof(*ceiling)); |
||
382 | save_p += sizeof(*ceiling); |
||
383 | ceiling->sector = (sector_t *)(ceiling->sector - sectors); |
||
384 | } |
||
385 | continue; |
||
386 | } |
||
387 | |||
388 | if (th->function.acp1 == (actionf_p1)T_MoveCeiling) |
||
389 | { |
||
390 | *save_p++ = tc_ceiling; |
||
391 | PADSAVEP(); |
||
392 | ceiling = (ceiling_t *)save_p; |
||
393 | memcpy (ceiling, th, sizeof(*ceiling)); |
||
394 | save_p += sizeof(*ceiling); |
||
395 | ceiling->sector = (sector_t *)(ceiling->sector - sectors); |
||
396 | continue; |
||
397 | } |
||
398 | |||
399 | if (th->function.acp1 == (actionf_p1)T_VerticalDoor) |
||
400 | { |
||
401 | *save_p++ = tc_door; |
||
402 | PADSAVEP(); |
||
403 | door = (vldoor_t *)save_p; |
||
404 | memcpy (door, th, sizeof(*door)); |
||
405 | save_p += sizeof(*door); |
||
406 | door->sector = (sector_t *)(door->sector - sectors); |
||
407 | continue; |
||
408 | } |
||
409 | |||
410 | if (th->function.acp1 == (actionf_p1)T_MoveFloor) |
||
411 | { |
||
412 | *save_p++ = tc_floor; |
||
413 | PADSAVEP(); |
||
414 | floor = (floormove_t *)save_p; |
||
415 | memcpy (floor, th, sizeof(*floor)); |
||
416 | save_p += sizeof(*floor); |
||
417 | floor->sector = (sector_t *)(floor->sector - sectors); |
||
418 | continue; |
||
419 | } |
||
420 | |||
421 | if (th->function.acp1 == (actionf_p1)T_PlatRaise) |
||
422 | { |
||
423 | *save_p++ = tc_plat; |
||
424 | PADSAVEP(); |
||
425 | plat = (plat_t *)save_p; |
||
426 | memcpy (plat, th, sizeof(*plat)); |
||
427 | save_p += sizeof(*plat); |
||
428 | plat->sector = (sector_t *)(plat->sector - sectors); |
||
429 | continue; |
||
430 | } |
||
431 | |||
432 | if (th->function.acp1 == (actionf_p1)T_LightFlash) |
||
433 | { |
||
434 | *save_p++ = tc_flash; |
||
435 | PADSAVEP(); |
||
436 | flash = (lightflash_t *)save_p; |
||
437 | memcpy (flash, th, sizeof(*flash)); |
||
438 | save_p += sizeof(*flash); |
||
439 | flash->sector = (sector_t *)(flash->sector - sectors); |
||
440 | continue; |
||
441 | } |
||
442 | |||
443 | if (th->function.acp1 == (actionf_p1)T_StrobeFlash) |
||
444 | { |
||
445 | *save_p++ = tc_strobe; |
||
446 | PADSAVEP(); |
||
447 | strobe = (strobe_t *)save_p; |
||
448 | memcpy (strobe, th, sizeof(*strobe)); |
||
449 | save_p += sizeof(*strobe); |
||
450 | strobe->sector = (sector_t *)(strobe->sector - sectors); |
||
451 | continue; |
||
452 | } |
||
453 | |||
454 | if (th->function.acp1 == (actionf_p1)T_Glow) |
||
455 | { |
||
456 | *save_p++ = tc_glow; |
||
457 | PADSAVEP(); |
||
458 | glow = (glow_t *)save_p; |
||
459 | memcpy (glow, th, sizeof(*glow)); |
||
460 | save_p += sizeof(*glow); |
||
461 | glow->sector = (sector_t *)(glow->sector - sectors); |
||
462 | continue; |
||
463 | } |
||
464 | } |
||
465 | |||
466 | // add a terminating marker |
||
467 | *save_p++ = tc_endspecials; |
||
468 | |||
469 | } |
||
470 | |||
471 | |||
472 | // |
||
473 | // P_UnArchiveSpecials |
||
474 | // |
||
475 | void P_UnArchiveSpecials (void) |
||
476 | { |
||
477 | byte tclass; |
||
478 | ceiling_t* ceiling; |
||
479 | vldoor_t* door; |
||
480 | floormove_t* floor; |
||
481 | plat_t* plat; |
||
482 | lightflash_t* flash; |
||
483 | strobe_t* strobe; |
||
484 | glow_t* glow; |
||
485 | |||
486 | |||
487 | // read in saved thinkers |
||
488 | while (1) |
||
489 | { |
||
490 | tclass = *save_p++; |
||
491 | switch (tclass) |
||
492 | { |
||
493 | case tc_endspecials: |
||
494 | return; // end of list |
||
495 | |||
496 | case tc_ceiling: |
||
497 | PADSAVEP(); |
||
498 | ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); |
||
499 | memcpy (ceiling, save_p, sizeof(*ceiling)); |
||
500 | save_p += sizeof(*ceiling); |
||
501 | ceiling->sector = §ors[(int)ceiling->sector]; |
||
502 | ceiling->sector->specialdata = ceiling; |
||
503 | |||
504 | if (ceiling->thinker.function.acp1) |
||
505 | ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; |
||
506 | |||
507 | P_AddThinker (&ceiling->thinker); |
||
508 | P_AddActiveCeiling(ceiling); |
||
509 | break; |
||
510 | |||
511 | case tc_door: |
||
512 | PADSAVEP(); |
||
513 | door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); |
||
514 | memcpy (door, save_p, sizeof(*door)); |
||
515 | save_p += sizeof(*door); |
||
516 | door->sector = §ors[(int)door->sector]; |
||
517 | door->sector->specialdata = door; |
||
518 | door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; |
||
519 | P_AddThinker (&door->thinker); |
||
520 | break; |
||
521 | |||
522 | case tc_floor: |
||
523 | PADSAVEP(); |
||
524 | floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); |
||
525 | memcpy (floor, save_p, sizeof(*floor)); |
||
526 | save_p += sizeof(*floor); |
||
527 | floor->sector = §ors[(int)floor->sector]; |
||
528 | floor->sector->specialdata = floor; |
||
529 | floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; |
||
530 | P_AddThinker (&floor->thinker); |
||
531 | break; |
||
532 | |||
533 | case tc_plat: |
||
534 | PADSAVEP(); |
||
535 | plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); |
||
536 | memcpy (plat, save_p, sizeof(*plat)); |
||
537 | save_p += sizeof(*plat); |
||
538 | plat->sector = §ors[(int)plat->sector]; |
||
539 | plat->sector->specialdata = plat; |
||
540 | |||
541 | if (plat->thinker.function.acp1) |
||
542 | plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise; |
||
543 | |||
544 | P_AddThinker (&plat->thinker); |
||
545 | P_AddActivePlat(plat); |
||
546 | break; |
||
547 | |||
548 | case tc_flash: |
||
549 | PADSAVEP(); |
||
550 | flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); |
||
551 | memcpy (flash, save_p, sizeof(*flash)); |
||
552 | save_p += sizeof(*flash); |
||
553 | flash->sector = §ors[(int)flash->sector]; |
||
554 | flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; |
||
555 | P_AddThinker (&flash->thinker); |
||
556 | break; |
||
557 | |||
558 | case tc_strobe: |
||
559 | PADSAVEP(); |
||
560 | strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); |
||
561 | memcpy (strobe, save_p, sizeof(*strobe)); |
||
562 | save_p += sizeof(*strobe); |
||
563 | strobe->sector = §ors[(int)strobe->sector]; |
||
564 | strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; |
||
565 | P_AddThinker (&strobe->thinker); |
||
566 | break; |
||
567 | |||
568 | case tc_glow: |
||
569 | PADSAVEP(); |
||
570 | glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); |
||
571 | memcpy (glow, save_p, sizeof(*glow)); |
||
572 | save_p += sizeof(*glow); |
||
573 | glow->sector = §ors[(int)glow->sector]; |
||
574 | glow->thinker.function.acp1 = (actionf_p1)T_Glow; |
||
575 | P_AddThinker (&glow->thinker); |
||
576 | break; |
||
577 | |||
578 | default: |
||
579 | I_Error ("P_UnarchiveSpecials:Unknown tclass %i " |
||
580 | "in savegame",tclass); |
||
581 | } |
||
582 | |||
583 | } |
||
584 | |||
585 | } |
||
586 |