From 575062a612f7c684cabc59748f496281db5bc118 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 6 Jan 2022 14:38:09 -0800 Subject: [PATCH 1/2] FifoPlayer: Store early memory updates option in the config Now, early memory updates is persisted across runs, and can be toggled before starting a fifolog. --- Source/Core/Core/Config/MainSettings.cpp | 2 ++ Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/Core/FifoPlayer/FifoPlayer.cpp | 8 +++++ Source/Core/Core/FifoPlayer/FifoPlayer.h | 11 +++---- .../Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp | 30 ++++++++++++++----- Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h | 8 +++-- 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 7f8c132c58..d729302190 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -354,6 +354,8 @@ const Info MAIN_GAMELIST_COLUMN_TAGS{{System::Main, "GameList", "ColumnTag // Main.FifoPlayer const Info MAIN_FIFOPLAYER_LOOP_REPLAY{{System::Main, "FifoPlayer", "LoopReplay"}, true}; +const Info MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES{ + {System::Main, "FifoPlayer", "EarlyMemoryUpdates"}, false}; // Main.AutoUpdate diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 0e5b0fdbe9..308c85b693 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -254,6 +254,7 @@ extern const Info MAIN_GAMELIST_COLUMN_TAGS; // Main.FifoPlayer extern const Info MAIN_FIFOPLAYER_LOOP_REPLAY; +extern const Info MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES; // Main.AutoUpdate diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 6a48352060..4a3677b936 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -165,10 +165,13 @@ bool IsPlayingBackFifologWithBrokenEFBCopies = false; FifoPlayer::FifoPlayer() : m_Loop{Config::Get(Config::MAIN_FIFOPLAYER_LOOP_REPLAY)} { + m_config_changed_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); + RefreshConfig(); } FifoPlayer::~FifoPlayer() { + Config::RemoveConfigChangedCallback(m_config_changed_callback_id); } bool FifoPlayer::Open(const std::string& filename) @@ -298,6 +301,11 @@ std::unique_ptr FifoPlayer::GetCPUCore() return std::make_unique(this); } +void FifoPlayer::RefreshConfig() +{ + m_EarlyMemoryUpdates = Config::Get(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES); +} + void FifoPlayer::SetFileLoadedCallback(CallbackFunc callback) { m_FileLoadedCb = std::move(callback); diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h index af19bac944..eb06012085 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h @@ -122,9 +122,7 @@ public: void SetObjectRangeStart(u32 start) { m_ObjectRangeStart = start; } u32 GetObjectRangeEnd() const { return m_ObjectRangeEnd; } void SetObjectRangeEnd(u32 end) { m_ObjectRangeEnd = end; } - // If enabled then all memory updates happen at once before the first frame - // Default is disabled - void SetEarlyMemoryUpdates(bool enabled) { m_EarlyMemoryUpdates = enabled; } + // Callbacks void SetFileLoadedCallback(CallbackFunc callback); void SetFrameWrittenCallback(CallbackFunc callback) { m_FrameWrittenCb = std::move(callback); } @@ -172,7 +170,11 @@ private: static bool IsIdleSet(); static bool IsHighWatermarkSet(); + void RefreshConfig(); + bool m_Loop; + // If enabled then all memory updates happen at once before the first frame + bool m_EarlyMemoryUpdates = false; u32 m_CurrentFrame = 0; u32 m_FrameRangeStart = 0; @@ -181,14 +183,13 @@ private: u32 m_ObjectRangeStart = 0; u32 m_ObjectRangeEnd = 10000; - bool m_EarlyMemoryUpdates = false; - u64 m_CyclesPerFrame = 0; u32 m_ElapsedCycles = 0; u32 m_FrameFifoSize = 0; CallbackFunc m_FileLoadedCb = nullptr; CallbackFunc m_FrameWrittenCb = nullptr; + size_t m_config_changed_callback_id; std::unique_ptr m_File; diff --git a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp index c9f9a6ceff..fcc1932e82 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp +++ b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp @@ -24,6 +24,7 @@ #include "Core/FifoPlayer/FifoPlayer.h" #include "Core/FifoPlayer/FifoRecorder.h" +#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h" #include "DolphinQt/FIFO/FIFOAnalyzer.h" #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" @@ -38,6 +39,7 @@ FIFOPlayerWindow::FIFOPlayerWindow(QWidget* parent) : QWidget(parent) CreateWidgets(); ConnectWidgets(); + AddDescriptions(); UpdateInfo(); @@ -116,7 +118,7 @@ void FIFOPlayerWindow::CreateWidgets() // Playback Options auto* playback_group = new QGroupBox(tr("Playback Options")); auto* playback_layout = new QGridLayout; - m_early_memory_updates = new QCheckBox(tr("Early Memory Updates")); + m_early_memory_updates = new ToolTipCheckBox(tr("Early Memory Updates")); playback_layout->addWidget(object_range_group, 0, 0); playback_layout->addWidget(frame_range_group, 0, 1); @@ -166,6 +168,11 @@ void FIFOPlayerWindow::CreateWidgets() setLayout(tab_layout); } +void FIFOPlayerWindow::LoadSettings() +{ + m_early_memory_updates->setChecked(Config::Get(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES)); +} + void FIFOPlayerWindow::ConnectWidgets() { connect(m_load, &QPushButton::clicked, this, &FIFOPlayerWindow::LoadRecording); @@ -173,8 +180,8 @@ void FIFOPlayerWindow::ConnectWidgets() connect(m_record, &QPushButton::clicked, this, &FIFOPlayerWindow::StartRecording); connect(m_stop, &QPushButton::clicked, this, &FIFOPlayerWindow::StopRecording); connect(m_button_box, &QDialogButtonBox::rejected, this, &FIFOPlayerWindow::hide); - connect(m_early_memory_updates, &QCheckBox::toggled, this, - &FIFOPlayerWindow::OnEarlyMemoryUpdatesChanged); + connect(m_early_memory_updates, &QCheckBox::toggled, this, &FIFOPlayerWindow::OnConfigChanged); + connect(m_frame_range_from, qOverload(&QSpinBox::valueChanged), this, &FIFOPlayerWindow::OnLimitsChanged); connect(m_frame_range_to, qOverload(&QSpinBox::valueChanged), this, @@ -186,6 +193,16 @@ void FIFOPlayerWindow::ConnectWidgets() &FIFOPlayerWindow::OnLimitsChanged); } +void FIFOPlayerWindow::AddDescriptions() +{ + static const char TR_MEMORY_UPDATES_DESCRIPTION[] = QT_TR_NOOP( + "If enabled, then all memory updates happen at once before the first frame.

" + "Causes issues with many fifologs, but can be useful for testing.

" + "If unsure, leave this unchecked."); + + m_early_memory_updates->SetDescription(tr(TR_MEMORY_UPDATES_DESCRIPTION)); +} + void FIFOPlayerWindow::LoadRecording() { QString path = DolphinFileDialog::getOpenFileName(this, tr("Open FIFO log"), QString(), @@ -324,9 +341,10 @@ void FIFOPlayerWindow::OnFIFOLoaded() m_analyzer->Update(); } -void FIFOPlayerWindow::OnEarlyMemoryUpdatesChanged(bool enabled) +void FIFOPlayerWindow::OnConfigChanged() { - FifoPlayer::GetInstance().SetEarlyMemoryUpdates(enabled); + Config::SetBase(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES, + m_early_memory_updates->isChecked()); } void FIFOPlayerWindow::OnLimitsChanged() @@ -363,8 +381,6 @@ void FIFOPlayerWindow::UpdateControls() m_object_range_to->setEnabled(is_playing); m_object_range_to_label->setEnabled(is_playing); - m_early_memory_updates->setEnabled(is_playing); - bool enable_frame_record_count = !is_playing && !is_recording; m_frame_record_count_label->setEnabled(enable_frame_record_count); diff --git a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h index 2fe7bce352..292e2783c7 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h +++ b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h @@ -7,12 +7,12 @@ #include "Core/Core.h" -class QCheckBox; class QDialogButtonBox; class QLabel; class QPushButton; class QSpinBox; class QTabWidget; +class ToolTipCheckBox; class FIFOAnalyzer; class FIFOPlayerWindow : public QWidget @@ -27,7 +27,9 @@ signals: private: void CreateWidgets(); + void LoadSettings(); void ConnectWidgets(); + void AddDescriptions(); void LoadRecording(); void SaveRecording(); @@ -37,9 +39,9 @@ private: void OnEmulationStarted(); void OnEmulationStopped(); void OnLimitsChanged(); - void OnEarlyMemoryUpdatesChanged(bool enabled); void OnRecordingDone(); void OnFIFOLoaded(); + void OnConfigChanged(); void UpdateControls(); void UpdateInfo(); @@ -62,7 +64,7 @@ private: QLabel* m_object_range_from_label; QSpinBox* m_object_range_to; QLabel* m_object_range_to_label; - QCheckBox* m_early_memory_updates; + ToolTipCheckBox* m_early_memory_updates; QDialogButtonBox* m_button_box; QWidget* m_main_widget; From 29df17d422bd4912987eda501e7d68c312763106 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 6 Jan 2022 14:47:36 -0800 Subject: [PATCH 2/2] FifoPlayer: Allow changing loop option at runtime This option has always existed since it's used by FifoCI, but now it can be changed at runtime. Looping is something that should almost always be on, but it can be useful to turn it off when frame-dumping is enabled so that hundreds of copies of the same frame aren't created. Before, turning it off required restarting Dolphin. --- Source/Core/Core/FifoPlayer/FifoPlayer.cpp | 3 ++- Source/Core/Core/FifoPlayer/FifoPlayer.h | 2 +- Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp | 12 +++++++++++- Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 4a3677b936..9117e4d0f4 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -163,7 +163,7 @@ void FifoPlaybackAnalyzer::OnCommand(const u8* data, u32 size) bool IsPlayingBackFifologWithBrokenEFBCopies = false; -FifoPlayer::FifoPlayer() : m_Loop{Config::Get(Config::MAIN_FIFOPLAYER_LOOP_REPLAY)} +FifoPlayer::FifoPlayer() { m_config_changed_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); RefreshConfig(); @@ -303,6 +303,7 @@ std::unique_ptr FifoPlayer::GetCPUCore() void FifoPlayer::RefreshConfig() { + m_Loop = Config::Get(Config::MAIN_FIFOPLAYER_LOOP_REPLAY); m_EarlyMemoryUpdates = Config::Get(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES); } diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h index eb06012085..365add85fe 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h @@ -172,7 +172,7 @@ private: void RefreshConfig(); - bool m_Loop; + bool m_Loop = true; // If enabled then all memory updates happen at once before the first frame bool m_EarlyMemoryUpdates = false; diff --git a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp index fcc1932e82..bda4da3d88 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp +++ b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp @@ -119,10 +119,12 @@ void FIFOPlayerWindow::CreateWidgets() auto* playback_group = new QGroupBox(tr("Playback Options")); auto* playback_layout = new QGridLayout; m_early_memory_updates = new ToolTipCheckBox(tr("Early Memory Updates")); + m_loop = new ToolTipCheckBox(tr("Loop")); playback_layout->addWidget(object_range_group, 0, 0); playback_layout->addWidget(frame_range_group, 0, 1); - playback_layout->addWidget(m_early_memory_updates, 1, 0, 1, -1); + playback_layout->addWidget(m_early_memory_updates, 1, 0); + playback_layout->addWidget(m_loop, 1, 1); playback_group->setLayout(playback_layout); // Recording Options @@ -171,6 +173,7 @@ void FIFOPlayerWindow::CreateWidgets() void FIFOPlayerWindow::LoadSettings() { m_early_memory_updates->setChecked(Config::Get(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES)); + m_loop->setChecked(Config::Get(Config::MAIN_FIFOPLAYER_LOOP_REPLAY)); } void FIFOPlayerWindow::ConnectWidgets() @@ -181,6 +184,7 @@ void FIFOPlayerWindow::ConnectWidgets() connect(m_stop, &QPushButton::clicked, this, &FIFOPlayerWindow::StopRecording); connect(m_button_box, &QDialogButtonBox::rejected, this, &FIFOPlayerWindow::hide); connect(m_early_memory_updates, &QCheckBox::toggled, this, &FIFOPlayerWindow::OnConfigChanged); + connect(m_loop, &QCheckBox::toggled, this, &FIFOPlayerWindow::OnConfigChanged); connect(m_frame_range_from, qOverload(&QSpinBox::valueChanged), this, &FIFOPlayerWindow::OnLimitsChanged); @@ -199,8 +203,13 @@ void FIFOPlayerWindow::AddDescriptions() "If enabled, then all memory updates happen at once before the first frame.

" "Causes issues with many fifologs, but can be useful for testing.

" "If unsure, leave this unchecked."); + static const char TR_LOOP_DESCRIPTION[] = + QT_TR_NOOP("If unchecked, then playback of the fifolog stops after the final frame.

" + "This is generally only useful when a frame-dumping option is enabled.

" + "If unsure, leave this checked."); m_early_memory_updates->SetDescription(tr(TR_MEMORY_UPDATES_DESCRIPTION)); + m_loop->SetDescription(tr(TR_LOOP_DESCRIPTION)); } void FIFOPlayerWindow::LoadRecording() @@ -345,6 +354,7 @@ void FIFOPlayerWindow::OnConfigChanged() { Config::SetBase(Config::MAIN_FIFOPLAYER_EARLY_MEMORY_UPDATES, m_early_memory_updates->isChecked()); + Config::SetBase(Config::MAIN_FIFOPLAYER_LOOP_REPLAY, m_loop->isChecked()); } void FIFOPlayerWindow::OnLimitsChanged() diff --git a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h index 292e2783c7..a5e2562c1f 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h +++ b/Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.h @@ -65,6 +65,7 @@ private: QSpinBox* m_object_range_to; QLabel* m_object_range_to_label; ToolTipCheckBox* m_early_memory_updates; + ToolTipCheckBox* m_loop; QDialogButtonBox* m_button_box; QWidget* m_main_widget;