Copy-paste retroachievement support from DuckStation. No fixes yet!

This commit is contained in:
Henrik Rydgård committed 2023-06-26 10:01:40 +02:00
1 parent da1691e4f9
commit 4745999665
5 files changed
+2323 -44

No files matched your search

+3
View File
@@ -62,6 +62,9 @@ enum LOG_TYPE {
SCEMISC,
NUMBER_OF_LOGS, // Must be last
// Temporary aliases
ACHIEVEMENTS = HLE, // TODO: Make a real category
};
enum LOG_LEVELS : int {
+5 -1
View File
@@ -178,7 +178,6 @@ static const ConfigSetting generalSettings[] = {
ConfigSetting("CwCheatRefreshRate", &g_Config.iCwCheatRefreshRate, 77, CfgFlag::PER_GAME),
ConfigSetting("CwCheatScrollPosition", &g_Config.fCwCheatScrollPosition, 0.0f, CfgFlag::PER_GAME),
ConfigSetting("GameListScrollPosition", &g_Config.fGameListScrollPosition, 0.0f, CfgFlag::DEFAULT),
ConfigSetting("EnableRetroAchievements", &g_Config.bEnableRetroAchievements, false, CfgFlag::PER_GAME),
ConfigSetting("ScreenshotsAsPNG", &g_Config.bScreenshotsAsPNG, false, CfgFlag::PER_GAME),
ConfigSetting("UseFFV1", &g_Config.bUseFFV1, false, CfgFlag::DEFAULT),
@@ -265,6 +264,10 @@ static bool DefaultSasThread() {
return cpu_info.num_cores > 1;
}
static const ConfigSetting achievementSettings[] = {
ConfigSetting("Enable", &g_Config.bAchievementsEnable, false, CfgFlag::PER_GAME),
};
static const ConfigSetting cpuSettings[] = {
ConfigSetting("CPUCore", &g_Config.iCpuCore, &DefaultCpuCore, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, CfgFlag::PER_GAME | CfgFlag::REPORT),
@@ -888,6 +891,7 @@ static const ConfigSectionSettings sections[] = {
{"Upgrade", upgradeSettings, ARRAY_SIZE(upgradeSettings)},
{"Theme", themeSettings, ARRAY_SIZE(themeSettings)},
{"VR", vrSettings, ARRAY_SIZE(vrSettings)},
{"Achievements", achievementSettings, ARRAY_SIZE(achievementSettings)},
};
const size_t numSections = ARRAY_SIZE(sections);
+7 -1
View File
@@ -216,7 +216,6 @@ public:
int iAutoLoadSaveState; // 0 = off, 1 = oldest, 2 = newest, >2 = slot number + 3
bool bEnableCheats;
bool bReloadCheats;
bool bEnableRetroAchievements;
int iCwCheatRefreshRate;
float fCwCheatScrollPosition;
float fGameListScrollPosition;
@@ -483,6 +482,13 @@ public:
bool bShowFrameProfiler;
bool bGpuLogProfiler; // Controls the Vulkan logging profiler (profiles textures uploads etc).
// Retro Achievement settings
bool bAchievementsEnable;
bool bAchievementsLeaderboards;
bool bAchievementsTestMode;
bool bAchievementsUnofficialTestMode;
bool bAchievementsRichPresence;
// Various directories. Autoconfigured, not read from ini.
Path currentDirectory; // The directory selected in the game browsing window.
Path defaultCurrentDirectory; // Platform dependent, initialized at startup.
+2135 -25
View File
File diff suppressed because it is too large. Load diff
+173 -17
View File
@@ -1,27 +1,183 @@
// PLEASE NOTE
//
// This is basically a copy/paste of Duckstation's RetroAchievements integration.
// Modifications and deletions have been made where needed.
// Refactoring it into a more PPSSPP-like style may or may not be a good idea -
// it'll make it harder to copy new features from Duckstation :)
#pragma once
#include "ext/rcheevos/include/rcheevos.h"
#include "ext/rcheevos/include/rc_runtime.h"
#include "Common/StringUtils.h"
#include "Common/CommonTypes.h"
enum class RetroState {
NONE,
LOGGED_IN,
#include <functional>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <mutex>
#define ALWAYS_INLINE __forceinline
class CDImage;
class StateWrapper;
namespace Achievements {
enum class AchievementCategory : u8
{
Local = 0,
Core = 3,
Unofficial = 5
};
class RetroAchievements {
public:
RetroAchievements();
~RetroAchievements();
struct Achievement
{
u32 id;
std::string title;
std::string description;
std::string memaddr;
std::string badge_name;
void Login(const char *username, const char *password);
void Logout();
// badge paths are mutable because they're resolved when they're needed.
mutable std::string locked_badge_path;
mutable std::string unlocked_badge_path;
private:
RetroState state_ = RetroState::LOGGED_IN;
rc_runtime_t *runtime_ = nullptr;
u32 points;
AchievementCategory category;
bool locked;
bool active;
bool primed;
};
extern RetroAchievements g_retroAchievements;
struct Leaderboard
{
u32 id;
std::string title;
std::string description;
int format;
};
// TODO: Move the screens out into their own files.
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();
void UpdateSettings();
/// 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();
/// 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.
void ProcessPendingHTTPRequests();
/// 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();
const std::string &GetUsername();
const std::string &GetRichPresenceString();
bool LoginAsync(const char *username, const char *password);
bool Login(const char *username, const char *password);
void Logout();
void GameChanged(const std::string &path, CDImage *image);
/// Re-enables hardcode mode if it is enabled in the settings.
bool ResetChallengeMode();
/// Forces hardcore mode off until next reset.
void DisableChallengeMode();
/// Prompts the user to disable hardcore mode, if they agree, returns true.
bool ConfirmChallengeModeDisable(const char *trigger);
/// Returns true if features such as save states should be disabled.
bool ChallengeModeActive();
const std::string &GetGameTitle();
const std::string &GetGameIcon();
bool EnumerateAchievements(std::function<bool(const Achievement &)> callback);
u32 GetUnlockedAchiementCount();
u32 GetAchievementCount();
u32 GetMaximumPointsForGame();
u32 GetCurrentPointsForGame();
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();
const Achievement *GetAchievementByID(u32 id);
std::pair<u32, u32> GetAchievementProgress(const Achievement &achievement);
std::string 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);
#ifdef WITH_RAINTEGRATION
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
/// Functions implemented in the frontend.
namespace Host {
void OnAchievementsRefreshed();
void OnAchievementsChallengeModeChanged();
} // namespace Host