Commits

Richard Goedeken committed d22a747

added new console-ui option --set for setting arbitrary configuration variables on the command line. This requires the latest core library, because it uses a new config function ConfigGetParameterType()

  • Participants
  • Parent commits 31468d5

Comments (0)

Files changed (5)

     --rsp (plugin-spec)   : use rsp plugin given by (plugin-spec)
     --emumode (mode)      : set emu mode to: 0=Pure Interpreter 1=Interpreter 2=DynaRec
     --testshots (list)    : take screenshots at frames given in comma-separated (list), then quit
+    --set (param-spec)    : set a configuration variable, format: ParamSection[ParamName]=Value
     --core-compare-send   : use the Core Comparison debugging feature, in data sending mode
     --core-compare-recv   : use the Core Comparison debugging feature, in data receiving mode
     --saveoptions         : save the given command-line options in configuration file for future

File src/core_interface.c

 ptr_ConfigSaveFile         ConfigSaveFile = NULL;
 ptr_ConfigSetParameter     ConfigSetParameter = NULL;
 ptr_ConfigGetParameter     ConfigGetParameter = NULL;
+ptr_ConfigGetParameterType ConfigGetParameterType = NULL;
 ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;
 ptr_ConfigSetDefaultInt    ConfigSetDefaultInt = NULL;
 ptr_ConfigSetDefaultFloat  ConfigSetDefaultFloat = NULL;
     ConfigSaveFile = (ptr_ConfigSaveFile) osal_dynlib_getproc(CoreHandle, "ConfigSaveFile");
     ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreHandle, "ConfigSetParameter");
     ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreHandle, "ConfigGetParameter");
+    ConfigGetParameterType = (ptr_ConfigGetParameterType) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterType");
     ConfigGetParameterHelp = (ptr_ConfigGetParameterHelp) osal_dynlib_getproc(CoreHandle, "ConfigGetParameterHelp");
     ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultInt");
     ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreHandle, "ConfigSetDefaultFloat");
     ConfigListParameters = NULL;
     ConfigSetParameter = NULL;
     ConfigGetParameter = NULL;
+    ConfigGetParameterType = NULL;
     ConfigGetParameterHelp = NULL;
     ConfigSetDefaultInt = NULL;
     ConfigSetDefaultBool = NULL;

File src/core_interface.h

 extern ptr_ConfigSaveFile         ConfigSaveFile;
 extern ptr_ConfigSetParameter     ConfigSetParameter;
 extern ptr_ConfigGetParameter     ConfigGetParameter;
+extern ptr_ConfigGetParameterType ConfigGetParameterType;
 extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp;
 extern ptr_ConfigSetDefaultInt    ConfigSetDefaultInt;
 extern ptr_ConfigSetDefaultFloat  ConfigSetDefaultFloat;
            "    --rsp (plugin-spec)   : use rsp plugin given by (plugin-spec)\n"
            "    --emumode (mode)      : set emu mode to: 0=Pure Interpreter 1=Interpreter 2=DynaRec\n"
            "    --testshots (list)    : take screenshots at frames given in comma-separated (list), then quit\n"
+           "    --set (param-spec)    : set a configuration variable, format: ParamSection[ParamName]=Value\n"
            "    --core-compare-send   : use the Core Comparison debugging feature, in data sending mode\n"
            "    --core-compare-recv   : use the Core Comparison debugging feature, in data receiving mode\n"
            "    --saveoptions         : save the given command-line options in configuration file for future\n"
     return;
 }
 
+static int SetConfigParameter(const char *ParamSpec)
+{
+    char *ParsedString, *VarName, *VarValue;
+    m64p_handle ConfigSection;
+    m64p_type VarType;
+    m64p_error rval;
+
+    if (ParamSpec == NULL)
+    {
+        fprintf(stderr, "UI-Console Error: ParamSpec is NULL in SetConfigParameter()\n");
+        return 1;
+    }
+
+    /* make a copy of the input string */
+    ParsedString = malloc(strlen(ParamSpec) + 1);
+    if (ParsedString == NULL)
+    {
+        fprintf(stderr, "UI-Console Error: SetConfigParameter() couldn't allocate memory for temporary string.\n");
+        return 2;
+    }
+    strcpy(ParsedString, ParamSpec);
+
+    /* parse it for the simple section[name]=value format */
+    VarName = strchr(ParsedString, '[');
+    if (VarName != NULL)
+    {
+        *VarName++ = 0;
+        VarValue = strchr(VarName, ']');
+        if (VarValue != NULL)
+        {
+            *VarValue++ = 0;
+        }
+    }
+    if (VarName == NULL || VarValue == NULL || *VarValue != '=')
+    {
+        fprintf(stderr, "UI-Console Error: invalid (param-spec) '%s'\n", ParamSpec);
+        return 3;
+    }
+    VarValue++;
+
+    /* then set the value */
+    rval = (*ConfigOpenSection)(ParsedString, &ConfigSection);
+    if (rval != M64ERR_SUCCESS)
+    {
+        fprintf(stderr, "UI-Console Error: SetConfigParameter failed to open config section '%s'\n", ParsedString);
+        return 4;
+    }
+    if ((*ConfigGetParameterType)(ConfigSection, VarName, &VarType) == M64ERR_SUCCESS)
+    {
+        switch(VarType)
+        {
+            int ValueInt;
+            float ValueFloat;
+            case M64TYPE_INT:
+                ValueInt = atoi(VarValue);
+                ConfigSetParameter(ConfigSection, VarName, M64TYPE_INT, &ValueInt);
+                break;
+            case M64TYPE_FLOAT:
+                ValueFloat = (float) atof(VarValue);
+                ConfigSetParameter(ConfigSection, VarName, M64TYPE_FLOAT, &ValueFloat);
+                break;
+            case M64TYPE_BOOL:
+                ValueInt = (int) (osal_insensitive_strcmp(VarValue, "true") == 0);
+                ConfigSetParameter(ConfigSection, VarName, M64TYPE_BOOL, &ValueInt);
+                break;
+            case M64TYPE_STRING:
+                ConfigSetParameter(ConfigSection, VarName, M64TYPE_STRING, VarValue);
+                break;
+            default:
+                fprintf(stderr, "UI-Console Error: invalid VarType in SetConfigParameter()\n");
+                return 5;
+        }
+    }
+    else
+    {
+        ConfigSetParameter(ConfigSection, VarName, M64TYPE_STRING, VarValue);
+    }
+
+    return 0;
+}
+
 static int *ParseNumberList(const char *InputString, int *ValuesFound)
 {
     const char *str;
             l_TestShotList = ParseNumberList(argv[i+1], NULL);
             i++;
         }
+        else if (strcmp(argv[i], "--set") == 0 && ArgsLeft >= 1)
+        {
+            if (SetConfigParameter(argv[i+1]) != 0)
+                return M64ERR_INPUT_INVALID;
+            i++;
+        }
         else if (strcmp(argv[i], "--core-compare-send") == 0)
         {
             l_CoreCompareMode = 1;
 
     /* missing ROM filepath */
     fprintf(stderr, "Error: no ROM filepath given\n");
-    exit(2);
-    return M64ERR_INTERNAL;
+    return M64ERR_INPUT_INVALID;
 }
 
 /*********************************************************************************************************
     {
         printf("UI-console: can't use --core-compare feature with this Mupen64Plus core library.\n");
         DetachCoreLib();
-        return 3;
+        return 6;
     }
     compare_core_init(l_CoreCompareMode);
 
         fprintf(stderr, "Error: couldn't open ROM file '%s' for reading.\n", l_ROMFilepath);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 6;
+        return 7;
     }
 
     /* get the length of the ROM, allocate memory buffer, load it from disk */
         fclose(fPtr);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 7;
+        return 8;
     }
     else if (fread(ROM_buffer, 1, romlength, fPtr) != romlength)
     {
         fclose(fPtr);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 8;
+        return 9;
     }
     fclose(fPtr);
 
         free(ROM_buffer);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 9;
+        return 10;
     }
     free(ROM_buffer); /* the core copies the ROM image, so we can release this buffer immediately */
 
         (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 10;
+        return 11;
     }
 
     /* search for and load plugins */
         (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL);
         (*CoreShutdown)();
         DetachCoreLib();
-        return 11;
+        return 12;
     }
 
     /* attach plugins to core */
             (*CoreDoCommand)(M64CMD_ROM_CLOSE, 0, NULL);
             (*CoreShutdown)();
             DetachCoreLib();
-            return 12;
+            return 13;
         }
     }
 

File src/osal_preproc.h

   #define OSAL_DIR_SEPARATOR           '\\'
   #define OSAL_CURRENT_DIR             ".\\"
   #define OSAL_DLL_EXTENSION           ".dll"
+  #define osal_insensitive_strcmp(x, y) _stricmp(x, y)
 
 #elif defined(__APPLE__)
 
   #define OSAL_DIR_SEPARATOR           '/'
   #define OSAL_CURRENT_DIR             "./"
   #define OSAL_DLL_EXTENSION           ".dylib"
-  
+  #define osal_insensitive_strcmp(x, y) strcasecmp(x, y)
+
 #else  /* Linux-like UNIX */
 
   #include <limits.h>  // for PATH_MAX
   #define OSAL_DIR_SEPARATOR           '/'
   #define OSAL_CURRENT_DIR             "./"
   #define OSAL_DLL_EXTENSION           ".so"
+  #define osal_insensitive_strcmp(x, y) strcasecmp(x, y)
 
 #endif