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