MPGSET.CPP 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /*
  2. ** Command & Conquer Red Alert(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. * MpgSet.cpp
  22. *
  23. * DESCRIPTION
  24. * Mpeg movie settings manager
  25. *
  26. * PROGRAMMER
  27. * Denzil E. Long, Jr.
  28. *
  29. * DATE
  30. * June 30, 1998
  31. *
  32. ****************************************************************************/
  33. #include "function.h"
  34. #ifdef DVD
  35. #include "mpgset.h"
  36. #ifdef MCIMPEG
  37. bool EnumMCI(MCIDevice* desc, void* context);
  38. #endif
  39. /****************************************************************************
  40. *
  41. * NAME
  42. * MPGSettings(DeviceName)
  43. *
  44. * DESCRIPTION
  45. * Default constructor
  46. *
  47. * INPUTS
  48. * DeviceName - Initial device to use for MPG playback (NULL = DXMedia)
  49. *
  50. * RESULT
  51. * NONE
  52. *
  53. ****************************************************************************/
  54. MPGSettings::MPGSettings(const char* deviceName)
  55. : mDeviceName(NULL)
  56. {
  57. SetDeviceName(deviceName);
  58. #ifdef MCIMPEG
  59. int count = mMCI.GetDeviceCount();
  60. mMCIDevices = NULL;
  61. mCount = 0;
  62. if (count)
  63. {
  64. mMCIDevices = new MCIDevice[count];
  65. if (mMCIDevices)
  66. {
  67. mMCI.EnumerateDevices(EnumMCI, this);
  68. }
  69. }
  70. #endif
  71. }
  72. MPGSettings::MPGSettings(FileClass& file)
  73. : mDeviceName(NULL)
  74. {
  75. INIClass ini;
  76. char buffer[256];
  77. char* device = NULL;
  78. #ifdef MCIMPEG
  79. int count = mMCI.GetDeviceCount();
  80. mMCIDevices = NULL;
  81. mCount = 0;
  82. // Enumerate all the MCI devices that can play a movie
  83. if (count)
  84. {
  85. mMCIDevices = new MCIDevice[count];
  86. if (mMCIDevices)
  87. {
  88. mMCI.EnumerateDevices(EnumMCI, this);
  89. }
  90. }
  91. #endif
  92. // Retrieve the user specified device from the config file
  93. buffer[0] = '\0';
  94. if (ini.Load(file))
  95. {
  96. ini.Get_String("MovieSettings", "Device", "Default", buffer, sizeof(buffer));
  97. }
  98. // If there is a specification in the config and it isn't the default
  99. if ((strlen(buffer) != 0) && (stricmp(buffer, "Default") != 0))
  100. {
  101. #ifdef MCIMPEG
  102. // Search for selection
  103. for (int i = 0; i < mCount; i++)
  104. {
  105. if (stricmp(buffer, mMCIDevices[i].name) == 0)
  106. {
  107. device = mMCIDevices[i].name;
  108. break;
  109. }
  110. }
  111. #endif
  112. }
  113. SetDeviceName(device);
  114. }
  115. /****************************************************************************
  116. *
  117. * NAME
  118. * ~MPGSettings
  119. *
  120. * DESCRIPTION
  121. * Destructor
  122. *
  123. * INPUTS
  124. * NONE
  125. *
  126. * RESULT
  127. * NONE
  128. *
  129. ****************************************************************************/
  130. MPGSettings::~MPGSettings(void)
  131. {
  132. if (mDeviceName)
  133. free(mDeviceName);
  134. #ifdef MCIMPEG
  135. if (mMCIDevices)
  136. delete[] mMCIDevices;
  137. #endif
  138. }
  139. /****************************************************************************
  140. *
  141. * NAME
  142. * SetDeviceName(DeviceName)
  143. *
  144. * DESCRIPTION
  145. * Change current device used for mpeg playback
  146. *
  147. * INPUTS
  148. * DeviceName - Device name type (IE: mpegvideo)
  149. *
  150. * RESULT
  151. * NONE
  152. *
  153. ****************************************************************************/
  154. void MPGSettings::SetDeviceName(const char* deviceName)
  155. {
  156. if (mDeviceName)
  157. free(mDeviceName);
  158. mDeviceName = NULL;
  159. if (deviceName)
  160. mDeviceName = strdup(deviceName);
  161. }
  162. bool MPGSettings::Save(FileClass& file)
  163. {
  164. INIClass ini;
  165. if (ini.Load(file))
  166. {
  167. const char* device = GetDeviceName();
  168. if (device)
  169. {
  170. ini.Put_String("MovieSettings", "Device", device);
  171. }
  172. else
  173. {
  174. ini.Put_String("MovieSettings", "Device", "Default");
  175. }
  176. ini.Save(file);
  177. return true;
  178. }
  179. return false;
  180. }
  181. /****************************************************************************
  182. *
  183. * NAME
  184. * Dialog()
  185. *
  186. * DESCRIPTION
  187. * Mpeg playback settings dialog
  188. *
  189. * INPUTS
  190. * NONE
  191. *
  192. * RESULT
  193. * NONE
  194. *
  195. ****************************************************************************/
  196. void MPGSettings::Dialog(void)
  197. {
  198. // Dialog & button dimensions
  199. int d_dialog_w = 200 *RESFACTOR;
  200. int d_dialog_h = 100 *RESFACTOR;
  201. int d_dialog_x = (((320*RESFACTOR) - d_dialog_w) / 2);
  202. int d_dialog_y = 70 * RESFACTOR;
  203. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);
  204. int d_txt6_h = 7 *RESFACTOR;
  205. int d_margin = 7 *RESFACTOR;
  206. int d_okay_w = 40 *RESFACTOR;
  207. int d_okay_h = 9 *RESFACTOR;
  208. int d_okay_x = d_dialog_x + d_margin + 20;
  209. int d_okay_y = ((d_dialog_y + d_dialog_h) - (d_okay_h + 20));
  210. int d_test_w = 40 *RESFACTOR;
  211. int d_test_h = 9 *RESFACTOR;
  212. int d_test_x = (d_dialog_cx - (d_test_w / 2));
  213. int d_test_y = ((d_dialog_y + d_dialog_h) - (d_test_h + 20));
  214. int d_cancel_w = 40 *RESFACTOR;
  215. int d_cancel_h = 9 *RESFACTOR;
  216. int d_cancel_x = ((d_dialog_x + d_dialog_w) - (d_cancel_w + d_margin + 20));
  217. int d_cancel_y = ((d_dialog_y + d_dialog_h) - (d_cancel_h + 20));
  218. int d_method_w = 165 * RESFACTOR;
  219. int d_method_h = 50 * RESFACTOR;
  220. int d_method_x = (d_dialog_cx - (d_method_w / 2));
  221. int d_method_y = (d_dialog_y + 40);
  222. // Button enumerations:
  223. enum
  224. {
  225. BUTTON_OKAY = 100,
  226. BUTTON_TEST,
  227. BUTTON_CANCEL,
  228. BUTTON_METHOD,
  229. NUM_OF_BUTTONS = 4,
  230. };
  231. int num_of_buttons = NUM_OF_BUTTONS;
  232. // Redraw values: in order from "top" to "bottom" layer of the dialog
  233. typedef enum
  234. {
  235. REDRAW_NONE = 0,
  236. REDRAW_BUTTONS, // includes map interior & coord values
  237. REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns
  238. REDRAW_ALL = REDRAW_BACKGROUND
  239. } RedrawType;
  240. // Dialog variables:
  241. KeyNumType input; // input from user
  242. bool process; // loop while true
  243. RedrawType display; // true = re-draw everything
  244. int selection;
  245. bool pressed;
  246. int curbutton;
  247. TextButtonClass * buttons[NUM_OF_BUTTONS];
  248. int i;
  249. char* origDevice = NULL;
  250. // Buttons
  251. ControlClass * commands = NULL; // the button list
  252. TextButtonClass okaybtn(BUTTON_OKAY, TXT_OK, TPF_BUTTON,
  253. d_okay_x, d_okay_y, d_okay_w, d_okay_h);
  254. TextButtonClass testbtn(BUTTON_TEST, "Test", TPF_BUTTON,
  255. d_test_x, d_test_y, d_test_w, d_test_h);
  256. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
  257. d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
  258. ListClass method(BUTTON_METHOD, d_method_x, d_method_y, d_method_w,
  259. d_method_h, TPF_TEXT, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
  260. // Initialize
  261. Set_Logic_Page(SeenBuff);
  262. // Create the list
  263. commands = &okaybtn;
  264. testbtn.Add_Tail(*commands);
  265. cancelbtn.Add_Tail(*commands);
  266. method.Add_Tail(*commands);
  267. // Fill array of button ptrs
  268. curbutton = 0;
  269. buttons[0] = &okaybtn;
  270. buttons[1] = &testbtn;
  271. buttons[2] = &cancelbtn;
  272. buttons[curbutton]->Turn_On();
  273. Keyboard->Clear();
  274. Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), TBLACK,
  275. TPF_CENTER | TPF_TEXT);
  276. // Add device to device control
  277. method.Add_Item("DirectX Media (Default)");
  278. #ifdef MCIMPEG
  279. for (i = 0; i < mCount; i++)
  280. {
  281. if (mMCIDevices[i].description != NULL)
  282. {
  283. method.Add_Item(mMCIDevices[i].description);
  284. }
  285. }
  286. #endif
  287. method.Set_Selected_Index(0);
  288. #ifdef MCIMPEG
  289. // Search for current selection
  290. if (GetDeviceName())
  291. {
  292. for (i = 0; i < mCount; i++)
  293. {
  294. if (stricmp(GetDeviceName(), mMCIDevices[i].name) == 0)
  295. {
  296. method.Set_Selected_Index(i + 1);
  297. break;
  298. }
  299. }
  300. }
  301. #endif
  302. // Save original device selection
  303. if (GetDeviceName())
  304. origDevice = strdup(GetDeviceName());
  305. //------------------------------------------------------------------------
  306. // Main Processing Loop
  307. //------------------------------------------------------------------------
  308. display = REDRAW_ALL;
  309. process = true;
  310. pressed = false;
  311. while (process)
  312. {
  313. #ifdef WIN32
  314. /*
  315. ** If we have just received input focus again after running in the background then
  316. ** we need to redraw.
  317. */
  318. if (AllSurfaces.SurfacesRestored)
  319. {
  320. AllSurfaces.SurfacesRestored=FALSE;
  321. display = REDRAW_ALL;
  322. }
  323. #endif
  324. // Invoke game callback
  325. Call_Back();
  326. // Refresh display if needed
  327. if (display)
  328. {
  329. Hide_Mouse();
  330. if (display >= REDRAW_BACKGROUND)
  331. {
  332. // Refresh the backdrop
  333. Load_Title_Page(true);
  334. CCPalette.Set();
  335. // Draw the background
  336. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  337. Draw_Caption("Movie Settings", d_dialog_x, d_dialog_y, d_dialog_w);
  338. }
  339. // Redraw buttons
  340. if (display >= REDRAW_BUTTONS)
  341. commands->Flag_List_To_Redraw();
  342. Show_Mouse();
  343. display = REDRAW_NONE;
  344. }
  345. // Get user input
  346. input = commands->Input();
  347. // Process input
  348. switch (input)
  349. {
  350. case (BUTTON_OKAY | KN_BUTTON):
  351. selection = BUTTON_OKAY;
  352. pressed = true;
  353. break;
  354. case (BUTTON_TEST | KN_BUTTON):
  355. selection = BUTTON_TEST;
  356. pressed = true;
  357. break;
  358. case (KN_ESC):
  359. case (BUTTON_CANCEL | KN_BUTTON):
  360. selection = BUTTON_CANCEL;
  361. pressed = true;
  362. break;
  363. case KN_UP:
  364. buttons[curbutton]->Turn_Off();
  365. buttons[curbutton]->Flag_To_Redraw();
  366. curbutton--;
  367. if (curbutton < 0)
  368. curbutton = (num_of_buttons - 1);
  369. buttons[curbutton]->Turn_On();
  370. buttons[curbutton]->Flag_To_Redraw();
  371. break;
  372. case KN_DOWN:
  373. buttons[curbutton]->Turn_Off();
  374. buttons[curbutton]->Flag_To_Redraw();
  375. curbutton++;
  376. if (curbutton > (num_of_buttons - 1))
  377. curbutton = 0;
  378. buttons[curbutton]->Turn_On();
  379. buttons[curbutton]->Flag_To_Redraw();
  380. break;
  381. case KN_RETURN:
  382. selection = curbutton + BUTTON_OKAY;
  383. pressed = true;
  384. break;
  385. default:
  386. break;
  387. }
  388. if (pressed)
  389. {
  390. // to make sure the selection is correct in case they used the mouse
  391. buttons[curbutton]->Turn_Off();
  392. buttons[curbutton]->Flag_To_Redraw();
  393. curbutton = selection - BUTTON_OKAY;
  394. buttons[curbutton]->Turn_On();
  395. buttons[curbutton]->IsPressed = true;
  396. buttons[curbutton]->Draw_Me(true);
  397. switch (selection)
  398. {
  399. case (BUTTON_TEST):
  400. buttons[curbutton]->IsPressed = false;
  401. if (method.Current_Index() == 0)
  402. {
  403. SetDeviceName(NULL);
  404. }
  405. else
  406. {
  407. i = method.Current_Index();
  408. #ifdef MCIMPEG
  409. SetDeviceName(mMCIDevices[i - 1].name);
  410. #endif
  411. }
  412. Theme.Fade_Out();
  413. Hide_Mouse();
  414. VisiblePage.Clear();
  415. PlayMpegMovie("acrop");
  416. Keyboard->Clear();
  417. Show_Mouse();
  418. Theme.Queue_Song(THEME_CRUS);
  419. display = REDRAW_ALL;
  420. buttons[curbutton]->Turn_Off();
  421. buttons[curbutton]->Flag_To_Redraw();
  422. buttons[0]->Turn_On();
  423. curbutton = 0;
  424. break;
  425. case (BUTTON_OKAY):
  426. process = false;
  427. if (method.Current_Index() == 0)
  428. {
  429. SetDeviceName(NULL);
  430. }
  431. else
  432. {
  433. i = method.Current_Index();
  434. #ifdef MCIMPEG
  435. SetDeviceName(mMCIDevices[i - 1].name);
  436. #endif
  437. }
  438. {
  439. RawFileClass file(CONFIG_FILE_NAME);
  440. Save(file);
  441. }
  442. break;
  443. case (BUTTON_CANCEL):
  444. process = false;
  445. SetDeviceName(origDevice);
  446. break;
  447. }
  448. pressed = false;
  449. }
  450. }
  451. if (origDevice)
  452. free(origDevice);
  453. }
  454. #ifdef MCIMPEG
  455. /****************************************************************************
  456. *
  457. * NAME
  458. * EnumMCI(DeviceDesc, Context)
  459. *
  460. * DESCRIPTION
  461. * MCI device enumeration callback
  462. *
  463. * INPUTS
  464. * DeviceDesc - MCI device description
  465. * Context - User defined context variable
  466. *
  467. * RESULT
  468. * Continue - Continue with next device flag
  469. *
  470. ****************************************************************************/
  471. bool EnumMCI(MCIDevice* desc, void* context)
  472. {
  473. MPGSettings* mpgset = (MPGSettings*)context;
  474. // Digital video device type?
  475. if (desc->type == MCI_DEVTYPE_DIGITAL_VIDEO)
  476. {
  477. if (MciMovie)
  478. {
  479. CCFileClass file;
  480. const char* filename;
  481. filename = file.Set_Name("movies\\acrop.mpg");
  482. if (!file.Is_Available())
  483. {
  484. char buffer[256];
  485. sprintf(buffer, "Couldn't test MCI device %s\n", desc->name);
  486. VisiblePage.Clear();
  487. GamePalette.Set();
  488. Show_Mouse();
  489. WWMessageBox().Process(buffer);
  490. Hide_Mouse();
  491. VisiblePage.Clear();
  492. return true;
  493. }
  494. if (MciMovie->Open(filename, desc->name))
  495. {
  496. MciMovie->Close();
  497. memcpy((void*)&mpgset->mMCIDevices[mpgset->mCount], (void*)desc,
  498. sizeof(MCIDevice));
  499. mpgset->mCount++;
  500. }
  501. }
  502. }
  503. return true;
  504. }
  505. #endif
  506. #endif