From 6bf20c78f5b69d40bcc4931df93d29198435ab67 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 17:39:27 +0000 Subject: newlines fixed git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/qcommon/cvar.c | 1812 +++++++++++++++++++++++++-------------------------- 1 file changed, 906 insertions(+), 906 deletions(-) (limited to 'code/qcommon/cvar.c') diff --git a/code/qcommon/cvar.c b/code/qcommon/cvar.c index 864969c..8b38712 100755 --- a/code/qcommon/cvar.c +++ b/code/qcommon/cvar.c @@ -1,906 +1,906 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// cvar.c -- dynamic variable tracking - -#include "../game/q_shared.h" -#include "qcommon.h" - -cvar_t *cvar_vars; -cvar_t *cvar_cheats; -int cvar_modifiedFlags; - -#define MAX_CVARS 1024 -cvar_t cvar_indexes[MAX_CVARS]; -int cvar_numIndexes; - -#define FILE_HASH_SIZE 256 -static cvar_t* hashTable[FILE_HASH_SIZE]; - -cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force); - -/* -================ -return a hash value for the filename -================ -*/ -static long generateHashValue( const char *fname ) { - int i; - long hash; - char letter; - - hash = 0; - i = 0; - while (fname[i] != '\0') { - letter = tolower(fname[i]); - hash+=(long)(letter)*(i+119); - i++; - } - hash &= (FILE_HASH_SIZE-1); - return hash; -} - -/* -============ -Cvar_ValidateString -============ -*/ -static qboolean Cvar_ValidateString( const char *s ) { - if ( !s ) { - return qfalse; - } - if ( strchr( s, '\\' ) ) { - return qfalse; - } - if ( strchr( s, '\"' ) ) { - return qfalse; - } - if ( strchr( s, ';' ) ) { - return qfalse; - } - return qtrue; -} - -/* -============ -Cvar_FindVar -============ -*/ -static cvar_t *Cvar_FindVar( const char *var_name ) { - cvar_t *var; - long hash; - - hash = generateHashValue(var_name); - - for (var=hashTable[hash] ; var ; var=var->hashNext) { - if (!Q_stricmp(var_name, var->name)) { - return var; - } - } - - return NULL; -} - -/* -============ -Cvar_VariableValue -============ -*/ -float Cvar_VariableValue( const char *var_name ) { - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) - return 0; - return var->value; -} - - -/* -============ -Cvar_VariableIntegerValue -============ -*/ -int Cvar_VariableIntegerValue( const char *var_name ) { - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) - return 0; - return var->integer; -} - - -/* -============ -Cvar_VariableString -============ -*/ -char *Cvar_VariableString( const char *var_name ) { - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) - return ""; - return var->string; -} - - -/* -============ -Cvar_VariableStringBuffer -============ -*/ -void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) { - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) { - *buffer = 0; - } - else { - Q_strncpyz( buffer, var->string, bufsize ); - } -} - - -/* -============ -Cvar_CommandCompletion -============ -*/ -void Cvar_CommandCompletion( void(*callback)(const char *s) ) { - cvar_t *cvar; - - for ( cvar = cvar_vars ; cvar ; cvar = cvar->next ) { - callback( cvar->name ); - } -} - - -/* -============ -Cvar_Get - -If the variable already exists, the value will not be set unless CVAR_ROM -The flags will be or'ed in if the variable exists. -============ -*/ -cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) { - cvar_t *var; - long hash; - - if ( !var_name || ! var_value ) { - Com_Error( ERR_FATAL, "Cvar_Get: NULL parameter" ); - } - - if ( !Cvar_ValidateString( var_name ) ) { - Com_Printf("invalid cvar name string: %s\n", var_name ); - var_name = "BADNAME"; - } - -#if 0 // FIXME: values with backslash happen - if ( !Cvar_ValidateString( var_value ) ) { - Com_Printf("invalid cvar value string: %s\n", var_value ); - var_value = "BADVALUE"; - } -#endif - - var = Cvar_FindVar (var_name); - if ( var ) { - // 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 ) - && var_value[0] ) { - var->flags &= ~CVAR_USER_CREATED; - Z_Free( var->resetString ); - var->resetString = CopyString( var_value ); - - // ZOID--needs to be set so that cvars the game sets as - // SERVERINFO get sent to clients - cvar_modifiedFlags |= flags; - } - - var->flags |= flags; - // only allow one non-empty reset string without a warning - if ( !var->resetString[0] ) { - // we don't have a reset string yet - Z_Free( var->resetString ); - var->resetString = CopyString( var_value ); - } else if ( var_value[0] && strcmp( var->resetString, var_value ) ) { - Com_DPrintf( "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", - var_name, var->resetString, var_value ); - } - // if we have a latched string, take that value now - if ( var->latchedString ) { - char *s; - - s = var->latchedString; - var->latchedString = NULL; // otherwise cvar_set2 would free it - Cvar_Set2( var_name, s, qtrue ); - 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; - } - - // - // allocate a new cvar - // - if ( cvar_numIndexes >= MAX_CVARS ) { - Com_Error( ERR_FATAL, "MAX_CVARS" ); - } - var = &cvar_indexes[cvar_numIndexes]; - cvar_numIndexes++; - var->name = CopyString (var_name); - var->string = CopyString (var_value); - var->modified = qtrue; - var->modificationCount = 1; - var->value = atof (var->string); - var->integer = atoi(var->string); - var->resetString = CopyString( var_value ); - - // link the variable in - var->next = cvar_vars; - cvar_vars = var; - - var->flags = flags; - - hash = generateHashValue(var_name); - var->hashNext = hashTable[hash]; - hashTable[hash] = var; - - return var; -} - -/* -============ -Cvar_Set2 -============ -*/ -cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { - cvar_t *var; - - Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value ); - - if ( !Cvar_ValidateString( var_name ) ) { - Com_Printf("invalid cvar name string: %s\n", var_name ); - var_name = "BADNAME"; - } - -#if 0 // FIXME - if ( value && !Cvar_ValidateString( value ) ) { - Com_Printf("invalid cvar value string: %s\n", value ); - var_value = "BADVALUE"; - } -#endif - - var = Cvar_FindVar (var_name); - if (!var) { - if ( !value ) { - return NULL; - } - // create it - if ( !force ) { - return Cvar_Get( var_name, value, CVAR_USER_CREATED ); - } else { - return Cvar_Get (var_name, value, 0); - } - } - - if (!value ) { - value = var->resetString; - } - - if (!strcmp(value,var->string)) { - return var; - } - // note what types of cvars have been modified (userinfo, archive, serverinfo, systeminfo) - cvar_modifiedFlags |= var->flags; - - if (!force) - { - if (var->flags & CVAR_ROM) - { - Com_Printf ("%s is read only.\n", var_name); - return var; - } - - if (var->flags & CVAR_INIT) - { - Com_Printf ("%s is write protected.\n", var_name); - return var; - } - - if (var->flags & CVAR_LATCH) - { - if (var->latchedString) - { - if (strcmp(value, var->latchedString) == 0) - return var; - Z_Free (var->latchedString); - } - else - { - if (strcmp(value, var->string) == 0) - return var; - } - - Com_Printf ("%s will be changed upon restarting.\n", var_name); - var->latchedString = CopyString(value); - var->modified = qtrue; - var->modificationCount++; - return var; - } - - if ( (var->flags & CVAR_CHEAT) && !cvar_cheats->integer ) - { - Com_Printf ("%s is cheat protected.\n", var_name); - return var; - } - - } - else - { - if (var->latchedString) - { - Z_Free (var->latchedString); - var->latchedString = NULL; - } - } - - if (!strcmp(value, var->string)) - return var; // not changed - - var->modified = qtrue; - var->modificationCount++; - - Z_Free (var->string); // free the old value string - - var->string = CopyString(value); - var->value = atof (var->string); - var->integer = atoi (var->string); - - return var; -} - -/* -============ -Cvar_Set -============ -*/ -void Cvar_Set( const char *var_name, const char *value) { - Cvar_Set2 (var_name, value, qtrue); -} - -/* -============ -Cvar_SetLatched -============ -*/ -void Cvar_SetLatched( const char *var_name, const char *value) { - Cvar_Set2 (var_name, value, qfalse); -} - -/* -============ -Cvar_SetValue -============ -*/ -void Cvar_SetValue( const char *var_name, float value) { - char val[32]; - - if ( value == (int)value ) { - Com_sprintf (val, sizeof(val), "%i",(int)value); - } else { - Com_sprintf (val, sizeof(val), "%f",value); - } - Cvar_Set (var_name, val); -} - - -/* -============ -Cvar_Reset -============ -*/ -void Cvar_Reset( const char *var_name ) { - Cvar_Set2( var_name, NULL, qfalse ); -} - - -/* -============ -Cvar_SetCheatState - -Any testing variables will be reset to the safe values -============ -*/ -void Cvar_SetCheatState( void ) { - cvar_t *var; - - // set all default vars to the safe value - for ( var = cvar_vars ; var ; var = var->next ) { - if ( var->flags & CVAR_CHEAT ) { - // the CVAR_LATCHED|CVAR_CHEAT vars might escape the reset here - // because of a different var->latchedString - if (var->latchedString) - { - Z_Free(var->latchedString); - var->latchedString = NULL; - } - if (strcmp(var->resetString,var->string)) { - Cvar_Set( var->name, var->resetString ); - } - } - } -} - -/* -============ -Cvar_Command - -Handles variable inspection and changing from the console -============ -*/ -qboolean Cvar_Command( void ) { - cvar_t *v; - - // check variables - v = Cvar_FindVar (Cmd_Argv(0)); - if (!v) { - return qfalse; - } - - // perform a variable print or set - if ( Cmd_Argc() == 1 ) { - Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n", v->name, v->string, v->resetString ); - if ( v->latchedString ) { - Com_Printf( "latched: \"%s\"\n", v->latchedString ); - } - return qtrue; - } - - // set the value if forcing isn't required - Cvar_Set2 (v->name, Cmd_Argv(1), qfalse); - return qtrue; -} - - -/* -============ -Cvar_Toggle_f - -Toggles a cvar for easy single key binding -============ -*/ -void Cvar_Toggle_f( void ) { - int v; - - if ( Cmd_Argc() != 2 ) { - Com_Printf ("usage: toggle \n"); - return; - } - - v = Cvar_VariableValue( Cmd_Argv( 1 ) ); - v = !v; - - Cvar_Set2 (Cmd_Argv(1), va("%i", v), qfalse); -} - -/* -============ -Cvar_Set_f - -Allows setting and defining of arbitrary cvars from console, even if they -weren't declared in C code. -============ -*/ -void Cvar_Set_f( void ) { - int i, c, l, len; - char combined[MAX_STRING_TOKENS]; - - c = Cmd_Argc(); - if ( c < 3 ) { - Com_Printf ("usage: set \n"); - return; - } - - combined[0] = 0; - l = 0; - for ( i = 2 ; i < c ; i++ ) { - len = strlen ( Cmd_Argv( i ) + 1 ); - if ( l + len >= MAX_STRING_TOKENS - 2 ) { - break; - } - strcat( combined, Cmd_Argv( i ) ); - if ( i != c-1 ) { - strcat( combined, " " ); - } - 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 \n"); - return; - } - Cvar_Set_f(); - v = Cvar_FindVar( Cmd_Argv( 1 ) ); - 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 \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 \n"); - return; - } - Cvar_Set_f(); - v = Cvar_FindVar( Cmd_Argv( 1 ) ); - if ( !v ) { - return; - } - v->flags |= CVAR_ARCHIVE; -} - -/* -============ -Cvar_Reset_f -============ -*/ -void Cvar_Reset_f( void ) { - if ( Cmd_Argc() != 2 ) { - Com_Printf ("usage: reset \n"); - return; - } - Cvar_Reset( Cmd_Argv( 1 ) ); -} - -/* -============ -Cvar_WriteVariables - -Appends lines containing "set variable value" for all variables -with the archive flag set to qtrue. -============ -*/ -void Cvar_WriteVariables( fileHandle_t f ) { - cvar_t *var; - char buffer[1024]; - - for (var = cvar_vars ; var ; var = var->next) { - if( Q_stricmp( var->name, "cl_cdkey" ) == 0 ) { - continue; - } - if( var->flags & CVAR_ARCHIVE ) { - // write the latched value, even if it hasn't taken effect yet - if ( var->latchedString ) { - Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->latchedString); - } else { - Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->string); - } - FS_Printf (f, "%s", buffer); - } - } -} - -/* -============ -Cvar_List_f -============ -*/ -void Cvar_List_f( void ) { - cvar_t *var; - int i; - char *match; - - if ( Cmd_Argc() > 1 ) { - match = Cmd_Argv( 1 ); - } else { - match = NULL; - } - - i = 0; - for (var = cvar_vars ; var ; var = var->next, i++) - { - if (match && !Com_Filter(match, var->name, qfalse)) continue; - - if (var->flags & CVAR_SERVERINFO) { - Com_Printf("S"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_USERINFO) { - Com_Printf("U"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_ROM) { - Com_Printf("R"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_INIT) { - Com_Printf("I"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_ARCHIVE) { - Com_Printf("A"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_LATCH) { - Com_Printf("L"); - } else { - Com_Printf(" "); - } - if (var->flags & CVAR_CHEAT) { - Com_Printf("C"); - } else { - Com_Printf(" "); - } - - Com_Printf (" %s \"%s\"\n", var->name, var->string); - } - - Com_Printf ("\n%i total cvars\n", i); - Com_Printf ("%i cvar indexes\n", cvar_numIndexes); -} - -/* -============ -Cvar_Restart_f - -Resets all cvars to their hardcoded values -============ -*/ -void Cvar_Restart_f( void ) { - cvar_t *var; - cvar_t **prev; - - prev = &cvar_vars; - while ( 1 ) { - var = *prev; - if ( !var ) { - break; - } - - // don't mess with rom values, or some inter-module - // communication will get broken (com_cl_running, etc) - if ( var->flags & ( CVAR_ROM | CVAR_INIT | CVAR_NORESTART ) ) { - prev = &var->next; - continue; - } - - // throw out any variables the user created - if ( var->flags & CVAR_USER_CREATED ) { - *prev = var->next; - if ( var->name ) { - Z_Free( var->name ); - } - if ( var->string ) { - Z_Free( var->string ); - } - if ( var->latchedString ) { - Z_Free( var->latchedString ); - } - if ( var->resetString ) { - Z_Free( var->resetString ); - } - // clear the var completely, since we - // can't remove the index from the list - Com_Memset( var, 0, sizeof( var ) ); - continue; - } - - Cvar_Set( var->name, var->resetString ); - - prev = &var->next; - } -} - - - -/* -===================== -Cvar_InfoString -===================== -*/ -char *Cvar_InfoString( int bit ) { - static char info[MAX_INFO_STRING]; - cvar_t *var; - - info[0] = 0; - - for (var = cvar_vars ; var ; var = var->next) { - if (var->flags & bit) { - Info_SetValueForKey (info, var->name, var->string); - } - } - return info; -} - -/* -===================== -Cvar_InfoString_Big - - handles large info strings ( CS_SYSTEMINFO ) -===================== -*/ -char *Cvar_InfoString_Big( int bit ) { - static char info[BIG_INFO_STRING]; - cvar_t *var; - - info[0] = 0; - - for (var = cvar_vars ; var ; var = var->next) { - if (var->flags & bit) { - Info_SetValueForKey_Big (info, var->name, var->string); - } - } - return info; -} - - - -/* -===================== -Cvar_InfoStringBuffer -===================== -*/ -void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) { - Q_strncpyz(buff,Cvar_InfoString(bit),buffsize); -} - -/* -===================== -Cvar_Register - -basically a slightly modified Cvar_Get for the interpreted modules -===================== -*/ -void Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) { - cvar_t *cv; - - cv = Cvar_Get( varName, defaultValue, flags ); - if ( !vmCvar ) { - return; - } - vmCvar->handle = cv - cvar_indexes; - vmCvar->modificationCount = -1; - Cvar_Update( vmCvar ); -} - - -/* -===================== -Cvar_Register - -updates an interpreted modules' version of a cvar -===================== -*/ -void Cvar_Update( vmCvar_t *vmCvar ) { - cvar_t *cv = NULL; // bk001129 - assert(vmCvar); // bk - - if ( (unsigned)vmCvar->handle >= cvar_numIndexes ) { - Com_Error( ERR_DROP, "Cvar_Update: handle out of range" ); - } - - cv = cvar_indexes + vmCvar->handle; - - if ( cv->modificationCount == vmCvar->modificationCount ) { - return; - } - if ( !cv->string ) { - return; // variable might have been cleared by a cvar_restart - } - vmCvar->modificationCount = cv->modificationCount; - // bk001129 - mismatches. - if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING ) - Com_Error( ERR_DROP, "Cvar_Update: src %s length %d exceeds MAX_CVAR_VALUE_STRING", - cv->string, - strlen(cv->string), - sizeof(vmCvar->string) ); - // bk001212 - Q_strncpyz guarantees zero padding and dest[MAX_CVAR_VALUE_STRING-1]==0 - // bk001129 - paranoia. Never trust the destination string. - // bk001129 - beware, sizeof(char*) is always 4 (for cv->string). - // sizeof(vmCvar->string) always MAX_CVAR_VALUE_STRING - //Q_strncpyz( vmCvar->string, cv->string, sizeof( vmCvar->string ) ); // id - Q_strncpyz( vmCvar->string, cv->string, MAX_CVAR_VALUE_STRING ); - - vmCvar->value = cv->value; - vmCvar->integer = cv->integer; -} - - -/* -============ -Cvar_Init - -Reads in all archived cvars -============ -*/ -void Cvar_Init (void) { - cvar_cheats = Cvar_Get("sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO ); - - 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 ("reset", Cvar_Reset_f); - Cmd_AddCommand ("cvarlist", Cvar_List_f); - Cmd_AddCommand ("cvar_restart", Cvar_Restart_f); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// cvar.c -- dynamic variable tracking + +#include "../game/q_shared.h" +#include "qcommon.h" + +cvar_t *cvar_vars; +cvar_t *cvar_cheats; +int cvar_modifiedFlags; + +#define MAX_CVARS 1024 +cvar_t cvar_indexes[MAX_CVARS]; +int cvar_numIndexes; + +#define FILE_HASH_SIZE 256 +static cvar_t* hashTable[FILE_HASH_SIZE]; + +cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force); + +/* +================ +return a hash value for the filename +================ +*/ +static long generateHashValue( const char *fname ) { + int i; + long hash; + char letter; + + hash = 0; + i = 0; + while (fname[i] != '\0') { + letter = tolower(fname[i]); + hash+=(long)(letter)*(i+119); + i++; + } + hash &= (FILE_HASH_SIZE-1); + return hash; +} + +/* +============ +Cvar_ValidateString +============ +*/ +static qboolean Cvar_ValidateString( const char *s ) { + if ( !s ) { + return qfalse; + } + if ( strchr( s, '\\' ) ) { + return qfalse; + } + if ( strchr( s, '\"' ) ) { + return qfalse; + } + if ( strchr( s, ';' ) ) { + return qfalse; + } + return qtrue; +} + +/* +============ +Cvar_FindVar +============ +*/ +static cvar_t *Cvar_FindVar( const char *var_name ) { + cvar_t *var; + long hash; + + hash = generateHashValue(var_name); + + for (var=hashTable[hash] ; var ; var=var->hashNext) { + if (!Q_stricmp(var_name, var->name)) { + return var; + } + } + + return NULL; +} + +/* +============ +Cvar_VariableValue +============ +*/ +float Cvar_VariableValue( const char *var_name ) { + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return 0; + return var->value; +} + + +/* +============ +Cvar_VariableIntegerValue +============ +*/ +int Cvar_VariableIntegerValue( const char *var_name ) { + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return 0; + return var->integer; +} + + +/* +============ +Cvar_VariableString +============ +*/ +char *Cvar_VariableString( const char *var_name ) { + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return ""; + return var->string; +} + + +/* +============ +Cvar_VariableStringBuffer +============ +*/ +void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) { + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) { + *buffer = 0; + } + else { + Q_strncpyz( buffer, var->string, bufsize ); + } +} + + +/* +============ +Cvar_CommandCompletion +============ +*/ +void Cvar_CommandCompletion( void(*callback)(const char *s) ) { + cvar_t *cvar; + + for ( cvar = cvar_vars ; cvar ; cvar = cvar->next ) { + callback( cvar->name ); + } +} + + +/* +============ +Cvar_Get + +If the variable already exists, the value will not be set unless CVAR_ROM +The flags will be or'ed in if the variable exists. +============ +*/ +cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) { + cvar_t *var; + long hash; + + if ( !var_name || ! var_value ) { + Com_Error( ERR_FATAL, "Cvar_Get: NULL parameter" ); + } + + if ( !Cvar_ValidateString( var_name ) ) { + Com_Printf("invalid cvar name string: %s\n", var_name ); + var_name = "BADNAME"; + } + +#if 0 // FIXME: values with backslash happen + if ( !Cvar_ValidateString( var_value ) ) { + Com_Printf("invalid cvar value string: %s\n", var_value ); + var_value = "BADVALUE"; + } +#endif + + var = Cvar_FindVar (var_name); + if ( var ) { + // 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 ) + && var_value[0] ) { + var->flags &= ~CVAR_USER_CREATED; + Z_Free( var->resetString ); + var->resetString = CopyString( var_value ); + + // ZOID--needs to be set so that cvars the game sets as + // SERVERINFO get sent to clients + cvar_modifiedFlags |= flags; + } + + var->flags |= flags; + // only allow one non-empty reset string without a warning + if ( !var->resetString[0] ) { + // we don't have a reset string yet + Z_Free( var->resetString ); + var->resetString = CopyString( var_value ); + } else if ( var_value[0] && strcmp( var->resetString, var_value ) ) { + Com_DPrintf( "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", + var_name, var->resetString, var_value ); + } + // if we have a latched string, take that value now + if ( var->latchedString ) { + char *s; + + s = var->latchedString; + var->latchedString = NULL; // otherwise cvar_set2 would free it + Cvar_Set2( var_name, s, qtrue ); + 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; + } + + // + // allocate a new cvar + // + if ( cvar_numIndexes >= MAX_CVARS ) { + Com_Error( ERR_FATAL, "MAX_CVARS" ); + } + var = &cvar_indexes[cvar_numIndexes]; + cvar_numIndexes++; + var->name = CopyString (var_name); + var->string = CopyString (var_value); + var->modified = qtrue; + var->modificationCount = 1; + var->value = atof (var->string); + var->integer = atoi(var->string); + var->resetString = CopyString( var_value ); + + // link the variable in + var->next = cvar_vars; + cvar_vars = var; + + var->flags = flags; + + hash = generateHashValue(var_name); + var->hashNext = hashTable[hash]; + hashTable[hash] = var; + + return var; +} + +/* +============ +Cvar_Set2 +============ +*/ +cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { + cvar_t *var; + + Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value ); + + if ( !Cvar_ValidateString( var_name ) ) { + Com_Printf("invalid cvar name string: %s\n", var_name ); + var_name = "BADNAME"; + } + +#if 0 // FIXME + if ( value && !Cvar_ValidateString( value ) ) { + Com_Printf("invalid cvar value string: %s\n", value ); + var_value = "BADVALUE"; + } +#endif + + var = Cvar_FindVar (var_name); + if (!var) { + if ( !value ) { + return NULL; + } + // create it + if ( !force ) { + return Cvar_Get( var_name, value, CVAR_USER_CREATED ); + } else { + return Cvar_Get (var_name, value, 0); + } + } + + if (!value ) { + value = var->resetString; + } + + if (!strcmp(value,var->string)) { + return var; + } + // note what types of cvars have been modified (userinfo, archive, serverinfo, systeminfo) + cvar_modifiedFlags |= var->flags; + + if (!force) + { + if (var->flags & CVAR_ROM) + { + Com_Printf ("%s is read only.\n", var_name); + return var; + } + + if (var->flags & CVAR_INIT) + { + Com_Printf ("%s is write protected.\n", var_name); + return var; + } + + if (var->flags & CVAR_LATCH) + { + if (var->latchedString) + { + if (strcmp(value, var->latchedString) == 0) + return var; + Z_Free (var->latchedString); + } + else + { + if (strcmp(value, var->string) == 0) + return var; + } + + Com_Printf ("%s will be changed upon restarting.\n", var_name); + var->latchedString = CopyString(value); + var->modified = qtrue; + var->modificationCount++; + return var; + } + + if ( (var->flags & CVAR_CHEAT) && !cvar_cheats->integer ) + { + Com_Printf ("%s is cheat protected.\n", var_name); + return var; + } + + } + else + { + if (var->latchedString) + { + Z_Free (var->latchedString); + var->latchedString = NULL; + } + } + + if (!strcmp(value, var->string)) + return var; // not changed + + var->modified = qtrue; + var->modificationCount++; + + Z_Free (var->string); // free the old value string + + var->string = CopyString(value); + var->value = atof (var->string); + var->integer = atoi (var->string); + + return var; +} + +/* +============ +Cvar_Set +============ +*/ +void Cvar_Set( const char *var_name, const char *value) { + Cvar_Set2 (var_name, value, qtrue); +} + +/* +============ +Cvar_SetLatched +============ +*/ +void Cvar_SetLatched( const char *var_name, const char *value) { + Cvar_Set2 (var_name, value, qfalse); +} + +/* +============ +Cvar_SetValue +============ +*/ +void Cvar_SetValue( const char *var_name, float value) { + char val[32]; + + if ( value == (int)value ) { + Com_sprintf (val, sizeof(val), "%i",(int)value); + } else { + Com_sprintf (val, sizeof(val), "%f",value); + } + Cvar_Set (var_name, val); +} + + +/* +============ +Cvar_Reset +============ +*/ +void Cvar_Reset( const char *var_name ) { + Cvar_Set2( var_name, NULL, qfalse ); +} + + +/* +============ +Cvar_SetCheatState + +Any testing variables will be reset to the safe values +============ +*/ +void Cvar_SetCheatState( void ) { + cvar_t *var; + + // set all default vars to the safe value + for ( var = cvar_vars ; var ; var = var->next ) { + if ( var->flags & CVAR_CHEAT ) { + // the CVAR_LATCHED|CVAR_CHEAT vars might escape the reset here + // because of a different var->latchedString + if (var->latchedString) + { + Z_Free(var->latchedString); + var->latchedString = NULL; + } + if (strcmp(var->resetString,var->string)) { + Cvar_Set( var->name, var->resetString ); + } + } + } +} + +/* +============ +Cvar_Command + +Handles variable inspection and changing from the console +============ +*/ +qboolean Cvar_Command( void ) { + cvar_t *v; + + // check variables + v = Cvar_FindVar (Cmd_Argv(0)); + if (!v) { + return qfalse; + } + + // perform a variable print or set + if ( Cmd_Argc() == 1 ) { + Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n", v->name, v->string, v->resetString ); + if ( v->latchedString ) { + Com_Printf( "latched: \"%s\"\n", v->latchedString ); + } + return qtrue; + } + + // set the value if forcing isn't required + Cvar_Set2 (v->name, Cmd_Argv(1), qfalse); + return qtrue; +} + + +/* +============ +Cvar_Toggle_f + +Toggles a cvar for easy single key binding +============ +*/ +void Cvar_Toggle_f( void ) { + int v; + + if ( Cmd_Argc() != 2 ) { + Com_Printf ("usage: toggle \n"); + return; + } + + v = Cvar_VariableValue( Cmd_Argv( 1 ) ); + v = !v; + + Cvar_Set2 (Cmd_Argv(1), va("%i", v), qfalse); +} + +/* +============ +Cvar_Set_f + +Allows setting and defining of arbitrary cvars from console, even if they +weren't declared in C code. +============ +*/ +void Cvar_Set_f( void ) { + int i, c, l, len; + char combined[MAX_STRING_TOKENS]; + + c = Cmd_Argc(); + if ( c < 3 ) { + Com_Printf ("usage: set \n"); + return; + } + + combined[0] = 0; + l = 0; + for ( i = 2 ; i < c ; i++ ) { + len = strlen ( Cmd_Argv( i ) + 1 ); + if ( l + len >= MAX_STRING_TOKENS - 2 ) { + break; + } + strcat( combined, Cmd_Argv( i ) ); + if ( i != c-1 ) { + strcat( combined, " " ); + } + 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 \n"); + return; + } + Cvar_Set_f(); + v = Cvar_FindVar( Cmd_Argv( 1 ) ); + 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 \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 \n"); + return; + } + Cvar_Set_f(); + v = Cvar_FindVar( Cmd_Argv( 1 ) ); + if ( !v ) { + return; + } + v->flags |= CVAR_ARCHIVE; +} + +/* +============ +Cvar_Reset_f +============ +*/ +void Cvar_Reset_f( void ) { + if ( Cmd_Argc() != 2 ) { + Com_Printf ("usage: reset \n"); + return; + } + Cvar_Reset( Cmd_Argv( 1 ) ); +} + +/* +============ +Cvar_WriteVariables + +Appends lines containing "set variable value" for all variables +with the archive flag set to qtrue. +============ +*/ +void Cvar_WriteVariables( fileHandle_t f ) { + cvar_t *var; + char buffer[1024]; + + for (var = cvar_vars ; var ; var = var->next) { + if( Q_stricmp( var->name, "cl_cdkey" ) == 0 ) { + continue; + } + if( var->flags & CVAR_ARCHIVE ) { + // write the latched value, even if it hasn't taken effect yet + if ( var->latchedString ) { + Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->latchedString); + } else { + Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->string); + } + FS_Printf (f, "%s", buffer); + } + } +} + +/* +============ +Cvar_List_f +============ +*/ +void Cvar_List_f( void ) { + cvar_t *var; + int i; + char *match; + + if ( Cmd_Argc() > 1 ) { + match = Cmd_Argv( 1 ); + } else { + match = NULL; + } + + i = 0; + for (var = cvar_vars ; var ; var = var->next, i++) + { + if (match && !Com_Filter(match, var->name, qfalse)) continue; + + if (var->flags & CVAR_SERVERINFO) { + Com_Printf("S"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_USERINFO) { + Com_Printf("U"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_ROM) { + Com_Printf("R"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_INIT) { + Com_Printf("I"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_ARCHIVE) { + Com_Printf("A"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_LATCH) { + Com_Printf("L"); + } else { + Com_Printf(" "); + } + if (var->flags & CVAR_CHEAT) { + Com_Printf("C"); + } else { + Com_Printf(" "); + } + + Com_Printf (" %s \"%s\"\n", var->name, var->string); + } + + Com_Printf ("\n%i total cvars\n", i); + Com_Printf ("%i cvar indexes\n", cvar_numIndexes); +} + +/* +============ +Cvar_Restart_f + +Resets all cvars to their hardcoded values +============ +*/ +void Cvar_Restart_f( void ) { + cvar_t *var; + cvar_t **prev; + + prev = &cvar_vars; + while ( 1 ) { + var = *prev; + if ( !var ) { + break; + } + + // don't mess with rom values, or some inter-module + // communication will get broken (com_cl_running, etc) + if ( var->flags & ( CVAR_ROM | CVAR_INIT | CVAR_NORESTART ) ) { + prev = &var->next; + continue; + } + + // throw out any variables the user created + if ( var->flags & CVAR_USER_CREATED ) { + *prev = var->next; + if ( var->name ) { + Z_Free( var->name ); + } + if ( var->string ) { + Z_Free( var->string ); + } + if ( var->latchedString ) { + Z_Free( var->latchedString ); + } + if ( var->resetString ) { + Z_Free( var->resetString ); + } + // clear the var completely, since we + // can't remove the index from the list + Com_Memset( var, 0, sizeof( var ) ); + continue; + } + + Cvar_Set( var->name, var->resetString ); + + prev = &var->next; + } +} + + + +/* +===================== +Cvar_InfoString +===================== +*/ +char *Cvar_InfoString( int bit ) { + static char info[MAX_INFO_STRING]; + cvar_t *var; + + info[0] = 0; + + for (var = cvar_vars ; var ; var = var->next) { + if (var->flags & bit) { + Info_SetValueForKey (info, var->name, var->string); + } + } + return info; +} + +/* +===================== +Cvar_InfoString_Big + + handles large info strings ( CS_SYSTEMINFO ) +===================== +*/ +char *Cvar_InfoString_Big( int bit ) { + static char info[BIG_INFO_STRING]; + cvar_t *var; + + info[0] = 0; + + for (var = cvar_vars ; var ; var = var->next) { + if (var->flags & bit) { + Info_SetValueForKey_Big (info, var->name, var->string); + } + } + return info; +} + + + +/* +===================== +Cvar_InfoStringBuffer +===================== +*/ +void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) { + Q_strncpyz(buff,Cvar_InfoString(bit),buffsize); +} + +/* +===================== +Cvar_Register + +basically a slightly modified Cvar_Get for the interpreted modules +===================== +*/ +void Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) { + cvar_t *cv; + + cv = Cvar_Get( varName, defaultValue, flags ); + if ( !vmCvar ) { + return; + } + vmCvar->handle = cv - cvar_indexes; + vmCvar->modificationCount = -1; + Cvar_Update( vmCvar ); +} + + +/* +===================== +Cvar_Register + +updates an interpreted modules' version of a cvar +===================== +*/ +void Cvar_Update( vmCvar_t *vmCvar ) { + cvar_t *cv = NULL; // bk001129 + assert(vmCvar); // bk + + if ( (unsigned)vmCvar->handle >= cvar_numIndexes ) { + Com_Error( ERR_DROP, "Cvar_Update: handle out of range" ); + } + + cv = cvar_indexes + vmCvar->handle; + + if ( cv->modificationCount == vmCvar->modificationCount ) { + return; + } + if ( !cv->string ) { + return; // variable might have been cleared by a cvar_restart + } + vmCvar->modificationCount = cv->modificationCount; + // bk001129 - mismatches. + if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING ) + Com_Error( ERR_DROP, "Cvar_Update: src %s length %d exceeds MAX_CVAR_VALUE_STRING", + cv->string, + strlen(cv->string), + sizeof(vmCvar->string) ); + // bk001212 - Q_strncpyz guarantees zero padding and dest[MAX_CVAR_VALUE_STRING-1]==0 + // bk001129 - paranoia. Never trust the destination string. + // bk001129 - beware, sizeof(char*) is always 4 (for cv->string). + // sizeof(vmCvar->string) always MAX_CVAR_VALUE_STRING + //Q_strncpyz( vmCvar->string, cv->string, sizeof( vmCvar->string ) ); // id + Q_strncpyz( vmCvar->string, cv->string, MAX_CVAR_VALUE_STRING ); + + vmCvar->value = cv->value; + vmCvar->integer = cv->integer; +} + + +/* +============ +Cvar_Init + +Reads in all archived cvars +============ +*/ +void Cvar_Init (void) { + cvar_cheats = Cvar_Get("sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO ); + + 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 ("reset", Cvar_Reset_f); + Cmd_AddCommand ("cvarlist", Cvar_List_f); + Cmd_AddCommand ("cvar_restart", Cvar_Restart_f); +} -- cgit v1.2.3