Files
Doom2DosOriginal/P_TICK.C
T

1 line
14 KiB
C++

#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 ; 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,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);
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;
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,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;
// 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 (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 == 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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &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;
}
}
//=============================================================================
/*
=================
=
= 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<MAXPLAYERS ; i++)
if (playeringame[i])
P_PlayerThink (&players[i]);
P_RunThinkers ();
P_UpdateSpecials ();
P_RespawnSpecials ();
leveltime++; // for par times
}