subtitlemanager.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. ** Command & Conquer Renegade(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. * FILE
  21. * $Archive: /Commando/Code/BinkMovie/subtitlemanager.cpp $
  22. *
  23. * DESCRIPTION
  24. * Subtitling manager
  25. *
  26. * PROGRAMMER
  27. * Denzil E. Long, Jr.
  28. *
  29. * VERSION INFO
  30. * $Author: Denzil_l $
  31. * $Modtime: 1/24/02 10:11a $
  32. * $Revision: 3 $
  33. *
  34. ****************************************************************************/
  35. #include "always.h"
  36. #include "subtitlemanager.h"
  37. #include "subtitleparser.h"
  38. #include "subtitle.h"
  39. #include "xstraw.h"
  40. #include "rawfile.h"
  41. #include "assetmgr.h"
  42. #include "ww3d.h"
  43. #include <stdlib.h>
  44. /******************************************************************************
  45. *
  46. * NAME
  47. * SubTitleManagerClass::Create
  48. *
  49. * DESCRIPTION
  50. * Instantiate a subtitle manager for the specified movie.
  51. *
  52. * INPUTS
  53. * Filename - Name of movie file to create subtitle manager for.
  54. *
  55. * RESULTS
  56. * NONE
  57. *
  58. ******************************************************************************/
  59. SubTitleManagerClass* SubTitleManagerClass::Create(const char* filename, const char* subtitlefilename, FontCharsClass* font)
  60. {
  61. if ((filename == NULL) || (strlen(filename) == 0)) {
  62. return NULL;
  63. }
  64. if (subtitlefilename && !font) {
  65. return NULL;
  66. }
  67. // Create subtitle manager for the vqa
  68. SubTitleManagerClass* instance = new SubTitleManagerClass();
  69. WWASSERT(instance != NULL);
  70. if (instance != NULL) {
  71. instance->Set_Font(font);
  72. // Retrieve moviename
  73. char fname[_MAX_FNAME];
  74. _splitpath(filename, NULL, NULL, fname, NULL);
  75. bool loaded = instance->Load_Sub_Titles(fname, subtitlefilename);
  76. if (loaded == false) {
  77. delete instance;
  78. return NULL;
  79. }
  80. }
  81. return instance;
  82. }
  83. /******************************************************************************
  84. *
  85. * NAME
  86. * SubTitleManagerClass::SubTitleManagerClass
  87. *
  88. * DESCRIPTION
  89. *
  90. * INPUTS
  91. *
  92. * RESULTS
  93. * NONE
  94. *
  95. ******************************************************************************/
  96. SubTitleManagerClass::SubTitleManagerClass()
  97. :
  98. mSubTitles(NULL),
  99. mSubTitleIndex(0),
  100. mActiveSubTitle(NULL)
  101. {
  102. }
  103. /******************************************************************************
  104. *
  105. * NAME
  106. * SubTitleManagerClass::~SubTitleManagerClass
  107. *
  108. * DESCRIPTION
  109. *
  110. * INPUTS
  111. * NONE
  112. *
  113. * RESULTS
  114. * NONE
  115. *
  116. ******************************************************************************/
  117. SubTitleManagerClass::~SubTitleManagerClass()
  118. {
  119. // Release subtitle entries
  120. if (mSubTitles != NULL) {
  121. for (int index = 0; index < mSubTitles->Count(); index++) {
  122. delete (*mSubTitles)[index];
  123. }
  124. delete mSubTitles;
  125. }
  126. }
  127. void SubTitleManagerClass::Set_Font(FontCharsClass* font)
  128. {
  129. if (font) {
  130. Renderer.Set_Font(font);
  131. }
  132. }
  133. /******************************************************************************
  134. *
  135. * NAME
  136. * SubTitleManagerClass::LoadSubTitles
  137. *
  138. * DESCRIPTION
  139. *
  140. * INPUTS
  141. * Moviename - Pointer to movie name
  142. *
  143. * RESULTS
  144. * Success -
  145. *
  146. ******************************************************************************/
  147. bool SubTitleManagerClass::Load_Sub_Titles(const char* moviename, const char* subtitlefilename)
  148. {
  149. if ((moviename == NULL) || (strlen(moviename) == 0)) {
  150. return false;
  151. }
  152. if ((subtitlefilename == NULL) || (strlen(subtitlefilename) == 0)) {
  153. return false;
  154. }
  155. RawFileClass file(subtitlefilename);
  156. if (!file.Is_Available()) {
  157. return false;
  158. }
  159. FileStraw input(file);
  160. SubTitleParserClass parser(input);
  161. mSubTitles = parser.Get_Sub_Titles(moviename);
  162. if (mSubTitles == NULL) {
  163. return false;
  164. }
  165. // TODO: Make sure entries are sorted by time.
  166. return true;
  167. }
  168. /******************************************************************************
  169. *
  170. * NAME
  171. * SubTitleManagerClass::Process
  172. *
  173. * DESCRIPTION
  174. * Handle subtitle processing. This must be called each frame advance.
  175. *
  176. * INPUTS
  177. * NONE
  178. *
  179. * RESULTS
  180. * NONE
  181. *
  182. ******************************************************************************/
  183. bool SubTitleManagerClass::Process(unsigned long movieTime)
  184. {
  185. if (mSubTitles == NULL) {
  186. return false;
  187. }
  188. bool update = false;
  189. for (;;) {
  190. // Terminate if there aren't more subtitles
  191. if (mSubTitleIndex >= mSubTitles->Count()) {
  192. break;
  193. }
  194. // Get the next subtitle
  195. SubTitleClass* subtitle = (*mSubTitles)[mSubTitleIndex];
  196. WWASSERT(subtitle != NULL);
  197. // Check the display time against the current movie time. If it is time
  198. // to display the subtitle then send a subtitle event to the client.
  199. unsigned long displayTime = subtitle->Get_Display_Time();
  200. // If its not time then we are done.
  201. if (displayTime > movieTime) {
  202. break;
  203. } else {
  204. // Make this subtitle the active one
  205. mActiveSubTitle = subtitle;
  206. // Advance to the next subtitle entry
  207. mSubTitleIndex++;
  208. Draw_Sub_Title(subtitle);
  209. update = true;
  210. // WWDEBUG_SAY(("SubTitle: %04d @ %u\n", mSubTitleIndex, movieTime));
  211. }
  212. }
  213. // If the active subtitles duration has expired then remove it as being active.
  214. if (mActiveSubTitle != NULL) {
  215. SubTitleClass* subtitle = mActiveSubTitle;
  216. unsigned long expireTime = subtitle->Get_Display_Time() + subtitle->Get_Display_Duration();
  217. if (movieTime >= expireTime) {
  218. mActiveSubTitle = NULL;
  219. // Erase subtitle
  220. Renderer.Reset();
  221. update = true;
  222. }
  223. }
  224. return update;
  225. }
  226. /******************************************************************************
  227. *
  228. * NAME
  229. * SubTitleManagerClass::Reset
  230. *
  231. * DESCRIPTION
  232. *
  233. * INPUTS
  234. * NONE
  235. *
  236. * RESULTS
  237. * NONE
  238. *
  239. ******************************************************************************/
  240. void SubTitleManagerClass::Reset(void)
  241. {
  242. mSubTitleIndex = 0;
  243. mActiveSubTitle = NULL;
  244. }
  245. /******************************************************************************
  246. *
  247. * NAME
  248. * SubTitleManagerClass::DrawSubTitle
  249. *
  250. * DESCRIPTION
  251. *
  252. * INPUTS
  253. * const SubTitleClass* subtitle
  254. *
  255. * RESULTS
  256. * NONE
  257. *
  258. ******************************************************************************/
  259. void SubTitleManagerClass::Draw_Sub_Title(const SubTitleClass* subtitle)
  260. {
  261. WWASSERT(subtitle != NULL);
  262. Renderer.Reset();
  263. unsigned short* string = (unsigned short*)subtitle->Get_Caption();
  264. int w,h,bits;
  265. bool windowed;
  266. WW3D::Get_Device_Resolution(w,h,bits,windowed);
  267. Vector2 extents=Renderer.Get_Text_Extents( string );
  268. // Assume left justification
  269. int xPos = 0;
  270. int yPos = subtitle->Get_Line_Position() * (h/16);
  271. int xSize=extents[0];
  272. SubTitleClass::Alignment align = subtitle->Get_Alignment();
  273. if (align == SubTitleClass::Center) {
  274. xPos = ((w - xSize) / 2);
  275. }
  276. else if (align == SubTitleClass::Right) {
  277. xPos = (w - xSize);
  278. }
  279. Renderer.Set_Location(Vector2(xPos,yPos));
  280. Renderer.Build_Sentence(string);
  281. // Set font color
  282. unsigned long rgbColor = subtitle->Get_RGB_Color()|0xff000000;
  283. Renderer.Draw_Sentence(rgbColor);
  284. }
  285. void SubTitleManagerClass::Render()
  286. {
  287. Renderer.Render();
  288. }