@@ -526,6 +526,59 @@ namespace SlidingTextsScalingFixes
526526 };
527527}
528528
529+
530+ // ============= Minimal HUD changes =============
531+ namespace MinimalHUD
532+ {
533+ // Wanted level stars
534+ static void (*orgSetDropShadowPosition)(short );
535+ static void (*orgSetDropColor)(const CRGBA&);
536+
537+ static int8_t * pDropShadowSize;
538+ static int8_t * pDropShadowR;
539+ static int8_t * pDropShadowG;
540+ static int8_t * pDropShadowB;
541+
542+ static void (*orgSetColor)(const CRGBA&);
543+ static void SetColor_SetShadow (const CRGBA& color)
544+ {
545+ orgSetDropShadowPosition (*pDropShadowSize);
546+ orgSetDropColor (CRGBA (*pDropShadowR, *pDropShadowG, *pDropShadowB, color.a ));
547+ orgSetColor (color);
548+ }
549+
550+
551+ // Show the energy values when losing armor
552+ static uint8_t * pPlayerInFocus;
553+ static uint32_t * pTimeLastArmorLoss;
554+
555+ static uint32_t LastTimeArmorLost;
556+
557+ static float (*orgDrawFadeState)(int state, int force);
558+ static float DrawFadeState_CheckArmor (int state, int force)
559+ {
560+ // This is a bit hacky, but we don't necessarily need better right now
561+ if (pTimeLastArmorLoss[92 * *pPlayerInFocus] != LastTimeArmorLost)
562+ {
563+ force = 1 ;
564+ LastTimeArmorLost = pTimeLastArmorLoss[92 * *pPlayerInFocus];
565+ }
566+ return orgDrawFadeState (state, force);
567+ }
568+
569+
570+ // Fade the weapon icon - fix the render state and pass the alpha parameter
571+ static void (*orgRenderOneXLUSprite)(float , float , float , float , float , uint8_t , uint8_t , uint8_t , int16_t , float , uint8_t );
572+ static void RenderOneXLUSprite_FloatAlpha (float arg1, float arg2, float arg3, float arg4, float arg5, uint8_t red, uint8_t green, uint8_t blue, int16_t mult, float arg10, float alpha)
573+ {
574+ RwScopedRenderState<rwRENDERSTATEVERTEXALPHAENABLE> vertexAlpha;
575+ RwRenderStateSet (rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE );
576+
577+ orgRenderOneXLUSprite (arg1, arg2, arg3, arg4, arg5, red, green, blue, mult, arg10, static_cast <uint8_t >(alpha));
578+ }
579+ }
580+
581+
529582float FixedRefValue ()
530583{
531584 return 1 .0f ;
@@ -1688,6 +1741,116 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
16881741 TXN_CATCH ();
16891742
16901743
1744+ // Minimal HUD
1745+ if (const int INIoption = GetPrivateProfileIntW (L" SilentPatch" , L" MinimalHUD" , -1 , wcModulePath); INIoption != -1 ) try
1746+ {
1747+ using namespace MinimalHUD ;
1748+
1749+ // Fix original bugs
1750+
1751+ // Wanted level stars losing their shadow if health/armour counters are off
1752+ auto setColor_WantedStars = get_pattern (" E8 ? ? ? ? DB 05 ? ? ? ? 8D 84 24 ? ? ? ? 59 50 50 D8 0D ? ? ? ? D8 0D ? ? ? ? D9 1C 24 FF 74 24 24" );
1753+
1754+ // Get SetDropShadowPosition and SetDropColor with their corresponding parameters straight from the armor counter,
1755+ // to preserve the current behaviour
1756+ auto setDropShadow = pattern (" 6A ? E8 ? ? ? ? 59 8D 8C 24 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 6A ? E8 ? ? ? ? 8D 84 24 ? ? ? ? 50 E8" ).get_one ();
1757+
1758+
1759+ // Show the energy values when losing armor
1760+ auto drawFadeState_Energy = get_pattern (" 6A 01 E8 ? ? ? ? DD D8" , 2 );
1761+
1762+ auto timeLastArmorLoss = pattern (" 0F B6 15 ? ? ? ? A1 ? ? ? ? 6B D2 2E 89 04 D5 ? ? ? ? D9 83" ).get_one ();
1763+
1764+
1765+ // Fade the weapon icon - fix the render state and pass the alpha parameter
1766+ auto drawWeaponIconAlphaPush = get_pattern (" 68 FF 00 00 00 D8 0D ? ? ? ? FF 35" );
1767+ auto renderOneXLUSprite = get_pattern (" E8 ? ? ? ? 83 C4 2C 6A 00 6A 08" );
1768+
1769+
1770+ // Stuff to let us (re)initialize
1771+ static void (*HUDReInitialise)() = static_cast <decltype (HUDReInitialise)>(get_pattern (" 31 C0 53 0F EF C0 C6 05" ));
1772+
1773+ // This pattern has 5 hits - first 2 are in Reinitialise, the rest is in Initialise
1774+ auto reinitialise1 = pattern (" C7 05 ? ? ? ? 05 00 00 00 66 C7 05 ? ? ? ? 00 00 C7 05 ? ? ? ? 00 00 00 00" ).count (5 );
1775+
1776+ // This one covers the rest of Reinitialise
1777+ auto reinitialise2 = pattern (" C7 05 ? ? ? ? 05 00 00 00 C6 05 ? ? ? ? 00 C7 05 ? ? ? ? 00 00 00 00" ).count (2 );
1778+
1779+ // This one we touch only once, no need for static
1780+ const std::array<uint32_t *, 4 > hudInitialiseVariables = {
1781+ reinitialise1.get (2 ).get <uint32_t >(6 ),
1782+ reinitialise1.get (3 ).get <uint32_t >(6 ),
1783+ reinitialise1.get (4 ).get <uint32_t >(6 ),
1784+
1785+ get_pattern<uint32_t >(" 8B 83 ? ? ? ? C7 05 ? ? ? ? 05 00 00 00" , 6 + 6 ),
1786+ };
1787+
1788+ static const std::array<uint32_t *, 4 > hudReinitialiseVariables = {
1789+ reinitialise1.get (0 ).get <uint32_t >(6 ),
1790+ reinitialise1.get (1 ).get <uint32_t >(6 ),
1791+
1792+ reinitialise2.get (0 ).get <uint32_t >(6 ),
1793+ reinitialise2.get (1 ).get <uint32_t >(6 ),
1794+ };
1795+
1796+
1797+ ReadCall (setDropShadow.get <void >(2 ), orgSetDropShadowPosition);
1798+ ReadCall (setDropShadow.get <void >(39 ), orgSetDropColor);
1799+ pDropShadowSize = setDropShadow.get <int8_t >(1 );
1800+ pDropShadowB = setDropShadow.get <int8_t >(20 + 1 );
1801+ pDropShadowG = setDropShadow.get <int8_t >(22 + 1 );
1802+ pDropShadowR = setDropShadow.get <int8_t >(24 + 1 );
1803+ InterceptCall (setColor_WantedStars, orgSetColor, SetColor_SetShadow);
1804+
1805+
1806+ pPlayerInFocus = *timeLastArmorLoss.get <uint8_t *>(3 );
1807+ pTimeLastArmorLoss = *timeLastArmorLoss.get <uint32_t *>(0xF + 3 );
1808+ InterceptCall (drawFadeState_Energy, orgDrawFadeState, DrawFadeState_CheckArmor);
1809+
1810+
1811+ // push 0FFh -> push dword ptr [esp+520h+var_4E0]
1812+ Patch (drawWeaponIconAlphaPush, { 0x90 , 0xFF , 0x74 , 0x24 , 0x40 });
1813+ InterceptCall (renderOneXLUSprite, orgRenderOneXLUSprite, RenderOneXLUSprite_FloatAlpha);
1814+
1815+ if (INIoption != 0 )
1816+ {
1817+ for (uint32_t * var : hudInitialiseVariables)
1818+ {
1819+ Patch<uint32_t >(var, 0 );
1820+ }
1821+ for (uint32_t * var : hudReinitialiseVariables)
1822+ {
1823+ Patch<uint32_t >(var, 0 );
1824+ }
1825+ }
1826+
1827+ if (bHasDebugMenu)
1828+ {
1829+ static bool bMinimalHUDEnabled = INIoption != 0 ;
1830+ DebugMenuAddVar (" SilentPatch" , " Minimal HUD" , &bMinimalHUDEnabled, [] {
1831+ if (bMinimalHUDEnabled)
1832+ {
1833+ for (uint32_t * var : hudReinitialiseVariables)
1834+ {
1835+ Memory::VP::Patch<uint32_t >(var, 0 );
1836+ }
1837+ }
1838+ else
1839+ {
1840+ for (uint32_t * var : hudReinitialiseVariables)
1841+ {
1842+ Memory::VP::Patch<uint32_t >(var, 5 );
1843+ }
1844+ }
1845+
1846+ // Call CHud::ReInitialise
1847+ HUDReInitialise ();
1848+ });
1849+ }
1850+ }
1851+ TXN_CATCH ();
1852+
1853+
16911854 // Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature
16921855 // Also since we're touching it, optionally allow to re-enable this feature.
16931856 try
0 commit comments