diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp index a6afb1150..882770aeb 100644 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ b/DataSpec/DNACommon/ParticleCommon.cpp @@ -909,7 +909,7 @@ void EmitterElementFactory::read(Athena::io::YAMLDocReader& r) m_elem.reset(new struct VESphere); break; case SBIG('ASPH'): - m_elem.reset(new struct VEAngularSphere); + m_elem.reset(new struct VEAngleSphere); break; default: m_elem.reset(); @@ -954,7 +954,7 @@ void EmitterElementFactory::read(Athena::io::IStreamReader& r) m_elem.reset(new struct VESphere); break; case SBIG('ASPH'): - m_elem.reset(new struct VEAngularSphere); + m_elem.reset(new struct VEAngleSphere); break; case SBIG('NONE'): m_elem.reset(); diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp index 13d8d2160..dddb58060 100644 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ b/DataSpec/DNACommon/ParticleCommon.hpp @@ -1002,7 +1002,7 @@ struct VESphere : IEmitterElement const char* ClassID() const {return "SPHE";} }; -struct VEAngularSphere : IEmitterElement +struct VEAngleSphere : IEmitterElement { DECL_YAML VectorElementFactory a; diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 1bedeac10..ccf6ea0f9 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -58,6 +58,7 @@ add_library(RuntimeCommon CPakFile.hpp CPakFile.cpp CStringExtras.hpp CCallStack.hpp + CTexture.hpp CTexture.cpp IOStreams.hpp IOStreams.cpp CMainFlowBase.hpp CMainFlowBase.cpp CMFGameBase.hpp diff --git a/Runtime/CTexture.cpp b/Runtime/CTexture.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/CTexture.hpp b/Runtime/CTexture.hpp new file mode 100644 index 000000000..2eea444e1 --- /dev/null +++ b/Runtime/CTexture.hpp @@ -0,0 +1,20 @@ +#ifndef __RETRO_CTEXTURE_HPP__ +#define __RETRO_CTEXTURE_HPP__ + +#include "GCNTypes.hpp" + +namespace Retro +{ + +class CTexture +{ + u16 x4_w; + u16 x6_h; +public: + u16 GetWidth() const {return x4_w;} + u16 GetHeight() const {return x6_h;} +}; + +} + +#endif // __RETRO_CTEXTURE_HPP__ diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index ca476c295..7d895b873 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -105,7 +105,7 @@ class CToken public: void Unlock() { - if (x4_lockHeld) + if (x0_objRef && x4_lockHeld) { x0_objRef->Unlock(); x4_lockHeld = false; @@ -113,7 +113,7 @@ public: } void Lock() { - if (!x4_lockHeld) + if (x0_objRef && !x4_lockHeld) { x0_objRef->Lock(); x4_lockHeld = true; @@ -121,7 +121,7 @@ public: } void RemoveRef() { - if (x0_objRef->RemoveReference() == 0) + if (x0_objRef && x0_objRef->RemoveReference() == 0) { delete x0_objRef; x0_objRef = nullptr; @@ -129,6 +129,8 @@ public: } IObj* GetObj() { + if (!x0_objRef) + return nullptr; Lock(); return x0_objRef->GetObject(); } @@ -137,9 +139,22 @@ public: Unlock(); RemoveRef(); x0_objRef = other.x0_objRef; - ++x0_objRef->x0_refCount; - if (other.x4_lockHeld) - Lock(); + if (x0_objRef) + { + ++x0_objRef->x0_refCount; + if (other.x4_lockHeld) + Lock(); + } + return *this; + } + CToken& operator=(CToken&& other) + { + Unlock(); + RemoveRef(); + x0_objRef = other.x0_objRef; + other.x0_objRef = nullptr; + x4_lockHeld = other.x4_lockHeld; + other.x4_lockHeld = false; return *this; } CToken() {} @@ -148,6 +163,12 @@ public: { ++x0_objRef->x0_refCount; } + CToken(CToken&& other) + : x0_objRef(other.x0_objRef), x4_lockHeld(other.x4_lockHeld) + { + other.x0_objRef = nullptr; + other.x4_lockHeld = false; + } CToken(IObj* obj) { x0_objRef = new CObjectReference(std::unique_ptr(obj)); @@ -161,9 +182,12 @@ public: } ~CToken() { - if (x4_lockHeld) - x0_objRef->Unlock(); - RemoveRef(); + if (x0_objRef) + { + if (x4_lockHeld) + x0_objRef->Unlock(); + RemoveRef(); + } } }; @@ -176,16 +200,18 @@ public: return TObjOwnerDerivedFromIObj::GetNewDerivedObject(std::move(obj)); } TToken() {} + TToken(const CToken& other) : CToken(other) {} TToken(T* obj) : CToken(GetIObjObjectFor(std::unique_ptr(obj))) {} TToken& operator=(T* obj) {*this = CToken(GetIObjObjectFor(obj)); return this;} + T* GetObj() {return static_cast*>(CToken::GetObj())->GetObj();} }; template class TLockedToken : public TToken { public: - using TToken::TToken; + TLockedToken(const CToken& other) : TToken(other) {CToken::Lock();} }; } diff --git a/Runtime/IObj.hpp b/Runtime/IObj.hpp index c97d97463..90fd7129b 100644 --- a/Runtime/IObj.hpp +++ b/Runtime/IObj.hpp @@ -30,6 +30,7 @@ public: (new TObjOwnerDerivedFromIObj(obj.release())); } ~TObjOwnerDerivedFromIObj() {delete static_cast(m_objPtr);} + T* GetObj() {return static_cast(m_objPtr);} }; } diff --git a/Runtime/Particle/CColorElement.hpp b/Runtime/Particle/CColorElement.hpp index 50092a524..193c9361c 100644 --- a/Runtime/Particle/CColorElement.hpp +++ b/Runtime/Particle/CColorElement.hpp @@ -8,43 +8,82 @@ namespace Retro class CCEKeyframeEmitter : public CColorElement { + u32 x4_percent; + u32 x8_unk1; + bool xc_loop; + bool xd_unk2; + u32 x10_loopEnd; + u32 x14_loopStart; + std::vector x18_keys; public: + CCEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCEConstant : public CColorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CCEConstant(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCEFastConstant : public CColorElement { + Zeus::CColor x4_val; public: + CCEFastConstant(float a, float b, float c, float d) + : x4_val(a, b, c, d) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCETimeChain : public CColorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CCETimeChain(CColorElement* a, CColorElement* b, CIntElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCEFadeEnd : public CColorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CCEFadeEnd(CColorElement* a, CColorElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCEFade : public CColorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CCEFade(CColorElement* a, CColorElement* b, CRealElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; class CCEPulse : public CColorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CCEPulse(CIntElement* a, CIntElement* b, CColorElement* c, CColorElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, Zeus::CColor& colorOut) const; }; diff --git a/Runtime/Particle/CEmitterElement.hpp b/Runtime/Particle/CEmitterElement.hpp index 9db5f8442..43948cb5c 100644 --- a/Runtime/Particle/CEmitterElement.hpp +++ b/Runtime/Particle/CEmitterElement.hpp @@ -6,23 +6,40 @@ namespace Retro { -class CEmitterElement : public IElement -{ -}; - class CEESimpleEmitter : public CEmitterElement { + std::unique_ptr x4_loc; + std::unique_ptr x8_vec; +public: + CEESimpleEmitter(CVectorElement* a, CVectorElement* b) + : x4_loc(a), x8_vec(b) {} }; class CVESphere : public CEmitterElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; +public: + CVESphere(CVectorElement* a, CRealElement* b, CRealElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} }; -class CVEAngularSphere : public CEmitterElement +class CVEAngleSphere : public CEmitterElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + std::unique_ptr x14_e; + std::unique_ptr x18_f; + std::unique_ptr x1c_g; +public: + CVEAngleSphere(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, + CRealElement* e, CRealElement* f, CRealElement* g) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e), x18_f(f), x1c_g(g) {} }; - } #endif // __RETRO_CEMITTERELEMENT_HPP__ diff --git a/Runtime/Particle/CIntElement.hpp b/Runtime/Particle/CIntElement.hpp index 525de465c..6dee4a2f3 100644 --- a/Runtime/Particle/CIntElement.hpp +++ b/Runtime/Particle/CIntElement.hpp @@ -8,85 +8,145 @@ namespace Retro class CIEKeyframeEmitter : public CIntElement { + u32 x4_percent; + u32 x8_unk1; + bool xc_loop; + bool xd_unk2; + u32 x10_loopEnd; + u32 x14_loopStart; + std::vector x18_keys; public: + CIEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, int& valOut) const; }; class CIEDeath : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIEDeath(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIEClamp : public CIntElement { + std::unique_ptr x4_min; + std::unique_ptr x8_max; + std::unique_ptr xc_val; public: + CIEClamp(CIntElement* a, CIntElement* b, CIntElement* c) + : x4_min(a), x8_max(b), xc_val(c) {} bool GetValue(int frame, int& valOut) const; }; class CIETimeChain : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CIETimeChain(CIntElement* a, CIntElement* b, CIntElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, int& valOut) const; }; class CIEAdd : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIEAdd(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIEConstant : public CIntElement { + int x4_val; public: + CIEConstant(int val) : x4_val(val) {} bool GetValue(int frame, int& valOut) const; }; class CIEImpulse : public CIntElement { + std::unique_ptr x4_a; public: + CIEImpulse(CIntElement* a) + : x4_a(a) {} bool GetValue(int frame, int& valOut) const; }; class CIELifetimePercent : public CIntElement { + std::unique_ptr x4_a; public: + CIELifetimePercent(CIntElement* a) + : x4_a(a) {} bool GetValue(int frame, int& valOut) const; }; class CIEInitialRandom : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIEInitialRandom(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIEPulse : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CIEPulse(CIntElement* a, CIntElement* b, CIntElement* c, CIntElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, int& valOut) const; }; class CIEMultiply : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIEMultiply(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIESampleAndHold : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CIESampleAndHold(CIntElement* a, CIntElement* b, CIntElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, int& valOut) const; }; class CIERandom : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIERandom(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIETimeScale : public CIntElement { + std::unique_ptr x4_a; public: + CIETimeScale(CRealElement* a) + : x4_a(a) {} bool GetValue(int frame, int& valOut) const; }; @@ -98,13 +158,21 @@ public: class CIEModulo : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIEModulo(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; class CIESubtract : public CIntElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CIESubtract(CIntElement* a, CIntElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, int& valOut) const; }; diff --git a/Runtime/Particle/CModVectorElement.hpp b/Runtime/Particle/CModVectorElement.hpp index 7ba31c507..ec3ffcbf0 100644 --- a/Runtime/Particle/CModVectorElement.hpp +++ b/Runtime/Particle/CModVectorElement.hpp @@ -8,80 +8,147 @@ namespace Retro class CMVEImplosion : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + bool x14_e; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, bool e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEExponentialImplosion : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + bool x14_e; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEExponentialImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, bool e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVETimeChain : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVETimeChain(CModVectorElement* a, CModVectorElement* b, CIntElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEBounce : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + bool x14_e; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEBounce(CVectorElement* a, CVectorElement* b, CRealElement* c, CRealElement* d, bool e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEConstant : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEConstant(CRealElement* a, CRealElement* b, CRealElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEFastConstant : public CModVectorElement { + Zeus::CVector3f x4_val; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEFastConstant(float a, float b, float c) + : x4_val(a, b, c) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEGravity : public CModVectorElement { + std::unique_ptr x4_a; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEGravity(CVectorElement* a) + : x4_a(a) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEExplode : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEExplode(CRealElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVESetPosition : public CModVectorElement { + std::unique_ptr x4_a; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVESetPosition(CVectorElement* a) + : x4_a(a) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVELinearImplosion : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + bool x14_e; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVELinearImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, bool e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEPulse : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEPulse(CIntElement* a, CIntElement* b, CModVectorElement* c, CModVectorElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVEWind : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVEWind(CVectorElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; class CMVESwirl : public CModVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: - bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const=0; + CMVESwirl(CVectorElement* a, CVectorElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} + bool GetValue(int frame, Zeus::CVector3f& vec1Out, Zeus::CVector3f& vec2Out) const; }; } diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index b351ee12c..7d6782544 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -32,6 +32,738 @@ FourCC CParticleDataFactory::GetClassID(CInputStream& in) return val; } +SParticleModel CParticleDataFactory::GetModel(CInputStream& in, CSimplePool* resPool) +{ + FourCC clsId = GetClassID(in); + if (clsId == SBIG('NONE')) + return {}; + TResID id = in.readUint32Big(); + if (!id) + return {}; + return {resPool->GetObj({FOURCC('CMDL'), id}), true}; +} + +SChildGeneratorDesc CParticleDataFactory::GetChildGeneratorDesc(TResID res, CSimplePool* resPool, const std::vector& tracker) +{ + if (std::count(tracker.cbegin(), tracker.cend(), res) == 0) + return {resPool->GetObj({FOURCC('PART'), res}), true}; + return {}; +} + +SChildGeneratorDesc CParticleDataFactory::GetChildGeneratorDesc(CInputStream& in, CSimplePool* resPool, const std::vector& tracker) +{ + FourCC clsId = GetClassID(in); + if (clsId == SBIG('NONE')) + return {}; + TResID id = in.readUint32Big(); + if (!id) + return {}; + return GetChildGeneratorDesc(id, resPool, tracker); +} + +SSwooshGeneratorDesc CParticleDataFactory::GetSwooshGeneratorDesc(CInputStream& in, CSimplePool* resPool) +{ + FourCC clsId = GetClassID(in); + if (clsId == SBIG('NONE')) + return {}; + TResID id = in.readUint32Big(); + if (!id) + return {}; + return {resPool->GetObj({FOURCC('SWHC'), id}), true}; +} + +SElectricGeneratorDesc CParticleDataFactory::GetElectricGeneratorDesc(CInputStream& in, CSimplePool* resPool) +{ + FourCC clsId = GetClassID(in); + if (clsId == SBIG('NONE')) + return {}; + TResID id = in.readUint32Big(); + if (!id) + return {}; + return {resPool->GetObj({FOURCC('ELSC'), id}), true}; +} + +CUVElement* CParticleDataFactory::GetTextureElement(CInputStream& in, CSimplePool* resPool) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('CNST'): + { + FourCC subId = GetClassID(in); + if (subId == SBIG('NONE')) + return nullptr; + TResID id = in.readUint32Big(); + TToken txtr = resPool->GetObj({FOURCC('TXTR'), id}); + return new CUVEConstant(std::move(txtr)); + } + case SBIG('ATEX'): + { + FourCC subId = GetClassID(in); + if (subId == SBIG('NONE')) + return nullptr; + TResID id = in.readUint32Big(); + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CIntElement* c = GetIntElement(in); + CIntElement* d = GetIntElement(in); + CIntElement* e = GetIntElement(in); + bool f = GetBool(in); + TToken txtr = resPool->GetObj({FOURCC('TXTR'), id}); + return new CUVEAnimTexture(std::move(txtr), a, b, c, d, e, f); + } + default: break; + } + return nullptr; +} + +CColorElement* CParticleDataFactory::GetColorElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('KEYE'): + case SBIG('KEYP'): + { + return new CCEKeyframeEmitter(in); + } + case SBIG('CNST'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + if (a->IsConstant() && b->IsConstant() && c->IsConstant() && d->IsConstant()) + { + float af, bf, cf, df; + a->GetValue(0, af); + b->GetValue(0, bf); + c->GetValue(0, cf); + d->GetValue(0, df); + return new CCEFastConstant(af, bf, cf, df); + } + else + { + return new CCEConstant(a, b, c, d); + } + } + case SBIG('CHAN'): + { + CColorElement* a = GetColorElement(in); + CColorElement* b = GetColorElement(in); + CIntElement* c = GetIntElement(in); + return new CCETimeChain(a, b, c); + } + case SBIG('CFDE'): + { + CColorElement* a = GetColorElement(in); + CColorElement* b = GetColorElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + return new CCEFadeEnd(a, b, c, d); + } + case SBIG('FADE'): + { + CColorElement* a = GetColorElement(in); + CColorElement* b = GetColorElement(in); + CRealElement* c = GetRealElement(in); + return new CCEFade(a, b, c); + } + case SBIG('PULS'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CColorElement* c = GetColorElement(in); + CColorElement* d = GetColorElement(in); + return new CCEPulse(a, b, c, d); + } + default: break; + } + return nullptr; +} + +CModVectorElement* CParticleDataFactory::GetModVectorElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('IMPL'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + bool e = GetBool(in); + return new CMVEImplosion(a, b, c, d, e); + } + case SBIG('EMPL'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + bool e = GetBool(in); + return new CMVEExponentialImplosion(a, b, c, d, e); + } + case SBIG('CHAN'): + { + CModVectorElement* a = GetModVectorElement(in); + CModVectorElement* b = GetModVectorElement(in); + CIntElement* c = GetIntElement(in); + return new CMVETimeChain(a, b, c); + } + case SBIG('BNCE'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + bool e = GetBool(in); + return new CMVEBounce(a, b, c, d, e); + } + case SBIG('CNST'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + if (a->IsConstant() && b->IsConstant() && c->IsConstant()) + { + float af, bf, cf; + a->GetValue(0, af); + b->GetValue(0, bf); + c->GetValue(0, cf); + return new CMVEFastConstant(af, bf, cf); + } + else + { + return new CMVEConstant(a, b, c); + } + } + case SBIG('GRAV'): + { + CVectorElement* a = GetVectorElement(in); + return new CMVEGravity(a); + } + case SBIG('EXPL'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CMVEExplode(a, b); + } + case SBIG('SPOS'): + { + CVectorElement* a = GetVectorElement(in); + return new CMVESetPosition(a); + } + case SBIG('LMPL'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + bool e = GetBool(in); + return new CMVELinearImplosion(a, b, c, d, e); + } + case SBIG('PULS'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CModVectorElement* c = GetModVectorElement(in); + CModVectorElement* d = GetModVectorElement(in); + return new CMVEPulse(a, b, c, d); + } + case SBIG('WIND'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + return new CMVEWind(a, b); + } + case SBIG('SWRL'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + return new CMVESwirl(a, b, c, d); + } + default: break; + } + return nullptr; +} + +CEmitterElement* CParticleDataFactory::GetEmitterElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('SETR'): + { + FourCC prop = GetClassID(in); + if (prop == SBIG('ILOC')) + { + CVectorElement* a = GetVectorElement(in); + prop = GetClassID(in); + if (prop == SBIG('IVEC')) + { + CVectorElement* b = GetVectorElement(in); + return new CEESimpleEmitter(a, b); + } + } + return nullptr; + } + case SBIG('SEMR'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + return new CEESimpleEmitter(a, b); + } + case SBIG('SPHE'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + return new CVESphere(a, b, c); + } + case SBIG('ASPH'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + CRealElement* e = GetRealElement(in); + CRealElement* f = GetRealElement(in); + CRealElement* g = GetRealElement(in); + return new CVEAngleSphere(a, b, c, d, e, f, g); + } + default: break; + } + return nullptr; +} + +CVectorElement* CParticleDataFactory::GetVectorElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('CONE'): + { + CVectorElement* a = GetVectorElement(in); + CRealElement* b = GetRealElement(in); + return new CVECone(a, b); + } + case SBIG('CHAN'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + CIntElement* c = GetIntElement(in); + return new CVETimeChain(a, b, c); + } + case SBIG('ANGC'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + CRealElement* e = GetRealElement(in); + return new CVEAngleCone(a, b, c, d, e); + } + case SBIG('ADD_'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + return new CVEAdd(a, b); + } + case SBIG('CCLU'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + CIntElement* c = GetIntElement(in); + CRealElement* d = GetRealElement(in); + return new CVECircleCluster(a, b, c, d); + } + case SBIG('CNST'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + if (a->IsConstant() && b->IsConstant() && c->IsConstant()) + { + float af, bf, cf; + a->GetValue(0, af); + b->GetValue(0, bf); + c->GetValue(0, cf); + return new CVEFastConstant(af, bf, cf); + } + else + { + return new CVEConstant(a, b, c); + } + } + case SBIG('CIRC'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + CRealElement* e = GetRealElement(in); + return new CVECircle(a, b, c, d, e); + } + case SBIG('KEYE'): + case SBIG('KEYP'): + { + return new CVEKeyframeEmitter(in); + } + case SBIG('MULT'): + { + CVectorElement* a = GetVectorElement(in); + CVectorElement* b = GetVectorElement(in); + return new CVEMultiply(a, b); + } + case SBIG('RTOV'): + { + CRealElement* a = GetRealElement(in); + return new CVERealToVector(a); + } + case SBIG('PULS'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CVectorElement* c = GetVectorElement(in); + CVectorElement* d = GetVectorElement(in); + return new CVEPulse(a, b, c, d); + } + case SBIG('PVEL'): + { + return new CVEParticleVelocity; + } + case SBIG('SPOS'): + { + CVectorElement* a = GetVectorElement(in); + return new CVESPOS(a); + } + case SBIG('PLCO'): + { + return new CVEPLCO; + } + case SBIG('PLOC'): + { + return new CVEPLOC; + } + case SBIG('PSOR'): + { + return new CVEPSOR; + } + case SBIG('PSOF'): + { + return new CVEPSOF; + } + default: break; + } + return nullptr; +} + +CRealElement* CParticleDataFactory::GetRealElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('LFTW'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CRELifetimeTween(a, b); + } + case SBIG('CNST'): + { + float a = GetReal(in); + return new CREConstant(a); + } + case SBIG('CHAN'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CIntElement* c = GetIntElement(in); + return new CRETimeChain(a, b, c); + } + case SBIG('ADD_'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CREAdd(a, b); + } + case SBIG('CLMP'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + return new CREClamp(a, b, c); + } + case SBIG('KEYE'): + case SBIG('KEYP'): + { + return new CREKeyframeEmitter(in); + } + case SBIG('IRND'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CREInitialRandom(a, b); + } + case SBIG('RAND'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CRERandom(a, b); + } + case SBIG('MULT'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CREMultiply(a, b); + } + case SBIG('PULS'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + return new CREPulse(a, b, c, d); + } + case SBIG('SCAL'): + { + CRealElement* a = GetRealElement(in); + return new CRETimeScale(a); + } + case SBIG('RLPT'): + { + CRealElement* a = GetRealElement(in); + return new CRELifetimePercent(a); + } + case SBIG('SINE'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + return new CRESineWave(a, b, c); + } + case SBIG('ISWT'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CREISWT(a, b); + } + case SBIG('CLTN'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + return new CRECompareLessThan(a, b, c, d); + } + case SBIG('CEQL'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + CRealElement* c = GetRealElement(in); + CRealElement* d = GetRealElement(in); + return new CRECompareEquals(a, b, c, d); + } + case SBIG('PAP1'): + { + return new CREParticleAccessParam1; + } + case SBIG('PAP2'): + { + return new CREParticleAccessParam2; + } + case SBIG('PAP3'): + { + return new CREParticleAccessParam3; + } + case SBIG('PAP4'): + { + return new CREParticleAccessParam4; + } + case SBIG('PAP5'): + { + return new CREParticleAccessParam5; + } + case SBIG('PAP6'): + { + return new CREParticleAccessParam6; + } + case SBIG('PAP7'): + { + return new CREParticleAccessParam7; + } + case SBIG('PAP8'): + { + return new CREParticleAccessParam8; + } + case SBIG('PSLL'): + { + return new CREPSLL; + } + case SBIG('PRLW'): + { + return new CREPRLW; + } + case SBIG('PSOF'): + { + return new CREPSOF; + } + case SBIG('SUB_'): + { + CRealElement* a = GetRealElement(in); + CRealElement* b = GetRealElement(in); + return new CRESubtract(a, b); + } + case SBIG('VMAG'): + { + CVectorElement* a = GetVectorElement(in); + return new CREVectorMagnitude(a); + } + case SBIG('VXTR'): + { + CVectorElement* a = GetVectorElement(in); + return new CREVectorXToReal(a); + } + case SBIG('VYTR'): + { + CVectorElement* a = GetVectorElement(in); + return new CREVectorYToReal(a); + } + case SBIG('VZTR'): + { + CVectorElement* a = GetVectorElement(in); + return new CREVectorZToReal(a); + } + case SBIG('CEXT'): + { + CIntElement* a = GetIntElement(in); + return new CRECEXT(a); + } + case SBIG('ITRL'): + { + CIntElement* a = GetIntElement(in); + CRealElement* b = GetRealElement(in); + return new CREITRL(a, b); + } + default: break; + } + return nullptr; +} + +CIntElement* CParticleDataFactory::GetIntElement(CInputStream& in) +{ + FourCC clsId = GetClassID(in); + switch (clsId) + { + case SBIG('KEYE'): + case SBIG('KEYP'): + { + return new CIEKeyframeEmitter(in); + } + case SBIG('DETH'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIEDeath(a, b); + } + case SBIG('CLMP'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CIntElement* c = GetIntElement(in); + return new CIEClamp(a, b, c); + } + case SBIG('CHAN'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CIntElement* c = GetIntElement(in); + return new CIETimeChain(a, b, c); + } + case SBIG('ADD_'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIEAdd(a, b); + } + case SBIG('CNST'): + { + int a = GetInt(in); + return new CIEConstant(a); + } + case SBIG('IMPL'): + { + CIntElement* a = GetIntElement(in); + return new CIEImpulse(a); + } + case SBIG('ILPT'): + { + CIntElement* a = GetIntElement(in); + return new CIELifetimePercent(a); + } + case SBIG('IRND'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIEInitialRandom(a, b); + } + case SBIG('PULS'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CIntElement* c = GetIntElement(in); + CIntElement* d = GetIntElement(in); + return new CIEPulse(a, b, c, d); + } + case SBIG('MULT'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIEMultiply(a, b); + } + case SBIG('SPAH'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + CIntElement* c = GetIntElement(in); + return new CIESampleAndHold(a, b, c); + } + case SBIG('RAND'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIERandom(a, b); + } + case SBIG('TSCL'): + { + CRealElement* a = GetRealElement(in); + return new CIETimeScale(a); + } + case SBIG('GTCP'): + { + return new CIEGTCP; + } + case SBIG('MODU'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIEModulo(a, b); + } + case SBIG('SUB_'): + { + CIntElement* a = GetIntElement(in); + CIntElement* b = GetIntElement(in); + return new CIESubtract(a, b); + } + default: break; + } + return nullptr; +} + CGenDescription* CParticleDataFactory::GetGeneratorDesc(CInputStream& in, CSimplePool* resPool) { std::vector tracker; diff --git a/Runtime/Particle/CParticleDataFactory.hpp b/Runtime/Particle/CParticleDataFactory.hpp index 337eab82c..6c8a67a91 100644 --- a/Runtime/Particle/CParticleDataFactory.hpp +++ b/Runtime/Particle/CParticleDataFactory.hpp @@ -25,25 +25,25 @@ class CIntElement; struct SParticleModel { TToken m_model; - bool m_found; + bool m_found = false; }; struct SChildGeneratorDesc { TToken m_model; - bool m_found; + bool m_found = false; }; struct SSwooshGeneratorDesc { TToken m_model; - bool m_found; + bool m_found = false; }; struct SElectricGeneratorDesc { TToken m_model; - bool m_found; + bool m_found = false; }; class CParticleDataFactory diff --git a/Runtime/Particle/CRealElement.cpp b/Runtime/Particle/CRealElement.cpp index 01d44ec0b..c4b3d37a8 100644 --- a/Runtime/Particle/CRealElement.cpp +++ b/Runtime/Particle/CRealElement.cpp @@ -34,15 +34,14 @@ bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const calcKey = v1 % v2; calcKey += x14_loopStart; } - valOut = x18_keys[calcKey]; } else { int v1 = x10_loopEnd - 1; if (v1 < emitterTime) calcKey = v1; - valOut = x18_keys[calcKey]; } + valOut = x18_keys[calcKey]; } else { @@ -75,7 +74,7 @@ bool CREConstant::GetValue(int frame, float& valOut) const bool CRETimeChain::GetValue(int frame, float& valOut) const { int v; - xc_c->GetValue(frame, v); + xc_swFrame->GetValue(frame, v); if (frame >= v) return x8_b->GetValue(frame, valOut); else @@ -94,9 +93,9 @@ bool CREAdd::GetValue(int frame, float& valOut) const bool CREClamp::GetValue(int frame, float &valOut) const { float a, b; - x4_a->GetValue(frame, a); - x8_b->GetValue(frame, b); - xc_c->GetValue(frame, valOut); + x4_min->GetValue(frame, a); + x8_max->GetValue(frame, b); + xc_val->GetValue(frame, valOut); if (valOut > b) valOut = b; if (valOut < a) diff --git a/Runtime/Particle/CRealElement.hpp b/Runtime/Particle/CRealElement.hpp index d3d293e69..24a7d4506 100644 --- a/Runtime/Particle/CRealElement.hpp +++ b/Runtime/Particle/CRealElement.hpp @@ -29,10 +29,10 @@ class CRETimeChain : public CRealElement { std::unique_ptr x4_a; std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr xc_swFrame; public: CRETimeChain(CRealElement* a, CRealElement* b, CIntElement* c) - : x4_a(a), x8_b(b), xc_c(c) {} + : x4_a(a), x8_b(b), xc_swFrame(c) {} bool GetValue(int frame, float& valOut) const; }; @@ -48,12 +48,12 @@ public: class CREClamp : public CRealElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr x4_min; + std::unique_ptr x8_max; + std::unique_ptr xc_val; public: CREClamp(CRealElement* a, CRealElement* b, CRealElement* c) - : x4_a(a), x8_b(b), xc_c(c) {} + : x4_min(a), x8_max(b), xc_val(c) {} bool GetValue(int frame, float& valOut) const; }; @@ -73,62 +73,107 @@ public: class CREInitialRandom : public CRealElement { + std::unique_ptr x4_min; + std::unique_ptr x8_max; public: + CREInitialRandom(CRealElement* a, CRealElement* b) + : x4_min(a), x8_max(b) {} bool GetValue(int frame, float& valOut) const; bool IsConstant() const {return true;} }; class CRERandom : public CRealElement { + std::unique_ptr x4_min; + std::unique_ptr x8_max; public: + CRERandom(CRealElement* a, CRealElement* b) + : x4_min(a), x8_max(b) {} bool GetValue(int frame, float& valOut) const; }; class CREMultiply : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CREMultiply(CRealElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, float& valOut) const; }; class CREPulse : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CREPulse(CIntElement* a, CIntElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, float& valOut) const; }; class CRETimeScale : public CRealElement { + std::unique_ptr x4_a; public: + CRETimeScale(CRealElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CRELifetimePercent : public CRealElement { + std::unique_ptr x4_a; public: + CRELifetimePercent(CRealElement* a) + : x4_a(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; public: + CRESineWave(CRealElement* a, CRealElement* b, CRealElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, float& valOut) const; }; class CREISWT : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CREISWT(CRealElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, float& valOut) const; }; class CRECompareLessThan : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CRECompareLessThan(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, float& valOut) const; }; class CRECompareEquals : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CRECompareEquals(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, float& valOut) const; }; @@ -200,43 +245,66 @@ public: class CRESubtract : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CRESubtract(CRealElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, float& valOut) const; }; class CREVectorMagnitude : public CRealElement { + std::unique_ptr x4_a; public: + CREVectorMagnitude(CVectorElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CREVectorXToReal : public CRealElement { + std::unique_ptr x4_a; public: + CREVectorXToReal(CVectorElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CREVectorYToReal : public CRealElement { + std::unique_ptr x4_a; public: + CREVectorYToReal(CVectorElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CREVectorZToReal : public CRealElement { + std::unique_ptr x4_a; public: + CREVectorZToReal(CVectorElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CRECEXT : public CRealElement { + std::unique_ptr x4_a; public: + CRECEXT(CIntElement* a) + : x4_a(a) {} bool GetValue(int frame, float& valOut) const; }; class CREITRL : public CRealElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CREITRL(CIntElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, float& valOut) const; }; diff --git a/Runtime/Particle/CUVElement.cpp b/Runtime/Particle/CUVElement.cpp index e69de29bb..c07aa0f57 100644 --- a/Runtime/Particle/CUVElement.cpp +++ b/Runtime/Particle/CUVElement.cpp @@ -0,0 +1,62 @@ +#include "CUVElement.hpp" + +namespace Retro +{ + +CUVEAnimTexture::CUVEAnimTexture(TToken&& tex, CIntElement* a, CIntElement* b, + CIntElement* c, CIntElement* d, CIntElement* e, bool f) +: x4_tex(std::move(tex)), xc_directTex(x4_tex.GetObj()), x24_loop(f), x28_cycleFrameRate(e) +{ + a->GetValue(0, x10_tileW); + delete a; + b->GetValue(0, x14_tileW); + delete b; + c->GetValue(0, x18_strideW); + delete c; + d->GetValue(0, x1c_strideH); + delete d; + + int width = xc_directTex->GetWidth(); + int height = xc_directTex->GetHeight(); + float widthF = width; + float heightF = height; + int xTiles = std::max(1, width / x18_strideW); + int yTiles = std::max(1, height / x1c_strideH); + x20_tiles = xTiles * yTiles; + x2c_uvElems.reserve(x20_tiles); + for (int y=yTiles-1 ; y>=0 ; --y) + { + for (int x=0 ; xGetValue(frame, cv); + float cvf = cv / float(x20_tiles); + cvf = frame / cvf; + + int tile = cvf; + if (x24_loop) + { + if (cvf >= x20_tiles) + tile = int(cvf) % x20_tiles; + } + else + { + if (cvf >= x20_tiles) + tile = x20_tiles - 1; + } + + valOut = x2c_uvElems[tile]; +} + +} diff --git a/Runtime/Particle/CUVElement.hpp b/Runtime/Particle/CUVElement.hpp index 07b699934..9280ee112 100644 --- a/Runtime/Particle/CUVElement.hpp +++ b/Runtime/Particle/CUVElement.hpp @@ -2,11 +2,21 @@ #define __RETRO_CUVELEMENT_HPP__ #include "IElement.hpp" +#include "CToken.hpp" +#include "CTexture.hpp" namespace Retro { class CToken; +struct SUVElementTexture +{ + TToken m_tex; + CTexture* m_directTex; + SUVElementTexture(TToken&& tex, CTexture* directTex) + : m_tex(std::move(tex)), m_directTex(directTex) {} +}; + struct SUVElementSet { float xMin, yMin, xMax, yMax; @@ -15,22 +25,50 @@ struct SUVElementSet class CUVElement : public IElement { public: - virtual CToken GetValueTexture(int frame) const=0; + virtual SUVElementTexture GetValueTexture(int frame) const=0; virtual void GetValueUV(int frame, SUVElementSet& valOut) const=0; + virtual bool HasConstantTexture() const=0; + virtual bool HasConstantUV() const=0; }; struct CUVEConstant : public CUVElement { + TToken x4_tex; + CTexture* xc_directTex; public: - CToken GetValueTexture(int frame) const; - void GetValueUV(int frame, SUVElementSet& valOut) const; + CUVEConstant(TToken&& tex) + : x4_tex(std::move(tex)), xc_directTex(x4_tex.GetObj()) {} + SUVElementTexture GetValueTexture(int frame) const + { + return SUVElementTexture(TLockedToken(x4_tex), xc_directTex); + } + void GetValueUV(int frame, SUVElementSet& valOut) const + { + valOut = {0.f, 0.f, 1.f, 1.f}; + } + bool HasConstantTexture() const {return true;} + bool HasConstantUV() const {return true;} }; struct CUVEAnimTexture : public CUVElement { + TToken x4_tex; + CTexture* xc_directTex; + int x10_tileW, x14_tileW, x18_strideW, x1c_strideH; + int x20_tiles; + bool x24_loop; + std::unique_ptr x28_cycleFrameRate; + std::vector x2c_uvElems; public: - CToken GetValueTexture(int frame) const; + CUVEAnimTexture(TToken&& tex, CIntElement* a, CIntElement* b, + CIntElement* c, CIntElement* d, CIntElement* e, bool f); + SUVElementTexture GetValueTexture(int frame) const + { + return SUVElementTexture(TLockedToken(x4_tex), xc_directTex); + } void GetValueUV(int frame, SUVElementSet& valOut) const; + bool HasConstantTexture() const {return true;} + bool HasConstantUV() const {return false;} }; } diff --git a/Runtime/Particle/CVectorElement.hpp b/Runtime/Particle/CVectorElement.hpp index 5cbf3be76..8cda91b6f 100644 --- a/Runtime/Particle/CVectorElement.hpp +++ b/Runtime/Particle/CVectorElement.hpp @@ -2,81 +2,141 @@ #define __RETRO_CVECTORELEMENT_HPP__ #include "IElement.hpp" -#include "CVector3f.hpp" namespace Retro { class CVECone : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CVECone(CVectorElement* a, CRealElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVETimeChain : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CVETimeChain(CVectorElement* a, CVectorElement* b, CIntElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEAngleCone : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + std::unique_ptr x14_e; public: + CVEAngleCone(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d, CRealElement* e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEAdd : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CVEAdd(CVectorElement* a, CVectorElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVECircleCluster : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CVECircleCluster(CVectorElement* a, CVectorElement* b, CIntElement* c, CRealElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEConstant : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; public: + CVEConstant(CRealElement* a, CRealElement* b, CRealElement* c) + : x4_a(a), x8_b(b), xc_c(c) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEFastConstant : public CVectorElement { + Zeus::CVector3f x4_val; public: + CVEFastConstant(float a, float b, float c) : x4_val(a, b, c) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; bool IsFastConstant() const {return true;} }; class CVECircle : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; + std::unique_ptr x14_e; public: + CVECircle(CVectorElement* a, CVectorElement* b, CRealElement* c, CRealElement* d, CRealElement* e) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d), x14_e(e) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEKeyframeEmitter : public CVectorElement { + u32 x4_percent; + u32 x8_unk1; + bool xc_loop; + bool xd_unk2; + u32 x10_loopEnd; + u32 x14_loopStart; + std::vector x18_keys; public: + CVEKeyframeEmitter(CInputStream& in); bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEMultiply : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; public: + CVEMultiply(CVectorElement* a, CVectorElement* b) + : x4_a(a), x8_b(b) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVERealToVector : public CVectorElement { + std::unique_ptr x4_a; public: + CVERealToVector(CRealElement* a) + : x4_a(a) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; class CVEPulse : public CVectorElement { + std::unique_ptr x4_a; + std::unique_ptr x8_b; + std::unique_ptr xc_c; + std::unique_ptr x10_d; public: + CVEPulse(CIntElement* a, CIntElement* b, CVectorElement* c, CVectorElement* d) + : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; @@ -88,7 +148,10 @@ public: class CVESPOS : public CVectorElement { + std::unique_ptr x4_a; public: + CVESPOS(CVectorElement* a) + : x4_a(a) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; diff --git a/Runtime/Particle/IElement.hpp b/Runtime/Particle/IElement.hpp index 4eebf6e50..007c406a3 100644 --- a/Runtime/Particle/IElement.hpp +++ b/Runtime/Particle/IElement.hpp @@ -48,6 +48,10 @@ public: virtual bool GetValue(int frame, Zeus::CColor& colorOut) const=0; }; +class CEmitterElement : public IElement +{ +}; + } #endif // __RETRO_IELEMENT_HPP__