cvar.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // cvar.c -- dynamic variable tracking
  19. #include "../game/q_shared.h"
  20. #include "qcommon.h"
  21. cvar_t *cvar_vars;
  22. cvar_t *cvar_cheats;
  23. int cvar_modifiedFlags;
  24. #define MAX_CVARS 1024
  25. cvar_t cvar_indexes[MAX_CVARS];
  26. int cvar_numIndexes;
  27. #define FILE_HASH_SIZE 256
  28. static cvar_t* hashTable[FILE_HASH_SIZE];
  29. cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force);
  30. /*
  31. ================
  32. return a hash value for the filename
  33. ================
  34. */
  35. static long generateHashValue( const char *fname ) {
  36. int i;
  37. long hash;
  38. char letter;
  39. hash = 0;
  40. i = 0;
  41. while (fname[i] != '\0') {
  42. letter = tolower(fname[i]);
  43. hash+=(long)(letter)*(i+119);
  44. i++;
  45. }
  46. hash &= (FILE_HASH_SIZE-1);
  47. return hash;
  48. }
  49. /*
  50. ============
  51. Cvar_ValidateString
  52. ============
  53. */
  54. static qboolean Cvar_ValidateString( const char *s ) {
  55. if ( !s ) {
  56. return qfalse;
  57. }
  58. if ( strchr( s, '\\' ) ) {
  59. return qfalse;
  60. }
  61. if ( strchr( s, '\"' ) ) {
  62. return qfalse;
  63. }
  64. if ( strchr( s, ';' ) ) {
  65. return qfalse;
  66. }
  67. return qtrue;
  68. }
  69. /*
  70. ============
  71. Cvar_FindVar
  72. ============
  73. */
  74. static cvar_t *Cvar_FindVar( const char *var_name ) {
  75. cvar_t *var;
  76. long hash;
  77. hash = generateHashValue(var_name);
  78. for (var=hashTable[hash] ; var ; var=var->hashNext) {
  79. if (!Q_stricmp(var_name, var->name)) {
  80. return var;
  81. }
  82. }
  83. return NULL;
  84. }
  85. /*
  86. ============
  87. Cvar_VariableValue
  88. ============
  89. */
  90. float Cvar_VariableValue( const char *var_name ) {
  91. cvar_t *var;
  92. var = Cvar_FindVar (var_name);
  93. if (!var)
  94. return 0;
  95. return var->value;
  96. }
  97. /*
  98. ============
  99. Cvar_VariableIntegerValue
  100. ============
  101. */
  102. int Cvar_VariableIntegerValue( const char *var_name ) {
  103. cvar_t *var;
  104. var = Cvar_FindVar (var_name);
  105. if (!var)
  106. return 0;
  107. return var->integer;
  108. }
  109. /*
  110. ============
  111. Cvar_VariableString
  112. ============
  113. */
  114. char *Cvar_VariableString( const char *var_name ) {
  115. cvar_t *var;
  116. var = Cvar_FindVar (var_name);
  117. if (!var)
  118. return "";
  119. return var->string;
  120. }
  121. /*
  122. ============
  123. Cvar_VariableStringBuffer
  124. ============
  125. */
  126. void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) {
  127. cvar_t *var;
  128. var = Cvar_FindVar (var_name);
  129. if (!var) {
  130. *buffer = 0;
  131. }
  132. else {
  133. Q_strncpyz( buffer, var->string, bufsize );
  134. }
  135. }
  136. /*
  137. ============
  138. Cvar_CommandCompletion
  139. ============
  140. */
  141. void Cvar_CommandCompletion( void(*callback)(const char *s) ) {
  142. cvar_t *cvar;
  143. for ( cvar = cvar_vars ; cvar ; cvar = cvar->next ) {
  144. callback( cvar->name );
  145. }
  146. }
  147. /*
  148. ============
  149. Cvar_Get
  150. If the variable already exists, the value will not be set unless CVAR_ROM
  151. The flags will be or'ed in if the variable exists.
  152. ============
  153. */
  154. cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
  155. cvar_t *var;
  156. long hash;
  157. if ( !var_name || ! var_value ) {
  158. Com_Error( ERR_FATAL, "Cvar_Get: NULL parameter" );
  159. }
  160. if ( !Cvar_ValidateString( var_name ) ) {
  161. Com_Printf("invalid cvar name string: %s\n", var_name );
  162. var_name = "BADNAME";
  163. }
  164. #if 0 // FIXME: values with backslash happen
  165. if ( !Cvar_ValidateString( var_value ) ) {
  166. Com_Printf("invalid cvar value string: %s\n", var_value );
  167. var_value = "BADVALUE";
  168. }
  169. #endif
  170. var = Cvar_FindVar (var_name);
  171. if ( var ) {
  172. // if the C code is now specifying a variable that the user already
  173. // set a value for, take the new value as the reset value
  174. if ( ( var->flags & CVAR_USER_CREATED ) && !( flags & CVAR_USER_CREATED )
  175. && var_value[0] ) {
  176. var->flags &= ~CVAR_USER_CREATED;
  177. Z_Free( var->resetString );
  178. var->resetString = CopyString( var_value );
  179. // ZOID--needs to be set so that cvars the game sets as
  180. // SERVERINFO get sent to clients
  181. cvar_modifiedFlags |= flags;
  182. }
  183. var->flags |= flags;
  184. // only allow one non-empty reset string without a warning
  185. if ( !var->resetString[0] ) {
  186. // we don't have a reset string yet
  187. Z_Free( var->resetString );
  188. var->resetString = CopyString( var_value );
  189. } else if ( var_value[0] && strcmp( var->resetString, var_value ) ) {
  190. Com_DPrintf( "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n",
  191. var_name, var->resetString, var_value );
  192. }
  193. // if we have a latched string, take that value now
  194. if ( var->latchedString ) {
  195. char *s;
  196. s = var->latchedString;
  197. var->latchedString = NULL; // otherwise cvar_set2 would free it
  198. Cvar_Set2( var_name, s, qtrue );
  199. Z_Free( s );
  200. }
  201. // use a CVAR_SET for rom sets, get won't override
  202. #if 0
  203. // CVAR_ROM always overrides
  204. if ( flags & CVAR_ROM ) {
  205. Cvar_Set2( var_name, var_value, qtrue );
  206. }
  207. #endif
  208. return var;
  209. }
  210. //
  211. // allocate a new cvar
  212. //
  213. if ( cvar_numIndexes >= MAX_CVARS ) {
  214. Com_Error( ERR_FATAL, "MAX_CVARS" );
  215. }
  216. var = &cvar_indexes[cvar_numIndexes];
  217. cvar_numIndexes++;
  218. var->name = CopyString (var_name);
  219. var->string = CopyString (var_value);
  220. var->modified = qtrue;
  221. var->modificationCount = 1;
  222. var->value = atof (var->string);
  223. var->integer = atoi(var->string);
  224. var->resetString = CopyString( var_value );
  225. // link the variable in
  226. var->next = cvar_vars;
  227. cvar_vars = var;
  228. var->flags = flags;
  229. hash = generateHashValue(var_name);
  230. var->hashNext = hashTable[hash];
  231. hashTable[hash] = var;
  232. return var;
  233. }
  234. /*
  235. ============
  236. Cvar_Set2
  237. ============
  238. */
  239. cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) {
  240. cvar_t *var;
  241. Com_DPrintf( "Cvar_Set2: %s %s\n", var_name, value );
  242. if ( !Cvar_ValidateString( var_name ) ) {
  243. Com_Printf("invalid cvar name string: %s\n", var_name );
  244. var_name = "BADNAME";
  245. }
  246. #if 0 // FIXME
  247. if ( value && !Cvar_ValidateString( value ) ) {
  248. Com_Printf("invalid cvar value string: %s\n", value );
  249. var_value = "BADVALUE";
  250. }
  251. #endif
  252. var = Cvar_FindVar (var_name);
  253. if (!var) {
  254. if ( !value ) {
  255. return NULL;
  256. }
  257. // create it
  258. if ( !force ) {
  259. return Cvar_Get( var_name, value, CVAR_USER_CREATED );
  260. } else {
  261. return Cvar_Get (var_name, value, 0);
  262. }
  263. }
  264. if (!value ) {
  265. value = var->resetString;
  266. }
  267. if (!strcmp(value,var->string)) {
  268. return var;
  269. }
  270. // note what types of cvars have been modified (userinfo, archive, serverinfo, systeminfo)
  271. cvar_modifiedFlags |= var->flags;
  272. if (!force)
  273. {
  274. if (var->flags & CVAR_ROM)
  275. {
  276. Com_Printf ("%s is read only.\n", var_name);
  277. return var;
  278. }
  279. if (var->flags & CVAR_INIT)
  280. {
  281. Com_Printf ("%s is write protected.\n", var_name);
  282. return var;
  283. }
  284. if (var->flags & CVAR_LATCH)
  285. {
  286. if (var->latchedString)
  287. {
  288. if (strcmp(value, var->latchedString) == 0)
  289. return var;
  290. Z_Free (var->latchedString);
  291. }
  292. else
  293. {
  294. if (strcmp(value, var->string) == 0)
  295. return var;
  296. }
  297. Com_Printf ("%s will be changed upon restarting.\n", var_name);
  298. var->latchedString = CopyString(value);
  299. var->modified = qtrue;
  300. var->modificationCount++;
  301. return var;
  302. }
  303. if ( (var->flags & CVAR_CHEAT) && !cvar_cheats->integer )
  304. {
  305. Com_Printf ("%s is cheat protected.\n", var_name);
  306. return var;
  307. }
  308. }
  309. else
  310. {
  311. if (var->latchedString)
  312. {
  313. Z_Free (var->latchedString);
  314. var->latchedString = NULL;
  315. }
  316. }
  317. if (!strcmp(value, var->string))
  318. return var; // not changed
  319. var->modified = qtrue;
  320. var->modificationCount++;
  321. Z_Free (var->string); // free the old value string
  322. var->string = CopyString(value);
  323. var->value = atof (var->string);
  324. var->integer = atoi (var->string);
  325. return var;
  326. }
  327. /*
  328. ============
  329. Cvar_Set
  330. ============
  331. */
  332. void Cvar_Set( const char *var_name, const char *value) {
  333. Cvar_Set2 (var_name, value, qtrue);
  334. }
  335. /*
  336. ============
  337. Cvar_SetLatched
  338. ============
  339. */
  340. void Cvar_SetLatched( const char *var_name, const char *value) {
  341. Cvar_Set2 (var_name, value, qfalse);
  342. }
  343. /*
  344. ============
  345. Cvar_SetValue
  346. ============
  347. */
  348. void Cvar_SetValue( const char *var_name, float value) {
  349. char val[32];
  350. if ( value == (int)value ) {
  351. Com_sprintf (val, sizeof(val), "%i",(int)value);
  352. } else {
  353. Com_sprintf (val, sizeof(val), "%f",value);
  354. }
  355. Cvar_Set (var_name, val);
  356. }
  357. /*
  358. ============
  359. Cvar_Reset
  360. ============
  361. */
  362. void Cvar_Reset( const char *var_name ) {
  363. Cvar_Set2( var_name, NULL, qfalse );
  364. }
  365. /*
  366. ============
  367. Cvar_SetCheatState
  368. Any testing variables will be reset to the safe values
  369. ============
  370. */
  371. void Cvar_SetCheatState( void ) {
  372. cvar_t *var;
  373. // set all default vars to the safe value
  374. for ( var = cvar_vars ; var ; var = var->next ) {
  375. if ( var->flags & CVAR_CHEAT ) {
  376. // the CVAR_LATCHED|CVAR_CHEAT vars might escape the reset here
  377. // because of a different var->latchedString
  378. if (var->latchedString)
  379. {
  380. Z_Free(var->latchedString);
  381. var->latchedString = NULL;
  382. }
  383. if (strcmp(var->resetString,var->string)) {
  384. Cvar_Set( var->name, var->resetString );
  385. }
  386. }
  387. }
  388. }
  389. /*
  390. ============
  391. Cvar_Command
  392. Handles variable inspection and changing from the console
  393. ============
  394. */
  395. qboolean Cvar_Command( void ) {
  396. cvar_t *v;
  397. // check variables
  398. v = Cvar_FindVar (Cmd_Argv(0));
  399. if (!v) {
  400. return qfalse;
  401. }
  402. // perform a variable print or set
  403. if ( Cmd_Argc() == 1 ) {
  404. Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n", v->name, v->string, v->resetString );
  405. if ( v->latchedString ) {
  406. Com_Printf( "latched: \"%s\"\n", v->latchedString );
  407. }
  408. return qtrue;
  409. }
  410. // set the value if forcing isn't required
  411. Cvar_Set2 (v->name, Cmd_Argv(1), qfalse);
  412. return qtrue;
  413. }
  414. /*
  415. ============
  416. Cvar_Toggle_f
  417. Toggles a cvar for easy single key binding
  418. ============
  419. */
  420. void Cvar_Toggle_f( void ) {
  421. int v;
  422. if ( Cmd_Argc() != 2 ) {
  423. Com_Printf ("usage: toggle <variable>\n");
  424. return;
  425. }
  426. v = Cvar_VariableValue( Cmd_Argv( 1 ) );
  427. v = !v;
  428. Cvar_Set2 (Cmd_Argv(1), va("%i", v), qfalse);
  429. }
  430. /*
  431. ============
  432. Cvar_Set_f
  433. Allows setting and defining of arbitrary cvars from console, even if they
  434. weren't declared in C code.
  435. ============
  436. */
  437. void Cvar_Set_f( void ) {
  438. int i, c, l, len;
  439. char combined[MAX_STRING_TOKENS];
  440. c = Cmd_Argc();
  441. if ( c < 3 ) {
  442. Com_Printf ("usage: set <variable> <value>\n");
  443. return;
  444. }
  445. combined[0] = 0;
  446. l = 0;
  447. for ( i = 2 ; i < c ; i++ ) {
  448. len = strlen ( Cmd_Argv( i ) + 1 );
  449. if ( l + len >= MAX_STRING_TOKENS - 2 ) {
  450. break;
  451. }
  452. strcat( combined, Cmd_Argv( i ) );
  453. if ( i != c-1 ) {
  454. strcat( combined, " " );
  455. }
  456. l += len;
  457. }
  458. Cvar_Set2 (Cmd_Argv(1), combined, qfalse);
  459. }
  460. /*
  461. ============
  462. Cvar_SetU_f
  463. As Cvar_Set, but also flags it as userinfo
  464. ============
  465. */
  466. void Cvar_SetU_f( void ) {
  467. cvar_t *v;
  468. if ( Cmd_Argc() != 3 ) {
  469. Com_Printf ("usage: setu <variable> <value>\n");
  470. return;
  471. }
  472. Cvar_Set_f();
  473. v = Cvar_FindVar( Cmd_Argv( 1 ) );
  474. if ( !v ) {
  475. return;
  476. }
  477. v->flags |= CVAR_USERINFO;
  478. }
  479. /*
  480. ============
  481. Cvar_SetS_f
  482. As Cvar_Set, but also flags it as userinfo
  483. ============
  484. */
  485. void Cvar_SetS_f( void ) {
  486. cvar_t *v;
  487. if ( Cmd_Argc() != 3 ) {
  488. Com_Printf ("usage: sets <variable> <value>\n");
  489. return;
  490. }
  491. Cvar_Set_f();
  492. v = Cvar_FindVar( Cmd_Argv( 1 ) );
  493. if ( !v ) {
  494. return;
  495. }
  496. v->flags |= CVAR_SERVERINFO;
  497. }
  498. /*
  499. ============
  500. Cvar_SetA_f
  501. As Cvar_Set, but also flags it as archived
  502. ============
  503. */
  504. void Cvar_SetA_f( void ) {
  505. cvar_t *v;
  506. if ( Cmd_Argc() != 3 ) {
  507. Com_Printf ("usage: seta <variable> <value>\n");
  508. return;
  509. }
  510. Cvar_Set_f();
  511. v = Cvar_FindVar( Cmd_Argv( 1 ) );
  512. if ( !v ) {
  513. return;
  514. }
  515. v->flags |= CVAR_ARCHIVE;
  516. }
  517. /*
  518. ============
  519. Cvar_Reset_f
  520. ============
  521. */
  522. void Cvar_Reset_f( void ) {
  523. if ( Cmd_Argc() != 2 ) {
  524. Com_Printf ("usage: reset <variable>\n");
  525. return;
  526. }
  527. Cvar_Reset( Cmd_Argv( 1 ) );
  528. }
  529. /*
  530. ============
  531. Cvar_WriteVariables
  532. Appends lines containing "set variable value" for all variables
  533. with the archive flag set to qtrue.
  534. ============
  535. */
  536. void Cvar_WriteVariables( fileHandle_t f ) {
  537. cvar_t *var;
  538. char buffer[1024];
  539. for (var = cvar_vars ; var ; var = var->next) {
  540. if( Q_stricmp( var->name, "cl_cdkey" ) == 0 ) {
  541. continue;
  542. }
  543. if( var->flags & CVAR_ARCHIVE ) {
  544. // write the latched value, even if it hasn't taken effect yet
  545. if ( var->latchedString ) {
  546. Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->latchedString);
  547. } else {
  548. Com_sprintf (buffer, sizeof(buffer), "seta %s \"%s\"\n", var->name, var->string);
  549. }
  550. FS_Printf (f, "%s", buffer);
  551. }
  552. }
  553. }
  554. /*
  555. ============
  556. Cvar_List_f
  557. ============
  558. */
  559. void Cvar_List_f( void ) {
  560. cvar_t *var;
  561. int i;
  562. char *match;
  563. if ( Cmd_Argc() > 1 ) {
  564. match = Cmd_Argv( 1 );
  565. } else {
  566. match = NULL;
  567. }
  568. i = 0;
  569. for (var = cvar_vars ; var ; var = var->next, i++)
  570. {
  571. if (match && !Com_Filter(match, var->name, qfalse)) continue;
  572. if (var->flags & CVAR_SERVERINFO) {
  573. Com_Printf("S");
  574. } else {
  575. Com_Printf(" ");
  576. }
  577. if (var->flags & CVAR_USERINFO) {
  578. Com_Printf("U");
  579. } else {
  580. Com_Printf(" ");
  581. }
  582. if (var->flags & CVAR_ROM) {
  583. Com_Printf("R");
  584. } else {
  585. Com_Printf(" ");
  586. }
  587. if (var->flags & CVAR_INIT) {
  588. Com_Printf("I");
  589. } else {
  590. Com_Printf(" ");
  591. }
  592. if (var->flags & CVAR_ARCHIVE) {
  593. Com_Printf("A");
  594. } else {
  595. Com_Printf(" ");
  596. }
  597. if (var->flags & CVAR_LATCH) {
  598. Com_Printf("L");
  599. } else {
  600. Com_Printf(" ");
  601. }
  602. if (var->flags & CVAR_CHEAT) {
  603. Com_Printf("C");
  604. } else {
  605. Com_Printf(" ");
  606. }
  607. Com_Printf (" %s \"%s\"\n", var->name, var->string);
  608. }
  609. Com_Printf ("\n%i total cvars\n", i);
  610. Com_Printf ("%i cvar indexes\n", cvar_numIndexes);
  611. }
  612. /*
  613. ============
  614. Cvar_Restart_f
  615. Resets all cvars to their hardcoded values
  616. ============
  617. */
  618. void Cvar_Restart_f( void ) {
  619. cvar_t *var;
  620. cvar_t **prev;
  621. prev = &cvar_vars;
  622. while ( 1 ) {
  623. var = *prev;
  624. if ( !var ) {
  625. break;
  626. }
  627. // don't mess with rom values, or some inter-module
  628. // communication will get broken (com_cl_running, etc)
  629. if ( var->flags & ( CVAR_ROM | CVAR_INIT | CVAR_NORESTART ) ) {
  630. prev = &var->next;
  631. continue;
  632. }
  633. // throw out any variables the user created
  634. if ( var->flags & CVAR_USER_CREATED ) {
  635. *prev = var->next;
  636. if ( var->name ) {
  637. Z_Free( var->name );
  638. }
  639. if ( var->string ) {
  640. Z_Free( var->string );
  641. }
  642. if ( var->latchedString ) {
  643. Z_Free( var->latchedString );
  644. }
  645. if ( var->resetString ) {
  646. Z_Free( var->resetString );
  647. }
  648. // clear the var completely, since we
  649. // can't remove the index from the list
  650. Com_Memset( var, 0, sizeof( var ) );
  651. continue;
  652. }
  653. Cvar_Set( var->name, var->resetString );
  654. prev = &var->next;
  655. }
  656. }
  657. /*
  658. =====================
  659. Cvar_InfoString
  660. =====================
  661. */
  662. char *Cvar_InfoString( int bit ) {
  663. static char info[MAX_INFO_STRING];
  664. cvar_t *var;
  665. info[0] = 0;
  666. for (var = cvar_vars ; var ; var = var->next) {
  667. if (var->flags & bit) {
  668. Info_SetValueForKey (info, var->name, var->string);
  669. }
  670. }
  671. return info;
  672. }
  673. /*
  674. =====================
  675. Cvar_InfoString_Big
  676. handles large info strings ( CS_SYSTEMINFO )
  677. =====================
  678. */
  679. char *Cvar_InfoString_Big( int bit ) {
  680. static char info[BIG_INFO_STRING];
  681. cvar_t *var;
  682. info[0] = 0;
  683. for (var = cvar_vars ; var ; var = var->next) {
  684. if (var->flags & bit) {
  685. Info_SetValueForKey_Big (info, var->name, var->string);
  686. }
  687. }
  688. return info;
  689. }
  690. /*
  691. =====================
  692. Cvar_InfoStringBuffer
  693. =====================
  694. */
  695. void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) {
  696. Q_strncpyz(buff,Cvar_InfoString(bit),buffsize);
  697. }
  698. /*
  699. =====================
  700. Cvar_Register
  701. basically a slightly modified Cvar_Get for the interpreted modules
  702. =====================
  703. */
  704. void Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ) {
  705. cvar_t *cv;
  706. cv = Cvar_Get( varName, defaultValue, flags );
  707. if ( !vmCvar ) {
  708. return;
  709. }
  710. vmCvar->handle = cv - cvar_indexes;
  711. vmCvar->modificationCount = -1;
  712. Cvar_Update( vmCvar );
  713. }
  714. /*
  715. =====================
  716. Cvar_Register
  717. updates an interpreted modules' version of a cvar
  718. =====================
  719. */
  720. void Cvar_Update( vmCvar_t *vmCvar ) {
  721. cvar_t *cv = NULL; // bk001129
  722. assert(vmCvar); // bk
  723. if ( (unsigned)vmCvar->handle >= cvar_numIndexes ) {
  724. Com_Error( ERR_DROP, "Cvar_Update: handle out of range" );
  725. }
  726. cv = cvar_indexes + vmCvar->handle;
  727. if ( cv->modificationCount == vmCvar->modificationCount ) {
  728. return;
  729. }
  730. if ( !cv->string ) {
  731. return; // variable might have been cleared by a cvar_restart
  732. }
  733. vmCvar->modificationCount = cv->modificationCount;
  734. // bk001129 - mismatches.
  735. if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING )
  736. Com_Error( ERR_DROP, "Cvar_Update: src %s length %d exceeds MAX_CVAR_VALUE_STRING",
  737. cv->string,
  738. strlen(cv->string),
  739. sizeof(vmCvar->string) );
  740. // bk001212 - Q_strncpyz guarantees zero padding and dest[MAX_CVAR_VALUE_STRING-1]==0
  741. // bk001129 - paranoia. Never trust the destination string.
  742. // bk001129 - beware, sizeof(char*) is always 4 (for cv->string).
  743. // sizeof(vmCvar->string) always MAX_CVAR_VALUE_STRING
  744. //Q_strncpyz( vmCvar->string, cv->string, sizeof( vmCvar->string ) ); // id
  745. Q_strncpyz( vmCvar->string, cv->string, MAX_CVAR_VALUE_STRING );
  746. vmCvar->value = cv->value;
  747. vmCvar->integer = cv->integer;
  748. }
  749. /*
  750. ============
  751. Cvar_Init
  752. Reads in all archived cvars
  753. ============
  754. */
  755. void Cvar_Init (void) {
  756. cvar_cheats = Cvar_Get("sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO );
  757. Cmd_AddCommand ("toggle", Cvar_Toggle_f);
  758. Cmd_AddCommand ("set", Cvar_Set_f);
  759. Cmd_AddCommand ("sets", Cvar_SetS_f);
  760. Cmd_AddCommand ("setu", Cvar_SetU_f);
  761. Cmd_AddCommand ("seta", Cvar_SetA_f);
  762. Cmd_AddCommand ("reset", Cvar_Reset_f);
  763. Cmd_AddCommand ("cvarlist", Cvar_List_f);
  764. Cmd_AddCommand ("cvar_restart", Cvar_Restart_f);
  765. }