#options GAME (IW4, IW5, T6) #filename "Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h" #if GAME == "IW4" #define FEATURE_IW4 #define HAS_WATER #elif GAME == "IW5" #define FEATURE_IW5 #define HAS_WATER #elif GAME == "T6" #define FEATURE_T6 #endif // This file was templated. // See JsonMaterialWriter.h.template. // Do not modify, changes will be lost. #pragma once #set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" #include GAME_HEADER #include "Json/JsonExtension.h" #include #include #include #include #include namespace GAME { NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilOp, { {GFXS_STENCILOP_KEEP, "keep" }, {GFXS_STENCILOP_ZERO, "zero" }, {GFXS_STENCILOP_REPLACE, "replace"}, {GFXS_STENCILOP_INCRSAT, "incrsat"}, {GFXS_STENCILOP_DECRSAT, "decrsat"}, {GFXS_STENCILOP_INVERT, "invert" }, {GFXS_STENCILOP_INCR, "incr" }, {GFXS_STENCILOP_DECR, "decr" }, }); NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilFunc, { {GFXS_STENCILFUNC_NEVER, "never" }, {GFXS_STENCILFUNC_LESS, "less" }, {GFXS_STENCILFUNC_EQUAL, "equal" }, {GFXS_STENCILFUNC_LESSEQUAL, "lessequal" }, {GFXS_STENCILFUNC_GREATER, "greater" }, {GFXS_STENCILFUNC_NOTEQUAL, "notequal" }, {GFXS_STENCILFUNC_GREATEREQUAL, "greaterequal"}, {GFXS_STENCILFUNC_ALWAYS, "always" }, }); class JsonStencil { public: GfxStencilOp pass; GfxStencilOp fail; GfxStencilOp zfail; GfxStencilFunc func; }; NLOHMANN_DEFINE_TYPE_EXTENSION( JsonStencil, pass, fail, zfail, func ); enum class JsonAlphaTest { INVALID, DISABLED, GT0, #if defined(FEATURE_IW4) || defined(FEATURE_IW5) LT128, #endif GE128 }; NLOHMANN_JSON_SERIALIZE_ENUM(JsonAlphaTest, { {JsonAlphaTest::INVALID, nullptr }, {JsonAlphaTest::DISABLED, "disabled"}, {JsonAlphaTest::GT0, "gt0" }, #if defined(FEATURE_IW4) || defined(FEATURE_IW5) {JsonAlphaTest::LT128, "lt128" }, #endif {JsonAlphaTest::GE128, "ge128" } }); enum class JsonCullFace { INVALID, NONE, BACK, FRONT }; NLOHMANN_JSON_SERIALIZE_ENUM(JsonCullFace, { {JsonCullFace::INVALID, nullptr}, {JsonCullFace::NONE, "none" }, {JsonCullFace::BACK, "back" }, {JsonCullFace::FRONT, "front"} }); enum class JsonDepthTest { INVALID, DISABLED, ALWAYS, LESS, EQUAL, LESS_EQUAL }; NLOHMANN_JSON_SERIALIZE_ENUM(JsonDepthTest, { {JsonDepthTest::INVALID, nullptr }, {JsonDepthTest::DISABLED, "disabled" }, {JsonDepthTest::ALWAYS, "always" }, {JsonDepthTest::LESS, "less" }, {JsonDepthTest::EQUAL, "equal" }, {JsonDepthTest::LESS_EQUAL, "less_equal"} }); NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlend, { {GFXS_BLEND_DISABLED, "disabled" }, {GFXS_BLEND_ZERO, "zero" }, {GFXS_BLEND_ONE, "one" }, {GFXS_BLEND_SRCCOLOR, "srccolor" }, {GFXS_BLEND_INVSRCCOLOR, "invsrccolor" }, {GFXS_BLEND_SRCALPHA, "srcalpha" }, {GFXS_BLEND_INVSRCALPHA, "invsrcalpha" }, {GFXS_BLEND_DESTALPHA, "destalpha" }, {GFXS_BLEND_INVDESTALPHA, "invdestalpha"}, {GFXS_BLEND_DESTCOLOR, "destcolor" }, {GFXS_BLEND_INVDESTCOLOR, "invdestcolor"}, }); NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlendOp, { {GFXS_BLENDOP_DISABLED, "disabled" }, {GFXS_BLENDOP_ADD, "add" }, {GFXS_BLENDOP_SUBTRACT, "subtract" }, {GFXS_BLENDOP_REVSUBTRACT, "revsubtract"}, {GFXS_BLENDOP_MIN, "min" }, {GFXS_BLENDOP_MAX, "max" }, }); NLOHMANN_JSON_SERIALIZE_ENUM(GfxPolygonOffset_e, { {GFXS_POLYGON_OFFSET_0, "offset0" }, {GFXS_POLYGON_OFFSET_1, "offset1" }, {GFXS_POLYGON_OFFSET_2, "offset2" }, {GFXS_POLYGON_OFFSET_SHADOWMAP, "offsetShadowmap"}, }); class JsonStateBitsTableEntry { public: GfxBlend srcBlendRgb; GfxBlend dstBlendRgb; GfxBlendOp blendOpRgb; JsonAlphaTest alphaTest; JsonCullFace cullFace; GfxBlend srcBlendAlpha; GfxBlend dstBlendAlpha; GfxBlendOp blendOpAlpha; bool colorWriteRgb; bool colorWriteAlpha; #if defined(FEATURE_IW4) || defined(FEATURE_IW5) bool gammaWrite; #endif bool polymodeLine; bool depthWrite; JsonDepthTest depthTest; GfxPolygonOffset_e polygonOffset; std::optional stencilFront; std::optional stencilBack; }; NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry, srcBlendRgb, dstBlendRgb, blendOpRgb, alphaTest, cullFace, srcBlendAlpha, dstBlendAlpha, blendOpAlpha, colorWriteRgb, colorWriteAlpha, #if defined(FEATURE_IW4) || defined(FEATURE_IW5) gammaWrite, #endif polymodeLine, depthWrite, depthWrite, depthTest, polygonOffset, stencilFront, stencilBack ); class JsonConstant { public: std::optional name; std::optional nameFragment; std::optional nameHash; std::vector literal; }; inline void to_json(nlohmann::json& out, const JsonConstant& in) { if (in.name.has_value()) { optional_to_json(out, "name", in.name); } else { optional_to_json(out, "nameFragment", in.nameFragment); optional_to_json(out, "nameHash", in.nameHash); } out["literal"] = in.literal; } inline void from_json(const nlohmann::json& in, JsonConstant& out) { optional_from_json(in, "name", out.name); optional_from_json(in, "nameFragment", out.nameFragment); optional_from_json(in, "nameHash", out.nameHash); in.at("literal").get_to(out.literal); }; NLOHMANN_JSON_SERIALIZE_ENUM(TextureFilter, { {TEXTURE_FILTER_DISABLED, "disabled"}, {TEXTURE_FILTER_NEAREST, "nearest" }, {TEXTURE_FILTER_LINEAR, "linear" }, {TEXTURE_FILTER_ANISO2X, "aniso2x" }, {TEXTURE_FILTER_ANISO4X, "aniso4x" }, #ifdef FEATURE_T6 {TEXTURE_FILTER_COMPARE, "compare" }, #endif }); NLOHMANN_JSON_SERIALIZE_ENUM(SamplerStateBitsMipMap_e, { {SAMPLER_MIPMAP_ENUM_DISABLED, "disabled"}, {SAMPLER_MIPMAP_ENUM_NEAREST, "nearest" }, {SAMPLER_MIPMAP_ENUM_LINEAR, "linear" }, }); class JsonSamplerState { public: TextureFilter filter; SamplerStateBitsMipMap_e mipMap; bool clampU; bool clampV; bool clampW; }; NLOHMANN_DEFINE_TYPE_EXTENSION( JsonSamplerState, filter, mipMap, clampU, clampV, clampW ); #ifdef HAS_WATER class JsonComplex { public: float real; float imag; }; NLOHMANN_DEFINE_TYPE_EXTENSION(JsonComplex, real, imag); class JsonWater { public: float floatTime; int m; int n; std::string h0; std::string wTerm; float lx; float lz; float gravity; float windvel; std::array winddir; float amplitude; std::array codeConstant; }; NLOHMANN_DEFINE_TYPE_EXTENSION( JsonWater, floatTime, m, n, h0, wTerm, lx, lz, gravity, windvel, winddir, amplitude, codeConstant ); #endif NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, { #if defined(FEATURE_IW4) || defined(FEATURE_IW5) {TS_2D, "2D" }, {TS_FUNCTION, "function" }, {TS_COLOR_MAP, "colorMap" }, {TS_DETAIL_MAP, "detailMap" }, {TS_UNUSED_2, "unused2" }, {TS_NORMAL_MAP, "normalMap" }, {TS_UNUSED_3, "unused3" }, {TS_UNUSED_4, "unused4" }, {TS_SPECULAR_MAP, "specularMap" }, {TS_UNUSED_5, "unused5" }, {TS_UNUSED_6, "unused6" }, {TS_WATER_MAP, "waterMap" }, #ifdef FEATURE_IW5 {TS_DISPLACEMENT_MAP, "displacementMap"}, #endif #elif defined(FEATURE_T6) {TS_2D, "2D" }, {TS_FUNCTION, "function" }, {TS_COLOR_MAP, "colorMap" }, {TS_UNUSED_1, "unused1" }, {TS_UNUSED_2, "unused2" }, {TS_NORMAL_MAP, "normalMap" }, {TS_UNUSED_3, "unused3" }, {TS_UNUSED_4, "unused4" }, {TS_SPECULAR_MAP, "specularMap" }, {TS_UNUSED_5, "unused5" }, {TS_OCCLUSION_MAP, "occlusionMap"}, {TS_UNUSED_6, "unused6" }, {TS_COLOR0_MAP, "color0Map" }, {TS_COLOR1_MAP, "color1Map" }, {TS_COLOR2_MAP, "color2Map" }, {TS_COLOR3_MAP, "color3Map" }, {TS_COLOR4_MAP, "color4Map" }, {TS_COLOR5_MAP, "color5Map" }, {TS_COLOR6_MAP, "color6Map" }, {TS_COLOR7_MAP, "color7Map" }, {TS_COLOR8_MAP, "color8Map" }, {TS_COLOR9_MAP, "color9Map" }, {TS_COLOR10_MAP, "color10Map" }, {TS_COLOR11_MAP, "color11Map" }, {TS_COLOR12_MAP, "color12Map" }, {TS_COLOR13_MAP, "color13Map" }, {TS_COLOR14_MAP, "color14Map" }, {TS_COLOR15_MAP, "color15Map" }, {TS_THROW_MAP, "throwMap" }, #endif }); class JsonTexture { public: std::optional name; std::optional nameHash; std::optional nameStart; std::optional nameEnd; TextureSemantic semantic; #ifdef FEATURE_T6 bool isMatureContent; #endif JsonSamplerState samplerState; std::string image; #ifdef HAS_WATER std::optional water; #endif }; inline void to_json(nlohmann::json& out, const JsonTexture& in) { if (in.name.has_value()) { optional_to_json(out, "name", in.name); } else { optional_to_json(out, "nameHash", in.nameHash); optional_to_json(out, "nameStart", in.nameStart); optional_to_json(out, "nameEnd", in.nameEnd); } out["semantic"] = in.semantic; #ifdef FEATURE_T6 out["isMatureContent"] = in.isMatureContent; #endif out["samplerState"] = in.samplerState; out["image"] = in.image; #ifdef HAS_WATER optional_to_json(out, "water", in.water); #endif } inline void from_json(const nlohmann::json& in, JsonTexture& out) { optional_from_json(in, "name", out.name); optional_from_json(in, "nameHash", out.nameHash); optional_from_json(in, "nameStart", out.nameStart); optional_from_json(in, "nameEnd", out.nameEnd); in.at("semantic").get_to(out.semantic); #ifdef FEATURE_T6 in.at("isMatureContent").get_to(out.isMatureContent); #endif in.at("samplerState").get_to(out.samplerState); in.at("image").get_to(out.image); #ifdef HAS_WATER optional_from_json(in, "water", out.water); #endif }; class JsonTextureAtlas { public: uint8_t rows; uint8_t columns; }; NLOHMANN_DEFINE_TYPE_EXTENSION( JsonTextureAtlas, rows, columns ); NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, { #if defined(FEATURE_IW4) || defined(FEATURE_IW5) {MTL_GAMEFLAG_1, "1" }, {MTL_GAMEFLAG_2, "2" }, {MTL_GAMEFLAG_4, "4" }, {MTL_GAMEFLAG_8, "8" }, {MTL_GAMEFLAG_10, "10" }, {MTL_GAMEFLAG_20, "20" }, {MTL_GAMEFLAG_40, "40" }, {MTL_GAMEFLAG_80, "80" }, #elif defined(FEATURE_T6) {MTL_GAMEFLAG_1, "1" }, {MTL_GAMEFLAG_2, "2" }, {MTL_GAMEFLAG_NO_MARKS, "NO_MARKS" }, {MTL_GAMEFLAG_NO_MARKS, "4" }, {MTL_GAMEFLAG_8, "8" }, {MTL_GAMEFLAG_10, "10" }, {MTL_GAMEFLAG_20, "20" }, {MTL_GAMEFLAG_CASTS_SHADOW, "CASTS_SHADOW"}, {MTL_GAMEFLAG_CASTS_SHADOW, "40" }, {MTL_GAMEFLAG_80, "80" }, {MTL_GAMEFLAG_100, "100" }, {MTL_GAMEFLAG_200, "200" }, {MTL_GAMEFLAG_400, "400" }, {MTL_GAMEFLAG_800, "800" }, {MTL_GAMEFLAG_1000, "1000" }, #endif }); NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, { #if defined(FEATURE_IW4) || defined(FEATURE_IW5) {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, {CAMERA_REGION_LIT_TRANS, "litTrans" }, {CAMERA_REGION_EMISSIVE, "emissive" }, {CAMERA_REGION_DEPTH_HACK, "depthHack" }, #ifdef FEATURE_IW5 {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, #endif {CAMERA_REGION_NONE, "none" }, #elif defined(FEATURE_T6) {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, {CAMERA_REGION_LIT_TRANS, "litTrans" }, {CAMERA_REGION_LIT_QUASI_OPAQUE, "litQuasiOpaque"}, {CAMERA_REGION_EMISSIVE_OPAQUE, "emissiveOpaque"}, {CAMERA_REGION_EMISSIVE_TRANS, "emissiveTrans" }, {CAMERA_REGION_EMISSIVE_FX, "emissiveFx" }, {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, {CAMERA_REGION_DEPTH_HACK, "depthHack" }, {CAMERA_REGION_UNUSED, "unused" }, {CAMERA_REGION_SONAR, "sonar" }, {CAMERA_REGION_NONE, "none" }, #endif }); class JsonMaterial { public: #ifdef FEATURE_T6 unsigned layeredSurfaceTypes; unsigned hashIndex; unsigned surfaceFlags; unsigned contents; uint8_t probeMipBits; std::optional thermalMaterial; #endif std::vector gameFlags; unsigned sortKey; std::optional textureAtlas; unsigned surfaceTypeBits; std::vector stateBitsEntry; unsigned stateFlags; GfxCameraRegionType cameraRegion; std::string techniqueSet; std::vector textures; std::vector constants; std::vector stateBits; }; NLOHMANN_DEFINE_TYPE_EXTENSION( JsonMaterial, #ifdef FEATURE_T6 layeredSurfaceTypes, hashIndex, surfaceFlags, contents, probeMipBits, thermalMaterial, #endif gameFlags, sortKey, textureAtlas, surfaceTypeBits, stateBitsEntry, stateFlags, cameraRegion, techniqueSet, textures, constants, stateBits ); } // namespace GAME