From 238c801711f9daa4613e988fa2147bd9e852ba91 Mon Sep 17 00:00:00 2001 From: aldelaro5 Date: Sat, 5 May 2018 18:17:06 -0400 Subject: [PATCH] Qt/debugger: properly updates when we break The Host_UpdateDisasmDialog was unimplemented in Qt which is required to get updates when we break. Additionally, this updates the debugger toolbar. --- .../DolphinQt2/Debugger/BreakpointWidget.cpp | 10 ++++ .../DolphinQt2/Debugger/CodeViewWidget.cpp | 9 ++-- .../Core/DolphinQt2/Debugger/CodeViewWidget.h | 8 ++- .../Core/DolphinQt2/Debugger/CodeWidget.cpp | 51 ++++++++++--------- Source/Core/DolphinQt2/Debugger/CodeWidget.h | 3 +- Source/Core/DolphinQt2/Host.cpp | 5 ++ Source/Core/DolphinQt2/Host.h | 1 + Source/Core/DolphinQt2/MenuBar.cpp | 4 ++ Source/Core/DolphinQt2/ToolBar.cpp | 18 +++++++ 9 files changed, 80 insertions(+), 29 deletions(-) diff --git a/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp index 3e50203778..7f746d289c 100644 --- a/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp @@ -206,7 +206,9 @@ void BreakpointWidget::OnDelete() auto address = m_table->selectedItems()[0]->data(Qt::UserRole).toUInt(); PowerPC::breakpoints.Remove(address); + Settings::Instance().blockSignals(true); PowerPC::memchecks.Remove(address); + Settings::Instance().blockSignals(false); Update(); } @@ -214,7 +216,9 @@ void BreakpointWidget::OnDelete() void BreakpointWidget::OnClear() { PowerPC::debug_interface.ClearAllBreakpoints(); + Settings::Instance().blockSignals(true); PowerPC::debug_interface.ClearAllMemChecks(); + Settings::Instance().blockSignals(false); m_table->setRowCount(0); Update(); @@ -247,7 +251,9 @@ void BreakpointWidget::OnLoad() if (ini.GetLines("MemoryBreakPoints", &newmcs, false)) { PowerPC::memchecks.Clear(); + Settings::Instance().blockSignals(true); PowerPC::memchecks.AddFromStrings(newmcs); + Settings::Instance().blockSignals(false); } Update(); @@ -283,7 +289,9 @@ void BreakpointWidget::AddAddressMBP(u32 addr, bool on_read, bool on_write, bool check.log_on_hit = do_log; check.break_on_hit = do_break; + Settings::Instance().blockSignals(true); PowerPC::memchecks.Add(check); + Settings::Instance().blockSignals(false); Update(); } @@ -301,7 +309,9 @@ void BreakpointWidget::AddRangedMBP(u32 from, u32 to, bool on_read, bool on_writ check.log_on_hit = do_log; check.break_on_hit = do_break; + Settings::Instance().blockSignals(true); PowerPC::memchecks.Add(check); + Settings::Instance().blockSignals(false); Update(); } diff --git a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp index 7bfc4131bd..10ac62d7a6 100644 --- a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp @@ -187,13 +187,14 @@ u32 CodeViewWidget::GetAddress() const return m_address; } -void CodeViewWidget::SetAddress(u32 address) +void CodeViewWidget::SetAddress(u32 address, SetAddressUpdate update) { if (m_address == address) return; m_address = address; - Update(); + if (update == SetAddressUpdate::WithUpdate) + Update(); } void CodeViewWidget::ReplaceAddress(u32 address, bool blr) @@ -367,7 +368,7 @@ void CodeViewWidget::OnFollowBranch() if (!branch_addr) return; - SetAddress(branch_addr); + SetAddress(branch_addr, SetAddressUpdate::WithUpdate); } void CodeViewWidget::OnRenameSymbol() @@ -533,7 +534,7 @@ void CodeViewWidget::mousePressEvent(QMouseEvent* event) if (column(item) == 0) ToggleBreakpoint(); else - SetAddress(addr); + SetAddress(addr, SetAddressUpdate::WithUpdate); Update(); break; diff --git a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.h b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.h index 3db80cfc16..a6e038b447 100644 --- a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.h +++ b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.h @@ -18,11 +18,17 @@ class CodeViewWidget : public QTableWidget { Q_OBJECT public: + enum class SetAddressUpdate + { + WithUpdate, + WithoutUpdate + }; + explicit CodeViewWidget(); u32 GetAddress() const; u32 GetContextAddress() const; - void SetAddress(u32 address); + void SetAddress(u32 address, SetAddressUpdate update); void Update(); diff --git a/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp b/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp index d1aa487591..060494c0c8 100644 --- a/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp @@ -21,7 +21,7 @@ #include "Core/HW/CPU.h" #include "Core/PowerPC/PPCSymbolDB.h" #include "Core/PowerPC/PowerPC.h" -#include "DolphinQt2/Debugger/CodeViewWidget.h" +#include "DolphinQt2/Host.h" #include "DolphinQt2/Settings.h" CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent) @@ -39,6 +39,12 @@ CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent) connect(&Settings::Instance(), &Settings::CodeVisibilityChanged, [this](bool visible) { setHidden(!visible); }); + connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] { + if (Core::GetState() == Core::State::Paused) + SetAddress(PowerPC::ppcState.pc, CodeViewWidget::SetAddressUpdate::WithoutUpdate); + Update(); + }); + connect(&Settings::Instance(), &Settings::DebugModeToggled, [this](bool enabled) { setHidden(!enabled || !Settings::Instance().IsCodeVisible()); }); @@ -175,7 +181,7 @@ void CodeWidget::OnSearchAddress() m_search_address->setFont(font); if (good) - m_code_view->SetAddress(address); + m_code_view->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } @@ -194,7 +200,8 @@ void CodeWidget::OnSelectSymbol() Symbol* symbol = g_symbolDB.GetSymbolFromAddr(items[0]->data(Qt::UserRole).toUInt()); - m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt()); + m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt(), + CodeViewWidget::SetAddressUpdate::WithUpdate); UpdateCallstack(); UpdateFunctionCalls(symbol); UpdateFunctionCallers(symbol); @@ -208,7 +215,8 @@ void CodeWidget::OnSelectCallstack() if (items.isEmpty()) return; - m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt()); + m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt(), + CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } @@ -218,7 +226,8 @@ void CodeWidget::OnSelectFunctionCalls() if (items.isEmpty()) return; - m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt()); + m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt(), + CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } @@ -228,10 +237,16 @@ void CodeWidget::OnSelectFunctionCallers() if (items.isEmpty()) return; - m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt()); + m_code_view->SetAddress(items[0]->data(Qt::UserRole).toUInt(), + CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } +void CodeWidget::SetAddress(u32 address, CodeViewWidget::SetAddressUpdate update) +{ + m_code_view->SetAddress(address, update); +} + void CodeWidget::Update() { Symbol* symbol = g_symbolDB.GetSymbolFromAddr(m_code_view->GetAddress()); @@ -239,14 +254,14 @@ void CodeWidget::Update() UpdateCallstack(); UpdateSymbols(); + m_code_view->Update(); + m_code_view->setFocus(); + if (!symbol) return; UpdateFunctionCalls(symbol); UpdateFunctionCallers(symbol); - - m_code_view->Update(); - m_code_view->setFocus(); } void CodeWidget::UpdateCallstack() @@ -358,10 +373,7 @@ void CodeWidget::Step() sync_event.WaitFor(std::chrono::milliseconds(20)); PowerPC::SetMode(old_mode); Core::DisplayMessage(tr("Step successful!").toStdString(), 2000); - - Core::SetState(Core::State::Paused); - m_code_view->SetAddress(PC); - Update(); + // Will get a UpdateDisasmDialog(), don't update the GUI here. } void CodeWidget::StepOver() @@ -381,10 +393,6 @@ void CodeWidget::StepOver() { Step(); } - - Core::SetState(Core::State::Paused); - m_code_view->SetAddress(PC); - Update(); } // Returns true on a rfi, blr or on a bclr that evaluates to true. @@ -404,7 +412,6 @@ void CodeWidget::StepOut() if (!CPU::IsStepping()) return; - Core::SetState(Core::State::Running); CPU::PauseAndLock(true, false); PowerPC::breakpoints.ClearAllTemporary(); @@ -447,16 +454,14 @@ void CodeWidget::StepOut() PowerPC::SetMode(old_mode); CPU::PauseAndLock(false, false); + emit Host::GetInstance()->UpdateDisasmDialog(); + if (PowerPC::breakpoints.IsAddressBreakPoint(PC)) Core::DisplayMessage(tr("Breakpoint encountered! Step out aborted.").toStdString(), 2000); else if (clock::now() >= timeout) Core::DisplayMessage(tr("Step out timed out!").toStdString(), 2000); else Core::DisplayMessage(tr("Step out successful!").toStdString(), 2000); - - Core::SetState(Core::State::Paused); - m_code_view->SetAddress(PC); - Update(); } void CodeWidget::Skip() @@ -467,7 +472,7 @@ void CodeWidget::Skip() void CodeWidget::ShowPC() { - m_code_view->SetAddress(PC); + m_code_view->SetAddress(PC, CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } diff --git a/Source/Core/DolphinQt2/Debugger/CodeWidget.h b/Source/Core/DolphinQt2/Debugger/CodeWidget.h index b9c1a9b962..ccc783bae6 100644 --- a/Source/Core/DolphinQt2/Debugger/CodeWidget.h +++ b/Source/Core/DolphinQt2/Debugger/CodeWidget.h @@ -8,8 +8,8 @@ #include #include "Common/CommonTypes.h" +#include "DolphinQt2/Debugger/CodeViewWidget.h" -class CodeViewWidget; class QCloseEvent; class QLineEdit; class QSplitter; @@ -33,6 +33,7 @@ public: void ToggleBreakpoint(); void AddBreakpoint(); + void SetAddress(u32 address, CodeViewWidget::SetAddressUpdate update); void Update(); signals: diff --git a/Source/Core/DolphinQt2/Host.cpp b/Source/Core/DolphinQt2/Host.cpp index 10773f0b12..83b8010539 100644 --- a/Source/Core/DolphinQt2/Host.cpp +++ b/Source/Core/DolphinQt2/Host.cpp @@ -14,6 +14,7 @@ #include "Core/Debugger/PPCDebugInterface.h" #include "Core/Host.h" #include "Core/PowerPC/PowerPC.h" +#include "DolphinQt2/QtUtils/RunOnObject.h" #include "DolphinQt2/Settings.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoConfig.h" @@ -109,6 +110,10 @@ void Host_YieldToUI() void Host_UpdateDisasmDialog() { + RunOnObject(QApplication::instance(), [&] { + emit Host::GetInstance()->UpdateDisasmDialog(); + return true; + }); } void Host_UpdateProgressDialog(const char* caption, int position, int total) diff --git a/Source/Core/DolphinQt2/Host.h b/Source/Core/DolphinQt2/Host.h index 486217bcf2..81f98f5272 100644 --- a/Source/Core/DolphinQt2/Host.h +++ b/Source/Core/DolphinQt2/Host.h @@ -33,6 +33,7 @@ signals: void RequestStop(); void RequestRenderSize(int w, int h); void UpdateProgressDialog(QString label, int position, int maximum); + void UpdateDisasmDialog(); private: Host(); diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index a7fb9c0744..7ffe83eecb 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -46,6 +46,7 @@ #include "DiscIO/WiiSaveBanner.h" #include "DolphinQt2/AboutDialog.h" +#include "DolphinQt2/Host.h" #include "DolphinQt2/QtUtils/ActionHelper.h" #include "DolphinQt2/Settings.h" @@ -65,6 +66,9 @@ MenuBar::MenuBar(QWidget* parent) : QMenuBar(parent) connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [=](Core::State state) { OnEmulationStateChanged(state); }); + connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, + [this] { OnEmulationStateChanged(Core::GetState()); }); + OnEmulationStateChanged(Core::GetState()); connect(&Settings::Instance(), &Settings::DebugModeToggled, this, &MenuBar::OnDebugModeToggled); diff --git a/Source/Core/DolphinQt2/ToolBar.cpp b/Source/Core/DolphinQt2/ToolBar.cpp index d7755344a4..0b186a8751 100644 --- a/Source/Core/DolphinQt2/ToolBar.cpp +++ b/Source/Core/DolphinQt2/ToolBar.cpp @@ -8,6 +8,7 @@ #include #include "Core/Core.h" +#include "DolphinQt2/Host.h" #include "DolphinQt2/QtUtils/ActionHelper.h" #include "DolphinQt2/Resources.h" #include "DolphinQt2/Settings.h" @@ -33,6 +34,9 @@ ToolBar::ToolBar(QWidget* parent) : QToolBar(parent) connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) { OnEmulationStateChanged(state); }); + connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, + [this] { OnEmulationStateChanged(Core::GetState()); }); + connect(&Settings::Instance(), &Settings::DebugModeToggled, this, &ToolBar::OnDebugModeToggled); connect(&Settings::Instance(), &Settings::ToolBarVisibilityChanged, this, &ToolBar::setVisible); @@ -56,6 +60,13 @@ void ToolBar::OnEmulationStateChanged(Core::State state) m_play_action->setVisible(!playing); m_pause_action->setEnabled(playing); m_pause_action->setVisible(playing); + + bool paused = Core::GetState() == Core::State::Paused; + m_step_action->setEnabled(paused); + m_step_over_action->setEnabled(paused); + m_step_out_action->setEnabled(paused); + m_skip_action->setEnabled(paused); + m_set_pc_action->setEnabled(paused); } void ToolBar::closeEvent(QCloseEvent*) @@ -71,6 +82,13 @@ void ToolBar::OnDebugModeToggled(bool enabled) m_skip_action->setVisible(enabled); m_show_pc_action->setVisible(enabled); m_set_pc_action->setVisible(enabled); + + bool paused = Core::GetState() == Core::State::Paused; + m_step_action->setEnabled(paused); + m_step_over_action->setEnabled(paused); + m_step_out_action->setEnabled(paused); + m_skip_action->setEnabled(paused); + m_set_pc_action->setEnabled(paused); } void ToolBar::MakeActions()