From a905a6d161d025208c3988ef9918f006497a69a2 Mon Sep 17 00:00:00 2001 From: njohnson Date: Thu, 30 Apr 2026 18:53:56 -0400 Subject: [PATCH 01/19] feat: add iw3 gfxlight dumper and loader --- docs/SupportedAssetTypes.md | 2 +- .../Game/IW3/LightDef/LightDefLoaderIW3.cpp | 77 +++++++++++++++++++ .../Game/IW3/LightDef/LightDefLoaderIW3.h | 13 ++++ src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp | 3 +- .../Game/IW3/LightDef/LightDefDumperIW3.cpp | 25 ++++++ .../Game/IW3/LightDef/LightDefDumperIW3.h | 13 ++++ src/ObjWriting/Game/IW3/ObjWriterIW3.cpp | 3 +- 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp create mode 100644 src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.h create mode 100644 src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp create mode 100644 src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index aa503afb..86ae5e34 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -26,7 +26,7 @@ The following section specify which assets are supported to be dumped to disk (u | GameWorldMp | ❌ | ❌ | | | MapEnts | ✅ | ❌ | | | GfxWorld | ❌ | ❌ | | -| GfxLightDef | ❌ | ❌ | | +| GfxLightDef | ✅ | ✅ | | | Font_s | ❌ | ❌ | | | MenuList | ❌ | ❌ | | | menuDef_t | ❌ | ❌ | | diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp new file mode 100644 index 00000000..3bf24bd4 --- /dev/null +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -0,0 +1,77 @@ +#include "LightDefLoaderIW3.h" + +#include "Game/IW3/IW3.h" +#include "LightDef/LightDefCommon.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace IW3; + +namespace +{ + constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; + + class LoaderLightDef final : public AssetCreator + { + public: + LoaderLightDef(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto filename = light_def::GetFileNameForAsset(assetName); + const auto file = m_search_path.Open(filename); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); + if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) + return AssetCreationResult::Failure(); + + auto* lightDef = m_memory.Alloc(); + lightDef->name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, lightDef); + + std::string imageName(static_cast(imageNameSize), '\0'); + + int8_t samplerState; + int8_t lmapLookupStart; + file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + file.m_stream->read(&imageName[0], static_cast(imageNameSize)); + file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + + auto* imageDependency = context.LoadDependency(imageName); + if (!imageDependency) + { + con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName); + return AssetCreationResult::Failure(); + } + registration.AddDependency(imageDependency); + + lightDef->attenuation.samplerState = samplerState; + lightDef->attenuation.image = imageDependency->Asset(); + lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace light_def +{ + std::unique_ptr> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace light_def diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.h b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.h new file mode 100644 index 00000000..f43da039 --- /dev/null +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW3/IW3.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace light_def +{ + std::unique_ptr> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath); +} // namespace light_def diff --git a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp index f7532754..0289eac4 100644 --- a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp @@ -9,6 +9,7 @@ #include "Game/IW3/Techset/PixelShaderLoaderIW3.h" #include "Game/IW3/Techset/VertexShaderLoaderIW3.h" #include "Game/IW3/XModel/LoaderXModelIW3.h" +#include "LightDef/LightDefLoaderIW3.h" #include "Localize/AssetLoaderLocalizeIW3.h" #include "Material/LoaderMaterialIW3.h" #include "ObjLoading.h" @@ -113,7 +114,7 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(light_def::CreateLoaderIW3(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); diff --git a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp new file mode 100644 index 00000000..4140ec2f --- /dev/null +++ b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp @@ -0,0 +1,25 @@ +#include "LightDefDumperIW3.h" + +#include "LightDef/LightDefCommon.h" + +using namespace IW3; + +namespace light_def +{ + void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + 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; + + auto& stream = *assetFile; + + const auto* imageName = lightDef->attenuation.image->name; + if (imageName[0] == ',') + imageName = &imageName[1]; + + stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + } +} // namespace light_def diff --git a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.h b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.h new file mode 100644 index 00000000..58e05461 --- /dev/null +++ b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW3/IW3.h" + +namespace light_def +{ + class DumperIW3 final : public AbstractAssetDumper + { + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; + }; +} // namespace light_def diff --git a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp index e81c2c37..b1dd5eac 100644 --- a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp +++ b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp @@ -4,6 +4,7 @@ #include "Game/IW3/Techset/TechsetDumperIW3.h" #include "Game/IW3/XModel/XModelDumperIW3.h" #include "Image/ImageDumperIW3.h" +#include "LightDef/LightDefDumperIW3.h" #include "Localize/LocalizeDumperIW3.h" #include "Maps/MapEntsDumperIW3.h" #include "PhysPreset/PhysPresetInfoStringDumperIW3.h" @@ -37,7 +38,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context) // REGISTER_DUMPER(AssetDumperGameWorldMp) RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperGfxWorld) - // REGISTER_DUMPER(AssetDumperGfxLightDef) + RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperFont_s) // REGISTER_DUMPER(AssetDumperMenuList) // REGISTER_DUMPER(AssetDumpermenuDef_t) From 3c15f8ad7e1f937bf7bc1cb946701da56f21b083 Mon Sep 17 00:00:00 2001 From: njohnson Date: Thu, 30 Apr 2026 19:14:53 -0400 Subject: [PATCH 02/19] feat: add iw5 gfxlight dumper and loader --- docs/SupportedAssetTypes.md | 2 +- .../Game/IW5/LightDef/LightDefLoaderIW5.cpp | 103 ++++++++++++++++++ .../Game/IW5/LightDef/LightDefLoaderIW5.h | 13 +++ src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp | 3 +- .../Game/IW5/LightDef/LightDefDumperIW5.cpp | 31 ++++++ .../Game/IW5/LightDef/LightDefDumperIW5.h | 13 +++ src/ObjWriting/Game/IW5/ObjWriterIW5.cpp | 3 +- 7 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.h create mode 100644 src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp create mode 100644 src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index 86ae5e34..0ee0b896 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -103,7 +103,7 @@ The following section specify which assets are supported to be dumped to disk (u | MapEnts | ❌ | ❌ | | | FxWorld | ❌ | ❌ | | | GfxWorld | ❌ | ❌ | | -| GfxLightDef | ❌ | ❌ | | +| GfxLightDef | ✅ | ✅ | | | Font_s | ❌ | ❌ | | | MenuList | ✅ | ✅ | The output is decompiled. The result will not be the same as the input. | | menuDef_t | ✅ | ✅ | See menulist. | diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp new file mode 100644 index 00000000..42f16b04 --- /dev/null +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -0,0 +1,103 @@ +#include "LightDefLoaderIW5.h" + +#include "Game/IW5/IW5.h" +#include "LightDef/LightDefCommon.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace IW5; + +namespace +{ + constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; + + class LoaderLightDef final : public AssetCreator + { + public: + LoaderLightDef(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto filename = light_def::GetFileNameForAsset(assetName); + const auto file = m_search_path.Open(filename); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* lightDef = m_memory.Alloc(); + lightDef->name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, lightDef); + + int8_t attenuationSamplerState; + file.m_stream->read(reinterpret_cast(&attenuationSamplerState), sizeof(int8_t)); + + std::string attenuationName = ""; + unsigned char letter; + file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); + while (letter != '\0') + { + attenuationName += letter; + + file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); + } + + auto* attenuationImageDependency = context.LoadDependency(attenuationName); + if (!attenuationImageDependency) + { + con::error("Could not load GfxLightDef \"{}\" due to missing attenuation image \"{}\"", assetName, attenuationName); + return AssetCreationResult::Failure(); + } + registration.AddDependency(attenuationImageDependency); + + int8_t cucolorisSamplerState; + file.m_stream->read(reinterpret_cast(&cucolorisSamplerState), sizeof(int8_t)); + + std::string cucolorisName = ""; + file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); + while (letter != '\0') + { + cucolorisName += letter; + + file.m_stream->read(reinterpret_cast(&cucolorisName), sizeof(int8_t)); + } + + auto* cucolorisImageDependency = context.LoadDependency(cucolorisName); + if (!cucolorisImageDependency) + { + con::error("Could not load GfxLightDef \"{}\" due to missing cucoloris image \"{}\"", assetName, cucolorisName); + return AssetCreationResult::Failure(); + } + registration.AddDependency(cucolorisImageDependency); + + int8_t lmapLookupStart; + file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + + lightDef->attenuation.samplerState = attenuationSamplerState; + lightDef->attenuation.image = attenuationImageDependency->Asset(); + lightDef->cucoloris.samplerState = cucolorisSamplerState; + lightDef->cucoloris.image = cucolorisImageDependency->Asset(); + lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace light_def +{ + std::unique_ptr> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace light_def diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.h b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.h new file mode 100644 index 00000000..07f0454a --- /dev/null +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/IW5/IW5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace light_def +{ + std::unique_ptr> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath); +} // namespace light_def diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp index a015ee7d..2b5ada65 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp @@ -10,6 +10,7 @@ #include "Game/IW5/Techset/VertexShaderLoaderIW5.h" #include "Game/IW5/XModel/LoaderXModelIW5.h" #include "Leaderboard/LoaderLeaderboardIW5.h" +#include "LightDef/LightDefLoaderIW5.h" #include "Localize/LoaderLocalizeIW5.h" #include "Material/LoaderMaterialIW5.h" #include "Menu/LoaderMenuListIW5.h" @@ -151,7 +152,7 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(light_def::CreateLoaderIW5(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); collection.AddAssetCreator(menu::CreateMenuListLoaderIW5(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); diff --git a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp new file mode 100644 index 00000000..4b0e912f --- /dev/null +++ b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp @@ -0,0 +1,31 @@ +#include "LightDefDumperIW5.h" + +#include "LightDef/LightDefCommon.h" + +using namespace IW5; + +namespace light_def +{ + void DumperIW5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + 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 || lightDef->cucoloris.image == nullptr + || lightDef->cucoloris.image->name == nullptr) + return; + + auto& stream = *assetFile; + + const auto* attenuationImageName = lightDef->attenuation.image->name; + if (attenuationImageName[0] == ',') + attenuationImageName = &attenuationImageName[1]; + + const auto* cucolorisImageName = lightDef->cucoloris.image->name; + if (cucolorisImageName[0] == ',') + cucolorisImageName = &cucolorisImageName[1]; + + stream << lightDef->attenuation.samplerState << attenuationImageName << '\0' << lightDef->cucoloris.samplerState << cucolorisImageName + << static_cast(lightDef->lmapLookupStart); + } +} // namespace light_def diff --git a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.h b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.h new file mode 100644 index 00000000..bf325e76 --- /dev/null +++ b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace light_def +{ + class DumperIW5 final : public AbstractAssetDumper + { + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; + }; +} // namespace light_def diff --git a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp index 92e33973..db308f2f 100644 --- a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp +++ b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp @@ -7,6 +7,7 @@ #include "Game/IW5/XModel/XModelDumperIW5.h" #include "Image/ImageDumperIW5.h" #include "Leaderboard/LeaderboardJsonDumperIW5.h" +#include "LightDef/LightDefDumperIW5.h" #include "Localize/LocalizeDumperIW5.h" #include "Maps/AddonMapEntsDumperIW5.h" #include "Menu/MenuDumperIW5.h" @@ -51,7 +52,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context) // REGISTER_DUMPER(AssetDumperMapEnts) // REGISTER_DUMPER(AssetDumperFxWorld) // REGISTER_DUMPER(AssetDumperGfxWorld) - // REGISTER_DUMPER(AssetDumperGfxLightDef) + RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperFont_s) RegisterAssetDumper(std::make_unique()); RegisterAssetDumper(std::make_unique()); From 5b6a725f781cf9ae1ab1a63ea6a7fe39bdfe0a83 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 14:26:17 +0200 Subject: [PATCH 03/19] feat: add t5 gfxlight dumper and loader --- docs/SupportedAssetTypes.md | 2 +- .../Game/T5/LightDef/LightDefLoaderT5.cpp | 77 +++++++++++++++++++ .../Game/T5/LightDef/LightDefLoaderT5.h | 13 ++++ src/ObjLoading/Game/T5/ObjLoaderT5.cpp | 3 +- .../Game/T5/LightDef/LightDefDumperT5.cpp | 25 ++++++ .../Game/T5/LightDef/LightDefDumperT5.h | 13 ++++ src/ObjWriting/Game/T5/ObjWriterT5.cpp | 3 +- 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp create mode 100644 src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.h create mode 100644 src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp create mode 100644 src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index 0ee0b896..ac186e48 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -142,7 +142,7 @@ The following section specify which assets are supported to be dumped to disk (u | GameWorldMp | ❌ | ❌ | | | MapEnts | ❌ | ❌ | | | GfxWorld | ❌ | ❌ | | -| GfxLightDef | ❌ | ❌ | | +| GfxLightDef | ✅ | ✅ | | | Font_s | ❌ | ❌ | | | MenuList | ❌ | ❌ | | | menuDef_t | ❌ | ❌ | | diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp new file mode 100644 index 00000000..0f484293 --- /dev/null +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp @@ -0,0 +1,77 @@ +#include "LightDefLoaderT5.h" + +#include "Game/T5/T5.h" +#include "LightDef/LightDefCommon.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace T5; + +namespace +{ + constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; + + class LoaderLightDef final : public AssetCreator + { + public: + LoaderLightDef(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto filename = light_def::GetFileNameForAsset(assetName); + const auto file = m_search_path.Open(filename); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); + if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) + return AssetCreationResult::Failure(); + + auto* lightDef = m_memory.Alloc(); + lightDef->name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, lightDef); + + std::string imageName(static_cast(imageNameSize), '\0'); + + int8_t samplerState; + int8_t lmapLookupStart; + file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + file.m_stream->read(&imageName[0], static_cast(imageNameSize)); + file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + + auto* imageDependency = context.LoadDependency(imageName); + if (!imageDependency) + { + con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName); + return AssetCreationResult::Failure(); + } + registration.AddDependency(imageDependency); + + lightDef->attenuation.samplerState = samplerState; + lightDef->attenuation.image = imageDependency->Asset(); + lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace light_def +{ + std::unique_ptr> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace light_def diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.h b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.h new file mode 100644 index 00000000..2583dd21 --- /dev/null +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T5/T5.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace light_def +{ + std::unique_ptr> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath); +} // namespace light_def diff --git a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp index 2c72f5c1..e39247d5 100644 --- a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp @@ -9,6 +9,7 @@ #include "Game/T5/Techset/PixelShaderLoaderT5.h" #include "Game/T5/Techset/VertexShaderLoaderT5.h" #include "Game/T5/XModel/LoaderXModelT5.h" +#include "LightDef/LightDefLoaderT5.h" #include "Localize/LoaderLocalizeT5.h" #include "Material/LoaderMaterialT5.h" #include "ObjLoading.h" @@ -125,7 +126,7 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(light_def::CreateLoaderT5(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); diff --git a/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp new file mode 100644 index 00000000..386a7646 --- /dev/null +++ b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp @@ -0,0 +1,25 @@ +#include "LightDefDumperT5.h" + +#include "LightDef/LightDefCommon.h" + +using namespace T5; + +namespace light_def +{ + void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + 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; + + auto& stream = *assetFile; + + const auto* imageName = lightDef->attenuation.image->name; + if (imageName[0] == ',') + imageName = &imageName[1]; + + stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + } +} // namespace light_def diff --git a/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.h b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.h new file mode 100644 index 00000000..0829d63d --- /dev/null +++ b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T5/T5.h" + +namespace light_def +{ + class DumperT5 final : public AbstractAssetDumper + { + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; + }; +} // namespace light_def diff --git a/src/ObjWriting/Game/T5/ObjWriterT5.cpp b/src/ObjWriting/Game/T5/ObjWriterT5.cpp index 4e23d39d..9250df8a 100644 --- a/src/ObjWriting/Game/T5/ObjWriterT5.cpp +++ b/src/ObjWriting/Game/T5/ObjWriterT5.cpp @@ -4,6 +4,7 @@ #include "Game/T5/Techset/TechsetDumperT5.h" #include "Game/T5/XModel/XModelDumperT5.h" #include "Image/ImageDumperT5.h" +#include "LightDef/LightDefDumperT5.h" #include "Localize/LocalizeDumperT5.h" #include "PhysPreset/PhysPresetInfoStringDumperT5.h" #include "RawFile/RawFileDumperT5.h" @@ -35,7 +36,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context) // 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) + RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperFont, m_font) // REGISTER_DUMPER(AssetDumperMenuList, m_menu_list) // REGISTER_DUMPER(AssetDumperMenuDef, m_menu_def) From 2b3f680d485378e6e1326c0193e51c48fde73a68 Mon Sep 17 00:00:00 2001 From: njohnson Date: Thu, 30 Apr 2026 19:27:49 -0400 Subject: [PATCH 04/19] feat: add t6 gfxlight dumper and loader --- docs/SupportedAssetTypes.md | 2 +- .../Game/T6/LightDef/LightDefLoaderT6.cpp | 77 +++++++++++++++++++ .../Game/T6/LightDef/LightDefLoaderT6.h | 13 ++++ src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 3 +- .../Game/T6/LightDef/LightDefDumperT6.cpp | 25 ++++++ .../Game/T6/LightDef/LightDefDumperT6.h | 13 ++++ src/ObjWriting/Game/T6/ObjWriterT6.cpp | 3 +- 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp create mode 100644 src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.h create mode 100644 src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp create mode 100644 src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.h diff --git a/docs/SupportedAssetTypes.md b/docs/SupportedAssetTypes.md index ac186e48..f2d9e404 100644 --- a/docs/SupportedAssetTypes.md +++ b/docs/SupportedAssetTypes.md @@ -179,7 +179,7 @@ The following section specify which assets are supported to be dumped to disk (u | GameWorldMp | ❌ | ❌ | | | MapEnts | ✅ | ❌ | | | GfxWorld | ❌ | ❌ | | -| GfxLightDef | ❌ | ❌ | | +| GfxLightDef | ✅ | ✅ | | | Font_s | ❌ | ❌ | | | FontIcon | ✅ | ✅ | | | MenuList | ❌ | ❌ | | diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp new file mode 100644 index 00000000..a0a5e0ed --- /dev/null +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp @@ -0,0 +1,77 @@ +#include "LightDefLoaderT6.h" + +#include "Game/T6/T6.h" +#include "LightDef/LightDefCommon.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace T6; + +namespace +{ + constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; + + class LoaderLightDef final : public AssetCreator + { + public: + LoaderLightDef(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto filename = light_def::GetFileNameForAsset(assetName); + const auto file = m_search_path.Open(filename); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); + if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) + return AssetCreationResult::Failure(); + + auto* lightDef = m_memory.Alloc(); + lightDef->name = m_memory.Dup(assetName.c_str()); + + AssetRegistration registration(assetName, lightDef); + + std::string imageName(static_cast(imageNameSize), '\0'); + + int8_t samplerState; + int8_t lmapLookupStart; + file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + file.m_stream->read(&imageName[0], static_cast(imageNameSize)); + file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + + auto* imageDependency = context.LoadDependency(imageName); + if (!imageDependency) + { + con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName); + return AssetCreationResult::Failure(); + } + registration.AddDependency(imageDependency); + + lightDef->attenuation.samplerState = samplerState; + lightDef->attenuation.image = imageDependency->Asset(); + lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace light_def +{ + std::unique_ptr> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace light_def diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.h b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.h new file mode 100644 index 00000000..b4377299 --- /dev/null +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T6/T6.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace light_def +{ + std::unique_ptr> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath); +} // namespace light_def diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 97c9128b..0721c573 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -17,6 +17,7 @@ #include "Image/IwiTypes.h" #include "Image/Texture.h" #include "Leaderboard/JsonLoaderLeaderboardT6.h" +#include "LightDef/LightDefLoaderT6.h" #include "Localize/LocalizeLoaderT6.h" #include "Material/LoaderMaterialT6.h" #include "ObjContainer/IPak/IPak.h" @@ -399,7 +400,7 @@ namespace T6 // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - // collection.AddAssetCreator(std::make_unique(memory)); + collection.AddAssetCreator(light_def::CreateLoaderT6(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); collection.AddAssetCreator(font_icon::CreateCsvLoaderT6(memory, searchPath)); collection.AddAssetCreator(font_icon::CreateJsonLoaderT6(memory, searchPath)); diff --git a/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp new file mode 100644 index 00000000..f748e408 --- /dev/null +++ b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp @@ -0,0 +1,25 @@ +#include "LightDefDumperT6.h" + +#include "LightDef/LightDefCommon.h" + +using namespace T6; + +namespace light_def +{ + void DumperT6::DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) + { + 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; + + auto& stream = *assetFile; + + const auto* imageName = lightDef->attenuation.image->name; + if (imageName[0] == ',') + imageName = &imageName[1]; + + stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + } +} // namespace light_def diff --git a/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.h b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.h new file mode 100644 index 00000000..eddd5289 --- /dev/null +++ b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T6/T6.h" + +namespace light_def +{ + class DumperT6 final : public AbstractAssetDumper + { + protected: + void DumpAsset(AssetDumpingContext& context, const XAssetInfo& asset) override; + }; +} // namespace light_def diff --git a/src/ObjWriting/Game/T6/ObjWriterT6.cpp b/src/ObjWriting/Game/T6/ObjWriterT6.cpp index f4d09da2..aa3cb9b1 100644 --- a/src/ObjWriting/Game/T6/ObjWriterT6.cpp +++ b/src/ObjWriting/Game/T6/ObjWriterT6.cpp @@ -6,6 +6,7 @@ #include "Game/T6/XModel/XModelDumperT6.h" #include "Image/ImageDumperT6.h" #include "Leaderboard/LeaderboardJsonDumperT6.h" +#include "LightDef/LightDefDumperT6.h" #include "Localize/LocalizeDumperT6.h" #include "Maps/MapEntsDumperT6.h" #include "PhysConstraints/PhysConstraintsInfoStringDumperT6.h" @@ -51,7 +52,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context) // REGISTER_DUMPER(AssetDumperGameWorldMp, m_game_world_mp) RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperGfxWorld, m_gfx_world) - // REGISTER_DUMPER(AssetDumperGfxLightDef, m_gfx_light_def) + RegisterAssetDumper(std::make_unique()); // REGISTER_DUMPER(AssetDumperFont, m_font) RegisterAssetDumper(font_icon::CreateDumperT6()); // REGISTER_DUMPER(AssetDumperMenuList, m_menu_list) From e0c1ba172464c551facde95b11c8e8c797a49b1d Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 13:08:08 -0400 Subject: [PATCH 05/19] Remove unused max constant. --- src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index 42f16b04..43908f7e 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -6,14 +6,13 @@ #include #include +#include #include using namespace IW5; namespace { - constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; - class LoaderLightDef final : public AssetCreator { public: From 7d3791a404035ace6d0b66e308ef0783253e5076 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 13:08:55 -0400 Subject: [PATCH 06/19] Change manual CString reader to std::getline builtin. Don't require cucoloris be present. --- .../Game/IW5/LightDef/LightDefLoaderIW5.cpp | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index 43908f7e..1d728e6c 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -37,16 +37,8 @@ namespace int8_t attenuationSamplerState; file.m_stream->read(reinterpret_cast(&attenuationSamplerState), sizeof(int8_t)); - std::string attenuationName = ""; - unsigned char letter; - file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); - while (letter != '\0') - { - attenuationName += letter; - - file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); - } - + std::string attenuationName; + std::getline(*file.m_stream, attenuationName, '\0'); auto* attenuationImageDependency = context.LoadDependency(attenuationName); if (!attenuationImageDependency) { @@ -58,22 +50,17 @@ namespace int8_t cucolorisSamplerState; file.m_stream->read(reinterpret_cast(&cucolorisSamplerState), sizeof(int8_t)); - std::string cucolorisName = ""; - file.m_stream->read(reinterpret_cast(&letter), sizeof(int8_t)); - while (letter != '\0') - { - cucolorisName += letter; - - file.m_stream->read(reinterpret_cast(&cucolorisName), sizeof(int8_t)); - } - + std::string cucolorisName; + std::getline(*file.m_stream, cucolorisName, '\0'); auto* cucolorisImageDependency = context.LoadDependency(cucolorisName); if (!cucolorisImageDependency) { - con::error("Could not load GfxLightDef \"{}\" due to missing cucoloris image \"{}\"", assetName, cucolorisName); - return AssetCreationResult::Failure(); + con::warn("Could not load GfxLightDef \"{}\" due to missing cucoloris image \"{}\"", assetName, cucolorisName); + } + else + { + registration.AddDependency(cucolorisImageDependency); } - registration.AddDependency(cucolorisImageDependency); int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); From 773fee4a03416e8e45848c06c3f8927105d0b50e Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 13:09:13 -0400 Subject: [PATCH 07/19] T5 and T6 set lmapLookupStart to 0. --- src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp | 2 +- src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp index 0f484293..37ee1392 100644 --- a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp @@ -57,7 +57,7 @@ namespace lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); - lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + lightDef->lmapLookupStart = 0; return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp index a0a5e0ed..b57b404f 100644 --- a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp @@ -57,7 +57,7 @@ namespace lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); - lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + lightDef->lmapLookupStart = 0; return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } From 92418daa6d2fef98cd03a4a6012bca45a20c1245 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 13:10:11 -0400 Subject: [PATCH 08/19] Add brackets for if. Do not dump lmapLookupStart. --- src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp index 4140ec2f..6b116ded 100644 --- a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp @@ -12,7 +12,9 @@ namespace light_def const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name)); if (!assetFile || lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { return; + } auto& stream = *assetFile; @@ -20,6 +22,6 @@ namespace light_def if (imageName[0] == ',') imageName = &imageName[1]; - stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + stream << lightDef->attenuation.samplerState << imageName; } } // namespace light_def From 54d4eaffd2cf21506d0d937b0e1be2fa15b6d505 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 13:11:04 -0400 Subject: [PATCH 09/19] Added assert for attenuation image. Do not dump lmapLookupStart. --- .../Game/IW5/LightDef/LightDefDumperIW5.cpp | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp index 4b0e912f..7938a813 100644 --- a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp @@ -2,6 +2,8 @@ #include "LightDef/LightDefCommon.h" +#include + using namespace IW5; namespace light_def @@ -10,22 +12,21 @@ namespace light_def { 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 || lightDef->cucoloris.image == nullptr - || lightDef->cucoloris.image->name == nullptr) - return; - auto& stream = *assetFile; + assert(lightDef->attenuation.image != nullptr); const auto* attenuationImageName = lightDef->attenuation.image->name; - if (attenuationImageName[0] == ',') + if (attenuationImageName && attenuationImageName[0] == ',') attenuationImageName = &attenuationImageName[1]; - const auto* cucolorisImageName = lightDef->cucoloris.image->name; - if (cucolorisImageName[0] == ',') - cucolorisImageName = &cucolorisImageName[1]; + const auto* cucolorisImageName = ""; + if (lightDef->cucoloris.image) + { + cucolorisImageName = lightDef->cucoloris.image->name; + if (cucolorisImageName && cucolorisImageName[0] == ',') + cucolorisImageName = &cucolorisImageName[1]; + } - stream << lightDef->attenuation.samplerState << attenuationImageName << '\0' << lightDef->cucoloris.samplerState << cucolorisImageName - << static_cast(lightDef->lmapLookupStart); + stream << lightDef->attenuation.samplerState << attenuationImageName << '\0' << lightDef->cucoloris.samplerState << cucolorisImageName; } } // namespace light_def From 531b4811ca38f2a4d39c26c901b7210b08252810 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 15:28:47 -0400 Subject: [PATCH 10/19] Fill in lookup start. --- src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp | 3 +++ src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp | 3 +++ src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 3bf24bd4..0e9240ea 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -2,6 +2,7 @@ #include "Game/IW3/IW3.h" #include "LightDef/LightDefCommon.h" +#include "Game/IW3/LightDef/LightDefAssetCreationStateIW3.h" #include "Utils/Logging/Log.h" #include @@ -37,6 +38,8 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); + AssetRegistration registration(assetName, lightDef); std::string imageName(static_cast(imageNameSize), '\0'); diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp index f4722b58..c3a7e09f 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp @@ -1,6 +1,7 @@ #include "LightDefLoaderIW4.h" #include "Game/IW4/IW4.h" +#include "Game/IW4/LightDef/LightDefAssetCreationStateIW4.h" #include "LightDef/LightDefCommon.h" #include "Utils/Logging/Log.h" @@ -37,6 +38,8 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); + AssetRegistration registration(assetName, lightDef); std::string imageName(static_cast(imageNameSize), '\0'); diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index 1d728e6c..f9a60106 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -1,6 +1,7 @@ #include "LightDefLoaderIW5.h" #include "Game/IW5/IW5.h" +#include "Game/IW5/LightDef/LightDefAssetCreationStateIW5.h" #include "LightDef/LightDefCommon.h" #include "Utils/Logging/Log.h" @@ -32,6 +33,8 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); + AssetRegistration registration(assetName, lightDef); int8_t attenuationSamplerState; From e92681914f021cfb43da51b3422f369f814fd3d7 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sat, 2 May 2026 15:29:50 -0400 Subject: [PATCH 11/19] Add CreationState to fill in lightdef lookup start. --- .../LightDefAssetCreationStateIW3.cpp | 37 +++++++++++++++++++ .../LightDef/LightDefAssetCreationStateIW3.h | 21 +++++++++++ .../LightDefAssetCreationStateIW4.cpp | 37 +++++++++++++++++++ .../LightDef/LightDefAssetCreationStateIW4.h | 21 +++++++++++ .../LightDefAssetCreationStateIW5.cpp | 37 +++++++++++++++++++ .../LightDef/LightDefAssetCreationStateIW5.h | 21 +++++++++++ 6 files changed, 174 insertions(+) create mode 100644 src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp create mode 100644 src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h create mode 100644 src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp create mode 100644 src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h create mode 100644 src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp create mode 100644 src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp new file mode 100644 index 00000000..112144fd --- /dev/null +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp @@ -0,0 +1,37 @@ +#include "LightDefAssetCreationStateIW3.h" + +#include "Utils/Logging/Log.h" + +using namespace IW3; + +LightDefAssetCreationState::LightDefAssetCreationState() + : m_lmap_pixels_used_for_falloff(0) +{ +} + +void LightDefAssetCreationState::SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context) +{ + const auto* image = lightDef->attenuation.image; + if (!image) + return; + + // We need the actual image to determine the width, so force load it, if it is a reference + if (image->name && image->name[0] == ',') + { + const auto forceLoadedImage = context.ForceLoadDependency(&image->name[1]); + if (!forceLoadedImage) + return; + + image = forceLoadedImage->Asset(); + } + + const int newLmapUsage = image->width + 2; + if (m_lmap_pixels_used_for_falloff + newLmapUsage > MAX_LMAP_USAGE) + { + con::error( + "Total pixel width of all attenuation textures plus 2 border pixels is {} > {}", m_lmap_pixels_used_for_falloff + newLmapUsage, MAX_LMAP_USAGE); + } + + lightDef->lmapLookupStart = m_lmap_pixels_used_for_falloff + 1; + m_lmap_pixels_used_for_falloff += newLmapUsage; +} diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h new file mode 100644 index 00000000..324ad65a --- /dev/null +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Asset/IZoneAssetCreationState.h" +#include "Asset/AssetCreationContext.h" +#include "Game/IW3/IW3.h" + +namespace IW3 +{ + constexpr auto MAX_LMAP_USAGE = 512; + + class LightDefAssetCreationState : public IZoneAssetCreationState + { + public: + LightDefAssetCreationState(); + + void SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context); + + private: + int m_lmap_pixels_used_for_falloff; + }; +} // namespace diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp new file mode 100644 index 00000000..c811e6a1 --- /dev/null +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp @@ -0,0 +1,37 @@ +#include "LightDefAssetCreationStateIW4.h" + +#include "Utils/Logging/Log.h" + +using namespace IW4; + +LightDefAssetCreationState::LightDefAssetCreationState() + : m_lmap_pixels_used_for_falloff(0) +{ +} + +void LightDefAssetCreationState::SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context) +{ + const auto* image = lightDef->attenuation.image; + if (!image) + return; + + // We need the actual image to determine the width, so force load it, if it is a reference + if (image->name && image->name[0] == ',') + { + const auto forceLoadedImage = context.ForceLoadDependency(&image->name[1]); + if (!forceLoadedImage) + return; + + image = forceLoadedImage->Asset(); + } + + const int newLmapUsage = image->width + 2; + if (m_lmap_pixels_used_for_falloff + newLmapUsage > MAX_LMAP_USAGE) + { + con::error( + "Total pixel width of all attenuation textures plus 2 border pixels is {} > {}", m_lmap_pixels_used_for_falloff + newLmapUsage, MAX_LMAP_USAGE); + } + + lightDef->lmapLookupStart = m_lmap_pixels_used_for_falloff + 1; + m_lmap_pixels_used_for_falloff += newLmapUsage; +} diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h new file mode 100644 index 00000000..8646b861 --- /dev/null +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Asset/IZoneAssetCreationState.h" +#include "Asset/AssetCreationContext.h" +#include "Game/IW4/IW4.h" + +namespace IW4 +{ + constexpr auto MAX_LMAP_USAGE = 512; + + class LightDefAssetCreationState : public IZoneAssetCreationState + { + public: + LightDefAssetCreationState(); + + void SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context); + + private: + int m_lmap_pixels_used_for_falloff; + }; +} // namespace diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp new file mode 100644 index 00000000..1bd15ed8 --- /dev/null +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp @@ -0,0 +1,37 @@ +#include "LightDefAssetCreationStateIW5.h" + +#include "Utils/Logging/Log.h" + +using namespace IW5; + +LightDefAssetCreationState::LightDefAssetCreationState() + : m_lmap_pixels_used_for_falloff(0) +{ +} + +void LightDefAssetCreationState::SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context) +{ + const auto* image = lightDef->attenuation.image; + if (!image) + return; + + // We need the actual image to determine the width, so force load it, if it is a reference + if (image->name && image->name[0] == ',') + { + const auto forceLoadedImage = context.ForceLoadDependency(&image->name[1]); + if (!forceLoadedImage) + return; + + image = forceLoadedImage->Asset(); + } + + const int newLmapUsage = image->width + 2; + if (m_lmap_pixels_used_for_falloff + newLmapUsage > MAX_LMAP_USAGE) + { + con::error( + "Total pixel width of all attenuation textures plus 2 border pixels is {} > {}", m_lmap_pixels_used_for_falloff + newLmapUsage, MAX_LMAP_USAGE); + } + + lightDef->lmapLookupStart = m_lmap_pixels_used_for_falloff + 1; + m_lmap_pixels_used_for_falloff += newLmapUsage; +} diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h new file mode 100644 index 00000000..1902411f --- /dev/null +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Asset/IZoneAssetCreationState.h" +#include "Asset/AssetCreationContext.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + constexpr auto MAX_LMAP_USAGE = 512; + + class LightDefAssetCreationState : public IZoneAssetCreationState + { + public: + LightDefAssetCreationState(); + + void SetLightDefLookupStart(GfxLightDef* lightDef, AssetCreationContext& context); + + private: + int m_lmap_pixels_used_for_falloff; + }; +} // namespace light_def From efbbc05626a76f4d37d519dae599028522d3559a Mon Sep 17 00:00:00 2001 From: njohnson Date: Sun, 3 May 2026 20:49:12 -0400 Subject: [PATCH 12/19] Clang format. --- .../Game/IW3/LightDef/LightDefAssetCreationStateIW3.h | 4 ++-- src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp | 2 +- .../Game/IW4/LightDef/LightDefAssetCreationStateIW4.h | 4 ++-- .../Game/IW5/LightDef/LightDefAssetCreationStateIW5.h | 4 ++-- src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h index 324ad65a..2cf65c70 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h @@ -1,7 +1,7 @@ #pragma once -#include "Asset/IZoneAssetCreationState.h" #include "Asset/AssetCreationContext.h" +#include "Asset/IZoneAssetCreationState.h" #include "Game/IW3/IW3.h" namespace IW3 @@ -18,4 +18,4 @@ namespace IW3 private: int m_lmap_pixels_used_for_falloff; }; -} // namespace +} // namespace IW3 diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 0e9240ea..904a3008 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -1,8 +1,8 @@ #include "LightDefLoaderIW3.h" #include "Game/IW3/IW3.h" -#include "LightDef/LightDefCommon.h" #include "Game/IW3/LightDef/LightDefAssetCreationStateIW3.h" +#include "LightDef/LightDefCommon.h" #include "Utils/Logging/Log.h" #include diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h index 8646b861..5f7dfee2 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h @@ -1,7 +1,7 @@ #pragma once -#include "Asset/IZoneAssetCreationState.h" #include "Asset/AssetCreationContext.h" +#include "Asset/IZoneAssetCreationState.h" #include "Game/IW4/IW4.h" namespace IW4 @@ -18,4 +18,4 @@ namespace IW4 private: int m_lmap_pixels_used_for_falloff; }; -} // namespace +} // namespace IW4 diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h index 1902411f..45a23f34 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h @@ -1,7 +1,7 @@ #pragma once -#include "Asset/IZoneAssetCreationState.h" #include "Asset/AssetCreationContext.h" +#include "Asset/IZoneAssetCreationState.h" #include "Game/IW5/IW5.h" namespace IW5 @@ -18,4 +18,4 @@ namespace IW5 private: int m_lmap_pixels_used_for_falloff; }; -} // namespace light_def +} // namespace IW5 diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index f9a60106..467dd355 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -7,8 +7,8 @@ #include #include -#include #include +#include using namespace IW5; From 42ed9d86168d2cb5db830d24becd9144328e1927 Mon Sep 17 00:00:00 2001 From: njohnson Date: Sun, 10 May 2026 22:57:14 -0400 Subject: [PATCH 13/19] Move const to anonymous namespace. --- .../Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp | 5 +++++ .../Game/IW3/LightDef/LightDefAssetCreationStateIW3.h | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp index 112144fd..7838e9ed 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.cpp @@ -4,6 +4,11 @@ using namespace IW3; +namespace +{ + constexpr auto MAX_LMAP_USAGE = 512; +}; + LightDefAssetCreationState::LightDefAssetCreationState() : m_lmap_pixels_used_for_falloff(0) { diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h index 2cf65c70..57e5d55a 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefAssetCreationStateIW3.h @@ -6,8 +6,6 @@ namespace IW3 { - constexpr auto MAX_LMAP_USAGE = 512; - class LightDefAssetCreationState : public IZoneAssetCreationState { public: From d1b74c7230c397fea223551cec5d2729e7ecdb8a Mon Sep 17 00:00:00 2001 From: njohnson Date: Sun, 10 May 2026 23:00:03 -0400 Subject: [PATCH 14/19] Remove vestigial lmapLookupStart code. --- src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 904a3008..57d55e72 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -48,7 +48,6 @@ namespace int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); file.m_stream->read(&imageName[0], static_cast(imageNameSize)); - file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); auto* imageDependency = context.LoadDependency(imageName); if (!imageDependency) @@ -60,7 +59,6 @@ namespace lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); - lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } From 4208bab758c8df3fc68429e1beed174946ede9e5 Mon Sep 17 00:00:00 2001 From: njohnson Date: Mon, 11 May 2026 14:54:10 -0400 Subject: [PATCH 15/19] Remove un-needed constants and switch to parsing name by null character. --- .../Game/IW3/LightDef/LightDefLoaderIW3.cpp | 13 +++---------- .../IW4/LightDef/LightDefAssetCreationStateIW4.cpp | 5 +++++ .../IW4/LightDef/LightDefAssetCreationStateIW4.h | 2 -- .../Game/IW4/LightDef/LightDefLoaderIW4.cpp | 12 ++---------- .../IW5/LightDef/LightDefAssetCreationStateIW5.cpp | 5 +++++ .../IW5/LightDef/LightDefAssetCreationStateIW5.h | 2 -- .../Game/T5/LightDef/LightDefLoaderT5.cpp | 12 ++---------- .../Game/T6/LightDef/LightDefLoaderT6.cpp | 12 ++---------- 8 files changed, 19 insertions(+), 44 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 57d55e72..17bd0d19 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -13,8 +13,6 @@ using namespace IW3; namespace { - constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; - class LoaderLightDef final : public AssetCreator { public: @@ -31,23 +29,18 @@ namespace if (!file.IsOpen()) return AssetCreationResult::NoAction(); - const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); - if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) - return AssetCreationResult::Failure(); - auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); AssetRegistration registration(assetName, lightDef); - - std::string imageName(static_cast(imageNameSize), '\0'); - + + std::string imageName; int8_t samplerState; int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); - file.m_stream->read(&imageName[0], static_cast(imageNameSize)); + std::getline(*file.m_stream, imageName, '\0'); auto* imageDependency = context.LoadDependency(imageName); if (!imageDependency) diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp index c811e6a1..87afdce7 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.cpp @@ -4,6 +4,11 @@ using namespace IW4; +namespace +{ + constexpr auto MAX_LMAP_USAGE = 512; +}; + LightDefAssetCreationState::LightDefAssetCreationState() : m_lmap_pixels_used_for_falloff(0) { diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h index 5f7dfee2..da7c3607 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefAssetCreationStateIW4.h @@ -6,8 +6,6 @@ namespace IW4 { - constexpr auto MAX_LMAP_USAGE = 512; - class LightDefAssetCreationState : public IZoneAssetCreationState { public: diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp index c3a7e09f..e46f6e52 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp @@ -13,8 +13,6 @@ using namespace IW4; namespace { - constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; - class LoaderLightDef final : public AssetCreator { public: @@ -31,10 +29,6 @@ namespace if (!file.IsOpen()) return AssetCreationResult::NoAction(); - const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); - if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) - return AssetCreationResult::Failure(); - auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); @@ -42,13 +36,11 @@ namespace AssetRegistration registration(assetName, lightDef); - std::string imageName(static_cast(imageNameSize), '\0'); - + std::string imageName; int8_t samplerState; int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); - file.m_stream->read(&imageName[0], static_cast(imageNameSize)); - file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + std::getline(*file.m_stream, imageName, '\0'); auto* imageDependency = context.LoadDependency(imageName); if (!imageDependency) diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp index 1bd15ed8..5000ddf0 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.cpp @@ -4,6 +4,11 @@ using namespace IW5; +namespace +{ + constexpr auto MAX_LMAP_USAGE = 512; +}; + LightDefAssetCreationState::LightDefAssetCreationState() : m_lmap_pixels_used_for_falloff(0) { diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h index 45a23f34..d38fd985 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefAssetCreationStateIW5.h @@ -6,8 +6,6 @@ namespace IW5 { - constexpr auto MAX_LMAP_USAGE = 512; - class LightDefAssetCreationState : public IZoneAssetCreationState { public: diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp index 37ee1392..ea4e4a64 100644 --- a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp @@ -12,8 +12,6 @@ using namespace T5; namespace { - constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; - class LoaderLightDef final : public AssetCreator { public: @@ -30,22 +28,16 @@ namespace if (!file.IsOpen()) return AssetCreationResult::NoAction(); - const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); - if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) - return AssetCreationResult::Failure(); - auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); AssetRegistration registration(assetName, lightDef); - std::string imageName(static_cast(imageNameSize), '\0'); - + std::string attenuationName; int8_t samplerState; int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); - file.m_stream->read(&imageName[0], static_cast(imageNameSize)); - file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + std::getline(*file.m_stream, attenuationName, '\0'); auto* imageDependency = context.LoadDependency(imageName); if (!imageDependency) diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp index b57b404f..3b26ce98 100644 --- a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp @@ -12,8 +12,6 @@ using namespace T6; namespace { - constexpr auto MAX_IMAGE_NAME_SIZE = 0x800; - class LoaderLightDef final : public AssetCreator { public: @@ -30,22 +28,16 @@ namespace if (!file.IsOpen()) return AssetCreationResult::NoAction(); - const auto imageNameSize = file.m_length - sizeof(char) - sizeof(char); - if (imageNameSize < 0 || imageNameSize > MAX_IMAGE_NAME_SIZE) - return AssetCreationResult::Failure(); - auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); AssetRegistration registration(assetName, lightDef); - std::string imageName(static_cast(imageNameSize), '\0'); - + std::string attenuationName; int8_t samplerState; int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); - file.m_stream->read(&imageName[0], static_cast(imageNameSize)); - file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); + std::getline(*file.m_stream, attenuationName, '\0'); auto* imageDependency = context.LoadDependency(imageName); if (!imageDependency) From 336c9d8d862f23aa45d6b3faefdc6dac9ad2b0c2 Mon Sep 17 00:00:00 2001 From: njohnson Date: Mon, 11 May 2026 14:55:04 -0400 Subject: [PATCH 16/19] Fix LMAP parsing and don't resolve till after ptr is ready. --- .../Game/IW3/LightDef/LightDefLoaderIW3.cpp | 5 ++-- .../Game/IW4/LightDef/LightDefLoaderIW4.cpp | 6 ++--- .../Game/IW5/LightDef/LightDefLoaderIW5.cpp | 24 ++++++++----------- .../Game/T5/LightDef/LightDefLoaderT5.cpp | 11 ++++----- .../Game/T6/LightDef/LightDefLoaderT6.cpp | 11 ++++----- .../Game/IW3/LightDef/LightDefDumperIW3.cpp | 12 +++++++--- .../Game/IW4/LightDef/LightDefDumperIW4.cpp | 14 ++++++++--- .../Game/IW5/LightDef/LightDefDumperIW5.cpp | 16 ++++++++++--- .../Game/T5/LightDef/LightDefDumperT5.cpp | 14 ++++++++--- .../Game/T6/LightDef/LightDefDumperT6.cpp | 14 ++++++++--- 10 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 17bd0d19..b060b7c8 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -32,13 +32,10 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); - context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); - AssetRegistration registration(assetName, lightDef); std::string imageName; int8_t samplerState; - int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); std::getline(*file.m_stream, imageName, '\0'); @@ -53,6 +50,8 @@ namespace lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp index e46f6e52..ef638766 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp @@ -32,13 +32,10 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); - context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); - AssetRegistration registration(assetName, lightDef); std::string imageName; int8_t samplerState; - int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); std::getline(*file.m_stream, imageName, '\0'); @@ -52,7 +49,8 @@ namespace lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); - lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index 467dd355..fe0d27ea 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -33,8 +33,6 @@ namespace auto* lightDef = m_memory.Alloc(); lightDef->name = m_memory.Dup(assetName.c_str()); - context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); - AssetRegistration registration(assetName, lightDef); int8_t attenuationSamplerState; @@ -55,24 +53,22 @@ namespace std::string cucolorisName; std::getline(*file.m_stream, cucolorisName, '\0'); - auto* cucolorisImageDependency = context.LoadDependency(cucolorisName); - if (!cucolorisImageDependency) - { - con::warn("Could not load GfxLightDef \"{}\" due to missing cucoloris image \"{}\"", assetName, cucolorisName); - } - else + if (!cucolorisName.empty()) { + auto* cucolorisImageDependency = context.LoadDependency(cucolorisName); + if (!cucolorisImageDependency) + { + con::warn("Could not load GfxLightDef \"{}\" due to missing cucoloris image \"{}\"", assetName, cucolorisName); + return AssetCreationResult::Failure(); + } registration.AddDependency(cucolorisImageDependency); + lightDef->cucoloris.image = cucolorisImageDependency->Asset(); } - - int8_t lmapLookupStart; - file.m_stream->read(reinterpret_cast(&lmapLookupStart), sizeof(int8_t)); - lightDef->attenuation.samplerState = attenuationSamplerState; lightDef->attenuation.image = attenuationImageDependency->Asset(); lightDef->cucoloris.samplerState = cucolorisSamplerState; - lightDef->cucoloris.image = cucolorisImageDependency->Asset(); - lightDef->lmapLookupStart = static_cast(static_cast(lmapLookupStart)); + + context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); return AssetCreationResult::Success(context.AddAsset(std::move(registration))); } diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp index ea4e4a64..acd68b55 100644 --- a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp @@ -35,20 +35,19 @@ namespace std::string attenuationName; int8_t samplerState; - int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); std::getline(*file.m_stream, attenuationName, '\0'); - auto* imageDependency = context.LoadDependency(imageName); - if (!imageDependency) + auto* attenuationImageDependency = context.LoadDependency(attenuationName); + if (!attenuationImageDependency) { - con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName); + con::error("Could not load GfxLightDef \"{}\" due to missing attenuation image \"{}\"", assetName, attenuationName); return AssetCreationResult::Failure(); } - registration.AddDependency(imageDependency); + registration.AddDependency(attenuationImageDependency); lightDef->attenuation.samplerState = samplerState; - lightDef->attenuation.image = imageDependency->Asset(); + lightDef->attenuation.image = attenuationImageDependency->Asset(); lightDef->lmapLookupStart = 0; return AssetCreationResult::Success(context.AddAsset(std::move(registration))); diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp index 3b26ce98..4a59c6a4 100644 --- a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp @@ -35,20 +35,19 @@ namespace std::string attenuationName; int8_t samplerState; - int8_t lmapLookupStart; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); std::getline(*file.m_stream, attenuationName, '\0'); - auto* imageDependency = context.LoadDependency(imageName); - if (!imageDependency) + auto* attenuationImageDependency = context.LoadDependency(attenuationName); + if (!attenuationImageDependency) { - con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName); + con::error("Could not load GfxLightDef \"{}\" due to missing attenuation image \"{}\"", assetName, attenuationName); return AssetCreationResult::Failure(); } - registration.AddDependency(imageDependency); + registration.AddDependency(attenuationImageDependency); lightDef->attenuation.samplerState = samplerState; - lightDef->attenuation.image = imageDependency->Asset(); + lightDef->attenuation.image = attenuationImageDependency->Asset(); lightDef->lmapLookupStart = 0; return AssetCreationResult::Success(context.AddAsset(std::move(registration))); diff --git a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp index 6b116ded..47e45684 100644 --- a/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp +++ b/src/ObjWriting/Game/IW3/LightDef/LightDefDumperIW3.cpp @@ -10,9 +10,15 @@ namespace light_def { 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) + if (!assetFile) { + con::error("Could not open GfxLightDef file for dumping!"); + return; + } + + if (lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { + con::error("GfxLightDef attenuation data was invalid!"); return; } @@ -22,6 +28,6 @@ namespace light_def if (imageName[0] == ',') imageName = &imageName[1]; - stream << lightDef->attenuation.samplerState << imageName; + stream << lightDef->attenuation.samplerState << imageName << '\0'; } } // namespace light_def diff --git a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp index 3806cddf..208aac0f 100644 --- a/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/LightDef/LightDefDumperIW4.cpp @@ -10,9 +10,17 @@ namespace light_def { 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) + if (!assetFile) + { + con::error("Could not open GfxLightDef file for dumping!"); return; + } + + if (lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { + con::error("GfxLightDef attenuation data was invalid!"); + return; + } auto& stream = *assetFile; @@ -20,6 +28,6 @@ namespace light_def if (imageName[0] == ',') imageName = &imageName[1]; - stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + stream << lightDef->attenuation.samplerState << imageName << '\0'; } } // namespace light_def diff --git a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp index 7938a813..0b61a8f4 100644 --- a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp @@ -13,20 +13,30 @@ namespace light_def const auto* lightDef = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name)); auto& stream = *assetFile; + if (!assetFile) + { + con::error("Could not open GfxLightDef file for dumping!"); + return; + } + + if (lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { + con::error("GfxLightDef attenuation data was invalid!"); + return; + } - assert(lightDef->attenuation.image != nullptr); const auto* attenuationImageName = lightDef->attenuation.image->name; if (attenuationImageName && attenuationImageName[0] == ',') attenuationImageName = &attenuationImageName[1]; const auto* cucolorisImageName = ""; - if (lightDef->cucoloris.image) + if (lightDef->cucoloris.image && lightDef->cucoloris.image->name) { cucolorisImageName = lightDef->cucoloris.image->name; if (cucolorisImageName && cucolorisImageName[0] == ',') cucolorisImageName = &cucolorisImageName[1]; } - stream << lightDef->attenuation.samplerState << attenuationImageName << '\0' << lightDef->cucoloris.samplerState << cucolorisImageName; + stream << lightDef->attenuation.samplerState << attenuationImageName << '\0' << lightDef->cucoloris.samplerState << cucolorisImageName << '\0'; } } // namespace light_def diff --git a/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp index 386a7646..37572774 100644 --- a/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp +++ b/src/ObjWriting/Game/T5/LightDef/LightDefDumperT5.cpp @@ -10,9 +10,17 @@ namespace light_def { 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) + if (!assetFile) + { + con::error("Could not open GfxLightDef file for dumping!"); return; + } + + if (lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { + con::error("GfxLightDef attenuation data was invalid!"); + return; + } auto& stream = *assetFile; @@ -20,6 +28,6 @@ namespace light_def if (imageName[0] == ',') imageName = &imageName[1]; - stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + stream << lightDef->attenuation.samplerState << imageName << '\0'; } } // namespace light_def diff --git a/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp index f748e408..d3b4f370 100644 --- a/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp +++ b/src/ObjWriting/Game/T6/LightDef/LightDefDumperT6.cpp @@ -10,9 +10,17 @@ namespace light_def { 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) + if (!assetFile) + { + con::error("Could not open GfxLightDef file for dumping!"); return; + } + + if (lightDef->attenuation.image == nullptr || lightDef->attenuation.image->name == nullptr) + { + con::error("GfxLightDef attenuation data was invalid!"); + return; + } auto& stream = *assetFile; @@ -20,6 +28,6 @@ namespace light_def if (imageName[0] == ',') imageName = &imageName[1]; - stream << lightDef->attenuation.samplerState << imageName << static_cast(lightDef->lmapLookupStart); + stream << lightDef->attenuation.samplerState << imageName << '\0'; } } // namespace light_def From cd2346e174adee46339fa8b42e8cc2794c4fa508 Mon Sep 17 00:00:00 2001 From: njohnson Date: Mon, 11 May 2026 16:46:35 -0400 Subject: [PATCH 17/19] Refactor something. --- src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp index 0b61a8f4..3abd8e09 100644 --- a/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/LightDef/LightDefDumperIW5.cpp @@ -12,7 +12,6 @@ namespace light_def { const auto* lightDef = asset.Asset(); const auto assetFile = context.OpenAssetFile(GetFileNameForAsset(asset.m_name)); - auto& stream = *assetFile; if (!assetFile) { con::error("Could not open GfxLightDef file for dumping!"); @@ -25,6 +24,8 @@ namespace light_def return; } + auto& stream = *assetFile; + const auto* attenuationImageName = lightDef->attenuation.image->name; if (attenuationImageName && attenuationImageName[0] == ',') attenuationImageName = &attenuationImageName[1]; From 72dd51609ff844084860c94fa1aa77edecceadb3 Mon Sep 17 00:00:00 2001 From: njohnson Date: Mon, 11 May 2026 16:46:50 -0400 Subject: [PATCH 18/19] Clang format. --- src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index b060b7c8..11ecfcc8 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -33,7 +33,7 @@ namespace lightDef->name = m_memory.Dup(assetName.c_str()); AssetRegistration registration(assetName, lightDef); - + std::string imageName; int8_t samplerState; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); From 015544eb793c109a87e907f7a44c0ef5c4a07617 Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Sat, 16 May 2026 10:45:26 +0200 Subject: [PATCH 19/19] chore: reorder assignment of light def members slightly --- src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp | 3 ++- src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp | 3 ++- src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp | 6 +++--- src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp | 3 ++- src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp | 3 ++- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp index 11ecfcc8..1746d50f 100644 --- a/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/LightDef/LightDefLoaderIW3.cpp @@ -37,6 +37,8 @@ namespace std::string imageName; int8_t samplerState; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + lightDef->attenuation.samplerState = samplerState; + std::getline(*file.m_stream, imageName, '\0'); auto* imageDependency = context.LoadDependency(imageName); @@ -47,7 +49,6 @@ namespace } registration.AddDependency(imageDependency); - lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); diff --git a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp index ef638766..fafe6660 100644 --- a/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/LightDef/LightDefLoaderIW4.cpp @@ -37,6 +37,8 @@ namespace std::string imageName; int8_t samplerState; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + lightDef->attenuation.samplerState = samplerState; + std::getline(*file.m_stream, imageName, '\0'); auto* imageDependency = context.LoadDependency(imageName); @@ -47,7 +49,6 @@ namespace } registration.AddDependency(imageDependency); - lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = imageDependency->Asset(); context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); diff --git a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp index fe0d27ea..cae04945 100644 --- a/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/LightDef/LightDefLoaderIW5.cpp @@ -37,6 +37,7 @@ namespace int8_t attenuationSamplerState; file.m_stream->read(reinterpret_cast(&attenuationSamplerState), sizeof(int8_t)); + lightDef->attenuation.samplerState = attenuationSamplerState; std::string attenuationName; std::getline(*file.m_stream, attenuationName, '\0'); @@ -47,9 +48,11 @@ namespace return AssetCreationResult::Failure(); } registration.AddDependency(attenuationImageDependency); + lightDef->attenuation.image = attenuationImageDependency->Asset(); int8_t cucolorisSamplerState; file.m_stream->read(reinterpret_cast(&cucolorisSamplerState), sizeof(int8_t)); + lightDef->cucoloris.samplerState = cucolorisSamplerState; std::string cucolorisName; std::getline(*file.m_stream, cucolorisName, '\0'); @@ -64,9 +67,6 @@ namespace registration.AddDependency(cucolorisImageDependency); lightDef->cucoloris.image = cucolorisImageDependency->Asset(); } - lightDef->attenuation.samplerState = attenuationSamplerState; - lightDef->attenuation.image = attenuationImageDependency->Asset(); - lightDef->cucoloris.samplerState = cucolorisSamplerState; context.GetZoneAssetCreationState().SetLightDefLookupStart(lightDef, context); diff --git a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp index acd68b55..6da541d5 100644 --- a/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/LightDef/LightDefLoaderT5.cpp @@ -36,6 +36,8 @@ namespace std::string attenuationName; int8_t samplerState; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + lightDef->attenuation.samplerState = samplerState; + std::getline(*file.m_stream, attenuationName, '\0'); auto* attenuationImageDependency = context.LoadDependency(attenuationName); @@ -46,7 +48,6 @@ namespace } registration.AddDependency(attenuationImageDependency); - lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = attenuationImageDependency->Asset(); lightDef->lmapLookupStart = 0; diff --git a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp index 4a59c6a4..04aab6e7 100644 --- a/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/LightDef/LightDefLoaderT6.cpp @@ -36,6 +36,8 @@ namespace std::string attenuationName; int8_t samplerState; file.m_stream->read(reinterpret_cast(&samplerState), sizeof(int8_t)); + lightDef->attenuation.samplerState = samplerState; + std::getline(*file.m_stream, attenuationName, '\0'); auto* attenuationImageDependency = context.LoadDependency(attenuationName); @@ -46,7 +48,6 @@ namespace } registration.AddDependency(attenuationImageDependency); - lightDef->attenuation.samplerState = samplerState; lightDef->attenuation.image = attenuationImageDependency->Asset(); lightDef->lmapLookupStart = 0;