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 S9xEnableCheatGroup(uint32_t index);
void S9xDisableCheatGroup(uint32_t index); void S9xDisableCheatGroup(uint32_t index);
void S9xDeleteCheats(void); void S9xDeleteCheats(void);
std::string S9xCheatGroupToText(const SCheatGroup &g);
std::string S9xCheatGroupToText(uint32_t index); std::string S9xCheatGroupToText(uint32_t index);
void S9xDeleteCheatGroup(uint32_t index); void S9xDeleteCheatGroup(uint32_t index);
bool8 S9xLoadCheatFile(const std::string &filename); bool8 S9xLoadCheatFile(const std::string &filename);

View File

@ -534,7 +534,7 @@ std::string S9xCheatToText(const SCheat &c)
return std::string(output); return std::string(output);
} }
std::string S9xCheatGroupToText(SCheatGroup &g) std::string S9xCheatGroupToText(const SCheatGroup &g)
{ {
std::string text = ""; 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>("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>("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>("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())); gtk_widget_realize(GTK_WIDGET(window->gobj()));
} }
@ -288,7 +287,9 @@ void Snes9xCheats::search_database()
for (const auto &dir : { S9xGetDirectory(CHEAT_DIR), for (const auto &dir : { S9xGetDirectory(CHEAT_DIR),
get_config_dir(), get_config_dir(),
std::string(DATADIR) }) std::string(DATADIR),
"/usr/share/snes9x",
"/usr/local/share/snes9x" })
{ {
filename = dir + "/cheats.bml"; filename = dir + "/cheats.bml";
result = S9xImportCheatsFromDatabase(filename); result = S9xImportCheatsFromDatabase(filename);

View File

@ -1,4 +1,15 @@
#include "CheatsDialog.hpp" #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 | static const auto desired_flags = Qt::ItemFlag::ItemIsUserCheckable |
Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsEnabled |
@ -9,19 +20,183 @@ CheatsDialog::CheatsDialog(QWidget *parent, EmuApplication *app_)
: app(app_), QDialog(parent) : app(app_), QDialog(parent)
{ {
setupUi(this); 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(); show();
}
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setFlags(desired_flags); void CheatsDialog::showEvent(QShowEvent *event)
item->setCheckState(0, Qt::CheckState::Checked); {
item->setText(1, "Invincibility"); refreshList();
item->setText(2, "dd32-6dad"); QDialog::showEvent(event);
}
treeWidget_cheats->insertTopLevelItem(0, item);
item = new QTreeWidgetItem(); void CheatsDialog::addCode()
item->setFlags(desired_flags); {
item->setCheckState(0, Qt::CheckState::Checked); auto description = lineEdit_description->text().toStdString();
item->setText(1, "Torzx"); auto code = lineEdit_code->text().toStdString();
item->setText(2, "7e0fff:ff\n7e0ff7:ff");
treeWidget_cheats->insertTopLevelItem(1, item); 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

@ -6,7 +6,15 @@ class CheatsDialog : public QDialog, public Ui_Dialog
{ {
public: public:
CheatsDialog(QWidget *parent, EmuApplication *app); 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; EmuApplication *app;
void resizeEvent(QResizeEvent *event) override;
}; };

View File

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

View File

@ -417,6 +417,11 @@ void EmuConfig::config(std::string filename, bool write)
String("LastROMFolder", last_rom_folder); String("LastROMFolder", last_rom_folder);
Int("MainWindowWidth", main_window_width); Int("MainWindowWidth", main_window_width);
Int("MainWindowHeight", main_window_height); 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 recent_count = recently_used.size();
Int("RecentlyUsedEntries", recent_count); Int("RecentlyUsedEntries", recent_count);
if (!write) if (!write)

View File

@ -31,6 +31,10 @@ struct EmuConfig
std::string last_rom_folder; std::string last_rom_folder;
int main_window_width = 0; int main_window_width = 0;
int main_window_height = 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; std::vector<std::string> recently_used;
// General // General

View File

@ -18,7 +18,6 @@
#include "EmuCanvasOpenGL.hpp" #include "EmuCanvasOpenGL.hpp"
#include "EmuCanvasQt.hpp" #include "EmuCanvasQt.hpp"
#include "CheatsDialog.hpp" #include "CheatsDialog.hpp"
#include "ShaderParametersDialog.hpp"
#undef KeyPress #undef KeyPress
static EmuSettingsWindow *g_emu_settings_window = nullptr; static EmuSettingsWindow *g_emu_settings_window = nullptr;
@ -265,7 +264,9 @@ void EmuMainWindow::createWidgets()
auto cheats_item = emulation_menu->addAction(tr("&Cheats")); auto cheats_item = emulation_menu->addAction(tr("&Cheats"));
connect(cheats_item, &QAction::triggered, [&] { 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); core_actions.push_back(cheats_item);
@ -663,3 +664,9 @@ void EmuMainWindow::shaderChanged()
canvas->shaderChanged(); canvas->shaderChanged();
}); });
} }
void EmuMainWindow::gameChanging()
{
if (cheats_dialog)
cheats_dialog->close();
}

View File

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

View File

@ -7,6 +7,7 @@
#include <QSpacerItem> #include <QSpacerItem>
#include <QScrollArea> #include <QScrollArea>
#include <QFileDialog> #include <QFileDialog>
#include <QResizeEvent>
static bool is_simple(const EmuCanvas::Parameter &p) 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); scroll_area->setWidget(scroll_area_widget_contents);
layout->addWidget(scroll_area); layout->addWidget(scroll_area);
layout->addLayout(buttonbox, 0); 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() void ShaderParametersDialog::save()
@ -197,6 +201,12 @@ void ShaderParametersDialog::closeEvent(QCloseEvent *event)
*parameters = saved_parameters; *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() ShaderParametersDialog::~ShaderParametersDialog()
{ {
} }

View File

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