From a5dfc68ac9206fb31f677ba399936bbbc3aa3a1e Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 26 Jan 2021 03:12:19 +1000 Subject: [PATCH] GameSettings: Add runahead as per-game setting --- src/duckstation-qt/gamepropertiesdialog.cpp | 14 ++++ src/duckstation-qt/gamepropertiesdialog.ui | 77 ++++++++++++++++++++- src/frontend-common/game_list.h | 2 +- src/frontend-common/game_settings.cpp | 35 ++++++++-- src/frontend-common/game_settings.h | 1 + 5 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/duckstation-qt/gamepropertiesdialog.cpp b/src/duckstation-qt/gamepropertiesdialog.cpp index c62067b2e..1e0e78fd2 100644 --- a/src/duckstation-qt/gamepropertiesdialog.cpp +++ b/src/duckstation-qt/gamepropertiesdialog.cpp @@ -268,6 +268,12 @@ void GamePropertiesDialog::populateGameSettings() m_trait_checkboxes[i]->setChecked(gs.HasTrait(static_cast(i))); } + if (gs.runahead_frames.has_value()) + { + QSignalBlocker sb(m_ui.userRunaheadFrames); + m_ui.userRunaheadFrames->setCurrentIndex(static_cast(gs.runahead_frames.value())); + } + if (gs.cpu_overclock_numerator.has_value() || gs.cpu_overclock_denominator.has_value()) { const u32 numerator = gs.cpu_overclock_numerator.value_or(1); @@ -491,6 +497,14 @@ void GamePropertiesDialog::connectUi() m_ui.exportCompatibilityInfo->setVisible(show_buttons); }); + connect(m_ui.userRunaheadFrames, QOverload::of(&QComboBox::currentIndexChanged), [this](int index) { + if (index <= 0) + m_game_settings.runahead_frames.reset(); + else + m_game_settings.runahead_frames = static_cast(index - 1); + saveGameSettings(); + }); + connectBooleanUserSetting(m_ui.userEnableCPUClockSpeedControl, &m_game_settings.cpu_overclock_enable); connect(m_ui.userEnableCPUClockSpeedControl, &QCheckBox::stateChanged, this, &GamePropertiesDialog::updateCPUClockSpeedLabel); diff --git a/src/duckstation-qt/gamepropertiesdialog.ui b/src/duckstation-qt/gamepropertiesdialog.ui index 09118dd3b..bd0e389b5 100644 --- a/src/duckstation-qt/gamepropertiesdialog.ui +++ b/src/duckstation-qt/gamepropertiesdialog.ui @@ -6,8 +6,8 @@ 0 0 - 750 - 567 + 793 + 619 @@ -436,7 +436,7 @@ Other Settings - + @@ -503,6 +503,77 @@ + + + + Runahead Frames: + + + + + + + + (unchanged) + + + + + Disabled + + + + + 1 Frame + + + + + 2 Frames + + + + + 3 Frames + + + + + 4 Frames + + + + + 5 Frames + + + + + 6 Frames + + + + + 7 Frames + + + + + 8 Frames + + + + + 9 Frames + + + + + 10 Frames + + + + diff --git a/src/frontend-common/game_list.h b/src/frontend-common/game_list.h index d7138287a..eaf311eb5 100644 --- a/src/frontend-common/game_list.h +++ b/src/frontend-common/game_list.h @@ -119,7 +119,7 @@ private: enum : u32 { GAME_LIST_CACHE_SIGNATURE = 0x45434C47, - GAME_LIST_CACHE_VERSION = 21 + GAME_LIST_CACHE_VERSION = 22 }; using DatabaseMap = std::unordered_map; diff --git a/src/frontend-common/game_settings.cpp b/src/frontend-common/game_settings.cpp index f7b47a912..291015118 100644 --- a/src/frontend-common/game_settings.cpp +++ b/src/frontend-common/game_settings.cpp @@ -105,7 +105,8 @@ bool Entry::LoadFromStream(ByteStream* stream) constexpr u32 num_bytes = (static_cast(Trait::Count) + 7) / 8; std::array bits; - if (!stream->Read2(bits.data(), num_bytes) || !ReadOptionalFromStream(stream, &cpu_overclock_numerator) || + if (!stream->Read2(bits.data(), num_bytes) || !ReadOptionalFromStream(stream, &runahead_frames) || + !ReadOptionalFromStream(stream, &cpu_overclock_numerator) || !ReadOptionalFromStream(stream, &cpu_overclock_denominator) || !ReadOptionalFromStream(stream, &cpu_overclock_enable) || !ReadOptionalFromStream(stream, &cdrom_read_speedup) || !ReadOptionalFromStream(stream, &display_active_start_offset) || @@ -156,7 +157,8 @@ bool Entry::SaveToStream(ByteStream* stream) const bits[i / 8] |= (1u << (i % 8)); } - return stream->Write2(bits.data(), num_bytes) && WriteOptionalToStream(stream, cpu_overclock_numerator) && + return stream->Write2(bits.data(), num_bytes) && WriteOptionalToStream(stream, runahead_frames) && + WriteOptionalToStream(stream, cpu_overclock_numerator) && WriteOptionalToStream(stream, cpu_overclock_denominator) && WriteOptionalToStream(stream, cpu_overclock_enable) && WriteOptionalToStream(stream, cdrom_read_speedup) && WriteOptionalToStream(stream, display_active_start_offset) && @@ -189,7 +191,11 @@ static void ParseIniSection(Entry* entry, const char* section, const CSimpleIniA entry->AddTrait(static_cast(trait)); } - const char* cvalue = ini.GetValue(section, "CPUOverclockNumerator", nullptr); + const char* cvalue = ini.GetValue(section, "RunaheadFrameCount", nullptr); + if (cvalue) + entry->runahead_frames = StringUtil::FromChars(cvalue); + + cvalue = ini.GetValue(section, "CPUOverclockNumerator", nullptr); if (cvalue) entry->cpu_overclock_numerator = StringUtil::FromChars(cvalue); cvalue = ini.GetValue(section, "CPUOverclockDenominator", nullptr); @@ -316,6 +322,9 @@ static void StoreIniSection(const Entry& entry, const char* section, CSimpleIniA ini.SetBoolValue(section, s_trait_names[trait].first, true); } + if (entry.runahead_frames.has_value()) + ini.SetLongValue(section, "RunaheadFrameCount", static_cast(entry.runahead_frames.value())); + if (entry.cpu_overclock_numerator.has_value()) ini.SetLongValue(section, "CPUOverclockNumerator", static_cast(entry.cpu_overclock_numerator.value())); if (entry.cpu_overclock_denominator.has_value()) @@ -409,7 +418,14 @@ static void StoreIniSection(const Entry& entry, const char* section, CSimpleIniA static std::optional GetEntryValueForKey(const Entry& entry, const std::string_view& key) { - if (key == "CPUOverclock") + if (key == "RunaheadFrameCount") + { + if (!entry.runahead_frames.has_value()) + return std::nullopt; + + return std::to_string(entry.runahead_frames.value()); + } + else if (key == "CPUOverclock") { if (!entry.cpu_overclock_enable.has_value()) return std::nullopt; @@ -592,7 +608,14 @@ static std::optional GetEntryValueForKey(const Entry& entry, const static void SetEntryValueForKey(Entry& entry, const std::string_view& key, const std::optional& value) { - if (key == "CPUOverclock") + if (key == "RunaheadFrameCount") + { + if (!value.has_value()) + entry.runahead_frames.reset(); + else + entry.runahead_frames = StringUtil::FromChars(value.value()); + } + else if (key == "CPUOverclock") { if (!value.has_value()) { @@ -897,6 +920,8 @@ void Entry::ApplySettings(bool display_osd_messages) const { constexpr float osd_duration = 10.0f; + if (runahead_frames.has_value()) + g_settings.runahead_frames = runahead_frames.value(); if (cpu_overclock_numerator.has_value()) g_settings.cpu_overclock_numerator = cpu_overclock_numerator.value(); if (cpu_overclock_denominator.has_value()) diff --git a/src/frontend-common/game_settings.h b/src/frontend-common/game_settings.h index 3325e047f..c1480e8ef 100644 --- a/src/frontend-common/game_settings.h +++ b/src/frontend-common/game_settings.h @@ -50,6 +50,7 @@ struct Entry std::optional gpu_pgxp_depth_threshold; // user settings + std::optional runahead_frames; std::optional cpu_overclock_numerator; std::optional cpu_overclock_denominator; std::optional cpu_overclock_enable;