MPLoadMap.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. #define MPLOADMAP_CPP
  2. /*************************************************************************************************\
  3. MPLoadMap.cpp : Implementation of the MPLoadMap component.
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. \*************************************************************************************************/
  8. #include "MPLoadMap.h"
  9. #include "prefs.h"
  10. #include "IniFile.h"
  11. #include "../MCLib/UserInput.h"
  12. #include "..\resource.h"
  13. #include <windows.h>
  14. #include "MissionBriefingScreen.h"
  15. #ifndef GAMESOUND_H
  16. #include "gamesound.h"
  17. #endif
  18. #define CHECK_BUTTON 200
  19. static int connectionType = 0;
  20. static const int FIRST_BUTTON_ID = 1000010;
  21. static const int OK_BUTTON_ID = 1000001;
  22. static const int CANCEL_BUTTON_ID = 1000002;
  23. MPLoadMap::MPLoadMap()
  24. {
  25. bDone = 0;
  26. status = RUNNING;
  27. helpTextArrayID = 6;
  28. }
  29. MPLoadMap::~MPLoadMap()
  30. {
  31. mapList.destroy();
  32. }
  33. int MPLoadMap::indexOfButtonWithID(int id)
  34. {
  35. int i;
  36. for (i = 0; i < buttonCount; i++)
  37. {
  38. if (buttons[i].getID() == id)
  39. {
  40. return i;
  41. }
  42. }
  43. return -1;
  44. }
  45. void MPLoadMap::init(FitIniFile* file)
  46. {
  47. LogisticsScreen::init( *file, "Static", "Text", "Rect", "Button" );
  48. if ( buttonCount )
  49. {
  50. for ( int i = 0; i < buttonCount; i++ )
  51. {
  52. buttons[i].setMessageOnRelease();
  53. if (buttons[i].getID() == 0)
  54. {
  55. buttons[i].setID(FIRST_BUTTON_ID + i);
  56. }
  57. }
  58. }
  59. file->seekBlock( "EnterAnim" );
  60. enterAnim.init( file, "" );
  61. file->seekBlock( "LeaveAnim" );
  62. exitAnim.init( file, "" );
  63. {
  64. char path[256];
  65. strcpy( path, artPath );
  66. strcat( path, "mcl_mp_loadmap_list0.fit" );
  67. FitIniFile PNfile;
  68. if ( NO_ERR != PNfile.open( path ) )
  69. {
  70. char error[256];
  71. sprintf( error, "couldn't open file %s", path );
  72. Assert( 0, 0, error );
  73. return;
  74. }
  75. PNfile.seekBlock("MapList"); /*for some reason aListBox::init(...) doesn't do the seekBlock itself*/
  76. mapList.init(&PNfile, "MapList");
  77. templateItem.init( &PNfile, "Text0" );
  78. }
  79. mapList.setOrange( true );
  80. }
  81. void MPLoadMap::begin()
  82. {
  83. // fill up the dialog....
  84. LogisticsDialog::begin();
  85. seedDialog( 0 );
  86. bIsSingle = false;
  87. }
  88. void MPLoadMap::beginSingleMission()
  89. {
  90. // fill up the dialog....
  91. LogisticsDialog::begin();
  92. seedDialog( 1 );
  93. bIsSingle = true;
  94. }
  95. void MPLoadMap::seedDialog( bool bSeedSingle )
  96. {
  97. mapList.removeAllItems( true );
  98. // need to add items to the save game list
  99. char findString[512];
  100. sprintf(findString,"%s*.fit",missionPath);
  101. WIN32_FIND_DATA findResult;
  102. HANDLE searchHandle = FindFirstFile(findString,&findResult);
  103. if ( searchHandle != INVALID_HANDLE_VALUE )
  104. {
  105. do
  106. {
  107. if ((findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
  108. {
  109. addFile( findResult.cFileName, bSeedSingle );
  110. }
  111. } while (FindNextFile(searchHandle,&findResult) != 0);
  112. }
  113. FindClose(searchHandle);
  114. if ( bSeedSingle )
  115. {
  116. seedFromCampaign();
  117. }
  118. else
  119. {
  120. seedFromFile( "Multi" );
  121. }
  122. statics[18].setTexture( (unsigned long)NULL );
  123. if ( bSeedSingle )
  124. mapList.SelectItem( 0);
  125. else
  126. mapList.SelectItem( 1 );
  127. updateMapInfo();
  128. }
  129. void MPLoadMap::addFile( const char* pFileName, bool bSeedSingle )
  130. {
  131. FitIniFile tmp;
  132. FullPathFileName path;
  133. path.init( missionPath, pFileName, ".fit" );
  134. if ( NO_ERR == tmp.open( path ) )
  135. {
  136. if ( NO_ERR == tmp.seekBlock( "MissionSettings" ) )
  137. {
  138. unsigned long bSingle;
  139. long result = tmp.readIdULong( "IsSinglePlayer", bSingle );
  140. bool bSingleResult = (bSingle != 0);
  141. if ( (result == NO_ERR) && (bSingleResult == bSeedSingle) )
  142. {
  143. char* pExt = (char*)strstr( pFileName, ".fit" );
  144. if ( !pExt )
  145. {
  146. pExt = (char*)(strstr( pFileName, ".FIT" ) );
  147. }
  148. if ( pExt )
  149. *pExt = NULL;
  150. aLocalizedListItem* pEntry = new aLocalizedListItem();
  151. *pEntry = templateItem;
  152. pEntry->resize( mapList.width() - mapList.getScrollBarWidth() - 30, pEntry->height());
  153. pEntry->setHiddenText( pFileName );
  154. char missionDisplayName[256];
  155. strcpy(missionDisplayName, "");
  156. getMapNameFromFile(pFileName, missionDisplayName, 255 );
  157. if (0 == strcmp("", missionDisplayName))
  158. {
  159. strcpy(missionDisplayName, pFileName);
  160. }
  161. pEntry->setText( missionDisplayName );
  162. pEntry->sizeToText();
  163. if ( !bSingle )
  164. {
  165. unsigned long type = 0;
  166. tmp.readIdULong( "MissionType", type );
  167. bool bFound = 0;
  168. // now go looking for the appropriate header
  169. for ( int i = 0; i < mapList.GetItemCount(); i++ )
  170. {
  171. if ( mapList.GetItem( i )->getID() - IDS_MP_LM_TYPE0 == type )
  172. {
  173. pEntry->move( 10, 0 );
  174. mapList.InsertItem( pEntry, i+1 );
  175. bFound = true;
  176. }
  177. }
  178. if ( !bFound )
  179. {
  180. aLocalizedListItem* pHeaderEntry = new aLocalizedListItem();
  181. *pHeaderEntry = templateItem;
  182. pHeaderEntry->setText( IDS_MP_LM_TYPE0 + type );
  183. pHeaderEntry->resize( mapList.width() - mapList.getScrollBarWidth() - 30, pHeaderEntry->height());
  184. pHeaderEntry->sizeToText();
  185. pHeaderEntry->setID( IDS_MP_LM_TYPE0 + type );
  186. pHeaderEntry->setState( aListItem::DISABLED );
  187. mapList.AddItem( pHeaderEntry );
  188. pEntry->move( 10, 0 );
  189. mapList.AddItem( pEntry );
  190. }
  191. }
  192. else
  193. mapList.AddItem( pEntry );
  194. }
  195. }
  196. }
  197. }
  198. void MPLoadMap::seedFromFile( const char* pFileName )
  199. {
  200. FullPathFileName path;
  201. path.init( missionPath, pFileName, ".csv" );
  202. CSVFile file;
  203. if ( NO_ERR != file.open( path ) )
  204. {
  205. Assert( 0, 0, "couldn't open multiplayer mission .csv file" );
  206. return;
  207. }
  208. int i = 1;
  209. char fileName[255];
  210. while( true )
  211. {
  212. if ( NO_ERR != file.readString( i, 1, fileName, 255 ) )
  213. break;
  214. path.init( missionPath, fileName, ".fit" );
  215. if ( fileExists( path ) )
  216. {
  217. addFile( fileName, false );
  218. }
  219. i++;
  220. }
  221. }
  222. void MPLoadMap::seedFromCampaign()
  223. {
  224. char searchStr[255];
  225. cLoadString( IDS_AUTOSAVE_NAME, searchStr, 255 );
  226. EString finalStr;
  227. finalStr = "*.fit";
  228. FullPathFileName findPath;
  229. findPath.init( savePath, finalStr, ".fit" );
  230. EString newestFile;
  231. long groupCount = -1;
  232. long missionCount = -1;
  233. FitIniFile tmpFile;
  234. WIN32_FIND_DATA findResult;
  235. HANDLE searchHandle = FindFirstFile(findPath,&findResult);
  236. if ( searchHandle != INVALID_HANDLE_VALUE )
  237. {
  238. do
  239. {
  240. if ((findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
  241. {
  242. FullPathFileName path;
  243. path.init( savePath, findResult.cFileName, ".fit" );
  244. tmpFile.open( path );
  245. if ( NO_ERR == tmpFile.seekBlock( "General" ) )
  246. {
  247. long group, missions;
  248. tmpFile.readIdLong( "Group ", group );
  249. if ( group > groupCount )
  250. {
  251. groupCount = group;
  252. tmpFile.readIdLong( "CompletedMissions", missions );
  253. missionCount = missions;
  254. newestFile = findResult.cFileName;
  255. }
  256. else if ( group == groupCount )
  257. {
  258. tmpFile.readIdLong( "CompletedMissions", missions );
  259. if ( missions > missionCount )
  260. missionCount = missions;
  261. newestFile = findResult.cFileName;
  262. }
  263. }
  264. tmpFile.close();
  265. }
  266. } while (FindNextFile(searchHandle,&findResult) != 0);
  267. }
  268. FindClose(searchHandle);
  269. if ( newestFile.Length() )
  270. {
  271. findPath.init( savePath, newestFile, ".fit" );
  272. FitIniFile file;
  273. long group;
  274. long missions;
  275. char campaignFileName[256];
  276. campaignFileName[0] = 0;
  277. if ( NO_ERR == file.open( findPath ) )
  278. {
  279. if ( NO_ERR == file.seekBlock( "General" ) )
  280. {
  281. file.readIdLong( "Group ", group );
  282. file.readIdLong( "CompletedMissions", missions );
  283. file.readIdString( "CampaignFile", campaignFileName, 255 );
  284. }
  285. }
  286. if ( strlen( campaignFileName ) && ( group || missions ) )
  287. {
  288. FitIniFile campaignFile;
  289. if ( NO_ERR == campaignFile.open( campaignFileName ) )
  290. {
  291. for ( int i = 0; i < group+1; i++ )
  292. {
  293. char blockName[64];
  294. sprintf( blockName, "Group%ld", i );
  295. if ( NO_ERR == campaignFile.seekBlock( blockName ) )
  296. {
  297. long count = missions;
  298. if ( i < group )
  299. {
  300. campaignFile.readIdLong( "MissionCount", count );
  301. }
  302. for ( int j = 0; j < count; j++ )
  303. {
  304. sprintf( blockName, "Group%ldMission%ld", i, j );
  305. if ( NO_ERR == campaignFile.seekBlock( blockName ) )
  306. {
  307. char tmpFileName[255];
  308. campaignFile.readIdString( "FileName", tmpFileName, 255 );
  309. aLocalizedListItem* pEntry = new aLocalizedListItem();
  310. *pEntry = templateItem;
  311. pEntry->resize( mapList.width() - mapList.getScrollBarWidth() - 20, pEntry->height());
  312. pEntry->setHiddenText( tmpFileName );
  313. char displayName[256];
  314. getMapNameFromFile( tmpFileName, displayName, 255 );
  315. pEntry->setText( displayName );
  316. pEntry->sizeToText();
  317. mapList.AddItem( pEntry );
  318. }
  319. }
  320. }
  321. }
  322. }
  323. }
  324. }
  325. }
  326. void MPLoadMap::end()
  327. {
  328. LogisticsDialog::end();
  329. statics[18].setTexture( ( unsigned long)NULL );
  330. statics[18].setColor( 0 );
  331. }
  332. void MPLoadMap::render(int, int )
  333. {
  334. float color = 0x7f000000;
  335. if ( enterAnim.isAnimating() && !enterAnim.isDone() )
  336. {
  337. float time = enterAnim.getCurrentTime();
  338. float endTime = enterAnim.getMaxTime();
  339. if ( endTime )
  340. {
  341. color = interpolateColor( 0x00000000, 0x7f000000, time/endTime );
  342. }
  343. }
  344. else if ( exitAnim.isAnimating() && !exitAnim.isDone() )
  345. {
  346. float time = exitAnim.getCurrentTime();
  347. float endTime = exitAnim.getMaxTime();
  348. if ( endTime )
  349. {
  350. color = interpolateColor( 0x7f000000, 0x00000000, time/endTime );
  351. }
  352. }
  353. GUI_RECT rect = { 0, 0, Environment.screenWidth, Environment.screenHeight };
  354. drawRect( rect, color );
  355. if ((!enterAnim.isAnimating() || enterAnim.isDone() ) && !exitAnim.isAnimating() )
  356. {
  357. mapList.render();
  358. }
  359. float xOffset = 0;
  360. float yOffset = 0 ;
  361. if ( enterAnim.isAnimating() )
  362. {
  363. xOffset = enterAnim.getXDelta();
  364. yOffset = enterAnim.getYDelta();
  365. }
  366. else if ( exitAnim.isAnimating() )
  367. {
  368. xOffset = exitAnim.getXDelta();
  369. yOffset = exitAnim.getYDelta();
  370. }
  371. LogisticsScreen::render( (int)xOffset, (int)yOffset );
  372. }
  373. void MPLoadMap::render()
  374. {
  375. render(0, 0);
  376. }
  377. int MPLoadMap::handleMessage( unsigned long message, unsigned long who)
  378. {
  379. status = who;
  380. end();
  381. exitAnim.begin();
  382. enterAnim.end();
  383. if ( status == YES )
  384. {
  385. }
  386. if ( RUNNING == status )
  387. {
  388. switch ( who )
  389. {
  390. case FIRST_BUTTON_ID+2:
  391. {
  392. getButton( FIRST_BUTTON_ID+2 )->press( 0 );
  393. connectionType = 0;
  394. buttons[indexOfButtonWithID(FIRST_BUTTON_ID+2)].press(!((1 == connectionType) || (2 == connectionType) || (3 == connectionType)));
  395. buttons[indexOfButtonWithID(FIRST_BUTTON_ID+3)].press(1 == connectionType);
  396. buttons[indexOfButtonWithID(FIRST_BUTTON_ID+4)].press(2 == connectionType);
  397. buttons[indexOfButtonWithID(FIRST_BUTTON_ID+5)].press(3 == connectionType);
  398. return 1;
  399. }
  400. break;
  401. }
  402. }
  403. return 0;
  404. }
  405. bool MPLoadMap::isDone()
  406. {
  407. return bDone;
  408. }
  409. void MPLoadMap::update()
  410. {
  411. LogisticsDialog::update();
  412. int oldSel = mapList.GetSelectedItem();
  413. mapList.update();
  414. int newSel = mapList.GetSelectedItem();
  415. if ( oldSel != newSel )
  416. updateMapInfo();
  417. helpTextID = 0;
  418. helpTextHeaderID = 0;
  419. /*
  420. for ( int i = 0; i < buttonCount; i++ )
  421. {
  422. buttons[i].update();
  423. if ( buttons[i].pointInside( userInput->getMouseX(), userInput->getMouseY() )
  424. && userInput->isLeftClick() )
  425. {
  426. handleMessage( buttons[i].getID(), buttons[i].getID() );
  427. }
  428. }
  429. */
  430. }
  431. void MPLoadMap::updateMapInfo()
  432. {
  433. int sel = mapList.GetSelectedItem();
  434. if ( sel != -1 )
  435. {
  436. FitIniFile file;
  437. FullPathFileName path;
  438. const char* fileName = ((aTextListItem*)mapList.GetItem( sel ))->getText();
  439. selMapName = ((aLocalizedListItem*)mapList.GetItem(sel))->getHiddenText();
  440. path.init( missionPath, selMapName, ".fit" );
  441. if ( NO_ERR == file.open( path ) )
  442. {
  443. char missionName[256];
  444. missionName[0] = 0;
  445. bool bRes = 0;
  446. char text[1024];
  447. char text2[1024];
  448. file.seekBlock( "MissionSettings" );
  449. file.readIdBoolean( "MissionNameUseResourceString", bRes );
  450. if ( bRes )
  451. {
  452. unsigned long lRes;
  453. file.readIdULong( "MissionNameResourceStringID", lRes );
  454. cLoadString( lRes, missionName, 255 );
  455. }
  456. else
  457. {
  458. file.readIdString( "MissionName", missionName, 255 );
  459. }
  460. long textureHandle = MissionBriefingScreen::getMissionTGA( selMapName );
  461. statics[18].setTexture( textureHandle );
  462. statics[18].setUVs( 0, 127, 127, 0 );
  463. statics[18].setColor( 0xffffffff );
  464. cLoadString( IDS_MP_LM_MAP_LIST_MAP_NAME, text, 255 );
  465. sprintf( text2, text, missionName );
  466. textObjects[3].setText( text2 );
  467. if ( !bIsSingle )
  468. {
  469. unsigned long type = 0;
  470. file.readIdULong( "MissionType", type );
  471. cLoadString( IDS_MP_LM_MAP_LIST_TYPE, text, 255 );
  472. char mType[128];
  473. cLoadString( IDS_MP_LM_TYPE0 + type, mType, 127 );
  474. sprintf( text2, text, mType );
  475. textObjects[4].setText( text2 );
  476. unsigned long numPlayers = 0;
  477. file.readIdULong( "MaximumNumberOfPlayers", numPlayers );
  478. cLoadString( IDS_MP_LM_MAP_LIST_MAX_PLAYERS, text, 255 );
  479. sprintf( text2, text, numPlayers );
  480. textObjects[2].setText( text2 );
  481. }
  482. else
  483. {
  484. textObjects[4].setText( "" );
  485. textObjects[2].setText( "" );
  486. }
  487. char blurb[1024];
  488. blurb[0] = 0;
  489. long result = file.readIdString("Blurb2", blurb, 1023 );
  490. bool tmpBool = false;
  491. result = file.readIdBoolean("Blurb2UseResourceString", tmpBool);
  492. if (NO_ERR == result && tmpBool )
  493. {
  494. unsigned long tmpInt = 0;
  495. result = file.readIdULong("Blurb2ResourceStringID", tmpInt);
  496. if (NO_ERR == result)
  497. {
  498. cLoadString( tmpInt, blurb, 1024 );
  499. }
  500. }
  501. textObjects[5].setText( blurb );
  502. }
  503. }
  504. else
  505. {
  506. textObjects[4].setText( "" );
  507. textObjects[3].setText( "" );
  508. textObjects[2].setText( "" );
  509. textObjects[5].setText( "" );
  510. statics[18].setColor( 0 );
  511. }
  512. }
  513. void MPLoadMap::getMapNameFromFile( const char* pFileName, char* missionName, long bufferLength )
  514. {
  515. FullPathFileName path;
  516. path.init( missionPath, pFileName, ".fit" );
  517. FitIniFile file;
  518. if ( NO_ERR != file.open( (char*)(const char*)path ) )
  519. {
  520. char errorStr[256];
  521. sprintf( errorStr, "couldn't open file %s", path );
  522. Assert( 0, 0, errorStr );
  523. }
  524. long result = file.seekBlock( "MissionSettings" );
  525. Assert( result == NO_ERR, 0, "Coudln't find the mission settings block in the mission file" );
  526. missionName[0] = 0;
  527. bool bRes = 0;
  528. result = file.readIdBoolean( "MissionNameUseResourceString", bRes );
  529. //Assert( result == NO_ERR, 0, "couldn't find the MissionNameUseResourceString" );
  530. if ( bRes )
  531. {
  532. unsigned long lRes;
  533. result = file.readIdULong( "MissionNameResourceStringID", lRes );
  534. Assert( result == NO_ERR, 0, "couldn't find the MissionNameResourceStringID" );
  535. cLoadString( lRes, missionName, bufferLength );
  536. }
  537. else
  538. {
  539. result = file.readIdString( "MissionName", missionName, bufferLength );
  540. Assert( result == NO_ERR, 0, "couldn't find the missionName" );
  541. }
  542. }
  543. //////////////////////////////////////////////
  544. //*************************************************************************************************
  545. // end of file ( MPLoadMap.cpp )