From a5613fc81590aa9f16f1bd744e3f22fec4bfa0ff Mon Sep 17 00:00:00 2001
From: Stenzek <stenzek@gmail.com>
Date: Mon, 22 Apr 2024 00:24:51 +1000
Subject: [PATCH] System: Add OSD message when all enhancements are disabled

---
 src/common/small_string.h |  5 ++++
 src/core/settings.cpp     | 10 ++++----
 src/core/system.cpp       | 50 ++++++++++++++++++---------------------
 3 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/src/common/small_string.h b/src/common/small_string.h
index 0060b1e6c..ead59c9a1 100644
--- a/src/common/small_string.h
+++ b/src/common/small_string.h
@@ -176,7 +176,12 @@ public:
   ALWAYS_INLINE const char* end_ptr() const { return m_buffer + m_length; }
 
   // STL adapters
+  ALWAYS_INLINE char& front() { return m_buffer[0]; }
+  ALWAYS_INLINE const char& front() const { return m_buffer[0]; }
+  ALWAYS_INLINE char& back() { return m_buffer[m_length - 1]; }
+  ALWAYS_INLINE const char& back() const { return m_buffer[m_length - 1]; }
   ALWAYS_INLINE void push_back(value_type&& val) { append(val); }
+  ALWAYS_INLINE void pop_back() { erase(-1); }
 
   // returns a string view for this string
   std::string_view view() const;
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 9dc5fa20e..b965ba829 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -684,7 +684,6 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
 {
   if (g_settings.disable_all_enhancements)
   {
-    Log_WarningPrintf("All enhancements disabled by config setting.");
     g_settings.cpu_overclock_enable = false;
     g_settings.cpu_overclock_active = false;
     g_settings.enable_8mb_ram = false;
@@ -712,7 +711,9 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
 
   if (g_settings.pcdrv_enable && g_settings.pcdrv_root.empty())
   {
-    Log_WarningPrintf("Disabling PCDrv because no root directory is specified.");
+    Host::AddKeyedOSDMessage("pcdrv_disabled_no_root",
+                             TRANSLATE_STR("OSDMessage", "Disabling PCDrv because no root directory is specified."),
+                             Host::OSD_WARNING_DURATION);
     g_settings.pcdrv_enable = false;
   }
 
@@ -756,8 +757,9 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
 
   if (g_settings.IsRunaheadEnabled() && g_settings.rewind_enable)
   {
-    Host::AddKeyedOSDMessage("rewind_disabled_android",
-                             TRANSLATE_STR("OSDMessage", "Rewind is disabled because runahead is enabled."), 10.0f);
+    Host::AddKeyedOSDMessage("rewind_disabled",
+                             TRANSLATE_STR("OSDMessage", "Rewind is disabled because runahead is enabled."),
+                             Host::OSD_WARNING_DURATION);
     g_settings.rewind_enable = false;
   }
 
diff --git a/src/core/system.cpp b/src/core/system.cpp
index 1f586fd28..d49c375a3 100644
--- a/src/core/system.cpp
+++ b/src/core/system.cpp
@@ -110,7 +110,7 @@ static bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_dis
 static bool CreateGPU(GPURenderer renderer, bool is_switching);
 static bool SaveUndoLoadState();
 static void WarnAboutUnsafeSettings();
-static void LogUnsafeSettingsToConsole(const std::string& messages);
+static void LogUnsafeSettingsToConsole(const SmallStringBase& messages);
 
 /// Throttles the system, i.e. sleeps until it's time to execute the next frame.
 static void Throttle(Common::Timer::Value current_time);
@@ -1017,9 +1017,9 @@ void System::ApplySettings(bool display_osd_messages)
 
   if (IsValid())
   {
+    WarnAboutUnsafeSettings();
     ResetPerformanceCounters();
-    if (s_system_executing)
-      s_system_interrupted = true;
+    InterruptExecution();
   }
 }
 
@@ -3952,13 +3952,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
 
 void System::WarnAboutUnsafeSettings()
 {
-  std::string messages;
-  auto append = [&messages](const char* icon, std::string_view msg) {
-    messages += icon;
-    messages += ' ';
-    messages += msg;
-    messages += '\n';
-  };
+  LargeString messages;
+  auto append = [&messages](const char* icon, std::string_view msg) { messages.append_format("{} {}\n", icon, msg); };
 
   if (g_settings.cpu_overclock_active)
   {
@@ -3993,6 +3988,15 @@ void System::WarnAboutUnsafeSettings()
   }
   if (g_settings.enable_8mb_ram)
     append(ICON_FA_MICROCHIP, TRANSLATE_SV("System", "8MB RAM is enabled, this may be incompatible with some games."));
+  if (g_settings.disable_all_enhancements)
+    append(ICON_FA_COGS, TRANSLATE_SV("System", "All enhancements are currently disabled."));
+
+  if (s_cheat_list && s_cheat_list->GetEnabledCodeCount() > 0)
+  {
+    append(ICON_FA_EXCLAMATION_TRIANGLE,
+           fmt::format(TRANSLATE_FS("System", "{} cheats are enabled. This may crash games."),
+                       s_cheat_list->GetEnabledCodeCount()));
+  }
 
   if (!messages.empty())
   {
@@ -4000,7 +4004,7 @@ void System::WarnAboutUnsafeSettings()
       messages.pop_back();
 
     LogUnsafeSettingsToConsole(messages);
-    Host::AddKeyedOSDMessage("performance_settings_warning", std::move(messages), Host::OSD_WARNING_DURATION);
+    Host::AddKeyedOSDMessage("performance_settings_warning", std::string(messages.view()), Host::OSD_WARNING_DURATION);
   }
   else
   {
@@ -4008,16 +4012,16 @@ void System::WarnAboutUnsafeSettings()
   }
 }
 
-void System::LogUnsafeSettingsToConsole(const std::string& messages)
+void System::LogUnsafeSettingsToConsole(const SmallStringBase& messages)
 {
   // a not-great way of getting rid of the icons for the console message
-  std::string console_messages = messages;
+  LargeString console_messages = messages;
   for (;;)
   {
-    const std::string::size_type pos = console_messages.find("\xef");
-    if (pos != std::string::npos)
+    const s32 pos = console_messages.find("\xef");
+    if (pos >= 0)
     {
-      console_messages.erase(pos, pos + 3);
+      console_messages.erase(pos, 3);
       console_messages.insert(pos, "[Unsafe Settings]");
     }
     else
@@ -4025,7 +4029,7 @@ void System::LogUnsafeSettingsToConsole(const std::string& messages)
       break;
     }
   }
-  Log_WarningPrint(console_messages.c_str());
+  Log_WarningPrint(console_messages);
 }
 
 void System::CalculateRewindMemoryUsage(u32 num_saves, u32 resolution_scale, u64* ram_usage, u64* vram_usage)
@@ -4679,19 +4683,11 @@ bool System::LoadCheatList()
   std::unique_ptr<CheatList> cl = std::make_unique<CheatList>();
   if (!cl->LoadFromFile(filename.c_str(), CheatList::Format::Autodetect))
   {
-    Host::AddFormattedOSDMessage(15.0f, TRANSLATE("OSDMessage", "Failed to load cheats from '%s'."), filename.c_str());
+    Host::AddIconOSDMessage("cheats_loaded", ICON_FA_EXCLAMATION_TRIANGLE,
+                            fmt::format(TRANSLATE_FS("OSDMessage", "Failed to load cheats from '{}'."), filename));
     return false;
   }
 
-  if (cl->GetEnabledCodeCount() > 0)
-  {
-    Host::AddIconOSDMessage(
-      "cheats_loaded", ICON_FA_EXCLAMATION_TRIANGLE,
-      fmt::format(TRANSLATE_FS("OSDMessage", "{} cheats are enabled. This may result in instability."),
-                  cl->GetEnabledCodeCount()),
-      Host::OSD_WARNING_DURATION);
-  }
-
   SetCheatList(std::move(cl));
   return true;
 }