From c58f8ceef631c3e8543128bba31c5a85cd35f65d Mon Sep 17 00:00:00 2001 From: Silent Date: Mon, 11 Sep 2017 00:39:46 +0200 Subject: [PATCH] First version of new timer fix for III/VC - VC only so far --- SilentPatch/Timer.cpp | 146 +++++--------------------------- SilentPatch/Timer.h | 10 +-- SilentPatchVC/SilentPatchVC.cpp | 51 +++++------ 3 files changed, 43 insertions(+), 164 deletions(-) diff --git a/SilentPatch/Timer.cpp b/SilentPatch/Timer.cpp index e5fbeb5..81f54fa 100644 --- a/SilentPatch/Timer.cpp +++ b/SilentPatch/Timer.cpp @@ -1,6 +1,8 @@ #include "StdAfx.h" #include "Timer.h" +#include "Patterns.h" + float* CTimer::ms_fTimeScale; float* CTimer::ms_fTimeStep; float* CTimer::ms_fTimeStepNotClipped; @@ -12,146 +14,44 @@ int* CTimer::m_snTimeInMillisecondsNonClipped; int* CTimer::m_snTimeInMillisecondsPauseMode; unsigned int* CTimer::m_FrameCounter; -static gtaTimer timerFunction; static unsigned int suspendDepth; static long long timerFreq; static long long oldTime, suspendTime; static long long cyclesTime, cyclesTimeNonClipped, cyclesTimePauseMode, cyclesPreviousTime; -static long long QPC() -{ - LARGE_INTEGER Counter; - QueryPerformanceCounter(&Counter); - return Counter.QuadPart; -} +static uint32_t& timerFrequency = **hook::get_pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08", -7 ); +static LARGE_INTEGER& prevTimer = **hook::get_pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08", 64 ); -static long long OldTimer() -{ - TIMECAPS caps; - long long nTime; - - timeGetDevCaps(&caps, sizeof(TIMECAPS)); - timeBeginPeriod(caps.wPeriodMin); - nTime = timeGetTime(); - timeEndPeriod(caps.wPeriodMin); - return nTime; -} - -static inline void InitTimerFunc() -{ - if ( timerFunction ) - return; - - LARGE_INTEGER Frequency; - if ( QueryPerformanceFrequency(&Frequency) ) - { - timerFreq = Frequency.QuadPart / 1000; - timerFunction = QPC; - } - else - { - timerFreq = 1; - timerFunction = OldTimer; - } -} extern void (__stdcall *AudioResetTimers)(unsigned int); extern bool* bSnapShotActive; -void CTimer::Initialise() +void CTimer::Update_SilentPatch() { - suspendDepth = 0; - *ms_fTimeScale = *ms_fTimeStep = 1.0f; - *m_UserPause = false; - *m_CodePause = false; - *m_snTimeInMilliseconds = 0; - *m_snPreviousTimeInMilliseconds = 0; - *m_snTimeInMillisecondsNonClipped = 0; - *m_FrameCounter = 0; + LARGE_INTEGER perfCount; + QueryPerformanceCounter( &perfCount ); - InitTimerFunc(); + double diff = double(perfCount.QuadPart - prevTimer.QuadPart); + if ( !*m_UserPause && !*m_CodePause ) diff *= *ms_fTimeScale; - oldTime = timerFunction(); - AudioResetTimers(0); -} + prevTimer = perfCount; -void CTimer::Suspend() -{ - if ( suspendDepth++ == 0 ) - suspendTime = timerFunction(); -} + static double DeltaRemainder = 0.0; + const double delta = diff / timerFrequency; + double deltaIntegral; + DeltaRemainder = modf( delta + DeltaRemainder, &deltaIntegral ); -void CTimer::Resume() -{ - if ( --suspendDepth == 0 ) - oldTime += timerFunction() - suspendTime; -} - -unsigned int CTimer::GetCyclesPerFrame() -{ - return static_cast(timerFunction() - oldTime); -} - -unsigned int CTimer::GetCyclesPerMillisecond() -{ - return static_cast(timerFreq); -} - -void CTimer::Update() -{ - *m_snPreviousTimeInMilliseconds = *m_snTimeInMilliseconds; - cyclesPreviousTime = cyclesTime; - - long long nCurTime; - float nDelta; - - nCurTime = timerFunction(); - nDelta = (nCurTime - oldTime) * *ms_fTimeScale; - oldTime = nCurTime; - - //*m_snTimeInMillisecondsPauseMode += nDelta; - cyclesTimePauseMode += static_cast(nDelta); - - if ( *m_UserPause || *m_CodePause ) - *ms_fTimeStep = 0.0f; + const int deltaInteger = int(deltaIntegral); + *m_snTimeInMillisecondsPauseMode += deltaInteger; + if ( !*m_UserPause && !*m_CodePause ) + { + *m_snTimeInMillisecondsNonClipped += deltaInteger; + *m_snTimeInMilliseconds += deltaInteger; + *ms_fTimeStep = float(delta * 0.05); + } else { - *ms_fTimeStep = (nDelta/timerFreq) * 0.05f; - cyclesTime += static_cast(nDelta); - cyclesTimeNonClipped += static_cast(nDelta); - //*m_snTimeInMilliseconds += nDelta; - //*m_snTimeInMillisecondsNonClipped += nDelta; + *ms_fTimeStep = 0.0f; } - -#ifdef _GTA_III - if ( *ms_fTimeStep < 0.01f && !*m_UserPause && !*m_CodePause ) -#else - if ( *ms_fTimeStep < 0.01f && !*m_UserPause && !*m_CodePause && !*bSnapShotActive ) -#endif - *ms_fTimeStep = 0.01f; - - *ms_fTimeStepNotClipped = *ms_fTimeStep; - - if ( *ms_fTimeStep > 3.0f ) - *ms_fTimeStep = 3.0f; - - /*if ( *m_snTimeInMilliseconds - *m_snPreviousTimeInMilliseconds > 60 ) - *m_snTimeInMilliseconds = *m_snPreviousTimeInMilliseconds + 60;*/ - if ( cyclesTime - cyclesPreviousTime > 60 * timerFreq ) - cyclesTime = cyclesPreviousTime + (60 * timerFreq); - - *m_snTimeInMillisecondsPauseMode = static_cast(cyclesTimePauseMode / timerFreq); - *m_snTimeInMilliseconds = static_cast(cyclesTime / timerFreq); - *m_snTimeInMillisecondsNonClipped = static_cast(cyclesTimeNonClipped / timerFreq); - - ++(*m_FrameCounter); -} - -void CTimer::RecoverFromSave() -{ - cyclesTime = *m_snTimeInMilliseconds * timerFreq; - cyclesPreviousTime = *m_snPreviousTimeInMilliseconds * timerFreq; - cyclesTimePauseMode = *m_snTimeInMillisecondsPauseMode * timerFreq; - cyclesTimeNonClipped = *m_snTimeInMillisecondsNonClipped * timerFreq; } \ No newline at end of file diff --git a/SilentPatch/Timer.h b/SilentPatch/Timer.h index 6173e44..a2d6b69 100644 --- a/SilentPatch/Timer.h +++ b/SilentPatch/Timer.h @@ -1,8 +1,6 @@ #ifndef __TIMER #define __TIMER -typedef long long(*gtaTimer)(); - class CTimer { public: @@ -18,13 +16,7 @@ public: static unsigned int* m_FrameCounter; public: - static void Initialise(); - static void Suspend(); - static void Resume(); - static unsigned int GetCyclesPerFrame(); - static unsigned int GetCyclesPerMillisecond(); - static void Update(); - static void RecoverFromSave(); + static void Update_SilentPatch(); }; #endif \ No newline at end of file diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 07ebc09..ff6cd61 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -1,6 +1,7 @@ #include "StdAfx.h" #include "Timer.h" +#include "Patterns.h" struct RsGlobalType { @@ -244,14 +245,6 @@ void Patch_VC_10(const RECT& desktop) Patch(0x48EB27, 16); Patch(0x541E7E, 16); - InjectHook(0x4D1300, CTimer::Initialise, PATCH_JUMP); - InjectHook(0x4D0ED0, CTimer::Suspend, PATCH_JUMP); - InjectHook(0x4D0E50, CTimer::Resume, PATCH_JUMP); - InjectHook(0x4D0DF0, CTimer::GetCyclesPerFrame, PATCH_JUMP); - InjectHook(0x4D0E30, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); - InjectHook(0x4D0F30, CTimer::Update, PATCH_JUMP); - InjectHook(0x61AA7D, CTimer::RecoverFromSave); - InjectHook(0x5433BD, FixedRefValue); InjectHook(0x42BFF7, RosiesAudioFix, PATCH_JUMP); @@ -395,14 +388,6 @@ void Patch_VC_11(const RECT& desktop) Patch(0x48EB37, 16); Patch(0x541E9E, 16); - InjectHook(0x4D1320, CTimer::Initialise, PATCH_JUMP); - InjectHook(0x4D0EF0, CTimer::Suspend, PATCH_JUMP); - InjectHook(0x4D0E70, CTimer::Resume, PATCH_JUMP); - InjectHook(0x4D0E10, CTimer::GetCyclesPerFrame, PATCH_JUMP); - InjectHook(0x4D0E50, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); - InjectHook(0x4D0F50, CTimer::Update, PATCH_JUMP); - InjectHook(0x61AA5D, CTimer::RecoverFromSave); - InjectHook(0x5433DD, FixedRefValue); InjectHook(0x42BFF7, RosiesAudioFix, PATCH_JUMP); @@ -537,14 +522,6 @@ void Patch_VC_Steam(const RECT& desktop) Patch(0x48EA37, 16); Patch(0x541D6E, 16); - InjectHook(0x4D11C0, CTimer::Initialise, PATCH_JUMP); - InjectHook(0x4D0D90, CTimer::Suspend, PATCH_JUMP); - InjectHook(0x4D0D10, CTimer::Resume, PATCH_JUMP); - InjectHook(0x4D0CB0, CTimer::GetCyclesPerFrame, PATCH_JUMP); - InjectHook(0x4D0CF0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); - InjectHook(0x4D0DF0, CTimer::Update, PATCH_JUMP); - InjectHook(0x61A6A6, CTimer::RecoverFromSave); - InjectHook(0x5432AD, FixedRefValue); InjectHook(0x42BFC7, RosiesAudioFix, PATCH_JUMP); @@ -650,7 +627,6 @@ void Patch_VC_Steam(const RECT& desktop) void Patch_VC_JP() { using namespace Memory; - ScopedUnprotect::Section Protect( (HINSTANCE)0x400000, ".text" ); // Y axis sensitivity fix // By ThirteenAG @@ -661,6 +637,21 @@ void Patch_VC_JP() Patch(0x481E8A + 0x4FE + 0x2, 0x94ABD8); } +void Patch_VC_Common() +{ + using namespace Memory; + using namespace hook; + + // New timers fix + { + auto hookPoint = pattern( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08" ).get_one(); + auto jmpPoint = get_pattern( "DD D8 E9 31 FF FF FF" ); + + InjectHook( hookPoint.get( 0x21 ), CTimer::Update_SilentPatch, PATCH_CALL ); + InjectHook( hookPoint.get( 0x21 + 5 ), jmpPoint, PATCH_JUMP ); + } +} + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(hinstDLL); @@ -672,21 +663,17 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) GetWindowRect(GetDesktopWindow(), &desktop); sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom); - ScopedUnprotect::Section Protect( (HINSTANCE)0x400000, ".text" ); + ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" ); if(*(DWORD*)0x667BF5 == 0xB85548EC) Patch_VC_10(desktop); else if(*(DWORD*)0x667C45 == 0xB85548EC) Patch_VC_11(desktop); else if (*(DWORD*)0x666BA5 == 0xB85548EC) Patch_VC_Steam(desktop); // Y axis sensitivity only - else if (*(DWORD*)0x601048 == 0x5E5F5D60) - { - Patch_VC_JP(); - return TRUE; - } + else if (*(DWORD*)0x601048 == 0x5E5F5D60) Patch_VC_JP(); else return TRUE; - CTimer::Initialise(); + Patch_VC_Common(); HMODULE hDummyHandle; GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&DllMain, &hDummyHandle);