diff --git a/src/Common/Game/IGame.h b/src/Common/Game/IGame.h index d8021ee2..a53ed7b6 100644 --- a/src/Common/Game/IGame.h +++ b/src/Common/Game/IGame.h @@ -2,10 +2,11 @@ #include "GameLanguage.h" +#include #include #include -enum class GameId +enum class GameId : std::uint8_t { IW3, IW4, @@ -18,7 +19,7 @@ enum class GameId // The full uppercase names are macros in the standard lib // So unfortunately not usable as values in the enum -enum class GameEndianness +enum class GameEndianness : std::uint8_t { /* Little endian */ LE, @@ -26,12 +27,19 @@ enum class GameEndianness BE }; -enum class GameWordSize +enum class GameWordSize : std::uint8_t { ARCH_32, ARCH_64 }; +enum class GamePlatform : std::uint8_t +{ + PC, + XBOX, + PS3 +}; + static constexpr const char* GameId_Names[]{ "IW3", "IW4", diff --git a/src/Common/Utils/ProgressCallback.h b/src/Common/Utils/ProgressCallback.h new file mode 100644 index 00000000..d2222d84 --- /dev/null +++ b/src/Common/Utils/ProgressCallback.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class ProgressCallback +{ +public: + ProgressCallback() = default; + virtual ~ProgressCallback() = default; + + virtual void OnProgress(size_t current, size_t total) = 0; +}; diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index 3da46b23..b7dce2bd 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -364,7 +364,7 @@ class LinkerImpl final : public Linker zoneDirectory = fs::current_path(); auto absoluteZoneDirectory = absolute(zoneDirectory).string(); - auto maybeZone = ZoneLoading::LoadZone(zonePath); + auto maybeZone = ZoneLoading::LoadZone(zonePath, std::nullopt); if (!maybeZone) { con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error()); diff --git a/src/ModMan/Context/FastFileContext.cpp b/src/ModMan/Context/FastFileContext.cpp index 3af0d92d..2a5f8112 100644 --- a/src/ModMan/Context/FastFileContext.cpp +++ b/src/ModMan/Context/FastFileContext.cpp @@ -4,6 +4,40 @@ #include "Web/UiCommunication.h" #include "ZoneLoading.h" +#include + +namespace fs = std::filesystem; + +namespace +{ + constexpr double MIN_PROGRESS_TO_REPORT = 0.005; + + class LoadingEventProgressReporter : public ProgressCallback + { + public: + explicit LoadingEventProgressReporter(std::string zoneName) + : m_zone_name(std::move(zoneName)), + m_last_progress(0) + { + } + + void OnProgress(const size_t current, const size_t total) override + { + const double percentage = static_cast(current) / static_cast(total); + + if (percentage - m_last_progress >= MIN_PROGRESS_TO_REPORT) + { + m_last_progress = percentage; + ui::NotifyZoneLoadProgress(m_zone_name, percentage); + } + } + + private: + std::string m_zone_name; + double m_last_progress; + }; +} // namespace + void FastFileContext::Destroy() { // Unload all zones @@ -12,7 +46,7 @@ void FastFileContext::Destroy() result::Expected FastFileContext::LoadFastFile(const std::string& path) { - auto zone = ZoneLoading::LoadZone(path); + auto zone = ZoneLoading::LoadZone(path, std::make_unique(fs::path(path).filename().replace_extension().string())); if (!zone) return result::Unexpected(std::move(zone.error())); diff --git a/src/ModMan/Web/Binds/UnlinkingBinds.cpp b/src/ModMan/Web/Binds/UnlinkingBinds.cpp index bc281dcf..82d9d9b2 100644 --- a/src/ModMan/Web/Binds/UnlinkingBinds.cpp +++ b/src/ModMan/Web/Binds/UnlinkingBinds.cpp @@ -14,22 +14,41 @@ namespace fs = std::filesystem; namespace { - class ZoneLoadedDto + class ZoneUnlinkProgressDto { public: std::string zoneName; - std::string filePath; + double percentage; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadedDto, zoneName, filePath); + NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnlinkProgressDto, zoneName, percentage); - class ZoneUnloadedDto + constexpr double MIN_PROGRESS_TO_REPORT = 0.005; + + class UnlinkingEventProgressReporter : public ProgressCallback { public: - std::string zoneName; - }; + explicit UnlinkingEventProgressReporter(std::string zoneName) + : m_zone_name(std::move(zoneName)), + m_last_progress(0) + { + } - NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnloadedDto, zoneName); + void OnProgress(const size_t current, const size_t total) override + { + const double percentage = static_cast(current) / static_cast(total); + + if (percentage - m_last_progress >= MIN_PROGRESS_TO_REPORT) + { + m_last_progress = percentage; + ui::NotifyZoneUnlinkProgress(m_zone_name, percentage); + } + } + + private: + std::string m_zone_name; + double m_last_progress; + }; result::Expected UnlinkZoneInDbThread(const std::string& zoneName) { @@ -52,7 +71,8 @@ namespace OutputPathFilesystem outputFolderOutputPath(outputFolderPath); SearchPaths searchPaths; - AssetDumpingContext dumpingContext(zone, outputFolderPathStr, outputFolderOutputPath, searchPaths); + AssetDumpingContext dumpingContext( + zone, outputFolderPathStr, outputFolderOutputPath, searchPaths, std::make_unique(zoneName)); objWriter->DumpZone(dumpingContext); return NoResult(); @@ -81,6 +101,15 @@ namespace namespace ui { + void NotifyZoneUnlinkProgress(std::string zoneName, const double percentage) + { + const ZoneUnlinkProgressDto dto{ + .zoneName = std::move(zoneName), + .percentage = percentage, + }; + Notify(*ModManContext::Get().m_main_webview, "zoneUnlinkProgress", dto); + } + void RegisterUnlinkingBinds(webview::webview& wv) { BindAsync(wv, diff --git a/src/ModMan/Web/Binds/UnlinkingBinds.h b/src/ModMan/Web/Binds/UnlinkingBinds.h index 4169a780..6d2ac0ed 100644 --- a/src/ModMan/Web/Binds/UnlinkingBinds.h +++ b/src/ModMan/Web/Binds/UnlinkingBinds.h @@ -4,5 +4,7 @@ namespace ui { + void NotifyZoneUnlinkProgress(std::string zoneName, double percentage); + void RegisterUnlinkingBinds(webview::webview& wv); } // namespace ui diff --git a/src/ModMan/Web/Binds/ZoneBinds.cpp b/src/ModMan/Web/Binds/ZoneBinds.cpp index 8882a7d0..fd538376 100644 --- a/src/ModMan/Web/Binds/ZoneBinds.cpp +++ b/src/ModMan/Web/Binds/ZoneBinds.cpp @@ -7,6 +7,15 @@ namespace { + class ZoneLoadProgressDto + { + public: + std::string zoneName; + double percentage; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadProgressDto, zoneName, percentage); + class ZoneLoadedDto { public: @@ -71,6 +80,15 @@ namespace namespace ui { + void NotifyZoneLoadProgress(std::string zoneName, const double percentage) + { + const ZoneLoadProgressDto dto{ + .zoneName = std::move(zoneName), + .percentage = percentage, + }; + Notify(*ModManContext::Get().m_main_webview, "zoneLoadProgress", dto); + } + void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath) { const ZoneLoadedDto dto{ diff --git a/src/ModMan/Web/Binds/ZoneBinds.h b/src/ModMan/Web/Binds/ZoneBinds.h index cf11f10d..142d5e5b 100644 --- a/src/ModMan/Web/Binds/ZoneBinds.h +++ b/src/ModMan/Web/Binds/ZoneBinds.h @@ -4,6 +4,7 @@ namespace ui { + void NotifyZoneLoadProgress(std::string zoneName, double percentage); void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath); void NotifyZoneUnloaded(std::string zoneName); diff --git a/src/ModManUi/src/App.vue b/src/ModManUi/src/App.vue index 8c4a4dc1..73f92c86 100644 --- a/src/ModManUi/src/App.vue +++ b/src/ModManUi/src/App.vue @@ -1,14 +1,16 @@ - diff --git a/src/ModManUi/src/main.scss b/src/ModManUi/src/main.scss index 37c9c0b0..bfd40850 100644 --- a/src/ModManUi/src/main.scss +++ b/src/ModManUi/src/main.scss @@ -14,13 +14,24 @@ -webkit-text-size-adjust: 100%; } +* { + box-sizing: border-box; +} + +body { + margin: 0; +} + .container { margin: 0; padding-top: 10vh; display: flex; + position: relative; flex-direction: column; - justify-content: center; + justify-content: start; text-align: center; + + height: 100vh; } .logo { diff --git a/src/ModManUi/src/native/UnlinkingBinds.ts b/src/ModManUi/src/native/UnlinkingBinds.ts index 8fe73c71..68559d7a 100644 --- a/src/ModManUi/src/native/UnlinkingBinds.ts +++ b/src/ModManUi/src/native/UnlinkingBinds.ts @@ -1,3 +1,12 @@ +export interface ZoneUnlinkProgressDto { + zoneName: string; + percentage: number; +} + export interface UnlinkingBinds { unlinkZone(zoneName: string): Promise; } + +export interface UnlinkingEventMap { + zoneUnlinkProgress: ZoneUnlinkProgressDto; +} diff --git a/src/ModManUi/src/native/ZoneBinds.ts b/src/ModManUi/src/native/ZoneBinds.ts index e0636061..d775479b 100644 --- a/src/ModManUi/src/native/ZoneBinds.ts +++ b/src/ModManUi/src/native/ZoneBinds.ts @@ -1,3 +1,8 @@ +export interface ZoneLoadProgressDto { + zoneName: string; + percentage: number; +} + export interface ZoneLoadedDto { zoneName: string; filePath: string; @@ -13,6 +18,7 @@ export interface ZoneBinds { } export interface ZoneEventMap { + zoneLoadProgress: ZoneLoadProgressDto; zoneLoaded: ZoneLoadedDto; zoneUnloaded: ZoneUnloadedDto; } diff --git a/src/ModManUi/src/native/index.ts b/src/ModManUi/src/native/index.ts index dc455af9..09a0683e 100644 --- a/src/ModManUi/src/native/index.ts +++ b/src/ModManUi/src/native/index.ts @@ -1,10 +1,10 @@ import type { DialogBinds } from "./DialogBinds"; -import type { UnlinkingBinds } from "./UnlinkingBinds"; +import type { UnlinkingBinds, UnlinkingEventMap } from "./UnlinkingBinds"; import type { ZoneBinds, ZoneEventMap } from "./ZoneBinds"; export type NativeMethods = DialogBinds & UnlinkingBinds & ZoneBinds; -type NativeEventMap = ZoneEventMap; +type NativeEventMap = UnlinkingEventMap & ZoneEventMap; type WebViewExtensions = { webviewBinds: NativeMethods; diff --git a/src/ObjLoading/Asset/IAssetCreator.h b/src/ObjLoading/Asset/IAssetCreator.h index 33153df6..42dfeed0 100644 --- a/src/ObjLoading/Asset/IAssetCreator.h +++ b/src/ObjLoading/Asset/IAssetCreator.h @@ -25,7 +25,8 @@ public: [[nodiscard]] virtual std::optional GetHandlingAssetType() const = 0; virtual AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) = 0; - virtual void FinalizeZone(AssetCreationContext& context) {}; + + virtual void FinalizeZone(AssetCreationContext& context) {} }; template class AssetCreator : public IAssetCreator diff --git a/src/ObjWriting/Dumping/AbstractAssetDumper.h b/src/ObjWriting/Dumping/AbstractAssetDumper.h index 53fa97dc..c0371bc4 100644 --- a/src/ObjWriting/Dumping/AbstractAssetDumper.h +++ b/src/ObjWriting/Dumping/AbstractAssetDumper.h @@ -1,28 +1,69 @@ #pragma once +#include "Game/IAsset.h" #include "IAssetDumper.h" +#include "Pool/AssetPool.h" -template class AbstractAssetDumper : public IAssetDumper +template class AbstractAssetDumper : public IAssetDumper { + static_assert(std::is_base_of_v); + +public: + using AssetType_t = AssetType; + + [[nodiscard]] size_t GetProgressTotalCount() const override + { + return m_pool.m_asset_lookup.size(); + } + + void Dump(AssetDumpingContext& context) override + { + for (const auto* assetInfo : m_pool) + { + if (assetInfo->m_name[0] == ',' || !ShouldDump(*assetInfo)) + { + context.IncrementProgress(); + continue; + } + + DumpAsset(context, *assetInfo); + context.IncrementProgress(); + } + } + protected: - virtual bool ShouldDump(XAssetInfo* asset) + explicit AbstractAssetDumper(const AssetPool& pool) + : m_pool(pool) + { + } + + virtual bool ShouldDump(const XAssetInfo& asset) { return true; } - virtual void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) = 0; + virtual void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) = 0; + + const AssetPool& m_pool; +}; + +template class AbstractSingleProgressAssetDumper : public IAssetDumper +{ + static_assert(std::is_base_of_v); public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override - { - for (auto assetInfo : *pool) - { - if (assetInfo->m_name[0] == ',' || !ShouldDump(assetInfo)) - { - continue; - } + using AssetType_t = AssetType; - DumpAsset(context, assetInfo); - } + [[nodiscard]] size_t GetProgressTotalCount() const override + { + return m_pool.m_asset_lookup.empty() ? 0uz : 1uz; } + +protected: + explicit AbstractSingleProgressAssetDumper(const AssetPool& pool) + : m_pool(pool) + { + } + + const AssetPool& m_pool; }; diff --git a/src/ObjWriting/Dumping/AssetDumpingContext.cpp b/src/ObjWriting/Dumping/AssetDumpingContext.cpp index ea3041e1..77e59fe0 100644 --- a/src/ObjWriting/Dumping/AssetDumpingContext.cpp +++ b/src/ObjWriting/Dumping/AssetDumpingContext.cpp @@ -1,18 +1,43 @@ #include "AssetDumpingContext.h" #include -#include -#include -AssetDumpingContext::AssetDumpingContext(const Zone& zone, const std::string& basePath, IOutputPath& outputPath, ISearchPath& objSearchPath) +AssetDumpingContext::AssetDumpingContext(const Zone& zone, + const std::string& basePath, + IOutputPath& outputPath, + ISearchPath& objSearchPath, + std::optional> progressCallback) : m_zone(zone), m_base_path(basePath), m_output_path(outputPath), - m_obj_search_path(objSearchPath) + m_obj_search_path(objSearchPath), + m_current_progress(0uz), + m_total_progress(0uz) { + if (progressCallback) + m_progress_callback = *std::move(progressCallback); } std::unique_ptr AssetDumpingContext::OpenAssetFile(const std::string& fileName) const { return m_output_path.Open(fileName); } + +void AssetDumpingContext::IncrementProgress() +{ + if (m_progress_callback) + { + m_current_progress++; + m_progress_callback->OnProgress(m_current_progress, m_total_progress); + } +} + +void AssetDumpingContext::SetTotalProgress(const size_t value) +{ + m_total_progress = value; +} + +bool AssetDumpingContext::ShouldTrackProgress() const +{ + return static_cast(m_progress_callback); +} diff --git a/src/ObjWriting/Dumping/AssetDumpingContext.h b/src/ObjWriting/Dumping/AssetDumpingContext.h index bfc384de..4d6c86b3 100644 --- a/src/ObjWriting/Dumping/AssetDumpingContext.h +++ b/src/ObjWriting/Dumping/AssetDumpingContext.h @@ -4,6 +4,7 @@ #include "Obj/Gdt/GdtStream.h" #include "SearchPath/IOutputPath.h" #include "SearchPath/ISearchPath.h" +#include "Utils/ProgressCallback.h" #include "Zone/Zone.h" #include @@ -14,10 +15,18 @@ class AssetDumpingContext { public: - AssetDumpingContext(const Zone& zone, const std::string& basePath, IOutputPath& outputPath, ISearchPath& objSearchPath); + AssetDumpingContext(const Zone& zone, + const std::string& basePath, + IOutputPath& outputPath, + ISearchPath& objSearchPath, + std::optional> progressCallback); [[nodiscard]] std::unique_ptr OpenAssetFile(const std::string& fileName) const; + void IncrementProgress(); + void SetTotalProgress(size_t value); + [[nodiscard]] bool ShouldTrackProgress() const; + template T* GetZoneAssetDumperState() { static_assert(std::is_base_of_v, "T must inherit IZoneAssetDumperState"); @@ -42,4 +51,7 @@ public: private: std::unordered_map> m_zone_asset_dumper_states; + std::unique_ptr m_progress_callback; + size_t m_current_progress; + size_t m_total_progress; }; diff --git a/src/ObjWriting/Dumping/IAssetDumper.h b/src/ObjWriting/Dumping/IAssetDumper.h index f712f1dd..7c046de3 100644 --- a/src/ObjWriting/Dumping/IAssetDumper.h +++ b/src/ObjWriting/Dumping/IAssetDumper.h @@ -1,9 +1,8 @@ #pragma once #include "AssetDumpingContext.h" -#include "Pool/AssetPool.h" -template class IAssetDumper +class IAssetDumper { public: IAssetDumper() = default; @@ -13,5 +12,6 @@ public: IAssetDumper& operator=(const IAssetDumper& other) = default; IAssetDumper& operator=(IAssetDumper&& other) noexcept = default; - virtual void DumpPool(AssetDumpingContext& context, AssetPool* pool) = 0; + [[nodiscard]] virtual size_t GetProgressTotalCount() const = 0; + virtual void Dump(AssetDumpingContext& context) = 0; }; diff --git a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp index fbc44a99..06d0b422 100644 --- a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.cpp @@ -62,7 +62,8 @@ namespace namespace image { - DumperIW3::DumperIW3() + DumperIW3::DumperIW3(const AssetPool& pool) + : AbstractAssetDumper(pool) { switch (ObjWriting::Configuration.ImageOutputFormat) { @@ -79,19 +80,14 @@ namespace image } } - bool DumperIW3::ShouldDump(XAssetInfo* asset) + void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void DumperIW3::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto* image = asset->Asset(); + const auto* image = asset.Asset(); const auto texture = LoadImageData(context.m_obj_search_path, *image); if (!texture) return; - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name, m_writer->GetFileExtension())); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h index 7a1b181c..32fdf23e 100644 --- a/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h +++ b/src/ObjWriting/Game/IW3/Image/ImageDumperIW3.h @@ -8,14 +8,13 @@ namespace image { - class DumperIW3 final : public AbstractAssetDumper + class DumperIW3 final : public AbstractAssetDumper { public: - DumperIW3(); + explicit DumperIW3(const AssetPool& pool); protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: std::unique_ptr m_writer; diff --git a/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.cpp b/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.cpp index 777c419b..e1e1c9e5 100644 --- a/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.cpp @@ -11,9 +11,19 @@ using namespace IW3; namespace localize { - void DumperIW3::DumpPool(AssetDumpingContext& context, AssetPool* pool) + DumperIW3::DumperIW3(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) { - if (pool->m_asset_lookup.empty()) + } + + size_t DumperIW3::GetProgressTotalCount() const + { + return m_pool.m_asset_lookup.empty() ? 0uz : 1uz; + } + + void DumperIW3::Dump(AssetDumpingContext& context) + { + if (m_pool.m_asset_lookup.empty()) return; const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language); @@ -30,7 +40,7 @@ namespace localize stringFileDumper.SetNotes(""); - for (auto* localizeEntry : *pool) + for (const auto* localizeEntry : m_pool) { stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); } @@ -41,5 +51,7 @@ namespace localize { con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name); } + + context.IncrementProgress(); } } // namespace localize diff --git a/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.h b/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.h index 4cebd7c8..18971f83 100644 --- a/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.h +++ b/src/ObjWriting/Game/IW3/Localize/LocalizeDumperIW3.h @@ -2,12 +2,16 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW3/IW3.h" +#include "Pool/AssetPool.h" namespace localize { - class DumperIW3 final : public IAssetDumper + class DumperIW3 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit DumperIW3(const AssetPool& pool); + + [[nodiscard]] size_t GetProgressTotalCount() const override; + void Dump(AssetDumpingContext& context) override; }; } // namespace localize diff --git a/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.cpp b/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.cpp index 759623e4..e89014a4 100644 --- a/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.cpp @@ -4,15 +4,15 @@ using namespace IW3; namespace map_ents { - bool DumperIW3::ShouldDump(XAssetInfo* asset) + DumperIW3::DumperIW3(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW3::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* mapEnts = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name + ".ents"); + const auto* mapEnts = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name + ".ents"); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.h b/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.h index cd41ccc8..7e7786ea 100644 --- a/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.h +++ b/src/ObjWriting/Game/IW3/Maps/MapEntsDumperIW3.h @@ -5,10 +5,12 @@ namespace map_ents { - class DumperIW3 final : public AbstractAssetDumper + class DumperIW3 final : public AbstractAssetDumper { + public: + explicit DumperIW3(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace map_ents diff --git a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp index 418e3156..aba69545 100644 --- a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp +++ b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp @@ -15,43 +15,55 @@ using namespace IW3; bool ObjWriter::DumpZone(AssetDumpingContext& context) const { -#define DUMP_ASSET_POOL(dumperType, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER(dumperType, poolName) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(dumperType::AssetType_t::EnumEntry)) \ { \ - dumperType dumper; \ - dumper.DumpPool(context, assetPools->poolName.get()); \ + dumpers.emplace_back(std::make_unique(*assetPools->poolName)); \ } const auto* assetPools = dynamic_cast(context.m_zone.m_pools.get()); + std::vector> dumpers; - // DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset, ASSET_TYPE_PHYSPRESET) - // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) - DUMP_ASSET_POOL(xmodel::DumperIW3, m_xmodel, ASSET_TYPE_XMODEL) - DUMP_ASSET_POOL(material::JsonDumperIW3, m_material, ASSET_TYPE_MATERIAL) - // DUMP_ASSET_POOL(AssetDumperMaterialTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) - DUMP_ASSET_POOL(image::DumperIW3, m_image, ASSET_TYPE_IMAGE) - // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) - // DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(sound::LoadedSoundDumperIW3, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) - // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_PVS) - // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) - // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) - // DUMP_ASSET_POOL(AssetDumperGameWorldMp, m_game_world_mp, ASSET_TYPE_GAMEWORLD_MP) - DUMP_ASSET_POOL(map_ents::DumperIW3, m_map_ents, ASSET_TYPE_MAP_ENTS) - // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world, ASSET_TYPE_GFXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def, ASSET_TYPE_LIGHT_DEF) - // DUMP_ASSET_POOL(AssetDumperFont_s, m_font, ASSET_TYPE_FONT) - // DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST) - // DUMP_ASSET_POOL(AssetDumpermenuDef_t, m_menu_def, ASSET_TYPE_MENU) - DUMP_ASSET_POOL(localize::DumperIW3, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - // DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON) - // DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) - // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) - // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) - DUMP_ASSET_POOL(raw_file::DumperIW3, m_raw_file, ASSET_TYPE_RAWFILE) - DUMP_ASSET_POOL(string_table::DumperIW3, m_string_table, ASSET_TYPE_STRINGTABLE) + // REGISTER_DUMPER(AssetDumperPhysPreset, m_phys_preset) + // REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts) + REGISTER_DUMPER(xmodel::DumperIW3, m_xmodel) + REGISTER_DUMPER(material::JsonDumperIW3, m_material) + // REGISTER_DUMPER(AssetDumperMaterialTechniqueSet, m_technique_set) + REGISTER_DUMPER(image::DumperIW3, m_image) + // REGISTER_DUMPER(AssetDumpersnd_alias_list_t, m_sound) + // REGISTER_DUMPER(AssetDumperSndCurve, m_sound_curve) + REGISTER_DUMPER(sound::LoadedSoundDumperIW3, m_loaded_sound) + // REGISTER_DUMPER(AssetDumperClipMap, m_clip_map) + // REGISTER_DUMPER(AssetDumperComWorld, m_com_world) + // REGISTER_DUMPER(AssetDumperGameWorldSp, m_game_world_sp) + // REGISTER_DUMPER(AssetDumperGameWorldMp, m_game_world_mp) + REGISTER_DUMPER(map_ents::DumperIW3, m_map_ents) + // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) + // REGISTER_DUMPER(AssetDumperGfxLightDef, m_gfx_light_def) + // REGISTER_DUMPER(AssetDumperFont_s, m_font) + // REGISTER_DUMPER(AssetDumperMenuList, m_menu_list) + // REGISTER_DUMPER(AssetDumpermenuDef_t, m_menu_def) + REGISTER_DUMPER(localize::DumperIW3, m_localize) + // REGISTER_DUMPER(AssetDumperWeapon, m_weapon) + // REGISTER_DUMPER(AssetDumperSndDriverGlobals, m_snd_driver_globals) + // REGISTER_DUMPER(AssetDumperFxEffectDef, m_fx) + // REGISTER_DUMPER(AssetDumperFxImpactTable, m_fx_impact_table) + REGISTER_DUMPER(raw_file::DumperIW3, m_raw_file) + REGISTER_DUMPER(string_table::DumperIW3, m_string_table) + + if (context.ShouldTrackProgress()) + { + size_t totalProgress = 0uz; + for (const auto& dumper : dumpers) + totalProgress += dumper->GetProgressTotalCount(); + + context.SetTotalProgress(totalProgress); + } + + for (const auto& dumper : dumpers) + dumper->Dump(context); return true; -#undef DUMP_ASSET_POOL +#undef REGISTER_DUMPER } diff --git a/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.cpp b/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.cpp index 4b2eb11b..9ec12f1d 100644 --- a/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.cpp @@ -4,15 +4,15 @@ using namespace IW3; namespace raw_file { - bool DumperIW3::ShouldDump(XAssetInfo* asset) + DumperIW3::DumperIW3(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW3::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* rawFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* rawFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.h b/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.h index 250bea7c..eb6a80b2 100644 --- a/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.h +++ b/src/ObjWriting/Game/IW3/RawFile/RawFileDumperIW3.h @@ -5,10 +5,12 @@ namespace raw_file { - class DumperIW3 final : public AbstractAssetDumper + class DumperIW3 final : public AbstractAssetDumper { + public: + explicit DumperIW3(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace raw_file diff --git a/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp index 923d3d57..2fe85a25 100644 --- a/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp @@ -25,15 +25,15 @@ namespace namespace sound { - bool LoadedSoundDumperIW3::ShouldDump(XAssetInfo* asset) + LoadedSoundDumperIW3::LoadedSoundDumperIW3(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void LoadedSoundDumperIW3::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void LoadedSoundDumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* loadedSound = asset->Asset(); - const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + const auto* loadedSound = asset.Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h index 458af961..c639ff07 100644 --- a/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h +++ b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h @@ -5,10 +5,12 @@ namespace sound { - class LoadedSoundDumperIW3 final : public AbstractAssetDumper + class LoadedSoundDumperIW3 final : public AbstractAssetDumper { + public: + explicit LoadedSoundDumperIW3(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace sound diff --git a/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.cpp b/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.cpp index b7188a34..cf36f2fe 100644 --- a/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.cpp @@ -6,15 +6,15 @@ using namespace IW3; namespace string_table { - bool DumperIW3::ShouldDump(XAssetInfo* asset) + DumperIW3::DumperIW3(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW3::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* stringTable = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* stringTable = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.h b/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.h index 21ef05d5..78c87d6f 100644 --- a/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.h +++ b/src/ObjWriting/Game/IW3/StringTable/StringTableDumperIW3.h @@ -5,10 +5,12 @@ namespace string_table { - class DumperIW3 final : public AbstractAssetDumper + class DumperIW3 final : public AbstractAssetDumper { + public: + explicit DumperIW3(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace string_table diff --git a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp index 248c4098..d921581c 100644 --- a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.cpp @@ -59,7 +59,8 @@ namespace namespace image { - DumperIW4::DumperIW4() + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { switch (ObjWriting::Configuration.ImageOutputFormat) { @@ -76,19 +77,14 @@ namespace image } } - bool DumperIW4::ShouldDump(XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto* image = asset->Asset(); + const auto* image = asset.Asset(); const auto texture = LoadImageData(context.m_obj_search_path, *image); if (!texture) return; - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name, m_writer->GetFileExtension())); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h index 5d268ccc..e87e71a9 100644 --- a/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Image/ImageDumperIW4.h @@ -8,14 +8,13 @@ namespace image { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { public: - DumperIW4(); + explicit DumperIW4(const AssetPool& pool); protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: std::unique_ptr m_writer; diff --git a/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.cpp b/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.cpp index 80ed3625..41840a68 100644 --- a/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.cpp @@ -77,19 +77,19 @@ namespace namespace leaderboard { - bool JsonDumperIW4::ShouldDump(XAssetInfo* asset) + JsonDumperIW4::JsonDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset.m_name)); if (!assetFile) return; Dumper dumper(*assetFile); - dumper.Dump(*asset->Asset()); + dumper.Dump(*asset.Asset()); } } // namespace leaderboard diff --git a/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.h b/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.h index a56e5127..e5098b64 100644 --- a/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Leaderboard/LeaderboardJsonDumperIW4.h @@ -5,10 +5,12 @@ namespace leaderboard { - class JsonDumperIW4 final : public AbstractAssetDumper + class JsonDumperIW4 final : public AbstractAssetDumper { + public: + explicit JsonDumperIW4(const AssetPool& pool); + protected: - [[nodiscard]] bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace leaderboard diff --git a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp index 205df266..402ed74a 100644 --- a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp @@ -2,21 +2,19 @@ #include "LightDef/LightDefCommon.h" -#include - using namespace IW4; namespace light_def { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* lightDef = asset->Asset(); - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name)); + const auto* lightDef = asset.Asset(); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name)); if (!assetFile || lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) return; diff --git a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.h b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.h index 29531abb..9bc28e3a 100644 --- a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.h +++ b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.h @@ -5,10 +5,12 @@ namespace light_def { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace light_def diff --git a/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.cpp b/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.cpp index bff7b2ee..67003134 100644 --- a/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.cpp @@ -5,15 +5,19 @@ #include "Utils/Logging/Log.h" #include -#include using namespace IW4; namespace localize { - void DumperIW4::DumpPool(AssetDumpingContext& context, AssetPool* pool) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) { - if (pool->m_asset_lookup.empty()) + } + + void DumperIW4::Dump(AssetDumpingContext& context) + { + if (m_pool.m_asset_lookup.empty()) return; const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language); @@ -30,7 +34,7 @@ namespace localize stringFileDumper.SetNotes(""); - for (auto* localizeEntry : *pool) + for (const auto* localizeEntry : m_pool) { stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); } @@ -41,5 +45,7 @@ namespace localize { con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name); } + + context.IncrementProgress(); } } // namespace localize diff --git a/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.h b/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.h index fd88c200..781e75f0 100644 --- a/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Localize/LocalizeDumperIW4.h @@ -5,9 +5,11 @@ namespace localize { - class DumperIW4 final : public IAssetDumper + class DumperIW4 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit DumperIW4(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; }; } // namespace localize diff --git a/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.cpp b/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.cpp index 37b45249..11de5e0e 100644 --- a/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.cpp @@ -7,15 +7,15 @@ using namespace IW4; namespace addon_map_ents { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* addonMapEnts = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* addonMapEnts = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.h b/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.h index 4f1ef6c8..9e3439ea 100644 --- a/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Maps/AddonMapEntsDumperIW4.h @@ -5,10 +5,12 @@ namespace addon_map_ents { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace addon_map_ents diff --git a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp index f706ed0e..749c8d52 100644 --- a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.cpp @@ -1110,17 +1110,17 @@ namespace namespace material { - bool DecompilingGdtDumperIW4::ShouldDump(XAssetInfo* asset) + DecompilingGdtDumperIW4::DecompilingGdtDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DecompilingGdtDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DecompilingGdtDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { if (!context.m_gdt) return; - MaterialGdtDumper dumper(*asset->Asset()); + MaterialGdtDumper dumper(*asset.Asset()); context.m_gdt->WriteEntry(dumper.CreateGdtEntry()); } } // namespace material diff --git a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.h b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.h index e6b73e35..f66ad842 100644 --- a/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Material/MaterialDecompilingDumperIW4.h @@ -5,10 +5,12 @@ namespace material { - class DecompilingGdtDumperIW4 final : public AbstractAssetDumper + class DecompilingGdtDumperIW4 final : public AbstractAssetDumper { + public: + explicit DecompilingGdtDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace material diff --git a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp index d3828080..e25e983a 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp @@ -1,7 +1,6 @@ #include "MenuDumperIW4.h" #include "Game/IW4/GameAssetPoolIW4.h" -#include "Game/IW4/Menu/MenuDumperIW4.h" #include "MenuListDumperIW4.h" #include "MenuWriterIW4.h" #include "ObjWriting.h" @@ -13,12 +12,12 @@ using namespace IW4; namespace { - std::string GetPathForMenu(menu::MenuDumpingZoneState* zoneState, XAssetInfo* asset) + std::string GetPathForMenu(menu::MenuDumpingZoneState* zoneState, const XAssetInfo& asset) { - const auto menuDumpingState = zoneState->m_menu_dumping_state_map.find(asset->Asset()); + const auto menuDumpingState = zoneState->m_menu_dumping_state_map.find(asset.Asset()); if (menuDumpingState == zoneState->m_menu_dumping_state_map.end()) - return "ui_mp/" + std::string(asset->Asset()->window.name) + ".menu"; + return "ui_mp/" + std::string(asset.Asset()->window.name) + ".menu"; return menuDumpingState->second.m_path; } @@ -26,20 +25,20 @@ namespace namespace menu { - bool MenuDumperIW4::ShouldDump(XAssetInfo* asset) + MenuDumperIW4::MenuDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void MenuDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void MenuDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* menu = asset->Asset(); + const auto* menu = asset.Asset(); auto* zoneState = context.GetZoneAssetDumperState(); if (!ObjWriting::ShouldHandleAssetType(ASSET_TYPE_MENULIST)) { // Make sure menu paths based on menu lists are created - const auto* gameAssetPool = dynamic_cast(asset->m_zone->m_pools.get()); + const auto* gameAssetPool = dynamic_cast(asset.m_zone->m_pools.get()); for (auto* menuListAsset : *gameAssetPool->m_menu_list) CreateDumpingStateForMenuListIW4(zoneState, menuListAsset->Asset()); } diff --git a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h index 43317e26..91e452ab 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "Menu/MenuDumpingZoneState.h" namespace menu { - class MenuDumperIW4 final : public AbstractAssetDumper + class MenuDumperIW4 final : public AbstractAssetDumper { + public: + explicit MenuDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace menu diff --git a/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.cpp b/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.cpp index 7946dfe9..217a3c3f 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.cpp @@ -147,15 +147,15 @@ namespace menu } } - bool MenuListDumperIW4::ShouldDump(XAssetInfo* asset) + MenuListDumperIW4::MenuListDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void MenuListDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void MenuListDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* menuList = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* menuList = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; @@ -174,13 +174,13 @@ namespace menu menuWriter->End(); } - void MenuListDumperIW4::DumpPool(AssetDumpingContext& context, AssetPool* pool) + void MenuListDumperIW4::Dump(AssetDumpingContext& context) { auto* zoneState = context.GetZoneAssetDumperState(); - for (auto* asset : *pool) + for (const auto* asset : m_pool) CreateDumpingStateForMenuListIW4(zoneState, asset->Asset()); - AbstractAssetDumper::DumpPool(context, pool); + AbstractAssetDumper::Dump(context); } } // namespace menu diff --git a/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.h b/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.h index b9329966..93610331 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Menu/MenuListDumperIW4.h @@ -2,20 +2,20 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "Game/IW4/Menu/MenuDumperIW4.h" #include "Menu/MenuDumpingZoneState.h" namespace menu { void CreateDumpingStateForMenuListIW4(MenuDumpingZoneState* zoneState, const IW4::MenuList* menuList); - class MenuListDumperIW4 final : public AbstractAssetDumper + class MenuListDumperIW4 final : public AbstractAssetDumper { - protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; - public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit MenuListDumperIW4(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; + + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace menu diff --git a/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp b/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp index b749a985..73d5b2d1 100644 --- a/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp +++ b/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp @@ -30,55 +30,67 @@ using namespace IW4; bool ObjWriter::DumpZone(AssetDumpingContext& context) const { -#define DUMP_ASSET_POOL(dumperType, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER(dumperType, poolName) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(dumperType::AssetType_t::EnumEntry)) \ { \ - dumperType dumper; \ - dumper.DumpPool(context, assetPools->poolName.get()); \ + dumpers.emplace_back(std::make_unique(*assetPools->poolName)); \ } const auto* assetPools = dynamic_cast(context.m_zone.m_pools.get()); + std::vector> dumpers; - DUMP_ASSET_POOL(phys_preset::InfoStringDumperIW4, m_phys_preset, ASSET_TYPE_PHYSPRESET) - DUMP_ASSET_POOL(phys_collmap::DumperIW4, m_phys_collmap, ASSET_TYPE_PHYSCOLLMAP) - // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) - DUMP_ASSET_POOL(xmodel::DumperIW4, m_xmodel, ASSET_TYPE_XMODEL) - DUMP_ASSET_POOL(material::JsonDumperIW4, m_material, ASSET_TYPE_MATERIAL) + REGISTER_DUMPER(phys_preset::InfoStringDumperIW4, m_phys_preset) + REGISTER_DUMPER(phys_collmap::DumperIW4, m_phys_collmap) + // REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts) + REGISTER_DUMPER(xmodel::DumperIW4, m_xmodel) + REGISTER_DUMPER(material::JsonDumperIW4, m_material) #ifdef EXPERIMENTAL_MATERIAL_COMPILATION - DUMP_ASSET_POOL(material::DecompilingGdtDumperIW4, m_material, ASSET_TYPE_MATERIAL) + DUMP_ASSET_POOL(material::DecompilingGdtDumperIW4, m_material) #endif - DUMP_ASSET_POOL(shader::PixelShaderDumperIW4, m_material_pixel_shader, ASSET_TYPE_PIXELSHADER) - DUMP_ASSET_POOL(shader::VertexShaderDumperIW4, m_material_vertex_shader, ASSET_TYPE_VERTEXSHADER) - DUMP_ASSET_POOL(techset::DumperIW4, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) - DUMP_ASSET_POOL(image::DumperIW4, m_image, ASSET_TYPE_IMAGE) - // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) - DUMP_ASSET_POOL(sound_curve::DumperIW4, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(sound::LoadedSoundDumperIW4, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) - // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_MP) - // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) - // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) - // DUMP_ASSET_POOL(AssetDumperGameWorldMp, m_game_world_mp, ASSET_TYPE_GAMEWORLD_MP) - // DUMP_ASSET_POOL(AssetDumperMapEnts, m_map_ents, ASSET_TYPE_MAP_ENTS) - // DUMP_ASSET_POOL(AssetDumperFxWorld, m_fx_world, ASSET_TYPE_FXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world, ASSET_TYPE_GFXWORLD) - DUMP_ASSET_POOL(light_def::DumperIW4, m_gfx_light_def, ASSET_TYPE_LIGHT_DEF) - // DUMP_ASSET_POOL(AssetDumperFont_s, m_font, ASSET_TYPE_FONT) - DUMP_ASSET_POOL(menu::MenuListDumperIW4, m_menu_list, ASSET_TYPE_MENULIST) - DUMP_ASSET_POOL(menu::MenuDumperIW4, m_menu_def, ASSET_TYPE_MENU) - DUMP_ASSET_POOL(localize::DumperIW4, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - DUMP_ASSET_POOL(weapon::DumperIW4, m_weapon, ASSET_TYPE_WEAPON) - // DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) - // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) - // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) - DUMP_ASSET_POOL(raw_file::DumperIW4, m_raw_file, ASSET_TYPE_RAWFILE) - DUMP_ASSET_POOL(string_table::DumperIW4, m_string_table, ASSET_TYPE_STRINGTABLE) - DUMP_ASSET_POOL(leaderboard::JsonDumperIW4, m_leaderboard, ASSET_TYPE_LEADERBOARD) - DUMP_ASSET_POOL(structured_data_def::DumperIW4, m_structed_data_def_set, ASSET_TYPE_STRUCTURED_DATA_DEF) - DUMP_ASSET_POOL(tracer::DumperIW4, m_tracer, ASSET_TYPE_TRACER) - DUMP_ASSET_POOL(vehicle::DumperIW4, m_vehicle, ASSET_TYPE_VEHICLE) - DUMP_ASSET_POOL(addon_map_ents::DumperIW4, m_addon_map_ents, ASSET_TYPE_ADDON_MAP_ENTS) + REGISTER_DUMPER(shader::PixelShaderDumperIW4, m_material_pixel_shader) + REGISTER_DUMPER(shader::VertexShaderDumperIW4, m_material_vertex_shader) + REGISTER_DUMPER(techset::DumperIW4, m_technique_set) + REGISTER_DUMPER(image::DumperIW4, m_image) + // REGISTER_DUMPER(AssetDumpersnd_alias_list_t, m_sound) + REGISTER_DUMPER(sound_curve::DumperIW4, m_sound_curve) + REGISTER_DUMPER(sound::LoadedSoundDumperIW4, m_loaded_sound) + // REGISTER_DUMPER(AssetDumperClipMap, m_clip_map) + // REGISTER_DUMPER(AssetDumperComWorld, m_com_world) + // REGISTER_DUMPER(AssetDumperGameWorldSp, m_game_world_sp) + // REGISTER_DUMPER(AssetDumperGameWorldMp, m_game_world_mp) + // REGISTER_DUMPER(AssetDumperMapEnts, m_map_ents) + // REGISTER_DUMPER(AssetDumperFxWorld, m_fx_world) + // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) + REGISTER_DUMPER(light_def::DumperIW4, m_gfx_light_def) + // REGISTER_DUMPER(AssetDumperFont_s, m_font) + REGISTER_DUMPER(menu::MenuListDumperIW4, m_menu_list) + REGISTER_DUMPER(menu::MenuDumperIW4, m_menu_def) + REGISTER_DUMPER(localize::DumperIW4, m_localize) + REGISTER_DUMPER(weapon::DumperIW4, m_weapon) + // REGISTER_DUMPER(AssetDumperSndDriverGlobals, m_snd_driver_globals) + // REGISTER_DUMPER(AssetDumperFxEffectDef, m_fx) + // REGISTER_DUMPER(AssetDumperFxImpactTable, m_fx_impact_table) + REGISTER_DUMPER(raw_file::DumperIW4, m_raw_file) + REGISTER_DUMPER(string_table::DumperIW4, m_string_table) + REGISTER_DUMPER(leaderboard::JsonDumperIW4, m_leaderboard) + REGISTER_DUMPER(structured_data_def::DumperIW4, m_structed_data_def_set) + REGISTER_DUMPER(tracer::DumperIW4, m_tracer) + REGISTER_DUMPER(vehicle::DumperIW4, m_vehicle) + REGISTER_DUMPER(addon_map_ents::DumperIW4, m_addon_map_ents) + + if (context.ShouldTrackProgress()) + { + size_t totalProgress = 0uz; + for (const auto& dumper : dumpers) + totalProgress += dumper->GetProgressTotalCount(); + + context.SetTotalProgress(totalProgress); + } + + for (const auto& dumper : dumpers) + dumper->Dump(context); return true; -#undef DUMP_ASSET_POOL +#undef REGISTER_DUMPER } diff --git a/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.cpp b/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.cpp index 523c64c8..2cf39ef3 100644 --- a/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.cpp @@ -10,15 +10,15 @@ using namespace IW4; namespace phys_collmap { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* physCollmap = asset->Asset(); - const auto assetFile = context.OpenAssetFile(phys_collmap::GetFileNameForAssetName(asset->m_name)); + const auto* physCollmap = asset.Asset(); + const auto assetFile = context.OpenAssetFile(phys_collmap::GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.h b/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.h index 4dbf68d6..c3cb8061 100644 --- a/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.h +++ b/src/ObjWriting/Game/IW4/PhysCollmap/PhysCollmapDumperIW4.h @@ -5,10 +5,12 @@ namespace phys_collmap { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace phys_collmap diff --git a/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.cpp b/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.cpp index 41ac1f64..c60e38a8 100644 --- a/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.cpp @@ -57,21 +57,21 @@ namespace physPresetInfo->perSurfaceSndAlias = physPreset->perSurfaceSndAlias ? 1 : 0; } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { auto* physPresetInfo = new PhysPresetInfo; - CopyToPhysPresetInfo(asset->Asset(), physPresetInfo); + CopyToPhysPresetInfo(asset.Asset(), physPresetInfo); InfoStringFromPhysPresetConverter converter(physPresetInfo, phys_preset_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -80,24 +80,24 @@ namespace namespace phys_preset { - bool InfoStringDumperIW4::ShouldDump(XAssetInfo* asset) + InfoStringDumperIW4::InfoStringDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void InfoStringDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void InfoStringDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_PHYS_PRESET); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_PHYS_PRESET); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.h b/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.h index 4651c1e0..17457ce9 100644 --- a/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.h +++ b/src/ObjWriting/Game/IW4/PhysPreset/PhysPresetInfoStringDumperIW4.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "InfoString/InfoString.h" namespace phys_preset { - class InfoStringDumperIW4 final : public AbstractAssetDumper + class InfoStringDumperIW4 final : public AbstractAssetDumper { + public: + explicit InfoStringDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace phys_preset diff --git a/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.cpp b/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.cpp index a1e9a045..39109672 100644 --- a/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.cpp @@ -10,15 +10,15 @@ using namespace IW4; namespace raw_file { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* rawFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* rawFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.h b/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.h index 9b8966ea..5a3b7559 100644 --- a/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.h +++ b/src/ObjWriting/Game/IW4/RawFile/RawFileDumperIW4.h @@ -5,10 +5,12 @@ namespace raw_file { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace raw_file diff --git a/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.cpp b/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.cpp index 318c9a68..9ef1571b 100644 --- a/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.cpp @@ -6,15 +6,15 @@ using namespace IW4; namespace shader { - bool PixelShaderDumperIW4::ShouldDump(XAssetInfo* asset) + PixelShaderDumperIW4::PixelShaderDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void PixelShaderDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void PixelShaderDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* pixelShader = asset->Asset(); - const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForPixelShaderAssetName(asset->m_name)); + const auto* pixelShader = asset.Asset(); + const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForPixelShaderAssetName(asset.m_name)); if (!shaderFile) return; diff --git a/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.h b/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.h index 01404d0a..0c1e5339 100644 --- a/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Shader/PixelShaderDumperIW4.h @@ -5,10 +5,12 @@ namespace shader { - class PixelShaderDumperIW4 final : public AbstractAssetDumper + class PixelShaderDumperIW4 final : public AbstractAssetDumper { + public: + explicit PixelShaderDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace shader diff --git a/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.cpp b/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.cpp index c3954562..d5a66fcb 100644 --- a/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.cpp @@ -6,15 +6,15 @@ using namespace IW4; namespace shader { - bool VertexShaderDumperIW4::ShouldDump(XAssetInfo* asset) + VertexShaderDumperIW4::VertexShaderDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void VertexShaderDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void VertexShaderDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* vertexShader = asset->Asset(); - const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForVertexShaderAssetName(asset->m_name)); + const auto* vertexShader = asset.Asset(); + const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForVertexShaderAssetName(asset.m_name)); if (!shaderFile) return; diff --git a/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.h b/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.h index 1b722461..5702e94d 100644 --- a/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Shader/VertexShaderDumperIW4.h @@ -5,10 +5,12 @@ namespace shader { - class VertexShaderDumperIW4 final : public AbstractAssetDumper + class VertexShaderDumperIW4 final : public AbstractAssetDumper { + public: + explicit VertexShaderDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace shader diff --git a/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp index 20e34703..e0d2ed2d 100644 --- a/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp @@ -25,15 +25,15 @@ namespace namespace sound { - bool LoadedSoundDumperIW4::ShouldDump(XAssetInfo* asset) + LoadedSoundDumperIW4::LoadedSoundDumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void LoadedSoundDumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void LoadedSoundDumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* loadedSound = asset->Asset(); - const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + const auto* loadedSound = asset.Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h index 7256bc88..fa28defe 100644 --- a/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h @@ -5,10 +5,12 @@ namespace sound { - class LoadedSoundDumperIW4 final : public AbstractAssetDumper + class LoadedSoundDumperIW4 final : public AbstractAssetDumper { + public: + explicit LoadedSoundDumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace sound diff --git a/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp index b7e00629..8a6ab9a2 100644 --- a/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp @@ -3,20 +3,18 @@ #include "Sound/SndCurveDumper.h" #include "Sound/SoundCurveCommon.h" -#include - using namespace IW4; namespace sound_curve { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* sndCurve = asset->Asset(); + const auto* sndCurve = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(sndCurve->filename)); diff --git a/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h index 241b7a79..0c4358d5 100644 --- a/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h @@ -5,10 +5,12 @@ namespace sound_curve { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace sound_curve diff --git a/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.cpp b/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.cpp index 784164e2..27a92ecb 100644 --- a/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.cpp @@ -6,15 +6,15 @@ using namespace IW4; namespace string_table { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* stringTable = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* stringTable = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.h b/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.h index 93f1af2b..8abb9057 100644 --- a/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.h +++ b/src/ObjWriting/Game/IW4/StringTable/StringTableDumperIW4.h @@ -5,10 +5,12 @@ namespace string_table { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace string_table diff --git a/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.cpp b/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.cpp index 2e5cf317..10665f83 100644 --- a/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.cpp @@ -1,9 +1,11 @@ #include "StructuredDataDefDumperIW4.h" +#include "StructuredDataDef/CommonStructuredDataDef.h" #include "StructuredDataDef/StructuredDataDefDumper.h" #include #include +#include #include using namespace IW4; @@ -185,15 +187,15 @@ namespace namespace structured_data_def { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* set = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* set = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile || set->defs == nullptr) return; diff --git a/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.h b/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.h index e03d8c61..47b14f89 100644 --- a/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.h +++ b/src/ObjWriting/Game/IW4/StructuredDataDef/StructuredDataDefDumperIW4.h @@ -2,16 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "StructuredDataDef/CommonStructuredDataDef.h" - -#include namespace structured_data_def { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace structured_data_def diff --git a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp index f8eb6e90..8714cd74 100644 --- a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.cpp @@ -536,14 +536,14 @@ namespace IW4 namespace techset { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* techset = asset->Asset(); + const auto* techset = asset.Asset(); const auto techsetFile = context.OpenAssetFile(GetFileNameForTechsetName(techset->name)); diff --git a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.h b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.h index 8115f527..ea8f076f 100644 --- a/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Techset/TechsetDumperIW4.h @@ -5,10 +5,12 @@ namespace techset { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace techset diff --git a/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.cpp b/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.cpp index 2e3635f8..63076021 100644 --- a/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.cpp @@ -32,18 +32,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromTracerConverter converter(asset->Asset(), + InfoStringFromTracerConverter converter(asset.Asset(), tracer_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -52,24 +52,24 @@ namespace namespace tracer { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_TRACER); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_TRACER); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_TRACER, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.h b/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.h index d13a9f60..708d7c76 100644 --- a/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Tracer/TracerDumperIW4.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "InfoString/InfoString.h" namespace tracer { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace tracer diff --git a/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.cpp b/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.cpp index 9110b559..5830391f 100644 --- a/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.cpp @@ -73,18 +73,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromVehicleConverter converter(asset->Asset(), + InfoStringFromVehicleConverter converter(asset.Asset(), vehicle_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -93,24 +93,24 @@ namespace namespace vehicle { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_VEHICLE); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_VEHICLE); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_VEHICLE, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.h b/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.h index 5afae348..1af2dcaa 100644 --- a/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Vehicle/VehicleDumperIW4.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "InfoString/InfoString.h" namespace vehicle { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace vehicle diff --git a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp index 1ebabfe7..6ca11889 100644 --- a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp @@ -353,31 +353,31 @@ namespace } } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { const auto fullDef = std::make_unique(); memset(fullDef.get(), 0, sizeof(WeaponFullDef)); - CopyToFullDef(asset->Asset(), fullDef.get()); + CopyToFullDef(asset.Asset(), fullDef.get()); InfoStringFromWeaponConverter converter(fullDef.get(), weapon_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); } - void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); - const auto weapon = asset->Asset(); + const auto weapon = asset.Asset(); const auto* weapDef = weapon->weapDef; if (!weapDef) @@ -405,24 +405,24 @@ namespace namespace weapon { - bool DumperIW4::ShouldDump(XAssetInfo* asset) + DumperIW4::DumperIW4(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW4::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW4::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_WEAPON); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.h b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.h index d6935e77..a97ff280 100644 --- a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -#include "InfoString/InfoString.h" namespace weapon { - class DumperIW4 final : public AbstractAssetDumper + class DumperIW4 final : public AbstractAssetDumper { + public: + explicit DumperIW4(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace weapon diff --git a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp index 038f94ea..6a219864 100644 --- a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.cpp @@ -60,7 +60,8 @@ namespace namespace image { - DumperIW5::DumperIW5() + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { switch (ObjWriting::Configuration.ImageOutputFormat) { @@ -77,19 +78,14 @@ namespace image } } - bool DumperIW5::ShouldDump(XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto* image = asset->Asset(); + const auto* image = asset.Asset(); const auto texture = LoadImageData(context.m_obj_search_path, *image); if (!texture) return; - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name, m_writer->GetFileExtension())); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h index 414465aa..7c4f8200 100644 --- a/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Image/ImageDumperIW5.h @@ -8,14 +8,13 @@ namespace image { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { public: - DumperIW5(); + explicit DumperIW5(const AssetPool& pool); protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: std::unique_ptr m_writer; diff --git a/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.cpp b/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.cpp index f79ea849..08586629 100644 --- a/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.cpp @@ -94,19 +94,19 @@ namespace namespace leaderboard { - bool JsonDumperIW5::ShouldDump(XAssetInfo* asset) + JsonDumperIW5::JsonDumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset.m_name)); if (!assetFile) return; Dumper dumper(*assetFile); - dumper.Dump(*asset->Asset()); + dumper.Dump(*asset.Asset()); } } // namespace leaderboard diff --git a/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.h b/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.h index 3e6ff7f8..04d07ecf 100644 --- a/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Leaderboard/LeaderboardJsonDumperIW5.h @@ -5,10 +5,12 @@ namespace leaderboard { - class JsonDumperIW5 final : public AbstractAssetDumper + class JsonDumperIW5 final : public AbstractAssetDumper { + public: + explicit JsonDumperIW5(const AssetPool& pool); + protected: - [[nodiscard]] bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace leaderboard diff --git a/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.cpp b/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.cpp index a9f979ee..55894aed 100644 --- a/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.cpp @@ -11,9 +11,14 @@ using namespace IW5; namespace localize { - void DumperIW5::DumpPool(AssetDumpingContext& context, AssetPool* pool) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) { - if (pool->m_asset_lookup.empty()) + } + + void DumperIW5::Dump(AssetDumpingContext& context) + { + if (m_pool.m_asset_lookup.empty()) return; const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language); @@ -30,7 +35,7 @@ namespace localize stringFileDumper.SetNotes(""); - for (auto* localizeEntry : *pool) + for (const auto* localizeEntry : m_pool) { stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); } @@ -41,5 +46,7 @@ namespace localize { con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name); } + + context.IncrementProgress(); } } // namespace localize diff --git a/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.h b/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.h index 26373073..427ca8dd 100644 --- a/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Localize/LocalizeDumperIW5.h @@ -5,9 +5,11 @@ namespace localize { - class DumperIW5 final : public IAssetDumper + class DumperIW5 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit DumperIW5(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; }; } // namespace localize diff --git a/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.cpp b/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.cpp index 3facfa1c..6c2ba3a3 100644 --- a/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.cpp @@ -7,15 +7,15 @@ using namespace IW5; namespace addon_map_ents { - bool DumperIW5::ShouldDump(XAssetInfo* asset) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* addonMapEnts = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* addonMapEnts = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.h b/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.h index 6c251086..d7a8d226 100644 --- a/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Maps/AddonMapEntsDumperIW5.h @@ -5,10 +5,12 @@ namespace addon_map_ents { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { + public: + explicit DumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace addon_map_ents diff --git a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp index 2abe44a0..986ee1cc 100644 --- a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.cpp @@ -15,10 +15,10 @@ using namespace IW5; namespace { - const MenuList* GetParentMenuList(XAssetInfo* asset) + const MenuList* GetParentMenuList(const XAssetInfo& asset) { - const auto* menu = asset->Asset(); - const auto* gameAssetPool = dynamic_cast(asset->m_zone->m_pools.get()); + const auto* menu = asset.Asset(); + const auto* gameAssetPool = dynamic_cast(asset.m_zone->m_pools.get()); for (const auto* menuList : *gameAssetPool->m_menu_list) { const auto* menuListAsset = menuList->Asset(); @@ -33,32 +33,32 @@ namespace return nullptr; } - std::string GetPathForMenu(XAssetInfo* asset) + std::string GetPathForMenu(const XAssetInfo& asset) { const auto* list = GetParentMenuList(asset); if (!list) - return std::format("ui_mp/{}.menu", asset->Asset()->window.name); + return std::format("ui_mp/{}.menu", asset.Asset()->window.name); const fs::path p(list->name); std::string parentPath; if (p.has_parent_path()) parentPath = p.parent_path().string() + "/"; - return std::format("{}{}.menu", parentPath, asset->Asset()->window.name); + return std::format("{}{}.menu", parentPath, asset.Asset()->window.name); } } // namespace namespace menu { - bool MenuDumperIW5::ShouldDump(XAssetInfo* asset) + MenuDumperIW5::MenuDumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void MenuDumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void MenuDumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* menu = asset->Asset(); + const auto* menu = asset.Asset(); const auto menuFilePath = GetPathForMenu(asset); if (ObjWriting::ShouldHandleAssetType(ASSET_TYPE_MENULIST)) diff --git a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.h b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.h index 03577fcb..e996e47d 100644 --- a/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Menu/MenuDumperIW5.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW5/IW5.h" -#include "Game/IW5/Menu/MenuDumperIW5.h" namespace menu { - class MenuDumperIW5 final : public AbstractAssetDumper + class MenuDumperIW5 final : public AbstractAssetDumper { + public: + explicit MenuDumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace menu diff --git a/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.cpp b/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.cpp index 9a1d674c..55e61eb1 100644 --- a/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.cpp @@ -106,15 +106,15 @@ namespace namespace menu { - bool MenuListDumperIW5::ShouldDump(XAssetInfo* asset) + MenuListDumperIW5::MenuListDumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void MenuListDumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void MenuListDumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* menuList = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* menuList = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.h b/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.h index d4da415f..7b87deda 100644 --- a/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Menu/MenuListDumperIW5.h @@ -5,10 +5,12 @@ namespace menu { - class MenuListDumperIW5 final : public AbstractAssetDumper + class MenuListDumperIW5 final : public AbstractAssetDumper { + public: + explicit MenuListDumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace menu diff --git a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp index 4cbd3f31..e7ca7a8f 100644 --- a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp +++ b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp @@ -21,56 +21,69 @@ using namespace IW5; bool ObjWriter::DumpZone(AssetDumpingContext& context) const { -#define DUMP_ASSET_POOL(dumperType, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER(dumperType, poolName) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(dumperType::AssetType_t::EnumEntry)) \ { \ - dumperType dumper; \ - dumper.DumpPool(context, assetPools->poolName.get()); \ + dumpers.emplace_back(std::make_unique(*assetPools->poolName)); \ } const auto* assetPools = dynamic_cast(context.m_zone.m_pools.get()); - // DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset, ASSET_TYPE_PHYSPRESET) - // DUMP_ASSET_POOL(AssetDumperPhysCollmap, m_phys_collmap, ASSET_TYPE_PHYSCOLLMAP) - // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) - // DUMP_ASSET_POOL(AssetDumperXModelSurfs, m_xmodel_surfs, ASSET_TYPE_XMODEL_SURFS) - DUMP_ASSET_POOL(xmodel::DumperIW5, m_xmodel, ASSET_TYPE_XMODEL) - DUMP_ASSET_POOL(material::JsonDumperIW5, m_material, ASSET_TYPE_MATERIAL) - // DUMP_ASSET_POOL(AssetDumperMaterialPixelShader, m_material_pixel_shader, ASSET_TYPE_PIXELSHADER) - // DUMP_ASSET_POOL(AssetDumperMaterialVertexShader, m_material_vertex_shader, ASSET_TYPE_VERTEXSHADER) - // DUMP_ASSET_POOL(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl, ASSET_TYPE_VERTEXDECL) - // DUMP_ASSET_POOL(AssetDumperMaterialTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) - DUMP_ASSET_POOL(image::DumperIW5, m_image, ASSET_TYPE_IMAGE) - // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) - // DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(sound::LoadedSoundDumperIW5, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) - // DUMP_ASSET_POOL(AssetDumperclipMap_t, m_clip_map, ASSET_TYPE_CLIPMAP) - // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) - // DUMP_ASSET_POOL(AssetDumperGlassWorld, m_glass_world, ASSET_TYPE_GLASSWORLD) - // DUMP_ASSET_POOL(AssetDumperPathData, m_path_data, ASSET_TYPE_PATHDATA) - // DUMP_ASSET_POOL(AssetDumperVehicleTrack, m_vehicle_track, ASSET_TYPE_VEHICLE_TRACK) - // DUMP_ASSET_POOL(AssetDumperMapEnts, m_map_ents, ASSET_TYPE_MAP_ENTS) - // DUMP_ASSET_POOL(AssetDumperFxWorld, m_fx_world, ASSET_TYPE_FXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world, ASSET_TYPE_GFXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def, ASSET_TYPE_LIGHT_DEF) - // DUMP_ASSET_POOL(AssetDumperFont_s, m_font, ASSET_TYPE_FONT) - DUMP_ASSET_POOL(menu::MenuListDumperIW5, m_menu_list, ASSET_TYPE_MENULIST) - DUMP_ASSET_POOL(menu::MenuDumperIW5, m_menu_def, ASSET_TYPE_MENU) - DUMP_ASSET_POOL(localize::DumperIW5, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - DUMP_ASSET_POOL(attachment::JsonDumperIW5, m_attachment, ASSET_TYPE_ATTACHMENT) - DUMP_ASSET_POOL(weapon::DumperIW5, m_weapon, ASSET_TYPE_WEAPON) - // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) - // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) - // DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX) - DUMP_ASSET_POOL(raw_file::DumperIW5, m_raw_file, ASSET_TYPE_RAWFILE) - DUMP_ASSET_POOL(script::DumperIW5, m_script_file, ASSET_TYPE_SCRIPTFILE) - DUMP_ASSET_POOL(string_table::DumperIW5, m_string_table, ASSET_TYPE_STRINGTABLE) - DUMP_ASSET_POOL(leaderboard::JsonDumperIW5, m_leaderboard, ASSET_TYPE_LEADERBOARD) - // DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set, ASSET_TYPE_STRUCTURED_DATA_DEF) - // DUMP_ASSET_POOL(AssetDumperTracerDef, m_tracer, ASSET_TYPE_TRACER) - // DUMP_ASSET_POOL(AssetDumperVehicleDef, m_vehicle, ASSET_TYPE_VEHICLE) - DUMP_ASSET_POOL(addon_map_ents::DumperIW5, m_addon_map_ents, ASSET_TYPE_ADDON_MAP_ENTS) + std::vector> dumpers; + + // REGISTER_DUMPER(AssetDumperPhysPreset, m_phys_preset) + // REGISTER_DUMPER(AssetDumperPhysCollmap, m_phys_collmap) + // REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts) + // REGISTER_DUMPER(AssetDumperXModelSurfs, m_xmodel_surfs) + REGISTER_DUMPER(xmodel::DumperIW5, m_xmodel) + REGISTER_DUMPER(material::JsonDumperIW5, m_material) + // REGISTER_DUMPER(AssetDumperMaterialPixelShader, m_material_pixel_shader) + // REGISTER_DUMPER(AssetDumperMaterialVertexShader, m_material_vertex_shader) + // REGISTER_DUMPER(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl) + // REGISTER_DUMPER(AssetDumperMaterialTechniqueSet, m_technique_set) + REGISTER_DUMPER(image::DumperIW5, m_image) + // REGISTER_DUMPER(AssetDumpersnd_alias_list_t, m_sound) + // REGISTER_DUMPER(AssetDumperSndCurve, m_sound_curve) + REGISTER_DUMPER(sound::LoadedSoundDumperIW5, m_loaded_sound) + // REGISTER_DUMPER(AssetDumperclipMap_t, m_clip_map) + // REGISTER_DUMPER(AssetDumperComWorld, m_com_world) + // REGISTER_DUMPER(AssetDumperGlassWorld, m_glass_world) + // REGISTER_DUMPER(AssetDumperPathData, m_path_data) + // REGISTER_DUMPER(AssetDumperVehicleTrack, m_vehicle_track) + // REGISTER_DUMPER(AssetDumperMapEnts, m_map_ents) + // REGISTER_DUMPER(AssetDumperFxWorld, m_fx_world) + // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) + // REGISTER_DUMPER(AssetDumperGfxLightDef, m_gfx_light_def) + // REGISTER_DUMPER(AssetDumperFont_s, m_font) + REGISTER_DUMPER(menu::MenuListDumperIW5, m_menu_list) + REGISTER_DUMPER(menu::MenuDumperIW5, m_menu_def) + REGISTER_DUMPER(localize::DumperIW5, m_localize) + REGISTER_DUMPER(attachment::JsonDumperIW5, m_attachment) + REGISTER_DUMPER(weapon::DumperIW5, m_weapon) + // REGISTER_DUMPER(AssetDumperFxEffectDef, m_fx) + // REGISTER_DUMPER(AssetDumperFxImpactTable, m_fx_impact_table) + // REGISTER_DUMPER(AssetDumperSurfaceFxTable, m_surface_fx_table) + REGISTER_DUMPER(raw_file::DumperIW5, m_raw_file) + REGISTER_DUMPER(script::DumperIW5, m_script_file) + REGISTER_DUMPER(string_table::DumperIW5, m_string_table) + REGISTER_DUMPER(leaderboard::JsonDumperIW5, m_leaderboard) + // REGISTER_DUMPER(AssetDumperStructuredDataDefSet, m_structed_data_def_set) + // REGISTER_DUMPER(AssetDumperTracerDef, m_tracer) + // REGISTER_DUMPER(AssetDumperVehicleDef, m_vehicle) + REGISTER_DUMPER(addon_map_ents::DumperIW5, m_addon_map_ents) + + if (context.ShouldTrackProgress()) + { + size_t totalProgress = 0uz; + for (const auto& dumper : dumpers) + totalProgress += dumper->GetProgressTotalCount(); + + context.SetTotalProgress(totalProgress); + } + + for (const auto& dumper : dumpers) + dumper->Dump(context); return true; -#undef DUMP_ASSET_POOL +#undef REGISTER_DUMPER } diff --git a/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.cpp b/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.cpp index 9021e3b3..30b9fcfb 100644 --- a/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.cpp @@ -10,15 +10,15 @@ using namespace IW5; namespace raw_file { - bool DumperIW5::ShouldDump(XAssetInfo* asset) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* rawFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* rawFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.h b/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.h index ed2ceb4f..1da93e45 100644 --- a/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.h +++ b/src/ObjWriting/Game/IW5/RawFile/RawFileDumperIW5.h @@ -5,10 +5,12 @@ namespace raw_file { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { + public: + explicit DumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace raw_file diff --git a/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.cpp b/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.cpp index d334cb1c..1fcbf206 100644 --- a/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.cpp @@ -4,16 +4,16 @@ using namespace IW5; namespace script { - bool DumperIW5::ShouldDump(XAssetInfo* asset) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } // See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - auto* scriptFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name + ".gscbin"); + auto* scriptFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name + ".gscbin"); if (!assetFile) return; @@ -21,10 +21,10 @@ namespace script auto& stream = *assetFile; // Dump the name and the numeric fields - stream.write(asset->m_name.c_str(), asset->m_name.size() + 1); - stream.write(reinterpret_cast(&scriptFile->compressedLen), sizeof(scriptFile->compressedLen)); - stream.write(reinterpret_cast(&scriptFile->len), sizeof(scriptFile->len)); - stream.write(reinterpret_cast(&scriptFile->bytecodeLen), sizeof(scriptFile->bytecodeLen)); + stream.write(asset.m_name.c_str(), asset.m_name.size() + 1); + stream.write(reinterpret_cast(&scriptFile->compressedLen), sizeof(scriptFile->compressedLen)); + stream.write(reinterpret_cast(&scriptFile->len), sizeof(scriptFile->len)); + stream.write(reinterpret_cast(&scriptFile->bytecodeLen), sizeof(scriptFile->bytecodeLen)); // Dump the buffers stream.write(scriptFile->buffer, scriptFile->compressedLen); diff --git a/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.h b/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.h index e1220f5f..920f3733 100644 --- a/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Script/ScriptDumperIW5.h @@ -5,10 +5,12 @@ namespace script { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { + public: + explicit DumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace script diff --git a/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp index 4a50e20b..5a847929 100644 --- a/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp @@ -25,15 +25,15 @@ namespace namespace sound { - bool LoadedSoundDumperIW5::ShouldDump(XAssetInfo* asset) + LoadedSoundDumperIW5::LoadedSoundDumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void LoadedSoundDumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void LoadedSoundDumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* loadedSound = asset->Asset(); - const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + const auto* loadedSound = asset.Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h index 8079f27d..32350c68 100644 --- a/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h @@ -5,10 +5,12 @@ namespace sound { - class LoadedSoundDumperIW5 final : public AbstractAssetDumper + class LoadedSoundDumperIW5 final : public AbstractAssetDumper { + public: + explicit LoadedSoundDumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace sound diff --git a/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.cpp b/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.cpp index 2bd7fa00..0b3dfae2 100644 --- a/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.cpp @@ -6,15 +6,15 @@ using namespace IW5; namespace string_table { - bool DumperIW5::ShouldDump(XAssetInfo* asset) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* stringTable = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* stringTable = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.h b/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.h index e826dfd0..071a08ee 100644 --- a/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.h +++ b/src/ObjWriting/Game/IW5/StringTable/StringTableDumperIW5.h @@ -5,10 +5,12 @@ namespace string_table { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { + public: + explicit DumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace string_table diff --git a/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.cpp b/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.cpp index c44f99a2..79f842c9 100644 --- a/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.cpp @@ -395,19 +395,19 @@ namespace namespace attachment { - bool JsonDumperIW5::ShouldDump(XAssetInfo* asset) + JsonDumperIW5::JsonDumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAssetName(asset.m_name)); if (!assetFile) return; const JsonDumperImpl dumper(context, *assetFile); - dumper.Dump(asset->Asset()); + dumper.Dump(asset.Asset()); } } // namespace attachment diff --git a/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.h b/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.h index 81088a63..f43204a1 100644 --- a/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Weapon/AttachmentJsonDumperIW5.h @@ -5,10 +5,12 @@ namespace attachment { - class JsonDumperIW5 final : public AbstractAssetDumper + class JsonDumperIW5 final : public AbstractAssetDumper { + public: + explicit JsonDumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace attachment diff --git a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp index 67ab7628..ed3f984d 100644 --- a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp @@ -681,31 +681,31 @@ namespace } } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { const auto fullDef = std::make_unique(); memset(fullDef.get(), 0, sizeof(WeaponFullDef)); - CopyToFullDef(asset->Asset(), fullDef.get()); + CopyToFullDef(asset.Asset(), fullDef.get()); InfoStringFromWeaponConverter converter(fullDef.get(), weapon_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); } - void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); - const auto weapon = asset->Asset(); + const auto weapon = asset.Asset(); const auto* weapDef = weapon->weapDef; if (!weapDef) @@ -733,12 +733,12 @@ namespace namespace weapon { - bool DumperIW5::ShouldDump(XAssetInfo* asset) + DumperIW5::DumperIW5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperIW5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // TODO: only dump infostring fields when non-default @@ -746,13 +746,13 @@ namespace weapon if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_WEAPON); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.h b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.h index 3e80c669..5772e5fc 100644 --- a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.h +++ b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW5/IW5.h" -#include "InfoString/InfoString.h" namespace weapon { - class DumperIW5 final : public AbstractAssetDumper + class DumperIW5 final : public AbstractAssetDumper { + public: + explicit DumperIW5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace weapon diff --git a/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp b/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp index 6843efa8..27fe8f03 100644 --- a/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp +++ b/src/ObjWriting/Game/T5/Image/ImageDumperT5.cpp @@ -59,7 +59,8 @@ namespace namespace image { - DumperT5::DumperT5() + DumperT5::DumperT5(const AssetPool& pool) + : AbstractAssetDumper(pool) { switch (ObjWriting::Configuration.ImageOutputFormat) { @@ -76,19 +77,14 @@ namespace image } } - bool DumperT5::ShouldDump(XAssetInfo* asset) + void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void DumperT5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto* image = asset->Asset(); + const auto* image = asset.Asset(); const auto texture = LoadImageData(context.m_obj_search_path, *image); if (!texture) return; - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name, m_writer->GetFileExtension())); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T5/Image/ImageDumperT5.h b/src/ObjWriting/Game/T5/Image/ImageDumperT5.h index 0be6b9bb..109758e5 100644 --- a/src/ObjWriting/Game/T5/Image/ImageDumperT5.h +++ b/src/ObjWriting/Game/T5/Image/ImageDumperT5.h @@ -8,14 +8,13 @@ namespace image { - class DumperT5 final : public AbstractAssetDumper + class DumperT5 final : public AbstractAssetDumper { public: - DumperT5(); + explicit DumperT5(const AssetPool& pool); protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: std::unique_ptr m_writer; diff --git a/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.cpp b/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.cpp index 0ed7388b..5edb14a4 100644 --- a/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.cpp +++ b/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.cpp @@ -11,9 +11,14 @@ using namespace T5; namespace localize { - void DumperT5::DumpPool(AssetDumpingContext& context, AssetPool* pool) + DumperT5::DumperT5(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) { - if (pool->m_asset_lookup.empty()) + } + + void DumperT5::Dump(AssetDumpingContext& context) + { + if (m_pool.m_asset_lookup.empty()) return; const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language); @@ -30,7 +35,7 @@ namespace localize stringFileDumper.SetNotes(""); - for (auto* localizeEntry : *pool) + for (const auto* localizeEntry : m_pool) { stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); } @@ -41,5 +46,7 @@ namespace localize { con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name); } + + context.IncrementProgress(); } } // namespace localize diff --git a/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.h b/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.h index 321a9aef..5dfac74c 100644 --- a/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.h +++ b/src/ObjWriting/Game/T5/Localize/LocalizeDumperT5.h @@ -5,9 +5,11 @@ namespace localize { - class DumperT5 final : public IAssetDumper + class DumperT5 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit DumperT5(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; }; } // namespace localize diff --git a/src/ObjWriting/Game/T5/ObjWriterT5.cpp b/src/ObjWriting/Game/T5/ObjWriterT5.cpp index 208f14ba..c1acccb0 100644 --- a/src/ObjWriting/Game/T5/ObjWriterT5.cpp +++ b/src/ObjWriting/Game/T5/ObjWriterT5.cpp @@ -13,49 +13,61 @@ using namespace T5; bool ObjWriter::DumpZone(AssetDumpingContext& context) const { -#define DUMP_ASSET_POOL(dumperType, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER(dumperType, poolName) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(dumperType::AssetType_t::EnumEntry)) \ { \ - dumperType dumper; \ - dumper.DumpPool(context, assetPools->poolName.get()); \ + dumpers.emplace_back(std::make_unique(*assetPools->poolName)); \ } const auto* assetPools = dynamic_cast(context.m_zone.m_pools.get()); + std::vector> dumpers; - // DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset, ASSET_TYPE_PHYSPRESET) - // DUMP_ASSET_POOL(AssetDumperPhysConstraints, m_phys_constraints, ASSET_TYPE_PHYSCONSTRAINTS) - // DUMP_ASSET_POOL(AssetDumperDestructibleDef, m_destructible_def, ASSET_TYPE_DESTRUCTIBLEDEF) - // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) - DUMP_ASSET_POOL(xmodel::DumperT5, m_xmodel, ASSET_TYPE_XMODEL) - DUMP_ASSET_POOL(material::JsonDumperT5, m_material, ASSET_TYPE_MATERIAL) - // DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) - DUMP_ASSET_POOL(image::DumperT5, m_image, ASSET_TYPE_IMAGE) - // DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank, ASSET_TYPE_SOUND) - // DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch, ASSET_TYPE_SOUND_PATCH) - // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_PVS) - // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) - // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) - // DUMP_ASSET_POOL(AssetDumperGameWorldMp, m_game_world_mp, ASSET_TYPE_GAMEWORLD_MP) - // DUMP_ASSET_POOL(AssetDumperMapEnts, m_map_ents, ASSET_TYPE_MAP_ENTS) - // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world, ASSET_TYPE_GFXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def, ASSET_TYPE_LIGHT_DEF) - // DUMP_ASSET_POOL(AssetDumperFont, m_font, ASSET_TYPE_FONT) - // DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST) - // DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU) - DUMP_ASSET_POOL(localize::DumperT5, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - // DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON) - // DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) - // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) - // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) - DUMP_ASSET_POOL(raw_file::DumperT5, m_raw_file, ASSET_TYPE_RAWFILE) - DUMP_ASSET_POOL(string_table::DumperT5, m_string_table, ASSET_TYPE_STRINGTABLE) - // DUMP_ASSET_POOL(AssetDumperPackIndex, m_pack_index, ASSET_TYPE_PACK_INDEX) - // DUMP_ASSET_POOL(AssetDumperXGlobals, m_xglobals, ASSET_TYPE_XGLOBALS) - // DUMP_ASSET_POOL(AssetDumperDDLRoot, m_ddl, ASSET_TYPE_DDL) - // DUMP_ASSET_POOL(AssetDumperGlasses, m_glasses, ASSET_TYPE_GLASSES) - // DUMP_ASSET_POOL(AssetDumperEmblemSet, m_emblem_set, ASSET_TYPE_EMBLEMSET) + // REGISTER_DUMPER(AssetDumperPhysPreset, m_phys_preset) + // REGISTER_DUMPER(AssetDumperPhysConstraints, m_phys_constraints) + // REGISTER_DUMPER(AssetDumperDestructibleDef, m_destructible_def) + // REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts) + REGISTER_DUMPER(xmodel::DumperT5, m_xmodel) + REGISTER_DUMPER(material::JsonDumperT5, m_material) + // REGISTER_DUMPER(AssetDumperTechniqueSet, m_technique_set) + REGISTER_DUMPER(image::DumperT5, m_image) + // REGISTER_DUMPER(AssetDumperSndBank, m_sound_bank) + // REGISTER_DUMPER(AssetDumperSndPatch, m_sound_patch) + // REGISTER_DUMPER(AssetDumperClipMap, m_clip_map) + // REGISTER_DUMPER(AssetDumperComWorld, m_com_world) + // REGISTER_DUMPER(AssetDumperGameWorldSp, m_game_world_sp) + // REGISTER_DUMPER(AssetDumperGameWorldMp, m_game_world_mp) + // REGISTER_DUMPER(AssetDumperMapEnts, m_map_ents) + // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) + // REGISTER_DUMPER(AssetDumperGfxLightDef, m_gfx_light_def) + // REGISTER_DUMPER(AssetDumperFont, m_font) + // REGISTER_DUMPER(AssetDumperMenuList, m_menu_list) + // REGISTER_DUMPER(AssetDumperMenuDef, m_menu_def) + REGISTER_DUMPER(localize::DumperT5, m_localize) + // REGISTER_DUMPER(AssetDumperWeapon, m_weapon) + // REGISTER_DUMPER(AssetDumperSndDriverGlobals, m_snd_driver_globals) + // REGISTER_DUMPER(AssetDumperFxEffectDef, m_fx) + // REGISTER_DUMPER(AssetDumperFxImpactTable, m_fx_impact_table) + REGISTER_DUMPER(raw_file::DumperT5, m_raw_file) + REGISTER_DUMPER(string_table::DumperT5, m_string_table) + // REGISTER_DUMPER(AssetDumperPackIndex, m_pack_index) + // REGISTER_DUMPER(AssetDumperXGlobals, m_xglobals) + // REGISTER_DUMPER(AssetDumperDDLRoot, m_ddl) + // REGISTER_DUMPER(AssetDumperGlasses, m_glasses) + // REGISTER_DUMPER(AssetDumperEmblemSet, m_emblem_set) + + if (context.ShouldTrackProgress()) + { + size_t totalProgress = 0uz; + for (const auto& dumper : dumpers) + totalProgress += dumper->GetProgressTotalCount(); + + context.SetTotalProgress(totalProgress); + } + + for (const auto& dumper : dumpers) + dumper->Dump(context); return true; -#undef DUMP_ASSET_POOL +#undef REGISTER_DUMPER } diff --git a/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.cpp b/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.cpp index a3d41751..ca86c231 100644 --- a/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.cpp +++ b/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.cpp @@ -15,9 +15,9 @@ namespace { constexpr static size_t GSC_MAX_SIZE = 0xC000000; - void DumpGsc(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) + void DumpGsc(AssetDumpingContext& context, const XAssetInfo& asset, std::ostream& stream) { - const auto* rawFile = asset->Asset(); + const auto* rawFile = asset.Asset(); if (rawFile->len <= 8) { @@ -96,15 +96,15 @@ namespace namespace raw_file { - bool DumperT5::ShouldDump(XAssetInfo* asset) + DumperT5::DumperT5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* rawFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* rawFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.h b/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.h index 056266ae..46ec5302 100644 --- a/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.h +++ b/src/ObjWriting/Game/T5/RawFile/RawFileDumperT5.h @@ -5,10 +5,12 @@ namespace raw_file { - class DumperT5 final : public AbstractAssetDumper + class DumperT5 final : public AbstractAssetDumper { + public: + explicit DumperT5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace raw_file diff --git a/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.cpp b/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.cpp index 0acc3587..ce6135e9 100644 --- a/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.cpp +++ b/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.cpp @@ -6,15 +6,15 @@ using namespace T5; namespace string_table { - bool DumperT5::ShouldDump(XAssetInfo* asset) + DumperT5::DumperT5(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT5::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* stringTable = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* stringTable = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.h b/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.h index 12ee953b..4d388533 100644 --- a/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.h +++ b/src/ObjWriting/Game/T5/StringTable/StringTableDumperT5.h @@ -5,10 +5,12 @@ namespace string_table { - class DumperT5 final : public AbstractAssetDumper + class DumperT5 final : public AbstractAssetDumper { + public: + explicit DumperT5(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace string_table diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.cpp b/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.cpp index 95c6f1cc..77282951 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.cpp +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.cpp @@ -133,19 +133,19 @@ namespace namespace font_icon { - bool CsvDumperT6::ShouldDump(XAssetInfo* asset) + CsvDumperT6::CsvDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void CsvDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void CsvDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; Dumper dumper(*assetFile); - dumper.Dump(*asset->Asset()); + dumper.Dump(*asset.Asset()); } } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.h b/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.h index aeaa8877..ee880ff2 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.h +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconCsvDumperT6.h @@ -5,10 +5,12 @@ namespace font_icon { - class CsvDumperT6 final : public AbstractAssetDumper + class CsvDumperT6 final : public AbstractAssetDumper { + public: + explicit CsvDumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.cpp b/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.cpp index 9f41412b..b042fd13 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.cpp +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.cpp @@ -9,12 +9,12 @@ using namespace T6; namespace font_icon { - std::unique_ptr> CreateDumperT6() + std::unique_ptr CreateDumperT6(const AssetPool& pool) { #ifdef DUMP_FONT_ICON_AS_CSV - return std::make_unique(); + return std::make_unique(pool); #else - return std::make_unique(); + return std::make_unique(pool); #endif } } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.h b/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.h index 55d048f9..e150b9c2 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.h +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconDumperT6.h @@ -7,5 +7,5 @@ namespace font_icon { - std::unique_ptr> CreateDumperT6(); + std::unique_ptr CreateDumperT6(const AssetPool& pool); } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.cpp b/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.cpp index e82b3b36..f82ef8dc 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.cpp +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.cpp @@ -78,18 +78,18 @@ namespace namespace font_icon { - bool JsonDumperT6::ShouldDump(XAssetInfo* asset) + JsonDumperT6::JsonDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAssetName(asset.m_name)); if (!assetFile) return; - DumpFontIcon(*assetFile, *asset->Asset()); + DumpFontIcon(*assetFile, *asset.Asset()); } } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.h b/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.h index aa1c0017..f25c0761 100644 --- a/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.h +++ b/src/ObjWriting/Game/T6/FontIcon/FontIconJsonDumperT6.h @@ -5,10 +5,12 @@ namespace font_icon { - class JsonDumperT6 final : public AbstractAssetDumper + class JsonDumperT6 final : public AbstractAssetDumper { + public: + explicit JsonDumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace font_icon diff --git a/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp b/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp index 02317695..3566f780 100644 --- a/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Image/ImageDumperT6.cpp @@ -77,7 +77,8 @@ namespace namespace image { - DumperT6::DumperT6() + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { switch (ObjWriting::Configuration.ImageOutputFormat) { @@ -94,19 +95,14 @@ namespace image } } - bool DumperT6::ShouldDump(XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto* image = asset->Asset(); + const auto* image = asset.Asset(); const auto texture = LoadImageData(context.m_obj_search_path, *image); if (!texture) return; - const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset->m_name, m_writer->GetFileExtension())); + const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name, m_writer->GetFileExtension())); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Image/ImageDumperT6.h b/src/ObjWriting/Game/T6/Image/ImageDumperT6.h index 5fac0233..81dc2e93 100644 --- a/src/ObjWriting/Game/T6/Image/ImageDumperT6.h +++ b/src/ObjWriting/Game/T6/Image/ImageDumperT6.h @@ -8,14 +8,13 @@ namespace image { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { public: - DumperT6(); + explicit DumperT6(const AssetPool& pool); protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; private: std::unique_ptr m_writer; diff --git a/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.cpp b/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.cpp index 4a90d7b2..0a68fd4a 100644 --- a/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.cpp @@ -98,19 +98,19 @@ namespace namespace leaderboard { - bool JsonDumperT6::ShouldDump(XAssetInfo* asset) + JsonDumperT6::JsonDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetJsonFileNameForAsset(asset.m_name)); if (!assetFile) return; Dumper dumper(*assetFile); - dumper.Dump(*asset->Asset()); + dumper.Dump(*asset.Asset()); } } // namespace leaderboard diff --git a/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.h b/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.h index ebbe4c9f..90db9a73 100644 --- a/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.h +++ b/src/ObjWriting/Game/T6/Leaderboard/LeaderboardJsonDumperT6.h @@ -5,10 +5,12 @@ namespace leaderboard { - class JsonDumperT6 final : public AbstractAssetDumper + class JsonDumperT6 final : public AbstractAssetDumper { + public: + explicit JsonDumperT6(const AssetPool& pool); + protected: - [[nodiscard]] bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace leaderboard diff --git a/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.cpp b/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.cpp index c6281264..5928599b 100644 --- a/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.cpp @@ -11,9 +11,14 @@ using namespace T6; namespace localize { - void DumperT6::DumpPool(AssetDumpingContext& context, AssetPool* pool) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) { - if (pool->m_asset_lookup.empty()) + } + + void DumperT6::Dump(AssetDumpingContext& context) + { + if (m_pool.m_asset_lookup.empty()) return; const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language); @@ -30,7 +35,7 @@ namespace localize stringFileDumper.SetNotes(""); - for (auto* localizeEntry : *pool) + for (const auto* localizeEntry : m_pool) { stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); } @@ -41,5 +46,7 @@ namespace localize { con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name); } + + context.IncrementProgress(); } } // namespace localize diff --git a/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.h b/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.h index 1a39defe..184d7a8b 100644 --- a/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.h +++ b/src/ObjWriting/Game/T6/Localize/LocalizeDumperT6.h @@ -5,9 +5,11 @@ namespace localize { - class DumperT6 final : public IAssetDumper + class DumperT6 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit DumperT6(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; }; } // namespace localize diff --git a/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.cpp b/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.cpp index caf8abd5..ad6c87aa 100644 --- a/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.cpp @@ -6,14 +6,14 @@ using namespace T6; namespace map_ents { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* mapEnts = asset->Asset(); + const auto* mapEnts = asset.Asset(); const auto mapEntsFile = context.OpenAssetFile(std::format("{}.ents", mapEnts->name)); diff --git a/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.h b/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.h index 9dbf36bb..76270145 100644 --- a/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.h +++ b/src/ObjWriting/Game/T6/Maps/MapEntsDumperT6.h @@ -5,10 +5,12 @@ namespace map_ents { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace map_ents diff --git a/src/ObjWriting/Game/T6/ObjWriterT6.cpp b/src/ObjWriting/Game/T6/ObjWriterT6.cpp index 06c66520..df9c60ab 100644 --- a/src/ObjWriting/Game/T6/ObjWriterT6.cpp +++ b/src/ObjWriting/Game/T6/ObjWriterT6.cpp @@ -31,71 +31,84 @@ using namespace T6; bool ObjWriter::DumpZone(AssetDumpingContext& context) const { -#define DUMP_ASSET_POOL(dumperType, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER(dumperType, poolName) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(dumperType::AssetType_t::EnumEntry)) \ { \ - dumperType dumper; \ - dumper.DumpPool(context, assetPools->poolName.get()); \ + dumpers.emplace_back(std::make_unique(*assetPools->poolName)); \ } -#define DUMP_ASSET_POOL_WITH_FACTORY(createDumper, poolName, assetType) \ - if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(assetType)) \ +#define REGISTER_DUMPER_WITH_FACTORY(createDumper, poolName, asset) \ + if (assetPools->poolName && ObjWriting::ShouldHandleAssetType(asset::EnumEntry)) \ { \ - const auto dumper = createDumper; \ - dumper->DumpPool(context, assetPools->poolName.get()); \ + auto dumper = createDumper(*assetPools->poolName); \ + if (dumper) \ + dumpers.emplace_back(std::move(dumper)); \ } const auto* assetPools = dynamic_cast(context.m_zone.m_pools.get()); + std::vector> dumpers; - DUMP_ASSET_POOL(phys_preset::InfoStringDumperT6, m_phys_preset, ASSET_TYPE_PHYSPRESET) - DUMP_ASSET_POOL(phys_constraints::InfoStringDumperT6, m_phys_constraints, ASSET_TYPE_PHYSCONSTRAINTS) - // DUMP_ASSET_POOL(AssetDumperDestructibleDef, m_destructible_def, ASSET_TYPE_DESTRUCTIBLEDEF) - // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS) - DUMP_ASSET_POOL(xmodel::DumperT6, m_xmodel, ASSET_TYPE_XMODEL) - DUMP_ASSET_POOL(material::JsonDumperT6, m_material, ASSET_TYPE_MATERIAL) - DUMP_ASSET_POOL(techset::DumperT6, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) - DUMP_ASSET_POOL(image::DumperT6, m_image, ASSET_TYPE_IMAGE) - DUMP_ASSET_POOL(sound::SndBankDumperT6, m_sound_bank, ASSET_TYPE_SOUND) - // DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch, ASSET_TYPE_SOUND_PATCH) - // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_PVS) - // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) - // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) - // DUMP_ASSET_POOL(AssetDumperGameWorldMp, m_game_world_mp, ASSET_TYPE_GAMEWORLD_MP) - DUMP_ASSET_POOL(map_ents::DumperT6, m_map_ents, ASSET_TYPE_MAP_ENTS) - // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world, ASSET_TYPE_GFXWORLD) - // DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def, ASSET_TYPE_LIGHT_DEF) - // DUMP_ASSET_POOL(AssetDumperFont, m_font, ASSET_TYPE_FONT) - DUMP_ASSET_POOL_WITH_FACTORY(font_icon::CreateDumperT6(), m_font_icon, ASSET_TYPE_FONTICON) - // DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST) - // DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU) - DUMP_ASSET_POOL(localize::DumperT6, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - DUMP_ASSET_POOL(weapon::DumperT6, m_weapon, ASSET_TYPE_WEAPON) - DUMP_ASSET_POOL(attachment::DumperT6, m_attachment, ASSET_TYPE_ATTACHMENT) - DUMP_ASSET_POOL(attachment_unique::DumperT6, m_attachment_unique, ASSET_TYPE_ATTACHMENT_UNIQUE) - DUMP_ASSET_POOL(camo::JsonDumperT6, m_camo, ASSET_TYPE_WEAPON_CAMO) - DUMP_ASSET_POOL(sound::SndDriverGlobalsDumperT6, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) - // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) - // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) - DUMP_ASSET_POOL(raw_file::DumperT6, m_raw_file, ASSET_TYPE_RAWFILE) - DUMP_ASSET_POOL(string_table::DumperT6, m_string_table, ASSET_TYPE_STRINGTABLE) - DUMP_ASSET_POOL(leaderboard::JsonDumperT6, m_leaderboard, ASSET_TYPE_LEADERBOARD) - // DUMP_ASSET_POOL(AssetDumperXGlobals, m_xglobals, ASSET_TYPE_XGLOBALS) - // DUMP_ASSET_POOL(AssetDumperDDLRoot, m_ddl, ASSET_TYPE_DDL) - // DUMP_ASSET_POOL(AssetDumperGlasses, m_glasses, ASSET_TYPE_GLASSES) - // DUMP_ASSET_POOL(AssetDumperEmblemSet, m_emblem_set, ASSET_TYPE_EMBLEMSET) - DUMP_ASSET_POOL(script::DumperT6, m_script, ASSET_TYPE_SCRIPTPARSETREE) - // DUMP_ASSET_POOL(AssetDumperKeyValuePairs, m_key_value_pairs, ASSET_TYPE_KEYVALUEPAIRS) - DUMP_ASSET_POOL(vehicle::DumperT6, m_vehicle, ASSET_TYPE_VEHICLEDEF) - // DUMP_ASSET_POOL(AssetDumperMemoryBlock, m_memory_block, ASSET_TYPE_MEMORYBLOCK) - // DUMP_ASSET_POOL(AssetDumperAddonMapEnts, m_addon_map_ents, ASSET_TYPE_ADDON_MAP_ENTS) - DUMP_ASSET_POOL(tracer::DumperT6, m_tracer, ASSET_TYPE_TRACER) - // DUMP_ASSET_POOL(AssetDumperSkinnedVertsDef, m_skinned_verts, ASSET_TYPE_SKINNEDVERTS) - DUMP_ASSET_POOL(qdb::DumperT6, m_qdb, ASSET_TYPE_QDB) - DUMP_ASSET_POOL(slug::DumperT6, m_slug, ASSET_TYPE_SLUG) - // DUMP_ASSET_POOL(AssetDumperFootstepTableDef, m_footstep_table, ASSET_TYPE_FOOTSTEP_TABLE) - // DUMP_ASSET_POOL(AssetDumperFootstepFXTableDef, m_footstep_fx_table, ASSET_TYPE_FOOTSTEPFX_TABLE) - DUMP_ASSET_POOL(z_barrier::DumperT6, m_zbarrier, ASSET_TYPE_ZBARRIER) + REGISTER_DUMPER(phys_preset::InfoStringDumperT6, m_phys_preset) + REGISTER_DUMPER(phys_constraints::InfoStringDumperT6, m_phys_constraints) + // REGISTER_DUMPER(AssetDumperDestructibleDef, m_destructible_def) + // REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts) + REGISTER_DUMPER(xmodel::DumperT6, m_xmodel) + REGISTER_DUMPER(material::JsonDumperT6, m_material) + REGISTER_DUMPER(techset::DumperT6, m_technique_set) + REGISTER_DUMPER(image::DumperT6, m_image) + REGISTER_DUMPER(sound::SndBankDumperT6, m_sound_bank) + // REGISTER_DUMPER(AssetDumperSndPatch, m_sound_patch) + // REGISTER_DUMPER(AssetDumperClipMap, m_clip_map) + // REGISTER_DUMPER(AssetDumperComWorld, m_com_world) + // REGISTER_DUMPER(AssetDumperGameWorldSp, m_game_world_sp) + // REGISTER_DUMPER(AssetDumperGameWorldMp, m_game_world_mp) + REGISTER_DUMPER(map_ents::DumperT6, m_map_ents) + // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) + // REGISTER_DUMPER(AssetDumperGfxLightDef, m_gfx_light_def) + // REGISTER_DUMPER(AssetDumperFont, m_font) + REGISTER_DUMPER_WITH_FACTORY(font_icon::CreateDumperT6, m_font_icon, AssetFontIcon) + // REGISTER_DUMPER(AssetDumperMenuList, m_menu_list) + // REGISTER_DUMPER(AssetDumperMenuDef, m_menu_def) + REGISTER_DUMPER(localize::DumperT6, m_localize) + REGISTER_DUMPER(weapon::DumperT6, m_weapon) + REGISTER_DUMPER(attachment::DumperT6, m_attachment) + REGISTER_DUMPER(attachment_unique::DumperT6, m_attachment_unique) + REGISTER_DUMPER(camo::JsonDumperT6, m_camo) + REGISTER_DUMPER(sound::SndDriverGlobalsDumperT6, m_snd_driver_globals) + // REGISTER_DUMPER(AssetDumperFxEffectDef, m_fx) + // REGISTER_DUMPER(AssetDumperFxImpactTable, m_fx_impact_table) + REGISTER_DUMPER(raw_file::DumperT6, m_raw_file) + REGISTER_DUMPER(string_table::DumperT6, m_string_table) + REGISTER_DUMPER(leaderboard::JsonDumperT6, m_leaderboard) + // REGISTER_DUMPER(AssetDumperXGlobals, m_xglobals) + // REGISTER_DUMPER(AssetDumperDDLRoot, m_ddl) + // REGISTER_DUMPER(AssetDumperGlasses, m_glasses) + // REGISTER_DUMPER(AssetDumperEmblemSet, m_emblem_set) + REGISTER_DUMPER(script::DumperT6, m_script) + // REGISTER_DUMPER(AssetDumperKeyValuePairs, m_key_value_pairs) + REGISTER_DUMPER(vehicle::DumperT6, m_vehicle) + // REGISTER_DUMPER(AssetDumperMemoryBlock, m_memory_block) + // REGISTER_DUMPER(AssetDumperAddonMapEnts, m_addon_map_ents) + REGISTER_DUMPER(tracer::DumperT6, m_tracer) + // REGISTER_DUMPER(AssetDumperSkinnedVertsDef, m_skinned_verts) + REGISTER_DUMPER(qdb::DumperT6, m_qdb) + REGISTER_DUMPER(slug::DumperT6, m_slug) + // REGISTER_DUMPER(AssetDumperFootstepTableDef, m_footstep_table) + // REGISTER_DUMPER(AssetDumperFootstepFXTableDef, m_footstep_fx_table) + REGISTER_DUMPER(z_barrier::DumperT6, m_zbarrier) + + if (context.ShouldTrackProgress()) + { + size_t totalProgress = 0uz; + for (const auto& dumper : dumpers) + totalProgress += dumper->GetProgressTotalCount(); + + context.SetTotalProgress(totalProgress); + } + + for (const auto& dumper : dumpers) + dumper->Dump(context); return true; -#undef DUMP_ASSET_POOL +#undef REGISTER_DUMPER } diff --git a/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.cpp b/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.cpp index c0c2d7ce..4f6dee21 100644 --- a/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.cpp +++ b/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.cpp @@ -39,20 +39,20 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - assert(asset->Asset()->count <= 4); + assert(asset.Asset()->count <= 4); - InfoStringFromPhysConstraintsConverter converter(asset->Asset(), + InfoStringFromPhysConstraintsConverter converter(asset.Asset(), phys_constraints_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -61,24 +61,24 @@ namespace namespace phys_constraints { - bool InfoStringDumperT6::ShouldDump(XAssetInfo* asset) + InfoStringDumperT6::InfoStringDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void InfoStringDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void InfoStringDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_PHYS_CONSTRAINTS); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_PHYS_CONSTRAINTS); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_PHYS_CONSTRAINTS, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.h b/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.h index 4d1c5e70..87ae940e 100644 --- a/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.h +++ b/src/ObjWriting/Game/T6/PhysConstraints/PhysConstraintsInfoStringDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace phys_constraints { - class InfoStringDumperT6 final : public AbstractAssetDumper + class InfoStringDumperT6 final : public AbstractAssetDumper { + public: + explicit InfoStringDumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace phys_constraints diff --git a/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.cpp b/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.cpp index c4f5dd85..b0948f97 100644 --- a/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.cpp +++ b/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.cpp @@ -59,21 +59,21 @@ namespace physPresetInfo->buoyancyBoxMax = physPreset->buoyancyBoxMax; } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { auto* physPresetInfo = new PhysPresetInfo; - CopyToPhysPresetInfo(asset->Asset(), physPresetInfo); + CopyToPhysPresetInfo(asset.Asset(), physPresetInfo); InfoStringFromPhysPresetConverter converter(physPresetInfo, phys_preset_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -82,24 +82,24 @@ namespace namespace phys_preset { - bool InfoStringDumperT6::ShouldDump(XAssetInfo* asset) + InfoStringDumperT6::InfoStringDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void InfoStringDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void InfoStringDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_PHYS_PRESET); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_PHYS_PRESET); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.h b/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.h index df52d539..90253b78 100644 --- a/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.h +++ b/src/ObjWriting/Game/T6/PhysPreset/PhysPresetInfoStringDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace phys_preset { - class InfoStringDumperT6 final : public AbstractAssetDumper + class InfoStringDumperT6 final : public AbstractAssetDumper { + public: + explicit InfoStringDumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace phys_preset diff --git a/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.cpp b/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.cpp index f990de0d..0ad923e0 100644 --- a/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.cpp @@ -4,15 +4,15 @@ using namespace T6; namespace qdb { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* qdb = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* qdb = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.h b/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.h index eb452510..6446d1eb 100644 --- a/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.h +++ b/src/ObjWriting/Game/T6/Qdb/QdbDumperT6.h @@ -5,10 +5,12 @@ namespace qdb { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace qdb diff --git a/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.cpp b/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.cpp index 9388c216..beda25b7 100644 --- a/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.cpp +++ b/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.cpp @@ -14,9 +14,9 @@ namespace { constexpr size_t ANIMTREE_MAX_SIZE = 0xC000000; - void DumpAnimtree(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) + void DumpAnimtree(AssetDumpingContext& context, const XAssetInfo& asset, std::ostream& stream) { - const auto* rawFile = asset->Asset(); + const auto* rawFile = asset.Asset(); if (rawFile->len <= 4) { @@ -77,15 +77,15 @@ namespace namespace raw_file { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* rawFile = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* rawFile = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.h b/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.h index c2faa0f9..a45aa9ac 100644 --- a/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.h +++ b/src/ObjWriting/Game/T6/RawFile/RawFileDumperT6.h @@ -5,10 +5,12 @@ namespace raw_file { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace raw_file diff --git a/src/ObjWriting/Game/T6/Script/ScriptDumperT6.cpp b/src/ObjWriting/Game/T6/Script/ScriptDumperT6.cpp index 2b2be090..dfe974a5 100644 --- a/src/ObjWriting/Game/T6/Script/ScriptDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Script/ScriptDumperT6.cpp @@ -4,15 +4,15 @@ using namespace T6; namespace script { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* scriptParseTree = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* scriptParseTree = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Script/ScriptDumperT6.h b/src/ObjWriting/Game/T6/Script/ScriptDumperT6.h index 895b55b4..bc1a9aee 100644 --- a/src/ObjWriting/Game/T6/Script/ScriptDumperT6.h +++ b/src/ObjWriting/Game/T6/Script/ScriptDumperT6.h @@ -5,10 +5,12 @@ namespace script { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace script diff --git a/src/ObjWriting/Game/T6/Slug/SlugDumperT6.cpp b/src/ObjWriting/Game/T6/Slug/SlugDumperT6.cpp index d02a11d0..7e71e468 100644 --- a/src/ObjWriting/Game/T6/Slug/SlugDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Slug/SlugDumperT6.cpp @@ -4,15 +4,15 @@ using namespace T6; namespace slug { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* slug = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* slug = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Slug/SlugDumperT6.h b/src/ObjWriting/Game/T6/Slug/SlugDumperT6.h index 3dd202e5..67bba25d 100644 --- a/src/ObjWriting/Game/T6/Slug/SlugDumperT6.h +++ b/src/ObjWriting/Game/T6/Slug/SlugDumperT6.h @@ -5,10 +5,12 @@ namespace slug { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace slug diff --git a/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp index aca65ad7..29f0485c 100644 --- a/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp @@ -198,7 +198,7 @@ namespace constexpr auto FORMATTING_RETRIES = 5; - class LoadedSoundBankHashes + class LoadedSoundBankHashes : public IZoneAssetDumperState { public: void Initialize() @@ -901,29 +901,30 @@ namespace *duckFile << duckObj.dump(4) << "\n"; } } - - void DumpSndBank(const AssetDumpingContext& context, const LoadedSoundBankHashes& hashes, const XAssetInfo& sndBankInfo) - { - const auto* sndBank = sndBankInfo.Asset(); - - DumpSndBankAliases(context, hashes, *sndBank); - DumpSoundRadverb(context, *sndBank); - DumpSoundDucks(context, *sndBank); - } } // namespace namespace sound { - void SndBankDumperT6::DumpPool(AssetDumpingContext& context, AssetPool* pool) + SndBankDumperT6::SndBankDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - LoadedSoundBankHashes soundBankHashes; - soundBankHashes.Initialize(); - for (const auto* assetInfo : *pool) - { - if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') - continue; + } - DumpSndBank(context, soundBankHashes, *assetInfo); - } + void SndBankDumperT6::Dump(AssetDumpingContext& context) + { + auto* hashes = context.GetZoneAssetDumperState(); + hashes->Initialize(); + + AbstractAssetDumper::Dump(context); + } + + void SndBankDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + const auto* sndBank = asset.Asset(); + const auto* hashes = context.GetZoneAssetDumperState(); + + DumpSndBankAliases(context, *hashes, *sndBank); + DumpSoundRadverb(context, *sndBank); + DumpSoundDucks(context, *sndBank); } } // namespace sound diff --git a/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h index f5d4f59d..616729f1 100644 --- a/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h +++ b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h @@ -5,9 +5,13 @@ namespace sound { - class SndBankDumperT6 final : public IAssetDumper + class SndBankDumperT6 final : public AbstractAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit SndBankDumperT6(const AssetPool& pool); + void Dump(AssetDumpingContext& context) override; + + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo::Type>& asset) override; }; } // namespace sound diff --git a/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp index 57649091..0c862429 100644 --- a/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp @@ -108,9 +108,9 @@ namespace { } - void DumpPool(AssetPool* pool) + void DumpPool(const AssetPool& pool) { - for (const auto* assetInfo : *pool) + for (const auto* assetInfo : pool) { if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') continue; @@ -385,9 +385,16 @@ namespace namespace sound { - void SndDriverGlobalsDumperT6::DumpPool(AssetDumpingContext& context, AssetPool* pool) + SndDriverGlobalsDumperT6::SndDriverGlobalsDumperT6(const AssetPool& pool) + : AbstractSingleProgressAssetDumper(pool) + { + } + + void SndDriverGlobalsDumperT6::Dump(AssetDumpingContext& context) { Internal internal(context); - internal.DumpPool(pool); + internal.DumpPool(m_pool); + + context.IncrementProgress(); } } // namespace sound diff --git a/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h index 042de43c..9ce2f55f 100644 --- a/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h +++ b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h @@ -5,9 +5,11 @@ namespace sound { - class SndDriverGlobalsDumperT6 final : public IAssetDumper + class SndDriverGlobalsDumperT6 final : public AbstractSingleProgressAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit SndDriverGlobalsDumperT6(const AssetPool& pool); + + void Dump(AssetDumpingContext& context) override; }; } // namespace sound diff --git a/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.cpp b/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.cpp index 4bd96479..840b0f74 100644 --- a/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.cpp +++ b/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.cpp @@ -6,15 +6,15 @@ using namespace T6; namespace string_table { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* stringTable = asset->Asset(); - const auto assetFile = context.OpenAssetFile(asset->m_name); + const auto* stringTable = asset.Asset(); + const auto assetFile = context.OpenAssetFile(asset.m_name); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.h b/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.h index b61a4380..7e6256cb 100644 --- a/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.h +++ b/src/ObjWriting/Game/T6/StringTable/StringTableDumperT6.h @@ -5,10 +5,12 @@ namespace string_table { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace string_table diff --git a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp index a2d7273c..157b17ea 100644 --- a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.cpp @@ -77,14 +77,14 @@ namespace namespace techset { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* techniqueSet = asset->Asset(); + const auto* techniqueSet = asset.Asset(); auto* shaderState = context.GetZoneAssetDumperState(); for (const auto* technique : techniqueSet->techniques) diff --git a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.h b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.h index 59a48f3f..c4093001 100644 --- a/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.h +++ b/src/ObjWriting/Game/T6/Techset/TechsetDumperT6.h @@ -5,10 +5,12 @@ namespace techset { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace techset diff --git a/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.cpp b/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.cpp index 854a45af..2767db5c 100644 --- a/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.cpp @@ -40,18 +40,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromTracerConverter converter(asset->Asset(), + InfoStringFromTracerConverter converter(asset.Asset(), tracer_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -60,24 +60,24 @@ namespace namespace tracer { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_TRACER); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_TRACER); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_TRACER, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.h b/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.h index 0bfb6d75..08b62c86 100644 --- a/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.h +++ b/src/ObjWriting/Game/T6/Tracer/TracerDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace tracer { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace tracer diff --git a/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.cpp b/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.cpp index 1178b394..ec71d6e0 100644 --- a/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.cpp @@ -91,18 +91,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromVehicleConverter converter(asset->Asset(), + InfoStringFromVehicleConverter converter(asset.Asset(), vehicle_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -111,24 +111,24 @@ namespace namespace vehicle { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_VEHICLE); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_VEHICLE); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_VEHICLE, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.h b/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.h index 5d328e87..58b64757 100644 --- a/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.h +++ b/src/ObjWriting/Game/T6/Vehicle/VehicleDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace vehicle { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace vehicle diff --git a/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.cpp index d7fcc4c7..d7649885 100644 --- a/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.cpp @@ -47,18 +47,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromAttachmentConverter converter(asset->Asset(), + InfoStringFromAttachmentConverter converter(asset.Asset(), attachment_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -67,24 +67,24 @@ namespace namespace attachment { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetInfoStringFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetInfoStringFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.h b/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.h index 0472e2a0..ad9aaee9 100644 --- a/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.h +++ b/src/ObjWriting/Game/T6/Weapon/AttachmentDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace attachment { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace attachment diff --git a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp index c10605ac..e61a2567 100644 --- a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp @@ -107,22 +107,22 @@ namespace } } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { const auto fullDef = std::make_unique(); memset(fullDef.get(), 0, sizeof(WeaponAttachmentUniqueFull)); - CopyToFullDef(asset->Asset(), fullDef.get()); + CopyToFullDef(asset.Asset(), fullDef.get()); InfoStringFromWeaponAttachmentUniqueConverter converter(fullDef.get(), attachment_unique_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -131,24 +131,24 @@ namespace namespace attachment_unique { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON_ATTACHMENT_UNIQUE, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.h b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.h index b3e2ae1a..65da39bc 100644 --- a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.h +++ b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace attachment_unique { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace attachment_unique diff --git a/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.cpp index 4a68492e..e7fda73e 100644 --- a/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.cpp @@ -104,20 +104,20 @@ namespace namespace camo { - bool JsonDumperT6::ShouldDump(XAssetInfo* asset) + JsonDumperT6::JsonDumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void JsonDumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void JsonDumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto fileName = GetJsonFileNameForAssetName(asset->m_name); + const auto fileName = GetJsonFileNameForAssetName(asset.m_name); const auto assetFile = context.OpenAssetFile(fileName); if (!assetFile) return; const JsonDumperImpl dumper(*assetFile); - dumper.Dump(asset->Asset()); + dumper.Dump(asset.Asset()); } } // namespace camo diff --git a/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.h b/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.h index 8bb91f12..7bf2d45b 100644 --- a/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.h +++ b/src/ObjWriting/Game/T6/Weapon/CamoJsonDumperT6.h @@ -5,10 +5,12 @@ namespace camo { - class JsonDumperT6 final : public AbstractAssetDumper + class JsonDumperT6 final : public AbstractAssetDumper { + public: + explicit JsonDumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace camo diff --git a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp index 96c5bcdc..4c7c991d 100644 --- a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp @@ -409,31 +409,31 @@ namespace } } - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { const auto fullDef = std::make_unique(); memset(fullDef.get(), 0, sizeof(WeaponFullDef)); - CopyToFullDef(asset->Asset(), fullDef.get()); + CopyToFullDef(asset.Asset(), fullDef.get()); InfoStringFromWeaponConverter converter(fullDef.get(), weapon_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); } - void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); - const auto weapon = asset->Asset(); + const auto weapon = asset.Asset(); const auto* weapDef = weapon->weapDef; if (!weapDef) @@ -461,24 +461,24 @@ namespace namespace weapon { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_WEAPON); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.h b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.h index 4b3b500f..18fddd9d 100644 --- a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.h +++ b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.h @@ -5,10 +5,12 @@ namespace weapon { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace weapon diff --git a/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.cpp b/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.cpp index 1a7edb80..f9e56c21 100644 --- a/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.cpp +++ b/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.cpp @@ -30,18 +30,18 @@ namespace } }; - InfoString CreateInfoString(XAssetInfo* asset) + InfoString CreateInfoString(const XAssetInfo& asset) { - InfoStringFromZBarrierConverter converter(asset->Asset(), + InfoStringFromZBarrierConverter converter(asset.Asset(), zbarrier_fields, std::extent_v, [asset](const scr_string_t scrStr) -> std::string { - assert(scrStr < asset->m_zone->m_script_strings.Count()); - if (scrStr >= asset->m_zone->m_script_strings.Count()) + assert(scrStr < asset.m_zone->m_script_strings.Count()); + if (scrStr >= asset.m_zone->m_script_strings.Count()) return ""; - return asset->m_zone->m_script_strings[scrStr]; + return asset.m_zone->m_script_strings[scrStr]; }); return converter.Convert(); @@ -50,24 +50,24 @@ namespace namespace z_barrier { - bool DumperT6::ShouldDump(XAssetInfo* asset) + DumperT6::DumperT6(const AssetPool& pool) + : AbstractAssetDumper(pool) { - return true; } - void DumperT6::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { // Only dump raw when no gdt available if (context.m_gdt) { const auto infoString = CreateInfoString(asset); - GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_ZBARRIER); + GdtEntry gdtEntry(asset.m_name, ObjConstants::GDF_FILENAME_ZBARRIER); infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_ZBARRIER, gdtEntry); context.m_gdt->WriteEntry(gdtEntry); } else { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; diff --git a/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.h b/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.h index 9e60f414..a16c3705 100644 --- a/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.h +++ b/src/ObjWriting/Game/T6/ZBarrier/ZBarrierDumperT6.h @@ -2,14 +2,15 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -#include "InfoString/InfoString.h" namespace z_barrier { - class DumperT6 final : public AbstractAssetDumper + class DumperT6 final : public AbstractAssetDumper { + public: + explicit DumperT6(const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace z_barrier diff --git a/src/ObjWriting/Material/MaterialJsonDumper.cpp.template b/src/ObjWriting/Material/MaterialJsonDumper.cpp.template index 7eb8ad51..c62ddc9f 100644 --- a/src/ObjWriting/Material/MaterialJsonDumper.cpp.template +++ b/src/ObjWriting/Material/MaterialJsonDumper.cpp.template @@ -361,27 +361,27 @@ namespace namespace material { - void CLASS_NAME::DumpPool(AssetDumpingContext& context, AssetPool* pool) + CLASS_NAME::CLASS_NAME (const AssetPool& pool) + : AbstractAssetDumper(pool) + { + } + + void CLASS_NAME::Dump(AssetDumpingContext& context) { auto* materialConstantState = context.GetZoneAssetDumperState(); materialConstantState->ExtractNamesFromZone(); - AbstractAssetDumper::DumpPool(context, pool); + AbstractAssetDumper::Dump(context); } - bool CLASS_NAME::ShouldDump(XAssetInfo* asset) + void CLASS_NAME::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { - return true; - } - - void CLASS_NAME::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) - { - const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name)); if (!assetFile) return; - const auto* material = asset->Asset(); + const auto* material = asset.Asset(); #if defined(FEATURE_T5) assert(material->info.gameFlags < 0x400); assert(material->maxStreamedMips == 0); diff --git a/src/ObjWriting/Material/MaterialJsonDumper.h.template b/src/ObjWriting/Material/MaterialJsonDumper.h.template index f8a41515..c58bd3f4 100644 --- a/src/ObjWriting/Material/MaterialJsonDumper.h.template +++ b/src/ObjWriting/Material/MaterialJsonDumper.h.template @@ -17,13 +17,13 @@ namespace material { - class CLASS_NAME final : public AbstractAssetDumper + class CLASS_NAME final : public AbstractAssetDumper { public: - void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + explicit CLASS_NAME (const AssetPool& pool); + void Dump(AssetDumpingContext& context) override; protected: - [[nodiscard]] bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace material diff --git a/src/ObjWriting/XModel/XModelDumper.cpp.template b/src/ObjWriting/XModel/XModelDumper.cpp.template index 4a569a56..c3bb23c8 100644 --- a/src/ObjWriting/XModel/XModelDumper.cpp.template +++ b/src/ObjWriting/XModel/XModelDumper.cpp.template @@ -560,9 +560,9 @@ namespace } } - void DumpObjMtl(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo* asset) + void DumpObjMtl(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); const auto mtlFile = context.OpenAssetFile(std::format("model_export/{}.mtl", model->name)); if (!mtlFile) @@ -575,9 +575,9 @@ namespace writer->Write(common); } - void DumpObjLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo* asset, const unsigned lod) + void DumpObjLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo& asset, const unsigned lod) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForLod(model->name, lod, ".obj")); if (!assetFile) @@ -591,9 +591,9 @@ namespace writer->Write(common); } - void DumpXModelExportLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo* asset, const unsigned lod) + void DumpXModelExportLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo& asset, const unsigned lod) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForLod(model->name, lod, ".xmodel_export")); if (!assetFile) @@ -604,9 +604,9 @@ namespace writer->Write(common); } - void DumpXModelBinLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo* asset, const unsigned lod) + void DumpXModelBinLod(const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo& asset, const unsigned lod) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForLod(model->name, lod, ".xmodel_bin")); if (!assetFile) @@ -619,9 +619,9 @@ namespace template void DumpGltfLod( - const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo* asset, const unsigned lod, const std::string& extension) + const XModelCommon& common, const AssetDumpingContext& context, const XAssetInfo& asset, const unsigned lod, const std::string& extension) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForLod(model->name, lod, extension)); if (!assetFile) @@ -634,14 +634,14 @@ namespace writer->Write(common); } - void DumpXModelSurfs(const AssetDumpingContext& context, const XAssetInfo* asset) + void DumpXModelSurfs(const AssetDumpingContext& context, const XAssetInfo& asset) { - const auto* model = asset->Asset(); + const auto* model = asset.Asset(); for (auto currentLod = 0u; currentLod < model->numLods; currentLod++) { XModelCommon common; - PopulateXModelWriter(common, context, currentLod, asset->Asset()); + PopulateXModelWriter(common, context, currentLod, asset.Asset()); switch (ObjWriting::Configuration.ModelOutputFormat) { @@ -841,25 +841,25 @@ namespace std::ostream& m_stream; }; - void DumpXModelJson(AssetDumpingContext& context, XAssetInfo* asset) + void DumpXModelJson(AssetDumpingContext& context, const XAssetInfo& asset) { - const auto assetFile = context.OpenAssetFile(xmodel::GetJsonFileNameForAssetName(asset->m_name)); + const auto assetFile = context.OpenAssetFile(xmodel::GetJsonFileNameForAssetName(asset.m_name)); if (!assetFile) return; const JsonDumper dumper(context, *assetFile); - dumper.Dump(asset->Asset()); + dumper.Dump(asset.Asset()); } } // namespace namespace xmodel { - bool CLASS_NAME::ShouldDump(XAssetInfo* asset) + CLASS_NAME::CLASS_NAME (const AssetPool& pool) + : AbstractAssetDumper(pool) { - return !asset->m_name.empty() && asset->m_name[0] != ','; } - void CLASS_NAME::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + void CLASS_NAME::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) { DumpXModelJson(context, asset); DumpXModelSurfs(context, asset); diff --git a/src/ObjWriting/XModel/XModelDumper.h.template b/src/ObjWriting/XModel/XModelDumper.h.template index 5483e209..8dce3422 100644 --- a/src/ObjWriting/XModel/XModelDumper.h.template +++ b/src/ObjWriting/XModel/XModelDumper.h.template @@ -17,10 +17,12 @@ namespace xmodel { - class CLASS_NAME final : public AbstractAssetDumper + class CLASS_NAME final : public AbstractAssetDumper { + public: + explicit CLASS_NAME (const AssetPool& pool); + protected: - bool ShouldDump(XAssetInfo* asset) override; - void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; }; } // namespace xmodel diff --git a/src/Unlinker/Unlinker.cpp b/src/Unlinker/Unlinker.cpp index 1503d215..e1f6ee76 100644 --- a/src/Unlinker/Unlinker.cpp +++ b/src/Unlinker/Unlinker.cpp @@ -176,7 +176,7 @@ private: return false; OutputPathFilesystem outputFolderOutputPath(outputFolderPath); - AssetDumpingContext context(zone, outputFolderPathStr, outputFolderOutputPath, searchPath); + AssetDumpingContext context(zone, outputFolderPathStr, outputFolderOutputPath, searchPath, std::nullopt); std::ofstream gdtStream; if (m_args.m_use_gdt) @@ -227,7 +227,7 @@ private: auto absoluteZoneDirectory = absolute(std::filesystem::path(zonePath).remove_filename()).string(); auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory); - auto maybeZone = ZoneLoading::LoadZone(zonePath); + auto maybeZone = ZoneLoading::LoadZone(zonePath, std::nullopt); if (!maybeZone) { con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error()); @@ -289,7 +289,7 @@ private: auto searchPathsForZone = paths.GetSearchPathsForZone(absoluteZoneDirectory); - auto maybeZone = ZoneLoading::LoadZone(zonePath); + auto maybeZone = ZoneLoading::LoadZone(zonePath, std::nullopt); if (!maybeZone) { con::error("Failed to load zone \"{}\": {}", zonePath, maybeZone.error()); diff --git a/src/ZoneCommon/Pool/AssetPool.h b/src/ZoneCommon/Pool/AssetPool.h index 7b4794a2..f22c71cd 100644 --- a/src/ZoneCommon/Pool/AssetPool.h +++ b/src/ZoneCommon/Pool/AssetPool.h @@ -41,6 +41,32 @@ public: } }; + class CIterator + { + typename std::map*>::const_iterator m_iterator; + + public: + explicit CIterator(typename std::map*>::const_iterator i) + { + m_iterator = i; + } + + bool operator!=(CIterator rhs) + { + return m_iterator != rhs.m_iterator; + } + + const XAssetInfo* operator*() + { + return m_iterator.operator*().second; + } + + void operator++() + { + ++m_iterator; + } + }; + AssetPool() { m_asset_lookup = std::map*>(); @@ -70,4 +96,14 @@ public: { return Iterator(m_asset_lookup.end()); } + + CIterator begin() const + { + return CIterator(m_asset_lookup.cbegin()); + } + + CIterator end() const + { + return CIterator(m_asset_lookup.cend()); + } }; diff --git a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp index 3a387efe..ae0708d5 100644 --- a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp +++ b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.cpp @@ -11,7 +11,6 @@ #include "Loading/Steps/StepAllocXBlocks.h" #include "Loading/Steps/StepLoadZoneContent.h" #include "Loading/Steps/StepLoadZoneSizes.h" -#include "Loading/Steps/StepSkipBytes.h" #include "Utils/ClassUtils.h" #include @@ -22,24 +21,6 @@ using namespace IW3; namespace { - bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) - { - assert(isSecure != nullptr); - assert(isOfficial != nullptr); - - if (header.m_version != ZoneConstants::ZONE_VERSION) - return false; - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) - { - *isSecure = false; - *isOfficial = true; - return true; - } - - return false; - } - void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) @@ -58,13 +39,33 @@ namespace } } // namespace -std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +std::optional ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const { - bool isSecure; - bool isOfficial; + if (header.m_version != ZoneConstants::ZONE_VERSION) + return std::nullopt; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) + { + return ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW3, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = true, + .m_is_signed = false, + .m_is_encrypted = false, + }; + } + + return std::nullopt; +} + +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const +{ + const auto inspectResult = InspectZoneHeader(header); + if (!inspectResult) return nullptr; // Create new zone @@ -93,7 +94,8 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK, - zonePtr->Memory())); + zonePtr->Memory(), + std::move(progressCallback))); return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h index 2e6ba8e6..e5957295 100644 --- a/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h +++ b/src/ZoneLoading/Game/IW3/ZoneLoaderFactoryIW3.h @@ -9,6 +9,9 @@ namespace IW3 class ZoneLoaderFactory final : public IZoneLoaderFactory { public: - std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; + [[nodiscard]] std::optional InspectZoneHeader(const ZoneHeader& header) const override; + [[nodiscard]] std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const override; }; } // namespace IW3 diff --git a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp index 1bfd60d6..3a23cbc9 100644 --- a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp +++ b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.cpp @@ -34,47 +34,75 @@ using namespace IW4; namespace { - bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isIw4x) + struct ZoneLoaderInspectionResultIW4 { - assert(isSecure != nullptr); - assert(isOfficial != nullptr); - assert(isIw4x != nullptr); + ZoneLoaderInspectionResult m_generic_result; + bool m_is_iw4x; + }; + std::optional InspectZoneHeaderIw4(const ZoneHeader& header) + { if (header.m_version != ZoneConstants::ZONE_VERSION) - { - return false; - } + return std::nullopt; if (!memcmp(header.m_magic, ZoneConstants::MAGIC_IW4X, std::char_traits::length(ZoneConstants::MAGIC_IW4X))) { - if (*reinterpret_cast(&header.m_magic[std::char_traits::length(ZoneConstants::MAGIC_IW4X)]) == ZoneConstants::IW4X_ZONE_VERSION) + if (*reinterpret_cast(&header.m_magic[std::char_traits::length(ZoneConstants::MAGIC_IW4X)]) + == ZoneConstants::IW4X_ZONE_VERSION) { - *isSecure = false; - *isOfficial = false; - *isIw4x = true; - return true; + return ZoneLoaderInspectionResultIW4{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW4, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = false, + .m_is_signed = false, + .m_is_encrypted = false, + }, + .m_is_iw4x = true, + }; } - return false; + return std::nullopt; } if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, std::char_traits::length(ZoneConstants::MAGIC_SIGNED_INFINITY_WARD))) { - *isSecure = true; - *isOfficial = true; - *isIw4x = false; - return true; + return ZoneLoaderInspectionResultIW4{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW4, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = true, + .m_is_signed = true, + .m_is_encrypted = false, + }, + .m_is_iw4x = false, + }; } if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) { - *isSecure = false; - *isOfficial = true; - *isIw4x = false; - return true; + return ZoneLoaderInspectionResultIW4{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW4, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = false, + .m_is_signed = false, + .m_is_encrypted = false, + }, + .m_is_iw4x = false, + }; } - return false; + return std::nullopt; } void SetupBlock(ZoneLoader& zoneLoader) @@ -116,14 +144,14 @@ namespace } } - void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader& zoneLoader, std::string& fileName) + void AddAuthHeaderSteps(const ZoneLoaderInspectionResultIW4& inspectResult, ZoneLoader& zoneLoader, const std::string& fileName) { // Unsigned zones do not have an auth header - if (!isSecure) + if (!inspectResult.m_generic_result.m_is_signed) return; // If file is signed setup a RSA instance. - auto rsa = SetupRsa(isOfficial); + auto rsa = SetupRsa(inspectResult.m_generic_result.m_is_official); zoneLoader.AddLoadingStep(step::CreateStepVerifyMagic(ZoneConstants::MAGIC_AUTH_HEADER)); zoneLoader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved @@ -165,14 +193,21 @@ namespace } } // namespace -std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +std::optional ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const { - bool isSecure; - bool isOfficial; - bool isIw4x; + auto resultIw4 = InspectZoneHeaderIw4(header); + if (!resultIw4) + return std::nullopt; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial, &isIw4x)) + return resultIw4->m_generic_result; +} + +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const +{ + const auto inspectResult = InspectZoneHeaderIw4(header); + if (!inspectResult) return nullptr; // Create new zone @@ -193,11 +228,11 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(8)); // Add steps for loading the auth header which also contain the signature of the zone if it is signed. - AddAuthHeaderSteps(isSecure, isOfficial, *zoneLoader, fileName); + AddAuthHeaderSteps(*inspectResult, *zoneLoader, fileName); zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE))); - if (isIw4x) // IW4x has one extra byte of padding here for protection purposes + if (inspectResult->m_is_iw4x) // IW4x has one extra byte of padding here for protection purposes { zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorIW4xDecryption())); zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(1)); @@ -216,7 +251,8 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK, - zonePtr->Memory())); + zonePtr->Memory(), + std::move(progressCallback))); return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h index a840e686..5513c726 100644 --- a/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h +++ b/src/ZoneLoading/Game/IW4/ZoneLoaderFactoryIW4.h @@ -9,6 +9,9 @@ namespace IW4 class ZoneLoaderFactory final : public IZoneLoaderFactory { public: - std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; + [[nodiscard]] std::optional InspectZoneHeader(const ZoneHeader& header) const override; + [[nodiscard]] std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const override; }; } // namespace IW4 diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp index b7e97184..d3d3cbb7 100644 --- a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp @@ -33,33 +33,6 @@ using namespace IW5; namespace { - bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) - { - assert(isSecure != nullptr); - assert(isOfficial != nullptr); - - if (header.m_version != ZoneConstants::ZONE_VERSION) - { - return false; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, std::char_traits::length(ZoneConstants::MAGIC_SIGNED_INFINITY_WARD))) - { - *isSecure = true; - *isOfficial = true; - return true; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) - { - *isSecure = false; - *isOfficial = true; - return true; - } - - return false; - } - void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) @@ -100,14 +73,14 @@ namespace } } - void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader& zoneLoader, std::string& fileName) + void AddAuthHeaderSteps(const ZoneLoaderInspectionResult& inspectResult, ZoneLoader& zoneLoader, const std::string& fileName) { // Unsigned zones do not have an auth header - if (!isSecure) + if (!inspectResult.m_is_signed) return; // If file is signed setup a RSA instance. - auto rsa = SetupRsa(isOfficial); + auto rsa = SetupRsa(inspectResult.m_is_official); zoneLoader.AddLoadingStep(step::CreateStepVerifyMagic(ZoneConstants::MAGIC_AUTH_HEADER)); zoneLoader.AddLoadingStep(step::CreateStepSkipBytes(4)); // Skip reserved @@ -149,13 +122,46 @@ namespace } } // namespace -std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +std::optional ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const { - bool isSecure; - bool isOfficial; + if (header.m_version != ZoneConstants::ZONE_VERSION) + return std::nullopt; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, std::char_traits::length(ZoneConstants::MAGIC_SIGNED_INFINITY_WARD))) + { + return ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW5, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = true, + .m_is_signed = true, + .m_is_encrypted = false, + }; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) + { + return ZoneLoaderInspectionResult{ + .m_game_id = GameId::IW5, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = false, + .m_is_signed = false, + .m_is_encrypted = false, + }; + } + + return std::nullopt; +} + +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const +{ + const auto inspectResult = InspectZoneHeader(header); + if (!inspectResult) return nullptr; // Create new zone @@ -176,7 +182,7 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(8)); // Add steps for loading the auth header which also contain the signature of the zone if it is signed. - AddAuthHeaderSteps(isSecure, isOfficial, *zoneLoader, fileName); + AddAuthHeaderSteps(*inspectResult, *zoneLoader, fileName); zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE))); @@ -193,7 +199,8 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK, - zonePtr->Memory())); + zonePtr->Memory(), + std::move(progressCallback))); return zoneLoader; } diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h index a3a522a1..847272aa 100644 --- a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h @@ -9,6 +9,9 @@ namespace IW5 class ZoneLoaderFactory final : public IZoneLoaderFactory { public: - std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; + [[nodiscard]] std::optional InspectZoneHeader(const ZoneHeader& header) const override; + [[nodiscard]] std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const override; }; } // namespace IW5 diff --git a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp index 34ee2025..861a0d4d 100644 --- a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp +++ b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.cpp @@ -11,7 +11,6 @@ #include "Loading/Steps/StepAllocXBlocks.h" #include "Loading/Steps/StepLoadZoneContent.h" #include "Loading/Steps/StepLoadZoneSizes.h" -#include "Loading/Steps/StepSkipBytes.h" #include "Utils/ClassUtils.h" #include @@ -22,26 +21,6 @@ using namespace T5; namespace { - bool CanLoad(const ZoneHeader& header, bool* isSecure, bool* isOfficial) - { - assert(isSecure != nullptr); - assert(isOfficial != nullptr); - - if (header.m_version != ZoneConstants::ZONE_VERSION) - { - return false; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) - { - *isSecure = false; - *isOfficial = true; - return true; - } - - return false; - } - void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) @@ -58,13 +37,34 @@ namespace } } // namespace -std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +std::optional ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const { - bool isSecure; - bool isOfficial; + if (header.m_version != ZoneConstants::ZONE_VERSION) + return std::nullopt; - // Check if this file is a supported IW4 zone. - if (!CanLoad(header, &isSecure, &isOfficial)) + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) + { + return ZoneLoaderInspectionResult{ + .m_game_id = GameId::T5, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + // There is no way to know whether unsigned zones are official. + .m_is_official = false, + .m_is_signed = false, + .m_is_encrypted = false, + }; + } + + return std::nullopt; +} + +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const +{ + const auto inspectResult = InspectZoneHeader(header); + if (!inspectResult) return nullptr; // Create new zone @@ -93,7 +93,8 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK, - zonePtr->Memory())); + zonePtr->Memory(), + std::move(progressCallback))); return zoneLoader; } diff --git a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h index 12c21ffb..efd298c9 100644 --- a/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h +++ b/src/ZoneLoading/Game/T5/ZoneLoaderFactoryT5.h @@ -9,6 +9,9 @@ namespace T5 class ZoneLoaderFactory final : public IZoneLoaderFactory { public: - std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; + [[nodiscard]] std::optional InspectZoneHeader(const ZoneHeader& header) const override; + [[nodiscard]] std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const override; }; } // namespace T5 diff --git a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp index 813d8602..b4023dc0 100644 --- a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp +++ b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.cpp @@ -24,11 +24,10 @@ #include "Zone/XChunk/XChunkProcessorSalsa20Decryption.h" #include -#include +#include #include #include #include -#include #include using namespace T6; @@ -36,6 +35,130 @@ namespace fs = std::filesystem; namespace { + enum class ZoneCompressionTypeT6 : std::uint8_t + { + DEFLATE, + LZX + }; + + struct ZoneLoaderInspectionResultT6 + { + ZoneLoaderInspectionResult m_generic_result; + ZoneCompressionTypeT6 m_compression_type; + }; + + std::optional InspectZoneHeaderT6(const ZoneHeader& header) + { + if (endianness::FromLittleEndian(header.m_version) == ZoneConstants::ZONE_VERSION_PC) + { + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_TREYARCH, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = true, + .m_is_signed = true, + .m_is_encrypted = true, + }, + .m_compression_type = ZoneCompressionTypeT6::DEFLATE, + }; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_OAT, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = false, + .m_is_signed = true, + .m_is_encrypted = true, + }, + .m_compression_type = ZoneCompressionTypeT6::DEFLATE, + }; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = false, + .m_is_signed = false, + .m_is_encrypted = true, + }, + .m_compression_type = ZoneCompressionTypeT6::DEFLATE, + }; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED_SERVER, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::LE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::PC, + .m_is_official = true, + .m_is_signed = false, + .m_is_encrypted = false, + }, + .m_compression_type = ZoneCompressionTypeT6::DEFLATE, + }; + } + } + else if (endianness::FromBigEndian(header.m_version) == ZoneConstants::ZONE_VERSION_XENON) + { + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_TREYARCH, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::BE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::XBOX, + .m_is_official = true, + .m_is_signed = true, + .m_is_encrypted = true, + }, + .m_compression_type = ZoneCompressionTypeT6::DEFLATE, + }; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_LZX_TREYARCH, 8)) + { + return ZoneLoaderInspectionResultT6{ + .m_generic_result = + ZoneLoaderInspectionResult{ + .m_game_id = GameId::T6, + .m_endianness = GameEndianness::BE, + .m_word_size = GameWordSize::ARCH_32, + .m_platform = GamePlatform::XBOX, + .m_is_official = true, + .m_is_signed = true, + .m_is_encrypted = true, + }, + .m_compression_type = ZoneCompressionTypeT6::LZX, + }; + } + } + + return std::nullopt; + } + GameLanguage GetZoneLanguage(const std::string& zoneName) { const auto& languagePrefixes = IGame::GetGameById(GameId::T6)->GetLanguagePrefixes(); @@ -51,68 +174,6 @@ namespace return GameLanguage::LANGUAGE_NONE; } - bool CanLoad(const ZoneHeader& header, bool& isBigEndian, bool& isSecure, bool& isOfficial, bool& isEncrypted, bool& isLzxCompressed) - { - if (endianness::FromLittleEndian(header.m_version) == ZoneConstants::ZONE_VERSION_PC) - { - isBigEndian = false; - isLzxCompressed = false; - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_TREYARCH, 8)) - { - isSecure = true; - isOfficial = true; - isEncrypted = true; - return true; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_OAT, 8)) - { - isSecure = true; - isOfficial = false; - isEncrypted = true; - return true; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, 8)) - { - isSecure = false; - isOfficial = true; - isEncrypted = true; - return true; - } - - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED_SERVER, 8)) - { - isSecure = false; - isOfficial = true; - isEncrypted = false; - return true; - } - } - else if (endianness::FromBigEndian(header.m_version) == ZoneConstants::ZONE_VERSION_XENON) - { - isBigEndian = true; - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_TREYARCH, 8)) - { - isSecure = true; - isOfficial = true; - isEncrypted = true; - isLzxCompressed = false; - return true; - } - if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_LZX_TREYARCH, 8)) - { - isSecure = true; - isOfficial = true; - isEncrypted = true; - isLzxCompressed = true; - return true; - } - } - - return false; - } - void SetupBlock(ZoneLoader& zoneLoader) { #define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) @@ -169,26 +230,16 @@ namespace return signatureLoadStepPtr; } - ICapturedDataProvider* - AddXChunkProcessor(const bool isBigEndian, const bool isEncrypted, const bool isLzxCompressed, ZoneLoader& zoneLoader, std::string& fileName) + ICapturedDataProvider* AddXChunkProcessor(const ZoneLoaderInspectionResultT6& inspectResult, ZoneLoader& zoneLoader, const std::string& fileName) { ICapturedDataProvider* result = nullptr; - std::unique_ptr xChunkProcessor; + auto xChunkProcessor = processor::CreateProcessorXChunks( + ZoneConstants::STREAM_COUNT, ZoneConstants::XCHUNK_SIZE, inspectResult.m_generic_result.m_endianness, ZoneConstants::VANILLA_BUFFER_SIZE); - if (isBigEndian) - { - xChunkProcessor = processor::CreateProcessorXChunks( - ZoneConstants::STREAM_COUNT, ZoneConstants::XCHUNK_SIZE, GameEndianness::BE, ZoneConstants::VANILLA_BUFFER_SIZE); - } - else - { - xChunkProcessor = processor::CreateProcessorXChunks( - ZoneConstants::STREAM_COUNT, ZoneConstants::XCHUNK_SIZE, GameEndianness::LE, ZoneConstants::VANILLA_BUFFER_SIZE); - } + const uint8_t (&salsa20Key)[32] = inspectResult.m_generic_result.m_platform == GamePlatform::XBOX ? ZoneConstants::SALSA20_KEY_TREYARCH_XENON + : ZoneConstants::SALSA20_KEY_TREYARCH_PC; - const uint8_t (&salsa20Key)[32] = isBigEndian ? ZoneConstants::SALSA20_KEY_TREYARCH_XENON : ZoneConstants::SALSA20_KEY_TREYARCH_PC; - - if (isEncrypted) + if (inspectResult.m_generic_result.m_is_encrypted) { // If zone is encrypted, the decryption is applied before the decompression. T6 Zones always use Salsa20. auto chunkProcessorSalsa20 = @@ -197,7 +248,7 @@ namespace xChunkProcessor->AddChunkProcessor(std::move(chunkProcessorSalsa20)); } - if (isLzxCompressed) + if (inspectResult.m_compression_type == ZoneCompressionTypeT6::LZX) { // Decompress the chunks using lzx xChunkProcessor->AddChunkProcessor(std::make_unique(ZoneConstants::STREAM_COUNT)); @@ -215,12 +266,21 @@ namespace } } // namespace -std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const +std::optional ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const { - bool isBigEndian, isSecure, isOfficial, isEncrypted, isLzxCompressed; + auto resultT6 = InspectZoneHeaderT6(header); + if (!resultT6) + return std::nullopt; - // Check if this file is a supported T6 zone. - if (!CanLoad(header, isBigEndian, isSecure, isOfficial, isEncrypted, isLzxCompressed)) + return resultT6->m_generic_result; +} + +std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const +{ + const auto inspectResult = InspectZoneHeaderT6(header); + if (!inspectResult) return nullptr; // Create new zone @@ -235,15 +295,15 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& SetupBlock(*zoneLoader); // If file is signed setup a RSA instance. - auto rsa = isSecure ? SetupRsa(isOfficial) : nullptr; + auto rsa = inspectResult->m_generic_result.m_is_signed ? SetupRsa(inspectResult->m_generic_result.m_is_official) : nullptr; // Add steps for loading the auth header which also contain the signature of the zone if it is signed. - ISignatureProvider* signatureProvider = AddAuthHeaderSteps(isSecure, *zoneLoader, fileName); + ISignatureProvider* signatureProvider = AddAuthHeaderSteps(inspectResult->m_generic_result.m_is_signed, *zoneLoader, fileName); // Setup loading XChunks from the zone from this point on. - ICapturedDataProvider* signatureDataProvider = AddXChunkProcessor(isBigEndian, isEncrypted, isLzxCompressed, *zoneLoader, fileName); + ICapturedDataProvider* signatureDataProvider = AddXChunkProcessor(*inspectResult, *zoneLoader, fileName); - if (!isBigEndian) + if (inspectResult->m_generic_result.m_endianness == GameEndianness::LE) { // Start of the XFile struct zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes()); @@ -258,12 +318,11 @@ std::unique_ptr ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK, - zonePtr->Memory())); + zonePtr->Memory(), + std::move(progressCallback))); - if (isSecure) - { + if (inspectResult->m_generic_result.m_is_signed) zoneLoader->AddLoadingStep(step::CreateStepVerifySignature(std::move(rsa), signatureProvider, signatureDataProvider)); - } } else { diff --git a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h index 0890f555..fd396d61 100644 --- a/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h +++ b/src/ZoneLoading/Game/T6/ZoneLoaderFactoryT6.h @@ -9,6 +9,9 @@ namespace T6 class ZoneLoaderFactory final : public IZoneLoaderFactory { public: - std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const override; + [[nodiscard]] std::optional InspectZoneHeader(const ZoneHeader& header) const override; + [[nodiscard]] std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const override; }; } // namespace T6 diff --git a/src/ZoneLoading/Loading/IZoneLoaderFactory.h b/src/ZoneLoading/Loading/IZoneLoaderFactory.h index 46ab7393..3d9f356c 100644 --- a/src/ZoneLoading/Loading/IZoneLoaderFactory.h +++ b/src/ZoneLoading/Loading/IZoneLoaderFactory.h @@ -1,9 +1,30 @@ #pragma once +#include "Game/IGame.h" +#include "Utils/ProgressCallback.h" #include "Zone/ZoneTypes.h" #include "ZoneLoader.h" #include +#include + +struct ZoneLoaderInspectionResult +{ + // The game this zone is created for. + GameId m_game_id; + // Whether the zone is meant for a little-endian or big-endian loader. + GameEndianness m_endianness; + // Whether the zone is meant for a 32bit or 64bit loader. + GameWordSize m_word_size; + // The platform this zone is for. + GamePlatform m_platform; + // Whether this zone is confirmed official. False if not official or unknown. + bool m_is_official; + // Whether this zone contains a signature confirming the identity of the creator. + bool m_is_signed; + // Whether this zone is encrypted. + bool m_is_encrypted; +}; class IZoneLoaderFactory { @@ -15,7 +36,10 @@ public: IZoneLoaderFactory& operator=(const IZoneLoaderFactory& other) = default; IZoneLoaderFactory& operator=(IZoneLoaderFactory&& other) noexcept = default; - virtual std::unique_ptr CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) const = 0; + [[nodiscard]] virtual std::optional InspectZoneHeader(const ZoneHeader& header) const = 0; + [[nodiscard]] virtual std::unique_ptr CreateLoaderForHeader(const ZoneHeader& header, + const std::string& fileName, + std::optional> progressCallback) const = 0; static const IZoneLoaderFactory* GetZoneLoaderFactoryForGame(GameId game); }; diff --git a/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp b/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp index 80cb3591..b4cbfb82 100644 --- a/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp +++ b/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.cpp @@ -11,19 +11,21 @@ namespace const unsigned pointerBitCount, const unsigned offsetBlockBitCount, const block_t insertBlock, - MemoryManager& memory) + MemoryManager& memory, + std::optional> progressCallback) : m_entry_point_factory(std::move(entryPointFactory)), m_pointer_bit_count(pointerBitCount), m_offset_block_bit_count(offsetBlockBitCount), m_insert_block(insertBlock), - m_memory(memory) + m_memory(memory), + m_progress_callback(std::move(progressCallback)) { } void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override { - const auto inputStream = - ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory); + const auto inputStream = ZoneInputStream::Create( + m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory, std::move(m_progress_callback)); const auto entryPoint = m_entry_point_factory(*inputStream); assert(entryPoint); @@ -37,6 +39,7 @@ namespace unsigned m_offset_block_bit_count; block_t m_insert_block; MemoryManager& m_memory; + std::optional> m_progress_callback; }; } // namespace @@ -46,8 +49,10 @@ namespace step const unsigned pointerBitCount, const unsigned offsetBlockBitCount, const block_t insertBlock, - MemoryManager& memory) + MemoryManager& memory, + std::optional> progressCallback) { - return std::make_unique(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory); + return std::make_unique( + std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory, std::move(progressCallback)); } } // namespace step diff --git a/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h b/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h index 621fa2a2..f832f1dd 100644 --- a/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h +++ b/src/ZoneLoading/Loading/Steps/StepLoadZoneContent.h @@ -13,5 +13,6 @@ namespace step unsigned pointerBitCount, unsigned offsetBlockBitCount, block_t insertBlock, - MemoryManager& memory); + MemoryManager& memory, + std::optional> progressCallback); } diff --git a/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp b/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp index 296060fc..f6722962 100644 --- a/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp +++ b/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp @@ -50,7 +50,8 @@ namespace std::vector& blocks, const block_t insertBlock, ILoadingStream& stream, - MemoryManager& memory) + MemoryManager& memory, + std::optional> progressCallback) : m_blocks(blocks), m_stream(stream), m_memory(memory), @@ -58,7 +59,10 @@ namespace m_block_mask((std::numeric_limits::max() >> (sizeof(uintptr_t) * 8 - blockBitCount)) << (pointerBitCount - blockBitCount)), m_block_shift(pointerBitCount - blockBitCount), m_offset_mask(std::numeric_limits::max() >> (sizeof(uintptr_t) * 8 - (pointerBitCount - blockBitCount))), - m_last_fill_size(0) + m_last_fill_size(0), + m_has_progress_callback(false), + m_progress_current_size(0uz), + m_progress_total_size(0uz) { assert(pointerBitCount % 8u == 0u); assert(insertBlock < static_cast(blocks.size())); @@ -68,6 +72,13 @@ namespace std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount); m_insert_block = blocks[insertBlock]; + + if (progressCallback) + { + m_has_progress_callback = true; + m_progress_callback = *std::move(progressCallback); + m_progress_total_size = CalculateTotalSize(); + } } [[nodiscard]] unsigned GetPointerBitCount() const override @@ -444,6 +455,13 @@ namespace void IncBlockPos(const XBlock& block, const size_t size) { m_block_offsets[block.m_index] += size; + + // We cannot know the full size of the temp block + if (m_has_progress_callback && block.m_type != XBlockType::BLOCK_TYPE_TEMP) + { + m_progress_current_size += size; + m_progress_callback->OnProgress(m_progress_current_size, m_progress_total_size); + } } void Align(const XBlock& block, const unsigned align) @@ -455,6 +473,20 @@ namespace } } + [[nodiscard]] size_t CalculateTotalSize() const + { + size_t result = 0uz; + + for (const auto& block : m_blocks) + { + // We cannot know the full size of the temp block + if (block->m_type != XBlockType::BLOCK_TYPE_TEMP) + result += block->m_buffer_size; + } + + return result; + } + std::vector& m_blocks; std::unique_ptr m_block_offsets; @@ -475,6 +507,11 @@ namespace // These lookups map a block offset to a pointer in case of a platform mismatch std::unordered_map m_pointer_redirect_lookup; std::unordered_map m_alias_redirect_lookup; + + bool m_has_progress_callback; + std::unique_ptr m_progress_callback; + size_t m_progress_current_size; + size_t m_progress_total_size; }; } // namespace @@ -483,7 +520,8 @@ std::unique_ptr ZoneInputStream::Create(const unsigned pointerB std::vector& blocks, const block_t insertBlock, ILoadingStream& stream, - MemoryManager& memory) + MemoryManager& memory, + std::optional> progressCallback) { - return std::make_unique(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory); + return std::make_unique(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory, std::move(progressCallback)); } diff --git a/src/ZoneLoading/Zone/Stream/ZoneInputStream.h b/src/ZoneLoading/Zone/Stream/ZoneInputStream.h index f86c2e4c..2007d7fd 100644 --- a/src/ZoneLoading/Zone/Stream/ZoneInputStream.h +++ b/src/ZoneLoading/Zone/Stream/ZoneInputStream.h @@ -3,6 +3,7 @@ #include "Loading/Exception/InvalidLookupPositionException.h" #include "Loading/ILoadingStream.h" #include "Utils/MemoryManager.h" +#include "Utils/ProgressCallback.h" #include "Zone/Stream/IZoneStream.h" #include "Zone/XBlock.h" @@ -10,6 +11,7 @@ #include #include #include +#include #include #include @@ -238,6 +240,11 @@ public: virtual void DebugOffsets(size_t assetIndex) const = 0; #endif - static std::unique_ptr Create( - unsigned pointerBitCount, unsigned blockBitCount, std::vector& blocks, block_t insertBlock, ILoadingStream& stream, MemoryManager& memory); + static std::unique_ptr Create(unsigned pointerBitCount, + unsigned blockBitCount, + std::vector& blocks, + block_t insertBlock, + ILoadingStream& stream, + MemoryManager& memory, + std::optional> progressCallback); }; diff --git a/src/ZoneLoading/ZoneLoading.cpp b/src/ZoneLoading/ZoneLoading.cpp index 36e2a2ed..e7d4962b 100644 --- a/src/ZoneLoading/ZoneLoading.cpp +++ b/src/ZoneLoading/ZoneLoading.cpp @@ -7,11 +7,11 @@ #include #include #include -#include namespace fs = std::filesystem; -result::Expected, std::string> ZoneLoading::LoadZone(const std::string& path) +result::Expected, std::string> ZoneLoading::LoadZone(const std::string& path, + std::optional> progressCallback) { auto zoneName = fs::path(path).filename().replace_extension().string(); std::ifstream file(path, std::fstream::in | std::fstream::binary); @@ -28,10 +28,11 @@ result::Expected, std::string> ZoneLoading::LoadZone(const for (auto game = 0u; game < static_cast(GameId::COUNT); game++) { const auto* factory = IZoneLoaderFactory::GetZoneLoaderFactoryForGame(static_cast(game)); - zoneLoader = factory->CreateLoaderForHeader(header, zoneName); - - if (zoneLoader) + if (factory->InspectZoneHeader(header)) + { + zoneLoader = factory->CreateLoaderForHeader(header, zoneName, std::move(progressCallback)); break; + } } if (!zoneLoader) diff --git a/src/ZoneLoading/ZoneLoading.h b/src/ZoneLoading/ZoneLoading.h index 330b3421..3c86ac8e 100644 --- a/src/ZoneLoading/ZoneLoading.h +++ b/src/ZoneLoading/ZoneLoading.h @@ -1,5 +1,6 @@ #pragma once +#include "Utils/ProgressCallback.h" #include "Utils/Result.h" #include "Zone/Zone.h" @@ -8,5 +9,6 @@ class ZoneLoading { public: - static result::Expected, std::string> LoadZone(const std::string& path); + static result::Expected, std::string> LoadZone(const std::string& path, + std::optional> progressCallback); }; diff --git a/test/ObjWritingTests/Game/IW3/Material/MaterialJsonDumperIW3Test.cpp b/test/ObjWritingTests/Game/IW3/Material/MaterialJsonDumperIW3Test.cpp index 66b71dd6..fda33fe2 100644 --- a/test/ObjWritingTests/Game/IW3/Material/MaterialJsonDumperIW3Test.cpp +++ b/test/ObjWritingTests/Game/IW3/Material/MaterialJsonDumperIW3Test.cpp @@ -556,14 +556,14 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic materialPool(0); GivenMaterial("wc/ch_plasterwall_long", materialPool, memory); - material::JsonDumperIW3 dumper; - dumper.DumpPool(context, &materialPool); + material::JsonDumperIW3 dumper(materialPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("materials/wc/ch_plasterwall_long.json"); REQUIRE(file); diff --git a/test/ObjWritingTests/Game/IW4/Material/MaterialJsonDumperIW4Test.cpp b/test/ObjWritingTests/Game/IW4/Material/MaterialJsonDumperIW4Test.cpp index ea108592..adbbc517 100644 --- a/test/ObjWritingTests/Game/IW4/Material/MaterialJsonDumperIW4Test.cpp +++ b/test/ObjWritingTests/Game/IW4/Material/MaterialJsonDumperIW4Test.cpp @@ -537,14 +537,14 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic materialPool(0); GivenMaterial("mc/ch_rubble01", materialPool, memory); - material::JsonDumperIW4 dumper; - dumper.DumpPool(context, &materialPool); + material::JsonDumperIW4 dumper(materialPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("materials/mc/ch_rubble01.json"); REQUIRE(file); diff --git a/test/ObjWritingTests/Game/IW5/Material/MaterialJsonDumperIW5Test.cpp b/test/ObjWritingTests/Game/IW5/Material/MaterialJsonDumperIW5Test.cpp index 941c961d..9c003335 100644 --- a/test/ObjWritingTests/Game/IW5/Material/MaterialJsonDumperIW5Test.cpp +++ b/test/ObjWritingTests/Game/IW5/Material/MaterialJsonDumperIW5Test.cpp @@ -590,14 +590,14 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic materialPool(0); GivenMaterial("wc/me_metal_rust_02", materialPool, memory); - material::JsonDumperIW5 dumper; - dumper.DumpPool(context, &materialPool); + material::JsonDumperIW5 dumper(materialPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("materials/wc/me_metal_rust_02.json"); REQUIRE(file); diff --git a/test/ObjWritingTests/Game/T5/Material/MaterialJsonDumperT5Test.cpp b/test/ObjWritingTests/Game/T5/Material/MaterialJsonDumperT5Test.cpp index 704ea0d5..0036b78e 100644 --- a/test/ObjWritingTests/Game/T5/Material/MaterialJsonDumperT5Test.cpp +++ b/test/ObjWritingTests/Game/T5/Material/MaterialJsonDumperT5Test.cpp @@ -619,14 +619,14 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic materialPool(0); GivenMaterial("mc/ch_rubble01", materialPool, memory); - material::JsonDumperT5 dumper; - dumper.DumpPool(context, &materialPool); + material::JsonDumperT5 dumper(materialPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("materials/mc/ch_rubble01.json"); REQUIRE(file); diff --git a/test/ObjWritingTests/Game/T6/FontIcon/FontIconJsonDumperT6Test.cpp b/test/ObjWritingTests/Game/T6/FontIcon/FontIconJsonDumperT6Test.cpp index eaeb798d..91b6b1f3 100644 --- a/test/ObjWritingTests/Game/T6/FontIcon/FontIconJsonDumperT6Test.cpp +++ b/test/ObjWritingTests/Game/T6/FontIcon/FontIconJsonDumperT6Test.cpp @@ -146,13 +146,13 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic fontIconPool(0); GivenFontIcon("fonticon/test.csv", fontIconPool, memory); - font_icon::JsonDumperT6 dumper; - dumper.DumpPool(context, &fontIconPool); + font_icon::JsonDumperT6 dumper(fontIconPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("fonticon/test.json"); REQUIRE(file); diff --git a/test/ObjWritingTests/Game/T6/Material/MaterialJsonDumperT6Test.cpp b/test/ObjWritingTests/Game/T6/Material/MaterialJsonDumperT6Test.cpp index f7b70376..bfefddb1 100644 --- a/test/ObjWritingTests/Game/T6/Material/MaterialJsonDumperT6Test.cpp +++ b/test/ObjWritingTests/Game/T6/Material/MaterialJsonDumperT6Test.cpp @@ -467,13 +467,13 @@ namespace MemoryManager memory; MockSearchPath mockObjPath; MockOutputPath mockOutput; - AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt); AssetPoolDynamic materialPool(0); GivenMaterial("wpc/metal_ac_duct", materialPool, memory); - material::JsonDumperT6 dumper; - dumper.DumpPool(context, &materialPool); + material::JsonDumperT6 dumper(materialPool); + dumper.Dump(context); const auto* file = mockOutput.GetMockedFile("materials/wpc/metal_ac_duct.json"); REQUIRE(file);