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;
}
CResourceEntry::~CResourceEntry()
{
if (mpResource) delete mpResource;
}
CResourceEntry::~CResourceEntry() = default;
bool CResourceEntry::LoadMetadata()
{
@ -386,7 +383,8 @@ bool CResourceEntry::Cook()
CResource* CResourceEntry::Load()
{
// 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.
// 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())
{
errorf("Failed to load raw resource; falling back on cooked. Raw path: %s", *RawAssetPath());
delete mpResource;
mpResource = nullptr;
mpResource.reset();
}
else
@ -419,7 +416,7 @@ CResource* CResourceEntry::Load()
}
if (mpResource)
return mpResource;
return mpResource.get();
}
ASSERT(!mpResource);
@ -446,8 +443,11 @@ CResource* CResourceEntry::Load()
CResource* CResourceEntry::LoadCooked(IInputStream& rInput)
{
// Overload to allow for load from an arbitrary input stream.
if (mpResource) return mpResource;
if (!rInput.IsValid()) return nullptr;
if (mpResource)
return mpResource.get();
if (!rInput.IsValid())
return nullptr;
// Set gpResourceStore to ensure the correct resource store is accessed by loader functions
CResourceStore *pOldStore = gpResourceStore;
@ -458,15 +458,14 @@ CResource* CResourceEntry::LoadCooked(IInputStream& rInput)
mpStore->TrackLoadedResource(this);
gpResourceStore = pOldStore;
return mpResource;
return mpResource.get();
}
bool CResourceEntry::Unload()
{
ASSERT(mpResource != nullptr);
ASSERT(!mpResource->IsReferenced());
delete mpResource;
mpResource = nullptr;
mpResource.reset();
return true;
}

View File

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

View File

@ -130,13 +130,16 @@ void CAnimEventLoader::LoadSoundEvent(IInputStream& rEVNT)
}
// ************ 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;
Loader.mpEventData = new CAnimEventData(pEntry);
Loader.mpEventData = ptr.get();
Loader.mGame = EGame::Prime;
Loader.LoadEvents(rEVNT);
return Loader.mpEventData;
return ptr;
}
CAnimEventData* CAnimEventLoader::LoadAnimSetEvents(IInputStream& rANCS)

View File

@ -3,6 +3,7 @@
#include "Core/Resource/Animation/CAnimEventData.h"
#include "Core/Resource/TResPtr.h"
#include <memory>
class CAnimEventLoader
{
@ -18,7 +19,7 @@ class CAnimEventLoader
void LoadSoundEvent(IInputStream& rEVNT);
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* LoadCorruptionCharacterEventSet(IInputStream& rCHAR);
};

View File

@ -5,9 +5,9 @@
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();
// Character Header
@ -91,10 +91,9 @@ CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
}
ProcessPrimitives();
return pSet;
}
CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
void CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
{
rCHAR.Skip(0x14);
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.
if ((Flag & 0x10) == 0)
return pSet;
return;
// Anim ID Map
if (Flag & 0x20)
@ -183,7 +182,7 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
break;
default:
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();
return pSet;
}
void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
@ -511,7 +509,7 @@ void CAnimSetLoader::ProcessPrimitives()
}
// ************ STATIC ************
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
std::unique_ptr<CAnimSet> CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
{
if (!rANCS.IsValid()) return nullptr;
@ -522,8 +520,10 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
return nullptr;
}
auto ptr = std::make_unique<CAnimSet>(pEntry);
CAnimSetLoader Loader;
Loader.pSet = new CAnimSet(pEntry);
Loader.pSet = ptr.get();
Loader.mGame = pEntry->Game();
uint32 NodeCount = rANCS.ReadLong();
@ -615,40 +615,50 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
Loader.LoadAnimationSet(rANCS);
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;
uint8 Check = rCHAR.ReadByte();
if (Check == 0x5 || Check == 0x3)
{
auto ptr = std::make_unique<CAnimSet>(pEntry);
Loader.mGame = EGame::Corruption;
Loader.pSet = new CAnimSet(pEntry);
return Loader.LoadCorruptionCHAR(rCHAR);
Loader.pSet = ptr.get();
Loader.LoadCorruptionCHAR(rCHAR);
return ptr;
}
if (Check == 0x59)
{
auto ptr = std::make_unique<CAnimSet>(pEntry);
Loader.mGame = EGame::DKCReturns;
Loader.pSet = new CAnimSet(pEntry);
return Loader.LoadReturnsCHAR(rCHAR);
Loader.pSet = ptr.get();
Loader.LoadReturnsCHAR(rCHAR);
return ptr;
}
errorf("%s: CHAR has invalid first byte: 0x%02X", *rCHAR.GetSourceString(), Check);
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
CSourceAnimData *pData = new CSourceAnimData(pEntry);
auto pData = std::make_unique<CSourceAnimData>(pEntry);
uint16 Unknown = rSAND.ReadShort(); // probably version
ASSERT(Unknown == 0);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
#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!
// Version check
uint32 Check = rAGSC.PeekLong();
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
if (Game == EGame::Prime)
@ -60,9 +60,9 @@ CAudioGroup* CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pE
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();
for (uint32 iMacro = 0; iMacro < NumMacroIDs; iMacro++)
@ -71,9 +71,9 @@ CAudioLookupTable* CAudioGroupLoader::LoadATBL(IInputStream& rATBL, CResourceEnt
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();
pOut->mStringList.reserve(NumStrings);

View File

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

View File

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

View File

@ -26,7 +26,7 @@ class CCollisionLoader
public:
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);
};

View File

@ -32,14 +32,15 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, uint32 DepCount)
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();
EGame Game = VersionTest(rDGRP, NumDependencies);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
for (uint32 iDep = 0; iDep < NumDependencies; iDep++)
{

View File

@ -3,6 +3,7 @@
#include "Core/Resource/CDependencyGroup.h"
#include <Common/EGame.h>
#include <memory>
class CDependencyGroupLoader
{
@ -10,7 +11,7 @@ class CDependencyGroupLoader
static EGame VersionTest(IInputStream& rDGRP, uint32 DepCount);
public:
static CDependencyGroup* LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadDGRP(IInputStream& rDGRP, CResourceEntry *pEntry);
};
#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
mpFont->mUnknown = rFONT.ReadLong();
@ -72,13 +72,12 @@ CFont* CFontLoader::LoadFont(IInputStream& rFONT)
Pair.Adjust = rFONT.ReadLong();
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);
if (Magic != FOURCC('FONT'))
@ -95,10 +94,14 @@ CFont* CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry)
return nullptr;
}
auto ptr = std::make_unique<CFont>(pEntry);
CFontLoader Loader;
Loader.mpFont = new CFont(pEntry);
Loader.mpFont = ptr.get();
Loader.mVersion = Version;
return Loader.LoadFont(rFONT);
Loader.LoadFont(rFONT);
return ptr;
}
EGame CFontLoader::GetFormatVersion(uint32 Version)

View File

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

View File

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

View File

@ -11,6 +11,8 @@
#include <assimp/scene.h>
#include <memory>
enum class EModelLoaderFlag
{
None = 0x0,
@ -24,8 +26,6 @@ DECLARE_FLAGS_ENUMCLASS(EModelLoaderFlag, FModelLoaderFlags)
class CModelLoader
{
public:
private:
TResPtr<CModel> mpModel;
std::vector<CMaterialSet*> mMaterials;
@ -58,7 +58,7 @@ private:
SSurface* LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet);
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* 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);

View File

@ -1,8 +1,8 @@
#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();
for (uint32 iMap = 0; iMap < NumMappings; iMap++)

View File

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

View File

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

View File

@ -3,7 +3,7 @@
#include "CScriptLoader.h"
#include <Common/Log.h>
CScan* CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
std::unique_ptr<CScan> CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
{
// Validate magic
uint Magic = SCAN.ReadLong();
@ -14,18 +14,21 @@ CScan* CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
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 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
// 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
// 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());
return mpScan;
return ptr;
}
CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
std::unique_ptr<CScan> CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
{
// Validate version
uint Version = SCAN.ReadLong();
@ -36,17 +39,19 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
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.
// 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.
SCAN.Skip(0x17);
mpScan = new CScan(pEntry);
mpScan = ptr.get();
CScriptLoader::LoadStructData(SCAN, mpScan->ScanData());
return mpScan;
return ptr;
}
// ************ STATIC/PUBLIC ************
CScan* CScanLoader::LoadSCAN(IInputStream& SCAN, CResourceEntry *pEntry)
std::unique_ptr<CScan> CScanLoader::LoadSCAN(IInputStream& SCAN, CResourceEntry *pEntry)
{
if (!SCAN.IsValid()) return nullptr;

View File

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

View File

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

View File

@ -2,10 +2,10 @@
#include <Common/Macros.h>
// ************ STATIC ************
CSkin* CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry)
std::unique_ptr<CSkin> CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry)
{
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
if (rCSKR.PeekLong() == FOURCC('SKIN'))

View File

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

View File

@ -211,9 +211,10 @@ void CStringLoader::LoadNameTable(IInputStream& STRG)
}
// ************ 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
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
auto ptr = std::make_unique<CStringTable>(pEntry);
CStringLoader Loader;
Loader.mpStringTable = new CStringTable(pEntry);
Loader.mpStringTable = ptr.get();
Loader.mVersion = Version;
if (Version == EGame::PrimeDemo) Loader.LoadPrimeDemoSTRG(STRG);
else if (Version < EGame::Corruption) Loader.LoadPrimeSTRG(STRG);
else Loader.LoadCorruptionSTRG(STRG);
return Loader.mpStringTable;
return ptr;
}
EGame CStringLoader::GetFormatVersion(uint32 Version)

View File

@ -5,6 +5,7 @@
#include "Core/Resource/TResPtr.h"
#include "Core/Resource/StringTable/CStringTable.h"
#include <Common/EGame.h>
#include <memory>
class CStringLoader
{
@ -18,7 +19,7 @@ class CStringLoader
void LoadNameTable(IInputStream& STRG);
public:
static CStringTable* LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry);
static std::unique_ptr<CStringTable> LoadSTRG(IInputStream& STRG, CResourceEntry* pEntry);
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->mWidth = mWidth;
pTex->mHeight = mHeight;
@ -91,7 +91,7 @@ CTexture* CTextureDecoder::CreateTexture()
}
// ************ STATIC ************
CTexture* CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry)
std::unique_ptr<CTexture> CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry)
{
CTextureDecoder Decoder;
Decoder.mpEntry = pEntry;
@ -100,19 +100,19 @@ CTexture* CTextureDecoder::LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry)
return Decoder.CreateTexture();
}
CTexture* CTextureDecoder::DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry)
std::unique_ptr<CTexture> CTextureDecoder::DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry)
{
CTextureDecoder Decoder;
Decoder.mpEntry = pEntry;
Decoder.ReadTXTR(rTXTR);
Decoder.FullDecodeGXTexture(rTXTR);
CTexture *pTexture = Decoder.CreateTexture();
auto pTexture = Decoder.CreateTexture();
pTexture->mTexelFormat = ETexelFormat::RGBA8;
return pTexture;
}
CTexture* CTextureDecoder::LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry)
std::unique_ptr<CTexture> CTextureDecoder::LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry)
{
CTextureDecoder Decoder;
Decoder.mpEntry = pEntry;

View File

@ -5,9 +5,10 @@
#include "Core/Resource/ETexelFormat.h"
#include <Common/BasicTypes.h>
#include <Common/CColor.h>
#include <Common/FileIO.h>
#include <memory>
class CTextureDecoder
{
CResourceEntry *mpEntry;
@ -36,7 +37,7 @@ class CTextureDecoder
// Private Functions
CTextureDecoder();
~CTextureDecoder();
CTexture* CreateTexture();
std::unique_ptr<CTexture> CreateTexture();
// Read
void ReadTXTR(IInputStream& rTXTR);
@ -78,9 +79,9 @@ class CTextureDecoder
// Static
public:
static CTexture* LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry);
static CTexture* LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry);
static CTexture* DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry);
static std::unique_ptr<CTexture> LoadTXTR(IInputStream& rTXTR, CResourceEntry *pEntry);
static std::unique_ptr<CTexture> LoadDDS(IInputStream& rDDS, CResourceEntry *pEntry);
static std::unique_ptr<CTexture> DoFullDecode(IInputStream& rTXTR, CResourceEntry *pEntry);
static CTexture* DoFullDecode(CTexture *pTexture);
// 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();
ASSERT(Magic == FOURCC('CAUD'));
@ -50,7 +50,7 @@ CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEn
EGame::Invalid);
ASSERT(Game != EGame::Invalid && Game == pEntry->Game());
CAudioMacro *pMacro = new CAudioMacro(pEntry);
auto pMacro = std::make_unique<CAudioMacro>(pEntry);
pMacro->mMacroName = rCAUD.ReadString();
// 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;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry)
{
uint32 Magic = rCSNG.ReadLong();
ASSERT(Magic == 0x2);
rCSNG.Seek(0x8, SEEK_CUR);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
pGroup->AddDependency(rCSNG.ReadLong());
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
if (rDUMB.PeekLong() == FOURCC('HIER'))
return LoadHIER(rDUMB, pEntry);
// 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;
PerformCheating(rDUMB, pEntry->Game(), DepList);
for (auto Iter = DepList.begin(); Iter != DepList.end(); Iter++)
pGroup->AddDependency(*Iter);
for (const auto& dep : DepList)
pGroup->AddDependency(dep);
return pGroup;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry)
{
uint32 Version = rFRME.ReadLong();
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
// Prime 1
if (Version == 0 || Version == 1)
@ -232,7 +232,6 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResou
rFRME.Seek(0x42, SEEK_CUR);
}
}
// 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)
{
@ -249,23 +248,21 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResou
pGroup->AddDependency( CAssetID(rFRME, Game) );
}
}
else
{
errorf("Unrecognized FRME version: %d", Version);
delete pGroup;
return nullptr;
}
return pGroup;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry)
{
uint32 Magic = rFSM2.ReadLong();
ASSERT(Magic == FOURCC('FSM2'));
CDependencyGroup *pOut = new CDependencyGroup(pEntry);
auto pOut = std::make_unique<CDependencyGroup>(pEntry);
uint32 Version = rFSM2.ReadLong();
uint32 NumStates = rFSM2.ReadLong();
uint32 NumUnkA = rFSM2.ReadLong();
@ -333,29 +330,29 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
return pOut;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry)
{
CFourCC Magic = rFSMC.ReadLong();
ASSERT(Magic == FOURCC('FSMC'));
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
std::list<CAssetID> AssetList;
PerformCheating(rFSMC, pEntry->Game(), AssetList);
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++)
pGroup->AddDependency(*Iter);
for (const auto& asset : AssetList)
pGroup->AddDependency(asset);
return pGroup;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry)
{
CFourCC Magic = rHIER.ReadLong();
ASSERT(Magic == "HIER");
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.
// 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;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry)
{
uint32 Magic = rHINT.ReadLong();
ASSERT(Magic == 0x00BADBAD);
@ -392,7 +389,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
}
// Read main file
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
uint32 NumHints = rHINT.ReadLong();
for (uint32 iHint = 0; iHint < NumHints; iHint++)
@ -427,9 +424,10 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
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.
CAssetID MapAreaID = pMap->ID();
@ -474,10 +472,10 @@ CMapArea* CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMAPA*/, CResourceE
}
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();
ASSERT(Magic == 0xDEADF00D);
@ -494,7 +492,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResou
rMAPW.Seek(AreasStart, SEEK_SET);
// Read MAPA IDs
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
for (uint32 iArea = 0; iArea < NumAreas; iArea++)
pGroup->AddDependency(CAssetID(rMAPW, IDLength));
@ -502,7 +500,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResou
return pGroup;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry)
{
uint32 Magic = rMAPU.ReadLong();
ASSERT(Magic == 0xABCDEF01);
@ -510,7 +508,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResou
uint32 Version = rMAPU.ReadLong();
ASSERT(Version == 0x1);
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
pGroup->AddDependency(rMAPU.ReadLong());
// Read worlds
@ -529,13 +527,13 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResou
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.
const uint32 Magic = rRULE.ReadLong();
ASSERT(Magic == FOURCC('RULE'));
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
auto pGroup = std::make_unique<CDependencyGroup>(pEntry);
rRULE.Seek(0x1, SEEK_CUR);
// Version test

View File

@ -4,29 +4,30 @@
#include "Core/Resource/CAudioMacro.h"
#include "Core/Resource/CDependencyGroup.h"
#include "Core/Resource/CMapArea.h"
#include <list>
#include <memory>
// 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.
class CUnsupportedFormatLoader
{
CDependencyGroup *mpGroup = nullptr;
CUnsupportedFormatLoader() = default;
static void PerformCheating(IInputStream& rFile, EGame Game, std::list<CAssetID>& rAssetList);
public:
static CAudioMacro* LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry);
static CDependencyGroup* LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry);
static CDependencyGroup* LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry);
static CDependencyGroup* LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry);
static CDependencyGroup* LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry);
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
static CMapArea* LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry);
static CDependencyGroup* LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
static CDependencyGroup* LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
static CDependencyGroup* LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry);
static std::unique_ptr<CAudioMacro> LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
static std::unique_ptr<CMapArea> LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry);
};
#endif // CUNSUPPORTEDFORMATLOADER_H

View File

@ -1763,10 +1763,10 @@ void CUnsupportedParticleLoader::ParseKeyframeEmitterData(IInputStream& rFile, c
}
// ************ STATIC ************
CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry)
std::unique_ptr<CDependencyGroup> CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry)
{
CUnsupportedParticleLoader Loader;
Loader.mpGroup = new CDependencyGroup(pEntry);
Loader.mpGroup = std::make_unique<CDependencyGroup>(pEntry);
// Validate DKCR asset header
if (pEntry->Game() == EGame::DKCReturns)
@ -1776,7 +1776,7 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile,
if (AssetHeader != 0x6E190001)
{
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;
}
return Loader.mpGroup;
return std::move(Loader.mpGroup);
}

View File

@ -2,12 +2,13 @@
#define CUNSUPPORTEDPARTICLELOADER_H
#include "Core/Resource/CDependencyGroup.h"
#include <memory>
// 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.
class CUnsupportedParticleLoader
{
CDependencyGroup *mpGroup = nullptr;
std::unique_ptr<CDependencyGroup> mpGroup;
CUnsupportedParticleLoader() = default;
// Format-Specific Parameter Loading
@ -41,7 +42,7 @@ class CUnsupportedParticleLoader
void ParseKeyframeEmitterData(IInputStream& rFile, const CFourCC& rkFunc, uint32 ElemSize);
public:
static CDependencyGroup* LoadParticle(IInputStream& rPART, CResourceEntry *pEntry);
static std::unique_ptr<CDependencyGroup> LoadParticle(IInputStream& rPART, CResourceEntry *pEntry);
};
#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;
@ -296,8 +296,10 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
}
// Filestream is valid, magic+version are valid; everything seems good!
auto ptr = std::make_unique<CWorld>(pEntry);
CWorldLoader Loader;
Loader.mpWorld = new CWorld(pEntry);
Loader.mpWorld = ptr.get();
Loader.mVersion = Version;
if (Version != EGame::DKCReturns)
@ -306,7 +308,7 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
Loader.LoadReturnsMLVL(rMLVL);
Loader.GenerateEditorData();
return Loader.mpWorld;
return ptr;
}
EGame CWorldLoader::GetFormatVersion(uint32 Version)

View File

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

View File

@ -2,7 +2,7 @@
#include "Core/Resource/Factory/CScriptLoader.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.
static const std::unordered_map<uint, const char*> skIdToTemplateName =
@ -24,26 +24,25 @@ CTweakData* CTweakLoader::LoadCTWK(IInputStream& CTWK, CResourceEntry* pEntry)
{ 0xF1ED8FD7, "TweakPlayerControls", }
};
auto Find = skIdToTemplateName.find( pEntry->ID().ToLong() );
ASSERT( Find != skIdToTemplateName.end() );
auto Find = skIdToTemplateName.find(pEntry->ID().ToLong());
ASSERT(Find != skIdToTemplateName.end());
const char* pkTemplateName = Find->second;
// Fetch template
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate( pEntry->Game() );
ASSERT( pGameTemplate != nullptr );
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate(pEntry->Game());
ASSERT(pGameTemplate != nullptr);
CScriptTemplate* pTweakTemplate = pGameTemplate->FindMiscTemplate(pkTemplateName);
ASSERT( pTweakTemplate != nullptr );
ASSERT(pTweakTemplate != nullptr);
// Load tweak data
CTweakData* pTweakData = new CTweakData(pTweakTemplate, pEntry->ID().ToLong(), pEntry);
CScriptLoader::LoadStructData( CTWK, pTweakData->TweakData() );
auto pTweakData = std::make_unique<CTweakData>(pTweakTemplate, pEntry->ID().ToLong(), pEntry);
CScriptLoader::LoadStructData(CTWK, pTweakData->TweakData());
// Verify
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());
delete pTweakData;
return nullptr;
}

View File

@ -2,6 +2,7 @@
#define CTWEAKLOADER_H
#include "CTweakData.h"
#include <memory>
/** Class responsible for loading tweak data */
class CTweakLoader
@ -11,7 +12,7 @@ class CTweakLoader
public:
/** 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);
};

View File

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

View File

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

View File

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