1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558 |
- /*
- ===========================================================================
- 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 );
- #ifdef _D3XP
- WriteInt( renderEntity.timeGroup );
- WriteInt( renderEntity.xrayIndex );
- #endif
- }
- /*
- ================
- 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 );
- #ifdef _D3XP
- ReadInt( renderEntity.timeGroup );
- ReadInt( renderEntity.xrayIndex );
- #endif
- }
- /*
- ================
- 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;
- }
|