From c9595794a31219c1ccf48c40afd7de7507b9d441 Mon Sep 17 00:00:00 2001 From: mo Date: Mon, 29 Jun 2026 18:27:16 +0100 Subject: [PATCH] feat: T4 RawFile and MapEnts loading (#870) --- docs/SupportedAssetTypes.md | 6 +-- .../Game/T4/Maps/MapEntsLoaderT4.cpp | 52 +++++++++++++++++++ src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.h | 13 +++++ src/ObjLoading/Game/T4/ObjLoaderT4.cpp | 4 ++ .../Game/T4/RawFile/AssetLoaderRawFileT4.cpp | 51 ++++++++++++++++++ .../Game/T4/RawFile/AssetLoaderRawFileT4.h | 13 +++++ .../Game/T4/Maps/MapEntsDumperT4.cpp | 2 +- 7 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.cpp create mode 100644 src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.h create mode 100644 src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.cpp create mode 100644 src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index 45b1cdb9..f1a8d2a6 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -142,17 +142,17 @@ using `Linker`): | ComWorld | ❌ | ❌ | | | GameWorldSp | ❌ | ❌ | | | GameWorldMp | ❌ | ❌ | | -| MapEnts | ✅ | ❌ | | +| MapEnts | ✅ | ✅ | | | GfxWorld | ❌ | ❌ | | | GfxLightDef | ❌ | ❌ | | | Font_s | ❌ | ❌ | | | MenuList | ❌ | ❌ | | | menuDef_t | ❌ | ❌ | | -| LocalizeEntry | ✅ | ❌ | | +| LocalizeEntry | ✅ | ✅ | | | WeaponDef | ❌ | ❌ | | | FxEffectDef | ❌ | ❌ | | | FxImpactTable | ❌ | ❌ | | -| RawFile | ✅ | ❌ | | +| RawFile | ✅ | ✅ | | | StringTable | ✅ | ❌ | | | PackIndex | ❌ | ❌ | | diff --git a/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.cpp b/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.cpp new file mode 100644 index 00000000..924637cf --- /dev/null +++ b/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.cpp @@ -0,0 +1,52 @@ +#include "MapEntsLoaderT4.h" + +#include "Game/T4/T4.h" +#include "Maps/MapEntsCommon.h" + +using namespace T4; + +namespace +{ + class MapEntsLoader final : public AssetCreator + { + public: + MapEntsLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto file = m_search_path.Open(map_ents::GetEntsFileNameForAssetName(assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* mapEnts = m_memory.Alloc(); + mapEnts->name = m_memory.Dup(assetName.c_str()); + mapEnts->numEntityChars = static_cast(file.m_length + 1); + + auto* fileBuffer = m_memory.Alloc(static_cast(file.m_length + 1)); + file.m_stream->read(fileBuffer, file.m_length); + if (file.m_stream->gcount() != file.m_length) + return AssetCreationResult::Failure(); + fileBuffer[static_cast(file.m_length)] = '\0'; + + mapEnts->entityString = fileBuffer; + + return AssetCreationResult::Success(context.AddAsset(assetName, mapEnts)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace map_ents +{ + std::unique_ptr> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace map_ents diff --git a/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.h b/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.h new file mode 100644 index 00000000..530ddd44 --- /dev/null +++ b/src/ObjLoading/Game/T4/Maps/MapEntsLoaderT4.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T4/T4.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace map_ents +{ + std::unique_ptr> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath); +} // namespace map_ents diff --git a/src/ObjLoading/Game/T4/ObjLoaderT4.cpp b/src/ObjLoading/Game/T4/ObjLoaderT4.cpp index 080fdf68..9c52ddf8 100644 --- a/src/ObjLoading/Game/T4/ObjLoaderT4.cpp +++ b/src/ObjLoading/Game/T4/ObjLoaderT4.cpp @@ -5,6 +5,8 @@ #include "Game/T4/T4.h" #include "Game/T4/XAnim/XAnimLoaderT4.h" #include "Localize/AssetLoaderLocalizeT4.h" +#include "Maps/MapEntsLoaderT4.h" +#include "RawFile/AssetLoaderRawFileT4.h" using namespace T4; @@ -88,6 +90,8 @@ namespace collection.AddAssetCreator(xanim::CreateLoaderT4(memory, searchPath, zone)); collection.AddAssetCreator(localize::CreateLoaderT4(memory, searchPath, zone)); + collection.AddAssetCreator(map_ents::CreateLoaderT4(memory, searchPath)); + collection.AddAssetCreator(raw_file::CreateLoaderT4(memory, searchPath)); } } // namespace diff --git a/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.cpp b/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.cpp new file mode 100644 index 00000000..5a612453 --- /dev/null +++ b/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.cpp @@ -0,0 +1,51 @@ +#include "AssetLoaderRawFileT4.h" + +#include "Game/T4/T4.h" + +using namespace T4; + +namespace +{ + class RawFileLoader final : public AssetCreator + { + public: + RawFileLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto file = m_search_path.Open(assetName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* rawFile = m_memory.Alloc(); + rawFile->name = m_memory.Dup(assetName.c_str()); + rawFile->len = static_cast(file.m_length); + + auto* fileBuffer = m_memory.Alloc(static_cast(file.m_length + 1)); + file.m_stream->read(fileBuffer, file.m_length); + if (file.m_stream->gcount() != file.m_length) + return AssetCreationResult::Failure(); + fileBuffer[rawFile->len] = '\0'; + + rawFile->buffer = fileBuffer; + + return AssetCreationResult::Success(context.AddAsset(assetName, rawFile)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace raw_file +{ + std::unique_ptr> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace raw_file diff --git a/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.h b/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.h new file mode 100644 index 00000000..e47d0557 --- /dev/null +++ b/src/ObjLoading/Game/T4/RawFile/AssetLoaderRawFileT4.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T4/T4.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace raw_file +{ + std::unique_ptr> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath); +} // namespace raw_file diff --git a/src/ObjWriting/Game/T4/Maps/MapEntsDumperT4.cpp b/src/ObjWriting/Game/T4/Maps/MapEntsDumperT4.cpp index 6598eb01..9db55d9e 100644 --- a/src/ObjWriting/Game/T4/Maps/MapEntsDumperT4.cpp +++ b/src/ObjWriting/Game/T4/Maps/MapEntsDumperT4.cpp @@ -15,6 +15,6 @@ namespace map_ents return; auto& stream = *assetFile; - stream.write(mapEnts->entityString, mapEnts->numEntityChars); + stream.write(mapEnts->entityString, std::max(mapEnts->numEntityChars - 1, 0)); } } // namespace map_ents