All int elements implemented

This commit is contained in:
Jack Andersen 2016-02-06 14:19:59 -10:00
parent 8fbe6a953c
commit 7ae8d21c55
9 changed files with 444 additions and 46 deletions

View File

@ -119,7 +119,7 @@ void RealElementFactory::read(Athena::io::YAMLDocReader& r)
m_elem.reset(new struct RECEXT); m_elem.reset(new struct RECEXT);
break; break;
case SBIG('ITRL'): case SBIG('ITRL'):
m_elem.reset(new struct REITRL); m_elem.reset(new struct REIntTimesReal);
break; break;
default: default:
m_elem.reset(); m_elem.reset();
@ -252,7 +252,7 @@ void RealElementFactory::read(Athena::io::IStreamReader& r)
m_elem.reset(new struct RECEXT); m_elem.reset(new struct RECEXT);
break; break;
case SBIG('ITRL'): case SBIG('ITRL'):
m_elem.reset(new struct REITRL); m_elem.reset(new struct REIntTimesReal);
break; break;
case SBIG('NONE'): case SBIG('NONE'):
m_elem.reset(); m_elem.reset();

View File

@ -372,7 +372,7 @@ struct RECEXT : IRealElement
const char* ClassID() const {return "CEXT";} const char* ClassID() const {return "CEXT";}
}; };
struct REITRL : IRealElement struct REIntTimesReal : IRealElement
{ {
DECL_YAML DECL_YAML
IntElementFactory a; IntElementFactory a;

View File

@ -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<count ; ++i)
x18_keys.push_back(in.readUint32Big());
}
bool CIEKeyframeEmitter::GetValue(int frame, int& valOut) const
{
if (!x4_percent)
{
int emitterTime = CParticleGlobals::g_emitterTimeInt;
int calcKey = emitterTime;
if (xc_loop)
{
if (emitterTime >= 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;
}
}

View File

@ -45,10 +45,10 @@ class CIETimeChain : public CIntElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_a;
std::unique_ptr<CIntElement> x8_b; std::unique_ptr<CIntElement> x8_b;
std::unique_ptr<CIntElement> xc_c; std::unique_ptr<CIntElement> xc_swFrame;
public: public:
CIETimeChain(CIntElement* a, CIntElement* b, CIntElement* c) 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; bool GetValue(int frame, int& valOut) const;
}; };
@ -81,10 +81,10 @@ public:
class CIELifetimePercent : public CIntElement class CIELifetimePercent : public CIntElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_percentVal;
public: public:
CIELifetimePercent(CIntElement* a) CIELifetimePercent(CIntElement* a)
: x4_a(a) {} : x4_percentVal(a) {}
bool GetValue(int frame, int& valOut) const; bool GetValue(int frame, int& valOut) const;
}; };
@ -100,13 +100,13 @@ public:
class CIEPulse : public CIntElement class CIEPulse : public CIntElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_aDuration;
std::unique_ptr<CIntElement> x8_b; std::unique_ptr<CIntElement> x8_bDuration;
std::unique_ptr<CIntElement> xc_c; std::unique_ptr<CIntElement> xc_aVal;
std::unique_ptr<CIntElement> x10_d; std::unique_ptr<CIntElement> x10_bVal;
public: public:
CIEPulse(CIntElement* a, CIntElement* b, CIntElement* c, CIntElement* d) 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; bool GetValue(int frame, int& valOut) const;
}; };
@ -122,22 +122,24 @@ public:
class CIESampleAndHold : public CIntElement class CIESampleAndHold : public CIntElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_sampleSource;
std::unique_ptr<CIntElement> x8_b; int x8_nextSampleFrame = 0;
std::unique_ptr<CIntElement> xc_c; std::unique_ptr<CIntElement> xc_waitFramesMin;
std::unique_ptr<CIntElement> x10_waitFramesMax;
int x14_holdVal;
public: public:
CIESampleAndHold(CIntElement* a, CIntElement* b, CIntElement* c) 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; bool GetValue(int frame, int& valOut) const;
}; };
class CIERandom : public CIntElement class CIERandom : public CIntElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_min;
std::unique_ptr<CIntElement> x8_b; std::unique_ptr<CIntElement> x8_max;
public: public:
CIERandom(CIntElement* a, CIntElement* b) CIERandom(CIntElement* a, CIntElement* b)
: x4_a(a), x8_b(b) {} : x4_min(a), x8_max(b) {}
bool GetValue(int frame, int& valOut) const; bool GetValue(int frame, int& valOut) const;
}; };

View File

@ -643,7 +643,7 @@ CRealElement* CParticleDataFactory::GetRealElement(CInputStream& in)
{ {
CIntElement* a = GetIntElement(in); CIntElement* a = GetIntElement(in);
CRealElement* b = GetRealElement(in); CRealElement* b = GetRealElement(in);
return new CREITRL(a, b); return new CREIntTimesReal(a, b);
} }
default: break; default: break;
} }

View File

@ -2,7 +2,6 @@
#include "CParticleGlobals.hpp" #include "CParticleGlobals.hpp"
#include "CRandom16.hpp" #include "CRandom16.hpp"
#include <math.h> #include <math.h>
#include <float.h>
namespace Retro namespace Retro
{ {
@ -53,7 +52,7 @@ bool CREKeyframeEmitter::GetValue(int frame, float& valOut) const
if (ltPerc == 100) if (ltPerc == 100)
valOut = x18_keys[100]; valOut = x18_keys[100];
else 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; return false;
} }
@ -307,7 +306,7 @@ bool CRECEXT::GetValue(int frame, float& valOut) const
return false; return false;
} }
bool CREITRL::GetValue(int frame, float& valOut) const bool CREIntTimesReal::GetValue(int frame, float& valOut) const
{ {
int a; int a;
x4_a->GetValue(frame, a); x4_a->GetValue(frame, a);

View File

@ -292,12 +292,12 @@ public:
bool GetValue(int frame, float& valOut) const; bool GetValue(int frame, float& valOut) const;
}; };
class CREITRL : public CRealElement class CREIntTimesReal : public CRealElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_a;
std::unique_ptr<CRealElement> x8_b; std::unique_ptr<CRealElement> x8_b;
public: public:
CREITRL(CIntElement* a, CRealElement* b) CREIntTimesReal(CIntElement* a, CRealElement* b)
: x4_a(a), x8_b(b) {} : x4_a(a), x8_b(b) {}
bool GetValue(int frame, float& valOut) const; bool GetValue(int frame, float& valOut) const;
}; };

View File

@ -0,0 +1,165 @@
#include "CVectorElement.hpp"
#include "CParticleGlobals.hpp"
#include "CRandom16.hpp"
#include <math.h>
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<count ; ++i)
x18_keys.push_back(in.readFloatBig());
}
bool CVEKeyframeEmitter::GetValue(int frame, Zeus::CVector3f& valOut) const
{
if (!x4_percent)
{
int emitterTime = CParticleGlobals::g_emitterTimeInt;
int calcKey = emitterTime;
if (xc_loop)
{
if (emitterTime >= 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_a(a), x8_b(b)
{
Zeus::CVector3f av;
x4_a->GetValue(0, av);
Zeus::CVector3f avNorm = av.normalized();
if (avNorm[0] > 0.8)
xc_vec1 = av.cross(Zeus::CVector3f(0.f, 1.f, 0.f));
else
xc_vec1 = av.cross(Zeus::CVector3f(1.f, 0.f, 0.f));
x18_vec2 = avNorm.cross(xc_vec1);
}
bool CVECone::GetValue(int frame, Zeus::CVector3f& valOut) const
{
float b;
x8_b->GetValue(frame, b);
Zeus::CVector3f av;
x4_a->GetValue(0, av);
float b2 = std::min(1.f, b);
while (true)
{
float rand = CRandom16::GetRandomNumber()->Float() - 0.5f;
float c = 2.f * b2 * rand;
c = c * c;
}
}
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;
}
}

View File

@ -6,13 +6,28 @@
namespace Retro 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<Zeus::CVector3f> x18_keys;
public:
CVEKeyframeEmitter(CInputStream& in);
bool GetValue(int frame, Zeus::CVector3f& valOut) const;
};
class CVECone : public CVectorElement class CVECone : public CVectorElement
{ {
std::unique_ptr<CVectorElement> x4_a; std::unique_ptr<CVectorElement> x4_a;
std::unique_ptr<CRealElement> x8_b; std::unique_ptr<CRealElement> x8_b;
Zeus::CVector3f xc_vec1;
Zeus::CVector3f x18_vec2;
public: public:
CVECone(CVectorElement* a, CRealElement* b) CVECone(CVectorElement* a, CRealElement* b);
: x4_a(a), x8_b(b) {}
bool GetValue(int frame, Zeus::CVector3f& valOut) const; bool GetValue(int frame, Zeus::CVector3f& valOut) const;
}; };
@ -95,20 +110,6 @@ public:
bool GetValue(int frame, Zeus::CVector3f& valOut) const; 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<Zeus::CVector3f> x18_keys;
public:
CVEKeyframeEmitter(CInputStream& in);
bool GetValue(int frame, Zeus::CVector3f& valOut) const;
};
class CVEMultiply : public CVectorElement class CVEMultiply : public CVectorElement
{ {
std::unique_ptr<CVectorElement> x4_a; std::unique_ptr<CVectorElement> x4_a;
@ -130,13 +131,13 @@ public:
class CVEPulse : public CVectorElement class CVEPulse : public CVectorElement
{ {
std::unique_ptr<CIntElement> x4_a; std::unique_ptr<CIntElement> x4_aDuration;
std::unique_ptr<CIntElement> x8_b; std::unique_ptr<CIntElement> x8_bDuration;
std::unique_ptr<CVectorElement> xc_c; std::unique_ptr<CVectorElement> xc_aVal;
std::unique_ptr<CVectorElement> x10_d; std::unique_ptr<CVectorElement> x10_bVal;
public: public:
CVEPulse(CIntElement* a, CIntElement* b, CVectorElement* c, CVectorElement* d) 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; bool GetValue(int frame, Zeus::CVector3f& valOut) const;
}; };