summaryrefslogtreecommitdiff
path: root/src/qcommon/cvar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qcommon/cvar.c')
-rw-r--r--src/qcommon/cvar.c317
1 files changed, 222 insertions, 95 deletions
diff --git a/src/qcommon/cvar.c b/src/qcommon/cvar.c
index f4f0b489..cb9f2634 100644
--- a/src/qcommon/cvar.c
+++ b/src/qcommon/cvar.c
@@ -190,6 +190,109 @@ void Cvar_CommandCompletion( void(*callback)(const char *s) ) {
}
}
+/*
+============
+Cvar_Validate
+============
+*/
+static const char *Cvar_Validate( cvar_t *var,
+ const char *value, qboolean warn )
+{
+ static char s[ MAX_CVAR_VALUE_STRING ];
+ float valuef;
+ qboolean changed = qfalse;
+
+ if( !var->validate )
+ return value;
+
+ if( !value )
+ return value;
+
+ if( Q_isanumber( value ) )
+ {
+ valuef = atof( value );
+
+ if( var->integral )
+ {
+ if( !Q_isintegral( valuef ) )
+ {
+ if( warn )
+ Com_Printf( "WARNING: cvar '%s' must be integral", var->name );
+
+ valuef = (int)valuef;
+ changed = qtrue;
+ }
+ }
+ }
+ else
+ {
+ if( warn )
+ Com_Printf( "WARNING: cvar '%s' must be numeric", var->name );
+
+ valuef = atof( var->resetString );
+ changed = qtrue;
+ }
+
+ if( valuef < var->min )
+ {
+ if( warn )
+ {
+ if( changed )
+ Com_Printf( " and is" );
+ else
+ Com_Printf( "WARNING: cvar '%s'", var->name );
+
+ if( Q_isintegral( var->min ) )
+ Com_Printf( " out of range (min %d)", (int)var->min );
+ else
+ Com_Printf( " out of range (min %f)", var->min );
+ }
+
+ valuef = var->min;
+ changed = qtrue;
+ }
+ else if( valuef > var->max )
+ {
+ if( warn )
+ {
+ if( changed )
+ Com_Printf( " and is" );
+ else
+ Com_Printf( "WARNING: cvar '%s'", var->name );
+
+ if( Q_isintegral( var->max ) )
+ Com_Printf( " out of range (max %d)", (int)var->max );
+ else
+ Com_Printf( " out of range (max %f)", var->max );
+ }
+
+ valuef = var->max;
+ changed = qtrue;
+ }
+
+ if( changed )
+ {
+ if( Q_isintegral( valuef ) )
+ {
+ Com_sprintf( s, sizeof( s ), "%d", (int)valuef );
+
+ if( warn )
+ Com_Printf( ", setting to %d\n", (int)valuef );
+ }
+ else
+ {
+ Com_sprintf( s, sizeof( s ), "%f", valuef );
+
+ if( warn )
+ Com_Printf( ", setting to %f\n", valuef );
+ }
+
+ return s;
+ }
+ else
+ return value;
+}
+
/*
============
@@ -221,6 +324,8 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
var = Cvar_FindVar (var_name);
if ( var ) {
+ var_value = Cvar_Validate( var, var_value, qfalse );
+
// if the C code is now specifying a variable that the user already
// set a value for, take the new value as the reset value
if ( ( var->flags & CVAR_USER_CREATED ) && !( flags & CVAR_USER_CREATED )
@@ -229,6 +334,17 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
Z_Free( var->resetString );
var->resetString = CopyString( var_value );
+ if(flags & CVAR_ROM)
+ {
+ // this variable was set by the user,
+ // so force it to value given by the engine.
+
+ if(var->latchedString)
+ Z_Free(var->latchedString);
+
+ var->latchedString = CopyString(var_value);
+ }
+
// ZOID--needs to be set so that cvars the game sets as
// SERVERINFO get sent to clients
cvar_modifiedFlags |= flags;
@@ -254,13 +370,6 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
Z_Free( s );
}
-// use a CVAR_SET for rom sets, get won't override
-#if 0
- // CVAR_ROM always overrides
- if ( flags & CVAR_ROM ) {
- Cvar_Set2( var_name, var_value, qtrue );
- }
-#endif
return var;
}
@@ -279,6 +388,7 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
var->value = atof (var->string);
var->integer = atoi(var->string);
var->resetString = CopyString( var_value );
+ var->validate = qfalse;
// link the variable in
var->next = cvar_vars;
@@ -297,6 +407,33 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
/*
============
+Cvar_Print
+
+Prints the value, default, and latched string of the given variable
+============
+*/
+void Cvar_Print( cvar_t *v ) {
+ Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\"",
+ v->name, v->string );
+
+ if ( !( v->flags & CVAR_ROM ) ) {
+ if ( !Q_stricmp( v->string, v->resetString ) ) {
+ Com_Printf (", the default" );
+ } else {
+ Com_Printf (" default:\"%s" S_COLOR_WHITE "\"",
+ v->resetString );
+ }
+ }
+
+ Com_Printf ("\n");
+
+ if ( v->latchedString ) {
+ Com_Printf( "latched: \"%s\"\n", v->latchedString );
+ }
+}
+
+/*
+============
Cvar_Set2
============
*/
@@ -334,6 +471,8 @@ cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) {
value = var->resetString;
}
+ value = Cvar_Validate( var, value, qtrue );
+
if((var->flags & CVAR_LATCH) && var->latchedString) {
if(!strcmp(value,var->latchedString))
return var;
@@ -509,23 +648,7 @@ qboolean Cvar_Command( void ) {
// perform a variable print or set
if ( Cmd_Argc() == 1 ) {
- Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\"",
- v->name, v->string );
-
- if ( !( v->flags & CVAR_ROM ) ) {
- if ( !Q_stricmp( v->string, v->resetString ) ) {
- Com_Printf (", the default" );
- } else {
- Com_Printf (" default:\"%s" S_COLOR_WHITE "\"",
- v->resetString );
- }
- }
-
- Com_Printf ("\n");
-
- if ( v->latchedString ) {
- Com_Printf( "latched: \"%s\"\n", v->latchedString );
- }
+ Cvar_Print( v );
return qtrue;
}
@@ -537,6 +660,35 @@ qboolean Cvar_Command( void ) {
/*
============
+Cvar_Print_f
+
+Prints the contents of a cvar
+(preferred over Cvar_Command where cvar names and commands conflict)
+============
+*/
+void Cvar_Print_f(void)
+{
+ char *name;
+ cvar_t *cv;
+
+ if(Cmd_Argc() != 2)
+ {
+ Com_Printf ("usage: print <variable>\n");
+ return;
+ }
+
+ name = Cmd_Argv(1);
+
+ cv = Cvar_FindVar(name);
+
+ if(cv)
+ Cvar_Print(cv);
+ else
+ Com_Printf ("Cvar %s does not exist.\n", name);
+}
+
+/*
+============
Cvar_Toggle_f
Toggles a cvar for easy single key binding
@@ -566,11 +718,18 @@ weren't declared in C code.
*/
void Cvar_Set_f( void ) {
int i, c, l, len;
- char combined[MAX_STRING_TOKENS];
+ char cmd[5], combined[MAX_STRING_TOKENS];
+ cvar_t *v;
c = Cmd_Argc();
- if ( c < 3 ) {
- Com_Printf ("usage: set <variable> <value>\n");
+ Q_strncpyz( cmd, Cmd_Argv(0), sizeof( cmd ) );
+
+ if ( c < 2 ) {
+ Com_Printf ("usage: %s <variable> <value>\n", cmd);
+ return;
+ }
+ if ( c == 2 ) {
+ Cvar_Print_f();
return;
}
@@ -587,73 +746,24 @@ void Cvar_Set_f( void ) {
}
l += len;
}
- Cvar_Set2 (Cmd_Argv(1), combined, qfalse);
-}
-
-/*
-============
-Cvar_SetU_f
-
-As Cvar_Set, but also flags it as userinfo
-============
-*/
-void Cvar_SetU_f( void ) {
- cvar_t *v;
-
- if ( Cmd_Argc() != 3 ) {
- Com_Printf ("usage: setu <variable> <value>\n");
- return;
- }
- Cvar_Set_f();
- v = Cvar_FindVar( Cmd_Argv( 1 ) );
- if ( !v ) {
+ v = Cvar_Set2 (Cmd_Argv(1), combined, qfalse);
+ if( !v ) {
return;
}
- v->flags |= CVAR_USERINFO;
-}
-
-/*
-============
-Cvar_SetS_f
-
-As Cvar_Set, but also flags it as userinfo
-============
-*/
-void Cvar_SetS_f( void ) {
- cvar_t *v;
-
- if ( Cmd_Argc() != 3 ) {
- Com_Printf ("usage: sets <variable> <value>\n");
- return;
- }
- Cvar_Set_f();
- v = Cvar_FindVar( Cmd_Argv( 1 ) );
- if ( !v ) {
- return;
- }
- v->flags |= CVAR_SERVERINFO;
-}
-
-/*
-============
-Cvar_SetA_f
-
-As Cvar_Set, but also flags it as archived
-============
-*/
-void Cvar_SetA_f( void ) {
- cvar_t *v;
-
- if ( Cmd_Argc() != 3 ) {
- Com_Printf ("usage: seta <variable> <value>\n");
- return;
- }
- Cvar_Set_f();
- v = Cvar_FindVar( Cmd_Argv( 1 ) );
- if ( !v ) {
- return;
+ switch( cmd[3] ) {
+ default:
+ case '\0':
+ break;
+ case 'u':
+ v->flags |= CVAR_USERINFO;
+ break;
+ case 's':
+ v->flags |= CVAR_SERVERINFO;
+ break;
+ case 'a':
+ v->flags |= CVAR_ARCHIVE;
+ break;
}
- v->flags |= CVAR_ARCHIVE;
}
/*
@@ -875,6 +985,22 @@ void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) {
/*
=====================
+Cvar_CheckRange
+=====================
+*/
+void Cvar_CheckRange( cvar_t *var, float min, float max, qboolean integral )
+{
+ var->validate = qtrue;
+ var->min = min;
+ var->max = max;
+ var->integral = integral;
+
+ // Force an initial range check
+ Cvar_Set( var->name, var->string );
+}
+
+/*
+=====================
Cvar_Register
basically a slightly modified Cvar_Get for the interpreted modules
@@ -895,7 +1021,7 @@ void Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultVa
/*
=====================
-Cvar_Register
+Cvar_Update
updates an interpreted modules' version of a cvar
=====================
@@ -938,11 +1064,12 @@ Reads in all archived cvars
void Cvar_Init (void) {
cvar_cheats = Cvar_Get("sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO );
+ Cmd_AddCommand ("print", Cvar_Print_f);
Cmd_AddCommand ("toggle", Cvar_Toggle_f);
Cmd_AddCommand ("set", Cvar_Set_f);
- Cmd_AddCommand ("sets", Cvar_SetS_f);
- Cmd_AddCommand ("setu", Cvar_SetU_f);
- Cmd_AddCommand ("seta", Cvar_SetA_f);
+ Cmd_AddCommand ("sets", Cvar_Set_f);
+ Cmd_AddCommand ("setu", Cvar_Set_f);
+ Cmd_AddCommand ("seta", Cvar_Set_f);
Cmd_AddCommand ("reset", Cvar_Reset_f);
Cmd_AddCommand ("cvarlist", Cvar_List_f);
Cmd_AddCommand ("cvar_restart", Cvar_Restart_f);