From a36581b06e0460e1b47d455178dc6964b9bbbaf6 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 28 Dec 2024 21:12:24 +0100 Subject: [PATCH] chore: fix loading and writing code for IW5 --- .../IW5/{InfoString => Weapon}/WeaponFields.h | 0 src/ObjLoading/Asset/AssetCreationContext.h | 2 +- src/ObjLoading/Asset/AssetCreationResult.cpp | 3 + .../AssetLoading/AssetLoadingManager.cpp | 176 ---------- .../AssetLoading/AssetLoadingManager.h | 31 -- .../AssetLoaders/AssetLoaderAddonMapEnts.cpp | 17 - .../AssetLoaders/AssetLoaderAddonMapEnts.h | 14 - .../IW5/AssetLoaders/AssetLoaderClipMap.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderClipMap.h | 13 - .../IW5/AssetLoaders/AssetLoaderComWorld.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderComWorld.h | 14 - .../Game/IW5/AssetLoaders/AssetLoaderFont.cpp | 17 - .../Game/IW5/AssetLoaders/AssetLoaderFont.h | 14 - .../Game/IW5/AssetLoaders/AssetLoaderFx.cpp | 17 - .../Game/IW5/AssetLoaders/AssetLoaderFx.h | 14 - .../AssetLoaders/AssetLoaderFxImpactTable.cpp | 17 - .../AssetLoaders/AssetLoaderFxImpactTable.h | 14 - .../IW5/AssetLoaders/AssetLoaderFxWorld.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderFxWorld.h | 14 - .../IW5/AssetLoaders/AssetLoaderGfxImage.cpp | 60 ---- .../IW5/AssetLoaders/AssetLoaderGfxImage.h | 17 - .../AssetLoaders/AssetLoaderGfxLightDef.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderGfxLightDef.h | 14 - .../IW5/AssetLoaders/AssetLoaderGfxWorld.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderGfxWorld.h | 14 - .../AssetLoaders/AssetLoaderGlassWorld.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderGlassWorld.h | 14 - .../AssetLoaders/AssetLoaderLeaderboard.cpp | 43 --- .../IW5/AssetLoaders/AssetLoaderLeaderboard.h | 17 - .../AssetLoaders/AssetLoaderLoadedSound.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderLoadedSound.h | 14 - .../IW5/AssetLoaders/AssetLoaderMapEnts.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderMapEnts.h | 14 - .../IW5/AssetLoaders/AssetLoaderMaterial.cpp | 57 ---- .../IW5/AssetLoaders/AssetLoaderMaterial.h | 19 -- .../IW5/AssetLoaders/AssetLoaderMenuDef.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderMenuDef.h | 14 - .../IW5/AssetLoaders/AssetLoaderMenuList.cpp | 233 -------------- .../IW5/AssetLoaders/AssetLoaderMenuList.h | 19 -- .../IW5/AssetLoaders/AssetLoaderPathData.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderPathData.h | 14 - .../AssetLoaders/AssetLoaderPhysCollmap.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderPhysCollmap.h | 14 - .../AssetLoaders/AssetLoaderPhysPreset.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderPhysPreset.h | 14 - .../AssetLoaders/AssetLoaderPixelShader.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderPixelShader.h | 14 - .../IW5/AssetLoaders/AssetLoaderRawFile.cpp | 80 ----- .../IW5/AssetLoaders/AssetLoaderRawFile.h | 19 -- .../AssetLoaders/AssetLoaderScriptFile.cpp | 78 ----- .../IW5/AssetLoaders/AssetLoaderScriptFile.h | 17 - .../AssetLoaderSoundAliasList.cpp | 17 - .../AssetLoaders/AssetLoaderSoundAliasList.h | 14 - .../AssetLoaders/AssetLoaderSoundCurve.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderSoundCurve.h | 14 - .../AssetLoaders/AssetLoaderStringTable.cpp | 40 --- .../IW5/AssetLoaders/AssetLoaderStringTable.h | 17 - .../AssetLoaderStructuredDataDef.cpp | 17 - .../AssetLoaderStructuredDataDef.h | 14 - .../AssetLoaderSurfaceFxTable.cpp | 17 - .../AssetLoaders/AssetLoaderSurfaceFxTable.h | 14 - .../AssetLoaders/AssetLoaderTechniqueSet.cpp | 17 - .../AssetLoaders/AssetLoaderTechniqueSet.h | 14 - .../IW5/AssetLoaders/AssetLoaderTracerDef.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderTracerDef.h | 14 - .../AssetLoaders/AssetLoaderVehicleDef.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderVehicleDef.h | 14 - .../AssetLoaders/AssetLoaderVehicleTrack.cpp | 17 - .../AssetLoaders/AssetLoaderVehicleTrack.h | 14 - .../AssetLoaders/AssetLoaderVertexDecl.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderVertexDecl.h | 14 - .../AssetLoaders/AssetLoaderVertexShader.cpp | 17 - .../AssetLoaders/AssetLoaderVertexShader.h | 14 - .../Game/IW5/AssetLoaders/AssetLoaderWeapon.h | 20 -- .../AssetLoaderWeaponAttachment.cpp | 45 --- .../AssetLoaderWeaponAttachment.h | 17 - .../IW5/AssetLoaders/AssetLoaderXAnim.cpp | 17 - .../Game/IW5/AssetLoaders/AssetLoaderXAnim.h | 14 - .../IW5/AssetLoaders/AssetLoaderXModel.cpp | 47 --- .../Game/IW5/AssetLoaders/AssetLoaderXModel.h | 19 -- .../AssetLoaders/AssetLoaderXModelSurfs.cpp | 17 - .../IW5/AssetLoaders/AssetLoaderXModelSurfs.h | 14 - .../Game/IW5/Image/LoaderImageIW5.cpp | 69 ++++ .../Game/IW5/Image/LoaderImageIW5.h | 13 + .../InfoStringToStructConverter.cpp | 45 +-- .../InfoString/InfoStringToStructConverter.h | 23 +- .../Leaderboard/JsonLeaderboardDefLoader.cpp | 4 +- .../Leaderboard/JsonLeaderboardDefLoader.h | 2 +- .../IW5/Leaderboard/LoaderLeaderboardIW5.cpp | 53 +++ .../IW5/Leaderboard/LoaderLeaderboardIW5.h | 13 + .../IW5/Localize/AssetLoaderLocalizeIW5.cpp | 23 -- .../IW5/Localize/AssetLoaderLocalizeIW5.h | 25 -- .../Game/IW5/Localize/LoaderLocalizeIW5.cpp | 44 +++ .../Game/IW5/Localize/LoaderLocalizeIW5.h | 14 + .../Game/IW5/Material/JsonMaterialLoader.cpp | 23 +- .../Game/IW5/Material/JsonMaterialLoader.h | 5 +- .../Game/IW5/Material/LoaderMaterialIW5.cpp | 70 ++++ .../Game/IW5/Material/LoaderMaterialIW5.h | 13 + .../Game/IW5/Menu/LoaderMenuListIW5.cpp | 230 +++++++++++++ .../Game/IW5/Menu/LoaderMenuListIW5.h | 13 + .../Game/IW5/Menu/MenuConverterIW5.cpp | 302 ++++++++--------- .../Game/IW5/Menu/MenuConverterIW5.h | 19 +- src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp | 42 ++- src/ObjLoading/Game/IW5/ObjLoaderIW5.h | 2 +- .../Game/IW5/RawFile/LoaderRawFileIW5.cpp | 90 ++++++ .../Game/IW5/RawFile/LoaderRawFileIW5.h | 13 + .../Game/IW5/Script/LoaderScriptFileIW5.cpp | 88 +++++ .../Game/IW5/Script/LoaderScriptFileIW5.h | 13 + .../IW5/StringTable/LoaderStringTableIW5.cpp | 49 +++ .../IW5/StringTable/LoaderStringTableIW5.h | 13 + .../Game/IW5/Weapon/GdtLoaderWeaponIW5.cpp | 53 +++ .../Game/IW5/Weapon/GdtLoaderWeaponIW5.h | 14 + .../InfoStringLoaderWeaponIW5.cpp} | 303 ++++++++---------- .../IW5/Weapon/InfoStringLoaderWeaponIW5.h | 21 ++ .../IW5/Weapon/JsonWeaponAttachmentLoader.cpp | 44 ++- .../IW5/Weapon/JsonWeaponAttachmentLoader.h | 10 +- .../Game/IW5/Weapon/LoaderAttachmentIW5.cpp | 54 ++++ .../Game/IW5/Weapon/LoaderAttachmentIW5.h | 13 + .../Game/IW5/Weapon/RawLoaderWeaponIW5.cpp | 54 ++++ .../Game/IW5/Weapon/RawLoaderWeaponIW5.h | 13 + .../Game/IW5/XModel/LoaderXModelIW5asdf.cpp | 55 ++++ .../Game/IW5/XModel/LoaderXModelIW5asdf.h | 13 + ...cpp.template => LoaderXModel.cpp.template} | 98 +++--- src/ObjLoading/XModel/LoaderXModel.h.template | 19 ++ .../XModel/PartClassificationState.cpp | 4 +- .../XModel/PartClassificationState.h | 13 +- src/ObjLoading/XModel/XModelLoader.h.template | 19 -- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 2 +- 128 files changed, 1554 insertions(+), 2535 deletions(-) rename src/ObjCommon/Game/IW5/{InfoString => Weapon}/WeaponFields.h (100%) delete mode 100644 src/ObjLoading/AssetLoading/AssetLoadingManager.cpp delete mode 100644 src/ObjLoading/AssetLoading/AssetLoadingManager.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.h delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.cpp delete mode 100644 src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.h create mode 100644 src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h create mode 100644 src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h delete mode 100644 src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.cpp delete mode 100644 src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.h create mode 100644 src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h create mode 100644 src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h create mode 100644 src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h create mode 100644 src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.h create mode 100644 src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.h create mode 100644 src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.h create mode 100644 src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.h rename src/ObjLoading/Game/IW5/{AssetLoaders/AssetLoaderWeapon.cpp => Weapon/InfoStringLoaderWeaponIW5.cpp} (71%) create mode 100644 src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.h create mode 100644 src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.h create mode 100644 src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.h create mode 100644 src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.cpp create mode 100644 src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.h rename src/ObjLoading/XModel/{XModelLoader.cpp.template => LoaderXModel.cpp.template} (92%) create mode 100644 src/ObjLoading/XModel/LoaderXModel.h.template delete mode 100644 src/ObjLoading/XModel/XModelLoader.h.template diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/Weapon/WeaponFields.h similarity index 100% rename from src/ObjCommon/Game/IW5/InfoString/WeaponFields.h rename to src/ObjCommon/Game/IW5/Weapon/WeaponFields.h diff --git a/src/ObjLoading/Asset/AssetCreationContext.h b/src/ObjLoading/Asset/AssetCreationContext.h index 804edff5..b8d3e23d 100644 --- a/src/ObjLoading/Asset/AssetCreationContext.h +++ b/src/ObjLoading/Asset/AssetCreationContext.h @@ -61,7 +61,7 @@ public: { static_assert(std::is_base_of_v); - return LoadIndirectAssetReferenceInternal(AssetType::EnumEntry, assetName); + return LoadIndirectAssetReferenceGeneric(AssetType::EnumEntry, assetName); } IndirectAssetReference LoadIndirectAssetReferenceGeneric(asset_type_t assetType, const std::string& assetName); diff --git a/src/ObjLoading/Asset/AssetCreationResult.cpp b/src/ObjLoading/Asset/AssetCreationResult.cpp index cc4ad30d..0a804b11 100644 --- a/src/ObjLoading/Asset/AssetCreationResult.cpp +++ b/src/ObjLoading/Asset/AssetCreationResult.cpp @@ -1,7 +1,10 @@ #include "AssetCreationResult.h" +#include + AssetCreationResult AssetCreationResult::Success(XAssetInfoGeneric* assetInfo) { + assert(assetInfo); return AssetCreationResult(true, assetInfo); } diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp deleted file mode 100644 index b3d0b492..00000000 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "AssetLoadingManager.h" - -#include "Utils/StringUtils.h" - -#include -#include -#include - -AssetLoadingManager::AssetLoadingManager(const std::unordered_map>& assetLoadersByType, - AssetLoadingContext& context) - : m_asset_loaders_by_type(assetLoadersByType), - m_context(context), - m_last_dependency_loaded(nullptr) -{ -} - -bool AssetLoadingManager::LoadAssetFromLoader(const asset_type_t assetType, const std::string& assetName) -{ - return LoadDependency(assetType, assetName) != nullptr; -} - -AssetLoadingContext* AssetLoadingManager::GetAssetLoadingContext() const -{ - return &m_context; -} - -XAssetInfoGeneric* AssetLoadingManager::AddAssetInternal(std::unique_ptr xAssetInfo) -{ - const auto assetType = xAssetInfo->m_type; - const auto* pAssetName = xAssetInfo->m_name.c_str(); - - m_last_dependency_loaded = m_context.m_zone.m_pools->AddAsset(std::move(xAssetInfo)); - if (m_last_dependency_loaded == nullptr) - std::cerr << std::format("Failed to add asset of type \"{}\" to pool: \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType), pAssetName); - - return m_last_dependency_loaded; -} - -XAssetInfoGeneric* AssetLoadingManager::AddAsset(std::unique_ptr xAssetInfo) -{ - xAssetInfo->m_zone = &m_context.m_zone; - return AddAssetInternal(std::move(xAssetInfo)); -} - -XAssetInfoGeneric* AssetLoadingManager::LoadIgnoredDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader) -{ - auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName); - if (alreadyLoadedAsset) - return alreadyLoadedAsset; - - auto* linkAsset = loader->CreateEmptyAsset(assetName, m_context.m_zone.GetMemory()); - if (linkAsset) - { - AddAsset(std::make_unique(assetType, assetName, linkAsset)); - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName); - if (existingAsset) - { - AddAssetInternal(std::make_unique(*existingAsset)); - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - std::cerr << std::format("Failed to create empty asset \"{}\" for type \"{}\"\n", assetName, *m_context.m_zone.m_pools->GetAssetTypeName(assetType)); - return nullptr; -} - -XAssetInfoGeneric* AssetLoadingManager::LoadAssetDependency(const asset_type_t assetType, const std::string& assetName, const IAssetLoader* loader) -{ - if (loader->CanLoadFromGdt() && !m_context.m_gdt_files.empty() - && loader->LoadFromGdt(assetName, &m_context, m_context.m_zone.GetMemory(), this, &m_context.m_zone)) - { - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - if (loader->CanLoadFromRaw() && loader->LoadFromRaw(assetName, &m_context.m_raw_search_path, m_context.m_zone.GetMemory(), this, &m_context.m_zone)) - { - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName); - if (!existingAsset && !assetName.empty() && assetName[0] != ',') - existingAsset = loader->LoadFromGlobalAssetPools(',' + assetName); - - if (existingAsset) - { - std::vector dependencies; - std::vector indirectAssetReferences; - for (const auto* dependency : existingAsset->m_dependencies) - { - auto* newDependency = LoadDependency(dependency->m_type, dependency->m_name); - if (newDependency) - dependencies.push_back(newDependency); - else - return nullptr; - } - - indirectAssetReferences.reserve(existingAsset->m_indirect_asset_references.size()); - for (const auto& indirectAssetReference : existingAsset->m_indirect_asset_references) - indirectAssetReferences.emplace_back(LoadIndirectAssetReference(indirectAssetReference.m_type, indirectAssetReference.m_name)); - - // Make sure any used script string is available in the created zone - // The replacement of the scr_string_t values will be done upon writing - for (const auto scrString : existingAsset->m_used_script_strings) - m_context.m_zone.m_script_strings.AddOrGetScriptString(existingAsset->m_zone->m_script_strings.CValue(scrString)); - - AddAssetInternal(std::make_unique(existingAsset->m_type, - existingAsset->m_name, - existingAsset->m_ptr, - std::move(dependencies), - existingAsset->m_used_script_strings, - std::move(indirectAssetReferences), - existingAsset->m_zone)); - - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - std::cerr << std::format("Failed to load asset of type \"{}\": \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType), assetName); - return nullptr; -} - -XAssetInfoGeneric* AssetLoadingManager::LoadDependency(const asset_type_t assetType, const std::string& assetName) -{ - auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName); - if (alreadyLoadedAsset) - return alreadyLoadedAsset; - - const auto loader = m_asset_loaders_by_type.find(assetType); - if (loader != m_asset_loaders_by_type.end()) - { - const auto ignoreEntry = m_context.m_ignored_asset_map.find(assetName); - if (ignoreEntry != m_context.m_ignored_asset_map.end() && ignoreEntry->second == assetType) - { - const auto linkAssetName = std::format(",{}", assetName); - - return LoadIgnoredDependency(assetType, linkAssetName, loader->second.get()); - } - - return LoadAssetDependency(assetType, assetName, loader->second.get()); - } - - std::cerr << std::format("Failed to find loader for asset type \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType)); - return nullptr; -} - -IndirectAssetReference AssetLoadingManager::LoadIndirectAssetReference(const asset_type_t assetType, const std::string& assetName) -{ - const auto* alreadyLoadedAsset = m_context.m_zone.m_pools->GetAssetOrAssetReference(assetType, assetName); - if (alreadyLoadedAsset) - return IndirectAssetReference(assetType, assetName); - - const auto ignoreEntry = m_context.m_ignored_asset_map.find(assetName); - if (ignoreEntry != m_context.m_ignored_asset_map.end() && ignoreEntry->second == assetType) - return IndirectAssetReference(assetType, assetName); - - const auto loader = m_asset_loaders_by_type.find(assetType); - if (loader != m_asset_loaders_by_type.end()) - { - LoadAssetDependency(assetType, assetName, loader->second.get()); - return IndirectAssetReference(assetType, assetName); - } - - std::cerr << std::format("Failed to find loader for asset type \"{}\"\n", *m_context.m_zone.m_pools->GetAssetTypeName(assetType)); - return IndirectAssetReference(assetType, assetName); -} diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.h b/src/ObjLoading/AssetLoading/AssetLoadingManager.h deleted file mode 100644 index 47e1dcec..00000000 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "AssetLoadingContext.h" -#include "IAssetLoader.h" -#include "IAssetLoadingManager.h" - -#include - -class AssetLoadingManager final : public IAssetLoadingManager -{ -public: - AssetLoadingManager(const std::unordered_map>& assetLoadersByType, AssetLoadingContext& context); - - bool LoadAssetFromLoader(asset_type_t assetType, const std::string& assetName); - - [[nodiscard]] AssetLoadingContext* GetAssetLoadingContext() const override; - - XAssetInfoGeneric* AddAsset(std::unique_ptr xAssetInfo) override; - XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) override; - IndirectAssetReference LoadIndirectAssetReference(asset_type_t assetType, const std::string& assetName) override; - -private: - XAssetInfoGeneric* LoadIgnoredDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader); - XAssetInfoGeneric* LoadAssetDependency(asset_type_t assetType, const std::string& assetName, const IAssetLoader* loader); - - XAssetInfoGeneric* AddAssetInternal(std::unique_ptr xAssetInfo); - - const std::unordered_map>& m_asset_loaders_by_type; - AssetLoadingContext& m_context; - XAssetInfoGeneric* m_last_dependency_loaded; -}; diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.cpp deleted file mode 100644 index c3109c50..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderAddonMapEnts.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderAddonMapEnts::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* addonMapEnts = memory->Create(); - memset(addonMapEnts, 0, sizeof(AddonMapEnts)); - addonMapEnts->name = memory->Dup(assetName.c_str()); - return addonMapEnts; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.h deleted file mode 100644 index a1b308ac..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderAddonMapEnts.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderAddonMapEnts final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.cpp deleted file mode 100644 index 3f0e93b0..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderClipMap.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderClipMap::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* clipMap = memory->Create(); - memset(clipMap, 0, sizeof(clipMap_t)); - clipMap->name = memory->Dup(assetName.c_str()); - return clipMap; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.h deleted file mode 100644 index 8b4d0d75..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderClipMap.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderClipMap : public BasicAssetLoader - { - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.cpp deleted file mode 100644 index 6cb25175..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderComWorld.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderComWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* comWorld = memory->Create(); - memset(comWorld, 0, sizeof(ComWorld)); - comWorld->name = memory->Dup(assetName.c_str()); - return comWorld; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.h deleted file mode 100644 index a491a99f..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderComWorld.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderComWorld final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.cpp deleted file mode 100644 index 121d92dc..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderFont.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderFont::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* font = memory->Create(); - memset(font, 0, sizeof(Font_s)); - font->fontName = memory->Dup(assetName.c_str()); - return font; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.h deleted file mode 100644 index ff08dd9f..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFont.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderFont final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.cpp deleted file mode 100644 index 613ec05f..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderFx.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderFx::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* fx = memory->Create(); - memset(fx, 0, sizeof(FxEffectDef)); - fx->name = memory->Dup(assetName.c_str()); - return fx; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.h deleted file mode 100644 index 1040158d..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFx.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderFx final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.cpp deleted file mode 100644 index f6a4c7bf..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderFxImpactTable.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderFxImpactTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* fxImpactTable = memory->Create(); - memset(fxImpactTable, 0, sizeof(FxImpactTable)); - fxImpactTable->name = memory->Dup(assetName.c_str()); - return fxImpactTable; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.h deleted file mode 100644 index 577fe178..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxImpactTable.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderFxImpactTable final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.cpp deleted file mode 100644 index 45b83494..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderFxWorld.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderFxWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* fxWorld = memory->Create(); - memset(fxWorld, 0, sizeof(FxWorld)); - fxWorld->name = memory->Dup(assetName.c_str()); - return fxWorld; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.h deleted file mode 100644 index 5e7005af..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderFxWorld.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderFxWorld final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.cpp deleted file mode 100644 index e6a1948e..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "AssetLoaderGfxImage.h" - -#include "Game/IW5/IW5.h" -#include "Image/IwiLoader.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderGfxImage::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* asset = memory->Alloc(); - asset->name = memory->Dup(assetName.c_str()); - return asset; -} - -bool AssetLoaderGfxImage::CanLoadFromRaw() const -{ - return true; -} - -bool AssetLoaderGfxImage::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto fileName = std::format("images/{}.iwi", assetName); - const auto file = searchPath->Open(fileName); - if (!file.IsOpen()) - return false; - - const auto fileSize = static_cast(file.m_length); - const auto fileData = std::make_unique(fileSize); - file.m_stream->read(fileData.get(), fileSize); - - std::istringstream ss(std::string(fileData.get(), fileSize)); - const auto texture = iwi::LoadIwi(ss); - if (!texture) - { - std::cerr << std::format("Failed to load texture from: {}\n", fileName); - return false; - } - - auto* image = memory->Create(); - memset(image, 0, sizeof(GfxImage)); - - image->name = memory->Dup(assetName.c_str()); - image->noPicmip = !texture->HasMipMaps(); - image->width = static_cast(texture->GetWidth()); - image->height = static_cast(texture->GetHeight()); - image->depth = static_cast(texture->GetDepth()); - - image->texture.loadDef = memory->Alloc(); - - manager->AddAsset(assetName, image); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.h deleted file mode 100644 index 7f2bec24..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxImage.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderGfxImage final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.cpp deleted file mode 100644 index d2bf64d3..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderGfxLightDef.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderGfxLightDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* lightDef = memory->Create(); - memset(lightDef, 0, sizeof(GfxLightDef)); - lightDef->name = memory->Dup(assetName.c_str()); - return lightDef; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.h deleted file mode 100644 index 7bb44a97..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxLightDef.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderGfxLightDef final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.cpp deleted file mode 100644 index 40775533..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderGfxWorld.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderGfxWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* gfxWorld = memory->Create(); - memset(gfxWorld, 0, sizeof(GfxWorld)); - gfxWorld->name = memory->Dup(assetName.c_str()); - return gfxWorld; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.h deleted file mode 100644 index d967cc06..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGfxWorld.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderGfxWorld final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.cpp deleted file mode 100644 index 418a844b..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderGlassWorld.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderGlassWorld::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* glassWorld = memory->Create(); - memset(glassWorld, 0, sizeof(GlassWorld)); - glassWorld->name = memory->Dup(assetName.c_str()); - return glassWorld; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.h deleted file mode 100644 index 6fb2162b..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderGlassWorld.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderGlassWorld final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.cpp deleted file mode 100644 index 25b25e48..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "AssetLoaderLeaderboard.h" - -#include "Game/IW5/IW5.h" -#include "Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderLeaderboard::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* leaderboard = memory->Create(); - 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->name = memory->Dup(assetName.c_str()); - - if (LoadLeaderboardAsJson(*file.m_stream, *leaderboardDef, memory)) - manager->AddAsset(assetName, leaderboardDef); - else - std::cerr << std::format("Failed to load leaderboard \"{}\"\n", assetName); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.h deleted file mode 100644 index 50c7cf72..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLeaderboard.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderLeaderboard final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.cpp deleted file mode 100644 index 26a1106d..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderLoadedSound.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderLoadedSound::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* loadedSound = memory->Create(); - memset(loadedSound, 0, sizeof(LoadedSound)); - loadedSound->name = memory->Dup(assetName.c_str()); - return loadedSound; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.h deleted file mode 100644 index cf6f0ca0..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLoadedSound.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderLoadedSound final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.cpp deleted file mode 100644 index 07f7781e..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderMapEnts.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderMapEnts::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* mapEnts = memory->Create(); - memset(mapEnts, 0, sizeof(MapEnts)); - mapEnts->name = memory->Dup(assetName.c_str()); - return mapEnts; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.h deleted file mode 100644 index 783d475a..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMapEnts.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderMapEnts final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.cpp deleted file mode 100644 index 13170e20..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "AssetLoaderMaterial.h" - -#include "Game/IW5/IW5.h" -#include "Game/IW5/Material/JsonMaterialLoader.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderMaterial::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* asset = memory->Alloc(); - asset->info.name = memory->Dup(assetName.c_str()); - return asset; -} - -bool AssetLoaderMaterial::CanLoadFromRaw() const -{ - return true; -} - -std::string AssetLoaderMaterial::GetFileNameForAsset(const std::string& assetName) -{ - std::string sanitizedFileName(assetName); - if (sanitizedFileName[0] == '*') - { - std::ranges::replace(sanitizedFileName, '*', '_'); - const auto parenthesisPos = sanitizedFileName.find('('); - if (parenthesisPos != std::string::npos) - sanitizedFileName.erase(parenthesisPos); - sanitizedFileName = "generated/" + sanitizedFileName; - } - - return std::format("materials/{}.json", sanitizedFileName); -} - -bool AssetLoaderMaterial::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto file = searchPath->Open(GetFileNameForAsset(assetName)); - if (!file.IsOpen()) - return false; - - auto* material = memory->Alloc(); - material->info.name = memory->Dup(assetName.c_str()); - - std::vector dependencies; - if (LoadMaterialAsJson(*file.m_stream, *material, memory, manager, dependencies)) - manager->AddAsset(assetName, material, std::move(dependencies)); - else - std::cerr << std::format("Failed to load material \"{}\"\n", assetName); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.h deleted file mode 100644 index f9f45d71..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMaterial.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderMaterial final : public BasicAssetLoader - { - static std::string GetFileNameForAsset(const std::string& assetName); - - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.cpp deleted file mode 100644 index dbbddba7..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderMenuDef.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderMenuDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* menu = memory->Create(); - memset(menu, 0, sizeof(menuDef_t)); - menu->window.name = memory->Dup(assetName.c_str()); - return menu; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.h deleted file mode 100644 index 24764024..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuDef.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderMenuDef final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.cpp deleted file mode 100644 index ce698821..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "AssetLoaderMenuList.h" - -#include "Game/IW5/IW5.h" -#include "Game/IW5/Menu/MenuConversionZoneStateIW5.h" -#include "Game/IW5/Menu/MenuConverterIW5.h" -#include "ObjLoading.h" -#include "Parsing/Menu/MenuFileReader.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include - -using namespace IW5; - -namespace IW5 -{ - class MenuLoader - { - public: - static bool ProcessParsedResults(const std::string& fileName, - ISearchPath* searchPath, - MemoryManager* memory, - IAssetLoadingManager* manager, - menu::ParsingResult* parsingResult, - menu::MenuAssetZoneState* zoneState, - MenuConversionZoneState* conversionState, - std::vector& menus, - std::vector& 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*> 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(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& menus) - { - auto* menuListAsset = memory->Create(); - menuListAsset->name = memory->Dup(assetName.c_str()); - menuListAsset->menuCount = static_cast(menus.size()); - - if (menuListAsset->menuCount > 0) - { - menuListAsset->menus = memory->Alloc(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 - ParseMenuFile(const std::string& menuFileName, ISearchPath* searchPath, const menu::MenuAssetZoneState* zoneState) - { - const auto file = searchPath->Open(menuFileName); - if (!file.IsOpen()) - return nullptr; - - menu::MenuFileReader reader(*file.m_stream, - menuFileName, - menu::FeatureLevel::IW5, - [searchPath](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr - { - auto foundFileToInclude = searchPath->Open(filename); - if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream) - return nullptr; - - return std::move(foundFileToInclude.m_stream); - }); - - reader.IncludeZoneState(zoneState); - reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing); - - return reader.ReadMenuFile(); - } - }; -} // namespace IW5 - -void* AssetLoaderMenuList::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* menuList = memory->Create(); - memset(menuList, 0, sizeof(MenuList)); - menuList->name = memory->Dup(assetName.c_str()); - return menuList; -} - -bool AssetLoaderMenuList::CanLoadFromRaw() const -{ - return true; -} - -bool BuildMenuFileQueue(std::deque& menuLoadQueue, - const std::string& menuListAssetName, - ISearchPath* searchPath, - MemoryManager* memory, - IAssetLoadingManager* manager, - menu::MenuAssetZoneState* zoneState, - MenuConversionZoneState* conversionState, - std::vector& menus, - std::vector& 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& menus, - std::vector& 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 menus; - std::vector menuListDependencies; - - auto* zoneState = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); - auto* conversionState = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); - - std::deque 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(assetName, menuListAsset, menuListDependencies); - - return true; -} - -void AssetLoaderMenuList::FinalizeAssetsForZone(AssetLoadingContext& context) const -{ - context.GetZoneAssetLoaderState()->FinalizeSupportingData(); -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.h deleted file mode 100644 index 00f42417..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderMenuList.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderMenuList final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - void FinalizeAssetsForZone(AssetLoadingContext& context) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.cpp deleted file mode 100644 index e9959372..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderPathData.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderPathData::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* pathData = memory->Create(); - memset(pathData, 0, sizeof(PathData)); - pathData->name = memory->Dup(assetName.c_str()); - return pathData; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.h deleted file mode 100644 index 700b0baf..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPathData.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderPathData final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.cpp deleted file mode 100644 index 544ad3ea..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderPhysCollmap.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderPhysCollmap::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* collmap = memory->Create(); - memset(collmap, 0, sizeof(PhysCollmap)); - collmap->name = memory->Dup(assetName.c_str()); - return collmap; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.h deleted file mode 100644 index 08d76909..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysCollmap.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderPhysCollmap final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.cpp deleted file mode 100644 index ecfa646b..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderPhysPreset.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderPhysPreset::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* physPreset = memory->Create(); - memset(physPreset, 0, sizeof(PhysPreset)); - physPreset->name = memory->Dup(assetName.c_str()); - return physPreset; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.h deleted file mode 100644 index 59abe996..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPhysPreset.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderPhysPreset final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.cpp deleted file mode 100644 index 787118a7..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderPixelShader.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderPixelShader::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* pixelShader = memory->Create(); - memset(pixelShader, 0, sizeof(MaterialPixelShader)); - pixelShader->name = memory->Dup(assetName.c_str()); - return pixelShader; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.h deleted file mode 100644 index 47bc4253..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderPixelShader.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderPixelShader final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp deleted file mode 100644 index b1a9a0a7..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "AssetLoaderRawFile.h" - -#include "Game/IW5/IW5.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* rawFile = memory->Create(); - 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(static_cast(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(file.m_length + COMPRESSED_BUFFER_SIZE_PADDING); - auto* compressedBuffer = memory->Alloc(compressionBufferSize); - - z_stream_s zs{}; - - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - zs.avail_in = static_cast(file.m_length); - zs.avail_out = compressionBufferSize; - zs.next_in = reinterpret_cast(uncompressedBuffer.get()); - zs.next_out = reinterpret_cast(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->name = memory->Dup(assetName.c_str()); - rawFile->compressedLen = static_cast(compressedSize); - rawFile->len = static_cast(file.m_length); - rawFile->buffer = static_cast(compressedBuffer); - - deflateEnd(&zs); - - manager->AddAsset(assetName, rawFile); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h deleted file mode 100644 index 94d235ef..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderRawFile final : public BasicAssetLoader - { - static constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64; - - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.cpp deleted file mode 100644 index 84d4a8bb..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "AssetLoaderScriptFile.h" - -#include "Game/IW5/IW5.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderScriptFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* scriptFile = memory->Create(); - memset(scriptFile, 0, sizeof(ScriptFile)); - scriptFile->name = memory->Dup(assetName.c_str()); - return scriptFile; -} - -bool AssetLoaderScriptFile::CanLoadFromRaw() const -{ - return true; -} - -// See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format -bool AssetLoaderScriptFile::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto file = searchPath->Open(assetName + ".gscbin"); - if (!file.IsOpen()) - return false; - - const auto fileBuffer = std::make_unique(static_cast(file.m_length)); - file.m_stream->read(fileBuffer.get(), file.m_length); - if (file.m_stream->gcount() != file.m_length) - return false; - - auto* scriptFile = memory->Create(); - scriptFile->name = memory->Dup(assetName.c_str()); - - // Retrieve data from the buffer - size_t offset = 0; - - // Read past the name pointer, we will use the one from assetName - offset += strlen(fileBuffer.get()) + 1; - - memcpy(&scriptFile->compressedLen, fileBuffer.get() + offset, sizeof(scriptFile->compressedLen)); - offset += sizeof(scriptFile->compressedLen); - - memcpy(&scriptFile->len, fileBuffer.get() + offset, sizeof(scriptFile->len)); - offset += sizeof(scriptFile->len); - - memcpy(&scriptFile->bytecodeLen, fileBuffer.get() + offset, sizeof(scriptFile->bytecodeLen)); - offset += sizeof(scriptFile->bytecodeLen); - - if (scriptFile->compressedLen <= 0 || scriptFile->bytecodeLen <= 0) - { - std::cerr << "Error: Invalid length of the buffers in " << assetName << " specified\n"; - return false; - } - - if (offset + (scriptFile->compressedLen + scriptFile->bytecodeLen) > file.m_length) - { - std::cerr << "Error: Specified length in " << assetName << " GSC BIN structure exceeds the actual file size\n"; - return false; - } - - scriptFile->buffer = memory->Alloc(scriptFile->compressedLen); - memcpy(const_cast(scriptFile->buffer), fileBuffer.get() + offset, scriptFile->compressedLen); - offset += scriptFile->compressedLen; - - scriptFile->bytecode = memory->Alloc(scriptFile->bytecodeLen); - memcpy(scriptFile->bytecode, fileBuffer.get() + offset, scriptFile->bytecodeLen); - - manager->AddAsset(assetName, scriptFile); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.h deleted file mode 100644 index 3cb47778..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderScriptFile final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.cpp deleted file mode 100644 index 0a581719..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderSoundAliasList.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderSoundAliasList::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* sndAliasList = memory->Create(); - memset(sndAliasList, 0, sizeof(snd_alias_list_t)); - sndAliasList->aliasName = memory->Dup(assetName.c_str()); - return sndAliasList; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.h deleted file mode 100644 index 7301d230..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundAliasList.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderSoundAliasList final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.cpp deleted file mode 100644 index 5d786501..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderSoundCurve.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderSoundCurve::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* sndCurve = memory->Create(); - memset(sndCurve, 0, sizeof(SndCurve)); - sndCurve->filename = memory->Dup(assetName.c_str()); - return sndCurve; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.h deleted file mode 100644 index 15ced190..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSoundCurve.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderSoundCurve final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.cpp deleted file mode 100644 index c91eceb9..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "AssetLoaderStringTable.h" - -#include "Csv/CsvStream.h" -#include "Game/IW5/CommonIW5.h" -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" -#include "StringTable/StringTableLoader.h" - -#include - -using namespace IW5; - -void* AssetLoaderStringTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* stringTable = memory->Create(); - 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 loader; - auto* stringTable = loader.LoadFromStream(assetName, *memory, *file.m_stream); - - manager->AddAsset(assetName, stringTable); - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.h deleted file mode 100644 index 80d1ce74..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStringTable.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderStringTable final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.cpp deleted file mode 100644 index bc52d984..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderStructuredDataDef.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderStructuredDataDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* structuredDataDefSet = memory->Create(); - memset(structuredDataDefSet, 0, sizeof(StructuredDataDefSet)); - structuredDataDefSet->name = memory->Dup(assetName.c_str()); - return structuredDataDefSet; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.h deleted file mode 100644 index 901d589e..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderStructuredDataDef.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderStructuredDataDef final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.cpp deleted file mode 100644 index 82cfd398..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderSurfaceFxTable.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderSurfaceFxTable::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* surfaceFxTable = memory->Create(); - memset(surfaceFxTable, 0, sizeof(SurfaceFxTable)); - surfaceFxTable->name = memory->Dup(assetName.c_str()); - return surfaceFxTable; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.h deleted file mode 100644 index 7ddda89c..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderSurfaceFxTable.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderSurfaceFxTable final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.cpp deleted file mode 100644 index 81aae5d7..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderTechniqueSet.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderTechniqueSet::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* techniqueSet = memory->Create(); - memset(techniqueSet, 0, sizeof(MaterialTechniqueSet)); - techniqueSet->name = memory->Dup(assetName.c_str()); - return techniqueSet; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.h deleted file mode 100644 index 9a280bd9..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTechniqueSet.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderTechniqueSet final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.cpp deleted file mode 100644 index 91bf73f6..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderTracerDef.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderTracerDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* tracerDef = memory->Create(); - memset(tracerDef, 0, sizeof(TracerDef)); - tracerDef->name = memory->Dup(assetName.c_str()); - return tracerDef; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.h deleted file mode 100644 index 7233dc28..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderTracerDef.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderTracerDef final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.cpp deleted file mode 100644 index f60fca54..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderVehicleDef.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderVehicleDef::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* vehicleDef = memory->Create(); - memset(vehicleDef, 0, sizeof(VehicleDef)); - vehicleDef->name = memory->Dup(assetName.c_str()); - return vehicleDef; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.h deleted file mode 100644 index f17a38a2..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleDef.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderVehicleDef final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.cpp deleted file mode 100644 index 4db1cb43..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderVehicleTrack.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderVehicleTrack::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* vehicleTrack = memory->Create(); - memset(vehicleTrack, 0, sizeof(VehicleTrack)); - vehicleTrack->name = memory->Dup(assetName.c_str()); - return vehicleTrack; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.h deleted file mode 100644 index 66d171e5..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVehicleTrack.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderVehicleTrack final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.cpp deleted file mode 100644 index 96be5b97..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderVertexDecl.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderVertexDecl::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* vertexDecl = memory->Create(); - memset(vertexDecl, 0, sizeof(MaterialVertexDeclaration)); - vertexDecl->name = memory->Dup(assetName.c_str()); - return vertexDecl; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.h deleted file mode 100644 index 2e8d7685..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexDecl.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderVertexDecl final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.cpp deleted file mode 100644 index 267f1c76..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderVertexShader.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderVertexShader::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* vertexShader = memory->Create(); - memset(vertexShader, 0, sizeof(MaterialVertexShader)); - vertexShader->name = memory->Dup(assetName.c_str()); - return vertexShader; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.h deleted file mode 100644 index dde8ba8d..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderVertexShader.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderVertexShader final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.h deleted file mode 100644 index 67495344..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderWeapon final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromGdt() const override; - bool LoadFromGdt( - const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.cpp deleted file mode 100644 index 0d04b56d..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "AssetLoaderWeaponAttachment.h" - -#include "Game/IW5/IW5.h" -#include "Game/IW5/Weapon/JsonWeaponAttachmentLoader.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderWeaponAttachment::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* attachment = memory->Create(); - memset(attachment, 0, sizeof(WeaponAttachment)); - attachment->szInternalName = memory->Dup(assetName.c_str()); - - return attachment; -} - -bool AssetLoaderWeaponAttachment::CanLoadFromRaw() const -{ - return true; -} - -bool AssetLoaderWeaponAttachment::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto file = searchPath->Open(std::format("attachment/{}.json", assetName)); - if (!file.IsOpen()) - return false; - - auto* attachment = memory->Alloc(); - attachment->szInternalName = memory->Dup(assetName.c_str()); - - std::vector dependencies; - std::vector indirectAssetReferences; - if (LoadWeaponAttachmentAsJson(*file.m_stream, *attachment, memory, manager, dependencies, indirectAssetReferences)) - manager->AddAsset(assetName, attachment, std::move(dependencies), std::vector(), std::move(indirectAssetReferences)); - else - std::cerr << "Failed to load attachment \"" << assetName << "\"\n"; - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.h deleted file mode 100644 index 72173e19..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeaponAttachment.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderWeaponAttachment final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.cpp deleted file mode 100644 index 0f0cc5e8..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderXAnim.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderXAnim::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* anim = memory->Create(); - memset(anim, 0, sizeof(XAnimParts)); - anim->name = memory->Dup(assetName.c_str()); - return anim; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.h deleted file mode 100644 index 16bf60a3..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXAnim.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderXAnim final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.cpp deleted file mode 100644 index 4f7f9629..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "AssetLoaderXModel.h" - -#include "Game/IW5/IW5.h" -#include "Game/IW5/XModel/XModelLoaderIW5.h" -#include "Pool/GlobalAssetPool.h" - -#include -#include -#include - -using namespace IW5; - -void* AssetLoaderXModel::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* asset = memory->Alloc(); - asset->name = memory->Dup(assetName.c_str()); - return asset; -} - -bool AssetLoaderXModel::CanLoadFromRaw() const -{ - return true; -} - -bool AssetLoaderXModel::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto file = searchPath->Open(std::format("xmodel/{}.json", assetName)); - if (!file.IsOpen()) - return false; - - auto* xmodel = memory->Alloc(); - xmodel->name = memory->Dup(assetName.c_str()); - - std::vector dependencies; - if (LoadXModel(*file.m_stream, *xmodel, memory, manager, dependencies)) - { - manager->AddAsset(assetName, xmodel, std::move(dependencies)); - } - else - { - std::cerr << std::format("Failed to load xmodel \"{}\"\n", assetName); - return false; - } - - return true; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.h deleted file mode 100644 index 3bee159f..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModel.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "AssetLoading/BasicAssetLoader.h" -#include "AssetLoading/IAssetLoadingManager.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderXModel final : public BasicAssetLoader - { - static std::string GetFileNameForAsset(const std::string& assetName); - - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - _NODISCARD bool CanLoadFromRaw() const override; - bool - LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.cpp deleted file mode 100644 index 11952da7..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "AssetLoaderXModelSurfs.h" - -#include "Game/IW5/IW5.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" - -#include - -using namespace IW5; - -void* AssetLoaderXModelSurfs::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) -{ - auto* modelSurfs = memory->Create(); - memset(modelSurfs, 0, sizeof(XModelSurfs)); - modelSurfs->name = memory->Dup(assetName.c_str()); - return modelSurfs; -} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.h deleted file mode 100644 index 2487afbe..00000000 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderXModelSurfs.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "AssetLoading/BasicAssetLoader.h" -#include "Game/IW5/IW5.h" -#include "SearchPath/ISearchPath.h" - -namespace IW5 -{ - class AssetLoaderXModelSurfs final : public BasicAssetLoader - { - public: - _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp new file mode 100644 index 00000000..f30d27e4 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.cpp @@ -0,0 +1,69 @@ +#include "LoaderImageIW5.h" + +#include "Game/IW5/IW5.h" +#include "Image/IwiLoader.h" + +#include +#include +#include +#include + +using namespace IW5; + +namespace +{ + constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; + + class ImageLoader final : public AssetCreator + { + public: + ImageLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto fileName = std::format("images/{}.iwi", assetName); + const auto file = m_search_path.Open(fileName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto fileSize = static_cast(file.m_length); + const auto fileData = std::make_unique(fileSize); + file.m_stream->read(fileData.get(), fileSize); + + std::istringstream ss(std::string(fileData.get(), fileSize)); + const auto texture = iwi::LoadIwi(ss); + if (!texture) + { + std::cerr << std::format("Failed to load texture from: {}\n", fileName); + return AssetCreationResult::Failure(); + } + + auto* image = m_memory.Alloc(); + image->name = m_memory.Dup(assetName.c_str()); + image->noPicmip = !texture->HasMipMaps(); + image->width = static_cast(texture->GetWidth()); + image->height = static_cast(texture->GetHeight()); + image->depth = static_cast(texture->GetDepth()); + + image->texture.loadDef = m_memory.Alloc(); + + return AssetCreationResult::Success(context.AddAsset(assetName, image)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h new file mode 100644 index 00000000..66609137 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Image/LoaderImageIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp index 4d312202..63be576b 100644 --- a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp +++ b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp @@ -1,6 +1,7 @@ #include "InfoStringToStructConverter.h" #include +#include #include using namespace IW5; @@ -8,12 +9,12 @@ using namespace IW5; InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure, ZoneScriptStrings& zoneScriptStrings, - MemoryManager* memory, - IAssetLoadingManager* manager, + MemoryManager& memory, + AssetCreationContext& context, + GenericAssetRegistration& registration, const cspField_t* fields, const size_t fieldCount) - : InfoStringToStructConverterBase(infoString, structure, zoneScriptStrings, memory), - m_loading_manager(manager), + : InfoStringToStructConverterBase(infoString, structure, zoneScriptStrings, memory, context, registration), m_fields(fields), m_field_count(fieldCount) { @@ -58,15 +59,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons return true; } - auto* fx = m_loading_manager->LoadDependency(value); + auto* fx = m_context.LoadDependency(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(reinterpret_cast(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(value); + auto* xmodel = m_context.LoadDependency(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(reinterpret_cast(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(value); + auto* material = m_context.LoadDependency(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(reinterpret_cast(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(value); + auto* tracer = m_context.LoadDependency(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(reinterpret_cast(m_structure) + field.iOffset) = tracer->Asset(); return true; @@ -160,15 +161,15 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons return true; } - auto* collmap = m_loading_manager->LoadDependency(value); + auto* collmap = m_context.LoadDependency(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(reinterpret_cast(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(); - name->soundName = m_memory->Dup(value.c_str()); + auto* name = m_memory.Alloc(); + name->soundName = m_memory.Dup(value.c_str()); reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset)->name = name; - m_indirect_asset_references.emplace(ASSET_TYPE_SOUND, value); + m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference(value)); return true; } diff --git a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h index f2026e18..88002e13 100644 --- a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h +++ b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h @@ -1,4 +1,5 @@ #pragma once + #include "AssetLoading/IAssetLoadingManager.h" #include "Game/IW5/IW5.h" #include "InfoString/InfoStringToStructConverterBase.h" @@ -7,24 +8,22 @@ namespace IW5 { class InfoStringToStructConverter : public InfoStringToStructConverterBase { - protected: - IAssetLoadingManager* m_loading_manager; - const cspField_t* m_fields; - size_t m_field_count; - - static bool GetHashValue(const std::string& value, unsigned int& hash); - - virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0; - bool ConvertBaseField(const cspField_t& field, const std::string& value); - public: InfoStringToStructConverter(const InfoString& infoString, void* structure, ZoneScriptStrings& zoneScriptStrings, - MemoryManager* memory, - IAssetLoadingManager* manager, + MemoryManager& memory, + AssetCreationContext& context, + GenericAssetRegistration& registration, const cspField_t* fields, size_t fieldCount); bool Convert() override; + + protected: + virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0; + bool ConvertBaseField(const cspField_t& field, const std::string& value); + + const cspField_t* m_fields; + size_t m_field_count; }; } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.cpp b/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.cpp index 092a510d..5c896d66 100644 --- a/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.cpp +++ b/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.cpp @@ -122,9 +122,9 @@ namespace namespace IW5 { - bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory) + bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory) { - const JsonLoader loader(stream, *memory); + const JsonLoader loader(stream, memory); return loader.Load(leaderboard); } diff --git a/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h b/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h index 1dc020b6..753a5db3 100644 --- a/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h +++ b/src/ObjLoading/Game/IW5/Leaderboard/JsonLeaderboardDefLoader.h @@ -7,5 +7,5 @@ namespace IW5 { - bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory); + bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory); } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp b/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp new file mode 100644 index 00000000..c18ed86b --- /dev/null +++ b/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.cpp @@ -0,0 +1,53 @@ +#include "LoaderLeaderboardIW5.h" + +#include "Game/IW5/IW5.h" +#include "JsonLeaderboardDefLoader.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + class LeaderboardLoader final : public AssetCreator + { + 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->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(assetName, leaderboardDef)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h b/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h new file mode 100644 index 00000000..6c144840 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Leaderboard/LoaderLeaderboardIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.cpp b/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.cpp deleted file mode 100644 index d2f37742..00000000 --- a/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "AssetLoaderLocalizeIW5.h" - -using namespace IW5; - -AssetLoaderLocalize::AssetLoaderLocalize(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) - : CommonLocalizeLoader(searchPath, zone), - m_memory(memory) -{ -} - -AssetCreationResult AssetLoaderLocalize::CreateAsset(const std::string& assetName, AssetCreationContext& context) -{ - return CreateLocalizeAsset(assetName, context); -} - -AssetCreationResult AssetLoaderLocalize::CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context) -{ - auto* asset = m_memory.Alloc(); - 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(localizeEntry.m_key, asset)); -} diff --git a/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.h b/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.h deleted file mode 100644 index 0daabd9e..00000000 --- a/src/ObjLoading/Game/IW5/Localize/AssetLoaderLocalizeIW5.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "Asset/AssetCreationContext.h" -#include "Asset/IAssetCreator.h" -#include "Game/IW5/IW5.h" -#include "Localize/CommonLocalizeLoader.h" -#include "SearchPath/ISearchPath.h" -#include "Utils/MemoryManager.h" -#include "Zone/Zone.h" - -namespace IW5 -{ - class AssetLoaderLocalize final : public AssetCreator, public CommonLocalizeLoader - { - public: - AssetLoaderLocalize(MemoryManager& memory, ISearchPath& searchPath, Zone& zone); - AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override; - - protected: - AssetCreationResult CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context) override; - - private: - MemoryManager& m_memory; - }; -} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp b/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp new file mode 100644 index 00000000..a531c42f --- /dev/null +++ b/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.cpp @@ -0,0 +1,44 @@ +#include "LoaderLocalizeIW5.h" + +#include "Localize/CommonLocalizeLoader.h" + +using namespace IW5; + +namespace +{ + class LocalizeLoader final : public AssetCreator, 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(); + 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(localizeEntry.m_key, asset)); + } + + private: + MemoryManager& m_memory; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) + { + return std::make_unique(memory, searchPath, zone); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h b/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h new file mode 100644 index 00000000..6c47a8d1 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Localize/LoaderLocalizeIW5.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" +#include "Zone/Zone.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.cpp b/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.cpp index a567e9dd..3742f848 100644 --- a/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.cpp +++ b/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.cpp @@ -16,12 +16,11 @@ namespace class JsonLoader { public: - JsonLoader(std::istream& stream, MemoryManager& memory, IAssetLoadingManager& manager, std::vector& dependencies) + JsonLoader(std::istream& stream, MemoryManager& memory, AssetCreationContext& context, AssetRegistration& registration) : m_stream(stream), m_memory(memory), - m_manager(manager), - m_dependencies(dependencies) - + m_context(context), + m_registration(registration) { } @@ -159,13 +158,13 @@ namespace textureDef.semantic = jTexture.semantic; - auto* imageAsset = m_manager.LoadDependency(jTexture.image); + auto* imageAsset = m_context.LoadDependency(jTexture.image); if (!imageAsset) { PrintError(material, std::format("Could not find textureDef image: {}", jTexture.image)); return false; } - m_dependencies.push_back(imageAsset); + m_registration.AddDependency(imageAsset); if (jTexture.water) { @@ -365,13 +364,13 @@ namespace material.stateFlags = static_cast(jMaterial.stateFlags); material.cameraRegion = jMaterial.cameraRegion; - auto* techniqueSet = m_manager.LoadDependency(jMaterial.techniqueSet); + auto* techniqueSet = m_context.LoadDependency(jMaterial.techniqueSet); if (!techniqueSet) { PrintError(material, "Could not find technique set"); return false; } - m_dependencies.push_back(techniqueSet); + m_registration.AddDependency(techniqueSet); material.techniqueSet = techniqueSet->Asset(); if (!jMaterial.textures.empty()) @@ -430,17 +429,17 @@ namespace std::istream& m_stream; MemoryManager& m_memory; - IAssetLoadingManager& m_manager; - std::vector& m_dependencies; + AssetCreationContext& m_context; + AssetRegistration& m_registration; }; } // namespace namespace IW5 { bool LoadMaterialAsJson( - std::istream& stream, Material& material, MemoryManager* memory, IAssetLoadingManager* manager, std::vector& dependencies) + std::istream& stream, Material& material, MemoryManager& memory, AssetCreationContext& context, AssetRegistration& registration) { - const JsonLoader loader(stream, *memory, *manager, dependencies); + const JsonLoader loader(stream, memory, context, registration); return loader.Load(material); } diff --git a/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.h b/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.h index b498852d..6b2b5b74 100644 --- a/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.h +++ b/src/ObjLoading/Game/IW5/Material/JsonMaterialLoader.h @@ -1,6 +1,7 @@ #pragma once -#include "AssetLoading/IAssetLoadingManager.h" +#include "Asset/AssetCreationContext.h" +#include "Asset/AssetRegistration.h" #include "Game/IW5/IW5.h" #include "Utils/MemoryManager.h" @@ -9,5 +10,5 @@ namespace IW5 { bool LoadMaterialAsJson( - std::istream& stream, Material& material, MemoryManager* memory, IAssetLoadingManager* manager, std::vector& dependencies); + std::istream& stream, Material& material, MemoryManager& memory, AssetCreationContext& context, AssetRegistration& registration); } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp b/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp new file mode 100644 index 00000000..96f5af0e --- /dev/null +++ b/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.cpp @@ -0,0 +1,70 @@ +#include "LoaderMaterialIW5.h" + +#include "Game/IW5/IW5.h" +#include "JsonMaterialLoader.h" + +#include +#include +#include +#include + +using namespace IW5; + +namespace +{ + class MaterialLoader final : public AssetCreator + { + public: + MaterialLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto file = m_search_path.Open(GetFileNameForAsset(assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* material = m_memory.Alloc(); + material->info.name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, material); + if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration)) + { + std::cerr << std::format("Failed to load material \"{}\"\n", assetName); + return AssetCreationResult::Failure(); + } + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + std::string GetFileNameForAsset(const std::string& assetName) + { + std::string sanitizedFileName(assetName); + if (sanitizedFileName[0] == '*') + { + std::ranges::replace(sanitizedFileName, '*', '_'); + const auto parenthesisPos = sanitizedFileName.find('('); + if (parenthesisPos != std::string::npos) + sanitizedFileName.erase(parenthesisPos); + sanitizedFileName = std::format("generated/{}", sanitizedFileName); + } + + return std::format("materials/{}.json", sanitizedFileName); + } + + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h b/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h new file mode 100644 index 00000000..5488c1a7 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Material/LoaderMaterialIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp b/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp new file mode 100644 index 00000000..5ca990c8 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.cpp @@ -0,0 +1,230 @@ +#include "LoaderMenuListIW5.h" + +#include "Game/IW5/IW5.h" +#include "Game/IW5/Menu/MenuConversionZoneStateIW5.h" +#include "Game/IW5/Menu/MenuConverterIW5.h" +#include "ObjLoading.h" +#include "Parsing/Menu/MenuFileReader.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + class MenuListLoader final : public AssetCreator + { + public: + MenuListLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + std::vector menus; + AssetRegistration registration(assetName); + + auto* zoneState = context.GetZoneAssetLoaderState(); + auto* conversionState = context.GetZoneAssetLoaderState(); + + std::deque 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(); + 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()->FinalizeSupportingData(); + } + + private: + bool LoadMenuFileFromQueue(const std::string& menuFilePath, + AssetCreationContext& context, + menu::MenuAssetZoneState* zoneState, + MenuConversionZoneState* conversionState, + std::vector& menus, + AssetRegistration& 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& menus, + AssetRegistration& 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*> 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(); + AssetRegistration 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& menus) + { + menuList.menuCount = static_cast(menus.size()); + + if (menuList.menuCount > 0) + { + menuList.menus = m_memory.Alloc(menuList.menuCount); + for (auto i = 0; i < menuList.menuCount; i++) + menuList.menus[i] = menus[i]; + } + else + menuList.menus = nullptr; + } + + std::unique_ptr 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 + { + auto foundFileToInclude = m_search_path.Open(filename); + if (!foundFileToInclude.IsOpen() || !foundFileToInclude.m_stream) + return nullptr; + + return std::move(foundFileToInclude.m_stream); + }); + + reader.IncludeZoneState(zoneState); + reader.SetPermissiveMode(ObjLoading::Configuration.MenuPermissiveParsing); + + return reader.ReadMenuFile(); + } + + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h b/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h new file mode 100644 index 00000000..823161b8 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Menu/LoaderMenuListIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.cpp b/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.cpp index e36a7b37..b6e06f06 100644 --- a/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.cpp +++ b/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.cpp @@ -16,18 +16,16 @@ #include #include +#include #include using namespace IW5; using namespace menu; -namespace IW5 +namespace { - class MenuConverterImpl : public AbstractMenuConverter + class MenuConverter final : public AbstractMenuConverter, public IMenuConverter { - MenuConversionZoneState* m_conversion_zone_state; - MenuAssetZoneState* m_parsing_zone_state; - _NODISCARD static rectDef_s ConvertRectDef(const CommonRect& rect) { return rectDef_s{ @@ -78,26 +76,26 @@ namespace IW5 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(materialName); + auto* materialDependency = m_context.LoadDependency(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(soundName); + auto* soundDependency = m_context.LoadDependency(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 IW5 if (!expression) return nullptr; - auto* statement = m_memory->Create(); + auto* statement = m_memory.Alloc(); for (auto& result : statement->persistentState.lastResult) result = Operand{}; for (auto& lastExecutionTime : statement->persistentState.lastExecuteTime) @@ -426,8 +424,8 @@ namespace IW5 std::vector expressionEntries; ConvertExpressionEntry(statement, expressionEntries, expression, menu, item); - auto* outputExpressionEntries = m_memory->Alloc(expressionEntries.size()); - memcpy(outputExpressionEntries, expressionEntries.data(), sizeof(expressionEntry) * expressionEntries.size()); + auto* outputExpressionEntries = m_memory.Alloc(expressionEntries.size()); + std::memcpy(outputExpressionEntries, expressionEntries.data(), sizeof(expressionEntry) * expressionEntries.size()); statement->entries = outputExpressionEntries; statement->numEntries = static_cast(expressionEntries.size()); @@ -435,10 +433,10 @@ namespace IW5 return statement; } - _NODISCARD Statement_s* ConvertOrApplyStatement(float& staticValue, - const ISimpleExpression* expression, - const CommonMenuDef* menu, - const CommonItemDef* item = nullptr) const + [[nodiscard]] Statement_s* ConvertOrApplyStatement(float& staticValue, + const ISimpleExpression* expression, + const CommonMenuDef* menu, + const CommonItemDef* item = nullptr) const { if (m_disable_optimizations) return ConvertExpression(expression, menu, item); @@ -466,10 +464,10 @@ namespace IW5 return ConvertExpression(expression, menu, item); } - _NODISCARD Statement_s* ConvertOrApplyStatement(const char*& staticValue, - const ISimpleExpression* expression, - const CommonMenuDef* menu, - const CommonItemDef* item = nullptr) const + [[nodiscard]] Statement_s* ConvertOrApplyStatement(const char*& staticValue, + const ISimpleExpression* expression, + const CommonMenuDef* menu, + const CommonItemDef* item = nullptr) const { if (m_disable_optimizations) return ConvertExpression(expression, menu, item); @@ -483,7 +481,7 @@ namespace IW5 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: @@ -496,10 +494,10 @@ namespace IW5 return ConvertExpression(expression, menu, item); } - _NODISCARD Statement_s* ConvertOrApplyStatement(Material*& staticValue, - const ISimpleExpression* expression, - const CommonMenuDef* menu, - const CommonItemDef* item = nullptr) const + [[nodiscard]] Statement_s* ConvertOrApplyStatement(Material*& staticValue, + const ISimpleExpression* expression, + const CommonMenuDef* menu, + const CommonItemDef* item = nullptr) const { if (m_disable_optimizations) return ConvertExpression(expression, menu, item); @@ -526,10 +524,10 @@ namespace IW5 return ConvertExpression(expression, menu, item); } - _NODISCARD Statement_s* ConvertVisibleExpression(windowDef_t* window, - const ISimpleExpression* expression, - const CommonMenuDef* commonMenu, - const CommonItemDef* commonItem = nullptr) const + [[nodiscard]] Statement_s* ConvertVisibleExpression(windowDef_t* window, + const ISimpleExpression* expression, + const CommonMenuDef* commonMenu, + const CommonItemDef* commonItem = nullptr) const { if (expression == nullptr) return nullptr; @@ -560,7 +558,7 @@ namespace IW5 return ConvertExpression(expression, commonMenu, commonItem); } - _NODISCARD static EventType SetLocalVarTypeToEventType(const SetLocalVarType setLocalVarType) + [[nodiscard]] static EventType SetLocalVarTypeToEventType(const SetLocalVarType setLocalVarType) { switch (setLocalVarType) { @@ -588,16 +586,16 @@ namespace IW5 if (!setLocalVar) return; - auto* outputHandler = m_memory->Alloc(); - auto* outputSetLocalVar = m_memory->Alloc(); + auto* outputHandler = m_memory.Alloc(); + auto* outputSetLocalVar = m_memory.Alloc(); 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); + elements.emplace_back(outputHandler); } void ConvertEventHandlerScript(std::vector& elements, const CommonEventHandlerScript* script) const @@ -606,11 +604,11 @@ namespace IW5 if (!script) return; - auto* outputHandler = m_memory->Create(); + auto* outputHandler = m_memory.Alloc(); 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); + elements.emplace_back(outputHandler); } void ConvertEventHandlerCondition(std::vector& elements, @@ -633,8 +631,8 @@ namespace IW5 } else { - auto* outputHandler = m_memory->Alloc(); - auto* outputCondition = m_memory->Alloc(); + auto* outputHandler = m_memory.Alloc(); + auto* outputCondition = m_memory.Alloc(); outputHandler->eventType = EVENT_IF; outputHandler->eventData.conditionalScript = outputCondition; @@ -646,7 +644,7 @@ namespace IW5 if (condition->m_else_elements) { - auto* outputElseHandler = m_memory->Create(); + auto* outputElseHandler = m_memory.Alloc(); outputElseHandler->eventType = EVENT_ELSE; outputElseHandler->eventData.elseScript = ConvertEventHandlerSet(condition->m_else_elements.get(), menu, item); @@ -689,7 +687,7 @@ namespace IW5 ConvertEventHandler(elements, element.get(), menu, item); } - _NODISCARD MenuEventHandlerSet* + [[nodiscard]] MenuEventHandlerSet* ConvertEventHandlerSet(const CommonEventHandlerSet* eventHandlerSet, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const { if (!eventHandlerSet) @@ -701,9 +699,9 @@ namespace IW5 if (elements.empty()) return nullptr; - auto* outputSet = m_memory->Alloc(); - auto* outputElements = m_memory->Alloc(elements.size()); - memcpy(outputElements, elements.data(), sizeof(void*) * elements.size()); + auto* outputSet = m_memory.Alloc(); + auto* outputElements = m_memory.Alloc(elements.size()); + std::memcpy(outputElements, elements.data(), sizeof(void*) * elements.size()); outputSet->eventHandlerCount = static_cast(elements.size()); outputSet->eventHandlers = outputElements; @@ -711,15 +709,15 @@ namespace IW5 return outputSet; } - _NODISCARD ItemKeyHandler* ConvertKeyHandler(const std::multimap>& keyHandlers, - const CommonMenuDef* menu, - const CommonItemDef* item = nullptr) const + [[nodiscard]] ItemKeyHandler* ConvertKeyHandler(const std::multimap>& keyHandlers, + const CommonMenuDef* menu, + const CommonItemDef* item = nullptr) const { if (keyHandlers.empty()) return nullptr; const auto keyHandlerCount = keyHandlers.size(); - auto* output = m_memory->Alloc(keyHandlerCount); + auto* output = m_memory.Alloc(keyHandlerCount); auto currentKeyHandler = keyHandlers.cbegin(); for (auto i = 0u; i < keyHandlerCount; i++) { @@ -831,7 +829,7 @@ namespace IW5 if (floatExpressionCount <= 0) return nullptr; - auto* floatExpressions = m_memory->Alloc(floatExpressionCount); + auto* floatExpressions = m_memory.Alloc(floatExpressionCount); auto floatExpressionIndex = 0; for (const auto& [expression, expressionIsStatic, target, staticValue, staticValueArraySize, dynamicFlagsToSet] : locations) { @@ -848,7 +846,7 @@ namespace IW5 return floatExpressions; } - _NODISCARD const char* CreateEnableDvarString(const std::vector& stringElements) const + [[nodiscard]] const char* CreateEnableDvarString(const std::vector& stringElements) const { std::ostringstream ss; @@ -857,10 +855,10 @@ namespace IW5 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 + [[nodiscard]] const char* ConvertEnableDvar(const CommonItemDef& commonItem, int& dvarFlags) const { dvarFlags = 0; @@ -897,15 +895,15 @@ namespace IW5 return nullptr; } - _NODISCARD listBoxDef_s* ConvertListBoxFeatures(itemDef_s* item, - CommonItemFeaturesListBox* commonListBox, - const CommonMenuDef& parentMenu, - const CommonItemDef& commonItem) const + [[nodiscard]] listBoxDef_s* ConvertListBoxFeatures(itemDef_s* item, + CommonItemFeaturesListBox* commonListBox, + const CommonMenuDef& parentMenu, + const CommonItemDef& commonItem) const { if (commonListBox == nullptr) return nullptr; - auto* listBox = m_memory->Alloc(); + auto* listBox = m_memory.Alloc(); listBox->notselectable = commonListBox->m_not_selectable ? 1 : 0; listBox->noScrollBars = commonListBox->m_no_scrollbars ? 1 : 0; listBox->usePaging = commonListBox->m_use_paging ? 1 : 0; @@ -935,15 +933,15 @@ namespace IW5 return listBox; } - _NODISCARD editFieldDef_s* ConvertEditFieldFeatures(itemDef_s* item, - CommonItemFeaturesEditField* commonEditField, - const CommonMenuDef& parentMenu, - const CommonItemDef& commonItem) const + [[nodiscard]] editFieldDef_s* ConvertEditFieldFeatures(itemDef_s* item, + CommonItemFeaturesEditField* commonEditField, + const CommonMenuDef& parentMenu, + const CommonItemDef& commonItem) const { if (commonEditField == nullptr) return nullptr; - auto* editField = m_memory->Alloc(); + auto* editField = m_memory.Alloc(); editField->stepVal = static_cast(commonEditField->m_def_val); editField->minVal = static_cast(commonEditField->m_min_val); editField->maxVal = static_cast(commonEditField->m_max_val); @@ -955,15 +953,15 @@ namespace IW5 return editField; } - _NODISCARD multiDef_s* ConvertMultiValueFeatures(itemDef_s* item, - CommonItemFeaturesMultiValue* commonMultiValue, - const CommonMenuDef& parentMenu, - const CommonItemDef& commonItem) const + [[nodiscard]] multiDef_s* ConvertMultiValueFeatures(itemDef_s* item, + CommonItemFeaturesMultiValue* commonMultiValue, + const CommonMenuDef& parentMenu, + const CommonItemDef& commonItem) const { if (commonMultiValue == nullptr) return nullptr; - auto* multiValue = m_memory->Alloc(); + auto* multiValue = m_memory.Alloc(); multiValue->count = static_cast(std::min(std::extent_v, commonMultiValue->m_step_names.size())); multiValue->strDef = !commonMultiValue->m_string_values.empty() ? 1 : 0; @@ -986,15 +984,15 @@ namespace IW5 return multiValue; } - _NODISCARD newsTickerDef_s* ConvertNewsTickerFeatures(itemDef_s* item, - CommonItemFeaturesNewsTicker* commonNewsTicker, - const CommonMenuDef& parentMenu, - const CommonItemDef& commonItem) const + [[nodiscard]] newsTickerDef_s* ConvertNewsTickerFeatures(itemDef_s* item, + CommonItemFeaturesNewsTicker* commonNewsTicker, + const CommonMenuDef& parentMenu, + const CommonItemDef& commonItem) const { if (commonNewsTicker == nullptr) return nullptr; - auto* newsTicker = m_memory->Alloc(); + auto* newsTicker = m_memory.Alloc(); newsTicker->spacing = commonNewsTicker->m_spacing; newsTicker->speed = commonNewsTicker->m_speed; newsTicker->feedId = commonNewsTicker->m_news_feed_id; @@ -1002,9 +1000,9 @@ namespace IW5 return newsTicker; } - _NODISCARD itemDef_s* ConvertItem(const CommonMenuDef& parentMenu, const CommonItemDef& commonItem) const + [[nodiscard]] itemDef_s* ConvertItem(const CommonMenuDef& parentMenu, const CommonItemDef& commonItem) const { - auto* item = m_memory->Create(); + auto* item = m_memory.Alloc(); memset(item, 0, sizeof(itemDef_s)); item->window.name = ConvertString(commonItem.m_name); @@ -1094,7 +1092,7 @@ namespace IW5 case CommonItemFeatureType::NONE: default: if (item->type == ITEM_TYPE_TEXT_SCROLL) - item->typeData.scroll = m_memory->Alloc(); + item->typeData.scroll = m_memory.Alloc(); break; } @@ -1110,7 +1108,7 @@ namespace IW5 return nullptr; } - auto* items = m_memory->Alloc(commonMenu.m_items.size()); + auto* items = m_memory.Alloc(commonMenu.m_items.size()); for (auto i = 0u; i < commonMenu.m_items.size(); i++) items[i] = ConvertItem(commonMenu, *commonMenu.m_items[i]); @@ -1120,101 +1118,79 @@ namespace IW5 } public: - MenuConverterImpl(const bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) - : AbstractMenuConverter(disableOptimizations, searchPath, memory, manager), - m_conversion_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState()), - m_parsing_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState()) + MenuConverter(const bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context) + : AbstractMenuConverter(disableOptimizations, searchPath, memory, context), + m_conversion_zone_state(context.GetZoneAssetLoaderState()), + m_parsing_zone_state(context.GetZoneAssetLoaderState()) { 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& registration) override { - auto* menu = m_memory->Create(); - auto* menuData = m_memory->Create(); - memset(menu, 0, sizeof(menuDef_t)); + try + { + auto* menuData = m_memory.Alloc(); - menu->data = menuData; - menu->window.name = m_memory->Dup(commonMenu.m_name.c_str()); - menuData->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(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(menuData->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); - menuData->soundName = ConvertString(commonMenu.m_sound_loop); - ApplyFlag(menu->window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP); - menuData->fadeClamp = static_cast(commonMenu.m_fade_clamp); - menuData->fadeCycle = commonMenu.m_fade_cycle; - menuData->fadeAmount = static_cast(commonMenu.m_fade_amount); - menuData->fadeInAmount = static_cast(commonMenu.m_fade_in_amount); - menuData->blurRadius = static_cast(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); - menuData->allowedBinding = ConvertString(commonMenu.m_allowed_binding); - ApplyFlag(menu->window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS); - menuData->visibleExp = ConvertVisibleExpression(&menu->window, commonMenu.m_visible_expression.get(), &commonMenu); - menuData->rectXExp = ConvertOrApplyStatement(menu->window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu); - menuData->rectYExp = ConvertOrApplyStatement(menu->window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu); - menuData->rectWExp = ConvertOrApplyStatement(menu->window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu); - menuData->rectHExp = ConvertOrApplyStatement(menu->window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu); - menuData->openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu); - menuData->closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu); - menuData->onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu); - menuData->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu); - menuData->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu); - menuData->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu); - menuData->onFocusDueToClose = ConvertEventHandlerSet(commonMenu.m_on_focus_due_to_close.get(), &commonMenu); - menuData->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu); - menu->items = ConvertMenuItems(commonMenu, menu->itemCount); - menuData->expressionData = m_conversion_zone_state->m_supporting_data; - - return menu; + menu.data = menuData; + menu.window.name = m_memory.Dup(commonMenu.m_name.c_str()); + menuData->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(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(menuData->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); + menuData->soundName = ConvertString(commonMenu.m_sound_loop); + ApplyFlag(menu.window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP); + menuData->fadeClamp = static_cast(commonMenu.m_fade_clamp); + menuData->fadeCycle = commonMenu.m_fade_cycle; + menuData->fadeAmount = static_cast(commonMenu.m_fade_amount); + menuData->fadeInAmount = static_cast(commonMenu.m_fade_in_amount); + menuData->blurRadius = static_cast(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); + menuData->allowedBinding = ConvertString(commonMenu.m_allowed_binding); + ApplyFlag(menu.window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS); + menuData->visibleExp = ConvertVisibleExpression(&menu.window, commonMenu.m_visible_expression.get(), &commonMenu); + menuData->rectXExp = ConvertOrApplyStatement(menu.window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu); + menuData->rectYExp = ConvertOrApplyStatement(menu.window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu); + menuData->rectWExp = ConvertOrApplyStatement(menu.window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu); + menuData->rectHExp = ConvertOrApplyStatement(menu.window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu); + menuData->openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu); + menuData->closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu); + menuData->onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu); + menuData->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu); + menuData->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu); + menuData->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu); + menuData->onFocusDueToClose = ConvertEventHandlerSet(commonMenu.m_on_focus_due_to_close.get(), &commonMenu); + menuData->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu); + menu.items = ConvertMenuItems(commonMenu, menu.itemCount); + menuData->expressionData = m_conversion_zone_state->m_supporting_data; + } + catch (const MenuConversionException& e) + { + PrintConversionExceptionDetails(e); + } } - std::vector m_dependencies; + MenuConversionZoneState* m_conversion_zone_state; + MenuAssetZoneState* m_parsing_zone_state; }; -} // namespace IW5 +} // 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::Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context) { -} - -std::vector& 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(disableOptimizations, searchPath, memory, context); } diff --git a/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.h b/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.h index 52381782..2f112270 100644 --- a/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.h +++ b/src/ObjLoading/Game/IW5/Menu/MenuConverterIW5.h @@ -1,26 +1,21 @@ #pragma once -#include "AssetLoading/IAssetLoadingManager.h" +#include "Asset/AssetCreationContext.h" #include "Game/IW5/IW5.h" #include "Parsing/Menu/Domain/CommonMenuDef.h" #include "SearchPath/ISearchPath.h" -#include "Utils/ClassUtils.h" #include "Utils/MemoryManager.h" namespace IW5 { - class MenuConverter + class IMenuConverter { - bool m_disable_optimizations; - ISearchPath* m_search_path; - MemoryManager* m_memory; - IAssetLoadingManager* m_manager; - std::vector m_dependencies; - public: - MenuConverter(bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager); + IMenuConverter() = default; + virtual ~IMenuConverter() = default; - std::vector& GetDependencies(); - _NODISCARD menuDef_t* ConvertMenu(const menu::CommonMenuDef& commonMenu); + virtual void ConvertMenu(const menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration& registration) = 0; + + static std::unique_ptr Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context); }; } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp index 383ed14d..49aad040 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp @@ -3,8 +3,19 @@ #include "Asset/GlobalAssetPoolsLoader.h" #include "Game/IW5/GameIW5.h" #include "Game/IW5/IW5.h" -#include "Localize/AssetLoaderLocalizeIW5.h" +#include "Game/IW5/XModel/LoaderXModelIW5.h" +#include "Image/LoaderImageIW5.h" +#include "Leaderboard/LoaderLeaderboardIW5.h" +#include "Localize/LoaderLocalizeIW5.h" +#include "Material/LoaderMaterialIW5.h" +#include "Menu/LoaderMenuListIW5.h" #include "ObjLoading.h" +#include "RawFile/LoaderRawFileIW5.h" +#include "Script/LoaderScriptFileIW5.h" +#include "StringTable/LoaderStringTableIW5.h" +#include "Weapon/GdtLoaderWeaponIW5.h" +#include "Weapon/LoaderAttachmentIW5.h" +#include "Weapon/RawLoaderWeaponIW5.h" #include @@ -106,7 +117,7 @@ namespace collection.AddAssetCreator(std::make_unique>(zone)); } - void ConfigureLoaders(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath) + void ConfigureLoaders(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt) { auto& memory = *zone.GetMemory(); @@ -114,13 +125,13 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(CreateXModelLoader(memory, searchPath, zone)); + collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(CreateImageLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); @@ -134,18 +145,19 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(CreateMenuListLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); - collection.AddAssetCreator(std::make_unique(memory, searchPath, zone)); - // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone)); + collection.AddAssetCreator(CreateAttachmentLoader(memory, searchPath)); + collection.AddAssetCreator(CreateRawWeaponLoader(memory, searchPath, zone)); + collection.AddAssetCreator(CreateGdtWeaponLoader(memory, searchPath, gdt, zone)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath)); + collection.AddAssetCreator(CreateScriptLoader(memory, searchPath)); + collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath)); + collection.AddAssetCreator(CreateLeaderboardLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); @@ -153,9 +165,9 @@ namespace } } // 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); } diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.h b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h index 86328991..b7e34526 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.h +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h @@ -12,6 +12,6 @@ namespace IW5 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 IW5 diff --git a/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.cpp b/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.cpp new file mode 100644 index 00000000..05e2ca8f --- /dev/null +++ b/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.cpp @@ -0,0 +1,90 @@ +#include "LoaderRawFileIW5.h" + +#include "Game/IW5/IW5.h" +#include "Pool/GlobalAssetPool.h" + +#include +#include +#include +#include +#include + +using namespace IW5; + +namespace +{ + constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64; + + class RawFileLoader final : public AssetCreator + { + public: + RawFileLoader(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(assetName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto uncompressedBuffer = std::make_unique(static_cast(file.m_length)); + file.m_stream->read(uncompressedBuffer.get(), file.m_length); + if (file.m_stream->gcount() != file.m_length) + return AssetCreationResult::Failure(); + + const auto compressionBufferSize = static_cast(file.m_length + COMPRESSED_BUFFER_SIZE_PADDING); + auto* compressedBuffer = m_memory.Alloc(compressionBufferSize); + + z_stream_s zs{}; + + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = static_cast(file.m_length); + zs.avail_out = compressionBufferSize; + zs.next_in = reinterpret_cast(uncompressedBuffer.get()); + zs.next_out = reinterpret_cast(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 << std::format("Deflate failed for loading rawfile \"{}\"\n", assetName); + deflateEnd(&zs); + return AssetCreationResult::Failure(); + } + + const auto compressedSize = compressionBufferSize - zs.avail_out; + + auto* rawFile = m_memory.Alloc(); + rawFile->name = m_memory.Dup(assetName.c_str()); + rawFile->compressedLen = static_cast(compressedSize); + rawFile->len = static_cast(file.m_length); + rawFile->buffer = static_cast(compressedBuffer); + + deflateEnd(&zs); + + return AssetCreationResult::Success(context.AddAsset(assetName, rawFile)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.h b/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.h new file mode 100644 index 00000000..3099146e --- /dev/null +++ b/src/ObjLoading/Game/IW5/RawFile/LoaderRawFileIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.cpp b/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.cpp new file mode 100644 index 00000000..df9bdc2d --- /dev/null +++ b/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.cpp @@ -0,0 +1,88 @@ +#include "LoaderScriptFileIW5.h" + +#include "Game/IW5/IW5.h" +#include "Pool/GlobalAssetPool.h" + +#include +#include +#include +#include + +using namespace IW5; + +namespace +{ + class ScriptLoader final : public AssetCreator + { + public: + ScriptLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + // See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format + const auto file = m_search_path.Open(std::format("{}.gscbin", assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto fileBuffer = std::make_unique(static_cast(file.m_length)); + file.m_stream->read(fileBuffer.get(), file.m_length); + if (file.m_stream->gcount() != file.m_length) + return AssetCreationResult::Failure(); + + auto* scriptFile = m_memory.Alloc(); + scriptFile->name = m_memory.Dup(assetName.c_str()); + + // Retrieve data from the buffer + size_t offset = 0; + + // Read past the name pointer, we will use the one from assetName + offset += strlen(fileBuffer.get()) + 1; + + std::memcpy(&scriptFile->compressedLen, fileBuffer.get() + offset, sizeof(scriptFile->compressedLen)); + offset += sizeof(scriptFile->compressedLen); + + std::memcpy(&scriptFile->len, fileBuffer.get() + offset, sizeof(scriptFile->len)); + offset += sizeof(scriptFile->len); + + std::memcpy(&scriptFile->bytecodeLen, fileBuffer.get() + offset, sizeof(scriptFile->bytecodeLen)); + offset += sizeof(scriptFile->bytecodeLen); + + if (scriptFile->compressedLen <= 0 || scriptFile->bytecodeLen <= 0) + { + std::cerr << std::format("Error: Invalid length of the buffers in {} specified\n", assetName); + return AssetCreationResult::Failure(); + } + + if (offset + (scriptFile->compressedLen + scriptFile->bytecodeLen) > file.m_length) + { + std::cerr << std::format("Error: Specified length in {} GSC BIN structure exceeds the actual file size\n", assetName); + return AssetCreationResult::Failure(); + } + + scriptFile->buffer = m_memory.Alloc(scriptFile->compressedLen); + std::memcpy(const_cast(scriptFile->buffer), fileBuffer.get() + offset, scriptFile->compressedLen); + offset += scriptFile->compressedLen; + + scriptFile->bytecode = m_memory.Alloc(scriptFile->bytecodeLen); + std::memcpy(scriptFile->bytecode, fileBuffer.get() + offset, scriptFile->bytecodeLen); + + return AssetCreationResult::Success(context.AddAsset(assetName, scriptFile)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateScriptLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.h b/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.h new file mode 100644 index 00000000..457a0957 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Script/LoaderScriptFileIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateScriptLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.cpp b/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.cpp new file mode 100644 index 00000000..2ca18723 --- /dev/null +++ b/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.cpp @@ -0,0 +1,49 @@ +#include "LoaderStringTableIW5.h" + +#include "Csv/CsvStream.h" +#include "Game/IW5/CommonIW5.h" +#include "Game/IW5/IW5.h" +#include "ObjLoading.h" +#include "Pool/GlobalAssetPool.h" +#include "StringTable/StringTableLoader.h" + +#include + +using namespace IW5; + +namespace +{ + class StringTableLoader final : public AssetCreator + { + public: + StringTableLoader(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(assetName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + string_table::StringTableLoaderV2 loader; + auto* stringTable = loader.LoadFromStream(assetName, m_memory, *file.m_stream); + + return AssetCreationResult::Success(context.AddAsset(assetName, stringTable)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.h b/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.h new file mode 100644 index 00000000..e07bf9c7 --- /dev/null +++ b/src/ObjLoading/Game/IW5/StringTable/LoaderStringTableIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.cpp b/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.cpp new file mode 100644 index 00000000..03897a0d --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.cpp @@ -0,0 +1,53 @@ +#include "GdtLoaderWeaponIW5.h" + +#include "Game/IW5/IW5.h" +#include "Game/IW5/ObjConstantsIW5.h" +#include "InfoString/InfoString.h" +#include "InfoStringLoaderWeaponIW5.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + class GdtLoaderWeapon final : public AssetCreator + { + public: + GdtLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone) + : m_gdt(gdt), + m_info_string_loader(memory, searchPath, zone) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto* gdtEntry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_WEAPON, assetName); + if (gdtEntry == nullptr) + return AssetCreationResult::NoAction(); + + InfoString infoString; + if (!infoString.FromGdtProperties(*gdtEntry)) + { + std::cerr << std::format("Failed to read weapon gdt entry: \"{}\"\n", assetName); + return AssetCreationResult::Failure(); + } + + return m_info_string_loader.CreateAsset(assetName, infoString, context); + } + + private: + IGdtQueryable& m_gdt; + InfoStringLoaderWeapon m_info_string_loader; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone) + { + return std::make_unique(memory, searchPath, gdt, zone); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.h b/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.h new file mode 100644 index 00000000..0e86b336 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/GdtLoaderWeaponIW5.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "Gdt/IGdtQueryable.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp similarity index 71% rename from src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp rename to src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp index 19713878..3e88d7da 100644 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp +++ b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp @@ -1,18 +1,15 @@ -#include "AssetLoaderWeapon.h" +#include "InfoStringLoaderWeaponIW5.h" #include "Game/IW5/IW5.h" #include "Game/IW5/InfoString/InfoStringToStructConverter.h" -#include "Game/IW5/InfoString/WeaponFields.h" -#include "Game/IW5/ObjConstantsIW5.h" -#include "InfoString/InfoString.h" -#include "ObjLoading.h" -#include "Pool/GlobalAssetPool.h" -#include "Utils/StringUtils.h" +#include "Game/IW5/Weapon/WeaponFields.h" #include "Weapon/AccuracyGraphLoader.h" +#include #include #include #include +#include using namespace IW5; @@ -31,7 +28,7 @@ namespace if (valueArray.size() > std::extent_v) { - std::cerr << "Cannot have more than " << std::extent_v << " hide tags!\n"; + std::cerr << std::format("Cannot have more than {} hide tags!\n", std::extent_v); return false; } @@ -39,7 +36,7 @@ namespace if (valueArray.size() < std::extent_v) { - m_used_script_string_list.emplace(m_zone_script_strings.AddOrGetScriptString(nullptr)); + m_registration.AddScriptString(m_zone_script_strings.AddOrGetScriptString(nullptr)); } auto currentHideTag = 0u; @@ -49,7 +46,7 @@ namespace const auto scrString = !currentValue.empty() ? m_zone_script_strings.AddOrGetScriptString(currentValue) : m_zone_script_strings.AddOrGetScriptString(nullptr); hideTags[currentHideTag] = scrString; - m_used_script_string_list.emplace(scrString); + m_registration.AddScriptString(scrString); } for (; currentHideTag < std::extent_v; currentHideTag++) @@ -60,7 +57,7 @@ namespace return true; } - _NODISCARD bool ConvertPerSurfaceTypeSound(const cspField_t& field, const std::string& value) const + [[nodiscard]] bool ConvertPerSurfaceTypeSound(const cspField_t& field, const std::string& value) const { auto** perSurfaceTypeSound = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); if (value.empty()) @@ -69,31 +66,31 @@ namespace return true; } - *perSurfaceTypeSound = m_memory->Alloc(SURF_TYPE_COUNT); + *perSurfaceTypeSound = m_memory.Alloc(SURF_TYPE_COUNT); for (auto i = 0u; i < SURF_TYPE_COUNT; i++) { const auto currentPerSurfaceTypeSound = value + surfaceTypeSoundSuffixes[i]; - (*perSurfaceTypeSound)[i].name = m_memory->Alloc(); - (*perSurfaceTypeSound)[i].name->soundName = m_memory->Dup(currentPerSurfaceTypeSound.c_str()); + (*perSurfaceTypeSound)[i].name = m_memory.Alloc(); + (*perSurfaceTypeSound)[i].name->soundName = m_memory.Dup(currentPerSurfaceTypeSound.c_str()); } return true; } - _NODISCARD bool ConvertNoteTrackMap(const cspField_t& field, const std::string& value, const char* mapName, const size_t keyAndValueCount) + [[nodiscard]] bool ConvertNoteTrackMap(const cspField_t& field, const std::string& value, const char* mapName, const size_t keyAndValueCount) { std::vector> pairs; if (!ParseAsArray(value, pairs)) { - std::cerr << "Failed to parse notetrack" << mapName << "map as pairs\n"; + std::cerr << std::format("Failed to parse notetrack{}map as pairs\n", mapName); return false; } if (pairs.size() > std::extent_v) { - std::cerr << "Cannot have more than " << std::extent_v << " notetrack" << mapName - << "map entries!\n"; + std::cerr << std::format( + "Cannot have more than {} notetrack{}map entries!\n", std::extent_v, mapName); return false; } @@ -103,7 +100,7 @@ namespace if (pairs.size() < keyAndValueCount) { - m_used_script_string_list.emplace(m_zone_script_strings.AddOrGetScriptString(nullptr)); + m_registration.AddScriptString(m_zone_script_strings.AddOrGetScriptString(nullptr)); } for (; currentEntryNum < pairs.size(); currentEntryNum++) @@ -115,10 +112,10 @@ namespace : m_zone_script_strings.AddOrGetScriptString(nullptr); keys[currentEntryNum] = keyScriptString; - m_used_script_string_list.emplace(keyScriptString); + m_registration.AddScriptString(keyScriptString); values[currentEntryNum] = valueScriptString; - m_used_script_string_list.emplace(valueScriptString); + m_registration.AddScriptString(valueScriptString); } for (; currentEntryNum < keyAndValueCount; currentEntryNum++) @@ -136,7 +133,7 @@ namespace if (ConvertString(value, field.iOffset)) { if (!value.empty()) - m_indirect_asset_references.emplace(m_loading_manager->LoadIndirectAssetReference(value)); + m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference(value)); return true; } @@ -158,41 +155,41 @@ namespace auto currentOther = 0u; for (const auto& attachmentName : valueArray) { - auto* attachmentInfo = m_loading_manager->LoadDependency(attachmentName); + auto* attachmentInfo = m_context.LoadDependency(attachmentName); if (!attachmentInfo) return false; - m_dependencies.emplace(attachmentInfo); + m_registration.AddDependency(attachmentInfo); auto* attachment = attachmentInfo->Asset(); if (attachment->type == ATTACHMENT_SCOPE) { if (currentScope >= std::extent_v) { - std::cerr << "Cannot have more than " << std::extent_v << " scopes\n"; + std::cerr << std::format("Cannot have more than {} scopes\n", std::extent_v); return false; } - m_weapon->scopes[currentScope++] = attachment; + m_weapon.scopes[currentScope++] = attachment; } else if (attachment->type == ATTACHMENT_UNDERBARREL) { if (currentUnderBarrel >= std::extent_v) { - std::cerr << "Cannot have more than " << std::extent_v << " under barrels\n"; + std::cerr << std::format("Cannot have more than {} under barrels\n", std::extent_v); return false; } - m_weapon->underBarrels[currentUnderBarrel++] = attachment; + m_weapon.underBarrels[currentUnderBarrel++] = attachment; } else if (attachment->type == ATTACHMENT_OTHER) { if (currentOther >= std::extent_v) { - std::cerr << "Cannot have more than " << std::extent_v << " other attachments\n"; + std::cerr << std::format("Cannot have more than {} other attachments\n", std::extent_v); return false; } - m_weapon->others[currentOther++] = attachment; + m_weapon.others[currentOther++] = attachment; } } @@ -208,7 +205,7 @@ namespace return false; } - auto* animOverrides = m_memory->Alloc(valueArray.size()); + auto* animOverrides = m_memory.Alloc(valueArray.size()); auto i = 0u; for (const auto& overrideValues : valueArray) @@ -234,8 +231,8 @@ namespace return false; } - m_weapon->weapCompleteDef.animOverrides = animOverrides; - m_weapon->weapCompleteDef.numAnimOverrides = valueArray.size(); + m_weapon.weapCompleteDef.animOverrides = animOverrides; + m_weapon.weapCompleteDef.numAnimOverrides = valueArray.size(); return true; } @@ -249,7 +246,7 @@ namespace return false; } - auto* soundOverrides = m_memory->Alloc(valueArray.size()); + auto* soundOverrides = m_memory.Alloc(valueArray.size()); auto i = 0u; for (const auto& overrideValues : valueArray) @@ -269,8 +266,8 @@ namespace ParseSoundAlias(overrideValues[4], soundOverride.altmodeSound); } - m_weapon->weapCompleteDef.soundOverrides = soundOverrides; - m_weapon->weapCompleteDef.numSoundOverrides = valueArray.size(); + m_weapon.weapCompleteDef.soundOverrides = soundOverrides; + m_weapon.weapCompleteDef.numSoundOverrides = valueArray.size(); return true; } @@ -284,7 +281,7 @@ namespace return false; } - auto* fxOverrides = m_memory->Alloc(valueArray.size()); + auto* fxOverrides = m_memory.Alloc(valueArray.size()); auto i = 0u; for (const auto& overrideValues : valueArray) @@ -307,8 +304,8 @@ namespace return false; } - m_weapon->weapCompleteDef.fxOverrides = fxOverrides; - m_weapon->weapCompleteDef.numFxOverrides = valueArray.size(); + m_weapon.weapCompleteDef.fxOverrides = fxOverrides; + m_weapon.weapCompleteDef.numFxOverrides = valueArray.size(); return true; } @@ -322,7 +319,7 @@ namespace return false; } - auto* reloadOverrides = m_memory->Alloc(valueArray.size()); + auto* reloadOverrides = m_memory.Alloc(valueArray.size()); auto i = 0u; for (const auto& overrideValues : valueArray) @@ -341,8 +338,8 @@ namespace return false; } - m_weapon->weapCompleteDef.reloadOverrides = reloadOverrides; - m_weapon->weapCompleteDef.numReloadStateTimerOverrides = valueArray.size(); + m_weapon.weapCompleteDef.reloadOverrides = reloadOverrides; + m_weapon.weapCompleteDef.numReloadStateTimerOverrides = valueArray.size(); return true; } @@ -373,15 +370,15 @@ namespace if (!ParseSingleWeaponAttachment(overrideValues[0], currentOverride.attachment)) return false; - currentOverride.notetrackSoundMapKeys = m_memory->Alloc(24u); - currentOverride.notetrackSoundMapValues = m_memory->Alloc(24u); + currentOverride.notetrackSoundMapKeys = m_memory.Alloc(24u); + currentOverride.notetrackSoundMapValues = m_memory.Alloc(24u); lastAttachment = overrideValues[0]; currentOverrideKeyOffset = 0u; } if (currentOverrideKeyOffset >= 24u) { - std::cerr << "Cannot have more than " << 24u << " note track overrides per attachment\n"; + std::cerr << std::format("Cannot have more than {} note track overrides per attachment\n", 24u); return false; } @@ -393,9 +390,9 @@ namespace if (currentOverrideKeyOffset > 0u) overrideVector.emplace_back(currentOverride); - m_weapon->weapCompleteDef.notetrackOverrides = m_memory->Alloc(overrideVector.size()); - memcpy(m_weapon->weapCompleteDef.notetrackOverrides, overrideVector.data(), sizeof(NoteTrackToSoundEntry) * overrideVector.size()); - m_weapon->weapCompleteDef.numNotetrackOverrides = overrideVector.size(); + m_weapon.weapCompleteDef.notetrackOverrides = m_memory.Alloc(overrideVector.size()); + memcpy(m_weapon.weapCompleteDef.notetrackOverrides, overrideVector.data(), sizeof(NoteTrackToSoundEntry) * overrideVector.size()); + m_weapon.weapCompleteDef.numNotetrackOverrides = overrideVector.size(); return true; } @@ -408,7 +405,7 @@ namespace for (auto i = 0u; i < std::extent_v; i++) { - const auto* scope = m_weapon->scopes[i]; + const auto* scope = m_weapon.scopes[i]; if (scope && scope->szInternalName && value == scope->szInternalName) { attachment.scope = static_cast(i + 1); @@ -418,7 +415,7 @@ namespace for (auto i = 0u; i < std::extent_v; i++) { - const auto* underBarrel = m_weapon->underBarrels[i]; + const auto* underBarrel = m_weapon.underBarrels[i]; if (underBarrel && underBarrel->szInternalName && value == underBarrel->szInternalName) { attachment.underBarrel = static_cast(i + 1); @@ -428,7 +425,7 @@ namespace for (auto i = 0u; i < std::extent_v; i++) { - const auto* other = m_weapon->others[i]; + const auto* other = m_weapon.others[i]; if (other && other->szInternalName && value == other->szInternalName) { attachment.other = static_cast(1u << i); @@ -436,7 +433,7 @@ namespace } } - std::cerr << "Weapon does not have attachment \"" << value << "\"\n"; + std::cerr << std::format("Weapon does not have attachment \"{}\"\n", value); return false; } @@ -448,8 +445,8 @@ namespace return; } - animName = m_memory->Dup(value.c_str()); - m_indirect_asset_references.emplace(m_loading_manager->LoadIndirectAssetReference(value)); + animName = m_memory.Dup(value.c_str()); + m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference(value)); } void ParseSoundAlias(const std::string& value, SndAliasCustom& soundAlias) @@ -460,9 +457,9 @@ namespace return; } - soundAlias.name = m_memory->Alloc(); - soundAlias.name->soundName = m_memory->Dup(value.c_str()); - m_indirect_asset_references.emplace(m_loading_manager->LoadIndirectAssetReference(value)); + soundAlias.name = m_memory.Alloc(); + soundAlias.name->soundName = m_memory.Dup(value.c_str()); + m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference(value)); } bool ParseFxEffectDef(const std::string& value, FxEffectDef*& fx) @@ -473,15 +470,15 @@ namespace return true; } - auto* fxInfo = m_loading_manager->LoadDependency(value); + auto* fxInfo = m_context.LoadDependency(value); if (!fxInfo) { - std::cerr << "Failed to load fx for override \"" << value << "\"\n"; + std::cerr << std::format("Failed to load fx for override \"{}\"\n", value); return false; } fx = fxInfo->Asset(); - m_dependencies.emplace(fxInfo); + m_registration.AddDependency(fxInfo); return true; } @@ -497,7 +494,7 @@ namespace } } - std::cerr << "Unknown anim file \"" << value << "\"\n"; + std::cerr << std::format("Unknown anim file \"{}\"\n", value); return false; } @@ -512,7 +509,7 @@ namespace } } - std::cerr << "Unknown sound type \"" << value << "\"\n"; + std::cerr << std::format("Unknown sound type \"{}\"\n", value); return false; } @@ -527,7 +524,7 @@ namespace } } - std::cerr << "Unknown fx type \"" << value << "\"\n"; + std::cerr << std::format("Unknown fx type \"{}\"\n", value); return false; } @@ -538,7 +535,7 @@ namespace if (size != value.size()) { - std::cerr << "Invalid int value: \"" << value << "\"\n"; + std::cerr << std::format("Invalid int value: \"{}\"\n", value); return false; } @@ -548,7 +545,7 @@ namespace void ParseScriptString(const std::string& value, ScriptString& out) { out = m_zone_script_strings.AddOrGetScriptString(value); - m_used_script_string_list.emplace(out); + m_registration.AddScriptString(out); } protected: @@ -652,47 +649,48 @@ namespace public: InfoStringToWeaponConverter(const InfoString& infoString, - WeaponFullDef* weaponFullDef, + WeaponFullDef& weaponFullDef, ZoneScriptStrings& zoneScriptStrings, - MemoryManager* memory, - IAssetLoadingManager* manager, + MemoryManager& memory, + AssetCreationContext& context, + AssetRegistration& registration, const cspField_t* fields, const size_t fieldCount) - : InfoStringToStructConverter(infoString, weaponFullDef, zoneScriptStrings, memory, manager, fields, fieldCount) + : InfoStringToStructConverter(infoString, &weaponFullDef, zoneScriptStrings, memory, context, registration, fields, fieldCount), + m_weapon(weaponFullDef) { - m_weapon = weaponFullDef; } private: - WeaponFullDef* m_weapon; + WeaponFullDef& m_weapon; }; - void InitWeaponFullDef(WeaponFullDef* weapon) + void InitWeaponFullDef(WeaponFullDef& weapon) { - weapon->weapCompleteDef.weapDef = &weapon->weapDef; - weapon->weapCompleteDef.hideTags = weapon->hideTags; - weapon->weapCompleteDef.szXAnims = weapon->szXAnims; - weapon->weapCompleteDef.scopes = weapon->scopes; - weapon->weapCompleteDef.underBarrels = weapon->underBarrels; - weapon->weapCompleteDef.others = weapon->others; - weapon->weapDef.gunXModel = weapon->gunXModel; - weapon->weapDef.szXAnimsRightHanded = weapon->szXAnimsRightHanded; - weapon->weapDef.szXAnimsLeftHanded = weapon->szXAnimsLeftHanded; - weapon->weapDef.notetrackSoundMapKeys = weapon->notetrackSoundMapKeys; - weapon->weapDef.notetrackSoundMapValues = weapon->notetrackSoundMapValues; - weapon->weapDef.notetrackRumbleMapKeys = weapon->notetrackRumbleMapKeys; - weapon->weapDef.notetrackRumbleMapValues = weapon->notetrackRumbleMapValues; - weapon->weapDef.worldModel = weapon->worldModel; - weapon->weapDef.parallelBounce = weapon->parallelBounce; - weapon->weapDef.perpendicularBounce = weapon->perpendicularBounce; - weapon->weapDef.locationDamageMultipliers = weapon->locationDamageMultipliers; + weapon.weapCompleteDef.weapDef = &weapon.weapDef; + weapon.weapCompleteDef.hideTags = weapon.hideTags; + weapon.weapCompleteDef.szXAnims = weapon.szXAnims; + weapon.weapCompleteDef.scopes = weapon.scopes; + weapon.weapCompleteDef.underBarrels = weapon.underBarrels; + weapon.weapCompleteDef.others = weapon.others; + weapon.weapDef.gunXModel = weapon.gunXModel; + weapon.weapDef.szXAnimsRightHanded = weapon.szXAnimsRightHanded; + weapon.weapDef.szXAnimsLeftHanded = weapon.szXAnimsLeftHanded; + weapon.weapDef.notetrackSoundMapKeys = weapon.notetrackSoundMapKeys; + weapon.weapDef.notetrackSoundMapValues = weapon.notetrackSoundMapValues; + weapon.weapDef.notetrackRumbleMapKeys = weapon.notetrackRumbleMapKeys; + weapon.weapDef.notetrackRumbleMapValues = weapon.notetrackRumbleMapValues; + weapon.weapDef.worldModel = weapon.worldModel; + weapon.weapDef.parallelBounce = weapon.parallelBounce; + weapon.weapDef.perpendicularBounce = weapon.perpendicularBounce; + weapon.weapDef.locationDamageMultipliers = weapon.locationDamageMultipliers; for (const auto& field : weapon_fields) { if (field.iFieldType != CSPFT_STRING) continue; - *reinterpret_cast(reinterpret_cast(weapon) + field.iOffset) = ""; + *reinterpret_cast(reinterpret_cast(&weapon) + field.iOffset) = ""; } } @@ -743,10 +741,10 @@ namespace } } - void CalculateWeaponFields(WeaponFullDef* weapon, MemoryManager* memory) + void CalculateWeaponFields(WeaponFullDef& weapon, MemoryManager& memory) { - auto& weaponCompleteDef = weapon->weapCompleteDef; - auto& weaponDef = weapon->weapDef; + auto& weaponCompleteDef = weapon.weapCompleteDef; + auto& weaponDef = weapon.weapDef; if (!weaponDef.viewLastShotEjectEffect) weaponDef.viewLastShotEjectEffect = weaponDef.viewShellEjectEffect; @@ -806,10 +804,10 @@ namespace uint16_t& originalGraphKnotCount, vec2_t*& graphKnots, uint16_t& graphKnotCount, - MemoryManager* memory) + MemoryManager& memory) { originalGraphKnotCount = static_cast(graph.knots.size()); - originalGraphKnots = memory->Alloc(originalGraphKnotCount); + originalGraphKnots = memory.Alloc(originalGraphKnotCount); for (auto i = 0u; i < originalGraphKnotCount; i++) { @@ -822,116 +820,69 @@ namespace graphKnotCount = originalGraphKnotCount; } - bool LoadAccuracyGraphs(WeaponFullDef* weaponFullDef, MemoryManager* memory, const IAssetLoadingManager* manager) + bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) { - auto* accuracyGraphLoader = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); + auto* accuracyGraphLoader = context.GetZoneAssetLoaderState(); - if (weaponFullDef->weapDef.aiVsAiAccuracyGraphName && weaponFullDef->weapDef.aiVsAiAccuracyGraphName[0]) + if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader->LoadAiVsAiGraph(manager, weaponFullDef->weapDef.aiVsAiAccuracyGraphName); + const auto* graph = accuracyGraphLoader->LoadAiVsAiGraph(searchPath, weaponFullDef.weapDef.aiVsAiAccuracyGraphName); if (!graph) return false; ConvertAccuracyGraph(*graph, - weaponFullDef->weapDef.originalAiVsAiAccuracyGraphKnots, - weaponFullDef->weapDef.originalAiVsAiAccuracyGraphKnotCount, - weaponFullDef->weapCompleteDef.aiVsAiAccuracyGraphKnots, - weaponFullDef->weapCompleteDef.aiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnotCount, memory); } - if (weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName[0]) + if (weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader->LoadAiVsPlayerGraph(manager, weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName); + const auto* graph = accuracyGraphLoader->LoadAiVsPlayerGraph(searchPath, weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName); if (!graph) return false; ConvertAccuracyGraph(*graph, - weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnots, - weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnotCount, - weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnots, - weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, memory); } return true; } - - bool LoadFromInfoString(const InfoString& infoString, const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) - { - auto* weaponFullDef = memory->Create(); - memset(weaponFullDef, 0, sizeof(WeaponFullDef)); - InitWeaponFullDef(weaponFullDef); - weaponFullDef->weapCompleteDef.szInternalName = memory->Dup(assetName.c_str()); - - InfoStringToWeaponConverter converter( - infoString, weaponFullDef, zone->m_script_strings, memory, manager, weapon_fields, std::extent_v); - if (!converter.Convert()) - { - std::cerr << "Failed to parse weapon: \"" << assetName << "\"\n"; - return true; - } - - CalculateWeaponFields(weaponFullDef, memory); - - LoadAccuracyGraphs(weaponFullDef, memory, manager); - - manager->AddAsset( - assetName, &weaponFullDef->weapCompleteDef, converter.GetDependencies(), converter.GetUsedScriptStrings(), converter.GetIndirectAssetReferences()); - - return true; - } } // namespace -void* AssetLoaderWeapon::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +InfoStringLoaderWeapon::InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) + : m_memory(memory), + m_search_path(searchPath), + m_zone(zone) { - auto* weapon = memory->Create(); - memset(weapon, 0, sizeof(WeaponCompleteDef)); - weapon->szInternalName = memory->Dup(assetName.c_str()); - return weapon; } -bool AssetLoaderWeapon::CanLoadFromGdt() const +AssetCreationResult InfoStringLoaderWeapon::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) { - return true; -} + auto* weaponFullDef = m_memory.Alloc(); -bool AssetLoaderWeapon::LoadFromGdt( - const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto* gdtEntry = gdtQueryable->GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_WEAPON, assetName); - if (gdtEntry == nullptr) - return false; + InitWeaponFullDef(*weaponFullDef); + weaponFullDef->weapCompleteDef.szInternalName = m_memory.Dup(assetName.c_str()); - InfoString infoString; - if (!infoString.FromGdtProperties(*gdtEntry)) + AssetRegistration registration(assetName, &weaponFullDef->weapCompleteDef); + + InfoStringToWeaponConverter converter( + infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v); + if (!converter.Convert()) { - std::cerr << "Failed to read weapon gdt entry: \"" << assetName << "\"\n"; - return true; + std::cerr << std::format("Failed to parse weapon: \"{}\"\n", assetName); + return AssetCreationResult::Failure(); } - return LoadFromInfoString(infoString, assetName, memory, manager, zone); -} - -bool AssetLoaderWeapon::CanLoadFromRaw() const -{ - return true; -} - -bool AssetLoaderWeapon::LoadFromRaw( - const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const -{ - const auto fileName = std::format("weapons/{}", assetName); - const auto file = searchPath->Open(fileName); - if (!file.IsOpen()) - return false; - - InfoString infoString; - if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_WEAPON, *file.m_stream)) - { - std::cerr << "Could not parse as info string file: \"" << fileName << "\"\n"; - return true; - } - - return LoadFromInfoString(infoString, assetName, memory, manager, zone); + CalculateWeaponFields(*weaponFullDef, m_memory); + + LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context); + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } diff --git a/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.h b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.h new file mode 100644 index 00000000..06d6e076 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Asset/AssetCreationContext.h" +#include "Asset/AssetCreationResult.h" +#include "InfoString/InfoString.h" + +namespace IW5 +{ + class InfoStringLoaderWeapon + { + public: + InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone); + + AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context); + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + Zone& m_zone; + }; +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.cpp b/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.cpp index 71a77664..f6ef081e 100644 --- a/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.cpp +++ b/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.cpp @@ -15,16 +15,11 @@ namespace class JsonLoader { public: - JsonLoader(std::istream& stream, - MemoryManager& memory, - IAssetLoadingManager& manager, - std::vector& dependencies, - std::vector& indirectAssetReferences) + JsonLoader(std::istream& stream, MemoryManager& memory, AssetCreationContext& context, AssetRegistration& registration) : m_stream(stream), m_memory(memory), - m_manager(manager), - m_dependencies(dependencies), - m_indirect_asset_references(indirectAssetReferences) + m_context(context), + m_registration(registration) { } @@ -129,13 +124,13 @@ namespace bool CreateTracerFromJson(const std::string& assetName, TracerDef*& tracerPtr, const WeaponAttachment& attachment) const { - auto* tracer = m_manager.LoadDependency(assetName); + auto* tracer = m_context.LoadDependency(assetName); if (!tracer) { PrintError(attachment, std::format("Could not find tracer {}", assetName)); return false; } - m_dependencies.push_back(tracer); + m_registration.AddDependency(tracer); tracerPtr = tracer->Asset(); return true; @@ -143,13 +138,13 @@ namespace bool CreateMaterialFromJson(const std::string& assetName, Material*& materialPtr, const WeaponAttachment& attachment) const { - auto* material = m_manager.LoadDependency(assetName); + auto* material = m_context.LoadDependency(assetName); if (!material) { PrintError(attachment, std::format("Could not find material {}", assetName)); return false; } - m_dependencies.push_back(material); + m_registration.AddDependency(material); materialPtr = material->Asset(); return true; @@ -157,13 +152,13 @@ namespace bool CreateFxFromJson(const std::string& assetName, FxEffectDef*& fxPtr, const WeaponAttachment& attachment) const { - auto* fx = m_manager.LoadDependency(assetName); + auto* fx = m_context.LoadDependency(assetName); if (!fx) { PrintError(attachment, std::format("Could not find fx {}", assetName)); return false; } - m_dependencies.push_back(fx); + m_registration.AddDependency(fx); fxPtr = fx->Asset(); return true; @@ -171,8 +166,7 @@ namespace bool CreateSoundFromJson(const std::string& assetName, SndAliasCustom& sndAliasCustom, const WeaponAttachment& attachment) const { - auto sound = m_manager.LoadIndirectAssetReference(assetName); - m_indirect_asset_references.push_back(std::move(sound)); + m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference(assetName)); sndAliasCustom.name = m_memory.Alloc(); sndAliasCustom.name->soundName = m_memory.Dup(assetName.c_str()); @@ -181,13 +175,13 @@ namespace bool CreateXModelFromJson(const std::string& assetName, XModel*& xmodelPtr, const WeaponAttachment& attachment) const { - auto* xmodel = m_manager.LoadDependency(assetName); + auto* xmodel = m_context.LoadDependency(assetName); if (!xmodel) { PrintError(attachment, std::format("Could not find xmodel {}", assetName)); return false; } - m_dependencies.push_back(xmodel); + m_registration.AddDependency(xmodel); xmodelPtr = xmodel->Asset(); return true; @@ -631,9 +625,8 @@ namespace std::istream& m_stream; MemoryManager& m_memory; - IAssetLoadingManager& m_manager; - std::vector& m_dependencies; - std::vector& m_indirect_asset_references; + AssetCreationContext& m_context; + AssetRegistration& m_registration; }; } // namespace @@ -641,12 +634,11 @@ namespace IW5 { bool LoadWeaponAttachmentAsJson(std::istream& stream, WeaponAttachment& attachment, - MemoryManager* memory, - IAssetLoadingManager* manager, - std::vector& dependencies, - std::vector& indirectAssetReferences) + MemoryManager& memory, + AssetCreationContext& context, + AssetRegistration& registration) { - const JsonLoader loader(stream, *memory, *manager, dependencies, indirectAssetReferences); + const JsonLoader loader(stream, memory, context, registration); return loader.Load(attachment); } diff --git a/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.h b/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.h index 8bf8df8b..5b9d7b06 100644 --- a/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.h +++ b/src/ObjLoading/Game/IW5/Weapon/JsonWeaponAttachmentLoader.h @@ -1,6 +1,7 @@ #pragma once -#include "AssetLoading/IAssetLoadingManager.h" +#include "Asset/AssetCreationContext.h" +#include "Asset/AssetRegistration.h" #include "Game/IW5/IW5.h" #include "Utils/MemoryManager.h" @@ -10,8 +11,7 @@ namespace IW5 { bool LoadWeaponAttachmentAsJson(std::istream& stream, WeaponAttachment& attachment, - MemoryManager* memory, - IAssetLoadingManager* manager, - std::vector& dependencies, - std::vector& indirectAssetReferences); + MemoryManager& memory, + AssetCreationContext& context, + AssetRegistration& registration); } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.cpp b/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.cpp new file mode 100644 index 00000000..ac7197c1 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.cpp @@ -0,0 +1,54 @@ +#include "LoaderAttachmentIW5.h" + +#include "Game/IW5/IW5.h" +#include "JsonWeaponAttachmentLoader.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + class AttachmentLoader final : public AssetCreator + { + public: + AttachmentLoader(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("attachment/{}.json", assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* attachment = m_memory.Alloc(); + attachment->szInternalName = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, attachment); + if (!LoadWeaponAttachmentAsJson(*file.m_stream, *attachment, m_memory, context, registration)) + { + std::cerr << std::format("Failed to load attachment \"{}\"\n", assetName); + return AssetCreationResult::Failure(); + } + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.h b/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.h new file mode 100644 index 00000000..ec43ff96 --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/LoaderAttachmentIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.cpp b/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.cpp new file mode 100644 index 00000000..642efa2e --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.cpp @@ -0,0 +1,54 @@ +#include "RawLoaderWeaponIW5.h" + +#include "Game/IW5/IW5.h" +#include "Game/IW5/ObjConstantsIW5.h" +#include "InfoString/InfoString.h" +#include "InfoStringLoaderWeaponIW5.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + class RawLoaderWeapon final : public AssetCreator + { + public: + RawLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) + : m_search_path(searchPath), + m_info_string_loader(memory, searchPath, zone) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto fileName = std::format("weapons/{}", assetName); + const auto file = m_search_path.Open(fileName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + InfoString infoString; + if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_WEAPON, *file.m_stream)) + { + std::cerr << std::format("Could not parse as info string file: \"{}\"\n", fileName); + return AssetCreationResult::Failure(); + } + + return m_info_string_loader.CreateAsset(assetName, infoString, context); + } + + private: + ISearchPath& m_search_path; + InfoStringLoaderWeapon m_info_string_loader; + }; +} // namespace + +namespace IW5 +{ + std::unique_ptr> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) + { + return std::make_unique(memory, searchPath, zone); + } +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.h b/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.h new file mode 100644 index 00000000..d5df5fcf --- /dev/null +++ b/src/ObjLoading/Game/IW5/Weapon/RawLoaderWeaponIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace IW5 +{ + std::unique_ptr> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone); +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.cpp b/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.cpp new file mode 100644 index 00000000..973d59f3 --- /dev/null +++ b/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.cpp @@ -0,0 +1,55 @@ +// #include "LoaderXModelIW5.h" + +// #include "Game/IW5/IW5.h" +// #include "Game/IW5/XModel/XModelLoaderIW5.h" +// #include "Pool/GlobalAssetPool.h" + +// #include +// #include +// #include + +// using namespace IW5; + +// namespace +// { +// class XModelLoader final : public AssetCreator +// { +// public: +// XModelLoader(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("xmodel/{}.json", assetName)); +// if (!file.IsOpen()) +// return AssetCreationResult::NoAction(); + +// auto* xmodel = m_memory.Alloc(); +// xmodel->name = m_memory.Dup(assetName.c_str()); + +// AssetRegistration registration(assetName, xmodel); +// if (!LoadXModel(*file.m_stream, *xmodel, m_memory, context, registration)) +// { +// std::cerr << std::format("Failed to load xmodel \"{}\"\n", assetName); +// return AssetCreationResult::Failure(); +// } + +// return AssetCreationResult::Success(context.AddAsset(std::move(registration))); +// } + +// private: +// MemoryManager& m_memory; +// ISearchPath& m_search_path; +// }; +// } // namespace + +// namespace IW5 +// { +// std::unique_ptr> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath) +// { +// return std::make_unique(memory, searchPath); +// } +// } // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.h b/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.h new file mode 100644 index 00000000..3d656f21 --- /dev/null +++ b/src/ObjLoading/Game/IW5/XModel/LoaderXModelIW5asdf.h @@ -0,0 +1,13 @@ +// #pragma once + +// #include "Asset/IAssetCreator.h" +// #include "Game/IW5/IW5.h" +// #include "SearchPath/ISearchPath.h" +// #include "Utils/MemoryManager.h" + +// #include + +// namespace IW5 +// { +// std::unique_ptr> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath); +// } // namespace IW5 diff --git a/src/ObjLoading/XModel/XModelLoader.cpp.template b/src/ObjLoading/XModel/LoaderXModel.cpp.template similarity index 92% rename from src/ObjLoading/XModel/XModelLoader.cpp.template rename to src/ObjLoading/XModel/LoaderXModel.cpp.template index 01994f05..28447a8d 100644 --- a/src/ObjLoading/XModel/XModelLoader.cpp.template +++ b/src/ObjLoading/XModel/LoaderXModel.cpp.template @@ -1,8 +1,8 @@ #options GAME(IW5, T5, T6) -#filename "Game/" + GAME + "/XModel/XModelLoader" + GAME + ".cpp" +#filename "Game/" + GAME + "/XModel/LoaderXModel" + GAME + ".cpp" -#set LOADER_HEADER "\"XModelLoader" + GAME + ".h\"" +#set LOADER_HEADER "\"LoaderXModel" + GAME + ".h\"" #set COMMON_HEADER "\"Game/" + GAME + "/Common" + GAME + ".h\"" #set CONSTANTS_HEADER "\"Game/" + GAME + "/XModel/XModelConstants" + GAME + ".h\"" #set JSON_HEADER "\"Game/" + GAME + "/XModel/JsonXModel" + GAME + ".h\"" @@ -21,6 +21,7 @@ #include CONSTANTS_HEADER #include JSON_HEADER +#include "Asset/AssetRegistration.h" #include "ObjLoading.h" #include "Utils/QuatInt16.h" #include "Utils/StringUtils.h" @@ -46,25 +47,43 @@ #include #include -namespace GAME +using namespace GAME; + +namespace { - class XModelLoader + class XModelLoader final : public AssetCreator { public: - XModelLoader(std::istream& stream, MemoryManager& memory, IAssetLoadingManager& manager, std::set& dependencies) - : m_stream(stream), - m_memory(memory), - m_script_strings(manager.GetAssetLoadingContext()->m_zone.m_script_strings), - m_manager(manager), - m_part_classification_state(*m_manager.GetAssetLoadingContext()->GetZoneAssetLoaderState()), - m_dependencies(dependencies) - + XModelLoader(MemoryManager& memory, ISearchPath& searchPath, ZoneScriptStrings& scriptStrings) + : m_memory(memory), + m_search_path(searchPath), + m_script_strings(scriptStrings) { } - bool Load(XModel& xmodel) + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override { - const auto jRoot = nlohmann::json::parse(m_stream); + const auto file = m_search_path.Open(std::format("xmodel/{}.json", assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* xmodel = m_memory.Alloc(); + xmodel->name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, xmodel); + if (!LoadFromFile(*file.m_stream, *xmodel, context, registration)) + { + std::cerr << std::format("Failed to load xmodel \"{}\"\n", assetName); + return AssetCreationResult::Failure(); + } + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + bool LoadFromFile(std::istream& jsonStream, XModel& xmodel, AssetCreationContext& context, AssetRegistration& registration) + { + const auto jRoot = nlohmann::json::parse(jsonStream); std::string type; unsigned version; @@ -80,7 +99,7 @@ namespace GAME try { const auto jXModel = jRoot.get(); - return CreateXModelFromJson(jXModel, xmodel); + return CreateXModelFromJson(jXModel, xmodel, context, registration); } catch (const nlohmann::json::exception& e) { @@ -90,7 +109,6 @@ namespace GAME return false; } - private: static void PrintError(const XModel& xmodel, const std::string& message) { std::cerr << std::format("Cannot load xmodel \"{}\": {}\n", xmodel.name, message); @@ -234,12 +252,12 @@ namespace GAME info.radiusSquared = halfSizeEigen.squaredNorm(); } - bool ApplyCommonBonesToXModel(const JsonXModelLod& jLod, XModel& xmodel, unsigned lodNumber, const XModelCommon& common) const + bool ApplyCommonBonesToXModel(const JsonXModelLod& jLod, XModel& xmodel, unsigned lodNumber, const XModelCommon& common) { if (common.m_bones.empty()) return true; - m_part_classification_state.Load(HITLOC_NAMES, std::extent_v, m_manager); + m_part_classification_state.Load(HITLOC_NAMES, std::extent_v, m_search_path); const auto boneCount = common.m_bones.size(); constexpr auto maxBones = std::numeric_limits::max(); @@ -614,9 +632,9 @@ namespace GAME return true; } - bool LoadLod(const JsonXModelLod& jLod, XModel& xmodel, unsigned lodNumber) + bool LoadLod(const JsonXModelLod& jLod, XModel& xmodel, unsigned lodNumber, AssetCreationContext& context, AssetRegistration& registration) { - const auto file = m_manager.GetAssetLoadingContext()->m_raw_search_path.Open(jLod.file); + const auto file = m_search_path.Open(jLod.file); if (!file.IsOpen()) { PrintError(xmodel, std::format("Failed to open file for lod {}: \"{}\"", lodNumber, jLod.file)); @@ -664,11 +682,11 @@ namespace GAME materialAssets.reserve(common->m_materials.size()); for (const auto& commonMaterial : common->m_materials) { - auto* assetInfo = m_manager.LoadDependency(commonMaterial.name); + auto* assetInfo = context.LoadDependency(commonMaterial.name); if (!assetInfo) return false; - m_dependencies.emplace(assetInfo); + registration.AddDependency(assetInfo); materialAssets.push_back(assetInfo->Asset()); } @@ -712,7 +730,7 @@ namespace GAME modelSurfs->surfs = m_memory.Alloc(modelSurfs->numsurfs); memcpy(modelSurfs->surfs, &m_surfaces[lodInfo.surfIndex], sizeof(XSurface) * modelSurfs->numsurfs); - m_manager.AddAsset(modelSurfsName, modelSurfs); + registration.AddDependency(context.AddAsset(modelSurfsName, modelSurfs)); lodInfo.modelSurfs = modelSurfs; lodInfo.surfs = modelSurfs->surfs; @@ -785,7 +803,7 @@ namespace GAME #endif } - bool CreateXModelFromJson(const JsonXModel& jXModel, XModel& xmodel) + bool CreateXModelFromJson(const JsonXModel& jXModel, XModel& xmodel, AssetCreationContext& context, AssetRegistration& registration) { constexpr auto maxLods = std::extent_v; if (jXModel.lods.size() > maxLods) @@ -798,7 +816,7 @@ namespace GAME xmodel.numLods = static_cast(jXModel.lods.size()); for (const auto& jLod : jXModel.lods) { - if (!LoadLod(jLod, xmodel, lodNumber++)) + if (!LoadLod(jLod, xmodel, lodNumber++, context, registration)) return false; } @@ -835,13 +853,13 @@ namespace GAME if (jXModel.physPreset) { - auto* physPreset = m_manager.LoadDependency(jXModel.physPreset.value()); + auto* physPreset = context.LoadDependency(jXModel.physPreset.value()); if (!physPreset) { PrintError(xmodel, "Could not find phys preset"); return false; } - m_dependencies.emplace(physPreset); + registration.AddDependency(physPreset); xmodel.physPreset = physPreset->Asset(); } else @@ -852,13 +870,13 @@ namespace GAME #if defined(FEATURE_IW5) if (jXModel.physCollmap) { - auto* physCollmap = m_manager.LoadDependency(jXModel.physCollmap.value()); + auto* physCollmap = context.LoadDependency(jXModel.physCollmap.value()); if (!physCollmap) { PrintError(xmodel, "Could not find phys collmap"); return false; } - m_dependencies.emplace(physCollmap); + registration.AddDependency(physCollmap); xmodel.physCollmap = physCollmap->Asset(); } else @@ -870,13 +888,13 @@ namespace GAME #if defined(FEATURE_T5) || defined(FEATURE_T6) if (jXModel.physConstraints) { - auto* physConstraints = m_manager.LoadDependency(jXModel.physConstraints.value()); + auto* physConstraints = context.LoadDependency(jXModel.physConstraints.value()); if (!physConstraints) { PrintError(xmodel, "Could not find phys constraints"); return false; } - m_dependencies.emplace(physConstraints); + registration.AddDependency(physConstraints); xmodel.physConstraints = physConstraints->Asset(); } else @@ -900,21 +918,17 @@ namespace GAME std::vector m_surfaces; std::vector m_materials; - std::istream& m_stream; MemoryManager& m_memory; + ISearchPath& m_search_path; ZoneScriptStrings& m_script_strings; - IAssetLoadingManager& m_manager; - PartClassificationState& m_part_classification_state; - std::set& m_dependencies; + PartClassificationState m_part_classification_state; }; +} // namespace GAME - bool LoadXModel(std::istream& stream, XModel& xmodel, MemoryManager* memory, IAssetLoadingManager* manager, std::vector& dependencies) +namespace GAME +{ + std::unique_ptr> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone) { - std::set dependenciesSet; - XModelLoader loader(stream, *memory, *manager, dependenciesSet); - - dependencies.assign(dependenciesSet.cbegin(), dependenciesSet.cend()); - - return loader.Load(xmodel); + return std::make_unique(memory, searchPath, zone.m_script_strings); } } // namespace GAME diff --git a/src/ObjLoading/XModel/LoaderXModel.h.template b/src/ObjLoading/XModel/LoaderXModel.h.template new file mode 100644 index 00000000..16075cb2 --- /dev/null +++ b/src/ObjLoading/XModel/LoaderXModel.h.template @@ -0,0 +1,19 @@ +#options GAME (IW5, T5, T6) + +#filename "Game/" + GAME + "/XModel/LoaderXModel" + GAME + ".h" + +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" + +#pragma once + +#include "Asset/IAssetCreator.h" +#include GAME_HEADER +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace GAME +{ + std::unique_ptr> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone); +} // namespace GAME diff --git a/src/ObjLoading/XModel/PartClassificationState.cpp b/src/ObjLoading/XModel/PartClassificationState.cpp index 6667a4df..e314b03e 100644 --- a/src/ObjLoading/XModel/PartClassificationState.cpp +++ b/src/ObjLoading/XModel/PartClassificationState.cpp @@ -12,7 +12,7 @@ PartClassificationState::PartClassificationState() { } -bool PartClassificationState::Load(const char** hitLocNames, const size_t hitLocNameCount, const IAssetLoadingManager& manager) +bool PartClassificationState::Load(const char** hitLocNames, const size_t hitLocNameCount, ISearchPath& searchPath) { if (m_loaded) return true; @@ -20,7 +20,7 @@ bool PartClassificationState::Load(const char** hitLocNames, const size_t hitLoc if (ObjLoading::Configuration.Verbose) std::cout << "Loading part classification...\n"; - const auto file = manager.GetAssetLoadingContext()->m_raw_search_path.Open(PART_CLASSIFICATION_FILE); + const auto file = searchPath.Open(PART_CLASSIFICATION_FILE); if (!file.IsOpen()) { std::cerr << std::format("Could not load part classification: Failed to open {}\n", PART_CLASSIFICATION_FILE); diff --git a/src/ObjLoading/XModel/PartClassificationState.h b/src/ObjLoading/XModel/PartClassificationState.h index 32bd4afc..76e95a11 100644 --- a/src/ObjLoading/XModel/PartClassificationState.h +++ b/src/ObjLoading/XModel/PartClassificationState.h @@ -1,8 +1,13 @@ #pragma once -#include "AssetLoading/IAssetLoadingManager.h" -#include "AssetLoading/IZoneAssetLoaderState.h" -class PartClassificationState final : public IZoneAssetLoaderState +#include "SearchPath/ISearchPath.h" + +#include +#include +#include +#include + +class PartClassificationState { // TODO: Use MP part classifications when building an mp fastfile static constexpr auto PART_CLASSIFICATION_FILE = "partclassification.csv"; @@ -12,7 +17,7 @@ class PartClassificationState final : public IZoneAssetLoaderState public: PartClassificationState(); - bool Load(const char** hitLocNames, size_t hitLocNameCount, const IAssetLoadingManager& manager); + bool Load(const char** hitLocNames, size_t hitLocNameCount, ISearchPath& searchPath); [[nodiscard]] unsigned GetPartClassificationForBoneName(const std::string& boneName) const; diff --git a/src/ObjLoading/XModel/XModelLoader.h.template b/src/ObjLoading/XModel/XModelLoader.h.template deleted file mode 100644 index 3b9d0729..00000000 --- a/src/ObjLoading/XModel/XModelLoader.h.template +++ /dev/null @@ -1,19 +0,0 @@ -#options GAME (IW5, T5, T6) - -#filename "Game/" + GAME + "/XModel/XModelLoader" + GAME + ".h" - -#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" - -#pragma once - -#include "AssetLoading/IAssetLoadingManager.h" -#include GAME_HEADER -#include "Utils/MemoryManager.h" - -#include -#include - -namespace GAME -{ - bool LoadXModel(std::istream& stream, XModel& xmodel, MemoryManager* memory, IAssetLoadingManager* manager, std::vector& dependencies); -} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 15d5fd5b..83e4cc93 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -2,8 +2,8 @@ #include "Game/IW5/CommonIW5.h" #include "Game/IW5/InfoString/InfoStringFromStructConverter.h" -#include "Game/IW5/InfoString/WeaponFields.h" #include "Game/IW5/ObjConstantsIW5.h" +#include "Game/IW5/Weapon/WeaponFields.h" #include "Weapon/AccuracyGraphWriter.h" #include