Skip to content

Commit bee5b44

Browse files
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
1 parent b6450d1 commit bee5b44

File tree

6 files changed

+453
-3
lines changed

6 files changed

+453
-3
lines changed

Config/SilentPatchIII.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ Units=-1
77
; it also corrects taxi sign light placement on Taxi
88
; and fixes placement of the search light of the search light on the police chopper.
99
EnableVehicleCoronaFixes=1
10+
; Enables the sliding mission title text, based on remnants of this feature in the game code.
11+
SlidingMissionTitleText=0
12+
; Enables the sliding odd job text, based on remnants of this feature in the game code.
13+
; This behaviour was visible in one of the beta clips released for GTA III.
14+
SlidingOddJobText=0
1015

1116
[ExtraCompSpecularityExceptions]
1217
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras

Config/SilentPatchSA.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ TrueInvicibility=0
2727
; Allows to override units used by the game - 0 forces metric units, 1 forces imperial units,
2828
; -1 makes the game use units based on system locale
2929
Units=-1
30+
; Enables the sliding mission title text, based on remnants of this feature in the game code.
31+
SlidingMissionTitleText=0
32+
; Enables the sliding odd job text, based on remnants of this feature in the game code.
33+
; This behaviour was visible in one of the beta clips released for GTA III.
34+
SlidingOddJobText=0
3035

3136
[RotorFixExceptions]
3237
; Put model IDs or names (one ID/name per line) here to exclude them from using blurred rotors

Config/SilentPatchVC.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ Units=-1
77
; it also adds a siren to FBI Washington, corrects taxi sign light placement on Taxi
88
; and fixes placement of the search light and rear rotor light on Police Maverick.
99
EnableVehicleCoronaFixes=1
10+
; Enables the sliding mission title text, based on remnants of this feature in the game code.
11+
SlidingMissionTitleText=0
12+
; Enables the sliding odd job text, based on remnants of this feature in the game code.
13+
; This behaviour was visible in one of the beta clips released for GTA III.
14+
SlidingOddJobText=0
1015

1116
[ExtraCompSpecularityExceptions]
1217
; Put model IDs or names (one ID/name per line) here to forcibly disable specularity on their extras

SilentPatchIII/SilentPatchIII.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,67 @@ namespace CreditsScalingFixes
10101010
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_ScaleY);
10111011
}
10121012

1013+
1014+
// ============= Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature =============
1015+
namespace SlidingTextsScalingFixes
1016+
{
1017+
static const unsigned int FIXED_RES_WIDTH_SCALE = 640;
1018+
1019+
static std::array<float, 6>* pBigMessageX;
1020+
static float* pOddJob2XOffset;
1021+
1022+
template<std::size_t BigMessageIndex>
1023+
struct BigMessageSlider
1024+
{
1025+
static inline bool bSlidingEnabled = false;
1026+
1027+
static inline float** pHorShadowValue;
1028+
1029+
template<std::size_t Index>
1030+
static void (*orgPrintString)(float,float,const wchar_t*);
1031+
1032+
template<std::size_t Index>
1033+
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
1034+
{
1035+
if (bSlidingEnabled)
1036+
{
1037+
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
1038+
fX = (*pBigMessageX)[BigMessageIndex] * RsGlobal->MaximumWidth / 640.0f;
1039+
// The first draws are shadows, add the shadow offset manually. We know this function is called BEFORE the one fixing the shadow scale,
1040+
// so we're fine with this approach.
1041+
if constexpr (Index == 0)
1042+
{
1043+
fX += **pHorShadowValue;
1044+
}
1045+
}
1046+
orgPrintString<Index>(fX, fY, pText);
1047+
}
1048+
1049+
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
1050+
};
1051+
1052+
struct OddJob2Slider
1053+
{
1054+
static inline bool bSlidingEnabled = false;
1055+
1056+
template<std::size_t Index>
1057+
static void (*orgPrintString)(float,float,const wchar_t*);
1058+
1059+
template<std::size_t Index>
1060+
static void PrintString_Slide(float fX, float fY, const wchar_t* pText)
1061+
{
1062+
// We divide by a constant 640.0, because the X position is meant to slide across the entire screen
1063+
if (bSlidingEnabled)
1064+
{
1065+
fX -= *pOddJob2XOffset * RsGlobal->MaximumWidth / 640.0f;
1066+
}
1067+
orgPrintString<Index>(fX, fY, pText);
1068+
}
1069+
1070+
HOOK_EACH_INIT(PrintString, orgPrintString, PrintString_Slide);
1071+
};
1072+
}
1073+
10131074
namespace ModelIndicesReadyHook
10141075
{
10151076
static void (*orgInitialiseObjectData)(const char*);
@@ -1310,6 +1371,67 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
13101371
}
13111372
TXN_CATCH();
13121373

1374+
1375+
// Fix some big messages staying on screen longer at high resolutions due to a cut sliding text feature
1376+
// Also since we're touching it, optionally allow to re-enable this feature.
1377+
try
1378+
{
1379+
using namespace SlidingTextsScalingFixes;
1380+
1381+
// "Unscale" text sliding thresholds, so texts don't stay on screen longer at high resolutions
1382+
auto scalingThreshold = pattern("A1 ? ? ? ? 59 83 C0 EC").count(2);
1383+
1384+
scalingThreshold.for_each_result([](pattern_match match)
1385+
{
1386+
Patch(match.get<void>(1), &FIXED_RES_WIDTH_SCALE);
1387+
});
1388+
1389+
// Optional sliding texts
1390+
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingMissionTitleText", -1, wcModulePath); INIoption != -1) try
1391+
{
1392+
// We need to manually add the shadow offset in this case
1393+
pBigMessageX = *get_pattern<std::array<float, 6>*>("DB 44 24 20 D8 1D ? ? ? ? DF E0", 4 + 2);
1394+
1395+
auto bigMessage1ShadowPrint = pattern("D8 05 ? ? ? ? D9 1C 24 DD D8 E8 ? ? ? ? D9 05 ? ? ? ? D9 7C 24 0C").get_one();
1396+
1397+
std::array<void*, 2> slidingMessage1 = {
1398+
bigMessage1ShadowPrint.get<void>(0xB),
1399+
get_pattern("E8 ? ? ? ? 83 C4 0C EB 0A C7 05 ? ? ? ? ? ? ? ? 83 C4 68"),
1400+
};
1401+
1402+
BigMessageSlider<1>::pHorShadowValue = bigMessage1ShadowPrint.get<float*>(2);
1403+
BigMessageSlider<1>::bSlidingEnabled = INIoption != 0;
1404+
BigMessageSlider<1>::HookEach_PrintString(slidingMessage1, InterceptCall);
1405+
1406+
if (bHasDebugMenu)
1407+
{
1408+
DebugMenuAddVar("SilentPatch", "Sliding mission title text", &BigMessageSlider<1>::bSlidingEnabled, nullptr);
1409+
}
1410+
}
1411+
TXN_CATCH();
1412+
1413+
if (const int INIoption = GetPrivateProfileIntW(L"SilentPatch", L"SlidingOddJobText", -1, wcModulePath); INIoption != -1) try
1414+
{
1415+
pOddJob2XOffset = *get_pattern<float*>("D9 05 ? ? ? ? D8 E1 D9 1D ? ? ? ? E9", 2);
1416+
1417+
std::array<void*, 2> slidingOddJob2 = {
1418+
get_pattern("E8 ? ? ? ? 83 C4 0C 8D 4C 24 5C"),
1419+
get_pattern("E8 ? ? ? ? 83 C4 0C 66 83 3D ? ? ? ? ? 0F 84"),
1420+
};
1421+
1422+
OddJob2Slider::bSlidingEnabled = INIoption != 0;
1423+
OddJob2Slider::HookEach_PrintString(slidingOddJob2, InterceptCall);
1424+
1425+
if (bHasDebugMenu)
1426+
{
1427+
DebugMenuAddVar("SilentPatch", "Sliding odd job text", &OddJob2Slider::bSlidingEnabled, nullptr);
1428+
}
1429+
}
1430+
TXN_CATCH();
1431+
}
1432+
TXN_CATCH();
1433+
1434+
13131435
FLAUtils::Init(moduleList);
13141436
}
13151437

0 commit comments

Comments
 (0)