DisassemblyWidget: Allow showing opcodes & some key bind modification

This commit is contained in:
Ty Lamontagne 2024-02-21 18:51:10 -05:00 committed by refractionpcsx2
parent a272d99335
commit 78b6323272
2 changed files with 52 additions and 13 deletions

View File

@ -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<QColor, 6> 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();
}

View File

@ -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 @@ private:
std::map<u32, std::tuple<u32, u32>> m_stubbedFunctions;
bool m_demangleFunctions = true;
bool m_showInstructionOpcode = true;
DisassemblyManager m_disassemblyManager;
inline QString DisassemblyStringFromAddress(u32 address, QFont font, u32 pc, bool selected);