Lots of work to get MP2 repacking functional

This commit is contained in:
parax0
2016-11-07 03:07:00 -07:00
parent 040caca896
commit f6fd78af14
135 changed files with 677 additions and 1239 deletions

View File

@@ -55,6 +55,15 @@ void CDependencyTree::AddDependency(CResource *pRes, bool AvoidDuplicates /*= tr
AddDependency(pRes->ID(), AvoidDuplicates);
}
void CDependencyTree::AddCharacterDependency(const CAnimationParameters& rkAnimParams)
{
// This is for formats other than MREA that use AnimationParameters (such as SCAN).
CAnimSet *pSet = rkAnimParams.AnimSet();
if (!pSet || rkAnimParams.CharacterIndex() == -1) return;
CCharPropertyDependency *pChar = new CCharPropertyDependency("NULL", pSet->ID(), rkAnimParams.CharacterIndex());
mChildren.push_back(pChar);
}
// ************ CResourceDependency ************
EDependencyNodeType CResourceDependency::Type() const
{
@@ -215,6 +224,7 @@ CSetCharacterDependency* CSetCharacterDependency::BuildTree(const CAnimSet *pkOw
pTree->AddDependency(pkChar->IceModel);
pTree->AddDependency(pkChar->IceSkin);
pTree->AddDependency(pkChar->SpatialPrimitives);
}
return pTree;
@@ -300,7 +310,8 @@ void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer)
CScriptInstanceDependency *pTree = CScriptInstanceDependency::BuildTree( pLayer->InstanceByIndex(iInst) );
ASSERT(pTree != nullptr);
if (pTree->NumChildren() > 0)
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= eEchoesDemo)
mChildren.push_back(pTree);
else
delete pTree;

View File

@@ -10,6 +10,7 @@ class CScriptLayer;
class CScriptObject;
class CPropertyStruct;
class CAnimSet;
class CAnimationParameters;
struct SSetCharacter;
// Group of node classes forming a tree of cached resource dependencies.
@@ -39,8 +40,8 @@ public:
virtual bool HasDependency(const CAssetID& rkID) const;
// Accessors
u32 NumChildren() const { return mChildren.size(); }
IDependencyNode* ChildByIndex(u32 Index) const { return mChildren[Index]; }
inline u32 NumChildren() const { return mChildren.size(); }
inline IDependencyNode* ChildByIndex(u32 Index) const { return mChildren[Index]; }
};
// Basic dependency tree; this class is sufficient for most resource types.
@@ -59,6 +60,7 @@ public:
void AddChild(IDependencyNode *pNode);
void AddDependency(const CAssetID& rkID, bool AvoidDuplicates = true);
void AddDependency(CResource *pRes, bool AvoidDuplicates = true);
void AddCharacterDependency(const CAnimationParameters& rkAnimParams);
// Accessors
inline void SetID(const CAssetID& rkID) { mRootID = rkID; }
@@ -183,6 +185,7 @@ public:
// Accessors
inline bool IsUsedByCharacter(u32 CharIdx) const { return mCharacterIndices.find(CharIdx) != mCharacterIndices.end(); }
inline bool IsUsedByAnyCharacter() const { return !mCharacterIndices.empty(); }
// Static
static CSetAnimationDependency* BuildTree(const CAnimSet *pkOwnerSet, u32 AnimIndex);

View File

@@ -1,4 +1,5 @@
#include "CGameProject.h"
#include "Core/Resource/Factory/CTemplateLoader.h"
#include "Core/Resource/Script/CMasterTemplate.h"
#include <Common/Serialization/XML.h>
@@ -21,6 +22,7 @@ bool CGameProject::Load(const TWideString& rkPath)
TString ProjPath = rkPath.ToUTF8();
CXMLReader Reader(ProjPath);
Serialize(Reader);
CTemplateLoader::LoadGameTemplates(mGame);
mpResourceStore->LoadResourceDatabase();
mpAudioManager->LoadAssets();

View File

@@ -159,7 +159,7 @@ void CPackage::Cook()
if (mpProject->Game() <= eEchoesDemo)
Success = CompressionUtil::CompressZlib(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedData.size(), CompressedSize);
else
Success = CompressionUtil::CompressLZOSegmented(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedSize);
Success = CompressionUtil::CompressLZOSegmented(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedSize, false);
// Make sure that the compressed data is actually smaller, accounting for padding + uncompressed size value
if (Success)
@@ -217,7 +217,7 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
TWideString CookedPath = CookedPackagePath(false);
CFileInStream Pak(CookedPath.ToUTF8().ToStdString(), IOUtil::eBigEndian);
if (!Pak.IsValid())
if (!Pak.IsValid() || Pak.Size() == 0)
{
Log::Error("Failed to compare to original asset list; couldn't open the original pak");
return;

View File

@@ -139,6 +139,21 @@ void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode)
rUsageList[UsedChar] = true;
}
// Parse dependencies of the referenced resource if it's a type that can reference animsets
else if (Type == eDNT_ResourceDependency || Type == eDNT_ScriptProperty)
{
CResourceDependency *pDep = static_cast<CResourceDependency*>(pNode);
CResourceEntry *pEntry = gpResourceStore->FindEntry(pDep->ID());
if (pEntry)
{
EResType ResType = pEntry->ResourceType();
if (ResType == eScan)
ParseDependencyNode(pEntry->Dependencies());
}
}
// Look for sub-dependencies of the current node
else
{
@@ -275,7 +290,7 @@ void CPackageDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurE
else if (Type == eDNT_SetAnimation)
{
CSetAnimationDependency *pAnim = static_cast<CSetAnimationDependency*>(pNode);
ParseChildren = mCharacterUsageMap.IsAnimationUsed(mCurrentAnimSetID, pAnim) || mIsPlayerActor; // todo - should maybe omit completely unused animations on PlayerActors?
ParseChildren = mCharacterUsageMap.IsAnimationUsed(mCurrentAnimSetID, pAnim) || (mIsPlayerActor && pAnim->IsUsedByAnyCharacter());
}
else
@@ -409,7 +424,10 @@ void CAreaDependencyListBuilder::AddDependency(const CAssetID& rkID, std::list<C
// Don't add CSNGs to the output dependency list (we parse them because we need their AGSC dependencies in the output AudioGroup set)
if (ResType != eMidi)
{
rOut.push_back(rkID);
mLayerUsedAssets.insert(rkID);
}
}
void CAreaDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut, std::set<CAssetID> *pAudioGroupsOut)
@@ -445,7 +463,7 @@ void CAreaDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntr
else if (Type == eDNT_SetAnimation)
{
CSetAnimationDependency *pAnim = static_cast<CSetAnimationDependency*>(pNode);
ParseChildren = mCharacterUsageMap.IsAnimationUsed(mCurrentAnimSetID, pAnim);
ParseChildren = mCharacterUsageMap.IsAnimationUsed(mCurrentAnimSetID, pAnim) || (mIsPlayerActor && pAnim->IsUsedByAnyCharacter());
}
else