mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Add CheatEngine and support for Gateway cheats (#4406)
* Add CheatEngine; Add support for Gateway cheats; Add Cheat UI * fix a potential crash on some systems * fix substr with negative length * Add Joker to the NonOp comp handling * Fixup JokerOp * minor fixup in patchop; add todo for nested loops * Add comment for PadState member variable in HID * fix: stol to stoul in parsing cheat file * fix misplaced parsing of values; fix patchop code * add missing break * Make read_func and write_func a template parameter
This commit is contained in:
		
							parent
							
								
									560df843b1
								
							
						
					
					
						commit
						b90ff739a0
					
				
					 23 changed files with 1052 additions and 1 deletions
				
			
		|  | @ -24,6 +24,8 @@ add_executable(citra-qt | |||
|     camera/qt_camera_base.h | ||||
|     camera/qt_multimedia_camera.cpp | ||||
|     camera/qt_multimedia_camera.h | ||||
|     cheats.cpp | ||||
|     cheats.h | ||||
|     citra-qt.rc | ||||
|     configuration/config.cpp | ||||
|     configuration/config.h | ||||
|  | @ -134,6 +136,7 @@ set(UIS | |||
|     multiplayer/client_room.ui | ||||
|     multiplayer/host_room.ui | ||||
|     aboutdialog.ui | ||||
|     cheats.ui | ||||
|     hotkeys.ui | ||||
|     main.ui | ||||
|     compatdb.ui | ||||
|  |  | |||
							
								
								
									
										75
									
								
								src/citra_qt/cheats.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/citra_qt/cheats.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <QCheckBox> | ||||
| #include <QTableWidgetItem> | ||||
| #include "citra_qt/cheats.h" | ||||
| #include "core/cheats/cheat_base.h" | ||||
| #include "core/cheats/cheats.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "ui_cheats.h" | ||||
| 
 | ||||
| CheatDialog::CheatDialog(QWidget* parent) | ||||
|     : QDialog(parent), ui(std::make_unique<Ui::CheatDialog>()) { | ||||
|     // Setup gui control settings
 | ||||
|     ui->setupUi(this); | ||||
|     setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); | ||||
|     ui->tableCheats->setColumnWidth(0, 30); | ||||
|     ui->tableCheats->setColumnWidth(2, 85); | ||||
|     ui->tableCheats->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); | ||||
|     ui->tableCheats->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); | ||||
|     ui->tableCheats->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed); | ||||
|     ui->textDetails->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::released, this, &CheatDialog::OnCancel); | ||||
|     connect(ui->tableCheats, &QTableWidget::cellClicked, this, &CheatDialog::OnRowSelected); | ||||
| 
 | ||||
|     LoadCheats(); | ||||
| } | ||||
| 
 | ||||
| CheatDialog::~CheatDialog() = default; | ||||
| 
 | ||||
| void CheatDialog::LoadCheats() { | ||||
|     const auto& cheats = Core::System::GetInstance().CheatEngine().GetCheats(); | ||||
| 
 | ||||
|     ui->tableCheats->setRowCount(cheats.size()); | ||||
| 
 | ||||
|     for (size_t i = 0; i < cheats.size(); i++) { | ||||
|         QCheckBox* enabled = new QCheckBox(); | ||||
|         enabled->setChecked(cheats[i]->IsEnabled()); | ||||
|         enabled->setStyleSheet("margin-left:7px;"); | ||||
|         ui->tableCheats->setItem(i, 0, new QTableWidgetItem()); | ||||
|         ui->tableCheats->setCellWidget(i, 0, enabled); | ||||
|         ui->tableCheats->setItem( | ||||
|             i, 1, new QTableWidgetItem(QString::fromStdString(cheats[i]->GetName()))); | ||||
|         ui->tableCheats->setItem( | ||||
|             i, 2, new QTableWidgetItem(QString::fromStdString(cheats[i]->GetType()))); | ||||
|         enabled->setProperty("row", static_cast<int>(i)); | ||||
| 
 | ||||
|         connect(enabled, &QCheckBox::stateChanged, this, &CheatDialog::OnCheckChanged); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void CheatDialog::OnCancel() { | ||||
|     close(); | ||||
| } | ||||
| 
 | ||||
| void CheatDialog::OnRowSelected(int row, int column) { | ||||
|     ui->textDetails->setEnabled(true); | ||||
|     ui->textNotes->setEnabled(true); | ||||
|     const auto& current_cheat = Core::System::GetInstance().CheatEngine().GetCheats()[row]; | ||||
|     ui->textNotes->setPlainText(QString::fromStdString(current_cheat->GetComments())); | ||||
|     ui->textDetails->setPlainText(QString::fromStdString(current_cheat->ToString())); | ||||
| } | ||||
| 
 | ||||
| void CheatDialog::OnCheckChanged(int state) { | ||||
|     const QCheckBox* checkbox = qobject_cast<QCheckBox*>(sender()); | ||||
|     int row = static_cast<int>(checkbox->property("row").toInt()); | ||||
|     Core::System::GetInstance().CheatEngine().GetCheats()[row]->SetEnabled(state); | ||||
| } | ||||
							
								
								
									
										30
									
								
								src/citra_qt/cheats.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/citra_qt/cheats.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <QDialog> | ||||
| 
 | ||||
| namespace Ui { | ||||
| class CheatDialog; | ||||
| } // namespace Ui
 | ||||
| 
 | ||||
| class CheatDialog : public QDialog { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     explicit CheatDialog(QWidget* parent = nullptr); | ||||
|     ~CheatDialog(); | ||||
| 
 | ||||
| private: | ||||
|     std::unique_ptr<Ui::CheatDialog> ui; | ||||
| 
 | ||||
|     void LoadCheats(); | ||||
| 
 | ||||
| private slots: | ||||
|     void OnCancel(); | ||||
|     void OnRowSelected(int row, int column); | ||||
|     void OnCheckChanged(int state); | ||||
| }; | ||||
							
								
								
									
										204
									
								
								src/citra_qt/cheats.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								src/citra_qt/cheats.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,204 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>CheatDialog</class> | ||||
|  <widget class="QDialog" name="CheatDialog"> | ||||
|   <property name="windowModality"> | ||||
|    <enum>Qt::ApplicationModal</enum> | ||||
|   </property> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>862</width> | ||||
|     <height>612</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="sizePolicy"> | ||||
|    <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> | ||||
|     <horstretch>0</horstretch> | ||||
|     <verstretch>0</verstretch> | ||||
|    </sizepolicy> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Cheats</string> | ||||
|   </property> | ||||
|   <widget class="QLabel" name="labelTitle"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>10</x> | ||||
|      <y>10</y> | ||||
|      <width>300</width> | ||||
|      <height>31</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="font"> | ||||
|     <font> | ||||
|      <pointsize>10</pointsize> | ||||
|     </font> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Title ID:</string> | ||||
|    </property> | ||||
|   </widget> | ||||
|   <widget class="QWidget" name="horizontalLayoutWidget"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>10</x> | ||||
|      <y>570</y> | ||||
|      <width>841</width> | ||||
|      <height>41</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|     <item> | ||||
|      <spacer name="horizontalSpacer"> | ||||
|       <property name="orientation"> | ||||
|        <enum>Qt::Horizontal</enum> | ||||
|       </property> | ||||
|       <property name="sizeHint" stdset="0"> | ||||
|        <size> | ||||
|         <width>40</width> | ||||
|         <height>20</height> | ||||
|        </size> | ||||
|       </property> | ||||
|      </spacer> | ||||
|     </item> | ||||
|     <item> | ||||
|      <widget class="QPushButton" name="buttonClose"> | ||||
|       <property name="text"> | ||||
|        <string>Close</string> | ||||
|       </property> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|   <widget class="QWidget" name="verticalLayoutWidget"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>10</x> | ||||
|      <y>80</y> | ||||
|      <width>551</width> | ||||
|      <height>471</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|     <item> | ||||
|      <widget class="QTableWidget" name="tableCheats"> | ||||
|       <property name="editTriggers"> | ||||
|        <set>QAbstractItemView::NoEditTriggers</set> | ||||
|       </property> | ||||
|       <property name="selectionBehavior"> | ||||
|        <enum>QAbstractItemView::SelectRows</enum> | ||||
|       </property> | ||||
|       <property name="showGrid"> | ||||
|        <bool>false</bool> | ||||
|       </property> | ||||
|       <property name="columnCount"> | ||||
|        <number>3</number> | ||||
|       </property> | ||||
|       <attribute name="horizontalHeaderVisible"> | ||||
|        <bool>true</bool> | ||||
|       </attribute> | ||||
|       <attribute name="verticalHeaderVisible"> | ||||
|        <bool>false</bool> | ||||
|       </attribute> | ||||
|       <column> | ||||
|        <property name="text"> | ||||
|         <string/> | ||||
|        </property> | ||||
|       </column> | ||||
|       <column> | ||||
|        <property name="text"> | ||||
|         <string>Name</string> | ||||
|        </property> | ||||
|       </column> | ||||
|       <column> | ||||
|        <property name="text"> | ||||
|         <string>Type</string> | ||||
|        </property> | ||||
|       </column> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|   <widget class="QLabel" name="labelAvailableCheats"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>10</x> | ||||
|      <y>60</y> | ||||
|      <width>121</width> | ||||
|      <height>16</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Available Cheats:</string> | ||||
|    </property> | ||||
|   </widget> | ||||
|   <widget class="QWidget" name="verticalLayoutWidget_2"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>580</x> | ||||
|      <y>440</y> | ||||
|      <width>271</width> | ||||
|      <height>111</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|     <item> | ||||
|      <widget class="QPlainTextEdit" name="textNotes"> | ||||
|       <property name="readOnly"> | ||||
|        <bool>true</bool> | ||||
|       </property> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|   <widget class="QLabel" name="labelNotes"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>580</x> | ||||
|      <y>420</y> | ||||
|      <width>111</width> | ||||
|      <height>16</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Notes:</string> | ||||
|    </property> | ||||
|   </widget> | ||||
|   <widget class="QWidget" name="verticalLayoutWidget_3"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>580</x> | ||||
|      <y>80</y> | ||||
|      <width>271</width> | ||||
|      <height>311</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|     <item> | ||||
|      <widget class="QPlainTextEdit" name="textDetails"> | ||||
|       <property name="readOnly"> | ||||
|        <bool>true</bool> | ||||
|       </property> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|   <widget class="QLabel" name="labelDetails"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>580</x> | ||||
|      <y>60</y> | ||||
|      <width>55</width> | ||||
|      <height>16</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Code:</string> | ||||
|    </property> | ||||
|   </widget> | ||||
|  </widget> | ||||
|  <resources/> | ||||
|  <connections/> | ||||
| </ui> | ||||
|  | @ -20,6 +20,7 @@ | |||
| #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" | ||||
|  | @ -467,6 +468,7 @@ void GMainWindow::RestoreUIState() { | |||
|     microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry); | ||||
|     microProfileDialog->setVisible(UISettings::values.microprofile_visible); | ||||
| #endif | ||||
|     ui.action_Cheats->setEnabled(false); | ||||
| 
 | ||||
|     game_list->LoadInterfaceLayout(); | ||||
| 
 | ||||
|  | @ -527,6 +529,7 @@ void GMainWindow::ConnectMenuEvents() { | |||
|     connect(ui.action_Report_Compatibility, &QAction::triggered, this, | ||||
|             &GMainWindow::OnMenuReportCompatibility); | ||||
|     connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); | ||||
|     connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); | ||||
| 
 | ||||
|     // View
 | ||||
|     connect(ui.action_Single_Window_Mode, &QAction::triggered, this, | ||||
|  | @ -870,6 +873,7 @@ void GMainWindow::ShutdownGame() { | |||
|     ui.action_Pause->setEnabled(false); | ||||
|     ui.action_Stop->setEnabled(false); | ||||
|     ui.action_Restart->setEnabled(false); | ||||
|     ui.action_Cheats->setEnabled(false); | ||||
|     ui.action_Load_Amiibo->setEnabled(false); | ||||
|     ui.action_Remove_Amiibo->setEnabled(false); | ||||
|     ui.action_Report_Compatibility->setEnabled(false); | ||||
|  | @ -1159,6 +1163,7 @@ void GMainWindow::OnStartGame() { | |||
|     ui.action_Pause->setEnabled(true); | ||||
|     ui.action_Stop->setEnabled(true); | ||||
|     ui.action_Restart->setEnabled(true); | ||||
|     ui.action_Cheats->setEnabled(true); | ||||
|     ui.action_Load_Amiibo->setEnabled(true); | ||||
|     ui.action_Report_Compatibility->setEnabled(true); | ||||
|     ui.action_Enable_Frame_Advancing->setEnabled(true); | ||||
|  | @ -1294,6 +1299,11 @@ void GMainWindow::OnSwapScreens() { | |||
|     Settings::Apply(); | ||||
| } | ||||
| 
 | ||||
| void GMainWindow::OnCheats() { | ||||
|     CheatDialog cheat_dialog(this); | ||||
|     cheat_dialog.exec(); | ||||
| } | ||||
| 
 | ||||
| void GMainWindow::OnConfigure() { | ||||
|     ConfigureDialog configureDialog(this, hotkey_registry); | ||||
|     connect(&configureDialog, &ConfigureDialog::languageChanged, this, | ||||
|  |  | |||
|  | @ -174,6 +174,7 @@ private slots: | |||
|     void ChangeScreenLayout(); | ||||
|     void ToggleScreenLayout(); | ||||
|     void OnSwapScreens(); | ||||
|     void OnCheats(); | ||||
|     void ShowFullscreen(); | ||||
|     void HideFullscreen(); | ||||
|     void ToggleWindowMode(); | ||||
|  |  | |||
|  | @ -85,6 +85,7 @@ | |||
|     <addaction name="action_Report_Compatibility"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="action_Configure"/> | ||||
|     <addaction name="action_Cheats"/> | ||||
|    </widget> | ||||
|    <widget class="QMenu" name="menu_View"> | ||||
|     <property name="title"> | ||||
|  | @ -227,6 +228,11 @@ | |||
|     <string>Configure...</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Cheats"> | ||||
|    <property name="text"> | ||||
|     <string>Cheats...</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Display_Dock_Widget_Headers"> | ||||
|    <property name="checkable"> | ||||
|     <bool>true</bool> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue