Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement debugger resize & disassembly #2876

Merged
merged 7 commits into from Jun 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 88 additions & 23 deletions rpcs3/rpcs3qt/cg_disasm_window.cpp
@@ -1,7 +1,8 @@
#include "stdafx.h"

#include "cg_disasm_window.h"
#include "Emu/System.h"

#include <QSplitter>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
Expand All @@ -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"));

Expand All @@ -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()));
});
}
else if (!m_path_last.isEmpty())
{
LOG_ERROR(LOADER, "CgDisasm: Failed to open %s", sstr(m_path_last));
}
}

myMenu.exec(globalPos);
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();
}
23 changes: 18 additions & 5 deletions rpcs3/rpcs3qt/cg_disasm_window.h
Expand Up @@ -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
104 changes: 61 additions & 43 deletions rpcs3/rpcs3qt/debugger_frame.cpp
@@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}