diff --git a/src/d_main.c b/src/d_main.c index 93b3eef77d..0b5f945dea 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -706,7 +706,7 @@ void D_DoomMain(void) } else { - sprintf (file,"%s.lmp", myargv[p + 1]); + sprintf(file,"%s.lmp", myargv[p + 1]); } if (D_AddFile(file)) diff --git a/src/g_game.c b/src/g_game.c index 7dd06ad890..77e5a9ba40 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1591,6 +1591,9 @@ void G_DoLoadGame(void) leveltime = savedleveltime; + bloodSplatQueueSlot = 0; + memset(bloodSplatQueue, 0, sizeof(mobj_t *) * BLOODSPLATQUEUESIZE); + // dearchive all the modifications P_UnArchivePlayers(); P_UnArchiveWorld(); @@ -2126,7 +2129,7 @@ void G_DoPlayDemo(void) int demoversion; gameaction = ga_nothing; - demobuffer = demo_p = (byte *)W_CacheLumpName (defdemoname, PU_STATIC); + demobuffer = demo_p = (byte *)W_CacheLumpName(defdemoname, PU_STATIC); demoversion = *demo_p++; diff --git a/src/info.c b/src/info.c index b034b94b30..6c2ee6f169 100644 --- a/src/info.c +++ b/src/info.c @@ -51,7 +51,7 @@ char *sprnames[] = { "POL3", "POL1", "POL6", "GOR2", "GOR3", "GOR4", "GOR5", "SMIT", "COL1", "COL2", "COL3", "COL4", "CAND", "CBRA", "COL6", "TRE1", "TRE2", "ELEC", "CEYE", "FSKU", "COL5", "TBLU", "TGRN", "TRED", "SMBT", "SMGT", "SMRT", "HDB1", "HDB2", "HDB3", - "HDB4", "HDB5", "HDB6", "POB1", "POB2", "BRS1", "TLMP", "TLP2", "BLD2", NULL // [BH] "BLD2" + "HDB4", "HDB5", "HDB6", "POB1", "POB2", "BRS1", "TLMP", "TLP2", "BLD2", NULL }; diff --git a/src/p_local.h b/src/p_local.h index f264a106f2..eafb913cb7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -102,13 +102,17 @@ void P_PlayerThink(player_t *player); #define ONCEILINGZ INT_MAX // Time interval for item respawning. -#define ITEMQUESIZE 128 +#define ITEMQUEUESIZE 128 -extern mapthing_t itemrespawnque[ITEMQUESIZE]; -extern int itemrespawntime[ITEMQUESIZE]; -extern int iquehead; -extern int iquetail; +extern mapthing_t itemrespawnqueue[ITEMQUEUESIZE]; +extern int itemrespawntime[ITEMQUEUESIZE]; +extern int iqueuehead; +extern int iqueuetail; +#define BLOODSPLATQUEUESIZE 512 + +extern mobj_t *bloodSplatQueue[BLOODSPLATQUEUESIZE]; +extern int bloodSplatQueueSlot; void P_RespawnSpecials(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index a66cdc4f03..1304376893 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -45,6 +45,10 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. void G_PlayerReborn(int player); +mobj_t *bloodSplatQueue[BLOODSPLATQUEUESIZE]; +int bloodSplatQueueSlot; + + // // P_SetMobjState // Returns true if the mobj is still present. @@ -585,10 +589,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // // P_RemoveMobj // -mapthing_t itemrespawnque[ITEMQUESIZE]; -int itemrespawntime[ITEMQUESIZE]; -int iquehead; -int iquetail; +mapthing_t itemrespawnqueue[ITEMQUEUESIZE]; +int itemrespawntime[ITEMQUEUESIZE]; +int iqueuehead; +int iqueuetail; void P_RemoveMobj(mobj_t *mobj) { @@ -597,17 +601,17 @@ void P_RemoveMobj(mobj_t *mobj) && (mobj->type != MT_INV) && (mobj->type != MT_INS)) { - itemrespawnque[iquehead] = mobj->spawnpoint; - itemrespawntime[iquehead] = leveltime; - iquehead = (iquehead + 1) & (ITEMQUESIZE - 1); + itemrespawnqueue[iqueuehead] = mobj->spawnpoint; + itemrespawntime[iqueuehead] = leveltime; + iqueuehead = (iqueuehead + 1) & (ITEMQUEUESIZE - 1); // lose one off the end? - if (iquehead == iquetail) - iquetail = (iquetail + 1) & (ITEMQUESIZE - 1); + if (iqueuehead == iqueuetail) + iqueuetail = (iqueuetail + 1) & (ITEMQUEUESIZE - 1); } if (mobj->type == MT_BLOOD) - P_SpawnBloodSplat(mobj->x, mobj->y, mobj->flags2); + P_SpawnBloodSplat(mobj->x, mobj->y, (mobjflag2_t)mobj->flags2); // unlink from sector and block lists P_UnsetThingPosition(mobj); @@ -654,14 +658,14 @@ void P_RespawnSpecials(void) return; // nothing left to respawn? - if (iquehead == iquetail) + if (iqueuehead == iqueuetail) return; // wait at least 30 seconds - if (leveltime - itemrespawntime[iquetail] < 30 * TICRATE) + if (leveltime - itemrespawntime[iqueuetail] < 30 * TICRATE) return; - mthing = &itemrespawnque[iquetail]; + mthing = &itemrespawnqueue[iqueuetail]; x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; @@ -690,7 +694,7 @@ void P_RespawnSpecials(void) mo->angle = ANG45 * (mthing->angle / 45); // pull it from the queue - iquetail = (iquetail + 1) & (ITEMQUESIZE - 1); + iqueuetail = (iqueuetail + 1) & (ITEMQUEUESIZE - 1); } @@ -955,14 +959,25 @@ void P_SpawnBlood(fixed_t x, fixed_t y, fixed_t z, angle_t angle, int damage, mo // -// P_SpawnBlood +// P_SpawnBloodSplat // void P_SpawnBloodSplat(fixed_t x, fixed_t y, mobjflag2_t flag) { - mobj_t *th = P_SpawnMobj(x, y, ONFLOORZ, MT_BLOODSPLAT); + mobj_t *newmobj = P_SpawnMobj(x, y, ONFLOORZ, MT_BLOODSPLAT); + + newmobj->flags2 |= flag; + P_SetMobjState(newmobj, (statenum_t)(S_BLOODSPLAT + M_RandomInt(0, 7))); - th->flags2 |= flag; - P_SetMobjState(th, (statenum_t)(S_BLOODSPLAT + M_RandomInt(0, 7))); + if (bloodSplatQueueSlot >= BLOODSPLATQUEUESIZE) + { + // Too many blood splats - remove an old one + mobj_t *old = bloodSplatQueue[bloodSplatQueueSlot % BLOODSPLATQUEUESIZE]; + + if (old) + P_RemoveMobj(old); + } + bloodSplatQueue[bloodSplatQueueSlot % BLOODSPLATQUEUESIZE] = newmobj; + bloodSplatQueueSlot++; } diff --git a/src/p_setup.c b/src/p_setup.c index c5ffe89e2b..b4141ac37f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1031,6 +1031,8 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill) bodyqueslot = 0; deathmatch_p = deathmatchstarts; + bloodSplatQueueSlot = 0; + memset(bloodSplatQueue, 0, sizeof(mobj_t *) * BLOODSPLATQUEUESIZE); P_LoadThings(lumpnum + ML_THINGS); // if deathmatch, randomly spawn the active players @@ -1046,7 +1048,7 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill) } // clear special respawning queue - iquehead = iquetail = 0; + iqueuehead = iqueuetail = 0; // set up world state P_SpawnSpecials(); diff --git a/src/r_things.c b/src/r_things.c index b22da07ae7..08819e2de0 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -42,6 +42,7 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. #include "doomstat.h" #include "v_video.h" +#include "p_local.h" @@ -307,7 +308,15 @@ vissprite_t overflowsprite; vissprite_t *R_NewVisSprite(void) { if (vissprite_p == &vissprites[MAXVISSPRITES]) - return &overflowsprite; + { + // Try to remove an old blood splat + mobj_t *old = bloodSplatQueue[bloodSplatQueueSlot % BLOODSPLATQUEUESIZE]; + + if (old) + P_RemoveMobj(old); + else + I_Error("R_NewVisSprite: MAXVISSPRITES reached"); + } vissprite_p++; return vissprite_p - 1; diff --git a/src/r_things.h b/src/r_things.h index ae0a1f1e99..51ba07029d 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -31,7 +31,7 @@ along with DOOM RETRO. If not, see http://www.gnu.org/licenses/. -#define MAXVISSPRITES 1024 +#define MAXVISSPRITES 2048 extern vissprite_t vissprites[MAXVISSPRITES]; extern vissprite_t *vissprite_p;