diff --git a/src/duckstation-qt/debuggerwindow.cpp b/src/duckstation-qt/debuggerwindow.cpp index 9247b371b..1f6115bb7 100644 --- a/src/duckstation-qt/debuggerwindow.cpp +++ b/src/duckstation-qt/debuggerwindow.cpp @@ -15,6 +15,8 @@ #include #include +static constexpr int TIMER_REFRESH_INTERVAL_MS = 100; + DebuggerWindow::DebuggerWindow(QWidget* parent /* = nullptr */) : QMainWindow(parent), m_active_memory_region(Bus::MemoryRegion::Count) { @@ -64,11 +66,16 @@ void DebuggerWindow::onDebuggerMessageReported(const QString& message) m_ui.statusbar->showMessage(message, 0); } +void DebuggerWindow::timerRefresh() +{ + m_ui.memoryView->forceRefresh(); +} + void DebuggerWindow::refreshAll() { m_registers_model->updateValues(); m_stack_model->invalidateView(); - m_ui.memoryView->repaint(); + m_ui.memoryView->forceRefresh(); m_code_model->setPC(CPU::g_state.pc); scrollToPC(); @@ -478,6 +485,9 @@ void DebuggerWindow::connectSignals() connect(m_ui.memorySearch, &QPushButton::clicked, this, &DebuggerWindow::onMemorySearchTriggered); connect(m_ui.memorySearchString, &QLineEdit::textChanged, this, &DebuggerWindow::onMemorySearchStringChanged); + + connect(&m_refresh_timer, &QTimer::timeout, this, &DebuggerWindow::timerRefresh); + m_refresh_timer.setInterval(TIMER_REFRESH_INTERVAL_MS); } void DebuggerWindow::disconnectSignals() @@ -514,28 +524,35 @@ void DebuggerWindow::createModels() void DebuggerWindow::setUIEnabled(bool enabled, bool allow_pause) { + const bool memory_view_enabled = (enabled || allow_pause); + m_ui.actionPause->setEnabled(allow_pause); // Disable all UI elements that depend on execution state m_ui.codeView->setEnabled(enabled); m_ui.registerView->setEnabled(enabled); m_ui.stackView->setEnabled(enabled); - m_ui.memoryView->setEnabled(enabled); + m_ui.memoryView->setEnabled(memory_view_enabled); m_ui.actionRunToCursor->setEnabled(enabled); m_ui.actionAddBreakpoint->setEnabled(enabled); m_ui.actionToggleBreakpoint->setEnabled(enabled); m_ui.actionClearBreakpoints->setEnabled(enabled); - m_ui.actionDumpAddress->setEnabled(enabled); + m_ui.actionDumpAddress->setEnabled(memory_view_enabled); m_ui.actionStepInto->setEnabled(enabled); m_ui.actionStepOver->setEnabled(enabled); m_ui.actionStepOut->setEnabled(enabled); m_ui.actionGoToAddress->setEnabled(enabled); m_ui.actionGoToPC->setEnabled(enabled); m_ui.actionTrace->setEnabled(enabled); - m_ui.memoryRegionRAM->setEnabled(enabled); - m_ui.memoryRegionEXP1->setEnabled(enabled); - m_ui.memoryRegionScratchpad->setEnabled(enabled); - m_ui.memoryRegionBIOS->setEnabled(enabled); + m_ui.memoryRegionRAM->setEnabled(memory_view_enabled); + m_ui.memoryRegionEXP1->setEnabled(memory_view_enabled); + m_ui.memoryRegionScratchpad->setEnabled(memory_view_enabled); + m_ui.memoryRegionBIOS->setEnabled(memory_view_enabled); + + // Partial/timer refreshes only active when not paused. + const bool timer_active = (!enabled && allow_pause); + if (m_refresh_timer.isActive() != timer_active) + timer_active ? m_refresh_timer.start() : m_refresh_timer.stop(); } void DebuggerWindow::saveCurrentState() diff --git a/src/duckstation-qt/debuggerwindow.h b/src/duckstation-qt/debuggerwindow.h index 571affe14..61aef9375 100644 --- a/src/duckstation-qt/debuggerwindow.h +++ b/src/duckstation-qt/debuggerwindow.h @@ -8,6 +8,7 @@ #include "core/cpu_core.h" #include "core/types.h" +#include #include #include #include @@ -41,6 +42,7 @@ private Q_SLOTS: void onSystemResumed(); void onDebuggerMessageReported(const QString& message); + void timerRefresh(); void refreshAll(); void scrollToPC(); @@ -89,6 +91,8 @@ private: std::unique_ptr m_registers_model; std::unique_ptr m_stack_model; + QTimer m_refresh_timer; + Bus::MemoryRegion m_active_memory_region; PhysicalMemoryAddress m_next_memory_search_address = 0; diff --git a/src/duckstation-qt/memoryviewwidget.cpp b/src/duckstation-qt/memoryviewwidget.cpp index 8621982d1..5b4d5cbb1 100644 --- a/src/duckstation-qt/memoryviewwidget.cpp +++ b/src/duckstation-qt/memoryviewwidget.cpp @@ -125,7 +125,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event) { m_selected_address--; m_editing_nibble = -1; - viewport()->update(); + forceRefresh(); } } else @@ -139,7 +139,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event) expandCurrentDataToInclude(m_selected_address); std::memcpy(static_cast(m_data) + m_selected_address, &ch, sizeof(unsigned char)); m_selected_address = std::min(m_selected_address + 1, m_data_size - 1); - viewport()->update(); + forceRefresh(); } else { @@ -165,7 +165,7 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event) m_selected_address = std::min(m_selected_address + 1, m_data_size - 1); } - viewport()->update(); + forceRefresh(); } } } @@ -381,7 +381,7 @@ void MemoryViewWidget::updateSelectedByte(const QPoint& pos) m_selected_address = new_selection; m_selection_was_ascii = new_ascii; m_editing_nibble = -1; - viewport()->update(); + forceRefresh(); } } @@ -419,6 +419,11 @@ void MemoryViewWidget::saveCurrentData() m_last_data_start_offset = m_start_offset; m_last_data.resize(size); std::memcpy(m_last_data.data(), static_cast(m_data) + m_start_offset, size); + forceRefresh(); +} + +void MemoryViewWidget::forceRefresh() +{ viewport()->update(); } @@ -447,5 +452,8 @@ void MemoryViewWidget::adjustContent() verticalScrollBar()->setRange(0, lineCount - m_rows_visible); verticalScrollBar()->setPageStep(m_rows_visible); - viewport()->update(); + expandCurrentDataToInclude(m_start_offset); + expandCurrentDataToInclude(m_end_offset); + + forceRefresh(); } \ No newline at end of file diff --git a/src/duckstation-qt/memoryviewwidget.h b/src/duckstation-qt/memoryviewwidget.h index 1791fc469..2f6209bf6 100644 --- a/src/duckstation-qt/memoryviewwidget.h +++ b/src/duckstation-qt/memoryviewwidget.h @@ -34,6 +34,7 @@ protected: public Q_SLOTS: void saveCurrentData(); + void forceRefresh(); private Q_SLOTS: void adjustContent();