diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index e12eb4349b92..452cdfaa5c5b 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -55,7 +55,7 @@ struct ConfigCache unsigned int framelimit; TEXIDevices m_EXIDevice[MAX_EXI_CHANNELS]; std::string strBackend, sBackend; - bool bSetFramelimit, bSetEXIDevice[MAX_EXI_CHANNELS], bSetUseFPS, bSetVolume, bSetPads[MAX_SI_CHANNELS], bSetWiimoteSource[MAX_BBMOTES]; + bool bSetFramelimit, bSetEXIDevice[MAX_EXI_CHANNELS], bSetVolume, bSetPads[MAX_SI_CHANNELS], bSetWiimoteSource[MAX_BBMOTES]; }; static ConfigCache config_cache; @@ -114,7 +114,6 @@ bool BootCore(const std::string& _rFilename) config_cache.Volume = SConfig::GetInstance().m_Volume; config_cache.sBackend = SConfig::GetInstance().sBackend; config_cache.framelimit = SConfig::GetInstance().m_Framelimit; - config_cache.bUseFPS = SConfig::GetInstance().b_UseFPS; for (unsigned int i = 0; i < MAX_BBMOTES; ++i) { config_cache.iWiimoteSource[i] = g_wiimote_sources[i]; @@ -150,8 +149,6 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2); if (game_ini.Get("Core", "FrameLimit", &SConfig::GetInstance().m_Framelimit, SConfig::GetInstance().m_Framelimit)) config_cache.bSetFramelimit = true; - if (game_ini.Get("Core", "UseFPS", &SConfig::GetInstance().b_UseFPS, SConfig::GetInstance().b_UseFPS)) - config_cache.bSetUseFPS = true; if (game_ini.Get("DSP", "Volume", &SConfig::GetInstance().m_Volume, SConfig::GetInstance().m_Volume)) config_cache.bSetVolume = true; game_ini.Get("DSP", "EnableJIT", &SConfig::GetInstance().m_EnableJIT, SConfig::GetInstance().m_EnableJIT); @@ -269,8 +266,6 @@ void Stop() // Only change these back if they were actually set by game ini, since they can be changed while a game is running. if (config_cache.bSetFramelimit) SConfig::GetInstance().m_Framelimit = config_cache.framelimit; - if (config_cache.bSetUseFPS) - SConfig::GetInstance().b_UseFPS = config_cache.bUseFPS; if (config_cache.bSetVolume) SConfig::GetInstance().m_Volume = config_cache.Volume; diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 279fd9107631..5152c643923d 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -256,7 +256,6 @@ void SConfig::SaveSettings() ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); ini.Set("Core", "FrameLimit", m_Framelimit); - ini.Set("Core", "UseFPS", b_UseFPS); // GFX Backend ini.Set("Core", "GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend); @@ -419,7 +418,6 @@ void SConfig::LoadSettings() ini.Get("Core", "FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false); ini.Get("Core", "DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false); ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default - ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default // GFX Backend ini.Get("Core", "GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, ""); diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 7a688760fa56..8cc4c37e0cb0 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -51,7 +51,6 @@ struct SConfig : NonCopyable int m_InterfaceLanguage; // framelimit choose unsigned int m_Framelimit; - bool b_UseFPS; // other interface settings bool m_InterfaceToolbar; bool m_InterfaceStatusbar; diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index ddbc490e9a2c..342d24184247 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -613,30 +613,6 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock) // This should only be called from VI void VideoThrottle() { - u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 2) ? - (SConfig::GetInstance().m_Framelimit - 1) * 5 : VideoInterface::TargetRefreshRate; - - if (Host_GetKeyState('\t')) - isTabPressed = true; - else - isTabPressed = false; - - // Disable the frame-limiter when the throttle (Tab) key is held down. Audio throttle: m_Framelimit = 2 - if (SConfig::GetInstance().m_Framelimit && SConfig::GetInstance().m_Framelimit != 2 && !Host_GetKeyState('\t')) - { - u32 frametime = ((SConfig::GetInstance().b_UseFPS)? Common::AtomicLoad(DrawnFrame) : DrawnVideo) * 1000 / TargetVPS; - - u32 timeDifference = (u32)Timer.GetTimeDifference(); - if (timeDifference < frametime) - { - Common::SleepCurrentThread(frametime - timeDifference - 1); - } - - while ((u32)Timer.GetTimeDifference() < frametime) - Common::YieldCPU(); - //Common::SleepCurrentThread(1); - } - // Update info per second u32 ElapseTime = (u32)Timer.GetTimeDifference(); if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo) @@ -697,9 +673,9 @@ void UpdateTitle() if (ElapseTime == 0) ElapseTime = 1; - u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime; - u32 VPS = DrawnVideo * 1000 / ElapseTime; - u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime); + float FPS = Common::AtomicLoad(DrawnFrame) * 1000.0 / ElapseTime; + float VPS = DrawnVideo * 1000.0 / ElapseTime; + float Speed = DrawnVideo * (100 * 1000.0) / (VideoInterface::TargetRefreshRate * ElapseTime); // Settings are shown the same for both extended and summary info std::string SSettings = StringFromFormat("%s %s | %s | %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC", @@ -735,11 +711,11 @@ void UpdateTitle() #else // Summary information std::string SFPS; if (Movie::IsPlayingInput()) - SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); + SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); else if (Movie::IsRecordingInput()) - SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); + SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %.0f - VPS: %.0f - %.0f%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); else - SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed); + SFPS = StringFromFormat("FPS: %.0f - VPS: %.0f - %.0f%%", FPS, VPS, Speed); #endif // This is our final "frame counter" string diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 976e2397cf8b..12c28979368e 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -75,6 +75,7 @@ IPC_HLE_PERIOD: For the Wiimote this is the call schedule: #include "Timer.h" #include "VideoBackendBase.h" #include "CommandProcessor.h" +#include "Host.h" namespace SystemTimers @@ -115,6 +116,7 @@ int et_AudioDMA; int et_DSP; int et_IPC_HLE; int et_PatchEngine; // PatchEngine updates every 1/60th of a second by default +int et_Throttle; // These are badly educated guesses // Feel free to experiment. Set these in Init below. @@ -229,6 +231,29 @@ void PatchEngineCallback(u64 userdata, int cyclesLate) CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_PatchEngine); } +void ThrottleCallback(u64 last_time, int cyclesLate) +{ + u32 time = Common::Timer::GetTimeMs(); + + int diff = (u32)last_time - time; + bool frame_limiter = SConfig::GetInstance().m_Framelimit && SConfig::GetInstance().m_Framelimit != 2 && !Host_GetKeyState('\t'); + u32 next_event = GetTicksPerSecond()/1000; + if (SConfig::GetInstance().m_Framelimit > 2) + { + next_event = next_event * (SConfig::GetInstance().m_Framelimit - 1) * 5 / VideoInterface::TargetRefreshRate; + } + + const int max_fallback = 40; // 40 ms for one frame on 25 fps games + if (frame_limiter && abs(diff) > max_fallback) + { + WARN_LOG(COMMON, "system too %s, %d ms skipped", diff<0 ? "slow" : "fast", abs(diff) - max_fallback); + last_time = time - max_fallback; + } + else if (frame_limiter && diff > 0) + Common::SleepCurrentThread(diff); + CoreTiming::ScheduleEvent(next_event - cyclesLate, et_Throttle, last_time + 1); +} + // split from Init to break a circular dependency between VideoInterface::Init and SystemTimers::Init void PreInit() { @@ -274,11 +299,13 @@ void Init() et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback); et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback); et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback); + et_Throttle = CoreTiming::RegisterEvent("Throttle", ThrottleCallback); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI); CoreTiming::ScheduleEvent(0, et_DSP); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_SI); CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA); + CoreTiming::ScheduleEvent(0, et_Throttle, Common::Timer::GetTimeMs()); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU) CoreTiming::ScheduleEvent(CP_PERIOD, et_CP); diff --git a/Source/Core/DolphinWX/ConfigMain.cpp b/Source/Core/DolphinWX/ConfigMain.cpp index 28e03ae4f6b6..90525d8c2542 100644 --- a/Source/Core/DolphinWX/ConfigMain.cpp +++ b/Source/Core/DolphinWX/ConfigMain.cpp @@ -118,7 +118,6 @@ EVT_CHECKBOX(ID_CPUTHREAD, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_IDLESKIP, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_ENABLECHEATS, CConfigMain::CoreSettingsChanged) EVT_CHOICE(ID_FRAMELIMIT, CConfigMain::CoreSettingsChanged) -EVT_CHECKBOX(ID_FRAMELIMIT_USEFPSFORLIMITING, CConfigMain::CoreSettingsChanged) EVT_RADIOBOX(ID_CPUENGINE, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_NTSCJ, CConfigMain::CoreSettingsChanged) @@ -324,7 +323,6 @@ void CConfigMain::InitializeGUIValues() SkipIdle->SetValue(startup_params.bSkipIdle); EnableCheats->SetValue(startup_params.bEnableCheats); Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit); - UseFPSForLimiting->SetValue(SConfig::GetInstance().b_UseFPS); // General - Advanced for (unsigned int a = 0; a < (sizeof(CPUCores) / sizeof(CPUCore)); ++a) @@ -549,7 +547,6 @@ void CConfigMain::CreateGUIControls() EnableCheats = new wxCheckBox(GeneralPage, ID_ENABLECHEATS, _("Enable Cheats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); // Framelimit Framelimit = new wxChoice(GeneralPage, ID_FRAMELIMIT, wxDefaultPosition, wxDefaultSize, arrayStringFor_Framelimit, 0, wxDefaultValidator); - UseFPSForLimiting = new wxCheckBox(GeneralPage, ID_FRAMELIMIT_USEFPSFORLIMITING, _("Limit by FPS"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); // Core Settings - Advanced CPUEngine = new wxRadioBox(GeneralPage, ID_CPUENGINE, _("CPU Emulator Engine"), wxDefaultPosition, wxDefaultSize, arrayStringFor_CPUEngine, 0, wxRA_SPECIFY_ROWS); _NTSCJ = new wxCheckBox(GeneralPage, ID_NTSCJ, _("Force Console as NTSC-J"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); @@ -558,7 +555,6 @@ void CConfigMain::CreateGUIControls() wxBoxSizer* sFramelimit = new wxBoxSizer(wxHORIZONTAL); sFramelimit->Add(TEXT_BOX(GeneralPage, _("Framelimit:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5); sFramelimit->Add(Framelimit, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5); - sFramelimit->Add(UseFPSForLimiting, 0, wxALL | wxEXPAND, 5); wxStaticBoxSizer* const sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, _("Basic Settings")); sbBasic->Add(CPUThread, 0, wxALL, 5); sbBasic->Add(SkipIdle, 0, wxALL, 5); @@ -890,9 +886,6 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event) SConfig::GetInstance().m_Framelimit = Framelimit->GetSelection(); AudioCommon::UpdateSoundStream(); break; - case ID_FRAMELIMIT_USEFPSFORLIMITING: - SConfig::GetInstance().b_UseFPS = UseFPSForLimiting->IsChecked(); - break; // Core - Advanced case ID_CPUENGINE: SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore = CPUCores[CPUEngine->GetSelection()].CPUid; diff --git a/Source/Core/DolphinWX/ConfigMain.h b/Source/Core/DolphinWX/ConfigMain.h index 43fa90c21bd4..b2f30b17dcc9 100644 --- a/Source/Core/DolphinWX/ConfigMain.h +++ b/Source/Core/DolphinWX/ConfigMain.h @@ -53,7 +53,6 @@ class CConfigMain : public wxDialog ID_IDLESKIP, ID_ENABLECHEATS, ID_FRAMELIMIT, - ID_FRAMELIMIT_USEFPSFORLIMITING, ID_CPUENGINE, ID_DSPTHREAD, @@ -123,7 +122,6 @@ class CConfigMain : public wxDialog wxCheckBox* SkipIdle; wxCheckBox* EnableCheats; wxChoice* Framelimit; - wxCheckBox* UseFPSForLimiting; // Advanced wxRadioBox* CPUEngine;