diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 4be9acf..683a469 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -362,6 +362,53 @@ static void __fastcall GiveWeapon_SP( void* ped, void*, unsigned int weapon, uns } +// ============= Credits! ============= +namespace Credits +{ + static void (*PrintCreditText)(float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset); + static void (*PrintCreditText_Hooked)(float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset); + + static void PrintCreditSpace( float scale, unsigned int& pos ) + { + pos += static_cast( scale * 25.0f ); + } + + constexpr wchar_t xvChar(const wchar_t ch) + { + constexpr uint8_t xv = SILENTPATCH_REVISION_ID; + return ch ^ xv; + } + + constexpr wchar_t operator "" _xv(const char ch) + { + return xvChar(ch); + } + + static void PrintSPCredits( float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset ) + { + // Original text we intercepted + PrintCreditText_Hooked( scaleX, scaleY, text, pos, timeOffset ); + PrintCreditSpace( 2.0f, pos ); + + { + wchar_t spText[] = { 'A'_xv, 'N'_xv, 'D'_xv, '\0'_xv }; + + for ( auto& ch : spText ) ch = xvChar(ch); + PrintCreditText( 1.7f, 1.0f, spText, pos, timeOffset ); + } + + PrintCreditSpace( 2.0f, pos ); + + { + wchar_t spText[] = { 'A'_xv, 'D'_xv, 'R'_xv, 'I'_xv, 'A'_xv, 'N'_xv, ' '_xv, '\''_xv, 'S'_xv, 'I'_xv, 'L'_xv, 'E'_xv, 'N'_xv, 'T'_xv, '\''_xv, ' '_xv, + 'Z'_xv, 'D'_xv, 'A'_xv, 'N'_xv, 'O'_xv, 'W'_xv, 'I'_xv, 'C'_xv, 'Z'_xv, '\0'_xv }; + + for ( auto& ch : spText ) ch = xvChar(ch); + PrintCreditText( 1.7f, 1.7f, spText, pos, timeOffset ); + } + } +} + // ============= Keyboard latency input fix ============= namespace KeyboardInputFix { @@ -880,6 +927,16 @@ void Patch_III_Common() } + // Credits =) + { + auto renderCredits = pattern( "83 C4 14 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 8D 45 F4 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59 E8" ).get_one(); + + ReadCall( renderCredits.get( -48 ), Credits::PrintCreditText ); + ReadCall( renderCredits.get( -5 ), Credits::PrintCreditText_Hooked ); + InjectHook( renderCredits.get( -5 ), Credits::PrintSPCredits ); + } + + // Decreased keyboard input latency { using namespace KeyboardInputFix; diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index a3dcaf5..08e259a 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -4963,6 +4963,17 @@ void Patch_SA_NewSteam_Common() // Fixed triangle above recruitable peds' heads Patch( get_pattern( "83 BE 98 05 00 00 ? D9 45 DC", 6 ), 8 ); // GANG2 + + // Credits =) + { + auto renderCredits = pattern( "83 C4 18 E8 ? ? ? ? 80 3D" ).get_one(); + + ReadCall( renderCredits.get( -58 ), Credits::PrintCreditText ); + ReadCall( renderCredits.get( -5 ), Credits::PrintCreditText_Hooked ); + InjectHook( renderCredits.get( -5 ), Credits::PrintSPCredits ); + } + + // TODO: OTHER FIXES NEED TO GO HERE // Decreased keyboard input latency diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index e39a14a..23d9c1d 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -233,6 +233,54 @@ static void __fastcall GiveWeapon_SP( void* ped, void*, unsigned int weapon, uns } +// ============= Credits! ============= +namespace Credits +{ + static void (*PrintCreditText)(float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset); + static void (*PrintCreditText_Hooked)(float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset); + + static void PrintCreditSpace( float scale, unsigned int& pos ) + { + pos += static_cast( scale * 25.0f ); + } + + constexpr wchar_t xvChar(const wchar_t ch) + { + constexpr uint8_t xv = SILENTPATCH_REVISION_ID; + return ch ^ xv; + } + + constexpr wchar_t operator "" _xv(const char ch) + { + return xvChar(ch); + } + + static void PrintSPCredits( float scaleX, float scaleY, const wchar_t* text, unsigned int& pos, float timeOffset ) + { + // Original text we intercepted + PrintCreditText_Hooked( scaleX, scaleY, text, pos, timeOffset ); + PrintCreditSpace( 1.5f, pos ); + + { + wchar_t spText[] = { 'A'_xv, 'N'_xv, 'D'_xv, '\0'_xv }; + + for ( auto& ch : spText ) ch = xvChar(ch); + PrintCreditText( 1.1f, 0.8f, spText, pos, timeOffset ); + } + + PrintCreditSpace( 1.5f, pos ); + + { + wchar_t spText[] = { 'A'_xv, 'D'_xv, 'R'_xv, 'I'_xv, 'A'_xv, 'N'_xv, ' '_xv, '\''_xv, 'S'_xv, 'I'_xv, 'L'_xv, 'E'_xv, 'N'_xv, 'T'_xv, '\''_xv, ' '_xv, + 'Z'_xv, 'D'_xv, 'A'_xv, 'N'_xv, 'O'_xv, 'W'_xv, 'I'_xv, 'C'_xv, 'Z'_xv, '\0'_xv }; + + for ( auto& ch : spText ) ch = xvChar(ch); + PrintCreditText( 1.1f, 1.1f, spText, pos, timeOffset ); + } + } +} + + // ============= Keyboard latency input fix ============= namespace KeyboardInputFix { @@ -704,6 +752,16 @@ void Patch_VC_Common() } + // Credits =) + { + auto renderCredits = pattern( "8D 44 24 28 83 C4 14 50 FF 35 ? ? ? ? E8 ? ? ? ? 8D 44 24 1C 59 59 50 FF 35 ? ? ? ? E8 ? ? ? ? 59 59" ).get_one(); + + ReadCall( renderCredits.get( -50 ), Credits::PrintCreditText ); + ReadCall( renderCredits.get( -5 ), Credits::PrintCreditText_Hooked ); + InjectHook( renderCredits.get( -5 ), Credits::PrintSPCredits ); + } + + // Decreased keyboard input latency { using namespace KeyboardInputFix;