Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

cvar.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 // cvar.c -- dynamic variable tracking
00023 
00024 #include "../game/q_shared.h"
00025 #include "qcommon.h"
00026 
00027 cvar_t      *cvar_vars;
00028 cvar_t      *cvar_cheats;
00029 int         cvar_modifiedFlags;
00030 
00031 #define MAX_CVARS   1024
00032 cvar_t      cvar_indexes[MAX_CVARS];
00033 int         cvar_numIndexes;
00034 
00035 #define FILE_HASH_SIZE      256
00036 static  cvar_t*     hashTable[FILE_HASH_SIZE];
00037 
00038 cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force);
00039 
00040 /*
00041 ================
00042 return a hash value for the filename
00043 ================
00044 */
00045 static long generateHashValue( const char *fname ) {
00046     int     i;
00047     long    hash;
00048     char    letter;
00049 
00050     hash = 0;
00051     i = 0;
00052     while (fname[i] != '\0') {
00053         letter = tolower(fname[i]);
00054         hash+=(long)(letter)*(i+119);
00055         i++;
00056     }
00057     hash &= (FILE_HASH_SIZE-1);
00058     return hash;
00059 }
00060 
00061 /*
00062 ============
00063 Cvar_ValidateString
00064 ============
00065 */
00066 static qboolean Cvar_ValidateString( const char *s ) {
00067     if ( !s ) {
00068         return qfalse;
00069     }
00070     if ( strchr( s, '\\' ) ) {
00071         return qfalse;
00072     }
00073     if ( strchr( s, '\"' ) ) {
00074         return qfalse;
00075     }
00076     if ( strchr( s, ';' ) ) {
00077         return qfalse;
00078     }
00079     return qtrue;
00080 }
00081 
00082 /*
00083 ============
00084 Cvar_FindVar
00085 ============
00086 */
00087 static cvar_t *Cvar_FindVar( const char *var_name ) {
00088     cvar_t  *var;
00089     long hash;
00090 
00091     hash = generateHashValue(var_name);
00092     
00093     for (var=hashTable[hash] ; var ; var=var->hashNext) {
00094         if (!Q_stricmp(var_name, var->name)) {
00095             return var;
00096         }
00097     }
00098 
00099     return NULL;
00100 }
00101 
00102 /*
00103 ============
00104 Cvar_VariableValue
00105 ============
00106 */
00107 float Cvar_VariableValue( const char *var_name ) {
00108     cvar_t  *var;
00109     
00110     var = Cvar_FindVar (var_name);
00111     if (!var)
00112         return 0;
00113     return var->value;
00114 }
00115 
00116 
00117 /*
00118 ============
00119 Cvar_VariableIntegerValue
00120 ============
00121 */
00122 int Cvar_VariableIntegerValue( const char *var_name ) {
00123     cvar_t  *var;
00124     
00125     var = Cvar_FindVar (var_name);
00126     if (!var)
00127         return 0;
00128     return var->integer;
00129 }
00130 
00131 
00132 /*
00133 ============
00134 Cvar_VariableString
00135 ============
00136 */
00137 char *Cvar_VariableString( const char *var_name ) {
00138     cvar_t *var;
00139     
00140     var = Cvar_FindVar (var_name);
00141     if (!var)
00142         return "";
00143     return var->string;
00144 }
00145 
00146 
00147 /*
00148 ============
00149 Cvar_VariableStringBuffer
00150 ============
00151 */
00152 void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) {
00153     cvar_t *var;
00154     
00155     var = Cvar_FindVar (var_name);
00156     if (!var) {
00157         *buffer = 0;
00158     }
00159     else {
00160         Q_strncpyz( buffer, var->string, bufsize );
00161     }
00162 }
00163 
00164 
00165 /*
00166 ============
00167 Cvar_CommandCompletion
00168 ============
00169 */
00170 void    Cvar_CommandCompletion( void(*callback)(const char *s) ) {
00171     cvar_t      *cvar;
00172     
00173     for ( cvar = cvar_vars ; cvar ; cvar = cvar->next ) {
00174         callback( cvar->name );
00175     }
00176 }
00177 
00178 
00179 /*
00180 ============
00181 Cvar_Get
00182 
00183 If the variable already exists, the value will not be set unless CVAR_ROM
00184 The flags will be or'ed in if the variable exists.
00185 ============
00186 */
00187 cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
00188     cvar_t  *var;
00189     long    hash;
00190 
00191   if ( !var_name || ! var_value ) {
00192         Com_Error( ERR_FATAL, "Cvar_Get: NULL parameter" );
00193   }
00194 
00195     if ( !Cvar_ValidateString( var_name ) ) {
00196         Com_Printf("invalid cvar name string: %s\n", var_name );
00197         var_name = "BADNAME";
00198     }
00199 
00200 #if 0       // FIXME: values with backslash happen
00201     if ( !Cvar_ValidateString( var_value ) ) {
00202         Com_Printf("invalid cvar value string: %s\n", var_value );
00203         var_value = "BADVALUE";
00204     }
00205 #endif
00206 
00207     var = Cvar_FindVar (var_name);
00208     if ( var ) {
00209         // if the C code is now specifying a variable that the user already
00210         // set a value for, take the new value as the reset value
00211         if ( ( var->flags & CVAR_USER_CREATED ) && !( flags & CVAR_USER_CREATED )
00212             && var_value[0] ) {
00213             var->flags &= ~CVAR_USER_CREATED;
00214             Z_Free( var->resetString );
00215             var->resetString = CopyString( var_value );
00216 
00217             // ZOID--needs to be set so that cvars the game sets as 
00218             // SERVERINFO get sent to clients
00219             cvar_modifiedFlags |= flags;
00220         }
00221 
00222         var->flags |= flags;
00223         // only allow one non-empty reset string without a warning
00224         if ( !var->resetString[0] ) {
00225             // we don't have a reset string yet
00226             Z_Free( var->resetString );
00227             var->resetString = CopyString( var_value );
00228         } else if ( var_value[0] && strcmp( var->resetString, var_value ) ) {
00229             Com_DPrintf( "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n",
00230                 var_name, var->resetString, var_value );
00231         }
00232         // if we have a latched string, take that value now
00233         if ( var->latchedString ) {
00234             char *s;
00235 
00236             s = var->latchedString;
00237             var->latchedString = NULL;  // otherwise cvar_set2 would free it
00238             Cvar_Set2( var_name, s, qtrue );
00239             Z_Free( s );
00240         }
00241 
00242 // use a CVAR_SET for rom sets, get won't override
00243 #if 0
00244         // CVAR_ROM always overrides
00245         if ( flags & CVAR_ROM ) {
00246             Cvar_Set2( var_name, var_value, qtrue );
00247         }
00248 #endif
00249         return var;
00250     }
00251 
00252     //
00253     // allocate a new cvar
00254     //
00255     if ( cvar_numIndexes >= MAX_CVARS ) {
00256         Com_Error( ERR_FATAL, "MAX_CVARS" );
00257     }
00258     var = &cvar_indexes[cvar_numIndexes];
00259     cvar_numIndexes++;
00260     var->name = CopyString (var_name);
00261     var->string = CopyString (var_value);
00262     var->modified = qtrue;
00263     var->modificationCount = 1;
00264     var->value = atof (var->string);
00265     var->integer = atoi(var->string);
00266     var->resetString = CopyString( var_value );
00267 
00268     // link the variable in
00269     var->next = cvar_vars;
00270     cvar_vars = var;
00271 
00272     var->flags = flags;
00273 
00274     hash = generateHashValue(var_name);
00275     var->hashNext = hashTable[hash];
00276     hashTable[hash] = var;
00277 
00278     return var;
00279 }
00280 
00281 /*
00282 ============
00283 Cvar_Set2
00284 ============
00285 */
00286 cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) {
00287     cvar_t  *var;
00288 
00289     Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value );
00290 
00291     if ( !Cvar_ValidateString( var_name ) ) {
00292         Com_Printf("invalid cvar name string: %s\n", var_name );
00293         var_name = "BADNAME";
00294     }
00295 
00296 #if 0   // FIXME
00297     if ( value && !Cvar_ValidateString( value ) ) {
00298         Com_Printf("invalid cvar value string: %s\n", value );
00299         var_value = "BADVALUE";
00300     }
00301 #endif
00302 
00303     var = Cvar_FindVar (var_name);
00304     if (!var) {
00305         if ( !value ) {
00306             return NULL;
00307         }
00308         // create it
00309         if ( !force ) {
00310             return Cvar_Get( var_name, value, CVAR_USER_CREATED );
00311         } else {
00312             return Cvar_Get (var_name, value, 0);
00313         }
00314     }
00315 
00316     if (!value ) {
00317         value = var->resetString;
00318     }
00319 
00320     if (!strcmp(value,var->string)) {
00321         return var;
00322     }
00323     // note what types of cvars have been modified (userinfo, archive, serverinfo, systeminfo)
00324     cvar_modifiedFlags |= var->flags;
00325 
00326     if (!force)
00327     {
00328         if (var->flags & CVAR_ROM)
00329         {
00330             Com_Printf ("%s is read only.\n", var_name);
00331             return var;
00332         }
00333 
00334         if (var->flags & CVAR_INIT)
00335         {
00336             Com_Printf ("%s is write protected.\n", var_name);
00337             return var;
00338         }
00339 
00340         if (var->flags & CVAR_LATCH)
00341         {
00342             if (var->latchedString)
00343             {
00344                 if (strcmp(value, var->latchedString) == 0)
00345                     return var;
00346                 Z_Free (var->latchedString);
00347             }
00348             else
00349             {
00350                 if (strcmp(value, var->string) == 0)
00351                     return var;
00352             }
00353 
00354             Com_Printf ("%s will be changed upon restarting.\n", var_name);
00355             var->latchedString = CopyString(value);
00356             var->modified = qtrue;
00357             var->modificationCount++;
00358             return var;
00359         }
00360 
00361         if ( (var->flags & CVAR_CHEAT) && !cvar_cheats->integer )
00362         {
00363             Com_Printf ("%s is cheat protected.\n", var_name);
00364             return var;
00365         }
00366 
00367     }
00368     else
00369     {
00370         if (var->latchedString)
00371         {
00372             Z_Free (var->latchedString);
00373             var->latchedString = NULL;
00374         }
00375     }
00376 
00377     if (!strcmp(value, var->string))
00378         return var;     // not changed
00379 
00380     var->modified = qtrue;
00381     var->modificationCount++;
00382     
00383     Z_Free (var->string);   // free the old value string
00384     
00385     var->string = CopyString(value);
00386     var->value = atof (var->string);
00387     var->integer = atoi (var->string);
00388 
00389     return var;
00390 }
00391 
00392 /*
00393 ============
00394 Cvar_Set
00395 ============
00396 */
00397 void Cvar_Set( const char *var_name, const char *value) {
00398     Cvar_Set2 (var_name, value, qtrue);
00399 }
00400 
00401 /*
00402 ============
00403 Cvar_SetLatched
00404 ============
00405 */
00406 void Cvar_SetLatched( const char *var_name, const char *value) {
00407     Cvar_Set2 (var_name, value, qfalse);
00408 }
00409 
00410 /*
00411 ============
00412 Cvar_SetValue
00413 ============
00414 */
00415 void Cvar_SetValue( const char *var_name, float value) {
00416     char    val[32];
00417 
00418     if ( value == (int)value ) {
00419         Com_sprintf (val, sizeof(val), "%i",(int)value);
00420     } else {
00421         Com_sprintf (val, sizeof(val), "%f",value);
00422     }
00423     Cvar_Set (var_name, val);
00424 }
00425 
00426 
00427 /*
00428 ============
00429 Cvar_Reset
00430 ============
00431 */
00432 void Cvar_Reset( const char *var_name ) {
00433     Cvar_Set2( var_name, NULL, qfalse );
00434 }
00435 
00436 
00437 /*
00438 ============
00439 Cvar_SetCheatState
00440 
00441 Any testing variables will be reset to the safe values
00442 ============
00443 */
00444 void Cvar_SetCheatState( void ) {
00445     cvar_t  *var;
00446 
00447     // set all default vars to the safe value
00448     for ( var = cvar_vars ; var ; var = var->next ) {
00449         if ( var->flags & CVAR_CHEAT ) {
00450       // the CVAR_LATCHED|CVAR_CHEAT vars might escape the reset here 
00451       // because of a different var->latchedString
00452       if (var->latchedString)
00453       {
00454         Z_Free(var->latchedString);
00455         var->latchedString = NULL;
00456       }
00457             if (strcmp(var->resetString,var->string)) {
00458         Cvar_Set( var->name, var->resetString );
00459             }
00460         }
00461     }
00462 }
00463 
00464 /*
00465 ============
00466 Cvar_Command
00467 
00468 Handles variable inspection and changing from the console
00469 ============
00470 */
00471 qboolean Cvar_Command( void ) {
00472     cvar_t          *v;
00473 
00474     // check variables
00475     v = Cvar_FindVar (Cmd_Argv(0));
00476     if (!v) {
00477         return qfalse;
00478     }
00479 
00480     // perform a variable print or set
00481     if ( Cmd_Argc() == 1 ) {
00482         Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n", v->name, v->string, v->resetString );
00483         if ( v->latchedString ) {
00484             Com_Printf( "latched: \"%s\"\n", v->latchedString );
00485         }
00486         return qtrue;
00487     }
00488 
00489     // set the value if forcing isn't required
00490     Cvar_Set2 (v->name, Cmd_Argv(1), qfalse);
00491     return qtrue;
00492 }
00493 
00494 
00495 /*
00496 ============
00497 Cvar_Toggle_f
00498 
00499 Toggles a cvar for easy single key binding
00500 ============
00501 */
00502 void Cvar_Toggle_f( void ) {
00503     int     v;
00504 
00505     if ( Cmd_Argc() != 2 ) {
00506         Com_Printf ("usage: toggle <variable>\n");
00507         return;
00508     }
00509 
00510     v = Cvar_VariableValue( Cmd_Argv( 1 ) );
00511     v = !v;
00512 
00513     Cvar_Set2 (Cmd_Argv(1), va("%i", v), qfalse);
00514 }
00515 
00516 /*
00517 ============
00518 Cvar_Set_f
00519 
00520 Allows setting and defining of arbitrary cvars from console, even if they
00521 weren't declared in C code.
00522 ============
00523 */
00524 void Cvar_Set_f( void ) {
00525     int     i, c, l, len;
00526     char    combined[MAX_STRING_TOKENS];
00527 
00528     c = Cmd_Argc();
00529     if ( c < 3 ) {
00530         Com_Printf ("usage: set <variable> <value>\n");
00531         return;
00532     }
00533 
00534     combined[0] = 0;
00535     l = 0;
00536     for ( i = 2 ; i < c ; i++ ) {
00537         len = strlen ( Cmd_Argv( i ) + 1 );
00538         if ( l + len >= MAX_STRING_TOKENS - 2 ) {
00539             break;
00540         }
00541         strcat( combined, Cmd_Argv( i ) );
00542         if ( i != c-1 ) {
00543             strcat( combined, " " );
00544         }
00545         l += len;
00546     }
00547     Cvar_Set2 (Cmd_Argv(1), combined, qfalse);
00548 }
00549 
00550 /*
00551 ============
00552 Cvar_SetU_f
00553 
00554 As Cvar_Set, but also flags it as userinfo
00555 ============
00556 */
00557 void Cvar_SetU_f( void ) {
00558     cvar_t  *v;
00559 
00560     if ( Cmd_Argc() != 3 ) {
00561         Com_Printf ("usage: setu <variable> <value>\n");
00562         return;
00563     }
00564     Cvar_Set_f();
00565     v = Cvar_FindVar( Cmd_Argv( 1 ) );
00566     if ( !v ) {
00567         return;
00568     }
00569     v->flags |= CVAR_USERINFO;
00570 }
00571 
00572 /*
00573 ============
00574 Cvar_SetS_f
00575 
00576 As Cvar_Set, but also flags it as userinfo
00577 ============
00578 */
00579 void Cvar_SetS_f( void ) {
00580     cvar_t  *v;
00581 
00582     if ( Cmd_Argc() != 3 ) {
00583         Com_Printf ("usage: sets <variable> <value>\n");
00584         return;
00585     }
00586     Cvar_Set_f();
00587     v = Cvar_FindVar( Cmd_Argv( 1 ) );
00588     if ( !v ) {
00589         return;
00590     }
00591     v->flags |= CVAR_SERVERINFO;
00592 }
00593 
00594 /*
00595 ============
00596 Cvar_SetA_f
00597 
00598 As Cvar_Set, but also flags it as archived
00599 ============
00600 */
00601 void Cvar_SetA_f( void ) {
00602     cvar_t  *v;
00603 
00604     if ( Cmd_Argc() != 3 ) {
00605         Com_Printf ("usage: seta <variable> <value>\n");
00606         return;
00607     }
00608     Cvar_Set_f();
00609     v = Cvar_FindVar( Cmd_Argv( 1 ) );
00610     if ( !v ) {
00611         return;
00612     }
00613     v->flags |= CVAR_ARCHIVE;
00614 }
00615 
00616 /*
00617 ============
00618 Cvar_Reset_f
00619 ============
00620 */
00621 void Cvar_Reset_f( void ) {
00622     if ( Cmd_Argc() != 2 ) {
00623         Com_Printf ("usage: reset <variable>\n");
00624         return;
00625     }
00626     Cvar_Reset( Cmd_Argv( 1 ) );
00627 }
00628 
00629 /*
00630 ============
00631 Cvar_WriteVariables
00632 
00633 Appends lines containing "set variable value" for all variables
00634 with the archive flag set to qtrue.
00635 ============
00636 */
00637 void Cvar_WriteVariables( fileHandle_t f ) {
00638     cvar_t  *var;
00639     char    buffer[1024];
00640 
00641     for (var = cvar_vars ; var ; var = var->next) {
00642         if( Q_stricmp( var->name, "cl_cdkey" ) == 0 ) {
00643             continue;
00644         }
00645         if( var->flags & CVAR_ARCHIVE ) {
00646             // write the latched value, even if it hasn't taken effect yet
00647             if ( var->latchedString ) {
00648                 Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->latchedString);
00649             } else {
00650                 Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->string);
00651             }
00652             FS_Printf (f, "%s", buffer);
00653         }
00654     }
00655 }
00656 
00657 /*
00658 ============
00659 Cvar_List_f
00660 ============
00661 */
00662 void Cvar_List_f( void ) {
00663     cvar_t  *var;
00664     int     i;
00665     char    *match;
00666 
00667     if ( Cmd_Argc() > 1 ) {
00668         match = Cmd_Argv( 1 );
00669     } else {
00670         match = NULL;
00671     }
00672 
00673     i = 0;
00674     for (var = cvar_vars ; var ; var = var->next, i++)
00675     {
00676         if (match && !Com_Filter(match, var->name, qfalse)) continue;
00677 
00678         if (var->flags & CVAR_SERVERINFO) {
00679             Com_Printf("S");
00680         } else {
00681             Com_Printf(" ");
00682         }
00683         if (var->flags & CVAR_USERINFO) {
00684             Com_Printf("U");
00685         } else {
00686             Com_Printf(" ");
00687         }
00688         if (var->flags & CVAR_ROM) {
00689             Com_Printf("R");
00690         } else {
00691             Com_Printf(" ");
00692         }
00693         if (var->flags & CVAR_INIT) {
00694             Com_Printf("I");
00695         } else {
00696             Com_Printf(" ");
00697         }
00698         if (var->flags & CVAR_ARCHIVE) {
00699             Com_Printf("A");
00700         } else {
00701             Com_Printf(" ");
00702         }
00703         if (var->flags & CVAR_LATCH) {
00704             Com_Printf("L");
00705         } else {
00706             Com_Printf(" ");
00707         }
00708         if (var->flags & CVAR_CHEAT) {
00709             Com_Printf("C");
00710         } else {
00711             Com_Printf(" ");
00712         }
00713 
00714         Com_Printf (" %s \"%s\"\n", var->name, var->string);
00715     }
00716 
00717     Com_Printf ("\n%i total cvars\n", i);
00718     Com_Printf ("%i cvar indexes\n", cvar_numIndexes);
00719 }
00720 
00721 /*
00722 ============
00723 Cvar_Restart_f
00724 
00725 Resets all cvars to their hardcoded values
00726 ============
00727 */
00728 void Cvar_Restart_f( void ) {
00729     cvar_t  *var;
00730     cvar_t  **prev;
00731 
00732     prev = &cvar_vars;
00733     while ( 1 ) {
00734         var = *prev;
00735         if ( !var ) {
00736             break;
00737         }
00738 
00739         // don't mess with rom values, or some inter-module
00740         // communication will get broken (com_cl_running, etc)
00741         if ( var->flags & ( CVAR_ROM | CVAR_INIT | CVAR_NORESTART ) ) {
00742             prev = &var->next;
00743             continue;
00744         }
00745 
00746         // throw out any variables the user created
00747         if ( var->flags & CVAR_USER_CREATED ) {
00748             *prev = var->next;
00749             if ( var->name ) {
00750                 Z_Free( var->name );
00751             }
00752             if ( var->string ) {
00753                 Z_Free( var->string );
00754             }
00755             if ( var->latchedString ) {
00756                 Z_Free( var->latchedString );
00757             }
00758             if ( var->resetString ) {
00759                 Z_Free( var->resetString );
00760             }
00761             // clear the var completely, since we
00762             // can't remove the index from the list
00763             Com_Memset( var, 0, sizeof( var ) );
00764             continue;
00765         }
00766 
00767         Cvar_Set( var->name, var->resetString );
00768 
00769         prev = &var->next;
00770     }
00771 }
00772 
00773 
00774 
00775 /*
00776 =====================
00777 Cvar_InfoString
00778 =====================
00779 */
00780 char    *Cvar_InfoString( int bit ) {
00781     static char info[MAX_INFO_STRING];
00782     cvar_t  *var;
00783 
00784     info[0] = 0;
00785 
00786     for (var = cvar_vars ; var ; var = var->next) {
00787         if (var->flags & bit) {
00788             Info_SetValueForKey (info, var->name, var->string);
00789         }
00790     }
00791     return info;
00792 }
00793 
00794 /*
00795 =====================
00796 Cvar_InfoString_Big
00797 
00798   handles large info strings ( CS_SYSTEMINFO )
00799 =====================
00800 */
00801 char    *Cvar_InfoString_Big( int bit ) {
00802     static char info[BIG_INFO_STRING];
00803     cvar_t  *var;
00804 
00805     info[0] = 0;
00806 
00807     for (var = cvar_vars ; var ; var = var->next) {
00808         if (var->flags & bit) {
00809             Info_SetValueForKey_Big (info, var->name, var->string);
00810         }
00811     }
00812     return info;
00813 }
00814 
00815 
00816 
00817 /*
00818 =====================
00819 Cvar_InfoStringBuffer
00820 =====================
00821 */
00822 void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) {
00823     Q_strncpyz(buff,Cvar_InfoString(bit),buffsize);
00824 }
00825 
00826 /*
00827 =====================
00828 Cvar_Register
00829 
00830 basically a slightly modified Cvar_Get for the interpreted modules
00831 =====================
00832 */
00833 void    Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) {
00834     cvar_t  *cv;
00835 
00836     cv = Cvar_Get( varName, defaultValue, flags );
00837     if ( !vmCvar ) {
00838         return;
00839     }
00840     vmCvar->handle = cv - cvar_indexes;
00841     vmCvar->modificationCount = -1;
00842     Cvar_Update( vmCvar );
00843 }
00844 
00845 
00846 /*
00847 =====================
00848 Cvar_Register
00849 
00850 updates an interpreted modules' version of a cvar
00851 =====================
00852 */
00853 void    Cvar_Update( vmCvar_t *vmCvar ) {
00854     cvar_t  *cv = NULL; // bk001129
00855     assert(vmCvar); // bk
00856 
00857     if ( (unsigned)vmCvar->handle >= cvar_numIndexes ) {
00858         Com_Error( ERR_DROP, "Cvar_Update: handle out of range" );
00859     }
00860 
00861     cv = cvar_indexes + vmCvar->handle;
00862 
00863     if ( cv->modificationCount == vmCvar->modificationCount ) {
00864         return;
00865     }
00866     if ( !cv->string ) {
00867         return;     // variable might have been cleared by a cvar_restart
00868     }
00869     vmCvar->modificationCount = cv->modificationCount;
00870     // bk001129 - mismatches.
00871     if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING ) 
00872       Com_Error( ERR_DROP, "Cvar_Update: src %s length %d exceeds MAX_CVAR_VALUE_STRING",
00873              cv->string, 
00874              strlen(cv->string), 
00875              sizeof(vmCvar->string) );
00876     // bk001212 - Q_strncpyz guarantees zero padding and dest[MAX_CVAR_VALUE_STRING-1]==0 
00877     // bk001129 - paranoia. Never trust the destination string.
00878     // bk001129 - beware, sizeof(char*) is always 4 (for cv->string). 
00879     //            sizeof(vmCvar->string) always MAX_CVAR_VALUE_STRING
00880     //Q_strncpyz( vmCvar->string, cv->string, sizeof( vmCvar->string ) ); // id
00881     Q_strncpyz( vmCvar->string, cv->string,  MAX_CVAR_VALUE_STRING ); 
00882 
00883     vmCvar->value = cv->value;
00884     vmCvar->integer = cv->integer;
00885 }
00886 
00887 
00888 /*
00889 ============
00890 Cvar_Init
00891 
00892 Reads in all archived cvars
00893 ============
00894 */
00895 void Cvar_Init (void) {
00896     cvar_cheats = Cvar_Get("sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO );
00897 
00898     Cmd_AddCommand ("toggle", Cvar_Toggle_f);
00899     Cmd_AddCommand ("set", Cvar_Set_f);
00900     Cmd_AddCommand ("sets", Cvar_SetS_f);
00901     Cmd_AddCommand ("setu", Cvar_SetU_f);
00902     Cmd_AddCommand ("seta", Cvar_SetA_f);
00903     Cmd_AddCommand ("reset", Cvar_Reset_f);
00904     Cmd_AddCommand ("cvarlist", Cvar_List_f);
00905     Cmd_AddCommand ("cvar_restart", Cvar_Restart_f);
00906 }

Generated on Thu Aug 25 12:37:47 2005 for Quake III Arena by  doxygen 1.3.9.1