]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Initial implementation of cvar aliases, with slowmo as a starting example
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 6 Jun 2020 18:11:31 +0000 (18:11 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 6 Jun 2020 18:11:31 +0000 (18:11 +0000)
This allows cvars to be renamed, and keep the old cvar by pointing it to
the new one. Pretty much every cvar finding function has been adapted to
return a the aliased cvar or the alias itself depending on context.

For example, if a value is needed, it'll dereference the alias. If the
cvar is needed to be listed somewhere or to check if the cvar merely
exists, it will not. Other than that, it's pretty straightforward.

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

15 files changed:
cl_input.c
cl_parse.c
cl_video.c
cmd.c
console.c
cvar.c
cvar.h
host.c
host_cmd.c
menu.c
prvm_cmds.c
prvm_edict.c
server.h
sv_main.c
vid_sdl.c

index ed7c44c3c99cfff78fa7d01ba6976891f0440312..903b240b4f4c797ad9ee83237b86d34928d57916 100644 (file)
@@ -1470,7 +1470,7 @@ static void CL_ClientMovement_PlayerMove(cl_clientmovement_state_t *s)
                CL_ClientMovement_Physics_Walk(s);
 }
 
-extern cvar_t slowmo;
+extern cvar_t host_timescale;
 void CL_UpdateMoveVars(void)
 {
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
@@ -1517,8 +1517,8 @@ void CL_UpdateMoveVars(void)
        else
        {
                cl.moveflags = 0;
-               cl.movevars_ticrate = (cls.demoplayback ? 1.0f : slowmo.value) / bound(1.0f, cl_netfps.value, 1000.0f);
-               cl.movevars_timescale = (cls.demoplayback ? 1.0f : slowmo.value);
+               cl.movevars_ticrate = (cls.demoplayback ? 1.0f : host_timescale.value) / bound(1.0f, cl_netfps.value, 1000.0f);
+               cl.movevars_timescale = (cls.demoplayback ? 1.0f : host_timescale.value);
                cl.movevars_gravity = sv_gravity.value;
                cl.movevars_stopspeed = cl_movement_stopspeed.value;
                cl.movevars_maxspeed = cl_movement_maxspeed.value;
index 45bd0137d95daa69c68dbfd503c8758190e3b817..78797300c20dc081fe8ad273e6071129317c6e54 100644 (file)
@@ -3278,7 +3278,7 @@ static qboolean CL_ExaminePrintString(const char *text)
        return true;
 }
 
-extern cvar_t slowmo;
+extern cvar_t host_timescale;
 extern cvar_t cl_lerpexcess;
 static void CL_NetworkTimeReceived(double newtime)
 {
index 5aebcd50a2dc06feecf44708dbaca9dd5bd04a40..a56f88430dd28a6b6000185a1cea884628842c45 100644 (file)
@@ -137,7 +137,7 @@ static void LoadSubtitles( clvideo_t *video, const char *subtitlesfile )
                char overridename[MAX_QPATH];
                cvar_t *langcvar;
 
-               langcvar = Cvar_FindVar(&cvars_all, "language", CVAR_CLIENT | CVAR_SERVER);
+               langcvar = Cvar_FindVar(&cvars_all, "language", CVAR_CLIENT | CVAR_SERVER, false);
                subtitle_text = NULL;
                if (langcvar)
                {
diff --git a/cmd.c b/cmd.c
index d1820e2c7e748c03ba946f2dd7aab1b4d88724b9..43794e8b1c4b96d52643b50a8f11d6dd6934b901 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -788,7 +788,7 @@ static void Cmd_Toggle_f(cmd_state_t *cmd)
        else
        { // Correct Arguments Specified
                // Acquire Potential CVar
-               cvar_t* cvCVar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 1), cmd->cvars_flagsmask);
+               cvar_t* cvCVar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 1), cmd->cvars_flagsmask, false);
 
                if(cvCVar != NULL)
                { // Valid CVar
@@ -1036,7 +1036,7 @@ static const char *Cmd_GetDirectCvarValue(cmd_state_t *cmd, const char *varname,
                }
        }
 
-       if((cvar = Cvar_FindVar(cmd->cvars, varname, cmd->cvars_flagsmask)) && !(cvar->flags & CVAR_PRIVATE))
+       if((cvar = Cvar_FindVar(cmd->cvars, varname, cmd->cvars_flagsmask, false)) && !(cvar->flags & CVAR_PRIVATE))
                return cvar->string;
 
        return NULL;
@@ -1712,7 +1712,7 @@ void Cmd_AddCommand(cmd_state_t *cmd, const char *cmd_name, xcommand_t function,
        cmd_function_t *prev, *current;
 
 // fail if the command is a variable name
-       if (Cvar_FindVar(cmd->cvars, cmd_name, ~0))
+       if (Cvar_FindVar(cmd->cvars, cmd_name, ~0, true))
        {
                Con_Printf("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
                return;
index ea394a1888e07c508aa8f4fe2ccfef7ef87496f8..59316d451a50f125ecd0601c19e82d8616931ab5 100644 (file)
--- a/console.c
+++ b/console.c
@@ -3007,11 +3007,11 @@ void Con_CompleteCommandLine (cmd_state_t *cmd)
                Con_Printf("\n%i possible command%s\n", c, (c > 1) ? "s: " : ":");
                Cmd_CompleteCommandPrint(cmd, s);
        }
-       v = Cvar_CompleteCountPossible(cmd->cvars, s, CVAR_CLIENT | CVAR_SERVER);
+       v = Cvar_CompleteCountPossible(cmd->cvars, s, CVAR_CLIENT | CVAR_SERVER | CVAR_ALIAS);
        if (v)
        {
                Con_Printf("\n%i possible variable%s\n", v, (v > 1) ? "s: " : ":");
-               Cvar_CompleteCvarPrint(cmd->cvars, s, CVAR_CLIENT | CVAR_SERVER);
+               Cvar_CompleteCvarPrint(cmd->cvars, s, CVAR_CLIENT | CVAR_SERVER | CVAR_ALIAS);
        }
        a = Cmd_CompleteAliasCountPossible(cmd, s);
        if (a)
diff --git a/cvar.c b/cvar.c
index 0b039e7f9754675ea802069689fe2891083eb40e..53996326d39316b40f3b97ac51d4c988962d948f 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -32,7 +32,7 @@ cvar_state_t cvars_null;
 Cvar_FindVar
 ============
 */
-cvar_t *Cvar_FindVar(cvar_state_t *cvars, const char *var_name, int neededflags)
+cvar_t *Cvar_FindVar(cvar_state_t *cvars, const char *var_name, int neededflags, qboolean alias)
 {
        int hashindex;
        cvar_t *var;
@@ -40,9 +40,12 @@ cvar_t *Cvar_FindVar(cvar_state_t *cvars, const char *var_name, int neededflags)
        // use hash lookup to minimize search time
        hashindex = CRC_Block((const unsigned char *)var_name, strlen(var_name)) % CVAR_HASHSIZE;
        for (var = cvars->hashtable[hashindex];var;var = var->nextonhashchain)
-               if (!strcmp (var_name, var->name) && (var->flags & neededflags))
+               if (!strcmp (var_name, var->name))
+               {
+                       if(!alias && var->alias)
+                               return var->alias;
                        return var;
-
+               }
        return NULL;
 }
 
@@ -52,7 +55,7 @@ cvar_t *Cvar_FindVarAfter(cvar_state_t *cvars, const char *prev_var_name, int ne
 
        if (*prev_var_name)
        {
-               var = Cvar_FindVar(cvars, prev_var_name, neededflags);
+               var = Cvar_FindVar(cvars, prev_var_name, neededflags, false);
                if (!var)
                        return NULL;
                var = var->next;
@@ -109,7 +112,7 @@ float Cvar_VariableValueOr(cvar_state_t *cvars, const char *var_name, float def,
 {
        cvar_t *var;
 
-       var = Cvar_FindVar(cvars, var_name, neededflags);
+       var = Cvar_FindVar(cvars, var_name, neededflags, false);
        if (!var)
                return def;
        return atof (var->string);
@@ -129,7 +132,7 @@ const char *Cvar_VariableStringOr(cvar_state_t *cvars, const char *var_name, con
 {
        cvar_t *var;
 
-       var = Cvar_FindVar(cvars, var_name, neededflags);
+       var = Cvar_FindVar(cvars, var_name, neededflags, false);
        if (!var)
                return def;
        return var->string;
@@ -149,7 +152,7 @@ const char *Cvar_VariableDefString(cvar_state_t *cvars, const char *var_name, in
 {
        cvar_t *var;
 
-       var = Cvar_FindVar(cvars, var_name, neededflags);
+       var = Cvar_FindVar(cvars, var_name, neededflags, false);
        if (!var)
                return cvar_null_string;
        return var->defstring;
@@ -164,7 +167,7 @@ const char *Cvar_VariableDescription(cvar_state_t *cvars, const char *var_name,
 {
        cvar_t *var;
 
-       var = Cvar_FindVar(cvars, var_name, neededflags);
+       var = Cvar_FindVar(cvars, var_name, neededflags, false);
        if (!var)
                return cvar_null_string;
        return var->description;
@@ -253,9 +256,20 @@ const char **Cvar_CompleteBuildList(cvar_state_t *cvars, const char *partial, in
 
 void Cvar_PrintHelp(cvar_t *cvar, qboolean full)
 {
-       Con_Printf("^3%s^7 is \"%s\" [\"%s\"] ", cvar->name, ((cvar->flags & CVAR_PRIVATE) ? "********"/*hunter2*/ : cvar->string), cvar->defstring);
+       cvar_t *cvar_actual;
+
+       Con_Printf("^3%s^7", cvar->name);
+       if(cvar->alias) {
+               cvar_actual = cvar->alias;
+               Con_Printf(" (now ^3%s^7)", cvar_actual->name);
+       } else {
+               cvar_actual = cvar;
+       }
+
+       Con_Printf(" is \"%s\" [\"%s\"] ", ((cvar_actual->flags & CVAR_PRIVATE) ? "********"/*hunter2*/ : cvar_actual->string), cvar_actual->defstring);
+       
        if (full)
-               Con_Printf("%s", cvar->description);
+               Con_Printf("%s", cvar_actual->description);
        Con_Printf("\n");
 }
 
@@ -351,6 +365,9 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
        char vabuf[1024];
        char new_value[MAX_INPUTLINE];
 
+       if(var->alias)
+               var = var->alias;
+
        changed = strcmp(var->string, value) != 0;
        // LadyHavoc: don't reallocate when there is no change
        if (!changed)
@@ -453,7 +470,7 @@ void Cvar_SetQuick (cvar_t *var, const char *value)
 void Cvar_Set(cvar_state_t *cvars, const char *var_name, const char *value)
 {
        cvar_t *var;
-       var = Cvar_FindVar(cvars, var_name, ~0);
+       var = Cvar_FindVar(cvars, var_name, ~0, false);
        if (var == NULL)
        {
                Con_Printf("Cvar_Set: variable %s not found\n", var_name);
@@ -489,9 +506,21 @@ void Cvar_SetValue(cvar_state_t *cvars, const char *var_name, float value)
        Cvar_Set(cvars, var_name, val);
 }
 
-void Cvar_RegisterCallback(cvar_t *variable, void (*callback)(char *))
+void Cvar_RegisterCallback(cvar_t *var, void (*callback)(char *))
 {
-       variable->callback = callback;
+       var->callback = callback;
+}
+
+void Cvar_RegisterAlias(cvar_t *alias, cvar_t *target)
+{
+       if(!(alias->flags & CVAR_ALIAS)) {
+               Con_Warnf("Cvar_RegisterAlias: \"%s\" is not declared as an alias\n", alias->name);
+               return;
+       }
+       // We'll want to register it first
+       Cvar_RegisterVariable(alias);
+
+       alias->alias = target;
 }
 
 /*
@@ -510,26 +539,33 @@ void Cvar_RegisterVariable (cvar_t *variable)
        size_t alloclen;
        int i;
 
-       switch (variable->flags & (CVAR_CLIENT | CVAR_SERVER))
+       if(!(variable->flags & CVAR_ALIAS))
+       {
+               switch (variable->flags & (CVAR_CLIENT | CVAR_SERVER))
+               {
+               case CVAR_CLIENT:
+               case CVAR_SERVER:
+               case CVAR_CLIENT | CVAR_SERVER:
+                       cvars = &cvars_all;
+                       break;
+               case 0:
+                       Sys_Error("Cvar_RegisterVariable({\"%s\", \"%s\", %i}) with no CVAR_CLIENT | CVAR_SERVER flags\n", variable->name, variable->string, variable->flags);
+                       break;
+               default:
+                       Sys_Error("Cvar_RegisterVariable({\"%s\", \"%s\", %i}) with weird CVAR_CLIENT | CVAR_SERVER flags\n", variable->name, variable->string, variable->flags);
+                       break;
+               }
+       }
+       else
        {
-       case CVAR_CLIENT:
-       case CVAR_SERVER:
-       case CVAR_CLIENT | CVAR_SERVER:
                cvars = &cvars_all;
-               break;
-       case 0:
-               Sys_Error("Cvar_RegisterVariable({\"%s\", \"%s\", %i}) with no CVAR_CLIENT | CVAR_SERVER flags\n", variable->name, variable->string, variable->flags);
-               break;
-       default:
-               Sys_Error("Cvar_RegisterVariable({\"%s\", \"%s\", %i}) with weird CVAR_CLIENT | CVAR_SERVER flags\n", variable->name, variable->string, variable->flags);
-               break;
        }
-
+       
        if (developer_extra.integer)
                Con_DPrintf("Cvar_RegisterVariable({\"%s\", \"%s\", %i});\n", variable->name, variable->string, variable->flags);
 
 // first check to see if it has already been defined
-       cvar = Cvar_FindVar(cvars, variable->name, ~0);
+       cvar = Cvar_FindVar(cvars, variable->name, ~0, true);
        if (cvar)
        {
                if (cvar->flags & CVAR_ALLOCATED)
@@ -580,16 +616,18 @@ void Cvar_RegisterVariable (cvar_t *variable)
                Con_Printf("Cvar_RegisterVariable: %s is a command\n", variable->name);
                return;
        }
-
-// copy the value off, because future sets will Z_Free it
-       oldstr = (char *)variable->string;
-       alloclen = strlen(variable->string) + 1;
-       variable->string = (char *)Z_Malloc (alloclen);
-       memcpy ((char *)variable->string, oldstr, alloclen);
-       variable->defstring = (char *)Z_Malloc (alloclen);
-       memcpy ((char *)variable->defstring, oldstr, alloclen);
-       variable->value = atof (variable->string);
-       variable->integer = (int) variable->value;
+       if(!(variable->flags & CVAR_ALIAS))
+       {
+               // copy the value off, because future sets will Z_Free it
+               oldstr = (char *)variable->string;
+               alloclen = strlen(variable->string) + 1;
+               variable->string = (char *)Z_Malloc (alloclen);
+               memcpy ((char *)variable->string, oldstr, alloclen);
+               variable->defstring = (char *)Z_Malloc (alloclen);
+               memcpy ((char *)variable->defstring, oldstr, alloclen);
+               variable->value = atof (variable->string);
+               variable->integer = (int) variable->value;
+       }
 
        // Mark it as not an autocvar.
        for (i = 0;i < PRVM_PROG_MAX;i++)
@@ -629,7 +667,7 @@ cvar_t *Cvar_Get(cvar_state_t *cvars, const char *name, const char *value, int f
                Con_DPrintf("Cvar_Get(\"%s\", \"%s\", %i);\n", name, value, flags);
 
 // first check to see if it has already been defined
-       cvar = Cvar_FindVar(cvars, name, ~0);
+       cvar = Cvar_FindVar(cvars, name, ~0, true);
        if (cvar)
        {
                cvar->flags |= flags;
@@ -699,6 +737,20 @@ cvar_t *Cvar_Get(cvar_state_t *cvars, const char *name, const char *value, int f
        return cvar;
 }
 
+qboolean Cvar_Readonly (cvar_t *var, const char *cmd_name)
+{
+       if (var->flags & CVAR_READONLY || (var->alias && (var->alias->flags & CVAR_READONLY)))
+       {
+               if(cmd_name)
+                       Con_Printf("%s: ",cmd_name);
+               Con_Printf("%s", var->name);
+               if (var->alias && var->alias->name)
+                       Con_Printf(" (from %s)",var->alias->name);
+               Con_Printf(" is read-only\n");
+               return true;
+       }
+       return false;
+}
 
 /*
 ============
@@ -713,7 +765,7 @@ qboolean    Cvar_Command (cmd_state_t *cmd)
        cvar_t                  *v;
 
 // check variables
-       v = Cvar_FindVar(cvars, Cmd_Argv(cmd, 0), cmd->cvars_flagsmask);
+       v = Cvar_FindVar(cvars, Cmd_Argv(cmd, 0), (cmd->cvars_flagsmask), true);
        if (!v)
                return false;
 
@@ -726,12 +778,10 @@ qboolean  Cvar_Command (cmd_state_t *cmd)
 
        if (developer_extra.integer)
                Con_DPrint("Cvar_Command: ");
-
-       if (v->flags & CVAR_READONLY)
-       {
-               Con_Printf("%s is read-only\n", v->name);
+       
+       if(Cvar_Readonly(v, NULL))
                return true;
-       }
+       
        Cvar_SetQuick(v, Cmd_Argv(cmd, 1));
        if (developer_extra.integer)
                Con_DPrint("\n");
@@ -745,7 +795,11 @@ void Cvar_UnlockDefaults(cmd_state_t *cmd)
        cvar_t *var;
        // unlock the default values of all cvars
        for (var = cvars->vars ; var ; var = var->next)
+       {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                var->flags &= ~CVAR_DEFAULTSET;
+       }
 }
 
 
@@ -756,6 +810,8 @@ void Cvar_LockDefaults_f(cmd_state_t *cmd)
        // lock in the default values of all cvars
        for (var = cvars->vars ; var ; var = var->next)
        {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                if (!(var->flags & CVAR_DEFAULTSET))
                {
                        size_t alloclen;
@@ -775,6 +831,8 @@ void Cvar_SaveInitState(cvar_state_t *cvars)
        cvar_t *c;
        for (c = cvars->vars;c;c = c->next)
        {
+               if(c->flags & CVAR_ALIAS)
+                       continue;
                c->initstate = true;
                c->initflags = c->flags;
                c->initdefstring = Mem_strdup(zonemempool, c->defstring);
@@ -792,6 +850,8 @@ void Cvar_RestoreInitState(cvar_state_t *cvars)
        cvar_t *c2, **cp2;
        for (cp = &cvars->vars;(c = *cp);)
        {
+               if(c->flags & CVAR_ALIAS)
+                       continue;
                if (c->initstate)
                {
                        // restore this cvar, it existed at init
@@ -868,8 +928,12 @@ void Cvar_ResetToDefaults_All_f(cmd_state_t *cmd)
        cvar_t *var;
        // restore the default values of all cvars
        for (var = cvars->vars ; var ; var = var->next)
+       {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                if((var->flags & CVAR_NORESETTODEFAULTS) == 0)
                        Cvar_SetQuick(var, var->defstring);
+       }
 }
 
 
@@ -879,8 +943,12 @@ void Cvar_ResetToDefaults_NoSaveOnly_f(cmd_state_t *cmd)
        cvar_t *var;
        // restore the default values of all cvars
        for (var = cvars->vars ; var ; var = var->next)
+       {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                if ((var->flags & (CVAR_NORESETTODEFAULTS | CVAR_SAVE)) == 0)
                        Cvar_SetQuick(var, var->defstring);
+       }
 }
 
 
@@ -890,8 +958,12 @@ void Cvar_ResetToDefaults_SaveOnly_f(cmd_state_t *cmd)
        cvar_t *var;
        // restore the default values of all cvars
        for (var = cvars->vars ; var ; var = var->next)
+       {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                if ((var->flags & (CVAR_NORESETTODEFAULTS | CVAR_SAVE)) == CVAR_SAVE)
                        Cvar_SetQuick(var, var->defstring);
+       }
 }
 
 
@@ -909,13 +981,16 @@ void Cvar_WriteVariables (cvar_state_t *cvars, qfile_t *f)
        char buf1[MAX_INPUTLINE], buf2[MAX_INPUTLINE];
 
        // don't save cvars that match their default value
-       for (var = cvars->vars ; var ; var = var->next)
+       for (var = cvars->vars ; var ; var = var->next) {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                if ((var->flags & CVAR_SAVE) && (strcmp(var->string, var->defstring) || ((var->flags & CVAR_ALLOCATED) && !(var->flags & CVAR_DEFAULTSET))))
                {
                        Cmd_QuoteString(buf1, sizeof(buf1), var->name, "\"\\$", false);
                        Cmd_QuoteString(buf2, sizeof(buf2), var->string, "\"\\$", false);
                        FS_Printf(f, "%s\"%s\" \"%s\"\n", var->flags & CVAR_ALLOCATED ? "seta " : "", buf1, buf2);
                }
+       }
 }
 
 
@@ -983,12 +1058,10 @@ void Cvar_Set_f(cmd_state_t *cmd)
        }
 
        // check if it's read-only
-       cvar = Cvar_FindVar(cvars, Cmd_Argv(cmd, 1), ~0);
-       if (cvar && cvar->flags & CVAR_READONLY)
-       {
-               Con_Printf("Set: %s is read-only\n", cvar->name);
-               return;
-       }
+       cvar = Cvar_FindVar(cvars, Cmd_Argv(cmd, 1), ~0, true);
+       if (cvar)
+               if(Cvar_Readonly(cvar,"Set"))
+                       return;
 
        if (developer_extra.integer)
                Con_DPrint("Set: ");
@@ -1010,12 +1083,10 @@ void Cvar_SetA_f(cmd_state_t *cmd)
        }
 
        // check if it's read-only
-       cvar = Cvar_FindVar(cvars, Cmd_Argv(cmd, 1), ~0);
-       if (cvar && cvar->flags & CVAR_READONLY)
-       {
-               Con_Printf("SetA: %s is read-only\n", cvar->name);
-               return;
-       }
+       cvar = Cvar_FindVar(cvars, Cmd_Argv(cmd, 1), ~0, true);
+       if (cvar)
+               if(Cvar_Readonly(cvar,"SetA"))
+                       return;
 
        if (developer_extra.integer)
                Con_DPrint("SetA: ");
@@ -1044,11 +1115,8 @@ void Cvar_Del_f(cmd_state_t *cmd)
                        Con_Printf("%s: %s is not defined\n", Cmd_Argv(cmd, 0), Cmd_Argv(cmd, i));
                        continue;
                }
-               if(cvar->flags & CVAR_READONLY)
-               {
-                       Con_Printf("%s: %s is read-only\n", Cmd_Argv(cmd, 0), cvar->name);
+               if(Cvar_Readonly(cvar, Cmd_Argv(cmd, 0)))
                        continue;
-               }
                if(!(cvar->flags & CVAR_ALLOCATED))
                {
                        Con_Printf("%s: %s is static and cannot be deleted\n", Cmd_Argv(cmd, 0), cvar->name);
@@ -1069,13 +1137,15 @@ void Cvar_Del_f(cmd_state_t *cmd)
                        parent->nextonhashchain = cvar->nextonhashchain;
                else if(link)
                        *link = cvar->nextonhashchain;
+               if(!(cvar->flags & CVAR_ALIAS))
+               {
+                       if(cvar->description != cvar_dummy_description)
+                               Z_Free((char *)cvar->description);
 
-               if(cvar->description != cvar_dummy_description)
-                       Z_Free((char *)cvar->description);
-
-               Z_Free((char *)cvar->name);
-               Z_Free((char *)cvar->string);
-               Z_Free((char *)cvar->defstring);
+                       Z_Free((char *)cvar->name);
+                       Z_Free((char *)cvar->string);
+                       Z_Free((char *)cvar->defstring);
+               }
                Z_Free(cvar);
        }
 }
@@ -1101,6 +1171,8 @@ void Cvar_FillAll_f(cmd_state_t *cmd)
        buf[n] = 0;
        for(var = cvars->vars; var; var = var->next)
        {
+               if(var->flags & CVAR_ALIAS)
+                       continue;
                for(i = 0, p = buf, q = var->name; i < n; ++i)
                {
                        *p++ = *q++;
diff --git a/cvar.h b/cvar.h
index 2bbcd1dc177bc9a4470d30ff59064ca7127db208..84248c56fb339d539bf22e87d7deabf015a447a1 100644 (file)
--- a/cvar.h
+++ b/cvar.h
@@ -76,8 +76,10 @@ interface from being ambiguous.
 #define CVAR_CLIENT 256
 // cvar is accessible in dedicated server
 #define CVAR_SERVER 512
+// cvar is an alias of another cvar
+#define CVAR_ALIAS 1024
 // used to determine if flags is valid
-#define CVAR_MAXFLAGSVAL 1023
+#define CVAR_MAXFLAGSVAL 2047
 // for internal use only!
 #define CVAR_DEFAULTSET (1<<30)
 #define CVAR_ALLOCATED (1<<31)
@@ -149,6 +151,7 @@ typedef struct cvar_s
        //menucvar_t menuinfo;
        struct cvar_s *next;
        struct cvar_s *nextonhashchain;
+       struct cvar_s *alias;
 } cvar_t;
 
 typedef struct cvar_state_s
@@ -172,10 +175,14 @@ void Cvar_MenuOption(cvar_t *variable, int menu, int value[16], const char *name
 
 /// registers a cvar that already has the name, string, and optionally the
 /// archive elements set.
+void Cvar_RegisterAlias(cvar_t *source, cvar_t *target);
+
 void Cvar_RegisterCallback(cvar_t *variable, void (*callback)(char *));
 
 void Cvar_RegisterVariable(cvar_t *variable);
 
+qboolean Cvar_Readonly (cvar_t *var, const char *cmd_name);
+
 /// equivelant to "<name> <variable>" typed at the console
 void Cvar_Set (cvar_state_t *cvars, const char *var_name, const char *value);
 
@@ -229,7 +236,7 @@ void Cvar_WriteVariables (cvar_state_t *cvars, qfile_t *f);
 // Writes lines containing "set variable value" for all variables
 // with the archive flag set to true.
 
-cvar_t *Cvar_FindVar(cvar_state_t *cvars, const char *var_name, int neededflags);
+cvar_t *Cvar_FindVar(cvar_state_t *cvars, const char *var_name, int neededflags, qboolean alias);
 cvar_t *Cvar_FindVarAfter(cvar_state_t *cvars, const char *prev_var_name, int neededflags);
 
 int Cvar_CompleteCountPossible(cvar_state_t *cvars, const char *partial, int neededflags);
diff --git a/host.c b/host.c
index 4fb4b28731d63f7f6e2b296c68d8d7663f1b1895..5459a444816446c77910206cac0add0ed29e1393 100644 (file)
--- a/host.c
+++ b/host.c
@@ -881,8 +881,8 @@ void Host_Main(void)
                                framelimit = cl_maxphysicsframesperserverframe.integer;
                                aborttime = Sys_DirtyTime() + 0.1;
                        }
-                       if(slowmo.value > 0 && slowmo.value < 1)
-                               advancetime = min(advancetime, 0.1 / slowmo.value);
+                       if(host_timescale.value > 0 && host_timescale.value < 1)
+                               advancetime = min(advancetime, 0.1 / host_timescale.value);
                        else
                                advancetime = min(advancetime, 0.1);
 
@@ -899,7 +899,7 @@ void Host_Main(void)
 
                        // only advance time if not paused
                        // the game also pauses in singleplayer when menu or console is used
-                       sv.frametime = advancetime * slowmo.value;
+                       sv.frametime = advancetime * host_timescale.value;
                        if (host_framerate.value)
                                sv.frametime = host_framerate.value;
                        if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
@@ -980,7 +980,7 @@ void Host_Main(void)
                        // scale playback speed of demos by slowmo cvar
                        if (cls.demoplayback)
                        {
-                               clframetime *= slowmo.value;
+                               clframetime *= host_timescale.value;
                                // if demo playback is paused, don't advance time at all
                                if (cls.demopaused)
                                        clframetime = 0;
index 280ce6a6f1c79e6dae8a8a9e3c0f51be45047190..9f50578adfc2b48cb6c0e81e7b265b08c0f665d6 100644 (file)
@@ -2502,13 +2502,13 @@ static void Host_SendCvar_f(cmd_state_t *cmd)
        cvarname = Cmd_Argv(cmd, 1);
        if (cls.state == ca_connected)
        {
-               c = Cvar_FindVar(&cvars_all, cvarname, CVAR_CLIENT | CVAR_SERVER);
+               c = Cvar_FindVar(&cvars_all, cvarname, CVAR_CLIENT | CVAR_SERVER, false);
                // LadyHavoc: if there is no such cvar or if it is private, send a
                // reply indicating that it has no value
                if(!c || (c->flags & CVAR_PRIVATE))
                        Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s", cvarname));
                else
-                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", c->name, c->string));
+                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", cvarname, c->string));
                return;
        }
        if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand))
diff --git a/menu.c b/menu.c
index be6c3c01d3b844ba72fee795310f95137802b943..b531ab1184d9017b3d4aa333beed95880e8c1276 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1581,7 +1581,7 @@ void M_Menu_Options_f(cmd_state_t *cmd)
        m_entersound = true;
 }
 
-extern cvar_t slowmo;
+extern cvar_t host_timescale;
 extern dllhandle_t jpeg_dll;
 extern cvar_t gl_texture_anisotropy;
 extern cvar_t r_textshadow;
index f947766ae6e9a56040f0643cde7a49127cb8592b..680aa06ef8de0c651c46542752daae6c6da9a7fd 100644 (file)
@@ -641,7 +641,7 @@ void VM_localcmd_server(prvm_prog_t *prog)
 static qboolean PRVM_Cvar_ReadOk(prvm_prog_t *prog, const char *string)
 {
        cvar_t *cvar;
-       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask);
+       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask, false);
        return ((cvar) && ((cvar->flags & CVAR_PRIVATE) == 0));
 }
 
@@ -683,7 +683,7 @@ void VM_cvar_type(prvm_prog_t *prog)
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask);
+       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask, true);
 
 
        if(!cvar)
@@ -1674,7 +1674,7 @@ void VM_registercvar(prvm_prog_t *prog)
                return;
 
 // first check to see if it has already been defined
-       if (Cvar_FindVar (prog->console_cmd->cvars, name, prog->console_cmd->cvars_flagsmask))
+       if (Cvar_FindVar (prog->console_cmd->cvars, name, prog->console_cmd->cvars_flagsmask, true))
                return;
 
 // check for overlap with a command
index 9d81ef048263355bba93ed028b8e64e2bc358130..9e0f36f0560761981dd67171279dca656172fd3e 100644 (file)
@@ -1164,12 +1164,11 @@ static void PRVM_ED_EdictGet_f(cmd_state_t *cmd)
        s = PRVM_UglyValueString(prog, (etype_t)key->type, v, valuebuf, sizeof(valuebuf));
        if(Cmd_Argc(cmd) == 5)
        {
-               cvar_t *cvar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 4), cmd->cvars_flagsmask);
-               if (cvar && cvar->flags & CVAR_READONLY)
-               {
-                       Con_Printf("prvm_edictget: %s is read-only\n", cvar->name);
-                       goto fail;
-               }
+               cvar_t *cvar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 4), cmd->cvars_flagsmask, true);
+               if (cvar)
+                       if(Cvar_Readonly(cvar, "prvm_edictget"))
+                               goto fail;
+
                Cvar_Get(cmd->cvars, Cmd_Argv(cmd, 4), s, cmd->cvars_flagsmask, NULL);
        }
        else
@@ -1207,12 +1206,10 @@ static void PRVM_ED_GlobalGet_f(cmd_state_t *cmd)
        s = PRVM_UglyValueString(prog, (etype_t)key->type, v, valuebuf, sizeof(valuebuf));
        if(Cmd_Argc(cmd) == 4)
        {
-               cvar_t *cvar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 3), cmd->cvars_flagsmask);
-               if (cvar && cvar->flags & CVAR_READONLY)
-               {
-                       Con_Printf("prvm_globalget: %s is read-only\n", cvar->name);
-                       goto fail;
-               }
+               cvar_t *cvar = Cvar_FindVar(cmd->cvars, Cmd_Argv(cmd, 3), cmd->cvars_flagsmask, true);
+               if (cvar)
+                       if(Cvar_Readonly(cvar, "prvm_globalget"))
+                               goto fail;
                Cvar_Get(cmd->cvars, Cmd_Argv(cmd, 3), s, cmd->cvars_flagsmask, NULL);
        }
        else
@@ -2390,7 +2387,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                )
                {
                        prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
-                       cvar = Cvar_FindVar(prog->console_cmd->cvars, name + 9, prog->console_cmd->cvars_flagsmask);
+                       cvar = Cvar_FindVar(prog->console_cmd->cvars, name + 9, prog->console_cmd->cvars_flagsmask, false);
                        //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, prog->name);
                        if(!cvar)
                        {
index c84fab1dece8779aa962cbd73262324c755d6081..46c124633d90e86a4e4d831ff0ef1146613e7ab6 100644 (file)
--- a/server.h
+++ b/server.h
@@ -404,7 +404,7 @@ extern cvar_t scratch2;
 extern cvar_t scratch3;
 extern cvar_t scratch4;
 extern cvar_t skill;
-extern cvar_t slowmo;
+extern cvar_t host_timescale;
 extern cvar_t sv_accelerate;
 extern cvar_t sv_aim;
 extern cvar_t sv_airaccel_qw;
index 0a0dd9820c36aa8639a822d6c1ebafd1f31bcd67..874174780ee9551e5a14e46e9df60da70acb6e48 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -47,7 +47,8 @@ cvar_t pausable = {CVAR_SERVER, "pausable","1", "allow players to pause or not (
 cvar_t pr_checkextension = {CVAR_SERVER | CVAR_READONLY, "pr_checkextension", "1", "indicates to QuakeC that the standard quakec extensions system is available (if 0, quakec should not attempt to use extensions)"};
 cvar_t samelevel = {CVAR_SERVER | CVAR_NOTIFY, "samelevel","0", "repeats same level if level ends (due to timelimit or someone hitting an exit)"};
 cvar_t skill = {CVAR_SERVER, "skill","1", "difficulty level of game, affects monster layouts in levels, 0 = easy, 1 = normal, 2 = hard, 3 = nightmare (same layout as hard but monsters fire twice)"};
-cvar_t slowmo = {CVAR_CLIENT | CVAR_SERVER, "slowmo", "1.0", "controls game speed, 0.5 is half speed, 2 is double speed"};
+cvar_t host_timescale = {CVAR_CLIENT | CVAR_SERVER, "host_timescale", "1.0", "controls game speed, 0.5 is half speed, 2 is double speed"};
+cvar_t slowmo = {CVAR_ALIAS, "slowmo"};
 
 cvar_t sv_accelerate = {CVAR_SERVER, "sv_accelerate", "10", "rate at which a player accelerates to sv_maxspeed"};
 cvar_t sv_aim = {CVAR_SERVER | CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"};
@@ -204,7 +205,7 @@ server_static_t svs;
 
 mempool_t *sv_mempool = NULL;
 
-extern cvar_t slowmo;
+extern cvar_t host_timescale;
 extern float           scr_centertime_off;
 
 // MUST match effectnameindex_t in client.h
@@ -413,7 +414,7 @@ prvm_required_field_t sv_reqglobals[] =
 #undef PRVM_DECLARE_function
 };
 
-static void SV_Slowmo_c(char *string)
+static void Host_Timescale_c(char *string)
 {
        double value;
        value = atof(string);
@@ -473,8 +474,9 @@ void SV_Init (void)
        Cvar_RegisterVariable (&pr_checkextension);
        Cvar_RegisterVariable (&samelevel);
        Cvar_RegisterVariable (&skill);
-       Cvar_RegisterVariable (&slowmo);
-       Cvar_RegisterCallback (&slowmo, SV_Slowmo_c);
+       Cvar_RegisterVariable (&host_timescale);
+       Cvar_RegisterCallback (&host_timescale, Host_Timescale_c);
+       Cvar_RegisterAlias (&slowmo, &host_timescale);
        Cvar_RegisterVariable (&sv_accelerate);
        Cvar_RegisterVariable (&sv_aim);
        Cvar_RegisterVariable (&sv_airaccel_qw);
@@ -2125,7 +2127,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                | (sv_gameplayfix_gravityunaffectedbyticrate.integer ? MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE : 0)
        ;
        statsf[STAT_MOVEVARS_TICRATE] = sys_ticrate.value;
-       statsf[STAT_MOVEVARS_TIMESCALE] = slowmo.value;
+       statsf[STAT_MOVEVARS_TIMESCALE] = host_timescale.value;
        statsf[STAT_MOVEVARS_GRAVITY] = sv_gravity.value;
        statsf[STAT_MOVEVARS_STOPSPEED] = sv_stopspeed.value;
        statsf[STAT_MOVEVARS_MAXSPEED] = sv_maxspeed.value;
@@ -4040,7 +4042,7 @@ static int SV_ThreadFunc(void *voiddata)
 
                        // only advance time if not paused
                        // the game also pauses in singleplayer when menu or console is used
-                       sv.frametime = advancetime * slowmo.value;
+                       sv.frametime = advancetime * host_timescale.value;
                        if (host_framerate.value)
                                sv.frametime = host_framerate.value;
                        if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
index 0b37e274a28fdfdfd60bfb9cd6c01052f96c1e26..74b7ce1e64a82658d850b19513c4f512ea510f1e 100644 (file)
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -1618,8 +1618,8 @@ extern cvar_t gl_info_driver;
 qboolean VID_InitMode(viddef_mode_t *mode)
 {
        // GAME_STEELSTORM specific
-       steelstorm_showing_map = Cvar_FindVar(&cvars_all, "steelstorm_showing_map", ~0);
-       steelstorm_showing_mousecursor = Cvar_FindVar(&cvars_all, "steelstorm_showing_mousecursor", ~0);
+       steelstorm_showing_map = Cvar_FindVar(&cvars_all, "steelstorm_showing_map", ~0, false);
+       steelstorm_showing_mousecursor = Cvar_FindVar(&cvars_all, "steelstorm_showing_mousecursor", ~0, false);
 
        if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
                Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());