From 09db4e9e2ad8af2d4c675b8ee1fceb240c3f1919 Mon Sep 17 00:00:00 2001 From: Nick Renieris Date: Wed, 1 Apr 2020 01:02:24 +0300 Subject: [PATCH] Qt/Debugger: Don't move entire list if it's not needed With 4 buffer spaces at the bottom. --- rpcs3/rpcs3qt/breakpoint_list.h | 2 +- rpcs3/rpcs3qt/call_stack_list.h | 2 +- rpcs3/rpcs3qt/debugger_list.cpp | 55 +++++++++++++++++++-------------- rpcs3/rpcs3qt/debugger_list.h | 2 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/rpcs3/rpcs3qt/breakpoint_list.h b/rpcs3/rpcs3qt/breakpoint_list.h index 77143cbac40..2b3eb950a80 100644 --- a/rpcs3/rpcs3qt/breakpoint_list.h +++ b/rpcs3/rpcs3qt/breakpoint_list.h @@ -22,7 +22,7 @@ class breakpoint_list : public QListWidget QColor m_text_color_bp; QColor m_color_bp; Q_SIGNALS: - void RequestShowAddress(u32 addr); + void RequestShowAddress(u32 addr, bool force = false); public Q_SLOTS: void HandleBreakpointRequest(u32 addr); private Q_SLOTS: diff --git a/rpcs3/rpcs3qt/call_stack_list.h b/rpcs3/rpcs3qt/call_stack_list.h index ca778e5e3bd..263ed8b2c5a 100644 --- a/rpcs3/rpcs3qt/call_stack_list.h +++ b/rpcs3/rpcs3qt/call_stack_list.h @@ -16,7 +16,7 @@ class call_stack_list : public QListWidget void UpdateCPUData(std::weak_ptr cpu, std::shared_ptr disasm); Q_SIGNALS: - void RequestShowAddress(u32 addr); + void RequestShowAddress(u32 addr, bool force = false); public Q_SLOTS: void HandleUpdate(std::vector call_stack); private Q_SLOTS: diff --git a/rpcs3/rpcs3qt/debugger_list.cpp b/rpcs3/rpcs3qt/debugger_list.cpp index d14a349c398..0c1d7dcccb5 100644 --- a/rpcs3/rpcs3qt/debugger_list.cpp +++ b/rpcs3/rpcs3qt/debugger_list.cpp @@ -51,29 +51,38 @@ u32 debugger_list::GetCenteredAddress(u32 address) const return address - ((m_item_count / 2) * 4); } -void debugger_list::ShowAddress(u32 addr) +void debugger_list::ShowAddress(u32 addr, bool force) { auto IsBreakpoint = [this](u32 pc) { return m_breakpoint_handler->HasBreakpoint(pc); }; - if (xgui_settings->GetValue(gui::d_centerPC).toBool()) - { - m_pc = GetCenteredAddress(addr); - } - else + const bool center_pc = xgui_settings->GetValue(gui::d_centerPC).toBool(); + + // How many spaces addr can move down without us needing to move the entire view + const u32 addr_margin = (m_item_count / (center_pc ? 2 : 1) - 4); // 4 is just a buffer of 4 spaces at the bottom + + if (force || addr - m_pc > addr_margin * 4) // 4 is the number of bytes in each instruction { - m_pc = addr; + if (center_pc) + { + m_pc = GetCenteredAddress(addr); + } + else + { + m_pc = addr; + } } const auto cpu = this->cpu.lock(); if (!cpu) { - for (uint i = 0; i < m_item_count; ++i, m_pc += 4) + u32 pc = m_pc; + for (uint i = 0; i < m_item_count; ++i, pc += 4) { - item(i)->setText(qstr(fmt::format(" [%08x] illegal address", m_pc))); + item(i)->setText(qstr(fmt::format(" [%08x] illegal address", pc))); } } else @@ -83,25 +92,27 @@ void debugger_list::ShowAddress(u32 addr) const u32 address_limits = (is_spu ? 0x3fffc : ~3); m_pc &= address_limits; m_disasm->offset = vm::get_super_ptr(cpu_offset); - for (uint i = 0, count = 4; isetText((IsBreakpoint(m_pc) ? ">> " : " ") + qstr(fmt::format("[%08x] illegal address", m_pc))); + item(i)->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] illegal address", pc))); count = 4; continue; } - count = m_disasm->disasm(m_disasm->dump_pc = m_pc); + count = m_disasm->disasm(m_disasm->dump_pc = pc); - item(i)->setText((IsBreakpoint(m_pc) ? ">> " : " ") + qstr(m_disasm->last_opcode)); + item(i)->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(m_disasm->last_opcode)); - if (cpu->is_paused() && m_pc == GetPc()) + if (cpu->is_paused() && pc == GetPc()) { item(i)->setForeground(m_text_color_pc); item(i)->setBackground(m_color_pc); } - else if (IsBreakpoint(m_pc)) + else if (IsBreakpoint(pc)) { item(i)->setForeground(m_text_color_bp); item(i)->setBackground(m_color_bp); @@ -141,24 +152,22 @@ void debugger_list::mouseDoubleClickEvent(QMouseEvent* event) int i = currentRow(); if (i < 0) return; - const u32 start_pc = m_pc - m_item_count * 4; - const u32 pc = start_pc + i * 4; + const u32 pc = m_pc + i * 4; // Let debugger_frame know about breakpoint. // Other option is to add to breakpoint manager directly and have a signal there instead. // Either the flow goes from debugger_list->breakpoint_manager->debugger_frame, or it goes debugger_list->debugger_frame, and I felt this was easier to read for now. Q_EMIT BreakpointRequested(pc); - - ShowAddress(start_pc); } } void debugger_list::wheelEvent(QWheelEvent* event) { - QPoint numSteps = event->angleDelta() / 8 / 15; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta + const QPoint numSteps = event->angleDelta() / 8 / 15; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta const int value = numSteps.y(); + const auto direction = (event->modifiers() == Qt::ControlModifier); - ShowAddress(m_pc - (event->modifiers() == Qt::ControlModifier ? m_item_count * (value + 1) : m_item_count + value) * 4); + ShowAddress(m_pc + (direction ? value : -value) * 4, true); } void debugger_list::resizeEvent(QResizeEvent* event) @@ -185,5 +194,5 @@ void debugger_list::resizeEvent(QResizeEvent* event) delete item(m_item_count); } - ShowAddress(m_pc - m_item_count * 4); + ShowAddress(m_pc); } diff --git a/rpcs3/rpcs3qt/debugger_list.h b/rpcs3/rpcs3qt/debugger_list.h index b6e2b164809..f4667f3831e 100644 --- a/rpcs3/rpcs3qt/debugger_list.h +++ b/rpcs3/rpcs3qt/debugger_list.h @@ -28,7 +28,7 @@ class debugger_list : public QListWidget debugger_list(QWidget* parent, std::shared_ptr settings, breakpoint_handler* handler); void UpdateCPUData(std::weak_ptr cpu, std::shared_ptr disasm); public Q_SLOTS: - void ShowAddress(u32 addr); + void ShowAddress(u32 addr, bool force = false); protected: void keyPressEvent(QKeyEvent* event) override; void mouseDoubleClickEvent(QMouseEvent* event) override;