GameWindowTransitions.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  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: GameWindowTransitions.cpp /////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Electronic Arts Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2002 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // created: Dec 2002
  34. //
  35. // Filename: GameWindowTransitions.cpp
  36. //
  37. // author: Chris Huybregts
  38. //
  39. // purpose:
  40. //
  41. //-----------------------------------------------------------------------------
  42. ///////////////////////////////////////////////////////////////////////////////
  43. //-----------------------------------------------------------------------------
  44. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  45. //-----------------------------------------------------------------------------
  46. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  47. #ifdef _INTERNAL
  48. // for occasional debugging...
  49. //#pragma optimize("", off)
  50. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  51. #endif
  52. //-----------------------------------------------------------------------------
  53. // USER INCLUDES //////////////////////////////////////////////////////////////
  54. //-----------------------------------------------------------------------------
  55. #include "Gamelogic/GameLogic.h"
  56. #include "GameClient/GameWindowTransitions.h"
  57. #include "GameClient/GameWindow.h"
  58. #include "GameClient/GameWindowManager.h"
  59. //-----------------------------------------------------------------------------
  60. // DEFINES ////////////////////////////////////////////////////////////////////
  61. //-----------------------------------------------------------------------------
  62. GameWindowTransitionsHandler *TheTransitionHandler = NULL;
  63. const FieldParse GameWindowTransitionsHandler::m_gameWindowTransitionsFieldParseTable[] =
  64. {
  65. { "Window", GameWindowTransitionsHandler::parseWindow, NULL, NULL },
  66. { "FireOnce", INI::parseBool, NULL, offsetof( TransitionGroup, m_fireOnce) },
  67. { NULL, NULL, NULL, 0 } // keep this last
  68. };
  69. void INI::parseWindowTransitions( INI* ini )
  70. {
  71. AsciiString name;
  72. TransitionGroup *g;
  73. // read the name
  74. const char* c = ini->getNextToken();
  75. name.set( c );
  76. // find existing item if present
  77. DEBUG_ASSERTCRASH( TheTransitionHandler, ("parseWindowTransitions: TheTransitionHandler doesn't exist yet\n") );
  78. if( !TheTransitionHandler )
  79. return;
  80. // If we have a previously allocated control bar, this will return a cleared out pointer to it so we
  81. // can overwrite it
  82. g = TheTransitionHandler->getNewGroup( name );
  83. // sanity
  84. DEBUG_ASSERTCRASH( g, ("parseWindowTransitions: Unable to allocate group '%s'\n", name.str()) );
  85. // parse the ini definition
  86. ini->initFromINI( g, TheTransitionHandler->getFieldParse() );
  87. }
  88. //-----------------------------------------------------------------------------
  89. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  90. //-----------------------------------------------------------------------------
  91. Transition *getTransitionForStyle( Int style )
  92. {
  93. switch (style) {
  94. case TRANSITION_FLASH:
  95. return NEW FlashTransition;
  96. case BUTTON_TRANSITION_FLASH:
  97. return NEW ButtonFlashTransition;
  98. case WIN_FADE_TRANSITION:
  99. return NEW FadeTransition;
  100. case WIN_SCALE_UP_TRANSITION:
  101. return NEW ScaleUpTransition;
  102. case MAINMENU_SCALE_UP_TRANSITION:
  103. return NEW MainMenuScaleUpTransition;
  104. case TEXT_TYPE_TRANSITION:
  105. return NEW TextTypeTransition;
  106. case SCREEN_FADE_TRANSITION:
  107. return NEW ScreenFadeTransition;
  108. case COUNT_UP_TRANSITION:
  109. return NEW CountUpTransition;
  110. case FULL_FADE_TRANSITION:
  111. return NEW FullFadeTransition;
  112. case TEXT_ON_FRAME_TRANSITION:
  113. return NEW TextOnFrameTransition;
  114. case REVERSE_SOUND_TRANSITION:
  115. return NEW ReverseSoundTransition;
  116. case MAINMENU_MEDIUM_SCALE_UP_TRANSITION:
  117. return NEW MainMenuMediumScaleUpTransition;
  118. case MAINMENU_SMALL_SCALE_DOWN_TRANSITION:
  119. return NEW MainMenuSmallScaleDownTransition;
  120. case CONTROL_BAR_ARROW_TRANSITION:
  121. return NEW ControlBarArrowTransition;
  122. case SCORE_SCALE_UP_TRANSITION:
  123. return NEW ScoreScaleUpTransition;
  124. default:
  125. DEBUG_ASSERTCRASH(FALSE, ("getTransitionForStyle:: An invalid style was passed in. Style = %d", style));
  126. return NULL;
  127. }
  128. return NULL;
  129. }
  130. TransitionWindow::TransitionWindow( void )
  131. {
  132. m_currentFrameDelay = m_frameDelay = 0;
  133. m_style = 0;
  134. m_winID = NAMEKEY_INVALID;
  135. m_win = NULL;
  136. m_transition = NULL;
  137. }
  138. TransitionWindow::~TransitionWindow( void )
  139. {
  140. m_win = NULL;
  141. if(m_transition)
  142. delete m_transition;
  143. m_transition = NULL;
  144. }
  145. Bool TransitionWindow::init( void )
  146. {
  147. m_winID = TheNameKeyGenerator->nameToKey(m_winName);
  148. m_win = TheWindowManager->winGetWindowFromId(NULL, m_winID);
  149. m_currentFrameDelay = m_frameDelay;
  150. // DEBUG_ASSERTCRASH( m_win, ("TransitionWindow::init Failed to find window %s", m_winName.str()));
  151. // if( !m_win )
  152. // return FALSE;
  153. if(m_transition)
  154. delete m_transition;
  155. m_transition = getTransitionForStyle( m_style );
  156. m_transition->init(m_win);
  157. return TRUE;
  158. }
  159. void TransitionWindow::update( Int frame )
  160. {
  161. if(frame < m_currentFrameDelay || frame > (m_currentFrameDelay + m_transition->getFrameLength()))
  162. return;
  163. if(m_transition)
  164. m_transition->update( frame - m_currentFrameDelay);
  165. }
  166. Bool TransitionWindow::isFinished( void )
  167. {
  168. if(m_transition)
  169. return m_transition->isFinished();
  170. return TRUE;
  171. }
  172. void TransitionWindow::reverse( Int totalFrames )
  173. {
  174. //m_currentFrameDelay = totalFrames - (m_transition->getFrameLength() + m_frameDelay);
  175. if(m_transition)
  176. m_transition->reverse();
  177. }
  178. void TransitionWindow::skip( void )
  179. {
  180. if(m_transition)
  181. m_transition->skip();
  182. }
  183. void TransitionWindow::draw( void )
  184. {
  185. if(m_transition)
  186. m_transition->draw();
  187. }
  188. Int TransitionWindow::getTotalFrames( void )
  189. {
  190. if(m_transition)
  191. {
  192. return m_frameDelay + m_transition->getFrameLength();
  193. }
  194. return m_frameDelay;
  195. }
  196. //-----------------------------------------------------------------------------
  197. TransitionGroup::TransitionGroup( void )
  198. {
  199. m_currentFrame = 0;
  200. m_fireOnce = FALSE;
  201. }
  202. TransitionGroup::~TransitionGroup( void )
  203. {
  204. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  205. while (it != m_transitionWindowList.end())
  206. {
  207. TransitionWindow *tWin = *it;
  208. delete tWin;
  209. tWin = NULL;
  210. it = m_transitionWindowList.erase(it);
  211. }
  212. }
  213. void TransitionGroup::init( void )
  214. {
  215. m_currentFrame = 0;
  216. m_directionMultiplier = 1;
  217. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  218. while (it != m_transitionWindowList.end())
  219. {
  220. TransitionWindow *tWin = *it;
  221. tWin->init();
  222. it++;
  223. }
  224. }
  225. void TransitionGroup::update( void )
  226. {
  227. m_currentFrame += m_directionMultiplier; // we go forward or backwards depending.
  228. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  229. while (it != m_transitionWindowList.end())
  230. {
  231. TransitionWindow *tWin = *it;
  232. tWin->update(m_currentFrame);
  233. it++;
  234. }
  235. }
  236. Bool TransitionGroup::isFinished( void )
  237. {
  238. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  239. while (it != m_transitionWindowList.end())
  240. {
  241. TransitionWindow *tWin = *it;
  242. if(tWin->isFinished() == FALSE)
  243. return FALSE;
  244. it++;
  245. }
  246. return TRUE;
  247. }
  248. void TransitionGroup::reverse( void )
  249. {
  250. Int totalFrames =0;
  251. m_directionMultiplier = -1;
  252. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  253. while (it != m_transitionWindowList.end())
  254. {
  255. TransitionWindow *tWin = *it;
  256. Int winFrames = tWin->getTotalFrames();
  257. if(winFrames > totalFrames)
  258. totalFrames = winFrames;
  259. it++;
  260. }
  261. it = m_transitionWindowList.begin();
  262. while (it != m_transitionWindowList.end())
  263. {
  264. TransitionWindow *tWin = *it;
  265. tWin->reverse(totalFrames);
  266. it++;
  267. }
  268. m_currentFrame = totalFrames;
  269. // m_currentFrame ++;
  270. }
  271. Bool TransitionGroup::isReversed( void )
  272. {
  273. if(m_directionMultiplier < 0)
  274. return TRUE;
  275. return FALSE;
  276. }
  277. void TransitionGroup::skip ( void )
  278. {
  279. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  280. while (it != m_transitionWindowList.end())
  281. {
  282. TransitionWindow *tWin = *it;
  283. tWin->skip();
  284. it++;
  285. }
  286. }
  287. void TransitionGroup::draw ( void )
  288. {
  289. TransitionWindowList::iterator it = m_transitionWindowList.begin();
  290. while (it != m_transitionWindowList.end())
  291. {
  292. TransitionWindow *tWin = *it;
  293. tWin->draw();
  294. it++;
  295. }
  296. }
  297. void TransitionGroup::addWindow( TransitionWindow *transWin )
  298. {
  299. if(!transWin)
  300. return;
  301. m_transitionWindowList.push_back(transWin);
  302. }
  303. //-----------------------------------------------------------------------------
  304. GameWindowTransitionsHandler::GameWindowTransitionsHandler(void)
  305. {
  306. m_currentGroup = NULL;
  307. m_pendingGroup = NULL;
  308. m_drawGroup = NULL;
  309. m_secondaryDrawGroup = NULL;
  310. }
  311. GameWindowTransitionsHandler::~GameWindowTransitionsHandler( void )
  312. {
  313. m_currentGroup = NULL;
  314. m_pendingGroup = NULL;
  315. m_drawGroup = NULL;
  316. m_secondaryDrawGroup = NULL;
  317. TransitionGroupList::iterator it = m_transitionGroupList.begin();
  318. while( it != m_transitionGroupList.end() )
  319. {
  320. TransitionGroup *g = *it;
  321. delete g;
  322. it = m_transitionGroupList.erase(it);
  323. }
  324. }
  325. void GameWindowTransitionsHandler::init(void )
  326. {
  327. m_currentGroup = NULL;
  328. m_pendingGroup = NULL;
  329. m_drawGroup = NULL;
  330. m_secondaryDrawGroup = NULL;
  331. }
  332. void GameWindowTransitionsHandler::load(void )
  333. {
  334. INI ini;
  335. // Read from INI all the ControlBarSchemes
  336. ini.load( AsciiString( "Data\\INI\\WindowTransitions.ini" ), INI_LOAD_OVERWRITE, NULL );
  337. }
  338. void GameWindowTransitionsHandler::reset( void )
  339. {
  340. m_currentGroup = NULL;
  341. m_pendingGroup = NULL;
  342. m_drawGroup = NULL;
  343. m_secondaryDrawGroup = NULL;
  344. }
  345. void GameWindowTransitionsHandler::update( void )
  346. {
  347. if(m_drawGroup != m_currentGroup)
  348. m_secondaryDrawGroup = m_drawGroup;
  349. else
  350. m_secondaryDrawGroup = NULL;
  351. m_drawGroup = m_currentGroup;
  352. if(m_currentGroup && !m_currentGroup->isFinished())
  353. m_currentGroup->update();
  354. if(m_currentGroup && m_currentGroup->isFinished() && m_currentGroup->isFireOnce())
  355. {
  356. m_currentGroup = NULL;
  357. }
  358. if(m_currentGroup && m_pendingGroup && m_currentGroup->isFinished())
  359. {
  360. m_currentGroup = m_pendingGroup;
  361. m_pendingGroup = NULL;
  362. }
  363. if(!m_currentGroup && m_pendingGroup)
  364. {
  365. m_currentGroup = m_pendingGroup;
  366. m_pendingGroup = NULL;
  367. }
  368. if(m_currentGroup && m_currentGroup->isFinished() && m_currentGroup->isReversed())
  369. m_currentGroup = NULL;
  370. }
  371. void GameWindowTransitionsHandler::draw( void )
  372. {
  373. // if( TheGameLogic->getFrame() > 0 )//if( areTransitionsEnabled() ) //KRIS
  374. if(m_drawGroup)
  375. m_drawGroup->draw();
  376. if(m_secondaryDrawGroup)
  377. m_secondaryDrawGroup->draw();
  378. }
  379. void GameWindowTransitionsHandler::setGroup(AsciiString groupName, Bool immidiate )
  380. {
  381. if(groupName.isEmpty() && immidiate)
  382. m_currentGroup = NULL;
  383. if(immidiate && m_currentGroup)
  384. {
  385. m_currentGroup->skip();
  386. m_currentGroup = findGroup(groupName);
  387. if(m_currentGroup)
  388. m_currentGroup->init();
  389. return;
  390. }
  391. if(m_currentGroup)
  392. {
  393. if(!m_currentGroup->isFireOnce() && !m_currentGroup->isReversed())
  394. m_currentGroup->reverse();
  395. m_pendingGroup = findGroup(groupName);
  396. if(m_pendingGroup)
  397. m_pendingGroup->init();
  398. return;
  399. }
  400. m_currentGroup = findGroup(groupName);
  401. if(m_currentGroup)
  402. m_currentGroup->init();
  403. }
  404. void GameWindowTransitionsHandler::reverse( AsciiString groupName )
  405. {
  406. TransitionGroup *g = findGroup(groupName);
  407. if( m_currentGroup == g )
  408. {
  409. m_currentGroup->reverse();
  410. return;
  411. }
  412. if( m_pendingGroup == g)
  413. {
  414. m_pendingGroup = NULL;
  415. return;
  416. }
  417. if(m_currentGroup)
  418. m_currentGroup->skip();
  419. if(m_pendingGroup)
  420. m_pendingGroup->skip();
  421. m_currentGroup = g;
  422. m_currentGroup->init();
  423. m_currentGroup->skip();
  424. m_currentGroup->reverse();
  425. m_pendingGroup = NULL;
  426. }
  427. void GameWindowTransitionsHandler::remove( AsciiString groupName, Bool skipPending )
  428. {
  429. TransitionGroup *g = findGroup(groupName);
  430. if(m_pendingGroup == g)
  431. {
  432. if(skipPending)
  433. m_pendingGroup->skip();
  434. m_pendingGroup = NULL;
  435. }
  436. if(m_currentGroup == g)
  437. {
  438. m_currentGroup->skip();
  439. m_currentGroup = NULL;
  440. if(m_pendingGroup)
  441. m_currentGroup = m_pendingGroup;
  442. }
  443. }
  444. TransitionGroup *GameWindowTransitionsHandler::getNewGroup( AsciiString name )
  445. {
  446. if(name.isEmpty())
  447. return NULL;
  448. // test to see if we're trying to add an already exisitng group.
  449. if(findGroup(name))
  450. {
  451. DEBUG_ASSERTCRASH(FALSE, ("GameWindowTransitionsHandler::getNewGroup - We already have a group %s", name.str()));
  452. return NULL;
  453. }
  454. TransitionGroup *g = NEW TransitionGroup;
  455. g->setName(name);
  456. m_transitionGroupList.push_back(g);
  457. return g;
  458. }
  459. Bool GameWindowTransitionsHandler::isFinished( void )
  460. {
  461. if(m_currentGroup)
  462. return m_currentGroup->isFinished();
  463. return TRUE;
  464. }
  465. //-----------------------------------------------------------------------------
  466. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  467. //-----------------------------------------------------------------------------
  468. TransitionGroup *GameWindowTransitionsHandler::findGroup( AsciiString groupName )
  469. {
  470. if(groupName.isEmpty())
  471. return NULL;
  472. TransitionGroupList::iterator it = m_transitionGroupList.begin();
  473. while( it != m_transitionGroupList.end() )
  474. {
  475. TransitionGroup *g = *it;
  476. if(groupName.compareNoCase(g->getName()) == 0)
  477. return g;
  478. it++;
  479. }
  480. return NULL;
  481. }
  482. void GameWindowTransitionsHandler::parseWindow( INI* ini, void *instance, void *store, const void *userData )
  483. {
  484. static const FieldParse myFieldParse[] =
  485. {
  486. { "WinName", INI::parseAsciiString, NULL, offsetof( TransitionWindow, m_winName ) },
  487. { "Style", INI::parseLookupList, TransitionStyleNames, offsetof( TransitionWindow, m_style ) },
  488. { "FrameDelay", INI::parseInt, NULL, offsetof( TransitionWindow, m_frameDelay ) },
  489. { NULL, NULL, NULL, 0 } // keep this last
  490. };
  491. TransitionWindow *transWin = NEW TransitionWindow;
  492. ini->initFromINI(transWin, myFieldParse);
  493. ((TransitionGroup*)instance)->addWindow(transWin);
  494. }