rpcs3/rpcs3/rpcs3qt/register_editor_dialog.cpp
Megamouse 662fe8cc95 [Qt/Input] Improve pad_settings_dialog a bit (#3611)
* Input: further work on remapping Xinput and begin work on remapping DS4

* Input: Improve pad_settings_dialog a bit and begin Remapping for XInput

* Input: begin evdev remapping and change all handlers to use cfg::string

* Input: finish work on remapping evdev

and some more crap

* Input: finish work on remapping Xinput and DS4

* Input: add DS4 Colors to DS4 config

* Input: Improve DS4 deadzone scaling

Jarves made some mistakes, so I'll fix them in the follow up commit

* Input: fix Jarves fixes on DS4 deadzone

and remove unnecessary usage of toUtf8

* Input: add primitive batterychecks to XInput and DS4

* Input: add mmjoystick remapping

* Input: Fix evdev and some Vibration issues

* Input: adjust capabilities to fix stick input for games like LoS 2

also fix threshold slider minimum
also add ps button to all the handlers

* Input: Further evdev work

based on danilaml code review and own debugging:
Fixed path issue, <= 0 issue, some captures, const, axis with same codes.
Adds a map to each device that differentiates negative and positive axis mappings.
adjusted rest of the file to tabs (ListDevices and beginning of threadProc)

* Input: use 20ms vibration update time for xbox one elite controllers.

* Input: Fix return type of Clamp()

* Input: Evdev Fix

* Input: Evdev Optional GetNextButtonPress

presumably better than the other

* Input: review changes

* Input: evdev: fix wrong index in axis handling

move bindpadtodevice down to keep consistency between handlers and not get crazy

* Input: evdev: fix expensive add_device in GetNextButtonPress

* cleanup

* Input: mmjoy: fix type

* Input: evdev: final fixes

* Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4

* Input: add deadzone preview by passing necessary values in callback

use 0.5 of max value for threshold in pad dialog

* Input: get rid of all-uppercase variables
2017-11-28 01:31:15 +04:00

208 lines
6.7 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);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
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);
switch (g_system)
{
case system_type::ps3:
{
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)));
}
break;
}
default:
QMessageBox::critical(this, tr("Error"), tr("Not supported thread."));
return;
}
// 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, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &register_editor_dialog::updateRegister);
}
void register_editor_dialog::updateRegister()
{
const auto cpu = this->cpu.lock();
std::string reg = sstr(m_register_combo->itemData(m_register_combo->currentIndex()));
std::string str;
if (g_system == system_type::ps3 && 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 if (g_system == system_type::ps3 && cpu->id_type() != 1)
{
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 (g_system == system_type::ps3 && 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 if (g_system == system_type::ps3 && cpu->id_type() != 1)
{
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."));
}