Fixed issues in MP3 package list building

This commit is contained in:
Aruki
2017-05-09 14:16:41 -06:00
parent f72f82d519
commit 560706d285
22 changed files with 269 additions and 48 deletions

View File

@@ -143,6 +143,24 @@ CAssetID CGameProject::FindNamedResource(const TString& rkName) const
return CAssetID::InvalidID(mGame);
}
CPackage* CGameProject::FindPackage(const TString& rkName) const
{
if (mGame == eCorruptionProto || mGame == eCorruption)
{
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
{
CPackage *pPackage = mPackages[iPkg];
if (pPackage->Name() == rkName)
{
return pPackage;
}
}
}
return nullptr;
}
CGameProject* CGameProject::CreateProjectForExport(
const TString& rkProjRootDir,
EGame Game,

View File

@@ -67,6 +67,7 @@ public:
void Serialize(IArchive& rArc);
void GetWorldList(std::list<CAssetID>& rOut) const;
CAssetID FindNamedResource(const TString& rkName) const;
CPackage* FindPackage(const TString& rkName) const;
// Static
static CGameProject* CreateProjectForExport(

View File

@@ -236,28 +236,56 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
return;
}
// Skip past header + named resources
// Determine pak version
u32 PakVersion = Pak.ReadLong();
ASSERT(PakVersion == 0x00030005);
Pak.Seek(0x4, SEEK_CUR);
u32 NumNamedResources = Pak.ReadLong();
for (u32 iName = 0; iName < NumNamedResources; iName++)
{
Pak.Seek(0x8, SEEK_CUR);
u32 NameLen = Pak.ReadLong();
Pak.Seek(NameLen, SEEK_CUR);
}
// Build a set out of the original pak resource list
u32 NumResources = Pak.ReadLong();
std::set<CAssetID> OldListSet;
for (u32 iRes = 0; iRes < NumResources; iRes++)
// Read MP1/2 pak
if (PakVersion == 0x00030005)
{
Pak.Seek(0x8, SEEK_CUR);
OldListSet.insert( CAssetID(Pak, e32Bit) );
Pak.Seek(0x8, SEEK_CUR);
Pak.Seek(0x4, SEEK_CUR);
u32 NumNamedResources = Pak.ReadLong();
for (u32 iName = 0; iName < NumNamedResources; iName++)
{
Pak.Seek(0x8, SEEK_CUR);
u32 NameLen = Pak.ReadLong();
Pak.Seek(NameLen, SEEK_CUR);
}
// Build a set out of the original pak resource list
u32 NumResources = Pak.ReadLong();
for (u32 iRes = 0; iRes < NumResources; iRes++)
{
Pak.Seek(0x8, SEEK_CUR);
OldListSet.insert( CAssetID(Pak, e32Bit) );
Pak.Seek(0x8, SEEK_CUR);
}
}
// Read MP3/DKCR pak
else
{
ASSERT(PakVersion == 0x2);
// Skip named resources
Pak.Seek(0x44, SEEK_SET);
CFourCC StringSecType = Pak.ReadLong();
u32 StringSecSize = Pak.ReadLong();
ASSERT(StringSecType == "STRG");
Pak.Seek(0x80 + StringSecSize, SEEK_SET);
// Read resource table
u32 NumResources = Pak.ReadLong();
for (u32 iRes = 0; iRes < NumResources; iRes++)
{
Pak.Seek(0x8, SEEK_CUR);
OldListSet.insert( CAssetID(Pak, e64Bit) );
Pak.Seek(0x8, SEEK_CUR);
}
}
// Check for missing resources in the new list

View File

@@ -3,6 +3,7 @@
// ************ CCharacterUsageMap ************
bool CCharacterUsageMap::IsCharacterUsed(const CAssetID& rkID, u32 CharacterIndex) const
{
if (mpStore->Game() >= eCorruptionProto) return true;
auto Find = mUsageMap.find(rkID);
if (Find == mUsageMap.end()) return false;
@@ -172,6 +173,7 @@ void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode)
void CPackageDependencyListBuilder::BuildDependencyList(bool AllowDuplicates, std::list<CAssetID>& rOut)
{
mEnableDuplicates = AllowDuplicates;
FindUniversalAreaAssets();
// Iterate over all resources and parse their dependencies
for (u32 iRes = 0; iRes < mpkPackage->NumNamedResources(); iRes++)
@@ -186,6 +188,8 @@ void CPackageDependencyListBuilder::BuildDependencyList(bool AllowDuplicates, st
continue;
}
mIsUniversalAreaAsset = (mUniversalAreaAssets.find(rkRes.ID) != mUniversalAreaAssets.end());
if (rkRes.Type == "MLVL")
{
mpWorld = (CWorld*) pEntry->Load();
@@ -217,7 +221,8 @@ void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, con
if (!IsValid) return;
if ( ( mCurrentAreaHasDuplicates && mAreaUsedAssets.find(rkID) != mAreaUsedAssets.end()) ||
(!mCurrentAreaHasDuplicates && mPackageUsedAssets.find(rkID) != mPackageUsedAssets.end()) )
(!mCurrentAreaHasDuplicates && mPackageUsedAssets.find(rkID) != mPackageUsedAssets.end()) ||
(!mIsUniversalAreaAsset && mUniversalAreaAssets.find(rkID) != mUniversalAreaAssets.end() ) )
return;
// Entry is valid, parse its sub-dependencies
@@ -258,6 +263,10 @@ void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, con
// Revert current animset ID
if (ResType == eAnimSet)
mCurrentAnimSetID = CAssetID::InvalidID(mGame);
// Revert duplicate flag
else if (ResType == eArea)
mCurrentAreaHasDuplicates = false;
}
void CPackageDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut)
@@ -316,6 +325,58 @@ void CPackageDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurE
}
}
void CPackageDependencyListBuilder::FindUniversalAreaAssets()
{
CGameProject *pProject = mpStore->Project();
CPackage *pPackage = pProject->FindPackage("UniverseArea");
if (pPackage)
{
// Iterate over all the package contents, keep track of all universal area assets
for (u32 ResIdx = 0; ResIdx < pPackage->NumNamedResources(); ResIdx++)
{
const SNamedResource& rkRes = pPackage->NamedResourceByIndex(ResIdx);
if (rkRes.ID.IsValid())
{
mUniversalAreaAssets.insert(rkRes.ID);
// For the universal area world, load it into memory to make sure we can exclude the area/map IDs
if (rkRes.Type == "MLVL")
{
CWorld *pUniverseWorld = gpResourceStore->LoadResource<CWorld>(rkRes.ID);
if (pUniverseWorld)
{
// Area IDs
for (u32 AreaIdx = 0; AreaIdx < pUniverseWorld->NumAreas(); AreaIdx++)
{
CAssetID AreaID = pUniverseWorld->AreaResourceID(AreaIdx);
if (AreaID.IsValid())
mUniversalAreaAssets.insert(AreaID);
}
// Map IDs
CDependencyGroup *pMapWorld = (CDependencyGroup*) pUniverseWorld->MapWorld();
if (pMapWorld)
{
for (u32 DepIdx = 0; DepIdx < pMapWorld->NumDependencies(); DepIdx++)
{
CAssetID DepID = pMapWorld->DependencyByIndex(DepIdx);
if (DepID.IsValid())
mUniversalAreaAssets.insert(DepID);
}
}
}
}
}
}
}
}
// ************ CAreaDependencyListBuilder ************
void CAreaDependencyListBuilder::BuildDependencyList(std::list<CAssetID>& rAssetsOut, std::list<u32>& rLayerOffsetsOut, std::set<CAssetID> *pAudioGroupsOut)
{

View File

@@ -46,8 +46,10 @@ class CPackageDependencyListBuilder
CCharacterUsageMap mCharacterUsageMap;
std::set<CAssetID> mPackageUsedAssets;
std::set<CAssetID> mAreaUsedAssets;
std::set<CAssetID> mUniversalAreaAssets;
bool mEnableDuplicates;
bool mCurrentAreaHasDuplicates;
bool mIsUniversalAreaAsset;
bool mIsPlayerActor;
public:
@@ -64,6 +66,7 @@ public:
void BuildDependencyList(bool AllowDuplicates, std::list<CAssetID>& rOut);
void AddDependency(CResourceEntry *pCurEntry, const CAssetID& rkID, std::list<CAssetID>& rOut);
void EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut);
void FindUniversalAreaAssets();
};
// ************ CAreaDependencyListBuilder ************