MENUS.CPP 31 KB

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