From c9c2e17e5a8e245475d34865da4fd2d1fb0e100a Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 15 Apr 2023 12:32:52 -0400 Subject: [PATCH] Added DoFrame to AchievementManager DoFrame is a function called every frame by the emulator so that rcheevos can be properly updated and processed. It requires a memory peeker and an event handler to be passed in; the memory peeker is called repeatedly each frame to measure what's in memory and compare to achievement definitions, and any events thrown by that comparison are sent to the event handler. Also, DoFrame checks for the current system time to determine when to ping rich presence. Rich Presence on the RetroAchievements website updates every two minutes, so if two minutes have elapsed since the previous ping, another ping is sent. --- Source/Core/Core/AchievementManager.cpp | 23 +++++++++++++++++++++++ Source/Core/Core/AchievementManager.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index ebb0302a53..9c8b3d1a4a 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -14,6 +14,7 @@ #include "Core/PowerPC/MMU.h" #include "Core/System.h" #include "DiscIO/Volume.h" +#include "VideoCommon/VideoEvents.h" static constexpr bool hardcore_mode_enabled = false; @@ -205,6 +206,28 @@ void AchievementManager::ActivateDeactivateRichPresence() nullptr, 0); } +void AchievementManager::DoFrame() +{ + if (!m_is_game_loaded) + return; + Core::RunAsCPUThread([&] { + rc_runtime_do_frame( + &m_runtime, + [](const rc_runtime_event_t* runtime_event) { + AchievementManager::GetInstance()->AchievementEventHandler(runtime_event); + }, + [](unsigned address, unsigned num_bytes, void* ud) { + return static_cast(ud)->MemoryPeeker(address, num_bytes, ud); + }, + this, nullptr); + }); + if (!m_system) + return; + u64 current_time = m_system->GetCoreTiming().GetTicks(); + if (current_time - m_last_ping_time > SystemTimers::GetTicksPerSecond() * 120) + m_queue.EmplaceItem([this] { PingRichPresence(GenerateRichPresence()); }); +} + u32 AchievementManager::MemoryPeeker(u32 address, u32 num_bytes, void* ud) { if (!m_system) diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 82e7eb723f..b6cbcde732 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -53,6 +53,7 @@ public: void ActivateDeactivateLeaderboards(); void ActivateDeactivateRichPresence(); + void DoFrame(); u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud); void AchievementEventHandler(const rc_runtime_event_t* runtime_event); @@ -93,6 +94,7 @@ private: u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false; + u64 m_last_ping_time = 0; struct UnlockStatus {