mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
chore: refactor IW4 asset loaders
This commit is contained in:
parent
f9456101e6
commit
7ef944ebd4
@ -1,6 +1,7 @@
|
||||
#include "ZoneCreator.h"
|
||||
|
||||
#include "AssetLoading/AssetLoadingContext.h"
|
||||
#include "Gdt/GdtLookup.h"
|
||||
#include "IObjCompiler.h"
|
||||
#include "IObjLoader.h"
|
||||
|
||||
@ -45,6 +46,19 @@ namespace
|
||||
|
||||
namespace zone_creator
|
||||
{
|
||||
void InitLookup(const ZoneCreationContext& context, GdtLookup& lookup)
|
||||
{
|
||||
std::vector<const Gdt*> gdtFiles;
|
||||
gdtFiles.reserve(context.m_gdt_files.size());
|
||||
|
||||
for (const auto& gdt : context.m_gdt_files)
|
||||
{
|
||||
gdtFiles.emplace_back(gdt.get());
|
||||
}
|
||||
|
||||
lookup.Initialize(gdtFiles);
|
||||
}
|
||||
|
||||
std::unique_ptr<Zone> CreateZoneForDefinition(GameId gameId, ZoneCreationContext& context)
|
||||
{
|
||||
auto zone = CreateZone(context, gameId);
|
||||
@ -53,12 +67,15 @@ namespace zone_creator
|
||||
IgnoreReferencesFromAssets(context);
|
||||
IgnoredAssetLookup ignoredAssetLookup(context.m_ignored_assets);
|
||||
|
||||
GdtLookup lookup;
|
||||
InitLookup(context, lookup);
|
||||
|
||||
const auto* objCompiler = IObjCompiler::GetObjCompilerForGame(gameId);
|
||||
const auto* objLoader = IObjLoader::GetObjLoaderForGame(gameId);
|
||||
|
||||
AssetCreatorCollection creatorCollection(*zone);
|
||||
objCompiler->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_definition);
|
||||
objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path);
|
||||
objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path, gdtLookup);
|
||||
|
||||
AssetCreationContext creationContext(zone.get(), &creatorCollection, &ignoredAssetLookup);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
|
||||
namespace IW4
|
@ -1,5 +1,6 @@
|
||||
#include "AssetCreationContext.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
@ -51,6 +52,8 @@ void GenericAssetRegistration::AddIndirectAssetReference(IndirectAssetReference
|
||||
|
||||
std::unique_ptr<XAssetInfoGeneric> GenericAssetRegistration::CreateXAssetInfo()
|
||||
{
|
||||
assert(m_asset);
|
||||
|
||||
std::vector<XAssetInfoGeneric*> dependencies(m_dependencies.begin(), m_dependencies.end());
|
||||
std::vector<scr_string_t> scriptStrings(m_used_script_strings.begin(), m_used_script_strings.end());
|
||||
std::vector<IndirectAssetReference> indirectAssetReferences(m_indirect_asset_references.begin(), m_indirect_asset_references.end());
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
{
|
||||
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
|
||||
|
||||
return static_cast<XAssetInfo<typename AssetType::Type>*>(LoadDependencyInternal(AssetType::EnumEntry, assetName));
|
||||
return static_cast<XAssetInfo<typename AssetType::Type>*>(LoadDependencyGeneric(AssetType::EnumEntry, assetName));
|
||||
}
|
||||
|
||||
XAssetInfoGeneric* LoadDependencyGeneric(asset_type_t assetType, const std::string& assetName);
|
||||
@ -76,7 +76,7 @@ public:
|
||||
return dynamic_cast<T*>(foundEntry->second.get());
|
||||
|
||||
auto newState = std::make_unique<T>();
|
||||
newState->SetZone(&m_zone);
|
||||
newState->SetZone(m_zone);
|
||||
auto* newStatePtr = newState.get();
|
||||
m_zone_asset_loader_states.emplace(std::make_pair<std::type_index, std::unique_ptr<IZoneAssetLoaderState>>(typeid(T), std::move(newState)));
|
||||
return newStatePtr;
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
|
||||
std::unique_ptr<XAssetInfoGeneric> CreateXAssetInfo();
|
||||
|
||||
private:
|
||||
protected:
|
||||
asset_type_t m_type;
|
||||
std::string m_name;
|
||||
void* m_asset;
|
||||
@ -39,6 +39,11 @@ template<typename AssetType> class AssetRegistration : public GenericAssetRegist
|
||||
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
|
||||
|
||||
public:
|
||||
AssetRegistration(std::string assetName)
|
||||
: GenericAssetRegistration(AssetType::EnumEntry, std::move(assetName), nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
AssetRegistration(std::string assetName, typename AssetType::Type* asset)
|
||||
: GenericAssetRegistration(AssetType::EnumEntry, std::move(assetName), asset)
|
||||
{
|
||||
@ -48,4 +53,9 @@ public:
|
||||
AssetRegistration(AssetRegistration&& other) = default;
|
||||
AssetRegistration& operator=(const AssetRegistration& other) = delete;
|
||||
AssetRegistration& operator=(AssetRegistration&& other) noexcept = default;
|
||||
|
||||
void SetAsset(typename AssetType::Type* asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
}
|
||||
};
|
||||
|
@ -2,49 +2,6 @@
|
||||
|
||||
AssetLoadingContext::AssetLoadingContext(Zone& zone, ISearchPath& rawSearchPath, std::vector<Gdt*> gdtFiles)
|
||||
: m_zone(zone),
|
||||
m_raw_search_path(rawSearchPath),
|
||||
m_gdt_files(std::move(gdtFiles))
|
||||
m_raw_search_path(rawSearchPath)
|
||||
{
|
||||
BuildGdtEntryCache();
|
||||
}
|
||||
|
||||
void AssetLoadingContext::BuildGdtEntryCache()
|
||||
{
|
||||
for (const auto* gdt : m_gdt_files)
|
||||
{
|
||||
for (const auto& entry : gdt->m_entries)
|
||||
{
|
||||
auto gdfMapEntry = m_entries_by_gdf_and_by_name.find(entry->m_gdf_name);
|
||||
if (gdfMapEntry == m_entries_by_gdf_and_by_name.end())
|
||||
{
|
||||
std::unordered_map<std::string, GdtEntry*> entryMap;
|
||||
entryMap.emplace(std::make_pair(entry->m_name, entry.get()));
|
||||
m_entries_by_gdf_and_by_name.emplace(std::make_pair(entry->m_gdf_name, std::move(entryMap)));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto entryMapEntry = gdfMapEntry->second.find(entry->m_name);
|
||||
|
||||
if (entryMapEntry == gdfMapEntry->second.end())
|
||||
gdfMapEntry->second.emplace(std::make_pair(entry->m_name, entry.get()));
|
||||
else
|
||||
entryMapEntry->second = entry.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GdtEntry* AssetLoadingContext::GetGdtEntryByGdfAndName(const std::string& gdfName, const std::string& entryName)
|
||||
{
|
||||
const auto foundGdtMap = m_entries_by_gdf_and_by_name.find(gdfName);
|
||||
|
||||
if (foundGdtMap == m_entries_by_gdf_and_by_name.end())
|
||||
return nullptr;
|
||||
|
||||
const auto foundGdtEntry = foundGdtMap->second.find(entryName);
|
||||
|
||||
if (foundGdtEntry == foundGdtMap->second.end())
|
||||
return nullptr;
|
||||
|
||||
return foundGdtEntry->second;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGdtQueryable.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "IZoneAssetLoaderState.h"
|
||||
#include "Obj/Gdt/Gdt.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
@ -32,15 +32,10 @@ public:
|
||||
return newStatePtr;
|
||||
}
|
||||
|
||||
private:
|
||||
void BuildGdtEntryCache();
|
||||
|
||||
public:
|
||||
Zone& m_zone;
|
||||
ISearchPath& m_raw_search_path;
|
||||
const std::vector<Gdt*> m_gdt_files;
|
||||
std::unordered_map<std::string, asset_type_t> m_ignored_asset_map;
|
||||
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, GdtEntry*>> m_entries_by_gdf_and_by_name;
|
||||
std::unordered_map<std::type_index, std::unique_ptr<IZoneAssetLoaderState>> m_zone_asset_loader_states;
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "IAssetLoadingManager.h"
|
||||
#include "IGdtQueryable.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "AssetLoaderRawFileIW3.h"
|
||||
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderAddonMapEnts.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderAddonMapEnts final : public BasicAssetLoader<AssetAddonMapEnts>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,27 +0,0 @@
|
||||
#include "AssetLoaderClipMap.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
asset_type_t AssetLoaderClipMapSp::GetHandlingAssetType() const
|
||||
{
|
||||
return ASSET_TYPE_CLIPMAP_SP;
|
||||
}
|
||||
|
||||
asset_type_t AssetLoaderClipMapMp::GetHandlingAssetType() const
|
||||
{
|
||||
return ASSET_TYPE_CLIPMAP_MP;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderClipMap : public BasicAssetLoaderWithoutType<clipMap_t>
|
||||
{
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
|
||||
class AssetLoaderClipMapSp final : public AssetLoaderClipMap
|
||||
{
|
||||
public:
|
||||
_NODISCARD asset_type_t GetHandlingAssetType() const override;
|
||||
};
|
||||
|
||||
class AssetLoaderClipMapMp final : public AssetLoaderClipMap
|
||||
{
|
||||
public:
|
||||
_NODISCARD asset_type_t GetHandlingAssetType() const override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderComWorld.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderComWorld final : public BasicAssetLoader<AssetComWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFont.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderFont final : public BasicAssetLoader<AssetFont>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFx.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderFx final : public BasicAssetLoader<AssetFx>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFxImpactTable.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderFxImpactTable final : public BasicAssetLoader<AssetImpactFx>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderFxWorld.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderFxWorld final : public BasicAssetLoader<AssetFxWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGameWorldMp.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderGameWorldMp::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* gameWorld = memory->Create<GameWorldMp>();
|
||||
memset(gameWorld, 0, sizeof(GameWorldMp));
|
||||
gameWorld->name = memory->Dup(assetName.c_str());
|
||||
return gameWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderGameWorldMp final : public BasicAssetLoader<AssetGameWorldMp>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGameWorldSp.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderGameWorldSp::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* gameWorld = memory->Create<GameWorldSp>();
|
||||
memset(gameWorld, 0, sizeof(GameWorldSp));
|
||||
gameWorld->name = memory->Dup(assetName.c_str());
|
||||
return gameWorld;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderGameWorldSp final : public BasicAssetLoader<AssetGameWorldSp>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGfxImage.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderGfxImage::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* image = memory->Create<GfxImage>();
|
||||
memset(image, 0, sizeof(GfxImage));
|
||||
image->name = memory->Dup(assetName.c_str());
|
||||
return image;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderGfxImage final : public BasicAssetLoader<AssetImage>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,72 +0,0 @@
|
||||
#include "AssetLoaderGfxLightDef.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
std::string AssetLoaderGfxLightDef::GetAssetFilename(const std::string& assetName)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "lights/" << assetName;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AssetLoaderGfxLightDef::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderGfxLightDef::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto filename = GetAssetFilename(assetName);
|
||||
const auto file = searchPath->Open(filename);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char);
|
||||
if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE)
|
||||
return false;
|
||||
|
||||
std::string imageName(static_cast<size_t>(imageNameSize), '\0');
|
||||
|
||||
int8_t samplerState;
|
||||
int8_t lmapLookupStart;
|
||||
file.m_stream->read(reinterpret_cast<char*>(&samplerState), sizeof(int8_t));
|
||||
file.m_stream->read(&imageName[0], static_cast<size_t>(imageNameSize));
|
||||
file.m_stream->read(reinterpret_cast<char*>(&lmapLookupStart), sizeof(int8_t));
|
||||
|
||||
auto* imageDependency = manager->LoadDependency<AssetImage>(imageName);
|
||||
|
||||
if (!imageDependency)
|
||||
{
|
||||
std::cerr << "Could not load GfxLightDef \"" << assetName << "\" due to missing image \"" << imageName << "\"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* lightDef = memory->Create<GfxLightDef>();
|
||||
lightDef->name = memory->Dup(assetName.c_str());
|
||||
lightDef->attenuation.samplerState = samplerState;
|
||||
lightDef->attenuation.image = imageDependency->Asset();
|
||||
lightDef->lmapLookupStart = static_cast<int>(static_cast<uint8_t>(lmapLookupStart));
|
||||
|
||||
manager->AddAsset<AssetLightDef>(assetName, lightDef);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderGfxLightDef final : public BasicAssetLoader<AssetLightDef>
|
||||
{
|
||||
static constexpr auto MAX_IMAGE_NAME_SIZE = 0x800;
|
||||
|
||||
static std::string GetAssetFilename(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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderGfxWorld.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderGfxWorld final : public BasicAssetLoader<AssetGfxWorld>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,43 +0,0 @@
|
||||
#include "AssetLoaderLeaderboard.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/Leaderboard/JsonLeaderboardDefLoader.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderLoadedSound.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderLoadedSound final : public BasicAssetLoader<AssetLoadedSound>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderMapEnts.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderMapEnts final : public BasicAssetLoader<AssetMapEnts>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderMaterial final : public BasicAssetLoader<AssetMaterial>
|
||||
{
|
||||
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;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderMenuDef.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderMenuDef final : public BasicAssetLoader<AssetMenu>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,233 +0,0 @@
|
||||
#include "AssetLoaderMenuList.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/Menu/MenuConversionZoneStateIW4.h"
|
||||
#include "Game/IW4/Menu/MenuConverterIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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::IW4,
|
||||
[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 IW4
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderPhysCollmap.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderPhysCollmap final : public BasicAssetLoader<AssetPhysCollMap>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,134 +0,0 @@
|
||||
#include "AssetLoaderPhysPreset.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/InfoString/InfoStringToStructConverter.h"
|
||||
#include "Game/IW4/InfoString/PhysPresetFields.h"
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class InfoStringToPhysPresetConverter final : public InfoStringToStructConverter
|
||||
{
|
||||
protected:
|
||||
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
InfoStringToPhysPresetConverter(const InfoString& infoString,
|
||||
PhysPresetInfo* physPreset,
|
||||
ZoneScriptStrings& zoneScriptStrings,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager,
|
||||
const cspField_t* fields,
|
||||
const size_t fieldCount)
|
||||
: InfoStringToStructConverter(infoString, physPreset, zoneScriptStrings, memory, manager, fields, fieldCount)
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace IW4
|
||||
|
||||
void AssetLoaderPhysPreset::CopyFromPhysPresetInfo(const PhysPresetInfo* physPresetInfo, PhysPreset* physPreset)
|
||||
{
|
||||
physPreset->mass = std::clamp(physPresetInfo->mass, 1.0f, 2000.0f) * 0.001f;
|
||||
physPreset->bounce = physPresetInfo->bounce;
|
||||
|
||||
if (physPresetInfo->isFrictionInfinity != 0)
|
||||
physPreset->friction = std::numeric_limits<float>::infinity();
|
||||
else
|
||||
physPreset->friction = physPresetInfo->friction;
|
||||
|
||||
physPreset->bulletForceScale = physPresetInfo->bulletForceScale;
|
||||
physPreset->explosiveForceScale = physPresetInfo->explosiveForceScale;
|
||||
physPreset->sndAliasPrefix = physPresetInfo->sndAliasPrefix;
|
||||
physPreset->piecesSpreadFraction = physPresetInfo->piecesSpreadFraction;
|
||||
physPreset->piecesUpwardVelocity = physPresetInfo->piecesUpwardVelocity;
|
||||
physPreset->tempDefaultToCylinder = physPresetInfo->tempDefaultToCylinder != 0;
|
||||
physPreset->perSurfaceSndAlias = physPresetInfo->perSurfaceSndAlias != 0;
|
||||
}
|
||||
|
||||
bool AssetLoaderPhysPreset::LoadFromInfoString(
|
||||
const InfoString& infoString, const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone)
|
||||
{
|
||||
const auto presetInfo = std::make_unique<PhysPresetInfo>();
|
||||
memset(presetInfo.get(), 0, sizeof(PhysPresetInfo));
|
||||
InfoStringToPhysPresetConverter converter(
|
||||
infoString, presetInfo.get(), zone->m_script_strings, memory, manager, phys_preset_fields, std::extent_v<decltype(phys_preset_fields)>);
|
||||
if (!converter.Convert())
|
||||
{
|
||||
std::cout << "Failed to parse phys preset: \"" << assetName << "\"\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* physPreset = memory->Create<PhysPreset>();
|
||||
|
||||
CopyFromPhysPresetInfo(presetInfo.get(), physPreset);
|
||||
physPreset->name = memory->Dup(assetName.c_str());
|
||||
|
||||
manager->AddAsset<AssetPhysPreset>(assetName, physPreset, converter.GetDependencies(), converter.GetUsedScriptStrings());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AssetLoaderPhysPreset::CanLoadFromGdt() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderPhysPreset::LoadFromGdt(
|
||||
const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
auto* gdtEntry = gdtQueryable->GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_PHYS_PRESET, assetName);
|
||||
if (gdtEntry == nullptr)
|
||||
return false;
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
{
|
||||
std::cout << "Failed to read phys preset gdt entry: \"" << assetName << "\"\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
return LoadFromInfoString(infoString, assetName, memory, manager, zone);
|
||||
}
|
||||
|
||||
bool AssetLoaderPhysPreset::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderPhysPreset::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto fileName = "physic/" + assetName;
|
||||
const auto file = searchPath->Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, *file.m_stream))
|
||||
{
|
||||
std::cerr << "Could not parse as info string file: \"" << fileName << "\"\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
return LoadFromInfoString(infoString, assetName, memory, manager, zone);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderPhysPreset final : public BasicAssetLoader<AssetPhysPreset>
|
||||
{
|
||||
static void CopyFromPhysPresetInfo(const PhysPresetInfo* physPresetInfo, PhysPreset* physPreset);
|
||||
|
||||
static bool
|
||||
LoadFromInfoString(const InfoString& infoString, const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone);
|
||||
|
||||
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 IW4
|
@ -1,63 +0,0 @@
|
||||
#include "AssetLoaderPixelShader.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AssetLoaderPixelShader::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AssetLoaderPixelShader::GetFileNameForAsset(const std::string& assetName)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "shader_bin/ps_" << assetName << ".cso";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool AssetLoaderPixelShader::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto fileName = GetFileNameForAsset(assetName);
|
||||
const auto file = searchPath->Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
if (file.m_length % sizeof(uint32_t) != 0)
|
||||
{
|
||||
std::cerr << "Invalid pixel shader \"" << assetName << "\": Size must be dividable by " << sizeof(uint32_t) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* pixelShader = memory->Create<MaterialPixelShader>();
|
||||
pixelShader->name = memory->Dup(assetName.c_str());
|
||||
pixelShader->prog.loadDef.programSize = static_cast<uint16_t>(static_cast<size_t>(file.m_length) / sizeof(uint32_t));
|
||||
pixelShader->prog.loadDef.loadForRenderer = 0;
|
||||
pixelShader->prog.ps = nullptr;
|
||||
|
||||
auto* fileBuffer = memory->Alloc<uint32_t>(pixelShader->prog.loadDef.programSize);
|
||||
file.m_stream->read(reinterpret_cast<char*>(fileBuffer), static_cast<std::streamsize>(pixelShader->prog.loadDef.programSize) * sizeof(uint32_t));
|
||||
if (file.m_stream->gcount() != file.m_length)
|
||||
return false;
|
||||
|
||||
pixelShader->prog.loadDef.program = fileBuffer;
|
||||
manager->AddAsset<AssetPixelShader>(assetName, pixelShader);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderPixelShader final : public BasicAssetLoader<AssetPixelShader>
|
||||
{
|
||||
public:
|
||||
_NODISCARD static std::string GetFileNameForAsset(const std::string& assetName);
|
||||
|
||||
_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 IW4
|
@ -1,80 +0,0 @@
|
||||
#include "AssetLoaderRawFile.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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->data.compressedBuffer = 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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
@ -1,63 +0,0 @@
|
||||
#include "AssetLoaderSndCurve.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "Sound/SoundCurveLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderSndCurve::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;
|
||||
}
|
||||
|
||||
bool AssetLoaderSndCurve::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderSndCurve::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto sndCurveData = sound_curve::LoadSoundCurve(manager, assetName);
|
||||
|
||||
if (!sndCurveData)
|
||||
return false;
|
||||
|
||||
if (sndCurveData->knots.size() > std::extent_v<decltype(SndCurve::knots)>)
|
||||
{
|
||||
std::cerr << "Failed to load SndCurve \"" << assetName << "\": Too many knots (" << sndCurveData->knots.size() << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* sndCurve = memory->Create<SndCurve>();
|
||||
sndCurve->filename = memory->Dup(assetName.c_str());
|
||||
sndCurve->knotCount = static_cast<uint16_t>(sndCurveData->knots.size());
|
||||
|
||||
for (auto i = 0u; i < std::extent_v<decltype(SndCurve::knots)>; i++)
|
||||
{
|
||||
if (i < sndCurveData->knots.size())
|
||||
{
|
||||
const auto& [x, y] = sndCurveData->knots[i];
|
||||
sndCurve->knots[i][0] = static_cast<float>(x);
|
||||
sndCurve->knots[i][1] = static_cast<float>(y);
|
||||
}
|
||||
else
|
||||
{
|
||||
sndCurve->knots[i][0] = 0;
|
||||
sndCurve->knots[i][1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
manager->AddAsset<AssetSoundCurve>(assetName, sndCurve);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderSndCurve final : public BasicAssetLoader<AssetSoundCurve>
|
||||
{
|
||||
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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderSoundAliasList.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderSoundAliasList final : public BasicAssetLoader<AssetSound>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,40 +0,0 @@
|
||||
#include "AssetLoaderStringTable.h"
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
#include "Game/IW4/CommonIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StringTable/StringTableLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
@ -1,220 +0,0 @@
|
||||
#include "AssetLoaderStructuredDataDefSet.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StructuredDataDef/StructuredDataDefReader.h"
|
||||
#include "Utils/Alignment.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderStructuredDataDefSet::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;
|
||||
}
|
||||
|
||||
bool AssetLoaderStructuredDataDefSet::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
StructuredDataType AssetLoaderStructuredDataDefSet::ConvertType(CommonStructuredDataType inputType)
|
||||
{
|
||||
switch (inputType.m_category)
|
||||
{
|
||||
case CommonStructuredDataTypeCategory::INT:
|
||||
return {DATA_INT, {0}};
|
||||
case CommonStructuredDataTypeCategory::BYTE:
|
||||
return {DATA_BYTE, {0}};
|
||||
case CommonStructuredDataTypeCategory::BOOL:
|
||||
return {DATA_BOOL, {0}};
|
||||
case CommonStructuredDataTypeCategory::FLOAT:
|
||||
return {DATA_FLOAT, {0}};
|
||||
case CommonStructuredDataTypeCategory::SHORT:
|
||||
return {DATA_SHORT, {0}};
|
||||
case CommonStructuredDataTypeCategory::STRING:
|
||||
return {DATA_STRING, {inputType.m_info.string_length}};
|
||||
case CommonStructuredDataTypeCategory::ENUM:
|
||||
return {DATA_ENUM, {inputType.m_info.type_index}};
|
||||
case CommonStructuredDataTypeCategory::STRUCT:
|
||||
return {DATA_STRUCT, {inputType.m_info.type_index}};
|
||||
case CommonStructuredDataTypeCategory::INDEXED_ARRAY:
|
||||
return {DATA_INDEXED_ARRAY, {inputType.m_info.type_index}};
|
||||
case CommonStructuredDataTypeCategory::ENUM_ARRAY:
|
||||
return {DATA_ENUM_ARRAY, {inputType.m_info.type_index}};
|
||||
case CommonStructuredDataTypeCategory::UNKNOWN:
|
||||
default:
|
||||
assert(false);
|
||||
return {DATA_INT, {0}};
|
||||
}
|
||||
}
|
||||
|
||||
void AssetLoaderStructuredDataDefSet::ConvertEnum(StructuredDataEnum* outputEnum, CommonStructuredDataEnum* inputEnum, MemoryManager* memory)
|
||||
{
|
||||
outputEnum->entryCount = static_cast<int>(inputEnum->m_entries.size());
|
||||
if (inputEnum->m_reserved_entry_count <= 0)
|
||||
outputEnum->reservedEntryCount = outputEnum->entryCount;
|
||||
else
|
||||
outputEnum->reservedEntryCount = inputEnum->m_reserved_entry_count;
|
||||
|
||||
inputEnum->SortEntriesByName();
|
||||
if (!inputEnum->m_entries.empty())
|
||||
{
|
||||
outputEnum->entries = memory->Alloc<StructuredDataEnumEntry>(inputEnum->m_entries.size());
|
||||
for (auto entryIndex = 0u; entryIndex < inputEnum->m_entries.size(); entryIndex++)
|
||||
{
|
||||
auto& outputEntry = outputEnum->entries[entryIndex];
|
||||
const auto& inputEntry = inputEnum->m_entries[entryIndex];
|
||||
|
||||
outputEntry.string = memory->Dup(inputEntry.m_name.c_str());
|
||||
outputEntry.index = static_cast<uint16_t>(inputEntry.m_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
outputEnum->entries = nullptr;
|
||||
}
|
||||
|
||||
void AssetLoaderStructuredDataDefSet::ConvertStruct(StructuredDataStruct* outputStruct, CommonStructuredDataStruct* inputStruct, MemoryManager* memory)
|
||||
{
|
||||
outputStruct->size = static_cast<int>(inputStruct->m_size_in_byte);
|
||||
outputStruct->bitOffset = inputStruct->m_bit_offset;
|
||||
|
||||
outputStruct->propertyCount = static_cast<int>(inputStruct->m_properties.size());
|
||||
inputStruct->SortPropertiesByName();
|
||||
if (!inputStruct->m_properties.empty())
|
||||
{
|
||||
outputStruct->properties = memory->Alloc<StructuredDataStructProperty>(inputStruct->m_properties.size());
|
||||
for (auto propertyIndex = 0u; propertyIndex < inputStruct->m_properties.size(); propertyIndex++)
|
||||
{
|
||||
auto& outputProperty = outputStruct->properties[propertyIndex];
|
||||
const auto& inputProperty = inputStruct->m_properties[propertyIndex];
|
||||
|
||||
outputProperty.name = memory->Dup(inputProperty.m_name.c_str());
|
||||
outputProperty.type = ConvertType(inputProperty.m_type);
|
||||
|
||||
if (outputProperty.type.type != DATA_BOOL)
|
||||
{
|
||||
assert(inputProperty.m_offset_in_bits % 8 == 0);
|
||||
outputProperty.offset = inputProperty.m_offset_in_bits / 8;
|
||||
}
|
||||
else
|
||||
outputProperty.offset = inputProperty.m_offset_in_bits;
|
||||
}
|
||||
}
|
||||
else
|
||||
outputStruct->properties = nullptr;
|
||||
}
|
||||
|
||||
void AssetLoaderStructuredDataDefSet::ConvertIndexedArray(StructuredDataIndexedArray* outputIndexedArray,
|
||||
const CommonStructuredDataIndexedArray* inputIndexedArray,
|
||||
MemoryManager* memory)
|
||||
{
|
||||
outputIndexedArray->arraySize = static_cast<int>(inputIndexedArray->m_element_count);
|
||||
outputIndexedArray->elementType = ConvertType(inputIndexedArray->m_array_type);
|
||||
outputIndexedArray->elementSize = utils::Align(inputIndexedArray->m_element_size_in_bits, 8u) / 8u;
|
||||
}
|
||||
|
||||
void AssetLoaderStructuredDataDefSet::ConvertEnumedArray(StructuredDataEnumedArray* outputEnumedArray,
|
||||
const CommonStructuredDataEnumedArray* inputEnumedArray,
|
||||
MemoryManager* memory)
|
||||
{
|
||||
outputEnumedArray->enumIndex = static_cast<int>(inputEnumedArray->m_enum_index);
|
||||
outputEnumedArray->elementType = ConvertType(inputEnumedArray->m_array_type);
|
||||
outputEnumedArray->elementSize = utils::Align(inputEnumedArray->m_element_size_in_bits, 8u) / 8u;
|
||||
}
|
||||
|
||||
void AssetLoaderStructuredDataDefSet::ConvertDef(StructuredDataDef* outputDef, const CommonStructuredDataDef* inputDef, MemoryManager* memory)
|
||||
{
|
||||
outputDef->version = inputDef->m_version;
|
||||
outputDef->formatChecksum = inputDef->m_checksum;
|
||||
|
||||
outputDef->enumCount = static_cast<int>(inputDef->m_enums.size());
|
||||
if (!inputDef->m_enums.empty())
|
||||
{
|
||||
outputDef->enums = memory->Alloc<StructuredDataEnum>(inputDef->m_enums.size());
|
||||
for (auto enumIndex = 0u; enumIndex < inputDef->m_enums.size(); enumIndex++)
|
||||
ConvertEnum(&outputDef->enums[enumIndex], inputDef->m_enums[enumIndex].get(), memory);
|
||||
}
|
||||
else
|
||||
outputDef->enums = nullptr;
|
||||
|
||||
outputDef->structCount = static_cast<int>(inputDef->m_structs.size());
|
||||
if (!inputDef->m_structs.empty())
|
||||
{
|
||||
outputDef->structs = memory->Alloc<StructuredDataStruct>(inputDef->m_structs.size());
|
||||
for (auto structIndex = 0u; structIndex < inputDef->m_structs.size(); structIndex++)
|
||||
ConvertStruct(&outputDef->structs[structIndex], inputDef->m_structs[structIndex].get(), memory);
|
||||
}
|
||||
else
|
||||
outputDef->structs = nullptr;
|
||||
|
||||
outputDef->indexedArrayCount = static_cast<int>(inputDef->m_indexed_arrays.size());
|
||||
if (!inputDef->m_indexed_arrays.empty())
|
||||
{
|
||||
outputDef->indexedArrays = memory->Alloc<StructuredDataIndexedArray>(inputDef->m_indexed_arrays.size());
|
||||
for (auto indexedArrayIndex = 0u; indexedArrayIndex < inputDef->m_indexed_arrays.size(); indexedArrayIndex++)
|
||||
ConvertIndexedArray(&outputDef->indexedArrays[indexedArrayIndex], &inputDef->m_indexed_arrays[indexedArrayIndex], memory);
|
||||
}
|
||||
else
|
||||
outputDef->indexedArrays = nullptr;
|
||||
|
||||
outputDef->enumedArrayCount = static_cast<int>(inputDef->m_enumed_arrays.size());
|
||||
if (!inputDef->m_enumed_arrays.empty())
|
||||
{
|
||||
outputDef->enumedArrays = memory->Alloc<StructuredDataEnumedArray>(inputDef->m_enumed_arrays.size());
|
||||
for (auto enumedArrayIndex = 0u; enumedArrayIndex < inputDef->m_enumed_arrays.size(); enumedArrayIndex++)
|
||||
ConvertEnumedArray(&outputDef->enumedArrays[enumedArrayIndex], &inputDef->m_enumed_arrays[enumedArrayIndex], memory);
|
||||
}
|
||||
else
|
||||
outputDef->enumedArrays = nullptr;
|
||||
|
||||
outputDef->rootType = ConvertType(inputDef->m_root_type);
|
||||
outputDef->size = inputDef->m_size_in_byte;
|
||||
}
|
||||
|
||||
StructuredDataDefSet* AssetLoaderStructuredDataDefSet::ConvertSet(const std::string& assetName,
|
||||
const std::vector<std::unique_ptr<CommonStructuredDataDef>>& defs,
|
||||
MemoryManager* memory)
|
||||
{
|
||||
auto* set = memory->Create<StructuredDataDefSet>();
|
||||
set->name = memory->Dup(assetName.c_str());
|
||||
set->defCount = defs.size();
|
||||
set->defs = memory->Alloc<StructuredDataDef>(defs.size());
|
||||
|
||||
for (auto defIndex = 0u; defIndex < defs.size(); defIndex++)
|
||||
ConvertDef(&set->defs[defIndex], defs[defIndex].get(), memory);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
bool AssetLoaderStructuredDataDefSet::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;
|
||||
|
||||
StructuredDataDefReader reader(*file.m_stream,
|
||||
assetName,
|
||||
[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);
|
||||
});
|
||||
|
||||
bool readingDefsSuccessful;
|
||||
const auto defs = reader.ReadStructureDataDefs(readingDefsSuccessful);
|
||||
|
||||
if (readingDefsSuccessful)
|
||||
manager->AddAsset<AssetStructuredDataDef>(assetName, ConvertSet(assetName, defs, memory));
|
||||
|
||||
return true;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderStructuredDataDefSet final : public BasicAssetLoader<AssetStructuredDataDef>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
_NODISCARD bool CanLoadFromRaw() const override;
|
||||
static StructuredDataType ConvertType(CommonStructuredDataType inputType);
|
||||
static void ConvertEnum(StructuredDataEnum* outputEnum, CommonStructuredDataEnum* inputEnum, MemoryManager* memory);
|
||||
static void ConvertStruct(StructuredDataStruct* outputStruct, CommonStructuredDataStruct* inputStruct, MemoryManager* memory);
|
||||
static void ConvertIndexedArray(StructuredDataIndexedArray* outputIndexedArray,
|
||||
const CommonStructuredDataIndexedArray* inputIndexedArray,
|
||||
MemoryManager* memory);
|
||||
static void
|
||||
ConvertEnumedArray(StructuredDataEnumedArray* outputEnumedArray, const CommonStructuredDataEnumedArray* inputEnumedArray, MemoryManager* memory);
|
||||
static void ConvertDef(StructuredDataDef* outputDef, const CommonStructuredDataDef* inputDef, MemoryManager* memory);
|
||||
static StructuredDataDefSet*
|
||||
ConvertSet(const std::string& assetName, const std::vector<std::unique_ptr<CommonStructuredDataDef>>& defs, MemoryManager* memory);
|
||||
bool
|
||||
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "StateMap/StateMapDefinition.h"
|
||||
#include "Techset/TechniqueStateMapCache.h"
|
||||
#include "Techset/TechsetDefinition.h"
|
||||
#include "Techset/TechsetDefinitionCache.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderTechniqueSet final : public BasicAssetLoader<AssetTechniqueSet>
|
||||
{
|
||||
static bool CreateTechsetFromDefinition(const std::string& assetName,
|
||||
const techset::TechsetDefinition& definition,
|
||||
ISearchPath* searchPath,
|
||||
MemoryManager* memory,
|
||||
IAssetLoadingManager* manager);
|
||||
|
||||
public:
|
||||
static std::string GetTechsetFileName(const std::string& techsetAssetName);
|
||||
static std::string GetTechniqueFileName(const std::string& techniqueName);
|
||||
static std::string GetStateMapFileName(const std::string& stateMapName);
|
||||
|
||||
static techset::TechsetDefinition*
|
||||
LoadTechsetDefinition(const std::string& assetName, ISearchPath* searchPath, techset::TechsetDefinitionCache* definitionCache);
|
||||
static const state_map::StateMapDefinition*
|
||||
LoadStateMapDefinition(const std::string& stateMapName, ISearchPath* searchPath, techset::TechniqueStateMapCache* stateMapCache);
|
||||
|
||||
_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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderTracer.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderTracer::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* tracer = memory->Create<TracerDef>();
|
||||
memset(tracer, 0, sizeof(TracerDef));
|
||||
tracer->name = memory->Dup(assetName.c_str());
|
||||
return tracer;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderTracer final : public BasicAssetLoader<AssetTracer>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderVehicle.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderVehicle::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* vehicle = memory->Create<VehicleDef>();
|
||||
memset(vehicle, 0, sizeof(VehicleDef));
|
||||
vehicle->name = memory->Dup(assetName.c_str());
|
||||
return vehicle;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderVehicle final : public BasicAssetLoader<AssetVehicle>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,101 +0,0 @@
|
||||
#include "AssetLoaderVertexDecl.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/TechsetConstantsIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AssetLoaderVertexDecl::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderVertexDecl::NextAbbreviation(const std::string& assetName, std::string& abbreviation, size_t& offset)
|
||||
{
|
||||
if (offset >= assetName.size())
|
||||
return false;
|
||||
|
||||
if (offset + 1 < assetName.size() && isdigit(assetName[offset + 1]))
|
||||
{
|
||||
abbreviation = std::string(assetName, offset, 2);
|
||||
offset += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
abbreviation = std::string(assetName, offset, 1);
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderVertexDecl::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
MaterialVertexDeclaration decl{};
|
||||
|
||||
size_t currentOffset = 0u;
|
||||
|
||||
if (!assetName.empty() && assetName[0] == ',')
|
||||
currentOffset = 1u;
|
||||
|
||||
std::string sourceAbbreviation;
|
||||
while (NextAbbreviation(assetName, sourceAbbreviation, currentOffset))
|
||||
{
|
||||
if (decl.streamCount >= std::extent_v<decltype(MaterialVertexStreamRouting::data)>)
|
||||
{
|
||||
std::cout << "Failed to add vertex decl stream. Too many abbreviations: " << assetName << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string destinationAbbreviation;
|
||||
if (!NextAbbreviation(assetName, destinationAbbreviation, currentOffset))
|
||||
{
|
||||
std::cout << "Failed to detect vertex decl destination abbreviation: " << assetName << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto foundSourceAbbreviation = std::ranges::find(materialStreamSourceAbbreviation, sourceAbbreviation);
|
||||
if (foundSourceAbbreviation == std::end(materialStreamSourceAbbreviation))
|
||||
{
|
||||
std::cout << "Unknown vertex decl source abbreviation: " << sourceAbbreviation << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto foundDestinationAbbreviation = std::ranges::find(materialStreamDestinationAbbreviation, destinationAbbreviation);
|
||||
if (foundDestinationAbbreviation == std::end(materialStreamDestinationAbbreviation))
|
||||
{
|
||||
std::cout << "Unknown vertex decl destination abbreviation: " << destinationAbbreviation << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto sourceIndex = static_cast<MaterialStreamStreamSource_e>(foundSourceAbbreviation - std::begin(materialStreamSourceAbbreviation));
|
||||
const auto destinationIndex =
|
||||
static_cast<MaterialStreamDestination_e>(foundDestinationAbbreviation - std::begin(materialStreamDestinationAbbreviation));
|
||||
|
||||
decl.routing.data[decl.streamCount].source = sourceIndex;
|
||||
decl.routing.data[decl.streamCount].dest = destinationIndex;
|
||||
decl.hasOptionalSource = decl.hasOptionalSource || sourceIndex >= STREAM_SRC_OPTIONAL_BEGIN;
|
||||
decl.streamCount++;
|
||||
}
|
||||
|
||||
decl.name = memory->Dup(assetName.c_str());
|
||||
|
||||
auto* allocatedDecl = memory->Create<MaterialVertexDeclaration>(decl);
|
||||
|
||||
manager->AddAsset<AssetVertexDecl>(assetName, allocatedDecl);
|
||||
return true;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderVertexDecl final : public BasicAssetLoader<AssetVertexDecl>
|
||||
{
|
||||
static bool NextAbbreviation(const std::string& assetName, std::string& abbreviation, size_t& offset);
|
||||
|
||||
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 IW4
|
@ -1,63 +0,0 @@
|
||||
#include "AssetLoaderVertexShader.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AssetLoaderVertexShader::CanLoadFromRaw() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AssetLoaderVertexShader::GetFileNameForAsset(const std::string& assetName)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "shader_bin/vs_" << assetName << ".cso";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool AssetLoaderVertexShader::LoadFromRaw(
|
||||
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto fileName = GetFileNameForAsset(assetName);
|
||||
const auto file = searchPath->Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return false;
|
||||
|
||||
if (file.m_length % sizeof(uint32_t) != 0)
|
||||
{
|
||||
std::cerr << "Invalid vertex shader \"" << assetName << "\": Size must be dividable by " << sizeof(uint32_t) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* vertexShader = memory->Create<MaterialVertexShader>();
|
||||
vertexShader->name = memory->Dup(assetName.c_str());
|
||||
vertexShader->prog.loadDef.programSize = static_cast<uint16_t>(static_cast<size_t>(file.m_length) / sizeof(uint32_t));
|
||||
vertexShader->prog.loadDef.loadForRenderer = 0;
|
||||
vertexShader->prog.vs = nullptr;
|
||||
|
||||
auto* fileBuffer = memory->Alloc<uint32_t>(vertexShader->prog.loadDef.programSize);
|
||||
file.m_stream->read(reinterpret_cast<char*>(fileBuffer), static_cast<std::streamsize>(vertexShader->prog.loadDef.programSize) * sizeof(uint32_t));
|
||||
if (file.m_stream->gcount() != file.m_length)
|
||||
return false;
|
||||
|
||||
vertexShader->prog.loadDef.program = fileBuffer;
|
||||
manager->AddAsset<AssetVertexShader>(assetName, vertexShader);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderVertexShader final : public BasicAssetLoader<AssetVertexShader>
|
||||
{
|
||||
public:
|
||||
_NODISCARD static std::string GetFileNameForAsset(const std::string& assetName);
|
||||
|
||||
_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 IW4
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderXAnim.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderXAnim final : public BasicAssetLoader<AssetXAnim>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderXModel.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
void* AssetLoaderXModel::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* model = memory->Create<XModel>();
|
||||
memset(model, 0, sizeof(XModel));
|
||||
model->name = memory->Dup(assetName.c_str());
|
||||
return model;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/BasicAssetLoader.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderXModel final : public BasicAssetLoader<AssetXModel>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,17 +0,0 @@
|
||||
#include "AssetLoaderXModelSurfs.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoaderXModelSurfs final : public BasicAssetLoader<AssetXModelSurfs>
|
||||
{
|
||||
public:
|
||||
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
|
||||
};
|
||||
} // namespace IW4
|
@ -1,6 +1,7 @@
|
||||
#include "InfoStringToStructConverter.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
@ -8,12 +9,12 @@ using namespace IW4;
|
||||
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;
|
||||
@ -145,7 +146,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (endPtr != &value[value.size()])
|
||||
{
|
||||
std::cout << "Failed to parse value \"" << value << "\" as mph\n";
|
||||
std::cerr << std::format("Failed to parse value \"{}\" as mph\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -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/IW4/IW4.h"
|
||||
#include "InfoString/InfoStringToStructConverterBase.h"
|
||||
@ -7,22 +8,22 @@ namespace IW4
|
||||
{
|
||||
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
||||
{
|
||||
protected:
|
||||
IAssetLoadingManager* m_loading_manager;
|
||||
const cspField_t* m_fields;
|
||||
size_t m_field_count;
|
||||
|
||||
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 IW4
|
||||
|
52
src/ObjLoading/Game/IW4/Leaderboard/LoaderLeaderboardIW4.cpp
Normal file
52
src/ObjLoading/Game/IW4/Leaderboard/LoaderLeaderboardIW4.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "AssetLoaderLeaderboardIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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 IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LeaderboardLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
13
src/ObjLoading/Game/IW4/Leaderboard/LoaderLeaderboardIW4.h
Normal file
13
src/ObjLoading/Game/IW4/Leaderboard/LoaderLeaderboardIW4.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
80
src/ObjLoading/Game/IW4/LightDef/LoaderLightDefIW4.cpp
Normal file
80
src/ObjLoading/Game/IW4/LightDef/LoaderLightDefIW4.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "LoaderLightDefIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto MAX_IMAGE_NAME_SIZE = 0x800;
|
||||
|
||||
class LoaderLightDef final : public AssetCreator<AssetLightDef>
|
||||
{
|
||||
public:
|
||||
LoaderLightDef(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto filename = GetAssetFilename(assetName);
|
||||
const auto file = m_search_path.Open(filename);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char);
|
||||
if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE)
|
||||
return AssetCreationResult::Failure();
|
||||
|
||||
auto* lightDef = m_memory.Alloc<GfxLightDef>();
|
||||
lightDef->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetLightDef> registration(assetName, lightDef);
|
||||
|
||||
std::string imageName(static_cast<size_t>(imageNameSize), '\0');
|
||||
|
||||
int8_t samplerState;
|
||||
int8_t lmapLookupStart;
|
||||
file.m_stream->read(reinterpret_cast<char*>(&samplerState), sizeof(int8_t));
|
||||
file.m_stream->read(&imageName[0], static_cast<size_t>(imageNameSize));
|
||||
file.m_stream->read(reinterpret_cast<char*>(&lmapLookupStart), sizeof(int8_t));
|
||||
|
||||
auto* imageDependency = context.LoadDependency<AssetImage>(imageName);
|
||||
if (!imageDependency)
|
||||
{
|
||||
std::cerr << std::format("Could not load GfxLightDef \"{}\" due to missing image \"{}\"\n", assetName, imageName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
registration.AddDependency(imageDependency);
|
||||
|
||||
lightDef->attenuation.samplerState = samplerState;
|
||||
lightDef->attenuation.image = imageDependency->Asset();
|
||||
lightDef->lmapLookupStart = static_cast<int>(static_cast<uint8_t>(lmapLookupStart));
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetAssetFilename(const std::string& assetName)
|
||||
{
|
||||
return std::format("lights/{}", assetName);
|
||||
}
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLightDef>> CreateLightDefLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LoaderLightDef>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
13
src/ObjLoading/Game/IW4/LightDef/LoaderLightDefIW4.h
Normal file
13
src/ObjLoading/Game/IW4/LightDef/LoaderLightDefIW4.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLightDef>> CreateLightDefLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
@ -1,23 +0,0 @@
|
||||
#include "AssetLoaderLocalizeIW4.h"
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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/IW4/IW4.h"
|
||||
#include "Localize/CommonLocalizeLoader.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
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 IW4
|
43
src/ObjLoading/Game/IW4/Localize/LoaderLocalizeIW4.cpp
Normal file
43
src/ObjLoading/Game/IW4/Localize/LoaderLocalizeIW4.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "AssetLoaderLocalizeIW4.h"
|
||||
#include "Localize/CommonLocalizeLoader.h"
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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 IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW4
|
14
src/ObjLoading/Game/IW4/Localize/LoaderLocalizeIW4.h
Normal file
14
src/ObjLoading/Game/IW4/Localize/LoaderLocalizeIW4.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW4
|
@ -1,4 +1,4 @@
|
||||
#include "AssetLoaderMaterial.h"
|
||||
#include "LoaderMaterialIW4.h"
|
||||
|
||||
#include "AssetLoaderTechniqueSet.h"
|
||||
#include "AssetLoading/AbstractGdtEntryReader.h"
|
||||
@ -6,21 +6,25 @@
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/MaterialConstantsIW4.h"
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "Game/IW4/Techset/LoaderTechsetIW4.h"
|
||||
#include "Game/IW4/TechsetConstantsIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "StateMap/StateMapFromTechniqueExtractor.h"
|
||||
#include "StateMap/StateMapHandler.h"
|
||||
#include "Techset/TechniqueFileReader.h"
|
||||
#include "Techset/TechniqueStateMapCache.h"
|
||||
#include "Techset/TechsetDefinitionCache.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace IW4
|
||||
namespace
|
||||
{
|
||||
class SkipMaterialException final : public std::exception
|
||||
{
|
||||
@ -29,39 +33,33 @@ namespace IW4
|
||||
class MaterialGdtLoader : AbstractGdtEntryReader
|
||||
{
|
||||
public:
|
||||
MaterialGdtLoader(const GdtEntry& entry, MemoryManager* memory, ISearchPath* searchPath, IAssetLoadingManager* manager)
|
||||
MaterialGdtLoader(const GdtEntry& entry,
|
||||
Material& material,
|
||||
MemoryManager& memory,
|
||||
ISearchPath& searchPath,
|
||||
AssetCreationContext& context,
|
||||
AssetRegistration<AssetMaterial>& registration)
|
||||
: AbstractGdtEntryReader(entry),
|
||||
m_material(material),
|
||||
m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_manager(manager),
|
||||
m_state_map_cache(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<techset::TechniqueStateMapCache>()),
|
||||
m_material(nullptr),
|
||||
m_base_state_bits{}
|
||||
m_context(context),
|
||||
m_registration(registration),
|
||||
m_state_map_cache(context.GetZoneAssetLoaderState<techset::TechniqueStateMapCache>()),
|
||||
m_base_state_bits{},
|
||||
m_techset_creator(CreateTechsetLoader(memory, searchPath))
|
||||
{
|
||||
}
|
||||
|
||||
bool Load()
|
||||
{
|
||||
m_material = m_memory->Create<Material>();
|
||||
memset(m_material, 0, sizeof(Material));
|
||||
|
||||
m_material->info.name = m_memory->Dup(m_entry.m_name.c_str());
|
||||
material_template();
|
||||
|
||||
FinalizeMaterial();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_NODISCARD Material* GetMaterial() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
_NODISCARD std::vector<XAssetInfoGeneric*> GetDependencies()
|
||||
{
|
||||
return std::move(m_dependencies);
|
||||
}
|
||||
|
||||
private:
|
||||
void material_template()
|
||||
{
|
||||
@ -120,11 +118,7 @@ namespace IW4
|
||||
custom_template();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown material type: \"" << materialType << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Unknown material type: \"{}\"", materialType));
|
||||
}
|
||||
|
||||
void mtl_phong_template()
|
||||
@ -253,7 +247,7 @@ namespace IW4
|
||||
else
|
||||
throw GdtReadingException("ColorMap may not be blank in particle cloud materials");
|
||||
|
||||
std::cout << "Using particlecloud for \"" << m_material->info.name << "\"\n";
|
||||
std::cout << std::format("Using particlecloud for \"{}\"\n", m_material.info.name);
|
||||
}
|
||||
|
||||
void mtl_tools_template()
|
||||
@ -332,11 +326,7 @@ namespace IW4
|
||||
mtl_splatter_template();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown custom template: \"" << customTemplate << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Unknown custom template: \"{}\"", customTemplate));
|
||||
}
|
||||
|
||||
void mtl_custom_template()
|
||||
@ -584,11 +574,7 @@ namespace IW4
|
||||
const auto sortKeyNum = strtoul(sortKey.c_str(), &endPtr, 10);
|
||||
|
||||
if (endPtr != &sortKey[sortKey.size()])
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid sort value: \"" << sortKey << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Invalid sort value: \"{}\"", sortKey));
|
||||
|
||||
SetSort(static_cast<unsigned char>(sortKeyNum));
|
||||
}
|
||||
@ -628,11 +614,7 @@ namespace IW4
|
||||
else if (alphaTest == GDT_ALPHA_TEST_GT0) // TODO: This is not available for IW3
|
||||
SetAlphaTest(AlphaTest_e::GT0);
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid alphatest value: \"" << alphaTest << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Invalid alphatest value: \"{}\"", alphaTest));
|
||||
}
|
||||
|
||||
void blendfunc_template()
|
||||
@ -682,9 +664,7 @@ namespace IW4
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid blendfunc value: \"" << blendFunc << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException(std::format("Invalid blendfunc value: \"{}\"", blendFunc));
|
||||
}
|
||||
}
|
||||
|
||||
@ -740,9 +720,7 @@ namespace IW4
|
||||
SetDepthWrite(false);
|
||||
else
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid depthWrite blendFunc value: \"" << blendFunc << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException(std::format("Invalid depthWrite blendFunc value: \"{}\"", blendFunc));
|
||||
}
|
||||
}
|
||||
|
||||
@ -807,28 +785,21 @@ namespace IW4
|
||||
|
||||
void SetTechniqueSet(const std::string& techsetName)
|
||||
{
|
||||
auto* techset = m_manager->LoadDependency<AssetTechniqueSet>(techsetName);
|
||||
auto* techset = m_context.LoadDependency<AssetTechniqueSet>(techsetName);
|
||||
|
||||
if (techset == nullptr)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Could not load techset: \"" << techsetName << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Could not load techset: \"{}\"", techsetName));
|
||||
|
||||
m_dependencies.push_back(techset);
|
||||
m_material->techniqueSet = techset->Asset();
|
||||
m_registration.AddDependency(techset);
|
||||
m_material.techniqueSet = techset->Asset();
|
||||
|
||||
auto* loadingContext = m_manager->GetAssetLoadingContext();
|
||||
auto& searchPath = loadingContext->m_raw_search_path;
|
||||
auto* definitionCache = loadingContext->GetZoneAssetLoaderState<techset::TechsetDefinitionCache>();
|
||||
auto* definitionCache = m_context.GetZoneAssetLoaderState<techset::TechsetDefinitionCache>();
|
||||
|
||||
const auto* techsetDefinition = AssetLoaderTechniqueSet::LoadTechsetDefinition(techsetName, &searchPath, definitionCache);
|
||||
bool failure = false;
|
||||
const auto* techsetDefinition = m_techset_creator->LoadTechsetDefinition(techsetName, m_context, failure);
|
||||
if (techsetDefinition == nullptr)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Could not find techset definition for: \"" << techsetName << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException(std::format("Could not find techset definition for: \"{}\"", techsetName));
|
||||
}
|
||||
|
||||
SetTechniqueSetStateBits(techsetDefinition);
|
||||
@ -852,17 +823,17 @@ namespace IW4
|
||||
|
||||
if (foundStateBits != m_state_bits.end())
|
||||
{
|
||||
m_material->stateBitsEntry[i] = static_cast<unsigned char>(foundStateBits - m_state_bits.begin());
|
||||
m_material.stateBitsEntry[i] = static_cast<unsigned char>(foundStateBits - m_state_bits.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->stateBitsEntry[i] = static_cast<unsigned char>(m_state_bits.size());
|
||||
m_material.stateBitsEntry[i] = static_cast<unsigned char>(m_state_bits.size());
|
||||
m_state_bits.push_back(stateBitsForTechnique);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->stateBitsEntry[i] = std::numeric_limits<unsigned char>::max();
|
||||
m_material.stateBitsEntry[i] = std::numeric_limits<unsigned char>::max();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -889,8 +860,8 @@ namespace IW4
|
||||
if (preloadedStateMap)
|
||||
return preloadedStateMap;
|
||||
|
||||
const auto techniqueFileName = AssetLoaderTechniqueSet::GetTechniqueFileName(techniqueName);
|
||||
const auto file = m_search_path->Open(techniqueFileName);
|
||||
const auto techniqueFileName = GetTechniqueFileName(techniqueName);
|
||||
const auto file = m_search_path.Open(techniqueFileName);
|
||||
if (!file.IsOpen())
|
||||
return nullptr;
|
||||
|
||||
@ -903,7 +874,7 @@ namespace IW4
|
||||
}
|
||||
|
||||
const auto stateMapName = extractor.RetrieveStateMap();
|
||||
const auto* loadedStateMap = AssetLoaderTechniqueSet::LoadStateMapDefinition(stateMapName, m_search_path, m_state_map_cache);
|
||||
const auto* loadedStateMap = m_techset_creator->LoadStateMapDefinition(stateMapName, m_context);
|
||||
m_state_map_cache->SetTechniqueUsesStateMap(techniqueName, loadedStateMap);
|
||||
|
||||
return loadedStateMap;
|
||||
@ -924,18 +895,18 @@ namespace IW4
|
||||
std::string tempName;
|
||||
if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_LIT, tempName))
|
||||
{
|
||||
if (m_material->info.sortKey >= SORTKEY_TRANS_START)
|
||||
m_material->cameraRegion = CAMERA_REGION_LIT_TRANS;
|
||||
if (m_material.info.sortKey >= SORTKEY_TRANS_START)
|
||||
m_material.cameraRegion = CAMERA_REGION_LIT_TRANS;
|
||||
else
|
||||
m_material->cameraRegion = CAMERA_REGION_LIT_OPAQUE;
|
||||
m_material.cameraRegion = CAMERA_REGION_LIT_OPAQUE;
|
||||
}
|
||||
else if (techsetDefinition->GetTechniqueByIndex(TECHNIQUE_EMISSIVE, tempName))
|
||||
{
|
||||
m_material->cameraRegion = CAMERA_REGION_EMISSIVE;
|
||||
m_material.cameraRegion = CAMERA_REGION_EMISSIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->cameraRegion = CAMERA_REGION_NONE;
|
||||
m_material.cameraRegion = CAMERA_REGION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -993,16 +964,12 @@ namespace IW4
|
||||
break;
|
||||
}
|
||||
|
||||
auto* image = m_manager->LoadDependency<AssetImage>(textureName);
|
||||
auto* image = m_context.LoadDependency<AssetImage>(textureName);
|
||||
|
||||
if (image == nullptr)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Could not load image: \"" << textureName << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
}
|
||||
throw GdtReadingException(std::format("Could not load image: \"{}\"", textureName));
|
||||
|
||||
m_dependencies.push_back(image);
|
||||
m_registration.AddDependency(image);
|
||||
textureDef.u.image = image->Asset();
|
||||
|
||||
m_textures.push_back(textureDef);
|
||||
@ -1023,13 +990,13 @@ namespace IW4
|
||||
|
||||
void SetSort(const unsigned char sort) const
|
||||
{
|
||||
m_material->info.sortKey = sort;
|
||||
m_material.info.sortKey = sort;
|
||||
}
|
||||
|
||||
void SetTextureAtlas(const unsigned char rowCount, const unsigned char columnCount) const
|
||||
{
|
||||
m_material->info.textureAtlasRowCount = rowCount;
|
||||
m_material->info.textureAtlasColumnCount = columnCount;
|
||||
m_material.info.textureAtlasRowCount = rowCount;
|
||||
m_material.info.textureAtlasColumnCount = columnCount;
|
||||
}
|
||||
|
||||
void SetAlphaTest(const AlphaTest_e alphaTest)
|
||||
@ -1054,9 +1021,7 @@ namespace IW4
|
||||
|
||||
case AlphaTest_e::UNKNOWN:
|
||||
default:
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown alphatest value: \"" << static_cast<int>(alphaTest) << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException(std::format("Unknown alphatest value: \"{}\"", static_cast<int>(alphaTest)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1113,9 +1078,7 @@ namespace IW4
|
||||
|
||||
if (colorWriteRed != colorWriteGreen || colorWriteRed != colorWriteBlue)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid ColorWrite values: values for rgb must match";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException("Invalid ColorWrite values: values for rgb must match");
|
||||
}
|
||||
|
||||
m_base_state_bits.loadBits[0] &= ~GFXS0_COLORWRITE_MASK;
|
||||
@ -1286,38 +1249,38 @@ namespace IW4
|
||||
{
|
||||
if (!m_textures.empty())
|
||||
{
|
||||
m_material->textureTable = m_memory->Alloc<MaterialTextureDef>(m_textures.size());
|
||||
m_material->textureCount = static_cast<unsigned char>(m_textures.size());
|
||||
memcpy(m_material->textureTable, m_textures.data(), sizeof(MaterialTextureDef) * m_textures.size());
|
||||
m_material.textureTable = m_memory.Alloc<MaterialTextureDef>(m_textures.size());
|
||||
m_material.textureCount = static_cast<unsigned char>(m_textures.size());
|
||||
std::memcpy(m_material.textureTable, m_textures.data(), sizeof(MaterialTextureDef) * m_textures.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->textureTable = nullptr;
|
||||
m_material->textureCount = 0u;
|
||||
m_material.textureTable = nullptr;
|
||||
m_material.textureCount = 0u;
|
||||
}
|
||||
|
||||
if (!m_constants.empty())
|
||||
{
|
||||
m_material->constantTable = m_memory->Alloc<MaterialConstantDef>(m_constants.size());
|
||||
m_material->constantCount = static_cast<unsigned char>(m_constants.size());
|
||||
memcpy(m_material->constantTable, m_constants.data(), sizeof(MaterialConstantDef) * m_constants.size());
|
||||
m_material.constantTable = m_memory.Alloc<MaterialConstantDef>(m_constants.size());
|
||||
m_material.constantCount = static_cast<unsigned char>(m_constants.size());
|
||||
std::memcpy(m_material.constantTable, m_constants.data(), sizeof(MaterialConstantDef) * m_constants.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->constantTable = nullptr;
|
||||
m_material->constantCount = 0u;
|
||||
m_material.constantTable = nullptr;
|
||||
m_material.constantCount = 0u;
|
||||
}
|
||||
|
||||
if (!m_state_bits.empty())
|
||||
{
|
||||
m_material->stateBitsTable = m_memory->Alloc<GfxStateBits>(m_state_bits.size());
|
||||
m_material->stateBitsCount = static_cast<unsigned char>(m_state_bits.size());
|
||||
memcpy(m_material->stateBitsTable, m_state_bits.data(), sizeof(GfxStateBits) * m_state_bits.size());
|
||||
m_material.stateBitsTable = m_memory.Alloc<GfxStateBits>(m_state_bits.size());
|
||||
m_material.stateBitsCount = static_cast<unsigned char>(m_state_bits.size());
|
||||
std::memcpy(m_material.stateBitsTable, m_state_bits.data(), sizeof(GfxStateBits) * m_state_bits.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_material->stateBitsTable = nullptr;
|
||||
m_material->stateBitsCount = 0u;
|
||||
m_material.stateBitsTable = nullptr;
|
||||
m_material.stateBitsCount = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1330,9 +1293,7 @@ namespace IW4
|
||||
return i;
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "Unknown " << propertyName << " value: \"" << value << "\"";
|
||||
throw GdtReadingException(ss.str());
|
||||
throw GdtReadingException(std::format("Unknown {} value: \"{}\"", propertyName, value));
|
||||
}
|
||||
|
||||
template<typename T> T ReadEnumProperty(const std::string& propertyName, const char** validValuesArray, const size_t validValuesArraySize) const
|
||||
@ -1340,59 +1301,69 @@ namespace IW4
|
||||
return static_cast<T>(GetIndexForString(propertyName, ReadStringProperty(propertyName), validValuesArray, validValuesArraySize));
|
||||
}
|
||||
|
||||
MemoryManager* m_memory;
|
||||
ISearchPath* m_search_path;
|
||||
IAssetLoadingManager* m_manager;
|
||||
Material& m_material;
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
AssetCreationContext& m_context;
|
||||
AssetRegistration<AssetMaterial>& m_registration;
|
||||
|
||||
techset::TechniqueStateMapCache* m_state_map_cache;
|
||||
std::unordered_map<const state_map::StateMapDefinition*, GfxStateBits> m_state_bits_per_state_map;
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
|
||||
Material* m_material;
|
||||
GfxStateBits m_base_state_bits;
|
||||
std::vector<GfxStateBits> m_state_bits;
|
||||
std::vector<MaterialTextureDef> m_textures;
|
||||
std::vector<MaterialConstantDef> m_constants;
|
||||
|
||||
std::unique_ptr<ITechsetCreator> m_techset_creator;
|
||||
};
|
||||
} // namespace IW4
|
||||
|
||||
void* AssetLoaderMaterial::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||
{
|
||||
auto* material = memory->Create<Material>();
|
||||
memset(material, 0, sizeof(Material));
|
||||
material->info.name = memory->Dup(assetName.c_str());
|
||||
return material;
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::CanLoadFromGdt() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetLoaderMaterial::LoadFromGdt(
|
||||
const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
|
||||
{
|
||||
const auto* entry = gdtQueryable->GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
MaterialGdtLoader loader(*entry, memory, &manager->GetAssetLoadingContext()->m_raw_search_path, manager);
|
||||
|
||||
try
|
||||
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
||||
{
|
||||
if (loader.Load())
|
||||
public:
|
||||
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
manager->AddAsset<AssetMaterial>(assetName, loader.GetMaterial(), loader.GetDependencies());
|
||||
}
|
||||
}
|
||||
catch (const SkipMaterialException&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (const GdtReadingException& e)
|
||||
{
|
||||
std::cerr << "Error while trying to load material from gdt: " << e.what() << " @ GdtEntry \"" << entry->m_name << "\"\n";
|
||||
return false;
|
||||
}
|
||||
const auto* entry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_MATERIAL, assetName);
|
||||
if (!entry)
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
return true;
|
||||
}
|
||||
auto* material = m_memory.Alloc<Material>();
|
||||
material->info.name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
|
||||
MaterialGdtLoader loader(*entry, *material, m_memory, m_search_path, context, registration);
|
||||
|
||||
try
|
||||
{
|
||||
if (loader.Load())
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
catch (const SkipMaterialException&)
|
||||
{
|
||||
return AssetCreationResult::NoAction();
|
||||
}
|
||||
catch (const GdtReadingException& e)
|
||||
{
|
||||
std::cerr << std::format("Error while trying to load material from gdt: {} @ GdtEntry \"{}\"\n", e.what(), entry->m_name);
|
||||
}
|
||||
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
IGdtQueryable& m_gdt;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath, gdt);
|
||||
}
|
||||
} // namespace IW4
|
12
src/ObjLoading/Game/IW4/Material/LoaderMaterialIW4.h
Normal file
12
src/ObjLoading/Game/IW4/Material/LoaderMaterialIW4.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt);
|
||||
} // namespace IW4
|
229
src/ObjLoading/Game/IW4/Menu/LoaderMenuListIW4.cpp
Normal file
229
src/ObjLoading/Game/IW4/Menu/LoaderMenuListIW4.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#include "AssetLoaderMenuListIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/Menu/MenuConversionZoneStateIW4.h"
|
||||
#include "Game/IW4/Menu/MenuConverterIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
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 IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MenuListLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
13
src/ObjLoading/Game/IW4/Menu/LoaderMenuListIW4.h
Normal file
13
src/ObjLoading/Game/IW4/Menu/LoaderMenuListIW4.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
@ -16,19 +16,17 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <sstream>
|
||||
|
||||
using namespace IW4;
|
||||
using namespace menu;
|
||||
|
||||
namespace IW4
|
||||
namespace
|
||||
{
|
||||
class MenuConverterImpl : public AbstractMenuConverter
|
||||
class MenuConverter : public AbstractMenuConverter, public IMenuConverter
|
||||
{
|
||||
MenuConversionZoneState* m_conversion_zone_state;
|
||||
MenuAssetZoneState* m_parsing_zone_state;
|
||||
|
||||
_NODISCARD static rectDef_s ConvertRectDef(const CommonRect& rect)
|
||||
[[nodiscard]] static rectDef_s ConvertRectDef(const CommonRect& rect)
|
||||
{
|
||||
return rectDef_s{
|
||||
static_cast<float>(rect.x),
|
||||
@ -40,7 +38,7 @@ namespace IW4
|
||||
};
|
||||
}
|
||||
|
||||
_NODISCARD static rectDef_s ConvertRectDefRelativeTo(const CommonRect& rect, const CommonRect& rectRelativeTo)
|
||||
[[nodiscard]] static rectDef_s ConvertRectDefRelativeTo(const CommonRect& rect, const CommonRect& rectRelativeTo)
|
||||
{
|
||||
return rectDef_s{
|
||||
static_cast<float>(rectRelativeTo.x + rect.x),
|
||||
@ -78,26 +76,26 @@ namespace IW4
|
||||
return input;
|
||||
}
|
||||
|
||||
_NODISCARD Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
|
||||
[[nodiscard]] Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
|
||||
{
|
||||
if (materialName.empty())
|
||||
return nullptr;
|
||||
|
||||
auto* materialDependency = m_manager->LoadDependency<AssetMaterial>(materialName);
|
||||
auto* materialDependency = m_context.LoadDependency<AssetMaterial>(materialName);
|
||||
if (!materialDependency)
|
||||
throw MenuConversionException("Failed to load material \"" + materialName + "\"", menu, item);
|
||||
throw MenuConversionException(std::format("Failed to load material \"{}\"", materialName), menu, item);
|
||||
|
||||
return materialDependency->Asset();
|
||||
}
|
||||
|
||||
_NODISCARD snd_alias_list_t* ConvertSound(const std::string& soundName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
|
||||
[[nodiscard]] snd_alias_list_t* ConvertSound(const std::string& soundName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
|
||||
{
|
||||
if (soundName.empty())
|
||||
return nullptr;
|
||||
|
||||
auto* soundDependency = m_manager->LoadDependency<AssetSound>(soundName);
|
||||
auto* soundDependency = m_context.LoadDependency<AssetSound>(soundName);
|
||||
if (!soundDependency)
|
||||
throw MenuConversionException("Failed to load sound \"" + soundName + "\"", menu, item);
|
||||
throw MenuConversionException(std::format("Failed to load sound \"{}\"", soundName), menu, item);
|
||||
|
||||
return soundDependency->Asset();
|
||||
}
|
||||
@ -416,7 +414,7 @@ namespace IW4
|
||||
if (!expression)
|
||||
return nullptr;
|
||||
|
||||
auto* statement = m_memory->Create<Statement_s>();
|
||||
auto* statement = m_memory.Alloc<Statement_s>();
|
||||
statement->lastResult = Operand{};
|
||||
statement->lastExecuteTime = 0;
|
||||
statement->supportingData = nullptr; // Supporting data is set upon using it
|
||||
@ -424,7 +422,7 @@ namespace IW4
|
||||
std::vector<expressionEntry> expressionEntries;
|
||||
ConvertExpressionEntry(statement, expressionEntries, expression, menu, item);
|
||||
|
||||
auto* outputExpressionEntries = m_memory->Alloc<expressionEntry>(expressionEntries.size());
|
||||
auto* outputExpressionEntries = m_memory.Alloc<expressionEntry>(expressionEntries.size());
|
||||
memcpy(outputExpressionEntries, expressionEntries.data(), sizeof(expressionEntry) * expressionEntries.size());
|
||||
|
||||
statement->entries = outputExpressionEntries;
|
||||
@ -481,7 +479,7 @@ namespace IW4
|
||||
switch (value.m_type)
|
||||
{
|
||||
case SimpleExpressionValue::Type::STRING:
|
||||
staticValue = m_memory->Dup(value.m_string_value->c_str());
|
||||
staticValue = m_memory.Dup(value.m_string_value->c_str());
|
||||
break;
|
||||
|
||||
case SimpleExpressionValue::Type::DOUBLE:
|
||||
@ -586,13 +584,13 @@ namespace IW4
|
||||
if (!setLocalVar)
|
||||
return;
|
||||
|
||||
auto* outputHandler = m_memory->Alloc<MenuEventHandler>();
|
||||
auto* outputSetLocalVar = m_memory->Alloc<SetLocalVarData>();
|
||||
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
|
||||
auto* outputSetLocalVar = m_memory.Alloc<SetLocalVarData>();
|
||||
|
||||
outputHandler->eventType = SetLocalVarTypeToEventType(setLocalVar->m_type);
|
||||
outputHandler->eventData.setLocalVarData = outputSetLocalVar;
|
||||
|
||||
outputSetLocalVar->localVarName = m_memory->Dup(setLocalVar->m_var_name.c_str());
|
||||
outputSetLocalVar->localVarName = m_memory.Dup(setLocalVar->m_var_name.c_str());
|
||||
outputSetLocalVar->expression = ConvertExpression(setLocalVar->m_value.get(), menu, item);
|
||||
|
||||
elements.push_back(outputHandler);
|
||||
@ -604,9 +602,9 @@ namespace IW4
|
||||
if (!script)
|
||||
return;
|
||||
|
||||
auto* outputHandler = m_memory->Create<MenuEventHandler>();
|
||||
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
|
||||
outputHandler->eventType = EVENT_UNCONDITIONAL;
|
||||
outputHandler->eventData.unconditionalScript = m_memory->Dup(script->m_script.c_str());
|
||||
outputHandler->eventData.unconditionalScript = m_memory.Dup(script->m_script.c_str());
|
||||
|
||||
elements.push_back(outputHandler);
|
||||
}
|
||||
@ -631,8 +629,8 @@ namespace IW4
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* outputHandler = m_memory->Alloc<MenuEventHandler>();
|
||||
auto* outputCondition = m_memory->Alloc<ConditionalScript>();
|
||||
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
|
||||
auto* outputCondition = m_memory.Alloc<ConditionalScript>();
|
||||
|
||||
outputHandler->eventType = EVENT_IF;
|
||||
outputHandler->eventData.conditionalScript = outputCondition;
|
||||
@ -644,7 +642,7 @@ namespace IW4
|
||||
|
||||
if (condition->m_else_elements)
|
||||
{
|
||||
auto* outputElseHandler = m_memory->Create<MenuEventHandler>();
|
||||
auto* outputElseHandler = m_memory.Alloc<MenuEventHandler>();
|
||||
outputElseHandler->eventType = EVENT_ELSE;
|
||||
outputElseHandler->eventData.elseScript = ConvertEventHandlerSet(condition->m_else_elements.get(), menu, item);
|
||||
|
||||
@ -699,8 +697,8 @@ namespace IW4
|
||||
if (elements.empty())
|
||||
return nullptr;
|
||||
|
||||
auto* outputSet = m_memory->Alloc<MenuEventHandlerSet>();
|
||||
auto* outputElements = m_memory->Alloc<MenuEventHandler*>(elements.size());
|
||||
auto* outputSet = m_memory.Alloc<MenuEventHandlerSet>();
|
||||
auto* outputElements = m_memory.Alloc<MenuEventHandler*>(elements.size());
|
||||
memcpy(outputElements, elements.data(), sizeof(void*) * elements.size());
|
||||
|
||||
outputSet->eventHandlerCount = static_cast<int>(elements.size());
|
||||
@ -717,7 +715,7 @@ namespace IW4
|
||||
return nullptr;
|
||||
|
||||
const auto keyHandlerCount = keyHandlers.size();
|
||||
auto* output = m_memory->Alloc<ItemKeyHandler>(keyHandlerCount);
|
||||
auto* output = m_memory.Alloc<ItemKeyHandler>(keyHandlerCount);
|
||||
auto currentKeyHandler = keyHandlers.cbegin();
|
||||
for (auto i = 0u; i < keyHandlerCount; i++)
|
||||
{
|
||||
@ -829,7 +827,7 @@ namespace IW4
|
||||
if (floatExpressionCount <= 0)
|
||||
return nullptr;
|
||||
|
||||
auto* floatExpressions = m_memory->Alloc<ItemFloatExpression>(floatExpressionCount);
|
||||
auto* floatExpressions = m_memory.Alloc<ItemFloatExpression>(floatExpressionCount);
|
||||
auto floatExpressionIndex = 0;
|
||||
for (const auto& [expression, expressionIsStatic, target, staticValue, staticValueArraySize, dynamicFlagsToSet] : locations)
|
||||
{
|
||||
@ -855,7 +853,7 @@ namespace IW4
|
||||
ss << "\"" << element << "\" ";
|
||||
}
|
||||
|
||||
return m_memory->Dup(ss.str().c_str());
|
||||
return m_memory.Dup(ss.str().c_str());
|
||||
}
|
||||
|
||||
_NODISCARD const char* ConvertEnableDvar(const CommonItemDef& commonItem, int& dvarFlags) const
|
||||
@ -903,7 +901,7 @@ namespace IW4
|
||||
if (commonListBox == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto* listBox = m_memory->Alloc<listBoxDef_s>();
|
||||
auto* listBox = m_memory.Alloc<listBoxDef_s>();
|
||||
listBox->notselectable = commonListBox->m_not_selectable ? 1 : 0;
|
||||
listBox->noScrollBars = commonListBox->m_no_scrollbars ? 1 : 0;
|
||||
listBox->usePaging = commonListBox->m_use_paging ? 1 : 0;
|
||||
@ -938,7 +936,7 @@ namespace IW4
|
||||
if (commonEditField == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto* editField = m_memory->Alloc<editFieldDef_s>();
|
||||
auto* editField = m_memory.Alloc<editFieldDef_s>();
|
||||
editField->defVal = static_cast<float>(commonEditField->m_def_val);
|
||||
editField->minVal = static_cast<float>(commonEditField->m_min_val);
|
||||
editField->maxVal = static_cast<float>(commonEditField->m_max_val);
|
||||
@ -958,7 +956,7 @@ namespace IW4
|
||||
if (commonMultiValue == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto* multiValue = m_memory->Alloc<multiDef_s>();
|
||||
auto* multiValue = m_memory.Alloc<multiDef_s>();
|
||||
multiValue->count = static_cast<int>(std::min(std::extent_v<decltype(multiDef_s::dvarList)>, commonMultiValue->m_step_names.size()));
|
||||
multiValue->strDef = !commonMultiValue->m_string_values.empty() ? 1 : 0;
|
||||
|
||||
@ -989,7 +987,7 @@ namespace IW4
|
||||
if (commonNewsTicker == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto* newsTicker = m_memory->Alloc<newsTickerDef_s>();
|
||||
auto* newsTicker = m_memory.Alloc<newsTickerDef_s>();
|
||||
newsTicker->spacing = commonNewsTicker->m_spacing;
|
||||
newsTicker->speed = commonNewsTicker->m_speed;
|
||||
newsTicker->feedId = commonNewsTicker->m_news_feed_id;
|
||||
@ -999,8 +997,7 @@ namespace IW4
|
||||
|
||||
_NODISCARD itemDef_s* ConvertItem(const CommonMenuDef& parentMenu, const CommonItemDef& commonItem) const
|
||||
{
|
||||
auto* item = m_memory->Create<itemDef_s>();
|
||||
memset(item, 0, sizeof(itemDef_s));
|
||||
auto* item = m_memory.Alloc<itemDef_s>();
|
||||
|
||||
item->window.name = ConvertString(commonItem.m_name);
|
||||
item->text = ConvertString(commonItem.m_text);
|
||||
@ -1087,7 +1084,7 @@ namespace IW4
|
||||
case CommonItemFeatureType::NONE:
|
||||
default:
|
||||
if (item->type == ITEM_TYPE_TEXT_SCROLL)
|
||||
item->typeData.scroll = m_memory->Alloc<textScrollDef_s>();
|
||||
item->typeData.scroll = m_memory.Alloc<textScrollDef_s>();
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1103,7 +1100,7 @@ namespace IW4
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* items = m_memory->Alloc<itemDef_s*>(commonMenu.m_items.size());
|
||||
auto* items = m_memory.Alloc<itemDef_s*>(commonMenu.m_items.size());
|
||||
for (auto i = 0u; i < commonMenu.m_items.size(); i++)
|
||||
items[i] = ConvertItem(commonMenu, *commonMenu.m_items[i]);
|
||||
|
||||
@ -1113,98 +1110,75 @@ namespace IW4
|
||||
}
|
||||
|
||||
public:
|
||||
MenuConverterImpl(const bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager)
|
||||
: AbstractMenuConverter(disableOptimizations, searchPath, memory, manager),
|
||||
m_conversion_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<MenuConversionZoneState>()),
|
||||
m_parsing_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<MenuAssetZoneState>())
|
||||
MenuConverter(const bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context)
|
||||
: AbstractMenuConverter(disableOptimizations, searchPath, memory, context),
|
||||
m_conversion_zone_state(context.GetZoneAssetLoaderState<MenuConversionZoneState>()),
|
||||
m_parsing_zone_state(context.GetZoneAssetLoaderState<MenuAssetZoneState>())
|
||||
{
|
||||
assert(m_conversion_zone_state);
|
||||
assert(m_parsing_zone_state);
|
||||
}
|
||||
|
||||
_NODISCARD menuDef_t* ConvertMenu(const CommonMenuDef& commonMenu) const
|
||||
void ConvertMenu(const menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration<AssetMenu>& registration) override
|
||||
{
|
||||
auto* menu = m_memory->Create<menuDef_t>();
|
||||
memset(menu, 0, sizeof(menuDef_t));
|
||||
|
||||
menu->window.name = m_memory->Dup(commonMenu.m_name.c_str());
|
||||
menu->fullScreen = commonMenu.m_full_screen;
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_screen_space, WINDOW_FLAG_SCREEN_SPACE);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_decoration, WINDOW_FLAG_DECORATION);
|
||||
menu->window.rect = ConvertRectDef(commonMenu.m_rect);
|
||||
menu->window.style = commonMenu.m_style;
|
||||
menu->window.border = commonMenu.m_border;
|
||||
menu->window.borderSize = static_cast<float>(commonMenu.m_border_size);
|
||||
ConvertColor(menu->window.backColor, commonMenu.m_back_color);
|
||||
ConvertColor(menu->window.foreColor, commonMenu.m_fore_color);
|
||||
ConvertColor(menu->window.borderColor, commonMenu.m_border_color);
|
||||
ConvertColor(menu->focusColor, commonMenu.m_focus_color);
|
||||
menu->window.background = ConvertMaterial(commonMenu.m_background, &commonMenu);
|
||||
menu->window.ownerDraw = commonMenu.m_owner_draw;
|
||||
menu->window.ownerDrawFlags = commonMenu.m_owner_draw_flags;
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_out_of_bounds_click, WINDOW_FLAG_OUT_OF_BOUNDS_CLICK);
|
||||
menu->soundName = ConvertString(commonMenu.m_sound_loop);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP);
|
||||
menu->fadeClamp = static_cast<float>(commonMenu.m_fade_clamp);
|
||||
menu->fadeCycle = commonMenu.m_fade_cycle;
|
||||
menu->fadeAmount = static_cast<float>(commonMenu.m_fade_amount);
|
||||
menu->fadeInAmount = static_cast<float>(commonMenu.m_fade_in_amount);
|
||||
menu->blurRadius = static_cast<float>(commonMenu.m_blur_radius);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_legacy_split_screen_scale, WINDOW_FLAG_LEGACY_SPLIT_SCREEN_SCALE);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_scope, WINDOW_FLAG_HIDDEN_DURING_SCOPE);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_flashbang, WINDOW_FLAG_HIDDEN_DURING_FLASH_BANG);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_ui, WINDOW_FLAG_HIDDEN_DURING_UI);
|
||||
menu->allowedBinding = ConvertString(commonMenu.m_allowed_binding);
|
||||
ApplyFlag(menu->window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS);
|
||||
menu->visibleExp = ConvertVisibleExpression(&menu->window, commonMenu.m_visible_expression.get(), &commonMenu);
|
||||
menu->rectXExp = ConvertOrApplyStatement(menu->window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu);
|
||||
menu->rectYExp = ConvertOrApplyStatement(menu->window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu);
|
||||
menu->rectWExp = ConvertOrApplyStatement(menu->window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu);
|
||||
menu->rectHExp = ConvertOrApplyStatement(menu->window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu);
|
||||
menu->openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu);
|
||||
menu->closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu);
|
||||
menu->onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu);
|
||||
menu->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu);
|
||||
menu->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu);
|
||||
menu->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu);
|
||||
menu->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu);
|
||||
menu->items = ConvertMenuItems(commonMenu, menu->itemCount);
|
||||
menu->expressionData = m_conversion_zone_state->m_supporting_data;
|
||||
|
||||
return menu;
|
||||
try
|
||||
{
|
||||
menu.window.name = m_memory.Dup(commonMenu.m_name.c_str());
|
||||
menu.fullScreen = commonMenu.m_full_screen;
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_screen_space, WINDOW_FLAG_SCREEN_SPACE);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_decoration, WINDOW_FLAG_DECORATION);
|
||||
menu.window.rect = ConvertRectDef(commonMenu.m_rect);
|
||||
menu.window.style = commonMenu.m_style;
|
||||
menu.window.border = commonMenu.m_border;
|
||||
menu.window.borderSize = static_cast<float>(commonMenu.m_border_size);
|
||||
ConvertColor(menu.window.backColor, commonMenu.m_back_color);
|
||||
ConvertColor(menu.window.foreColor, commonMenu.m_fore_color);
|
||||
ConvertColor(menu.window.borderColor, commonMenu.m_border_color);
|
||||
ConvertColor(menu.focusColor, commonMenu.m_focus_color);
|
||||
menu.window.background = ConvertMaterial(commonMenu.m_background, &commonMenu);
|
||||
menu.window.ownerDraw = commonMenu.m_owner_draw;
|
||||
menu.window.ownerDrawFlags = commonMenu.m_owner_draw_flags;
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_out_of_bounds_click, WINDOW_FLAG_OUT_OF_BOUNDS_CLICK);
|
||||
menu.soundName = ConvertString(commonMenu.m_sound_loop);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP);
|
||||
menu.fadeClamp = static_cast<float>(commonMenu.m_fade_clamp);
|
||||
menu.fadeCycle = commonMenu.m_fade_cycle;
|
||||
menu.fadeAmount = static_cast<float>(commonMenu.m_fade_amount);
|
||||
menu.fadeInAmount = static_cast<float>(commonMenu.m_fade_in_amount);
|
||||
menu.blurRadius = static_cast<float>(commonMenu.m_blur_radius);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_legacy_split_screen_scale, WINDOW_FLAG_LEGACY_SPLIT_SCREEN_SCALE);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_scope, WINDOW_FLAG_HIDDEN_DURING_SCOPE);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_flashbang, WINDOW_FLAG_HIDDEN_DURING_FLASH_BANG);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_ui, WINDOW_FLAG_HIDDEN_DURING_UI);
|
||||
menu.allowedBinding = ConvertString(commonMenu.m_allowed_binding);
|
||||
ApplyFlag(menu.window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS);
|
||||
menu.visibleExp = ConvertVisibleExpression(&menu.window, commonMenu.m_visible_expression.get(), &commonMenu);
|
||||
menu.rectXExp = ConvertOrApplyStatement(menu.window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu);
|
||||
menu.rectYExp = ConvertOrApplyStatement(menu.window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu);
|
||||
menu.rectWExp = ConvertOrApplyStatement(menu.window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu);
|
||||
menu.rectHExp = ConvertOrApplyStatement(menu.window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu);
|
||||
menu.openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu);
|
||||
menu.closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu);
|
||||
menu.onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu);
|
||||
menu.onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu);
|
||||
menu.onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu);
|
||||
menu.onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu);
|
||||
menu.onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu);
|
||||
menu.items = ConvertMenuItems(commonMenu, menu.itemCount);
|
||||
menu.expressionData = m_conversion_zone_state->m_supporting_data;
|
||||
}
|
||||
catch (const MenuConversionException& e)
|
||||
{
|
||||
PrintConversionExceptionDetails(e);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
MenuConversionZoneState* m_conversion_zone_state;
|
||||
MenuAssetZoneState* m_parsing_zone_state;
|
||||
};
|
||||
} // namespace IW4
|
||||
} // namespace
|
||||
|
||||
MenuConverter::MenuConverter(const bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager)
|
||||
: m_disable_optimizations(disableOptimizations),
|
||||
m_search_path(searchPath),
|
||||
m_memory(memory),
|
||||
m_manager(manager)
|
||||
std::unique_ptr<IMenuConverter> IMenuConverter::Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<XAssetInfoGeneric*>& MenuConverter::GetDependencies()
|
||||
{
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
menuDef_t* MenuConverter::ConvertMenu(const CommonMenuDef& commonMenu)
|
||||
{
|
||||
MenuConverterImpl impl(m_disable_optimizations, m_search_path, m_memory, m_manager);
|
||||
|
||||
try
|
||||
{
|
||||
auto* result = impl.ConvertMenu(commonMenu);
|
||||
m_dependencies = std::move(impl.m_dependencies);
|
||||
return result;
|
||||
}
|
||||
catch (const MenuConversionException& e)
|
||||
{
|
||||
MenuConverterImpl::PrintConversionExceptionDetails(e);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return std::make_unique<MenuConverter>(disableOptimizations, searchPath, memory, context);
|
||||
}
|
||||
|
@ -1,26 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssetLoading/IAssetLoadingManager.h"
|
||||
#include "Asset/AssetCreationContext.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Parsing/Menu/Domain/CommonMenuDef.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class MenuConverter
|
||||
class IMenuConverter
|
||||
{
|
||||
bool m_disable_optimizations;
|
||||
ISearchPath* m_search_path;
|
||||
MemoryManager* m_memory;
|
||||
IAssetLoadingManager* m_manager;
|
||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||
|
||||
public:
|
||||
MenuConverter(bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager);
|
||||
IMenuConverter() = default;
|
||||
virtual ~IMenuConverter() = default;
|
||||
|
||||
std::vector<XAssetInfoGeneric*>& GetDependencies();
|
||||
_NODISCARD menuDef_t* ConvertMenu(const menu::CommonMenuDef& commonMenu);
|
||||
virtual void ConvertMenu(const menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration<AssetMenu>& registration) = 0;
|
||||
|
||||
static std::unique_ptr<IMenuConverter> Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context);
|
||||
};
|
||||
} // namespace IW4
|
||||
|
@ -3,8 +3,24 @@
|
||||
#include "Asset/GlobalAssetPoolsLoader.h"
|
||||
#include "Game/IW4/GameIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Localize/AssetLoaderLocalizeIW4.h"
|
||||
#include "Leaderboard/LoaderLeaderboardIW4.h"
|
||||
#include "LightDef/LoaderLightDefIW4.h"
|
||||
#include "Localize/LoaderLocalizeIW4.h"
|
||||
#include "Material/LoaderMaterialIW4.h"
|
||||
#include "Menu/LoaderMenuListIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "PhysPreset/GdtLoaderPhysPresetIW4.h"
|
||||
#include "PhysPreset/RawLoaderPhysPresetIW4.h"
|
||||
#include "RawFile/LoaderRawFileIW4.h"
|
||||
#include "Shader/LoaderPixelShaderIW4.h"
|
||||
#include "Shader/LoaderVertexShaderIW4.h"
|
||||
#include "Sound/LoaderSoundCurveIW4.h"
|
||||
#include "StringTable/LoaderStringTableIW4.h"
|
||||
#include "StructuredDataDef/LoaderStructuredDataDefIW4.h"
|
||||
#include "Techset/LoaderTechsetIW4.h"
|
||||
#include "Techset/LoaderVertexDeclIW4.h"
|
||||
#include "Weapon/GdtLoaderWeaponIW4.h"
|
||||
#include "Weapon/RawLoaderWeaponIW4.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -100,23 +116,24 @@ namespace
|
||||
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetAddonMapEnts>>(zone));
|
||||
}
|
||||
|
||||
void ConfigureLoaders(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath)
|
||||
void ConfigureLoaders(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt)
|
||||
{
|
||||
auto& memory = *zone.GetMemory();
|
||||
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysPreset>(memory));
|
||||
collection.AddAssetCreator(std::make_unique<RawLoaderPhysPreset>(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(std::make_unique<GdtLoaderPhysPreset>(memory, gdt, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysCollMap>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModelSurfs>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModel>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMaterial>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPixelShader>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVertexShader>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVertexDecl>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechniqueSet>(memory));
|
||||
collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath, gdt));
|
||||
collection.AddAssetCreator(CreatePixelShaderLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateVertexShaderLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateVertexDeclLoader(memory));
|
||||
collection.AddAssetCreator(CreateTechsetLoader(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImage>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSound>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundCurve>(memory));
|
||||
collection.AddAssetCreator(CreateSoundCurveLoader(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLoadedSound>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderClipMapSp>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderClipMapMp>(memory));
|
||||
@ -126,27 +143,28 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMapEnts>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFxWorld>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderGfxWorld>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLightDef>(memory));
|
||||
collection.AddAssetCreator(CreateLightDefLoader(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
|
||||
collection.AddAssetCreator(CreateMenuListLoader(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||
collection.AddAssetCreator(std::make_unique<AssetLoaderLocalize>(memory, searchPath, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderWeapon>(memory));
|
||||
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateRawWeaponLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateGdtWeaponLoader(memory, searchPath, gdt, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderRawFile>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderStringTable>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLeaderboard>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderStructuredDataDef>(memory));
|
||||
collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateLeaderboardLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStructuredDataDefLoader(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTracer>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVehicle>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderAddonMapEnts>(memory));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath) const
|
||||
void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt) const
|
||||
{
|
||||
ConfigureDefaultCreators(collection, zone);
|
||||
ConfigureLoaders(collection, zone, searchPath);
|
||||
ConfigureLoaders(collection, zone, searchPath, gdt);
|
||||
ConfigureGlobalAssetPoolsLoaders(collection, zone);
|
||||
}
|
||||
|
@ -13,6 +13,6 @@ namespace IW4
|
||||
void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override;
|
||||
void UnloadContainersOfZone(Zone& zone) const override;
|
||||
|
||||
void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath) const override;
|
||||
void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt) const override;
|
||||
};
|
||||
} // namespace IW4
|
||||
|
@ -0,0 +1,35 @@
|
||||
#include "GdtLoaderPhysPresetIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderPhysPresetIW4.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
GdtLoaderPhysPreset::GdtLoaderPhysPreset(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_gdt(gdt),
|
||||
m_zone(zone)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult GdtLoaderPhysPreset::CreateAsset(const std::string& assetName, AssetCreationContext& context)
|
||||
{
|
||||
auto* gdtEntry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_PHYS_PRESET, assetName);
|
||||
if (gdtEntry == nullptr)
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
{
|
||||
std::cerr << std::format("Failed to read phys preset gdt entry: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
InfoStringLoaderPhysPreset infoStringLoader(m_memory, m_zone);
|
||||
return infoStringLoader.CreateAsset(assetName, infoString, context);
|
||||
}
|
22
src/ObjLoading/Game/IW4/PhysPreset/GdtLoaderPhysPresetIW4.h
Normal file
22
src/ObjLoading/Game/IW4/PhysPreset/GdtLoaderPhysPresetIW4.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class GdtLoaderPhysPreset final : public AssetCreator<AssetPhysPreset>
|
||||
{
|
||||
public:
|
||||
GdtLoaderPhysPreset(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
IGdtQueryable& m_gdt;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW4
|
@ -0,0 +1,86 @@
|
||||
#include "InfoStringLoaderPhysPresetIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/InfoString/InfoStringToStructConverter.h"
|
||||
#include "Game/IW4/PhysPreset/PhysPresetFields.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
namespace
|
||||
{
|
||||
class InfoStringToPhysPresetConverter final : public InfoStringToStructConverter
|
||||
{
|
||||
public:
|
||||
InfoStringToPhysPresetConverter(const InfoString& infoString,
|
||||
void* structure,
|
||||
ZoneScriptStrings& zoneScriptStrings,
|
||||
MemoryManager& memory,
|
||||
AssetCreationContext& context,
|
||||
GenericAssetRegistration& registration,
|
||||
const cspField_t* fields,
|
||||
size_t fieldCount)
|
||||
: InfoStringToStructConverter(infoString, structure, zoneScriptStrings, memory, context, registration, fields, fieldCount)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void CopyFromPhysPresetInfo(const PhysPresetInfo& physPresetInfo, PhysPreset& physPreset)
|
||||
{
|
||||
physPreset.mass = std::clamp(physPresetInfo.mass, 1.0f, 2000.0f) * 0.001f;
|
||||
physPreset.bounce = physPresetInfo.bounce;
|
||||
|
||||
if (physPresetInfo.isFrictionInfinity != 0)
|
||||
physPreset.friction = std::numeric_limits<float>::infinity();
|
||||
else
|
||||
physPreset.friction = physPresetInfo.friction;
|
||||
|
||||
physPreset.bulletForceScale = physPresetInfo.bulletForceScale;
|
||||
physPreset.explosiveForceScale = physPresetInfo.explosiveForceScale;
|
||||
physPreset.sndAliasPrefix = physPresetInfo.sndAliasPrefix;
|
||||
physPreset.piecesSpreadFraction = physPresetInfo.piecesSpreadFraction;
|
||||
physPreset.piecesUpwardVelocity = physPresetInfo.piecesUpwardVelocity;
|
||||
physPreset.tempDefaultToCylinder = physPresetInfo.tempDefaultToCylinder != 0;
|
||||
physPreset.perSurfaceSndAlias = physPresetInfo.perSurfaceSndAlias != 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
InfoStringLoaderPhysPreset::InfoStringLoaderPhysPreset(MemoryManager& memory, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_zone(zone)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult InfoStringLoaderPhysPreset::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
||||
{
|
||||
PhysPresetInfo presetInfo;
|
||||
std::memset(&presetInfo, 0, sizeof(presetInfo));
|
||||
|
||||
auto* physPreset = m_memory.Alloc<PhysPreset>();
|
||||
AssetRegistration<AssetPhysPreset> registration(assetName, physPreset);
|
||||
|
||||
InfoStringToPhysPresetConverter converter(
|
||||
infoString, &presetInfo, m_zone.m_script_strings, m_memory, context, registration, phys_preset_fields, std::extent_v<decltype(phys_preset_fields)>);
|
||||
if (!converter.Convert())
|
||||
{
|
||||
std::cerr << std::format("Failed to parse phys preset: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CopyFromPhysPresetInfo(presetInfo, *physPreset);
|
||||
physPreset->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
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