diff --git a/Data/Sys/Resources/achievements_game.png b/Data/Sys/Resources/achievements_game.png new file mode 100644 index 0000000000..624c3a917d Binary files /dev/null and b/Data/Sys/Resources/achievements_game.png differ diff --git a/Data/Sys/Resources/achievements_locked.png b/Data/Sys/Resources/achievements_locked.png new file mode 100644 index 0000000000..286709b1b1 Binary files /dev/null and b/Data/Sys/Resources/achievements_locked.png differ diff --git a/Data/Sys/Resources/achievements_player.png b/Data/Sys/Resources/achievements_player.png new file mode 100644 index 0000000000..d99412b839 Binary files /dev/null and b/Data/Sys/Resources/achievements_player.png differ diff --git a/Data/Sys/Resources/achievements_unlocked.png b/Data/Sys/Resources/achievements_unlocked.png new file mode 100644 index 0000000000..e95e60558a Binary files /dev/null and b/Data/Sys/Resources/achievements_unlocked.png differ diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index dd81a6e871..dec365b290 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -13,6 +13,8 @@ #include #include +#include "Common/CommonPaths.h" +#include "Common/FileUtil.h" #include "Common/Image.h" #include "Common/Logging/Log.h" #include "Common/ScopeGuard.h" @@ -35,6 +37,7 @@ AchievementManager& AchievementManager::GetInstance() void AchievementManager::Init() { + LoadDefaultBadges(); if (!m_client && Config::Get(Config::RA_ENABLED)) { m_client = rc_client_create(MemoryPeeker, Request); @@ -499,6 +502,55 @@ void AchievementManager::FilereaderClose(void* file_handle) delete static_cast(file_handle); } +void AchievementManager::LoadDefaultBadges() +{ + std::lock_guard lg{m_lock}; + + std::string directory = File::GetSysDirectory() + DIR_SEP + RESOURCES_DIR + DIR_SEP; + + if (m_default_player_badge.data.empty()) + { + if (!LoadPNGTexture(&m_default_player_badge, + fmt::format("{}{}", directory, DEFAULT_PLAYER_BADGE_FILENAME))) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Default player badge '{}' failed to load", + DEFAULT_PLAYER_BADGE_FILENAME); + } + } + m_player_badge.badge = m_default_player_badge; + + if (m_default_game_badge.data.empty()) + { + if (!LoadPNGTexture(&m_default_game_badge, + fmt::format("{}{}", directory, DEFAULT_GAME_BADGE_FILENAME))) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Default game badge '{}' failed to load", + DEFAULT_GAME_BADGE_FILENAME); + } + } + m_game_badge.badge = m_default_game_badge; + + if (m_default_unlocked_badge.data.empty()) + { + if (!LoadPNGTexture(&m_default_unlocked_badge, + fmt::format("{}{}", directory, DEFAULT_UNLOCKED_BADGE_FILENAME))) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Default unlocked achievement badge '{}' failed to load", + DEFAULT_UNLOCKED_BADGE_FILENAME); + } + } + + if (m_default_locked_badge.data.empty()) + { + if (!LoadPNGTexture(&m_default_locked_badge, + fmt::format("{}{}", directory, DEFAULT_LOCKED_BADGE_FILENAME))) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Default locked achievement badge '{}' failed to load", + DEFAULT_LOCKED_BADGE_FILENAME); + } + } +} + void AchievementManager::LoginCallback(int result, const char* error_message, rc_client_t* client, void* userdata) { @@ -669,14 +721,13 @@ void AchievementManager::DisplayWelcomeMessage() void AchievementManager::HandleAchievementTriggeredEvent(const rc_client_event_t* client_event) { - OSD::AddMessage( - fmt::format("Unlocked: {} ({})", client_event->achievement->title, - client_event->achievement->points), - OSD::Duration::VERY_LONG, - (rc_client_get_hardcore_enabled(AchievementManager::GetInstance().m_client)) ? - OSD::Color::YELLOW : - OSD::Color::CYAN, - &AchievementManager::GetInstance().m_unlocked_badges[client_event->achievement->id].badge); + const auto& instance = AchievementManager::GetInstance(); + OSD::AddMessage(fmt::format("Unlocked: {} ({})", client_event->achievement->title, + client_event->achievement->points), + OSD::Duration::VERY_LONG, + (rc_client_get_hardcore_enabled(instance.m_client)) ? OSD::Color::YELLOW : + OSD::Color::CYAN, + &instance.GetAchievementBadge(client_event->achievement->id, false).badge); } void AchievementManager::HandleLeaderboardStartedEvent(const rc_client_event_t* client_event) @@ -733,13 +784,11 @@ void AchievementManager::HandleLeaderboardTrackerHideEvent(const rc_client_event void AchievementManager::HandleAchievementChallengeIndicatorShowEvent( const rc_client_event_t* client_event) { - auto& unlocked_badges = AchievementManager::GetInstance().m_unlocked_badges; - if (const auto unlocked_iter = unlocked_badges.find(client_event->achievement->id); - unlocked_iter != unlocked_badges.end()) - { - AchievementManager::GetInstance().m_active_challenges[client_event->achievement->badge_name] = - &unlocked_iter->second.badge; - } + auto& instance = AchievementManager::GetInstance(); + instance.m_active_challenges[client_event->achievement->badge_name] = + &AchievementManager::GetInstance() + .GetAchievementBadge(client_event->achievement->id, false) + .badge; } void AchievementManager::HandleAchievementChallengeIndicatorHideEvent( @@ -752,11 +801,11 @@ void AchievementManager::HandleAchievementChallengeIndicatorHideEvent( void AchievementManager::HandleAchievementProgressIndicatorShowEvent( const rc_client_event_t* client_event) { - OSD::AddMessage( - fmt::format("{} {}", client_event->achievement->title, - client_event->achievement->measured_progress), - OSD::Duration::SHORT, OSD::Color::GREEN, - &AchievementManager::GetInstance().m_unlocked_badges[client_event->achievement->id].badge); + const auto& instance = AchievementManager::GetInstance(); + OSD::AddMessage(fmt::format("{} {}", client_event->achievement->title, + client_event->achievement->measured_progress), + OSD::Duration::SHORT, OSD::Color::GREEN, + &instance.GetAchievementBadge(client_event->achievement->id, false).badge); } void AchievementManager::HandleGameCompletedEvent(const rc_client_event_t* client_event, diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index e7aaa672e3..17abceeaa8 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -53,6 +53,10 @@ public: Badge badge{}; }; + static constexpr std::string_view DEFAULT_PLAYER_BADGE_FILENAME = "achievements_player.png"; + static constexpr std::string_view DEFAULT_GAME_BADGE_FILENAME = "achievements_game.png"; + static constexpr std::string_view DEFAULT_LOCKED_BADGE_FILENAME = "achievements_locked.png"; + static constexpr std::string_view DEFAULT_UNLOCKED_BADGE_FILENAME = "achievements_unlocked.png"; static constexpr std::string_view GRAY = "transparent"; static constexpr std::string_view GOLD = "#FFD700"; static constexpr std::string_view BLUE = "#0B71C1"; @@ -137,6 +141,7 @@ private: static size_t FilereaderRead(void* file_handle, void* buffer, size_t requested_bytes); static void FilereaderClose(void* file_handle); + void LoadDefaultBadges(); static void LoginCallback(int result, const char* error_message, rc_client_t* client, void* userdata); @@ -181,6 +186,10 @@ private: bool m_is_runtime_initialized = false; UpdateCallback m_update_callback = [](const UpdatedItems&) {}; std::unique_ptr m_loading_volume; + Badge m_default_player_badge; + Badge m_default_game_badge; + Badge m_default_unlocked_badge; + Badge m_default_locked_badge; BadgeStatus m_player_badge; Hash m_game_hash{}; u32 m_game_id = 0;