Fixed frameskipping when using a strict framerate setting (minfps==maxfps). The setting is ideal for users playing high-fps games as it allows you to disable the timestretching on your SPU2 plugin. :)

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@390 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2008-12-04 19:48:10 +00:00 committed by Gregory Hainaut
parent 10ea6b9c05
commit 3696028dbe
4 changed files with 33 additions and 14 deletions

View File

@ -115,7 +115,6 @@ void rcntInit() {
// debug code, used for stats // debug code, used for stats
int g_nCounters[4]; int g_nCounters[4];
static int iFrame = 0; static int iFrame = 0;
//long iFrameLimitEnable = 1;
#ifndef _WIN32 #ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
@ -327,6 +326,11 @@ void vSyncDebugStuff() {
#endif #endif
} }
void frameLimitReset()
{
m_iStart = GetCPUTicks();
}
// Framelimiter - Measures the delta time between calls and stalls until a // Framelimiter - Measures the delta time between calls and stalls until a
// certain amount of time passes if such time hasn't passed yet. // certain amount of time passes if such time hasn't passed yet.
// See the GS FrameSkip function for details on why this is here and not in the GS. // See the GS FrameSkip function for details on why this is here and not in the GS.
@ -356,7 +360,7 @@ static __forceinline void frameLimit()
// Keeps the GS skipper from trying to catch up to a framerate // Keeps the GS skipper from trying to catch up to a framerate
// that the limiter already gave up on. // that the limiter already gave up on.
gsSyncLimiterStartTime( m_iStart ); gsSyncLimiterLostTime( (s32)(m_iStart - uExpectedEnd) );
return; return;
} }

View File

@ -1660,7 +1660,7 @@ void gifMFIFOInterrupt()
cpuRegs.interrupt &= ~(1 << 11); cpuRegs.interrupt &= ~(1 << 11);
} }
extern "C" void gsSyncLimiterStartTime( u64 startTime ) extern "C" void gsSyncLimiterLostTime( s32 deltaTime )
{ {
// This sync issue applies only to configs that are trying to maintain // This sync issue applies only to configs that are trying to maintain
// a perfect "specific" framerate (where both min and max fps are the same) // a perfect "specific" framerate (where both min and max fps are the same)
@ -1672,17 +1672,17 @@ extern "C" void gsSyncLimiterStartTime( u64 startTime )
if( CHECK_MULTIGS ) if( CHECK_MULTIGS )
{ {
const u32* stp = (u32*)&startTime; //const u32* stp = (u32*)&startTime;
GSRingBufSimplePacket( GSRingBufSimplePacket(
GS_RINGTYPE_STARTTIME, GS_RINGTYPE_STARTTIME,
stp[0], deltaTime,
stp[1], 0,
0 0
); );
} }
else else
{ {
m_iSlowStart = startTime; m_iSlowStart += deltaTime;
//m_justSkipped = false; //m_justSkipped = false;
} }
} }
@ -1847,6 +1847,15 @@ extern "C" void gsResetFrameSkip()
_resetFrameskip(); _resetFrameskip();
} }
extern "C" void frameLimitReset();
extern "C" void gsDynamicSkipEnable()
{
if( !m_StrictSkipping ) return;
gsWaitGS();
m_iSlowStart = GetCPUTicks();
frameLimitReset();
}
GS_THREADPROC GS_THREADPROC
{ {
@ -2030,7 +2039,7 @@ GS_THREADPROC
break; break;
case GS_RINGTYPE_STARTTIME: case GS_RINGTYPE_STARTTIME:
m_iSlowStart = *(u64*)(g_pGSRingPos+4); m_iSlowStart += *(u32*)(g_pGSRingPos+4);
//m_justSkipped = false; //m_justSkipped = false;
break; break;

View File

@ -81,7 +81,8 @@ void gsShutdown();
void gsReset(); void gsReset();
void gsSetVideoRegionType( u32 isPal ); void gsSetVideoRegionType( u32 isPal );
void gsResetFrameSkip(); void gsResetFrameSkip();
void gsSyncLimiterStartTime( u64 startTime ); void gsSyncLimiterLostTime( s32 deltaTime );
void gsDynamicSkipEnable();
// mem and size are the ones from GSRingBufCopy // mem and size are the ones from GSRingBufCopy
extern void GSRINGBUF_DONECOPY(const u8 *mem, u32 size); extern void GSRINGBUF_DONECOPY(const u8 *mem, u32 size);

View File

@ -881,22 +881,23 @@ void ProcessFKeys(int fkey, int shift)
case 4: case 4:
{ {
const char* limitMsg; const char* limitMsg;
u32 newOptions;
#ifdef PCSX2_NORECBUILD #ifdef PCSX2_NORECBUILD
SysPrintf("frame skipping only valid for recompiler build\n"); SysPrintf("frame skipping only valid for recompiler build\n");
#else #else
// cycle // cycle
if( shift ) { if( shift ) {
// previous // previous
Config.Options = (Config.Options&~PCSX2_FRAMELIMIT_MASK)|(((Config.Options&PCSX2_FRAMELIMIT_MASK)+PCSX2_FRAMELIMIT_VUSKIP)&PCSX2_FRAMELIMIT_MASK); newOptions = (Config.Options&~PCSX2_FRAMELIMIT_MASK)|(((Config.Options&PCSX2_FRAMELIMIT_MASK)+PCSX2_FRAMELIMIT_VUSKIP)&PCSX2_FRAMELIMIT_MASK);
} }
else { else {
// next // next
Config.Options = (Config.Options&~PCSX2_FRAMELIMIT_MASK)|(((Config.Options&PCSX2_FRAMELIMIT_MASK)+PCSX2_FRAMELIMIT_LIMIT)&PCSX2_FRAMELIMIT_MASK); newOptions = (Config.Options&~PCSX2_FRAMELIMIT_MASK)|(((Config.Options&PCSX2_FRAMELIMIT_MASK)+PCSX2_FRAMELIMIT_LIMIT)&PCSX2_FRAMELIMIT_MASK);
} }
gsResetFrameSkip(); gsResetFrameSkip();
switch(CHECK_FRAMELIMIT) { switch(newOptions & PCSX2_FRAMELIMIT_MASK) {
case PCSX2_FRAMELIMIT_NORMAL: case PCSX2_FRAMELIMIT_NORMAL:
limitMsg = "None/Normal"; limitMsg = "None/Normal";
break; break;
@ -907,17 +908,21 @@ void ProcessFKeys(int fkey, int shift)
case PCSX2_FRAMELIMIT_VUSKIP: case PCSX2_FRAMELIMIT_VUSKIP:
if( GSsetFrameSkip == NULL ) if( GSsetFrameSkip == NULL )
{ {
Config.Options &= ~PCSX2_FRAMELIMIT_MASK; newOptions &= ~PCSX2_FRAMELIMIT_MASK;
SysPrintf("Notice: GS Plugin does not support frameskipping.\n"); SysPrintf("Notice: GS Plugin does not support frameskipping.\n");
limitMsg = "None/Normal"; limitMsg = "None/Normal";
} }
else else
{ {
limitMsg = (CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP) ? "Skip" : "VUSkip"; // When enabling Skipping we have to make sure Skipper (GS) and Limiter (EE)
// are properly synchronized.
gsDynamicSkipEnable();
limitMsg = ((newOptions & PCSX2_FRAMELIMIT_MASK) == PCSX2_FRAMELIMIT_SKIP) ? "Skip" : "VUSkip";
} }
break; break;
} }
InterlockedExchange( &Config.Options, newOptions );
SysPrintf("Frame Limit Mode Changed: %s\n", limitMsg ); SysPrintf("Frame Limit Mode Changed: %s\n", limitMsg );