CResourceFactory: Make use of unique_ptr

Makes the API more memory safe
This commit is contained in:
Lioncash 2020-06-11 18:57:09 -04:00
parent ce315280c3
commit 907f1270bd
44 changed files with 314 additions and 276 deletions

View File

@ -89,10 +89,7 @@ CResourceEntry* CResourceEntry::BuildFromDirectory(CResourceStore *pStore, CResT
return pEntry; return pEntry;
} }
CResourceEntry::~CResourceEntry() CResourceEntry::~CResourceEntry() = default;
{
if (mpResource) delete mpResource;
}
bool CResourceEntry::LoadMetadata() bool CResourceEntry::LoadMetadata()
{ {
@ -386,7 +383,8 @@ bool CResourceEntry::Cook()
CResource* CResourceEntry::Load() CResource* CResourceEntry::Load()
{ {
// If the asset is already loaded then just return it immediately // If the asset is already loaded then just return it immediately
if (mpResource) return mpResource; if (mpResource)
return mpResource.get();
// Always try to load raw version as the raw version contains extra editor-only data. // Always try to load raw version as the raw version contains extra editor-only data.
// If there is no raw version (which will be the case for resource types that don't // If there is no raw version (which will be the case for resource types that don't
@ -406,8 +404,7 @@ CResource* CResourceEntry::Load()
if (!Reader.IsValid()) if (!Reader.IsValid())
{ {
errorf("Failed to load raw resource; falling back on cooked. Raw path: %s", *RawAssetPath()); errorf("Failed to load raw resource; falling back on cooked. Raw path: %s", *RawAssetPath());
delete mpResource; mpResource.reset();
mpResource = nullptr;
} }
else else
@ -419,7 +416,7 @@ CResource* CResourceEntry::Load()
} }
if (mpResource) if (mpResource)
return mpResource; return mpResource.get();
} }
ASSERT(!mpResource); ASSERT(!mpResource);
@ -446,8 +443,11 @@ CResource* CResourceEntry::Load()
CResource* CResourceEntry::LoadCooked(IInputStream& rInput) CResource* CResourceEntry::LoadCooked(IInputStream& rInput)
{ {
// Overload to allow for load from an arbitrary input stream. // Overload to allow for load from an arbitrary input stream.
if (mpResource) return mpResource; if (mpResource)
if (!rInput.IsValid()) return nullptr; return mpResource.get();
if (!rInput.IsValid())
return nullptr;
// Set gpResourceStore to ensure the correct resource store is accessed by loader functions // Set gpResourceStore to ensure the correct resource store is accessed by loader functions
CResourceStore *pOldStore = gpResourceStore; CResourceStore *pOldStore = gpResourceStore;
@ -458,15 +458,14 @@ CResource* CResourceEntry::LoadCooked(IInputStream& rInput)
mpStore->TrackLoadedResource(this); mpStore->TrackLoadedResource(this);
gpResourceStore = pOldStore; gpResourceStore = pOldStore;
return mpResource; return mpResource.get();
} }
bool CResourceEntry::Unload() bool CResourceEntry::Unload()
{ {
ASSERT(mpResource != nullptr); ASSERT(mpResource != nullptr);
ASSERT(!mpResource->IsReferenced()); ASSERT(!mpResource->IsReferenced());
delete mpResource; mpResource.reset();
mpResource = nullptr;
return true; return true;
} }

View File

@ -27,7 +27,7 @@ DECLARE_FLAGS(EResEntryFlag, FResEntryFlags)
class CResourceEntry class CResourceEntry
{ {
CResource *mpResource; std::unique_ptr<CResource> mpResource;
CResTypeInfo *mpTypeInfo; CResTypeInfo *mpTypeInfo;
CResourceStore *mpStore; CResourceStore *mpStore;
std::unique_ptr<CDependencyTree> mpDependencies; std::unique_ptr<CDependencyTree> mpDependencies;
@ -97,7 +97,7 @@ public:
bool IsLoaded() const { return mpResource != nullptr; } bool IsLoaded() const { return mpResource != nullptr; }
bool IsCategorized() const { return mpDirectory && !mpDirectory->FullPath().CaseInsensitiveCompare( mpStore->DefaultResourceDirPath() ); } bool IsCategorized() const { return mpDirectory && !mpDirectory->FullPath().CaseInsensitiveCompare( mpStore->DefaultResourceDirPath() ); }
bool IsNamed() const { return mName != mID.ToString(); } bool IsNamed() const { return mName != mID.ToString(); }
CResource* Resource() const { return mpResource; } CResource* Resource() const { return mpResource.get(); }
CResTypeInfo* TypeInfo() const { return mpTypeInfo; } CResTypeInfo* TypeInfo() const { return mpTypeInfo; }
CResourceStore* ResourceStore() const { return mpStore; } CResourceStore* ResourceStore() const { return mpStore; }
CDependencyTree* Dependencies() const { return mpDependencies.get(); } CDependencyTree* Dependencies() const { return mpDependencies.get(); }

View File

@ -130,13 +130,16 @@ void CAnimEventLoader::LoadSoundEvent(IInputStream& rEVNT)
} }
// ************ STATIC ************ // ************ STATIC ************
CAnimEventData* CAnimEventLoader::LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry) std::unique_ptr<CAnimEventData> CAnimEventLoader::LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry)
{ {
auto ptr = std::make_unique<CAnimEventData>(pEntry);
CAnimEventLoader Loader; CAnimEventLoader Loader;
Loader.mpEventData = new CAnimEventData(pEntry); Loader.mpEventData = ptr.get();
Loader.mGame = EGame::Prime; Loader.mGame = EGame::Prime;
Loader.LoadEvents(rEVNT); Loader.LoadEvents(rEVNT);
return Loader.mpEventData;
return ptr;
} }
CAnimEventData* CAnimEventLoader::LoadAnimSetEvents(IInputStream& rANCS) CAnimEventData* CAnimEventLoader::LoadAnimSetEvents(IInputStream& rANCS)

View File

@ -3,6 +3,7 @@
#include "Core/Resource/Animation/CAnimEventData.h" #include "Core/Resource/Animation/CAnimEventData.h"
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include <memory>
class CAnimEventLoader class CAnimEventLoader
{ {
@ -18,7 +19,7 @@ class CAnimEventLoader
void LoadSoundEvent(IInputStream& rEVNT); void LoadSoundEvent(IInputStream& rEVNT);
public: public:
static CAnimEventData* LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry); static std::unique_ptr<CAnimEventData> LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry);
static CAnimEventData* LoadAnimSetEvents(IInputStream& rANCS); static CAnimEventData* LoadAnimSetEvents(IInputStream& rANCS);
static CAnimEventData* LoadCorruptionCharacterEventSet(IInputStream& rCHAR); static CAnimEventData* LoadCorruptionCharacterEventSet(IInputStream& rCHAR);
}; };

View File

@ -5,9 +5,9 @@
CAnimSetLoader::CAnimSetLoader() = default; CAnimSetLoader::CAnimSetLoader() = default;
CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR) void CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
{ {
pSet->mCharacters.emplace_back( SSetCharacter() );; pSet->mCharacters.emplace_back(SSetCharacter());
SSetCharacter& rChar = pSet->mCharacters.back(); SSetCharacter& rChar = pSet->mCharacters.back();
// Character Header // Character Header
@ -91,10 +91,9 @@ CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
} }
ProcessPrimitives(); ProcessPrimitives();
return pSet;
} }
CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR) void CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
{ {
rCHAR.Skip(0x14); rCHAR.Skip(0x14);
uint8 Flag = rCHAR.ReadByte(); uint8 Flag = rCHAR.ReadByte();
@ -149,7 +148,7 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
// The only other thing we care about right now is the dependency list. If this file doesn't have a dependency list, exit out. // The only other thing we care about right now is the dependency list. If this file doesn't have a dependency list, exit out.
if ((Flag & 0x10) == 0) if ((Flag & 0x10) == 0)
return pSet; return;
// Anim ID Map // Anim ID Map
if (Flag & 0x20) if (Flag & 0x20)
@ -183,7 +182,7 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
break; break;
default: default:
errorf("%s [0x%X]: Invalid transition type: %d", *rCHAR.GetSourceString(), rCHAR.Tell() - 2, Type); errorf("%s [0x%X]: Invalid transition type: %d", *rCHAR.GetSourceString(), rCHAR.Tell() - 2, Type);
return pSet; return;
} }
} }
@ -234,7 +233,6 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
} }
ProcessPrimitives(); ProcessPrimitives();
return pSet;
} }
void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4) void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
@ -511,7 +509,7 @@ void CAnimSetLoader::ProcessPrimitives()
} }
// ************ STATIC ************ // ************ STATIC ************
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry) std::unique_ptr<CAnimSet> CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
{ {
if (!rANCS.IsValid()) return nullptr; if (!rANCS.IsValid()) return nullptr;
@ -522,8 +520,10 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CAnimSet>(pEntry);
CAnimSetLoader Loader; CAnimSetLoader Loader;
Loader.pSet = new CAnimSet(pEntry); Loader.pSet = ptr.get();
Loader.mGame = pEntry->Game(); Loader.mGame = pEntry->Game();
uint32 NodeCount = rANCS.ReadLong(); uint32 NodeCount = rANCS.ReadLong();
@ -615,40 +615,50 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
Loader.LoadAnimationSet(rANCS); Loader.LoadAnimationSet(rANCS);
Loader.ProcessPrimitives(); Loader.ProcessPrimitives();
return Loader.pSet; return ptr;
} }
CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry) std::unique_ptr<CAnimSet> CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry)
{ {
if (!rCHAR.IsValid()) return nullptr; if (!rCHAR.IsValid())
return nullptr;
CAnimSetLoader Loader; CAnimSetLoader Loader;
uint8 Check = rCHAR.ReadByte(); uint8 Check = rCHAR.ReadByte();
if (Check == 0x5 || Check == 0x3) if (Check == 0x5 || Check == 0x3)
{ {
auto ptr = std::make_unique<CAnimSet>(pEntry);
Loader.mGame = EGame::Corruption; Loader.mGame = EGame::Corruption;
Loader.pSet = new CAnimSet(pEntry); Loader.pSet = ptr.get();
return Loader.LoadCorruptionCHAR(rCHAR); Loader.LoadCorruptionCHAR(rCHAR);
return ptr;
} }
if (Check == 0x59) if (Check == 0x59)
{ {
auto ptr = std::make_unique<CAnimSet>(pEntry);
Loader.mGame = EGame::DKCReturns; Loader.mGame = EGame::DKCReturns;
Loader.pSet = new CAnimSet(pEntry); Loader.pSet = ptr.get();
return Loader.LoadReturnsCHAR(rCHAR); Loader.LoadReturnsCHAR(rCHAR);
return ptr;
} }
errorf("%s: CHAR has invalid first byte: 0x%02X", *rCHAR.GetSourceString(), Check); errorf("%s: CHAR has invalid first byte: 0x%02X", *rCHAR.GetSourceString(), Check);
return nullptr; return nullptr;
} }
CSourceAnimData* CAnimSetLoader::LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry) std::unique_ptr<CSourceAnimData> CAnimSetLoader::LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry)
{ {
if (!rSAND.IsValid()) return nullptr; if (!rSAND.IsValid())
return nullptr;
// We only care about the transitions right now // We only care about the transitions right now
CSourceAnimData *pData = new CSourceAnimData(pEntry); auto pData = std::make_unique<CSourceAnimData>(pEntry);
uint16 Unknown = rSAND.ReadShort(); // probably version uint16 Unknown = rSAND.ReadShort(); // probably version
ASSERT(Unknown == 0); ASSERT(Unknown == 0);

View File

@ -4,6 +4,7 @@
#include "Core/Resource/Animation/CAnimSet.h" #include "Core/Resource/Animation/CAnimSet.h"
#include "Core/Resource/Animation/CSourceAnimData.h" #include "Core/Resource/Animation/CSourceAnimData.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CAnimSetLoader class CAnimSetLoader
{ {
@ -11,8 +12,8 @@ class CAnimSetLoader
EGame mGame{}; EGame mGame{};
CAnimSetLoader(); CAnimSetLoader();
CAnimSet* LoadCorruptionCHAR(IInputStream& rCHAR); void LoadCorruptionCHAR(IInputStream& rCHAR);
CAnimSet* LoadReturnsCHAR(IInputStream& rCHAR); void LoadReturnsCHAR(IInputStream& rCHAR);
void LoadPASDatabase(IInputStream& rPAS4); void LoadPASDatabase(IInputStream& rPAS4);
void LoadParticleResourceData(IInputStream& rFile, SSetCharacter *pChar, uint16 Version); void LoadParticleResourceData(IInputStream& rFile, SSetCharacter *pChar, uint16 Version);
@ -20,9 +21,9 @@ class CAnimSetLoader
void ProcessPrimitives(); void ProcessPrimitives();
public: public:
static CAnimSet* LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry); static std::unique_ptr<CAnimSet> LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry);
static CAnimSet* LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry); static std::unique_ptr<CAnimSet> LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry);
static CSourceAnimData* LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry); static std::unique_ptr<CSourceAnimData> LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry);
}; };
#endif // CCHARACTERLOADER_H #endif // CCHARACTERLOADER_H

View File

@ -463,11 +463,11 @@ CQuaternion CAnimationLoader::DequantizeRotation(bool Sign, int16 X, int16 Y, in
} }
// ************ STATIC ************ // ************ STATIC ************
CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry) std::unique_ptr<CAnimation> CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry)
{ {
// MP3/DKCR unsupported // MP3/DKCR unsupported
if (pEntry->Game() > EGame::Echoes) if (pEntry->Game() > EGame::Echoes)
return new CAnimation(pEntry); return std::make_unique<CAnimation>(pEntry);
uint32 CompressionType = rANIM.ReadLong(); uint32 CompressionType = rANIM.ReadLong();
@ -477,8 +477,10 @@ CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEnt
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CAnimation>(pEntry);
CAnimationLoader Loader; CAnimationLoader Loader;
Loader.mpAnim = new CAnimation(pEntry); Loader.mpAnim = ptr.get();
Loader.mGame = pEntry->Game(); Loader.mGame = pEntry->Game();
Loader.mpInput = &rANIM; Loader.mpInput = &rANIM;
@ -487,5 +489,5 @@ CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEnt
else else
Loader.ReadCompressedANIM(); Loader.ReadCompressedANIM();
return Loader.mpAnim; return ptr;
} }

View File

@ -4,6 +4,7 @@
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include "Core/Resource/Animation/CAnimation.h" #include "Core/Resource/Animation/CAnimation.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CAnimationLoader class CAnimationLoader
{ {
@ -41,7 +42,7 @@ class CAnimationLoader
CQuaternion DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z); CQuaternion DequantizeRotation(bool Sign, int16 X, int16 Y, int16 Z);
public: public:
static CAnimation* LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry); static std::unique_ptr<CAnimation> LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry);
}; };
#endif // CANIMATIONLOADER_H #endif // CANIMATIONLOADER_H

View File

@ -727,7 +727,7 @@ void CAreaLoader::SetUpObjects(CScriptLayer *pGenLayer)
} }
// ************ STATIC ************ // ************ STATIC ************
CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry) std::unique_ptr<CGameArea> CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
{ {
CAreaLoader Loader; CAreaLoader Loader;
@ -741,8 +741,10 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CGameArea>(pEntry);
// Header // Header
Loader.mpArea = new CGameArea(pEntry); Loader.mpArea = ptr.get();
uint32 Version = MREA.ReadLong(); uint32 Version = MREA.ReadLong();
Loader.mVersion = GetFormatVersion(Version); Loader.mVersion = GetFormatVersion(Version);
Loader.mpMREA = &MREA; Loader.mpMREA = &MREA;
@ -812,7 +814,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
// Cleanup // Cleanup
delete Loader.mpSectionMgr; delete Loader.mpSectionMgr;
return Loader.mpArea; return ptr;
} }
EGame CAreaLoader::GetFormatVersion(uint32 Version) EGame CAreaLoader::GetFormatVersion(uint32 Version)

View File

@ -7,6 +7,7 @@
#include "Core/Resource/Script/CLink.h" #include "Core/Resource/Script/CLink.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <Common/FileIO.h> #include <Common/FileIO.h>
#include <memory>
class CAreaLoader class CAreaLoader
{ {
@ -81,7 +82,7 @@ class CAreaLoader
void SetUpObjects(CScriptLayer *pGenLayer); void SetUpObjects(CScriptLayer *pGenLayer);
public: public:
static CGameArea* LoadMREA(IInputStream& rMREA, CResourceEntry *pEntry); static std::unique_ptr<CGameArea> LoadMREA(IInputStream& rMREA, CResourceEntry *pEntry);
static EGame GetFormatVersion(uint32 Version); static EGame GetFormatVersion(uint32 Version);
}; };

View File

@ -1,12 +1,12 @@
#include "CAudioGroupLoader.h" #include "CAudioGroupLoader.h"
CAudioGroup* CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pEntry) std::unique_ptr<CAudioGroup> CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pEntry)
{ {
// For now we only load sound define IDs and the group ID! // For now we only load sound define IDs and the group ID!
// Version check // Version check
uint32 Check = rAGSC.PeekLong(); uint32 Check = rAGSC.PeekLong();
EGame Game = (Check == 0x1 ? EGame::Echoes : EGame::Prime); EGame Game = (Check == 0x1 ? EGame::Echoes : EGame::Prime);
CAudioGroup *pOut = new CAudioGroup(pEntry); auto pOut = std::make_unique<CAudioGroup>(pEntry);
// Read header, navigate to Proj chunk // Read header, navigate to Proj chunk
if (Game == EGame::Prime) if (Game == EGame::Prime)
@ -60,9 +60,9 @@ CAudioGroup* CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pE
return pOut; return pOut;
} }
CAudioLookupTable* CAudioGroupLoader::LoadATBL(IInputStream& rATBL, CResourceEntry *pEntry) std::unique_ptr<CAudioLookupTable> CAudioGroupLoader::LoadATBL(IInputStream& rATBL, CResourceEntry *pEntry)
{ {
CAudioLookupTable *pOut = new CAudioLookupTable(pEntry); auto pOut = std::make_unique<CAudioLookupTable>(pEntry);
uint32 NumMacroIDs = rATBL.ReadLong(); uint32 NumMacroIDs = rATBL.ReadLong();
for (uint32 iMacro = 0; iMacro < NumMacroIDs; iMacro++) for (uint32 iMacro = 0; iMacro < NumMacroIDs; iMacro++)
@ -71,9 +71,9 @@ CAudioLookupTable* CAudioGroupLoader::LoadATBL(IInputStream& rATBL, CResourceEnt
return pOut; return pOut;
} }
CStringList* CAudioGroupLoader::LoadSTLC(IInputStream& rSTLC, CResourceEntry *pEntry) std::unique_ptr<CStringList> CAudioGroupLoader::LoadSTLC(IInputStream& rSTLC, CResourceEntry *pEntry)
{ {
CStringList *pOut = new CStringList(pEntry); auto pOut = std::make_unique<CStringList>(pEntry);
uint32 NumStrings = rSTLC.ReadLong(); uint32 NumStrings = rSTLC.ReadLong();
pOut->mStringList.reserve(NumStrings); pOut->mStringList.reserve(NumStrings);

View File

@ -4,15 +4,16 @@
#include "Core/Resource/CAudioGroup.h" #include "Core/Resource/CAudioGroup.h"
#include "Core/Resource/CAudioLookupTable.h" #include "Core/Resource/CAudioLookupTable.h"
#include "Core/Resource/CStringList.h" #include "Core/Resource/CStringList.h"
#include <memory>
class CAudioGroupLoader class CAudioGroupLoader
{ {
CAudioGroupLoader() {} CAudioGroupLoader() {}
public: public:
static CAudioGroup* LoadAGSC(IInputStream& rAGSC, CResourceEntry *pEntry); static std::unique_ptr<CAudioGroup> LoadAGSC(IInputStream& rAGSC, CResourceEntry *pEntry);
static CAudioLookupTable* LoadATBL(IInputStream& rATBL, CResourceEntry *pEntry); static std::unique_ptr<CAudioLookupTable> LoadATBL(IInputStream& rATBL, CResourceEntry *pEntry);
static CStringList* LoadSTLC(IInputStream& rSTLC, CResourceEntry *pEntry); static std::unique_ptr<CStringList> LoadSTLC(IInputStream& rSTLC, CResourceEntry *pEntry);
}; };
#endif // CAUDIOGROUPLOADER_H #endif // CAUDIOGROUPLOADER_H

View File

@ -220,12 +220,14 @@ CCollisionMeshGroup* CCollisionLoader::LoadAreaCollision(IInputStream& rMREA)
return pOut; return pOut;
} }
CCollisionMeshGroup* CCollisionLoader::LoadDCLN(IInputStream& rDCLN, CResourceEntry *pEntry) std::unique_ptr<CCollisionMeshGroup> CCollisionLoader::LoadDCLN(IInputStream& rDCLN, CResourceEntry *pEntry)
{ {
if (!rDCLN.IsValid()) return nullptr; if (!rDCLN.IsValid()) return nullptr;
auto ptr = std::make_unique<CCollisionMeshGroup>(pEntry);
CCollisionLoader Loader; CCollisionLoader Loader;
Loader.mpGroup = new CCollisionMeshGroup(pEntry); Loader.mpGroup = ptr.get();
uint32 NumMeshes = rDCLN.ReadLong(); uint32 NumMeshes = rDCLN.ReadLong();
@ -269,7 +271,8 @@ CCollisionMeshGroup* CCollisionLoader::LoadDCLN(IInputStream& rDCLN, CResourceEn
CCollidableOBBTree* pOBBTree = static_cast<CCollidableOBBTree*>(Loader.mpMesh); CCollidableOBBTree* pOBBTree = static_cast<CCollidableOBBTree*>(Loader.mpMesh);
pOBBTree->mpOBBTree = std::unique_ptr<SOBBTreeNode>( Loader.ParseOBBNode(rDCLN) ); pOBBTree->mpOBBTree = std::unique_ptr<SOBBTreeNode>( Loader.ParseOBBNode(rDCLN) );
} }
return Loader.mpGroup;
return ptr;
} }
EGame CCollisionLoader::GetFormatVersion(uint32 Version) EGame CCollisionLoader::GetFormatVersion(uint32 Version)

View File

@ -26,7 +26,7 @@ class CCollisionLoader
public: public:
static CCollisionMeshGroup* LoadAreaCollision(IInputStream& rMREA); static CCollisionMeshGroup* LoadAreaCollision(IInputStream& rMREA);
static CCollisionMeshGroup* LoadDCLN(IInputStream& rDCLN, CResourceEntry *pEntry); static std::unique_ptr<CCollisionMeshGroup> LoadDCLN(IInputStream& rDCLN, CResourceEntry *pEntry);
static EGame GetFormatVersion(uint32 Version); static EGame GetFormatVersion(uint32 Version);
}; };

View File

@ -32,14 +32,15 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, uint32 DepCount)
return Game; return Game;
} }
CDependencyGroup* CDependencyGroupLoader::LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CDependencyGroupLoader::LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry)
{ {
if (!rDGRP.IsValid()) return nullptr; if (!rDGRP.IsValid())
return nullptr;
uint32 NumDependencies = rDGRP.ReadLong(); uint32 NumDependencies = rDGRP.ReadLong();
EGame Game = VersionTest(rDGRP, NumDependencies); EGame Game = VersionTest(rDGRP, NumDependencies);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
for (uint32 iDep = 0; iDep < NumDependencies; iDep++) for (uint32 iDep = 0; iDep < NumDependencies; iDep++)
{ {

View File

@ -3,6 +3,7 @@
#include "Core/Resource/CDependencyGroup.h" #include "Core/Resource/CDependencyGroup.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CDependencyGroupLoader class CDependencyGroupLoader
{ {
@ -10,7 +11,7 @@ class CDependencyGroupLoader
static EGame VersionTest(IInputStream& rDGRP, uint32 DepCount); static EGame VersionTest(IInputStream& rDGRP, uint32 DepCount);
public: public:
static CDependencyGroup* LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry);
}; };
#endif // CDEPENDENCYGROUPLOADER_H #endif // CDEPENDENCYGROUPLOADER_H

View File

@ -6,7 +6,7 @@ CFontLoader::CFontLoader()
{ {
} }
CFont* CFontLoader::LoadFont(IInputStream& rFONT) void CFontLoader::LoadFont(IInputStream& rFONT)
{ {
// If I seek past a value without reading it, then it's because I don't know what it is // If I seek past a value without reading it, then it's because I don't know what it is
mpFont->mUnknown = rFONT.ReadLong(); mpFont->mUnknown = rFONT.ReadLong();
@ -72,13 +72,12 @@ CFont* CFontLoader::LoadFont(IInputStream& rFONT)
Pair.Adjust = rFONT.ReadLong(); Pair.Adjust = rFONT.ReadLong();
mpFont->mKerningTable.push_back(Pair); mpFont->mKerningTable.push_back(Pair);
} }
return mpFont;
} }
CFont* CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry) std::unique_ptr<CFont> CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry)
{ {
if (!rFONT.IsValid()) return nullptr; if (!rFONT.IsValid())
return nullptr;
CFourCC Magic(rFONT); CFourCC Magic(rFONT);
if (Magic != FOURCC('FONT')) if (Magic != FOURCC('FONT'))
@ -95,10 +94,14 @@ CFont* CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry)
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CFont>(pEntry);
CFontLoader Loader; CFontLoader Loader;
Loader.mpFont = new CFont(pEntry); Loader.mpFont = ptr.get();
Loader.mVersion = Version; Loader.mVersion = Version;
return Loader.LoadFont(rFONT); Loader.LoadFont(rFONT);
return ptr;
} }
EGame CFontLoader::GetFormatVersion(uint32 Version) EGame CFontLoader::GetFormatVersion(uint32 Version)

View File

@ -4,6 +4,7 @@
#include "Core/GameProject/CResourceStore.h" #include "Core/GameProject/CResourceStore.h"
#include "Core/Resource/CFont.h" #include "Core/Resource/CFont.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CFontLoader class CFontLoader
{ {
@ -11,10 +12,10 @@ class CFontLoader
EGame mVersion; EGame mVersion;
CFontLoader(); CFontLoader();
CFont* LoadFont(IInputStream& rFONT); void LoadFont(IInputStream& rFONT);
public: public:
static CFont* LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry); static std::unique_ptr<CFont> LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry);
static EGame GetFormatVersion(uint32 Version); static EGame GetFormatVersion(uint32 Version);
}; };

View File

@ -384,7 +384,7 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
} }
// ************ STATIC ************ // ************ STATIC ************
CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry) std::unique_ptr<CModel> CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry)
{ {
CModelLoader Loader; CModelLoader Loader;
@ -438,7 +438,6 @@ CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry)
rCMDL.Seek(0x14, SEEK_CUR); // no clue what any of this is! rCMDL.Seek(0x14, SEEK_CUR); // no clue what any of this is!
} }
} }
else else
{ {
errorf("%s: Invalid CMDL magic: 0x%08X", *rCMDL.GetSourceString(), Magic); errorf("%s: Invalid CMDL magic: 0x%08X", *rCMDL.GetSourceString(), Magic);
@ -454,8 +453,8 @@ CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry)
return nullptr; return nullptr;
} }
CModel *pModel = new CModel(pEntry); auto pModel = std::make_unique<CModel>(pEntry);
Loader.mpModel = pModel; Loader.mpModel = pModel.get();
Loader.mpSectionMgr = new CSectionMgrIn(BlockCount, &rCMDL); Loader.mpSectionMgr = new CSectionMgrIn(BlockCount, &rCMDL);
rCMDL.SeekToBoundary(32); rCMDL.SeekToBoundary(32);
Loader.mpSectionMgr->Init(); Loader.mpSectionMgr->Init();

View File

@ -11,6 +11,8 @@
#include <assimp/scene.h> #include <assimp/scene.h>
#include <memory>
enum class EModelLoaderFlag enum class EModelLoaderFlag
{ {
None = 0x0, None = 0x0,
@ -24,8 +26,6 @@ DECLARE_FLAGS_ENUMCLASS(EModelLoaderFlag, FModelLoaderFlags)
class CModelLoader class CModelLoader
{ {
public:
private: private:
TResPtr<CModel> mpModel; TResPtr<CModel> mpModel;
std::vector<CMaterialSet*> mMaterials; std::vector<CMaterialSet*> mMaterials;
@ -58,7 +58,7 @@ private:
SSurface* LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet); SSurface* LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet);
public: public:
static CModel* LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry); static std::unique_ptr<CModel> LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry);
static CModel* LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version); static CModel* LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, EGame Version);
static CModel* LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version); static CModel* LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockMgr, CMaterialSet& rMatSet, uint32 HeaderSecNum, uint32 GPUSecNum, EGame Version);
static void BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<CModel*>& rOut, bool DeleteInputModels); static void BuildWorldMeshes(const std::vector<CModel*>& rkIn, std::vector<CModel*>& rOut, bool DeleteInputModels);

View File

@ -1,8 +1,8 @@
#include "CPoiToWorldLoader.h" #include "CPoiToWorldLoader.h"
CPoiToWorld* CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC, CResourceEntry *pEntry) std::unique_ptr<CPoiToWorld> CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC, CResourceEntry *pEntry)
{ {
CPoiToWorld *pOut = new CPoiToWorld(pEntry); auto pOut = std::make_unique<CPoiToWorld>(pEntry);
uint32 NumMappings = rEGMC.ReadLong(); uint32 NumMappings = rEGMC.ReadLong();
for (uint32 iMap = 0; iMap < NumMappings; iMap++) for (uint32 iMap = 0; iMap < NumMappings; iMap++)

View File

@ -3,15 +3,14 @@
#include "Core/Resource/CPoiToWorld.h" #include "Core/Resource/CPoiToWorld.h"
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include <memory>
class CPoiToWorldLoader class CPoiToWorldLoader
{ {
TResPtr<CPoiToWorld> mpPoiToWorld;
CPoiToWorldLoader() = default; CPoiToWorldLoader() = default;
public: public:
static CPoiToWorld* LoadEGMC(IInputStream& rEGMC, CResourceEntry *pEntry); static std::unique_ptr<CPoiToWorld> LoadEGMC(IInputStream& rEGMC, CResourceEntry *pEntry);
}; };
#endif // CPOITOWORLDLOADER_H #endif // CPOITOWORLDLOADER_H

View File

@ -32,85 +32,85 @@ class CResourceFactory
CResourceFactory() {} CResourceFactory() {}
public: public:
static CResource* CreateResource(CResourceEntry *pEntry) static std::unique_ptr<CResource> CreateResource(CResourceEntry *pEntry)
{ {
switch (pEntry->ResourceType()) switch (pEntry->ResourceType())
{ {
case EResourceType::Animation: return new CAnimation(pEntry); case EResourceType::Animation: return std::make_unique<CAnimation>(pEntry);
case EResourceType::AnimEventData: return new CAnimEventData(pEntry); case EResourceType::AnimEventData: return std::make_unique<CAnimEventData>(pEntry);
case EResourceType::AnimSet: return new CAnimSet(pEntry); case EResourceType::AnimSet: return std::make_unique<CAnimSet>(pEntry);
case EResourceType::Area: return new CGameArea(pEntry); case EResourceType::Area: return std::make_unique<CGameArea>(pEntry);
case EResourceType::AudioMacro: return new CAudioMacro(pEntry); case EResourceType::AudioMacro: return std::make_unique<CAudioMacro>(pEntry);
case EResourceType::AudioGroup: return new CAudioGroup(pEntry); case EResourceType::AudioGroup: return std::make_unique<CAudioGroup>(pEntry);
case EResourceType::AudioLookupTable: return new CAudioLookupTable(pEntry); case EResourceType::AudioLookupTable: return std::make_unique<CAudioLookupTable>(pEntry);
case EResourceType::Character: return new CAnimSet(pEntry); case EResourceType::Character: return std::make_unique<CAnimSet>(pEntry);
case EResourceType::DynamicCollision: return new CCollisionMeshGroup(pEntry); case EResourceType::DynamicCollision: return std::make_unique<CCollisionMeshGroup>(pEntry);
case EResourceType::DependencyGroup: return new CDependencyGroup(pEntry); case EResourceType::DependencyGroup: return std::make_unique<CDependencyGroup>(pEntry);
case EResourceType::Font: return new CFont(pEntry); case EResourceType::Font: return std::make_unique<CFont>(pEntry);
case EResourceType::MapArea: return new CMapArea(pEntry); case EResourceType::MapArea: return std::make_unique<CMapArea>(pEntry);
case EResourceType::Model: return new CModel(pEntry); case EResourceType::Model: return std::make_unique<CModel>(pEntry);
case EResourceType::Scan: return new CScan(pEntry); case EResourceType::Scan: return std::make_unique<CScan>(pEntry);
case EResourceType::Skeleton: return new CSkeleton(pEntry); case EResourceType::Skeleton: return std::make_unique<CSkeleton>(pEntry);
case EResourceType::Skin: return new CSkin(pEntry); case EResourceType::Skin: return std::make_unique<CSkin>(pEntry);
case EResourceType::SourceAnimData: return new CSourceAnimData(pEntry); case EResourceType::SourceAnimData: return std::make_unique<CSourceAnimData>(pEntry);
case EResourceType::StaticGeometryMap: return new CPoiToWorld(pEntry); case EResourceType::StaticGeometryMap: return std::make_unique<CPoiToWorld>(pEntry);
case EResourceType::StringList: return new CStringList(pEntry); case EResourceType::StringList: return std::make_unique<CStringList>(pEntry);
case EResourceType::StringTable: return new CStringTable(pEntry); case EResourceType::StringTable: return std::make_unique<CStringTable>(pEntry);
case EResourceType::Texture: return new CTexture(pEntry); case EResourceType::Texture: return std::make_unique<CTexture>(pEntry);
case EResourceType::World: return new CWorld(pEntry); case EResourceType::World: return std::make_unique<CWorld>(pEntry);
default: return nullptr; // should it return a CResource instead? default: return nullptr; // should it return a CResource instead?
} }
} }
static CResource* LoadCookedResource(CResourceEntry *pEntry, IInputStream& rInput) static std::unique_ptr<CResource> LoadCookedResource(CResourceEntry *pEntry, IInputStream& rInput)
{ {
// Warning: It is the caller's responsibility to check if the required resource is already in memory before calling this function. // Warning: It is the caller's responsibility to check if the required resource is already in memory before calling this function.
if (!rInput.IsValid()) return nullptr; if (!rInput.IsValid())
CResource *pRes = nullptr; return nullptr;
switch (pEntry->ResourceType()) switch (pEntry->ResourceType())
{ {
case EResourceType::Animation: pRes = CAnimationLoader::LoadANIM(rInput, pEntry); break; case EResourceType::Animation: return CAnimationLoader::LoadANIM(rInput, pEntry);
case EResourceType::AnimEventData: pRes = CAnimEventLoader::LoadEVNT(rInput, pEntry); break; case EResourceType::AnimEventData: return CAnimEventLoader::LoadEVNT(rInput, pEntry);
case EResourceType::AnimSet: pRes = CAnimSetLoader::LoadANCS(rInput, pEntry); break; case EResourceType::AnimSet: return CAnimSetLoader::LoadANCS(rInput, pEntry);
case EResourceType::Area: pRes = CAreaLoader::LoadMREA(rInput, pEntry); break; case EResourceType::Area: return CAreaLoader::LoadMREA(rInput, pEntry);
case EResourceType::AudioMacro: pRes = CUnsupportedFormatLoader::LoadCAUD(rInput, pEntry); break; case EResourceType::AudioMacro: return CUnsupportedFormatLoader::LoadCAUD(rInput, pEntry);
case EResourceType::AudioGroup: pRes = CAudioGroupLoader::LoadAGSC(rInput, pEntry); break; case EResourceType::AudioGroup: return CAudioGroupLoader::LoadAGSC(rInput, pEntry);
case EResourceType::AudioLookupTable: pRes = CAudioGroupLoader::LoadATBL(rInput, pEntry); break; case EResourceType::AudioLookupTable: return CAudioGroupLoader::LoadATBL(rInput, pEntry);
case EResourceType::BinaryData: pRes = CUnsupportedFormatLoader::LoadDUMB(rInput, pEntry); break; case EResourceType::BinaryData: return CUnsupportedFormatLoader::LoadDUMB(rInput, pEntry);
case EResourceType::Character: pRes = CAnimSetLoader::LoadCHAR(rInput, pEntry); break; case EResourceType::Character: return CAnimSetLoader::LoadCHAR(rInput, pEntry);
case EResourceType::DependencyGroup: pRes = CDependencyGroupLoader::LoadDGRP(rInput, pEntry); break; case EResourceType::DependencyGroup: return CDependencyGroupLoader::LoadDGRP(rInput, pEntry);
case EResourceType::DynamicCollision: pRes = CCollisionLoader::LoadDCLN(rInput, pEntry); break; case EResourceType::DynamicCollision: return CCollisionLoader::LoadDCLN(rInput, pEntry);
case EResourceType::Font: pRes = CFontLoader::LoadFONT(rInput, pEntry); break; case EResourceType::Font: return CFontLoader::LoadFONT(rInput, pEntry);
case EResourceType::GuiFrame: pRes = CUnsupportedFormatLoader::LoadFRME(rInput, pEntry); break; case EResourceType::GuiFrame: return CUnsupportedFormatLoader::LoadFRME(rInput, pEntry);
case EResourceType::HintSystem: pRes = CUnsupportedFormatLoader::LoadHINT(rInput, pEntry); break; case EResourceType::HintSystem: return CUnsupportedFormatLoader::LoadHINT(rInput, pEntry);
case EResourceType::MapArea: pRes = CUnsupportedFormatLoader::LoadMAPA(rInput, pEntry); break; case EResourceType::MapArea: return CUnsupportedFormatLoader::LoadMAPA(rInput, pEntry);
case EResourceType::MapWorld: pRes = CUnsupportedFormatLoader::LoadMAPW(rInput, pEntry); break; case EResourceType::MapWorld: return CUnsupportedFormatLoader::LoadMAPW(rInput, pEntry);
case EResourceType::MapUniverse: pRes = CUnsupportedFormatLoader::LoadMAPU(rInput, pEntry); break; case EResourceType::MapUniverse: return CUnsupportedFormatLoader::LoadMAPU(rInput, pEntry);
case EResourceType::Midi: pRes = CUnsupportedFormatLoader::LoadCSNG(rInput, pEntry); break; case EResourceType::Midi: return CUnsupportedFormatLoader::LoadCSNG(rInput, pEntry);
case EResourceType::Model: pRes = CModelLoader::LoadCMDL(rInput, pEntry); break; case EResourceType::Model: return CModelLoader::LoadCMDL(rInput, pEntry);
case EResourceType::RuleSet: pRes = CUnsupportedFormatLoader::LoadRULE(rInput, pEntry); break; case EResourceType::RuleSet: return CUnsupportedFormatLoader::LoadRULE(rInput, pEntry);
case EResourceType::Scan: pRes = CScanLoader::LoadSCAN(rInput, pEntry); break; case EResourceType::Scan: return CScanLoader::LoadSCAN(rInput, pEntry);
case EResourceType::Skeleton: pRes = CSkeletonLoader::LoadCINF(rInput, pEntry); break; case EResourceType::Skeleton: return CSkeletonLoader::LoadCINF(rInput, pEntry);
case EResourceType::Skin: pRes = CSkinLoader::LoadCSKR(rInput, pEntry); break; case EResourceType::Skin: return CSkinLoader::LoadCSKR(rInput, pEntry);
case EResourceType::SourceAnimData: pRes = CAnimSetLoader::LoadSAND(rInput, pEntry); break; case EResourceType::SourceAnimData: return CAnimSetLoader::LoadSAND(rInput, pEntry);
case EResourceType::StateMachine2: pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry); break; case EResourceType::StateMachine2: return CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
case EResourceType::StaticGeometryMap: pRes = CPoiToWorldLoader::LoadEGMC(rInput, pEntry); break; case EResourceType::StaticGeometryMap: return CPoiToWorldLoader::LoadEGMC(rInput, pEntry);
case EResourceType::StringList: pRes = CAudioGroupLoader::LoadSTLC(rInput, pEntry); break; case EResourceType::StringList: return CAudioGroupLoader::LoadSTLC(rInput, pEntry);
case EResourceType::StringTable: pRes = CStringLoader::LoadSTRG(rInput, pEntry); break; case EResourceType::StringTable: return CStringLoader::LoadSTRG(rInput, pEntry);
case EResourceType::Texture: pRes = CTextureDecoder::LoadTXTR(rInput, pEntry); break; case EResourceType::Texture: return CTextureDecoder::LoadTXTR(rInput, pEntry);
case EResourceType::Tweaks: pRes = CTweakLoader::LoadCTWK(rInput, pEntry); break; case EResourceType::Tweaks: return CTweakLoader::LoadCTWK(rInput, pEntry);
case EResourceType::World: pRes = CWorldLoader::LoadMLVL(rInput, pEntry); break; case EResourceType::World: return CWorldLoader::LoadMLVL(rInput, pEntry);
case EResourceType::StateMachine: case EResourceType::StateMachine:
// AFSM currently unsupported // AFSM currently unsupported
if (pEntry->Game() <= EGame::Echoes) if (pEntry->Game() <= EGame::Echoes)
pRes = new CDependencyGroup(pEntry); return std::make_unique<CDependencyGroup>(pEntry);
else if (pEntry->Game() <= EGame::Corruption) if (pEntry->Game() <= EGame::Corruption)
pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry); return CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
else if (pEntry->Game() == EGame::DKCReturns) if (pEntry->Game() == EGame::DKCReturns)
pRes = CUnsupportedFormatLoader::LoadFSMC(rInput, pEntry); return CUnsupportedFormatLoader::LoadFSMC(rInput, pEntry);
break; return nullptr;
case EResourceType::BurstFireData: case EResourceType::BurstFireData:
case EResourceType::Particle: case EResourceType::Particle:
@ -123,15 +123,11 @@ public:
case EResourceType::ParticleCollisionResponse: case EResourceType::ParticleCollisionResponse:
case EResourceType::ParticleTransform: case EResourceType::ParticleTransform:
case EResourceType::UserEvaluatorData: case EResourceType::UserEvaluatorData:
pRes = CUnsupportedParticleLoader::LoadParticle(rInput, pEntry); return CUnsupportedParticleLoader::LoadParticle(rInput, pEntry);
break;
default: default:
pRes = new CResource(pEntry); return std::make_unique<CResource>(pEntry);
break;
} }
return pRes;
} }
}; };

View File

@ -3,7 +3,7 @@
#include "CScriptLoader.h" #include "CScriptLoader.h"
#include <Common/Log.h> #include <Common/Log.h>
CScan* CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry) std::unique_ptr<CScan> CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
{ {
// Validate magic // Validate magic
uint Magic = SCAN.ReadLong(); uint Magic = SCAN.ReadLong();
@ -14,18 +14,21 @@ CScan* CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CScan>(pEntry);
// The SCAN format in MP2 and later games uses the script loader to load SCAN parameters. // The SCAN format in MP2 and later games uses the script loader to load SCAN parameters.
// The MP1 format is not loaded the same way, as far as I'm aware, and is loaded the same // The MP1 format is not loaded the same way, as far as I'm aware, and is loaded the same
// way as a normal file format... however, since we support all games, we need to support // way as a normal file format... however, since we support all games, we need to support
// the script object method for proper MP2/3 support (including dealing with property names/IDs). // the script object method for proper MP2/3 support (including dealing with property names/IDs).
// So, it's simplest to use the script loader to load the MP1 SCAN format as well... that enables // So, it's simplest to use the script loader to load the MP1 SCAN format as well... that enables
// us to just create one class for all SCAN assets that works for every game. // us to just create one class for all SCAN assets that works for every game.
mpScan = new CScan(pEntry); mpScan = ptr.get();
CScriptLoader::LoadStructData(SCAN, mpScan->ScanData()); CScriptLoader::LoadStructData(SCAN, mpScan->ScanData());
return mpScan;
return ptr;
} }
CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry) std::unique_ptr<CScan> CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
{ {
// Validate version // Validate version
uint Version = SCAN.ReadLong(); uint Version = SCAN.ReadLong();
@ -36,17 +39,19 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
return nullptr; return nullptr;
} }
auto ptr = std::make_unique<CScan>(pEntry);
// The SCAN format in MP2 embeds a ScannableObjectInfo script object using the same file format as SCLY. // The SCAN format in MP2 embeds a ScannableObjectInfo script object using the same file format as SCLY.
// As such we use CScriptLoader to load parameters, but since we don't actually want to create a script // As such we use CScriptLoader to load parameters, but since we don't actually want to create a script
// object, we will skip past the script object/layer header and just load the properties directly. // object, we will skip past the script object/layer header and just load the properties directly.
SCAN.Skip(0x17); SCAN.Skip(0x17);
mpScan = new CScan(pEntry); mpScan = ptr.get();
CScriptLoader::LoadStructData(SCAN, mpScan->ScanData()); CScriptLoader::LoadStructData(SCAN, mpScan->ScanData());
return mpScan; return ptr;
} }
// ************ STATIC/PUBLIC ************ // ************ STATIC/PUBLIC ************
CScan* CScanLoader::LoadSCAN(IInputStream& SCAN, CResourceEntry *pEntry) std::unique_ptr<CScan> CScanLoader::LoadSCAN(IInputStream& SCAN, CResourceEntry *pEntry)
{ {
if (!SCAN.IsValid()) return nullptr; if (!SCAN.IsValid()) return nullptr;

View File

@ -3,17 +3,18 @@
#include "Core/Resource/Scan/CScan.h" #include "Core/Resource/Scan/CScan.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CScanLoader class CScanLoader
{ {
TResPtr<CScan> mpScan; TResPtr<CScan> mpScan;
CScanLoader() = default; CScanLoader() = default;
CScan* LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry); std::unique_ptr<CScan> LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry);
CScan* LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry); std::unique_ptr<CScan> LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry);
public: public:
static CScan* LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry); static std::unique_ptr<CScan> LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry);
}; };
#endif // CSCANLOADER_H #endif // CSCANLOADER_H

View File

@ -25,19 +25,20 @@ void CSkeletonLoader::CalculateBoneInverseBindMatrices()
} }
// ************ STATIC ************ // ************ STATIC ************
CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry) std::unique_ptr<CSkeleton> CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry)
{ {
auto ptr = std::make_unique<CSkeleton>(pEntry);
CSkeletonLoader Loader; CSkeletonLoader Loader;
CSkeleton *pSkel = new CSkeleton(pEntry); Loader.mpSkeleton = ptr.get();
Loader.mpSkeleton = pSkel;
EGame Game = pEntry->Game(); EGame Game = pEntry->Game();
// We don't support DKCR CINF right now // We don't support DKCR CINF right now
if (rCINF.PeekLong() == 0x9E220006) if (rCINF.PeekLong() == 0x9E220006)
return pSkel; return ptr;
uint32 NumBones = rCINF.ReadLong(); uint32 NumBones = rCINF.ReadLong();
pSkel->mBones.reserve(NumBones); ptr->mBones.reserve(NumBones);
// Read bones // Read bones
struct SBoneInfo struct SBoneInfo
@ -49,8 +50,8 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
for (uint32 iBone = 0; iBone < NumBones; iBone++) for (uint32 iBone = 0; iBone < NumBones; iBone++)
{ {
CBone *pBone = new CBone(pSkel); CBone *pBone = new CBone(ptr.get());
pSkel->mBones.push_back(pBone); ptr->mBones.push_back(pBone);
pBone->mID = rCINF.ReadLong(); pBone->mID = rCINF.ReadLong();
BoneInfo[iBone].ParentID = rCINF.ReadLong(); BoneInfo[iBone].ParentID = rCINF.ReadLong();
@ -86,15 +87,15 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
// Fill in bone info // Fill in bone info
for (uint32 iBone = 0; iBone < NumBones; iBone++) for (uint32 iBone = 0; iBone < NumBones; iBone++)
{ {
CBone *pBone = pSkel->mBones[iBone]; CBone *pBone = ptr->mBones[iBone];
SBoneInfo& rInfo = BoneInfo[iBone]; SBoneInfo& rInfo = BoneInfo[iBone];
pBone->mpParent = pSkel->BoneByID(rInfo.ParentID); pBone->mpParent = ptr->BoneByID(rInfo.ParentID);
for (uint32 iChild = 0; iChild < rInfo.ChildIDs.size(); iChild++) for (uint32 iChild = 0; iChild < rInfo.ChildIDs.size(); iChild++)
{ {
uint32 ChildID = rInfo.ChildIDs[iChild]; uint32 ChildID = rInfo.ChildIDs[iChild];
CBone *pChild = pSkel->BoneByID(ChildID); CBone *pChild = ptr->BoneByID(ChildID);
if (pChild) if (pChild)
pBone->mChildren.push_back(pChild); pBone->mChildren.push_back(pChild);
@ -104,14 +105,14 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
if (!pBone->mpParent) if (!pBone->mpParent)
{ {
if (!pSkel->mpRootBone) if (!ptr->mpRootBone)
pSkel->mpRootBone = pBone; ptr->mpRootBone = pBone;
else else
errorf("%s: Multiple root bones?", *rCINF.GetSourceString()); errorf("%s: Multiple root bones?", *rCINF.GetSourceString());
} }
} }
Loader.SetLocalBoneCoords(pSkel->mpRootBone); Loader.SetLocalBoneCoords(ptr->mpRootBone);
Loader.CalculateBoneInverseBindMatrices(); Loader.CalculateBoneInverseBindMatrices();
// Skip bone ID array // Skip bone ID array
@ -126,8 +127,8 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
TString Name = rCINF.ReadString(); TString Name = rCINF.ReadString();
uint32 BoneID = rCINF.ReadLong(); uint32 BoneID = rCINF.ReadLong();
pSkel->BoneByID(BoneID)->mName = Name; ptr->BoneByID(BoneID)->mName = Name;
} }
return pSkel; return ptr;
} }

View File

@ -4,6 +4,7 @@
#include "Core/Resource/Animation/CSkeleton.h" #include "Core/Resource/Animation/CSkeleton.h"
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CSkeletonLoader class CSkeletonLoader
{ {
@ -15,7 +16,7 @@ class CSkeletonLoader
void CalculateBoneInverseBindMatrices(); void CalculateBoneInverseBindMatrices();
public: public:
static CSkeleton* LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry); static std::unique_ptr<CSkeleton> LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry);
}; };
#endif // CSKELETONLOADER_H #endif // CSKELETONLOADER_H

View File

@ -2,10 +2,10 @@
#include <Common/Macros.h> #include <Common/Macros.h>
// ************ STATIC ************ // ************ STATIC ************
CSkin* CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry) std::unique_ptr<CSkin> CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry)
{ {
if (!rCSKR.IsValid()) return nullptr; if (!rCSKR.IsValid()) return nullptr;
CSkin *pSkin = new CSkin(pEntry); auto pSkin = std::make_unique<CSkin>(pEntry);
// We don't support MP3/DKCR CSKR yet // We don't support MP3/DKCR CSKR yet
if (rCSKR.PeekLong() == FOURCC('SKIN')) if (rCSKR.PeekLong() == FOURCC('SKIN'))

View File

@ -3,13 +3,14 @@
#include "Core/Resource/Animation/CSkin.h" #include "Core/Resource/Animation/CSkin.h"
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include <memory>
class CSkinLoader class CSkinLoader
{ {
CSkinLoader() = default; CSkinLoader() = default;
public: public:
static CSkin* LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry); static std::unique_ptr<CSkin> LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry);
}; };
#endif // CSKINLOADER_H #endif // CSKINLOADER_H

View File

@ -211,9 +211,10 @@ void CStringLoader::LoadNameTable(IInputStream& STRG)
} }
// ************ STATIC ************ // ************ STATIC ************
CStringTable* CStringLoader::LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry) std::unique_ptr<CStringTable> CStringLoader::LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry)
{ {
if (!STRG.IsValid()) return nullptr; if (!STRG.IsValid())
return nullptr;
// Verify that this is a valid STRG // Verify that this is a valid STRG
uint Magic = STRG.ReadLong(); uint Magic = STRG.ReadLong();
@ -250,15 +251,16 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry
} }
// Valid; now we create the loader and call the function that reads the rest of the file // Valid; now we create the loader and call the function that reads the rest of the file
auto ptr = std::make_unique<CStringTable>(pEntry);
CStringLoader Loader; CStringLoader Loader;
Loader.mpStringTable = new CStringTable(pEntry); Loader.mpStringTable = ptr.get();
Loader.mVersion = Version; Loader.mVersion = Version;
if (Version == EGame::PrimeDemo) Loader.LoadPrimeDemoSTRG(STRG); if (Version == EGame::PrimeDemo) Loader.LoadPrimeDemoSTRG(STRG);
else if (Version < EGame::Corruption) Loader.LoadPrimeSTRG(STRG); else if (Version < EGame::Corruption) Loader.LoadPrimeSTRG(STRG);
else Loader.LoadCorruptionSTRG(STRG); else Loader.LoadCorruptionSTRG(STRG);
return Loader.mpStringTable; return ptr;
} }
EGame CStringLoader::GetFormatVersion(uint32 Version) EGame CStringLoader::GetFormatVersion(uint32 Version)

View File

@ -5,6 +5,7 @@
#include "Core/Resource/TResPtr.h" #include "Core/Resource/TResPtr.h"
#include "Core/Resource/StringTable/CStringTable.h" #include "Core/Resource/StringTable/CStringTable.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <memory>
class CStringLoader class CStringLoader
{ {
@ -18,7 +19,7 @@ class CStringLoader
void LoadNameTable(IInputStream& STRG); void LoadNameTable(IInputStream& STRG);
public: public:
static CStringTable* LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry); static std::unique_ptr<CStringTable> LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry);
static EGame GetFormatVersion(uint Version); static EGame GetFormatVersion(uint Version);
}; };

View File

@ -42,9 +42,9 @@ CTextureDecoder::~CTextureDecoder()
{ {
} }
CTexture* CTextureDecoder::CreateTexture() std::unique_ptr<CTexture> CTextureDecoder::CreateTexture()
{ {
CTexture *pTex = new CTexture(mpEntry); auto pTex = std::make_unique<CTexture>(mpEntry);
pTex->mSourceTexelFormat = mTexelFormat; pTex->mSourceTexelFormat = mTexelFormat;
pTex->mWidth = mWidth; pTex->mWidth = mWidth;
pTex->mHeight = mHeight; pTex->mHeight = mHeight;
@ -91,7 +91,7 @@ CTexture* CTextureDecoder::CreateTexture()
} }
// ************ STATIC ************ // ************ STATIC ************
CTexture* CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry) std::unique_ptr<CTexture> CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry)
{ {
CTextureDecoder Decoder; CTextureDecoder Decoder;
Decoder.mpEntry = pEntry; Decoder.mpEntry = pEntry;
@ -100,19 +100,19 @@ CTexture* CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry)
return Decoder.CreateTexture(); return Decoder.CreateTexture();
} }
CTexture* CTextureDecoder::DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry) std::unique_ptr<CTexture> CTextureDecoder::DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry)
{ {
CTextureDecoder Decoder; CTextureDecoder Decoder;
Decoder.mpEntry = pEntry; Decoder.mpEntry = pEntry;
Decoder.ReadTXTR(rTXTR); Decoder.ReadTXTR(rTXTR);
Decoder.FullDecodeGXTexture(rTXTR); Decoder.FullDecodeGXTexture(rTXTR);
CTexture *pTexture = Decoder.CreateTexture(); auto pTexture = Decoder.CreateTexture();
pTexture->mTexelFormat = ETexelFormat::RGBA8; pTexture->mTexelFormat = ETexelFormat::RGBA8;
return pTexture; return pTexture;
} }
CTexture* CTextureDecoder::LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry) std::unique_ptr<CTexture> CTextureDecoder::LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry)
{ {
CTextureDecoder Decoder; CTextureDecoder Decoder;
Decoder.mpEntry = pEntry; Decoder.mpEntry = pEntry;

View File

@ -5,9 +5,10 @@
#include "Core/Resource/ETexelFormat.h" #include "Core/Resource/ETexelFormat.h"
#include <Common/BasicTypes.h> #include <Common/BasicTypes.h>
#include <Common/CColor.h> #include <Common/CColor.h>
#include <Common/FileIO.h> #include <Common/FileIO.h>
#include <memory>
class CTextureDecoder class CTextureDecoder
{ {
CResourceEntry *mpEntry; CResourceEntry *mpEntry;
@ -36,7 +37,7 @@ class CTextureDecoder
// Private Functions // Private Functions
CTextureDecoder(); CTextureDecoder();
~CTextureDecoder(); ~CTextureDecoder();
CTexture* CreateTexture(); std::unique_ptr<CTexture> CreateTexture();
// Read // Read
void ReadTXTR(IInputStream& rTXTR); void ReadTXTR(IInputStream& rTXTR);
@ -78,9 +79,9 @@ class CTextureDecoder
// Static // Static
public: public:
static CTexture* LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry); static std::unique_ptr<CTexture> LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry);
static CTexture* LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry); static std::unique_ptr<CTexture> LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry);
static CTexture* DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry); static std::unique_ptr<CTexture> DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry);
static CTexture* DoFullDecode(CTexture *pTexture); static CTexture* DoFullDecode(CTexture *pTexture);
// Utility // Utility

View File

@ -38,7 +38,7 @@ void CUnsupportedFormatLoader::PerformCheating(IInputStream& rFile, EGame Game,
} }
} }
CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry) std::unique_ptr<CAudioMacro> CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry)
{ {
uint32 Magic = rCAUD.ReadLong(); uint32 Magic = rCAUD.ReadLong();
ASSERT(Magic == FOURCC('CAUD')); ASSERT(Magic == FOURCC('CAUD'));
@ -50,7 +50,7 @@ CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEn
EGame::Invalid); EGame::Invalid);
ASSERT(Game != EGame::Invalid && Game == pEntry->Game()); ASSERT(Game != EGame::Invalid && Game == pEntry->Game());
CAudioMacro *pMacro = new CAudioMacro(pEntry); auto pMacro = std::make_unique<CAudioMacro>(pEntry);
pMacro->mMacroName = rCAUD.ReadString(); pMacro->mMacroName = rCAUD.ReadString();
// DKCR is missing the sample data size value, and the bulk of the format isn't well understood, unfortunately // DKCR is missing the sample data size value, and the bulk of the format isn't well understood, unfortunately
@ -90,39 +90,39 @@ CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEn
return pMacro; return pMacro;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry)
{ {
uint32 Magic = rCSNG.ReadLong(); uint32 Magic = rCSNG.ReadLong();
ASSERT(Magic == 0x2); ASSERT(Magic == 0x2);
rCSNG.Seek(0x8, SEEK_CUR); rCSNG.Seek(0x8, SEEK_CUR);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
pGroup->AddDependency(rCSNG.ReadLong()); pGroup->AddDependency(rCSNG.ReadLong());
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry)
{ {
// Check for HIER, which needs special handling // Check for HIER, which needs special handling
if (rDUMB.PeekLong() == FOURCC('HIER')) if (rDUMB.PeekLong() == FOURCC('HIER'))
return LoadHIER(rDUMB, pEntry); return LoadHIER(rDUMB, pEntry);
// Load other DUMB file. DUMB files don't have a set format - they're different between different files // Load other DUMB file. DUMB files don't have a set format - they're different between different files
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
std::list<CAssetID> DepList; std::list<CAssetID> DepList;
PerformCheating(rDUMB, pEntry->Game(), DepList); PerformCheating(rDUMB, pEntry->Game(), DepList);
for (auto Iter = DepList.begin(); Iter != DepList.end(); Iter++) for (const auto& dep : DepList)
pGroup->AddDependency(*Iter); pGroup->AddDependency(dep);
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry)
{ {
uint32 Version = rFRME.ReadLong(); uint32 Version = rFRME.ReadLong();
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
// Prime 1 // Prime 1
if (Version == 0 || Version == 1) if (Version == 0 || Version == 1)
@ -232,7 +232,6 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResou
rFRME.Seek(0x42, SEEK_CUR); rFRME.Seek(0x42, SEEK_CUR);
} }
} }
// MP2/MP3/DKCR are much easier... dependency list right at the beginning of the file // MP2/MP3/DKCR are much easier... dependency list right at the beginning of the file
else if (Version == 4 || Version == 5 || Version == 0xD || Version == 0xE || Version == 0x10) else if (Version == 4 || Version == 5 || Version == 0xD || Version == 0xE || Version == 0x10)
{ {
@ -249,23 +248,21 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResou
pGroup->AddDependency( CAssetID(rFRME, Game) ); pGroup->AddDependency( CAssetID(rFRME, Game) );
} }
} }
else else
{ {
errorf("Unrecognized FRME version: %d", Version); errorf("Unrecognized FRME version: %d", Version);
delete pGroup;
return nullptr; return nullptr;
} }
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry)
{ {
uint32 Magic = rFSM2.ReadLong(); uint32 Magic = rFSM2.ReadLong();
ASSERT(Magic == FOURCC('FSM2')); ASSERT(Magic == FOURCC('FSM2'));
CDependencyGroup *pOut = new CDependencyGroup(pEntry); auto pOut = std::make_unique<CDependencyGroup>(pEntry);
uint32 Version = rFSM2.ReadLong(); uint32 Version = rFSM2.ReadLong();
uint32 NumStates = rFSM2.ReadLong(); uint32 NumStates = rFSM2.ReadLong();
uint32 NumUnkA = rFSM2.ReadLong(); uint32 NumUnkA = rFSM2.ReadLong();
@ -333,29 +330,29 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
return pOut; return pOut;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry)
{ {
CFourCC Magic = rFSMC.ReadLong(); CFourCC Magic = rFSMC.ReadLong();
ASSERT(Magic == FOURCC('FSMC')); ASSERT(Magic == FOURCC('FSMC'));
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
std::list<CAssetID> AssetList; std::list<CAssetID> AssetList;
PerformCheating(rFSMC, pEntry->Game(), AssetList); PerformCheating(rFSMC, pEntry->Game(), AssetList);
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++) for (const auto& asset : AssetList)
pGroup->AddDependency(*Iter); pGroup->AddDependency(asset);
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry)
{ {
CFourCC Magic = rHIER.ReadLong(); CFourCC Magic = rHIER.ReadLong();
ASSERT(Magic == "HIER"); ASSERT(Magic == "HIER");
uint32 NumNodes = rHIER.ReadLong(); uint32 NumNodes = rHIER.ReadLong();
CDependencyGroup *pOut = new CDependencyGroup(pEntry); auto pOut = std::make_unique<CDependencyGroup>(pEntry);
// Note: For some reason this file still exists in MP3 and it's identical to MP2, including with 32-bit asset IDs. // Note: For some reason this file still exists in MP3 and it's identical to MP2, including with 32-bit asset IDs.
// Obviously we can't read 32-bit asset IDs in MP3, so this file should just be ignored. // Obviously we can't read 32-bit asset IDs in MP3, so this file should just be ignored.
@ -373,7 +370,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResou
return pOut; return pOut;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry)
{ {
uint32 Magic = rHINT.ReadLong(); uint32 Magic = rHINT.ReadLong();
ASSERT(Magic == 0x00BADBAD); ASSERT(Magic == 0x00BADBAD);
@ -392,7 +389,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
} }
// Read main file // Read main file
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
uint32 NumHints = rHINT.ReadLong(); uint32 NumHints = rHINT.ReadLong();
for (uint32 iHint = 0; iHint < NumHints; iHint++) for (uint32 iHint = 0; iHint < NumHints; iHint++)
@ -427,9 +424,10 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
return pGroup; return pGroup;
} }
CMapArea* CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMAPA*/, CResourceEntry *pEntry) std::unique_ptr<CMapArea> CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMAPA*/, CResourceEntry *pEntry)
{ {
TResPtr<CMapArea> pMap = new CMapArea(pEntry); auto ptr = std::make_unique<CMapArea>(pEntry);
TResPtr<CMapArea> pMap = ptr.get();
// We don't actually read the file. Just fetch the name string so we can build the dependency tree. // We don't actually read the file. Just fetch the name string so we can build the dependency tree.
CAssetID MapAreaID = pMap->ID(); CAssetID MapAreaID = pMap->ID();
@ -474,10 +472,10 @@ CMapArea* CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMAPA*/, CResourceE
} }
pMap->Entry()->ResourceStore()->DestroyUnreferencedResources(); pMap->Entry()->ResourceStore()->DestroyUnreferencedResources();
return pMap; return ptr;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry)
{ {
uint32 Magic = rMAPW.ReadLong(); uint32 Magic = rMAPW.ReadLong();
ASSERT(Magic == 0xDEADF00D); ASSERT(Magic == 0xDEADF00D);
@ -494,7 +492,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResou
rMAPW.Seek(AreasStart, SEEK_SET); rMAPW.Seek(AreasStart, SEEK_SET);
// Read MAPA IDs // Read MAPA IDs
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
for (uint32 iArea = 0; iArea < NumAreas; iArea++) for (uint32 iArea = 0; iArea < NumAreas; iArea++)
pGroup->AddDependency(CAssetID(rMAPW, IDLength)); pGroup->AddDependency(CAssetID(rMAPW, IDLength));
@ -502,7 +500,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResou
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry)
{ {
uint32 Magic = rMAPU.ReadLong(); uint32 Magic = rMAPU.ReadLong();
ASSERT(Magic == 0xABCDEF01); ASSERT(Magic == 0xABCDEF01);
@ -510,7 +508,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResou
uint32 Version = rMAPU.ReadLong(); uint32 Version = rMAPU.ReadLong();
ASSERT(Version == 0x1); ASSERT(Version == 0x1);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
pGroup->AddDependency(rMAPU.ReadLong()); pGroup->AddDependency(rMAPU.ReadLong());
// Read worlds // Read worlds
@ -529,13 +527,13 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResou
return pGroup; return pGroup;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry)
{ {
// RULE files can contain a reference to another RULE file, but has no other dependencies. // RULE files can contain a reference to another RULE file, but has no other dependencies.
const uint32 Magic = rRULE.ReadLong(); const uint32 Magic = rRULE.ReadLong();
ASSERT(Magic == FOURCC('RULE')); ASSERT(Magic == FOURCC('RULE'));
CDependencyGroup *pGroup = new CDependencyGroup(pEntry); auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
rRULE.Seek(0x1, SEEK_CUR); rRULE.Seek(0x1, SEEK_CUR);
// Version test // Version test

View File

@ -4,29 +4,30 @@
#include "Core/Resource/CAudioMacro.h" #include "Core/Resource/CAudioMacro.h"
#include "Core/Resource/CDependencyGroup.h" #include "Core/Resource/CDependencyGroup.h"
#include "Core/Resource/CMapArea.h" #include "Core/Resource/CMapArea.h"
#include <list>
#include <memory>
// This class is responsible for loading formats that aren't yet fully supported. // 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. // This is needed so we have access to the full dependency list of all resource types.
class CUnsupportedFormatLoader class CUnsupportedFormatLoader
{ {
CDependencyGroup *mpGroup = nullptr;
CUnsupportedFormatLoader() = default; CUnsupportedFormatLoader() = default;
static void PerformCheating(IInputStream& rFile, EGame Game, std::list<CAssetID>& rAssetList); static void PerformCheating(IInputStream& rFile, EGame Game, std::list<CAssetID>& rAssetList);
public: public:
static CAudioMacro* LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry); static std::unique_ptr<CAudioMacro> LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry);
static CDependencyGroup* LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry);
static CDependencyGroup* LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry);
static CDependencyGroup* LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry);
static CDependencyGroup* LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry);
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
static CMapArea* LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry); static std::unique_ptr<CMapArea> LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry);
static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
static CDependencyGroup* LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry);
}; };
#endif // CUNSUPPORTEDFORMATLOADER_H #endif // CUNSUPPORTEDFORMATLOADER_H

View File

@ -1763,10 +1763,10 @@ void CUnsupportedParticleLoader::ParseKeyframeEmitterData(IInputStream& rFile, c
} }
// ************ STATIC ************ // ************ STATIC ************
CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry) std::unique_ptr<CDependencyGroup> CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry)
{ {
CUnsupportedParticleLoader Loader; CUnsupportedParticleLoader Loader;
Loader.mpGroup = new CDependencyGroup(pEntry); Loader.mpGroup = std::make_unique<CDependencyGroup>(pEntry);
// Validate DKCR asset header // Validate DKCR asset header
if (pEntry->Game() == EGame::DKCReturns) if (pEntry->Game() == EGame::DKCReturns)
@ -1776,7 +1776,7 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile,
if (AssetHeader != 0x6E190001) if (AssetHeader != 0x6E190001)
{ {
errorf("Invalid DKCR particle header: %08X", AssetHeader); errorf("Invalid DKCR particle header: %08X", AssetHeader);
return Loader.mpGroup; return std::move(Loader.mpGroup);
} }
} }
@ -1810,5 +1810,5 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile,
if (!ShouldContinue) break; if (!ShouldContinue) break;
} }
return Loader.mpGroup; return std::move(Loader.mpGroup);
} }

View File

@ -2,12 +2,13 @@
#define CUNSUPPORTEDPARTICLELOADER_H #define CUNSUPPORTEDPARTICLELOADER_H
#include "Core/Resource/CDependencyGroup.h" #include "Core/Resource/CDependencyGroup.h"
#include <memory>
// This class is responsible for loading particle formats that aren't yet fully supported. // This class is responsible for loading particle formats that aren't yet fully supported.
// Used for finding dependencies. Split from CUnsupportedFormatLoader for being too big. // Used for finding dependencies. Split from CUnsupportedFormatLoader for being too big.
class CUnsupportedParticleLoader class CUnsupportedParticleLoader
{ {
CDependencyGroup *mpGroup = nullptr; std::unique_ptr<CDependencyGroup> mpGroup;
CUnsupportedParticleLoader() = default; CUnsupportedParticleLoader() = default;
// Format-Specific Parameter Loading // Format-Specific Parameter Loading
@ -41,7 +42,7 @@ class CUnsupportedParticleLoader
void ParseKeyframeEmitterData(IInputStream& rFile, const CFourCC& rkFunc, uint32 ElemSize); void ParseKeyframeEmitterData(IInputStream& rFile, const CFourCC& rkFunc, uint32 ElemSize);
public: public:
static CDependencyGroup* LoadParticle(IInputStream& rPART, CResourceEntry *pEntry); static std::unique_ptr<CDependencyGroup> LoadParticle(IInputStream& rPART, CResourceEntry *pEntry);
}; };
#endif // CUNSUPPORTEDPARTICLELOADER_H #endif // CUNSUPPORTEDPARTICLELOADER_H

View File

@ -276,7 +276,7 @@ void CWorldLoader::GenerateEditorData()
} }
} }
CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry) std::unique_ptr<CWorld> CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
{ {
if (!rMLVL.IsValid()) return nullptr; if (!rMLVL.IsValid()) return nullptr;
@ -296,8 +296,10 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
} }
// Filestream is valid, magic+version are valid; everything seems good! // Filestream is valid, magic+version are valid; everything seems good!
auto ptr = std::make_unique<CWorld>(pEntry);
CWorldLoader Loader; CWorldLoader Loader;
Loader.mpWorld = new CWorld(pEntry); Loader.mpWorld = ptr.get();
Loader.mVersion = Version; Loader.mVersion = Version;
if (Version != EGame::DKCReturns) if (Version != EGame::DKCReturns)
@ -306,7 +308,7 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
Loader.LoadReturnsMLVL(rMLVL); Loader.LoadReturnsMLVL(rMLVL);
Loader.GenerateEditorData(); Loader.GenerateEditorData();
return Loader.mpWorld; return ptr;
} }
EGame CWorldLoader::GetFormatVersion(uint32 Version) EGame CWorldLoader::GetFormatVersion(uint32 Version)

View File

@ -5,6 +5,7 @@
#include "Core/Resource/CWorld.h" #include "Core/Resource/CWorld.h"
#include <Common/EGame.h> #include <Common/EGame.h>
#include <Common/FileIO.h> #include <Common/FileIO.h>
#include <memory>
class CWorldLoader class CWorldLoader
{ {
@ -17,7 +18,7 @@ class CWorldLoader
void GenerateEditorData(); void GenerateEditorData();
public: public:
static CWorld* LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry); static std::unique_ptr<CWorld> LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry);
static EGame GetFormatVersion(uint32 Version); static EGame GetFormatVersion(uint32 Version);
}; };

View File

@ -2,7 +2,7 @@
#include "Core/Resource/Factory/CScriptLoader.h" #include "Core/Resource/Factory/CScriptLoader.h"
#include "Core/Resource/Script/NGameList.h" #include "Core/Resource/Script/NGameList.h"
CTweakData* CTweakLoader::LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry) std::unique_ptr<CTweakData> CTweakLoader::LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry)
{ {
// Find the correct template based on the asset ID. // Find the correct template based on the asset ID.
static const std::unordered_map<uint, const char*> skIdToTemplateName = static const std::unordered_map<uint, const char*> skIdToTemplateName =
@ -36,14 +36,13 @@ CTweakData* CTweakLoader::LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry)
ASSERT(pTweakTemplate != nullptr); ASSERT(pTweakTemplate != nullptr);
// Load tweak data // Load tweak data
CTweakData* pTweakData = new CTweakData(pTweakTemplate, pEntry->ID().ToLong(), pEntry); auto pTweakData = std::make_unique<CTweakData>(pTweakTemplate, pEntry->ID().ToLong(), pEntry);
CScriptLoader::LoadStructData(CTWK, pTweakData->TweakData()); CScriptLoader::LoadStructData(CTWK, pTweakData->TweakData());
// Verify // Verify
if (!CTWK.EoF() && CTWK.PeekShort() != -1) if (!CTWK.EoF() && CTWK.PeekShort() != -1)
{ {
errorf("%s: unread property data, tweak template may be malformed (%d bytes left)", *CTWK.GetSourceString(), CTWK.Size() - CTWK.Tell()); errorf("%s: unread property data, tweak template may be malformed (%d bytes left)", *CTWK.GetSourceString(), CTWK.Size() - CTWK.Tell());
delete pTweakData;
return nullptr; return nullptr;
} }

View File

@ -2,6 +2,7 @@
#define CTWEAKLOADER_H #define CTWEAKLOADER_H
#include "CTweakData.h" #include "CTweakData.h"
#include <memory>
/** Class responsible for loading tweak data */ /** Class responsible for loading tweak data */
class CTweakLoader class CTweakLoader
@ -11,7 +12,7 @@ class CTweakLoader
public: public:
/** Loader entry point */ /** Loader entry point */
static CTweakData* LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry); static std::unique_ptr<CTweakData> LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry);
static void LoadNTWK(IInputStream& NTWK, EGame Game, std::vector<CTweakData*>& OutTweaks); static void LoadNTWK(IInputStream& NTWK, EGame Game, std::vector<CTweakData*>& OutTweaks);
}; };

View File

@ -772,7 +772,7 @@ void CModelEditorWindow::ConvertToDDS()
TString TexFilename = TO_TSTRING(Input); TString TexFilename = TO_TSTRING(Input);
CFileInStream InTextureFile(TexFilename, EEndian::LittleEndian); CFileInStream InTextureFile(TexFilename, EEndian::LittleEndian);
CTexture *pTex = CTextureDecoder::LoadTXTR( InTextureFile, nullptr ); auto pTex = CTextureDecoder::LoadTXTR( InTextureFile, nullptr );
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds"; TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds";
CFileOutStream Out(OutName, EEndian::LittleEndian); CFileOutStream Out(OutName, EEndian::LittleEndian);
@ -784,8 +784,6 @@ void CModelEditorWindow::ConvertToDDS()
if (!Success) QMessageBox::warning(this, "Error", "Couldn't write output DDS!"); if (!Success) QMessageBox::warning(this, "Error", "Couldn't write output DDS!");
else QMessageBox::information(this, "Success", "Successfully converted to DDS!"); else QMessageBox::information(this, "Success", "Successfully converted to DDS!");
} }
delete pTex;
} }
void CModelEditorWindow::ConvertToTXTR() void CModelEditorWindow::ConvertToTXTR()
@ -795,7 +793,7 @@ void CModelEditorWindow::ConvertToTXTR()
TString TexFilename = TO_TSTRING(Input); TString TexFilename = TO_TSTRING(Input);
CFileInStream InTextureFile = CFileInStream(TexFilename, EEndian::LittleEndian); CFileInStream InTextureFile = CFileInStream(TexFilename, EEndian::LittleEndian);
CTexture *pTex = CTextureDecoder::LoadDDS(InTextureFile, nullptr); auto pTex = CTextureDecoder::LoadDDS(InTextureFile, nullptr);
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr"; TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr";
if ((pTex->TexelFormat() != ETexelFormat::DXT1) || (pTex->NumMipMaps() > 1)) if ((pTex->TexelFormat() != ETexelFormat::DXT1) || (pTex->NumMipMaps() > 1))
@ -808,7 +806,7 @@ void CModelEditorWindow::ConvertToTXTR()
else else
{ {
CTextureEncoder::EncodeTXTR(Out, pTex, ETexelFormat::GX_CMPR); CTextureEncoder::EncodeTXTR(Out, pTex.get(), ETexelFormat::GX_CMPR);
QMessageBox::information(this, "Success", "Successfully converted to TXTR!"); QMessageBox::information(this, "Success", "Successfully converted to TXTR!");
} }
} }

View File

@ -843,7 +843,7 @@ void CResourceBrowser::FindAssetByID()
EIDLength IDLength = CAssetID::GameIDLength(Game); EIDLength IDLength = CAssetID::GameIDLength(Game);
bool WasValid = false; bool WasValid = false;
if (StringAssetID.IsHexString(false, IDLength * 2)) if (StringAssetID.IsHexString(false, static_cast<int>(IDLength) * 2))
{ {
if (StringAssetID.StartsWith("0x", false)) if (StringAssetID.StartsWith("0x", false))
StringAssetID = StringAssetID.ChopFront(2); StringAssetID = StringAssetID.ChopFront(2);

View File

@ -97,7 +97,7 @@ public:
if (mCompareBitLength > 0) if (mCompareBitLength > 0)
{ {
uint32 IDBitLength = pEntry->ID().Length() * 8; const auto IDBitLength = static_cast<uint32>(pEntry->ID().Length()) * 8;
if (mCompareBitLength <= IDBitLength) if (mCompareBitLength <= IDBitLength)
{ {