mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05:00
III/VC/SA: Fix sliding text leftovers causing texts to stay on screen for too long at high resolutions
Also introduced new INI/debug mode options to re-enable those cut features in all 3 games: * SlidingMissionTitleText * SlidingOddJobText
This commit is contained in:
parent
b6450d1853
commit
bee5b44af1
6 changed files with 453 additions and 3 deletions
|
@ -7,6 +7,11 @@ Units=-1
|
|||
; it also corrects taxi sign light placement on Taxi
|
||||
; and fixes placement of the search light of the search light on the police chopper.
|
||||
EnableVehicleCoronaFixes=1
|
||||
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
||||
SlidingMissionTitleText=0
|
||||
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
||||
; This behaviour was visible in one of the beta clips released for GTA III.
|
||||
SlidingOddJobText=0
|
||||
|
||||
[ExtraCompSpecularityExceptions]
|
||||
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras
|
||||
|
|
|
@ -27,6 +27,11 @@ TrueInvicibility=0
|
|||
; 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
|
||||
Units=-1
|
||||
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
||||
SlidingMissionTitleText=0
|
||||
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
||||
; This behaviour was visible in one of the beta clips released for GTA III.
|
||||
SlidingOddJobText=0
|
||||
|
||||
[RotorFixExceptions]
|
||||
; Put model IDs or names (one ID/name per line) here to exclude them from using blurred rotors
|
||||
|
|
|
@ -7,6 +7,11 @@ Units=-1
|
|||
; 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.
|
||||
EnableVehicleCoronaFixes=1
|
||||
; Enables the sliding mission title text, based on remnants of this feature in the game code.
|
||||
SlidingMissionTitleText=0
|
||||
; Enables the sliding odd job text, based on remnants of this feature in the game code.
|
||||
; This behaviour was visible in one of the beta clips released for GTA III.
|
||||
SlidingOddJobText=0
|
||||
|
||||
[ExtraCompSpecularityExceptions]
|
||||
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras
|
||||
|
|
|
@ -1010,6 +1010,67 @@ namespace CreditsScalingFixes
|
|||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_ScaleY);
|
||||
}
|
||||
|
||||
|
||||
// ============= Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature =============
|
||||
namespace SlidingTextsScalingFixes
|
||||
{
|
||||
static const unsigned int FIXED_RES_WIDTH_SCALE = 640;
|
||||
|
||||
static std::array<float, 6>* pBigMessageX;
|
||||
static float* pOddJob2XOffset;
|
||||
|
||||
template<std::size_t BigMessageIndex>
|
||||
struct BigMessageSlider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
static inline float** pHorShadowValue;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
if (bSlidingEnabled)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
fX = (*pBigMessageX)[BigMessageIndex] * RsGlobal->MaximumWidth / 640.0f;
|
||||
// The first draws are shadows, add the shadow offset manually. We know this function is called BEFORE the one fixing the shadow scale,
|
||||
// so we're fine with this approach.
|
||||
if constexpr (Index == 0)
|
||||
{
|
||||
fX += **pHorShadowValue;
|
||||
}
|
||||
}
|
||||
orgPrintString<Index>(fX, fY, pText);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
};
|
||||
|
||||
struct OddJob2Slider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
if (bSlidingEnabled)
|
||||
{
|
||||
fX -= *pOddJob2XOffset * RsGlobal->MaximumWidth / 640.0f;
|
||||
}
|
||||
orgPrintString<Index>(fX, fY, pText);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
};
|
||||
}
|
||||
|
||||
namespace ModelIndicesReadyHook
|
||||
{
|
||||
static void (*orgInitialiseObjectData)(const char*);
|
||||
|
@ -1310,6 +1371,67 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
|
|||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
// 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.
|
||||
try
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
// "Unscale" text sliding thresholds, so texts don't stay on screen longer at high resolutions
|
||||
auto scalingThreshold = pattern("A1 ? ? ? ? 59 83 C0 EC").count(2);
|
||||
|
||||
scalingThreshold.for_each_result([](pattern_match match)
|
||||
{
|
||||
Patch(match.get<void>(1), &FIXED_RES_WIDTH_SCALE);
|
||||
});
|
||||
|
||||
// Optional sliding texts
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingMissionTitleText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
// We need to manually add the shadow offset in this case
|
||||
pBigMessageX = *get_pattern<std::array<float, 6>*>("DB 44 24 20 D8 1D ? ? ? ? DF E0", 4 + 2);
|
||||
|
||||
auto bigMessage1ShadowPrint = pattern("D8 05 ? ? ? ? D9 1C 24 DD D8 E8 ? ? ? ? D9 05 ? ? ? ? D9 7C 24 0C").get_one();
|
||||
|
||||
std::array<void*, 2> slidingMessage1 = {
|
||||
bigMessage1ShadowPrint.get<void>(0xB),
|
||||
get_pattern("E8 ? ? ? ? 83 C4 0C EB 0A C7 05 ? ? ? ? ? ? ? ? 83 C4 68"),
|
||||
};
|
||||
|
||||
BigMessageSlider<1>::pHorShadowValue = bigMessage1ShadowPrint.get<float*>(2);
|
||||
BigMessageSlider<1>::bSlidingEnabled = INIoption != 0;
|
||||
BigMessageSlider<1>::HookEach_PrintString(slidingMessage1, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding mission title text", &BigMessageSlider<1>::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingOddJobText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
pOddJob2XOffset = *get_pattern<float*>("D9 05 ? ? ? ? D8 E1 D9 1D ? ? ? ? E9", 2);
|
||||
|
||||
std::array<void*, 2> slidingOddJob2 = {
|
||||
get_pattern("E8 ? ? ? ? 83 C4 0C 8D 4C 24 5C"),
|
||||
get_pattern("E8 ? ? ? ? 83 C4 0C 66 83 3D ? ? ? ? ? 0F 84"),
|
||||
};
|
||||
|
||||
OddJob2Slider::bSlidingEnabled = INIoption != 0;
|
||||
OddJob2Slider::HookEach_PrintString(slidingOddJob2, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding odd job text", &OddJob2Slider::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
FLAUtils::Init(moduleList);
|
||||
}
|
||||
|
||||
|
|
|
@ -2841,6 +2841,65 @@ namespace CreditsScalingFixes
|
|||
}
|
||||
|
||||
|
||||
// ============= Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature =============
|
||||
namespace SlidingTextsScalingFixes
|
||||
{
|
||||
static const unsigned int FIXED_RES_WIDTH_SCALE = 640;
|
||||
|
||||
static std::array<float, 6>* pBigMessageX;
|
||||
static float* pOddJob2XOffset;
|
||||
|
||||
template<std::size_t BigMessageIndex>
|
||||
struct BigMessageSlider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
orgPrintString<Index>(bSlidingEnabled ? (*pBigMessageX)[BigMessageIndex] * RsGlobal->MaximumWidth / 640.0f : fX, fY, pText);
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgSetRightJustifyWrap)(float wrap);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void SetRightJustifyWrap_Slide(float wrap)
|
||||
{
|
||||
orgSetRightJustifyWrap<Index>(bSlidingEnabled ? ScaleX(-500.0f) : wrap);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
HOOK_EACH_INIT(RightJustifyWrap, orgSetRightJustifyWrap, SetRightJustifyWrap_Slide);
|
||||
};
|
||||
|
||||
struct OddJob2Slider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
if (bSlidingEnabled)
|
||||
{
|
||||
fX -= *pOddJob2XOffset * RsGlobal->MaximumWidth / 640.0f;
|
||||
}
|
||||
orgPrintString<Index>(fX, fY, pText);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// ============= LS-RP Mode stuff =============
|
||||
namespace LSRPMode
|
||||
{
|
||||
|
@ -4227,6 +4286,47 @@ BOOL InjectDelayedPatches_10()
|
|||
}
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingMissionTitleText", -1, wcModulePath); INIoption != -1)
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
pBigMessageX = *(std::array<float, 6>**)(0x58C919 + 2);
|
||||
|
||||
std::array<uintptr_t, 1> slidingMessage1 = { 0x58D470 };
|
||||
|
||||
std::array<uintptr_t, 1> textWrapFix = { 0x58D2A9 };
|
||||
|
||||
BigMessageSlider<1>::bSlidingEnabled = INIoption != 0;
|
||||
BigMessageSlider<1>::HookEach_PrintString(slidingMessage1, InterceptCall);
|
||||
BigMessageSlider<1>::HookEach_RightJustifyWrap(textWrapFix, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding mission title text", &BigMessageSlider<1>::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingOddJobText", -1, wcModulePath); INIoption != -1)
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
pOddJob2XOffset = *(float**)(0x58D077 + 2);
|
||||
|
||||
std::array<uintptr_t, 1> slidingOddJob2 = { 0x58D21A };
|
||||
|
||||
OddJob2Slider::bSlidingEnabled = INIoption != 0;
|
||||
OddJob2Slider::HookEach_PrintString(slidingOddJob2, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding odd job text", &OddJob2Slider::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ( const int QPCDays = GetPrivateProfileIntW(L"Debug", L"AddDaysToQPC", 0, wcModulePath); QPCDays != 0 )
|
||||
{
|
||||
|
@ -4589,7 +4689,7 @@ BOOL InjectDelayedPatches_Steam()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL InjectDelayedPatches_Newsteam()
|
||||
BOOL InjectDelayedPatches_NewBinaries()
|
||||
{
|
||||
if ( !IsAlreadyRunning() )
|
||||
{
|
||||
|
@ -4600,6 +4700,13 @@ BOOL InjectDelayedPatches_Newsteam()
|
|||
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( hInstance, ".text" );
|
||||
ScopedUnprotect::Section Protect2( hInstance, ".rdata" );
|
||||
|
||||
// Obtain a path to the ASI
|
||||
wchar_t wcModulePath[MAX_PATH];
|
||||
GetModuleFileNameW(reinterpret_cast<HMODULE>(&__ImageBase), wcModulePath, _countof(wcModulePath) - 3); // Minus max required space for extension
|
||||
PathRenameExtensionW(wcModulePath, L".ini");
|
||||
|
||||
const bool bHasDebugMenu = DebugMenuLoad();
|
||||
|
||||
// Race condition in CdStream fixed
|
||||
// Not taking effect with modloader
|
||||
//if ( !ModCompat::ModloaderCdStreamRaceConditionAware( modloaderModule ) )
|
||||
|
@ -4648,6 +4755,54 @@ BOOL InjectDelayedPatches_Newsteam()
|
|||
}
|
||||
|
||||
|
||||
// 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.
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingMissionTitleText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
pBigMessageX = *get_pattern<std::array<float, 6>*>("8D 4E EC D9 05 ? ? ? ? 83 C4 04", 3 + 2);
|
||||
|
||||
std::array<void*, 1> slidingMessage1 = {
|
||||
get_pattern("E8 ? ? ? ? 6A 00 E8 ? ? ? ? 83 C4 10 8B E5"),
|
||||
};
|
||||
|
||||
std::array<void*, 1> textWrapFix = {
|
||||
get_pattern("E8 ? ? ? ? 6A 02 E8 ? ? ? ? 6A 03"),
|
||||
};
|
||||
|
||||
BigMessageSlider<1>::bSlidingEnabled = INIoption != 0;
|
||||
BigMessageSlider<1>::HookEach_PrintString(slidingMessage1, InterceptCall);
|
||||
BigMessageSlider<1>::HookEach_RightJustifyWrap(textWrapFix, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding mission title text", &BigMessageSlider<1>::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingOddJobText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
pOddJob2XOffset = *get_pattern<float*>("D9 05 ? ? ? ? DD 05 ? ? ? ? D8 F9", 2);
|
||||
|
||||
std::array<void*, 1> slidingOddJob2 = {
|
||||
get_pattern("DB 45 08 D9 1C 24 E8 ? ? ? ? 83 C4 0C 8B E5 5D C3", 6),
|
||||
};
|
||||
|
||||
OddJob2Slider::bSlidingEnabled = INIoption != 0;
|
||||
OddJob2Slider::HookEach_PrintString(slidingOddJob2, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding odd job text", &OddJob2Slider::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -5719,6 +5874,22 @@ void Patch_SA_10(HINSTANCE hInstance)
|
|||
}
|
||||
|
||||
|
||||
// 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.
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
// "Unscale" text sliding thresholds, so texts don't stay on screen longer at high resolutions
|
||||
Patch(0x58D2E9 + 1, &FIXED_RES_WIDTH_SCALE);
|
||||
|
||||
// Replace dword ptr [esp+0Ch+X], eax \ dword ptr [esp+0Ch+X]
|
||||
// with a constant fld [620.0]
|
||||
static const float f620 = FIXED_RES_WIDTH_SCALE - 20.0f;
|
||||
Patch(0x58C90E, { 0x90, 0x90, 0xD9, 0x05 });
|
||||
Patch(0x58C90E + 4, &f620);
|
||||
}
|
||||
|
||||
|
||||
#if FULL_PRECISION_D3D
|
||||
// Test - full precision D3D device
|
||||
Patch<uint8_t>( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE );
|
||||
|
@ -6486,7 +6657,7 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
|
|||
{
|
||||
void* isAlreadyRunning = get_pattern( "85 C0 74 08 33 C0 8B E5 5D C2 10 00", -5 );
|
||||
ReadCall( isAlreadyRunning, IsAlreadyRunning );
|
||||
InjectHook(isAlreadyRunning, InjectDelayedPatches_Newsteam);
|
||||
InjectHook(isAlreadyRunning, InjectDelayedPatches_NewBinaries);
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
@ -7777,6 +7948,27 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
|
|||
Patch(addr, &FIXED_RES_HEIGHT_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
try
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
// "Unscale" text sliding thresholds, so texts don't stay on screen longer at high resolutions
|
||||
auto bigMessage0Threshold = pattern("83 C4 04 89 4D F4 DB 45 F4").get_one();
|
||||
auto bigMessage1Threshold = get_pattern("A1 ? ? ? ? D9 05 ? ? ? ? 83 C0 EC", 1);
|
||||
|
||||
Patch(bigMessage1Threshold, &FIXED_RES_WIDTH_SCALE);
|
||||
|
||||
// Replace dword ptr [ebp+X], eax \ dword ptr [ebp+X]
|
||||
// with a constant fld [620.0]
|
||||
static const float f620 = FIXED_RES_WIDTH_SCALE - 20.0f;
|
||||
Patch(bigMessage0Threshold.get<void>(3), { 0xD9, 0x05 });
|
||||
Patch(bigMessage0Threshold.get<void>(3 + 2), &f620);
|
||||
}
|
||||
TXN_CATCH();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -467,6 +467,65 @@ namespace CreditsScalingFixes
|
|||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_ScaleY);
|
||||
}
|
||||
|
||||
|
||||
// ============= Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature =============
|
||||
namespace SlidingTextsScalingFixes
|
||||
{
|
||||
static const unsigned int FIXED_RES_WIDTH_SCALE = 640;
|
||||
|
||||
static std::array<float, 6>* pBigMessageX;
|
||||
static float* pOddJob2XOffset;
|
||||
|
||||
template<std::size_t BigMessageIndex>
|
||||
struct BigMessageSlider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
orgPrintString<Index>(bSlidingEnabled ? (*pBigMessageX)[BigMessageIndex] * RsGlobal->MaximumWidth / 640.0f : fX, fY, pText);
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgSetRightJustifyWrap)(float wrap);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void SetRightJustifyWrap_Slide(float wrap)
|
||||
{
|
||||
orgSetRightJustifyWrap<Index>(bSlidingEnabled ? -500.0f * GetWidthMult() * RsGlobal->MaximumWidth : wrap);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
HOOK_EACH_INIT(RightJustifyWrap, orgSetRightJustifyWrap, SetRightJustifyWrap_Slide);
|
||||
};
|
||||
|
||||
struct OddJob2Slider
|
||||
{
|
||||
static inline bool bSlidingEnabled = false;
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (*orgPrintString)(float,float,const wchar_t*);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
|
||||
{
|
||||
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
|
||||
if (bSlidingEnabled)
|
||||
{
|
||||
fX -= *pOddJob2XOffset * RsGlobal->MaximumWidth / 640.0f;
|
||||
}
|
||||
orgPrintString<Index>(fX, fY, pText);
|
||||
}
|
||||
|
||||
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
|
||||
};
|
||||
}
|
||||
|
||||
float FixedRefValue()
|
||||
{
|
||||
return 1.0f;
|
||||
|
@ -1250,7 +1309,7 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
|||
static const char * const str[] = { "Default", "Metric", "Imperial" };
|
||||
DebugMenuEntry *e = DebugMenuAddVar( "SilentPatch", "Forced units", &forcedUnits, nullptr, 1, -1, 1, str );
|
||||
DebugMenuEntrySetWrap(e, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1628,6 +1687,68 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
|||
}
|
||||
TXN_CATCH();
|
||||
|
||||
|
||||
// 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.
|
||||
try
|
||||
{
|
||||
using namespace SlidingTextsScalingFixes;
|
||||
|
||||
// "Unscale" text sliding thresholds, so texts don't stay on screen longer at high resolutions
|
||||
void* scalingThreshold[] = {
|
||||
get_pattern("A1 ? ? ? ? 59 83 C0 EC", 1),
|
||||
get_pattern("59 A1 ? ? ? ? 83 C0 EC", 1 + 1)
|
||||
};
|
||||
|
||||
for (void* addr : scalingThreshold)
|
||||
{
|
||||
Patch(addr, &FIXED_RES_WIDTH_SCALE);
|
||||
}
|
||||
|
||||
// Optional sliding texts
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingMissionTitleText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
pBigMessageX = *get_pattern<std::array<float, 6>*>("DB 44 24 68 D8 1D ? ? ? ? DF E0", 4 + 2);
|
||||
|
||||
std::array<void*, 1> slidingMessage1 = {
|
||||
get_pattern("E8 ? ? ? ? 83 C4 0C EB 0A C7 05 ? ? ? ? ? ? ? ? 83 C4 60"),
|
||||
};
|
||||
|
||||
std::array<void*, 1> textWrapFix = {
|
||||
get_pattern("E8 ? ? ? ? 59 E8 ? ? ? ? 6A 00 E8 ? ? ? ? 59 8B 0D"),
|
||||
};
|
||||
|
||||
BigMessageSlider<1>::bSlidingEnabled = INIoption != 0;
|
||||
BigMessageSlider<1>::HookEach_PrintString(slidingMessage1, InterceptCall);
|
||||
BigMessageSlider<1>::HookEach_RightJustifyWrap(textWrapFix, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding mission title text", &BigMessageSlider<1>::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingOddJobText", -1, wcModulePath); INIoption != -1) try
|
||||
{
|
||||
pOddJob2XOffset = *get_pattern<float*>("D9 05 ? ? ? ? D8 E1 D9 1D ? ? ? ? E9", 2);
|
||||
|
||||
std::array<void*, 1> slidingOddJob2 = {
|
||||
get_pattern("E8 ? ? ? ? 83 C4 0C 66 83 3D ? ? ? ? ? 0F 84"),
|
||||
};
|
||||
|
||||
OddJob2Slider::bSlidingEnabled = INIoption != 0;
|
||||
OddJob2Slider::HookEach_PrintString(slidingOddJob2, InterceptCall);
|
||||
|
||||
if (bHasDebugMenu)
|
||||
{
|
||||
DebugMenuAddVar("SilentPatch", "Sliding odd job text", &OddJob2Slider::bSlidingEnabled, nullptr);
|
||||
}
|
||||
}
|
||||
TXN_CATCH();
|
||||
}
|
||||
TXN_CATCH();
|
||||
|
||||
FLAUtils::Init(moduleList);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue