achievements.h (5622B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR PolyForm-Strict-1.0.0) 3 4 #pragma once 5 6 #include "common/small_string.h" 7 #include "common/types.h" 8 9 #include <functional> 10 #include <mutex> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 struct rc_client_t; 16 17 class Error; 18 class StateWrapper; 19 class CDImage; 20 21 struct Settings; 22 23 namespace Achievements { 24 25 enum class LoginRequestReason 26 { 27 UserInitiated, 28 TokenInvalid, 29 }; 30 31 /// Acquires the achievements lock. Must be held when accessing any achievement state from another thread. 32 std::unique_lock<std::recursive_mutex> GetLock(); 33 34 /// Returns the rc_client instance. Should have the lock held. 35 rc_client_t* GetClient(); 36 37 /// Initializes the RetroAchievments client. 38 bool Initialize(); 39 40 /// Updates achievements settings. 41 void UpdateSettings(const Settings& old_config); 42 43 /// Resets the internal state of all achievement tracking. Call on system reset. 44 void ResetClient(); 45 46 /// Called when the system is being reset. If it returns false, the reset should be aborted. 47 bool ConfirmSystemReset(); 48 49 /// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted. 50 bool Shutdown(bool allow_cancel); 51 52 /// Called when the system is being paused and resumed. 53 void OnSystemPaused(bool paused); 54 55 /// Called once a frame at vsync time on the CPU thread. 56 void FrameUpdate(); 57 58 /// Called when the system is paused, because FrameUpdate() won't be getting called. 59 void IdleUpdate(); 60 61 /// Returns true if idle updates are necessary (e.g. outstanding requests). 62 bool NeedsIdleUpdate(); 63 64 /// Saves/loads state. 65 bool DoState(StateWrapper& sw); 66 67 /// Attempts to log in to RetroAchievements using the specified credentials. 68 /// If the login is successful, the token returned by the server will be saved. 69 bool Login(const char* username, const char* password, Error* error); 70 71 /// Logs out of RetroAchievements, clearing any credentials. 72 void Logout(); 73 74 /// Called when the system changes game, or is booting. 75 void GameChanged(const std::string& path, CDImage* image); 76 77 /// Re-enables hardcore mode if it is enabled in the settings. 78 bool ResetHardcoreMode(bool is_booting); 79 80 /// Forces hardcore mode off until next reset. 81 void DisableHardcoreMode(); 82 83 /// Prompts the user to disable hardcore mode, if they agree, returns true. 84 bool ConfirmHardcoreModeDisable(const char* trigger); 85 void ConfirmHardcoreModeDisableAsync(const char* trigger, std::function<void(bool)> callback); 86 87 /// Returns true if hardcore mode is active, and functionality should be restricted. 88 bool IsHardcoreModeActive(); 89 90 /// RAIntegration only exists for Windows, so no point checking it on other platforms. 91 bool IsUsingRAIntegration(); 92 93 /// Returns true if the achievement system is active. Achievements can be active without a valid client. 94 bool IsActive(); 95 96 /// Returns true if RetroAchievements game data has been loaded. 97 bool HasActiveGame(); 98 99 /// Returns the RetroAchievements ID for the current game. 100 u32 GetGameID(); 101 102 /// Returns true if the current game has any achievements or leaderboards. 103 bool HasAchievementsOrLeaderboards(); 104 105 /// Returns true if the current game has any leaderboards. 106 bool HasAchievements(); 107 108 /// Returns true if the current game has any leaderboards. 109 bool HasLeaderboards(); 110 111 /// Returns true if the game supports rich presence. 112 bool HasRichPresence(); 113 114 /// Returns the current rich presence string. 115 /// Should be called with the lock held. 116 const std::string& GetRichPresenceString(); 117 118 /// Returns the RetroAchievements title for the current game. 119 /// Should be called with the lock held. 120 const std::string& GetGameTitle(); 121 122 /// Returns the logged-in user name. 123 const char* GetLoggedInUserName(); 124 125 /// Returns the path to the user's profile avatar. 126 /// Should be called with the lock held. 127 std::string GetLoggedInUserBadgePath(); 128 129 /// Clears all cached state used to render the UI. 130 void ClearUIState(); 131 132 /// Draws ImGui overlays when not paused. 133 void DrawGameOverlays(); 134 135 /// Draws ImGui overlays when paused. 136 void DrawPauseMenuOverlays(); 137 138 #ifndef __ANDROID__ 139 140 /// Queries the achievement list, and if no achievements are available, returns false. 141 bool PrepareAchievementsWindow(); 142 143 /// Renders the achievement list. 144 void DrawAchievementsWindow(); 145 146 /// Queries the leaderboard list, and if no leaderboards are available, returns false. 147 bool PrepareLeaderboardsWindow(); 148 149 /// Renders the leaderboard list. 150 void DrawLeaderboardsWindow(); 151 152 #endif // __ANDROID__ 153 154 #ifdef ENABLE_RAINTEGRATION 155 /// Prevents the internal implementation from being used. Instead, RAIntegration will be 156 /// called into when achievement-related events occur. 157 void SwitchToRAIntegration(); 158 159 namespace RAIntegration { 160 void MainWindowChanged(void* new_handle); 161 void GameChanged(); 162 std::vector<std::tuple<int, std::string, bool>> GetMenuItems(); 163 void ActivateMenuItem(int item); 164 } // namespace RAIntegration 165 #endif 166 } // namespace Achievements 167 168 /// Functions implemented in the frontend. 169 namespace Host { 170 /// Called if the big picture UI requests achievements login, or token login fails. 171 void OnAchievementsLoginRequested(Achievements::LoginRequestReason reason); 172 173 /// Called when achievements login completes. 174 void OnAchievementsLoginSuccess(const char* display_name, u32 points, u32 sc_points, u32 unread_messages); 175 176 /// Called whenever game details or rich presence information is updated. 177 /// Implementers can assume the lock is held when this is called. 178 void OnAchievementsRefreshed(); 179 180 /// Called whenever hardcore mode is toggled. 181 void OnAchievementsHardcoreModeChanged(bool enabled); 182 } // namespace Host