rpcs3/rpcs3/rpcs3qt/register_editor_dialog.cpp
Megamouse cf1c45dfe8 Qt: use setAttribute(AA_DisableWindowContextHelpButton) instead of flags
probably needs Qt 5.10.1 to work propery
2018-02-22 00:18:14 +04:00

206 lines
6.3 KiB
C++

#include "register_editor_dialog.h"
constexpr auto qstr = QString::fromStdString;
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
inline std::string sstr(const QVariant& _in) { return sstr(_in.toString()); }
register_editor_dialog::register_editor_dialog(QWidget *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
: QDialog(parent)
, m_pc(_pc)
, cpu(_cpu)
, m_disasm(_disasm)
{
setWindowTitle(tr("Edit registers"));
setAttribute(Qt::WA_DeleteOnClose);
QVBoxLayout* vbox_panel = new QVBoxLayout();
QHBoxLayout* hbox_panel = new QHBoxLayout();
QVBoxLayout* vbox_left_panel = new QVBoxLayout();
QVBoxLayout* vbox_right_panel = new QVBoxLayout();
QHBoxLayout* hbox_button_panel = new QHBoxLayout();
QLabel* t1_text = new QLabel(tr("Register: "), this);
QLabel* t2_text = new QLabel(tr("Value (Hex):"), this);
QPushButton* button_ok = new QPushButton(tr("&Ok"));
QPushButton* button_cancel = new QPushButton(tr("&Cancel"));
button_ok->setFixedWidth(80);
button_cancel->setFixedWidth(80);
m_register_combo = new QComboBox(this);
m_value_line = new QLineEdit(this);
m_value_line->setFixedWidth(200);
// Layouts
vbox_left_panel->addWidget(t1_text);
vbox_left_panel->addWidget(t2_text);
vbox_right_panel->addWidget(m_register_combo);
vbox_right_panel->addWidget(m_value_line);
hbox_button_panel->addWidget(button_ok);
hbox_button_panel->addWidget(button_cancel);
hbox_button_panel->setAlignment(Qt::AlignCenter);
if (1)
{
if (_cpu->id_type() == 1)
{
for (int i = 0; i < 32; i++) m_register_combo->addItem(qstr(fmt::format("GPR[%d]", i)));
for (int i = 0; i < 32; i++) m_register_combo->addItem(qstr(fmt::format("FPR[%d]", i)));
for (int i = 0; i < 32; i++) m_register_combo->addItem(qstr(fmt::format("VR[%d]", i)));
m_register_combo->addItem("CR");
m_register_combo->addItem("LR");
m_register_combo->addItem("CTR");
//m_register_combo->addItem("XER");
//m_register_combo->addItem("FPSCR");
}
else
{
for (int i = 0; i < 128; i++) m_register_combo->addItem(qstr(fmt::format("GPR[%d]", i)));
}
}
// Main Layout
hbox_panel->addLayout(vbox_left_panel);
hbox_panel->addSpacing(10);
hbox_panel->addLayout(vbox_right_panel);
vbox_panel->addLayout(hbox_panel);
vbox_panel->addSpacing(10);
vbox_panel->addLayout(hbox_button_panel);
setLayout(vbox_panel);
setModal(true);
// Events
connect(button_ok, &QAbstractButton::pressed, this, [=](){OnOkay(_cpu); accept();});
connect(button_cancel, &QAbstractButton::pressed, this, &register_editor_dialog::reject);
connect(m_register_combo, &QComboBox::currentTextChanged, this, &register_editor_dialog::updateRegister);
updateRegister(m_register_combo->currentText());
}
void register_editor_dialog::updateRegister(const QString& text)
{
if (text.isEmpty())
{
m_value_line->setText("");
return;
}
const auto cpu = this->cpu.lock();
std::string reg = sstr(text);
std::string str;
if (cpu->id_type() == 1)
{
auto& ppu = *static_cast<ppu_thread*>(cpu.get());
std::size_t first_brk = reg.find('[');
if (first_brk != -1)
{
long reg_index = std::atol(reg.substr(first_brk + 1, reg.length() - first_brk - 2).c_str());
if (reg.find("GPR") == 0) str = fmt::format("%016llx", ppu.gpr[reg_index]);
if (reg.find("FPR") == 0) str = fmt::format("%016llx", ppu.fpr[reg_index]);
if (reg.find("VR") == 0) str = fmt::format("%016llx%016llx", ppu.vr[reg_index]._u64[1], ppu.vr[reg_index]._u64[0]);
}
if (reg == "CR") str = fmt::format("%08x", ppu.cr_pack());
if (reg == "LR") str = fmt::format("%016llx", ppu.lr);
if (reg == "CTR") str = fmt::format("%016llx", ppu.ctr);
}
else
{
auto& spu = *static_cast<SPUThread*>(cpu.get());
std::string::size_type first_brk = reg.find('[');
if (first_brk != std::string::npos)
{
long reg_index;
reg_index = atol(reg.substr(first_brk + 1, reg.length() - 2).c_str());
if (reg.find("GPR") == 0) str = fmt::format("%016llx%016llx", spu.gpr[reg_index]._u64[1], spu.gpr[reg_index]._u64[0]);
}
}
m_value_line->setText(qstr(str));
}
void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
{
const auto cpu = _cpu.get();
std::string reg = sstr(m_register_combo->itemData(m_register_combo->currentIndex()));
std::string value = sstr(m_value_line->text());
if (cpu->id_type() == 1)
{
auto& ppu = *static_cast<ppu_thread*>(cpu);
while (value.length() < 32) value = "0" + value;
const auto first_brk = reg.find('[');
try
{
if (first_brk != -1)
{
const long reg_index = std::atol(reg.substr(first_brk + 1, reg.length() - first_brk - 2).c_str());
if (reg.find("GPR") == 0 || reg.find("FPR") == 0)
{
const ullong reg_value = std::stoull(value.substr(16, 31), 0, 16);
if (reg.find("GPR") == 0) ppu.gpr[reg_index] = (u64)reg_value;
if (reg.find("FPR") == 0) (u64&)ppu.fpr[reg_index] = (u64)reg_value;
return;
}
if (reg.find("VR") == 0)
{
const ullong reg_value0 = std::stoull(value.substr(16, 31), 0, 16);
const ullong reg_value1 = std::stoull(value.substr(0, 15), 0, 16);
ppu.vr[reg_index]._u64[0] = (u64)reg_value0;
ppu.vr[reg_index]._u64[1] = (u64)reg_value1;
return;
}
}
if (reg == "LR" || reg == "CTR")
{
const ullong reg_value = std::stoull(value.substr(16, 31), 0, 16);
if (reg == "LR") ppu.lr = (u64)reg_value;
if (reg == "CTR") ppu.ctr = (u64)reg_value;
return;
}
if (reg == "CR")
{
const ullong reg_value = std::stoull(value.substr(24, 31), 0, 16);
if (reg == "CR") ppu.cr_unpack((u32)reg_value);
return;
}
}
catch (std::invalid_argument&) //if any of the stoull conversion fail
{
}
}
else
{
auto& spu = *static_cast<SPUThread*>(cpu);
while (value.length() < 32) value = "0" + value;
const auto first_brk = reg.find('[');
try
{
if (first_brk != -1)
{
const long reg_index = std::atol(reg.substr(first_brk + 1, reg.length() - 2).c_str());
if (reg.find("GPR") == 0)
{
const ullong reg_value0 = std::stoull(value.substr(16, 31), 0, 16);
const ullong reg_value1 = std::stoull(value.substr(0, 15), 0, 16);
spu.gpr[reg_index]._u64[0] = (u64)reg_value0;
spu.gpr[reg_index]._u64[1] = (u64)reg_value1;
return;
}
}
}
catch (std::invalid_argument&)
{
}
}
QMessageBox::critical(this, tr("Error"), tr("This value could not be converted.\nNo changes were made."));
}