Duckstation/src/core/achievements.h

183 lines
5.5 KiB
C
Raw Normal View History

2023-08-23 12:06:48 +00:00
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
2023-08-23 12:06:48 +00:00
2023-09-20 13:49:14 +00:00
#include "common/small_string.h"
#include "common/types.h"
#include <functional>
2023-09-30 05:17:18 +00:00
#include <mutex>
2023-08-13 06:28:28 +00:00
#include <string>
2023-08-23 12:06:48 +00:00
#include <utility>
#include <vector>
2023-08-13 06:28:28 +00:00
2023-10-31 15:32:29 +00:00
struct rc_client_t;
2023-09-07 10:13:48 +00:00
class Error;
class StateWrapper;
class CDImage;
2023-09-07 10:13:48 +00:00
struct Settings;
2023-08-23 12:06:48 +00:00
2023-09-07 10:13:48 +00:00
namespace Achievements {
2023-08-23 12:06:48 +00:00
2023-09-07 10:13:48 +00:00
enum class LoginRequestReason
2023-08-23 12:06:48 +00:00
{
2023-09-07 10:13:48 +00:00
UserInitiated,
TokenInvalid,
2023-08-23 12:06:48 +00:00
};
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
std::unique_lock<std::recursive_mutex> GetLock();
2023-10-31 15:32:29 +00:00
/// Returns the rc_client instance. Should have the lock held.
rc_client_t* GetClient();
2023-09-07 10:13:48 +00:00
/// Initializes the RetroAchievments client.
bool Initialize();
/// Updates achievements settings.
2023-08-23 12:06:48 +00:00
void UpdateSettings(const Settings& old_config);
2023-09-07 10:13:48 +00:00
/// Resets the internal state of all achievement tracking. Call on system reset.
void ResetClient();
2023-08-23 12:06:48 +00:00
/// Called when the system is being reset. If it returns false, the reset should be aborted.
bool ConfirmSystemReset();
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
2023-09-07 10:13:48 +00:00
bool Shutdown(bool allow_cancel);
2023-08-23 12:06:48 +00:00
/// Called when the system is being paused and resumed.
void OnSystemPaused(bool paused);
/// Called once a frame at vsync time on the CPU thread.
void FrameUpdate();
/// Called when the system is paused, because FrameUpdate() won't be getting called.
2023-09-07 10:13:48 +00:00
void IdleUpdate();
2023-08-23 12:06:48 +00:00
2023-10-31 15:32:29 +00:00
/// Returns true if idle updates are necessary (e.g. outstanding requests).
bool NeedsIdleUpdate();
2023-08-23 12:06:48 +00:00
/// Saves/loads state.
bool DoState(StateWrapper& sw);
2023-09-07 10:13:48 +00:00
/// Attempts to log in to RetroAchievements using the specified credentials.
/// If the login is successful, the token returned by the server will be saved.
bool Login(const char* username, const char* password, Error* error);
2023-08-23 12:06:48 +00:00
2023-09-07 10:13:48 +00:00
/// Logs out of RetroAchievements, clearing any credentials.
2023-08-23 12:06:48 +00:00
void Logout();
2023-09-07 10:13:48 +00:00
/// Called when the system changes game, or is booting.
2023-08-23 12:06:48 +00:00
void GameChanged(const std::string& path, CDImage* image);
2024-02-06 13:24:33 +00:00
/// Re-enables hardcore mode if it is enabled in the settings.
2023-09-07 10:13:48 +00:00
bool ResetHardcoreMode();
/// Forces hardcore mode off until next reset.
2023-09-07 10:13:48 +00:00
void DisableHardcoreMode();
/// Prompts the user to disable hardcore mode, if they agree, returns true.
2023-09-07 10:13:48 +00:00
bool ConfirmHardcoreModeDisable(const char* trigger);
void ConfirmHardcoreModeDisableAsync(const char* trigger, std::function<void(bool)> callback);
2023-09-07 10:13:48 +00:00
/// Returns true if hardcore mode is active, and functionality should be restricted.
bool IsHardcoreModeActive();
/// RAIntegration only exists for Windows, so no point checking it on other platforms.
bool IsUsingRAIntegration();
/// Returns true if the achievement system is active. Achievements can be active without a valid client.
bool IsActive();
/// Returns true if RetroAchievements game data has been loaded.
bool HasActiveGame();
/// Returns the RetroAchievements ID for the current game.
u32 GetGameID();
/// Returns true if the current game has any achievements or leaderboards.
bool HasAchievementsOrLeaderboards();
2023-09-18 12:29:47 +00:00
/// Returns true if the current game has any leaderboards.
bool HasAchievements();
2023-09-07 10:13:48 +00:00
/// Returns true if the current game has any leaderboards.
bool HasLeaderboards();
/// Returns true if the game supports rich presence.
bool HasRichPresence();
2023-09-07 10:13:48 +00:00
/// Returns the current rich presence string.
/// Should be called with the lock held.
const std::string& GetRichPresenceString();
2023-08-23 12:06:48 +00:00
2023-09-07 10:13:48 +00:00
/// Returns the RetroAchievements title for the current game.
/// Should be called with the lock held.
2023-08-23 12:06:48 +00:00
const std::string& GetGameTitle();
2023-09-07 10:13:48 +00:00
/// Returns the logged-in user name.
const char* GetLoggedInUserName();
/// Returns the path to the user's profile avatar.
/// Should be called with the lock held.
std::string GetLoggedInUserBadgePath();
2023-09-07 10:13:48 +00:00
/// Clears all cached state used to render the UI.
void ClearUIState();
/// Draws ImGui overlays when not paused.
void DrawGameOverlays();
/// Draws ImGui overlays when paused.
void DrawPauseMenuOverlays();
2023-10-31 15:32:29 +00:00
#ifndef __ANDROID__
2023-09-07 10:13:48 +00:00
/// Queries the achievement list, and if no achievements are available, returns false.
bool PrepareAchievementsWindow();
/// Renders the achievement list.
void DrawAchievementsWindow();
/// Queries the leaderboard list, and if no leaderboards are available, returns false.
bool PrepareLeaderboardsWindow();
/// Renders the leaderboard list.
void DrawLeaderboardsWindow();
2023-08-23 12:06:48 +00:00
2023-10-31 15:32:29 +00:00
#endif // __ANDROID__
#ifdef ENABLE_RAINTEGRATION
2023-09-07 10:13:48 +00:00
/// Prevents the internal implementation from being used. Instead, RAIntegration will be
/// called into when achievement-related events occur.
2023-08-23 12:06:48 +00:00
void SwitchToRAIntegration();
namespace RAIntegration {
void MainWindowChanged(void* new_handle);
void GameChanged();
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
void ActivateMenuItem(int item);
} // namespace RAIntegration
#endif
} // namespace Achievements
2023-08-23 12:06:48 +00:00
/// Functions implemented in the frontend.
namespace Host {
2023-09-07 10:13:48 +00:00
/// Called if the big picture UI requests achievements login, or token login fails.
void OnAchievementsLoginRequested(Achievements::LoginRequestReason reason);
/// Called when achievements login completes.
void OnAchievementsLoginSuccess(const char* display_name, u32 points, u32 sc_points, u32 unread_messages);
/// Called whenever game details or rich presence information is updated.
/// Implementers can assume the lock is held when this is called.
2023-08-23 12:06:48 +00:00
void OnAchievementsRefreshed();
2023-09-07 10:13:48 +00:00
/// Called whenever hardcore mode is toggled.
2023-09-18 12:29:47 +00:00
void OnAchievementsHardcoreModeChanged(bool enabled);
2023-08-23 12:06:48 +00:00
} // namespace Host