doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TypeInfo.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 // This is real evil but allows the code to inspect arbitrary class variables.
30 #define private public
31 #define protected public
32 
33 #include "../../idlib/precompiled.h"
34 #pragma hdrstop
35 
36 #include "../Game_local.h"
37 
38 #ifdef ID_DEBUG_MEMORY
39 #include "GameTypeInfo.h" // Make sure this is up to date!
40 #else
41 #include "NoGameTypeInfo.h"
42 #endif
43 
44 // disabled because it's adds about 64MB to state dumps and takes a really long time
45 //#define DUMP_GAMELOCAL
46 
47 
48 typedef void (*WriteVariableType_t)( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
49 
50 
52 public:
53  static const classTypeInfo_t * FindClassInfo( const char *typeName );
54  static const enumTypeInfo_t * FindEnumInfo( const char *typeName );
55  static bool IsSubclassOf( const char *typeName, const char *superType );
56  static void PrintType( const void *typePtr, const char *typeName );
57  static void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName );
58  static void InitTypeVariables( const void *typePtr, const char *typeName, int value );
59  static void WriteGameState( const char *fileName );
60  static void CompareGameState( const char *fileName );
61 
62 private:
63  static idFile * fp;
64  static int initValue;
66  static idLexer * src;
67  static bool typeError;
68 
69  static const char * OutputString( const char *string );
70  static bool ParseTemplateArguments( idLexer &src, idStr &arguments );
71  static void PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
72  static void WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
73  static void WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
74  static void InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
75  static void VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize );
76  static int WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth );
77  static void WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth );
78 };
79 
84 bool idTypeInfoTools::typeError = false;
85 
86 
87 /*
88 ================
89 GetTypeVariableName
90 ================
91 */
92 const char *GetTypeVariableName( const char *typeName, int offset ) {
93  static char varName[1024];
94  int i;
95 
96  for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
97  if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
98  if ( classTypeInfo[i].variables[0].name != NULL && offset >= classTypeInfo[i].variables[0].offset ) {
99  break;
100  }
101  typeName = classTypeInfo[i].superType;
102  if ( *typeName == '\0' ) {
103  return "<unknown>";
104  }
105  i = -1;
106  }
107  }
108 
109  const classTypeInfo_t &classInfo = classTypeInfo[i];
110 
111  for ( i = 0; classInfo.variables[i].name != NULL; i++ ) {
112  if ( offset <= classInfo.variables[i].offset ) {
113  break;
114  }
115  }
116  if ( i == 0 ) {
117  idStr::snPrintf( varName, sizeof( varName ), "%s::<unknown>", classInfo.typeName );
118  } else {
119  idStr::snPrintf( varName, sizeof( varName ), "%s::%s", classInfo.typeName, classInfo.variables[i-1].name );
120  }
121  return varName;
122 }
123 
124 /*
125 ================
126 idTypeInfoTools::FindClassInfo
127 ================
128 */
129 const classTypeInfo_t *idTypeInfoTools::FindClassInfo( const char *typeName ) {
130  int i;
131 
132  for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
133  if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
134  return &classTypeInfo[i];
135  }
136  }
137  return NULL;
138 }
139 
140 /*
141 ================
142 idTypeInfoTools::FindEnumInfo
143 ================
144 */
145 const enumTypeInfo_t *idTypeInfoTools::FindEnumInfo( const char *typeName ) {
146  int i;
147 
148  for ( i = 0; enumTypeInfo[i].typeName != NULL; i++ ) {
149  if ( idStr::Cmp( typeName, enumTypeInfo[i].typeName ) == 0 ) {
150  return &enumTypeInfo[i];
151  }
152  }
153  return NULL;
154 }
155 
156 /*
157 ================
158 idTypeInfoTools::IsSubclassOf
159 ================
160 */
161 bool idTypeInfoTools::IsSubclassOf( const char *typeName, const char *superType ) {
162  int i;
163 
164  while( *typeName != '\0' ) {
165  if ( idStr::Cmp( typeName, superType ) == 0 ) {
166  return true;
167  }
168  for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
169  if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
170  typeName = classTypeInfo[i].superType;
171  break;
172  }
173  }
174  if ( classTypeInfo[i].typeName == NULL ) {
175  common->Warning( "super class %s not found", typeName );
176  break;
177  }
178  }
179  return false;
180 }
181 
182 /*
183 ================
184 idTypeInfoTools::OutputString
185 ================
186 */
187 const char *idTypeInfoTools::OutputString( const char *string ) {
188  static int index = 0;
189  static char buffers[4][16384];
190  char *out;
191  int i, c;
192 
193  out = buffers[index];
194  index = ( index + 1 ) & 3;
195 
196  if ( string == NULL ) {
197  return NULL;
198  }
199 
200  for ( i = 0; i < sizeof( buffers[0] ) - 2; i++ ) {
201  c = *string++;
202  switch( c ) {
203  case '\0': out[i] = '\0'; return out;
204  case '\\': out[i++] = '\\'; out[i] = '\\'; break;
205  case '\n': out[i++] = '\\'; out[i] = 'n'; break;
206  case '\r': out[i++] = '\\'; out[i] = 'r'; break;
207  case '\t': out[i++] = '\\'; out[i] = 't'; break;
208  case '\v': out[i++] = '\\'; out[i] = 'v'; break;
209  default: out[i] = c; break;
210  }
211  }
212  out[i] = '\0';
213  return out;
214 }
215 
216 /*
217 ================
218 idTypeInfoTools::ParseTemplateArguments
219 ================
220 */
222  int indent;
223  idToken token;
224 
225  arguments = "";
226 
227  if ( !src.ExpectTokenString( "<" ) ) {
228  return false;
229  }
230 
231  indent = 1;
232  while( indent ) {
233  if ( !src.ReadToken( &token ) ) {
234  break;
235  }
236  if ( token == "<" ) {
237  indent++;
238  } else if ( token == ">" ) {
239  indent--;
240  } else {
241  if ( arguments.Length() ) {
242  arguments += " ";
243  }
244  arguments += token;
245  }
246  }
247  return true;
248 }
249 
250 /*
251 ================
252 idTypeInfoTools::PrintType
253 ================
254 */
255 void idTypeInfoTools::PrintType( const void *typePtr, const char *typeName ) {
256  idTypeInfoTools::fp = NULL;
259  WriteClass_r( typePtr, "", typeName, "", "", 0 );
260 }
261 
262 /*
263 ================
264 idTypeInfoTools::WriteTypeToFile
265 ================
266 */
267 void idTypeInfoTools::WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) {
268  idTypeInfoTools::fp = fp;
271  WriteClass_r( typePtr, "", typeName, "", "", 0 );
272 }
273 
274 /*
275 ================
276 idTypeInfoTools::InitTypeVariables
277 ================
278 */
279 void idTypeInfoTools::InitTypeVariables( const void *typePtr, const char *typeName, int value ) {
280  idTypeInfoTools::fp = NULL;
283  WriteClass_r( typePtr, "", typeName, "", "", 0 );
284 }
285 
286 /*
287 ================
288 IsAllowedToChangedFromSaveGames
289 ================
290 */
291 bool IsAllowedToChangedFromSaveGames( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) {
292  if ( idStr::Icmp( scope, "idAnimator" ) == 0 ) {
293  if ( idStr::Icmp( varName, "forceUpdate" ) == 0 ) {
294  return true;
295  }
296  if ( idStr::Icmp( varName, "lastTransformTime" ) == 0 ) {
297  return true;
298  }
299  if ( idStr::Icmp( varName, "AFPoseTime" ) == 0 ) {
300  return true;
301  }
302  if ( idStr::Icmp( varName, "frameBounds" ) == 0 ) {
303  return true;
304  }
305  } else if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) {
306  if ( idStr::Icmp( varName, "touchCount" ) == 0 ) {
307  return true;
308  }
309  } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) {
310  if ( idStr::Icmp( varName, "numPVSAreas" ) == 0 ) {
311  return true;
312  }
313  if ( idStr::Icmp( varName, "renderView" ) == 0 ) {
314  return true;
315  }
316  } else if ( idStr::Icmp( scope, "idBrittleFracture" ) == 0 ) {
317  if ( idStr::Icmp( varName, "changed" ) == 0 ) {
318  return true;
319  }
320  } else if ( idStr::Icmp( scope, "idPhysics_AF" ) == 0 ) {
321  return true;
322  } else if ( idStr::Icmp( scope, "renderEntity_t" ) == 0 ) {
323  // These get fixed up when UpdateVisuals is called
324  if ( idStr::Icmp( varName, "origin" ) == 0 ) {
325  return true;
326  }
327  if ( idStr::Icmp( varName, "axis" ) == 0 ) {
328  return true;
329  }
330  if ( idStr::Icmp( varName, "bounds" ) == 0 ) {
331  return true;
332  }
333  }
334 
335  if ( idStr::Icmpn( prefix, "idAFEntity_Base::af.idAF::physicsObj.idPhysics_AF", 49) == 0 ) {
336  return true;
337  }
338 
339  return false;
340 }
341 
342 /*
343 ================
344 IsRenderHandleVariable
345 ================
346 */
347 bool IsRenderHandleVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) {
348  if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) {
349  if ( idStr::Icmp( varName, "renderModelHandle" ) == 0 ) {
350  return true;
351  }
352  } else if ( idStr::Icmp( scope, "idFXLocalAction" ) == 0 ) {
353  if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
354  return true;
355  }
356  if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) {
357  return true;
358  }
359  } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) {
360  if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) {
361  return true;
362  }
363  } else if ( idStr::Icmp( scope, "idLight" ) == 0 ) {
364  if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
365  return true;
366  }
367  } else if ( idStr::Icmp( scope, "idAFEntity_Gibbable" ) == 0 ) {
368  if ( idStr::Icmp( varName, "skeletonModelDefHandle" ) == 0 ) {
369  return true;
370  }
371  } else if ( idStr::Icmp( scope, "idAFEntity_SteamPipe" ) == 0 ) {
372  if ( idStr::Icmp( varName, "steamModelHandle" ) == 0 ) {
373  return true;
374  }
375  } else if ( idStr::Icmp( scope, "idItem" ) == 0 ) {
376  if ( idStr::Icmp( varName, "itemShellHandle" ) == 0 ) {
377  return true;
378  }
379  } else if ( idStr::Icmp( scope, "idExplodingBarrel" ) == 0 ) {
380  if ( idStr::Icmp( varName, "particleModelDefHandle" ) == 0 ) {
381  return true;
382  }
383  if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
384  return true;
385  }
386  } else if ( idStr::Icmp( scope, "idProjectile" ) == 0 ) {
387  if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
388  return true;
389  }
390  } else if ( idStr::Icmp( scope, "idBFGProjectile" ) == 0 ) {
391  if ( idStr::Icmp( varName, "secondModelDefHandle" ) == 0 ) {
392  return true;
393  }
394  } else if ( idStr::Icmp( scope, "idSmokeParticles" ) == 0 ) {
395  if ( idStr::Icmp( varName, "renderEntityHandle" ) == 0 ) {
396  return true;
397  }
398  } else if ( idStr::Icmp( scope, "idWeapon" ) == 0 ) {
399  if ( idStr::Icmp( varName, "muzzleFlashHandle" ) == 0 ) {
400  return true;
401  }
402  if ( idStr::Icmp( varName, "worldMuzzleFlashHandle" ) == 0 ) {
403  return true;
404  }
405  if ( idStr::Icmp( varName, "guiLightHandle" ) == 0 ) {
406  return true;
407  }
408  if ( idStr::Icmp( varName, "nozzleGlowHandle" ) == 0 ) {
409  return true;
410  }
411  }
412  return false;
413 }
414 
415 /*
416 ================
417 idTypeInfoTools::PrintVariable
418 ================
419 */
420 void idTypeInfoTools::PrintVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) {
421  common->Printf( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
422 }
423 
424 /*
425 ================
426 idTypeInfoTools::WriteVariable
427 ================
428 */
429 void idTypeInfoTools::WriteVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) {
430 
431  for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) {
432  if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 ||
433  idStr::Icmpn( value+i+1, "IND", 3 ) == 0 ||
434  idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 ||
435  idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 ||
436  idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) {
437  common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value );
438  break;
439  }
440  }
441  fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
442 }
443 
444 /*
445 ================
446 idTypeInfoTools::WriteGameStateVariable
447 ================
448 */
449 void idTypeInfoTools::WriteGameStateVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) {
450 
451  for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) {
452  if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 ||
453  idStr::Icmpn( value+i+1, "IND", 3 ) == 0 ||
454  idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 ||
455  idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 ||
456  idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) {
457  common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value );
458  break;
459  }
460  }
461 
462  if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
463  return;
464  }
465 
466  if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) {
467  return;
468  }
469 
470  fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
471 }
472 
473 /*
474 ================
475 idTypeInfoTools::InitVariable
476 ================
477 */
478 void idTypeInfoTools::InitVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) {
479  if ( varPtr != NULL && varSize > 0 ) {
480  // NOTE: skip renderer handles
481  if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
482  return;
483  }
484  memset( const_cast<void*>(varPtr), initValue, varSize );
485  }
486 }
487 
488 /*
489 ================
490 idTypeInfoTools::VerifyVariable
491 ================
492 */
493 void idTypeInfoTools::VerifyVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize ) {
494  idToken token;
495 
496  if ( typeError ) {
497  return;
498  }
499 
500  src->SkipUntilString( "=" );
501  src->ExpectTokenType( TT_STRING, 0, &token );
502  if ( token.Cmp( value ) != 0 ) {
503 
504  // NOTE: skip several things
505 
506  if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
507  return;
508  }
509 
510  if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) {
511  return;
512  }
513 
514  src->Warning( "state diff for %s%s::%s%s\n%s\n%s", prefix, scope, varName, postfix, token.c_str(), value );
515  typeError = true;
516  }
517 }
518 
519 /*
520 ================
521 idTypeInfoTools::WriteVariable_r
522 ================
523 */
524 int idTypeInfoTools::WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ) {
525  int i, isPointer, typeSize;
526  idLexer typeSrc;
527  idToken token;
528  idStr typeString, templateArgs;
529 
530  isPointer = 0;
531  typeSize = -1;
532 
533  // create a type string without 'const', 'mutable', 'class', 'struct', 'union'
534  typeSrc.LoadMemory( varType, idStr::Length( varType ), varName );
535  while( typeSrc.ReadToken( &token ) ) {
536  if ( token != "const" && token != "mutable" && token != "class" && token != "struct" && token != "union" ) {
537  typeString += token + " ";
538  }
539  }
540  typeString.StripTrailing( ' ' );
541  typeSrc.FreeSource();
542 
543  // if this is an array
544  if ( typeString[typeString.Length() - 1] == ']' ) {
545  for ( i = typeString.Length(); i > 0 && typeString[i - 1] != '['; i-- ) {
546  }
547  int num = atoi( &typeString[i] );
548  idStr listVarType = typeString;
549  listVarType.CapLength( i - 1 );
550  typeSize = 0;
551  for ( i = 0; i < num; i++ ) {
552  idStr listVarName = va( "%s[%d]", varName, i );
553  int size = WriteVariable_r( varPtr, listVarName, listVarType, scope, prefix, pointerDepth );
554  typeSize += size;
555  if ( size == -1 ) {
556  break;
557  }
558  varPtr = (void *)( ( (byte *) varPtr ) + size );
559  }
560  return typeSize;
561  }
562 
563  // if this is a pointer
564  isPointer = 0;
565  for ( i = typeString.Length(); i > 0 && typeString[i - 1] == '*'; i -= 2 ) {
566  if ( varPtr == (void *)0xcdcdcdcd || ( varPtr != NULL && *((unsigned long *)varPtr) == 0xcdcdcdcd ) ) {
567  common->Warning( "%s%s::%s%s references uninitialized memory", prefix, scope, varName, "" );
568  return typeSize;
569  }
570  if ( varPtr != NULL ) {
571  varPtr = *((void **)varPtr);
572  }
573  isPointer++;
574  }
575 
576  if ( varPtr == NULL ) {
577  Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, 0 );
578  return sizeof( void * );
579  }
580 
581  typeSrc.LoadMemory( typeString, typeString.Length(), varName );
582 
583  if ( !typeSrc.ReadToken( &token ) ) {
584  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
585  return -1;
586  }
587 
588  // get full type
589  while( typeSrc.CheckTokenString( "::" ) ) {
590  idToken newToken;
591  typeSrc.ExpectTokenType( TT_NAME, 0, &newToken );
592  token += "::" + newToken;
593  }
594 
595  if ( token == "signed" ) {
596 
597  if ( !typeSrc.ReadToken( &token ) ) {
598  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
599  return -1;
600  }
601  if ( token == "char" ) {
602 
603  typeSize = sizeof( signed char );
604  Write( varName, varType, scope, prefix, "", va( "%d", *((signed char *)varPtr) ), varPtr, typeSize );
605 
606  } else if ( token == "short" ) {
607 
608  typeSize = sizeof( signed short );
609  Write( varName, varType, scope, prefix, "", va( "%d", *((signed short *)varPtr) ), varPtr, typeSize );
610 
611  } else if ( token == "int" ) {
612 
613  typeSize = sizeof( signed int );
614  Write( varName, varType, scope, prefix, "", va( "%d", *((signed int *)varPtr) ), varPtr, typeSize );
615 
616  } else if ( token == "long" ) {
617 
618  typeSize = sizeof( signed long );
619  Write( varName, varType, scope, prefix, "", va( "%ld", *((signed long *)varPtr) ), varPtr, typeSize );
620 
621  } else {
622 
623  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
624  return -1;
625  }
626 
627  } else if ( token == "unsigned" ) {
628 
629  if ( !typeSrc.ReadToken( &token ) ) {
630  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
631  return -1;
632  }
633  if ( token == "char" ) {
634 
635  typeSize = sizeof( unsigned char );
636  Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned char *)varPtr) ), varPtr, typeSize );
637 
638  } else if ( token == "short" ) {
639 
640  typeSize = sizeof( unsigned short );
641  Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned short *)varPtr) ), varPtr, typeSize );
642 
643  } else if ( token == "int" ) {
644 
645  typeSize = sizeof( unsigned int );
646  Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned int *)varPtr) ), varPtr, typeSize );
647 
648  } else if ( token == "long" ) {
649 
650  typeSize = sizeof( unsigned long );
651  Write( varName, varType, scope, prefix, "", va( "%lu", *((unsigned long *)varPtr) ), varPtr, typeSize );
652 
653  } else {
654 
655  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
656  return -1;
657  }
658 
659  } else if ( token == "byte" ) {
660 
661  typeSize = sizeof( byte );
662  Write( varName, varType, scope, prefix, "", va( "%d", *((byte *)varPtr) ), varPtr, typeSize );
663 
664  } else if ( token == "word" ) {
665 
666  typeSize = sizeof( word );
667  Write( varName, varType, scope, prefix, "", va( "%d", *((word *)varPtr) ), varPtr, typeSize );
668 
669  } else if ( token == "dword" ) {
670 
671  typeSize = sizeof( dword );
672  Write( varName, varType, scope, prefix, "", va( "%d", *((dword *)varPtr) ), varPtr, typeSize );
673 
674  } else if ( token == "bool" ) {
675 
676  typeSize = sizeof( bool );
677  Write( varName, varType, scope, prefix, "", va( "%d", *((bool *)varPtr) ), varPtr, typeSize );
678 
679  } else if ( token == "char" ) {
680 
681  typeSize = sizeof( char );
682  Write( varName, varType, scope, prefix, "", va( "%d", *((char *)varPtr) ), varPtr, typeSize );
683 
684  } else if ( token == "short" ) {
685 
686  typeSize = sizeof( short );
687  Write( varName, varType, scope, prefix, "", va( "%d", *((short *)varPtr) ), varPtr, typeSize );
688 
689  } else if ( token == "int" ) {
690 
691  typeSize = sizeof( int );
692  Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
693 
694  } else if ( token == "long" ) {
695 
696  typeSize = sizeof( long );
697  Write( varName, varType, scope, prefix, "", va( "%ld", *((long *)varPtr) ), varPtr, typeSize );
698 
699  } else if ( token == "float" ) {
700 
701  typeSize = sizeof( float );
702  Write( varName, varType, scope, prefix, "", idStr( *((float *)varPtr) ).c_str(), varPtr, typeSize );
703 
704  } else if ( token == "double" ) {
705 
706  typeSize = sizeof( double );
707  Write( varName, varType, scope, prefix, "", idStr( (float)*((double *)varPtr) ).c_str(), varPtr, typeSize );
708 
709  } else if ( token == "idVec2" ) {
710 
711  typeSize = sizeof( idVec2 );
712  Write( varName, varType, scope, prefix, "", ((idVec2 *)varPtr)->ToString( 8 ), varPtr, typeSize );
713 
714  } else if ( token == "idVec3" ) {
715 
716  typeSize = sizeof( idVec3 );
717  Write( varName, varType, scope, prefix, "", ((idVec3 *)varPtr)->ToString( 8 ), varPtr, typeSize );
718 
719  } else if ( token == "idVec4" ) {
720 
721  typeSize = sizeof( idVec4 );
722  Write( varName, varType, scope, prefix, "", ((idVec4 *)varPtr)->ToString( 8 ), varPtr, typeSize );
723 
724  } else if ( token == "idVec5" ) {
725 
726  typeSize = sizeof( idVec5 );
727  Write( varName, varType, scope, prefix, "", ((idVec5 *)varPtr)->ToString( 8 ), varPtr, typeSize );
728 
729  } else if ( token == "idVec6" ) {
730 
731  typeSize = sizeof( idVec6 );
732  Write( varName, varType, scope, prefix, "", ((idVec6 *)varPtr)->ToString( 8 ), varPtr, typeSize );
733 
734  } else if ( token == "idVecX" ) {
735 
736  const idVecX *vec = ((idVecX *)varPtr);
737  if ( vec->ToFloatPtr() != NULL ) {
738  Write( varName, varType, scope, prefix, "", vec->ToString( 8 ), vec->ToFloatPtr(), vec->GetSize() * sizeof( float ) );
739  } else {
740  Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, 0 );
741  }
742  typeSize = sizeof( idVecX );
743 
744  } else if ( token == "idMat2" ) {
745 
746  typeSize = sizeof( idMat2 );
747  Write( varName, varType, scope, prefix, "", ((idMat2 *)varPtr)->ToString( 8 ), varPtr, typeSize );
748 
749  } else if ( token == "idMat3" ) {
750 
751  typeSize = sizeof( idMat3 );
752  Write( varName, varType, scope, prefix, "", ((idMat3 *)varPtr)->ToString( 8 ), varPtr, typeSize );
753 
754  } else if ( token == "idMat4" ) {
755 
756  typeSize = sizeof( idMat4 );
757  Write( varName, varType, scope, prefix, "", ((idMat4 *)varPtr)->ToString( 8 ), varPtr, typeSize );
758 
759  } else if ( token == "idMat5" ) {
760 
761  typeSize = sizeof( idMat5 );
762  Write( varName, varType, scope, prefix, "", ((idMat5 *)varPtr)->ToString( 8 ), varPtr, typeSize );
763 
764  } else if ( token == "idMat6" ) {
765 
766  typeSize = sizeof( idMat6 );
767  Write( varName, varType, scope, prefix, "", ((idMat6 *)varPtr)->ToString( 8 ), varPtr, typeSize );
768 
769  } else if ( token == "idMatX" ) {
770 
771  typeSize = sizeof( idMatX );
772  const idMatX *mat = ((idMatX *)varPtr);
773  if ( mat->ToFloatPtr() != NULL ) {
774  Write( varName, varType, scope, prefix, "", mat->ToString( 8 ), mat->ToFloatPtr(), mat->GetNumColumns() * mat->GetNumRows() * sizeof( float ) );
775  } else {
776  Write( varName, varType, scope, prefix, "", "<NULL>", NULL, 0 );
777  }
778 
779  } else if ( token == "idAngles" ) {
780 
781  typeSize = sizeof( idAngles );
782  Write( varName, varType, scope, prefix, "", ((idAngles *)varPtr)->ToString( 8 ), varPtr, typeSize );
783 
784  } else if ( token == "idQuat" ) {
785 
786  typeSize = sizeof( idQuat );
787  Write( varName, varType, scope, prefix, "", ((idQuat *)varPtr)->ToString( 8 ), varPtr, typeSize );
788 
789  } else if ( token == "idBounds" ) {
790 
791  typeSize = sizeof( idBounds );
792  const idBounds *bounds = ((idBounds *)varPtr);
793  if ( bounds->IsCleared() ) {
794  Write( varName, varType, scope, prefix, "", "<cleared>", varPtr, typeSize );
795  } else {
796  Write( varName, varType, scope, prefix, "", va( "(%s)-(%s)", (*bounds)[0].ToString( 8 ), (*bounds)[1].ToString( 8 ) ), varPtr, typeSize );
797  }
798 
799  } else if ( token == "idList" ) {
800 
801  idList<int> *list = ((idList<int> *)varPtr);
802  Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 );
803  // NOTE: we don't care about the amount of memory allocated
804  //Write( varName, varType, scope, prefix, ".size", va( "%d", list->Size() ), NULL, 0 );
805  Write( varName, varType, scope, prefix, ".granularity", va( "%d", list->GetGranularity() ), NULL, 0 );
806 
807  if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) {
808  void *listVarPtr = list->Ptr();
809  for ( i = 0; i < list->Num(); i++ ) {
810  idStr listVarName = va( "%s[%d]", varName, i );
811  int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth );
812  if ( size == -1 ) {
813  break;
814  }
815  listVarPtr = (void *)( ( (byte *) listVarPtr ) + size );
816  }
817  }
818 
819  typeSize = sizeof( idList<int> );
820 
821  } else if ( token == "idStaticList" ) {
822 
823  idStaticList<int, 1> *list = ((idStaticList<int, 1> *)varPtr);
824  Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 );
825 
826  int totalSize = 0;
827  if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) {
828  void *listVarPtr = list->Ptr();
829  for ( i = 0; i < list->Num(); i++ ) {
830  idStr listVarName = va( "%s[%d]", varName, i );
831  int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth );
832  if ( size == -1 ) {
833  break;
834  }
835  totalSize += size;
836  listVarPtr = (void *)( ( (byte *) listVarPtr ) + size );
837  }
838  }
839 
840  typeSize = sizeof( int ) + totalSize;
841 
842  } else if ( token == "idLinkList" ) {
843 
844  // FIXME: implement
845  typeSize = sizeof( idLinkList<idEntity> );
846  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), NULL, 0 );
847 
848  } else if ( token == "idStr" ) {
849 
850  typeSize = sizeof( idStr );
851 
852  const idStr *str = ((idStr *)varPtr);
853  Write( varName, varType, scope, prefix, "", OutputString( str->c_str() ), str->c_str(), str->Length() );
854 
855  } else if ( token == "idStrList" ) {
856 
857  typeSize = sizeof( idStrList );
858 
859  const idStrList *list = ((idStrList *)varPtr);
860  if ( list->Num() ) {
861  for ( i = 0; i < list->Num(); i++ ) {
862  Write( varName, varType, scope, prefix, va("[%d]", i ), OutputString( (*list)[i].c_str() ), (*list)[i].c_str(), (*list)[i].Length() );
863  }
864  } else {
865  Write( varName, varType, scope, prefix, "", "<empty>", NULL, 0 );
866  }
867 
868  } else if ( token == "idDict" ) {
869 
870  typeSize = sizeof( idDict );
871 
872  const idDict *dict = ((idDict *)varPtr);
873  if ( dict->GetNumKeyVals() ) {
874  for ( i = 0; i < dict->GetNumKeyVals(); i++ ) {
875  const idKeyValue *kv = dict->GetKeyVal( i );
876  Write( varName, varType, scope, prefix, va("[%d]", i ), va( "\'%s\' \'%s\'", OutputString( kv->GetKey().c_str() ), OutputString( kv->GetValue().c_str() ) ), NULL, 0 );
877  }
878  } else {
879  Write( varName, varType, scope, prefix, "", "<empty>", NULL, 0 );
880  }
881 
882  } else if ( token == "idExtrapolate" ) {
883 
884  const idExtrapolate<float> *interpolate = ((idExtrapolate<float> *)varPtr);
885  Write( varName, varType, scope, prefix, ".extrapolationType", idStr( interpolate->GetExtrapolationType() ).c_str(), &interpolate->extrapolationType, sizeof( interpolate->extrapolationType ) );
886  Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
887  Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) );
888 
889  if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
890  if ( templateArgs == "int" ) {
891  const idExtrapolate<int> *interpolate = ((idExtrapolate<int> *)varPtr);
892  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
893  Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
894  Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) );
895  typeSize = sizeof( idExtrapolate<int> );
896  } else if ( templateArgs == "float" ) {
897  const idExtrapolate<float> *interpolate = ((idExtrapolate<float> *)varPtr);
898  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
899  Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
900  Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) );
901  typeSize = sizeof( idExtrapolate<float> );
902  } else if ( templateArgs == "idVec3" ) {
903  const idExtrapolate<idVec3> *interpolate = ((idExtrapolate<idVec3> *)varPtr);
904  Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) );
905  Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
906  Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) );
907  typeSize = sizeof( idExtrapolate<idVec3> );
908  } else if ( templateArgs == "idAngles" ) {
909  const idExtrapolate<idAngles> *interpolate = ((idExtrapolate<idAngles> *)varPtr);
910  Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) );
911  Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
912  Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) );
913  typeSize = sizeof( idExtrapolate<idAngles> );
914  } else {
915  Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idExtrapolate>", templateArgs.c_str() ), NULL, 0 );
916  }
917  }
918 
919  } else if ( token == "idInterpolate" ) {
920 
921  const idInterpolate<float> *interpolate = ((idInterpolate<float> *)varPtr);
922  Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
923  Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) );
924 
925  if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
926  if ( templateArgs == "int" ) {
927  const idInterpolate<int> *interpolate = ((idInterpolate<int> *)varPtr);
928  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
929  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
930  typeSize = sizeof( idInterpolate<int> );
931  } else if ( templateArgs == "float" ) {
932  const idInterpolate<float> *interpolate = ((idInterpolate<float> *)varPtr);
933  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
934  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
935  typeSize = sizeof( idInterpolate<float> );
936  } else {
937  Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolate>", templateArgs.c_str() ), NULL, 0 );
938  }
939  }
940 
941  } else if ( token == "idInterpolateAccelDecelLinear" ) {
942 
944  Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
945  Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) );
946  Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) );
947  Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) );
948 
949  if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
950  if ( templateArgs == "int" ) {
952  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
953  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
954  typeSize = sizeof( idInterpolateAccelDecelLinear<int> );
955  } else if ( templateArgs == "float" ) {
957  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
958  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
959  typeSize = sizeof( idInterpolateAccelDecelLinear<float> );
960  } else {
961  Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolateAccelDecelLinear>", templateArgs.c_str() ), NULL, 0 );
962  }
963  }
964 
965  } else if ( token == "idInterpolateAccelDecelSine" ) {
966 
968  Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
969  Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) );
970  Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) );
971  Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) );
972 
973  if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
974  if ( templateArgs == "int" ) {
976  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
977  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
978  typeSize = sizeof( idInterpolateAccelDecelSine<int> );
979  } else if ( templateArgs == "float" ) {
981  Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
982  Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
983  typeSize = sizeof( idInterpolateAccelDecelSine<float> );
984  } else {
985  Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolateAccelDecelSine>", templateArgs.c_str() ), NULL, 0 );
986  }
987  }
988 
989  } else if ( token == "idUserInterface" ) {
990 
991  typeSize = sizeof( idUserInterface );
992  const idUserInterface *gui = ((idUserInterface *)varPtr);
993  Write( varName, varType, scope, prefix, "", gui->Name(), varPtr, sizeof( varPtr ) );
994 
995  } else if ( token == "idRenderModel" ) {
996 
997  typeSize = sizeof( idRenderModel );
998  const idRenderModel *model = ((idRenderModel *)varPtr);
999  Write( varName, varType, scope, prefix, "", model->Name(), varPtr, sizeof( varPtr ) );
1000 
1001  } else if ( token == "qhandle_t" ) {
1002 
1003  typeSize = sizeof( int );
1004  Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
1005 
1006  } else if ( token == "cmHandle_t" ) {
1007 
1008  typeSize = sizeof( int );
1009  Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
1010 
1011  } else if ( token == "idEntityPtr" ) {
1012 
1013  typeSize = sizeof( idEntityPtr<idEntity> );
1014 
1015  const idEntityPtr<idEntity> *entPtr = ((idEntityPtr<idEntity> *)varPtr);
1016  if ( entPtr->GetEntity() ) {
1017  idEntity *entity = entPtr->GetEntity();
1018  Write( varName, varType, scope, prefix, ".", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), varPtr, typeSize );
1019  } else {
1020  Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, typeSize );
1021  }
1022 
1023  } else if ( token == "idEntity::entityFlags_s" ) {
1024 
1025  const idEntity::entityFlags_s *flags = ((idEntity::entityFlags_s *)varPtr);
1026  Write( varName, varType, scope, prefix, ".notarget", flags->notarget ? "true" : "false", NULL, 0 );
1027  Write( varName, varType, scope, prefix, ".noknockback", flags->noknockback ? "true" : "false", NULL, 0 );
1028  Write( varName, varType, scope, prefix, ".takedamage", flags->takedamage ? "true" : "false", NULL, 0 );
1029  Write( varName, varType, scope, prefix, ".hidden", flags->hidden ? "true" : "false", NULL, 0 );
1030  Write( varName, varType, scope, prefix, ".bindOrientated", flags->bindOrientated ? "true" : "false", NULL, 0 );
1031  Write( varName, varType, scope, prefix, ".solidForTeam", flags->solidForTeam ? "true" : "false", NULL, 0 );
1032  Write( varName, varType, scope, prefix, ".forcePhysicsUpdate", flags->forcePhysicsUpdate ? "true" : "false", NULL, 0 );
1033  Write( varName, varType, scope, prefix, ".selected", flags->selected ? "true" : "false", NULL, 0 );
1034  Write( varName, varType, scope, prefix, ".neverDormant", flags->neverDormant ? "true" : "false", NULL, 0 );
1035  Write( varName, varType, scope, prefix, ".isDormant", flags->isDormant ? "true" : "false", NULL, 0 );
1036  Write( varName, varType, scope, prefix, ".hasAwakened", flags->hasAwakened ? "true" : "false", NULL, 0 );
1037  Write( varName, varType, scope, prefix, ".networkSync", flags->networkSync ? "true" : "false", NULL, 0 );
1038  typeSize = sizeof( idEntity::entityFlags_s );
1039 
1040  } else if ( token == "idScriptBool" ) {
1041 
1042  typeSize = sizeof( idScriptBool );
1043 
1044  const idScriptBool *scriptBool = ((idScriptBool *)varPtr);
1045  if ( scriptBool->IsLinked() ) {
1046  Write( varName, varType, scope, prefix, "", ( *scriptBool != 0 ) ? "true" : "false", varPtr, typeSize );
1047  } else {
1048  Write( varName, varType, scope, prefix, "", "<not linked>", varPtr, typeSize );
1049  }
1050 
1051  } else {
1052 
1053  const classTypeInfo_t *classTypeInfo = FindClassInfo( scope + ( "::" + token ) );
1054  if ( classTypeInfo == NULL ) {
1055  classTypeInfo = FindClassInfo( token );
1056  }
1057  if ( classTypeInfo != NULL ) {
1058 
1059  typeSize = classTypeInfo->size;
1060 
1061  if ( !isPointer ) {
1062 
1063  char newPrefix[1024];
1064  idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s.", prefix, scope, varName );
1065  WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth );
1066 
1067  } else if ( token == "idAnim" ) {
1068 
1069  const idAnim *anim = ((idAnim*)varPtr);
1070  Write( varName, varType, scope, prefix, "", anim->Name(), NULL, 0 );
1071 
1072  } else if ( token == "idPhysics" ) {
1073 
1074  const idPhysics *physics = ((idPhysics*)varPtr);
1075  Write( varName, varType, scope, prefix, "", physics->GetType()->classname, NULL, 0 );
1076 
1077  } else if ( IsSubclassOf( token, "idEntity" ) ) {
1078 
1079  const idEntity *entity = ((idEntity*)varPtr);
1080  Write( varName, varType, scope, prefix, "", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), NULL, 0 );
1081 
1082  } else if ( IsSubclassOf( token, "idDecl" ) ) {
1083 
1084  const idDecl *decl = ((idDecl *)varPtr);
1085  Write( varName, varType, scope, prefix, "", decl->GetName(), NULL, 0 );
1086 
1087  } else if ( pointerDepth == 0 && (
1088  token == "idAFBody" ||
1089  token == "idAFTree" ||
1090  token == "idClipModel" ||
1091  IsSubclassOf( token, "idAFConstraint" )
1092  ) ) {
1093 
1094  char newPrefix[1024];
1095  idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s->", prefix, scope, varName );
1096  WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth + 1 );
1097 
1098  } else {
1099 
1100  Write( varName, varType, scope, prefix, "", va( "<pointer type '%s' not listed>", varType ), NULL, 0 );
1101  return -1;
1102  }
1103  } else {
1104  const enumTypeInfo_t *enumTypeInfo = FindEnumInfo( scope + ( "::" + token ) );
1105  if ( enumTypeInfo == NULL ) {
1106  enumTypeInfo = FindEnumInfo( token );
1107  }
1108  if ( enumTypeInfo != NULL ) {
1109 
1110  typeSize = sizeof( int ); // NOTE: assuming sizeof( enum ) is sizeof( int )
1111 
1112  for ( i = 0; enumTypeInfo->values[i].name != NULL; i++ ) {
1113  if ( *((int *)varPtr) == enumTypeInfo->values[i].value ) {
1114  break;
1115  }
1116  }
1117  if ( enumTypeInfo->values[i].name != NULL ) {
1118  Write( varName, varType, scope, prefix, "", enumTypeInfo->values[i].name, NULL, 0 );
1119  } else {
1120  Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), NULL, 0 );
1121  }
1122 
1123  } else {
1124  Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), NULL, 0 );
1125  return -1;
1126  }
1127  }
1128  }
1129 
1130  i = 0;
1131  do {
1132  if ( *((unsigned long *)varPtr) == 0xcdcdcdcd ) {
1133  common->Warning( "%s%s::%s%s uses uninitialized memory", prefix, scope, varName, "" );
1134  break;
1135  }
1136  } while( ++i < typeSize );
1137 
1138  if ( isPointer ) {
1139  return sizeof( void * );
1140  }
1141  return typeSize;
1142 }
1143 
1144 /*
1145 ================
1146 idTypeInfoTools::WriteClass_r
1147 ================
1148 */
1149 void idTypeInfoTools::WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ) {
1150  int i;
1151 
1152  const classTypeInfo_t *classInfo = FindClassInfo( classType );
1153  if ( !classInfo ) {
1154  return;
1155  }
1156  if ( *classInfo->superType != '\0' ) {
1157  WriteClass_r( classPtr, className, classInfo->superType, scope, prefix, pointerDepth );
1158  }
1159 
1160  for ( i = 0; classInfo->variables[i].name != NULL; i++ ) {
1161  const classVariableInfo_t &classVar = classInfo->variables[i];
1162 
1163  void *varPtr = (void *) (((byte *)classPtr) + classVar.offset);
1164 
1165  WriteVariable_r( varPtr, classVar.name, classVar.type, classType, prefix, pointerDepth );
1166  }
1167 }
1168 
1169 /*
1170 ================
1171 idTypeInfoTools::WriteGameState
1172 ================
1173 */
1174 void idTypeInfoTools::WriteGameState( const char *fileName ) {
1175  int i, num;
1176  idFile *file;
1177 
1178  file = fileSystem->OpenFileWrite( fileName );
1179  if ( !file ) {
1180  common->Warning( "couldn't open %s", fileName );
1181  return;
1182  }
1183 
1184  fp = file;
1185  Write = WriteGameStateVariable; //WriteVariable;
1186 
1187 #ifdef DUMP_GAMELOCAL
1188 
1189  file->WriteFloatString( "\ngameLocal {\n" );
1190  WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 );
1191  file->WriteFloatString( "}\n" );
1192 
1193 #endif
1194 
1195  for ( num = i = 0; i < gameLocal.num_entities; i++ ) {
1196  idEntity *ent = gameLocal.entities[i];
1197  if ( ent == NULL ) {
1198  continue;
1199  }
1200  file->WriteFloatString( "\nentity %d %s {\n", i, ent->GetType()->classname );
1201  WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 );
1202  file->WriteFloatString( "}\n" );
1203  num++;
1204  }
1205 
1206  fileSystem->CloseFile( file );
1207 
1208  common->Printf( "%d entities written\n", num );
1209 }
1210 
1211 /*
1212 ================
1213 idTypeInfoTools::CompareGameState
1214 ================
1215 */
1216 void idTypeInfoTools::CompareGameState( const char *fileName ) {
1217  int entityNum;
1218  idToken token;
1219 
1220  src = new idLexer();
1221  src->SetFlags( LEXFL_NOSTRINGESCAPECHARS );
1222 
1223  if ( !src->LoadFile( fileName ) ) {
1224  common->Warning( "couldn't load %s", fileName );
1225  delete src;
1226  src = NULL;
1227  return;
1228  }
1229 
1230  fp = NULL;
1232 
1233 #ifdef DUMP_GAMELOCAL
1234 
1235  if ( !src->ExpectTokenString( "gameLocal" ) || !src->ExpectTokenString( "{" ) ) {
1236  delete src;
1237  src = NULL;
1238  return;
1239  }
1240 
1241  WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 );
1242 
1243  if ( !src->ExpectTokenString( "}" ) ) {
1244  delete src;
1245  src = NULL;
1246  return;
1247  }
1248 
1249 #endif
1250 
1251  while( src->ReadToken( &token ) ) {
1252  if ( token != "entity" ) {
1253  break;
1254  }
1255  if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) {
1256  break;
1257  }
1258 
1259  entityNum = token.GetIntValue();
1260 
1261  if ( entityNum < 0 || entityNum >= gameLocal.num_entities ) {
1262  src->Warning( "entity number %d out of range", entityNum );
1263  break;
1264  }
1265 
1266  typeError = false;
1267 
1268  idEntity *ent = gameLocal.entities[entityNum];
1269  if ( !ent ) {
1270  src->Warning( "entity %d is not spawned", entityNum );
1271  src->SkipBracedSection( true );
1272  continue;
1273  }
1274 
1275  if ( !src->ExpectTokenType( TT_NAME, 0, &token ) ) {
1276  break;
1277  }
1278 
1279  if ( token.Cmp( ent->GetType()->classname ) != 0 ) {
1280  src->Warning( "entity %d has wrong type", entityNum );
1281  src->SkipBracedSection( true );
1282  continue;
1283  }
1284 
1285  if ( !src->ExpectTokenString( "{" ) ) {
1286  src->Warning( "entity %d missing leading {", entityNum );
1287  break;
1288  }
1289 
1290  WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 );
1291 
1292  if ( !src->SkipBracedSection( false ) ) {
1293  src->Warning( "entity %d missing trailing }", entityNum );
1294  break;
1295  }
1296  }
1297 
1298  delete src;
1299  src = NULL;
1300 }
1301 
1302 /*
1303 ================
1304 WriteGameState_f
1305 ================
1306 */
1307 void WriteGameState_f( const idCmdArgs &args ) {
1308  idStr fileName;
1309 
1310  if ( args.Argc() > 1 ) {
1311  fileName = args.Argv(1);
1312  } else {
1313  fileName = "GameState.txt";
1314  }
1315  fileName.SetFileExtension( "gameState.txt" );
1316 
1317  idTypeInfoTools::WriteGameState( fileName );
1318 }
1319 
1320 /*
1321 ================
1322 CompareGameState_f
1323 ================
1324 */
1325 void CompareGameState_f( const idCmdArgs &args ) {
1326  idStr fileName;
1327 
1328  if ( args.Argc() > 1 ) {
1329  fileName = args.Argv(1);
1330  } else {
1331  fileName = "GameState.txt";
1332  }
1333  fileName.SetFileExtension( "gameState.txt" );
1334 
1336 }
1337 
1338 /*
1339 ================
1340 TestSaveGame_f
1341 ================
1342 */
1343 void TestSaveGame_f( const idCmdArgs &args ) {
1344  idStr name;
1345 
1346  if ( args.Argc() <= 1 ) {
1347  gameLocal.Printf( "testSaveGame <mapName>\n" );
1348  return;
1349  }
1350 
1351  name = args.Argv( 1 );
1352 
1353  try {
1354  cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "map %s", name.c_str() ) );
1355  name.Replace( "\\", "_" );
1356  name.Replace( "/", "_" );
1357  cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "saveGame test_%s", name.c_str() ) );
1358  cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "loadGame test_%s", name.c_str() ) );
1359  }
1360  catch( idException & ) {
1361  // an ERR_DROP was thrown
1362  }
1364 }
1365 
1366 /*
1367 ================
1368 WriteTypeToFile
1369 ================
1370 */
1371 void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) {
1372  idTypeInfoTools::WriteTypeToFile( fp, typePtr, typeName );
1373 }
1374 
1375 /*
1376 ================
1377 PrintType
1378 ================
1379 */
1380 void PrintType( const void *typePtr, const char *typeName ) {
1381  idTypeInfoTools::PrintType( typePtr, typeName );
1382 }
1383 
1384 /*
1385 ================
1386 InitTypeVariables
1387 ================
1388 */
1389 void InitTypeVariables( const void *typePtr, const char *typeName, int value ) {
1390  idTypeInfoTools::InitTypeVariables( typePtr, typeName, value );
1391 }
1392 
1393 /*
1394 ================
1395 ListTypeInfo_f
1396 ================
1397 */
1398 int SortTypeInfoByName( const int *a, const int *b ) {
1399  return idStr::Icmp( classTypeInfo[*a].typeName, classTypeInfo[*b].typeName );
1400 }
1401 
1402 int SortTypeInfoBySize( const int *a, const int *b ) {
1403  if ( classTypeInfo[*a].size < classTypeInfo[*b].size ) {
1404  return -1;
1405  }
1406  if ( classTypeInfo[*a].size > classTypeInfo[*b].size ) {
1407  return 1;
1408  }
1409  return 0;
1410 }
1411 
1412 void ListTypeInfo_f( const idCmdArgs &args ) {
1413  int i, j;
1415 
1416  common->Printf( "%-32s : %-32s size (B)\n", "type name", "super type name" );
1417  for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
1418  index.Append( i );
1419  }
1420 
1421  if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "size" ) == 0 ) {
1422  index.Sort( SortTypeInfoBySize );
1423  } else {
1424  index.Sort( SortTypeInfoByName );
1425  }
1426 
1427  for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
1428  j = index[i];
1429  common->Printf( "%-32s : %-32s %d\n", classTypeInfo[j].typeName, classTypeInfo[j].superType, classTypeInfo[j].size );
1430  }
1431 }
static void WriteGameState(const char *fileName)
Definition: TypeInfo.cpp:1174
int CheckTokenString(const char *string)
Definition: Lexer.cpp:1007
static WriteVariableType_t Write
Definition: TypeInfo.cpp:65
unsigned int dword
Definition: Lib.h:77
static int snPrintf(char *dest, int size, const char *fmt,...) id_attribute((format(printf
Definition: Str.cpp:1465
static const char * OutputString(const char *string)
Definition: TypeInfo.cpp:187
GLsizei const GLfloat * value
Definition: glext.h:3614
static void WriteClass_r(const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth)
Definition: TypeInfo.cpp:1149
int num_entities
Definition: Game_local.h:278
void WriteGameState_f(const idCmdArgs &args)
Definition: TypeInfo.cpp:1307
idStr & SetFileExtension(const char *extension)
Definition: Str.cpp:743
static void PrintType(const void *typePtr, const char *typeName)
Definition: TypeInfo.cpp:255
const type & GetEndValue(void) const
Definition: Interpolate.h:149
int Cmp(const char *text) const
Definition: Str.h:652
static idTypeInfo * GetType(int num)
Definition: Class.cpp:570
int GetSize(void) const
Definition: Vector.h:1467
float GetStartTime(void) const
Definition: Extrapolate.h:60
void Printf(const char *fmt,...) const id_attribute((format(printf
Definition: Game_local.cpp:699
type * GetEntity(void) const
Definition: Game_local.h:695
static bool ParseTemplateArguments(idLexer &src, idStr &arguments)
Definition: TypeInfo.cpp:221
const idStr & GetKey(void) const
Definition: Dict.h:52
void FreeSource(void)
Definition: Lexer.cpp:1676
const char * ToString(int precision=2) const
Definition: Angles.cpp:238
#define TT_NAME
Definition: Token.h:44
void WriteTypeToFile(idFile *fp, const void *typePtr, const char *typeName)
Definition: TypeInfo.cpp:1371
int Length(void) const
Definition: Str.h:702
static void PrintVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:420
const type & GetStartValue(void) const
Definition: Interpolate.h:148
#define TT_INTEGER
Definition: Token.h:48
int GetGranularity(void) const
Definition: List.h:329
void TestSaveGame_f(const idCmdArgs &args)
Definition: TypeInfo.cpp:1343
void StripTrailing(const char c)
Definition: Str.cpp:515
case const int
Definition: Callbacks.cpp:52
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
const enumValueInfo_t * values
const classVariableInfo_t * variables
const GLuint * buffers
Definition: glext.h:3109
const char * GetName(void) const
Definition: DeclManager.h:140
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
type * Ptr(void)
Definition: List.h:596
virtual const char * Name() const =0
float GetDeceleration(void) const
Definition: Interpolate.h:147
static const enumTypeInfo_t * FindEnumInfo(const char *typeName)
Definition: TypeInfo.cpp:145
extrapolation_t extrapolationType
Definition: Extrapolate.h:70
idCmdSystem * cmdSystem
Definition: CmdSystem.cpp:116
Definition: Token.h:71
#define TT_STRING
Definition: Token.h:41
float GetDuration(void) const
Definition: Interpolate.h:56
GLuint src
Definition: glext.h:5390
float GetAcceleration(void) const
Definition: Interpolate.h:146
int i
Definition: process.py:33
GLintptr offset
Definition: glext.h:3113
const type & GetEndValue(void) const
Definition: Interpolate.h:298
GLuint GLuint num
Definition: glext.h:5390
static void WriteVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:429
static int WriteVariable_r(const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth)
Definition: TypeInfo.cpp:524
extrapolation_t GetExtrapolationType(void) const
Definition: Extrapolate.h:67
float startTime
Definition: Extrapolate.h:71
int Icmp(const char *text) const
Definition: Str.h:667
static void InitTypeVariables(const void *typePtr, const char *typeName, int value)
Definition: TypeInfo.cpp:279
const type & GetEndValue(void) const
Definition: Interpolate.h:58
#define TT_NUMBER
Definition: Token.h:43
int SortTypeInfoBySize(const int *a, const int *b)
Definition: TypeInfo.cpp:1402
const type & GetStartValue(void) const
Definition: Interpolate.h:297
int Icmpn(const char *text, int n) const
Definition: Str.h:672
Definition: File.h:50
virtual void BufferCommandText(cmdExecution_t exec, const char *text)=0
void PrintType(const void *typePtr, const char *typeName)
Definition: TypeInfo.cpp:1380
static idLexer * src
Definition: TypeInfo.cpp:66
Definition: Lexer.h:137
void Sort(cmp_t *compare=(cmp_t *)&idListSortCompare< type >)
Definition: List.h:898
int ExpectTokenType(int type, int subtype, idToken *token)
Definition: Lexer.cpp:938
int GetNumColumns(void) const
Definition: Matrix.h:1822
const char * typeName
float GetDeceleration(void) const
Definition: Interpolate.h:296
Definition: Vector.h:52
void ListTypeInfo_f(const idCmdArgs &args)
Definition: TypeInfo.cpp:1412
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
const char * GetTypeVariableName(const char *typeName, int offset)
Definition: TypeInfo.cpp:92
Definition: Vector.h:808
void(* WriteVariableType_t)(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:48
const char * ToString(int precision=2) const
Definition: Vector.cpp:395
idCommon * common
Definition: Common.cpp:206
float startTime
Definition: Interpolate.h:61
Definition: Dict.h:65
#define NULL
Definition: Lib.h:88
float GetStartTime(void) const
Definition: Interpolate.h:292
const float * ToFloatPtr(void) const
Definition: Vector.h:1910
void CapLength(int)
Definition: Str.h:859
float duration
Definition: Extrapolate.h:72
float GetStartTime(void) const
Definition: Interpolate.h:54
float GetDuration(void) const
Definition: Extrapolate.h:62
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
const char * ToString(int precision=2) const
Definition: Matrix.cpp:3439
virtual const char * Name() const =0
int GetNumRows(void) const
Definition: Matrix.h:1821
const idStr & GetValue(void) const
Definition: Dict.h:53
int Argc(void) const
Definition: CmdArgs.h:48
const char * superType
void CompareGameState_f(const idCmdArgs &args)
Definition: TypeInfo.cpp:1325
bool IsLinked(void) const
virtual int WriteFloatString(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:294
idGameLocal gameLocal
Definition: Game_local.cpp:64
const type & GetBaseSpeed(void) const
Definition: Extrapolate.h:65
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
const char * Name(void) const
Definition: Anim_Blend.cpp:145
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
Definition: Lexer.cpp:1646
float GetAcceleration(void) const
Definition: Interpolate.h:295
bool IsRenderHandleVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value)
Definition: TypeInfo.cpp:347
static bool typeError
Definition: TypeInfo.cpp:67
static void WriteTypeToFile(idFile *fp, const void *typePtr, const char *typeName)
Definition: TypeInfo.cpp:267
idList< idStr > idStrList
Definition: StrList.h:40
const char * ToString(int precision=2) const
Definition: Vector.cpp:221
GLubyte GLubyte b
Definition: glext.h:4662
idEntity * entities[MAX_GENTITIES]
Definition: Game_local.h:275
Definition: Quat.h:48
static void InitVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:478
const type & GetStartValue(void) const
Definition: Interpolate.h:57
int ExpectTokenString(const char *string)
Definition: Lexer.cpp:919
static int FindChar(const char *str, const char c, int start=0, int end=-1)
Definition: Str.cpp:186
const type & GetSpeed(void) const
Definition: Extrapolate.h:66
int Append(const type &obj)
Definition: List.h:646
Definition: Matrix.h:333
const type & GetStartValue(void) const
Definition: Extrapolate.h:64
void InitTypeVariables(const void *typePtr, const char *typeName, int value)
Definition: TypeInfo.cpp:1389
unsigned short word
Definition: Lib.h:76
bool IsCleared(void) const
Definition: Bounds.h:222
int Num(void) const
Definition: List.h:265
unsigned char byte
Definition: Lib.h:75
type * Ptr(void)
Definition: StaticList.h:263
float GetStartTime(void) const
Definition: Interpolate.h:143
static int initValue
Definition: TypeInfo.cpp:64
const GLcharARB * name
Definition: glext.h:3629
GLsizeiptr size
Definition: glext.h:3112
idScriptVariable< int, ev_boolean, int > idScriptBool
Definition: Str.h:116
bool IsAllowedToChangedFromSaveGames(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value)
Definition: TypeInfo.cpp:291
const char * name
static void CompareGameState(const char *fileName)
Definition: TypeInfo.cpp:1216
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
int GetIntValue(void)
Definition: Token.h:152
const char * c_str(void) const
Definition: Str.h:487
int SortTypeInfoByName(const int *a, const int *b)
Definition: TypeInfo.cpp:1398
static idFile * fp
Definition: TypeInfo.cpp:63
const idKeyValue * GetKeyVal(int index) const
Definition: Dict.h:294
unsigned char bool
Definition: setup.h:74
const char * Argv(int arg) const
Definition: CmdArgs.h:50
GLint j
Definition: qgl.h:264
const char * classname
Definition: Class.h:273
char * va(const char *fmt,...)
Definition: Str.cpp:1568
virtual void CloseFile(idFile *f)=0
Definition: Matrix.h:55
int entityNumber
Definition: Entity.h:111
void Replace(const char *old, const char *nw)
Definition: Str.cpp:563
idStr name
Definition: Entity.h:121
int Num(void) const
Definition: StaticList.h:159
Definition: Matrix.h:764
const float * ToFloatPtr(void) const
Definition: Matrix.h:2935
int GetNumKeyVals(void) const
Definition: Dict.h:290
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
Definition: Anim.h:280
static bool IsSubclassOf(const char *typeName, const char *superType)
Definition: TypeInfo.cpp:161
float duration
Definition: Interpolate.h:62
static void VerifyVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:493
static const classTypeInfo_t * FindClassInfo(const char *typeName)
Definition: TypeInfo.cpp:129
static void WriteGameStateVariable(const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value, const void *varPtr, int varSize)
Definition: TypeInfo.cpp:449