mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 07:35:41 +00:00
Achievements: Implement disc change without state reset
This commit is contained in:
parent
b9ff358ab3
commit
db305660c1
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
// TODO: Don't poll when booting the game, e.g. Crash Warped freaks out.
|
// TODO: Don't poll when booting the game, e.g. Crash Warped freaks out.
|
||||||
// TODO: rc_client_begin_change_media
|
|
||||||
|
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
|
@ -135,6 +134,7 @@ static void ShowLoginSuccess(const rc_client_t* client);
|
||||||
static void ShowLoginNotification();
|
static void ShowLoginNotification();
|
||||||
static void IdentifyGame(const std::string& path, CDImage* image);
|
static void IdentifyGame(const std::string& path, CDImage* image);
|
||||||
static void BeginLoadGame();
|
static void BeginLoadGame();
|
||||||
|
static void BeginChangeDisc();
|
||||||
static void UpdateGameSummary();
|
static void UpdateGameSummary();
|
||||||
static void DownloadImage(std::string url, std::string cache_filename);
|
static void DownloadImage(std::string url, std::string cache_filename);
|
||||||
|
|
||||||
|
@ -872,18 +872,14 @@ void Achievements::IdentifyGame(const std::string& path, CDImage* image)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rc_client_is_game_loaded(s_client))
|
||||||
BeginLoadGame();
|
BeginLoadGame();
|
||||||
|
else
|
||||||
|
BeginChangeDisc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::BeginLoadGame()
|
void Achievements::BeginLoadGame()
|
||||||
{
|
{
|
||||||
// cancel previous requests
|
|
||||||
if (s_load_game_request)
|
|
||||||
{
|
|
||||||
rc_client_abort_async(s_client, s_load_game_request);
|
|
||||||
s_load_game_request = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearGameInfo();
|
ClearGameInfo();
|
||||||
|
|
||||||
if (s_game_hash.empty())
|
if (s_game_hash.empty())
|
||||||
|
@ -891,8 +887,10 @@ void Achievements::BeginLoadGame()
|
||||||
// when we're booting the bios, this will fail
|
// when we're booting the bios, this will fail
|
||||||
if (!s_game_path.empty())
|
if (!s_game_path.empty())
|
||||||
{
|
{
|
||||||
Host::AddKeyedOSDMessage("retroachievements_disc_read_failed",
|
Host::AddKeyedOSDMessage(
|
||||||
"Failed to read executable from disc. Achievements disabled.", Host::OSD_ERROR_DURATION);
|
"retroachievements_disc_read_failed",
|
||||||
|
TRANSLATE_STR("Achievements", "Failed to read executable from disc. Achievements disabled."),
|
||||||
|
Host::OSD_ERROR_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisableHardcoreMode();
|
DisableHardcoreMode();
|
||||||
|
@ -902,8 +900,39 @@ void Achievements::BeginLoadGame()
|
||||||
s_load_game_request = rc_client_begin_load_game(s_client, s_game_hash.c_str(), ClientLoadGameCallback, nullptr);
|
s_load_game_request = rc_client_begin_load_game(s_client, s_game_hash.c_str(), ClientLoadGameCallback, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Achievements::BeginChangeDisc()
|
||||||
|
{
|
||||||
|
// cancel previous requests
|
||||||
|
if (s_load_game_request)
|
||||||
|
{
|
||||||
|
rc_client_abort_async(s_client, s_load_game_request);
|
||||||
|
s_load_game_request = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_game_hash.empty())
|
||||||
|
{
|
||||||
|
// when we're booting the bios, this will fail
|
||||||
|
if (!s_game_path.empty())
|
||||||
|
{
|
||||||
|
Host::AddKeyedOSDMessage(
|
||||||
|
"retroachievements_disc_read_failed",
|
||||||
|
TRANSLATE_STR("Achievements", "Failed to read executable from disc. Achievements disabled."),
|
||||||
|
Host::OSD_ERROR_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearGameInfo();
|
||||||
|
DisableHardcoreMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_load_game_request = rc_client_begin_change_media_from_hash(s_client, s_game_hash.c_str(), ClientLoadGameCallback,
|
||||||
|
reinterpret_cast<void*>(static_cast<uintptr_t>(1)));
|
||||||
|
}
|
||||||
|
|
||||||
void Achievements::ClientLoadGameCallback(int result, const char* error_message, rc_client_t* client, void* userdata)
|
void Achievements::ClientLoadGameCallback(int result, const char* error_message, rc_client_t* client, void* userdata)
|
||||||
{
|
{
|
||||||
|
const bool was_disc_change = (userdata != nullptr);
|
||||||
|
|
||||||
s_load_game_request = nullptr;
|
s_load_game_request = nullptr;
|
||||||
s_state_buffer.deallocate();
|
s_state_buffer.deallocate();
|
||||||
|
|
||||||
|
@ -911,6 +940,9 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||||
{
|
{
|
||||||
// Unknown game.
|
// Unknown game.
|
||||||
INFO_LOG("Unknown game '{}', disabling achievements.", s_game_hash);
|
INFO_LOG("Unknown game '{}', disabling achievements.", s_game_hash);
|
||||||
|
if (was_disc_change)
|
||||||
|
ClearGameInfo();
|
||||||
|
|
||||||
DisableHardcoreMode();
|
DisableHardcoreMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -923,14 +955,27 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||||
else if (result != RC_OK)
|
else if (result != RC_OK)
|
||||||
{
|
{
|
||||||
ReportFmtError("Loading game failed: {}", error_message);
|
ReportFmtError("Loading game failed: {}", error_message);
|
||||||
|
if (was_disc_change)
|
||||||
|
ClearGameInfo();
|
||||||
|
|
||||||
DisableHardcoreMode();
|
DisableHardcoreMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (result == RC_HARDCORE_DISABLED)
|
||||||
|
{
|
||||||
|
if (error_message)
|
||||||
|
ReportError(error_message);
|
||||||
|
|
||||||
|
DisableHardcoreMode();
|
||||||
|
}
|
||||||
|
|
||||||
const rc_client_game_t* info = rc_client_get_game_info(s_client);
|
const rc_client_game_t* info = rc_client_get_game_info(s_client);
|
||||||
if (!info)
|
if (!info)
|
||||||
{
|
{
|
||||||
ReportError("rc_client_get_game_info() returned NULL");
|
ReportError("rc_client_get_game_info() returned NULL");
|
||||||
|
if (was_disc_change)
|
||||||
|
ClearGameInfo();
|
||||||
|
|
||||||
DisableHardcoreMode();
|
DisableHardcoreMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -938,6 +983,9 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||||
const bool has_achievements = rc_client_has_achievements(client);
|
const bool has_achievements = rc_client_has_achievements(client);
|
||||||
const bool has_leaderboards = rc_client_has_leaderboards(client);
|
const bool has_leaderboards = rc_client_has_leaderboards(client);
|
||||||
|
|
||||||
|
// Only display summary if the game title has changed across discs.
|
||||||
|
const bool display_summary = (s_game_id != info->id || s_game_title != info->title);
|
||||||
|
|
||||||
// If the game has a RetroAchievements entry but no achievements or leaderboards,
|
// If the game has a RetroAchievements entry but no achievements or leaderboards,
|
||||||
// enforcing hardcore mode is pointless.
|
// enforcing hardcore mode is pointless.
|
||||||
if (!has_achievements && !has_leaderboards)
|
if (!has_achievements && !has_leaderboards)
|
||||||
|
@ -954,6 +1002,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||||
s_game_icon = {};
|
s_game_icon = {};
|
||||||
|
|
||||||
// ensure fullscreen UI is ready for notifications
|
// ensure fullscreen UI is ready for notifications
|
||||||
|
if (display_summary)
|
||||||
FullscreenUI::Initialize();
|
FullscreenUI::Initialize();
|
||||||
|
|
||||||
if (const std::string_view badge_name = info->badge_name; !badge_name.empty())
|
if (const std::string_view badge_name = info->badge_name; !badge_name.empty())
|
||||||
|
@ -974,6 +1023,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateGameSummary();
|
UpdateGameSummary();
|
||||||
|
if (display_summary)
|
||||||
DisplayAchievementSummary();
|
DisplayAchievementSummary();
|
||||||
|
|
||||||
Host::OnAchievementsRefreshed();
|
Host::OnAchievementsRefreshed();
|
||||||
|
|
Loading…
Reference in a new issue