From 8a66e393e7e9880a580ffd1f22720e47d34d2828 Mon Sep 17 00:00:00 2001 From: Aruki Date: Tue, 31 Jan 2017 21:56:53 -0700 Subject: [PATCH] Added CResTypeInfo class --- src/Common/CFourCC.h | 29 +- src/Core/Core.pro | 7 +- src/Core/GameProject/CGameExporter.cpp | 2 +- src/Core/GameProject/CPackage.cpp | 4 +- src/Core/GameProject/CResourceEntry.cpp | 22 +- src/Core/GameProject/CResourceEntry.h | 6 +- src/Core/GameProject/CResourceStore.cpp | 42 +- src/Core/GameProject/CResourceStore.h | 1 - src/Core/GameProject/CVirtualDirectory.cpp | 16 +- src/Core/GameProject/CVirtualDirectory.h | 8 +- src/Core/Resource/CResTypeInfo.cpp | 362 ++++++++++++++++++ src/Core/Resource/CResTypeInfo.h | 70 ++++ src/Core/Resource/CResource.cpp | 243 ------------ src/Core/Resource/CResource.h | 11 +- src/Editor/CProjectOverviewDialog.cpp | 2 +- .../ResourceBrowser/CResourceTableModel.h | 4 +- 16 files changed, 503 insertions(+), 326 deletions(-) create mode 100644 src/Core/Resource/CResTypeInfo.cpp create mode 100644 src/Core/Resource/CResTypeInfo.h delete mode 100644 src/Core/Resource/CResource.cpp diff --git a/src/Common/CFourCC.h b/src/Common/CFourCC.h index 3a8a76fe..60938b93 100644 --- a/src/Common/CFourCC.h +++ b/src/Common/CFourCC.h @@ -64,14 +64,7 @@ public: CFourCC Out; for (int iChr = 0; iChr < 4; iChr++) - { - char Chr = (*this)[iChr]; - - if ((Chr >= 0x61) && (Chr <= 0x7A)) - Chr -= 0x20; - - Out.mFourCC |= (Chr << (8 * (3 - iChr))); - } + Out.mFourCC_Chars[iChr] = TString::CharToUpper(mFourCC_Chars[iChr]); return CFourCC(Out); } @@ -100,6 +93,26 @@ public: return ((char*)(&mFourCC))[Index]; } + inline TString operator+(const char *pkText) const + { + return ToString() + pkText; + } + + inline TString operator+(const TString& rkStr) const + { + return ToString() + rkStr; + } + + inline friend TString operator+(const char *pkText, const CFourCC& rkFourCC) + { + return pkText + rkFourCC.ToString(); + } + + inline friend TString operator+(const TString& rkStr, const CFourCC& rkFourCC) + { + return rkStr + rkFourCC.ToString(); + } + inline CFourCC& operator=(const char *pkSrc) { mFourCC = FOURCC(pkSrc); return *this; } inline CFourCC& operator=(const TString& rkSrc) { mFourCC = FOURCC(rkSrc); return *this; } inline CFourCC& operator=(u32 Src) { mFourCC = Src; return *this; } diff --git a/src/Core/Core.pro b/src/Core/Core.pro index 1ea3b1b3..5d45af02 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -217,7 +217,8 @@ HEADERS += \ Resource/Animation/IMetaAnimation.h \ GameProject/CAssetNameMap.h \ GameProject/AssetNameGeneration.h \ - GameProject/CGameInfo.h + GameProject/CGameInfo.h \ + Resource/CResTypeInfo.h # Source Files SOURCES += \ @@ -256,7 +257,6 @@ SOURCES += \ Resource/CLight.cpp \ Resource/CMaterial.cpp \ Resource/CMaterialPass.cpp \ - Resource/CResource.cpp \ Resource/CTexture.cpp \ Resource/CWorld.cpp \ Scene/CCollisionNode.cpp \ @@ -322,4 +322,5 @@ SOURCES += \ Resource/Animation/IMetaTransition.cpp \ GameProject/AssetNameGeneration.cpp \ GameProject/CAssetNameMap.cpp \ - GameProject/CGameInfo.cpp + GameProject/CGameInfo.cpp \ + Resource/CResTypeInfo.cpp diff --git a/src/Core/GameProject/CGameExporter.cpp b/src/Core/GameProject/CGameExporter.cpp index 5582250d..c42291ab 100644 --- a/src/Core/GameProject/CGameExporter.cpp +++ b/src/Core/GameProject/CGameExporter.cpp @@ -518,7 +518,7 @@ void CGameExporter::ExportResource(SResourceInstance& rRes) // Register resource and write to file TString Directory, Name; mNameMap.GetNameInfo(rRes.ResourceID, Directory, Name); - CResourceEntry *pEntry = mpStore->RegisterResource(rRes.ResourceID, CResource::ResTypeForExtension(rRes.ResourceType), Directory, Name); + CResourceEntry *pEntry = mpStore->RegisterResource(rRes.ResourceID, CResTypeInfo::TypeForCookedExtension(mGame, rRes.ResourceType)->Type(), Directory, Name); #if EXPORT_COOKED // Save cooked asset diff --git a/src/Core/GameProject/CPackage.cpp b/src/Core/GameProject/CPackage.cpp index 3e1f5315..51749485 100644 --- a/src/Core/GameProject/CPackage.cpp +++ b/src/Core/GameProject/CPackage.cpp @@ -255,7 +255,7 @@ void CPackage::CompareOriginalAssetList(const std::list& rkNewList) if (NewListSet.find(ID) == NewListSet.end()) { CResourceEntry *pEntry = gpResourceStore->FindEntry(ID); - TString Extension = (pEntry ? "." + GetResourceCookedExtension(pEntry->ResourceType(), pEntry->Game()) : ""); + TString Extension = (pEntry ? "." + pEntry->CookedExtension() : ""); Log::Error("Missing resource: " + ID.ToString() + Extension); } } @@ -268,7 +268,7 @@ void CPackage::CompareOriginalAssetList(const std::list& rkNewList) if (OldListSet.find(ID) == OldListSet.end()) { CResourceEntry *pEntry = gpResourceStore->FindEntry(ID); - TString Extension = (pEntry ? "." + GetResourceCookedExtension(pEntry->ResourceType(), pEntry->Game()) : ""); + TString Extension = (pEntry ? "." + pEntry->CookedExtension() : ""); Log::Error("Extra resource: " + ID.ToString() + Extension); } } diff --git a/src/Core/GameProject/CResourceEntry.cpp b/src/Core/GameProject/CResourceEntry.cpp index c448a3d6..484680b3 100644 --- a/src/Core/GameProject/CResourceEntry.cpp +++ b/src/Core/GameProject/CResourceEntry.cpp @@ -16,12 +16,14 @@ CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID, , mpStore(pStore) , mpDependencies(nullptr) , mID(rkID) - , mType(Type) , mpDirectory(nullptr) , mName(rkFilename) , mCachedSize(-1) , mCachedUppercaseName(rkFilename.ToUpper()) { + mpTypeInfo = CResTypeInfo::FindTypeInfo(Type); + ASSERT(mpTypeInfo); + if (Transient) mFlags |= eREF_Transient; mpDirectory = mpStore->GetVirtualDirectory(rkDir, Transient, true); @@ -93,7 +95,7 @@ bool CResourceEntry::HasCookedVersion() const TString CResourceEntry::RawAssetPath(bool Relative) const { - TWideString Ext = GetResourceRawExtension(mType, mGame).ToUTF16(); + TWideString Ext = RawExtension().ToUTF16(); TWideString Path = mpDirectory ? mpDirectory->FullPath() : L""; TWideString Name = mName + L"." + Ext; return ((IsTransient() || Relative) ? Path + Name : mpStore->RawDir(false) + Path + Name); @@ -101,12 +103,12 @@ TString CResourceEntry::RawAssetPath(bool Relative) const TString CResourceEntry::RawExtension() const { - return GetResourceRawExtension(mType, mGame); + return mpTypeInfo->RawExtension(); } TString CResourceEntry::CookedAssetPath(bool Relative) const { - TWideString Ext = GetResourceCookedExtension(mType, mGame).ToUTF16(); + TWideString Ext = CookedExtension().ToString().ToUTF16(); TWideString Path = mpDirectory ? mpDirectory->FullPath() : L""; TWideString Name = mName + L"." + Ext; return ((IsTransient() || Relative) ? Path + Name : mpStore->CookedDir(false) + Path + Name); @@ -114,7 +116,7 @@ TString CResourceEntry::CookedAssetPath(bool Relative) const CFourCC CResourceEntry::CookedExtension() const { - return CFourCC( GetResourceCookedExtension(mType, mGame) ); + return mpTypeInfo->CookedExtension(mGame); } bool CResourceEntry::IsInDirectory(CVirtualDirectory *pDir) const @@ -178,7 +180,7 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/) bool ShouldCollectGarbage = false; // Save raw resource - if (ResourceSupportsSerialization(ResourceType())) + if (mpTypeInfo->CanBeSerialized()) { ShouldCollectGarbage = !IsLoaded(); @@ -190,7 +192,9 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/) TString Dir = Path.GetFileDirectory(); FileUtil::CreateDirectory(Dir.ToUTF16()); - CXMLWriter Writer(Path, GetResourceSerialName(ResourceType()), 0, mGame); + TString SerialName = mpTypeInfo->TypeName(); + SerialName.RemoveWhitespace(); + CXMLWriter Writer(Path, SerialName, 0, mGame); mpResource->Serialize(Writer); } @@ -288,7 +292,7 @@ bool CResourceEntry::CanMoveTo(const TWideString& rkDir, const TWideString& rkNa // We need to validate the path isn't taken already - either the directory doesn't exist, or doesn't have a resource by this name CVirtualDirectory *pDir = mpStore->GetVirtualDirectory(rkDir, false, false); - if (pDir && pDir->FindChildResource(rkName, mType)) return false; + if (pDir && pDir->FindChildResource(rkName, ResourceType())) return false; // All checks are true return true; @@ -309,7 +313,7 @@ bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName) if (pNewDir == mpDirectory && rkName == mName) return false; // Check if we can legally move to this spot - ASSERT(pNewDir->FindChildResource(rkName, mType) == nullptr); // this check should be guaranteed to pass due to CanMoveTo() having already checked it + ASSERT(pNewDir->FindChildResource(rkName, ResourceType()) == nullptr); // this check should be guaranteed to pass due to CanMoveTo() having already checked it mpDirectory = pNewDir; mName = rkName; diff --git a/src/Core/GameProject/CResourceEntry.h b/src/Core/GameProject/CResourceEntry.h index 84f68f10..edcc6635 100644 --- a/src/Core/GameProject/CResourceEntry.h +++ b/src/Core/GameProject/CResourceEntry.h @@ -2,6 +2,7 @@ #define CRESOURCEENTRY_H #include "CVirtualDirectory.h" +#include "Core/Resource/CResTypeInfo.h" #include "Core/Resource/EResType.h" #include #include @@ -26,10 +27,10 @@ DECLARE_FLAGS(EResEntryFlag, FResEntryFlags) class CResourceEntry { CResource *mpResource; + CResTypeInfo *mpTypeInfo; CResourceStore *mpStore; CDependencyTree *mpDependencies; CAssetID mID; - EResType mType; EGame mGame; CVirtualDirectory *mpDirectory; TWideString mName; @@ -74,6 +75,7 @@ public: inline bool IsCategorized() const { return mpDirectory && mpDirectory->FullPath() != L"Uncategorized\\"; } inline bool IsNamed() const { return mName != mID.ToString().ToUTF16(); } inline CResource* Resource() const { return mpResource; } + inline CResTypeInfo* TypeInfo() const { return mpTypeInfo; } inline CResourceStore* ResourceStore() const { return mpStore; } inline CDependencyTree* Dependencies() const { return mpDependencies; } inline CAssetID ID() const { return mID; } @@ -82,7 +84,7 @@ public: inline TWideString DirectoryPath() const { return mpDirectory->FullPath(); } inline TWideString Name() const { return mName; } inline const TWideString& UppercaseName() const { return mCachedUppercaseName; } - inline EResType ResourceType() const { return mType; } + inline EResType ResourceType() const { return mpTypeInfo->Type(); } inline bool IsTransient() const { return mFlags.HasFlag(eREF_Transient); } inline bool IsHidden() const { return mFlags.HasFlag(eREF_Hidden); } diff --git a/src/Core/GameProject/CResourceStore.cpp b/src/Core/GameProject/CResourceStore.cpp index cf64915e..521ee8d0 100644 --- a/src/Core/GameProject/CResourceStore.cpp +++ b/src/Core/GameProject/CResourceStore.cpp @@ -21,7 +21,7 @@ CResourceStore::CResourceStore(const TWideString& rkDatabasePath) , mDatabaseDirty(false) , mCacheFileDirty(false) { - mpDatabaseRoot = new CVirtualDirectory(); + mpDatabaseRoot = new CVirtualDirectory(this); mDatabasePath = FileUtil::MakeAbsolute(rkDatabasePath.GetFileDirectory()); mDatabaseName = rkDatabasePath.GetFileName(); } @@ -100,7 +100,7 @@ void CResourceStore::SerializeResourceDatabase(IArchive& rArc) for (auto Iter = Resources.begin(); Iter != Resources.end(); Iter++) { SDatabaseResource& rRes = *Iter; - RegisterResource(rRes.ID, CResource::ResTypeForExtension(rRes.Type), rRes.Directory, rRes.Name); + RegisterResource(rRes.ID, CResTypeInfo::TypeForCookedExtension(rArc.Game(), rRes.Type)->Type(), rRes.Directory, rRes.Name); } } } @@ -111,7 +111,7 @@ void CResourceStore::LoadResourceDatabase() TString Path = DatabasePath().ToUTF8(); if (!mpDatabaseRoot) - mpDatabaseRoot = new CVirtualDirectory(); + mpDatabaseRoot = new CVirtualDirectory(this); CXMLReader Reader(Path); @@ -238,7 +238,7 @@ void CResourceStore::SetProject(CGameProject *pProj) TWideString DatabasePath = mpProj->ResourceDBPath(false); mDatabasePath = DatabasePath.GetFileDirectory(); mDatabaseName = DatabasePath.GetFileName(); - mpDatabaseRoot = new CVirtualDirectory(); + mpDatabaseRoot = new CVirtualDirectory(this); mGame = mpProj->Game(); } } @@ -296,7 +296,7 @@ CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TWideString& rkPath if (AllowCreate) { - CVirtualDirectory *pDir = new CVirtualDirectory(rkPath); + CVirtualDirectory *pDir = new CVirtualDirectory(rkPath, this); mTransientRoots.push_back(pDir); return pDir; } @@ -409,7 +409,7 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT if (DataBuffer.empty()) return nullptr; CMemoryInStream MemStream(DataBuffer.data(), DataBuffer.size(), IOUtil::eBigEndian); - EResType Type = CResource::ResTypeForExtension(rkType); + EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, rkType)->Type(); CResourceEntry *pEntry = RegisterTransientResource(Type, rkID); CResource *pRes = pEntry->LoadCooked(MemStream); return pRes; @@ -423,7 +423,7 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT if (pEntry) return pEntry->Load(); // Check in transient load directory - this only works for cooked - EResType Type = CResource::ResTypeForExtension(rkType); + EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, rkType)->Type(); if (Type != eInvalidResType) { @@ -490,7 +490,7 @@ CResource* CResourceStore::LoadResource(const TWideString& rkPath) // Determine type TString PathUTF8 = rkPath.ToUTF8(); TString Extension = TString(PathUTF8).GetFileExtension().ToUpper(); - EResType Type = CResource::ResTypeForExtension(Extension); + EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, Extension)->Type(); if (Type == eInvalidResType) { @@ -527,32 +527,6 @@ void CResourceStore::TrackLoadedResource(CResourceEntry *pEntry) mLoadedResources[pEntry->ID()] = pEntry; } -CFourCC CResourceStore::ResourceTypeByID(const CAssetID& rkID, const TStringList& rkPossibleTypes) const -{ - if (!rkID.IsValid()) return eInvalidResType; - if (rkPossibleTypes.size() == 1) return CFourCC(rkPossibleTypes.front()); - - // Check for existing entry - auto Find = mResourceEntries.find(rkID); - if (Find != mResourceEntries.end()) - return GetResourceCookedExtension(Find->second->ResourceType(), Find->second->Game()); - - // Determine extension from filesystem - try every extension until we find the file - TString PathBase = mTransientLoadDir.ToUTF8() + rkID.ToString() + '.'; - - for (auto It = rkPossibleTypes.begin(); It != rkPossibleTypes.end(); It++) - { - TString NewPath = PathBase + *It; - - if (FileUtil::Exists(NewPath)) - return CFourCC(*It); - } - - // Couldn't find one, so return unknown. Note that it'd be possible to look up the extension from the - // filesystem even if it's not one of the provided possible types, but this would be too slow. - return "UNKN"; -} - void CResourceStore::DestroyUnreferencedResources() { // This can be updated to avoid the do-while loop when reference lookup is implemented. diff --git a/src/Core/GameProject/CResourceStore.h b/src/Core/GameProject/CResourceStore.h index 86216a93..e5802486 100644 --- a/src/Core/GameProject/CResourceStore.h +++ b/src/Core/GameProject/CResourceStore.h @@ -72,7 +72,6 @@ public: CResource* LoadResource(const CAssetID& rkID, const CFourCC& rkType); CResource* LoadResource(const TWideString& rkPath); void TrackLoadedResource(CResourceEntry *pEntry); - CFourCC ResourceTypeByID(const CAssetID& rkID, const TStringList& rkPossibleTypes) const; void DestroyUnreferencedResources(); bool DeleteResourceEntry(CResourceEntry *pEntry); void SetTransientLoadDir(const TString& rkDir); diff --git a/src/Core/GameProject/CVirtualDirectory.cpp b/src/Core/GameProject/CVirtualDirectory.cpp index fb7544a3..51556139 100644 --- a/src/Core/GameProject/CVirtualDirectory.cpp +++ b/src/Core/GameProject/CVirtualDirectory.cpp @@ -4,16 +4,16 @@ #include "Core/Resource/CResource.h" #include -CVirtualDirectory::CVirtualDirectory() - : mpParent(nullptr) +CVirtualDirectory::CVirtualDirectory(CResourceStore *pStore) + : mpParent(nullptr), mpStore(pStore) {} -CVirtualDirectory::CVirtualDirectory(const TWideString& rkName) - : mpParent(nullptr), mName(rkName) +CVirtualDirectory::CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore) + : mpParent(nullptr), mName(rkName), mpStore(pStore) {} -CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName) - : mpParent(pParent), mName(rkName) +CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore) + : mpParent(pParent), mName(rkName), mpStore(pStore) {} CVirtualDirectory::~CVirtualDirectory() @@ -93,7 +93,7 @@ CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkPath) else if (!Name.IsEmpty()) { TWideString Ext = Name.GetFileExtension(); - EResType Type = CResource::ResTypeForExtension(Ext); + EResType Type = CResTypeInfo::TypeForCookedExtension(mpStore->Game(), Ext)->Type(); return FindChildResource(Name.GetFileName(false), Type); } @@ -137,7 +137,7 @@ void CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt if (!pSubdir) { - pSubdir = new CVirtualDirectory(this, DirName); + pSubdir = new CVirtualDirectory(this, DirName, mpStore); mSubdirectories.push_back(pSubdir); std::sort(mSubdirectories.begin(), mSubdirectories.end(), [](CVirtualDirectory *pLeft, CVirtualDirectory *pRight) -> bool { diff --git a/src/Core/GameProject/CVirtualDirectory.h b/src/Core/GameProject/CVirtualDirectory.h index f2fecd32..8e48f541 100644 --- a/src/Core/GameProject/CVirtualDirectory.h +++ b/src/Core/GameProject/CVirtualDirectory.h @@ -8,18 +8,20 @@ #include class CResourceEntry; +class CResourceStore; class CVirtualDirectory { CVirtualDirectory *mpParent; + CResourceStore *mpStore; TWideString mName; std::vector mSubdirectories; std::vector mResources; public: - CVirtualDirectory(); - CVirtualDirectory(const TWideString& rkName); - CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName); + CVirtualDirectory(CResourceStore *pStore); + CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore); + CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore); ~CVirtualDirectory(); bool IsEmpty() const; diff --git a/src/Core/Resource/CResTypeInfo.cpp b/src/Core/Resource/CResTypeInfo.cpp new file mode 100644 index 00000000..2adc7c3d --- /dev/null +++ b/src/Core/Resource/CResTypeInfo.cpp @@ -0,0 +1,362 @@ +#include "CResTypeInfo.h" +#include +#include + +std::unordered_map CResTypeInfo::smTypeMap; + +CResTypeInfo::CResTypeInfo(EResType Type, const TString& rkTypeName) + : mType(Type) + , mTypeName(rkTypeName) + , mHidden(false) + , mCanBeSerialized(false) +{ +#if !PUBLIC_RELEASE + ASSERT(smTypeMap.find(Type) == smTypeMap.end()); +#endif + smTypeMap[Type] = this; +} + +CResTypeInfo::~CResTypeInfo() +{ + // shouldn't happen - we want to just create these at launch and keep them around forever + ASSERT(false); +} + +bool CResTypeInfo::IsInGame(EGame Game) const +{ + for (u32 iGame = 0; iGame < mCookedExtensions.size(); iGame++) + { + if (mCookedExtensions[iGame].Game == Game) + return true; + } + return false; +} + +CFourCC CResTypeInfo::CookedExtension(EGame Game) const +{ + for (u32 iGame = 0; iGame < mCookedExtensions.size(); iGame++) + { + if (mCookedExtensions[iGame].Game == Game) + return mCookedExtensions[iGame].CookedExt; + } + + return "NONE"; +} + +// ************ STATIC ************ +void CResTypeInfo::GetAllTypesInGame(EGame Game, std::list& rOut) +{ + for (auto Iter = smTypeMap.begin(); Iter != smTypeMap.end(); Iter++) + { + CResTypeInfo *pType = Iter->second; + + if (pType->IsInGame(Game)) + rOut.push_back(pType); + } +} + +CResTypeInfo* CResTypeInfo::TypeForCookedExtension(EGame Game, CFourCC Ext) +{ + // Extensions can vary between games, but we're not likely to be calling this function for different games very often. + // So, to speed things up a little, cache the lookup results in a map. + static EGame sCachedGame = eUnknownGame; + static std::map sCachedTypeMap; + Ext = Ext.ToUpper(); + + // When the game changes, our cache is invalidated, so clear it + if (sCachedGame != Game) + { + sCachedGame = Game; + sCachedTypeMap.clear(); + } + + // Is this type cached? + auto Iter = sCachedTypeMap.find(Ext); + if (Iter != sCachedTypeMap.end()) + return Iter->second; + + // Not cached - do a slow lookup + for (auto Iter = smTypeMap.begin(); Iter != smTypeMap.end(); Iter++) + { + CResTypeInfo *pType = Iter->second; + + if (pType->CookedExtension(Game) == Ext) + { + sCachedTypeMap[Ext] = pType; + return pType; + } + } + + // Haven't found it; caller gave us an invalid type + Log::Error("Failed to find resource type for cooked extension: " + Ext.ToString()); + DEBUG_BREAK; + sCachedTypeMap[Ext] = nullptr; + return nullptr; +} + +// ************ CREATION ************ +CResTypeInfo::CResTypeInfoFactory CResTypeInfo::smTypeInfoFactory; + +CResTypeInfo::CResTypeInfoFactory::CResTypeInfoFactory() +{ + InitTypes(); +} + +void CResTypeInfo::CResTypeInfoFactory::AddExtension(CResTypeInfo *pType, CFourCC Ext, EGame FirstGame, EGame LastGame) +{ + ASSERT(FirstGame >= ePrimeDemo && LastGame <= eReturns && FirstGame <= LastGame); + ASSERT(FirstGame != eUnknownGame && LastGame != eUnknownGame); + + for (int iGame = FirstGame; iGame <= LastGame; iGame++) + { +#if !PUBLIC_RELEASE + ASSERT(!pType->IsInGame((EGame) iGame)); +#endif + + CResTypeInfo::SGameExtension Info { (EGame) iGame, Ext }; + pType->mCookedExtensions.push_back(Info); + } + + std::sort(pType->mCookedExtensions.begin(), pType->mCookedExtensions.end(), [](const CResTypeInfo::SGameExtension& rkLeft, const CResTypeInfo::SGameExtension& rkRight) -> bool { + return rkLeft.Game < rkRight.Game; + }); +} + +void CResTypeInfo::CResTypeInfoFactory::InitTypes() +{ + { + CResTypeInfo *pType = new CResTypeInfo(eAnimation, "Animation"); + AddExtension(pType, "ANIM", ePrimeDemo, eReturns); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eAnimCollisionPrimData, "Animation Collision Primitive Data"); + AddExtension(pType, "CPRM", eReturns, eReturns); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eAnimEventData, "Animation Event Data"); + AddExtension(pType, "EVNT", ePrimeDemo, ePrime); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eAnimSet, "Animation Character Set"); + AddExtension(pType, "ANCS", ePrimeDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eArea, "Area"); + AddExtension(pType, "MREA", ePrimeDemo, eReturns); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eAudioGroup, "Audio Group"); + AddExtension(pType, "AGSC", ePrimeDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eAudioMacro, "Audio Macro"); + AddExtension(pType, "CAUD", eCorruptionProto, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eAudioSample, "Audio Sample"); + AddExtension(pType, "CSMP", eCorruptionProto, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eAudioLookupTable, "Audio Lookup Table"); + AddExtension(pType, "ATBL", ePrimeDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eBinaryData, "Binary Data"); + AddExtension(pType, "DUMB", ePrimeDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eBurstFireData, "Burst Fire Data"); + AddExtension(pType, "BFRC", eCorruptionProto, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eCharacter, "Character"); + AddExtension(pType, "CHAR", eCorruptionProto, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eDependencyGroup, "Dependency Group"); + AddExtension(pType, "DGRP", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eDynamicCollision, "Dynamic Collision"); + AddExtension(pType, "DCLN", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eFont, "Font"); + AddExtension(pType, "FONT", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eGuiFrame, "Gui Frame"); + AddExtension(pType, "FRME", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eGuiKeyFrame, "Gui Keyframe"); + AddExtension(pType, "KFAM", ePrimeDemo, ePrimeDemo); + } + { + CResTypeInfo *pType = new CResTypeInfo(eHintSystem, "Hint System Data"); + AddExtension(pType, "HINT", ePrime, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eMapArea, "Area Map"); + AddExtension(pType, "MAPA", ePrimeDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eMapWorld, "World Map"); + AddExtension(pType, "MAPW", ePrimeDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eMapUniverse, "Universe Map"); + AddExtension(pType, "MAPU", ePrimeDemo, eEchoes); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eMidi, "MIDI"); + AddExtension(pType, "CSNG", ePrimeDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eModel, "Model"); + AddExtension(pType, "CMDL", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticle, "Particle System"); + AddExtension(pType, "PART", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleCollisionResponse, "Collision Response Particle System"); + AddExtension(pType, "CRSC", ePrimeDemo, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleDecal, "Decal Particle System"); + AddExtension(pType, "DPSC", ePrimeDemo, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleElectric, "Electric Particle System"); + AddExtension(pType, "ELSC", ePrimeDemo, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleSorted, "Sorted Particle System"); + AddExtension(pType, "SRSC", eEchoesDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleSpawn, "Spawn Particle System"); + AddExtension(pType, "SPSC", eEchoesDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleSwoosh, "Swoosh Particle System"); + AddExtension(pType, "SWHC", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleTransform, "Transform Particle System"); + AddExtension(pType, "XFSC", eReturns, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eParticleWeapon, "Weapon Particle System"); + AddExtension(pType, "WPSC", ePrimeDemo, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(ePathfinding, "Pathfinding Mesh"); + AddExtension(pType, "PATH", ePrimeDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(ePortalArea, "Portal Area"); + AddExtension(pType, "PTLA", eEchoesDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eRuleSet, "Rule Set"); + AddExtension(pType, "RULE", eEchoesDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eSaveArea, "Area Save Info"); + AddExtension(pType, "SAVA", eCorruptionProto, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eSaveWorld, "World Save Info"); + AddExtension(pType, "SAVW", ePrime, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eScan, "Scan"); + AddExtension(pType, "SCAN", ePrimeDemo, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eSkeleton, "Skeleton"); + AddExtension(pType, "CINF", ePrimeDemo, eReturns); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eSkin, "Skin"); + AddExtension(pType, "CSKR", ePrimeDemo, eReturns); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eSourceAnimData, "Source Animation Data"); + AddExtension(pType, "SAND", eCorruptionProto, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eSpatialPrimitive, "Spatial Primitive"); + AddExtension(pType, "CSPP", eEchoesDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eStateMachine, "State Machine"); + AddExtension(pType, "AFSM", ePrimeDemo, eEchoes); + AddExtension(pType, "FSM2", eCorruptionProto, eCorruption); + AddExtension(pType, "FSMC", eReturns, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eStateMachine2, "State Machine 2"); + AddExtension(pType, "FSM2", eEchoesDemo, eEchoes); + } + { + CResTypeInfo *pType = new CResTypeInfo(eStaticGeometryMap, "Static Geometry Map"); + AddExtension(pType, "EGMC", eEchoesDemo, eCorruption); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eStreamedAudio, "Streamed Audio"); + AddExtension(pType, "STRM", eCorruptionProto, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eStringList, "String List"); + AddExtension(pType, "STLC", eEchoesDemo, eCorruptionProto); + pType->mHidden = true; + } + { + CResTypeInfo *pType = new CResTypeInfo(eStringTable, "String Table"); + AddExtension(pType, "STRG", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eTexture, "Texture"); + AddExtension(pType, "TXTR", ePrimeDemo, eReturns); + } + { + CResTypeInfo *pType = new CResTypeInfo(eTweak, "Tweak Data"); + AddExtension(pType, "CTWK", ePrimeDemo, ePrime); + } + { + CResTypeInfo *pType = new CResTypeInfo(eUnknown_CAAD, "CAAD"); + AddExtension(pType, "CAAD", eCorruption, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eUserEvaluatorData, "User Evaluator Data"); + AddExtension(pType, "USRC", eCorruptionProto, eCorruption); + } + { + CResTypeInfo *pType = new CResTypeInfo(eWorld, "World"); + AddExtension(pType, "MLVL", ePrimeDemo, eReturns); + pType->mRawExtension = "mwld"; + pType->mHidden = true; + pType->mCanBeSerialized = true; + } +} diff --git a/src/Core/Resource/CResTypeInfo.h b/src/Core/Resource/CResTypeInfo.h new file mode 100644 index 00000000..832bf3bf --- /dev/null +++ b/src/Core/Resource/CResTypeInfo.h @@ -0,0 +1,70 @@ +#ifndef CRESTYPEINFO +#define CRESTYPEINFO + +#include "EResType.h" +#include +#include +#include +#include +#include +#include + +class CResTypeInfo +{ + struct SGameExtension + { + EGame Game; + CFourCC CookedExt; + }; + + EResType mType; + TString mTypeName; + TString mRawExtension; + std::vector mCookedExtensions; + bool mHidden; + bool mCanBeSerialized; + + static std::unordered_map smTypeMap; + + // Private Methods + CResTypeInfo(EResType Type, const TString& rkTypeName); + ~CResTypeInfo(); + + // Public Methods +public: + bool IsInGame(EGame Game) const; + CFourCC CookedExtension(EGame Game) const; + + // Accessors + inline EResType Type() const { return mType; } + inline TString TypeName() const { return mTypeName; } + inline TString RawExtension() const { return mRawExtension; } + inline bool IsVisibleInBrowser() const { return !mHidden; } + inline bool CanBeSerialized() const { return mCanBeSerialized; } + + // Static + static void GetAllTypesInGame(EGame Game, std::list& rOut); + static CResTypeInfo* TypeForCookedExtension(EGame, CFourCC Ext); + + inline static CResTypeInfo* FindTypeInfo(EResType Type) + { + auto Iter = smTypeMap.find(Type); + return (Iter == smTypeMap.end() ? nullptr : Iter->second); + } + +private: + // Creation + friend class CResTypeInfoFactory; + + class CResTypeInfoFactory + { + public: + CResTypeInfoFactory(); + void AddExtension(CResTypeInfo *pType, CFourCC Ext, EGame FirstGame, EGame LastGame); + void InitTypes(); + }; + static CResTypeInfoFactory smTypeInfoFactory; +}; + +#endif // CRESTYPEINFO + diff --git a/src/Core/Resource/CResource.cpp b/src/Core/Resource/CResource.cpp deleted file mode 100644 index f6675593..00000000 --- a/src/Core/Resource/CResource.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "CResource.h" -#include "Core/GameProject/CResourceStore.h" -#include -#include - -std::map gExtensionTypeMap; -std::map gTypeExtensionMap; - -u32 GetGameTypeID(EGame Game, EResType ResType) -{ - return ((Game & 0xFFFF) << 16) | (ResType & 0xFFFF); -} - -// ************ STATIC ************ -EResType CResource::ResTypeForExtension(CFourCC Extension) -{ - auto Find = gExtensionTypeMap.find(Extension.ToUpper().ToLong()); - - if (Find == gExtensionTypeMap.end()) - { - Log::Error("Couldn't find resource type for requested cooked extension: " + Extension.ToString()); - return eInvalidResType; - } - - return Find->second; -} - -// ************ GLOBAL ************ -bool ResourceSupportsSerialization(EResType Type) -{ - switch (Type) - { - case eWorld: - return true; - default: - return false; - } -} - -TString GetResourceTypeName(EResType Type) -{ - switch (Type) - { - case eAnimation: return "Animation"; - case eAnimCollisionPrimData: return "Animation Collision Primitive Data"; - case eAnimEventData: return "Animation Event Data"; - case eAnimSet: return "Animation Character Set"; - case eArea: return "Area"; - case eAreaCollision: return "Area Collision"; - case eAreaGeometry: return "Area Geometry"; - case eAreaLights: return "Area Lights"; - case eAreaMaterials: return "Area Materials"; - case eAreaSurfaceBounds: return "Area Surface Bounds"; - case eAreaOctree: return "Area Octree"; - case eAreaVisibilityTree: return "Area Visibility Tree"; - case eAudioGroup: return "Audio Group Set"; - case eAudioMacro: return "Audio Macro"; - case eAudioSample: return "Audio Sample"; - case eAudioLookupTable: return "Audio Lookup Table"; - case eBinaryData: return "Binary Data"; - case eBurstFireData: return "Burst Fire Data"; - case eCharacter: return "Character"; - case eDependencyGroup: return "Dependency Group"; - case eDynamicCollision: return "Dynamic Collision"; - case eFont: return "Font"; - case eGuiFrame: return "Gui Frame"; - case eGuiKeyFrame: return "Gui Keyframe"; - case eHintSystem: return "Hint System"; - case eMapArea: return "Area Map"; - case eMapWorld: return "World Map"; - case eMapUniverse: return "Universe Map"; - case eMidi: return "MIDI"; - case eModel: return "Model"; - case eMusicTrack: return "Music"; - case ePackage: return "Package"; - case eParticle: return "Particle System"; - case eParticleCollisionResponse: return "Collision Response Particle System"; - case eParticleDecal: return "Decal Particle System"; - case eParticleElectric: return "Electric Particle System"; - case eParticleSorted: return "Sorted Particle System"; - case eParticleSpawn: return "Spawn Particle System"; - case eParticleSwoosh: return "Swoosh Particle System"; - case eParticleTransform: return "Transform Particle System"; - case eParticleWeapon: return "Weapon Particle System"; - case ePathfinding: return "Pathfinding Mesh"; - case ePortalArea: return "Portal Area"; - case eResource: return "Resource"; - case eRuleSet: return "Rule Set"; - case eSaveArea: return "Area Save Info"; - case eSaveWorld: return "World Save Info"; - case eScan: return "Scan"; - case eSkeleton: return "Skeleton"; - case eSkin: return "Skin"; - case eSourceAnimData: return "Source Animation Data"; - case eSpatialPrimitive: return "Spatial Primitive"; - case eStateMachine: return "State Machine"; - case eStateMachine2: return "State Machine"; - case eStaticGeometryMap: return "Static Geometry Map"; - case eStreamedAudio: return "Streamed Audio"; - case eStringList: return "String List"; - case eStringTable: return "String Table"; - case eTexture: return "Texture"; - case eTweak: return "Tweak Data"; - case eUnknown_CAAD: return "CAAD"; - case eUserEvaluatorData: return "User Evaluator Data"; - case eVideo: return "Video"; - case eWorld: return "World"; - default: return "INVALID"; - } -} - -TString GetResourceSerialName(EResType Type) -{ - TString Name = GetResourceTypeName(Type); - Name.RemoveWhitespace(); - return Name; -} - -TString GetResourceRawExtension(EResType Type, EGame /*Game*/) -{ - if (Type == eWorld) return "mwld"; - return ""; -} - -TString GetResourceCookedExtension(EResType Type, EGame Game) -{ - if (Game == eUnknownGame) - Game = ePrime; - - u32 GameTypeID = GetGameTypeID(Game, Type); - auto Find = gTypeExtensionMap.find(GameTypeID); - if (Find != gTypeExtensionMap.end()) return Find->second; - else return ""; -} - -// ************ TYPE REGISTRATIONS ************ -/* This macro registers a resource's cooked extension with an EResType enum, which allows for - * a resource type to be looked up via its extension, and vice versa. Because certain EResType - * enumerators are reused with different extensions between games, it's possible to set up a - * registration to be valid for only a specific range of games, and then tie a different - * extension to the same enumerator for a different game. This allows you to always look up the - * correct extension for a given resource type with a combination of an EResType and an EGame. - * - * You shouldn't need to add any new resource types, as the currently registered ones cover every - * resource type for every game from the MP1 demo up to DKCR. However, if you do, simply add an - * extra REGISTER_RESOURCE_TYPE line to the list below. - */ -#define REGISTER_RESOURCE_TYPE(CookedExtension, TypeEnum, FirstGame, LastGame) \ - class CResourceTypeRegistrant__##CookedExtension \ - { \ - public: \ - CResourceTypeRegistrant__##CookedExtension() \ - { \ - ASSERT(FirstGame != eUnknownGame); \ - \ - /* Register extension with resource type (should be consistent across all games) */ \ - u32 IntExt = CFourCC(#CookedExtension).ToLong(); \ - auto ExtFind = gExtensionTypeMap.find(IntExt); \ - if (ExtFind != gExtensionTypeMap.end()) \ - ASSERT(ExtFind->second == TypeEnum); \ - \ - gExtensionTypeMap[IntExt] = TypeEnum; \ - \ - /* Register resource type with extension for the specified game range */ \ - EGame Game = FirstGame; \ - \ - while (Game <= LastGame) \ - { \ - u32 GameTypeID = GetGameTypeID(Game, TypeEnum); \ - auto Find = gTypeExtensionMap.find(GameTypeID); \ - ASSERT(Find == gTypeExtensionMap.end()); \ - gTypeExtensionMap[GameTypeID] = #CookedExtension; \ - Game = (EGame) ((int) Game + 1); \ - } \ - } \ - }; \ - CResourceTypeRegistrant__##CookedExtension gResourceTypeRegistrant__##CookedExtension; - -REGISTER_RESOURCE_TYPE(AFSM, eStateMachine, ePrimeDemo, eEchoes) -REGISTER_RESOURCE_TYPE(AGSC, eAudioGroup, ePrimeDemo, eCorruptionProto) -REGISTER_RESOURCE_TYPE(ANCS, eAnimSet, ePrimeDemo, eEchoes) -REGISTER_RESOURCE_TYPE(ANIM, eAnimation, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(ATBL, eAudioLookupTable, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(BFRC, eBurstFireData, eCorruptionProto, eCorruption) -REGISTER_RESOURCE_TYPE(CAAD, eUnknown_CAAD, eCorruption, eCorruption) -REGISTER_RESOURCE_TYPE(CAUD, eAudioMacro, eCorruptionProto, eReturns) -REGISTER_RESOURCE_TYPE(CHAR, eAnimSet, eCorruptionProto, eReturns) -REGISTER_RESOURCE_TYPE(CINF, eSkeleton, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(CMDL, eModel, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(CRSC, eParticleCollisionResponse, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(CPRM, eAnimCollisionPrimData, eReturns, eReturns) -REGISTER_RESOURCE_TYPE(CSKR, eSkin, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(CSMP, eAudioSample, eCorruptionProto, eReturns) -REGISTER_RESOURCE_TYPE(CSNG, eMidi, ePrimeDemo, eEchoes) -REGISTER_RESOURCE_TYPE(CSPP, eSpatialPrimitive, eEchoesDemo, eEchoes) -REGISTER_RESOURCE_TYPE(CTWK, eTweak, ePrimeDemo, ePrime) -REGISTER_RESOURCE_TYPE(DCLN, eDynamicCollision, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(DGRP, eDependencyGroup, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(DPSC, eParticleDecal, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(DUMB, eBinaryData, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(EGMC, eStaticGeometryMap, eEchoesDemo, eCorruption) -REGISTER_RESOURCE_TYPE(ELSC, eParticleElectric, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(EVNT, eAnimEventData, ePrimeDemo, ePrime) -REGISTER_RESOURCE_TYPE(FONT, eFont, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(FRME, eGuiFrame, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(FSM2, eStateMachine2, eEchoesDemo, eCorruption) -REGISTER_RESOURCE_TYPE(FSMC, eStateMachine, eReturns, eReturns) -REGISTER_RESOURCE_TYPE(HINT, eHintSystem, ePrime, eCorruption) -REGISTER_RESOURCE_TYPE(KFAM, eGuiKeyFrame, ePrimeDemo, ePrimeDemo) -REGISTER_RESOURCE_TYPE(MAPA, eMapArea, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(MAPU, eMapUniverse, ePrimeDemo, eEchoes) -REGISTER_RESOURCE_TYPE(MAPW, eMapWorld, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(MLVL, eWorld, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(MREA, eArea, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(NTWK, eTweak, eEchoesDemo, eReturns) -REGISTER_RESOURCE_TYPE(PAK , ePackage, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(PART, eParticle, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(PATH, ePathfinding, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(PTLA, ePortalArea, eEchoesDemo, eCorruption) -REGISTER_RESOURCE_TYPE(RULE, eRuleSet, eEchoesDemo, eReturns) -REGISTER_RESOURCE_TYPE(SAND, eSourceAnimData, eCorruptionProto, eCorruption) -REGISTER_RESOURCE_TYPE(SAVA, eSaveArea, eCorruptionProto, eCorruption) -REGISTER_RESOURCE_TYPE(SAVW, eSaveWorld, ePrime, eReturns) -REGISTER_RESOURCE_TYPE(SCAN, eScan, ePrimeDemo, eCorruption) -REGISTER_RESOURCE_TYPE(SPSC, eParticleSpawn, eEchoesDemo, eReturns) -REGISTER_RESOURCE_TYPE(SRSC, eParticleSorted, eEchoesDemo, eEchoes) -REGISTER_RESOURCE_TYPE(STLC, eStringList, eEchoesDemo, eCorruptionProto) -REGISTER_RESOURCE_TYPE(STRG, eStringTable, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(STRM, eStreamedAudio, eCorruptionProto, eReturns) -REGISTER_RESOURCE_TYPE(SWHC, eParticleSwoosh, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(THP , eVideo, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(TXTR, eTexture, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(USRC, eUserEvaluatorData, eCorruptionProto, eCorruption) -REGISTER_RESOURCE_TYPE(XFSC, eParticleTransform, eReturns, eReturns) -REGISTER_RESOURCE_TYPE(WPSC, eParticleWeapon, ePrimeDemo, eCorruption) -// Split Area Data -REGISTER_RESOURCE_TYPE(AMAT, eAreaMaterials, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(AGEO, eAreaGeometry, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(AOCT, eAreaOctree, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(ABOX, eAreaSurfaceBounds, eEchoesDemo, eReturns) -REGISTER_RESOURCE_TYPE(ACLN, eAreaCollision, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(ALIT, eAreaLights, ePrimeDemo, eReturns) -REGISTER_RESOURCE_TYPE(AVIS, eAreaVisibilityTree, ePrimeDemo, eReturns) diff --git a/src/Core/Resource/CResource.h b/src/Core/Resource/CResource.h index 393241a3..1643e2d6 100644 --- a/src/Core/Resource/CResource.h +++ b/src/Core/Resource/CResource.h @@ -1,6 +1,7 @@ #ifndef CRESOURCE_H #define CRESOURCE_H +#include "CResTypeInfo.h" #include "EResType.h" #include "Core/GameProject/CDependencyTree.h" #include "Core/GameProject/CResourceEntry.h" @@ -45,6 +46,7 @@ public: virtual void Serialize(IArchive& /*rArc*/) {} inline CResourceEntry* Entry() const { return mpEntry; } + inline CResTypeInfo* TypeInfo() const { return mpEntry->TypeInfo(); } 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; } @@ -53,15 +55,6 @@ public: inline void SetGame(EGame Game) { if (mpEntry) mpEntry->SetGame(Game); } inline void Lock() { mRefCount++; } inline void Release() { mRefCount--; } - - static EResType ResTypeForExtension(CFourCC Extension); }; -// Global Functions -bool ResourceSupportsSerialization(EResType Type); -TString GetResourceTypeName(EResType Type); -TString GetResourceSerialName(EResType Type); -TString GetResourceRawExtension(EResType Type, EGame Game); -TString GetResourceCookedExtension(EResType Type, EGame Game); - #endif // CRESOURCE_H diff --git a/src/Editor/CProjectOverviewDialog.cpp b/src/Editor/CProjectOverviewDialog.cpp index 14a72d4b..8ae1b54f 100644 --- a/src/Editor/CProjectOverviewDialog.cpp +++ b/src/Editor/CProjectOverviewDialog.cpp @@ -59,7 +59,7 @@ void CProjectOverviewDialog::ExportGame() { // TEMP - hardcoded names for convenience. will remove later! #define USE_HARDCODED_GAME_ROOT 0 -#define USE_HARDCODED_EXPORT_DIR 1 +#define USE_HARDCODED_EXPORT_DIR 0 #if USE_HARDCODED_GAME_ROOT QString GameRoot = "E:/Unpacked/Metroid Prime"; diff --git a/src/Editor/ResourceBrowser/CResourceTableModel.h b/src/Editor/ResourceBrowser/CResourceTableModel.h index 5b0fd4b9..2ff8981a 100644 --- a/src/Editor/ResourceBrowser/CResourceTableModel.h +++ b/src/Editor/ResourceBrowser/CResourceTableModel.h @@ -43,7 +43,7 @@ public: if (Col == 1) { - return TO_QSTRING(GetResourceTypeName(pEntry->ResourceType())); + return TO_QSTRING(pEntry->TypeInfo()->TypeName()); } if (Col == 2) @@ -54,7 +54,7 @@ public: } else if (Role == Qt::ToolTipRole) - return TO_QSTRING(pEntry->Directory()->FullPath() + pEntry->Name()); + return TO_QSTRING(pEntry->CookedAssetPath(true)); else if (Role == Qt::TextAlignmentRole && rkIndex.column() == 2) return Qt::AlignRight;