MENUS.CPP 31 KB

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