Rewrote SCAN asset handling + loading

This commit is contained in:
Aruki
2019-01-12 21:28:04 -08:00
parent a174548750
commit a1d94cc58f
37 changed files with 342 additions and 1296 deletions

View File

@@ -3,9 +3,10 @@
#include "CResourceIterator.h"
#include "Core/Resource/CAudioMacro.h"
#include "Core/Resource/CFont.h"
#include "Core/Resource/CScan.h"
#include "Core/Resource/CWorld.h"
#include "Core/Resource/Animation/CAnimSet.h"
#include "Core/Resource/Scan/CScan.h"
#include "Core/Resource/Scan/SScanParametersMP1.h"
#include "Core/Resource/Script/CScriptLayer.h"
#include <Common/Math/MathUtil.h>
@@ -311,10 +312,15 @@ void GenerateAssetNames(CGameProject *pProj)
ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), ScanName);
CScan *pScan = (CScan*) pEntry->Load();
if (pScan && pScan->ScanText())
if (pScan)
{
CResourceEntry *pStringEntry = pScan->ScanText()->Entry();
ApplyGeneratedName(pStringEntry, pStringEntry->DirectoryPath(), ScanName);
CAssetID StringID = pScan->ScanStringPropertyRef();
CResourceEntry* pStringEntry = gpResourceStore->FindEntry(StringID);
if (pStringEntry)
{
ApplyGeneratedName(pStringEntry, pStringEntry->DirectoryPath(), ScanName);
}
}
}
}
@@ -609,16 +615,10 @@ void GenerateAssetNames(CGameProject *pProj)
CScan *pScan = (CScan*) It->Load();
TString ScanName;
if (pProj->Game() >= EGame::EchoesDemo)
{
CAssetID DisplayAsset = pScan->LogbookDisplayAssetID();
CResourceEntry *pEntry = pStore->FindEntry(DisplayAsset);
if (pEntry && pEntry->IsNamed()) ScanName = pEntry->Name();
}
if (ScanName.IsEmpty())
{
CStringTable *pString = pScan->ScanText();
CAssetID StringID = pScan->ScanStringPropertyRef().Get();
CStringTable *pString = (CStringTable*) gpResourceStore->LoadResource(StringID, EResourceType::StringTable);
if (pString) ScanName = pString->Entry()->Name();
}
@@ -626,13 +626,14 @@ void GenerateAssetNames(CGameProject *pProj)
if (!ScanName.IsEmpty() && pProj->Game() <= EGame::Prime)
{
CAssetID FrameID = pScan->GuiFrame();
CResourceEntry *pEntry = pStore->FindEntry(FrameID);
const SScanParametersMP1& kParms = *static_cast<SScanParametersMP1*>(pScan->ScanData().DataPointer());
CResourceEntry *pEntry = pStore->FindEntry(kParms.GuiFrame);
if (pEntry) ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), "ScanFrame");
for (uint32 iImg = 0; iImg < 4; iImg++)
{
CAssetID ImageID = pScan->ScanImage(iImg);
CAssetID ImageID = kParms.ScanImages[iImg].Texture;
CResourceEntry *pImgEntry = pStore->FindEntry(ImageID);
if (pImgEntry) ApplyGeneratedName(pImgEntry, pImgEntry->DirectoryPath(), TString::Format("%s_Image%d", *ScanName, iImg));
}

View File

@@ -30,6 +30,70 @@ void IDependencyNode::GetAllResourceReferences(std::set<CAssetID>& rOutSet) cons
mChildren[iChild]->GetAllResourceReferences(rOutSet);
}
void IDependencyNode::ParseProperties(CResourceEntry* pParentEntry, CStructProperty* pProperties, void* pData)
{
// Recursive function for parsing dependencies in properties
for (uint32 PropertyIdx = 0; PropertyIdx < pProperties->NumChildren(); PropertyIdx++)
{
IProperty* pProp = pProperties->ChildByIndex(PropertyIdx);
EPropertyType Type = pProp->Type();
// Technically we aren't parsing array children, but it's not really worth refactoring this function
// to support it when there aren't any array properties that contain any asset references anyway...
if (Type == EPropertyType::Struct)
ParseProperties( pParentEntry, TPropCast<CStructProperty>(pProp), pData );
else if (Type == EPropertyType::Sound)
{
uint32 SoundID = TPropCast<CSoundProperty>(pProp)->Value(pData);
if (SoundID != -1)
{
CGameProject* pProj = pParentEntry->Project();
SSoundInfo Info = pProj->AudioManager()->GetSoundInfo(SoundID);
if (Info.pAudioGroup)
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), Info.pAudioGroup->ID());
mChildren.push_back(pDep);
}
}
}
else if (Type == EPropertyType::Asset)
{
CAssetID ID = TPropCast<CAssetProperty>(pProp)->Value(pData);
if (ID.IsValid())
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID);
mChildren.push_back(pDep);
}
}
else if (Type == EPropertyType::AnimationSet)
{
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(pData);
CAssetID ID = Params.ID();
if (ID.IsValid())
{
// Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier
if (pProperties->Game() <= EGame::Echoes)
{
CCharPropertyDependency *pDep = new CCharPropertyDependency(pProp->IDString(true), ID, Params.CharacterIndex());
mChildren.push_back(pDep);
}
else
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID);
mChildren.push_back(pDep);
}
}
}
}
}
// Serialization constructor
IDependencyNode* IDependencyNode::ArchiveConstructor(EDependencyNodeType Type)
{
@@ -149,76 +213,10 @@ CScriptInstanceDependency* CScriptInstanceDependency::BuildTree(CScriptObject *p
{
CScriptInstanceDependency *pInst = new CScriptInstanceDependency();
pInst->mObjectType = pInstance->ObjectTypeID();
ParseStructDependencies(pInst, pInstance, pInstance->Template()->Properties());
pInst->ParseProperties(pInstance->Area()->Entry(), pInstance->Template()->Properties(), pInstance->PropertyData());
return pInst;
}
void CScriptInstanceDependency::ParseStructDependencies(CScriptInstanceDependency* pInst, CScriptObject* pInstance, CStructProperty *pStruct)
{
// Recursive function for parsing script dependencies and loading them into the script instance dependency
void* pPropertyData = pInstance->PropertyData();
for (uint32 PropertyIdx = 0; PropertyIdx < pStruct->NumChildren(); PropertyIdx++)
{
IProperty *pProp = pStruct->ChildByIndex(PropertyIdx);
EPropertyType Type = pProp->Type();
// Technically we aren't parsing array children, but it's not really worth refactoring this function
// to support it when there aren't any array properties that contain any asset references anyway...
if (Type == EPropertyType::Struct)
ParseStructDependencies(pInst, pInstance, TPropCast<CStructProperty>(pProp));
else if (Type == EPropertyType::Sound)
{
uint32 SoundID = TPropCast<CSoundProperty>(pProp)->Value(pPropertyData);
if (SoundID != -1)
{
CGameProject *pProj = pInstance->Area()->Entry()->Project();
SSoundInfo Info = pProj->AudioManager()->GetSoundInfo(SoundID);
if (Info.pAudioGroup)
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), Info.pAudioGroup->ID());
pInst->mChildren.push_back(pDep);
}
}
}
else if (Type == EPropertyType::Asset)
{
CAssetID ID = TPropCast<CAssetProperty>(pProp)->Value(pPropertyData);
if (ID.IsValid())
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID);
pInst->mChildren.push_back(pDep);
}
}
else if (Type == EPropertyType::AnimationSet)
{
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(pPropertyData);
CAssetID ID = Params.ID();
if (ID.IsValid())
{
// Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier
if (pStruct->Game() <= EGame::Echoes)
{
CCharPropertyDependency *pDep = new CCharPropertyDependency(pProp->IDString(true), ID, Params.CharacterIndex());
pInst->mChildren.push_back(pDep);
}
else
{
CPropertyDependency *pDep = new CPropertyDependency(pProp->IDString(true), ID);
pInst->mChildren.push_back(pDep);
}
}
}
}
}
// ************ CSetCharacterDependency ************
EDependencyNodeType CSetCharacterDependency::Type() const
{

View File

@@ -39,6 +39,7 @@ public:
virtual void Serialize(IArchive& rArc) = 0;
virtual void GetAllResourceReferences(std::set<CAssetID>& rOutSet) const;
virtual bool HasDependency(const CAssetID& rkID) const;
void ParseProperties(CResourceEntry* pParentEntry, CStructProperty* pProperties, void* pData);
// Serialization constructor
static IDependencyNode* ArchiveConstructor(EDependencyNodeType Type);
@@ -144,8 +145,6 @@ public:
// Static
static CScriptInstanceDependency* BuildTree(CScriptObject *pInstance);
protected:
static void ParseStructDependencies(CScriptInstanceDependency *pTree, CScriptObject* pInstance, CStructProperty *pStruct);
};
// Node representing an animset character. Indicates what index the character is within the animset.