123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- // 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++;
- }
|