MN_MENU.C 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744
  1. //**************************************************************************
  2. //**
  3. //** mn_menu.c : Heretic 2 : Raven Software, Corp.
  4. //**
  5. //** $RCSfile: mn_menu.c,v $
  6. //** $Revision: 1.32 $
  7. //** $Date: 96/01/01 01:51:28 $
  8. //** $Author: bgokey $
  9. //**
  10. //**************************************************************************
  11. // HEADER FILES ------------------------------------------------------------
  12. #include <ctype.h>
  13. #include "h2def.h"
  14. #include "p_local.h"
  15. #include "r_local.h"
  16. #include "soundst.h"
  17. // MACROS ------------------------------------------------------------------
  18. #define LEFT_DIR 0
  19. #define RIGHT_DIR 1
  20. #define ITEM_HEIGHT 20
  21. #define SELECTOR_XOFFSET (-28)
  22. #define SELECTOR_YOFFSET (-1)
  23. #define SLOTTEXTLEN 16
  24. #define ASCII_CURSOR '['
  25. // TYPES -------------------------------------------------------------------
  26. typedef enum
  27. {
  28. ITT_EMPTY,
  29. ITT_EFUNC,
  30. ITT_LRFUNC,
  31. ITT_SETMENU,
  32. ITT_INERT
  33. } ItemType_t;
  34. typedef enum
  35. {
  36. MENU_MAIN,
  37. MENU_CLASS,
  38. MENU_SKILL,
  39. MENU_OPTIONS,
  40. MENU_OPTIONS2,
  41. MENU_FILES,
  42. MENU_LOAD,
  43. MENU_SAVE,
  44. MENU_NONE
  45. } MenuType_t;
  46. typedef struct
  47. {
  48. ItemType_t type;
  49. char *text;
  50. void (*func)(int option);
  51. int option;
  52. MenuType_t menu;
  53. } MenuItem_t;
  54. typedef struct
  55. {
  56. int x;
  57. int y;
  58. void (*drawFunc)(void);
  59. int itemCount;
  60. MenuItem_t *items;
  61. int oldItPos;
  62. MenuType_t prevMenu;
  63. } Menu_t;
  64. // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
  65. // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
  66. // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
  67. static void InitFonts(void);
  68. static void SetMenu(MenuType_t menu);
  69. static void SCQuitGame(int option);
  70. static void SCClass(int option);
  71. static void SCSkill(int option);
  72. static void SCMouseSensi(int option);
  73. static void SCSfxVolume(int option);
  74. static void SCMusicVolume(int option);
  75. static void SCScreenSize(int option);
  76. static boolean SCNetCheck(int option);
  77. static void SCNetCheck2(int option);
  78. static void SCLoadGame(int option);
  79. static void SCSaveGame(int option);
  80. static void SCMessages(int option);
  81. static void SCEndGame(int option);
  82. static void SCInfo(int option);
  83. static void DrawMainMenu(void);
  84. static void DrawClassMenu(void);
  85. static void DrawSkillMenu(void);
  86. static void DrawOptionsMenu(void);
  87. static void DrawOptions2Menu(void);
  88. static void DrawFileSlots(Menu_t *menu);
  89. static void DrawFilesMenu(void);
  90. static void MN_DrawInfo(void);
  91. static void DrawLoadMenu(void);
  92. static void DrawSaveMenu(void);
  93. static void DrawSlider(Menu_t *menu, int item, int width, int slot);
  94. void MN_LoadSlotText(void);
  95. // EXTERNAL DATA DECLARATIONS ----------------------------------------------
  96. extern int detailLevel;
  97. extern int screenblocks;
  98. extern char *SavePath;
  99. extern int key_speed, key_strafe;
  100. extern boolean gamekeydown[256]; // The NUMKEYS macro is local to g_game
  101. // PUBLIC DATA DEFINITIONS -------------------------------------------------
  102. boolean MenuActive;
  103. int InfoType;
  104. boolean messageson;
  105. boolean mn_SuicideConsole;
  106. // PRIVATE DATA DEFINITIONS ------------------------------------------------
  107. static int FontABaseLump;
  108. static int FontAYellowBaseLump;
  109. static int FontBBaseLump;
  110. static int MauloBaseLump;
  111. static Menu_t *CurrentMenu;
  112. static int CurrentItPos;
  113. static int MenuPClass;
  114. static int MenuTime;
  115. static boolean soundchanged;
  116. boolean askforquit;
  117. boolean typeofask;
  118. static boolean FileMenuKeySteal;
  119. static boolean slottextloaded;
  120. static char SlotText[6][SLOTTEXTLEN+2];
  121. static char oldSlotText[SLOTTEXTLEN+2];
  122. static int SlotStatus[6];
  123. static int slotptr;
  124. static int currentSlot;
  125. static int quicksave;
  126. static int quickload;
  127. static MenuItem_t MainItems[] =
  128. {
  129. { ITT_SETMENU, "NEW GAME", SCNetCheck2, 1, MENU_CLASS },
  130. { ITT_SETMENU, "OPTIONS", NULL, 0, MENU_OPTIONS },
  131. { ITT_SETMENU, "GAME FILES", NULL, 0, MENU_FILES },
  132. { ITT_EFUNC, "INFO", SCInfo, 0, MENU_NONE },
  133. { ITT_EFUNC, "QUIT GAME", SCQuitGame, 0, MENU_NONE }
  134. };
  135. static Menu_t MainMenu =
  136. {
  137. 110, 56,
  138. DrawMainMenu,
  139. 5, MainItems,
  140. 0,
  141. MENU_NONE
  142. };
  143. static MenuItem_t ClassItems[] =
  144. {
  145. { ITT_EFUNC, "FIGHTER", SCClass, 0, MENU_NONE },
  146. { ITT_EFUNC, "CLERIC", SCClass, 1, MENU_NONE },
  147. { ITT_EFUNC, "MAGE", SCClass, 2, MENU_NONE }
  148. };
  149. static Menu_t ClassMenu =
  150. {
  151. 66, 66,
  152. DrawClassMenu,
  153. 3, ClassItems,
  154. 0,
  155. MENU_MAIN
  156. };
  157. static MenuItem_t FilesItems[] =
  158. {
  159. { ITT_SETMENU, "LOAD GAME", SCNetCheck2, 2, MENU_LOAD },
  160. { ITT_SETMENU, "SAVE GAME", NULL, 0, MENU_SAVE }
  161. };
  162. static Menu_t FilesMenu =
  163. {
  164. 110, 60,
  165. DrawFilesMenu,
  166. 2, FilesItems,
  167. 0,
  168. MENU_MAIN
  169. };
  170. static MenuItem_t LoadItems[] =
  171. {
  172. { ITT_EFUNC, NULL, SCLoadGame, 0, MENU_NONE },
  173. { ITT_EFUNC, NULL, SCLoadGame, 1, MENU_NONE },
  174. { ITT_EFUNC, NULL, SCLoadGame, 2, MENU_NONE },
  175. { ITT_EFUNC, NULL, SCLoadGame, 3, MENU_NONE },
  176. { ITT_EFUNC, NULL, SCLoadGame, 4, MENU_NONE },
  177. { ITT_EFUNC, NULL, SCLoadGame, 5, MENU_NONE }
  178. };
  179. static Menu_t LoadMenu =
  180. {
  181. 70, 30,
  182. DrawLoadMenu,
  183. 6, LoadItems,
  184. 0,
  185. MENU_FILES
  186. };
  187. static MenuItem_t SaveItems[] =
  188. {
  189. { ITT_EFUNC, NULL, SCSaveGame, 0, MENU_NONE },
  190. { ITT_EFUNC, NULL, SCSaveGame, 1, MENU_NONE },
  191. { ITT_EFUNC, NULL, SCSaveGame, 2, MENU_NONE },
  192. { ITT_EFUNC, NULL, SCSaveGame, 3, MENU_NONE },
  193. { ITT_EFUNC, NULL, SCSaveGame, 4, MENU_NONE },
  194. { ITT_EFUNC, NULL, SCSaveGame, 5, MENU_NONE }
  195. };
  196. static Menu_t SaveMenu =
  197. {
  198. 70, 30,
  199. DrawSaveMenu,
  200. 6, SaveItems,
  201. 0,
  202. MENU_FILES
  203. };
  204. static MenuItem_t SkillItems[] =
  205. {
  206. { ITT_EFUNC, NULL, SCSkill, sk_baby, MENU_NONE },
  207. { ITT_EFUNC, NULL, SCSkill, sk_easy, MENU_NONE },
  208. { ITT_EFUNC, NULL, SCSkill, sk_medium, MENU_NONE },
  209. { ITT_EFUNC, NULL, SCSkill, sk_hard, MENU_NONE },
  210. { ITT_EFUNC, NULL, SCSkill, sk_nightmare, MENU_NONE }
  211. };
  212. static Menu_t SkillMenu =
  213. {
  214. 120, 44,
  215. DrawSkillMenu,
  216. 5, SkillItems,
  217. 2,
  218. MENU_CLASS
  219. };
  220. static MenuItem_t OptionsItems[] =
  221. {
  222. { ITT_EFUNC, "END GAME", SCEndGame, 0, MENU_NONE },
  223. { ITT_EFUNC, "MESSAGES : ", SCMessages, 0, MENU_NONE },
  224. { ITT_LRFUNC, "MOUSE SENSITIVITY", SCMouseSensi, 0, MENU_NONE },
  225. { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
  226. { ITT_SETMENU, "MORE...", NULL, 0, MENU_OPTIONS2 }
  227. };
  228. static Menu_t OptionsMenu =
  229. {
  230. 88, 30,
  231. DrawOptionsMenu,
  232. 5, OptionsItems,
  233. 0,
  234. MENU_MAIN
  235. };
  236. static MenuItem_t Options2Items[] =
  237. {
  238. { ITT_LRFUNC, "SCREEN SIZE", SCScreenSize, 0, MENU_NONE },
  239. { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
  240. { ITT_LRFUNC, "SFX VOLUME", SCSfxVolume, 0, MENU_NONE },
  241. { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
  242. { ITT_LRFUNC, "MUSIC VOLUME", SCMusicVolume, 0, MENU_NONE },
  243. { ITT_EMPTY, NULL, NULL, 0, MENU_NONE }
  244. };
  245. static Menu_t Options2Menu =
  246. {
  247. 90, 20,
  248. DrawOptions2Menu,
  249. 6, Options2Items,
  250. 0,
  251. MENU_OPTIONS
  252. };
  253. static Menu_t *Menus[] =
  254. {
  255. &MainMenu,
  256. &ClassMenu,
  257. &SkillMenu,
  258. &OptionsMenu,
  259. &Options2Menu,
  260. &FilesMenu,
  261. &LoadMenu,
  262. &SaveMenu
  263. };
  264. #ifdef __WATCOMC__
  265. static char *GammaText[] =
  266. {
  267. TXT_GAMMA_LEVEL_OFF,
  268. TXT_GAMMA_LEVEL_1,
  269. TXT_GAMMA_LEVEL_2,
  270. TXT_GAMMA_LEVEL_3,
  271. TXT_GAMMA_LEVEL_4
  272. };
  273. #endif
  274. // CODE --------------------------------------------------------------------
  275. //---------------------------------------------------------------------------
  276. //
  277. // PROC MN_Init
  278. //
  279. //---------------------------------------------------------------------------
  280. void MN_Init(void)
  281. {
  282. InitFonts();
  283. MenuActive = false;
  284. // messageson = true; // Set by defaults in .CFG
  285. MauloBaseLump = W_GetNumForName("FBULA0"); // ("M_SKL00");
  286. }
  287. //---------------------------------------------------------------------------
  288. //
  289. // PROC InitFonts
  290. //
  291. //---------------------------------------------------------------------------
  292. static void InitFonts(void)
  293. {
  294. FontABaseLump = W_GetNumForName("FONTA_S")+1;
  295. FontAYellowBaseLump = W_GetNumForName("FONTAY_S")+1;
  296. FontBBaseLump = W_GetNumForName("FONTB_S")+1;
  297. }
  298. //---------------------------------------------------------------------------
  299. //
  300. // PROC MN_DrTextA
  301. //
  302. // Draw text using font A.
  303. //
  304. //---------------------------------------------------------------------------
  305. void MN_DrTextA(char *text, int x, int y)
  306. {
  307. char c;
  308. patch_t *p;
  309. while((c = *text++) != 0)
  310. {
  311. if(c < 33)
  312. {
  313. x += 5;
  314. }
  315. else
  316. {
  317. p = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
  318. V_DrawPatch(x, y, p);
  319. x += p->width-1;
  320. }
  321. }
  322. }
  323. //==========================================================================
  324. //
  325. // MN_DrTextAYellow
  326. //
  327. //==========================================================================
  328. void MN_DrTextAYellow(char *text, int x, int y)
  329. {
  330. char c;
  331. patch_t *p;
  332. while((c = *text++) != 0)
  333. {
  334. if(c < 33)
  335. {
  336. x += 5;
  337. }
  338. else
  339. {
  340. p = W_CacheLumpNum(FontAYellowBaseLump+c-33, PU_CACHE);
  341. V_DrawPatch(x, y, p);
  342. x += p->width-1;
  343. }
  344. }
  345. }
  346. //---------------------------------------------------------------------------
  347. //
  348. // FUNC MN_TextAWidth
  349. //
  350. // Returns the pixel width of a string using font A.
  351. //
  352. //---------------------------------------------------------------------------
  353. int MN_TextAWidth(char *text)
  354. {
  355. char c;
  356. int width;
  357. patch_t *p;
  358. width = 0;
  359. while((c = *text++) != 0)
  360. {
  361. if(c < 33)
  362. {
  363. width += 5;
  364. }
  365. else
  366. {
  367. p = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
  368. width += p->width-1;
  369. }
  370. }
  371. return(width);
  372. }
  373. //---------------------------------------------------------------------------
  374. //
  375. // PROC MN_DrTextB
  376. //
  377. // Draw text using font B.
  378. //
  379. //---------------------------------------------------------------------------
  380. void MN_DrTextB(char *text, int x, int y)
  381. {
  382. char c;
  383. patch_t *p;
  384. while((c = *text++) != 0)
  385. {
  386. if(c < 33)
  387. {
  388. x += 8;
  389. }
  390. else
  391. {
  392. p = W_CacheLumpNum(FontBBaseLump+c-33, PU_CACHE);
  393. V_DrawPatch(x, y, p);
  394. x += p->width-1;
  395. }
  396. }
  397. }
  398. //---------------------------------------------------------------------------
  399. //
  400. // FUNC MN_TextBWidth
  401. //
  402. // Returns the pixel width of a string using font B.
  403. //
  404. //---------------------------------------------------------------------------
  405. int MN_TextBWidth(char *text)
  406. {
  407. char c;
  408. int width;
  409. patch_t *p;
  410. width = 0;
  411. while((c = *text++) != 0)
  412. {
  413. if(c < 33)
  414. {
  415. width += 5;
  416. }
  417. else
  418. {
  419. p = W_CacheLumpNum(FontBBaseLump+c-33, PU_CACHE);
  420. width += p->width-1;
  421. }
  422. }
  423. return(width);
  424. }
  425. //---------------------------------------------------------------------------
  426. //
  427. // PROC MN_Ticker
  428. //
  429. //---------------------------------------------------------------------------
  430. void MN_Ticker(void)
  431. {
  432. if(MenuActive == false)
  433. {
  434. return;
  435. }
  436. MenuTime++;
  437. }
  438. //---------------------------------------------------------------------------
  439. //
  440. // PROC MN_Drawer
  441. //
  442. //---------------------------------------------------------------------------
  443. char *QuitEndMsg[] =
  444. {
  445. "ARE YOU SURE YOU WANT TO QUIT?",
  446. "ARE YOU SURE YOU WANT TO END THE GAME?",
  447. "DO YOU WANT TO QUICKSAVE THE GAME NAMED",
  448. "DO YOU WANT TO QUICKLOAD THE GAME NAMED",
  449. "ARE YOU SURE YOU WANT TO SUICIDE?"
  450. };
  451. #define BETA_FLASH_TEXT "BETA"
  452. void MN_Drawer(void)
  453. {
  454. int i;
  455. int x;
  456. int y;
  457. MenuItem_t *item;
  458. char *selName;
  459. #ifdef TIMEBOMB
  460. // Beta blinker ***
  461. if(leveltime&16)
  462. {
  463. MN_DrTextA( BETA_FLASH_TEXT,
  464. 160-(MN_TextAWidth(BETA_FLASH_TEXT)>>1), 12);
  465. }
  466. #endif // TIMEBOMB
  467. if(MenuActive == false)
  468. {
  469. if(askforquit)
  470. {
  471. MN_DrTextA(QuitEndMsg[typeofask-1], 160-
  472. MN_TextAWidth(QuitEndMsg[typeofask-1])/2, 80);
  473. if(typeofask == 3)
  474. {
  475. MN_DrTextA(SlotText[quicksave-1], 160-
  476. MN_TextAWidth(SlotText[quicksave-1])/2, 90);
  477. MN_DrTextA("?", 160+
  478. MN_TextAWidth(SlotText[quicksave-1])/2, 90);
  479. }
  480. if(typeofask == 4)
  481. {
  482. MN_DrTextA(SlotText[quickload-1], 160-
  483. MN_TextAWidth(SlotText[quickload-1])/2, 90);
  484. MN_DrTextA("?", 160+
  485. MN_TextAWidth(SlotText[quicksave-1])/2, 90);
  486. }
  487. UpdateState |= I_FULLSCRN;
  488. }
  489. return;
  490. }
  491. else
  492. {
  493. UpdateState |= I_FULLSCRN;
  494. if(InfoType)
  495. {
  496. MN_DrawInfo();
  497. return;
  498. }
  499. if(screenblocks < 10)
  500. {
  501. BorderNeedRefresh = true;
  502. }
  503. if(CurrentMenu->drawFunc != NULL)
  504. {
  505. CurrentMenu->drawFunc();
  506. }
  507. x = CurrentMenu->x;
  508. y = CurrentMenu->y;
  509. item = CurrentMenu->items;
  510. for(i = 0; i < CurrentMenu->itemCount; i++)
  511. {
  512. if(item->type != ITT_EMPTY && item->text)
  513. {
  514. MN_DrTextB(item->text, x, y);
  515. }
  516. y += ITEM_HEIGHT;
  517. item++;
  518. }
  519. y = CurrentMenu->y+(CurrentItPos*ITEM_HEIGHT)+SELECTOR_YOFFSET;
  520. selName = MenuTime&16 ? "M_SLCTR1" : "M_SLCTR2";
  521. V_DrawPatch(x+SELECTOR_XOFFSET, y,
  522. W_CacheLumpName(selName, PU_CACHE));
  523. }
  524. }
  525. //---------------------------------------------------------------------------
  526. //
  527. // PROC DrawMainMenu
  528. //
  529. //---------------------------------------------------------------------------
  530. static void DrawMainMenu(void)
  531. {
  532. int frame;
  533. frame = (MenuTime/5)%7;
  534. V_DrawPatch(88, 0, W_CacheLumpName("M_HTIC", PU_CACHE));
  535. // Old Gold skull positions: (40, 10) and (232, 10)
  536. V_DrawPatch(37, 80, W_CacheLumpNum(MauloBaseLump+(frame+2)%7,
  537. PU_CACHE));
  538. V_DrawPatch(278, 80, W_CacheLumpNum(MauloBaseLump+frame, PU_CACHE));
  539. }
  540. //==========================================================================
  541. //
  542. // DrawClassMenu
  543. //
  544. //==========================================================================
  545. static void DrawClassMenu(void)
  546. {
  547. pclass_t class;
  548. static char *boxLumpName[3] =
  549. {
  550. "m_fbox",
  551. "m_cbox",
  552. "m_mbox"
  553. };
  554. static char *walkLumpName[3] =
  555. {
  556. "m_fwalk1",
  557. "m_cwalk1",
  558. "m_mwalk1"
  559. };
  560. MN_DrTextB("CHOOSE CLASS:", 34, 24);
  561. class = (pclass_t)CurrentMenu->items[CurrentItPos].option;
  562. V_DrawPatch(174, 8, W_CacheLumpName(boxLumpName[class], PU_CACHE));
  563. V_DrawPatch(174+24, 8+12,
  564. W_CacheLumpNum(W_GetNumForName(walkLumpName[class])
  565. +((MenuTime>>3)&3), PU_CACHE));
  566. }
  567. //---------------------------------------------------------------------------
  568. //
  569. // PROC DrawSkillMenu
  570. //
  571. //---------------------------------------------------------------------------
  572. static void DrawSkillMenu(void)
  573. {
  574. MN_DrTextB("CHOOSE SKILL LEVEL:", 74, 16);
  575. }
  576. //---------------------------------------------------------------------------
  577. //
  578. // PROC DrawFilesMenu
  579. //
  580. //---------------------------------------------------------------------------
  581. static void DrawFilesMenu(void)
  582. {
  583. // clear out the quicksave/quickload stuff
  584. quicksave = 0;
  585. quickload = 0;
  586. P_ClearMessage(&players[consoleplayer]);
  587. }
  588. //---------------------------------------------------------------------------
  589. //
  590. // PROC DrawLoadMenu
  591. //
  592. //---------------------------------------------------------------------------
  593. static void DrawLoadMenu(void)
  594. {
  595. MN_DrTextB("LOAD GAME", 160-MN_TextBWidth("LOAD GAME")/2, 10);
  596. if(!slottextloaded)
  597. {
  598. MN_LoadSlotText();
  599. }
  600. DrawFileSlots(&LoadMenu);
  601. }
  602. //---------------------------------------------------------------------------
  603. //
  604. // PROC DrawSaveMenu
  605. //
  606. //---------------------------------------------------------------------------
  607. static void DrawSaveMenu(void)
  608. {
  609. MN_DrTextB("SAVE GAME", 160-MN_TextBWidth("SAVE GAME")/2, 10);
  610. if(!slottextloaded)
  611. {
  612. MN_LoadSlotText();
  613. }
  614. DrawFileSlots(&SaveMenu);
  615. }
  616. //===========================================================================
  617. //
  618. // MN_LoadSlotText
  619. //
  620. // For each slot, looks for save games and reads the description field.
  621. //
  622. //===========================================================================
  623. void MN_LoadSlotText(void)
  624. {
  625. int slot;
  626. FILE *fp;
  627. char name[100];
  628. char versionText[HXS_VERSION_TEXT_LENGTH];
  629. char description[HXS_DESCRIPTION_LENGTH];
  630. boolean found;
  631. for(slot = 0; slot < 6; slot++)
  632. {
  633. found = false;
  634. sprintf(name, "%shex%d.hxs", SavePath, slot);
  635. fp = fopen(name, "rb");
  636. if(fp)
  637. {
  638. fread(description, HXS_DESCRIPTION_LENGTH, 1, fp);
  639. fread(versionText, HXS_VERSION_TEXT_LENGTH, 1, fp);
  640. fclose(fp);
  641. if(!strcmp(versionText, HXS_VERSION_TEXT))
  642. {
  643. found = true;
  644. }
  645. }
  646. if(found)
  647. {
  648. memcpy(SlotText[slot], description, SLOTTEXTLEN);
  649. SlotStatus[slot] = 1;
  650. }
  651. else
  652. {
  653. memset(SlotText[slot], 0, SLOTTEXTLEN);
  654. SlotStatus[slot] = 0;
  655. }
  656. }
  657. slottextloaded = true;
  658. }
  659. //---------------------------------------------------------------------------
  660. //
  661. // PROC DrawFileSlots
  662. //
  663. //---------------------------------------------------------------------------
  664. static void DrawFileSlots(Menu_t *menu)
  665. {
  666. int i;
  667. int x;
  668. int y;
  669. x = menu->x;
  670. y = menu->y;
  671. for(i = 0; i < 6; i++)
  672. {
  673. V_DrawPatch(x, y, W_CacheLumpName("M_FSLOT", PU_CACHE));
  674. if(SlotStatus[i])
  675. {
  676. MN_DrTextA(SlotText[i], x+5, y+5);
  677. }
  678. y += ITEM_HEIGHT;
  679. }
  680. }
  681. //---------------------------------------------------------------------------
  682. //
  683. // PROC DrawOptionsMenu
  684. //
  685. //---------------------------------------------------------------------------
  686. static void DrawOptionsMenu(void)
  687. {
  688. if(messageson)
  689. {
  690. MN_DrTextB("ON", 196, 50);
  691. }
  692. else
  693. {
  694. MN_DrTextB("OFF", 196, 50);
  695. }
  696. DrawSlider(&OptionsMenu, 3, 10, mouseSensitivity);
  697. }
  698. //---------------------------------------------------------------------------
  699. //
  700. // PROC DrawOptions2Menu
  701. //
  702. //---------------------------------------------------------------------------
  703. static void DrawOptions2Menu(void)
  704. {
  705. DrawSlider(&Options2Menu, 1, 9, screenblocks-3);
  706. DrawSlider(&Options2Menu, 3, 16, snd_MaxVolume);
  707. DrawSlider(&Options2Menu, 5, 16, snd_MusicVolume);
  708. }
  709. //---------------------------------------------------------------------------
  710. //
  711. // PROC SCQuitGame
  712. //
  713. //---------------------------------------------------------------------------
  714. static void SCQuitGame(int option)
  715. {
  716. MenuActive = false;
  717. askforquit = true;
  718. typeofask = 1; //quit game
  719. if(!netgame && !demoplayback)
  720. {
  721. paused = true;
  722. }
  723. }
  724. //---------------------------------------------------------------------------
  725. //
  726. // PROC SCEndGame
  727. //
  728. //---------------------------------------------------------------------------
  729. static void SCEndGame(int option)
  730. {
  731. if(demoplayback)
  732. {
  733. return;
  734. }
  735. if(SCNetCheck(3))
  736. {
  737. MenuActive = false;
  738. askforquit = true;
  739. typeofask = 2; //endgame
  740. if(!netgame && !demoplayback)
  741. {
  742. paused = true;
  743. }
  744. }
  745. }
  746. //---------------------------------------------------------------------------
  747. //
  748. // PROC SCMessages
  749. //
  750. //---------------------------------------------------------------------------
  751. static void SCMessages(int option)
  752. {
  753. messageson ^= 1;
  754. if(messageson)
  755. {
  756. P_SetMessage(&players[consoleplayer], "MESSAGES ON", true);
  757. }
  758. else
  759. {
  760. P_SetMessage(&players[consoleplayer], "MESSAGES OFF", true);
  761. }
  762. S_StartSound(NULL, SFX_CHAT);
  763. }
  764. //===========================================================================
  765. //
  766. // SCNetCheck
  767. //
  768. //===========================================================================
  769. static boolean SCNetCheck(int option)
  770. {
  771. if(!netgame)
  772. {
  773. return true;
  774. }
  775. switch(option)
  776. {
  777. case 1: // new game
  778. P_SetMessage(&players[consoleplayer],
  779. "YOU CAN'T START A NEW GAME IN NETPLAY!", true);
  780. break;
  781. case 2: // load game
  782. P_SetMessage(&players[consoleplayer],
  783. "YOU CAN'T LOAD A GAME IN NETPLAY!", true);
  784. break;
  785. case 3: // end game
  786. P_SetMessage(&players[consoleplayer],
  787. "YOU CAN'T END A GAME IN NETPLAY!", true);
  788. break;
  789. }
  790. MenuActive = false;
  791. S_StartSound(NULL, SFX_CHAT);
  792. return false;
  793. }
  794. //===========================================================================
  795. //
  796. // SCNetCheck2
  797. //
  798. //===========================================================================
  799. static void SCNetCheck2(int option)
  800. {
  801. SCNetCheck(option);
  802. return;
  803. }
  804. //---------------------------------------------------------------------------
  805. //
  806. // PROC SCLoadGame
  807. //
  808. //---------------------------------------------------------------------------
  809. static void SCLoadGame(int option)
  810. {
  811. if(!SlotStatus[option])
  812. { // Don't try to load from an empty slot
  813. return;
  814. }
  815. G_LoadGame(option);
  816. MN_DeactivateMenu();
  817. BorderNeedRefresh = true;
  818. if(quickload == -1)
  819. {
  820. quickload = option+1;
  821. P_ClearMessage(&players[consoleplayer]);
  822. }
  823. }
  824. //---------------------------------------------------------------------------
  825. //
  826. // PROC SCSaveGame
  827. //
  828. //---------------------------------------------------------------------------
  829. static void SCSaveGame(int option)
  830. {
  831. char *ptr;
  832. if(!FileMenuKeySteal)
  833. {
  834. FileMenuKeySteal = true;
  835. strcpy(oldSlotText, SlotText[option]);
  836. ptr = SlotText[option];
  837. while(*ptr)
  838. {
  839. ptr++;
  840. }
  841. *ptr = '[';
  842. *(ptr+1) = 0;
  843. SlotStatus[option]++;
  844. currentSlot = option;
  845. slotptr = ptr-SlotText[option];
  846. return;
  847. }
  848. else
  849. {
  850. G_SaveGame(option, SlotText[option]);
  851. FileMenuKeySteal = false;
  852. MN_DeactivateMenu();
  853. }
  854. BorderNeedRefresh = true;
  855. if(quicksave == -1)
  856. {
  857. quicksave = option+1;
  858. P_ClearMessage(&players[consoleplayer]);
  859. }
  860. }
  861. //==========================================================================
  862. //
  863. // SCClass
  864. //
  865. //==========================================================================
  866. static void SCClass(int option)
  867. {
  868. if(netgame)
  869. {
  870. P_SetMessage(&players[consoleplayer],
  871. "YOU CAN'T START A NEW GAME FROM WITHIN A NETGAME!", true);
  872. return;
  873. }
  874. MenuPClass = option;
  875. switch(MenuPClass)
  876. {
  877. case PCLASS_FIGHTER:
  878. SkillMenu.x = 120;
  879. SkillItems[0].text = "SQUIRE";
  880. SkillItems[1].text = "KNIGHT";
  881. SkillItems[2].text = "WARRIOR";
  882. SkillItems[3].text = "BERSERKER";
  883. SkillItems[4].text = "TITAN";
  884. break;
  885. case PCLASS_CLERIC:
  886. SkillMenu.x = 116;
  887. SkillItems[0].text = "ALTAR BOY";
  888. SkillItems[1].text = "ACOLYTE";
  889. SkillItems[2].text = "PRIEST";
  890. SkillItems[3].text = "CARDINAL";
  891. SkillItems[4].text = "POPE";
  892. break;
  893. case PCLASS_MAGE:
  894. SkillMenu.x = 112;
  895. SkillItems[0].text = "APPRENTICE";
  896. SkillItems[1].text = "ENCHANTER";
  897. SkillItems[2].text = "SORCERER";
  898. SkillItems[3].text = "WARLOCK";
  899. SkillItems[4].text = "ARCHIMAGE";
  900. break;
  901. }
  902. SetMenu(MENU_SKILL);
  903. }
  904. //---------------------------------------------------------------------------
  905. //
  906. // PROC SCSkill
  907. //
  908. //---------------------------------------------------------------------------
  909. static void SCSkill(int option)
  910. {
  911. extern int SB_state;
  912. PlayerClass[consoleplayer] = MenuPClass;
  913. G_DeferredNewGame(option);
  914. SB_SetClassData();
  915. SB_state = -1;
  916. MN_DeactivateMenu();
  917. }
  918. //---------------------------------------------------------------------------
  919. //
  920. // PROC SCMouseSensi
  921. //
  922. //---------------------------------------------------------------------------
  923. static void SCMouseSensi(int option)
  924. {
  925. if(option == RIGHT_DIR)
  926. {
  927. if(mouseSensitivity < 9)
  928. {
  929. mouseSensitivity++;
  930. }
  931. }
  932. else if(mouseSensitivity)
  933. {
  934. mouseSensitivity--;
  935. }
  936. }
  937. //---------------------------------------------------------------------------
  938. //
  939. // PROC SCSfxVolume
  940. //
  941. //---------------------------------------------------------------------------
  942. static void SCSfxVolume(int option)
  943. {
  944. if(option == RIGHT_DIR)
  945. {
  946. if(snd_MaxVolume < 15)
  947. {
  948. snd_MaxVolume++;
  949. }
  950. }
  951. else if(snd_MaxVolume)
  952. {
  953. snd_MaxVolume--;
  954. }
  955. soundchanged = true; // we'll set it when we leave the menu
  956. }
  957. //---------------------------------------------------------------------------
  958. //
  959. // PROC SCMusicVolume
  960. //
  961. //---------------------------------------------------------------------------
  962. static void SCMusicVolume(int option)
  963. {
  964. if(option == RIGHT_DIR)
  965. {
  966. if(snd_MusicVolume < 15)
  967. {
  968. snd_MusicVolume++;
  969. }
  970. }
  971. else if(snd_MusicVolume)
  972. {
  973. snd_MusicVolume--;
  974. }
  975. S_SetMusicVolume();
  976. }
  977. //---------------------------------------------------------------------------
  978. //
  979. // PROC SCScreenSize
  980. //
  981. //---------------------------------------------------------------------------
  982. static void SCScreenSize(int option)
  983. {
  984. if(option == RIGHT_DIR)
  985. {
  986. if(screenblocks < 11)
  987. {
  988. screenblocks++;
  989. }
  990. }
  991. else if(screenblocks > 3)
  992. {
  993. screenblocks--;
  994. }
  995. R_SetViewSize(screenblocks, detailLevel);
  996. }
  997. //---------------------------------------------------------------------------
  998. //
  999. // PROC SCInfo
  1000. //
  1001. //---------------------------------------------------------------------------
  1002. static void SCInfo(int option)
  1003. {
  1004. InfoType = 1;
  1005. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1006. if(!netgame && !demoplayback)
  1007. {
  1008. paused = true;
  1009. }
  1010. }
  1011. //---------------------------------------------------------------------------
  1012. //
  1013. // FUNC MN_Responder
  1014. //
  1015. //---------------------------------------------------------------------------
  1016. boolean MN_Responder(event_t *event)
  1017. {
  1018. int key;
  1019. int i;
  1020. MenuItem_t *item;
  1021. extern boolean automapactive;
  1022. static boolean shiftdown;
  1023. extern void H2_StartTitle(void);
  1024. extern void G_CheckDemoStatus(void);
  1025. char *textBuffer;
  1026. if(event->data1 == KEY_RSHIFT)
  1027. {
  1028. shiftdown = (event->type == ev_keydown);
  1029. }
  1030. if(event->type != ev_keydown)
  1031. {
  1032. return(false);
  1033. }
  1034. key = event->data1;
  1035. if(InfoType)
  1036. {
  1037. if(shareware)
  1038. {
  1039. InfoType = (InfoType+1)%5;
  1040. }
  1041. else
  1042. {
  1043. InfoType = (InfoType+1)%4;
  1044. }
  1045. if(key == KEY_ESCAPE)
  1046. {
  1047. InfoType = 0;
  1048. }
  1049. if(!InfoType)
  1050. {
  1051. if(!netgame && !demoplayback)
  1052. {
  1053. paused = false;
  1054. }
  1055. MN_DeactivateMenu();
  1056. SB_state = -1; //refresh the statbar
  1057. BorderNeedRefresh = true;
  1058. }
  1059. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1060. return(true); //make the info screen eat the keypress
  1061. }
  1062. if(ravpic && key == KEY_F1)
  1063. {
  1064. G_ScreenShot();
  1065. return(true);
  1066. }
  1067. if(askforquit)
  1068. {
  1069. switch(key)
  1070. {
  1071. case 'y':
  1072. if(askforquit)
  1073. {
  1074. switch(typeofask)
  1075. {
  1076. case 1:
  1077. G_CheckDemoStatus();
  1078. I_Quit();
  1079. break;
  1080. case 2:
  1081. P_ClearMessage(&players[consoleplayer]);
  1082. typeofask = 0;
  1083. askforquit = false;
  1084. paused = false;
  1085. I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
  1086. H2_StartTitle(); // go to intro/demo mode.
  1087. break;
  1088. case 3:
  1089. P_SetMessage(&players[consoleplayer],
  1090. "QUICKSAVING....", false);
  1091. FileMenuKeySteal = true;
  1092. SCSaveGame(quicksave-1);
  1093. askforquit = false;
  1094. typeofask = 0;
  1095. BorderNeedRefresh = true;
  1096. return true;
  1097. case 4:
  1098. P_SetMessage(&players[consoleplayer],
  1099. "QUICKLOADING....", false);
  1100. SCLoadGame(quickload-1);
  1101. askforquit = false;
  1102. typeofask = 0;
  1103. BorderNeedRefresh = true;
  1104. return true;
  1105. case 5:
  1106. askforquit = false;
  1107. typeofask = 0;
  1108. BorderNeedRefresh = true;
  1109. mn_SuicideConsole = true;
  1110. return true;
  1111. break;
  1112. default:
  1113. return true; // eat the 'y' keypress
  1114. }
  1115. }
  1116. return false;
  1117. case 'n':
  1118. case KEY_ESCAPE:
  1119. if(askforquit)
  1120. {
  1121. players[consoleplayer].messageTics = 0;
  1122. askforquit = false;
  1123. typeofask = 0;
  1124. paused = false;
  1125. UpdateState |= I_FULLSCRN;
  1126. BorderNeedRefresh = true;
  1127. return true;
  1128. }
  1129. return false;
  1130. }
  1131. return false; // don't let the keys filter thru
  1132. }
  1133. if(MenuActive == false && !chatmodeon)
  1134. {
  1135. switch(key)
  1136. {
  1137. case KEY_MINUS:
  1138. if(automapactive)
  1139. { // Don't screen size in automap
  1140. return(false);
  1141. }
  1142. SCScreenSize(LEFT_DIR);
  1143. S_StartSound(NULL, SFX_PICKUP_KEY);
  1144. BorderNeedRefresh = true;
  1145. UpdateState |= I_FULLSCRN;
  1146. return(true);
  1147. case KEY_EQUALS:
  1148. if(automapactive)
  1149. { // Don't screen size in automap
  1150. return(false);
  1151. }
  1152. SCScreenSize(RIGHT_DIR);
  1153. S_StartSound(NULL, SFX_PICKUP_KEY);
  1154. BorderNeedRefresh = true;
  1155. UpdateState |= I_FULLSCRN;
  1156. return(true);
  1157. #ifdef __NeXT__
  1158. case 'q':
  1159. MenuActive = false;
  1160. askforquit = true;
  1161. typeofask = 5; // suicide
  1162. return true;
  1163. #endif
  1164. #ifndef __NeXT__
  1165. case KEY_F1: // help screen
  1166. SCInfo(0); // start up info screens
  1167. MenuActive = true;
  1168. return(true);
  1169. case KEY_F2: // save game
  1170. if(gamestate == GS_LEVEL && !demoplayback)
  1171. {
  1172. MenuActive = true;
  1173. FileMenuKeySteal = false;
  1174. MenuTime = 0;
  1175. CurrentMenu = &SaveMenu;
  1176. CurrentItPos = CurrentMenu->oldItPos;
  1177. if(!netgame && !demoplayback)
  1178. {
  1179. paused = true;
  1180. }
  1181. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1182. slottextloaded = false; //reload the slot text, when needed
  1183. }
  1184. return true;
  1185. case KEY_F3: // load game
  1186. if(SCNetCheck(2))
  1187. {
  1188. MenuActive = true;
  1189. FileMenuKeySteal = false;
  1190. MenuTime = 0;
  1191. CurrentMenu = &LoadMenu;
  1192. CurrentItPos = CurrentMenu->oldItPos;
  1193. if(!netgame && !demoplayback)
  1194. {
  1195. paused = true;
  1196. }
  1197. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1198. slottextloaded = false; //reload the slot text, when needed
  1199. }
  1200. return true;
  1201. case KEY_F4: // volume
  1202. MenuActive = true;
  1203. FileMenuKeySteal = false;
  1204. MenuTime = 0;
  1205. CurrentMenu = &Options2Menu;
  1206. CurrentItPos = CurrentMenu->oldItPos;
  1207. if(!netgame && !demoplayback)
  1208. {
  1209. paused = true;
  1210. }
  1211. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1212. slottextloaded = false; //reload the slot text, when needed
  1213. return true;
  1214. case KEY_F5:
  1215. MenuActive = false;
  1216. askforquit = true;
  1217. typeofask = 5; // suicide
  1218. return true;
  1219. case KEY_F6: // quicksave
  1220. if(gamestate == GS_LEVEL && !demoplayback)
  1221. {
  1222. if(!quicksave || quicksave == -1)
  1223. {
  1224. MenuActive = true;
  1225. FileMenuKeySteal = false;
  1226. MenuTime = 0;
  1227. CurrentMenu = &SaveMenu;
  1228. CurrentItPos = CurrentMenu->oldItPos;
  1229. if(!netgame && !demoplayback)
  1230. {
  1231. paused = true;
  1232. }
  1233. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1234. slottextloaded = false; //reload the slot text
  1235. quicksave = -1;
  1236. P_SetMessage(&players[consoleplayer],
  1237. "CHOOSE A QUICKSAVE SLOT", true);
  1238. }
  1239. else
  1240. {
  1241. askforquit = true;
  1242. typeofask = 3;
  1243. if(!netgame && !demoplayback)
  1244. {
  1245. paused = true;
  1246. }
  1247. S_StartSound(NULL, SFX_CHAT);
  1248. }
  1249. }
  1250. return true;
  1251. case KEY_F7: // endgame
  1252. if(SCNetCheck(3))
  1253. {
  1254. if(gamestate == GS_LEVEL && !demoplayback)
  1255. {
  1256. S_StartSound(NULL, SFX_CHAT);
  1257. SCEndGame(0);
  1258. }
  1259. }
  1260. return true;
  1261. case KEY_F8: // toggle messages
  1262. SCMessages(0);
  1263. return true;
  1264. case KEY_F9: // quickload
  1265. if(SCNetCheck(2))
  1266. {
  1267. if(!quickload || quickload == -1)
  1268. {
  1269. MenuActive = true;
  1270. FileMenuKeySteal = false;
  1271. MenuTime = 0;
  1272. CurrentMenu = &LoadMenu;
  1273. CurrentItPos = CurrentMenu->oldItPos;
  1274. if(!netgame && !demoplayback)
  1275. {
  1276. paused = true;
  1277. }
  1278. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1279. slottextloaded = false; // reload the slot text
  1280. quickload = -1;
  1281. P_SetMessage(&players[consoleplayer],
  1282. "CHOOSE A QUICKLOAD SLOT", true);
  1283. }
  1284. else
  1285. {
  1286. askforquit = true;
  1287. if(!netgame && !demoplayback)
  1288. {
  1289. paused = true;
  1290. }
  1291. typeofask = 4;
  1292. S_StartSound(NULL, SFX_CHAT);
  1293. }
  1294. }
  1295. return true;
  1296. case KEY_F10: // quit
  1297. if(gamestate == GS_LEVEL || gamestate == GS_FINALE)
  1298. {
  1299. SCQuitGame(0);
  1300. S_StartSound(NULL, SFX_CHAT);
  1301. }
  1302. return true;
  1303. case KEY_F11: // F11 - gamma mode correction
  1304. usegamma++;
  1305. if(usegamma > 4)
  1306. {
  1307. usegamma = 0;
  1308. }
  1309. SB_PaletteFlash(true); // force change
  1310. P_SetMessage(&players[consoleplayer], GammaText[usegamma],
  1311. false);
  1312. return true;
  1313. case KEY_F12: // F12 - reload current map (devmaps mode)
  1314. if(netgame || DevMaps == false)
  1315. {
  1316. return false;
  1317. }
  1318. if(gamekeydown[key_speed])
  1319. { // Monsters ON
  1320. nomonsters = false;
  1321. }
  1322. if(gamekeydown[key_strafe])
  1323. { // Monsters OFF
  1324. nomonsters = true;
  1325. }
  1326. G_DeferedInitNew(gameskill, gameepisode, gamemap);
  1327. P_SetMessage(&players[consoleplayer], TXT_CHEATWARP,
  1328. false);
  1329. return true;
  1330. #endif
  1331. }
  1332. }
  1333. if(MenuActive == false)
  1334. {
  1335. if(key == KEY_ESCAPE || gamestate == GS_DEMOSCREEN || demoplayback)
  1336. {
  1337. MN_ActivateMenu();
  1338. return(true);
  1339. }
  1340. return(false);
  1341. }
  1342. if(!FileMenuKeySteal)
  1343. {
  1344. item = &CurrentMenu->items[CurrentItPos];
  1345. switch(key)
  1346. {
  1347. case KEY_DOWNARROW:
  1348. do
  1349. {
  1350. if(CurrentItPos+1 > CurrentMenu->itemCount-1)
  1351. {
  1352. CurrentItPos = 0;
  1353. }
  1354. else
  1355. {
  1356. CurrentItPos++;
  1357. }
  1358. } while(CurrentMenu->items[CurrentItPos].type == ITT_EMPTY);
  1359. S_StartSound(NULL, SFX_FIGHTER_HAMMER_HITWALL);
  1360. return(true);
  1361. break;
  1362. case KEY_UPARROW:
  1363. do
  1364. {
  1365. if(CurrentItPos == 0)
  1366. {
  1367. CurrentItPos = CurrentMenu->itemCount-1;
  1368. }
  1369. else
  1370. {
  1371. CurrentItPos--;
  1372. }
  1373. } while(CurrentMenu->items[CurrentItPos].type == ITT_EMPTY);
  1374. S_StartSound(NULL, SFX_FIGHTER_HAMMER_HITWALL);
  1375. return(true);
  1376. break;
  1377. case KEY_LEFTARROW:
  1378. if(item->type == ITT_LRFUNC && item->func != NULL)
  1379. {
  1380. item->func(LEFT_DIR);
  1381. S_StartSound(NULL, SFX_PICKUP_KEY);
  1382. }
  1383. return(true);
  1384. break;
  1385. case KEY_RIGHTARROW:
  1386. if(item->type == ITT_LRFUNC && item->func != NULL)
  1387. {
  1388. item->func(RIGHT_DIR);
  1389. S_StartSound(NULL, SFX_PICKUP_KEY);
  1390. }
  1391. return(true);
  1392. break;
  1393. case KEY_ENTER:
  1394. if(item->type == ITT_SETMENU)
  1395. {
  1396. if(item->func != NULL)
  1397. {
  1398. item->func(item->option);
  1399. }
  1400. SetMenu(item->menu);
  1401. }
  1402. else if(item->func != NULL)
  1403. {
  1404. CurrentMenu->oldItPos = CurrentItPos;
  1405. if(item->type == ITT_LRFUNC)
  1406. {
  1407. item->func(RIGHT_DIR);
  1408. }
  1409. else if(item->type == ITT_EFUNC)
  1410. {
  1411. item->func(item->option);
  1412. }
  1413. }
  1414. S_StartSound(NULL, SFX_DOOR_LIGHT_CLOSE);
  1415. return(true);
  1416. break;
  1417. case KEY_ESCAPE:
  1418. MN_DeactivateMenu();
  1419. return(true);
  1420. case KEY_BACKSPACE:
  1421. S_StartSound(NULL, SFX_PICKUP_KEY);
  1422. if(CurrentMenu->prevMenu == MENU_NONE)
  1423. {
  1424. MN_DeactivateMenu();
  1425. }
  1426. else
  1427. {
  1428. SetMenu(CurrentMenu->prevMenu);
  1429. }
  1430. return(true);
  1431. default:
  1432. for(i = 0; i < CurrentMenu->itemCount; i++)
  1433. {
  1434. if(CurrentMenu->items[i].text)
  1435. {
  1436. if(toupper(key)
  1437. == toupper(CurrentMenu->items[i].text[0]))
  1438. {
  1439. CurrentItPos = i;
  1440. return(true);
  1441. }
  1442. }
  1443. }
  1444. break;
  1445. }
  1446. return(false);
  1447. }
  1448. else
  1449. { // Editing file names
  1450. textBuffer = &SlotText[currentSlot][slotptr];
  1451. if(key == KEY_BACKSPACE)
  1452. {
  1453. if(slotptr)
  1454. {
  1455. *textBuffer-- = 0;
  1456. *textBuffer = ASCII_CURSOR;
  1457. slotptr--;
  1458. }
  1459. return(true);
  1460. }
  1461. if(key == KEY_ESCAPE)
  1462. {
  1463. memset(SlotText[currentSlot], 0, SLOTTEXTLEN+2);
  1464. strcpy(SlotText[currentSlot], oldSlotText);
  1465. SlotStatus[currentSlot]--;
  1466. MN_DeactivateMenu();
  1467. return(true);
  1468. }
  1469. if(key == KEY_ENTER)
  1470. {
  1471. SlotText[currentSlot][slotptr] = 0; // clear the cursor
  1472. item = &CurrentMenu->items[CurrentItPos];
  1473. CurrentMenu->oldItPos = CurrentItPos;
  1474. if(item->type == ITT_EFUNC)
  1475. {
  1476. item->func(item->option);
  1477. if(item->menu != MENU_NONE)
  1478. {
  1479. SetMenu(item->menu);
  1480. }
  1481. }
  1482. return(true);
  1483. }
  1484. if(slotptr < SLOTTEXTLEN && key != KEY_BACKSPACE)
  1485. {
  1486. if((key >= 'a' && key <= 'z'))
  1487. {
  1488. *textBuffer++ = key-32;
  1489. *textBuffer = ASCII_CURSOR;
  1490. slotptr++;
  1491. return(true);
  1492. }
  1493. if(((key >= '0' && key <= '9') || key == ' '
  1494. || key == ',' || key == '.' || key == '-')
  1495. && !shiftdown)
  1496. {
  1497. *textBuffer++ = key;
  1498. *textBuffer = ASCII_CURSOR;
  1499. slotptr++;
  1500. return(true);
  1501. }
  1502. if(shiftdown && key == '1')
  1503. {
  1504. *textBuffer++ = '!';
  1505. *textBuffer = ASCII_CURSOR;
  1506. slotptr++;
  1507. return(true);
  1508. }
  1509. }
  1510. return(true);
  1511. }
  1512. return(false);
  1513. }
  1514. //---------------------------------------------------------------------------
  1515. //
  1516. // PROC MN_ActivateMenu
  1517. //
  1518. //---------------------------------------------------------------------------
  1519. void MN_ActivateMenu(void)
  1520. {
  1521. if(MenuActive)
  1522. {
  1523. return;
  1524. }
  1525. if(paused)
  1526. {
  1527. S_ResumeSound();
  1528. }
  1529. MenuActive = true;
  1530. FileMenuKeySteal = false;
  1531. MenuTime = 0;
  1532. CurrentMenu = &MainMenu;
  1533. CurrentItPos = CurrentMenu->oldItPos;
  1534. if(!netgame && !demoplayback)
  1535. {
  1536. paused = true;
  1537. }
  1538. S_StartSound(NULL, SFX_PLATFORM_STOP);
  1539. slottextloaded = false; //reload the slot text, when needed
  1540. }
  1541. //---------------------------------------------------------------------------
  1542. //
  1543. // PROC MN_DeactivateMenu
  1544. //
  1545. //---------------------------------------------------------------------------
  1546. void MN_DeactivateMenu(void)
  1547. {
  1548. CurrentMenu->oldItPos = CurrentItPos;
  1549. MenuActive = false;
  1550. if(!netgame)
  1551. {
  1552. paused = false;
  1553. }
  1554. S_StartSound(NULL, SFX_PLATFORM_STOP);
  1555. P_ClearMessage(&players[consoleplayer]);
  1556. }
  1557. //---------------------------------------------------------------------------
  1558. //
  1559. // PROC MN_DrawInfo
  1560. //
  1561. //---------------------------------------------------------------------------
  1562. void MN_DrawInfo(void)
  1563. {
  1564. I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
  1565. memcpy(screen, (byte *)W_CacheLumpNum(W_GetNumForName("TITLE")+InfoType,
  1566. PU_CACHE), SCREENWIDTH*SCREENHEIGHT);
  1567. // V_DrawPatch(0, 0, W_CacheLumpNum(W_GetNumForName("TITLE")+InfoType,
  1568. // PU_CACHE));
  1569. }
  1570. //---------------------------------------------------------------------------
  1571. //
  1572. // PROC SetMenu
  1573. //
  1574. //---------------------------------------------------------------------------
  1575. static void SetMenu(MenuType_t menu)
  1576. {
  1577. CurrentMenu->oldItPos = CurrentItPos;
  1578. CurrentMenu = Menus[menu];
  1579. CurrentItPos = CurrentMenu->oldItPos;
  1580. }
  1581. //---------------------------------------------------------------------------
  1582. //
  1583. // PROC DrawSlider
  1584. //
  1585. //---------------------------------------------------------------------------
  1586. static void DrawSlider(Menu_t *menu, int item, int width, int slot)
  1587. {
  1588. int x;
  1589. int y;
  1590. int x2;
  1591. int count;
  1592. x = menu->x+24;
  1593. y = menu->y+2+(item*ITEM_HEIGHT);
  1594. V_DrawPatch(x-32, y, W_CacheLumpName("M_SLDLT", PU_CACHE));
  1595. for(x2 = x, count = width; count--; x2 += 8)
  1596. {
  1597. V_DrawPatch(x2, y, W_CacheLumpName(count&1 ? "M_SLDMD1"
  1598. : "M_SLDMD2", PU_CACHE));
  1599. }
  1600. V_DrawPatch(x2, y, W_CacheLumpName("M_SLDRT", PU_CACHE));
  1601. V_DrawPatch(x+4+slot*8, y+7, W_CacheLumpName("M_SLDKB", PU_CACHE));
  1602. }