Added CResTypeInfo class

This commit is contained in:
Aruki 2017-01-31 21:56:53 -07:00
parent 4f03c2431e
commit 8a66e393e7
16 changed files with 503 additions and 326 deletions

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -255,7 +255,7 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& 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<CAssetID>& 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);
}
}

View File

@ -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;

View File

@ -2,6 +2,7 @@
#define CRESOURCEENTRY_H
#include "CVirtualDirectory.h"
#include "Core/Resource/CResTypeInfo.h"
#include "Core/Resource/EResType.h"
#include <Common/CAssetID.h>
#include <Common/CFourCC.h>
@ -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); }

View File

@ -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.

View File

@ -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);

View File

@ -4,16 +4,16 @@
#include "Core/Resource/CResource.h"
#include <algorithm>
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 {

View File

@ -8,18 +8,20 @@
#include <vector>
class CResourceEntry;
class CResourceStore;
class CVirtualDirectory
{
CVirtualDirectory *mpParent;
CResourceStore *mpStore;
TWideString mName;
std::vector<CVirtualDirectory*> mSubdirectories;
std::vector<CResourceEntry*> 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;

View File

@ -0,0 +1,362 @@
#include "CResTypeInfo.h"
#include <Common/AssertMacro.h>
#include <algorithm>
std::unordered_map<EResType, CResTypeInfo*> 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<CResTypeInfo*>& 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<CFourCC, CResTypeInfo*> 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;
}
}

View File

@ -0,0 +1,70 @@
#ifndef CRESTYPEINFO
#define CRESTYPEINFO
#include "EResType.h"
#include <Common/CFourCC.h>
#include <Common/EGame.h>
#include <Common/Flags.h>
#include <Common/TString.h>
#include <unordered_map>
#include <vector>
class CResTypeInfo
{
struct SGameExtension
{
EGame Game;
CFourCC CookedExt;
};
EResType mType;
TString mTypeName;
TString mRawExtension;
std::vector<SGameExtension> mCookedExtensions;
bool mHidden;
bool mCanBeSerialized;
static std::unordered_map<EResType, CResTypeInfo*> 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<CResTypeInfo*>& 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

View File

@ -1,243 +0,0 @@
#include "CResource.h"
#include "Core/GameProject/CResourceStore.h"
#include <Common/AssertMacro.h>
#include <map>
std::map<u32, EResType> gExtensionTypeMap;
std::map<u32, TString> 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)

View File

@ -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

View File

@ -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";

View File

@ -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;