diff options
Diffstat (limited to 'demos/3rdparty/doom/p_saveg.c')
-rw-r--r-- | demos/3rdparty/doom/p_saveg.c | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/demos/3rdparty/doom/p_saveg.c b/demos/3rdparty/doom/p_saveg.c new file mode 100644 index 00000000..4500a540 --- /dev/null +++ b/demos/3rdparty/doom/p_saveg.c @@ -0,0 +1,586 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// Archiving: SaveGame I/O. +// +//----------------------------------------------------------------------------- + +static const char +rcsid[] = "$Id: p_tick.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; + +#include "i_system.h" +#include "z_zone.h" +#include "p_local.h" + +// State. +#include "doomstat.h" +#include "r_state.h" + +byte* save_p; + + +// Pads save_p to a 4-byte boundary +// so that the load/save works on SGI&Gecko. +#define PADSAVEP() save_p += (4 - ((int) save_p & 3)) & 3 + + + +// +// P_ArchivePlayers +// +void P_ArchivePlayers (void) +{ + int i; + int j; + player_t* dest; + + for (i=0 ; i<MAXPLAYERS ; i++) + { + if (!playeringame[i]) + continue; + + PADSAVEP(); + + dest = (player_t *)save_p; + memcpy (dest,&players[i],sizeof(player_t)); + save_p += sizeof(player_t); + for (j=0 ; j<NUMPSPRITES ; j++) + { + if (dest->psprites[j].state) + { + dest->psprites[j].state + = (state_t *)(dest->psprites[j].state-states); + } + } + } +} + + + +// +// P_UnArchivePlayers +// +void P_UnArchivePlayers (void) +{ + int i; + int j; + + for (i=0 ; i<MAXPLAYERS ; i++) + { + if (!playeringame[i]) + continue; + + PADSAVEP(); + + memcpy (&players[i],save_p, sizeof(player_t)); + save_p += sizeof(player_t); + + // will be set when unarc thinker + players[i].mo = NULL; + players[i].message = NULL; + players[i].attacker = NULL; + + for (j=0 ; j<NUMPSPRITES ; j++) + { + if (players[i]. psprites[j].state) + { + players[i]. psprites[j].state + = &states[ (int)players[i].psprites[j].state ]; + } + } + } +} + + +// +// P_ArchiveWorld +// +void P_ArchiveWorld (void) +{ + int i; + int j; + sector_t* sec; + line_t* li; + side_t* si; + short* put; + + put = (short *)save_p; + + // do sectors + for (i=0, sec = sectors ; i<numsectors ; i++,sec++) + { + *put++ = sec->floorheight >> FRACBITS; + *put++ = sec->ceilingheight >> FRACBITS; + *put++ = sec->floorpic; + *put++ = sec->ceilingpic; + *put++ = sec->lightlevel; + *put++ = sec->special; // needed? + *put++ = sec->tag; // needed? + } + + + // do lines + for (i=0, li = lines ; i<numlines ; i++,li++) + { + *put++ = li->flags; + *put++ = li->special; + *put++ = li->tag; + for (j=0 ; j<2 ; j++) + { + if (li->sidenum[j] == -1) + continue; + + si = &sides[li->sidenum[j]]; + + *put++ = si->textureoffset >> FRACBITS; + *put++ = si->rowoffset >> FRACBITS; + *put++ = si->toptexture; + *put++ = si->bottomtexture; + *put++ = si->midtexture; + } + } + + save_p = (byte *)put; +} + + + +// +// P_UnArchiveWorld +// +void P_UnArchiveWorld (void) +{ + int i; + int j; + sector_t* sec; + line_t* li; + side_t* si; + short* get; + + get = (short *)save_p; + + // do sectors + for (i=0, sec = sectors ; i<numsectors ; i++,sec++) + { + sec->floorheight = *get++ << FRACBITS; + sec->ceilingheight = *get++ << FRACBITS; + sec->floorpic = *get++; + sec->ceilingpic = *get++; + sec->lightlevel = *get++; + sec->special = *get++; // needed? + sec->tag = *get++; // needed? + sec->specialdata = 0; + sec->soundtarget = 0; + } + + // do lines + for (i=0, li = lines ; i<numlines ; i++,li++) + { + li->flags = *get++; + li->special = *get++; + li->tag = *get++; + for (j=0 ; j<2 ; j++) + { + if (li->sidenum[j] == -1) + continue; + si = &sides[li->sidenum[j]]; + si->textureoffset = *get++ << FRACBITS; + si->rowoffset = *get++ << FRACBITS; + si->toptexture = *get++; + si->bottomtexture = *get++; + si->midtexture = *get++; + } + } + save_p = (byte *)get; +} + + + + + +// +// Thinkers +// +typedef enum +{ + tc_end, + tc_mobj + +} thinkerclass_t; + + + +// +// P_ArchiveThinkers +// +void P_ArchiveThinkers (void) +{ + thinker_t* th; + mobj_t* mobj; + + // save off the current thinkers + for (th = thinkercap.next ; th != &thinkercap ; th=th->next) + { + if (th->function.acp1 == (actionf_p1)P_MobjThinker) + { + *save_p++ = tc_mobj; + PADSAVEP(); + mobj = (mobj_t *)save_p; + memcpy (mobj, th, sizeof(*mobj)); + save_p += sizeof(*mobj); + mobj->state = (state_t *)(mobj->state - states); + + if (mobj->player) + mobj->player = (player_t *)((mobj->player-players) + 1); + continue; + } + + // I_Error ("P_ArchiveThinkers: Unknown thinker function"); + } + + // add a terminating marker + *save_p++ = tc_end; +} + + + +// +// P_UnArchiveThinkers +// +void P_UnArchiveThinkers (void) +{ + byte tclass; + thinker_t* currentthinker; + thinker_t* next; + mobj_t* mobj; + + // remove all the current thinkers + currentthinker = thinkercap.next; + while (currentthinker != &thinkercap) + { + next = currentthinker->next; + + if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) + P_RemoveMobj ((mobj_t *)currentthinker); + else + Z_Free (currentthinker); + + currentthinker = next; + } + P_InitThinkers (); + + // read in saved thinkers + while (1) + { + tclass = *save_p++; + switch (tclass) + { + case tc_end: + return; // end of list + + case tc_mobj: + PADSAVEP(); + mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL); + memcpy (mobj, save_p, sizeof(*mobj)); + save_p += sizeof(*mobj); + mobj->state = &states[(int)mobj->state]; + mobj->target = NULL; + if (mobj->player) + { + mobj->player = &players[(int)mobj->player-1]; + mobj->player->mo = mobj; + } + P_SetThingPosition (mobj); + mobj->info = &mobjinfo[mobj->type]; + mobj->floorz = mobj->subsector->sector->floorheight; + mobj->ceilingz = mobj->subsector->sector->ceilingheight; + mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; + P_AddThinker (&mobj->thinker); + break; + + default: + I_Error ("Unknown tclass %i in savegame",tclass); + } + + } + +} + + +// +// P_ArchiveSpecials +// +enum +{ + tc_ceiling, + tc_door, + tc_floor, + tc_plat, + tc_flash, + tc_strobe, + tc_glow, + tc_endspecials + +} specials_e; + + + +// +// Things to handle: +// +// T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list +// T_VerticalDoor, (vldoor_t: sector_t * swizzle), +// T_MoveFloor, (floormove_t: sector_t * swizzle), +// T_LightFlash, (lightflash_t: sector_t * swizzle), +// T_StrobeFlash, (strobe_t: sector_t *), +// T_Glow, (glow_t: sector_t *), +// T_PlatRaise, (plat_t: sector_t *), - active list +// +void P_ArchiveSpecials (void) +{ + thinker_t* th; + ceiling_t* ceiling; + vldoor_t* door; + floormove_t* floor; + plat_t* plat; + lightflash_t* flash; + strobe_t* strobe; + glow_t* glow; + int i; + + // save off the current thinkers + for (th = thinkercap.next ; th != &thinkercap ; th=th->next) + { + if (th->function.acv == (actionf_v)NULL) + { + for (i = 0; i < MAXCEILINGS;i++) + if (activeceilings[i] == (ceiling_t *)th) + break; + + if (i<MAXCEILINGS) + { + *save_p++ = tc_ceiling; + PADSAVEP(); + ceiling = (ceiling_t *)save_p; + memcpy (ceiling, th, sizeof(*ceiling)); + save_p += sizeof(*ceiling); + ceiling->sector = (sector_t *)(ceiling->sector - sectors); + } + continue; + } + + if (th->function.acp1 == (actionf_p1)T_MoveCeiling) + { + *save_p++ = tc_ceiling; + PADSAVEP(); + ceiling = (ceiling_t *)save_p; + memcpy (ceiling, th, sizeof(*ceiling)); + save_p += sizeof(*ceiling); + ceiling->sector = (sector_t *)(ceiling->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_VerticalDoor) + { + *save_p++ = tc_door; + PADSAVEP(); + door = (vldoor_t *)save_p; + memcpy (door, th, sizeof(*door)); + save_p += sizeof(*door); + door->sector = (sector_t *)(door->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_MoveFloor) + { + *save_p++ = tc_floor; + PADSAVEP(); + floor = (floormove_t *)save_p; + memcpy (floor, th, sizeof(*floor)); + save_p += sizeof(*floor); + floor->sector = (sector_t *)(floor->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_PlatRaise) + { + *save_p++ = tc_plat; + PADSAVEP(); + plat = (plat_t *)save_p; + memcpy (plat, th, sizeof(*plat)); + save_p += sizeof(*plat); + plat->sector = (sector_t *)(plat->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_LightFlash) + { + *save_p++ = tc_flash; + PADSAVEP(); + flash = (lightflash_t *)save_p; + memcpy (flash, th, sizeof(*flash)); + save_p += sizeof(*flash); + flash->sector = (sector_t *)(flash->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_StrobeFlash) + { + *save_p++ = tc_strobe; + PADSAVEP(); + strobe = (strobe_t *)save_p; + memcpy (strobe, th, sizeof(*strobe)); + save_p += sizeof(*strobe); + strobe->sector = (sector_t *)(strobe->sector - sectors); + continue; + } + + if (th->function.acp1 == (actionf_p1)T_Glow) + { + *save_p++ = tc_glow; + PADSAVEP(); + glow = (glow_t *)save_p; + memcpy (glow, th, sizeof(*glow)); + save_p += sizeof(*glow); + glow->sector = (sector_t *)(glow->sector - sectors); + continue; + } + } + + // add a terminating marker + *save_p++ = tc_endspecials; + +} + + +// +// P_UnArchiveSpecials +// +void P_UnArchiveSpecials (void) +{ + byte tclass; + ceiling_t* ceiling; + vldoor_t* door; + floormove_t* floor; + plat_t* plat; + lightflash_t* flash; + strobe_t* strobe; + glow_t* glow; + + + // read in saved thinkers + while (1) + { + tclass = *save_p++; + switch (tclass) + { + case tc_endspecials: + return; // end of list + + case tc_ceiling: + PADSAVEP(); + ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); + memcpy (ceiling, save_p, sizeof(*ceiling)); + save_p += sizeof(*ceiling); + ceiling->sector = §ors[(int)ceiling->sector]; + ceiling->sector->specialdata = ceiling; + + if (ceiling->thinker.function.acp1) + ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; + + P_AddThinker (&ceiling->thinker); + P_AddActiveCeiling(ceiling); + break; + + case tc_door: + PADSAVEP(); + door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); + memcpy (door, save_p, sizeof(*door)); + save_p += sizeof(*door); + door->sector = §ors[(int)door->sector]; + door->sector->specialdata = door; + door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; + P_AddThinker (&door->thinker); + break; + + case tc_floor: + PADSAVEP(); + floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); + memcpy (floor, save_p, sizeof(*floor)); + save_p += sizeof(*floor); + floor->sector = §ors[(int)floor->sector]; + floor->sector->specialdata = floor; + floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; + P_AddThinker (&floor->thinker); + break; + + case tc_plat: + PADSAVEP(); + plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); + memcpy (plat, save_p, sizeof(*plat)); + save_p += sizeof(*plat); + plat->sector = §ors[(int)plat->sector]; + plat->sector->specialdata = plat; + + if (plat->thinker.function.acp1) + plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise; + + P_AddThinker (&plat->thinker); + P_AddActivePlat(plat); + break; + + case tc_flash: + PADSAVEP(); + flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); + memcpy (flash, save_p, sizeof(*flash)); + save_p += sizeof(*flash); + flash->sector = §ors[(int)flash->sector]; + flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; + P_AddThinker (&flash->thinker); + break; + + case tc_strobe: + PADSAVEP(); + strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); + memcpy (strobe, save_p, sizeof(*strobe)); + save_p += sizeof(*strobe); + strobe->sector = §ors[(int)strobe->sector]; + strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; + P_AddThinker (&strobe->thinker); + break; + + case tc_glow: + PADSAVEP(); + glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); + memcpy (glow, save_p, sizeof(*glow)); + save_p += sizeof(*glow); + glow->sector = §ors[(int)glow->sector]; + glow->thinker.function.acp1 = (actionf_p1)T_Glow; + P_AddThinker (&glow->thinker); + break; + + default: + I_Error ("P_UnarchiveSpecials:Unknown tclass %i " + "in savegame",tclass); + } + + } + +} + |