- moved particle storage to FLevelLocals.

This commit is contained in:
Christoph Oelckers 2019-01-10 01:21:17 +01:00
parent 2aa9c065ac
commit 8cc563b80f
18 changed files with 102 additions and 103 deletions

View file

@ -80,6 +80,7 @@
#include "i_music.h" #include "i_music.h"
#include "a_dynlight.h" #include "a_dynlight.h"
#include "p_conversation.h" #include "p_conversation.h"
#include "p_effect.h"
#include "gi.h" #include "gi.h"
@ -1469,6 +1470,8 @@ int G_FinishTravel ()
void FLevelLocals::InitLevelLocals () void FLevelLocals::InitLevelLocals ()
{ {
P_InitParticles(this);
P_ClearParticles(this);
BaseBlendA = 0.0f; // Remove underwater blend effect, if any BaseBlendA = 0.0f; // Remove underwater blend effect, if any
gravity = sv_gravity * 35/TICRATE; gravity = sv_gravity * 35/TICRATE;

View file

@ -45,6 +45,7 @@
#include "po_man.h" #include "po_man.h"
#include "p_acs.h" #include "p_acs.h"
#include "p_tags.h" #include "p_tags.h"
#include "p_effect.h"
#include "p_destructible.h" #include "p_destructible.h"
#include "r_data/r_interpolate.h" #include "r_data/r_interpolate.h"
#include "r_data/r_sections.h" #include "r_data/r_sections.h"
@ -228,6 +229,12 @@ struct FLevelLocals : public FLevelData
int ActiveSequences; int ActiveSequences;
DSeqNode *SequenceListHead; DSeqNode *SequenceListHead;
// [RH] particle globals
uint32_t ActiveParticles;
uint32_t InactiveParticles;
TArray<particle_t> Particles;
TArray<uint16_t> ParticlesInSubsec;
TArray<DVector2> Scrolls; // NULL if no DScrollers in this level TArray<DVector2> Scrolls; // NULL if no DScrollers in this level
int8_t WallVertLight; // Light diffs for vert/horiz walls int8_t WallVertLight; // Light diffs for vert/horiz walls

View file

@ -246,7 +246,8 @@ sector_t *FGLRenderer::RenderView(player_t* player)
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.; if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
else r_viewpoint.TicFrac = I_GetTimeFrac(); else r_viewpoint.TicFrac = I_GetTimeFrac();
P_FindParticleSubsectors(); auto Level = player->camera->Level;
ForAllLevels(P_FindParticleSubsectors);
screen->mLights->Clear(); screen->mLights->Clear();
screen->mViewpoints->Clear(); screen->mViewpoints->Clear();
@ -255,7 +256,6 @@ sector_t *FGLRenderer::RenderView(player_t* player)
bool saved_niv = NoInterpolateView; bool saved_niv = NoInterpolateView;
NoInterpolateView = false; NoInterpolateView = false;
// prepare all camera textures that have been used in the last frame // prepare all camera textures that have been used in the last frame
auto Level = player->camera->Level;
gl_RenderState.CheckTimer(Level->ShaderStartTime); gl_RenderState.CheckTimer(Level->ShaderStartTime);
Level->canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov) Level->canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov)
{ {
@ -354,7 +354,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
mBuffers = mSaveBuffers; mBuffers = mSaveBuffers;
hw_ClearFakeFlat(); hw_ClearFakeFlat();
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. ForAllLevels(P_FindParticleSubsectors);
gl_RenderState.SetVertexBuffer(screen->mVertexData); gl_RenderState.SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset(); screen->mVertexData->Reset();
screen->mLights->Clear(); screen->mLights->Clear();

View file

@ -554,16 +554,16 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front) void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front)
{ {
SetupSprite.Clock(); 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) if (mClipPortal)
{ {
int clipres = mClipPortal->ClipPoint(Particles[i].Pos); int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos);
if (clipres == PClip_InFront) continue; if (clipres == PClip_InFront) continue;
} }
GLSprite sprite; GLSprite sprite;
sprite.ProcessParticle(this, &Particles[i], front); sprite.ProcessParticle(this, &Level->Particles[i], front);
} }
SetupSprite.Unclock(); SetupSprite.Unclock();
} }
@ -626,7 +626,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
} }
// [RH] Add particles // [RH] Add particles
if (gl_render_things && ParticlesInSubsec[sub->Index()] != NO_PARTICLE) if (gl_render_things &&Level->ParticlesInSubsec[sub->Index()] != NO_PARTICLE)
{ {
if (multithread) if (multithread)
{ {

View file

@ -424,7 +424,7 @@ void HWDrawInfo::CreateScene()
// reset the portal manager // reset the portal manager
screen->mPortalState->StartFrame(); screen->mPortalState->StartFrame();
PO_LinkToSubsectors(Level); ForAllLevels(PO_LinkToSubsectors);
ProcessAll.Clock(); ProcessAll.Clock();

View file

@ -6485,7 +6485,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
size = fabs(size); size = fabs(size);
if (lifetime != 0) 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(xvel), ACSToDouble(yvel), ACSToDouble(zvel)),
DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)), DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)),
color, startalpha/255., lifetime, size, endsize, fadestep/255., fullbright); color, startalpha/255., lifetime, size, endsize, fadestep/255., fullbright);

View file

@ -1656,7 +1656,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnParticle)
acc.X = accelx * c + accely * s; acc.X = accelx * c + accely * s;
acc.Y = accelx * s - accely * c; 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; return 0;
} }

View file

@ -59,12 +59,6 @@ FRandom pr_railtrail("RailTrail");
#define FADEFROMTTL(a) (1.f/(a)) #define FADEFROMTTL(a) (1.f/(a))
// [RH] particle globals
uint32_t ActiveParticles;
uint32_t InactiveParticles;
TArray<particle_t> Particles;
TArray<uint16_t> ParticlesInSubsec;
static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black, static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black,
red1, green1, blue1, yellow1, purple, purple1, white, red1, green1, blue1, yellow1, purple, purple1, white,
rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5, rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5,
@ -103,15 +97,15 @@ static const struct ColorList {
{NULL, 0, 0, 0 } {NULL, 0, 0, 0 }
}; };
inline particle_t *NewParticle (void) inline particle_t *NewParticle (FLevelLocals *Level)
{ {
particle_t *result = nullptr; particle_t *result = nullptr;
if (InactiveParticles != NO_PARTICLE) if (Level->InactiveParticles != NO_PARTICLE)
{ {
result = &Particles[InactiveParticles]; result = &Level->Particles[Level->InactiveParticles];
InactiveParticles = result->tnext; Level->InactiveParticles = result->tnext;
result->tnext = ActiveParticles; result->tnext = Level->ActiveParticles;
ActiveParticles = uint32_t(result - Particles.Data()); Level->ActiveParticles = uint32_t(result - Level->Particles.Data());
} }
return result; return result;
} }
@ -119,7 +113,7 @@ inline particle_t *NewParticle (void)
// //
// [RH] Particle functions // [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 // [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!). // with lots of nice hardware can have lots of particles!).
@ -134,11 +128,11 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
if ( gamestate != GS_STARTUP ) if ( gamestate != GS_STARTUP )
{ {
P_InitParticles( ); ForAllLevels(P_InitParticles);
} }
} }
void P_InitParticles () void P_InitParticles (FLevelLocals *Level)
{ {
const char *i; const char *i;
int num; int num;
@ -152,45 +146,45 @@ void P_InitParticles ()
// This should be good, but eh... // This should be good, but eh...
int NumParticles = clamp<int>(num, 100, 65535); int NumParticles = clamp<int>(num, 100, 65535);
Particles.Resize(NumParticles); Level->Particles.Resize(NumParticles);
P_ClearParticles (); P_ClearParticles (Level);
} }
void P_ClearParticles () void P_ClearParticles (FLevelLocals *Level)
{ {
int i = 0; int i = 0;
memset (Particles.Data(), 0, Particles.Size() * sizeof(particle_t)); memset (Level->Particles.Data(), 0, Level->Particles.Size() * sizeof(particle_t));
ActiveParticles = NO_PARTICLE; Level->ActiveParticles = NO_PARTICLE;
InactiveParticles = 0; Level->InactiveParticles = 0;
for (auto &p : Particles) for (auto &p : Level->Particles)
p.tnext = ++i; p.tnext = ++i;
Particles.Last().tnext = NO_PARTICLE; Level->Particles.Last().tnext = NO_PARTICLE;
} }
// Group particles by subsectors. Because particles are always // Group particles by subsectors. Because particles are always
// in motion, there is little benefit to caching this information // in motion, there is little benefit to caching this information
// from one frame to the next. // 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) if (!r_particles)
{ {
return; 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. // Try to reuse the subsector from the last portal check, if still valid.
if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(&level, Particles[i].Pos); if (Level->Particles[i].subsector == NULL) Level->Particles[i].subsector = R_PointInSubsector(&level, Level->Particles[i].Pos);
int ssnum = Particles[i].subsector->Index(); int ssnum = Level->Particles[i].subsector->Index();
Particles[i].snext = ParticlesInSubsec[ssnum]; Level->Particles[i].snext = Level->ParticlesInSubsec[ssnum];
ParticlesInSubsec[ssnum] = i; Level->ParticlesInSubsec[ssnum] = i;
} }
} }
@ -220,7 +214,6 @@ void P_InitEffects ()
{ {
const struct ColorList *color = Colors; const struct ColorList *color = Colors;
P_InitParticles();
while (color->color) while (color->color)
{ {
*(color->color) = ParticleColor(color->r, color->g, color->b); *(color->color) = ParticleColor(color->r, color->g, color->b);
@ -232,16 +225,16 @@ void P_InitEffects ()
blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3); blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
} }
void P_ThinkParticles () void P_ThinkParticles (FLevelLocals *Level)
{ {
int i; int i;
particle_t *particle, *prev; particle_t *particle, *prev;
i = ActiveParticles; i = Level->ActiveParticles;
prev = NULL; prev = NULL;
while (i != NO_PARTICLE) while (i != NO_PARTICLE)
{ {
particle = &Particles[i]; particle = &Level->Particles[i];
i = particle->tnext; i = particle->tnext;
if (!particle->notimefreeze && ((level.freeze) || (level.flags2 & LEVEL2_FROZEN))) if (!particle->notimefreeze && ((level.freeze) || (level.flags2 & LEVEL2_FROZEN)))
{ {
@ -258,9 +251,9 @@ void P_ThinkParticles ()
if (prev) if (prev)
prev->tnext = i; prev->tnext = i;
else else
ActiveParticles = i; Level->ActiveParticles = i;
particle->tnext = InactiveParticles; particle->tnext = Level->InactiveParticles;
InactiveParticles = (int)(particle - Particles.Data()); Level->InactiveParticles = (int)(particle - Level->Particles.Data());
continue; continue;
} }
@ -299,10 +292,10 @@ enum PSFlag
PS_NOTIMEFREEZE = 1 << 5, 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) double fadestep, double sizestep, int flags)
{ {
particle_t *particle = NewParticle(); particle_t *particle = NewParticle(Level);
if (particle) if (particle)
{ {
@ -326,7 +319,7 @@ void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &a
// //
// Run effects on all actors in the world // Run effects on all actors in the world
// //
void P_RunEffects () void P_RunEffects (FLevelLocals *Level)
{ {
if (players[consoleplayer].camera == NULL) return; if (players[consoleplayer].camera == NULL) return;
@ -339,10 +332,7 @@ void P_RunEffects ()
{ {
if (actor->effects || actor->fountaincolor) if (actor->effects || actor->fountaincolor)
{ {
// Only run the effect if the actor is potentially visible P_RunEffect (actor, actor->effects);
int rnum = pnum + actor->Sector->Index();
if (level.rejectmatrix.Size() == 0 || !(level.rejectmatrix[rnum>>3] & (1 << (rnum & 7))))
P_RunEffect (actor, actor->effects);
} }
} }
} }
@ -352,14 +342,14 @@ void P_RunEffects ()
// //
// Creates a particle with "jitter" // 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. // [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) { if (particle) {
int i; int i;
@ -385,7 +375,7 @@ static void MakeFountain (AActor *actor, int color1, int color2)
if (!(level.time & 1)) if (!(level.time & 1))
return; return;
particle = JitterParticle (51); particle = JitterParticle (actor->Level, 51);
if (particle) if (particle)
{ {
@ -425,7 +415,7 @@ void P_RunEffect (AActor *actor, int effects)
DAngle an = moveangle + 90.; DAngle an = moveangle + 90.;
double speed; double speed;
particle = JitterParticle (3 + (M_Random() & 31)); particle = JitterParticle (actor->Level, 3 + (M_Random() & 31));
if (particle) { if (particle) {
double pathdist = M_Random() / 256.; double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset( DVector3 pos = actor->Vec3Offset(
@ -442,7 +432,7 @@ void P_RunEffect (AActor *actor, int effects)
particle->size = 2; particle->size = 2;
} }
for (i = 6; i; i--) { 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) { if (particle) {
double pathdist = M_Random() / 256.; double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset( DVector3 pos = actor->Vec3Offset(
@ -471,7 +461,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)); 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) if (actor->fountaincolor)
{ {
@ -498,7 +488,7 @@ void P_RunEffect (AActor *actor, int effects)
for (i = 3; i > 0; i--) for (i = 3; i > 0; i--)
{ {
particle = JitterParticle (16); particle = JitterParticle (actor->Level, 16);
if (particle != NULL) if (particle != NULL)
{ {
DAngle ang = M_Random() * (360 / 256.); DAngle ang = M_Random() * (360 / 256.);
@ -519,7 +509,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; int color1, color2;
@ -535,7 +525,7 @@ void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind)
for (; count; count--) for (; count; count--)
{ {
particle_t *p = JitterParticle (10); particle_t *p = JitterParticle (Level, 10);
if (!p) if (!p)
break; break;
@ -553,7 +543,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; int color1, color2, zadd;
double zvel, zspread; double zvel, zspread;
@ -584,7 +574,7 @@ void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, in
for (; count; count--) for (; count; count--)
{ {
particle_t *p = NewParticle (); particle_t *p = NewParticle (Level);
DAngle an; DAngle an;
if (!p) if (!p)
@ -724,7 +714,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
deg = (double)SpiralOffset; deg = (double)SpiralOffset;
for (i = spiral_steps; i; i--) for (i = spiral_steps; i; i--)
{ {
particle_t *p = NewParticle (); particle_t *p = NewParticle (source->Level);
DVector3 tempvec; DVector3 tempvec;
if (!p) if (!p)
@ -795,7 +785,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
{ {
// [XA] inner trail uses a different default duration (33). // [XA] inner trail uses a different default duration (33).
int innerduration = (duration == 0) ? 33 : duration; int innerduration = (duration == 0) ? 33 : duration;
particle_t *p = JitterParticle (innerduration, (float)drift); particle_t *p = JitterParticle (source->Level, innerduration, (float)drift);
if (!p) if (!p)
return; return;
@ -915,7 +905,7 @@ void P_DisconnectEffect (AActor *actor)
for (i = 64; i; i--) for (i = 64; i; i--)
{ {
particle_t *p = JitterParticle (TICRATE*2); particle_t *p = JitterParticle (actor->Level, TICRATE*2);
if (!p) if (!p)
break; break;

View file

@ -62,24 +62,22 @@ struct particle_t
uint16_t snext; uint16_t snext;
}; };
extern TArray<particle_t> Particles;
extern TArray<uint16_t> ParticlesInSubsec;
const uint16_t NO_PARTICLE = 0xffff; const uint16_t NO_PARTICLE = 0xffff;
void P_ClearParticles (); void P_InitParticles(FLevelLocals *);
void P_FindParticleSubsectors (); void P_ClearParticles (FLevelLocals *Level);
void P_FindParticleSubsectors (FLevelLocals *Level);
class AActor; class AActor;
particle_t *JitterParticle (int ttl); particle_t *JitterParticle (FLevelLocals *Level, int ttl);
particle_t *JitterParticle (int ttl, double drift); particle_t *JitterParticle (FLevelLocals *Level, int ttl, double drift);
void P_ThinkParticles (void); void P_ThinkParticles (FLevelLocals *Level);
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_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_InitEffects (void);
void P_RunEffects (void); void P_RunEffects (FLevelLocals *Level);
void P_RunEffect (AActor *actor, int effects); void P_RunEffect (AActor *actor, int effects);
@ -91,6 +89,6 @@ struct SPortalHit
}; };
void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &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_DrawRailTrail(AActor *source, TArray<SPortalHit> &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_DrawSplash (FLevelLocals *Level, 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);
void P_DisconnectEffect (AActor *actor); void P_DisconnectEffect (AActor *actor);

View file

@ -6208,7 +6208,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
DAngle an = (M_Random() - 128) * (360./256); DAngle an = (M_Random() - 128) * (360./256);
if (cl_bloodtype >= 1) 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)) if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound))

View file

@ -5639,7 +5639,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1
{ {
if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) 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; if (cl_pufftype == 1) puff->renderflags |= RF_INVISIBLE;
} }
@ -5763,7 +5763,7 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
} }
if (bloodtype >= 1) 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) DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
@ -5814,7 +5814,7 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2 (40, pos, hitangle-180., 2, originator->BloodColor); P_DrawSplash2 (originator->Level, 40, pos, hitangle-180., 2, originator->BloodColor);
} }
} }
@ -5855,7 +5855,7 @@ void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle)
} }
if (bloodtype >= 1) 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);
} }
} }
@ -5915,7 +5915,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
} }
if (bloodtype >= 1) 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);
} }
} }

View file

@ -508,7 +508,7 @@ void P_SetupLevel(FLevelLocals *Level, const char *lumpname, int position, bool
R_OldBlend = 0xffffffff; R_OldBlend = 0xffffffff;
// [RH] Remove all particles // [RH] Remove all particles
P_ClearParticles(); P_ClearParticles(Level);
// preload graphics and sounds // preload graphics and sounds
if (precache) if (precache)

View file

@ -128,7 +128,7 @@ void P_Ticker (void)
// Since things will be moving, it's okay to interpolate them in the renderer. // Since things will be moving, it's okay to interpolate them in the renderer.
r_NoInterpolate = false; r_NoInterpolate = false;
P_ThinkParticles(); // [RH] make the particles think P_ThinkParticles(Level); // [RH] make the particles think
}); });
for (int i = 0; i < MAXPLAYERS; i++) for (int i = 0; i < MAXPLAYERS; i++)
@ -155,7 +155,7 @@ void P_Ticker (void)
if (!Level->freeze && !(Level->flags2 & LEVEL2_FROZEN)) if (!Level->freeze && !(Level->flags2 & LEVEL2_FROZEN))
{ {
P_UpdateSpecials(Level); P_UpdateSpecials(Level);
P_RunEffects(); // [RH] Run particle effects P_RunEffects(Level); // [RH] Run particle effects
} }
// for par times // for par times

View file

@ -135,8 +135,8 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
Level = actor->Level; Level = actor->Level;
R_SetupFrame(Viewpoint, Viewwindow, actor); R_SetupFrame(Viewpoint, Viewwindow, actor);
P_FindParticleSubsectors(); ForAllLevels(P_FindParticleSubsectors);
PO_LinkToSubsectors(&level); ForAllLevels(PO_LinkToSubsectors);
static bool firstcall = true; static bool firstcall = true;
if (firstcall) if (firstcall)

View file

@ -146,6 +146,7 @@ void RenderPolyScene::RenderSectors()
void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth) void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth)
{ {
sector_t *frontsector = sub->sector; sector_t *frontsector = sub->sector;
auto Level = frontsector->Level;
frontsector->MoreFlags |= SECMF_DRAWN; frontsector->MoreFlags |= SECMF_DRAWN;
if (sub->polys) if (sub->polys)
@ -187,9 +188,9 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub
} }
int subsectorIndex = sub->Index(); 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<PolyTranslucentParticle>(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue)); thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucentParticle>(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue));
} }
} }

View file

@ -1256,7 +1256,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetReplacee, ZS_GetReplacee)
static void DrawSplash(AActor *self, int count, double angle, int kind) 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) DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash)
@ -1265,7 +1265,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash)
PARAM_INT(count); PARAM_INT(count);
PARAM_FLOAT(angle); PARAM_FLOAT(angle);
PARAM_INT(kind); PARAM_INT(kind);
P_DrawSplash(count, self->Pos(), angle, kind); P_DrawSplash(self->Level, count, self->Pos(), angle, kind);
return 0; return 0;
} }

View file

@ -616,9 +616,9 @@ namespace swrenderer
if ((unsigned int)(sub->Index()) < Level->subsectors.Size()) if ((unsigned int)(sub->Index()) < Level->subsectors.Size())
{ // Only do it for the main BSP. { // Only do it for the main BSP.
int lightlevel = (floorlightlevel + ceilinglightlevel) / 2; 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);
} }
} }

View file

@ -160,10 +160,10 @@ namespace swrenderer
this->dontmaplines = dontmaplines; this->dontmaplines = dontmaplines;
// [RH] Setup particles for this frame // [RH] Setup particles for this frame
P_FindParticleSubsectors(); ForAllLevels(P_FindParticleSubsectors);
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors(&level); ForAllLevels(PO_LinkToSubsectors);
R_UpdateFuzzPosFrameStart(); R_UpdateFuzzPosFrameStart();