diff --git a/src/common/layered_settings_interface.cpp b/src/common/layered_settings_interface.cpp
index 134097252..92fc3e930 100644
--- a/src/common/layered_settings_interface.cpp
+++ b/src/common/layered_settings_interface.cpp
@@ -103,6 +103,20 @@ bool LayeredSettingsInterface::GetStringValue(const char* section, const char* k
   return false;
 }
 
+bool LayeredSettingsInterface::GetStringValue(const char* section, const char* key, SmallStringBase* value) const
+{
+  for (u32 layer = FIRST_LAYER; layer <= LAST_LAYER; layer++)
+  {
+    if (SettingsInterface* sif = m_layers[layer]; sif != nullptr)
+    {
+      if (sif->GetStringValue(section, key, value))
+        return true;
+    }
+  }
+
+  return false;
+}
+
 void LayeredSettingsInterface::SetIntValue(const char* section, const char* key, int value)
 {
   Panic("Attempt to call SetIntValue() on layered settings interface");
diff --git a/src/common/layered_settings_interface.h b/src/common/layered_settings_interface.h
index 689593393..611a2a68a 100644
--- a/src/common/layered_settings_interface.h
+++ b/src/common/layered_settings_interface.h
@@ -33,6 +33,7 @@ public:
   bool GetDoubleValue(const char* section, const char* key, double* value) const override;
   bool GetBoolValue(const char* section, const char* key, bool* value) const override;
   bool GetStringValue(const char* section, const char* key, std::string* value) const override;
+  bool GetStringValue(const char* section, const char* key, SmallStringBase* value) const override;
 
   void SetIntValue(const char* section, const char* key, s32 value) override;
   void SetUIntValue(const char* section, const char* key, u32 value) override;
diff --git a/src/common/memory_settings_interface.cpp b/src/common/memory_settings_interface.cpp
index 5b2d09ef1..a8edc3a94 100644
--- a/src/common/memory_settings_interface.cpp
+++ b/src/common/memory_settings_interface.cpp
@@ -126,6 +126,20 @@ bool MemorySettingsInterface::GetStringValue(const char* section, const char* ke
   return true;
 }
 
+bool MemorySettingsInterface::GetStringValue(const char* section, const char* key, SmallStringBase* value) const
+{
+  const auto sit = m_sections.find(section);
+  if (sit == m_sections.end())
+    return false;
+
+  const auto iter = sit->second.find(key);
+  if (iter == sit->second.end())
+    return false;
+
+  value->assign(iter->second);
+  return true;
+}
+
 void MemorySettingsInterface::SetIntValue(const char* section, const char* key, s32 value)
 {
   SetValue(section, key, std::to_string(value));
diff --git a/src/common/memory_settings_interface.h b/src/common/memory_settings_interface.h
index aab5bccf4..90ee47f46 100644
--- a/src/common/memory_settings_interface.h
+++ b/src/common/memory_settings_interface.h
@@ -22,6 +22,7 @@ public:
   bool GetDoubleValue(const char* section, const char* key, double* value) const override;
   bool GetBoolValue(const char* section, const char* key, bool* value) const override;
   bool GetStringValue(const char* section, const char* key, std::string* value) const override;
+  bool GetStringValue(const char* section, const char* key, SmallStringBase* value) const override;
 
   void SetIntValue(const char* section, const char* key, s32 value) override;
   void SetUIntValue(const char* section, const char* key, u32 value) override;
diff --git a/src/common/settings_interface.h b/src/common/settings_interface.h
index d7378c5cf..5efd6a976 100644
--- a/src/common/settings_interface.h
+++ b/src/common/settings_interface.h
@@ -3,7 +3,9 @@
 
 #pragma once
 
+#include "small_string.h"
 #include "types.h"
+
 #include <optional>
 #include <string>
 #include <vector>
@@ -24,6 +26,7 @@ public:
   virtual bool GetDoubleValue(const char* section, const char* key, double* value) const = 0;
   virtual bool GetBoolValue(const char* section, const char* key, bool* value) const = 0;
   virtual bool GetStringValue(const char* section, const char* key, std::string* value) const = 0;
+  virtual bool GetStringValue(const char* section, const char* key, SmallStringBase* value) const = 0;
 
   virtual void SetIntValue(const char* section, const char* key, s32 value) = 0;
   virtual void SetUIntValue(const char* section, const char* key, u32 value) = 0;
@@ -82,6 +85,24 @@ public:
     return value;
   }
 
+  ALWAYS_INLINE SmallString GetSmallStringValue(const char* section, const char* key,
+                                                const char* default_value = "") const
+  {
+    SmallString value;
+    if (!GetStringValue(section, key, &value))
+      value.assign(default_value);
+    return value;
+  }
+
+  ALWAYS_INLINE SmallString GetTinyStringValue(const char* section, const char* key,
+                                               const char* default_value = "") const
+  {
+    TinyString value;
+    if (!GetStringValue(section, key, &value))
+      value.assign(default_value);
+    return value;
+  }
+
   ALWAYS_INLINE std::optional<s32> GetOptionalIntValue(const char* section, const char* key,
                                                        std::optional<s32> default_value = std::nullopt)
   {
@@ -122,7 +143,32 @@ public:
                          std::optional<const char*> default_value = std::nullopt) const
   {
     std::string ret;
-    return GetStringValue(section, key, &ret) ? std::optional<std::string>(ret) : default_value;
+    return GetStringValue(section, key, &ret) ?
+             std::optional<std::string>(ret) :
+             (default_value.has_value() ? std::optional<std::string>(default_value.value()) :
+                                          std::optional<std::string>());
+  }
+
+  ALWAYS_INLINE std::optional<SmallString>
+  GetOptionalSmallStringValue(const char* section, const char* key,
+                              std::optional<const char*> default_value = std::nullopt) const
+  {
+    SmallString ret;
+    return GetStringValue(section, key, &ret) ?
+             std::optional<SmallString>(ret) :
+             (default_value.has_value() ? std::optional<SmallString>(default_value.value()) :
+                                          std::optional<SmallString>());
+  }
+
+  ALWAYS_INLINE std::optional<TinyString>
+  GetOptionalTinyStringValue(const char* section, const char* key,
+                             std::optional<const char*> default_value = std::nullopt) const
+  {
+    TinyString ret;
+    return GetStringValue(section, key, &ret) ?
+             std::optional<TinyString>(ret) :
+             (default_value.has_value() ? std::optional<TinyString>(default_value.value()) :
+                                          std::optional<TinyString>());
   }
 
   ALWAYS_INLINE void SetOptionalIntValue(const char* section, const char* key, const std::optional<s32>& value)
diff --git a/src/core/host.cpp b/src/core/host.cpp
index b21255cc7..91c30ebec 100644
--- a/src/core/host.cpp
+++ b/src/core/host.cpp
@@ -53,6 +53,21 @@ std::string Host::GetBaseStringSettingValue(const char* section, const char* key
     ->GetStringValue(section, key, default_value);
 }
 
+SmallString Host::GetBaseSmallStringSettingValue(const char* section, const char* key,
+                                                 const char* default_value /*= ""*/)
+{
+  std::unique_lock lock(s_settings_mutex);
+  return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
+    ->GetSmallStringValue(section, key, default_value);
+}
+
+TinyString Host::GetBaseTinyStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
+{
+  std::unique_lock lock(s_settings_mutex);
+  return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
+    ->GetTinyStringValue(section, key, default_value);
+}
+
 bool Host::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
 {
   std::unique_lock lock(s_settings_mutex);
@@ -100,6 +115,18 @@ std::string Host::GetStringSettingValue(const char* section, const char* key, co
   return s_layered_settings_interface.GetStringValue(section, key, default_value);
 }
 
+SmallString Host::GetSmallStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
+{
+  std::unique_lock lock(s_settings_mutex);
+  return s_layered_settings_interface.GetSmallStringValue(section, key, default_value);
+}
+
+TinyString Host::GetTinyStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
+{
+  std::unique_lock lock(s_settings_mutex);
+  return s_layered_settings_interface.GetTinyStringValue(section, key, default_value);
+}
+
 bool Host::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
 {
   std::unique_lock lock(s_settings_mutex);
diff --git a/src/core/host.h b/src/core/host.h
index 36b5ede06..9cfe47e4c 100644
--- a/src/core/host.h
+++ b/src/core/host.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
+// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
 
 #pragma once
@@ -29,6 +29,8 @@ class CDImage;
 namespace Host {
 // Base setting retrieval, bypasses layers.
 std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = "");
+SmallString GetBaseSmallStringSettingValue(const char* section, const char* key, const char* default_value = "");
+TinyString GetBaseTinyStringSettingValue(const char* section, const char* key, const char* default_value = "");
 bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false);
 s32 GetBaseIntSettingValue(const char* section, const char* key, s32 default_value = 0);
 u32 GetBaseUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
@@ -53,6 +55,8 @@ void CommitBaseSettingChanges();
 
 // Settings access, thread-safe.
 std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "");
+SmallString GetSmallStringSettingValue(const char* section, const char* key, const char* default_value = "");
+TinyString GetTinyStringSettingValue(const char* section, const char* key, const char* default_value = "");
 bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false);
 int GetIntSettingValue(const char* section, const char* key, s32 default_value = 0);
 u32 GetUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
diff --git a/src/util/ini_settings_interface.cpp b/src/util/ini_settings_interface.cpp
index 715c4821b..4223ddb67 100644
--- a/src/util/ini_settings_interface.cpp
+++ b/src/util/ini_settings_interface.cpp
@@ -3,11 +3,11 @@
 
 #include "ini_settings_interface.h"
 
+#include "common/error.h"
 #include "common/file_system.h"
 #include "common/log.h"
 #include "common/path.h"
 #include "common/string_util.h"
-#include "common/error.h"
 
 #include <algorithm>
 #include <iterator>
@@ -46,7 +46,9 @@ static std::string GetTemporaryFileName(const std::string& original_filename)
   return temporary_filename;
 }
 
-INISettingsInterface::INISettingsInterface(std::string filename) : m_filename(std::move(filename)), m_ini(true, true) {}
+INISettingsInterface::INISettingsInterface(std::string filename) : m_filename(std::move(filename)), m_ini(true, true)
+{
+}
 
 INISettingsInterface::~INISettingsInterface()
 {
@@ -195,6 +197,16 @@ bool INISettingsInterface::GetStringValue(const char* section, const char* key,
   return true;
 }
 
+bool INISettingsInterface::GetStringValue(const char* section, const char* key, SmallStringBase* value) const
+{
+  const char* str_value = m_ini.GetValue(section, key);
+  if (!str_value)
+    return false;
+
+  value->assign(str_value);
+  return true;
+}
+
 void INISettingsInterface::SetIntValue(const char* section, const char* key, s32 value)
 {
   m_dirty = true;
diff --git a/src/util/ini_settings_interface.h b/src/util/ini_settings_interface.h
index 7a72b2dfd..a18bc69eb 100644
--- a/src/util/ini_settings_interface.h
+++ b/src/util/ini_settings_interface.h
@@ -29,6 +29,7 @@ public:
   bool GetDoubleValue(const char* section, const char* key, double* value) const override;
   bool GetBoolValue(const char* section, const char* key, bool* value) const override;
   bool GetStringValue(const char* section, const char* key, std::string* value) const override;
+  bool GetStringValue(const char* section, const char* key, SmallStringBase* value) const override;
 
   void SetIntValue(const char* section, const char* key, s32 value) override;
   void SetUIntValue(const char* section, const char* key, u32 value) override;