Achievements: Add option to disable notifications

This commit is contained in:
Connor McLaughlin 2022-11-05 15:01:48 +10:00
parent 601e3586b2
commit a6a52b31ad
7 changed files with 92 additions and 66 deletions

View file

@ -350,6 +350,7 @@ void Settings::Load(SettingsInterface& si)
achievements_rich_presence = si.GetBoolValue("Cheevos", "RichPresence", true); achievements_rich_presence = si.GetBoolValue("Cheevos", "RichPresence", true);
achievements_challenge_mode = si.GetBoolValue("Cheevos", "ChallengeMode", false); achievements_challenge_mode = si.GetBoolValue("Cheevos", "ChallengeMode", false);
achievements_leaderboards = si.GetBoolValue("Cheevos", "Leaderboards", true); achievements_leaderboards = si.GetBoolValue("Cheevos", "Leaderboards", true);
achievements_notifications = si.GetBoolValue("Cheevos", "Notifications", true);
achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true); achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true);
achievements_primed_indicators = si.GetBoolValue("Cheevos", "PrimedIndicators", 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", "RichPresence", achievements_rich_presence);
si.SetBoolValue("Cheevos", "ChallengeMode", achievements_challenge_mode); si.SetBoolValue("Cheevos", "ChallengeMode", achievements_challenge_mode);
si.SetBoolValue("Cheevos", "Leaderboards", achievements_leaderboards); si.SetBoolValue("Cheevos", "Leaderboards", achievements_leaderboards);
si.SetBoolValue("Cheevos", "Notifications", achievements_notifications);
si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects); si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects);
si.SetBoolValue("Cheevos", "PrimedIndicators", achievements_primed_indicators); si.SetBoolValue("Cheevos", "PrimedIndicators", achievements_primed_indicators);

View file

@ -178,6 +178,7 @@ struct Settings
bool achievements_rich_presence = true; bool achievements_rich_presence = true;
bool achievements_challenge_mode = false; bool achievements_challenge_mode = false;
bool achievements_leaderboards = true; bool achievements_leaderboards = true;
bool achievements_notifications = true;
bool achievements_sound_effects = true; bool achievements_sound_effects = true;
bool achievements_primed_indicators = true; bool achievements_primed_indicators = true;
#endif #endif

View file

@ -25,6 +25,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useFirstDiscFromPlaylist, "Cheevos", SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useFirstDiscFromPlaylist, "Cheevos",
"UseFirstDiscFromPlaylist", true); "UseFirstDiscFromPlaylist", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.leaderboards, "Cheevos", "Leaderboards", 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.soundEffects, "Cheevos", "SoundEffects", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.primedIndicators, "Cheevos", "PrimedIndicators", 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"), dialog->registerWidgetHelp(m_ui.challengeMode, tr("Enable Hardcore Mode"), tr("Unchecked"),
tr("\"Challenge\" mode for achievements, including leaderboard tracking. Disables save " tr("\"Challenge\" mode for achievements, including leaderboard tracking. Disables save "
"state, cheats, and slowdown functions.")); "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( dialog->registerWidgetHelp(
m_ui.soundEffects, tr("Enable Sound Effects"), tr("Checked"), m_ui.soundEffects, tr("Enable Sound Effects"), tr("Checked"),
tr("Plays sound effects for events such as achievement unlocks and leaderboard submissions.")); 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.")); 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.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::updateEnableState);
connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::onChallengeModeStateChanged); 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 enabled = m_dialog->getEffectiveBoolValue("Cheevos", "Enabled", false);
const bool challenge = m_dialog->getEffectiveBoolValue("Cheevos", "ChallengeMode", 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.testMode->setEnabled(enabled);
m_ui.useFirstDiscFromPlaylist->setEnabled(enabled); m_ui.useFirstDiscFromPlaylist->setEnabled(enabled);
m_ui.richPresence->setEnabled(enabled); m_ui.richPresence->setEnabled(enabled);
m_ui.challengeMode->setEnabled(enabled); m_ui.challengeMode->setEnabled(enabled);
m_ui.leaderboards->setEnabled(enabled && challenge); m_ui.leaderboards->setEnabled(enabled && challenge);
m_ui.unofficialTestMode->setEnabled(enabled); 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); m_ui.primedIndicators->setEnabled(enabled);
} }

View file

@ -32,24 +32,10 @@
<string>Global Settings</string> <string>Global Settings</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="unofficialTestMode"> <widget class="QCheckBox" name="richPresence">
<property name="text"> <property name="text">
<string>Test Unofficial Achievements</string> <string>Enable Rich Presence</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="soundEffects">
<property name="text">
<string>Enable Sound Effects</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="enable">
<property name="text">
<string>Enable Achievements</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -60,17 +46,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="primedIndicators"> <widget class="QCheckBox" name="enable">
<property name="text"> <property name="text">
<string>Show Challenge Indicators</string> <string>Enable Achievements</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="richPresence">
<property name="text">
<string>Enable Rich Presence</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -81,6 +60,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QCheckBox" name="primedIndicators">
<property name="text">
<string>Show Challenge Indicators</string>
</property>
</widget>
</item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QCheckBox" name="useFirstDiscFromPlaylist"> <widget class="QCheckBox" name="useFirstDiscFromPlaylist">
<property name="text"> <property name="text">
@ -88,13 +74,34 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QCheckBox" name="testMode"> <widget class="QCheckBox" name="testMode">
<property name="text"> <property name="text">
<string>Enable Test Mode</string> <string>Enable Test Mode</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1">
<widget class="QCheckBox" name="unofficialTestMode">
<property name="text">
<string>Test Unofficial Achievements</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="soundEffects">
<property name="text">
<string>Enable Sound Effects</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="notifications">
<property name="text">
<string>Show Notifications</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View file

@ -1020,18 +1020,20 @@ void Achievements::DisplayAchievementSummary()
} }
Host::RunOnCPUThread([title = std::move(title), summary = std::move(summary), icon = s_game_icon]() { 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)); 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. // 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) if (g_settings.achievements_sound_effects)
FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str()); FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str());
}
}); });
} }
void Achievements::DisplayMasteredNotification() void Achievements::DisplayMasteredNotification()
{ {
if (!FullscreenUI::IsInitialized()) if (!FullscreenUI::IsInitialized() || !g_settings.achievements_notifications)
return; return;
std::string title(fmt::format("Mastered {}", s_game_title)); std::string title(fmt::format("Mastered {}", s_game_title));
@ -1757,7 +1759,7 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, std::string conten
return; return;
const Leaderboard* lb = GetLeaderboardByID(std::exchange(s_submitting_lboard_id, 0u)); const Leaderboard* lb = GetLeaderboardByID(std::exchange(s_submitting_lboard_id, 0u));
if (!lb) if (!lb || !FullscreenUI::IsInitialized() || !g_settings.achievements_notifications)
return; return;
char submitted_score[128]; char submitted_score[128];
@ -1797,6 +1799,8 @@ 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); Log_InfoPrintf("Achievement %s (%u) for game %u unlocked", achievement->title.c_str(), achievement_id, s_game_id);
if (FullscreenUI::IsInitialized() && g_settings.achievements_notifications)
{
std::string title; std::string title;
switch (achievement->category) switch (achievement->category)
{ {
@ -1816,6 +1820,7 @@ void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification /
GetAchievementBadgePath(*achievement)); GetAchievementBadgePath(*achievement));
if (g_settings.achievements_sound_effects) if (g_settings.achievements_sound_effects)
FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str()); FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str());
}
if (IsMastered()) if (IsMastered())
DisplayMasteredNotification(); DisplayMasteredNotification();

View file

@ -4208,6 +4208,7 @@ void FullscreenUI::DrawAchievementsSettingsPage()
const bool enabled = bsi->GetBoolValue("Cheevos", "Enabled", false); const bool enabled = bsi->GetBoolValue("Cheevos", "Enabled", false);
const bool challenge = bsi->GetBoolValue("Cheevos", "ChallengeMode", 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", DrawToggleSetting(bsi, ICON_FA_USER_FRIENDS " Rich Presence",
"When enabled, rich presence information will be collected and sent to the server where supported.", "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", DrawToggleSetting(bsi, ICON_FA_LIST_OL " Leaderboards",
"Enables tracking and submission of leaderboards in supported games.", "Cheevos", "Leaderboards", "Enables tracking and submission of leaderboards in supported games.", "Cheevos", "Leaderboards",
true, enabled && challenge); 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.", "Plays sound effects for events such as achievement unlocks and leaderboard submissions.",
"Cheevos", "SoundEffects", true, enabled); "Cheevos", "SoundEffects", true, enabled && notifications);
DrawToggleSetting( DrawToggleSetting(
bsi, ICON_FA_MAGIC " Show Challenge Indicators", 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", "Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active.", "Cheevos",

View file

@ -460,18 +460,18 @@ bool ImGuiManager::AddIconFonts(float size)
{ {
static constexpr ImWchar range_fa[] = { static constexpr ImWchar range_fa[] = {
0xf002, 0xf002, 0xf005, 0xf005, 0xf007, 0xf007, 0xf00c, 0xf00e, 0xf011, 0xf011, 0xf013, 0xf013, 0xf017, 0xf017, 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, 0xf019, 0xf019, 0xf01c, 0xf01c, 0xf021, 0xf021, 0xf023, 0xf023, 0xf025, 0xf025, 0xf027, 0xf028, 0xf02d, 0xf02e,
0xf03a, 0xf03a, 0xf03d, 0xf03d, 0xf049, 0xf04c, 0xf050, 0xf050, 0xf059, 0xf059, 0xf05e, 0xf05e, 0xf062, 0xf063, 0xf030, 0xf030, 0xf03a, 0xf03a, 0xf03d, 0xf03d, 0xf049, 0xf04c, 0xf050, 0xf050, 0xf059, 0xf059, 0xf05e, 0xf05e,
0xf065, 0xf065, 0xf067, 0xf067, 0xf071, 0xf071, 0xf075, 0xf075, 0xf077, 0xf078, 0xf07b, 0xf07c, 0xf084, 0xf085, 0xf062, 0xf063, 0xf065, 0xf065, 0xf067, 0xf067, 0xf071, 0xf071, 0xf075, 0xf075, 0xf077, 0xf078, 0xf07b, 0xf07c,
0xf091, 0xf091, 0xf0a0, 0xf0a0, 0xf0ac, 0xf0ad, 0xf0c5, 0xf0c5, 0xf0c7, 0xf0c8, 0xf0cb, 0xf0cb, 0xf0d0, 0xf0d0, 0xf084, 0xf085, 0xf091, 0xf091, 0xf0a0, 0xf0a0, 0xf0ac, 0xf0ad, 0xf0c5, 0xf0c5, 0xf0c7, 0xf0c8, 0xf0cb, 0xf0cb,
0xf0dc, 0xf0dc, 0xf0e2, 0xf0e2, 0xf0eb, 0xf0eb, 0xf0f1, 0xf0f1, 0xf0f3, 0xf0f3, 0xf0fe, 0xf0fe, 0xf110, 0xf110, 0xf0d0, 0xf0d0, 0xf0dc, 0xf0dc, 0xf0e2, 0xf0e2, 0xf0eb, 0xf0eb, 0xf0f1, 0xf0f1, 0xf0f3, 0xf0f3, 0xf0fe, 0xf0fe,
0xf119, 0xf119, 0xf11b, 0xf11c, 0xf140, 0xf140, 0xf144, 0xf144, 0xf14a, 0xf14a, 0xf15b, 0xf15b, 0xf15d, 0xf15d, 0xf110, 0xf110, 0xf119, 0xf119, 0xf11b, 0xf11c, 0xf140, 0xf140, 0xf144, 0xf144, 0xf14a, 0xf14a, 0xf15b, 0xf15b,
0xf188, 0xf188, 0xf191, 0xf192, 0xf1dd, 0xf1de, 0xf1e6, 0xf1e6, 0xf1eb, 0xf1eb, 0xf1f8, 0xf1f8, 0xf1fc, 0xf1fc, 0xf15d, 0xf15d, 0xf188, 0xf188, 0xf191, 0xf192, 0xf1dd, 0xf1de, 0xf1e6, 0xf1e6, 0xf1eb, 0xf1eb, 0xf1f8, 0xf1f8,
0xf242, 0xf242, 0xf245, 0xf245, 0xf26c, 0xf26c, 0xf279, 0xf279, 0xf2d0, 0xf2d0, 0xf2db, 0xf2db, 0xf2f2, 0xf2f2, 0xf1fc, 0xf1fc, 0xf242, 0xf242, 0xf245, 0xf245, 0xf26c, 0xf26c, 0xf279, 0xf279, 0xf2d0, 0xf2d0, 0xf2db, 0xf2db,
0xf2f5, 0xf2f5, 0xf3c1, 0xf3c1, 0xf410, 0xf410, 0xf466, 0xf466, 0xf500, 0xf500, 0xf51f, 0xf51f, 0xf545, 0xf545, 0xf2f2, 0xf2f2, 0xf2f5, 0xf2f5, 0xf3c1, 0xf3c1, 0xf410, 0xf410, 0xf466, 0xf466, 0xf500, 0xf500, 0xf51f, 0xf51f,
0xf548, 0xf548, 0xf552, 0xf552, 0xf57a, 0xf57a, 0xf5a2, 0xf5a2, 0xf5aa, 0xf5aa, 0xf5e7, 0xf5e7, 0xf65d, 0xf65e, 0xf545, 0xf545, 0xf548, 0xf548, 0xf552, 0xf552, 0xf57a, 0xf57a, 0xf5a2, 0xf5a2, 0xf5aa, 0xf5aa, 0xf5e7, 0xf5e7,
0xf6a9, 0xf6a9, 0xf7c2, 0xf7c2, 0xf807, 0xf807, 0xf815, 0xf815, 0xf818, 0xf818, 0xf84c, 0xf84c, 0xf8cc, 0xf8cc, 0xf65d, 0xf65e, 0xf6a9, 0xf6a9, 0xf7c2, 0xf7c2, 0xf807, 0xf807, 0xf815, 0xf815, 0xf818, 0xf818, 0xf84c, 0xf84c,
0x0, 0x0}; 0xf8cc, 0xf8cc, 0x0, 0x0};
ImFontConfig cfg; ImFontConfig cfg;
cfg.MergeMode = true; cfg.MergeMode = true;