From 57c4a6ee11a3375a042268914a6e3b3d47b42b13 Mon Sep 17 00:00:00 2001 From: Felipe <54341095+Pipe530@users.noreply.github.com> Date: Thu, 15 Oct 2026 20:37:51 -0300 Subject: [PATCH] Make trophy toast duration configurable (5-10s, default 6s) (#1538) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/common/emulatorConfig.cpp | 4 ++++ src/common/emulatorConfig.h | 2 ++ src/graphics/presentation/systemOverlay.cpp | 2 +- .../forms/configuration_edit_dialog.ui | 23 +++++++++++++++++++ src/launcher/include/configuration.h | 2 ++ src/launcher/src/configuration.cpp | 5 ++++ src/launcher/src/configurationEditDialog.cpp | 2 ++ src/launcher/src/mainDialog.cpp | 1 + src/main.cpp | 7 ++++++ 9 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp index 5470bce62..cd90b7939 100644 --- a/src/common/emulatorConfig.cpp +++ b/src/common/emulatorConfig.cpp @@ -172,6 +172,10 @@ bool TrophyEnabled() { return g_config->trophy_enabled; } +uint32_t GetTrophyDurationSeconds() { + return std::clamp(g_config->trophy_duration_seconds, 5u, 10u); +} + bool PlayGoHackEnabled() { return g_config->playgo_hack_enabled; } diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h index c7d641878..fb5cb6deb 100644 --- a/src/common/emulatorConfig.h +++ b/src/common/emulatorConfig.h @@ -79,6 +79,7 @@ struct ConfigOptions { bool sync_raw_image_buffers = false; bool tessellation_enabled = false; bool trophy_enabled = true; + uint32_t trophy_duration_seconds = 6; bool playgo_hack_enabled = false; bool skip_notice_screen = false; #if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS @@ -135,6 +136,7 @@ bool ReadbackLinearImagesEnabled(); bool SyncRawImageBuffersEnabled(); bool TessellationEnabled(); bool TrophyEnabled(); +uint32_t GetTrophyDurationSeconds(); bool PlayGoHackEnabled(); bool SkipNoticeScreen(); #if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS diff --git a/src/graphics/presentation/systemOverlay.cpp b/src/graphics/presentation/systemOverlay.cpp index f39d2c73e..9197644d1 100644 --- a/src/graphics/presentation/systemOverlay.cpp +++ b/src/graphics/presentation/systemOverlay.cpp @@ -1199,7 +1199,7 @@ struct SystemOverlay::Impl { ImGui::UnregisterUserTexture(texture.get()); return true; }); - constexpr float TOAST_LIFETIME = 5.0f; + const float TOAST_LIFETIME = static_cast(Config::GetTrophyDurationSeconds()); if (trophy_notification && std::chrono::duration(now - trophy_notification_born).count() >= TOAST_LIFETIME) { diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index b79c83f0e..792da6a37 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -201,6 +201,29 @@ true + + + + + Trophy notification duration: + + + + + How long each trophy unlock notification stays on screen. + s + 5 + 10 + 6 + + + + + Qt::Horizontal + + + + diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h index e4bf3c8bf..2f743c3b4 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -123,6 +123,7 @@ public: bool sync_raw_image_buffers = false; bool tessellation_enabled = false; bool trophy_enabled = true; + int trophy_duration_seconds = 6; bool skip_notice_screen = false; bool network_connected = false; int vblank_frequency = 60; @@ -160,6 +161,7 @@ public: sync_raw_image_buffers = other.sync_raw_image_buffers; tessellation_enabled = other.tessellation_enabled; trophy_enabled = other.trophy_enabled; + trophy_duration_seconds = other.trophy_duration_seconds; skip_notice_screen = other.skip_notice_screen; network_connected = other.network_connected; vblank_frequency = other.vblank_frequency; diff --git a/src/launcher/src/configuration.cpp b/src/launcher/src/configuration.cpp index b2527f39e..5f394b6c6 100644 --- a/src/launcher/src/configuration.cpp +++ b/src/launcher/src/configuration.cpp @@ -16,6 +16,7 @@ QVariantMap Configuration::GameSettings() const { KYTY_CFG_SET(sync_raw_image_buffers); KYTY_CFG_SET(tessellation_enabled); KYTY_CFG_SET(trophy_enabled); + KYTY_CFG_SET(trophy_duration_seconds); KYTY_CFG_SET(skip_notice_screen); KYTY_CFG_SET(network_connected); KYTY_CFG_SET(vblank_frequency); @@ -63,6 +64,7 @@ void Configuration::ReadGameSettingsValues(const Settings& s) { KYTY_CFG_GET(sync_raw_image_buffers); KYTY_CFG_GET(tessellation_enabled); trophy_enabled = s.value("trophy_enabled", trophy_enabled).toBool(); + KYTY_CFG_GET(trophy_duration_seconds); KYTY_CFG_GET(skip_notice_screen); KYTY_CFG_GET(network_connected); vblank_frequency = s.value("vblank_frequency", vblank_frequency).toInt(); @@ -143,6 +145,9 @@ bool Configuration::SetGameSettings(const QJsonObject& settings, QString& error) if (vblank_frequency < 30 || vblank_frequency > 360) { return fail(tr("Vblank frequency must be between 30 and 360.")); } + if (trophy_duration_seconds < 5 || trophy_duration_seconds > 10) { + return fail(tr("Trophy notification duration must be between 5 and 10 seconds.")); + } if ((shader_log_direction == LogDirection::File && shader_log_folder.isEmpty()) || (printf_direction == LogDirection::File && printf_output_file.isEmpty()) || (command_buffer_dump_enabled && command_buffer_dump_folder.isEmpty())) { diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp index 4c95ef6a7..65e1b195a 100644 --- a/src/launcher/src/configurationEditDialog.cpp +++ b/src/launcher/src/configurationEditDialog.cpp @@ -281,6 +281,7 @@ void ConfigurationEditDialog::Init(const Configuration& info) { m_ui->checkBox_skip_notice_screen->setChecked(info.skip_notice_screen); m_ui->checkBox_network_connected->setChecked(info.network_connected); m_ui->checkBox_trophy_notifications->setChecked(info.trophy_enabled); + m_ui->spinBox_trophy_duration->setValue(info.trophy_duration_seconds); m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency); m_ui->comboBox_console_language->clear(); m_ui->comboBox_console_language->addItems(CONSOLE_LANGUAGE_NAMES); @@ -444,6 +445,7 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui, boo info.skip_notice_screen = ui.checkBox_skip_notice_screen->isChecked(); info.network_connected = ui.checkBox_network_connected->isChecked(); info.trophy_enabled = ui.checkBox_trophy_notifications->isChecked(); + info.trophy_duration_seconds = ui.spinBox_trophy_duration->value(); info.vblank_frequency = ui.spinBox_vblank_frequency->value(); info.console_language = ui.comboBox_console_language->currentIndex(); info.vulkan_validation_enabled = ui.checkBox_vulkan_validation->isChecked(); diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp index 260999331..03f90b316 100644 --- a/src/launcher/src/mainDialog.cpp +++ b/src/launcher/src/mainDialog.cpp @@ -254,6 +254,7 @@ static QStringList CreateEmulatorArgs(const Configuration& info) { args << "--readback-linear-images" << BoolArg(info.readback_linear_images); args << "--sync-raw-image-buffers" << BoolArg(info.sync_raw_image_buffers); args << "--trophy-notifications" << BoolArg(info.trophy_enabled); + args << "--trophy-duration" << QString::number(info.trophy_duration_seconds); args << "--skip-notice-screen" << BoolArg(info.skip_notice_screen); args << "--network-connected" << BoolArg(info.network_connected); if (info.tessellation_enabled) { diff --git a/src/main.cpp b/src/main.cpp index a96101022..7f6d8f87a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -91,6 +91,8 @@ static void PrintUsage() { " --sync-raw-image-buffers Synchronize raw reads of GPU images. Default: false.\n"); ::printf( " --trophy-notifications Show trophy unlock toasts and play their sound.\n"); + ::printf( + " --trophy-duration Trophy toast duration, 5-10. Default: 6.\n"); ::printf(" --playgo-hack Use the supplied PlayGo stub fallback.\n"); ::printf( " --skip-notice-screen Skip startup logos and notices in supported games.\n" @@ -384,6 +386,11 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he ::printf("invalid vblank frequency: %s\n", value.c_str()); return false; } + } else if (arg == "--trophy-duration") { + if (!ParseUint32(value, options.config.trophy_duration_seconds)) { + ::printf("invalid trophy duration: %s\n", value.c_str()); + return false; + } } else if (arg == "--console-language") { if (!ParseConsoleLanguage(value, options.config.console_language)) { ::printf("invalid console language: %s\n", value.c_str());