From ec29d120b5b47acb90834a8c3954e45ae8422acc Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 3 Mar 2025 20:36:08 -0600 Subject: [PATCH] CoreTiming: Add a setting to pursue accurate emulation time. --- Source/Core/Core/Config/MainSettings.cpp | 1 + Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/Core/CoreTiming.cpp | 16 +++++++++++++++- Source/Core/Core/CoreTiming.h | 3 +++ Source/Core/DolphinQt/Settings/AdvancedPane.cpp | 12 ++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 9f4d1cce17..98a985e177 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -45,6 +45,7 @@ const Info MAIN_ACCURATE_CPU_CACHE{{System::Main, "Core", "AccurateCPUCach const Info MAIN_DSP_HLE{{System::Main, "Core", "DSPHLE"}, true}; const Info MAIN_MAX_FALLBACK{{System::Main, "Core", "MaxFallback"}, 100}; const Info MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40}; +const Info MAIN_CORRECT_TIME_DRIFT{{System::Main, "Core", "CorrectTimeDrift"}, false}; const Info MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true}; const Info MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true}; const Info MAIN_DEFAULT_ISO{{System::Main, "Core", "DefaultISO"}, ""}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 28a044d253..4d66ecc3c4 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -63,6 +63,7 @@ extern const Info MAIN_ACCURATE_CPU_CACHE; extern const Info MAIN_DSP_HLE; extern const Info MAIN_MAX_FALLBACK; extern const Info MAIN_TIMING_VARIANCE; +extern const Info MAIN_CORRECT_TIME_DRIFT; extern const Info MAIN_CPU_THREAD; extern const Info MAIN_SYNC_ON_SKIP_IDLE; extern const Info MAIN_DEFAULT_ISO; diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp index 0de77f4446..d4c2fd6ce9 100644 --- a/Source/Core/Core/CoreTiming.cpp +++ b/Source/Core/Core/CoreTiming.cpp @@ -105,10 +105,20 @@ void CoreTimingManager::Init() m_last_oc_factor = m_config_oc_factor; m_globals.last_OC_factor_inverted = m_config_oc_inv_factor; + + m_on_state_changed_handle = Core::AddOnStateChangedCallback([this](Core::State state) { + if (state == Core::State::Running) + { + // We don't want Throttle to attempt catch-up for all the time lost while paused. + ResetThrottle(GetTicks()); + } + }); } void CoreTimingManager::Shutdown() { + Core::RemoveOnStateChangedCallback(&m_on_state_changed_handle); + std::lock_guard lk(m_ts_write_lock); MoveEvents(); ClearPendingEvents(); @@ -129,6 +139,8 @@ void CoreTimingManager::RefreshConfig() m_max_variance = std::chrono::duration_cast
(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE))); + m_correct_time_drift = Config::Get(Config::MAIN_CORRECT_TIME_DRIFT); + if (AchievementManager::GetInstance().IsHardcoreModeActive() && Config::Get(Config::MAIN_EMULATION_SPEED) < 1.0f && Config::Get(Config::MAIN_EMULATION_SPEED) > 0.0f) @@ -426,7 +438,9 @@ void CoreTimingManager::Throttle(const s64 target_cycle) const TimePoint time = Clock::now(); const TimePoint min_target = time - m_max_fallback; - if (target_time < min_target) + + // "Correct Time Drift" setting prevents timing relaxing. + if (!m_correct_time_drift && target_time < min_target) { // Core is running too slow.. i.e. CPU bottleneck. const DT adjustment = min_target - target_time; diff --git a/Source/Core/Core/CoreTiming.h b/Source/Core/Core/CoreTiming.h index d6f652c35a..48d3eddf6f 100644 --- a/Source/Core/Core/CoreTiming.h +++ b/Source/Core/Core/CoreTiming.h @@ -209,6 +209,7 @@ private: DT m_max_fallback = {}; DT m_max_variance = {}; + bool m_correct_time_drift = false; double m_emulation_speed = 1.0; bool IsSpeedUnlimited() const; @@ -223,6 +224,8 @@ private: std::atomic_bool m_use_precision_timer = false; Common::PrecisionTimer m_precision_cpu_timer; Common::PrecisionTimer m_precision_gpu_timer; + + int m_on_state_changed_handle; }; } // namespace CoreTiming diff --git a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp index 917e7e898c..c372eb966c 100644 --- a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp +++ b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp @@ -88,6 +88,18 @@ void AdvancedPane::CreateLayout() "needed.

If unsure, leave this unchecked.")); cpu_options_group_layout->addWidget(m_accurate_cpu_cache_checkbox); + auto* const timing_group = new QGroupBox(tr("Timing")); + main_layout->addWidget(timing_group); + auto* timing_group_layout = new QVBoxLayout{timing_group}; + auto* const correct_time_drift = + new ConfigBool{tr("Correct Time Drift"), Config::MAIN_CORRECT_TIME_DRIFT}; + correct_time_drift->SetDescription( + tr("Allow the emulated console to run fast after stutters," + "
pursuing accurate overall elapsed time unless paused or speed-adjusted." + "

This may be useful for internet play." + "

If unsure, leave this unchecked.")); + timing_group_layout->addWidget(correct_time_drift); + auto* clock_override = new QGroupBox(tr("Clock Override")); auto* clock_override_layout = new QVBoxLayout(); clock_override->setLayout(clock_override_layout);