Achievements: Switch to rc_client
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
add_library(core
|
||||
achievements.cpp
|
||||
achievements.h
|
||||
analog_controller.cpp
|
||||
analog_controller.h
|
||||
@@ -123,7 +124,7 @@ target_precompile_headers(core PRIVATE "pch.h")
|
||||
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(core PUBLIC Threads::Threads common util zlib)
|
||||
target_link_libraries(core PRIVATE stb xxhash imgui rapidjson)
|
||||
target_link_libraries(core PRIVATE stb xxhash imgui rapidjson rcheevos)
|
||||
|
||||
if(${CPU_ARCH} STREQUAL "x64")
|
||||
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../dep/xbyak/xbyak")
|
||||
@@ -154,14 +155,6 @@ else()
|
||||
message("Not building recompiler")
|
||||
endif()
|
||||
|
||||
if(ENABLE_CHEEVOS)
|
||||
target_sources(core PRIVATE
|
||||
achievements.cpp
|
||||
)
|
||||
target_compile_definitions(core PUBLIC -DWITH_CHEEVOS=1)
|
||||
target_link_libraries(core PRIVATE rcheevos rapidjson)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DISCORD_PRESENCE)
|
||||
target_compile_definitions(core PUBLIC -DWITH_DISCORD_PRESENCE=1)
|
||||
target_link_libraries(core PRIVATE discord-rpc)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,105 +3,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "common/string.h"
|
||||
#include "common/types.h"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class Error;
|
||||
class StateWrapper;
|
||||
class CDImage;
|
||||
|
||||
struct Settings;
|
||||
|
||||
namespace Achievements {
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
|
||||
enum class AchievementCategory : u8
|
||||
enum class LoginRequestReason
|
||||
{
|
||||
Local = 0,
|
||||
Core = 3,
|
||||
Unofficial = 5
|
||||
UserInitiated,
|
||||
TokenInvalid,
|
||||
};
|
||||
|
||||
struct Achievement
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string memaddr;
|
||||
std::string badge_name;
|
||||
|
||||
// badge paths are mutable because they're resolved when they're needed.
|
||||
mutable std::string locked_badge_path;
|
||||
mutable std::string unlocked_badge_path;
|
||||
|
||||
u32 points;
|
||||
AchievementCategory category;
|
||||
bool locked;
|
||||
bool active;
|
||||
bool primed;
|
||||
};
|
||||
|
||||
struct Leaderboard
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
int format;
|
||||
};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
std::string user;
|
||||
std::string formatted_score;
|
||||
time_t submitted;
|
||||
u32 rank;
|
||||
bool is_self;
|
||||
};
|
||||
|
||||
// RAIntegration only exists for Windows, so no point checking it on other platforms.
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
|
||||
bool IsUsingRAIntegration();
|
||||
|
||||
#else
|
||||
|
||||
static ALWAYS_INLINE bool IsUsingRAIntegration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
bool IsUnofficialTestModeActive();
|
||||
bool IsRichPresenceEnabled();
|
||||
bool HasActiveGame();
|
||||
|
||||
u32 GetGameID();
|
||||
|
||||
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
|
||||
void Initialize();
|
||||
/// Initializes the RetroAchievments client.
|
||||
bool Initialize();
|
||||
|
||||
/// Updates achievements settings.
|
||||
void UpdateSettings(const Settings& old_config);
|
||||
void ResetRuntime();
|
||||
|
||||
/// Resets the internal state of all achievement tracking. Call on system reset.
|
||||
void ResetClient();
|
||||
|
||||
/// 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.
|
||||
bool Shutdown();
|
||||
bool Shutdown(bool allow_cancel);
|
||||
|
||||
/// Called when the system is being paused and resumed.
|
||||
void OnSystemPaused(bool paused);
|
||||
@@ -110,60 +49,86 @@ void OnSystemPaused(bool paused);
|
||||
void FrameUpdate();
|
||||
|
||||
/// Called when the system is paused, because FrameUpdate() won't be getting called.
|
||||
void ProcessPendingHTTPRequests();
|
||||
void IdleUpdate();
|
||||
|
||||
/// Saves/loads state.
|
||||
bool DoState(StateWrapper& sw);
|
||||
|
||||
/// Returns true if the current game has any achievements or leaderboards.
|
||||
/// Does not need to have the lock held.
|
||||
bool SafeHasAchievementsOrLeaderboards();
|
||||
/// 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);
|
||||
|
||||
const std::string& GetUsername();
|
||||
const std::string& GetRichPresenceString();
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
/// Logs out of RetroAchievements, clearing any credentials.
|
||||
void Logout();
|
||||
|
||||
/// Called when the system changes game, or is booting.
|
||||
void GameChanged(const std::string& path, CDImage* image);
|
||||
|
||||
/// Re-enables hardcode mode if it is enabled in the settings.
|
||||
bool ResetChallengeMode();
|
||||
bool ResetHardcoreMode();
|
||||
|
||||
/// Forces hardcore mode off until next reset.
|
||||
void DisableChallengeMode();
|
||||
void DisableHardcoreMode();
|
||||
|
||||
/// Prompts the user to disable hardcore mode, if they agree, returns true.
|
||||
bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
bool ConfirmHardcoreModeDisable(const char* trigger);
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
bool ChallengeModeActive();
|
||||
/// 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();
|
||||
|
||||
/// Returns true if the current game has any leaderboards.
|
||||
bool HasLeaderboards();
|
||||
|
||||
/// Returns true if the game supports rich presence.
|
||||
bool HasRichPresence();
|
||||
|
||||
/// Returns the current rich presence string.
|
||||
/// Should be called with the lock held.
|
||||
const std::string& GetRichPresenceString();
|
||||
|
||||
/// Returns the RetroAchievements title for the current game.
|
||||
/// Should be called with the lock held.
|
||||
const std::string& GetGameTitle();
|
||||
const std::string& GetGameIcon();
|
||||
|
||||
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
|
||||
u32 GetUnlockedAchiementCount();
|
||||
u32 GetAchievementCount();
|
||||
u32 GetMaximumPointsForGame();
|
||||
u32 GetCurrentPointsForGame();
|
||||
/// Clears all cached state used to render the UI.
|
||||
void ClearUIState();
|
||||
|
||||
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
|
||||
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
|
||||
const Leaderboard* GetLeaderboardByID(u32 id);
|
||||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
u32 GetPrimedAchievementCount();
|
||||
/// Draws ImGui overlays when not paused.
|
||||
void DrawGameOverlays();
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
TinyString GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(const Achievement& achievement, bool download_if_missing = true,
|
||||
bool force_unlocked_icon = false);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
/// Draws ImGui overlays when paused.
|
||||
void DrawPauseMenuOverlays();
|
||||
|
||||
/// 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();
|
||||
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
/// Prevents the internal implementation from being used. Instead, RAIntegration will be
|
||||
/// called into when achievement-related events occur.
|
||||
void SwitchToRAIntegration();
|
||||
|
||||
namespace RAIntegration {
|
||||
@@ -173,46 +138,20 @@ std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
|
||||
void ActivateMenuItem(int item);
|
||||
} // namespace RAIntegration
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Make noops when compiling without cheevos.
|
||||
static inline bool ConfirmSystemReset()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline void ResetRuntime()
|
||||
{
|
||||
}
|
||||
static inline bool DoState(StateWrapper& sw)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static constexpr inline bool ChallengeModeActive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool ResetChallengeMode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void DisableChallengeMode()
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool ConfirmChallengeModeDisable(const char* trigger)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Achievements
|
||||
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host {
|
||||
/// 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.
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
|
||||
/// Called whenever hardcore mode is toggled.
|
||||
void OnAchievementsHardcoreModeChanged();
|
||||
} // namespace Host
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WITH_CHEEVOS=1;WITH_DISCORD_PRESENCE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WITH_DISCORD_PRESENCE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="('$(Platform)'!='ARM64')">WITH_RAINTEGRATION=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="('$(Platform)'=='x64' Or '$(Platform)'=='ARM' Or '$(Platform)'=='ARM64')">WITH_RECOMPILER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="('$(Platform)'=='x64' Or '$(Platform)'=='ARM64')">WITH_MMAP_FASTMEM=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class GPUTexture;
|
||||
class String;
|
||||
|
||||
struct Settings;
|
||||
|
||||
@@ -23,11 +23,15 @@ void OnSystemDestroyed();
|
||||
void OnRunningGameChanged();
|
||||
void OpenPauseMenu();
|
||||
bool OpenAchievementsWindow();
|
||||
bool IsAchievementsWindowOpen();
|
||||
bool OpenLeaderboardsWindow();
|
||||
bool IsLeaderboardsWindowOpen();
|
||||
void ReturnToMainWindow();
|
||||
|
||||
void Shutdown();
|
||||
void Render();
|
||||
void InvalidateCoverCache();
|
||||
void TimeToPrintableString(String* str, time_t t);
|
||||
|
||||
// Returns true if the message has been dismissed.
|
||||
bool DrawErrorWindow(const char* message);
|
||||
|
||||
@@ -160,7 +160,7 @@ DEFINE_HOTKEY("Screenshot", TRANSLATE_NOOP("Hotkeys", "General"), TRANSLATE_NOOP
|
||||
System::SaveScreenshot();
|
||||
})
|
||||
|
||||
#if !defined(__ANDROID__) && defined(WITH_CHEEVOS)
|
||||
#if !defined(__ANDROID__)
|
||||
DEFINE_HOTKEY("OpenAchievements", TRANSLATE_NOOP("Hotkeys", "General"),
|
||||
TRANSLATE_NOOP("Hotkeys", "Open Achievement List"), [](s32 pressed) {
|
||||
if (!pressed)
|
||||
@@ -184,7 +184,7 @@ DEFINE_HOTKEY("OpenLeaderboards", TRANSLATE_NOOP("Hotkeys", "General"),
|
||||
}
|
||||
}
|
||||
})
|
||||
#endif // !defined(__ANDROID__) && defined(WITH_CHEEVOS)
|
||||
#endif // !defined(__ANDROID__)
|
||||
|
||||
DEFINE_HOTKEY("Reset", TRANSLATE_NOOP("Hotkeys", "System"), TRANSLATE_NOOP("Hotkeys", "Reset System"), [](s32 pressed) {
|
||||
if (!pressed)
|
||||
|
||||
@@ -365,16 +365,20 @@ void Settings::Load(SettingsInterface& si)
|
||||
memory_card_use_playlist_title = si.GetBoolValue("MemoryCards", "UsePlaylistTitle", true);
|
||||
|
||||
achievements_enabled = si.GetBoolValue("Cheevos", "Enabled", false);
|
||||
achievements_test_mode = si.GetBoolValue("Cheevos", "TestMode", false);
|
||||
achievements_hardcore_mode = si.GetBoolValue("Cheevos", "ChallengeMode", false);
|
||||
achievements_notifications = si.GetBoolValue("Cheevos", "Notifications", true);
|
||||
achievements_leaderboard_notifications = si.GetBoolValue("Cheevos", "LeaderboardNotifications", true);
|
||||
achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true);
|
||||
achievements_overlays = si.GetBoolValue("Cheevos", "Overlays", true);
|
||||
achievements_encore_mode = si.GetBoolValue("Cheevos", "EncoreMode", false);
|
||||
achievements_spectator_mode = si.GetBoolValue("Cheevos", "SpectatorMode", false);
|
||||
achievements_unofficial_test_mode = si.GetBoolValue("Cheevos", "UnofficialTestMode", false);
|
||||
achievements_use_first_disc_from_playlist = si.GetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", true);
|
||||
achievements_rich_presence = si.GetBoolValue("Cheevos", "RichPresence", true);
|
||||
achievements_challenge_mode = si.GetBoolValue("Cheevos", "ChallengeMode", false);
|
||||
achievements_leaderboards = si.GetBoolValue("Cheevos", "Leaderboards", true);
|
||||
achievements_notifications = si.GetBoolValue("Cheevos", "Notifications", true);
|
||||
achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true);
|
||||
achievements_primed_indicators = si.GetBoolValue("Cheevos", "PrimedIndicators", true);
|
||||
achievements_use_raintegration = si.GetBoolValue("Cheevos", "UseRAIntegration", false);
|
||||
achievements_notification_duration =
|
||||
si.GetFloatValue("Cheevos", "NotificationsDuration", DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME);
|
||||
achievements_leaderboard_duration =
|
||||
si.GetFloatValue("Cheevos", "LeaderboardsDuration", DEFAULT_LEADERBOARD_NOTIFICATION_TIME);
|
||||
|
||||
log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str())
|
||||
.value_or(DEFAULT_LOG_LEVEL);
|
||||
@@ -564,16 +568,18 @@ void Settings::Save(SettingsInterface& si) const
|
||||
si.SetStringValue("ControllerPorts", "MultitapMode", GetMultitapModeName(multitap_mode));
|
||||
|
||||
si.SetBoolValue("Cheevos", "Enabled", achievements_enabled);
|
||||
si.SetBoolValue("Cheevos", "TestMode", achievements_test_mode);
|
||||
si.SetBoolValue("Cheevos", "ChallengeMode", achievements_hardcore_mode);
|
||||
si.SetBoolValue("Cheevos", "Notifications", achievements_notifications);
|
||||
si.SetBoolValue("Cheevos", "LeaderboardNotifications", achievements_leaderboard_notifications);
|
||||
si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects);
|
||||
si.SetBoolValue("Cheevos", "Overlays", achievements_overlays);
|
||||
si.SetBoolValue("Cheevos", "EncoreMode", achievements_encore_mode);
|
||||
si.SetBoolValue("Cheevos", "SpectatorMode", achievements_spectator_mode);
|
||||
si.SetBoolValue("Cheevos", "UnofficialTestMode", achievements_unofficial_test_mode);
|
||||
si.SetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", achievements_use_first_disc_from_playlist);
|
||||
si.SetBoolValue("Cheevos", "RichPresence", achievements_rich_presence);
|
||||
si.SetBoolValue("Cheevos", "ChallengeMode", achievements_challenge_mode);
|
||||
si.SetBoolValue("Cheevos", "Leaderboards", achievements_leaderboards);
|
||||
si.SetBoolValue("Cheevos", "Notifications", achievements_notifications);
|
||||
si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects);
|
||||
si.SetBoolValue("Cheevos", "PrimedIndicators", achievements_primed_indicators);
|
||||
si.SetBoolValue("Cheevos", "UseRAIntegration", achievements_use_raintegration);
|
||||
si.SetFloatValue("Cheevos", "NotificationsDuration", achievements_notification_duration);
|
||||
si.SetFloatValue("Cheevos", "LeaderboardsDuration", achievements_leaderboard_duration);
|
||||
|
||||
si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level));
|
||||
si.SetStringValue("Logging", "LogFilter", log_filter.c_str());
|
||||
@@ -696,7 +702,7 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
||||
}
|
||||
|
||||
// if challenge mode is enabled, disable things like rewind since they use save states
|
||||
if (Achievements::ChallengeModeActive())
|
||||
if (Achievements::IsHardcoreModeActive())
|
||||
{
|
||||
g_settings.emulation_speed =
|
||||
(g_settings.emulation_speed != 0.0f) ? std::max(g_settings.emulation_speed, 1.0f) : 0.0f;
|
||||
|
||||
@@ -180,16 +180,18 @@ struct Settings
|
||||
|
||||
// achievements
|
||||
bool achievements_enabled = false;
|
||||
bool achievements_test_mode = false;
|
||||
bool achievements_hardcore_mode = false;
|
||||
bool achievements_notifications = true;
|
||||
bool achievements_leaderboard_notifications = true;
|
||||
bool achievements_sound_effects = true;
|
||||
bool achievements_overlays = true;
|
||||
bool achievements_encore_mode = false;
|
||||
bool achievements_spectator_mode = false;
|
||||
bool achievements_unofficial_test_mode = false;
|
||||
bool achievements_use_first_disc_from_playlist = true;
|
||||
bool achievements_rich_presence = true;
|
||||
bool achievements_challenge_mode = false;
|
||||
bool achievements_leaderboards = true;
|
||||
bool achievements_notifications = true;
|
||||
bool achievements_sound_effects = true;
|
||||
bool achievements_primed_indicators = true;
|
||||
bool achievements_use_raintegration = false;
|
||||
float achievements_notification_duration = DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME;
|
||||
float achievements_leaderboard_duration = DEFAULT_LEADERBOARD_NOTIFICATION_TIME;
|
||||
|
||||
struct DebugSettings
|
||||
{
|
||||
@@ -473,6 +475,9 @@ struct Settings
|
||||
static constexpr MemoryCardType DEFAULT_MEMORY_CARD_2_TYPE = MemoryCardType::None;
|
||||
static constexpr MultitapMode DEFAULT_MULTITAP_MODE = MultitapMode::Disabled;
|
||||
|
||||
static constexpr float DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME = 10.0f;
|
||||
static constexpr float DEFAULT_LEADERBOARD_NOTIFICATION_TIME = 10.0f;
|
||||
|
||||
static constexpr LOGLEVEL DEFAULT_LOG_LEVEL = LOGLEVEL_INFO;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
|
||||
@@ -135,7 +135,6 @@ static void SetTimerResolutionIncreased(bool enabled);
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
static void InitializeDiscordPresence();
|
||||
static void ShutdownDiscordPresence();
|
||||
static void UpdateDiscordPresence(bool rich_presence_only);
|
||||
static void PollDiscordPresence();
|
||||
#endif
|
||||
} // namespace System
|
||||
@@ -233,11 +232,7 @@ static u32 s_runahead_replay_frames = 0;
|
||||
static u64 s_session_start_time = 0;
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
// discord rich presence
|
||||
static bool s_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
static std::string s_discord_presence_cheevos_string;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static TinyString GetTimestampStringForFileName()
|
||||
@@ -250,14 +245,12 @@ void System::Internal::ProcessStartup()
|
||||
// This will call back to Host::LoadSettings() -> ReloadSources().
|
||||
LoadSettings(false);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
if (Host::GetBaseBoolSettingValue("Cheevos", "UseRAIntegration", false))
|
||||
Achievements::SwitchToRAIntegration();
|
||||
#endif
|
||||
if (g_settings.achievements_enabled)
|
||||
Achievements::Initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
void System::Internal::ProcessShutdown()
|
||||
@@ -266,9 +259,7 @@ void System::Internal::ProcessShutdown()
|
||||
ShutdownDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::Shutdown();
|
||||
#endif
|
||||
Achievements::Shutdown(false);
|
||||
|
||||
InputManager::CloseSources();
|
||||
}
|
||||
@@ -281,9 +272,7 @@ void System::Internal::IdlePollUpdate()
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::ProcessPendingHTTPRequests();
|
||||
#endif
|
||||
Achievements::IdleUpdate();
|
||||
}
|
||||
|
||||
System::State System::GetState()
|
||||
@@ -1068,13 +1057,11 @@ void System::ResetSystem()
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (!Achievements::ConfirmSystemReset())
|
||||
return;
|
||||
|
||||
if (Achievements::ResetChallengeMode())
|
||||
if (Achievements::ResetHardcoreMode())
|
||||
ApplySettings(false);
|
||||
#endif
|
||||
|
||||
InternalReset();
|
||||
ResetPerformanceCounters();
|
||||
@@ -1096,9 +1083,7 @@ void System::PauseSystem(bool paused)
|
||||
|
||||
InputManager::PauseVibration();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(true);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
@@ -1110,9 +1095,7 @@ void System::PauseSystem(bool paused)
|
||||
{
|
||||
FullscreenUI::OnSystemResumed();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(false);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
@@ -1131,13 +1114,11 @@ bool System::LoadState(const char* filename)
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::ChallengeModeActive() &&
|
||||
!Achievements::ConfirmChallengeModeDisable(TRANSLATE("Achievements", "Loading state")))
|
||||
if (Achievements::IsHardcoreModeActive() &&
|
||||
!Achievements::ConfirmHardcoreModeDisable(TRANSLATE("Achievements", "Loading state")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
Common::Timer load_timer;
|
||||
|
||||
@@ -1265,11 +1246,11 @@ bool System::BootSystem(SystemBootParameters parameters)
|
||||
(do_exe_boot ? GetRegionForExe(parameters.filename.c_str()) : GetRegionForPsf(parameters.filename.c_str()));
|
||||
Log_InfoPrintf("EXE/PSF Region: %s", Settings::GetDiscRegionDisplayName(file_region));
|
||||
s_region = GetConsoleRegionForDiscRegion(file_region);
|
||||
if (do_psf_boot)
|
||||
psf_boot = std::move(parameters.filename);
|
||||
else
|
||||
exe_boot = std::move(parameters.filename);
|
||||
}
|
||||
if (do_psf_boot)
|
||||
psf_boot = std::move(parameters.filename);
|
||||
else
|
||||
exe_boot = std::move(parameters.filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1350,17 +1331,15 @@ bool System::BootSystem(SystemBootParameters parameters)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
// Check for resuming with hardcore mode.
|
||||
if (!parameters.save_state.empty() && Achievements::ChallengeModeActive() &&
|
||||
!Achievements::ConfirmChallengeModeDisable(TRANSLATE("Achievements", "Resuming state")))
|
||||
if (!parameters.save_state.empty() && Achievements::IsHardcoreModeActive() &&
|
||||
!Achievements::ConfirmHardcoreModeDisable(TRANSLATE("Achievements", "Resuming state")))
|
||||
{
|
||||
s_state = State::Shutdown;
|
||||
ClearRunningGame();
|
||||
Host::OnSystemDestroyed();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Load BIOS image.
|
||||
if (!LoadBIOS(parameters.override_bios))
|
||||
@@ -1683,12 +1662,10 @@ void System::ClearRunningGame()
|
||||
|
||||
Host::OnGameChanged(s_running_game_path, s_running_game_serial, s_running_game_title);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::GameChanged(s_running_game_path, nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(false);
|
||||
UpdateDiscordPresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1760,10 +1737,8 @@ void System::FrameDone()
|
||||
if (s_cheat_list)
|
||||
s_cheat_list->Apply();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::FrameUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
@@ -2131,23 +2106,13 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
|
||||
if (!sw.DoMarker("Cheevos"))
|
||||
return false;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (!Achievements::DoState(sw))
|
||||
return false;
|
||||
#else
|
||||
// if we compiled without cheevos, we need to toss out the data from states which were
|
||||
u32 data_size = 0;
|
||||
sw.Do(&data_size);
|
||||
if (data_size > 0)
|
||||
sw.SkipBytes(data_size);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WITH_CHEEVOS
|
||||
// loading an old state without cheevos, so reset the runtime
|
||||
Achievements::ResetRuntime();
|
||||
#endif
|
||||
Achievements::ResetClient();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2208,9 +2173,7 @@ void System::InternalReset()
|
||||
TimingEvents::Reset();
|
||||
ResetPerformanceCounters();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::ResetRuntime();
|
||||
#endif
|
||||
Achievements::ResetClient();
|
||||
}
|
||||
|
||||
std::string System::GetMediaPathFromSaveState(const char* path)
|
||||
@@ -2352,15 +2315,13 @@ bool System::LoadStateFromStream(ByteStream* state, bool update_display, bool ig
|
||||
|
||||
ClearMemorySaveStates();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
// Updating game/loading settings can turn on hardcore mode. Catch this.
|
||||
if (Achievements::ChallengeModeActive())
|
||||
if (Achievements::IsHardcoreModeActive())
|
||||
{
|
||||
Host::AddKeyedOSDMessage("challenge_mode_reset",
|
||||
TRANSLATE_STR("Achievements", "Hardcore mode disabled by state switch."), 10.0f);
|
||||
Achievements::DisableChallengeMode();
|
||||
Achievements::DisableHardcoreMode();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!state->SeekAbsolute(header.offset_to_data))
|
||||
return false;
|
||||
@@ -2720,10 +2681,8 @@ void System::SetRewindState(bool enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::ChallengeModeActive() && !Achievements::ConfirmChallengeModeDisable("Rewinding"))
|
||||
if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Rewinding"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
System::SetRewinding(enabled);
|
||||
UpdateSpeedLimiterState();
|
||||
@@ -2734,10 +2693,8 @@ void System::DoFrameStep()
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::ChallengeModeActive() && !Achievements::ConfirmChallengeModeDisable("Frame stepping"))
|
||||
if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Frame stepping"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
s_frame_step_request = true;
|
||||
PauseSystem(false);
|
||||
@@ -2748,10 +2705,8 @@ void System::DoToggleCheats()
|
||||
if (!System::IsValid())
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::ChallengeModeActive() && !Achievements::ConfirmChallengeModeDisable("Toggling cheats"))
|
||||
if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Toggling cheats"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
CheatList* cl = GetCheatList();
|
||||
if (!cl)
|
||||
@@ -3341,18 +3296,16 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
||||
|
||||
g_texture_replacements.SetGameID(s_running_game_serial);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (booting)
|
||||
Achievements::ResetChallengeMode();
|
||||
Achievements::ResetHardcoreMode();
|
||||
|
||||
Achievements::GameChanged(s_running_game_path, image);
|
||||
#endif
|
||||
|
||||
UpdateGameSettingsLayer();
|
||||
ApplySettings(true);
|
||||
|
||||
s_cheat_list.reset();
|
||||
if (g_settings.auto_load_cheats && !Achievements::ChallengeModeActive())
|
||||
if (g_settings.auto_load_cheats && !Achievements::IsHardcoreModeActive())
|
||||
LoadCheatListFromGameTitle();
|
||||
|
||||
if (s_running_game_serial != prev_serial)
|
||||
@@ -3361,7 +3314,7 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
||||
SaveStateSelectorUI::RefreshList();
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(false);
|
||||
UpdateDiscordPresence();
|
||||
#endif
|
||||
|
||||
Host::OnGameChanged(s_running_game_path, s_running_game_serial, s_running_game_title);
|
||||
@@ -3732,9 +3685,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||
if (g_settings.multitap_mode != old_settings.multitap_mode)
|
||||
UpdateMultitaps();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::UpdateSettings(old_settings);
|
||||
#endif
|
||||
|
||||
FullscreenUI::CheckForConfigChanges(old_settings);
|
||||
|
||||
@@ -4417,7 +4368,7 @@ bool System::LoadCheatList(const char* filename)
|
||||
bool System::LoadCheatListFromGameTitle()
|
||||
{
|
||||
// Called when booting, needs to test for shutdown.
|
||||
if (IsShutdown() || Achievements::ChallengeModeActive())
|
||||
if (IsShutdown() || Achievements::IsHardcoreModeActive())
|
||||
return false;
|
||||
|
||||
const std::string filename(GetCheatFileName());
|
||||
@@ -4429,7 +4380,7 @@ bool System::LoadCheatListFromGameTitle()
|
||||
|
||||
bool System::LoadCheatListFromDatabase()
|
||||
{
|
||||
if (IsShutdown() || s_running_game_serial.empty() || Achievements::ChallengeModeActive())
|
||||
if (IsShutdown() || s_running_game_serial.empty() || Achievements::IsHardcoreModeActive())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<CheatList> cl = std::make_unique<CheatList>();
|
||||
@@ -4775,7 +4726,7 @@ void System::InitializeDiscordPresence()
|
||||
Discord_Initialize("705325712680288296", &handlers, 0, nullptr);
|
||||
s_discord_presence_active = true;
|
||||
|
||||
UpdateDiscordPresence(false);
|
||||
UpdateDiscordPresence();
|
||||
}
|
||||
|
||||
void System::ShutdownDiscordPresence()
|
||||
@@ -4786,31 +4737,13 @@ void System::ShutdownDiscordPresence()
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
s_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
s_discord_presence_cheevos_string.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void System::UpdateDiscordPresence(bool rich_presence_only)
|
||||
void System::UpdateDiscordPresence()
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
// Update only if RetroAchievements rich presence has changed
|
||||
const std::string& new_rich_presence = Achievements::GetRichPresenceString();
|
||||
if (new_rich_presence == s_discord_presence_cheevos_string && rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
s_discord_presence_cheevos_string = new_rich_presence;
|
||||
#else
|
||||
if (rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields
|
||||
DiscordRichPresence rp = {};
|
||||
rp.largeImageKey = "duckstation_logo";
|
||||
@@ -4827,22 +4760,19 @@ void System::UpdateDiscordPresence(bool rich_presence_only)
|
||||
details_string.AppendString("No Game Running");
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
SmallString state_string;
|
||||
// Trim to 128 bytes as per Discord-RPC requirements
|
||||
if (s_discord_presence_cheevos_string.length() >= 128)
|
||||
{
|
||||
// 124 characters + 3 dots + null terminator
|
||||
state_string = s_discord_presence_cheevos_string.substr(0, 124);
|
||||
state_string.AppendString("...");
|
||||
}
|
||||
else
|
||||
{
|
||||
state_string = s_discord_presence_cheevos_string;
|
||||
}
|
||||
|
||||
rp.state = state_string;
|
||||
#endif
|
||||
if (Achievements::HasRichPresence())
|
||||
{
|
||||
const auto lock = Achievements::GetLock();
|
||||
const std::string_view richp = Achievements::GetRichPresenceString();
|
||||
if (richp.length() >= 128)
|
||||
state_string.AppendFmtString("{}...", richp.substr(0, 124));
|
||||
else
|
||||
state_string.Assign(richp);
|
||||
|
||||
rp.state = state_string;
|
||||
}
|
||||
rp.details = details_string;
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
@@ -4853,8 +4783,6 @@ void System::PollDiscordPresence()
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
UpdateDiscordPresence(true);
|
||||
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
|
||||
@@ -479,6 +479,11 @@ void UpdateMemorySaveStateSettings();
|
||||
bool LoadRewindState(u32 skip_saves = 0, bool consume_state = true);
|
||||
void SetRunaheadReplayFlag();
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
/// Called when rich presence changes.
|
||||
void UpdateDiscordPresence();
|
||||
#endif
|
||||
|
||||
namespace Internal {
|
||||
/// Called on process startup.
|
||||
void ProcessStartup();
|
||||
|
||||
Reference in New Issue
Block a user