Merge pull request #11904 from LillyJadeKatrin/retroachievements-hardcore-v2

RetroAchievements - Hardcore Mode (V2)
This commit is contained in:
Mai 2023-12-05 01:31:54 -05:00 committed by GitHub
commit 6e6695c24b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 582 additions and 48 deletions

View file

@ -633,6 +633,18 @@ std::recursive_mutex* AchievementManager::GetLock()
return &m_lock;
}
bool AchievementManager::IsHardcoreModeActive() const
{
std::lock_guard lg{m_lock};
if (!Config::Get(Config::RA_HARDCORE_ENABLED))
return false;
if (!Core::IsRunning())
return true;
if (!IsGameLoaded())
return false;
return (m_runtime.trigger_count + m_runtime.lboard_count > 0);
}
std::string AchievementManager::GetPlayerDisplayName() const
{
return IsLoggedIn() ? m_display_name : "";

View file

@ -119,6 +119,7 @@ public:
void AchievementEventHandler(const rc_runtime_event_t* runtime_event);
std::recursive_mutex* GetLock();
bool IsHardcoreModeActive() const;
std::string GetPlayerDisplayName() const;
u32 GetPlayerScore() const;
const BadgeStatus& GetPlayerBadge() const;
@ -190,7 +191,7 @@ private:
Common::WorkQueueThread<std::function<void()>> m_queue;
Common::WorkQueueThread<std::function<void()>> m_image_queue;
std::recursive_mutex m_lock;
mutable std::recursive_mutex m_lock;
}; // class AchievementManager
#endif // USE_RETRO_ACHIEVEMENTS

View file

@ -114,7 +114,7 @@ struct ARAddr
// AR Remote Functions
void ApplyCodes(std::span<const ARCode> codes)
{
if (!Config::Get(Config::MAIN_ENABLE_CHEATS))
if (!Config::AreCheatsEnabled())
return;
std::lock_guard guard(s_lock);
@ -143,7 +143,7 @@ void UpdateSyncedCodes(std::span<const ARCode> codes)
std::vector<ARCode> ApplyAndReturnCodes(std::span<const ARCode> codes)
{
if (Config::Get(Config::MAIN_ENABLE_CHEATS))
if (Config::AreCheatsEnabled())
{
std::lock_guard guard(s_lock);
s_disable_logging = false;
@ -158,7 +158,7 @@ std::vector<ARCode> ApplyAndReturnCodes(std::span<const ARCode> codes)
void AddCode(ARCode code)
{
if (!Config::Get(Config::MAIN_ENABLE_CHEATS))
if (!Config::AreCheatsEnabled())
return;
if (code.enabled)
@ -990,7 +990,7 @@ static bool RunCodeLocked(const Core::CPUThreadGuard& guard, const ARCode& arcod
void RunAllActive(const Core::CPUThreadGuard& cpu_guard)
{
if (!Config::Get(Config::MAIN_ENABLE_CHEATS))
if (!Config::AreCheatsEnabled())
return;
// If the mutex is idle then acquiring it should be cheap, fast mutexes

View file

@ -16,6 +16,7 @@
#include "Common/BitUtils.h"
#include "Common/StringUtil.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/MMU.h"
@ -206,6 +207,10 @@ Cheats::NewSearch(const Core::CPUThreadGuard& guard,
PowerPC::RequestedAddressSpace address_space, bool aligned,
const std::function<bool(const T& value)>& validator)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
#endif // USE_RETRO_ACHIEVEMENTS
const u32 data_size = sizeof(T);
std::vector<Cheats::SearchResult<T>> results;
Cheats::SearchErrorCode error_code = Cheats::SearchErrorCode::Success;
@ -269,6 +274,10 @@ Cheats::NextSearch(const Core::CPUThreadGuard& guard,
PowerPC::RequestedAddressSpace address_space,
const std::function<bool(const T& new_value, const T& old_value)>& validator)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
#endif // USE_RETRO_ACHIEVEMENTS
std::vector<Cheats::SearchResult<T>> results;
Cheats::SearchErrorCode error_code = Cheats::SearchErrorCode::Success;
Core::RunAsCPUThread([&] {
@ -444,6 +453,10 @@ MakeCompareFunctionForLastValue(Cheats::CompareType op)
template <typename T>
Cheats::SearchErrorCode Cheats::CheatSearchSession<T>::RunSearch(const Core::CPUThreadGuard& guard)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return Cheats::SearchErrorCode::DisabledInHardcoreMode;
#endif // USE_RETRO_ACHIEVEMENTS
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>> result =
Cheats::SearchErrorCode::InvalidParameters;
if (m_filter_type == FilterType::CompareAgainstSpecificValue)

View file

@ -99,6 +99,11 @@ enum class SearchErrorCode
// This is returned if PowerPC::RequestedAddressSpace::Virtual is given but the MSR.DR flag is
// currently off in the emulated game.
VirtualAddressesCurrentlyNotAccessible,
#ifdef USE_RETRO_ACHIEVEMENTS
// Cheats and memory reading are disabled in RetroAchievements hardcore mode.
DisabledInHardcoreMode,
#endif // USE_RETRO_ACHIEVEMENTS
};
// Returns the corresponding DataType enum for the value currently held by the given SearchValue.

View file

@ -1,6 +1,7 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef USE_RETRO_ACHIEVEMENTS
#include "Core/Config/AchievementSettings.h"
#include <string>
@ -19,6 +20,8 @@ const Info<bool> RA_LEADERBOARDS_ENABLED{
{System::Achievements, "Achievements", "LeaderboardsEnabled"}, false};
const Info<bool> RA_RICH_PRESENCE_ENABLED{
{System::Achievements, "Achievements", "RichPresenceEnabled"}, false};
const Info<bool> RA_HARDCORE_ENABLED{{System::Achievements, "Achievements", "HardcoreEnabled"},
false};
const Info<bool> RA_PROGRESS_ENABLED{{System::Achievements, "Achievements", "ProgressEnabled"},
false};
const Info<bool> RA_BADGES_ENABLED{{System::Achievements, "Achievements", "BadgesEnabled"}, false};
@ -26,3 +29,5 @@ const Info<bool> RA_UNOFFICIAL_ENABLED{{System::Achievements, "Achievements", "U
false};
const Info<bool> RA_ENCORE_ENABLED{{System::Achievements, "Achievements", "EncoreEnabled"}, false};
} // namespace Config
#endif // USE_RETRO_ACHIEVEMENTS

View file

@ -1,6 +1,7 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef USE_RETRO_ACHIEVEMENTS
#pragma once
#include "Common/Config/Config.h"
@ -14,8 +15,11 @@ extern const Info<std::string> RA_API_TOKEN;
extern const Info<bool> RA_ACHIEVEMENTS_ENABLED;
extern const Info<bool> RA_LEADERBOARDS_ENABLED;
extern const Info<bool> RA_RICH_PRESENCE_ENABLED;
extern const Info<bool> RA_HARDCORE_ENABLED;
extern const Info<bool> RA_PROGRESS_ENABLED;
extern const Info<bool> RA_BADGES_ENABLED;
extern const Info<bool> RA_UNOFFICIAL_ENABLED;
extern const Info<bool> RA_ENCORE_ENABLED;
} // namespace Config
#endif // USE_RETRO_ACHIEVEMENTS

View file

@ -18,6 +18,7 @@
#include "Common/MathUtil.h"
#include "Common/StringUtil.h"
#include "Common/Version.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/DefaultLocale.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/EXI/EXI_Device.h"
@ -738,4 +739,24 @@ bool IsDefaultGCIFolderPathConfigured(ExpansionInterface::Slot slot)
{
return Config::Get(GetInfoForGCIPath(slot)).empty();
}
bool AreCheatsEnabled()
{
#ifdef USE_RETRO_ACHIEVEMENTS
return Config::Get(::Config::MAIN_ENABLE_CHEATS) && !::Config::Get(::Config::RA_HARDCORE_ENABLED);
#else // USE_RETRO_ACHIEVEMENTS
return Config::Get(::Config::MAIN_ENABLE_CHEATS);
#endif // USE_RETRO_ACHIEVEMENTS
}
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

View file

@ -378,4 +378,6 @@ std::string GetGCIFolderPath(ExpansionInterface::Slot slot, std::optional<DiscIO
std::string GetGCIFolderPath(std::string configured_folder, ExpansionInterface::Slot slot,
std::optional<DiscIO::Region> region);
bool IsDefaultGCIFolderPathConfigured(ExpansionInterface::Slot slot);
bool AreCheatsEnabled();
bool IsDebuggingEnabled();
} // namespace Config

View file

@ -42,6 +42,7 @@
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/CoreTiming.h"
@ -1081,6 +1082,13 @@ void HostDispatchJobs()
// NOTE: Host Thread
void DoFrameStep()
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (AchievementManager::GetInstance()->IsHardcoreModeActive())
{
OSD::AddMessage("Frame stepping is disabled in RetroAchievements hardcore mode");
return;
}
#endif // USE_RETRO_ACHIEVEMENTS
if (GetState() == State::Paused)
{
// if already paused, frame advance for 1 frame

View file

@ -16,13 +16,16 @@
#include "Common/Logging/Log.h"
#include "Common/SPSCQueue.h"
#include "Core/AchievementManager.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PerformanceMetrics.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
@ -135,6 +138,17 @@ void CoreTimingManager::RefreshConfig()
m_max_variance = std::chrono::duration_cast<DT>(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE)));
#ifdef USE_RETRO_ACHIEVEMENTS
if (AchievementManager::GetInstance()->IsHardcoreModeActive() &&
Config::Get(Config::MAIN_EMULATION_SPEED) < 1.0f &&
Config::Get(Config::MAIN_EMULATION_SPEED) > 0.0f)
{
Config::SetCurrent(Config::MAIN_EMULATION_SPEED, 1.0f);
m_emulation_speed = 1.0f;
OSD::AddMessage("Minimum speed is 100% in Hardcore Mode");
}
#endif // USE_RETRO_ACHIEVEMENTS
m_emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED);
}

View file

@ -16,6 +16,7 @@
#include "Common/GekkoDisassembler.h"
#include "Common/StringUtil.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/Debugger/OSThread.h"
@ -29,6 +30,10 @@
void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, Common::Debug::MemoryPatch& patch,
bool store_existing_value)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return;
#endif // USE_RETRO_ACHIEVEMENTS
if (patch.value.empty())
return;

View file

@ -3,7 +3,9 @@
#include "Core/FreeLookConfig.h"
#include "Core/AchievementManager.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/FreeLookSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
@ -44,6 +46,11 @@ void Config::Refresh()
}
camera_config.control_type = ::Config::Get(::Config::FL1_CONTROL_TYPE);
#ifdef USE_RETRO_ACHIEVEMENTS
enabled = ::Config::Get(::Config::FREE_LOOK_ENABLED) &&
!AchievementManager::GetInstance()->IsHardcoreModeActive();
#else // USE_RETRO_ACHIEVEMENTS
enabled = ::Config::Get(::Config::FREE_LOOK_ENABLED);
#endif // USE_RETRO_ACHIEVEMENTS
}
} // namespace FreeLook

View file

@ -71,7 +71,7 @@ void SetActiveCodes(std::span<const GeckoCode> gcodes)
std::lock_guard lk(s_active_codes_lock);
s_active_codes.clear();
if (Config::Get(Config::MAIN_ENABLE_CHEATS))
if (Config::AreCheatsEnabled())
{
s_active_codes.reserve(gcodes.size());
std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes),
@ -103,7 +103,7 @@ std::vector<GeckoCode> SetAndReturnActiveCodes(std::span<const GeckoCode> gcodes
std::lock_guard lk(s_active_codes_lock);
s_active_codes.clear();
if (Config::Get(Config::MAIN_ENABLE_CHEATS))
if (Config::AreCheatsEnabled())
{
s_active_codes.reserve(gcodes.size());
std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes),
@ -238,7 +238,7 @@ void Shutdown()
void RunCodeHandler(const Core::CPUThreadGuard& guard)
{
if (!Config::Get(Config::MAIN_ENABLE_CHEATS))
if (!Config::AreCheatsEnabled())
return;
// NOTE: Need to release the lock because of GUI deadlocks with PanicAlert in HostWrite_*

View file

@ -90,7 +90,7 @@ void PatchFixedFunctions(Core::System& system)
// HLE jump to loader (homebrew). Disabled when Gecko is active as it interferes with the code
// handler
if (!Config::Get(Config::MAIN_ENABLE_CHEATS))
if (!Config::AreCheatsEnabled())
{
Patch(system, 0x80001800, "HBReload");
auto& memory = system.GetMemory();
@ -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;
}

View file

@ -34,6 +34,7 @@
#include "Common/Version.h"
#include "Core/Boot/Boot.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/WiimoteSettings.h"
@ -974,6 +975,12 @@ bool PlayInput(const std::string& movie_path, std::optional<std::string>* savest
}
ReadHeader();
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return false;
#endif // USE_RETRO_ACHIEVEMENTS
s_totalFrames = tmpHeader.frameCount;
s_totalLagCount = tmpHeader.lagCount;
s_totalInputCount = tmpHeader.inputCount;
@ -1010,6 +1017,12 @@ bool PlayInput(const std::string& movie_path, std::optional<std::string>* savest
}
s_bRecordingFromSaveState = true;
#ifdef USE_RETRO_ACHIEVEMENTS
// On the chance someone tries to re-enable before the TAS can start
Config::SetBase(Config::RA_HARDCORE_ENABLED, false);
#endif // USE_RETRO_ACHIEVEMENTS
Movie::LoadInput(movie_path);
}

View file

@ -1356,7 +1356,7 @@ bool NetPlayServer::SetupNetSettings()
// Copy all relevant settings
settings.cpu_thread = Config::Get(Config::MAIN_CPU_THREAD);
settings.cpu_core = Config::Get(Config::MAIN_CPU_CORE);
settings.enable_cheats = Config::Get(Config::MAIN_ENABLE_CHEATS);
settings.enable_cheats = Config::AreCheatsEnabled();
settings.selected_language = Config::Get(Config::MAIN_GC_LANGUAGE);
settings.override_region_settings = Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS);
settings.dsp_hle = Config::Get(Config::MAIN_DSP_HLE);

View file

@ -26,6 +26,7 @@
#include "Core/ActionReplay.h"
#include "Core/CheatCodes.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
@ -232,6 +233,10 @@ void LoadPatches()
static void ApplyPatches(const Core::CPUThreadGuard& guard, const std::vector<Patch>& patches)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return;
#endif // USE_RETRO_ACHIEVEMENTS
for (const Patch& patch : patches)
{
if (patch.enabled)
@ -273,6 +278,10 @@ static void ApplyPatches(const Core::CPUThreadGuard& guard, const std::vector<Pa
static void ApplyMemoryPatches(const Core::CPUThreadGuard& guard,
std::span<const std::size_t> memory_patch_indices)
{
#ifdef USE_RETRO_ACHIEVEMENTS
if (Config::Get(Config::RA_HARDCORE_ENABLED))
return;
#endif // USE_RETRO_ACHIEVEMENTS
std::lock_guard lock(s_on_frame_memory_mutex);
for (std::size_t index : memory_patch_indices)
{

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -31,6 +31,8 @@
#include "Common/Version.h"
#include "Common/WorkQueueThread.h"
#include "Core/AchievementManager.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
@ -204,6 +206,14 @@ void LoadFromBuffer(std::vector<u8>& buffer)
return;
}
#ifdef USE_RETRO_ACHIEVEMENTS
if (AchievementManager::GetInstance()->IsHardcoreModeActive())
{
OSD::AddMessage("Loading savestates is disabled in RetroAchievements hardcore mode");
return;
}
#endif // USE_RETRO_ACHIEVEMENTS
Core::RunOnCPUThread(
[&] {
u8* ptr = buffer.data();
@ -842,6 +852,14 @@ void LoadAs(const std::string& filename)
return;
}
#ifdef USE_RETRO_ACHIEVEMENTS
if (AchievementManager::GetInstance()->IsHardcoreModeActive())
{
OSD::AddMessage("Loading savestates is disabled in RetroAchievements hardcore mode");
return;
}
#endif // USE_RETRO_ACHIEVEMENTS
std::unique_lock lk(s_load_or_save_in_progress_mutex, std::try_to_lock);
if (!lk)
return;