@@ -1010,6 +1010,67 @@ namespace CreditsScalingFixes
1010
1010
HOOK_EACH_INIT (PrintString, orgPrintString, PrintString_ScaleY);
1011
1011
}
1012
1012
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
+
1013
1074
namespace ModelIndicesReadyHook
1014
1075
{
1015
1076
static void (*orgInitialiseObjectData)(const char *);
@@ -1310,6 +1371,67 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
1310
1371
}
1311
1372
TXN_CATCH ();
1312
1373
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
+
1313
1435
FLAUtils::Init (moduleList);
1314
1436
}
1315
1437
0 commit comments