From 1b880564cbc8da9894af065e9ac1cc9c608352a1 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 15 Apr 2023 12:28:58 -0400 Subject: [PATCH] Added MemoryPeeker to AchievementManager MemoryPeeker is a function passed by pointer into rcheevos DoFrame functionality that forms the lynchpin of the rcheevos runtime - it provides the interface by which rcheevos accesses memory and determines if the fields provided by achievement, leaderboard, and rich presence definitions are meeting the criteria needed. --- Source/Core/Core/AchievementManager.cpp | 34 ++++++++++++++++++++++++- Source/Core/Core/AchievementManager.h | 7 +++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 536f5fe63f..2d4fce9af8 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -9,8 +9,10 @@ #include "Common/HttpRequest.h" #include "Common/WorkQueueThread.h" -#include "Config/AchievementSettings.h" +#include "Core/Config/AchievementSettings.h" #include "Core/Core.h" +#include "Core/PowerPC/MMU.h" +#include "Core/System.h" #include "DiscIO/Volume.h" static constexpr bool hardcore_mode_enabled = false; @@ -62,6 +64,7 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, callback(AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED); return; } + m_system = &Core::System::GetInstance(); struct FilereaderState { int64_t position = 0; @@ -202,6 +205,34 @@ void AchievementManager::ActivateDeactivateRichPresence() nullptr, 0); } +u32 AchievementManager::MemoryPeeker(u32 address, u32 num_bytes, void* ud) +{ + if (!m_system) + return 0u; + Core::CPUThreadGuard threadguard(*m_system); + switch (num_bytes) + { + case 1: + return m_system->GetMMU() + .HostTryReadU8(threadguard, address) + .value_or(PowerPC::ReadResult(false, 0u)) + .value; + case 2: + return m_system->GetMMU() + .HostTryReadU16(threadguard, address) + .value_or(PowerPC::ReadResult(false, 0u)) + .value; + case 4: + return m_system->GetMMU() + .HostTryReadU32(threadguard, address) + .value_or(PowerPC::ReadResult(false, 0u)) + .value; + default: + ASSERT(false); + return 0u; + } +} + void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runtime_event) { switch (runtime_event->type) @@ -221,6 +252,7 @@ void AchievementManager::CloseGame() m_game_id = 0; m_queue.Cancel(); m_unlock_map.clear(); + m_system = nullptr; ActivateDeactivateAchievements(); ActivateDeactivateLeaderboards(); ActivateDeactivateRichPresence(); diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 293ac00202..d041259c1c 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -22,6 +22,11 @@ using AchievementId = u32; constexpr size_t RP_SIZE = 256; using RichPresence = std::array; +namespace Core +{ +class System; +} + class AchievementManager { public: @@ -48,6 +53,7 @@ public: void ActivateDeactivateLeaderboards(); void ActivateDeactivateRichPresence(); + u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud); void AchievementEventHandler(const rc_runtime_event_t* runtime_event); void CloseGame(); @@ -80,6 +86,7 @@ private: const std::function& process_response); rc_runtime_t m_runtime{}; + Core::System* m_system{}; bool m_is_runtime_initialized = false; std::array m_game_hash{}; u32 m_game_id = 0;