Added support for gathering dependencies of ANCS and FRME; changed CDependencyGroup to use a vector instead of a set
This commit is contained in:
parent
11a7b86120
commit
3bca8410b0
|
@ -154,6 +154,31 @@ void CAnimSetDependencyTree::Write(IOutputStream& rFile, EIDLength IDLength) con
|
||||||
rFile.WriteLong( mCharacterOffsets[iChar] );
|
rFile.WriteLong( mCharacterOffsets[iChar] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAnimSetDependencyTree::AddCharacter(const SSetCharacter *pkChar)
|
||||||
|
{
|
||||||
|
mCharacterOffsets.push_back( NumDependencies() );
|
||||||
|
if (!pkChar) return;
|
||||||
|
|
||||||
|
AddDependency(pkChar->pModel);
|
||||||
|
AddDependency(pkChar->pSkeleton);
|
||||||
|
AddDependency(pkChar->pSkin);
|
||||||
|
|
||||||
|
const std::vector<CAssetID> *pkParticleVectors[5] = {
|
||||||
|
&pkChar->GenericParticles, &pkChar->ElectricParticles,
|
||||||
|
&pkChar->SwooshParticles, &pkChar->SpawnParticles,
|
||||||
|
&pkChar->EffectParticles
|
||||||
|
};
|
||||||
|
|
||||||
|
for (u32 iVec = 0; iVec < 5; iVec++)
|
||||||
|
{
|
||||||
|
for (u32 iPart = 0; iPart < pkParticleVectors[iVec]->size(); iPart++)
|
||||||
|
AddDependency(pkParticleVectors[iVec]->at(iPart));
|
||||||
|
}
|
||||||
|
|
||||||
|
AddDependency(pkChar->IceModel);
|
||||||
|
AddDependency(pkChar->IceSkin);
|
||||||
|
}
|
||||||
|
|
||||||
// ************ CScriptInstanceDependencyTree ************
|
// ************ CScriptInstanceDependencyTree ************
|
||||||
CScriptInstanceDependencyTree::~CScriptInstanceDependencyTree()
|
CScriptInstanceDependencyTree::~CScriptInstanceDependencyTree()
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@ class CScriptLayer;
|
||||||
class CScriptObject;
|
class CScriptObject;
|
||||||
class CPropertyStruct;
|
class CPropertyStruct;
|
||||||
class TCharacterProperty;
|
class TCharacterProperty;
|
||||||
|
struct SSetCharacter;
|
||||||
|
|
||||||
// Group of node classes forming a tree of cached resource dependencies.
|
// Group of node classes forming a tree of cached resource dependencies.
|
||||||
enum EDependencyNodeType
|
enum EDependencyNodeType
|
||||||
|
@ -109,6 +110,8 @@ public:
|
||||||
virtual EDependencyNodeType Type() const;
|
virtual EDependencyNodeType Type() const;
|
||||||
virtual void Read(IInputStream& rFile, EIDLength IDLength);
|
virtual void Read(IInputStream& rFile, EIDLength IDLength);
|
||||||
virtual void Write(IOutputStream& rFile, EIDLength IDLength) const;
|
virtual void Write(IOutputStream& rFile, EIDLength IDLength) const;
|
||||||
|
|
||||||
|
void AddCharacter(const SSetCharacter *pkChar);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Node representing a script object. Indicates the type of object.
|
// Node representing a script object. Indicates the type of object.
|
||||||
|
|
|
@ -116,9 +116,12 @@ bool CResourceEntry::SaveCacheData()
|
||||||
|
|
||||||
u32 DepsStart = File.Tell();
|
u32 DepsStart = File.Tell();
|
||||||
if (mpDependencies) mpDependencies->Write(File, Game() <= eEchoes ? e32Bit : e64Bit);
|
if (mpDependencies) mpDependencies->Write(File, Game() <= eEchoes ? e32Bit : e64Bit);
|
||||||
u32 DepsSize = File.Tell() - DepsStart;
|
u32 DepsEnd = File.Tell();
|
||||||
|
u32 DepsSize = DepsEnd- DepsStart;
|
||||||
|
|
||||||
File.Seek(DepsSizeOffset, SEEK_SET);
|
File.Seek(DepsSizeOffset, SEEK_SET);
|
||||||
File.WriteLong(DepsSize);
|
File.WriteLong(DepsSize);
|
||||||
|
File.Seek(DepsEnd, SEEK_SET);
|
||||||
|
|
||||||
// Thumbnail
|
// Thumbnail
|
||||||
File.WriteLong(0); // Reserved Space (Thumbnail Size)
|
File.WriteLong(0); // Reserved Space (Thumbnail Size)
|
||||||
|
@ -262,6 +265,7 @@ CResource* CResourceEntry::Load(IInputStream& rInput)
|
||||||
case eDependencyGroup: mpResource = CDependencyGroupLoader::LoadDGRP(rInput, this); break;
|
case eDependencyGroup: mpResource = CDependencyGroupLoader::LoadDGRP(rInput, this); break;
|
||||||
case eDynamicCollision: mpResource = CCollisionLoader::LoadDCLN(rInput, this); break;
|
case eDynamicCollision: mpResource = CCollisionLoader::LoadDCLN(rInput, this); break;
|
||||||
case eFont: mpResource = CFontLoader::LoadFONT(rInput, this); break;
|
case eFont: mpResource = CFontLoader::LoadFONT(rInput, this); break;
|
||||||
|
case eGuiFrame: mpResource = CUnsupportedFormatLoader::LoadFRME(rInput, this); break;
|
||||||
case eHintSystem: mpResource = CUnsupportedFormatLoader::LoadHINT(rInput, this); break;
|
case eHintSystem: mpResource = CUnsupportedFormatLoader::LoadHINT(rInput, this); break;
|
||||||
case eMapWorld: mpResource = CUnsupportedFormatLoader::LoadMAPW(rInput, this); break;
|
case eMapWorld: mpResource = CUnsupportedFormatLoader::LoadMAPW(rInput, this); break;
|
||||||
case eMapUniverse: mpResource = CUnsupportedFormatLoader::LoadMAPU(rInput, this); break;
|
case eMapUniverse: mpResource = CUnsupportedFormatLoader::LoadMAPU(rInput, this); break;
|
||||||
|
|
|
@ -12,21 +12,28 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// will expand later! this is where animation support will come in
|
// will expand later! this is where animation support will come in
|
||||||
|
struct SSetCharacter
|
||||||
|
{
|
||||||
|
TString Name;
|
||||||
|
TResPtr<CModel> pModel;
|
||||||
|
TResPtr<CSkin> pSkin;
|
||||||
|
TResPtr<CSkeleton> pSkeleton;
|
||||||
|
|
||||||
|
std::vector<CAssetID> GenericParticles;
|
||||||
|
std::vector<CAssetID> ElectricParticles;
|
||||||
|
std::vector<CAssetID> SwooshParticles;
|
||||||
|
std::vector<CAssetID> SpawnParticles;
|
||||||
|
std::vector<CAssetID> EffectParticles;
|
||||||
|
CAssetID IceModel;
|
||||||
|
CAssetID IceSkin;
|
||||||
|
};
|
||||||
|
|
||||||
class CAnimSet : public CResource
|
class CAnimSet : public CResource
|
||||||
{
|
{
|
||||||
DECLARE_RESOURCE_TYPE(eAnimSet)
|
DECLARE_RESOURCE_TYPE(eAnimSet)
|
||||||
friend class CAnimSetLoader;
|
friend class CAnimSetLoader;
|
||||||
|
|
||||||
struct SNode
|
std::vector<SSetCharacter> mCharacters;
|
||||||
{
|
|
||||||
TString Name;
|
|
||||||
TResPtr<CModel> pModel;
|
|
||||||
TResPtr<CSkin> pSkin;
|
|
||||||
TResPtr<CSkeleton> pSkeleton;
|
|
||||||
|
|
||||||
SNode() { pModel = nullptr; }
|
|
||||||
};
|
|
||||||
std::vector<SNode> mNodes;
|
|
||||||
|
|
||||||
struct SAnimation
|
struct SAnimation
|
||||||
{
|
{
|
||||||
|
@ -38,15 +45,28 @@ class CAnimSet : public CResource
|
||||||
public:
|
public:
|
||||||
CAnimSet(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
CAnimSet(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
||||||
|
|
||||||
u32 NumNodes() const { return mNodes.size(); }
|
u32 NumNodes() const { return mCharacters.size(); }
|
||||||
TString NodeName(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].Name; }
|
TString NodeName(u32 Index) { if (Index >= mCharacters.size()) Index = 0; return mCharacters[Index].Name; }
|
||||||
CModel* NodeModel(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].pModel; }
|
CModel* NodeModel(u32 Index) { if (Index >= mCharacters.size()) Index = 0; return mCharacters[Index].pModel; }
|
||||||
CSkin* NodeSkin(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].pSkin; }
|
CSkin* NodeSkin(u32 Index) { if (Index >= mCharacters.size()) Index = 0; return mCharacters[Index].pSkin; }
|
||||||
CSkeleton* NodeSkeleton(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].pSkeleton; }
|
CSkeleton* NodeSkeleton(u32 Index) { if (Index >= mCharacters.size()) Index = 0; return mCharacters[Index].pSkeleton; }
|
||||||
|
|
||||||
u32 NumAnims() const { return mAnims.size(); }
|
u32 NumAnims() const { return mAnims.size(); }
|
||||||
CAnimation* Animation(u32 Index) { if (Index >= mAnims.size()) Index = 0; return mAnims[Index].pAnim; }
|
CAnimation* Animation(u32 Index) { if (Index >= mAnims.size()) Index = 0; return mAnims[Index].pAnim; }
|
||||||
TString AnimName(u32 Index) { if (Index >= mAnims.size()) Index = 0; return mAnims[Index].Name; }
|
TString AnimName(u32 Index) { if (Index >= mAnims.size()) Index = 0; return mAnims[Index].Name; }
|
||||||
|
|
||||||
|
CDependencyTree* BuildDependencyTree() const
|
||||||
|
{
|
||||||
|
CAnimSetDependencyTree *pTree = new CAnimSetDependencyTree(ID());
|
||||||
|
|
||||||
|
for (u32 iAnim = 0; iAnim < mAnims.size(); iAnim++)
|
||||||
|
pTree->AddDependency(mAnims[iAnim].pAnim);
|
||||||
|
|
||||||
|
for (u32 iNode = 0; iNode < mCharacters.size(); iNode++)
|
||||||
|
pTree->AddCharacter(&mCharacters[iNode]);
|
||||||
|
|
||||||
|
return pTree;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCHARACTERSET_H
|
#endif // CCHARACTERSET_H
|
||||||
|
|
|
@ -6,17 +6,49 @@
|
||||||
class CDependencyGroup : public CResource
|
class CDependencyGroup : public CResource
|
||||||
{
|
{
|
||||||
DECLARE_RESOURCE_TYPE(eDependencyGroup)
|
DECLARE_RESOURCE_TYPE(eDependencyGroup)
|
||||||
std::set<CAssetID> mDependencies;
|
std::vector<CAssetID> mDependencies;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDependencyGroup(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
CDependencyGroup(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
||||||
inline void AddDependency(const CAssetID& rkID) { mDependencies.insert(rkID); }
|
|
||||||
inline void AddDependency(CResource *pRes) { if (pRes) mDependencies.insert(pRes->ID()); }
|
|
||||||
inline void RemoveDependency(const CAssetID& rkID) { mDependencies.erase(rkID); }
|
|
||||||
inline void Clear() { mDependencies.clear(); }
|
inline void Clear() { mDependencies.clear(); }
|
||||||
inline bool HasDependency(const CAssetID& rkID) const { return mDependencies.find(rkID) != mDependencies.end(); }
|
|
||||||
inline u32 NumDependencies() const { return mDependencies.size(); }
|
inline u32 NumDependencies() const { return mDependencies.size(); }
|
||||||
inline CAssetID DependencyByIndex(u32 Index) const { return *std::next(mDependencies.begin(), Index); }
|
inline CAssetID DependencyByIndex(u32 Index) const { return mDependencies[Index]; }
|
||||||
|
|
||||||
|
inline void AddDependency(const CAssetID& rkID)
|
||||||
|
{
|
||||||
|
if (!HasDependency(rkID))
|
||||||
|
mDependencies.push_back(rkID);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AddDependency(CResource *pRes)
|
||||||
|
{
|
||||||
|
if ( pRes && !HasDependency(pRes->ID()) )
|
||||||
|
mDependencies.push_back(pRes->ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveDependency(const CAssetID& rkID)
|
||||||
|
{
|
||||||
|
for (auto Iter = mDependencies.begin(); Iter != mDependencies.end(); Iter++)
|
||||||
|
{
|
||||||
|
if (*Iter == rkID)
|
||||||
|
{
|
||||||
|
mDependencies.erase(Iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasDependency(const CAssetID &rkID) const
|
||||||
|
{
|
||||||
|
for (u32 iDep = 0; iDep < mDependencies.size(); iDep++)
|
||||||
|
{
|
||||||
|
if (mDependencies[iDep] == rkID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CDependencyTree* BuildDependencyTree() const
|
CDependencyTree* BuildDependencyTree() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,11 +10,11 @@ CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
// For now, we only read enough to fetch the model
|
||||||
rCHAR.Seek(0x1, SEEK_CUR);
|
rCHAR.Seek(0x1, SEEK_CUR);
|
||||||
pSet->mNodes.resize(1);
|
pSet->mCharacters.resize(1);
|
||||||
CAnimSet::SNode& node = pSet->mNodes[0];
|
SSetCharacter& rNode = pSet->mCharacters[0];
|
||||||
|
|
||||||
node.Name = rCHAR.ReadString();
|
rNode.Name = rCHAR.ReadString();
|
||||||
node.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
rNode.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
||||||
return pSet;
|
return pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
// For now, we only read enough to fetch the model
|
||||||
rCHAR.Seek(0x16, SEEK_CUR);
|
rCHAR.Seek(0x16, SEEK_CUR);
|
||||||
pSet->mNodes.resize(1);
|
pSet->mCharacters.resize(1);
|
||||||
CAnimSet::SNode& rNode = pSet->mNodes[0];
|
SSetCharacter& rNode = pSet->mCharacters[0];
|
||||||
|
|
||||||
rNode.Name = rCHAR.ReadString();
|
rNode.Name = rCHAR.ReadString();
|
||||||
rCHAR.Seek(0x14, SEEK_CUR);
|
rCHAR.Seek(0x14, SEEK_CUR);
|
||||||
|
@ -224,11 +224,11 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
Loader.mVersion = pEntry->Game();
|
Loader.mVersion = pEntry->Game();
|
||||||
|
|
||||||
u32 NodeCount = rANCS.ReadLong();
|
u32 NodeCount = rANCS.ReadLong();
|
||||||
Loader.pSet->mNodes.resize(NodeCount);
|
Loader.pSet->mCharacters.resize(NodeCount);
|
||||||
|
|
||||||
for (u32 iNode = 0; iNode < NodeCount; iNode++)
|
for (u32 iNode = 0; iNode < NodeCount; iNode++)
|
||||||
{
|
{
|
||||||
CAnimSet::SNode *pNode = &Loader.pSet->mNodes[iNode];
|
SSetCharacter *pChar = &Loader.pSet->mCharacters[iNode];
|
||||||
|
|
||||||
rANCS.Seek(0x4, SEEK_CUR); // Skipping node self-index
|
rANCS.Seek(0x4, SEEK_CUR); // Skipping node self-index
|
||||||
u16 Unknown1 = rANCS.ReadShort();
|
u16 Unknown1 = rANCS.ReadShort();
|
||||||
|
@ -237,11 +237,11 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
Loader.mVersion = (Unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately
|
Loader.mVersion = (Unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately
|
||||||
Loader.pSet->SetGame(Loader.mVersion);
|
Loader.pSet->SetGame(Loader.mVersion);
|
||||||
}
|
}
|
||||||
pNode->Name = rANCS.ReadString();
|
pChar->Name = rANCS.ReadString();
|
||||||
pNode->pModel = gpResourceStore->LoadResource(rANCS.ReadLong(), "CMDL");
|
pChar->pModel = gpResourceStore->LoadResource(rANCS.ReadLong(), "CMDL");
|
||||||
pNode->pSkin = gpResourceStore->LoadResource(rANCS.ReadLong(), "CSKR");
|
pChar->pSkin = gpResourceStore->LoadResource(rANCS.ReadLong(), "CSKR");
|
||||||
pNode->pSkeleton = gpResourceStore->LoadResource(rANCS.ReadLong(), "CINF");
|
pChar->pSkeleton = gpResourceStore->LoadResource(rANCS.ReadLong(), "CINF");
|
||||||
if (pNode->pModel) pNode->pModel->SetSkin(pNode->pSkin);
|
if (pChar->pModel) pChar->pModel->SetSkin(pChar->pSkin);
|
||||||
|
|
||||||
// Unfortunately that's all that's actually supported at the moment. Hope to expand later.
|
// Unfortunately that's all that's actually supported at the moment. Hope to expand later.
|
||||||
// Since there's no size value I have to actually read the rest of the node to reach the next one
|
// Since there's no size value I have to actually read the rest of the node to reach the next one
|
||||||
|
@ -259,17 +259,32 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
|
|
||||||
// Particles
|
// Particles
|
||||||
u32 ParticleCount = rANCS.ReadLong();
|
u32 ParticleCount = rANCS.ReadLong();
|
||||||
rANCS.Seek(ParticleCount * 4, SEEK_CUR);
|
pChar->GenericParticles.reserve(ParticleCount);
|
||||||
|
|
||||||
|
for (u32 iPart = 0; iPart < ParticleCount; iPart++)
|
||||||
|
pChar->GenericParticles.push_back( CAssetID(rANCS, e32Bit) );
|
||||||
|
|
||||||
u32 SwooshCount = rANCS.ReadLong();
|
u32 SwooshCount = rANCS.ReadLong();
|
||||||
rANCS.Seek(SwooshCount * 4, SEEK_CUR);
|
pChar->SwooshParticles.reserve(SwooshCount);
|
||||||
|
|
||||||
|
for (u32 iSwoosh = 0; iSwoosh < SwooshCount; iSwoosh++)
|
||||||
|
pChar->SwooshParticles.push_back( CAssetID(rANCS, e32Bit) );
|
||||||
|
|
||||||
if (Unknown1 != 5) rANCS.Seek(0x4, SEEK_CUR);
|
if (Unknown1 != 5) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
u32 ElectricCount = rANCS.ReadLong();
|
u32 ElectricCount = rANCS.ReadLong();
|
||||||
rANCS.Seek(ElectricCount * 4, SEEK_CUR);
|
pChar->ElectricParticles.reserve(ElectricCount);
|
||||||
|
|
||||||
|
for (u32 iElec = 0; iElec < ElectricCount; iElec++)
|
||||||
|
pChar->ElectricParticles.push_back( CAssetID(rANCS, e32Bit) );
|
||||||
|
|
||||||
if (Loader.mVersion == eEchoes)
|
if (Loader.mVersion == eEchoes)
|
||||||
{
|
{
|
||||||
u32 SPSCCount = rANCS.ReadLong();
|
u32 SpawnCount = rANCS.ReadLong();
|
||||||
rANCS.Seek(SPSCCount * 4, SEEK_CUR);
|
pChar->SpawnParticles.reserve(SpawnCount);
|
||||||
|
|
||||||
|
for (u32 iSpawn = 0; iSpawn < SpawnCount; iSpawn++)
|
||||||
|
pChar->SpawnParticles.push_back( CAssetID(rANCS, e32Bit) );
|
||||||
}
|
}
|
||||||
|
|
||||||
rANCS.Seek(0x4, SEEK_CUR);
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
|
@ -291,13 +306,17 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
for (u32 iEffect = 0; iEffect < EffectCount; iEffect++)
|
for (u32 iEffect = 0; iEffect < EffectCount; iEffect++)
|
||||||
{
|
{
|
||||||
rANCS.ReadString();
|
rANCS.ReadString();
|
||||||
rANCS.Seek(0x8, SEEK_CUR);
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
|
CAssetID ParticleID(rANCS, e32Bit);
|
||||||
|
if (ParticleID.IsValid()) pChar->EffectParticles.push_back(ParticleID);
|
||||||
|
|
||||||
if (Loader.mVersion == ePrime) rANCS.ReadString();
|
if (Loader.mVersion == ePrime) rANCS.ReadString();
|
||||||
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
rANCS.Seek(0xC, SEEK_CUR);
|
rANCS.Seek(0xC, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rANCS.Seek(0x8, SEEK_CUR);
|
pChar->IceModel = CAssetID(rANCS, e32Bit);
|
||||||
|
pChar->IceSkin = CAssetID(rANCS, e32Bit);
|
||||||
|
|
||||||
u32 UnknownCount = rANCS.ReadLong();
|
u32 UnknownCount = rANCS.ReadLong();
|
||||||
rANCS.Seek(UnknownCount * 4, SEEK_CUR);
|
rANCS.Seek(UnknownCount * 4, SEEK_CUR);
|
||||||
|
|
|
@ -56,6 +56,122 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadEVNT(IInputStream& rEVNT, CResou
|
||||||
return pGroup;
|
return pGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->Game() >= eEchoesDemo) return nullptr;
|
||||||
|
|
||||||
|
u32 Version = rFRME.ReadLong();
|
||||||
|
ASSERT(Version == 0 || Version == 1);
|
||||||
|
|
||||||
|
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
|
||||||
|
rFRME.Seek(0xC, SEEK_CUR);
|
||||||
|
u32 NumWidgets = rFRME.ReadLong();
|
||||||
|
|
||||||
|
for (u32 iWgt = 0; iWgt < NumWidgets; iWgt++)
|
||||||
|
{
|
||||||
|
// Widget Header
|
||||||
|
CFourCC WidgetType = rFRME.ReadLong();
|
||||||
|
rFRME.ReadString();
|
||||||
|
rFRME.ReadString();
|
||||||
|
rFRME.Seek(0x18, SEEK_CUR);
|
||||||
|
|
||||||
|
// Head Widget / Base Widget
|
||||||
|
if (WidgetType == "HWIG" || WidgetType == "BWIG")
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
else if (WidgetType == "CAMR")
|
||||||
|
{
|
||||||
|
u32 ProjectionType = rFRME.ReadLong();
|
||||||
|
|
||||||
|
if (ProjectionType == 0)
|
||||||
|
rFRME.Seek(0x10, SEEK_CUR);
|
||||||
|
else
|
||||||
|
rFRME.Seek(0x18, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light
|
||||||
|
else if (WidgetType == "LITE")
|
||||||
|
{
|
||||||
|
u32 LightType = rFRME.ReadLong();
|
||||||
|
rFRME.Seek(0x1C, SEEK_CUR);
|
||||||
|
if (LightType == 0) rFRME.Seek(0x4, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meter
|
||||||
|
else if (WidgetType == "METR")
|
||||||
|
rFRME.Seek(0xA, SEEK_CUR);
|
||||||
|
|
||||||
|
// Group
|
||||||
|
else if (WidgetType == "GRUP")
|
||||||
|
rFRME.Seek(0x3, SEEK_CUR);
|
||||||
|
|
||||||
|
// Table Group
|
||||||
|
else if (WidgetType == "TBGP")
|
||||||
|
rFRME.Seek(0x23, SEEK_CUR);
|
||||||
|
|
||||||
|
// Model
|
||||||
|
else if (WidgetType == "MODL")
|
||||||
|
{
|
||||||
|
pGroup->AddDependency( CAssetID(rFRME, e32Bit) ); // CMDL
|
||||||
|
rFRME.Seek(0x8, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text Pane
|
||||||
|
else if (WidgetType == "TXPN")
|
||||||
|
{
|
||||||
|
rFRME.Seek(0x14, SEEK_CUR);
|
||||||
|
pGroup->AddDependency( CAssetID(rFRME, e32Bit) ); // FONT
|
||||||
|
rFRME.Seek(0x32, SEEK_CUR);
|
||||||
|
|
||||||
|
if (Version == 1)
|
||||||
|
{
|
||||||
|
pGroup->AddDependency( CAssetID(rFRME, e32Bit) ); // FONT
|
||||||
|
rFRME.Seek(0x8, SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image Pane
|
||||||
|
else if (WidgetType == "IMGP")
|
||||||
|
{
|
||||||
|
pGroup->AddDependency( CAssetID(rFRME, e32Bit) ); // TXTR
|
||||||
|
if (rFRME.ReadLong() != 0xFFFFFFFF) DEBUG_BREAK;
|
||||||
|
rFRME.Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
|
u32 NumQuadCoords = rFRME.ReadLong();
|
||||||
|
rFRME.Seek(NumQuadCoords * 0xC, SEEK_CUR);
|
||||||
|
u32 NumUVCoords = rFRME.ReadLong();
|
||||||
|
rFRME.Seek(NumUVCoords * 8, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Energy Bar
|
||||||
|
else if (WidgetType == "ENRG")
|
||||||
|
{
|
||||||
|
pGroup->AddDependency( CAssetID(rFRME, e32Bit) ); // TXTR
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slider Group
|
||||||
|
else if (WidgetType == "SLGP")
|
||||||
|
{
|
||||||
|
rFRME.Seek(0x10, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::Error("Unrecognized FRME widget type: " + WidgetType.ToString());
|
||||||
|
DEBUG_BREAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget Footer
|
||||||
|
if (rFRME.ReadByte() != 0)
|
||||||
|
rFRME.Seek(0x2, SEEK_CUR);
|
||||||
|
|
||||||
|
rFRME.Seek(0x42, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pGroup;
|
||||||
|
}
|
||||||
|
|
||||||
CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry)
|
CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
u32 Magic = rHINT.ReadLong();
|
u32 Magic = rHINT.ReadLong();
|
||||||
|
|
|
@ -13,6 +13,7 @@ class CUnsupportedFormatLoader
|
||||||
public:
|
public:
|
||||||
static CDependencyGroup* LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry);
|
static CDependencyGroup* LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry);
|
||||||
static CDependencyGroup* LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry);
|
static CDependencyGroup* LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry);
|
||||||
|
static CDependencyGroup* LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry);
|
||||||
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
|
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
|
||||||
static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
|
static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
|
||||||
static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
|
static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
|
||||||
|
|
Loading…
Reference in New Issue