MENUS.CPP 29 KB

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