From a6a52b31ad996f55d18c8db043e57f023f5560e0 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 5 Nov 2022 15:01:48 +1000 Subject: [PATCH] Achievements: Add option to disable notifications --- src/core/settings.cpp | 2 + src/core/settings.h | 1 + .../achievementsettingswidget.cpp | 9 ++- .../achievementsettingswidget.ui | 63 ++++++++++--------- src/frontend-common/achievements.cpp | 51 ++++++++------- src/frontend-common/fullscreen_ui.cpp | 8 ++- src/frontend-common/imgui_manager.cpp | 24 +++---- 7 files changed, 92 insertions(+), 66 deletions(-) diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 61ee95255..819078f96 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -350,6 +350,7 @@ void Settings::Load(SettingsInterface& si) 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); @@ -536,6 +537,7 @@ void Settings::Save(SettingsInterface& si) const 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); diff --git a/src/core/settings.h b/src/core/settings.h index 3558e00f2..2781d890c 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -178,6 +178,7 @@ struct Settings 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; #endif diff --git a/src/duckstation-qt/achievementsettingswidget.cpp b/src/duckstation-qt/achievementsettingswidget.cpp index 6f9def962..3e1b907e3 100644 --- a/src/duckstation-qt/achievementsettingswidget.cpp +++ b/src/duckstation-qt/achievementsettingswidget.cpp @@ -25,6 +25,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useFirstDiscFromPlaylist, "Cheevos", "UseFirstDiscFromPlaylist", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.leaderboards, "Cheevos", "Leaderboards", true); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.notifications, "Cheevos", "Notifications", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.soundEffects, "Cheevos", "SoundEffects", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.primedIndicators, "Cheevos", "PrimedIndicators", true); @@ -47,6 +48,9 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi dialog->registerWidgetHelp(m_ui.challengeMode, tr("Enable Hardcore Mode"), tr("Unchecked"), tr("\"Challenge\" mode for achievements, including leaderboard tracking. Disables save " "state, cheats, and slowdown functions.")); + dialog->registerWidgetHelp( + m_ui.notifications, tr("Show Notifications"), tr("Checked"), + tr("Displays popup messages on events such as achievement unlocks and leaderboard submissions.")); dialog->registerWidgetHelp( m_ui.soundEffects, tr("Enable Sound Effects"), tr("Checked"), tr("Plays sound effects for events such as achievement unlocks and leaderboard submissions.")); @@ -59,6 +63,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi tr("Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active.")); connect(m_ui.enable, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState); + connect(m_ui.notifications, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState); connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState); connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::onChallengeModeStateChanged); @@ -92,13 +97,15 @@ void AchievementSettingsWidget::updateEnableState() { const bool enabled = m_dialog->getEffectiveBoolValue("Cheevos", "Enabled", false); const bool challenge = m_dialog->getEffectiveBoolValue("Cheevos", "ChallengeMode", false); + const bool notifications = m_dialog->getEffectiveBoolValue("Cheevos", "Notifications", true); m_ui.testMode->setEnabled(enabled); m_ui.useFirstDiscFromPlaylist->setEnabled(enabled); m_ui.richPresence->setEnabled(enabled); m_ui.challengeMode->setEnabled(enabled); m_ui.leaderboards->setEnabled(enabled && challenge); m_ui.unofficialTestMode->setEnabled(enabled); - m_ui.soundEffects->setEnabled(enabled); + m_ui.notifications->setEnabled(enabled); + m_ui.soundEffects->setEnabled(enabled && notifications); m_ui.primedIndicators->setEnabled(enabled); } diff --git a/src/duckstation-qt/achievementsettingswidget.ui b/src/duckstation-qt/achievementsettingswidget.ui index b5995a6e9..20150c36f 100644 --- a/src/duckstation-qt/achievementsettingswidget.ui +++ b/src/duckstation-qt/achievementsettingswidget.ui @@ -32,24 +32,10 @@ Global Settings - - + + - Test Unofficial Achievements - - - - - - - Enable Sound Effects - - - - - - - Enable Achievements + Enable Rich Presence @@ -60,17 +46,10 @@ - - + + - Show Challenge Indicators - - - - - - - Enable Rich Presence + Enable Achievements @@ -81,6 +60,13 @@ + + + + Show Challenge Indicators + + + @@ -88,13 +74,34 @@ - + Enable Test Mode + + + + Test Unofficial Achievements + + + + + + + Enable Sound Effects + + + + + + + Show Notifications + + + diff --git a/src/frontend-common/achievements.cpp b/src/frontend-common/achievements.cpp index 1cbc0d570..9e6b5d8de 100644 --- a/src/frontend-common/achievements.cpp +++ b/src/frontend-common/achievements.cpp @@ -1020,18 +1020,20 @@ void Achievements::DisplayAchievementSummary() } Host::RunOnCPUThread([title = std::move(title), summary = std::move(summary), icon = s_game_icon]() { - if (FullscreenUI::IsInitialized()) + if (FullscreenUI::IsInitialized() && g_settings.achievements_notifications) + { ImGuiFullscreen::AddNotification(10.0f, std::move(title), std::move(summary), std::move(icon)); - // Technically not going through the resource API, but since we're passing this to something else, we can't. - if (g_settings.achievements_sound_effects) - FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str()); + // Technically not going through the resource API, but since we're passing this to something else, we can't. + if (g_settings.achievements_sound_effects) + FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str()); + } }); } void Achievements::DisplayMasteredNotification() { - if (!FullscreenUI::IsInitialized()) + if (!FullscreenUI::IsInitialized() || !g_settings.achievements_notifications) return; std::string title(fmt::format("Mastered {}", s_game_title)); @@ -1757,7 +1759,7 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, std::string conten return; const Leaderboard* lb = GetLeaderboardByID(std::exchange(s_submitting_lboard_id, 0u)); - if (!lb) + if (!lb || !FullscreenUI::IsInitialized() || !g_settings.achievements_notifications) return; char submitted_score[128]; @@ -1797,25 +1799,28 @@ void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification / Log_InfoPrintf("Achievement %s (%u) for game %u unlocked", achievement->title.c_str(), achievement_id, s_game_id); - std::string title; - switch (achievement->category) + if (FullscreenUI::IsInitialized() && g_settings.achievements_notifications) { - case AchievementCategory::Local: - title = fmt::format("{} (Local)", achievement->title); - break; - case AchievementCategory::Unofficial: - title = fmt::format("{} (Unofficial)", achievement->title); - break; - case AchievementCategory::Core: - default: - title = achievement->title; - break; - } + std::string title; + switch (achievement->category) + { + case AchievementCategory::Local: + title = fmt::format("{} (Local)", achievement->title); + break; + case AchievementCategory::Unofficial: + title = fmt::format("{} (Unofficial)", achievement->title); + break; + case AchievementCategory::Core: + default: + title = achievement->title; + break; + } - ImGuiFullscreen::AddNotification(15.0f, std::move(title), achievement->description, - GetAchievementBadgePath(*achievement)); - if (g_settings.achievements_sound_effects) - FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str()); + ImGuiFullscreen::AddNotification(15.0f, std::move(title), achievement->description, + GetAchievementBadgePath(*achievement)); + if (g_settings.achievements_sound_effects) + FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str()); + } if (IsMastered()) DisplayMasteredNotification(); diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index fc83ba236..8f1b4ea4b 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -4208,6 +4208,7 @@ void FullscreenUI::DrawAchievementsSettingsPage() const bool enabled = bsi->GetBoolValue("Cheevos", "Enabled", false); const bool challenge = bsi->GetBoolValue("Cheevos", "ChallengeMode", false); + const bool notifications = bsi->GetBoolValue("Cheevos", "Notifications", true); DrawToggleSetting(bsi, ICON_FA_USER_FRIENDS " Rich Presence", "When enabled, rich presence information will be collected and sent to the server where supported.", @@ -4223,9 +4224,12 @@ void FullscreenUI::DrawAchievementsSettingsPage() DrawToggleSetting(bsi, ICON_FA_LIST_OL " Leaderboards", "Enables tracking and submission of leaderboards in supported games.", "Cheevos", "Leaderboards", true, enabled && challenge); - DrawToggleSetting(bsi, ICON_FA_HEADPHONES " Sound Effects", + DrawToggleSetting(bsi, ICON_FA_INBOX " Show Notifications", + "Displays popup messages on events such as achievement unlocks and leaderboard submissions.", + "Cheevos", "Notifications", true, enabled); + DrawToggleSetting(bsi, ICON_FA_HEADPHONES " Enable Sound Effects", "Plays sound effects for events such as achievement unlocks and leaderboard submissions.", - "Cheevos", "SoundEffects", true, enabled); + "Cheevos", "SoundEffects", true, enabled && notifications); DrawToggleSetting( bsi, ICON_FA_MAGIC " Show Challenge Indicators", "Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active.", "Cheevos", diff --git a/src/frontend-common/imgui_manager.cpp b/src/frontend-common/imgui_manager.cpp index ec86453eb..49f6c641a 100644 --- a/src/frontend-common/imgui_manager.cpp +++ b/src/frontend-common/imgui_manager.cpp @@ -460,18 +460,18 @@ bool ImGuiManager::AddIconFonts(float size) { static constexpr ImWchar range_fa[] = { 0xf002, 0xf002, 0xf005, 0xf005, 0xf007, 0xf007, 0xf00c, 0xf00e, 0xf011, 0xf011, 0xf013, 0xf013, 0xf017, 0xf017, - 0xf019, 0xf019, 0xf021, 0xf021, 0xf023, 0xf023, 0xf025, 0xf025, 0xf027, 0xf028, 0xf02d, 0xf02e, 0xf030, 0xf030, - 0xf03a, 0xf03a, 0xf03d, 0xf03d, 0xf049, 0xf04c, 0xf050, 0xf050, 0xf059, 0xf059, 0xf05e, 0xf05e, 0xf062, 0xf063, - 0xf065, 0xf065, 0xf067, 0xf067, 0xf071, 0xf071, 0xf075, 0xf075, 0xf077, 0xf078, 0xf07b, 0xf07c, 0xf084, 0xf085, - 0xf091, 0xf091, 0xf0a0, 0xf0a0, 0xf0ac, 0xf0ad, 0xf0c5, 0xf0c5, 0xf0c7, 0xf0c8, 0xf0cb, 0xf0cb, 0xf0d0, 0xf0d0, - 0xf0dc, 0xf0dc, 0xf0e2, 0xf0e2, 0xf0eb, 0xf0eb, 0xf0f1, 0xf0f1, 0xf0f3, 0xf0f3, 0xf0fe, 0xf0fe, 0xf110, 0xf110, - 0xf119, 0xf119, 0xf11b, 0xf11c, 0xf140, 0xf140, 0xf144, 0xf144, 0xf14a, 0xf14a, 0xf15b, 0xf15b, 0xf15d, 0xf15d, - 0xf188, 0xf188, 0xf191, 0xf192, 0xf1dd, 0xf1de, 0xf1e6, 0xf1e6, 0xf1eb, 0xf1eb, 0xf1f8, 0xf1f8, 0xf1fc, 0xf1fc, - 0xf242, 0xf242, 0xf245, 0xf245, 0xf26c, 0xf26c, 0xf279, 0xf279, 0xf2d0, 0xf2d0, 0xf2db, 0xf2db, 0xf2f2, 0xf2f2, - 0xf2f5, 0xf2f5, 0xf3c1, 0xf3c1, 0xf410, 0xf410, 0xf466, 0xf466, 0xf500, 0xf500, 0xf51f, 0xf51f, 0xf545, 0xf545, - 0xf548, 0xf548, 0xf552, 0xf552, 0xf57a, 0xf57a, 0xf5a2, 0xf5a2, 0xf5aa, 0xf5aa, 0xf5e7, 0xf5e7, 0xf65d, 0xf65e, - 0xf6a9, 0xf6a9, 0xf7c2, 0xf7c2, 0xf807, 0xf807, 0xf815, 0xf815, 0xf818, 0xf818, 0xf84c, 0xf84c, 0xf8cc, 0xf8cc, - 0x0, 0x0}; + 0xf019, 0xf019, 0xf01c, 0xf01c, 0xf021, 0xf021, 0xf023, 0xf023, 0xf025, 0xf025, 0xf027, 0xf028, 0xf02d, 0xf02e, + 0xf030, 0xf030, 0xf03a, 0xf03a, 0xf03d, 0xf03d, 0xf049, 0xf04c, 0xf050, 0xf050, 0xf059, 0xf059, 0xf05e, 0xf05e, + 0xf062, 0xf063, 0xf065, 0xf065, 0xf067, 0xf067, 0xf071, 0xf071, 0xf075, 0xf075, 0xf077, 0xf078, 0xf07b, 0xf07c, + 0xf084, 0xf085, 0xf091, 0xf091, 0xf0a0, 0xf0a0, 0xf0ac, 0xf0ad, 0xf0c5, 0xf0c5, 0xf0c7, 0xf0c8, 0xf0cb, 0xf0cb, + 0xf0d0, 0xf0d0, 0xf0dc, 0xf0dc, 0xf0e2, 0xf0e2, 0xf0eb, 0xf0eb, 0xf0f1, 0xf0f1, 0xf0f3, 0xf0f3, 0xf0fe, 0xf0fe, + 0xf110, 0xf110, 0xf119, 0xf119, 0xf11b, 0xf11c, 0xf140, 0xf140, 0xf144, 0xf144, 0xf14a, 0xf14a, 0xf15b, 0xf15b, + 0xf15d, 0xf15d, 0xf188, 0xf188, 0xf191, 0xf192, 0xf1dd, 0xf1de, 0xf1e6, 0xf1e6, 0xf1eb, 0xf1eb, 0xf1f8, 0xf1f8, + 0xf1fc, 0xf1fc, 0xf242, 0xf242, 0xf245, 0xf245, 0xf26c, 0xf26c, 0xf279, 0xf279, 0xf2d0, 0xf2d0, 0xf2db, 0xf2db, + 0xf2f2, 0xf2f2, 0xf2f5, 0xf2f5, 0xf3c1, 0xf3c1, 0xf410, 0xf410, 0xf466, 0xf466, 0xf500, 0xf500, 0xf51f, 0xf51f, + 0xf545, 0xf545, 0xf548, 0xf548, 0xf552, 0xf552, 0xf57a, 0xf57a, 0xf5a2, 0xf5a2, 0xf5aa, 0xf5aa, 0xf5e7, 0xf5e7, + 0xf65d, 0xf65e, 0xf6a9, 0xf6a9, 0xf7c2, 0xf7c2, 0xf807, 0xf807, 0xf815, 0xf815, 0xf818, 0xf818, 0xf84c, 0xf84c, + 0xf8cc, 0xf8cc, 0x0, 0x0}; ImFontConfig cfg; cfg.MergeMode = true;