This commit is contained in:
Jack Andersen 2016-03-18 17:58:34 -10:00
commit 08ccc1be63
11 changed files with 115 additions and 90 deletions

View File

@ -10,19 +10,19 @@ void EVNT::read(athena::io::IStreamReader& reader)
version = reader.readUint32Big();
atUint32 loopCount = reader.readUint32Big();
reader.enumerate(loopEvents, loopCount);
reader.enumerate(boolPOINodes, loopCount);
uevtEvents.clear();
int32POINodes.clear();
atUint32 uevtCount = reader.readUint32Big();
reader.enumerate(uevtEvents, uevtCount);
reader.enumerate(int32POINodes, uevtCount);
atUint32 effectCount = reader.readUint32Big();
reader.enumerate(effectEvents, effectCount);
reader.enumerate(particlePOINodes, effectCount);
if (version == 2)
{
atUint32 sfxCount = reader.readUint32Big();
reader.enumerate(sfxEvents, sfxCount);
reader.enumerate(soundPOINodes, sfxCount);
}
}
@ -30,19 +30,19 @@ void EVNT::write(athena::io::IStreamWriter& writer) const
{
writer.writeUint32Big(version);
writer.writeUint32Big(loopEvents.size());
writer.enumerate(loopEvents);
writer.writeUint32Big(boolPOINodes.size());
writer.enumerate(boolPOINodes);
writer.writeUint32Big(uevtEvents.size());
writer.enumerate(uevtEvents);
writer.writeUint32Big(int32POINodes.size());
writer.enumerate(int32POINodes);
writer.writeUint32Big(effectEvents.size());
writer.enumerate(effectEvents);
writer.writeUint32Big(particlePOINodes.size());
writer.enumerate(particlePOINodes);
if (version == 2)
{
writer.writeUint32Big(sfxEvents.size());
writer.enumerate(sfxEvents);
writer.writeUint32Big(soundPOINodes.size());
writer.enumerate(soundPOINodes);
}
}
@ -50,16 +50,16 @@ void EVNT::read(athena::io::YAMLDocReader& reader)
{
version = reader.readUint32("version");
reader.enumerate("loopEvents", loopEvents);
reader.enumerate("boolPOINodes", boolPOINodes);
uevtEvents.clear();
reader.enumerate("uevtEvents", uevtEvents);
int32POINodes.clear();
reader.enumerate("int32POINodes", int32POINodes);
reader.enumerate("effectEvents", effectEvents);
reader.enumerate("particlePOINodes", particlePOINodes);
if (version == 2)
{
reader.enumerate("sfxEvents", sfxEvents);
reader.enumerate("soundPOINodes", soundPOINodes);
}
}
@ -67,15 +67,15 @@ void EVNT::write(athena::io::YAMLDocWriter& writer) const
{
writer.writeUint32("version", version);
writer.enumerate("loopEvents", loopEvents);
writer.enumerate("boolPOINodes", boolPOINodes);
writer.enumerate("uevtEvents", uevtEvents);
writer.enumerate("int32POINodes", int32POINodes);
writer.enumerate("effectEvents", effectEvents);
writer.enumerate("particlePOINodes", particlePOINodes);
if (version == 2)
{
writer.enumerate("sfxEvents", sfxEvents);
writer.enumerate("soundPOINodes", soundPOINodes);
}
}
@ -86,11 +86,11 @@ const char* EVNT::DNAType()
size_t EVNT::binarySize(size_t __isz) const
{
__isz = __EnumerateSize(__isz, loopEvents);
__isz = __EnumerateSize(__isz, uevtEvents);
__isz = __EnumerateSize(__isz, effectEvents);
__isz = __EnumerateSize(__isz, boolPOINodes);
__isz = __EnumerateSize(__isz, int32POINodes);
__isz = __EnumerateSize(__isz, particlePOINodes);
if (version == 2)
__isz = __EnumerateSize(__isz, sfxEvents);
__isz = __EnumerateSize(__isz, soundPOINodes);
return __isz + (version == 2 ? 20 : 16);
}

View File

@ -15,56 +15,62 @@ struct EVNT : BigYAML
Delete expl;
Value<atUint32> version;
struct EventBase : BigYAML
struct POINode : BigYAML
{
DECL_YAML
Value<atUint16> unk0;
String<-1> name;
Value<atUint16> type;
Value<float> startTime;
Value<atUint32> unk1;
struct CharAnimTime : BigYAML
{
DECL_YAML
Value<float> time;
Value<atUint32> unk1;
};
CharAnimTime animTime;
Value<atUint32> idx;
Value<atUint8> unk2;
Value<bool> unk2;
Value<float> unk3;
Value<atUint32> unk4;
Value<atUint32> unk5;
};
struct LoopEvent : EventBase
struct BoolPOINode : POINode
{
DECL_YAML
Value<atUint8> flag;
Value<atUint8> value;
};
std::vector<LoopEvent> loopEvents;
std::vector<BoolPOINode> boolPOINodes;
struct UEVTEvent : EventBase
struct Int32POINode : POINode
{
DECL_YAML
Value<atUint32> uevtType;
String<-1> boneName;
Value<atUint32> value;
String<-1> locatorName;
};
std::vector<UEVTEvent> uevtEvents;
std::vector<Int32POINode> int32POINodes;
struct EffectEvent : EventBase
struct ParticlePOINode : POINode
{
DECL_YAML
Value<atUint32> frameCount;
Value<atUint32> duration;
DNAFourCC effectType;
UniqueID32 effectId;
String<-1> boneName;
String<-1> locatorName;
Value<float> scale;
Value<atUint32> parentMode;
};
std::vector<EffectEvent> effectEvents;
std::vector<ParticlePOINode> particlePOINodes;
struct SFXEvent : EventBase
struct SoundPOINode : POINode
{
DECL_YAML
Value<atUint32> soundId;
Value<float> smallNum;
Value<float> bigNum;
Value<float> falloff;
Value<float> maxDist;
};
std::vector<SFXEvent> sfxEvents;
std::vector<SoundPOINode> soundPOINodes;
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath)
{

View File

@ -1,8 +1,6 @@
## URDE
**Status:** Extract Only
[![Project Stats](https://www.openhub.net/p/URDE/widgets/project_partner_badge?format=gif)](https://www.openhub.net/p/URDE)
### Download
Precompiled builds of the command-line extraction utility (`hecl`) with embedded dataspec libraries are available at https://github.com/AxioDL/urde/releases. This will give you intermediate dumps of original formats as *blender* and *yaml* representations.

View File

@ -456,6 +456,9 @@ CElementGen::~CElementGen()
void CElementGen::Update(double t)
{
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem { FOURCC('PART'), this };
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CGenDescription* desc = x1c_genDesc.GetObj();
CIntElement* pswtElem = desc->x10_x4_PSWT.get();
if (pswtElem && !x225_28_warmedUp)
@ -472,6 +475,7 @@ void CElementGen::Update(double t)
}
}
InternalUpdate(t);
CParticleGlobals::g_currentParticleSystem = prevSystem;
}
bool CElementGen::InternalUpdate(double dt)
@ -806,6 +810,7 @@ void CElementGen::CreateNewParticles(int count)
}
AccumulateBounds(particle.x4_pos, particle.x2c_lineLengthOrSize);
++x260_cumulativeParticles;
++x210_curEmitterFrame;
--g_FreeIndex;
}
@ -1117,6 +1122,17 @@ void CElementGen::EndLifetime()
ch->SetParticleEmission(false);
}
void CElementGen::ForceParticleCreation(int amount)
{
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{ FOURCC('PART'), this };
CParticleGlobals::g_currentParticleSystem = &thisSystem;
/* This is a guess, but it seems right, retail loads x74 */
CParticleGlobals::SetEmitterTime(x50_curFrame);
CreateNewParticles(amount);
CParticleGlobals::g_currentParticleSystem = prevSystem;
}
void CElementGen::BuildParticleSystemBounds()
{
zeus::CAABox aabb;
@ -1193,6 +1209,9 @@ u32 CElementGen::GetSystemCount()
void CElementGen::Render()
{
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{ FOURCC('PART'), this };
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CGenDescription* desc = x1c_genDesc.GetObj();
x22c_backupLightActive = CGraphics::g_LightActive;
@ -1222,6 +1241,7 @@ void CElementGen::Render()
else
RenderParticles();
}
CParticleGlobals::g_currentParticleSystem = prevSystem;
}
void CElementGen::RenderModels()

View File

@ -128,6 +128,7 @@ private:
std::vector<std::unique_ptr<CElementGen>> x248_finishPartChildren;
int x258_SISY = 16;
int x25c_PISY = 16;
u32 x260_cumulativeParticles = 0; /* Retail */
std::vector<std::unique_ptr<CParticleSwoosh>> x260_swhcChildren;
int x270_SSSD = 0;
zeus::CVector3f x274_SSPO;
@ -196,11 +197,17 @@ public:
CElementGen* ConstructChildParticleSystem(const TToken<CGenDescription>&);
void UpdateLightParameters();
void BuildParticleSystemBounds();
u32 GetEmitterTime() const
{
/* Game returns x74, guessing x50 is what it's asking for */
return x50_curFrame;
}
u32 GetSystemCount();
u32 GetCumulativeParticleCount() const { return x260_cumulativeParticles; }
u32 GetParticleCountAllInternal() const;
u32 GetParticleCountAll() const {return x20c_recursiveParticleCount;}
void EndLifetime();
void ForceParticleCreation(int amount) { CreateNewParticles(amount); }
void ForceParticleCreation(int amount);
bool InternalUpdate(double);
void RenderModels();

View File

@ -1,7 +1,7 @@
#include "CIntElement.hpp"
#include "CParticleGlobals.hpp"
#include "CRandom16.hpp"
#include "CElementGen.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Int_Elements */
namespace urde
@ -203,21 +203,21 @@ bool CIETimeScale::GetValue(int frame, int& valOut) const
return false;
}
bool CIEGTCP::GetValue(int frame, int& valOut) const
bool CIEGetCumulativeParticleCount::GetValue(int frame, int& valOut) const
{
/* TODO: Do */
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetCumulativeParticleCount();
return false;
}
bool CIEGAPC::GetValue(int frame, int &valOut) const
bool CIEGetActiveParticleCount::GetValue(int frame, int &valOut) const
{
/* TODO: Do */
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetParticleCount();
return false;
}
bool CIEGEMT::GetValue(int frame, int &valOut) const
bool CIEGetEmitterTime::GetValue(int frame, int &valOut) const
{
/* TODO: Do */
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetEmitterTime();
return false;
}

View File

@ -154,19 +154,19 @@ public:
bool GetValue(int frame, int& valOut) const;
};
class CIEGTCP : public CIntElement
class CIEGetCumulativeParticleCount : public CIntElement
{
public:
bool GetValue(int frame, int& valOut) const;
};
class CIEGAPC : public CIntElement
class CIEGetActiveParticleCount : public CIntElement
{
public:
bool GetValue(int frame, int &valOut) const;
};
class CIEGEMT : public CIntElement
class CIEGetEmitterTime : public CIntElement
{
public:
bool GetValue(int frame, int &valOut) const;

View File

@ -446,27 +446,27 @@ CVectorElement* CParticleDataFactory::GetVectorElement(CInputStream& in)
}
case SBIG('PLCO'):
{
return new CVEPLCO;
return new CVEParticleColor;
}
case SBIG('PLOC'):
{
return new CVEPLOC;
return new CVEParticleLocation;
}
case SBIG('PSOF'):
{
return new CVEPSOF;
return new CVEParticleSystemOrientationFront;
}
case SBIG('PSOU'):
{
return new CVEPSOU;
return new CVEParticleSystemOrientationUp;
}
case SBIG('PSOR'):
{
return new CVEPSOR;
return new CVEParticleSystemOrientationRight;
}
case SBIG('PSTR'):
{
return new CVEPSTR;
return new CVEParticleSystemTranslation;
}
case SBIG('SUB_'):
{
@ -798,15 +798,15 @@ CIntElement* CParticleDataFactory::GetIntElement(CInputStream& in)
}
case SBIG('GAPC'):
{
return new CIEGAPC;
return new CIEGetActiveParticleCount;
}
case SBIG('GTCP'):
{
return new CIEGTCP;
return new CIEGetCumulativeParticleCount;
}
case SBIG('GEMT'):
{
return new CIEGEMT;
return new CIEGetEmitterTime;
}
case SBIG('MODU'):
{

View File

@ -7,7 +7,7 @@
namespace urde
{
class CParticleGen;
class CElementGen;
class CParticleGlobals
{
public:
@ -43,7 +43,7 @@ public:
struct SParticleSystem
{
FourCC x0_type;
CParticleGen* x4_system;
CElementGen* x4_system;
};
static SParticleSystem* g_currentParticleSystem;

View File

@ -270,46 +270,40 @@ bool CVEParticleVelocity::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
return false;
}
bool CVEPLCO::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleColor::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
valOut = CElementGen::g_currentParticle->x10_prevPos;
return false;
}
bool CVEPLOC::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleLocation::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
valOut = CElementGen::g_currentParticle->x4_pos;
return false;
}
bool CVEPSOF::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleSystemOrientationFront::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
/* TODO: Get front vector */
zeus::CTransform trans= CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation();
valOut.x = trans.m_basis[0].y;
valOut.y = trans.m_basis[1].z;
valOut.z = trans.m_origin.x;
return false;
}
bool CVEPSOU::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleSystemOrientationUp::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
/* TODO: Get up vector */
zeus::CTransform trans= CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation();
valOut.x = trans.m_basis[0].z;
valOut.y = trans.m_basis[1].x;
valOut.z = trans.m_origin.y;
return false;
}
bool CVEPSOR::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleSystemOrientationRight::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
/* TODO: Get right vector */
zeus::CTransform trans= CParticleGlobals::g_currentParticleSystem->x4_system->GetOrientation();
valOut.x = trans.m_basis[0].x;
valOut.y = trans.m_basis[1].y;
valOut.z = trans.m_basis[2].z;
return false;
}
bool CVEPSTR::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
bool CVEParticleSystemTranslation::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
{
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetTranslation();
return false;

View File

@ -149,37 +149,37 @@ public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPLCO : public CVectorElement
class CVEParticleColor : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPLOC : public CVectorElement
class CVEParticleLocation : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPSOF : public CVectorElement
class CVEParticleSystemOrientationFront : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPSOU : public CVectorElement
class CVEParticleSystemOrientationUp : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPSOR : public CVectorElement
class CVEParticleSystemOrientationRight : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;
};
class CVEPSTR : public CVectorElement
class CVEParticleSystemTranslation : public CVectorElement
{
public:
bool GetValue(int frame, zeus::CVector3f& valOut) const;