diff --git a/src/Core/GameProject/CResourceEntry.cpp b/src/Core/GameProject/CResourceEntry.cpp index ca619883..fe5471df 100644 --- a/src/Core/GameProject/CResourceEntry.cpp +++ b/src/Core/GameProject/CResourceEntry.cpp @@ -261,6 +261,10 @@ CResource* CResourceEntry::Load(IInputStream& rInput) case eDependencyGroup: mpResource = CDependencyGroupLoader::LoadDGRP(rInput, this); break; case eDynamicCollision: mpResource = CCollisionLoader::LoadDCLN(rInput, this); break; case eFont: mpResource = CFontLoader::LoadFONT(rInput, this); break; + case eHintSystem: mpResource = CUnsupportedFormatLoader::LoadHINT(rInput, this); break; + case eMapWorld: mpResource = CUnsupportedFormatLoader::LoadMAPW(rInput, this); break; + case eMapUniverse: mpResource = CUnsupportedFormatLoader::LoadMAPU(rInput, this); break; + case eMidi: mpResource = CUnsupportedFormatLoader::LoadCSNG(rInput, this); break; case eModel: mpResource = CModelLoader::LoadCMDL(rInput, this); break; case eRuleSet: mpResource = CUnsupportedFormatLoader::LoadRULE(rInput, this); break; case eScan: mpResource = CScanLoader::LoadSCAN(rInput, this); break; diff --git a/src/Core/Resource/CAnimation.cpp b/src/Core/Resource/CAnimation.cpp index b9ac8afc..e77ebe5f 100644 --- a/src/Core/Resource/CAnimation.cpp +++ b/src/Core/Resource/CAnimation.cpp @@ -16,6 +16,13 @@ CAnimation::CAnimation(CResourceEntry *pEntry /*= 0*/) } } +CDependencyTree* CAnimation::BuildDependencyTree() const +{ + CDependencyTree *pTree = new CDependencyTree(ID()); + pTree->AddDependency(mEventData); + return pTree; +} + void CAnimation::EvaluateTransform(float Time, u32 BoneID, CVector3f *pOutTranslation, CQuaternion *pOutRotation, CVector3f *pOutScale) const { const bool kInterpolate = true; diff --git a/src/Core/Resource/CAnimation.h b/src/Core/Resource/CAnimation.h index 104f3360..39946bf8 100644 --- a/src/Core/Resource/CAnimation.h +++ b/src/Core/Resource/CAnimation.h @@ -31,8 +31,11 @@ class CAnimation : public CResource }; SBoneChannelInfo mBoneInfo[100]; + CAssetID mEventData; + public: CAnimation(CResourceEntry *pEntry = 0); + CDependencyTree* BuildDependencyTree() const; void EvaluateTransform(float Time, u32 BoneID, CVector3f *pOutTranslation, CQuaternion *pOutRotation, CVector3f *pOutScale) const; bool HasTranslation(u32 BoneID) const; diff --git a/src/Core/Resource/Factory/CAnimationLoader.cpp b/src/Core/Resource/Factory/CAnimationLoader.cpp index d97a6dd8..c04e50d6 100644 --- a/src/Core/Resource/Factory/CAnimationLoader.cpp +++ b/src/Core/Resource/Factory/CAnimationLoader.cpp @@ -202,7 +202,7 @@ void CAnimationLoader::ReadUncompressedANIM() if (mGame == ePrime) { - // Skip EVNT file + mpAnim->mEventData = mpInput->ReadLong(); } } @@ -217,7 +217,13 @@ void CAnimationLoader::ReadCompressedANIM() mpAnim->SetGame(mGame); } - mpInput->Seek(mGame == ePrime ? 0x8 : 0x2, SEEK_CUR); // Skip EVNT (MP1) and unknowns + if (mGame == ePrime) + { + mpAnim->mEventData = mpInput->ReadLong(); + mpInput->Seek(0x4, SEEK_CUR); // Skip unknown + } + else mpInput->Seek(0x2, SEEK_CUR); // Skip unknowns + mpAnim->mDuration = mpInput->ReadFloat(); mpAnim->mTickInterval = mpInput->ReadFloat(); mpInput->Seek(0x8, SEEK_CUR); // Skip two unknown values diff --git a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp index 61deced1..fe9675f6 100644 --- a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp +++ b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp @@ -1,13 +1,119 @@ #include "CUnsupportedFormatLoader.h" #include "Core/Resource/ParticleParameters.h" +CDependencyGroup* CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry) +{ + u32 Magic = rCSNG.ReadLong(); + ASSERT(Magic == 0x2); + rCSNG.Seek(0x8, SEEK_CUR); + + CDependencyGroup *pGroup = new CDependencyGroup(pEntry); + pGroup->AddDependency(rCSNG.ReadLong()); + return pGroup; +} + +CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry) +{ + u32 Magic = rHINT.ReadLong(); + ASSERT(Magic == 0x00BADBAD); + + // Determine version + u32 Version = rHINT.ReadLong(); + EGame Game; + + if (Version == 0x1) Game = ePrime; + else if (Version == 0x3) Game = eCorruption; + + else + { + Log::Error("Unrecognized HINT version: " + TString::FromInt32(Version, 0, 10)); + return nullptr; + } + + EIDLength IDLength = (Game <= eEchoes ? e32Bit : e64Bit); + + // Read main file + CDependencyGroup *pGroup = new CDependencyGroup(pEntry); + u32 NumHints = rHINT.ReadLong(); + + for (u32 iHint = 0; iHint < NumHints; iHint++) + { + rHINT.ReadString(); // Skip hint name + rHINT.Seek(0x8, SEEK_CUR); // Skip unknown + appear time + pGroup->AddDependency( CAssetID(rHINT, IDLength) ); // Pop-up STRG + rHINT.Seek(0x8, SEEK_CUR); // Skip unknowns + + if (Game <= eEchoes) + { + pGroup->AddDependency( CAssetID(rHINT, IDLength) ); // Target MLVL + pGroup->AddDependency( CAssetID(rHINT, IDLength) ); // Target MREA + rHINT.Seek(0x4, SEEK_CUR); // Skip target room index + pGroup->AddDependency( CAssetID(rHINT, IDLength) ); // Map STRG + } + } + + return pGroup; +} + +CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry) +{ + u32 Magic = rMAPW.ReadLong(); + ASSERT(Magic == 0xDEADF00D); + + u32 Version = rMAPW.ReadLong(); + ASSERT(Version == 1); + + u32 NumAreas = rMAPW.ReadLong(); + + // Version check + u32 AreasStart = rMAPW.Tell(); + rMAPW.Seek(NumAreas * 4, SEEK_CUR); + EIDLength IDLength = (rMAPW.EoF() || rMAPW.ReadLong() == 0xFFFFFFFF ? e32Bit : e64Bit); + rMAPW.Seek(AreasStart, SEEK_SET); + + // Read MAPA IDs + CDependencyGroup *pGroup = new CDependencyGroup(pEntry); + + for (u32 iArea = 0; iArea < NumAreas; iArea++) + pGroup->AddDependency( CAssetID(rMAPW, IDLength) ); + + return pGroup; +} + +CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry) +{ + u32 Magic = rMAPU.ReadLong(); + ASSERT(Magic == 0xABCDEF01); + + u32 Version = rMAPU.ReadLong(); + ASSERT(Version == 0x1); + + CDependencyGroup *pGroup = new CDependencyGroup(pEntry); + pGroup->AddDependency(rMAPU.ReadLong()); + + // Read worlds + u32 NumWorlds = rMAPU.ReadLong(); + + for (u32 iWorld = 0; iWorld < NumWorlds; iWorld++) + { + rMAPU.ReadString(); // Skip world name + pGroup->AddDependency(rMAPU.ReadLong()); // World MLVL + rMAPU.Seek(0x30, SEEK_CUR); // Skip world map transform + u32 NumHexagons = rMAPU.ReadLong(); + rMAPU.Seek(NumHexagons * 0x30, SEEK_CUR); // Skip hexagon transforms + rMAPU.Seek(0x10, SEEK_CUR); // Skip world color + } + + return pGroup; +} + CDependencyGroup* CUnsupportedFormatLoader::LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry) { // RULE files can contain a reference to another RULE file, but has no other dependencies. u32 Magic = rRULE.ReadLong(); ASSERT(CFourCC(Magic) == "RULE"); - CDependencyGroup *pOut = new CDependencyGroup(pEntry); + CDependencyGroup *pGroup = new CDependencyGroup(pEntry); rRULE.Seek(0x1, SEEK_CUR); // Version test @@ -19,6 +125,6 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadRULE(IInputStream& rRULE, CResou // Read rule ID CAssetID RuleID(rRULE, IDLength); - pOut->AddDependency(RuleID); - return pOut; + pGroup->AddDependency(RuleID); + return pGroup; } diff --git a/src/Core/Resource/Factory/CUnsupportedFormatLoader.h b/src/Core/Resource/Factory/CUnsupportedFormatLoader.h index 769e3a17..59d3ad33 100644 --- a/src/Core/Resource/Factory/CUnsupportedFormatLoader.h +++ b/src/Core/Resource/Factory/CUnsupportedFormatLoader.h @@ -11,8 +11,11 @@ class CUnsupportedFormatLoader CUnsupportedFormatLoader() {} public: + static CDependencyGroup* LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry); + static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry); + static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry); + static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry); static CDependencyGroup* LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry); - static CDependencyGroup* LoadPART(IInputStream& rPART, CResourceEntry *pEntry); }; #endif // CUNSUPPORTEDFORMATLOADER_H