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
;
256 // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
257 // thinker indices could be used by the code that saves sector info.
259 static int number_of_thinkers
;
261 void P_ThinkerToIndex(void)
266 // count the number of thinkers, and mark each one with its index, using
267 // the prev field as a placeholder, since it can be restored later.
269 number_of_thinkers
= 0;
270 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
271 if (th
->function
== P_MobjThinker
)
272 th
->prev
= (thinker_t
*)(long)(++number_of_thinkers
);
275 // phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the
276 // thinker indices could be used by the code that saves sector info.
278 void P_IndexToThinker(void)
280 // killough 2/14/98: restore prev pointers
282 thinker_t
*prev
= &thinkercap
;
284 for (th
= thinkercap
.next
; th
!= &thinkercap
; prev
=th
, th
=th
->next
)
291 // 2/14/98 killough: substantially modified to fix savegame bugs
293 void P_ArchiveThinkers (void)
297 CheckSaveGame(sizeof brain
); // killough 3/26/98: Save boss brain state
298 memcpy(save_p
, &brain
, sizeof brain
);
299 save_p
+= sizeof brain
;
301 /* check that enough room is available in savegame buffer
303 * cph - use number_of_thinkers saved by P_ThinkerToIndex above
305 CheckSaveGame(number_of_thinkers
*(sizeof(mobj_t
)+4));
307 // save off the current thinkers
308 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
309 if (th
->function
== P_MobjThinker
)
315 mobj
= (mobj_t
*)save_p
;
316 memcpy (mobj
, th
, sizeof(*mobj
));
317 save_p
+= sizeof(*mobj
);
318 mobj
->state
= (state_t
*)(mobj
->state
- states
);
320 // killough 2/14/98: convert pointers into indices.
321 // Fixes many savegame problems, by properly saving
322 // target and tracer fields. Note: we store NULL if
323 // the thinker pointed to by these fields is not a
327 mobj
->target
= mobj
->target
->thinker
.function
==
329 (mobj_t
*) mobj
->target
->thinker
.prev
: NULL
;
332 mobj
->tracer
= mobj
->tracer
->thinker
.function
==
334 (mobj_t
*) mobj
->tracer
->thinker
.prev
: NULL
;
336 // killough 2/14/98: new field: save last known enemy. Prevents
337 // monsters from going to sleep after killing monsters and not
338 // seeing player anymore.
341 mobj
->lastenemy
= mobj
->lastenemy
->thinker
.function
==
343 (mobj_t
*) mobj
->lastenemy
->thinker
.prev
: NULL
;
345 // killough 2/14/98: end changes
347 if (mobj
->above_thing
) // phares
348 mobj
->above_thing
= mobj
->above_thing
->thinker
.function
==
350 (mobj_t
*) mobj
->above_thing
->thinker
.prev
: NULL
;
352 if (mobj
->below_thing
)
353 mobj
->below_thing
= mobj
->below_thing
->thinker
.function
==
355 (mobj_t
*) mobj
->below_thing
->thinker
.prev
: NULL
; // phares
358 mobj
->player
= (player_t
*)((mobj
->player
-players
) + 1);
361 // add a terminating marker
364 // killough 9/14/98: save soundtargets
367 CheckSaveGame(numsectors
* sizeof(mobj_t
*)); // killough 9/14/98
368 for (i
= 0; i
< numsectors
; i
++)
370 mobj_t
*target
= sectors
[i
].soundtarget
;
372 target
= (mobj_t
*) target
->thinker
.prev
;
373 memcpy(save_p
, &target
, sizeof target
);
374 save_p
+= sizeof target
;
382 * Same as P_SetTarget() in p_tick.c, except that the target is nullified
383 * first, so that no old target's reference count is decreased (when loading
384 * savegames, old targets are indices, not really pointers to targets).
387 static void P_SetNewTarget(mobj_t
**mop
, mobj_t
*targ
)
390 P_SetTarget(mop
, targ
);
394 // P_UnArchiveThinkers
396 // 2/14/98 killough: substantially modified to fix savegame bugs
399 void P_UnArchiveThinkers (void)
402 mobj_t
**mobj_p
; // killough 2/14/98: Translation table
403 size_t size
; // killough 2/14/98: size of or index into table
406 // killough 3/26/98: Load boss brain state
407 memcpy(&brain
, save_p
, sizeof brain
);
408 save_p
+= sizeof brain
;
410 // remove all the current thinkers
411 for (th
= thinkercap
.next
; th
!= &thinkercap
; )
413 thinker_t
*next
= th
->next
;
414 if (th
->function
== P_MobjThinker
)
415 P_RemoveMobj ((mobj_t
*) th
);
422 // killough 2/14/98: count number of thinkers by skipping through them
424 byte
*sp
= save_p
; // save pointer and skip header
425 for (size
= 1; *save_p
++ == tc_mobj
; size
++) // killough 2/14/98
426 { // skip all entries, adding up count
428 save_p
+= sizeof(mobj_t
);
431 if (*--save_p
!= tc_end
)
432 I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p
);
434 // first table entry special: 0 maps to NULL
435 *(mobj_p
= malloc(size
* sizeof *mobj_p
)) = 0; // table of pointers
436 save_p
= sp
; // restore save pointer
439 // read in saved thinkers
440 for (size
= 1; *save_p
++ == tc_mobj
; size
++) // killough 2/14/98
442 mobj_t
*mobj
= Z_Malloc(sizeof(mobj_t
), PU_LEVEL
, NULL
);
444 // killough 2/14/98 -- insert pointers to thinkers into table, in order:
448 memcpy (mobj
, save_p
, sizeof(mobj_t
));
449 save_p
+= sizeof(mobj_t
);
450 mobj
->state
= states
+ (unsigned long) mobj
->state
;
453 (mobj
->player
= &players
[(unsigned long) mobj
->player
- 1]) -> mo
= mobj
;
455 P_SetThingPosition (mobj
);
456 mobj
->info
= &mobjinfo
[mobj
->type
];
459 // Fix for falling down into a wall after savegame loaded:
460 // mobj->floorz = mobj->subsector->sector->floorheight;
461 // mobj->ceilingz = mobj->subsector->sector->ceilingheight;
463 mobj
->thinker
.function
= P_MobjThinker
;
464 P_AddThinker (&mobj
->thinker
);
466 if (!((mobj
->flags
^ MF_COUNTKILL
) & (MF_FRIEND
| MF_COUNTKILL
| MF_CORPSE
)))
470 // killough 2/14/98: adjust target and tracer fields, plus
471 // lastenemy field, to correctly point to mobj thinkers.
472 // NULL entries automatically handled by first table entry.
474 // killough 11/98: use P_SetNewTarget() to set fields
476 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
478 P_SetNewTarget(&((mobj_t
*) th
)->target
,
479 mobj_p
[(size_t)((mobj_t
*)th
)->target
]);
481 P_SetNewTarget(&((mobj_t
*) th
)->tracer
,
482 mobj_p
[(size_t)((mobj_t
*)th
)->tracer
]);
484 P_SetNewTarget(&((mobj_t
*) th
)->lastenemy
,
485 mobj_p
[(size_t)((mobj_t
*)th
)->lastenemy
]);
487 // phares: added two new fields for Sprite Height problem
489 P_SetNewTarget(&((mobj_t
*) th
)->above_thing
,
490 mobj_p
[(size_t)((mobj_t
*)th
)->above_thing
]);
492 P_SetNewTarget(&((mobj_t
*) th
)->below_thing
,
493 mobj_p
[(size_t)((mobj_t
*)th
)->below_thing
]);
496 { // killough 9/14/98: restore soundtargets
498 for (i
= 0; i
< numsectors
; i
++)
501 memcpy(&target
, save_p
, sizeof target
);
502 save_p
+= sizeof target
;
503 P_SetNewTarget(§ors
[i
].soundtarget
, mobj_p
[(size_t) target
]);
507 free(mobj_p
); // free translation table
509 // killough 3/26/98: Spawn icon landings:
510 if (gamemode
== commercial
)
511 P_SpawnBrainTargets();
525 tc_elevator
, //jff 2/22/98 new elevator type thinker
526 tc_scroll
, // killough 3/7/98: new scroll effect thinker
527 tc_pusher
, // phares 3/22/98: new push/pull effect thinker
528 tc_flicker
, // killough 10/4/98
535 // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
536 // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
537 // T_MoveFloor, (floormove_t: sector_t * swizzle),
538 // T_LightFlash, (lightflash_t: sector_t * swizzle),
539 // T_StrobeFlash, (strobe_t: sector_t *),
540 // T_Glow, (glow_t: sector_t *),
541 // T_PlatRaise, (plat_t: sector_t *), - active list
542 // T_MoveElevator, (plat_t: sector_t *), - active list // jff 2/22/98
543 // T_Scroll // killough 3/7/98
544 // T_Pusher // phares 3/22/98
545 // T_FireFlicker // killough 10/4/98
548 void P_ArchiveSpecials (void)
551 size_t size
= 0; // killough
553 // save off the current thinkers (memory size calculation -- killough)
555 for (th
= thinkercap
.next
; th
!= &thinkercap
; th
=th
->next
)
559 ceilinglist_t
*cl
; //jff 2/22/98 need this for ceilings too now
560 for (pl
=activeplats
; pl
; pl
=pl
->next
)
561 if (pl
->plat
== (plat_t
*) th
) // killough 2/14/98
563 size
+= 4+sizeof(plat_t
);
566 for (cl
=activeceilings
; cl
; cl
=cl
->next
) // search for activeceiling
567 if (cl
->ceiling
== (ceiling_t
*) th
) //jff 2/22/98
569 size
+= 4+sizeof(ceiling_t
);
576 th
->function
==T_MoveCeiling
? 4+sizeof(ceiling_t
) :
577 th
->function
==T_VerticalDoor
? 4+sizeof(vldoor_t
) :
578 th
->function
==T_MoveFloor
? 4+sizeof(floormove_t
):
579 th
->function
==T_PlatRaise
? 4+sizeof(plat_t
) :
580 th
->function
==T_LightFlash
? 4+sizeof(lightflash_t
):
581 th
->function
==T_StrobeFlash
? 4+sizeof(strobe_t
) :
582 th
->function
==T_Glow
? 4+sizeof(glow_t
) :
583 th
->function
==T_MoveElevator
? 4+sizeof(elevator_t
):
584 th
->function
==T_Scroll
? 4+sizeof(scroll_t
) :
585 th
->function
==T_Pusher
? 4+sizeof(pusher_t
) :
586 th
->function
==T_FireFlicker
? 4+sizeof(fireflicker_t
) :
589 CheckSaveGame(size
); // killough
591 // save off the current thinkers
592 for (th
=thinkercap
.next
; th
!=&thinkercap
; th
=th
->next
)
597 ceilinglist_t
*cl
; //jff 2/22/98 add iter variable for ceilings
599 // killough 2/8/98: fix plat original height bug.
600 // Since acv==NULL, this could be a plat in stasis.
601 // so check the active plats list, and save this
602 // plat (jff: or ceiling) even if it is in stasis.
604 for (pl
=activeplats
; pl
; pl
=pl
->next
)
605 if (pl
->plat
== (plat_t
*) th
) // killough 2/14/98
608 for (cl
=activeceilings
; cl
; cl
=cl
->next
)
609 if (cl
->ceiling
== (ceiling_t
*) th
) //jff 2/22/98
615 if (th
->function
== T_MoveCeiling
)
618 ceiling
: // killough 2/14/98
619 *save_p
++ = tc_ceiling
;
621 ceiling
= (ceiling_t
*)save_p
;
622 memcpy (ceiling
, th
, sizeof(*ceiling
));
623 save_p
+= sizeof(*ceiling
);
624 ceiling
->sector
= (sector_t
*)(ceiling
->sector
- sectors
);
628 if (th
->function
== T_VerticalDoor
)
633 door
= (vldoor_t
*) save_p
;
634 memcpy (door
, th
, sizeof *door
);
635 save_p
+= sizeof(*door
);
636 door
->sector
= (sector_t
*)(door
->sector
- sectors
);
637 //jff 1/31/98 archive line remembered by door as well
638 door
->line
= (line_t
*) (door
->line
? door
->line
-lines
: -1);
642 if (th
->function
== T_MoveFloor
)
645 *save_p
++ = tc_floor
;
647 floor
= (floormove_t
*)save_p
;
648 memcpy (floor
, th
, sizeof(*floor
));
649 save_p
+= sizeof(*floor
);
650 floor
->sector
= (sector_t
*)(floor
->sector
- sectors
);
654 if (th
->function
== T_PlatRaise
)
657 plat
: // killough 2/14/98: added fix for original plat height above
660 plat
= (plat_t
*)save_p
;
661 memcpy (plat
, th
, sizeof(*plat
));
662 save_p
+= sizeof(*plat
);
663 plat
->sector
= (sector_t
*)(plat
->sector
- sectors
);
667 if (th
->function
== T_LightFlash
)
670 *save_p
++ = tc_flash
;
672 flash
= (lightflash_t
*)save_p
;
673 memcpy (flash
, th
, sizeof(*flash
));
674 save_p
+= sizeof(*flash
);
675 flash
->sector
= (sector_t
*)(flash
->sector
- sectors
);
679 if (th
->function
== T_StrobeFlash
)
682 *save_p
++ = tc_strobe
;
684 strobe
= (strobe_t
*)save_p
;
685 memcpy (strobe
, th
, sizeof(*strobe
));
686 save_p
+= sizeof(*strobe
);
687 strobe
->sector
= (sector_t
*)(strobe
->sector
- sectors
);
691 if (th
->function
== T_Glow
)
696 glow
= (glow_t
*)save_p
;
697 memcpy (glow
, th
, sizeof(*glow
));
698 save_p
+= sizeof(*glow
);
699 glow
->sector
= (sector_t
*)(glow
->sector
- sectors
);
703 // killough 10/4/98: save flickers
704 if (th
->function
== T_FireFlicker
)
706 fireflicker_t
*flicker
;
707 *save_p
++ = tc_flicker
;
709 flicker
= (fireflicker_t
*)save_p
;
710 memcpy (flicker
, th
, sizeof(*flicker
));
711 save_p
+= sizeof(*flicker
);
712 flicker
->sector
= (sector_t
*)(flicker
->sector
- sectors
);
716 //jff 2/22/98 new case for elevators
717 if (th
->function
== T_MoveElevator
)
719 elevator_t
*elevator
; //jff 2/22/98
720 *save_p
++ = tc_elevator
;
722 elevator
= (elevator_t
*)save_p
;
723 memcpy (elevator
, th
, sizeof(*elevator
));
724 save_p
+= sizeof(*elevator
);
725 elevator
->sector
= (sector_t
*)(elevator
->sector
- sectors
);
729 // killough 3/7/98: Scroll effect thinkers
730 if (th
->function
== T_Scroll
)
732 *save_p
++ = tc_scroll
;
733 memcpy (save_p
, th
, sizeof(scroll_t
));
734 save_p
+= sizeof(scroll_t
);
738 // phares 3/22/98: Push/Pull effect thinkers
740 if (th
->function
== T_Pusher
)
742 *save_p
++ = tc_pusher
;
743 memcpy (save_p
, th
, sizeof(pusher_t
));
744 save_p
+= sizeof(pusher_t
);
749 // add a terminating marker
750 *save_p
++ = tc_endspecials
;
755 // P_UnArchiveSpecials
757 void P_UnArchiveSpecials (void)
761 // read in saved thinkers
762 while ((tclass
= *save_p
++) != tc_endspecials
) // killough 2/14/98
768 ceiling_t
*ceiling
= Z_Malloc (sizeof(*ceiling
), PU_LEVEL
, NULL
);
769 memcpy (ceiling
, save_p
, sizeof(*ceiling
));
770 save_p
+= sizeof(*ceiling
);
771 ceiling
->sector
= §ors
[(unsigned long)ceiling
->sector
];
772 ceiling
->sector
->ceilingdata
= ceiling
; //jff 2/22/98
774 if (ceiling
->thinker
.function
)
775 ceiling
->thinker
.function
= T_MoveCeiling
;
777 P_AddThinker (&ceiling
->thinker
);
778 P_AddActiveCeiling(ceiling
);
785 vldoor_t
*door
= Z_Malloc (sizeof(*door
), PU_LEVEL
, NULL
);
786 memcpy (door
, save_p
, sizeof(*door
));
787 save_p
+= sizeof(*door
);
788 door
->sector
= §ors
[(unsigned long)door
->sector
];
790 //jff 1/31/98 unarchive line remembered by door as well
791 door
->line
= (long)door
->line
!=-1? &lines
[(unsigned long)door
->line
] : NULL
;
793 door
->sector
->ceilingdata
= door
; //jff 2/22/98
794 door
->thinker
.function
= T_VerticalDoor
;
795 P_AddThinker (&door
->thinker
);
802 floormove_t
*floor
= Z_Malloc (sizeof(*floor
), PU_LEVEL
, NULL
);
803 memcpy (floor
, save_p
, sizeof(*floor
));
804 save_p
+= sizeof(*floor
);
805 floor
->sector
= §ors
[(unsigned long)floor
->sector
];
806 floor
->sector
->floordata
= floor
; //jff 2/22/98
807 floor
->thinker
.function
= T_MoveFloor
;
808 P_AddThinker (&floor
->thinker
);
815 plat_t
*plat
= Z_Malloc (sizeof(*plat
), PU_LEVEL
, NULL
);
816 memcpy (plat
, save_p
, sizeof(*plat
));
817 save_p
+= sizeof(*plat
);
818 plat
->sector
= §ors
[(unsigned long)plat
->sector
];
819 plat
->sector
->floordata
= plat
; //jff 2/22/98
821 if (plat
->thinker
.function
)
822 plat
->thinker
.function
= T_PlatRaise
;
824 P_AddThinker (&plat
->thinker
);
825 P_AddActivePlat(plat
);
832 lightflash_t
*flash
= Z_Malloc (sizeof(*flash
), PU_LEVEL
, NULL
);
833 memcpy (flash
, save_p
, sizeof(*flash
));
834 save_p
+= sizeof(*flash
);
835 flash
->sector
= §ors
[(unsigned long)flash
->sector
];
836 flash
->thinker
.function
= T_LightFlash
;
837 P_AddThinker (&flash
->thinker
);
844 strobe_t
*strobe
= Z_Malloc (sizeof(*strobe
), PU_LEVEL
, NULL
);
845 memcpy (strobe
, save_p
, sizeof(*strobe
));
846 save_p
+= sizeof(*strobe
);
847 strobe
->sector
= §ors
[(unsigned long)strobe
->sector
];
848 strobe
->thinker
.function
= T_StrobeFlash
;
849 P_AddThinker (&strobe
->thinker
);
856 glow_t
*glow
= Z_Malloc (sizeof(*glow
), PU_LEVEL
, NULL
);
857 memcpy (glow
, save_p
, sizeof(*glow
));
858 save_p
+= sizeof(*glow
);
859 glow
->sector
= §ors
[(unsigned long)glow
->sector
];
860 glow
->thinker
.function
= T_Glow
;
861 P_AddThinker (&glow
->thinker
);
865 case tc_flicker
: // killough 10/4/98
868 fireflicker_t
*flicker
= Z_Malloc (sizeof(*flicker
), PU_LEVEL
, NULL
);
869 memcpy (flicker
, save_p
, sizeof(*flicker
));
870 save_p
+= sizeof(*flicker
);
871 flicker
->sector
= §ors
[(unsigned long)flicker
->sector
];
872 flicker
->thinker
.function
= T_FireFlicker
;
873 P_AddThinker (&flicker
->thinker
);
877 //jff 2/22/98 new case for elevators
881 elevator_t
*elevator
= Z_Malloc (sizeof(*elevator
), PU_LEVEL
, NULL
);
882 memcpy (elevator
, save_p
, sizeof(*elevator
));
883 save_p
+= sizeof(*elevator
);
884 elevator
->sector
= §ors
[(unsigned long)elevator
->sector
];
885 elevator
->sector
->floordata
= elevator
; //jff 2/22/98
886 elevator
->sector
->ceilingdata
= elevator
; //jff 2/22/98
887 elevator
->thinker
.function
= T_MoveElevator
;
888 P_AddThinker (&elevator
->thinker
);
892 case tc_scroll
: // killough 3/7/98: scroll effect thinkers
894 scroll_t
*scroll
= Z_Malloc (sizeof(scroll_t
), PU_LEVEL
, NULL
);
895 memcpy (scroll
, save_p
, sizeof(scroll_t
));
896 save_p
+= sizeof(scroll_t
);
897 scroll
->thinker
.function
= T_Scroll
;
898 P_AddThinker(&scroll
->thinker
);
902 case tc_pusher
: // phares 3/22/98: new Push/Pull effect thinkers
904 pusher_t
*pusher
= Z_Malloc (sizeof(pusher_t
), PU_LEVEL
, NULL
);
905 memcpy (pusher
, save_p
, sizeof(pusher_t
));
906 save_p
+= sizeof(pusher_t
);
907 pusher
->thinker
.function
= T_Pusher
;
908 pusher
->source
= P_GetPushThing(pusher
->affectee
);
909 P_AddThinker(&pusher
->thinker
);
914 I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass
);
918 // killough 2/16/98: save/restore random number generator state information
920 void P_ArchiveRNG(void)
922 CheckSaveGame(sizeof rng
);
923 memcpy(save_p
, &rng
, sizeof rng
);
924 save_p
+= sizeof rng
;
927 void P_UnArchiveRNG(void)
929 memcpy(&rng
, save_p
, sizeof rng
);
930 save_p
+= sizeof rng
;
933 // killough 2/22/98: Save/restore automap state
934 // killough 2/22/98: Save/restore automap state
935 void P_ArchiveMap(void)
937 int zero
= 0, one
= 1;
938 CheckSaveGame(2 * sizeof zero
+ sizeof markpointnum
+
939 markpointnum
* sizeof *markpoints
+
940 sizeof automapmode
+ sizeof one
);
942 memcpy(save_p
, &automapmode
, sizeof automapmode
);
943 save_p
+= sizeof automapmode
;
944 memcpy(save_p
, &one
, sizeof one
); // CPhipps - used to be viewactive, now
945 save_p
+= sizeof one
; // that's worked out locally by D_Display
946 memcpy(save_p
, &zero
, sizeof zero
); // CPhipps - used to be followplayer
947 save_p
+= sizeof zero
; // that is now part of automapmode
948 memcpy(save_p
, &zero
, sizeof zero
); // CPhipps - used to be automap_grid, ditto
949 save_p
+= sizeof zero
;
950 memcpy(save_p
, &markpointnum
, sizeof markpointnum
);
951 save_p
+= sizeof markpointnum
;
955 memcpy(save_p
, markpoints
, sizeof *markpoints
* markpointnum
);
956 save_p
+= markpointnum
* sizeof *markpoints
;
960 void P_UnArchiveMap(void)
963 memcpy(&automapmode
, save_p
, sizeof automapmode
);
964 save_p
+= sizeof automapmode
;
965 memcpy(&unused
, save_p
, sizeof unused
);
966 save_p
+= sizeof unused
;
967 memcpy(&unused
, save_p
, sizeof unused
);
968 save_p
+= sizeof unused
;
969 memcpy(&unused
, save_p
, sizeof unused
);
970 save_p
+= sizeof unused
;
972 if (automapmode
& am_active
)
975 memcpy(&markpointnum
, save_p
, sizeof markpointnum
);
976 save_p
+= sizeof markpointnum
;
980 while (markpointnum
>= markpointnum_max
)
981 markpoints
= realloc(markpoints
, sizeof *markpoints
*
982 (markpointnum_max
= markpointnum_max
? markpointnum_max
*2 : 16));
983 memcpy(markpoints
, save_p
, markpointnum
* sizeof *markpoints
);
984 save_p
+= markpointnum
* sizeof *markpoints
;