added set (create/set a cvar) and seta (create/set a saved cvar) commands, now config...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 17 Sep 2004 21:25:04 +0000 (21:25 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 17 Sep 2004 21:25:04 +0000 (21:25 +0000)
cleaned up some of the command/cvar startup sequence, the menu commands and cvars were being registered AFTER config loading and video init, now they're registered before like they should be
cleaned up some cvar code and added developer printing of the more important cvar calls

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4514 d7cf8633-e32d-0410-b094-e92efae38249

cmd.c
cvar.c
cvar.h
host.c
menu.c
menu.h
pr_cmds.c
prvm_cmds.c

diff --git a/cmd.c b/cmd.c
index 41a68f5..2e1323a 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -455,6 +455,8 @@ void Cmd_Init (void)
        Cmd_AddCommand ("cmdlist", Cmd_List_f);         // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com
        Cmd_AddCommand ("cvarlist", Cvar_List_f);       // 2000-01-09 CmdList, CvarList commands
                                                                                                // By Matthias "Maddes" Buecher
+       Cmd_AddCommand ("set", Cvar_Set_f);
+       Cmd_AddCommand ("seta", Cvar_SetA_f);
 }
 
 /*
@@ -781,7 +783,7 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
        }
 
 // check functions (only after host_initialized)
-       if (host_initialized || !strcasecmp(cmd_argv[0], "exec"))
+       if (host_initialized || !strcasecmp(cmd_argv[0], "exec") || !strcasecmp(cmd_argv[0], "set") || !strcasecmp(cmd_argv[0], "seta"))
        {
                for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
                {
diff --git a/cvar.c b/cvar.c
index 98a7207..2de6617 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -34,7 +34,7 @@ cvar_t *Cvar_FindVar (const char *var_name)
        cvar_t *var;
 
        for (var = cvar_vars;var;var = var->next)
-               if (!strcmp (var_name, var->name))
+               if (!strcasecmp (var_name, var->name))
                        return var;
 
        return NULL;
@@ -113,7 +113,7 @@ const char *Cvar_CompleteVariable (const char *partial)
 
 // check functions
        for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
-               if (!strncmp (partial,cvar->name, len))
+               if (!strncasecmp (partial,cvar->name, len))
                        return cvar->name;
 
        return NULL;
@@ -181,16 +181,10 @@ const char **Cvar_CompleteBuildList (const char *partial)
 Cvar_Set
 ============
 */
-void Cvar_SetQuick (cvar_t *var, const char *value)
+void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
 {
        qboolean changed;
 
-       if (var == NULL)
-       {
-               Con_Print("Cvar_SetQuick: var == NULL\n");
-               return;
-       }
-
        changed = strcmp(var->string, value);
        // LordHavoc: don't reallocate when there is no change
        if (!changed)
@@ -210,22 +204,29 @@ void Cvar_SetQuick (cvar_t *var, const char *value)
                SV_BroadcastPrintf("\"%s\" changed to \"%s\"\n", var->name, var->string);
 }
 
+void Cvar_SetQuick (cvar_t *var, const char *value)
+{
+       if (var == NULL)
+       {
+               Con_Print("Cvar_SetQuick: var == NULL\n");
+               return;
+       }
+
+       if (developer.integer)
+               Con_Printf("Cvar_SetQuick({\"%s\", \"%s\", %i}, \"%s\");\n", var->name, var->string, var->flags, value);
+
+       Cvar_SetQuick_Internal(var, value);
+}
+
 void Cvar_Set (const char *var_name, const char *value)
 {
        cvar_t *var;
        var = Cvar_FindVar (var_name);
        if (var == NULL)
        {
-               // there is an error in C code if this happens
                Con_Printf("Cvar_Set: variable %s not found\n", var_name);
                return;
        }
-       if (var->flags & CVAR_READONLY)
-       {
-               Con_Printf("Cvar_Set: %s is read-only\n", var_name);
-               return;
-       }
-
        Cvar_SetQuick(var, value);
 }
 
@@ -265,12 +266,51 @@ Adds a freestanding variable to the variable list.
 */
 void Cvar_RegisterVariable (cvar_t *variable)
 {
-       char    *oldstr;
+       cvar_t *cvar, *cvar2;
+       char *oldstr;
+
+       if (developer.integer)
+               Con_Printf("Cvar_RegisterVariable({\"%s\", \"%s\", %i});\n", variable->name, variable->string, variable->flags);
 
 // first check to see if it has already been defined
-       if (Cvar_FindVar (variable->name))
+       cvar = Cvar_FindVar (variable->name);
+       if (cvar)
        {
-               Con_Printf("Can't register variable %s, already defined\n", variable->name);
+               if (cvar->flags & CVAR_ALLOCATED)
+               {
+                       if (developer.integer)
+                               Con_Printf("...  replacing existing allocated cvar {\"%s\", \"%s\", %i}", cvar->name, cvar->string, cvar->flags);
+                       // fixed variables replace allocated ones
+                       // (because the engine directly accesses fixed variables)
+                       // NOTE: this isn't actually used currently
+                       // (all cvars are registered before config parsing)
+                       variable->flags |= (cvar->flags & ~CVAR_ALLOCATED);
+                       // cvar->string is now owned by variable instead
+                       variable->string = cvar->string;
+                       variable->value = atof (variable->string);
+                       variable->integer = (int) variable->value;
+                       // replace cvar with this one...
+                       variable->next = cvar->next;
+                       if (cvar_vars == cvar)
+                       {
+                               // head of the list is easy to change
+                               cvar_vars = variable;
+                       }
+                       else
+                       {
+                               // otherwise find it somewhere in the list
+                               for (cvar2 = cvar_vars;cvar2->next != cvar;cvar2 = cvar2->next);
+                               if (cvar2->next == cvar)
+                                       cvar2->next = variable;
+                       }
+
+                       // get rid of old allocated cvar
+                       // (but not the cvar->string, because we kept that)
+                       Z_Free(cvar->name);
+                       Z_Free(cvar);
+               }
+               else
+                       Con_Printf("Can't register variable %s, already defined\n", variable->name);
                return;
        }
 
@@ -293,6 +333,54 @@ void Cvar_RegisterVariable (cvar_t *variable)
        cvar_vars = variable;
 }
 
+/*
+============
+Cvar_Get
+
+Adds a newly allocated variable to the variable list or sets its value.
+============
+*/
+cvar_t *Cvar_Get (const char *name, const char *value, int flags)
+{
+       cvar_t *cvar;
+
+       if (developer.integer)
+               Con_Printf("Cvar_Get(\"%s\", \"%s\", %i);\n", name, value, flags);
+       
+// first check to see if it has already been defined
+       cvar = Cvar_FindVar (name);
+       if (cvar)
+       {
+               cvar->flags |= flags;
+               Cvar_SetQuick_Internal (cvar, value);
+               return cvar;
+       }
+
+// check for overlap with a command
+       if (Cmd_Exists (name))
+       {
+               Con_Printf("Cvar_Get: %s is a command\n", name);
+               return NULL;
+       }
+
+// allocate a new cvar, cvar name, and cvar string
+// FIXME: these never get Z_Free'd
+       cvar = Z_Malloc(sizeof(cvar_t));
+       cvar->flags = flags | CVAR_ALLOCATED;
+       cvar->name = Z_Malloc(strlen(name)+1);
+       strcpy(cvar->name, name);
+       cvar->string = Z_Malloc(strlen(value)+1);
+       strcpy(cvar->string, value);
+       cvar->value = atof (cvar->string);
+       cvar->integer = (int) cvar->value;
+
+// link the variable in
+       cvar->next = cvar_vars;
+       cvar_vars = cvar;
+       return cvar;
+}
+
+
 /*
 ============
 Cvar_Command
@@ -318,6 +406,14 @@ qboolean   Cvar_Command (void)
                return true;
        }
 
+       if (developer.integer)
+               Con_Print("Cvar_Command: ");
+
+       if (v->flags & CVAR_READONLY)
+       {
+               Con_Printf("%s is read-only\n", v->name);
+               return true;
+       }
        Cvar_Set (v->name, Cmd_Argv(1));
        return true;
 }
@@ -337,7 +433,7 @@ void Cvar_WriteVariables (qfile_t *f)
 
        for (var = cvar_vars ; var ; var = var->next)
                if (var->flags & CVAR_SAVE)
-                       FS_Printf(f, "%s \"%s\"\n", var->name, var->string);
+                       FS_Printf(f, "seta %s \"%s\"\n", var->name, var->string);
 }
 
 
@@ -368,7 +464,7 @@ void Cvar_List_f (void)
        count = 0;
        for (cvar = cvar_vars; cvar; cvar = cvar->next)
        {
-               if (partial && strncmp (partial,cvar->name,len))
+               if (partial && strncasecmp (partial,cvar->name,len))
                        continue;
 
                Con_Printf("%s is \"%s\"\n", cvar->name, cvar->string);
@@ -382,3 +478,56 @@ void Cvar_List_f (void)
 }
 // 2000-01-09 CvarList command by Maddes
 
+void Cvar_Set_f (void)
+{
+       cvar_t *cvar;
+
+       // make sure it's the right number of parameters
+       if (Cmd_Argc() < 3)
+       {
+               Con_Printf("Set: wrong number of parameters, usage: set <variablename> <value>\n");
+               return;
+       }
+
+       // check if it's read-only
+       cvar = Cvar_FindVar(Cmd_Argv(1));
+       if (cvar && cvar->flags & CVAR_READONLY)
+       {
+               Con_Printf("Set: %s is read-only\n", cvar->name);
+               return;
+       }
+
+       if (developer.integer)
+               Con_Print("Set: ");
+
+       // all looks ok, create/modify the cvar
+       Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), 0);
+}
+
+void Cvar_SetA_f (void)
+{
+       cvar_t *cvar;
+
+       // make sure it's the right number of parameters
+       if (Cmd_Argc() < 3)
+       {
+               Con_Printf("SetA: wrong number of parameters, usage: seta <variablename> <value>\n");
+               return;
+       }
+
+       // check if it's read-only
+       cvar = Cvar_FindVar(Cmd_Argv(1));
+       if (cvar && cvar->flags & CVAR_READONLY)
+       {
+               Con_Printf("SetA: %s is read-only\n", cvar->name);
+               return;
+       }
+
+       if (developer.integer)
+               Con_Print("SetA: ");
+
+       // all looks ok, create/modify the cvar
+       Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), CVAR_SAVE);
+}
+
+
diff --git a/cvar.h b/cvar.h
index 0ed510a..9523404 100644 (file)
--- a/cvar.h
+++ b/cvar.h
@@ -61,7 +61,10 @@ interface from being ambiguous.
 #define CVAR_SAVE 1
 #define CVAR_NOTIFY 2
 #define        CVAR_READONLY 4
-#define CVAR_MAXFLAGSVAL 7 // used to determine if flags is valid
+// used to determine if flags is valid
+#define CVAR_MAXFLAGSVAL 7
+// for internal use only!
+#define CVAR_ALLOCATED (1<<31)
 
 /*
 // type of a cvar for menu purposes
@@ -166,5 +169,14 @@ void Cvar_List_f (void);
 // Added by EvilTypeGuy eviltypeguy@qeradiant.com
 // Thanks to Matthias "Maddes" Buecher, http://www.inside3d.com/qip/
 
+void Cvar_Set_f (void);
+void Cvar_SetA_f (void);
+// commands to create new cvars (or set existing ones)
+// seta creates an archived cvar (saved to config)
+
+cvar_t *Cvar_Get (const char *name, const char *value, int flags);
+// allocates a cvar by name and returns its address,
+// or merely sets its value if it already exists.
+
 #endif
 
diff --git a/host.c b/host.c
index ee92486..5cd787a 100644 (file)
--- a/host.c
+++ b/host.c
@@ -868,6 +868,7 @@ void Host_Init (void)
        if (cls.state != ca_dedicated)
        {
                Palette_Init();
+               MR_Init_Commands();
                VID_Shared_Init();
                VID_Init();
 
diff --git a/menu.c b/menu.c
index 8a1105d..917374f 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -4260,7 +4260,7 @@ void Call_MR_ToggleMenu_f(void)
                MR_ToggleMenu_f();
 }
 
-void MR_Init()
+void MR_Init_Commands(void)
 {
        // set router console commands
        Cvar_RegisterVariable (&forceqmenu);
@@ -4268,7 +4268,10 @@ void MR_Init()
                Cmd_AddCommand ("menu_fallback", MP_Error); //Force to old-style menu
        Cmd_AddCommand ("menu_restart",MR_Restart);
        Cmd_AddCommand ("togglemenu", Call_MR_ToggleMenu_f);
+}
 
+void MR_Init(void)
+{
        // use -forceqmenu to use always the normal quake menu (it sets forceqmenu to 1)
        if(COM_CheckParm("-forceqmenu"))
                Cvar_SetValueQuick(&forceqmenu,1);
diff --git a/menu.h b/menu.h
index 8b51832..883bfb5 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -70,6 +70,7 @@ void MP_Shutdown (void);*/
 //
 // menu router
 //
+void MR_Init_Commands (void);
 void MR_Init (void);
 void MR_Restart (void);
 void (*MR_Keydown) (int key, char ascii);
index b226827..89702b3 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -2044,17 +2044,13 @@ void PF_GetLight (void)
        VectorMA(ambientcolor, 0.5, diffusecolor, G_VECTOR(OFS_RETURN));
 }
 
-#define MAX_QC_CVARS 128
-cvar_t qc_cvar[MAX_QC_CVARS];
-int currentqc_cvar;
-
 void PF_registercvar (void)
 {
        char *name, *value;
-       cvar_t *variable;
        name = G_STRING(OFS_PARM0);
        value = G_STRING(OFS_PARM1);
        G_FLOAT(OFS_RETURN) = 0;
+
 // first check to see if it has already been defined
        if (Cvar_FindVar (name))
                return;
@@ -2066,18 +2062,8 @@ void PF_registercvar (void)
                return;
        }
 
-       if (currentqc_cvar >= MAX_QC_CVARS)
-               PF_ERROR("PF_registercvar: ran out of cvar slots\n");
-
-// copy the name and value
-       variable = &qc_cvar[currentqc_cvar++];
-       variable->name = Z_Malloc (strlen(name)+1);
-       strcpy (variable->name, name);
-       variable->string = Z_Malloc (strlen(value)+1);
-       strcpy (variable->string, value);
-       variable->value = atof (value);
+       Cvar_Get(name, value, 0);
 
-       Cvar_RegisterVariable(variable);
        G_FLOAT(OFS_RETURN) = 1; // success
 }
 
index 503fafc..79fee2a 100644 (file)
@@ -180,11 +180,6 @@ mempool_t *vm_strings_mempool[PRVM_MAXPROGS];
 static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH];
 static int vm_string_tempindex = 0;
 
-// qc cvar 
-#define MAX_QC_CVARS 128 * PRVM_MAXPROGS
-cvar_t vm_qc_cvar[MAX_QC_CVARS];
-int vm_currentqc_cvar;
-
 // qc file handling
 #define MAX_VMFILES            256
 #define MAX_PRVMFILES  MAX_VMFILES * PRVM_MAXPROGS
@@ -1496,8 +1491,7 @@ float     registercvar (string name, string value, float flags)
 void VM_registercvar (void)
 {
        char *name, *value;
-       cvar_t *variable;
-       int     flags;  
+       int     flags;
 
        VM_SAFEPARMCOUNT(3,VM_registercvar);
 
@@ -1520,19 +1514,8 @@ void VM_registercvar (void)
                return;
        }
 
-       if (vm_currentqc_cvar >= MAX_QC_CVARS)
-               PRVM_ERROR ("VM_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
-
-// copy the name and value
-       variable = &vm_qc_cvar[vm_currentqc_cvar++];
-       variable->flags = flags;
-       variable->name = Z_Malloc (strlen(name)+1);
-       strcpy (variable->name, name);
-       variable->string = Z_Malloc (strlen(value)+1);
-       strcpy (variable->string, value);
-       variable->value = atof (value);
+       Cvar_Get(name, value, 0);
 
-       Cvar_RegisterVariable(variable);
        PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }