diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp index 5943f3d067..67b21ea33b 100644 --- a/Source/Core/Common/Config/Config.cpp +++ b/Source/Core/Common/Config/Config.cpp @@ -5,17 +5,19 @@ #include #include -#include #include #include #include +#include +#include namespace Config { using Layers = std::map>; static Layers s_layers; -static std::list s_callbacks; +static std::vector> s_callbacks; +static size_t s_next_callback_id = 0; static u32 s_callback_guards = 0; static std::atomic s_config_version = 0; @@ -63,9 +65,24 @@ void RemoveLayer(LayerType layer) OnConfigChanged(); } -void AddConfigChangedCallback(ConfigChangedCallback func) +size_t AddConfigChangedCallback(ConfigChangedCallback func) { - s_callbacks.emplace_back(std::move(func)); + const size_t callback_id = s_next_callback_id; + ++s_next_callback_id; + s_callbacks.emplace_back(std::make_pair(callback_id, std::move(func))); + return callback_id; +} + +void RemoveConfigChangedCallback(size_t callback_id) +{ + for (auto it = s_callbacks.begin(); it != s_callbacks.end(); ++it) + { + if (it->first == callback_id) + { + s_callbacks.erase(it); + return; + } + } } void OnConfigChanged() @@ -79,7 +96,7 @@ void OnConfigChanged() return; for (const auto& callback : s_callbacks) - callback(); + callback.second(); } u64 GetConfigVersion() diff --git a/Source/Core/Common/Config/Config.h b/Source/Core/Common/Config/Config.h index d2d3fd5c10..d956a203aa 100644 --- a/Source/Core/Common/Config/Config.h +++ b/Source/Core/Common/Config/Config.h @@ -22,7 +22,9 @@ void AddLayer(std::unique_ptr loader); std::shared_ptr GetLayer(LayerType layer); void RemoveLayer(LayerType layer); -void AddConfigChangedCallback(ConfigChangedCallback func); +// returns an ID that can be passed to RemoveConfigChangedCallback() +size_t AddConfigChangedCallback(ConfigChangedCallback func); +void RemoveConfigChangedCallback(size_t callback_id); void OnConfigChanged(); // Returns the number of times the config has changed in the current execution of the program diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 83361a1c1e..40930117aa 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -91,8 +91,6 @@ private: int iSelectedLanguage = 0; PowerPC::CPUCore cpu_core = PowerPC::CPUCore::Interpreter; float m_EmulationSpeed = 0; - float m_OCFactor = 0; - bool m_OCEnable = false; bool m_bt_passthrough_enabled = false; std::string m_strGPUDeterminismMode; std::array iWiimoteSource{}; @@ -123,8 +121,6 @@ void ConfigCache::SaveConfig(const SConfig& config) cpu_core = config.cpu_core; m_EmulationSpeed = config.m_EmulationSpeed; m_strGPUDeterminismMode = config.m_strGPUDeterminismMode; - m_OCFactor = config.m_OCFactor; - m_OCEnable = config.m_OCEnable; m_bt_passthrough_enabled = config.m_bt_passthrough_enabled; for (int i = 0; i != MAX_BBMOTES; ++i) @@ -193,8 +189,6 @@ void ConfigCache::RestoreConfig(SConfig* config) } config->m_strGPUDeterminismMode = m_strGPUDeterminismMode; - config->m_OCFactor = m_OCFactor; - config->m_OCEnable = m_OCEnable; config->m_bt_passthrough_enabled = m_bt_passthrough_enabled; } @@ -265,8 +259,6 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) core_section->Get("GPUDeterminismMode", &StartUp.m_strGPUDeterminismMode, StartUp.m_strGPUDeterminismMode); - core_section->Get("Overclock", &StartUp.m_OCFactor, StartUp.m_OCFactor); - core_section->Get("OverclockEnable", &StartUp.m_OCEnable, StartUp.m_OCEnable); for (unsigned int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i) { @@ -344,8 +336,6 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) StartUp.cpu_core = netplay_settings.m_CPUcore; StartUp.SelectedLanguage = netplay_settings.m_SelectedLanguage; StartUp.bOverrideRegionSettings = netplay_settings.m_OverrideRegionSettings; - StartUp.m_OCEnable = netplay_settings.m_OCEnable; - StartUp.m_OCFactor = netplay_settings.m_OCFactor; StartUp.m_EXIDevice[0] = netplay_settings.m_EXIDevice[0]; StartUp.m_EXIDevice[1] = netplay_settings.m_EXIDevice[1]; StartUp.m_EXIDevice[2] = netplay_settings.m_EXIDevice[2]; diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp index 972f66bb2f..281b77d77a 100644 --- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp +++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp @@ -60,6 +60,8 @@ bool IsSettingSaveable(const Config::Location& config_location) &Config::MAIN_AUDIO_LATENCY.GetLocation(), &Config::MAIN_AUDIO_STRETCH.GetLocation(), &Config::MAIN_AUDIO_STRETCH_LATENCY.GetLocation(), + &Config::MAIN_OVERCLOCK.GetLocation(), + &Config::MAIN_OVERCLOCK_ENABLE.GetLocation(), &Config::MAIN_RAM_OVERRIDE_ENABLE.GetLocation(), &Config::MAIN_MEM1_SIZE.GetLocation(), &Config::MAIN_MEM2_SIZE.GetLocation(), diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 0a156d98fe..87e931d613 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -195,8 +195,6 @@ void SConfig::SaveCoreSettings(IniFile& ini) core->Set("RunCompareClient", bRunCompareClient); core->Set("MMU", bMMU); core->Set("EmulationSpeed", m_EmulationSpeed); - core->Set("Overclock", m_OCFactor); - core->Set("OverclockEnable", m_OCEnable); core->Set("GPUDeterminismMode", m_strGPUDeterminismMode); core->Set("PerfMapDir", m_perfDir); core->Set("EnableCustomRTC", bEnableCustomRTC); @@ -397,8 +395,6 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("AccurateNaNs", &bAccurateNaNs, false); core->Get("DisableICache", &bDisableICache, false); core->Get("EmulationSpeed", &m_EmulationSpeed, 1.0f); - core->Get("Overclock", &m_OCFactor, 1.0f); - core->Get("OverclockEnable", &m_OCEnable, false); core->Get("GPUDeterminismMode", &m_strGPUDeterminismMode, "auto"); core->Get("PerfMapDir", &m_perfDir, ""); core->Get("EnableCustomRTC", &bEnableCustomRTC, false); diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index f08eaabc76..35603b5ad1 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -221,8 +221,6 @@ struct SConfig // interface language std::string m_InterfaceLanguage; float m_EmulationSpeed; - bool m_OCEnable; - float m_OCFactor; // other interface settings bool m_InterfaceExtendedFPSInfo; bool m_show_active_title = false; diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp index b72c3e3bd8..f850c726d6 100644 --- a/Source/Core/Core/CoreTiming.cpp +++ b/Source/Core/Core/CoreTiming.cpp @@ -16,6 +16,7 @@ #include "Common/Logging/Log.h" #include "Common/SPSCQueue.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/PowerPC/PowerPC.h" @@ -77,6 +78,10 @@ Globals g; static EventType* s_ev_lost = nullptr; +static size_t s_registered_config_callback_id; +static float s_config_OC_factor; +static float s_config_OC_inv_factor; + static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) { } @@ -121,8 +126,12 @@ void UnregisterAllEvents() void Init() { - s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; - g.last_OC_factor_inverted = 1.0f / s_last_OC_factor; + s_registered_config_callback_id = + Config::AddConfigChangedCallback([]() { Core::RunAsCPUThread([]() { RefreshConfig(); }); }); + RefreshConfig(); + + s_last_OC_factor = s_config_OC_factor; + g.last_OC_factor_inverted = s_config_OC_inv_factor; PowerPC::ppcState.downcount = CyclesToDowncount(MAX_SLICE_LENGTH); g.slice_length = MAX_SLICE_LENGTH; g.global_timer = 0; @@ -144,6 +153,14 @@ void Shutdown() MoveEvents(); ClearPendingEvents(); UnregisterAllEvents(); + Config::RemoveConfigChangedCallback(s_registered_config_callback_id); +} + +void RefreshConfig() +{ + s_config_OC_factor = + Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f; + s_config_OC_inv_factor = 1.0f / s_config_OC_factor; } void DoState(PointerWrap& p) @@ -316,8 +333,8 @@ void Advance() int cyclesExecuted = g.slice_length - DowncountToCycles(PowerPC::ppcState.downcount); g.global_timer += cyclesExecuted; - s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; - g.last_OC_factor_inverted = 1.0f / s_last_OC_factor; + s_last_OC_factor = s_config_OC_factor; + g.last_OC_factor_inverted = s_config_OC_inv_factor; g.slice_length = MAX_SLICE_LENGTH; s_is_global_timer_sane = true; diff --git a/Source/Core/Core/CoreTiming.h b/Source/Core/Core/CoreTiming.h index f66fba5614..255aa612ca 100644 --- a/Source/Core/Core/CoreTiming.h +++ b/Source/Core/Core/CoreTiming.h @@ -46,6 +46,8 @@ typedef void (*TimedCallback)(u64 userdata, s64 cyclesLate); u64 GetTicks(); u64 GetIdleTicks(); +void RefreshConfig(); + void DoState(PointerWrap& p); struct EventType; diff --git a/Source/Core/Core/DolphinAnalytics.cpp b/Source/Core/Core/DolphinAnalytics.cpp index a15715c58f..e780f21685 100644 --- a/Source/Core/Core/DolphinAnalytics.cpp +++ b/Source/Core/Core/DolphinAnalytics.cpp @@ -363,8 +363,8 @@ void DolphinAnalytics::MakePerGameBuilder() builder.AddData("cfg-fastmem", SConfig::GetInstance().bFastmem); builder.AddData("cfg-syncgpu", SConfig::GetInstance().bSyncGPU); builder.AddData("cfg-audio-backend", Config::Get(Config::MAIN_AUDIO_BACKEND)); - builder.AddData("cfg-oc-enable", SConfig::GetInstance().m_OCEnable); - builder.AddData("cfg-oc-factor", SConfig::GetInstance().m_OCFactor); + builder.AddData("cfg-oc-enable", Config::Get(Config::MAIN_OVERCLOCK_ENABLE)); + builder.AddData("cfg-oc-factor", Config::Get(Config::MAIN_OVERCLOCK)); builder.AddData("cfg-render-to-main", Config::Get(Config::MAIN_RENDER_TO_MAIN)); if (g_video_backend) { diff --git a/Source/Core/Core/IOS/DolphinDevice.cpp b/Source/Core/Core/IOS/DolphinDevice.cpp index face12f66d..699cacfd42 100644 --- a/Source/Core/Core/IOS/DolphinDevice.cpp +++ b/Source/Core/Core/IOS/DolphinDevice.cpp @@ -15,6 +15,7 @@ #include "Common/Timer.h" #include "Common/Version.h" #include "Core/BootManager.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/Memmap.h" @@ -79,8 +80,8 @@ IPCReply GetCPUSpeed(const IOCtlVRequest& request) return IPCReply(IPC_EINVAL); } - const SConfig& config = SConfig::GetInstance(); - const float oc = config.m_OCEnable ? config.m_OCFactor : 1.0f; + const bool overclock_enabled = Config::Get(Config::MAIN_OVERCLOCK_ENABLE); + const float oc = overclock_enabled ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f; const u32 core_clock = u32(float(SystemTimers::GetTicksPerSecond()) * oc); diff --git a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp index e38533ee94..78b1fcc3d7 100644 --- a/Source/Core/DolphinQt/Settings/AdvancedPane.cpp +++ b/Source/Core/DolphinQt/Settings/AdvancedPane.cpp @@ -181,9 +181,8 @@ void AdvancedPane::ConnectLayout() connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this, [](bool checked) { SConfig::GetInstance().bMMU = checked; }); - m_cpu_clock_override_checkbox->setChecked(SConfig::GetInstance().m_OCEnable); + m_cpu_clock_override_checkbox->setChecked(Config::Get(Config::MAIN_OVERCLOCK_ENABLE)); connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) { - SConfig::GetInstance().m_OCEnable = enable_clock_override; Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK_ENABLE, enable_clock_override); Update(); }); @@ -191,7 +190,6 @@ void AdvancedPane::ConnectLayout() connect(m_cpu_clock_override_slider, &QSlider::valueChanged, [this](int oc_factor) { // Vaguely exponential scaling? const float factor = std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f); - SConfig::GetInstance().m_OCFactor = factor; Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK, factor); Update(); }); @@ -232,7 +230,7 @@ void AdvancedPane::ConnectLayout() void AdvancedPane::Update() { const bool running = Core::GetState() != Core::State::Uninitialized; - const bool enable_cpu_clock_override_widgets = SConfig::GetInstance().m_OCEnable; + const bool enable_cpu_clock_override_widgets = Config::Get(Config::MAIN_OVERCLOCK_ENABLE); const bool enable_ram_override_widgets = Config::Get(Config::MAIN_RAM_OVERRIDE_ENABLE); const bool enable_custom_rtc_widgets = SConfig::GetInstance().bEnableCustomRTC && !running; @@ -258,14 +256,14 @@ void AdvancedPane::Update() { const QSignalBlocker blocker(m_cpu_clock_override_slider); - m_cpu_clock_override_slider->setValue( - static_cast(std::round(std::log2f(SConfig::GetInstance().m_OCFactor) * 25.f + 100.f))); + m_cpu_clock_override_slider->setValue(static_cast( + std::round(std::log2f(Config::Get(Config::MAIN_OVERCLOCK)) * 25.f + 100.f))); } m_cpu_clock_override_slider_label->setText([] { int core_clock = SystemTimers::GetTicksPerSecond() / std::pow(10, 6); - int percent = static_cast(std::round(SConfig::GetInstance().m_OCFactor * 100.f)); - int clock = static_cast(std::round(SConfig::GetInstance().m_OCFactor * core_clock)); + int percent = static_cast(std::round(Config::Get(Config::MAIN_OVERCLOCK) * 100.f)); + int clock = static_cast(std::round(Config::Get(Config::MAIN_OVERCLOCK) * core_clock)); return tr("%1% (%2 MHz)").arg(QString::number(percent), QString::number(clock)); }()); diff --git a/Source/UnitTests/Core/CoreTimingTest.cpp b/Source/UnitTests/Core/CoreTimingTest.cpp index fa4678df1b..b08919679d 100644 --- a/Source/UnitTests/Core/CoreTimingTest.cpp +++ b/Source/UnitTests/Core/CoreTimingTest.cpp @@ -9,6 +9,7 @@ #include "Common/Config/Config.h" #include "Common/FileUtil.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" @@ -304,8 +305,8 @@ TEST(CoreTiming, Overclocking) CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>); // Overclock - SConfig::GetInstance().m_OCEnable = true; - SConfig::GetInstance().m_OCFactor = 2.0; + Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, true); + Config::SetCurrent(Config::MAIN_OVERCLOCK, 2.0f); // Enter slice 0 // Updates s_last_OC_factor. @@ -325,7 +326,7 @@ TEST(CoreTiming, Overclocking) AdvanceAndCheck(4, MAX_SLICE_LENGTH * 2); // Underclock - SConfig::GetInstance().m_OCFactor = 0.5; + Config::SetCurrent(Config::MAIN_OVERCLOCK, 0.5f); CoreTiming::Advance(); CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]); @@ -342,7 +343,7 @@ TEST(CoreTiming, Overclocking) AdvanceAndCheck(4, MAX_SLICE_LENGTH / 2); // Try switching the clock mid-emulation - SConfig::GetInstance().m_OCFactor = 1.0; + Config::SetCurrent(Config::MAIN_OVERCLOCK, 1.0f); CoreTiming::Advance(); CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]); @@ -353,11 +354,11 @@ TEST(CoreTiming, Overclocking) EXPECT_EQ(100, PowerPC::ppcState.downcount); AdvanceAndCheck(0, 100); // (200 - 100) - SConfig::GetInstance().m_OCFactor = 2.0; + Config::SetCurrent(Config::MAIN_OVERCLOCK, 2.0f); AdvanceAndCheck(1, 400); // (400 - 200) * 2 AdvanceAndCheck(2, 800); // (800 - 400) * 2 - SConfig::GetInstance().m_OCFactor = 0.1f; + Config::SetCurrent(Config::MAIN_OVERCLOCK, 0.1f); AdvanceAndCheck(3, 80); // (1600 - 800) / 10 - SConfig::GetInstance().m_OCFactor = 1.0; + Config::SetCurrent(Config::MAIN_OVERCLOCK, 1.0f); AdvanceAndCheck(4, MAX_SLICE_LENGTH); }