Xfer.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program 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. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: Xfer.cpp /////////////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, February 2002
  25. // Desc: The Xfer system is capable of setting up operations to work with blocks of data
  26. // from other subsystems. It can work things such as file reading, file writing,
  27. // CRC computations etc
  28. ///////////////////////////////////////////////////////////////////////////////////////////////////
  29. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  30. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  31. #include "Common/Upgrade.h"
  32. #include "Common/GameState.h"
  33. #include "Common/Xfer.h"
  34. #include "Common/BitFlagsIO.h"
  35. #ifdef _INTERNAL
  36. // for occasional debugging...
  37. //#pragma optimize("", off)
  38. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  39. #endif
  40. //-------------------------------------------------------------------------------------------------
  41. //-------------------------------------------------------------------------------------------------
  42. Xfer::Xfer( void )
  43. {
  44. m_options = XO_NONE;
  45. m_xferMode = XFER_INVALID;
  46. } // end Xfer
  47. //-------------------------------------------------------------------------------------------------
  48. //-------------------------------------------------------------------------------------------------
  49. Xfer::~Xfer( void )
  50. {
  51. } // end ~Xfer
  52. // ------------------------------------------------------------------------------------------------
  53. /** Open */
  54. // ------------------------------------------------------------------------------------------------
  55. void Xfer::open( AsciiString identifier )
  56. {
  57. // save identifier
  58. m_identifier = identifier;
  59. } // end open
  60. // ------------------------------------------------------------------------------------------------
  61. // ------------------------------------------------------------------------------------------------
  62. void Xfer::xferByte( Byte *byteData )
  63. {
  64. xferImplementation( byteData, sizeof( Byte ) );
  65. } // end xferByte
  66. // ------------------------------------------------------------------------------------------------
  67. // ------------------------------------------------------------------------------------------------
  68. void Xfer::xferVersion( XferVersion *versionData, XferVersion currentVersion )
  69. {
  70. xferImplementation( versionData, sizeof( XferVersion ) );
  71. // sanity, after the xfer, version data is never allowed to be higher than the current version
  72. if( *versionData > currentVersion )
  73. {
  74. DEBUG_CRASH(( "XferVersion - Unknown version '%d' should be no higher than '%d'\n",
  75. *versionData, currentVersion ));
  76. throw XFER_INVALID_VERSION;
  77. } // end if
  78. } // end xferVersion
  79. // ------------------------------------------------------------------------------------------------
  80. // ------------------------------------------------------------------------------------------------
  81. void Xfer::xferUnsignedByte( UnsignedByte *unsignedByteData )
  82. {
  83. xferImplementation( unsignedByteData, sizeof( UnsignedByte ) );
  84. } // end xferUnsignedByte
  85. // ------------------------------------------------------------------------------------------------
  86. // ------------------------------------------------------------------------------------------------
  87. void Xfer::xferBool( Bool *boolData )
  88. {
  89. xferImplementation( boolData, sizeof( Bool ) );
  90. } // end xferBool
  91. // ------------------------------------------------------------------------------------------------
  92. // ------------------------------------------------------------------------------------------------
  93. void Xfer::xferInt( Int *intData )
  94. {
  95. xferImplementation( intData, sizeof( Int ) );
  96. } // end xferInt
  97. // ------------------------------------------------------------------------------------------------
  98. // ------------------------------------------------------------------------------------------------
  99. void Xfer::xferInt64( Int64 *int64Data )
  100. {
  101. xferImplementation( int64Data, sizeof( Int64 ) );
  102. } // end xferInt64
  103. // ------------------------------------------------------------------------------------------------
  104. // ------------------------------------------------------------------------------------------------
  105. void Xfer::xferUnsignedInt( UnsignedInt *unsignedIntData )
  106. {
  107. xferImplementation( unsignedIntData, sizeof( UnsignedInt ) );
  108. } // end xferUnsignedInt
  109. // ------------------------------------------------------------------------------------------------
  110. // ------------------------------------------------------------------------------------------------
  111. void Xfer::xferShort( Short *shortData )
  112. {
  113. xferImplementation( shortData, sizeof( Short ) );
  114. } // end xferShort
  115. // ------------------------------------------------------------------------------------------------
  116. // ------------------------------------------------------------------------------------------------
  117. void Xfer::xferUnsignedShort( UnsignedShort *unsignedShortData )
  118. {
  119. xferImplementation( unsignedShortData, sizeof( UnsignedShort ) );
  120. } // end xferUnsignedShort
  121. // ------------------------------------------------------------------------------------------------
  122. // ------------------------------------------------------------------------------------------------
  123. void Xfer::xferReal( Real *realData )
  124. {
  125. xferImplementation( realData, sizeof( Real ) );
  126. } // end xferReal
  127. // ------------------------------------------------------------------------------------------------
  128. // ------------------------------------------------------------------------------------------------
  129. void Xfer::xferMapName( AsciiString *mapNameData )
  130. {
  131. if (getXferMode() == XFER_SAVE)
  132. {
  133. AsciiString tmp = TheGameState->realMapPathToPortableMapPath(*mapNameData);
  134. xferAsciiString(&tmp);
  135. }
  136. else if (getXferMode() == XFER_LOAD)
  137. {
  138. xferAsciiString(mapNameData);
  139. *mapNameData = TheGameState->portableMapPathToRealMapPath(*mapNameData);
  140. }
  141. } // end xferAsciiString
  142. // ------------------------------------------------------------------------------------------------
  143. // ------------------------------------------------------------------------------------------------
  144. void Xfer::xferAsciiString( AsciiString *asciiStringData )
  145. {
  146. xferImplementation( (void *)asciiStringData->str(), sizeof( Byte ) * asciiStringData->getLength() );
  147. } // end xferAsciiString
  148. // ------------------------------------------------------------------------------------------------
  149. // ------------------------------------------------------------------------------------------------
  150. void Xfer::xferMarkerLabel( AsciiString asciiStringData )
  151. {
  152. } // end xferMarkerLabel
  153. // ------------------------------------------------------------------------------------------------
  154. // ------------------------------------------------------------------------------------------------
  155. void Xfer::xferUnicodeString( UnicodeString *unicodeStringData )
  156. {
  157. xferImplementation( (void *)unicodeStringData->str(), sizeof( WideChar ) * unicodeStringData->getLength() );
  158. } // end xferUnicodeString
  159. // ------------------------------------------------------------------------------------------------
  160. // ------------------------------------------------------------------------------------------------
  161. void Xfer::xferCoord3D( Coord3D *coord3D )
  162. {
  163. xferReal( &coord3D->x );
  164. xferReal( &coord3D->y );
  165. xferReal( &coord3D->z );
  166. } // end xferCoord3D
  167. // ------------------------------------------------------------------------------------------------
  168. // ------------------------------------------------------------------------------------------------
  169. void Xfer::xferICoord3D( ICoord3D *iCoord3D )
  170. {
  171. xferInt( &iCoord3D->x );
  172. xferInt( &iCoord3D->y );
  173. xferInt( &iCoord3D->z );
  174. } // end xferICoor3D
  175. // ------------------------------------------------------------------------------------------------
  176. // ------------------------------------------------------------------------------------------------
  177. void Xfer::xferRegion3D( Region3D *region3D )
  178. {
  179. xferCoord3D( &region3D->lo );
  180. xferCoord3D( &region3D->hi );
  181. } // end xferRegion3D
  182. // ------------------------------------------------------------------------------------------------
  183. // ------------------------------------------------------------------------------------------------
  184. void Xfer::xferIRegion3D( IRegion3D *iRegion3D )
  185. {
  186. xferICoord3D( &iRegion3D->lo );
  187. xferICoord3D( &iRegion3D->hi );
  188. } // end xferIRegion3D
  189. // ------------------------------------------------------------------------------------------------
  190. // ------------------------------------------------------------------------------------------------
  191. void Xfer::xferCoord2D( Coord2D *coord2D )
  192. {
  193. xferReal( &coord2D->x );
  194. xferReal( &coord2D->y );
  195. } // end xferCoord2D
  196. // ------------------------------------------------------------------------------------------------
  197. // ------------------------------------------------------------------------------------------------
  198. void Xfer::xferICoord2D( ICoord2D *iCoord2D )
  199. {
  200. xferInt( &iCoord2D->x );
  201. xferInt( &iCoord2D->y );
  202. } // end xferICoord2D
  203. // ------------------------------------------------------------------------------------------------
  204. // ------------------------------------------------------------------------------------------------
  205. void Xfer::xferRegion2D( Region2D *region2D )
  206. {
  207. xferCoord2D( &region2D->lo );
  208. xferCoord2D( &region2D->hi );
  209. } // end xferRegion2D
  210. // ------------------------------------------------------------------------------------------------
  211. // ------------------------------------------------------------------------------------------------
  212. void Xfer::xferIRegion2D( IRegion2D *iRegion2D )
  213. {
  214. xferICoord2D( &iRegion2D->lo );
  215. xferICoord2D( &iRegion2D->hi );
  216. } // end xferIRegion2D
  217. // ------------------------------------------------------------------------------------------------
  218. // ------------------------------------------------------------------------------------------------
  219. void Xfer::xferRealRange( RealRange *realRange )
  220. {
  221. xferReal( &realRange->lo );
  222. xferReal( &realRange->hi );
  223. } // end xferRealRange
  224. // ------------------------------------------------------------------------------------------------
  225. // ------------------------------------------------------------------------------------------------
  226. void Xfer::xferColor( Color *color )
  227. {
  228. xferImplementation( color, sizeof( Color ) );
  229. } // end xferColor
  230. // ------------------------------------------------------------------------------------------------
  231. // ------------------------------------------------------------------------------------------------
  232. void Xfer::xferRGBColor( RGBColor *rgbColor )
  233. {
  234. xferReal( &rgbColor->red );
  235. xferReal( &rgbColor->green );
  236. xferReal( &rgbColor->blue );
  237. } // end xferRGBColor
  238. // ------------------------------------------------------------------------------------------------
  239. // ------------------------------------------------------------------------------------------------
  240. void Xfer::xferRGBAColorReal( RGBAColorReal *rgbaColorReal )
  241. {
  242. xferReal( &rgbaColorReal->red );
  243. xferReal( &rgbaColorReal->green );
  244. xferReal( &rgbaColorReal->blue );
  245. xferReal( &rgbaColorReal->alpha );
  246. } // end xferRGBAColorReal
  247. // ------------------------------------------------------------------------------------------------
  248. // ------------------------------------------------------------------------------------------------
  249. void Xfer::xferRGBAColorInt( RGBAColorInt *rgbaColorInt )
  250. {
  251. xferUnsignedInt( &rgbaColorInt->red );
  252. xferUnsignedInt( &rgbaColorInt->green );
  253. xferUnsignedInt( &rgbaColorInt->blue );
  254. xferUnsignedInt( &rgbaColorInt->alpha );
  255. } // end xferRGBAColorInt
  256. // ------------------------------------------------------------------------------------------------
  257. // ------------------------------------------------------------------------------------------------
  258. void Xfer::xferObjectID( ObjectID *objectID )
  259. {
  260. xferImplementation( objectID, sizeof( ObjectID ) );
  261. } // end xferObjeftID
  262. // ------------------------------------------------------------------------------------------------
  263. // ------------------------------------------------------------------------------------------------
  264. void Xfer::xferDrawableID( DrawableID *drawableID )
  265. {
  266. xferImplementation( drawableID, sizeof( DrawableID ) );
  267. } // end xferDrawableID
  268. // ------------------------------------------------------------------------------------------------
  269. void Xfer::xferSTLObjectIDVector( std::vector<ObjectID> *objectIDVectorData )
  270. {
  271. //
  272. // the fact that this is a list and a little higher level than a simple data type
  273. // is reason enough to have every one of these versioned
  274. //
  275. XferVersion currentVersion = 1;
  276. XferVersion version = currentVersion;
  277. xferVersion( &version, currentVersion );
  278. // xfer the count of the vector
  279. UnsignedShort listCount = objectIDVectorData->size();
  280. xferUnsignedShort( &listCount );
  281. // xfer vector data
  282. ObjectID objectID;
  283. if( getXferMode() == XFER_SAVE || getXferMode() == XFER_CRC )
  284. {
  285. // save all ids
  286. std::vector< ObjectID >::const_iterator it;
  287. for( it = objectIDVectorData->begin(); it != objectIDVectorData->end(); ++it )
  288. {
  289. objectID = *it;
  290. xferObjectID( &objectID );
  291. } // end for
  292. } // end if, save
  293. else if( getXferMode() == XFER_LOAD )
  294. {
  295. // sanity, the list should be empty before we transfer more data into it
  296. if( objectIDVectorData->size() != 0 )
  297. {
  298. DEBUG_CRASH(( "Xfer::xferSTLObjectIDList - object vector should be empty before loading\n" ));
  299. throw XFER_LIST_NOT_EMPTY;
  300. } // end if
  301. // read all ids
  302. for( UnsignedShort i = 0; i < listCount; ++i )
  303. {
  304. xferObjectID( &objectID );
  305. objectIDVectorData->push_back( objectID );
  306. } // end for, i
  307. } // end else if
  308. else
  309. {
  310. DEBUG_CRASH(( "xferSTLObjectIDList - Unknown xfer mode '%d'\n", getXferMode() ));
  311. throw XFER_MODE_UNKNOWN;
  312. } // end else
  313. }
  314. // ------------------------------------------------------------------------------------------------
  315. /** STL Object ID list (cause it's a common data structure we use a lot)
  316. * Version Info;
  317. * 1: Initial version */
  318. // ------------------------------------------------------------------------------------------------
  319. void Xfer::xferSTLObjectIDList( std::list< ObjectID > *objectIDListData )
  320. {
  321. //
  322. // the fact that this is a list and a little higher level than a simple data type
  323. // is reason enough to have every one of these versioned
  324. //
  325. XferVersion currentVersion = 1;
  326. XferVersion version = currentVersion;
  327. xferVersion( &version, currentVersion );
  328. // xfer the count of the list
  329. UnsignedShort listCount = objectIDListData->size();
  330. xferUnsignedShort( &listCount );
  331. // xfer list data
  332. ObjectID objectID;
  333. if( getXferMode() == XFER_SAVE || getXferMode() == XFER_CRC )
  334. {
  335. // save all ids
  336. std::list< ObjectID >::const_iterator it;
  337. for( it = objectIDListData->begin(); it != objectIDListData->end(); ++it )
  338. {
  339. objectID = *it;
  340. xferObjectID( &objectID );
  341. } // end for
  342. } // end if, save
  343. else if( getXferMode() == XFER_LOAD )
  344. {
  345. // sanity, the list should be empty before we transfer more data into it
  346. if( objectIDListData->size() != 0 )
  347. {
  348. DEBUG_CRASH(( "Xfer::xferSTLObjectIDList - object list should be empty before loading\n" ));
  349. throw XFER_LIST_NOT_EMPTY;
  350. } // end if
  351. // read all ids
  352. for( UnsignedShort i = 0; i < listCount; ++i )
  353. {
  354. xferObjectID( &objectID );
  355. objectIDListData->push_back( objectID );
  356. } // end for, i
  357. } // end else if
  358. else
  359. {
  360. DEBUG_CRASH(( "xferSTLObjectIDList - Unknown xfer mode '%d'\n", getXferMode() ));
  361. throw XFER_MODE_UNKNOWN;
  362. } // end else
  363. } // end xferSTLObjectIDList
  364. // ------------------------------------------------------------------------------------------------
  365. // ------------------------------------------------------------------------------------------------
  366. void Xfer::xferSTLIntList( std::list< Int > *intListData )
  367. {
  368. // sanity
  369. if( intListData == NULL )
  370. return;
  371. // version
  372. XferVersion currentVersion = 1;
  373. XferVersion version = currentVersion;
  374. xferVersion( &version, currentVersion );
  375. // xfer the count of the list
  376. UnsignedShort listCount = intListData->size();
  377. xferUnsignedShort( &listCount );
  378. // xfer list data
  379. Int intData;
  380. if( getXferMode() == XFER_SAVE || getXferMode() == XFER_CRC )
  381. {
  382. // save all ids
  383. std::list< Int >::const_iterator it;
  384. for( it = intListData->begin(); it != intListData->end(); ++it )
  385. {
  386. intData = *it;
  387. xferInt( &intData );
  388. } // end for
  389. } // end if, save
  390. else if( getXferMode() == XFER_LOAD )
  391. {
  392. // sanity, the list should be empty before we transfer more data into it
  393. if( intListData->size() != 0 )
  394. {
  395. DEBUG_CRASH(( "Xfer::xferSTLIntList - int list should be empty before loading\n" ));
  396. throw XFER_LIST_NOT_EMPTY;
  397. } // end if
  398. // read all ids
  399. for( UnsignedShort i = 0; i < listCount; ++i )
  400. {
  401. xferInt( &intData );
  402. intListData->push_back( intData );
  403. } // end for, i
  404. } // end else if
  405. else
  406. {
  407. DEBUG_CRASH(( "xferSTLIntList - Unknown xfer mode '%d'\n", getXferMode() ));
  408. throw XFER_MODE_UNKNOWN;
  409. } // end else
  410. } // end xferSTLIntList
  411. // ------------------------------------------------------------------------------------------------
  412. // ------------------------------------------------------------------------------------------------
  413. void Xfer::xferScienceType( ScienceType *science )
  414. {
  415. // sanity
  416. DEBUG_ASSERTCRASH( science != NULL, ("xferScienceType - Invalid parameters\n") );
  417. AsciiString scienceName;
  418. if( getXferMode() == XFER_SAVE )
  419. {
  420. // translate to string
  421. scienceName = TheScienceStore->getInternalNameForScience( *science );
  422. // write the string
  423. xferAsciiString( &scienceName );
  424. } // end if, save
  425. else if( getXferMode() == XFER_LOAD )
  426. {
  427. xferAsciiString( &scienceName );
  428. // translate to science
  429. *science = TheScienceStore->getScienceFromInternalName( scienceName );
  430. if( *science == SCIENCE_INVALID )
  431. {
  432. DEBUG_CRASH(( "xferScienceType - Unknown science '%s'\n", scienceName.str() ));
  433. throw XFER_UNKNOWN_STRING;
  434. } // end if
  435. } // end else if, load
  436. else if( getXferMode() == XFER_CRC )
  437. {
  438. xferImplementation( science, sizeof( *science ) );
  439. } // end else if, crc
  440. else
  441. {
  442. DEBUG_CRASH(( "xferScienceType - Unknown xfer mode '%d'\n", getXferMode() ));
  443. throw XFER_MODE_UNKNOWN;
  444. } // end else
  445. } // end xferScienceType
  446. // ------------------------------------------------------------------------------------------------
  447. // ------------------------------------------------------------------------------------------------
  448. void Xfer::xferScienceVec( ScienceVec *scienceVec )
  449. {
  450. // sanity
  451. DEBUG_ASSERTCRASH( scienceVec != NULL, ("xferScienceVec - Invalid parameters\n") );
  452. // this deserves a version number
  453. const XferVersion currentVersion = 1;
  454. XferVersion version = currentVersion;
  455. xferVersion( &version, currentVersion );
  456. // count of vector
  457. UnsignedShort count = scienceVec->size();
  458. xferUnsignedShort( &count );
  459. if( getXferMode() == XFER_SAVE )
  460. {
  461. for( ScienceVec::const_iterator it = scienceVec->begin(); it != scienceVec->end(); ++it )
  462. {
  463. ScienceType science = *it;
  464. xferScienceType(&science);
  465. }
  466. }
  467. else if( getXferMode() == XFER_LOAD )
  468. {
  469. // vector should be empty at this point
  470. if( scienceVec->empty() == FALSE )
  471. {
  472. // Not worth an assert, since things can give you Sciences on creation. Just handle it and load.
  473. scienceVec->clear();
  474. // Homework for today. Write 2000 words reconciling "Your code must never crash" with "Intentionally putting crashes in the code". Fucktard.
  475. // DEBUG_CRASH(( "xferScienceVec - vector is not empty, but should be\n" ));
  476. // throw XFER_LIST_NOT_EMPTY;
  477. }
  478. for( UnsignedShort i = 0; i < count; ++i )
  479. {
  480. ScienceType science;
  481. xferScienceType(&science);
  482. scienceVec->push_back( science );
  483. }
  484. }
  485. else if( getXferMode() == XFER_CRC )
  486. {
  487. for( ScienceVec::const_iterator it = scienceVec->begin(); it != scienceVec->end(); ++it )
  488. {
  489. ScienceType science = *it;
  490. xferImplementation( &science, sizeof( ScienceType ) );
  491. } // end for, it
  492. } // end else if, crc
  493. else
  494. {
  495. DEBUG_CRASH(( "xferScienceVec - Unknown xfer mode '%d'\n", getXferMode() ));
  496. throw XFER_MODE_UNKNOWN;
  497. } // end else
  498. } // end xferScienceVec
  499. // ------------------------------------------------------------------------------------------------
  500. /** kind of type, for load/save it is xfered as a string so we can reorder the
  501. * kindofs if we like
  502. * Version Info:
  503. * 1: Initial version */
  504. // ------------------------------------------------------------------------------------------------
  505. void Xfer::xferKindOf( KindOfType *kindOfData )
  506. {
  507. // this deserves a version number
  508. XferVersion currentVersion = 1;
  509. XferVersion version = currentVersion;
  510. xferVersion( &version, currentVersion );
  511. // check which type of xfer we're doing
  512. if( getXferMode() == XFER_SAVE )
  513. {
  514. // save as an ascii string
  515. AsciiString kindOfName = KindOfMaskType::getNameFromSingleBit(*kindOfData);
  516. xferAsciiString( &kindOfName );
  517. } // end if, save
  518. else if( getXferMode() == XFER_LOAD )
  519. {
  520. // read ascii string from file
  521. AsciiString kindOfName;
  522. xferAsciiString( &kindOfName );
  523. // turn kind of name into an enum value
  524. Int bit = KindOfMaskType::getSingleBitFromName(kindOfName.str());
  525. if (bit != -1)
  526. *kindOfData = (KindOfType)bit;
  527. } // end else if, load
  528. else if( getXferMode() == XFER_CRC )
  529. {
  530. // just call the xfer implementation on the data values
  531. xferImplementation( kindOfData, sizeof( KindOfType ) );
  532. } // end else if, crc
  533. else
  534. {
  535. DEBUG_CRASH(( "xferKindOf - Unknown xfer mode '%d'\n", getXferMode() ));
  536. throw XFER_MODE_UNKNOWN;
  537. } // end else
  538. } // end xferKindOf
  539. // ------------------------------------------------------------------------------------------------
  540. // ------------------------------------------------------------------------------------------------
  541. void Xfer::xferUpgradeMask( UpgradeMaskType *upgradeMaskData )
  542. {
  543. // this deserves a version number
  544. XferVersion currentVersion = 1;
  545. XferVersion version = currentVersion;
  546. xferVersion( &version, currentVersion );
  547. //Kris: The Upgrade system has been converted from Int64 to BitFlags. However because the
  548. //names of upgrades are saved to preserve order reassignments (inserting a new upgrade in
  549. //the INI file will skew the bit values), we must continue saving the names of the upgrades
  550. //in order to recalculate the actual bit value of said upgrade.
  551. //---------------------------------------------------------------------------------------------
  552. //NOTE: The xfer code didn't have to change with the bitset upgrades, because either way, we're
  553. //converting data <-> Ascii, so the minor syntax works with the before and after code!
  554. // check which type of xfer we're doing
  555. if( getXferMode() == XFER_SAVE )
  556. {
  557. AsciiString upgradeName;
  558. // count how many bits are set in the mask
  559. UnsignedShort count = 0;
  560. UpgradeTemplate *upgradeTemplate;
  561. for( upgradeTemplate = TheUpgradeCenter->firstUpgradeTemplate(); upgradeTemplate; upgradeTemplate = upgradeTemplate->friend_getNext() )
  562. {
  563. // if the mask of this upgrade is set, it counts
  564. if( upgradeMaskData->testForAll( upgradeTemplate->getUpgradeMask() ) )
  565. {
  566. count++;
  567. }
  568. } // end for, upgradeTemplate
  569. // write the count
  570. xferUnsignedShort( &count );
  571. // write out the upgrades as strings
  572. for( upgradeTemplate = TheUpgradeCenter->firstUpgradeTemplate(); upgradeTemplate; upgradeTemplate = upgradeTemplate->friend_getNext() )
  573. {
  574. // if the mask of this upgrade is set, it counts
  575. if( upgradeMaskData->testForAll( upgradeTemplate->getUpgradeMask() ) )
  576. {
  577. upgradeName = upgradeTemplate->getUpgradeName();
  578. xferAsciiString( &upgradeName );
  579. } // end if
  580. } // end for, upgradeTemplate
  581. } // end if, save
  582. else if( getXferMode() == XFER_LOAD )
  583. {
  584. AsciiString upgradeName;
  585. const UpgradeTemplate *upgradeTemplate;
  586. // how many strings are we going to read from the file
  587. UnsignedShort count;
  588. xferUnsignedShort( &count );
  589. // zero the mask data
  590. upgradeMaskData->clear();
  591. // read all the strings and set the mask vaules
  592. for( UnsignedShort i = 0; i < count; ++i )
  593. {
  594. // read the string
  595. xferAsciiString( &upgradeName );
  596. // find this upgrade template
  597. upgradeTemplate = TheUpgradeCenter->findUpgrade( upgradeName );
  598. if( upgradeTemplate == NULL )
  599. {
  600. DEBUG_CRASH(( "Xfer::xferUpgradeMask - Unknown upgrade '%s'\n", upgradeName.str() ));
  601. throw XFER_UNKNOWN_STRING;
  602. } // end if
  603. // set the mask data
  604. upgradeMaskData->set( upgradeTemplate->getUpgradeMask() );
  605. } // end for i
  606. } // end else if, load
  607. else if( getXferMode() == XFER_CRC )
  608. {
  609. // just xfer implementation the data itself
  610. xferImplementation( upgradeMaskData, sizeof( UpgradeMaskType ) );
  611. } // end else if, crc
  612. else
  613. {
  614. DEBUG_CRASH(( "xferUpgradeMask - Unknown xfer mode '%d'\n", getXferMode() ));
  615. throw XFER_MODE_UNKNOWN;
  616. } // end else
  617. } // end xferUpgradeMask
  618. // ------------------------------------------------------------------------------------------------
  619. // ------------------------------------------------------------------------------------------------
  620. void Xfer::xferUser( void *data, Int dataSize )
  621. {
  622. xferImplementation( data, dataSize );
  623. } // end xferUser
  624. // ------------------------------------------------------------------------------------------------
  625. // ------------------------------------------------------------------------------------------------
  626. void Xfer::xferMatrix3D( Matrix3D* mtx )
  627. {
  628. // this deserves a version number
  629. const XferVersion currentVersion = 1;
  630. XferVersion version = currentVersion;
  631. xferVersion( &version, currentVersion );
  632. Vector4& tmp0 = (*mtx)[0];
  633. Vector4& tmp1 = (*mtx)[1];
  634. Vector4& tmp2 = (*mtx)[2];
  635. xferReal(&tmp0.X);
  636. xferReal(&tmp0.Y);
  637. xferReal(&tmp0.Z);
  638. xferReal(&tmp0.W);
  639. xferReal(&tmp1.X);
  640. xferReal(&tmp1.Y);
  641. xferReal(&tmp1.Z);
  642. xferReal(&tmp1.W);
  643. xferReal(&tmp2.X);
  644. xferReal(&tmp2.Y);
  645. xferReal(&tmp2.Z);
  646. xferReal(&tmp2.W);
  647. }