Qt: Abstract cheats interface.

This commit is contained in:
BearOso 2023-12-16 13:12:09 -06:00
parent b8d71c6562
commit 4dddce8b88
5 changed files with 174 additions and 33 deletions

View File

@ -1,16 +1,13 @@
#include "CheatsDialog.hpp" #include "CheatsDialog.hpp"
#include "EmuApplication.hpp" #include "EmuApplication.hpp"
#include "EmuConfig.hpp" #include "EmuConfig.hpp"
#include "../cheats.h"
#include "fscompat.h" #include "fscompat.h"
#include <tuple>
#include <QMessageBox> #include <QMessageBox>
#include <QDir> #include <QDir>
#include <QtEvents> #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 |
Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsSelectable |
@ -35,12 +32,10 @@ CheatsDialog::CheatsDialog(QWidget *parent, EmuApplication *app_)
auto index = treeWidget_cheats->indexOfTopLevelItem(item); auto index = treeWidget_cheats->indexOfTopLevelItem(item);
app->suspendThread();
if (item->checkState(0) == Qt::Checked) if (item->checkState(0) == Qt::Checked)
S9xEnableCheatGroup(index); app->enableCheat(index);
else else
S9xDisableCheatGroup(index); app->disableCheat(index);
app->unsuspendThread();
}); });
connect(treeWidget_cheats, &QTreeWidget::itemDoubleClicked, [&](QTreeWidgetItem *item, int column) { connect(treeWidget_cheats, &QTreeWidget::itemDoubleClicked, [&](QTreeWidgetItem *item, int column) {
@ -68,7 +63,7 @@ void CheatsDialog::addCode()
if (description.empty()) if (description.empty())
description = tr("No description").toStdString(); description = tr("No description").toStdString();
if (S9xAddCheatGroup(description, code) < 0) if (app->addCheat(description, code))
{ {
QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid.")); QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid."));
return; return;
@ -84,9 +79,7 @@ void CheatsDialog::removeCode()
return; return;
auto index = treeWidget_cheats->currentIndex().row(); auto index = treeWidget_cheats->currentIndex().row();
app->suspendThread(); app->deleteCheat(index);
S9xDeleteCheatGroup(index);
app->unsuspendThread();
auto item = treeWidget_cheats->takeTopLevelItem(index); auto item = treeWidget_cheats->takeTopLevelItem(index);
if (item) if (item)
delete item; delete item;
@ -94,19 +87,14 @@ void CheatsDialog::removeCode()
void CheatsDialog::disableAll() void CheatsDialog::disableAll()
{ {
app->suspendThread(); app->disableAllCheats();
for (size_t i = 0; i < clist.size(); i++)
S9xDisableCheatGroup(i);
app->unsuspendThread();
refreshList(); refreshList();
} }
void CheatsDialog::removeAll() void CheatsDialog::removeAll()
{ {
treeWidget_cheats->clear(); treeWidget_cheats->clear();
app->suspendThread(); app->deleteAllCheats();
S9xDeleteCheats();
app->unsuspendThread();
} }
void CheatsDialog::searchDatabase() void CheatsDialog::searchDatabase()
@ -125,9 +113,7 @@ void CheatsDialog::searchDatabase()
for (auto &path : dirs) for (auto &path : dirs)
{ {
auto filename = QDir(QString::fromStdString(path)).absoluteFilePath("cheats.bml").toStdString(); auto filename = QDir(QString::fromStdString(path)).absoluteFilePath("cheats.bml").toStdString();
app->suspendThread(); auto result = app->tryImportCheats(filename);
auto result = S9xImportCheatsFromDatabase(filename);
app->unsuspendThread();
if (result == 0) if (result == 0)
{ {
refreshList(); refreshList();
@ -159,16 +145,14 @@ void CheatsDialog::updateCurrent()
if (description.empty()) if (description.empty())
description = tr("No description").toStdString(); description = tr("No description").toStdString();
auto validated = S9xCheatValidate(code); auto validated = app->validateCheat(code);
if (validated.empty()) if (validated.empty())
{ {
QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid.")); QMessageBox::information(this, tr("Invalid Cheat"), tr("The cheat you entered was not valid."));
return; return;
} }
app->suspendThread(); app->modifyCheat(index, description, validated);
S9xModifyCheatGroup(index, description, validated);
app->unsuspendThread();
treeWidget_cheats->currentItem()->setText(1, lineEdit_description->text()); treeWidget_cheats->currentItem()->setText(1, lineEdit_description->text());
treeWidget_cheats->currentItem()->setText(2, QString::fromStdString(validated)); treeWidget_cheats->currentItem()->setText(2, QString::fromStdString(validated));
@ -180,17 +164,16 @@ void CheatsDialog::refreshList()
QList<QTreeWidgetItem *> items; QList<QTreeWidgetItem *> items;
app->suspendThread(); auto clist = app->getCheatList();
for (const auto &c: clist) for (const auto &[enabled, name, cheat]: clist)
{ {
auto i = new QTreeWidgetItem(); auto i = new QTreeWidgetItem();
i->setFlags(desired_flags); i->setFlags(desired_flags);
i->setCheckState(0, c.enabled ? Qt::Checked : Qt::Unchecked); i->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked);
i->setText(1, QString::fromStdString(c.name)); i->setText(1, QString::fromStdString(name));
i->setText(2, QString::fromStdString(S9xCheatGroupToText(c))); i->setText(2, QString::fromStdString(cheat));
items.push_back(i); items.push_back(i);
} }
app->unsuspendThread();
treeWidget_cheats->insertTopLevelItems(0, items); treeWidget_cheats->insertTopLevelItems(0, items);
} }

View File

@ -525,6 +525,82 @@ std::string EmuApplication::getStateFolder()
return core->getStateFolder(); return core->getStateFolder();
} }
std::vector<std::tuple<bool, std::string, std::string>> EmuApplication::getCheatList()
{
suspendThread();
auto cheat_list = core->getCheatList();
unsuspendThread();
return std::move(cheat_list);
}
void EmuApplication::disableAllCheats()
{
emu_thread->runOnThread([&] {
core->disableAllCheats();
});
}
void EmuApplication::enableCheat(int index)
{
emu_thread->runOnThread([&] {
core->enableCheat(index);
});
}
void EmuApplication::disableCheat(int index)
{
emu_thread->runOnThread([&] {
core->disableCheat(index);
});
}
bool EmuApplication::addCheat(std::string description, std::string code)
{
suspendThread();
auto retval = core->addCheat(description, code);
unsuspendThread();
return retval;
}
void EmuApplication::deleteCheat(int index)
{
emu_thread->runOnThread([&] {
core->deleteCheat(index);
});
}
void EmuApplication::deleteAllCheats()
{
emu_thread->runOnThread([&] {
core->deleteAllCheats();
});
}
int EmuApplication::tryImportCheats(std::string filename)
{
suspendThread();
auto retval = core->tryImportCheats(filename);
unsuspendThread();
return retval;
}
std::string EmuApplication::validateCheat(std::string code)
{
suspendThread();
auto retval = core->validateCheat(code);
unsuspendThread();
return retval;
}
int EmuApplication::modifyCheat(int index, std::string name, std::string code)
{
suspendThread();
auto retval = core->modifyCheat(index, name, code);
unsuspendThread();
return retval;
}
bool EmuApplication::isCoreActive() bool EmuApplication::isCoreActive()
{ {
return core->active; return core->active;

View File

@ -84,6 +84,17 @@ struct EmuApplication
bool isCoreActive(); bool isCoreActive();
QString iconPrefix(); QString iconPrefix();
std::vector<std::tuple<bool, std::string, std::string>> getCheatList();
void disableAllCheats();
void enableCheat(int index);
void disableCheat(int index);
bool addCheat(std::string description, std::string code);
void deleteCheat(int index);
void deleteAllCheats();
int tryImportCheats(std::string filename);
std::string validateCheat(std::string code);
int modifyCheat(int index, std::string name, std::string code);
enum Handler enum Handler
{ {
Core = 0, Core = 0,

View File

@ -744,4 +744,64 @@ bool Snes9xController::saveState(int slot)
void Snes9xController::setMessage(std::string message) void Snes9xController::setMessage(std::string message)
{ {
S9xSetInfoString(message.c_str()); S9xSetInfoString(message.c_str());
} }
std::vector<std::tuple<bool, std::string, std::string>> Snes9xController::getCheatList()
{
std::vector<std::tuple<bool, std::string, std::string>> cheat_list;
cheat_list.reserve(Cheat.group.size());
for (auto &c : Cheat.group)
cheat_list.push_back({ c.enabled, c.name, S9xCheatGroupToText(c) });
return std::move(cheat_list);
}
void Snes9xController::disableAllCheats()
{
for (size_t i = 0; i < Cheat.group.size(); i++)
{
S9xDisableCheatGroup(i);
}
}
void Snes9xController::enableCheat(int index)
{
S9xEnableCheatGroup(index);
}
void Snes9xController::disableCheat(int index)
{
S9xDisableCheatGroup(index);
}
bool Snes9xController::addCheat(std::string description, std::string code)
{
return S9xAddCheatGroup(description, code) >= 0;
}
void Snes9xController::deleteCheat(int index)
{
S9xDeleteCheatGroup(index);
}
void Snes9xController::deleteAllCheats()
{
S9xDeleteCheats();
}
int Snes9xController::tryImportCheats(std::string filename)
{
return S9xImportCheatsFromDatabase(filename);
}
std::string Snes9xController::validateCheat(std::string code)
{
return S9xCheatValidate(code);
}
int Snes9xController::modifyCheat(int index, std::string name, std::string code)
{
return S9xModifyCheatGroup(index, name, code);
}

View File

@ -36,6 +36,17 @@ class Snes9xController
void setPaused(bool paused); void setPaused(bool paused);
void setMessage(std::string message); void setMessage(std::string message);
void clearSoundBuffer(); void clearSoundBuffer();
std::vector<std::tuple<bool, std::string, std::string>> getCheatList();
void disableAllCheats();
void enableCheat(int index);
void disableCheat(int index);
bool addCheat(std::string description, std::string code);
void deleteCheat(int index);
void deleteAllCheats();
int tryImportCheats(std::string filename);
std::string validateCheat(std::string code);
int modifyCheat(int index, std::string name, std::string code);
std::string getStateFolder(); std::string getStateFolder();
std::string config_folder; std::string config_folder;
std::string sram_folder; std::string sram_folder;