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