MPGameBrowser.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. #define MPGAMEBROWSER_CPP
  2. /*************************************************************************************************\
  3. MPGameBrowser.cpp : Implementation of the MPGameBrowser component.
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. \*************************************************************************************************/
  8. #include "MPGameBrowser.h"
  9. #include "prefs.h"
  10. #include "IniFile.h"
  11. #include "../MCLib/UserInput.h"
  12. #include "..\resource.h"
  13. #include "Multplyr.h"
  14. #include "MechBayScreen.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. #define SORT_ORDER_NAME 200
  24. #define SORT_ORDER_PLAYERS 201
  25. #define SORT_ORDER_MAP 202
  26. #define SORT_ORDER_PING 203
  27. extern CPrefs prefs;
  28. MPGameBrowser::MPGameBrowser()
  29. {
  30. status = NEXT;
  31. helpTextArrayID = 5;
  32. bShowErrorDlg = 0;
  33. sortOrder = SORT_ORDER_NAME;
  34. bSortUpward = 1;
  35. bHosting = 0;
  36. bShowErrorDlg = 0;
  37. }
  38. MPGameBrowser::~MPGameBrowser()
  39. {
  40. // gameList.destroy();
  41. }
  42. int MPGameBrowser::indexOfButtonWithID(int id)
  43. {
  44. int i;
  45. for (i = 0; i < buttonCount; i++)
  46. {
  47. if (buttons[i].getID() == id)
  48. {
  49. return i;
  50. }
  51. }
  52. return -1;
  53. }
  54. void MPGameBrowser::init(FitIniFile* file)
  55. {
  56. LogisticsScreen::init( *file, "Static", "Text", "Rect", "Button" );
  57. if ( buttonCount )
  58. {
  59. for ( int i = 0; i < buttonCount; i++ )
  60. {
  61. buttons[i].setMessageOnRelease();
  62. if (buttons[i].getID() == 0)
  63. {
  64. buttons[i].setID(FIRST_BUTTON_ID + i);
  65. buttons[i].setPressFX( LOG_VIDEOBUTTONS );
  66. buttons[i].setHighlightFX( LOG_DIGITALHIGHLIGHT );
  67. buttons[i].setDisabledFX( LOG_WRONGBUTTON );
  68. }
  69. }
  70. }
  71. {
  72. char path[256];
  73. strcpy( path, artPath );
  74. strcat( path, "mcl_mp_lanbrowsercombobox0.fit" );
  75. FitIniFile PNfile;
  76. if ( NO_ERR != PNfile.open( path ) )
  77. {
  78. char error[256];
  79. sprintf( error, "couldn't open file %s", path );
  80. Assert( 0, 0, error );
  81. return;
  82. }
  83. PNfile.seekBlock("GameList"); /*for some reason aListBox::init(...) doesn't do the seekBlock itself*/
  84. gameList.init(&PNfile, "GameList");
  85. gameList.SelectItem(0);
  86. gameList.init( rects[0].left(), rects[0].top(), rects[0].width(), rects[0].height() );
  87. gameList.setOrange( true );
  88. templateItem.init(&PNfile, "GameListItem");
  89. for ( int i = 0; i < 256; i++ )
  90. {
  91. items[i] = templateItem;
  92. }
  93. }
  94. hostDlg.init();
  95. }
  96. void MPGameBrowser::begin()
  97. {
  98. status = RUNNING;
  99. bHosting = 0;
  100. bShowErrorDlg = 0;
  101. if ( MPlayer )
  102. {
  103. MPlayer->closeSession();
  104. // MPlayer->leaveSession(); // make sure I'm not hosting or already in a game....
  105. MPlayer->beginSessionScan (NULL);
  106. MPlayer->setMode(MULTIPLAYER_MODE_BROWSER);
  107. }
  108. }
  109. void MPGameBrowser::end()
  110. {
  111. if ( MPlayer )
  112. MPlayer->endSessionScan();
  113. bHosting = 0;
  114. }
  115. void MPGameBrowser::render(int xOffset, int yOffset )
  116. {
  117. if ((0 == xOffset) && (0 == yOffset))
  118. {
  119. gameList.render();
  120. }
  121. LogisticsScreen::render(xOffset, yOffset);
  122. if ( bHosting )
  123. {
  124. hostDlg.render();
  125. }
  126. if ( bShowErrorDlg )
  127. {
  128. LogisticsOneButtonDialog::instance()->render();
  129. return;
  130. }
  131. }
  132. void MPGameBrowser::render()
  133. {
  134. render(0, 0);
  135. }
  136. int MPGameBrowser::handleMessage( unsigned long message, unsigned long who)
  137. {
  138. if ( RUNNING == status )
  139. {
  140. switch ( who )
  141. {
  142. case SORT_ORDER_NAME:
  143. case SORT_ORDER_PLAYERS:
  144. case SORT_ORDER_MAP:
  145. case SORT_ORDER_PING:
  146. if ( sortOrder == who )
  147. bSortUpward ^= 1;
  148. else
  149. bSortUpward = 1;
  150. sortOrder = who;
  151. break;
  152. case 57/*MB_MSG_MAINMENU*/:
  153. {
  154. getButton( 57/*MB_MSG_MAINMENU*/ )->press( 0 );
  155. status = MAINMENU;
  156. }
  157. break;
  158. case 51/*MB_MSG_PREV*/:
  159. {
  160. getButton( 51/*MB_MSG_PREV*/ )->press( 0 );
  161. status = PREVIOUS;
  162. }
  163. break;
  164. case 50/*MB_MSG_NEXT*/:
  165. {
  166. getButton( 50/*MB_MSG_NEXT*/ )->press( 0 );
  167. int index = gameList.GetSelectedItem();
  168. if ( index != -1 )
  169. {
  170. aGameListItem* pItem = (aGameListItem*)gameList.GetItem( index );
  171. if ( pItem )
  172. {
  173. if ( MPlayer )
  174. {
  175. long retVal = MPlayer->joinSession ( (MC2Session*)pItem->getSession(), &prefs.playerName[0][0] );
  176. if ( retVal == MPLAYER_NO_ERR ) {
  177. MPlayer->setMode(MULTIPLAYER_MODE_PARAMETERS);
  178. status = NEXT;
  179. }
  180. else
  181. {
  182. int errorID = IDS_MP_CONNECT_NO_SESSION;
  183. int fontID = IDS_MP_CONNECT_ERROR_NO_SESSION_FONT;
  184. // display a dialog about why this can't happen....
  185. switch ( retVal )
  186. {
  187. case MPLAYER_ERR_HOST_NOT_FOUND:
  188. errorID = IDS_MP_CONNECT_ERROR_NO_HOST;
  189. fontID = IDS_MP_CONNECT_ERROR_NO_HOST_FONT;
  190. break;
  191. case MPLAYER_ERR_NO_CONNECTION:
  192. errorID = IDS_MP_CONNECT_ERROR_NO_CONNECTION;
  193. fontID = IDS_MP_CONNECT_ERROR_NO_CONNECTION_FONT;
  194. break;
  195. case MPLAYER_ERR_SESSION_IN_PROGRESS:
  196. errorID = IDS_MP_CONNECT_ERROR_IN_PROGRESS;
  197. fontID = IDS_MP_CONNECT_ERROR_IN_PROGRESS_FONT;
  198. break;
  199. case MPLAYER_ERR_SESSION_LOCKED:
  200. errorID = IDS_MP_CONNECT_ERROR_LOCKED;
  201. fontID = IDS_MP_CONNECT_ERROR_LOCKED_FONT;
  202. break;
  203. case MPLAYER_ERR_BAD_VERSION:
  204. errorID = IDS_MP_CONNECTION_ERROR_WRONG_VERSION;
  205. fontID = IDS_MP_CONNECTION_ERROR_WRONG_VERSION_FONT;
  206. break;
  207. case MPLAYER_ERR_SESSION_FULL:
  208. errorID = IDS_MP_CONNECTION_ERROR_FULL;
  209. fontID = IDS_MP_CONNECTION_ERROR_FULL_FONT;
  210. break;
  211. }
  212. LogisticsOneButtonDialog::instance()->begin();
  213. LogisticsOneButtonDialog::instance()->setText( errorID, IDS_DIALOG_OK, IDS_DIALOG_OK );
  214. LogisticsOneButtonDialog::instance()->setFont( fontID );
  215. bShowErrorDlg = true;
  216. }
  217. }
  218. }
  219. }
  220. }
  221. break;
  222. case FIRST_BUTTON_ID+1:
  223. {
  224. //join game
  225. getButton( FIRST_BUTTON_ID+1 )->press( 0 );
  226. status = NEXT;
  227. return 1;
  228. }
  229. break;
  230. case FIRST_BUTTON_ID+2:
  231. {
  232. //host game
  233. getButton( FIRST_BUTTON_ID+2 )->press( 0 );
  234. bHosting = true;
  235. hostDlg.begin();
  236. return 1;
  237. }
  238. break;
  239. }
  240. }
  241. return 0;
  242. }
  243. bool MPGameBrowser::isDone()
  244. {
  245. return status != RUNNING;
  246. }
  247. void MPGameBrowser::update()
  248. {
  249. if ( bHosting )
  250. {
  251. hostDlg.update();
  252. if ( hostDlg.isDone() )
  253. {
  254. bHosting = 0;
  255. if ( hostDlg.getStatus() == YES )
  256. {
  257. status = NEXT;
  258. }
  259. }
  260. return;
  261. }
  262. else if ( bShowErrorDlg )
  263. {
  264. LogisticsOneButtonDialog::instance()->update();
  265. if ( LogisticsOneButtonDialog::instance()->isDone() )
  266. {
  267. bShowErrorDlg = 0;
  268. }
  269. return;
  270. }
  271. LogisticsScreen::update();
  272. gameList.update();
  273. float oldScrollPos = gameList.getScrollPos();
  274. if ( userInput->isLeftDoubleClick() )
  275. {
  276. int index = gameList.GetSelectedItem();
  277. if ( index != -1 )
  278. {
  279. handleMessage( MB_MSG_NEXT, MB_MSG_NEXT );
  280. return;
  281. }
  282. }
  283. int oldSel = gameList.GetSelectedItem();
  284. int oldHighlight = -1;
  285. for ( int i = 0; i < gameList.GetItemCount(); i++ )
  286. {
  287. if ( gameList.GetItem( i )->getState() == aListItem::HIGHLITE )
  288. oldHighlight = i;
  289. }
  290. helpTextID = 0;
  291. helpTextHeaderID = 0;
  292. long sessionCount = 0;
  293. if ( MPlayer )
  294. {
  295. MC2Session* pSessions = MPlayer->getSessions (sessionCount);
  296. gameList.removeAllItems( 0 );
  297. // could easily do sort here.
  298. for ( int i = 0; i < sessionCount; i++ )
  299. {
  300. if (pSessions[i].cancelled)
  301. continue;
  302. items[i].setSessionInfo( &pSessions[i] );
  303. items[i].moveTo( templateItem.globalX(), templateItem.globalY() );
  304. bool bAdded = 0;
  305. for ( int j = 0; j < gameList.GetItemCount(); j++ )
  306. {
  307. aGameListItem* pItem = (aGameListItem*)gameList.GetItem( j );
  308. int res = stricmp( pItem->getText( sortOrder ), items[i].getText( sortOrder ) );
  309. if ( (bSortUpward && res > 0) || (!bSortUpward && res < 0) )
  310. {
  311. gameList.InsertItem( &items[i], j );
  312. bAdded = true;
  313. break;
  314. }
  315. }
  316. if ( !bAdded )
  317. {
  318. gameList.AddItem( &items[i] );
  319. }
  320. }
  321. gameList.SelectItem( oldSel );
  322. if ( oldHighlight != -1 && gameList.GetItem( oldHighlight ) )
  323. gameList.GetItem( oldHighlight )->setState( aListItem::HIGHLITE );
  324. }
  325. long sel = gameList.GetSelectedItem();
  326. if ( sel == -1 )
  327. {
  328. getButton( MB_MSG_NEXT )->disable( true );
  329. }
  330. else
  331. getButton( MB_MSG_NEXT )->disable( false );
  332. gameList.setScrollPos(oldScrollPos);
  333. }
  334. long aStyle3TextListItem::init( FitIniFile* file, const char* blockName )
  335. {
  336. file->seekBlock( blockName );
  337. long x = 0;
  338. long y = 0;
  339. file->readIdLong( "XLocation", x );
  340. file->readIdLong( "YLocation", y );
  341. long fontResID = 0;
  342. file->readIdLong( "Font", fontResID );
  343. long textID = 0;
  344. file->readIdLong( "TextID", textID );
  345. aTextListItem::init(fontResID);
  346. setText(textID);
  347. long color = 0xff808080;
  348. file->readIdLong( "Color", color );
  349. normalColor = color;
  350. setColor(color);
  351. char tmpStr[64];
  352. strcpy(tmpStr, "");
  353. file->readIdString( "Animation", tmpStr, 63 );
  354. if (0 == strcmp("", tmpStr))
  355. {
  356. hasAnimation = false;
  357. }
  358. else
  359. {
  360. hasAnimation = true;
  361. animGroup.init(file, tmpStr);
  362. }
  363. moveTo(x, y);
  364. return 0;
  365. }
  366. void aStyle3TextListItem::render()
  367. {
  368. unsigned long color;
  369. animGroup.update();
  370. if (aListItem::SELECTED == getState())
  371. {
  372. animGroup.setState( aAnimGroup::PRESSED );
  373. color = animGroup.getCurrentColor( aAnimGroup::PRESSED );
  374. }
  375. else if (aListItem::HIGHLITE == getState())
  376. {
  377. animGroup.setState( aAnimGroup::HIGHLIGHT );
  378. color = animGroup.getCurrentColor( aAnimGroup::HIGHLIGHT );
  379. }
  380. else if (aListItem::DISABLED == getState())
  381. {
  382. animGroup.setState( aAnimGroup::DISABLED );
  383. color = animGroup.getCurrentColor( aAnimGroup::DISABLED );
  384. }
  385. else
  386. {
  387. animGroup.setState( aAnimGroup::NORMAL );
  388. color = animGroup.getCurrentColor( aAnimGroup::NORMAL );
  389. }
  390. aTextListItem::setColor((unsigned long)color);
  391. aTextListItem::render();
  392. }
  393. aGameListItem& aGameListItem::operator=( const aGameListItem& src )
  394. {
  395. removeAllChildren( );
  396. aObject::operator=( src );
  397. session = src.session;
  398. allTechGraphic = src.allTechGraphic;
  399. gameName = src.gameName;
  400. numPlayers = src.numPlayers;
  401. mapName = src.mapName;
  402. latency = src.latency;
  403. allTechRect = src.allTechRect;
  404. gameNameRect = src.gameNameRect;
  405. numPlayersRect = src.numPlayersRect;
  406. mapNameRect = src.mapNameRect;
  407. latencyRect = src.latencyRect;
  408. pingIcon = src.pingIcon;
  409. addChild(&allTechGraphic);
  410. addChild(&gameName);
  411. addChild(&numPlayers);
  412. addChild(&mapName);
  413. addChild(&latency);
  414. addChild(&allTechRect);
  415. addChild(&gameNameRect);
  416. addChild(&numPlayersRect);
  417. addChild(&mapNameRect);
  418. addChild(&latencyRect);
  419. addChild(&pingIcon );
  420. return *this;
  421. }
  422. aGameListItem::aGameListItem() : latency( IDS_MP_LANBROW_PING_FONT )
  423. {
  424. }
  425. long aGameListItem::init( FitIniFile* file, const char* blockName )
  426. {
  427. file->seekBlock( blockName );
  428. long width = 0;
  429. long height = 0;
  430. file->readIdLong( "Width", width );
  431. file->readIdLong( "Height", height );
  432. EString graphicBlockName;
  433. graphicBlockName += "Static0";
  434. allTechGraphic.init(file, graphicBlockName.Data());
  435. if (allTechGraphic.height() + 5 > height)
  436. {
  437. height = allTechGraphic.height() + 5;
  438. }
  439. if (allTechGraphic.globalRight() - globalX() > width)
  440. {
  441. width = allTechGraphic.globalRight() - globalX();
  442. }
  443. EString textBlockName;
  444. textBlockName = "Text0";
  445. gameName.init(file, textBlockName.Data());
  446. if (gameName.height() > height)
  447. {
  448. height = gameName.height();
  449. }
  450. if (gameName.globalRight() - globalX() > width)
  451. {
  452. //width = gameName.globalRight() - globalX();
  453. }
  454. textBlockName = "Text1";
  455. numPlayers.init(file, textBlockName.Data());
  456. if (numPlayers.height() > height)
  457. {
  458. height = numPlayers.height();
  459. }
  460. if (numPlayers.globalRight() - globalX() > width)
  461. {
  462. //width = numPlayers.globalRight() - globalX();
  463. }
  464. textBlockName = "Text2";
  465. mapName.init(file, textBlockName.Data());
  466. if (mapName.height() > height)
  467. {
  468. height = mapName.height();
  469. }
  470. if (mapName.globalRight() - globalX() > width)
  471. {
  472. //width = mapName.globalRight() - globalX();
  473. }
  474. textBlockName = "Text3";
  475. latency.init(*file, textBlockName.Data());
  476. if (latency.height() > height)
  477. {
  478. height = latency.height();
  479. }
  480. if (latency.globalRight() - globalX() > width)
  481. {
  482. //width = latency.globalRight() - globalX();
  483. }
  484. EString rectBlockName;
  485. rectBlockName = "Rect0";
  486. allTechRect.init(file, rectBlockName.Data());
  487. if (allTechRect.height() > height)
  488. {
  489. height = allTechRect.height();
  490. }
  491. if (allTechRect.globalRight() - globalX() > width)
  492. {
  493. width = allTechRect.globalRight() - globalX();
  494. }
  495. rectBlockName = "Rect1";
  496. gameNameRect.init(file, rectBlockName.Data());
  497. if (gameNameRect.height() > height)
  498. {
  499. height = gameNameRect.height();
  500. }
  501. if (gameNameRect.globalRight() - globalX() > width)
  502. {
  503. width = gameNameRect.globalRight() - globalX();
  504. }
  505. rectBlockName = "Rect2";
  506. numPlayersRect.init(file, rectBlockName.Data());
  507. if (numPlayersRect.height() > height)
  508. {
  509. height = numPlayersRect.height();
  510. }
  511. if (numPlayersRect.globalRight() - globalX() > width)
  512. {
  513. width = numPlayersRect.globalRight() - globalX();
  514. }
  515. rectBlockName = "Rect3";
  516. mapNameRect.init(file, rectBlockName.Data());
  517. if (mapNameRect.height() > height)
  518. {
  519. height = mapNameRect.height();
  520. }
  521. if (mapNameRect.globalRight() - globalX() > width)
  522. {
  523. width = mapNameRect.globalRight() - globalX();
  524. }
  525. rectBlockName = "Rect4";
  526. latencyRect.init(file, rectBlockName.Data());
  527. if (latencyRect.height() > height)
  528. {
  529. height = latencyRect.height();
  530. }
  531. if (latencyRect.globalRight() - globalX() > width)
  532. {
  533. width = latencyRect.globalRight() - globalX();
  534. }
  535. pingIcon.init( file, "Static1" );
  536. aObject::init(0, 0, width, height);
  537. addChild(&allTechGraphic);
  538. addChild(&gameName);
  539. addChild(&numPlayers);
  540. addChild(&mapName);
  541. addChild(&latency);
  542. addChild(&allTechRect);
  543. addChild(&gameNameRect);
  544. addChild(&numPlayersRect);
  545. addChild(&mapNameRect);
  546. addChild(&latencyRect);
  547. addChild( &pingIcon );
  548. return 0;
  549. }
  550. void aGameListItem::setSessionInfo( MC2Session* pSession )
  551. {
  552. memcpy(&session, pSession, sizeof(MC2Session));
  553. gameName.setText( pSession->name );
  554. mapName.setText( pSession->map );
  555. char tmp[256];
  556. sprintf( tmp, "%ld/%ld", pSession->numPlayers, pSession->maxPlayers );
  557. numPlayers.setText( tmp );
  558. sprintf( tmp, "%ld", pSession->ping );
  559. latency.setText( tmp );
  560. if ( state == DISABLED )
  561. setState( ENABLED );
  562. if ( pSession->locked )
  563. {
  564. allTechGraphic.showGUIWindow( true );
  565. setState( DISABLED );
  566. }
  567. else
  568. {
  569. allTechGraphic.showGUIWindow( false );
  570. }
  571. if ( pSession->numPlayers == pSession->maxPlayers || pSession->inProgress )
  572. setState( DISABLED );
  573. long color = 0xff00ff00;
  574. if ( pSession->ping > 500 )
  575. color = 0xffff0000;
  576. else if ( pSession->ping > 300 )
  577. color = 0xffffff00;
  578. latency.setColor( color );
  579. pingIcon.setColor( color );
  580. //<300ms - green
  581. //301-500ms - yellow
  582. //>501ms - red
  583. }
  584. const char* aGameListItem::getText( int which )
  585. {
  586. if ( which == SORT_ORDER_NAME )
  587. return gameName.getText();
  588. else if ( which == SORT_ORDER_PLAYERS )
  589. return numPlayers.getText();
  590. else if ( which == SORT_ORDER_PING )
  591. return numPlayers.getText();
  592. else if ( which == SORT_ORDER_MAP )
  593. return mapName.getText();
  594. return NULL;
  595. }
  596. const char* aGameListItem::getSessionName( )
  597. {
  598. return gameName.getText();
  599. }
  600. void aGameListItem::update()
  601. {
  602. gameName.setState(getState());
  603. numPlayers.setState(getState());
  604. mapName.setState(getState());
  605. latency.setState(getState());
  606. aListItem::update();
  607. }
  608. //////////////////////////////////////////////
  609. //*************************************************************************************************
  610. // end of file ( MPGameBrowser.cpp )