CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

MPGSET.CPP (12832B)


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