diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp index 882770aeb..2dc36ec52 100644 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ b/DataSpec/DNACommon/ParticleCommon.cpp @@ -100,9 +100,6 @@ void RealElementFactory::read(Athena::io::YAMLDocReader& r) case SBIG('PRLW'): m_elem.reset(new struct REPRLW); break; - case SBIG('PSOF'): - m_elem.reset(new struct REPSOF); - break; case SBIG('SUB_'): m_elem.reset(new struct RESubtract); break; @@ -236,9 +233,6 @@ void RealElementFactory::read(Athena::io::IStreamReader& r) case SBIG('PRLW'): m_elem.reset(new struct REPRLW); break; - case SBIG('PSOF'): - m_elem.reset(new struct REPSOF); - break; case SBIG('SUB_'): m_elem.reset(new struct RESubtract); break; diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp index dddb58060..faaf03ed9 100644 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ b/DataSpec/DNACommon/ParticleCommon.hpp @@ -329,12 +329,6 @@ struct REPRLW : IRealElement const char* ClassID() const {return "PRLW";} }; -struct REPSOF : IRealElement -{ - DECL_YAML - const char* ClassID() const {return "PSOF";} -}; - struct RESubtract : IRealElement { DECL_YAML diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index 7d6782544..18e4d93d7 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -608,10 +608,6 @@ CRealElement* CParticleDataFactory::GetRealElement(CInputStream& in) { return new CREPRLW; } - case SBIG('PSOF'): - { - return new CREPSOF; - } case SBIG('SUB_'): { CRealElement* a = GetRealElement(in); diff --git a/Runtime/Particle/CParticleGlobals.cpp b/Runtime/Particle/CParticleGlobals.cpp index 9cff58fab..73d011221 100644 --- a/Runtime/Particle/CParticleGlobals.cpp +++ b/Runtime/Particle/CParticleGlobals.cpp @@ -13,4 +13,7 @@ int CParticleGlobals::g_particleLifetimePercentTweenInt = 0; float CParticleGlobals::g_particleLifetimePercentTweenFloat = 0.0; float CParticleGlobals::g_particleLifetimePercentTweenIntFloatRem = 0.0; +float* CParticleGlobals::g_papValues = nullptr; +CParticleGlobals::SParticleMetrics* CParticleGlobals::g_particleMetrics = nullptr; + } diff --git a/Runtime/Particle/CParticleGlobals.hpp b/Runtime/Particle/CParticleGlobals.hpp index 6769887ed..9fd94ed08 100644 --- a/Runtime/Particle/CParticleGlobals.hpp +++ b/Runtime/Particle/CParticleGlobals.hpp @@ -1,6 +1,8 @@ #ifndef __RETRO_CPARTICLEGLOBALS_HPP__ #define __RETRO_CPARTICLEGLOBALS_HPP__ +#include "CVector3f.hpp" + namespace Retro { @@ -33,6 +35,18 @@ public: g_particleLifetimePercentTweenInt = g_particleLifetimePercentTweenFloat; g_particleLifetimePercentTweenIntFloatRem = g_particleLifetimePercentTweenFloat - g_particleLifetimePercentTweenInt; } + + static float* g_papValues; + + struct SParticleMetrics + { + Zeus::CVector3f x0_ploc; + Zeus::CVector3f x10_plco; + Zeus::CVector3f x1c_pvel; + float x2c_psll; + float x30_prlw; + }; + static SParticleMetrics* g_particleMetrics; }; } diff --git a/Runtime/Particle/CRealElement.cpp b/Runtime/Particle/CRealElement.cpp index c4b3d37a8..4990c80a1 100644 --- a/Runtime/Particle/CRealElement.cpp +++ b/Runtime/Particle/CRealElement.cpp @@ -1,5 +1,8 @@ #include "CRealElement.hpp" #include "CParticleGlobals.hpp" +#include "CRandom16.hpp" +#include +#include namespace Retro { @@ -103,4 +106,215 @@ bool CREClamp::GetValue(int frame, float &valOut) const return false; } +bool CRERandom::GetValue(int frame, float& valOut) const +{ + float a, b; + x4_min->GetValue(frame, a); + x8_max->GetValue(frame, b); + float rand = CRandom16::GetRandomNumber()->Float(); + valOut = b * rand + a * (1.0f - rand); + return false; +} + +bool CREPulse::GetValue(int frame, float& valOut) const +{ + int a, b; + x4_aDuration->GetValue(frame, a); + x8_bDuration->GetValue(frame, b); + int cv = std::max(1, a + b + 1); + + if (b >= 1) + { + int cv2 = frame % cv; + if (cv2 >= a) + x10_valB->GetValue(frame, valOut); + else + xc_valA->GetValue(frame, valOut); + } + else + xc_valA->GetValue(frame, valOut); + + return false; +} + +bool CRETimeScale::GetValue(int frame, float& valOut) const +{ + float a; + x4_a->GetValue(frame, a); + valOut = float(frame) * a; + return false; +} + +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_particleLifetimeFloat; + return false; +} + +bool CRESineWave::GetValue(int frame, float& valOut) const +{ + float a, b, c; + x4_magnitude->GetValue(frame, a); + x8_linearFrame->GetValue(frame, b); + xc_constantFrame->GetValue(frame, c); + valOut = sinf((frame * b + c) * M_PI / 180.f) * a; + return false; +} + +bool CREISWT::GetValue(int frame, float& valOut) const +{ + if (frame == 0) + x4_a->GetValue(frame, valOut); + else + x8_b->GetValue(frame, valOut); + return false; +} + +bool CRECompareLessThan::GetValue(int frame, float& valOut) const +{ + float a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + if (a < b) + xc_c->GetValue(frame, valOut); + else + x10_d->GetValue(frame, valOut); + return false; +} + +bool CRECompareEquals::GetValue(int frame, float& valOut) const +{ + float a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + if (fabsf(a-b) < 0.00001) + xc_c->GetValue(frame, valOut); + else + x10_d->GetValue(frame, valOut); + return false; +} + +bool CREParticleAccessParam1::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[0]; + return false; +} + +bool CREParticleAccessParam2::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[1]; + return false; +} + +bool CREParticleAccessParam3::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[2]; + return false; +} + +bool CREParticleAccessParam4::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[3]; + return false; +} + +bool CREParticleAccessParam5::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[4]; + return false; +} + +bool CREParticleAccessParam6::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[5]; + return false; +} + +bool CREParticleAccessParam7::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[6]; + return false; +} + +bool CREParticleAccessParam8::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_papValues[7]; + return false; +} + +bool CREPSLL::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_particleMetrics->x2c_psll; + return false; +} + +bool CREPRLW::GetValue(int frame, float& valOut) const +{ + valOut = CParticleGlobals::g_particleMetrics->x30_prlw; + return false; +} + +bool CRESubtract::GetValue(int frame, float& valOut) const +{ + float a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a - b; + return false; +} + +bool CREVectorMagnitude::GetValue(int frame, float& valOut) const +{ + Zeus::CVector3f a; + x4_a->GetValue(frame, a); + valOut = a.magnitude(); + return false; +} + +bool CREVectorXToReal::GetValue(int frame, float& valOut) const +{ + Zeus::CVector3f a; + x4_a->GetValue(frame, a); + valOut = a[0]; + return false; +} + +bool CREVectorYToReal::GetValue(int frame, float& valOut) const +{ + Zeus::CVector3f a; + x4_a->GetValue(frame, a); + valOut = a[1]; + return false; +} + +bool CREVectorZToReal::GetValue(int frame, float& valOut) const +{ + Zeus::CVector3f a; + x4_a->GetValue(frame, a); + valOut = a[2]; + return false; +} + +bool CRECEXT::GetValue(int frame, float& valOut) const +{ + int a; + x4_a->GetValue(frame, a); + int cv = std::max(0, a); + /* TODO: Figure out how value table is generated/stored in 0-00 */ + return false; +} + +bool CREITRL::GetValue(int frame, float& valOut) const +{ + int a; + x4_a->GetValue(frame, a); + float b; + x8_b->GetValue(frame, b); + valOut = float(a) * b; + return false; +} + } diff --git a/Runtime/Particle/CRealElement.hpp b/Runtime/Particle/CRealElement.hpp index 24a7d4506..e9af25079 100644 --- a/Runtime/Particle/CRealElement.hpp +++ b/Runtime/Particle/CRealElement.hpp @@ -6,6 +6,20 @@ namespace Retro { +class CREKeyframeEmitter : public CRealElement +{ + u32 x4_percent; + u32 x8_unk1; + bool xc_loop; + bool xd_unk2; + u32 x10_loopEnd; + u32 x14_loopStart; + std::vector x18_keys; +public: + CREKeyframeEmitter(CInputStream& in); + bool GetValue(int frame, float& valOut) const; +}; + class CRELifetimeTween : public CRealElement { std::unique_ptr x4_a; @@ -57,20 +71,6 @@ public: bool GetValue(int frame, float& valOut) const; }; -class CREKeyframeEmitter : public CRealElement -{ - u32 x4_percent; - u32 x8_unk1; - bool xc_loop; - bool xd_unk2; - u32 x10_loopEnd; - u32 x14_loopStart; - std::vector x18_keys; -public: - CREKeyframeEmitter(CInputStream& in); - bool GetValue(int frame, float& valOut) const; -}; - class CREInitialRandom : public CRealElement { std::unique_ptr x4_min; @@ -104,13 +104,13 @@ public: class CREPulse : public CRealElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; - std::unique_ptr xc_c; - std::unique_ptr x10_d; + std::unique_ptr x4_aDuration; + std::unique_ptr x8_bDuration; + std::unique_ptr xc_valA; + std::unique_ptr x10_valB; public: CREPulse(CIntElement* a, CIntElement* b, CRealElement* c, CRealElement* d) - : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} + : x4_aDuration(a), x8_bDuration(b), xc_valA(c), x10_valB(d) {} bool GetValue(int frame, float& valOut) const; }; @@ -125,21 +125,21 @@ public: class CRELifetimePercent : public CRealElement { - std::unique_ptr x4_a; + std::unique_ptr x4_percentVal; public: CRELifetimePercent(CRealElement* a) - : x4_a(a) {} + : x4_percentVal(a) {} bool GetValue(int frame, float& valOut) const; }; class CRESineWave : public CRealElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr x4_magnitude; + std::unique_ptr x8_linearFrame; + std::unique_ptr xc_constantFrame; public: CRESineWave(CRealElement* a, CRealElement* b, CRealElement* c) - : x4_a(a), x8_b(b), xc_c(c) {} + : x4_magnitude(a), x8_linearFrame(b), xc_constantFrame(c) {} bool GetValue(int frame, float& valOut) const; }; @@ -237,12 +237,6 @@ public: bool GetValue(int frame, float& valOut) const; }; -class CREPSOF : public CRealElement -{ -public: - bool GetValue(int frame, float& valOut) const; -}; - class CRESubtract : public CRealElement { std::unique_ptr x4_a; diff --git a/Runtime/Particle/CUVElement.cpp b/Runtime/Particle/CUVElement.cpp index c07aa0f57..343496f65 100644 --- a/Runtime/Particle/CUVElement.cpp +++ b/Runtime/Particle/CUVElement.cpp @@ -9,7 +9,7 @@ CUVEAnimTexture::CUVEAnimTexture(TToken&& tex, CIntElement* a, CIntEle { a->GetValue(0, x10_tileW); delete a; - b->GetValue(0, x14_tileW); + b->GetValue(0, x14_tileH); delete b; c->GetValue(0, x18_strideW); delete c; @@ -31,7 +31,7 @@ CUVEAnimTexture::CUVEAnimTexture(TToken&& tex, CIntElement* a, CIntEle int px = x18_strideW * x; int px2 = px + x10_tileW; int py = x1c_strideH * y; - int py2 = py + x14_tileW; + int py2 = py + x14_tileH; x2c_uvElems.push_back({px / widthF, py / heightF, px2 / widthF, py2 / heightF}); } } diff --git a/Runtime/Particle/CUVElement.hpp b/Runtime/Particle/CUVElement.hpp index 9280ee112..e62569b33 100644 --- a/Runtime/Particle/CUVElement.hpp +++ b/Runtime/Particle/CUVElement.hpp @@ -54,7 +54,7 @@ struct CUVEAnimTexture : public CUVElement { TToken x4_tex; CTexture* xc_directTex; - int x10_tileW, x14_tileW, x18_strideW, x1c_strideH; + int x10_tileW, x14_tileH, x18_strideW, x1c_strideH; int x20_tiles; bool x24_loop; std::unique_ptr x28_cycleFrameRate;