From 39c141eb5668f5fd42b8e8f90fdaf4e4c37fd94b Mon Sep 17 00:00:00 2001 From: Silent Date: Thu, 23 May 2024 21:48:53 +0200 Subject: [PATCH] VC: Correct the duration of the outro splash to 2.5 seconds and fix flicker The original code hints at 1.5s, but that makes it hard to read the splash before it vanishes + Update the DrawBackfaces list --- Config/SilentPatchVC.ini | 2 ++ SilentPatchVC/SilentPatchVC.cpp | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Config/SilentPatchVC.ini b/Config/SilentPatchVC.ini index 49cd835..cc49594 100644 --- a/Config/SilentPatchVC.ini +++ b/Config/SilentPatchVC.ini @@ -123,6 +123,7 @@ nbt_htlpoolbar01 nbt_pizzaplace newbuild01 nhaiticar13 +od_chariot od_clevelander_dy od_clevelander_nt od_lightbeam @@ -138,6 +139,7 @@ sjmbigsig sjmbigsig2 sjmbigsign01 sjmbigsign02 +starblocks03 streetlamp1 streetlamp2 stripback diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 12b1a9c..d7c9f92 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -885,6 +885,22 @@ namespace ModelIndicesReadyHook } +// ============= Fix the outro splash flickering for a frame when fading in ============= +namespace OutroSplashFix +{ + struct RGBA + { + uint8_t r, g, b, a; + }; + + static RGBA* (__thiscall *orgRGBASet)(RGBA*, uint8_t, uint8_t, uint8_t, uint8_t); + static RGBA* __fastcall RGBASet_Clamp(RGBA* rgba, void*, int r, int g, int b, int a) + { + return orgRGBASet(rgba, static_cast(r), static_cast(g), static_cast(b), static_cast(std::clamp(a, 0, 255))); + } +} + + void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath ) { using namespace Memory; @@ -1843,6 +1859,35 @@ void Patch_VC_Common() InjectHook(entity_render.get(-7), EntityRender_BackfaceCulling, HookType::Jump); } TXN_CATCH(); + + + // Correct the duration of the outro splash to 2.5 seconds + // The outro splash displays for 150 ticks from the moment it fully fades in, with the tick cpimt supposedly incrementing every 10ms + // However, since the game is locked to 30FPS, the tick count actually increments every 33.3ms, so the splash takes around 5s + // Correct the "tick rate" to 33ms and the "tick count" to 75, so it is more or less 2.5s at 30FPS, + // and similarly long when running at 60FPS or uncapped. The original code hints at 1.5s, + // but that makes it hard to read the splash before it vanishes + // + // Also fix the splash flickering for a frame when fading in + try + { + using namespace OutroSplashFix; + + auto outro_tick_rate = get_pattern("83 F8 0A 76 10", 2); + auto outro_tick_count = get_pattern("81 3D ? ? ? ? 96 00 00 00", 6); + auto splash_rgba = get_pattern("E8 ? ? ? ? DB 05 ? ? ? ? 8D 54 24 2C"); + auto alpha_clamp = get_pattern("8A 83 ? ? ? ? 8D 4C 24 2C"); + + // Ideally, we want (time - lastTime) >= 33, but we can express the same with > 32 + Patch(outro_tick_rate, 32); + Patch(outro_tick_count, 75); + + InterceptCall(splash_rgba, orgRGBASet, RGBASet_Clamp); + + // al -> eax + Patch(alpha_clamp, 0x8B); + } + TXN_CATCH(); } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)