67f215032d
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29841 a1c6a512-1295-4272-9138-f99709370657
1862 lines
35 KiB
C
1862 lines
35 KiB
C
// Emacs style mode select -*- C++ -*-
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Id$
|
|
//
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// $Log$
|
|
// Revision 1.7 2006/12/13 04:44:17 kkurbjun
|
|
// Dehacked and BEX support for Doom - currently only supports a DEHACKED file in a WAD (not as a standalone file yet).
|
|
//
|
|
// Revision 1.6 2006-04-16 23:14:04 kkurbjun
|
|
// Fix run so that it stays enabled across level loads. Removed some unused code and added some back in for hopeful future use.
|
|
//
|
|
// Revision 1.5 2006-04-04 23:58:37 kkurbjun
|
|
// Make savegame strings more informative
|
|
//
|
|
// Revision 1.4 2006-04-04 23:13:50 kkurbjun
|
|
// Fix up configurable keys, edit exit string, more work needs to be done on menu keys
|
|
//
|
|
// Revision 1.3 2006-04-03 20:03:02 kkurbjun
|
|
// Updates doom menu w/ new graphics, now requires rockdoom.wad: http://alamode.mines.edu/~kkurbjun/rockdoom.wad
|
|
//
|
|
// Revision 1.2 2006-04-03 00:28:13 kkurbjun
|
|
// Fixes graphic errors in scaling code, note sure about the fix in hu_lib.c though. I havn't seen any corrupted text but it may still need a proper fix.
|
|
//
|
|
// Revision 1.1 2006-03-28 15:44:01 dave
|
|
// Patch #2969 - Doom! Currently only working on the H300.
|
|
//
|
|
//
|
|
// DESCRIPTION:
|
|
// DOOM selection menu, options, episode etc.
|
|
// Sliders and icons. Kinda widget stuff.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "doomdef.h"
|
|
#include "dstrings.h"
|
|
|
|
#include "d_main.h"
|
|
|
|
#include "i_system.h"
|
|
#include "i_video.h"
|
|
#include "z_zone.h"
|
|
#include "v_video.h"
|
|
#include "w_wad.h"
|
|
|
|
#include "r_main.h"
|
|
#include "d_deh.h"
|
|
#include "hu_stuff.h"
|
|
|
|
#include "g_game.h"
|
|
|
|
#include "m_argv.h"
|
|
#include "m_swap.h"
|
|
#include "s_sound.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
// Data.
|
|
#include "sounds.h"
|
|
|
|
#include "m_menu.h"
|
|
#include "rockmacros.h"
|
|
|
|
|
|
extern patchnum_t hu_font[HU_FONTSIZE];
|
|
extern boolean message_dontfuckwithme;
|
|
|
|
extern boolean chat_on; // in heads-up code
|
|
|
|
//
|
|
// defaulted values
|
|
//
|
|
int mouseSensitivity; // has default
|
|
|
|
// Show messages has default, 0 = off, 1 = on
|
|
int showMessages;
|
|
|
|
// Blocky mode, has default, 0 = high, 1 = normal
|
|
int screenblocks; // has default
|
|
|
|
// temp for screenblocks (0-9)
|
|
int screenSize;
|
|
|
|
// -1 = no quicksave slot picked!
|
|
int quickSaveSlot;
|
|
|
|
// 1 = message to be printed
|
|
int messageToPrint;
|
|
// ...and here is the message string!
|
|
const char* messageString;
|
|
|
|
// message x & y
|
|
int messx;
|
|
int messy;
|
|
int messageLastMenuActive;
|
|
|
|
// timed message = no input from user
|
|
boolean messageNeedsInput;
|
|
|
|
void (*messageRoutine)(int response);
|
|
|
|
#define SAVESTRINGSIZE 24
|
|
|
|
// we are going to be entering a savegame string
|
|
int saveStringEnter;
|
|
int saveSlot; // which slot to save in
|
|
int saveCharIndex; // which char we're editing
|
|
// old save description before edit
|
|
char saveOldString[SAVESTRINGSIZE];
|
|
|
|
boolean inhelpscreens;
|
|
boolean menuactive;
|
|
|
|
#define SKULLXOFF -32
|
|
#define LINEHEIGHT 16
|
|
|
|
extern boolean sendpause;
|
|
char savegamestrings[10][SAVESTRINGSIZE];
|
|
|
|
char endstring[170];
|
|
|
|
|
|
//
|
|
// MENU TYPEDEFS
|
|
//
|
|
typedef struct
|
|
{
|
|
// 0 = no cursor here, 1 = ok, 2 = arrows ok
|
|
short status;
|
|
|
|
char name[10];
|
|
|
|
// choice = menu item #.
|
|
// if status = 2,
|
|
// choice=0:leftarrow,1:rightarrow
|
|
void (*routine)(int choice);
|
|
|
|
// hotkey in menu
|
|
char alphaKey;
|
|
}
|
|
menuitem_t;
|
|
|
|
|
|
|
|
typedef struct menu_s
|
|
{
|
|
short numitems; // # of menu items
|
|
struct menu_s* prevMenu; // previous menu
|
|
menuitem_t* menuitems; // menu items
|
|
void (*routine)(void); // draw routine ROCKBOX
|
|
short x;
|
|
short y; // x,y of menu
|
|
short lastOn; // last item user was on in menu
|
|
}
|
|
menu_t;
|
|
|
|
short itemOn; // menu item skull is on
|
|
short skullAnimCounter; // skull animation counter
|
|
short whichSkull; // which skull to draw
|
|
int systemvol;
|
|
|
|
// graphic name of skulls
|
|
// warning: initializer-string for array of chars is too long
|
|
char skullName[2][/*8*/9] = {"M_SKULL1","M_SKULL2"};
|
|
|
|
// current menudef
|
|
menu_t* currentMenu;
|
|
|
|
//
|
|
// PROTOTYPES
|
|
//
|
|
void M_NewGame(int choice);
|
|
void M_Episode(int choice);
|
|
void M_ChooseSkill(int choice);
|
|
void M_LoadGame(int choice);
|
|
void M_SaveGame(int choice);
|
|
void M_Options(int choice);
|
|
void M_EndGame(int choice);
|
|
void M_ReadThis(int choice);
|
|
void M_ReadThis2(int choice);
|
|
void M_QuitDOOM(int choice);
|
|
|
|
void M_ChangeMessages(int choice);
|
|
void M_ChangeGamma(int choice);
|
|
void M_SfxVol(int choice);
|
|
void M_MusicVol(int choice);
|
|
void M_SystemVol(int choice);
|
|
void M_SizeDisplay(int choice);
|
|
void M_StartGame(int choice);
|
|
void M_Sound(int choice);
|
|
|
|
void M_FinishReadThis(int choice);
|
|
void M_LoadSelect(int choice);
|
|
void M_SaveSelect(int choice);
|
|
void M_ReadSaveStrings(void);
|
|
void M_QuickSave(void);
|
|
void M_QuickLoad(void);
|
|
|
|
void M_DrawMainMenu(void);
|
|
void M_DrawReadThis1(void);
|
|
void M_DrawReadThis2(void);
|
|
void M_DrawNewGame(void);
|
|
void M_DrawEpisode(void);
|
|
void M_DrawOptions(void);
|
|
void M_DrawSound(void);
|
|
void M_DrawLoad(void);
|
|
void M_DrawSave(void);
|
|
|
|
void M_DrawSaveLoadBorder(int x,int y);
|
|
void M_SetupNextMenu(menu_t *menudef);
|
|
void M_DrawThermo(int x,int y,int thermWidth,int thermDot);
|
|
void M_DrawEmptyCell(menu_t *menu,int item);
|
|
void M_DrawSelCell(menu_t *menu,int item);
|
|
void M_WriteText(int x, int y, char *string);
|
|
int M_StringWidth(const char* string);
|
|
int M_StringHeight(const char* string);
|
|
void M_StartControlPanel(void);
|
|
void M_StartMessage(const char *string,void *routine,boolean input);
|
|
void M_StopMessage(void);
|
|
void M_ClearMenus (void);
|
|
|
|
|
|
|
|
|
|
//
|
|
// DOOM MENU
|
|
//
|
|
enum
|
|
{
|
|
newgame = 0,
|
|
options,
|
|
loadgame,
|
|
savegame,
|
|
readthis,
|
|
quitdoom,
|
|
main_end
|
|
};
|
|
unsigned main_e;
|
|
|
|
menuitem_t MainMenu[]=
|
|
{
|
|
{1,"M_NGAME",M_NewGame,'n'},
|
|
{1,"M_OPTION",M_Options,'o'},
|
|
{1,"M_LOADG",M_LoadGame,'l'},
|
|
{1,"M_SAVEG",M_SaveGame,'s'},
|
|
// Another hickup with Special edition.
|
|
{1,"M_RDTHIS",M_ReadThis,'r'},
|
|
{1,"M_QUITG",M_QuitDOOM,'q'}
|
|
};
|
|
|
|
menu_t MainDef =
|
|
{
|
|
main_end,
|
|
NULL,
|
|
MainMenu,
|
|
M_DrawMainMenu,
|
|
97,64,
|
|
0
|
|
};
|
|
|
|
|
|
//
|
|
// EPISODE SELECT
|
|
//
|
|
enum
|
|
{
|
|
ep1,
|
|
ep2,
|
|
ep3,
|
|
ep4,
|
|
ep_end
|
|
};
|
|
unsigned episodes_e;
|
|
|
|
menuitem_t EpisodeMenu[]=
|
|
{
|
|
{1,"M_EPI1", M_Episode,'k'},
|
|
{1,"M_EPI2", M_Episode,'t'},
|
|
{1,"M_EPI3", M_Episode,'i'},
|
|
{1,"M_EPI4", M_Episode,'t'}
|
|
};
|
|
|
|
menu_t EpiDef =
|
|
{
|
|
ep_end, // # of menu items
|
|
&MainDef, // previous menu
|
|
EpisodeMenu, // menuitem_t ->
|
|
M_DrawEpisode, // drawing routine ->
|
|
48,63, // x,y
|
|
ep1 // lastOn
|
|
};
|
|
|
|
//
|
|
// NEW GAME
|
|
//
|
|
enum
|
|
{
|
|
killthings,
|
|
toorough,
|
|
hurtme,
|
|
violence,
|
|
nightmare,
|
|
newg_end
|
|
};
|
|
unsigned newgame_e;
|
|
|
|
menuitem_t NewGameMenu[]=
|
|
{
|
|
{1,"M_JKILL", M_ChooseSkill, 'i'},
|
|
{1,"M_ROUGH", M_ChooseSkill, 'h'},
|
|
{1,"M_HURT", M_ChooseSkill, 'h'},
|
|
{1,"M_ULTRA", M_ChooseSkill, 'u'},
|
|
{1,"M_NMARE", M_ChooseSkill, 'n'}
|
|
};
|
|
|
|
menu_t NewDef =
|
|
{
|
|
newg_end, // # of menu items
|
|
&EpiDef, // previous menu
|
|
NewGameMenu, // menuitem_t ->
|
|
M_DrawNewGame, // drawing routine ->
|
|
48,63, // x,y
|
|
hurtme // lastOn
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// OPTIONS MENU
|
|
//
|
|
enum
|
|
{
|
|
endgame,
|
|
messages,
|
|
scrnsize,
|
|
option_empty1,
|
|
gamasens,
|
|
option_empty2,
|
|
soundvol,
|
|
opt_end
|
|
};
|
|
unsigned options_e;
|
|
|
|
menuitem_t OptionsMenu[]=
|
|
{
|
|
{1,"M_ENDGAM", M_EndGame,'e'},
|
|
{1,"M_MESSG", M_ChangeMessages,'m'},
|
|
{2,"M_SCRNSZ", M_SizeDisplay,'s'},
|
|
{-1,"",0,0},
|
|
{2,"M_GAMMA", M_ChangeGamma,'m'},
|
|
{-1,"",0,0},
|
|
{1,"M_SVOL", M_Sound,'s'}
|
|
};
|
|
|
|
menu_t OptionsDef =
|
|
{
|
|
opt_end,
|
|
&MainDef,
|
|
OptionsMenu,
|
|
M_DrawOptions,
|
|
60,37,
|
|
0
|
|
};
|
|
|
|
//
|
|
// Read This! MENU 1 & 2
|
|
//
|
|
enum
|
|
{
|
|
rdthsempty1,
|
|
read1_end
|
|
};
|
|
unsigned read_e;
|
|
|
|
menuitem_t ReadMenu1[] =
|
|
{
|
|
{1,"",M_ReadThis2,0}
|
|
};
|
|
|
|
menu_t ReadDef1 =
|
|
{
|
|
read1_end,
|
|
&MainDef,
|
|
ReadMenu1,
|
|
M_DrawReadThis1,
|
|
280,185,
|
|
0
|
|
};
|
|
|
|
enum
|
|
{
|
|
rdthsempty2,
|
|
read2_end
|
|
};
|
|
unsigned read_e2;
|
|
|
|
menuitem_t ReadMenu2[]=
|
|
{
|
|
{1,"",M_FinishReadThis,0}
|
|
};
|
|
|
|
menu_t ReadDef2 =
|
|
{
|
|
read2_end,
|
|
&ReadDef1,
|
|
ReadMenu2,
|
|
M_DrawReadThis2,
|
|
330,175,
|
|
0
|
|
};
|
|
|
|
//
|
|
// SOUND VOLUME MENU
|
|
//
|
|
enum
|
|
{
|
|
sfx_vol,
|
|
sfx_empty1,
|
|
music_vol,
|
|
sfx_empty2,
|
|
system_vol,
|
|
sfx_empty3,
|
|
sound_end
|
|
};
|
|
unsigned sound_e;
|
|
|
|
menuitem_t SoundMenu[]=
|
|
{
|
|
{2,"M_SFXVOL",M_SfxVol,'s'},
|
|
{-1,"",0,0}, //ROCKBOX
|
|
{2,"M_MUSVOL",M_MusicVol,'m'},
|
|
{-1,"",0,0}, //ROCKBOX
|
|
{2,"M_SYSVOL",M_SystemVol,'z'},
|
|
{-1,"",0,0} //ROCKBOX
|
|
};
|
|
|
|
menu_t SoundDef =
|
|
{
|
|
sound_end,
|
|
&OptionsDef,
|
|
SoundMenu,
|
|
M_DrawSound,
|
|
80,64,
|
|
0
|
|
};
|
|
|
|
//
|
|
// LOAD GAME MENU
|
|
//
|
|
enum
|
|
{
|
|
load1,
|
|
load2,
|
|
load3,
|
|
load4,
|
|
load5,
|
|
load6,
|
|
load_end
|
|
};
|
|
unsigned load_e;
|
|
|
|
menuitem_t LoadMenu[]=
|
|
{
|
|
{1,"", M_LoadSelect,'1'},
|
|
{1,"", M_LoadSelect,'2'},
|
|
{1,"", M_LoadSelect,'3'},
|
|
{1,"", M_LoadSelect,'4'},
|
|
{1,"", M_LoadSelect,'5'},
|
|
{1,"", M_LoadSelect,'6'}
|
|
};
|
|
|
|
menu_t LoadDef =
|
|
{
|
|
load_end,
|
|
&MainDef,
|
|
LoadMenu,
|
|
M_DrawLoad,
|
|
80,54,
|
|
0
|
|
};
|
|
|
|
//
|
|
// SAVE GAME MENU
|
|
//
|
|
menuitem_t SaveMenu[]=
|
|
{
|
|
{1,"", M_SaveSelect,'1'},
|
|
{1,"", M_SaveSelect,'2'},
|
|
{1,"", M_SaveSelect,'3'},
|
|
{1,"", M_SaveSelect,'4'},
|
|
{1,"", M_SaveSelect,'5'},
|
|
{1,"", M_SaveSelect,'6'}
|
|
};
|
|
|
|
menu_t SaveDef =
|
|
{
|
|
load_end,
|
|
&MainDef,
|
|
SaveMenu,
|
|
M_DrawSave,
|
|
80,54,
|
|
0
|
|
};
|
|
|
|
|
|
//
|
|
// M_ReadSaveStrings
|
|
// read the strings from the savegame files
|
|
//
|
|
void M_ReadSaveStrings(void)
|
|
{
|
|
int handle;
|
|
int i;
|
|
char name[256];
|
|
|
|
for (i = 0;i < load_end;i++)
|
|
{
|
|
if (M_CheckParm("-cdrom"))
|
|
snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i);
|
|
else
|
|
snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",i);
|
|
|
|
handle = open (name, O_RDONLY | 0);
|
|
if (handle == -1)
|
|
{
|
|
strcpy(&savegamestrings[i][0],EMPTYSTRING);
|
|
LoadMenu[i].status = 0;
|
|
continue;
|
|
}
|
|
read (handle, &savegamestrings[i], SAVESTRINGSIZE);
|
|
close (handle);
|
|
LoadMenu[i].status = 1;
|
|
}
|
|
}
|
|
|
|
#define LOADGRAPHIC_Y 8
|
|
//
|
|
// M_LoadGame & Cie.
|
|
//
|
|
void M_DrawLoad(void)
|
|
{
|
|
int i;
|
|
|
|
V_DrawNamePatch(72 ,LOADGRAPHIC_Y, 0, "M_LOADG", CR_DEFAULT, VPT_STRETCH);
|
|
for (i = 0;i < load_end; i++)
|
|
{
|
|
M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i);
|
|
M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Draw border for the savegame description
|
|
//
|
|
void M_DrawSaveLoadBorder(int x,int y)
|
|
{
|
|
int i;
|
|
|
|
V_DrawNamePatch(x-8, y+7, 0, "M_LSLEFT", CR_DEFAULT, VPT_STRETCH);
|
|
for (i = 0;i < 24;i++)
|
|
{
|
|
V_DrawNamePatch(x, y+7, 0, "M_LSCNTR", CR_DEFAULT, VPT_STRETCH);
|
|
x += 8;
|
|
}
|
|
V_DrawNamePatch(x, y+7, 0, "M_LSRGHT", CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// User wants to load this game
|
|
//
|
|
void M_LoadSelect(int choice)
|
|
{
|
|
char name[256];
|
|
|
|
if (M_CheckParm("-cdrom"))
|
|
snprintf(name,sizeof(name),"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice);
|
|
else
|
|
snprintf(name,sizeof(name),SAVEGAMENAME"%d.dsg",choice);
|
|
G_LoadGame (choice, false);
|
|
M_ClearMenus ();
|
|
}
|
|
|
|
//
|
|
// Selected from DOOM menu
|
|
//
|
|
void M_LoadGame (int choice)
|
|
{
|
|
(void)choice;
|
|
if (netgame)
|
|
{
|
|
M_StartMessage(LOADNET,NULL,false);
|
|
return;
|
|
}
|
|
|
|
M_SetupNextMenu(&LoadDef);
|
|
M_ReadSaveStrings();
|
|
}
|
|
|
|
|
|
//
|
|
// M_SaveGame & Cie.
|
|
//
|
|
void M_DrawSave(void)
|
|
{
|
|
int i;
|
|
|
|
V_DrawNamePatch(72, LOADGRAPHIC_Y, 0, "M_SAVEG", CR_DEFAULT, VPT_STRETCH);
|
|
for (i = 0;i < load_end; i++)
|
|
{
|
|
M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i);
|
|
M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]);
|
|
}
|
|
|
|
if (saveStringEnter)
|
|
{
|
|
i = M_StringWidth(savegamestrings[saveSlot]);
|
|
M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_");
|
|
}
|
|
}
|
|
|
|
//
|
|
// M_Responder calls this when user is finished
|
|
//
|
|
void M_DoSave(int slot)
|
|
{
|
|
G_SaveGame (slot,savegamestrings[slot]);
|
|
M_ClearMenus ();
|
|
|
|
// PICK QUICKSAVE SLOT YET?
|
|
if (quickSaveSlot == -2)
|
|
quickSaveSlot = slot;
|
|
}
|
|
|
|
//
|
|
// User wants to save. Start string input for M_Responder
|
|
//
|
|
void M_SaveSelect(int choice)
|
|
{
|
|
// we are going to be intercepting all chars
|
|
saveStringEnter = 1;
|
|
|
|
saveSlot = choice;
|
|
snprintf(savegamestrings[choice], sizeof(savegamestrings[choice]),
|
|
(gamemode==shareware||gamemode==registered||gamemode==retail) ?
|
|
*mapnames[(gameepisode-1)*9+gamemap-1] : (gamemission==doom2) ?
|
|
*mapnames2[gamemap-1] : (gamemission==pack_plut) ?
|
|
*mapnamesp[gamemap-1] : (gamemission==pack_tnt) ?
|
|
*mapnamest[gamemap-1] : "Unknown Location", choice);
|
|
if (!strcmp(savegamestrings[choice],s_EMPTYSTRING))
|
|
savegamestrings[choice][0] = 0;
|
|
saveCharIndex = strlen(savegamestrings[choice]);
|
|
}
|
|
|
|
//
|
|
// Selected from DOOM menu
|
|
//
|
|
void M_SaveGame (int choice)
|
|
{
|
|
(void)choice;
|
|
if (!usergame)
|
|
{
|
|
M_StartMessage(s_SAVEDEAD,NULL,false);
|
|
return;
|
|
}
|
|
|
|
if (gamestate != GS_LEVEL)
|
|
return;
|
|
|
|
M_SetupNextMenu(&SaveDef);
|
|
M_ReadSaveStrings();
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// M_QuickSave
|
|
//
|
|
char tempstring[80];
|
|
|
|
void M_QuickSaveResponse(int ch)
|
|
{
|
|
if (ch == 'y')
|
|
{
|
|
M_DoSave(quickSaveSlot);
|
|
|
|
S_StartSound(NULL,sfx_swtchx);
|
|
|
|
}
|
|
}
|
|
|
|
void M_QuickSave(void)
|
|
{
|
|
if (!usergame)
|
|
{
|
|
S_StartSound(NULL,sfx_oof);
|
|
return;
|
|
}
|
|
|
|
if (gamestate != GS_LEVEL)
|
|
return;
|
|
|
|
if (quickSaveSlot < 0)
|
|
{
|
|
M_StartControlPanel();
|
|
M_ReadSaveStrings();
|
|
M_SetupNextMenu(&SaveDef);
|
|
quickSaveSlot = -2; // means to pick a slot now
|
|
return;
|
|
}
|
|
snprintf(tempstring,sizeof(tempstring),s_QSPROMPT,savegamestrings[quickSaveSlot]);
|
|
M_StartMessage(tempstring,M_QuickSaveResponse,true);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// M_QuickLoad
|
|
//
|
|
void M_QuickLoadResponse(int ch)
|
|
{
|
|
if (ch == 'y')
|
|
{
|
|
M_LoadSelect(quickSaveSlot);
|
|
S_StartSound(NULL,sfx_swtchx);
|
|
}
|
|
}
|
|
|
|
|
|
void M_QuickLoad(void)
|
|
{
|
|
if (netgame)
|
|
{
|
|
M_StartMessage(QLOADNET,NULL,false);
|
|
return;
|
|
}
|
|
|
|
if (quickSaveSlot < 0)
|
|
{
|
|
M_StartMessage(QSAVESPOT,NULL,false);
|
|
return;
|
|
}
|
|
snprintf(tempstring, sizeof(tempstring), QLPROMPT,savegamestrings[quickSaveSlot]);
|
|
M_StartMessage(tempstring,M_QuickLoadResponse,true);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Read This Menus
|
|
// Had a "quick hack to fix romero bug"
|
|
//
|
|
void M_DrawReadThis1(void)
|
|
{
|
|
inhelpscreens = true;
|
|
switch ( gamemode )
|
|
{
|
|
case commercial:
|
|
V_DrawNamePatch(0, 0, 0, "HELP", CR_DEFAULT, VPT_STRETCH);
|
|
break;
|
|
case shareware:
|
|
case registered:
|
|
case retail:
|
|
V_DrawNamePatch(0, 0, 0, "HELP1", CR_DEFAULT, VPT_STRETCH);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Read This Menus - optional second page.
|
|
//
|
|
void M_DrawReadThis2(void)
|
|
{
|
|
inhelpscreens = true;
|
|
switch ( gamemode )
|
|
{
|
|
case retail:
|
|
case commercial:
|
|
// This hack keeps us from having to change menus.
|
|
V_DrawNamePatch(0, 0, 0, "CREDIT", CR_DEFAULT, VPT_STRETCH);
|
|
break;
|
|
case shareware:
|
|
case registered:
|
|
V_DrawNamePatch(0, 0, 0, "HELP2", CR_DEFAULT, VPT_STRETCH);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Change Sfx & Music volumes
|
|
//
|
|
void M_DrawSound(void)
|
|
{
|
|
int sysmax=(rb->sound_max(SOUND_VOLUME)-rb->sound_min(SOUND_VOLUME));
|
|
V_DrawNamePatch(60, 38, 0, "M_SVOL", CR_DEFAULT, VPT_STRETCH);
|
|
|
|
M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1),
|
|
16,snd_SfxVolume);
|
|
|
|
M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1),
|
|
16,snd_MusicVolume);
|
|
|
|
M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(system_vol+1),
|
|
16,(sysmax+systemvol)/5);
|
|
}
|
|
|
|
void M_Sound(int choice)
|
|
{
|
|
(void) choice;
|
|
M_SetupNextMenu(&SoundDef);
|
|
}
|
|
|
|
void M_SfxVol(int choice)
|
|
{
|
|
switch(choice)
|
|
{
|
|
case 0:
|
|
if (snd_SfxVolume)
|
|
snd_SfxVolume--;
|
|
break;
|
|
case 1:
|
|
if (snd_SfxVolume < 15)
|
|
snd_SfxVolume++;
|
|
break;
|
|
}
|
|
|
|
S_SetSfxVolume(snd_SfxVolume /* *8 */);
|
|
}
|
|
|
|
void M_MusicVol(int choice)
|
|
{
|
|
switch(choice)
|
|
{
|
|
case 0:
|
|
if (snd_MusicVolume)
|
|
snd_MusicVolume--;
|
|
break;
|
|
case 1:
|
|
if (snd_MusicVolume < 15)
|
|
snd_MusicVolume++;
|
|
break;
|
|
}
|
|
|
|
S_SetMusicVolume(snd_MusicVolume /* *8 */);
|
|
}
|
|
|
|
void M_SystemVol(int choice)
|
|
{
|
|
switch(choice)
|
|
{
|
|
case 0:
|
|
if (systemvol-5>rb->sound_min(SOUND_VOLUME))
|
|
{
|
|
systemvol-=5;
|
|
rb->sound_set(SOUND_VOLUME, systemvol);
|
|
rb->global_settings->volume = systemvol;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (systemvol+5<rb->sound_max(SOUND_VOLUME))
|
|
{
|
|
systemvol+=5;
|
|
rb->sound_set(SOUND_VOLUME, systemvol);
|
|
rb->global_settings->volume = systemvol;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// M_DrawMainMenu
|
|
//
|
|
void M_DrawMainMenu(void)
|
|
{
|
|
V_DrawNamePatch(94, 2, 0, "M_DOOM", CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// M_NewGame
|
|
//
|
|
void M_DrawNewGame(void)
|
|
{
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(96, 14, 0, "M_NEWG", CR_DEFAULT, VPT_STRETCH);
|
|
V_DrawNamePatch(54, 38, 0, "M_SKILL",CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
void M_NewGame(int choice)
|
|
{
|
|
(void) choice;
|
|
if (netgame && !demoplayback)
|
|
{
|
|
M_StartMessage(s_NEWGAME,NULL,false);
|
|
return;
|
|
}
|
|
|
|
if ( gamemode == commercial )
|
|
M_SetupNextMenu(&NewDef);
|
|
else
|
|
M_SetupNextMenu(&EpiDef);
|
|
}
|
|
|
|
|
|
//
|
|
// M_Episode
|
|
//
|
|
int epi;
|
|
|
|
void M_DrawEpisode(void)
|
|
{
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(54, 38, 0, "M_EPISOD", CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
void M_VerifyNightmare(int ch)
|
|
{
|
|
if (ch != key_menu_enter)
|
|
return;
|
|
|
|
G_DeferedInitNew(nightmare,epi+1,1);
|
|
M_ClearMenus ();
|
|
}
|
|
|
|
void M_ChooseSkill(int choice)
|
|
{
|
|
if (choice == nightmare)
|
|
{
|
|
M_StartMessage(s_NIGHTMARE,M_VerifyNightmare,true);
|
|
return;
|
|
}
|
|
|
|
//jff 3/24/98 remember last skill selected
|
|
// killough 10/98 moved to here
|
|
defaultskill = choice+1;
|
|
|
|
G_DeferedInitNew(choice,epi+1,1);
|
|
M_ClearMenus ();
|
|
}
|
|
|
|
void M_Episode(int choice)
|
|
{
|
|
if ( (gamemode == shareware)
|
|
&& choice)
|
|
{
|
|
M_StartMessage(s_SWSTRING,NULL,false); // Ty 03/27/98 - externalized
|
|
M_SetupNextMenu(&ReadDef1);
|
|
return;
|
|
}
|
|
|
|
// Yet another hack...
|
|
if ( (gamemode == registered)
|
|
&& (choice > 2))
|
|
{
|
|
/* Digita */
|
|
// fprintf( stderr,
|
|
// "M_Episode: 4th episode requires UltimateDOOM\n");
|
|
choice = 0;
|
|
}
|
|
|
|
epi = choice;
|
|
M_SetupNextMenu(&NewDef);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// M_Options
|
|
//
|
|
char detailNames[2][9] = {"M_GDHIGH","M_GDLOW"};
|
|
char msgNames[2][9] = {"M_MSGOFF","M_MSGON"};
|
|
|
|
|
|
void M_DrawOptions(void)
|
|
{
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(108, 15, 0, "M_OPTTTL", CR_DEFAULT, VPT_STRETCH);
|
|
|
|
V_DrawNamePatch(OptionsDef.x + 120, OptionsDef.y+LINEHEIGHT*messages, 0,
|
|
msgNames[showMessages], CR_DEFAULT, VPT_STRETCH);
|
|
|
|
M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(gamasens+1),
|
|
4,usegamma);
|
|
|
|
M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1),
|
|
9,screenSize);
|
|
}
|
|
|
|
void M_Options(int choice)
|
|
{
|
|
(void)choice;
|
|
M_SetupNextMenu(&OptionsDef);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Toggle messages on/off
|
|
//
|
|
void M_ChangeMessages(int choice)
|
|
{
|
|
(void)choice;
|
|
showMessages = 1 - showMessages;
|
|
|
|
if (!showMessages)
|
|
players[consoleplayer].message = s_MSGOFF;
|
|
else
|
|
players[consoleplayer].message = s_MSGON ;
|
|
|
|
message_dontfuckwithme = true;
|
|
}
|
|
|
|
|
|
//
|
|
// M_EndGame
|
|
//
|
|
void M_EndGameResponse(int ch)
|
|
{
|
|
if (ch != key_menu_enter)
|
|
return;
|
|
|
|
// killough 5/26/98: make endgame quit if recording or playing back demo
|
|
if (demorecording || singledemo)
|
|
G_CheckDemoStatus();
|
|
|
|
currentMenu->lastOn = itemOn;
|
|
M_ClearMenus ();
|
|
D_StartTitle ();
|
|
}
|
|
|
|
void M_EndGame(int choice)
|
|
{
|
|
(void)choice;
|
|
if (!usergame)
|
|
{
|
|
S_StartSound(NULL,sfx_oof);
|
|
return;
|
|
}
|
|
|
|
if (netgame)
|
|
{
|
|
M_StartMessage(s_NETEND,NULL,false);
|
|
return;
|
|
}
|
|
|
|
M_StartMessage(s_ENDGAME,M_EndGameResponse,true);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// M_ReadThis
|
|
//
|
|
void M_ReadThis(int choice)
|
|
{
|
|
(void)choice;
|
|
M_SetupNextMenu(&ReadDef1);
|
|
}
|
|
|
|
void M_ReadThis2(int choice)
|
|
{
|
|
(void)choice;
|
|
M_SetupNextMenu(&ReadDef2);
|
|
}
|
|
|
|
void M_FinishReadThis(int choice)
|
|
{
|
|
(void)choice;
|
|
M_SetupNextMenu(&MainDef);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// M_QuitDOOM
|
|
//
|
|
int quitsounds[8] =
|
|
{
|
|
sfx_pldeth,
|
|
sfx_dmpain,
|
|
sfx_popain,
|
|
sfx_slop,
|
|
sfx_telept,
|
|
sfx_posit1,
|
|
sfx_posit3,
|
|
sfx_sgtatk
|
|
};
|
|
|
|
int quitsounds2[8] =
|
|
{
|
|
sfx_vilact,
|
|
sfx_getpow,
|
|
sfx_boscub,
|
|
sfx_slop,
|
|
sfx_skeswg,
|
|
sfx_kntdth,
|
|
sfx_bspact,
|
|
sfx_sgtatk
|
|
};
|
|
|
|
|
|
|
|
void M_QuitResponse(int ch)
|
|
{
|
|
if (ch != key_menu_enter)
|
|
return;
|
|
if (!netgame)
|
|
{
|
|
if (gamemode == commercial)
|
|
S_StartSound(NULL,quitsounds2[(gametic>>2)&7]);
|
|
else
|
|
S_StartSound(NULL,quitsounds[(gametic>>2)&7]);
|
|
I_WaitVBL(105);
|
|
}
|
|
I_Quit ();
|
|
}
|
|
|
|
|
|
|
|
|
|
void M_QuitDOOM(int choice)
|
|
{
|
|
(void)choice;
|
|
// We pick index 0 which is language sensitive,
|
|
// or one at random, between 1 and maximum number.
|
|
if (language != english )
|
|
snprintf(endstring,sizeof(endstring),"%s\n\n%s",s_DOSY, endmsg[0] );
|
|
else
|
|
snprintf(endstring,sizeof(endstring),"%s\n\n%s", endmsg[gametic%(NUM_QUITMESSAGES-1)+1], s_DOSY);
|
|
|
|
M_StartMessage(endstring,M_QuitResponse,true);
|
|
}
|
|
|
|
|
|
|
|
|
|
void M_ChangeGamma(int choice)
|
|
{
|
|
switch(choice)
|
|
{
|
|
case 0:
|
|
if (usegamma)
|
|
usegamma--;
|
|
break;
|
|
case 1:
|
|
if (usegamma < 4)
|
|
usegamma++;
|
|
break;
|
|
}
|
|
V_SetPalette (0);
|
|
}
|
|
|
|
void M_SizeDisplay(int choice)
|
|
{
|
|
switch(choice)
|
|
{
|
|
case 0:
|
|
if (screenSize > 0)
|
|
{
|
|
screenblocks--;
|
|
screenSize--;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (screenSize < 8)
|
|
{
|
|
screenblocks++;
|
|
screenSize++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
R_SetViewSize (screenblocks);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Menu Functions
|
|
//
|
|
void
|
|
M_DrawThermo
|
|
( int x,
|
|
int y,
|
|
int thermWidth,
|
|
int thermDot )
|
|
{
|
|
int xx;
|
|
int i;
|
|
|
|
xx = x;
|
|
V_DrawNamePatch(xx, y, 0, "M_THERML", CR_DEFAULT, VPT_STRETCH);
|
|
xx += 8;
|
|
for (i=0;i<thermWidth;i++)
|
|
{
|
|
V_DrawNamePatch(xx, y, 0, "M_THERMM", CR_DEFAULT, VPT_STRETCH);
|
|
xx += 8;
|
|
}
|
|
V_DrawNamePatch(xx, y, 0, "M_THERMR", CR_DEFAULT, VPT_STRETCH);
|
|
V_DrawNamePatch((x+8)+thermDot*8,y,0,"M_THERMO",CR_DEFAULT,VPT_STRETCH);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
M_DrawEmptyCell
|
|
( menu_t* menu,
|
|
int item )
|
|
{
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0,
|
|
"M_CELL1", CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
void
|
|
M_DrawSelCell
|
|
( menu_t* menu,
|
|
int item )
|
|
{
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0,
|
|
"M_CELL2", CR_DEFAULT, VPT_STRETCH);
|
|
}
|
|
|
|
|
|
void
|
|
M_StartMessage
|
|
( const char* string,
|
|
void* routine,
|
|
boolean input )
|
|
{
|
|
messageLastMenuActive = menuactive;
|
|
messageToPrint = 1;
|
|
messageString = string;
|
|
messageRoutine = routine;
|
|
messageNeedsInput = input;
|
|
menuactive = true;
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void M_StopMessage(void)
|
|
{
|
|
menuactive = messageLastMenuActive;
|
|
messageToPrint = 0;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Find string width from hu_font chars
|
|
//
|
|
int M_StringWidth(const char* string)
|
|
{
|
|
int i, c, w = 0;
|
|
for (i = 0;(size_t)i < strlen(string);i++)
|
|
w += (c = toupper(string[i]) - HU_FONTSTART) < 0 || c >= HU_FONTSIZE ?
|
|
4 : SHORT(hu_font[c].width);
|
|
return w;
|
|
}
|
|
|
|
//
|
|
// Find string height from hu_font chars
|
|
//
|
|
|
|
int M_StringHeight(const char* string)
|
|
{
|
|
int i, h, height = h = SHORT(hu_font[0].height);
|
|
for (i = 0;string[i];i++) // killough 1/31/98
|
|
if (string[i] == '\n')
|
|
h += height;
|
|
return h;
|
|
}
|
|
|
|
|
|
//
|
|
// Write a string using the hu_font
|
|
//
|
|
void
|
|
M_WriteText
|
|
( int x,
|
|
int y,
|
|
char* string)
|
|
{
|
|
int w;
|
|
char* ch;
|
|
int c;
|
|
int cx;
|
|
int cy;
|
|
|
|
|
|
ch = string;
|
|
cx = x;
|
|
cy = y;
|
|
|
|
while(1)
|
|
{
|
|
c = *ch++;
|
|
if (!c)
|
|
break;
|
|
if (c == '\n')
|
|
{
|
|
cx = x;
|
|
cy += 12;
|
|
continue;
|
|
}
|
|
|
|
c = toupper(c) - HU_FONTSTART;
|
|
if (c < 0 || c>= HU_FONTSIZE)
|
|
{
|
|
cx += 4;
|
|
continue;
|
|
}
|
|
|
|
w = SHORT (hu_font[c].width);
|
|
if (cx+w > 320)
|
|
break;
|
|
// proff/nicolas 09/20/98 -- changed for hi-res
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH);
|
|
cx+=w;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// CONTROL PANEL
|
|
//
|
|
|
|
//
|
|
// M_Responder
|
|
//
|
|
boolean M_Responder (event_t* ev)
|
|
{
|
|
int ch;
|
|
int i;
|
|
// static int joywait = 0;
|
|
// static int mousewait = 0;
|
|
// static int mousey = 0;
|
|
// static int lasty = 0;
|
|
// static int mousex = 0;
|
|
// static int lastx = 0;
|
|
|
|
ch = -1;
|
|
|
|
// Process joystick input
|
|
|
|
/* if (ev->type == ev_joystick && joywait < I_GetTime())
|
|
{
|
|
if (ev->data3 == -1)
|
|
{
|
|
ch = KEY_UPARROW;
|
|
joywait = I_GetTime() + 5;
|
|
}
|
|
else if (ev->data3 == 1)
|
|
{
|
|
ch = KEY_DOWNARROW;
|
|
joywait = I_GetTime() + 5;
|
|
}
|
|
|
|
if (ev->data2 == -1)
|
|
{
|
|
ch = KEY_LEFTARROW;
|
|
joywait = I_GetTime() + 2;
|
|
}
|
|
else if (ev->data2 == 1)
|
|
{
|
|
ch = KEY_RIGHTARROW;
|
|
joywait = I_GetTime() + 2;
|
|
}
|
|
|
|
if (ev->data1&1)
|
|
{
|
|
ch = key_menu_enter;
|
|
joywait = I_GetTime() + 5;
|
|
}
|
|
if (ev->data1&2)
|
|
{
|
|
ch = KEY_BACKSPACE;
|
|
joywait = I_GetTime() + 5;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Process mouse input
|
|
if (ev->type == ev_mouse && mousewait < I_GetTime())
|
|
{
|
|
mousey += ev->data3;
|
|
if (mousey < lasty-30)
|
|
{
|
|
ch = KEY_DOWNARROW;
|
|
mousewait = I_GetTime() + 5;
|
|
mousey = lasty -= 30;
|
|
}
|
|
else if (mousey > lasty+30)
|
|
{
|
|
ch = KEY_UPARROW;
|
|
mousewait = I_GetTime() + 5;
|
|
mousey = lasty += 30;
|
|
}
|
|
|
|
mousex += ev->data2;
|
|
if (mousex < lastx-30)
|
|
{
|
|
ch = KEY_LEFTARROW;
|
|
mousewait = I_GetTime() + 5;
|
|
mousex = lastx -= 30;
|
|
}
|
|
else if (mousex > lastx+30)
|
|
{
|
|
ch = KEY_RIGHTARROW;
|
|
mousewait = I_GetTime() + 5;
|
|
mousex = lastx += 30;
|
|
}
|
|
|
|
if (ev->data1&1)
|
|
{
|
|
ch = key_menu_enter;
|
|
mousewait = I_GetTime() + 15;
|
|
}
|
|
|
|
if (ev->data1&2)
|
|
{
|
|
ch = KEY_BACKSPACE;
|
|
mousewait = I_GetTime() + 15;
|
|
}
|
|
}
|
|
else */if (ev->type == ev_keydown)
|
|
{
|
|
ch = ev->data1;
|
|
}
|
|
// }
|
|
|
|
if (ch == -1)
|
|
return false;
|
|
|
|
|
|
// Save Game string input
|
|
if (saveStringEnter)
|
|
{
|
|
switch(ch)
|
|
{
|
|
case KEY_BACKSPACE:
|
|
if (saveCharIndex > 0)
|
|
{
|
|
saveCharIndex--;
|
|
savegamestrings[saveSlot][saveCharIndex] = 0;
|
|
}
|
|
break;
|
|
|
|
case KEY_ESCAPE:
|
|
saveStringEnter = 0;
|
|
strcpy(&savegamestrings[saveSlot][0],saveOldString);
|
|
break;
|
|
|
|
case KEY_ENTER:
|
|
saveStringEnter = 0;
|
|
if (savegamestrings[saveSlot][0])
|
|
M_DoSave(saveSlot);
|
|
break;
|
|
|
|
default:
|
|
ch = toupper(ch);
|
|
if (ch != 32)
|
|
if (ch-HU_FONTSTART < 0 || ch-HU_FONTSTART >= HU_FONTSIZE)
|
|
break;
|
|
if (ch >= 32 && ch <= 127 &&
|
|
saveCharIndex < SAVESTRINGSIZE-1 &&
|
|
M_StringWidth(savegamestrings[saveSlot]) <
|
|
(SAVESTRINGSIZE-2)*8)
|
|
{
|
|
savegamestrings[saveSlot][saveCharIndex++] = ch;
|
|
savegamestrings[saveSlot][saveCharIndex] = 0;
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Take care of any messages that need input
|
|
if (messageToPrint)
|
|
{
|
|
if (messageNeedsInput == true &&
|
|
!(ch == ' ' || ch == 'n' || ch == key_menu_enter || ch == key_menu_escape))
|
|
return false;
|
|
|
|
menuactive = messageLastMenuActive;
|
|
messageToPrint = 0;
|
|
if (messageRoutine)
|
|
messageRoutine(ch);
|
|
|
|
menuactive = false;
|
|
S_StartSound(NULL,sfx_swtchx);
|
|
return true;
|
|
}
|
|
/*
|
|
if (ch == KEY_F1) // devparm &&
|
|
{
|
|
G_ScreenShot ();
|
|
return true;
|
|
}
|
|
*/
|
|
// F-Keys
|
|
if (!menuactive)
|
|
{
|
|
if (ch == key_autorun) // Autorun // V
|
|
{
|
|
autorun = !autorun;
|
|
return true;
|
|
}
|
|
|
|
switch(ch)
|
|
{
|
|
/*
|
|
case KEY_F1: // Help key
|
|
M_StartControlPanel ();
|
|
|
|
if ( gamemode == retail )
|
|
currentMenu = &ReadDef2;
|
|
else
|
|
currentMenu = &ReadDef1;
|
|
|
|
itemOn = 0;
|
|
S_StartSound(NULL,sfx_swtchn);
|
|
return true;
|
|
|
|
case KEY_F6: // Quicksave
|
|
S_StartSound(NULL,sfx_swtchn);
|
|
M_QuickSave();
|
|
return true;
|
|
|
|
case KEY_F9: // Quickload
|
|
S_StartSound(NULL,sfx_swtchn);
|
|
M_QuickLoad();
|
|
return true;
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
// Pop-up menu?
|
|
if (!menuactive)
|
|
{
|
|
if (ch == key_menu_escape)
|
|
{
|
|
M_StartControlPanel ();
|
|
S_StartSound(NULL,sfx_swtchn);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// Keys usable within menu
|
|
switch (ch)
|
|
{
|
|
case KEY_DOWNARROW:
|
|
do
|
|
{
|
|
if (itemOn+1 > currentMenu->numitems-1)
|
|
itemOn = 0;
|
|
else
|
|
itemOn++;
|
|
S_StartSound(NULL,sfx_pstop);
|
|
}
|
|
while(currentMenu->menuitems[itemOn].status==-1);
|
|
return true;
|
|
|
|
case KEY_UPARROW:
|
|
do
|
|
{
|
|
if (!itemOn)
|
|
itemOn = currentMenu->numitems-1;
|
|
else
|
|
itemOn--;
|
|
S_StartSound(NULL,sfx_pstop);
|
|
}
|
|
while(currentMenu->menuitems[itemOn].status==-1);
|
|
return true;
|
|
|
|
case KEY_LEFTARROW:
|
|
if (currentMenu->menuitems[itemOn].routine &&
|
|
currentMenu->menuitems[itemOn].status == 2)
|
|
{
|
|
S_StartSound(NULL,sfx_stnmov);
|
|
currentMenu->menuitems[itemOn].routine(0);
|
|
}
|
|
return true;
|
|
|
|
case KEY_RIGHTARROW:
|
|
if (currentMenu->menuitems[itemOn].routine &&
|
|
currentMenu->menuitems[itemOn].status == 2)
|
|
{
|
|
S_StartSound(NULL,sfx_stnmov);
|
|
currentMenu->menuitems[itemOn].routine(1);
|
|
}
|
|
return true;
|
|
|
|
case KEY_ENTER:
|
|
if (currentMenu->menuitems[itemOn].routine &&
|
|
currentMenu->menuitems[itemOn].status)
|
|
{
|
|
currentMenu->lastOn = itemOn;
|
|
if (currentMenu->menuitems[itemOn].status == 2)
|
|
{
|
|
currentMenu->menuitems[itemOn].routine(1); // right arrow
|
|
S_StartSound(NULL,sfx_stnmov);
|
|
}
|
|
else
|
|
{
|
|
currentMenu->menuitems[itemOn].routine(itemOn);
|
|
S_StartSound(NULL,sfx_pistol);
|
|
}
|
|
}
|
|
return true;
|
|
|
|
case KEY_ESCAPE:
|
|
currentMenu->lastOn = itemOn;
|
|
M_ClearMenus ();
|
|
S_StartSound(NULL,sfx_swtchx);
|
|
return true;
|
|
|
|
case KEY_BACKSPACE:
|
|
currentMenu->lastOn = itemOn;
|
|
if (currentMenu->prevMenu)
|
|
{
|
|
currentMenu = currentMenu->prevMenu;
|
|
itemOn = currentMenu->lastOn;
|
|
S_StartSound(NULL,sfx_swtchn);
|
|
}
|
|
return true;
|
|
|
|
default:
|
|
for (i = itemOn+1;i < currentMenu->numitems;i++)
|
|
if (currentMenu->menuitems[i].alphaKey == ch)
|
|
{
|
|
itemOn = i;
|
|
S_StartSound(NULL,sfx_pstop);
|
|
return true;
|
|
}
|
|
for (i = 0;i <= itemOn;i++)
|
|
if (currentMenu->menuitems[i].alphaKey == ch)
|
|
{
|
|
itemOn = i;
|
|
S_StartSound(NULL,sfx_pstop);
|
|
return true;
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// M_StartControlPanel
|
|
//
|
|
void M_StartControlPanel (void)
|
|
{
|
|
// intro might call this repeatedly
|
|
if (menuactive)
|
|
return;
|
|
|
|
menuactive = 1;
|
|
currentMenu = &MainDef; // JDC
|
|
itemOn = currentMenu->lastOn; // JDC
|
|
}
|
|
|
|
|
|
//
|
|
// M_Drawer
|
|
// Called after the view has been rendered,
|
|
// but before it has been blitted.
|
|
//
|
|
void M_Drawer (void)
|
|
{
|
|
static short x;
|
|
static short y;
|
|
unsigned short i;
|
|
short max;
|
|
char string[40];
|
|
int start;
|
|
|
|
inhelpscreens = false;
|
|
|
|
|
|
// Horiz. & Vertically center string and print it.
|
|
if (messageToPrint)
|
|
{
|
|
start = 0;
|
|
y = 100 - M_StringHeight(messageString)/2;
|
|
while(*(messageString+start))
|
|
{
|
|
for (i = 0;i < strlen(messageString+start);i++)
|
|
if (*(messageString+start+i) == '\n')
|
|
{
|
|
memset(string,0,40);
|
|
strncpy(string,messageString+start,i);
|
|
start += i+1;
|
|
break;
|
|
}
|
|
if (i == strlen(messageString+start))
|
|
{
|
|
strcpy(string,messageString+start);
|
|
start += i;
|
|
}
|
|
|
|
x = 160 - M_StringWidth(string)/2;
|
|
M_WriteText(x,y,string);
|
|
y += SHORT(hu_font[0].height);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!menuactive)
|
|
return;
|
|
|
|
if (currentMenu->routine)
|
|
currentMenu->routine(); // call Draw routine
|
|
|
|
// DRAW MENU
|
|
x = currentMenu->x;
|
|
y = currentMenu->y;
|
|
max = currentMenu->numitems;
|
|
|
|
for (i=0;i<max;i++)
|
|
{
|
|
if (currentMenu->menuitems[i].name[0])
|
|
V_DrawNamePatch(x,y,0,currentMenu->menuitems[i].name,
|
|
CR_DEFAULT, VPT_STRETCH);
|
|
y += LINEHEIGHT;
|
|
}
|
|
|
|
// DRAW SKULL
|
|
// CPhipps - patch drawing updated
|
|
V_DrawNamePatch(x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,0,
|
|
skullName[whichSkull], CR_DEFAULT, VPT_STRETCH);
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// M_ClearMenus
|
|
//
|
|
void M_ClearMenus (void)
|
|
{
|
|
menuactive = 0;
|
|
// if (!netgame && usergame && paused)
|
|
// sendpause = true;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// M_SetupNextMenu
|
|
//
|
|
void M_SetupNextMenu(menu_t *menudef)
|
|
{
|
|
currentMenu = menudef;
|
|
itemOn = currentMenu->lastOn;
|
|
}
|
|
|
|
|
|
//
|
|
// M_Ticker
|
|
//
|
|
void M_Ticker (void)
|
|
{
|
|
if (--skullAnimCounter <= 0)
|
|
{
|
|
whichSkull ^= 1;
|
|
skullAnimCounter = 8;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// M_Init
|
|
//
|
|
void M_Init (void)
|
|
{
|
|
currentMenu = &MainDef;
|
|
menuactive = 0;
|
|
itemOn = currentMenu->lastOn;
|
|
whichSkull = 0;
|
|
skullAnimCounter = 10;
|
|
screenSize = screenblocks - 3;
|
|
messageToPrint = 0;
|
|
messageString = NULL;
|
|
messageLastMenuActive = menuactive;
|
|
quickSaveSlot = -1;
|
|
|
|
// Here we could catch other version dependencies,
|
|
// like HELP1/2, and four episodes.
|
|
|
|
|
|
switch ( gamemode )
|
|
{
|
|
case commercial:
|
|
// This is used because DOOM 2 had only one HELP
|
|
// page. I use CREDIT as second page now, but
|
|
// kept this hack for educational purposes.
|
|
MainMenu[readthis] = MainMenu[quitdoom];
|
|
MainDef.numitems--;
|
|
MainDef.y += 8;
|
|
NewDef.prevMenu = &MainDef;
|
|
ReadDef1.routine = M_DrawReadThis1;
|
|
ReadDef1.x = 330;
|
|
ReadDef1.y = 165;
|
|
ReadMenu1[0].routine = M_FinishReadThis;
|
|
break;
|
|
case shareware:
|
|
// Episode 2 and 3 are handled,
|
|
// branching to an ad screen.
|
|
case registered:
|
|
// We need to remove the fourth episode.
|
|
EpiDef.numitems--;
|
|
break;
|
|
case retail:
|
|
// We are fine.
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|