#include "doomdef.h" #include "p_local.h" // 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 int leveltime; //============================================================================= /* ==================== = = P_ArchivePlayers = ==================== */ void P_ArchivePlayers (void) { int i,j; player_t *dest; for (i=0 ; ipsprites[j].state) dest->psprites[j].state = (state_t *)(dest->psprites[j].state-states); } } } /* ==================== = = P_UnArchivePlayers = ==================== */ void P_UnArchivePlayers (void) { int i,j; for (i=0 ; ifloorheight >> 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 ; iflags; *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,j; sector_t *sec; line_t *li; side_t *si; short *get; get = (short *)save_p; // // do sectors // for (i=0, sec = sectors ; ifloorheight = *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 ; iflags = *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; } //============================================================================= 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 == 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, *next; mobj_t *mobj; // // remove all the current thinkers // currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function == 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 = 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; void P_ArchiveSpecials (void) { /* 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 */ 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 == NULL) { for (i = 0; i < MAXCEILINGS;i++) if (activeceilings[i] == (ceiling_t *)th) break; if (isector = (sector_t *)(ceiling->sector - sectors); } continue; } if (th->function == 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 == 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 == 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 == 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 == 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 == 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 == 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) ceiling->thinker.function = 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 = 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 = 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) plat->thinker.function = 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 = 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 = 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 = T_Glow; P_AddThinker (&glow->thinker); break; default: I_Error ("P_UnarchiveSpecials:Unknown tclass %i " "in savegame",tclass); } } } /* =============================================================================== THINKERS All thinkers should be allocated by Z_Malloc so they can be operated on uniformly. The actual structures will vary in size, but the first element must be thinker_t. =============================================================================== */ thinker_t thinkercap; // both the head and tail of the thinker list /* =============== = = P_InitThinkers = =============== */ void P_InitThinkers (void) { thinkercap.prev = thinkercap.next = &thinkercap; } /* =============== = = P_AddThinker = = Adds a new thinker at the end of the list = =============== */ void P_AddThinker (thinker_t *thinker) { thinkercap.prev->next = thinker; thinker->next = &thinkercap; thinker->prev = thinkercap.prev; thinkercap.prev = thinker; } /* =============== = = P_RemoveThinker = = Deallocation is lazy -- it will not actually be freed until its = thinking turn comes up = =============== */ void P_RemoveThinker (thinker_t *thinker) { thinker->function = (think_t)-1; } /* =============== = = P_AllocateThinker = = Allocates memory and adds a new thinker at the end of the list = =============== */ void P_AllocateThinker (thinker_t *thinker) { } /* =============== = = P_RunThinkers = =============== */ void P_RunThinkers (void) { thinker_t *currentthinker; currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { if (currentthinker->function == (think_t)-1) { // time to remove it currentthinker->next->prev = currentthinker->prev; currentthinker->prev->next = currentthinker->next; Z_Free (currentthinker); } else { if (currentthinker->function) currentthinker->function (currentthinker); } currentthinker = currentthinker->next; } } //============================================================================= /* ================= = = P_Ticker = ================= */ //extern int soundVolume; extern int sfxVolume; extern int musicVolume; void P_Ticker (void) { int i; // // run the tic // if (paused) return; // pause if in menu and at least one tic has been run if ( !netgame && menuactive && !demoplayback && players[consoleplayer].viewz != 1) return; for (i=0 ; i