mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
Reimplement debugger resize & disassembly (#2876)
* Reimplement debugger resize fix interrupt * add splitter to disassembly fix debugger regression of last commit fix gotoaddr pos * travis sth sth * add drag & drop to cg_disasm * check for invalid address on set breakpoint reenable debugger controls on Emu.IsReady() * check for valid address more thoroughly
This commit is contained in:
parent
aca5c73fb3
commit
31cedb6192
@ -1,7 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "cg_disasm_window.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include <QSplitter>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
@ -11,51 +12,53 @@
|
||||
#include <QDockWidget>
|
||||
#include <QCoreApplication>
|
||||
#include <QFontDatabase>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "Emu/RSX/CgBinaryProgram.h"
|
||||
|
||||
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
|
||||
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
|
||||
|
||||
cg_disasm_window::cg_disasm_window(QWidget* parent): QTabWidget()
|
||||
cg_disasm_window::cg_disasm_window(std::shared_ptr<gui_settings> xSettings, QWidget* parent): QWidget(), xgui_settings(xSettings)
|
||||
{
|
||||
setWindowTitle(tr("Cg Disasm"));
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setMinimumSize(200, 150); // seems fine on win 10
|
||||
setAcceptDrops(true);
|
||||
setMinimumSize(QSize(200, 150)); // seems fine on win 10
|
||||
resize(QSize(620, 395));
|
||||
|
||||
m_path_last = xgui_settings->GetValue(GUI::fd_cg_disasm).toString();
|
||||
|
||||
tab_disasm = new QWidget(this);
|
||||
tab_glsl = new QWidget(this);
|
||||
addTab(tab_disasm, "ASM");
|
||||
addTab(tab_glsl, "GLSL");
|
||||
|
||||
QVBoxLayout* layout_disasm = new QVBoxLayout();
|
||||
m_disasm_text = new QTextEdit();
|
||||
m_disasm_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_disasm_text = new QTextEdit(this);
|
||||
m_disasm_text->setReadOnly(true);
|
||||
m_disasm_text->setWordWrapMode(QTextOption::NoWrap);
|
||||
m_disasm_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
layout_disasm->addWidget(m_disasm_text);
|
||||
tab_disasm->setLayout(layout_disasm);
|
||||
|
||||
QVBoxLayout* layout_glsl = new QVBoxLayout();
|
||||
m_glsl_text = new QTextEdit();
|
||||
m_glsl_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_glsl_text = new QTextEdit(this);
|
||||
m_glsl_text->setReadOnly(true);
|
||||
m_glsl_text->setWordWrapMode(QTextOption::NoWrap);
|
||||
m_glsl_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
layout_glsl->addWidget(m_glsl_text);
|
||||
tab_glsl->setLayout(layout_glsl);
|
||||
|
||||
QSplitter* splitter = new QSplitter();
|
||||
splitter->addWidget(m_disasm_text);
|
||||
splitter->addWidget(m_glsl_text);
|
||||
|
||||
QHBoxLayout* layout = new QHBoxLayout();
|
||||
layout->addWidget(splitter);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
m_disasm_text->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_glsl_text->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_disasm_text, &QWidget::customContextMenuRequested, this, &cg_disasm_window::ShowContextMenu);
|
||||
connect(m_glsl_text, &QWidget::customContextMenuRequested, this, &cg_disasm_window::ShowContextMenu);
|
||||
|
||||
ShowDisasm();
|
||||
}
|
||||
|
||||
void cg_disasm_window::ShowContextMenu(const QPoint &pos) // this is a slot
|
||||
void cg_disasm_window::ShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu myMenu;
|
||||
QPoint globalPos = mapToGlobal(pos);
|
||||
QAction* clear = new QAction(tr("&Clear"));
|
||||
QAction* open = new QAction(tr("Open &Cg binary program"));
|
||||
|
||||
@ -70,11 +73,73 @@ void cg_disasm_window::ShowContextMenu(const QPoint &pos) // this is a slot
|
||||
if (filePath == NULL) return;
|
||||
m_path_last = QFileInfo(filePath).path();
|
||||
|
||||
CgBinaryDisasm disasm(sstr(filePath));
|
||||
ShowDisasm();
|
||||
});
|
||||
|
||||
myMenu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void cg_disasm_window::ShowDisasm()
|
||||
{
|
||||
if (QFileInfo(m_path_last).isFile())
|
||||
{
|
||||
CgBinaryDisasm disasm(sstr(m_path_last));
|
||||
disasm.BuildShaderBody();
|
||||
m_disasm_text->setText(qstr(disasm.GetArbShader()));
|
||||
m_glsl_text->setText(qstr(disasm.GetGlslShader()));
|
||||
});
|
||||
|
||||
myMenu.exec(globalPos);
|
||||
}
|
||||
else if (!m_path_last.isEmpty())
|
||||
{
|
||||
LOG_ERROR(LOADER, "CgDisasm: Failed to open %s", sstr(m_path_last));
|
||||
}
|
||||
}
|
||||
|
||||
bool cg_disasm_window::IsValidFile(const QMimeData& md, bool save)
|
||||
{
|
||||
for (auto url : md.urls())
|
||||
{
|
||||
for (QString suff : {"fpo", "vpo"})
|
||||
{
|
||||
if (QFileInfo(url.fileName()).suffix().toLower() == suff)
|
||||
{
|
||||
if (save)
|
||||
{
|
||||
m_path_last = url.toLocalFile();
|
||||
xgui_settings->SetValue(GUI::fd_cg_disasm, m_path_last);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cg_disasm_window::dropEvent(QDropEvent* ev)
|
||||
{
|
||||
if (IsValidFile(*ev->mimeData(), true))
|
||||
{
|
||||
ShowDisasm();
|
||||
}
|
||||
}
|
||||
|
||||
void cg_disasm_window::dragEnterEvent(QDragEnterEvent* ev)
|
||||
{
|
||||
if (IsValidFile(*ev->mimeData()))
|
||||
{
|
||||
ev->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void cg_disasm_window::dragMoveEvent(QDragMoveEvent* ev)
|
||||
{
|
||||
if (IsValidFile(*ev->mimeData()))
|
||||
{
|
||||
ev->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void cg_disasm_window::dragLeaveEvent(QDragLeaveEvent* ev)
|
||||
{
|
||||
ev->accept();
|
||||
}
|
||||
|
@ -2,25 +2,38 @@
|
||||
#define CGDISASMWINDOW_H
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QMainWindow>
|
||||
#include <QDropEvent>
|
||||
|
||||
class cg_disasm_window : public QTabWidget
|
||||
#include "stdafx.h"
|
||||
#include "gui_settings.h"
|
||||
|
||||
class cg_disasm_window : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void ShowContextMenu(const QPoint &pos);
|
||||
void ShowDisasm();
|
||||
bool IsValidFile(const QMimeData& md, bool save = false);
|
||||
|
||||
private:
|
||||
QString m_path_last;
|
||||
QTextEdit* m_disasm_text;
|
||||
QTextEdit* m_glsl_text;
|
||||
QWidget* tab_disasm;
|
||||
QWidget* tab_glsl;
|
||||
QList<QUrl> m_urls;
|
||||
|
||||
QAction *openCgBinaryProgram;
|
||||
|
||||
std::shared_ptr<gui_settings> xgui_settings;
|
||||
|
||||
public:
|
||||
explicit cg_disasm_window(QWidget *parent);
|
||||
explicit cg_disasm_window(std::shared_ptr<gui_settings> xSettings, QWidget *parent);
|
||||
|
||||
protected:
|
||||
void dropEvent(QDropEvent* ev);
|
||||
void dragEnterEvent(QDragEnterEvent* ev);
|
||||
void dragMoveEvent(QDragMoveEvent* ev);
|
||||
void dragLeaveEvent(QDragLeaveEvent* ev);
|
||||
};
|
||||
|
||||
#endif // CGDISASMWINDOW_H
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "debugger_frame.h"
|
||||
|
||||
#include <QSplitter>
|
||||
#include <QApplication>
|
||||
#include <QFontDatabase>
|
||||
|
||||
inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); }
|
||||
|
||||
debugger_frame::debugger_frame(QWidget *parent) : QDockWidget(tr("Debugger"), parent)
|
||||
@ -30,7 +34,7 @@ debugger_frame::debugger_frame(QWidget *parent) : QDockWidget(tr("Debugger"), pa
|
||||
m_btn_run = new QPushButton(tr("Run"), this);
|
||||
m_btn_pause = new QPushButton(tr("Pause"), this);
|
||||
|
||||
EnableButtons(Emu.IsRunning() || Emu.IsPaused());
|
||||
EnableButtons(!Emu.IsStopped());
|
||||
|
||||
hbox_b_main->addWidget(m_go_to_addr);
|
||||
hbox_b_main->addWidget(m_go_to_pc);
|
||||
@ -48,9 +52,12 @@ debugger_frame::debugger_frame(QWidget *parent) : QDockWidget(tr("Debugger"), pa
|
||||
m_list->setFont(mono);
|
||||
m_regs->setFont(mono);
|
||||
|
||||
QSplitter* splitter = new QSplitter(this);
|
||||
splitter->addWidget(m_list);
|
||||
splitter->addWidget(m_regs);
|
||||
|
||||
QHBoxLayout* hbox_w_list = new QHBoxLayout();
|
||||
hbox_w_list->addWidget(m_list);
|
||||
hbox_w_list->addWidget(m_regs);
|
||||
hbox_w_list->addWidget(splitter);
|
||||
|
||||
vbox_p_main->addLayout(hbox_b_main);
|
||||
vbox_p_main->addLayout(hbox_w_list);
|
||||
@ -190,25 +197,36 @@ void debugger_frame::UpdateUnitList()
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant old_cpu = m_choice_units->currentData();
|
||||
|
||||
m_choice_units->clear();
|
||||
|
||||
const auto on_select = [&](u32, cpu_thread& cpu)
|
||||
{
|
||||
QVariant var_cpu = qVariantFromValue((void *)&cpu);
|
||||
m_choice_units->addItem(qstr(cpu.get_name()), var_cpu);
|
||||
if (old_cpu == var_cpu) m_choice_units->setCurrentIndex(m_choice_units->count() - 1);
|
||||
};
|
||||
|
||||
idm::select<ppu_thread>(on_select);
|
||||
idm::select<ARMv7Thread>(on_select);
|
||||
idm::select<RawSPUThread>(on_select);
|
||||
idm::select<SPUThread>(on_select);
|
||||
{
|
||||
const QSignalBlocker blocker(m_choice_units);
|
||||
|
||||
idm::select<ppu_thread>(on_select);
|
||||
idm::select<ARMv7Thread>(on_select);
|
||||
idm::select<RawSPUThread>(on_select);
|
||||
idm::select<SPUThread>(on_select);
|
||||
}
|
||||
|
||||
OnSelectUnit();
|
||||
|
||||
m_choice_units->update();
|
||||
}
|
||||
|
||||
void debugger_frame::OnSelectUnit()
|
||||
{
|
||||
if (m_choice_units->count() < 1) return;
|
||||
if (m_choice_units->count() < 1 || m_current_choice == m_choice_units->currentText()) return;
|
||||
|
||||
m_current_choice = m_choice_units->currentText();
|
||||
|
||||
m_disasm.reset();
|
||||
|
||||
@ -242,38 +260,6 @@ void debugger_frame::OnSelectUnit()
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
//void debugger_frame::resizeEvent(QResizeEvent* event)
|
||||
//{
|
||||
// if (0)
|
||||
// {
|
||||
// if (!m_list->rowCount())
|
||||
// {
|
||||
// m_list->InsertItem(m_list->rowCount(), "");
|
||||
// }
|
||||
//
|
||||
// int size = 0;
|
||||
// m_list->clear();
|
||||
// int item = 0;
|
||||
// while (size < m_list->GetSize().GetHeight())
|
||||
// {
|
||||
// item = m_list->rowCount();
|
||||
// m_list->InsertItem(item, "");
|
||||
// QRect rect;
|
||||
// m_list->GetItemRect(item, rect);
|
||||
//
|
||||
// size = rect.GetBottom();
|
||||
// }
|
||||
//
|
||||
// if (item)
|
||||
// {
|
||||
// m_list->removeRow(--item);
|
||||
// }
|
||||
//
|
||||
// m_item_count = item;
|
||||
// ShowAddr(m_pc);
|
||||
// }
|
||||
//}
|
||||
|
||||
void debugger_frame::DoUpdate()
|
||||
{
|
||||
Show_PC();
|
||||
@ -360,7 +346,9 @@ void debugger_frame::Show_Val()
|
||||
|
||||
connect(p_pc, &QLineEdit::textChanged, l_changeLabel);
|
||||
connect(button_ok, &QAbstractButton::clicked, diag, &QDialog::accept);
|
||||
connect(button_cancel, &QAbstractButton::clicked, diag, &QDialog::reject);;
|
||||
connect(button_cancel, &QAbstractButton::clicked, diag, &QDialog::reject);
|
||||
|
||||
diag->move(QCursor::pos());
|
||||
|
||||
if (diag->exec() == QDialog::Accepted)
|
||||
{
|
||||
@ -537,7 +525,7 @@ void debugger_list::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
void debugger_list::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && (Emu.IsRunning() || Emu.IsPaused()))
|
||||
if (event->button() == Qt::LeftButton && !Emu.IsStopped())
|
||||
{
|
||||
long i = currentRow();
|
||||
if (i < 0) return;
|
||||
@ -552,7 +540,12 @@ void debugger_list::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBreakPoint(pc);
|
||||
const auto cpu = m_debugFrame->cpu.lock();
|
||||
|
||||
if (g_system == system_type::ps3 && cpu->id_type() == 1 && vm::check_addr(pc))
|
||||
{
|
||||
AddBreakPoint(pc);
|
||||
}
|
||||
}
|
||||
|
||||
ShowAddr(start_pc);
|
||||
@ -566,3 +559,28 @@ void debugger_list::wheelEvent(QWheelEvent* event)
|
||||
|
||||
ShowAddr(m_pc - (event->modifiers() == Qt::ControlModifier ? m_item_count * (value + 1) : m_item_count + value) * 4);
|
||||
}
|
||||
|
||||
void debugger_list::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
if (count() < 1 || visualItemRect(item(0)).height() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_item_count = (rect().height() - frameWidth()*2) / visualItemRect(item(0)).height();
|
||||
|
||||
clear();
|
||||
|
||||
for (u32 i = 0; i < m_item_count; ++i)
|
||||
{
|
||||
insertItem(i, new QListWidgetItem(""));
|
||||
}
|
||||
|
||||
if (horizontalScrollBar())
|
||||
{
|
||||
m_item_count--;
|
||||
delete item(m_item_count);
|
||||
}
|
||||
|
||||
ShowAddr(m_pc - m_item_count * 4);
|
||||
}
|
||||
|
@ -19,16 +19,12 @@
|
||||
#include "instruction_editor_dialog.h"
|
||||
#include "register_editor_dialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDockWidget>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QInputDialog>
|
||||
#include <QFontDatabase>
|
||||
#include <QTimer>
|
||||
#include <QTextEdit>
|
||||
|
||||
@ -49,6 +45,7 @@ class debugger_frame : public QDockWidget
|
||||
QPushButton* m_btn_run;
|
||||
QPushButton* m_btn_pause;
|
||||
QComboBox* m_choice_units;
|
||||
QString m_current_choice;
|
||||
|
||||
u64 m_threads_created = 0;
|
||||
u64 m_threads_deleted = 0;
|
||||
@ -69,7 +66,6 @@ public:
|
||||
|
||||
u32 GetPc() const;
|
||||
u32 CentrePc(u32 pc) const;
|
||||
//void resizeEvent(QResizeEvent* event);
|
||||
void DoUpdate();
|
||||
void WriteRegs();
|
||||
void EnableButtons(bool enable);
|
||||
@ -114,6 +110,7 @@ protected:
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
};
|
||||
|
||||
#endif // DEBUGGERFRAME_H
|
||||
|
@ -64,6 +64,7 @@ namespace GUI
|
||||
const GUI_SAVE fd_boot_elf = GUI_SAVE( main_window, "lastExplorePathELF", "" );
|
||||
const GUI_SAVE fd_boot_game = GUI_SAVE( main_window, "lastExplorePathGAME", "" );
|
||||
const GUI_SAVE fd_decrypt_sprx = GUI_SAVE( main_window, "lastExplorePathSPRX", "" );
|
||||
const GUI_SAVE fd_cg_disasm = GUI_SAVE( main_window, "lastExplorePathCGD", "" );
|
||||
|
||||
const GUI_SAVE mw_debugger = GUI_SAVE( main_window, "debuggerVisible", false );
|
||||
const GUI_SAVE mw_logger = GUI_SAVE( main_window, "loggerVisible", true );
|
||||
|
@ -742,6 +742,7 @@ void main_window::OnEmuStop()
|
||||
|
||||
void main_window::OnEmuReady()
|
||||
{
|
||||
debuggerFrame->EnableButtons(true);
|
||||
#ifdef _WIN32
|
||||
thumb_playPause->setToolTip(Emu.IsReady() ? tr("Start") : tr("Resume"));
|
||||
thumb_playPause->setIcon(icon_play);
|
||||
@ -1162,7 +1163,7 @@ void main_window::CreateConnects()
|
||||
sdid->show();
|
||||
});
|
||||
connect(toolsCgDisasmAct, &QAction::triggered, [=](){
|
||||
cg_disasm_window* cgdw = new cg_disasm_window(this);
|
||||
cg_disasm_window* cgdw = new cg_disasm_window(guiSettings, this);
|
||||
cgdw->show();
|
||||
});
|
||||
connect(toolskernel_explorerAct, &QAction::triggered, [=](){
|
||||
|
Loading…
Reference in New Issue
Block a user