diff options
Diffstat (limited to 'src/strife/m_menu.c')
-rw-r--r-- | src/strife/m_menu.c | 2317 |
1 files changed, 2317 insertions, 0 deletions
diff --git a/src/strife/m_menu.c b/src/strife/m_menu.c new file mode 100644 index 00000000..1fb3eeaf --- /dev/null +++ b/src/strife/m_menu.c @@ -0,0 +1,2317 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 2005 Simon Howard +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// DESCRIPTION: +// DOOM selection menu, options, episode etc. +// Sliders and icons. Kinda widget stuff. +// +//----------------------------------------------------------------------------- + + +#include <stdlib.h> +#include <ctype.h> + + +#include "doomdef.h" +#include "doomkeys.h" +#include "dstrings.h" + +#include "d_main.h" +#include "deh_main.h" + +#include "i_swap.h" +#include "i_system.h" +#include "i_timer.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_controls.h" +#include "m_saves.h" // [STRIFE] +#include "p_saveg.h" + +#include "s_sound.h" + +#include "doomstat.h" + +// Data. +#include "sounds.h" + +#include "m_menu.h" +#include "p_dialog.h" + + +extern void M_QuitStrife(int); + +extern patch_t* hu_font[HU_FONTSIZE]; +extern boolean message_dontfuckwithme; + +extern boolean chat_on; // in heads-up code +extern boolean sendsave; // [STRIFE] + +// +// defaulted values +// +int mouseSensitivity = 5; + +// [STRIFE]: removed this entirely +// Show messages has default, 0 = off, 1 = on +//int showMessages = 1; + + +// Blocky mode, has default, 0 = high, 1 = normal +int detailLevel = 0; +int screenblocks = 9; + +// 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); + +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; +boolean menupause; // haleyjd 08/29/10: [STRIFE] New global +int menupausetime; // haleyjd 09/04/10: [STRIFE] New global +boolean menuindialog; // haleyjd 09/04/10: ditto + +// haleyjd 08/27/10: [STRIFE] SKULLXOFF == -28, LINEHEIGHT == 19 +#define CURSORXOFF -28 +#define LINEHEIGHT 19 + +extern boolean sendpause; +char savegamestrings[10][SAVESTRINGSIZE]; + +char endstring[160]; + +// haleyjd 09/04/10: [STRIFE] Moved menuitem / menu structures into header +// because they are needed externally by the dialog engine. + +// haleyjd 08/27/10: [STRIFE] skull* stuff changed to cursor* stuff +short itemOn; // menu item skull is on +short cursorAnimCounter; // skull animation counter +short whichCursor; // which skull to draw + +// graphic name of cursors +// haleyjd 08/27/10: [STRIFE] M_SKULL* -> M_CURS* +char *cursorName[8] = {"M_CURS1", "M_CURS2", "M_CURS3", "M_CURS4", + "M_CURS5", "M_CURS6", "M_CURS7", "M_CURS8" }; + +// haleyjd 20110210 [STRIFE]: skill level for menus +int menuskill; + +// 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_ReadThis3(int choice); // [STRIFE] +void M_QuitStrife(int choice); + +//void M_ChangeMessages(int choice); [STRIFE] +void M_ChangeSensitivity(int choice); +void M_SfxVol(int choice); +void M_VoiceVol(int choice); // [STRIFE] +void M_MusicVol(int choice); +void M_SizeDisplay(int choice); +void M_StartGame(int choice); +void M_Sound(int choice); + +//void M_FinishReadThis(int choice); - [STRIFE] unused +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_DrawReadThis3(void); // [STRIFE] +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); +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 (int choice); + + + + +// +// 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,'h'}, // haleyjd 08/28/10: 'r' -> 'h' + {1,"M_QUITG",M_QuitStrife,'q'} +}; + +menu_t MainDef = +{ + main_end, + NULL, + MainMenu, + M_DrawMainMenu, + 97,45, // haleyjd 08/28/10: [STRIFE] changed y coord + 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[]= +{ + // haleyjd 08/28/10: [STRIFE] changed all shortcut letters + {1,"M_JKILL", M_ChooseSkill, 't'}, + {1,"M_ROUGH", M_ChooseSkill, 'r'}, + {1,"M_HURT", M_ChooseSkill, 'v'}, + {1,"M_ULTRA", M_ChooseSkill, 'e'}, + {1,"M_NMARE", M_ChooseSkill, 'b'} +}; + +menu_t NewDef = +{ + newg_end, // # of menu items + &MainDef, // previous menu - haleyjd [STRIFE] changed to MainDef + NewGameMenu, // menuitem_t -> + M_DrawNewGame, // drawing routine -> + 48,63, // x,y + toorough // lastOn - haleyjd [STRIFE]: default to skill 1 +}; + +// +// OPTIONS MENU +// +enum +{ + // haleyjd 08/28/10: [STRIFE] Removed messages, mouse sens., detail. + endgame, + scrnsize, + option_empty1, + soundvol, + opt_end +} options_e; + +menuitem_t OptionsMenu[]= +{ + // haleyjd 08/28/10: [STRIFE] Removed messages, mouse sens., detail. + {1,"M_ENDGAM", M_EndGame,'e'}, + {2,"M_SCRNSZ", M_SizeDisplay,'s'}, + {-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 & [STRIFE] 3 +// +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_ReadThis3,0} // haleyjd 08/28/10: [STRIFE] Go to ReadThis3 +}; + +menu_t ReadDef2 = +{ + read2_end, + &ReadDef1, + ReadMenu2, + M_DrawReadThis2, + 250,185, // haleyjd 08/28/10: [STRIFE] changed coords + 0 +}; + +// haleyjd 08/28/10: Added Read This! menu 3 +enum +{ + rdthsempty3, + read3_end +} read_e3; + +menuitem_t ReadMenu3[]= +{ + {1,"",M_ClearMenus,0} +}; + +menu_t ReadDef3 = +{ + read3_end, + &ReadDef2, + ReadMenu3, + M_DrawReadThis3, + 250, 185, + 0 +}; + +// +// SOUND VOLUME MENU +// +enum +{ + sfx_vol, + sfx_empty1, + music_vol, + sfx_empty2, + voice_vol, + sfx_empty3, + sfx_mouse, + sfx_empty4, + sound_end +} sound_e; + +// haleyjd 08/29/10: +// [STRIFE] +// * Added voice volume +// * Moved mouse sensitivity here (who knows why...) +menuitem_t SoundMenu[]= +{ + {2,"M_SFXVOL",M_SfxVol,'s'}, + {-1,"",0,'\0'}, + {2,"M_MUSVOL",M_MusicVol,'m'}, + {-1,"",0,'\0'}, + {2,"M_VOIVOL",M_VoiceVol,'v'}, + {-1,"",0,'\0'}, + {2,"M_MSENS",M_ChangeSensitivity,'m'}, + {-1,"",0,'\0'} +}; + +menu_t SoundDef = +{ + sound_end, + &OptionsDef, + SoundMenu, + M_DrawSound, + 80,35, // [STRIFE] changed y coord 64 -> 35 + 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 +}; + +void M_DrawNameChar(void); + +// +// NAME CHARACTER MENU +// +// [STRIFE] +// haleyjd 20110210: New "Name Your Character" Menu +// +menu_t NameCharDef = +{ + load_end, + &NewDef, + SaveMenu, + M_DrawNameChar, + 80,54, + 0 +}; + + +// +// M_ReadSaveStrings +// read the strings from the savegame files +// +// [STRIFE] +// haleyjd 20110210: Rewritten to read "name" file in each slot directory +// +void M_ReadSaveStrings(void) +{ + FILE *handle; + int count; + int i; + char *fname = NULL; + + for(i = 0; i < load_end; i++) + { + if(fname) + Z_Free(fname); + fname = M_SafeFilePath(savegamedir, M_MakeStrifeSaveDir(i, "\\name")); + + handle = fopen(fname, "rb"); + if(handle == NULL) + { + strcpy(savegamestrings[i], EMPTYSTRING); + LoadMenu[i].status = 0; + continue; + } + count = fread(savegamestrings[i], 1, SAVESTRINGSIZE, handle); + fclose(handle); + LoadMenu[i].status = 1; + } + + if(fname) + Z_Free(fname); +} + +// +// M_DrawNameChar +// +// haleyjd 09/22/10: [STRIFE] New function +// Handler for drawing the "Name Your Character" menu. +// +void M_DrawNameChar(void) +{ + int i; + + M_WriteText(72, 28, DEH_String("Name Your Character")); + + 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[quickSaveSlot]); + M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*quickSaveSlot,"_"); + } +} + +// +// M_DoNameChar +// +// haleyjd 09/22/10: [STRIFE] New function +// Handler for items in the "Name Your Character" menu. +// +void M_DoNameChar(int choice) +{ + int map; + + sendsave = 1; + ClearTmp(); + G_WriteSaveName(choice, savegamestrings[choice]); + quickSaveSlot = choice; // VERIFY VARIABLE + SaveDef.lastOn = choice; + ClearSlot(); + FromCurr(); + + if(isdemoversion) + map = 33; + else + map = 2; + + G_DeferedInitNew(menuskill, map); + M_ClearMenus(0); +} + +// +// M_LoadGame & Cie. +// +void M_DrawLoad(void) +{ + int i; + + V_DrawPatchDirect(72, 28, + W_CacheLumpName(DEH_String("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, + W_CacheLumpName(DEH_String("M_LSLEFT"), PU_CACHE)); + + for (i = 0;i < 24;i++) + { + V_DrawPatchDirect(x, y + 7, + W_CacheLumpName(DEH_String("M_LSCNTR"), PU_CACHE)); + x += 8; + } + + V_DrawPatchDirect(x, y + 7, + W_CacheLumpName(DEH_String("M_LSRGHT"), PU_CACHE)); +} + + + +// +// User wants to load this game +// +void M_LoadSelect(int choice) +{ + /* + char name[256]; + + strcpy(name, P_SaveGameFile(choice)); + + G_LoadGame (name); + M_ClearMenus (0); + */ + + // [STRIFE] (v1.2) - TODO: v1.31 + char *name = NULL; + + G_WriteSaveName(choice, savegamestrings[choice]); + ToCurr(); + + name = M_SafeFilePath(savegamedir, M_MakeStrifeSaveDir(choice, "")); + + G_ReadCurrent(name); + quickSaveSlot = choice; + M_ClearMenus(0); + + Z_Free(name); +} + +// +// Selected from DOOM menu +// +// [STRIFE] Verified unmodified (v1.2) - TODO: v1.31 +// +void M_LoadGame (int choice) +{ + if (netgame) + { + M_StartMessage(DEH_String(LOADNET), NULL, false); + return; + } + + M_SetupNextMenu(&LoadDef); + M_ReadSaveStrings(); +} + + +// +// M_SaveGame & Cie. +// +void M_DrawSave(void) +{ + int i; + + V_DrawPatchDirect(72, 28, W_CacheLumpName(DEH_String("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[quickSaveSlot]); + M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*quickSaveSlot,"_"); + } +} + +// +// M_Responder calls this when user is finished +// +void M_DoSave(int slot) +{ + /* + G_SaveGame (slot,savegamestrings[slot]); + M_ClearMenus (0); + + // PICK QUICKSAVE SLOT YET? + if (quickSaveSlot == -2) + quickSaveSlot = slot; + */ + // [STRIFE] (v1.2) - TODO: v1.31 + if(slot >= 0) + { + sendsave = 1; + G_WriteSaveName(slot, savegamestrings[slot]); + M_ClearMenus(0); + quickSaveSlot = slot; + FromCurr(); + } + else + M_StartMessage(DEH_String(QSAVESPOT), NULL, false); +} + +// +// 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; + + // [STRIFE] (v1.2) - TODO: 1.31 + quickSaveSlot = choice; + //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) +{ + // [STRIFE] (v1.2) - TODO: v1.31 + if (netgame) + { + // haleyjd 20110211: Hooray for Rogue's awesome multiplayer support... + M_StartMessage(DEH_String("You can't save a netgame"), NULL, false); + return; + } + if (!usergame) + { + M_StartMessage(DEH_String(SAVEDEAD),NULL,false); + return; + } + + if (gamestate != GS_LEVEL) + return; + + // [STRIFE] (v1.2) - TODO: v1.31 + //M_SetupNextMenu(&SaveDef); + M_ReadSaveStrings(); + M_DoSave(quickSaveSlot); +} + + + +// +// M_QuickSave +// +char tempstring[80]; + +void M_QuickSaveResponse(int key) +{ + if (key == key_menu_confirm) + { + M_DoSave(quickSaveSlot); + S_StartSound(NULL, sfx_mtalht); // [STRIFE] sound + } +} + +void M_QuickSave(void) +{ + if (netgame) + { + // haleyjd 20110211 [STRIFE]: More fun... + M_StartMessage(DEH_String("You can't save a netgame"), NULL, false); + return; + } + + 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; + } + DEH_snprintf(tempstring, 80, QSPROMPT, savegamestrings[quickSaveSlot]); + M_StartMessage(tempstring,M_QuickSaveResponse,true); +} + + + +// +// M_QuickLoadResponse +// +void M_QuickLoadResponse(int key) +{ + if (key == key_menu_confirm) + { + M_LoadSelect(quickSaveSlot); + S_StartSound(NULL, sfx_mtalht); // [STRIFE] sound + } +} + +// +// M_QuickLoad +// +// [STRIFE] Verified unmodified (v1.2) - TODO: v1.31 +// +void M_QuickLoad(void) +{ + if (netgame) + { + M_StartMessage(DEH_String(QLOADNET),NULL,false); + return; + } + + if (quickSaveSlot < 0) + { + M_StartMessage(DEH_String(QSAVESPOT),NULL,false); + return; + } + DEH_snprintf(tempstring, 80, QLPROMPT, savegamestrings[quickSaveSlot]); + M_StartMessage(tempstring,M_QuickLoadResponse,true); +} + + + + +// +// Read This Menus +// Had a "quick hack to fix romero bug" +// haleyjd 08/28/10: [STRIFE] Draw HELP1, unconditionally. +// +void M_DrawReadThis1(void) +{ + inhelpscreens = true; + + V_DrawPatchDirect (0, 0, W_CacheLumpName(DEH_String("HELP1"), PU_CACHE)); +} + + + +// +// Read This Menus +// haleyjd 08/28/10: [STRIFE] Not optional, draws HELP2 +// +void M_DrawReadThis2(void) +{ + inhelpscreens = true; + + V_DrawPatchDirect(0, 0, W_CacheLumpName(DEH_String("HELP2"), PU_CACHE)); +} + + +// +// Read This Menus +// haleyjd 08/28/10: [STRIFE] New function to draw HELP3. +// +void M_DrawReadThis3(void) +{ + inhelpscreens = true; + + V_DrawPatchDirect(0, 0, W_CacheLumpName(DEH_String("HELP3"), PU_CACHE)); +} + +// +// Change Sfx & Music volumes +// +// haleyjd 08/29/10: [STRIFE] +// * Changed title graphic coordinates +// * Added voice volume and sensitivity sliders +// +void M_DrawSound(void) +{ + V_DrawPatchDirect (100, 10, W_CacheLumpName(DEH_String("M_SVOL"), PU_CACHE)); + + M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1), + 16,sfxVolume); + + M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1), + 16,musicVolume); + + M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(voice_vol+1), + 16,voiceVolume); + + M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_mouse+1), + 16,mouseSensitivity); +} + +void M_Sound(int choice) +{ + M_SetupNextMenu(&SoundDef); +} + +void M_SfxVol(int choice) +{ + switch(choice) + { + case 0: + if (sfxVolume) + sfxVolume--; + break; + case 1: + if (sfxVolume < 15) + sfxVolume++; + break; + } + + S_SetSfxVolume(sfxVolume * 8); +} + +// +// M_VoiceVol +// +// haleyjd 08/29/10: [STRIFE] New function +// Sets voice volume level. +// +void M_VoiceVol(int choice) +{ + switch(choice) + { + case 0: + if (voiceVolume) + voiceVolume--; + break; + case 1: + if (voiceVolume < 15) + voiceVolume++; + break; + } + + S_SetVoiceVolume(voiceVolume * 8); +} + +void M_MusicVol(int choice) +{ + switch(choice) + { + case 0: + if (musicVolume) + musicVolume--; + break; + case 1: + if (musicVolume < 15) + musicVolume++; + break; + } + + S_SetMusicVolume(musicVolume * 8); +} + + + + +// +// M_DrawMainMenu +// +// haleyjd 08/27/10: [STRIFE] Changed x coordinate; M_DOOM -> M_STRIFE +// +void M_DrawMainMenu(void) +{ + V_DrawPatchDirect(84, 2, + W_CacheLumpName(DEH_String("M_STRIFE"), PU_CACHE)); +} + + + + +// +// M_NewGame +// +// haleyjd 08/31/10: [STRIFE] Changed M_NEWG -> M_NGAME +// +void M_DrawNewGame(void) +{ + V_DrawPatchDirect(96, 14, W_CacheLumpName(DEH_String("M_NGAME"), PU_CACHE)); + V_DrawPatchDirect(54, 38, W_CacheLumpName(DEH_String("M_SKILL"), PU_CACHE)); +} + +void M_NewGame(int choice) +{ + if (netgame && !demoplayback) + { + M_StartMessage(DEH_String(NEWGAME),NULL,false); + return; + } + // haleyjd 09/07/10: [STRIFE] Removed Chex Quest and DOOM gamemodes + M_SetupNextMenu(&NewDef); +} + + +// +// M_Episode +// +int epi; + +void M_DrawEpisode(void) +{ + V_DrawPatchDirect(54, 38, W_CacheLumpName(DEH_String("M_EPISOD"), PU_CACHE)); +} + +/* +// haleyjd: [STRIFE] Unused +void M_VerifyNightmare(int key) +{ + if (key != key_menu_confirm) + return; + + G_DeferedInitNew(nightmare, 1); + M_ClearMenus (0); +} +*/ + +void M_ChooseSkill(int choice) +{ + // haleyjd 09/07/10: Removed nightmare confirmation + // [STRIFE]: start "Name Your Character" menu + menuskill = choice; + currentMenu = &NameCharDef; + itemOn = NameCharDef.lastOn; + M_ReadSaveStrings(); +} + +/* +// haleyjd [STRIFE] Unused +void M_Episode(int choice) +{ + if ( (gamemode == shareware) + && choice) + { + M_StartMessage(DEH_String(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) +{ + // haleyjd 08/27/10: [STRIFE] M_OPTTTL -> M_OPTION + V_DrawPatchDirect(108, 15, + W_CacheLumpName(DEH_String("M_OPTION"), PU_CACHE)); + + // haleyjd 08/26/10: [STRIFE] Removed messages, sensitivity, detail. + + M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1), + 9,screenSize); +} + +void M_Options(int choice) +{ + M_SetupNextMenu(&OptionsDef); +} + +// +// M_AutoUseHealth +// +// [STRIFE] New function +// haleyjd 20110211: toggle autouse health state +// +void M_AutoUseHealth(void) +{ + if(!netgame && usergame) + { + players[consoleplayer].cheats ^= CF_AUTOHEALTH; + + if(players[consoleplayer].cheats & CF_AUTOHEALTH) + players[consoleplayer].message = DEH_String("Auto use health ON"); + else + players[consoleplayer].message = DEH_String("Auto use health OFF"); + } +} + +// +// M_ChangeShowText +// +// [STRIFE] New function +// +void M_ChangeShowText(void) +{ + dialogshowtext ^= true; + + if(dialogshowtext) + players[consoleplayer].message = DEH_String("Conversation Text On"); + else + players[consoleplayer].message = DEH_String("Conversation Text Off"); +} + +// +// Toggle messages on/off +// +// [STRIFE] Messages cannot be disabled in Strife +/* +void M_ChangeMessages(int choice) +{ + // warning: unused parameter `int choice' + choice = 0; + showMessages = 1 - showMessages; + + if (!showMessages) + players[consoleplayer].message = DEH_String(MSGOFF); + else + players[consoleplayer].message = DEH_String(MSGON); + + message_dontfuckwithme = true; +} +*/ + + +// +// M_EndGame +// +void M_EndGameResponse(int key) +{ + if (key != key_menu_confirm) + return; + + currentMenu->lastOn = itemOn; + M_ClearMenus (0); + D_StartTitle (); +} + +void M_EndGame(int choice) +{ + choice = 0; + if (!usergame) + { + S_StartSound(NULL,sfx_oof); + return; + } + + if (netgame) + { + M_StartMessage(DEH_String(NETEND),NULL,false); + return; + } + + M_StartMessage(DEH_String(ENDGAME),M_EndGameResponse,true); +} + + + + +// +// M_ReadThis +// +void M_ReadThis(int choice) +{ + choice = 0; + M_SetupNextMenu(&ReadDef1); +} + +// +// M_ReadThis2 +// +// haleyjd 08/28/10: [STRIFE] Eliminated DOOM stuff. +// +void M_ReadThis2(int choice) +{ + choice = 0; + M_SetupNextMenu(&ReadDef2); +} + +// +// M_ReadThis3 +// +// haleyjd 08/28/10: [STRIFE] New function. +// +void M_ReadThis3(int choice) +{ + choice = 0; + M_SetupNextMenu(&ReadDef3); +} + +/* +// haleyjd 08/28/10: [STRIFE] Not used. +void M_FinishReadThis(int choice) +{ + choice = 0; + M_SetupNextMenu(&MainDef); +} +*/ + + +// +// M_QuitResponse +// +// haleyjd 09/11/10: [STRIFE] Modifications to start up endgame +// demosequence. +// +void M_QuitResponse(int key) +{ + char buffer[20]; + + if (key != key_menu_confirm) + return; + + if(netgame) + I_Quit(); + else + { + DEH_snprintf(buffer, sizeof(buffer), "qfmrm%i", gametic % 8 + 1); + I_StartVoice(buffer); + D_QuitGame(); + } +} + +/* +// haleyjd 09/11/10: [STRIFE] Unused +static char *M_SelectEndMessage(void) +{ +} +*/ + +// +// M_QuitStrife +// +// [STRIFE] Renamed from M_QuitDOOM +// haleyjd 09/11/10: No randomized text message; that's taken care of +// by the randomized voice message after confirmation. +// +void M_QuitStrife(int choice) +{ + DEH_snprintf(endstring, sizeof(endstring), + "Do you really want to leave?\n\n" DOSY); + + 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; + } +} + +/* +// haleyjd [STRIFE] Unused +void M_ChangeDetail(int choice) +{ + choice = 0; + detailLevel = 1 - detailLevel; + + R_SetViewSize (screenblocks, detailLevel); + + if (!detailLevel) + players[consoleplayer].message = DEH_String(DETAILHI); + else + players[consoleplayer].message = DEH_String(DETAILLO); +} +*/ + +// [STRIFE] Verified unmodified +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 +// + +// +// M_DrawThermo +// +// haleyjd 08/28/10: [STRIFE] Changes to some patch coordinates. +// +void +M_DrawThermo +( int x, + int y, + int thermWidth, + int thermDot ) +{ + int xx; + int yy; // [STRIFE] Needs a temp y coordinate variable + int i; + + xx = x; + yy = y + 6; // [STRIFE] +6 to y coordinate + V_DrawPatchDirect(xx, yy, W_CacheLumpName(DEH_String("M_THERML"), PU_CACHE)); + xx += 8; + for (i=0;i<thermWidth;i++) + { + V_DrawPatchDirect(xx, yy, W_CacheLumpName(DEH_String("M_THERMM"), PU_CACHE)); + xx += 8; + } + V_DrawPatchDirect(xx, yy, W_CacheLumpName(DEH_String("M_THERMR"), PU_CACHE)); + + // [STRIFE] +2 to initial y coordinate + V_DrawPatchDirect((x + 8) + thermDot * 8, y + 2, + W_CacheLumpName(DEH_String("M_THERMO"), PU_CACHE)); +} + + +// haleyjd: These are from DOOM v0.5 and the prebeta! They drew those ugly red & +// blue checkboxes... preserved for historical interest, as not in Strife. +void +M_DrawEmptyCell +( menu_t* menu, + int item ) +{ + V_DrawPatchDirect(menu->x - 10, menu->y + item * LINEHEIGHT - 1, + W_CacheLumpName(DEH_String("M_CELL1"), PU_CACHE)); +} + +void +M_DrawSelCell +( menu_t* menu, + int item ) +{ + V_DrawPatchDirect(menu->x - 10, menu->y + item * LINEHEIGHT - 1, + W_CacheLumpName(DEH_String("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) +{ + size_t 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) +{ + size_t 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; +} + + +// +// M_WriteText +// +// Write a string using the hu_font +// haleyjd 09/04/10: [STRIFE] +// * Rogue made a lot of changes to this for the dialog system. +// +int +M_WriteText +( int x, + int y, + const char* string) // haleyjd: made const for safety w/dialog engine +{ + int w; + const char* ch; + int c; + int cx; + int cy; + + ch = string; + cx = x; + cy = y; + + while(1) + { + c = *ch++; + if (!c) + break; + + // haleyjd 09/04/10: [STRIFE] Don't draw spaces at the start of lines. + if(c == ' ' && cx == x) + continue; + + if (c == '\n') + { + cx = x; + cy += 11; // haleyjd 09/04/10: [STRIFE]: Changed 12 -> 11 + continue; + } + + c = toupper(c) - HU_FONTSTART; + if (c < 0 || c>= HU_FONTSIZE) + { + cx += 4; + continue; + } + + w = SHORT (hu_font[c]->width); + + // haleyjd 09/04/10: [STRIFE] Different linebreak handling + if (cx + w > SCREENWIDTH - 20) + { + cx = x; + cy += 11; + --ch; + } + else + { + V_DrawPatchDirect(cx, cy, hu_font[c]); + cx += w; + } + } + + // [STRIFE] Return final y coordinate. + return cy + 12; +} + +// +// M_DialogDimMsg +// +// [STRIFE] New function +// haleyjd 09/04/10: Painstakingly transformed from the assembly code, as the +// decompiler could not touch it. Redimensions a string to fit on screen, leaving +// at least a 20 pixel margin on the right side. The string passed in must be +// writable. +// +void M_DialogDimMsg(int x, int y, char *str, boolean useyfont) +{ + int rightbound = (SCREENWIDTH - 20) - x; + patch_t **fontarray; // ebp + int linewidth = 0; // esi + int i = 0; // edx + char *message = str; // edi + char bl; // bl + + if(useyfont) + fontarray = yfont; + else + fontarray = hu_font; + + bl = toupper(*message); + + if(!bl) + return; + + // outer loop - run to end of string + do + { + if(bl != '\n') + { + int charwidth; // eax + int tempwidth; // ecx + + if(bl < HU_FONTSTART || bl > HU_FONTEND) + charwidth = 4; + else + charwidth = SHORT(fontarray[bl - HU_FONTSTART]->width); + + tempwidth = linewidth + charwidth; + + // Test if the line still fits within the boundary... + if(tempwidth >= rightbound) + { + // Doesn't fit... + char *tempptr = &message[i]; // ebx + char al; // al + + // inner loop - run backward til a space (or the start of the + // string) is found, subtracting width off the current line. + // BUG: shouldn't we stop at a previous '\n' too? + while(*tempptr != ' ' && i > 0) + { + tempptr--; + // BUG: they didn't add the first char to linewidth yet... + linewidth -= charwidth; + i--; + al = toupper(*tempptr); + if(al < HU_FONTSTART || al > HU_FONTEND) + charwidth = 4; + else + charwidth = SHORT(fontarray[al - HU_FONTSTART]->width); + } + // Replace the space with a linebreak. + // BUG: what if i is zero? ... infinite loop time! + message[i] = '\n'; + linewidth = 0; + } + else + { + // The line does fit. + // Spaces at the start of a line don't count though. + if(!(bl == ' ' && linewidth == 0)) + linewidth += charwidth; + } + } + else + linewidth = 0; // '\n' seen, so reset the line width + } + while((bl = toupper(message[++i])) != 0); // step to the next character +} + + +// +// CONTROL PANEL +// + +// +// M_Responder +// +boolean M_Responder (event_t* ev) +{ + int ch; + int key; + 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; + + // "close" button pressed on window? + if (ev->type == ev_quit) + { + S_StartSound(NULL, sfx_swtchn); + M_QuitStrife(0); + return true; + } + + // key is the key pressed, ch is the actual character typed + + ch = 0; + key = -1; + + if (ev->type == ev_joystick && joywait < I_GetTime()) + { + if (ev->data3 < 0) + { + key = key_menu_up; + joywait = I_GetTime() + 5; + } + else if (ev->data3 > 0) + { + key = key_menu_down; + joywait = I_GetTime() + 5; + } + + if (ev->data2 < 0) + { + key = key_menu_left; + joywait = I_GetTime() + 2; + } + else if (ev->data2 > 0) + { + key = key_menu_right; + joywait = I_GetTime() + 2; + } + + if (ev->data1&1) + { + key = key_menu_forward; + joywait = I_GetTime() + 5; + } + if (ev->data1&2) + { + key = key_menu_back; + joywait = I_GetTime() + 5; + } + } + else + { + if (ev->type == ev_mouse && mousewait < I_GetTime()) + { + mousey += ev->data3; + if (mousey < lasty-30) + { + key = key_menu_down; + mousewait = I_GetTime() + 5; + mousey = lasty -= 30; + } + else if (mousey > lasty+30) + { + key = key_menu_up; + mousewait = I_GetTime() + 5; + mousey = lasty += 30; + } + + mousex += ev->data2; + if (mousex < lastx-30) + { + key = key_menu_left; + mousewait = I_GetTime() + 5; + mousex = lastx -= 30; + } + else if (mousex > lastx+30) + { + key = key_menu_right; + mousewait = I_GetTime() + 5; + mousex = lastx += 30; + } + + if (ev->data1&1) + { + key = key_menu_forward; + mousewait = I_GetTime() + 15; + mouse_fire_countdown = 5; // villsa [STRIFE] + } + + if (ev->data1&2) + { + key = key_menu_back; + mousewait = I_GetTime() + 15; + } + } + else + { + if (ev->type == ev_keydown) + { + key = ev->data1; + ch = ev->data2; + } + } + } + + if (key == -1) + return false; + + // In testcontrols mode, none of the function keys should do anything + // - the only key is escape to quit. + + if (testcontrols) + { + if (key == key_menu_activate || key == key_menu_quit) + { + I_Quit(); + return true; + } + + return false; + } + + // Save Game string input + if (saveStringEnter) + { + switch(key) + { + case KEY_BACKSPACE: + if (saveCharIndex > 0) + { + saveCharIndex--; + savegamestrings[quickSaveSlot][saveCharIndex] = 0; + } + break; + + case KEY_ESCAPE: + saveStringEnter = 0; + strcpy(&savegamestrings[quickSaveSlot][0],saveOldString); + break; + + case KEY_ENTER: + // [STRIFE] v1.2 - TODO: v1.31 + saveStringEnter = 0; + if (savegamestrings[quickSaveSlot][0]) + M_DoNameChar(quickSaveSlot); + break; + + default: + // Entering a character - use the 'ch' value, not the key + + ch = toupper(ch); + + if (ch != ' ' + && (ch - HU_FONTSTART < 0 || ch - HU_FONTSTART >= HU_FONTSIZE)) + { + break; + } + + if (ch >= 32 && ch <= 127 && + saveCharIndex < SAVESTRINGSIZE-1 && + M_StringWidth(savegamestrings[quickSaveSlot]) < + (SAVESTRINGSIZE-2)*8) + { + savegamestrings[quickSaveSlot][saveCharIndex++] = ch; + savegamestrings[quickSaveSlot][saveCharIndex] = 0; + } + break; + } + return true; + } + + // Take care of any messages that need input + if (messageToPrint) + { + if (messageNeedsInput) + { + if (key != ' ' && key != KEY_ESCAPE + && key != key_menu_confirm && key != key_menu_abort) + { + return false; + } + } + + menuactive = messageLastMenuActive; + messageToPrint = 0; + if (messageRoutine) + messageRoutine(key); + + menupause = false; // [STRIFE] unpause + menuactive = false; + S_StartSound(NULL, sfx_mtalht); // [STRIFE] sound + return true; + } + + // [STRIFE]: + // * In v1.2 this is moved to F9 (quickload) + // * In v1.31 it is moved to a different button and quicksave + // functionality is restored separate from normal saving (STRIFE-TODO) + /* + if (devparm && key == key_menu_help) + { + G_ScreenShot (); + return true; + } + */ + + // F-Keys + if (!menuactive) + { + if (key == key_menu_decscreen) // Screen size down + { + if (automapactive || chat_on) + return false; + M_SizeDisplay(0); + S_StartSound(NULL, sfx_stnmov); + return true; + } + else if (key == key_menu_incscreen) // Screen size up + { + if (automapactive || chat_on) + return false; + M_SizeDisplay(1); + S_StartSound(NULL, sfx_stnmov); + return true; + } + else if (key == key_menu_help) // Help key + { + M_StartControlPanel (); + // haleyjd 08/29/10: [STRIFE] always ReadDef1 + currentMenu = &ReadDef1; + + itemOn = 0; + S_StartSound(NULL, sfx_swtchn); + return true; + } + else if (key == key_menu_save) // Save + { + /* + M_StartControlPanel(); + S_StartSound(NULL, sfx_swtchn); + M_SaveGame(0); + */ + // [STRIFE] (v1.2) - TODO: v1.31 + if(netgame || players[consoleplayer].health <= 0 || + players[consoleplayer].cheats & CF_ONFIRE) + { + S_StartSound(NULL, sfx_oof); + } + else + { + M_StartControlPanel(); + S_StartSound(NULL, sfx_swtchn); + M_SaveGame(0); + } + return true; + } + else if (key == key_menu_load) // Load + { + /* + M_StartControlPanel(); + S_StartSound(NULL, sfx_swtchn); + M_LoadGame(0); + */ + // [STRIFE] (v1.2) - TODO: v1.31 + S_StartSound(NULL, sfx_swtchn); + M_QuickLoad(); + return true; + } + else if (key == key_menu_volume) // Sound Volume + { + M_StartControlPanel (); + currentMenu = &SoundDef; + itemOn = sfx_vol; + S_StartSound(NULL, sfx_swtchn); + return true; + } + else if (key == key_menu_detail) // Detail toggle + { + //M_ChangeDetail(0); + M_AutoUseHealth(); // [STRIFE] + S_StartSound(NULL,sfx_swtchn); + return true; + } + // STRIFE-TODO: autouse health toggle + else if (key == key_menu_qsave) // Quicksave + { + //S_StartSound(NULL, sfx_swtchn); + //M_QuickSave(); + // [STRIFE] (v1.2) - TODO: v1.31 + if(netgame || players[consoleplayer].health <= 0 || + players[consoleplayer].cheats & CF_ONFIRE) + { + S_StartSound(NULL, sfx_oof); + } + else + { + S_StartSound(NULL, sfx_swtchn); + M_QuickSave(); + } + return true; + } + else if (key == key_menu_endgame) // End game + { + S_StartSound(NULL, sfx_swtchn); + M_EndGame(0); + return true; + } + else if (key == key_menu_messages) // Toggle messages + { + //M_ChangeMessages(0); + M_ChangeShowText(); // [STRIFE] + S_StartSound(NULL, sfx_swtchn); + return true; + } + else if (key == key_menu_qload) // Quickload + { + // [STRIFE] + // * v1.2: takes a screenshot + // * v1.31: does quickload again... (STRIFE-TODO) + /* + S_StartSound(NULL, sfx_swtchn); + M_QuickLoad(); + */ + G_ScreenShot(); + return true; + } + else if (key == key_menu_quit) // Quit DOOM + { + S_StartSound(NULL, sfx_swtchn); + M_QuitStrife(0); + return true; + } + else if (key == key_menu_gamma) // gamma toggle + { + usegamma++; + if (usegamma > 4) + usegamma = 0; + players[consoleplayer].message = DEH_String(gammamsg[usegamma]); + I_SetPalette (W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE)); + return true; + } + } + + // Pop-up menu? + if (!menuactive) + { + if (key == key_menu_activate) + { + M_StartControlPanel (); + S_StartSound(NULL, sfx_swtchn); + return true; + } + return false; + } + + + // Keys usable within menu + + if (key == key_menu_down) + { + // Move down to next item + + do + { + if (itemOn+1 > currentMenu->numitems-1) + itemOn = 0; + else itemOn++; + S_StartSound(NULL, sfx_pstop); + } while(currentMenu->menuitems[itemOn].status==-1); + + return true; + } + else if (key == key_menu_up) + { + // Move back up to previous item + + do + { + if (!itemOn) + itemOn = currentMenu->numitems-1; + else itemOn--; + S_StartSound(NULL, sfx_pstop); + } while(currentMenu->menuitems[itemOn].status==-1); + + return true; + } + else if (key == key_menu_left) + { + // Slide slider left + + if (currentMenu->menuitems[itemOn].routine && + currentMenu->menuitems[itemOn].status == 2) + { + S_StartSound(NULL, sfx_stnmov); + currentMenu->menuitems[itemOn].routine(0); + } + return true; + } + else if (key == key_menu_right) + { + // Slide slider right + + if (currentMenu->menuitems[itemOn].routine && + currentMenu->menuitems[itemOn].status == 2) + { + S_StartSound(NULL, sfx_stnmov); + currentMenu->menuitems[itemOn].routine(1); + } + return true; + } + else if (key == key_menu_forward) + { + // Activate menu item + + 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_swish); [STRIFE] No sound is played here. + } + } + return true; + } + else if (key == key_menu_activate) + { + // Deactivate menu + if(menuindialog) // [STRIFE] - Get out of dialog engine semi-gracefully + P_DialogDoChoice(-1); + + currentMenu->lastOn = itemOn; + M_ClearMenus (0); + S_StartSound(NULL, sfx_mtalht); // villsa [STRIFE] TODO - fix sounds + return true; + } + else if (key == key_menu_back) + { + // Go back to previous menu + + currentMenu->lastOn = itemOn; + if (currentMenu->prevMenu) + { + currentMenu = currentMenu->prevMenu; + itemOn = currentMenu->lastOn; + S_StartSound(NULL, sfx_swtchn); + } + return true; + } + else if (ch != 0) + { + // Keyboard shortcut? + + 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; + } + } + } + + return false; +} + + + +// +// M_StartControlPanel +// +void M_StartControlPanel (void) +{ + // intro might call this repeatedly + if (menuactive) + return; + + menuactive = 1; + menupause = true; + 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 int i; + unsigned int max; + char string[80]; + char *name; + int start; + + inhelpscreens = false; + + // Horiz. & Vertically center string and print it. + if (messageToPrint) + { + start = 0; + y = 100 - M_StringHeight(messageString) / 2; + while (messageString[start] != '\0') + { + int foundnewline = 0; + + for (i = 0; i < strlen(messageString + start); i++) + if (messageString[start + i] == '\n') + { + memset(string, 0, sizeof(string)); + strncpy(string, messageString + start, i); + foundnewline = 1; + start += i + 1; + break; + } + + if (!foundnewline) + { + strcpy(string, messageString + start); + start += strlen(string); + } + + 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++) + { + name = DEH_String(currentMenu->menuitems[i].name); + + if (name[0]) + { + V_DrawPatchDirect (x, y, W_CacheLumpName(name, PU_CACHE)); + } + y += LINEHEIGHT; + } + + + // haleyjd 08/27/10: [STRIFE] Adjust to draw spinning Sigil + // DRAW SIGIL + V_DrawPatchDirect(x + CURSORXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT, + W_CacheLumpName(DEH_String(cursorName[whichCursor]), + PU_CACHE)); + +} + + +// +// M_ClearMenus +// +// haleyjd 08/28/10: [STRIFE] Added an int param so this can be called by menus. +// 09/08/10: Added menupause. +// +void M_ClearMenus (int choice) +{ + choice = 0; // haleyjd: for no warning; not from decompilation. + menuactive = 0; + menupause = 0; +} + + + + +// +// M_SetupNextMenu +// +void M_SetupNextMenu(menu_t *menudef) +{ + currentMenu = menudef; + itemOn = currentMenu->lastOn; +} + + +// +// M_Ticker +// +// haleyjd 08/27/10: [STRIFE] Rewritten for Sigil cursor +// +void M_Ticker (void) +{ + if (--cursorAnimCounter <= 0) + { + whichCursor = (whichCursor + 1) % 8; + cursorAnimCounter = 5; + } +} + + +// +// M_Init +// +// haleyjd 08/27/10: [STRIFE] Removed DOOM gamemode stuff +// +void M_Init (void) +{ + currentMenu = &MainDef; + menuactive = 0; + itemOn = currentMenu->lastOn; + whichCursor = 0; + cursorAnimCounter = 10; + screenSize = screenblocks - 3; + messageToPrint = 0; + messageString = NULL; + messageLastMenuActive = menuactive; // STRIFE-FIXME: assigns 0 here... + quickSaveSlot = -1; + + // [STRIFE]: Initialize savegame paths and clear temporary directory + G_WriteSaveName(5, "ME"); + ClearTmp(); + + // Here we could catch other version dependencies, + // like HELP1/2, and four episodes. +} + |