2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-06-27 23:01:55 +00:00

Add AssetLoader basis

This commit is contained in:
Jan
2021-03-13 14:27:20 +01:00
parent 83080db991
commit a7860c7c76
34 changed files with 736 additions and 149 deletions

View File

@ -0,0 +1,45 @@
#include "AssetLoadingContext.h"
AssetLoadingContext::AssetLoadingContext(Zone* zone, ISearchPath* rawSearchPath, std::vector<Gdt*> gdtFiles)
: m_zone(zone),
m_raw_search_path(rawSearchPath),
m_gdt_files(std::move(gdtFiles))
{
BuildGdtEntryCache();
}
void AssetLoadingContext::BuildGdtEntryCache()
{
for(auto* gdt : m_gdt_files)
{
for(const auto& entry : gdt->m_entries)
{
auto gdfMapEntry = m_entries_by_gdf_and_by_name.find(entry->m_gdf_name);
if(gdfMapEntry == m_entries_by_gdf_and_by_name.end())
{
std::unordered_map<std::string, GdtEntry*> entryMap;
entryMap.emplace(std::make_pair(entry->m_name, entry.get()));
m_entries_by_gdf_and_by_name.emplace(std::make_pair(entry->m_gdf_name, std::move(entryMap)));
}
else
{
gdfMapEntry->second.emplace(std::make_pair(entry->m_name, entry.get()));
}
}
}
}
GdtEntry* AssetLoadingContext::GetGdtEntryByGdfAndName(const std::string& gdfName, const std::string& entryName)
{
const auto foundGdtMap = m_entries_by_gdf_and_by_name.find(gdfName);
if (foundGdtMap == m_entries_by_gdf_and_by_name.end())
return nullptr;
const auto foundGdtEntry = foundGdtMap->second.find(entryName);
if (foundGdtEntry == foundGdtMap->second.end())
return nullptr;
return foundGdtEntry->second;
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <unordered_map>
#include "IGdtQueryable.h"
#include "Obj/Gdt/Gdt.h"
#include "SearchPath/ISearchPath.h"
#include "Zone/Zone.h"
class AssetLoadingContext final : public IGdtQueryable
{
std::unordered_map<std::string, std::unordered_map<std::string, GdtEntry*>> m_entries_by_gdf_and_by_name;
void BuildGdtEntryCache();
public:
Zone* const m_zone;
ISearchPath* const m_raw_search_path;
const std::vector<Gdt*> m_gdt_files;
AssetLoadingContext(Zone* zone, ISearchPath* rawSearchPath, std::vector<Gdt*> gdtFiles);
GdtEntry* GetGdtEntryByGdfAndName(const std::string& gdfName, const std::string& entryName) override;
};

View File

@ -0,0 +1,69 @@
#include "AssetLoadingManager.h"
#include <iostream>
AssetLoadingManager::AssetLoadingManager(const std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>>& assetLoadersByType, AssetLoadingContext& context):
m_asset_loaders_by_type(assetLoadersByType),
m_context(context),
m_last_dependency_loaded(nullptr)
{
}
bool AssetLoadingManager::LoadAssetFromLoader(const asset_type_t assetType, const std::string& assetName)
{
return LoadDependency(assetType, assetName) != nullptr;
}
void AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset, std::vector<XAssetInfoGeneric*>& dependencies)
{
m_last_dependency_loaded = m_context.m_zone->m_pools->AddAsset(assetType, assetName, asset, dependencies);
if (m_last_dependency_loaded == nullptr)
std::cout << "Failed to add asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\" to pool: \"" << assetName << "\"" << std::endl;
}
XAssetInfoGeneric* AssetLoadingManager::LoadDependency(const asset_type_t assetType, const std::string& assetName)
{
const auto loader = m_asset_loaders_by_type.find(assetType);
if (loader != m_asset_loaders_by_type.end())
{
if (loader->second->CanLoadFromGdt() && loader->second->LoadFromGdt(assetName, &m_context, m_context.m_zone->GetMemory(), this))
{
auto* lastDependency = m_last_dependency_loaded;
m_last_dependency_loaded = nullptr;
return lastDependency;
}
if (loader->second->CanLoadFromRaw() && loader->second->LoadFromRaw(assetName, m_context.m_raw_search_path, m_context.m_zone->GetMemory(), this))
{
auto* lastDependency = m_last_dependency_loaded;
m_last_dependency_loaded = nullptr;
return lastDependency;
}
auto* existingAsset = loader->second->LoadFromGlobalAssetPools(assetName);
if(existingAsset)
{
std::vector<XAssetInfoGeneric*> dependencies;
for (const auto* dependency : existingAsset->m_dependencies)
{
auto* newDependency = LoadDependency(dependency->m_type, dependency->m_name);
if (newDependency)
dependencies.push_back(newDependency);
else
return nullptr;
}
AddAsset(existingAsset->m_type, existingAsset->m_name, existingAsset->m_ptr, dependencies);
auto* lastDependency = m_last_dependency_loaded;
m_last_dependency_loaded = nullptr;
return lastDependency;
}
std::cout << "Failed to load asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\": \"" << assetName << "\"" << std::endl;
}
else
{
std::cout << "Failed to find loader for asset type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\"" << std::endl;
}
return nullptr;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <unordered_map>
#include "AssetLoadingContext.h"
#include "IAssetLoader.h"
#include "IAssetLoadingManager.h"
class AssetLoadingManager final : public IAssetLoadingManager
{
const std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>>& m_asset_loaders_by_type;
AssetLoadingContext& m_context;
XAssetInfoGeneric* m_last_dependency_loaded;
public:
AssetLoadingManager(const std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>>& assetLoadersByType, AssetLoadingContext& context);
bool LoadAssetFromLoader(asset_type_t assetType, const std::string& assetName);
void AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector<XAssetInfoGeneric*>& dependencies) override;
XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) override;
};

View File

@ -0,0 +1,18 @@
#pragma once
#include "IAssetLoader.h"
#include "Pool/GlobalAssetPool.h"
template<asset_type_t AssetType, typename T>
class BasicAssetLoader : public IAssetLoader
{
public:
_NODISCARD asset_type_t GetHandlingAssetType() const override
{
return AssetType;
}
_NODISCARD XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const override
{
return GlobalAssetPool<T>::GetAssetByName(assetName);
}
};

View File

@ -0,0 +1,42 @@
#pragma once
#include <string>
#include "Utils/ClassUtils.h"
#include "SearchPath/ISearchPath.h"
#include "IAssetLoadingManager.h"
#include "IGdtQueryable.h"
#include "Zone/ZoneTypes.h"
class IAssetLoader
{
public:
IAssetLoader() = default;
virtual ~IAssetLoader() = default;
IAssetLoader(const IAssetLoader& other) = default;
IAssetLoader(IAssetLoader&& other) noexcept = default;
IAssetLoader& operator=(const IAssetLoader& other) = default;
IAssetLoader& operator=(IAssetLoader&& other) noexcept = default;
_NODISCARD virtual asset_type_t GetHandlingAssetType() const = 0;
_NODISCARD virtual XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const = 0;
_NODISCARD virtual bool CanLoadFromGdt() const
{
return false;
}
_NODISCARD virtual bool CanLoadFromRaw() const
{
return false;
}
virtual bool LoadFromGdt(const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager) const
{
return false;
}
virtual bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const
{
return false;
}
};

View File

@ -0,0 +1,24 @@
#pragma once
#include <string>
#include "Pool/XAssetInfo.h"
#include "Zone/ZoneTypes.h"
class IAssetLoadingManager
{
public:
IAssetLoadingManager() = default;
virtual ~IAssetLoadingManager() = default;
IAssetLoadingManager(const IAssetLoadingManager& other) = default;
IAssetLoadingManager(IAssetLoadingManager&& other) noexcept = default;
IAssetLoadingManager& operator=(const IAssetLoadingManager& other) = default;
IAssetLoadingManager& operator=(IAssetLoadingManager&& other) noexcept = default;
virtual void AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector<XAssetInfoGeneric*>& dependencies) = 0;
void AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset)
{
std::vector<XAssetInfoGeneric*> dependencies;
AddAsset(assetType, assetName, asset, dependencies);
}
virtual XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) = 0;
};

View File

@ -0,0 +1,17 @@
#pragma once
#include <string>
#include "Obj/Gdt/GdtEntry.h"
class IGdtQueryable
{
public:
IGdtQueryable() = default;
virtual ~IGdtQueryable() = default;
IGdtQueryable(const IGdtQueryable& other) = default;
IGdtQueryable(IGdtQueryable&& other) noexcept = default;
IGdtQueryable& operator=(const IGdtQueryable& other) = default;
IGdtQueryable& operator=(IGdtQueryable&& other) noexcept = default;
virtual GdtEntry* GetGdtEntryByGdfAndName(const std::string& gdfName, const std::string& entryName) = 0;
};

View File

@ -0,0 +1,32 @@
#include "AssetLoaderRawFile.h"
#include "Game/IW4/IW4.h"
#include "Pool/GlobalAssetPool.h"
using namespace IW4;
bool AssetLoaderRawFile::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const
{
const auto file = searchPath->Open(assetName);
if (!file.IsOpen())
return false;
auto* rawFile = memory->Create<RawFile>();
rawFile->name = memory->Dup(assetName.c_str());
rawFile->len = static_cast<int>(file.m_length);
auto* fileBuffer = static_cast<char*>(memory->Alloc(static_cast<size_t>(file.m_length + 1)));
file.m_stream->read(fileBuffer, file.m_length);
if (file.m_stream->gcount() != file.m_length)
return false;
rawFile->data.buffer = fileBuffer;
manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile);
return true;
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Game/IW4/IW4.h"
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "SearchPath/ISearchPath.h"
namespace IW4
{
class AssetLoaderRawFile final : public BasicAssetLoader<ASSET_TYPE_RAWFILE, RawFile>
{
public:
_NODISCARD bool CanLoadFromRaw() const override;
bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override;
};
}

View File

@ -3,106 +3,160 @@
#include "Game/IW4/GameAssetPoolIW4.h"
#include "ObjContainer/IPak/IPak.h"
#include "ObjLoading.h"
#include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoading/AssetLoadingManager.h"
#include "Image/Texture.h"
#include "Image/IwiLoader.h"
namespace IW4
using namespace IW4;
ObjLoader::ObjLoader()
{
bool ObjLoader::SupportsZone(Zone* zone) const
#define REGISTER_ASSET_LOADER(t) {auto l = std::make_unique<t>(); m_asset_loaders_by_type[l->GetHandlingAssetType()] = std::move(l);}
#define BASIC_LOADER(assetType, assetClass) BasicAssetLoader<assetType, assetClass>
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSPRESET, PhysPreset))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XANIMPARTS, XAnimParts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL_SURFS, XModelSurfs))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL, XModel))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MATERIAL, Material))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PIXELSHADER, MaterialPixelShader))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMAGE, GfxImage))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND, snd_alias_list_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND_CURVE, SndCurve))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOADED_SOUND, LoadedSound))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_SP, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_MP, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_COMWORLD, ComWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_SP, GameWorldSp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_MP, GameWorldMp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MAP_ENTS, MapEnts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FXWORLD, FxWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GFXWORLD, GfxWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LIGHT_DEF, GfxLightDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRINGTABLE, StringTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TRACER, TracerDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLE, VehicleDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts))
#undef BASIC_LOADER
#undef REGISTER_ASSET_LOADER
}
bool ObjLoader::SupportsZone(Zone* zone) const
{
return zone->m_game == &g_GameIW4;
}
bool ObjLoader::IsMpZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "mp_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_mp") == 0;
}
bool ObjLoader::IsZmZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "zm_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_zm") == 0;
}
void ObjLoader::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const
{
}
void ObjLoader::UnloadContainersOfZone(Zone* zone) const
{
}
void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone)
{
// TODO: Load Texture from LoadDef here
}
void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone)
{
Texture* loadedTexture = nullptr;
IwiLoader loader(zone->GetMemory());
const auto imageFileName = "images/" + std::string(image->name) + ".iwi";
{
return zone->m_game == &g_GameIW4;
}
bool ObjLoader::IsMpZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "mp_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_mp") == 0;
}
bool ObjLoader::IsZmZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "zm_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_zm") == 0;
}
void ObjLoader::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const
{
}
void ObjLoader::UnloadContainersOfZone(Zone* zone) const
{
}
void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone)
{
// TODO: Load Texture from LoadDef here
}
void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone)
{
Texture* loadedTexture = nullptr;
IwiLoader loader(zone->GetMemory());
const auto imageFileName = "images/" + std::string(image->name) + ".iwi";
const auto filePathImage = searchPath->Open(imageFileName);
if (filePathImage.IsOpen())
{
const auto filePathImage = searchPath->Open(imageFileName);
if (filePathImage.IsOpen())
{
loadedTexture = loader.LoadIwi(*filePathImage.m_stream);
}
}
if (loadedTexture != nullptr)
{
image->texture.texture = loadedTexture;
image->cardMemory.platform[0] = 0;
const auto textureMipCount = loadedTexture->GetMipMapCount();
for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++)
image->cardMemory.platform[0] += static_cast<int>(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount());
}
else
{
printf("Could not find data for image \"%s\"\n", image->name);
loadedTexture = loader.LoadIwi(*filePathImage.m_stream);
}
}
void ObjLoader::LoadImageData(ISearchPath* searchPath, Zone* zone)
if (loadedTexture != nullptr)
{
auto* assetPool = dynamic_cast<GameAssetPoolIW4*>(zone->m_pools.get());
image->texture.texture = loadedTexture;
image->cardMemory.platform[0] = 0;
if (assetPool && assetPool->m_image != nullptr)
{
for (auto* imageEntry : *assetPool->m_image)
{
auto* image = imageEntry->Asset();
if (image->cardMemory.platform[0] > 0)
{
continue;
}
// Do not load linked assets
if (image->name && image->name[0] == ',')
{
continue;
}
if (image->texture.loadDef && image->texture.loadDef->resourceSize > 0)
{
LoadImageFromLoadDef(image, zone);
}
else
{
LoadImageFromIwi(image, searchPath, zone);
}
}
}
const auto textureMipCount = loadedTexture->GetMipMapCount();
for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++)
image->cardMemory.platform[0] += static_cast<int>(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount());
}
void ObjLoader::LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const
else
{
LoadImageData(searchPath, zone);
printf("Could not find data for image \"%s\"\n", image->name);
}
}
void ObjLoader::LoadImageData(ISearchPath* searchPath, Zone* zone)
{
auto* assetPool = dynamic_cast<GameAssetPoolIW4*>(zone->m_pools.get());
if (assetPool && assetPool->m_image != nullptr)
{
for (auto* imageEntry : *assetPool->m_image)
{
auto* image = imageEntry->Asset();
if (image->cardMemory.platform[0] > 0)
{
continue;
}
// Do not load linked assets
if (image->name && image->name[0] == ',')
{
continue;
}
if (image->texture.loadDef && image->texture.loadDef->resourceSize > 0)
{
LoadImageFromLoadDef(image, zone);
}
else
{
LoadImageFromIwi(image, searchPath, zone);
}
}
}
}
void ObjLoader::LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const
{
LoadImageData(searchPath, zone);
}
bool ObjLoader::LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const
{
AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, *context);
return assetLoadingManager.LoadAssetFromLoader(assetType, assetName);
}

View File

@ -1,6 +1,10 @@
#pragma once
#include <unordered_map>
#include <memory>
#include "IObjLoader.h"
#include "AssetLoading/IAssetLoader.h"
#include "SearchPath/ISearchPath.h"
#include "Game/IW4/IW4.h"
@ -8,6 +12,8 @@ namespace IW4
{
class ObjLoader final : public IObjLoader
{
std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>> m_asset_loaders_by_type;
static void LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone);
static void LoadImageFromLoadDef(GfxImage* image, Zone* zone);
static void LoadImageData(ISearchPath* searchPath, Zone* zone);
@ -16,11 +22,15 @@ namespace IW4
static bool IsZmZone(Zone* zone);
public:
ObjLoader();
bool SupportsZone(Zone* zone) const override;
void LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const override;
void UnloadContainersOfZone(Zone* zone) const override;
void LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const override;
bool LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const override;
};
}

View File

@ -0,0 +1,32 @@
#include "AssetLoaderRawFile.h"
#include "Game/T6/T6.h"
#include "Pool/GlobalAssetPool.h"
using namespace T6;
bool AssetLoaderRawFile::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const
{
const auto file = searchPath->Open(assetName);
if (!file.IsOpen())
return false;
auto* rawFile = memory->Create<RawFile>();
rawFile->name = memory->Dup(assetName.c_str());
rawFile->len = static_cast<int>(file.m_length);
auto* fileBuffer = static_cast<char*>(memory->Alloc(static_cast<size_t>(file.m_length + 1)));
file.m_stream->read(fileBuffer, file.m_length);
if (file.m_stream->gcount() != file.m_length)
return false;
rawFile->buffer = static_cast<char16*>(fileBuffer);
manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile);
return true;
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Game/T6/T6.h"
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "SearchPath/ISearchPath.h"
namespace T6
{
class AssetLoaderRawFile final : public BasicAssetLoader<ASSET_TYPE_RAWFILE, RawFile>
{
public:
_NODISCARD bool CanLoadFromRaw() const override;
bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override;
};
}

View File

@ -4,6 +4,8 @@
#include "Game/T6/GameAssetPoolT6.h"
#include "ObjContainer/IPak/IPak.h"
#include "ObjLoading.h"
#include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoading/AssetLoadingManager.h"
#include "Image/Texture.h"
#include "Image/IwiLoader.h"
#include "Game/T6/CommonT6.h"
@ -13,6 +15,64 @@ namespace T6
const int ObjLoader::IPAK_READ_HASH = CommonT6::Com_HashKey("ipak_read", 64);
const int ObjLoader::GLOBAL_HASH = CommonT6::Com_HashKey("GLOBAL", 64);
ObjLoader::ObjLoader()
{
#define REGISTER_ASSET_LOADER(t) {auto l = std::make_unique<t>(); m_asset_loaders_by_type[l->GetHandlingAssetType()] = std::move(l);}
#define BASIC_LOADER(assetType, assetClass) BasicAssetLoader<assetType, assetClass>
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSPRESET, PhysPreset))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XANIMPARTS, XAnimParts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL, XModel))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MATERIAL, Material))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMAGE, GfxImage))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND, SndBank))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND_PATCH, SndPatch))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_PVS, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_COMWORLD, ComWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_SP, GameWorldSp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_MP, GameWorldMp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MAP_ENTS, MapEnts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GFXWORLD, GfxWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LIGHT_DEF, GfxLightDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONTICON, FontIcon))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponVariantDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT, WeaponAttachment))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT_UNIQUE, WeaponAttachmentUnique))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON_CAMO, WeaponCamo))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRINGTABLE, StringTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XGLOBALS, XGlobals))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_DDL, ddlDef_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GLASSES, Glasses))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_EMBLEMSET, EmblemSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SCRIPTPARSETREE, ScriptParseTree))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLEDEF, VehicleDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MEMORYBLOCK, MemoryBlock))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TRACER, TracerDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SKINNEDVERTS, SkinnedVertsDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_QDB, Qdb))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SLUG, Slug))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FOOTSTEP_TABLE, FootstepTableDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FOOTSTEPFX_TABLE, FootstepFXTableDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ZBARRIER, ZBarrierDef))
#undef BASIC_LOADER
#undef REGISTER_ASSET_LOADER
}
bool ObjLoader::SupportsZone(Zone* zone) const
{
return zone->m_game == &g_GameT6;
@ -227,4 +287,10 @@ namespace T6
{
LoadImageData(searchPath, zone);
}
bool ObjLoader::LoadAssetForZone(AssetLoadingContext* context, const asset_type_t assetType, const std::string& assetName) const
{
AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, *context);
return assetLoadingManager.LoadAssetFromLoader(assetType, assetName);
}
}

View File

@ -1,6 +1,10 @@
#pragma once
#include <unordered_map>
#include <memory>
#include "IObjLoader.h"
#include "AssetLoading/IAssetLoader.h"
#include "SearchPath/ISearchPath.h"
#include "Game/T6/T6.h"
@ -11,6 +15,8 @@ namespace T6
static const int IPAK_READ_HASH;
static const int GLOBAL_HASH;
std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>> m_asset_loaders_by_type;
static void LoadIPakForZone(ISearchPath* searchPath, const std::string& ipakName, Zone* zone);
static void LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone);
@ -22,11 +28,15 @@ namespace T6
static void LoadCommonIPaks(ISearchPath* searchPath, Zone* zone);
public:
ObjLoader();
bool SupportsZone(Zone* zone) const override;
void LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const override;
void UnloadContainersOfZone(Zone* zone) const override;
void LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const override;
bool LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const override;
};
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "AssetLoading/AssetLoadingContext.h"
#include "SearchPath/ISearchPath.h"
#include "Zone/Zone.h"
@ -34,4 +35,6 @@ public:
* \param zone The zone of the assets to load the obj data for.
*/
virtual void LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const = 0;
virtual bool LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const = 0;
};

View File

@ -87,3 +87,16 @@ SearchPaths ObjLoading::GetIWDSearchPaths()
return iwdPaths;
}
bool ObjLoading::LoadAssetForZone(AssetLoadingContext* context, const asset_type_t assetType, const std::string& assetName)
{
for (const auto* loader : OBJ_LOADERS)
{
if (loader->SupportsZone(context->m_zone))
{
return loader->LoadAssetForZone(context, assetType, assetName);
}
}
return false;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "AssetLoading/AssetLoadingContext.h"
#include "Zone/Zone.h"
#include "SearchPath/ISearchPath.h"
#include "SearchPath/SearchPaths.h"
@ -50,4 +51,6 @@ public:
* \param zone The zone of the assets to load the obj data for.
*/
static void LoadObjDataForZone(ISearchPath* searchPath, Zone* zone);
static bool LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName);
};