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

View file

@ -45,6 +45,7 @@
#include "po_man.h"
#include "p_acs.h"
#include "p_tags.h"
#include "p_effect.h"
#include "p_destructible.h"
#include "r_data/r_interpolate.h"
#include "r_data/r_sections.h"
@ -228,6 +229,12 @@ struct FLevelLocals : public FLevelData
int ActiveSequences;
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
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.;
else r_viewpoint.TicFrac = I_GetTimeFrac();
P_FindParticleSubsectors();
auto Level = player->camera->Level;
ForAllLevels(P_FindParticleSubsectors);
screen->mLights->Clear();
screen->mViewpoints->Clear();
@ -255,7 +256,6 @@ sector_t *FGLRenderer::RenderView(player_t* player)
bool saved_niv = NoInterpolateView;
NoInterpolateView = false;
// prepare all camera textures that have been used in the last frame
auto Level = player->camera->Level;
gl_RenderState.CheckTimer(Level->ShaderStartTime);
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;
hw_ClearFakeFlat();
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
ForAllLevels(P_FindParticleSubsectors);
gl_RenderState.SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset();
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)
{
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)
{

View file

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

View file

@ -6485,7 +6485,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);

View file

@ -1656,7 +1656,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;
}

View file

@ -59,12 +59,6 @@ FRandom pr_railtrail("RailTrail");
#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,
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,11 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
if ( gamestate != GS_STARTUP )
{
P_InitParticles( );
ForAllLevels(P_InitParticles);
}
}
void P_InitParticles ()
void P_InitParticles (FLevelLocals *Level)
{
const char *i;
int num;
@ -152,45 +146,45 @@ void P_InitParticles ()
// This should be good, but eh...
int NumParticles = clamp<int>(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(&level, Particles[i].Pos);
int ssnum = Particles[i].subsector->Index();
Particles[i].snext = ParticlesInSubsec[ssnum];
ParticlesInSubsec[ssnum] = i;
if (Level->Particles[i].subsector == NULL) Level->Particles[i].subsector = R_PointInSubsector(&level, Level->Particles[i].Pos);
int ssnum = Level->Particles[i].subsector->Index();
Level->Particles[i].snext = Level->ParticlesInSubsec[ssnum];
Level->ParticlesInSubsec[ssnum] = i;
}
}
@ -220,7 +214,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 +225,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.freeze) || (level.flags2 & LEVEL2_FROZEN)))
{
@ -258,9 +251,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 +292,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 +319,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 +332,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 +342,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 +375,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 +415,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 +432,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 +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));
P_DrawSplash2 (6, pos, moveangle + 180, 2, 2);
P_DrawSplash2 (actor->Level, 6, pos, moveangle + 180, 2, 2);
}
if (actor->fountaincolor)
{
@ -498,7 +488,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 +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;
@ -535,7 +525,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 +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;
double zvel, zspread;
@ -584,7 +574,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 +714,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &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 +785,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &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 +905,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;

View file

@ -62,24 +62,22 @@ struct particle_t
uint16_t snext;
};
extern TArray<particle_t> Particles;
extern TArray<uint16_t> 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 +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_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);

View file

@ -6208,7 +6208,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))

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))
{
P_DrawSplash2 (32, pos, particledir, updown, 1);
P_DrawSplash2 (source->Level, 32, pos, particledir, updown, 1);
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)
P_DrawSplash2 (40, pos, dir, 2, originator->BloodColor);
P_DrawSplash2 (originator->Level, 40, pos, dir, 2, originator->BloodColor);
}
DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
@ -5814,7 +5814,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);
}
}
@ -5855,7 +5855,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);
}
}
@ -5915,7 +5915,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);
}
}

View file

@ -508,7 +508,7 @@ void P_SetupLevel(FLevelLocals *Level, const char *lumpname, int position, bool
R_OldBlend = 0xffffffff;
// [RH] Remove all particles
P_ClearParticles();
P_ClearParticles(Level);
// preload graphics and sounds
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.
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++)
@ -155,7 +155,7 @@ void P_Ticker (void)
if (!Level->freeze && !(Level->flags2 & LEVEL2_FROZEN))
{
P_UpdateSpecials(Level);
P_RunEffects(); // [RH] Run particle effects
P_RunEffects(Level); // [RH] Run particle effects
}
// for par times

View file

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

View file

@ -146,6 +146,7 @@ void RenderPolyScene::RenderSectors()
void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth)
{
sector_t *frontsector = sub->sector;
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<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)
{
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;
}

View file

@ -616,9 +616,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);
}
}

View file

@ -160,10 +160,10 @@ namespace swrenderer
this->dontmaplines = dontmaplines;
// [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
PO_LinkToSubsectors(&level);
ForAllLevels(PO_LinkToSubsectors);
R_UpdateFuzzPosFrameStart();