attempt to compensate for scheduling jitter
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "TimingData.h"
|
||||
#include "NotesLoaderSM.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "RageDisplay.h"
|
||||
|
||||
RageSounds *SOUND = NULL;
|
||||
|
||||
@@ -308,6 +309,41 @@ RageSounds::~RageSounds()
|
||||
delete g_Mutex;
|
||||
}
|
||||
|
||||
static float GetFrameTimingAdjustment( float fDeltaTime )
|
||||
{
|
||||
/*
|
||||
* We get one update per frame, and we're updated early, almost immediately after vsync,
|
||||
* near the beginning of the game loop. However, it's very likely that we'll lose the
|
||||
* scheduler while waiting for vsync, and some other thread will be working. Especially
|
||||
* with a low-resolution scheduler (Linux 2.4, Win9x), we may not get the scheduler back
|
||||
* immediately after the vsync; there may be up to a ~10ms delay. This can cause jitter
|
||||
* in the rendered arrows.
|
||||
*
|
||||
* Compensate. If vsync is enabled, and we're maintaining the refresh rate consistently,
|
||||
* we should have a very precise game loop interval. If we have that, but we're off by
|
||||
* a small amount (less than the interval), adjust the time to line it up. As long as we
|
||||
* adjust both the sound time and the timestamp, this won't adversely affect input timing.
|
||||
* If we're off by more than that, we probably had a frame skip, in which case we have
|
||||
* bigger skip problems, so don't adjust.
|
||||
*/
|
||||
static int iLastFPS = 0;
|
||||
int iThisFPS = DISPLAY->GetFPS();
|
||||
|
||||
if( iThisFPS != DISPLAY->GetVideoModeParams().rate || iThisFPS != iLastFPS )
|
||||
{
|
||||
iLastFPS = iThisFPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float fExpectedDelay = 1.0f / iThisFPS;
|
||||
const float fExtraDelay = fDeltaTime - fExpectedDelay;
|
||||
if( fabsf(fExtraDelay) >= fExpectedDelay )
|
||||
return 0;
|
||||
|
||||
/* Subtract the extra delay. (We might have delayed too little, in which case we'll return
|
||||
* a positive number; this is normal.) */
|
||||
return -fExtraDelay;
|
||||
}
|
||||
|
||||
void RageSounds::Update( float fDeltaTime )
|
||||
{
|
||||
@@ -316,6 +352,8 @@ void RageSounds::Update( float fDeltaTime )
|
||||
if( !g_UpdatingTimer )
|
||||
return;
|
||||
|
||||
const float fAdjust = GetFrameTimingAdjustment( fDeltaTime );
|
||||
|
||||
if( !g_Playing->m_Music->IsPlaying() )
|
||||
{
|
||||
/* There's no song playing. Fake it. */
|
||||
@@ -367,7 +405,7 @@ void RageSounds::Update( float fDeltaTime )
|
||||
}
|
||||
|
||||
CHECKPOINT_M( ssprintf("%f", fSeconds) );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds, g_Playing->m_Timing, tm );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, g_Playing->m_Timing, tm+fAdjust );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user