From 39adfff2a9f73919dd09593efc38884dc2a05f40 Mon Sep 17 00:00:00 2001 From: inmarket Date: Tue, 24 Dec 2013 01:00:14 +1000 Subject: demo - DOOM the game. Runs but not quite functional yet (requires user input to be completed). Shareware WAD file. Please read README.txt and DOOMLIC.txt --- demos/3rdparty/doom/m_menu.c | 1893 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1893 insertions(+) create mode 100644 demos/3rdparty/doom/m_menu.c (limited to 'demos/3rdparty/doom/m_menu.c') diff --git a/demos/3rdparty/doom/m_menu.c b/demos/3rdparty/doom/m_menu.c new file mode 100644 index 00000000..4d415aed --- /dev/null +++ b/demos/3rdparty/doom/m_menu.c @@ -0,0 +1,1893 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// DOOM selection menu, options, episode etc. +// Sliders and icons. Kinda widget stuff. +// +//----------------------------------------------------------------------------- + +static const char +rcsid[] = "$Id: m_menu.c,v 1.7 1997/02/03 22:45:10 b1 Exp $"; + +#include +#include +#include +#include +#include +#include + + +#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_local.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" + + + +extern patch_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 detailLevel; +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! +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 + +char gammamsg[5][26] = +{ + GAMMALVL0, + GAMMALVL1, + GAMMALVL2, + GAMMALVL3, + GAMMALVL4 +}; + +// 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[160]; + + +// +// 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)(); // draw routine + 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 + +// 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_ChangeSensitivity(int choice); +void M_SfxVol(int choice); +void M_MusicVol(int choice); +void M_ChangeDetail(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(char *string); +int M_StringHeight(char *string); +void M_StartControlPanel(void); +void M_StartMessage(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 +} 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 +} 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 +} 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, + detail, + scrnsize, + option_empty1, + mousesens, + option_empty2, + soundvol, + opt_end +} options_e; + +menuitem_t OptionsMenu[]= +{ + {1,"M_ENDGAM", M_EndGame,'e'}, + {1,"M_MESSG", M_ChangeMessages,'m'}, + {1,"M_DETAIL", M_ChangeDetail,'g'}, + {2,"M_SCRNSZ", M_SizeDisplay,'s'}, + {-1,"",0}, + {2,"M_MSENS", M_ChangeSensitivity,'m'}, + {-1,"",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 +} 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 +} 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, + sound_end +} sound_e; + +menuitem_t SoundMenu[]= +{ + {2,"M_SFXVOL",M_SfxVol,'s'}, + {-1,"",0}, + {2,"M_MUSVOL",M_MusicVol,'m'}, + {-1,"",0} +}; + +menu_t SoundDef = +{ + sound_end, + &OptionsDef, + SoundMenu, + M_DrawSound, + 80,64, + 0 +}; + +// +// LOAD GAME MENU +// +enum +{ + load1, + load2, + load3, + load4, + load5, + load6, + load_end +} 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 count; + int i; + char name[256]; + + for (i = 0;i < load_end;i++) + { + if (M_CheckParm("-cdrom")) + sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i); + else + sprintf(name,SAVEGAMENAME"%d.dsg",i); + + handle = open (name, O_RDONLY | 0, 0666); + if (handle == -1) + { + strcpy(&savegamestrings[i][0],EMPTYSTRING); + LoadMenu[i].status = 0; + continue; + } + count = read (handle, &savegamestrings[i], SAVESTRINGSIZE); + close (handle); + LoadMenu[i].status = 1; + } +} + + +// +// M_LoadGame & Cie. +// +void M_DrawLoad(void) +{ + int i; + + V_DrawPatchDirect (72,28,0,W_CacheLumpName("M_LOADG",PU_CACHE)); + 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_DrawPatchDirect (x-8,y+7,0,W_CacheLumpName("M_LSLEFT",PU_CACHE)); + + for (i = 0;i < 24;i++) + { + V_DrawPatchDirect (x,y+7,0,W_CacheLumpName("M_LSCNTR",PU_CACHE)); + x += 8; + } + + V_DrawPatchDirect (x,y+7,0,W_CacheLumpName("M_LSRGHT",PU_CACHE)); +} + + + +// +// User wants to load this game +// +void M_LoadSelect(int choice) +{ + char name[256]; + + if (M_CheckParm("-cdrom")) + sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice); + else + sprintf(name,SAVEGAMENAME"%d.dsg",choice); + G_LoadGame (name); + M_ClearMenus (); +} + +// +// Selected from DOOM menu +// +void M_LoadGame (int choice) +{ + if (netgame) + { + M_StartMessage(LOADNET,NULL,false); + return; + } + + M_SetupNextMenu(&LoadDef); + M_ReadSaveStrings(); +} + + +// +// M_SaveGame & Cie. +// +void M_DrawSave(void) +{ + int i; + + V_DrawPatchDirect (72,28,0,W_CacheLumpName("M_SAVEG",PU_CACHE)); + 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; + strcpy(saveOldString,savegamestrings[choice]); + if (!strcmp(savegamestrings[choice],EMPTYSTRING)) + savegamestrings[choice][0] = 0; + saveCharIndex = strlen(savegamestrings[choice]); +} + +// +// Selected from DOOM menu +// +void M_SaveGame (int choice) +{ + if (!usergame) + { + M_StartMessage(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; + } + sprintf(tempstring,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; + } + sprintf(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_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP",PU_CACHE)); + break; + case shareware: + case registered: + case retail: + V_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP1",PU_CACHE)); + 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_DrawPatchDirect (0,0,0,W_CacheLumpName("CREDIT",PU_CACHE)); + break; + case shareware: + case registered: + V_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP2",PU_CACHE)); + break; + default: + break; + } + return; +} + + +// +// Change Sfx & Music volumes +// +void M_DrawSound(void) +{ + V_DrawPatchDirect (60,38,0,W_CacheLumpName("M_SVOL",PU_CACHE)); + + 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); +} + +void M_Sound(int 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 */); +} + + + + +// +// M_DrawMainMenu +// +void M_DrawMainMenu(void) +{ + V_DrawPatchDirect (94,2,0,W_CacheLumpName("M_DOOM",PU_CACHE)); +} + + + + +// +// M_NewGame +// +void M_DrawNewGame(void) +{ + V_DrawPatchDirect (96,14,0,W_CacheLumpName("M_NEWG",PU_CACHE)); + V_DrawPatchDirect (54,38,0,W_CacheLumpName("M_SKILL",PU_CACHE)); +} + +void M_NewGame(int choice) +{ + if (netgame && !demoplayback) + { + M_StartMessage(NEWGAME,NULL,false); + return; + } + + if ( gamemode == commercial ) + M_SetupNextMenu(&NewDef); + else + M_SetupNextMenu(&EpiDef); +} + + +// +// M_Episode +// +int epi; + +void M_DrawEpisode(void) +{ + V_DrawPatchDirect (54,38,0,W_CacheLumpName("M_EPISOD",PU_CACHE)); +} + +void M_VerifyNightmare(int ch) +{ + if (ch != 'y') + return; + + G_DeferedInitNew(nightmare,epi+1,1); + M_ClearMenus (); +} + +void M_ChooseSkill(int choice) +{ + if (choice == nightmare) + { + M_StartMessage(NIGHTMARE,M_VerifyNightmare,true); + return; + } + + G_DeferedInitNew(choice,epi+1,1); + M_ClearMenus (); +} + +void M_Episode(int choice) +{ + if ( (gamemode == shareware) + && choice) + { + M_StartMessage(SWSTRING,NULL,false); + M_SetupNextMenu(&ReadDef1); + return; + } + + // Yet another hack... + if ( (gamemode == registered) + && (choice > 2)) + { + 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) +{ + V_DrawPatchDirect (108,15,0,W_CacheLumpName("M_OPTTTL",PU_CACHE)); + + V_DrawPatchDirect (OptionsDef.x + 175,OptionsDef.y+LINEHEIGHT*detail,0, + W_CacheLumpName(detailNames[detailLevel],PU_CACHE)); + + V_DrawPatchDirect (OptionsDef.x + 120,OptionsDef.y+LINEHEIGHT*messages,0, + W_CacheLumpName(msgNames[showMessages],PU_CACHE)); + + M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(mousesens+1), + 10,mouseSensitivity); + + M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1), + 9,screenSize); +} + +void M_Options(int choice) +{ + M_SetupNextMenu(&OptionsDef); +} + + + +// +// Toggle messages on/off +// +void M_ChangeMessages(int choice) +{ + // warning: unused parameter `int choice' + choice = 0; + showMessages = 1 - showMessages; + + if (!showMessages) + players[consoleplayer].message = MSGOFF; + else + players[consoleplayer].message = MSGON ; + + message_dontfuckwithme = true; +} + + +// +// M_EndGame +// +void M_EndGameResponse(int ch) +{ + if (ch != 'y') + return; + + currentMenu->lastOn = itemOn; + M_ClearMenus (); + D_StartTitle (); +} + +void M_EndGame(int choice) +{ + choice = 0; + if (!usergame) + { + S_StartSound(NULL,sfx_oof); + return; + } + + if (netgame) + { + M_StartMessage(NETEND,NULL,false); + return; + } + + M_StartMessage(ENDGAME,M_EndGameResponse,true); +} + + + + +// +// M_ReadThis +// +void M_ReadThis(int choice) +{ + choice = 0; + M_SetupNextMenu(&ReadDef1); +} + +void M_ReadThis2(int choice) +{ + choice = 0; + M_SetupNextMenu(&ReadDef2); +} + +void M_FinishReadThis(int choice) +{ + choice = 0; + 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 != 'y') + 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) +{ + // We pick index 0 which is language sensitive, + // or one at random, between 1 and maximum number. + if (language != english ) + sprintf(endstring,"%s\n\n"DOSY, endmsg[0] ); + else + sprintf(endstring,"%s\n\n"DOSY, endmsg[ (gametic%(NUM_QUITMESSAGES-2))+1 ]); + + M_StartMessage(endstring,M_QuitResponse,true); +} + + + + +void M_ChangeSensitivity(int choice) +{ + switch(choice) + { + case 0: + if (mouseSensitivity) + mouseSensitivity--; + break; + case 1: + if (mouseSensitivity < 9) + mouseSensitivity++; + break; + } +} + + + + +void M_ChangeDetail(int choice) +{ + choice = 0; + detailLevel = 1 - detailLevel; + + // FIXME - does not work. Remove anyway? + fprintf( stderr, "M_ChangeDetail: low detail mode n.a.\n"); + + return; + + /*R_SetViewSize (screenblocks, detailLevel); + + if (!detailLevel) + players[consoleplayer].message = DETAILHI; + else + players[consoleplayer].message = DETAILLO;*/ +} + + + + +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, detailLevel); +} + + + + +// +// Menu Functions +// +void +M_DrawThermo +( int x, + int y, + int thermWidth, + int thermDot ) +{ + int xx; + int i; + + xx = x; + V_DrawPatchDirect (xx,y,0,W_CacheLumpName("M_THERML",PU_CACHE)); + xx += 8; + for (i=0;ix - 10, menu->y+item*LINEHEIGHT - 1, 0, + W_CacheLumpName("M_CELL1",PU_CACHE)); +} + +void +M_DrawSelCell +( menu_t* menu, + int item ) +{ + V_DrawPatchDirect (menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, + W_CacheLumpName("M_CELL2",PU_CACHE)); +} + + +void +M_StartMessage +( 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(char* string) +{ + int i; + int w = 0; + int c; + + for (i = 0;i < strlen(string);i++) + { + c = toupper(string[i]) - HU_FONTSTART; + if (c < 0 || c >= HU_FONTSIZE) + w += 4; + else + w += SHORT (hu_font[c]->width); + } + + return w; +} + + + +// +// Find string height from hu_font chars +// +int M_StringHeight(char* string) +{ + int i; + int h; + int height = SHORT(hu_font[0]->height); + + h = height; + for (i = 0;i < strlen(string);i++) + 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 > SCREENWIDTH) + break; + V_DrawPatchDirect(cx, cy, 0, hu_font[c]); + 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; + + 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_ENTER; + joywait = I_GetTime() + 5; + } + if (ev->data1&2) + { + ch = KEY_BACKSPACE; + joywait = I_GetTime() + 5; + } + } + else + { + 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_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 == 'y' || ch == KEY_ESCAPE)) + return false; + + menuactive = messageLastMenuActive; + messageToPrint = 0; + if (messageRoutine) + messageRoutine(ch); + + menuactive = false; + S_StartSound(NULL,sfx_swtchx); + return true; + } + + if (devparm && ch == KEY_F1) + { + G_ScreenShot (); + return true; + } + + + // F-Keys + if (!menuactive) + switch(ch) + { + case KEY_MINUS: // Screen size down + if (automapactive || chat_on) + return false; + M_SizeDisplay(0); + S_StartSound(NULL,sfx_stnmov); + return true; + + case KEY_EQUALS: // Screen size up + if (automapactive || chat_on) + return false; + M_SizeDisplay(1); + S_StartSound(NULL,sfx_stnmov); + return true; + + 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_F2: // Save + M_StartControlPanel(); + S_StartSound(NULL,sfx_swtchn); + M_SaveGame(0); + return true; + + case KEY_F3: // Load + M_StartControlPanel(); + S_StartSound(NULL,sfx_swtchn); + M_LoadGame(0); + return true; + + case KEY_F4: // Sound Volume + M_StartControlPanel (); + currentMenu = &SoundDef; + itemOn = sfx_vol; + S_StartSound(NULL,sfx_swtchn); + return true; + + case KEY_F5: // Detail toggle + M_ChangeDetail(0); + S_StartSound(NULL,sfx_swtchn); + return true; + + case KEY_F6: // Quicksave + S_StartSound(NULL,sfx_swtchn); + M_QuickSave(); + return true; + + case KEY_F7: // End game + S_StartSound(NULL,sfx_swtchn); + M_EndGame(0); + return true; + + case KEY_F8: // Toggle messages + M_ChangeMessages(0); + S_StartSound(NULL,sfx_swtchn); + return true; + + case KEY_F9: // Quickload + S_StartSound(NULL,sfx_swtchn); + M_QuickLoad(); + return true; + + case KEY_F10: // Quit DOOM + S_StartSound(NULL,sfx_swtchn); + M_QuitDOOM(0); + return true; + + case KEY_F11: // gamma toggle + usegamma++; + if (usegamma > 4) + usegamma = 0; + players[consoleplayer].message = gammamsg[usegamma]; + I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE)); + return true; + + } + + + // Pop-up menu? + if (!menuactive) + { + if (ch == KEY_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; + 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;imenuitems[i].name[0]) + V_DrawPatchDirect (x,y,0, + W_CacheLumpName(currentMenu->menuitems[i].name ,PU_CACHE)); + y += LINEHEIGHT; + } + + + // DRAW SKULL + V_DrawPatchDirect(x + SKULLXOFF,currentMenu->y - 5 + itemOn*LINEHEIGHT, 0, + W_CacheLumpName(skullName[whichSkull],PU_CACHE)); + +} + + +// +// 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; + } + +} + -- cgit v1.2.3