Move CParticleGlobals from the executable and onto the heap, minor fixes, update wiki link

This commit is contained in:
Phillip Stephens 2019-12-03 00:47:05 -08:00
parent 697a100bca
commit 34e78a2dd0
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
29 changed files with 162 additions and 161 deletions

View File

@ -708,7 +708,7 @@ ROOT_SHADER_GROUPS = (
)
# UV animation nodes:
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime)#UV_Animations
# https://wiki.axiodl.com/w/Materials_(Metroid_Prime)#UV_Animations
# 0 - Modelview Inverse (zero translation)
def make_uva0():
@ -1179,7 +1179,7 @@ UV_ANIMATION_GROUPS = (
)
# MP3 / DKCR Material Passes:
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime_3)
# https://wiki.axiodl.com/w/Materials_(Metroid_Prime_3)
# Lightmap
def make_pass_diff():

View File

@ -704,9 +704,10 @@ constexpr uint8_t Convert4To8(uint8_t v) {
return (v << 4) | v;
}
void SpecBase::extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& noAramPath) {
hecl::ProjectPath entropyPath(noAramPath, _SYS_STR("RandomStaticEntropy.png"));
hecl::ProjectPath catalogPath(noAramPath, _SYS_STR("!catalog.yaml"));
void SpecBase::extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath) {
hecl::ProjectPath entropyPath(pakPath, _SYS_STR("RandomStaticEntropy.png"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
entropyPath.makeDirChain(false);
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), fmt("RandomStaticEntropy: {}\n"), entropyPath.getRelativePathUTF8());

View File

@ -142,7 +142,7 @@ struct SpecBase : hecl::Database::IDataSpec {
hecl::Database::Project& getProject() const { return m_project; }
/* Extract RandomStatic entropy */
void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& noAramPath);
void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath);
/* Tag cache functions */
urde::SObjectTag tagFromPath(const hecl::ProjectPath& path) const;

View File

@ -63,7 +63,14 @@ extern hecl::Database::DataSpecEntry SpecEntMP1PC;
extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
struct TextureCache {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project) {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project, const hecl::ProjectPath& pakPath) {
hecl::ProjectPath texturePath(pakPath, _SYS_STR("texture_cache.yaml"));
hecl::ProjectPath catalogPath(pakPath, _SYS_STR("!catalog.yaml"));
if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), _SYS_STR("a"))) {
fmt::print(fp.get(), fmt("TextureCache: {}\n"), texturePath.getRelativePathUTF8());
}
Log.report(logvisor::Level::Info, fmt("Gathering Texture metadata (this can take up to 10 seconds)..."));
std::unordered_map<UniqueID32, TXTR::Meta> metaMap;
@ -82,9 +89,7 @@ struct TextureCache {
pair.second.write(yamlW);
}
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP1/!texture_cache.yaml");
path.makeDirChain(false);
athena::io::FileWriter fileW(path.getAbsolutePath());
athena::io::FileWriter fileW(texturePath.getAbsolutePath());
yamlW.finish(&fileW);
Log.report(logvisor::Level::Info, fmt("Done..."));
}
@ -367,11 +372,11 @@ struct SpecMP1 : SpecBase {
process.waitUntilComplete();
/* Extract part of .dol for RandomStatic entropy */
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP1/NoARAM"));
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP1/URDE"));
extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath);
/* Generate Texture Cache containing meta data for every texture file */
TextureCache::Generate(m_pakRouter, m_project);
TextureCache::Generate(m_pakRouter, m_project, noAramPath);
return true;
}

View File

@ -87,6 +87,7 @@ float CBodyController::GetAnimTimeRemaining() const {
}
void CBodyController::SetPlaybackRate(float r) { x0_actor.GetModelData()->GetAnimationData()->SetPlaybackRate(r); }
// GX uses a HW approximation of 3/8 + 5/8 instead of 1/3 + 2/3.
const CPASDatabase& CBodyController::GetPASDatabase() const {
return x0_actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase();

View File

@ -306,7 +306,7 @@ void CParticleDatabase::SetParticleEffectState(std::string_view name, bool activ
void CParticleDatabase::SetCEXTValue(std::string_view name, int idx, float value) {
if (CParticleGenInfo* info = GetParticleEffect(name)) {
static_cast<CElementGen*>(static_cast<CParticleGenInfoGeneric*>(info)->GetParticleSystem().get())
->SetCEXTValue(idx, value);
->SetExternalVar(idx, value);
}
}

View File

@ -5,7 +5,7 @@
#include "zeus/Math.hpp"
#include "CGenDescription.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Color_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Color_Elements */
namespace urde {
@ -25,7 +25,7 @@ CCEKeyframeEmitter::CCEKeyframeEmitter(CInputStream& in) {
bool CCEKeyframeEmitter::GetValue(int frame, zeus::CColor& valOut) const {
if (!x4_percent) {
int emitterTime = CParticleGlobals::g_EmitterTime;
int emitterTime = CParticleGlobals::instance()->m_EmitterTime;
int calcKey = emitterTime;
if (xc_loop) {
if (emitterTime >= x10_loopEnd) {
@ -41,8 +41,8 @@ bool CCEKeyframeEmitter::GetValue(int frame, zeus::CColor& valOut) const {
}
valOut = x18_keys[calcKey];
} else {
int ltPerc = CParticleGlobals::g_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::g_ParticleLifetimePercentageRemainder;
int ltPerc = CParticleGlobals::instance()->m_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::instance()->m_ParticleLifetimePercentageRemainder;
if (ltPerc == 100)
valOut = x18_keys[100];
else

View File

@ -6,7 +6,7 @@
#include "Runtime/GCNTypes.hpp"
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Color_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Color_Elements */
namespace urde {

View File

@ -239,22 +239,22 @@ void CDecal::Render() const {
return;
CGraphics::DisableAllLights();
CParticleGlobals::SetEmitterTime(x58_frameIdx);
CParticleGlobals::instance()->SetEmitterTime(x58_frameIdx);
const CDecalDescription& desc = *x0_description;
if (desc.x0_Quads[0].x14_TEX && !x5c_31_quad1Invalid) {
CParticleGlobals::SetParticleLifetime(x3c_decalQuads[0].x4_lifetime);
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
CParticleGlobals::instance()->SetParticleLifetime(x3c_decalQuads[0].x4_lifetime);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(x58_frameIdx);
RenderQuad(const_cast<CQuadDecal&>(x3c_decalQuads[0]), desc.x0_Quads[0]);
}
if (desc.x0_Quads[1].x14_TEX && !x5c_30_quad2Invalid) {
CParticleGlobals::SetParticleLifetime(x3c_decalQuads[1].x4_lifetime);
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
CParticleGlobals::instance()->SetParticleLifetime(x3c_decalQuads[1].x4_lifetime);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(x58_frameIdx);
RenderQuad(const_cast<CQuadDecal&>(x3c_decalQuads[1]), desc.x0_Quads[1]);
}
if (desc.x38_DMDL && !x5c_29_modelInvalid) {
CParticleGlobals::SetParticleLifetime(x54_modelLifetime);
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
CParticleGlobals::instance()->SetParticleLifetime(x54_modelLifetime);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(x58_frameIdx);
RenderMdl();
}
}

View File

@ -229,9 +229,9 @@ CElementGen::~CElementGen() {
}
bool CElementGen::Update(double t) {
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem;
CGenDescription* desc = x1c_genDesc.GetObj();
CIntElement* pswtElem = desc->x10_x4_PSWT.get();
if (pswtElem && !x26d_25_warmedUp) {
@ -242,7 +242,7 @@ bool CElementGen::Update(double t) {
x26d_25_warmedUp = true;
}
bool ret = InternalUpdate(t);
CParticleGlobals::g_currentParticleSystem = prevSystem;
CParticleGlobals::instance()->m_currentParticleSystem = prevSystem;
return ret;
}
@ -254,7 +254,7 @@ bool CElementGen::InternalUpdate(double dt) {
if (std::fabs(dt - 1.0 / 60.0) >= 1.0 / 60000.0)
dt1 = dt;
double t = x74_curFrame / 60.0;
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
if (CRealElement* pstsElem = desc->x14_x8_PSTS.get()) {
float psts;
@ -276,9 +276,9 @@ bool CElementGen::InternalUpdate(double dt) {
x2d4_aabbMin.splat(FLT_MAX);
x2e0_aabbMax.splat(-FLT_MAX);
x2ec_maxSize = 0.f;
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
UpdateExistingParticles();
CParticleGlobals::SetParticleLifetime(x268_PSLT);
CParticleGlobals::instance()->SetParticleLifetime(x268_PSLT);
if (x74_curFrame < x268_PSLT && x88_particleEmission) {
float grte = 0.f;
@ -338,14 +338,14 @@ void CElementGen::AccumulateBounds(const zeus::CVector3f& pos, float size) {
void CElementGen::UpdateAdvanceAccessParameters(u32 activeParticleCount, u32 particleFrame) {
if (activeParticleCount >= x60_advValues.size()) {
CParticleGlobals::g_particleAccessParameters = nullptr;
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
return;
}
CGenDescription* desc = x1c_genDesc.GetObj();
std::array<float, 8>& arr = x60_advValues[activeParticleCount];
CParticleGlobals::g_particleAccessParameters = &arr;
CParticleGlobals::instance()->m_particleAccessParameters = &arr;
if (CRealElement* adv1 = desc->x10c_ADV1.get())
adv1->GetValue(particleFrame, arr[0]);
@ -389,11 +389,11 @@ void CElementGen::UpdateExistingParticles() {
CGenDescription* desc = x1c_genDesc.GetObj();
x25c_activeParticleCount = 0;
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
if (x25c_activeParticleCount < x60_advValues.size())
CParticleGlobals::g_particleAccessParameters = &x60_advValues[x25c_activeParticleCount];
CParticleGlobals::instance()->m_particleAccessParameters = &x60_advValues[x25c_activeParticleCount];
else
CParticleGlobals::g_particleAccessParameters = nullptr;
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
for (auto it = x30_particles.begin(); it != x30_particles.end();) {
CParticle& particle = *it;
@ -423,9 +423,9 @@ void CElementGen::UpdateExistingParticles() {
g_currentParticle = &particle;
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
int particleFrame = x74_curFrame - particle.x28_startFrame;
CParticleGlobals::UpdateParticleLifetimeTweenValues(particleFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(particleFrame);
if (x26d_28_enableADV)
UpdateAdvanceAccessParameters(x25c_activeParticleCount, particleFrame);
@ -484,7 +484,7 @@ void CElementGen::CreateNewParticles(int count) {
if (x26d_28_enableADV && x60_advValues.empty())
x60_advValues.resize(m_maxMAXP);
CParticleGlobals::g_particleAccessParameters = nullptr;
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
for (int i = 0; i < count; ++i) {
x30_particles.emplace_back();
@ -498,8 +498,8 @@ void CElementGen::CreateNewParticles(int count) {
particle.x28_startFrame = x74_curFrame;
if (CIntElement* ltme = desc->x34_x28_LTME.get())
ltme->GetValue(0, particle.x0_endFrame);
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame);
CParticleGlobals::UpdateParticleLifetimeTweenValues(0);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(0);
g_currentParticle = &particle;
if (x26d_28_enableADV)
UpdateAdvanceAccessParameters(x30_particles.size() - 1, 0);
@ -744,12 +744,12 @@ void CElementGen::EndLifetime() {
}
void CElementGen::ForceParticleCreation(int amount) {
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem;
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
CreateNewParticles(amount);
CParticleGlobals::g_currentParticleSystem = prevSystem;
CParticleGlobals::instance()->m_currentParticleSystem = prevSystem;
}
void CElementGen::BuildParticleSystemBounds() {
@ -803,9 +803,9 @@ void CElementGen::Render(const CActorLights* actorLights) {
for (std::unique_ptr<CParticleGen>& child : x290_activePartChildren)
child->Render(actorLights);
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem;
if (x30_particles.size()) {
SParticleModel& pmdl = desc->x5c_x48_PMDL;
@ -818,7 +818,7 @@ void CElementGen::Render(const CActorLights* actorLights) {
RenderParticles();
}
CParticleGlobals::g_currentParticleSystem = prevSystem;
CParticleGlobals::instance()->m_currentParticleSystem = prevSystem;
}
void CElementGen::RenderModels(const CActorLights* actorLights) {
@ -913,7 +913,7 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
}
rot = orient * rot;
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
zeus::CColor col = {1.f, 1.f, 1.f, 1.f};
zeus::CVector3f pmopVec;
@ -927,13 +927,13 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
++matrixIt;
continue;
}
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
int partFrame = x74_curFrame - particle.x28_startFrame - 1;
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame);
if (i < x60_advValues.size())
CParticleGlobals::g_particleAccessParameters = &x60_advValues[i];
CParticleGlobals::instance()->m_particleAccessParameters = &x60_advValues[i];
else
CParticleGlobals::g_particleAccessParameters = nullptr;
CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
CVectorElement* pmop = desc->x6c_x58_PMOP.get();
if (pmop)
pmop->GetValue(partFrame, pmopVec);
@ -1251,7 +1251,7 @@ void CElementGen::RenderParticles() {
int mbspVal = std::max(1, x270_MBSP);
CParticleGlobals::SetEmitterTime(x74_curFrame);
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
if (!x26c_30_MBLR) {
#if 0
if (!desc->x44_28_x30_28_SORT && constUVs && !x26c_29_ORNT)
@ -1310,8 +1310,8 @@ void CElementGen::RenderParticles() {
((particle.x4_pos - particle.x10_prevPos) * x80_timeDeltaScale + particle.x10_prevPos);
if (!constUVs) {
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame);
texr->GetValueUV(partFrame, uvs);
}
@ -1422,8 +1422,8 @@ void CElementGen::RenderParticles() {
}
if (!constUVs) {
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame);
texr->GetValueUV(partFrame, uvs);
}
@ -1497,8 +1497,8 @@ void CElementGen::RenderParticles() {
int partFrame = x74_curFrame - particle.x28_startFrame - 1;
if (!constUVs) {
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
CParticleGlobals::instance()->SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(partFrame);
texr->GetValueUV(partFrame, uvs);
}
@ -1669,7 +1669,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
CParticle& particle = x30_particles[partIdx];
g_currentParticle = &particle;
int partFrame = x74_curFrame - particle.x28_startFrame;
int thisPartFrame = x74_curFrame - particle.x28_startFrame;
zeus::CVector3f viewPoint;
if (desc->x44_28_x30_28_SORT)
viewPoint = sortItems[i].x4_viewPoint;
@ -1678,7 +1678,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) * x80_timeDeltaScale + particle.x10_prevPos);
if (!constTexr) {
CTexture* tex = texr->GetValueTexture(partFrame).GetObj();
CTexture* tex = texr->GetValueTexture(thisPartFrame).GetObj();
if (tex != cachedTex) {
tex->Load(0, CTexture::EClampMode::One);
cachedTex = tex;
@ -1686,7 +1686,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
}
if (!constIndTexr) {
CTexture* tex = tind->GetValueTexture(partFrame).GetObj();
CTexture* tex = tind->GetValueTexture(thisPartFrame).GetObj();
if (tex != cachedIndTex) {
tex->Load(2, CTexture::EClampMode::One);
cachedIndTex = tex;
@ -1694,10 +1694,10 @@ void CElementGen::RenderParticlesIndirectTexture() {
}
if (!constUVs)
texr->GetValueUV(partFrame, uvs);
texr->GetValueUV(thisPartFrame, uvs);
if (!constIndUVs)
tind->GetValueUV(partFrame, uvsInd);
tind->GetValueUV(thisPartFrame, uvsInd);
float size = 0.5f * particle.x2c_lineLengthOrSize;
zeus::CVector3f p1 = {viewPoint.x() - size, viewPoint.y(), viewPoint.z() - size};

View File

@ -187,7 +187,7 @@ public:
void EndLifetime();
void ForceParticleCreation(int amount);
float GetExternalVar(int i) const { return x9c_externalVars[i]; }
void SetCEXTValue(int i, float v) { x9c_externalVars[i] = v; }
void SetExternalVar(int i, float v) { x9c_externalVars[i] = v; }
bool InternalUpdate(double);
void RenderModels(const CActorLights* actLights);

View File

@ -1,7 +1,7 @@
#include "CEmitterElement.hpp"
#include "CRandom16.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Emitter_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Emitter_Elements */
namespace urde {

View File

@ -3,7 +3,7 @@
#include <memory>
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Emitter_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Emitter_Elements */
namespace urde {

View File

@ -12,7 +12,7 @@
#include "Runtime/Particle/CUVElement.hpp"
#include "Runtime/Particle/CVectorElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/PART_(File_Format) */
/* Documentation at: https://wiki.axiodl.com/w/PART_(File_Format) */
namespace urde {

View File

@ -7,7 +7,7 @@
#include "Runtime/Particle/CGenDescription.hpp"
#include "Runtime/Particle/CParticleGlobals.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Int_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Int_Elements */
namespace urde {
@ -27,7 +27,7 @@ CIEKeyframeEmitter::CIEKeyframeEmitter(CInputStream& in) {
bool CIEKeyframeEmitter::GetValue(int frame, int& valOut) const {
if (!x4_percent) {
int emitterTime = CParticleGlobals::g_EmitterTime;
int emitterTime = CParticleGlobals::instance()->m_EmitterTime;
int calcKey = emitterTime;
if (xc_loop) {
if (emitterTime >= x10_loopEnd) {
@ -43,8 +43,8 @@ bool CIEKeyframeEmitter::GetValue(int frame, int& valOut) const {
}
valOut = x18_keys[calcKey];
} else {
int ltPerc = CParticleGlobals::g_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::g_ParticleLifetimePercentageRemainder;
int ltPerc = CParticleGlobals::instance()->m_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::instance()->m_ParticleLifetimePercentageRemainder;
if (ltPerc == 100)
valOut = x18_keys[100];
else
@ -131,7 +131,7 @@ bool CIELifetimePercent::GetValue(int frame, int& valOut) const {
int a;
x4_percentVal->GetValue(frame, a);
a = std::max(0, a);
valOut = (a / 100.0f) * CParticleGlobals::g_ParticleLifetimeReal + 0.5f;
valOut = (a / 100.0f) * CParticleGlobals::instance()->m_ParticleLifetimeReal + 0.5f;
return false;
}
@ -228,21 +228,21 @@ bool CIETimeScale::GetValue(int frame, int& valOut) const {
int CIETimeScale::GetMaxValue() const { return 10000; /* Assume 10000 frames max (not ideal estimate) */ }
bool CIEGetCumulativeParticleCount::GetValue(int frame, int& valOut) const {
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetCumulativeParticleCount();
valOut = CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetCumulativeParticleCount();
return false;
}
int CIEGetCumulativeParticleCount::GetMaxValue() const { return 256; }
bool CIEGetActiveParticleCount::GetValue(int frame, int& valOut) const {
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetParticleCount();
valOut = CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetParticleCount();
return false;
}
int CIEGetActiveParticleCount::GetMaxValue() const { return 256; }
bool CIEGetEmitterTime::GetValue(int frame, int& valOut) const {
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetEmitterTime();
valOut = CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetEmitterTime();
return false;
}

View File

@ -5,7 +5,7 @@
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Int_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Int_Elements */
namespace urde {

View File

@ -3,7 +3,7 @@
#include "CRandom16.hpp"
#include "zeus/Math.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Mod_Vector_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Mod_Vector_Elements */
namespace urde {

View File

@ -3,7 +3,7 @@
#include <memory>
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Mod_Vector_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Mod_Vector_Elements */
namespace urde {

View File

@ -163,9 +163,9 @@ void CParticleElectric::UpdateElectricalEffects() {
continue;
}
CParticleGlobals::SetParticleLifetime(elec.xc_endFrame - elec.x8_startFrame);
CParticleGlobals::instance()->SetParticleLifetime(elec.xc_endFrame - elec.x8_startFrame);
int frame = x28_currentFrame - elec.x8_startFrame;
CParticleGlobals::UpdateParticleLifetimeTweenValues(frame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(frame);
if (x450_27_haveSSWH) {
CParticleSwoosh& swoosh = *x1e0_swooshGenerators[elec.x0_idx];
@ -333,9 +333,9 @@ void CParticleElectric::CreateNewParticles(int count) {
x3e8_electricManagers.push_back(CParticleElectricManager(allocIdx, lifetime, x28_currentFrame));
CParticleElectricManager& elec = x3e8_electricManagers.back();
CParticleGlobals::SetParticleLifetime(elec.xc_endFrame - elec.x8_startFrame);
CParticleGlobals::instance()->SetParticleLifetime(elec.xc_endFrame - elec.x8_startFrame);
int frame = x28_currentFrame - elec.x8_startFrame;
CParticleGlobals::UpdateParticleLifetimeTweenValues(frame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(frame);
CalculatePoints();
if (x450_27_haveSSWH) {
@ -515,7 +515,7 @@ bool CParticleElectric::Update(double dt) {
}
while (evalTime < x30_curTime) {
CParticleGlobals::SetEmitterTime(x28_currentFrame);
CParticleGlobals::instance()->SetEmitterTime(x28_currentFrame);
UpdateElectricalEffects();
if (emitting)
AddElectricalEffects();

View File

@ -1,17 +1,5 @@
#include "CParticleGlobals.hpp"
namespace urde {
int CParticleGlobals::g_EmitterTime = 0;
float CParticleGlobals::g_EmitterTimeReal = 0.0;
int CParticleGlobals::g_ParticleLifetime = 0;
float CParticleGlobals::g_ParticleLifetimeReal = 0.0;
int CParticleGlobals::g_ParticleLifetimePercentage = 0;
float CParticleGlobals::g_ParticleLifetimePercentageReal = 0.0;
float CParticleGlobals::g_ParticleLifetimePercentageRemainder = 0.0;
const std::array<float, 8>* CParticleGlobals::g_particleAccessParameters = nullptr;
CParticleGlobals::SParticleSystem* CParticleGlobals::g_currentParticleSystem = nullptr;
std::unique_ptr<CParticleGlobals> CParticleGlobals::g_ParticleGlobals;
} // namespace urde

View File

@ -13,40 +13,49 @@
namespace urde {
class CElementGen;
class CParticleGlobals {
CParticleGlobals()=default;
static std::unique_ptr<CParticleGlobals> g_ParticleGlobals;
public:
static int g_EmitterTime;
static float g_EmitterTimeReal;
static void SetEmitterTime(int frame) {
g_EmitterTime = frame;
g_EmitterTimeReal = frame;
int m_EmitterTime = 0;
float m_EmitterTimeReal = 0.f;
void SetEmitterTime(int frame) {
m_EmitterTime = frame;
m_EmitterTimeReal = frame;
}
static int g_ParticleLifetime;
static float g_ParticleLifetimeReal;
static void SetParticleLifetime(int frame) {
g_ParticleLifetime = frame;
g_ParticleLifetimeReal = frame;
int m_ParticleLifetime = 0;
float m_ParticleLifetimeReal = 0.f;
void SetParticleLifetime(int frame) {
m_ParticleLifetime = frame;
m_ParticleLifetimeReal = frame;
}
static int g_ParticleLifetimePercentage;
static float g_ParticleLifetimePercentageReal;
static float g_ParticleLifetimePercentageRemainder;
static void UpdateParticleLifetimeTweenValues(int frame) {
float lt = g_ParticleLifetime != 0.0f ? g_ParticleLifetime : 1.0f;
g_ParticleLifetimePercentageReal = 100.0f * frame / lt;
g_ParticleLifetimePercentage = int(g_ParticleLifetimePercentageReal);
g_ParticleLifetimePercentageRemainder = g_ParticleLifetimePercentageReal - g_ParticleLifetimePercentage;
g_ParticleLifetimePercentage = zeus::clamp(0, g_ParticleLifetimePercentage, 100);
int m_ParticleLifetimePercentage = 0;
float m_ParticleLifetimePercentageReal = 0.f;
float m_ParticleLifetimePercentageRemainder = 0.f;
void UpdateParticleLifetimeTweenValues(int frame) {
float lt = m_ParticleLifetime != 0.0f ? m_ParticleLifetime : 1.0f;
m_ParticleLifetimePercentageReal = 100.0f * frame / lt;
m_ParticleLifetimePercentage = int(m_ParticleLifetimePercentageReal);
m_ParticleLifetimePercentageRemainder = m_ParticleLifetimePercentageReal - m_ParticleLifetimePercentage;
m_ParticleLifetimePercentage = zeus::clamp(0, m_ParticleLifetimePercentage, 100);
}
static const std::array<float, 8>* g_particleAccessParameters;
const std::array<float, 8>* m_particleAccessParameters = nullptr;
struct SParticleSystem {
FourCC x0_type;
CElementGen* x4_system;
};
static SParticleSystem* g_currentParticleSystem;
SParticleSystem* m_currentParticleSystem;
static CParticleGlobals* instance() {
if (!g_ParticleGlobals)
g_ParticleGlobals.reset(new CParticleGlobals());
return g_ParticleGlobals.get();
}
};
struct SParticleInstanceTex {

View File

@ -110,8 +110,8 @@ void CParticleSwoosh::UpdateTranslationAndOrientation() {
x208_maxRadius = 0.f;
x1f0_aabbMin = zeus::CVector3f(FLT_MAX);
x1fc_aabbMax = zeus::CVector3f(-FLT_MAX);
CParticleGlobals::SetParticleLifetime(x1b4_LENG);
CParticleGlobals::SetEmitterTime(x28_curFrame);
CParticleGlobals::instance()->SetParticleLifetime(x1b4_LENG);
CParticleGlobals::instance()->SetEmitterTime(x28_curFrame);
for (int i = 0; i < x15c_swooshes.size(); ++i) {
SSwooshData& swoosh = x15c_swooshes[i];
@ -119,7 +119,7 @@ void CParticleSwoosh::UpdateTranslationAndOrientation() {
continue;
swoosh.x68_frame = x28_curFrame - swoosh.x70_startFrame;
CParticleGlobals::UpdateParticleLifetimeTweenValues(swoosh.x68_frame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(swoosh.x68_frame);
if (x1c_desc->x44_28_SROT) {
if (CRealElement* irot = x1c_desc->x1c_IROT.get())
irot->GetValue(x28_curFrame, swoosh.x30_irot);
@ -187,9 +187,9 @@ bool CParticleSwoosh::Update(double dt) {
if (!IsValid())
return false;
CParticleGlobals::SetParticleLifetime(x1b4_LENG);
CParticleGlobals::SetEmitterTime(x28_curFrame);
CParticleGlobals::UpdateParticleLifetimeTweenValues(0);
CParticleGlobals::instance()->SetParticleLifetime(x1b4_LENG);
CParticleGlobals::instance()->SetEmitterTime(x28_curFrame);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(0);
CGlobalRandom gr(x1c0_rand);
double evalTime = x28_curFrame / 60.0;
@ -393,7 +393,7 @@ void CParticleSwoosh::RenderNSidedSpline() {
otherK = 0;
zeus::CColor color = refSwoosh.x6c_color * x20c_moduColor;
if (cros) {
int otherK = k + x1b8_SIDE / 2;
otherK = k + x1b8_SIDE / 2;
zeus::CVector3f v0 = GetSplinePoint(x16c_p0[k], x17c_p1[k], x18c_p2[k], x19c_p3[k], t0);
zeus::CVector3f v1 = GetSplinePoint(x16c_p0[otherK], x17c_p1[otherK], x18c_p2[otherK], x19c_p3[otherK], t0);
zeus::CVector3f v2 = GetSplinePoint(x16c_p0[otherK], x17c_p1[otherK], x18c_p2[otherK], x19c_p3[otherK], t1);
@ -877,7 +877,7 @@ void CParticleSwoosh::Render(const CActorLights*) {
if (m_dataBind[0])
CGraphics::SetShaderDataBinding(m_dataBind[g_Renderer->IsThermalVisorHotPass()]);
CParticleGlobals::SetParticleLifetime(x1b4_LENG);
CParticleGlobals::instance()->SetParticleLifetime(x1b4_LENG);
CGlobalRandom gr(x1c0_rand);
CGraphics::DisableAllLights();
// Z-test, Z-update if x45_24_ZBUF
@ -985,10 +985,7 @@ bool CParticleSwoosh::IsSystemDeletable() const {
if (x1d0_24_emitting && x28_curFrame < x2c_PSLT)
return false;
if (GetParticleCount() >= 2)
return false;
return true;
return GetParticleCount() < 2;
}
std::optional<zeus::CAABox> CParticleSwoosh::GetBounds() const {

View File

@ -6,7 +6,7 @@
#include "zeus/Math.hpp"
#include "CGenDescription.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Real_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Real_Elements */
namespace urde {
@ -26,7 +26,7 @@ CREKeyframeEmitter::CREKeyframeEmitter(CInputStream& in) {
bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const {
if (!x4_percent) {
int emitterTime = CParticleGlobals::g_EmitterTime;
int emitterTime = CParticleGlobals::instance()->m_EmitterTime;
int calcKey = emitterTime;
if (xc_loop) {
if (emitterTime >= x10_loopEnd) {
@ -42,8 +42,8 @@ bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const {
}
valOut = x18_keys[calcKey];
} else {
int ltPerc = CParticleGlobals::g_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::g_ParticleLifetimePercentageRemainder;
int ltPerc = CParticleGlobals::instance()->m_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::instance()->m_ParticleLifetimePercentageRemainder;
if (ltPerc == 100)
valOut = x18_keys[100];
else
@ -53,7 +53,7 @@ bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const {
}
bool CRELifetimeTween::GetValue(int frame, float& valOut) const {
float ltFac = frame / CParticleGlobals::g_ParticleLifetimeReal;
float ltFac = frame / CParticleGlobals::instance()->instance()->m_ParticleLifetimeReal;
float a, b;
x4_a->GetValue(frame, a);
x8_b->GetValue(frame, b);
@ -160,7 +160,7 @@ bool CRELifetimePercent::GetValue(int frame, float& valOut) const {
float a;
x4_percentVal->GetValue(frame, a);
a = std::max(0.0f, a);
valOut = (a / 100.0f) * CParticleGlobals::g_ParticleLifetimeReal;
valOut = (a / 100.0f) * CParticleGlobals::instance()->m_ParticleLifetimeReal;
return false;
}
@ -204,42 +204,42 @@ bool CRECompareEquals::GetValue(int frame, float& valOut) const {
}
bool CREParticleAccessParam1::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[0];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[0];
return false;
}
bool CREParticleAccessParam2::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[1];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[1];
return false;
}
bool CREParticleAccessParam3::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[2];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[2];
return false;
}
bool CREParticleAccessParam4::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[3];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[3];
return false;
}
bool CREParticleAccessParam5::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[4];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[4];
return false;
}
bool CREParticleAccessParam6::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[5];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[5];
return false;
}
bool CREParticleAccessParam7::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[6];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[6];
return false;
}
bool CREParticleAccessParam8::GetValue(int /*frame*/, float& valOut) const {
valOut = (*CParticleGlobals::g_particleAccessParameters)[7];
valOut = (*CParticleGlobals::instance()->m_particleAccessParameters)[7];
return false;
}
@ -293,7 +293,7 @@ bool CREExternalVar::GetValue(int frame, float& valOut) const {
int a;
x4_a->GetValue(frame, a);
int cv = std::max(0, a);
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetExternalVar(cv & 0xf);
valOut = CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetExternalVar(cv & 0xf);
return false;
}

View File

@ -6,7 +6,7 @@
#include "Runtime/GCNTypes.hpp"
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Real_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Real_Elements */
namespace urde {

View File

@ -1,6 +1,6 @@
#include "CUVElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#UV_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#UV_Elements */
namespace urde {

View File

@ -8,7 +8,7 @@
#include "Runtime/Graphics/CTexture.hpp"
#include "Runtime/Particle/IElement.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#UV_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#UV_Elements */
namespace urde {
class CToken;

View File

@ -5,7 +5,7 @@
#include "zeus/Math.hpp"
#include "CGenDescription.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Vector_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Vector_Elements */
namespace urde {
@ -25,7 +25,7 @@ CVEKeyframeEmitter::CVEKeyframeEmitter(CInputStream& in) {
bool CVEKeyframeEmitter::GetValue(int frame, zeus::CVector3f& valOut) const {
if (!x4_percent) {
int emitterTime = CParticleGlobals::g_EmitterTime;
int emitterTime = CParticleGlobals::instance()->m_EmitterTime;
int calcKey = emitterTime;
if (xc_loop) {
if (emitterTime >= x10_loopEnd) {
@ -41,8 +41,8 @@ bool CVEKeyframeEmitter::GetValue(int frame, zeus::CVector3f& valOut) const {
}
valOut = x18_keys[calcKey];
} else {
int ltPerc = CParticleGlobals::g_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::g_ParticleLifetimePercentageRemainder;
int ltPerc = CParticleGlobals::instance()->m_ParticleLifetimePercentage;
float ltPercRem = CParticleGlobals::instance()->m_ParticleLifetimePercentageRemainder;
if (ltPerc == 100)
valOut = x18_keys[100];
else
@ -255,27 +255,27 @@ bool CVEParticleLocation::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleSystemOrientationFront::GetValue(int /*frame*/, zeus::CVector3f& valOut) const {
zeus::CMatrix4f trans =
CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
valOut.assign(trans.m[0].y(), trans.m[1].y(), trans.m[2].y());
return false;
}
bool CVEParticleSystemOrientationUp::GetValue(int /*frame*/, zeus::CVector3f& valOut) const {
zeus::CMatrix4f trans =
CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
valOut.assign(trans.m[0].z(), trans.m[1].z(), trans.m[2].z());
return false;
}
bool CVEParticleSystemOrientationRight::GetValue(int /*frame*/, zeus::CVector3f& valOut) const {
zeus::CMatrix4f trans =
CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetOrientation().toMatrix4f().transposed();
valOut.assign(trans.m[0].x(), trans.m[1].x(), trans.m[2].x());
return false;
}
bool CVEParticleSystemTranslation::GetValue(int /*frame*/, zeus::CVector3f& valOut) const {
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetTranslation();
valOut = CParticleGlobals::instance()->m_currentParticleSystem->x4_system->GetTranslation();
return false;
}

View File

@ -8,7 +8,7 @@
#include <zeus/CVector3f.hpp>
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Vector_Elements */
/* Documentation at: https://wiki.axiodl.com/w/Particle_Script#Vector_Elements */
namespace urde {

View File

@ -408,9 +408,9 @@ void CProjectileWeapon::Update(float dt) {
while (actualTime < xd0_curTime && !zeus::close_enough(actualTime, xd0_curTime)) {
if (xf4_curFrame < xe8_lifetime) {
CParticleGlobals::SetEmitterTime(xf4_curFrame);
CParticleGlobals::SetParticleLifetime(xe8_lifetime);
CParticleGlobals::UpdateParticleLifetimeTweenValues(xf4_curFrame);
CParticleGlobals::instance()->SetEmitterTime(xf4_curFrame);
CParticleGlobals::instance()->SetParticleLifetime(xe8_lifetime);
CParticleGlobals::instance()->UpdateParticleLifetimeTweenValues(xf4_curFrame);
UpdatePSTranslationAndOrientation();
}
actualTime += (1.0 / 60.0);