cvar.c

Go to the documentation of this file.
00001 
00011 /*
00012 Copyright (C) 1997-2001 Id Software, Inc.
00013 
00014 This program is free software; you can redistribute it and/or
00015 modify it under the terms of the GNU General Public License
00016 as published by the Free Software Foundation; either version 2
00017 of the License, or (at your option) any later version.
00018 
00019 This program is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 
00023 See the GNU General Public License for more details.
00024 
00025 You should have received a copy of the GNU General Public License
00026 along with this program; if not, write to the Free Software
00027 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00028 
00029 */
00030 
00031 #include "common.h"
00032 #include "../shared/infostring.h"
00033 
00034 #define CVAR_HASH_SIZE          64
00035 
00036 static cvar_t *cvarVarsHash[CVAR_HASH_SIZE];
00037 
00042 static qboolean renderModified;
00043 
00048 static qboolean userinfoModified;
00049 
00050 void Com_SetUserinfoModified (qboolean modified)
00051 {
00052     userinfoModified = modified;
00053 }
00054 
00055 qboolean Com_IsUserinfoModified (void)
00056 {
00057     return userinfoModified;
00058 }
00059 
00060 void Com_SetRenderModified (qboolean modified)
00061 {
00062     renderModified = modified;
00063 }
00064 
00065 qboolean Com_IsRenderModified (void)
00066 {
00067     return renderModified;
00068 }
00069 
00073 static cvar_t *cvarVars;
00074 
00075 static qboolean Cvar_InfoValidate (const char *s)
00076 {
00077     if (strstr(s, "\\"))
00078         return qfalse;
00079     if (strstr(s, "\""))
00080         return qfalse;
00081     if (strstr(s, ";"))
00082         return qfalse;
00083     return qtrue;
00084 }
00085 
00093 cvar_t *Cvar_FindVar (const char *varName)
00094 {
00095     cvar_t *var;
00096     const unsigned hash = Com_HashKey(varName, CVAR_HASH_SIZE);
00097 
00098     for (var = cvarVarsHash[hash]; var; var = var->hash_next)
00099         if (!strcmp(varName, var->name))
00100             return var;
00101 
00102     return NULL;
00103 }
00104 
00112 float Cvar_GetValue (const char *varName)
00113 {
00114     cvar_t *var;
00115 
00116     var = Cvar_FindVar(varName);
00117     if (!var)
00118         return 0.0;
00119     return atof(var->string);
00120 }
00121 
00122 
00128 qboolean Cvar_SetCheckFunction (const char *varName, qboolean (*check) (cvar_t* cvar))
00129 {
00130     cvar_t *var;
00131 
00132     var = Cvar_FindVar(varName);
00133     if (!var) {
00134         Com_Printf("Could not set check function for cvar '%s'\n", varName);
00135         return qfalse;
00136     }
00137     var->check = check;
00138     /* execute the check */
00139     var->check(var);
00140     return qtrue;
00141 }
00142 
00152 qboolean Cvar_AssertValue (cvar_t * cvar, float minVal, float maxVal, qboolean shouldBeIntegral)
00153 {
00154     assert(cvar);
00155 
00156     if (shouldBeIntegral) {
00157         if ((int)cvar->value != cvar->integer) {
00158             Com_Printf("WARNING: cvar '%s' must be integral (%f)\n", cvar->name, cvar->value);
00159             Cvar_Set(cvar->name, va("%d", cvar->integer));
00160             return qtrue;
00161         }
00162     }
00163 
00164     if (cvar->value < minVal) {
00165         Com_Printf("WARNING: cvar '%s' out of range (%f < %f)\n", cvar->name, cvar->value, minVal);
00166         Cvar_SetValue(cvar->name, minVal);
00167         return qtrue;
00168     } else if (cvar->value > maxVal) {
00169         Com_Printf("WARNING: cvar '%s' out of range (%f > %f)\n", cvar->name, cvar->value, maxVal);
00170         Cvar_SetValue(cvar->name, maxVal);
00171         return qtrue;
00172     }
00173 
00174     /* no changes */
00175     return qfalse;
00176 }
00177 
00186 qboolean Cvar_AssertString (cvar_t * cvar, char **array, int arraySize)
00187 {
00188     int i;
00189     char *string;
00190 
00191     assert(cvar);
00192 
00193     for (i = 0; i < arraySize; i++) {
00194         string = array[i];
00195         if (strncmp(cvar->string, string, sizeof(cvar->string))) {
00196             /* valid value */
00197             return qfalse;
00198         }
00199     }
00200 
00201     Com_Printf("Cvar '%s' has not a valid value\n", cvar->name);
00202 
00203     if (cvar->oldString)
00204         Cvar_Set(cvar->name, cvar->oldString);
00205 
00206     /* not a valid value */
00207     return qtrue;
00208 }
00209 
00217 int Cvar_GetInteger (const char *varName)
00218 {
00219     const cvar_t *var;
00220 
00221     var = Cvar_FindVar(varName);
00222     if (!var)
00223         return 0;
00224     return var->integer;
00225 }
00226 
00235 const char *Cvar_GetString (const char *varName)
00236 {
00237     const cvar_t *var;
00238 
00239     var = Cvar_FindVar(varName);
00240     if (!var)
00241         return "";
00242     return var->string;
00243 }
00244 
00253 const char *Cvar_VariableStringOld (const char *varName)
00254 {
00255     cvar_t *var;
00256 
00257     var = Cvar_FindVar(varName);
00258     if (!var)
00259         return "";
00260     if (var->oldString)
00261         return var->oldString;
00262     else
00263         return "";
00264 }
00265 
00273 int Cvar_CompleteVariable (const char *partial, const char **match)
00274 {
00275     int matches = 0;
00276     const char *localMatch[MAX_COMPLETE];
00277     cvar_t* cvar;
00278     size_t len;
00279 
00280     len = strlen(partial);
00281     if (!len)
00282         return 0;
00283 
00284     localMatch[matches] = NULL;
00285 
00286     /* check for partial matches */
00287     for (cvar = cvarVars; cvar; cvar = cvar->next)
00288         if (!strncmp(partial, cvar->name, len)) {
00289 #ifndef DEBUG
00290             if (cvar->flags & CVAR_DEVELOPER)
00291                 continue;
00292 #endif
00293             Com_Printf("[var] %-20s = \"%s\"\n", cvar->name, cvar->string);
00294             if (cvar->description)
00295                 Com_Printf(COLORED_GREEN "      %s\n", cvar->description);
00296             localMatch[matches++] = cvar->name;
00297             if (matches >= MAX_COMPLETE)
00298                 break;
00299         }
00300 
00301     return Cmd_GenericCompleteFunction(len, match, matches, localMatch);
00302 }
00303 
00307 qboolean Cvar_Delete (const char *varName)
00308 {
00309     unsigned hash;
00310     cvar_t *var, *previousVar = NULL;
00311 
00312     hash = Com_HashKey(varName, CVAR_HASH_SIZE);
00313     for (var = cvarVarsHash[hash]; var; var = var->hash_next) {
00314         if (!Q_strcasecmp(varName, var->name)) {
00315             cvarChangeListener_t *changeListener;
00316             if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO | CVAR_NOSET | CVAR_LATCH)) {
00317                 Com_Printf("Can't delete the cvar '%s' - it's a special cvar\n", varName);
00318                 return qfalse;
00319             }
00320             if (var->prev) {
00321                 assert(var->prev->next == var);
00322                 var->prev->next = var->next;
00323             } else
00324                 cvarVars = var->next;
00325             if (var->next) {
00326                 assert(var->next->prev == var);
00327                 var->next->prev = var->prev;
00328             }
00329             if (previousVar) {
00330                 assert(previousVar->hash_next == var);
00331                 previousVar->hash_next = var->hash_next;
00332             } else {
00333                 cvarVarsHash[hash] = var->hash_next;
00334             }
00335             Mem_Free(var->name);
00336             Mem_Free(var->string);
00337             if (var->description)
00338                 Mem_Free(var->description);
00339             if (var->oldString)
00340                 Mem_Free(var->oldString);
00341             if (var->defaultString)
00342                 Mem_Free(var->defaultString);
00343             /* latched cvars should not be removable */
00344             assert(var->latchedString == NULL);
00345             changeListener = var->changeListener;
00346             while (changeListener) {
00347                 cvarChangeListener_t *changeListener2 = changeListener->next;
00348                 Mem_Free(changeListener);
00349                 changeListener = changeListener2;
00350             }
00351             Mem_Free(var);
00352 
00353             return qtrue;
00354         }
00355         previousVar = var;
00356     }
00357     Com_Printf("Cvar '%s' wasn't found\n", varName);
00358     return qfalse;
00359 }
00360 
00377 cvar_t *Cvar_Get (const char *var_name, const char *var_value, int flags, const char* desc)
00378 {
00379     cvar_t *var;
00380     const unsigned hash = Com_HashKey(var_name, CVAR_HASH_SIZE);
00381 
00382     if (flags & (CVAR_USERINFO | CVAR_SERVERINFO))
00383         if (!Cvar_InfoValidate(var_name)) {
00384             Com_Printf("invalid info cvar name\n");
00385             return NULL;
00386         }
00387 
00388     var = Cvar_FindVar(var_name);
00389     if (var) {
00390         if (!var->defaultString && flags & CVAR_CHEAT)
00391             var->defaultString = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);
00392         var->flags |= flags;
00393         if (desc) {
00394             if (var->description)
00395                 Mem_Free(var->description);
00396             var->description = Mem_PoolStrDup(desc, com_cvarSysPool, 0);
00397         }
00398         return var;
00399     }
00400 
00401     if (!var_value)
00402         return NULL;
00403 
00404     if (flags & (CVAR_USERINFO | CVAR_SERVERINFO))
00405         if (!Cvar_InfoValidate(var_value)) {
00406             Com_Printf("invalid info cvar value '%s' of cvar '%s'\n", var_value, var_name);
00407             return NULL;
00408         }
00409 
00410     var = Mem_PoolAlloc(sizeof(*var), com_cvarSysPool, 0);
00411     var->name = Mem_PoolStrDup(var_name, com_cvarSysPool, 0);
00412     var->string = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);
00413     var->oldString = NULL;
00414     var->modified = qtrue;
00415     var->value = atof(var->string);
00416     var->integer = atoi(var->string);
00417     if (desc)
00418         var->description = Mem_PoolStrDup(desc, com_cvarSysPool, 0);
00419 
00420     HASH_Add(cvarVarsHash, var, hash);
00421     /* link the variable in */
00422     var->next = cvarVars;
00423     cvarVars = var;
00424     if (var->next)
00425         var->next->prev = var;
00426 
00427     var->flags = flags;
00428     if (var->flags & CVAR_CHEAT)
00429         var->defaultString = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);
00430 
00431     return var;
00432 }
00433 
00438 static void Cvar_ExecuteChangeListener (const cvar_t* cvar)
00439 {
00440     const cvarChangeListener_t *listener = cvar->changeListener;
00441     while (listener) {
00442         listener->exec(cvar->name, cvar->oldString, cvar->string);
00443         listener = listener->next;
00444     }
00445 }
00446 
00447 static cvarChangeListener_t *Cvar_GetChangeListener (cvarChangeListenerFunc_t listenerFunc)
00448 {
00449     cvarChangeListener_t *listener = Mem_PoolAlloc(sizeof(*listener), com_cvarSysPool, 0);
00450     listener->exec = listenerFunc;
00451     return listener;
00452 }
00453 
00460 void Cvar_RegisterChangeListener (const char *varName, cvarChangeListenerFunc_t listenerFunc)
00461 {
00462     cvarChangeListener_t *listener;
00463     cvar_t *var = Cvar_FindVar(varName);
00464     if (!var) {
00465         Com_Printf("Could not register change listener, cvar '%s' wasn't found\n", varName);
00466         return;
00467     }
00468 
00469     listener = Cvar_GetChangeListener(listenerFunc);
00470     if (!var->changeListener) {
00471         var->changeListener = listener;
00472     } else {
00473         cvarChangeListener_t *l = var->changeListener;
00474         while (l) {
00475             if (l->exec == listenerFunc) {
00476                 Com_Printf("Cvar change listener already registered\n");
00477                 return;
00478             }
00479             l = l->next;
00480         }
00481 
00482         l = var->changeListener;
00483         while (l) {
00484             if (!l->next) {
00485                 l->next = listener;
00486                 l->next->next = NULL;
00487                 break;
00488             }
00489             l = l->next;
00490         }
00491     }
00492 }
00493 
00499 void Cvar_UnRegisterChangeListener (const char *varName, cvarChangeListenerFunc_t listenerFunc)
00500 {
00501     cvar_t *var = Cvar_FindVar(varName);
00502     cvarChangeListener_t *l, *prev;
00503 
00504     if (!var) {
00505         Com_Printf("Could not unregister change listener, cvar '%s' wasn't found\n", varName);
00506         return;
00507     }
00508 
00509     l = var->changeListener;
00510     prev = NULL;
00511     while (l) {
00512         if (l->exec == listenerFunc) {
00513             if (prev) {
00514                 prev->next = l->next;
00515             } else {
00516                 var->changeListener = l->next;
00517             }
00518             Mem_Free(l);
00519             return;
00520         }
00521         prev = l;
00522         l = l->next;
00523     }
00524 }
00525 
00533 static cvar_t *Cvar_Set2 (const char *varName, const char *value, qboolean force)
00534 {
00535     cvar_t *var;
00536 
00537     if (!value)
00538         return NULL;
00539 
00540     var = Cvar_FindVar(varName);
00541     /* create it */
00542     if (!var)
00543         return Cvar_Get(varName, value, 0, NULL);
00544 
00545     if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO))
00546         if (!Cvar_InfoValidate(value)) {
00547             Com_Printf("invalid info cvar value '%s' of cvar '%s'\n", value, varName);
00548             return var;
00549         }
00550 
00551     if (!force) {
00552         if (var->flags & CVAR_NOSET) {
00553             Com_Printf("%s is write protected.\n", varName);
00554             return var;
00555         }
00556 #ifndef DEBUG
00557         if (var->flags & CVAR_DEVELOPER) {
00558             Com_Printf("%s is a developer cvar.\n", varName);
00559             return var;
00560         }
00561 #endif
00562 
00563         if (var->flags & CVAR_LATCH) {
00564             if (var->latchedString) {
00565                 if (!strcmp(value, var->latchedString))
00566                     return var;
00567                 Mem_Free(var->latchedString);
00568                 var->latchedString = NULL;
00569             } else {
00570                 if (!strcmp(value, var->string))
00571                     return var;
00572             }
00573 
00574             /* if we are running a server */
00575             if (Com_ServerState()) {
00576                 Com_Printf("%s will be changed for next game.\n", varName);
00577                 var->latchedString = Mem_PoolStrDup(value, com_cvarSysPool, 0);
00578             } else {
00579                 if (var->oldString)
00580                     Mem_Free(var->oldString);
00581                 var->oldString = var->string;
00582                 var->string = Mem_PoolStrDup(value, com_cvarSysPool, 0);
00583                 var->value = atof(var->string);
00584                 var->integer = atoi(var->string);
00585             }
00586 
00587             if (var->check)
00588                 if (var->check(var))
00589                     Com_Printf("Invalid value for cvar %s\n", varName);
00590 
00591             return var;
00592         }
00593     } else {
00594         if (var->latchedString) {
00595             Mem_Free(var->latchedString);
00596             var->latchedString = NULL;
00597         }
00598     }
00599 
00600     if (!strcmp(value, var->string))
00601         return var;             /* not changed */
00602 
00603     if (var->flags & CVAR_R_MASK)
00604         Com_SetRenderModified(qtrue);
00605 
00606     if (var->oldString)
00607         Mem_Free(var->oldString);       /* free the old value string */
00608     var->oldString = var->string;
00609     var->modified = qtrue;
00610 
00611     if (var->flags & CVAR_USERINFO)
00612         Com_SetUserinfoModified(qtrue); /* transmit at next opportunity */
00613 
00614     var->string = Mem_PoolStrDup(value, com_cvarSysPool, 0);
00615     var->value = atof(var->string);
00616     var->integer = atoi(var->string);
00617 
00618     if (var->check)
00619         if (var->check(var)) {
00620             Com_Printf("Invalid value for cvar %s\n", varName);
00621             return var;
00622         }
00623 
00624     Cvar_ExecuteChangeListener(var);
00625 
00626     return var;
00627 }
00628 
00632 cvar_t *Cvar_ForceSet (const char *varName, const char *value)
00633 {
00634     return Cvar_Set2(varName, value, qtrue);
00635 }
00636 
00643 cvar_t *Cvar_Set (const char *varName, const char *value)
00644 {
00645     return Cvar_Set2(varName, value, qfalse);
00646 }
00647 
00662 cvar_t *Cvar_FullSet (const char *varName, const char *value, int flags)
00663 {
00664     cvar_t *var;
00665 
00666     if (!value)
00667         return NULL;
00668 
00669     var = Cvar_FindVar(varName);
00670     /* create it */
00671     if (!var)
00672         return Cvar_Get(varName, value, flags, NULL);
00673 
00674     var->modified = qtrue;
00675 
00676     /* transmit at next opportunity */
00677     if (var->flags & CVAR_USERINFO)
00678         Com_SetUserinfoModified(qtrue);
00679 
00680     if (var->oldString)
00681         Mem_Free(var->oldString);       /* free the old value string */
00682     var->oldString = var->string;
00683 
00684     var->string = Mem_PoolStrDup(value, com_cvarSysPool, 0);
00685     var->value = atof(var->string);
00686     var->integer = atoi(var->string);
00687     var->flags = flags;
00688 
00689     return var;
00690 }
00691 
00696 void Cvar_SetValue (const char *varName, float value)
00697 {
00698     char val[32];
00699 
00700     if (value == (int) value)
00701         Com_sprintf(val, sizeof(val), "%i", (int) value);
00702     else
00703         Com_sprintf(val, sizeof(val), "%1.2f", value);
00704     Cvar_Set(varName, val);
00705 }
00706 
00707 
00712 void Cvar_UpdateLatchedVars (void)
00713 {
00714     cvar_t *var;
00715 
00716     for (var = cvarVars; var; var = var->next) {
00717         if (!var->latchedString)
00718             continue;
00719         var->oldString = var->string;
00720         var->string = var->latchedString;
00721         var->latchedString = NULL;
00722         var->value = atof(var->string);
00723         var->integer = atoi(var->string);
00724     }
00725 }
00726 
00739 qboolean Cvar_Command (void)
00740 {
00741     cvar_t *v;
00742 
00743     /* check variables */
00744     v = Cvar_FindVar(Cmd_Argv(0));
00745     if (!v)
00746         return qfalse;
00747 
00748     /* perform a variable print or set */
00749     if (Cmd_Argc() == 1) {
00750         Com_Printf("\"%s\" is \"%s\"\n", v->name, v->string);
00751         return qtrue;
00752     }
00753 
00754     Cvar_Set(v->name, Cmd_Argv(1));
00755     return qtrue;
00756 }
00757 
00761 static void Cvar_SetOld_f (void)
00762 {
00763     cvar_t *v;
00764 
00765     if (Cmd_Argc() != 2) {
00766         Com_Printf("Usage: %s <variable>\n", Cmd_Argv(0));
00767         return;
00768     }
00769 
00770     /* check variables */
00771     v = Cvar_FindVar(Cmd_Argv(1));
00772     if (!v) {
00773         Com_Printf("cvar '%s' not found\n", Cmd_Argv(1));
00774         return;
00775     }
00776     if (v->oldString)
00777         Cvar_Set(Cmd_Argv(1), v->oldString);
00778 }
00779 
00780 static void Cvar_Define_f (void)
00781 {
00782     const char *name;
00783 
00784     if (Cmd_Argc() < 2) {
00785         Com_Printf("Usage: %s <cvarname> <value>\n", Cmd_Argv(0));
00786         return;
00787     }
00788 
00789     name = Cmd_Argv(1);
00790 
00791     if (Cvar_FindVar(name) == NULL)
00792         Cvar_Set(name, Cmd_Argc() == 3 ? Cmd_Argv(2) : "");
00793 }
00794 
00798 static void Cvar_Set_f (void)
00799 {
00800     const int c = Cmd_Argc();
00801     if (c != 3 && c != 4) {
00802         Com_Printf("Usage: %s <variable> <value> [u / s]\n", Cmd_Argv(0));
00803         return;
00804     }
00805 
00806     if (c == 4) {
00807         const char *arg = Cmd_Argv(3);
00808         int flags = 0;
00809 
00810         while (arg[0] != '\0') {
00811             switch (arg[0]) {
00812             case 'u':
00813                 flags |= CVAR_USERINFO;
00814                 break;
00815             case 's':
00816                 flags |= CVAR_SERVERINFO;
00817                 break;
00818             case 'a':
00819                 flags |= CVAR_ARCHIVE;
00820                 break;
00821             default:
00822                 Com_Printf("invalid flags %c given\n", arg[0]);
00823             }
00824             arg++;
00825         }
00826         Cvar_FullSet(Cmd_Argv(1), Cmd_Argv(2), flags);
00827     } else
00828         Cvar_Set(Cmd_Argv(1), Cmd_Argv(2));
00829 }
00830 
00831 
00836 static void Cvar_Copy_f (void)
00837 {
00838     int c;
00839 
00840     c = Cmd_Argc();
00841     if (c < 3) {
00842         Com_Printf("Usage: %s <target> <source>\n", Cmd_Argv(0));
00843         return;
00844     }
00845 
00846     Cvar_Set(Cmd_Argv(1), Cvar_GetString(Cmd_Argv(2)));
00847 }
00848 
00849 
00855 void Cvar_WriteVariables (qFILE *f)
00856 {
00857     const cvar_t *var;
00858 
00859     for (var = cvarVars; var; var = var->next)
00860         if (var->flags & CVAR_ARCHIVE)
00861             FS_Printf(f, "set %s \"%s\" a\n", var->name, var->string);
00862 }
00863 
00869 qboolean Cvar_PendingCvars (int flags)
00870 {
00871     const cvar_t *var;
00872 
00873     for (var = cvarVars; var; var = var->next)
00874         if ((var->flags & flags) && var->modified)
00875             return qtrue;
00876 
00877     return qfalse;
00878 }
00879 
00880 void Cvar_ClearVars (int flags)
00881 {
00882     cvar_t *var;
00883 
00884     for (var = cvarVars; var; var = var->next)
00885         if ((var->flags & flags) && var->modified)
00886             var->modified = qfalse;
00887 }
00888 
00892 static void Cvar_List_f (void)
00893 {
00894     cvar_t *var;
00895     int i, c, l = 0;
00896     const char *token = NULL;
00897 
00898     c = Cmd_Argc();
00899 
00900     if (c == 2) {
00901         token = Cmd_Argv(1);
00902         l = strlen(token);
00903     }
00904 
00905     i = 0;
00906     for (var = cvarVars; var; var = var->next, i++) {
00907         if (c == 2 && strncmp(var->name, token, l)) {
00908             i--;
00909             continue;
00910         }
00911 #ifndef DEBUG
00912         /* don't show developer cvars in release mode */
00913         if (var->flags & CVAR_DEVELOPER)
00914             continue;
00915 #endif
00916 
00917         if (var->flags & CVAR_ARCHIVE)
00918             Com_Printf("A");
00919         else
00920             Com_Printf(" ");
00921         if (var->flags & CVAR_USERINFO)
00922             Com_Printf("U");
00923         else
00924             Com_Printf(" ");
00925         if (var->flags & CVAR_SERVERINFO)
00926             Com_Printf("S");
00927         else
00928             Com_Printf(" ");
00929         if (var->modified)
00930             Com_Printf("M");
00931         else
00932             Com_Printf(" ");
00933         if (var->flags & CVAR_DEVELOPER)
00934             Com_Printf("D");
00935         else
00936             Com_Printf(" ");
00937         if (var->flags & CVAR_R_IMAGES)
00938             Com_Printf("I");
00939         else
00940             Com_Printf(" ");
00941         if (var->flags & CVAR_NOSET)
00942             Com_Printf("-");
00943         else if (var->flags & CVAR_LATCH)
00944             Com_Printf("L");
00945         else
00946             Com_Printf(" ");
00947         Com_Printf(" %-20s \"%s\"\n", var->name, var->string);
00948         if (var->description)
00949             Com_Printf(COLORED_GREEN "        %s\n", var->description);
00950     }
00951     Com_Printf("%i cvars\n", i);
00952     Com_Printf("legend:\n"
00953         "S: Serverinfo\n"
00954         "L: Latched\n"
00955         "D: Developer\n"
00956         "U: Userinfo\n"
00957         "I: Image\n"
00958         "*: Archive\n"
00959         "-: Not changeable\n"
00960     );
00961 }
00962 
00967 static char *Cvar_BitInfo (int bit)
00968 {
00969     static char info[MAX_INFO_STRING];
00970     cvar_t *var;
00971 
00972     info[0] = 0;
00973 
00974     for (var = cvarVars; var; var = var->next)
00975         if (var->flags & bit)
00976             Info_SetValueForKey(info, sizeof(info), var->name, var->string);
00977     return info;
00978 }
00979 
00983 const char *Cvar_Userinfo (void)
00984 {
00985     return Cvar_BitInfo(CVAR_USERINFO);
00986 }
00987 
00992 const char *Cvar_Serverinfo (void)
00993 {
00994     return Cvar_BitInfo(CVAR_SERVERINFO);
00995 }
00996 
01001 static void Cvar_Del_f (void)
01002 {
01003     int c;
01004 
01005     c = Cmd_Argc();
01006     if (c != 2) {
01007         Com_Printf("Usage: %s <variable>\n", Cmd_Argv(0));
01008         return;
01009     }
01010 
01011     Cvar_Delete(Cmd_Argv(1));
01012 }
01013 
01017 static void Cvar_Add_f (void)
01018 {
01019     cvar_t *cvar;
01020     float value;
01021     if (Cmd_Argc() != 3) {
01022         Com_Printf("Usage: %s <variable> <value>\n", Cmd_Argv(0));
01023         return;
01024     }
01025 
01026     cvar = Cvar_FindVar(Cmd_Argv(1));
01027     if (!cvar) {
01028         Com_Printf("Cvar_Add_f: %s not exists\n", Cmd_Argv(1));
01029         return;
01030     }
01031 
01032     value = cvar->value + atof(Cmd_Argv(2));
01033     Cvar_SetValue(Cmd_Argv(1), value);
01034 }
01035 
01039 static void Cvar_Mod_f (void)
01040 {
01041     cvar_t *cvar;
01042     int value;
01043     if (Cmd_Argc() != 3) {
01044         Com_Printf("Usage: %s <variable> <value>\n", Cmd_Argv(0));
01045         return;
01046     }
01047 
01048     cvar = Cvar_FindVar(Cmd_Argv(1));
01049     if (!cvar) {
01050         Com_Printf("Cvar_Mod_f: %s not exists\n", Cmd_Argv(1));
01051         return;
01052     }
01053 
01054     value = cvar->integer % atoi(Cmd_Argv(2));
01055     Cvar_SetValue(Cmd_Argv(1), value);
01056 }
01057 
01062 void Cvar_FixCheatVars (void)
01063 {
01064     cvar_t *var;
01065 
01066     if (!(Com_ServerState() && !Cvar_GetInteger("sv_cheats")))
01067         return;
01068 
01069     for (var = cvarVars; var; var = var->next) {
01070         if (!(var->flags & CVAR_CHEAT))
01071             continue;
01072 
01073         if (!var->defaultString) {
01074             Com_Printf("Cheat cvars: Cvar %s has no default value\n", var->name);
01075             continue;
01076         }
01077 
01078         if (!strcmp(var->string, var->defaultString))
01079             continue;
01080 
01081         /* also remove the oldString value here */
01082         if (var->oldString) {
01083             Mem_Free(var->oldString);
01084             var->oldString = NULL;
01085         }
01086         Mem_Free(var->string);
01087         var->string = Mem_PoolStrDup(var->defaultString, com_cvarSysPool, 0);
01088         var->value = atof(var->string);
01089         var->integer = atoi(var->string);
01090 
01091         Com_Printf("'%s' is a cheat cvar - activate sv_cheats to use it.\n", var->name);
01092     }
01093 }
01094 
01095 #ifdef DEBUG
01096 void Cvar_PrintDebugCvars (void)
01097 {
01098     const cvar_t *var;
01099 
01100     Com_Printf("Debug cvars:\n");
01101     for (var = cvarVars; var; var = var->next) {
01102         if ((var->flags & CVAR_DEVELOPER) || !strncmp(var->name, "debug_", 6))
01103             Com_Printf(" * %s (%s)\n   %s\n", var->name, var->string, var->description ? var->description : "");
01104     }
01105     Com_Printf("\n");
01106 }
01107 #endif
01108 
01113 void Cvar_Init (void)
01114 {
01115     Cmd_AddCommand("setold", Cvar_SetOld_f, "Restore the cvar old value");
01116     Cmd_AddCommand("del", Cvar_Del_f, "Delete a cvar");
01117     Cmd_AddCommand("set", Cvar_Set_f, "Set a cvar value");
01118     Cmd_AddCommand("add", Cvar_Add_f, "Add a value to a cvar");
01119     Cmd_AddCommand("define", Cvar_Define_f, "Defines a cvar if it does not exist");
01120     Cmd_AddCommand("mod", Cvar_Mod_f, "Apply a modulo on a cvar");
01121     Cmd_AddCommand("copy", Cvar_Copy_f, "Copy cvar target to source");
01122     Cmd_AddCommand("cvarlist", Cvar_List_f, "Show all cvars");
01123 }
01124 
01125 void Cvar_Shutdown (void)
01126 {
01127     cvarVars = NULL;
01128     memset(cvarVarsHash, 0, sizeof(cvarVarsHash));
01129 }

Generated by  doxygen 1.6.2