diff --git a/pcsx2-qt/Debugger/DisassemblyWidget.cpp b/pcsx2-qt/Debugger/DisassemblyWidget.cpp index a32412cf6a483..6f7cce38ab346 100644 --- a/pcsx2-qt/Debugger/DisassemblyWidget.cpp +++ b/pcsx2-qt/Debugger/DisassemblyWidget.cpp @@ -320,6 +320,13 @@ void DisassemblyWidget::contextRestoreFunction() QMessageBox::warning(this, tr("Restore Function Error"), tr("Unable to stub selected address.")); } } + +void DisassemblyWidget::contextShowOpcode() +{ + m_showInstructionOpcode = !m_showInstructionOpcode; + this->repaint(); +} + void DisassemblyWidget::SetCpu(DebugInterface* cpu) { m_cpu = cpu; @@ -406,11 +413,11 @@ void DisassemblyWidget::paintEvent(QPaintEvent* event) s32 skippedBranches = 0; for (const auto& branchLine : branchLines) { - if (branchCount == 5) + if (branchCount == (m_showInstructionOpcode ? 3 : 5)) break; const int winBottom = this->height(); - const int x = this->width() - 10 - ((std::max(0, branchLine.laneIndex - skippedBranches)) * 10); + const int x = this->width() - 10 - (branchCount * 10); int top, bottom; // If the start is technically 'above' our address view @@ -621,6 +628,9 @@ void DisassemblyWidget::keyPressEvent(QKeyEvent* event) case Qt::Key_G: contextGoToAddress(); break; + case Qt::Key_J: + contextJumpToCursor(); + break; case Qt::Key_C: contextCopyInstructionText(); break; @@ -637,6 +647,9 @@ void DisassemblyWidget::keyPressEvent(QKeyEvent* event) case Qt::Key_Left: gotoAddress(m_cpu->getPC()); break; + case Qt::Key_O: + m_showInstructionOpcode = !m_showInstructionOpcode; + break; } this->repaint(); @@ -654,9 +667,10 @@ void DisassemblyWidget::customMenuRequested(QPoint pos) connect(action, &QAction::triggered, this, &DisassemblyWidget::contextCopyAddress); contextMenu->addAction(action = new QAction(tr("Copy Instruction Hex"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextCopyInstructionHex); - contextMenu->addAction(action = new QAction(tr("Copy Instruction Text"), this)); + contextMenu->addAction(action = new QAction(tr("&Copy Instruction Text"), this)); + action->setShortcut(QKeySequence(Qt::Key_C)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextCopyInstructionText); - if (m_selectedAddressStart == m_cpu->GetSymbolMap().GetFunctionStart(m_selectedAddressStart)) + if (m_selectedAddressStart == m_cpu->GetSymbolMap().GetFunctionStart(m_selectedAddressStart)) { contextMenu->addAction(action = new QAction(tr("Copy Function Name"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextCopyFunctionName); @@ -667,21 +681,25 @@ void DisassemblyWidget::customMenuRequested(QPoint pos) contextMenu->addAction(action = new QAction(tr("Restore Instruction(s)"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextRestoreInstruction); } - contextMenu->addAction(action = new QAction(tr("Assemble new Instruction(s)"), this)); + contextMenu->addAction(action = new QAction(tr("Asse&mble new Instruction(s)"), this)); + action->setShortcut(QKeySequence(Qt::Key_M)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextAssembleInstruction); contextMenu->addAction(action = new QAction(tr("NOP Instruction(s)"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextNoopInstruction); contextMenu->addSeparator(); contextMenu->addAction(action = new QAction(tr("Run to Cursor"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextRunToCursor); - contextMenu->addAction(action = new QAction(tr("Jump to Cursor"), this)); + contextMenu->addAction(action = new QAction(tr("&Jump to Cursor"), this)); + action->setShortcut(QKeySequence(Qt::Key_J)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextJumpToCursor); - contextMenu->addAction(action = new QAction(tr("Toggle Breakpoint"), this)); + contextMenu->addAction(action = new QAction(tr("Toggle &Breakpoint"), this)); + action->setShortcut(QKeySequence(Qt::Key_B)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextToggleBreakpoint); contextMenu->addAction(action = new QAction(tr("Follow Branch"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextFollowBranch); contextMenu->addSeparator(); - contextMenu->addAction(action = new QAction(tr("Go to Address"), this)); + contextMenu->addAction(action = new QAction(tr("&Go to Address"), this)); + action->setShortcut(QKeySequence(Qt::Key_G)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextGoToAddress); contextMenu->addAction(action = new QAction(tr("Go to in Memory View"), this)); connect(action, &QAction::triggered, this, [this]() { gotoInMemory(m_selectedAddressStart); }); @@ -702,6 +720,14 @@ void DisassemblyWidget::customMenuRequested(QPoint pos) contextMenu->addAction(action = new QAction(tr("Stub (NOP) Function"), this)); connect(action, &QAction::triggered, this, &DisassemblyWidget::contextStubFunction); } + + contextMenu->addSeparator(); + contextMenu->addAction(action = new QAction(tr("Show &Opcode"), this)); + action->setShortcut(QKeySequence(Qt::Key_O)); + action->setCheckable(true); + action->setChecked(m_showInstructionOpcode); + connect(action, &QAction::triggered, this, &DisassemblyWidget::contextShowOpcode); + contextMenu->setAttribute(Qt::WA_DeleteOnClose); contextMenu->popup(this->mapToGlobal(pos)); } @@ -720,10 +746,19 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon const bool isCurrentPC = m_cpu->getPC() == address; const std::string addressSymbol = m_cpu->GetSymbolMap().GetLabelName(address); + const u32 opcode = m_cpu->read32(address); const auto demangler = demangler::CDemangler::createGcc(); - QString lineString(" %1 %2 %3 %4 %5"); + QString lineString; + if (m_showInstructionOpcode) + { + lineString = QString(" %1 %2 %3 %4 %5 %6"); + } + else + { + lineString = QString(" %1 %2 %3 %4 %5"); + } if (addressSymbol.empty()) // The address wont have symbol text if it's the start of a function for example lineString = lineString.arg(address, 8, 16, QChar('0')).toUpper(); @@ -745,9 +780,12 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon symbolString = QString::fromStdString(addressSymbol); } - lineString = lineString.arg(metric.elidedText(symbolString, Qt::ElideRight, (selected ? 32 : 8) * font.pointSize())); + lineString = lineString.arg(metric.elidedText(symbolString, Qt::ElideRight, (selected ? 32.0f : 7.5f) * font.pointSize())); } + if (m_showInstructionOpcode) + lineString = lineString.arg(QtUtils::FilledQStringFromValue(opcode, 16)); + lineString = lineString.leftJustified(4, ' ') // Address / symbol .arg(line.name.c_str()) .arg(line.params.c_str()) // opcode + arguments @@ -760,7 +798,7 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon QColor DisassemblyWidget::GetAddressFunctionColor(u32 address) { // This is an attempt to figure out if the current palette is dark or light - // We calculate the luminescence of the alternateBase colour + // We calculate the luminance of the alternateBase colour // and swap between our darker and lighter function colours std::array colors; @@ -832,7 +870,7 @@ void DisassemblyWidget::gotoAddress(u32 address, bool should_set_focus) m_selectedAddressEnd = destAddress; this->repaint(); - if(should_set_focus) + if (should_set_focus) this->setFocus(); } diff --git a/pcsx2-qt/Debugger/DisassemblyWidget.h b/pcsx2-qt/Debugger/DisassemblyWidget.h index 5f836c74b7ae9..67b81493ef939 100644 --- a/pcsx2-qt/Debugger/DisassemblyWidget.h +++ b/pcsx2-qt/Debugger/DisassemblyWidget.h @@ -56,6 +56,7 @@ public slots: void contextRemoveFunction(); void contextStubFunction(); void contextRestoreFunction(); + void contextShowOpcode(); void gotoAddress(u32 address, bool should_set_focus = true); @@ -79,7 +80,7 @@ public slots: std::map> m_stubbedFunctions; bool m_demangleFunctions = true; - + bool m_showInstructionOpcode = true; DisassemblyManager m_disassemblyManager; inline QString DisassemblyStringFromAddress(u32 address, QFont font, u32 pc, bool selected);