SaveGame.cpp 34 KB

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