From cb2fa9a1f2873edf2704729cfcef4c317206acbd Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Wed, 7 Jun 2023 21:54:49 -0400 Subject: [PATCH] Disable Debug Mode in hardcore mode Debug Mode gives players direct read and write access to memory, which could be used to completely manipulate RetroAchievements logic and therefore is not allowed in hardcore mode. --- Source/Core/Core/Config/MainSettings.cpp | 11 ++++++++++ Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/Core/HLE/HLE.cpp | 2 +- .../Core/PowerPC/Interpreter/Interpreter.cpp | 2 +- Source/Core/Core/PowerPC/Jit64/JitAsm.cpp | 2 +- Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp | 2 +- Source/Core/DolphinQt/Debugger/JITWidget.cpp | 2 +- Source/Core/DolphinQt/HotkeyScheduler.cpp | 2 +- Source/Core/DolphinQt/Settings.cpp | 5 +++++ .../Core/DolphinQt/Settings/InterfacePane.cpp | 22 ++++++++++++++++++- .../Core/DolphinQt/Settings/InterfacePane.h | 4 +++- 11 files changed, 47 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 4a7470ada8..7ee58576f0 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -738,4 +738,15 @@ bool IsDefaultGCIFolderPathConfigured(ExpansionInterface::Slot slot) { return Config::Get(GetInfoForGCIPath(slot)).empty(); } + +bool IsDebuggingEnabled() +{ +#ifdef USE_RETRO_ACHIEVEMENTS + return Config::Get(::Config::MAIN_ENABLE_DEBUGGING) && + !::Config::Get(::Config::RA_HARDCORE_ENABLED); +#else // USE_RETRO_ACHIEVEMENTS + return Config::Get(::Config::MAIN_ENABLE_DEBUGGING); +#endif // USE_RETRO_ACHIEVEMENTS +} + } // namespace Config diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index b591a00de4..c3e2667a96 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -378,4 +378,5 @@ std::string GetGCIFolderPath(ExpansionInterface::Slot slot, std::optional region); bool IsDefaultGCIFolderPathConfigured(ExpansionInterface::Slot slot); +bool IsDebuggingEnabled(); } // namespace Config diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp index 2d4f3313f2..6291fd01c9 100644 --- a/Source/Core/Core/HLE/HLE.cpp +++ b/Source/Core/Core/HLE/HLE.cpp @@ -219,7 +219,7 @@ TryReplaceFunctionResult TryReplaceFunction(u32 address) bool IsEnabled(HookFlag flag) { - return flag != HLE::HookFlag::Debug || Config::Get(Config::MAIN_ENABLE_DEBUGGING) || + return flag != HLE::HookFlag::Debug || Config::IsDebuggingEnabled() || Core::System::GetInstance().GetPowerPC().GetMode() == PowerPC::CoreMode::Interpreter; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index f3d3619f1b..6b475e1204 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -236,7 +236,7 @@ void Interpreter::Run() core_timing.Advance(); // we have to check exceptions at branches apparently (or maybe just rfi?) - if (Config::Get(Config::MAIN_ENABLE_DEBUGGING)) + if (Config::IsDebuggingEnabled()) { #ifdef SHOW_HISTORY s_pc_block_vec.push_back(m_ppc_state.pc); diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index f77afc563c..a5d89cd315 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -44,7 +44,7 @@ void Jit64AsmRoutineManager::Regenerate() void Jit64AsmRoutineManager::Generate() { - const bool enable_debugging = Config::Get(Config::MAIN_ENABLE_DEBUGGING); + const bool enable_debugging = Config::IsDebuggingEnabled(); enter_code = AlignCode16(); // We need to own the beginning of RSP, so we do an extra stack adjustment diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index cc3f7cc298..350edc2ba4 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -30,7 +30,7 @@ void JitArm64::GenerateAsm() { const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes; - const bool enable_debugging = Config::Get(Config::MAIN_ENABLE_DEBUGGING); + const bool enable_debugging = Config::IsDebuggingEnabled(); // This value is all of the callee saved registers that we are required to save. // According to the AACPS64 we need to save R19 ~ R30 and Q8 ~ Q15. diff --git a/Source/Core/DolphinQt/Debugger/JITWidget.cpp b/Source/Core/DolphinQt/Debugger/JITWidget.cpp index 771f72473c..6148528891 100644 --- a/Source/Core/DolphinQt/Debugger/JITWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/JITWidget.cpp @@ -160,7 +160,7 @@ void JITWidget::Update() PPCAnalyst::BlockRegStats fpa; PPCAnalyst::CodeBlock code_block; PPCAnalyst::PPCAnalyzer analyzer; - analyzer.SetDebuggingEnabled(Config::Get(Config::MAIN_ENABLE_DEBUGGING)); + analyzer.SetDebuggingEnabled(Config::IsDebuggingEnabled()); analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH)); analyzer.SetFloatExceptionsEnabled(Config::Get(Config::MAIN_FLOAT_EXCEPTIONS)); analyzer.SetDivByZeroExceptionsEnabled(Config::Get(Config::MAIN_DIVIDE_BY_ZERO_EXCEPTIONS)); diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 05b38a367f..b527e96c6c 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -257,7 +257,7 @@ void HotkeyScheduler::Run() if (auto bt = WiiUtils::GetBluetoothRealDevice()) bt->UpdateSyncButtonState(IsHotkey(HK_TRIGGER_SYNC_BUTTON, true)); - if (Config::Get(Config::MAIN_ENABLE_DEBUGGING)) + if (Config::IsDebuggingEnabled()) { CheckDebuggingHotkeys(); } diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index 2e21835b6f..e3bb288c7b 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -33,6 +33,7 @@ #include "Common/FileUtil.h" #include "Common/StringUtil.h" +#include "Core/Config/AchievementSettings.h" #include "Core/Config/GraphicsSettings.h" #include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" @@ -563,6 +564,10 @@ void Settings::SetCheatsEnabled(bool enabled) void Settings::SetDebugModeEnabled(bool enabled) { +#ifdef USE_RETRO_ACHIEVEMENTS + if (Config::Get(Config::RA_HARDCORE_ENABLED)) + enabled = false; +#endif // USE_RETRO_ACHIEVEMENTS if (IsDebugModeEnabled() != enabled) { Config::SetBaseOrCurrent(Config::MAIN_ENABLE_DEBUGGING, enabled); diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.cpp b/Source/Core/DolphinQt/Settings/InterfacePane.cpp index 81a0453c7e..39c11733c0 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.cpp +++ b/Source/Core/DolphinQt/Settings/InterfacePane.cpp @@ -19,9 +19,11 @@ #include "Common/MsgHandler.h" #include "Common/StringUtil.h" +#include "Core/Config/AchievementSettings.h" #include "Core/Config/MainSettings.h" #include "Core/Config/UISettings.h" +#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" @@ -84,6 +86,9 @@ InterfacePane::InterfacePane(QWidget* parent) : QWidget(parent) CreateLayout(); LoadConfig(); ConnectLayout(); + + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + &InterfacePane::LoadConfig); } void InterfacePane::CreateLayout() @@ -151,7 +156,7 @@ void InterfacePane::CreateUI() m_checkbox_use_builtin_title_database = new QCheckBox(tr("Use Built-In Database of Game Names")); m_checkbox_use_covers = new QCheckBox(tr("Download Game Covers from GameTDB.com for Use in Grid Mode")); - m_checkbox_show_debugging_ui = new QCheckBox(tr("Enable Debugging UI")); + m_checkbox_show_debugging_ui = new ToolTipCheckBox(tr("Enable Debugging UI")); m_checkbox_focused_hotkeys = new QCheckBox(tr("Hotkeys Require Window Focus")); m_checkbox_disable_screensaver = new QCheckBox(tr("Inhibit Screensaver During Emulation")); @@ -249,6 +254,21 @@ void InterfacePane::LoadConfig() ->setChecked(Config::Get(Config::MAIN_USE_BUILT_IN_TITLE_DATABASE)); SignalBlocking(m_checkbox_show_debugging_ui) ->setChecked(Settings::Instance().IsDebugModeEnabled()); + +#ifdef USE_RETRO_ACHIEVEMENTS + bool hardcore = Config::Get(Config::RA_HARDCORE_ENABLED); + SignalBlocking(m_checkbox_show_debugging_ui)->setEnabled(!hardcore); + if (hardcore) + { + m_checkbox_show_debugging_ui->SetDescription( + tr("Disabled in Hardcore Mode.")); + } + else + { + m_checkbox_show_debugging_ui->SetDescription({}); + } +#endif // USE_RETRO_ACHIEVEMENTS + SignalBlocking(m_combobox_language) ->setCurrentIndex(m_combobox_language->findData( QString::fromStdString(Config::Get(Config::MAIN_INTERFACE_LANGUAGE)))); diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.h b/Source/Core/DolphinQt/Settings/InterfacePane.h index ffa09c3f72..22c1a2b4f3 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.h +++ b/Source/Core/DolphinQt/Settings/InterfacePane.h @@ -10,6 +10,7 @@ class QComboBox; class QLabel; class QRadioButton; class QVBoxLayout; +class ToolTipCheckBox; class InterfacePane final : public QWidget { @@ -36,7 +37,8 @@ private: QLabel* m_label_userstyle; QCheckBox* m_checkbox_top_window; QCheckBox* m_checkbox_use_builtin_title_database; - QCheckBox* m_checkbox_show_debugging_ui; + QCheckBox* m_checkbox_use_userstyle; + ToolTipCheckBox* m_checkbox_show_debugging_ui; QCheckBox* m_checkbox_focused_hotkeys; QCheckBox* m_checkbox_use_covers; QCheckBox* m_checkbox_disable_screensaver;