From f6e73a0aec93e0dc2d500c89d97150d9f5c42c35 Mon Sep 17 00:00:00 2001 From: spycrab Date: Tue, 23 Apr 2019 21:42:37 +0200 Subject: [PATCH] Qt/Debugger: Implement patch instruction preview --- Source/Core/DolphinQt/CMakeLists.txt | 1 + .../DolphinQt/Debugger/CodeViewWidget.cpp | 12 ++-- .../Debugger/PatchInstructionDialog.cpp | 67 +++++++++++++++++++ .../Debugger/PatchInstructionDialog.h | 35 ++++++++++ Source/Core/DolphinQt/DolphinQt.vcxproj | 3 + 5 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 Source/Core/DolphinQt/Debugger/PatchInstructionDialog.cpp create mode 100644 Source/Core/DolphinQt/Debugger/PatchInstructionDialog.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index a82cc672fb..27eda16cb4 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -84,6 +84,7 @@ add_executable(dolphin-emu Debugger/MemoryViewWidget.cpp Debugger/MemoryWidget.cpp Debugger/NewBreakpointDialog.cpp + Debugger/PatchInstructionDialog.cpp Debugger/RegisterColumn.cpp Debugger/RegisterWidget.cpp Debugger/WatchWidget.cpp diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp index 295902d264..71518a2dda 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp @@ -26,6 +26,7 @@ #include "Core/PowerPC/PPCAnalyst.h" #include "Core/PowerPC/PPCSymbolDB.h" #include "Core/PowerPC/PowerPC.h" +#include "DolphinQt/Debugger/PatchInstructionDialog.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" @@ -463,17 +464,12 @@ void CodeViewWidget::OnReplaceInstruction() if (!read_result.valid) return; - bool good; - QString name = QInputDialog::getText( - this, tr("Change instruction"), tr("New instruction:"), QLineEdit::Normal, - QStringLiteral("%1").arg(read_result.hex, 8, 16, QLatin1Char('0')), &good); + PatchInstructionDialog dialog(this, addr, PowerPC::debug_interface.ReadInstruction(addr)); - u32 code = name.toUInt(&good, 16); - - if (good) + if (dialog.exec() == QDialog::Accepted) { PowerPC::debug_interface.UnsetPatch(addr); - PowerPC::debug_interface.SetPatch(addr, code); + PowerPC::debug_interface.SetPatch(addr, dialog.GetCode()); Update(); } } diff --git a/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.cpp b/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.cpp new file mode 100644 index 0000000000..91d4c24548 --- /dev/null +++ b/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.cpp @@ -0,0 +1,67 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Debugger/PatchInstructionDialog.h" + +#include +#include +#include +#include +#include + +#include "Common/GekkoDisassembler.h" + +PatchInstructionDialog::PatchInstructionDialog(QWidget* parent, u32 address, u32 value) + : QDialog(parent), m_address(address) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowModality(Qt::WindowModal); + setWindowTitle(tr("Instruction")); + + CreateWidgets(); + ConnectWidgets(); + + m_input_edit->setText(QStringLiteral("%1").arg(value, 8, 16, QLatin1Char('0'))); +} + +void PatchInstructionDialog::CreateWidgets() +{ + auto* layout = new QVBoxLayout; + + m_input_edit = new QLineEdit; + m_preview_label = new QLabel; + m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + layout->addWidget(new QLabel(tr("New instruction:"))); + layout->addWidget(m_input_edit); + layout->addWidget(m_preview_label); + layout->addWidget(m_button_box); + + setLayout(layout); +} + +void PatchInstructionDialog::ConnectWidgets() +{ + connect(m_button_box, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); + + connect(m_input_edit, &QLineEdit::textChanged, this, &PatchInstructionDialog::OnEditChanged); +} + +void PatchInstructionDialog::OnEditChanged() +{ + bool good; + m_code = m_input_edit->text().toUInt(&good, 16); + + m_button_box->button(QDialogButtonBox::Ok)->setEnabled(good); + + m_preview_label->setText( + tr("Instruction: %1") + .arg(QString::fromStdString(Common::GekkoDisassembler::Disassemble(m_code, m_address)))); +} + +u32 PatchInstructionDialog::GetCode() const +{ + return m_code; +} diff --git a/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.h b/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.h new file mode 100644 index 0000000000..c800e4b3e6 --- /dev/null +++ b/Source/Core/DolphinQt/Debugger/PatchInstructionDialog.h @@ -0,0 +1,35 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "Common/CommonTypes.h" + +class QDialogButtonBox; +class QLabel; +class QLineEdit; + +class PatchInstructionDialog : public QDialog +{ + Q_OBJECT +public: + explicit PatchInstructionDialog(QWidget* parent, u32 address, u32 value); + + u32 GetCode() const; + +private: + void CreateWidgets(); + void ConnectWidgets(); + + void OnEditChanged(); + + u32 m_code; + u32 m_address; + + QLineEdit* m_input_edit; + QLabel* m_preview_label; + QDialogButtonBox* m_button_box; +}; diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 97048502f4..f5f1742c67 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -126,6 +126,7 @@ + @@ -255,6 +256,7 @@ + @@ -351,6 +353,7 @@ +