diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 1a05af90bc..27e82a8c55 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -183,6 +183,11 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, }); } +bool AchievementManager::IsGameLoaded() const +{ + return m_is_game_loaded; +} + void AchievementManager::LoadUnlockData(const ResponseCallback& callback) { m_queue.EmplaceItem([this, callback] { @@ -313,6 +318,64 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti } } +std::string AchievementManager::GetPlayerDisplayName() const +{ + return IsLoggedIn() ? m_display_name : ""; +} + +u32 AchievementManager::GetPlayerScore() const +{ + return IsLoggedIn() ? m_player_score : 0; +} + +std::string AchievementManager::GetGameDisplayName() const +{ + return IsGameLoaded() ? m_game_data.title : ""; +} + +AchievementManager::PointSpread AchievementManager::TallyScore() const +{ + PointSpread spread{}; + if (!IsGameLoaded()) + return spread; + for (const auto& entry : m_unlock_map) + { + u32 points = entry.second.points; + spread.total_count++; + spread.total_points += points; + if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::HARDCORE || + (hardcore_mode_enabled && entry.second.session_unlock_count > 0)) + { + spread.hard_unlocks++; + spread.hard_points += points; + } + else if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::SOFTCORE || + entry.second.session_unlock_count > 0) + { + spread.soft_unlocks++; + spread.soft_points += points; + } + } + return spread; +} + +rc_api_fetch_game_data_response_t* AchievementManager::GetGameData() +{ + return &m_game_data; +} + +AchievementManager::UnlockStatus +AchievementManager::GetUnlockStatus(AchievementId achievement_id) const +{ + return m_unlock_map.at(achievement_id); +} + +void AchievementManager::GetAchievementProgress(AchievementId achievement_id, u32* value, + u32* target) +{ + rc_runtime_get_achievement_measured(&m_runtime, achievement_id, value, target); +} + void AchievementManager::CloseGame() { m_is_game_loaded = false; @@ -353,6 +416,7 @@ AchievementManager::ResponseType AchievementManager::VerifyCredentials(const std { Config::SetBaseOrCurrent(Config::RA_API_TOKEN, login_data.api_token); m_display_name = login_data.display_name; + m_player_score = login_data.score; } rc_api_destroy_login_response(&login_data); return r_type; @@ -618,30 +682,6 @@ void AchievementManager::HandleLeaderboardTriggeredEvent(const rc_runtime_event_ } } -AchievementManager::PointSpread AchievementManager::TallyScore() const -{ - PointSpread spread{}; - for (const auto& entry : m_unlock_map) - { - u32 points = entry.second.points; - spread.total_count++; - spread.total_points += points; - if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::HARDCORE || - (hardcore_mode_enabled && entry.second.session_unlock_count > 0)) - { - spread.hard_unlocks++; - spread.hard_points += points; - } - else if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::SOFTCORE || - entry.second.session_unlock_count > 0) - { - spread.soft_unlocks++; - spread.soft_points += points; - } - } - return spread; -} - // Every RetroAchievements API call, with only a partial exception for fetch_image, follows // the same design pattern (here, X is the name of the call): // Create a specific rc_api_X_request_t struct and populate with the necessary values diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index f35cd5f659..00c2055920 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -52,12 +52,26 @@ public: u32 soft_points; }; + struct UnlockStatus + { + AchievementId game_data_index = 0; + enum class UnlockType + { + LOCKED, + SOFTCORE, + HARDCORE + } remote_unlock_status = UnlockType::LOCKED; + u32 session_unlock_count = 0; + u32 points = 0; + }; + static AchievementManager* GetInstance(); void Init(); ResponseType Login(const std::string& password); void LoginAsync(const std::string& password, const ResponseCallback& callback); bool IsLoggedIn() const; void LoadGameByFilenameAsync(const std::string& iso_path, const ResponseCallback& callback); + bool IsGameLoaded() const; void LoadUnlockData(const ResponseCallback& callback); void ActivateDeactivateAchievements(); @@ -68,6 +82,14 @@ public: u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud); void AchievementEventHandler(const rc_runtime_event_t* runtime_event); + std::string GetPlayerDisplayName() const; + u32 GetPlayerScore() const; + std::string GetGameDisplayName() const; + PointSpread TallyScore() const; + rc_api_fetch_game_data_response_t* GetGameData(); + UnlockStatus GetUnlockStatus(AchievementId achievement_id) const; + void GetAchievementProgress(AchievementId achievement_id, u32* value, u32* target); + void CloseGame(); void Logout(); void Shutdown(); @@ -95,8 +117,6 @@ private: void HandleLeaderboardCanceledEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardTriggeredEvent(const rc_runtime_event_t* runtime_event); - PointSpread TallyScore() const; - template ResponseType Request(RcRequest rc_request, RcResponse* rc_response, const std::function& init_request, @@ -106,24 +126,13 @@ private: Core::System* m_system{}; bool m_is_runtime_initialized = false; std::string m_display_name; + u32 m_player_score = 0; std::array m_game_hash{}; u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false; time_t m_last_ping_time = 0; - struct UnlockStatus - { - AchievementId game_data_index = 0; - enum class UnlockType - { - LOCKED, - SOFTCORE, - HARDCORE - } remote_unlock_status = UnlockType::LOCKED; - u32 session_unlock_count = 0; - u32 points = 0; - }; std::unordered_map m_unlock_map; Common::WorkQueueThread> m_queue;