SaveGame.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. 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.
  17. 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.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "../Game_local.h"
  23. #include "TypeInfo.h"
  24. /*
  25. Save game related helper classes.
  26. Save games are implemented in two classes, idSaveGame and idRestoreGame, that implement write/read functions for
  27. common types. They're passed in to each entity and object for them to archive themselves. Each class
  28. implements save/restore functions for it's own data. When restoring, all the objects are instantiated,
  29. then the restore function is called on each, superclass first, then subclasses.
  30. Pointers are restored by saving out an object index for each unique object pointer and adding them to a list of
  31. objects that are to be saved. Restore instantiates all the objects in the list before calling the Restore function
  32. on each object so that the pointers returned are valid. No object's restore function should rely on any other objects
  33. being fully instantiated until after the restore process is complete. Post restore fixup should be done by posting
  34. events with 0 delay.
  35. The savegame header will have the Game Name, Version, Map Name, and Player Persistent Info.
  36. Changes in version make savegames incompatible, and the game will start from the beginning of the level with
  37. the player's persistent info.
  38. Changes to classes that don't need to break compatibilty can use the build number as the savegame version.
  39. Later versions are responsible for restoring from previous versions by ignoring any unused data and initializing
  40. variables that weren't in previous versions with safe information.
  41. At the head of the save game is enough information to restore the player to the beginning of the level should the
  42. file be unloadable in some way (for example, due to script changes).
  43. */
  44. /*
  45. ================
  46. idSaveGame::idSaveGame()
  47. ================
  48. */
  49. idSaveGame::idSaveGame( idFile *savefile ) {
  50. file = savefile;
  51. // Put NULL at the start of the list so we can skip over it.
  52. objects.Clear();
  53. objects.Append( NULL );
  54. }
  55. /*
  56. ================
  57. idSaveGame::~idSaveGame()
  58. ================
  59. */
  60. idSaveGame::~idSaveGame() {
  61. if ( objects.Num() ) {
  62. Close();
  63. }
  64. }
  65. /*
  66. ================
  67. idSaveGame::Close
  68. ================
  69. */
  70. void idSaveGame::Close( void ) {
  71. int i;
  72. WriteSoundCommands();
  73. // read trace models
  74. idClipModel::SaveTraceModels( this );
  75. for( i = 1; i < objects.Num(); i++ ) {
  76. CallSave_r( objects[ i ]->GetType(), objects[ i ] );
  77. }
  78. objects.Clear();
  79. #ifdef ID_DEBUG_MEMORY
  80. idStr gameState = file->GetName();
  81. gameState.StripFileExtension();
  82. WriteGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ), false ) );
  83. #endif
  84. }
  85. /*
  86. ================
  87. idSaveGame::WriteObjectList
  88. ================
  89. */
  90. void idSaveGame::WriteObjectList( void ) {
  91. int i;
  92. WriteInt( objects.Num() - 1 );
  93. for( i = 1; i < objects.Num(); i++ ) {
  94. WriteString( objects[ i ]->GetClassname() );
  95. }
  96. }
  97. /*
  98. ================
  99. idSaveGame::CallSave_r
  100. ================
  101. */
  102. void idSaveGame::CallSave_r( const idTypeInfo *cls, const idClass *obj ) {
  103. if ( cls->super ) {
  104. CallSave_r( cls->super, obj );
  105. if ( cls->super->Save == cls->Save ) {
  106. // don't call save on this inheritance level since the function was called in the super class
  107. return;
  108. }
  109. }
  110. ( obj->*cls->Save )( this );
  111. }
  112. /*
  113. ================
  114. idSaveGame::AddObject
  115. ================
  116. */
  117. void idSaveGame::AddObject( const idClass *obj ) {
  118. objects.AddUnique( obj );
  119. }
  120. /*
  121. ================
  122. idSaveGame::Write
  123. ================
  124. */
  125. void idSaveGame::Write( const void *buffer, int len ) {
  126. file->Write( buffer, len );
  127. }
  128. /*
  129. ================
  130. idSaveGame::WriteInt
  131. ================
  132. */
  133. void idSaveGame::WriteInt( const int value ) {
  134. file->WriteInt( value );
  135. }
  136. /*
  137. ================
  138. idSaveGame::WriteJoint
  139. ================
  140. */
  141. void idSaveGame::WriteJoint( const jointHandle_t value ) {
  142. file->WriteInt( (int&)value );
  143. }
  144. /*
  145. ================
  146. idSaveGame::WriteShort
  147. ================
  148. */
  149. void idSaveGame::WriteShort( const short value ) {
  150. file->WriteShort( value );
  151. }
  152. /*
  153. ================
  154. idSaveGame::WriteByte
  155. ================
  156. */
  157. void idSaveGame::WriteByte( const byte value ) {
  158. file->Write( &value, sizeof( value ) );
  159. }
  160. /*
  161. ================
  162. idSaveGame::WriteSignedChar
  163. ================
  164. */
  165. void idSaveGame::WriteSignedChar( const signed char value ) {
  166. file->Write( &value, sizeof( value ) );
  167. }
  168. /*
  169. ================
  170. idSaveGame::WriteFloat
  171. ================
  172. */
  173. void idSaveGame::WriteFloat( const float value ) {
  174. file->WriteFloat( value );
  175. }
  176. /*
  177. ================
  178. idSaveGame::WriteBool
  179. ================
  180. */
  181. void idSaveGame::WriteBool( const bool value ) {
  182. file->WriteBool( value );
  183. }
  184. /*
  185. ================
  186. idSaveGame::WriteString
  187. ================
  188. */
  189. void idSaveGame::WriteString( const char *string ) {
  190. int len;
  191. len = strlen( string );
  192. WriteInt( len );
  193. file->Write( string, len );
  194. }
  195. /*
  196. ================
  197. idSaveGame::WriteVec2
  198. ================
  199. */
  200. void idSaveGame::WriteVec2( const idVec2 &vec ) {
  201. file->WriteVec2( vec );
  202. }
  203. /*
  204. ================
  205. idSaveGame::WriteVec3
  206. ================
  207. */
  208. void idSaveGame::WriteVec3( const idVec3 &vec ) {
  209. file->WriteVec3( vec );
  210. }
  211. /*
  212. ================
  213. idSaveGame::WriteVec4
  214. ================
  215. */
  216. void idSaveGame::WriteVec4( const idVec4 &vec ) {
  217. file->WriteVec4( vec );
  218. }
  219. /*
  220. ================
  221. idSaveGame::WriteVec6
  222. ================
  223. */
  224. void idSaveGame::WriteVec6( const idVec6 &vec ) {
  225. file->WriteVec6( vec );
  226. }
  227. /*
  228. ================
  229. idSaveGame::WriteBounds
  230. ================
  231. */
  232. void idSaveGame::WriteBounds( const idBounds &bounds ) {
  233. idBounds b = bounds;
  234. LittleRevBytes( &b, sizeof(float), sizeof(b)/sizeof(float) );
  235. file->Write( &b, sizeof( b ) );
  236. }
  237. /*
  238. ================
  239. idSaveGame::WriteBounds
  240. ================
  241. */
  242. void idSaveGame::WriteWinding( const idWinding &w )
  243. {
  244. int i, num;
  245. num = w.GetNumPoints();
  246. file->WriteInt( num );
  247. for ( i = 0; i < num; i++ ) {
  248. idVec5 v = w[i];
  249. LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
  250. file->Write( &v, sizeof(v) );
  251. }
  252. }
  253. /*
  254. ================
  255. idSaveGame::WriteMat3
  256. ================
  257. */
  258. void idSaveGame::WriteMat3( const idMat3 &mat ) {
  259. file->WriteMat3( mat );
  260. }
  261. /*
  262. ================
  263. idSaveGame::WriteAngles
  264. ================
  265. */
  266. void idSaveGame::WriteAngles( const idAngles &angles ) {
  267. idAngles v = angles;
  268. LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
  269. file->Write( &v, sizeof( v ) );
  270. }
  271. /*
  272. ================
  273. idSaveGame::WriteObject
  274. ================
  275. */
  276. void idSaveGame::WriteObject( const idClass *obj ) {
  277. int index;
  278. index = objects.FindIndex( obj );
  279. if ( index < 0 ) {
  280. gameLocal.DPrintf( "idSaveGame::WriteObject - WriteObject FindIndex failed\n" );
  281. // Use the NULL index
  282. index = 0;
  283. }
  284. WriteInt( index );
  285. }
  286. /*
  287. ================
  288. idSaveGame::WriteStaticObject
  289. ================
  290. */
  291. void idSaveGame::WriteStaticObject( const idClass &obj ) {
  292. CallSave_r( obj.GetType(), &obj );
  293. }
  294. /*
  295. ================
  296. idSaveGame::WriteDict
  297. ================
  298. */
  299. void idSaveGame::WriteDict( const idDict *dict ) {
  300. int num;
  301. int i;
  302. const idKeyValue *kv;
  303. if ( !dict ) {
  304. WriteInt( -1 );
  305. } else {
  306. num = dict->GetNumKeyVals();
  307. WriteInt( num );
  308. for( i = 0; i < num; i++ ) {
  309. kv = dict->GetKeyVal( i );
  310. WriteString( kv->GetKey() );
  311. WriteString( kv->GetValue() );
  312. }
  313. }
  314. }
  315. /*
  316. ================
  317. idSaveGame::WriteMaterial
  318. ================
  319. */
  320. void idSaveGame::WriteMaterial( const idMaterial *material ) {
  321. if ( !material ) {
  322. WriteString( "" );
  323. } else {
  324. WriteString( material->GetName() );
  325. }
  326. }
  327. /*
  328. ================
  329. idSaveGame::WriteSkin
  330. ================
  331. */
  332. void idSaveGame::WriteSkin( const idDeclSkin *skin ) {
  333. if ( !skin ) {
  334. WriteString( "" );
  335. } else {
  336. WriteString( skin->GetName() );
  337. }
  338. }
  339. /*
  340. ================
  341. idSaveGame::WriteParticle
  342. ================
  343. */
  344. void idSaveGame::WriteParticle( const idDeclParticle *particle ) {
  345. if ( !particle ) {
  346. WriteString( "" );
  347. } else {
  348. WriteString( particle->GetName() );
  349. }
  350. }
  351. /*
  352. ================
  353. idSaveGame::WriteFX
  354. ================
  355. */
  356. void idSaveGame::WriteFX( const idDeclFX *fx ) {
  357. if ( !fx ) {
  358. WriteString( "" );
  359. } else {
  360. WriteString( fx->GetName() );
  361. }
  362. }
  363. /*
  364. ================
  365. idSaveGame::WriteModelDef
  366. ================
  367. */
  368. void idSaveGame::WriteModelDef( const idDeclModelDef *modelDef ) {
  369. if ( !modelDef ) {
  370. WriteString( "" );
  371. } else {
  372. WriteString( modelDef->GetName() );
  373. }
  374. }
  375. /*
  376. ================
  377. idSaveGame::WriteSoundShader
  378. ================
  379. */
  380. void idSaveGame::WriteSoundShader( const idSoundShader *shader ) {
  381. const char *name;
  382. if ( !shader ) {
  383. WriteString( "" );
  384. } else {
  385. name = shader->GetName();
  386. WriteString( name );
  387. }
  388. }
  389. /*
  390. ================
  391. idSaveGame::WriteModel
  392. ================
  393. */
  394. void idSaveGame::WriteModel( const idRenderModel *model ) {
  395. const char *name;
  396. if ( !model ) {
  397. WriteString( "" );
  398. } else {
  399. name = model->Name();
  400. WriteString( name );
  401. }
  402. }
  403. /*
  404. ================
  405. idSaveGame::WriteUserInterface
  406. ================
  407. */
  408. void idSaveGame::WriteUserInterface( const idUserInterface *ui, bool unique ) {
  409. const char *name;
  410. if ( !ui ) {
  411. WriteString( "" );
  412. } else {
  413. name = ui->Name();
  414. WriteString( name );
  415. WriteBool( unique );
  416. if ( ui->WriteToSaveGame( file ) == false ) {
  417. gameLocal.Error( "idSaveGame::WriteUserInterface: ui failed to write properly\n" );
  418. }
  419. }
  420. }
  421. /*
  422. ================
  423. idSaveGame::WriteRenderEntity
  424. ================
  425. */
  426. void idSaveGame::WriteRenderEntity( const renderEntity_t &renderEntity ) {
  427. int i;
  428. WriteModel( renderEntity.hModel );
  429. WriteInt( renderEntity.entityNum );
  430. WriteInt( renderEntity.bodyId );
  431. WriteBounds( renderEntity.bounds );
  432. // callback is set by class's Restore function
  433. WriteInt( renderEntity.suppressSurfaceInViewID );
  434. WriteInt( renderEntity.suppressShadowInViewID );
  435. WriteInt( renderEntity.suppressShadowInLightID );
  436. WriteInt( renderEntity.allowSurfaceInViewID );
  437. WriteVec3( renderEntity.origin );
  438. WriteMat3( renderEntity.axis );
  439. WriteMaterial( renderEntity.customShader );
  440. WriteMaterial( renderEntity.referenceShader );
  441. WriteSkin( renderEntity.customSkin );
  442. if ( renderEntity.referenceSound != NULL ) {
  443. WriteInt( renderEntity.referenceSound->Index() );
  444. } else {
  445. WriteInt( 0 );
  446. }
  447. for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
  448. WriteFloat( renderEntity.shaderParms[ i ] );
  449. }
  450. for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
  451. WriteUserInterface( renderEntity.gui[ i ], renderEntity.gui[ i ] ? renderEntity.gui[ i ]->IsUniqued() : false );
  452. }
  453. WriteFloat( renderEntity.modelDepthHack );
  454. WriteBool( renderEntity.noSelfShadow );
  455. WriteBool( renderEntity.noShadow );
  456. WriteBool( renderEntity.noDynamicInteractions );
  457. WriteBool( renderEntity.weaponDepthHack );
  458. WriteInt( renderEntity.forceUpdate );
  459. }
  460. /*
  461. ================
  462. idSaveGame::WriteRenderLight
  463. ================
  464. */
  465. void idSaveGame::WriteRenderLight( const renderLight_t &renderLight ) {
  466. int i;
  467. WriteMat3( renderLight.axis );
  468. WriteVec3( renderLight.origin );
  469. WriteInt( renderLight.suppressLightInViewID );
  470. WriteInt( renderLight.allowLightInViewID );
  471. WriteBool( renderLight.noShadows );
  472. WriteBool( renderLight.noSpecular );
  473. WriteBool( renderLight.pointLight );
  474. WriteBool( renderLight.parallel );
  475. WriteVec3( renderLight.lightRadius );
  476. WriteVec3( renderLight.lightCenter );
  477. WriteVec3( renderLight.target );
  478. WriteVec3( renderLight.right );
  479. WriteVec3( renderLight.up );
  480. WriteVec3( renderLight.start );
  481. WriteVec3( renderLight.end );
  482. // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there
  483. // WriteModel( renderLight.prelightModel );
  484. WriteInt( renderLight.lightId );
  485. WriteMaterial( renderLight.shader );
  486. for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
  487. WriteFloat( renderLight.shaderParms[ i ] );
  488. }
  489. if ( renderLight.referenceSound != NULL ) {
  490. WriteInt( renderLight.referenceSound->Index() );
  491. } else {
  492. WriteInt( 0 );
  493. }
  494. }
  495. /*
  496. ================
  497. idSaveGame::WriteRefSound
  498. ================
  499. */
  500. void idSaveGame::WriteRefSound( const refSound_t &refSound ) {
  501. if ( refSound.referenceSound ) {
  502. WriteInt( refSound.referenceSound->Index() );
  503. } else {
  504. WriteInt( 0 );
  505. }
  506. WriteVec3( refSound.origin );
  507. WriteInt( refSound.listenerId );
  508. WriteSoundShader( refSound.shader );
  509. WriteFloat( refSound.diversity );
  510. WriteBool( refSound.waitfortrigger );
  511. WriteFloat( refSound.parms.minDistance );
  512. WriteFloat( refSound.parms.maxDistance );
  513. WriteFloat( refSound.parms.volume );
  514. WriteFloat( refSound.parms.shakes );
  515. WriteInt( refSound.parms.soundShaderFlags );
  516. WriteInt( refSound.parms.soundClass );
  517. }
  518. /*
  519. ================
  520. idSaveGame::WriteRenderView
  521. ================
  522. */
  523. void idSaveGame::WriteRenderView( const renderView_t &view ) {
  524. int i;
  525. WriteInt( view.viewID );
  526. WriteInt( view.x );
  527. WriteInt( view.y );
  528. WriteInt( view.width );
  529. WriteInt( view.height );
  530. WriteFloat( view.fov_x );
  531. WriteFloat( view.fov_y );
  532. WriteVec3( view.vieworg );
  533. WriteMat3( view.viewaxis );
  534. WriteBool( view.cramZNear );
  535. WriteInt( view.time );
  536. for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
  537. WriteFloat( view.shaderParms[ i ] );
  538. }
  539. }
  540. /*
  541. ===================
  542. idSaveGame::WriteUsercmd
  543. ===================
  544. */
  545. void idSaveGame::WriteUsercmd( const usercmd_t &usercmd ) {
  546. WriteInt( usercmd.gameFrame );
  547. WriteInt( usercmd.gameTime );
  548. WriteInt( usercmd.duplicateCount );
  549. WriteByte( usercmd.buttons );
  550. WriteSignedChar( usercmd.forwardmove );
  551. WriteSignedChar( usercmd.rightmove );
  552. WriteSignedChar( usercmd.upmove );
  553. WriteShort( usercmd.angles[0] );
  554. WriteShort( usercmd.angles[1] );
  555. WriteShort( usercmd.angles[2] );
  556. WriteShort( usercmd.mx );
  557. WriteShort( usercmd.my );
  558. WriteSignedChar( usercmd.impulse );
  559. WriteByte( usercmd.flags );
  560. WriteInt( usercmd.sequence );
  561. }
  562. /*
  563. ===================
  564. idSaveGame::WriteContactInfo
  565. ===================
  566. */
  567. void idSaveGame::WriteContactInfo( const contactInfo_t &contactInfo ) {
  568. WriteInt( (int)contactInfo.type );
  569. WriteVec3( contactInfo.point );
  570. WriteVec3( contactInfo.normal );
  571. WriteFloat( contactInfo.dist );
  572. WriteInt( contactInfo.contents );
  573. WriteMaterial( contactInfo.material );
  574. WriteInt( contactInfo.modelFeature );
  575. WriteInt( contactInfo.trmFeature );
  576. WriteInt( contactInfo.entityNum );
  577. WriteInt( contactInfo.id );
  578. }
  579. /*
  580. ===================
  581. idSaveGame::WriteTrace
  582. ===================
  583. */
  584. void idSaveGame::WriteTrace( const trace_t &trace ) {
  585. WriteFloat( trace.fraction );
  586. WriteVec3( trace.endpos );
  587. WriteMat3( trace.endAxis );
  588. WriteContactInfo( trace.c );
  589. }
  590. /*
  591. ===================
  592. idRestoreGame::WriteTraceModel
  593. ===================
  594. */
  595. void idSaveGame::WriteTraceModel( const idTraceModel &trace ) {
  596. int j, k;
  597. WriteInt( (int&)trace.type );
  598. WriteInt( trace.numVerts );
  599. for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) {
  600. WriteVec3( trace.verts[j] );
  601. }
  602. WriteInt( trace.numEdges );
  603. for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) {
  604. WriteInt( trace.edges[j].v[0] );
  605. WriteInt( trace.edges[j].v[1] );
  606. WriteVec3( trace.edges[j].normal );
  607. }
  608. WriteInt( trace.numPolys );
  609. for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) {
  610. WriteVec3( trace.polys[j].normal );
  611. WriteFloat( trace.polys[j].dist );
  612. WriteBounds( trace.polys[j].bounds );
  613. WriteInt( trace.polys[j].numEdges );
  614. for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) {
  615. WriteInt( trace.polys[j].edges[k] );
  616. }
  617. }
  618. WriteVec3( trace.offset );
  619. WriteBounds( trace.bounds );
  620. WriteBool( trace.isConvex );
  621. // padding win32 native structs
  622. char tmp[3];
  623. memset( tmp, 0, sizeof( tmp ) );
  624. file->Write( tmp, 3 );
  625. }
  626. /*
  627. ===================
  628. idSaveGame::WriteClipModel
  629. ===================
  630. */
  631. void idSaveGame::WriteClipModel( const idClipModel *clipModel ) {
  632. if ( clipModel != NULL ) {
  633. WriteBool( true );
  634. clipModel->Save( this );
  635. } else {
  636. WriteBool( false );
  637. }
  638. }
  639. /*
  640. ===================
  641. idSaveGame::WriteSoundCommands
  642. ===================
  643. */
  644. void idSaveGame::WriteSoundCommands( void ) {
  645. gameSoundWorld->WriteToSaveGame( file );
  646. }
  647. /*
  648. ======================
  649. idSaveGame::WriteBuildNumber
  650. ======================
  651. */
  652. void idSaveGame::WriteBuildNumber( const int value ) {
  653. file->WriteInt( BUILD_NUMBER );
  654. }
  655. /***********************************************************************
  656. idRestoreGame
  657. ***********************************************************************/
  658. /*
  659. ================
  660. idRestoreGame::RestoreGame
  661. ================
  662. */
  663. idRestoreGame::idRestoreGame( idFile *savefile ) {
  664. file = savefile;
  665. }
  666. /*
  667. ================
  668. idRestoreGame::~idRestoreGame()
  669. ================
  670. */
  671. idRestoreGame::~idRestoreGame() {
  672. }
  673. /*
  674. ================
  675. void idRestoreGame::CreateObjects
  676. ================
  677. */
  678. void idRestoreGame::CreateObjects( void ) {
  679. int i, num;
  680. idStr classname;
  681. idTypeInfo *type;
  682. ReadInt( num );
  683. // create all the objects
  684. objects.SetNum( num + 1 );
  685. memset( objects.Ptr(), 0, sizeof( objects[ 0 ] ) * objects.Num() );
  686. for( i = 1; i < objects.Num(); i++ ) {
  687. ReadString( classname );
  688. type = idClass::GetClass( classname );
  689. if ( !type ) {
  690. Error( "idRestoreGame::CreateObjects: Unknown class '%s'", classname.c_str() );
  691. }
  692. objects[ i ] = type->CreateInstance();
  693. #ifdef ID_DEBUG_MEMORY
  694. InitTypeVariables( objects[i], type->classname, 0xce );
  695. #endif
  696. }
  697. }
  698. /*
  699. ================
  700. void idRestoreGame::RestoreObjects
  701. ================
  702. */
  703. void idRestoreGame::RestoreObjects( void ) {
  704. int i;
  705. ReadSoundCommands();
  706. // read trace models
  707. idClipModel::RestoreTraceModels( this );
  708. // restore all the objects
  709. for( i = 1; i < objects.Num(); i++ ) {
  710. CallRestore_r( objects[ i ]->GetType(), objects[ i ] );
  711. }
  712. // regenerate render entities and render lights because are not saved
  713. for( i = 1; i < objects.Num(); i++ ) {
  714. if ( objects[ i ]->IsType( idEntity::Type ) ) {
  715. idEntity *ent = static_cast<idEntity *>( objects[ i ] );
  716. ent->UpdateVisuals();
  717. ent->Present();
  718. }
  719. }
  720. #ifdef ID_DEBUG_MEMORY
  721. idStr gameState = file->GetName();
  722. gameState.StripFileExtension();
  723. WriteGameState_f( idCmdArgs( va( "test %s_restore", gameState.c_str() ), false ) );
  724. //CompareGameState_f( idCmdArgs( va( "test %s_save", gameState.c_str() ) ) );
  725. gameLocal.Error( "dumped game states" );
  726. #endif
  727. }
  728. /*
  729. ====================
  730. void idRestoreGame::DeleteObjects
  731. ====================
  732. */
  733. void idRestoreGame::DeleteObjects( void ) {
  734. // Remove the NULL object before deleting
  735. objects.RemoveIndex( 0 );
  736. objects.DeleteContents( true );
  737. }
  738. /*
  739. ================
  740. idRestoreGame::Error
  741. ================
  742. */
  743. void idRestoreGame::Error( const char *fmt, ... ) {
  744. va_list argptr;
  745. char text[ 1024 ];
  746. va_start( argptr, fmt );
  747. vsprintf( text, fmt, argptr );
  748. va_end( argptr );
  749. objects.DeleteContents( true );
  750. gameLocal.Error( "%s", text );
  751. }
  752. /*
  753. ================
  754. idRestoreGame::CallRestore_r
  755. ================
  756. */
  757. void idRestoreGame::CallRestore_r( const idTypeInfo *cls, idClass *obj ) {
  758. if ( cls->super ) {
  759. CallRestore_r( cls->super, obj );
  760. if ( cls->super->Restore == cls->Restore ) {
  761. // don't call save on this inheritance level since the function was called in the super class
  762. return;
  763. }
  764. }
  765. ( obj->*cls->Restore )( this );
  766. }
  767. /*
  768. ================
  769. idRestoreGame::Read
  770. ================
  771. */
  772. void idRestoreGame::Read( void *buffer, int len ) {
  773. file->Read( buffer, len );
  774. }
  775. /*
  776. ================
  777. idRestoreGame::ReadInt
  778. ================
  779. */
  780. void idRestoreGame::ReadInt( int &value ) {
  781. file->ReadInt( value );
  782. }
  783. /*
  784. ================
  785. idRestoreGame::ReadJoint
  786. ================
  787. */
  788. void idRestoreGame::ReadJoint( jointHandle_t &value ) {
  789. file->ReadInt( (int&)value );
  790. }
  791. /*
  792. ================
  793. idRestoreGame::ReadShort
  794. ================
  795. */
  796. void idRestoreGame::ReadShort( short &value ) {
  797. file->ReadShort( value );
  798. }
  799. /*
  800. ================
  801. idRestoreGame::ReadByte
  802. ================
  803. */
  804. void idRestoreGame::ReadByte( byte &value ) {
  805. file->Read( &value, sizeof( value ) );
  806. }
  807. /*
  808. ================
  809. idRestoreGame::ReadSignedChar
  810. ================
  811. */
  812. void idRestoreGame::ReadSignedChar( signed char &value ) {
  813. file->Read( &value, sizeof( value ) );
  814. }
  815. /*
  816. ================
  817. idRestoreGame::ReadFloat
  818. ================
  819. */
  820. void idRestoreGame::ReadFloat( float &value ) {
  821. file->ReadFloat( value );
  822. }
  823. /*
  824. ================
  825. idRestoreGame::ReadBool
  826. ================
  827. */
  828. void idRestoreGame::ReadBool( bool &value ) {
  829. file->ReadBool( value );
  830. }
  831. /*
  832. ================
  833. idRestoreGame::ReadString
  834. ================
  835. */
  836. void idRestoreGame::ReadString( idStr &string ) {
  837. int len;
  838. ReadInt( len );
  839. if ( len < 0 ) {
  840. Error( "idRestoreGame::ReadString: invalid length" );
  841. }
  842. string.Fill( ' ', len );
  843. file->Read( &string[ 0 ], len );
  844. }
  845. /*
  846. ================
  847. idRestoreGame::ReadVec2
  848. ================
  849. */
  850. void idRestoreGame::ReadVec2( idVec2 &vec ) {
  851. file->ReadVec2( vec );
  852. }
  853. /*
  854. ================
  855. idRestoreGame::ReadVec3
  856. ================
  857. */
  858. void idRestoreGame::ReadVec3( idVec3 &vec ) {
  859. file->ReadVec3( vec );
  860. }
  861. /*
  862. ================
  863. idRestoreGame::ReadVec4
  864. ================
  865. */
  866. void idRestoreGame::ReadVec4( idVec4 &vec ) {
  867. file->ReadVec4( vec );
  868. }
  869. /*
  870. ================
  871. idRestoreGame::ReadVec6
  872. ================
  873. */
  874. void idRestoreGame::ReadVec6( idVec6 &vec ) {
  875. file->ReadVec6( vec );
  876. }
  877. /*
  878. ================
  879. idRestoreGame::ReadBounds
  880. ================
  881. */
  882. void idRestoreGame::ReadBounds( idBounds &bounds ) {
  883. file->Read( &bounds, sizeof( bounds ) );
  884. LittleRevBytes( &bounds, sizeof(float), sizeof(bounds)/sizeof(float) );
  885. }
  886. /*
  887. ================
  888. idRestoreGame::ReadWinding
  889. ================
  890. */
  891. void idRestoreGame::ReadWinding( idWinding &w )
  892. {
  893. int i, num;
  894. file->ReadInt( num );
  895. w.SetNumPoints( num );
  896. for ( i = 0; i < num; i++ ) {
  897. file->Read( &w[i], sizeof(idVec5) );
  898. LittleRevBytes(&w[i], sizeof(float), sizeof(idVec5)/sizeof(float) );
  899. }
  900. }
  901. /*
  902. ================
  903. idRestoreGame::ReadMat3
  904. ================
  905. */
  906. void idRestoreGame::ReadMat3( idMat3 &mat ) {
  907. file->ReadMat3( mat );
  908. }
  909. /*
  910. ================
  911. idRestoreGame::ReadAngles
  912. ================
  913. */
  914. void idRestoreGame::ReadAngles( idAngles &angles ) {
  915. file->Read( &angles, sizeof( angles ) );
  916. LittleRevBytes(&angles, sizeof(float), sizeof(idAngles)/sizeof(float) );
  917. }
  918. /*
  919. ================
  920. idRestoreGame::ReadObject
  921. ================
  922. */
  923. void idRestoreGame::ReadObject( idClass *&obj ) {
  924. int index;
  925. ReadInt( index );
  926. if ( ( index < 0 ) || ( index >= objects.Num() ) ) {
  927. Error( "idRestoreGame::ReadObject: invalid object index" );
  928. }
  929. obj = objects[ index ];
  930. }
  931. /*
  932. ================
  933. idRestoreGame::ReadStaticObject
  934. ================
  935. */
  936. void idRestoreGame::ReadStaticObject( idClass &obj ) {
  937. CallRestore_r( obj.GetType(), &obj );
  938. }
  939. /*
  940. ================
  941. idRestoreGame::ReadDict
  942. ================
  943. */
  944. void idRestoreGame::ReadDict( idDict *dict ) {
  945. int num;
  946. int i;
  947. idStr key;
  948. idStr value;
  949. ReadInt( num );
  950. if ( num < 0 ) {
  951. dict = NULL;
  952. } else {
  953. dict->Clear();
  954. for( i = 0; i < num; i++ ) {
  955. ReadString( key );
  956. ReadString( value );
  957. dict->Set( key, value );
  958. }
  959. }
  960. }
  961. /*
  962. ================
  963. idRestoreGame::ReadMaterial
  964. ================
  965. */
  966. void idRestoreGame::ReadMaterial( const idMaterial *&material ) {
  967. idStr name;
  968. ReadString( name );
  969. if ( !name.Length() ) {
  970. material = NULL;
  971. } else {
  972. material = declManager->FindMaterial( name );
  973. }
  974. }
  975. /*
  976. ================
  977. idRestoreGame::ReadSkin
  978. ================
  979. */
  980. void idRestoreGame::ReadSkin( const idDeclSkin *&skin ) {
  981. idStr name;
  982. ReadString( name );
  983. if ( !name.Length() ) {
  984. skin = NULL;
  985. } else {
  986. skin = declManager->FindSkin( name );
  987. }
  988. }
  989. /*
  990. ================
  991. idRestoreGame::ReadParticle
  992. ================
  993. */
  994. void idRestoreGame::ReadParticle( const idDeclParticle *&particle ) {
  995. idStr name;
  996. ReadString( name );
  997. if ( !name.Length() ) {
  998. particle = NULL;
  999. } else {
  1000. particle = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, name ) );
  1001. }
  1002. }
  1003. /*
  1004. ================
  1005. idRestoreGame::ReadFX
  1006. ================
  1007. */
  1008. void idRestoreGame::ReadFX( const idDeclFX *&fx ) {
  1009. idStr name;
  1010. ReadString( name );
  1011. if ( !name.Length() ) {
  1012. fx = NULL;
  1013. } else {
  1014. fx = static_cast<const idDeclFX *>( declManager->FindType( DECL_FX, name ) );
  1015. }
  1016. }
  1017. /*
  1018. ================
  1019. idRestoreGame::ReadSoundShader
  1020. ================
  1021. */
  1022. void idRestoreGame::ReadSoundShader( const idSoundShader *&shader ) {
  1023. idStr name;
  1024. ReadString( name );
  1025. if ( !name.Length() ) {
  1026. shader = NULL;
  1027. } else {
  1028. shader = declManager->FindSound( name );
  1029. }
  1030. }
  1031. /*
  1032. ================
  1033. idRestoreGame::ReadModelDef
  1034. ================
  1035. */
  1036. void idRestoreGame::ReadModelDef( const idDeclModelDef *&modelDef ) {
  1037. idStr name;
  1038. ReadString( name );
  1039. if ( !name.Length() ) {
  1040. modelDef = NULL;
  1041. } else {
  1042. modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, name, false ) );
  1043. }
  1044. }
  1045. /*
  1046. ================
  1047. idRestoreGame::ReadModel
  1048. ================
  1049. */
  1050. void idRestoreGame::ReadModel( idRenderModel *&model ) {
  1051. idStr name;
  1052. ReadString( name );
  1053. if ( !name.Length() ) {
  1054. model = NULL;
  1055. } else {
  1056. model = renderModelManager->FindModel( name );
  1057. }
  1058. }
  1059. /*
  1060. ================
  1061. idRestoreGame::ReadUserInterface
  1062. ================
  1063. */
  1064. void idRestoreGame::ReadUserInterface( idUserInterface *&ui ) {
  1065. idStr name;
  1066. ReadString( name );
  1067. if ( !name.Length() ) {
  1068. ui = NULL;
  1069. } else {
  1070. bool unique;
  1071. ReadBool( unique );
  1072. ui = uiManager->FindGui( name, true, unique );
  1073. if ( ui ) {
  1074. if ( ui->ReadFromSaveGame( file ) == false ) {
  1075. Error( "idSaveGame::ReadUserInterface: ui failed to read properly\n" );
  1076. } else {
  1077. ui->StateChanged( gameLocal.time );
  1078. }
  1079. }
  1080. }
  1081. }
  1082. /*
  1083. ================
  1084. idRestoreGame::ReadRenderEntity
  1085. ================
  1086. */
  1087. void idRestoreGame::ReadRenderEntity( renderEntity_t &renderEntity ) {
  1088. int i;
  1089. int index;
  1090. ReadModel( renderEntity.hModel );
  1091. ReadInt( renderEntity.entityNum );
  1092. ReadInt( renderEntity.bodyId );
  1093. ReadBounds( renderEntity.bounds );
  1094. // callback is set by class's Restore function
  1095. renderEntity.callback = NULL;
  1096. renderEntity.callbackData = NULL;
  1097. ReadInt( renderEntity.suppressSurfaceInViewID );
  1098. ReadInt( renderEntity.suppressShadowInViewID );
  1099. ReadInt( renderEntity.suppressShadowInLightID );
  1100. ReadInt( renderEntity.allowSurfaceInViewID );
  1101. ReadVec3( renderEntity.origin );
  1102. ReadMat3( renderEntity.axis );
  1103. ReadMaterial( renderEntity.customShader );
  1104. ReadMaterial( renderEntity.referenceShader );
  1105. ReadSkin( renderEntity.customSkin );
  1106. ReadInt( index );
  1107. renderEntity.referenceSound = gameSoundWorld->EmitterForIndex( index );
  1108. for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
  1109. ReadFloat( renderEntity.shaderParms[ i ] );
  1110. }
  1111. for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
  1112. ReadUserInterface( renderEntity.gui[ i ] );
  1113. }
  1114. // idEntity will restore "cameraTarget", which will be used in idEntity::Present to restore the remoteRenderView
  1115. renderEntity.remoteRenderView = NULL;
  1116. renderEntity.joints = NULL;
  1117. renderEntity.numJoints = 0;
  1118. ReadFloat( renderEntity.modelDepthHack );
  1119. ReadBool( renderEntity.noSelfShadow );
  1120. ReadBool( renderEntity.noShadow );
  1121. ReadBool( renderEntity.noDynamicInteractions );
  1122. ReadBool( renderEntity.weaponDepthHack );
  1123. ReadInt( renderEntity.forceUpdate );
  1124. }
  1125. /*
  1126. ================
  1127. idRestoreGame::ReadRenderLight
  1128. ================
  1129. */
  1130. void idRestoreGame::ReadRenderLight( renderLight_t &renderLight ) {
  1131. int index;
  1132. int i;
  1133. ReadMat3( renderLight.axis );
  1134. ReadVec3( renderLight.origin );
  1135. ReadInt( renderLight.suppressLightInViewID );
  1136. ReadInt( renderLight.allowLightInViewID );
  1137. ReadBool( renderLight.noShadows );
  1138. ReadBool( renderLight.noSpecular );
  1139. ReadBool( renderLight.pointLight );
  1140. ReadBool( renderLight.parallel );
  1141. ReadVec3( renderLight.lightRadius );
  1142. ReadVec3( renderLight.lightCenter );
  1143. ReadVec3( renderLight.target );
  1144. ReadVec3( renderLight.right );
  1145. ReadVec3( renderLight.up );
  1146. ReadVec3( renderLight.start );
  1147. ReadVec3( renderLight.end );
  1148. // only idLight has a prelightModel and it's always based on the entityname, so we'll restore it there
  1149. // ReadModel( renderLight.prelightModel );
  1150. renderLight.prelightModel = NULL;
  1151. ReadInt( renderLight.lightId );
  1152. ReadMaterial( renderLight.shader );
  1153. for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
  1154. ReadFloat( renderLight.shaderParms[ i ] );
  1155. }
  1156. ReadInt( index );
  1157. renderLight.referenceSound = gameSoundWorld->EmitterForIndex( index );
  1158. }
  1159. /*
  1160. ================
  1161. idRestoreGame::ReadRefSound
  1162. ================
  1163. */
  1164. void idRestoreGame::ReadRefSound( refSound_t &refSound ) {
  1165. int index;
  1166. ReadInt( index );
  1167. refSound.referenceSound = gameSoundWorld->EmitterForIndex( index );
  1168. ReadVec3( refSound.origin );
  1169. ReadInt( refSound.listenerId );
  1170. ReadSoundShader( refSound.shader );
  1171. ReadFloat( refSound.diversity );
  1172. ReadBool( refSound.waitfortrigger );
  1173. ReadFloat( refSound.parms.minDistance );
  1174. ReadFloat( refSound.parms.maxDistance );
  1175. ReadFloat( refSound.parms.volume );
  1176. ReadFloat( refSound.parms.shakes );
  1177. ReadInt( refSound.parms.soundShaderFlags );
  1178. ReadInt( refSound.parms.soundClass );
  1179. }
  1180. /*
  1181. ================
  1182. idRestoreGame::ReadRenderView
  1183. ================
  1184. */
  1185. void idRestoreGame::ReadRenderView( renderView_t &view ) {
  1186. int i;
  1187. ReadInt( view.viewID );
  1188. ReadInt( view.x );
  1189. ReadInt( view.y );
  1190. ReadInt( view.width );
  1191. ReadInt( view.height );
  1192. ReadFloat( view.fov_x );
  1193. ReadFloat( view.fov_y );
  1194. ReadVec3( view.vieworg );
  1195. ReadMat3( view.viewaxis );
  1196. ReadBool( view.cramZNear );
  1197. ReadInt( view.time );
  1198. for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
  1199. ReadFloat( view.shaderParms[ i ] );
  1200. }
  1201. }
  1202. /*
  1203. =================
  1204. idRestoreGame::ReadUsercmd
  1205. =================
  1206. */
  1207. void idRestoreGame::ReadUsercmd( usercmd_t &usercmd ) {
  1208. ReadInt( usercmd.gameFrame );
  1209. ReadInt( usercmd.gameTime );
  1210. ReadInt( usercmd.duplicateCount );
  1211. ReadByte( usercmd.buttons );
  1212. ReadSignedChar( usercmd.forwardmove );
  1213. ReadSignedChar( usercmd.rightmove );
  1214. ReadSignedChar( usercmd.upmove );
  1215. ReadShort( usercmd.angles[0] );
  1216. ReadShort( usercmd.angles[1] );
  1217. ReadShort( usercmd.angles[2] );
  1218. ReadShort( usercmd.mx );
  1219. ReadShort( usercmd.my );
  1220. ReadSignedChar( usercmd.impulse );
  1221. ReadByte( usercmd.flags );
  1222. ReadInt( usercmd.sequence );
  1223. }
  1224. /*
  1225. ===================
  1226. idRestoreGame::ReadContactInfo
  1227. ===================
  1228. */
  1229. void idRestoreGame::ReadContactInfo( contactInfo_t &contactInfo ) {
  1230. ReadInt( (int &)contactInfo.type );
  1231. ReadVec3( contactInfo.point );
  1232. ReadVec3( contactInfo.normal );
  1233. ReadFloat( contactInfo.dist );
  1234. ReadInt( contactInfo.contents );
  1235. ReadMaterial( contactInfo.material );
  1236. ReadInt( contactInfo.modelFeature );
  1237. ReadInt( contactInfo.trmFeature );
  1238. ReadInt( contactInfo.entityNum );
  1239. ReadInt( contactInfo.id );
  1240. }
  1241. /*
  1242. ===================
  1243. idRestoreGame::ReadTrace
  1244. ===================
  1245. */
  1246. void idRestoreGame::ReadTrace( trace_t &trace ) {
  1247. ReadFloat( trace.fraction );
  1248. ReadVec3( trace.endpos );
  1249. ReadMat3( trace.endAxis );
  1250. ReadContactInfo( trace.c );
  1251. }
  1252. /*
  1253. ===================
  1254. idRestoreGame::ReadTraceModel
  1255. ===================
  1256. */
  1257. void idRestoreGame::ReadTraceModel( idTraceModel &trace ) {
  1258. int j, k;
  1259. ReadInt( (int&)trace.type );
  1260. ReadInt( trace.numVerts );
  1261. for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) {
  1262. ReadVec3( trace.verts[j] );
  1263. }
  1264. ReadInt( trace.numEdges );
  1265. for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) {
  1266. ReadInt( trace.edges[j].v[0] );
  1267. ReadInt( trace.edges[j].v[1] );
  1268. ReadVec3( trace.edges[j].normal );
  1269. }
  1270. ReadInt( trace.numPolys );
  1271. for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) {
  1272. ReadVec3( trace.polys[j].normal );
  1273. ReadFloat( trace.polys[j].dist );
  1274. ReadBounds( trace.polys[j].bounds );
  1275. ReadInt( trace.polys[j].numEdges );
  1276. for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) {
  1277. ReadInt( trace.polys[j].edges[k] );
  1278. }
  1279. }
  1280. ReadVec3( trace.offset );
  1281. ReadBounds( trace.bounds );
  1282. ReadBool( trace.isConvex );
  1283. // padding win32 native structs
  1284. char tmp[3];
  1285. file->Read( tmp, 3 );
  1286. }
  1287. /*
  1288. =====================
  1289. idRestoreGame::ReadClipModel
  1290. =====================
  1291. */
  1292. void idRestoreGame::ReadClipModel( idClipModel *&clipModel ) {
  1293. bool restoreClipModel;
  1294. ReadBool( restoreClipModel );
  1295. if ( restoreClipModel ) {
  1296. clipModel = new idClipModel();
  1297. clipModel->Restore( this );
  1298. } else {
  1299. clipModel = NULL;
  1300. }
  1301. }
  1302. /*
  1303. =====================
  1304. idRestoreGame::ReadSoundCommands
  1305. =====================
  1306. */
  1307. void idRestoreGame::ReadSoundCommands( void ) {
  1308. gameSoundWorld->StopAllSounds();
  1309. gameSoundWorld->ReadFromSaveGame( file );
  1310. }
  1311. /*
  1312. =====================
  1313. idRestoreGame::ReadBuildNumber
  1314. =====================
  1315. */
  1316. void idRestoreGame::ReadBuildNumber( void ) {
  1317. file->ReadInt( buildNumber );
  1318. }
  1319. /*
  1320. =====================
  1321. idRestoreGame::GetBuildNumber
  1322. =====================
  1323. */
  1324. int idRestoreGame::GetBuildNumber( void ) {
  1325. return buildNumber;
  1326. }