1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * Archiving: SaveGame I/O.
30 *-----------------------------------------------------------------------------*/
42 #include "rockmacros.h"
45 // Pads save_p to a 4-byte boundary
46 // so that the load/save works on SGI&Gecko.
47 #define PADSAVEP() do { save_p += (4 - ((unsigned long) save_p & 3)) & 3; } while (0)
51 void P_ArchivePlayers (void)
55 CheckSaveGame(sizeof(player_t
) * MAXPLAYERS
); // killough
56 for (i
=0 ; i
<MAXPLAYERS
; i
++)
63 dest
= (player_t
*) save_p
;
64 memcpy(dest
, &players
[i
], sizeof(player_t
));
65 save_p
+= sizeof(player_t
);
66 for (j
=0; j
<NUMPSPRITES
; j
++)
67 if (dest
->psprites
[j
].state
)
68 dest
->psprites
[j
].state
=
69 (state_t
*)(dest
->psprites
[j
].state
-states
);
76 void P_UnArchivePlayers (void)
80 for (i
=0 ; i
<MAXPLAYERS
; i
++)
87 memcpy(&players
[i
], save_p
, sizeof(player_t
));
88 save_p
+= sizeof(player_t
);
90 // will be set when unarc thinker
92 players
[i
].message
= NULL
;
93 players
[i
].attacker
= NULL
;
95 for (j
=0 ; j
<NUMPSPRITES
; j
++)
96 if (players
[i
]. psprites
[j
].state
)
97 players
[i
]. psprites
[j
].state
=
98 &states
[ (unsigned long)players
[i
].psprites
[j
].state
];
106 void P_ArchiveWorld (void)
114 // killough 3/22/98: fix bug caused by hoisting save_p too early
115 // killough 10/98: adjust size for changes below
117 (sizeof(short)*5 + sizeof sec
->floorheight
+ sizeof sec
->ceilingheight
)
118 * numsectors
+ sizeof(short)*3*numlines
+ 4;
120 for (i
=0; i
<numlines
; i
++)
122 if (lines
[i
].sidenum
[0] != -1)
124 sizeof(short)*3 + sizeof si
->textureoffset
+ sizeof si
->rowoffset
;
125 if (lines
[i
].sidenum
[1] != -1)
127 sizeof(short)*3 + sizeof si
->textureoffset
+ sizeof si
->rowoffset
;
130 CheckSaveGame(size
); // killough
132 PADSAVEP(); // killough 3/22/98
134 put
= (short *)save_p
;
137 for (i
=0, sec
= sectors
; i
<numsectors
; i
++,sec
++)
139 // killough 10/98: save full floor & ceiling heights, including fraction
140 memcpy(put
, &sec
->floorheight
, sizeof sec
->floorheight
);
141 put
= (void *)((char *) put
+ sizeof sec
->floorheight
);
142 memcpy(put
, &sec
->ceilingheight
, sizeof sec
->ceilingheight
);
143 put
= (void *)((char *) put
+ sizeof sec
->ceilingheight
);
145 *put
++ = sec
->floorpic
;
146 *put
++ = sec
->ceilingpic
;
147 *put
++ = sec
->lightlevel
;
148 *put
++ = sec
->special
; // needed? yes -- transfer types
149 *put
++ = sec
->tag
; // needed? need them -- killough
153 for (i
=0, li
= lines
; i
<numlines
; i
++,li
++)
158 *put
++ = li
->special
;
162 if (li
->sidenum
[j
] != -1)
164 si
= &sides
[li
->sidenum
[j
]];
166 // killough 10/98: save full sidedef offsets,
167 // preserving fractional scroll offsets
169 memcpy(put
, &si
->textureoffset
, sizeof si
->textureoffset
);
170 put
= (void *)((char *) put
+ sizeof si
->textureoffset
);
171 memcpy(put
, &si
->rowoffset
, sizeof si
->rowoffset
);
172 put
= (void *)((char *) put
+ sizeof si
->rowoffset
);
174 *put
++ = si
->toptexture
;
175 *put
++ = si
->bottomtexture
;
176 *put
++ = si
->midtexture
;
179 save_p
= (byte
*) put
;
187 void P_UnArchiveWorld (void)
194 PADSAVEP(); // killough 3/22/98
196 get
= (short *) save_p
;
199 for (i
=0, sec
= sectors
; i
<numsectors
; i
++,sec
++)
201 // killough 10/98: load full floor & ceiling heights, including fractions
203 memcpy(&sec
->floorheight
, get
, sizeof sec
->floorheight
);
204 get
= (void *)((char *) get
+ sizeof sec
->floorheight
);
205 memcpy(&sec
->ceilingheight
, get
, sizeof sec
->ceilingheight
);
206 get
= (void *)((char *) get
+ sizeof sec
->ceilingheight
);
208 sec
->floorpic
= *get
++;
209 sec
->ceilingpic
= *get
++;
210 sec
->lightlevel
= *get
++;
211 sec
->special
= *get
++;
213 sec
->ceilingdata
= 0; //jff 2/22/98 now three thinker fields, not two
215 sec
->lightingdata
= 0;
216 sec
->soundtarget
= 0;
220 for (i
=0, li
= lines
; i
<numlines
; i
++,li
++)
225 li
->special
= *get
++;
227 for (j
=0 ; j
<2 ; j
++)
228 if (li
->sidenum
[j
] != -1)
230 side_t
*si
= &sides
[li
->sidenum
[j
]];
232 // killough 10/98: load full sidedef offsets, including fractions
234 memcpy(&si
->textureoffset
, get
, sizeof si
->textureoffset
);
235 get
= (void *)((char *) get
+ sizeof si
->textureoffset
);
236 memcpy(&si
->rowoffset
, get
, sizeof si
->rowoffset
);
237 get
= (void *)((char *) get
+ sizeof si
->rowoffset
);
239 si
->toptexture
= *get
++;
240 si
->bottomtexture
= *get
++;
241 si
->midtexture
= *get
++;
244 save_p
= (byte
*) get
;
255 typedef unsigned thinkerclass_t
;
257 // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
258 // thinker indices could be used by the code that saves sector info.
260 static int number_of_thinkers
;
262 void P_ThinkerToIndex(void)
267 // count the number of thinkers, and mark each one with its index, using
268 // the prev field as a placeholder, since it can be restored later.
270 number_of_thinkers
= 0;
271 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
272 if (th
->function
== P_MobjThinker
)
273 th
->prev
= (thinker_t
*)(long)(++number_of_thinkers
);
276 // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
277 // thinker indices could be used by the code that saves sector info.
279 void P_IndexToThinker(void)
281 // killough 2/14/98: restore prev pointers
283 thinker_t
*prev
= &thinkercap
;
285 for (th
= thinkercap
.next
; th
!= &thinkercap
; prev
=th
, th
=th
->next
)
292 // 2/14/98 killough: substantially modified to fix savegame bugs
294 void P_ArchiveThinkers (void)
298 CheckSaveGame(sizeof brain
); // killough 3/26/98: Save boss brain state
299 memcpy(save_p
, &brain
, sizeof brain
);
300 save_p
+= sizeof brain
;
302 /* check that enough room is available in savegame buffer
304 * cph - use number_of_thinkers saved by P_ThinkerToIndex above
306 CheckSaveGame(number_of_thinkers
*(sizeof(mobj_t
)+4));
308 // save off the current thinkers
309 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
310 if (th
->function
== P_MobjThinker
)
316 mobj
= (mobj_t
*)save_p
;
317 memcpy (mobj
, th
, sizeof(*mobj
));
318 save_p
+= sizeof(*mobj
);
319 mobj
->state
= (state_t
*)(mobj
->state
- states
);
321 // killough 2/14/98: convert pointers into indices.
322 // Fixes many savegame problems, by properly saving
323 // target and tracer fields. Note: we store NULL if
324 // the thinker pointed to by these fields is not a
328 mobj
->target
= mobj
->target
->thinker
.function
==
330 (mobj_t
*) mobj
->target
->thinker
.prev
: NULL
;
333 mobj
->tracer
= mobj
->tracer
->thinker
.function
==
335 (mobj_t
*) mobj
->tracer
->thinker
.prev
: NULL
;
337 // killough 2/14/98: new field: save last known enemy. Prevents
338 // monsters from going to sleep after killing monsters and not
339 // seeing player anymore.
342 mobj
->lastenemy
= mobj
->lastenemy
->thinker
.function
==
344 (mobj_t
*) mobj
->lastenemy
->thinker
.prev
: NULL
;
346 // killough 2/14/98: end changes
348 if (mobj
->above_thing
) // phares
349 mobj
->above_thing
= mobj
->above_thing
->thinker
.function
==
351 (mobj_t
*) mobj
->above_thing
->thinker
.prev
: NULL
;
353 if (mobj
->below_thing
)
354 mobj
->below_thing
= mobj
->below_thing
->thinker
.function
==
356 (mobj_t
*) mobj
->below_thing
->thinker
.prev
: NULL
; // phares
359 mobj
->player
= (player_t
*)((mobj
->player
-players
) + 1);
362 // add a terminating marker
365 // killough 9/14/98: save soundtargets
368 CheckSaveGame(numsectors
* sizeof(mobj_t
*)); // killough 9/14/98
369 for (i
= 0; i
< numsectors
; i
++)
371 mobj_t
*target
= sectors
[i
].soundtarget
;
373 target
= (mobj_t
*) target
->thinker
.prev
;
374 memcpy(save_p
, &target
, sizeof target
);
375 save_p
+= sizeof target
;
383 * Same as P_SetTarget() in p_tick.c, except that the target is nullified
384 * first, so that no old target's reference count is decreased (when loading
385 * savegames, old targets are indices, not really pointers to targets).
388 static void P_SetNewTarget(mobj_t
**mop
, mobj_t
*targ
)
391 P_SetTarget(mop
, targ
);
395 // P_UnArchiveThinkers
397 // 2/14/98 killough: substantially modified to fix savegame bugs
400 void P_UnArchiveThinkers (void)
403 mobj_t
**mobj_p
; // killough 2/14/98: Translation table
404 size_t size
; // killough 2/14/98: size of or index into table
407 // killough 3/26/98: Load boss brain state
408 memcpy(&brain
, save_p
, sizeof brain
);
409 save_p
+= sizeof brain
;
411 // remove all the current thinkers
412 for (th
= thinkercap
.next
; th
!= &thinkercap
; )
414 thinker_t
*next
= th
->next
;
415 if (th
->function
== P_MobjThinker
)
416 P_RemoveMobj ((mobj_t
*) th
);
423 // killough 2/14/98: count number of thinkers by skipping through them
425 byte
*sp
= save_p
; // save pointer and skip header
426 for (size
= 1; *save_p
++ == tc_mobj
; size
++) // killough 2/14/98
427 { // skip all entries, adding up count
429 save_p
+= sizeof(mobj_t
);
432 if (*--save_p
!= tc_end
)
433 I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p
);
435 // first table entry special: 0 maps to NULL
436 *(mobj_p
= malloc(size
* sizeof *mobj_p
)) = 0; // table of pointers
437 save_p
= sp
; // restore save pointer
440 // read in saved thinkers
441 for (size
= 1; *save_p
++ == tc_mobj
; size
++) // killough 2/14/98
443 mobj_t
*mobj
= Z_Malloc(sizeof(mobj_t
), PU_LEVEL
, NULL
);
445 // killough 2/14/98 -- insert pointers to thinkers into table, in order:
449 memcpy (mobj
, save_p
, sizeof(mobj_t
));
450 save_p
+= sizeof(mobj_t
);
451 mobj
->state
= states
+ (unsigned long) mobj
->state
;
454 (mobj
->player
= &players
[(unsigned long) mobj
->player
- 1]) -> mo
= mobj
;
456 P_SetThingPosition (mobj
);
457 mobj
->info
= &mobjinfo
[mobj
->type
];
460 // Fix for falling down into a wall after savegame loaded:
461 // mobj->floorz = mobj->subsector->sector->floorheight;
462 // mobj->ceilingz = mobj->subsector->sector->ceilingheight;
464 mobj
->thinker
.function
= P_MobjThinker
;
465 P_AddThinker (&mobj
->thinker
);
467 if (!((mobj
->flags
^ MF_COUNTKILL
) & (MF_FRIEND
| MF_COUNTKILL
| MF_CORPSE
)))
471 // killough 2/14/98: adjust target and tracer fields, plus
472 // lastenemy field, to correctly point to mobj thinkers.
473 // NULL entries automatically handled by first table entry.
475 // killough 11/98: use P_SetNewTarget() to set fields
477 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
479 P_SetNewTarget(&((mobj_t
*) th
)->target
,
480 mobj_p
[(size_t)((mobj_t
*)th
)->target
]);
482 P_SetNewTarget(&((mobj_t
*) th
)->tracer
,
483 mobj_p
[(size_t)((mobj_t
*)th
)->tracer
]);
485 P_SetNewTarget(&((mobj_t
*) th
)->lastenemy
,
486 mobj_p
[(size_t)((mobj_t
*)th
)->lastenemy
]);
488 // phares: added two new fields for Sprite Height problem
490 P_SetNewTarget(&((mobj_t
*) th
)->above_thing
,
491 mobj_p
[(size_t)((mobj_t
*)th
)->above_thing
]);
493 P_SetNewTarget(&((mobj_t
*) th
)->below_thing
,
494 mobj_p
[(size_t)((mobj_t
*)th
)->below_thing
]);
497 { // killough 9/14/98: restore soundtargets
499 for (i
= 0; i
< numsectors
; i
++)
502 memcpy(&target
, save_p
, sizeof target
);
503 save_p
+= sizeof target
;
504 P_SetNewTarget(§ors
[i
].soundtarget
, mobj_p
[(size_t) target
]);
508 free(mobj_p
); // free translation table
510 // killough 3/26/98: Spawn icon landings:
511 if (gamemode
== commercial
)
512 P_SpawnBrainTargets();
526 tc_elevator
, //jff 2/22/98 new elevator type thinker
527 tc_scroll
, // killough 3/7/98: new scroll effect thinker
528 tc_pusher
, // phares 3/22/98: new push/pull effect thinker
529 tc_flicker
, // killough 10/4/98
537 // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
538 // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
539 // T_MoveFloor, (floormove_t: sector_t * swizzle),
540 // T_LightFlash, (lightflash_t: sector_t * swizzle),
541 // T_StrobeFlash, (strobe_t: sector_t *),
542 // T_Glow, (glow_t: sector_t *),
543 // T_PlatRaise, (plat_t: sector_t *), - active list
544 // T_MoveElevator, (plat_t: sector_t *), - active list // jff 2/22/98
545 // T_Scroll // killough 3/7/98
546 // T_Pusher // phares 3/22/98
547 // T_FireFlicker // killough 10/4/98
550 void P_ArchiveSpecials (void)
553 size_t size
= 0; // killough
555 // save off the current thinkers (memory size calculation -- killough)
557 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
561 ceilinglist_t
*cl
; //jff 2/22/98 need this for ceilings too now
562 for (pl
=activeplats
; pl
; pl
=pl
->next
)
563 if (pl
->plat
== (plat_t
*) th
) // killough 2/14/98
565 size
+= 4+sizeof(plat_t
);
568 for (cl
=activeceilings
; cl
; cl
=cl
->next
) // search for activeceiling
569 if (cl
->ceiling
== (ceiling_t
*) th
) //jff 2/22/98
571 size
+= 4+sizeof(ceiling_t
);
578 th
->function
==T_MoveCeiling
? 4+sizeof(ceiling_t
) :
579 th
->function
==T_VerticalDoor
? 4+sizeof(vldoor_t
) :
580 th
->function
==T_MoveFloor
? 4+sizeof(floormove_t
):
581 th
->function
==T_PlatRaise
? 4+sizeof(plat_t
) :
582 th
->function
==T_LightFlash
? 4+sizeof(lightflash_t
):
583 th
->function
==T_StrobeFlash
? 4+sizeof(strobe_t
) :
584 th
->function
==T_Glow
? 4+sizeof(glow_t
) :
585 th
->function
==T_MoveElevator
? 4+sizeof(elevator_t
):
586 th
->function
==T_Scroll
? 4+sizeof(scroll_t
) :
587 th
->function
==T_Pusher
? 4+sizeof(pusher_t
) :
588 th
->function
==T_FireFlicker
? 4+sizeof(fireflicker_t
) :
591 CheckSaveGame(size
); // killough
593 // save off the current thinkers
594 for (th
=thinkercap
.next
; th
!=&thinkercap
; th
=th
->next
)
599 ceilinglist_t
*cl
; //jff 2/22/98 add iter variable for ceilings
601 // killough 2/8/98: fix plat original height bug.
602 // Since acv==NULL, this could be a plat in stasis.
603 // so check the active plats list, and save this
604 // plat (jff: or ceiling) even if it is in stasis.
606 for (pl
=activeplats
; pl
; pl
=pl
->next
)
607 if (pl
->plat
== (plat_t
*) th
) // killough 2/14/98
610 for (cl
=activeceilings
; cl
; cl
=cl
->next
)
611 if (cl
->ceiling
== (ceiling_t
*) th
) //jff 2/22/98
617 if (th
->function
== T_MoveCeiling
)
620 ceiling
: // killough 2/14/98
621 *save_p
++ = tc_ceiling
;
623 ceiling
= (ceiling_t
*)save_p
;
624 memcpy (ceiling
, th
, sizeof(*ceiling
));
625 save_p
+= sizeof(*ceiling
);
626 ceiling
->sector
= (sector_t
*)(ceiling
->sector
- sectors
);
630 if (th
->function
== T_VerticalDoor
)
635 door
= (vldoor_t
*) save_p
;
636 memcpy (door
, th
, sizeof *door
);
637 save_p
+= sizeof(*door
);
638 door
->sector
= (sector_t
*)(door
->sector
- sectors
);
639 //jff 1/31/98 archive line remembered by door as well
640 door
->line
= (line_t
*) (door
->line
? door
->line
-lines
: -1);
644 if (th
->function
== T_MoveFloor
)
647 *save_p
++ = tc_floor
;
649 floor
= (floormove_t
*)save_p
;
650 memcpy (floor
, th
, sizeof(*floor
));
651 save_p
+= sizeof(*floor
);
652 floor
->sector
= (sector_t
*)(floor
->sector
- sectors
);
656 if (th
->function
== T_PlatRaise
)
659 plat
: // killough 2/14/98: added fix for original plat height above
662 plat
= (plat_t
*)save_p
;
663 memcpy (plat
, th
, sizeof(*plat
));
664 save_p
+= sizeof(*plat
);
665 plat
->sector
= (sector_t
*)(plat
->sector
- sectors
);
669 if (th
->function
== T_LightFlash
)
672 *save_p
++ = tc_flash
;
674 flash
= (lightflash_t
*)save_p
;
675 memcpy (flash
, th
, sizeof(*flash
));
676 save_p
+= sizeof(*flash
);
677 flash
->sector
= (sector_t
*)(flash
->sector
- sectors
);
681 if (th
->function
== T_StrobeFlash
)
684 *save_p
++ = tc_strobe
;
686 strobe
= (strobe_t
*)save_p
;
687 memcpy (strobe
, th
, sizeof(*strobe
));
688 save_p
+= sizeof(*strobe
);
689 strobe
->sector
= (sector_t
*)(strobe
->sector
- sectors
);
693 if (th
->function
== T_Glow
)
698 glow
= (glow_t
*)save_p
;
699 memcpy (glow
, th
, sizeof(*glow
));
700 save_p
+= sizeof(*glow
);
701 glow
->sector
= (sector_t
*)(glow
->sector
- sectors
);
705 // killough 10/4/98: save flickers
706 if (th
->function
== T_FireFlicker
)
708 fireflicker_t
*flicker
;
709 *save_p
++ = tc_flicker
;
711 flicker
= (fireflicker_t
*)save_p
;
712 memcpy (flicker
, th
, sizeof(*flicker
));
713 save_p
+= sizeof(*flicker
);
714 flicker
->sector
= (sector_t
*)(flicker
->sector
- sectors
);
718 //jff 2/22/98 new case for elevators
719 if (th
->function
== T_MoveElevator
)
721 elevator_t
*elevator
; //jff 2/22/98
722 *save_p
++ = tc_elevator
;
724 elevator
= (elevator_t
*)save_p
;
725 memcpy (elevator
, th
, sizeof(*elevator
));
726 save_p
+= sizeof(*elevator
);
727 elevator
->sector
= (sector_t
*)(elevator
->sector
- sectors
);
731 // killough 3/7/98: Scroll effect thinkers
732 if (th
->function
== T_Scroll
)
734 *save_p
++ = tc_scroll
;
735 memcpy (save_p
, th
, sizeof(scroll_t
));
736 save_p
+= sizeof(scroll_t
);
740 // phares 3/22/98: Push/Pull effect thinkers
742 if (th
->function
== T_Pusher
)
744 *save_p
++ = tc_pusher
;
745 memcpy (save_p
, th
, sizeof(pusher_t
));
746 save_p
+= sizeof(pusher_t
);
751 // add a terminating marker
752 *save_p
++ = tc_endspecials
;
757 // P_UnArchiveSpecials
759 void P_UnArchiveSpecials (void)
763 // read in saved thinkers
764 while ((tclass
= *save_p
++) != tc_endspecials
) // killough 2/14/98
770 ceiling_t
*ceiling
= Z_Malloc (sizeof(*ceiling
), PU_LEVEL
, NULL
);
771 memcpy (ceiling
, save_p
, sizeof(*ceiling
));
772 save_p
+= sizeof(*ceiling
);
773 ceiling
->sector
= §ors
[(unsigned long)ceiling
->sector
];
774 ceiling
->sector
->ceilingdata
= ceiling
; //jff 2/22/98
776 if (ceiling
->thinker
.function
)
777 ceiling
->thinker
.function
= T_MoveCeiling
;
779 P_AddThinker (&ceiling
->thinker
);
780 P_AddActiveCeiling(ceiling
);
787 vldoor_t
*door
= Z_Malloc (sizeof(*door
), PU_LEVEL
, NULL
);
788 memcpy (door
, save_p
, sizeof(*door
));
789 save_p
+= sizeof(*door
);
790 door
->sector
= §ors
[(unsigned long)door
->sector
];
792 //jff 1/31/98 unarchive line remembered by door as well
793 door
->line
= (long)door
->line
!=-1? &lines
[(unsigned long)door
->line
] : NULL
;
795 door
->sector
->ceilingdata
= door
; //jff 2/22/98
796 door
->thinker
.function
= T_VerticalDoor
;
797 P_AddThinker (&door
->thinker
);
804 floormove_t
*floor
= Z_Malloc (sizeof(*floor
), PU_LEVEL
, NULL
);
805 memcpy (floor
, save_p
, sizeof(*floor
));
806 save_p
+= sizeof(*floor
);
807 floor
->sector
= §ors
[(unsigned long)floor
->sector
];
808 floor
->sector
->floordata
= floor
; //jff 2/22/98
809 floor
->thinker
.function
= T_MoveFloor
;
810 P_AddThinker (&floor
->thinker
);
817 plat_t
*plat
= Z_Malloc (sizeof(*plat
), PU_LEVEL
, NULL
);
818 memcpy (plat
, save_p
, sizeof(*plat
));
819 save_p
+= sizeof(*plat
);
820 plat
->sector
= §ors
[(unsigned long)plat
->sector
];
821 plat
->sector
->floordata
= plat
; //jff 2/22/98
823 if (plat
->thinker
.function
)
824 plat
->thinker
.function
= T_PlatRaise
;
826 P_AddThinker (&plat
->thinker
);
827 P_AddActivePlat(plat
);
834 lightflash_t
*flash
= Z_Malloc (sizeof(*flash
), PU_LEVEL
, NULL
);
835 memcpy (flash
, save_p
, sizeof(*flash
));
836 save_p
+= sizeof(*flash
);
837 flash
->sector
= §ors
[(unsigned long)flash
->sector
];
838 flash
->thinker
.function
= T_LightFlash
;
839 P_AddThinker (&flash
->thinker
);
846 strobe_t
*strobe
= Z_Malloc (sizeof(*strobe
), PU_LEVEL
, NULL
);
847 memcpy (strobe
, save_p
, sizeof(*strobe
));
848 save_p
+= sizeof(*strobe
);
849 strobe
->sector
= §ors
[(unsigned long)strobe
->sector
];
850 strobe
->thinker
.function
= T_StrobeFlash
;
851 P_AddThinker (&strobe
->thinker
);
858 glow_t
*glow
= Z_Malloc (sizeof(*glow
), PU_LEVEL
, NULL
);
859 memcpy (glow
, save_p
, sizeof(*glow
));
860 save_p
+= sizeof(*glow
);
861 glow
->sector
= §ors
[(unsigned long)glow
->sector
];
862 glow
->thinker
.function
= T_Glow
;
863 P_AddThinker (&glow
->thinker
);
867 case tc_flicker
: // killough 10/4/98
870 fireflicker_t
*flicker
= Z_Malloc (sizeof(*flicker
), PU_LEVEL
, NULL
);
871 memcpy (flicker
, save_p
, sizeof(*flicker
));
872 save_p
+= sizeof(*flicker
);
873 flicker
->sector
= §ors
[(unsigned long)flicker
->sector
];
874 flicker
->thinker
.function
= T_FireFlicker
;
875 P_AddThinker (&flicker
->thinker
);
879 //jff 2/22/98 new case for elevators
883 elevator_t
*elevator
= Z_Malloc (sizeof(*elevator
), PU_LEVEL
, NULL
);
884 memcpy (elevator
, save_p
, sizeof(*elevator
));
885 save_p
+= sizeof(*elevator
);
886 elevator
->sector
= §ors
[(unsigned long)elevator
->sector
];
887 elevator
->sector
->floordata
= elevator
; //jff 2/22/98
888 elevator
->sector
->ceilingdata
= elevator
; //jff 2/22/98
889 elevator
->thinker
.function
= T_MoveElevator
;
890 P_AddThinker (&elevator
->thinker
);
894 case tc_scroll
: // killough 3/7/98: scroll effect thinkers
896 scroll_t
*scroll
= Z_Malloc (sizeof(scroll_t
), PU_LEVEL
, NULL
);
897 memcpy (scroll
, save_p
, sizeof(scroll_t
));
898 save_p
+= sizeof(scroll_t
);
899 scroll
->thinker
.function
= T_Scroll
;
900 P_AddThinker(&scroll
->thinker
);
904 case tc_pusher
: // phares 3/22/98: new Push/Pull effect thinkers
906 pusher_t
*pusher
= Z_Malloc (sizeof(pusher_t
), PU_LEVEL
, NULL
);
907 memcpy (pusher
, save_p
, sizeof(pusher_t
));
908 save_p
+= sizeof(pusher_t
);
909 pusher
->thinker
.function
= T_Pusher
;
910 pusher
->source
= P_GetPushThing(pusher
->affectee
);
911 P_AddThinker(&pusher
->thinker
);
916 I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass
);
920 // killough 2/16/98: save/restore random number generator state information
922 void P_ArchiveRNG(void)
924 CheckSaveGame(sizeof rng
);
925 memcpy(save_p
, &rng
, sizeof rng
);
926 save_p
+= sizeof rng
;
929 void P_UnArchiveRNG(void)
931 memcpy(&rng
, save_p
, sizeof rng
);
932 save_p
+= sizeof rng
;
935 // killough 2/22/98: Save/restore automap state
936 // killough 2/22/98: Save/restore automap state
937 void P_ArchiveMap(void)
939 int zero
= 0, one
= 1;
940 CheckSaveGame(2 * sizeof zero
+ sizeof markpointnum
+
941 markpointnum
* sizeof *markpoints
+
942 sizeof automapmode
+ sizeof one
);
944 memcpy(save_p
, &automapmode
, sizeof automapmode
);
945 save_p
+= sizeof automapmode
;
946 memcpy(save_p
, &one
, sizeof one
); // CPhipps - used to be viewactive, now
947 save_p
+= sizeof one
; // that's worked out locally by D_Display
948 memcpy(save_p
, &zero
, sizeof zero
); // CPhipps - used to be followplayer
949 save_p
+= sizeof zero
; // that is now part of automapmode
950 memcpy(save_p
, &zero
, sizeof zero
); // CPhipps - used to be automap_grid, ditto
951 save_p
+= sizeof zero
;
952 memcpy(save_p
, &markpointnum
, sizeof markpointnum
);
953 save_p
+= sizeof markpointnum
;
957 memcpy(save_p
, markpoints
, sizeof *markpoints
* markpointnum
);
958 save_p
+= markpointnum
* sizeof *markpoints
;
962 void P_UnArchiveMap(void)
965 memcpy(&automapmode
, save_p
, sizeof automapmode
);
966 save_p
+= sizeof automapmode
;
967 memcpy(&unused
, save_p
, sizeof unused
);
968 save_p
+= sizeof unused
;
969 memcpy(&unused
, save_p
, sizeof unused
);
970 save_p
+= sizeof unused
;
971 memcpy(&unused
, save_p
, sizeof unused
);
972 save_p
+= sizeof unused
;
974 if (automapmode
& am_active
)
977 memcpy(&markpointnum
, save_p
, sizeof markpointnum
);
978 save_p
+= sizeof markpointnum
;
982 while (markpointnum
>= markpointnum_max
)
983 markpoints
= realloc(markpoints
, sizeof *markpoints
*
984 (markpointnum_max
= markpointnum_max
? markpointnum_max
*2 : 16));
985 memcpy(markpoints
, save_p
, markpointnum
* sizeof *markpoints
);
986 save_p
+= markpointnum
* sizeof *markpoints
;