diff --git a/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp index 3e50203778..7f0e81bfc0 100644 --- a/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.cpp @@ -40,8 +40,16 @@ BreakpointWidget::BreakpointWidget(QWidget* parent) : QDockWidget(parent) if (!Settings::Instance().IsDebugModeEnabled()) return; - m_load->setEnabled(Core::IsRunning()); - m_save->setEnabled(Core::IsRunning()); + bool is_initialised = state != Core::State::Uninitialized; + m_new->setEnabled(is_initialised); + m_load->setEnabled(is_initialised); + m_save->setEnabled(is_initialised); + if (!is_initialised) + { + PowerPC::breakpoints.Clear(); + PowerPC::memchecks.Clear(); + Update(); + } }); connect(&Settings::Instance(), &Settings::BreakpointsVisibilityChanged, @@ -77,8 +85,18 @@ void BreakpointWidget::CreateWidgets() m_table->setColumnCount(5); m_table->setSelectionMode(QAbstractItemView::SingleSelection); m_table->setSelectionBehavior(QAbstractItemView::SelectRows); + m_table->setEditTriggers(QAbstractItemView::NoEditTriggers); m_table->verticalHeader()->hide(); + connect(m_table, &QTableWidget::itemClicked, [this](QTableWidgetItem* item) { + if (m_table->selectedItems()[0]->row() == item->row() && + Core::GetState() == Core::State::Paused) + { + auto address = m_table->selectedItems()[0]->data(Qt::UserRole).toUInt(); + emit SelectedBreakpoint(address); + } + }); + auto* layout = new QVBoxLayout; layout->addWidget(m_toolbar); @@ -91,6 +109,7 @@ void BreakpointWidget::CreateWidgets() m_load = AddAction(m_toolbar, tr("Load"), this, &BreakpointWidget::OnLoad); m_save = AddAction(m_toolbar, tr("Save"), this, &BreakpointWidget::OnSave); + m_new->setEnabled(false); m_load->setEnabled(false); m_save->setEnabled(false); @@ -122,6 +141,7 @@ void BreakpointWidget::Update() {tr("Active"), tr("Type"), tr("Function"), tr("Address"), tr("Flags")}); int i = 0; + m_table->setRowCount(i); auto create_item = [this](const QString string = QStringLiteral("")) { QTableWidgetItem* item = new QTableWidgetItem(string); @@ -206,7 +226,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 +236,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 +271,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 +309,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 +329,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/BreakpointWidget.h b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.h index e7c5c93226..ed93890670 100644 --- a/Source/Core/DolphinQt2/Debugger/BreakpointWidget.h +++ b/Source/Core/DolphinQt2/Debugger/BreakpointWidget.h @@ -29,6 +29,7 @@ public: signals: void BreakpointsChanged(); + void SelectedBreakpoint(u32 address); protected: void closeEvent(QCloseEvent*) override; diff --git a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp index 0705dc5708..e531fc66c8 100644 --- a/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/CodeViewWidget.cpp @@ -39,12 +39,12 @@ CodeViewWidget::CodeViewWidget() setShowGrid(false); setContextMenuPolicy(Qt::CustomContextMenu); setSelectionMode(QAbstractItemView::SingleSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); verticalScrollBar()->setHidden(true); for (int i = 0; i < columnCount(); i++) { - horizontalHeader()->setSectionResizeMode(i, i == 0 ? QHeaderView::Fixed : - QHeaderView::ResizeToContents); + horizontalHeader()->setSectionResizeMode(i, QHeaderView::Fixed); } verticalHeader()->hide(); @@ -56,6 +56,7 @@ CodeViewWidget::CodeViewWidget() Update(); connect(this, &CodeViewWidget::customContextMenuRequested, this, &CodeViewWidget::OnContextMenu); + connect(this, &CodeViewWidget::itemSelectionChanged, this, &CodeViewWidget::OnSelectionChanged); connect(&Settings::Instance(), &Settings::DebugFontChanged, this, &QWidget::setFont); connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this] { m_address = PC; @@ -119,6 +120,23 @@ void CodeViewWidget::Update() auto* param_item = new QTableWidgetItem(QString::fromStdString(param)); auto* description_item = new QTableWidgetItem(QString::fromStdString(desc)); + for (auto* item : {bp_item, addr_item, ins_item, param_item, description_item}) + { + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + item->setData(Qt::UserRole, addr); + + if (color != 0xFFFFFF) + { + item->setForeground(QColor(Qt::black)); + item->setBackground(QColor(color)); + } + if (addr == pc && item != bp_item) + { + item->setBackground(QColor(Qt::green)); + item->setForeground(QColor(Qt::black)); + } + } + // look for hex strings to decode branches std::string hex_str; size_t pos = param.find("0x"); @@ -137,20 +155,6 @@ void CodeViewWidget::Update() if (ins == "blr") ins_item->setForeground(Qt::darkGreen); - for (auto* item : {bp_item, addr_item, ins_item, param_item, description_item}) - { - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); - item->setData(Qt::UserRole, addr); - - if (color != 0xFFFFFF) - item->setBackground(QColor(color).darker(110)); - - if (addr == pc && item != bp_item) - { - item->setBackground(QColor(Qt::green).darker(110)); - } - } - if (PowerPC::debug_interface.IsBreakpoint(addr)) { bp_item->setData(Qt::DecorationRole, @@ -165,10 +169,11 @@ void CodeViewWidget::Update() if (addr == GetAddress()) { - addr_item->setSelected(true); + selectRow(addr_item->row()); } } + resizeColumnsToContents(); setColumnWidth(0, 24 + 5); g_symbolDB.FillInCallers(); @@ -182,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) @@ -362,7 +368,7 @@ void CodeViewWidget::OnFollowBranch() if (!branch_addr) return; - SetAddress(branch_addr); + SetAddress(branch_addr, SetAddressUpdate::WithUpdate); } void CodeViewWidget::OnRenameSymbol() @@ -387,6 +393,19 @@ void CodeViewWidget::OnRenameSymbol() } } +void CodeViewWidget::OnSelectionChanged() +{ + if (m_address == PowerPC::ppcState.pc) + { + setStyleSheet(QString::fromStdString( + "QTableView::item:selected {background-color: #00FF00; color: #000000;}")); + } + else if (!styleSheet().isEmpty()) + { + setStyleSheet(QString::fromStdString("")); + } +} + void CodeViewWidget::OnSetSymbolSize() { const u32 addr = GetContextAddress(); @@ -515,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 4189588d07..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(); @@ -49,6 +55,7 @@ private: void OnCopyCode(); void OnCopyHex(); void OnRenameSymbol(); + void OnSelectionChanged(); void OnSetSymbolSize(); void OnSetSymbolEndAddress(); void OnRunToHere(); diff --git a/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp b/Source/Core/DolphinQt2/Debugger/CodeWidget.cpp index d1aa487591..8c644e7375 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()); }); @@ -141,7 +147,7 @@ void CodeWidget::ConnectWidgets() connect(m_search_address, &QLineEdit::textChanged, this, &CodeWidget::OnSearchAddress); connect(m_search_symbols, &QLineEdit::textChanged, this, &CodeWidget::OnSearchSymbols); - connect(m_symbols_list, &QListWidget::itemSelectionChanged, this, &CodeWidget::OnSelectSymbol); + connect(m_symbols_list, &QListWidget::itemClicked, this, &CodeWidget::OnSelectSymbol); connect(m_callstack_list, &QListWidget::itemSelectionChanged, this, &CodeWidget::OnSelectCallstack); connect(m_function_calls_list, &QListWidget::itemSelectionChanged, this, @@ -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,25 +237,30 @@ 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()); 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 +372,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 +392,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 +411,6 @@ void CodeWidget::StepOut() if (!CPU::IsStepping()) return; - Core::SetState(Core::State::Running); CPU::PauseAndLock(true, false); PowerPC::breakpoints.ClearAllTemporary(); @@ -447,16 +453,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 +471,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..70e2168b1c 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,8 +33,10 @@ public: void ToggleBreakpoint(); void AddBreakpoint(); + void SetAddress(u32 address, CodeViewWidget::SetAddressUpdate update); void Update(); + void UpdateSymbols(); signals: void BreakpointsChanged(); void RequestPPCComparison(u32 addr); @@ -43,7 +45,6 @@ private: void CreateWidgets(); void ConnectWidgets(); void UpdateCallstack(); - void UpdateSymbols(); void UpdateFunctionCalls(Symbol* symbol); void UpdateFunctionCallers(Symbol* symbol); diff --git a/Source/Core/DolphinQt2/Debugger/RegisterWidget.cpp b/Source/Core/DolphinQt2/Debugger/RegisterWidget.cpp index 57d0487c07..98db9f671f 100644 --- a/Source/Core/DolphinQt2/Debugger/RegisterWidget.cpp +++ b/Source/Core/DolphinQt2/Debugger/RegisterWidget.cpp @@ -7,6 +7,7 @@ #include "Core/Core.h" #include "Core/HW/ProcessorInterface.h" #include "Core/PowerPC/PowerPC.h" +#include "DolphinQt2/Host.h" #include "DolphinQt2/QtUtils/ActionHelper.h" #include "DolphinQt2/Settings.h" @@ -30,15 +31,13 @@ RegisterWidget::RegisterWidget(QWidget* parent) : QDockWidget(parent) PopulateTable(); ConnectWidgets(); - connect(&Settings::Instance(), &Settings::EmulationStateChanged, [this](Core::State state) { + connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] { if (Settings::Instance().IsDebugModeEnabled() && Core::GetState() == Core::State::Paused) - emit RequestTableUpdate(); - }); - - connect(this, &RegisterWidget::RequestTableUpdate, [this] { - m_updating = true; - emit UpdateTable(); - m_updating = false; + { + m_updating = true; + emit UpdateTable(); + m_updating = false; + } }); connect(&Settings::Instance(), &Settings::RegistersVisibilityChanged, @@ -74,7 +73,8 @@ void RegisterWidget::CreateWidgets() m_table->verticalHeader()->setVisible(false); m_table->verticalHeader()->setDefaultSectionSize(24); m_table->setContextMenuPolicy(Qt::CustomContextMenu); - m_table->setSelectionMode(QAbstractItemView::SingleSelection); + m_table->setSelectionMode(QAbstractItemView::NoSelection); + m_table->setFont(Settings::Instance().GetDebugFont()); QStringList empty_list; @@ -108,108 +108,105 @@ void RegisterWidget::ShowContextMenu() { QMenu* menu = new QMenu(this); - if (m_table->selectedItems().size()) + auto variant = m_table->currentItem()->data(DATA_TYPE); + + if (!variant.isNull()) { - auto variant = m_table->selectedItems()[0]->data(DATA_TYPE); + auto* item = static_cast(m_table->currentItem()); + auto type = static_cast(item->data(DATA_TYPE).toInt()); + auto display = item->GetDisplay(); - if (!variant.isNull()) + AddAction(menu, tr("Add to &watch"), this, + [this, item] { emit RequestMemoryBreakpoint(item->GetValue()); }); + menu->addAction(tr("View &memory")); + menu->addAction(tr("View &code")); + + menu->addSeparator(); + + QActionGroup* group = new QActionGroup(menu); + group->setExclusive(true); + + auto* view_hex = menu->addAction(tr("Hexadecimal")); + auto* view_int = menu->addAction(tr("Signed Integer")); + auto* view_uint = menu->addAction(tr("Unsigned Integer")); + // i18n: A floating point number + auto* view_float = menu->addAction(tr("Float")); + // i18n: A double precision floating point number + auto* view_double = menu->addAction(tr("Double")); + + for (auto* action : {view_hex, view_int, view_uint, view_float, view_double}) { - auto* item = reinterpret_cast(m_table->selectedItems()[0]); - auto type = static_cast(item->data(DATA_TYPE).toInt()); - auto display = item->GetDisplay(); - - AddAction(menu, tr("Add to &watch"), this, - [this, item] { emit RequestMemoryBreakpoint(item->GetValue()); }); - menu->addAction(tr("View &memory")); - menu->addAction(tr("View &code")); - - menu->addSeparator(); - - QActionGroup* group = new QActionGroup(menu); - group->setExclusive(true); - - auto* view_hex = menu->addAction(tr("Hexadecimal")); - auto* view_int = menu->addAction(tr("Signed Integer")); - auto* view_uint = menu->addAction(tr("Unsigned Integer")); - // i18n: A floating point number - auto* view_float = menu->addAction(tr("Float")); - // i18n: A double precision floating point number - auto* view_double = menu->addAction(tr("Double")); - - for (auto* action : {view_hex, view_int, view_uint, view_float, view_double}) - { - action->setCheckable(true); - action->setVisible(false); - action->setActionGroup(group); - } - - switch (display) - { - case RegisterDisplay::Hex: - view_hex->setChecked(true); - break; - case RegisterDisplay::SInt32: - view_int->setChecked(true); - break; - case RegisterDisplay::UInt32: - view_uint->setChecked(true); - break; - case RegisterDisplay::Float: - view_float->setChecked(true); - break; - case RegisterDisplay::Double: - view_double->setChecked(true); - break; - } - - switch (type) - { - case RegisterType::gpr: - view_hex->setVisible(true); - view_int->setVisible(true); - view_uint->setVisible(true); - view_float->setVisible(true); - break; - case RegisterType::fpr: - view_hex->setVisible(true); - view_double->setVisible(true); - break; - default: - break; - } - - connect(view_hex, &QAction::triggered, [this, item] { - m_updating = true; - item->SetDisplay(RegisterDisplay::Hex); - m_updating = false; - }); - - connect(view_int, &QAction::triggered, [this, item] { - m_updating = true; - item->SetDisplay(RegisterDisplay::SInt32); - m_updating = false; - }); - - connect(view_uint, &QAction::triggered, [this, item] { - m_updating = true; - item->SetDisplay(RegisterDisplay::UInt32); - m_updating = false; - }); - - connect(view_float, &QAction::triggered, [this, item] { - m_updating = true; - item->SetDisplay(RegisterDisplay::Float); - m_updating = false; - }); - - connect(view_double, &QAction::triggered, [this, item] { - m_updating = true; - item->SetDisplay(RegisterDisplay::Double); - m_updating = false; - }); - - menu->addSeparator(); + action->setCheckable(true); + action->setVisible(false); + action->setActionGroup(group); } + + switch (display) + { + case RegisterDisplay::Hex: + view_hex->setChecked(true); + break; + case RegisterDisplay::SInt32: + view_int->setChecked(true); + break; + case RegisterDisplay::UInt32: + view_uint->setChecked(true); + break; + case RegisterDisplay::Float: + view_float->setChecked(true); + break; + case RegisterDisplay::Double: + view_double->setChecked(true); + break; + } + + switch (type) + { + case RegisterType::gpr: + view_hex->setVisible(true); + view_int->setVisible(true); + view_uint->setVisible(true); + view_float->setVisible(true); + break; + case RegisterType::fpr: + view_hex->setVisible(true); + view_double->setVisible(true); + break; + default: + break; + } + + connect(view_hex, &QAction::triggered, [this, item] { + m_updating = true; + item->SetDisplay(RegisterDisplay::Hex); + m_updating = false; + }); + + connect(view_int, &QAction::triggered, [this, item] { + m_updating = true; + item->SetDisplay(RegisterDisplay::SInt32); + m_updating = false; + }); + + connect(view_uint, &QAction::triggered, [this, item] { + m_updating = true; + item->SetDisplay(RegisterDisplay::UInt32); + m_updating = false; + }); + + connect(view_float, &QAction::triggered, [this, item] { + m_updating = true; + item->SetDisplay(RegisterDisplay::Float); + m_updating = false; + }); + + connect(view_double, &QAction::triggered, [this, item] { + m_updating = true; + item->SetDisplay(RegisterDisplay::Double); + m_updating = false; + }); + + menu->addSeparator(); } AddAction(menu, tr("Update"), this, [this] { emit RequestTableUpdate(); }); @@ -356,10 +353,12 @@ void RegisterWidget::AddRegister(int row, int column, RegisterType type, std::st m_table->setItem(row, column, label); m_table->setItem(row, column + 1, value); + m_table->item(row, column + 1)->setTextAlignment(Qt::AlignRight); } else { m_table->setItem(row, column, value); + m_table->item(row, column)->setTextAlignment(Qt::AlignRight); } connect(this, &RegisterWidget::UpdateTable, [value] { value->RefreshValue(); }); 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/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 48e02313e7..8064717bf9 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -54,6 +54,7 @@ #include "DolphinQt2/Config/Mapping/MappingWindow.h" #include "DolphinQt2/Config/SettingsWindow.h" #include "DolphinQt2/Debugger/BreakpointWidget.h" +#include "DolphinQt2/Debugger/CodeViewWidget.h" #include "DolphinQt2/Debugger/CodeWidget.h" #include "DolphinQt2/Debugger/JITWidget.h" #include "DolphinQt2/Debugger/MemoryWidget.h" @@ -256,6 +257,10 @@ void MainWindow::CreateComponents() &CodeWidget::Update); connect(m_breakpoint_widget, &BreakpointWidget::BreakpointsChanged, m_memory_widget, &MemoryWidget::Update); + connect(m_breakpoint_widget, &BreakpointWidget::SelectedBreakpoint, [this](u32 address) { + if (Core::GetState() == Core::State::Paused) + m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithUpdate); + }); #if defined(HAVE_XRANDR) && HAVE_XRANDR m_xrr_config = std::make_unique( @@ -346,6 +351,12 @@ void MainWindow::ConnectMenuBar() connect(m_game_list, &GameList::SelectionChanged, m_menu_bar, &MenuBar::SelectionChanged); connect(this, &MainWindow::ReadOnlyModeChanged, m_menu_bar, &MenuBar::ReadOnlyModeChanged); connect(this, &MainWindow::RecordingStatusChanged, m_menu_bar, &MenuBar::RecordingStatusChanged); + + // Symbols + connect(m_menu_bar, &MenuBar::NotifySymbolsUpdated, [this] { + m_code_widget->UpdateSymbols(); + m_code_widget->Update(); + }); } void MainWindow::ConnectHotkeys() @@ -453,14 +464,14 @@ void MainWindow::ConnectStack() setCentralWidget(m_stack); setTabPosition(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea, QTabWidget::North); - addDockWidget(Qt::RightDockWidgetArea, m_log_widget); - addDockWidget(Qt::RightDockWidgetArea, m_log_config_widget); - addDockWidget(Qt::RightDockWidgetArea, m_code_widget); - addDockWidget(Qt::RightDockWidgetArea, m_register_widget); - addDockWidget(Qt::RightDockWidgetArea, m_watch_widget); - addDockWidget(Qt::RightDockWidgetArea, m_breakpoint_widget); - addDockWidget(Qt::RightDockWidgetArea, m_memory_widget); - addDockWidget(Qt::RightDockWidgetArea, m_jit_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_log_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_log_config_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_code_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_register_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_watch_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_breakpoint_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_memory_widget); + addDockWidget(Qt::LeftDockWidgetArea, m_jit_widget); tabifyDockWidget(m_log_widget, m_log_config_widget); tabifyDockWidget(m_log_widget, m_code_widget); diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index a7fb9c0744..7d4e46ceba 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); @@ -1016,13 +1020,13 @@ void MenuBar::ClearSymbols() return; g_symbolDB.Clear(); - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } void MenuBar::GenerateSymbolsFromAddress() { PPCAnalyst::FindFunctions(0x80000000, 0x81800000, &g_symbolDB); - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } void MenuBar::GenerateSymbolsFromSignatureDB() @@ -1044,7 +1048,7 @@ void MenuBar::GenerateSymbolsFromSignatureDB() tr("'%1' not found, no symbol names generated").arg(QString::fromStdString(TOTALDB))); } - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } void MenuBar::GenerateSymbolsFromRSO() @@ -1063,7 +1067,7 @@ void MenuBar::GenerateSymbolsFromRSO() if (rso_chain.Load(static_cast(address))) { rso_chain.Apply(&g_symbolDB); - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } else { @@ -1097,7 +1101,7 @@ void MenuBar::LoadSymbolMap() } HLE::PatchFunctions(); - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } void MenuBar::SaveSymbolMap() @@ -1119,7 +1123,7 @@ void MenuBar::LoadOtherSymbolMap() g_symbolDB.LoadMap(file.toStdString()); HLE::PatchFunctions(); - Host_NotifyMapLoaded(); + emit NotifySymbolsUpdated(); } void MenuBar::SaveSymbolMapAs() diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index fb2f2b9d4b..8998c8f3d5 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -102,6 +102,9 @@ signals: void RecordingStatusChanged(bool recording); void ReadOnlyModeChanged(bool read_only); + // Synbols + void NotifySymbolsUpdated(); + private: void OnEmulationStateChanged(Core::State state); 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()