Display.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. ** Command & Conquer Generals(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: Display.cpp //////////////////////////////////////////////////////////
  24. // The implementation of the Display class
  25. // Author: Michael S. Booth, March 2001
  26. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  27. #include "GameClient/Display.h"
  28. #include "GameClient/Mouse.h"
  29. #include "GameClient/VideoPlayer.h"
  30. #include "GameClient/DisplayStringManager.h"
  31. #include "GameClient/GameText.h"
  32. #include "GameClient/GlobalLanguage.h"
  33. //#include "GameLogic/ScriptEngine.h"
  34. //#include "GameLogic/GameLogic.h"
  35. /// The Display singleton instance.
  36. Display *TheDisplay = NULL;
  37. Display::Display()
  38. {
  39. m_viewList = NULL;
  40. m_width = 0;
  41. m_height = 0;
  42. m_bitDepth = 0;
  43. m_windowed = FALSE;
  44. m_videoBuffer = NULL;
  45. m_videoStream = NULL;
  46. m_debugDisplayCallback = NULL;
  47. m_debugDisplayUserData = NULL;
  48. m_debugDisplay = NULL;
  49. m_letterBoxFadeLevel = 0;
  50. m_letterBoxEnabled = FALSE;
  51. m_cinematicText = AsciiString::TheEmptyString;
  52. m_cinematicFont = NULL;
  53. m_cinematicTextFrames = 0;
  54. m_movieHoldTime = -1;
  55. m_copyrightHoldTime = -1;
  56. m_elapsedMovieTime = 0;
  57. m_elapsedCopywriteTime = 0;
  58. m_copyrightDisplayString = NULL;
  59. // Added by Sadullah Nader
  60. // Initializations missing and needed
  61. m_currentlyPlayingMovie.clear();
  62. m_letterBoxFadeStartTime = 0;
  63. // End Add
  64. }
  65. /**
  66. * Destructor for the Display. Destroy all views attached to it.
  67. */
  68. Display::~Display()
  69. {
  70. stopMovie();
  71. // delete all our views if present
  72. deleteViews();
  73. }
  74. /**
  75. * Delete all views in the Display
  76. */
  77. void Display::deleteViews( void )
  78. {
  79. View *v, *next;
  80. for( v = m_viewList; v; v = next )
  81. {
  82. next = v->getNextView();
  83. delete v;
  84. }
  85. m_viewList = NULL;
  86. }
  87. /**
  88. * Attach the given view to the world
  89. * @todo Rethink the "attachView" notion...
  90. */
  91. void Display::attachView( View *view )
  92. {
  93. // prepend to head of list
  94. m_viewList = view->prependViewToList( m_viewList );
  95. }
  96. /**
  97. * Render all views of the world
  98. */
  99. void Display::drawViews( void )
  100. {
  101. for( View *v = m_viewList; v; v = v->getNextView() )
  102. v->drawView();
  103. }
  104. /**
  105. * Updates all views of the world. This forces state variables
  106. to refresh without actually drawing anything.
  107. */
  108. void Display::updateViews( void )
  109. {
  110. for( View *v = m_viewList; v; v = v->getNextView() )
  111. v->updateView();
  112. }
  113. /// Redraw the entire display
  114. void Display::draw( void )
  115. {
  116. // redraw all views
  117. drawViews();
  118. // redraw the in-game user interface
  119. /// @todo Switch between in-game and shell interfaces
  120. }
  121. /** Sets screen resolution/mode*/
  122. Bool Display::setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bitdepth, Bool windowed )
  123. {
  124. //Get old values
  125. UnsignedInt oldDisplayHeight=getHeight();
  126. UnsignedInt oldDisplayWidth=getWidth();
  127. Int oldViewWidth=TheTacticalView->getWidth();
  128. Int oldViewHeight=TheTacticalView->getHeight();
  129. Int oldViewOriginX,oldViewOriginY;
  130. TheTacticalView->getOrigin(&oldViewOriginX,&oldViewOriginY);
  131. setWidth(xres);
  132. setHeight(yres);
  133. //Adjust view to match previous proportions
  134. TheTacticalView->setWidth((Real)oldViewWidth/(Real)oldDisplayWidth*(Real)xres);
  135. TheTacticalView->setHeight((Real)oldViewHeight/(Real)oldDisplayHeight*(Real)yres);
  136. TheTacticalView->setOrigin((Real)oldViewOriginX/(Real)oldDisplayWidth*(Real)xres,
  137. (Real)oldViewOriginY/(Real)oldDisplayHeight*(Real)yres);
  138. return TRUE;
  139. }
  140. // Display::setWidth ==========================================================
  141. /** Set the width of the display */
  142. //=============================================================================
  143. void Display::setWidth( UnsignedInt width )
  144. {
  145. // set the new width
  146. m_width = width;
  147. // set the new mouse limits
  148. if( TheMouse )
  149. TheMouse->setMouseLimits();
  150. } // end setWidth
  151. // Display::setHeight =========================================================
  152. /** Set the height of the display */
  153. //=============================================================================
  154. void Display::setHeight( UnsignedInt height )
  155. {
  156. // se the new height
  157. m_height = height;
  158. // set the new mouse limits
  159. if( TheMouse )
  160. TheMouse->setMouseLimits();
  161. } // end setHeight
  162. //============================================================================
  163. // Display::playLogoMovie
  164. // minMovieLength is in milliseconds
  165. // minCopyrightLength
  166. //============================================================================
  167. void Display::playLogoMovie( AsciiString movieName, Int minMovieLength, Int minCopyrightLength )
  168. {
  169. stopMovie();
  170. m_videoStream = TheVideoPlayer->open( movieName );
  171. if ( m_videoStream == NULL )
  172. {
  173. return;
  174. }
  175. m_currentlyPlayingMovie = movieName;
  176. m_movieHoldTime = minMovieLength;
  177. m_copyrightHoldTime = minCopyrightLength;
  178. m_elapsedMovieTime = timeGetTime(); // we're using time get time becuase legal want's actual "Seconds"
  179. m_videoBuffer = createVideoBuffer();
  180. if ( m_videoBuffer == NULL ||
  181. !m_videoBuffer->allocate( m_videoStream->width(),
  182. m_videoStream->height())
  183. )
  184. {
  185. stopMovie();
  186. return;
  187. }
  188. }
  189. //============================================================================
  190. // Display::playMovie
  191. //============================================================================
  192. void Display::playMovie( AsciiString movieName)
  193. {
  194. stopMovie();
  195. m_videoStream = TheVideoPlayer->open( movieName );
  196. if ( m_videoStream == NULL )
  197. {
  198. return;
  199. }
  200. m_currentlyPlayingMovie = movieName;
  201. m_videoBuffer = createVideoBuffer();
  202. if ( m_videoBuffer == NULL ||
  203. !m_videoBuffer->allocate( m_videoStream->width(),
  204. m_videoStream->height())
  205. )
  206. {
  207. stopMovie();
  208. return;
  209. }
  210. }
  211. //============================================================================
  212. // Display::stopMovie
  213. //============================================================================
  214. void Display::stopMovie( void )
  215. {
  216. delete m_videoBuffer;
  217. m_videoBuffer = NULL;
  218. if ( m_videoStream )
  219. {
  220. m_videoStream->close();
  221. m_videoStream = NULL;
  222. }
  223. if (!m_currentlyPlayingMovie.isEmpty()) {
  224. //TheScriptEngine->notifyOfCompletedVideo(m_currentlyPlayingMovie); // Removing this sync-error cause MDC
  225. m_currentlyPlayingMovie = AsciiString::TheEmptyString;
  226. }
  227. if(m_copyrightDisplayString)
  228. {
  229. TheDisplayStringManager->freeDisplayString(m_copyrightDisplayString);
  230. m_copyrightDisplayString = NULL;
  231. }
  232. m_copyrightHoldTime = -1;
  233. m_movieHoldTime = -1;
  234. }
  235. //============================================================================
  236. // Display::update
  237. //============================================================================
  238. void Display::update( void )
  239. {
  240. if ( m_videoStream && m_videoBuffer )
  241. {
  242. if ( m_videoStream->isFrameReady())
  243. {
  244. m_videoStream->frameDecompress();
  245. m_videoStream->frameRender( m_videoBuffer );
  246. if( m_videoStream->frameIndex() != m_videoStream->frameCount() - 1)
  247. m_videoStream->frameNext();
  248. else if( m_copyrightHoldTime >= 0 ||m_movieHoldTime >= 0 )
  249. {
  250. if( m_elapsedCopywriteTime == 0 && m_elapsedCopywriteTime >= 0)
  251. {
  252. //display the copyrighttext;
  253. if(m_copyrightDisplayString)
  254. m_copyrightDisplayString->deleteInstance();
  255. m_copyrightDisplayString = TheDisplayStringManager->newDisplayString();
  256. m_copyrightDisplayString->setText(TheGameText->fetch("GUI:EACopyright"));
  257. if (TheGlobalLanguageData && TheGlobalLanguageData->m_copyrightFont.name.isNotEmpty())
  258. { FontDesc *fontdesc=&TheGlobalLanguageData->m_copyrightFont;
  259. m_copyrightDisplayString->setFont(TheFontLibrary->getFont(fontdesc->name,
  260. TheGlobalLanguageData->adjustFontSize(fontdesc->size),
  261. fontdesc->bold));
  262. }
  263. else
  264. m_copyrightDisplayString->setFont(TheFontLibrary->getFont("Courier",
  265. TheGlobalLanguageData->adjustFontSize(12), TRUE));
  266. m_elapsedCopywriteTime = timeGetTime();
  267. }
  268. if(m_movieHoldTime + m_elapsedMovieTime < timeGetTime() &&
  269. m_copyrightHoldTime + m_elapsedCopywriteTime < timeGetTime())
  270. {
  271. m_movieHoldTime = -1;
  272. m_elapsedMovieTime = 0;
  273. m_elapsedCopywriteTime = 0;
  274. m_copyrightHoldTime = -1;
  275. }
  276. }
  277. else
  278. {
  279. stopMovie();
  280. }
  281. }
  282. }
  283. }
  284. //============================================================================
  285. // Display::reset
  286. //============================================================================
  287. void Display::reset()
  288. {
  289. //Remove letterbox border that may have been enabled by a script
  290. m_letterBoxFadeLevel = 0;
  291. m_letterBoxEnabled = FALSE;
  292. stopMovie();
  293. // Reset all views that need resetting
  294. for( View *v = m_viewList; v; v = v->getNextView() )
  295. v->reset();
  296. }
  297. //============================================================================
  298. // Display::isMoviePlaying
  299. //============================================================================
  300. Bool Display::isMoviePlaying(void)
  301. {
  302. return m_videoStream != NULL && m_videoBuffer != NULL;
  303. }
  304. //============================================================================
  305. // Display::setDebugDisplayCallback
  306. //============================================================================
  307. void Display::setDebugDisplayCallback( DebugDisplayCallback *callback, void *userData )
  308. {
  309. m_debugDisplayCallback = callback;
  310. m_debugDisplayUserData = userData;
  311. }
  312. //============================================================================
  313. // Display::getDebugDisplayCallback
  314. //============================================================================
  315. Display::DebugDisplayCallback *Display::getDebugDisplayCallback()
  316. {
  317. return m_debugDisplayCallback;
  318. }