summaryrefslogtreecommitdiff
path: root/src/heretic/p_tick.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heretic/p_tick.c')
-rw-r--r--src/heretic/p_tick.c643
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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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++;
+}