1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- 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.
- 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.
- ===========================================================================
- */
- // This is real evil but allows the code to inspect arbitrary class variables.
- #define private public
- #define protected public
- #include "../../idlib/precompiled.h"
- #pragma hdrstop
- #include "../Game_local.h"
- #ifdef ID_DEBUG_MEMORY
- #include "GameTypeInfo.h" // Make sure this is up to date!
- #else
- #include "NoGameTypeInfo.h"
- #endif
- // disabled because it's adds about 64MB to state dumps and takes a really long time
- //#define DUMP_GAMELOCAL
- 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 );
- class idTypeInfoTools {
- public:
- static const classTypeInfo_t * FindClassInfo( const char *typeName );
- static const enumTypeInfo_t * FindEnumInfo( const char *typeName );
- static bool IsSubclassOf( const char *typeName, const char *superType );
- static void PrintType( const void *typePtr, const char *typeName );
- static void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName );
- static void InitTypeVariables( const void *typePtr, const char *typeName, int value );
- static void WriteGameState( const char *fileName );
- static void CompareGameState( const char *fileName );
- private:
- static idFile * fp;
- static int initValue;
- static WriteVariableType_t Write;
- static idLexer * src;
- static bool typeError;
- static const char * OutputString( const char *string );
- static bool ParseTemplateArguments( idLexer &src, idStr &arguments );
- 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 );
- 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 );
- 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 );
- 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 );
- 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 );
- static int WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth );
- static void WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth );
- };
- idFile * idTypeInfoTools::fp = NULL;
- int idTypeInfoTools::initValue = 0;
- WriteVariableType_t idTypeInfoTools::Write = NULL;
- idLexer * idTypeInfoTools::src = NULL;
- bool idTypeInfoTools::typeError = false;
- /*
- ================
- GetTypeVariableName
- ================
- */
- const char *GetTypeVariableName( const char *typeName, int offset ) {
- static char varName[1024];
- int i;
- for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
- if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
- if ( classTypeInfo[i].variables[0].name != NULL && offset >= classTypeInfo[i].variables[0].offset ) {
- break;
- }
- typeName = classTypeInfo[i].superType;
- if ( *typeName == '\0' ) {
- return "<unknown>";
- }
- i = -1;
- }
- }
- const classTypeInfo_t &classInfo = classTypeInfo[i];
- for ( i = 0; classInfo.variables[i].name != NULL; i++ ) {
- if ( offset <= classInfo.variables[i].offset ) {
- break;
- }
- }
- if ( i == 0 ) {
- idStr::snPrintf( varName, sizeof( varName ), "%s::<unknown>", classInfo.typeName );
- } else {
- idStr::snPrintf( varName, sizeof( varName ), "%s::%s", classInfo.typeName, classInfo.variables[i-1].name );
- }
- return varName;
- }
- /*
- ================
- idTypeInfoTools::FindClassInfo
- ================
- */
- const classTypeInfo_t *idTypeInfoTools::FindClassInfo( const char *typeName ) {
- int i;
- for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
- if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
- return &classTypeInfo[i];
- }
- }
- return NULL;
- }
- /*
- ================
- idTypeInfoTools::FindEnumInfo
- ================
- */
- const enumTypeInfo_t *idTypeInfoTools::FindEnumInfo( const char *typeName ) {
- int i;
- for ( i = 0; enumTypeInfo[i].typeName != NULL; i++ ) {
- if ( idStr::Cmp( typeName, enumTypeInfo[i].typeName ) == 0 ) {
- return &enumTypeInfo[i];
- }
- }
- return NULL;
- }
- /*
- ================
- idTypeInfoTools::IsSubclassOf
- ================
- */
- bool idTypeInfoTools::IsSubclassOf( const char *typeName, const char *superType ) {
- int i;
- while( *typeName != '\0' ) {
- if ( idStr::Cmp( typeName, superType ) == 0 ) {
- return true;
- }
- for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
- if ( idStr::Cmp( typeName, classTypeInfo[i].typeName ) == 0 ) {
- typeName = classTypeInfo[i].superType;
- break;
- }
- }
- if ( classTypeInfo[i].typeName == NULL ) {
- common->Warning( "super class %s not found", typeName );
- break;
- }
- }
- return false;
- }
- /*
- ================
- idTypeInfoTools::OutputString
- ================
- */
- const char *idTypeInfoTools::OutputString( const char *string ) {
- static int index = 0;
- static char buffers[4][16384];
- char *out;
- int i, c;
- out = buffers[index];
- index = ( index + 1 ) & 3;
- if ( string == NULL ) {
- return NULL;
- }
- for ( i = 0; i < sizeof( buffers[0] ) - 2; i++ ) {
- c = *string++;
- switch( c ) {
- case '\0': out[i] = '\0'; return out;
- case '\\': out[i++] = '\\'; out[i] = '\\'; break;
- case '\n': out[i++] = '\\'; out[i] = 'n'; break;
- case '\r': out[i++] = '\\'; out[i] = 'r'; break;
- case '\t': out[i++] = '\\'; out[i] = 't'; break;
- case '\v': out[i++] = '\\'; out[i] = 'v'; break;
- default: out[i] = c; break;
- }
- }
- out[i] = '\0';
- return out;
- }
- /*
- ================
- idTypeInfoTools::ParseTemplateArguments
- ================
- */
- bool idTypeInfoTools::ParseTemplateArguments( idLexer &src, idStr &arguments ) {
- int indent;
- idToken token;
- arguments = "";
- if ( !src.ExpectTokenString( "<" ) ) {
- return false;
- }
- indent = 1;
- while( indent ) {
- if ( !src.ReadToken( &token ) ) {
- break;
- }
- if ( token == "<" ) {
- indent++;
- } else if ( token == ">" ) {
- indent--;
- } else {
- if ( arguments.Length() ) {
- arguments += " ";
- }
- arguments += token;
- }
- }
- return true;
- }
- /*
- ================
- idTypeInfoTools::PrintType
- ================
- */
- void idTypeInfoTools::PrintType( const void *typePtr, const char *typeName ) {
- idTypeInfoTools::fp = NULL;
- idTypeInfoTools::initValue = 0;
- idTypeInfoTools::Write = PrintVariable;
- WriteClass_r( typePtr, "", typeName, "", "", 0 );
- }
- /*
- ================
- idTypeInfoTools::WriteTypeToFile
- ================
- */
- void idTypeInfoTools::WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) {
- idTypeInfoTools::fp = fp;
- idTypeInfoTools::initValue = 0;
- idTypeInfoTools::Write = WriteVariable;
- WriteClass_r( typePtr, "", typeName, "", "", 0 );
- }
- /*
- ================
- idTypeInfoTools::InitTypeVariables
- ================
- */
- void idTypeInfoTools::InitTypeVariables( const void *typePtr, const char *typeName, int value ) {
- idTypeInfoTools::fp = NULL;
- idTypeInfoTools::initValue = value;
- idTypeInfoTools::Write = InitVariable;
- WriteClass_r( typePtr, "", typeName, "", "", 0 );
- }
- /*
- ================
- IsAllowedToChangedFromSaveGames
- ================
- */
- bool IsAllowedToChangedFromSaveGames( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) {
- if ( idStr::Icmp( scope, "idAnimator" ) == 0 ) {
- if ( idStr::Icmp( varName, "forceUpdate" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "lastTransformTime" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "AFPoseTime" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "frameBounds" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) {
- if ( idStr::Icmp( varName, "touchCount" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) {
- if ( idStr::Icmp( varName, "numPVSAreas" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "renderView" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idBrittleFracture" ) == 0 ) {
- if ( idStr::Icmp( varName, "changed" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idPhysics_AF" ) == 0 ) {
- return true;
- } else if ( idStr::Icmp( scope, "renderEntity_t" ) == 0 ) {
- // These get fixed up when UpdateVisuals is called
- if ( idStr::Icmp( varName, "origin" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "axis" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "bounds" ) == 0 ) {
- return true;
- }
- }
- if ( idStr::Icmpn( prefix, "idAFEntity_Base::af.idAF::physicsObj.idPhysics_AF", 49) == 0 ) {
- return true;
- }
- return false;
- }
- /*
- ================
- IsRenderHandleVariable
- ================
- */
- bool IsRenderHandleVariable( const char *varName, const char *varType, const char *scope, const char *prefix, const char *postfix, const char *value ) {
- if ( idStr::Icmp( scope, "idClipModel" ) == 0 ) {
- if ( idStr::Icmp( varName, "renderModelHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idFXLocalAction" ) == 0 ) {
- if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idEntity" ) == 0 ) {
- if ( idStr::Icmp( varName, "modelDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idLight" ) == 0 ) {
- if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idAFEntity_Gibbable" ) == 0 ) {
- if ( idStr::Icmp( varName, "skeletonModelDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idAFEntity_SteamPipe" ) == 0 ) {
- if ( idStr::Icmp( varName, "steamModelHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idItem" ) == 0 ) {
- if ( idStr::Icmp( varName, "itemShellHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idExplodingBarrel" ) == 0 ) {
- if ( idStr::Icmp( varName, "particleModelDefHandle" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idProjectile" ) == 0 ) {
- if ( idStr::Icmp( varName, "lightDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idBFGProjectile" ) == 0 ) {
- if ( idStr::Icmp( varName, "secondModelDefHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idSmokeParticles" ) == 0 ) {
- if ( idStr::Icmp( varName, "renderEntityHandle" ) == 0 ) {
- return true;
- }
- } else if ( idStr::Icmp( scope, "idWeapon" ) == 0 ) {
- if ( idStr::Icmp( varName, "muzzleFlashHandle" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "worldMuzzleFlashHandle" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "guiLightHandle" ) == 0 ) {
- return true;
- }
- if ( idStr::Icmp( varName, "nozzleGlowHandle" ) == 0 ) {
- return true;
- }
- }
- return false;
- }
- /*
- ================
- idTypeInfoTools::PrintVariable
- ================
- */
- 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 ) {
- common->Printf( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
- }
- /*
- ================
- idTypeInfoTools::WriteVariable
- ================
- */
- 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 ) {
- for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) {
- if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "IND", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 ||
- idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) {
- common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value );
- break;
- }
- }
- fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
- }
- /*
- ================
- idTypeInfoTools::WriteGameStateVariable
- ================
- */
- 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 ) {
- for ( int i = idStr::FindChar( value, '#', 0 ); i >= 0; i = idStr::FindChar( value, '#', i+1 ) ) {
- if ( idStr::Icmpn( value+i+1, "INF", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "IND", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "NAN", 3 ) == 0 ||
- idStr::Icmpn( value+i+1, "QNAN", 4 ) == 0 ||
- idStr::Icmpn( value+i+1, "SNAN", 4 ) == 0 ) {
- common->Warning( "%s%s::%s%s = \"%s\"", prefix, scope, varName, postfix, value );
- break;
- }
- }
- if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
- return;
- }
- if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) {
- return;
- }
- fp->WriteFloatString( "%s%s::%s%s = \"%s\"\n", prefix, scope, varName, postfix, value );
- }
- /*
- ================
- idTypeInfoTools::InitVariable
- ================
- */
- 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 ) {
- if ( varPtr != NULL && varSize > 0 ) {
- // NOTE: skip renderer handles
- if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
- return;
- }
- memset( const_cast<void*>(varPtr), initValue, varSize );
- }
- }
- /*
- ================
- idTypeInfoTools::VerifyVariable
- ================
- */
- 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 ) {
- idToken token;
- if ( typeError ) {
- return;
- }
- src->SkipUntilString( "=" );
- src->ExpectTokenType( TT_STRING, 0, &token );
- if ( token.Cmp( value ) != 0 ) {
- // NOTE: skip several things
- if ( IsRenderHandleVariable( varName, varType, scope, prefix, postfix, value ) ) {
- return;
- }
- if ( IsAllowedToChangedFromSaveGames( varName, varType, scope, prefix, postfix, value ) ) {
- return;
- }
- src->Warning( "state diff for %s%s::%s%s\n%s\n%s", prefix, scope, varName, postfix, token.c_str(), value );
- typeError = true;
- }
- }
- /*
- ================
- idTypeInfoTools::WriteVariable_r
- ================
- */
- int idTypeInfoTools::WriteVariable_r( const void *varPtr, const char *varName, const char *varType, const char *scope, const char *prefix, const int pointerDepth ) {
- int i, isPointer, typeSize;
- idLexer typeSrc;
- idToken token;
- idStr typeString, templateArgs;
- isPointer = 0;
- typeSize = -1;
- // create a type string without 'const', 'mutable', 'class', 'struct', 'union'
- typeSrc.LoadMemory( varType, idStr::Length( varType ), varName );
- while( typeSrc.ReadToken( &token ) ) {
- if ( token != "const" && token != "mutable" && token != "class" && token != "struct" && token != "union" ) {
- typeString += token + " ";
- }
- }
- typeString.StripTrailing( ' ' );
- typeSrc.FreeSource();
- // if this is an array
- if ( typeString[typeString.Length() - 1] == ']' ) {
- for ( i = typeString.Length(); i > 0 && typeString[i - 1] != '['; i-- ) {
- }
- int num = atoi( &typeString[i] );
- idStr listVarType = typeString;
- listVarType.CapLength( i - 1 );
- typeSize = 0;
- for ( i = 0; i < num; i++ ) {
- idStr listVarName = va( "%s[%d]", varName, i );
- int size = WriteVariable_r( varPtr, listVarName, listVarType, scope, prefix, pointerDepth );
- typeSize += size;
- if ( size == -1 ) {
- break;
- }
- varPtr = (void *)( ( (byte *) varPtr ) + size );
- }
- return typeSize;
- }
- // if this is a pointer
- isPointer = 0;
- for ( i = typeString.Length(); i > 0 && typeString[i - 1] == '*'; i -= 2 ) {
- if ( varPtr == (void *)0xcdcdcdcd || ( varPtr != NULL && *((unsigned long *)varPtr) == 0xcdcdcdcd ) ) {
- common->Warning( "%s%s::%s%s references uninitialized memory", prefix, scope, varName, "" );
- return typeSize;
- }
- if ( varPtr != NULL ) {
- varPtr = *((void **)varPtr);
- }
- isPointer++;
- }
- if ( varPtr == NULL ) {
- Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, 0 );
- return sizeof( void * );
- }
- typeSrc.LoadMemory( typeString, typeString.Length(), varName );
- if ( !typeSrc.ReadToken( &token ) ) {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
- return -1;
- }
- // get full type
- while( typeSrc.CheckTokenString( "::" ) ) {
- idToken newToken;
- typeSrc.ExpectTokenType( TT_NAME, 0, &newToken );
- token += "::" + newToken;
- }
- if ( token == "signed" ) {
- if ( !typeSrc.ReadToken( &token ) ) {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
- return -1;
- }
- if ( token == "char" ) {
- typeSize = sizeof( signed char );
- Write( varName, varType, scope, prefix, "", va( "%d", *((signed char *)varPtr) ), varPtr, typeSize );
- } else if ( token == "short" ) {
- typeSize = sizeof( signed short );
- Write( varName, varType, scope, prefix, "", va( "%d", *((signed short *)varPtr) ), varPtr, typeSize );
- } else if ( token == "int" ) {
- typeSize = sizeof( signed int );
- Write( varName, varType, scope, prefix, "", va( "%d", *((signed int *)varPtr) ), varPtr, typeSize );
- } else if ( token == "long" ) {
- typeSize = sizeof( signed long );
- Write( varName, varType, scope, prefix, "", va( "%ld", *((signed long *)varPtr) ), varPtr, typeSize );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
- return -1;
- }
- } else if ( token == "unsigned" ) {
- if ( !typeSrc.ReadToken( &token ) ) {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
- return -1;
- }
- if ( token == "char" ) {
- typeSize = sizeof( unsigned char );
- Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned char *)varPtr) ), varPtr, typeSize );
- } else if ( token == "short" ) {
- typeSize = sizeof( unsigned short );
- Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned short *)varPtr) ), varPtr, typeSize );
- } else if ( token == "int" ) {
- typeSize = sizeof( unsigned int );
- Write( varName, varType, scope, prefix, "", va( "%d", *((unsigned int *)varPtr) ), varPtr, typeSize );
- } else if ( token == "long" ) {
- typeSize = sizeof( unsigned long );
- Write( varName, varType, scope, prefix, "", va( "%lu", *((unsigned long *)varPtr) ), varPtr, typeSize );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), varPtr, 0 );
- return -1;
- }
- } else if ( token == "byte" ) {
- typeSize = sizeof( byte );
- Write( varName, varType, scope, prefix, "", va( "%d", *((byte *)varPtr) ), varPtr, typeSize );
- } else if ( token == "word" ) {
- typeSize = sizeof( word );
- Write( varName, varType, scope, prefix, "", va( "%d", *((word *)varPtr) ), varPtr, typeSize );
- } else if ( token == "dword" ) {
- typeSize = sizeof( dword );
- Write( varName, varType, scope, prefix, "", va( "%d", *((dword *)varPtr) ), varPtr, typeSize );
- } else if ( token == "bool" ) {
- typeSize = sizeof( bool );
- Write( varName, varType, scope, prefix, "", va( "%d", *((bool *)varPtr) ), varPtr, typeSize );
- } else if ( token == "char" ) {
- typeSize = sizeof( char );
- Write( varName, varType, scope, prefix, "", va( "%d", *((char *)varPtr) ), varPtr, typeSize );
- } else if ( token == "short" ) {
- typeSize = sizeof( short );
- Write( varName, varType, scope, prefix, "", va( "%d", *((short *)varPtr) ), varPtr, typeSize );
- } else if ( token == "int" ) {
- typeSize = sizeof( int );
- Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
- } else if ( token == "long" ) {
- typeSize = sizeof( long );
- Write( varName, varType, scope, prefix, "", va( "%ld", *((long *)varPtr) ), varPtr, typeSize );
- } else if ( token == "float" ) {
- typeSize = sizeof( float );
- Write( varName, varType, scope, prefix, "", idStr( *((float *)varPtr) ).c_str(), varPtr, typeSize );
- } else if ( token == "double" ) {
- typeSize = sizeof( double );
- Write( varName, varType, scope, prefix, "", idStr( (float)*((double *)varPtr) ).c_str(), varPtr, typeSize );
- } else if ( token == "idVec2" ) {
- typeSize = sizeof( idVec2 );
- Write( varName, varType, scope, prefix, "", ((idVec2 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idVec3" ) {
- typeSize = sizeof( idVec3 );
- Write( varName, varType, scope, prefix, "", ((idVec3 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idVec4" ) {
- typeSize = sizeof( idVec4 );
- Write( varName, varType, scope, prefix, "", ((idVec4 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idVec5" ) {
- typeSize = sizeof( idVec5 );
- Write( varName, varType, scope, prefix, "", ((idVec5 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idVec6" ) {
- typeSize = sizeof( idVec6 );
- Write( varName, varType, scope, prefix, "", ((idVec6 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idVecX" ) {
- const idVecX *vec = ((idVecX *)varPtr);
- if ( vec->ToFloatPtr() != NULL ) {
- Write( varName, varType, scope, prefix, "", vec->ToString( 8 ), vec->ToFloatPtr(), vec->GetSize() * sizeof( float ) );
- } else {
- Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, 0 );
- }
- typeSize = sizeof( idVecX );
- } else if ( token == "idMat2" ) {
- typeSize = sizeof( idMat2 );
- Write( varName, varType, scope, prefix, "", ((idMat2 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idMat3" ) {
- typeSize = sizeof( idMat3 );
- Write( varName, varType, scope, prefix, "", ((idMat3 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idMat4" ) {
- typeSize = sizeof( idMat4 );
- Write( varName, varType, scope, prefix, "", ((idMat4 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idMat5" ) {
- typeSize = sizeof( idMat5 );
- Write( varName, varType, scope, prefix, "", ((idMat5 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idMat6" ) {
- typeSize = sizeof( idMat6 );
- Write( varName, varType, scope, prefix, "", ((idMat6 *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idMatX" ) {
- typeSize = sizeof( idMatX );
- const idMatX *mat = ((idMatX *)varPtr);
- if ( mat->ToFloatPtr() != NULL ) {
- Write( varName, varType, scope, prefix, "", mat->ToString( 8 ), mat->ToFloatPtr(), mat->GetNumColumns() * mat->GetNumRows() * sizeof( float ) );
- } else {
- Write( varName, varType, scope, prefix, "", "<NULL>", NULL, 0 );
- }
- } else if ( token == "idAngles" ) {
- typeSize = sizeof( idAngles );
- Write( varName, varType, scope, prefix, "", ((idAngles *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idQuat" ) {
- typeSize = sizeof( idQuat );
- Write( varName, varType, scope, prefix, "", ((idQuat *)varPtr)->ToString( 8 ), varPtr, typeSize );
- } else if ( token == "idBounds" ) {
- typeSize = sizeof( idBounds );
- const idBounds *bounds = ((idBounds *)varPtr);
- if ( bounds->IsCleared() ) {
- Write( varName, varType, scope, prefix, "", "<cleared>", varPtr, typeSize );
- } else {
- Write( varName, varType, scope, prefix, "", va( "(%s)-(%s)", (*bounds)[0].ToString( 8 ), (*bounds)[1].ToString( 8 ) ), varPtr, typeSize );
- }
- } else if ( token == "idList" ) {
- idList<int> *list = ((idList<int> *)varPtr);
- Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 );
- // NOTE: we don't care about the amount of memory allocated
- //Write( varName, varType, scope, prefix, ".size", va( "%d", list->Size() ), NULL, 0 );
- Write( varName, varType, scope, prefix, ".granularity", va( "%d", list->GetGranularity() ), NULL, 0 );
- if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) {
- void *listVarPtr = list->Ptr();
- for ( i = 0; i < list->Num(); i++ ) {
- idStr listVarName = va( "%s[%d]", varName, i );
- int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth );
- if ( size == -1 ) {
- break;
- }
- listVarPtr = (void *)( ( (byte *) listVarPtr ) + size );
- }
- }
- typeSize = sizeof( idList<int> );
- } else if ( token == "idStaticList" ) {
- idStaticList<int, 1> *list = ((idStaticList<int, 1> *)varPtr);
- Write( varName, varType, scope, prefix, ".num", va( "%d", list->Num() ), NULL, 0 );
- int totalSize = 0;
- if ( list->Num() && ParseTemplateArguments( typeSrc, templateArgs ) ) {
- void *listVarPtr = list->Ptr();
- for ( i = 0; i < list->Num(); i++ ) {
- idStr listVarName = va( "%s[%d]", varName, i );
- int size = WriteVariable_r( listVarPtr, listVarName, templateArgs, scope, prefix, pointerDepth );
- if ( size == -1 ) {
- break;
- }
- totalSize += size;
- listVarPtr = (void *)( ( (byte *) listVarPtr ) + size );
- }
- }
- typeSize = sizeof( int ) + totalSize;
- } else if ( token == "idLinkList" ) {
- // FIXME: implement
- typeSize = sizeof( idLinkList<idEntity> );
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), NULL, 0 );
- } else if ( token == "idStr" ) {
- typeSize = sizeof( idStr );
- const idStr *str = ((idStr *)varPtr);
- Write( varName, varType, scope, prefix, "", OutputString( str->c_str() ), str->c_str(), str->Length() );
- } else if ( token == "idStrList" ) {
- typeSize = sizeof( idStrList );
- const idStrList *list = ((idStrList *)varPtr);
- if ( list->Num() ) {
- for ( i = 0; i < list->Num(); i++ ) {
- Write( varName, varType, scope, prefix, va("[%d]", i ), OutputString( (*list)[i].c_str() ), (*list)[i].c_str(), (*list)[i].Length() );
- }
- } else {
- Write( varName, varType, scope, prefix, "", "<empty>", NULL, 0 );
- }
- } else if ( token == "idDict" ) {
- typeSize = sizeof( idDict );
- const idDict *dict = ((idDict *)varPtr);
- if ( dict->GetNumKeyVals() ) {
- for ( i = 0; i < dict->GetNumKeyVals(); i++ ) {
- const idKeyValue *kv = dict->GetKeyVal( i );
- Write( varName, varType, scope, prefix, va("[%d]", i ), va( "\'%s\' \'%s\'", OutputString( kv->GetKey().c_str() ), OutputString( kv->GetValue().c_str() ) ), NULL, 0 );
- }
- } else {
- Write( varName, varType, scope, prefix, "", "<empty>", NULL, 0 );
- }
- } else if ( token == "idExtrapolate" ) {
- const idExtrapolate<float> *interpolate = ((idExtrapolate<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".extrapolationType", idStr( interpolate->GetExtrapolationType() ).c_str(), &interpolate->extrapolationType, sizeof( interpolate->extrapolationType ) );
- Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
- Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) );
- if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
- if ( templateArgs == "int" ) {
- const idExtrapolate<int> *interpolate = ((idExtrapolate<int> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
- Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) );
- typeSize = sizeof( idExtrapolate<int> );
- } else if ( templateArgs == "float" ) {
- const idExtrapolate<float> *interpolate = ((idExtrapolate<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".baseSpeed", idStr( interpolate->GetBaseSpeed() ).c_str(), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
- Write( varName, varType, scope, prefix, ".speed", idStr( interpolate->GetSpeed() ).c_str(), &interpolate->speed, sizeof( interpolate->speed ) );
- typeSize = sizeof( idExtrapolate<float> );
- } else if ( templateArgs == "idVec3" ) {
- const idExtrapolate<idVec3> *interpolate = ((idExtrapolate<idVec3> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
- Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) );
- typeSize = sizeof( idExtrapolate<idVec3> );
- } else if ( templateArgs == "idAngles" ) {
- const idExtrapolate<idAngles> *interpolate = ((idExtrapolate<idAngles> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", interpolate->GetStartValue().ToString( 8 ), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".baseSpeed", interpolate->GetBaseSpeed().ToString( 8 ), &interpolate->baseSpeed, sizeof( interpolate->baseSpeed ) );
- Write( varName, varType, scope, prefix, ".speed", interpolate->GetSpeed().ToString( 8 ), &interpolate->speed, sizeof( interpolate->speed ) );
- typeSize = sizeof( idExtrapolate<idAngles> );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idExtrapolate>", templateArgs.c_str() ), NULL, 0 );
- }
- }
- } else if ( token == "idInterpolate" ) {
- const idInterpolate<float> *interpolate = ((idInterpolate<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
- Write( varName, varType, scope, prefix, ".duration", idStr( interpolate->GetDuration() ).c_str(), &interpolate->duration, sizeof( interpolate->duration ) );
- if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
- if ( templateArgs == "int" ) {
- const idInterpolate<int> *interpolate = ((idInterpolate<int> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolate<int> );
- } else if ( templateArgs == "float" ) {
- const idInterpolate<float> *interpolate = ((idInterpolate<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolate<float> );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolate>", templateArgs.c_str() ), NULL, 0 );
- }
- }
- } else if ( token == "idInterpolateAccelDecelLinear" ) {
- const idInterpolateAccelDecelLinear<float> *interpolate = ((idInterpolateAccelDecelLinear<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
- Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) );
- Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) );
- Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) );
- if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
- if ( templateArgs == "int" ) {
- const idInterpolateAccelDecelLinear<int> *interpolate = ((idInterpolateAccelDecelLinear<int> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolateAccelDecelLinear<int> );
- } else if ( templateArgs == "float" ) {
- const idInterpolateAccelDecelLinear<float> *interpolate = ((idInterpolateAccelDecelLinear<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolateAccelDecelLinear<float> );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolateAccelDecelLinear>", templateArgs.c_str() ), NULL, 0 );
- }
- }
- } else if ( token == "idInterpolateAccelDecelSine" ) {
- const idInterpolateAccelDecelSine<float> *interpolate = ((idInterpolateAccelDecelSine<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startTime", idStr( interpolate->GetStartTime() ).c_str(), &interpolate->startTime, sizeof( interpolate->startTime ) );
- Write( varName, varType, scope, prefix, ".accelTime", idStr( interpolate->GetAcceleration() ).c_str(), &interpolate->accelTime, sizeof( interpolate->accelTime ) );
- Write( varName, varType, scope, prefix, ".linearTime", idStr( interpolate->linearTime ).c_str(), &interpolate->linearTime, sizeof( interpolate->linearTime ) );
- Write( varName, varType, scope, prefix, ".decelTime", idStr( interpolate->GetDeceleration() ).c_str(), &interpolate->decelTime, sizeof( interpolate->decelTime ) );
- if ( ParseTemplateArguments( typeSrc, templateArgs ) ) {
- if ( templateArgs == "int" ) {
- const idInterpolateAccelDecelSine<int> *interpolate = ((idInterpolateAccelDecelSine<int> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolateAccelDecelSine<int> );
- } else if ( templateArgs == "float" ) {
- const idInterpolateAccelDecelSine<float> *interpolate = ((idInterpolateAccelDecelSine<float> *)varPtr);
- Write( varName, varType, scope, prefix, ".startValue", idStr( interpolate->GetStartValue() ).c_str(), &interpolate->startValue, sizeof( interpolate->startValue ) );
- Write( varName, varType, scope, prefix, ".endValue", idStr( interpolate->GetEndValue() ).c_str(), &interpolate->endValue, sizeof( interpolate->endValue ) );
- typeSize = sizeof( idInterpolateAccelDecelSine<float> );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown template argument type '%s' for idInterpolateAccelDecelSine>", templateArgs.c_str() ), NULL, 0 );
- }
- }
- } else if ( token == "idUserInterface" ) {
- typeSize = sizeof( idUserInterface );
- const idUserInterface *gui = ((idUserInterface *)varPtr);
- Write( varName, varType, scope, prefix, "", gui->Name(), varPtr, sizeof( varPtr ) );
- } else if ( token == "idRenderModel" ) {
- typeSize = sizeof( idRenderModel );
- const idRenderModel *model = ((idRenderModel *)varPtr);
- Write( varName, varType, scope, prefix, "", model->Name(), varPtr, sizeof( varPtr ) );
- } else if ( token == "qhandle_t" ) {
- typeSize = sizeof( int );
- Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
- } else if ( token == "cmHandle_t" ) {
- typeSize = sizeof( int );
- Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), varPtr, typeSize );
- } else if ( token == "idEntityPtr" ) {
- typeSize = sizeof( idEntityPtr<idEntity> );
- const idEntityPtr<idEntity> *entPtr = ((idEntityPtr<idEntity> *)varPtr);
- if ( entPtr->GetEntity() ) {
- idEntity *entity = entPtr->GetEntity();
- Write( varName, varType, scope, prefix, ".", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), varPtr, typeSize );
- } else {
- Write( varName, varType, scope, prefix, "", "<NULL>", varPtr, typeSize );
- }
- } else if ( token == "idEntity::entityFlags_s" ) {
- const idEntity::entityFlags_s *flags = ((idEntity::entityFlags_s *)varPtr);
- Write( varName, varType, scope, prefix, ".notarget", flags->notarget ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".noknockback", flags->noknockback ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".takedamage", flags->takedamage ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".hidden", flags->hidden ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".bindOrientated", flags->bindOrientated ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".solidForTeam", flags->solidForTeam ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".forcePhysicsUpdate", flags->forcePhysicsUpdate ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".selected", flags->selected ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".neverDormant", flags->neverDormant ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".isDormant", flags->isDormant ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".hasAwakened", flags->hasAwakened ? "true" : "false", NULL, 0 );
- Write( varName, varType, scope, prefix, ".networkSync", flags->networkSync ? "true" : "false", NULL, 0 );
- typeSize = sizeof( idEntity::entityFlags_s );
- } else if ( token == "idScriptBool" ) {
- typeSize = sizeof( idScriptBool );
- const idScriptBool *scriptBool = ((idScriptBool *)varPtr);
- if ( scriptBool->IsLinked() ) {
- Write( varName, varType, scope, prefix, "", ( *scriptBool != 0 ) ? "true" : "false", varPtr, typeSize );
- } else {
- Write( varName, varType, scope, prefix, "", "<not linked>", varPtr, typeSize );
- }
- } else {
- const classTypeInfo_t *classTypeInfo = FindClassInfo( scope + ( "::" + token ) );
- if ( classTypeInfo == NULL ) {
- classTypeInfo = FindClassInfo( token );
- }
- if ( classTypeInfo != NULL ) {
- typeSize = classTypeInfo->size;
- if ( !isPointer ) {
- char newPrefix[1024];
- idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s.", prefix, scope, varName );
- WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth );
- } else if ( token == "idAnim" ) {
- const idAnim *anim = ((idAnim*)varPtr);
- Write( varName, varType, scope, prefix, "", anim->Name(), NULL, 0 );
- } else if ( token == "idPhysics" ) {
- const idPhysics *physics = ((idPhysics*)varPtr);
- Write( varName, varType, scope, prefix, "", physics->GetType()->classname, NULL, 0 );
- } else if ( IsSubclassOf( token, "idEntity" ) ) {
- const idEntity *entity = ((idEntity*)varPtr);
- Write( varName, varType, scope, prefix, "", va( "entity %d: \'%s\'", entity->entityNumber, entity->name.c_str() ), NULL, 0 );
- } else if ( IsSubclassOf( token, "idDecl" ) ) {
- const idDecl *decl = ((idDecl *)varPtr);
- Write( varName, varType, scope, prefix, "", decl->GetName(), NULL, 0 );
- } else if ( pointerDepth == 0 && (
- token == "idAFBody" ||
- token == "idAFTree" ||
- token == "idClipModel" ||
- IsSubclassOf( token, "idAFConstraint" )
- ) ) {
- char newPrefix[1024];
- idStr::snPrintf( newPrefix, sizeof( newPrefix ), "%s%s::%s->", prefix, scope, varName );
- WriteClass_r( varPtr, "", token, token, newPrefix, pointerDepth + 1 );
- } else {
- Write( varName, varType, scope, prefix, "", va( "<pointer type '%s' not listed>", varType ), NULL, 0 );
- return -1;
- }
- } else {
- const enumTypeInfo_t *enumTypeInfo = FindEnumInfo( scope + ( "::" + token ) );
- if ( enumTypeInfo == NULL ) {
- enumTypeInfo = FindEnumInfo( token );
- }
- if ( enumTypeInfo != NULL ) {
- typeSize = sizeof( int ); // NOTE: assuming sizeof( enum ) is sizeof( int )
- for ( i = 0; enumTypeInfo->values[i].name != NULL; i++ ) {
- if ( *((int *)varPtr) == enumTypeInfo->values[i].value ) {
- break;
- }
- }
- if ( enumTypeInfo->values[i].name != NULL ) {
- Write( varName, varType, scope, prefix, "", enumTypeInfo->values[i].name, NULL, 0 );
- } else {
- Write( varName, varType, scope, prefix, "", va( "%d", *((int *)varPtr) ), NULL, 0 );
- }
- } else {
- Write( varName, varType, scope, prefix, "", va( "<unknown type '%s'>", varType ), NULL, 0 );
- return -1;
- }
- }
- }
- i = 0;
- do {
- if ( *((unsigned long *)varPtr) == 0xcdcdcdcd ) {
- common->Warning( "%s%s::%s%s uses uninitialized memory", prefix, scope, varName, "" );
- break;
- }
- } while( ++i < typeSize );
- if ( isPointer ) {
- return sizeof( void * );
- }
- return typeSize;
- }
- /*
- ================
- idTypeInfoTools::WriteClass_r
- ================
- */
- void idTypeInfoTools::WriteClass_r( const void *classPtr, const char *className, const char *classType, const char *scope, const char *prefix, const int pointerDepth ) {
- int i;
- const classTypeInfo_t *classInfo = FindClassInfo( classType );
- if ( !classInfo ) {
- return;
- }
- if ( *classInfo->superType != '\0' ) {
- WriteClass_r( classPtr, className, classInfo->superType, scope, prefix, pointerDepth );
- }
- for ( i = 0; classInfo->variables[i].name != NULL; i++ ) {
- const classVariableInfo_t &classVar = classInfo->variables[i];
- void *varPtr = (void *) (((byte *)classPtr) + classVar.offset);
- WriteVariable_r( varPtr, classVar.name, classVar.type, classType, prefix, pointerDepth );
- }
- }
- /*
- ================
- idTypeInfoTools::WriteGameState
- ================
- */
- void idTypeInfoTools::WriteGameState( const char *fileName ) {
- int i, num;
- idFile *file;
- file = fileSystem->OpenFileWrite( fileName );
- if ( !file ) {
- common->Warning( "couldn't open %s", fileName );
- return;
- }
- fp = file;
- Write = WriteGameStateVariable; //WriteVariable;
- #ifdef DUMP_GAMELOCAL
- file->WriteFloatString( "\ngameLocal {\n" );
- WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 );
- file->WriteFloatString( "}\n" );
- #endif
- for ( num = i = 0; i < gameLocal.num_entities; i++ ) {
- idEntity *ent = gameLocal.entities[i];
- if ( ent == NULL ) {
- continue;
- }
- file->WriteFloatString( "\nentity %d %s {\n", i, ent->GetType()->classname );
- WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 );
- file->WriteFloatString( "}\n" );
- num++;
- }
- fileSystem->CloseFile( file );
- common->Printf( "%d entities written\n", num );
- }
- /*
- ================
- idTypeInfoTools::CompareGameState
- ================
- */
- void idTypeInfoTools::CompareGameState( const char *fileName ) {
- int entityNum;
- idToken token;
- src = new idLexer();
- src->SetFlags( LEXFL_NOSTRINGESCAPECHARS );
- if ( !src->LoadFile( fileName ) ) {
- common->Warning( "couldn't load %s", fileName );
- delete src;
- src = NULL;
- return;
- }
- fp = NULL;
- Write = VerifyVariable;
- #ifdef DUMP_GAMELOCAL
- if ( !src->ExpectTokenString( "gameLocal" ) || !src->ExpectTokenString( "{" ) ) {
- delete src;
- src = NULL;
- return;
- }
- WriteClass_r( (void *)&gameLocal, "", "idGameLocal", "idGameLocal", "", 0 );
- if ( !src->ExpectTokenString( "}" ) ) {
- delete src;
- src = NULL;
- return;
- }
- #endif
- while( src->ReadToken( &token ) ) {
- if ( token != "entity" ) {
- break;
- }
- if ( !src->ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) {
- break;
- }
- entityNum = token.GetIntValue();
- if ( entityNum < 0 || entityNum >= gameLocal.num_entities ) {
- src->Warning( "entity number %d out of range", entityNum );
- break;
- }
- typeError = false;
- idEntity *ent = gameLocal.entities[entityNum];
- if ( !ent ) {
- src->Warning( "entity %d is not spawned", entityNum );
- src->SkipBracedSection( true );
- continue;
- }
- if ( !src->ExpectTokenType( TT_NAME, 0, &token ) ) {
- break;
- }
- if ( token.Cmp( ent->GetType()->classname ) != 0 ) {
- src->Warning( "entity %d has wrong type", entityNum );
- src->SkipBracedSection( true );
- continue;
- }
- if ( !src->ExpectTokenString( "{" ) ) {
- src->Warning( "entity %d missing leading {", entityNum );
- break;
- }
- WriteClass_r( (void *)ent, "", ent->GetType()->classname, ent->GetType()->classname, "", 0 );
- if ( !src->SkipBracedSection( false ) ) {
- src->Warning( "entity %d missing trailing }", entityNum );
- break;
- }
- }
- delete src;
- src = NULL;
- }
- /*
- ================
- WriteGameState_f
- ================
- */
- void WriteGameState_f( const idCmdArgs &args ) {
- idStr fileName;
- if ( args.Argc() > 1 ) {
- fileName = args.Argv(1);
- } else {
- fileName = "GameState.txt";
- }
- fileName.SetFileExtension( "gameState.txt" );
- idTypeInfoTools::WriteGameState( fileName );
- }
- /*
- ================
- CompareGameState_f
- ================
- */
- void CompareGameState_f( const idCmdArgs &args ) {
- idStr fileName;
- if ( args.Argc() > 1 ) {
- fileName = args.Argv(1);
- } else {
- fileName = "GameState.txt";
- }
- fileName.SetFileExtension( "gameState.txt" );
- idTypeInfoTools::CompareGameState( fileName );
- }
- /*
- ================
- TestSaveGame_f
- ================
- */
- void TestSaveGame_f( const idCmdArgs &args ) {
- idStr name;
- if ( args.Argc() <= 1 ) {
- gameLocal.Printf( "testSaveGame <mapName>\n" );
- return;
- }
- name = args.Argv( 1 );
- try {
- cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "map %s", name.c_str() ) );
- name.Replace( "\\", "_" );
- name.Replace( "/", "_" );
- cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "saveGame test_%s", name.c_str() ) );
- cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "loadGame test_%s", name.c_str() ) );
- }
- catch( idException & ) {
- // an ERR_DROP was thrown
- }
- cmdSystem->BufferCommandText( CMD_EXEC_NOW, "quit" );
- }
- /*
- ================
- WriteTypeToFile
- ================
- */
- void WriteTypeToFile( idFile *fp, const void *typePtr, const char *typeName ) {
- idTypeInfoTools::WriteTypeToFile( fp, typePtr, typeName );
- }
- /*
- ================
- PrintType
- ================
- */
- void PrintType( const void *typePtr, const char *typeName ) {
- idTypeInfoTools::PrintType( typePtr, typeName );
- }
- /*
- ================
- InitTypeVariables
- ================
- */
- void InitTypeVariables( const void *typePtr, const char *typeName, int value ) {
- idTypeInfoTools::InitTypeVariables( typePtr, typeName, value );
- }
- /*
- ================
- ListTypeInfo_f
- ================
- */
- int SortTypeInfoByName( const int *a, const int *b ) {
- return idStr::Icmp( classTypeInfo[*a].typeName, classTypeInfo[*b].typeName );
- }
- int SortTypeInfoBySize( const int *a, const int *b ) {
- if ( classTypeInfo[*a].size < classTypeInfo[*b].size ) {
- return -1;
- }
- if ( classTypeInfo[*a].size > classTypeInfo[*b].size ) {
- return 1;
- }
- return 0;
- }
- void ListTypeInfo_f( const idCmdArgs &args ) {
- int i, j;
- idList<int> index;
- common->Printf( "%-32s : %-32s size (B)\n", "type name", "super type name" );
- for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
- index.Append( i );
- }
- if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "size" ) == 0 ) {
- index.Sort( SortTypeInfoBySize );
- } else {
- index.Sort( SortTypeInfoByName );
- }
- for ( i = 0; classTypeInfo[i].typeName != NULL; i++ ) {
- j = index[i];
- common->Printf( "%-32s : %-32s %d\n", classTypeInfo[j].typeName, classTypeInfo[j].superType, classTypeInfo[j].size );
- }
- }
|