diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp index 2dc36ec52..cc8876fa6 100644 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ b/DataSpec/DNACommon/ParticleCommon.cpp @@ -119,7 +119,7 @@ void RealElementFactory::read(Athena::io::YAMLDocReader& r) m_elem.reset(new struct RECEXT); break; case SBIG('ITRL'): - m_elem.reset(new struct REITRL); + m_elem.reset(new struct REIntTimesReal); break; default: m_elem.reset(); @@ -252,7 +252,7 @@ void RealElementFactory::read(Athena::io::IStreamReader& r) m_elem.reset(new struct RECEXT); break; case SBIG('ITRL'): - m_elem.reset(new struct REITRL); + m_elem.reset(new struct REIntTimesReal); break; case SBIG('NONE'): m_elem.reset(); diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp index faaf03ed9..c7e27e0d5 100644 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ b/DataSpec/DNACommon/ParticleCommon.hpp @@ -372,7 +372,7 @@ struct RECEXT : IRealElement const char* ClassID() const {return "CEXT";} }; -struct REITRL : IRealElement +struct REIntTimesReal : IRealElement { DECL_YAML IntElementFactory a; diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 7d895b873..ad1e51da2 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -89,6 +89,10 @@ public: x3_loading = false; return x10_object; } + const SObjectTag& GetObjectTag() const + { + return x4_objTag; + } ~CObjectReference() { if (x10_object) @@ -103,6 +107,7 @@ class CToken CObjectReference* x0_objRef = nullptr; bool x4_lockHeld = false; public: + operator bool() const {return x0_objRef != nullptr;} void Unlock() { if (x0_objRef && x4_lockHeld) @@ -157,7 +162,7 @@ public: other.x4_lockHeld = false; return *this; } - CToken() {} + CToken() = default; CToken(const CToken& other) : x0_objRef(other.x0_objRef) { @@ -180,6 +185,12 @@ public: x0_objRef = obj; ++x0_objRef->x0_refCount; } + const SObjectTag* GetObjectTag() const + { + if (!x0_objRef) + return nullptr; + return &x0_objRef->GetObjectTag(); + } ~CToken() { if (x0_objRef) @@ -199,7 +210,7 @@ public: { return TObjOwnerDerivedFromIObj::GetNewDerivedObject(std::move(obj)); } - TToken() {} + TToken() = default; TToken(const CToken& other) : CToken(other) {} TToken(T* obj) : CToken(GetIObjObjectFor(std::unique_ptr(obj))) {} diff --git a/Runtime/Particle/CIntElement.cpp b/Runtime/Particle/CIntElement.cpp index e69de29bb..db544400d 100644 --- a/Runtime/Particle/CIntElement.cpp +++ b/Runtime/Particle/CIntElement.cpp @@ -0,0 +1,231 @@ +#include "CIntElement.hpp" +#include "CParticleGlobals.hpp" +#include "CRandom16.hpp" + +namespace Retro +{ + +CIEKeyframeEmitter::CIEKeyframeEmitter(CInputStream& in) +{ + x4_percent = in.readUint32Big(); + x8_unk1 = in.readUint32Big(); + xc_loop = in.readBool(); + xd_unk2 = in.readBool(); + x10_loopEnd = in.readUint32Big(); + x14_loopStart = in.readUint32Big(); + + u32 count = in.readUint32Big(); + x18_keys.reserve(count); + for (u32 i=0 ; i= x10_loopEnd) + { + int v1 = emitterTime - x14_loopStart; + int v2 = x10_loopEnd - x14_loopStart; + calcKey = v1 % v2; + calcKey += x14_loopStart; + } + } + else + { + int v1 = x10_loopEnd - 1; + if (v1 < emitterTime) + calcKey = v1; + } + valOut = x18_keys[calcKey]; + } + else + { + int ltPerc = CParticleGlobals::g_particleLifetimePercentTweenInt; + float ltPercRem = CParticleGlobals::g_particleLifetimePercentTweenIntFloatRem; + if (ltPerc == 100) + valOut = x18_keys[100]; + else + valOut = ltPercRem * x18_keys[ltPerc+1] + (1.0f - ltPercRem) * x18_keys[ltPerc]; + } + return false; +} + +bool CIEDeath::GetValue(int frame, int &valOut) const +{ + x4_a->GetValue(frame, valOut); + int b; + x8_b->GetValue(frame, b); + /* Not 100% sure about this, originally some kinda branchless comparison */ + return frame > b; +} + +bool CIEClamp::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_min->GetValue(frame, a); + x8_max->GetValue(frame, b); + xc_val->GetValue(frame, valOut); + if (valOut > b) + valOut = b; + if (valOut < a) + valOut = a; + return false; +} + +bool CIETimeChain::GetValue(int frame, int& valOut) const +{ + int v; + xc_swFrame->GetValue(frame, v); + if (frame >= v) + return x8_b->GetValue(frame, valOut); + else + return x4_a->GetValue(frame, valOut); +} + +bool CIEAdd::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a + b; + return false; +} + +bool CIEConstant::GetValue(int frame, int& valOut) const +{ + valOut = x4_val; + return false; +} + +bool CIEImpulse::GetValue(int frame, int& valOut) const +{ + if (frame == 0) + x4_a->GetValue(frame, valOut); + else + valOut = 0; + return false; +} + +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_particleLifetimeFloat; + return false; +} + +bool CIEInitialRandom::GetValue(int frame, int& valOut) const +{ + if (frame == 0) + { + int a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = CRandom16::GetRandomNumber()->Range(a, b); + } + return false; +} + +bool CIEPulse::GetValue(int frame, int& 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_bVal->GetValue(frame, valOut); + else + xc_aVal->GetValue(frame, valOut); + } + else + xc_aVal->GetValue(frame, valOut); + + return false; +} + + +bool CIEMultiply::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a * b; + return false; +} + +bool CIESampleAndHold::GetValue(int frame, int& valOut) const +{ + if (x8_nextSampleFrame < frame) + { + int b, c; + xc_waitFramesMin->GetValue(frame, b); + x10_waitFramesMax->GetValue(frame, c); + /* const-correctness, who needs it? */ + ((CIESampleAndHold*)this)->x8_nextSampleFrame = CRandom16::GetRandomNumber()->Range(b, c) + frame; + x4_sampleSource->GetValue(frame, valOut); + ((CIESampleAndHold*)this)->x14_holdVal = valOut; + } + else + valOut = x14_holdVal; + return false; +} + +bool CIERandom::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_min->GetValue(frame, a); + x8_max->GetValue(frame, b); + if (frame > 0) + valOut = CRandom16::GetRandomNumber()->Range(a, b); + else + valOut = CRandom16::GetRandomNumber()->Next(); + return false; +} + +bool CIETimeScale::GetValue(int frame, int& valOut) const +{ + float a; + x4_a->GetValue(frame, a); + valOut = float(frame) * a; + return false; +} + +bool CIEGTCP::GetValue(int frame, int& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CIEModulo::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + if (b != 0) + valOut = a % b; + else + valOut = a; + return false; +} + +bool CIESubtract::GetValue(int frame, int& valOut) const +{ + int a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a - b; + return false; +} + +} diff --git a/Runtime/Particle/CIntElement.hpp b/Runtime/Particle/CIntElement.hpp index 6dee4a2f3..61bd45b4b 100644 --- a/Runtime/Particle/CIntElement.hpp +++ b/Runtime/Particle/CIntElement.hpp @@ -45,10 +45,10 @@ class CIETimeChain : public CIntElement { std::unique_ptr x4_a; std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr xc_swFrame; public: CIETimeChain(CIntElement* a, CIntElement* 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, int& valOut) const; }; @@ -81,10 +81,10 @@ public: class CIELifetimePercent : public CIntElement { - std::unique_ptr x4_a; + std::unique_ptr x4_percentVal; public: CIELifetimePercent(CIntElement* a) - : x4_a(a) {} + : x4_percentVal(a) {} bool GetValue(int frame, int& valOut) const; }; @@ -100,13 +100,13 @@ public: class CIEPulse : public CIntElement { - 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_aVal; + std::unique_ptr x10_bVal; public: CIEPulse(CIntElement* a, CIntElement* b, CIntElement* c, CIntElement* d) - : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} + : x4_aDuration(a), x8_bDuration(b), xc_aVal(c), x10_bVal(d) {} bool GetValue(int frame, int& valOut) const; }; @@ -122,22 +122,24 @@ public: class CIESampleAndHold : public CIntElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr x4_sampleSource; + int x8_nextSampleFrame = 0; + std::unique_ptr xc_waitFramesMin; + std::unique_ptr x10_waitFramesMax; + int x14_holdVal; public: CIESampleAndHold(CIntElement* a, CIntElement* b, CIntElement* c) - : x4_a(a), x8_b(b), xc_c(c) {} + : x4_sampleSource(a), xc_waitFramesMin(b), x10_waitFramesMax(c) {} bool GetValue(int frame, int& valOut) const; }; class CIERandom : public CIntElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; + std::unique_ptr x4_min; + std::unique_ptr x8_max; public: CIERandom(CIntElement* a, CIntElement* b) - : x4_a(a), x8_b(b) {} + : x4_min(a), x8_max(b) {} bool GetValue(int frame, int& valOut) const; }; diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index 18e4d93d7..ad88b0c5b 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -37,25 +37,25 @@ SParticleModel CParticleDataFactory::GetModel(CInputStream& in, CSimplePool* res FourCC clsId = GetClassID(in); if (clsId == SBIG('NONE')) return {}; - TResID id = in.readUint32Big(); + 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) +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) +SChildGeneratorDesc CParticleDataFactory::GetChildGeneratorDesc(CInputStream& in, CSimplePool* resPool, const std::vector& tracker) { FourCC clsId = GetClassID(in); if (clsId == SBIG('NONE')) return {}; - TResID id = in.readUint32Big(); + TResId id = in.readUint32Big(); if (!id) return {}; return GetChildGeneratorDesc(id, resPool, tracker); @@ -66,7 +66,7 @@ SSwooshGeneratorDesc CParticleDataFactory::GetSwooshGeneratorDesc(CInputStream& FourCC clsId = GetClassID(in); if (clsId == SBIG('NONE')) return {}; - TResID id = in.readUint32Big(); + TResId id = in.readUint32Big(); if (!id) return {}; return {resPool->GetObj({FOURCC('SWHC'), id}), true}; @@ -77,7 +77,7 @@ SElectricGeneratorDesc CParticleDataFactory::GetElectricGeneratorDesc(CInputStre FourCC clsId = GetClassID(in); if (clsId == SBIG('NONE')) return {}; - TResID id = in.readUint32Big(); + TResId id = in.readUint32Big(); if (!id) return {}; return {resPool->GetObj({FOURCC('ELSC'), id}), true}; @@ -93,7 +93,7 @@ CUVElement* CParticleDataFactory::GetTextureElement(CInputStream& in, CSimplePoo FourCC subId = GetClassID(in); if (subId == SBIG('NONE')) return nullptr; - TResID id = in.readUint32Big(); + TResId id = in.readUint32Big(); TToken txtr = resPool->GetObj({FOURCC('TXTR'), id}); return new CUVEConstant(std::move(txtr)); } @@ -102,7 +102,7 @@ CUVElement* CParticleDataFactory::GetTextureElement(CInputStream& in, CSimplePoo FourCC subId = GetClassID(in); if (subId == SBIG('NONE')) return nullptr; - TResID id = in.readUint32Big(); + TResId id = in.readUint32Big(); CIntElement* a = GetIntElement(in); CIntElement* b = GetIntElement(in); CIntElement* c = GetIntElement(in); @@ -643,7 +643,7 @@ CRealElement* CParticleDataFactory::GetRealElement(CInputStream& in) { CIntElement* a = GetIntElement(in); CRealElement* b = GetRealElement(in); - return new CREITRL(a, b); + return new CREIntTimesReal(a, b); } default: break; } @@ -762,13 +762,13 @@ CIntElement* CParticleDataFactory::GetIntElement(CInputStream& in) CGenDescription* CParticleDataFactory::GetGeneratorDesc(CInputStream& in, CSimplePool* resPool) { - std::vector tracker; + std::vector tracker; tracker.reserve(8); return CreateGeneratorDescription(in, tracker, 0, resPool); } -CGenDescription* CParticleDataFactory::CreateGeneratorDescription(CInputStream& in, std::vector& tracker, - TResID resId, CSimplePool* resPool) +CGenDescription* CParticleDataFactory::CreateGeneratorDescription(CInputStream& in, std::vector& tracker, + TResId resId, CSimplePool* resPool) { if (std::count(tracker.cbegin(), tracker.cend(), resId) == 0) { @@ -786,7 +786,7 @@ CGenDescription* CParticleDataFactory::CreateGeneratorDescription(CInputStream& } bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& in, - std::vector& tracker, CSimplePool* resPool) + std::vector& tracker, CSimplePool* resPool) { FourCC clsId = GetClassID(in); while (clsId != SBIG('_END')) diff --git a/Runtime/Particle/CParticleDataFactory.hpp b/Runtime/Particle/CParticleDataFactory.hpp index c7c8e94b5..aad04199d 100644 --- a/Runtime/Particle/CParticleDataFactory.hpp +++ b/Runtime/Particle/CParticleDataFactory.hpp @@ -49,8 +49,8 @@ struct SElectricGeneratorDesc class CParticleDataFactory { static SParticleModel GetModel(CInputStream& in, CSimplePool* resPool); - static SChildGeneratorDesc GetChildGeneratorDesc(TResID res, CSimplePool* resPool, const std::vector& tracker); - static SChildGeneratorDesc GetChildGeneratorDesc(CInputStream& in, CSimplePool* resPool, const std::vector& tracker); + static SChildGeneratorDesc GetChildGeneratorDesc(TResId res, CSimplePool* resPool, const std::vector& tracker); + static SChildGeneratorDesc GetChildGeneratorDesc(CInputStream& in, CSimplePool* resPool, const std::vector& tracker); static SSwooshGeneratorDesc GetSwooshGeneratorDesc(CInputStream& in, CSimplePool* resPool); static SElectricGeneratorDesc GetElectricGeneratorDesc(CInputStream& in, CSimplePool* resPool); static CUVElement* GetTextureElement(CInputStream& in, CSimplePool* resPool); @@ -68,10 +68,10 @@ class CParticleDataFactory public: static CGenDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool); - static CGenDescription* CreateGeneratorDescription(CInputStream& in, std::vector& tracker, - TResID resId, CSimplePool* resPool); + static CGenDescription* CreateGeneratorDescription(CInputStream& in, std::vector& tracker, + TResId resId, CSimplePool* resPool); static bool CreateGPSM(CGenDescription* fillDesc, CInputStream& in, - std::vector& tracker, CSimplePool* resPool); + std::vector& tracker, CSimplePool* resPool); static void LoadGPSMTokens(CGenDescription* desc); }; diff --git a/Runtime/Particle/CRealElement.cpp b/Runtime/Particle/CRealElement.cpp index 4990c80a1..041330d13 100644 --- a/Runtime/Particle/CRealElement.cpp +++ b/Runtime/Particle/CRealElement.cpp @@ -2,7 +2,6 @@ #include "CParticleGlobals.hpp" #include "CRandom16.hpp" #include -#include namespace Retro { @@ -53,7 +52,7 @@ bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const if (ltPerc == 100) valOut = x18_keys[100]; else - valOut = x18_keys[ltPerc+1] * ltPercRem + (1.0f - ltPercRem) * x18_keys[ltPerc]; + valOut = ltPercRem * x18_keys[ltPerc+1] + (1.0f - ltPercRem) * x18_keys[ltPerc]; } return false; } @@ -307,7 +306,7 @@ bool CRECEXT::GetValue(int frame, float& valOut) const return false; } -bool CREITRL::GetValue(int frame, float& valOut) const +bool CREIntTimesReal::GetValue(int frame, float& valOut) const { int a; x4_a->GetValue(frame, a); diff --git a/Runtime/Particle/CRealElement.hpp b/Runtime/Particle/CRealElement.hpp index e9af25079..9207401d8 100644 --- a/Runtime/Particle/CRealElement.hpp +++ b/Runtime/Particle/CRealElement.hpp @@ -292,12 +292,12 @@ public: bool GetValue(int frame, float& valOut) const; }; -class CREITRL : public CRealElement +class CREIntTimesReal : public CRealElement { std::unique_ptr x4_a; std::unique_ptr x8_b; public: - CREITRL(CIntElement* a, CRealElement* b) + CREIntTimesReal(CIntElement* a, CRealElement* b) : x4_a(a), x8_b(b) {} bool GetValue(int frame, float& valOut) const; }; diff --git a/Runtime/Particle/CVectorElement.cpp b/Runtime/Particle/CVectorElement.cpp index e69de29bb..ee71f5e07 100644 --- a/Runtime/Particle/CVectorElement.cpp +++ b/Runtime/Particle/CVectorElement.cpp @@ -0,0 +1,215 @@ +#include "CVectorElement.hpp" +#include "CParticleGlobals.hpp" +#include "CRandom16.hpp" +#include + +namespace Retro +{ + +CVEKeyframeEmitter::CVEKeyframeEmitter(CInputStream& in) +{ + x4_percent = in.readUint32Big(); + x8_unk1 = in.readUint32Big(); + xc_loop = in.readBool(); + xd_unk2 = in.readBool(); + x10_loopEnd = in.readUint32Big(); + x14_loopStart = in.readUint32Big(); + + u32 count = in.readUint32Big(); + x18_keys.reserve(count); + for (u32 i=0 ; i= x10_loopEnd) + { + int v1 = emitterTime - x14_loopStart; + int v2 = x10_loopEnd - x14_loopStart; + calcKey = v1 % v2; + calcKey += x14_loopStart; + } + } + else + { + int v1 = x10_loopEnd - 1; + if (v1 < emitterTime) + calcKey = v1; + } + valOut = x18_keys[calcKey]; + } + else + { + int ltPerc = CParticleGlobals::g_particleLifetimePercentTweenInt; + float ltPercRem = CParticleGlobals::g_particleLifetimePercentTweenIntFloatRem; + if (ltPerc == 100) + valOut = x18_keys[100]; + else + valOut = ltPercRem * x18_keys[ltPerc+1] + (1.0f - ltPercRem) * x18_keys[ltPerc]; + } + return false; +} + +CVECone::CVECone(CVectorElement* a, CRealElement* b) +: x4_direction(a), x8_magnitude(b) +{ + Zeus::CVector3f av; + x4_direction->GetValue(0, av); + Zeus::CVector3f avNorm = av.normalized(); + if (avNorm[0] > 0.8) + xc_xVec = avNorm.cross(Zeus::CVector3f(0.f, 1.f, 0.f)); + else + xc_xVec = avNorm.cross(Zeus::CVector3f(1.f, 0.f, 0.f)); + x18_yVec = avNorm.cross(xc_xVec); +} + +bool CVECone::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + float b; + x8_magnitude->GetValue(frame, b); + Zeus::CVector3f dir; + x4_direction->GetValue(frame, dir); + float b2 = std::min(1.f, b); + + float randX, randY; + do + { + float rand1 = CRandom16::GetRandomNumber()->Float() - 0.5f; + randX = 2.f * b2 * rand1; + float rand2 = CRandom16::GetRandomNumber()->Float() - 0.5f; + randY = 2.f * b2 * rand2; + } while (randX * randX + randY * randY > 1.f); + + valOut = xc_xVec * randX + x18_yVec * randY + dir; + return false; +} + +bool CVETimeChain::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + int v; + xc_swFrame->GetValue(frame, v); + if (frame >= v) + return x8_b->GetValue(frame, valOut); + else + return x4_a->GetValue(frame, valOut); +} + +bool CVEAngleCone::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + float xc, yc, xr, yr; + x4_angleXConstant->GetValue(frame, xc); + x8_angleYConstant->GetValue(frame, yc); + xc_angleXRange->GetValue(frame, xr); + x10_angleYRange->GetValue(frame, yr); + + float xtmp = CRandom16::GetRandomNumber()->Float() * xr; + float xang = (0.5f * xr - xtmp + xc) * M_PI / 180.f; + + float ytmp = CRandom16::GetRandomNumber()->Float() * yr; + float yang = (0.5f * yr - ytmp + yc) * M_PI / 180.f; + + float mag; + x14_magnitude->GetValue(frame, mag); + + /* This takes a +Z vector and rotates it around X and Y axis (like a rotation matrix would) */ + valOut = Zeus::CVector3f(cosf(xang) * -sinf(yang), sinf(xang), cosf(xang) * cosf(yang)) * Zeus::CVector3f(mag); + return false; +} + +bool CVEAdd::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + Zeus::CVector3f a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a + b; + return false; +} + +bool CVECircleCluster::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + + return false; +} + +bool CVEMultiply::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + Zeus::CVector3f a, b; + x4_a->GetValue(frame, a); + x8_b->GetValue(frame, b); + valOut = a * b; + return false; +} + +bool CVERealToVector::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + float a; + x4_a->GetValue(frame, a); + valOut = Zeus::CVector3f(a); + return false; +} + +bool CVEPulse::GetValue(int frame, Zeus::CVector3f& 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_bVal->GetValue(frame, valOut); + else + xc_aVal->GetValue(frame, valOut); + } + else + xc_aVal->GetValue(frame, valOut); + + return false; +} + +bool CVEParticleVelocity::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CVESPOS::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CVEPLCO::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CVEPLOC::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CVEPSOR::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +bool CVEPSOF::GetValue(int frame, Zeus::CVector3f& valOut) const +{ + /* TODO: Do */ + return false; +} + +} diff --git a/Runtime/Particle/CVectorElement.hpp b/Runtime/Particle/CVectorElement.hpp index 8cda91b6f..588136cb5 100644 --- a/Runtime/Particle/CVectorElement.hpp +++ b/Runtime/Particle/CVectorElement.hpp @@ -6,13 +6,28 @@ namespace Retro { +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 CVECone : public CVectorElement { - std::unique_ptr x4_a; - std::unique_ptr x8_b; + std::unique_ptr x4_direction; + std::unique_ptr x8_magnitude; + Zeus::CVector3f xc_xVec; + Zeus::CVector3f x18_yVec; public: - CVECone(CVectorElement* a, CRealElement* b) - : x4_a(a), x8_b(b) {} + CVECone(CVectorElement* a, CRealElement* b); bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; @@ -20,23 +35,23 @@ class CVETimeChain : public CVectorElement { std::unique_ptr x4_a; std::unique_ptr x8_b; - std::unique_ptr xc_c; + std::unique_ptr xc_swFrame; public: CVETimeChain(CVectorElement* a, CVectorElement* 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, 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; + std::unique_ptr x4_angleXConstant; + std::unique_ptr x8_angleYConstant; + std::unique_ptr xc_angleXRange; + std::unique_ptr x10_angleYRange; + std::unique_ptr x14_magnitude; 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) {} + : x4_angleXConstant(a), x8_angleYConstant(b), xc_angleXRange(c), x10_angleYRange(d), x14_magnitude(e) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; @@ -95,20 +110,6 @@ public: 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; @@ -130,13 +131,13 @@ public: class CVEPulse : 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 x4_aDuration; + std::unique_ptr x8_bDuration; + std::unique_ptr xc_aVal; + std::unique_ptr x10_bVal; public: CVEPulse(CIntElement* a, CIntElement* b, CVectorElement* c, CVectorElement* d) - : x4_a(a), x8_b(b), xc_c(c), x10_d(d) {} + : x4_aDuration(a), x8_bDuration(b), xc_aVal(c), x10_bVal(d) {} bool GetValue(int frame, Zeus::CVector3f& valOut) const; }; diff --git a/Runtime/RetroTypes.hpp b/Runtime/RetroTypes.hpp index 19d174d44..8ab0ce6db 100644 --- a/Runtime/RetroTypes.hpp +++ b/Runtime/RetroTypes.hpp @@ -12,12 +12,12 @@ namespace Retro { using FourCC = HECL::FourCC; -using TResID = u32; +using TResId = u32; struct SObjectTag { FourCC type; - TResID id = -1; + TResId id = -1; bool operator!=(const SObjectTag& other) const {return id != other.id;} bool operator==(const SObjectTag& other) const {return id == other.id;} };