From de688615ff2a22f9425523f5388c1f0147dcec83 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 12 Feb 2021 00:20:04 +1000 Subject: [PATCH] Qt: Add Clear and Reset buttons to cheat manager --- src/core/cheats.cpp | 10 ++- src/duckstation-qt/cheatmanagerdialog.cpp | 69 +++++++++++++++---- src/duckstation-qt/cheatmanagerdialog.h | 3 + src/duckstation-qt/cheatmanagerdialog.ui | 14 ++++ src/frontend-common/common_host_interface.cpp | 34 +++++++++ src/frontend-common/common_host_interface.h | 6 ++ 6 files changed, 119 insertions(+), 17 deletions(-) diff --git a/src/core/cheats.cpp b/src/core/cheats.cpp index 4e119ebf2..c82b41cf6 100644 --- a/src/core/cheats.cpp +++ b/src/core/cheats.cpp @@ -607,10 +607,16 @@ CheatList::Format CheatList::DetectFileFormat(const std::string& str) bool CheatList::LoadFromFile(const char* filename, Format format) { - std::optional str = FileSystem::ReadFileToString(filename); - if (!str.has_value() || str->empty()) + if (!FileSystem::FileExists(filename)) return false; + std::optional str = FileSystem::ReadFileToString(filename); + if (!str.has_value()) + return false; + + if (str->empty()) + return true; + return LoadFromString(str.value(), format); } diff --git a/src/duckstation-qt/cheatmanagerdialog.cpp b/src/duckstation-qt/cheatmanagerdialog.cpp index 77180c42d..1b0c57090 100644 --- a/src/duckstation-qt/cheatmanagerdialog.cpp +++ b/src/duckstation-qt/cheatmanagerdialog.cpp @@ -29,18 +29,20 @@ static QString formatHexValue(u32 value, u8 size) static QString formatHexAndDecValue(u32 value, u8 size, bool is_signed) { - + if (is_signed) - { - u32 value_raw = value; - if (size==2) - value_raw &= 0xFF; - else if (size==4) - value_raw &= 0xFFFF; - return QStringLiteral("0x%1 (%2)").arg(static_cast(value_raw), size, 16, QChar('0')).arg(static_cast(value)); + { + u32 value_raw = value; + if (size == 2) + value_raw &= 0xFF; + else if (size == 4) + value_raw &= 0xFFFF; + return QStringLiteral("0x%1 (%2)") + .arg(static_cast(value_raw), size, 16, QChar('0')) + .arg(static_cast(value)); } else - return QStringLiteral("0x%1 (%2)").arg(static_cast(value), size, 16, QChar('0')).arg(static_cast(value)); + return QStringLiteral("0x%1 (%2)").arg(static_cast(value), size, 16, QChar('0')).arg(static_cast(value)); } static QString formatValue(u32 value, bool is_signed) @@ -85,6 +87,8 @@ void CheatManagerDialog::connectUi() connect(m_ui.cheatListActivate, &QPushButton::clicked, this, &CheatManagerDialog::activateCodeClicked); connect(m_ui.cheatListImport, &QPushButton::clicked, this, &CheatManagerDialog::importClicked); connect(m_ui.cheatListExport, &QPushButton::clicked, this, &CheatManagerDialog::exportClicked); + connect(m_ui.cheatListClear, &QPushButton::clicked, this, &CheatManagerDialog::clearClicked); + connect(m_ui.cheatListReset, &QPushButton::clicked, this, &CheatManagerDialog::resetClicked); connect(m_ui.scanValue, &QLineEdit::textChanged, this, &CheatManagerDialog::updateScanValue); connect(m_ui.scanValueBase, QOverload::of(&QComboBox::currentIndexChanged), @@ -304,6 +308,11 @@ CheatList* CheatManagerDialog::getCheatList() const return list; } +void CheatManagerDialog::queueUpdateCheatList() +{ + QMetaObject::invokeMethod(this, &CheatManagerDialog::updateCheatList, Qt::QueuedConnection); +} + void CheatManagerDialog::updateCheatList() { QSignalBlocker sb(m_ui.cheatList); @@ -647,6 +656,36 @@ void CheatManagerDialog::exportClicked() QMessageBox::critical(this, tr("Error"), tr("Failed to save cheat file. The log may contain more information.")); } +void CheatManagerDialog::clearClicked() +{ + if (QMessageBox::question(this, tr("Confirm Clear"), + tr("Are you sure you want to remove all cheats? This is not reversible.")) != + QMessageBox::Yes) + { + return; + } + + QtHostInterface::GetInstance()->executeOnEmulationThread([] { QtHostInterface::GetInstance()->ClearCheatList(true); }, + true); + updateCheatList(); +} + +void CheatManagerDialog::resetClicked() +{ + if (QMessageBox::question( + this, tr("Confirm Reset"), + tr( + "Are you sure you want to reset the cheat list? Any cheats not in the DuckStation database WILL BE LOST.")) != + QMessageBox::Yes) + { + return; + } + + QtHostInterface::GetInstance()->executeOnEmulationThread([] { QtHostInterface::GetInstance()->DeleteCheatList(); }, + true); + updateCheatList(); +} + void CheatManagerDialog::addToWatchClicked() { const int index = getSelectedResultIndex(); @@ -675,11 +714,11 @@ void CheatManagerDialog::addManualWatchAddressClicked() if (index < 0 || !ok) return; - if (index==1 || index==4) - address.value() &= 0xFFFFFFFE; - else if (index==2 || index==5) - address.value() &= 0xFFFFFFFC; - + if (index == 1 || index == 4) + address.value() &= 0xFFFFFFFE; + else if (index == 2 || index == 5) + address.value() &= 0xFFFFFFFC; + m_watch.AddEntry(StringUtil::StdStringFromFormat("0x%08x", address.value()), address.value(), static_cast(index % 3), (index > 3), false); updateWatch(); @@ -858,7 +897,7 @@ void CheatManagerDialog::updateResultsValues() { QTableWidgetItem* item = m_ui.scanTable->item(row, 1); if (m_ui.scanValueBase->currentIndex() == 0) - item->setText(formatValue(res.value, m_scanner.GetValueSigned())); + item->setText(formatValue(res.value, m_scanner.GetValueSigned())); else if (m_scanner.GetSize() == MemoryAccessSize::Byte) item->setText(formatHexValue(res.value, 2)); else if (m_scanner.GetSize() == MemoryAccessSize::HalfWord) diff --git a/src/duckstation-qt/cheatmanagerdialog.h b/src/duckstation-qt/cheatmanagerdialog.h index 10b7d4d19..66dbee61f 100644 --- a/src/duckstation-qt/cheatmanagerdialog.h +++ b/src/duckstation-qt/cheatmanagerdialog.h @@ -40,6 +40,8 @@ private Q_SLOTS: void importFromFileTriggered(); void importFromTextTriggered(); void exportClicked(); + void clearClicked(); + void resetClicked(); void addToWatchClicked(); void addManualWatchAddressClicked(); @@ -73,6 +75,7 @@ private: int getSelectedCheatIndex() const; int getSelectedResultIndex() const; int getSelectedWatchIndex() const; + void queueUpdateCheatList(); Ui::CheatManagerDialog m_ui; diff --git a/src/duckstation-qt/cheatmanagerdialog.ui b/src/duckstation-qt/cheatmanagerdialog.ui index 79c537aa5..4523da306 100644 --- a/src/duckstation-qt/cheatmanagerdialog.ui +++ b/src/duckstation-qt/cheatmanagerdialog.ui @@ -84,6 +84,20 @@ + + + + Clear + + + + + + + Reset + + + diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index 0fbbcd1b9..caaa03dd5 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -2722,6 +2722,40 @@ bool CommonHostInterface::SaveCheatList(const char* filename) return true; } +bool CommonHostInterface::DeleteCheatList() +{ + if (!System::IsValid()) + return false; + + const std::string filename(GetCheatFileName()); + if (!filename.empty()) + { + if (!FileSystem::DeleteFile(filename.c_str())) + return false; + + AddFormattedOSDMessage(5.0f, TranslateString("OSDMessage", "Deleted cheat list '%s'."), filename.c_str()); + } + + System::SetCheatList(nullptr); + return true; +} + +void CommonHostInterface::ClearCheatList(bool save_to_file) +{ + if (!System::IsValid()) + return; + + CheatList* cl = System::GetCheatList(); + if (!cl) + return; + + while (cl->GetCodeCount() > 0) + cl->RemoveCode(cl->GetCodeCount() - 1); + + if (save_to_file) + SaveCheatList(); +} + void CommonHostInterface::SetCheatCodeState(u32 index, bool enabled, bool save_to_file) { if (!System::IsValid() || !System::HasCheatList()) diff --git a/src/frontend-common/common_host_interface.h b/src/frontend-common/common_host_interface.h index dce2e05ac..6748aa567 100644 --- a/src/frontend-common/common_host_interface.h +++ b/src/frontend-common/common_host_interface.h @@ -220,6 +220,12 @@ public: /// Saves the current cheat list to the specified file. bool SaveCheatList(const char* filename); + /// Deletes the cheat list, if present. + bool DeleteCheatList(); + + /// Removes all cheats from the cheat list. + void ClearCheatList(bool save_to_file); + /// Enables/disabled the specified cheat code. void SetCheatCodeState(u32 index, bool enabled, bool save_to_file);