From 2ff936e4fbad5adc0ead2445cde50f6c5af2df95 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 10 Sep 2024 22:10:42 +1000 Subject: [PATCH] Settings: Remove second source of truth for OSD notifications And split it into warnings/messages. Warnings are always displayed regardless of the "Show OSD Messages" setting, because they're critical and users forget they disable messages. --- README.md | 13 +- src/core/game_database.cpp | 6 +- src/core/host.cpp | 3 +- src/core/settings.cpp | 4 +- src/core/settings.h | 1 - src/core/system.cpp | 107 ++++++++-------- src/duckstation-qt/graphicssettingswidget.cpp | 2 +- src/util/imgui_manager.cpp | 118 ++++++++++++++---- src/util/imgui_manager.h | 8 +- 9 files changed, 170 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index 43cd070cd..2e3fd645b 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ To download: You will need a device with armv7 (32-bit ARM), AArch64 (64-bit ARM), or x86_64 (64-bit x86). 64-bit is preferred, the requirements are higher for 32-bit, you'll probably want at least a 1.5GHz CPU. Download from Google Play: https://play.google.com/store/apps/details?id=com.github.stenzek.duckstation + APK and Beta Downloads: https://www.duckstation.org/android/ **No support is provided for the Android app**, it is free and your expectations should be in line with that. Please **do not** email me about issues about it, or ask for help, you will be ignored. @@ -206,9 +207,9 @@ If you wish to use a "portable" build, where the user directory is the same as w in the same directory as the DuckStation executable. ## Bindings for Qt frontend -Your keyboard or game controller can be used to simulate a variety of PlayStation controllers. Controller input is supported through DInput, XInput, and SDL backends and can be changed through `Settings -> General Settings`. +Your keyboard or game controller can be used to simulate a variety of PlayStation controllers. Controller input is supported through DInput, XInput, and SDL backends and can be changed through `Settings -> Controllers`. -To bind your input device, go to `Settings -> Controllers`. Each of the buttons/axes for the simulated controller will be listed, alongside the corresponding key/button on your device that it is currently bound to. To rebind, click the box next to the button/axis name, and press the key or button on your input device that you wish to bind to. When binding rumble, simply press any button on the controller you wish to send rumble to. +To bind your input device, go to `Settings -> Controllers`, and select the virtual controller you want to map. Automatic mapping handles the majority of ocntrollers. However, if you need to manually bind a controller, click the box below the button/axis name, and press the key or button on your input device that you wish to bind to. ## SDL Game Controller Database DuckStation releases ship with a database of game controller mappings for the SDL controller backend, courtesy of https://github.com/mdqinc/SDL_GameControllerDB. The included `gamecontrollerdb.txt` file can be found in the `resources` subdirectory of the DuckStation program directory. @@ -216,6 +217,9 @@ DuckStation releases ship with a database of game controller mappings for the SD If you are experiencing issues binding your controller with the SDL controller backend, you may need to add a custom mapping to the database file. Make a copy of `gamecontrollerdb.txt` and place it in your [user directory](#user-directories) (or directly in the program directory, if running in portable mode) and then follow the instructions in the [SDL_GameControllerDB repository](https://github.com/mdqinc/SDL_GameControllerDB) for creating a new mapping. Add this mapping to the new copy of `gamecontrollerdb.txt` and your controller should then be recognized properly. ## Default bindings + +Bindings for controllers and hotkeys can be changed in `Settings -> Controllers`. + Controller 1: - **Left Stick:** W/A/S/D - **Right Stick:** T/F/G/H @@ -229,6 +233,11 @@ Controller 1: Hotkeys: - **Escape:** Open Pause Menu + - **F1:** Load State + - **F2:** Save State + - **F3:** Select Previous Save State + - **F4:** Select Next Save State + - **F10:** Save Screenshot - **F11:** Toggle Fullscreen - **Tab:** Temporarily Disable Speed Limiter - **Space:** Pause/Resume Emulation diff --git a/src/core/game_database.cpp b/src/core/game_database.cpp index d5f44ac24..e539ff39c 100644 --- a/src/core/game_database.cpp +++ b/src/core/game_database.cpp @@ -543,7 +543,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes } else if (settings.gpu_pgxp_enable && settings.gpu_pgxp_vertex_cache) { - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "gamedb_force_pgxp_vertex_cache", ICON_EMOJI_WARNING, TRANSLATE_STR( "GameDatabase", @@ -558,7 +558,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes #ifndef __ANDROID__ APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "PGXP CPU mode enabled.")); #else - Host::AddIconOSDMessage("gamedb_force_pgxp_cpu", ICON_EMOJI_WARNING, + Host::AddIconOSDWarning("gamedb_force_pgxp_cpu", ICON_EMOJI_WARNING, "This game requires PGXP CPU mode, which increases system requirements.\n" " If the game runs too slow, disable PGXP for this game.", Host::OSD_WARNING_DURATION); @@ -569,7 +569,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes } else if (settings.UsingPGXPCPUMode()) { - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "gamedb_force_pgxp_cpu", ICON_EMOJI_WARNING, TRANSLATE_STR("GameDatabase", "PGXP CPU mode is enabled, but it is not required for this game. This may cause rendering errors."), diff --git a/src/core/host.cpp b/src/core/host.cpp index 36f901440..c0d80db8a 100644 --- a/src/core/host.cpp +++ b/src/core/host.cpp @@ -315,8 +315,7 @@ bool Host::CreateGPUDevice(RenderAPI api, Error* error) return false; } - if (!ImGuiManager::Initialize(g_settings.display_osd_scale / 100.0f, g_settings.display_show_osd_messages, - &create_error)) + if (!ImGuiManager::Initialize(g_settings.display_osd_scale / 100.0f, &create_error)) { ERROR_LOG("Failed to initialize ImGuiManager: {}", create_error.GetDescription()); Error::SetStringFmt(error, "Failed to initialize ImGuiManager: {}", create_error.GetDescription()); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 1453b9a53..1e9151a35 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -305,7 +305,7 @@ void Settings::Load(SettingsInterface& si, SettingsInterface& controller_si) display_active_end_offset = static_cast(si.GetIntValue("Display", "ActiveEndOffset", 0)); display_line_start_offset = static_cast(si.GetIntValue("Display", "LineStartOffset", 0)); display_line_end_offset = static_cast(si.GetIntValue("Display", "LineEndOffset", 0)); - display_show_osd_messages = si.GetBoolValue("Display", "ShowOSDMessages", true); + ImGuiManager::SetShowOSDMessages(si.GetBoolValue("Display", "ShowOSDMessages", true)); display_show_fps = si.GetBoolValue("Display", "ShowFPS", false); display_show_speed = si.GetBoolValue("Display", "ShowSpeed", false); display_show_gpu_stats = si.GetBoolValue("Display", "ShowGPUStatistics", false); @@ -575,7 +575,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator); if (!ignore_base) { - si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages); + si.SetBoolValue("Display", "ShowOSDMessages", ImGuiManager::IsShowingOSDMessages()); si.SetBoolValue("Display", "ShowFPS", display_show_fps); si.SetBoolValue("Display", "ShowSpeed", display_show_speed); si.SetBoolValue("Display", "ShowResolution", display_show_resolution); diff --git a/src/core/settings.h b/src/core/settings.h index f12393a88..e4c2358c9 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -160,7 +160,6 @@ struct Settings bool display_disable_mailbox_presentation : 1 = true; bool display_force_4_3_for_24bit : 1 = false; bool display_24bit_chroma_smoothing : 1 = false; - bool display_show_osd_messages : 1 = true; bool display_show_fps : 1 = false; bool display_show_speed : 1 = false; bool display_show_gpu_stats : 1 = false; diff --git a/src/core/system.cpp b/src/core/system.cpp index 78d46cae4..e6db5ab9f 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1236,7 +1236,7 @@ void System::HandleHostGPUDeviceLost() std::memcpy(g_vram, vram_backup.data(), VRAM_SIZE); // First frame after reopening is definitely going to be trash, so skip it. - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "HostGPUDeviceLost", ICON_EMOJI_WARNING, TRANSLATE_STR("System", "Host GPU device encountered an error and has recovered. This may cause broken rendering."), Host::OSD_CRITICAL_ERROR_DURATION); @@ -1301,7 +1301,7 @@ LayeredSettingsInterface System::GetControllerSettingsLayers(std::unique_lockGetBoolValue("ControllerPorts", "UseGameSettingsForController", false)) @@ -1332,7 +1332,6 @@ void System::SetDefaultSettings(SettingsInterface& si) Settings temp; // we don't want to reset some things (e.g. OSD) - temp.display_show_osd_messages = g_settings.display_show_osd_messages; temp.display_show_fps = g_settings.display_show_fps; temp.display_show_speed = g_settings.display_show_speed; temp.display_show_gpu_stats = g_settings.display_show_gpu_stats; @@ -1940,7 +1939,8 @@ void System::DestroySystem() GDBServer::Shutdown(); #endif - Host::ClearOSDMessages(); + // TODO-GPU-THREAD: Needs to be called on GPU thread. + Host::ClearOSDMessages(true); PostProcessing::Shutdown(); @@ -2398,7 +2398,7 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di { WARNING_LOG("BIOS hash mismatch: System: {} | State: {}", BIOS::ImageInfo::GetHashString(s_bios_hash), BIOS::ImageInfo::GetHashString(bios_hash)); - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "StateBIOSMismatch", ICON_FA_EXCLAMATION_TRIANGLE, TRANSLATE_STR("System", "This save state was created with a different BIOS. This may cause stability issues."), Host::OSD_WARNING_DURATION); @@ -3934,7 +3934,7 @@ bool System::InsertMedia(const char* path) std::unique_ptr image = CDImage::Open(path, g_settings.cdrom_load_image_patches, &error); if (!image) { - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "DiscInserted", ICON_FA_COMPACT_DISC, fmt::format(TRANSLATE_FS("OSDMessage", "Failed to open disc image '{}': {}."), path, error.GetDescription()), Host::OSD_ERROR_DURATION); @@ -4474,8 +4474,6 @@ void System::CheckForSettingsChanges(const Settings& old_settings) { if (g_settings.display_osd_scale != old_settings.display_osd_scale) ImGuiManager::SetGlobalScale(g_settings.display_osd_scale / 100.0f); - if (g_settings.display_show_osd_messages != old_settings.display_show_osd_messages) - ImGuiManager::SetShowOSDMessages(g_settings.display_show_osd_messages); } bool controllers_updated = false; @@ -4601,6 +4599,8 @@ void System::WarnAboutUnsafeSettings() { append(ICON_EMOJI_WARNING, TRANSLATE_SV("System", "All enhancements are currently disabled.")); + if (ImGuiManager::IsShowingOSDMessages()) + { #define APPEND_SUBMESSAGE(msg) \ do \ { \ @@ -4609,49 +4609,50 @@ void System::WarnAboutUnsafeSettings() messages.append('\n'); \ } while (0) - if (g_settings.cpu_overclock_active) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Overclock disabled.")); - if (g_settings.enable_8mb_ram) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "8MB RAM disabled.")); - if (g_settings.enable_cheats) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Cheats disabled.")); - if (g_settings.gpu_resolution_scale != 1) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Resolution scale set to 1x.")); - if (g_settings.gpu_multisamples != 1) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Multisample anti-aliasing disabled.")); - if (g_settings.gpu_true_color) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "True color disabled.")); - if (g_settings.gpu_true_color && g_settings.gpu_debanding) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "True color debanding disabled.")); - if (g_settings.gpu_texture_filter != GPUTextureFilter::Nearest || - g_settings.gpu_sprite_texture_filter != GPUTextureFilter::Nearest) - { - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Texture filtering disabled.")); - } - if (g_settings.display_deinterlacing_mode == DisplayDeinterlacingMode::Progressive) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Interlaced rendering enabled.")); - if (g_settings.gpu_force_video_timing != ForceVideoTimingMode::Disabled) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Video timings set to default.")); - if (g_settings.gpu_widescreen_hack) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Widescreen rendering disabled.")); - if (g_settings.display_24bit_chroma_smoothing) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "FMV chroma smoothing disabled.")); - if (g_settings.cdrom_read_speedup != 1) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "CD-ROM read speedup disabled.")); - if (g_settings.cdrom_seek_speedup != 1) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "CD-ROM seek speedup disabled.")); - if (g_settings.cdrom_mute_cd_audio) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Mute CD-ROM audio disabled.")); - if (g_settings.texture_replacements.enable_vram_write_replacements) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "VRAM write texture replacements disabled.")); - if (g_settings.use_old_mdec_routines) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Use old MDEC routines disabled.")); - if (g_settings.pcdrv_enable) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "PCDrv disabled.")); - if (g_settings.bios_patch_fast_boot) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Fast boot disabled.")); + if (g_settings.cpu_overclock_active) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Overclock disabled.")); + if (g_settings.enable_8mb_ram) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "8MB RAM disabled.")); + if (g_settings.enable_cheats) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Cheats disabled.")); + if (g_settings.gpu_resolution_scale != 1) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Resolution scale set to 1x.")); + if (g_settings.gpu_multisamples != 1) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Multisample anti-aliasing disabled.")); + if (g_settings.gpu_true_color) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "True color disabled.")); + if (g_settings.gpu_true_color && g_settings.gpu_debanding) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "True color debanding disabled.")); + if (g_settings.gpu_texture_filter != GPUTextureFilter::Nearest || + g_settings.gpu_sprite_texture_filter != GPUTextureFilter::Nearest) + { + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Texture filtering disabled.")); + } + if (g_settings.display_deinterlacing_mode == DisplayDeinterlacingMode::Progressive) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Interlaced rendering enabled.")); + if (g_settings.gpu_force_video_timing != ForceVideoTimingMode::Disabled) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Video timings set to default.")); + if (g_settings.gpu_widescreen_hack) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Widescreen rendering disabled.")); + if (g_settings.display_24bit_chroma_smoothing) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "FMV chroma smoothing disabled.")); + if (g_settings.cdrom_read_speedup != 1) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "CD-ROM read speedup disabled.")); + if (g_settings.cdrom_seek_speedup != 1) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "CD-ROM seek speedup disabled.")); + if (g_settings.cdrom_mute_cd_audio) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Mute CD-ROM audio disabled.")); + if (g_settings.texture_replacements.enable_vram_write_replacements) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "VRAM write texture replacements disabled.")); + if (g_settings.use_old_mdec_routines) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Use old MDEC routines disabled.")); + if (g_settings.pcdrv_enable) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "PCDrv disabled.")); + if (g_settings.bios_patch_fast_boot) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Fast boot disabled.")); #undef APPEND_SUBMESSAGE + } } if (!g_settings.apply_compatibility_settings) @@ -4666,11 +4667,11 @@ void System::WarnAboutUnsafeSettings() messages.pop_back(); LogUnsafeSettingsToConsole(messages); - Host::AddKeyedOSDMessage("performance_settings_warning", std::string(messages.view()), Host::OSD_WARNING_DURATION); + Host::AddKeyedOSDWarning("performance_settings_warning", std::string(messages.view()), Host::OSD_WARNING_DURATION); } else { - Host::RemoveKeyedOSDMessage("performance_settings_warning"); + Host::RemoveKeyedOSDWarning("performance_settings_warning"); } } @@ -5217,7 +5218,7 @@ bool System::StartMediaCapture(std::string path, bool capture_video, bool captur std::string(), &error)) { - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "MediaCapture", ICON_FA_EXCLAMATION_TRIANGLE, fmt::format(TRANSLATE_FS("System", "Failed to create media capture: {0}"), error.GetDescription()), Host::OSD_ERROR_DURATION); @@ -5256,7 +5257,7 @@ void System::StopMediaCapture() } else { - Host::AddIconOSDMessage( + Host::AddIconOSDWarning( "MediaCapture", ICON_FA_EXCLAMATION_TRIANGLE, fmt::format(TRANSLATE_FS("System", "Stopped {0}: {1}."), GetCaptureTypeForMessage(s_media_capture->IsCapturingVideo(), s_media_capture->IsCapturingAudio()), diff --git a/src/duckstation-qt/graphicssettingswidget.cpp b/src/duckstation-qt/graphicssettingswidget.cpp index d460cccf8..7e7797e8a 100644 --- a/src/duckstation-qt/graphicssettingswidget.cpp +++ b/src/duckstation-qt/graphicssettingswidget.cpp @@ -383,7 +383,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* dialog->registerWidgetHelp( m_ui.stretchDisplayVertically, tr("Stretch Vertically"), tr("Unchecked"), tr("Prefers stretching the display vertically instead of horizontally, when applying the display aspect ratio.")); - dialog->registerWidgetHelp(m_ui.stretchDisplayVertically, tr("Automatically Resize Window"), tr("Unchecked"), + dialog->registerWidgetHelp(m_ui.automaticallyResizeWindow, tr("Automatically Resize Window"), tr("Unchecked"), tr("Automatically resizes the window to match the internal resolution. For high " "internal resolutions, this will create very large windows.")); #ifdef _WIN32 diff --git a/src/util/imgui_manager.cpp b/src/util/imgui_manager.cpp index 07fb1143d..abae68198 100644 --- a/src/util/imgui_manager.cpp +++ b/src/util/imgui_manager.cpp @@ -56,6 +56,7 @@ struct OSDMessage float duration; float target_y; float last_y; + bool is_warning; }; } // namespace @@ -71,6 +72,9 @@ static bool AddImGuiFonts(bool fullscreen_fonts); static ImFont* AddTextFont(float size, bool full_glyph_range); static ImFont* AddFixedFont(float size); static bool AddIconFonts(float size); +static void AddOSDMessage(std::string key, std::string message, float duration, bool is_warning); +static void RemoveKeyedOSDMessage(std::string key, bool is_warning); +static void ClearOSDMessages(bool clear_warnings); static void AcquirePendingOSDMessages(Common::Timer::Value current_time); static void DrawOSDMessages(Common::Timer::Value current_time); static void CreateSoftwareCursorTextures(); @@ -203,6 +207,11 @@ void ImGuiManager::SetGlobalScale(float global_scale) s_scale_changed = true; } +bool ImGuiManager::IsShowingOSDMessages() +{ + return s_show_osd_messages; +} + void ImGuiManager::SetShowOSDMessages(bool enable) { if (s_show_osd_messages == enable) @@ -210,10 +219,10 @@ void ImGuiManager::SetShowOSDMessages(bool enable) s_show_osd_messages = enable; if (!enable) - Host::ClearOSDMessages(); + Host::ClearOSDMessages(false); } -bool ImGuiManager::Initialize(float global_scale, bool show_osd_messages, Error* error) +bool ImGuiManager::Initialize(float global_scale, Error* error) { if (!LoadFontData()) { @@ -224,7 +233,6 @@ bool ImGuiManager::Initialize(float global_scale, bool show_osd_messages, Error* s_global_prescale = global_scale; s_global_scale = std::max(g_gpu_device->GetWindowScale() * global_scale, 1.0f); s_scale_changed = false; - s_show_osd_messages = show_osd_messages; ImGui::CreateContext(); @@ -743,24 +751,19 @@ bool ImGuiManager::HasFullscreenFonts() return (s_medium_font && s_large_font); } -void Host::AddOSDMessage(std::string message, float duration /*= 2.0f*/) -{ - AddKeyedOSDMessage(std::string(), std::move(message), duration); -} - -void Host::AddKeyedOSDMessage(std::string key, std::string message, float duration /* = 2.0f */) +void ImGuiManager::AddOSDMessage(std::string key, std::string message, float duration, bool is_warning) { if (!key.empty()) INFO_LOG("OSD [{}]: {}", key, message); else INFO_LOG("OSD: {}", message); - if (!ImGuiManager::s_show_osd_messages) + if (!s_show_osd_messages && !is_warning) return; const Common::Timer::Value current_time = Common::Timer::GetCurrentValue(); - ImGuiManager::OSDMessage msg; + OSDMessage msg; msg.key = std::move(key); msg.text = std::move(message); msg.duration = duration; @@ -768,37 +771,60 @@ void Host::AddKeyedOSDMessage(std::string key, std::string message, float durati msg.move_time = current_time; msg.target_y = -1.0f; msg.last_y = -1.0f; + msg.is_warning = is_warning; - std::unique_lock lock(ImGuiManager::s_osd_messages_lock); - ImGuiManager::s_osd_posted_messages.push_back(std::move(msg)); + std::unique_lock lock(s_osd_messages_lock); + s_osd_posted_messages.push_back(std::move(msg)); } -void Host::AddIconOSDMessage(std::string key, const char* icon, std::string message, float duration /* = 2.0f */) +void ImGuiManager::RemoveKeyedOSDMessage(std::string key, bool is_warning) { - return AddKeyedOSDMessage(std::move(key), fmt::format("{} {}", icon, message), duration); -} - -void Host::RemoveKeyedOSDMessage(std::string key) -{ - if (!ImGuiManager::s_show_osd_messages) + if (!s_show_osd_messages && !is_warning) return; ImGuiManager::OSDMessage msg = {}; msg.key = std::move(key); msg.duration = 0.0f; + msg.is_warning = is_warning; - std::unique_lock lock(ImGuiManager::s_osd_messages_lock); - ImGuiManager::s_osd_posted_messages.push_back(std::move(msg)); + std::unique_lock lock(s_osd_messages_lock); + s_osd_posted_messages.push_back(std::move(msg)); } -void Host::ClearOSDMessages() +void ImGuiManager::ClearOSDMessages(bool clear_warnings) { { - std::unique_lock lock(ImGuiManager::s_osd_messages_lock); - ImGuiManager::s_osd_posted_messages.clear(); + std::unique_lock lock(s_osd_messages_lock); + if (clear_warnings) + { + s_osd_posted_messages.clear(); + } + else + { + for (auto iter = s_osd_posted_messages.begin(); iter != s_osd_posted_messages.end();) + { + if (!iter->is_warning) + iter = s_osd_posted_messages.erase(iter); + else + ++iter; + } + } } - ImGuiManager::s_osd_active_messages.clear(); + if (clear_warnings) + { + s_osd_active_messages.clear(); + } + else + { + for (auto iter = s_osd_active_messages.begin(); iter != s_osd_active_messages.end();) + { + if (!iter->is_warning) + s_osd_active_messages.erase(iter); + else + ++iter; + } + } } void ImGuiManager::AcquirePendingOSDMessages(Common::Timer::Value current_time) @@ -940,6 +966,46 @@ void ImGuiManager::RenderOSDMessages() DrawOSDMessages(current_time); } +void Host::AddOSDMessage(std::string message, float duration /*= 2.0f*/) +{ + ImGuiManager::AddOSDMessage(std::string(), std::move(message), duration, false); +} + +void Host::AddKeyedOSDMessage(std::string key, std::string message, float duration /* = 2.0f */) +{ + ImGuiManager::AddOSDMessage(std::move(key), std::move(message), duration, false); +} + +void Host::AddIconOSDMessage(std::string key, const char* icon, std::string message, float duration /* = 2.0f */) +{ + ImGuiManager::AddOSDMessage(std::move(key), fmt::format("{} {}", icon, message), duration, false); +} + +void Host::AddKeyedOSDWarning(std::string key, std::string message, float duration /* = 2.0f */) +{ + ImGuiManager::AddOSDMessage(std::move(key), std::move(message), duration, true); +} + +void Host::AddIconOSDWarning(std::string key, const char* icon, std::string message, float duration /* = 2.0f */) +{ + ImGuiManager::AddOSDMessage(std::move(key), fmt::format("{} {}", icon, message), duration, true); +} + +void Host::RemoveKeyedOSDMessage(std::string key) +{ + ImGuiManager::RemoveKeyedOSDMessage(std::move(key), false); +} + +void Host::RemoveKeyedOSDWarning(std::string key) +{ + ImGuiManager::RemoveKeyedOSDMessage(std::move(key), true); +} + +void Host::ClearOSDMessages(bool clear_warnings) +{ + ImGuiManager::ClearOSDMessages(clear_warnings); +} + float ImGuiManager::GetGlobalScale() { return s_global_scale; diff --git a/src/util/imgui_manager.h b/src/util/imgui_manager.h index db64851bd..e13a416d2 100644 --- a/src/util/imgui_manager.h +++ b/src/util/imgui_manager.h @@ -33,10 +33,11 @@ std::vector CompactFontRange(std::span range); void SetGlobalScale(float global_scale); /// Changes whether OSD messages are silently dropped. +bool IsShowingOSDMessages(); void SetShowOSDMessages(bool enable); /// Initializes ImGui, creates fonts, etc. -bool Initialize(float global_scale, bool show_osd_messages, Error* error); +bool Initialize(float global_scale, Error* error); /// Frees all ImGui resources. void Shutdown(); @@ -137,6 +138,9 @@ static constexpr float OSD_QUICK_DURATION = 2.5f; void AddOSDMessage(std::string message, float duration = 2.0f); void AddKeyedOSDMessage(std::string key, std::string message, float duration = 2.0f); void AddIconOSDMessage(std::string key, const char* icon, std::string message, float duration = 2.0f); +void AddKeyedOSDWarning(std::string key, std::string message, float duration = 2.0f); +void AddIconOSDWarning(std::string key, const char* icon, std::string message, float duration = 2.0f); void RemoveKeyedOSDMessage(std::string key); -void ClearOSDMessages(); +void RemoveKeyedOSDWarning(std::string key); +void ClearOSDMessages(bool clear_warnings); } // namespace Host