Qt: Attach cheats dialog directly to Snes9x.

Update sizing for cheats and shader params dialogs.
This commit is contained in:
BearOso 2023-08-14 16:51:50 -05:00
parent 34aab85f69
commit bd41d010f3
14 changed files with 262 additions and 45 deletions

View file

@ -81,6 +81,7 @@ int S9xModifyCheatGroup(uint32_t index, const std::string &name, const std::stri
void S9xEnableCheatGroup(uint32_t index);
void S9xDisableCheatGroup(uint32_t index);
void S9xDeleteCheats(void);
std::string S9xCheatGroupToText(const SCheatGroup &g);
std::string S9xCheatGroupToText(uint32_t index);
void S9xDeleteCheatGroup(uint32_t index);
bool8 S9xLoadCheatFile(const std::string &filename);

View file

@ -534,7 +534,7 @@ std::string S9xCheatToText(const SCheat &c)
return std::string(output);
}
std::string S9xCheatGroupToText(SCheatGroup &g)
std::string S9xCheatGroupToText(const SCheatGroup &g)
{
std::string text = "";

@ -1 +1 @@
Subproject commit 4e2fdb25671c742a9fbe93a6034eb1542244c7e1
Subproject commit bccaa94db814af33d8ef05c153e7c34d8bd4d685

2
external/glslang vendored

@ -1 +1 @@
Subproject commit 3ebb72cc7429f0ab8218104dc3687c659c0f364d
Subproject commit 9c7fd1a33e5cecbe465e1cd70170167d5e40d398

View file

@ -94,7 +94,6 @@ Snes9xCheats::Snes9xCheats()
get_object<Gtk::Button>("disable_all_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::disable_all));
get_object<Gtk::Button>("delete_all_cheats_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::delete_all_cheats));
get_object<Gtk::Button>("cheat_search_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::search_database));
get_object<Gtk::Button>("update_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::update_code));
gtk_widget_realize(GTK_WIDGET(window->gobj()));
}
@ -288,7 +287,9 @@ void Snes9xCheats::search_database()
for (const auto &dir : { S9xGetDirectory(CHEAT_DIR),
get_config_dir(),
std::string(DATADIR) })
std::string(DATADIR),
"/usr/share/snes9x",
"/usr/local/share/snes9x" })
{
filename = dir + "/cheats.bml";
result = S9xImportCheatsFromDatabase(filename);

View file

@ -1,27 +1,202 @@
#include "CheatsDialog.hpp"
static const auto desired_flags = Qt::ItemFlag::ItemIsUserCheckable |
Qt::ItemFlag::ItemIsEnabled |
Qt::ItemFlag::ItemIsSelectable |
Qt::ItemFlag::ItemIsDragEnabled;
CheatsDialog::CheatsDialog(QWidget *parent, EmuApplication *app_)
: app(app_), QDialog(parent)
{
setupUi(this);
show();
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setFlags(desired_flags);
item->setCheckState(0, Qt::CheckState::Checked);
item->setText(1, "Invincibility");
item->setText(2, "dd32-6dad");
treeWidget_cheats->insertTopLevelItem(0, item);
item = new QTreeWidgetItem();
item->setFlags(desired_flags);
item->setCheckState(0, Qt::CheckState::Checked);
item->setText(1, "Torzx");
item->setText(2, "7e0fff:ff\n7e0ff7:ff");
treeWidget_cheats->insertTopLevelItem(1, item);
#include "CheatsDialog.hpp"
#include "EmuApplication.hpp"
#include "EmuConfig.hpp"
#include "../cheats.h"
#include "fscompat.h"
#include <QMessageBox>
#include <QDir>
#include <QtEvents>
extern SCheatData Cheat;
auto &clist = Cheat.group;
static const auto desired_flags = Qt::ItemFlag::ItemIsUserCheckable |
Qt::ItemFlag::ItemIsEnabled |
Qt::ItemFlag::ItemIsSelectable |
Qt::ItemFlag::ItemIsDragEnabled;
CheatsDialog::CheatsDialog(QWidget *parent, EmuApplication *app_)
: app(app_), QDialog(parent)
{
setupUi(this);
connect(pushButton_add, &QPushButton::clicked, [&] { addCode(); });
connect(pushButton_remove, &QPushButton::clicked, [&] { removeCode(); });
connect(pushButton_remove_all, &QPushButton::clicked, [&] { removeAll(); });
connect(pushButton_check_database, &QPushButton::clicked, [&] { searchDatabase(); });
connect(pushButton_update, &QPushButton::clicked, [&] { updateCurrent(); });
treeWidget_cheats->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
connect(treeWidget_cheats, &QTreeWidget::itemChanged, [&](QTreeWidgetItem *item, int column) {
if (column != 0)
return;
auto index = treeWidget_cheats->indexOfTopLevelItem(item);
app->suspendThread();
if (item->checkState(0) == Qt::Checked)
S9xEnableCheatGroup(index);
else
S9xDisableCheatGroup(index);
app->unsuspendThread();
});
connect(treeWidget_cheats, &QTreeWidget::itemDoubleClicked, [&](QTreeWidgetItem *item, int column) {
lineEdit_description->setText(item->text(1));
lineEdit_code->setText(item->text(2));
});
if (app->config->cheat_dialog_width != 0)
resize(app->config->cheat_dialog_width, app->config->cheat_dialog_height);
show();
}
void CheatsDialog::showEvent(QShowEvent *event)
{
refreshList();
QDialog::showEvent(event);
}
void CheatsDialog::addCode()
{
auto description = lineEdit_description->text().toStdString();
auto code = lineEdit_code->text().toStdString();
if (description.empty())
description = tr("No description").toStdString();
if (S9xAddCheatGroup(description, code) < 0)
{
QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid."));
return;
}
refreshList();
treeWidget_cheats->setTreePosition(treeWidget_cheats->topLevelItemCount() - 1);
}
void CheatsDialog::removeCode()
{
if (!treeWidget_cheats->currentIndex().isValid())
return;
auto index = treeWidget_cheats->currentIndex().row();
app->suspendThread();
S9xDeleteCheatGroup(index);
app->unsuspendThread();
auto item = treeWidget_cheats->takeTopLevelItem(index);
if (item)
delete item;
}
void CheatsDialog::disableAll()
{
app->suspendThread();
for (size_t i = 0; i < clist.size(); i++)
S9xDisableCheatGroup(i);
app->unsuspendThread();
refreshList();
}
void CheatsDialog::removeAll()
{
treeWidget_cheats->clear();
app->suspendThread();
S9xDeleteCheats();
app->unsuspendThread();
}
void CheatsDialog::searchDatabase()
{
std::initializer_list<std::string> dirs =
{
EmuConfig::findConfigDir(),
QGuiApplication::applicationDirPath().toStdString(),
S9xGetDirectory(CHEAT_DIR),
"/usr/share/snes9x",
"/usr/local/share/snes9x"
};
bool found = false;
for (auto &path : dirs)
{
auto filename = QDir(QString::fromStdString(path)).absoluteFilePath("cheats.bml").toStdString();
app->suspendThread();
auto result = S9xImportCheatsFromDatabase(filename);
app->unsuspendThread();
if (result == 0)
{
refreshList();
return;
}
if (result == -1)
continue;
if (result == -2)
{
QMessageBox::information(this, tr("No Cheats Found"), tr("No cheats for the current game were found in the database."));
return;
}
}
QMessageBox::information(this, tr("Unable to Open Cheats Database"), tr("cheats.bml was not found."));
}
void CheatsDialog::updateCurrent()
{
if (!treeWidget_cheats->currentIndex().isValid())
return;
auto description = lineEdit_description->text().toStdString();
auto code = lineEdit_code->text().toStdString();
auto index = treeWidget_cheats->currentIndex().row();
if (description.empty())
description = tr("No description").toStdString();
auto validated = S9xCheatValidate(code);
if (validated.empty())
{
QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid."));
return;
}
app->suspendThread();
S9xModifyCheatGroup(index, description, validated);
app->unsuspendThread();
treeWidget_cheats->currentItem()->setText(1, lineEdit_description->text());
treeWidget_cheats->currentItem()->setText(2, QString::fromStdString(validated));
}
void CheatsDialog::refreshList()
{
treeWidget_cheats->clear();
QList<QTreeWidgetItem *> items;
app->suspendThread();
for (const auto &c: clist)
{
auto i = new QTreeWidgetItem();
i->setFlags(desired_flags);
i->setCheckState(0, c.enabled ? Qt::Checked : Qt::Unchecked);
i->setText(1, QString::fromStdString(c.name));
i->setText(2, QString::fromStdString(S9xCheatGroupToText(c)));
items.push_back(i);
}
app->unsuspendThread();
treeWidget_cheats->insertTopLevelItems(0, items);
}
void CheatsDialog::resizeEvent(QResizeEvent *event)
{
app->config->cheat_dialog_width = event->size().width();
app->config->cheat_dialog_height = event->size().height();
}

View file

@ -1,12 +1,20 @@
#include "ui_CheatsDialog.h"
class EmuApplication;
class CheatsDialog : public QDialog, public Ui_Dialog
{
public:
CheatsDialog(QWidget *parent, EmuApplication *app);
EmuApplication *app;
};
#include "ui_CheatsDialog.h"
class EmuApplication;
class CheatsDialog : public QDialog, public Ui_Dialog
{
public:
CheatsDialog(QWidget *parent, EmuApplication *app);
void addCode();
void removeCode();
void updateCurrent();
void disableAll();
void removeAll();
void searchDatabase();
void refreshList();
void showEvent(QShowEvent *) override;
EmuApplication *app;
void resizeEvent(QResizeEvent *event) override;
};

View file

@ -246,6 +246,7 @@ void EmuApplication::startThread()
bool EmuApplication::openFile(std::string filename)
{
window->gameChanging();
suspendThread();
auto result = core->openFile(filename);
unsuspendThread();

View file

@ -417,6 +417,11 @@ void EmuConfig::config(std::string filename, bool write)
String("LastROMFolder", last_rom_folder);
Int("MainWindowWidth", main_window_width);
Int("MainWindowHeight", main_window_height);
Int("ShaderParametersDialogWidth", shader_parameters_dialog_width);
Int("ShaderParametersDialogHeight", shader_parameters_dialog_height);
Int("CheatDialogWidth", cheat_dialog_width);
Int("CheatDialogHeight", cheat_dialog_height);
int recent_count = recently_used.size();
Int("RecentlyUsedEntries", recent_count);
if (!write)

View file

@ -31,6 +31,10 @@ struct EmuConfig
std::string last_rom_folder;
int main_window_width = 0;
int main_window_height = 0;
int cheat_dialog_width = 0;
int cheat_dialog_height = 0;
int shader_parameters_dialog_width = 0;
int shader_parameters_dialog_height = 0;
std::vector<std::string> recently_used;
// General

View file

@ -18,7 +18,6 @@
#include "EmuCanvasOpenGL.hpp"
#include "EmuCanvasQt.hpp"
#include "CheatsDialog.hpp"
#include "ShaderParametersDialog.hpp"
#undef KeyPress
static EmuSettingsWindow *g_emu_settings_window = nullptr;
@ -265,7 +264,9 @@ void EmuMainWindow::createWidgets()
auto cheats_item = emulation_menu->addAction(tr("&Cheats"));
connect(cheats_item, &QAction::triggered, [&] {
auto cheats_dialog = new CheatsDialog(this, app);
if (!cheats_dialog)
cheats_dialog = std::make_unique<CheatsDialog>(this, app);
cheats_dialog->show();
});
core_actions.push_back(cheats_item);
@ -662,4 +663,10 @@ void EmuMainWindow::shaderChanged()
if (canvas)
canvas->shaderChanged();
});
}
void EmuMainWindow::gameChanging()
{
if (cheats_dialog)
cheats_dialog->close();
}

View file

@ -6,6 +6,7 @@
#include "EmuCanvas.hpp"
class EmuApplication;
class CheatsDialog;
class EmuMainWindow : public QMainWindow
{
@ -35,6 +36,7 @@ class EmuMainWindow : public QMainWindow
bool openFile(std::string filename);
void recreateUIAssets();
void shaderChanged();
void gameChanging();
std::vector<std::string> getDisplayDeviceList();
EmuApplication *app;
EmuCanvas *canvas;
@ -46,6 +48,8 @@ class EmuMainWindow : public QMainWindow
static const size_t recent_menu_size = 10;
static const size_t state_items_size = 10;
std::unique_ptr<CheatsDialog> cheats_dialog;
bool manual_pause = false;
bool focus_pause = false;
bool minimized_pause = false;

View file

@ -7,6 +7,7 @@
#include <QSpacerItem>
#include <QScrollArea>
#include <QFileDialog>
#include <QResizeEvent>
static bool is_simple(const EmuCanvas::Parameter &p)
{
@ -129,6 +130,9 @@ ShaderParametersDialog::ShaderParametersDialog(EmuCanvas *parent_, std::vector<E
scroll_area->setWidget(scroll_area_widget_contents);
layout->addWidget(scroll_area);
layout->addLayout(buttonbox, 0);
if (config->shader_parameters_dialog_width != 0)
resize(config->shader_parameters_dialog_width, config->shader_parameters_dialog_height);
}
void ShaderParametersDialog::save()
@ -197,6 +201,12 @@ void ShaderParametersDialog::closeEvent(QCloseEvent *event)
*parameters = saved_parameters;
}
void ShaderParametersDialog::resizeEvent(QResizeEvent *event)
{
config->shader_parameters_dialog_width = event->size().width();
config->shader_parameters_dialog_height = event->size().height();
}
ShaderParametersDialog::~ShaderParametersDialog()
{
}

View file

@ -16,6 +16,7 @@ class ShaderParametersDialog : public QDialog
void refreshWidgets();
void showEvent(QShowEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void save();
void saveAs();