mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 05:21:25 +12:00
172 lines
4 KiB
C++
172 lines
4 KiB
C++
#include "cg_disasm_window.h"
|
|
#include "gui_settings.h"
|
|
#include "syntax_highlighter.h"
|
|
|
|
#include <QSplitter>
|
|
#include <QMenu>
|
|
#include <QFileDialog>
|
|
#include <QHBoxLayout>
|
|
#include <QFontDatabase>
|
|
#include <QMimeData>
|
|
|
|
#include "Emu/RSX/Program/CgBinaryProgram.h"
|
|
|
|
LOG_CHANNEL(gui_log, "GUI");
|
|
|
|
cg_disasm_window::cg_disasm_window(std::shared_ptr<gui_settings> gui_settings)
|
|
: m_gui_settings(std::move(gui_settings))
|
|
{
|
|
setWindowTitle(tr("Cg Disasm"));
|
|
setObjectName("cg_disasm");
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
setAttribute(Qt::WA_StyledBackground);
|
|
setAcceptDrops(true);
|
|
setMinimumSize(QSize(200, 150)); // seems fine on win 10
|
|
resize(QSize(620, 395));
|
|
|
|
m_path_last = m_gui_settings->GetValue(gui::fd_cg_disasm).toString();
|
|
|
|
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));
|
|
|
|
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));
|
|
|
|
// m_disasm_text syntax highlighter
|
|
sh_asm = new AsmHighlighter(m_disasm_text->document());
|
|
|
|
// m_glsl_text syntax highlighter
|
|
sh_glsl = new GlslHighlighter(m_glsl_text->document());
|
|
|
|
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)
|
|
{
|
|
QMenu menu;
|
|
QAction* clear = new QAction(tr("&Clear"));
|
|
QAction* open = new QAction(tr("Open &Cg binary program"));
|
|
|
|
menu.addAction(open);
|
|
menu.addSeparator();
|
|
menu.addAction(clear);
|
|
|
|
connect(clear, &QAction::triggered, [this]()
|
|
{
|
|
m_disasm_text->clear();
|
|
m_glsl_text->clear();
|
|
});
|
|
|
|
connect(open, &QAction::triggered, [this]()
|
|
{
|
|
const QString file_path = QFileDialog::getOpenFileName(this, tr("Select Cg program object"), m_path_last, tr("Cg program objects (*.fpo;*.vpo);;"));
|
|
if (file_path.isEmpty())
|
|
return;
|
|
m_path_last = file_path;
|
|
ShowDisasm();
|
|
});
|
|
|
|
const auto obj = qobject_cast<QTextEdit*>(sender());
|
|
|
|
QPoint origin;
|
|
|
|
if (obj == m_disasm_text)
|
|
{
|
|
origin = m_disasm_text->viewport()->mapToGlobal(pos);
|
|
}
|
|
else if (obj == m_glsl_text)
|
|
{
|
|
origin = m_glsl_text->viewport()->mapToGlobal(pos);
|
|
}
|
|
else
|
|
{
|
|
origin = mapToGlobal(pos);
|
|
}
|
|
|
|
menu.exec(origin);
|
|
}
|
|
|
|
void cg_disasm_window::ShowDisasm() const
|
|
{
|
|
if (QFileInfo(m_path_last).isFile())
|
|
{
|
|
CgBinaryDisasm disasm(m_path_last.toStdString());
|
|
disasm.BuildShaderBody();
|
|
m_disasm_text->setText(QString::fromStdString(disasm.GetArbShader()));
|
|
m_glsl_text->setText(QString::fromStdString(disasm.GetGlslShader()));
|
|
m_gui_settings->SetValue(gui::fd_cg_disasm, m_path_last);
|
|
}
|
|
else if (!m_path_last.isEmpty())
|
|
{
|
|
gui_log.error("CgDisasm: Failed to open %s", m_path_last);
|
|
}
|
|
}
|
|
|
|
bool cg_disasm_window::IsValidFile(const QMimeData& md, bool save)
|
|
{
|
|
const QList<QUrl> urls = md.urls();
|
|
|
|
if (urls.count() > 1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const QString suff = QFileInfo(urls[0].fileName()).suffix().toLower();
|
|
|
|
if (suff == "fpo" || suff == "vpo")
|
|
{
|
|
if (save)
|
|
{
|
|
m_path_last = urls[0].toLocalFile();
|
|
}
|
|
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();
|
|
}
|