diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 72831b4e0a..13d17548a4 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -67,6 +67,8 @@ namespace Core // Declarations and definitions +Common::Timer Timer; +u32 frames = 0; // Function forwarding @@ -587,6 +589,30 @@ void Callback_VideoLog(const TCHAR *_szMessage, int _bDoBreak) INFO_LOG(VIDEO, _szMessage); } +// reports if a frame should be skipped or not +// depending on the framelimit set +bool report_slow(int skipped) +{ + u32 targetfps = SConfig::GetInstance().m_Framelimit * 5; + double wait_frametime; + + if (targetfps < 5) + wait_frametime = (1000.0 / VideoInterface::TargetRefreshRate); + else + wait_frametime = (1000.0 / targetfps); + + bool fps_slow; + + if (Timer.GetTimeDifference() < wait_frametime * (frames + skipped - 1)) + fps_slow=false; + else + fps_slow=true; + + if (targetfps == 5) + fps_slow=true; + + return fps_slow; +} // Callback_VideoCopiedToXFB // WARNING - THIS IS EXECUTED FROM VIDEO THREAD @@ -599,15 +625,18 @@ void Callback_VideoCopiedToXFB(bool video_update) SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; //count FPS and VPS - static Common::Timer Timer; - static u32 frames = 0; static u32 videoupd = 0; + static u32 no_framelimit = 0; + if (video_update) videoupd++; else frames++; + if (no_framelimit>0) + no_framelimit--; + // Custom frame limiter // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ u32 targetfps = SConfig::GetInstance().m_Framelimit * 5; @@ -616,18 +645,28 @@ void Callback_VideoCopiedToXFB(bool video_update) { double wait_frametime = (1000.0 / targetfps); + if (Timer.GetTimeDifference() >= wait_frametime * frames) + no_framelimit=Timer.GetTimeDifference(); + while (Timer.GetTimeDifference() < wait_frametime * frames) - Common::SleepCurrentThread(1); + { + if (no_framelimit==0) + Common::SleepCurrentThread(1); + } } else if (targetfps < 5) { double wait_frametime = (1000.0 / VideoInterface::TargetRefreshRate); + if (Timer.GetTimeDifference() >= wait_frametime * frames) + no_framelimit=Timer.GetTimeDifference(); + while (Timer.GetTimeDifference() < wait_frametime * videoupd) { // TODO : This is wrong, the sleep shouldn't be there but rather in cputhread // as it's not based on the fps but on the refresh rate... - Common::SleepCurrentThread(1); + if (no_framelimit==0) + Common::SleepCurrentThread(1); } } diff --git a/Source/Core/Core/Src/Core.h b/Source/Core/Core/Src/Core.h index 0bd40ef2c3..49cbaa7ec0 100644 --- a/Source/Core/Core/Src/Core.h +++ b/Source/Core/Core/Src/Core.h @@ -72,6 +72,8 @@ namespace Core void SetBlockStart(u32 addr); void StopTrace(); + bool report_slow(int skipped); + // ----------------------------------------- #ifdef RERECORDING // ----------------- diff --git a/Source/Core/Core/Src/OnFrame.cpp b/Source/Core/Core/Src/OnFrame.cpp index 36c43123e8..b3515bf5ce 100644 --- a/Source/Core/Core/Src/OnFrame.cpp +++ b/Source/Core/Core/Src/OnFrame.cpp @@ -33,16 +33,15 @@ bool g_bFirstKey = true; int g_framesToSkip = 0, g_frameSkipCounter = 0; void FrameUpdate() { + + if (g_bFrameStep) Core::SetState(Core::CORE_PAUSE); + FrameSkipping(); + if (g_bAutoFire) g_bFirstKey = !g_bFirstKey; - - if (g_framesToSkip) - FrameSkipping(); - else - CPluginManager::GetInstance().GetVideo()->Video_SetRendering(true); } @@ -123,7 +122,7 @@ void FrameSkipping() cs_frameSkip.Enter(); g_frameSkipCounter++; - if (g_frameSkipCounter > g_framesToSkip) + if (g_frameSkipCounter > g_framesToSkip || Core::report_slow(g_frameSkipCounter) == false) g_frameSkipCounter = 0; CPluginManager::GetInstance().GetVideo()->Video_SetRendering(!g_frameSkipCounter);