123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548 |
- /*
- ===========================================================================
- 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.
- ===========================================================================
- */
- #include "../../idlib/precompiled.h"
- #pragma hdrstop
- #include "../Game_local.h"
- #include "TypeInfo.h"
- /*
- Save game related helper classes.
- Save games are implemented in two classes, idSaveGame and idRestoreGame, that implement write/read functions for
- common types. They're passed in to each entity and object for them to archive themselves. Each class
- implements save/restore functions for it's own data. When restoring, all the objects are instantiated,
- then the restore function is called on each, superclass first, then subclasses.
- Pointers are restored by saving out an object index for each unique object pointer and adding them to a list of
- objects that are to be saved. Restore instantiates all the objects in the list before calling the Restore function
- on each object so that the pointers returned are valid. No object's restore function should rely on any other objects
- being fully instantiated until after the restore process is complete. Post restore fixup should be done by posting
- events with 0 delay.
- The savegame header will have the Game Name, Version, Map Name, and Player Persistent Info.
- Changes in version make savegames incompatible, and the game will start from the beginning of the level with
- the player's persistent info.
- Changes to classes that don't need to break compatibilty can use the build number as the savegame version.
- Later versions are responsible for restoring from previous versions by ignoring any unused data and initializing
- variables that weren't in previous versions with safe information.
- At the head of the save game is enough information to restore the player to the beginning of the level should the
- file be unloadable in some way (for example, due to script changes).
- */
- /*
- ================
- idSaveGame::idSaveGame()
- ================
- */
- idSaveGame::idSaveGame( idFile *savefile ) {
- file = savefile;
- // Put NULL at the start of the list so we can skip over it.
- objects.Clear();
- objects.Append( NULL );
- }
- /*
- ================
- idSaveGame::~idSaveGame()
- ================
- */
- idSaveGame::~idSaveGame() {
- if ( objects.Num() ) {
- Close();
- }
- }
- /*
- ================
- idSaveGame::Close
- ================
- */
- void idSaveGame::Close( void ) {
- int i;
- WriteSoundCommands();
- // read trace models
- idClipModel::SaveTraceModels( this );
- for( i = 1; i < objects.Num(); i++ ) {
- CallSave_r( objects[ i ]->GetType(), objects[ i ] );
- }
- objects.Clear();
- #ifdef ID_DEBUG_MEMORY
- idStr gameState = file->GetName();
- gameState.StripFileExtension();
- WriteGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ), false ) );
- #endif
- }
- /*
- ================
- idSaveGame::WriteObjectList
- ================
- */
- void idSaveGame::WriteObjectList( void ) {
- int i;
- WriteInt( objects.Num() - 1 );
- for( i = 1; i < objects.Num(); i++ ) {
- WriteString( objects[ i ]->GetClassname() );
- }
- }
- /*
- ================
- idSaveGame::CallSave_r
- ================
- */
- void idSaveGame::CallSave_r( const idTypeInfo *cls, const idClass *obj ) {
- if ( cls->super ) {
- CallSave_r( cls->super, obj );
- if ( cls->super->Save == cls->Save ) {
- // don't call save on this inheritance level since the function was called in the super class
- return;
- }
- }
-
- ( obj->*cls->Save )( this );
- }
- /*
- ================
- idSaveGame::AddObject
- ================
- */
- void idSaveGame::AddObject( const idClass *obj ) {
- objects.AddUnique( obj );
- }
- /*
- ================
- idSaveGame::Write
- ================
- */
- void idSaveGame::Write( const void *buffer, int len ) {
- file->Write( buffer, len );
- }
- /*
- ================
- idSaveGame::WriteInt
- ================
- */
- void idSaveGame::WriteInt( const int value ) {
- file->WriteInt( value );
- }
- /*
- ================
- idSaveGame::WriteJoint
- ================
- */
- void idSaveGame::WriteJoint( const jointHandle_t value ) {
- file->WriteInt( (int&)value );
- }
- /*
- ================
- idSaveGame::WriteShort
- ================
- */
- void idSaveGame::WriteShort( const short value ) {
- file->WriteShort( value );
- }
- /*
- ================
- idSaveGame::WriteByte
- ================
- */
- void idSaveGame::WriteByte( const byte value ) {
- file->Write( &value, sizeof( value ) );
- }
- /*
- ================
- idSaveGame::WriteSignedChar
- ================
- */
- void idSaveGame::WriteSignedChar( const signed char value ) {
- file->Write( &value, sizeof( value ) );
- }
- /*
- ================
- idSaveGame::WriteFloat
- ================
- */
- void idSaveGame::WriteFloat( const float value ) {
- file->WriteFloat( value );
- }
- /*
- ================
- idSaveGame::WriteBool
- ================
- */
- void idSaveGame::WriteBool( const bool value ) {
- file->WriteBool( value );
- }
- /*
- ================
- idSaveGame::WriteString
- ================
- */
- void idSaveGame::WriteString( const char *string ) {
- int len;
- len = strlen( string );
- WriteInt( len );
- file->Write( string, len );
- }
- /*
- ================
- idSaveGame::WriteVec2
- ================
- */
- void idSaveGame::WriteVec2( const idVec2 &vec ) {
- file->WriteVec2( vec );
- }
- /*
- ================
- idSaveGame::WriteVec3
- ================
- */
- void idSaveGame::WriteVec3( const idVec3 &vec ) {
- file->WriteVec3( vec );
- }
- /*
- ================
- idSaveGame::WriteVec4
- ================
- */
- void idSaveGame::WriteVec4( const idVec4 &vec ) {
- file->WriteVec4( vec );
- }
- /*
- ================
- idSaveGame::WriteVec6
- ================
- */
- void idSaveGame::WriteVec6( const idVec6 &vec ) {
- file->WriteVec6( vec );
- }
- /*
- ================
- idSaveGame::WriteBounds
- ================
- */
- void idSaveGame::WriteBounds( const idBounds &bounds ) {
- idBounds b = bounds;
- LittleRevBytes( &b, sizeof(float), sizeof(b)/sizeof(float) );
- file->Write( &b, sizeof( b ) );
- }
- /*
- ================
- idSaveGame::WriteBounds
- ================
- */
- void idSaveGame::WriteWinding( const idWinding &w )
- {
- int i, num;
- num = w.GetNumPoints();
- file->WriteInt( num );
- for ( i = 0; i < num; i++ ) {
- idVec5 v = w[i];
- LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
- file->Write( &v, sizeof(v) );
- }
- }
- /*
- ================
- idSaveGame::WriteMat3
- ================
- */
- void idSaveGame::WriteMat3( const idMat3 &mat ) {
- file->WriteMat3( mat );
- }
- /*
- ================
- idSaveGame::WriteAngles
- ================
- */
- void idSaveGame::WriteAngles( const idAngles &angles ) {
- idAngles v = angles;
- LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
- file->Write( &v, sizeof( v ) );
- }
- /*
- ================
- idSaveGame::WriteObject
- ================
- */
- void idSaveGame::WriteObject( const idClass *obj ) {
- int index;
- index = objects.FindIndex( obj );
- if ( index < 0 ) {
- gameLocal.DPrintf( "idSaveGame::WriteObject - WriteObject FindIndex failed\n" );
- // Use the NULL index
- index = 0;
- }
- WriteInt( index );
- }
- /*
- ================
- idSaveGame::WriteStaticObject
- ================
- */
- void idSaveGame::WriteStaticObject( const idClass &obj ) {
- CallSave_r( obj.GetType(), &obj );
- }
- /*
- ================
- idSaveGame::WriteDict
- ================
- */
- void idSaveGame::WriteDict( const idDict *dict ) {
- int num;
- int i;
- const idKeyValue *kv;
- if ( !dict ) {
- WriteInt( -1 );
- } else {
- num = dict->GetNumKeyVals();
- WriteInt( num );
- for( i = 0; i < num; i++ ) {
- kv = dict->GetKeyVal( i );
- WriteString( kv->GetKey() );
- WriteString( kv->GetValue() );
- }
- }
- }
- /*
- ================
- idSaveGame::WriteMaterial
- ================
- */
- void idSaveGame::WriteMaterial( const idMaterial *material ) {
- if ( !material ) {
- WriteString( "" );
- } else {
- WriteString( material->GetName() );
- }
- }
- /*
- ================
- idSaveGame::WriteSkin
- ================
- */
- void idSaveGame::WriteSkin( const idDeclSkin *skin ) {
- if ( !skin ) {
- WriteString( "" );
- } else {
- WriteString( skin->GetName() );
- }
- }
- /*
- ================
- idSaveGame::WriteParticle
- ================
- */
- void idSaveGame::WriteParticle( const idDeclParticle *particle ) {
- if ( !particle ) {
- WriteString( "" );
- } else {
- WriteString( particle->GetName() );
- }
- }
- /*
- ================
- idSaveGame::WriteFX
- ================
- */
- void idSaveGame::WriteFX( const idDeclFX *fx ) {
- if ( !fx ) {
- WriteString( "" );
- } else {
- WriteString( fx->GetName() );
- }
- }
- /*
- ================
- idSaveGame::WriteModelDef
- ================
- */
- void idSaveGame::WriteModelDef( const idDeclModelDef *modelDef ) {
- if ( !modelDef ) {
- WriteString( "" );
- } else {
- WriteString( modelDef->GetName() );
- }
- }
- /*
- ================
- idSaveGame::WriteSoundShader
- ================
- */
- void idSaveGame::WriteSoundShader( const idSoundShader *shader ) {
- const char *name;
- if ( !shader ) {
- WriteString( "" );
- } else {
- name = shader->GetName();
- WriteString( name );
- }
- }
- /*
- ================
- idSaveGame::WriteModel
- ================
- */
- void idSaveGame::WriteModel( const idRenderModel *model ) {
- const char *name;
- if ( !model ) {
- WriteString( "" );
- } else {
- name = model->Name();
- WriteString( name );
- }
- }
- /*
- ================
- idSaveGame::WriteUserInterface
- ================
- */
- void idSaveGame::WriteUserInterface( const idUserInterface *ui, bool unique ) {
- const char *name;
- if ( !ui ) {
- WriteString( "" );
- } else {
- name = ui->Name();
- WriteString( name );
- WriteBool( unique );
- if ( ui->WriteToSaveGame( file ) == false ) {
- gameLocal.Error( "idSaveGame::WriteUserInterface: ui failed to write properly\n" );
- }
- }
- }
- /*
- ================
- idSaveGame::WriteRenderEntity
- ================
- */
- void idSaveGame::WriteRenderEntity( const renderEntity_t &renderEntity ) {
- int i;
- WriteModel( renderEntity.hModel );
- WriteInt( renderEntity.entityNum );
- WriteInt( renderEntity.bodyId );
- WriteBounds( renderEntity.bounds );
- // callback is set by class's Restore function
- WriteInt( renderEntity.suppressSurfaceInViewID );
- WriteInt( renderEntity.suppressShadowInViewID );
- WriteInt( renderEntity.suppressShadowInLightID );
- WriteInt( renderEntity.allowSurfaceInViewID );
- WriteVec3( renderEntity.origin );
- WriteMat3( renderEntity.axis );
- WriteMaterial( renderEntity.customShader );
- WriteMaterial( renderEntity.referenceShader );
- WriteSkin( renderEntity.customSkin );
- if ( renderEntity.referenceSound != NULL ) {
- WriteInt( renderEntity.referenceSound->Index() );
- } else {
- WriteInt( 0 );
- }
- for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
- WriteFloat( renderEntity.shaderParms[ i ] );
- }
- for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
- WriteUserInterface( renderEntity.gui[ i ], renderEntity.gui[ i ] ? renderEntity.gui[ i ]->IsUniqued() : false );
- }
- WriteFloat( renderEntity.modelDepthHack );
- WriteBool( renderEntity.noSelfShadow );
- WriteBool( renderEntity.noShadow );
- WriteBool( renderEntity.noDynamicInteractions );
- WriteBool( renderEntity.weaponDepthHack );
- WriteInt( renderEntity.forceUpdate );
- }
- /*
- ================
- idSaveGame::WriteRenderLight
- ================
- */
- void idSaveGame::WriteRenderLight( const renderLight_t &renderLight ) {
- int i;
- WriteMat3( renderLight.axis );
- WriteVec3( renderLight.origin );
- WriteInt( renderLight.suppressLightInViewID );
- WriteInt( renderLight.allowLightInViewID );
- WriteBool( renderLight.noShadows );
- WriteBool( renderLight.noSpecular );
- WriteBool( renderLight.pointLight );
- WriteBool( renderLight.parallel );
- WriteVec3( renderLight.lightRadius );
- WriteVec3( renderLight.lightCenter );
- WriteVec3( renderLight.target );
- WriteVec3( renderLight.right );
- WriteVec3( renderLight.up );
- WriteVec3( renderLight.start );
- WriteVec3( renderLight.end );
- // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there
- // WriteModel( renderLight.prelightModel );
- WriteInt( renderLight.lightId );
- WriteMaterial( renderLight.shader );
- for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
- WriteFloat( renderLight.shaderParms[ i ] );
- }
- if ( renderLight.referenceSound != NULL ) {
- WriteInt( renderLight.referenceSound->Index() );
- } else {
- WriteInt( 0 );
- }
- }
- /*
- ================
- idSaveGame::WriteRefSound
- ================
- */
- void idSaveGame::WriteRefSound( const refSound_t &refSound ) {
- if ( refSound.referenceSound ) {
- WriteInt( refSound.referenceSound->Index() );
- } else {
- WriteInt( 0 );
- }
- WriteVec3( refSound.origin );
- WriteInt( refSound.listenerId );
- WriteSoundShader( refSound.shader );
- WriteFloat( refSound.diversity );
- WriteBool( refSound.waitfortrigger );
- WriteFloat( refSound.parms.minDistance );
- WriteFloat( refSound.parms.maxDistance );
- WriteFloat( refSound.parms.volume );
- WriteFloat( refSound.parms.shakes );
- WriteInt( refSound.parms.soundShaderFlags );
- WriteInt( refSound.parms.soundClass );
- }
- /*
- ================
- idSaveGame::WriteRenderView
- ================
- */
- void idSaveGame::WriteRenderView( const renderView_t &view ) {
- int i;
- WriteInt( view.viewID );
- WriteInt( view.x );
- WriteInt( view.y );
- WriteInt( view.width );
- WriteInt( view.height );
- WriteFloat( view.fov_x );
- WriteFloat( view.fov_y );
- WriteVec3( view.vieworg );
- WriteMat3( view.viewaxis );
- WriteBool( view.cramZNear );
- WriteInt( view.time );
- for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
- WriteFloat( view.shaderParms[ i ] );
- }
- }
- /*
- ===================
- idSaveGame::WriteUsercmd
- ===================
- */
- void idSaveGame::WriteUsercmd( const usercmd_t &usercmd ) {
- WriteInt( usercmd.gameFrame );
- WriteInt( usercmd.gameTime );
- WriteInt( usercmd.duplicateCount );
- WriteByte( usercmd.buttons );
- WriteSignedChar( usercmd.forwardmove );
- WriteSignedChar( usercmd.rightmove );
- WriteSignedChar( usercmd.upmove );
- WriteShort( usercmd.angles[0] );
- WriteShort( usercmd.angles[1] );
- WriteShort( usercmd.angles[2] );
- WriteShort( usercmd.mx );
- WriteShort( usercmd.my );
- WriteSignedChar( usercmd.impulse );
- WriteByte( usercmd.flags );
- WriteInt( usercmd.sequence );
- }
- /*
- ===================
- idSaveGame::WriteContactInfo
- ===================
- */
- void idSaveGame::WriteContactInfo( const contactInfo_t &contactInfo ) {
- WriteInt( (int)contactInfo.type );
- WriteVec3( contactInfo.point );
- WriteVec3( contactInfo.normal );
- WriteFloat( contactInfo.dist );
- WriteInt( contactInfo.contents );
- WriteMaterial( contactInfo.material );
- WriteInt( contactInfo.modelFeature );
- WriteInt( contactInfo.trmFeature );
- WriteInt( contactInfo.entityNum );
- WriteInt( contactInfo.id );
- }
- /*
- ===================
- idSaveGame::WriteTrace
- ===================
- */
- void idSaveGame::WriteTrace( const trace_t &trace ) {
- WriteFloat( trace.fraction );
- WriteVec3( trace.endpos );
- WriteMat3( trace.endAxis );
- WriteContactInfo( trace.c );
- }
- /*
- ===================
- idRestoreGame::WriteTraceModel
- ===================
- */
- void idSaveGame::WriteTraceModel( const idTraceModel &trace ) {
- int j, k;
-
- WriteInt( (int&)trace.type );
- WriteInt( trace.numVerts );
- for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) {
- WriteVec3( trace.verts[j] );
- }
- WriteInt( trace.numEdges );
- for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) {
- WriteInt( trace.edges[j].v[0] );
- WriteInt( trace.edges[j].v[1] );
- WriteVec3( trace.edges[j].normal );
- }
- WriteInt( trace.numPolys );
- for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) {
- WriteVec3( trace.polys[j].normal );
- WriteFloat( trace.polys[j].dist );
- WriteBounds( trace.polys[j].bounds );
- WriteInt( trace.polys[j].numEdges );
- for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) {
- WriteInt( trace.polys[j].edges[k] );
- }
- }
- WriteVec3( trace.offset );
- WriteBounds( trace.bounds );
- WriteBool( trace.isConvex );
- // padding win32 native structs
- char tmp[3];
- memset( tmp, 0, sizeof( tmp ) );
- file->Write( tmp, 3 );
- }
- /*
- ===================
- idSaveGame::WriteClipModel
- ===================
- */
- void idSaveGame::WriteClipModel( const idClipModel *clipModel ) {
- if ( clipModel != NULL ) {
- WriteBool( true );
- clipModel->Save( this );
- } else {
- WriteBool( false );
- }
- }
- /*
- ===================
- idSaveGame::WriteSoundCommands
- ===================
- */
- void idSaveGame::WriteSoundCommands( void ) {
- gameSoundWorld->WriteToSaveGame( file );
- }
- /*
- ======================
- idSaveGame::WriteBuildNumber
- ======================
- */
- void idSaveGame::WriteBuildNumber( const int value ) {
- file->WriteInt( BUILD_NUMBER );
- }
- /***********************************************************************
- idRestoreGame
-
- ***********************************************************************/
- /*
- ================
- idRestoreGame::RestoreGame
- ================
- */
- idRestoreGame::idRestoreGame( idFile *savefile ) {
- file = savefile;
- }
- /*
- ================
- idRestoreGame::~idRestoreGame()
- ================
- */
- idRestoreGame::~idRestoreGame() {
- }
- /*
- ================
- void idRestoreGame::CreateObjects
- ================
- */
- void idRestoreGame::CreateObjects( void ) {
- int i, num;
- idStr classname;
- idTypeInfo *type;
- ReadInt( num );
- // create all the objects
- objects.SetNum( num + 1 );
- memset( objects.Ptr(), 0, sizeof( objects[ 0 ] ) * objects.Num() );
- for( i = 1; i < objects.Num(); i++ ) {
- ReadString( classname );
- type = idClass::GetClass( classname );
- if ( !type ) {
- Error( "idRestoreGame::CreateObjects: Unknown class '%s'", classname.c_str() );
- }
- objects[ i ] = type->CreateInstance();
- #ifdef ID_DEBUG_MEMORY
- InitTypeVariables( objects[i], type->classname, 0xce );
- #endif
- }
- }
- /*
- ================
- void idRestoreGame::RestoreObjects
- ================
- */
- void idRestoreGame::RestoreObjects( void ) {
- int i;
- ReadSoundCommands();
- // read trace models
- idClipModel::RestoreTraceModels( this );
- // restore all the objects
- for( i = 1; i < objects.Num(); i++ ) {
- CallRestore_r( objects[ i ]->GetType(), objects[ i ] );
- }
- // regenerate render entities and render lights because are not saved
- for( i = 1; i < objects.Num(); i++ ) {
- if ( objects[ i ]->IsType( idEntity::Type ) ) {
- idEntity *ent = static_cast<idEntity *>( objects[ i ] );
- ent->UpdateVisuals();
- ent->Present();
- }
- }
- #ifdef ID_DEBUG_MEMORY
- idStr gameState = file->GetName();
- gameState.StripFileExtension();
- WriteGameState_f( idCmdArgs( va( "test %s_restore", gameState.c_str() ), false ) );
- //CompareGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ) ) );
- gameLocal.Error( "dumped game states" );
- #endif
- }
- /*
- ====================
- void idRestoreGame::DeleteObjects
- ====================
- */
- void idRestoreGame::DeleteObjects( void ) {
- // Remove the NULL object before deleting
- objects.RemoveIndex( 0 );
- objects.DeleteContents( true );
- }
- /*
- ================
- idRestoreGame::Error
- ================
- */
- void idRestoreGame::Error( const char *fmt, ... ) {
- va_list argptr;
- char text[ 1024 ];
- va_start( argptr, fmt );
- vsprintf( text, fmt, argptr );
- va_end( argptr );
- objects.DeleteContents( true );
- gameLocal.Error( "%s", text );
- }
- /*
- ================
- idRestoreGame::CallRestore_r
- ================
- */
- void idRestoreGame::CallRestore_r( const idTypeInfo *cls, idClass *obj ) {
- if ( cls->super ) {
- CallRestore_r( cls->super, obj );
- if ( cls->super->Restore == cls->Restore ) {
- // don't call save on this inheritance level since the function was called in the super class
- return;
- }
- }
-
- ( obj->*cls->Restore )( this );
- }
- /*
- ================
- idRestoreGame::Read
- ================
- */
- void idRestoreGame::Read( void *buffer, int len ) {
- file->Read( buffer, len );
- }
- /*
- ================
- idRestoreGame::ReadInt
- ================
- */
- void idRestoreGame::ReadInt( int &value ) {
- file->ReadInt( value );
- }
- /*
- ================
- idRestoreGame::ReadJoint
- ================
- */
- void idRestoreGame::ReadJoint( jointHandle_t &value ) {
- file->ReadInt( (int&)value );
- }
- /*
- ================
- idRestoreGame::ReadShort
- ================
- */
- void idRestoreGame::ReadShort( short &value ) {
- file->ReadShort( value );
- }
- /*
- ================
- idRestoreGame::ReadByte
- ================
- */
- void idRestoreGame::ReadByte( byte &value ) {
- file->Read( &value, sizeof( value ) );
- }
- /*
- ================
- idRestoreGame::ReadSignedChar
- ================
- */
- void idRestoreGame::ReadSignedChar( signed char &value ) {
- file->Read( &value, sizeof( value ) );
- }
- /*
- ================
- idRestoreGame::ReadFloat
- ================
- */
- void idRestoreGame::ReadFloat( float &value ) {
- file->ReadFloat( value );
- }
- /*
- ================
- idRestoreGame::ReadBool
- ================
- */
- void idRestoreGame::ReadBool( bool &value ) {
- file->ReadBool( value );
- }
- /*
- ================
- idRestoreGame::ReadString
- ================
- */
- void idRestoreGame::ReadString( idStr &string ) {
- int len;
- ReadInt( len );
- if ( len < 0 ) {
- Error( "idRestoreGame::ReadString: invalid length" );
- }
- string.Fill( ' ', len );
- file->Read( &string[ 0 ], len );
- }
- /*
- ================
- idRestoreGame::ReadVec2
- ================
- */
- void idRestoreGame::ReadVec2( idVec2 &vec ) {
- file->ReadVec2( vec );
- }
- /*
- ================
- idRestoreGame::ReadVec3
- ================
- */
- void idRestoreGame::ReadVec3( idVec3 &vec ) {
- file->ReadVec3( vec );
- }
- /*
- ================
- idRestoreGame::ReadVec4
- ================
- */
- void idRestoreGame::ReadVec4( idVec4 &vec ) {
- file->ReadVec4( vec );
- }
- /*
- ================
- idRestoreGame::ReadVec6
- ================
- */
- void idRestoreGame::ReadVec6( idVec6 &vec ) {
- file->ReadVec6( vec );
- }
- /*
- ================
- idRestoreGame::ReadBounds
- ================
- */
- void idRestoreGame::ReadBounds( idBounds &bounds ) {
- file->Read( &bounds, sizeof( bounds ) );
- LittleRevBytes( &bounds, sizeof(float), sizeof(bounds)/sizeof(float) );
- }
- /*
- ================
- idRestoreGame::ReadWinding
- ================
- */
- void idRestoreGame::ReadWinding( idWinding &w )
- {
- int i, num;
- file->ReadInt( num );
- w.SetNumPoints( num );
- for ( i = 0; i < num; i++ ) {
- file->Read( &w[i], sizeof(idVec5) );
- LittleRevBytes(&w[i], sizeof(float), sizeof(idVec5)/sizeof(float) );
- }
- }
- /*
- ================
- idRestoreGame::ReadMat3
- ================
- */
- void idRestoreGame::ReadMat3( idMat3 &mat ) {
- file->ReadMat3( mat );
- }
- /*
- ================
- idRestoreGame::ReadAngles
- ================
- */
- void idRestoreGame::ReadAngles( idAngles &angles ) {
- file->Read( &angles, sizeof( angles ) );
- LittleRevBytes(&angles, sizeof(float), sizeof(idAngles)/sizeof(float) );
- }
- /*
- ================
- idRestoreGame::ReadObject
- ================
- */
- void idRestoreGame::ReadObject( idClass *&obj ) {
- int index;
- ReadInt( index );
- if ( ( index < 0 ) || ( index >= objects.Num() ) ) {
- Error( "idRestoreGame::ReadObject: invalid object index" );
- }
- obj = objects[ index ];
- }
- /*
- ================
- idRestoreGame::ReadStaticObject
- ================
- */
- void idRestoreGame::ReadStaticObject( idClass &obj ) {
- CallRestore_r( obj.GetType(), &obj );
- }
- /*
- ================
- idRestoreGame::ReadDict
- ================
- */
- void idRestoreGame::ReadDict( idDict *dict ) {
- int num;
- int i;
- idStr key;
- idStr value;
- ReadInt( num );
- if ( num < 0 ) {
- dict = NULL;
- } else {
- dict->Clear();
- for( i = 0; i < num; i++ ) {
- ReadString( key );
- ReadString( value );
- dict->Set( key, value );
- }
- }
- }
- /*
- ================
- idRestoreGame::ReadMaterial
- ================
- */
- void idRestoreGame::ReadMaterial( const idMaterial *&material ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- material = NULL;
- } else {
- material = declManager->FindMaterial( name );
- }
- }
- /*
- ================
- idRestoreGame::ReadSkin
- ================
- */
- void idRestoreGame::ReadSkin( const idDeclSkin *&skin ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- skin = NULL;
- } else {
- skin = declManager->FindSkin( name );
- }
- }
- /*
- ================
- idRestoreGame::ReadParticle
- ================
- */
- void idRestoreGame::ReadParticle( const idDeclParticle *&particle ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- particle = NULL;
- } else {
- particle = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, name ) );
- }
- }
- /*
- ================
- idRestoreGame::ReadFX
- ================
- */
- void idRestoreGame::ReadFX( const idDeclFX *&fx ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- fx = NULL;
- } else {
- fx = static_cast<const idDeclFX *>( declManager->FindType( DECL_FX, name ) );
- }
- }
- /*
- ================
- idRestoreGame::ReadSoundShader
- ================
- */
- void idRestoreGame::ReadSoundShader( const idSoundShader *&shader ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- shader = NULL;
- } else {
- shader = declManager->FindSound( name );
- }
- }
- /*
- ================
- idRestoreGame::ReadModelDef
- ================
- */
- void idRestoreGame::ReadModelDef( const idDeclModelDef *&modelDef ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- modelDef = NULL;
- } else {
- modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, name, false ) );
- }
- }
- /*
- ================
- idRestoreGame::ReadModel
- ================
- */
- void idRestoreGame::ReadModel( idRenderModel *&model ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- model = NULL;
- } else {
- model = renderModelManager->FindModel( name );
- }
- }
- /*
- ================
- idRestoreGame::ReadUserInterface
- ================
- */
- void idRestoreGame::ReadUserInterface( idUserInterface *&ui ) {
- idStr name;
- ReadString( name );
- if ( !name.Length() ) {
- ui = NULL;
- } else {
- bool unique;
- ReadBool( unique );
- ui = uiManager->FindGui( name, true, unique );
- if ( ui ) {
- if ( ui->ReadFromSaveGame( file ) == false ) {
- Error( "idSaveGame::ReadUserInterface: ui failed to read properly\n" );
- } else {
- ui->StateChanged( gameLocal.time );
- }
- }
- }
- }
- /*
- ================
- idRestoreGame::ReadRenderEntity
- ================
- */
- void idRestoreGame::ReadRenderEntity( renderEntity_t &renderEntity ) {
- int i;
- int index;
- ReadModel( renderEntity.hModel );
- ReadInt( renderEntity.entityNum );
- ReadInt( renderEntity.bodyId );
- ReadBounds( renderEntity.bounds );
- // callback is set by class's Restore function
- renderEntity.callback = NULL;
- renderEntity.callbackData = NULL;
- ReadInt( renderEntity.suppressSurfaceInViewID );
- ReadInt( renderEntity.suppressShadowInViewID );
- ReadInt( renderEntity.suppressShadowInLightID );
- ReadInt( renderEntity.allowSurfaceInViewID );
- ReadVec3( renderEntity.origin );
- ReadMat3( renderEntity.axis );
- ReadMaterial( renderEntity.customShader );
- ReadMaterial( renderEntity.referenceShader );
- ReadSkin( renderEntity.customSkin );
- ReadInt( index );
- renderEntity.referenceSound = gameSoundWorld->EmitterForIndex( index );
- for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
- ReadFloat( renderEntity.shaderParms[ i ] );
- }
- for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
- ReadUserInterface( renderEntity.gui[ i ] );
- }
- // idEntity will restore "cameraTarget", which will be used in idEntity::Present to restore the remoteRenderView
- renderEntity.remoteRenderView = NULL;
- renderEntity.joints = NULL;
- renderEntity.numJoints = 0;
- ReadFloat( renderEntity.modelDepthHack );
- ReadBool( renderEntity.noSelfShadow );
- ReadBool( renderEntity.noShadow );
- ReadBool( renderEntity.noDynamicInteractions );
- ReadBool( renderEntity.weaponDepthHack );
- ReadInt( renderEntity.forceUpdate );
- }
- /*
- ================
- idRestoreGame::ReadRenderLight
- ================
- */
- void idRestoreGame::ReadRenderLight( renderLight_t &renderLight ) {
- int index;
- int i;
- ReadMat3( renderLight.axis );
- ReadVec3( renderLight.origin );
- ReadInt( renderLight.suppressLightInViewID );
- ReadInt( renderLight.allowLightInViewID );
- ReadBool( renderLight.noShadows );
- ReadBool( renderLight.noSpecular );
- ReadBool( renderLight.pointLight );
- ReadBool( renderLight.parallel );
- ReadVec3( renderLight.lightRadius );
- ReadVec3( renderLight.lightCenter );
- ReadVec3( renderLight.target );
- ReadVec3( renderLight.right );
- ReadVec3( renderLight.up );
- ReadVec3( renderLight.start );
- ReadVec3( renderLight.end );
- // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there
- // ReadModel( renderLight.prelightModel );
- renderLight.prelightModel = NULL;
- ReadInt( renderLight.lightId );
- ReadMaterial( renderLight.shader );
- for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
- ReadFloat( renderLight.shaderParms[ i ] );
- }
- ReadInt( index );
- renderLight.referenceSound = gameSoundWorld->EmitterForIndex( index );
- }
- /*
- ================
- idRestoreGame::ReadRefSound
- ================
- */
- void idRestoreGame::ReadRefSound( refSound_t &refSound ) {
- int index;
- ReadInt( index );
- refSound.referenceSound = gameSoundWorld->EmitterForIndex( index );
- ReadVec3( refSound.origin );
- ReadInt( refSound.listenerId );
- ReadSoundShader( refSound.shader );
- ReadFloat( refSound.diversity );
- ReadBool( refSound.waitfortrigger );
- ReadFloat( refSound.parms.minDistance );
- ReadFloat( refSound.parms.maxDistance );
- ReadFloat( refSound.parms.volume );
- ReadFloat( refSound.parms.shakes );
- ReadInt( refSound.parms.soundShaderFlags );
- ReadInt( refSound.parms.soundClass );
- }
- /*
- ================
- idRestoreGame::ReadRenderView
- ================
- */
- void idRestoreGame::ReadRenderView( renderView_t &view ) {
- int i;
- ReadInt( view.viewID );
- ReadInt( view.x );
- ReadInt( view.y );
- ReadInt( view.width );
- ReadInt( view.height );
- ReadFloat( view.fov_x );
- ReadFloat( view.fov_y );
- ReadVec3( view.vieworg );
- ReadMat3( view.viewaxis );
- ReadBool( view.cramZNear );
- ReadInt( view.time );
- for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
- ReadFloat( view.shaderParms[ i ] );
- }
- }
- /*
- =================
- idRestoreGame::ReadUsercmd
- =================
- */
- void idRestoreGame::ReadUsercmd( usercmd_t &usercmd ) {
- ReadInt( usercmd.gameFrame );
- ReadInt( usercmd.gameTime );
- ReadInt( usercmd.duplicateCount );
- ReadByte( usercmd.buttons );
- ReadSignedChar( usercmd.forwardmove );
- ReadSignedChar( usercmd.rightmove );
- ReadSignedChar( usercmd.upmove );
- ReadShort( usercmd.angles[0] );
- ReadShort( usercmd.angles[1] );
- ReadShort( usercmd.angles[2] );
- ReadShort( usercmd.mx );
- ReadShort( usercmd.my );
- ReadSignedChar( usercmd.impulse );
- ReadByte( usercmd.flags );
- ReadInt( usercmd.sequence );
- }
- /*
- ===================
- idRestoreGame::ReadContactInfo
- ===================
- */
- void idRestoreGame::ReadContactInfo( contactInfo_t &contactInfo ) {
- ReadInt( (int &)contactInfo.type );
- ReadVec3( contactInfo.point );
- ReadVec3( contactInfo.normal );
- ReadFloat( contactInfo.dist );
- ReadInt( contactInfo.contents );
- ReadMaterial( contactInfo.material );
- ReadInt( contactInfo.modelFeature );
- ReadInt( contactInfo.trmFeature );
- ReadInt( contactInfo.entityNum );
- ReadInt( contactInfo.id );
- }
- /*
- ===================
- idRestoreGame::ReadTrace
- ===================
- */
- void idRestoreGame::ReadTrace( trace_t &trace ) {
- ReadFloat( trace.fraction );
- ReadVec3( trace.endpos );
- ReadMat3( trace.endAxis );
- ReadContactInfo( trace.c );
- }
- /*
- ===================
- idRestoreGame::ReadTraceModel
- ===================
- */
- void idRestoreGame::ReadTraceModel( idTraceModel &trace ) {
- int j, k;
-
- ReadInt( (int&)trace.type );
- ReadInt( trace.numVerts );
- for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) {
- ReadVec3( trace.verts[j] );
- }
- ReadInt( trace.numEdges );
- for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) {
- ReadInt( trace.edges[j].v[0] );
- ReadInt( trace.edges[j].v[1] );
- ReadVec3( trace.edges[j].normal );
- }
- ReadInt( trace.numPolys );
- for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) {
- ReadVec3( trace.polys[j].normal );
- ReadFloat( trace.polys[j].dist );
- ReadBounds( trace.polys[j].bounds );
- ReadInt( trace.polys[j].numEdges );
- for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) {
- ReadInt( trace.polys[j].edges[k] );
- }
- }
- ReadVec3( trace.offset );
- ReadBounds( trace.bounds );
- ReadBool( trace.isConvex );
- // padding win32 native structs
- char tmp[3];
- file->Read( tmp, 3 );
- }
- /*
- =====================
- idRestoreGame::ReadClipModel
- =====================
- */
- void idRestoreGame::ReadClipModel( idClipModel *&clipModel ) {
- bool restoreClipModel;
- ReadBool( restoreClipModel );
- if ( restoreClipModel ) {
- clipModel = new idClipModel();
- clipModel->Restore( this );
- } else {
- clipModel = NULL;
- }
- }
- /*
- =====================
- idRestoreGame::ReadSoundCommands
- =====================
- */
- void idRestoreGame::ReadSoundCommands( void ) {
- gameSoundWorld->StopAllSounds();
- gameSoundWorld->ReadFromSaveGame( file );
- }
- /*
- =====================
- idRestoreGame::ReadBuildNumber
- =====================
- */
- void idRestoreGame::ReadBuildNumber( void ) {
- file->ReadInt( buildNumber );
- }
- /*
- =====================
- idRestoreGame::GetBuildNumber
- =====================
- */
- int idRestoreGame::GetBuildNumber( void ) {
- return buildNumber;
- }
|