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(); version = reader.readUint32Big();
atUint32 loopCount = reader.readUint32Big(); atUint32 loopCount = reader.readUint32Big();
reader.enumerate(loopEvents, loopCount); reader.enumerate(boolPOINodes, loopCount);
uevtEvents.clear(); int32POINodes.clear();
atUint32 uevtCount = reader.readUint32Big(); atUint32 uevtCount = reader.readUint32Big();
reader.enumerate(uevtEvents, uevtCount); reader.enumerate(int32POINodes, uevtCount);
atUint32 effectCount = reader.readUint32Big(); atUint32 effectCount = reader.readUint32Big();
reader.enumerate(effectEvents, effectCount); reader.enumerate(particlePOINodes, effectCount);
if (version == 2) if (version == 2)
{ {
atUint32 sfxCount = reader.readUint32Big(); 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(version);
writer.writeUint32Big(loopEvents.size()); writer.writeUint32Big(boolPOINodes.size());
writer.enumerate(loopEvents); writer.enumerate(boolPOINodes);
writer.writeUint32Big(uevtEvents.size()); writer.writeUint32Big(int32POINodes.size());
writer.enumerate(uevtEvents); writer.enumerate(int32POINodes);
writer.writeUint32Big(effectEvents.size()); writer.writeUint32Big(particlePOINodes.size());
writer.enumerate(effectEvents); writer.enumerate(particlePOINodes);
if (version == 2) if (version == 2)
{ {
writer.writeUint32Big(sfxEvents.size()); writer.writeUint32Big(soundPOINodes.size());
writer.enumerate(sfxEvents); writer.enumerate(soundPOINodes);
} }
} }
@ -50,16 +50,16 @@ void EVNT::read(athena::io::YAMLDocReader& reader)
{ {
version = reader.readUint32("version"); version = reader.readUint32("version");
reader.enumerate("loopEvents", loopEvents); reader.enumerate("boolPOINodes", boolPOINodes);
uevtEvents.clear(); int32POINodes.clear();
reader.enumerate("uevtEvents", uevtEvents); reader.enumerate("int32POINodes", int32POINodes);
reader.enumerate("effectEvents", effectEvents); reader.enumerate("particlePOINodes", particlePOINodes);
if (version == 2) 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.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) 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 size_t EVNT::binarySize(size_t __isz) const
{ {
__isz = __EnumerateSize(__isz, loopEvents); __isz = __EnumerateSize(__isz, boolPOINodes);
__isz = __EnumerateSize(__isz, uevtEvents); __isz = __EnumerateSize(__isz, int32POINodes);
__isz = __EnumerateSize(__isz, effectEvents); __isz = __EnumerateSize(__isz, particlePOINodes);
if (version == 2) if (version == 2)
__isz = __EnumerateSize(__isz, sfxEvents); __isz = __EnumerateSize(__isz, soundPOINodes);
return __isz + (version == 2 ? 20 : 16); return __isz + (version == 2 ? 20 : 16);
} }

View File

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

View File

@ -1,8 +1,6 @@
## URDE ## URDE
**Status:** Extract Only **Status:** Extract Only
[![Project Stats](https://www.openhub.net/p/URDE/widgets/project_partner_badge?format=gif)](https://www.openhub.net/p/URDE)
### Download ### 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. 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) 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(); CGenDescription* desc = x1c_genDesc.GetObj();
CIntElement* pswtElem = desc->x10_x4_PSWT.get(); CIntElement* pswtElem = desc->x10_x4_PSWT.get();
if (pswtElem && !x225_28_warmedUp) if (pswtElem && !x225_28_warmedUp)
@ -472,6 +475,7 @@ void CElementGen::Update(double t)
} }
} }
InternalUpdate(t); InternalUpdate(t);
CParticleGlobals::g_currentParticleSystem = prevSystem;
} }
bool CElementGen::InternalUpdate(double dt) bool CElementGen::InternalUpdate(double dt)
@ -806,6 +810,7 @@ void CElementGen::CreateNewParticles(int count)
} }
AccumulateBounds(particle.x4_pos, particle.x2c_lineLengthOrSize); AccumulateBounds(particle.x4_pos, particle.x2c_lineLengthOrSize);
++x260_cumulativeParticles;
++x210_curEmitterFrame; ++x210_curEmitterFrame;
--g_FreeIndex; --g_FreeIndex;
} }
@ -1117,6 +1122,17 @@ void CElementGen::EndLifetime()
ch->SetParticleEmission(false); 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() void CElementGen::BuildParticleSystemBounds()
{ {
zeus::CAABox aabb; zeus::CAABox aabb;
@ -1193,6 +1209,9 @@ u32 CElementGen::GetSystemCount()
void CElementGen::Render() void CElementGen::Render()
{ {
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{ FOURCC('PART'), this };
CParticleGlobals::g_currentParticleSystem = &thisSystem;
CGenDescription* desc = x1c_genDesc.GetObj(); CGenDescription* desc = x1c_genDesc.GetObj();
x22c_backupLightActive = CGraphics::g_LightActive; x22c_backupLightActive = CGraphics::g_LightActive;
@ -1222,6 +1241,7 @@ void CElementGen::Render()
else else
RenderParticles(); RenderParticles();
} }
CParticleGlobals::g_currentParticleSystem = prevSystem;
} }
void CElementGen::RenderModels() void CElementGen::RenderModels()

View File

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

View File

@ -1,7 +1,7 @@
#include "CIntElement.hpp" #include "CIntElement.hpp"
#include "CParticleGlobals.hpp" #include "CParticleGlobals.hpp"
#include "CRandom16.hpp" #include "CRandom16.hpp"
#include "CElementGen.hpp"
/* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Int_Elements */ /* Documentation at: http://www.metroid2002.com/retromodding/wiki/Particle_Script#Int_Elements */
namespace urde namespace urde
@ -203,21 +203,21 @@ bool CIETimeScale::GetValue(int frame, int& valOut) const
return false; 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; 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; 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; return false;
} }

View File

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

View File

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

View File

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

View File

@ -270,46 +270,40 @@ bool CVEParticleVelocity::GetValue(int /*frame*/, zeus::CVector3f& valOut) const
return false; 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; valOut = CElementGen::g_currentParticle->x10_prevPos;
return false; 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; valOut = CElementGen::g_currentParticle->x4_pos;
return false; 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(); 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; 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(); 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; 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(); 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; 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(); valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetTranslation();
return false; return false;

View File

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