#include "quakedef.h"#include "colormatrix.h" enum { MAIN_ITEMS = 5, SINGLEPLAYER_ITEMS = 3, MULTIPLAYER_ITEMS = 3, NUM_SETUP_CMDS = 5, OPTIONS_ITEMS = 12, SLIDER_RANGE = 10, NUM_HELP_PAGES = 6, NUM_LANCONFIG_CMDS = 2, NUM_GAMEOPTIONS = 9,}; char savs[Nsav][Nsavcm];int savcanld[Nsav];int m_return_state;bool m_return_onerror;char m_return_reason[32]; static int m_save_demonum;static byte identityTable[256];static byte translationTable[256]; static int m_main_cursor;static int m_singleplayer_cursor;static int load_cursor; // 0 < load_cursor < Nsavstatic int m_multiplayer_cursor;static int setup_cursor = 4;static int setup_cursor_table[] = {40, 56, 80, 104, 140};static char setup_hostname[16];static char setup_myname[16];static int setup_oldtop;static int setup_oldbottom;static int setup_top;static int setup_bottom;static bool m_entersound; // play after drawing a frame, so caching won't disrupt the soundstatic bool m_recursiveDraw;static int options_cursor;static int help_page;static int msgNumber;static int m_quit_prevstate;static bool wasInMenus;static int lanConfig_cursor = -1;static int lanConfig_cursor_table[] = {72, 92};static char lanConfig_portname[8];static char lanConfig_joinname[22];static int startepisode;static int startlevel;static int maxplayers;static bool m_serverInfoMessage = false;static double m_serverInfoMessageTime;static int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 112, 120};static int gameoptions_cursor;static int keys_cursor;static int bind_grab; #define StartingGame (m_multiplayer_cursor == 1)#define JoiningGame (m_multiplayer_cursor == 0) enum { m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_options, m_keys, m_help, m_quit, m_lanconfig, m_gameoptions,} m_state; void M_Menu_Main_f(cmd_t *c);static void M_Menu_SinglePlayer_f(cmd_t *c);static void M_Menu_Load_f(cmd_t *c);static void M_Menu_Save_f(cmd_t *c);static void M_Menu_MultiPlayer_f(cmd_t *c);static void M_Menu_Setup_f(cmd_t *c);static void M_Menu_Options_f(cmd_t *c);static void M_Menu_Keys_f(cmd_t *c);static void M_Menu_Help_f(cmd_t *c);void M_Menu_Quit_f(cmd_t *c);static void M_Menu_LanConfig_f(cmd_t *c);static void M_Menu_GameOptions_f(cmd_t *c); static void M_Main_Draw(void);static void M_SinglePlayer_Draw(void);static void M_Load_Draw(void);static void M_Save_Draw(void);static void M_MultiPlayer_Draw(void);static void M_Setup_Draw(void);static void M_Options_Draw(void);static void M_Keys_Draw(void);static void M_Help_Draw(void);static void M_Quit_Draw(void);static void M_LanConfig_Draw(void);static void M_GameOptions_Draw(void); static void M_Main_Key(int key);static void M_SinglePlayer_Key(int key);static void M_Load_Key(int key);static void M_Save_Key(int key);static void M_MultiPlayer_Key(int key);static void M_Setup_Key(int key);static void M_Options_Key(int key);static void M_Keys_Key(int key);static void M_Help_Key(int key);static void M_Quit_Key(int key);static void M_LanConfig_Key(int key);static void M_GameOptions_Key(int key); /* Draws one solid graphics character */static voidM_DrawCharacter(int cx, int line, int num){ Draw_Character(cx + ((vid.width - 320) >> 1), line, num);} static voidM_Print(int cx, int cy, const char *str){ while(*str) { M_DrawCharacter(cx, cy, (*str) + 128); str++; cx += 8; }} static voidM_PrintWhite(int cx, int cy, const char *str){ while(*str) { M_DrawCharacter(cx, cy, *str); str++; cx += 8; }} static voidM_DrawTransPic(int x, int y, qpic_t *pic){ Draw_TransPic(x + ((vid.width - 320) >> 1), y, pic);} static voidM_BuildTranslationTable(int top, int bottom){ int j; byte *dest, *source; for(j = 0; j < 256; j++) identityTable[j] = j; dest = translationTable; source = identityTable; memmove(dest, source, 256); if(top < 128) // the artists made some backwards ranges. sigh. memmove(dest + TOP_RANGE, source + top, 16); else { for(j = 0; j < 16; j++) dest[TOP_RANGE + j] = source[top + 15 - j]; } if(bottom < 128) memmove(dest + BOTTOM_RANGE, source + bottom, 16); else { for(j = 0; j < 16; j++) dest[BOTTOM_RANGE + j] = source[bottom + 15 - j]; }} static voidM_DrawTransPicTranslate(int x, int y, qpic_t *pic){ Draw_TransPicTranslate(x + ((vid.width - 320) >> 1), y, pic, translationTable);} static voidM_DrawTextBox(int x, int y, int width, int lines){ qpic_t *p; int cx, cy, n; // draw left side cx = x; cy = y; p = Draw_CachePic("gfx/box_tl.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_ml.lmp"); for(n = 0; n < lines; n++) { cy += 8; M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_bl.lmp"); M_DrawTransPic(cx, cy + 8, p); // draw middle cx += 8; while(width > 0) { cy = y; p = Draw_CachePic("gfx/box_tm.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_mm.lmp"); for(n = 0; n < lines; n++) { cy += 8; if(n == 1) p = Draw_CachePic("gfx/box_mm2.lmp"); M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_bm.lmp"); M_DrawTransPic(cx, cy + 8, p); width -= 2; cx += 16; } // draw right side cy = y; p = Draw_CachePic("gfx/box_tr.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_mr.lmp"); for(n = 0; n < lines; n++) { cy += 8; M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_br.lmp"); M_DrawTransPic(cx, cy + 8, p);} voidM_ToggleMenu_f(cmd_t *c){ USED(c); m_entersound = true; if(key_dest == key_menu) { if(m_state != m_main) { M_Menu_Main_f(nil); return; } key_dest = key_game; m_state = m_none; return; } if(key_dest == key_console) Con_ToggleConsole_f(nil); else { IN_Grabm(false); M_Menu_Main_f(nil); }} /* MAIN MENU */ voidM_Menu_Main_f(cmd_t *c){ USED(c); if(key_dest != key_menu) { m_save_demonum = cls.demonum; cls.demonum = -1; } key_dest = key_menu; m_state = m_main; m_entersound = true;} static voidM_Main_Draw(void){ int f; qpic_t *p; M_DrawTransPic(16, 4, Draw_CachePic("gfx/qplaque.lmp")); p = Draw_CachePic("gfx/ttl_main.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); M_DrawTransPic(72, 32, Draw_CachePic("gfx/mainmenu.lmp")); f = (int)(host_time * 10) % 6; M_DrawTransPic(54, 32 + m_main_cursor * 20, Draw_CachePic(va("gfx/menudot%d.lmp", f + 1)));} static voidM_Main_Key(int key){ switch(key) { case K_ESCAPE: key_dest = key_game; m_state = m_none; cls.demonum = m_save_demonum; if(cls.state != ca_connected && !cls.demoplayback && cls.demonum != -1) CL_NextDemo(); if(cls.state == ca_connected || cls.demoplayback) IN_Grabm(true); else Con_ToggleConsole_f(nil); break; case K_DOWNARROW: localsfx("misc/menu1.wav"); if(++m_main_cursor >= MAIN_ITEMS) m_main_cursor = 0; break; case K_UPARROW: localsfx("misc/menu1.wav"); if(--m_main_cursor < 0) m_main_cursor = MAIN_ITEMS - 1; break; case K_ENTER: m_entersound = true; switch(m_main_cursor) { case 0: M_Menu_SinglePlayer_f(nil); break; case 1: M_Menu_MultiPlayer_f(nil); break; case 2: M_Menu_Options_f(nil); break; case 3: M_Menu_Help_f(nil); break; case 4: M_Menu_Quit_f(nil); break; } }} /* SINGLE PLAYER MENU */ static voidM_Menu_SinglePlayer_f(cmd_t *c){ USED(c); key_dest = key_menu; m_state = m_singleplayer; m_entersound = true;} static voidM_SinglePlayer_Draw(void){ int f; qpic_t *p; M_DrawTransPic(16, 4, Draw_CachePic("gfx/qplaque.lmp")); p = Draw_CachePic("gfx/ttl_sgl.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); M_DrawTransPic(72, 32, Draw_CachePic("gfx/sp_menu.lmp")); f = (int)(host_time * 10) % 6; M_DrawTransPic( 54, 32 + m_singleplayer_cursor * 20, Draw_CachePic(va("gfx/menudot%d.lmp", f + 1)) );} static voidM_SinglePlayer_Key(int key){ switch(key) { case K_ESCAPE: M_Menu_Main_f(nil); break; case K_DOWNARROW: localsfx("misc/menu1.wav"); if(++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS) m_singleplayer_cursor = 0; break; case K_UPARROW: localsfx("misc/menu1.wav"); if(--m_singleplayer_cursor < 0) m_singleplayer_cursor = SINGLEPLAYER_ITEMS - 1; break; case K_ENTER: m_entersound = true; switch(m_singleplayer_cursor) { case 0: if(sv.active && !SCR_ModalMessage("Are you sure you want to\nstart a new game?\n")) break; key_dest = key_game; if(sv.active) Cbuf_AddText("disconnect\n"); Cbuf_AddText("maxplayers 1\n"); Cbuf_AddText("map start\n"); break; case 1: M_Menu_Load_f(nil); break; case 2: M_Menu_Save_f(nil); break; } }} /* LOAD/SAVE MENU */ static voidM_Menu_Load_f(cmd_t *c){ USED(c); m_entersound = true; m_state = m_load; key_dest = key_menu; savnames();} static voidM_Menu_Save_f(cmd_t *c){ USED(c); if(!sv.active) return; if(cl.intermission) return; if(svs.maxclients != 1) return; m_entersound = true; m_state = m_save; key_dest = key_menu; savnames();} static voidM_Load_Draw(void){ int i; qpic_t *p; p = Draw_CachePic("gfx/p_load.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); for(i = 0; i < Nsav; i++) M_Print(16, 32 + 8 * i, savs[i]); // line cursor M_DrawCharacter(8, 32 + load_cursor * 8, 12 + ((int)(realtime * 4) & 1));} static voidM_Save_Draw(void){ int i; qpic_t *p; p = Draw_CachePic("gfx/p_save.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); for(i = 0; i < Nsav; i++) M_Print(16, 32 + 8 * i, savs[i]); // line cursor M_DrawCharacter(8, 32 + load_cursor * 8, 12 + ((int)(realtime * 4) & 1));} static voidM_Load_Key(int k){ switch(k) { case K_ESCAPE: M_Menu_SinglePlayer_f(nil); break; case K_ENTER: localsfx("misc/menu2.wav"); if(!savcanld[load_cursor]) return; m_state = m_none; key_dest = key_game; // Host_Loadgame_f can't bring up the loading plaque because too much // stack space has been used, so do it now SCR_BeginLoadingPlaque(); // issue the load command Cbuf_AddText(va("load s%d\n", load_cursor)); return; case K_UPARROW: case K_LEFTARROW: localsfx("misc/menu1.wav"); load_cursor--; if(load_cursor < 0) load_cursor = Nsav - 1;Lines 1–500 of 1985. Load more
#include "quakedef.h" #include "colormatrix.h" enum { MAIN_ITEMS = 5, SINGLEPLAYER_ITEMS = 3, MULTIPLAYER_ITEMS = 3, NUM_SETUP_CMDS = 5, OPTIONS_ITEMS = 12, SLIDER_RANGE = 10, NUM_HELP_PAGES = 6, NUM_LANCONFIG_CMDS = 2, NUM_GAMEOPTIONS = 9, }; char savs[Nsav][Nsavcm]; int savcanld[Nsav]; int m_return_state; bool m_return_onerror; char m_return_reason[32]; static int m_save_demonum; static byte identityTable[256]; static byte translationTable[256]; static int m_main_cursor; static int m_singleplayer_cursor; static int load_cursor; // 0 < load_cursor < Nsav static int m_multiplayer_cursor; static int setup_cursor = 4; static int setup_cursor_table[] = {40, 56, 80, 104, 140}; static char setup_hostname[16]; static char setup_myname[16]; static int setup_oldtop; static int setup_oldbottom; static int setup_top; static int setup_bottom; static bool m_entersound; // play after drawing a frame, so caching won't disrupt the sound static bool m_recursiveDraw; static int options_cursor; static int help_page; static int msgNumber; static int m_quit_prevstate; static bool wasInMenus; static int lanConfig_cursor = -1; static int lanConfig_cursor_table[] = {72, 92}; static char lanConfig_portname[8]; static char lanConfig_joinname[22]; static int startepisode; static int startlevel; static int maxplayers; static bool m_serverInfoMessage = false; static double m_serverInfoMessageTime; static int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 112, 120}; static int gameoptions_cursor; static int keys_cursor; static int bind_grab; #define StartingGame (m_multiplayer_cursor == 1) #define JoiningGame (m_multiplayer_cursor == 0) enum { m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_options, m_keys, m_help, m_quit, m_lanconfig, m_gameoptions, } m_state; void M_Menu_Main_f(cmd_t *c); static void M_Menu_SinglePlayer_f(cmd_t *c); static void M_Menu_Load_f(cmd_t *c); static void M_Menu_Save_f(cmd_t *c); static void M_Menu_MultiPlayer_f(cmd_t *c); static void M_Menu_Setup_f(cmd_t *c); static void M_Menu_Options_f(cmd_t *c); static void M_Menu_Keys_f(cmd_t *c); static void M_Menu_Help_f(cmd_t *c); void M_Menu_Quit_f(cmd_t *c); static void M_Menu_LanConfig_f(cmd_t *c); static void M_Menu_GameOptions_f(cmd_t *c); static void M_Main_Draw(void); static void M_SinglePlayer_Draw(void); static void M_Load_Draw(void); static void M_Save_Draw(void); static void M_MultiPlayer_Draw(void); static void M_Setup_Draw(void); static void M_Options_Draw(void); static void M_Keys_Draw(void); static void M_Help_Draw(void); static void M_Quit_Draw(void); static void M_LanConfig_Draw(void); static void M_GameOptions_Draw(void); static void M_Main_Key(int key); static void M_SinglePlayer_Key(int key); static void M_Load_Key(int key); static void M_Save_Key(int key); static void M_MultiPlayer_Key(int key); static void M_Setup_Key(int key); static void M_Options_Key(int key); static void M_Keys_Key(int key); static void M_Help_Key(int key); static void M_Quit_Key(int key); static void M_LanConfig_Key(int key); static void M_GameOptions_Key(int key); /* Draws one solid graphics character */ static void M_DrawCharacter(int cx, int line, int num) { Draw_Character(cx + ((vid.width - 320) >> 1), line, num); } static void M_Print(int cx, int cy, const char *str) { while(*str) { M_DrawCharacter(cx, cy, (*str) + 128); str++; cx += 8; } } static void M_PrintWhite(int cx, int cy, const char *str) { while(*str) { M_DrawCharacter(cx, cy, *str); str++; cx += 8; } } static void M_DrawTransPic(int x, int y, qpic_t *pic) { Draw_TransPic(x + ((vid.width - 320) >> 1), y, pic); } static void M_BuildTranslationTable(int top, int bottom) { int j; byte *dest, *source; for(j = 0; j < 256; j++) identityTable[j] = j; dest = translationTable; source = identityTable; memmove(dest, source, 256); if(top < 128) // the artists made some backwards ranges. sigh. memmove(dest + TOP_RANGE, source + top, 16); else { for(j = 0; j < 16; j++) dest[TOP_RANGE + j] = source[top + 15 - j]; } if(bottom < 128) memmove(dest + BOTTOM_RANGE, source + bottom, 16); else { for(j = 0; j < 16; j++) dest[BOTTOM_RANGE + j] = source[bottom + 15 - j]; } } static void M_DrawTransPicTranslate(int x, int y, qpic_t *pic) { Draw_TransPicTranslate(x + ((vid.width - 320) >> 1), y, pic, translationTable); } static void M_DrawTextBox(int x, int y, int width, int lines) { qpic_t *p; int cx, cy, n; // draw left side cx = x; cy = y; p = Draw_CachePic("gfx/box_tl.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_ml.lmp"); for(n = 0; n < lines; n++) { cy += 8; M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_bl.lmp"); M_DrawTransPic(cx, cy + 8, p); // draw middle cx += 8; while(width > 0) { cy = y; p = Draw_CachePic("gfx/box_tm.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_mm.lmp"); for(n = 0; n < lines; n++) { cy += 8; if(n == 1) p = Draw_CachePic("gfx/box_mm2.lmp"); M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_bm.lmp"); M_DrawTransPic(cx, cy + 8, p); width -= 2; cx += 16; } // draw right side cy = y; p = Draw_CachePic("gfx/box_tr.lmp"); M_DrawTransPic(cx, cy, p); p = Draw_CachePic("gfx/box_mr.lmp"); for(n = 0; n < lines; n++) { cy += 8; M_DrawTransPic(cx, cy, p); } p = Draw_CachePic("gfx/box_br.lmp"); M_DrawTransPic(cx, cy + 8, p); } void M_ToggleMenu_f(cmd_t *c) { USED(c); m_entersound = true; if(key_dest == key_menu) { if(m_state != m_main) { M_Menu_Main_f(nil); return; } key_dest = key_game; m_state = m_none; return; } if(key_dest == key_console) Con_ToggleConsole_f(nil); else { IN_Grabm(false); M_Menu_Main_f(nil); } } /* MAIN MENU */ void M_Menu_Main_f(cmd_t *c) { USED(c); if(key_dest != key_menu) { m_save_demonum = cls.demonum; cls.demonum = -1; } key_dest = key_menu; m_state = m_main; m_entersound = true; } static void M_Main_Draw(void) { int f; qpic_t *p; M_DrawTransPic(16, 4, Draw_CachePic("gfx/qplaque.lmp")); p = Draw_CachePic("gfx/ttl_main.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); M_DrawTransPic(72, 32, Draw_CachePic("gfx/mainmenu.lmp")); f = (int)(host_time * 10) % 6; M_DrawTransPic(54, 32 + m_main_cursor * 20, Draw_CachePic(va("gfx/menudot%d.lmp", f + 1))); } static void M_Main_Key(int key) { switch(key) { case K_ESCAPE: key_dest = key_game; m_state = m_none; cls.demonum = m_save_demonum; if(cls.state != ca_connected && !cls.demoplayback && cls.demonum != -1) CL_NextDemo(); if(cls.state == ca_connected || cls.demoplayback) IN_Grabm(true); else Con_ToggleConsole_f(nil); break; case K_DOWNARROW: localsfx("misc/menu1.wav"); if(++m_main_cursor >= MAIN_ITEMS) m_main_cursor = 0; break; case K_UPARROW: localsfx("misc/menu1.wav"); if(--m_main_cursor < 0) m_main_cursor = MAIN_ITEMS - 1; break; case K_ENTER: m_entersound = true; switch(m_main_cursor) { case 0: M_Menu_SinglePlayer_f(nil); break; case 1: M_Menu_MultiPlayer_f(nil); break; case 2: M_Menu_Options_f(nil); break; case 3: M_Menu_Help_f(nil); break; case 4: M_Menu_Quit_f(nil); break; } } } /* SINGLE PLAYER MENU */ static void M_Menu_SinglePlayer_f(cmd_t *c) { USED(c); key_dest = key_menu; m_state = m_singleplayer; m_entersound = true; } static void M_SinglePlayer_Draw(void) { int f; qpic_t *p; M_DrawTransPic(16, 4, Draw_CachePic("gfx/qplaque.lmp")); p = Draw_CachePic("gfx/ttl_sgl.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); M_DrawTransPic(72, 32, Draw_CachePic("gfx/sp_menu.lmp")); f = (int)(host_time * 10) % 6; M_DrawTransPic( 54, 32 + m_singleplayer_cursor * 20, Draw_CachePic(va("gfx/menudot%d.lmp", f + 1)) ); } static void M_SinglePlayer_Key(int key) { switch(key) { case K_ESCAPE: M_Menu_Main_f(nil); break; case K_DOWNARROW: localsfx("misc/menu1.wav"); if(++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS) m_singleplayer_cursor = 0; break; case K_UPARROW: localsfx("misc/menu1.wav"); if(--m_singleplayer_cursor < 0) m_singleplayer_cursor = SINGLEPLAYER_ITEMS - 1; break; case K_ENTER: m_entersound = true; switch(m_singleplayer_cursor) { case 0: if(sv.active && !SCR_ModalMessage("Are you sure you want to\nstart a new game?\n")) break; key_dest = key_game; if(sv.active) Cbuf_AddText("disconnect\n"); Cbuf_AddText("maxplayers 1\n"); Cbuf_AddText("map start\n"); break; case 1: M_Menu_Load_f(nil); break; case 2: M_Menu_Save_f(nil); break; } } } /* LOAD/SAVE MENU */ static void M_Menu_Load_f(cmd_t *c) { USED(c); m_entersound = true; m_state = m_load; key_dest = key_menu; savnames(); } static void M_Menu_Save_f(cmd_t *c) { USED(c); if(!sv.active) return; if(cl.intermission) return; if(svs.maxclients != 1) return; m_entersound = true; m_state = m_save; key_dest = key_menu; savnames(); } static void M_Load_Draw(void) { int i; qpic_t *p; p = Draw_CachePic("gfx/p_load.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); for(i = 0; i < Nsav; i++) M_Print(16, 32 + 8 * i, savs[i]); // line cursor M_DrawCharacter(8, 32 + load_cursor * 8, 12 + ((int)(realtime * 4) & 1)); } static void M_Save_Draw(void) { int i; qpic_t *p; p = Draw_CachePic("gfx/p_save.lmp"); M_DrawTransPic((320 - p->width) / 2, 4, p); for(i = 0; i < Nsav; i++) M_Print(16, 32 + 8 * i, savs[i]); // line cursor M_DrawCharacter(8, 32 + load_cursor * 8, 12 + ((int)(realtime * 4) & 1)); } static void M_Load_Key(int k) { switch(k) { case K_ESCAPE: M_Menu_SinglePlayer_f(nil); break; case K_ENTER: localsfx("misc/menu2.wav"); if(!savcanld[load_cursor]) return; m_state = m_none; key_dest = key_game; // Host_Loadgame_f can't bring up the loading plaque because too much // stack space has been used, so do it now SCR_BeginLoadingPlaque(); // issue the load command Cbuf_AddText(va("load s%d\n", load_cursor)); return; case K_UPARROW: case K_LEFTARROW: localsfx("misc/menu1.wav"); load_cursor--; if(load_cursor < 0) load_cursor = Nsav - 1;