From 68667e5eaa6fd0ba6cc965d286389d8249e68ecb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Jan 2019 01:09:02 +0100 Subject: [PATCH] - moved particle storage into FLevelLocals. - moved parts of the render setup out of the separate render functions. Things like particle and polyobject linking were duplicated several times for rendering different things in different renderers. These things only need to be set up once before the renderer is started so it makes a lot more sense to consolidate them into one place outside the actual rendering code. --- src/d_event.h | 2 + src/d_main.cpp | 47 ++++++---- src/g_game.cpp | 6 +- src/g_level.cpp | 3 + src/g_levellocals.h | 7 ++ src/gl/renderer/gl_renderer.cpp | 3 - src/hwrenderer/scene/hw_bsp.cpp | 8 +- src/hwrenderer/scene/hw_drawinfo.cpp | 1 - src/maploader/polyobjects.cpp | 5 +- src/p_acs.cpp | 2 +- src/p_actionfunctions.cpp | 2 +- src/p_effect.cpp | 117 ++++++++++++------------- src/p_effect.h | 23 +++-- src/p_map.cpp | 2 +- src/p_mobj.cpp | 10 +-- src/p_setup.cpp | 2 +- src/p_tick.cpp | 4 +- src/polyrenderer/poly_renderer.cpp | 4 +- src/polyrenderer/scene/poly_scene.cpp | 5 +- src/scripting/vmthunks_actors.cpp | 4 +- src/swrenderer/scene/r_opaque_pass.cpp | 4 +- src/swrenderer/scene/r_scene.cpp | 6 -- 22 files changed, 139 insertions(+), 128 deletions(-) diff --git a/src/d_event.h b/src/d_event.h index 22988cda5..b751155df 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 65458d7a9..098eb6876 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 677ba8a30..5d8cdde6f 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 a80b8d6ae..b820eb421 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 ca14ee839..b2ade4bd6 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 76e4f9932..00a4f3460 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 7ecbccaf2..011c905c0 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 8856fc9e2..fc1f74f73 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 2bc931d1c..e1b042743 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 6d2e62082..d6285bff8 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 9afe3597e..55bcb4a86 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 1fd04ebc3..3f0bebb7e 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 00689118a..22a9ab823 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 68275cf0b..164c94ade 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 9ec9a6339..9b960d48f 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 7b482b0ad..fb9499a00 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 97e8af6a0..cec6e2b06 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 68cf3560c..a670907bb 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 79d3112b2..12f00fda8 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 02bd00755..01e696918 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)