Achievement: Fix default custom sound effect behavior

Achievements: Preview custom sounds directly instead of using/opening the system's default audio player.
This commit is contained in:
KamFretoZ
2026-04-06 00:15:57 +07:00
committed by lightningterror
parent 87319a2d2f
commit cc8292753f
7 changed files with 60 additions and 53 deletions
+15 -26
View File
@@ -23,6 +23,7 @@
#include <QtWidgets/QSpinBox> #include <QtWidgets/QSpinBox>
#include "common/FileSystem.h" #include "common/FileSystem.h"
#include "common/HostSys.h"
#include "common/Path.h" #include "common/Path.h"
#include "pcsx2/Config.h" #include "pcsx2/Config.h"
@@ -1261,8 +1262,8 @@ namespace SettingWidgetBinder
widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed)); widget->connect(widget, &QLineEdit::editingFinished, widget, std::move(value_changed));
} }
static inline void BindWidgetToFileSetting(SettingsInterface* sif, QLineEdit* widget, QAbstractButton* browse_button, static inline void BindWidgetToAudioFileSetting(SettingsInterface* sif, QLineEdit* widget, QAbstractButton* browse_button,
QAbstractButton* open_button, QAbstractButton* reset_button, std::string section, std::string key, std::string default_value, QAbstractButton* preview_button, QAbstractButton* reset_button, std::string section, std::string key, std::string default_value,
const QString& filter, bool allow_pergame = false, bool use_relative = true) const QString& filter, bool allow_pergame = false, bool use_relative = true)
{ {
using Accessor = SettingAccessor<QLineEdit>; using Accessor = SettingAccessor<QLineEdit>;
@@ -1296,40 +1297,25 @@ namespace SettingWidgetBinder
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str()); Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), relative_path.c_str());
} }
else else
{
Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.c_str()); Host::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.c_str());
}
if (!FileSystem::FileExists(new_value.c_str())) if (!FileSystem::FileExists(new_value.c_str()))
{
QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"), QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"),
qApp->translate("SettingWidgetBinder", "File cannot be found.")); qApp->translate("SettingWidgetBinder", "File cannot be found."));
}
Host::CommitBaseSettingChanges(); Host::CommitBaseSettingChanges();
return; return;
} }
else else
{ Host::RemoveBaseSettingValue(section.c_str(), key.c_str());
QMessageBox::critical(QtUtils::GetRootWidget(widget), qApp->translate("SettingWidgetBinder", "Error"),
qApp->translate("SettingWidgetBinder", "File path cannot be empty."));
}
// reset to old value
std::string current_path(Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str()));
if (current_path.empty())
current_path = default_value;
else if (use_relative && !Path::IsAbsolute(current_path))
current_path = Path::Canonicalize(Path::Combine(EmuFolders::DataRoot, current_path));
widget->setText(QString::fromStdString(current_path));
}; };
if (browse_button) if (browse_button)
{ {
QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key, value_changed, filter]() { QObject::connect(browse_button, &QAbstractButton::clicked, browse_button, [widget, key, value_changed, filter]() {
const QString path(QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(widget), const QString path(QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(widget),
qApp->translate("SettingWidgetBinder", "Select File"), QString(), filter))); qApp->translate("SettingWidgetBinder", "Select Audio File"), QString(), filter)));
if (path.isEmpty()) if (path.isEmpty())
return; return;
@@ -1337,19 +1323,22 @@ namespace SettingWidgetBinder
value_changed(); value_changed();
}); });
} }
if (open_button) if (preview_button)
{ {
QObject::connect(open_button, &QAbstractButton::clicked, open_button, [widget]() { QObject::connect(preview_button, &QAbstractButton::clicked, preview_button, [widget, default_value = std::move(default_value)]() {
QString path(Accessor::getStringValue(widget)); const QByteArray path = widget->text().toUtf8();
if (!path.isEmpty()) Common::PlaySoundAsync(
QtUtils::OpenURL(QtUtils::GetRootWidget(widget), QUrl::fromLocalFile(path)); (path.isEmpty()
? default_value
: path.constData()).c_str()
);
}); });
} }
if (reset_button) if (reset_button)
{ {
QObject::connect( QObject::connect(
reset_button, &QAbstractButton::clicked, reset_button, [widget, default_value = std::move(default_value), value_changed]() { reset_button, &QAbstractButton::clicked, reset_button, [widget, value_changed]() {
widget->setText(QString::fromStdString(default_value)); widget->clear();
value_changed(); value_changed();
}); });
} }
@@ -17,7 +17,10 @@
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtWidgets/QMessageBox> #include <QtWidgets/QMessageBox>
const char* AchievementSettingsWidget::AUDIO_FILE_FILTER = QT_TRANSLATE_NOOP("AchievementSettingsWidget", "WAV Audio Files (*.wav)"); static constexpr const char* AUDIO_FILE_FILTER = QT_TRANSLATE_NOOP("AchievementSettingsWidget", "WAV Audio Files (*.wav)");
static constexpr const char* DEFAULT_INFO_SOUND_NAME = "sounds/achievements/message.wav";
static constexpr const char* DEFAULT_UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav";
static constexpr const char* DEFAULT_LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* settings_dialog, QWidget* parent) AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* settings_dialog, QWidget* parent)
: SettingsWidget(settings_dialog, parent) : SettingsWidget(settings_dialog, parent)
@@ -44,9 +47,9 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* settings_di
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.achievementNotificationsDuration, "Achievements", "NotificationsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_NOTIFICATION_DURATION); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.achievementNotificationsDuration, "Achievements", "NotificationsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_NOTIFICATION_DURATION);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.leaderboardNotificationsDuration, "Achievements", "LeaderboardsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_LEADERBOARD_DURATION); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.leaderboardNotificationsDuration, "Achievements", "LeaderboardsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_LEADERBOARD_DURATION);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.notificationSoundPath, m_ui.notificationSoundBrowse, m_ui.notificationSoundOpen, m_ui.notificationSoundReset, "Achievements", "InfoSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_INFO_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false); SettingWidgetBinder::BindWidgetToAudioFileSetting(sif, m_ui.notificationSoundPath, m_ui.notificationSoundBrowse, m_ui.notificationSoundOpen, m_ui.notificationSoundReset, "Achievements", "InfoSoundName", Path::Combine(EmuFolders::Resources, DEFAULT_INFO_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.unlockSoundPath, m_ui.unlockSoundBrowse, m_ui.unlockSoundOpen, m_ui.unlockSoundReset, "Achievements", "UnlockSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_UNLOCK_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false); SettingWidgetBinder::BindWidgetToAudioFileSetting(sif, m_ui.unlockSoundPath, m_ui.unlockSoundBrowse, m_ui.unlockSoundOpen, m_ui.unlockSoundReset, "Achievements", "UnlockSoundName", Path::Combine(EmuFolders::Resources, DEFAULT_UNLOCK_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false);
SettingWidgetBinder::BindWidgetToFileSetting(sif, m_ui.lbSoundPath, m_ui.lbSoundBrowse, m_ui.lbSoundOpen, m_ui.lbSoundReset, "Achievements", "LBSubmitSoundName", Path::Combine(EmuFolders::Resources, EmuConfig.Achievements.DEFAULT_LBSUBMIT_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false); SettingWidgetBinder::BindWidgetToAudioFileSetting(sif, m_ui.lbSoundPath, m_ui.lbSoundBrowse, m_ui.lbSoundOpen, m_ui.lbSoundReset, "Achievements", "LBSubmitSoundName", Path::Combine(EmuFolders::Resources, DEFAULT_LBSUBMIT_SOUND_NAME), qApp->translate("AchievementSettingsWidget", AUDIO_FILE_FILTER), true, false);
dialog()->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"), tr("When enabled and logged in, PCSX2 will scan for achievements on startup.")); dialog()->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"), tr("When enabled and logged in, PCSX2 will scan for achievements on startup."));
dialog()->registerWidgetHelp(m_ui.hardcoreMode, 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.hardcoreMode, tr("Enable Hardcore Mode"), tr("Unchecked"), tr("\"Challenge\" mode for achievements, including leaderboard tracking. Disables save state, cheats, and slowdown functions."));
@@ -26,7 +26,6 @@ private Q_SLOTS:
private: private:
void updateLoginState(); void updateLoginState();
static const char* AUDIO_FILE_FILTER;
Ui::AchievementSettingsWidget m_ui; Ui::AchievementSettingsWidget m_ui;
}; };
+19 -7
View File
@@ -316,10 +316,18 @@
</property> </property>
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QGridLayout" name="gridLayout_6">
<item row="5" column="0"> <item row="5" column="0">
<widget class="QLineEdit" name="lbSoundPath"/> <widget class="QLineEdit" name="lbSoundPath">
<property name="placeholderText">
<string>Default Sound Effect</string>
</property>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLineEdit" name="notificationSoundPath"/> <widget class="QLineEdit" name="notificationSoundPath">
<property name="placeholderText">
<string>Default Sound Effect</string>
</property>
</widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QPushButton" name="unlockSoundBrowse"> <widget class="QPushButton" name="unlockSoundBrowse">
@@ -350,7 +358,11 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLineEdit" name="unlockSoundPath"/> <widget class="QLineEdit" name="unlockSoundPath">
<property name="placeholderText">
<string>Default Sound Effect</string>
</property>
</widget>
</item> </item>
<item row="5" column="1"> <item row="5" column="1">
<widget class="QPushButton" name="lbSoundBrowse"> <widget class="QPushButton" name="lbSoundBrowse">
@@ -426,12 +438,12 @@ Login token generated at:</string>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
</property>
<property name="buddy"> <property name="buddy">
<cstring>viewProfile</cstring> <cstring>viewProfile</cstring>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@@ -473,7 +485,7 @@ Login token generated at:</string>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property> </property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set> <set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
</property> </property>
</widget> </widget>
</item> </item>
+19 -3
View File
@@ -63,6 +63,10 @@ namespace Achievements
static constexpr float LEADERBOARD_STARTED_NOTIFICATION_TIME = 3.0f; static constexpr float LEADERBOARD_STARTED_NOTIFICATION_TIME = 3.0f;
static constexpr float LEADERBOARD_FAILED_NOTIFICATION_TIME = 3.0f; static constexpr float LEADERBOARD_FAILED_NOTIFICATION_TIME = 3.0f;
static constexpr const char* DEFAULT_INFO_SOUND_NAME = "sounds/achievements/message.wav";
static constexpr const char* DEFAULT_UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav";
static constexpr const char* DEFAULT_LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
static constexpr float INDICATOR_FADE_IN_TIME = 0.1f; static constexpr float INDICATOR_FADE_IN_TIME = 0.1f;
static constexpr float INDICATOR_FADE_OUT_TIME = 0.5f; static constexpr float INDICATOR_FADE_OUT_TIME = 0.5f;
@@ -1142,7 +1146,11 @@ void Achievements::DisplayAchievementSummary()
} }
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.InfoSound) if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.InfoSound)
Common::PlaySoundAsync(EmuConfig.Achievements.InfoSoundName.c_str()); Common::PlaySoundAsync(
(EmuConfig.Achievements.InfoSoundName.empty()
? Path::Combine(EmuFolders::Resources, DEFAULT_INFO_SOUND_NAME)
: EmuConfig.Achievements.InfoSoundName).c_str()
);
} }
void Achievements::DisplayHardcoreDeferredMessage() void Achievements::DisplayHardcoreDeferredMessage()
@@ -1194,7 +1202,11 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
} }
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.UnlockSound) if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.UnlockSound)
Common::PlaySoundAsync(EmuConfig.Achievements.UnlockSoundName.c_str()); Common::PlaySoundAsync(
(EmuConfig.Achievements.UnlockSoundName.empty()
? Path::Combine(EmuFolders::Resources, DEFAULT_UNLOCK_SOUND_NAME)
: EmuConfig.Achievements.UnlockSoundName).c_str()
);
} }
void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event) void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
@@ -1315,7 +1327,11 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
} }
if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.LBSubmitSound) if (EmuConfig.Achievements.SoundEffects && EmuConfig.Achievements.LBSubmitSound)
Common::PlaySoundAsync(EmuConfig.Achievements.LBSubmitSoundName.c_str()); Common::PlaySoundAsync(
(EmuConfig.Achievements.LBSubmitSoundName.empty()
? Path::Combine(EmuFolders::Resources, DEFAULT_LBSUBMIT_SOUND_NAME)
: EmuConfig.Achievements.LBSubmitSoundName).c_str()
);
} }
void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event) void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event)
-3
View File
@@ -1285,9 +1285,6 @@ struct Pcsx2Config
static constexpr u32 MAXIMUM_NOTIFICATION_DURATION = 30; static constexpr u32 MAXIMUM_NOTIFICATION_DURATION = 30;
static constexpr u32 DEFAULT_NOTIFICATION_DURATION = 5; static constexpr u32 DEFAULT_NOTIFICATION_DURATION = 5;
static constexpr u32 DEFAULT_LEADERBOARD_DURATION = 10; static constexpr u32 DEFAULT_LEADERBOARD_DURATION = 10;
static constexpr const char* DEFAULT_INFO_SOUND_NAME = "sounds/achievements/message.wav";
static constexpr const char* DEFAULT_UNLOCK_SOUND_NAME = "sounds/achievements/unlock.wav";
static constexpr const char* DEFAULT_LBSUBMIT_SOUND_NAME = "sounds/achievements/lbsubmit.wav";
static const char* OverlayPositionNames[(size_t)AchievementOverlayPosition::MaxCount + 1]; static const char* OverlayPositionNames[(size_t)AchievementOverlayPosition::MaxCount + 1];
-9
View File
@@ -1884,15 +1884,6 @@ void Pcsx2Config::AchievementsOptions::LoadSave(SettingsWrapper& wrap)
{ {
SettingsWrapSection("Achievements"); SettingsWrapSection("Achievements");
if (InfoSoundName.empty())
InfoSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_INFO_SOUND_NAME);
if (UnlockSoundName.empty())
UnlockSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_UNLOCK_SOUND_NAME);
if (LBSubmitSoundName.empty())
LBSubmitSoundName = Path::Combine(EmuFolders::Resources, DEFAULT_LBSUBMIT_SOUND_NAME);
SettingsWrapBitBool(Enabled); SettingsWrapBitBool(Enabled);
SettingsWrapBitBoolEx(HardcoreMode, "ChallengeMode"); SettingsWrapBitBoolEx(HardcoreMode, "ChallengeMode");
SettingsWrapBitBool(EncoreMode); SettingsWrapBitBool(EncoreMode);