diff --git a/src/GameState.cpp b/src/GameState.cpp index ef37531f02..066c11c3c5 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -912,6 +912,8 @@ const float GameState::MUSIC_SECONDS_INVALID = -5000.0f; void GameState::ResetMusicStatistics() { m_Position.Reset(); + m_LastPositionTimer.Touch(); + m_LastPositionSeconds = 0.0f; Actor::SetBGMTime( 0, 0, 0, 0 ); @@ -960,7 +962,21 @@ void GameState::ResetStageStatistics() void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp, bool bUpdatePlayers ) { - + /* It's not uncommon to get a lot of duplicated positions from the sound + * driver, like so: 13.120953,13.130975,13.130975,13.130975,13.140998,... + * This causes visual stuttering of the arrows. To compensate, keep a + * RageTimer since the last change. */ + if (fPositionSeconds == m_LastPositionSeconds) + fPositionSeconds += m_LastPositionTimer.Ago(); + else + { + //LOG->Info("Time difference: %+f", + // m_LastPositionTimer.Ago() - (fPositionSeconds - m_LastPositionSeconds) + //); + m_LastPositionTimer.Touch(); + m_LastPositionSeconds = fPositionSeconds; + } + m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp ); if( bUpdatePlayers ) diff --git a/src/GameState.h b/src/GameState.h index 58639618fc..244d94ae3d 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -394,6 +394,10 @@ private: int m_iAwardedExtraStages[NUM_PLAYERS]; bool m_bEarnedExtraStage; + // Timing position corrections + RageTimer m_LastPositionTimer; + float m_LastPositionSeconds; + GameState(const GameState& rhs); GameState& operator=(const GameState& rhs);