Shell.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  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: Shell.cpp ////////////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, September 2001
  25. // Description: Shell menu representations
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  29. #include "Common/RandomValue.h"
  30. #include "GameClient/Shell.h"
  31. #include "GameClient/WindowLayout.h"
  32. #include "GameClient/GameWindowManager.h"
  33. #include "GameClient/GameWindowTransitions.h"
  34. #include "GameClient/IMEManager.h"
  35. #include "GameClient/AnimateWindowManager.h"
  36. #include "GameClient/ShellMenuScheme.h"
  37. #include "GameLogic/GameLogic.h"
  38. #include "GameNetwork/GameSpyOverlay.h"
  39. #include "GameNetwork/GameSpy/PeerDefsImplementation.h"
  40. #include <rts/profile.h>
  41. // PUBLIC DATA ////////////////////////////////////////////////////////////////////////////////////
  42. Shell *TheShell = NULL; ///< the shell singleton definition
  43. #ifdef _INTERNAL
  44. // for occasional debugging...
  45. //#pragma optimize("", off)
  46. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  47. #endif
  48. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
  49. //-------------------------------------------------------------------------------------------------
  50. //-------------------------------------------------------------------------------------------------
  51. Shell::Shell( void )
  52. {
  53. Int i;
  54. m_screenCount = 0;
  55. for( i = 0; i < MAX_SHELL_STACK; i++ )
  56. m_screenStack[ i ] = NULL;
  57. m_pendingPush = FALSE;
  58. m_pendingPop = FALSE;
  59. m_pendingPushName.set( "" );
  60. m_isShellActive = TRUE;
  61. m_shellMapOn = FALSE;
  62. m_background = NULL;
  63. m_clearBackground = FALSE;
  64. m_animateWindowManager = NEW AnimateWindowManager;
  65. m_schemeManager = NEW ShellMenuSchemeManager;
  66. m_saveLoadMenuLayout = NULL;
  67. m_popupReplayLayout = NULL;
  68. //Added By Sadullah Nader
  69. //Initializations
  70. m_optionsLayout = NULL;
  71. m_screenCount = 0;
  72. //
  73. } // end Shell
  74. //-------------------------------------------------------------------------------------------------
  75. //-------------------------------------------------------------------------------------------------
  76. Shell::~Shell( void )
  77. {
  78. WindowLayout *newTop = top();
  79. while(newTop)
  80. {
  81. popImmediate();
  82. newTop = top();
  83. }
  84. if(m_background)
  85. {
  86. m_background->destroyWindows();
  87. m_background->deleteInstance();
  88. m_background = NULL;
  89. }
  90. if(m_animateWindowManager)
  91. delete m_animateWindowManager;
  92. m_animateWindowManager = NULL;
  93. if(m_schemeManager)
  94. delete m_schemeManager;
  95. m_schemeManager = NULL;
  96. // delete the save/load menu if present
  97. if( m_saveLoadMenuLayout )
  98. {
  99. m_saveLoadMenuLayout->destroyWindows();
  100. m_saveLoadMenuLayout->deleteInstance();
  101. m_saveLoadMenuLayout = NULL;
  102. } //end if
  103. // delete the replay save menu if present
  104. if( m_popupReplayLayout )
  105. {
  106. m_popupReplayLayout->destroyWindows();
  107. m_popupReplayLayout->deleteInstance();
  108. m_popupReplayLayout = NULL;
  109. } //end if
  110. // delete the options menu if present.
  111. if (m_optionsLayout != NULL) {
  112. m_optionsLayout->destroyWindows();
  113. m_optionsLayout->deleteInstance();
  114. m_optionsLayout = NULL;
  115. }
  116. } // end ~Shell
  117. //-------------------------------------------------------------------------------------------------
  118. /** Initialize the shell system */
  119. //-------------------------------------------------------------------------------------------------
  120. void Shell::init( void )
  121. {
  122. INI ini;
  123. // Read from INI all the ShellMenuScheme
  124. ini.load( AsciiString( "Data\\INI\\Default\\ShellMenuScheme.ini" ), INI_LOAD_OVERWRITE, NULL );
  125. ini.load( AsciiString( "Data\\INI\\ShellMenuScheme.ini" ), INI_LOAD_OVERWRITE, NULL );
  126. if( m_schemeManager )
  127. m_schemeManager->init();
  128. } // end init
  129. //-------------------------------------------------------------------------------------------------
  130. /** Reset the shell system to a clean state just as though init had
  131. * just been called and ready to re-use */
  132. //-------------------------------------------------------------------------------------------------
  133. void Shell::reset( void )
  134. {
  135. if (TheIMEManager)
  136. TheIMEManager->detatch();
  137. // pop all screens
  138. while( m_screenCount )
  139. pop();
  140. m_animateWindowManager->reset();
  141. } // end reset
  142. //-------------------------------------------------------------------------------------------------
  143. /** Update shell system cycle. All windows are updated that are on the stack, starting
  144. * with the top layout and progressing to the bottom one */
  145. //-------------------------------------------------------------------------------------------------
  146. void Shell::update( void )
  147. {
  148. static Int lastUpdate = timeGetTime();
  149. static const Int shellUpdateDelay = 30; // try to update 30 frames a second
  150. Int now = timeGetTime();
  151. //
  152. // we keep the shell updates fixed in time so that we can write consitent animation
  153. // speeds during the screen update functions
  154. //
  155. if( now - lastUpdate >= ((1000.0f / shellUpdateDelay ) - 1) )
  156. {
  157. // run the updates for every window layout on the stack
  158. for( Int i = m_screenCount - 1; i >= 0; i-- )
  159. {
  160. DEBUG_ASSERTCRASH( m_screenStack[ i ], ("Top of shell stack is NULL!\n") );
  161. m_screenStack[ i ]->runUpdate( NULL );
  162. } // end for i
  163. if(TheGlobalData->m_shellMapOn && m_shellMapOn &&m_background)
  164. {
  165. m_background->destroyWindows();
  166. m_background->deleteInstance();
  167. m_background = NULL;
  168. }
  169. // Update the animate window manager
  170. m_animateWindowManager->update();
  171. m_schemeManager->update();
  172. // mark last time we ran the updates
  173. lastUpdate = now;
  174. } // end if
  175. } // end update
  176. //-------------------------------------------------------------------------------------------------
  177. /** Find a screen via the .wnd script filename loaded */
  178. //-------------------------------------------------------------------------------------------------
  179. WindowLayout *Shell::findScreenByFilename( AsciiString filename )
  180. {
  181. if (filename.isEmpty())
  182. return NULL;
  183. // search screen list
  184. WindowLayout *screen;
  185. Int i;
  186. for( i = 0; i < MAX_SHELL_STACK; i++ )
  187. {
  188. screen = m_screenStack[ i ];
  189. if( screen && filename.compareNoCase(screen->getFilename()) == 0 )
  190. return screen;
  191. } // end for i
  192. return NULL;
  193. } // end findScreenByFilename
  194. //-------------------------------------------------------------------------------------------------
  195. /** Hide or unhide all window layouts loaded */
  196. //-------------------------------------------------------------------------------------------------
  197. void Shell::hide( Bool hide )
  198. {
  199. Int i;
  200. for( i = 0; i < MAX_SHELL_STACK; i++ )
  201. if( m_screenStack[ i ] )
  202. m_screenStack[ i ]->hide( hide );
  203. if (TheIMEManager)
  204. TheIMEManager->detatch();
  205. } // end hide
  206. //-------------------------------------------------------------------------------------------------
  207. /** Push layout onto shell */
  208. //-------------------------------------------------------------------------------------------------
  209. void Shell::push( AsciiString filename, Bool shutdownImmediate )
  210. {
  211. // sanity
  212. if( filename.isEmpty() )
  213. return;
  214. if(TheGameSpyInfo)
  215. GameSpyCloseAllOverlays();
  216. #ifdef DEBUG_LOGGING
  217. DEBUG_LOG(("Shell:push(%s) - stack was\n", filename.str()));
  218. for (Int i=0; i<m_screenCount; ++i)
  219. {
  220. DEBUG_LOG(("\t\t%s\n", m_screenStack[i]->getFilename().str()));
  221. }
  222. #endif
  223. // make sure we have an available spot for another screen
  224. if( m_screenCount >= MAX_SHELL_STACK )
  225. {
  226. DEBUG_LOG(( "Unable to load screen '%s', max '%d' reached\n",
  227. filename, MAX_SHELL_STACK ));
  228. return;
  229. } // end if
  230. // set a push as pending with the layout name passed in
  231. m_pendingPush = TRUE;
  232. m_pendingPushName = filename;
  233. // get the top of the current stack
  234. WindowLayout *currentTop = top();
  235. //
  236. // if we have someting on the top of the stack we won't do the push
  237. // right now, we will instead shutdown the top, and when the top tells
  238. // us it's done shutting down (via the shutdownComplete() method) we do
  239. // the push then
  240. //
  241. if( currentTop && !currentTop->isHidden() )
  242. {
  243. // run the shutdown
  244. currentTop->runShutdown( &shutdownImmediate );
  245. } // end if
  246. else
  247. {
  248. // just call shutdownComplete() which will immediately cause the push to happen
  249. shutdownComplete( NULL );
  250. } // end else
  251. // if (TheIMEManager)
  252. // TheIMEManager->detatch();
  253. } // end push
  254. //-------------------------------------------------------------------------------------------------
  255. /** Pop top layout of the stack. Note that we don't actually do the pop right here,
  256. * we instead run the layout shutdown. That shutdown() in turn notifies the
  257. * shell when the shutdown is complete and at that point we do the actual pop */
  258. //-------------------------------------------------------------------------------------------------
  259. void Shell::pop( void )
  260. {
  261. WindowLayout *screen = top();
  262. if(TheGameSpyInfo)
  263. GameSpyCloseAllOverlays();
  264. // sanity
  265. if( screen == NULL )
  266. return;
  267. #ifdef DEBUG_LOGGING
  268. DEBUG_LOG(("Shell:pop() - stack was\n"));
  269. for (Int i=0; i<m_screenCount; ++i)
  270. {
  271. DEBUG_LOG(("\t\t%s\n", m_screenStack[i]->getFilename().str()));
  272. }
  273. #endif
  274. // set a pop as pending
  275. m_pendingPop = TRUE;
  276. //
  277. // run the shutdown function for the screen, when it's actually shutdown it
  278. // will call Shell::shutdownComplete(), where the pending pop will be seen
  279. // and the actual pop will occur
  280. //
  281. Bool immediatePop = FALSE;
  282. screen->runShutdown( &immediatePop );
  283. if (TheIMEManager)
  284. TheIMEManager->detatch();
  285. } // end pop
  286. //-------------------------------------------------------------------------------------------------
  287. /** When you need to immediately pop a screen off the stack use this method. It
  288. * gives the screen the opportunity to shutdown and tells the shutdown
  289. * method that an immediate pop is going to take place. When control returns
  290. * from the shutdown() for the screen, it will be immediately popped off
  291. * the stack */
  292. //-------------------------------------------------------------------------------------------------
  293. void Shell::popImmediate( void )
  294. {
  295. WindowLayout *screen = top();
  296. // sanity
  297. if( screen == NULL )
  298. return;
  299. #ifdef DEBUG_LOGGING
  300. DEBUG_LOG(("Shell:popImmediate() - stack was\n"));
  301. for (Int i=0; i<m_screenCount; ++i)
  302. {
  303. DEBUG_LOG(("\t\t%s\n", m_screenStack[i]->getFilename().str()));
  304. }
  305. #endif
  306. // do NOT set pending pop, we are going to force a pop after the shutdown is run
  307. m_pendingPop = FALSE;
  308. // run the shutdown
  309. Bool immediatePop = TRUE;
  310. screen->runShutdown( &immediatePop );
  311. // pop the screen of the stack
  312. doPop( FALSE );
  313. if (TheIMEManager)
  314. TheIMEManager->detatch();
  315. } // end popImmediate
  316. //-------------------------------------------------------------------------------------------------
  317. /** Run the initialize function for the top of the stack just as though it was pushed
  318. * on the stack. We want this behavior when we want to act like the top was just
  319. * pushed on the stack, but it's already there (ie going from in game back to the
  320. * pre-game shell menus */
  321. //-------------------------------------------------------------------------------------------------
  322. void Shell::showShell( Bool runInit )
  323. {
  324. DEBUG_LOG(("Shell:showShell() - %s (%s)\n", TheGlobalData->m_initialFile.str(), (top())?top()->getFilename().str():"no top screen"));
  325. if(!TheGlobalData->m_initialFile.isEmpty())
  326. {
  327. return;
  328. }
  329. // runInit is used if we want show shell to run
  330. if(runInit)
  331. {
  332. WindowLayout *layout = top();
  333. if( layout )
  334. {
  335. layout->runInit( NULL );
  336. // layout->bringForward();
  337. }
  338. }
  339. // @todo remove this hack
  340. // TheGlobalData->m_inGame = FALSE;
  341. // add in the background stuff
  342. // if(TheGlobalData->m_shellMapOn)
  343. // {
  344. // if( top() )
  345. // top()->hide(TRUE);
  346. // m_background = TheWindowManager->winCreateLayout("Menus/BlankWindow.wnd");
  347. // DEBUG_ASSERTCRASH(m_background,("We Couldn't Load Menus/BlankWindow.wnd"));
  348. // m_background->hide(FALSE);
  349. // m_background->bringForward();
  350. // if (TheGameLogic->isInGame())
  351. // TheMessageStream->appendMessage( GameMessage::MSG_CLEAR_GAME_DATA );
  352. //
  353. // TheGlobalData->m_pendingFile = TheGlobalData->m_shellMapName;
  354. // GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_NEW_GAME );
  355. // msg->appendIntegerArgument(GAME_SHELL);
  356. // }
  357. // else
  358. // {
  359. //
  360. // m_background = TheWindowManager->winCreateLayout("Menus/BlankWindow.wnd");
  361. //
  362. // DEBUG_ASSERTCRASH(m_background,("We Couldn't Load Menus/BlankWindow.wnd"));
  363. // m_background->hide(FALSE);
  364. // if (top())
  365. // top()->bringForward();
  366. //
  367. // }
  368. if (!TheGlobalData->m_shellMapOn && m_screenCount == 0)
  369. {
  370. #ifdef _PROFILE
  371. Profile::StopRange("init");
  372. #endif
  373. //else
  374. TheShell->push( AsciiString("Menus/MainMenu.wnd") );
  375. }
  376. m_isShellActive = TRUE;
  377. } // end showShell
  378. void Shell::showShellMap(Bool useShellMap )
  379. {
  380. // we don't want any of this to show if we're loading straight into a file
  381. if(TheGlobalData->m_initialFile.isNotEmpty() || !TheGameLogic )
  382. return;
  383. if(useShellMap && TheGlobalData->m_shellMapOn)
  384. {
  385. // we're already in a shell game, return
  386. if(TheGameLogic->isInGame() && TheGameLogic->getGameMode() == GAME_SHELL)
  387. return;
  388. // we're in some other kind of game, clear it out foo!
  389. if(TheGameLogic->isInGame())
  390. TheMessageStream->appendMessage( GameMessage::MSG_CLEAR_GAME_DATA );
  391. TheWritableGlobalData->m_pendingFile = TheGlobalData->m_shellMapName;
  392. InitGameLogicRandom(0);
  393. GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_NEW_GAME );
  394. msg->appendIntegerArgument(GAME_SHELL);
  395. m_shellMapOn = TRUE;
  396. }
  397. else
  398. {
  399. // we're in a shell game, stop it!
  400. if(TheGameLogic->isInGame() && TheGameLogic->getGameMode() == GAME_SHELL)
  401. TheMessageStream->appendMessage( GameMessage::MSG_CLEAR_GAME_DATA );
  402. // if the shell is active,we need a background
  403. if(!m_isShellActive)
  404. return;
  405. if(!m_background)
  406. m_background = TheWindowManager->winCreateLayout("Menus/BlankWindow.wnd");
  407. DEBUG_ASSERTCRASH(m_background,("We Couldn't Load Menus/BlankWindow.wnd"));
  408. m_background->getFirstWindow()->winSetStatus(WIN_STATUS_IMAGE);
  409. m_background->hide(FALSE);
  410. if (top())
  411. top()->bringForward();
  412. m_shellMapOn = FALSE;
  413. m_clearBackground = FALSE;
  414. }
  415. }
  416. //-------------------------------------------------------------------------------------------------
  417. /** Run the shutdown() function for the top of the stack just like we're going to pop
  418. * it off but DO NOT pop it off the stack. We want this behavior when leaving the
  419. * pre-game menus and entering the game and want the shell to still exist and contain
  420. * the stack information but don't want it to go away */
  421. //-------------------------------------------------------------------------------------------------
  422. void Shell::hideShell( void )
  423. {
  424. // If we have the 3d background running, mark it to close
  425. m_clearBackground = TRUE;
  426. DEBUG_LOG(("Shell:hideShell() - %s\n", (top())?top()->getFilename().str():"no top screen"));
  427. WindowLayout *layout = top();
  428. if( layout )
  429. {
  430. Bool immediatePop = TRUE;
  431. layout->runShutdown( &immediatePop );
  432. } // end if
  433. if (TheIMEManager)
  434. TheIMEManager->detatch();
  435. // Mark that the shell is no longer up.
  436. m_isShellActive = FALSE;
  437. } // end hideShell
  438. //-------------------------------------------------------------------------------------------------
  439. /** Return the top layout on the stack */
  440. //-------------------------------------------------------------------------------------------------
  441. WindowLayout *Shell::top( void )
  442. {
  443. // emtpy stack
  444. if( m_screenCount == 0 )
  445. return NULL;
  446. // top layout is at count index
  447. return m_screenStack[ m_screenCount - 1 ];
  448. } // end top
  449. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////////////////////
  450. //-------------------------------------------------------------------------------------------------
  451. /** Add screen to our list */
  452. //-------------------------------------------------------------------------------------------------
  453. void Shell::linkScreen( WindowLayout *screen )
  454. {
  455. // sanity
  456. if( screen == NULL )
  457. return;
  458. // check to see if at top already
  459. if( m_screenCount == MAX_SHELL_STACK )
  460. {
  461. DEBUG_CRASH(( "No room in shell stack for screen\n" ));
  462. return;
  463. } // end if
  464. // add to array at top index
  465. m_screenStack[ m_screenCount++ ] = screen;
  466. } // end linkScreen
  467. //-------------------------------------------------------------------------------------------------
  468. /** Remove screen from our list */
  469. //-------------------------------------------------------------------------------------------------
  470. void Shell::unlinkScreen( WindowLayout *screen )
  471. {
  472. // sanity
  473. if( screen == NULL )
  474. return;
  475. DEBUG_ASSERTCRASH( m_screenStack[ m_screenCount - 1 ] == screen,
  476. ("Screen not on top of stack\n") );
  477. // remove reference to screen and decrease count
  478. if( m_screenStack[ m_screenCount - 1 ] == screen )
  479. m_screenStack[ --m_screenCount ] = NULL;
  480. } // end unlinkScreen
  481. //-------------------------------------------------------------------------------------------------
  482. /** Actually do the work for a push */
  483. //-------------------------------------------------------------------------------------------------
  484. void Shell::doPush( AsciiString layoutFile )
  485. {
  486. if(TheGameSpyInfo)
  487. GameSpyCloseAllOverlays();
  488. WindowLayout *newScreen;
  489. // create new layout and load from window manager
  490. newScreen = TheWindowManager->winCreateLayout( layoutFile );
  491. DEBUG_ASSERTCRASH( newScreen != NULL, ("Shell unable to load pending push layout\n") );
  492. // link screen to the top
  493. linkScreen( newScreen );
  494. if (TheIMEManager)
  495. TheIMEManager->detatch();
  496. // run the init function automatically
  497. newScreen->runInit( NULL );
  498. newScreen->bringForward();
  499. } // end doPush
  500. //-------------------------------------------------------------------------------------------------
  501. /** Actually do the work for a pop */
  502. //-------------------------------------------------------------------------------------------------
  503. void Shell::doPop( Bool impendingPush )
  504. {
  505. WindowLayout *currentTop = top();
  506. // there better be a top of the stack since we're popping
  507. DEBUG_ASSERTCRASH( currentTop, ("Shell: No top of stack and we want to pop!\n") );
  508. // remove this screen from our list
  509. unlinkScreen( currentTop );
  510. // delete all the windows in the screen
  511. currentTop->destroyWindows();
  512. // release the screen object back to the memory pool
  513. currentTop->deleteInstance();
  514. // run the init for the new top of the stack if present
  515. WindowLayout *newTop = top();
  516. if( newTop && !impendingPush )
  517. {
  518. newTop->runInit( NULL );
  519. //newTop->bringForward();
  520. }
  521. if (TheIMEManager)
  522. TheIMEManager->detatch();
  523. } // end doPop
  524. //-------------------------------------------------------------------------------------------------
  525. /** This is called when a layout has finished its shutdown process. Layouts are
  526. * shutdown when a new screen is being pushed on the stack, or when we are
  527. * popping the current screen off the top of the stack. It is here that we
  528. * can look for any pending push or pop operations and actually do them
  529. *
  530. * NOTE: It is possible for the screen parameter to be NULL when we are
  531. * short circuiting the shutdown logic because there is no layout
  532. * to actually shutdown (ie, the stack is empty and we push) */
  533. //-------------------------------------------------------------------------------------------------
  534. void Shell::shutdownComplete( WindowLayout *screen, Bool impendingPush )
  535. {
  536. // there should never be a pending push AND pop operation
  537. DEBUG_ASSERTCRASH( m_pendingPush == FALSE || m_pendingPop == FALSE,
  538. ("There is a pending push AND pop in the shell. Not allowed!\n") );
  539. // Reset the AnimateWindowManager
  540. m_animateWindowManager->reset();
  541. // check for pending push or pop
  542. if( m_pendingPush )
  543. {
  544. // do the push
  545. doPush( m_pendingPushName );
  546. // no more pending pushy for you!
  547. m_pendingPush = FALSE;
  548. m_pendingPushName.set( "" );
  549. } // end if
  550. else if( m_pendingPop )
  551. {
  552. // do the pop
  553. doPop( impendingPush );
  554. // no more pending pop for you!
  555. m_pendingPop = FALSE;
  556. } // end else if
  557. if(m_clearBackground)
  558. {
  559. if(m_background)
  560. {
  561. m_background->destroyWindows();
  562. m_background->deleteInstance();
  563. m_background = NULL;
  564. m_clearBackground = FALSE;
  565. }
  566. }
  567. } // end shutdownComplete
  568. void Shell::registerWithAnimateManager( GameWindow *win, AnimTypes animType, Bool needsToFinish, UnsignedInt delayMS)
  569. {
  570. if(!m_animateWindowManager)
  571. {
  572. DEBUG_CRASH(("We called registerWithAnimateManager and we don't have an Animate Manager created"));
  573. return;
  574. }
  575. if (TheGlobalData->m_animateWindows)
  576. m_animateWindowManager->registerGameWindow(win,animType,needsToFinish, 500,delayMS);
  577. }
  578. Bool Shell::isAnimFinished( void )
  579. {
  580. // check the new way also.
  581. if (!TheTransitionHandler->isFinished())
  582. return FALSE;
  583. if(!m_animateWindowManager)
  584. {
  585. DEBUG_CRASH(("We called registerWithAnimateManager and we don't have an Animate Manager created"));
  586. return TRUE;
  587. }
  588. if (TheGlobalData->m_animateWindows)
  589. return m_animateWindowManager->isFinished();
  590. else
  591. return TRUE;
  592. }
  593. void Shell::reverseAnimatewindow( void )
  594. {
  595. if(!m_animateWindowManager)
  596. {
  597. DEBUG_CRASH(("We called registerWithAnimateManager and we don't have an Animate Manager created"));
  598. return;
  599. }
  600. if (TheGlobalData->m_animateWindows)
  601. m_animateWindowManager->reverseAnimateWindow();
  602. }
  603. Bool Shell::isAnimReversed( void )
  604. {
  605. if(!m_animateWindowManager)
  606. {
  607. DEBUG_CRASH(("We called registerWithAnimateManager and we don't have an Animate Manager created"));
  608. return TRUE;
  609. }
  610. if (TheGlobalData->m_animateWindows)
  611. return m_animateWindowManager->isReversed();
  612. else
  613. return TRUE;
  614. }
  615. void Shell::loadScheme( AsciiString name )
  616. {
  617. if(!m_schemeManager)
  618. return;
  619. m_schemeManager->setShellMenuScheme( name );
  620. }
  621. // ------------------------------------------------------------------------------------------------
  622. // ------------------------------------------------------------------------------------------------
  623. WindowLayout *Shell::getSaveLoadMenuLayout( void )
  624. {
  625. // if layout has not been created, create it now
  626. if( m_saveLoadMenuLayout == NULL )
  627. m_saveLoadMenuLayout = TheWindowManager->winCreateLayout( AsciiString( "Menus/PopupSaveLoad.wnd" ) );
  628. // sanity
  629. DEBUG_ASSERTCRASH( m_saveLoadMenuLayout, ("Unable to create save/load menu layout\n") );
  630. // return the layout
  631. return m_saveLoadMenuLayout;
  632. } // end getSaveLoadMenuLayout
  633. // ------------------------------------------------------------------------------------------------
  634. // ------------------------------------------------------------------------------------------------
  635. WindowLayout *Shell::getPopupReplayLayout( void )
  636. {
  637. // if layout has not been created, create it now
  638. if( m_popupReplayLayout == NULL )
  639. m_popupReplayLayout = TheWindowManager->winCreateLayout( AsciiString( "Menus/PopupReplay.wnd" ) );
  640. // sanity
  641. DEBUG_ASSERTCRASH( m_popupReplayLayout, ("Unable to create replay save menu layout\n") );
  642. // return the layout
  643. return m_popupReplayLayout;
  644. } // end getSaveLoadMenuLayout
  645. // ------------------------------------------------------------------------------------------------
  646. // ------------------------------------------------------------------------------------------------
  647. WindowLayout *Shell::getOptionsLayout( Bool create )
  648. {
  649. // if layout has not been created, create it now
  650. if ((m_optionsLayout == NULL) && (create == TRUE))
  651. {
  652. m_optionsLayout = TheWindowManager->winCreateLayout( AsciiString( "Menus/OptionsMenu.wnd" ) );
  653. // sanity
  654. DEBUG_ASSERTCRASH( m_optionsLayout, ("Unable to create options menu layout\n") );
  655. }
  656. // return the layout
  657. return m_optionsLayout;
  658. } // end getOptionsLayout
  659. // ------------------------------------------------------------------------------------------------
  660. // ------------------------------------------------------------------------------------------------
  661. void Shell::destroyOptionsLayout() {
  662. if (m_optionsLayout != NULL) {
  663. m_optionsLayout->destroyWindows();
  664. m_optionsLayout->deleteInstance();
  665. m_optionsLayout = NULL;
  666. }
  667. }