CnC_Remastered_Collection

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

MENUS.CPP (31892B)


      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 /* $Header: /CounterStrike/MENUS.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : MENUS.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Phil W. Gorrow                                               *
     26  *                                                                                             *
     27  *                   Start Date : September 10, 1993                                           *
     28  *                                                                                             *
     29  *                  Last Update : Oct. 24, 1996 Victor Grippi                                  *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   Main_Menu -- Menu processing                                                              *
     34  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     35 
     36 #include "function.h"
     37 #ifdef WIN32
     38 #include "ccdde.h"
     39 #else	//WIN32
     40 #include	<sys\timeb.h>
     41 #endif
     42 
     43 /*****************************
     44 **	Function prototypes
     45 ******************************/
     46 
     47 PRIVATE int Coordinates_In_Region(int x, int y, int inx1, int iny1, int inx2, int iny2);
     48 PRIVATE int Select_To_Entry(int select, unsigned long bitfield, int index);
     49 PRIVATE void Flash_Line(char const *text, int xpix, int ypix, unsigned nfgc, unsigned hfgc, unsigned bgc);
     50 
     51 int UnknownKey;
     52 
     53 PRIVATE int MenuUpdate=1;
     54 PRIVATE int MenuSkip;
     55 
     56 #ifdef FIXIT_VERSION_3
     57 #include "WolStrng.h"
     58 #endif
     59 
     60 /*=========================================================================*/
     61 /*	SELECT_TO_ENTRY:																			*/
     62 /*																									*/
     63 /*		This routine converts a selection to the correct string entry. It	   */
     64 /*	does this by search through a long bitfield starting at position index	*/
     65 /*	until it finds the correct conversion to entries.								*/
     66 /*																									*/
     67 /*	INPUTS:	int selection from menu, long the bit field to search, int 	   */
     68 /*				the starting index within the bit field.								*/
     69 /*	RETURNS:	int the index into the table of entries								*/
     70 /*=========================================================================*/
     71 PRIVATE int Select_To_Entry(int select, unsigned long bitfield, int index)
     72 {
     73 	int placement;
     74 
     75 	if (bitfield==0xFFFFFFFFL) 							/* if all bits are set	*/
     76 		return(select);										/*		then it as is		*/
     77 
     78 	placement=0;												/* current pos zero		*/
     79 	while (select) {											/* while still ones		*/
     80 		if (bitfield & (1L<<(placement+index)))			/* if this flagged then	*/
     81 			select--;											/* decrement counter		*/
     82 		placement++;											/* and we moved a place	*/
     83 	}
     84 	while (!(bitfield & (1L<<(placement+index)))) {
     85 		placement++;
     86 	}
     87 
     88 	return(placement);										/* return the position	*/
     89 }
     90 
     91 
     92 /*=========================================================================*/
     93 /*	FLASH_LINE:																					*/
     94 /*																									*/
     95 /*		This routine will flash the line at the desired location for the		*/
     96 /*	menu routine. It is way cool awesome!												*/
     97 /*																									*/
     98 /*	INPUTS:	char *text, int x position on line, int y position, char		   */
     99 /*				normal foreground color, char hilight foreground color, char 	*/
    100 /*				background color																*/
    101 /*	RETURNS:	none																				*/
    102 /*=========================================================================*/
    103 PRIVATE void Flash_Line(char const *text, int xpix, int ypix, unsigned nfgc, unsigned hfgc, unsigned bgc)
    104 {
    105 	int loop;
    106 
    107 	for (loop=0;loop<3;loop++) {
    108 		Hide_Mouse();
    109 		Plain_Text_Print(text, xpix, ypix, hfgc, bgc, TPF_8POINT|TPF_DROPSHADOW);
    110 		Delay(2);
    111 		Plain_Text_Print(text, xpix, ypix, nfgc, bgc, TPF_8POINT|TPF_DROPSHADOW);
    112 		Show_Mouse();
    113 		Delay(2);
    114 	}
    115 }
    116 
    117 /*=========================================================================*/
    118 /*	COORDINATES_IN_REGION:																	*/
    119 /*																									*/
    120 /*		Test to see if a given pair of coordinates are within the given 		*/
    121 /*	rectangular region.																		*/
    122 /*																									*/
    123 /*	INPUTS:	int x to be tested, int y to be tested, int left x pos,			*/
    124 /*				int top y pos, int right x pos, int bottom y pos					*/
    125 /*	RETURNS:	none																				*/
    126 /*=========================================================================*/
    127 PRIVATE int Coordinates_In_Region(int x, int y, int inx1, int iny1, int inx2, int iny2)
    128 {
    129 	return((x>=inx1)&&(x<=inx2)&&(y>=iny1)&&(y<=iny2));
    130 }
    131 
    132 #ifdef NEVER
    133 /*=========================================================================*/
    134 /*	FIND_MENU_ITEMS:																			*/
    135 /*																									*/
    136 /*		This routine finds the real total items in a menu when certain items	*/
    137 /*	may be disabled by bit fields and the like. This is done by looping		*/
    138 /*	through the fields, starting at the position passed in index and 			*/
    139 /*	counting the number of bits that are set.											*/
    140 /*																									*/
    141 /*	INPUTS:	int the maximum number of items possible on the menu, long 		*/
    142 /*				the bit field of enabled and disabled items, char the index		*/
    143 /*				point to start at within the list.										*/
    144 /*	RETURNS:	int the total number of items in the menu							*/
    145 /*=========================================================================*/
    146  int Find_Menu_Items(int maxitems, unsigned long field, char index)
    147  {
    148 	int loop,ctr;
    149 
    150 	if (field==0xFFFFFFFFL) 										/* if all bits are set	*/
    151 		return(maxitems);										/* then maxitems set		*/
    152 
    153 	for (loop=ctr=0;loop<maxitems;loop++) {			/* loop through items	*/
    154 		if (field & (1L<<(loop+index))) {				/* if the bit is set		*/
    155 			ctr++;												/*		count the item		*/
    156 		}
    157 	}
    158 	return(ctr);
    159 }
    160 #endif
    161 
    162 
    163 /*=========================================================================*/
    164 /*	SETUP_EOB_MONITOR_MENU:																	*/
    165 /*																									*/
    166 /*		This routine sets up the eye of the beholder monitor menu.				*/
    167 /*																									*/
    168 /*	INPUTS:	int the menu we are using, char *[] the array of text which		*/
    169 /*				makes up the menu commands, long the info field, int the			*/
    170 /*				index into the field, int the number of lines to skip.			*/
    171 /*	RETURNS:	none																				*/
    172 /*=========================================================================*/
    173 void Setup_Menu(int menu, char const * text[], unsigned long field, int index, int skip)
    174 {
    175 	int * menuptr,lp;
    176 	int menuy,menux,idx,item,num,drawy;
    177 
    178 	menuptr=&MenuList[menu][0];							/* get pointer to menu	*/
    179 	menuy=WinY+menuptr[MENUY];								/* get the absolute 		*/
    180 	menux=(WinX+menuptr[MENUX]);						/*		coords of menu		*/
    181 	item=Select_To_Entry(menuptr[MSELECTED], field, index);
    182 	num=menuptr[ITEMSHIGH];
    183 
    184 	Plain_Text_Print(0, 0, 0, TBLACK, TBLACK, TPF_8POINT|TPF_DROPSHADOW);
    185  	Hide_Mouse();
    186 	for (lp=0;lp<num;lp++) {
    187 		idx=Select_To_Entry(lp, field, index);
    188 		drawy=menuy+(lp*FontHeight)+(lp*skip);
    189 		Plain_Text_Print(text[idx], menux, drawy, menuptr[((idx==item) && (MenuUpdate )) ? HILITE : NORMCOL], TBLACK, TPF_8POINT|TPF_DROPSHADOW);
    190 //		if ((idx==item) && (MenuUpdate ))
    191 //			Text_Print(text[idx], menux, drawy, menuptr[HILITE], TBLACK);
    192 	}
    193 	MenuSkip=skip;
    194 	Show_Mouse();
    195 	Keyboard->Clear();
    196 }
    197 
    198 
    199 /*=========================================================================*/
    200 /*	CHECK_MENU:																					*/
    201 /*																									*/
    202 /*																									*/
    203 /*																									*/
    204 /*	INPUTS:																						*/
    205 /*	RETURNS:																						*/
    206 /*=========================================================================*/
    207 int Check_Menu(int menu, char const * text[], char *, long field, int index)
    208 {
    209 	int maxitem,select,key,menuy,menux;
    210 	int mx1,mx2,my1,my2,tempy;
    211 	int drawy,menuskip,halfskip;
    212 	int normcol,litcol,item,newitem,idx;
    213 	int * menuptr;
    214 
    215 	//selection++;												/* get rid of warning	*/
    216 
    217 	menuptr = &MenuList[menu][0];							/* get pointer to menu	*/
    218 	maxitem = menuptr[ITEMSHIGH]-1;							/* find max items			*/
    219 	newitem = item = menuptr[MSELECTED]%(maxitem+1);	/* find selected 			*/
    220 	select = -1;													/* no selection made		*/
    221 	menuskip = FontHeight+MenuSkip;							/* calc new font height	*/
    222 	halfskip = MenuSkip>>1;									/* adjustment for menus	*/
    223 
    224 	menuy = WinY+menuptr[MENUY];								/* get the absolute 		*/
    225 	menux = (WinX+menuptr[MENUX]);						/*		coords of menu		*/
    226 	normcol = menuptr[NORMCOL];
    227 	litcol = menuptr[HILITE];
    228 
    229 	/*
    230 	**	Fetch a pending keystroke from the buffer if there is a keystroke
    231 	**	present. If no keystroke is pending then simple mouse tracking will
    232 	**	be done.
    233 	*/
    234 	key = 0;
    235 	UnknownKey = 0;
    236 	if (Keyboard->Check()) {
    237 #ifdef WIN32
    238 		key = (Keyboard->Get() & ~(WWKEY_SHIFT_BIT|WWKEY_ALT_BIT|WWKEY_CTRL_BIT) );			/* mask off all but release bit	*/
    239 #else
    240 		key = (Keyboard->Get()&0x08FF);			/* mask off all but release bit	*/
    241 #endif
    242 	}
    243 
    244 	/*
    245 	**	if we are using the mouse and it is installed, then find the mouse
    246 	**	coordinates of the menu and if we are not somewhere on the menu get
    247 	**	the heck outta here. If we are somewhere on the menu, then figure
    248 	**	out the new selected item, and continue forward.
    249 	*/
    250 	mx1=(WinX)+(menuptr[MENUX]*FontWidth);		/* get menu coords		*/
    251 	my1=(WinY)+(menuptr[MENUY])-halfskip;			/*		from the menu		*/
    252 	mx2=mx1+(menuptr[ITEMWIDTH]*FontWidth)-1;		/*		structure as		*/
    253 	my2=my1+(menuptr[ITEMSHIGH]*menuskip)-1;		/*		necessary			*/
    254 
    255 		tempy=Get_Mouse_Y();
    256 		if (Coordinates_In_Region(Get_Mouse_X(), tempy, mx1, my1, mx2, my2)&& MenuUpdate) {
    257 			newitem=(tempy-my1)/menuskip;
    258 		}
    259 
    260 	switch (key) {
    261 
    262 		case KN_UP:												/* if the key moves up	*/
    263 			newitem--;											/* 	new item up one	*/
    264 			if (newitem<0) 									/* if invalid new item	*/
    265 				newitem=maxitem;								/* put at list bottom	*/
    266 			break;
    267 		case KN_DOWN:											/* if key moves down		*/
    268 			newitem++;											/*		new item down one	*/
    269 			if (newitem>maxitem) 							/* if new item past 		*/
    270 				newitem=0;										/*		list end, clear	*/
    271 			break;
    272 		case KN_HOME:											/* if top of list key 	*/
    273 		case KN_PGUP:											/*		is selected then	*/
    274 			newitem=0;											/*		new item = top		*/
    275 			break;
    276 		case KN_END:											/* if bottom of list is	*/
    277 		case KN_PGDN:											/*		selected then		*/
    278 			newitem=maxitem;									/*		new item = bottom	*/
    279 			break;
    280 
    281 		/*
    282 		**	Handle mouse button press. Set selection and then fall into the
    283 		**	normal menu item select logic.
    284 		*/
    285 		case KN_RMOUSE:
    286 		case KN_LMOUSE:
    287 			if (Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY, mx1, my1, mx2, my2)) {
    288 				newitem = (Keyboard->MouseQY - my1) / menuskip;
    289 			} else {
    290 				UnknownKey = key;			//	Pass the unprocessed button click back.
    291 				break;
    292 			}
    293 
    294 		/*
    295 		**	Normal menu item select logic. Will flash line and exit with menu
    296 		**	selection number.
    297 		*/
    298 		case KN_RETURN:										/* if a selection is 	*/
    299 		case KN_SPACE:											/*		made with key		*/
    300 		case KN_CENTER:
    301 			select=newitem;									/*		flag it made.		*/
    302 			break;
    303 
    304 		case 0:
    305 			break;
    306 
    307 		/*
    308 		**	When no key was pressed or an unknown key was pressed, set the
    309 		**	global record of the key and exit normally.
    310 		**	EXCEPTION:	If the key matches the first letter of any of the
    311 		**					menu entries, then presume it as a selection of
    312 		**					that entry.
    313 		*/
    314 		default:
    315 			for (idx = 0; idx < menuptr[ITEMSHIGH]; idx++) {
    316 				if (toupper(*(text[Select_To_Entry(idx, field, index)])) == toupper(Keyboard->To_ASCII((KeyNumType)(key&0x0FF)))) {
    317 					newitem = select = idx;
    318 					break;
    319 				}
    320 			}
    321 			UnknownKey = key;
    322 			break;
    323 	}
    324 
    325 	if (newitem!=item) {
    326 		Hide_Mouse();
    327 		idx=Select_To_Entry(item, field, index);
    328 		drawy=menuy+(item*menuskip);
    329 		Plain_Text_Print(text[idx], menux, drawy, normcol, TBLACK, TPF_8POINT|TPF_DROPSHADOW);
    330 		idx=Select_To_Entry(newitem, field, index);
    331 		drawy=menuy+(newitem*menuskip);
    332 		Plain_Text_Print(text[idx], menux, drawy, litcol, TBLACK, TPF_8POINT|TPF_DROPSHADOW);
    333 		Show_Mouse();												/* resurrect the mouse	*/
    334 	}
    335 
    336 	if (select!=-1) {
    337 		idx=Select_To_Entry(select, field, index);
    338 		Hide_Mouse();												/* get rid of the mouse	*/
    339 		drawy=menuy+(newitem*menuskip);
    340 		Flash_Line(text[idx], menux, drawy, normcol, litcol, TBLACK);
    341 		Show_Mouse();
    342 		select=idx;
    343 	}
    344 
    345 	menuptr[MSELECTED]=newitem;							/* update menu select	*/
    346 
    347 	return(select);
    348 }
    349 
    350 
    351 /***************************************************************************
    352  * Do_Menu -- Generic menu processor.                                      *
    353  *                                                                         *
    354  *    This helper function displays a menu of specified entries and waits  *
    355  *    for the player to make a selection. If a selection is made, then     *
    356  *    a whole number (starting at 0) is returned matching the entry        *
    357  *    selected. If ESC is pressed, then -1 is returned.                    *
    358  *                                                                         *
    359  * INPUT:   strings  -- A pointer to an array of pointers to text strings. *
    360  *                      Each entry in the list will be a menu entry that   *
    361  *                      can be selected.                                   *
    362  *                                                                         *
    363  *          blue     -- Should the special blue color be used to display   *
    364  *                      the menu?                                          *
    365  *                                                                         *
    366  * OUTPUT:  Returns with the cardinal number of the selected menu entry.   *
    367  *          If ESC was pressed, then -1 is returned.                       *
    368  *                                                                         *
    369  * WARNINGS:   none                                                        *
    370  *                                                                         *
    371  * HISTORY:                                                                *
    372  *   05/16/1994 JLB : Created.                                             *
    373  *=========================================================================*/
    374 int Do_Menu(char const ** strings, bool )
    375 {
    376 	int	count;		// Number of entries in this menu.
    377 	int	length;		// The width of the menu (in pixels).
    378 	char	const ** ptr;		// Working menu text pointer.
    379 	int	selection;	// Selection from user.
    380 
    381 	if (!strings) return(-1);
    382 	Set_Logic_Page(SeenBuff);
    383 	Keyboard->Clear();
    384 
    385 	/*
    386 	**	Determine the number of entries in this string.
    387 	*/
    388 	ptr = strings;
    389 	count = 0;
    390 	while (*ptr++) {
    391 		count++;
    392 	}
    393 	MenuList[0][ITEMSHIGH] = count;
    394 
    395 	/*
    396 	**	Determine the width of the menu by finding the length of the
    397 	**	longest menu entry.
    398 	*/
    399 	Plain_Text_Print(TXT_NONE, 0, 0, 0, 0, TPF_8POINT|TPF_DROPSHADOW);
    400 	length = 0;
    401 	ptr = strings;
    402 	while (*ptr) {
    403 		length = max(length, (int)String_Pixel_Width(*ptr));
    404 		ptr++;
    405 	}
    406 	length += 7;
    407 	MenuList[0][ITEMWIDTH] = length >> 3;
    408 
    409 	/*
    410 	**	Adjust the window values to match the size of the
    411 	**	specified menu.
    412 	*/
    413 	WindowList[WINDOW_MENU][WINDOWWIDTH] = (MenuList[0][ITEMWIDTH] + 2) * 8;
    414 	WindowList[WINDOW_MENU][WINDOWX] = (19 - (length >> 4)) * 8;
    415 	WindowList[WINDOW_MENU][WINDOWY] = 174 - (unsigned)(MenuList[0][ITEMSHIGH] * (FontHeight+FontYSpacing));
    416 	WindowList[WINDOW_MENU][WINDOWHEIGHT] = MenuList[0][ITEMSHIGH] * FontHeight + 5 /*11*/;
    417 
    418 	/*
    419 	**	Display the menu.
    420 	*/
    421 	Change_Window((int)WINDOW_MENU);
    422 	Show_Mouse();
    423 	Window_Box(WINDOW_MENU, BOXSTYLE_RAISED);
    424 	Setup_Menu(0, strings, 0xFFFFL, 0, 0);
    425 
    426 	Keyboard->Clear();
    427 	selection = -1;
    428 	UnknownKey = 0;
    429 	while (selection == -1) {
    430 		Call_Back();
    431 		selection = Check_Menu(0, strings, NULL, 0xFFL, 0);
    432 		if (UnknownKey != 0 || UnknownKey == KN_ESC || UnknownKey==KN_LMOUSE || UnknownKey==KN_RMOUSE) break;
    433 	}
    434 	Keyboard->Clear();
    435 	Hide_Mouse();
    436 
    437 	HidPage.Blit(SeenPage);
    438 //WindowList[WINDOW_MAIN][2] = SeenBuff.Get_Width();//BG
    439 	Change_Window((int)WINDOW_MAIN);
    440 	Map.Flag_To_Redraw(true);
    441 	return(selection);
    442 }
    443 
    444 
    445 /***************************************************************************
    446  * Main_Menu -- Menu processing                                            *
    447  *                                                                         *
    448  * INPUT:                                                                  *
    449  *		none.																						*
    450  *                                                                         *
    451  * OUTPUT:                                                                 *
    452  *		index of item selected, -1 if time out											*
    453  *                                                                         *
    454  * WARNINGS:                                                               *
    455  *		none.																						*
    456  *                                                                         *
    457  * HISTORY:                                                                *
    458  *   05/17/1995 BRR : Created.                                             *
    459  *=========================================================================*/
    460 int Main_Menu(unsigned long )
    461 {
    462 	/*
    463 	**	Dialog & button dimensions
    464 	*/
    465 	int	d_dialog_w = 152 * RESFACTOR;
    466 #ifdef FIXIT_VERSION_3
    467 	int	d_dialog_h = 100 * RESFACTOR;
    468 #else
    469 //#ifdef WIN32	//Extra 'Internet' option on WIN32 menu
    470 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - No internet play
    471 	int	d_dialog_h = 100 * RESFACTOR;
    472 #else
    473 //	#if defined(MPEGMOVIE) // Denzil 6/25/98 - Video settings
    474 //	int	d_dialog_h = 100 * RESFACTOR;
    475 //	#else
    476 	int	d_dialog_h = 80 * RESFACTOR;
    477 //	#endif
    478 #endif	//WIN32
    479 #endif	//FIXIT_VERSION_3
    480 	int	d_dialog_x = 85 * RESFACTOR;
    481 	int	d_dialog_y = 75 * RESFACTOR;
    482 	int	d_dialog_cx = d_dialog_x + (d_dialog_w / 2);
    483 
    484 	int	d_start_w = 118 * RESFACTOR;
    485 	int	d_start_h = 9 * RESFACTOR;
    486 	int	d_start_x = 102 * RESFACTOR;
    487 #ifndef FIXIT_VERSION_3			//	Removed button from main menu.
    488 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - no internet play
    489 	int	d_internet_w = 118 * RESFACTOR;
    490 	int	d_internet_h = 9 * RESFACTOR;
    491 	int	d_internet_x = 102 * RESFACTOR;
    492 #endif	//WIN32
    493 #endif
    494 
    495 //#if defined(MPEGMOVIE) // Denzil 6/26/98 Video settings
    496 //	int	d_movie_w = 118 * RESFACTOR;
    497 //	int	d_movie_h = 9 * RESFACTOR;
    498 //	int	d_movie_x = 102 * RESFACTOR;
    499 //#endif
    500 
    501 	int	d_load_w = 118 * RESFACTOR;
    502 	int	d_load_h = 9 * RESFACTOR;
    503 	int	d_load_x = 102 * RESFACTOR;
    504 
    505 	int	d_multi_w = 118 * RESFACTOR;
    506 	int	d_multi_h = 9 * RESFACTOR;
    507 	int	d_multi_x = 102 * RESFACTOR;
    508 
    509 	int	d_intro_w = 118 * RESFACTOR;
    510 	int	d_intro_h = 9 * RESFACTOR;
    511 	int	d_intro_x = 102 * RESFACTOR;
    512 
    513 	int	d_exit_w = 118 * RESFACTOR;    //changed value to 118 V.Grippi
    514 	int	d_exit_h = 9 * RESFACTOR;
    515 	int     d_exit_x = 102 *RESFACTOR;   //Added V.Grippi
    516 
    517 	int starty = d_dialog_y + (12 * RESFACTOR);
    518 
    519 //#if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - No internet play
    520 //#ifndef FIXIT_VERSION_3
    521 	static int	max_buttons = 7;
    522 //#else
    523 //	static int	max_buttons = 6;
    524 //#endif
    525 
    526 //#if defined(MPEGMOVIE) // Denzil 6/26/98 Video settings
    527 //	max_buttons++;
    528 //#endif
    529 	/*
    530 	**	Button enumerations:
    531 	*/
    532 	//	Enums in Select_Game() must match order of buttons in Main_Menu().
    533 #ifdef FIXIT_VERSION_3
    534 	enum {
    535 		BUTTON_EXPAND=100,			//	(CS)
    536 		BUTTON_EXPAND_AM,
    537 		BUTTON_START,
    538 		BUTTON_LOAD,
    539 		BUTTON_MULTI,
    540 		BUTTON_INTRO,
    541 		BUTTON_EXIT,
    542 	};
    543 #else	//	FIXIT_VERSION_3
    544 	enum {
    545 		BUTTON_EXPAND=100,
    546 		BUTTON_START,
    547 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - No internet play
    548 		BUTTON_INTERNET,
    549 #endif	//WIN32
    550 //#if defined(MPEGMOVIE) // Denzil 6/26/98 Video settings
    551 //		BUTTON_MOVIE,
    552 //#endif
    553 		BUTTON_LOAD,
    554 		BUTTON_MULTI,
    555 		BUTTON_INTRO,
    556 		BUTTON_EXIT,
    557 	};
    558 #endif	//	FIXIT_VERSION_3
    559 
    560 	/*
    561 	**	Dialog variables:
    562 	*/
    563 #ifdef FIXIT_VERSION_3
    564 	bool bExpansionCS = Expansion_CS_Present();
    565 	bool bExpansionAM = Expansion_AM_Present();
    566 #else
    567 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
    568 	bool expansions = Expansion_CS_Present() | Expansion_AM_Present();
    569 #else
    570 	bool expansions = Expansion_CS_Present();
    571 #endif
    572 #endif
    573 	KeyNumType input;								// input from user
    574 	int retval;										// return value
    575 	int curbutton;
    576 	TextButtonClass * buttons[7];
    577 	unsigned long starttime;
    578 
    579 	/*
    580 	**	Buttons
    581 	*/
    582 	ControlClass * commands = NULL;				// the button list
    583 
    584 #ifdef FIXIT_VERSION_3
    585 	int ystep = 14 * RESFACTOR;
    586 	if( bExpansionCS )
    587 	{
    588 		if( bExpansionAM )
    589 			ystep = 12 * RESFACTOR;
    590 		else
    591 			ystep = 13 * RESFACTOR;
    592 	}
    593 	else if( bExpansionAM )
    594 		ystep = 13 * RESFACTOR;
    595 
    596 	TextButtonClass expandbtnCS( BUTTON_EXPAND, TXT_WOL_CS_MISSIONS, TPF_BUTTON, d_start_x, starty, d_start_w, d_start_h );
    597 	if( bExpansionCS )
    598 		starty += ystep;
    599 	TextButtonClass expandbtnAM( BUTTON_EXPAND_AM, TXT_WOL_AM_MISSIONS, TPF_BUTTON, d_start_x, starty, d_start_w, d_start_h );
    600 	if( bExpansionAM )
    601 		starty += ystep;
    602 #else
    603 	int ystep = 12 * RESFACTOR;
    604 	if (expansions) ystep = 10 * RESFACTOR;
    605 	
    606 	TextButtonClass expandbtn (BUTTON_EXPAND, TXT_NEW_MISSIONS, TPF_BUTTON, d_start_x, starty, d_start_w, d_start_h);
    607 	if (expansions) starty += ystep;
    608 #endif
    609 
    610 	TextButtonClass startbtn(BUTTON_START, TXT_START_NEW_GAME, TPF_BUTTON, d_start_x, starty, d_start_w, d_start_h);
    611 	starty += ystep;
    612 #ifndef FIXIT_VERSION_3
    613 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - no internet play
    614 	TextButtonClass internetbutton (BUTTON_INTERNET, TXT_INTERNET, TPF_BUTTON, d_internet_x, starty, d_internet_w, d_internet_h);
    615 	starty += ystep;
    616 #endif	//WIN32
    617 #endif
    618 
    619 //#if defined(MPEGMOVIE) // Denzil 6/26/98 Video settings
    620 //	TextButtonClass moviebutton(BUTTON_MOVIE, "Movie Settings", TPF_BUTTON, d_movie_x, starty, d_movie_w, d_movie_h);
    621 //	starty += ystep;
    622 //#endif	//WIN32
    623 
    624 	TextButtonClass loadbtn(BUTTON_LOAD, TXT_LOAD_MISSION, TPF_BUTTON, d_load_x, starty, d_load_w, d_load_h);
    625 	starty += ystep;
    626 
    627 	TextButtonClass multibtn(BUTTON_MULTI, TXT_MULTIPLAYER_GAME, TPF_BUTTON, d_multi_x, starty, d_multi_w, d_multi_h);
    628 	starty += ystep;
    629 
    630 	TextButtonClass introbtn(BUTTON_INTRO, TXT_INTRO, TPF_BUTTON, d_intro_x, starty, d_intro_w, d_intro_h);
    631 	starty += ystep;
    632 
    633 	TextButtonClass exitbtn(BUTTON_EXIT, TXT_EXIT_GAME, TPF_BUTTON,
    634 		d_exit_x, starty, d_exit_w, d_exit_h);
    635 	starty += ystep;
    636 
    637 	/*
    638 	**	Initialize
    639 	*/
    640 	if (RequiredCD != -2) {
    641 		RequiredCD = -1;
    642 		Force_CD_Available(RequiredCD);
    643 	}
    644 	Set_Logic_Page(SeenBuff);
    645 	Keyboard->Clear();
    646 	starttime = TickCount;
    647 
    648 	/*
    649 	**	Create the list
    650 	*/
    651 	commands = &startbtn;
    652 #ifdef FIXIT_VERSION_3
    653 	if( bExpansionCS )
    654 		expandbtnCS.Add_Tail(*commands);
    655 	if( bExpansionAM )
    656 		expandbtnAM.Add_Tail(*commands);
    657 #else
    658 	if (expansions) {
    659 		expandbtn.Add_Tail(*commands);
    660 	}
    661 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - No internet play
    662 	internetbutton.Add_Tail(*commands);
    663 #endif	//WIN32
    664 #endif
    665 //#if defined(MPEGMOVIE) // Denzil 6/26/98 Video settings
    666 //	moviebutton.Add_Tail(*commands);
    667 //#endif
    668 	loadbtn.Add_Tail(*commands);
    669 	multibtn.Add_Tail(*commands);
    670 	introbtn.Add_Tail(*commands);
    671 	exitbtn.Add_Tail(*commands);
    672 
    673 	/*
    674 	**	Fill array of button ptrs
    675 	*/
    676 #ifdef FIXIT_VERSION_3
    677 	curbutton = bExpansionCS ? 0 : ( bExpansionAM ? 1 : 2 );
    678 
    679 	buttons[0] = &expandbtnCS;
    680 	buttons[1] = &expandbtnAM;
    681 	buttons[2] = &startbtn;
    682 	buttons[3] = &loadbtn;
    683 	buttons[4] = &multibtn;
    684 	buttons[5] = &introbtn;
    685 	buttons[6] = &exitbtn;
    686 #else
    687 	if (expansions) {
    688 		curbutton = 0;
    689 	} else {
    690 		curbutton = 1;
    691 	}
    692 	
    693 	buttons[0] = &expandbtn;
    694 	buttons[1] = &startbtn;
    695 	buttons[2] = &internetbutton;
    696 	buttons[3] = &loadbtn;
    697 	buttons[4] = &multibtn;
    698 	buttons[5] = &introbtn;
    699 	buttons[6] = &exitbtn;
    700 #endif
    701 
    702 	buttons[curbutton]->Turn_On();
    703 
    704 	Keyboard->Clear();
    705 
    706 	Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(),
    707 		TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
    708 
    709 	fixed oldvolume = Options.ScoreVolume;
    710 	if (oldvolume == 0) {
    711 		Options.Set_Score_Volume(fixed(4, 10), false);
    712 	}
    713 	Theme.Play_Song(THEME_INTRO);
    714 
    715 	/*
    716 	**	Main Processing Loop.
    717 	*/
    718 	bool display = true;
    719 	bool process = true;
    720 	while (process) {
    721 
    722 #ifdef WIN32
    723 		/*
    724 		** If we have just received input focus again after running in the background then
    725 		** we need to redraw.
    726 		*/
    727 		if (AllSurfaces.SurfacesRestored) {
    728 			AllSurfaces.SurfacesRestored=FALSE;
    729 			display = true;
    730 		}
    731 #endif
    732 
    733 		/*
    734 		**	If timeout expires, bail
    735 		*/
    736 //		if (timeout && TickCount - starttime > timeout) {
    737 //			retval = -1;
    738 //			process = false;
    739 //		}
    740 
    741 		/*
    742 		**	Invoke game callback.
    743 		*/
    744 		Call_Back();
    745 
    746 		/*
    747 		**	Refresh display if needed.
    748 		*/
    749 		if (display) {
    750 
    751 			/*
    752 			**	Load the background picture.
    753 			*/
    754 			Load_Title_Page();
    755 			CCPalette.Set();
    756 
    757 			/*
    758 			**	Display the title and text overlay for the menu.
    759 			*/
    760 			Set_Logic_Page(HidPage);
    761 //			Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
    762 //			Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w);
    763 			commands->Draw_All();
    764 #ifdef FIXIT_VERSION_3
    765 #if (0)//PG
    766 			Fancy_Text_Print("V%s", d_dialog_x+d_dialog_w- (18 * RESFACTOR),
    767 				d_dialog_y+d_dialog_h-(5 * RESFACTOR), GadgetClass::Get_Color_Scheme(), TBLACK,
    768 				TPF_EFNT|TPF_NOSHADOW|TPF_RIGHT,
    769 				Version_Name());
    770 #endif
    771 #else
    772 #ifndef WIN32
    773 			Fancy_Text_Print("V%s", d_dialog_x+d_dialog_w- (18 * RESFACTOR),
    774 				d_dialog_y+d_dialog_h-(8  * RESFACTOR), GadgetClass::Get_Color_Scheme(), TBLACK,
    775 				TPF_EFNT|TPF_NOSHADOW|TPF_RIGHT,
    776 				Version_Name());
    777 
    778 #else
    779 			Fancy_Text_Print("V%s", d_dialog_x+d_dialog_w- (18 * RESFACTOR),
    780 				d_dialog_y+d_dialog_h-(11 * RESFACTOR), GadgetClass::Get_Color_Scheme(), TBLACK,
    781 				TPF_EFNT|TPF_NOSHADOW|TPF_RIGHT,
    782 				Version_Name());
    783 
    784 #endif
    785 #endif
    786 
    787 			/*
    788 			**	Copy the menu to the visible page.
    789 			*/
    790 			Hide_Mouse();
    791 			HidPage.Blit(SeenPage);
    792 			Show_Mouse();
    793 
    794 			Set_Logic_Page(SeenBuff);
    795 			display = false;
    796 		}
    797 		else {
    798 			if (RunningAsDLL) {	//PG
    799 				retval = -1;
    800 				process = false;
    801 			}
    802 		}
    803 
    804 
    805 		/*
    806 		**	Get and process player input.
    807 		*/
    808 		input = commands->Input();
    809 
    810 #ifndef FIXIT_VERSION_3
    811 #if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - No Internet play
    812 		/*
    813 		** Check to see if WChat has told us to start playing an internet game
    814 		*/
    815 		if (DDEServer.Get_MPlayer_Game_Info()) {
    816 			retval = BUTTON_INTERNET - BUTTON_EXPAND;
    817 			process = false;
    818 			input = KN_NONE;
    819 		}
    820 #endif	//WIN32
    821 #endif
    822 
    823 		/*
    824 		**	If there is input, then take this opportunity to seed some bits
    825 		**	to the cryptographic random number generator.
    826 		*/
    827 		if (input != 0) {
    828 			#ifdef WIN32
    829 				SYSTEMTIME t;
    830 				GetSystemTime(&t);
    831 				CryptRandom.Seed_Byte(t.wMilliseconds);
    832 			#else
    833 				struct timeb t;
    834 				ftime(&t);
    835 				CryptRandom.Seed_Byte(t.millitm);
    836 			#endif
    837 		}
    838 
    839 		/*
    840 		**	Dispatch the input to be processed.
    841 		*/
    842 		switch (input) {
    843 			case (BUTTON_EXPAND | KN_BUTTON):
    844 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    845 				process = false;
    846 				break;
    847 
    848 #ifdef FIXIT_VERSION_3
    849 			case (BUTTON_EXPAND_AM | KN_BUTTON):
    850 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    851 				process = false;
    852 				break;
    853 #endif
    854 
    855 			case (BUTTON_START | KN_BUTTON):
    856 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    857 				process = false;
    858 				break;
    859 
    860 #ifndef FIXIT_VERSION_3
    861 			#if defined(WIN32) && !defined(INTERNET_OFF) // Denzil 5/1/98 - Internet play
    862 			case (BUTTON_INTERNET | KN_BUTTON):
    863 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    864 				process = false;
    865 				break;
    866 			#endif	//WIN32
    867 #endif
    868 
    869 //			#if defined(MPEGMOVIE)
    870 //			case (BUTTON_MOVIE | KN_BUTTON):
    871 //				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    872 //				process = false;
    873 //			break;
    874 //			#endif
    875 			
    876 			case (BUTTON_LOAD | KN_BUTTON):
    877 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    878 				process = false;
    879 				break;
    880 
    881 			case (BUTTON_MULTI | KN_BUTTON):
    882 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    883 				process = false;
    884 				break;
    885 
    886 			case (BUTTON_INTRO | KN_BUTTON):
    887 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    888 				process = false;
    889 				break;
    890 
    891 			case (BUTTON_EXIT | KN_BUTTON):
    892 				retval = (input & 0x7FFF) - BUTTON_EXPAND;
    893 				process = false;
    894 				break;
    895 #if (0)
    896 			case KN_BACKSPACE:
    897 				Show_Who_Was_Responsible ();
    898 				display = true;
    899 				Theme.Play_Song(THEME_INTRO);
    900 				break;
    901 #endif	//(0)
    902 			case KN_UP:
    903 				buttons[curbutton]->Turn_Off();
    904 				buttons[curbutton]->Flag_To_Redraw();
    905 				curbutton--;
    906 #ifdef FIXIT_VERSION_3
    907 				switch( curbutton )
    908 				{
    909 				case -1:
    910 					curbutton = max_buttons - 1;
    911 					break;
    912 				case 0:
    913 					if( !bExpansionCS )
    914 						curbutton = max_buttons - 1;
    915 					break;
    916 				case 1:
    917 					if( !bExpansionAM )
    918 					{
    919 						if( bExpansionCS )
    920 							curbutton = 0;
    921 						else
    922 							curbutton = max_buttons - 1;
    923 					}
    924 					break;
    925 				}
    926 #else
    927 				if (expansions) {
    928 					if (curbutton < 0) {
    929 						curbutton = max_buttons-1;
    930 					}
    931 				} else {
    932 					if (curbutton < 1) {
    933 						curbutton = max_buttons-1;
    934 					}
    935 				}
    936 #endif
    937 				buttons[curbutton]->Turn_On();
    938 				buttons[curbutton]->Flag_To_Redraw();
    939 				break;
    940 
    941 			case KN_DOWN:
    942 				buttons[curbutton]->Turn_Off();
    943 				buttons[curbutton]->Flag_To_Redraw();
    944 				curbutton++;
    945 #ifdef FIXIT_VERSION_3
    946 				if( curbutton == max_buttons )
    947 				{
    948 					if( bExpansionCS )
    949 						curbutton = 0;
    950 					else if( bExpansionAM )
    951 						curbutton = 1;
    952 					else
    953 						curbutton = 2;
    954 				}
    955 				else if( curbutton == 1 && !bExpansionAM )
    956 					curbutton = 2;
    957 #else
    958 				if (curbutton > (max_buttons - 1)) {
    959 					if (expansions) {
    960 						curbutton = 0;
    961 					} else {
    962 						curbutton = 1;
    963 					}
    964 				}
    965 #endif
    966 				buttons[curbutton]->Turn_On();
    967 				buttons[curbutton]->Flag_To_Redraw();
    968 				break;
    969 
    970 			case KN_RETURN:
    971 				buttons[curbutton]->IsPressed = true;
    972 				buttons[curbutton]->Draw_Me(true);
    973 				retval = curbutton;
    974 				process = false;
    975 				break;
    976 
    977 
    978 
    979 			case KN_LMOUSE:
    980 #if (0)//PG
    981 				if (Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY,
    982 
    983 													9*RESFACTOR, 10*RESFACTOR,
    984 													79*RESFACTOR, 24*RESFACTOR)){
    985 					Show_Who_Was_Responsible();
    986 					display = true;
    987 					Theme.Play_Song(THEME_INTRO);
    988 
    989 					break;
    990 				}
    991 #endif
    992 #ifdef FIXIT_ANTS
    993 			#ifdef FIXIT_PATCH_108
    994 			if (Is_Counterstrike_Installed() == true)
    995 				{
    996 			#endif
    997 				if ((Keyboard->Down(KN_LSHIFT) || Keyboard->Down(KN_RSHIFT)) && Coordinates_In_Region(Keyboard->MouseQX, Keyboard->MouseQY, 260*RESFACTOR, 0, 320*RESFACTOR, 50*RESFACTOR))  {
    998 					AntsEnabled = true;
    999 					process = false;
   1000 #ifdef FIXIT_VERSION_3
   1001 					retval = 2;		//	To match SEL_START_NEW_GAME
   1002 #else
   1003 					retval = 1;
   1004 #endif
   1005 				}
   1006 			#ifdef FIXIT_PATCH_108
   1007 			}
   1008 			#endif
   1009 #endif
   1010 
   1011 
   1012 			default:
   1013 				break;
   1014 		}
   1015 	}
   1016 
   1017 	Options.Set_Score_Volume(oldvolume, false);
   1018 
   1019 	return(retval);
   1020 }