Revert "Remove arbitrary particle limit of 256, unfortunately this breaks various particle systems including Essence Shockwave and flamethrower particles"

This reverts commit 35482529
This commit is contained in:
Luke Street 2021-02-15 21:54:44 -05:00
parent 5f263b8a4f
commit 732831de9a
4 changed files with 42 additions and 21 deletions

View File

@ -203,7 +203,8 @@ void CMetroidPrimeEssence::DoUserAnimEvent(CStateManager& mgr, const CInt32POINo
} }
case EUserEventType::BeginAction: { case EUserEventType::BeginAction: {
SShockWaveData data(x660_, x698_, 2.f, x664_, x70c_); SShockWaveData data(x660_, x698_, 2.f, x664_, x70c_);
data.SetSpeedIncrease(180.f); // TODO: Need to fix CElementGen accessing null ParticleAccessParameters
// data.SetSpeedIncrease(180.f);
DropShockwave(mgr, data); DropShockwave(mgr, data);
ShakeCamera(mgr, 1.f); ShakeCamera(mgr, 1.f);
return; return;

View File

@ -83,6 +83,7 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
if (CIntElement* mbspElem = desc->x48_x34_MBSP.get()) if (CIntElement* mbspElem = desc->x48_x34_MBSP.get())
mbspElem->GetValue(x74_curFrame, x270_MBSP); mbspElem->GetValue(x74_curFrame, x270_MBSP);
m_maxMBSP = x270_MBSP;
if (CModVectorElement* elem = desc->x7c_x68_VEL1.get()) { if (CModVectorElement* elem = desc->x7c_x68_VEL1.get()) {
x280_VELSources[0] = elem; x280_VELSources[0] = elem;
@ -151,11 +152,13 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
if (CIntElement* maxpElem = desc->x28_x1c_MAXP.get()) { if (CIntElement* maxpElem = desc->x28_x1c_MAXP.get()) {
maxpElem->GetValue(x74_curFrame, x90_MAXP); maxpElem->GetValue(x74_curFrame, x90_MAXP);
m_maxMAXP = maxpElem->GetMaxValue();
} }
x30_particles.reserve(x90_MAXP); m_maxMAXP = std::min(m_maxMAXP, 256);
x30_particles.reserve(m_maxMAXP);
if (x2c_orientType == EModelOrientationType::One) if (x2c_orientType == EModelOrientationType::One)
x50_parentMatrices.resize(x90_MAXP); x50_parentMatrices.resize(m_maxMAXP);
x26c_31_LINE = desc->x44_24_x30_24_LINE; x26c_31_LINE = desc->x44_24_x30_24_LINE;
x26d_24_FXLL = desc->x44_25_x30_25_FXLL; x26d_24_FXLL = desc->x44_25_x30_25_FXLL;
@ -202,14 +205,14 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
boo::ObjToken<boo::ITexture> tex; boo::ObjToken<boo::ITexture> tex;
if (texr) if (texr)
tex = texr->GetValueTexture(0).GetObj()->GetBooTexture(); tex = texr->GetValueTexture(0).GetObj()->GetBooTexture();
int maxVerts = x90_MAXP; int maxVerts = (m_maxMAXP == 0 ? 256 : m_maxMAXP);
m_lineRenderer.reset( m_lineRenderer.reset(
new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2, tex, x26c_26_AAPH, x26c_28_zTest)); new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines, maxVerts * 2, tex, x26c_26_AAPH, x26c_28_zTest));
} else { } else {
m_shaderClass = CElementGenShaders::GetShaderClass(*this); m_shaderClass = CElementGenShaders::GetShaderClass(*this);
} }
size_t maxInsts = x26c_30_MBLR ? (x270_MBSP * x90_MAXP) : x90_MAXP; size_t maxInsts = x26c_30_MBLR ? (m_maxMBSP * m_maxMAXP) : m_maxMAXP;
maxInsts = (maxInsts == 0 ? 256 : maxInsts); maxInsts = (maxInsts == 0 ? 256 : maxInsts);
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
@ -271,6 +274,7 @@ bool CElementGen::InternalUpdate(double dt) {
if (x26c_30_MBLR && dt > 0.0) { if (x26c_30_MBLR && dt > 0.0) {
if (CIntElement* mbspElem = desc->x48_x34_MBSP.get()) if (CIntElement* mbspElem = desc->x48_x34_MBSP.get())
mbspElem->GetValue(x74_curFrame, x270_MBSP); mbspElem->GetValue(x74_curFrame, x270_MBSP);
x270_MBSP = std::min(x270_MBSP, m_maxMBSP);
} }
int frameUpdateCount = 0; int frameUpdateCount = 0;
@ -339,7 +343,12 @@ void CElementGen::AccumulateBounds(const zeus::CVector3f& pos, float size) {
} }
void CElementGen::UpdateAdvanceAccessParameters(u32 activeParticleCount, s32 particleFrame) { void CElementGen::UpdateAdvanceAccessParameters(u32 activeParticleCount, s32 particleFrame) {
CGenDescription* desc = x28_loadedGenDesc; if (activeParticleCount >= x60_advValues.size()) {
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
return;
}
CGenDescription* desc = x1c_genDesc.GetObj();
std::array<float, 8>& arr = x60_advValues[activeParticleCount]; std::array<float, 8>& arr = x60_advValues[activeParticleCount];
CParticleGlobals::instance()->m_particleAccessParameters = &arr; CParticleGlobals::instance()->m_particleAccessParameters = &arr;
@ -395,7 +404,10 @@ void CElementGen::UpdateExistingParticles() {
x25c_activeParticleCount = 0; x25c_activeParticleCount = 0;
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame); CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->m_particleAccessParameters = nullptr; if (x25c_activeParticleCount < x60_advValues.size())
CParticleGlobals::instance()->m_particleAccessParameters = &x60_advValues[x25c_activeParticleCount];
else
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
for (auto it = x30_particles.begin(); it != x30_particles.end();) { for (auto it = x30_particles.begin(); it != x30_particles.end();) {
CParticle& particle = *it; CParticle& particle = *it;
@ -486,14 +498,13 @@ void CElementGen::CreateNewParticles(int count) {
CGlobalRandom gr(x27c_randState); CGlobalRandom gr(x27c_randState);
x30_particles.reserve(x90_MAXP); x30_particles.reserve(x90_MAXP);
if (x26d_28_enableADV && x60_advValues.empty()) if (x26d_28_enableADV && x60_advValues.empty())
x60_advValues.resize(x90_MAXP); x60_advValues.resize(m_maxMAXP);
CParticleGlobals::instance()->m_particleAccessParameters = nullptr; CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
CParticle& particle = x30_particles.emplace_back(); CParticle& particle = x30_particles.emplace_back();
++g_ParticleAliveCount; ++g_ParticleAliveCount;
u32 particleCount = x30_particles.size() - 1;
++x25c_activeParticleCount; ++x25c_activeParticleCount;
++x260_cumulativeParticles; ++x260_cumulativeParticles;
if (x2c_orientType == EModelOrientationType::One) { if (x2c_orientType == EModelOrientationType::One) {
@ -507,16 +518,14 @@ void CElementGen::CreateNewParticles(int count) {
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame); CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(0); CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(0);
g_currentParticle = &particle; g_currentParticle = &particle;
if (x26d_28_enableADV) { if (x26d_28_enableADV)
UpdateAdvanceAccessParameters(particleCount, 0); UpdateAdvanceAccessParameters(x30_particles.size() - 1, 0);
}
particle.x0_endFrame += x74_curFrame; particle.x0_endFrame += x74_curFrame;
if (CColorElement* colr = desc->x30_x24_COLR.get()) { if (CColorElement* colr = desc->x30_x24_COLR.get())
colr->GetValue(0, particle.x34_color); colr->GetValue(0, particle.x34_color);
} else { else
particle.x34_color = zeus::skWhite; particle.x34_color = zeus::skWhite;
}
if (CEmitterElement* emtr = desc->x40_x2c_EMTR.get()) { if (CEmitterElement* emtr = desc->x40_x2c_EMTR.get()) {
emtr->GetValue(x74_curFrame, particle.x4_pos, particle.x1c_vel); emtr->GetValue(x74_curFrame, particle.x4_pos, particle.x1c_vel);
@ -831,13 +840,12 @@ void CElementGen::Render(const CActorLights* actorLights) {
} }
void CElementGen::RenderModels(const CActorLights* actorLights) { void CElementGen::RenderModels(const CActorLights* actorLights) {
CParticleGlobals::instance()->m_particleAccessParameters = nullptr; CGenDescription* desc = x1c_genDesc.GetObj();
if (x26d_26_modelsUseLights) if (x26d_26_modelsUseLights)
CGraphics::SetLightState(x274_backupLightActive); CGraphics::SetLightState(x274_backupLightActive);
CGlobalRandom gr(x27c_randState); CGlobalRandom gr(x27c_randState);
CGenDescription* desc = x1c_genDesc.GetObj();
SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f}; SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f};
CUVElement* texr = desc->x54_x40_TEXR.get(); CUVElement* texr = desc->x54_x40_TEXR.get();
CTexture* cachedTex = nullptr; CTexture* cachedTex = nullptr;
@ -940,10 +948,10 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame); CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
int partFrame = x74_curFrame - particle.x28_startFrame - 1; int partFrame = x74_curFrame - particle.x28_startFrame - 1;
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame); CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame);
if (x26d_28_enableADV) { if (i < x60_advValues.size())
CParticleGlobals::instance()->m_particleAccessParameters = &x60_advValues[i]; CParticleGlobals::instance()->m_particleAccessParameters = &x60_advValues[i];
} else
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
CVectorElement* pmop = desc->x6c_x58_PMOP.get(); CVectorElement* pmop = desc->x6c_x58_PMOP.get();
if (pmop) if (pmop)
pmop->GetValue(partFrame, pmopVec); pmop->GetValue(partFrame, pmopVec);

View File

@ -65,6 +65,7 @@ private:
bool x88_particleEmission = true; bool x88_particleEmission = true;
float x8c_generatorRemainder = 0.f; float x8c_generatorRemainder = 0.f;
int x90_MAXP = 0; int x90_MAXP = 0;
int m_maxMAXP = 256;
u16 x94_randomSeed = g_GlobalSeed; u16 x94_randomSeed = g_GlobalSeed;
float x98_generatorRate = 1.f; float x98_generatorRate = 1.f;
std::array<float, 16> x9c_externalVars{}; std::array<float, 16> x9c_externalVars{};
@ -100,6 +101,7 @@ private:
bool x26d_27_enableOPTS : 1; bool x26d_27_enableOPTS : 1;
bool x26d_28_enableADV : 1 = false; bool x26d_28_enableADV : 1 = false;
int x270_MBSP = 0; int x270_MBSP = 0;
int m_maxMBSP = 0;
ERglLightBits x274_backupLightActive = ERglLightBits::None; ERglLightBits x274_backupLightActive = ERglLightBits::None;
std::array<bool, 4> x278_hasVMD{}; std::array<bool, 4> x278_hasVMD{};
CRandom16 x27c_randState; CRandom16 x27c_randState;
@ -223,6 +225,7 @@ public:
static void SetMoveRedToAlphaBuffer(bool move); static void SetMoveRedToAlphaBuffer(bool move);
s32 GetMaxParticles() const { return x90_MAXP; } s32 GetMaxParticles() const { return x90_MAXP; }
s32 GetMaxMaxParticles() const { return m_maxMAXP; }
std::vector<CParticle> const& GetParticles() const { return x30_particles; } std::vector<CParticle> const& GetParticles() const { return x30_particles; }
std::vector<CParticle> &GetParticles() { return x30_particles; } std::vector<CParticle> &GetParticles() { return x30_particles; }

View File

@ -368,6 +368,15 @@ void CNewFlameThrower::UpdateFx(const zeus::CTransform& xf, float dt, CStateMana
float tmp = std::clamp(unk.magnitude() * 30.f, 1.f, x37c_26_runningSlowish ? 2.f : 4.f); float tmp = std::clamp(unk.magnitude() * 30.f, 1.f, x37c_26_runningSlowish ? 2.f : 4.f);
x3b4_numSmokeParticlesSpawned = std::max(static_cast<int>(round(tmp)), x3b4_numSmokeParticlesSpawned - 1); x3b4_numSmokeParticlesSpawned = std::max(static_cast<int>(round(tmp)), x3b4_numSmokeParticlesSpawned - 1);
// INSERT
if ((x35c_mainSmokeGen->GetParticles().size() + x3b4_numSmokeParticlesSpawned) >
x35c_mainSmokeGen->GetMaxMaxParticles()) {
x3b4_numSmokeParticlesSpawned = x3b4_numSmokeParticlesSpawned -
((x35c_mainSmokeGen->GetParticles().size() + x3b4_numSmokeParticlesSpawned) -
x35c_mainSmokeGen->GetMaxMaxParticles());
}
// END INSERT
// This limit shouldn't be needed, m_maxMAXP should be removed?
x35c_mainSmokeGen->SetTranslation(swoosh_1.xc_translation); x35c_mainSmokeGen->SetTranslation(swoosh_1.xc_translation);
x35c_mainSmokeGen->SetOrientation(swoosh_1.x38_orientation); x35c_mainSmokeGen->SetOrientation(swoosh_1.x38_orientation);