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
|
; it also corrects taxi sign light placement on Taxi
|
||||||
; and fixes placement of the search light of the search light on the police chopper.
|
; and fixes placement of the search light of the search light on the police chopper.
|
||||||
EnableVehicleCoronaFixes=1
|
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]
|
[ExtraCompSpecularityExceptions]
|
||||||
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras
|
; 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,
|
; 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 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]
|
[RotorFixExceptions]
|
||||||
; Put model IDs or names (one ID/name per line) here to exclude them from using blurred rotors
|
; 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
|
; 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 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]
|
[ExtraCompSpecularityExceptions]
|
||||||
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras
|
; 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);
|
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
|
namespace ModelIndicesReadyHook
|
||||||
{
|
{
|
||||||
static void (*orgInitialiseObjectData)(const char*);
|
static void (*orgInitialiseObjectData)(const char*);
|
||||||
|
@ -1310,6 +1371,67 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
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);
|
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 =============
|
// ============= LS-RP Mode stuff =============
|
||||||
namespace LSRPMode
|
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
|
#ifndef NDEBUG
|
||||||
if ( const int QPCDays = GetPrivateProfileIntW(L"Debug", L"AddDaysToQPC", 0, wcModulePath); QPCDays != 0 )
|
if ( const int QPCDays = GetPrivateProfileIntW(L"Debug", L"AddDaysToQPC", 0, wcModulePath); QPCDays != 0 )
|
||||||
{
|
{
|
||||||
|
@ -4589,7 +4689,7 @@ BOOL InjectDelayedPatches_Steam()
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL InjectDelayedPatches_Newsteam()
|
BOOL InjectDelayedPatches_NewBinaries()
|
||||||
{
|
{
|
||||||
if ( !IsAlreadyRunning() )
|
if ( !IsAlreadyRunning() )
|
||||||
{
|
{
|
||||||
|
@ -4600,6 +4700,13 @@ BOOL InjectDelayedPatches_Newsteam()
|
||||||
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( hInstance, ".text" );
|
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( hInstance, ".text" );
|
||||||
ScopedUnprotect::Section Protect2( hInstance, ".rdata" );
|
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
|
// Race condition in CdStream fixed
|
||||||
// Not taking effect with modloader
|
// Not taking effect with modloader
|
||||||
//if ( !ModCompat::ModloaderCdStreamRaceConditionAware( modloaderModule ) )
|
//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 FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
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
|
#if FULL_PRECISION_D3D
|
||||||
// Test - full precision D3D device
|
// Test - full precision D3D device
|
||||||
Patch<uint8_t>( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE );
|
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 );
|
void* isAlreadyRunning = get_pattern( "85 C0 74 08 33 C0 8B E5 5D C2 10 00", -5 );
|
||||||
ReadCall( isAlreadyRunning, IsAlreadyRunning );
|
ReadCall( isAlreadyRunning, IsAlreadyRunning );
|
||||||
InjectHook(isAlreadyRunning, InjectDelayedPatches_Newsteam);
|
InjectHook(isAlreadyRunning, InjectDelayedPatches_NewBinaries);
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
|
|
||||||
|
@ -7777,6 +7948,27 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
|
||||||
Patch(addr, &FIXED_RES_HEIGHT_SCALE);
|
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);
|
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()
|
float FixedRefValue()
|
||||||
{
|
{
|
||||||
return 1.0f;
|
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" };
|
static const char * const str[] = { "Default", "Metric", "Imperial" };
|
||||||
DebugMenuEntry *e = DebugMenuAddVar( "SilentPatch", "Forced units", &forcedUnits, nullptr, 1, -1, 1, str );
|
DebugMenuEntry *e = DebugMenuAddVar( "SilentPatch", "Forced units", &forcedUnits, nullptr, 1, -1, 1, str );
|
||||||
DebugMenuEntrySetWrap(e, true);
|
DebugMenuEntrySetWrap(e, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1628,6 +1687,68 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
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);
|
FLAUtils::Init(moduleList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue