mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
chore: fix loading and writing code for IW5
This commit is contained in:
parent
9ae5aaa1db
commit
a36581b06e
@ -61,7 +61,7 @@ public:
|
||||
{
|
||||
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
|
||||
|
||||
return LoadIndirectAssetReferenceInternal(AssetType::EnumEntry, assetName);
|
||||
return LoadIndirectAssetReferenceGeneric(AssetType::EnumEntry, assetName);
|
||||
}
|
||||
|
||||
IndirectAssetReference LoadIndirectAssetReferenceGeneric(asset_type_t assetType, const std::string& assetName);
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include "AssetCreationResult.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
AssetCreationResult AssetCreationResult::Success(XAssetInfoGeneric* assetInfo)
|
||||
{
|
||||
assert(assetInfo);
|
||||
return AssetCreationResult(true, assetInfo);
|
||||
}
|
||||
|
||||
|
@ -1,176 +0,0 @@
|
||||
#include "AssetLoadingManager.h"
|
||||
|
||||
#include "Utils/StringUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
#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;
|
||||
}
|
||||
|
||||
AssetLoadingContext* AssetLoadingManager::GetAssetLoadingContext() const
|
||||
{
|
||||
return &m_context;
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoadingManager::AddAssetInternal(std::unique_ptr<XAssetInfoGeneric> xAssetInfo)
|
||||
{
|
||||
const auto assetType = xAssetInfo->m_type;
|
||||
const auto* pAssetName = xAssetInfo->m_name.c_str();
|
||||
|
||||
m_last_dependency_loaded = m_context.m_zone.m_pools->AddAsset(std::move(xAssetInfo));
|
||||
if (m_last_dependency_loaded == nullptr)
|
||||
std::cerr << std::format("Failed to add asset of type \"{}\" to pool: \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType), pAssetName);
|
||||
|
||||
return m_last_dependency_loaded;
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoadingManager::AddAsset(std::unique_ptr<XAssetInfoGeneric> xAssetInfo)
|
||||
{
|
||||
xAssetInfo->m_zone = &m_context.m_zone;
|
||||
return AddAssetInternal(std::move(xAssetInfo));
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoadingManager::LoadIgnoredDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader)
|
||||
{
|
||||
auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
|
||||
if (alreadyLoadedAsset)
|
||||
return alreadyLoadedAsset;
|
||||
|
||||
auto* linkAsset = loader->CreateEmptyAsset(assetName, m_context.m_zone.GetMemory());
|
||||
if (linkAsset)
|
||||
{
|
||||
AddAsset(std::make_unique<XAssetInfoGeneric>(assetType, assetName, linkAsset));
|
||||
auto* lastDependency = m_last_dependency_loaded;
|
||||
m_last_dependency_loaded = nullptr;
|
||||
return lastDependency;
|
||||
}
|
||||
|
||||
auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName);
|
||||
if (existingAsset)
|
||||
{
|
||||
AddAssetInternal(std::make_unique<XAssetInfoGeneric>(*existingAsset));
|
||||
auto* lastDependency = m_last_dependency_loaded;
|
||||
m_last_dependency_loaded = nullptr;
|
||||
return lastDependency;
|
||||
}
|
||||
|
||||
std::cerr << std::format("Failed to create empty asset \"{}\" for type \"{}\"\n", assetName, *m_context.m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoadingManager::LoadAssetDependency(const asset_type_t assetType, const std::string& assetName, const IAssetLoader* loader)
|
||||
{
|
||||
if (loader->CanLoadFromGdt() && !m_context.m_gdt_files.empty()
|
||||
&& loader->LoadFromGdt(assetName, &m_context, m_context.m_zone.GetMemory(), this, &m_context.m_zone))
|
||||
{
|
||||
auto* lastDependency = m_last_dependency_loaded;
|
||||
m_last_dependency_loaded = nullptr;
|
||||
return lastDependency;
|
||||
}
|
||||
|
||||
if (loader->CanLoadFromRaw() && loader->LoadFromRaw(assetName, &m_context.m_raw_search_path, m_context.m_zone.GetMemory(), this, &m_context.m_zone))
|
||||
{
|
||||
auto* lastDependency = m_last_dependency_loaded;
|
||||
m_last_dependency_loaded = nullptr;
|
||||
return lastDependency;
|
||||
}
|
||||
|
||||
auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName);
|
||||
if (!existingAsset && !assetName.empty() && assetName[0] != ',')
|
||||
existingAsset = loader->LoadFromGlobalAssetPools(',' + assetName);
|
||||
|
||||
if (existingAsset)
|
||||
{
|
||||
std::vector<XAssetInfoGeneric*> dependencies;
|
||||
std::vector<IndirectAssetReference> indirectAssetReferences;
|
||||
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;
|
||||
}
|
||||
|
||||
indirectAssetReferences.reserve(existingAsset->m_indirect_asset_references.size());
|
||||
for (const auto& indirectAssetReference : existingAsset->m_indirect_asset_references)
|
||||
indirectAssetReferences.emplace_back(LoadIndirectAssetReference(indirectAssetReference.m_type, indirectAssetReference.m_name));
|
||||
|
||||
// Make sure any used script string is available in the created zone
|
||||
// The replacement of the scr_string_t values will be done upon writing
|
||||
for (const auto scrString : existingAsset->m_used_script_strings)
|
||||
m_context.m_zone.m_script_strings.AddOrGetScriptString(existingAsset->m_zone->m_script_strings.CValue(scrString));
|
||||
|
||||
AddAssetInternal(std::make_unique<XAssetInfoGeneric>(existingAsset->m_type,
|
||||
existingAsset->m_name,
|
||||
existingAsset->m_ptr,
|
||||
std::move(dependencies),
|
||||
existingAsset->m_used_script_strings,
|
||||
std::move(indirectAssetReferences),
|
||||
existingAsset->m_zone));
|
||||
|
||||
auto* lastDependency = m_last_dependency_loaded;
|
||||
m_last_dependency_loaded = nullptr;
|
||||
return lastDependency;
|
||||
}
|
||||
|
||||
std::cerr << std::format("Failed to load asset of type \"{}\": \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType), assetName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* AssetLoadingManager::LoadDependency(const asset_type_t assetType, const std::string& assetName)
|
||||
{
|
||||
auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
|
||||
if (alreadyLoadedAsset)
|
||||
return alreadyLoadedAsset;
|
||||
|
||||
const auto loader = m_asset_loaders_by_type.find(assetType);
|
||||
if (loader != m_asset_loaders_by_type.end())
|
||||
{
|
||||
const auto ignoreEntry = m_context.m_ignored_asset_map.find(assetName);
|
||||
if (ignoreEntry != m_context.m_ignored_asset_map.end() && ignoreEntry->second == assetType)
|
||||
{
|
||||
const auto linkAssetName = std::format(",{}", assetName);
|
||||
|
||||
return LoadIgnoredDependency(assetType, linkAssetName, loader->second.get());
|
||||
}
|
||||
|
||||
return LoadAssetDependency(assetType, assetName, loader->second.get());
|
||||
}
|
||||
|
||||
std::cerr << std::format("Failed to find loader for asset type \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IndirectAssetReference AssetLoadingManager::LoadIndirectAssetReference(const asset_type_t assetType, const std::string& assetName)
|
||||
{
|
||||
const auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName);
|
||||
if (alreadyLoadedAsset)
|
||||
return IndirectAssetReference(assetType, assetName);
|
||||
|
||||
const auto ignoreEntry = m_context.m_ignored_asset_map.find(assetName);
|
||||
if (ignoreEntry != m_context.m_ignored_asset_map.end() && ignoreEntry->second == assetType)
|
||||
return IndirectAssetReference(assetType, assetName);
|
||||
|
||||
const auto loader = m_asset_loaders_by_type.find(assetType);
|
||||
if (loader != m_asset_loaders_by_type.end())
|
||||
{
|
||||
LoadAssetDependency(assetType, assetName, loader->second.get());
|
||||
return IndirectAssetReference(assetType, assetName);
|
||||
}
|
||||
|
||||
std::cerr << std::format("Failed to find loader for asset type \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
return IndirectAssetReference(assetType, assetName);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoadingContext.h"
|
||||
#include "IAssetLoader.h"
|
||||
#include "IAssetLoadingManager.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class AssetLoadingManager final : public IAssetLoadingManager
|
||||
{
|
||||
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);
|
||||
|
||||
[[nodiscard]] AssetLoadingContext* GetAssetLoadingContext() const override;
|
||||
|
||||
XAssetInfoGeneric* AddAsset(std::unique_ptr<XAssetInfoGeneric> xAssetInfo) override;
|
||||
XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) override;
|
||||
IndirectAssetReference LoadIndirectAssetReference(asset_type_t assetType, const std::string& assetName) override;
|
||||
|
||||
private:
|
||||
XAssetInfoGeneric* LoadIgnoredDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader);
|
||||
XAssetInfoGeneric* LoadAssetDependency(asset_type_t assetType, const std::string& assetName, const IAssetLoader* loader);
|
||||
|
||||
XAssetInfoGeneric* AddAssetInternal(std::unique_ptr<XAssetInfoGeneric> xAssetInfo);
|
||||
|
||||
const std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>>& m_asset_loaders_by_type;
|
||||
AssetLoadingContext& m_context;
|
||||
XAssetInfoGeneric* m_last_dependency_loaded;
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderAddonMapEnts.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderAddonMapEnts::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* addonMapEnts = memory->Create<AddonMapEnts>();
|
||||
memset(addonMapEnts, 0, sizeof(AddonMapEnts));
|
||||
addonMapEnts->name = memory->Dup(assetName.c_str());
|
||||
return addonMapEnts;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderAddonMapEnts final : public BasicAssetLoader<AssetAddonMapEnts>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderClipMap.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderClipMap::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* clipMap = memory->Create<clipMap_t>();
|
||||
memset(clipMap, 0, sizeof(clipMap_t));
|
||||
clipMap->name = memory->Dup(assetName.c_str());
|
||||
return clipMap;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderClipMap : public BasicAssetLoader<AssetClipMap>
|
||||
{
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderComWorld.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderComWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* comWorld = memory->Create<ComWorld>();
|
||||
memset(comWorld, 0, sizeof(ComWorld));
|
||||
comWorld->name = memory->Dup(assetName.c_str());
|
||||
return comWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderComWorld final : public BasicAssetLoader<AssetComWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFont.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderFont::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* font = memory->Create<Font_s>();
|
||||
memset(font, 0, sizeof(Font_s));
|
||||
font->fontName = memory->Dup(assetName.c_str());
|
||||
return font;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderFont final : public BasicAssetLoader<AssetFont>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFx.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderFx::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* fx = memory->Create<FxEffectDef>();
|
||||
memset(fx, 0, sizeof(FxEffectDef));
|
||||
fx->name = memory->Dup(assetName.c_str());
|
||||
return fx;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderFx final : public BasicAssetLoader<AssetFx>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFxImpactTable.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderFxImpactTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* fxImpactTable = memory->Create<FxImpactTable>();
|
||||
memset(fxImpactTable, 0, sizeof(FxImpactTable));
|
||||
fxImpactTable->name = memory->Dup(assetName.c_str());
|
||||
return fxImpactTable;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderFxImpactTable final : public BasicAssetLoader<AssetImpactFx>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFxWorld.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderFxWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* fxWorld = memory->Create<FxWorld>();
|
||||
memset(fxWorld, 0, sizeof(FxWorld));
|
||||
fxWorld->name = memory->Dup(assetName.c_str());
|
||||
return fxWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderFxWorld final : public BasicAssetLoader<AssetFxWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,60 +0,0 @@
|
||||
#include "AssetLoaderGfxImage.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Image/IwiLoader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderGfxImage::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* asset = memory->Alloc<AssetImage::Type>();
|
||||
asset->name = memory->Dup(assetName.c_str());
|
||||
return asset;
|
||||
}
|
||||
|
||||
bool AssetLoaderGfxImage::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderGfxImage::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto fileName = std::format("images/{}.iwi", assetName);
|
||||
const auto file = searchPath->Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
const auto fileSize = static_cast<size_t>(file.m_length);
|
||||
const auto fileData = std::make_unique<char[]>(fileSize);
|
||||
file.m_stream->read(fileData.get(), fileSize);
|
||||
|
||||
std::istringstream ss(std::string(fileData.get(), fileSize));
|
||||
const auto texture = iwi::LoadIwi(ss);
|
||||
if (!texture)
|
||||
{
|
||||
std::cerr << std::format("Failed to load texture from: {}\n", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* image = memory->Create<GfxImage>();
|
||||
memset(image, 0, sizeof(GfxImage));
|
||||
|
||||
image->name = memory->Dup(assetName.c_str());
|
||||
image->noPicmip = !texture->HasMipMaps();
|
||||
image->width = static_cast<uint16_t>(texture->GetWidth());
|
||||
image->height = static_cast<uint16_t>(texture->GetHeight());
|
||||
image->depth = static_cast<uint16_t>(texture->GetDepth());
|
||||
|
||||
image->texture.loadDef = memory->Alloc<GfxImageLoadDef>();
|
||||
|
||||
manager->AddAsset<AssetImage>(assetName, image);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderGfxImage final : public BasicAssetLoader<AssetImage>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGfxLightDef.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderGfxLightDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* lightDef = memory->Create<GfxLightDef>();
|
||||
memset(lightDef, 0, sizeof(GfxLightDef));
|
||||
lightDef->name = memory->Dup(assetName.c_str());
|
||||
return lightDef;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderGfxLightDef final : public BasicAssetLoader<AssetLightDef>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGfxWorld.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderGfxWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* gfxWorld = memory->Create<GfxWorld>();
|
||||
memset(gfxWorld, 0, sizeof(GfxWorld));
|
||||
gfxWorld->name = memory->Dup(assetName.c_str());
|
||||
return gfxWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderGfxWorld final : public BasicAssetLoader<AssetGfxWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGlassWorld.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderGlassWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* glassWorld = memory->Create<GlassWorld>();
|
||||
memset(glassWorld, 0, sizeof(GlassWorld));
|
||||
glassWorld->name = memory->Dup(assetName.c_str());
|
||||
return glassWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderGlassWorld final : public BasicAssetLoader<AssetGlassWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,43 +0,0 @@
|
||||
#include "AssetLoaderLeaderboard.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderLeaderboard::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* leaderboard = memory->Create<LeaderboardDef>();
|
||||
memset(leaderboard, 0, sizeof(LeaderboardDef));
|
||||
leaderboard->name = memory->Dup(assetName.c_str());
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
bool AssetLoaderLeaderboard::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderLeaderboard::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(std::format("leaderboards/{}.json", assetName));
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* leaderboardDef = memory->Alloc<LeaderboardDef>();
|
||||
leaderboardDef->name = memory->Dup(assetName.c_str());
|
||||
|
||||
if (LoadLeaderboardAsJson(*file.m_stream, *leaderboardDef, memory))
|
||||
manager->AddAsset<AssetLeaderboard>(assetName, leaderboardDef);
|
||||
else
|
||||
std::cerr << std::format("Failed to load leaderboard \"{}\"\n", assetName);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderLeaderboard final : public BasicAssetLoader<AssetLeaderboard>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderLoadedSound.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderLoadedSound::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* loadedSound = memory->Create<LoadedSound>();
|
||||
memset(loadedSound, 0, sizeof(LoadedSound));
|
||||
loadedSound->name = memory->Dup(assetName.c_str());
|
||||
return loadedSound;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderLoadedSound final : public BasicAssetLoader<AssetLoadedSound>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderMapEnts.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderMapEnts::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* mapEnts = memory->Create<MapEnts>();
|
||||
memset(mapEnts, 0, sizeof(MapEnts));
|
||||
mapEnts->name = memory->Dup(assetName.c_str());
|
||||
return mapEnts;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderMapEnts final : public BasicAssetLoader<AssetMapEnts>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,57 +0,0 @@
|
||||
#include "AssetLoaderMaterial.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Material/JsonMaterialLoader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderMaterial::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* asset = memory->Alloc<AssetMaterial::Type>();
|
||||
asset->info.name = memory->Dup(assetName.c_str());
|
||||
return asset;
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AssetLoaderMaterial::GetFileNameForAsset(const std::string& assetName)
|
||||
{
|
||||
std::string sanitizedFileName(assetName);
|
||||
if (sanitizedFileName[0] == '*')
|
||||
{
|
||||
std::ranges::replace(sanitizedFileName, '*', '_');
|
||||
const auto parenthesisPos = sanitizedFileName.find('(');
|
||||
if (parenthesisPos != std::string::npos)
|
||||
sanitizedFileName.erase(parenthesisPos);
|
||||
sanitizedFileName = "generated/" + sanitizedFileName;
|
||||
}
|
||||
|
||||
return std::format("materials/{}.json", sanitizedFileName);
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(GetFileNameForAsset(assetName));
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* material = memory->Alloc<Material>();
|
||||
material->info.name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<XAssetInfoGeneric*> dependencies;
|
||||
if (LoadMaterialAsJson(*file.m_stream, *material, memory, manager, dependencies))
|
||||
manager->AddAsset<AssetMaterial>(assetName, material, std::move(dependencies));
|
||||
else
|
||||
std::cerr << std::format("Failed to load material \"{}\"\n", assetName);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderMaterial final : public BasicAssetLoader<AssetMaterial>
|
||||
{
|
||||
static std::string GetFileNameForAsset(const std::string& assetName);
|
||||
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderMenuDef.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderMenuDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* menu = memory->Create<menuDef_t>();
|
||||
memset(menu, 0, sizeof(menuDef_t));
|
||||
menu->window.name = memory->Dup(assetName.c_str());
|
||||
return menu;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderMenuDef final : public BasicAssetLoader<AssetMenu>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,233 +0,0 @@
|
||||
#include "AssetLoaderMenuList.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Menu/MenuConversionZoneStateIW5.h"
|
||||
#include "Game/IW5/Menu/MenuConverterIW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class MenuLoader
|
||||
{
|
||||
public:
|
||||
static bool ProcessParsedResults(const std::string& fileName,
|
||||
ISearchPath* searchPath,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
menu::ParsingResult* parsingResult,
|
||||
menu::MenuAssetZoneState* zoneState,
|
||||
MenuConversionZoneState* conversionState,
|
||||
std::vector<menuDef_t*>& menus,
|
||||
std::vector<XAssetInfoGeneric*>& menuListDependencies)
|
||||
{
|
||||
const auto menuCount = parsingResult->m_menus.size();
|
||||
const auto functionCount = parsingResult->m_functions.size();
|
||||
const auto menuLoadCount = parsingResult->m_menus_to_load.size();
|
||||
auto totalItemCount = 0u;
|
||||
for (const auto& menu : parsingResult->m_menus)
|
||||
totalItemCount += menu->m_items.size();
|
||||
|
||||
std::cout << "Successfully read menu file \"" << fileName << "\" (" << menuLoadCount << " loads, " << menuCount << " menus, " << functionCount
|
||||
<< " functions, " << totalItemCount << " items)\n";
|
||||
|
||||
// Add all functions to the zone state to make them available for all menus to be converted
|
||||
for (auto& function : parsingResult->m_functions)
|
||||
zoneState->AddFunction(std::move(function));
|
||||
|
||||
// Prepare a list of all menus of this file
|
||||
std::vector<XAssetInfo<menuDef_t>*> allMenusOfFile;
|
||||
allMenusOfFile.reserve(parsingResult->m_menus.size());
|
||||
|
||||
// Convert all menus and add them as assets
|
||||
for (auto& menu : parsingResult->m_menus)
|
||||
{
|
||||
MenuConverter converter(ObjLoading::Configuration.MenuNoOptimization, searchPath, memory, manager);
|
||||
auto* menuAsset = converter.ConvertMenu(*menu);
|
||||
if (menuAsset == nullptr)
|
||||
{
|
||||
std::cout << "Failed to convert menu file \"" << menu->m_name << "\"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
menus.push_back(menuAsset);
|
||||
auto* menuAssetInfo = manager->AddAsset<AssetMenu>(menu->m_name, menuAsset, std::move(converter.GetDependencies()));
|
||||
|
||||
if (menuAssetInfo)
|
||||
{
|
||||
allMenusOfFile.push_back(menuAssetInfo);
|
||||
menuListDependencies.push_back(menuAssetInfo);
|
||||
}
|
||||
|
||||
zoneState->AddMenu(std::move(menu));
|
||||
}
|
||||
|
||||
// Register this file with all loaded menus
|
||||
conversionState->AddLoadedFile(fileName, std::move(allMenusOfFile));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static MenuList* CreateMenuListAsset(const std::string& assetName, MemoryManager* memory, const std::vector<menuDef_t*>& menus)
|
||||
{
|
||||
auto* menuListAsset = memory->Create<MenuList>();
|
||||
menuListAsset->name = memory->Dup(assetName.c_str());
|
||||
menuListAsset->menuCount = static_cast<int>(menus.size());
|
||||
|
||||
if (menuListAsset->menuCount > 0)
|
||||
{
|
||||
menuListAsset->menus = memory->Alloc<menuDef_t*>(menuListAsset->menuCount);
|
||||
for (auto i = 0; i < menuListAsset->menuCount; i++)
|
||||
menuListAsset->menus[i] = menus[i];
|
||||
}
|
||||
else
|
||||
menuListAsset->menus = nullptr;
|
||||
|
||||
return menuListAsset;
|
||||
}
|
||||
|
||||
static std::unique_ptr<menu::ParsingResult>
|
||||
ParseMenuFile(const std::string& menuFileName, ISearchPath* searchPath, const menu::MenuAssetZoneState* zoneState)
|
||||
{
|
||||
const auto file = searchPath->Open(menuFileName);
|
||||
if (!file.IsOpen())
|
||||
return nullptr;
|
||||
|
||||
menu::MenuFileReader reader(*file.m_stream,
|
||||
menuFileName,
|
||||
menu::FeatureLevel::IW5,
|
||||
[searchPath](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr<std::istream>
|
||||
{
|
||||
auto foundFileToInclude = searchPath->Open(filename);
|
||||
if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream)
|
||||
return nullptr;
|
||||
|
||||
return std::move(foundFileToInclude.m_stream);
|
||||
});
|
||||
|
||||
reader.IncludeZoneState(zoneState);
|
||||
reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing);
|
||||
|
||||
return reader.ReadMenuFile();
|
||||
}
|
||||
};
|
||||
} // namespace IW5
|
||||
|
||||
void* AssetLoaderMenuList::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* menuList = memory->Create<MenuList>();
|
||||
memset(menuList, 0, sizeof(MenuList));
|
||||
menuList->name = memory->Dup(assetName.c_str());
|
||||
return menuList;
|
||||
}
|
||||
|
||||
bool AssetLoaderMenuList::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildMenuFileQueue(std::deque<std::string>& menuLoadQueue,
|
||||
const std::string& menuListAssetName,
|
||||
ISearchPath* searchPath,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
menu::MenuAssetZoneState* zoneState,
|
||||
MenuConversionZoneState* conversionState,
|
||||
std::vector<menuDef_t*>& menus,
|
||||
std::vector<XAssetInfoGeneric*>& menuListDependencies)
|
||||
{
|
||||
const auto alreadyLoadedMenuListFileMenus = conversionState->m_menus_by_filename.find(menuListAssetName);
|
||||
|
||||
if (alreadyLoadedMenuListFileMenus == conversionState->m_menus_by_filename.end())
|
||||
{
|
||||
const auto menuListResult = MenuLoader::ParseMenuFile(menuListAssetName, searchPath, zoneState);
|
||||
if (menuListResult)
|
||||
{
|
||||
MenuLoader::ProcessParsedResults(
|
||||
menuListAssetName, searchPath, memory, manager, menuListResult.get(), zoneState, conversionState, menus, menuListDependencies);
|
||||
|
||||
for (const auto& menuToLoad : menuListResult->m_menus_to_load)
|
||||
menuLoadQueue.push_back(menuToLoad);
|
||||
|
||||
zoneState->AddMenusToLoad(menuListAssetName, std::move(menuListResult->m_menus_to_load));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadMenuFileFromQueue(const std::string& menuFilePath,
|
||||
ISearchPath* searchPath,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
menu::MenuAssetZoneState* zoneState,
|
||||
MenuConversionZoneState* conversionState,
|
||||
std::vector<menuDef_t*>& menus,
|
||||
std::vector<XAssetInfoGeneric*>& menuListDependencies)
|
||||
{
|
||||
const auto alreadyLoadedMenuFile = conversionState->m_menus_by_filename.find(menuFilePath);
|
||||
if (alreadyLoadedMenuFile != conversionState->m_menus_by_filename.end())
|
||||
{
|
||||
std::cout << "Already loaded \"" << menuFilePath << "\", skipping\n";
|
||||
for (auto* menu : alreadyLoadedMenuFile->second)
|
||||
{
|
||||
menus.push_back(menu->Asset());
|
||||
menuListDependencies.push_back(menu);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const auto menuFileResult = MenuLoader::ParseMenuFile(menuFilePath, searchPath, zoneState);
|
||||
if (menuFileResult)
|
||||
{
|
||||
MenuLoader::ProcessParsedResults(
|
||||
menuFilePath, searchPath, memory, manager, menuFileResult.get(), zoneState, conversionState, menus, menuListDependencies);
|
||||
if (!menuFileResult->m_menus_to_load.empty())
|
||||
std::cout << "WARNING: Menu file has menus to load even though it is not a menu list, ignoring: \"" << menuFilePath << "\"\n";
|
||||
}
|
||||
else
|
||||
std::cerr << "Could not read menu file \"" << menuFilePath << "\"\n";
|
||||
}
|
||||
|
||||
bool AssetLoaderMenuList::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
std::vector<menuDef_t*> menus;
|
||||
std::vector<XAssetInfoGeneric*> menuListDependencies;
|
||||
|
||||
auto* zoneState = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<menu::MenuAssetZoneState>();
|
||||
auto* conversionState = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<MenuConversionZoneState>();
|
||||
|
||||
std::deque<std::string> menuLoadQueue;
|
||||
if (!BuildMenuFileQueue(menuLoadQueue, assetName, searchPath, memory, manager, zoneState, conversionState, menus, menuListDependencies))
|
||||
return false;
|
||||
|
||||
while (!menuLoadQueue.empty())
|
||||
{
|
||||
const auto& menuFileToLoad = menuLoadQueue.front();
|
||||
|
||||
LoadMenuFileFromQueue(menuFileToLoad, searchPath, memory, manager, zoneState, conversionState, menus, menuListDependencies);
|
||||
|
||||
menuLoadQueue.pop_front();
|
||||
}
|
||||
|
||||
auto* menuListAsset = MenuLoader::CreateMenuListAsset(assetName, memory, menus);
|
||||
|
||||
if (menuListAsset)
|
||||
manager->AddAsset<AssetMenuList>(assetName, menuListAsset, menuListDependencies);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetLoaderMenuList::FinalizeAssetsForZone(AssetLoadingContext& context) const
|
||||
{
|
||||
context.GetZoneAssetLoaderState<MenuConversionZoneState>()->FinalizeSupportingData();
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderMenuList final : public BasicAssetLoader<AssetMenuList>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
void FinalizeAssetsForZone(AssetLoadingContext& context) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderPathData.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderPathData::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* pathData = memory->Create<PathData>();
|
||||
memset(pathData, 0, sizeof(PathData));
|
||||
pathData->name = memory->Dup(assetName.c_str());
|
||||
return pathData;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderPathData final : public BasicAssetLoader<AssetPathData>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderPhysCollmap.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderPhysCollmap::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* collmap = memory->Create<PhysCollmap>();
|
||||
memset(collmap, 0, sizeof(PhysCollmap));
|
||||
collmap->name = memory->Dup(assetName.c_str());
|
||||
return collmap;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderPhysCollmap final : public BasicAssetLoader<AssetPhysCollMap>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderPhysPreset.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderPhysPreset::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* physPreset = memory->Create<PhysPreset>();
|
||||
memset(physPreset, 0, sizeof(PhysPreset));
|
||||
physPreset->name = memory->Dup(assetName.c_str());
|
||||
return physPreset;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderPhysPreset final : public BasicAssetLoader<AssetPhysPreset>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderPixelShader.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderPixelShader::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* pixelShader = memory->Create<MaterialPixelShader>();
|
||||
memset(pixelShader, 0, sizeof(MaterialPixelShader));
|
||||
pixelShader->name = memory->Dup(assetName.c_str());
|
||||
return pixelShader;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderPixelShader final : public BasicAssetLoader<AssetPixelShader>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,80 +0,0 @@
|
||||
#include "AssetLoaderRawFile.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* rawFile = memory->Create<RawFile>();
|
||||
memset(rawFile, 0, sizeof(RawFile));
|
||||
rawFile->name = memory->Dup(assetName.c_str());
|
||||
return rawFile;
|
||||
}
|
||||
|
||||
bool AssetLoaderRawFile::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderRawFile::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(assetName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
const auto uncompressedBuffer = std::make_unique<char[]>(static_cast<size_t>(file.m_length));
|
||||
file.m_stream->read(uncompressedBuffer.get(), file.m_length);
|
||||
if (file.m_stream->gcount() != file.m_length)
|
||||
return false;
|
||||
|
||||
const auto compressionBufferSize = static_cast<size_t>(file.m_length + COMPRESSED_BUFFER_SIZE_PADDING);
|
||||
auto* compressedBuffer = memory->Alloc<char>(compressionBufferSize);
|
||||
|
||||
z_stream_s zs{};
|
||||
|
||||
zs.zalloc = Z_NULL;
|
||||
zs.zfree = Z_NULL;
|
||||
zs.opaque = Z_NULL;
|
||||
zs.avail_in = static_cast<uInt>(file.m_length);
|
||||
zs.avail_out = compressionBufferSize;
|
||||
zs.next_in = reinterpret_cast<const Bytef*>(uncompressedBuffer.get());
|
||||
zs.next_out = reinterpret_cast<Bytef*>(compressedBuffer);
|
||||
|
||||
int ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
|
||||
|
||||
if (ret != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("Initializing deflate failed");
|
||||
}
|
||||
|
||||
ret = deflate(&zs, Z_FINISH);
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
std::cerr << "Deflate failed for loading rawfile \"" << assetName << "\"\n";
|
||||
deflateEnd(&zs);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto compressedSize = compressionBufferSize - zs.avail_out;
|
||||
|
||||
auto* rawFile = memory->Create<RawFile>();
|
||||
rawFile->name = memory->Dup(assetName.c_str());
|
||||
rawFile->compressedLen = static_cast<int>(compressedSize);
|
||||
rawFile->len = static_cast<int>(file.m_length);
|
||||
rawFile->buffer = static_cast<const char*>(compressedBuffer);
|
||||
|
||||
deflateEnd(&zs);
|
||||
|
||||
manager->AddAsset<AssetRawFile>(assetName, rawFile);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderRawFile final : public BasicAssetLoader<AssetRawFile>
|
||||
{
|
||||
static constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64;
|
||||
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,78 +0,0 @@
|
||||
#include "AssetLoaderScriptFile.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderScriptFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* scriptFile = memory->Create<ScriptFile>();
|
||||
memset(scriptFile, 0, sizeof(ScriptFile));
|
||||
scriptFile->name = memory->Dup(assetName.c_str());
|
||||
return scriptFile;
|
||||
}
|
||||
|
||||
bool AssetLoaderScriptFile::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format
|
||||
bool AssetLoaderScriptFile::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(assetName + ".gscbin");
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
const auto fileBuffer = std::make_unique<char[]>(static_cast<size_t>(file.m_length));
|
||||
file.m_stream->read(fileBuffer.get(), file.m_length);
|
||||
if (file.m_stream->gcount() != file.m_length)
|
||||
return false;
|
||||
|
||||
auto* scriptFile = memory->Create<ScriptFile>();
|
||||
scriptFile->name = memory->Dup(assetName.c_str());
|
||||
|
||||
// Retrieve data from the buffer
|
||||
size_t offset = 0;
|
||||
|
||||
// Read past the name pointer, we will use the one from assetName
|
||||
offset += strlen(fileBuffer.get()) + 1;
|
||||
|
||||
memcpy(&scriptFile->compressedLen, fileBuffer.get() + offset, sizeof(scriptFile->compressedLen));
|
||||
offset += sizeof(scriptFile->compressedLen);
|
||||
|
||||
memcpy(&scriptFile->len, fileBuffer.get() + offset, sizeof(scriptFile->len));
|
||||
offset += sizeof(scriptFile->len);
|
||||
|
||||
memcpy(&scriptFile->bytecodeLen, fileBuffer.get() + offset, sizeof(scriptFile->bytecodeLen));
|
||||
offset += sizeof(scriptFile->bytecodeLen);
|
||||
|
||||
if (scriptFile->compressedLen <= 0 || scriptFile->bytecodeLen <= 0)
|
||||
{
|
||||
std::cerr << "Error: Invalid length of the buffers in " << assetName << " specified\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset + (scriptFile->compressedLen + scriptFile->bytecodeLen) > file.m_length)
|
||||
{
|
||||
std::cerr << "Error: Specified length in " << assetName << " GSC BIN structure exceeds the actual file size\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
scriptFile->buffer = memory->Alloc<char>(scriptFile->compressedLen);
|
||||
memcpy(const_cast<char*>(scriptFile->buffer), fileBuffer.get() + offset, scriptFile->compressedLen);
|
||||
offset += scriptFile->compressedLen;
|
||||
|
||||
scriptFile->bytecode = memory->Alloc<unsigned char>(scriptFile->bytecodeLen);
|
||||
memcpy(scriptFile->bytecode, fileBuffer.get() + offset, scriptFile->bytecodeLen);
|
||||
|
||||
manager->AddAsset<AssetScript>(assetName, scriptFile);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderScriptFile final : public BasicAssetLoader<AssetScript>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderSoundAliasList.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderSoundAliasList::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* sndAliasList = memory->Create<snd_alias_list_t>();
|
||||
memset(sndAliasList, 0, sizeof(snd_alias_list_t));
|
||||
sndAliasList->aliasName = memory->Dup(assetName.c_str());
|
||||
return sndAliasList;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderSoundAliasList final : public BasicAssetLoader<AssetSound>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderSoundCurve.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderSoundCurve::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* sndCurve = memory->Create<SndCurve>();
|
||||
memset(sndCurve, 0, sizeof(SndCurve));
|
||||
sndCurve->filename = memory->Dup(assetName.c_str());
|
||||
return sndCurve;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderSoundCurve final : public BasicAssetLoader<AssetSoundCurve>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,40 +0,0 @@
|
||||
#include "AssetLoaderStringTable.h"
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
#include "Game/IW5/CommonIW5.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderStringTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* stringTable = memory->Create<StringTable>();
|
||||
memset(stringTable, 0, sizeof(StringTable));
|
||||
stringTable->name = memory->Dup(assetName.c_str());
|
||||
return stringTable;
|
||||
}
|
||||
|
||||
bool AssetLoaderStringTable::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderStringTable::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(assetName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
string_table::StringTableLoaderV2<StringTable, Common::StringTable_HashString> loader;
|
||||
auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream);
|
||||
|
||||
manager->AddAsset<AssetStringTable>(assetName, stringTable);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderStringTable final : public BasicAssetLoader<AssetStringTable>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderStructuredDataDef.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderStructuredDataDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* structuredDataDefSet = memory->Create<StructuredDataDefSet>();
|
||||
memset(structuredDataDefSet, 0, sizeof(StructuredDataDefSet));
|
||||
structuredDataDefSet->name = memory->Dup(assetName.c_str());
|
||||
return structuredDataDefSet;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderStructuredDataDef final : public BasicAssetLoader<AssetStructuredDataDef>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderSurfaceFxTable.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderSurfaceFxTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* surfaceFxTable = memory->Create<SurfaceFxTable>();
|
||||
memset(surfaceFxTable, 0, sizeof(SurfaceFxTable));
|
||||
surfaceFxTable->name = memory->Dup(assetName.c_str());
|
||||
return surfaceFxTable;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderSurfaceFxTable final : public BasicAssetLoader<AssetSurfaceFx>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderTechniqueSet.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderTechniqueSet::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* techniqueSet = memory->Create<MaterialTechniqueSet>();
|
||||
memset(techniqueSet, 0, sizeof(MaterialTechniqueSet));
|
||||
techniqueSet->name = memory->Dup(assetName.c_str());
|
||||
return techniqueSet;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderTechniqueSet final : public BasicAssetLoader<AssetTechniqueSet>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderTracerDef.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderTracerDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* tracerDef = memory->Create<TracerDef>();
|
||||
memset(tracerDef, 0, sizeof(TracerDef));
|
||||
tracerDef->name = memory->Dup(assetName.c_str());
|
||||
return tracerDef;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderTracerDef final : public BasicAssetLoader<AssetTracer>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderVehicleDef.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderVehicleDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* vehicleDef = memory->Create<VehicleDef>();
|
||||
memset(vehicleDef, 0, sizeof(VehicleDef));
|
||||
vehicleDef->name = memory->Dup(assetName.c_str());
|
||||
return vehicleDef;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderVehicleDef final : public BasicAssetLoader<AssetVehicle>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderVehicleTrack.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderVehicleTrack::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* vehicleTrack = memory->Create<VehicleTrack>();
|
||||
memset(vehicleTrack, 0, sizeof(VehicleTrack));
|
||||
vehicleTrack->name = memory->Dup(assetName.c_str());
|
||||
return vehicleTrack;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderVehicleTrack final : public BasicAssetLoader<AssetVehicleTrack>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderVertexDecl.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderVertexDecl::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* vertexDecl = memory->Create<MaterialVertexDeclaration>();
|
||||
memset(vertexDecl, 0, sizeof(MaterialVertexDeclaration));
|
||||
vertexDecl->name = memory->Dup(assetName.c_str());
|
||||
return vertexDecl;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderVertexDecl final : public BasicAssetLoader<AssetVertexDecl>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderVertexShader.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderVertexShader::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* vertexShader = memory->Create<MaterialVertexShader>();
|
||||
memset(vertexShader, 0, sizeof(MaterialVertexShader));
|
||||
vertexShader->name = memory->Dup(assetName.c_str());
|
||||
return vertexShader;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderVertexShader final : public BasicAssetLoader<AssetVertexShader>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderWeapon final : public BasicAssetLoader<AssetWeapon>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromGdt() const override;
|
||||
bool LoadFromGdt(
|
||||
const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,45 +0,0 @@
|
||||
#include "AssetLoaderWeaponAttachment.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Weapon/JsonWeaponAttachmentLoader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderWeaponAttachment::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* attachment = memory->Create<WeaponAttachment>();
|
||||
memset(attachment, 0, sizeof(WeaponAttachment));
|
||||
attachment->szInternalName = memory->Dup(assetName.c_str());
|
||||
|
||||
return attachment;
|
||||
}
|
||||
|
||||
bool AssetLoaderWeaponAttachment::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderWeaponAttachment::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(std::format("attachment/{}.json", assetName));
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* attachment = memory->Alloc<WeaponAttachment>();
|
||||
attachment->szInternalName = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<XAssetInfoGeneric*> dependencies;
|
||||
std::vector<IndirectAssetReference> indirectAssetReferences;
|
||||
if (LoadWeaponAttachmentAsJson(*file.m_stream, *attachment, memory, manager, dependencies, indirectAssetReferences))
|
||||
manager->AddAsset<AssetAttachment>(assetName, attachment, std::move(dependencies), std::vector<scr_string_t>(), std::move(indirectAssetReferences));
|
||||
else
|
||||
std::cerr << "Failed to load attachment \"" << assetName << "\"\n";
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderWeaponAttachment final : public BasicAssetLoader<AssetAttachment>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderXAnim.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderXAnim::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* anim = memory->Create<XAnimParts>();
|
||||
memset(anim, 0, sizeof(XAnimParts));
|
||||
anim->name = memory->Dup(assetName.c_str());
|
||||
return anim;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderXAnim final : public BasicAssetLoader<AssetXAnim>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,47 +0,0 @@
|
||||
#include "AssetLoaderXModel.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/XModel/XModelLoaderIW5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderXModel::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* asset = memory->Alloc<AssetXModel::Type>();
|
||||
asset->name = memory->Dup(assetName.c_str());
|
||||
return asset;
|
||||
}
|
||||
|
||||
bool AssetLoaderXModel::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderXModel::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto file = searchPath->Open(std::format("xmodel/{}.json", assetName));
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
auto* xmodel = memory->Alloc<XModel>();
|
||||
xmodel->name = memory->Dup(assetName.c_str());
|
||||
|
||||
std::vector<XAssetInfoGeneric*> dependencies;
|
||||
if (LoadXModel(*file.m_stream, *xmodel, memory, manager, dependencies))
|
||||
{
|
||||
manager->AddAsset<AssetXModel>(assetName, xmodel, std::move(dependencies));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << std::format("Failed to load xmodel \"{}\"\n", assetName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderXModel final : public BasicAssetLoader<AssetXModel>
|
||||
{
|
||||
static std::string GetFileNameForAsset(const std::string& assetName);
|
||||
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW5
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderXModelSurfs.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
void* AssetLoaderXModelSurfs::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* modelSurfs = memory->Create<XModelSurfs>();
|
||||
memset(modelSurfs, 0, sizeof(XModelSurfs));
|
||||
modelSurfs->name = memory->Dup(assetName.c_str());
|
||||
return modelSurfs;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderXModelSurfs final : public BasicAssetLoader<AssetXModelSurfs>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW5
|
69
src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp
Normal file
69
src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "LoaderImageIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Image/IwiLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto MAX_IMAGE_NAME_SIZE = 0x800;
|
||||
|
||||
class ImageLoader final : public AssetCreator<AssetImage>
|
||||
{
|
||||
public:
|
||||
ImageLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = std::format("images/{}.iwi", assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
const auto fileSize = static_cast<size_t>(file.m_length);
|
||||
const auto fileData = std::make_unique<char[]>(fileSize);
|
||||
file.m_stream->read(fileData.get(), fileSize);
|
||||
|
||||
std::istringstream ss(std::string(fileData.get(), fileSize));
|
||||
const auto texture = iwi::LoadIwi(ss);
|
||||
if (!texture)
|
||||
{
|
||||
std::cerr << std::format("Failed to load texture from: {}\n", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
auto* image = m_memory.Alloc<GfxImage>();
|
||||
image->name = m_memory.Dup(assetName.c_str());
|
||||
image->noPicmip = !texture->HasMipMaps();
|
||||
image->width = static_cast<uint16_t>(texture->GetWidth());
|
||||
image->height = static_cast<uint16_t>(texture->GetHeight());
|
||||
image->depth = static_cast<uint16_t>(texture->GetDepth());
|
||||
|
||||
image->texture.loadDef = m_memory.Alloc<GfxImageLoadDef>();
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset<AssetImage>(assetName, image));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<ImageLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
13
src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h
Normal file
13
src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
@ -1,6 +1,7 @@
|
||||
#include "InfoStringToStructConverter.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
@ -8,12 +9,12 @@ using namespace IW5;
|
||||
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString,
|
||||
void* structure,
|
||||
ZoneScriptStrings& zoneScriptStrings,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
MemoryManager& memory,
|
||||
AssetCreationContext& context,
|
||||
GenericAssetRegistration& registration,
|
||||
const cspField_t* fields,
|
||||
const size_t fieldCount)
|
||||
: InfoStringToStructConverterBase(infoString, structure, zoneScriptStrings, memory),
|
||||
m_loading_manager(manager),
|
||||
: InfoStringToStructConverterBase(infoString, structure, zoneScriptStrings, memory, context, registration),
|
||||
m_fields(fields),
|
||||
m_field_count(fieldCount)
|
||||
{
|
||||
@ -58,15 +59,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* fx = m_loading_manager->LoadDependency<AssetFx>(value);
|
||||
auto* fx = m_context.LoadDependency<AssetFx>(value);
|
||||
|
||||
if (fx == nullptr)
|
||||
{
|
||||
std::cout << "Failed to load fx asset \"" << value << "\"\n";
|
||||
std::cerr << std::format("Failed to load fx asset \"{}\"\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dependencies.emplace(fx);
|
||||
m_registration.AddDependency(fx);
|
||||
*reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset) = fx->Asset();
|
||||
|
||||
return true;
|
||||
@ -80,15 +81,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* xmodel = m_loading_manager->LoadDependency<AssetXModel>(value);
|
||||
auto* xmodel = m_context.LoadDependency<AssetXModel>(value);
|
||||
|
||||
if (xmodel == nullptr)
|
||||
{
|
||||
std::cout << "Failed to load xmodel asset \"" << value << "\"\n";
|
||||
std::cerr << std::format("Failed to load xmodel asset \"{}\"\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dependencies.emplace(xmodel);
|
||||
m_registration.AddDependency(xmodel);
|
||||
*reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset) = xmodel->Asset();
|
||||
|
||||
return true;
|
||||
@ -102,15 +103,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* material = m_loading_manager->LoadDependency<AssetMaterial>(value);
|
||||
auto* material = m_context.LoadDependency<AssetMaterial>(value);
|
||||
|
||||
if (material == nullptr)
|
||||
{
|
||||
std::cout << "Failed to load material asset \"" << value << "\"\n";
|
||||
std::cerr << std::format("Failed to load material asset \"{}\"\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dependencies.emplace(material);
|
||||
m_registration.AddDependency(material);
|
||||
*reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset) = material->Asset();
|
||||
|
||||
return true;
|
||||
@ -124,15 +125,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* tracer = m_loading_manager->LoadDependency<AssetTracer>(value);
|
||||
auto* tracer = m_context.LoadDependency<AssetTracer>(value);
|
||||
|
||||
if (tracer == nullptr)
|
||||
{
|
||||
std::cout << "Failed to load tracer asset \"" << value << "\"\n";
|
||||
std::cerr << std::format("Failed to load tracer asset \"{}\"\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dependencies.emplace(tracer);
|
||||
m_registration.AddDependency(tracer);
|
||||
*reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset) = tracer->Asset();
|
||||
|
||||
return true;
|
||||
@ -160,15 +161,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* collmap = m_loading_manager->LoadDependency<AssetPhysCollMap>(value);
|
||||
auto* collmap = m_context.LoadDependency<AssetPhysCollMap>(value);
|
||||
|
||||
if (collmap == nullptr)
|
||||
{
|
||||
std::cout << "Failed to load collmap asset \"" << value << "\"\n";
|
||||
std::cerr << std::format("Failed to load collmap asset \"{}\"\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dependencies.emplace(collmap);
|
||||
m_registration.AddDependency(collmap);
|
||||
*reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset) = collmap->Asset();
|
||||
|
||||
return true;
|
||||
@ -182,12 +183,12 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* name = m_memory->Alloc<snd_alias_list_name>();
|
||||
name->soundName = m_memory->Dup(value.c_str());
|
||||
auto* name = m_memory.Alloc<snd_alias_list_name>();
|
||||
name->soundName = m_memory.Dup(value.c_str());
|
||||
|
||||
reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset)->name = name;
|
||||
|
||||
m_indirect_asset_references.emplace(ASSET_TYPE_SOUND, value);
|
||||
m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference<AssetSound>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "InfoString/InfoStringToStructConverterBase.h"
|
||||
@ -7,24 +8,22 @@ namespace IW5
|
||||
{
|
||||
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
||||
{
|
||||
protected:
|
||||
IAssetLoadingManager* m_loading_manager;
|
||||
const cspField_t* m_fields;
|
||||
size_t m_field_count;
|
||||
|
||||
static bool GetHashValue(const std::string& value, unsigned int& hash);
|
||||
|
||||
virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0;
|
||||
bool ConvertBaseField(const cspField_t& field, const std::string& value);
|
||||
|
||||
public:
|
||||
InfoStringToStructConverter(const InfoString& infoString,
|
||||
void* structure,
|
||||
ZoneScriptStrings& zoneScriptStrings,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
MemoryManager& memory,
|
||||
AssetCreationContext& context,
|
||||
GenericAssetRegistration& registration,
|
||||
const cspField_t* fields,
|
||||
size_t fieldCount);
|
||||
bool Convert() override;
|
||||
|
||||
protected:
|
||||
virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0;
|
||||
bool ConvertBaseField(const cspField_t& field, const std::string& value);
|
||||
|
||||
const cspField_t* m_fields;
|
||||
size_t m_field_count;
|
||||
};
|
||||
} // namespace IW5
|
||||
|
@ -122,9 +122,9 @@ namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory)
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory)
|
||||
{
|
||||
const JsonLoader loader(stream, *memory);
|
||||
const JsonLoader loader(stream, memory);
|
||||
|
||||
return loader.Load(leaderboard);
|
||||
}
|
||||
|
@ -7,5 +7,5 @@
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory);
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory);
|
||||
} // namespace IW5
|
||||
|
53
src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp
Normal file
53
src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "LoaderLeaderboardIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class LeaderboardLoader final : public AssetCreator<AssetLeaderboard>
|
||||
{
|
||||
public:
|
||||
LeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(std::format("leaderboards/{}.json", assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* leaderboardDef = m_memory.Alloc<LeaderboardDef>();
|
||||
leaderboardDef->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
if (!LoadLeaderboardAsJson(*file.m_stream, *leaderboardDef, m_memory))
|
||||
{
|
||||
std::cerr << std::format("Failed to load leaderboard \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset<AssetLeaderboard>(assetName, leaderboardDef));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LeaderboardLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
13
src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h
Normal file
13
src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
@ -1,23 +0,0 @@
|
||||
#include "AssetLoaderLocalizeIW5.h"
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
AssetLoaderLocalize::AssetLoaderLocalize(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: CommonLocalizeLoader(searchPath, zone),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult AssetLoaderLocalize::CreateAsset(const std::string& assetName, AssetCreationContext& context)
|
||||
{
|
||||
return CreateLocalizeAsset(assetName, context);
|
||||
}
|
||||
|
||||
AssetCreationResult AssetLoaderLocalize::CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context)
|
||||
{
|
||||
auto* asset = m_memory.Alloc<LocalizeEntry>();
|
||||
asset->name = m_memory.Dup(localizeEntry.m_key.c_str());
|
||||
asset->value = m_memory.Dup(localizeEntry.m_value.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset<AssetLocalize>(localizeEntry.m_key, asset));
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/AssetCreationContext.h"
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Localize/CommonLocalizeLoader.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
class AssetLoaderLocalize final : public AssetCreator<AssetLocalize>, public CommonLocalizeLoader
|
||||
{
|
||||
public:
|
||||
AssetLoaderLocalize(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override;
|
||||
|
||||
protected:
|
||||
AssetCreationResult CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context) override;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace IW5
|
44
src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp
Normal file
44
src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "LoaderLocalizeIW5.h"
|
||||
|
||||
#include "Localize/CommonLocalizeLoader.h"
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class LocalizeLoader final : public AssetCreator<AssetLocalize>, public CommonLocalizeLoader
|
||||
{
|
||||
public:
|
||||
LocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: CommonLocalizeLoader(searchPath, zone),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
return CreateLocalizeAsset(assetName, context);
|
||||
}
|
||||
|
||||
protected:
|
||||
AssetCreationResult CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context) override
|
||||
{
|
||||
auto* asset = m_memory.Alloc<LocalizeEntry>();
|
||||
asset->name = m_memory.Dup(localizeEntry.m_key.c_str());
|
||||
asset->value = m_memory.Dup(localizeEntry.m_value.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset<AssetLocalize>(localizeEntry.m_key, asset));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW5
|
14
src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h
Normal file
14
src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW5
|
@ -16,12 +16,11 @@ namespace
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory, IAssetLoadingManager& manager, std::vector<XAssetInfoGeneric*>& dependencies)
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetMaterial>& registration)
|
||||
: m_stream(stream),
|
||||
m_memory(memory),
|
||||
m_manager(manager),
|
||||
m_dependencies(dependencies)
|
||||
|
||||
m_context(context),
|
||||
m_registration(registration)
|
||||
{
|
||||
}
|
||||
|
||||
@ -159,13 +158,13 @@ namespace
|
||||
|
||||
textureDef.semantic = jTexture.semantic;
|
||||
|
||||
auto* imageAsset = m_manager.LoadDependency<AssetImage>(jTexture.image);
|
||||
auto* imageAsset = m_context.LoadDependency<AssetImage>(jTexture.image);
|
||||
if (!imageAsset)
|
||||
{
|
||||
PrintError(material, std::format("Could not find textureDef image: {}", jTexture.image));
|
||||
return false;
|
||||
}
|
||||
m_dependencies.push_back(imageAsset);
|
||||
m_registration.AddDependency(imageAsset);
|
||||
|
||||
if (jTexture.water)
|
||||
{
|
||||
@ -365,13 +364,13 @@ namespace
|
||||
material.stateFlags = static_cast<unsigned char>(jMaterial.stateFlags);
|
||||
material.cameraRegion = jMaterial.cameraRegion;
|
||||
|
||||
auto* techniqueSet = m_manager.LoadDependency<AssetTechniqueSet>(jMaterial.techniqueSet);
|
||||
auto* techniqueSet = m_context.LoadDependency<AssetTechniqueSet>(jMaterial.techniqueSet);
|
||||
if (!techniqueSet)
|
||||
{
|
||||
PrintError(material, "Could not find technique set");
|
||||
return false;
|
||||
}
|
||||
m_dependencies.push_back(techniqueSet);
|
||||
m_registration.AddDependency(techniqueSet);
|
||||
material.techniqueSet = techniqueSet->Asset();
|
||||
|
||||
if (!jMaterial.textures.empty())
|
||||
@ -430,17 +429,17 @@ namespace
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
IAssetLoadingManager& m_manager;
|
||||
std::vector<XAssetInfoGeneric*>& m_dependencies;
|
||||
AssetCreationContext& m_context;
|
||||
AssetRegistration<AssetMaterial>& m_registration;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadMaterialAsJson(
|
||||
std::istream& stream, Material& material, MemoryManager* memory, IAssetLoadingManager* manager, std::vector<XAssetInfoGeneric*>& dependencies)
|
||||
std::istream& stream, Material& material, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetMaterial>& registration)
|
||||
{
|
||||
const JsonLoader loader(stream, *memory, *manager, dependencies);
|
||||
const JsonLoader loader(stream, memory, context, registration);
|
||||
|
||||
return loader.Load(material);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Asset/AssetCreationContext.h"
|
||||
#include "Asset/AssetRegistration.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
@ -9,5 +10,5 @@
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadMaterialAsJson(
|
||||
std::istream& stream, Material& material, MemoryManager* memory, IAssetLoadingManager* manager, std::vector<XAssetInfoGeneric*>& dependencies);
|
||||
std::istream& stream, Material& material, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetMaterial>& registration);
|
||||
} // namespace IW5
|
||||
|
70
src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp
Normal file
70
src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "LoaderMaterialIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "JsonMaterialLoader.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
||||
{
|
||||
public:
|
||||
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(GetFileNameForAsset(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* material = m_memory.Alloc<Material>();
|
||||
material->info.name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
|
||||
{
|
||||
std::cerr << std::format("Failed to load material \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetFileNameForAsset(const std::string& assetName)
|
||||
{
|
||||
std::string sanitizedFileName(assetName);
|
||||
if (sanitizedFileName[0] == '*')
|
||||
{
|
||||
std::ranges::replace(sanitizedFileName, '*', '_');
|
||||
const auto parenthesisPos = sanitizedFileName.find('(');
|
||||
if (parenthesisPos != std::string::npos)
|
||||
sanitizedFileName.erase(parenthesisPos);
|
||||
sanitizedFileName = std::format("generated/{}", sanitizedFileName);
|
||||
}
|
||||
|
||||
return std::format("materials/{}.json", sanitizedFileName);
|
||||
}
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
13
src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h
Normal file
13
src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
230
src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp
Normal file
230
src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include "LoaderMenuListIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Menu/MenuConversionZoneStateIW5.h"
|
||||
#include "Game/IW5/Menu/MenuConverterIW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class MenuListLoader final : public AssetCreator<AssetMenuList>
|
||||
{
|
||||
public:
|
||||
MenuListLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
std::vector<menuDef_t*> menus;
|
||||
AssetRegistration<AssetMenuList> registration(assetName);
|
||||
|
||||
auto* zoneState = context.GetZoneAssetLoaderState<menu::MenuAssetZoneState>();
|
||||
auto* conversionState = context.GetZoneAssetLoaderState<MenuConversionZoneState>();
|
||||
|
||||
std::deque<std::string> menuLoadQueue;
|
||||
const auto alreadyLoadedMenuListFileMenus = conversionState->m_menus_by_filename.find(assetName);
|
||||
|
||||
if (alreadyLoadedMenuListFileMenus == conversionState->m_menus_by_filename.end())
|
||||
{
|
||||
const auto file = m_search_path.Open(assetName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
const auto menuListResult = ParseMenuFile(*file.m_stream, assetName, zoneState);
|
||||
if (menuListResult)
|
||||
{
|
||||
ProcessParsedResults(assetName, context, menuListResult.get(), zoneState, conversionState, menus, registration);
|
||||
|
||||
for (const auto& menuToLoad : menuListResult->m_menus_to_load)
|
||||
menuLoadQueue.emplace_back(menuToLoad);
|
||||
|
||||
zoneState->AddMenusToLoad(assetName, std::move(menuListResult->m_menus_to_load));
|
||||
}
|
||||
else
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
while (!menuLoadQueue.empty())
|
||||
{
|
||||
const auto& menuFileToLoad = menuLoadQueue.front();
|
||||
|
||||
LoadMenuFileFromQueue(menuFileToLoad, context, zoneState, conversionState, menus, registration);
|
||||
|
||||
menuLoadQueue.pop_front();
|
||||
}
|
||||
|
||||
auto* menuListAsset = m_memory.Create<MenuList>();
|
||||
menuListAsset->name = m_memory.Dup(assetName.c_str());
|
||||
registration.SetAsset(menuListAsset);
|
||||
|
||||
CreateMenuListAsset(*menuListAsset, menus);
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
|
||||
void FinalizeZone(AssetCreationContext& context) override
|
||||
{
|
||||
context.GetZoneAssetLoaderState<MenuConversionZoneState>()->FinalizeSupportingData();
|
||||
}
|
||||
|
||||
private:
|
||||
bool LoadMenuFileFromQueue(const std::string& menuFilePath,
|
||||
AssetCreationContext& context,
|
||||
menu::MenuAssetZoneState* zoneState,
|
||||
MenuConversionZoneState* conversionState,
|
||||
std::vector<menuDef_t*>& menus,
|
||||
AssetRegistration<AssetMenuList>& registration)
|
||||
{
|
||||
const auto alreadyLoadedMenuFile = conversionState->m_menus_by_filename.find(menuFilePath);
|
||||
if (alreadyLoadedMenuFile != conversionState->m_menus_by_filename.end())
|
||||
{
|
||||
std::cout << std::format("Already loaded \"{}\", skipping\n", menuFilePath);
|
||||
for (auto* menu : alreadyLoadedMenuFile->second)
|
||||
{
|
||||
menus.emplace_back(menu->Asset());
|
||||
registration.AddDependency(menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto file = m_search_path.Open(menuFilePath);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
std::cerr << std::format("Could not open menu file \"{}\"\n", menuFilePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto menuFileResult = ParseMenuFile(*file.m_stream, menuFilePath, zoneState);
|
||||
if (menuFileResult)
|
||||
{
|
||||
ProcessParsedResults(menuFilePath, context, menuFileResult.get(), zoneState, conversionState, menus, registration);
|
||||
if (!menuFileResult->m_menus_to_load.empty())
|
||||
std::cout << std::format("WARNING: Menu file has menus to load even though it is not a menu list, ignoring: \"{}\"\n", menuFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
std::cerr << std::format("Could not read menu file \"{}\"\n", menuFilePath);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessParsedResults(const std::string& fileName,
|
||||
AssetCreationContext& context,
|
||||
menu::ParsingResult* parsingResult,
|
||||
menu::MenuAssetZoneState* zoneState,
|
||||
MenuConversionZoneState* conversionState,
|
||||
std::vector<menuDef_t*>& menus,
|
||||
AssetRegistration<AssetMenuList>& registration)
|
||||
{
|
||||
const auto menuCount = parsingResult->m_menus.size();
|
||||
const auto functionCount = parsingResult->m_functions.size();
|
||||
const auto menuLoadCount = parsingResult->m_menus_to_load.size();
|
||||
auto totalItemCount = 0u;
|
||||
for (const auto& menu : parsingResult->m_menus)
|
||||
totalItemCount += menu->m_items.size();
|
||||
|
||||
std::cout << std::format("Successfully read menu file \"{}\" ({} loads, {} menus, {} functions, {} items)\n",
|
||||
fileName,
|
||||
menuLoadCount,
|
||||
menuCount,
|
||||
functionCount,
|
||||
totalItemCount);
|
||||
|
||||
// Add all functions to the zone state to make them available for all menus to be converted
|
||||
for (auto& function : parsingResult->m_functions)
|
||||
zoneState->AddFunction(std::move(function));
|
||||
|
||||
// Prepare a list of all menus of this file
|
||||
std::vector<XAssetInfo<menuDef_t>*> allMenusOfFile;
|
||||
allMenusOfFile.reserve(parsingResult->m_menus.size());
|
||||
|
||||
// Convert all menus and add them as assets
|
||||
for (auto& commonMenu : parsingResult->m_menus)
|
||||
{
|
||||
auto converter = IMenuConverter::Create(ObjLoading::Configuration.MenuNoOptimization, m_search_path, m_memory, context);
|
||||
|
||||
auto* menuAsset = m_memory.Alloc<menuDef_t>();
|
||||
AssetRegistration<AssetMenu> menuRegistration(commonMenu->m_name, menuAsset);
|
||||
|
||||
converter->ConvertMenu(*commonMenu, *menuAsset, menuRegistration);
|
||||
if (menuAsset == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to convert menu file \"{}\"\n", commonMenu->m_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
menus.emplace_back(menuAsset);
|
||||
auto* menuAssetInfo = context.AddAsset(std::move(menuRegistration));
|
||||
|
||||
if (menuAssetInfo)
|
||||
{
|
||||
allMenusOfFile.emplace_back(menuAssetInfo);
|
||||
registration.AddDependency(menuAssetInfo);
|
||||
}
|
||||
|
||||
zoneState->AddMenu(std::move(commonMenu));
|
||||
}
|
||||
|
||||
// Register this file with all loaded menus
|
||||
conversionState->AddLoadedFile(fileName, std::move(allMenusOfFile));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CreateMenuListAsset(MenuList& menuList, const std::vector<menuDef_t*>& menus)
|
||||
{
|
||||
menuList.menuCount = static_cast<int>(menus.size());
|
||||
|
||||
if (menuList.menuCount > 0)
|
||||
{
|
||||
menuList.menus = m_memory.Alloc<menuDef_t*>(menuList.menuCount);
|
||||
for (auto i = 0; i < menuList.menuCount; i++)
|
||||
menuList.menus[i] = menus[i];
|
||||
}
|
||||
else
|
||||
menuList.menus = nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<menu::ParsingResult> ParseMenuFile(std::istream& stream, const std::string& menuFileName, const menu::MenuAssetZoneState* zoneState)
|
||||
{
|
||||
menu::MenuFileReader reader(stream,
|
||||
menuFileName,
|
||||
menu::FeatureLevel::IW4,
|
||||
[this](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr<std::istream>
|
||||
{
|
||||
auto foundFileToInclude = m_search_path.Open(filename);
|
||||
if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream)
|
||||
return nullptr;
|
||||
|
||||
return std::move(foundFileToInclude.m_stream);
|
||||
});
|
||||
|
||||
reader.IncludeZoneState(zoneState);
|
||||
reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing);
|
||||
|
||||
return reader.ReadMenuFile();
|
||||
}
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MenuListLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
13
src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h
Normal file
13
src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user