From 38bd04c439e33ff8411f4590cd6e287080e4d31e Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 17 Jun 2023 12:40:07 -0400 Subject: [PATCH] Add Rich Presence to Achievement Dialog Header This refactors the Rich Presence generation to store to a member field that can be exposed to the UI to display the Rich Presence in the achievement header. It still updates at its original rate of once per two minutes, but calls an update on the dialog when that ticks. --- Source/Core/Core/AchievementManager.cpp | 26 ++++++++++++------- Source/Core/Core/AchievementManager.h | 4 ++- .../Achievements/AchievementHeaderWidget.cpp | 9 +++---- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 74bd257311..2463952e07 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -290,9 +290,11 @@ void AchievementManager::DoFrame() time_t current_time = std::time(nullptr); if (difftime(current_time, m_last_ping_time) > 120) { - RichPresence rp = GenerateRichPresence(); - m_queue.EmplaceItem([this, rp] { PingRichPresence(rp); }); + GenerateRichPresence(); + m_queue.EmplaceItem([this] { PingRichPresence(m_rich_presence); }); m_last_ping_time = current_time; + if (m_update_callback) + m_update_callback(); } } @@ -305,17 +307,17 @@ u32 AchievementManager::MemoryPeeker(u32 address, u32 num_bytes, void* ud) { case 1: return m_system->GetMMU() - .HostTryReadU8(threadguard, address) + .HostTryReadU8(threadguard, address, PowerPC::RequestedAddressSpace::Physical) .value_or(PowerPC::ReadResult(false, 0u)) .value; case 2: return m_system->GetMMU() - .HostTryReadU16(threadguard, address) + .HostTryReadU16(threadguard, address, PowerPC::RequestedAddressSpace::Physical) .value_or(PowerPC::ReadResult(false, 0u)) .value; case 4: return m_system->GetMMU() - .HostTryReadU32(threadguard, address) + .HostTryReadU32(threadguard, address, PowerPC::RequestedAddressSpace::Physical) .value_or(PowerPC::ReadResult(false, 0u)) .value; default: @@ -411,6 +413,13 @@ void AchievementManager::GetAchievementProgress(AchievementId achievement_id, u3 rc_runtime_get_achievement_measured(&m_runtime, achievement_id, value, target); } +AchievementManager::RichPresence AchievementManager::GetRichPresence() +{ + std::lock_guard lg{m_lock}; + RichPresence rich_presence = m_rich_presence; + return rich_presence; +} + void AchievementManager::CloseGame() { { @@ -585,18 +594,17 @@ void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool en rc_runtime_deactivate_achievement(&m_runtime, id); } -AchievementManager::RichPresence AchievementManager::GenerateRichPresence() +void AchievementManager::GenerateRichPresence() { - RichPresence rp_buffer; Core::RunAsCPUThread([&] { + std::lock_guard lg{m_lock}; rc_runtime_get_richpresence( - &m_runtime, rp_buffer.data(), RP_SIZE, + &m_runtime, m_rich_presence.data(), RP_SIZE, [](unsigned address, unsigned num_bytes, void* ud) { return static_cast(ud)->MemoryPeeker(address, num_bytes, ud); }, this, nullptr); }); - return rp_buffer; } AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id) diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index a2e159c7e3..a4e333d6dc 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -94,6 +94,7 @@ public: rc_api_fetch_game_data_response_t* GetGameData(); UnlockStatus GetUnlockStatus(AchievementId achievement_id) const; void GetAchievementProgress(AchievementId achievement_id, u32* value, u32* target); + RichPresence GetRichPresence(); void CloseGame(); void Logout(); @@ -111,7 +112,7 @@ private: ResponseType FetchUnlockData(bool hardcore); void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore); - RichPresence GenerateRichPresence(); + void GenerateRichPresence(); ResponseType AwardAchievement(AchievementId achievement_id); ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value); @@ -137,6 +138,7 @@ private: u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false; + RichPresence m_rich_presence; time_t m_last_ping_time = 0; std::unordered_map m_unlock_map; diff --git a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp index 4dc3e66538..2d817a6891 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp @@ -20,6 +20,7 @@ #include #include "Core/AchievementManager.h" +#include "Core/Config/AchievementSettings.h" #include "Core/Core.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" @@ -101,11 +102,9 @@ void AchievementHeaderWidget::UpdateData() m_game_progress_soft->setValue(point_spread.hard_unlocks); m_game_progress_soft->setRange(0, point_spread.total_count); m_game_progress_soft->setValue(point_spread.hard_unlocks + point_spread.soft_unlocks); - // TODO: RP needs a minor refactor to work here, will be a future PR - // m_rich_presence->setText(QString::fromStdString(AchievementManager::GetInstance()->GenerateRichPresence())); - // m_rich_presence->setVisible(Config::Get(Config::RA_RICH_PRESENCE_ENABLED)); - m_rich_presence->setText(QString{}); - m_rich_presence->setVisible(false); + m_rich_presence->setText( + QString::fromUtf8(AchievementManager::GetInstance()->GetRichPresence().data())); + m_rich_presence->setVisible(Config::Get(Config::RA_RICH_PRESENCE_ENABLED)); m_user_box->setVisible(false); m_game_box->setVisible(true);