summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/m_menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/m_menu.c')
-rw-r--r--apps/plugins/doom/m_menu.c1848
1 files changed, 1848 insertions, 0 deletions
diff --git a/apps/plugins/doom/m_menu.c b/apps/plugins/doom/m_menu.c
new file mode 100644
index 0000000000..34f3e22ce2
--- /dev/null
+++ b/apps/plugins/doom/m_menu.c
@@ -0,0 +1,1848 @@
1// Emacs style mode select -*- C++ -*-
2//-----------------------------------------------------------------------------
3//
4// $Id$
5//
6// Copyright (C) 1993-1996 by id Software, Inc.
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License
10// as published by the Free Software Foundation; either version 2
11// of the License, or (at your option) any later version.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// $Log$
19// Revision 1.1 2006/03/28 15:44:01 dave
20// Patch #2969 - Doom! Currently only working on the H300.
21//
22//
23// DESCRIPTION:
24// DOOM selection menu, options, episode etc.
25// Sliders and icons. Kinda widget stuff.
26//
27//-----------------------------------------------------------------------------
28
29#include "doomdef.h"
30#include "dstrings.h"
31
32#include "d_main.h"
33
34#include "i_system.h"
35#include "i_video.h"
36#include "z_zone.h"
37#include "v_video.h"
38#include "w_wad.h"
39
40#include "r_main.h"
41
42#include "hu_stuff.h"
43
44#include "g_game.h"
45
46#include "m_argv.h"
47#include "m_swap.h"
48#include "s_sound.h"
49
50#include "doomstat.h"
51
52// Data.
53#include "sounds.h"
54
55#include "m_menu.h"
56#include "rockmacros.h"
57
58
59extern patchnum_t hu_font[HU_FONTSIZE];
60extern boolean message_dontfuckwithme;
61
62extern boolean chat_on; // in heads-up code
63
64//
65// defaulted values
66//
67int mouseSensitivity; // has default
68
69// Show messages has default, 0 = off, 1 = on
70int showMessages;
71
72// Blocky mode, has default, 0 = high, 1 = normal
73int screenblocks; // has default
74
75// temp for screenblocks (0-9)
76int screenSize;
77
78// -1 = no quicksave slot picked!
79int quickSaveSlot;
80
81// 1 = message to be printed
82int messageToPrint;
83// ...and here is the message string!
84char* messageString;
85
86// message x & y
87int messx;
88int messy;
89int messageLastMenuActive;
90
91// timed message = no input from user
92boolean messageNeedsInput;
93
94void (*messageRoutine)(int response);
95
96#define SAVESTRINGSIZE 24
97
98char gammamsg[5][26] =
99 {
100 GAMMALVL0,
101 GAMMALVL1,
102 GAMMALVL2,
103 GAMMALVL3,
104 GAMMALVL4
105 };
106
107// we are going to be entering a savegame string
108int saveStringEnter;
109int saveSlot; // which slot to save in
110int saveCharIndex; // which char we're editing
111// old save description before edit
112char saveOldString[SAVESTRINGSIZE];
113
114boolean inhelpscreens;
115boolean menuactive;
116
117#define SKULLXOFF -32
118#define LINEHEIGHT 16
119
120extern boolean sendpause;
121char savegamestrings[10][SAVESTRINGSIZE];
122
123char endstring[170];
124
125
126//
127// MENU TYPEDEFS
128//
129typedef struct
130{
131 // 0 = no cursor here, 1 = ok, 2 = arrows ok
132 short status;
133
134 char name[10];
135
136 // choice = menu item #.
137 // if status = 2,
138 // choice=0:leftarrow,1:rightarrow
139 void (*routine)(int choice);
140
141 // hotkey in menu
142 char alphaKey;
143}
144menuitem_t;
145
146
147
148typedef struct menu_s
149{
150 short numitems; // # of menu items
151 struct menu_s* prevMenu; // previous menu
152 menuitem_t* menuitems; // menu items
153 void (*routine)(void); // draw routine ROCKBOX
154 short x;
155 short y; // x,y of menu
156 short lastOn; // last item user was on in menu
157}
158menu_t;
159
160short itemOn; // menu item skull is on
161short skullAnimCounter; // skull animation counter
162short whichSkull; // which skull to draw
163int systemvol;
164
165// graphic name of skulls
166// warning: initializer-string for array of chars is too long
167char skullName[2][/*8*/9] = {"M_SKULL1","M_SKULL2"};
168
169// current menudef
170menu_t* currentMenu;
171
172//
173// PROTOTYPES
174//
175void M_NewGame(int choice);
176void M_Episode(int choice);
177void M_ChooseSkill(int choice);
178void M_LoadGame(int choice);
179void M_SaveGame(int choice);
180void M_Options(int choice);
181void M_EndGame(int choice);
182void M_ReadThis(int choice);
183void M_ReadThis2(int choice);
184void M_QuitDOOM(int choice);
185
186void M_ChangeMessages(int choice);
187void M_ChangeSensitivity(int choice);
188void M_SfxVol(int choice);
189void M_MusicVol(int choice);
190void M_SystemVol(int choice);
191void M_SizeDisplay(int choice);
192void M_StartGame(int choice);
193void M_Sound(int choice);
194
195void M_FinishReadThis(int choice);
196void M_LoadSelect(int choice);
197void M_SaveSelect(int choice);
198void M_ReadSaveStrings(void);
199void M_QuickSave(void);
200void M_QuickLoad(void);
201
202void M_DrawMainMenu(void);
203void M_DrawReadThis1(void);
204void M_DrawReadThis2(void);
205void M_DrawNewGame(void);
206void M_DrawEpisode(void);
207void M_DrawOptions(void);
208void M_DrawSound(void);
209void M_DrawLoad(void);
210void M_DrawSave(void);
211
212void M_DrawSaveLoadBorder(int x,int y);
213void M_SetupNextMenu(menu_t *menudef);
214void M_DrawThermo(int x,int y,int thermWidth,int thermDot);
215void M_DrawEmptyCell(menu_t *menu,int item);
216void M_DrawSelCell(menu_t *menu,int item);
217void M_WriteText(int x, int y, char *string);
218int M_StringWidth(const char* string);
219int M_StringHeight(const char* string);
220void M_StartControlPanel(void);
221void M_StartMessage(char *string,void *routine,boolean input);
222void M_StopMessage(void);
223void M_ClearMenus (void);
224
225
226
227
228//
229// DOOM MENU
230//
231enum
232{
233 newgame = 0,
234 options,
235 loadgame,
236 savegame,
237 readthis,
238 quitdoom,
239 main_end
240} main_e;
241
242menuitem_t MainMenu[]=
243 {
244 {1,"M_NGAME",M_NewGame,'n'},
245 {1,"M_OPTION",M_Options,'o'},
246 {1,"M_LOADG",M_LoadGame,'l'},
247 {1,"M_SAVEG",M_SaveGame,'s'},
248 // Another hickup with Special edition.
249 {1,"M_RDTHIS",M_ReadThis,'r'},
250 {1,"M_QUITG",M_QuitDOOM,'q'}
251 };
252
253menu_t MainDef =
254 {
255 main_end,
256 NULL,
257 MainMenu,
258 M_DrawMainMenu,
259 97,64,
260 0
261 };
262
263
264//
265// EPISODE SELECT
266//
267enum
268{
269 ep1,
270 ep2,
271 ep3,
272 ep4,
273 ep_end
274} episodes_e;
275
276menuitem_t EpisodeMenu[]=
277 {
278 {1,"M_EPI1", M_Episode,'k'},
279 {1,"M_EPI2", M_Episode,'t'},
280 {1,"M_EPI3", M_Episode,'i'},
281 {1,"M_EPI4", M_Episode,'t'}
282 };
283
284menu_t EpiDef =
285 {
286 ep_end, // # of menu items
287 &MainDef, // previous menu
288 EpisodeMenu, // menuitem_t ->
289 M_DrawEpisode, // drawing routine ->
290 48,63, // x,y
291 ep1 // lastOn
292 };
293
294//
295// NEW GAME
296//
297enum
298{
299 killthings,
300 toorough,
301 hurtme,
302 violence,
303 nightmare,
304 newg_end
305} newgame_e;
306
307menuitem_t NewGameMenu[]=
308 {
309 {1,"M_JKILL", M_ChooseSkill, 'i'},
310 {1,"M_ROUGH", M_ChooseSkill, 'h'},
311 {1,"M_HURT", M_ChooseSkill, 'h'},
312 {1,"M_ULTRA", M_ChooseSkill, 'u'},
313 {1,"M_NMARE", M_ChooseSkill, 'n'}
314 };
315
316menu_t NewDef =
317 {
318 newg_end, // # of menu items
319 &EpiDef, // previous menu
320 NewGameMenu, // menuitem_t ->
321 M_DrawNewGame, // drawing routine ->
322 48,63, // x,y
323 hurtme // lastOn
324 };
325
326
327
328//
329// OPTIONS MENU
330//
331enum
332{
333 endgame,
334 messages,
335 scrnsize,
336 option_empty1,
337 gamasens,
338 option_empty2,
339 soundvol,
340 opt_end
341} options_e;
342
343menuitem_t OptionsMenu[]=
344 {
345 {1,"M_ENDGAM", M_EndGame,'e'},
346 {1,"M_MESSG", M_ChangeMessages,'m'},
347 {2,"M_SCRNSZ", M_SizeDisplay,'s'},
348 {-1,"",0,0},
349 {2,"M_MSENS", M_ChangeSensitivity,'m'},
350 {-1,"",0,0},
351 {1,"M_SVOL", M_Sound,'s'}
352 };
353
354menu_t OptionsDef =
355 {
356 opt_end,
357 &MainDef,
358 OptionsMenu,
359 M_DrawOptions,
360 60,37,
361 0
362 };
363
364//
365// Read This! MENU 1 & 2
366//
367enum
368{
369 rdthsempty1,
370 read1_end
371} read_e;
372
373menuitem_t ReadMenu1[] =
374 {
375 {1,"",M_ReadThis2,0}
376 };
377
378menu_t ReadDef1 =
379 {
380 read1_end,
381 &MainDef,
382 ReadMenu1,
383 M_DrawReadThis1,
384 280,185,
385 0
386 };
387
388enum
389{
390 rdthsempty2,
391 read2_end
392} read_e2;
393
394menuitem_t ReadMenu2[]=
395 {
396 {1,"",M_FinishReadThis,0}
397 };
398
399menu_t ReadDef2 =
400 {
401 read2_end,
402 &ReadDef1,
403 ReadMenu2,
404 M_DrawReadThis2,
405 330,175,
406 0
407 };
408
409//
410// SOUND VOLUME MENU
411//
412enum
413{
414 sfx_vol,
415 sfx_empty1,
416 music_vol,
417 sfx_empty2,
418 system_vol,
419 sfx_empty3,
420 sound_end
421} sound_e;
422
423menuitem_t SoundMenu[]=
424 {
425 {2,"M_SFXVOL",M_SfxVol,'s'},
426 {-1,"",0,0}, //ROCKBOX
427 {2,"M_MUSVOL",M_MusicVol,'m'},
428 {-1,"",0,0}, //ROCKBOX
429 {2,"M_MUSVOL",M_SystemVol,'z'},
430 {-1,"",0,0} //ROCKBOX
431 };
432
433menu_t SoundDef =
434 {
435 sound_end,
436 &OptionsDef,
437 SoundMenu,
438 M_DrawSound,
439 80,64,
440 0
441 };
442
443//
444// LOAD GAME MENU
445//
446enum
447{
448 load1,
449 load2,
450 load3,
451 load4,
452 load5,
453 load6,
454 load_end
455} load_e;
456
457menuitem_t LoadMenu[]=
458 {
459 {1,"", M_LoadSelect,'1'},
460 {1,"", M_LoadSelect,'2'},
461 {1,"", M_LoadSelect,'3'},
462 {1,"", M_LoadSelect,'4'},
463 {1,"", M_LoadSelect,'5'},
464 {1,"", M_LoadSelect,'6'}
465 };
466
467menu_t LoadDef =
468 {
469 load_end,
470 &MainDef,
471 LoadMenu,
472 M_DrawLoad,
473 80,54,
474 0
475 };
476
477//
478// SAVE GAME MENU
479//
480menuitem_t SaveMenu[]=
481 {
482 {1,"", M_SaveSelect,'1'},
483 {1,"", M_SaveSelect,'2'},
484 {1,"", M_SaveSelect,'3'},
485 {1,"", M_SaveSelect,'4'},
486 {1,"", M_SaveSelect,'5'},
487 {1,"", M_SaveSelect,'6'}
488 };
489
490menu_t SaveDef =
491 {
492 load_end,
493 &MainDef,
494 SaveMenu,
495 M_DrawSave,
496 80,54,
497 0
498 };
499
500
501//
502// M_ReadSaveStrings
503// read the strings from the savegame files
504//
505void M_ReadSaveStrings(void)
506{
507 int handle;
508 int count;
509 int i;
510 char name[256];
511
512 for (i = 0;i < load_end;i++)
513 {
514 if (M_CheckParm("-cdrom"))
515 snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i);
516 else
517 snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",i);
518
519 handle = open (name, O_RDONLY | 0);
520 if (handle == -1)
521 {
522 strcpy(&savegamestrings[i][0],EMPTYSTRING);
523 LoadMenu[i].status = 0;
524 continue;
525 }
526 count = read (handle, &savegamestrings[i], SAVESTRINGSIZE);
527 close (handle);
528 LoadMenu[i].status = 1;
529 }
530}
531
532#define LOADGRAPHIC_Y 8
533//
534// M_LoadGame & Cie.
535//
536void M_DrawLoad(void)
537{
538 int i;
539
540 V_DrawNamePatch(72 ,LOADGRAPHIC_Y, 0, "M_LOADG", CR_DEFAULT, VPT_STRETCH);
541 for (i = 0;i < load_end; i++)
542 {
543 M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i);
544 M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]);
545 }
546}
547
548
549
550//
551// Draw border for the savegame description
552//
553void M_DrawSaveLoadBorder(int x,int y)
554{
555 int i;
556
557 V_DrawNamePatch(x-8, y+7, 0, "M_LSLEFT", CR_DEFAULT, VPT_STRETCH);
558 for (i = 0;i < 24;i++)
559 {
560 V_DrawNamePatch(x, y+7, 0, "M_LSCNTR", CR_DEFAULT, VPT_STRETCH);
561 x += 8;
562 }
563 V_DrawNamePatch(x, y+7, 0, "M_LSRGHT", CR_DEFAULT, VPT_STRETCH);
564}
565
566
567
568//
569// User wants to load this game
570//
571void M_LoadSelect(int choice)
572{
573 char name[256];
574
575 if (M_CheckParm("-cdrom"))
576 snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice);
577 else
578 snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",choice);
579 G_LoadGame (choice, false);
580 M_ClearMenus ();
581}
582
583//
584// Selected from DOOM menu
585//
586void M_LoadGame (int choice)
587{
588 (void)choice;
589 if (netgame)
590 {
591 M_StartMessage(LOADNET,NULL,false);
592 return;
593 }
594
595 M_SetupNextMenu(&LoadDef);
596 M_ReadSaveStrings();
597}
598
599
600//
601// M_SaveGame & Cie.
602//
603void M_DrawSave(void)
604{
605 int i;
606
607 V_DrawNamePatch(72, LOADGRAPHIC_Y, 0, "M_SAVEG", CR_DEFAULT, VPT_STRETCH);
608 for (i = 0;i < load_end; i++)
609 {
610 M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i);
611 M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]);
612 }
613
614 if (saveStringEnter)
615 {
616 i = M_StringWidth(savegamestrings[saveSlot]);
617 M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_");
618 }
619}
620
621//
622// M_Responder calls this when user is finished
623//
624void M_DoSave(int slot)
625{
626 G_SaveGame (slot,savegamestrings[slot]);
627 M_ClearMenus ();
628
629 // PICK QUICKSAVE SLOT YET?
630 if (quickSaveSlot == -2)
631 quickSaveSlot = slot;
632}
633
634//
635// User wants to save. Start string input for M_Responder
636//
637void M_SaveSelect(int choice)
638{
639 // we are going to be intercepting all chars
640 saveStringEnter = 1;
641
642 saveSlot = choice;
643 snprintf(savegamestrings[choice], sizeof(savegamestrings[choice]), "Mysave%d", choice);
644// strcpy(saveOldString,savegamestrings[choice]);
645 if (!strcmp(savegamestrings[choice],EMPTYSTRING))
646 savegamestrings[choice][0] = 0;
647 saveCharIndex = strlen(savegamestrings[choice]);
648}
649
650//
651// Selected from DOOM menu
652//
653void M_SaveGame (int choice)
654{
655 (void)choice;
656 if (!usergame)
657 {
658 M_StartMessage(SAVEDEAD,NULL,false);
659 return;
660 }
661
662 if (gamestate != GS_LEVEL)
663 return;
664
665 M_SetupNextMenu(&SaveDef);
666 M_ReadSaveStrings();
667}
668
669
670
671//
672// M_QuickSave
673//
674char tempstring[80];
675
676void M_QuickSaveResponse(int ch)
677{
678 if (ch == 'y')
679 {
680 M_DoSave(quickSaveSlot);
681
682 S_StartSound(NULL,sfx_swtchx);
683
684 }
685}
686
687void M_QuickSave(void)
688{
689 if (!usergame)
690 {
691 S_StartSound(NULL,sfx_oof);
692 return;
693 }
694
695 if (gamestate != GS_LEVEL)
696 return;
697
698 if (quickSaveSlot < 0)
699 {
700 M_StartControlPanel();
701 M_ReadSaveStrings();
702 M_SetupNextMenu(&SaveDef);
703 quickSaveSlot = -2; // means to pick a slot now
704 return;
705 }
706 snprintf(tempstring,sizeof(tempstring),QSPROMPT,savegamestrings[quickSaveSlot]);
707 M_StartMessage(tempstring,M_QuickSaveResponse,true);
708}
709
710
711
712//
713// M_QuickLoad
714//
715void M_QuickLoadResponse(int ch)
716{
717 if (ch == 'y')
718 {
719 M_LoadSelect(quickSaveSlot);
720 S_StartSound(NULL,sfx_swtchx);
721 }
722}
723
724
725void M_QuickLoad(void)
726{
727 if (netgame)
728 {
729 M_StartMessage(QLOADNET,NULL,false);
730 return;
731 }
732
733 if (quickSaveSlot < 0)
734 {
735 M_StartMessage(QSAVESPOT,NULL,false);
736 return;
737 }
738 snprintf(tempstring, sizeof(tempstring), QLPROMPT,savegamestrings[quickSaveSlot]);
739 M_StartMessage(tempstring,M_QuickLoadResponse,true);
740}
741
742
743
744
745//
746// Read This Menus
747// Had a "quick hack to fix romero bug"
748//
749void M_DrawReadThis1(void)
750{
751 inhelpscreens = true;
752 switch ( gamemode )
753 {
754 case commercial:
755 V_DrawNamePatch(0, 0, 0, "HELP", CR_DEFAULT, VPT_STRETCH);
756 break;
757 case shareware:
758 case registered:
759 case retail:
760 V_DrawNamePatch(0, 0, 0, "HELP1", CR_DEFAULT, VPT_STRETCH);
761 break;
762 default:
763 break;
764 }
765 return;
766}
767
768
769
770//
771// Read This Menus - optional second page.
772//
773void M_DrawReadThis2(void)
774{
775 inhelpscreens = true;
776 switch ( gamemode )
777 {
778 case retail:
779 case commercial:
780 // This hack keeps us from having to change menus.
781 V_DrawNamePatch(0, 0, 0, "CREDIT", CR_DEFAULT, VPT_STRETCH);
782 break;
783 case shareware:
784 case registered:
785 V_DrawNamePatch(0, 0, 0, "HELP2", CR_DEFAULT, VPT_STRETCH);
786 break;
787 default:
788 break;
789 }
790 return;
791}
792
793
794//
795// Change Sfx & Music volumes
796//
797void M_DrawSound(void)
798{
799 int sysmax=(rb->sound_max(SOUND_VOLUME)-rb->sound_min(SOUND_VOLUME));
800 V_DrawNamePatch(60, 38, 0, "M_SVOL", CR_DEFAULT, VPT_STRETCH);
801
802 M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1),
803 16,snd_SfxVolume);
804
805 M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1),
806 16,snd_MusicVolume);
807
808 M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(system_vol+1),
809 16,(sysmax+systemvol)/5);
810}
811
812void M_Sound(int choice)
813{
814 (void) choice;
815 M_SetupNextMenu(&SoundDef);
816}
817
818void M_SfxVol(int choice)
819{
820 switch(choice)
821 {
822 case 0:
823 if (snd_SfxVolume)
824 snd_SfxVolume--;
825 break;
826 case 1:
827 if (snd_SfxVolume < 15)
828 snd_SfxVolume++;
829 break;
830 }
831
832 S_SetSfxVolume(snd_SfxVolume /* *8 */);
833}
834
835void M_MusicVol(int choice)
836{
837 switch(choice)
838 {
839 case 0:
840 if (snd_MusicVolume)
841 snd_MusicVolume--;
842 break;
843 case 1:
844 if (snd_MusicVolume < 15)
845 snd_MusicVolume++;
846 break;
847 }
848
849 S_SetMusicVolume(snd_MusicVolume /* *8 */);
850}
851
852void M_SystemVol(int choice)
853{
854 switch(choice)
855 {
856 case 0:
857 if (systemvol-5>rb->sound_min(SOUND_VOLUME))
858 {
859 systemvol-=5;
860 rb->sound_set(SOUND_VOLUME, systemvol);
861 rb->global_settings->volume = systemvol;
862 }
863 break;
864 case 1:
865 if (systemvol+5<rb->sound_max(SOUND_VOLUME))
866 {
867 systemvol+=5;
868 rb->sound_set(SOUND_VOLUME, systemvol);
869 rb->global_settings->volume = systemvol;
870 }
871 break;
872 }
873}
874
875//
876// M_DrawMainMenu
877//
878void M_DrawMainMenu(void)
879{
880 V_DrawNamePatch(94, 2, 0, "M_DOOM", CR_DEFAULT, VPT_STRETCH);
881}
882
883
884
885
886//
887// M_NewGame
888//
889void M_DrawNewGame(void)
890{
891 // CPhipps - patch drawing updated
892 V_DrawNamePatch(96, 14, 0, "M_NEWG", CR_DEFAULT, VPT_STRETCH);
893 V_DrawNamePatch(54, 38, 0, "M_SKILL",CR_DEFAULT, VPT_STRETCH);
894}
895
896void M_NewGame(int choice)
897{
898 (void) choice;
899 if (netgame && !demoplayback)
900 {
901 M_StartMessage(NEWGAME,NULL,false);
902 return;
903 }
904
905 if ( gamemode == commercial )
906 M_SetupNextMenu(&NewDef);
907 else
908 M_SetupNextMenu(&EpiDef);
909}
910
911
912//
913// M_Episode
914//
915int epi;
916
917void M_DrawEpisode(void)
918{
919 // CPhipps - patch drawing updated
920 V_DrawNamePatch(54, 38, 0, "M_EPISOD", CR_DEFAULT, VPT_STRETCH);
921}
922
923void M_VerifyNightmare(int ch)
924{
925 if (ch != KEY_ENTER)
926 return;
927
928 G_DeferedInitNew(nightmare,epi+1,1);
929 M_ClearMenus ();
930}
931
932void M_ChooseSkill(int choice)
933{
934 if (choice == nightmare)
935 {
936 M_StartMessage(NIGHTMARE,M_VerifyNightmare,true);
937 return;
938 }
939
940 //jff 3/24/98 remember last skill selected
941 // killough 10/98 moved to here
942 defaultskill = choice+1;
943
944 G_DeferedInitNew(choice,epi+1,1);
945 M_ClearMenus ();
946}
947
948void M_Episode(int choice)
949{
950 if ( (gamemode == shareware)
951 && choice)
952 {
953 M_StartMessage(SWSTRING,NULL,false);
954 M_SetupNextMenu(&ReadDef1);
955 return;
956 }
957
958 // Yet another hack...
959 if ( (gamemode == registered)
960 && (choice > 2))
961 {
962 /* Digita */
963 // fprintf( stderr,
964 // "M_Episode: 4th episode requires UltimateDOOM\n");
965 choice = 0;
966 }
967
968 epi = choice;
969 M_SetupNextMenu(&NewDef);
970}
971
972
973
974//
975// M_Options
976//
977char detailNames[2][9] = {"M_GDHIGH","M_GDLOW"};
978char msgNames[2][9] = {"M_MSGOFF","M_MSGON"};
979
980
981void M_DrawOptions(void)
982{
983 // CPhipps - patch drawing updated
984 V_DrawNamePatch(108, 15, 0, "M_OPTTTL", CR_DEFAULT, VPT_STRETCH);
985
986 V_DrawNamePatch(OptionsDef.x + 120, OptionsDef.y+LINEHEIGHT*messages, 0,
987 msgNames[showMessages], CR_DEFAULT, VPT_STRETCH);
988
989 M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(gamasens+1),
990 4,usegamma);
991
992 M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1),
993 9,screenSize);
994}
995
996void M_Options(int choice)
997{
998 (void)choice;
999 M_SetupNextMenu(&OptionsDef);
1000}
1001
1002
1003
1004//
1005// Toggle messages on/off
1006//
1007void M_ChangeMessages(int choice)
1008{
1009 // warning: unused parameter `int choice'
1010 choice = 0;
1011 showMessages = 1 - showMessages;
1012
1013 if (!showMessages)
1014 players[consoleplayer].message = MSGOFF;
1015 else
1016 players[consoleplayer].message = MSGON ;
1017
1018 message_dontfuckwithme = true;
1019}
1020
1021
1022//
1023// M_EndGame
1024//
1025void M_EndGameResponse(int ch)
1026{
1027 if (ch != KEY_ENTER)
1028 return;
1029
1030 // killough 5/26/98: make endgame quit if recording or playing back demo
1031 if (demorecording || singledemo)
1032 G_CheckDemoStatus();
1033
1034 currentMenu->lastOn = itemOn;
1035 M_ClearMenus ();
1036 D_StartTitle ();
1037}
1038
1039void M_EndGame(int choice)
1040{
1041 choice = 0;
1042 if (!usergame)
1043 {
1044 S_StartSound(NULL,sfx_oof);
1045 return;
1046 }
1047
1048 if (netgame)
1049 {
1050 M_StartMessage(NETEND,NULL,false);
1051 return;
1052 }
1053
1054 M_StartMessage(ENDGAME,M_EndGameResponse,true);
1055}
1056
1057
1058
1059
1060//
1061// M_ReadThis
1062//
1063void M_ReadThis(int choice)
1064{
1065 choice = 0;
1066 M_SetupNextMenu(&ReadDef1);
1067}
1068
1069void M_ReadThis2(int choice)
1070{
1071 choice = 0;
1072 M_SetupNextMenu(&ReadDef2);
1073}
1074
1075void M_FinishReadThis(int choice)
1076{
1077 choice = 0;
1078 M_SetupNextMenu(&MainDef);
1079}
1080
1081
1082
1083
1084//
1085// M_QuitDOOM
1086//
1087int quitsounds[8] =
1088 {
1089 sfx_pldeth,
1090 sfx_dmpain,
1091 sfx_popain,
1092 sfx_slop,
1093 sfx_telept,
1094 sfx_posit1,
1095 sfx_posit3,
1096 sfx_sgtatk
1097 };
1098
1099int quitsounds2[8] =
1100 {
1101 sfx_vilact,
1102 sfx_getpow,
1103 sfx_boscub,
1104 sfx_slop,
1105 sfx_skeswg,
1106 sfx_kntdth,
1107 sfx_bspact,
1108 sfx_sgtatk
1109 };
1110
1111
1112
1113void M_QuitResponse(int ch)
1114{
1115 if (ch != KEY_ENTER)
1116 return;
1117 if (!netgame)
1118 {
1119 if (gamemode == commercial)
1120 S_StartSound(NULL,quitsounds2[(gametic>>2)&7]);
1121 else
1122 S_StartSound(NULL,quitsounds[(gametic>>2)&7]);
1123 I_WaitVBL(105);
1124 }
1125 I_Quit ();
1126}
1127
1128
1129
1130
1131void M_QuitDOOM(int choice)
1132{
1133 (void)choice;
1134 // We pick index 0 which is language sensitive,
1135 // or one at random, between 1 and maximum number.
1136 if (language != english )
1137 snprintf(endstring,sizeof(endstring),"%s\n\n"DOSY, endmsg[0] );
1138 else
1139 snprintf(endstring,sizeof(endstring),"%s\n\n%s", endmsg[gametic%(NUM_QUITMESSAGES-1)+1], DOSY);
1140
1141 M_StartMessage(endstring,M_QuitResponse,true);
1142}
1143
1144
1145
1146
1147void M_ChangeSensitivity(int choice)
1148{
1149 switch(choice)
1150 {
1151 case 0:
1152 if (usegamma)
1153 usegamma--;
1154 break;
1155 case 1:
1156 if (usegamma < 4)
1157 usegamma++;
1158 break;
1159 }
1160 V_SetPalette (0);
1161}
1162
1163void M_SizeDisplay(int choice)
1164{
1165 switch(choice)
1166 {
1167 case 0:
1168 if (screenSize > 0)
1169 {
1170 screenblocks--;
1171 screenSize--;
1172 }
1173 break;
1174 case 1:
1175 if (screenSize < 8)
1176 {
1177 screenblocks++;
1178 screenSize++;
1179 }
1180 break;
1181 }
1182
1183
1184 R_SetViewSize (screenblocks);
1185}
1186
1187
1188
1189
1190//
1191// Menu Functions
1192//
1193void
1194M_DrawThermo
1195( int x,
1196 int y,
1197 int thermWidth,
1198 int thermDot )
1199{
1200 int xx;
1201 int i;
1202
1203 xx = x;
1204 V_DrawNamePatch(xx, y, 0, "M_THERML", CR_DEFAULT, VPT_STRETCH);
1205 xx += 8;
1206 for (i=0;i<thermWidth;i++)
1207 {
1208 V_DrawNamePatch(xx, y, 0, "M_THERMM", CR_DEFAULT, VPT_STRETCH);
1209 xx += 8;
1210 }
1211 V_DrawNamePatch(xx, y, 0, "M_THERMR", CR_DEFAULT, VPT_STRETCH);
1212 V_DrawNamePatch((x+8)+thermDot*8,y,0,"M_THERMO",CR_DEFAULT,VPT_STRETCH);
1213}
1214
1215
1216
1217void
1218M_DrawEmptyCell
1219( menu_t* menu,
1220 int item )
1221{
1222 // CPhipps - patch drawing updated
1223 V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0,
1224 "M_CELL1", CR_DEFAULT, VPT_STRETCH);
1225}
1226
1227void
1228M_DrawSelCell
1229( menu_t* menu,
1230 int item )
1231{
1232 // CPhipps - patch drawing updated
1233 V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0,
1234 "M_CELL2", CR_DEFAULT, VPT_STRETCH);
1235}
1236
1237
1238void
1239M_StartMessage
1240( char* string,
1241 void* routine,
1242 boolean input )
1243{
1244 messageLastMenuActive = menuactive;
1245 messageToPrint = 1;
1246 messageString = string;
1247 messageRoutine = routine;
1248 messageNeedsInput = input;
1249 menuactive = true;
1250 return;
1251}
1252
1253
1254
1255void M_StopMessage(void)
1256{
1257 menuactive = messageLastMenuActive;
1258 messageToPrint = 0;
1259}
1260
1261
1262
1263//
1264// Find string width from hu_font chars
1265//
1266int M_StringWidth(const char* string)
1267{
1268 int i, c, w = 0;
1269 for (i = 0;(size_t)i < strlen(string);i++)
1270 w += (c = toupper(string[i]) - HU_FONTSTART) < 0 || c >= HU_FONTSIZE ?
1271 4 : SHORT(hu_font[c].width);
1272 return w;
1273}
1274
1275//
1276// Find string height from hu_font chars
1277//
1278
1279int M_StringHeight(const char* string)
1280{
1281 int i, h, height = h = SHORT(hu_font[0].height);
1282 for (i = 0;string[i];i++) // killough 1/31/98
1283 if (string[i] == '\n')
1284 h += height;
1285 return h;
1286}
1287
1288
1289//
1290// Write a string using the hu_font
1291//
1292void
1293M_WriteText
1294( int x,
1295 int y,
1296 char* string)
1297{
1298 int w;
1299 char* ch;
1300 int c;
1301 int cx;
1302 int cy;
1303
1304
1305 ch = string;
1306 cx = x;
1307 cy = y;
1308
1309 while(1)
1310 {
1311 c = *ch++;
1312 if (!c)
1313 break;
1314 if (c == '\n')
1315 {
1316 cx = x;
1317 cy += 12;
1318 continue;
1319 }
1320
1321 c = toupper(c) - HU_FONTSTART;
1322 if (c < 0 || c>= HU_FONTSIZE)
1323 {
1324 cx += 4;
1325 continue;
1326 }
1327
1328 w = SHORT (hu_font[c].width);
1329 if (cx+w > SCREENWIDTH)
1330 break;
1331 // proff/nicolas 09/20/98 -- changed for hi-res
1332 // CPhipps - patch drawing updated
1333 V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH);
1334 cx+=w;
1335 }
1336}
1337
1338
1339
1340//
1341// CONTROL PANEL
1342//
1343
1344//
1345// M_Responder
1346//
1347boolean M_Responder (event_t* ev)
1348{
1349 int ch;
1350 int i;
1351// static int joywait = 0;
1352// static int mousewait = 0;
1353// static int mousey = 0;
1354// static int lasty = 0;
1355// static int mousex = 0;
1356// static int lastx = 0;
1357
1358 ch = -1;
1359
1360 // Process joystick input
1361
1362/* if (ev->type == ev_joystick && joywait < I_GetTime())
1363 {
1364 if (ev->data3 == -1)
1365 {
1366 ch = KEY_UPARROW;
1367 joywait = I_GetTime() + 5;
1368 }
1369 else if (ev->data3 == 1)
1370 {
1371 ch = KEY_DOWNARROW;
1372 joywait = I_GetTime() + 5;
1373 }
1374
1375 if (ev->data2 == -1)
1376 {
1377 ch = KEY_LEFTARROW;
1378 joywait = I_GetTime() + 2;
1379 }
1380 else if (ev->data2 == 1)
1381 {
1382 ch = KEY_RIGHTARROW;
1383 joywait = I_GetTime() + 2;
1384 }
1385
1386 if (ev->data1&1)
1387 {
1388 ch = KEY_ENTER;
1389 joywait = I_GetTime() + 5;
1390 }
1391 if (ev->data1&2)
1392 {
1393 ch = KEY_BACKSPACE;
1394 joywait = I_GetTime() + 5;
1395 }
1396 }
1397 else
1398 {
1399 // Process mouse input
1400 if (ev->type == ev_mouse && mousewait < I_GetTime())
1401 {
1402 mousey += ev->data3;
1403 if (mousey < lasty-30)
1404 {
1405 ch = KEY_DOWNARROW;
1406 mousewait = I_GetTime() + 5;
1407 mousey = lasty -= 30;
1408 }
1409 else if (mousey > lasty+30)
1410 {
1411 ch = KEY_UPARROW;
1412 mousewait = I_GetTime() + 5;
1413 mousey = lasty += 30;
1414 }
1415
1416 mousex += ev->data2;
1417 if (mousex < lastx-30)
1418 {
1419 ch = KEY_LEFTARROW;
1420 mousewait = I_GetTime() + 5;
1421 mousex = lastx -= 30;
1422 }
1423 else if (mousex > lastx+30)
1424 {
1425 ch = KEY_RIGHTARROW;
1426 mousewait = I_GetTime() + 5;
1427 mousex = lastx += 30;
1428 }
1429
1430 if (ev->data1&1)
1431 {
1432 ch = KEY_ENTER;
1433 mousewait = I_GetTime() + 15;
1434 }
1435
1436 if (ev->data1&2)
1437 {
1438 ch = KEY_BACKSPACE;
1439 mousewait = I_GetTime() + 15;
1440 }
1441 }
1442 else */if (ev->type == ev_keydown)
1443 {
1444 ch = ev->data1;
1445 }
1446// }
1447
1448 if (ch == -1)
1449 return false;
1450
1451
1452 // Save Game string input
1453 if (saveStringEnter)
1454 {
1455 switch(ch)
1456 {
1457 case KEY_BACKSPACE:
1458 if (saveCharIndex > 0)
1459 {
1460 saveCharIndex--;
1461 savegamestrings[saveSlot][saveCharIndex] = 0;
1462 }
1463 break;
1464
1465 case KEY_ESCAPE:
1466 saveStringEnter = 0;
1467 strcpy(&savegamestrings[saveSlot][0],saveOldString);
1468 break;
1469
1470 case KEY_ENTER:
1471 saveStringEnter = 0;
1472 if (savegamestrings[saveSlot][0])
1473 M_DoSave(saveSlot);
1474 break;
1475
1476 default:
1477 ch = toupper(ch);
1478 if (ch != 32)
1479 if (ch-HU_FONTSTART < 0 || ch-HU_FONTSTART >= HU_FONTSIZE)
1480 break;
1481 if (ch >= 32 && ch <= 127 &&
1482 saveCharIndex < SAVESTRINGSIZE-1 &&
1483 M_StringWidth(savegamestrings[saveSlot]) <
1484 (SAVESTRINGSIZE-2)*8)
1485 {
1486 savegamestrings[saveSlot][saveCharIndex++] = ch;
1487 savegamestrings[saveSlot][saveCharIndex] = 0;
1488 }
1489 break;
1490 }
1491 return true;
1492 }
1493
1494 // Take care of any messages that need input
1495 if (messageToPrint)
1496 {
1497 if (messageNeedsInput == true &&
1498 !(ch == ' ' || ch == 'n' || ch == KEY_ENTER || ch == KEY_ESCAPE))
1499 return false;
1500
1501 menuactive = messageLastMenuActive;
1502 messageToPrint = 0;
1503 if (messageRoutine)
1504 messageRoutine(ch);
1505
1506 menuactive = false;
1507 S_StartSound(NULL,sfx_swtchx);
1508 return true;
1509 }
1510/*
1511 if (ch == KEY_F1) // devparm &&
1512 {
1513 G_ScreenShot ();
1514 return true;
1515 }
1516*/
1517 // F-Keys
1518 if (!menuactive)
1519 switch(ch)
1520 {
1521 case KEY_MINUS: // Screen size down
1522 if ((automapmode & am_active) || chat_on)
1523 return false;
1524 M_SizeDisplay(0);
1525 S_StartSound(NULL,sfx_stnmov);
1526 return true;
1527
1528 case KEY_EQUALS: // Screen size up
1529 if ((automapmode & am_active) || chat_on)
1530 return false;
1531 M_SizeDisplay(1);
1532 S_StartSound(NULL,sfx_stnmov);
1533 return true;
1534/*
1535 case KEY_F1: // Help key
1536 M_StartControlPanel ();
1537
1538 if ( gamemode == retail )
1539 currentMenu = &ReadDef2;
1540 else
1541 currentMenu = &ReadDef1;
1542
1543 itemOn = 0;
1544 S_StartSound(NULL,sfx_swtchn);
1545 return true;
1546
1547 case KEY_F6: // Quicksave
1548 S_StartSound(NULL,sfx_swtchn);
1549 M_QuickSave();
1550 return true;
1551
1552 case KEY_F9: // Quickload
1553 S_StartSound(NULL,sfx_swtchn);
1554 M_QuickLoad();
1555 return true;
1556*/
1557 }
1558
1559
1560 // Pop-up menu?
1561 if (!menuactive)
1562 {
1563 if (ch == KEY_ESCAPE)
1564 {
1565 M_StartControlPanel ();
1566 S_StartSound(NULL,sfx_swtchn);
1567 return true;
1568 }
1569 return false;
1570 }
1571
1572
1573 // Keys usable within menu
1574 switch (ch)
1575 {
1576 case KEY_DOWNARROW:
1577 do
1578 {
1579 if (itemOn+1 > currentMenu->numitems-1)
1580 itemOn = 0;
1581 else
1582 itemOn++;
1583 S_StartSound(NULL,sfx_pstop);
1584 }
1585 while(currentMenu->menuitems[itemOn].status==-1);
1586 return true;
1587
1588 case KEY_UPARROW:
1589 do
1590 {
1591 if (!itemOn)
1592 itemOn = currentMenu->numitems-1;
1593 else
1594 itemOn--;
1595 S_StartSound(NULL,sfx_pstop);
1596 }
1597 while(currentMenu->menuitems[itemOn].status==-1);
1598 return true;
1599
1600 case KEY_LEFTARROW:
1601 if (currentMenu->menuitems[itemOn].routine &&
1602 currentMenu->menuitems[itemOn].status == 2)
1603 {
1604 S_StartSound(NULL,sfx_stnmov);
1605 currentMenu->menuitems[itemOn].routine(0);
1606 }
1607 return true;
1608
1609 case KEY_RIGHTARROW:
1610 if (currentMenu->menuitems[itemOn].routine &&
1611 currentMenu->menuitems[itemOn].status == 2)
1612 {
1613 S_StartSound(NULL,sfx_stnmov);
1614 currentMenu->menuitems[itemOn].routine(1);
1615 }
1616 return true;
1617
1618 case KEY_ENTER:
1619 if (currentMenu->menuitems[itemOn].routine &&
1620 currentMenu->menuitems[itemOn].status)
1621 {
1622 currentMenu->lastOn = itemOn;
1623 if (currentMenu->menuitems[itemOn].status == 2)
1624 {
1625 currentMenu->menuitems[itemOn].routine(1); // right arrow
1626 S_StartSound(NULL,sfx_stnmov);
1627 }
1628 else
1629 {
1630 currentMenu->menuitems[itemOn].routine(itemOn);
1631 S_StartSound(NULL,sfx_pistol);
1632 }
1633 }
1634 return true;
1635
1636 case KEY_ESCAPE:
1637 currentMenu->lastOn = itemOn;
1638 M_ClearMenus ();
1639 S_StartSound(NULL,sfx_swtchx);
1640 return true;
1641
1642 case KEY_BACKSPACE:
1643 currentMenu->lastOn = itemOn;
1644 if (currentMenu->prevMenu)
1645 {
1646 currentMenu = currentMenu->prevMenu;
1647 itemOn = currentMenu->lastOn;
1648 S_StartSound(NULL,sfx_swtchn);
1649 }
1650 return true;
1651
1652 default:
1653 for (i = itemOn+1;i < currentMenu->numitems;i++)
1654 if (currentMenu->menuitems[i].alphaKey == ch)
1655 {
1656 itemOn = i;
1657 S_StartSound(NULL,sfx_pstop);
1658 return true;
1659 }
1660 for (i = 0;i <= itemOn;i++)
1661 if (currentMenu->menuitems[i].alphaKey == ch)
1662 {
1663 itemOn = i;
1664 S_StartSound(NULL,sfx_pstop);
1665 return true;
1666 }
1667 break;
1668
1669 }
1670
1671 return false;
1672}
1673
1674
1675
1676//
1677// M_StartControlPanel
1678//
1679void M_StartControlPanel (void)
1680{
1681 // intro might call this repeatedly
1682 if (menuactive)
1683 return;
1684
1685 menuactive = 1;
1686 currentMenu = &MainDef; // JDC
1687 itemOn = currentMenu->lastOn; // JDC
1688}
1689
1690
1691//
1692// M_Drawer
1693// Called after the view has been rendered,
1694// but before it has been blitted.
1695//
1696void M_Drawer (void)
1697{
1698 static short x;
1699 static short y;
1700 unsigned short i;
1701 short max;
1702 char string[40];
1703 int start;
1704
1705 inhelpscreens = false;
1706
1707
1708 // Horiz. & Vertically center string and print it.
1709 if (messageToPrint)
1710 {
1711 start = 0;
1712 y = 100 - M_StringHeight(messageString)/2;
1713 while(*(messageString+start))
1714 {
1715 for (i = 0;i < strlen(messageString+start);i++)
1716 if (*(messageString+start+i) == '\n')
1717 {
1718 memset(string,0,40);
1719 strncpy(string,messageString+start,i);
1720 start += i+1;
1721 break;
1722 }
1723 if (i == strlen(messageString+start))
1724 {
1725 strcpy(string,messageString+start);
1726 start += i;
1727 }
1728
1729 x = 160 - M_StringWidth(string)/2;
1730 M_WriteText(x,y,string);
1731 y += SHORT(hu_font[0].height);
1732 }
1733 return;
1734 }
1735
1736 if (!menuactive)
1737 return;
1738
1739 if (currentMenu->routine)
1740 currentMenu->routine(); // call Draw routine
1741
1742 // DRAW MENU
1743 x = currentMenu->x;
1744 y = currentMenu->y;
1745 max = currentMenu->numitems;
1746
1747 for (i=0;i<max;i++)
1748 {
1749 if (currentMenu->menuitems[i].name[0])
1750 V_DrawNamePatch(x,y,0,currentMenu->menuitems[i].name,
1751 CR_DEFAULT, VPT_STRETCH);
1752 y += LINEHEIGHT;
1753 }
1754
1755 // DRAW SKULL
1756 // CPhipps - patch drawing updated
1757 V_DrawNamePatch(x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,0,
1758 skullName[whichSkull], CR_DEFAULT, VPT_STRETCH);
1759
1760}
1761
1762
1763//
1764// M_ClearMenus
1765//
1766void M_ClearMenus (void)
1767{
1768 menuactive = 0;
1769 // if (!netgame && usergame && paused)
1770 // sendpause = true;
1771}
1772
1773
1774
1775
1776//
1777// M_SetupNextMenu
1778//
1779void M_SetupNextMenu(menu_t *menudef)
1780{
1781 currentMenu = menudef;
1782 itemOn = currentMenu->lastOn;
1783}
1784
1785
1786//
1787// M_Ticker
1788//
1789void M_Ticker (void)
1790{
1791 if (--skullAnimCounter <= 0)
1792 {
1793 whichSkull ^= 1;
1794 skullAnimCounter = 8;
1795 }
1796}
1797
1798
1799//
1800// M_Init
1801//
1802void M_Init (void)
1803{
1804 currentMenu = &MainDef;
1805 menuactive = 0;
1806 itemOn = currentMenu->lastOn;
1807 whichSkull = 0;
1808 skullAnimCounter = 10;
1809 screenSize = screenblocks - 3;
1810 messageToPrint = 0;
1811 messageString = NULL;
1812 messageLastMenuActive = menuactive;
1813 quickSaveSlot = -1;
1814
1815 // Here we could catch other version dependencies,
1816 // like HELP1/2, and four episodes.
1817
1818
1819 switch ( gamemode )
1820 {
1821 case commercial:
1822 // This is used because DOOM 2 had only one HELP
1823 // page. I use CREDIT as second page now, but
1824 // kept this hack for educational purposes.
1825 MainMenu[readthis] = MainMenu[quitdoom];
1826 MainDef.numitems--;
1827 MainDef.y += 8;
1828 NewDef.prevMenu = &MainDef;
1829 ReadDef1.routine = M_DrawReadThis1;
1830 ReadDef1.x = 330;
1831 ReadDef1.y = 165;
1832 ReadMenu1[0].routine = M_FinishReadThis;
1833 break;
1834 case shareware:
1835 // Episode 2 and 3 are handled,
1836 // branching to an ad screen.
1837 case registered:
1838 // We need to remove the fourth episode.
1839 EpiDef.numitems--;
1840 break;
1841 case retail:
1842 // We are fine.
1843 default:
1844 break;
1845 }
1846
1847}
1848