First version of new timer fix for III/VC - VC only so far

This commit is contained in:
Silent 2017-09-11 00:39:46 +02:00
parent 8901d95359
commit c58f8ceef6
3 changed files with 43 additions and 164 deletions

View File

@ -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<uint32_t*>( "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<LARGE_INTEGER*>( "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<unsigned int>(timerFunction() - oldTime);
}
unsigned int CTimer::GetCyclesPerMillisecond()
{
return static_cast<unsigned int>(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<long long>(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<long long>(nDelta);
cyclesTimeNonClipped += static_cast<long long>(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<int>(cyclesTimePauseMode / timerFreq);
*m_snTimeInMilliseconds = static_cast<int>(cyclesTime / timerFreq);
*m_snTimeInMillisecondsNonClipped = static_cast<int>(cyclesTimeNonClipped / timerFreq);
++(*m_FrameCounter);
}
void CTimer::RecoverFromSave()
{
cyclesTime = *m_snTimeInMilliseconds * timerFreq;
cyclesPreviousTime = *m_snPreviousTimeInMilliseconds * timerFreq;
cyclesTimePauseMode = *m_snTimeInMillisecondsPauseMode * timerFreq;
cyclesTimeNonClipped = *m_snTimeInMillisecondsNonClipped * timerFreq;
}

View File

@ -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

View File

@ -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<BYTE>(0x48EB27, 16);
Patch<BYTE>(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<BYTE>(0x48EB37, 16);
Patch<BYTE>(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<BYTE>(0x48EA37, 16);
Patch<BYTE>(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<DWORD>(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<int>( 0x21 ), CTimer::Update_SilentPatch, PATCH_CALL );
InjectHook( hookPoint.get<int>( 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);