Qt: Add Edit Cheats/Patches to Tools menu

Closes #4634.
This commit is contained in:
Stenzek 2023-09-09 14:47:26 +10:00 committed by Connor McLaughlin
parent b601c49f6c
commit 388e488bc1
5 changed files with 77 additions and 27 deletions

View File

@ -148,7 +148,7 @@ void MainWindow::initialize()
restoreStateFromConfig();
switchToGameListView();
updateWindowTitle();
updateSaveStateMenusEnableState(false);
updateGameDependentActions();
#ifdef _WIN32
registerForDeviceNotifications();
@ -389,6 +389,8 @@ void MainWindow::connectSignals()
connect(m_ui.actionShowAdvancedSettings, &QAction::toggled, this, &MainWindow::onShowAdvancedSettingsToggled);
connect(m_ui.actionSaveGSDump, &QAction::triggered, this, &MainWindow::onSaveGSDumpActionTriggered);
connect(m_ui.actionToolsVideoCapture, &QAction::toggled, this, &MainWindow::onToolsVideoCaptureToggled);
connect(m_ui.actionEditPatches, &QAction::triggered, this, [this]() { onToolsEditCheatsPatchesTriggered(false); });
connect(m_ui.actionEditCheats, &QAction::triggered, this, [this]() { onToolsEditCheatsPatchesTriggered(true); });
// Input Recording
connect(m_ui.actionInputRecNew, &QAction::triggered, this, &MainWindow::onInputRecNewActionTriggered);
@ -1278,14 +1280,12 @@ void MainWindow::onChangeDiscMenuAboutToHide()
void MainWindow::onLoadStateMenuAboutToShow()
{
m_ui.menuLoadState->clear();
updateSaveStateMenusEnableState(!m_current_disc_serial.isEmpty());
populateLoadStateMenu(m_ui.menuLoadState, m_current_disc_path, m_current_disc_serial, m_current_disc_crc);
}
void MainWindow::onSaveStateMenuAboutToShow()
{
m_ui.menuSaveState->clear();
updateSaveStateMenusEnableState(!m_current_disc_serial.isEmpty());
populateSaveStateMenu(m_ui.menuSaveState, m_current_disc_serial, m_current_disc_crc);
}
@ -1475,6 +1475,32 @@ void MainWindow::onToolsCoverDownloaderTriggered()
dlg.exec();
}
void MainWindow::onToolsEditCheatsPatchesTriggered(bool cheats)
{
if (m_current_disc_serial.isEmpty() || m_current_running_crc == 0)
return;
const std::string path = Patch::GetPnachFilename(m_current_disc_serial.toStdString(), m_current_running_crc, cheats);
if (!FileSystem::FileExists(path.c_str()))
{
if (QMessageBox::question(this, tr("Confirm File Creation"),
tr("The pnach file '%1' does not currently exist. Do you want to create it?")
.arg(QtUtils::StringViewToQString(Path::GetFileName(path))),
QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
{
return;
}
if (!FileSystem::WriteStringToFile(path.c_str(), std::string_view()))
{
QMessageBox::critical(this, tr("Error"), tr("Failed to create '%1'.").arg(QString::fromStdString(path)));
return;
}
}
QtUtils::OpenURL(this, QUrl::fromLocalFile(QString::fromStdString(path)));
}
void MainWindow::updateTheme()
{
QtHost::UpdateApplicationTheme();
@ -1616,15 +1642,11 @@ void MainWindow::onInputRecOpenViewer()
}
}
void MainWindow::onVMStarting()
{
s_vm_valid = true;
updateEmulationActions(true, false, false);
updateWindowTitle();
// prevent loading state until we're fully initialized
updateSaveStateMenusEnableState(false);
}
void MainWindow::onVMStarted()
@ -1632,6 +1654,7 @@ void MainWindow::onVMStarted()
s_vm_valid = true;
m_was_disc_change_request = false;
updateEmulationActions(true, true, false);
updateGameDependentActions();
updateWindowTitle();
updateStatusBarWidgetVisibility();
updateInputRecordingActions(true);
@ -1689,6 +1712,7 @@ void MainWindow::onVMStopped()
s_vm_paused = false;
m_last_fps_status = QString();
updateEmulationActions(false, false, false);
updateGameDependentActions();
updateWindowTitle();
updateWindowState();
updateStatusBarWidgetVisibility();
@ -1722,7 +1746,7 @@ void MainWindow::onGameChanged(const QString& title, const QString& elf_override
m_current_disc_crc = disc_crc;
m_current_running_crc = crc;
updateWindowTitle();
updateSaveStateMenusEnableState(!serial.isEmpty());
updateGameDependentActions();
}
void MainWindow::showEvent(QShowEvent* event)
@ -2544,14 +2568,18 @@ void MainWindow::populateSaveStateMenu(QMenu* menu, const QString& serial, quint
}
}
void MainWindow::updateSaveStateMenusEnableState(bool enable)
void MainWindow::updateGameDependentActions()
{
const bool load_enabled = enable;
const bool save_enabled = enable && s_vm_valid;
m_ui.menuLoadState->setEnabled(load_enabled);
m_ui.actionToolbarLoadState->setEnabled(load_enabled);
m_ui.menuSaveState->setEnabled(save_enabled);
m_ui.actionToolbarSaveState->setEnabled(save_enabled);
const bool valid_serial_and_crc = (s_vm_valid && !m_current_disc_serial.isEmpty() && m_current_disc_crc != 0);
m_ui.menuLoadState->setEnabled(valid_serial_and_crc);
m_ui.actionToolbarLoadState->setEnabled(valid_serial_and_crc);
m_ui.menuSaveState->setEnabled(valid_serial_and_crc);
m_ui.actionToolbarSaveState->setEnabled(valid_serial_and_crc);
const bool can_use_pnach = (s_vm_valid && !m_current_disc_serial.isEmpty() && m_current_running_crc != 0);
m_ui.actionEditCheats->setEnabled(can_use_pnach);
m_ui.actionEditPatches->setEnabled(can_use_pnach);
m_ui.actionReloadPatches->setEnabled(s_vm_valid);
}
void MainWindow::doStartFile(std::optional<CDVD_SourceType> source, const QString& path)

View File

@ -165,6 +165,7 @@ private Q_SLOTS:
void onAboutActionTriggered();
void onToolsOpenDataDirectoryTriggered();
void onToolsCoverDownloaderTriggered();
void onToolsEditCheatsPatchesTriggered(bool cheats);
void updateTheme();
void updateLanguage();
void onScreenshotActionTriggered();
@ -222,6 +223,7 @@ private:
void updateEmulationActions(bool starting, bool running, bool stopping);
void updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen);
void updateGameDependentActions();
void updateStatusBarWidgetVisibility();
void updateWindowTitle();
void updateWindowState(bool force_visible = false);
@ -267,7 +269,6 @@ private:
void loadSaveStateFile(const QString& filename, const QString& state_filename);
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
void updateSaveStateMenusEnableState(bool enable);
void doStartFile(std::optional<CDVD_SourceType> source, const QString& path);
void doDiscChange(CDVD_SourceType source, const QString& path);

View File

@ -186,7 +186,7 @@
</property>
<property name="icon">
<iconset theme="keyboard-line">
<normaloff>.</normaloff>.</iconset>
<normaloff>.</normaloff>.</iconset>
</property>
<addaction name="actionInputRecNew"/>
<addaction name="actionInputRecPlay"/>
@ -201,8 +201,11 @@
<addaction name="actionOpenDataDirectory"/>
<addaction name="actionCoverDownloader"/>
<addaction name="separator"/>
<addaction name="actionToggleSoftwareRendering"/>
<addaction name="actionEditCheats"/>
<addaction name="actionEditPatches"/>
<addaction name="actionReloadPatches"/>
<addaction name="separator"/>
<addaction name="actionToggleSoftwareRendering"/>
<addaction name="menuInput_Recording"/>
<addaction name="actionToolsVideoCapture"/>
<addaction name="separator"/>
@ -864,13 +867,13 @@
</property>
</action>
<action name="actionToggleSoftwareRendering">
<property name="text">
<string>Toggle Software Rendering</string>
</property>
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Toggle Software Rendering</string>
</property>
</action>
<action name="actionDebugger">
<property name="icon">
@ -882,13 +885,13 @@
</property>
</action>
<action name="actionReloadPatches">
<property name="text">
<string>Reload Cheats/Patches</string>
</property>
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Reload Cheats/Patches</string>
</property>
</action>
<action name="actionEnableSystemConsole">
<property name="checkable">
@ -923,13 +926,13 @@
</property>
</action>
<action name="actionSaveGSDump">
<property name="text">
<string>Save Single Frame GS Dump</string>
</property>
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Save Single Frame GS Dump</string>
</property>
</action>
<action name="actionInputRecNew">
<property name="enabled">
@ -1064,6 +1067,16 @@
<string>Video Capture</string>
</property>
</action>
<action name="actionEditCheats">
<property name="text">
<string>Edit Cheats...</string>
</property>
</action>
<action name="actionEditPatches">
<property name="text">
<string>Edit Patches...</string>
</property>
</action>
</widget>
<resources>
<include location="resources/resources.qrc"/>

View File

@ -471,6 +471,11 @@ Patch::PatchInfoList Patch::GetPatchInfo(const std::string_view& serial, u32 crc
return ret;
}
std::string Patch::GetPnachFilename(const std::string_view& serial, u32 crc, bool cheats)
{
return Path::Combine(cheats ? EmuFolders::Cheats : EmuFolders::Patches, GetPnachTemplate(serial, crc, true, false, false));
}
void Patch::ReloadEnabledLists()
{
if (EmuConfig.EnableCheats && !Achievements::ChallengeModeActive())

View File

@ -95,6 +95,9 @@ namespace Patch
extern PatchInfoList GetPatchInfo(const std::string_view& serial, u32 crc, bool cheats, u32* num_unlabelled_patches);
/// Returns the path to a new cheat/patch pnach for the specified serial and CRC.
extern std::string GetPnachFilename(const std::string_view& serial, u32 crc, bool cheats);
/// Reloads cheats/patches. If verbose is set, the number of patches loaded will be shown in the OSD.
extern void ReloadPatches(const std::string& serial, u32 crc, bool reload_files, bool reload_enabled_list, bool verbose, bool verbose_if_changed);