Achievements: Backports from PCSX2

This commit is contained in:
Stenzek 2023-09-18 22:29:47 +10:00
parent 4b24bf74f4
commit 846f74c86d
16 changed files with 234 additions and 208 deletions

View file

@ -121,11 +121,10 @@ static void ClearGameInfo();
static void ClearGameHash(); static void ClearGameHash();
static std::string GetUserAgent(); static std::string GetUserAgent();
static std::string GetGameHash(CDImage* image); static std::string GetGameHash(CDImage* image);
static void SetChallengeMode(bool enabled); static void SetHardcoreMode(bool enabled);
static bool IsLoggedIn(); static bool IsLoggedIn();
static void ShowLoginSuccess(const rc_client_t* client); static void ShowLoginSuccess(const rc_client_t* client);
static void ShowLoginNotification(); static void ShowLoginNotification();
static void CancelGameLoad();
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 UpdateGameSummary(); static void UpdateGameSummary();
@ -349,6 +348,11 @@ bool Achievements::HasAchievementsOrLeaderboards()
return s_has_achievements || s_has_leaderboards; return s_has_achievements || s_has_leaderboards;
} }
bool Achievements::HasAchievements()
{
return s_has_achievements;
}
bool Achievements::HasLeaderboards() bool Achievements::HasLeaderboards()
{ {
return s_has_leaderboards; return s_has_leaderboards;
@ -389,7 +393,7 @@ bool Achievements::Initialize()
rc_client_set_event_handler(s_client, ClientEventHandler); rc_client_set_event_handler(s_client, ClientEventHandler);
rc_client_set_hardcore_enabled(s_client, s_hardcore_mode); rc_client_set_hardcore_enabled(s_client, s_hardcore_mode);
rc_client_set_encore_mode_enabled(s_client, g_settings.achievements_spectator_mode); rc_client_set_encore_mode_enabled(s_client, g_settings.achievements_encore_mode);
rc_client_set_unofficial_enabled(s_client, g_settings.achievements_unofficial_test_mode); rc_client_set_unofficial_enabled(s_client, g_settings.achievements_unofficial_test_mode);
rc_client_set_spectator_mode_enabled(s_client, g_settings.achievements_spectator_mode); rc_client_set_spectator_mode_enabled(s_client, g_settings.achievements_spectator_mode);
@ -475,24 +479,37 @@ void Achievements::UpdateSettings(const Settings& old_config)
ResetHardcoreMode(); ResetHardcoreMode();
} }
else if (!s_hardcore_mode && g_settings.achievements_hardcore_mode) else if (!s_hardcore_mode && g_settings.achievements_hardcore_mode)
{
if (HasActiveGame() && FullscreenUI::Initialize())
{ {
ImGuiFullscreen::ShowToast(std::string(), ImGuiFullscreen::ShowToast(std::string(),
TRANSLATE_STR("Achievements", "Hardcore mode will be enabled on system reset."), TRANSLATE_STR("Achievements", "Hardcore mode will be enabled on system reset."),
Host::OSD_WARNING_DURATION); Host::OSD_WARNING_DURATION);
} }
} }
}
// These cannot be modified while a game is loaded, so just toss state and reload. // These cannot be modified while a game is loaded, so just toss state and reload.
if (HasActiveGame() && if (HasActiveGame())
(g_settings.achievements_encore_mode != old_config.achievements_encore_mode || {
if (g_settings.achievements_encore_mode != old_config.achievements_encore_mode ||
g_settings.achievements_spectator_mode != old_config.achievements_spectator_mode || g_settings.achievements_spectator_mode != old_config.achievements_spectator_mode ||
g_settings.achievements_unofficial_test_mode != old_config.achievements_unofficial_test_mode || g_settings.achievements_unofficial_test_mode != old_config.achievements_unofficial_test_mode)
g_settings.achievements_use_first_disc_from_playlist != old_config.achievements_use_first_disc_from_playlist))
{ {
Shutdown(false); Shutdown(false);
Initialize(); Initialize();
return; return;
} }
}
else
{
if (g_settings.achievements_encore_mode != old_config.achievements_encore_mode)
rc_client_set_encore_mode_enabled(s_client, g_settings.achievements_encore_mode);
if (g_settings.achievements_spectator_mode != old_config.achievements_spectator_mode)
rc_client_set_spectator_mode_enabled(s_client, g_settings.achievements_spectator_mode);
if (g_settings.achievements_unofficial_test_mode != old_config.achievements_unofficial_test_mode)
rc_client_set_unofficial_enabled(s_client, g_settings.achievements_unofficial_test_mode);
}
// in case cache directory changed // in case cache directory changed
EnsureCacheDirectoriesExist(); EnsureCacheDirectoriesExist();
@ -520,6 +537,7 @@ bool Achievements::Shutdown(bool allow_cancel)
ClearGameInfo(); ClearGameInfo();
ClearGameHash(); ClearGameHash();
DisableHardcoreMode();
if (s_load_game_request) if (s_load_game_request)
{ {
@ -765,30 +783,6 @@ void Achievements::GameChanged(const std::string& path, CDImage* image)
IdentifyGame(path, image); IdentifyGame(path, image);
} }
void Achievements::CancelGameLoad()
{
Log_ErrorPrint("Cancelling game load");
if (s_load_game_request)
{
rc_client_abort_async(s_client, s_load_game_request);
s_load_game_request = nullptr;
}
rc_client_unload_game(s_client);
ClearGameHash();
ClearGameInfo();
DisableHardcoreMode();
Host::OnAchievementsRefreshed();
#ifdef ENABLE_RAINTEGRATION
if (IsUsingRAIntegration())
{
RAIntegration::GameChanged();
return;
}
#endif
}
void Achievements::IdentifyGame(const std::string& path, CDImage* image) void Achievements::IdentifyGame(const std::string& path, CDImage* image)
{ {
if (s_game_path == path) if (s_game_path == path)
@ -804,17 +798,13 @@ void Achievements::IdentifyGame(const std::string& path, CDImage* image)
temp_image = CDImage::Open(path.c_str(), g_settings.cdrom_load_image_patches, nullptr); temp_image = CDImage::Open(path.c_str(), g_settings.cdrom_load_image_patches, nullptr);
image = temp_image.get(); image = temp_image.get();
if (!temp_image) if (!temp_image)
{
Log_ErrorPrintf("Failed to open temporary CD image '%s'", path.c_str()); Log_ErrorPrintf("Failed to open temporary CD image '%s'", path.c_str());
CancelGameLoad();
return;
}
} }
std::string game_hash; std::string game_hash;
if (image) if (image)
{
game_hash = GetGameHash(image); game_hash = GetGameHash(image);
if (s_game_hash == game_hash) if (s_game_hash == game_hash)
{ {
// only the path has changed - different format/save state/etc. // only the path has changed - different format/save state/etc.
@ -822,7 +812,6 @@ void Achievements::IdentifyGame(const std::string& path, CDImage* image)
s_game_path = path; s_game_path = path;
return; return;
} }
}
ClearGameHash(); ClearGameHash();
s_game_path = path; s_game_path = path;
@ -843,6 +832,7 @@ void Achievements::IdentifyGame(const std::string& path, CDImage* image)
if (!IsLoggedIn()) if (!IsLoggedIn())
{ {
Log_InfoPrintf("Skipping load game because we're not logged in."); Log_InfoPrintf("Skipping load game because we're not logged in.");
DisableHardcoreMode();
return; return;
} }
@ -859,7 +849,6 @@ void Achievements::BeginLoadGame()
} }
ClearGameInfo(); ClearGameInfo();
Host::OnAchievementsRefreshed();
if (s_game_hash.empty()) if (s_game_hash.empty())
{ {
@ -870,7 +859,7 @@ void Achievements::BeginLoadGame()
"Failed to read executable from disc. Achievements disabled.", Host::OSD_ERROR_DURATION); "Failed to read executable from disc. Achievements disabled.", Host::OSD_ERROR_DURATION);
} }
rc_client_unload_game(s_client); DisableHardcoreMode();
return; return;
} }
@ -881,10 +870,17 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
{ {
s_load_game_request = nullptr; s_load_game_request = nullptr;
if (result != RC_OK) if (result == RC_NO_GAME_LOADED)
{
// Unknown game.
Log_InfoPrintf("Unknown game '%s', disabling achievements.", s_game_hash.c_str());
DisableHardcoreMode();
return;
}
else if (result != RC_OK)
{ {
ReportFmtError("Loading game failed: {}", error_message); ReportFmtError("Loading game failed: {}", error_message);
SetChallengeMode(false); DisableHardcoreMode();
return; return;
} }
@ -892,7 +888,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
if (!info) if (!info)
{ {
ReportError("rc_client_get_game_info() returned NULL"); ReportError("rc_client_get_game_info() returned NULL");
SetChallengeMode(false); DisableHardcoreMode();
return; return;
} }
@ -935,6 +931,14 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
void Achievements::ClearGameInfo() void Achievements::ClearGameInfo()
{ {
ClearUIState(); ClearUIState();
if (s_load_game_request)
{
rc_client_abort_async(s_client, s_load_game_request);
s_load_game_request = nullptr;
}
rc_client_unload_game(s_client);
s_active_leaderboard_trackers = {}; s_active_leaderboard_trackers = {};
s_active_challenge_indicators = {}; s_active_challenge_indicators = {};
s_active_progress_indicator.reset(); s_active_progress_indicator.reset();
@ -946,6 +950,8 @@ void Achievements::ClearGameInfo()
s_has_rich_presence = false; s_has_rich_presence = false;
s_rich_presence_string = {}; s_rich_presence_string = {};
s_game_summary = {}; s_game_summary = {};
Host::OnAchievementsRefreshed();
} }
void Achievements::ClearGameHash() void Achievements::ClearGameHash()
@ -1014,8 +1020,8 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
std::string badge_path = GetAchievementBadgePath(cheevo, cheevo->state); std::string badge_path = GetAchievementBadgePath(cheevo, cheevo->state);
ImGuiFullscreen::AddNotification(fmt::format("achievement_unlock_{}", cheevo->id), ImGuiFullscreen::AddNotification(fmt::format("achievement_unlock_{}", cheevo->id),
g_settings.achievements_notification_duration, std::move(title), static_cast<float>(g_settings.achievements_notification_duration),
cheevo->description, std::move(badge_path)); std::move(title), cheevo->description, std::move(badge_path));
} }
if (g_settings.achievements_sound_effects) if (g_settings.achievements_sound_effects)
@ -1075,21 +1081,22 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
if (g_settings.achievements_leaderboard_notifications && FullscreenUI::Initialize()) if (g_settings.achievements_leaderboard_notifications && FullscreenUI::Initialize())
{ {
static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS] = { static const char* value_strings[NUM_RC_CLIENT_LEADERBOARD_FORMATS] = {
TRANSLATE_NOOP("Achievements", "Your Time: {} (Submitting)"), TRANSLATE_NOOP("Achievements", "Your Time: {}{}"),
TRANSLATE_NOOP("Achievements", "Your Score: {} (Submitting)"), TRANSLATE_NOOP("Achievements", "Your Score: {}{}"),
TRANSLATE_NOOP("Achievements", "Your Value: {} (Submitting)"), TRANSLATE_NOOP("Achievements", "Your Value: {}{}"),
}; };
std::string title = event->leaderboard->title; std::string title = event->leaderboard->title;
std::string message = std::string message = fmt::format(
fmt::format(fmt::runtime(Host::TranslateToStringView( fmt::runtime(Host::TranslateToStringView(
"Achievements", "Achievements",
value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)])), value_strings[std::min<u8>(event->leaderboard->format, NUM_RC_CLIENT_LEADERBOARD_FORMATS - 1)])),
event->leaderboard->tracker_value ? event->leaderboard->tracker_value : "Unknown"); event->leaderboard->tracker_value ? event->leaderboard->tracker_value : "Unknown",
g_settings.achievements_spectator_mode ? std::string_view() : TRANSLATE_SV("Achievements", " (Submitting)"));
ImGuiFullscreen::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id), ImGuiFullscreen::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
g_settings.achievements_leaderboard_duration, std::move(title), std::move(message), static_cast<float>(g_settings.achievements_leaderboard_duration), std::move(title),
s_game_icon); std::move(message), s_game_icon);
} }
if (g_settings.achievements_sound_effects) if (g_settings.achievements_sound_effects)
@ -1119,8 +1126,8 @@ void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* eve
event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries); event->leaderboard_scoreboard->new_rank, event->leaderboard_scoreboard->num_entries);
ImGuiFullscreen::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id), ImGuiFullscreen::AddNotification(fmt::format("leaderboard_{}", event->leaderboard->id),
g_settings.achievements_leaderboard_duration, std::move(title), std::move(message), static_cast<float>(g_settings.achievements_leaderboard_duration), std::move(title),
s_game_icon); std::move(message), s_game_icon);
} }
} }
@ -1319,7 +1326,7 @@ void Achievements::DisableHardcoreMode()
#endif #endif
if (s_hardcore_mode) if (s_hardcore_mode)
SetChallengeMode(false); SetHardcoreMode(false);
} }
bool Achievements::ResetHardcoreMode() bool Achievements::ResetHardcoreMode()
@ -1335,11 +1342,11 @@ bool Achievements::ResetHardcoreMode()
if (s_hardcore_mode == wanted_hardcore_mode) if (s_hardcore_mode == wanted_hardcore_mode)
return false; return false;
SetChallengeMode(wanted_hardcore_mode); SetHardcoreMode(wanted_hardcore_mode);
return true; return true;
} }
void Achievements::SetChallengeMode(bool enabled) void Achievements::SetHardcoreMode(bool enabled)
{ {
if (enabled == s_hardcore_mode) if (enabled == s_hardcore_mode)
return; return;
@ -1347,7 +1354,7 @@ void Achievements::SetChallengeMode(bool enabled)
// new mode // new mode
s_hardcore_mode = enabled; s_hardcore_mode = enabled;
if (HasActiveGame()) if (HasActiveGame() && FullscreenUI::Initialize())
{ {
ImGuiFullscreen::ShowToast(std::string(), ImGuiFullscreen::ShowToast(std::string(),
enabled ? TRANSLATE_STR("Achievements", "Hardcore mode is now enabled.") : enabled ? TRANSLATE_STR("Achievements", "Hardcore mode is now enabled.") :
@ -1363,7 +1370,7 @@ void Achievements::SetChallengeMode(bool enabled)
// Toss away UI state, because it's invalid now // Toss away UI state, because it's invalid now
ClearUIState(); ClearUIState();
Host::OnAchievementsHardcoreModeChanged(); Host::OnAchievementsHardcoreModeChanged(enabled);
} }
bool Achievements::DoState(StateWrapper& sw) bool Achievements::DoState(StateWrapper& sw)
@ -1693,11 +1700,7 @@ void Achievements::Logout()
const auto lock = GetLock(); const auto lock = GetLock();
if (HasActiveGame()) if (HasActiveGame())
{
ClearGameInfo(); ClearGameInfo();
ClearGameHash();
Host::OnAchievementsRefreshed();
}
Log_InfoPrint("Logging out..."); Log_InfoPrint("Logging out...");
rc_client_logout(s_client); rc_client_logout(s_client);
@ -1743,7 +1746,7 @@ bool Achievements::ConfirmHardcoreModeDisable(const char* trigger)
void Achievements::ClearUIState() void Achievements::ClearUIState()
{ {
if (FullscreenUI::IsAchievementsWindowOpen() || FullscreenUI::IsLeaderboardsWindowOpen()) if (FullscreenUI::IsAchievementsWindowOpen() || FullscreenUI::IsLeaderboardsWindowOpen())
FullscreenUI::ReturnToMainWindow(); FullscreenUI::ReturnToPreviousWindow();
s_achievement_badge_paths = {}; s_achievement_badge_paths = {};
@ -2008,9 +2011,6 @@ void Achievements::DrawAchievementsWindow()
auto lock = Achievements::GetLock(); auto lock = Achievements::GetLock();
// ensure image downloads still happen while we're paused
Achievements::IdleUpdate();
static constexpr float alpha = 0.8f; static constexpr float alpha = 0.8f;
static constexpr float heading_alpha = 0.95f; static constexpr float heading_alpha = 0.95f;
static constexpr float heading_height_unscaled = 110.0f; static constexpr float heading_height_unscaled = 110.0f;
@ -2058,7 +2058,7 @@ void Achievements::DrawAchievementsWindow()
g_large_font) || g_large_font) ||
ImGuiFullscreen::WantsToCloseMenu()) ImGuiFullscreen::WantsToCloseMenu())
{ {
FullscreenUI::ReturnToMainWindow(); FullscreenUI::ReturnToPreviousWindow();
} }
const ImRect title_bb(ImVec2(left, top), ImVec2(right, top + g_large_font->FontSize)); const ImRect title_bb(ImVec2(left, top), ImVec2(right, top + g_large_font->FontSize));
@ -2124,6 +2124,12 @@ void Achievements::DrawAchievementsWindow()
background, 0.0f, 0.0f, 0)) background, 0.0f, 0.0f, 0))
{ {
static bool buckets_collapsed[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS] = {}; static bool buckets_collapsed[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS] = {};
static const char* bucket_names[NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS] = {
TRANSLATE_NOOP("Achievements", "Unknown"), TRANSLATE_NOOP("Achievements", "Locked"),
TRANSLATE_NOOP("Achievements", "Unlocked"), TRANSLATE_NOOP("Achievements", "Unsupported"),
TRANSLATE_NOOP("Achievements", "Unofficial"), TRANSLATE_NOOP("Achievements", "Recently Unlocked"),
TRANSLATE_NOOP("Achievements", "Active Challenges"), TRANSLATE_NOOP("Achievements", "Almost There"),
};
ImGuiFullscreen::BeginMenuButtons(); ImGuiFullscreen::BeginMenuButtons();
@ -2140,10 +2146,11 @@ void Achievements::DrawAchievementsWindow()
DebugAssert(bucket.bucket_type < NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS); DebugAssert(bucket.bucket_type < NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS);
// TODO: This should be translated. // TODO: Once subsets are supported, this will need to change.
bool& bucket_collapsed = buckets_collapsed[bucket.bucket_type]; bool& bucket_collapsed = buckets_collapsed[bucket.bucket_type];
bucket_collapsed ^= ImGuiFullscreen::MenuHeadingButton(bucket.label, bucket_collapsed ? ICON_FA_CHEVRON_DOWN : bucket_collapsed ^=
ICON_FA_CHEVRON_UP); ImGuiFullscreen::MenuHeadingButton(Host::TranslateToCString("Achievements", bucket_names[bucket.bucket_type]),
bucket_collapsed ? ICON_FA_CHEVRON_DOWN : ICON_FA_CHEVRON_UP);
if (!bucket_collapsed) if (!bucket_collapsed)
{ {
for (u32 i = 0; i < bucket.num_achievements; i++) for (u32 i = 0; i < bucket.num_achievements; i++)
@ -2310,9 +2317,6 @@ void Achievements::DrawLeaderboardsWindow()
auto lock = Achievements::GetLock(); auto lock = Achievements::GetLock();
// ensure image downloads still happen while we're paused
Achievements::IdleUpdate();
const bool is_leaderboard_open = (s_open_leaderboard != nullptr); const bool is_leaderboard_open = (s_open_leaderboard != nullptr);
bool close_leaderboard_on_exit = false; bool close_leaderboard_on_exit = false;
@ -2381,7 +2385,7 @@ void Achievements::DrawLeaderboardsWindow()
g_large_font) || g_large_font) ||
ImGuiFullscreen::WantsToCloseMenu()) ImGuiFullscreen::WantsToCloseMenu())
{ {
FullscreenUI::ReturnToMainWindow(); FullscreenUI::ReturnToPreviousWindow();
} }
} }
else else

View file

@ -91,6 +91,9 @@ u32 GetGameID();
/// Returns true if the current game has any achievements or leaderboards. /// Returns true if the current game has any achievements or leaderboards.
bool HasAchievementsOrLeaderboards(); bool HasAchievementsOrLeaderboards();
/// Returns true if the current game has any leaderboards.
bool HasAchievements();
/// Returns true if the current game has any leaderboards. /// Returns true if the current game has any leaderboards.
bool HasLeaderboards(); bool HasLeaderboards();
@ -153,5 +156,5 @@ void OnAchievementsLoginSuccess(const char* display_name, u32 points, u32 sc_poi
void OnAchievementsRefreshed(); void OnAchievementsRefreshed();
/// Called whenever hardcore mode is toggled. /// Called whenever hardcore mode is toggled.
void OnAchievementsHardcoreModeChanged(); void OnAchievementsHardcoreModeChanged(bool enabled);
} // namespace Host } // namespace Host

View file

@ -217,11 +217,11 @@ static void CancelAsyncOps();
// Main // Main
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static void ToggleTheme(); static void ToggleTheme();
static void PauseForMenuOpen(); static void PauseForMenuOpen(bool set_pause_menu_open);
static void ClosePauseMenu(); static void ClosePauseMenu();
static void OpenPauseSubMenu(PauseSubMenu submenu); static void OpenPauseSubMenu(PauseSubMenu submenu);
static void DrawLandingWindow(); static void DrawLandingWindow();
static void DrawPauseMenu(MainWindowType type); static void DrawPauseMenu();
static void ExitFullscreenAndOpenURL(const std::string_view& url); static void ExitFullscreenAndOpenURL(const std::string_view& url);
static void CopyTextToClipboard(std::string title, const std::string_view& text); static void CopyTextToClipboard(std::string title, const std::string_view& text);
static void DrawAboutWindow(); static void DrawAboutWindow();
@ -616,7 +616,7 @@ void FullscreenUI::CheckForConfigChanges(const Settings& old_settings)
if (old_settings.achievements_enabled && !g_settings.achievements_enabled) if (old_settings.achievements_enabled && !g_settings.achievements_enabled)
{ {
if (s_current_main_window == MainWindowType::Achievements || s_current_main_window == MainWindowType::Leaderboards) if (s_current_main_window == MainWindowType::Achievements || s_current_main_window == MainWindowType::Leaderboards)
ReturnToMainWindow(); ReturnToPreviousWindow();
} }
} }
@ -647,6 +647,8 @@ void FullscreenUI::OnSystemDestroyed()
return; return;
s_pause_menu_was_open = false; s_pause_menu_was_open = false;
s_was_paused_on_quick_menu_open = false;
s_current_pause_submenu = PauseSubMenu::None;
SwitchToLanding(); SwitchToLanding();
} }
@ -671,13 +673,13 @@ void FullscreenUI::ToggleTheme()
ImGuiFullscreen::SetTheme(new_light); ImGuiFullscreen::SetTheme(new_light);
} }
void FullscreenUI::PauseForMenuOpen() void FullscreenUI::PauseForMenuOpen(bool set_pause_menu_open)
{ {
s_was_paused_on_quick_menu_open = (System::GetState() == System::State::Paused); s_was_paused_on_quick_menu_open = (System::GetState() == System::State::Paused);
if (g_settings.pause_on_menu && !s_was_paused_on_quick_menu_open) if (g_settings.pause_on_menu && !s_was_paused_on_quick_menu_open)
Host::RunOnCPUThread([]() { System::PauseSystem(true); }); Host::RunOnCPUThread([]() { System::PauseSystem(true); });
s_pause_menu_was_open = true; s_pause_menu_was_open |= set_pause_menu_open;
} }
void FullscreenUI::OpenPauseMenu() void FullscreenUI::OpenPauseMenu()
@ -688,7 +690,7 @@ void FullscreenUI::OpenPauseMenu()
if (!Initialize() || s_current_main_window != MainWindowType::None) if (!Initialize() || s_current_main_window != MainWindowType::None)
return; return;
PauseForMenuOpen(); PauseForMenuOpen(true);
s_current_main_window = MainWindowType::PauseMenu; s_current_main_window = MainWindowType::PauseMenu;
s_current_pause_submenu = PauseSubMenu::None; s_current_pause_submenu = PauseSubMenu::None;
QueueResetFocus(); QueueResetFocus();
@ -762,7 +764,7 @@ void FullscreenUI::Render()
DrawSettingsWindow(); DrawSettingsWindow();
break; break;
case MainWindowType::PauseMenu: case MainWindowType::PauseMenu:
DrawPauseMenu(s_current_main_window); DrawPauseMenu();
break; break;
case MainWindowType::Achievements: case MainWindowType::Achievements:
Achievements::DrawAchievementsWindow(); Achievements::DrawAchievementsWindow();
@ -818,11 +820,22 @@ void FullscreenUI::InvalidateCoverCache()
Host::RunOnCPUThread([]() { s_cover_image_map.clear(); }); Host::RunOnCPUThread([]() { s_cover_image_map.clear(); });
} }
void FullscreenUI::ReturnToPreviousWindow()
{
if (System::IsValid() && s_pause_menu_was_open)
{
s_current_main_window = MainWindowType::PauseMenu;
QueueResetFocus();
}
else
{
ReturnToMainWindow();
}
}
void FullscreenUI::ReturnToMainWindow() void FullscreenUI::ReturnToMainWindow()
{ {
if (s_pause_menu_was_open)
ClosePauseMenu(); ClosePauseMenu();
s_current_main_window = System::IsValid() ? MainWindowType::None : MainWindowType::Landing; s_current_main_window = System::IsValid() ? MainWindowType::None : MainWindowType::Landing;
} }
@ -956,7 +969,7 @@ void FullscreenUI::DoChangeDiscFromFile()
QueueResetFocus(); QueueResetFocus();
CloseFileSelector(); CloseFileSelector();
ReturnToMainWindow(); ReturnToPreviousWindow();
}; };
OpenFileSelector(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), false, std::move(callback), OpenFileSelector(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), false, std::move(callback),
@ -991,7 +1004,7 @@ void FullscreenUI::DoChangeDisc()
QueueResetFocus(); QueueResetFocus();
CloseChoiceDialog(); CloseChoiceDialog();
ReturnToMainWindow(); ReturnToPreviousWindow();
}; };
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), true, std::move(options), OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), true, std::move(options),
@ -1055,7 +1068,7 @@ void FullscreenUI::DoCheatsMenu()
{ {
Host::AddKeyedOSDMessage("load_cheat_list", Host::AddKeyedOSDMessage("load_cheat_list",
fmt::format(FSUI_FSTR("No cheats found for {}."), System::GetGameTitle()), 10.0f); fmt::format(FSUI_FSTR("No cheats found for {}."), System::GetGameTitle()), 10.0f);
ReturnToMainWindow(); ReturnToPreviousWindow();
return; return;
} }
} }
@ -1071,7 +1084,7 @@ void FullscreenUI::DoCheatsMenu()
auto callback = [](s32 index, const std::string& title, bool checked) { auto callback = [](s32 index, const std::string& title, bool checked) {
if (index < 0) if (index < 0)
{ {
ReturnToMainWindow(); ReturnToPreviousWindow();
return; return;
} }
@ -2537,7 +2550,7 @@ void FullscreenUI::DrawSettingsWindow()
} }
if (NavButton(ICON_FA_BACKWARD, true, true)) if (NavButton(ICON_FA_BACKWARD, true, true))
ReturnToMainWindow(); ReturnToPreviousWindow();
if (s_game_settings_entry) if (s_game_settings_entry)
NavTitle(s_game_settings_entry->title.c_str()); NavTitle(s_game_settings_entry->title.c_str());
@ -2568,7 +2581,7 @@ void FullscreenUI::DrawSettingsWindow()
if (WantsToCloseMenu()) if (WantsToCloseMenu())
{ {
if (ImGui::IsWindowFocused()) if (ImGui::IsWindowFocused())
ReturnToMainWindow(); ReturnToPreviousWindow();
} }
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
@ -4429,10 +4442,6 @@ void FullscreenUI::DrawAchievementsSettingsPage()
} }
#endif #endif
const auto lock = Achievements::GetLock();
if (Achievements::IsActive() && !System::IsRunning())
Achievements::IdleUpdate();
SettingsInterface* bsi = GetEditingSettingsInterface(); SettingsInterface* bsi = GetEditingSettingsInterface();
BeginMenuButtons(); BeginMenuButtons();
@ -4443,7 +4452,6 @@ void FullscreenUI::DrawAchievementsSettingsPage()
"Cheevos", "Enabled", false); "Cheevos", "Enabled", false);
const bool enabled = bsi->GetBoolValue("Cheevos", "Enabled", false); const bool enabled = bsi->GetBoolValue("Cheevos", "Enabled", false);
const bool hardcore = bsi->GetBoolValue("Cheevos", "ChallengeMode", false);
if (DrawToggleSetting( if (DrawToggleSetting(
bsi, FSUI_ICONSTR(ICON_FA_HARD_HAT, "Hardcore Mode"), bsi, FSUI_ICONSTR(ICON_FA_HARD_HAT, "Hardcore Mode"),
@ -4460,7 +4468,7 @@ void FullscreenUI::DrawAchievementsSettingsPage()
"Notifications", true, enabled); "Notifications", true, enabled);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_LIST_OL, "Leaderboard Notifications"), DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_LIST_OL, "Leaderboard Notifications"),
FSUI_CSTR("Displays popup messages when starting, submitting, or failing a leaderboard challenge."), FSUI_CSTR("Displays popup messages when starting, submitting, or failing a leaderboard challenge."),
"Cheevos", "LeaderboardNotifications", true, enabled && hardcore); "Cheevos", "LeaderboardNotifications", true, enabled);
DrawToggleSetting( DrawToggleSetting(
bsi, FSUI_ICONSTR(ICON_FA_HEADPHONES, "Sound Effects"), bsi, FSUI_ICONSTR(ICON_FA_HEADPHONES, "Sound Effects"),
FSUI_CSTR("Plays sound effects for events such as achievement unlocks and leaderboard submissions."), "Cheevos", FSUI_CSTR("Plays sound effects for events such as achievement unlocks and leaderboard submissions."), "Cheevos",
@ -4518,6 +4526,8 @@ void FullscreenUI::DrawAchievementsSettingsPage()
MenuHeading(FSUI_CSTR("Current Game")); MenuHeading(FSUI_CSTR("Current Game"));
if (Achievements::HasActiveGame()) if (Achievements::HasActiveGame())
{ {
const auto lock = Achievements::GetLock();
ImGui::PushStyleColor(ImGuiCol_TextDisabled, ImGui::GetStyle().Colors[ImGuiCol_Text]); ImGui::PushStyleColor(ImGuiCol_TextDisabled, ImGui::GetStyle().Colors[ImGuiCol_Text]);
ActiveButton(SmallString::FromFmt(fmt::runtime(FSUI_ICONSTR(ICON_FA_BOOKMARK, "Game: {} ({})")), ActiveButton(SmallString::FromFmt(fmt::runtime(FSUI_ICONSTR(ICON_FA_BOOKMARK, "Game: {} ({})")),
Achievements::GetGameID(), Achievements::GetGameTitle()), Achievements::GetGameID(), Achievements::GetGameTitle()),
@ -4656,7 +4666,7 @@ void FullscreenUI::DrawAdvancedSettingsPage()
EndMenuButtons(); EndMenuButtons();
} }
void FullscreenUI::DrawPauseMenu(MainWindowType type) void FullscreenUI::DrawPauseMenu()
{ {
SmallString buffer; SmallString buffer;
@ -4779,6 +4789,9 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
// NOTE: Menu close must come first, because otherwise VM destruction options will race. // NOTE: Menu close must come first, because otherwise VM destruction options will race.
const bool has_game = System::IsValid() && !System::GetGameSerial().empty(); const bool has_game = System::IsValid() && !System::GetGameSerial().empty();
if (just_focused)
ImGui::SetFocusID(ImGui::GetID(FSUI_ICONSTR(ICON_FA_PLAY, "Resume Game")), ImGui::GetCurrentWindow());
if (ActiveButton(FSUI_ICONSTR(ICON_FA_PLAY, "Resume Game"), false) || WantsToCloseMenu()) if (ActiveButton(FSUI_ICONSTR(ICON_FA_PLAY, "Resume Game"), false) || WantsToCloseMenu())
ClosePauseMenu(); ClosePauseMenu();
@ -4819,7 +4832,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
} }
if (ActiveButton(FSUI_ICONSTR(ICON_FA_TROPHY, "Achievements"), false, if (ActiveButton(FSUI_ICONSTR(ICON_FA_TROPHY, "Achievements"), false,
Achievements::HasActiveGame() && Achievements::HasAchievementsOrLeaderboards())) Achievements::HasAchievementsOrLeaderboards()))
{ {
// skip second menu and go straight to cheevos if there's no lbs // skip second menu and go straight to cheevos if there's no lbs
if (!Achievements::HasLeaderboards()) if (!Achievements::HasLeaderboards())
@ -4857,14 +4870,14 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
case PauseSubMenu::Exit: case PauseSubMenu::Exit:
{ {
if (just_focused) if (just_focused)
{
ImGui::SetFocusID(ImGui::GetID(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Exit Without Saving")), ImGui::SetFocusID(ImGui::GetID(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Exit Without Saving")),
ImGui::GetCurrentWindow()); ImGui::GetCurrentWindow());
if (ActiveButton(FSUI_ICONSTR(ICON_FA_BACKWARD, "Back To Pause Menu"), false))
{
OpenPauseSubMenu(PauseSubMenu::None);
} }
if (ActiveButton(FSUI_ICONSTR(ICON_FA_BACKWARD, "Back To Pause Menu"), false) || WantsToCloseMenu())
OpenPauseSubMenu(PauseSubMenu::None);
if (ActiveButton(FSUI_ICONSTR(ICON_FA_SYNC, "Reset System"), false)) if (ActiveButton(FSUI_ICONSTR(ICON_FA_SYNC, "Reset System"), false))
{ {
ClosePauseMenu(); ClosePauseMenu();
@ -4881,7 +4894,13 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
case PauseSubMenu::Achievements: case PauseSubMenu::Achievements:
{ {
if (ActiveButton(FSUI_ICONSTR(ICON_FA_BACKWARD, "Back To Pause Menu"), false)) if (just_focused)
{
ImGui::SetFocusID(ImGui::GetID(FSUI_ICONSTR(ICON_FA_BACKWARD, "Back To Pause Menu")),
ImGui::GetCurrentWindow());
}
if (ActiveButton(FSUI_ICONSTR(ICON_FA_BACKWARD, "Back To Pause Menu"), false) || WantsToCloseMenu())
OpenPauseSubMenu(PauseSubMenu::None); OpenPauseSubMenu(PauseSubMenu::None);
if (ActiveButton(FSUI_ICONSTR(ICON_FA_TROPHY, "Achievements"), false)) if (ActiveButton(FSUI_ICONSTR(ICON_FA_TROPHY, "Achievements"), false))
@ -5057,8 +5076,6 @@ void FullscreenUI::CloseSaveStateSelector()
s_save_state_selector_loading = false; s_save_state_selector_loading = false;
s_save_state_selector_resuming = false; s_save_state_selector_resuming = false;
s_save_state_selector_game_path = {}; s_save_state_selector_game_path = {};
if (s_current_main_window != MainWindowType::GameList)
ReturnToMainWindow();
} }
void FullscreenUI::DrawSaveStateSelector(bool is_loading) void FullscreenUI::DrawSaveStateSelector(bool is_loading)
@ -5089,7 +5106,10 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PopStyleVar(5); ImGui::PopStyleVar(5);
if (!is_open) if (!is_open)
{
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
}
return; return;
} }
@ -5102,7 +5122,10 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
{ {
BeginNavBar(); BeginNavBar();
if (NavButton(ICON_FA_BACKWARD, true, true)) if (NavButton(ICON_FA_BACKWARD, true, true))
{
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
}
NavTitle(is_loading ? FSUI_CSTR("Load State") : FSUI_CSTR("Save State")); NavTitle(is_loading ? FSUI_CSTR("Load State") : FSUI_CSTR("Save State"));
EndNavBar(); EndNavBar();
@ -5206,12 +5229,14 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
{ {
DoLoadState(entry.path); DoLoadState(entry.path);
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
break; break;
} }
else else
{ {
DoSaveState(entry.slot, entry.global); DoSaveState(entry.slot, entry.global);
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
break; break;
} }
} }
@ -5268,6 +5293,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
DoSaveState(entry.slot, entry.global); DoSaveState(entry.slot, entry.global);
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
closed = true; closed = true;
} }
@ -5287,6 +5313,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
if (s_save_state_selector_slots.empty()) if (s_save_state_selector_slots.empty())
{ {
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
closed = true; closed = true;
} }
else else
@ -5352,7 +5379,10 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PopStyleVar(5); ImGui::PopStyleVar(5);
if (!close_handled && WantsToCloseMenu()) if (!close_handled && WantsToCloseMenu())
{
CloseSaveStateSelector(); CloseSaveStateSelector();
ReturnToPreviousWindow();
}
} }
bool FullscreenUI::OpenLoadStateSelectorForGameResume(const GameList::Entry* entry) bool FullscreenUI::OpenLoadStateSelectorForGameResume(const GameList::Entry* entry)
@ -5599,7 +5629,7 @@ void FullscreenUI::DrawGameListWindow()
} }
if (NavButton(ICON_FA_BACKWARD, true, true)) if (NavButton(ICON_FA_BACKWARD, true, true))
ReturnToMainWindow(); ReturnToPreviousWindow();
NavTitle(Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(s_game_list_page)])); NavTitle(Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(s_game_list_page)]));
RightAlignNavButtons(count, ITEM_WIDTH, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY); RightAlignNavButtons(count, ITEM_WIDTH, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
@ -5851,7 +5881,7 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
if (WantsToCloseMenu()) if (WantsToCloseMenu())
{ {
if (ImGui::IsWindowFocused()) if (ImGui::IsWindowFocused())
ReturnToMainWindow(); ReturnToPreviousWindow();
} }
ResetFocusHere(); ResetFocusHere();
@ -6018,7 +6048,7 @@ void FullscreenUI::DrawGameListSettingsPage(const ImVec2& heading_size)
if (WantsToCloseMenu()) if (WantsToCloseMenu())
{ {
if (ImGui::IsWindowFocused()) if (ImGui::IsWindowFocused())
ReturnToMainWindow(); ReturnToPreviousWindow();
} }
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
@ -6459,20 +6489,29 @@ bool FullscreenUI::DrawConfirmWindow(const char* message, bool* result)
return !is_open; return !is_open;
} }
bool FullscreenUI::OpenAchievementsWindow() void FullscreenUI::OpenAchievementsWindow()
{ {
if (!System::IsValid() || !Achievements::HasActiveGame() || !Initialize() || if (!Achievements::IsActive())
!Achievements::PrepareAchievementsWindow())
{ {
return false; Host::AddKeyedOSDMessage("achievements_disabled", FSUI_STR("Achievements are not enabled."),
Host::OSD_INFO_DURATION);
return;
}
if (!System::IsValid() || !Initialize())
return;
if (!Achievements::HasAchievements() || !Achievements::PrepareAchievementsWindow())
{
ShowToast(std::string(), FSUI_STR("This game has no achievements."));
return;
} }
if (s_current_main_window != MainWindowType::PauseMenu) if (s_current_main_window != MainWindowType::PauseMenu)
PauseForMenuOpen(); PauseForMenuOpen(false);
s_current_main_window = MainWindowType::Achievements; s_current_main_window = MainWindowType::Achievements;
QueueResetFocus(); QueueResetFocus();
return true;
} }
bool FullscreenUI::IsAchievementsWindowOpen() bool FullscreenUI::IsAchievementsWindowOpen()
@ -6480,17 +6519,29 @@ bool FullscreenUI::IsAchievementsWindowOpen()
return (s_current_main_window == MainWindowType::Achievements); return (s_current_main_window == MainWindowType::Achievements);
} }
bool FullscreenUI::OpenLeaderboardsWindow() void FullscreenUI::OpenLeaderboardsWindow()
{ {
if (!Achievements::HasLeaderboards() || !Initialize() || !Achievements::PrepareLeaderboardsWindow()) if (!Achievements::IsActive())
return false; {
Host::AddKeyedOSDMessage("achievements_disabled", FSUI_STR("Leaderboards are not enabled."),
Host::OSD_INFO_DURATION);
return;
}
if (!System::IsValid() || !Initialize())
return;
if (!Achievements::HasLeaderboards() || !Achievements::PrepareLeaderboardsWindow())
{
ShowToast(std::string(), FSUI_STR("This game has no leaderboards."));
return;
}
if (s_current_main_window != MainWindowType::PauseMenu) if (s_current_main_window != MainWindowType::PauseMenu)
PauseForMenuOpen(); PauseForMenuOpen(false);
s_current_main_window = MainWindowType::Leaderboards; s_current_main_window = MainWindowType::Leaderboards;
QueueResetFocus(); QueueResetFocus();
return true;
} }
bool FullscreenUI::IsLeaderboardsWindowOpen() bool FullscreenUI::IsLeaderboardsWindowOpen()

View file

@ -22,11 +22,12 @@ void OnSystemResumed();
void OnSystemDestroyed(); void OnSystemDestroyed();
void OnRunningGameChanged(); void OnRunningGameChanged();
void OpenPauseMenu(); void OpenPauseMenu();
bool OpenAchievementsWindow(); void OpenAchievementsWindow();
bool IsAchievementsWindowOpen(); bool IsAchievementsWindowOpen();
bool OpenLeaderboardsWindow(); void OpenLeaderboardsWindow();
bool IsLeaderboardsWindowOpen(); bool IsLeaderboardsWindowOpen();
void ReturnToMainWindow(); void ReturnToMainWindow();
void ReturnToPreviousWindow();
void Shutdown(); void Shutdown();
void Render(); void Render();

View file

@ -164,25 +164,13 @@ DEFINE_HOTKEY("Screenshot", TRANSLATE_NOOP("Hotkeys", "General"), TRANSLATE_NOOP
DEFINE_HOTKEY("OpenAchievements", TRANSLATE_NOOP("Hotkeys", "General"), DEFINE_HOTKEY("OpenAchievements", TRANSLATE_NOOP("Hotkeys", "General"),
TRANSLATE_NOOP("Hotkeys", "Open Achievement List"), [](s32 pressed) { TRANSLATE_NOOP("Hotkeys", "Open Achievement List"), [](s32 pressed) {
if (!pressed) if (!pressed)
{ FullscreenUI::OpenAchievementsWindow();
if (!FullscreenUI::OpenAchievementsWindow())
{
Host::AddOSDMessage(
TRANSLATE_STR("OSDMessage", "Achievements are disabled or unavailable for game."), 10.0f);
}
}
}) })
DEFINE_HOTKEY("OpenLeaderboards", TRANSLATE_NOOP("Hotkeys", "General"), DEFINE_HOTKEY("OpenLeaderboards", TRANSLATE_NOOP("Hotkeys", "General"),
TRANSLATE_NOOP("Hotkeys", "Open Leaderboard List"), [](s32 pressed) { TRANSLATE_NOOP("Hotkeys", "Open Leaderboard List"), [](s32 pressed) {
if (!pressed) if (!pressed)
{ FullscreenUI::OpenLeaderboardsWindow();
if (!FullscreenUI::OpenLeaderboardsWindow())
{
Host::AddOSDMessage(
TRANSLATE_STR("OSDMessage", "Leaderboards are disabled or unavailable for game."), 10.0f);
}
}
}) })
#endif // !defined(__ANDROID__) #endif // !defined(__ANDROID__)

View file

@ -376,9 +376,9 @@ void Settings::Load(SettingsInterface& si)
achievements_use_first_disc_from_playlist = si.GetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", true); achievements_use_first_disc_from_playlist = si.GetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", true);
achievements_use_raintegration = si.GetBoolValue("Cheevos", "UseRAIntegration", false); achievements_use_raintegration = si.GetBoolValue("Cheevos", "UseRAIntegration", false);
achievements_notification_duration = achievements_notification_duration =
si.GetFloatValue("Cheevos", "NotificationsDuration", DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME); si.GetIntValue("Cheevos", "NotificationsDuration", DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME);
achievements_leaderboard_duration = achievements_leaderboard_duration =
si.GetFloatValue("Cheevos", "LeaderboardsDuration", DEFAULT_LEADERBOARD_NOTIFICATION_TIME); si.GetIntValue("Cheevos", "LeaderboardsDuration", DEFAULT_LEADERBOARD_NOTIFICATION_TIME);
log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str()) log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str())
.value_or(DEFAULT_LOG_LEVEL); .value_or(DEFAULT_LOG_LEVEL);
@ -578,8 +578,8 @@ void Settings::Save(SettingsInterface& si) const
si.SetBoolValue("Cheevos", "UnofficialTestMode", achievements_unofficial_test_mode); si.SetBoolValue("Cheevos", "UnofficialTestMode", achievements_unofficial_test_mode);
si.SetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", achievements_use_first_disc_from_playlist); si.SetBoolValue("Cheevos", "UseFirstDiscFromPlaylist", achievements_use_first_disc_from_playlist);
si.SetBoolValue("Cheevos", "UseRAIntegration", achievements_use_raintegration); si.SetBoolValue("Cheevos", "UseRAIntegration", achievements_use_raintegration);
si.SetFloatValue("Cheevos", "NotificationsDuration", achievements_notification_duration); si.SetIntValue("Cheevos", "NotificationsDuration", achievements_notification_duration);
si.SetFloatValue("Cheevos", "LeaderboardsDuration", achievements_leaderboard_duration); si.SetIntValue("Cheevos", "LeaderboardsDuration", achievements_leaderboard_duration);
si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level)); si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level));
si.SetStringValue("Logging", "LogFilter", log_filter.c_str()); si.SetStringValue("Logging", "LogFilter", log_filter.c_str());

View file

@ -190,8 +190,8 @@ struct Settings
bool achievements_unofficial_test_mode = false; bool achievements_unofficial_test_mode = false;
bool achievements_use_first_disc_from_playlist = true; bool achievements_use_first_disc_from_playlist = true;
bool achievements_use_raintegration = false; bool achievements_use_raintegration = false;
float achievements_notification_duration = DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME; s32 achievements_notification_duration = DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME;
float achievements_leaderboard_duration = DEFAULT_LEADERBOARD_NOTIFICATION_TIME; s32 achievements_leaderboard_duration = DEFAULT_LEADERBOARD_NOTIFICATION_TIME;
struct DebugSettings struct DebugSettings
{ {
@ -475,8 +475,8 @@ struct Settings
static constexpr MemoryCardType DEFAULT_MEMORY_CARD_2_TYPE = MemoryCardType::None; static constexpr MemoryCardType DEFAULT_MEMORY_CARD_2_TYPE = MemoryCardType::None;
static constexpr MultitapMode DEFAULT_MULTITAP_MODE = MultitapMode::Disabled; static constexpr MultitapMode DEFAULT_MULTITAP_MODE = MultitapMode::Disabled;
static constexpr float DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME = 10.0f; static constexpr s32 DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME = 5;
static constexpr float DEFAULT_LEADERBOARD_NOTIFICATION_TIME = 10.0f; static constexpr s32 DEFAULT_LEADERBOARD_NOTIFICATION_TIME = 10;
static constexpr LOGLEVEL DEFAULT_LOG_LEVEL = LOGLEVEL_INFO; static constexpr LOGLEVEL DEFAULT_LOG_LEVEL = LOGLEVEL_INFO;

View file

@ -4752,31 +4752,15 @@ void System::UpdateDiscordPresence()
rp.largeImageKey = "duckstation_logo"; rp.largeImageKey = "duckstation_logo";
rp.largeImageText = "DuckStation PS1/PSX Emulator"; rp.largeImageText = "DuckStation PS1/PSX Emulator";
rp.startTimestamp = std::time(nullptr); rp.startTimestamp = std::time(nullptr);
rp.details = System::IsValid() ? System::GetGameTitle().c_str() : "No Game Running";
SmallString details_string; std::string state_string;
if (!System::IsShutdown())
{
details_string.AppendFormattedString("%s (%s)", System::GetGameTitle().c_str(), System::GetGameSerial().c_str());
}
else
{
details_string.AppendString("No Game Running");
}
SmallString state_string;
if (Achievements::HasRichPresence()) if (Achievements::HasRichPresence())
{ {
const auto lock = Achievements::GetLock(); const auto lock = Achievements::GetLock();
const std::string_view richp = Achievements::GetRichPresenceString(); state_string = StringUtil::Ellipsise(Achievements::GetRichPresenceString(), 128);
if (richp.length() >= 128) rp.state = state_string.c_str();
state_string.AppendFmtString("{}...", richp.substr(0, 124));
else
state_string.Assign(richp);
rp.state = state_string;
} }
rp.details = details_string;
Discord_UpdatePresence(&rp); Discord_UpdatePresence(&rp);
} }

View file

@ -766,7 +766,7 @@ void Host::OnAchievementsRefreshed()
// noop // noop
} }
void Host::OnAchievementsHardcoreModeChanged() void Host::OnAchievementsHardcoreModeChanged(bool enabled)
{ {
// noop // noop
} }

View file

@ -159,16 +159,16 @@ void AchievementSettingsWidget::onHardcoreModeStateChanged()
void AchievementSettingsWidget::onAchievementsNotificationDurationSliderChanged() void AchievementSettingsWidget::onAchievementsNotificationDurationSliderChanged()
{ {
const float duration = m_dialog->getEffectiveFloatValue("Cheevos", "NotificationsDuration", const int duration =
Settings::DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME); m_dialog->getEffectiveIntValue("Cheevos", "NotificationsDuration", Settings::DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME);
m_ui.achievementNotificationsDurationLabel->setText(tr("%n seconds", nullptr, static_cast<int>(duration))); m_ui.achievementNotificationsDurationLabel->setText(tr("%n seconds", nullptr, duration));
} }
void AchievementSettingsWidget::onLeaderboardsNotificationDurationSliderChanged() void AchievementSettingsWidget::onLeaderboardsNotificationDurationSliderChanged()
{ {
const float duration = m_dialog->getEffectiveFloatValue("Cheevos", "LeaderboardsDuration", const int duration =
Settings::DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME); m_dialog->getEffectiveIntValue("Cheevos", "LeaderboardsDuration", Settings::DEFAULT_LEADERBOARD_NOTIFICATION_TIME);
m_ui.leaderboardNotificationsDurationLabel->setText(tr("%n seconds", nullptr, static_cast<int>(duration))); m_ui.leaderboardNotificationsDurationLabel->setText(tr("%n seconds", nullptr, duration));
} }
void AchievementSettingsWidget::updateLoginState() void AchievementSettingsWidget::updateLoginState()

View file

@ -2657,10 +2657,9 @@ void MainWindow::onAchievementsLoginSucceeded(const QString& display_name, quint
m_ui.statusBar->showMessage(message); m_ui.statusBar->showMessage(message);
} }
void MainWindow::onAchievementsChallengeModeChanged() void MainWindow::onAchievementsChallengeModeChanged(bool enabled)
{ {
const bool active = Achievements::IsHardcoreModeActive(); if (enabled)
if (active)
{ {
if (m_cheat_manager_dialog) if (m_cheat_manager_dialog)
{ {
@ -2677,7 +2676,7 @@ void MainWindow::onAchievementsChallengeModeChanged()
} }
} }
updateEmulationActions(false, System::IsValid(), active); updateEmulationActions(false, System::IsValid(), enabled);
} }
void MainWindow::onToolsMemoryCardEditorTriggered() void MainWindow::onToolsMemoryCardEditorTriggered()

View file

@ -134,7 +134,7 @@ private Q_SLOTS:
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason); void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
void onAchievementsLoginSucceeded(const QString& display_name, quint32 points, quint32 sc_points, void onAchievementsLoginSucceeded(const QString& display_name, quint32 points, quint32 sc_points,
quint32 unread_messages); quint32 unread_messages);
void onAchievementsChallengeModeChanged(); void onAchievementsChallengeModeChanged(bool enabled);
void onApplicationStateChanged(Qt::ApplicationState state); void onApplicationStateChanged(Qt::ApplicationState state);
void onStartFileActionTriggered(); void onStartFileActionTriggered();

View file

@ -1231,7 +1231,7 @@ void Host::OnAchievementsRefreshed()
const std::string& rich_presence_string = Achievements::GetRichPresenceString(); const std::string& rich_presence_string = Achievements::GetRichPresenceString();
if (Achievements::HasRichPresence() && !rich_presence_string.empty()) if (Achievements::HasRichPresence() && !rich_presence_string.empty())
game_info.append(QString::fromStdString(rich_presence_string)); game_info.append(QString::fromStdString(StringUtil::Ellipsise(rich_presence_string, 128)));
else else
game_info.append(qApp->translate("EmuThread", "Rich presence inactive or unsupported.")); game_info.append(qApp->translate("EmuThread", "Rich presence inactive or unsupported."));
} }
@ -1243,9 +1243,9 @@ void Host::OnAchievementsRefreshed()
emit g_emu_thread->achievementsRefreshed(game_id, game_info); emit g_emu_thread->achievementsRefreshed(game_id, game_info);
} }
void Host::OnAchievementsHardcoreModeChanged() void Host::OnAchievementsHardcoreModeChanged(bool enabled)
{ {
emit g_emu_thread->achievementsChallengeModeChanged(); emit g_emu_thread->achievementsChallengeModeChanged(enabled);
} }
void EmuThread::doBackgroundControllerPoll() void EmuThread::doBackgroundControllerPoll()

View file

@ -144,7 +144,7 @@ Q_SIGNALS:
void achievementsLoginSucceeded(const QString& display_name, quint32 points, quint32 sc_points, void achievementsLoginSucceeded(const QString& display_name, quint32 points, quint32 sc_points,
quint32 unread_messages); quint32 unread_messages);
void achievementsRefreshed(quint32 id, const QString& game_info_string); void achievementsRefreshed(quint32 id, const QString& game_info_string);
void achievementsChallengeModeChanged(); void achievementsChallengeModeChanged(bool enabled);
void cheatEnabled(quint32 index, bool enabled); void cheatEnabled(quint32 index, bool enabled);
public Q_SLOTS: public Q_SLOTS:

View file

@ -340,7 +340,7 @@ void Host::OnAchievementsRefreshed()
// noop // noop
} }
void Host::OnAchievementsHardcoreModeChanged() void Host::OnAchievementsHardcoreModeChanged(bool enabled)
{ {
// noop // noop
} }

View file

@ -80,6 +80,7 @@ ImVec4 UISecondaryTextColor;
static u32 s_menu_button_index = 0; static u32 s_menu_button_index = 0;
static u32 s_close_button_state = 0; static u32 s_close_button_state = 0;
static bool s_focus_reset_queued = false; static bool s_focus_reset_queued = false;
static bool s_light_theme = false;
static LRUCache<std::string, std::shared_ptr<GPUTexture>> s_texture_cache(128, true); static LRUCache<std::string, std::shared_ptr<GPUTexture>> s_texture_cache(128, true);
static std::shared_ptr<GPUTexture> s_placeholder_texture; static std::shared_ptr<GPUTexture> s_placeholder_texture;
@ -2484,17 +2485,10 @@ void ImGuiFullscreen::DrawNotifications(ImVec2& position, float spacing)
ImFont* const title_font = ImGuiFullscreen::g_large_font; ImFont* const title_font = ImGuiFullscreen::g_large_font;
ImFont* const text_font = ImGuiFullscreen::g_medium_font; ImFont* const text_font = ImGuiFullscreen::g_medium_font;
#if 0 const u32 toast_background_color = s_light_theme ? IM_COL32(241, 241, 241, 255) : IM_COL32(0x21, 0x21, 0x21, 255);
static constexpr u32 toast_background_color = IM_COL32(241, 241, 241, 255); const u32 toast_border_color = s_light_theme ? IM_COL32(0x88, 0x88, 0x88, 255) : IM_COL32(0x48, 0x48, 0x48, 255);
static constexpr u32 toast_border_color = IM_COL32(0x88, 0x88, 0x88, 255); const u32 toast_title_color = s_light_theme ? IM_COL32(1, 1, 1, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
static constexpr u32 toast_title_color = IM_COL32(1, 1, 1, 255); const u32 toast_text_color = s_light_theme ? IM_COL32(0, 0, 0, 255) : IM_COL32(0xff, 0xff, 0xff, 255);
static constexpr u32 toast_text_color = IM_COL32(0, 0, 0, 255);
#else
static constexpr u32 toast_background_color = IM_COL32(0x21, 0x21, 0x21, 255);
static constexpr u32 toast_border_color = IM_COL32(0x48, 0x48, 0x48, 255);
static constexpr u32 toast_title_color = IM_COL32(0xff, 0xff, 0xff, 255);
static constexpr u32 toast_text_color = IM_COL32(0xff, 0xff, 0xff, 255);
#endif
for (u32 index = 0; index < static_cast<u32>(s_notifications.size());) for (u32 index = 0; index < static_cast<u32>(s_notifications.size());)
{ {
@ -2668,6 +2662,8 @@ void ImGuiFullscreen::DrawToast()
void ImGuiFullscreen::SetTheme(bool light) void ImGuiFullscreen::SetTheme(bool light)
{ {
s_light_theme = light;
if (!light) if (!light)
{ {
// dark // dark