diff options
Diffstat (limited to 'src/heretic/p_tick.c')
-rw-r--r-- | src/heretic/p_tick.c | 643 |
1 files changed, 643 insertions, 0 deletions
diff --git a/src/heretic/p_tick.c b/src/heretic/p_tick.c new file mode 100644 index 00000000..bbed1292 --- /dev/null +++ b/src/heretic/p_tick.c @@ -0,0 +1,643 @@ + +// P_tick.c + +#include "DoomDef.h" +#include "P_local.h" + +int leveltime; +int TimerGame; + +/* +==================== += += P_ArchivePlayers += +==================== +*/ + +void P_ArchivePlayers(void) +{ + int i; + int j; + player_t dest; + + for(i = 0; i < MAXPLAYERS; i++) + { + if(!playeringame[i]) + { + continue; + } + memcpy(&dest, &players[i], 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); + } + } + SV_Write(&dest, sizeof(player_t)); + } +} + +/* +==================== += += P_UnArchivePlayers += +==================== +*/ + +void P_UnArchivePlayers (void) +{ + int i,j; + + for (i=0 ; i<MAXPLAYERS ; i++) + { + if (!playeringame[i]) + continue; + memcpy (&players[i],save_p, sizeof(player_t)); + save_p += sizeof(player_t); + players[i].mo = NULL; // will be set when unarc thinker + 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, j; + sector_t *sec; + line_t *li; + side_t *si; + + // Sectors + for(i = 0, sec = sectors; i < numsectors; i++, sec++) + { + SV_WriteWord(sec->floorheight>>FRACBITS); + SV_WriteWord(sec->ceilingheight>>FRACBITS); + SV_WriteWord(sec->floorpic); + SV_WriteWord(sec->ceilingpic); + SV_WriteWord(sec->lightlevel); + SV_WriteWord(sec->special); // needed? + SV_WriteWord(sec->tag); // needed? + } + + // Lines + for(i = 0, li = lines; i < numlines; i++, li++) + { + SV_WriteWord(li->flags); + SV_WriteWord(li->special); + SV_WriteWord(li->tag); + for(j = 0; j < 2; j++) + { + if(li->sidenum[j] == -1) + { + continue; + } + si = &sides[li->sidenum[j]]; + SV_WriteWord(si->textureoffset>>FRACBITS); + SV_WriteWord(si->rowoffset>>FRACBITS); + SV_WriteWord(si->toptexture); + SV_WriteWord(si->bottomtexture); + SV_WriteWord(si->midtexture); + } + } +} + +/* +==================== += += 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 ; 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; +} + +//============================================================================= + +typedef enum +{ + tc_end, + tc_mobj +} thinkerclass_t; + +/* +==================== += += P_ArchiveThinkers += +==================== +*/ + +void P_ArchiveThinkers(void) +{ + thinker_t *th; + mobj_t mobj; + + for(th = thinkercap.next; th != &thinkercap; th = th->next) + { + if(th->function == P_MobjThinker) + { + SV_WriteByte(tc_mobj); + memcpy(&mobj, th, sizeof(mobj_t)); + mobj.state = (state_t *)(mobj.state-states); + if(mobj.player) + { + mobj.player = (player_t *)((mobj.player-players)+1); + } + SV_Write(&mobj, sizeof(mobj_t)); + continue; + } + //I_Error("P_ArchiveThinkers: Unknown thinker function"); + } + + // Add a terminating marker + SV_WriteByte(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: + 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; + + for(th = thinkercap.next; th != &thinkercap; th = th->next) + { + if(th->function == T_MoveCeiling) + { + SV_WriteByte(tc_ceiling); + memcpy(&ceiling, th, sizeof(ceiling_t)); + ceiling.sector = (sector_t *)(ceiling.sector-sectors); + SV_Write(&ceiling, sizeof(ceiling_t)); + continue; + } + if(th->function == T_VerticalDoor) + { + SV_WriteByte(tc_door); + memcpy(&door, th, sizeof(vldoor_t)); + door.sector = (sector_t *)(door.sector-sectors); + SV_Write(&door, sizeof(vldoor_t)); + continue; + } + if(th->function == T_MoveFloor) + { + SV_WriteByte(tc_floor); + memcpy(&floor, th, sizeof(floormove_t)); + floor.sector = (sector_t *)(floor.sector-sectors); + SV_Write(&floor, sizeof(floormove_t)); + continue; + } + if(th->function == T_PlatRaise) + { + SV_WriteByte(tc_plat); + memcpy(&plat, th, sizeof(plat_t)); + plat.sector = (sector_t *)(plat.sector-sectors); + SV_Write(&plat, sizeof(plat_t)); + continue; + } + if(th->function == T_LightFlash) + { + SV_WriteByte(tc_flash); + memcpy(&flash, th, sizeof(lightflash_t)); + flash.sector = (sector_t *)(flash.sector-sectors); + SV_Write(&flash, sizeof(lightflash_t)); + continue; + } + if(th->function == T_StrobeFlash) + { + SV_WriteByte(tc_strobe); + memcpy(&strobe, th, sizeof(strobe_t)); + strobe.sector = (sector_t *)(strobe.sector-sectors); + SV_Write(&strobe, sizeof(strobe_t)); + continue; + } + if(th->function == T_Glow) + { + SV_WriteByte(tc_glow); + memcpy(&glow, th, sizeof(glow_t)); + glow.sector = (sector_t *)(glow.sector-sectors); + SV_Write(&glow, sizeof(glow_t)); + continue; + } + } + // Add a terminating marker + SV_WriteByte(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: + 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 = T_MoveCeiling; + if (ceiling->thinker.function) + ceiling->thinker.function = T_MoveCeiling; + P_AddThinker (&ceiling->thinker); + P_AddActiveCeiling(ceiling); + break; + + case tc_door: + 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: + 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 = T_MoveFloor; + floor->thinker.function = T_MoveFloor; + P_AddThinker (&floor->thinker); + break; + + case tc_plat: + 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 = T_PlatRaise; + if (plat->thinker.function) + plat->thinker.function = T_PlatRaise; + P_AddThinker (&plat->thinker); + P_AddActivePlat(plat); + break; + + case tc_flash: + 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: + 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: + 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; + } +} + +//---------------------------------------------------------------------------- +// +// PROC P_Ticker +// +//---------------------------------------------------------------------------- + +void P_Ticker(void) +{ + int i; + + if(paused) + { + return; + } + for(i = 0; i < MAXPLAYERS; i++) + { + if(playeringame[i]) + { + P_PlayerThink(&players[i]); + } + } + if(TimerGame) + { + if(!--TimerGame) + { + G_ExitLevel(); + } + } + P_RunThinkers(); + P_UpdateSpecials(); + P_AmbientSound(); + leveltime++; +} |