From a3d561fdff551c095ddff13f062daf38bd0f9492 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 7 Oct 2023 00:05:45 -0400 Subject: [PATCH 1/2] Add badges to achievement messages Updated OSD::AddMessage calls for achievements and game start to pass in the badges intended to be shown. --- Source/Core/Core/AchievementManager.cpp | 52 ++++++++++++++++++++----- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index d5acdc84e9..6b4148a9ed 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -5,12 +5,15 @@ #include "Core/AchievementManager.h" +#include + #include #include #include #include "Common/HttpRequest.h" +#include "Common/Image.h" #include "Common/Logging/Log.h" #include "Common/WorkQueueThread.h" #include "Core/Config/AchievementSettings.h" @@ -23,6 +26,8 @@ static constexpr bool hardcore_mode_enabled = false; +static std::unique_ptr DecodeBadgeToOSDIcon(const AchievementManager::Badge& badge); + AchievementManager* AchievementManager::GetInstance() { static AchievementManager s_instance; @@ -197,10 +202,12 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, PointSpread spread = TallyScore(); if (hardcore_mode_enabled) { - OSD::AddMessage(fmt::format("You have {}/{} achievements worth {}/{} points", - spread.hard_unlocks, spread.total_count, spread.hard_points, - spread.total_points), - OSD::Duration::VERY_LONG, OSD::Color::YELLOW); + OSD::AddMessage( + fmt::format("You have {}/{} achievements worth {}/{} points", spread.hard_unlocks, + spread.total_count, spread.hard_points, spread.total_points), + OSD::Duration::VERY_LONG, OSD::Color::YELLOW, + (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); OSD::AddMessage("Hardcore mode is ON", OSD::Duration::VERY_LONG, OSD::Color::YELLOW); } else @@ -208,7 +215,10 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, OSD::AddMessage(fmt::format("You have {}/{} achievements worth {}/{} points", spread.hard_unlocks + spread.soft_unlocks, spread.total_count, spread.hard_points + spread.soft_points, spread.total_points), - OSD::Duration::VERY_LONG, OSD::Color::CYAN); + OSD::Duration::VERY_LONG, OSD::Color::CYAN, + (Config::Get(Config::RA_BADGES_ENABLED)) ? + DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); OSD::AddMessage("Hardcore mode is OFF", OSD::Duration::VERY_LONG, OSD::Color::CYAN); } } @@ -1199,19 +1209,26 @@ void AchievementManager::HandleAchievementTriggeredEvent(const rc_runtime_event_ OSD::AddMessage(fmt::format("Unlocked: {} ({})", m_game_data.achievements[game_data_index].title, m_game_data.achievements[game_data_index].points), OSD::Duration::VERY_LONG, - (hardcore_mode_enabled) ? OSD::Color::YELLOW : OSD::Color::CYAN); + (hardcore_mode_enabled) ? OSD::Color::YELLOW : OSD::Color::CYAN, + (Config::Get(Config::RA_BADGES_ENABLED)) ? + DecodeBadgeToOSDIcon(it->second.unlocked_badge.badge) : + nullptr); PointSpread spread = TallyScore(); if (spread.hard_points == spread.total_points) { OSD::AddMessage( fmt::format("Congratulations! {} has mastered {}", m_display_name, m_game_data.title), - OSD::Duration::VERY_LONG, OSD::Color::YELLOW); + OSD::Duration::VERY_LONG, OSD::Color::YELLOW, + (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); } else if (spread.hard_points + spread.soft_points == spread.total_points) { OSD::AddMessage( fmt::format("Congratulations! {} has completed {}", m_display_name, m_game_data.title), - OSD::Duration::VERY_LONG, OSD::Color::CYAN); + OSD::Duration::VERY_LONG, OSD::Color::CYAN, + (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); } ActivateDeactivateAchievement(event_id, Config::Get(Config::RA_ACHIEVEMENTS_ENABLED), Config::Get(Config::RA_UNOFFICIAL_ENABLED), @@ -1240,7 +1257,10 @@ void AchievementManager::HandleAchievementProgressUpdatedEvent( } OSD::AddMessage( fmt::format("{} {}", m_game_data.achievements[game_data_index].title, value.data()), - OSD::Duration::VERY_LONG, OSD::Color::GREEN); + OSD::Duration::VERY_LONG, OSD::Color::GREEN, + (Config::Get(Config::RA_BADGES_ENABLED)) ? + DecodeBadgeToOSDIcon(it->second.unlocked_badge.badge) : + nullptr); } void AchievementManager::HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event) @@ -1388,4 +1408,18 @@ AchievementManager::RequestImage(rc_api_fetch_image_request_t rc_request, Badge* } } +static std::unique_ptr DecodeBadgeToOSDIcon(const AchievementManager::Badge& badge) +{ + if (badge.empty()) + return nullptr; + + auto icon = std::make_unique(); + if (!Common::LoadPNG(badge, &icon->rgba_data, &icon->width, &icon->height)) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Error decoding badge."); + return nullptr; + } + return icon; +} + #endif // USE_RETRO_ACHIEVEMENTS From db784374989e07ce0aaef932443e9a58545fa756 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 7 Oct 2023 00:09:47 -0400 Subject: [PATCH 2/2] Refactored welcome message to render after game start Split the "welcome" messages letting players know achievements are active into a separate method that gets called (currently) after a number of frames to ensure that the emulator has started properly and has somewhere to display the messages. --- Source/Core/Core/AchievementManager.cpp | 58 +++++++++++++++---------- Source/Core/Core/AchievementManager.h | 3 ++ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 6b4148a9ed..54671a1388 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -195,32 +195,11 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, { std::lock_guard lg{m_lock}; m_is_game_loaded = true; + m_framecount = 0; LoadUnlockData([](ResponseType r_type) {}); ActivateDeactivateAchievements(); ActivateDeactivateLeaderboards(); ActivateDeactivateRichPresence(); - PointSpread spread = TallyScore(); - if (hardcore_mode_enabled) - { - OSD::AddMessage( - fmt::format("You have {}/{} achievements worth {}/{} points", spread.hard_unlocks, - spread.total_count, spread.hard_points, spread.total_points), - OSD::Duration::VERY_LONG, OSD::Color::YELLOW, - (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) : - nullptr); - OSD::AddMessage("Hardcore mode is ON", OSD::Duration::VERY_LONG, OSD::Color::YELLOW); - } - else - { - OSD::AddMessage(fmt::format("You have {}/{} achievements worth {}/{} points", - spread.hard_unlocks + spread.soft_unlocks, spread.total_count, - spread.hard_points + spread.soft_points, spread.total_points), - OSD::Duration::VERY_LONG, OSD::Color::CYAN, - (Config::Get(Config::RA_BADGES_ENABLED)) ? - DecodeBadgeToOSDIcon(m_game_badge.badge) : - nullptr); - OSD::AddMessage("Hardcore mode is OFF", OSD::Duration::VERY_LONG, OSD::Color::CYAN); - } } FetchBadges(); // Reset this to zero so that RP immediately triggers on the first frame @@ -562,6 +541,14 @@ void AchievementManager::DoFrame() { if (!m_is_game_loaded) return; + if (m_framecount == 0x200) + { + DisplayWelcomeMessage(); + } + if (m_framecount <= 0x200) + { + m_framecount++; + } Core::RunAsCPUThread([&] { rc_runtime_do_frame( &m_runtime, @@ -1194,6 +1181,33 @@ AchievementManager::PingRichPresence(const RichPresence& rich_presence) return r_type; } +void AchievementManager::DisplayWelcomeMessage() +{ + std::lock_guard lg{m_lock}; + PointSpread spread = TallyScore(); + if (hardcore_mode_enabled) + { + OSD::AddMessage( + fmt::format("You have {}/{} achievements worth {}/{} points", spread.hard_unlocks, + spread.total_count, spread.hard_points, spread.total_points), + OSD::Duration::VERY_LONG, OSD::Color::YELLOW, + (Config::Get(Config::RA_BADGES_ENABLED)) ? DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); + OSD::AddMessage("Hardcore mode is ON", OSD::Duration::VERY_LONG, OSD::Color::YELLOW); + } + else + { + OSD::AddMessage(fmt::format("You have {}/{} achievements worth {}/{} points", + spread.hard_unlocks + spread.soft_unlocks, spread.total_count, + spread.hard_points + spread.soft_points, spread.total_points), + OSD::Duration::VERY_LONG, OSD::Color::CYAN, + (Config::Get(Config::RA_BADGES_ENABLED)) ? + DecodeBadgeToOSDIcon(m_game_badge.badge) : + nullptr); + OSD::AddMessage("Hardcore mode is OFF", OSD::Duration::VERY_LONG, OSD::Color::CYAN); + } +} + void AchievementManager::HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event) { const auto event_id = runtime_event->id; diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index b5c1eee200..be2469dc9e 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -155,6 +155,8 @@ private: ResponseType SubmitLeaderboard(AchievementId leaderboard_id, int value); ResponseType PingRichPresence(const RichPresence& rich_presence); + void DisplayWelcomeMessage(); + void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event); void HandleAchievementProgressUpdatedEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event); @@ -178,6 +180,7 @@ private: u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false; + u32 m_framecount = 0; BadgeStatus m_game_badge; RichPresence m_rich_presence; time_t m_last_ping_time = 0;