summaryrefslogtreecommitdiff
path: root/src/strife/m_menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/strife/m_menu.c')
-rw-r--r--src/strife/m_menu.c2330
1 files changed, 2330 insertions, 0 deletions
diff --git a/src/strife/m_menu.c b/src/strife/m_menu.c
new file mode 100644
index 00000000..2fa63abc
--- /dev/null
+++ b/src/strife/m_menu.c
@@ -0,0 +1,2330 @@
+// 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;
+
+ // In testcontrols mode, none of the function keys should do anything
+ // - the only key is escape to quit.
+
+ if (testcontrols)
+ {
+ if (ev->type == ev_quit
+ || (ev->type == ev_keydown
+ && (ev->data1 == key_menu_activate || ev->data1 == key_menu_quit)))
+ {
+ I_Quit();
+ return true;
+ }
+
+ return false;
+ }
+
+ // "close" button pressed on window?
+ if (ev->type == ev_quit)
+ {
+ // First click on close button = bring up quit confirm message.
+ // Second click on close button = confirm quit
+
+ if (menuactive && messageToPrint && messageRoutine == M_QuitResponse)
+ {
+ M_QuitResponse(key_menu_confirm);
+ }
+ else
+ {
+ 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;
+
+ // 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.
+}
+