mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
A few more items: Standardising on 'OK' for all base language uses (rather than 'Ok', or 'Okay'). It's perceived as the 'most correct' variant, and importantly having a single variant is best from a translation perspective. Added plurality handling for multiple PPU caches created. Added plurality handling for multiple items deleted in save manager. Capitalised trophy grade to align with Sony terminology. Brought trophy name position into translatable string (for languages that might really want to deviate from SVO)
281 lines
8.1 KiB
C++
281 lines
8.1 KiB
C++
#include "auto_pause_settings_dialog.h"
|
|
#include "table_item_delegate.h"
|
|
#include "Emu/System.h"
|
|
|
|
#include <QFontDatabase>
|
|
#include <QMenu>
|
|
#include <QMouseEvent>
|
|
#include <QVBoxLayout>
|
|
#include <QPushButton>
|
|
|
|
LOG_CHANNEL(autopause_log, "AutoPause");
|
|
|
|
constexpr auto qstr = QString::fromStdString;
|
|
|
|
auto_pause_settings_dialog::auto_pause_settings_dialog(QWidget *parent) : QDialog(parent)
|
|
{
|
|
QLabel *description = new QLabel(tr("To use auto pause: enter the ID(s) of a function or a system call.\nRestart of the game is required to apply. You can enable/disable this in the settings."), this);
|
|
|
|
pauseList = new QTableWidget(this);
|
|
pauseList->setColumnCount(2);
|
|
pauseList->setHorizontalHeaderLabels(QStringList() << tr("Call ID") << tr("Type"));
|
|
//pauseList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
|
pauseList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
pauseList->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
pauseList->setItemDelegate(new table_item_delegate(this));
|
|
pauseList->setShowGrid(false);
|
|
|
|
QPushButton *clearButton = new QPushButton(tr("Clear"), this);
|
|
QPushButton *reloadButton = new QPushButton(tr("Reload"), this);
|
|
QPushButton *saveButton = new QPushButton(tr("Save"), this);
|
|
QPushButton *cancelButton = new QPushButton(tr("Cancel"), this);
|
|
cancelButton->setDefault(true);
|
|
|
|
QHBoxLayout *buttonsLayout = new QHBoxLayout();
|
|
buttonsLayout->addWidget(clearButton);
|
|
buttonsLayout->addWidget(reloadButton);
|
|
buttonsLayout->addStretch();
|
|
buttonsLayout->addWidget(saveButton);
|
|
buttonsLayout->addWidget(cancelButton);
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
|
mainLayout->addWidget(description);
|
|
mainLayout->addWidget(pauseList);
|
|
mainLayout->addLayout(buttonsLayout);
|
|
setLayout(mainLayout);
|
|
|
|
setMinimumSize(QSize(400, 360));
|
|
setWindowTitle(tr("Auto Pause Manager"));
|
|
setObjectName("auto_pause_manager");
|
|
|
|
//Events
|
|
connect(pauseList, &QTableWidget::customContextMenuRequested, this, &auto_pause_settings_dialog::ShowContextMenu);
|
|
connect(clearButton, &QAbstractButton::clicked, [this](){ m_entries.clear(); UpdateList(); });
|
|
connect(reloadButton, &QAbstractButton::clicked, [this](){ LoadEntries(); UpdateList(); });
|
|
connect(saveButton, &QAbstractButton::clicked, [this]()
|
|
{
|
|
SaveEntries();
|
|
autopause_log.success("File pause.bin was updated.");
|
|
});
|
|
connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close);
|
|
|
|
Emu.SetForceBoot(true);
|
|
Emu.Stop();
|
|
|
|
LoadEntries();
|
|
UpdateList();
|
|
setFixedSize(sizeHint());
|
|
}
|
|
|
|
//Copied some from AutoPause.
|
|
void auto_pause_settings_dialog::LoadEntries(void)
|
|
{
|
|
m_entries.clear();
|
|
m_entries.reserve(16);
|
|
|
|
fs::file list(fs::get_config_dir() + "pause.bin");
|
|
|
|
if (list)
|
|
{
|
|
//System calls ID and Function calls ID are all u32 iirc.
|
|
u32 num;
|
|
size_t fmax = list.size();
|
|
size_t fcur = 0;
|
|
list.seek(0);
|
|
while (fcur <= fmax - sizeof(u32))
|
|
{
|
|
list.read(&num, sizeof(u32));
|
|
fcur += sizeof(u32);
|
|
if (num == 0xFFFFFFFF) break;
|
|
|
|
m_entries.emplace_back(num);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Copied some from AutoPause.
|
|
//Tip: This one doesn't check for the file is being read or not.
|
|
//This would always use a 0xFFFFFFFF as end of the pause.bin
|
|
void auto_pause_settings_dialog::SaveEntries(void)
|
|
{
|
|
fs::file list(fs::get_config_dir() + "pause.bin", fs::rewrite);
|
|
//System calls ID and Function calls ID are all u32 iirc.
|
|
u32 num = 0;
|
|
list.seek(0);
|
|
for (size_t i = 0; i < m_entries.size(); ++i)
|
|
{
|
|
if (num == 0xFFFFFFFF) continue;
|
|
num = m_entries[i];
|
|
list.write(&num, sizeof(u32));
|
|
}
|
|
num = 0xFFFFFFFF;
|
|
list.write(&num, sizeof(u32));
|
|
}
|
|
|
|
void auto_pause_settings_dialog::UpdateList(void)
|
|
{
|
|
const int entries_size = static_cast<int>(m_entries.size());
|
|
pauseList->clearContents();
|
|
pauseList->setRowCount(entries_size);
|
|
for (int i = 0; i < entries_size; ++i)
|
|
{
|
|
QTableWidgetItem* callItem = new QTableWidgetItem;
|
|
QTableWidgetItem* typeItem = new QTableWidgetItem;
|
|
callItem->setFlags(callItem->flags() & ~Qt::ItemIsEditable);
|
|
typeItem->setFlags(typeItem->flags() & ~Qt::ItemIsEditable);
|
|
if (m_entries[i] != 0xFFFFFFFF)
|
|
{
|
|
callItem->setData(Qt::DisplayRole, qstr(fmt::format("%08x", m_entries[i])));
|
|
}
|
|
else
|
|
{
|
|
callItem->setData(Qt::DisplayRole, tr("Unset"));
|
|
}
|
|
|
|
if (m_entries[i] < 1024)
|
|
{
|
|
typeItem->setData(Qt::DisplayRole, tr("System Call"));
|
|
}
|
|
else
|
|
{
|
|
typeItem->setData(Qt::DisplayRole, tr("Function Call"));
|
|
}
|
|
|
|
pauseList->setItem(i, 0, callItem);
|
|
pauseList->setItem(i, 1, typeItem);
|
|
}
|
|
}
|
|
|
|
void auto_pause_settings_dialog::ShowContextMenu(const QPoint &pos)
|
|
{
|
|
int row = pauseList->indexAt(pos).row();
|
|
|
|
QMenu myMenu;
|
|
|
|
// Make Actions
|
|
QAction* add = myMenu.addAction(tr("&Add"));
|
|
QAction* remove = myMenu.addAction(tr("&Remove"));
|
|
myMenu.addSeparator();
|
|
QAction* config = myMenu.addAction(tr("&Config"));
|
|
|
|
if (row == -1)
|
|
{
|
|
remove->setEnabled(false);
|
|
config->setEnabled(false);
|
|
}
|
|
|
|
auto OnEntryConfig = [this](int row, bool newEntry)
|
|
{
|
|
AutoPauseConfigDialog *config = new AutoPauseConfigDialog(this, this, newEntry, &m_entries[row]);
|
|
config->setModal(true);
|
|
config->exec();
|
|
UpdateList();
|
|
};
|
|
|
|
connect(add, &QAction::triggered, [=, this]() {
|
|
m_entries.emplace_back(0xFFFFFFFF);
|
|
UpdateList();
|
|
int idx = static_cast<int>(m_entries.size()) - 1;
|
|
pauseList->selectRow(idx);
|
|
OnEntryConfig(idx, true);
|
|
});
|
|
connect(remove, &QAction::triggered, this, &auto_pause_settings_dialog::OnRemove);
|
|
connect(config, &QAction::triggered, [=, this]() {OnEntryConfig(row, false); });
|
|
|
|
myMenu.exec(pauseList->viewport()->mapToGlobal(pos));
|
|
}
|
|
|
|
void auto_pause_settings_dialog::OnRemove()
|
|
{
|
|
QModelIndexList selection = pauseList->selectionModel()->selectedRows();
|
|
std::sort(selection.begin(), selection.end());
|
|
for (int i = selection.count() - 1; i >= 0; i--)
|
|
{
|
|
m_entries.erase(m_entries.begin() + selection.at(i).row());
|
|
}
|
|
UpdateList();
|
|
}
|
|
|
|
void auto_pause_settings_dialog::keyPressEvent(QKeyEvent *event)
|
|
{
|
|
if (event->key() == Qt::Key_Delete)
|
|
{
|
|
OnRemove();
|
|
}
|
|
}
|
|
|
|
AutoPauseConfigDialog::AutoPauseConfigDialog(QWidget* parent, auto_pause_settings_dialog* apsd, bool newEntry, u32 *entry)
|
|
: QDialog(parent), m_presult(entry), m_newEntry(newEntry), m_apsd(apsd)
|
|
{
|
|
m_entry = *m_presult;
|
|
setMinimumSize(QSize(300, -1));
|
|
|
|
QPushButton* button_ok = new QPushButton(tr("&Ok"), this);
|
|
QPushButton* button_cancel = new QPushButton(tr("&Cancel"), this);
|
|
button_ok->setFixedWidth(50);
|
|
button_cancel->setFixedWidth(50);
|
|
|
|
QLabel* description = new QLabel(tr("Specify ID of System Call or Function Call below. You need to use a Hexadecimal ID."), this);
|
|
description->setWordWrap(true);
|
|
|
|
m_current_converted = new QLabel(tr("Currently it gets an id of \"Unset\"."), this);
|
|
m_current_converted->setWordWrap(true);
|
|
|
|
m_id = new QLineEdit(this);
|
|
m_id->setText(qstr(fmt::format("%08x", m_entry)));
|
|
m_id->setPlaceholderText("ffffffff");
|
|
m_id->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
|
m_id->setMaxLength(8);
|
|
m_id->setFixedWidth(65);
|
|
setWindowTitle("Auto Pause Setting: " + m_id->text());
|
|
|
|
connect(button_cancel, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnCancel);
|
|
connect(button_ok, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnOk);
|
|
connect(m_id, &QLineEdit::textChanged, this, &AutoPauseConfigDialog::OnUpdateValue);
|
|
|
|
QHBoxLayout* configHBox = new QHBoxLayout();
|
|
configHBox->addWidget(m_id);
|
|
configHBox->addWidget(button_ok);
|
|
configHBox->addWidget(button_cancel);
|
|
configHBox->setAlignment(Qt::AlignCenter);
|
|
|
|
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
|
mainLayout->addWidget(description);
|
|
mainLayout->addLayout(configHBox);
|
|
mainLayout->addWidget(m_current_converted);
|
|
|
|
setLayout(mainLayout);
|
|
setFixedSize(QSize(300, sizeHint().height()));
|
|
|
|
OnUpdateValue();
|
|
}
|
|
|
|
void AutoPauseConfigDialog::OnOk()
|
|
{
|
|
bool ok;
|
|
ullong value = m_id->text().toULongLong(&ok, 16);
|
|
|
|
m_entry = value;
|
|
*m_presult = m_entry;
|
|
|
|
accept();
|
|
}
|
|
|
|
void AutoPauseConfigDialog::OnCancel()
|
|
{
|
|
if (m_newEntry)
|
|
{
|
|
m_apsd->OnRemove();
|
|
}
|
|
close();
|
|
}
|
|
|
|
void AutoPauseConfigDialog::OnUpdateValue()
|
|
{
|
|
bool ok;
|
|
ullong value = m_id->text().toULongLong(&ok, 16);
|
|
const bool is_ok = ok && value <= UINT32_MAX;
|
|
|
|
m_current_converted->setText(tr("Current value: %1 (%2)").arg(value, 8, 16).arg(is_ok ? tr("OK") : tr("Conversion failed")));
|
|
}
|