Fixed issues in MP3 package list building
This commit is contained in:
parent
f72f82d519
commit
560706d285
|
@ -33,9 +33,11 @@ CAssetID::CAssetID(u64 ID, EIDLength Length)
|
|||
mID &= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void CAssetID::Write(IOutputStream& rOutput) const
|
||||
void CAssetID::Write(IOutputStream& rOutput, EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
||||
{
|
||||
if (mLength == e32Bit)
|
||||
EIDLength Length = (ForcedLength == eInvalidIDLength ? mLength : ForcedLength);
|
||||
|
||||
if (Length == e32Bit)
|
||||
rOutput.WriteLong(ToLong());
|
||||
else
|
||||
rOutput.WriteLongLong(ToLongLong());
|
||||
|
@ -53,9 +55,11 @@ CAssetID::CAssetID(IInputStream& rInput, EGame Game)
|
|||
*this = CAssetID(rInput, (Game <= eEchoes ? e32Bit : e64Bit));
|
||||
}
|
||||
|
||||
TString CAssetID::ToString() const
|
||||
TString CAssetID::ToString(EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
||||
{
|
||||
if (mLength == e32Bit)
|
||||
EIDLength Length = (ForcedLength == eInvalidIDLength ? mLength : ForcedLength);
|
||||
|
||||
if (Length == e32Bit)
|
||||
return TString::HexString(ToLong(), 8, false, true);
|
||||
else
|
||||
return TString::FromInt64(ToLongLong(), 16, 16).ToUpper();
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
CAssetID(u64 ID, EIDLength Length);
|
||||
CAssetID(IInputStream& rInput, EIDLength Length);
|
||||
CAssetID(IInputStream& rInput, EGame Game);
|
||||
void Write(IOutputStream& rOutput) const;
|
||||
TString ToString() const;
|
||||
void Write(IOutputStream& rOutput, EIDLength ForcedLength = eInvalidIDLength) const;
|
||||
TString ToString(EIDLength ForcedLength = eInvalidIDLength) const;
|
||||
bool IsValid() const;
|
||||
|
||||
// Operators
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); }
|
||||
virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); }
|
||||
|
||||
virtual void SerializeHexPrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializeHexPrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); }
|
||||
virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream, CAssetID::GameIDLength(Game())); }
|
||||
|
||||
virtual void SerializeHexPrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializeHexPrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
virtual void SerializePrimitive(TString& rValue) { WriteParam(*rValue); }
|
||||
virtual void SerializePrimitive(TWideString& rValue) { WriteParam(*rValue.ToUTF8()); }
|
||||
virtual void SerializePrimitive(CFourCC& rValue) { WriteParam(*rValue.ToString()); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { WriteParam(*rValue.ToString()); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { WriteParam(*rValue.ToString( CAssetID::GameIDLength(Game()) )); }
|
||||
|
||||
virtual void SerializeHexPrimitive(u8& rValue) { WriteParam(*TString::HexString(rValue, 2)); }
|
||||
virtual void SerializeHexPrimitive(u16& rValue) { WriteParam(*TString::HexString(rValue, 4)); }
|
||||
|
|
|
@ -225,7 +225,8 @@ HEADERS += \
|
|||
Resource/Cooker/CResourceCooker.h \
|
||||
Resource/CAudioMacro.h \
|
||||
CompressionUtil.h \
|
||||
Resource/Animation/CSourceAnimData.h
|
||||
Resource/Animation/CSourceAnimData.h \
|
||||
Resource/CMapArea.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ************
|
||||
|
|
|
@ -140,7 +140,7 @@ const SSetCharacter* CAnimationParameters::GetCurrentSetCharacter(s32 NodeIndex
|
|||
{
|
||||
CAnimSet *pSet = AnimSet();
|
||||
|
||||
if (pSet && pSet->Type() == eAnimSet)
|
||||
if (pSet && (pSet->Type() == eAnimSet || pSet->Type() == eCharacter))
|
||||
{
|
||||
if (NodeIndex == -1)
|
||||
NodeIndex = mCharIndex;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef CMAPAREA_H
|
||||
#define CMAPAREA_H
|
||||
|
||||
#include "CResource.h"
|
||||
|
||||
// Barebones class
|
||||
class CMapArea : public CResource
|
||||
{
|
||||
friend class CUnsupportedFormatLoader;
|
||||
CAssetID mNameString;
|
||||
|
||||
public:
|
||||
CMapArea(CResourceEntry *pEntry = 0)
|
||||
: CResource(pEntry)
|
||||
{}
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree();
|
||||
pTree->AddDependency(mNameString);
|
||||
return pTree;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CMAPAREA_H
|
|
@ -242,7 +242,6 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
|
|||
CResTypeInfo *pType = new CResTypeInfo(eMapArea, "Area Map");
|
||||
AddExtension(pType, "MAPA", ePrimeDemo, eCorruption);
|
||||
pType->mHidden = true;
|
||||
pType->mCanHaveDependencies = false;
|
||||
}
|
||||
{
|
||||
CResTypeInfo *pType = new CResTypeInfo(eMapWorld, "World Map");
|
||||
|
@ -371,7 +370,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
|
|||
}
|
||||
{
|
||||
CResTypeInfo *pType = new CResTypeInfo(eStateMachine2, "State Machine 2");
|
||||
AddExtension(pType, "FSM2", eEchoesDemo, eEchoes);
|
||||
AddExtension(pType, "FSM2", eEchoesDemo, eCorruption);
|
||||
pType->mRawExtension = "fsm2";
|
||||
}
|
||||
{
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
// Must be included on every CResource subclass.
|
||||
#define DECLARE_RESOURCE_TYPE(ResTypeEnum) \
|
||||
public: \
|
||||
virtual EResType Type() const \
|
||||
{ \
|
||||
return ResTypeEnum; \
|
||||
} \
|
||||
\
|
||||
static EResType StaticType() \
|
||||
{ \
|
||||
return ResTypeEnum; \
|
||||
|
@ -52,6 +47,7 @@ public:
|
|||
|
||||
inline CResourceEntry* Entry() const { return mpEntry; }
|
||||
inline CResTypeInfo* TypeInfo() const { return mpEntry->TypeInfo(); }
|
||||
inline EResType Type() const { return mpEntry->TypeInfo()->Type(); }
|
||||
inline TString Source() const { return mpEntry ? mpEntry->CookedAssetPath(true).GetFileName() : ""; }
|
||||
inline TString FullSource() const { return mpEntry ? mpEntry->CookedAssetPath(true) : ""; }
|
||||
inline CAssetID ID() const { return mpEntry ? mpEntry->ID() : CAssetID::skInvalidID64; }
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
case eDynamicCollision: return new CCollisionMeshGroup(pEntry);
|
||||
case eDependencyGroup: return new CDependencyGroup(pEntry);
|
||||
case eFont: return new CFont(pEntry);
|
||||
case eMapArea: return new CMapArea(pEntry);
|
||||
case eModel: return new CModel(pEntry);
|
||||
case eScan: return new CScan(pEntry);
|
||||
case eSkeleton: return new CSkeleton(pEntry);
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
case eFont: pRes = CFontLoader::LoadFONT(rInput, pEntry); break;
|
||||
case eGuiFrame: pRes = CUnsupportedFormatLoader::LoadFRME(rInput, pEntry); break;
|
||||
case eHintSystem: pRes = CUnsupportedFormatLoader::LoadHINT(rInput, pEntry); break;
|
||||
case eMapArea: pRes = CUnsupportedFormatLoader::LoadMAPA(rInput, pEntry); break;
|
||||
case eMapWorld: pRes = CUnsupportedFormatLoader::LoadMAPW(rInput, pEntry); break;
|
||||
case eMapUniverse: pRes = CUnsupportedFormatLoader::LoadMAPU(rInput, pEntry); break;
|
||||
case eMidi: pRes = CUnsupportedFormatLoader::LoadCSNG(rInput, pEntry); break;
|
||||
|
@ -97,6 +99,12 @@ public:
|
|||
case eTexture: pRes = CTextureDecoder::LoadTXTR(rInput, pEntry); break;
|
||||
case eWorld: pRes = CWorldLoader::LoadMLVL(rInput, pEntry); break;
|
||||
|
||||
case eStateMachine:
|
||||
// AFSM and FSMC currently unsupported
|
||||
if (pEntry->Game() == eCorruptionProto || pEntry->Game() == eCorruption)
|
||||
pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
|
||||
break;
|
||||
|
||||
case eBurstFireData:
|
||||
case eParticle:
|
||||
case eParticleElectric:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "CUnsupportedFormatLoader.h"
|
||||
#include "Core/GameProject/CGameProject.h"
|
||||
#include "Core/GameProject/CResourceIterator.h"
|
||||
#include "Core/Resource/CWorld.h"
|
||||
|
||||
CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry)
|
||||
{
|
||||
|
@ -253,11 +255,12 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
|
|||
u32 NumUnkA = rFSM2.ReadLong();
|
||||
u32 NumUnkB = rFSM2.ReadLong();
|
||||
u32 NumUnkC = rFSM2.ReadLong();
|
||||
ASSERT(Version == 1);
|
||||
ASSERT(Version == 1 || Version == 2);
|
||||
|
||||
for (u32 iState = 0; iState < NumStates; iState++)
|
||||
{
|
||||
rFSM2.ReadString();
|
||||
if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR);
|
||||
u32 UnkCount = rFSM2.ReadLong();
|
||||
|
||||
for (u32 iUnk = 0; iUnk < UnkCount; iUnk++)
|
||||
|
@ -270,6 +273,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
|
|||
for (u32 iUnkA = 0; iUnkA < NumUnkA; iUnkA++)
|
||||
{
|
||||
rFSM2.ReadString();
|
||||
if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR);
|
||||
rFSM2.Seek(0x4, SEEK_CUR);
|
||||
u32 UnkCount = rFSM2.ReadLong();
|
||||
|
||||
|
@ -285,6 +289,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
|
|||
for (u32 iUnkB = 0; iUnkB < NumUnkB; iUnkB++)
|
||||
{
|
||||
rFSM2.ReadString();
|
||||
if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR);
|
||||
u32 UnkCount = rFSM2.ReadLong();
|
||||
|
||||
for (u32 iUnkB2 = 0; iUnkB2 < UnkCount; iUnkB2++)
|
||||
|
@ -297,6 +302,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
|
|||
for (u32 iUnkC = 0; iUnkC < NumUnkC; iUnkC++)
|
||||
{
|
||||
rFSM2.ReadString();
|
||||
if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR);
|
||||
u32 UnkCount = rFSM2.ReadLong();
|
||||
|
||||
for (u32 iUnkC2 = 0; iUnkC2 < UnkCount; iUnkC2++)
|
||||
|
@ -305,7 +311,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
|
|||
rFSM2.Seek(0x4, SEEK_CUR);
|
||||
}
|
||||
|
||||
pOut->AddDependency( CAssetID(rFSM2, eEchoes) );
|
||||
pOut->AddDependency( CAssetID(rFSM2, pEntry->Game()) );
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
@ -362,20 +368,83 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
|
|||
rHINT.ReadString(); // Skip hint name
|
||||
rHINT.Seek(0x8, SEEK_CUR); // Skip unknown + appear time
|
||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Pop-up STRG
|
||||
rHINT.Seek(0x8, SEEK_CUR); // Skip unknowns
|
||||
rHINT.Seek(0x4, SEEK_CUR); // Skip unknowns
|
||||
|
||||
if (Game <= eEchoes)
|
||||
{
|
||||
rHINT.Seek(0x4, SEEK_CUR);
|
||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MLVL
|
||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MREA
|
||||
rHINT.Seek(0x4, SEEK_CUR); // Skip target room index
|
||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Map STRG
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
u32 NumLocations = rHINT.ReadLong();
|
||||
|
||||
for (u32 iLoc = 0; iLoc < NumLocations; iLoc++)
|
||||
{
|
||||
rHINT.Seek(0x14, SEEK_CUR); // Skip world/area ID, area index
|
||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Objective string
|
||||
rHINT.Seek(0xC, SEEK_CUR); // Skip unknown data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pGroup;
|
||||
}
|
||||
|
||||
CMapArea* CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMAPA*/, CResourceEntry *pEntry)
|
||||
{
|
||||
TResPtr<CMapArea> pMap = new CMapArea(pEntry);
|
||||
|
||||
// We don't actually read the file. Just fetch the name string so we can build the dependency tree.
|
||||
CAssetID MapAreaID = pMap->ID();
|
||||
|
||||
// Find a MapWorld that contains this MapArea
|
||||
CAssetID MapWorldID;
|
||||
u32 WorldIndex = -1;
|
||||
|
||||
for (TResourceIterator<eMapWorld> It; It; ++It)
|
||||
{
|
||||
CDependencyGroup *pGroup = (CDependencyGroup*) It->Load();
|
||||
|
||||
for (u32 AreaIdx = 0; AreaIdx < pGroup->NumDependencies(); AreaIdx++)
|
||||
{
|
||||
if (pGroup->DependencyByIndex(AreaIdx) == MapAreaID)
|
||||
{
|
||||
WorldIndex = AreaIdx;
|
||||
MapWorldID = pGroup->ID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WorldIndex != -1)
|
||||
break;
|
||||
}
|
||||
|
||||
// Find a world that contains this MapWorld
|
||||
if (WorldIndex != -1)
|
||||
{
|
||||
for (TResourceIterator<eWorld> It; It; ++It)
|
||||
{
|
||||
CWorld *pWorld = (CWorld*) It->Load();
|
||||
CDependencyGroup *pMapWorld = (CDependencyGroup*) pWorld->MapWorld();
|
||||
|
||||
if (pMapWorld && pMapWorld->ID() == MapWorldID)
|
||||
{
|
||||
CStringTable *pNameString = pWorld->AreaName(WorldIndex);
|
||||
pMap->mNameString = (pNameString ? pNameString->ID() : CAssetID::InvalidID(pEntry->Game()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pMap->Entry()->ResourceStore()->DestroyUnreferencedResources();
|
||||
return pMap;
|
||||
}
|
||||
|
||||
CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry)
|
||||
{
|
||||
u32 Magic = rMAPW.ReadLong();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Core/Resource/CAudioMacro.h"
|
||||
#include "Core/Resource/CDependencyGroup.h"
|
||||
#include "Core/Resource/CMapArea.h"
|
||||
|
||||
// This class is responsible for loading formats that aren't yet fully supported.
|
||||
// This is needed so we have access to the full dependency list of all resource types.
|
||||
|
@ -19,6 +20,7 @@ public:
|
|||
static CDependencyGroup* LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry);
|
||||
static CDependencyGroup* LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry);
|
||||
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
|
||||
static CMapArea* LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry);
|
||||
static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
|
||||
static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
|
||||
static CDependencyGroup* LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry);
|
||||
|
|
|
@ -27,7 +27,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
|||
{
|
||||
mpWorld->mpWorldName = gpResourceStore->LoadResource(rMLVL.ReadLongLong(), eStringTable);
|
||||
rMLVL.Seek(0x4, SEEK_CUR); // Skipping unknown value
|
||||
mpWorld->mpSaveWorld = gpResourceStore->LoadResource(rMLVL.ReadLongLong(), eStringTable);
|
||||
mpWorld->mpSaveWorld = gpResourceStore->LoadResource(rMLVL.ReadLongLong(), eSaveWorld);
|
||||
mpWorld->mpDefaultSkybox = gpResourceStore->LoadResource(rMLVL.ReadLongLong(), eModel);
|
||||
}
|
||||
|
||||
|
|
|
@ -655,7 +655,7 @@ CModel* CScriptNode::ActiveModel() const
|
|||
{
|
||||
if (mpDisplayAsset->Type() == eModel)
|
||||
return static_cast<CModel*>(mpDisplayAsset.RawPointer());
|
||||
else if (mpDisplayAsset->Type() == eAnimSet)
|
||||
else if (mpDisplayAsset->Type() == eAnimSet || mpDisplayAsset->Type() == eCharacter)
|
||||
return static_cast<CAnimSet*>(mpDisplayAsset.RawPointer())->Character(mCharIndex)->pModel;
|
||||
}
|
||||
|
||||
|
@ -664,7 +664,7 @@ CModel* CScriptNode::ActiveModel() const
|
|||
|
||||
CAnimSet* CScriptNode::ActiveAnimSet() const
|
||||
{
|
||||
if (mpDisplayAsset && mpDisplayAsset->Type() == eAnimSet)
|
||||
if (mpDisplayAsset && (mpDisplayAsset->Type() == eAnimSet || mpDisplayAsset->Type() == eCharacter))
|
||||
return static_cast<CAnimSet*>(mpDisplayAsset.RawPointer());
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -739,7 +739,7 @@ void CScriptNode::SetDisplayAsset(CResource *pRes)
|
|||
{
|
||||
mpDisplayAsset = pRes;
|
||||
|
||||
bool IsAnimSet = (pRes && pRes->Type() == eAnimSet);
|
||||
bool IsAnimSet = (pRes && (pRes->Type() == eAnimSet || pRes->Type() == eCharacter));
|
||||
mCharIndex = (IsAnimSet ? mpInstance->ActiveCharIndex() : -1);
|
||||
mAnimIndex = (IsAnimSet ? mpInstance->ActiveAnimIndex() : -1);
|
||||
|
||||
|
|
|
@ -78,9 +78,13 @@ void CProjectSettingsDialog::SetupPackagesList()
|
|||
void CProjectSettingsDialog::CookPackage()
|
||||
{
|
||||
u32 PackageIdx = mpUI->PackagesList->currentRow();
|
||||
CPackage *pPackage = mpProject->PackageByIndex(PackageIdx);
|
||||
pPackage->Cook();
|
||||
SetupPackagesList();
|
||||
|
||||
if (PackageIdx != -1)
|
||||
{
|
||||
CPackage *pPackage = mpProject->PackageByIndex(PackageIdx);
|
||||
pPackage->Cook();
|
||||
SetupPackagesList();
|
||||
}
|
||||
}
|
||||
|
||||
void CProjectSettingsDialog::CookAllDirtyPackages()
|
||||
|
|
|
@ -763,7 +763,7 @@ void CModelEditorWindow::ConvertToDDS()
|
|||
if (Input.isEmpty()) return;
|
||||
|
||||
TString TexFilename = TO_TSTRING(Input);
|
||||
TResPtr<CTexture> pTex = gpResourceStore->LoadResource(TexFilename);
|
||||
CTexture *pTex = CTextureDecoder::LoadDDS( CFileInStream(TexFilename, IOUtil::eLittleEndian), nullptr );
|
||||
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds";
|
||||
|
||||
CFileOutStream Out(OutName, IOUtil::eLittleEndian);
|
||||
|
@ -775,6 +775,8 @@ void CModelEditorWindow::ConvertToDDS()
|
|||
if (!Success) QMessageBox::warning(this, "Error", "Couldn't write output DDS!");
|
||||
else QMessageBox::information(this, "Success", "Successfully converted to DDS!");
|
||||
}
|
||||
|
||||
delete pTex;
|
||||
}
|
||||
|
||||
void CModelEditorWindow::ConvertToTXTR()
|
||||
|
|
Loading…
Reference in New Issue