From ea561430ff79ac1b3b4fb0efe8ed8afbd39058ef Mon Sep 17 00:00:00 2001 From: daco65 Date: Wed, 12 Aug 2009 16:42:51 +0000 Subject: [PATCH] auto frameskip by Iulius. the automatic should make it so that dolphin doesn't skip more then needed (example: you have frameskip 9 but only need 4.2, auto will make it skip on 4.2) framelimit should be on git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3972 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/Core.cpp | 47 +++++++++++++++++++++++++++++--- Source/Core/Core/Src/Core.h | 2 ++ Source/Core/Core/Src/OnFrame.cpp | 11 ++++---- 3 files changed, 50 insertions(+), 10 deletions(-) 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);