diff --git a/src/d_event.h b/src/d_event.h index 22988cda54..b751155df2 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -25,6 +25,7 @@ #include "basictypes.h" +#include // @@ -119,6 +120,7 @@ typedef enum // Called by IO functions when input is detected. void D_PostEvent (const event_t* ev); void D_RemoveNextCharEvent(); +void D_Render(std::function action, bool interpolate); // diff --git a/src/d_main.cpp b/src/d_main.cpp index 65458d7a9b..098eb68768 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -351,6 +351,35 @@ void D_RemoveNextCharEvent() } } +//========================================================================== +// +// Render wrapper. +// This function contains all the needed setup and cleanup for starting a render job. +// +//========================================================================== + +void D_Render(std::function action, bool interpolate) +{ + for (auto Level : AllLevels()) + { + // Check for the presence of dynamic lights at the start of the frame once. + if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4)) + { + Level->HasDynamicLights = !!level.lights; + } + else Level->HasDynamicLights = false; // lights are off so effectively we have none. + if (interpolate) Level->interpolator.DoInterpolations(I_GetTimeFrac()); + P_FindParticleSubsectors(Level); + PO_LinkToSubsectors(Level); + } + action(); + + if (interpolate) for (auto Level : AllLevels()) + { + Level->interpolator.RestoreInterpolations(); + } +} + //========================================================================== // // CVAR dmflags @@ -746,22 +775,10 @@ void D_Display () //E_RenderFrame(); // - for (auto Level : AllLevels()) + D_Render([&]() { - // Check for the presence of dynamic lights at the start of the frame once. - if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4)) - { - Level->HasDynamicLights = !!level.lights; - } - else Level->HasDynamicLights = false; // lights are off so effectively we have none. - Level->interpolator.DoInterpolations(I_GetTimeFrac()); - } - viewsec = screen->RenderView(&players[consoleplayer]); - - for (auto Level : AllLevels()) - { - Level->interpolator.RestoreInterpolations(); - } + viewsec = screen->RenderView(&players[consoleplayer]); + }, true); screen->Begin2D(); screen->DrawBlend(viewsec); diff --git a/src/g_game.cpp b/src/g_game.cpp index 677ba8a303..5d8cdde6f1 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -72,6 +72,7 @@ #include "vm.h" #include "dobjgc.h" #include "gi.h" +#include "a_dynlight.h" #include "g_hub.h" #include "g_levellocals.h" @@ -2101,7 +2102,10 @@ static void PutSavePic (FileWriter *file, int width, int height) } else { - screen->WriteSavePic(&players[consoleplayer], file, width, height); + D_Render([&]() + { + screen->WriteSavePic(&players[consoleplayer], file, width, height); + }, false); } } diff --git a/src/g_level.cpp b/src/g_level.cpp index a80b8d6aec..b820eb4211 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -80,6 +80,7 @@ #include "i_music.h" #include "a_dynlight.h" #include "p_conversation.h" +#include "p_effect.h" #include "gi.h" @@ -1460,6 +1461,8 @@ int G_FinishTravel () void FLevelLocals::Init() { + P_InitParticles(this); + P_ClearParticles(this); BaseBlendA = 0.0f; // Remove underwater blend effect, if any gravity = sv_gravity * 35/TICRATE; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index ca14ee839d..b2ade4bd63 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -47,6 +47,7 @@ #include "p_tags.h" #include "p_spec.h" #include "actor.h" +#include "p_effect.h" #include "p_destructible.h" #include "r_data/r_sections.h" #include "r_data/r_canvastexture.h" @@ -491,6 +492,12 @@ public: int ActiveSequences; DSeqNode *SequenceListHead; + // [RH] particle globals + uint32_t ActiveParticles; + uint32_t InactiveParticles; + TArray Particles; + TArray ParticlesInSubsec; + TArray Scrolls; // NULL if no DScrollers in this level int8_t WallVertLight; // Light diffs for vert/horiz walls diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 76e4f9932c..00a4f34604 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -245,8 +245,6 @@ sector_t *FGLRenderer::RenderView(player_t* player) if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.; else r_viewpoint.TicFrac = I_GetTimeFrac(); - P_FindParticleSubsectors(); - screen->mLights->Clear(); screen->mViewpoints->Clear(); @@ -358,7 +356,6 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i mBuffers = mSaveBuffers; hw_ClearFakeFlat(); - P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. gl_RenderState.SetVertexBuffer(screen->mVertexData); screen->mVertexData->Reset(); screen->mLights->Clear(); diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 7ecbccaf21..011c905c02 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -554,16 +554,16 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector) void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front) { SetupSprite.Clock(); - for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) + for (int i = Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Level->Particles[i].snext) { if (mClipPortal) { - int clipres = mClipPortal->ClipPoint(Particles[i].Pos); + int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos); if (clipres == PClip_InFront) continue; } GLSprite sprite; - sprite.ProcessParticle(this, &Particles[i], front); + sprite.ProcessParticle(this, &Level->Particles[i], front); } SetupSprite.Unclock(); } @@ -626,7 +626,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) } // [RH] Add particles - if (gl_render_things && ParticlesInSubsec[sub->Index()] != NO_PARTICLE) + if (gl_render_things && Level->ParticlesInSubsec[sub->Index()] != NO_PARTICLE) { if (multithread) { diff --git a/src/hwrenderer/scene/hw_drawinfo.cpp b/src/hwrenderer/scene/hw_drawinfo.cpp index 8856fc9e2d..fc1f74f733 100644 --- a/src/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/hwrenderer/scene/hw_drawinfo.cpp @@ -429,7 +429,6 @@ void HWDrawInfo::CreateScene() // reset the portal manager screen->mPortalState->StartFrame(); - PO_LinkToSubsectors(Level); ProcessAll.Clock(); diff --git a/src/maploader/polyobjects.cpp b/src/maploader/polyobjects.cpp index 2bc931d1c8..e1b0427431 100644 --- a/src/maploader/polyobjects.cpp +++ b/src/maploader/polyobjects.cpp @@ -152,6 +152,7 @@ void MapLoader::SpawnPolyobj (int index, int tag, int type) unsigned int ii; int i; FPolyObj *po = &Level->Polyobjects[index]; + po->Level = Level; for (ii = 0; ii < KnownPolySides.Size(); ++ii) { @@ -351,10 +352,6 @@ void MapLoader::PO_Init (void) InitSideLists (); Level->Polyobjects.Resize(NumPolyobjs); - for (auto p : Level->Polyobjects) - { - p.Level = Level; - } polyIndex = 0; // index polyobj number // Find the startSpot points, and spawn each polyobj diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 6d2e62082f..d6285bff86 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6447,7 +6447,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) size = fabs(size); if (lifetime != 0) - P_SpawnParticle(DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)), + P_SpawnParticle(Level, DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)), DVector3(ACSToDouble(xvel), ACSToDouble(yvel), ACSToDouble(zvel)), DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)), color, startalpha/255., lifetime, size, endsize, fadestep/255., fullbright); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 9afe3597e5..55bcb4a860 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1669,7 +1669,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnParticle) acc.X = accelx * c + accely * s; acc.Y = accelx * s - accely * c; } - P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, startalpha, lifetime, size, fadestep, sizestep, flags); + P_SpawnParticle(self->Level, self->Vec3Offset(pos), vel, acc, color, startalpha, lifetime, size, fadestep, sizestep, flags); } return 0; } diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 1fd04ebc39..3f0bebb7e7 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -59,12 +59,6 @@ FRandom pr_railtrail("RailTrail"); #define FADEFROMTTL(a) (1.f/(a)) -// [RH] particle globals -uint32_t ActiveParticles; -uint32_t InactiveParticles; -TArray Particles; -TArray ParticlesInSubsec; - static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black, red1, green1, blue1, yellow1, purple, purple1, white, rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5, @@ -103,15 +97,15 @@ static const struct ColorList { {NULL, 0, 0, 0 } }; -inline particle_t *NewParticle (void) +inline particle_t *NewParticle (FLevelLocals *Level) { particle_t *result = nullptr; - if (InactiveParticles != NO_PARTICLE) + if (Level->InactiveParticles != NO_PARTICLE) { - result = &Particles[InactiveParticles]; - InactiveParticles = result->tnext; - result->tnext = ActiveParticles; - ActiveParticles = uint32_t(result - Particles.Data()); + result = &Level->Particles[Level->InactiveParticles]; + Level->InactiveParticles = result->tnext; + result->tnext = Level->ActiveParticles; + Level->ActiveParticles = uint32_t(result - Level->Particles.Data()); } return result; } @@ -119,7 +113,7 @@ inline particle_t *NewParticle (void) // // [RH] Particle functions // -void P_InitParticles (); +void P_InitParticles (FLevelLocals *); // [BC] Allow the maximum number of particles to be specified by a cvar (so people // with lots of nice hardware can have lots of particles!). @@ -134,11 +128,14 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE ) if ( gamestate != GS_STARTUP ) { - P_InitParticles( ); + for (auto Level : AllLevels()) + { + P_InitParticles(Level); + } } } -void P_InitParticles () +void P_InitParticles (FLevelLocals *Level) { const char *i; int num; @@ -152,45 +149,45 @@ void P_InitParticles () // This should be good, but eh... int NumParticles = clamp(num, 100, 65535); - Particles.Resize(NumParticles); - P_ClearParticles (); + Level->Particles.Resize(NumParticles); + P_ClearParticles (Level); } -void P_ClearParticles () +void P_ClearParticles (FLevelLocals *Level) { int i = 0; - memset (Particles.Data(), 0, Particles.Size() * sizeof(particle_t)); - ActiveParticles = NO_PARTICLE; - InactiveParticles = 0; - for (auto &p : Particles) + memset (Level->Particles.Data(), 0, Level->Particles.Size() * sizeof(particle_t)); + Level->ActiveParticles = NO_PARTICLE; + Level->InactiveParticles = 0; + for (auto &p : Level->Particles) p.tnext = ++i; - Particles.Last().tnext = NO_PARTICLE; + Level->Particles.Last().tnext = NO_PARTICLE; } // Group particles by subsectors. Because particles are always // in motion, there is little benefit to caching this information // from one frame to the next. -void P_FindParticleSubsectors () +void P_FindParticleSubsectors (FLevelLocals *Level) { - if (ParticlesInSubsec.Size() < level.subsectors.Size()) + if (Level->ParticlesInSubsec.Size() < level.subsectors.Size()) { - ParticlesInSubsec.Reserve (level.subsectors.Size() - ParticlesInSubsec.Size()); + Level->ParticlesInSubsec.Reserve (level.subsectors.Size() - Level->ParticlesInSubsec.Size()); } - fillshort (&ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE); + fillshort (&Level->ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE); if (!r_particles) { return; } - for (uint16_t i = ActiveParticles; i != NO_PARTICLE; i = Particles[i].tnext) + for (uint16_t i = Level->ActiveParticles; i != NO_PARTICLE; i = Level->Particles[i].tnext) { // Try to reuse the subsector from the last portal check, if still valid. - if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(Particles[i].Pos); - int ssnum = Particles[i].subsector->Index(); - Particles[i].snext = ParticlesInSubsec[ssnum]; - ParticlesInSubsec[ssnum] = i; + if (Level->Particles[i].subsector == nullptr) Level->Particles[i].subsector = R_PointInSubsector(Level->Particles[i].Pos); + int ssnum = Level->Particles[i].subsector->Index(); + Level->Particles[i].snext = Level->ParticlesInSubsec[ssnum]; + Level->ParticlesInSubsec[ssnum] = i; } } @@ -220,7 +217,6 @@ void P_InitEffects () { const struct ColorList *color = Colors; - P_InitParticles(); while (color->color) { *(color->color) = ParticleColor(color->r, color->g, color->b); @@ -232,16 +228,16 @@ void P_InitEffects () blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3); } -void P_ThinkParticles () +void P_ThinkParticles (FLevelLocals *Level) { int i; particle_t *particle, *prev; - i = ActiveParticles; + i = Level->ActiveParticles; prev = NULL; while (i != NO_PARTICLE) { - particle = &Particles[i]; + particle = &Level->Particles[i]; i = particle->tnext; if (!particle->notimefreeze && level.isFrozen()) { @@ -258,9 +254,9 @@ void P_ThinkParticles () if (prev) prev->tnext = i; else - ActiveParticles = i; - particle->tnext = InactiveParticles; - InactiveParticles = (int)(particle - Particles.Data()); + Level->ActiveParticles = i; + particle->tnext = Level->InactiveParticles; + Level->InactiveParticles = (int)(particle - Level->Particles.Data()); continue; } @@ -299,10 +295,10 @@ enum PSFlag PS_NOTIMEFREEZE = 1 << 5, }; -void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, +void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags) { - particle_t *particle = NewParticle(); + particle_t *particle = NewParticle(Level); if (particle) { @@ -326,7 +322,7 @@ void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &a // // Run effects on all actors in the world // -void P_RunEffects () +void P_RunEffects (FLevelLocals *Level) { if (players[consoleplayer].camera == NULL) return; @@ -339,10 +335,7 @@ void P_RunEffects () { if (actor->effects || actor->fountaincolor) { - // Only run the effect if the actor is potentially visible - int rnum = pnum + actor->Sector->Index(); - if (level.rejectmatrix.Size() == 0 || !(level.rejectmatrix[rnum>>3] & (1 << (rnum & 7)))) - P_RunEffect (actor, actor->effects); + P_RunEffect (actor, actor->effects); } } } @@ -352,14 +345,14 @@ void P_RunEffects () // // Creates a particle with "jitter" // -particle_t *JitterParticle (int ttl) +particle_t *JitterParticle (FLevelLocals *Level, int ttl) { - return JitterParticle (ttl, 1.0); + return JitterParticle (Level, ttl, 1.0); } // [XA] Added "drift speed" multiplier setting for enhanced railgun stuffs. -particle_t *JitterParticle (int ttl, double drift) +particle_t *JitterParticle (FLevelLocals *Level, int ttl, double drift) { - particle_t *particle = NewParticle (); + particle_t *particle = NewParticle (Level); if (particle) { int i; @@ -385,7 +378,7 @@ static void MakeFountain (AActor *actor, int color1, int color2) if (!(level.time & 1)) return; - particle = JitterParticle (51); + particle = JitterParticle (actor->Level, 51); if (particle) { @@ -425,7 +418,7 @@ void P_RunEffect (AActor *actor, int effects) DAngle an = moveangle + 90.; double speed; - particle = JitterParticle (3 + (M_Random() & 31)); + particle = JitterParticle (actor->Level, 3 + (M_Random() & 31)); if (particle) { double pathdist = M_Random() / 256.; DVector3 pos = actor->Vec3Offset( @@ -442,7 +435,7 @@ void P_RunEffect (AActor *actor, int effects) particle->size = 2; } for (i = 6; i; i--) { - particle_t *particle = JitterParticle (3 + (M_Random() & 31)); + particle_t *particle = JitterParticle (actor->Level, 3 + (M_Random() & 31)); if (particle) { double pathdist = M_Random() / 256.; DVector3 pos = actor->Vec3Offset( @@ -471,7 +464,7 @@ void P_RunEffect (AActor *actor, int effects) DVector3 pos = actor->Vec3Angle(-actor->radius * 2, moveangle, -actor->Height * actor->Vel.Z / 8 + actor->Height * (2. / 3)); - P_DrawSplash2 (6, pos, moveangle + 180, 2, 2); + P_DrawSplash2 (actor->Level, 6, pos, moveangle + 180, 2, 2); } if (actor->fountaincolor) { @@ -498,7 +491,7 @@ void P_RunEffect (AActor *actor, int effects) for (i = 3; i > 0; i--) { - particle = JitterParticle (16); + particle = JitterParticle (actor->Level, 16); if (particle != NULL) { DAngle ang = M_Random() * (360 / 256.); @@ -519,7 +512,7 @@ void P_RunEffect (AActor *actor, int effects) } } -void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind) +void P_DrawSplash (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int kind) { int color1, color2; @@ -535,7 +528,7 @@ void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind) for (; count; count--) { - particle_t *p = JitterParticle (10); + particle_t *p = JitterParticle (Level, 10); if (!p) break; @@ -553,7 +546,7 @@ void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind) } } -void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind) +void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int updown, int kind) { int color1, color2, zadd; double zvel, zspread; @@ -584,7 +577,7 @@ void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, in for (; count; count--) { - particle_t *p = NewParticle (); + particle_t *p = NewParticle (Level); DAngle an; if (!p) @@ -724,7 +717,7 @@ void P_DrawRailTrail(AActor *source, TArray &portalhits, int color1, deg = (double)SpiralOffset; for (i = spiral_steps; i; i--) { - particle_t *p = NewParticle (); + particle_t *p = NewParticle (source->Level); DVector3 tempvec; if (!p) @@ -795,7 +788,7 @@ void P_DrawRailTrail(AActor *source, TArray &portalhits, int color1, { // [XA] inner trail uses a different default duration (33). int innerduration = (duration == 0) ? 33 : duration; - particle_t *p = JitterParticle (innerduration, (float)drift); + particle_t *p = JitterParticle (source->Level, innerduration, (float)drift); if (!p) return; @@ -915,7 +908,7 @@ void P_DisconnectEffect (AActor *actor) for (i = 64; i; i--) { - particle_t *p = JitterParticle (TICRATE*2); + particle_t *p = JitterParticle (actor->Level, TICRATE*2); if (!p) break; diff --git a/src/p_effect.h b/src/p_effect.h index 00689118ac..22a9ab8236 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -41,6 +41,7 @@ #define FX_VISIBILITYPULSE 0x00000040 struct subsector_t; +struct FLevelLocals; // [RH] Particle details @@ -62,24 +63,22 @@ struct particle_t uint16_t snext; }; -extern TArray Particles; -extern TArray ParticlesInSubsec; - const uint16_t NO_PARTICLE = 0xffff; -void P_ClearParticles (); -void P_FindParticleSubsectors (); +void P_InitParticles(FLevelLocals *); +void P_ClearParticles (FLevelLocals *Level); +void P_FindParticleSubsectors (FLevelLocals *Level); class AActor; -particle_t *JitterParticle (int ttl); -particle_t *JitterParticle (int ttl, double drift); +particle_t *JitterParticle (FLevelLocals *Level, int ttl); +particle_t *JitterParticle (FLevelLocals *Level, int ttl, double drift); -void P_ThinkParticles (void); -void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags = 0); +void P_ThinkParticles (FLevelLocals *Level); +void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags = 0); void P_InitEffects (void); -void P_RunEffects (void); +void P_RunEffects (FLevelLocals *Level); void P_RunEffect (AActor *actor, int effects); @@ -91,6 +90,6 @@ struct SPortalHit }; void P_DrawRailTrail(AActor *source, TArray &portalhits, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, DAngle angle = 0., int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270, DAngle pitch = 0.); -void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind); -void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind); +void P_DrawSplash (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int kind); +void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int updown, int kind); void P_DisconnectEffect (AActor *actor); diff --git a/src/p_map.cpp b/src/p_map.cpp index 68275cf0bc..164c94ade4 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6203,7 +6203,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos) DAngle an = (M_Random() - 128) * (360./256); if (cl_bloodtype >= 1) { - P_DrawSplash2(32, thing->PosPlusZ(thing->Height/2), an, 2, thing->BloodColor); + P_DrawSplash2(thing->Level, 32, thing->PosPlusZ(thing->Height/2), an, 2, thing->BloodColor); } } if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 9ec9a6339d..9b960d48ff 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5619,7 +5619,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1 { if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) { - P_DrawSplash2 (32, pos, particledir, updown, 1); + P_DrawSplash2 (source->Level, 32, pos, particledir, updown, 1); if (cl_pufftype == 1) puff->renderflags |= RF_INVISIBLE; } @@ -5743,7 +5743,7 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina } if (bloodtype >= 1) - P_DrawSplash2 (40, pos, dir, 2, originator->BloodColor); + P_DrawSplash2 (originator->Level, 40, pos, dir, 2, originator->BloodColor); } DEFINE_ACTION_FUNCTION(AActor, SpawnBlood) @@ -5794,7 +5794,7 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle) } if (bloodtype >= 1) { - P_DrawSplash2 (40, pos, hitangle-180., 2, originator->BloodColor); + P_DrawSplash2 (originator->Level, 40, pos, hitangle-180., 2, originator->BloodColor); } } @@ -5835,7 +5835,7 @@ void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle) } if (bloodtype >= 1) { - P_DrawSplash2(40, pos + add, hitangle - 180., 2, originator->BloodColor); + P_DrawSplash2(originator->Level, 40, pos + add, hitangle - 180., 2, originator->BloodColor); } } @@ -5895,7 +5895,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) } if (bloodtype >= 1) { - P_DrawSplash2(28, pos, bleeder->AngleTo(mo) + 180., 0, bleeder->BloodColor); + P_DrawSplash2(bleeder->Level, 28, pos, bleeder->AngleTo(mo) + 180., 0, bleeder->BloodColor); } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 7b482b0adb..fb9499a000 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -509,7 +509,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) R_OldBlend = 0xffffffff; // [RH] Remove all particles - P_ClearParticles(); + P_ClearParticles(Level); // preload graphics and sounds if (precache) diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 97e8af6a00..cec6e2b062 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -135,12 +135,12 @@ void P_Ticker (void) { ac->ClearInterpolation(); } + P_ThinkParticles(Level); // [RH] make the particles think } // Since things will be moving, it's okay to interpolate them in the renderer. r_NoInterpolate = false; - P_ThinkParticles(); // [RH] make the particles think for (i = 0; isector; + auto Level = frontsector->Level; frontsector->MoreFlags |= SECMF_DRAWN; if (sub->polys) @@ -187,9 +188,9 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub } int subsectorIndex = sub->Index(); - for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext) + for (int i = Level->ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Level->Particles[i].snext) { - particle_t *particle = &Particles[i]; + particle_t *particle = &Level->Particles[i]; thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue)); } } diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index 68cf3560c7..a670907bb1 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -1256,7 +1256,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetReplacee, ZS_GetReplacee) static void DrawSplash(AActor *self, int count, double angle, int kind) { - P_DrawSplash(count, self->Pos(), angle, kind); + P_DrawSplash(self->Level, count, self->Pos(), angle, kind); } DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash) @@ -1265,7 +1265,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash) PARAM_INT(count); PARAM_FLOAT(angle); PARAM_INT(kind); - P_DrawSplash(count, self->Pos(), angle, kind); + P_DrawSplash(self->Level, count, self->Pos(), angle, kind); return 0; } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 79d3112b2f..12f00fda8d 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -615,9 +615,9 @@ namespace swrenderer if ((unsigned int)(sub->Index()) < Level->subsectors.Size()) { // Only do it for the main BSP. int lightlevel = (floorlightlevel + ceilinglightlevel) / 2; - for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) + for (int i = frontsector->Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = frontsector->Level->Particles[i].snext) { - RenderParticle::Project(Thread, &Particles[i], sub->sector, lightlevel, FakeSide, foggy); + RenderParticle::Project(Thread, &frontsector->Level->Particles[i], sub->sector, lightlevel, FakeSide, foggy); } } diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 02bd007555..01e696918c 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -159,12 +159,6 @@ namespace swrenderer this->dontmaplines = dontmaplines; - // [RH] Setup particles for this frame - P_FindParticleSubsectors(); - - // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function - PO_LinkToSubsectors(&level); - R_UpdateFuzzPosFrameStart(); if (r_modelscene)