diff --git a/dynamic.c b/dynamic.c
index a6190943c8..d8a6cb1464 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -335,6 +335,33 @@ static bool environment_cb(unsigned cmd, void *data)
          SSNES_LOG("Environ GET_CAN_REWIND: %s\n", g_settings.rewind_enable ? "true" : "false");
          break;
 
+      case SNES_ENVIRONMENT_GET_VARIABLE:
+      {
+         struct snes_variable *var = data;
+         if (var->key)
+         {
+            // Split string has '\0' delimiters so we have to find the position in original string,
+            // then pass the corresponding offset into the split string.
+            const char *key = strstr(g_extern.system.environment, var->key);
+            size_t key_len = strlen(var->key);
+            if (key && key[key_len] == '=')
+            {
+               ptrdiff_t offset = key - g_extern.system.environment;
+               var->value = &g_extern.system.environment_split[offset + key_len + 1];
+            }
+            else
+               var->value = NULL;
+         }
+         else
+            var->value = g_extern.system.environment;
+
+         SSNES_LOG("Environ GET_VARIABLE: %s=%s\n",
+               var->key ? var->key : "null",
+               var->value ? var->value : "null");
+
+         break;
+      }
+
       default:
          SSNES_LOG("Environ UNSUPPORTED (#%u)!\n", cmd);
          return false;
@@ -377,5 +404,9 @@ static void set_environment_defaults(void)
    g_extern.system.geom.base_height = 224;
    g_extern.system.geom.max_width = 512;
    g_extern.system.geom.max_height = 512;
+
+   // Split up environment variables beforehand.
+   if (g_extern.system.environment_split && strtok(g_extern.system.environment_split, ";"))
+      while (strtok(NULL, ";"));
 }
 
diff --git a/general.h b/general.h
index 5561ca652f..3439111da8 100644
--- a/general.h
+++ b/general.h
@@ -264,6 +264,9 @@ struct global
       struct snes_system_timing timing;
       bool timing_set;
       bool need_fullpath;
+
+      char *environment;
+      char *environment_split;
    } system;
 
    struct
diff --git a/libsnes.hpp b/libsnes.hpp
index 77160f76a1..3f36045009 100755
--- a/libsnes.hpp
+++ b/libsnes.hpp
@@ -100,6 +100,21 @@ extern "C" {
                                                 // Some implementations might need to take extra precautions
                                                 // to allow this as smoothly as possible.
 
+#define SNES_ENVIRONMENT_GET_VARIABLE 8         // struct snes_variable * --
+                                                // Interface to aquire user-defined information from environment
+                                                // that cannot feasibly be supported in a multi-system way.
+                                                // Mostly used for obscure,
+                                                // specific features that the user can tap into when neseccary.
+
+struct snes_variable
+{
+   const char *key;        // Variable to query in SNES_ENVIRONMENT_GET_VARIABLE.
+                           // If NULL, obtains the complete environment string if more complex parsing is necessary.
+                           // The environment string is formatted as key-value pairs delimited by semicolons as so:
+                           // "key1=value1;key2=value2;..."
+   const char *value;      // Value to be obtained. If key does not exist, it is set to NULL.
+};
+
 struct snes_geometry
 {
    unsigned base_width;    // Nominal video width of system.
diff --git a/settings.c b/settings.c
index 8dc22daab1..08cc72f1c1 100644
--- a/settings.c
+++ b/settings.c
@@ -466,6 +466,18 @@ bool config_load_file(const char *path)
    CONFIG_GET_BOOL(block_sram_overwrite, "block_sram_overwrite");
    CONFIG_GET_BOOL(savestate_auto_index, "savestate_auto_index");
 
+   if (config_get_string(conf, "environment_variables",
+            &g_extern.system.environment))
+   {
+      g_extern.system.environment_split = strdup(g_extern.system.environment);
+      if (!g_extern.system.environment_split)
+      {
+         SSNES_ERR("Failed to allocate environment variables. Will ignore them.\n");
+         free(g_extern.system.environment);
+         g_extern.system.environment = NULL;
+      }
+   }
+
    if (!g_extern.has_set_save_path && config_get_array(conf, "savefile_directory", tmp_str, sizeof(tmp_str)))
    {
       if (path_is_directory(tmp_str))
diff --git a/ssnes.c b/ssnes.c
index 9a96d762e4..2ba4142d42 100644
--- a/ssnes.c
+++ b/ssnes.c
@@ -2079,10 +2079,15 @@ static void init_state(void)
 void ssnes_main_clear_state(void)
 {
    memset(&g_settings, 0, sizeof(g_settings));
+
+   free(g_extern.system.environment);
+   free(g_extern.system.environment_split);
    memset(&g_extern, 0, sizeof(g_extern));
+
 #ifdef SSNES_CONSOLE
    memset(&g_console, 0, sizeof(g_console));
 #endif
+
    init_state();
 }
 
@@ -2274,6 +2279,7 @@ int main(int argc, char *argv[])
    if ((init_ret = ssnes_main_init(argc, argv))) return init_ret;
    while (ssnes_main_iterate());
    ssnes_main_deinit();
+   ssnes_main_clear_state();
    return 0;
 }
 
diff --git a/ssnes.cfg b/ssnes.cfg
index cb7a6b6490..6045182034 100644
--- a/ssnes.cfg
+++ b/ssnes.cfg
@@ -8,9 +8,18 @@
 # This will be overridden by explicit command line options.
 # savestate_directory =
 
-## If enabled, load libsnes from a dynamic location.
+# If enabled, load libsnes from a dynamic location.
 # libsnes_path = "/path/to/libsnes.so"
 
+# Environment variables internally in SSNES.
+# Implementations can tap into this user-specificed information to enable functionality
+# that is deemed too obscure to expose directly.
+# Some variables might be "standardized" at a later time if needed.
+# The string is formatted as key value pairs delimited by a semicolon ';'.
+# Any white space between the delimiter ';' and the '=' is significant.
+# I.e.: "key1=value1;key2=value2;..."
+# environment_variables =
+
 #### Video
 
 # Video driver to use. "gl", "xvideo", "sdl" or "ext" (external API driver)