From 7327c334ca722214faf882150924ec15d247145e Mon Sep 17 00:00:00 2001 From: luc-git <102831178+luc-git@users.noreply.github.com> Date: Sun, 30 Apr 2023 16:36:02 +0200 Subject: [PATCH] Add cheats in per game configuration (#6379) --- src/citra_qt/CMakeLists.txt | 6 +- .../configure_cheats.cpp} | 80 +++++++++---------- .../configure_cheats.h} | 21 ++--- .../configure_cheats.ui} | 26 +----- .../configuration/configure_per_game.cpp | 16 ++++ .../configuration/configure_per_game.h | 3 + .../configuration/configure_per_game.ui | 16 ---- src/citra_qt/main.cpp | 9 --- src/citra_qt/main.h | 1 - src/citra_qt/main.ui | 8 +- src/core/cheats/cheats.cpp | 17 ++-- src/core/cheats/cheats.h | 3 +- src/core/core.cpp | 2 +- 13 files changed, 86 insertions(+), 122 deletions(-) rename src/citra_qt/{cheats.cpp => configuration/configure_cheats.cpp} (78%) rename src/citra_qt/{cheats.h => configuration/configure_cheats.h} (76%) rename src/citra_qt/{cheats.ui => configuration/configure_cheats.ui} (89%) diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index dc043dc2f3..2bfc36c820 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -28,9 +28,6 @@ add_executable(citra-qt camera/qt_camera_base.h camera/qt_multimedia_camera.cpp camera/qt_multimedia_camera.h - cheats.cpp - cheats.h - cheats.ui citra-qt.rc compatdb.cpp compatdb.h @@ -88,6 +85,9 @@ add_executable(citra-qt configuration/configure_web.cpp configuration/configure_web.h configuration/configure_web.ui + configuration/configure_cheats.cpp + configuration/configure_cheats.h + configuration/configure_cheats.ui debugger/console.h debugger/console.cpp debugger/graphics/graphics.cpp diff --git a/src/citra_qt/cheats.cpp b/src/citra_qt/configuration/configure_cheats.cpp similarity index 78% rename from src/citra_qt/cheats.cpp rename to src/citra_qt/configuration/configure_cheats.cpp index 343568004a..4569f7ed84 100644 --- a/src/citra_qt/cheats.cpp +++ b/src/citra_qt/configuration/configure_cheats.cpp @@ -5,16 +5,16 @@ #include #include #include -#include "citra_qt/cheats.h" +#include "configure_cheats.h" #include "core/cheats/cheat_base.h" #include "core/cheats/cheats.h" #include "core/cheats/gateway_cheat.h" #include "core/core.h" #include "core/hle/kernel/process.h" -#include "ui_cheats.h" +#include "ui_configure_cheats.h" -CheatDialog::CheatDialog(QWidget* parent) - : QDialog(parent), ui(std::make_unique()) { +ConfigureCheats::ConfigureCheats(u64 title_id_, QWidget* parent) + : QWidget(parent), ui(std::make_unique()), title_id{title_id_} { // Setup gui control settings ui->setupUi(this); ui->tableCheats->setColumnWidth(0, 30); @@ -25,28 +25,26 @@ CheatDialog::CheatDialog(QWidget* parent) ui->lineName->setEnabled(false); ui->textCode->setEnabled(false); ui->textNotes->setEnabled(false); - const auto game_id = fmt::format( - "{:016X}", Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); - ui->labelTitle->setText(tr("Title ID: %1").arg(QString::fromStdString(game_id))); - connect(ui->buttonClose, &QPushButton::clicked, this, &CheatDialog::OnCancel); - connect(ui->buttonAddCheat, &QPushButton::clicked, this, &CheatDialog::OnAddCheat); - connect(ui->tableCheats, &QTableWidget::cellClicked, this, &CheatDialog::OnRowSelected); - connect(ui->lineName, &QLineEdit::textEdited, this, &CheatDialog::OnTextEdited); - connect(ui->textNotes, &QPlainTextEdit::textChanged, this, &CheatDialog::OnTextEdited); - connect(ui->textCode, &QPlainTextEdit::textChanged, this, &CheatDialog::OnTextEdited); + connect(ui->buttonAddCheat, &QPushButton::clicked, this, &ConfigureCheats::OnAddCheat); + connect(ui->tableCheats, &QTableWidget::cellClicked, this, &ConfigureCheats::OnRowSelected); + connect(ui->lineName, &QLineEdit::textEdited, this, &ConfigureCheats::OnTextEdited); + connect(ui->textNotes, &QPlainTextEdit::textChanged, this, &ConfigureCheats::OnTextEdited); + connect(ui->textCode, &QPlainTextEdit::textChanged, this, &ConfigureCheats::OnTextEdited); connect(ui->buttonSave, &QPushButton::clicked, this, [this] { SaveCheat(ui->tableCheats->currentRow()); }); - connect(ui->buttonDelete, &QPushButton::clicked, this, &CheatDialog::OnDeleteCheat); + connect(ui->buttonDelete, &QPushButton::clicked, this, &ConfigureCheats::OnDeleteCheat); + + cheat_engine = std::make_unique(title_id, Core::System::GetInstance()); LoadCheats(); } -CheatDialog::~CheatDialog() = default; +ConfigureCheats::~ConfigureCheats() = default; -void CheatDialog::LoadCheats() { - cheats = Core::System::GetInstance().CheatEngine().GetCheats(); +void ConfigureCheats::LoadCheats() { + cheats = cheat_engine->GetCheats(); const int cheats_count = static_cast(cheats.size()); ui->tableCheats->setRowCount(cheats_count); @@ -63,11 +61,11 @@ void CheatDialog::LoadCheats() { i, 2, new QTableWidgetItem(QString::fromStdString(cheats[i]->GetType()))); enabled->setProperty("row", static_cast(i)); - connect(enabled, &QCheckBox::stateChanged, this, &CheatDialog::OnCheckChanged); + connect(enabled, &QCheckBox::stateChanged, this, &ConfigureCheats::OnCheckChanged); } } -bool CheatDialog::CheckSaveCheat() { +bool ConfigureCheats::CheckSaveCheat() { auto answer = QMessageBox::warning( this, tr("Cheats"), tr("Would you like to save the current cheat?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel); @@ -79,7 +77,7 @@ bool CheatDialog::CheckSaveCheat() { } } -bool CheatDialog::SaveCheat(int row) { +bool ConfigureCheats::SaveCheat(int row) { if (ui->lineName->text().isEmpty()) { QMessageBox::critical(this, tr("Save Cheat"), tr("Please enter a cheat name.")); return false; @@ -110,12 +108,12 @@ bool CheatDialog::SaveCheat(int row) { ui->textNotes->toPlainText().toStdString()); if (newly_created) { - Core::System::GetInstance().CheatEngine().AddCheat(cheat); + cheat_engine->AddCheat(cheat); newly_created = false; } else { - Core::System::GetInstance().CheatEngine().UpdateCheat(row, cheat); + cheat_engine->UpdateCheat(row, cheat); } - Core::System::GetInstance().CheatEngine().SaveCheatFile(); + cheat_engine->SaveCheatFile(); int previous_row = ui->tableCheats->currentRow(); int previous_col = ui->tableCheats->currentColumn(); @@ -128,19 +126,7 @@ bool CheatDialog::SaveCheat(int row) { return true; } -void CheatDialog::closeEvent(QCloseEvent* event) { - if (edited && !CheckSaveCheat()) { - event->ignore(); - return; - } - event->accept(); -} - -void CheatDialog::OnCancel() { - close(); -} - -void CheatDialog::OnRowSelected(int row, int column) { +void ConfigureCheats::OnRowSelected(int row, int column) { if (row == last_row) { return; } @@ -173,25 +159,24 @@ void CheatDialog::OnRowSelected(int row, int column) { last_col = column; } -void CheatDialog::OnCheckChanged(int state) { +void ConfigureCheats::OnCheckChanged(int state) { const QCheckBox* checkbox = qobject_cast(sender()); int row = static_cast(checkbox->property("row").toInt()); cheats[row]->SetEnabled(state); - Core::System::GetInstance().CheatEngine().SaveCheatFile(); + cheat_engine->SaveCheatFile(); } -void CheatDialog::OnTextEdited() { +void ConfigureCheats::OnTextEdited() { edited = true; ui->buttonSave->setEnabled(true); } -void CheatDialog::OnDeleteCheat() { +void ConfigureCheats::OnDeleteCheat() { if (newly_created) { newly_created = false; } else { - auto& cheat_engine = Core::System::GetInstance().CheatEngine(); - cheat_engine.RemoveCheat(ui->tableCheats->currentRow()); - cheat_engine.SaveCheatFile(); + cheat_engine->RemoveCheat(ui->tableCheats->currentRow()); + cheat_engine->SaveCheatFile(); } LoadCheats(); @@ -221,7 +206,14 @@ void CheatDialog::OnDeleteCheat() { ui->buttonAddCheat->setEnabled(true); } -void CheatDialog::OnAddCheat() { +bool ConfigureCheats::ApplyConfiguration() { + if (edited) { + return SaveCheat(ui->tableCheats->currentRow()); + } + return true; +} + +void ConfigureCheats::OnAddCheat() { if (edited && !CheckSaveCheat()) { return; } diff --git a/src/citra_qt/cheats.h b/src/citra_qt/configuration/configure_cheats.h similarity index 76% rename from src/citra_qt/cheats.h rename to src/citra_qt/configuration/configure_cheats.h index 89c08b1c51..5242c82d81 100644 --- a/src/citra_qt/cheats.h +++ b/src/citra_qt/configuration/configure_cheats.h @@ -5,22 +5,24 @@ #pragma once #include -#include +#include "common/common_types.h" namespace Cheats { class CheatBase; -} +class CheatEngine; +} // namespace Cheats namespace Ui { -class CheatDialog; +class ConfigureCheats; } // namespace Ui -class CheatDialog : public QDialog { +class ConfigureCheats : public QWidget { Q_OBJECT public: - explicit CheatDialog(QWidget* parent = nullptr); - ~CheatDialog(); + explicit ConfigureCheats(u64 title_id_, QWidget* parent = nullptr); + ~ConfigureCheats(); + bool ApplyConfiguration(); private: /** @@ -42,10 +44,7 @@ private: */ bool SaveCheat(int row); - void closeEvent(QCloseEvent* event) override; - private slots: - void OnCancel(); void OnRowSelected(int row, int column); void OnCheckChanged(int state); void OnTextEdited(); @@ -53,8 +52,10 @@ private slots: void OnAddCheat(); private: - std::unique_ptr ui; + std::unique_ptr ui; std::vector> cheats; bool edited = false, newly_created = false; int last_row = -1, last_col = -1; + u64 title_id; + std::unique_ptr cheat_engine; }; diff --git a/src/citra_qt/cheats.ui b/src/citra_qt/configuration/configure_cheats.ui similarity index 89% rename from src/citra_qt/cheats.ui rename to src/citra_qt/configuration/configure_cheats.ui index c029d19bf3..68375b5913 100644 --- a/src/citra_qt/cheats.ui +++ b/src/citra_qt/configuration/configure_cheats.ui @@ -1,7 +1,7 @@ - + - CheatDialog - + ConfigureCheats + Qt::ApplicationModal @@ -25,18 +25,6 @@ - - - - - 10 - - - - Title ID: - - - @@ -208,13 +196,6 @@ - - - - Close - - - @@ -227,7 +208,6 @@ textCode buttonSave buttonDelete - buttonClose diff --git a/src/citra_qt/configuration/configure_per_game.cpp b/src/citra_qt/configuration/configure_per_game.cpp index e41fa462a3..fa11e3240d 100644 --- a/src/citra_qt/configuration/configure_per_game.cpp +++ b/src/citra_qt/configuration/configure_per_game.cpp @@ -9,6 +9,7 @@ #include #include "citra_qt/configuration/config.h" #include "citra_qt/configuration/configure_audio.h" +#include "citra_qt/configuration/configure_cheats.h" #include "citra_qt/configuration/configure_debug.h" #include "citra_qt/configuration/configure_enhancements.h" #include "citra_qt/configuration/configure_general.h" @@ -35,6 +36,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString graphics_tab = std::make_unique(this); system_tab = std::make_unique(this); debug_tab = std::make_unique(this); + cheat_tab = std::make_unique(title_id, this); ui->setupUi(this); @@ -44,6 +46,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); ui->tabWidget->addTab(debug_tab.get(), tr("Debug")); + ui->tabWidget->addTab(cheat_tab.get(), tr("Cheats")); setFocusPolicy(Qt::ClickFocus); setWindowTitle(tr("Properties")); @@ -60,6 +63,9 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString connect(ui->button_reset_per_game, &QPushButton::clicked, this, &ConfigurePerGame::ResetDefaults); + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &ConfigurePerGame::HandleAcceptedEvent); + LoadConfiguration(); } @@ -81,6 +87,13 @@ void ConfigurePerGame::ResetDefaults() { close(); } +void ConfigurePerGame::HandleAcceptedEvent() { + if (ui->tabWidget->currentWidget() == cheat_tab.get()) { + cheat_tab->ApplyConfiguration(); + } + accept(); +} + void ConfigurePerGame::ApplyConfiguration() { general_tab->ApplyConfiguration(); system_tab->ApplyConfiguration(); @@ -109,6 +122,9 @@ void ConfigurePerGame::RetranslateUI() { void ConfigurePerGame::HandleApplyButtonClicked() { ApplyConfiguration(); + if (ui->tabWidget->currentWidget() == cheat_tab.get()) { + cheat_tab->ApplyConfiguration(); + } } static QPixmap GetQPixmapFromSMDH(std::vector& smdh_data) { diff --git a/src/citra_qt/configuration/configure_per_game.h b/src/citra_qt/configuration/configure_per_game.h index d84b42c282..e3953fcb77 100644 --- a/src/citra_qt/configuration/configure_per_game.h +++ b/src/citra_qt/configuration/configure_per_game.h @@ -19,6 +19,7 @@ class ConfigureEnhancements; class ConfigureGraphics; class ConfigureSystem; class ConfigureDebug; +class ConfigureCheats; class QGraphicsScene; class QStandardItem; @@ -51,6 +52,7 @@ public: private: void changeEvent(QEvent* event) override; void RetranslateUI(); + void HandleAcceptedEvent(); void HandleApplyButtonClicked(); @@ -70,4 +72,5 @@ private: std::unique_ptr graphics_tab; std::unique_ptr system_tab; std::unique_ptr debug_tab; + std::unique_ptr cheat_tab; }; diff --git a/src/citra_qt/configuration/configure_per_game.ui b/src/citra_qt/configuration/configure_per_game.ui index cd5de38c70..4accbad400 100644 --- a/src/citra_qt/configuration/configure_per_game.ui +++ b/src/citra_qt/configuration/configure_per_game.ui @@ -235,22 +235,6 @@ - - buttonBox - accepted() - ConfigurePerGame - accept() - - - 20 - 20 - - - 20 - 20 - - - buttonBox rejected() diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 066152778f..3b5e104cec 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -34,7 +34,6 @@ #include "citra_qt/bootmanager.h" #include "citra_qt/camera/qt_multimedia_camera.h" #include "citra_qt/camera/still_image_camera.h" -#include "citra_qt/cheats.h" #include "citra_qt/compatdb.h" #include "citra_qt/compatibility_list.h" #include "citra_qt/configuration/config.h" @@ -663,7 +662,6 @@ void GMainWindow::RestoreUIState() { microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry); microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue()); #endif - ui->action_Cheats->setEnabled(false); game_list->LoadInterfaceLayout(); @@ -765,7 +763,6 @@ void GMainWindow::ConnectMenuEvents() { connect_menu(ui->action_Report_Compatibility, &GMainWindow::OnMenuReportCompatibility); connect_menu(ui->action_Configure, &GMainWindow::OnConfigure); connect_menu(ui->action_Configure_Current_Game, &GMainWindow::OnConfigurePerGame); - connect_menu(ui->action_Cheats, &GMainWindow::OnCheats); // View connect_menu(ui->action_Single_Window_Mode, &GMainWindow::ToggleWindowMode); @@ -851,7 +848,6 @@ void GMainWindow::UpdateMenuState() { ui->action_Load_Amiibo, ui->action_Remove_Amiibo, ui->action_Pause, - ui->action_Cheats, ui->action_Advance_Frame, }; @@ -1937,11 +1933,6 @@ void GMainWindow::TriggerRotateScreens() { ui->action_Screen_Layout_Upright_Screens->trigger(); } -void GMainWindow::OnCheats() { - CheatDialog cheat_dialog(this); - cheat_dialog.exec(); -} - void GMainWindow::OnSaveState() { QAction* action = qobject_cast(sender()); assert(action); diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 7ee2165579..6ee7dc5625 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -217,7 +217,6 @@ private slots: void OnRotateScreens(); void TriggerSwapScreens(); void TriggerRotateScreens(); - void OnCheats(); void ShowFullscreen(); void HideFullscreen(); void ToggleWindowMode(); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index ba64ab75f9..3451395688 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -45,7 +45,7 @@ 0 0 1081 - 25 + 22 @@ -115,7 +115,6 @@ - @@ -333,11 +332,6 @@ QAction::PreferencesRole - - - Cheats... - - true diff --git a/src/core/cheats/cheats.cpp b/src/core/cheats/cheats.cpp index f056aad6b6..14fd027753 100644 --- a/src/core/cheats/cheats.cpp +++ b/src/core/cheats/cheats.cpp @@ -19,9 +19,12 @@ namespace Cheats { // we use the same value constexpr u64 run_interval_ticks = 50'000'000; -CheatEngine::CheatEngine(Core::System& system_) : system(system_) { +CheatEngine::CheatEngine(u64 title_id_, Core::System& system_) + : system(system_), title_id{title_id_} { LoadCheatFile(); - Connect(); + if (system.IsPoweredOn()) { + Connect(); + } } void CheatEngine::Connect() { @@ -32,7 +35,9 @@ void CheatEngine::Connect() { } CheatEngine::~CheatEngine() { - system.CoreTiming().UnscheduleEvent(event, 0); + if (system.IsPoweredOn()) { + system.CoreTiming().UnscheduleEvent(event, 0); + } } std::vector> CheatEngine::GetCheats() const { @@ -65,8 +70,7 @@ void CheatEngine::UpdateCheat(std::size_t index, const std::shared_ptrcodeset->program_id); + const std::string filepath = fmt::format("{}{:016X}.txt", cheat_dir, title_id); if (!FileUtil::IsDirectory(cheat_dir)) { FileUtil::CreateDir(cheat_dir); @@ -81,8 +85,7 @@ void CheatEngine::SaveCheatFile() const { void CheatEngine::LoadCheatFile() { const std::string cheat_dir = FileUtil::GetUserPath(FileUtil::UserPath::CheatsDir); - const std::string filepath = fmt::format( - "{}{:016X}.txt", cheat_dir, system.Kernel().GetCurrentProcess()->codeset->program_id); + const std::string filepath = fmt::format("{}{:016X}.txt", cheat_dir, title_id); if (!FileUtil::IsDirectory(cheat_dir)) { FileUtil::CreateDir(cheat_dir); diff --git a/src/core/cheats/cheats.h b/src/core/cheats/cheats.h index 9d339abb7e..f19212e601 100644 --- a/src/core/cheats/cheats.h +++ b/src/core/cheats/cheats.h @@ -24,7 +24,7 @@ class CheatBase; class CheatEngine { public: - explicit CheatEngine(Core::System& system); + explicit CheatEngine(u64 title_id_, Core::System& system); ~CheatEngine(); void Connect(); std::vector> GetCheats() const; @@ -40,5 +40,6 @@ private: mutable std::shared_mutex cheats_list_mutex; Core::TimingEventType* event; Core::System& system; + u64 title_id; }; } // namespace Cheats diff --git a/src/core/core.cpp b/src/core/core.cpp index b1dc1622f2..5de35b47c3 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -312,12 +312,12 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st } } kernel->SetCurrentProcess(process); - cheat_engine = std::make_unique(*this); title_id = 0; if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", static_cast(load_result)); } + cheat_engine = std::make_unique(title_id, *this); perf_stats = std::make_unique(title_id); if (Settings::values.custom_textures) {