1 
2 /* MN_menu.c */
3 
4 #include <ctype.h>
5 #include "doomdef.h"
6 #include "p_local.h"
7 #include "r_local.h"
8 #include "soundst.h"
9 
10 #ifdef GL_HERETIC
11 #include "gl_struct.h"
12 #endif
13 
14 extern long do_grabMouse;
15 
16 /* Macros */
17 
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 
26 #ifndef GL_HERETIC
27 #define MNU_X(x)		x+(screenwidth-320)/2
28 #define MNU_Y(y)		y+(screenheight-200)/2
29 #else
30 #define MNU_X(x)		(int)((float)(x)*screenwidth/320.0f)
31 #define MNU_Y(y)		(int)((float)(y)*screenhright/200.0f)
32 boolean g_bFullScreen=FALSE;
33 #endif
34 
35 #ifdef GL_HERETIC
36 extern boolean g_bMlook;
37 #endif
38 
39 /* Types */
40 
41 typedef enum
42 {
43   ITT_EMPTY,
44   ITT_EFUNC,
45   ITT_LRFUNC,
46   ITT_SETMENU,
47   ITT_INERT
48 } ItemType_t;
49 
50 typedef enum
51 {
52   MENU_MAIN,
53   MENU_EPISODE,
54   MENU_SKILL,
55   MENU_OPTIONS,
56   MENU_OPTIONS2,
57   MENU_OPTIONS3,
58   MENU_FILES,
59   MENU_LOAD,
60   MENU_SAVE,
61   MENU_NONE
62 } MenuType_t;
63 
64 typedef struct
65 {
66   ItemType_t type;
67   char *text;
68   boolean (*func)(int option);
69   int option;
70   MenuType_t menu;
71 } MenuItem_t;
72 
73 typedef struct
74 {
75   int x;
76   int y;
77   void (*drawFunc)(void);
78   int itemCount;
79   MenuItem_t *items;
80   int oldItPos;
81   MenuType_t prevMenu;
82 } Menu_t;
83 
84 /* Private Functions */
85 
86 static void InitFonts(void);
87 static void SetMenu(MenuType_t menu);
88 static boolean SCNetCheck(int option);
89 static boolean SCQuitGame(int option);
90 static boolean SCEpisode(int option);
91 static boolean SCSkill(int option);
92 static boolean SCMouseXSensi(int option);
93 static boolean SCMouseYSensi(int option);
94 static boolean SCMouseLook(int option);
95 static boolean SCMouseInvert(int option);
96 static boolean SCMouseGrab(int option);
97 static boolean SCSfxVolume(int option);
98 static boolean SCMusicVolume(int option);
99 static boolean SCScreenSize(int option);
100 static boolean SCLoadGame(int option);
101 static boolean SCSaveGame(int option);
102 static boolean SCMessages(int option);
103 static boolean SCEndGame(int option);
104 static boolean SCInfo(int option);
105 static void DrawMainMenu(void);
106 static void DrawEpisodeMenu(void);
107 static void DrawSkillMenu(void);
108 static void DrawOptionsMenu(void);
109 static void DrawOptions2Menu(void);
110 static void DrawOptions3Menu(void);
111 static void DrawFileSlots(Menu_t *menu);
112 static void DrawFilesMenu(void);
113 static void MN_DrawInfo(void);
114 static void DrawLoadMenu(void);
115 static void DrawSaveMenu(void);
116 static void DrawSlider(Menu_t *menu, int item, int width, int slot);
117 void MN_LoadSlotText(void);
118 
119 /* External Data */
120 
121 extern int detailLevel;
122 extern long screenblocks;
123 
124 extern char* homedir;
125 
126 /* Public Data */
127 
128 boolean MenuActive;
129 int InfoType;
130 boolean messageson;
131 int FontABaseLump;
132 int FontBBaseLump;
133 
134 /* Private Data */
135 
136 static int SkullBaseLump;
137 static Menu_t *CurrentMenu;
138 static int CurrentItPos;
139 static int MenuEpisode;
140 static int MenuTime;
141 static boolean soundchanged;
142 
143 boolean askforquit;
144 int typeofask;
145 static boolean FileMenuKeySteal;
146 static boolean slottextloaded;
147 static char SlotText[6][SLOTTEXTLEN+2];
148 static char oldSlotText[SLOTTEXTLEN+2];
149 static int SlotStatus[6];
150 static int slotptr;
151 static int currentSlot;
152 static int quicksave;
153 static int quickload;
154 
155 static MenuItem_t MainItems[] =
156 {
157   { ITT_EFUNC, "NEW GAME", SCNetCheck, 1, MENU_EPISODE },
158   { ITT_SETMENU, "OPTIONS", NULL, 0, MENU_OPTIONS },
159   { ITT_SETMENU, "GAME FILES", NULL, 0, MENU_FILES },
160   { ITT_EFUNC, "INFO", SCInfo, 0, MENU_NONE },
161   { ITT_EFUNC, "QUIT GAME", SCQuitGame, 0, MENU_NONE }
162 };
163 
164 static Menu_t MainMenu =
165 {
166   110, 56,
167   DrawMainMenu,
168   5, MainItems,
169   0,
170   MENU_NONE
171 };
172 
173 static MenuItem_t EpisodeItems[] =
174 {
175   { ITT_EFUNC, "CITY OF THE DAMNED", SCEpisode, 1, MENU_NONE },
176   { ITT_EFUNC, "HELL'S MAW", SCEpisode, 2, MENU_NONE },
177   { ITT_EFUNC, "THE DOME OF D'SPARIL", SCEpisode, 3, MENU_NONE },
178   { ITT_EFUNC, "THE OSSUARY", SCEpisode, 4, MENU_NONE },
179   { ITT_EFUNC, "THE STAGNANT DEMESNE", SCEpisode, 5, MENU_NONE }
180 };
181 
182 static Menu_t EpisodeMenu =
183 {
184   80, 50,
185   DrawEpisodeMenu,
186   3, EpisodeItems,
187   0,
188   MENU_MAIN
189 };
190 
191 static MenuItem_t FilesItems[] =
192 {
193   { ITT_EFUNC, "LOAD GAME", SCNetCheck, 2, MENU_LOAD },
194   { ITT_SETMENU, "SAVE GAME", NULL, 0, MENU_SAVE }
195 };
196 
197 static Menu_t FilesMenu =
198 {
199   110, 60,
200   DrawFilesMenu,
201   2, FilesItems,
202   0,
203   MENU_MAIN
204 };
205 
206 static MenuItem_t LoadItems[] =
207 {
208   { ITT_EFUNC, NULL, SCLoadGame, 0, MENU_NONE },
209   { ITT_EFUNC, NULL, SCLoadGame, 1, MENU_NONE },
210   { ITT_EFUNC, NULL, SCLoadGame, 2, MENU_NONE },
211   { ITT_EFUNC, NULL, SCLoadGame, 3, MENU_NONE },
212   { ITT_EFUNC, NULL, SCLoadGame, 4, MENU_NONE },
213   { ITT_EFUNC, NULL, SCLoadGame, 5, MENU_NONE }
214 };
215 
216 static Menu_t LoadMenu =
217 {
218   70, 30,
219   DrawLoadMenu,
220   6, LoadItems,
221   0,
222   MENU_FILES
223 };
224 
225 static MenuItem_t SaveItems[] =
226 {
227   { ITT_EFUNC, NULL, SCSaveGame, 0, MENU_NONE },
228   { ITT_EFUNC, NULL, SCSaveGame, 1, MENU_NONE },
229   { ITT_EFUNC, NULL, SCSaveGame, 2, MENU_NONE },
230   { ITT_EFUNC, NULL, SCSaveGame, 3, MENU_NONE },
231   { ITT_EFUNC, NULL, SCSaveGame, 4, MENU_NONE },
232   { ITT_EFUNC, NULL, SCSaveGame, 5, MENU_NONE }
233 };
234 
235 static Menu_t SaveMenu =
236 {
237   70, 30,
238   DrawSaveMenu,
239   6, SaveItems,
240   0,
241   MENU_FILES
242 };
243 
244 static MenuItem_t SkillItems[] =
245 {
246   { ITT_EFUNC, "THOU NEEDETH A WET-NURSE", SCSkill, sk_baby, MENU_NONE },
247   { ITT_EFUNC, "YELLOWBELLIES-R-US", SCSkill, sk_easy, MENU_NONE },
248   { ITT_EFUNC, "BRINGEST THEM ONETH", SCSkill, sk_medium, MENU_NONE },
249   { ITT_EFUNC, "THOU ART A SMITE-MEISTER", SCSkill, sk_hard, MENU_NONE },
250   { ITT_EFUNC, "BLACK PLAGUE POSSESSES THEE",
251     SCSkill, sk_nightmare, MENU_NONE }
252 };
253 
254 static Menu_t SkillMenu =
255 {
256   38, 30,
257   DrawSkillMenu,
258   5, SkillItems,
259   2,
260   MENU_EPISODE
261 };
262 
263 static MenuItem_t OptionsItems[] =
264 {
265   { ITT_EFUNC, "END GAME", SCEndGame, 0, MENU_NONE },
266   { ITT_EFUNC, "MESSAGES : ", SCMessages, 0, MENU_NONE },
267   { ITT_SETMENU, "EFFECTS...", NULL, 0, MENU_OPTIONS2 },
268   { ITT_SETMENU, "CONTROLS...", NULL, 0, MENU_OPTIONS3 }
269 };
270 
271 static Menu_t OptionsMenu =
272 {
273   88, 50,
274   DrawOptionsMenu,
275   4, OptionsItems,
276   0,
277   MENU_MAIN
278 };
279 
280 static MenuItem_t Options2Items[] =
281 {
282   { ITT_LRFUNC, "SCREEN SIZE", SCScreenSize, 0, MENU_NONE },
283   { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
284   { ITT_LRFUNC, "SFX VOLUME", SCSfxVolume, 0, MENU_NONE },
285   { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
286   { ITT_LRFUNC, "MUSIC VOLUME", SCMusicVolume, 0, MENU_NONE },
287   { ITT_EMPTY, NULL, NULL, 0, MENU_NONE }
288 };
289 
290 static Menu_t Options2Menu =
291 {
292   90, 20,
293   DrawOptions2Menu,
294   6, Options2Items,
295   0,
296   MENU_OPTIONS
297 };
298 
299 static MenuItem_t Options3Items[] =
300 {
301   { ITT_EFUNC, "MOUSE LOOK : ", SCMouseLook, 0, MENU_NONE },
302   { ITT_EFUNC, "MOUSE INVERT Y : ", SCMouseInvert, 0, MENU_NONE },
303   { ITT_EFUNC, "GRAB MOUSE : ", SCMouseGrab, 0, MENU_NONE },
304   { ITT_LRFUNC, "MOUSE X-SENSITIVITY", SCMouseXSensi, 0, MENU_NONE },
305   { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
306   { ITT_LRFUNC, "MOUSE Y-SENSITIVITY", SCMouseYSensi, 0, MENU_NONE },
307   { ITT_EMPTY, NULL, NULL, 0, MENU_NONE },
308 };
309 
310 static Menu_t Options3Menu =
311 {
312   88, 30,
313   DrawOptions3Menu,
314   6, Options3Items,
315   0,
316   MENU_OPTIONS
317 };
318 
319 static Menu_t *Menus[] =
320 {
321   &MainMenu,
322   &EpisodeMenu,
323   &SkillMenu,
324   &OptionsMenu,
325   &Options2Menu,
326   &Options3Menu,
327   &FilesMenu,
328   &LoadMenu,
329   &SaveMenu
330 };
331 
332 
333 /*
334   //---------------------------------------------------------------------------
335   //
336   // PROC MN_Init
337   //
338   //---------------------------------------------------------------------------
339 */
MN_Init(void)340 void MN_Init(void)
341 {
342   InitFonts();
343   MenuActive = false;
344   messageson = true;
345 //  do_grabMouse = 1;
346 //  mouseLook = 1;
347 //  mouseInvert = 1;
348 #ifndef GL_HERETIC
349   SkullBaseLump = W_GetNumForName("M_SKL00");
350 #else
351   SkullBaseLump = GL_GetNumForName("M_SKL00");
352 #endif
353   if(ExtendedWAD)
354     { /* Add episodes 4 and 5 to the menu */
355       EpisodeMenu.itemCount = 5;
356       EpisodeMenu.y -= ITEM_HEIGHT;
357     }
358 }
359 
360 
361 /*
362   //---------------------------------------------------------------------------
363   //
364   // PROC InitFonts
365   //
366   //---------------------------------------------------------------------------
367 */
InitFonts(void)368 static void InitFonts(void)
369 {
370   FontABaseLump = W_GetNumForName("FONTA_S")+1;
371   FontBBaseLump = W_GetNumForName("FONTB_S")+1;
372 #ifdef GL_HERETIC
373   fn_vGLInitFonts();
374 #endif
375 }
376 
377 
378 /*
379   //---------------------------------------------------------------------------
380   //
381   // PROC MN_DrTextA
382   //
383   // Draw text using font A.
384   //
385   //---------------------------------------------------------------------------
386 */
MN_DrTextA(char * text,int x,int y)387 void MN_DrTextA(char *text, int x, int y)
388 {
389 #ifndef GL_HERETIC
390   char c;
391   patch_t *p;
392 
393   while((c = *text++) != 0)
394     {
395       if(c < 33)
396 	{
397 	  x += 5;
398 	}
399       else
400 	{
401 	  p = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
402 	  V_DrawPatch(x, y, p);
403 	  x += SHORT(p->width)-1;
404 	}
405     }
406 #else
407   GL_DrTextA(text,x,y);
408 #endif
409 }
410 
411 
412 /*
413   //---------------------------------------------------------------------------
414   //
415   // FUNC MN_TextAWidth
416   //
417   // Returns the pixel width of a string using font A.
418   //
419   //---------------------------------------------------------------------------
420 */
MN_TextAWidth(char * text)421 int MN_TextAWidth(char *text)
422 {
423   char c;
424   int width;
425   patch_t *p;
426 
427   width = 0;
428   while((c = *text++) != 0)
429     {
430       if(c < 33)
431 	{
432 	  width += 5;
433 	}
434       else
435 	{
436 	  p = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
437 	  width += SHORT(p->width)-1;
438 	}
439     }
440   return(width);
441 }
442 
443 
444 /*
445   //---------------------------------------------------------------------------
446   //
447   // PROC MN_DrTextB
448   //
449   // Draw text using font B.
450   //
451   //---------------------------------------------------------------------------
452 */
MN_DrTextB(char * text,int x,int y)453 void MN_DrTextB(char *text, int x, int y)
454 {
455 #ifndef GL_HERETIC
456   char c;
457   patch_t *p;
458 
459   while((c = *text++) != 0)
460     {
461       if(c < 33)
462 	{
463 	  x += 8;
464 	}
465       else
466 	{
467 	  p = W_CacheLumpNum(FontBBaseLump+c-33, PU_CACHE);
468 	  V_DrawPatch(x, y, p);
469 	  x += SHORT(p->width)-1;
470 	}
471     }
472 #else
473   GL_DrTextB(text,x,y);
474 #endif
475 }
476 
477 
478 /*
479   //---------------------------------------------------------------------------
480   //
481   // FUNC MN_TextBWidth
482   //
483   // Returns the pixel width of a string using font B.
484   //
485   //---------------------------------------------------------------------------
486 */
MN_TextBWidth(char * text)487 int MN_TextBWidth(char *text)
488 {
489   char c;
490   int width;
491   patch_t *p;
492 
493   width = 0;
494   while((c = *text++) != 0)
495     {
496       if(c < 33)
497 	{
498 	  width += 5;
499 	}
500       else
501 	{
502 	  p = W_CacheLumpNum(FontBBaseLump+c-33, PU_CACHE);
503 	  width += SHORT(p->width)-1;
504 	}
505     }
506   return(width);
507 }
508 
509 
510 /*
511   //---------------------------------------------------------------------------
512   //
513   // PROC MN_Ticker
514   //
515   //---------------------------------------------------------------------------
516 */
MN_Ticker(void)517 void MN_Ticker(void)
518 {
519   if(MenuActive == false)
520     {
521       return;
522     }
523   MenuTime++;
524 }
525 
526 
527 /*
528   //---------------------------------------------------------------------------
529   //
530   // PROC MN_Drawer
531   //
532   //---------------------------------------------------------------------------
533 */
534 char *QuitEndMsg[] =
535 {
536   "ARE YOU SURE YOU WANT TO QUIT?",
537   "ARE YOU SURE YOU WANT TO END THE GAME?",
538   "DO YOU WANT TO QUICKSAVE THE GAME NAMED",
539   "DO YOU WANT TO QUICKLOAD THE GAME NAMED"
540 };
541 
MN_Drawer(void)542 void MN_Drawer(void)
543 {
544   int i;
545   int x;
546   int y;
547   MenuItem_t *item;
548   char *selName;
549 
550   if(MenuActive == false)
551     {
552       if(askforquit)
553 	{
554 #ifdef GL_HERETIC
555 	  MN_DrTextA(QuitEndMsg[typeofask-1], 160-
556 		     MN_TextAWidth(QuitEndMsg[typeofask-1])/2, 80);
557 #else
558 	  MN_DrTextA(QuitEndMsg[typeofask-1], 160-
559 		     MN_TextAWidth(QuitEndMsg[typeofask-1])/2, Y_DISP+80);
560 #endif
561 	  if(typeofask == 3)
562 	    {
563 #ifdef GL_HERETIC
564 	      MN_DrTextA(SlotText[quicksave-1], 160-
565 			 MN_TextAWidth(SlotText[quicksave-1])/2, 90);
566 	      MN_DrTextA("?", 160+
567 			 MN_TextAWidth(SlotText[quicksave-1])/2, 90);
568 #else
569 	      MN_DrTextA(SlotText[quicksave-1], 160-
570 			 MN_TextAWidth(SlotText[quicksave-1])/2, Y_DISP+90);
571 	      MN_DrTextA("?", 160+
572 			 MN_TextAWidth(SlotText[quicksave-1])/2, Y_DISP+90);
573 #endif
574 	    }
575 	  if(typeofask == 4)
576 	    {
577 #ifdef GL_HERETIC
578 	      MN_DrTextA(SlotText[quickload-1], 160-
579 			 MN_TextAWidth(SlotText[quickload-1])/2, 90);
580 	      MN_DrTextA("?", 160+
581 			 MN_TextAWidth(SlotText[quickload-1])/2, 90);
582 #else
583 	      MN_DrTextA(SlotText[quickload-1], 160-
584 			 MN_TextAWidth(SlotText[quickload-1])/2, Y_DISP+90);
585 	      MN_DrTextA("?", 160+
586 			 MN_TextAWidth(SlotText[quickload-1])/2, Y_DISP+90);
587 #endif
588 	    }
589 	  /* UpdateState |= I_FULLSCRN; */
590 	}
591       return;
592     }
593   else
594     {
595       /* UpdateState |= I_FULLSCRN; */
596       if(InfoType)
597 	{
598 	  MN_DrawInfo();
599 	  return;
600 	}
601       if(screenblocks < 10)
602 	{
603 	  BorderNeedRefresh = true;
604 		}
605       if(CurrentMenu->drawFunc != NULL)
606 	{
607 	  CurrentMenu->drawFunc();
608 	}
609       x = CurrentMenu->x;
610       y = CurrentMenu->y;
611       item = CurrentMenu->items;
612       for(i = 0; i < CurrentMenu->itemCount; i++)
613 	{
614 	  if(item->type != ITT_EMPTY && item->text)
615 	    {
616 	      MN_DrTextB(item->text, x, Y_DISP+y);
617 	    }
618 	  y += ITEM_HEIGHT;
619 	  item++;
620 	}
621       y = CurrentMenu->y+(CurrentItPos*ITEM_HEIGHT)+SELECTOR_YOFFSET;
622       selName = MenuTime&16 ? "M_SLCTR1" : "M_SLCTR2";
623 #ifndef GL_HERETIC
624       V_DrawPatch(x+SELECTOR_XOFFSET, Y_DISP+y,
625 		  W_CacheLumpName(selName, PU_CACHE));
626 #else
627       GL_DrawPatch(x+SELECTOR_XOFFSET, y,GL_GetNumForName(selName));
628 #endif
629     }
630 }
631 
632 
633 /*
634   //---------------------------------------------------------------------------
635   //
636   // PROC DrawMainMenu
637   //
638   //---------------------------------------------------------------------------
639 */
DrawMainMenu(void)640 static void DrawMainMenu(void)
641 {
642   int frame;
643 
644   frame = (MenuTime/3)%18;
645 #ifndef GL_HERETIC
646   V_DrawPatch(88, Y_DISP+0, W_CacheLumpName("M_HTIC", PU_CACHE));
647   V_DrawPatch(40, Y_DISP+10, W_CacheLumpNum(SkullBaseLump+(17-frame),
648 				     PU_CACHE));
649   V_DrawPatch(232, Y_DISP+10, W_CacheLumpNum(SkullBaseLump+frame, PU_CACHE));
650 #else
651   GL_DrawPatch(88, 0, GL_GetNumForName("M_HTIC"));
652   GL_DrawPatch(40, 10, SkullBaseLump+(17-frame));
653   GL_DrawPatch(232, 10, SkullBaseLump+frame);
654 #endif
655 }
656 
657 
658 /*
659   //---------------------------------------------------------------------------
660   //
661   // PROC DrawEpisodeMenu
662   //
663   //---------------------------------------------------------------------------
664 */
DrawEpisodeMenu(void)665 static void DrawEpisodeMenu(void)
666 {
667 }
668 
669 
670 /*
671   //---------------------------------------------------------------------------
672   //
673   // PROC DrawSkillMenu
674   //
675   //---------------------------------------------------------------------------
676 */
DrawSkillMenu(void)677 static void DrawSkillMenu(void)
678 {
679 }
680 
681 //---------------------------------------------------------------------------
682 //
683 // PROC DrawFilesMenu
684 //
685 //---------------------------------------------------------------------------
686 
DrawFilesMenu(void)687 static void DrawFilesMenu(void)
688 {
689   /* clear out the quicksave/quickload stuff */
690   quicksave = 0;
691   quickload = 0;
692   players[consoleplayer].message = NULL;
693   players[consoleplayer].messageTics = 1;
694 }
695 
696 
697 /*
698   //---------------------------------------------------------------------------
699   //
700   // PROC DrawLoadMenu
701   //
702   //---------------------------------------------------------------------------
703 */
DrawLoadMenu(void)704 static void DrawLoadMenu(void)
705 {
706   MN_DrTextB("LOAD GAME", 160-MN_TextBWidth("LOAD GAME")/2, Y_DISP+10);
707   if(!slottextloaded)
708     {
709       MN_LoadSlotText();
710     }
711   DrawFileSlots(&LoadMenu);
712 }
713 
714 
715 /*
716   //---------------------------------------------------------------------------
717   //
718   // PROC DrawSaveMenu
719   //
720   //---------------------------------------------------------------------------
721 */
DrawSaveMenu(void)722 static void DrawSaveMenu(void)
723 {
724   MN_DrTextB("SAVE GAME", 160-MN_TextBWidth("SAVE GAME")/2, Y_DISP+10);
725   if(!slottextloaded)
726     {
727       MN_LoadSlotText();
728     }
729   DrawFileSlots(&SaveMenu);
730 }
731 
732 
733 /*
734   //===========================================================================
735   //
736   // MN_LoadSlotText
737   //
738   //              Loads in the text message for each slot
739   //===========================================================================
740 */
MN_LoadSlotText(void)741 void MN_LoadSlotText(void)
742 {
743   FILE    *fp;
744   int     count;
745   int     i;
746   char    name[256];
747 
748   for (i = 0; i < 6; i++)
749     {
750       if(cdrom)
751 	{
752 	  sprintf(name, SAVEGAMENAMECD"%d.hsg", i);
753 	}
754       else
755 	{
756 	  sprintf(name, "%s"SAVEGAMENAME"%d.hsg", homedir, i);
757 	}
758       fp = fopen(name, "rb+");
759       if (!fp)
760 	{
761 	  SlotText[i][0] = 0; /* empty the string */
762 	  SlotStatus[i] = 0;
763 	  continue;
764 	}
765       count = fread(&SlotText[i], SLOTTEXTLEN, 1, fp);
766       fclose(fp);
767       SlotStatus[i] = 1;
768     }
769   slottextloaded = true;
770 }
771 
772 
773 /*
774   //---------------------------------------------------------------------------
775   //
776   // PROC DrawFileSlots
777   //
778   //---------------------------------------------------------------------------
779 */
DrawFileSlots(Menu_t * menu)780 static void DrawFileSlots(Menu_t *menu)
781 {
782   int i;
783   int x;
784   int y;
785 
786   x = menu->x;
787   y = menu->y;
788   for(i = 0; i < 6; i++)
789     {
790 #ifndef GL_HERETIC
791       V_DrawPatch(x, Y_DISP+y, W_CacheLumpName("M_FSLOT", PU_CACHE));
792 #else
793       GL_DrawPatch(x, y, GL_GetNumForName("M_FSLOT"));
794 #endif
795       if(SlotStatus[i])
796 	{
797 #ifdef GL_HERETIC
798 	  MN_DrTextA(SlotText[i], x+5, y+5);
799 #else
800 	  MN_DrTextA(SlotText[i], x+5, Y_DISP+y+5);
801 #endif
802 	}
803       y += ITEM_HEIGHT;
804     }
805 }
806 
807 
808 /*
809   //---------------------------------------------------------------------------
810   //
811   // PROC DrawOptionsMenu
812   //
813   //---------------------------------------------------------------------------
814 */
DrawOptionsMenu(void)815 static void DrawOptionsMenu(void)
816 {
817   if(messageson)
818     {
819       MN_DrTextB("ON", 196, Y_DISP+50);
820     }
821   else
822     {
823       MN_DrTextB("OFF", 196, Y_DISP+50);
824     }
825 }
826 
827 
828 /*
829   //---------------------------------------------------------------------------
830   //
831   // PROC DrawOptions2Menu
832   //
833   //---------------------------------------------------------------------------
834 */
DrawOptions2Menu(void)835 static void DrawOptions2Menu(void)
836 {
837   DrawSlider(&Options2Menu, 1, 9, screenblocks-3);
838   DrawSlider(&Options2Menu, 3, 16, snd_SfxVolume);
839   DrawSlider(&Options2Menu, 5, 16, snd_MusicVolume);
840 }
841 
842 
843 /*
844   //---------------------------------------------------------------------------
845   //
846   // PROC DrawOptions3Menu
847   //
848   //---------------------------------------------------------------------------
849 */
DrawOptions3Menu(void)850 static void DrawOptions3Menu(void)
851 {
852   if(mouseLook)
853     {
854       MN_DrTextB("ON", 216, Y_DISP+30);
855     }
856   else
857     {
858       MN_DrTextB("OFF", 216, Y_DISP+30);
859     }
860   if(mouseInvert)
861     {
862       MN_DrTextB("ON", 246, Y_DISP+50);
863     }
864   else
865     {
866       MN_DrTextB("OFF", 246, Y_DISP+50);
867     }
868   if(do_grabMouse)
869     {
870       MN_DrTextB("ON", 216, Y_DISP+70);
871     }
872   else
873     {
874       MN_DrTextB("OFF", 216, Y_DISP+70);
875     }
876   DrawSlider(&OptionsMenu, 3, 10, mouseXSensitivity);
877   DrawSlider(&OptionsMenu, 5, 10, mouseYSensitivity);
878 }
879 
880 
881 /*
882   //---------------------------------------------------------------------------
883   //
884   // PROC SCNetCheck
885   //
886   //---------------------------------------------------------------------------
887 */
SCNetCheck(int option)888 static boolean SCNetCheck(int option)
889 {
890   if(!netgame)
891     { /* okay to go into the menu */
892       return true;
893     }
894   switch(option)
895     {
896     case 1:
897       P_SetMessage(&players[consoleplayer],
898 		   "YOU CAN'T START A NEW GAME IN NETPLAY!", true);
899       break;
900     case 2:
901       P_SetMessage(&players[consoleplayer],
902 		   "YOU CAN'T LOAD A GAME IN NETPLAY!", true);
903       break;
904     default:
905       break;
906     }
907   MenuActive = false;
908   return false;
909 }
910 
911 
912 /*
913   //---------------------------------------------------------------------------
914   //
915   // PROC SCQuitGame
916   //
917   //---------------------------------------------------------------------------
918 */
SCQuitGame(int option)919 static boolean SCQuitGame(int option)
920 {
921   MenuActive = false;
922   askforquit = true;
923   typeofask = 1; /* quit game */
924   if(!netgame && !demoplayback)
925     {
926       paused = true;
927     }
928   return true;
929 }
930 
931 
932 /*
933   //---------------------------------------------------------------------------
934   //
935   // PROC SCEndGame
936   //
937   //---------------------------------------------------------------------------
938 */
SCEndGame(int option)939 static boolean SCEndGame(int option)
940 {
941   if(demoplayback || netgame)
942     {
943       return false;
944     }
945   MenuActive = false;
946   askforquit = true;
947   typeofask = 2; /* endgame */
948   if(!netgame && !demoplayback)
949     {
950       paused = true;
951     }
952   return true;
953 }
954 
955 
956 /*
957   //---------------------------------------------------------------------------
958   //
959   // PROC SCMessages
960   //
961   //---------------------------------------------------------------------------
962 */
SCMessages(int option)963 static boolean SCMessages(int option)
964 {
965   messageson ^= 1;
966   if(messageson)
967     {
968       P_SetMessage(&players[consoleplayer], "MESSAGES ON", true);
969     }
970   else
971     {
972       P_SetMessage(&players[consoleplayer], "MESSAGES OFF", true);
973     }
974   S_StartSound(NULL, sfx_chat);
975   return true;
976 }
977 
978 
979 /*
980   //---------------------------------------------------------------------------
981   //
982   // PROC SCMessages
983   //
984   //---------------------------------------------------------------------------
985 */
SCMouseGrab(int option)986 static boolean SCMouseGrab(int option)
987 {
988   do_grabMouse ^= 1;
989   if(do_grabMouse)
990     {
991       P_SetMessage(&players[consoleplayer], "MOUSEGRAB ON", true);
992     }
993   else
994     {
995       P_SetMessage(&players[consoleplayer], "MOUSEGRAB OFF", true);
996     }
997   S_StartSound(NULL, sfx_chat);
998   return true;
999 }
1000 
SCMouseLook(int option)1001 static boolean SCMouseLook(int option)
1002 {
1003   mouseLook ^= 1;
1004 
1005 #ifdef GL_HERETIC
1006   if (mouseLook)
1007      g_bMlook = TRUE;
1008   else
1009      g_bMlook = FALSE;
1010 #endif
1011 
1012   if(mouseLook)
1013     {
1014       P_SetMessage(&players[consoleplayer], "MOUSELOOK ON", true);
1015     }
1016   else
1017     {
1018       P_SetMessage(&players[consoleplayer], "MOUSELOOK OFF", true);
1019     }
1020   S_StartSound(NULL, sfx_chat);
1021   return true;
1022 }
1023 
1024 
1025 /*
1026   //---------------------------------------------------------------------------
1027   //
1028   // PROC SCMessages
1029   //
1030   //---------------------------------------------------------------------------
1031 */
SCMouseInvert(int option)1032 static boolean SCMouseInvert(int option)
1033 {
1034   mouseInvert ^= 1;
1035   if(mouseInvert)
1036     {
1037       P_SetMessage(&players[consoleplayer], "MOUSEINVERT ON", true);
1038     }
1039   else
1040     {
1041       P_SetMessage(&players[consoleplayer], "MOUSEINVERT OFF", true);
1042     }
1043   S_StartSound(NULL, sfx_chat);
1044   return true;
1045 }
1046 
1047 
1048 /*
1049   //---------------------------------------------------------------------------
1050   //
1051   // PROC SCLoadGame
1052   //
1053   //---------------------------------------------------------------------------
1054 */
SCLoadGame(int option)1055 static boolean SCLoadGame(int option)
1056 {
1057   char name[256];
1058 
1059   if(!SlotStatus[option])
1060     { /* slot's empty...don't try and load */
1061       return false;
1062     }
1063   if(cdrom)
1064     {
1065       sprintf(name, SAVEGAMENAMECD"%d.hsg", option);
1066     }
1067   else
1068     {
1069       sprintf(name, "%s"SAVEGAMENAME"%d.hsg", homedir, option);
1070     }
1071   G_LoadGame(name);
1072   MN_DeactivateMenu();
1073   BorderNeedRefresh = true;
1074   if(quickload == -1)
1075     {
1076       quickload = option+1;
1077       players[consoleplayer].message = NULL;
1078       players[consoleplayer].messageTics = 1;
1079     }
1080   return true;
1081 }
1082 
1083 
1084 /*
1085   //---------------------------------------------------------------------------
1086   //
1087   // PROC SCSaveGame
1088   //
1089   //---------------------------------------------------------------------------
1090 */
SCSaveGame(int option)1091 static boolean SCSaveGame(int option)
1092 {
1093   char *ptr;
1094 
1095   if(!FileMenuKeySteal)
1096     {
1097       FileMenuKeySteal = true;
1098       strcpy(oldSlotText, SlotText[option]);
1099       ptr = SlotText[option];
1100       while(*ptr)
1101 	{
1102 	  ptr++;
1103 	}
1104       *ptr = '[';
1105       *(ptr+1) = 0;
1106       SlotStatus[option]++;
1107       currentSlot = option;
1108       slotptr = ptr-SlotText[option];
1109       return false;
1110     }
1111   else
1112     {
1113       G_SaveGame(option, SlotText[option]);
1114       FileMenuKeySteal = false;
1115       MN_DeactivateMenu();
1116     }
1117   BorderNeedRefresh = true;
1118   if(quicksave == -1)
1119     {
1120       quicksave = option+1;
1121       players[consoleplayer].message = NULL;
1122       players[consoleplayer].messageTics = 1;
1123     }
1124   return true;
1125 }
1126 
1127 
1128 /*
1129   //---------------------------------------------------------------------------
1130   //
1131   // PROC SCEpisode
1132   //
1133   //---------------------------------------------------------------------------
1134 */
SCEpisode(int option)1135 static boolean SCEpisode(int option)
1136 {
1137   if(shareware && (option > 1))
1138     {
1139       P_SetMessage(&players[consoleplayer],
1140 		   "ONLY AVAILABLE IN THE REGISTERED VERSION", true);
1141     }
1142   else
1143     {
1144       MenuEpisode = option;
1145       SetMenu(MENU_SKILL);
1146     }
1147   return true;
1148 }
1149 
1150 
1151 /*
1152   //---------------------------------------------------------------------------
1153   //
1154   // PROC SCSkill
1155   //
1156   //---------------------------------------------------------------------------
1157 */
SCSkill(int option)1158 static boolean SCSkill(int option)
1159 {
1160   G_DeferedInitNew(option, MenuEpisode, 1);
1161   MN_DeactivateMenu();
1162   return true;
1163 }
1164 
1165 
1166 /*
1167   //---------------------------------------------------------------------------
1168   //
1169   // PROC SCMouseXSensi
1170   //
1171   //---------------------------------------------------------------------------
1172 */
SCMouseXSensi(int option)1173 static boolean SCMouseXSensi(int option)
1174 {
1175   if(option == RIGHT_DIR)
1176     {
1177       if(mouseXSensitivity < 9)
1178 	{
1179 	  mouseXSensitivity++;
1180 	}
1181     }
1182   else if(mouseXSensitivity)
1183     {
1184       mouseXSensitivity--;
1185     }
1186   return true;
1187 }
1188 
1189 
1190 /*
1191   //---------------------------------------------------------------------------
1192   //
1193   // PROC SCMouseYSensi
1194   //
1195   //---------------------------------------------------------------------------
1196 */
SCMouseYSensi(int option)1197 static boolean SCMouseYSensi(int option)
1198 {
1199   if(option == RIGHT_DIR)
1200     {
1201       if(mouseYSensitivity < 9)
1202 	{
1203 	  mouseYSensitivity++;
1204 	}
1205     }
1206   else if(mouseYSensitivity)
1207     {
1208       mouseYSensitivity--;
1209     }
1210   return true;
1211 }
1212 
1213 
1214 /*
1215   //---------------------------------------------------------------------------
1216   //
1217   // PROC SCSfxVolume
1218   //
1219   //---------------------------------------------------------------------------
1220 */
SCSfxVolume(int option)1221 static boolean SCSfxVolume(int option)
1222 {
1223   if(option == RIGHT_DIR)
1224     {
1225       if(snd_SfxVolume < 15)
1226 	{
1227 	  snd_SfxVolume++;
1228 	}
1229     }
1230   else if(snd_SfxVolume)
1231     {
1232       snd_SfxVolume--;
1233     }
1234   S_SetSfxVolume(snd_SfxVolume); /* don't recalc the sound curve, yet */
1235   /* soundchanged = true; */  /* we'll set it when we leave the menu */
1236   return true;
1237 }
1238 
1239 
1240 /*
1241   //---------------------------------------------------------------------------
1242   //
1243   // PROC SCMusicVolume
1244   //
1245   //---------------------------------------------------------------------------
1246 */
SCMusicVolume(int option)1247 static boolean SCMusicVolume(int option)
1248 {
1249   if(option == RIGHT_DIR)
1250     {
1251       if(snd_MusicVolume < 15)
1252 	{
1253 	  snd_MusicVolume++;
1254 	}
1255     }
1256   else if(snd_MusicVolume)
1257     {
1258       snd_MusicVolume--;
1259     }
1260   S_SetMusicVolume(snd_MusicVolume);
1261   return true;
1262 }
1263 
1264 
1265 /*
1266   //---------------------------------------------------------------------------
1267   //
1268   // PROC SCScreenSize
1269   //
1270   //---------------------------------------------------------------------------
1271 */
SCScreenSize(int option)1272 static boolean SCScreenSize(int option)
1273 {
1274   if(option == RIGHT_DIR)
1275     {
1276       if(screenblocks < 11)
1277 	{
1278 	  screenblocks++;
1279 	}
1280     }
1281   else if(screenblocks > 3)
1282     {
1283       screenblocks--;
1284     }
1285   R_SetViewSize(screenblocks, detailLevel);
1286   return true;
1287 }
1288 
1289 
1290 /*
1291   //---------------------------------------------------------------------------
1292   //
1293   // PROC SCInfo
1294   //
1295   //---------------------------------------------------------------------------
1296 */
SCInfo(int option)1297 static boolean SCInfo(int option)
1298 {
1299   InfoType = 1;
1300   S_StartSound(NULL, sfx_dorcls);
1301   if(!netgame && !demoplayback)
1302     {
1303       paused = true;
1304     }
1305   return true;
1306 }
1307 
1308 
1309 /*
1310   //---------------------------------------------------------------------------
1311   //
1312   // FUNC MN_Responder
1313   //
1314   //---------------------------------------------------------------------------
1315 */
MN_Responder(event_t * event)1316 boolean MN_Responder(event_t *event)
1317 {
1318   int key;
1319   int i;
1320   MenuItem_t *item;
1321   extern boolean automapactive;
1322   static boolean shiftdown;
1323   extern void D_StartTitle(void);
1324   extern boolean G_CheckDemoStatus(void);
1325   char *textBuffer;
1326 
1327   if(event->data1 == KEY_RSHIFT)
1328     {
1329       shiftdown = (event->type == ev_keydown);
1330     }
1331   if(event->type != ev_keydown)
1332     {
1333       return(false);
1334     }
1335   key = event->data1;
1336   if(InfoType)
1337     {
1338       if(shareware)
1339 	{
1340 	  InfoType = (InfoType+1)%5;
1341 	}
1342       else
1343 	{
1344 	  InfoType = (InfoType+1)%4;
1345 	}
1346       if(key == KEY_ESCAPE)
1347 	{
1348 	  InfoType = 0;
1349 	}
1350       if(!InfoType)
1351 	{
1352 	  paused = false;
1353 	  MN_DeactivateMenu();
1354 	  SB_state = -1; /* refresh the statbar */
1355 	  BorderNeedRefresh = true;
1356 	}
1357       S_StartSound(NULL, sfx_dorcls);
1358       return(true); /* make the info screen eat the keypress */
1359     }
1360 
1361   if(ravpic && key == KEY_F1)
1362     {
1363       G_ScreenShot();
1364       return(true);
1365     }
1366 
1367   if(askforquit)
1368     {
1369       switch(key)
1370 	{
1371 	case 'y':
1372 	  if(askforquit)
1373 	    {
1374 	      switch(typeofask)
1375 		{
1376 		case 1:
1377 		  G_CheckDemoStatus();
1378 		  I_Quit();
1379 		  break;
1380 		case 2:
1381 		  players[consoleplayer].messageTics = 0;
1382 		  /* set the msg to be cleared */
1383 		  players[consoleplayer].message = NULL;
1384 		  typeofask = 0;
1385 		  askforquit = false;
1386 		  paused = false;
1387 		  I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
1388 		  D_StartTitle(); /* go to intro/demo mode. */
1389 		  break;
1390 		case 3:
1391 		  P_SetMessage(&players[consoleplayer], "QUICKSAVING....", false);
1392 		  FileMenuKeySteal = true;
1393 		  SCSaveGame(quicksave-1);
1394 		  askforquit = false;
1395 		  typeofask = 0;
1396 		  BorderNeedRefresh = true;
1397 		  return true;
1398 		case 4:
1399 		  P_SetMessage(&players[consoleplayer], "QUICKLOADING....", false);
1400 		  SCLoadGame(quickload-1);
1401 		  askforquit = false;
1402 		  typeofask = 0;
1403 		  BorderNeedRefresh = true;
1404 		  return true;
1405 		default:
1406 		  return true; /* eat the 'y' keypress */
1407 		}
1408 	    }
1409 	  return false;
1410 	case 'n':
1411 	case KEY_ESCAPE:
1412 	  if(askforquit)
1413 	    {
1414 	      players[consoleplayer].messageTics = 1; /* set the msg to be cleared */
1415 	      askforquit = false;
1416 	      typeofask = 0;
1417 	      paused = false;
1418 	      /* UpdateState |= I_FULLSCRN; */
1419 	      BorderNeedRefresh = true;
1420 	      return true;
1421 	    }
1422 	  return false;
1423 	}
1424       return false; /* don't let the keys filter thru */
1425     }
1426   if(MenuActive == false && !chatmodeon)
1427     {
1428       switch(key)
1429 	{
1430 	case KEY_MINUS:
1431 	  if(automapactive)
1432 	    { /* Don't screen size in automap */
1433 	      return(false);
1434 	    }
1435 #ifndef GL_HERETIC
1436 	  SCScreenSize(LEFT_DIR);
1437 #else
1438 	  g_bFullScreen=FALSE;
1439 #endif
1440 	  S_StartSound(NULL, sfx_keyup);
1441 	  BorderNeedRefresh = true;
1442 	  /* UpdateState |= I_FULLSCRN; */
1443 	  return(true);
1444 	case KEY_EQUALS:
1445 	  if(automapactive)
1446 	    { /* Don't screen size in automap */
1447 	      return(false);
1448 	    }
1449 #ifndef GL_HERETIC
1450 	  SCScreenSize(RIGHT_DIR);
1451 #else
1452 	  g_bFullScreen=TRUE;
1453 #endif
1454 	  S_StartSound(NULL, sfx_keyup);
1455 	  BorderNeedRefresh = true;
1456 	  /* UpdateState |= I_FULLSCRN; */
1457 	  return(true);
1458 #ifndef __NeXT__
1459 	case KEY_F1: /* help screen */
1460 	  SCInfo(0); /* start up info screens */
1461 	  MenuActive = true;
1462 	  return(true);
1463 	case KEY_F2: /* save game */
1464 	  if(gamestate == GS_LEVEL && !demoplayback)
1465 	    {
1466 	      MenuActive = true;
1467 	      FileMenuKeySteal = false;
1468 	      MenuTime = 0;
1469 	      CurrentMenu = &SaveMenu;
1470 	      CurrentItPos = CurrentMenu->oldItPos;
1471 	      if(!netgame && !demoplayback)
1472 		{
1473 		  paused = true;
1474 		}
1475 	      S_StartSound(NULL, sfx_dorcls);
1476 	      slottextloaded = false; /* reload the slot text, when needed */
1477 	    }
1478 	  return true;
1479 	case KEY_F3: /* load game */
1480 	  if(SCNetCheck(2))
1481 	    {
1482 	      MenuActive = true;
1483 	      FileMenuKeySteal = false;
1484 	      MenuTime = 0;
1485 	      CurrentMenu = &LoadMenu;
1486 	      CurrentItPos = CurrentMenu->oldItPos;
1487 	      if(!netgame && !demoplayback)
1488 		{
1489 		  paused = true;
1490 		}
1491 	      S_StartSound(NULL, sfx_dorcls);
1492 	      slottextloaded = false; /* reload the slot text, when needed */
1493 	    }
1494 	  return true;
1495 	case KEY_F4: /* volume */
1496 	  MenuActive = true;
1497 	  FileMenuKeySteal = false;
1498 	  MenuTime = 0;
1499 	  CurrentMenu = &Options2Menu;
1500 	  CurrentItPos = CurrentMenu->oldItPos;
1501 	  if(!netgame && !demoplayback)
1502 	    {
1503 	      paused = true;
1504 	    }
1505 	  S_StartSound(NULL, sfx_dorcls);
1506 	  slottextloaded = false; /* reload the slot text, when needed */
1507 	  return true;
1508 	case KEY_F5: /* F5 isn't used in Heretic. (detail level) */
1509 	  return true;
1510 	case KEY_F6: /* quicksave */
1511 	  if(gamestate == GS_LEVEL && !demoplayback)
1512 	    {
1513 	      if(!quicksave || quicksave == -1)
1514 		{
1515 		  MenuActive = true;
1516 		  FileMenuKeySteal = false;
1517 		  MenuTime = 0;
1518 		  CurrentMenu = &SaveMenu;
1519 		  CurrentItPos = CurrentMenu->oldItPos;
1520 		  if(!netgame && !demoplayback)
1521 		    {
1522 		      paused = true;
1523 		    }
1524 		  S_StartSound(NULL, sfx_dorcls);
1525 		  slottextloaded = false; /* reload the slot text, when needed */
1526 		  quicksave = -1;
1527 		  P_SetMessage(&players[consoleplayer],
1528 			       "CHOOSE A QUICKSAVE SLOT", true);
1529 		}
1530 	      else
1531 		{
1532 		  askforquit = true;
1533 		  typeofask = 3;
1534 		  if(!netgame && !demoplayback)
1535 		    {
1536 		      paused = true;
1537 		    }
1538 		  S_StartSound(NULL, sfx_chat);
1539 		}
1540 	    }
1541 	  return true;
1542 	case KEY_F7: /* endgame */
1543 	  if(gamestate == GS_LEVEL && !demoplayback)
1544 	    {
1545 	      S_StartSound(NULL, sfx_chat);
1546 	      SCEndGame(0);
1547 	    }
1548 	  return true;
1549 	case KEY_F8: /* toggle messages */
1550 	  SCMessages(0);
1551 	  return true;
1552 	case KEY_F9: /* quickload */
1553 	  if(!quickload || quickload == -1)
1554 	    {
1555 	      MenuActive = true;
1556 	      FileMenuKeySteal = false;
1557 	      MenuTime = 0;
1558 	      CurrentMenu = &LoadMenu;
1559 	      CurrentItPos = CurrentMenu->oldItPos;
1560 	      if(!netgame && !demoplayback)
1561 		{
1562 		  paused = true;
1563 		}
1564 	      S_StartSound(NULL, sfx_dorcls);
1565  	      slottextloaded = false; /* reload the slot text, when needed */
1566 	      quickload = -1;
1567 	      P_SetMessage(&players[consoleplayer],
1568 			   "CHOOSE A QUICKLOAD SLOT", true);
1569 	    }
1570 	  else
1571 	    {
1572 	      askforquit = true;
1573 	      if(!netgame && !demoplayback)
1574 		{
1575 		  paused = true;
1576 		}
1577 	      typeofask = 4;
1578 	      S_StartSound(NULL, sfx_chat);
1579 	    }
1580 	  return true;
1581 	case KEY_F10: /* quit */
1582 	  if(gamestate == GS_LEVEL)
1583 	    {
1584 	      SCQuitGame(0);
1585 	      S_StartSound(NULL, sfx_chat);
1586 	    }
1587 	  return true;
1588 	case KEY_F11: /* F11 - gamma mode correction */
1589 	  usegamma++;
1590 #ifdef GL_HERETIC
1591 	  if(usegamma > 8)
1592 #else
1593     if(usegamma > 4)
1594 #endif
1595 	    {
1596 	      usegamma = 0;
1597 	    }
1598 	  I_SetPalette((byte *)W_CacheLumpName("PLAYPAL", PU_CACHE));
1599 	  return true;
1600 #endif
1601 	}
1602 
1603     }
1604 
1605   if(MenuActive == false)
1606     {
1607       if(key == KEY_ESCAPE)
1608 	{
1609 	  MN_ActivateMenu();
1610 	  return(true);
1611 	}
1612       return(false);
1613     }
1614   if(!FileMenuKeySteal)
1615     {
1616       item = &CurrentMenu->items[CurrentItPos];
1617       switch(key)
1618 	{
1619 	case KEY_DOWNARROW:
1620 	  do
1621 	    {
1622 	      if(CurrentItPos+1 > CurrentMenu->itemCount-1)
1623 		{
1624 		  CurrentItPos = 0;
1625 		}
1626 	      else
1627 		{
1628 		  CurrentItPos++;
1629 		}
1630 	    } while(CurrentMenu->items[CurrentItPos].type == ITT_EMPTY);
1631 	  S_StartSound(NULL, sfx_switch);
1632 	  return(true);
1633 	  break;
1634 	case KEY_UPARROW:
1635 	  do
1636 	    {
1637 	      if(CurrentItPos == 0)
1638 		{
1639 		  CurrentItPos = CurrentMenu->itemCount-1;
1640 		}
1641 	      else
1642 		{
1643 		  CurrentItPos--;
1644 		}
1645 	    } while(CurrentMenu->items[CurrentItPos].type == ITT_EMPTY);
1646 	  S_StartSound(NULL, sfx_switch);
1647 	  return(true);
1648 	  break;
1649 	case KEY_LEFTARROW:
1650 	  if(item->type == ITT_LRFUNC && item->func != NULL)
1651 	    {
1652 	      item->func(LEFT_DIR);
1653 	      S_StartSound(NULL, sfx_keyup);
1654 	    }
1655 	  return(true);
1656 	  break;
1657 	case KEY_RIGHTARROW:
1658 	  if(item->type == ITT_LRFUNC && item->func != NULL)
1659 	    {
1660 	      item->func(RIGHT_DIR);
1661 	      S_StartSound(NULL, sfx_keyup);
1662 	    }
1663 	  return(true);
1664 	  break;
1665 	case KEY_ENTER:
1666 	  if(item->type == ITT_SETMENU)
1667 	    {
1668 	      SetMenu(item->menu);
1669 	    }
1670 	  else if(item->func != NULL)
1671 	    {
1672 	      CurrentMenu->oldItPos = CurrentItPos;
1673 	      if(item->type == ITT_LRFUNC)
1674 		{
1675 		  item->func(RIGHT_DIR);
1676 		}
1677 	      else if(item->type == ITT_EFUNC)
1678 		{
1679 		  if(item->func(item->option))
1680 		    {
1681 		      if(item->menu != MENU_NONE)
1682 			{
1683 			  SetMenu(item->menu);
1684 			}
1685 		    }
1686 		}
1687 	    }
1688 	  S_StartSound(NULL, sfx_dorcls);
1689 	  return(true);
1690 	  break;
1691 	case KEY_ESCAPE:
1692 	  MN_DeactivateMenu();
1693 	  return(true);
1694 	case KEY_BACKSPACE:
1695 	  S_StartSound(NULL, sfx_switch);
1696 	  if(CurrentMenu->prevMenu == MENU_NONE)
1697 	    {
1698 	      MN_DeactivateMenu();
1699 	    }
1700 	  else
1701 	    {
1702 	      SetMenu(CurrentMenu->prevMenu);
1703 	    }
1704 	  return(true);
1705 	default:
1706 	  for(i = 0; i < CurrentMenu->itemCount; i++)
1707 	    {
1708 	      if(CurrentMenu->items[i].text)
1709 		{
1710 		  if(toupper(key)
1711 		     == toupper(CurrentMenu->items[i].text[0]))
1712 		    {
1713 		      CurrentItPos = i;
1714 		      return(true);
1715 		    }
1716 		}
1717 	    }
1718 	  break;
1719 	}
1720       return(false);
1721     }
1722   else
1723     { /* Editing file names */
1724       textBuffer = &SlotText[currentSlot][slotptr];
1725       if(key == KEY_BACKSPACE)
1726 	{
1727 	  if(slotptr)
1728 	    {
1729 	      *textBuffer-- = 0;
1730 	      *textBuffer = ASCII_CURSOR;
1731 	      slotptr--;
1732 	    }
1733 	  return(true);
1734 	}
1735       if(key == KEY_ESCAPE)
1736 	{
1737 	  memset(SlotText[currentSlot], 0, SLOTTEXTLEN+2);
1738 	  strcpy(SlotText[currentSlot], oldSlotText);
1739 	  SlotStatus[currentSlot]--;
1740 	  MN_DeactivateMenu();
1741 	  return(true);
1742 	}
1743       if(key == KEY_ENTER)
1744 	{
1745 	  SlotText[currentSlot][slotptr] = 0; /* clear the cursor */
1746 	  item = &CurrentMenu->items[CurrentItPos];
1747 	  CurrentMenu->oldItPos = CurrentItPos;
1748 	  if(item->type == ITT_EFUNC)
1749 	    {
1750 	      item->func(item->option);
1751 	      if(item->menu != MENU_NONE)
1752 		{
1753 		  SetMenu(item->menu);
1754 		}
1755 	    }
1756 	  return(true);
1757 	}
1758       if(slotptr < SLOTTEXTLEN && key != KEY_BACKSPACE)
1759 	{
1760 	  if((key >= 'a' && key <= 'z'))
1761 	    {
1762 	      *textBuffer++ = key-32;
1763 	      *textBuffer = ASCII_CURSOR;
1764 	      slotptr++;
1765 	      return(true);
1766 	    }
1767 	  if(((key >= '0' && key <= '9') || key == ' '
1768 	      || key == ',' || key == '.' || key == '-')
1769 	     && !shiftdown)
1770 	    {
1771 	      *textBuffer++ = key;
1772 	      *textBuffer = ASCII_CURSOR;
1773 	      slotptr++;
1774 	      return(true);
1775 	    }
1776 	  if(shiftdown && key == '1')
1777 	    {
1778 	      *textBuffer++ = '!';
1779 	      *textBuffer = ASCII_CURSOR;
1780 	      slotptr++;
1781 	      return(true);
1782 	    }
1783 	}
1784       return(true);
1785     }
1786   return(false);
1787 }
1788 
1789 
1790 /*
1791   //---------------------------------------------------------------------------
1792   //
1793   // PROC MN_ActivateMenu
1794   //
1795   //---------------------------------------------------------------------------
1796 */
MN_ActivateMenu(void)1797 void MN_ActivateMenu(void)
1798 {
1799   if(MenuActive)
1800     {
1801       return;
1802     }
1803   if(paused)
1804     {
1805       S_ResumeSound();
1806     }
1807   MenuActive = true;
1808   FileMenuKeySteal = false;
1809   MenuTime = 0;
1810   CurrentMenu = &MainMenu;
1811   CurrentItPos = CurrentMenu->oldItPos;
1812   if(!netgame && !demoplayback)
1813     {
1814       paused = true;
1815     }
1816   S_StartSound(NULL, sfx_dorcls);
1817   slottextloaded = false; /* reload the slot text, when needed */
1818 }
1819 
1820 
1821 /*
1822   //---------------------------------------------------------------------------
1823   //
1824   // PROC MN_DeactivateMenu
1825   //
1826   //---------------------------------------------------------------------------
1827 */
MN_DeactivateMenu(void)1828 void MN_DeactivateMenu(void)
1829 {
1830   if (CurrentMenu)
1831     CurrentMenu->oldItPos = CurrentItPos;
1832   MenuActive = false;
1833   if(!netgame)
1834     {
1835       paused = false;
1836     }
1837   S_StartSound(NULL, sfx_dorcls);
1838   if(soundchanged)
1839     {
1840       /* S_SetSfxVolume(true); */ /* recalc the sound curve */
1841       /* S_SetSfxVolume(snd_SfxVolume); */
1842 #ifdef USE_GSI
1843 	    soundchanged = false;
1844 #endif
1845     }
1846   players[consoleplayer].message = NULL;
1847   players[consoleplayer].messageTics = 1;
1848 }
1849 
1850 
1851 /*
1852   //---------------------------------------------------------------------------
1853   //
1854   // PROC MN_DrawInfo
1855   //
1856   //---------------------------------------------------------------------------
1857 */
MN_DrawInfo(void)1858 void MN_DrawInfo(void)
1859 {
1860 #ifndef GL_HERETIC
1861   I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
1862 
1863   V_DrawRawScreen((byte *)W_CacheLumpNum(W_GetNumForName("TITLE")
1864 					 +InfoType, PU_CACHE));
1865 #else
1866   GLDrawScreen(InfoType);
1867 #endif
1868 }
1869 
1870 
1871 /*
1872   //---------------------------------------------------------------------------
1873   //
1874   // PROC SetMenu
1875   //
1876   //---------------------------------------------------------------------------
1877 */
SetMenu(MenuType_t menu)1878 static void SetMenu(MenuType_t menu)
1879 {
1880   CurrentMenu->oldItPos = CurrentItPos;
1881   CurrentMenu = Menus[menu];
1882   CurrentItPos = CurrentMenu->oldItPos;
1883 }
1884 
1885 
1886 /*
1887   //---------------------------------------------------------------------------
1888   //
1889   // PROC DrawSlider
1890   //
1891   //---------------------------------------------------------------------------
1892 */
DrawSlider(Menu_t * menu,int item,int width,int slot)1893 static void DrawSlider(Menu_t *menu, int item, int width, int slot)
1894 {
1895   int x;
1896   int y;
1897   int x2;
1898   int count;
1899 
1900   x = menu->x+24;
1901   y = menu->y+2+(item*ITEM_HEIGHT) + Y_DISP;
1902 #ifndef GL_HERETIC
1903   V_DrawPatch(x-32, y, W_CacheLumpName("M_SLDLT", PU_CACHE));
1904   for(x2 = x, count = width; count--; x2 += 8)
1905     {
1906       V_DrawPatch(x2, y, W_CacheLumpName(count&1 ? "M_SLDMD1"
1907 					 : "M_SLDMD2", PU_CACHE));
1908     }
1909   V_DrawPatch(x2, y, W_CacheLumpName("M_SLDRT", PU_CACHE));
1910   V_DrawPatch(x+4+slot*8, y+7, W_CacheLumpName("M_SLDKB", PU_CACHE));
1911 #else
1912   GL_DrawPatch(x-32, y, GL_GetNumForName("M_SLDLT"));
1913   for(x2 = x, count = width; count--; x2 += 8)
1914     {
1915       GL_DrawPatch(x2, y, GL_GetNumForName(count&1 ? "M_SLDMD1" : "M_SLDMD2"));
1916     }
1917   GL_DrawPatch(x2, y, GL_GetNumForName("M_SLDRT"));
1918   GL_DrawPatch(x+4+slot*8, y+7, GL_GetNumForName("M_SLDKB"));
1919 #endif
1920 }
1921