From f1e0fe8aec99597ebe1ffadf3dc8ff4786518579 Mon Sep 17 00:00:00 2001 From: Louvenarde Date: Thu, 15 Dec 2022 23:52:49 +0100 Subject: [PATCH] Delay Model Surface and fix Static model flags --- src/Components/Modules/IGfxWorld.cpp | 11 ++++- src/Components/Modules/IMaterial.cpp | 68 ++++++++++++++++++++++++++++ src/Components/Modules/IMaterial.hpp | 3 ++ src/Game/Functions.cpp | 2 +- src/Game/Structs.hpp | 2 +- 5 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/IGfxWorld.cpp b/src/Components/Modules/IGfxWorld.cpp index 7671ca3..ab1ce10 100644 --- a/src/Components/Modules/IGfxWorld.cpp +++ b/src/Components/Modules/IGfxWorld.cpp @@ -946,7 +946,14 @@ namespace Components map.dpvs.smodelDrawInsts[i].reflectionProbeIndex = world->dpvs.smodelDrawInsts[i].reflectionProbeIndex; map.dpvs.smodelDrawInsts[i].primaryLightIndex = world->dpvs.smodelDrawInsts[i].primaryLightIndex; map.dpvs.smodelDrawInsts[i].lightingHandle = world->dpvs.smodelDrawInsts[i].lightingHandle; - map.dpvs.smodelDrawInsts[i].flags = world->dpvs.smodelDrawInsts[i].flags; + map.dpvs.smodelDrawInsts[i].flags = 0; + + if (world->dpvs.smodelDrawInsts[i].flags & Game::IW3::STATIC_MODEL_FLAG_NO_SHADOW) + { + // Confirmed to be the same in the rendering functions + // Check R_AddAllStaticModelSurfacesSpotShadow in both iw3 and iw4 + map.dpvs.smodelDrawInsts[i].flags |= Game::IW4::STATIC_MODEL_FLAG_NO_CAST_SHADOW; + } // This has been moved if (world->dpvs.smodelInsts) @@ -957,7 +964,7 @@ namespace Components //// Whenever a model needs ground lighting in iw4, it has to specify it if (map.dpvs.smodelDrawInsts[i].groundLighting.packed > 0) { - map.dpvs.smodelDrawInsts[i].flags |= 0x20; + map.dpvs.smodelDrawInsts[i].flags |= Game::IW4::STATIC_MODEL_FLAG_GROUND_LIGHTING; } } } diff --git a/src/Components/Modules/IMaterial.cpp b/src/Components/Modules/IMaterial.cpp index 039bfca..39e4fd5 100644 --- a/src/Components/Modules/IMaterial.cpp +++ b/src/Components/Modules/IMaterial.cpp @@ -4,6 +4,7 @@ namespace Components { + std::unordered_map IMaterial::exampleMaterialForKey{}; std::unordered_map IMaterial::sortKeysTable = { {0, 43}, // Distortion // Opaque water (never used) @@ -369,6 +370,9 @@ namespace Components mat.gameFlags.fields.unk8 = material->info.gameFlags.fields.unk7; mat.gameFlags.fields.unk7 = material->info.gameFlags.fields.unk8; + // Do not delay model surface ever! In iw4 this doesn't even exist + // If this flag is ever set to 1 it usually burns the delayed surface buffer of IW4 + mat.gameFlags.fields.delayModelSurface = 0; // Sort key #if USE_IW3_SORTKEYS mat.sortKey = material->info.sortKey; // Using iw3 value directly @@ -458,6 +462,16 @@ namespace Components Logger::Print("Set statebit %i loadbit 0 to GFXS0_CULL_NONE on material %s (it is glass)\n", index, mat.name); } +#if not USE_IW3_SORTKEYS + Game::IW4::Material conflict; + if (CheckSortKeyConflict(&mat, conflict)) + { + Components::Logger::Print("There is a sort key conflict between %s and %s on the key %i. One of these two (most probably the first one) doesn't have the right sort key! You will need to fix the material JSON manually.\n", + mat.name, conflict.name, mat.sortKey); + assert(false); + } +#endif + IMaterial::SaveConvertedMaterial(&mat); } @@ -538,6 +552,15 @@ namespace Components return 34; } + + if (techsetName.contains("effect")) + { + // Really not sure about this! But some posters on some custom maps (mp_nuked_xmas) are on wc_effect tecshet + // and cause a sort crash when put on the decal layer (9) + Logger::Print("Material %s was given sortkey %i from %i (techset name contains 'effect')\n", name.data(), 34, iw3Key); + return 48; + } + /* - 16 (3 matches) - mp_crash:mc\ch_bulletinboardpaperdecals_2.json @@ -669,6 +692,51 @@ namespace Components return iw3Key; } + bool IMaterial::CheckSortKeyConflict(Game::IW4::Material* material, OUT Game::IW4::Material& conflictingMaterial) + { + if (exampleMaterialForKey.find(material->sortKey) == exampleMaterialForKey.end()) + { + exampleMaterialForKey[material->sortKey] = *material; + return false; + } + + auto* otherMaterial = &exampleMaterialForKey.at(material->sortKey); + + assert(material->techniqueSet); + + bool hasLit = material->techniqueSet->techniques[Game::IW4::TECHNIQUE_LIT] != nullptr; + bool otherHasLit = otherMaterial->techniqueSet->techniques[Game::IW4::TECHNIQUE_LIT] != nullptr; + + if (otherHasLit != hasLit) + { + conflictingMaterial = *otherMaterial; + return true; + } + + if (hasLit) + { + bool hasEmissive = material->techniqueSet->techniques[Game::IW4::TECHNIQUE_EMISSIVE]; + bool otherHasEmissive = otherMaterial->techniqueSet->techniques[Game::IW4::TECHNIQUE_EMISSIVE]; + + if (hasEmissive) + { + conflictingMaterial = *otherMaterial; + return true; + } + + if (otherHasEmissive) + { + conflictingMaterial = *otherMaterial; + return true; + } + } + + + return false; + } + + + IMaterial::IMaterial() { diff --git a/src/Components/Modules/IMaterial.hpp b/src/Components/Modules/IMaterial.hpp index 07fd1c8..be3dd45 100644 --- a/src/Components/Modules/IMaterial.hpp +++ b/src/Components/Modules/IMaterial.hpp @@ -14,12 +14,15 @@ namespace Components private: static std::unordered_map sortKeysTable; + static std::unordered_map exampleMaterialForKey; static void Dump(Game::IW3::Material* material); static void SaveConvertedMaterial(Game::IW4::Material* asset); static char GetConvertedSortKey(Game::IW3::Material* material); + + static bool CheckSortKeyConflict(Game::IW4::Material* material, OUT Game::IW4::Material& conflictingMaterial); static rapidjson::Value StateBitsToJsonArray(Game::IW3::GfxStateBits* stateBits, unsigned char count, rapidjson::MemoryPoolAllocator& allocator); }; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index dc2b1ba..6753e2a 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -113,7 +113,7 @@ namespace Game if (entry->entry.asset.type == type) { auto assetName = DB_GetXAssetNameHandlers[entry->entry.asset.type](&entry->entry.asset.header); - if (!stricmp(name, assetName)) + if (!_stricmp(name, assetName)) break; } diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 12de541..4d99e18 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -136,7 +136,7 @@ namespace Game unsigned char isFoliageRequiresGroundLighting : 1; unsigned char unk4 : 1; unsigned char unk5 : 1; - unsigned char unk6 : 1; + unsigned char delayModelSurface : 1; unsigned char unk7 : 1; unsigned char unk8 : 1; };