mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05:00
VC/SA: Add Minimal HUD to VC, document it in SA
This commit is contained in:
parent
8301635efc
commit
3d205cdf95
4 changed files with 175 additions and 6 deletions
|
@ -27,6 +27,9 @@ TrueInvincibility=0
|
||||||
; Allows to override units used by the game - 0 forces metric units, 1 forces imperial units,
|
; Allows to override units used by the game - 0 forces metric units, 1 forces imperial units,
|
||||||
; -1 makes the game use units based on system locale
|
; -1 makes the game use units based on system locale
|
||||||
Units=-1
|
Units=-1
|
||||||
|
; Enables an unfinished "minimal HUD" feature, where health, armour, weapon and money UI elements
|
||||||
|
; fade out when inactive.
|
||||||
|
MinimalHUD=0
|
||||||
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
||||||
SlidingMissionTitleText=0
|
SlidingMissionTitleText=0
|
||||||
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
||||||
|
|
|
@ -7,6 +7,9 @@ Units=-1
|
||||||
; it also adds a siren to FBI Washington, corrects taxi sign light placement on Taxi
|
; it also adds a siren to FBI Washington, corrects taxi sign light placement on Taxi
|
||||||
; and fixes placement of the search light and rear rotor light on Police Maverick.
|
; and fixes placement of the search light and rear rotor light on Police Maverick.
|
||||||
EnableVehicleCoronaFixes=1
|
EnableVehicleCoronaFixes=1
|
||||||
|
; Enables an unfinished "minimal HUD" feature, where health, armour, weapon and money UI elements
|
||||||
|
; fade out when inactive.
|
||||||
|
MinimalHUD=0
|
||||||
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
||||||
SlidingMissionTitleText=0
|
SlidingMissionTitleText=0
|
||||||
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
||||||
|
|
|
@ -1457,8 +1457,8 @@ static int64_t AudioUtilsGetCurrentTimeInMs()
|
||||||
return ((currentTime.QuadPart - UtilsStartTime.QuadPart) * 1000) / UtilsFrequency.QuadPart;
|
return ((currentTime.QuadPart - UtilsStartTime.QuadPart) * 1000) / UtilsFrequency.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minimal HUD changes
|
// ============= Minimal HUD changes =============
|
||||||
namespace MinimalHud
|
namespace MinimalHUD
|
||||||
{
|
{
|
||||||
static CRGBA* __fastcall SetRGBA_FloatAlpha( CRGBA* rgba, void*, uint8_t red, uint8_t green, uint8_t blue, float alpha )
|
static CRGBA* __fastcall SetRGBA_FloatAlpha( CRGBA* rgba, void*, uint8_t red, uint8_t green, uint8_t blue, float alpha )
|
||||||
{
|
{
|
||||||
|
@ -4146,9 +4146,9 @@ BOOL InjectDelayedPatches_10()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minimal HUD
|
// Minimal HUD
|
||||||
if ( const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"MinimalHud", -1, wcModulePath); INIoption != -1 )
|
if ( const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"MinimalHUD", -1, wcModulePath); INIoption != -1 )
|
||||||
{
|
{
|
||||||
using namespace MinimalHud;
|
using namespace MinimalHUD;
|
||||||
|
|
||||||
// Fix original bugs
|
// Fix original bugs
|
||||||
Patch( 0x58950E, { 0x90, 0xFF, 0x74, 0x24, 0x1C } );
|
Patch( 0x58950E, { 0x90, 0xFF, 0x74, 0x24, 0x1C } );
|
||||||
|
@ -4159,14 +4159,14 @@ BOOL InjectDelayedPatches_10()
|
||||||
InjectHook( 0x58D8FD, &RenderXLUSprite_FloatAlpha );
|
InjectHook( 0x58D8FD, &RenderXLUSprite_FloatAlpha );
|
||||||
|
|
||||||
// Re-enable
|
// Re-enable
|
||||||
if ( INIoption == 1 )
|
if ( INIoption != 0 )
|
||||||
{
|
{
|
||||||
Patch<int32_t>( 0x588905 + 1, 0 );
|
Patch<int32_t>( 0x588905 + 1, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bHasDebugMenu )
|
if ( bHasDebugMenu )
|
||||||
{
|
{
|
||||||
static bool bMinimalHUDEnabled = INIoption == 1;
|
static bool bMinimalHUDEnabled = INIoption != 0;
|
||||||
DebugMenuAddVar( "SilentPatch", "Minimal HUD", &bMinimalHUDEnabled, []() {
|
DebugMenuAddVar( "SilentPatch", "Minimal HUD", &bMinimalHUDEnabled, []() {
|
||||||
if ( bMinimalHUDEnabled )
|
if ( bMinimalHUDEnabled )
|
||||||
{
|
{
|
||||||
|
|
|
@ -526,6 +526,59 @@ namespace SlidingTextsScalingFixes
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============= Minimal HUD changes =============
|
||||||
|
namespace MinimalHUD
|
||||||
|
{
|
||||||
|
// Wanted level stars
|
||||||
|
static void (*orgSetDropShadowPosition)(short);
|
||||||
|
static void (*orgSetDropColor)(const CRGBA&);
|
||||||
|
|
||||||
|
static int8_t* pDropShadowSize;
|
||||||
|
static int8_t* pDropShadowR;
|
||||||
|
static int8_t* pDropShadowG;
|
||||||
|
static int8_t* pDropShadowB;
|
||||||
|
|
||||||
|
static void (*orgSetColor)(const CRGBA&);
|
||||||
|
static void SetColor_SetShadow(const CRGBA& color)
|
||||||
|
{
|
||||||
|
orgSetDropShadowPosition(*pDropShadowSize);
|
||||||
|
orgSetDropColor(CRGBA(*pDropShadowR, *pDropShadowG, *pDropShadowB, color.a));
|
||||||
|
orgSetColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Show the energy values when losing armor
|
||||||
|
static uint8_t* pPlayerInFocus;
|
||||||
|
static uint32_t* pTimeLastArmorLoss;
|
||||||
|
|
||||||
|
static uint32_t LastTimeArmorLost;
|
||||||
|
|
||||||
|
static float (*orgDrawFadeState)(int state, int force);
|
||||||
|
static float DrawFadeState_CheckArmor(int state, int force)
|
||||||
|
{
|
||||||
|
// This is a bit hacky, but we don't necessarily need better right now
|
||||||
|
if (pTimeLastArmorLoss[92 * *pPlayerInFocus] != LastTimeArmorLost)
|
||||||
|
{
|
||||||
|
force = 1;
|
||||||
|
LastTimeArmorLost = pTimeLastArmorLoss[92 * *pPlayerInFocus];
|
||||||
|
}
|
||||||
|
return orgDrawFadeState(state, force);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fade the weapon icon - fix the render state and pass the alpha parameter
|
||||||
|
static void (*orgRenderOneXLUSprite)(float, float, float, float, float, uint8_t, uint8_t, uint8_t, int16_t, float, uint8_t);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
RwScopedRenderState<rwRENDERSTATEVERTEXALPHAENABLE> vertexAlpha;
|
||||||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||||
|
|
||||||
|
orgRenderOneXLUSprite(arg1, arg2, arg3, arg4, arg5, red, green, blue, mult, arg10, static_cast<uint8_t>(alpha));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float FixedRefValue()
|
float FixedRefValue()
|
||||||
{
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
@ -1688,6 +1741,116 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
|
// Minimal HUD
|
||||||
|
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"MinimalHUD", -1, wcModulePath); INIoption != -1) try
|
||||||
|
{
|
||||||
|
using namespace MinimalHUD;
|
||||||
|
|
||||||
|
// Fix original bugs
|
||||||
|
|
||||||
|
// Wanted level stars losing their shadow if health/armour counters are off
|
||||||
|
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");
|
||||||
|
|
||||||
|
// Get SetDropShadowPosition and SetDropColor with their corresponding parameters straight from the armor counter,
|
||||||
|
// to preserve the current behaviour
|
||||||
|
auto setDropShadow = pattern("6A ? E8 ? ? ? ? 59 8D 8C 24 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 6A ? E8 ? ? ? ? 8D 84 24 ? ? ? ? 50 E8").get_one();
|
||||||
|
|
||||||
|
|
||||||
|
// Show the energy values when losing armor
|
||||||
|
auto drawFadeState_Energy = get_pattern("6A 01 E8 ? ? ? ? DD D8", 2);
|
||||||
|
|
||||||
|
auto timeLastArmorLoss = pattern("0F B6 15 ? ? ? ? A1 ? ? ? ? 6B D2 2E 89 04 D5 ? ? ? ? D9 83").get_one();
|
||||||
|
|
||||||
|
|
||||||
|
// Fade the weapon icon - fix the render state and pass the alpha parameter
|
||||||
|
auto drawWeaponIconAlphaPush = get_pattern("68 FF 00 00 00 D8 0D ? ? ? ? FF 35");
|
||||||
|
auto renderOneXLUSprite = get_pattern("E8 ? ? ? ? 83 C4 2C 6A 00 6A 08");
|
||||||
|
|
||||||
|
|
||||||
|
// Stuff to let us (re)initialize
|
||||||
|
static void (*HUDReInitialise)() = static_cast<decltype(HUDReInitialise)>(get_pattern("31 C0 53 0F EF C0 C6 05"));
|
||||||
|
|
||||||
|
// This pattern has 5 hits - first 2 are in Reinitialise, the rest is in Initialise
|
||||||
|
auto reinitialise1 = pattern("C7 05 ? ? ? ? 05 00 00 00 66 C7 05 ? ? ? ? 00 00 C7 05 ? ? ? ? 00 00 00 00").count(5);
|
||||||
|
|
||||||
|
// This one covers the rest of Reinitialise
|
||||||
|
auto reinitialise2 = pattern("C7 05 ? ? ? ? 05 00 00 00 C6 05 ? ? ? ? 00 C7 05 ? ? ? ? 00 00 00 00").count(2);
|
||||||
|
|
||||||
|
// This one we touch only once, no need for static
|
||||||
|
const std::array<uint32_t*, 4> hudInitialiseVariables = {
|
||||||
|
reinitialise1.get(2).get<uint32_t>(6),
|
||||||
|
reinitialise1.get(3).get<uint32_t>(6),
|
||||||
|
reinitialise1.get(4).get<uint32_t>(6),
|
||||||
|
|
||||||
|
get_pattern<uint32_t>("8B 83 ? ? ? ? C7 05 ? ? ? ? 05 00 00 00", 6 + 6),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::array<uint32_t*, 4> hudReinitialiseVariables = {
|
||||||
|
reinitialise1.get(0).get<uint32_t>(6),
|
||||||
|
reinitialise1.get(1).get<uint32_t>(6),
|
||||||
|
|
||||||
|
reinitialise2.get(0).get<uint32_t>(6),
|
||||||
|
reinitialise2.get(1).get<uint32_t>(6),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ReadCall(setDropShadow.get<void>(2), orgSetDropShadowPosition);
|
||||||
|
ReadCall(setDropShadow.get<void>(39), orgSetDropColor);
|
||||||
|
pDropShadowSize = setDropShadow.get<int8_t>(1);
|
||||||
|
pDropShadowB = setDropShadow.get<int8_t>(20 + 1);
|
||||||
|
pDropShadowG = setDropShadow.get<int8_t>(22 + 1);
|
||||||
|
pDropShadowR = setDropShadow.get<int8_t>(24 + 1);
|
||||||
|
InterceptCall(setColor_WantedStars, orgSetColor, SetColor_SetShadow);
|
||||||
|
|
||||||
|
|
||||||
|
pPlayerInFocus = *timeLastArmorLoss.get<uint8_t*>(3);
|
||||||
|
pTimeLastArmorLoss = *timeLastArmorLoss.get<uint32_t*>(0xF + 3);
|
||||||
|
InterceptCall(drawFadeState_Energy, orgDrawFadeState, DrawFadeState_CheckArmor);
|
||||||
|
|
||||||
|
|
||||||
|
// push 0FFh -> push dword ptr [esp+520h+var_4E0]
|
||||||
|
Patch(drawWeaponIconAlphaPush, { 0x90, 0xFF, 0x74, 0x24, 0x40 });
|
||||||
|
InterceptCall(renderOneXLUSprite, orgRenderOneXLUSprite, RenderOneXLUSprite_FloatAlpha);
|
||||||
|
|
||||||
|
if (INIoption != 0)
|
||||||
|
{
|
||||||
|
for (uint32_t* var : hudInitialiseVariables)
|
||||||
|
{
|
||||||
|
Patch<uint32_t>(var, 0);
|
||||||
|
}
|
||||||
|
for (uint32_t* var : hudReinitialiseVariables)
|
||||||
|
{
|
||||||
|
Patch<uint32_t>(var, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bHasDebugMenu)
|
||||||
|
{
|
||||||
|
static bool bMinimalHUDEnabled = INIoption != 0;
|
||||||
|
DebugMenuAddVar("SilentPatch", "Minimal HUD", &bMinimalHUDEnabled, [] {
|
||||||
|
if (bMinimalHUDEnabled)
|
||||||
|
{
|
||||||
|
for (uint32_t* var : hudReinitialiseVariables)
|
||||||
|
{
|
||||||
|
Memory::VP::Patch<uint32_t>(var, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint32_t* var : hudReinitialiseVariables)
|
||||||
|
{
|
||||||
|
Memory::VP::Patch<uint32_t>(var, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call CHud::ReInitialise
|
||||||
|
HUDReInitialise();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
// Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature
|
// Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature
|
||||||
// Also since we're touching it, optionally allow to re-enable this feature.
|
// Also since we're touching it, optionally allow to re-enable this feature.
|
||||||
try
|
try
|
||||||
|
|
Loading…
Reference in a new issue