MCIMOVIE.CPP 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. #include "function.h"
  15. #ifdef MCIMPEG
  16. #include "mcimovie.h"
  17. #include <memory.h>
  18. /****************************************************************************
  19. *
  20. * NAME
  21. * MCIMovie - Constructor
  22. *
  23. * DESCRIPTION
  24. *
  25. * INPUTS
  26. * HInstance - Application instance handle
  27. *
  28. * RESULT
  29. * NONE
  30. *
  31. ****************************************************************************/
  32. MCIMovie::MCIMovie(HWND mainWindow)
  33. : mMainWindow(mainWindow), mMCIWindow(NULL), mName(NULL), mDeviceID(0)
  34. {
  35. mWidth = mHeight = 0;
  36. }
  37. /****************************************************************************
  38. *
  39. * NAME
  40. * ~MCIMovie - Destructor
  41. *
  42. * DESCRIPTION
  43. *
  44. * INPUTS
  45. *
  46. * RESULT
  47. *
  48. ****************************************************************************/
  49. MCIMovie::~MCIMovie()
  50. {
  51. // Stop any playing movie
  52. Close();
  53. // Free name
  54. if (mName != NULL)
  55. free(mName);
  56. }
  57. /****************************************************************************
  58. *
  59. * NAME
  60. * Open()
  61. *
  62. * DESCRIPTION
  63. * Open the media file in preparation for playback.
  64. *
  65. * INPUTS
  66. * NONE
  67. *
  68. * RESULT
  69. * Success - Success/Failure flag
  70. *
  71. ****************************************************************************/
  72. bool MCIMovie::Open(const char* name, const char* device)
  73. {
  74. MCIERROR rc;
  75. MCI_DGV_RECT_PARMS rectParm;
  76. MCI_BREAK_PARMS breakParm;
  77. // Stop any currently playing movie
  78. Close();
  79. // Copy the movie name for our use
  80. if (mName != NULL)
  81. free(mName);
  82. mName = strdup(name);
  83. if (device == NULL)
  84. device = "mpegvideo";
  85. // Setup open parameters
  86. memset((void*)&mOpenParm, 0, sizeof(mOpenParm));
  87. mOpenParm.dwCallback = NULL;
  88. mOpenParm.lpstrDeviceType = device;
  89. mOpenParm.lpstrElementName = name;
  90. rc = mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE |
  91. MCI_OPEN_ELEMENT, (DWORD)&mOpenParm);
  92. if (rc)
  93. {
  94. char buffer[512];
  95. mciGetErrorString(rc, buffer, 512);
  96. return false;
  97. }
  98. // Set device ID
  99. mDeviceID = mOpenParm.wDeviceID;
  100. // Retrieve movie dimensions
  101. rectParm.dwCallback = NULL;
  102. rc = mciSendCommand(mDeviceID, MCI_WHERE, MCI_WAIT | MCI_DGV_WHERE_SOURCE,
  103. (DWORD)&rectParm);
  104. if (rc)
  105. {
  106. char buffer[512];
  107. mciGetErrorString(rc, buffer, 512);
  108. return false;
  109. }
  110. mWidth = rectParm.rc.right - rectParm.rc.left;
  111. mHeight = rectParm.rc.bottom - rectParm.rc.top;
  112. // Set break key to escape
  113. breakParm.dwCallback = NULL;
  114. breakParm.nVirtKey = VK_ESCAPE;
  115. breakParm.hwndBreak = mMainWindow;
  116. rc = mciSendCommand(mDeviceID, MCI_BREAK, MCI_WAIT | MCI_BREAK_HWND |
  117. MCI_BREAK_KEY, (DWORD)&breakParm);
  118. if (rc)
  119. {
  120. char buffer[512];
  121. mciGetErrorString(rc, buffer, 512);
  122. }
  123. return true;
  124. }
  125. /****************************************************************************
  126. *
  127. * NAME
  128. * Play - Play the specified movie.
  129. *
  130. * DESCRIPTION
  131. *
  132. * INPUTS
  133. *
  134. * RESULT
  135. * Success - Success/Failure flag
  136. *
  137. ****************************************************************************/
  138. bool MCIMovie::Play(HWND window)
  139. {
  140. MCIERROR rc;
  141. if (mDeviceID == 0)
  142. return false;
  143. // Provide window for playback
  144. if (AttachWindow(window))
  145. {
  146. // Size the video area
  147. if (SizeDestination())
  148. {
  149. // Start playing
  150. memset((void*)&mPlayParm, 0, sizeof(mPlayParm));
  151. mPlayParm.dwCallback = NULL;
  152. rc = mciSendCommand(mDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)&mPlayParm);
  153. if (rc)
  154. {
  155. char buffer[512];
  156. mciGetErrorString(rc, buffer, 512);
  157. return false;
  158. }
  159. Close();
  160. }
  161. }
  162. return true;
  163. }
  164. /****************************************************************************
  165. *
  166. * NAME
  167. * Pause
  168. *
  169. * DESCRIPTION
  170. *
  171. * INPUTS
  172. *
  173. * RESULT
  174. * Success - Success/Failure flag
  175. *
  176. ****************************************************************************/
  177. bool MCIMovie::Pause(void)
  178. {
  179. if (mDeviceID == 0)
  180. return false;
  181. if (mciSendCommand(mDeviceID, MCI_PAUSE, 0, (DWORD)NULL))
  182. return false;
  183. return true;
  184. }
  185. /****************************************************************************
  186. *
  187. * NAME
  188. * Stop
  189. *
  190. * DESCRIPTION
  191. *
  192. * INPUTS
  193. *
  194. * RESULT
  195. * Success - Success/Failure flag
  196. *
  197. ****************************************************************************/
  198. bool MCIMovie::Close(void)
  199. {
  200. MCIERROR rc;
  201. if (mDeviceID == 0)
  202. return false;
  203. rc = mciSendCommand(mDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
  204. mDeviceID = 0;
  205. if (rc)
  206. {
  207. char buffer[512];
  208. mciGetErrorString(rc, buffer, 512);
  209. return false;
  210. }
  211. return true;
  212. }
  213. /****************************************************************************
  214. *
  215. * NAME
  216. * SizeDestination
  217. *
  218. * DESCRIPTION
  219. *
  220. * INPUTS
  221. *
  222. * RESULT
  223. *
  224. ****************************************************************************/
  225. bool MCIMovie::SizeDestination(void)
  226. {
  227. MCIERROR rc;
  228. MCI_DGV_PUT_PARMS putParm;
  229. RECT rect;
  230. if (mMCIWindow == NULL)
  231. return false;
  232. GetClientRect(mMCIWindow, &rect);
  233. ClientToScreen(mMCIWindow, (LPPOINT)&rect);
  234. ClientToScreen(mMCIWindow, (LPPOINT)&rect + 1);
  235. putParm.dwCallback = NULL;
  236. putParm.rc.left = rect.left;
  237. putParm.rc.top = rect.top;
  238. putParm.rc.right = rect.right;
  239. putParm.rc.bottom = rect.bottom;
  240. rc = mciSendCommand(mDeviceID, MCI_PUT, MCI_WAIT | MCI_DGV_RECT |
  241. MCI_DGV_PUT_DESTINATION, (DWORD)&putParm);
  242. if (rc)
  243. {
  244. char buffer[512];
  245. mciGetErrorString(rc, buffer, 512);
  246. return false;
  247. }
  248. return true;
  249. }
  250. /****************************************************************************
  251. *
  252. * NAME
  253. * AttachWindow
  254. *
  255. * DESCRIPTION
  256. *
  257. * INPUTS
  258. *
  259. * RESULT
  260. *
  261. ****************************************************************************/
  262. bool MCIMovie::AttachWindow(HWND window)
  263. {
  264. MCIERROR rc;
  265. MCI_DGV_WINDOW_PARMS winParm;
  266. mMCIWindow = window;
  267. memset((void*)&winParm, 0, sizeof(winParm));
  268. winParm.dwCallback = NULL;
  269. winParm.hWnd = window;
  270. winParm.nCmdShow = SW_SHOW;
  271. rc = mciSendCommand(mDeviceID, MCI_WINDOW, MCI_WAIT| MCI_DGV_WINDOW_HWND |
  272. MCI_DGV_WINDOW_STATE, (DWORD)&winParm);
  273. if (rc)
  274. {
  275. char buffer[512];
  276. mciGetErrorString(rc, buffer, 512);
  277. return false;
  278. }
  279. return true;
  280. }
  281. #endif // MCIMPEG