feat: add support for t4 materials (#891)

* feat: add support for t4 materials

* fix: t4 material struct
This commit is contained in:
Jan Laupetin
2026-07-08 22:50:22 +02:00
committed by GitHub
parent a4229788d7
commit c385f50a0e
13 changed files with 402 additions and 45 deletions
+1 -1
View File
@@ -132,7 +132,7 @@ using `Linker`):
| DestructibleDef | ❌ | ❌ | |
| XAnimParts | ✅ | ✅ | |
| XModel | ✅ | ❌ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
| Material | | | |
| Material | | | |
| MaterialTechniqueSet | ❌ | ❌ | |
| GfxImage | ✅ | ✅ | A few special image encodings are not yet supported. |
| snd_alias_list_t | ❌ | ❌ | |
+28 -20
View File
@@ -1046,6 +1046,7 @@ namespace T4
unsigned char textureAtlasColumnCount;
GfxDrawSurf drawSurf;
unsigned int surfaceTypeBits;
unsigned int layeredSurfaceTypes;
uint16_t hashIndex;
};
@@ -1074,7 +1075,7 @@ namespace T4
struct Material
{
MaterialInfo info;
char stateBitsEntry[67];
char stateBitsEntry[59];
unsigned char textureCount;
unsigned char constantCount;
unsigned char stateBitsCount;
@@ -1479,27 +1480,34 @@ namespace T4
TECHNIQUE_LIT_OMNI_FADE_CHARRED = 0x21,
TECHNIQUE_LIT_OMNI_SHADOW_CHARRED = 0x22,
TECHNIQUE_LIT_OMNI_SHADOW_FADE_CHARRED = 0x23,
TECHNIQUE_LIT_INSTANCED = 0x24,
TECHNIQUE_LIT_INSTANCED_SUN = 0x25,
TECHNIQUE_LIT_INSTANCED_SUN_SHADOW = 0x26,
TECHNIQUE_LIT_INSTANCED_SPOT = 0x27,
TECHNIQUE_LIT_INSTANCED_SPOT_SHADOW = 0x28,
TECHNIQUE_LIT_INSTANCED_OMNI = 0x29,
TECHNIQUE_LIT_INSTANCED_OMNI_SHADOW = 0x2A,
TECHNIQUE_LIT_END = 0x24,
TECHNIQUE_LIT_END = 0x2B,
TECHNIQUE_LIGHT_SPOT = 0x24,
TECHNIQUE_LIGHT_OMNI = 0x25,
TECHNIQUE_LIGHT_SPOT_SHADOW = 0x26,
TECHNIQUE_LIGHT_SPOT_CHARRED = 0x27,
TECHNIQUE_LIGHT_OMNI_CHARRED = 0x28,
TECHNIQUE_LIGHT_SPOT_SHADOW_CHARRED = 0x29,
TECHNIQUE_FAKELIGHT_NORMAL = 0x2A,
TECHNIQUE_FAKELIGHT_VIEW = 0x2B,
TECHNIQUE_SUNLIGHT_PREVIEW = 0x2C,
TECHNIQUE_CASE_TEXTURE = 0x2D,
TECHNIQUE_WIREFRAME_SOLID = 0x2E,
TECHNIQUE_WIREFRAME_SHADED = 0x2F,
TECHNIQUE_SHADOWCOOKIE_CASTER = 0x30,
TECHNIQUE_SHADOWCOOKIE_RECEIVER = 0x31,
TECHNIQUE_DEBUG_BUMPMAP = 0x32,
TECHNIQUE_COUNT = 0x33,
TECHNIQUE_TOTAL_COUNT = 0x34,
TECHNIQUE_NONE = 0x35,
TECHNIQUE_LIGHT_SPOT = 0x2B,
TECHNIQUE_LIGHT_OMNI = 0x2C,
TECHNIQUE_LIGHT_SPOT_SHADOW = 0x2D,
TECHNIQUE_LIGHT_SPOT_CHARRED = 0x2E,
TECHNIQUE_LIGHT_OMNI_CHARRED = 0x2F,
TECHNIQUE_LIGHT_SPOT_SHADOW_CHARRED = 0x30,
TECHNIQUE_FAKELIGHT_NORMAL = 0x31,
TECHNIQUE_FAKELIGHT_VIEW = 0x32,
TECHNIQUE_SUNLIGHT_PREVIEW = 0x33,
TECHNIQUE_CASE_TEXTURE = 0x34,
TECHNIQUE_WIREFRAME_SOLID = 0x35,
TECHNIQUE_WIREFRAME_SHADED = 0x36,
TECHNIQUE_SHADOWCOOKIE_CASTER = 0x37,
TECHNIQUE_SHADOWCOOKIE_RECEIVER = 0x38,
TECHNIQUE_DEBUG_BUMPMAP = 0x39,
TECHNIQUE_DEBUG_BUMPMAP_INSTANCED = 0x3A,
TECHNIQUE_COUNT
};
enum MaterialWorldVertexFormat : unsigned char
+15 -12
View File
@@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T5, T6)
#options GAME (IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h"
@@ -11,6 +11,9 @@
#elif GAME == "IW5"
#define FEATURE_IW5
#define HAS_WATER
#elif GAME == "T4"
#define FEATURE_T4
#define HAS_WATER
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
@@ -81,7 +84,7 @@ namespace GAME
INVALID,
DISABLED,
GT0,
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
LT128,
#elif defined(FEATURE_T5)
GE255,
@@ -93,7 +96,7 @@ namespace GAME
{JsonAlphaTest::INVALID, nullptr },
{JsonAlphaTest::DISABLED, "disabled"},
{JsonAlphaTest::GT0, "gt0" },
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
{JsonAlphaTest::LT128, "lt128" },
#elif defined(FEATURE_T5)
{JsonAlphaTest::GE255, "ge255" },
@@ -328,7 +331,7 @@ namespace GAME
{TS_2D, "2D" },
{TS_FUNCTION, "function" },
{TS_COLOR_MAP, "colorMap" },
#if defined(FEATURE_IW3) || defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_IW3) || defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
{TS_UNUSED_1, "unused1" },
#else
{TS_DETAIL_MAP, "detailMap" },
@@ -343,7 +346,7 @@ namespace GAME
{TS_OCCLUSION_MAP, "occlusionMap" },
#endif
{TS_UNUSED_6, "unused6" },
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4) || defined(FEATURE_T5)
{TS_WATER_MAP, "waterMap" },
#endif
#ifdef FEATURE_IW5
@@ -378,7 +381,7 @@ namespace GAME
std::optional<std::string> nameStart;
std::optional<std::string> nameEnd;
TextureSemantic semantic;
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
bool isMatureContent;
#endif
JsonSamplerState samplerState;
@@ -402,7 +405,7 @@ namespace GAME
}
out["semantic"] = in.semantic;
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
out["isMatureContent"] = in.isMatureContent;
#endif
out["samplerState"] = in.samplerState;
@@ -419,7 +422,7 @@ namespace GAME
optional_from_json(in, "nameStart", out.nameStart);
optional_from_json(in, "nameEnd", out.nameEnd);
in.at("semantic").get_to(out.semantic);
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
in.at("isMatureContent").get_to(out.isMatureContent);
#endif
in.at("samplerState").get_to(out.samplerState);
@@ -454,14 +457,14 @@ namespace GAME
{MTL_GAMEFLAG_8, "8" },
{MTL_GAMEFLAG_10, "10" },
{MTL_GAMEFLAG_20, "20" },
#if defined(FEATURE_IW3) || defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_IW3) || defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
{MTL_GAMEFLAG_CASTS_SHADOW, "CASTS_SHADOW"},
{MTL_GAMEFLAG_CASTS_SHADOW, "40" },
#else
{MTL_GAMEFLAG_40, "40" },
#endif
{MTL_GAMEFLAG_80, "80" },
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
{MTL_GAMEFLAG_100, "100" },
{MTL_GAMEFLAG_200, "200" },
#if defined(FEATURE_T6)
@@ -475,7 +478,7 @@ namespace GAME
});
NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, {
#if defined(FEATURE_IW3) || defined(FEATURE_T5)
#if defined(FEATURE_IW3) || defined(FEATURE_T4) || defined(FEATURE_T5)
{CAMERA_REGION_LIT, "lit" },
{CAMERA_REGION_DECAL, "decal" },
{CAMERA_REGION_EMISSIVE, "emissive" },
@@ -506,7 +509,7 @@ namespace GAME
class JsonMaterial
{
public:
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
unsigned layeredSurfaceTypes;
#if defined(FEATURE_T6)
unsigned surfaceFlags;
@@ -0,0 +1,55 @@
#include "LoaderMaterialT4.h"
#include "Game/T4/Material/JsonMaterialLoaderT4.h"
#include "Game/T4/T4.h"
#include "Material/MaterialCommon.h"
#include "Utils/Logging/Log.h"
#include <format>
#include <iostream>
using namespace T4;
namespace
{
class MaterialLoader final : public AssetCreator<AssetMaterial>
{
public:
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto file = m_search_path.Open(material::GetFileNameForAssetName(assetName));
if (!file.IsOpen())
return AssetCreationResult::NoAction();
auto* material = m_memory.Alloc<Material>();
material->info.name = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetMaterial> registration(assetName, material);
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
{
con::error("Failed to load material \"{}\"", assetName);
return AssetCreationResult::Failure();
}
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace material
{
std::unique_ptr<AssetCreator<AssetMaterial>> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<MaterialLoader>(memory, searchPath);
}
} // namespace material
@@ -0,0 +1,12 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T4/T4.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
namespace material
{
std::unique_ptr<AssetCreator<T4::AssetMaterial>> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath);
} // namespace material
+2
View File
@@ -10,6 +10,7 @@
#include "Game/T4/XAnim/XAnimLoaderT4.h"
#include "Localize/AssetLoaderLocalizeT4.h"
#include "Maps/MapEntsLoaderT4.h"
#include "Material/LoaderMaterialT4.h"
#include "RawFile/AssetLoaderRawFileT4.h"
#include "Weapon/FlameTableLoaderT4.h"
#include "Weapon/WeaponGdtLoaderT4.h"
@@ -98,6 +99,7 @@ namespace
collection.AddAssetCreator(xanim::CreateLoaderT4(memory, searchPath, zone));
collection.AddAssetCreator(image::CreateLoaderEmbeddedT4(memory, searchPath));
collection.AddAssetCreator(image::CreateLoaderExternalT4(memory, searchPath));
collection.AddAssetCreator(material::CreateLoaderT4(memory, searchPath));
collection.AddAssetCreator(font::CreateLoaderT4(memory, searchPath));
collection.AddAssetCreator(localize::CreateLoaderT4(memory, searchPath, zone));
collection.AddAssetCreator(map_ents::CreateLoaderT4(memory, searchPath));
@@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T5, T6)
#options GAME (IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialLoader" + GAME + ".cpp"
@@ -14,6 +14,10 @@
#define FEATURE_IW5
#define HAS_WATER
#define GAME_LOWER "iw5"
#elif GAME == "T4"
#define FEATURE_T4
#define HAS_WATER
#define GAME_LOWER "t4"
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
@@ -104,7 +108,7 @@ namespace
con::error("Cannot load material \"{}\": {}", material.info.name, message);
}
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
static bool CreateGameFlagsFromJson(const JsonMaterial& jMaterial, unsigned char& gameFlags)
#elif defined(FEATURE_T5) || defined(FEATURE_T6)
static bool CreateGameFlagsFromJson(const JsonMaterial& jMaterial, unsigned& gameFlags)
@@ -207,7 +211,7 @@ namespace
CreateSamplerStateFromJson(jTexture.samplerState, textureDef.samplerState);
textureDef.semantic = jTexture.semantic;
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
textureDef.isMatureContent = jTexture.isMatureContent;
#endif
@@ -314,7 +318,7 @@ namespace
structured.alphaTestDisabled = 0;
structured.alphaTest = GFXS_ALPHA_TEST_GT_0;
}
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
else if (jStateBitsTableEntry.alphaTest == JsonAlphaTest::LT128)
{
structured.alphaTestDisabled = 0;
@@ -419,7 +423,7 @@ namespace
}
material.info.surfaceTypeBits = jMaterial.surfaceTypeBits;
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
material.info.layeredSurfaceTypes = jMaterial.layeredSurfaceTypes;
#endif
#if defined(FEATURE_T6)
@@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T5, T6)
#options GAME (IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialLoader" + GAME + ".h"
@@ -0,0 +1,249 @@
#include "MaterialConstantZoneStateT4.h"
#include "Game/T4/CommonT4.h"
#include "Game/T4/GameT4.h"
#include "ObjWriting.h"
#include "Zone/ZoneRegistry.h"
namespace
{
const char* KNOWN_CONSTANT_NAMES[]{
"worldViewProjectionMatrix",
"worldViewMatrix2",
"worldViewMatrix1",
"worldViewMatrix",
"worldOutdoorLookupMatrix",
"worldMatrix",
"waterColor",
"viewportDimensions",
"viewProjectionMatrix",
"uvScale",
"uvAnimParms",
"thermalColorOffset",
"sunShadowmapPixelAdjust",
"ssaoParms",
"spotShadowmapPixelAdjust",
"shadowmapSwitchPartition",
"shadowmapScale",
"shadowmapPolygonOffset",
"shadowLookupMatrix",
"renderTargetSize",
"renderSourceSize",
"projectionMatrix",
"playlistPopulationParams",
"pixelCostFracs",
"pixelCostDecode",
"particleCloudSparkColor2",
"particleCloudSparkColor1",
"particleCloudSparkColor0",
"particleCloudMatrix2",
"particleCloudMatrix1",
"particleCloudMatrix",
"particleCloudColor",
"outdoorFeatherParms",
"oceanUVAnimParmPaintedFoam",
"oceanUVAnimParmOctave2",
"oceanUVAnimParmOctave1",
"oceanUVAnimParmOctave0",
"oceanUVAnimParmFoam",
"oceanUVAnimParmDetail1",
"oceanUVAnimParmDetail0",
"oceanScrollParms",
"oceanMiscParms",
"oceanFoamParms",
"oceanAmplitude",
"materialColor",
"lightprobeAmbient",
"lightingLookupScale",
"lightSpotFactors",
"lightSpotDir",
"lightSpecular",
"lightPosition",
"lightFalloffPlacement",
"lightDiffuse",
"inverseWorldViewMatrix",
"inverseViewProjectionMatrix",
"inverseTransposeWorldViewMatrix",
"heatMapDetail",
"glowSetup",
"glowApply",
"gameTime",
"fullscreenDistortion",
"fogSunDir",
"fogSunConsts",
"fogSunColorLinear",
"fogSunColorGamma",
"fogConsts",
"fogColorLinear",
"fogColorGamma",
"flagParms",
"filterTap",
"featherParms",
"falloffParms",
"falloffEndColor",
"falloffBeginColor",
"fadeEffect",
"eyeOffsetParms",
"eyeOffset",
"envMapParms",
"dustTint",
"dustParms",
"dustEyeParms",
"dofRowDelta",
"dofLerpScale",
"dofLerpBias",
"dofEquationViewModelAndFarBlur",
"dofEquationScene",
"distortionScale",
"detailScale",
"depthFromClip",
"debugBumpmap",
"colorTintQuadraticDelta",
"colorTintDelta",
"colorTintBase",
"colorSaturationR",
"colorSaturationG",
"colorSaturationB",
"colorObjMin",
"colorObjMax",
"colorMatrixR",
"colorMatrixG",
"colorMatrixB",
"colorBias",
"codeMeshArg",
"clipSpaceLookupScale",
"clipSpaceLookupOffset",
"baseLightingCoords",
};
const char* KNOWN_TEXTURE_DEF_NAMES[]{
"attenuation",
"attenuationSampler",
"cinematicA",
"cinematicASampler",
"cinematicCb",
"cinematicCbSampler",
"cinematicCr",
"cinematicCrSampler",
"cinematicY",
"cinematicYSampler",
"colorMap",
"colorMap1",
"colorMap2",
"colorMapPostSun",
"colorMapPostSunSampler",
"colorMapSampler",
"colorMapSampler1",
"colorMapSampler2",
"cucoloris",
"cucolorisSampler",
"detailMap",
"detailMapSampler",
"dust",
"dustSampler",
"fadeMap",
"fadeMapSampler",
"floatZ",
"floatZSampler",
"grainMap",
"grainMapSampler",
"halfParticleColor",
"halfParticleColorSampler",
"halfParticleDepth",
"halfParticleDepthSampler",
"heatmap",
"heatmapSampler",
"lightmapPrimary",
"lightmapSamplerPrimary",
"lightmapSamplerSecondary",
"lightmapSecondary",
"lookupMap",
"lookupMapSampler",
"modelLighting",
"modelLightingSampler",
"normalMap",
"normalMapSampler",
"oceanColorRamp",
"oceanColorRampSampler",
"oceanDetailNormal",
"oceanDetailNormalSampler",
"oceanDisplacement",
"oceanDisplacementSampler",
"oceanEnv",
"oceanEnvSampler",
"oceanFoam",
"oceanFoamSampler",
"oceanHeightNormal",
"oceanHeightNormalSampler",
"oceanPaintedFoam",
"oceanPaintedFoamSampler",
"outdoorMap",
"outdoorMapSampler",
"population",
"populationSampler",
"reflectionProbe",
"reflectionProbeSampler",
"shadowmapSamplerSpot",
"shadowmapSamplerSun",
"shadowmapSpot",
"shadowmapSun",
"skyMap",
"skyMapSampler",
"specularMap",
"specularMapSampler",
"ssao",
"ssaoSampler",
"worldMap",
"worldMapSampler",
};
} // namespace
namespace T4
{
void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{
for (const auto* zone : ZoneRegistry::GetRegistryForGame(GameId::T4)->Zones())
{
for (const auto* techniqueSetInfo : zone->m_pools.PoolAssets<AssetTechniqueSet>())
{
const auto* techniqueSet = techniqueSetInfo->Asset();
for (const auto* technique : techniqueSet->techniques)
{
if (technique)
ExtractNamesFromTechnique(technique);
}
}
}
}
unsigned MaterialConstantZoneState::HashString(const std::string& str) const
{
return Common::R_HashString(str.c_str());
}
void MaterialConstantZoneState::ExtractNamesFromTechnique(const MaterialTechnique* technique)
{
if (!ShouldDumpFromStruct(technique))
return;
for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++)
{
const auto& pass = technique->passArray[passIndex];
if (pass.vertexShader && pass.vertexShader->prog.loadDef.program)
ExtractNamesFromShader(pass.vertexShader->prog.loadDef.program, pass.vertexShader->prog.loadDef.programSize);
if (pass.pixelShader && pass.pixelShader->prog.loadDef.program)
ExtractNamesFromShader(pass.pixelShader->prog.loadDef.program, pass.pixelShader->prog.loadDef.programSize);
}
}
void MaterialConstantZoneState::AddStaticKnownNames()
{
for (const auto* knownConstantName : KNOWN_CONSTANT_NAMES)
AddConstantName(knownConstantName);
for (const auto* knownTextureDefName : KNOWN_TEXTURE_DEF_NAMES)
AddTextureDefName(knownTextureDefName);
}
} // namespace T4
@@ -0,0 +1,18 @@
#pragma once
#include "Game/T4/T4.h"
#include "Material/AbstractMaterialConstantZoneState.h"
#include <string>
namespace T4
{
class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx9
{
protected:
void ExtractNamesFromZoneInternal() override;
void ExtractNamesFromTechnique(const MaterialTechnique* technique);
void AddStaticKnownNames() override;
[[nodiscard]] unsigned HashString(const std::string& str) const override;
};
} // namespace T4
+2
View File
@@ -2,6 +2,7 @@
#include "Game/T4/Font/FontDumperT4.h"
#include "Game/T4/Image/ImageDumperT4.h"
#include "Game/T4/Material/MaterialJsonDumperT4.h"
#include "Game/T4/XAnim/XAnimDumperT4.h"
#include "Game/T4/XModel/XModelDumperT4.h"
#include "Localize/LocalizeDumperT4.h"
@@ -17,6 +18,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context)
{
RegisterAssetDumper(std::make_unique<xanim::DumperT4>());
RegisterAssetDumper(std::make_unique<xmodel::DumperT4>());
RegisterAssetDumper(std::make_unique<material::JsonDumperT4>());
RegisterAssetDumper(std::make_unique<image::DumperT4>());
RegisterAssetDumper(std::make_unique<sound::LoadedSoundDumperT4>());
RegisterAssetDumper(std::make_unique<map_ents::DumperT4>());
@@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T5, T6)
#options GAME (IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Material/MaterialJsonDumper" + GAME + ".cpp"
@@ -14,6 +14,10 @@
#define FEATURE_IW5
#define HAS_WATER
#define GAME_LOWER "iw5"
#elif GAME == "T4"
#define FEATURE_T4
#define HAS_WATER
#define GAME_LOWER "t4"
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
@@ -153,7 +157,7 @@ namespace
}
jTextureDef.semantic = static_cast<TextureSemantic>(textureDef.semantic);
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
jTextureDef.isMatureContent = textureDef.isMatureContent;
#endif
@@ -231,7 +235,7 @@ namespace
assert(structured.alphaTestDisabled
|| structured.alphaTest == GFXS_ALPHA_TEST_GT_0
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
|| structured.alphaTest == GFXS_ALPHA_TEST_LT_128
#elif defined(FEATURE_T5)
|| structured.alphaTest == GFXS_ALPHA_TEST_GE_255
@@ -241,7 +245,7 @@ namespace
jStateBitsTableEntry.alphaTest = JsonAlphaTest::DISABLED;
else if (structured.alphaTest == GFXS_ALPHA_TEST_GT_0)
jStateBitsTableEntry.alphaTest = JsonAlphaTest::GT0;
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
else if (structured.alphaTest == GFXS_ALPHA_TEST_LT_128)
jStateBitsTableEntry.alphaTest = JsonAlphaTest::LT128;
#elif defined(FEATURE_T5)
@@ -318,7 +322,7 @@ namespace
jMaterial.textureAtlas->columns = material.info.textureAtlasColumnCount;
jMaterial.surfaceTypeBits = material.info.surfaceTypeBits;
#if defined(FEATURE_T5) || defined(FEATURE_T6)
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
jMaterial.layeredSurfaceTypes = material.info.layeredSurfaceTypes;
#endif
#if defined(FEATURE_T6)
@@ -1,4 +1,4 @@
#options GAME(IW3, IW4, IW5, T5, T6)
#options GAME(IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Material/MaterialJsonDumper" + GAME + ".h"