From a23197cf8d332cfe802a1f22e4dbdafbcf300526 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 15 Mar 2025 03:54:17 +0100 Subject: [PATCH 01/33] god i hate cvars --- src/command.c | 14 +++++++++++++- src/console.c | 38 +++++++++++++++++++------------------- src/console.h | 1 + src/d_main.cpp | 34 ++++++++++++++++++++-------------- src/hardware/hw_main.c | 3 ++- src/screen.c | 3 --- src/sdl/i_system.cpp | 2 +- src/sdl/i_video.cpp | 21 ++++++++++++++------- src/v_video.c | 40 ++++++++++++++++++++-------------------- 9 files changed, 90 insertions(+), 66 deletions(-) diff --git a/src/command.c b/src/command.c index 133bcfd69..a6f14c9a8 100644 --- a/src/command.c +++ b/src/command.c @@ -1624,7 +1624,19 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) const char *overridestr = valstr; - if (CV_CompleteValue(var, &overridestr, &overrideval)) + if (mainwads == 0 && var->PossibleValue == Color_cons_t) + { + override = true; + if (!strcmp(valstr, "Blue")) + overrideval = SKINCOLOR_BLUE; + else if (!strcmp(valstr, "Orange")) + overrideval = SKINCOLOR_ORANGE; + else if (!strcmp(valstr, "Red")) + overrideval = SKINCOLOR_RED; + else + I_Error("Sorry, you need to add %s to the list of skincolors in Setvalue", valstr); + } + else if (CV_CompleteValue(var, &overridestr, &overrideval)) { if (overridestr) { diff --git a/src/console.c b/src/console.c index aa95975f0..613eb4353 100644 --- a/src/console.c +++ b/src/console.c @@ -153,7 +153,7 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, { {15,"Periwinkle"}, {16,"Blue"}, {17,"Purple"}, {18,"Lavender"}, {0, NULL}}; -consvar_t cons_backcolor = CVAR_INIT ("con_backcolor", "Black", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change); +consvar_t cons_backcolor = CVAR_INIT ("con_backcolor", "Black", CV_CALL|CV_NOINIT|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change); static CV_PossibleValue_t menuhighlight_cons_t[] = { @@ -461,38 +461,38 @@ void CON_Init(void) con_destlines = vid.height; con_curlines = vid.height; - Unlock_state(); - if (!dedicated) { - Lock_state(); con_started = true; con_startup = true; consoletoggle = false; - - Unlock_state(); - - CV_RegisterVar(&cons_msgtimeout); - CV_RegisterVar(&cons_hudlines); - CV_RegisterVar(&cons_speed); - CV_RegisterVar(&cons_height); - CV_RegisterVar(&cons_backpic); - CV_RegisterVar(&cons_backcolor); - CV_RegisterVar(&cons_menuhighlight); - COM_AddCommand("bind", CONS_Bind_f); } else { - Lock_state(); - con_started = true; con_startup = false; consoletoggle = true; - - Unlock_state(); } + + Unlock_state(); } + +void CON_Register(void) +{ + if (dedicated) + return; + + CV_RegisterVar(&cons_msgtimeout); + CV_RegisterVar(&cons_hudlines); + CV_RegisterVar(&cons_speed); + CV_RegisterVar(&cons_height); + CV_RegisterVar(&cons_backpic); + CV_RegisterVar(&cons_backcolor); + CV_RegisterVar(&cons_menuhighlight); + COM_AddCommand("bind", CONS_Bind_f); +} + // Console input initialization // static void CON_InputInit(void) diff --git a/src/console.h b/src/console.h index 496c3418d..c32430576 100644 --- a/src/console.h +++ b/src/console.h @@ -22,6 +22,7 @@ extern "C" { #endif void CON_Init(void); +void CON_Register(void); boolean CON_Responder(event_t *ev); diff --git a/src/d_main.cpp b/src/d_main.cpp index 686d18bd1..ef7152a6c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1472,6 +1472,26 @@ void D_SRB2Main(void) // Have to be done here before files are loaded M_InitCharacterTables(); + D_RegisterServerCommands(); + D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame + R_RegisterEngineStuff(); + S_RegisterSoundStuff(); + CON_Register(); + if (!dedicated) + { + CV_RegisterVar(&cv_ticrate); + CV_RegisterVar(&cv_constextsize); + } + + I_RegisterSysCommands(); + +#ifdef HWRENDER + // Lactozilla: Add every hardware mode CVAR and CCMD. + // Has to be done before the configuration file loads, + // ~~but after the OpenGL library loads.~~ G: no lol + HWR_AddCommands(); +#endif + // load wad, including the main wad file CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); W_InitMultipleFiles(startupiwads, false); @@ -1535,13 +1555,6 @@ void D_SRB2Main(void) CONS_Printf("I_StartupGraphics()...\n"); I_StartupGraphics(); -#ifdef HWRENDER - // Lactozilla: Add every hardware mode CVAR and CCMD. - // Has to be done before the configuration file loads, - // but after the OpenGL library loads. - HWR_AddCommands(); -#endif - //--------------------------------------------------------- CONSOLE // setup loading screen SCR_Startup(); @@ -1561,13 +1574,6 @@ void D_SRB2Main(void) timelimits[GT_BATTLE] = 2; - D_RegisterServerCommands(); - D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame - R_RegisterEngineStuff(); - S_RegisterSoundStuff(); - - I_RegisterSysCommands(); - CON_SetLoadingProgress(LOADED_HUINIT); CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n"); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c4e39fddd..3e14d75c2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6367,13 +6367,14 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glbatching); + + CV_RegisterVar(&cv_glanisotropicmode); } void HWR_AddSessionCommands(void) { if (gl_sessioncommandsadded) return; - CV_RegisterVar(&cv_glanisotropicmode); gl_sessioncommandsadded = true; } diff --git a/src/screen.c b/src/screen.c index ddc9f5af0..01ff1559e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -349,9 +349,6 @@ void SCR_Startup(void) V_Init(); V_Recalc(); - CV_RegisterVar(&cv_ticrate); - CV_RegisterVar(&cv_constextsize); - V_SetPalette(0); } diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index fce0ee9d9..6a91f94c8 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -2688,6 +2688,6 @@ UINT32 I_GetFreeMem(UINT32 *total) } // note CPUAFFINITY code used to reside here -void I_RegisterSysCommands(void) {} +//void I_RegisterSysCommands(void) {} #endif // HAVE_SDL diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 12b858db9..0db299e36 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1779,6 +1779,20 @@ static void Impl_VideoSetupBuffer(void) } } +void I_RegisterSysCommands(void) +{ + if (dedicated || graphics_started) + return; + + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); + COM_AddCommand ("vid_info", VID_Command_Info_f); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); + COM_AddCommand ("vid_mode", VID_Command_Mode_f); + CV_RegisterVar (&cv_vidwait); + CV_RegisterVar (&cv_stretch); + CV_RegisterVar (&cv_alwaysgrabmouse); +} + void I_StartupGraphics(void) { if (dedicated) @@ -1789,13 +1803,6 @@ void I_StartupGraphics(void) if (graphics_started) return; - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand ("vid_mode", VID_Command_Mode_f); - CV_RegisterVar (&cv_vidwait); - CV_RegisterVar (&cv_stretch); - CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = static_cast(M_CheckParm("-nomouse")); disable_fullscreen = M_CheckParm("-win") ? SDL_TRUE : SDL_FALSE; diff --git a/src/v_video.c b/src/v_video.c index c0e079a40..e2c7785f6 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -54,34 +54,34 @@ consvar_t cv_ticrate = CVAR_INIT ("showfps", "No", CV_SAVE, CV_YesNo, NULL); static void CV_palette_OnChange(void); static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {5, "MAX"}, {0, NULL}}; -consvar_t cv_globalgamma = CVAR_INIT ("gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_globalgamma = CVAR_INIT ("gamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; -consvar_t cv_globalsaturation = CVAR_INIT ("saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_globalsaturation = CVAR_INIT ("saturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); #define huecoloursteps 4 static CV_PossibleValue_t hue_cons_t[] = {{0, "MIN"}, {(huecoloursteps*6)-1, "MAX"}, {0, NULL}}; -consvar_t cv_rhue = CVAR_INIT ("rhue", "0", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); -consvar_t cv_yhue = CVAR_INIT ("yhue", "4", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); -consvar_t cv_ghue = CVAR_INIT ("ghue", "8", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); -consvar_t cv_chue = CVAR_INIT ("chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); -consvar_t cv_bhue = CVAR_INIT ("bhue", "16", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); -consvar_t cv_mhue = CVAR_INIT ("mhue", "20", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange); +consvar_t cv_rhue = CVAR_INIT ("rhue", "0", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); +consvar_t cv_yhue = CVAR_INIT ("yhue", "4", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); +consvar_t cv_ghue = CVAR_INIT ("ghue", "8", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); +consvar_t cv_chue = CVAR_INIT ("chue", "12", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); +consvar_t cv_bhue = CVAR_INIT ("bhue", "16", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); +consvar_t cv_mhue = CVAR_INIT ("mhue", "20", CV_SAVE|CV_CALL|CV_NOINIT, hue_cons_t, CV_palette_OnChange); -consvar_t cv_rgamma = CVAR_INIT ("rgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_ygamma = CVAR_INIT ("ygamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_ggamma = CVAR_INIT ("ggamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_cgamma = CVAR_INIT ("cgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_bgamma = CVAR_INIT ("bgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_mgamma = CVAR_INIT ("mgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_rgamma = CVAR_INIT ("rgamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_ygamma = CVAR_INIT ("ygamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_ggamma = CVAR_INIT ("ggamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_cgamma = CVAR_INIT ("cgamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_bgamma = CVAR_INIT ("bgamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); +consvar_t cv_mgamma = CVAR_INIT ("mgamma", "0", CV_SAVE|CV_CALL|CV_NOINIT, gamma_cons_t, CV_palette_OnChange); -consvar_t cv_rsaturation = CVAR_INIT ("rsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); -consvar_t cv_ysaturation = CVAR_INIT ("ysaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); -consvar_t cv_gsaturation = CVAR_INIT ("gsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); -consvar_t cv_csaturation = CVAR_INIT ("csaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); -consvar_t cv_bsaturation = CVAR_INIT ("bsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); -consvar_t cv_msaturation = CVAR_INIT ("msaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_rsaturation = CVAR_INIT ("rsaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_ysaturation = CVAR_INIT ("ysaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_gsaturation = CVAR_INIT ("gsaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_csaturation = CVAR_INIT ("csaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_bsaturation = CVAR_INIT ("bsaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); +consvar_t cv_msaturation = CVAR_INIT ("msaturation", "10", CV_SAVE|CV_CALL|CV_NOINIT, saturation_cons_t, CV_palette_OnChange); static CV_PossibleValue_t constextsize_cons_t[] = { {V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"}, From 0e30c0c5eb55a1c2abe5f996c0a51d63e8826ac9 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 15 Mar 2025 04:03:44 +0100 Subject: [PATCH 02/33] SOC menus, part 1 --- src/deh_lua.c | 25 ++++- src/deh_soc.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++- src/deh_tables.c | 14 +++ src/deh_tables.h | 2 + src/m_menu.c | 38 +++++++- src/m_menu.h | 21 ++++- 6 files changed, 332 insertions(+), 7 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 887b48338..a9ffa3a82 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -197,6 +197,21 @@ static inline int lib_freeslot(lua_State *L) CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n"); } } + else if (fastcmp(type, "MN")) + { + menutype_t i; + for (i = 0; i < NUMMENUFREESLOTS; i++) + if (!FREE_MENUS[i]) { + CONS_Printf("Menu MN_%s allocated.\n",word); + FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); + strcpy(FREE_MENUS[i],word); + lua_pushinteger(L, MN_FIRSTFREESLOT + i); + r++; + break; + } + if (i == NUMMENUFREESLOTS) + CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n"); + } Z_Free(s); lua_remove(L, 1); continue; @@ -633,7 +648,15 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("MN_",word,3)) { p = word+3; - for (i = 0; i < NUMMENUTYPES; i++) + for (i = 0; i < NUMMENUFREESLOTS; i++) { + if (!FREE_MENUS[i]) + break; + if (fastcmp(p, FREE_MENUS[i])) { + CacheAndPushConstant(L, word, MN_FIRSTFREESLOT+i); + return 1; + } + } + for (i = 0; i < MN_FIRSTFREESLOT; i++) if (fastcmp(p, MENUTYPES_LIST[i])) { CacheAndPushConstant(L, word, i); return 1; diff --git a/src/deh_soc.c b/src/deh_soc.c index 783cc14e1..2a54dc1a2 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -534,6 +534,16 @@ void readfreeslots(MYFILE *f) } else deh_warning("Ran out of free PRECIP slots!\n"); } + else if (fastcmp(type, "MN")) + { + for (i = 0; i < NUMMENUFREESLOTS; i++) + if (!FREE_MENUS[i]) { + CONS_Printf("Menu MN_%s allocated.\n",word); + FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); + strcpy(FREE_MENUS[i],word); + break; + } + } else deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word); } @@ -2135,6 +2145,150 @@ void readtextprompt(MYFILE *f, INT32 num) Z_Free(s); } +static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word = s; + char *word2; + char *tmp; + + menuitem_t *menuitem = menudef->menuitems + menudef->numitems; + (void)itemname; // menuitem->itemname = Z_StrDup(itemname); + boolean actionset = false; + boolean textset = false; + + // taking quite possibly the only opportunity i'll ever get + // to avoid three tabs of indentation... + do if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + // First remove trailing newline, if there is one + tmp = strchr(s, '\n'); + if (tmp) + *tmp = '\0'; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + // Get the part before the " = " + tmp = strchr(s, '='); + if (tmp) + *(tmp-1) = '\0'; + else + break; + strupr(word); + + // Now get the part after + word2 = tmp += 2; + //strupr(word2); + + if (fastcmp(word, "PATCH")) + { + menuitem->patch = Z_StrDup(word2); + } + else if (fastncmp(word, "TEXT", 4)) + { + UINT16 flags = IT_STRING; + if (fastcmp(word+4, "HEADER")) + flags = IT_HEADER; + else if (fastcmp(word+4, "SECRET")) + flags = IT_SECRET; + else if (word[4]) + { + deh_warning("MenuItem %s: unknown word '%s'", "", word); + continue; + } + + if (textset) + { + deh_warning("MenuItem %s: text already set!", ""); + continue; + } + textset = true; + menuitem->status |= flags; + menuitem->text = Z_StrDup(word2); + } + else if (fastncmp(word, "CVAR", 4)) + { + UINT16 flags = IT_CVAR; + if (fastcmp(word+4, "SLIDER")) + flags |= IT_CV_SLIDER; + else if (fastcmp(word+4, "STRING")) + flags |= IT_CV_STRING; + else if (fastcmp(word+4, "INTEGER")) + flags |= IT_CV_INTEGERSTEP; + else if (word[4]) + { + deh_warning("MenuItem %s: unknown word '%s'", "", word); + continue; + } + + if (actionset) + { + deh_warning("MenuItem %s: action already set!", ""); + continue; + } + consvar_t *cvar = CV_FindVar(word2); + if (!cvar) + { + deh_warning("MenuItem %s: unable to find cvar '%s'", "", word2); + continue; + } + actionset = true; + menuitem->status |= flags; + menuitem->itemaction.cvar = cvar; + } + else if (fastcmp(word, "SUBMENU")) + { + if (actionset) + { + deh_warning("MenuItem %s: action already set!", ""); + continue; + } + menutype_t mn = get_menutype(word2); + if (mn == MN_NONE) + { + deh_warning("MenuItem %s: unknown menu '%s'", "", word2); + continue; + } + actionset = true; + menuitem->status |= IT_SUBMENU; + menuitem->itemaction.submenu = menunum2menudef[mn]; + } + else if (fastcmp(word, "CALL") || fastcmp(word, "KEYHANDLER")) + { + if (actionset) + { + deh_warning("MenuItem %s: action already set!", ""); + continue; + } + void (*routine)(INT32 choice) = NULL; // TODO + if (!routine) + { + deh_warning("MenuItem %s: unknown call routine '%s'", "", word2); + continue; + } + actionset = true; + menuitem->status |= word[0] == 'C' ? IT_CALL : IT_KEYHANDLER; + menuitem->itemaction.routine = routine; + } + else if (fastcmp(word, "ALPHAKEY") || fastcmp(word, "Y")) + { + menuitem->alphaKey = atoi(word2); + } + else + deh_warning("MenuItem %s: unknown word '%s'", "", word); + } + while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + void readmenu(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2142,6 +2296,20 @@ void readmenu(MYFILE *f, INT32 num) char *word2; char *tmp; INT32 value; + boolean space = false; + + menu_t *menudef = menunum2menudef[num]; + if (menudef == NULL) + { + deh_warning("No def for menu %d, that is certainly strange...", num); + return; + } + + //menuactive = false; + + memset(menudef, 0, sizeof(menu_t)); + menudef->menuid = num; + menudef->drawroutine = M_DrawGenericMenu; do { @@ -2161,12 +2329,21 @@ void readmenu(MYFILE *f, INT32 num) if (s == tmp) continue; // Skip comment lines, but don't break. + space = false; + // Get the part before the " = " tmp = strchr(s, '='); if (tmp) *(tmp-1) = '\0'; else - break; + { + space = true; + tmp = strchr(s, ' '); + if (tmp) + *tmp-- = '\0'; // decrement after, so word2 is correct + else + break; + } strupr(word); // Now get the part after @@ -2175,6 +2352,19 @@ void readmenu(MYFILE *f, INT32 num) value = atoi(word2); // used for numerical settings + if (space) + { + if (fastcmp(word, "MENUITEM")) + { + menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL); + readmenuitem(f, menudef, word2); + menudef->numitems++; + } + else + deh_warning("Menu %d: unknown word '%s'", num, word); + continue; + } + if (fastcmp(word, "BACKGROUNDNAME")) { strncpy(menupres[num].bgname, word2, 8); @@ -2315,6 +2505,45 @@ void readmenu(MYFILE *f, INT32 num) menupres[num].exitwipe = get_number(word2); titlechanged = true; } + // MENUDEF STARTS HERE + else if (fastcmp(word, "MENUTITLEPIC") || fastcmp(word, "TITLEPIC")) + { + menudef->menutitlepic = Z_StrDup(word2); + } + else if (fastcmp(word, "PREVMENU")) + { + value = get_menutype(word2); + if (value == MN_NONE) + { + deh_warning("Menu %d: unknown previous menu '%s'", num, word2); + continue; + } + menudef->prevMenu = menunum2menudef[value]; + } + else if (fastcmp(word, "DRAWROUTINE")) + { + { + deh_warning("Menu %d: unknown draw routine '%s'", num, word2); + continue; + } + } + else if (fastcmp(word, "X")) + { + menudef->x = value; + } + else if (fastcmp(word, "Y")) + { + menudef->y = value; + } + else if (fastcmp(word, "QUITROUTINE")) + { + { + deh_warning("Menu %d: unknown quit routine '%s'", num, word2); + continue; + } + } + else + deh_warning("Menu %d: unknown word '%s'", num, word); } } while (!myfeof(f)); // finish when the line is empty @@ -4061,7 +4290,13 @@ menutype_t get_menutype(const char *word) return atoi(word); if (fastncmp("MN_",word,3)) word += 3; // take off the MN_ - for (i = 0; i < NUMMENUTYPES; i++) + for (i = 0; i < NUMMENUFREESLOTS; i++) { + if (!FREE_MENUS[i]) + break; + if (fastcmp(word, FREE_MENUS[i])) + return MN_FIRSTFREESLOT+i; + } + for (i = 0; i < MN_FIRSTFREESLOT; i++) if (fastcmp(word, MENUTYPES_LIST[i])) return i; deh_warning("Couldn't find menutype named 'MN_%s'",word); diff --git a/src/deh_tables.c b/src/deh_tables.c index ddaa1fb03..dbb9098f0 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -33,6 +33,7 @@ char *FREE_STATES[NUMSTATEFREESLOTS]; char *FREE_MOBJS[NUMMOBJFREESLOTS]; char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; +char *FREE_MENUS[NUMMENUFREESLOTS]; UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. struct flickytypes_s FLICKYTYPES[] = { @@ -615,6 +616,8 @@ const char *const MENUTYPES_LIST[] = { "SP_NIGHTS_REPLAY", "SP_NIGHTS_GHOST", + "SP_MARATHON", + // Multiplayer "MP_MAIN", "MP_SPLITSCREEN", // SplitServer @@ -681,6 +684,17 @@ const char *const MENUTYPES_LIST[] = { // "MAPAUSE", // "HELP", + // SRB2Kart + "OP_HUD", + "OP_CHAT", + "OP_GAME", + "OP_BLANKARTGAME", + "OP_ADVANCEDSERVER", + "OP_CAMERA", + "OP_P3CAMERA", + "OP_P4CAMERA", + "MISC_REPLAY", + "SPECIAL" }; diff --git a/src/deh_tables.h b/src/deh_tables.h index 484cb281b..15923a6c0 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -16,6 +16,7 @@ #include "doomdef.h" // Constants #include "d_think.h" // actionf_t #include "info.h" // Mobj, state, sprite, etc constants +#include "m_menu.h" // NUMMENUFREESLOTS #include "lua_script.h" #ifdef __cplusplus @@ -27,6 +28,7 @@ extern "C" { extern char *FREE_STATES[NUMSTATEFREESLOTS]; extern char *FREE_MOBJS[NUMMOBJFREESLOTS]; extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; +extern char *FREE_MENUS[NUMMENUFREESLOTS]; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ diff --git a/src/m_menu.c b/src/m_menu.c index 4ade3ffc4..2bd418f26 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -203,6 +203,9 @@ static void M_HandleServerPage(INT32 choice); void M_SetWaitingMode(int mode); int M_GetWaitingMode(void); +// a single freeslot menu for testing +menu_t FreeslotTest; + // the haxor message menu menu_t MessageDef; @@ -359,7 +362,6 @@ static void M_PlaybackQuit(INT32 choice); static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked // Drawing functions -static void M_DrawGenericMenu(void); static void M_DrawGenericBackgroundMenu(void); static void M_DrawCenteredMenu(void); static void M_DrawAddons(void); @@ -410,6 +412,33 @@ static void Dummymenuplayer_OnChange(void); //static void Dummymares_OnChange(void); static void Dummystaff_OnChange(void); +// temporary measure until menu_t and menupres_t are merged (hopefully) +menu_t *menunum2menudef[NUMMENUTYPES] = { + [MN_OP_CAMERA] = &OP_CamOptionsDef, + [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, + [MN_OP_P2CAMERA] = &OP_Player2CamOptionsDef, + [MN_OP_P3CAMERA] = &OP_Player3CamOptionsDef, + [MN_OP_P4CAMERA] = &OP_Player4CamOptionsDef, + + [MN_OP_MAIN] = &OP_MainDef, + [MN_OP_CHANGECONTROLS] = &OP_ControlsDef, + [MN_OP_VIDEO] = &OP_VideoOptionsDef, + [MN_OP_OPENGL] = &OP_OpenGLOptionsDef, + [MN_OP_SOUND] = &OP_SoundOptionsDef, + [MN_OP_CHAT] = &OP_ChatOptionsDef, + [MN_OP_HUD] = &OP_HUDOptionsDef, + [MN_OP_GAME] = &OP_GameOptionsDef, + [MN_OP_BLANKARTGAME] = &OP_BlanKartGameOptionsDef, + [MN_OP_SERVER] = &OP_ServerOptionsDef, + [MN_OP_ADVANCEDSERVER] = &OP_AdvServerOptionsDef, + [MN_OP_MONITORTOGGLE] = &OP_MonitorToggleDef, + [MN_OP_DATA] = &OP_DataOptionsDef, + [MN_OP_ERASEDATA] = &OP_EraseDataDef, + [MN_MISC_REPLAY] = &MISC_ReplayOptionsDef, + + [MN_FIRSTFREESLOT] = &FreeslotTest, +}; + // ========================================================================== // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== @@ -3003,7 +3032,10 @@ boolean M_Responder(event_t *ev) break; case IT_SUBMENU: currentMenu->lastOn = itemOn; - M_SetupNextMenu((menu_t *)currentMenu->menuitems[itemOn].itemaction.submenu); + if ((menu_t *)(currentMenu->menuitems[itemOn].itemaction.submenu)->menuitems == NULL) + CONS_Alert(CONS_WARNING, "Submenu is empty!\n"); + else + M_SetupNextMenu((menu_t *)currentMenu->menuitems[itemOn].itemaction.submenu); break; } } @@ -3919,7 +3951,7 @@ static void M_DrawMenuTitle(void) } } -static void M_DrawGenericMenu(void) +void M_DrawGenericMenu(void) { INT32 x, y, w, i, cursory = 0; diff --git a/src/m_menu.h b/src/m_menu.h index f652c5345..f9d1e8875 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -138,13 +138,30 @@ typedef enum // MN_MAPAUSE, // MN_HELP, + // SRB2Kart + MN_OP_HUD, + MN_OP_CHAT, + MN_OP_GAME, + MN_OP_BLANKARTGAME, + MN_OP_ADVANCEDSERVER, + MN_OP_CAMERA, + MN_OP_P3CAMERA, + MN_OP_P4CAMERA, + MN_MISC_REPLAY, + MN_SPECIAL, + + MN_FIRSTFREESLOT, + MN_LASTFREESLOT, NUMMENUTYPES, -} menutype_t; // up to 63; MN_SPECIAL = 53 +} menutype_t; // up to 63 +#define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT) #define MTREE2(a,b) (a | (b< Date: Sun, 16 Mar 2025 21:58:24 +0100 Subject: [PATCH 03/33] Rename titlepics to headers, fold quit routines into normal routines To avoid confusion with all the TitlePicsAbc stuff in SOC None of the extant quit routines ever return false, do this to simplify SOC code and maybe prevent evil trap menus :P --- src/deh_soc.c | 4 ++-- src/m_menu.c | 57 +++++++++++++++++++++++++-------------------------- src/m_menu.h | 4 ++-- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 2a54dc1a2..c1f8aa3c8 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2506,9 +2506,9 @@ void readmenu(MYFILE *f, INT32 num) titlechanged = true; } // MENUDEF STARTS HERE - else if (fastcmp(word, "MENUTITLEPIC") || fastcmp(word, "TITLEPIC")) + else if (fastcmp(word, "HEADERPIC")) { - menudef->menutitlepic = Z_StrDup(word2); + menudef->headerpic = Z_StrDup(word2); } else if (fastcmp(word, "PREVMENU")) { diff --git a/src/m_menu.c b/src/m_menu.c index 2bd418f26..715837f6b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -259,7 +259,7 @@ menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef; static void M_GrandPrixTemp(INT32 choice); static void M_StartGrandPrix(INT32 choice); static void M_TimeAttack(INT32 choice); -static boolean M_QuitTimeAttackMenu(void); +static void M_QuitTimeAttackMenu(INT32 choice); static void M_ItemBreaker(INT32 choice); static void M_Statistics(INT32 choice); static void M_HandleStaffReplay(INT32 choice); @@ -346,7 +346,7 @@ menu_t MISC_ReplayOptionsDef; static void M_HandleReplayHutList(INT32 choice); static void M_DrawReplayHut(void); static void M_DrawReplayStartMenu(void); -static boolean M_QuitReplayHut(void); +static void M_QuitReplayHut(INT32 choice); static void M_HutStartReplay(INT32 choice); static void M_DrawPlaybackMenu(void); @@ -389,9 +389,9 @@ static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); // Handling functions -static boolean M_CancelConnect(void); -static boolean M_ExitPandorasBox(void); -static boolean M_QuitMultiPlayerMenu(void); +static void M_CancelConnect(INT32 choice); +static void M_ExitPandorasBox(INT32 choice); +static void M_QuitMultiPlayerMenu(INT32 choice); static void M_HandleAddons(INT32 choice); static void M_HandleSoundTest(INT32 choice); static void M_HandleMusicTest(INT32 choice); @@ -3467,8 +3467,8 @@ void M_ClearMenus(boolean callexitmenufunc) if (!menuactive) return; - if (currentMenu->quitroutine && callexitmenufunc && !currentMenu->quitroutine()) - return; // we can't quit this menu (also used to set parameter from the menu) + if (currentMenu->quitroutine && callexitmenufunc) + currentMenu->quitroutine(0); #ifndef DC // Save the config file. I'm sick of crashing the game later and losing all my changes! COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile)); @@ -3487,12 +3487,10 @@ void M_SetupNextMenu(menu_t *menudef) { INT16 i; - if (currentMenu->quitroutine) - { - // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH - if (currentMenu != menudef && !currentMenu->quitroutine()) - return; // we can't quit this menu (also used to set parameter from the menu) - } + // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH + if (currentMenu != menudef && currentMenu->quitroutine) + currentMenu->quitroutine(0); + currentMenu = menudef; itemOn = currentMenu->lastOn; @@ -3920,9 +3918,9 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y) static void M_DrawMenuTitle(void) { - if (currentMenu->menutitlepic) + if (currentMenu->headerpic) { - patch_t *p = W_CachePatchName(currentMenu->menutitlepic, PU_CACHE); + patch_t *p = W_CachePatchName(currentMenu->headerpic, PU_CACHE); if (p->height > 24) // title is larger than normal { @@ -5520,7 +5518,7 @@ static void M_HandleReplayHutList(INT32 choice) break; case KEY_ESCAPE: - M_QuitReplayHut(); + M_QuitReplayHut(0); break; case KEY_ENTER: @@ -5541,7 +5539,7 @@ static void M_HandleReplayHutList(INT32 choice) if (!preparefilemenu(true, true)) { - M_QuitReplayHut(); + M_QuitReplayHut(0); return; } } @@ -5564,7 +5562,7 @@ static void M_HandleReplayHutList(INT32 choice) menupath[menupathindex[++menudepthleft]] = 0; if (!preparefilemenu(false, true)) { - M_QuitReplayHut(); + M_QuitReplayHut(0); return; } PrepReplayList(); @@ -5988,8 +5986,10 @@ static void M_DrawReplayStartMenu(void) V_DrawSmallString(4, BASEVIDHEIGHT-14, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, warning); } -static boolean M_QuitReplayHut(void) +static void M_QuitReplayHut(INT32 choice) { + (void)choice; + // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. menuactive = false; D_StartTitle(); @@ -5999,8 +5999,6 @@ static boolean M_QuitReplayHut(void) demolist = NULL; demo.inreplayhut = false; - - return true; } static void M_HutStartReplay(INT32 choice) @@ -6292,13 +6290,13 @@ static void M_PandorasBox(INT32 choice) M_SetupNextMenu(&SR_PandoraDef); } -static boolean M_ExitPandorasBox(void) +static void M_ExitPandorasBox(INT32 choice) { + (void)choice; if (cv_dummyrings.value != players[consoleplayer].rings) COM_ImmedExecute(va("setrings %d", cv_dummyrings.value)); if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); - return true; } static void M_ChangeLevel(INT32 choice) @@ -8600,11 +8598,12 @@ static void M_ItemBreaker(INT32 choice) S_ChangeMusicInternal("racent", true); } -static boolean M_QuitTimeAttackMenu(void) +static void M_QuitTimeAttackMenu(INT32 choice) { + (void)choice; + // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText(va("skin \"%s\"\n", cv_chooseskin.string)); - return true; } // Player has selected the "START" from the time attack screen @@ -9176,10 +9175,10 @@ static void M_DrawConnectMenu(void) } } -static boolean M_CancelConnect(void) +void M_CancelConnect(INT32 choice) { + (void)choice; D_CloseConnection(); - return true; } // Ascending order, not descending. @@ -10531,8 +10530,9 @@ static void M_SetupMultiPlayer4(INT32 choice) M_SetupNextMenu(&MP_PlayerSetupDef); } -static boolean M_QuitMultiPlayerMenu(void) +void M_QuitMultiPlayerMenu(INT32 choice) { + (void)choice; size_t l; const char *followername = setupm_fakefollower == -1 ? "None" : followers[setupm_fakefollower].skinname; @@ -10549,7 +10549,6 @@ static boolean M_QuitMultiPlayerMenu(void) COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name)); COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor->color)); COM_BufAddText (va("%s %s\n",setupm_cvfollower->name,followername)); - return true; } void M_AddMenuColor(UINT16 color) { diff --git a/src/m_menu.h b/src/m_menu.h index f9d1e8875..284a29aee 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -359,14 +359,14 @@ struct menuitem_t struct menu_t { UINT32 menuid; // ID to encode menu type and hierarchy - const char *menutitlepic; + const char *headerpic; INT16 numitems; // # of menu items menu_t *prevMenu; // previous menu menuitem_t *menuitems; // menu items void (*drawroutine)(void); // draw routine INT16 x, y; // x, y of menu INT16 lastOn; // last item user was on in menu - boolean (*quitroutine)(void); // called before quit a menu return true if we can + void (*quitroutine)(INT32 choice); // called before quit a menu }; void M_SetupNextMenu(menu_t *menudef); From d916fee3a642859a42321f86f735adde2b8ae027 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 16 Mar 2025 22:16:49 +0100 Subject: [PATCH 04/33] Expose menu routines/drawers Plus some extras for SOCcing more menus --- src/deh_soc.c | 50 +++++++++++++++++++++++- src/deh_soc.h | 2 + src/deh_tables.c | 43 ++++++++++++++++++++ src/deh_tables.h | 12 ++++++ src/m_menu.c | 100 +++++++++++++++++++---------------------------- src/m_menu.h | 35 +++++++++++++++++ 6 files changed, 180 insertions(+), 62 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index c1f8aa3c8..c2131b084 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2145,6 +2145,13 @@ void readtextprompt(MYFILE *f, INT32 num) Z_Free(s); } +// super secret menu cvars... :shushing_face: +static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { + { "NEXTMAP", &cv_nextmap }, + { "NEWGAMETYPE", &cv_newgametype }, + { NULL, NULL } +}; + static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2198,6 +2205,8 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) flags = IT_HEADER; else if (fastcmp(word+4, "SECRET")) flags = IT_SECRET; + else if (fastcmp(word+4, "WHITE")) + flags = IT_WHITESTRING; else if (word[4]) { deh_warning("MenuItem %s: unknown word '%s'", "", word); @@ -2234,6 +2243,13 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } consvar_t *cvar = CV_FindVar(word2); + if (!cvar) + for (size_t i = 0; HIDDENVARS[i].name; i++) + if (fasticmp(word2, HIDDENVARS[i].name)) + { + cvar = HIDDENVARS[i].var; + break; + } if (!cvar) { deh_warning("MenuItem %s: unable to find cvar '%s'", "", word2); @@ -2267,7 +2283,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) deh_warning("MenuItem %s: action already set!", ""); continue; } - void (*routine)(INT32 choice) = NULL; // TODO + void (*routine)(INT32) = get_menuroutine(word2); if (!routine) { deh_warning("MenuItem %s: unknown call routine '%s'", "", word2); @@ -2279,7 +2295,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) } else if (fastcmp(word, "ALPHAKEY") || fastcmp(word, "Y")) { - menuitem->alphaKey = atoi(word2); + menuitem->alphaKey = get_number(word2); } else deh_warning("MenuItem %s: unknown word '%s'", "", word); @@ -2522,10 +2538,13 @@ void readmenu(MYFILE *f, INT32 num) } else if (fastcmp(word, "DRAWROUTINE")) { + void (*drawer)(void) = get_menudrawer(word2); + if (drawer == NULL) { deh_warning("Menu %d: unknown draw routine '%s'", num, word2); continue; } + menudef->drawroutine = drawer; } else if (fastcmp(word, "X")) { @@ -2537,10 +2556,13 @@ void readmenu(MYFILE *f, INT32 num) } else if (fastcmp(word, "QUITROUTINE")) { + void (*routine)(INT32) = get_menuroutine(word2); + if (!routine) { deh_warning("Menu %d: unknown quit routine '%s'", num, word2); continue; } + menudef->quitroutine = routine; } else deh_warning("Menu %d: unknown word '%s'", num, word); @@ -4303,6 +4325,30 @@ menutype_t get_menutype(const char *word) return MN_NONE; } +void (*get_menuroutine(const char *word))(INT32) +{ // Returns the value of MR_ enumerations + size_t i; + if (fastncmp("MR_",word,3)) + word += 3; // take off the MR_ + for (i = 0; MENU_ROUTINES[i].name; i++) + if (fasticmp(word, MENU_ROUTINES[i].name)) + return MENU_ROUTINES[i].routine; + deh_warning("Couldn't find menu routine named 'MR_%s'",word); + return NULL; +} + +void (*get_menudrawer(const char *word))(void) +{ // Returns the value of MD_ enumerations + size_t i; + if (fastncmp("MD_",word,3)) + word += 3; // take off the MD_ + for (i = 0; MENU_DRAWERS[i].name; i++) + if (fasticmp(word, MENU_DRAWERS[i].name)) + return MENU_DRAWERS[i].drawer; + deh_warning("Couldn't find menu drawer named 'MD_%s'",word); + return NULL; +} + /*static INT16 get_gametype(const char *word) { // Returns the value of GT_ enumerations INT16 i; diff --git a/src/deh_soc.h b/src/deh_soc.h index cb24db595..a1f7f104e 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -57,6 +57,8 @@ spritenum_t get_sprite(const char *word); playersprite_t get_sprite2(const char *word); sfxenum_t get_sfx(const char *word); menutype_t get_menutype(const char *word); +void (*get_menuroutine(const char *word))(INT32); +void (*get_menudrawer(const char *word))(void); //INT16 get_gametype(const char *word); //powertype_t get_power(const char *word); skincolornum_t get_skincolor(const char *word); diff --git a/src/deh_tables.c b/src/deh_tables.c index dbb9098f0..346bebbc2 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -694,10 +694,53 @@ const char *const MENUTYPES_LIST[] = { "OP_P3CAMERA", "OP_P4CAMERA", "MISC_REPLAY", + "MP_OFFLINESERVER", "SPECIAL" }; +struct menu_routine_s const MENU_ROUTINES[] = { + { "SETUPMULTIHANDLER", &M_SetupMultiHandler }, + { "HANDLESETUPMULTIPLAYER", &M_HandleSetupMultiPlayer }, + { "QUITMULTIPLAYERMENU", &M_QuitMultiPlayerMenu }, + { "STARTSERVERMENU", &M_StartServerMenu }, + { "STARTOFFLINESERVERMENU", &M_StartOfflineServerMenu }, + { "STARTSERVER", &M_StartServer }, + { "CONNECTMENUMODCHECKS", &M_ConnectMenuModChecks }, + { "HANDLECONNECTIP", &M_HandleConnectIP }, + { "CANCELCONNECT", &M_CancelConnect }, + { "SETUP1PCONTROLSMENU", &M_Setup1PControlsMenu }, + { "SETUP2PCONTROLSMENU", &M_Setup2PControlsMenu }, + { "SETUP3PCONTROLSMENU", &M_Setup3PControlsMenu }, + { "SETUP4PCONTROLSMENU", &M_Setup4PControlsMenu }, + { "VIDEOMODEMENU", &M_VideoModeMenu }, +#ifdef HWRENDER + { "OPENGLOPTIONSMENU", &M_OpenGLOptionsMenu }, +#endif + { "HANDLEVIDEOMODE", &M_HandleVideoMode }, + { "HANDLESOUNDTEST", &M_HandleSoundTest }, + { "MUSICTEST", &M_MusicTest }, + { "SCREENSHOTOPTIONS", &M_ScreenshotOptions }, + { "ADDONSOPTIONS", &M_AddonsOptions }, + { "ERASEDATA", &M_EraseData }, + { "MANUAL", &M_Manual }, + { "CREDITS", &M_Credits }, + { "BLANCREDITS", &M_BlanCredits }, + { NULL, NULL } +}; + +struct menu_drawer_s const MENU_DRAWERS[] = { + { "DRAWGENERICMENU", &M_DrawGenericMenu }, + { "DRAWMPMAINMENU", &M_DrawMPMainMenu }, + { "DRAWSETUPMULTIPLAYERMENU", &M_DrawSetupMultiPlayerMenu }, + { "DRAWSERVERMENU", &M_DrawServerMenu }, + { "DRAWVIDEOMENU", &M_DrawVideoMenu }, + { "DRAWVIDEOMODE", &M_DrawVideoMode }, + { "DRAWSKYROOM", &M_DrawSkyRoom }, + { "DRAWHUDOPTIONS", &M_DrawHUDOptions }, + { NULL, NULL } +}; + struct int_const_s const INT_CONST[] = { // If a mod removes some variables here, // please leave the names in-tact and just set diff --git a/src/deh_tables.h b/src/deh_tables.h index 15923a6c0..b67743ee6 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -53,6 +53,16 @@ struct actionpointer_t const char *name; ///< Name of the action in ALL CAPS. }; +struct menu_routine_s { + const char *name; + void (*routine)(INT32); +}; + +struct menu_drawer_s { + const char *name; + void (*drawer)(void); +}; + struct int_const_s { const char *n; // has to be able to hold both fixed_t and angle_t, so drastic measure!! @@ -82,6 +92,8 @@ extern const char *const KARTSTUFF_LIST[]; extern const char *const KARTHUD_LIST[]; extern const char *const HUDITEMS_LIST[]; extern const char *const MENUTYPES_LIST[]; +extern struct menu_routine_s const MENU_ROUTINES[]; +extern struct menu_drawer_s const MENU_DRAWERS[]; extern struct int_const_s const INT_CONST[]; diff --git a/src/m_menu.c b/src/m_menu.c index 715837f6b..582b80955 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -227,9 +227,6 @@ FUNCNORETURN static ATTRNORETURN void M_UltimateCheat(INT32 choice); static void M_GetAllEmeralds(INT32 choice); static void M_DestroyRobots(INT32 choice); //static void M_LevelSelectWarp(INT32 choice); -static void M_Credits(INT32 choice); -static void M_BlanCredits(INT32 choice); -static void M_MusicTest(INT32 choice); static void M_PandorasBox(INT32 choice); static void M_EmblemHints(INT32 choice); static char *M_GetConditionString(condition_t cond); @@ -238,7 +235,6 @@ menu_t SR_MainDef, SR_UnlockChecklistDef; // Misc. Main Menu static void M_SinglePlayerMenu(INT32 choice); static void M_Options(INT32 choice); -static void M_Manual(INT32 choice); static void M_SelectableClearMenus(INT32 choice); static void M_Retry(INT32 choice); static void M_EndGame(INT32 choice); @@ -275,29 +271,19 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; //static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; // Multiplayer -static void M_StartServerMenu(INT32 choice); static void M_ConnectMenu(INT32 choice); -static void M_ConnectMenuModChecks(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); -static void M_StartOfflineServerMenu(INT32 choice); -static void M_StartServer(INT32 choice); static void M_SetupMultiPlayer(INT32 choice); static void M_SetupMultiPlayer2(INT32 choice); static void M_SetupMultiPlayer3(INT32 choice); static void M_SetupMultiPlayer4(INT32 choice); -static void M_SetupMultiHandler(INT32 choice); // Options // Split into multiple parts due to size // Controls menu_t OP_ControlsDef, OP_AllControlsDef; menu_t OP_MouseOptionsDef; -static void M_VideoModeMenu(INT32 choice); -static void M_Setup1PControlsMenu(INT32 choice); -static void M_Setup2PControlsMenu(INT32 choice); -static void M_Setup3PControlsMenu(INT32 choice); -static void M_Setup4PControlsMenu(INT32 choice); static void M_Setup1PJoystickMenu(INT32 choice); static void M_Setup2PJoystickMenu(INT32 choice); @@ -315,7 +301,6 @@ menu_t OP_Player1CamOptionsDef, OP_Player2CamOptionsDef, OP_Player3CamOptionsDef // Video & Sound menu_t OP_VideoOptionsDef, OP_VideoModeDef; #ifdef HWRENDER -static void M_OpenGLOptionsMenu(INT32 choice); menu_t OP_OpenGLOptionsDef; #endif menu_t OP_SoundOptionsDef; @@ -331,11 +316,8 @@ menu_t OP_GameOptionsDef, OP_BlanKartGameOptionsDef, OP_ServerOptionsDef; menu_t OP_AdvServerOptionsDef; //menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; -static void M_ScreenshotOptions(INT32 choice); -static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); -static void M_AddonsOptions(INT32 choice); static patch_t *addonsp[NUM_EXT+5]; #define numaddonsshown 4 @@ -365,13 +347,11 @@ static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the butto static void M_DrawGenericBackgroundMenu(void); static void M_DrawCenteredMenu(void); static void M_DrawAddons(void); -static void M_DrawSkyRoom(void); static void M_DrawChecklist(void); static void M_DrawMusicTest(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); -static void M_DrawServerMenu(void); static void M_DrawImageDef(void); //static void M_DrawLoad(void); static void M_DrawLevelStats(void); @@ -379,28 +359,17 @@ static void M_DrawTimeAttackMenu(void); //static void M_DrawNightsAttackMenu(void); //static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControl(void); -static void M_DrawVideoMenu(void); -static void M_DrawHUDOptions(void); -static void M_DrawVideoMode(void); static void M_DrawMonitorToggles(void); -static void M_DrawMPMainMenu(void); static void M_DrawConnectMenu(void); static void M_DrawJoystick(void); -static void M_DrawSetupMultiPlayerMenu(void); // Handling functions -static void M_CancelConnect(INT32 choice); static void M_ExitPandorasBox(INT32 choice); -static void M_QuitMultiPlayerMenu(INT32 choice); static void M_HandleAddons(INT32 choice); -static void M_HandleSoundTest(INT32 choice); static void M_HandleMusicTest(INT32 choice); static void M_HandleImageDef(INT32 choice); //static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); -static void M_HandleConnectIP(INT32 choice); -static void M_HandleSetupMultiPlayer(INT32 choice); -static void M_HandleVideoMode(INT32 choice); static void M_HandleMonitorToggles(INT32 choice); // uhhhhhh hack? @@ -413,6 +382,7 @@ static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) +menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef; menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_CAMERA] = &OP_CamOptionsDef, [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, @@ -423,6 +393,7 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_MAIN] = &OP_MainDef, [MN_OP_CHANGECONTROLS] = &OP_ControlsDef, [MN_OP_VIDEO] = &OP_VideoOptionsDef, + [MN_OP_VIDEOMODE] = &OP_VideoModeDef, [MN_OP_OPENGL] = &OP_OpenGLOptionsDef, [MN_OP_SOUND] = &OP_SoundOptionsDef, [MN_OP_CHAT] = &OP_ChatOptionsDef, @@ -433,9 +404,18 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_ADVANCEDSERVER] = &OP_AdvServerOptionsDef, [MN_OP_MONITORTOGGLE] = &OP_MonitorToggleDef, [MN_OP_DATA] = &OP_DataOptionsDef, + [MN_OP_ADDONS] = &OP_AddonsOptionsDef, + [MN_OP_SCREENSHOTS] = &OP_ScreenshotOptionsDef, [MN_OP_ERASEDATA] = &OP_EraseDataDef, [MN_MISC_REPLAY] = &MISC_ReplayOptionsDef, + [MN_MP_MAIN] = &MP_MainDef, + [MN_MP_PLAYERSETUP] = &MP_PlayerSetupDef, + [MN_MP_SERVER] = &MP_ServerDef, + [MN_MP_OFFLINESERVER] = &MP_OfflineServerDef, + + [MN_MAIN] = &MainDef, + [MN_FIRSTFREESLOT] = &FreeslotTest, }; @@ -2152,7 +2132,7 @@ menu_t OP_MonitorToggleDef = }; #ifdef HWRENDER -static void M_OpenGLOptionsMenu(INT32 choice) +void M_OpenGLOptionsMenu(INT32 choice) { (void)choice; @@ -4873,7 +4853,7 @@ static void M_HandleImageDef(INT32 choice) // MISC MAIN MENU OPTIONS // ====================== -static void M_AddonsOptions(INT32 choice) +void M_AddonsOptions(INT32 choice) { (void)choice; Addons_option_Onchange(); @@ -6424,7 +6404,7 @@ static void M_Options(INT32 choice) M_SetupNextMenu(&OP_MainDef); } -static void M_Manual(INT32 choice) +void M_Manual(INT32 choice) { (void)choice; @@ -6702,7 +6682,7 @@ static void M_DrawEmblemHints(void) M_DrawGenericMenu(); } -static void M_DrawSkyRoom(void) +void M_DrawSkyRoom(void) { INT32 i, y = 0; INT32 lengthstring = 0; @@ -6757,7 +6737,7 @@ static void M_DrawSkyRoom(void) } } -static void M_HandleSoundTest(INT32 choice) +void M_HandleSoundTest(INT32 choice) { boolean exitmenu = false; // exit to previous menu @@ -6807,7 +6787,7 @@ static size_t st_namescrollstate = 0; //static patch_t* st_radio[9]; //static patch_t* st_launchpad[4]; -static void M_MusicTest(INT32 choice) +void M_MusicTest(INT32 choice) { //INT32 ul = skyRoomMenuTranslations[choice-1]; //UINT8 i; @@ -7234,7 +7214,7 @@ static void M_NewGame(void) M_SetupChoosePlayer(0); }*/ -static void M_Credits(INT32 choice) +void M_Credits(INT32 choice) { (void)choice; cursaveslot = -2; @@ -7242,7 +7222,7 @@ static void M_Credits(INT32 choice) F_StartCredits(); } -static void M_BlanCredits(INT32 choice) +void M_BlanCredits(INT32 choice) { (void)choice; cursaveslot = -2; @@ -9336,7 +9316,7 @@ static void M_ConnectMenu(INT32 choice) #endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/ } -static void M_ConnectMenuModChecks(INT32 choice) +void M_ConnectMenuModChecks(INT32 choice) { (void)choice; // okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work @@ -9379,7 +9359,7 @@ static INT32 M_FindFirstMap(INT32 gtype) return 1; } -static void M_StartServer(INT32 choice) +void M_StartServer(INT32 choice) { UINT8 ssplayers = cv_splitplayers.value-1; @@ -9527,7 +9507,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) #undef horizspac } -static void M_DrawServerMenu(void) +void M_DrawServerMenu(void) { M_DrawLevelSelectOnly(false, false); M_DrawGenericMenu(); @@ -9546,7 +9526,7 @@ static void M_MapChange(INT32 choice) M_SetupNextMenu(&MISC_ChangeLevelDef); } -static void M_StartOfflineServerMenu(INT32 choice) +void M_StartOfflineServerMenu(INT32 choice) { (void)choice; levellistmode = LLM_CREATESERVER; @@ -9554,7 +9534,7 @@ static void M_StartOfflineServerMenu(INT32 choice) M_SetupNextMenu(&MP_OfflineServerDef); } -static void M_StartServerMenu(INT32 choice) +void M_StartServerMenu(INT32 choice) { (void)choice; levellistmode = LLM_CREATESERVER; @@ -9572,7 +9552,7 @@ static UINT8 setupm_pselect = 1; // Draw the funky Connect IP menu. Tails 11-19-2002 // So much work for such a little thing! -static void M_DrawMPMainMenu(void) +void M_DrawMPMainMenu(void) { INT32 x = currentMenu->x; INT32 y = currentMenu->y; @@ -9655,7 +9635,7 @@ static void Splitplayers_OnChange(void) setupm_pselect = 1; } -static void M_SetupMultiHandler(INT32 choice) +void M_SetupMultiHandler(INT32 choice) { boolean exitmenu = false; // exit to previous menu and send name change @@ -9750,7 +9730,7 @@ static void M_ConnectIP(INT32 choice) } // Tails 11-19-2002 -static void M_HandleConnectIP(INT32 choice) +void M_HandleConnectIP(INT32 choice) { size_t l; boolean exitmenu = false; // exit to previous menu and send name change @@ -9853,7 +9833,7 @@ static INT32 setupm_fakeskin; static menucolor_t *setupm_fakecolor; static INT32 setupm_fakefollower; // -1 is for none, our followers start at 0 -static void M_DrawSetupMultiPlayerMenu(void) +void M_DrawSetupMultiPlayerMenu(void) { INT32 mx, my, st, flags = 0; spritedef_t *sprdef; @@ -10198,7 +10178,7 @@ static void M_GetFollowerState(void) } // Handle 1P/2P MP Setup -static void M_HandleSetupMultiPlayer(INT32 choice) +void M_HandleSetupMultiPlayer(INT32 choice) { size_t l; INT32 prev_setupm_fakeskin; @@ -10754,7 +10734,7 @@ static void M_EraseDataResponse(INT32 ch) M_ClearMenus(true); } -static void M_EraseData(INT32 choice) +void M_EraseData(INT32 choice) { const char *eschoice, *esstr = M_GetText("Are you sure you want to erase\n%s?\n\n(Press 'Y' to confirm)\n"); @@ -10770,7 +10750,7 @@ static void M_EraseData(INT32 choice) M_StartMessage(va(esstr, eschoice), FUNCPTRCAST(M_EraseDataResponse), MM_YESNO); } -static void M_ScreenshotOptions(INT32 choice) +void M_ScreenshotOptions(INT32 choice) { (void)choice; Screenshot_option_Onchange(); @@ -10916,7 +10896,7 @@ static void M_AssignJoystick(INT32 choice) // CONTROLS MENU // ============= -static void M_Setup1PControlsMenu(INT32 choice) +void M_Setup1PControlsMenu(INT32 choice) { (void)choice; setupcontrolplayer = 1; @@ -10949,7 +10929,7 @@ static void M_Setup1PControlsMenu(INT32 choice) M_SetupNextMenu(&OP_AllControlsDef); } -static void M_Setup2PControlsMenu(INT32 choice) +void M_Setup2PControlsMenu(INT32 choice) { (void)choice; setupcontrolplayer = 2; @@ -10982,7 +10962,7 @@ static void M_Setup2PControlsMenu(INT32 choice) M_SetupNextMenu(&OP_AllControlsDef); } -static void M_Setup3PControlsMenu(INT32 choice) +void M_Setup3PControlsMenu(INT32 choice) { (void)choice; setupcontrolplayer = 3; @@ -11015,7 +10995,7 @@ static void M_Setup3PControlsMenu(INT32 choice) M_SetupNextMenu(&OP_AllControlsDef); } -static void M_Setup4PControlsMenu(INT32 choice) +void M_Setup4PControlsMenu(INT32 choice) { (void)choice; setupcontrolplayer = 4; @@ -11333,7 +11313,7 @@ static void M_ResetControls(INT32 choice) static modedesc_t modedescs[MAXMODEDESCS]; -static void M_VideoModeMenu(INT32 choice) +void M_VideoModeMenu(INT32 choice) { INT32 i, j, vdup, nummodes; UINT32 width, height; @@ -11406,7 +11386,7 @@ static void M_VideoModeMenu(INT32 choice) M_SetupNextMenu(&OP_VideoModeDef); } -static void M_DrawVideoMenu(void) +void M_DrawVideoMenu(void) { M_DrawGenericMenu(); @@ -11431,7 +11411,7 @@ static void M_DrawVideoMenu(void) } } -static void M_DrawHUDOptions(void) +void M_DrawHUDOptions(void) { const char *str0 = ")"; const char *str1 = " Warning highlight"; @@ -11454,7 +11434,7 @@ static void M_DrawHUDOptions(void) } // Draw the video modes list, a-la-Quake -static void M_DrawVideoMode(void) +void M_DrawVideoMode(void) { INT32 i, j, row, col; @@ -11526,7 +11506,7 @@ static void M_DrawVideoMode(void) } // special menuitem key handler for video mode list -static void M_HandleVideoMode(INT32 ch) +void M_HandleVideoMode(INT32 ch) { if (vidm_testingmode > 0) switch (ch) { diff --git a/src/m_menu.h b/src/m_menu.h index 284a29aee..c2d02349f 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -148,6 +148,7 @@ typedef enum MN_OP_P3CAMERA, MN_OP_P4CAMERA, MN_MISC_REPLAY, + MN_MP_OFFLINESERVER, MN_SPECIAL, @@ -372,7 +373,41 @@ struct menu_t void M_SetupNextMenu(menu_t *menudef); void M_ClearMenus(boolean callexitmenufunc); +void M_SetupMultiHandler(INT32 choice); +void M_HandleSetupMultiPlayer(INT32 choice); +void M_QuitMultiPlayerMenu(INT32 choice); +void M_StartServerMenu(INT32 choice); +void M_StartOfflineServerMenu(INT32 choice); +void M_StartServer(INT32 choice); +void M_ConnectMenuModChecks(INT32 choice); +void M_HandleConnectIP(INT32 choice); +void M_CancelConnect(INT32 choice); +void M_Setup1PControlsMenu(INT32 choice); +void M_Setup2PControlsMenu(INT32 choice); +void M_Setup3PControlsMenu(INT32 choice); +void M_Setup4PControlsMenu(INT32 choice); +void M_VideoModeMenu(INT32 choice); +#ifdef HWRENDER +void M_OpenGLOptionsMenu(INT32 choice); +#endif +void M_HandleVideoMode(INT32 ch); +void M_HandleSoundTest(INT32 choice); +void M_MusicTest(INT32 choice); +void M_ScreenshotOptions(INT32 choice); +void M_AddonsOptions(INT32 choice); +void M_EraseData(INT32 choice); +void M_Manual(INT32 choice); +void M_Credits(INT32 choice); +void M_BlanCredits(INT32 choice); + void M_DrawGenericMenu(void); +void M_DrawMPMainMenu(void); +void M_DrawSetupMultiPlayerMenu(void); +void M_DrawServerMenu(void); +void M_DrawVideoMenu(void); +void M_DrawVideoMode(void); +void M_DrawSkyRoom(void); +void M_DrawHUDOptions(void); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); From 56dcba35946c0759ce2c0918b49b80d5ead7913e Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 18 Mar 2025 23:16:44 +0100 Subject: [PATCH 05/33] SOC the entire main menu --- src/deh_soc.c | 29 +++++++++++++-- src/deh_tables.c | 29 ++++++++++++++- src/m_menu.c | 94 ++++++++++++++++++++++-------------------------- src/m_menu.h | 29 ++++++++++++++- 4 files changed, 125 insertions(+), 56 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index c2131b084..2bfefad0b 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2147,6 +2147,10 @@ void readtextprompt(MYFILE *f, INT32 num) // super secret menu cvars... :shushing_face: static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { + { "CHOOSESKIN", &cv_chooseskin }, + { "DUMMYGPDIFFICULTY", &cv_dummygpdifficulty }, + { "DUMMYGPENCORE", &cv_dummygpencore }, + { "DUMMYGPCUP", &cv_dummygpcup }, { "NEXTMAP", &cv_nextmap }, { "NEWGAMETYPE", &cv_newgametype }, { NULL, NULL } @@ -2207,6 +2211,8 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) flags = IT_SECRET; else if (fastcmp(word+4, "WHITE")) flags = IT_WHITESTRING; + else if (fastcmp(word+4, "DISABLED")) + flags = IT_DISABLED; else if (word[4]) { deh_warning("MenuItem %s: unknown word '%s'", "", word); @@ -2276,8 +2282,23 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) menuitem->status |= IT_SUBMENU; menuitem->itemaction.submenu = menunum2menudef[mn]; } - else if (fastcmp(word, "CALL") || fastcmp(word, "KEYHANDLER")) + else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER")) { + UINT16 flags; + if (word[0] == 'C') + { + flags = IT_CALL; + if (fastcmp(word+4, "NOTMODIFIED")) + flags |= IT_CALL_NOTMODIFIED; + else if (word[4]) + { + deh_warning("MenuItem %s: unknown word '%s'", "", word); + continue; + } + } + else + flags = IT_KEYHANDLER; + if (actionset) { deh_warning("MenuItem %s: action already set!", ""); @@ -2290,7 +2311,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } actionset = true; - menuitem->status |= word[0] == 'C' ? IT_CALL : IT_KEYHANDLER; + menuitem->status |= flags; menuitem->itemaction.routine = routine; } else if (fastcmp(word, "ALPHAKEY") || fastcmp(word, "Y")) @@ -2302,6 +2323,10 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) } while (!myfeof(f)); // finish when the line is empty + // text pointer cannot be null + if (!textset) + menuitem->text = ""; + Z_Free(s); } diff --git a/src/deh_tables.c b/src/deh_tables.c index 346bebbc2..ca1da9eb3 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -693,13 +693,33 @@ const char *const MENUTYPES_LIST[] = { "OP_CAMERA", "OP_P3CAMERA", "OP_P4CAMERA", - "MISC_REPLAY", + "MISC_REPLAYOPTIONS", "MP_OFFLINESERVER", + "SP_GRANDPRIX", + "MISC_REPLAYHUT", "SPECIAL" }; struct menu_routine_s const MENU_ROUTINES[] = { + { "SINGLEPLAYERMENU", &M_SinglePlayerMenu }, + { "OPTIONS", &M_Options }, + { "ADDONS", &M_Addons }, + { "QUITSRB2", &M_QuitSRB2 }, + { "STATISTICS", &M_Statistics }, + { "HANDLELEVELSTATS", &M_HandleLevelStats }, + { "REPLAYHUT", &M_ReplayHut }, + { "QUITREPLAYHUT", &M_QuitReplayHut }, + { "HANDLEREPLAYHUTLIST", &M_HandleReplayHutList }, + { "GRANDPRIXTEMP", &M_GrandPrixTemp }, + { "TIMEATTACK", &M_TimeAttack }, + { "ITEMBREAKER", &M_ItemBreaker }, + { "STARTGRANDPRIX", &M_StartGrandPrix }, + { "QUITTIMEATTACKMENU", &M_QuitTimeAttackMenu }, + { "CHOOSETIMEATTACK", &M_ChooseTimeAttack }, + { "SETGUESTREPLAY", &M_SetGuestReplay }, + { "REPLAYTIMEATTACK", &M_ReplayTimeAttack }, + { "HANDLESTAFFREPLAY", &M_HandleStaffReplay }, { "SETUPMULTIHANDLER", &M_SetupMultiHandler }, { "HANDLESETUPMULTIPLAYER", &M_HandleSetupMultiPlayer }, { "QUITMULTIPLAYERMENU", &M_QuitMultiPlayerMenu }, @@ -726,11 +746,17 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "MANUAL", &M_Manual }, { "CREDITS", &M_Credits }, { "BLANCREDITS", &M_BlanCredits }, + { "HANDLEADDONS", &M_HandleAddons }, { NULL, NULL } }; struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWGENERICMENU", &M_DrawGenericMenu }, + { "DRAWCENTEREDMENU", &M_DrawCenteredMenu }, + { "DRAWCHECKLIST", &M_DrawChecklist }, + { "DRAWLEVELSTATS", &M_DrawLevelStats }, + { "DRAWREPLAYHUT", &M_DrawReplayHut }, + { "DRAWTIMEATTACKMENU", &M_DrawTimeAttackMenu }, { "DRAWMPMAINMENU", &M_DrawMPMainMenu }, { "DRAWSETUPMULTIPLAYERMENU", &M_DrawSetupMultiPlayerMenu }, { "DRAWSERVERMENU", &M_DrawServerMenu }, @@ -738,6 +764,7 @@ struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWVIDEOMODE", &M_DrawVideoMode }, { "DRAWSKYROOM", &M_DrawSkyRoom }, { "DRAWHUDOPTIONS", &M_DrawHUDOptions }, + { "DRAWADDONS", &M_DrawAddons }, { NULL, NULL } }; diff --git a/src/m_menu.c b/src/m_menu.c index 582b80955..a6c63c0fb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -233,8 +233,6 @@ static char *M_GetConditionString(condition_t cond); menu_t SR_MainDef, SR_UnlockChecklistDef; // Misc. Main Menu -static void M_SinglePlayerMenu(INT32 choice); -static void M_Options(INT32 choice); static void M_SelectableClearMenus(INT32 choice); static void M_Retry(INT32 choice); static void M_EndGame(INT32 choice); @@ -247,23 +245,12 @@ static void M_ConfirmTeamChange(INT32 choice); static void M_ConfirmSpectateChange(INT32 choice); //static void M_SecretsMenu(INT32 choice); //static void M_SetupChoosePlayer(INT32 choice); -static void M_QuitSRB2(INT32 choice); menu_t SP_MainDef, MP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef; // Single Player -static void M_GrandPrixTemp(INT32 choice); -static void M_StartGrandPrix(INT32 choice); -static void M_TimeAttack(INT32 choice); -static void M_QuitTimeAttackMenu(INT32 choice); -static void M_ItemBreaker(INT32 choice); -static void M_Statistics(INT32 choice); -static void M_HandleStaffReplay(INT32 choice); -static void M_ReplayTimeAttack(INT32 choice); -static void M_ChooseTimeAttack(INT32 choice); //static void M_ChooseNightsAttack(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); -static void M_SetGuestReplay(INT32 choice); //static void M_ChoosePlayer(INT32 choice); menu_t SP_LevelStatsDef; static menu_t SP_GrandPrixTempDef; @@ -317,7 +304,6 @@ menu_t OP_AdvServerOptionsDef; //menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; -static void M_Addons(INT32 choice); static patch_t *addonsp[NUM_EXT+5]; #define numaddonsshown 4 @@ -325,10 +311,7 @@ static patch_t *addonsp[NUM_EXT+5]; // Replay hut menu_t MISC_ReplayHutDef; menu_t MISC_ReplayOptionsDef; -static void M_HandleReplayHutList(INT32 choice); -static void M_DrawReplayHut(void); static void M_DrawReplayStartMenu(void); -static void M_QuitReplayHut(INT32 choice); static void M_HutStartReplay(INT32 choice); static void M_DrawPlaybackMenu(void); @@ -345,17 +328,12 @@ static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the butto // Drawing functions static void M_DrawGenericBackgroundMenu(void); -static void M_DrawCenteredMenu(void); -static void M_DrawAddons(void); -static void M_DrawChecklist(void); static void M_DrawMusicTest(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); static void M_DrawImageDef(void); //static void M_DrawLoad(void); -static void M_DrawLevelStats(void); -static void M_DrawTimeAttackMenu(void); //static void M_DrawNightsAttackMenu(void); //static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControl(void); @@ -365,11 +343,9 @@ static void M_DrawJoystick(void); // Handling functions static void M_ExitPandorasBox(INT32 choice); -static void M_HandleAddons(INT32 choice); static void M_HandleMusicTest(INT32 choice); static void M_HandleImageDef(INT32 choice); //static void M_HandleLoadSave(INT32 choice); -static void M_HandleLevelStats(INT32 choice); static void M_HandleMonitorToggles(INT32 choice); // uhhhhhh hack? @@ -382,7 +358,7 @@ static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) -menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef; +menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef; menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_CAMERA] = &OP_CamOptionsDef, [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, @@ -407,13 +383,27 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_ADDONS] = &OP_AddonsOptionsDef, [MN_OP_SCREENSHOTS] = &OP_ScreenshotOptionsDef, [MN_OP_ERASEDATA] = &OP_EraseDataDef, - [MN_MISC_REPLAY] = &MISC_ReplayOptionsDef, + [MN_MISC_REPLAYOPTIONS] = &MISC_ReplayOptionsDef, [MN_MP_MAIN] = &MP_MainDef, [MN_MP_PLAYERSETUP] = &MP_PlayerSetupDef, [MN_MP_SERVER] = &MP_ServerDef, [MN_MP_OFFLINESERVER] = &MP_OfflineServerDef, + [MN_SP_MAIN] = &SP_MainDef, + [MN_SP_GRANDPRIX] = &SP_GrandPrixTempDef, + [MN_SP_TIMEATTACK] = &SP_TimeAttackDef, + [MN_SP_GUESTREPLAY] = &SP_GuestReplayDef, + [MN_SP_REPLAY] = &SP_ReplayDef, + [MN_SP_GHOST] = &SP_GhostDef, + + [MN_SR_MAIN] = &SR_MainDef, + [MN_SR_UNLOCKCHECKLIST] = &SR_UnlockChecklistDef, + [MN_SP_LEVELSTATS] = &SP_LevelStatsDef, + [MN_MISC_REPLAYHUT] = &MISC_ReplayHutDef, + + [MN_AD_MAIN] = &MISC_AddonsDef, + [MN_MAIN] = &MainDef, [MN_FIRSTFREESLOT] = &FreeslotTest, @@ -498,9 +488,9 @@ static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDEN|CV_CALL, static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {3, "Master"}, {0, NULL}}; static CV_PossibleValue_t dummygpcup_cons_t[50] = {{1, "TEMP"}}; // A REALLY BIG NUMBER, SINCE THIS IS TEMP UNTIL NEW MENUS -static consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HIDEN, dummygpdifficulty_cons_t, NULL); -static consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL); -static consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL); +consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HIDEN, dummygpdifficulty_cons_t, NULL); +consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL); +consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL); // ========================================================================== // ORGANIZATION START. @@ -4252,7 +4242,7 @@ static void M_DrawPauseMenu(void) M_DrawGenericMenu(); } -static void M_DrawCenteredMenu(void) +void M_DrawCenteredMenu(void) { INT32 x, y, i, cursory = 0; @@ -4864,7 +4854,7 @@ void M_AddonsOptions(INT32 choice) #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!" #define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make addons!" -static void M_Addons(INT32 choice) +void M_Addons(INT32 choice) { const char *pathname = "."; @@ -5071,7 +5061,7 @@ static boolean M_AddonsRefresh(void) return false; } -static void M_DrawAddons(void) +void M_DrawAddons(void) { INT32 x, y; ssize_t i, m; @@ -5257,7 +5247,7 @@ static boolean M_ChangeStringAddons(INT32 choice) } #undef len -static void M_HandleAddons(INT32 choice) +void M_HandleAddons(INT32 choice) { boolean exitmenu = false; // exit to previous menu @@ -5471,7 +5461,7 @@ void M_ReplayHut(INT32 choice) S_ChangeMusicInternal("replst", true); } -static void M_HandleReplayHutList(INT32 choice) +void M_HandleReplayHutList(INT32 choice) { switch (choice) { @@ -5710,7 +5700,7 @@ static void DrawReplayHutReplayInfo(void) } } -static void M_DrawReplayHut(void) +void M_DrawReplayHut(void) { INT32 x, y, cursory = 0; INT16 i; @@ -5966,7 +5956,7 @@ static void M_DrawReplayStartMenu(void) V_DrawSmallString(4, BASEVIDHEIGHT-14, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, warning); } -static void M_QuitReplayHut(INT32 choice) +void M_QuitReplayHut(INT32 choice) { (void)choice; @@ -6381,7 +6371,7 @@ static void M_ConfirmSpectateChange(INT32 choice) } } -static void M_Options(INT32 choice) +void M_Options(INT32 choice) { (void)choice; @@ -6563,7 +6553,7 @@ static char *M_GetConditionString(condition_t cond) } #define NUMCHECKLIST 23 -static void M_DrawChecklist(void) +void M_DrawChecklist(void) { UINT32 i, line = 0, c; INT32 lastid; @@ -7251,7 +7241,7 @@ void M_BlanCredits(INT32 choice) // SINGLE PLAYER MENU // ================== -static void M_SinglePlayerMenu(INT32 choice) +void M_SinglePlayerMenu(INT32 choice) { (void)choice; @@ -7938,7 +7928,7 @@ static statpage_t statsPages[] = { #define LENSTATSPAGES (sizeof(statsPages)/sizeof(statsPages[0])) #define NUMSTATSPAGES (kartstats.vanilla ? 2 : LENSTATSPAGES) -static void M_Statistics(INT32 choice) +void M_Statistics(INT32 choice) { INT16 i, j = 0; @@ -8160,7 +8150,7 @@ static void M_DrawStatsExtra(void) #undef DRAWAMOUNTSTAT #undef DRAWTIMESTAT -static void M_DrawLevelStats(void) +void M_DrawLevelStats(void) { M_DrawMenuTitle(); @@ -8176,7 +8166,7 @@ static void M_DrawLevelStats(void) } // Handle statistics. -static void M_HandleLevelStats(INT32 choice) +void M_HandleLevelStats(INT32 choice) { boolean exitmenu = false; // exit to previous menu @@ -8240,7 +8230,7 @@ static void M_HandleLevelStats(INT32 choice) } } -static void M_GrandPrixTemp(INT32 choice) +void M_GrandPrixTemp(INT32 choice) { (void)choice; if (!M_PrepareCupList()) @@ -8253,7 +8243,7 @@ static void M_GrandPrixTemp(INT32 choice) } // Start Grand Prix! -static void M_StartGrandPrix(INT32 choice) +void M_StartGrandPrix(INT32 choice) { cupheader_t *gpcup = kartcupheaders; INT32 levelNum; @@ -8513,7 +8503,7 @@ void M_DrawTimeAttackMenu(void) } // Going to Time Attack menu... -static void M_TimeAttack(INT32 choice) +void M_TimeAttack(INT32 choice) { (void)choice; @@ -8546,7 +8536,7 @@ static void M_TimeAttack(INT32 choice) } // Same as above, but sets a different levellistmode. Should probably be merged... -static void M_ItemBreaker(INT32 choice) +void M_ItemBreaker(INT32 choice) { (void)choice; @@ -8578,7 +8568,7 @@ static void M_ItemBreaker(INT32 choice) S_ChangeMusicInternal("racent", true); } -static void M_QuitTimeAttackMenu(INT32 choice) +void M_QuitTimeAttackMenu(INT32 choice) { (void)choice; @@ -8587,7 +8577,7 @@ static void M_QuitTimeAttackMenu(INT32 choice) } // Player has selected the "START" from the time attack screen -static void M_ChooseTimeAttack(INT32 choice) +void M_ChooseTimeAttack(INT32 choice) { char *gpath; char nameofdemo[256]; @@ -8613,7 +8603,7 @@ static void M_ChooseTimeAttack(INT32 choice) G_DeferedInitNew(false, cv_nextmap.value, (UINT8)(cv_chooseskin.value-1), 0, false); } -static void M_HandleStaffReplay(INT32 choice) +void M_HandleStaffReplay(INT32 choice) { boolean exitmenu = false; // exit to previous menu lumpnum_t l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value),cv_dummystaff.value)); @@ -8661,7 +8651,7 @@ static void M_HandleStaffReplay(INT32 choice) } // Player has selected the "REPLAY" from the time attack screen -static void M_ReplayTimeAttack(INT32 choice) +void M_ReplayTimeAttack(INT32 choice) { const char *which; const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; @@ -8786,7 +8776,7 @@ static void M_OverwriteGuest_Last(INT32 choice) M_OverwriteGuest("last"); } -static void M_SetGuestReplay(INT32 choice) +void M_SetGuestReplay(INT32 choice) { void (*which)(INT32); switch(choice) @@ -11916,7 +11906,7 @@ void M_QuitResponse(INT32 ch) I_Quit(); } -static void M_QuitSRB2(INT32 choice) +void M_QuitSRB2(INT32 choice) { // We pick index 0 which is language sensitive, or one at random, // between 1 and maximum number. diff --git a/src/m_menu.h b/src/m_menu.h index c2d02349f..316c3755b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -147,8 +147,10 @@ typedef enum MN_OP_CAMERA, MN_OP_P3CAMERA, MN_OP_P4CAMERA, - MN_MISC_REPLAY, + MN_MISC_REPLAYOPTIONS, MN_MP_OFFLINESERVER, + MN_SP_GRANDPRIX, + MN_MISC_REPLAYHUT, MN_SPECIAL, @@ -373,6 +375,23 @@ struct menu_t void M_SetupNextMenu(menu_t *menudef); void M_ClearMenus(boolean callexitmenufunc); +void M_SinglePlayerMenu(INT32 choice); +void M_Options(INT32 choice); +void M_Addons(INT32 choice); +void M_QuitSRB2(INT32 choice); +void M_Statistics(INT32 choice); +void M_HandleLevelStats(INT32 choice); +void M_QuitReplayHut(INT32 choice); +void M_HandleReplayHutList(INT32 choice); +void M_GrandPrixTemp(INT32 choice); +void M_TimeAttack(INT32 choice); +void M_ItemBreaker(INT32 choice); +void M_StartGrandPrix(INT32 choice); +void M_QuitTimeAttackMenu(INT32 choice); +void M_ChooseTimeAttack(INT32 choice); +void M_SetGuestReplay(INT32 choice); +void M_ReplayTimeAttack(INT32 choice); +void M_HandleStaffReplay(INT32 choice); void M_SetupMultiHandler(INT32 choice); void M_HandleSetupMultiPlayer(INT32 choice); void M_QuitMultiPlayerMenu(INT32 choice); @@ -399,8 +418,14 @@ void M_EraseData(INT32 choice); void M_Manual(INT32 choice); void M_Credits(INT32 choice); void M_BlanCredits(INT32 choice); +void M_HandleAddons(INT32 choice); void M_DrawGenericMenu(void); +void M_DrawCenteredMenu(void); +void M_DrawChecklist(void); +void M_DrawLevelStats(void); +void M_DrawReplayHut(void); +void M_DrawTimeAttackMenu(void); void M_DrawMPMainMenu(void); void M_DrawSetupMultiPlayerMenu(void); void M_DrawServerMenu(void); @@ -408,6 +433,7 @@ void M_DrawVideoMenu(void); void M_DrawVideoMode(void); void M_DrawSkyRoom(void); void M_DrawHUDOptions(void); +void M_DrawAddons(void); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); @@ -494,6 +520,7 @@ extern description_t description[MAXSKINS]; extern consvar_t cv_showfocuslost; extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; +extern consvar_t cv_dummygpdifficulty, cv_dummygpencore, cv_dummygpcup; extern CV_PossibleValue_t gametype_cons_t[]; extern char dummystaffname[22]; From f3226c84a45081c8b98526537460c48f89d0c37a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 19 Mar 2025 00:41:49 +0100 Subject: [PATCH 06/33] SOC the pause menus Oops, I reopened pandora's box :^) --- src/deh_soc.c | 6 ++++ src/deh_tables.c | 38 ++++++++++++++++---- src/m_menu.c | 93 +++++++++++++++++++++--------------------------- src/m_menu.h | 39 ++++++++++++++++---- 4 files changed, 111 insertions(+), 65 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 2bfefad0b..041a1f87e 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2153,6 +2153,12 @@ static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { { "DUMMYGPCUP", &cv_dummygpcup }, { "NEXTMAP", &cv_nextmap }, { "NEWGAMETYPE", &cv_newgametype }, + { "DUMMYRINGS", &cv_dummyrings }, + { "DUMMYLIVES", &cv_dummylives }, + { "DUMMYMENUPLAYER", &cv_dummymenuplayer }, + { "DUMMYTEAM", &cv_dummyteam }, + { "DUMMYSPECTATE", &cv_dummyspectate }, + { "DUMMYSCRAMBLE", &cv_dummyscramble }, { NULL, NULL } }; diff --git a/src/deh_tables.c b/src/deh_tables.c index ca1da9eb3..31d7db051 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -674,14 +674,14 @@ const char *const MENUTYPES_LIST[] = { // MISC // "MESSAGE", - // "SPAUSE", + "SPAUSE", - // "MPAUSE", - // "SCRAMBLETEAM", - // "CHANGETEAM", - // "CHANGELEVEL", + "MPAUSE", + "SCRAMBLETEAM", + "CHANGETEAM", + "CHANGELEVEL", - // "MAPAUSE", + "MAPAUSE", // "HELP", // SRB2Kart @@ -697,6 +697,8 @@ const char *const MENUTYPES_LIST[] = { "MP_OFFLINESERVER", "SP_GRANDPRIX", "MISC_REPLAYHUT", + "MISC_DISCORDREQUESTS", + "CHANGESPECTATE", "SPECIAL" }; @@ -747,12 +749,35 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "CREDITS", &M_Credits }, { "BLANCREDITS", &M_BlanCredits }, { "HANDLEADDONS", &M_HandleAddons }, + { "SELECTABLECLEARMENUS", &M_SelectableClearMenus }, + { "MODEATTACKRETRY", &M_ModeAttackRetry }, + { "MODEATTACKENDGAME", &M_ModeAttackEndGame }, + { "PANDORASBOX", &M_PandorasBox }, + { "EMBLEMHINTS", &M_EmblemHints }, + { "RETRY", &M_Retry }, + { "ENDGAME", &M_EndGame }, + { "MAPCHANGE", &M_MapChange }, + { "SETUPMULTIPLAYER", &M_SetupMultiPlayer }, + { "SETUPMULTIPLAYER2", &M_SetupMultiPlayer2 }, + { "SETUPMULTIPLAYER3", &M_SetupMultiPlayer3 }, + { "SETUPMULTIPLAYER4", &M_SetupMultiPlayer4 }, + { "CONFIRMSPECTATE", &M_ConfirmSpectate }, + { "CONFIRMENTERGAME", &M_ConfirmEnterGame }, + { "EXITPANDORASBOX", &M_ExitPandorasBox }, + { "GETALLEMERALDS", &M_GetAllEmeralds }, + { "DESTROYROBOTS", &M_DestroyRobots }, + { "ULTIMATECHEAT", &M_UltimateCheat }, + { "CONFIRMTEAMSCRAMBLE", &M_ConfirmTeamScramble }, + { "CONFIRMTEAMCHANGE", &M_ConfirmTeamChange }, + { "CONFIRMSPECTATECHANGE", &M_ConfirmSpectateChange }, + { "CHANGELEVEL", &M_ChangeLevel }, { NULL, NULL } }; struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWGENERICMENU", &M_DrawGenericMenu }, { "DRAWCENTEREDMENU", &M_DrawCenteredMenu }, + { "DRAWPAUSEMENU", &M_DrawPauseMenu }, { "DRAWCHECKLIST", &M_DrawChecklist }, { "DRAWLEVELSTATS", &M_DrawLevelStats }, { "DRAWREPLAYHUT", &M_DrawReplayHut }, @@ -765,6 +790,7 @@ struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWSKYROOM", &M_DrawSkyRoom }, { "DRAWHUDOPTIONS", &M_DrawHUDOptions }, { "DRAWADDONS", &M_DrawAddons }, + { "DRAWEMBLEMHINTS", &M_DrawEmblemHints }, { NULL, NULL } }; diff --git a/src/m_menu.c b/src/m_menu.c index a6c63c0fb..ae2bca645 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -222,27 +222,12 @@ menu_t SPauseDef; // Sky Room //static void M_CustomLevelSelect(INT32 choice); //static void M_CustomWarp(INT32 choice); -FUNCNORETURN static ATTRNORETURN void M_UltimateCheat(INT32 choice); //static void M_LoadGameLevelSelect(INT32 choice); -static void M_GetAllEmeralds(INT32 choice); -static void M_DestroyRobots(INT32 choice); //static void M_LevelSelectWarp(INT32 choice); -static void M_PandorasBox(INT32 choice); -static void M_EmblemHints(INT32 choice); static char *M_GetConditionString(condition_t cond); menu_t SR_MainDef, SR_UnlockChecklistDef; // Misc. Main Menu -static void M_SelectableClearMenus(INT32 choice); -static void M_Retry(INT32 choice); -static void M_EndGame(INT32 choice); -static void M_MapChange(INT32 choice); -static void M_ChangeLevel(INT32 choice); -static void M_ConfirmSpectate(INT32 choice); -static void M_ConfirmEnterGame(INT32 choice); -static void M_ConfirmTeamScramble(INT32 choice); -static void M_ConfirmTeamChange(INT32 choice); -static void M_ConfirmSpectateChange(INT32 choice); //static void M_SecretsMenu(INT32 choice); //static void M_SetupChoosePlayer(INT32 choice); menu_t SP_MainDef, MP_MainDef, OP_MainDef; @@ -250,7 +235,6 @@ menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef; // Single Player //static void M_ChooseNightsAttack(INT32 choice); -static void M_ModeAttackEndGame(INT32 choice); //static void M_ChoosePlayer(INT32 choice); menu_t SP_LevelStatsDef; static menu_t SP_GrandPrixTempDef; @@ -261,10 +245,6 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; static void M_ConnectMenu(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); -static void M_SetupMultiPlayer(INT32 choice); -static void M_SetupMultiPlayer2(INT32 choice); -static void M_SetupMultiPlayer3(INT32 choice); -static void M_SetupMultiPlayer4(INT32 choice); // Options // Split into multiple parts due to size @@ -329,8 +309,6 @@ static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the butto // Drawing functions static void M_DrawGenericBackgroundMenu(void); static void M_DrawMusicTest(void); -static void M_DrawEmblemHints(void); -static void M_DrawPauseMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); static void M_DrawImageDef(void); //static void M_DrawLoad(void); @@ -342,7 +320,6 @@ static void M_DrawConnectMenu(void); static void M_DrawJoystick(void); // Handling functions -static void M_ExitPandorasBox(INT32 choice); static void M_HandleMusicTest(INT32 choice); static void M_HandleImageDef(INT32 choice); //static void M_HandleLoadSave(INT32 choice); @@ -358,7 +335,7 @@ static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) -menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef; +menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef, MPauseDef, MAPauseDef, SR_EmblemHintDef, SR_PandoraDef, MISC_ChangeLevelDef; menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_CAMERA] = &OP_CamOptionsDef, [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, @@ -401,9 +378,19 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_SR_UNLOCKCHECKLIST] = &SR_UnlockChecklistDef, [MN_SP_LEVELSTATS] = &SP_LevelStatsDef, [MN_MISC_REPLAYHUT] = &MISC_ReplayHutDef, + [MN_SR_EMBLEMHINT] = &SR_EmblemHintDef, + [MN_SR_PANDORA] = &SR_PandoraDef, [MN_AD_MAIN] = &MISC_AddonsDef, + [MN_SPAUSE] = &SPauseDef, + [MN_MPAUSE] = &MPauseDef, + [MN_SCRAMBLETEAM] = &MISC_ScrambleTeamDef, + [MN_CHANGETEAM] = &MISC_ChangeTeamDef, + [MN_MAPAUSE] = &MAPauseDef, + [MN_CHANGESPECTATE] = &MISC_ChangeSpectateDef, + [MN_CHANGELEVEL] = &MISC_ChangeLevelDef, + [MN_MAIN] = &MainDef, [MN_FIRSTFREESLOT] = &FreeslotTest, @@ -477,12 +464,12 @@ static CV_PossibleValue_t liveslimit_cons_t[] = {{-1, "MIN"}, {9, "MAX"}, {0, NU };*/ static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, NULL}}; -static consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange); -static consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDEN, dummyteam_cons_t, NULL); -static consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDEN, dummyspectate_cons_t, NULL); -static consvar_t cv_dummyscramble = CVAR_INIT ("dummyscramble", "Random", CV_HIDEN, dummyscramble_cons_t, NULL); -static consvar_t cv_dummyrings = CVAR_INIT ("dummyrings", "0", CV_HIDEN, ringlimit_cons_t, NULL); -static consvar_t cv_dummylives = CVAR_INIT ("dummylives", "0", CV_HIDEN, liveslimit_cons_t, NULL); +consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange); +consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDEN, dummyteam_cons_t, NULL); +consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDEN, dummyspectate_cons_t, NULL); +consvar_t cv_dummyscramble = CVAR_INIT ("dummyscramble", "Random", CV_HIDEN, dummyscramble_cons_t, NULL); +consvar_t cv_dummyrings = CVAR_INIT ("dummyrings", "0", CV_HIDEN, ringlimit_cons_t, NULL); +consvar_t cv_dummylives = CVAR_INIT ("dummylives", "0", CV_HIDEN, liveslimit_cons_t, NULL); static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange); static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {3, "Master"}, {0, NULL}}; @@ -4067,7 +4054,7 @@ static void M_DrawGenericBackgroundMenu(void) M_DrawGenericMenu(); } -static void M_DrawPauseMenu(void) +void M_DrawPauseMenu(void) { #if 0 if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) @@ -6252,7 +6239,7 @@ static void M_PlaybackQuit(INT32 choice) D_StartTitle(); } -static void M_PandorasBox(INT32 choice) +void M_PandorasBox(INT32 choice) { (void)choice; CV_StealthSetValue(&cv_dummyrings, players[consoleplayer].rings); @@ -6260,7 +6247,7 @@ static void M_PandorasBox(INT32 choice) M_SetupNextMenu(&SR_PandoraDef); } -static void M_ExitPandorasBox(INT32 choice) +void M_ExitPandorasBox(INT32 choice) { (void)choice; if (cv_dummyrings.value != players[consoleplayer].rings) @@ -6269,7 +6256,7 @@ static void M_ExitPandorasBox(INT32 choice) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); } -static void M_ChangeLevel(INT32 choice) +void M_ChangeLevel(INT32 choice) { (void)choice; INT16 map = cv_nextmap.value ? cv_nextmap.value : G_RandMap(G_TOLFlag(cv_newgametype.value), gamestate == GS_LEVEL ? gamemap-1 : prevmap, 0, 0, false, NULL); @@ -6277,7 +6264,7 @@ static void M_ChangeLevel(INT32 choice) COM_BufAddText(va("map %d -gametype \"%s\"\n", map, cv_newgametype.string)); } -static void M_ConfirmSpectate(INT32 choice) +void M_ConfirmSpectate(INT32 choice) { (void)choice; // We allow switching to spectator even if team changing is not allowed @@ -6285,7 +6272,7 @@ static void M_ConfirmSpectate(INT32 choice) COM_ImmedExecute("changeteam spectator"); } -static void M_ConfirmEnterGame(INT32 choice) +void M_ConfirmEnterGame(INT32 choice) { (void)choice; if (!cv_allowteamchange.value) @@ -6297,7 +6284,7 @@ static void M_ConfirmEnterGame(INT32 choice) COM_ImmedExecute("changeteam playing"); } -static void M_ConfirmTeamScramble(INT32 choice) +void M_ConfirmTeamScramble(INT32 choice) { (void)choice; M_ClearMenus(true); @@ -6305,7 +6292,7 @@ static void M_ConfirmTeamScramble(INT32 choice) COM_ImmedExecute(va("teamscramble %d", cv_dummyscramble.value+1)); } -static void M_ConfirmTeamChange(INT32 choice) +void M_ConfirmTeamChange(INT32 choice) { (void)choice; @@ -6338,7 +6325,7 @@ static void M_ConfirmTeamChange(INT32 choice) } } -static void M_ConfirmSpectateChange(INT32 choice) +void M_ConfirmSpectateChange(INT32 choice) { (void)choice; @@ -6414,13 +6401,13 @@ static void M_RetryResponse(INT32 ch) G_SetRetryFlag(); } -static void M_Retry(INT32 choice) +void M_Retry(INT32 choice) { (void)choice; M_StartMessage(va("Start this %s over?\n\n(Press 'Y' to confirm)\n", (gametyperules & GTR_CIRCUIT) ? "race" : "battle"),FUNCPTRCAST(M_RetryResponse),MM_YESNO); } -static void M_SelectableClearMenus(INT32 choice) +void M_SelectableClearMenus(INT32 choice) { (void)choice; M_ClearMenus(true); @@ -6444,13 +6431,13 @@ void M_RefreshPauseMenu(void) // CHEATS // ====== -static void M_UltimateCheat(INT32 choice) +ATTRNORETURN void FUNCNORETURN M_UltimateCheat(INT32 choice) { (void)choice; I_Quit(); } -static void M_GetAllEmeralds(INT32 choice) +void M_GetAllEmeralds(INT32 choice) { (void)choice; @@ -6471,7 +6458,7 @@ static void M_DestroyRobotsResponse(INT32 ch) G_SetGameModified(multiplayer, true); } -static void M_DestroyRobots(INT32 choice) +void M_DestroyRobots(INT32 choice) { (void)choice; @@ -6616,7 +6603,7 @@ void M_DrawChecklist(void) #undef NUMCHECKLIST #define NUMHINTS 5 -static void M_EmblemHints(INT32 choice) +void M_EmblemHints(INT32 choice) { (void)choice; SR_EmblemHintMenu[0].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); @@ -6624,7 +6611,7 @@ static void M_EmblemHints(INT32 choice) itemOn = 1; // always start on back. } -static void M_DrawEmblemHints(void) +void M_DrawEmblemHints(void) { INT32 i, j = 0; UINT32 collected = 0; @@ -8809,7 +8796,7 @@ void M_ModeAttackRetry(INT32 choice) M_ChooseTimeAttack(0); } -static void M_ModeAttackEndGame(INT32 choice) +void M_ModeAttackEndGame(INT32 choice) { (void)choice; G_CheckDemoStatus(); // Cancel recording @@ -8845,7 +8832,7 @@ static void M_ExitGameResponse(INT32 ch) M_ClearMenus(true); } -static void M_EndGame(INT32 choice) +void M_EndGame(INT32 choice) { (void)choice; if (demo.playback) @@ -9503,7 +9490,7 @@ void M_DrawServerMenu(void) M_DrawGenericMenu(); } -static void M_MapChange(INT32 choice) +void M_MapChange(INT32 choice) { (void)choice; @@ -10324,7 +10311,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) } // start the multiplayer setup menu -static void M_SetupMultiPlayer(INT32 choice) +void M_SetupMultiPlayer(INT32 choice) { (void)choice; @@ -10369,7 +10356,7 @@ static void M_SetupMultiPlayer(INT32 choice) } // start the multiplayer setup menu, for secondary player (splitscreen mode) -static void M_SetupMultiPlayer2(INT32 choice) +void M_SetupMultiPlayer2(INT32 choice) { (void)choice; @@ -10413,7 +10400,7 @@ static void M_SetupMultiPlayer2(INT32 choice) } // start the multiplayer setup menu, for third player (splitscreen mode) -static void M_SetupMultiPlayer3(INT32 choice) +void M_SetupMultiPlayer3(INT32 choice) { (void)choice; @@ -10457,7 +10444,7 @@ static void M_SetupMultiPlayer3(INT32 choice) } // start the multiplayer setup menu, for third player (splitscreen mode) -static void M_SetupMultiPlayer4(INT32 choice) +void M_SetupMultiPlayer4(INT32 choice) { (void)choice; diff --git a/src/m_menu.h b/src/m_menu.h index 316c3755b..47e3a363f 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -128,14 +128,14 @@ typedef enum // MISC // MN_MESSAGE, - // MN_SPAUSE, + MN_SPAUSE, - // MN_MPAUSE, - // MN_SCRAMBLETEAM, - // MN_CHANGETEAM, - // MN_CHANGELEVEL, + MN_MPAUSE, + MN_SCRAMBLETEAM, + MN_CHANGETEAM, + MN_CHANGELEVEL, - // MN_MAPAUSE, + MN_MAPAUSE, // MN_HELP, // SRB2Kart @@ -151,6 +151,8 @@ typedef enum MN_MP_OFFLINESERVER, MN_SP_GRANDPRIX, MN_MISC_REPLAYHUT, + MN_MISC_DISCORDREQUESTS, + MN_CHANGESPECTATE, MN_SPECIAL, @@ -419,9 +421,31 @@ void M_Manual(INT32 choice); void M_Credits(INT32 choice); void M_BlanCredits(INT32 choice); void M_HandleAddons(INT32 choice); +void M_SelectableClearMenus(INT32 choice); +void M_ModeAttackEndGame(INT32 choice); +void M_PandorasBox(INT32 choice); +void M_EmblemHints(INT32 choice); +void M_Retry(INT32 choice); +void M_EndGame(INT32 choice); +void M_MapChange(INT32 choice); +void M_SetupMultiPlayer(INT32 choice); +void M_SetupMultiPlayer2(INT32 choice); +void M_SetupMultiPlayer3(INT32 choice); +void M_SetupMultiPlayer4(INT32 choice); +void M_ConfirmSpectate(INT32 choice); +void M_ConfirmEnterGame(INT32 choice); +void M_ExitPandorasBox(INT32 choice); +void M_GetAllEmeralds(INT32 choice); +void M_DestroyRobots(INT32 choice); +ATTRNORETURN void FUNCNORETURN M_UltimateCheat(INT32 choice); +void M_ConfirmTeamScramble(INT32 choice); +void M_ConfirmTeamChange(INT32 choice); +void M_ConfirmSpectateChange(INT32 choice); +void M_ChangeLevel(INT32 choice); void M_DrawGenericMenu(void); void M_DrawCenteredMenu(void); +void M_DrawPauseMenu(void); void M_DrawChecklist(void); void M_DrawLevelStats(void); void M_DrawReplayHut(void); @@ -434,6 +458,7 @@ void M_DrawVideoMode(void); void M_DrawSkyRoom(void); void M_DrawHUDOptions(void); void M_DrawAddons(void); +void M_DrawEmblemHints(void); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); @@ -521,6 +546,8 @@ extern description_t description[MAXSKINS]; extern consvar_t cv_showfocuslost; extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; extern consvar_t cv_dummygpdifficulty, cv_dummygpencore, cv_dummygpcup; +extern consvar_t cv_dummyrings, cv_dummylives; +extern consvar_t cv_dummymenuplayer, cv_dummyteam, cv_dummyspectate, cv_dummyscramble; extern CV_PossibleValue_t gametype_cons_t[]; extern char dummystaffname[22]; From 3d016d4009a52ea455054fb6b8a635e0f731ddae Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 19 Mar 2025 13:47:42 +0100 Subject: [PATCH 07/33] Sweep through the remaining menus Server list remains untouched because I can't test it --- src/deh_soc.c | 10 ++++-- src/deh_tables.c | 31 +++++++++++++++- src/m_menu.c | 93 +++++++++++++++++++----------------------------- src/m_menu.h | 31 +++++++++++++++- 4 files changed, 104 insertions(+), 61 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 041a1f87e..452db4231 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2219,6 +2219,8 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) flags = IT_WHITESTRING; else if (fastcmp(word+4, "DISABLED")) flags = IT_DISABLED; + else if (fastcmp(word+4, "2")) + flags = IT_STRING2; else if (word[4]) { deh_warning("MenuItem %s: unknown word '%s'", "", word); @@ -2288,7 +2290,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) menuitem->status |= IT_SUBMENU; menuitem->itemaction.submenu = menunum2menudef[mn]; } - else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER")) + else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS")) { UINT16 flags; if (word[0] == 'C') @@ -2302,8 +2304,12 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } } - else + else if (word[0] == 'K') flags = IT_KEYHANDLER; + else if (word[0] == 'A') + flags = IT_ARROWS; + else + I_Error("bruh"); // i should probably just make "CALL" the stem for all of these if (actionset) { diff --git a/src/deh_tables.c b/src/deh_tables.c index 31d7db051..bbfe9de2f 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -682,7 +682,7 @@ const char *const MENUTYPES_LIST[] = { "CHANGELEVEL", "MAPAUSE", - // "HELP", + "HELP", // SRB2Kart "OP_HUD", @@ -699,6 +699,9 @@ const char *const MENUTYPES_LIST[] = { "MISC_REPLAYHUT", "MISC_DISCORDREQUESTS", "CHANGESPECTATE", + "MISC_REPLAYSTART", + "PLAYBACK", + "OP_CONTROLSETUP", "SPECIAL" }; @@ -771,6 +774,25 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "CONFIRMTEAMCHANGE", &M_ConfirmTeamChange }, { "CONFIRMSPECTATECHANGE", &M_ConfirmSpectateChange }, { "CHANGELEVEL", &M_ChangeLevel }, + { "HUTSTARTREPLAY", &M_HutStartReplay }, + { "PLAYBACKREWIND", &M_PlaybackRewind }, + { "PLAYBACKPAUSE", &M_PlaybackPause }, + { "PLAYBACKFASTFORWARD", &M_PlaybackFastForward }, + { "PLAYBACKADVANCE", &M_PlaybackAdvance }, + { "PLAYBACKSETVIEWS", &M_PlaybackSetViews }, + { "PLAYBACKADJUSTVIEW", &M_PlaybackAdjustView }, + { "PLAYBACKTOGGLEFREECAM", &M_PlaybackToggleFreecam }, + { "PLAYBACKQUIT", &M_PlaybackQuit }, + { "HANDLEIMAGEDEF", &M_HandleImageDef }, + { "HANDLEMUSICTEST", &M_HandleMusicTest }, + { "SETUP1PJOYSTICKMENU", &M_Setup1PJoystickMenu }, + { "SETUP2PJOYSTICKMENU", &M_Setup2PJoystickMenu }, + { "SETUP3PJOYSTICKMENU", &M_Setup3PJoystickMenu }, + { "SETUP4PJOYSTICKMENU", &M_Setup4PJoystickMenu }, + { "RESETCONTROLS", &M_ResetControls }, + { "CHANGECONTROL", &M_ChangeControl }, + { "ASSIGNJOYSTICK", &M_AssignJoystick }, + { "HANDLEMONITORTOGGLES", &M_HandleMonitorToggles }, { NULL, NULL } }; @@ -791,6 +813,13 @@ struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWHUDOPTIONS", &M_DrawHUDOptions }, { "DRAWADDONS", &M_DrawAddons }, { "DRAWEMBLEMHINTS", &M_DrawEmblemHints }, + { "DRAWREPLAYSTARTMENU", &M_DrawReplayStartMenu }, + { "DRAWPLAYBACKMENU", &M_DrawPlaybackMenu }, + { "DRAWIMAGEDEF", &M_DrawImageDef }, + { "DRAWMUSICTEST", &M_DrawMusicTest }, + { "DRAWCONTROL", &M_DrawControl }, + { "DRAWJOYSTICK", &M_DrawJoystick }, + { "DRAWMONITORTOGGLES", &M_DrawMonitorToggles }, { NULL, NULL } }; diff --git a/src/m_menu.c b/src/m_menu.c index ae2bca645..d1416144a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -252,15 +252,6 @@ static void M_Connect(INT32 choice); menu_t OP_ControlsDef, OP_AllControlsDef; menu_t OP_MouseOptionsDef; -static void M_Setup1PJoystickMenu(INT32 choice); -static void M_Setup2PJoystickMenu(INT32 choice); -static void M_Setup3PJoystickMenu(INT32 choice); -static void M_Setup4PJoystickMenu(INT32 choice); - -static void M_AssignJoystick(INT32 choice); -static void M_ChangeControl(INT32 choice); -static void M_ResetControls(INT32 choice); - //camera options menu menu_t OP_CamOptionsDef; menu_t OP_Player1CamOptionsDef, OP_Player2CamOptionsDef, OP_Player3CamOptionsDef, OP_Player4CamOptionsDef; @@ -291,39 +282,19 @@ static patch_t *addonsp[NUM_EXT+5]; // Replay hut menu_t MISC_ReplayHutDef; menu_t MISC_ReplayOptionsDef; -static void M_DrawReplayStartMenu(void); -static void M_HutStartReplay(INT32 choice); - -static void M_DrawPlaybackMenu(void); -static void M_PlaybackRewind(INT32 choice); -static void M_PlaybackPause(INT32 choice); -static void M_PlaybackFastForward(INT32 choice); -static void M_PlaybackAdvance(INT32 choice); -static void M_PlaybackSetViews(INT32 choice); -static void M_PlaybackAdjustView(INT32 choice); -static void M_PlaybackToggleFreecam(INT32 choice); -static void M_PlaybackQuit(INT32 choice); static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked // Drawing functions static void M_DrawGenericBackgroundMenu(void); -static void M_DrawMusicTest(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); -static void M_DrawImageDef(void); //static void M_DrawLoad(void); //static void M_DrawNightsAttackMenu(void); //static void M_DrawSetupChoosePlayerMenu(void); -static void M_DrawControl(void); -static void M_DrawMonitorToggles(void); static void M_DrawConnectMenu(void); -static void M_DrawJoystick(void); // Handling functions -static void M_HandleMusicTest(INT32 choice); -static void M_HandleImageDef(INT32 choice); //static void M_HandleLoadSave(INT32 choice); -static void M_HandleMonitorToggles(INT32 choice); // uhhhhhh hack? static void M_ChangecontrolResponse(event_t *ev); @@ -335,7 +306,7 @@ static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) -menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef, MPauseDef, MAPauseDef, SR_EmblemHintDef, SR_PandoraDef, MISC_ChangeLevelDef; +menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef, MPauseDef, MAPauseDef, SR_EmblemHintDef, SR_PandoraDef, MISC_ChangeLevelDef, MISC_ReplayStartDef, PlaybackMenuDef, MISC_HelpDef, SR_MusicTestDef, OP_JoystickSetDef; menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_CAMERA] = &OP_CamOptionsDef, [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, @@ -344,7 +315,7 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_P4CAMERA] = &OP_Player4CamOptionsDef, [MN_OP_MAIN] = &OP_MainDef, - [MN_OP_CHANGECONTROLS] = &OP_ControlsDef, + [MN_OP_CONTROLSETUP] = &OP_ControlsDef, [MN_OP_VIDEO] = &OP_VideoOptionsDef, [MN_OP_VIDEOMODE] = &OP_VideoModeDef, [MN_OP_OPENGL] = &OP_OpenGLOptionsDef, @@ -391,6 +362,14 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_CHANGESPECTATE] = &MISC_ChangeSpectateDef, [MN_CHANGELEVEL] = &MISC_ChangeLevelDef, + // who even cares how i sort this shit anymore + [MN_MISC_REPLAYSTART] = &MISC_ReplayStartDef, + [MN_PLAYBACK] = &PlaybackMenuDef, + [MN_HELP] = &MISC_HelpDef, + [MN_SR_SOUNDTEST] = &SR_MusicTestDef, + [MN_OP_CHANGECONTROLS] = &OP_AllControlsDef, + [MN_OP_JOYSTICKSET] = &OP_JoystickSetDef, + [MN_MAIN] = &MainDef, [MN_FIRSTFREESLOT] = &FreeslotTest, @@ -4762,7 +4741,7 @@ static void M_StopMessage(INT32 choice) // Draw an Image Def. Aka, Help images. // Defines what image is used in (menuitem_t)->text. // You can even put multiple images in one menu! -static void M_DrawImageDef(void) +void M_DrawImageDef(void) { patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); if (patch->width <= BASEVIDWIDTH) @@ -4790,7 +4769,7 @@ static void M_DrawImageDef(void) // Handles the ImageDefs. Just a specialized function that // uses left and right movement. -static void M_HandleImageDef(INT32 choice) +void M_HandleImageDef(INT32 choice) { boolean exitmenu = false; @@ -5833,7 +5812,7 @@ void M_DrawReplayHut(void) } } -static void M_DrawReplayStartMenu(void) +void M_DrawReplayStartMenu(void) { const char *warning; UINT8 i; @@ -5958,7 +5937,7 @@ void M_QuitReplayHut(INT32 choice) demo.inreplayhut = false; } -static void M_HutStartReplay(INT32 choice) +void M_HutStartReplay(INT32 choice) { (void)choice; @@ -5974,7 +5953,7 @@ void M_SetPlaybackMenuPointer(void) itemOn = playback_pause; } -static void M_DrawPlaybackMenu(void) +void M_DrawPlaybackMenu(void) { INT16 i; patch_t *icon; @@ -6105,7 +6084,7 @@ static void M_DrawPlaybackMenu(void) } } -static void M_PlaybackRewind(INT32 choice) +void M_PlaybackRewind(INT32 choice) { static tic_t lastconfirmtime; @@ -6131,7 +6110,7 @@ static void M_PlaybackRewind(INT32 choice) CV_SetValue(&cv_playbackspeed, 1); } -static void M_PlaybackPause(INT32 choice) +void M_PlaybackPause(INT32 choice) { (void)choice; @@ -6151,7 +6130,7 @@ static void M_PlaybackPause(INT32 choice) CV_SetValue(&cv_playbackspeed, 1); } -static void M_PlaybackFastForward(INT32 choice) +void M_PlaybackFastForward(INT32 choice) { (void)choice; @@ -6164,7 +6143,7 @@ static void M_PlaybackFastForward(INT32 choice) CV_SetValue(&cv_playbackspeed, cv_playbackspeed.value == 1 ? 4 : 1); } -static void M_PlaybackAdvance(INT32 choice) +void M_PlaybackAdvance(INT32 choice) { (void)choice; @@ -6174,7 +6153,7 @@ static void M_PlaybackAdvance(INT32 choice) } -static void M_PlaybackSetViews(INT32 choice) +void M_PlaybackSetViews(INT32 choice) { if (demo.freecam) @@ -6192,13 +6171,13 @@ static void M_PlaybackSetViews(INT32 choice) } } -static void M_PlaybackAdjustView(INT32 choice) +void M_PlaybackAdjustView(INT32 choice) { G_AdjustView(itemOn - playback_viewcount, (choice > 0) ? 1 : -1, true); } // this one's rather tricky -static void M_PlaybackToggleFreecam(INT32 choice) +void M_PlaybackToggleFreecam(INT32 choice) { (void)choice; M_ClearMenus(true); @@ -6223,7 +6202,7 @@ static void M_PlaybackToggleFreecam(INT32 choice) } -static void M_PlaybackQuit(INT32 choice) +void M_PlaybackQuit(INT32 choice) { (void)choice; G_StopDemo(); @@ -6785,7 +6764,7 @@ void M_MusicTest(INT32 choice) M_SetupNextMenu(&SR_MusicTestDef); } -static void M_DrawMusicTest(void) +void M_DrawMusicTest(void) { INT32 x, y, i; @@ -7001,7 +6980,7 @@ static void M_DrawMusicTest(void) } } -static void M_HandleMusicTest(INT32 choice) +void M_HandleMusicTest(INT32 choice) { boolean exitmenu = false; // exit to previous menu @@ -10743,7 +10722,7 @@ void M_ScreenshotOptions(INT32 choice) // Start the controls menu, setting it up for either the console player, // or the secondary splitscreen player -static void M_DrawJoystick(void) +void M_DrawJoystick(void) { INT32 i; INT32 compareval; @@ -10805,31 +10784,31 @@ void M_SetupJoystickMenu(INT32 choice) M_SetupNextMenu(&OP_JoystickSetDef); } -static void M_Setup1PJoystickMenu(INT32 choice) +void M_Setup1PJoystickMenu(INT32 choice) { setupcontrolplayer = 1; M_SetupJoystickMenu(choice); } -static void M_Setup2PJoystickMenu(INT32 choice) +void M_Setup2PJoystickMenu(INT32 choice) { setupcontrolplayer = 2; M_SetupJoystickMenu(choice); } -static void M_Setup3PJoystickMenu(INT32 choice) +void M_Setup3PJoystickMenu(INT32 choice) { setupcontrolplayer = 3; M_SetupJoystickMenu(choice); } -static void M_Setup4PJoystickMenu(INT32 choice) +void M_Setup4PJoystickMenu(INT32 choice) { setupcontrolplayer = 4; M_SetupJoystickMenu(choice); } -static void M_AssignJoystick(INT32 choice) +void M_AssignJoystick(INT32 choice) { const UINT8 p = setupcontrolplayer-1; @@ -11008,7 +10987,7 @@ void M_Setup4PControlsMenu(INT32 choice) #define controlheight 18 // Draws the Customise Controls menu -static void M_DrawControl(void) +void M_DrawControl(void) { char tmp[32*MAXINPUTMAPPING]; // should be enough :^) INT32 x, y, w, i, max, cursory = 0, iter; @@ -11228,7 +11207,7 @@ static void M_ChangecontrolResponse(event_t *ev) M_StopMessage(0); } -static void M_ChangeControl(INT32 choice) +void M_ChangeControl(INT32 choice) { // This buffer assumes a 35-character message (per below) plus a max control name limit of 32 chars (per controltochangetext) // If you change the below message, then change the size of this buffer! @@ -11265,7 +11244,7 @@ static void M_ResetControlsResponse(INT32 ch) S_StartSound(NULL, sfx_s224); } -static void M_ResetControls(INT32 choice) +void M_ResetControls(INT32 choice) { (void)choice; M_StartMessage(va(M_GetText("Reset Player %d's controls to defaults?\n\n(Press 'Y' to confirm)\n"), setupcontrolplayer), FUNCPTRCAST(M_ResetControlsResponse), MM_YESNO); @@ -11561,7 +11540,7 @@ void M_HandleVideoMode(INT32 ch) static tic_t shitsfree = 0; -static void M_DrawMonitorToggles(void) +void M_DrawMonitorToggles(void) { const INT32 edges = 4; const INT32 height = 4; @@ -11732,7 +11711,7 @@ static void M_DrawMonitorToggles(void) V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, highlightflags, va("* %s *", currentMenu->menuitems[itemOn].text)); } -static void M_HandleMonitorToggles(INT32 choice) +void M_HandleMonitorToggles(INT32 choice) { const INT32 width = 6, height = 4; INT32 column = itemOn/height, row = itemOn%height; diff --git a/src/m_menu.h b/src/m_menu.h index 47e3a363f..a342df50d 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -136,7 +136,7 @@ typedef enum MN_CHANGELEVEL, MN_MAPAUSE, - // MN_HELP, + MN_HELP, // SRB2Kart MN_OP_HUD, @@ -153,6 +153,9 @@ typedef enum MN_MISC_REPLAYHUT, MN_MISC_DISCORDREQUESTS, MN_CHANGESPECTATE, + MN_MISC_REPLAYSTART, + MN_PLAYBACK, + MN_OP_CONTROLSETUP, MN_SPECIAL, @@ -442,6 +445,25 @@ void M_ConfirmTeamScramble(INT32 choice); void M_ConfirmTeamChange(INT32 choice); void M_ConfirmSpectateChange(INT32 choice); void M_ChangeLevel(INT32 choice); +void M_HutStartReplay(INT32 choice); +void M_PlaybackRewind(INT32 choice); +void M_PlaybackPause(INT32 choice); +void M_PlaybackFastForward(INT32 choice); +void M_PlaybackAdvance(INT32 choice); +void M_PlaybackSetViews(INT32 choice); +void M_PlaybackAdjustView(INT32 choice); +void M_PlaybackToggleFreecam(INT32 choice); +void M_PlaybackQuit(INT32 choice); +void M_HandleImageDef(INT32 choice); +void M_HandleMusicTest(INT32 choice); +void M_Setup1PJoystickMenu(INT32 choice); +void M_Setup2PJoystickMenu(INT32 choice); +void M_Setup3PJoystickMenu(INT32 choice); +void M_Setup4PJoystickMenu(INT32 choice); +void M_ResetControls(INT32 choice); +void M_ChangeControl(INT32 choice); +void M_AssignJoystick(INT32 choice); +void M_HandleMonitorToggles(INT32 choice); void M_DrawGenericMenu(void); void M_DrawCenteredMenu(void); @@ -459,6 +481,13 @@ void M_DrawSkyRoom(void); void M_DrawHUDOptions(void); void M_DrawAddons(void); void M_DrawEmblemHints(void); +void M_DrawReplayStartMenu(void); +void M_DrawPlaybackMenu(void); +void M_DrawImageDef(void); +void M_DrawMusicTest(void); +void M_DrawControl(void); +void M_DrawJoystick(void); +void M_DrawMonitorToggles(void); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); From 8abf268cf45a87497b6df7546762a68e67ae8cb1 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 19 Mar 2025 15:11:35 +0100 Subject: [PATCH 08/33] Expose gamecontrol constants Not gonna leave control setup broken until the Lua input library is merged --- src/deh_tables.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index bbfe9de2f..e4e0f1f97 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -27,6 +27,7 @@ #include "r_data.h" // patchalphastyle_t #include "k_boss.h" // spottype_t (for lua) #include "k_follower.h" // followermode_t (for lua) +#include "g_input.h" // Game controls (for lua) #include "deh_tables.h" @@ -1456,6 +1457,41 @@ struct int_const_s const INT_CONST[] = { {"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS}, {"GS_BLANCREDITS",GS_BLANCREDITS}, + // Game controls + {"GC_NULL",gc_null}, + {"GC_AIMFORWARD",gc_aimforward}, + {"GC_AIMBACKWARD",gc_aimbackward}, + {"GC_TURNLEFT",gc_turnleft}, + {"GC_TURNRIGHT",gc_turnright}, + {"GC_ACCELERATE",gc_accelerate}, + {"GC_DRIFT",gc_drift}, + {"GC_BRAKE",gc_brake}, + {"GC_FIRE",gc_fire}, + {"GC_LOOKBACK",gc_lookback}, + {"GC_CAMRESET",gc_camreset}, + {"GC_CAMTOGGLE",gc_camtoggle}, + {"GC_SPECTATE",gc_spectate}, + {"GC_LOOKUP",gc_lookup}, + {"GC_LOOKDOWN",gc_lookdown}, + {"GC_CENTERVIEW",gc_centerview}, + {"GC_TALKKEY",gc_talkkey}, + {"GC_TEAMKEY",gc_teamkey}, + {"GC_SCORES",gc_scores}, + {"GC_CONSOLE",gc_console}, + {"GC_PAUSE",gc_pause}, + {"GC_SYSTEMMENU",gc_systemmenu}, + {"GC_SCREENSHOT",gc_screenshot}, + {"GC_RECORDGIF",gc_recordgif}, + {"GC_VIEWPOINT",gc_viewpoint}, + {"GC_CUSTOM1",gc_custom1}, + {"GC_CUSTOM2",gc_custom2}, + {"GC_CUSTOM3",gc_custom3}, + {"NUM_GAMECONTROLS",num_gamecontrols}, + + // screen.h constants + {"BASEVIDWIDTH", BASEVIDWIDTH}, + {"BASEVIDHEIGHT", BASEVIDHEIGHT}, + // SRB2Kart // kartitems_t #define FOREACH( name, n ) { TOSTR (KITEM_ ## name), KITEM_ ## name } @@ -1512,10 +1548,6 @@ struct int_const_s const INT_CONST[] = { {"KARTSPEED_EASY", KARTSPEED_EASY}, {"KARTSPEED_NORMAL", KARTSPEED_NORMAL}, {"KARTSPEED_HARD", KARTSPEED_HARD}, - - // screen.h constants - {"BASEVIDWIDTH", BASEVIDWIDTH}, - {"BASEVIDHEIGHT", BASEVIDHEIGHT}, // Custom client features exposed to lua {"FEATURE_INTERMISSIONHUD",1}, // This is to trick kart luas that look for this since its already here. From bb3688a8c395c511ed7191e953c9ae6061685deb Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 19 Mar 2025 17:13:27 +0100 Subject: [PATCH 09/33] Remove commented out stuff in m_menu.c --- src/m_menu.c | 1324 +------------------------------------------------- 1 file changed, 6 insertions(+), 1318 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index d1416144a..db3a3df1d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -148,9 +148,6 @@ const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 description_t description[MAXSKINS]; -//static char *char_notes = NULL; -//static fixed_t char_scroll = 0; - boolean menuactive = false; boolean fromlevelselect = false; @@ -169,8 +166,6 @@ UINT8 maplistoption = 0; static char joystickInfo[MAXGAMEPADS][29]; static UINT32 serverlistpage; -//static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games. - INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 @@ -220,26 +215,17 @@ menu_t SPauseDef; #define lsheadingheight 16 // Sky Room -//static void M_CustomLevelSelect(INT32 choice); -//static void M_CustomWarp(INT32 choice); -//static void M_LoadGameLevelSelect(INT32 choice); -//static void M_LevelSelectWarp(INT32 choice); static char *M_GetConditionString(condition_t cond); menu_t SR_MainDef, SR_UnlockChecklistDef; // Misc. Main Menu -//static void M_SecretsMenu(INT32 choice); -//static void M_SetupChoosePlayer(INT32 choice); menu_t SP_MainDef, MP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef; // Single Player -//static void M_ChooseNightsAttack(INT32 choice); -//static void M_ChoosePlayer(INT32 choice); menu_t SP_LevelStatsDef; static menu_t SP_GrandPrixTempDef; static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; -//static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; // Multiplayer static void M_ConnectMenu(INT32 choice); @@ -262,7 +248,6 @@ menu_t OP_VideoOptionsDef, OP_VideoModeDef; menu_t OP_OpenGLOptionsDef; #endif menu_t OP_SoundOptionsDef; -//static void M_RestartAudio(void); //Misc menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; @@ -272,7 +257,6 @@ menu_t OP_DiscordOptionsDef; menu_t OP_HUDOptionsDef, OP_ChatOptionsDef; menu_t OP_GameOptionsDef, OP_BlanKartGameOptionsDef, OP_ServerOptionsDef; menu_t OP_AdvServerOptionsDef; -//menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; static patch_t *addonsp[NUM_EXT+5]; @@ -288,21 +272,14 @@ static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the butto // Drawing functions static void M_DrawGenericBackgroundMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); -//static void M_DrawLoad(void); -//static void M_DrawNightsAttackMenu(void); -//static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawConnectMenu(void); -// Handling functions -//static void M_HandleLoadSave(INT32 choice); - // uhhhhhh hack? static void M_ChangecontrolResponse(event_t *ev); // Consvar onchange functions static void Newgametype_OnChange(void); static void Dummymenuplayer_OnChange(void); -//static void Dummymares_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) @@ -438,9 +415,6 @@ static CV_PossibleValue_t dummyspectate_cons_t[] = {{0, "Spectator"}, {1, "Playi static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}}; static CV_PossibleValue_t ringlimit_cons_t[] = {{-20, "MIN"}, {20, "MAX"}, {0, NULL}}; static CV_PossibleValue_t liveslimit_cons_t[] = {{-1, "MIN"}, {9, "MAX"}, {0, NULL}}; -/*static CV_PossibleValue_t dummymares_cons_t[] = { - {-1, "END"}, {0,"Overall"}, {1,"Mare 1"}, {2,"Mare 2"}, {3,"Mare 3"}, {4,"Mare 4"}, {5,"Mare 5"}, {6,"Mare 6"}, {7,"Mare 7"}, {8,"Mare 8"}, {0,NULL} -};*/ static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, NULL}}; consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange); @@ -639,7 +613,6 @@ static menuitem_t SPauseMenu[] = // Pandora's Box will be shifted up if both options are available {IT_CALL | IT_STRING, NULL, "Pandora's Box...", {.routine = M_PandorasBox}, 16}, {IT_CALL | IT_STRING, NULL, "Medal Hints...", {.routine = M_EmblemHints}, 24}, - //{IT_CALL | IT_STRING, NULL, "Level Select...", M_LoadGameLevelSelect, 32}, {IT_CALL | IT_STRING, NULL, "Continue", {.routine = M_SelectableClearMenus},48}, {IT_CALL | IT_STRING, NULL, "Retry", {.routine = M_Retry}, 56}, @@ -653,7 +626,6 @@ typedef enum { spause_pandora = 0, spause_hints, - //spause_levelselect, spause_continue, spause_retry, @@ -778,12 +750,6 @@ static menuitem_t SR_MainMenu[] = }; -/*static menuitem_t SR_LevelSelectMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 130}, -};*/ - static menuitem_t SR_UnlockChecklistMenu[] = { {IT_SUBMENU | IT_STRING, NULL, "NEXT", {.submenu = &MainDef}, 192}, @@ -871,18 +837,6 @@ static menuitem_t SP_ReplayMenu[] = {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} }; -/*static menuitem_t SP_NightsReplayMenu[] = -{ - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Score", M_ReplayTimeAttack, 0}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack,16}, - - {IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack,21}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack,29}, - {IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,37}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_NightsAttackDef, 50} -};*/ - static menuitem_t SP_GuestReplayMenu[] = { {IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", {.routine = M_SetGuestReplay}, 94}, @@ -894,17 +848,6 @@ static menuitem_t SP_GuestReplayMenu[] = {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} }; -/*static menuitem_t SP_NightsGuestReplayMenu[] = -{ - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Score as Guest", M_SetGuestReplay, 8}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay,16}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,24}, - - {IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,37}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_NightsAttackDef, 50} -};*/ - static menuitem_t SP_GhostMenu[] = { {IT_STRING|IT_CVAR, NULL, "Best Time", {.cvar = &cv_ghost_besttime}, 88}, @@ -916,30 +859,6 @@ static menuitem_t SP_GhostMenu[] = {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} }; -/*static menuitem_t SP_NightsGhostMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Best Score", &cv_ghost_bestscore, 0}, - {IT_STRING|IT_CVAR, NULL, "Best Time", &cv_ghost_besttime, 8}, - {IT_STRING|IT_CVAR, NULL, "Last", &cv_ghost_last, 16}, - - {IT_STRING|IT_CVAR, NULL, "Guest", &cv_ghost_guest, 29}, - {IT_STRING|IT_CVAR, NULL, "Staff Attack",&cv_ghost_staff, 37}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_NightsAttackDef, 50} -};*/ - -// Single Player Nights Attack -/*static menuitem_t SP_NightsAttackMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 44}, - {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 54}, - - {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108}, - {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118}, - {IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128}, - {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 138}, -};*/ - enum { nalevel, @@ -957,12 +876,6 @@ static menuitem_t SP_LevelStatsMenu[] = {IT_KEYHANDLER | IT_NOTHING, NULL, "", {.routine = M_HandleLevelStats}, '\0'}, // dummy menuitem for the control func }; -// A rare case. -// External files modify this menu, so we can't call it static. -// And I'm too lazy to go through and rename it everywhere. ARRGH! -#define M_ChoosePlayer NULL -menuitem_t PlayerMenu[MAXSKINS]; - // ----------------------------------- // Multiplayer and all of its submenus // ----------------------------------- @@ -982,8 +895,6 @@ static menuitem_t MP_MainMenu[] = {IT_HEADER, NULL, "Join a game", {NULL}, 132-24}, {IT_STRING|IT_CALL, NULL, "Internet server browser...",{.routine = M_ConnectMenuModChecks}, 142-24}, {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", {.routine = M_HandleConnectIP}, 150-24}, - //{IT_HEADER, NULL, "Player setup", NULL, 80}, - //{IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90}, }; static menuitem_t MP_ServerMenu[] = @@ -1299,8 +1210,6 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", {.cvar = &cv_digmusicvolume}, 38}, - //{IT_STRING|IT_CALL, NULL, "Restart Audio System", M_RestartAudio, 50}, - {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", {.cvar = &stereoreverse}, 50}, {IT_STRING|IT_CVAR, NULL, "Surround Sound", {.cvar = &surround}, 60}, @@ -1508,38 +1417,6 @@ static menuitem_t OP_AdvServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Log file transfers", {.cvar = &cv_noticedownload}, 150}, }; -/*static menuitem_t OP_NetgameOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 10}, - {IT_STRING | IT_CVAR, NULL, "Point Limit", &cv_pointlimit, 18}, - - {IT_STRING | IT_CVAR, NULL, "Frantic Items", &cv_kartfrantic, 34}, - - {IT_STRING | IT_CVAR, NULL, "Item Respawn", &cv_itemrespawn, 50}, - {IT_STRING | IT_CVAR, NULL, "Item Respawn Delay", &cv_itemrespawntime, 58}, - - {IT_STRING | IT_CVAR, NULL, "Player Respawn Delay", &cv_respawntime, 74}, - - {IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 90}, - {IT_STRING | IT_CVAR, NULL, "Restrict Skin Changes", &cv_restrictskinchange, 98}, - - //{IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 114}, - //{IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 122}, -};*/ - -/*static menuitem_t OP_GametypeOptionsMenu[] = -{ - {IT_HEADER, NULL, "RACE", NULL, 2}, - {IT_STRING | IT_CVAR, NULL, "Game Speed", &cv_kartspeed, 10}, - {IT_STRING | IT_CVAR, NULL, "Encore Mode", &cv_kartencore, 18}, - {IT_STRING | IT_CVAR, NULL, "Number of Laps", &cv_numlaps, 26}, - {IT_STRING | IT_CVAR, NULL, "Use Map Lap Counts", &cv_usemapnumlaps, 34}, - - {IT_HEADER, NULL, "BATTLE", NULL, 50}, - {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 58}, - {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 66}, -};*/ - //#define ITEMTOGGLEBOTTOMRIGHT static menuitem_t OP_MonitorToggleMenu[] = @@ -1788,8 +1665,6 @@ menu_t SR_PandoraDef = }; menu_t SR_MainDef = CENTERMENUSTYLE(MN_NONE, NULL, SR_MainMenu, &MainDef, 72); -//menu_t SR_LevelSelectDef = MAPICONMENUSTYLE(NULL, SR_LevelSelectMenu, &SR_MainDef); - menu_t SR_UnlockChecklistDef = { MN_NONE, @@ -1831,19 +1706,6 @@ menu_t SR_EmblemHintDef = // Single Player menu_t SP_MainDef = CENTERMENUSTYLE(MN_NONE, NULL, SP_MainMenu, &MainDef, 72); -/*menu_t SP_LoadDef = -{ - MN_NONE, - "M_PICKG", - 1, - &SP_MainDef, - SP_LoadGameMenu, - M_DrawLoad, - 68, 46, - 0, - NULL -}; -menu_t SP_LevelSelectDef = MAPICONMENUSTYLE(NULL, SP_LevelSelectMenu, &SP_LoadDef);*/ menu_t SP_LevelStatsDef = { @@ -1909,19 +1771,6 @@ static menu_t SP_GhostDef = NULL }; -/*menu_t SP_PlayerDef = -{ - MN_NONE, - "M_PICKP", - sizeof (PlayerMenu)/sizeof (menuitem_t),//player_end, - &SP_MainDef, - PlayerMenu, - M_DrawSetupChoosePlayerMenu, - 24, 32, - 0, - NULL -};*/ - // Multiplayer menu_t MP_MainDef = { @@ -2071,9 +1920,6 @@ menu_t OP_BlanKartGameOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_GAME", OP_BlanKa menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 24, 30); menu_t OP_AdvServerOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_AdvServerOptionsMenu, &OP_ServerOptionsDef, 24, 30); -//menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); -//menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); -//menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_GAME", OP_ChatOptionsMenu, &OP_GameOptionsDef, 30, 30); menu_t OP_MonitorToggleDef = { MN_NONE, @@ -2240,24 +2086,6 @@ static void Dummymenuplayer_OnChange(void) CV_StealthSetValue(&cv_dummymenuplayer, 1); } -/*static void Dummymares_OnChange(void) -{ - if (!nightsrecords[cv_nextmap.value-1]) - { - CV_StealthSetValue(&cv_dummymares, 0); - return; - } - else - { - UINT8 mares = nightsrecords[cv_nextmap.value-1]->nummares; - - if (cv_dummymares.value < 0) - CV_StealthSetValue(&cv_dummymares, mares); - else if (cv_dummymares.value > mares) - CV_StealthSetValue(&cv_dummymares, 0); - } -}*/ - char dummystaffname[22]; static void Dummystaff_OnChange(void) @@ -2905,21 +2733,11 @@ boolean M_Responder(event_t *ev) case KEY_DOWNARROW: M_NextOpt(); S_StartSound(NULL, sfx_menu1); - /*if (currentMenu == &SP_PlayerDef) - { - Z_Free(char_notes); - char_notes = NULL; - }*/ return true; case KEY_UPARROW: M_PrevOpt(); S_StartSound(NULL, sfx_menu1); - /*if (currentMenu == &SP_PlayerDef) - { - Z_Free(char_notes); - char_notes = NULL; - }*/ return true; case KEY_LEFTARROW: @@ -2991,7 +2809,7 @@ boolean M_Responder(event_t *ev) multiplayer = false; } - if (currentMenu == &SP_TimeAttackDef) //|| currentMenu == &SP_NightsAttackDef + if (currentMenu == &SP_TimeAttackDef) { // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. menuactive = false; @@ -3215,9 +3033,6 @@ void M_StartControlPanel(void) } else if (!Playing()) { - // Secret menu! - //MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); - currentMenu = &MainDef; itemOn = singleplr; } @@ -3235,37 +3050,11 @@ void M_StartControlPanel(void) } else { - //INT32 numlives = 2; - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); - - /*if (&players[consoleplayer]) - { - numlives = players[consoleplayer].lives; - if (players[consoleplayer].playerstate != PST_LIVE) - ++numlives; - } - - // The list of things that can disable retrying is (was?) a little too complex - // for me to want to use the short if statement syntax - if (numlives <= 1 || G_IsSpecialStage(gamemap)) - SPauseMenu[spause_retry].status = (IT_GRAYEDOUT); - else*/ - SPauseMenu[spause_retry].status = (IT_STRING | IT_CALL); + SPauseMenu[spause_retry].status = (IT_STRING | IT_CALL); } - // We can always use level select though. :33 - //SPauseMenu[spause_levelselect].status = (gamecomplete) ? (IT_STRING | IT_CALL) : (IT_DISABLED); - - // And emblem hints. - SPauseMenu[spause_hints].status = /*(M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) :*/ (IT_DISABLED); - - // Shift up Pandora's Box if both pandora and levelselect are active - /*if (SPauseMenu[spause_pandora].status != (IT_DISABLED) - && SPauseMenu[spause_levelselect].status != (IT_DISABLED)) - SPauseMenu[spause_pandora].alphaKey = 24; - else - SPauseMenu[spause_pandora].alphaKey = 32;*/ + SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); currentMenu = &SPauseDef; itemOn = spause_continue; @@ -3508,8 +3297,6 @@ void M_Ticker(void) // void M_Init(void) { - UINT8 i; - CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); @@ -3558,15 +3345,6 @@ void M_Init(void) quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n...right?\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG6] = M_GetText("Aww, is Eggman's Nightclub too\ndifficult for you?\n\n(Press 'Y' to quit)"); - // Setup PlayerMenu table - for (i = 0; i < MAXSKINS; i++) - { - PlayerMenu[i].status = (i == 0 ? IT_CALL : IT_DISABLED); - PlayerMenu[i].patch = PlayerMenu[i].text = NULL; - PlayerMenu[i].itemaction.routine = M_ChoosePlayer; - PlayerMenu[i].alphaKey = 0; - } - CV_RegisterVar(&cv_serversort); } @@ -3574,15 +3352,6 @@ void M_InitCharacterTables(void) { UINT8 i; - // Setup PlayerMenu table - for (i = 0; i < MAXSKINS; i++) - { - PlayerMenu[i].status = (i < 4 ? IT_CALL : IT_DISABLED); - PlayerMenu[i].patch = PlayerMenu[i].text = NULL; - PlayerMenu[i].itemaction.routine = M_ChoosePlayer; - PlayerMenu[i].alphaKey = 0; - } - // Setup description table for (i = 0; i < MAXSKINS; i++) { @@ -3739,72 +3508,8 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // Solid color textbox. V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159); //V_DrawFill(x+8, y+8, width*8, boxlines*8, 31); -/* - patch_t *p; - INT32 cx, cy, n; - INT32 step, boff; - - step = 8; - boff = 8; - - // draw left side - cx = x; - cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_CACHE)); - cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); - for (n = 0; n < boxlines; n++) - { - V_DrawScaledPatch(cx, cy, V_WRAPY, p); - cy += step; - } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_CACHE)); - - // draw middle - V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); - - cx += boff; - cy = y; - while (width > 0) - { - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, 0, W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE)); - width--; - cx += step; - } - - // draw right side - cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_CACHE)); - cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); - for (n = 0; n < boxlines; n++) - { - V_DrawScaledPatch(cx, cy, V_WRAPY, p); - cy += step; - } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_CACHE)); -*/ } -// -// Draw border for the savegame description -// -/*static void M_DrawSaveLoadBorder(INT32 x,INT32 y) -{ - INT32 i; - - V_DrawScaledPatch (x-8,y+7,0,W_CachePatchName("M_LSLEFT",PU_CACHE)); - - for (i = 0;i < 24;i++) - { - V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSCNTR",PU_CACHE)); - x += 8; - } - - V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSRGHT",PU_CACHE)); -}*/ - // horizontally centered text static void M_CentreText(INT32 y, const char *string) { @@ -4035,157 +3740,6 @@ static void M_DrawGenericBackgroundMenu(void) void M_DrawPauseMenu(void) { -#if 0 - if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING)) - { - emblem_t *emblem_detail[3] = {NULL, NULL, NULL}; - char emblem_text[3][20]; - INT32 i; - - M_DrawTextBox(27, 16, 32, 6); - - // Draw any and all emblems at the top. - M_DrawMapEmblems(gamemap, 272, 28); - - if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) - { - if (mapheaderinfo[gamemap-1]->actnum[0]) - V_DrawString(40, 28, highlightflags, va("%s %s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); - else - V_DrawString(40, 28, highlightflags, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl)); - } - else - { - if (mapheaderinfo[gamemap-1]->actnum[0]) - V_DrawString(40, 28, highlightflags, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); - else - V_DrawString(40, 28, highlightflags, mapheaderinfo[gamemap-1]->lvlttl); - } - - // Set up the detail boxes. - { - emblem_t *emblem = M_GetLevelEmblems(gamemap); - while (emblem) - { - INT32 emblemslot; - char targettext[9], currenttext[9]; - - switch (emblem->type) - { - /*case ET_SCORE: - snprintf(targettext, 9, "%d", emblem->var); - snprintf(currenttext, 9, "%u", G_GetBestScore(gamemap)); - - targettext[8] = 0; - currenttext[8] = 0; - - emblemslot = 0; - break;*/ - case ET_TIME: - emblemslot = emblem->var; // dumb hack - snprintf(targettext, 9, "%i:%02i.%02i", - G_TicsToMinutes((tic_t)emblemslot, false), - G_TicsToSeconds((tic_t)emblemslot), - G_TicsToCentiseconds((tic_t)emblemslot)); - - emblemslot = (INT32)G_GetBestTime(gamemap); // dumb hack pt ii - if ((tic_t)emblemslot == UINT32_MAX) - snprintf(currenttext, 9, "-:--.--"); - else - snprintf(currenttext, 9, "%i:%02i.%02i", - G_TicsToMinutes((tic_t)emblemslot, false), - G_TicsToSeconds((tic_t)emblemslot), - G_TicsToCentiseconds((tic_t)emblemslot)); - - targettext[8] = 0; - currenttext[8] = 0; - - emblemslot = 1; - break; - /*case ET_RINGS: - snprintf(targettext, 9, "%d", emblem->var); - snprintf(currenttext, 9, "%u", G_GetBestRings(gamemap)); - - targettext[8] = 0; - currenttext[8] = 0; - - emblemslot = 2; - break; - case ET_NGRADE: - snprintf(targettext, 9, "%u", P_GetScoreForGrade(gamemap, 0, emblem->var)); - snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0)); - - targettext[8] = 0; - currenttext[8] = 0; - - emblemslot = 1; - break; - case ET_NTIME: - emblemslot = emblem->var; // dumb hack pt iii - snprintf(targettext, 9, "%i:%02i.%02i", - G_TicsToMinutes((tic_t)emblemslot, false), - G_TicsToSeconds((tic_t)emblemslot), - G_TicsToCentiseconds((tic_t)emblemslot)); - - emblemslot = (INT32)G_GetBestNightsTime(gamemap, 0); // dumb hack pt iv - if ((tic_t)emblemslot == UINT32_MAX) - snprintf(currenttext, 9, "-:--.--"); - else - snprintf(currenttext, 9, "%i:%02i.%02i", - G_TicsToMinutes((tic_t)emblemslot, false), - G_TicsToSeconds((tic_t)emblemslot), - G_TicsToCentiseconds((tic_t)emblemslot)); - - targettext[8] = 0; - currenttext[8] = 0; - - emblemslot = 2; - break;*/ - default: - goto bademblem; - } - if (emblem_detail[emblemslot]) - goto bademblem; - - emblem_detail[emblemslot] = emblem; - snprintf(emblem_text[emblemslot], 20, "%8s /%8s", currenttext, targettext); - emblem_text[emblemslot][19] = 0; - - bademblem: - emblem = M_GetLevelEmblems(-1); - } - } - for (i = 0; i < 3; ++i) - { - emblem_t *emblem = emblem_detail[i]; - if (!emblem) - continue; - - if (emblem->collected) - V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), - R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE)); - else - V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE)); - - switch (emblem->type) - { - /*case ET_SCORE: - case ET_NGRADE: - V_DrawString(56, 44 + (i*8), highlightflags, "SCORE:"); - break;*/ - case ET_TIME: - //case ET_NTIME: - V_DrawString(56, 44 + (i*8), highlightflags, "TIME:"); - break; - /*case ET_RINGS: - V_DrawString(56, 44 + (i*8), highlightflags, "RINGS:"); - break;*/ - } - V_DrawRightAlignedString(284, 44 + (i*8), V_MONOSPACE, emblem_text[i]); - } - } -#endif - #ifdef HAVE_DISCORDRPC // kind of hackily baked in here if (currentMenu == &MPauseDef && discordRequestList != NULL) @@ -6444,31 +5998,6 @@ void M_DestroyRobots(INT32 choice) M_StartMessage(M_GetText("Do you want to destroy all\nrobots in the current level?\n\n(Press 'Y' to confirm)\n"), FUNCPTRCAST(M_DestroyRobotsResponse), MM_YESNO); } -/*static void M_LevelSelectWarp(INT32 choice) -{ - boolean fromloadgame = (currentMenu == &SP_LevelSelectDef); - - (void)choice; - - if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR) - { -// CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value)); - return; - } - - startmap = (INT16)(cv_nextmap.value); - - fromlevelselect = true; - - if (fromloadgame) - G_LoadGame((UINT32)cursaveslot, startmap); - else - { - cursaveslot = -1; - M_SetupChoosePlayer(0); - } -}*/ - // ======== // SKY ROOM // ======== @@ -6740,8 +6269,6 @@ static INT32 st_sel = 0; static tic_t st_time = 0; static size_t st_namescroll = 0; static size_t st_namescrollstate = 0; -//static patch_t* st_radio[9]; -//static patch_t* st_launchpad[4]; void M_MusicTest(INT32 choice) { @@ -7067,109 +6594,10 @@ void M_HandleMusicTest(INT32 choice) } } -// Entering secrets menu -/*static void M_SecretsMenu(INT32 choice) -{ - INT32 i, j, ul; - UINT8 done[MAXUNLOCKABLES]; - UINT16 curheight; - - (void)choice; - - // Clear all before starting - for (i = 1; i < MAXUNLOCKABLES+1; ++i) - SR_MainMenu[i].status = IT_DISABLED; - - memset(skyRoomMenuTranslations, 0, sizeof(skyRoomMenuTranslations)); - memset(done, 0, sizeof(done)); - - for (i = 1; i < MAXUNLOCKABLES+1; ++i) - { - curheight = UINT16_MAX; - ul = -1; - - // Autosort unlockables - for (j = 0; j < MAXUNLOCKABLES; ++j) - { - if (!unlockables[j].height || done[j] || unlockables[j].type < 0) - continue; - - if (unlockables[j].height < curheight) - { - curheight = unlockables[j].height; - ul = j; - } - } - if (ul < 0) - break; - - done[ul] = true; - - skyRoomMenuTranslations[i-1] = (UINT8)ul; - SR_MainMenu[i].text = unlockables[ul].name; - SR_MainMenu[i].alphaKey = (UINT8)unlockables[ul].height; - - if (unlockables[ul].type == SECRET_HEADER) - { - SR_MainMenu[i].status = IT_HEADER; - continue; - } - - SR_MainMenu[i].status = IT_SECRET; - - if (unlockables[ul].unlocked) - { - switch (unlockables[ul].type) - { - case SECRET_LEVELSELECT: - SR_MainMenu[i].status = IT_STRING|IT_CALL; - SR_MainMenu[i].itemaction = M_CustomLevelSelect; - break; - case SECRET_WARP: - SR_MainMenu[i].status = IT_STRING|IT_CALL; - SR_MainMenu[i].itemaction = M_CustomWarp; - break; - case SECRET_CREDITS: - SR_MainMenu[i].status = IT_STRING|IT_CALL; - SR_MainMenu[i].itemaction = M_Credits; - break; - case SECRET_SOUNDTEST: - SR_MainMenu[i].status = IT_STRING|IT_KEYHANDLER; - SR_MainMenu[i].itemaction = M_HandleSoundTest; - default: - break; - } - } - } - - M_SetupNextMenu(&SR_MainDef); -}*/ - // ================== // NEW GAME FUNCTIONS // ================== -/*INT32 ultimate_selectable = false; - -static void M_NewGame(void) -{ - fromlevelselect = false; - - startmap = spstage_start; - CV_SetValue(&cv_newgametype, GT_RACE); // SRB2kart - - M_SetupChoosePlayer(0); -}*/ - -/*static void M_CustomWarp(INT32 choice) -{ - INT32 ul = skyRoomMenuTranslations[choice-1]; - - startmap = (INT16)(unlockables[ul].variable); - - M_SetupChoosePlayer(0); -}*/ - void M_Credits(INT32 choice) { (void)choice; @@ -7186,23 +6614,6 @@ void M_BlanCredits(INT32 choice) F_BlanStartCredits(); } -/*static void M_CustomLevelSelect(INT32 choice) -{ - INT32 ul = skyRoomMenuTranslations[choice-1]; - - SR_LevelSelectDef.prevMenu = currentMenu; - levellistmode = LLM_LEVELSELECT; - maplistoption = (UINT8)(unlockables[ul].variable); - if (M_CountLevelsToShowInList() == 0) - { - M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); - return; - } - - M_PrepareLevelSelect(); - M_SetupNextMenu(&SR_LevelSelectDef); -}*/ - // ================== // SINGLE PLAYER MENU // ================== @@ -7220,650 +6631,23 @@ void M_SinglePlayerMenu(INT32 choice) M_SetupNextMenu(&SP_MainDef); } -/*static void M_LoadGameLevelSelect(INT32 choice) -{ - (void)choice; - levellistmode = LLM_LEVELSELECT; - maplistoption = 1; - if (M_CountLevelsToShowInList() == 0) - { - M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); - return; - } - - SP_LevelSelectDef.prevMenu = currentMenu; - - M_PrepareLevelSelect(); - M_SetupNextMenu(&SP_LevelSelectDef); -}*/ // ============== -// LOAD GAME MENU +/* ignore the garbage, i'm just trying to keep git happy // ============== -/*static INT32 saveSlotSelected = 0; -static short menumovedir = 0; -static void M_DrawLoadGameData(void) { - INT32 ecks; - INT32 i; - ecks = SP_LoadDef.x + 24; - M_DrawTextBox(SP_LoadDef.x-12,144, 24, 4); - - if (saveSlotSelected == NOSAVESLOT) // last slot is play without saving { - if (ultimate_selectable) - { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "ULTIMATE MODE"); - V_DrawCenteredString(ecks + 68, 156, 0, "NO RINGS, NO ONE-UPS,"); - V_DrawCenteredString(ecks + 68, 164, 0, "NO CONTINUES, ONE LIFE,"); - V_DrawCenteredString(ecks + 68, 172, 0, "FINAL DESTINATION."); - } - else - { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "PLAY WITHOUT SAVING"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS GAME WILL NOT BE"); - V_DrawCenteredString(ecks + 68, 164, 0, "SAVED, BUT YOU CAN STILL"); - V_DrawCenteredString(ecks + 68, 172, 0, "GET MEDALS AND SECRETS."); - } - return; } - if (savegameinfo[saveSlotSelected].lives == -42) // Empty - { - V_DrawCenteredString(ecks + 68, 160, 0, "NO DATA"); - return; - } - if (savegameinfo[saveSlotSelected].lives == -666) // savegame is bad - { - V_DrawCenteredString(ecks + 68, 144, warningflags, "CORRUPT SAVE FILE"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS SAVE FILE"); - V_DrawCenteredString(ecks + 68, 164, 0, "CAN NOT BE LOADED."); - V_DrawCenteredString(ecks + 68, 172, 0, "DELETE USING BACKSPACE."); - return; - } - // Draw the back sprite, it looks ugly if we don't - V_DrawScaledPatch(SP_LoadDef.x, 144+8, 0, livesback); - if (savegameinfo[saveSlotSelected].skincolor == 0) - V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE)); - else - { - UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, GTC_MENUCACHE); - V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap); - } - V_DrawString(ecks + 12, 152, 0, savegameinfo[saveSlotSelected].playername); -#ifdef SAVEGAMES_OTHERVERSIONS - if (savegameinfo[saveSlotSelected].gamemap & 16384) - V_DrawCenteredString(ecks + 68, 144, warningflags, "OUTDATED SAVE FILE!"); -#endif - if (savegameinfo[saveSlotSelected].gamemap & 8192) - V_DrawString(ecks + 12, 160, recommendedflags, "CLEAR!"); - else - V_DrawString(ecks + 12, 160, 0, va("%s", savegameinfo[saveSlotSelected].levelname)); - // Use the big face pic for lives, duh. :3 - V_DrawScaledPatch(ecks + 12, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 40, 172, 0, savegameinfo[saveSlotSelected].lives); - - // Absolute ridiculousness, condensed into another function. - V_DrawContinueIcon(ecks + 58, 182, 0, savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor); - V_DrawScaledPatch(ecks + 68, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 96, 172, 0, savegameinfo[saveSlotSelected].continues); - - for (i = 0; i < 7; ++i) - { - if (savegameinfo[saveSlotSelected].numemeralds & (1 << i)) - V_DrawScaledPatch(ecks + 104 + (i * 8), 172, 0, tinyemeraldpics[i]); - } -} - -#define LOADBARHEIGHT SP_LoadDef.y + (LINEHEIGHT * (j+1)) + ymod -#define CURSORHEIGHT SP_LoadDef.y + (LINEHEIGHT*3) - 1 -static void M_DrawLoad(void) -{ - INT32 i, j; - INT32 ymod = 0, offset = 0; - - M_DrawMenuTitle(); - fixed_t scrollfrac = FixedDiv(2, 3); - - if (menumovedir != 0) //movement illusion - { - ymod = (-(LINEHEIGHT/4))*menumovedir; - offset = ((menumovedir > 0) ? -1 : 1); - } - - V_DrawCenteredString(BASEVIDWIDTH/2, 40, 0, "Press backspace to delete a save."); - - for (i = MAXSAVEGAMES + saveSlotSelected - 2 + offset, j = 0;i <= MAXSAVEGAMES + saveSlotSelected + 2 + offset; i++, j++) - { - if ((menumovedir < 0 && j == 4) || (menumovedir > 0 && j == 0)) - continue; //this helps give the illusion of movement - - M_DrawSaveLoadBorder(SP_LoadDef.x, LOADBARHEIGHT); - - if ((i%MAXSAVEGAMES) == NOSAVESLOT) // play without saving - { - if (ultimate_selectable) - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "ULTIMATE MODE"); - else - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "PLAY WITHOUT SAVING"); - continue; - } - - if (savegameinfo[i%MAXSAVEGAMES].lives == -42) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_TRANSLUCENT, "NO DATA"); - else if (savegameinfo[i%MAXSAVEGAMES].lives == -666) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, warningflags, "CORRUPT SAVE FILE"); - else if (savegameinfo[i%MAXSAVEGAMES].gamemap & 8192) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, recommendedflags, "CLEAR!"); - else - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, 0, va("%s", savegameinfo[i%MAXSAVEGAMES].levelname)); - - //Draw the save slot number on the right side - V_DrawRightAlignedString(SP_LoadDef.x+192, LOADBARHEIGHT - 1, 0, va("%d",(i%MAXSAVEGAMES) + 1)); - } - - //Draw cursors on both sides. - V_DrawScaledPatch( 32, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawScaledPatch(274, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - - M_DrawLoadGameData(); - - //finishing the movement illusion - if (menumovedir) - menumovedir += ((menumovedir > 0) ? 1 : -1); - if (abs(menumovedir) > 3) - menumovedir = 0; -} -#undef LOADBARHEIGHT -#undef CURSORHEIGHT - -// -// User wants to load this game -// -static void M_LoadSelect(INT32 choice) -{ - (void)choice; - - if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving - { - M_NewGame(); - cursaveslot = -1; - return; - } - - if (!FIL_ReadFileOK(va(savegamename, saveSlotSelected))) - { - // This slot is empty, so start a new game here. - M_NewGame(); - } - else if (savegameinfo[saveSlotSelected].gamemap & 8192) // Completed - M_LoadGameLevelSelect(saveSlotSelected + 1); - else - G_LoadGame((UINT32)saveSlotSelected, 0); - - cursaveslot = saveSlotSelected; -} - -#define VERSIONSIZE 16 -#define BADSAVE { savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; } -#define CHECKPOS if (save_p >= end_p) BADSAVE -// Reads the save file to list lives, level, player, etc. -// Tails 05-29-2003 -static void M_ReadSavegameInfo(UINT32 slot) -{ - size_t length; - char savename[255]; - UINT8 *savebuffer; - UINT8 *end_p; // buffer end point, don't read past here - UINT8 *save_p; - INT32 fake; // Dummy variable - char temp[sizeof(timeattackfolder)]; - char vcheck[VERSIONSIZE]; -#ifdef SAVEGAMES_OTHERVERSIONS - boolean oldversion = false; -#endif - - sprintf(savename, savegamename, slot); - - length = FIL_ReadFile(savename, &savebuffer); - if (length == 0) - { - savegameinfo[slot].lives = -42; - return; - } - - end_p = savebuffer + length; - - // skip the description field - save_p = savebuffer; - - // Version check - memset(vcheck, 0, sizeof (vcheck)); - sprintf(vcheck, "version %d", VERSION); - if (strcmp((const char *)save_p, (const char *)vcheck)) - { -#ifdef SAVEGAMES_OTHERVERSIONS - oldversion = true; -#else - BADSAVE // Incompatible versions? -#endif - } - save_p += VERSIONSIZE; - - // dearchive all the modifications - // P_UnArchiveMisc() - - CHECKPOS - fake = READINT16(save_p); - - if (((fake-1) & 8191) >= NUMMAPS) BADSAVE - - if(!mapheaderinfo[(fake-1) & 8191]) - { - savegameinfo[slot].levelname[0] = '\0'; - savegameinfo[slot].actnum = 0; - } - else - { - strcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl); - savegameinfo[slot].actnum = 0; //mapheaderinfo[(fake-1) & 8191]->actnum - } - -#ifdef SAVEGAMES_OTHERVERSIONS - if (oldversion) - { - if (fake == 24) //meh, let's count old Clear! saves too - fake |= 8192; - fake |= 16384; // marker for outdated version - } -#endif - savegameinfo[slot].gamemap = fake; - - CHECKPOS - fake = READUINT16(save_p)-357; // emeralds - - savegameinfo[slot].numemeralds = (UINT8)fake; - - CHECKPOS - READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to - - if (strcmp(temp, timeattackfolder)) BADSAVE - - // P_UnArchivePlayer() - CHECKPOS - savegameinfo[slot].skincolor = READUINT8(save_p); - CHECKPOS - savegameinfo[slot].skinnum = READUINT8(save_p); - - CHECKPOS - (void)READINT32(save_p); // Score - - CHECKPOS - savegameinfo[slot].lives = READINT32(save_p); // lives - CHECKPOS - savegameinfo[slot].continues = READINT32(save_p); // continues - - if (fake & (1<<10)) - { - CHECKPOS - savegameinfo[slot].botskin = READUINT8(save_p); - if (savegameinfo[slot].botskin-1 >= numskins) - savegameinfo[slot].botskin = 0; - CHECKPOS - savegameinfo[slot].botcolor = READUINT8(save_p); // because why not. - } - else - savegameinfo[slot].botskin = 0; - - if (savegameinfo[slot].botskin) - snprintf(savegameinfo[slot].playername, 36, "%s & %s", - skins[savegameinfo[slot].skinnum].realname, - skins[savegameinfo[slot].botskin-1].realname); - else - strcpy(savegameinfo[slot].playername, skins[savegameinfo[slot].skinnum].realname); - - savegameinfo[slot].playername[31] = 0; - - // File end marker check - CHECKPOS - if (READUINT8(save_p) != 0x1d) BADSAVE; - - // done - Z_Free(savebuffer); -} -#undef CHECKPOS -#undef BADSAVE - -// -// M_ReadSaveStrings -// read the strings from the savegame files -// and put it in savegamestrings global variable -// -static void M_ReadSaveStrings(void) -{ - FILE *handle; - UINT32 i; - char name[256]; - - for (i = 0; i < MAXSAVEGAMES; i++) - { - snprintf(name, sizeof name, savegamename, i); - name[sizeof name - 1] = '\0'; - - handle = fopen(name, "rb"); - if (handle == NULL) - { - savegameinfo[i].lives = -42; - continue; - } - fclose(handle); - M_ReadSavegameInfo(i); - } -} - -// -// User wants to delete this game -// -static void M_SaveGameDeleteResponse(INT32 ch) -{ - char name[256]; - - if (ch != 'y' && ch != KEY_ENTER) - return; - - // delete savegame - snprintf(name, sizeof name, savegamename, saveSlotSelected); - name[sizeof name - 1] = '\0'; - remove(name); - - // Refresh savegame menu info - M_ReadSaveStrings(); -} - -static void M_HandleLoadSave(INT32 choice) -{ - boolean exitmenu = false; // exit to previous menu - - switch (choice) - { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); - ++saveSlotSelected; - if (saveSlotSelected >= MAXSAVEGAMES) - saveSlotSelected -= MAXSAVEGAMES; - menumovedir = 1; - break; - - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); - --saveSlotSelected; - if (saveSlotSelected < 0) - saveSlotSelected += MAXSAVEGAMES; - menumovedir = -1; - break; - - case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - if (savegameinfo[saveSlotSelected].lives != -666) // don't allow loading of "bad saves" - M_LoadSelect(saveSlotSelected); - break; - - case KEY_ESCAPE: - exitmenu = true; - break; - - case KEY_BACKSPACE: - S_StartSound(NULL, sfx_menu1); - // Don't allow people to 'delete' "Play without Saving." - // Nor allow people to 'delete' slots with no saves in them. - if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected].lives != -42) - M_StartMessage(M_GetText("Are you sure you want to delete\nthis save game?\n\n(Press 'Y' to confirm)\n"),M_SaveGameDeleteResponse,MM_YESNO); - break; - } - if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } -} - -// -// Selected from SRB2 menu -// -static void M_LoadGame(INT32 choice) -{ - (void)choice; - - M_ReadSaveStrings(); - M_SetupNextMenu(&SP_LoadDef); -} - -// -// Used by cheats to force the save menu to a specific spot. -// -void M_ForceSaveSlotSelected(INT32 sslot) -{ - // Already there? Out of bounds? Whatever, then! - if (sslot == saveSlotSelected || sslot >= MAXSAVEGAMES) - return; - - // Figure out whether to display up movement or down movement - menumovedir = (saveSlotSelected - sslot) > 0 ? -1 : 1; - if (abs(saveSlotSelected - sslot) > (MAXSAVEGAMES>>1)) - menumovedir *= -1; - - saveSlotSelected = sslot; -} - -// ================ -// CHARACTER SELECT -// ================ - -static void M_SetupChoosePlayer(INT32 choice) -{ - (void)choice; - - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') - { - M_ChoosePlayer(0); //oh for crying out loud just get STARTED, it doesn't matter! - return; - } - - if (Playing() == false) - { - S_StopMusic(); - S_ChangeMusicInternal("chrsel", true); - } - - SP_PlayerDef.prevMenu = currentMenu; - M_SetupNextMenu(&SP_PlayerDef); - char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu - Z_Free(char_notes); - char_notes = NULL; -} - -// Draw the choose player setup menu, had some fun with player anim -static void M_DrawSetupChoosePlayerMenu(void) -{ - const INT32 my = 24; - patch_t *patch; - INT32 i, o, j; - char *picname; - - // Black BG - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - //V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - - // Character select profile images!1 - M_DrawTextBox(0, my, 16, 20); - - if (abs(itemOn*128*FRACUNIT - char_scroll) > 256*FRACUNIT) - char_scroll = itemOn*128*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll > 128*FRACUNIT) - char_scroll += 48*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll < -128*FRACUNIT) - char_scroll -= 48*FRACUNIT; - else if (itemOn*128*FRACUNIT > char_scroll+16*FRACUNIT) - char_scroll += 16*FRACUNIT; - else if (itemOn*128*FRACUNIT < char_scroll-16*FRACUNIT) - char_scroll -= 16*FRACUNIT; - else // close enough. - char_scroll = itemOn*128*FRACUNIT; // just be exact now. - i = (char_scroll+16*FRACUNIT)/(128*FRACUNIT); - o = ((char_scroll/FRACUNIT)+16)%128; - - // prev character - if (i-1 >= 0 && PlayerMenu[i-1].status != IT_DISABLED - && o < 32) - { - picname = description[i-1].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i-1].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); - else - V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); - W_UnlockCachedPatch(patch); - } - - // next character - if (i+1 < currentMenu->numitems && PlayerMenu[i+1].status != IT_DISABLED - && o < 128) - { - picname = description[i+1].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i+1].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), o*2); - else - V_DrawCroppedPatch(8<width), o); - W_UnlockCachedPatch(patch); - } - - // current character - if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED) - { - picname = description[i].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; - } - patch = W_CachePatchName(picname, PU_CACHE); - if (o >= 0 && o <= 32) - { - if (SHORT(patch->width) >= 256) - V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch); - else - V_DrawScaledPatch(8, my + 40 - o, 0, patch); - } - else - { - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), SHORT(patch->height)); - else - V_DrawCroppedPatch(8<width), SHORT(patch->height)); - } - W_UnlockCachedPatch(patch); - } - - // draw title (or big pic) - M_DrawMenuTitle(); - - // Character description - M_DrawTextBox(136, my, 21, 20); - if (!char_notes) - char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes); - V_DrawString(146, my + 9, V_ALLOWLOWERCASE, char_notes); -} - -// Chose the player you want to use Tails 03-02-2002 -static void M_ChoosePlayer(INT32 choice) -{ - char *skin1,*skin2; - INT32 skinnum; - //boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); - - // skip this if forcecharacter - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] == '\0') - { - // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. - char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu - M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout - } - M_ClearMenus(true); - - skin1 = strtok(description[choice].skinname, "&"); - skin2 = strtok(NULL, "&"); - - if (skin2) { - // this character has a second skin - skinnum = R_SkinAvailable(skin1); - botskin = (UINT8)(R_SkinAvailable(skin2)+1); - botingame = true; - - botcolor = skins[botskin-1].prefcolor; - - // undo the strtok - description[choice].skinname[strlen(skin1)] = '&'; - } else { - skinnum = R_SkinAvailable(description[choice].skinname); - botingame = false; - botskin = 0; - botcolor = 0; - } - - if (startmap != spstage_start) - cursaveslot = -1; - - lastmapsaved = 0; - gamecomplete = false; - - G_DeferedInitNew(false, G_BuildMapName(startmap), (UINT8)skinnum, 0, fromlevelselect); - COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this }*/ // =============== @@ -8391,51 +7175,6 @@ void M_DrawTimeAttackMenu(void) V_DrawRightAlignedString(292, 80, highlightflags, "BEST TIME:"); K_drawKartTimestamp(time, 162, 86, cv_nextmap.value-1, 1); } - /*{ - char beststr[40]; - emblem_t *em; - - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(mainrecords[cv_nextmap.value-1]->time, true), - G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), - G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - - V_DrawString(64, y+48, highlightflags, "BEST TIME:"); - V_DrawRightAlignedString(BASEVIDWIDTH - 64 - 24 - 8, y+48, V_ALLOWLOWERCASE, beststr); - - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->lap) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(mainrecords[cv_nextmap.value-1]->lap, true), - G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->lap), - G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->lap)); - - V_DrawString(64, y+56, highlightflags, "BEST LAP:"); - V_DrawRightAlignedString(BASEVIDWIDTH - 64 - 24 - 8, y+56, V_ALLOWLOWERCASE, beststr); - - // Draw record emblems. - em = M_GetLevelEmblems(cv_nextmap.value); - while (em) - { - switch (em->type) - { - case ET_TIME: break; - default: - goto skipThisOne; - } - - if (em->collected) - V_DrawMappedPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE), - R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_MENUCACHE)); - else - V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE)); - - skipThisOne: - em = M_GetLevelEmblems(-1); - } - }*/ // ALWAYS DRAW player name, level name, skin and color even when not on this menu! if (currentMenu != &SP_TimeAttackDef) @@ -8646,28 +7385,6 @@ void M_ReplayTimeAttack(INT32 choice) // srb2/replay/main/map01-sonic-time-best.lmp G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, gamemode, which)); } - /*else if (currentMenu == &SP_NightsReplayDef) - { - switch(choice) { - default: - case 0: // best score - which = "score-best"; - break; - case 1: // best time - which = "time-best"; - break; - case 2: // last - which = "last"; - break; - case 3: // staff - return; // M_HandleStaffReplay - case 4: // guest - which = "guest"; - break; - } - // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); - }*/ } static void M_EraseGuest(INT32 choice) @@ -8677,10 +7394,7 @@ static void M_EraseGuest(INT32 choice) (void)choice; if (FIL_FileExists(rguest)) remove(rguest); - /*if (currentMenu == &SP_NightsGuestReplayDef) - M_SetupNextMenu(&SP_NightsAttackDef); - else*/ - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(&SP_TimeAttackDef); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); @@ -8702,10 +7416,7 @@ static void M_OverwriteGuest(const char *which) } FIL_WriteFile(rguest, buf, len); Z_Free(rguest); - /*if (currentMenu == &SP_NightsGuestReplayDef) - M_SetupNextMenu(&SP_NightsAttackDef); - else*/ - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(&SP_TimeAttackDef); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data saved.\n"),NULL,MM_NOTHING); @@ -8723,19 +7434,6 @@ static void M_OverwriteGuest_Lap(INT32 choice) M_OverwriteGuest("lap-best"); } -/* SRB2Kart -static void M_OverwriteGuest_Score(INT32 choice) -{ - (void)choice; - M_OverwriteGuest("score-best"); -} - -static void M_OverwriteGuest_Rings(INT32 choice) -{ - (void)choice; - M_OverwriteGuest("rings-best"); -}*/ - static void M_OverwriteGuest_Last(INT32 choice) { (void)choice; @@ -10732,7 +9430,6 @@ void M_DrawJoystick(void) for (i = 0; i <= MAXGAMEPADS; i++) { M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1); - //M_DrawSaveLoadBorder(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i); #ifdef JOYSTICK_HOTPLUG if (atoi(cv_usejoystick[setupcontrolplayer-1].string) > I_NumJoys()) @@ -11250,15 +9947,6 @@ void M_ResetControls(INT32 choice) M_StartMessage(va(M_GetText("Reset Player %d's controls to defaults?\n\n(Press 'Y' to confirm)\n"), setupcontrolplayer), FUNCPTRCAST(M_ResetControlsResponse), MM_YESNO); } -// ===== -// SOUND -// ===== - -/*static void M_RestartAudio(void) -{ - COM_ImmedExecute("restartaudio"); -}*/ - // =============== // VIDEO MODE MENU // =============== From 65a86671fe403f4bcf6b937854c670af990e13e9 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Thu, 20 Mar 2025 01:35:30 +0100 Subject: [PATCH 10/33] Menuitem names, GO! --- src/deh_soc.c | 10 +- src/filesrch.c | 2 +- src/m_menu.c | 767 +++++++++++++++++++++++++++++-------------------- src/m_menu.h | 6 + src/m_misc.cpp | 4 +- 5 files changed, 467 insertions(+), 322 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 452db4231..353c6d102 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2170,10 +2170,16 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) char *tmp; menuitem_t *menuitem = menudef->menuitems + menudef->numitems; - (void)itemname; // menuitem->itemname = Z_StrDup(itemname); boolean actionset = false; boolean textset = false; + if (strlen(itemname) > 6) + { + deh_warning("MenuItem %s: name too long (max 6 characters)", itemname); + goto toolong; + } + strncpy(menuitem->itemname, itemname, 6); + // taking quite possibly the only opportunity i'll ever get // to avoid three tabs of indentation... do if (myfgets(s, MAXLINELEN, f)) @@ -2335,6 +2341,8 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) } while (!myfeof(f)); // finish when the line is empty +toolong: + // text pointer cannot be null if (!textset) menuitem->text = ""; diff --git a/src/filesrch.c b/src/filesrch.c index a662cc160..4d15454e7 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -314,7 +314,7 @@ static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"}, #endif {3, "CUSTOM"}, {0, NULL}}; -consvar_t cv_addons_option = CVAR_INIT ("addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange); +consvar_t cv_addons_option = CVAR_INIT ("addons_option", "Default", CV_SAVE|CV_CALL|CV_NOINIT, addons_cons_t, Addons_option_Onchange); consvar_t cv_addons_folder = CVAR_INIT ("addons_folder", "", CV_SAVE, NULL, NULL); static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}}; diff --git a/src/m_menu.c b/src/m_menu.c index db3a3df1d..6cc94cc17 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -352,6 +352,125 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_FIRSTFREESLOT] = &FreeslotTest, }; +// a wide array of functions for interacting with menu items +// should probably trim these a bit... + +static INT16 M_GetMenuIndexByName(menutype_t type, const char *name) +{ + INT16 i; + menu_t *menu = menunum2menudef[type]; + I_Assert(menu); + + for (i = 0; i < menu->numitems; i++) + if (!strncmp(menu->menuitems[i].itemname, name, 6)) + return i; + return -1; +} + +static menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name) +{ + INT16 i = M_GetMenuIndexByName(type, name); + return i >= 0 ? &menunum2menudef[type]->menuitems[i] : NULL; +} + +static void M_GetMenuItemNameByIndex(menutype_t type, INT16 index, char out[6]) +{ + menu_t *menu = menunum2menudef[type]; + I_Assert(menu); + strncpy(out, menu->menuitems[index].itemname, 6); +} + +static boolean M_IsItemOn(menutype_t type, const char *name) +{ + INT16 index = M_GetMenuIndexByName(type, name); + if (index < 0) + I_Error("Menu %d has no item %s", type, name); + return itemOn == index; +} + +static void M_SetItemOn(menutype_t type, const char *name) +{ + INT16 index = M_GetMenuIndexByName(type, name); + if (index < 0) + I_Error("Menu %d has no item %s", type, name); + itemOn = index; +} + +static void M_SetItemStatus(menutype_t type, const char *name, UINT16 flags) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + item->status = flags; +} + +static UINT16 M_GetItemStatus(menutype_t type, const char *name) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + return item->status; +} + +static void M_SetItemRoutine(menutype_t type, const char *name, void (*routine)(INT32 choice)) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + item->itemaction.routine = routine; +} + +static void M_SetItemCvar(menutype_t type, const char *name, consvar_t *cvar) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + item->itemaction.cvar = cvar; +} + +static void M_SetItemKey(menutype_t type, const char *name, UINT16 key) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + item->alphaKey = key; +} +#define M_SetItemY M_SetItemKey +#define M_SetItemX M_SetItemKey // 2D menus wen + +static UINT16 M_GetItemKey(menutype_t type, const char *name) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + return item->alphaKey; +} +#define M_GetItemY M_GetItemKey + +static void M_AdjustItemY(menutype_t type, const char *name, INT16 amount) +{ + menuitem_t *item = M_GetMenuItemByName(type, name); + if (!item) + I_Error("Menu %d has no item %s", type, name); + item->alphaKey += amount; +} + +// ensure there are numitems menuitems between name1 and name2 +// then return the index of name1 +static INT16 M_MenuItemRange(menutype_t type, const char *name1, const char *name2, INT16 numitems) +{ + INT16 index1 = M_GetMenuIndexByName(type, name1); + if (index1 < 0) + I_Error("Menu %d has no item %s", type, name1); + INT16 index2 = M_GetMenuIndexByName(type, name2); + if (index2 < 0) + I_Error("Menu %d has no item %s", type, name2); + INT16 range = index2 - index1 + 1; + if (range != numitems) + I_Error("Menu %d should have %d items between %s and %s inclusive, but %d were found", type, numitems, name1, name2, range); + return index1; +} + // ========================================================================== // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== @@ -2004,74 +2123,75 @@ void Nextmap_OnChange(void) // see also p_setup.c's P_LoadRecordGhosts const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; char *gpath = xva("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); - INT32 i; UINT8 active = 0; CV_StealthSetValue(&cv_dummystaff, 0); active = 0; - SP_TimeAttackMenu[taguest].status = IT_DISABLED; - SP_TimeAttackMenu[tareplay].status = IT_DISABLED; - //SP_TimeAttackMenu[taghost].status = IT_DISABLED; + M_SetItemStatus(MN_SP_TIMEATTACK, "GUEST", IT_DISABLED); + M_SetItemStatus(MN_SP_TIMEATTACK, "REPLAY", IT_DISABLED); // Check if file exists, if not, disable REPLAY option - for (i = 0; i < 4; i++) - { - SP_ReplayMenu[i].status = IT_DISABLED; - SP_GuestReplayMenu[i].status = IT_DISABLED; - } - SP_ReplayMenu[4].status = IT_DISABLED; + M_SetItemStatus(MN_SP_REPLAY, "RPTIME", IT_DISABLED); + M_SetItemStatus(MN_SP_REPLAY, "RPLAP", IT_DISABLED); + M_SetItemStatus(MN_SP_REPLAY, "RPLAST", IT_DISABLED); + M_SetItemStatus(MN_SP_REPLAY, "RPGUES", IT_DISABLED); + M_SetItemStatus(MN_SP_REPLAY, "RPSTAF", IT_DISABLED); + M_SetItemStatus(MN_SP_GUESTREPLAY, "STIME", IT_DISABLED); + M_SetItemStatus(MN_SP_GUESTREPLAY, "SLAP", IT_DISABLED); + M_SetItemStatus(MN_SP_GUESTREPLAY, "SLAST", IT_DISABLED); + M_SetItemStatus(MN_SP_GUESTREPLAY, "DELETE", IT_DISABLED); - SP_GhostMenu[3].status = IT_DISABLED; - SP_GhostMenu[4].status = IT_DISABLED; + M_SetItemStatus(MN_SP_GHOST, "GUEST", IT_DISABLED); + M_SetItemStatus(MN_SP_GHOST, "STAFF", IT_DISABLED); if (FIL_FileExists(va("%s-%s-%s-time-best.lmp", gpath, cv_chooseskin.string, gamemode))) { - SP_ReplayMenu[0].status = IT_WHITESTRING|IT_CALL; - SP_GuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; + M_SetItemStatus(MN_SP_REPLAY, "RPTIME", IT_WHITESTRING|IT_CALL); + M_SetItemStatus(MN_SP_GUESTREPLAY, "STIME", IT_WHITESTRING|IT_CALL); active |= 3; } if (levellistmode != LLM_ITEMBREAKER) { if (FIL_FileExists(va("%s-%s-%s-lap-best.lmp", gpath, cv_chooseskin.string, gamemode))) { - SP_ReplayMenu[1].status = IT_WHITESTRING|IT_CALL; - SP_GuestReplayMenu[1].status = IT_WHITESTRING|IT_CALL; + M_SetItemStatus(MN_SP_REPLAY, "RPLAP", IT_WHITESTRING|IT_CALL); + M_SetItemStatus(MN_SP_GUESTREPLAY, "SLAP", IT_WHITESTRING|IT_CALL); active |= 3; } } if (FIL_FileExists(va("%s-%s-%s-last.lmp", gpath, cv_chooseskin.string, gamemode))) { - SP_ReplayMenu[2].status = IT_WHITESTRING|IT_CALL; - SP_GuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; + M_SetItemStatus(MN_SP_REPLAY, "RPLAST", IT_WHITESTRING|IT_CALL); + M_SetItemStatus(MN_SP_GUESTREPLAY, "SLAST", IT_WHITESTRING|IT_CALL); active |= 3; } if (FIL_FileExists(va("%s-%s-guest.lmp", gpath, gamemode))) { - SP_ReplayMenu[3].status = IT_WHITESTRING|IT_CALL; - SP_GuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; - SP_GhostMenu[3].status = IT_STRING|IT_CVAR; + M_SetItemStatus(MN_SP_REPLAY, "RPGUES", IT_WHITESTRING|IT_CALL); + M_SetItemStatus(MN_SP_GUESTREPLAY, "DELETE", IT_WHITESTRING|IT_CALL); + M_SetItemStatus(MN_SP_GHOST, "GUEST", IT_STRING|IT_CVAR); active |= 3; } CV_SetValue(&cv_dummystaff, 1); if (cv_dummystaff.value) { - SP_ReplayMenu[4].status = IT_WHITESTRING|IT_KEYHANDLER; - SP_GhostMenu[4].status = IT_STRING|IT_CVAR; + M_SetItemStatus(MN_SP_REPLAY, "RPSTAF", IT_WHITESTRING|IT_KEYHANDLER); + M_SetItemStatus(MN_SP_GHOST, "STAFF", IT_STRING|IT_CVAR); CV_StealthSetValue(&cv_dummystaff, 1); active |= 1; } if (active) { if (active & 1) - SP_TimeAttackMenu[tareplay].status = IT_WHITESTRING|IT_SUBMENU; + M_SetItemStatus(MN_SP_TIMEATTACK, "REPLAY", IT_WHITESTRING|IT_SUBMENU); if (active & 2) - SP_TimeAttackMenu[taguest].status = IT_WHITESTRING|IT_SUBMENU; + M_SetItemStatus(MN_SP_TIMEATTACK, "GUEST", IT_WHITESTRING|IT_SUBMENU); } - else if (itemOn == tareplay) // Reset lastOn so replay isn't still selected when not available. + else if (M_IsItemOn(MN_SP_TIMEATTACK, "REPLAY")) // Reset lastOn so replay isn't still selected when not available. { currentMenu->lastOn = itemOn; - itemOn = tastart; + M_SetItemOn(MN_SP_TIMEATTACK, "START"); } free(gpath); @@ -2141,37 +2261,38 @@ static void Newgametype_OnChange(void) void Screenshot_option_Onchange(void) { - OP_ScreenshotOptionsMenu[op_screenshot_folder].status = - (cv_screenshot_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "FOLDER", cv_screenshot_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED); } void Moviemode_mode_Onchange(void) { - INT32 i, cstart, cend; - for (i = op_screenshot_gif_start; i <= op_screenshot_apng_end; ++i) - OP_ScreenshotOptionsMenu[i].status = IT_DISABLED; + M_SetItemStatus(MN_OP_SCREENSHOTS, "GIFOPT", IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "GIFDWN", IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNMEM", IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNCMP", IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNSTR", IT_DISABLED); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNWIN", IT_DISABLED); switch (cv_moviemode.value) { - case MM_GIF: - cstart = op_screenshot_gif_start; - cend = op_screenshot_gif_end; - break; - case MM_APNG: - cstart = op_screenshot_apng_start; - cend = op_screenshot_apng_end; - break; - default: - return; + case MM_GIF: + M_SetItemStatus(MN_OP_SCREENSHOTS, "GIFOPT", IT_STRING|IT_CVAR); + M_SetItemStatus(MN_OP_SCREENSHOTS, "GIFDWN", IT_STRING|IT_CVAR); + break; + case MM_APNG: + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNMEM", IT_STRING|IT_CVAR); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNCMP", IT_STRING|IT_CVAR); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNSTR", IT_STRING|IT_CVAR); + M_SetItemStatus(MN_OP_SCREENSHOTS, "APNWIN", IT_STRING|IT_CVAR); + break; + default: + break; } - for (i = cstart; i <= cend; ++i) - OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR; } void Addons_option_Onchange(void) { - OP_AddonsOptionsMenu[op_addons_folder].status = - (cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED); + M_SetItemStatus(MN_OP_ADDONS, "FOLDER", cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED); } void Moviemode_option_Onchange(void) @@ -3034,146 +3155,144 @@ void M_StartControlPanel(void) else if (!Playing()) { currentMenu = &MainDef; - itemOn = singleplr; + M_SetItemOn(MN_MAIN, "SINGLE"); } else if (modeattacking) { currentMenu = &MAPauseDef; - itemOn = mapause_continue; + M_SetItemOn(MN_MAPAUSE, "CONTIN"); } else if (!(netgame || multiplayer)) // Single Player { if (gamestate != GS_LEVEL /*|| ultimatemode*/) // intermission, so gray out stuff. { - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_GRAYEDOUT) : (IT_DISABLED); - SPauseMenu[spause_retry].status = IT_GRAYEDOUT; + M_SetItemStatus(MN_SPAUSE, "PANDOR", M_SecretUnlocked(SECRET_PANDORA) ? IT_GRAYEDOUT : IT_DISABLED); + M_SetItemStatus(MN_SPAUSE, "RETRY", IT_GRAYEDOUT); } else { - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); - SPauseMenu[spause_retry].status = (IT_STRING | IT_CALL); + M_SetItemStatus(MN_SPAUSE, "PANDOR", M_SecretUnlocked(SECRET_PANDORA) ? IT_STRING|IT_CALL : IT_DISABLED); + M_SetItemStatus(MN_SPAUSE, "RETRY", IT_STRING|IT_CALL); } - SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + M_SetItemStatus(MN_SPAUSE, "EMBLEM", M_SecretUnlocked(SECRET_EMBLEMHINTS) ? IT_STRING|IT_CALL : IT_DISABLED); currentMenu = &SPauseDef; - itemOn = spause_continue; + M_SetItemOn(MN_SPAUSE, "CONTIN"); } else // multiplayer { - MPauseMenu[mpause_switchmap].status = IT_DISABLED; - MPauseMenu[mpause_addons].status = IT_DISABLED; - MPauseMenu[mpause_scramble].status = IT_DISABLED; - MPauseMenu[mpause_psetupsplit].status = IT_DISABLED; - MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED; - MPauseMenu[mpause_psetupsplit3].status = IT_DISABLED; - MPauseMenu[mpause_psetupsplit4].status = IT_DISABLED; - MPauseMenu[mpause_spectate].status = IT_DISABLED; - MPauseMenu[mpause_entergame].status = IT_DISABLED; - MPauseMenu[mpause_canceljoin].status = IT_DISABLED; - MPauseMenu[mpause_switchteam].status = IT_DISABLED; - MPauseMenu[mpause_switchspectate].status = IT_DISABLED; - MPauseMenu[mpause_psetup].status = IT_DISABLED; - MISC_ChangeTeamMenu[0].status = IT_DISABLED; - MISC_ChangeSpectateMenu[0].status = IT_DISABLED; + M_SetItemStatus(MN_MPAUSE, "MAPCHG", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "ADDONS", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SCRMBL", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SETUP1", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SETUP2", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SETUP3", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SETUP4", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SPECTA", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "ENTER", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "CANCJO", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "TEAMCH", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "SPECCH", IT_DISABLED); + M_SetItemStatus(MN_MPAUSE, "PSETUP", IT_DISABLED); + M_SetItemStatus(MN_CHANGETEAM, "PLAYER", IT_DISABLED); + M_SetItemStatus(MN_CHANGESPECTATE, "PLAYER", IT_DISABLED); // Reset these in case splitscreen messes things up - MPauseMenu[mpause_addons].alphaKey = 8; - MPauseMenu[mpause_scramble].alphaKey = 8; - MPauseMenu[mpause_switchmap].alphaKey = 24; + M_SetItemY(MN_MPAUSE, "ADDONS", 8); + M_SetItemY(MN_MPAUSE, "SCRMBL", 8); + M_SetItemY(MN_MPAUSE, "MAPCHG", 24); - MPauseMenu[mpause_switchteam].alphaKey = 48; - MPauseMenu[mpause_switchspectate].alphaKey = 48; - MPauseMenu[mpause_options].alphaKey = 64; - MPauseMenu[mpause_title].alphaKey = 80; - MPauseMenu[mpause_quit].alphaKey = 88; + M_SetItemY(MN_MPAUSE, "TEAMCH", 48); + M_SetItemY(MN_MPAUSE, "SPECCH", 48); + M_SetItemY(MN_MPAUSE, "OPTION", 64); + M_SetItemY(MN_MPAUSE, "TITLE", 80); + M_SetItemY(MN_MPAUSE, "QUIT", 88); Dummymenuplayer_OnChange(); if ((server || IsPlayerAdmin(consoleplayer))) { - MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL; - MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "MAPCHG", IT_STRING | IT_CALL); + M_SetItemStatus(MN_MPAUSE, "ADDONS", IT_STRING | IT_CALL); if (G_GametypeHasTeams()) - MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU; + M_SetItemStatus(MN_MPAUSE, "SCRMBL", IT_STRING | IT_SUBMENU); } if (splitscreen) { - MPauseMenu[mpause_psetupsplit].status = MPauseMenu[mpause_psetupsplit2].status = IT_STRING | IT_CALL; - MISC_ChangeTeamMenu[0].status = MISC_ChangeSpectateMenu[0].status = IT_STRING|IT_CVAR; + M_SetItemStatus(MN_MPAUSE, "SETUP1", IT_STRING | IT_CALL); + M_SetItemStatus(MN_MPAUSE, "SETUP2", IT_STRING | IT_CALL); + M_SetItemStatus(MN_CHANGETEAM, "PLAYER", IT_STRING|IT_CVAR); + M_SetItemStatus(MN_CHANGESPECTATE, "PLAYER", IT_STRING|IT_CVAR); if (netgame) { if (G_GametypeHasTeams()) { - MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU; - MPauseMenu[mpause_switchteam].alphaKey += ((splitscreen+1) * 8); - MPauseMenu[mpause_options].alphaKey += 8; - MPauseMenu[mpause_title].alphaKey += 8; - MPauseMenu[mpause_quit].alphaKey += 8; + M_SetItemStatus(MN_MPAUSE, "TEAMCH", IT_STRING | IT_SUBMENU); + M_AdjustItemY(MN_MPAUSE, "TEAMCH", (splitscreen+1) * 8); + M_AdjustItemY(MN_MPAUSE, "OPTION", 8); + M_AdjustItemY(MN_MPAUSE, "TITLE", 8); + M_AdjustItemY(MN_MPAUSE, "QUIT", 8); } else if (G_GametypeHasSpectators()) { - MPauseMenu[mpause_switchspectate].status = IT_STRING | IT_SUBMENU; - MPauseMenu[mpause_switchspectate].alphaKey += ((splitscreen+1) * 8); - MPauseMenu[mpause_options].alphaKey += 8; - MPauseMenu[mpause_title].alphaKey += 8; - MPauseMenu[mpause_quit].alphaKey += 8; + M_SetItemStatus(MN_MPAUSE, "SPECCH", IT_STRING | IT_SUBMENU); + M_AdjustItemY(MN_MPAUSE, "SPECCH", (splitscreen+1) * 8); + M_AdjustItemY(MN_MPAUSE, "OPTION", 8); + M_AdjustItemY(MN_MPAUSE, "TITLE", 8); + M_AdjustItemY(MN_MPAUSE, "QUIT", 8); } } if (splitscreen > 1) { - MPauseMenu[mpause_psetupsplit3].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "SETUP3", IT_STRING | IT_CALL); - MPauseMenu[mpause_options].alphaKey += 8; - MPauseMenu[mpause_title].alphaKey += 8; - MPauseMenu[mpause_quit].alphaKey += 8; + M_AdjustItemY(MN_MPAUSE, "OPTION", 8); + M_AdjustItemY(MN_MPAUSE, "TITLE", 8); + M_AdjustItemY(MN_MPAUSE, "QUIT", 8); if (splitscreen > 2) { - MPauseMenu[mpause_psetupsplit4].status = IT_STRING | IT_CALL; - MPauseMenu[mpause_options].alphaKey += 8; - MPauseMenu[mpause_title].alphaKey += 8; - MPauseMenu[mpause_quit].alphaKey += 8; + M_SetItemStatus(MN_MPAUSE, "SETUP4", IT_STRING | IT_CALL); + M_AdjustItemY(MN_MPAUSE, "OPTION", 8); + M_AdjustItemY(MN_MPAUSE, "TITLE", 8); + M_AdjustItemY(MN_MPAUSE, "QUIT", 8); } } } else { - MPauseMenu[mpause_psetup].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "PSETUP", IT_STRING | IT_CALL); if (G_GametypeHasTeams()) - MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU; + M_SetItemStatus(MN_MPAUSE, "TEAMCH", IT_STRING | IT_SUBMENU); else if (G_GametypeHasSpectators()) { if (!players[consoleplayer].spectator) - MPauseMenu[mpause_spectate].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "SPECTA", IT_STRING | IT_CALL); else if (players[consoleplayer].pflags & PF_WANTSTOJOIN) - MPauseMenu[mpause_canceljoin].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "CANCJO", IT_STRING | IT_CALL); else - MPauseMenu[mpause_entergame].status = IT_STRING | IT_CALL; + M_SetItemStatus(MN_MPAUSE, "ENTER", IT_STRING | IT_CALL); } else // in this odd case, we still want something to be on the menu even if it's useless - MPauseMenu[mpause_spectate].status = IT_GRAYEDOUT; + M_SetItemStatus(MN_MPAUSE, "SPECTA", IT_GRAYEDOUT); } #ifdef HAVE_DISCORDRPC { - UINT8 i; - - for (i = 0; i < mpause_discordrequests; i++) - MPauseMenu[i].alphaKey -= 8; - - MPauseMenu[mpause_discordrequests].alphaKey = MPauseMenu[i].alphaKey; - + M_AdjustItemY(MN_MPAUSE, "ADDONS", -8); + M_AdjustItemY(MN_MPAUSE, "SCRMBL", -8); + M_AdjustItemY(MN_MPAUSE, "MAPCHG", -8); M_RefreshPauseMenu(); } #endif currentMenu = &MPauseDef; - itemOn = mpause_continue; + M_SetItemOn(MN_MPAUSE, "CONTIN"); } CON_ToggleOff(); // move away console @@ -3749,7 +3868,7 @@ void M_DrawPauseMenu(void) if ((leveltime % freq) >= freq/2) { V_DrawFixedPatch(204 * FRACUNIT, - (currentMenu->y + MPauseMenu[mpause_discordrequests].alphaKey - 1) * FRACUNIT, + (currentMenu->y + (M_GetItemY(MN_MPAUSE, "DISCRQ") - 1) * FRACUNIT, FRACUNIT, 0, W_CachePatchName("K_REQUE2", PU_CACHE), @@ -5068,32 +5187,32 @@ void M_HandleReplayHutList(INT32 choice) { case DFILE_ERROR_CANNOTLOAD: // Only show "Watch Replay Without Addons" - MISC_ReplayStartMenu[0].status = IT_DISABLED; - MISC_ReplayStartMenu[1].status = IT_CALL|IT_STRING; - //MISC_ReplayStartMenu[1].alphaKey = 0; - MISC_ReplayStartMenu[2].status = IT_DISABLED; - itemOn = 1; + M_SetItemStatus(MN_MISC_REPLAYSTART, "LOADWA", IT_DISABLED); + M_SetItemStatus(MN_MISC_REPLAYSTART, "NOLOAD", IT_CALL|IT_STRING); + //M_SetItemY(MN_MISC_REPLAYSTART, "NOLOAD", 0); + M_SetItemStatus(MN_MISC_REPLAYSTART, "WATCH", IT_DISABLED); + M_SetItemOn(MN_MISC_REPLAYSTART, "NOLOAD"); break; case DFILE_ERROR_NOTLOADED: case DFILE_ERROR_INCOMPLETEOUTOFORDER: // Show "Load Addons and Watch Replay" and "Watch Replay Without Addons" - MISC_ReplayStartMenu[0].status = IT_CALL|IT_STRING; - MISC_ReplayStartMenu[1].status = IT_CALL|IT_STRING; - //MISC_ReplayStartMenu[1].alphaKey = 10; - MISC_ReplayStartMenu[2].status = IT_DISABLED; - itemOn = 0; + M_SetItemStatus(MN_MISC_REPLAYSTART, "LOADWA", IT_CALL|IT_STRING); + M_SetItemStatus(MN_MISC_REPLAYSTART, "NOLOAD", IT_CALL|IT_STRING); + //M_SetItemY(MN_MISC_REPLAYSTART, "NOLOAD", 10); + M_SetItemStatus(MN_MISC_REPLAYSTART, "WATCH", IT_DISABLED); + M_SetItemOn(MN_MISC_REPLAYSTART, "LOADWA"); break; case DFILE_ERROR_EXTRAFILES: case DFILE_ERROR_OUTOFORDER: default: // Show "Watch Replay" - MISC_ReplayStartMenu[0].status = IT_DISABLED; - MISC_ReplayStartMenu[1].status = IT_DISABLED; - MISC_ReplayStartMenu[2].status = IT_CALL|IT_STRING; - //MISC_ReplayStartMenu[2].alphaKey = 0; - itemOn = 2; + M_SetItemStatus(MN_MISC_REPLAYSTART, "LOADWA", IT_DISABLED); + M_SetItemStatus(MN_MISC_REPLAYSTART, "NOLOAD", IT_DISABLED); + M_SetItemStatus(MN_MISC_REPLAYSTART, "WATCH", IT_CALL|IT_STRING); + //M_SetItemY(MN_MISC_REPLAYSTART, "WATCH", 0); + M_SetItemOn(MN_MISC_REPLAYSTART, "WATCH"); break; } } @@ -5496,20 +5615,21 @@ void M_HutStartReplay(INT32 choice) (void)choice; M_ClearMenus(false); - demo.loadfiles = (itemOn == 0); - demo.ignorefiles = (itemOn != 0); + demo.loadfiles = M_IsItemOn(MN_MISC_REPLAYSTART, "LOADWA"); + demo.ignorefiles = !M_IsItemOn(MN_MISC_REPLAYSTART, "LOADWA"); G_DoPlayDemo(demolist[dir_on[menudepthleft]].filepath); } void M_SetPlaybackMenuPointer(void) { - itemOn = playback_pause; + M_SetItemOn(MN_PLAYBACK, "PAUSE"); } void M_DrawPlaybackMenu(void) { INT16 i; + INT16 view1index = M_MenuItemRange(MN_PLAYBACK, "VIEW1", "VIEW4", 4); patch_t *icon; UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE); UINT32 transmap = max(0, (INT32)(leveltime - playback_last_menu_interaction_leveltime - 4*TICRATE)) / 5; @@ -5518,44 +5638,65 @@ void M_DrawPlaybackMenu(void) if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE) playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE; + INT16 rewindix = M_MenuItemRange(MN_PLAYBACK, "REWIND", "FASTFW", 3); + INT16 backix = M_MenuItemRange(MN_PLAYBACK, "REWFRA", "ADVFRA", 3); + // Toggle items if (paused && !demo.rewinding) { - PlaybackMenu[playback_pause].status = PlaybackMenu[playback_fastforward].status = PlaybackMenu[playback_rewind].status = IT_DISABLED; - PlaybackMenu[playback_resume].status = PlaybackMenu[playback_advanceframe].status = PlaybackMenu[playback_backframe].status = IT_CALL|IT_STRING; + M_SetItemStatus(MN_PLAYBACK, "PAUSE", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "FASTFW", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "REWIND", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "RESUME", IT_CALL|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "ADVFRA", IT_CALL|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "REWFRA", IT_CALL|IT_STRING); - if (itemOn >= playback_rewind && itemOn <= playback_fastforward) - itemOn += playback_backframe - playback_rewind; + if (itemOn >= rewindix && itemOn <= rewindix+2) + { + i = itemOn - rewindix; + M_SetItemOn(MN_PLAYBACK, "REWFRA"); + itemOn += i; + } } else { - PlaybackMenu[playback_pause].status = PlaybackMenu[playback_fastforward].status = PlaybackMenu[playback_rewind].status = IT_CALL|IT_STRING; - PlaybackMenu[playback_resume].status = PlaybackMenu[playback_advanceframe].status = PlaybackMenu[playback_backframe].status = IT_DISABLED; + M_SetItemStatus(MN_PLAYBACK, "PAUSE", IT_CALL|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "FASTFW", IT_CALL|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "REWIND", IT_CALL|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "RESUME", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "ADVFRA", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "REWFRA", IT_DISABLED); - if (itemOn >= playback_backframe && itemOn <= playback_advanceframe) - itemOn -= playback_backframe - playback_rewind; + if (itemOn >= backix && itemOn <= backix+2) + { + i = itemOn - backix; + M_SetItemOn(MN_PLAYBACK, "REWIND"); + itemOn += i; + } } if (modeattacking) { - for (i = playback_viewcount; i <= playback_view4; i++) - PlaybackMenu[i].status = IT_DISABLED; - PlaybackMenu[playback_freecamera].alphaKey = 72; - PlaybackMenu[playback_quit].alphaKey = 88; + M_SetItemStatus(MN_PLAYBACK, "NUMVIE", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW1", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW2", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW3", IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW4", IT_DISABLED); + M_SetItemX(MN_PLAYBACK, "FRECAM", 72); + M_SetItemX(MN_PLAYBACK, "QUIT", 88); currentMenu->x = BASEVIDWIDTH/2 - 52; } else { - PlaybackMenu[playback_viewcount].status = IT_ARROWS|IT_STRING; + M_SetItemStatus(MN_PLAYBACK, "NUMVIE", IT_ARROWS|IT_STRING); + M_SetItemStatus(MN_PLAYBACK, "VIEW1", r_splitscreen >= 0 ? IT_ARROWS|IT_STRING : IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW2", r_splitscreen >= 1 ? IT_ARROWS|IT_STRING : IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW3", r_splitscreen >= 2 ? IT_ARROWS|IT_STRING : IT_DISABLED); + M_SetItemStatus(MN_PLAYBACK, "VIEW4", r_splitscreen >= 3 ? IT_ARROWS|IT_STRING : IT_DISABLED); - for (i = 0; i <= r_splitscreen; i++) - PlaybackMenu[playback_view1+i].status = IT_ARROWS|IT_STRING; - for (i = r_splitscreen+1; i < 4; i++) - PlaybackMenu[playback_view1+i].status = IT_DISABLED; - - PlaybackMenu[playback_freecamera].alphaKey = 156; - PlaybackMenu[playback_quit].alphaKey = 172; + M_SetItemX(MN_PLAYBACK, "FRECAM", 156); + M_SetItemX(MN_PLAYBACK, "QUIT", 172); currentMenu->x = BASEVIDWIDTH/2 - 88; } @@ -5566,14 +5707,17 @@ void M_DrawPlaybackMenu(void) for (i = 0; i < currentMenu->numitems; i++) { UINT8 *inactivemap = NULL; + char nameon[6]; + M_GetMenuItemNameByIndex(MN_PLAYBACK, i, nameon); - if (i >= playback_view1 && i <= playback_view4) + INT16 splitnum = i - view1index; + if (splitnum >= 0 && splitnum < 4) { if (modeattacking) continue; - if (r_splitscreen >= i - playback_view1) + if (r_splitscreen >= splitnum) { - INT32 ply = displayplayers[i - playback_view1]; + INT32 ply = displayplayers[splitnum]; icon = faceprefix[players[ply].skin][FACE_RANK]; if (i != itemOn) @@ -5591,7 +5735,7 @@ void M_DrawPlaybackMenu(void) else icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp - if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding)) + if ((ITNAMECMP(nameon, "FASTFW") && cv_playbackspeed.value > 1) || (ITNAMECMP(nameon, "REWIND") && demo.rewinding)) V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE)); else V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap); @@ -5605,32 +5749,22 @@ void M_DrawPlaybackMenu(void) if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS) { - char *str; + char *str = NULL; - if (!(i == playback_viewcount && r_splitscreen == 3)) + if (!(ITNAMECMP(nameon, "NUMVIE") && r_splitscreen == 3)) V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5), '\x1A' | transmap|V_SNAPTOTOP|highlightflags, false); // up arrow - if (!(i == playback_viewcount && r_splitscreen == 0)) + if (!(ITNAMECMP(nameon, "NUMVIE") && r_splitscreen == 0)) V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5), '\x1B' | transmap|V_SNAPTOTOP|highlightflags, false); // down arrow - switch (i) - { - case playback_viewcount: + if (ITNAMECMP(nameon, "NUMVIE")) str = va("%d", r_splitscreen+1); - break; - - case playback_view1: - case playback_view2: - case playback_view3: - case playback_view4: - str = player_names[displayplayers[i - playback_view1]]; // 0 to 3 - break; - - default: // shouldn't ever be reached but whatever - continue; - } + else if (splitnum >= 0 && splitnum < 4) + str = player_names[displayplayers[splitnum]]; // 0 to 3 + else + I_Error("bruh"); V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 38, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE|highlightflags, str); } @@ -5727,7 +5861,8 @@ void M_PlaybackSetViews(INT32 choice) void M_PlaybackAdjustView(INT32 choice) { - G_AdjustView(itemOn - playback_viewcount, (choice > 0) ? 1 : -1, true); + INT16 viewix = M_MenuItemRange(MN_PLAYBACK, "VIEW1", "VIEW4", 4); + G_AdjustView((itemOn - viewix)+1, (choice > 0) ? 1 : -1, true); } // this one's rather tricky @@ -5896,19 +6031,15 @@ void M_Options(INT32 choice) (void)choice; // if the player is not admin or server, disable gameplay & server options - OP_MainMenu[5].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + M_SetItemStatus(MN_OP_MAIN, "GAMEPL", Playing() && !(server || IsPlayerAdmin(consoleplayer)) ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); + M_SetItemStatus(MN_OP_MAIN, "SERVER", Playing() && !(server || IsPlayerAdmin(consoleplayer)) ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); - OP_MainMenu[9].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits - OP_MainMenu[10].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits + // no credits or data erasing in-game + M_SetItemStatus(MN_OP_MAIN, "KCRED", Playing() ? IT_GRAYEDOUT : IT_STRING|IT_CALL); + M_SetItemStatus(MN_OP_MAIN, "BCRED", Playing() ? IT_GRAYEDOUT : IT_STRING|IT_CALL); + M_SetItemStatus(MN_OP_DATA, "ERASE", Playing() ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); -#ifdef HAVE_DISCORDRPC - OP_DataOptionsMenu[4].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); // Erase data -#else - OP_DataOptionsMenu[3].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); // Erase data -#endif - - OP_GameOptionsMenu[5].status = - (M_SecretUnlocked(SECRET_ENCORE)) ? (IT_CVAR|IT_STRING) : IT_SECRET; // cv_kartencore + M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET); OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); @@ -5951,11 +6082,11 @@ void M_RefreshPauseMenu(void) #ifdef HAVE_DISCORDRPC if (discordRequestList != NULL) { - MPauseMenu[mpause_discordrequests].status = IT_STRING | IT_SUBMENU; + M_SetItemStatus(MN_MPAUSE, "DISCRQ", IT_STRING | IT_SUBMENU); } else { - MPauseMenu[mpause_discordrequests].status = IT_GRAYEDOUT; + M_SetItemStatus(MN_MPAUSE, "DISCRQ", IT_GRAYEDOUT); } #endif } @@ -6114,9 +6245,9 @@ void M_DrawChecklist(void) void M_EmblemHints(INT32 choice) { (void)choice; - SR_EmblemHintMenu[0].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); + M_SetItemStatus(MN_SR_EMBLEMHINT, "RADAR", M_SecretUnlocked(SECRET_ITEMFINDER) ? IT_CVAR|IT_STRING : IT_SECRET); M_SetupNextMenu(&SR_EmblemHintDef); - itemOn = 1; // always start on back. + M_SetItemOn(MN_SR_EMBLEMHINT, "BACK"); // always start on back. } void M_DrawEmblemHints(void) @@ -6177,18 +6308,18 @@ void M_DrawSkyRoom(void) if (currentMenu == &OP_SoundOptionsDef) { V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, - currentMenu->y+currentMenu->menuitems[0].alphaKey, + currentMenu->y+M_GetItemY(MN_OP_SOUND, "SNDENA"), (sound_disabled ? warningflags : highlightflags), (sound_disabled ? "OFF" : "ON")); V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, - currentMenu->y+currentMenu->menuitems[2].alphaKey, + currentMenu->y+M_GetItemY(MN_OP_SOUND, "MUSENA"), (digital_disabled ? warningflags : highlightflags), (digital_disabled ? "OFF" : "ON")); - if (itemOn == 0) + if (M_IsItemOn(MN_OP_SOUND, "SNDENA")) lengthstring = 8*(sound_disabled ? 3 : 2); - else if (itemOn == 2) + else if (M_IsItemOn(MN_OP_SOUND, "MUSENA")) lengthstring = 8*(digital_disabled ? 3 : 2); } @@ -6621,13 +6752,9 @@ void M_BlanCredits(INT32 choice) void M_SinglePlayerMenu(INT32 choice) { (void)choice; - - SP_MainMenu[spgrandprix].status = IT_CALL|IT_STRING; - SP_MainMenu[sptimeattack].status = - (M_SecretUnlocked(SECRET_TIMEATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; - SP_MainMenu[spitembreaker].status = - (M_SecretUnlocked(SECRET_ITEMBREAKER)) ? IT_CALL|IT_STRING : IT_SECRET; - + M_SetItemStatus(MN_SP_MAIN, "GP", IT_CALL|IT_STRING); + M_SetItemStatus(MN_SP_MAIN, "TA", M_SecretUnlocked(SECRET_TIMEATTACK) ? IT_CALL|IT_STRING : IT_SECRET); + M_SetItemStatus(MN_SP_MAIN, "IT", M_SecretUnlocked(SECRET_ITEMBREAKER) ? IT_CALL|IT_STRING : IT_SECRET); M_SetupNextMenu(&SP_MainDef); } @@ -7177,16 +7304,20 @@ void M_DrawTimeAttackMenu(void) } // ALWAYS DRAW player name, level name, skin and color even when not on this menu! - if (currentMenu != &SP_TimeAttackDef) + // TODO: this whole thing needs to go + menu_t *tamenu = menunum2menudef[MN_SP_TIMEATTACK]; + if (currentMenu != tamenu) { consvar_t *ncv; + INT16 first = M_MenuItemRange(MN_SP_TIMEATTACK, "NAME", "LEVEL", 4); + menuitem_t *taitems = tamenu->menuitems; - for (i = 0; i < 4; ++i) + for (i = first; i < first+4; ++i) { - y = currentMenu->y+SP_TimeAttackMenu[i].alphaKey; - V_DrawString(x, y, V_TRANSLUCENT, SP_TimeAttackMenu[i].text); - ncv = SP_TimeAttackMenu[i].itemaction.cvar; - if (SP_TimeAttackMenu[i].status & IT_CV_STRING) + y = currentMenu->y+taitems[i].alphaKey; + V_DrawString(x, y, V_TRANSLUCENT, taitems[i].text); + ncv = taitems[i].itemaction.cvar; + if (taitems[i].status & IT_CV_STRING) { M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1); V_DrawString(x + 40, y, V_TRANSLUCENT|V_ALLOWLOWERCASE, ncv->string); @@ -7235,7 +7366,7 @@ void M_TimeAttack(INT32 choice) else CV_AddValue(&cv_nextmap, 1); - itemOn = tastart; // "Start" is selected. + M_SetItemOn(MN_SP_TIMEATTACK, "START"); // "Start" is selected. S_ChangeMusicInternal("racent", true); } @@ -7268,7 +7399,7 @@ void M_ItemBreaker(INT32 choice) else CV_AddValue(&cv_nextmap, 1); - itemOn = tastart; // "Start" is selected. + M_SetItemOn(MN_SP_TIMEATTACK, "START"); // "Start" is selected. S_ChangeMusicInternal("racent", true); } @@ -8217,15 +8348,15 @@ void M_DrawMPMainMenu(void) #if MAXPLAYERS != 16 Update the maxplayers label... #endif - V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[4].alphaKey, - ((itemOn == 4) ? highlightflags : 0), "(2-16 players)"); + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+M_GetItemY(MN_MP_MAIN, "STASRV"), + (M_IsItemOn(MN_MP_MAIN, "STASRV") ? highlightflags : 0), "(2-16 players)"); - V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[5].alphaKey, - ((itemOn == 5) ? highlightflags : 0), + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+M_GetItemY(MN_MP_MAIN, "OFLSRV"), + (M_IsItemOn(MN_MP_MAIN, "OFLSRV") ? highlightflags : 0), "(2-4 players)" ); - y += MP_MainMenu[8].alphaKey; + y += M_GetItemY(MN_MP_MAIN, "CONIP"); V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); @@ -8233,7 +8364,7 @@ Update the maxplayers label... V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip); // draw text cursor for name - if (itemOn == 8 + if (M_IsItemOn(MN_MP_MAIN, "CONIP") && skullAnimCounter < 4) //blink cursor V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false); @@ -8265,7 +8396,7 @@ Update the maxplayers label... V_DrawFixedPatch(x<color].name, 0); V_DrawString(BASEVIDWIDTH - mx - st, my + 152, highlightflags|V_ALLOWLOWERCASE, skincolors[setupm_fakecolor->color].name); // SRB2kart - if (itemOn == 3) + if (M_IsItemOn(MN_MP_PLAYERSETUP, "COLOR")) { V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 152, '\x1C' | highlightflags, false); // left arrow @@ -8851,7 +8982,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_LEFTARROW: - if (itemOn == 1) //player skin + if (M_IsItemOn(MN_MP_PLAYERSETUP, "SKIN")) //player skin { S_StartSound(NULL,sfx_menu1); // Tails prev_setupm_fakeskin = setupm_fakeskin; @@ -8864,13 +8995,13 @@ void M_HandleSetupMultiPlayer(INT32 choice) while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_FSTN, NULL); } - else if (itemOn == 2) // follower + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "FOLLOW")) // follower { S_StartSound(NULL,sfx_menu1); setupm_fakefollower--; M_GetFollowerState(); // update follower state } - else if (itemOn == 3) // player color + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "COLOR")) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor = setupm_fakecolor->prev; @@ -8878,7 +9009,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_RIGHTARROW: - if (itemOn == 1) //player skin + if (M_IsItemOn(MN_MP_PLAYERSETUP, "SKIN")) //player skin { S_StartSound(NULL,sfx_menu1); // Tails prev_setupm_fakeskin = setupm_fakeskin; @@ -8891,13 +9022,13 @@ void M_HandleSetupMultiPlayer(INT32 choice) while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_FSTN, NULL); } - else if (itemOn == 2) // follower + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "FOLLOW")) // follower { S_StartSound(NULL,sfx_menu1); setupm_fakefollower++; M_GetFollowerState(); } - else if (itemOn == 3) // player color + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "COLOR")) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor = setupm_fakecolor->next; @@ -8909,7 +9040,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_BACKSPACE: - if (itemOn == 0) + if (M_IsItemOn(MN_MP_PLAYERSETUP, "NAME")) { if ((l = strlen(setupm_name))!=0) { @@ -8917,12 +9048,12 @@ void M_HandleSetupMultiPlayer(INT32 choice) setupm_name[l-1] =0; } } - else if (itemOn == 2) // follower + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "FOLLOW")) // follower { S_StartSound(NULL,sfx_menu1); setupm_fakefollower = -1; } - else if (itemOn == 3) + else if (M_IsItemOn(MN_MP_PLAYERSETUP, "COLOR")) { UINT16 col = skins[setupm_fakeskin].prefcolor; if ((setupm_fakecolor->color != col) && skincolors[col].accessible) @@ -8936,7 +9067,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_DEL: - if (itemOn == 0 && (l = strlen(setupm_name))!=0) + if (M_IsItemOn(MN_MP_PLAYERSETUP, "NAME") && (l = strlen(setupm_name))!=0) { S_StartSound(NULL,sfx_menu1); // Tails setupm_name[0] = 0; @@ -8944,7 +9075,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) break; default: - if (choice < 32 || choice > 127 || itemOn != 0) + if (choice < 32 || choice > 127 || !M_IsItemOn(MN_MP_PLAYERSETUP, "NAME")) break; l = strlen(setupm_name); if (l < MAXPLAYERNAME) @@ -8969,7 +9100,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) } // check color - if (itemOn == 2 && !skincolors[setupm_fakecolor->color].accessible) { + if (M_IsItemOn(MN_MP_PLAYERSETUP, "FOLLOW") && !skincolors[setupm_fakecolor->color].accessible) { if (choice == KEY_LEFTARROW) while (!skincolors[setupm_fakecolor->color].accessible) setupm_fakecolor = setupm_fakecolor->prev; @@ -9024,9 +9155,9 @@ void M_SetupMultiPlayer(INT32 choice) // disable skin changes if we can't actually change skins if (!CanChangeSkin(consoleplayer)) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER|IT_STRING); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -9068,9 +9199,9 @@ void M_SetupMultiPlayer2(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen && !CanChangeSkin(g_localplayers[1])) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -9112,9 +9243,9 @@ void M_SetupMultiPlayer3(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen > 1 && !CanChangeSkin(g_localplayers[2])) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -9156,9 +9287,9 @@ void M_SetupMultiPlayer4(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen > 2 && !CanChangeSkin(g_localplayers[3])) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -9557,26 +9688,26 @@ void M_Setup1PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[0].itemaction.routine = M_Setup1PJoystickMenu; - OP_AllControlsMenu[1].itemaction.cvar = &cv_deadzone[0]; + M_SetItemRoutine(MN_OP_CHANGECONTROLS, "SETJOY", M_Setup1PJoystickMenu); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEADZ", &cv_deadzone[0]); // Unhide P1-only controls - OP_AllControlsMenu[16].status = IT_CONTROL; // Chat - //OP_AllControlsMenu[17].status = IT_CONTROL; // Team-chat - OP_AllControlsMenu[17].status = IT_CONTROL; // Rankings - //OP_AllControlsMenu[18].status = IT_CONTROL; // Viewpoint + M_SetItemStatus(MN_OP_CHANGECONTROLS, "TALK", IT_CONTROL); // Chat + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "TEAM", IT_CONTROL); // Team-chat + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCORES", IT_CONTROL); // Rankings + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "VIEWPT", IT_CONTROL); // Viewpoint // 19 is Reset Camera, 20 is Toggle Chasecam - OP_AllControlsMenu[21].status = IT_CONTROL; // Pause - OP_AllControlsMenu[22].status = IT_CONTROL; // Screenshot - OP_AllControlsMenu[23].status = IT_CONTROL; // GIF - OP_AllControlsMenu[24].status = IT_CONTROL; // System Menu - OP_AllControlsMenu[25].status = IT_CONTROL; // Console - /*OP_AllControlsMenu[26].status = IT_HEADER; // Spectator Controls header - OP_AllControlsMenu[27].status = IT_SPACE; // Spectator Controls space - OP_AllControlsMenu[28].status = IT_CONTROL; // Spectate - OP_AllControlsMenu[29].status = IT_CONTROL; // Look Up - OP_AllControlsMenu[30].status = IT_CONTROL; // Look Down - OP_AllControlsMenu[31].status = IT_CONTROL; // Center View + M_SetItemStatus(MN_OP_CHANGECONTROLS, "PAUSE", IT_CONTROL); // Pause + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCRSHT", IT_CONTROL); // Screenshot + M_SetItemStatus(MN_OP_CHANGECONTROLS, "RECGIF", IT_CONTROL); // GIF + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SYSMEN", IT_CONTROL); // System Menu + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CONSOL", IT_CONTROL); // Console + /*M_SetItemStatus(MN_OP_CHANGECONTROLS, 26, IT_HEADER); // Spectator Controls header + M_SetItemStatus(MN_OP_CHANGECONTROLS, 27, IT_SPACE); // Spectator Controls space + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SPECTA", IT_CONTROL); // Spectate + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKUP", IT_CONTROL); // Look Up + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKDW", IT_CONTROL); // Look Down + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_CONTROL); // Center View */ M_SetupNextMenu(&OP_AllControlsDef); @@ -9590,26 +9721,26 @@ void M_Setup2PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[0].itemaction.routine = M_Setup2PJoystickMenu; - OP_AllControlsMenu[1].itemaction.cvar = &cv_deadzone[1]; + M_SetItemRoutine(MN_OP_CHANGECONTROLS, "SETJOY", M_Setup2PJoystickMenu); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEADZ", &cv_deadzone[1]); // Hide P1-only controls - OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat - //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat - OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings - //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint + M_SetItemStatus(MN_OP_CHANGECONTROLS, "TALK", IT_GRAYEDOUT2); // Chat + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "TEAM", IT_GRAYEDOUT2); // Team-chat + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCORES", IT_GRAYEDOUT2); // Rankings + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "VIEWPT", IT_GRAYEDOUT2); // Viewpoint // 19 is Reset Camera, 20 is Toggle Chasecam - OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause - OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot - OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF - OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu - OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console - /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header - OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space - OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate - OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up - OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down - OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View + M_SetItemStatus(MN_OP_CHANGECONTROLS, "PAUSE", IT_GRAYEDOUT2); // Pause + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCRSHT", IT_GRAYEDOUT2); // Screenshot + M_SetItemStatus(MN_OP_CHANGECONTROLS, "RECGIF", IT_GRAYEDOUT2); // GIF + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SYSMEN", IT_GRAYEDOUT2); // System Menu + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CONSOL", IT_GRAYEDOUT2); // Console + /*M_SetItemStatus(MN_OP_CHANGECONTROLS, 26, IT_GRAYEDOUT2); // Spectator Controls header + M_SetItemStatus(MN_OP_CHANGECONTROLS, 27, IT_GRAYEDOUT2); // Spectator Controls space + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SPECTA", IT_GRAYEDOUT2); // Spectate + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKUP", IT_GRAYEDOUT2); // Look Up + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKDW", IT_GRAYEDOUT2); // Look Down + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ M_SetupNextMenu(&OP_AllControlsDef); @@ -9623,26 +9754,26 @@ void M_Setup3PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[0].itemaction.routine = M_Setup3PJoystickMenu; - OP_AllControlsMenu[1].itemaction.cvar = &cv_deadzone[2]; + M_SetItemRoutine(MN_OP_CHANGECONTROLS, "SETJOY", M_Setup3PJoystickMenu); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEADZ", &cv_deadzone[2]); // Hide P1-only controls - OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat - //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat - OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings - //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint + M_SetItemStatus(MN_OP_CHANGECONTROLS, "TALK", IT_GRAYEDOUT2); // Chat + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "TEAM", IT_GRAYEDOUT2); // Team-chat + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCORES", IT_GRAYEDOUT2); // Rankings + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "VIEWPT", IT_GRAYEDOUT2); // Viewpoint // 19 is Reset Camera, 20 is Toggle Chasecam - OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause - OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot - OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF - OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu - OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console - /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header - OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space - OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate - OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up - OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down - OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View + M_SetItemStatus(MN_OP_CHANGECONTROLS, "PAUSE", IT_GRAYEDOUT2); // Pause + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCRSHT", IT_GRAYEDOUT2); // Screenshot + M_SetItemStatus(MN_OP_CHANGECONTROLS, "RECGIF", IT_GRAYEDOUT2); // GIF + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SYSMEN", IT_GRAYEDOUT2); // System Menu + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CONSOL", IT_GRAYEDOUT2); // Console + /*M_SetItemStatus(MN_OP_CHANGECONTROLS, 26, IT_GRAYEDOUT2); // Spectator Controls header + M_SetItemStatus(MN_OP_CHANGECONTROLS, 27, IT_GRAYEDOUT2); // Spectator Controls space + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SPECTA", IT_GRAYEDOUT2); // Spectate + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKUP", IT_GRAYEDOUT2); // Look Up + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKDW", IT_GRAYEDOUT2); // Look Down + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ M_SetupNextMenu(&OP_AllControlsDef); @@ -9656,26 +9787,26 @@ void M_Setup4PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[0].itemaction.routine = M_Setup4PJoystickMenu; - OP_AllControlsMenu[1].itemaction.cvar = &cv_deadzone[3]; + M_SetItemRoutine(MN_OP_CHANGECONTROLS, "SETJOY", M_Setup4PJoystickMenu); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEADZ", &cv_deadzone[3]); // Hide P1-only controls - OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat - //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat - OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings - //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint + M_SetItemStatus(MN_OP_CHANGECONTROLS, "TALK", IT_GRAYEDOUT2); // Chat + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "TEAM", IT_GRAYEDOUT2); // Team-chat + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCORES", IT_GRAYEDOUT2); // Rankings + //M_SetItemStatus(MN_OP_CHANGECONTROLS, "VIEWPT", IT_GRAYEDOUT2); // Viewpoint // 19 is Reset Camera, 20 is Toggle Chasecam - OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause - OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot - OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF - OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu - OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console - /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header - OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space - OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate - OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up - OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down - OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View + M_SetItemStatus(MN_OP_CHANGECONTROLS, "PAUSE", IT_GRAYEDOUT2); // Pause + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SCRSHT", IT_GRAYEDOUT2); // Screenshot + M_SetItemStatus(MN_OP_CHANGECONTROLS, "RECGIF", IT_GRAYEDOUT2); // GIF + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SYSMEN", IT_GRAYEDOUT2); // System Menu + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CONSOL", IT_GRAYEDOUT2); // Console + /*M_SetItemStatus(MN_OP_CHANGECONTROLS, 26, IT_GRAYEDOUT2); // Spectator Controls header + M_SetItemStatus(MN_OP_CHANGECONTROLS, 27, IT_GRAYEDOUT2); // Spectator Controls space + M_SetItemStatus(MN_OP_CHANGECONTROLS, "SPECTA", IT_GRAYEDOUT2); // Spectate + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKUP", IT_GRAYEDOUT2); // Look Up + M_SetItemStatus(MN_OP_CHANGECONTROLS, "LOOKDW", IT_GRAYEDOUT2); // Look Down + M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ M_SetupNextMenu(&OP_AllControlsDef); @@ -10034,7 +10165,7 @@ void M_DrawVideoMenu(void) { M_DrawGenericMenu(); - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + OP_VideoOptionsMenu[0].alphaKey, + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + M_GetItemY(MN_OP_VIDEO, "SETMOD"), (SCR_IsAspectCorrect(vid.width, vid.height) ? recommendedflags : highlightflags), va("%dx%d", vid.width, vid.height)); @@ -10042,15 +10173,15 @@ void M_DrawVideoMenu(void) // Hide some options based on the current render mode if (rendermode == render_opengl) { - OP_VideoOptionsMenu[op_video_ogl].status = IT_CALL | IT_STRING; - //OP_VideoOptionsMenu[op_video_para].status = IT_DISABLED; + M_SetItemStatus(MN_OP_VIDEO, "OPENGL", IT_CALL | IT_STRING); + //M_SetItemStatus(MN_OP_VIDEO, "PARSOF", IT_DISABLED); } else #endif { - //OP_VideoOptionsMenu[op_video_para].status = IT_CALL | IT_CVAR; + //M_SetItemStatus(MN_OP_VIDEO, "PARSOF", IT_CALL | IT_CVAR); #ifdef HWRENDER - OP_VideoOptionsMenu[op_video_ogl].status = IT_DISABLED; + M_SetItemStatus(MN_OP_VIDEO, "OPENGL", IT_DISABLED); #endif } } @@ -10709,13 +10840,13 @@ static void M_DrawDiscordRequests(void) if (discordRequestList == NULL) { // No other requests - MPauseMenu[mpause_discordrequests].status = IT_GRAYEDOUT; + M_SetItemStatus(MN_MPAUSE, "DISCRQ", IT_GRAYEDOUT); if (currentMenu->prevMenu) { M_SetupNextMenu(currentMenu->prevMenu); if (currentMenu == &MPauseDef) - itemOn = mpause_continue; + M_SetItemOn(MN_MPAUSE, "CONTIN"); } else M_ClearMenus(true); diff --git a/src/m_menu.h b/src/m_menu.h index a342df50d..14a2b25d1 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -362,8 +362,14 @@ struct menuitem_t // hotkey in menu or y of the item UINT16 alphaKey; + + // an identifier to replace hardcoded indices + char itemname[6]; }; +// so i don't have to put magic numbers everywhere +#define ITNAMECMP(s1, s2) !strncmp(s1, s2, 6) + struct menu_t { UINT32 menuid; // ID to encode menu type and hierarchy diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 28ce90af8..a76a0820f 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -109,13 +109,13 @@ typedef off_t off64_t; #endif static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2, "SRB2"}, {3, "CUSTOM"}, {0, NULL}}; -consvar_t cv_screenshot_option = CVAR_INIT ("screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange); +consvar_t cv_screenshot_option = CVAR_INIT ("screenshot_option", "Default", CV_SAVE|CV_CALL|CV_NOINIT, screenshot_cons_t, Screenshot_option_Onchange); consvar_t cv_screenshot_folder = CVAR_INIT ("screenshot_folder", "", CV_SAVE, NULL, NULL); consvar_t cv_screenshot_colorprofile = CVAR_INIT ("screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL); static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}}; -consvar_t cv_moviemode = CVAR_INIT ("moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange); +consvar_t cv_moviemode = CVAR_INIT ("moviemode_mode", "GIF", CV_SAVE|CV_CALL|CV_NOINIT, moviemode_cons_t, Moviemode_mode_Onchange); consvar_t cv_movie_option = CVAR_INIT ("movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange); consvar_t cv_movie_folder = CVAR_INIT ("movie_folder", "", CV_SAVE, NULL, NULL); From d0bb9a33cee077ebe9480cc70dbe8cd32a9d1c40 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Thu, 20 Mar 2025 02:13:23 +0100 Subject: [PATCH 11/33] DEATH TO ALL HARDCODE MENUS except master server and discord :^) --- src/deh_soc.c | 20 +- src/m_menu.c | 1403 +------------------------------------------------ src/m_menu.h | 66 --- 3 files changed, 24 insertions(+), 1465 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 353c6d102..30690964d 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2145,6 +2145,15 @@ void readtextprompt(MYFILE *f, INT32 num) Z_Free(s); } +static menu_t *allocmenu(INT32 num) +{ + if (num < 0 || num >= NUMMENUTYPES) + I_Error("Tried to allocate out-of-range menu number"); + if (menunum2menudef[num] == NULL) + menunum2menudef[num] = Z_Malloc(sizeof(menu_t), PU_STATIC, NULL); + return menunum2menudef[num]; +} + // super secret menu cvars... :shushing_face: static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { { "CHOOSESKIN", &cv_chooseskin }, @@ -2294,7 +2303,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) } actionset = true; menuitem->status |= IT_SUBMENU; - menuitem->itemaction.submenu = menunum2menudef[mn]; + menuitem->itemaction.submenu = allocmenu(mn); } else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS")) { @@ -2359,12 +2368,7 @@ void readmenu(MYFILE *f, INT32 num) INT32 value; boolean space = false; - menu_t *menudef = menunum2menudef[num]; - if (menudef == NULL) - { - deh_warning("No def for menu %d, that is certainly strange...", num); - return; - } + menu_t *menudef = allocmenu(num); //menuactive = false; @@ -2579,7 +2583,7 @@ void readmenu(MYFILE *f, INT32 num) deh_warning("Menu %d: unknown previous menu '%s'", num, word2); continue; } - menudef->prevMenu = menunum2menudef[value]; + menudef->prevMenu = allocmenu(value); } else if (fastcmp(word, "DRAWROUTINE")) { diff --git a/src/m_menu.c b/src/m_menu.c index 6cc94cc17..a747c4138 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -210,63 +210,26 @@ static void M_HandleDiscordRequests(INT32 choice); static void M_DrawDiscordRequests(void); #endif -menu_t SPauseDef; - #define lsheadingheight 16 // Sky Room static char *M_GetConditionString(condition_t cond); -menu_t SR_MainDef, SR_UnlockChecklistDef; - -// Misc. Main Menu -menu_t SP_MainDef, MP_MainDef, OP_MainDef; -menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef; - -// Single Player -menu_t SP_LevelStatsDef; -static menu_t SP_GrandPrixTempDef; -static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; // Multiplayer static void M_ConnectMenu(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); -// Options -// Split into multiple parts due to size -// Controls -menu_t OP_ControlsDef, OP_AllControlsDef; -menu_t OP_MouseOptionsDef; - -//camera options menu -menu_t OP_CamOptionsDef; -menu_t OP_Player1CamOptionsDef, OP_Player2CamOptionsDef, OP_Player3CamOptionsDef, OP_Player4CamOptionsDef; - -// Video & Sound -menu_t OP_VideoOptionsDef, OP_VideoModeDef; -#ifdef HWRENDER -menu_t OP_OpenGLOptionsDef; -#endif -menu_t OP_SoundOptionsDef; - //Misc -menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef; #ifdef HAVE_DISCORDRPC menu_t OP_DiscordOptionsDef; #endif -menu_t OP_HUDOptionsDef, OP_ChatOptionsDef; -menu_t OP_GameOptionsDef, OP_BlanKartGameOptionsDef, OP_ServerOptionsDef; -menu_t OP_AdvServerOptionsDef; -menu_t OP_MonitorToggleDef; static patch_t *addonsp[NUM_EXT+5]; #define numaddonsshown 4 // Replay hut -menu_t MISC_ReplayHutDef; -menu_t MISC_ReplayOptionsDef; - static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked // Drawing functions @@ -283,32 +246,24 @@ static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); // temporary measure until menu_t and menupres_t are merged (hopefully) -menu_t MP_PlayerSetupDef, MP_ServerDef, MP_OfflineServerDef, OP_AddonsOptionsDef, MISC_AddonsDef, MPauseDef, MAPauseDef, SR_EmblemHintDef, SR_PandoraDef, MISC_ChangeLevelDef, MISC_ReplayStartDef, PlaybackMenuDef, MISC_HelpDef, SR_MusicTestDef, OP_JoystickSetDef; +static menu_t MP_MainDef = {0}, OP_OpenGLOptionsDef = {0}, SP_TimeAttackDef = {0}, +OP_SoundOptionsDef = {0}, OP_MainDef = {0}, PlaybackMenuDef = {0}, MAPauseDef = {0}, +SPauseDef = {0}, MPauseDef = {0}, OP_AddonsOptionsDef = {0}, MISC_AddonsDef = {0}, +MISC_ReplayHutDef = {0}, SR_PandoraDef = {0}, MISC_HelpDef = {0}, SR_EmblemHintDef = {0}, +SR_MusicTestDef = {0}, SP_MainDef = {0}, SP_LevelStatsDef = {0}, SP_GrandPrixTempDef = {0}, +MISC_ReplayStartDef = {0}, SP_ReplayDef = {0}, MP_OfflineServerDef = {0}, +MISC_ChangeLevelDef = {0}, MP_ServerDef = {0}, MP_PlayerSetupDef = {0}, +OP_ScreenshotOptionsDef = {0}, OP_AllControlsDef = {0}, OP_VideoModeDef = {0}, +OP_DataOptionsDef = {0}; +menu_t MainDef = {0}, OP_JoystickSetDef = {0}; menu_t *menunum2menudef[NUMMENUTYPES] = { - [MN_OP_CAMERA] = &OP_CamOptionsDef, - [MN_OP_P1CAMERA] = &OP_Player1CamOptionsDef, - [MN_OP_P2CAMERA] = &OP_Player2CamOptionsDef, - [MN_OP_P3CAMERA] = &OP_Player3CamOptionsDef, - [MN_OP_P4CAMERA] = &OP_Player4CamOptionsDef, - [MN_OP_MAIN] = &OP_MainDef, - [MN_OP_CONTROLSETUP] = &OP_ControlsDef, - [MN_OP_VIDEO] = &OP_VideoOptionsDef, [MN_OP_VIDEOMODE] = &OP_VideoModeDef, [MN_OP_OPENGL] = &OP_OpenGLOptionsDef, [MN_OP_SOUND] = &OP_SoundOptionsDef, - [MN_OP_CHAT] = &OP_ChatOptionsDef, - [MN_OP_HUD] = &OP_HUDOptionsDef, - [MN_OP_GAME] = &OP_GameOptionsDef, - [MN_OP_BLANKARTGAME] = &OP_BlanKartGameOptionsDef, - [MN_OP_SERVER] = &OP_ServerOptionsDef, - [MN_OP_ADVANCEDSERVER] = &OP_AdvServerOptionsDef, - [MN_OP_MONITORTOGGLE] = &OP_MonitorToggleDef, [MN_OP_DATA] = &OP_DataOptionsDef, [MN_OP_ADDONS] = &OP_AddonsOptionsDef, [MN_OP_SCREENSHOTS] = &OP_ScreenshotOptionsDef, - [MN_OP_ERASEDATA] = &OP_EraseDataDef, - [MN_MISC_REPLAYOPTIONS] = &MISC_ReplayOptionsDef, [MN_MP_MAIN] = &MP_MainDef, [MN_MP_PLAYERSETUP] = &MP_PlayerSetupDef, @@ -318,12 +273,8 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_SP_MAIN] = &SP_MainDef, [MN_SP_GRANDPRIX] = &SP_GrandPrixTempDef, [MN_SP_TIMEATTACK] = &SP_TimeAttackDef, - [MN_SP_GUESTREPLAY] = &SP_GuestReplayDef, [MN_SP_REPLAY] = &SP_ReplayDef, - [MN_SP_GHOST] = &SP_GhostDef, - [MN_SR_MAIN] = &SR_MainDef, - [MN_SR_UNLOCKCHECKLIST] = &SR_UnlockChecklistDef, [MN_SP_LEVELSTATS] = &SP_LevelStatsDef, [MN_MISC_REPLAYHUT] = &MISC_ReplayHutDef, [MN_SR_EMBLEMHINT] = &SR_EmblemHintDef, @@ -333,10 +284,7 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_SPAUSE] = &SPauseDef, [MN_MPAUSE] = &MPauseDef, - [MN_SCRAMBLETEAM] = &MISC_ScrambleTeamDef, - [MN_CHANGETEAM] = &MISC_ChangeTeamDef, [MN_MAPAUSE] = &MAPauseDef, - [MN_CHANGESPECTATE] = &MISC_ChangeSpectateDef, [MN_CHANGELEVEL] = &MISC_ChangeLevelDef, // who even cares how i sort this shit anymore @@ -551,208 +499,6 @@ consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HI consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL); consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL); -// ========================================================================== -// ORGANIZATION START. -// ========================================================================== -// Note: Never should we be jumping from one category of menu options to another -// without first going to the Main Menu. -// Note: Ignore the above if you're working with the Pause menu. -// Note: (Prefix)_MainMenu should be the target of all Main Menu options that -// point to submenus. - -// --------- -// Main Menu -// --------- -static menuitem_t MainMenu[] = -{ - {IT_SUBMENU|IT_STRING, NULL, "Extras", {.submenu = &SR_MainDef}, 76}, - {IT_CALL |IT_STRING, NULL, "1 Player", {.routine = M_SinglePlayerMenu}, 84}, - {IT_SUBMENU|IT_STRING, NULL, "Multiplayer", {.submenu = &MP_MainDef}, 92}, - {IT_CALL |IT_STRING, NULL, "Options", {.routine = M_Options}, 100}, - /* I don't think is useful at all... */ - {IT_CALL |IT_STRING, NULL, "Addons", {.routine = M_Addons}, 108}, - {IT_CALL |IT_STRING, NULL, "Quit Game", {.routine = M_QuitSRB2}, 116}, -}; - -typedef enum -{ - secrets = 0, - singleplr, - multiplr, - options, - addons, - quitdoom -} main_e; - -static menuitem_t MISC_AddonsMenu[] = -{ - {IT_KEYHANDLER | IT_NOTHING, NULL, "", {.routine = M_HandleAddons}, 0}, // dummy menuitem for the control func -}; - -static menuitem_t MISC_ReplayHutMenu[] = -{ - {IT_KEYHANDLER|IT_NOTHING, NULL, "", {.routine = M_HandleReplayHutList}, 0}, // Dummy menuitem for the replay list - {IT_NOTHING, NULL, "", {NULL}, 0}, // Dummy for handling wrapping to the top of the menu.. -}; - -static menuitem_t MISC_ReplayStartMenu[] = -{ - {IT_CALL |IT_STRING, NULL, "Load Addons and Watch", {.routine = M_HutStartReplay}, 0}, - {IT_CALL |IT_STRING, NULL, "Watch Without Addons", {.routine = M_HutStartReplay}, 10}, - {IT_CALL |IT_STRING, NULL, "Watch Replay", {.routine = M_HutStartReplay}, 10}, - {IT_SUBMENU |IT_STRING, NULL, "Back", {.submenu = &MISC_ReplayHutDef}, 30}, -}; - -static menuitem_t MISC_ReplayOptionsMenu[] = -{ - {IT_CVAR|IT_STRING, NULL, "Record Replays", {.cvar = &cv_recordmultiplayerdemos}, 0}, - {IT_CVAR|IT_STRING, NULL, "Sync Check Interval", {.cvar = &cv_netdemosyncquality}, 10}, -}; - -static tic_t playback_last_menu_interaction_leveltime = 0; -static menuitem_t PlaybackMenu[] = -{ - {IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu (Esc)", {.routine = M_SelectableClearMenus}, 0}, - - {IT_CALL | IT_STRING, "M_PREW", "Rewind ([)", {.routine = M_PlaybackRewind}, 20}, - {IT_CALL | IT_STRING, "M_PPAUSE", "Pause (\\)", {.routine = M_PlaybackPause}, 36}, - {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward (])", {.routine = M_PlaybackFastForward}, 52}, - {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame ([)", {.routine = M_PlaybackRewind}, 20}, - {IT_CALL | IT_STRING, "M_PRESUM", "Resume", {.routine = M_PlaybackPause}, 36}, - {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame (])", {.routine = M_PlaybackAdvance}, 52}, - - {IT_ARROWS | IT_STRING, "M_PVIEWS", "View Count (- and =)", {.routine = M_PlaybackSetViews}, 72}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint (1)", {.routine = M_PlaybackAdjustView}, 88}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 2 (2)", {.routine = M_PlaybackAdjustView}, 104}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 3 (3)", {.routine = M_PlaybackAdjustView}, 120}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 4 (4)", {.routine = M_PlaybackAdjustView}, 136}, - - {IT_CALL | IT_STRING, "M_PVIEWS", "Toggle Free Camera (')", {.routine = M_PlaybackToggleFreecam}, 156}, - {IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", {.routine = M_PlaybackQuit}, 172}, -}; -typedef enum -{ - playback_hide, - playback_rewind, - playback_pause, - playback_fastforward, - playback_backframe, - playback_resume, - playback_advanceframe, - playback_viewcount, - playback_view1, - playback_view2, - playback_view3, - playback_view4, - playback_freecamera, - //playback_moreoptions, - playback_quit -} playback_e; - -// --------------------------------- -// Pause Menu Mode Attacking Edition -// --------------------------------- -static menuitem_t MAPauseMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Continue", {.routine = M_SelectableClearMenus},48}, - {IT_CALL | IT_STRING, NULL, "Retry", {.routine = M_ModeAttackRetry}, 56}, - {IT_CALL | IT_STRING, NULL, "Abort", {.routine = M_ModeAttackEndGame}, 64}, -}; - -typedef enum -{ - mapause_continue, - mapause_retry, - mapause_abort -} mapause_e; - -// --------------------- -// Pause Menu MP Edition -// --------------------- -static menuitem_t MPauseMenu[] = -{ - {IT_STRING | IT_CALL, NULL, "Addons...", {.routine = M_Addons}, 8}, - {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", {.submenu = &MISC_ScrambleTeamDef}, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Map..." , {.routine = M_MapChange}, 24}, - -#ifdef HAVE_DISCORDRPC - {IT_STRING | IT_SUBMENU, NULL, "Ask To Join Requests...", {.submenu = &MISC_DiscordRequestsDef}, 24}, -#endif - - {IT_CALL | IT_STRING, NULL, "Continue", {.routine = M_SelectableClearMenus}, 40}, - {IT_CALL | IT_STRING, NULL, "P1 Setup...", {.routine = M_SetupMultiPlayer}, 48}, // splitscreen - {IT_CALL | IT_STRING, NULL, "P2 Setup...", {.routine = M_SetupMultiPlayer2}, 56}, // splitscreen - {IT_CALL | IT_STRING, NULL, "P3 Setup...", {.routine = M_SetupMultiPlayer3}, 64}, // splitscreen - {IT_CALL | IT_STRING, NULL, "P4 Setup...", {.routine = M_SetupMultiPlayer4}, 72}, // splitscreen - - {IT_STRING | IT_CALL, NULL, "Spectate", {.routine = M_ConfirmSpectate}, 48}, // alone - {IT_STRING | IT_CALL, NULL, "Enter Game", {.routine = M_ConfirmEnterGame}, 48}, // alone - {IT_STRING | IT_CALL, NULL, "Cancel Join", {.routine = M_ConfirmSpectate}, 48}, // alone - {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", {.submenu = &MISC_ChangeTeamDef}, 48}, - {IT_STRING | IT_SUBMENU, NULL, "Enter/Spectate...", {.submenu = &MISC_ChangeSpectateDef}, 48}, - {IT_CALL | IT_STRING, NULL, "Player Setup...", {.routine = M_SetupMultiPlayer}, 56}, // alone - {IT_CALL | IT_STRING, NULL, "Options", {.routine = M_Options}, 64}, - - {IT_CALL | IT_STRING, NULL, "Return to Title", {.routine = M_EndGame}, 80}, - {IT_CALL | IT_STRING, NULL, "Quit Game", {.routine = M_QuitSRB2}, 88}, -}; - -typedef enum -{ - mpause_addons = 0, - mpause_scramble, - mpause_switchmap, -#ifdef HAVE_DISCORDRPC - mpause_discordrequests, -#endif - - mpause_continue, - mpause_psetupsplit, - mpause_psetupsplit2, - mpause_psetupsplit3, - mpause_psetupsplit4, - - mpause_spectate, - mpause_entergame, - mpause_canceljoin, - mpause_switchteam, - mpause_switchspectate, - mpause_psetup, - mpause_options, - - mpause_title, - mpause_quit -} mpause_e; - -// --------------------- -// Pause Menu SP Edition -// --------------------- -static menuitem_t SPauseMenu[] = -{ - // Pandora's Box will be shifted up if both options are available - {IT_CALL | IT_STRING, NULL, "Pandora's Box...", {.routine = M_PandorasBox}, 16}, - {IT_CALL | IT_STRING, NULL, "Medal Hints...", {.routine = M_EmblemHints}, 24}, - - {IT_CALL | IT_STRING, NULL, "Continue", {.routine = M_SelectableClearMenus},48}, - {IT_CALL | IT_STRING, NULL, "Retry", {.routine = M_Retry}, 56}, - {IT_CALL | IT_STRING, NULL, "Options", {.routine = M_Options}, 64}, - - {IT_CALL | IT_STRING, NULL, "Return to Title", {.routine = M_EndGame}, 80}, - {IT_CALL | IT_STRING, NULL, "Quit Game", {.routine = M_QuitSRB2}, 88}, -}; - -typedef enum -{ - spause_pandora = 0, - spause_hints, - - spause_continue, - spause_retry, - spause_options, - spause_title, - spause_quit -} spause_e; - #ifdef HAVE_DISCORDRPC static menuitem_t MISC_DiscordRequestsMenu[] = { @@ -760,290 +506,7 @@ static menuitem_t MISC_DiscordRequestsMenu[] = }; #endif -// ----------------- -// Misc menu options -// ----------------- -// Prefix: MISC_ -static menuitem_t MISC_ScrambleTeamMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Scramble Method", {.cvar = &cv_dummyscramble}, 30}, - {IT_WHITESTRING|IT_CALL, NULL, "Confirm", {.routine = M_ConfirmTeamScramble}, 90}, -}; - -static menuitem_t MISC_ChangeTeamMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Player", {.cvar = &cv_dummymenuplayer}, 30}, - {IT_STRING|IT_CVAR, NULL, "Team", {.cvar = &cv_dummyteam}, 40}, - {IT_WHITESTRING|IT_CALL, NULL, "Confirm", {.routine = M_ConfirmTeamChange}, 90}, -}; - -static menuitem_t MISC_ChangeSpectateMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Player", {.cvar = &cv_dummymenuplayer}, 30}, - {IT_STRING|IT_CVAR, NULL, "Status", {.cvar = &cv_dummyspectate}, 40}, - {IT_WHITESTRING|IT_CALL, NULL, "Confirm", {.routine = M_ConfirmSpectateChange}, 90}, -}; - -static menuitem_t MISC_ChangeLevelMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Game Type", {.cvar = &cv_newgametype}, 68}, - {IT_STRING|IT_CVAR, NULL, "Level", {.cvar = &cv_nextmap}, 78}, - {IT_WHITESTRING|IT_CALL, NULL, "Change Level", {.routine = M_ChangeLevel}, 130}, -}; - -static menuitem_t MISC_HelpMenu[] = -{ - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL00", {.routine = M_HandleImageDef}, 0}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL01", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL02", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL03", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL04", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL05", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL06", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL07", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL08", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL09", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL10", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL11", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL12", {.routine = M_HandleImageDef}, 1}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "MANUAL99", {.routine = M_HandleImageDef}, 0}, -}; - -// -------------------------------- -// Sky Room and all of its submenus -// -------------------------------- -// Prefix: SR_ - -// Pause Menu Pandora's Box Options -static menuitem_t SR_PandorasBox[] = -{ - {IT_STRING | IT_CVAR, NULL, "Rings", {.cvar = &cv_dummyrings}, 20}, - {IT_STRING | IT_CVAR, NULL, "Lives", {.cvar = &cv_dummylives}, 30}, - - {IT_STRING | IT_CVAR, NULL, "Gravity", {.cvar = &cv_gravity}, 60}, - - {IT_STRING | IT_CALL, NULL, "Get All Emeralds", {.routine = M_GetAllEmeralds}, 90}, - {IT_STRING | IT_CALL, NULL, "Destroy All Robots", {.routine = M_DestroyRobots}, 100}, - - {IT_STRING | IT_CALL, NULL, "Ultimate Cheat", {.routine = M_UltimateCheat}, 130}, -}; - -// Sky Room Custom Unlocks -static menuitem_t SR_MainMenu[] = -{ - {IT_STRING|IT_SUBMENU, NULL, "Unlockables", {.submenu = &SR_UnlockChecklistDef}, 100}, - {IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED, NULL, "Statistics", {.routine = M_Statistics}, 108}, - {IT_CALL|IT_STRING, NULL, "Replay Hut", {.routine = M_ReplayHut}, 116}, - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom1 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom2 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom3 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom4 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom5 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom6 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom7 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom8 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom9 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom10 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom11 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom12 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom13 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom14 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom15 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom16 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom17 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom18 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom19 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom20 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom21 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom22 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom23 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom24 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom25 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom26 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom27 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom28 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom29 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom30 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom31 - {IT_DISABLED, NULL, "", {NULL}, 0}, // Custom32 - -}; - -static menuitem_t SR_UnlockChecklistMenu[] = -{ - {IT_SUBMENU | IT_STRING, NULL, "NEXT", {.submenu = &MainDef}, 192}, -}; - -static menuitem_t SR_MusicTestMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, "", {.routine = M_HandleMusicTest}, 0}, -}; -static menuitem_t SR_EmblemHintMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Medal Radar", {.cvar = &cv_itemfinder}, 10}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SPauseDef}, 20} -}; - -// -------------------------------- -// 1 Player and all of its submenus -// -------------------------------- -// Prefix: SP_ - -// Single Player Main -static menuitem_t SP_MainMenu[] = -{ - {IT_STRING|IT_CALL, NULL, "Grand Prix", {.routine = M_GrandPrixTemp}, 92}, - {IT_SECRET, NULL, "Time Attack", {.routine = M_TimeAttack}, 100}, - {IT_SECRET, NULL, "Item Breaker", {.routine = M_ItemBreaker}, 108}, -}; - -enum -{ - spgrandprix, - sptimeattack, - spitembreaker, -}; - -// Single Player Load Game -static menuitem_t SP_GrandPrixPlaceholderMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Character", {.cvar = &cv_chooseskin}, 10}, - {IT_STRING|IT_CVAR, NULL, "Color", {.cvar = &cv_playercolor[0]}, 20}, - - {IT_STRING|IT_CVAR, NULL, "Difficulty", {.cvar = &cv_dummygpdifficulty}, 40}, - {IT_STRING|IT_CVAR, NULL, "Encore Mode", {.cvar = &cv_dummygpencore}, 50}, - - {IT_STRING|IT_CVAR, NULL, "Cup", {.cvar = &cv_dummygpcup}, 70}, - {IT_STRING|IT_CALL, NULL, "Start", {.routine = M_StartGrandPrix}, 80}, -}; - -// Single Player Time Attack -static menuitem_t SP_TimeAttackMenu[] = -{ - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Name", {.cvar = &cv_playername[0]}, 0}, - {IT_STRING|IT_CVAR, NULL, "Character", {.cvar = &cv_chooseskin}, 13}, - {IT_STRING|IT_CVAR, NULL, "Color", {.cvar = &cv_playercolor[0]}, 26}, - {IT_STRING|IT_CVAR, NULL, "Level", {.cvar = &cv_nextmap}, 78}, - - {IT_DISABLED, NULL, "Guest...", {.submenu = &SP_GuestReplayDef}, 98}, - {IT_DISABLED, NULL, "Replay...", {.submenu = &SP_ReplayDef}, 108}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Ghosts...", {.submenu = &SP_GhostDef}, 118}, - {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", {.routine = M_ChooseTimeAttack}, 130}, -}; - -enum -{ - taname, - taplayer, - tacolor, - talevel, - - taguest, - tareplay, - taghost, - tastart -}; - -static menuitem_t SP_ReplayMenu[] = -{ - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", {.routine = M_ReplayTimeAttack}, 90}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", {.routine = M_ReplayTimeAttack}, 98}, - - {IT_WHITESTRING|IT_CALL, NULL, "Replay Last", {.routine = M_ReplayTimeAttack}, 106}, - {IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", {.routine = M_ReplayTimeAttack}, 114}, - {IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",{.routine = M_HandleStaffReplay},122}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} -}; - -static menuitem_t SP_GuestReplayMenu[] = -{ - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", {.routine = M_SetGuestReplay}, 94}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", {.routine = M_SetGuestReplay},102}, - {IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", {.routine = M_SetGuestReplay},110}, - - {IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", {.routine = M_SetGuestReplay},120}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} -}; - -static menuitem_t SP_GhostMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Best Time", {.cvar = &cv_ghost_besttime}, 88}, - {IT_STRING|IT_CVAR, NULL, "Best Lap", {.cvar = &cv_ghost_bestlap}, 96}, - {IT_STRING|IT_CVAR, NULL, "Last", {.cvar = &cv_ghost_last}, 104}, - {IT_DISABLED, NULL, "Guest", {.cvar = &cv_ghost_guest}, 112}, - {IT_DISABLED, NULL, "Staff Attack", {.cvar = &cv_ghost_staff}, 120}, - - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", {.submenu = &SP_TimeAttackDef}, 130} -}; - -enum -{ - nalevel, - narecords, - - naguest, - nareplay, - naghost, - nastart -}; - -// Statistics -static menuitem_t SP_LevelStatsMenu[] = -{ - {IT_KEYHANDLER | IT_NOTHING, NULL, "", {.routine = M_HandleLevelStats}, '\0'}, // dummy menuitem for the control func -}; - -// ----------------------------------- -// Multiplayer and all of its submenus -// ----------------------------------- -// Prefix: MP_ - -static menuitem_t MP_MainMenu[] = -{ - {IT_HEADER, NULL, "Players", {NULL}, 0}, - {IT_STRING|IT_CVAR, NULL, "Number of local players", {.cvar = &cv_splitplayers}, 10}, - - {IT_STRING|IT_KEYHANDLER,NULL, "Player setup...", {.routine = M_SetupMultiHandler}, 18}, - - {IT_HEADER, NULL, "Host a game", {NULL}, 100-24}, - {IT_STRING|IT_CALL, NULL, "Internet/LAN...", {.routine = M_StartServerMenu}, 110-24}, - {IT_STRING|IT_CALL, NULL, "Offline...", {.routine = M_StartOfflineServerMenu}, 118-24}, - - {IT_HEADER, NULL, "Join a game", {NULL}, 132-24}, - {IT_STRING|IT_CALL, NULL, "Internet server browser...",{.routine = M_ConnectMenuModChecks}, 142-24}, - {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", {.routine = M_HandleConnectIP}, 150-24}, -}; - -static menuitem_t MP_ServerMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Max. Player Count", {.cvar = &cv_maxplayers}, 10}, - {IT_STRING|IT_CVAR, NULL, "Advertise", {.cvar = &cv_advertise}, 20}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", {.cvar = &cv_servername}, 30}, - - {IT_STRING|IT_CVAR, NULL, "Game Type", {.cvar = &cv_newgametype}, 68}, - {IT_STRING|IT_CVAR, NULL, "Level", {.cvar = &cv_nextmap}, 78}, - - {IT_WHITESTRING|IT_CALL, NULL, "Start", {.routine = M_StartServer}, 130}, -}; - -// Separated offline and normal servers. -static menuitem_t MP_OfflineServerMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Game Type", {.cvar = &cv_newgametype}, 68}, - {IT_STRING|IT_CVAR, NULL, "Level", {.cvar = &cv_nextmap}, 78}, - - {IT_WHITESTRING|IT_CALL, NULL, "Start", {.routine = M_StartServer}, 130}, -}; - -static menuitem_t MP_PlayerSetupMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, "Name", {.routine = M_HandleSetupMultiPlayer}, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Character", {.routine = M_HandleSetupMultiPlayer}, 16}, // Tails 01-18-2001 - {IT_KEYHANDLER | IT_STRING, NULL, "Follower", {.routine = M_HandleSetupMultiPlayer}, 26}, - {IT_KEYHANDLER | IT_STRING, NULL, "Color", {.routine = M_HandleSetupMultiPlayer}, 152}, -}; +static tic_t playback_last_menu_interaction_leveltime = 0; static menuitem_t MP_ConnectMenu[] = { @@ -1072,351 +535,6 @@ enum FIRSTSERVERLINE }; -// ------------------------------------ -// Options and most (?) of its submenus -// ------------------------------------ -// Prefix: OP_ -static menuitem_t OP_MainMenu[] = -{ - {IT_SUBMENU|IT_STRING, NULL, "Control Setup...", {.submenu = &OP_ControlsDef}, 10}, - - {IT_SUBMENU|IT_STRING, NULL, "Video Options...", {.submenu = &OP_VideoOptionsDef}, 30}, - {IT_SUBMENU|IT_STRING, NULL, "Sound Options...", {.submenu = &OP_SoundOptionsDef}, 40}, - - {IT_SUBMENU|IT_STRING, NULL, "HUD Options...", {.submenu = &OP_HUDOptionsDef}, 60}, - {IT_SUBMENU|IT_STRING, NULL, "Camera Options...", {.submenu = &OP_CamOptionsDef}, 70}, - {IT_SUBMENU|IT_STRING, NULL, "Gameplay Options...", {.submenu = &OP_GameOptionsDef}, 80}, - {IT_SUBMENU|IT_STRING, NULL, "Server Options...", {.submenu = &OP_ServerOptionsDef}, 90}, - - {IT_SUBMENU|IT_STRING, NULL, "Data Options...", {.submenu = &OP_DataOptionsDef}, 110}, - - {IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", {.routine = M_Manual}, 130}, - {IT_CALL|IT_STRING, NULL, "Play Kart Credits", {.routine = M_Credits}, 140}, - {IT_CALL|IT_STRING, NULL, "Play BlanKart Credits", {.routine = M_BlanCredits}, 150}, -}; - -static menuitem_t OP_CamOptionsMenu[] = -{ - {IT_HEADER, NULL, "Camera Options", {NULL}, 0}, - - {IT_STRING | IT_CVAR, NULL, "Camera Tiling", {.cvar = &cv_tilting}, 20}, - {IT_STRING | IT_CVAR, NULL, "Lagless Camera", {.cvar = &cv_laglesscam}, 30}, - - {IT_STRING | IT_SUBMENU, NULL, "Player 1 Camera options...", {.submenu = &OP_Player1CamOptionsDef}, 50}, - {IT_STRING | IT_SUBMENU, NULL, "Player 2 Camera options...", {.submenu = &OP_Player2CamOptionsDef}, 60}, - {IT_STRING | IT_SUBMENU, NULL, "Player 3 Camera options...", {.submenu = &OP_Player3CamOptionsDef}, 70}, - {IT_STRING | IT_SUBMENU, NULL, "Player 4 Camera options...", {.submenu = &OP_Player4CamOptionsDef}, 80}, -}; - -static menuitem_t OP_Player1CamOptionsMenu[] = -{ - {IT_HEADER, NULL, "Player 1 Camera Options", {NULL}, 0}, - - {IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[0]}, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[0]}, 40}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[0]}, 50}, - {IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[0]}, 60}, - //{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[0]}, 85}, -}; - -static menuitem_t OP_Player2CamOptionsMenu[] = -{ - {IT_HEADER, NULL, "Player 2 Camera Options", {NULL}, 0}, - - {IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[1]}, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[1]}, 40}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[1]}, 50}, - {IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[1]}, 60}, - //{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[1]}, 85}, -}; - -static menuitem_t OP_Player3CamOptionsMenu[] = -{ - {IT_HEADER, NULL, "Player 3 Camera Options", {NULL}, 0}, - - {IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[2]}, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[2]}, 40}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[2]}, 50}, - {IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[2]}, 60}, - //{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[2]}, 85}, -}; - -static menuitem_t OP_Player4CamOptionsMenu[] = -{ - {IT_HEADER, NULL, "Player 4 Camera Options", {NULL}, 0}, - - {IT_STRING | IT_CVAR, NULL, "Flipcam", {.cvar = &cv_flipcam[3]}, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Distance", {.cvar = &cv_cam_dist[3]}, 40}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL,"Camera Height", {.cvar = &cv_cam_height[3]}, 50}, - {IT_STRING | IT_CVAR, NULL, "Camera Speed", {.cvar = &cv_cam_speed[3]}, 60}, - //{IT_STRING | IT_CVAR, NULL, "Camera Rotation Speed", {.cvar = &cv_cam_rotspeed[0]}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Third Person Camera", {.cvar = &cv_chasecam[3]}, 85}, -}; - -static menuitem_t OP_ControlsMenu[] = -{ - {IT_CALL | IT_STRING, NULL, "Player 1 Controls...", {.routine = M_Setup1PControlsMenu}, 10}, - {IT_CALL | IT_STRING, NULL, "Player 2 Controls...", {.routine = M_Setup2PControlsMenu}, 20}, - - {IT_CALL | IT_STRING, NULL, "Player 3 Controls...", {.routine = M_Setup3PControlsMenu}, 30}, - {IT_CALL | IT_STRING, NULL, "Player 4 Controls...", {.routine = M_Setup4PControlsMenu}, 40}, - - {IT_STRING | IT_CVAR, NULL, "Controls per key", {.cvar = &cv_controlperkey}, 60}, - {IT_STRING | IT_CVAR, NULL, "Digital turn easing", {.cvar = &cv_turnsmooth}, 70}, -}; - -// NOTE: max 16 characters for control name! -static menuitem_t OP_AllControlsMenu[] = -{ - {IT_CALL|IT_STRING, NULL, "Select Gamepad...", {.routine = M_Setup1PJoystickMenu}, 0}, - {IT_CVAR|IT_STRING, NULL, "Deadzone" , {.cvar = &cv_deadzone[0]}, 8}, - {IT_CALL|IT_STRING, NULL, "Reset to defaults", {.routine = M_ResetControls}, 16}, - {IT_HEADER, NULL, "Gameplay Controls", {NULL}, 0}, - {IT_SPACE, NULL, NULL, {NULL}, 0}, - {IT_CONTROL, NULL, "Accelerate", {.routine = M_ChangeControl}, gc_accelerate }, - {IT_CONTROL, NULL, "Turn Left", {.routine = M_ChangeControl}, gc_turnleft }, - {IT_CONTROL, NULL, "Turn Right", {.routine = M_ChangeControl}, gc_turnright }, - {IT_CONTROL, NULL, "Drift", {.routine = M_ChangeControl}, gc_drift }, - {IT_CONTROL, NULL, "Brake", {.routine = M_ChangeControl}, gc_brake }, - {IT_CONTROL, NULL, "Use/Throw Item", {.routine = M_ChangeControl}, gc_fire }, - {IT_CONTROL, NULL, "Aim Forward", {.routine = M_ChangeControl}, gc_aimforward }, - {IT_CONTROL, NULL, "Aim Backward", {.routine = M_ChangeControl}, gc_aimbackward}, - {IT_CONTROL, NULL, "Look Backward", {.routine = M_ChangeControl}, gc_lookback }, - {IT_HEADER, NULL, "Miscelleanous Controls", {NULL}, 0}, - {IT_SPACE, NULL, NULL, {NULL}, 0}, - {IT_CONTROL, NULL, "Chat", {.routine = M_ChangeControl}, gc_talkkey }, - //{IT_CONTROL, NULL, "Team Chat", M_ChangeControl, gc_teamkey }, - {IT_CONTROL, NULL, "Show Rankings", {.routine = M_ChangeControl}, gc_scores }, - {IT_CONTROL, NULL, "Change Viewpoint", {.routine = M_ChangeControl}, gc_viewpoint }, - {IT_CONTROL, NULL, "Reset Camera", {.routine = M_ChangeControl}, gc_camreset }, - {IT_CONTROL, NULL, "Toggle Chasecam", {.routine = M_ChangeControl}, gc_camtoggle }, - {IT_CONTROL, NULL, "Pause", {.routine = M_ChangeControl}, gc_pause }, - {IT_CONTROL, NULL, "Screenshot", {.routine = M_ChangeControl}, gc_screenshot }, - {IT_CONTROL, NULL, "Record GIF", {.routine = M_ChangeControl}, gc_recordgif }, - {IT_CONTROL, NULL, "Open/Close Menu", {.routine = M_ChangeControl}, gc_systemmenu }, - {IT_CONTROL, NULL, "Open Console", {.routine = M_ChangeControl}, gc_console }, - {IT_HEADER, NULL, "Spectator Controls", {NULL}, 0}, - {IT_SPACE, NULL, NULL, {NULL}, 0}, - {IT_CONTROL, NULL, "Become Spectator", {.routine = M_ChangeControl}, gc_spectate }, - {IT_CONTROL, NULL, "Look Up", {.routine = M_ChangeControl}, gc_lookup }, - {IT_CONTROL, NULL, "Look Down", {.routine = M_ChangeControl}, gc_lookdown }, - {IT_CONTROL, NULL, "Center View", {.routine = M_ChangeControl}, gc_centerview }, - {IT_HEADER, NULL, "Custom Lua Actions", {NULL}, 0}, - {IT_SPACE, NULL, NULL, {NULL}, 0}, - {IT_CONTROL, NULL, "Custom Action 1", {.routine = M_ChangeControl}, gc_custom1 }, - {IT_CONTROL, NULL, "Custom Action 2", {.routine = M_ChangeControl}, gc_custom2 }, - {IT_CONTROL, NULL, "Custom Action 3", {.routine = M_ChangeControl}, gc_custom3 }, -}; - -static menuitem_t OP_JoystickSetMenu[] = -{ - {IT_CALL | IT_NOTHING, ":chonkbuncle:", NULL, {.routine = M_AssignJoystick}, LINEHEIGHT+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*2)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*3)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*4)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*5)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*6)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*7)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*8)+5}, - {IT_CALL | IT_NOTHING, "", NULL, {.routine = M_AssignJoystick}, (LINEHEIGHT*9)+5}, -}; - -/* -static menuitem_t OP_MouseOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10}, - - - {IT_STRING | IT_CVAR, NULL, "First-Person MouseLook", &cv_alwaysfreelook, 30}, - {IT_STRING | IT_CVAR, NULL, "Third-Person MouseLook", &cv_chasefreelook, 40}, - {IT_STRING | IT_CVAR, NULL, "Mouse Move", &cv_mousemove, 50}, - {IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 60}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse X Speed", &cv_mousesens, 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Mouse Y Speed", &cv_mouseysens, 80}, -}; -*/ - -static menuitem_t OP_VideoOptionsMenu[] = -{ - {IT_STRING | IT_CALL, NULL, "Set Resolution...", {.routine = M_VideoModeMenu}, 10}, -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", {.cvar = &cv_fullscreen}, 20}, -#endif -#ifdef HWRENDER - {IT_STRING | IT_CVAR, NULL, "Renderer", {.cvar = &cv_renderer}, 30}, -#else - {IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", {.cvar = &cv_renderer}, 30}, -#endif - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Gamma", {.cvar = &cv_globalgamma}, 50}, - - {IT_STRING | IT_CVAR, NULL, "Show FPS", {.cvar = &cv_ticrate}, 60}, - {IT_STRING | IT_CVAR, NULL, "Vertical Sync", {.cvar = &cv_vidwait}, 70}, - {IT_STRING | IT_CVAR, NULL, "FPS Cap", {.cvar = &cv_fpscap}, 80}, - - {IT_STRING | IT_CVAR, NULL, "VHS Effect", {.cvar = &cv_vhseffect}, 100}, - - {IT_STRING | IT_CVAR, NULL, "Draw Distance", {.cvar = &cv_drawdist}, 110}, - {IT_STRING | IT_CVAR, NULL, "Weather Draw Distance", {.cvar = &cv_drawdist_precip}, 120}, - {IT_STRING | IT_CVAR, NULL, "Skyboxes", {.cvar = &cv_skybox}, 130}, - {IT_STRING | IT_CVAR, NULL, "Parallel Software", {.cvar = &cv_parallelsoftware}, 140}, - - -#ifdef HWRENDER - {IT_CALL | IT_STRING, NULL, "OpenGL Options...", {.routine = M_OpenGLOptionsMenu}, 160}, -#endif -}; - -enum -{ - op_video_res = 0, -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - op_video_fullscreen, -#endif - op_video_renderer, - op_video_gamma, - op_vide_showfps, - op_video_vsync, - op_video_fps, - op_video_vhs, - op_video_dd, - op_video_wdd, - op_video_skybox, - op_video_para, -#ifdef HWRENDER - op_video_ogl -#endif -}; - -static menuitem_t OP_VideoModeMenu[] = -{ - {IT_KEYHANDLER | IT_NOTHING, NULL, "", {.routine = M_HandleVideoMode}, '\0'}, // dummy menuitem for the control func -}; - -#ifdef HWRENDER -static menuitem_t OP_OpenGLOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "3D Models", {.cvar = &cv_glmodels}, 10}, - {IT_STRING | IT_CVAR, NULL, "Model Interpolation", {.cvar = &cv_glmodelinterpolation}, 20}, - {IT_STRING | IT_CVAR, NULL, "Model Lighting", {.cvar = &cv_glmodellighting}, 30}, - {IT_STRING|IT_CVAR, NULL, "Shaders", {.cvar = &cv_glshaders}, 40}, - - {IT_STRING|IT_CVAR, NULL, "Texture Quality", {.cvar = &cv_scr_depth}, 60}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", {.cvar = &cv_glfiltermode}, 70}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", {.cvar = &cv_glanisotropicmode}, 80}, - - {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", {.cvar = &cv_glspritebillboarding}, 100}, - {IT_STRING|IT_CVAR, NULL, "Software Perspective", {.cvar = &cv_glshearing}, 110}, -}; -#endif - -static menuitem_t OP_SoundOptionsMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "SFX", {.cvar = &cv_gamesounds}, 10}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, - NULL, "SFX Volume", {.cvar = &cv_soundvolume}, 18}, - - {IT_STRING|IT_CVAR, NULL, "Music", {.cvar = &cv_gamedigimusic}, 30}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, - NULL, "Music Volume", {.cvar = &cv_digmusicvolume}, 38}, - - {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", {.cvar = &stereoreverse}, 50}, - {IT_STRING|IT_CVAR, NULL, "Surround Sound", {.cvar = &surround}, 60}, - - {IT_STRING|IT_CVAR, NULL, "Chat Notifications", {.cvar = &cv_chatnotifications}, 75}, - {IT_STRING|IT_CVAR, NULL, "Character voices", {.cvar = &cv_kartvoices}, 85}, - {IT_STRING|IT_CVAR, NULL, "Powerup Warning", {.cvar = &cv_kartinvinsfx}, 95}, - - {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", {.routine = M_HandleSoundTest}, 110}, - {IT_STRING|IT_CALL, NULL, "Music Test", {.routine = M_MusicTest}, 120}, - - {IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", {.cvar = &cv_playmusicifunfocused}, 135}, - {IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", {.cvar = &cv_playsoundifunfocused}, 145}, -}; - -static menuitem_t OP_DataOptionsMenu[] = -{ - - {IT_STRING | IT_CALL, NULL, "Screenshot Options...", {.routine = M_ScreenshotOptions}, 10}, - {IT_STRING | IT_CALL, NULL, "Addon Options...", {.routine = M_AddonsOptions}, 20}, - {IT_STRING | IT_SUBMENU, NULL, "Replay Options...", {.submenu = &MISC_ReplayOptionsDef}, 30}, -#ifdef HAVE_DISCORDRPC - {IT_STRING | IT_SUBMENU, NULL, "Discord Options...", {.submenu = &OP_DiscordOptionsDef}, 40}, - - {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", {.submenu = &OP_EraseDataDef}, 60}, -#else - {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", {.submenu = &OP_EraseDataDef}, 50}, -#endif -}; - -static menuitem_t OP_ScreenshotOptionsMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Storage Location", {.cvar = &cv_screenshot_option}, 10}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", {.cvar = &cv_screenshot_folder}, 20}, - - {IT_HEADER, NULL, "Screenshots (F8)", {NULL}, 50}, - {IT_STRING|IT_CVAR, NULL, "Memory Level", {.cvar = &cv_zlib_memory}, 60}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", {.cvar = &cv_zlib_level}, 70}, - {IT_STRING|IT_CVAR, NULL, "Strategy", {.cvar = &cv_zlib_strategy}, 80}, - {IT_STRING|IT_CVAR, NULL, "Window Size", {.cvar = &cv_zlib_window_bits}, 90}, - - {IT_HEADER, NULL, "Movie Mode (F9)", {NULL}, 105}, - {IT_STRING|IT_CVAR, NULL, "Capture Mode", {.cvar = &cv_moviemode}, 115}, - - {IT_STRING|IT_CVAR, NULL, "Region Optimizing", {.cvar = &cv_gif_optimize}, 125}, - {IT_STRING|IT_CVAR, NULL, "Downscaling", {.cvar = &cv_gif_downscale}, 135}, - - {IT_STRING|IT_CVAR, NULL, "Memory Level", {.cvar = &cv_zlib_memorya}, 125}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", {.cvar = &cv_zlib_levela}, 135}, - {IT_STRING|IT_CVAR, NULL, "Strategy", {.cvar = &cv_zlib_strategya}, 145}, - {IT_STRING|IT_CVAR, NULL, "Window Size", {.cvar = &cv_zlib_window_bitsa}, 155}, -}; - -enum -{ - op_screenshot_folder = 1, - op_screenshot_capture = 8, - op_screenshot_gif_start = 9, - op_screenshot_gif_end = 10, - op_screenshot_apng_start = 11, - op_screenshot_apng_end = 14, -}; - -static menuitem_t OP_EraseDataMenu[] = -{ - {IT_STRING | IT_CALL, NULL, "Erase Record Data", {.routine = M_EraseData}, 10}, - {IT_STRING | IT_CALL, NULL, "Erase Unlockable Data", {.routine = M_EraseData}, 20}, - - {IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", {.routine = M_EraseData}, 40}, -}; - -static menuitem_t OP_AddonsOptionsMenu[] = -{ - {IT_HEADER, NULL, "Menu", {NULL}, 0}, - {IT_STRING|IT_CVAR, NULL, "Location", {.cvar = &cv_addons_option}, 10}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", {.cvar = &cv_addons_folder}, 20}, - {IT_STRING|IT_CVAR, NULL, "Identify addons via", {.cvar = &cv_addons_md5}, 48}, - {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", {.cvar = &cv_addons_showall}, 58}, - - {IT_HEADER, NULL, "Search", {NULL}, 76}, - {IT_STRING|IT_CVAR, NULL, "Matching", {.cvar = &cv_addons_search_type}, 86}, - {IT_STRING|IT_CVAR, NULL, "Case-sensitive", {.cvar = &cv_addons_search_case}, 96}, -}; - -enum -{ - op_addons_folder = 2, -}; - #ifdef HAVE_DISCORDRPC static menuitem_t OP_DiscordOptionsMenu[] = { @@ -1430,227 +548,10 @@ static menuitem_t OP_DiscordOptionsMenu[] = }; #endif -static menuitem_t OP_HUDOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", {.cvar = &cv_showhud}, 20}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "HUD Visibility", {.cvar = &cv_translucenthud}, 30}, - - {IT_STRING | IT_SUBMENU, NULL, "Online HUD options...", {.submenu = &OP_ChatOptionsDef}, 45}, - {IT_STRING | IT_CVAR, NULL, "Background Glass", {.cvar = &cons_backcolor}, 55}, - - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Minimap Visibility", {.cvar = &cv_kartminimap}, 70}, - {IT_STRING | IT_CVAR, NULL, "Speedometer Display", {.cvar = &cv_kartspeedometer}, 80}, - {IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", {.cvar = &cv_kartcheck}, 90}, - - {IT_STRING | IT_CVAR, NULL, "Menu Highlights", {.cvar = &cons_menuhighlight}, 105}, - // highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 105 (see M_DrawHUDOptions) - - {IT_STRING | IT_CVAR, NULL, "Console Text Size", {.cvar = &cv_constextsize}, 130}, - - {IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", {.cvar = &cv_showfocuslost}, 145}, -}; - -// Ok it's still called chatoptions but we'll put ping display in here to be clean -static menuitem_t OP_ChatOptionsMenu[] = -{ - // will ANYONE who doesn't know how to use the console want to touch this one? - {IT_STRING | IT_CVAR, NULL, "Chat Mode", {.cvar = &cv_consolechat}, 10}, // nonetheless... - - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Chat Box Width", {.cvar = &cv_chatwidth}, 25}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Chat Box Height", {.cvar = &cv_chatheight}, 35}, - - {IT_STRING | IT_CVAR, NULL, "Chat Background Tint", {.cvar = &cv_chatbacktint}, 50}, - {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", {.cvar = &cv_chattime}, 60}, - {IT_STRING | IT_CVAR, NULL, "Spam Protection", {.cvar = &cv_chatspamprotection}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Local ping display", {.cvar = &cv_showping}, 90}, // shows ping next to framerate if we want to. -}; - -static menuitem_t OP_GameOptionsMenu[] = -{ - {IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", {.submenu = &OP_MonitorToggleDef}, 10}, - - {IT_STRING | IT_SUBMENU, NULL, "BlanKart Gameplay...", {.submenu = &OP_BlanKartGameOptionsDef}, 30}, - - {IT_STRING | IT_CVAR, NULL, "Race Game Speed", {.cvar = &cv_kartspeed}, 40}, - {IT_STRING | IT_CVAR, NULL, "Battle Game Speed", {.cvar = &cv_kartbattlespeed}, 50}, - {IT_STRING | IT_CVAR, NULL, "Frantic Items", {.cvar = &cv_kartfrantic}, 60}, - {IT_SECRET, NULL, "Encore Mode", {.cvar = &cv_kartencore}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Number of Laps", {.cvar = &cv_numlaps}, 90}, - {IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", {.cvar = &cv_countdowntime}, 100}, - - {IT_STRING | IT_CVAR, NULL, "Time Limit", {.cvar = &cv_timelimit}, 120}, - {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", {.cvar = &cv_kartbumpers}, 130}, - {IT_STRING | IT_CVAR, NULL, "Karma Comeback", {.cvar = &cv_kartcomeback}, 140}, - - {IT_STRING | IT_CVAR, NULL, "Track Power Levels", {.cvar = &cv_kartusepwrlv}, 160}, -}; - -static menuitem_t OP_BlanKartGameOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Rings", {.cvar = &cv_kartrings}, 10}, - {IT_STRING | IT_CVAR, NULL, "Purple Drift", {.cvar = &cv_kartpurpledrift}, 20}, - -}; - -static menuitem_t OP_ServerOptionsMenu[] = -{ - {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server Name", {.cvar = &cv_servername}, 10}, - - {IT_STRING | IT_CVAR, NULL, "Intermission Timer", {.cvar = &cv_inttime}, 40}, - {IT_STRING | IT_CVAR, NULL, "Map Progression", {.cvar = &cv_advancemap}, 50}, - {IT_STRING | IT_CVAR, NULL, "Voting Timer", {.cvar = &cv_votetime}, 60}, - {IT_STRING | IT_CVAR, NULL, "Voting Rule Changes", {.cvar = &cv_kartvoterulechanges}, 70}, - - {IT_STRING | IT_CVAR, NULL, "Max. Player Count", {.cvar = &cv_maxplayers}, 90}, - {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", {.cvar = &cv_allownewplayer}, 100}, - {IT_STRING | IT_CVAR, NULL, "Allow Addon Downloading", {.cvar = &cv_downloading}, 110}, - {IT_STRING | IT_CVAR, NULL, "Pause Permission", {.cvar = &cv_pause}, 120}, - {IT_STRING | IT_CVAR, NULL, "Mute All Chat", {.cvar = &cv_mute}, 130}, - - {IT_SUBMENU|IT_STRING, NULL, "Advanced Options...", {.submenu = &OP_AdvServerOptionsDef}, 150}, -}; - -static menuitem_t OP_AdvServerOptionsMenu[] = -{ - {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server Browser Address", {.cvar = &cv_masterserver}, 10}, - - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", {.cvar = &cv_resynchattempts}, 40}, - {IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", {.cvar = &cv_maxping}, 50}, - {IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", {.cvar = &cv_pingtimeout}, 60}, - {IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", {.cvar = &cv_nettimeout}, 70}, - {IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", {.cvar = &cv_jointimeout}, 80}, - - {IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", {.cvar = &cv_maxsend}, 100}, - {IT_STRING | IT_CVAR, NULL, "File transfer packet rate", {.cvar = &cv_downloadspeed}, 110}, - - {IT_STRING | IT_CVAR, NULL, "Log join addresses", {.cvar = &cv_showjoinaddress}, 130}, - {IT_STRING | IT_CVAR, NULL, "Log resyncs", {.cvar = &cv_blamecfail}, 140}, - {IT_STRING | IT_CVAR, NULL, "Log file transfers", {.cvar = &cv_noticedownload}, 150}, -}; - -//#define ITEMTOGGLEBOTTOMRIGHT - -static menuitem_t OP_MonitorToggleMenu[] = -{ - // Mostly handled by the drawing function. - // Instead of using this for dumb monitors, lets use the new item bools we have :V - {IT_KEYHANDLER | IT_NOTHING, NULL, "Sneakers", {.routine = M_HandleMonitorToggles}, KITEM_SNEAKER}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Sneakers x3", {.routine = M_HandleMonitorToggles}, KRITEM_TRIPLESNEAKER}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Rocket Sneakers", {.routine = M_HandleMonitorToggles}, KITEM_ROCKETSNEAKER}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Toggle All", {.routine = M_HandleMonitorToggles}, 0}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Bananas", {.routine = M_HandleMonitorToggles}, KITEM_BANANA}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Bananas x3", {.routine = M_HandleMonitorToggles}, KRITEM_TRIPLEBANANA}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Bananas x10", {.routine = M_HandleMonitorToggles}, KRITEM_TENFOLDBANANA}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Eggman Monitors", {.routine = M_HandleMonitorToggles}, KITEM_EGGMAN}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Orbinauts", {.routine = M_HandleMonitorToggles}, KITEM_ORBINAUT}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Orbinauts x3", {.routine = M_HandleMonitorToggles}, KRITEM_TRIPLEORBINAUT}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Orbinauts x4", {.routine = M_HandleMonitorToggles}, KRITEM_QUADORBINAUT}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Mines", {.routine = M_HandleMonitorToggles}, KITEM_MINE}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Land Mines", {.routine = M_HandleMonitorToggles}, KITEM_LANDMINE}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Jawz", {.routine = M_HandleMonitorToggles}, KITEM_JAWZ}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Jawz x2", {.routine = M_HandleMonitorToggles}, KRITEM_DUALJAWZ}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Ballhogs", {.routine = M_HandleMonitorToggles}, KITEM_BALLHOG}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Self-Propelled Bombs", {.routine = M_HandleMonitorToggles}, KITEM_SPB}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Invinciblity", {.routine = M_HandleMonitorToggles}, KITEM_INVINCIBILITY}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Grow", {.routine = M_HandleMonitorToggles}, KITEM_GROW}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Shrink", {.routine = M_HandleMonitorToggles}, KITEM_SHRINK}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Thunder Shields", {.routine = M_HandleMonitorToggles}, KITEM_THUNDERSHIELD}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Bubble Shields", {.routine = M_HandleMonitorToggles}, KITEM_BUBBLESHIELD}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Flame Shields", {.routine = M_HandleMonitorToggles}, KITEM_FLAMESHIELD}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Hyudoros", {.routine = M_HandleMonitorToggles}, KITEM_HYUDORO}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Pogo Springs", {.routine = M_HandleMonitorToggles}, KITEM_POGOSPRING}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Super Rings", {.routine = M_HandleMonitorToggles}, KITEM_SUPERRING}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Kitchen Sinks", {.routine = M_HandleMonitorToggles}, KITEM_KITCHENSINK}, - {IT_KEYHANDLER | IT_NOTHING, NULL, "Drop Target", {.routine = M_HandleMonitorToggles}, KITEM_DROPTARGET}, -#ifdef ITEMTOGGLEBOTTOMRIGHT - {IT_KEYHANDLER | IT_NOTHING, NULL, "---", {.routine = M_HandleMonitorToggles}, 255}, -#endif -}; - // ========================================================================== // ALL MENU DEFINITIONS GO HERE // ========================================================================== -// Main Menu and related -menu_t MainDef = CENTERMENUSTYLE(MN_NONE, NULL, MainMenu, NULL, 72); - -menu_t MISC_AddonsDef = -{ - MN_NONE, - NULL, - sizeof (MISC_AddonsMenu)/sizeof (menuitem_t), - &OP_DataOptionsDef, - MISC_AddonsMenu, - M_DrawAddons, - 50, 28, - 0, - NULL -}; - -menu_t MISC_ReplayHutDef = -{ - MN_NONE, - NULL, - sizeof (MISC_ReplayHutMenu)/sizeof (menuitem_t), - NULL, - MISC_ReplayHutMenu, - M_DrawReplayHut, - 30, 80, - 0, - M_QuitReplayHut -}; - -menu_t MISC_ReplayOptionsDef = -{ - MN_NONE, - "M_REPOPT", - sizeof (MISC_ReplayOptionsMenu)/sizeof (menuitem_t), - &OP_DataOptionsDef, - MISC_ReplayOptionsMenu, - M_DrawGenericMenu, - 27, 40, - 0, - NULL -}; - -menu_t MISC_ReplayStartDef = -{ - MN_NONE, - NULL, - sizeof (MISC_ReplayStartMenu)/sizeof (menuitem_t), - &MISC_ReplayHutDef, - MISC_ReplayStartMenu, - M_DrawReplayStartMenu, - 30, 90, - 0, - NULL -}; - -menu_t PlaybackMenuDef = { - MN_NONE, - NULL, - sizeof (PlaybackMenu)/sizeof (menuitem_t), - NULL, - PlaybackMenu, - M_DrawPlaybackMenu, - //BASEVIDWIDTH/2 - 94, 2, - BASEVIDWIDTH/2 - 88, 2, - 0, - NULL -}; - -menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72); -menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72); -menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72); - #ifdef HAVE_DISCORDRPC menu_t MISC_DiscordRequestsDef = { MN_NONE, @@ -1665,13 +566,6 @@ menu_t MISC_DiscordRequestsDef = { }; #endif -// Misc Main Menu -menu_t MISC_ScrambleTeamDef = DEFAULTMENUSTYLE(MN_NONE, NULL, MISC_ScrambleTeamMenu, &MPauseDef, 27, 40); -menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(MN_NONE, NULL, MISC_ChangeTeamMenu, &MPauseDef, 27, 40); -menu_t MISC_ChangeSpectateDef = DEFAULTMENUSTYLE(MN_NONE, NULL, MISC_ChangeSpectateMenu, &MPauseDef, 27, 40); -menu_t MISC_ChangeLevelDef = MAPICONMENUSTYLE(NULL, MISC_ChangeLevelMenu, &MPauseDef); -menu_t MISC_HelpDef = IMAGEDEF(MISC_HelpMenu); - // // M_GetGametypeColor // @@ -1769,145 +663,7 @@ fixed_t M_GetMapThumbnail(INT16 mapnum, patch_t **out) return patch->width >= 320 ? FRACUNIT : FRACUNIT*2; } -// Sky Room -menu_t SR_PandoraDef = -{ - MN_NONE, - "M_PANDRA", - sizeof (SR_PandorasBox)/sizeof (menuitem_t), - &SPauseDef, - SR_PandorasBox, - M_DrawGenericMenu, - 60, 40, - 0, - M_ExitPandorasBox -}; -menu_t SR_MainDef = CENTERMENUSTYLE(MN_NONE, NULL, SR_MainMenu, &MainDef, 72); - -menu_t SR_UnlockChecklistDef = -{ - MN_NONE, - NULL, - 1, - &SR_MainDef, - SR_UnlockChecklistMenu, - M_DrawChecklist, - 280, 185, - 0, - NULL -}; - -menu_t SR_MusicTestDef = -{ - MN_NONE, - NULL, - sizeof (SR_MusicTestMenu)/sizeof (menuitem_t), - &OP_SoundOptionsDef, - SR_MusicTestMenu, - M_DrawMusicTest, - 60, 150, - 0, - NULL -}; - -menu_t SR_EmblemHintDef = -{ - MN_NONE, - NULL, - sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), - &SPauseDef, - SR_EmblemHintMenu, - M_DrawEmblemHints, - 60, 150, - 0, - NULL -}; - -// Single Player -menu_t SP_MainDef = CENTERMENUSTYLE(MN_NONE, NULL, SP_MainMenu, &MainDef, 72); - -menu_t SP_LevelStatsDef = -{ - MN_NONE, - "M_STATS", - 1, - &SR_MainDef, - SP_LevelStatsMenu, - M_DrawLevelStats, - 280, 185, - 0, - NULL -}; - -static menu_t SP_GrandPrixTempDef = DEFAULTMENUSTYLE(MN_NONE, NULL, SP_GrandPrixPlaceholderMenu, &MainDef, 60, 30); - -static menu_t SP_TimeAttackDef = -{ - MN_NONE, - "M_ATTACK", - sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), - &MainDef, // Doesn't matter. - SP_TimeAttackMenu, - M_DrawTimeAttackMenu, - 34, 40, - 0, - M_QuitTimeAttackMenu -}; -static menu_t SP_ReplayDef = -{ - MN_NONE, - "M_ATTACK", - sizeof(SP_ReplayMenu)/sizeof(menuitem_t), - &SP_TimeAttackDef, - SP_ReplayMenu, - M_DrawTimeAttackMenu, - 34, 40, - 0, - NULL -}; -static menu_t SP_GuestReplayDef = -{ - MN_NONE, - "M_ATTACK", - sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), - &SP_TimeAttackDef, - SP_GuestReplayMenu, - M_DrawTimeAttackMenu, - 34, 40, - 0, - NULL -}; -static menu_t SP_GhostDef = -{ - MN_NONE, - "M_ATTACK", - sizeof(SP_GhostMenu)/sizeof(menuitem_t), - &SP_TimeAttackDef, - SP_GhostMenu, - M_DrawTimeAttackMenu, - 34, 40, - 0, - NULL -}; - // Multiplayer -menu_t MP_MainDef = -{ - MN_NONE, - "M_MULTI", - sizeof (MP_MainMenu)/sizeof (menuitem_t), - &MainDef, - MP_MainMenu, - M_DrawMPMainMenu, - 42, 30, - 0, - M_CancelConnect -}; - -menu_t MP_OfflineServerDef = MAPICONMENUSTYLE("M_MULTI", MP_OfflineServerMenu, &MP_MainDef); - -menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef); - menu_t MP_ConnectDef = { MN_NONE, @@ -1921,137 +677,7 @@ menu_t MP_ConnectDef = M_CancelConnect }; -menu_t MP_PlayerSetupDef = -{ - MN_NONE, - NULL, //"M_SPLAYR" - sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), - &MP_MainDef, - MP_PlayerSetupMenu, - M_DrawSetupMultiPlayerMenu, - 36, 14, - 0, - M_QuitMultiPlayerMenu -}; - // Options -menu_t OP_MainDef = -{ - MN_NONE, - "M_OPTTTL", - sizeof (OP_MainMenu)/sizeof (menuitem_t), - &MainDef, - OP_MainMenu, - M_DrawGenericMenu, - 60, 30, - 0, - NULL -}; - -menu_t OP_ControlsDef = DEFAULTMENUSTYLE(MN_NONE, "M_CONTRO", OP_ControlsMenu, &OP_MainDef, 60, 30); -menu_t OP_AllControlsDef = -{ - MN_NONE, - "M_CONTRO", - sizeof (OP_AllControlsMenu)/sizeof (menuitem_t), - &OP_ControlsDef, - OP_AllControlsMenu, - M_DrawControl, - 20, 40, - 0, - NULL -}; -menu_t OP_JoystickSetDef = -{ - MN_NONE, - "M_CONTRO", - sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), - &OP_AllControlsDef, - OP_JoystickSetMenu, - M_DrawJoystick, - 50, 40, - 0, - NULL -}; - -menu_t OP_VideoOptionsDef = -{ - MN_NONE, - "M_VIDEO", - sizeof(OP_VideoOptionsMenu)/sizeof(menuitem_t), - &OP_MainDef, - OP_VideoOptionsMenu, - M_DrawVideoMenu, - 30, 30, - 0, - NULL -}; - -menu_t OP_VideoModeDef = -{ - MN_NONE, - "M_VIDEO", - 1, - &OP_VideoOptionsDef, - OP_VideoModeMenu, - M_DrawVideoMode, - 48, 26, - 0, - NULL -}; - -menu_t OP_SoundOptionsDef = -{ - MN_NONE, - "M_SOUND", - sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), - &OP_MainDef, - OP_SoundOptionsMenu, - M_DrawSkyRoom, - 30, 30, - 0, - NULL -}; - -menu_t OP_HUDOptionsDef = -{ - MN_NONE, - "M_HUD", - sizeof (OP_HUDOptionsMenu)/sizeof (menuitem_t), - &OP_MainDef, - OP_HUDOptionsMenu, - M_DrawHUDOptions, - 30, 30, - 0, - NULL -}; - -menu_t OP_CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_CamOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_Player1CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player1CamOptionsMenu, &OP_CamOptionsDef, 30, 30); -menu_t OP_Player2CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player2CamOptionsMenu, &OP_CamOptionsDef, 30, 30); -menu_t OP_Player3CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player3CamOptionsMenu, &OP_CamOptionsDef, 30, 30); -menu_t OP_Player4CamOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_Player4CamOptionsMenu, &OP_CamOptionsDef, 30, 30); - -menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 30); - -menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_BlanKartGameOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_GAME", OP_BlanKartGameOptionsMenu, &OP_GameOptionsDef, 30, 30); -menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 24, 30); -menu_t OP_AdvServerOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SERVER", OP_AdvServerOptionsMenu, &OP_ServerOptionsDef, 24, 30); - -menu_t OP_MonitorToggleDef = -{ - MN_NONE, - "M_GAME", - sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), - &OP_GameOptionsDef, - OP_MonitorToggleMenu, - M_DrawMonitorToggles, - 30, 30, - 0, - NULL -}; - #ifdef HWRENDER void M_OpenGLOptionsMenu(INT32 choice) { @@ -2062,16 +688,11 @@ void M_OpenGLOptionsMenu(INT32 choice) else M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING); } - -menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #endif -menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); -menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_SCSHOT", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30); -menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE(MN_NONE, "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); + #ifdef HAVE_DISCORDRPC menu_t OP_DiscordOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_DiscordOptionsMenu, &OP_DataOptionsDef, 30, 30); #endif -menu_t OP_EraseDataDef = DEFAULTMENUSTYLE(MN_NONE, "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 30, 30); // ========================================================================== // CVAR ONCHANGE EVENTS GO HERE diff --git a/src/m_menu.h b/src/m_menu.h index 14a2b25d1..3fb2b9769 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -505,7 +505,6 @@ extern I_mutex m_menu_mutex; extern menu_t *currentMenu; extern menu_t MainDef; -extern menu_t SP_LoadDef; // Call upon joystick hotplug void M_SetupJoystickMenu(INT32 choice); @@ -658,71 +657,6 @@ void M_FreePlayerSetupColors(void); NULL\ } -#define DEFAULTSCROLLMENUSTYLE(id, header, source, prev, x, y)\ -{\ - id,\ - header,\ - sizeof(source)/sizeof(menuitem_t),\ - prev,\ - source,\ - M_DrawGenericScrollMenu,\ - x, y,\ - 0,\ - NULL\ -} - -#define PAUSEMENUSTYLE(source, x, y)\ -{\ - MN_SPECIAL,\ - NULL,\ - sizeof(source)/sizeof(menuitem_t),\ - NULL,\ - source,\ - M_DrawPauseMenu,\ - x, y,\ - 0,\ - NULL\ -} - -#define CENTERMENUSTYLE(id, header, source, prev, y)\ -{\ - id,\ - header,\ - sizeof(source)/sizeof(menuitem_t),\ - prev,\ - source,\ - M_DrawCenteredMenu,\ - BASEVIDWIDTH/2, y,\ - 0,\ - NULL\ -} - -#define MAPICONMENUSTYLE(header, source, prev)\ -{\ - MN_NONE,\ - header,\ - sizeof (source)/sizeof (menuitem_t),\ - prev,\ - source,\ - M_DrawServerMenu,\ - 24,40,\ - 0,\ - NULL\ -} - -#define IMAGEDEF(source)\ -{\ - MN_SPECIAL,\ - NULL,\ - sizeof (source)/sizeof (menuitem_t),\ - NULL,\ - source,\ - M_DrawImageDef,\ - 0, 0,\ - 0,\ - NULL\ -} - #ifdef __cplusplus } // extern "C" #endif From 8465dd5fcf4470ddd2cae0a609d05a3eb9603a58 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Fri, 21 Mar 2025 14:28:45 +0100 Subject: [PATCH 12/33] Fix compile and missing menus --- src/deh_tables.c | 2 ++ src/m_menu.c | 2 +- src/m_menu.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index e7856ac91..cac87bce6 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -721,6 +721,8 @@ const char *const MENUTYPES_LIST[] = { "MISC_REPLAYSTART", "PLAYBACK", "OP_CONTROLSETUP", + "OP_GAMEHUD", + "OP_VISUAL", "SPECIAL" }; diff --git a/src/m_menu.c b/src/m_menu.c index b8b59dc5e..779912c72 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2489,7 +2489,7 @@ void M_DrawPauseMenu(void) if ((leveltime % freq) >= freq/2) { V_DrawFixedPatch(204 * FRACUNIT, - (currentMenu->y + (M_GetItemY(MN_MPAUSE, "DISCRQ") - 1) * FRACUNIT, + (currentMenu->y + M_GetItemY(MN_MPAUSE, "DISCRQ") - 1) * FRACUNIT, FRACUNIT, 0, W_CachePatchName("K_REQUE2", PU_CACHE), diff --git a/src/m_menu.h b/src/m_menu.h index 3fb2b9769..0fcc97cd7 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -156,6 +156,8 @@ typedef enum MN_MISC_REPLAYSTART, MN_PLAYBACK, MN_OP_CONTROLSETUP, + MN_OP_GAMEHUD, + MN_OP_VISUAL, MN_SPECIAL, From 802a86422d6d3cfeb304b64b7659755357dbdf0a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Fri, 21 Mar 2025 17:44:22 +0100 Subject: [PATCH 13/33] Impromptu support for menuitem replacement Need this for Discord menus right about now --- src/deh_soc.c | 62 +++++++++++++++++++++++++-------------------------- src/m_menu.c | 2 +- src/m_menu.h | 1 + 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 30690964d..4c4852d83 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2149,9 +2149,16 @@ static menu_t *allocmenu(INT32 num) { if (num < 0 || num >= NUMMENUTYPES) I_Error("Tried to allocate out-of-range menu number"); - if (menunum2menudef[num] == NULL) - menunum2menudef[num] = Z_Malloc(sizeof(menu_t), PU_STATIC, NULL); - return menunum2menudef[num]; + + menu_t *menu = menunum2menudef[num]; + if (menu == NULL) + { + menunum2menudef[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL); + menu->menuid = num; + } + if (menu->drawroutine == NULL) + menu->drawroutine = M_DrawGenericMenu; + return menu; } // super secret menu cvars... :shushing_face: @@ -2171,24 +2178,17 @@ static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { { NULL, NULL } }; -static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) +static void readmenuitem(MYFILE *f, menuitem_t *menuitem) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word = s; char *word2; char *tmp; - menuitem_t *menuitem = menudef->menuitems + menudef->numitems; + UINT16 status = 0; boolean actionset = false; boolean textset = false; - if (strlen(itemname) > 6) - { - deh_warning("MenuItem %s: name too long (max 6 characters)", itemname); - goto toolong; - } - strncpy(menuitem->itemname, itemname, 6); - // taking quite possibly the only opportunity i'll ever get // to avoid three tabs of indentation... do if (myfgets(s, MAXLINELEN, f)) @@ -2248,7 +2248,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } textset = true; - menuitem->status |= flags; + status |= flags; menuitem->text = Z_StrDup(word2); } else if (fastncmp(word, "CVAR", 4)) @@ -2285,7 +2285,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } actionset = true; - menuitem->status |= flags; + status |= flags; menuitem->itemaction.cvar = cvar; } else if (fastcmp(word, "SUBMENU")) @@ -2302,7 +2302,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } actionset = true; - menuitem->status |= IT_SUBMENU; + status |= IT_SUBMENU; menuitem->itemaction.submenu = allocmenu(mn); } else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS")) @@ -2338,7 +2338,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) continue; } actionset = true; - menuitem->status |= flags; + status |= flags; menuitem->itemaction.routine = routine; } else if (fastcmp(word, "ALPHAKEY") || fastcmp(word, "Y")) @@ -2350,12 +2350,7 @@ static void readmenuitem(MYFILE *f, menu_t *menudef, char *itemname) } while (!myfeof(f)); // finish when the line is empty -toolong: - - // text pointer cannot be null - if (!textset) - menuitem->text = ""; - + menuitem->status = status; Z_Free(s); } @@ -2370,12 +2365,6 @@ void readmenu(MYFILE *f, INT32 num) menu_t *menudef = allocmenu(num); - //menuactive = false; - - memset(menudef, 0, sizeof(menu_t)); - menudef->menuid = num; - menudef->drawroutine = M_DrawGenericMenu; - do { if (myfgets(s, MAXLINELEN, f)) @@ -2421,9 +2410,20 @@ void readmenu(MYFILE *f, INT32 num) { if (fastcmp(word, "MENUITEM")) { - menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL); - readmenuitem(f, menudef, word2); - menudef->numitems++; + if (strlen(word2) > 6) + { + deh_warning("Menu %d: item name %s is too long (max 6 characters)", num, word2); + continue; + } + menuitem_t *item = word2[0] == '.' ? NULL : M_GetMenuItemByName(num, word2); + if (item == NULL) + { + menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL); + item = menudef->menuitems + menudef->numitems++; + strncpy(item->itemname, word2, 6); + item->text = ""; + } + readmenuitem(f, item); } else deh_warning("Menu %d: unknown word '%s'", num, word); diff --git a/src/m_menu.c b/src/m_menu.c index 779912c72..d340dbfef 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -315,7 +315,7 @@ static INT16 M_GetMenuIndexByName(menutype_t type, const char *name) return -1; } -static menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name) +menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name) { INT16 i = M_GetMenuIndexByName(type, name); return i >= 0 ? &menunum2menudef[type]->menuitems[i] : NULL; diff --git a/src/m_menu.h b/src/m_menu.h index 0fcc97cd7..7ccca840b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -387,6 +387,7 @@ struct menu_t void M_SetupNextMenu(menu_t *menudef); void M_ClearMenus(boolean callexitmenufunc); +menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name); void M_SinglePlayerMenu(INT32 choice); void M_Options(INT32 choice); From 8471ecabd813a0a0ad207903296a77f1dfb2fafb Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Fri, 21 Mar 2025 18:00:05 +0100 Subject: [PATCH 14/33] SOC the Discord menus Thanks nep for making rich presence build again lol --- src/deh_tables.c | 12 +++++++++++- src/dehacked.c | 9 +++++++++ src/discord.c | 22 ++++++++++++++++++++++ src/m_menu.c | 48 ++---------------------------------------------- src/m_menu.h | 26 +++++++++++--------------- 5 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index cac87bce6..8dac4741a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -716,7 +716,6 @@ const char *const MENUTYPES_LIST[] = { "MP_OFFLINESERVER", "SP_GRANDPRIX", "MISC_REPLAYHUT", - "MISC_DISCORDREQUESTS", "CHANGESPECTATE", "MISC_REPLAYSTART", "PLAYBACK", @@ -724,6 +723,11 @@ const char *const MENUTYPES_LIST[] = { "OP_GAMEHUD", "OP_VISUAL", +#ifdef HAVE_DISCORDRPC + "OP_DISCORD", + "MISC_DISCORDREQUESTS", +#endif + "SPECIAL" }; @@ -814,6 +818,9 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "CHANGECONTROL", &M_ChangeControl }, { "ASSIGNJOYSTICK", &M_AssignJoystick }, { "HANDLEMONITORTOGGLES", &M_HandleMonitorToggles }, +#ifdef HAVE_DISCORDRPC + { "HANDLEDISCORDREQUESTS", &M_HandleDiscordRequests }, +#endif { NULL, NULL } }; @@ -841,6 +848,9 @@ struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWCONTROL", &M_DrawControl }, { "DRAWJOYSTICK", &M_DrawJoystick }, { "DRAWMONITORTOGGLES", &M_DrawMonitorToggles }, +#ifdef HAVE_DISCORDRPC + { "DRAWDISCORDREQUESTS", &M_DrawDiscordRequests }, +#endif { NULL, NULL } }; diff --git a/src/dehacked.c b/src/dehacked.c index 2afd3b8f7..0b00454d8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -234,6 +234,15 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) readfollower(f); continue; } + // sigh... menu hack + else if (fastcmp(word, "DISCORDONLY")) + { +#ifdef HAVE_DISCORDRPC + continue; +#else + break; +#endif + } word2 = strtok(NULL, " "); if (word2) { diff --git a/src/discord.c b/src/discord.c index 4e8af70eb..0c67d2761 100644 --- a/src/discord.c +++ b/src/discord.c @@ -312,6 +312,20 @@ void DRPC_RemoveRequest(discordRequest_t *removeRequest) Z_Free(removeRequest); } +#ifdef _DEBUG +static boolean comregistered = false; +static void COM_DiscordTest_f(void) +{ + DiscordUser test = { + .username = "Jeffma Balls", + .discriminator = "6942", + .userId = "69420694206942069", + .avatar = NULL, // doesn't matter + }; + DRPC_HandleJoinRequest(&test); +} +#endif + /*-------------------------------------------------- void DRPC_Init(void) @@ -334,6 +348,14 @@ void DRPC_Init(void) Discord_Initialize(DISCORD_APPID, &handlers, 1, NULL); I_AddExitFunc(DRPC_Shutdown); DRPC_UpdatePresence(); + +#ifdef _DEBUG + if (!comregistered) + { + COM_AddCommand("discordtest", COM_DiscordTest_f); + comregistered = true; + } +#endif } void DRPC_Shutdown(void) diff --git a/src/m_menu.c b/src/m_menu.c index d340dbfef..8c180d89b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -204,12 +204,6 @@ menu_t FreeslotTest; // the haxor message menu menu_t MessageDef; -#ifdef HAVE_DISCORDRPC -menu_t MISC_DiscordRequestsDef; -static void M_HandleDiscordRequests(INT32 choice); -static void M_DrawDiscordRequests(void); -#endif - #define lsheadingheight 16 // Sky Room @@ -499,13 +493,6 @@ consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HI consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL); consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL); -#ifdef HAVE_DISCORDRPC -static menuitem_t MISC_DiscordRequestsMenu[] = -{ - {IT_KEYHANDLER|IT_NOTHING, NULL, "", {.routine = M_HandleDiscordRequests}, 0}, -}; -#endif - static tic_t playback_last_menu_interaction_leveltime = 0; static menuitem_t MP_ConnectMenu[] = @@ -535,37 +522,10 @@ enum FIRSTSERVERLINE }; -#ifdef HAVE_DISCORDRPC -static menuitem_t OP_DiscordOptionsMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Rich Presence", {.cvar = &cv_discordrp}, 10}, - - {IT_HEADER, NULL, "Rich Presence Settings", {NULL}, 30}, - {IT_STRING | IT_CVAR, NULL, "Streamer Mode", {.cvar = &cv_discordstreamer}, 40}, - - {IT_STRING | IT_CVAR, NULL, "Allow Ask To Join", {.cvar = &cv_discordasks}, 60}, - {IT_STRING | IT_CVAR, NULL, "Allow Invites", {.cvar = &cv_discordinvites}, 70}, -}; -#endif - // ========================================================================== // ALL MENU DEFINITIONS GO HERE // ========================================================================== -#ifdef HAVE_DISCORDRPC -menu_t MISC_DiscordRequestsDef = { - MN_NONE, - NULL, - sizeof (MISC_DiscordRequestsMenu)/sizeof (menuitem_t), - &MPauseDef, - MISC_DiscordRequestsMenu, - M_DrawDiscordRequests, - 0, 0, - 0, - NULL -}; -#endif - // // M_GetGametypeColor // @@ -690,10 +650,6 @@ void M_OpenGLOptionsMenu(INT32 choice) } #endif -#ifdef HAVE_DISCORDRPC -menu_t OP_DiscordOptionsDef = DEFAULTMENUSTYLE(MN_NONE, NULL, OP_DiscordOptionsMenu, &OP_DataOptionsDef, 30, 30); -#endif - // ========================================================================== // CVAR ONCHANGE EVENTS GO HERE // ========================================================================== @@ -9326,7 +9282,7 @@ static const tic_t confirmLength = 3*TICRATE/4; static tic_t confirmDelay = 0; static boolean confirmAccept = false; -static void M_HandleDiscordRequests(INT32 choice) +void M_HandleDiscordRequests(INT32 choice) { if (confirmDelay > 0) return; @@ -9382,7 +9338,7 @@ static void M_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean is V_DrawFixedPatch((x + width)*FRACUNIT, y*FRACUNIT, FRACUNIT, flags|V_FLIP, stickerEnd, NULL); } -static void M_DrawDiscordRequests(void) +void M_DrawDiscordRequests(void) { discordRequest_t *curRequest = discordRequestList; UINT8 *colormap; diff --git a/src/m_menu.h b/src/m_menu.h index 7ccca840b..af09bd978 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -151,7 +151,6 @@ typedef enum MN_MP_OFFLINESERVER, MN_SP_GRANDPRIX, MN_MISC_REPLAYHUT, - MN_MISC_DISCORDREQUESTS, MN_CHANGESPECTATE, MN_MISC_REPLAYSTART, MN_PLAYBACK, @@ -159,6 +158,11 @@ typedef enum MN_OP_GAMEHUD, MN_OP_VISUAL, +#ifdef HAVE_DISCORDRPC + MN_OP_DISCORD, + MN_MISC_DISCORDREQUESTS, +#endif + MN_SPECIAL, MN_FIRSTFREESLOT, @@ -473,6 +477,9 @@ void M_ResetControls(INT32 choice); void M_ChangeControl(INT32 choice); void M_AssignJoystick(INT32 choice); void M_HandleMonitorToggles(INT32 choice); +#ifdef HAVE_DISCORDRPC +void M_HandleDiscordRequests(INT32 choice); +#endif void M_DrawGenericMenu(void); void M_DrawCenteredMenu(void); @@ -497,6 +504,9 @@ void M_DrawMusicTest(void); void M_DrawControl(void); void M_DrawJoystick(void); void M_DrawMonitorToggles(void); +#ifdef HAVE_DISCORDRPC +void M_DrawDiscordRequests(void); +#endif // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); @@ -646,20 +656,6 @@ UINT16 M_GetColorAfter(UINT16 color); void M_InitPlayerSetupColors(void); void M_FreePlayerSetupColors(void); -// These defines make it a little easier to make menus -#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\ -{\ - id,\ - header,\ - sizeof(source)/sizeof(menuitem_t),\ - prev,\ - source,\ - M_DrawGenericMenu,\ - x, y,\ - 0,\ - NULL\ -} - #ifdef __cplusplus } // extern "C" #endif From fca25051cb4ec4d3f58d26047c47b60d2958f802 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 22 Mar 2025 00:45:38 +0100 Subject: [PATCH 15/33] SOC the server connection menu --- src/d_main.cpp | 3 +- src/deh_tables.c | 4 ++ src/m_menu.c | 113 +++++++++++++++++------------------------------ src/m_menu.h | 4 ++ 4 files changed, 49 insertions(+), 75 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index ef7152a6c..188e0daf7 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1477,6 +1477,7 @@ void D_SRB2Main(void) R_RegisterEngineStuff(); S_RegisterSoundStuff(); CON_Register(); + M_Init(); if (!dedicated) { CV_RegisterVar(&cv_ticrate); @@ -1600,8 +1601,6 @@ void D_SRB2Main(void) //--------------------------------------------------------- CONFIG.CFG M_FirstLoadConfig(); // WARNING : this do a "COM_BufExecute()" - M_Init(); - #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen #endif diff --git a/src/deh_tables.c b/src/deh_tables.c index 8dac4741a..e96a47975 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -763,6 +763,9 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "SETUP2PCONTROLSMENU", &M_Setup2PControlsMenu }, { "SETUP3PCONTROLSMENU", &M_Setup3PControlsMenu }, { "SETUP4PCONTROLSMENU", &M_Setup4PControlsMenu }, + { "HANDLESERVERPAGE", &M_HandleServerPage }, + { "REFRESH", &M_Refresh }, + { "CONNECT", &M_Connect }, { "VIDEOMODEMENU", &M_VideoModeMenu }, #ifdef HWRENDER { "OPENGLOPTIONSMENU", &M_OpenGLOptionsMenu }, @@ -848,6 +851,7 @@ struct menu_drawer_s const MENU_DRAWERS[] = { { "DRAWCONTROL", &M_DrawControl }, { "DRAWJOYSTICK", &M_DrawJoystick }, { "DRAWMONITORTOGGLES", &M_DrawMonitorToggles }, + { "DRAWCONNECTMENU", &M_DrawConnectMenu }, #ifdef HAVE_DISCORDRPC { "DRAWDISCORDREQUESTS", &M_DrawDiscordRequests }, #endif diff --git a/src/m_menu.c b/src/m_menu.c index 8c180d89b..557559381 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -106,7 +106,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #define SMALLLINEHEIGHT 8 #define SLIDER_RANGE 10 #define SLIDER_WIDTH (8*SLIDER_RANGE+6) -#define SERVERS_PER_PAGE 11 typedef enum { @@ -188,8 +187,6 @@ static INT32 vidm_column_size; static void M_StopMessage(INT32 choice); -static void M_HandleServerPage(INT32 choice); - // Prototyping is fun, innit? // ========================================================================== // NEEDED FUNCTION PROTOTYPES GO HERE @@ -211,13 +208,6 @@ static char *M_GetConditionString(condition_t cond); // Multiplayer static void M_ConnectMenu(INT32 choice); -static void M_Refresh(INT32 choice); -static void M_Connect(INT32 choice); - -//Misc -#ifdef HAVE_DISCORDRPC -menu_t OP_DiscordOptionsDef; -#endif static patch_t *addonsp[NUM_EXT+5]; @@ -229,7 +219,6 @@ static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the butto // Drawing functions static void M_DrawGenericBackgroundMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); -static void M_DrawConnectMenu(void); // uhhhhhh hack? static void M_ChangecontrolResponse(event_t *ev); @@ -248,7 +237,7 @@ SR_MusicTestDef = {0}, SP_MainDef = {0}, SP_LevelStatsDef = {0}, SP_GrandPrixTem MISC_ReplayStartDef = {0}, SP_ReplayDef = {0}, MP_OfflineServerDef = {0}, MISC_ChangeLevelDef = {0}, MP_ServerDef = {0}, MP_PlayerSetupDef = {0}, OP_ScreenshotOptionsDef = {0}, OP_AllControlsDef = {0}, OP_VideoModeDef = {0}, -OP_DataOptionsDef = {0}; +OP_DataOptionsDef = {0}, MP_ConnectDef = {0}; menu_t MainDef = {0}, OP_JoystickSetDef = {0}; menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_OP_MAIN] = &OP_MainDef, @@ -288,6 +277,7 @@ menu_t *menunum2menudef[NUMMENUTYPES] = { [MN_SR_SOUNDTEST] = &SR_MusicTestDef, [MN_OP_CHANGECONTROLS] = &OP_AllControlsDef, [MN_OP_JOYSTICKSET] = &OP_JoystickSetDef, + [MN_MP_CONNECT] = &MP_ConnectDef, [MN_MAIN] = &MainDef, @@ -413,6 +403,15 @@ static INT16 M_MenuItemRange(menutype_t type, const char *name1, const char *nam return index1; } +// bruh... +static UINT32 M_ServersPerPage(void) +{ + INT32 spp = M_GetMenuIndexByName(MN_MP_CONNECT, "LASLIN") - M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN") + 1; + if (spp < 1 || spp >= MAXSERVERLIST) + I_Error("Broken server connection menu"); + return (UINT32)spp; +} + // ========================================================================== // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== @@ -424,12 +423,12 @@ static CV_PossibleValue_t map_cons_t[] = { {NEXTMAP_SPECIAL, "MAX"}, // TODO: kill nextmap (can't do that i'm afraid!) {0, NULL} }; -consvar_t cv_nextmap = CVAR_INIT ("nextmap", "1", CV_HIDEN|CV_CALL, map_cons_t, Nextmap_OnChange); +consvar_t cv_nextmap = CVAR_INIT ("nextmap", "1", CV_HIDEN|CV_CALL|CV_NOINIT, map_cons_t, Nextmap_OnChange); static INT16 lastnextmap = 1; static CV_PossibleValue_t skins_cons_t[MAXSKINS+1] = {{1, DEFAULTSKIN}}; -consvar_t cv_chooseskin = CVAR_INIT ("chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_cons_t, Nextmap_OnChange); +consvar_t cv_chooseskin = CVAR_INIT ("chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL|CV_NOINIT, skins_cons_t, Nextmap_OnChange); // This gametype list is integral for many different reasons. // When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h! @@ -495,33 +494,6 @@ consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_ static tic_t playback_last_menu_interaction_leveltime = 0; -static menuitem_t MP_ConnectMenu[] = -{ - {IT_STRING | IT_CVAR, NULL, "Sort By", {.cvar = &cv_serversort}, 4}, - {IT_STRING | IT_KEYHANDLER, NULL, "Page", {.routine = M_HandleServerPage}, 12}, - {IT_STRING | IT_CALL, NULL, "Refresh", {.routine = M_Refresh}, 20}, - - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 36}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 48}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 60}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 72}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 84}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 96}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 108}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 120}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 132}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 144}, - {IT_STRING | IT_SPACE, NULL, "", {.routine = M_Connect}, 156}, -}; - -enum -{ - mp_connect_sort, - mp_connect_page, - mp_connect_refresh, - FIRSTSERVERLINE -}; - // ========================================================================== // ALL MENU DEFINITIONS GO HERE // ========================================================================== @@ -623,20 +595,6 @@ fixed_t M_GetMapThumbnail(INT16 mapnum, patch_t **out) return patch->width >= 320 ? FRACUNIT : FRACUNIT*2; } -// Multiplayer -menu_t MP_ConnectDef = -{ - MN_NONE, - "M_MULTI", - sizeof (MP_ConnectMenu)/sizeof (menuitem_t), - &MP_MainDef, - MP_ConnectMenu, - M_DrawConnectMenu, - 27,24, - 0, - M_CancelConnect -}; - // Options #ifdef HWRENDER void M_OpenGLOptionsMenu(INT32 choice) @@ -2673,9 +2631,18 @@ static boolean M_PrepareCupList(void) return true; } +static boolean nextmapinit = false; + // Call before showing any level-select menus static void M_PrepareLevelSelect(void) { + if (!nextmapinit) + { + // nextmap needs CV_NOINIT because it's registered before IWADs + // we have to init here, or else you'll see "1" on the level select... + Nextmap_OnChange(); + nextmapinit = true; + } if (levellistmode != LLM_CREATESERVER) CV_SetValue(&cv_nextmap, M_GetFirstLevelInList()); else @@ -6350,9 +6317,7 @@ Fetch_servers_thread (int *id) #define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT) -static UINT32 localservercount; - -static void M_HandleServerPage(INT32 choice) +void M_HandleServerPage(INT32 choice) { boolean exitmenu = false; // exit to previous menu @@ -6374,7 +6339,7 @@ static void M_HandleServerPage(INT32 choice) case KEY_ENTER: case KEY_RIGHTARROW: S_StartSound(NULL, sfx_menu1); - if ((serverlistpage + 1) * SERVERS_PER_PAGE < serverlistcount) + if ((serverlistpage + 1) * M_ServersPerPage() < serverlistcount) serverlistpage++; break; case KEY_LEFTARROW: @@ -6395,15 +6360,16 @@ static void M_HandleServerPage(INT32 choice) } } -static void M_Connect(INT32 choice) +void M_Connect(INT32 choice) { // do not call menuexitfunc M_ClearMenus(false); - COM_BufAddText(va("connect node %d\n", serverlist[choice-FIRSTSERVERLINE + serverlistpage * SERVERS_PER_PAGE].node)); + INT16 firstserverline = M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN"); + COM_BufAddText(va("connect node %d\n", serverlist[choice-firstserverline + serverlistpage * M_ServersPerPage()].node)); } -static void M_Refresh(INT32 choice) +void M_Refresh(INT32 choice) { (void)choice; @@ -6430,23 +6396,26 @@ static void M_Refresh(INT32 choice) #endif/*MASTERSERVER*/ } -static void M_DrawConnectMenu(void) +void M_DrawConnectMenu(void) { UINT16 i; //const char *gt = "Unknown"; //const char *spd = ""; const char *pwr = "----"; - INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; + INT16 firstserverline = M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN"); + UINT32 serversperpage = M_ServersPerPage(); // server sperpage? + INT32 numPages = (serverlistcount+(serversperpage-1))/serversperpage; int waiting; + menu_t *conmenu = menunum2menudef[MN_MP_CONNECT]; // meh, whatever - for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) - MP_ConnectMenu[i].status = IT_STRING | IT_SPACE; + for (i = firstserverline; i < firstserverline+serversperpage; i++) + conmenu->menuitems[i].status = IT_STRING | IT_SPACE; if (!numPages) numPages = 1; // Page num - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_page].alphaKey, + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + M_GetItemY(MN_MP_CONNECT, "PAGE"), highlightflags, va("%u of %d", serverlistpage+1, numPages)); // Horizontal line! @@ -6455,11 +6424,11 @@ static void M_DrawConnectMenu(void) if (serverlistcount <= 0) V_DrawString(currentMenu->x,currentMenu->y+SERVERHEADERHEIGHT, 0, "No servers found"); else - for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++) + for (i = 0; i < min(serverlistcount - serverlistpage * serversperpage, serversperpage); i++) { - INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE; + INT32 slindex = i + serverlistpage * serversperpage; UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0) - |((itemOn == FIRSTSERVERLINE+i) ? highlightflags : 0)|V_ALLOWLOWERCASE; + |((itemOn == firstserverline+i) ? highlightflags : 0)|V_ALLOWLOWERCASE; V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); @@ -6493,11 +6462,9 @@ static void M_DrawConnectMenu(void) if (serverlist[slindex].info.cheatsenabled) V_DrawSmallString(currentMenu->x+265, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); - MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; + conmenu->menuitems[i+firstserverline].status = IT_STRING | IT_CALL; } - localservercount = serverlistcount; - M_DrawGenericMenu(); waiting = M_GetWaitingMode(); diff --git a/src/m_menu.h b/src/m_menu.h index af09bd978..371778dea 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -423,6 +423,9 @@ void M_Setup1PControlsMenu(INT32 choice); void M_Setup2PControlsMenu(INT32 choice); void M_Setup3PControlsMenu(INT32 choice); void M_Setup4PControlsMenu(INT32 choice); +void M_HandleServerPage(INT32 choice); +void M_Refresh(INT32 choice); +void M_Connect(INT32 choice); void M_VideoModeMenu(INT32 choice); #ifdef HWRENDER void M_OpenGLOptionsMenu(INT32 choice); @@ -491,6 +494,7 @@ void M_DrawTimeAttackMenu(void); void M_DrawMPMainMenu(void); void M_DrawSetupMultiPlayerMenu(void); void M_DrawServerMenu(void); +void M_DrawConnectMenu(void); void M_DrawVideoMenu(void); void M_DrawVideoMode(void); void M_DrawSkyRoom(void); From c119f0c31d17fe03e2d4cafc3a7c685120e1ed14 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 22 Mar 2025 00:49:18 +0100 Subject: [PATCH 16/33] The Python script I used for testing --- extras/testms.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 extras/testms.py diff --git a/extras/testms.py b/extras/testms.py new file mode 100644 index 000000000..8ee80643f --- /dev/null +++ b/extras/testms.py @@ -0,0 +1,40 @@ +# connection menu testing script +# "masterserver http://localhost:12345" in console +# i know nothing about HTTP + +import http.server + +# just enough for two pages... +fakeserverlist = """\ +localhost 5029 Discord: Jeffma Balls#6942 +localhost 5030 Discord: Jeffma Balls#6942 +localhost 5031 Discord: Jeffma Balls#6942 +localhost 5032 Discord: Jeffma Balls#6942 +localhost 5033 Discord: Jeffma Balls#6942 +localhost 5034 Discord: Jeffma Balls#6942 +localhost 5035 Discord: Jeffma Balls#6942 +localhost 5036 Discord: Jeffma Balls#6942 +localhost 5037 Discord: Jeffma Balls#6942 +localhost 5038 Discord: Jeffma Balls#6942 +localhost 5039 Discord: Jeffma Balls#6942 +localhost 5040 Discord: Jeffma Balls#6942 +""" + +class jart(http.server.BaseHTTPRequestHandler): + def do_GET(self): + response = "" + if self.path.startswith("/games/SRB2Kart/version"): + response = "11 the best version\n" + elif self.path.startswith("/games/SRB2Kart/11/servers") or self.path.startswith("/games/SRB2Kart/10/servers"): + response = fakeserverlist + elif self.path.startswith("/rules"): + response = "Do whatever lol\n\n" + + self.send_response(200) + self.end_headers() + if not response: + print("No response!?") + self.wfile.write(bytes(response, "utf-8")) + +server = http.server.HTTPServer(("localhost", 12345), jart) +server.serve_forever() From f51868ed3f1331430e04580ad9cb745d50270834 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 22 Mar 2025 01:40:33 +0100 Subject: [PATCH 17/33] No more menu_t definitions, use menutype constants everywhere --- src/d_main.cpp | 2 +- src/deh_soc.c | 10 +- src/f_finale.c | 2 +- src/m_cheat.c | 4 +- src/m_menu.c | 270 ++++++++++++++++++-------------------------- src/m_menu.h | 14 +-- src/sdl/i_video.cpp | 4 +- 7 files changed, 126 insertions(+), 180 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 188e0daf7..925fc7366 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1062,7 +1062,7 @@ void D_StartTitle(void) F_StartTitleScreen(); - currentMenu = &MainDef; // reset the current menu ID + M_SetCurrentMenu(MN_MAIN); // reset the current menu ID // Reset the palette if (rendermode != render_none) diff --git a/src/deh_soc.c b/src/deh_soc.c index 4c4852d83..fc32b2a11 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2150,10 +2150,10 @@ static menu_t *allocmenu(INT32 num) if (num < 0 || num >= NUMMENUTYPES) I_Error("Tried to allocate out-of-range menu number"); - menu_t *menu = menunum2menudef[num]; + menu_t *menu = menudefs[num]; if (menu == NULL) { - menunum2menudef[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL); + menudefs[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL); menu->menuid = num; } if (menu->drawroutine == NULL) @@ -2303,7 +2303,8 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) } actionset = true; status |= IT_SUBMENU; - menuitem->itemaction.submenu = allocmenu(mn); + allocmenu(mn); + menuitem->itemaction.submenu = mn; } else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS")) { @@ -2583,7 +2584,8 @@ void readmenu(MYFILE *f, INT32 num) deh_warning("Menu %d: unknown previous menu '%s'", num, word2); continue; } - menudef->prevMenu = allocmenu(value); + allocmenu(value); + menudef->prevMenu = value; } else if (fastcmp(word, "DRAWROUTINE")) { diff --git a/src/f_finale.c b/src/f_finale.c index 6ccf2da24..dd2009d27 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1169,7 +1169,7 @@ void F_InitMenuPresValues(void) { menuanimtimer = 0; prevMenuId = 0; - activeMenuId = MainDef.menuid; + activeMenuId = MN_MAIN; // Set defaults for presentation values strncpy(curbgname, "TITLESKY", 9); diff --git a/src/m_cheat.c b/src/m_cheat.c index 61c7f3441..eecee10fe 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -82,7 +82,7 @@ static UINT8 cheatf_warp(void) /*if (modifiedgame) * return 0;*/ - if (menuactive && currentMenu != &MainDef) + if (menuactive && activeMenuId != MN_MAIN) return 0; // Only on the main menu! // Temporarily unlock EVERYTHING. @@ -117,7 +117,7 @@ static UINT8 cheatf_devmode(void) if (modifiedgame) return 0; - if (menuactive && currentMenu != &MainDef) + if (menuactive && activeMenuId != MN_MAIN) return 0; // Only on the main menu! S_StartSound(0, sfx_itemup); diff --git a/src/m_menu.c b/src/m_menu.c index 557559381..3f0aea728 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -167,6 +167,8 @@ static UINT32 serverlistpage; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? +menu_t *menudefs[NUMMENUTYPES] = {NULL}; // pointers to all menudefs +static menu_t *currentMenu; // current menudef static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 skullAnimCounter = 10; // skull animation counter static tic_t followertimer = 0; // Used for smooth follower floating @@ -195,9 +197,6 @@ static void M_StopMessage(INT32 choice); void M_SetWaitingMode(int mode); int M_GetWaitingMode(void); -// a single freeslot menu for testing -menu_t FreeslotTest; - // the haxor message menu menu_t MessageDef; @@ -228,69 +227,13 @@ static void Newgametype_OnChange(void); static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); -// temporary measure until menu_t and menupres_t are merged (hopefully) -static menu_t MP_MainDef = {0}, OP_OpenGLOptionsDef = {0}, SP_TimeAttackDef = {0}, -OP_SoundOptionsDef = {0}, OP_MainDef = {0}, PlaybackMenuDef = {0}, MAPauseDef = {0}, -SPauseDef = {0}, MPauseDef = {0}, OP_AddonsOptionsDef = {0}, MISC_AddonsDef = {0}, -MISC_ReplayHutDef = {0}, SR_PandoraDef = {0}, MISC_HelpDef = {0}, SR_EmblemHintDef = {0}, -SR_MusicTestDef = {0}, SP_MainDef = {0}, SP_LevelStatsDef = {0}, SP_GrandPrixTempDef = {0}, -MISC_ReplayStartDef = {0}, SP_ReplayDef = {0}, MP_OfflineServerDef = {0}, -MISC_ChangeLevelDef = {0}, MP_ServerDef = {0}, MP_PlayerSetupDef = {0}, -OP_ScreenshotOptionsDef = {0}, OP_AllControlsDef = {0}, OP_VideoModeDef = {0}, -OP_DataOptionsDef = {0}, MP_ConnectDef = {0}; -menu_t MainDef = {0}, OP_JoystickSetDef = {0}; -menu_t *menunum2menudef[NUMMENUTYPES] = { - [MN_OP_MAIN] = &OP_MainDef, - [MN_OP_VIDEOMODE] = &OP_VideoModeDef, - [MN_OP_OPENGL] = &OP_OpenGLOptionsDef, - [MN_OP_SOUND] = &OP_SoundOptionsDef, - [MN_OP_DATA] = &OP_DataOptionsDef, - [MN_OP_ADDONS] = &OP_AddonsOptionsDef, - [MN_OP_SCREENSHOTS] = &OP_ScreenshotOptionsDef, - - [MN_MP_MAIN] = &MP_MainDef, - [MN_MP_PLAYERSETUP] = &MP_PlayerSetupDef, - [MN_MP_SERVER] = &MP_ServerDef, - [MN_MP_OFFLINESERVER] = &MP_OfflineServerDef, - - [MN_SP_MAIN] = &SP_MainDef, - [MN_SP_GRANDPRIX] = &SP_GrandPrixTempDef, - [MN_SP_TIMEATTACK] = &SP_TimeAttackDef, - [MN_SP_REPLAY] = &SP_ReplayDef, - - [MN_SP_LEVELSTATS] = &SP_LevelStatsDef, - [MN_MISC_REPLAYHUT] = &MISC_ReplayHutDef, - [MN_SR_EMBLEMHINT] = &SR_EmblemHintDef, - [MN_SR_PANDORA] = &SR_PandoraDef, - - [MN_AD_MAIN] = &MISC_AddonsDef, - - [MN_SPAUSE] = &SPauseDef, - [MN_MPAUSE] = &MPauseDef, - [MN_MAPAUSE] = &MAPauseDef, - [MN_CHANGELEVEL] = &MISC_ChangeLevelDef, - - // who even cares how i sort this shit anymore - [MN_MISC_REPLAYSTART] = &MISC_ReplayStartDef, - [MN_PLAYBACK] = &PlaybackMenuDef, - [MN_HELP] = &MISC_HelpDef, - [MN_SR_SOUNDTEST] = &SR_MusicTestDef, - [MN_OP_CHANGECONTROLS] = &OP_AllControlsDef, - [MN_OP_JOYSTICKSET] = &OP_JoystickSetDef, - [MN_MP_CONNECT] = &MP_ConnectDef, - - [MN_MAIN] = &MainDef, - - [MN_FIRSTFREESLOT] = &FreeslotTest, -}; - // a wide array of functions for interacting with menu items // should probably trim these a bit... static INT16 M_GetMenuIndexByName(menutype_t type, const char *name) { INT16 i; - menu_t *menu = menunum2menudef[type]; + menu_t *menu = menudefs[type]; I_Assert(menu); for (i = 0; i < menu->numitems; i++) @@ -302,12 +245,12 @@ static INT16 M_GetMenuIndexByName(menutype_t type, const char *name) menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name) { INT16 i = M_GetMenuIndexByName(type, name); - return i >= 0 ? &menunum2menudef[type]->menuitems[i] : NULL; + return i >= 0 ? &menudefs[type]->menuitems[i] : NULL; } static void M_GetMenuItemNameByIndex(menutype_t type, INT16 index, char out[6]) { - menu_t *menu = menunum2menudef[type]; + menu_t *menu = menudefs[type]; I_Assert(menu); strncpy(out, menu->menuitems[index].itemname, 6); } @@ -412,6 +355,14 @@ static UINT32 M_ServersPerPage(void) return (UINT32)spp; } +// set the current menu, but without doing everything that M_SetupNextMenu does +// is this even necessary...? +void M_SetCurrentMenu(menutype_t num) +{ + currentMenu = menudefs[num]; + activeMenuId = num; +} + // ========================================================================== // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== @@ -602,7 +553,7 @@ void M_OpenGLOptionsMenu(INT32 choice) (void)choice; if (rendermode == render_opengl) - M_SetupNextMenu(&OP_OpenGLOptionsDef); + M_SetupNextMenu(MN_OP_OPENGL); else M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING); } @@ -653,7 +604,7 @@ void Nextmap_OnChange(void) leveltitle = cv_nextmap.value ? G_BuildMapTitle(cv_nextmap.value) : Z_StrDup("Random"); cv_nextmap.string = cv_nextmap.zstring = leveltitle; - if (currentMenu == &SP_TimeAttackDef) + if (activeMenuId == MN_SP_TIMEATTACK) { // see also p_setup.c's P_LoadRecordGhosts const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; @@ -839,9 +790,6 @@ void Moviemode_option_Onchange(void) // END ORGANIZATION STUFF. // ========================================================================== -// current menudef -menu_t *currentMenu = &MainDef; - // ========================================================================= // MENU PRESENTATION PARAMETER HANDLING (BACKGROUNDS) // ========================================================================= @@ -1209,7 +1157,7 @@ boolean M_Responder(event_t *ev) return true; M_StartControlPanel(); M_Options(0); - currentMenu = &OP_SoundOptionsDef; + M_SetCurrentMenu(MN_OP_SOUND); itemOn = 0; return true; @@ -1231,7 +1179,7 @@ boolean M_Responder(event_t *ev) return true; M_StartControlPanel(); M_Options(0); - M_SetupNextMenu(&OP_MainDef); + M_SetupNextMenu(MN_OP_MAIN); return true; // Screenshots on F8 now handled elsewhere @@ -1319,7 +1267,7 @@ boolean M_Responder(event_t *ev) routine = M_ChangeCvar; } - if (currentMenu == &PlaybackMenuDef && !con_destlines) + if (activeMenuId == MN_PLAYBACK && !con_destlines) { playback_last_menu_interaction_leveltime = leveltime; // Flip left/right with up/down for the playback menu, since it's a horizontal icon row. @@ -1400,7 +1348,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) + if (activeMenuId != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(0); } @@ -1410,7 +1358,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) + if (activeMenuId != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(1); } @@ -1420,7 +1368,7 @@ boolean M_Responder(event_t *ev) noFurtherInput = true; currentMenu->lastOn = itemOn; - if (currentMenu == &PlaybackMenuDef) + if (activeMenuId == MN_PLAYBACK) { boolean held = (boolean)playback_enterheld; if (held) @@ -1442,10 +1390,7 @@ boolean M_Responder(event_t *ev) break; case IT_SUBMENU: currentMenu->lastOn = itemOn; - if ((menu_t *)(currentMenu->menuitems[itemOn].itemaction.submenu)->menuitems == NULL) - CONS_Alert(CONS_WARNING, "Submenu is empty!\n"); - else - M_SetupNextMenu((menu_t *)currentMenu->menuitems[itemOn].itemaction.submenu); + M_SetupNextMenu(currentMenu->menuitems[itemOn].itemaction.submenu); break; } } @@ -1465,7 +1410,7 @@ boolean M_Responder(event_t *ev) multiplayer = false; } - if (currentMenu == &SP_TimeAttackDef) + if (activeMenuId == MN_SP_TIMEATTACK) { // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. menuactive = false; @@ -1499,7 +1444,7 @@ boolean M_Responder(event_t *ev) || cv == &cv_newgametype) return true; - if (currentMenu != &OP_SoundOptionsDef || itemOn > 3) + if (activeMenuId != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(-1); return true; @@ -1619,7 +1564,7 @@ void M_Drawer(void) if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) - if (!WipeInAction && currentMenu != &PlaybackMenuDef) // Replay playback has its own background + if (!WipeInAction && activeMenuId != MN_PLAYBACK) // Replay playback has its own background V_DrawFadeScreen(0xFF00, 16); if (currentMenu->drawroutine) @@ -1628,7 +1573,7 @@ void M_Drawer(void) currentMenu->drawroutine(); // call current menu Draw routine } - if (currentMenu == &MainDef) + if (activeMenuId == MN_MAIN) { INT32 texty = vid.height - 10*vid.dupy; #define addtext(f, str) {\ @@ -1684,17 +1629,17 @@ void M_StartControlPanel(void) if (demo.playback) { - currentMenu = &PlaybackMenuDef; + M_SetCurrentMenu(MN_PLAYBACK); playback_last_menu_interaction_leveltime = leveltime; } else if (!Playing()) { - currentMenu = &MainDef; + M_SetCurrentMenu(MN_MAIN); M_SetItemOn(MN_MAIN, "SINGLE"); } else if (modeattacking) { - currentMenu = &MAPauseDef; + M_SetCurrentMenu(MN_MAPAUSE); M_SetItemOn(MN_MAPAUSE, "CONTIN"); } else if (!(netgame || multiplayer)) // Single Player @@ -1712,7 +1657,7 @@ void M_StartControlPanel(void) M_SetItemStatus(MN_SPAUSE, "EMBLEM", M_SecretUnlocked(SECRET_EMBLEMHINTS) ? IT_STRING|IT_CALL : IT_DISABLED); - currentMenu = &SPauseDef; + M_SetCurrentMenu(MN_SPAUSE); M_SetItemOn(MN_SPAUSE, "CONTIN"); } else // multiplayer @@ -1826,7 +1771,7 @@ void M_StartControlPanel(void) } #endif - currentMenu = &MPauseDef; + M_SetCurrentMenu(MN_MPAUSE); M_SetItemOn(MN_MPAUSE, "CONTIN"); } @@ -1854,7 +1799,7 @@ void M_ClearMenus(boolean callexitmenufunc) #endif //Alam: But not on the Dreamcast's VMUs if (currentMenu == &MessageDef) // Oh sod off! - currentMenu = &MainDef; // Not like it matters + M_SetCurrentMenu(MN_MAIN); // Not like it matters menuactive = false; hidetitlemap = false; } @@ -1862,15 +1807,17 @@ void M_ClearMenus(boolean callexitmenufunc) // // M_SetupNextMenu // -void M_SetupNextMenu(menu_t *menudef) +void M_SetupNextMenu(menutype_t menunum) { INT16 i; + menu_t *menudef = menudefs[menunum]; // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH if (currentMenu != menudef && currentMenu->quitroutine) currentMenu->quitroutine(0); currentMenu = menudef; + activeMenuId = menunum; itemOn = currentMenu->lastOn; // in case of... @@ -1916,7 +1863,7 @@ void M_Ticker(void) followertimer++; - if (currentMenu == &PlaybackMenuDef) + if (activeMenuId == MN_PLAYBACK) { if (playback_enterheld > 0) playback_enterheld--; @@ -2396,7 +2343,7 @@ void M_DrawPauseMenu(void) { #ifdef HAVE_DISCORDRPC // kind of hackily baked in here - if (currentMenu == &MPauseDef && discordRequestList != NULL) + if (activeMenuId == MN_MPAUSE && discordRequestList != NULL) { const tic_t freq = TICRATE/2; @@ -2771,7 +2718,7 @@ menu_t MessageDef = MN_NONE, // id NULL, // title 1, // # of menu items - NULL, // previous menu (TO HACK) + MN_NONE, // previous menu (TO HACK) MessageMenu, // menuitem_t -> M_DrawMessageMenu, // drawing routine -> 0, 0, // x, y (TO HACK) @@ -2825,9 +2772,9 @@ void M_StartMessage(const char *string, void *routine, M_StartControlPanel(); // can't put menuactive to true if (currentMenu == &MessageDef) // Prevent recursion - MessageDef.prevMenu = ((demo.playback) ? &PlaybackMenuDef : &MainDef); + MessageDef.prevMenu = demo.playback ? MN_PLAYBACK : MN_MAIN; else - MessageDef.prevMenu = currentMenu; + MessageDef.prevMenu = activeMenuId; MessageDef.menuitems[0].text = message; MessageDef.menuitems[0].alphaKey = (UINT8)itemtype; @@ -2875,6 +2822,7 @@ void M_StartMessage(const char *string, void *routine, //M_SetupNextMenu(); currentMenu = &MessageDef; + activeMenuId = MN_NONE; itemOn = 0; } @@ -3031,7 +2979,7 @@ void M_AddonsOptions(INT32 choice) (void)choice; Addons_option_Onchange(); - M_SetupNextMenu(&OP_AddonsOptionsDef); + M_SetupNextMenu(MN_OP_ADDONS); } #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!" @@ -3099,8 +3047,8 @@ void M_Addons(INT32 choice) addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); - MISC_AddonsDef.prevMenu = currentMenu; - M_SetupNextMenu(&MISC_AddonsDef); + menudefs[MN_AD_MAIN]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_AD_MAIN); } #define width 4 @@ -3170,7 +3118,7 @@ static char *M_AddonsHeaderPath(void) } #define UNEXIST S_StartSound(NULL, sfx_s26d);\ - M_SetupNextMenu(MISC_AddonsDef.prevMenu);\ + M_SetupNextMenu(menudefs[MN_AD_MAIN]->prevMenu);\ M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING) #define CLEARNAME Z_Free(refreshdirname);\ @@ -3634,7 +3582,7 @@ void M_ReplayHut(INT32 choice) PrepReplayList(); menuactive = true; - M_SetupNextMenu(&MISC_ReplayHutDef); + M_SetupNextMenu(MN_MISC_REPLAYHUT); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -3723,7 +3671,7 @@ void M_HandleReplayHutList(INT32 choice) default: // We can't just use M_SetupNextMenu because that'll run ReplayDef's quitroutine and boot us back to the title screen! currentMenu->lastOn = itemOn; - currentMenu = &MISC_ReplayStartDef; + M_SetCurrentMenu(MN_MISC_REPLAYSTART); replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; @@ -4456,7 +4404,7 @@ void M_PandorasBox(INT32 choice) (void)choice; CV_StealthSetValue(&cv_dummyrings, players[consoleplayer].rings); CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); - M_SetupNextMenu(&SR_PandoraDef); + M_SetupNextMenu(MN_SR_PANDORA); } void M_ExitPandorasBox(INT32 choice) @@ -4585,16 +4533,16 @@ void M_Options(INT32 choice) M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET); - OP_MainDef.prevMenu = currentMenu; - M_SetupNextMenu(&OP_MainDef); + menudefs[MN_OP_MAIN]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_OP_MAIN); } void M_Manual(INT32 choice) { (void)choice; - MISC_HelpDef.prevMenu = (choice == INT32_MAX ? NULL : currentMenu); - M_SetupNextMenu(&MISC_HelpDef); + menudefs[MN_HELP]->prevMenu = choice == INT32_MAX ? MN_NONE : activeMenuId; + M_SetupNextMenu(MN_HELP); } static void M_RetryResponse(INT32 ch) @@ -4790,7 +4738,7 @@ void M_EmblemHints(INT32 choice) { (void)choice; M_SetItemStatus(MN_SR_EMBLEMHINT, "RADAR", M_SecretUnlocked(SECRET_ITEMFINDER) ? IT_CVAR|IT_STRING : IT_SECRET); - M_SetupNextMenu(&SR_EmblemHintDef); + M_SetupNextMenu(MN_SR_EMBLEMHINT); M_SetItemOn(MN_SR_EMBLEMHINT, "BACK"); // always start on back. } @@ -4849,7 +4797,7 @@ void M_DrawSkyRoom(void) M_DrawGenericMenu(); - if (currentMenu == &OP_SoundOptionsDef) + if (activeMenuId == MN_OP_SOUND) { V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+M_GetItemY(MN_OP_SOUND, "SNDENA"), @@ -4963,7 +4911,7 @@ void M_MusicTest(INT32 choice) st_sel = 0; - M_SetupNextMenu(&SR_MusicTestDef); + M_SetupNextMenu(MN_SR_SOUNDTEST); } void M_DrawMusicTest(void) @@ -5300,7 +5248,7 @@ void M_SinglePlayerMenu(INT32 choice) M_SetItemStatus(MN_SP_MAIN, "GP", IT_CALL|IT_STRING); M_SetItemStatus(MN_SP_MAIN, "TA", M_SecretUnlocked(SECRET_TIMEATTACK) ? IT_CALL|IT_STRING : IT_SECRET); M_SetItemStatus(MN_SP_MAIN, "IT", M_SecretUnlocked(SECRET_ITEMBREAKER) ? IT_CALL|IT_STRING : IT_SECRET); - M_SetupNextMenu(&SP_MainDef); + M_SetupNextMenu(MN_SP_MAIN); } @@ -5383,7 +5331,7 @@ void M_Statistics(INT32 choice) if (statsMax < 0) statsMax = 0; - M_SetupNextMenu(&SP_LevelStatsDef); + M_SetupNextMenu(MN_SP_LEVELSTATS); } static void M_DrawStatsMaps(void) @@ -5661,7 +5609,7 @@ void M_GrandPrixTemp(INT32 choice) return; } M_PatchSkinNameTable(); - M_SetupNextMenu(&SP_GrandPrixTempDef); + M_SetupNextMenu(MN_SP_GRANDPRIX); } // Start Grand Prix! @@ -5746,7 +5694,7 @@ void M_DrawTimeAttackMenu(void) V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); M_DrawMenuTitle(); - if (currentMenu == &SP_TimeAttackDef) + if (activeMenuId == MN_SP_TIMEATTACK) M_DrawLevelSelectOnly(true, false); // draw menu (everything else goes on top of it) @@ -5789,7 +5737,7 @@ void M_DrawTimeAttackMenu(void) INT32 soffset = 40, strw = V_StringWidth(str, 0); // hack to keep the menu from overlapping the level icon - if (currentMenu != &SP_TimeAttackDef || cv == &cv_nextmap) + if (activeMenuId != MN_SP_TIMEATTACK || cv == &cv_nextmap) soffset = 0; // Should see nothing but strings @@ -5850,8 +5798,8 @@ void M_DrawTimeAttackMenu(void) // ALWAYS DRAW player name, level name, skin and color even when not on this menu! // TODO: this whole thing needs to go - menu_t *tamenu = menunum2menudef[MN_SP_TIMEATTACK]; - if (currentMenu != tamenu) + menu_t *tamenu = menudefs[MN_SP_TIMEATTACK]; + if (activeMenuId != MN_SP_TIMEATTACK) { consvar_t *ncv; INT16 first = M_MenuItemRange(MN_SP_TIMEATTACK, "NAME", "LEVEL", 4); @@ -5901,7 +5849,7 @@ void M_TimeAttack(INT32 choice) M_PatchSkinNameTable(); M_PrepareLevelSelect(); - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(MN_SP_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -5934,7 +5882,7 @@ void M_ItemBreaker(INT32 choice) M_PatchSkinNameTable(); M_PrepareLevelSelect(); - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(MN_SP_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -6040,7 +5988,7 @@ void M_ReplayTimeAttack(INT32 choice) modeattacking = (levellistmode == LLM_ITEMBREAKER ? ATTACKING_ITEMBREAK : ATTACKING_TIME); // set modeattacking before G_DoPlayDemo so the map loader knows demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed - if (currentMenu == &SP_ReplayDef) + if (activeMenuId == MN_SP_REPLAY) { switch(choice) { default: @@ -6070,7 +6018,7 @@ static void M_EraseGuest(INT32 choice) (void)choice; if (FIL_FileExists(rguest)) remove(rguest); - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(MN_SP_TIMEATTACK); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); @@ -6092,7 +6040,7 @@ static void M_OverwriteGuest(const char *which) } FIL_WriteFile(rguest, buf, len); Z_Free(rguest); - M_SetupNextMenu(&SP_TimeAttackDef); + M_SetupNextMenu(MN_SP_TIMEATTACK); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data saved.\n"),NULL,MM_NOTHING); @@ -6160,7 +6108,7 @@ void M_ModeAttackEndGame(INT32 choice) M_StartControlPanel(); if (modeattacking) - currentMenu = &SP_TimeAttackDef; + M_SetCurrentMenu(MN_SP_TIMEATTACK); itemOn = currentMenu->lastOn; G_SetGamestate(GS_TIMEATTACK); @@ -6406,7 +6354,7 @@ void M_DrawConnectMenu(void) UINT32 serversperpage = M_ServersPerPage(); // server sperpage? INT32 numPages = (serverlistcount+(serversperpage-1))/serversperpage; int waiting; - menu_t *conmenu = menunum2menudef[MN_MP_CONNECT]; // meh, whatever + menu_t *conmenu = menudefs[MN_MP_CONNECT]; // meh, whatever for (i = firstserverline; i < firstserverline+serversperpage; i++) conmenu->menuitems[i].status = IT_STRING | IT_SPACE; @@ -6613,7 +6561,7 @@ static void M_ConnectMenu(INT32 choice) // first page of servers serverlistpage = 0; - M_SetupNextMenu(&MP_ConnectDef); + M_SetupNextMenu(MN_MP_CONNECT); itemOn = 0; #if defined (MASTERSERVER) && defined (HAVE_THREADS) @@ -6695,7 +6643,7 @@ void M_StartServer(INT32 choice) (void)choice; - if (currentMenu == &MP_OfflineServerDef) + if (activeMenuId == MN_MP_OFFLINESERVER) netgame = false; else netgame = true; @@ -6724,7 +6672,7 @@ void M_StartServer(INT32 choice) SplitScreen_OnChange(); } - if (currentMenu == &MP_OfflineServerDef) // offline server + if (activeMenuId == MN_MP_OFFLINESERVER) // offline server { paused = false; SV_StartSinglePlayerServer(); @@ -6853,7 +6801,7 @@ void M_MapChange(INT32 choice) CV_SetValue(&cv_nextmap, gamemap); M_PrepareLevelSelect(); - M_SetupNextMenu(&MISC_ChangeLevelDef); + M_SetupNextMenu(MN_CHANGELEVEL); } void M_StartOfflineServerMenu(INT32 choice) @@ -6861,7 +6809,7 @@ void M_StartOfflineServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - M_SetupNextMenu(&MP_OfflineServerDef); + M_SetupNextMenu(MN_MP_OFFLINESERVER); } void M_StartServerMenu(INT32 choice) @@ -6869,7 +6817,7 @@ void M_StartServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - M_SetupNextMenu(&MP_ServerDef); + M_SetupNextMenu(MN_MP_SERVER); } @@ -7181,8 +7129,8 @@ void M_DrawSetupMultiPlayerMenu(void) char *fname; INT16 i; - mx = MP_PlayerSetupDef.x; - my = MP_PlayerSetupDef.y; + mx = menudefs[MN_MP_PLAYERSETUP]->x; + my = menudefs[MN_MP_PLAYERSETUP]->y; statx = (BASEVIDWIDTH - mx - 118); staty = (my+62); @@ -7704,8 +7652,8 @@ void M_SetupMultiPlayer(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER|IT_STRING); - MP_PlayerSetupDef.prevMenu = currentMenu; - M_SetupNextMenu(&MP_PlayerSetupDef); + menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_MP_PLAYERSETUP); } // start the multiplayer setup menu, for secondary player (splitscreen mode) @@ -7748,8 +7696,8 @@ void M_SetupMultiPlayer2(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - MP_PlayerSetupDef.prevMenu = currentMenu; - M_SetupNextMenu(&MP_PlayerSetupDef); + menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_MP_PLAYERSETUP); } // start the multiplayer setup menu, for third player (splitscreen mode) @@ -7792,8 +7740,8 @@ void M_SetupMultiPlayer3(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - MP_PlayerSetupDef.prevMenu = currentMenu; - M_SetupNextMenu(&MP_PlayerSetupDef); + menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_MP_PLAYERSETUP); } // start the multiplayer setup menu, for third player (splitscreen mode) @@ -7836,8 +7784,8 @@ void M_SetupMultiPlayer4(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - MP_PlayerSetupDef.prevMenu = currentMenu; - M_SetupNextMenu(&MP_PlayerSetupDef); + menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; + M_SetupNextMenu(MN_MP_PLAYERSETUP); } void M_QuitMultiPlayerMenu(INT32 choice) @@ -8086,7 +8034,7 @@ void M_ScreenshotOptions(INT32 choice) Screenshot_option_Onchange(); Moviemode_mode_Onchange(); - M_SetupNextMenu(&OP_ScreenshotOptionsDef); + M_SetupNextMenu(MN_OP_SCREENSHOTS); } // ============= @@ -8105,7 +8053,7 @@ void M_DrawJoystick(void) for (i = 0; i <= MAXGAMEPADS; i++) { - M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1); + M_DrawTextBox(menudefs[MN_OP_JOYSTICKSET]->x-8, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-12, 28, 1); #ifdef JOYSTICK_HOTPLUG if (atoi(cv_usejoystick[setupcontrolplayer-1].string) > I_NumJoys()) @@ -8114,7 +8062,7 @@ void M_DrawJoystick(void) #endif compareval = cv_usejoystick[setupcontrolplayer-1].value; - V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4, (i == compareval) ? V_GREENMAP : 0, joystickInfo[i]); + V_DrawString(menudefs[MN_OP_JOYSTICKSET]->x, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-4, (i == compareval) ? V_GREENMAP : 0, joystickInfo[i]); } } @@ -8154,7 +8102,7 @@ void M_SetupJoystickMenu(INT32 choice) #endif } - M_SetupNextMenu(&OP_JoystickSetDef); + M_SetupNextMenu(MN_OP_JOYSTICKSET); } void M_Setup1PJoystickMenu(INT32 choice) @@ -8255,7 +8203,7 @@ void M_Setup1PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_CONTROL); // Center View */ - M_SetupNextMenu(&OP_AllControlsDef); + M_SetupNextMenu(MN_OP_CHANGECONTROLS); } void M_Setup2PControlsMenu(INT32 choice) @@ -8288,7 +8236,7 @@ void M_Setup2PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(&OP_AllControlsDef); + M_SetupNextMenu(MN_OP_CHANGECONTROLS); } void M_Setup3PControlsMenu(INT32 choice) @@ -8321,7 +8269,7 @@ void M_Setup3PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(&OP_AllControlsDef); + M_SetupNextMenu(MN_OP_CHANGECONTROLS); } void M_Setup4PControlsMenu(INT32 choice) @@ -8354,7 +8302,7 @@ void M_Setup4PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(&OP_AllControlsDef); + M_SetupNextMenu(MN_OP_CHANGECONTROLS); } #define controlheight 18 @@ -8559,7 +8507,7 @@ static void M_ChangecontrolResponse(event_t *ev) { // This buffer assumes a 125-character message plus a 32-character control name (per controltochangetext buffer size) static char tmp[158]; - menu_t *prev = currentMenu->prevMenu; + menutype_t prev = currentMenu->prevMenu; if (controltochange == gc_pause) sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), @@ -8703,7 +8651,7 @@ void M_VideoModeMenu(INT32 choice) vidm_column_size = (vidm_nummodes+2) / 3; - M_SetupNextMenu(&OP_VideoModeDef); + M_SetupNextMenu(MN_OP_VIDEOMODE); } void M_DrawVideoMenu(void) @@ -8761,11 +8709,11 @@ void M_DrawVideoMode(void) // draw title M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y, highlightflags, "Choose mode, reselect to change default"); row = 41; - col = OP_VideoModeDef.y + 14; + col = menudefs[MN_OP_VIDEOMODE]->y + 14; for (i = 0; i < vidm_nummodes; i++) { if (i == vidm_selected) @@ -8778,7 +8726,7 @@ void M_DrawVideoMode(void) if ((i % vidm_column_size) == (vidm_column_size-1)) { row += 7*13; - col = OP_VideoModeDef.y + 14; + col = menudefs[MN_OP_VIDEOMODE]->y + 14; } } @@ -8786,40 +8734,40 @@ void M_DrawVideoMode(void) { INT32 testtime = (vidm_testingmode/TICRATE) + 1; - M_CentreText(OP_VideoModeDef.y + 116, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116, va("Previewing mode %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(OP_VideoModeDef.y + 138, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 138, "Press ENTER again to keep this mode"); - M_CentreText(OP_VideoModeDef.y + 150, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 150, va("Wait %d second%s", testtime, (testtime > 1) ? "s" : "")); - M_CentreText(OP_VideoModeDef.y + 158, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 158, "or press ESC to return"); } else { - M_CentreText(OP_VideoModeDef.y + 116, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116, va("Current mode is %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(OP_VideoModeDef.y + 124, + M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 124, va("Default mode is %c%dx%d", (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, cv_scr_width.value, cv_scr_height.value)); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 138, recommendedflags, "Marked modes are recommended."); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 146, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 146, highlightflags, "Other modes may have visual errors."); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158, + V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 158, highlightflags, "Larger modes may have performance issues."); } // Draw the cursor for the VidMode menu i = 41 - 10 + ((vidm_selected / vidm_column_size)*7*13); - j = OP_VideoModeDef.y + 14 + ((vidm_selected % vidm_column_size)*8); + j = menudefs[MN_OP_VIDEOMODE]->y + 14 + ((vidm_selected % vidm_column_size)*8); V_DrawScaledPatch(i - 8, j, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); @@ -9390,7 +9338,7 @@ void M_DrawDiscordRequests(void) if (currentMenu->prevMenu) { M_SetupNextMenu(currentMenu->prevMenu); - if (currentMenu == &MPauseDef) + if (activeMenuId == MN_MPAUSE) M_SetItemOn(MN_MPAUSE, "CONTIN"); } else diff --git a/src/m_menu.h b/src/m_menu.h index 371778dea..a38ec891c 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -174,7 +174,7 @@ typedef enum #define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c)) #define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d)) -extern menu_t *menunum2menudef[NUMMENUTYPES]; +extern menu_t *menudefs[NUMMENUTYPES]; typedef struct { @@ -347,7 +347,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); typedef union { - menu_t *submenu; // IT_SUBMENU + menutype_t submenu; // IT_SUBMENU consvar_t *cvar; // IT_CVAR void (*routine)(INT32 choice); // IT_CALL, IT_KEYHANDLER, IT_ARROWS void (*eventhandler)(event_t *ev); // MM_EVENTHANDLER @@ -381,7 +381,7 @@ struct menu_t UINT32 menuid; // ID to encode menu type and hierarchy const char *headerpic; INT16 numitems; // # of menu items - menu_t *prevMenu; // previous menu + menutype_t prevMenu; // previous menu menuitem_t *menuitems; // menu items void (*drawroutine)(void); // draw routine INT16 x, y; // x, y of menu @@ -389,7 +389,8 @@ struct menu_t void (*quitroutine)(INT32 choice); // called before quit a menu }; -void M_SetupNextMenu(menu_t *menudef); +void M_SetupNextMenu(menutype_t menu); +void M_SetCurrentMenu(menutype_t menu); void M_ClearMenus(boolean callexitmenufunc); menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name); @@ -519,13 +520,8 @@ boolean M_MouseNeeded(void); extern I_mutex m_menu_mutex; #endif -extern menu_t *currentMenu; - -extern menu_t MainDef; - // Call upon joystick hotplug void M_SetupJoystickMenu(INT32 choice); -extern menu_t OP_JoystickSetDef; // Stuff for customizing the player select screen typedef struct diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 0db299e36..9f29b501e 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1005,7 +1005,7 @@ void I_GetEvent(void) CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); // update the menu - if (currentMenu == &OP_JoystickSetDef) + if (activeMenuId == MN_OP_JOYSTICKSET) M_SetupJoystickMenu(0); for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) @@ -1065,7 +1065,7 @@ void I_GetEvent(void) CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); // update the menu - if (currentMenu == &OP_JoystickSetDef) + if (activeMenuId == MN_OP_JOYSTICKSET) M_SetupJoystickMenu(0); break; case SDL_DROPFILE: From 4933f9642260da44915f7985da1bde9b8239b49a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 22 Mar 2025 20:44:57 +0100 Subject: [PATCH 18/33] Clean up menuitem functions --- src/deh_soc.c | 8 +-- src/m_menu.c | 146 ++++++++++---------------------------------------- src/m_menu.h | 13 +++-- 3 files changed, 39 insertions(+), 128 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index fc32b2a11..ad5049377 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2411,17 +2411,17 @@ void readmenu(MYFILE *f, INT32 num) { if (fastcmp(word, "MENUITEM")) { - if (strlen(word2) > 6) + if (strlen(word2) > ITEMNAMELEN) { - deh_warning("Menu %d: item name %s is too long (max 6 characters)", num, word2); + deh_warning("Menu %d: item name %s is too long (max %d characters)", num, word2, ITEMNAMELEN); continue; } - menuitem_t *item = word2[0] == '.' ? NULL : M_GetMenuItemByName(num, word2); + menuitem_t *item = word2[0] == '.' ? NULL : M_CheckMenuItem(num, word2); if (item == NULL) { menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL); item = menudef->menuitems + menudef->numitems++; - strncpy(item->itemname, word2, 6); + strncpy(item->itemname, word2, ITEMNAMELEN); item->text = ""; } readmenuitem(f, item); diff --git a/src/m_menu.c b/src/m_menu.c index 3f0aea728..99f3dff7d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -227,119 +227,52 @@ static void Newgametype_OnChange(void); static void Dummymenuplayer_OnChange(void); static void Dummystaff_OnChange(void); -// a wide array of functions for interacting with menu items -// should probably trim these a bit... - -static INT16 M_GetMenuIndexByName(menutype_t type, const char *name) +// menus now use short names rather than hardcoded indices to identify menuitems +menuitem_t *M_CheckMenuItem(menutype_t type, const char *name) { INT16 i; menu_t *menu = menudefs[type]; I_Assert(menu); for (i = 0; i < menu->numitems; i++) - if (!strncmp(menu->menuitems[i].itemname, name, 6)) - return i; - return -1; + if (!strncmp(menu->menuitems[i].itemname, name, ITEMNAMELEN)) + return &menu->menuitems[i]; + return NULL; } -menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name) +menuitem_t *M_GetMenuItem(menutype_t type, const char *name) { - INT16 i = M_GetMenuIndexByName(type, name); - return i >= 0 ? &menudefs[type]->menuitems[i] : NULL; -} - -static void M_GetMenuItemNameByIndex(menutype_t type, INT16 index, char out[6]) -{ - menu_t *menu = menudefs[type]; - I_Assert(menu); - strncpy(out, menu->menuitems[index].itemname, 6); -} - -static boolean M_IsItemOn(menutype_t type, const char *name) -{ - INT16 index = M_GetMenuIndexByName(type, name); - if (index < 0) - I_Error("Menu %d has no item %s", type, name); - return itemOn == index; -} - -static void M_SetItemOn(menutype_t type, const char *name) -{ - INT16 index = M_GetMenuIndexByName(type, name); - if (index < 0) - I_Error("Menu %d has no item %s", type, name); - itemOn = index; -} - -static void M_SetItemStatus(menutype_t type, const char *name, UINT16 flags) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); + menuitem_t *item = M_CheckMenuItem(type, name); if (!item) I_Error("Menu %d has no item %s", type, name); - item->status = flags; + return item; } -static UINT16 M_GetItemStatus(menutype_t type, const char *name) +static INT16 M_GetMenuIndex(menutype_t type, const char *name) { - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - return item->status; + return M_GetMenuItem(type, name) - menudefs[type]->menuitems; } -static void M_SetItemRoutine(menutype_t type, const char *name, void (*routine)(INT32 choice)) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - item->itemaction.routine = routine; -} - -static void M_SetItemCvar(menutype_t type, const char *name, consvar_t *cvar) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - item->itemaction.cvar = cvar; -} - -static void M_SetItemKey(menutype_t type, const char *name, UINT16 key) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - item->alphaKey = key; -} +// an array of macros for getting/setting menuitem properties +#define M_IsItemOn(t, n) (itemOn == M_GetMenuIndex(t, n)) +#define M_SetItemOn(t, n) (itemOn = M_GetMenuIndex(t, n)) +#define M_SetItemStatus(t, n, v) (M_GetMenuItem(t, n)->status = v) +#define M_GetItemStatus(t, n) (M_GetMenuItem(t, n)->status) +#define M_SetItemRoutine(t, n, v) (M_GetMenuItem(t, n)->itemaction.routine = v) +#define M_SetItemCvar(t, n, v) (M_GetMenuItem(t, n)->itemaction.cvar = v) +#define M_SetItemKey(t, n, v) (M_GetMenuItem(t, n)->alphaKey = v) #define M_SetItemY M_SetItemKey #define M_SetItemX M_SetItemKey // 2D menus wen - -static UINT16 M_GetItemKey(menutype_t type, const char *name) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - return item->alphaKey; -} +#define M_GetItemKey(t, n) (M_GetMenuItem(t, n)->alphaKey) #define M_GetItemY M_GetItemKey - -static void M_AdjustItemY(menutype_t type, const char *name, INT16 amount) -{ - menuitem_t *item = M_GetMenuItemByName(type, name); - if (!item) - I_Error("Menu %d has no item %s", type, name); - item->alphaKey += amount; -} +#define M_AdjustItemY(t, n, v) (M_GetMenuItem(t, n)->alphaKey += v) // ensure there are numitems menuitems between name1 and name2 // then return the index of name1 static INT16 M_MenuItemRange(menutype_t type, const char *name1, const char *name2, INT16 numitems) { - INT16 index1 = M_GetMenuIndexByName(type, name1); - if (index1 < 0) - I_Error("Menu %d has no item %s", type, name1); - INT16 index2 = M_GetMenuIndexByName(type, name2); - if (index2 < 0) - I_Error("Menu %d has no item %s", type, name2); + INT16 index1 = M_GetMenuIndex(type, name1); + INT16 index2 = M_GetMenuIndex(type, name2); INT16 range = index2 - index1 + 1; if (range != numitems) I_Error("Menu %d should have %d items between %s and %s inclusive, but %d were found", type, numitems, name1, name2, range); @@ -349,7 +282,7 @@ static INT16 M_MenuItemRange(menutype_t type, const char *name1, const char *nam // bruh... static UINT32 M_ServersPerPage(void) { - INT32 spp = M_GetMenuIndexByName(MN_MP_CONNECT, "LASLIN") - M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN") + 1; + INT32 spp = M_GetMenuIndex(MN_MP_CONNECT, "LASLIN") - M_GetMenuIndex(MN_MP_CONNECT, "FIRLIN") + 1; if (spp < 1 || spp >= MAXSERVERLIST) I_Error("Broken server connection menu"); return (UINT32)spp; @@ -4199,8 +4132,6 @@ void M_DrawPlaybackMenu(void) for (i = 0; i < currentMenu->numitems; i++) { UINT8 *inactivemap = NULL; - char nameon[6]; - M_GetMenuItemNameByIndex(MN_PLAYBACK, i, nameon); INT16 splitnum = i - view1index; if (splitnum >= 0 && splitnum < 4) @@ -4227,7 +4158,7 @@ void M_DrawPlaybackMenu(void) else icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp - if ((ITNAMECMP(nameon, "FASTFW") && cv_playbackspeed.value > 1) || (ITNAMECMP(nameon, "REWIND") && demo.rewinding)) + if ((i == M_GetMenuIndex(MN_PLAYBACK, "FASTFW") && cv_playbackspeed.value > 1) || (i == M_GetMenuIndex(MN_PLAYBACK, "REWIND") && demo.rewinding)) V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE)); else V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap); @@ -4243,15 +4174,15 @@ void M_DrawPlaybackMenu(void) { char *str = NULL; - if (!(ITNAMECMP(nameon, "NUMVIE") && r_splitscreen == 3)) + if (!(i == M_GetMenuIndex(MN_PLAYBACK, "NUMVIE") && r_splitscreen == 3)) V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5), '\x1A' | transmap|V_SNAPTOTOP|highlightflags, false); // up arrow - if (!(ITNAMECMP(nameon, "NUMVIE") && r_splitscreen == 0)) + if (!(i == M_GetMenuIndex(MN_PLAYBACK, "NUMVIE") && r_splitscreen == 0)) V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5), '\x1B' | transmap|V_SNAPTOTOP|highlightflags, false); // down arrow - if (ITNAMECMP(nameon, "NUMVIE")) + if (i == M_GetMenuIndex(MN_PLAYBACK, "NUMVIE")) str = va("%d", r_splitscreen+1); else if (splitnum >= 0 && splitnum < 4) str = player_names[displayplayers[splitnum]]; // 0 to 3 @@ -5251,25 +5182,6 @@ void M_SinglePlayerMenu(INT32 choice) M_SetupNextMenu(MN_SP_MAIN); } - -// ============== -/* ignore the garbage, i'm just trying to keep git happy -// ============== - - -{ - - { - } - - - - - - - -}*/ - // =============== // STATISTICS MENU // =============== @@ -6313,7 +6225,7 @@ void M_Connect(INT32 choice) // do not call menuexitfunc M_ClearMenus(false); - INT16 firstserverline = M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN"); + INT16 firstserverline = M_GetMenuIndex(MN_MP_CONNECT, "FIRLIN"); COM_BufAddText(va("connect node %d\n", serverlist[choice-firstserverline + serverlistpage * M_ServersPerPage()].node)); } @@ -6350,7 +6262,7 @@ void M_DrawConnectMenu(void) //const char *gt = "Unknown"; //const char *spd = ""; const char *pwr = "----"; - INT16 firstserverline = M_GetMenuIndexByName(MN_MP_CONNECT, "FIRLIN"); + INT16 firstserverline = M_GetMenuIndex(MN_MP_CONNECT, "FIRLIN"); UINT32 serversperpage = M_ServersPerPage(); // server sperpage? INT32 numPages = (serverlistcount+(serversperpage-1))/serversperpage; int waiting; diff --git a/src/m_menu.h b/src/m_menu.h index a38ec891c..925f2f5e3 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -345,6 +345,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define MAXSTRINGLENGTH 32 +#define ITEMNAMELEN 6 + typedef union { menutype_t submenu; // IT_SUBMENU @@ -358,6 +360,8 @@ typedef union // struct menuitem_t { + char itemname[ITEMNAMELEN]; + // show IT_xxx UINT16 status; @@ -368,14 +372,8 @@ struct menuitem_t // hotkey in menu or y of the item UINT16 alphaKey; - - // an identifier to replace hardcoded indices - char itemname[6]; }; -// so i don't have to put magic numbers everywhere -#define ITNAMECMP(s1, s2) !strncmp(s1, s2, 6) - struct menu_t { UINT32 menuid; // ID to encode menu type and hierarchy @@ -392,7 +390,8 @@ struct menu_t void M_SetupNextMenu(menutype_t menu); void M_SetCurrentMenu(menutype_t menu); void M_ClearMenus(boolean callexitmenufunc); -menuitem_t *M_GetMenuItemByName(menutype_t type, const char *name); +menuitem_t *M_CheckMenuItem(menutype_t type, const char *name); +menuitem_t *M_GetMenuItem(menutype_t type, const char *name); void M_SinglePlayerMenu(INT32 choice); void M_Options(INT32 choice); From a609c7b5ce8466ca807e854927e568b5bea61635 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 23 Mar 2025 01:42:39 +0100 Subject: [PATCH 19/33] Replace prevmenu with menustack menustack[0] replaces both menuactive and activeMenuId Hopefully this is the last major change to the codebase... --- src/console.c | 4 +- src/d_clisrv.c | 2 +- src/d_main.cpp | 2 - src/d_netcmd.c | 2 +- src/deh_soc.c | 16 +- src/dehacked.c | 4 +- src/doomstat.h | 1 - src/f_finale.c | 5 +- src/g_demo.c | 5 +- src/g_game.c | 2 +- src/g_input.c | 5 +- src/lua_script.c | 2 +- src/m_cheat.c | 6 +- src/m_menu.c | 375 ++++++++++++++++++-------------------------- src/m_menu.h | 18 +-- src/m_misc.cpp | 2 +- src/p_user.c | 3 +- src/screen.c | 4 +- src/sdl/i_video.cpp | 8 +- src/st_stuff.c | 2 +- 20 files changed, 184 insertions(+), 284 deletions(-) diff --git a/src/console.c b/src/console.c index 613eb4353..ced99246e 100644 --- a/src/console.c +++ b/src/console.c @@ -254,7 +254,7 @@ static void CONS_Bind_f(void) CONS_Printf("\x82%s", M_GetText("Bind table :\n")); na = 0; for (key = 0; key < NUMINPUTS; key++) - if (!menuactive && bindtable[key]) + if (!menustack[0] && bindtable[key]) { CONS_Printf("%s : \"%s\"\n", G_KeynumToString(key), bindtable[key]); na = 1; @@ -978,7 +978,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (! menuactive && bindtable[key]) + if (!menustack[0] && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9b3eedf7c..c5039f9e0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -575,7 +575,7 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - if (!menuactive) // menu already draws its own fade + if (!menustack[0]) // menu already draws its own fade V_DrawFadeScreen(0xFF00, 16); // force default if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES && cl_mode != CL_CHECKFILES diff --git a/src/d_main.cpp b/src/d_main.cpp index 925fc7366..02f2e9506 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1062,8 +1062,6 @@ void D_StartTitle(void) F_StartTitleScreen(); - M_SetCurrentMenu(MN_MAIN); // reset the current menu ID - // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d08112fe6..01fda96e3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3302,7 +3302,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) if (paused) { - if (!menuactive || netgame) + if (!menustack[0] || netgame) S_PauseAudio(); } else diff --git a/src/deh_soc.c b/src/deh_soc.c index ad5049377..d413e3651 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2154,10 +2154,9 @@ static menu_t *allocmenu(INT32 num) if (menu == NULL) { menudefs[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL); - menu->menuid = num; - } - if (menu->drawroutine == NULL) menu->drawroutine = M_DrawGenericMenu; + } + return menu; } @@ -2576,17 +2575,6 @@ void readmenu(MYFILE *f, INT32 num) { menudef->headerpic = Z_StrDup(word2); } - else if (fastcmp(word, "PREVMENU")) - { - value = get_menutype(word2); - if (value == MN_NONE) - { - deh_warning("Menu %d: unknown previous menu '%s'", num, word2); - continue; - } - allocmenu(value); - menudef->prevMenu = value; - } else if (fastcmp(word, "DRAWROUTINE")) { void (*drawer)(void) = get_menudrawer(word2); diff --git a/src/dehacked.c b/src/dehacked.c index 0b00454d8..59c88267a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -659,13 +659,13 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { if (introchanged) { - menuactive = false; + M_ClearMenus(true); I_UpdateMouseGrab(); COM_BufAddText("playintro"); } else if (titlechanged) { - menuactive = false; + M_ClearMenus(true); I_UpdateMouseGrab(); COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed } diff --git a/src/doomstat.h b/src/doomstat.h index 77c954a25..55d5837e2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -172,7 +172,6 @@ extern boolean digital_disabled; // ========================= // -extern boolean menuactive; // Menu overlaid? extern UINT8 paused; // Game paused? extern UINT8 window_notinfocus; // are we in focus? (backend independant -- handles auto pausing and display of "focus lost" message) extern INT32 window_x; diff --git a/src/f_finale.c b/src/f_finale.c index dd2009d27..683b5c9cb 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1168,8 +1168,7 @@ void F_GameEndTicker(void) void F_InitMenuPresValues(void) { menuanimtimer = 0; - prevMenuId = 0; - activeMenuId = MN_MAIN; + M_ClearMenus(false); // TODO maybe call exit funcs here? but that triggers an infinite loop in replay hut... // Set defaults for presentation values strncpy(curbgname, "TITLESKY", 9); @@ -1611,7 +1610,7 @@ void F_TitleScreenTicker(boolean run) } // Hold up for a bit if menu or console active - if (menuactive || CON_Ready()) + if (menustack[0] || CON_Ready()) { demoIdleLeft = demoIdleTime; return; diff --git a/src/g_demo.c b/src/g_demo.c index e0301e14d..dc326811d 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1651,13 +1651,11 @@ void G_ConfirmRewind(tic_t rewindtime) { SINT8 i; tic_t j; - boolean oldmenuactive = menuactive, oldsounddisabled = sound_disabled; + boolean oldsounddisabled = sound_disabled; INT32 olddp1 = displayplayers[0], olddp2 = displayplayers[1], olddp3 = displayplayers[2], olddp4 = displayplayers[3]; UINT8 oldss = splitscreen; - menuactive = false; // Prevent loops - CV_StealthSetValue(&cv_renderview, 0); if (rewindtime <= starttime) @@ -1693,7 +1691,6 @@ void G_ConfirmRewind(tic_t rewindtime) } demo.rewinding = false; - menuactive = oldmenuactive; // Bring the menu back up sound_disabled = oldsounddisabled; // Re-enable SFX wipegamestate = gamestate; // No fading back in! diff --git a/src/g_game.c b/src/g_game.c index 3f119241a..2edfb01e2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1609,7 +1609,7 @@ boolean G_Responder(event_t *ev) if (modeattacking && !demo.playback && (gamestate == GS_LEVEL)) { pausebreakkey = (ev->data1 == KEY_PAUSE); - if (menuactive || pausedelay < 0 || leveltime < 2) + if (menustack[0] || pausedelay < 0 || leveltime < 2) return true; if (pausedelay < 1+(NEWTICRATE/2)) diff --git a/src/g_input.c b/src/g_input.c index 459571a22..fcbddaa49 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -19,6 +19,7 @@ #include "d_net.h" #include "console.h" #include "i_joy.h" // JOYAXISRANGE +#include "m_menu.h" // menustack #define MAXMOUSESENSITIVITY 100 // sensitivity steps @@ -176,7 +177,7 @@ void G_MapEventsToControls(event_t *ev) break; case ev_mouse: // buttons are virtual keys - if (menuactive) + if (menustack[0]) { break; } @@ -211,7 +212,7 @@ void G_MapEventsToControls(event_t *ev) break; case ev_joystick: // buttons are virtual keys - if (menuactive) + if (menustack[0]) { break; } diff --git a/src/lua_script.c b/src/lua_script.c index f203d765c..fc5520665 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -196,7 +196,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) lua_pushboolean(L, modifiedgame && !savemoddata); return 1; } else if (fastcmp(word,"menuactive")) { - lua_pushboolean(L, menuactive); + lua_pushboolean(L, menustack[0]); return 1; } else if (fastcmp(word,"paused")) { lua_pushboolean(L, paused); diff --git a/src/m_cheat.c b/src/m_cheat.c index eecee10fe..dd633cf9e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -62,7 +62,7 @@ typedef struct // Cheat responders /*static UINT8 cheatf_ultimate(void) { - if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef)) + if (menustack[0] != MN_MAIN && menustack[0] != MN_SP_LOAD)) return 0; // Only on the main menu, or the save select! BwehHehHe(); @@ -82,7 +82,7 @@ static UINT8 cheatf_warp(void) /*if (modifiedgame) * return 0;*/ - if (menuactive && activeMenuId != MN_MAIN) + if (menustack[0] != MN_MAIN) return 0; // Only on the main menu! // Temporarily unlock EVERYTHING. @@ -117,7 +117,7 @@ static UINT8 cheatf_devmode(void) if (modifiedgame) return 0; - if (menuactive && activeMenuId != MN_MAIN) + if (menustack[0] != MN_MAIN) return 0; // Only on the main menu! S_StartSound(0, sfx_itemup); diff --git a/src/m_menu.c b/src/m_menu.c index 99f3dff7d..2ee97fe65 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -147,7 +147,6 @@ const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 description_t description[MAXSKINS]; -boolean menuactive = false; boolean fromlevelselect = false; typedef enum @@ -168,6 +167,7 @@ static UINT32 serverlistpage; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? menu_t *menudefs[NUMMENUTYPES] = {NULL}; // pointers to all menudefs +menutype_t menustack[NUMMENULEVELS]; // stack of active menus, [0] == current menu static menu_t *currentMenu; // current menudef static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 skullAnimCounter = 10; // skull animation counter @@ -288,14 +288,6 @@ static UINT32 M_ServersPerPage(void) return (UINT32)spp; } -// set the current menu, but without doing everything that M_SetupNextMenu does -// is this even necessary...? -void M_SetCurrentMenu(menutype_t num) -{ - currentMenu = menudefs[num]; - activeMenuId = num; -} - // ========================================================================== // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== @@ -486,7 +478,7 @@ void M_OpenGLOptionsMenu(INT32 choice) (void)choice; if (rendermode == render_opengl) - M_SetupNextMenu(MN_OP_OPENGL); + M_EnterMenu(MN_OP_OPENGL, true); else M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING); } @@ -537,7 +529,7 @@ void Nextmap_OnChange(void) leveltitle = cv_nextmap.value ? G_BuildMapTitle(cv_nextmap.value) : Z_StrDup("Random"); cv_nextmap.string = cv_nextmap.zstring = leveltitle; - if (activeMenuId == MN_SP_TIMEATTACK) + if (menustack[0] == MN_SP_TIMEATTACK) { // see also p_setup.c's P_LoadRecordGhosts const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; @@ -666,7 +658,7 @@ static void Dummystaff_OnChange(void) // Newgametype. Used for gametype changes. static void Newgametype_OnChange(void) { - if (menuactive && cv_nextmap.value) + if (menustack[0] && cv_nextmap.value) { INT32 gt = cv_newgametype.value; @@ -727,10 +719,6 @@ void Moviemode_option_Onchange(void) // MENU PRESENTATION PARAMETER HANDLING (BACKGROUNDS) // ========================================================================= -// menu IDs are equal to current/prevMenu in most cases, except MN_SPECIAL when we don't want to operate on Message, Pause, etc. -UINT32 prevMenuId = 0; -UINT32 activeMenuId = 0; - menupres_t menupres[NUMMENUTYPES]; void M_InitMenuPresTables(void) @@ -971,7 +959,7 @@ boolean M_Responder(event_t *ev) break; } } - else if (menuactive) + else if (menustack[0]) { if (ev->type == ev_joystick && deviceplayer == 0) { @@ -1053,7 +1041,7 @@ boolean M_Responder(event_t *ev) for (size_t r = 0; r < sizeof(joyremap)/sizeof(*joyremap); r++) { INT32 gc = joyremap[r][0]; - if (gc == gc_brake && !menuactive) + if (gc == gc_brake && !menustack[0]) continue; // don't open the menu with brake! if (G_ControlBoundToKey(0, gc, ch, true)) @@ -1068,7 +1056,7 @@ boolean M_Responder(event_t *ev) return false; // F-Keys - if (!menuactive) + if (!menustack[0]) { noFurtherInput = true; @@ -1090,7 +1078,7 @@ boolean M_Responder(event_t *ev) return true; M_StartControlPanel(); M_Options(0); - M_SetCurrentMenu(MN_OP_SOUND); + M_EnterMenu(MN_OP_SOUND, true); itemOn = 0; return true; @@ -1100,6 +1088,7 @@ boolean M_Responder(event_t *ev) return true; M_StartControlPanel(); M_Options(0); + M_EnterMenu(MN_OP_VIDEO, true); M_VideoModeMenu(0); return true; #endif @@ -1112,7 +1101,6 @@ boolean M_Responder(event_t *ev) return true; M_StartControlPanel(); M_Options(0); - M_SetupNextMenu(MN_OP_MAIN); return true; // Screenshots on F8 now handled elsewhere @@ -1200,7 +1188,7 @@ boolean M_Responder(event_t *ev) routine = M_ChangeCvar; } - if (activeMenuId == MN_PLAYBACK && !con_destlines) + if (menustack[0] == MN_PLAYBACK && !con_destlines) { playback_last_menu_interaction_leveltime = leveltime; // Flip left/right with up/down for the playback menu, since it's a horizontal icon row. @@ -1281,7 +1269,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (activeMenuId != MN_OP_SOUND || itemOn > 3) + if (menustack[0] != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(0); } @@ -1291,7 +1279,7 @@ boolean M_Responder(event_t *ev) if (routine && ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_ARROWS || (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)) { - if (activeMenuId != MN_OP_SOUND || itemOn > 3) + if (menustack[0] != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(1); } @@ -1301,7 +1289,7 @@ boolean M_Responder(event_t *ev) noFurtherInput = true; currentMenu->lastOn = itemOn; - if (activeMenuId == MN_PLAYBACK) + if (menustack[0] == MN_PLAYBACK) { boolean held = (boolean)playback_enterheld; if (held) @@ -1323,7 +1311,7 @@ boolean M_Responder(event_t *ev) break; case IT_SUBMENU: currentMenu->lastOn = itemOn; - M_SetupNextMenu(currentMenu->menuitems[itemOn].itemaction.submenu); + M_EnterMenu(currentMenu->menuitems[itemOn].itemaction.submenu, true); break; } } @@ -1333,7 +1321,12 @@ boolean M_Responder(event_t *ev) //case KEY_JOY1 + 2: noFurtherInput = true; currentMenu->lastOn = itemOn; - if (currentMenu->prevMenu) + if (menustack[0] == MN_SP_TIMEATTACK) + { + // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. + D_StartTitle(); + } + else { //If we entered the game search menu, but didn't enter a game, //make sure the game doesn't still think we're in a netgame. @@ -1342,18 +1335,8 @@ boolean M_Responder(event_t *ev) netgame = false; multiplayer = false; } - - if (activeMenuId == MN_SP_TIMEATTACK) - { - // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - menuactive = false; - D_StartTitle(); - } - else - M_SetupNextMenu(currentMenu->prevMenu); + M_ExitMenu(); } - else - M_ClearMenus(true); return true; @@ -1377,7 +1360,7 @@ boolean M_Responder(event_t *ev) || cv == &cv_newgametype) return true; - if (activeMenuId != MN_OP_SOUND || itemOn > 3) + if (menustack[0] != MN_OP_SOUND || itemOn > 3) S_StartSound(NULL, sfx_menu1); routine(-1); return true; @@ -1491,13 +1474,10 @@ boolean M_DemoResponder(event_t *ev) // void M_Drawer(void) { - if (currentMenu == &MessageDef) - menuactive = true; - - if (menuactive) + if (menustack[0]) { // now that's more readable with a faded background (yeah like Quake...) - if (!WipeInAction && activeMenuId != MN_PLAYBACK) // Replay playback has its own background + if (!WipeInAction && menustack[0] != MN_PLAYBACK) // Replay playback has its own background V_DrawFadeScreen(0xFF00, 16); if (currentMenu->drawroutine) @@ -1506,7 +1486,7 @@ void M_Drawer(void) currentMenu->drawroutine(); // call current menu Draw routine } - if (activeMenuId == MN_MAIN) + if (menustack[0] == MN_MAIN) { INT32 texty = vid.height - 10*vid.dupy; #define addtext(f, str) {\ @@ -1552,27 +1532,25 @@ void M_Drawer(void) void M_StartControlPanel(void) { // intro might call this repeatedly - if (menuactive) + if (menustack[0]) { CON_ToggleOff(); // move away console return; } - menuactive = true; - if (demo.playback) { - M_SetCurrentMenu(MN_PLAYBACK); + M_EnterMenu(MN_PLAYBACK, true); playback_last_menu_interaction_leveltime = leveltime; } else if (!Playing()) { - M_SetCurrentMenu(MN_MAIN); + M_EnterMenu(MN_MAIN, true); M_SetItemOn(MN_MAIN, "SINGLE"); } else if (modeattacking) { - M_SetCurrentMenu(MN_MAPAUSE); + M_EnterMenu(MN_MAPAUSE, true); M_SetItemOn(MN_MAPAUSE, "CONTIN"); } else if (!(netgame || multiplayer)) // Single Player @@ -1590,7 +1568,7 @@ void M_StartControlPanel(void) M_SetItemStatus(MN_SPAUSE, "EMBLEM", M_SecretUnlocked(SECRET_EMBLEMHINTS) ? IT_STRING|IT_CALL : IT_DISABLED); - M_SetCurrentMenu(MN_SPAUSE); + M_EnterMenu(MN_SPAUSE, true); M_SetItemOn(MN_SPAUSE, "CONTIN"); } else // multiplayer @@ -1704,7 +1682,7 @@ void M_StartControlPanel(void) } #endif - M_SetCurrentMenu(MN_MPAUSE); + M_EnterMenu(MN_MPAUSE, true); M_SetItemOn(MN_MPAUSE, "CONTIN"); } @@ -1721,36 +1699,33 @@ void M_EndModeAttackRun(void) // void M_ClearMenus(boolean callexitmenufunc) { - if (!menuactive) - return; - - if (currentMenu->quitroutine && callexitmenufunc) + if (currentMenu && currentMenu->quitroutine && callexitmenufunc) currentMenu->quitroutine(0); #ifndef DC // Save the config file. I'm sick of crashing the game later and losing all my changes! - COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile)); + if (menustack[0]) + COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile)); #endif //Alam: But not on the Dreamcast's VMUs - if (currentMenu == &MessageDef) // Oh sod off! - M_SetCurrentMenu(MN_MAIN); // Not like it matters - menuactive = false; + memset(menustack, 0, sizeof(menustack)); + currentMenu = NULL; hidetitlemap = false; } // // M_SetupNextMenu // -void M_SetupNextMenu(menutype_t menunum) +static void M_SetupNextMenu(menutype_t menunum, boolean callexit) { INT16 i; menu_t *menudef = menudefs[menunum]; + I_Assert(menudef); // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH - if (currentMenu != menudef && currentMenu->quitroutine) + if (callexit && currentMenu && currentMenu != menudef && currentMenu->quitroutine) currentMenu->quitroutine(0); currentMenu = menudef; - activeMenuId = menunum; itemOn = currentMenu->lastOn; // in case of... @@ -1774,6 +1749,34 @@ void M_SetupNextMenu(menutype_t menunum) hidetitlemap = false; } +// pop the active menu from the stack +void M_ExitMenu(void) +{ + size_t i; + + for (i = 0; i < NUMMENULEVELS-1; i++) + menustack[i] = menustack[i+1]; + menustack[NUMMENULEVELS-1] = MN_NONE; + + if (menustack[0]) + M_SetupNextMenu(menustack[0], true); + else + M_ClearMenus(true); +} + +// push a new menu to the stack +void M_EnterMenu(menutype_t menunum, boolean callexit) +{ + size_t i = NUMMENULEVELS-1; + if (menustack[i]) + CONS_Alert(CONS_WARNING, "Max menu depth (%d) exceeded!\n", NUMMENULEVELS); + + do menustack[i] = menustack[i-1]; while (--i); // one-line do-while loop... that's something :^) + menustack[0] = menunum; + + M_SetupNextMenu(menunum, callexit); +} + // Guess I'll put this here, idk boolean M_MouseNeeded(void) { @@ -1796,7 +1799,7 @@ void M_Ticker(void) followertimer++; - if (activeMenuId == MN_PLAYBACK) + if (menustack[0] == MN_PLAYBACK) { if (playback_enterheld > 0) playback_enterheld--; @@ -2276,7 +2279,7 @@ void M_DrawPauseMenu(void) { #ifdef HAVE_DISCORDRPC // kind of hackily baked in here - if (activeMenuId == MN_MPAUSE && discordRequestList != NULL) + if (menustack[0] == MN_MPAUSE && discordRequestList != NULL) { const tic_t freq = TICRATE/2; @@ -2648,10 +2651,8 @@ static menuitem_t MessageMenu[] = {0}; menu_t MessageDef = { - MN_NONE, // id NULL, // title 1, // # of menu items - MN_NONE, // previous menu (TO HACK) MessageMenu, // menuitem_t -> M_DrawMessageMenu, // drawing routine -> 0, 0, // x, y (TO HACK) @@ -2704,11 +2705,6 @@ void M_StartMessage(const char *string, void *routine, M_StartControlPanel(); // can't put menuactive to true - if (currentMenu == &MessageDef) // Prevent recursion - MessageDef.prevMenu = demo.playback ? MN_PLAYBACK : MN_MAIN; - else - MessageDef.prevMenu = activeMenuId; - MessageDef.menuitems[0].text = message; MessageDef.menuitems[0].alphaKey = (UINT8)itemtype; if (!routine && itemtype != MM_NOTHING) itemtype = MM_NOTHING; @@ -2753,9 +2749,7 @@ void M_StartMessage(const char *string, void *routine, MessageDef.lastOn = (INT16)((strlines<<8)+max); - //M_SetupNextMenu(); currentMenu = &MessageDef; - activeMenuId = MN_NONE; itemOn = 0; } @@ -2828,8 +2822,10 @@ static void M_DrawMessageMenu(void) static void M_StopMessage(INT32 choice) { (void)choice; - if (menuactive) - M_SetupNextMenu(MessageDef.prevMenu); + if (menustack[0]) + M_SetupNextMenu(menustack[0], true); + else + M_ClearMenus(true); } // ========= @@ -2895,12 +2891,7 @@ void M_HandleImageDef(INT32 choice) } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // ====================== @@ -2912,7 +2903,7 @@ void M_AddonsOptions(INT32 choice) (void)choice; Addons_option_Onchange(); - M_SetupNextMenu(MN_OP_ADDONS); + M_EnterMenu(MN_OP_ADDONS, true); } #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!" @@ -2980,8 +2971,7 @@ void M_Addons(INT32 choice) addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); - menudefs[MN_AD_MAIN]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_AD_MAIN); + M_EnterMenu(MN_AD_MAIN, true); } #define width 4 @@ -3051,7 +3041,7 @@ static char *M_AddonsHeaderPath(void) } #define UNEXIST S_StartSound(NULL, sfx_s26d);\ - M_SetupNextMenu(menudefs[MN_AD_MAIN]->prevMenu);\ + M_ExitMenu();\ M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING) #define CLEARNAME Z_Free(refreshdirname);\ @@ -3448,10 +3438,7 @@ void M_HandleAddons(INT32 choice) // Secret menu! //MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); + M_ExitMenu(); } } @@ -3514,8 +3501,8 @@ void M_ReplayHut(INT32 choice) PrepReplayList(); - menuactive = true; - M_SetupNextMenu(MN_MISC_REPLAYHUT); + M_ClearMenus(true); + M_EnterMenu(MN_MISC_REPLAYHUT, true); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -3602,9 +3589,8 @@ void M_HandleReplayHutList(INT32 choice) PrepReplayList(); break; default: - // We can't just use M_SetupNextMenu because that'll run ReplayDef's quitroutine and boot us back to the title screen! currentMenu->lastOn = itemOn; - M_SetCurrentMenu(MN_MISC_REPLAYSTART); + M_EnterMenu(MN_MISC_REPLAYSTART, false); // ReplayDef's quit routine would boot us back to the title screen replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; @@ -4025,7 +4011,6 @@ void M_QuitReplayHut(INT32 choice) (void)choice; // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - menuactive = false; D_StartTitle(); if (demolist) @@ -4335,7 +4320,7 @@ void M_PandorasBox(INT32 choice) (void)choice; CV_StealthSetValue(&cv_dummyrings, players[consoleplayer].rings); CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); - M_SetupNextMenu(MN_SR_PANDORA); + M_EnterMenu(MN_SR_PANDORA, true); } void M_ExitPandorasBox(INT32 choice) @@ -4464,16 +4449,13 @@ void M_Options(INT32 choice) M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET); - menudefs[MN_OP_MAIN]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_OP_MAIN); + M_EnterMenu(MN_OP_MAIN, true); } void M_Manual(INT32 choice) { (void)choice; - - menudefs[MN_HELP]->prevMenu = choice == INT32_MAX ? MN_NONE : activeMenuId; - M_SetupNextMenu(MN_HELP); + M_EnterMenu(MN_HELP, true); } static void M_RetryResponse(INT32 ch) @@ -4669,7 +4651,7 @@ void M_EmblemHints(INT32 choice) { (void)choice; M_SetItemStatus(MN_SR_EMBLEMHINT, "RADAR", M_SecretUnlocked(SECRET_ITEMFINDER) ? IT_CVAR|IT_STRING : IT_SECRET); - M_SetupNextMenu(MN_SR_EMBLEMHINT); + M_EnterMenu(MN_SR_EMBLEMHINT, true); M_SetItemOn(MN_SR_EMBLEMHINT, "BACK"); // always start on back. } @@ -4728,7 +4710,7 @@ void M_DrawSkyRoom(void) M_DrawGenericMenu(); - if (activeMenuId == MN_OP_SOUND) + if (menustack[0] == MN_OP_SOUND) { V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+M_GetItemY(MN_OP_SOUND, "SNDENA"), @@ -4810,12 +4792,7 @@ void M_HandleSoundTest(INT32 choice) break; } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } static musicdef_t *curplaying = NULL; @@ -4842,7 +4819,7 @@ void M_MusicTest(INT32 choice) st_sel = 0; - M_SetupNextMenu(MN_SR_SOUNDTEST); + M_EnterMenu(MN_SR_SOUNDTEST, true); } void M_DrawMusicTest(void) @@ -5142,10 +5119,7 @@ void M_HandleMusicTest(INT32 choice) Z_Free(soundtestdefs); soundtestdefs = NULL; - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); + M_ExitMenu(); } } @@ -5179,7 +5153,7 @@ void M_SinglePlayerMenu(INT32 choice) M_SetItemStatus(MN_SP_MAIN, "GP", IT_CALL|IT_STRING); M_SetItemStatus(MN_SP_MAIN, "TA", M_SecretUnlocked(SECRET_TIMEATTACK) ? IT_CALL|IT_STRING : IT_SECRET); M_SetItemStatus(MN_SP_MAIN, "IT", M_SecretUnlocked(SECRET_ITEMBREAKER) ? IT_CALL|IT_STRING : IT_SECRET); - M_SetupNextMenu(MN_SP_MAIN); + M_EnterMenu(MN_SP_MAIN, true); } // =============== @@ -5243,7 +5217,7 @@ void M_Statistics(INT32 choice) if (statsMax < 0) statsMax = 0; - M_SetupNextMenu(MN_SP_LEVELSTATS); + M_EnterMenu(MN_SP_LEVELSTATS, true); } static void M_DrawStatsMaps(void) @@ -5504,12 +5478,7 @@ void M_HandleLevelStats(INT32 choice) break; } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } void M_GrandPrixTemp(INT32 choice) @@ -5521,7 +5490,7 @@ void M_GrandPrixTemp(INT32 choice) return; } M_PatchSkinNameTable(); - M_SetupNextMenu(MN_SP_GRANDPRIX); + M_EnterMenu(MN_SP_GRANDPRIX, true); } // Start Grand Prix! @@ -5606,7 +5575,7 @@ void M_DrawTimeAttackMenu(void) V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); M_DrawMenuTitle(); - if (activeMenuId == MN_SP_TIMEATTACK) + if (menustack[0] == MN_SP_TIMEATTACK) M_DrawLevelSelectOnly(true, false); // draw menu (everything else goes on top of it) @@ -5649,7 +5618,7 @@ void M_DrawTimeAttackMenu(void) INT32 soffset = 40, strw = V_StringWidth(str, 0); // hack to keep the menu from overlapping the level icon - if (activeMenuId != MN_SP_TIMEATTACK || cv == &cv_nextmap) + if (menustack[0] != MN_SP_TIMEATTACK || cv == &cv_nextmap) soffset = 0; // Should see nothing but strings @@ -5711,7 +5680,7 @@ void M_DrawTimeAttackMenu(void) // ALWAYS DRAW player name, level name, skin and color even when not on this menu! // TODO: this whole thing needs to go menu_t *tamenu = menudefs[MN_SP_TIMEATTACK]; - if (activeMenuId != MN_SP_TIMEATTACK) + if (menustack[0] != MN_SP_TIMEATTACK) { consvar_t *ncv; INT16 first = M_MenuItemRange(MN_SP_TIMEATTACK, "NAME", "LEVEL", 4); @@ -5761,7 +5730,8 @@ void M_TimeAttack(INT32 choice) M_PatchSkinNameTable(); M_PrepareLevelSelect(); - M_SetupNextMenu(MN_SP_TIMEATTACK); + M_ClearMenus(true); + M_EnterMenu(MN_SP_TIMEATTACK, true); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -5794,7 +5764,8 @@ void M_ItemBreaker(INT32 choice) M_PatchSkinNameTable(); M_PrepareLevelSelect(); - M_SetupNextMenu(MN_SP_TIMEATTACK); + M_ClearMenus(true); + M_EnterMenu(MN_SP_TIMEATTACK, true); G_SetGamestate(GS_TIMEATTACK); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -5883,12 +5854,7 @@ void M_HandleStaffReplay(INT32 choice) break; } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // Player has selected the "REPLAY" from the time attack screen @@ -5900,27 +5866,24 @@ void M_ReplayTimeAttack(INT32 choice) modeattacking = (levellistmode == LLM_ITEMBREAKER ? ATTACKING_ITEMBREAK : ATTACKING_TIME); // set modeattacking before G_DoPlayDemo so the map loader knows demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed - if (activeMenuId == MN_SP_REPLAY) - { - switch(choice) { - default: - case 0: // best time - which = "time-best"; - break; - case 1: // best lap - which = "lap-best"; - break; - case 2: // last - which = "last"; - break; - case 3: // guest - // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode)); - return; - } - // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, gamemode, which)); + switch(choice) { + default: + case 0: // best time + which = "time-best"; + break; + case 1: // best lap + which = "lap-best"; + break; + case 2: // last + which = "last"; + break; + case 3: // guest + // srb2/replay/main/map01-guest.lmp + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode)); + return; } + // srb2/replay/main/map01-sonic-time-best.lmp + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, gamemode, which)); } static void M_EraseGuest(INT32 choice) @@ -5930,7 +5893,7 @@ static void M_EraseGuest(INT32 choice) (void)choice; if (FIL_FileExists(rguest)) remove(rguest); - M_SetupNextMenu(MN_SP_TIMEATTACK); + M_ExitMenu(); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); @@ -5952,7 +5915,7 @@ static void M_OverwriteGuest(const char *which) } FIL_WriteFile(rguest, buf, len); Z_Free(rguest); - M_SetupNextMenu(MN_SP_TIMEATTACK); + M_ExitMenu(); CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, 1); M_StartMessage(M_GetText("Guest replay data saved.\n"),NULL,MM_NOTHING); @@ -6020,9 +5983,11 @@ void M_ModeAttackEndGame(INT32 choice) M_StartControlPanel(); if (modeattacking) - M_SetCurrentMenu(MN_SP_TIMEATTACK); + { + M_ClearMenus(true); + M_EnterMenu(MN_SP_TIMEATTACK, true); + } - itemOn = currentMenu->lastOn; G_SetGamestate(GS_TIMEATTACK); modeattacking = ATTACKING_NONE; S_ChangeMusicInternal("racent", true); @@ -6212,12 +6177,7 @@ void M_HandleServerPage(INT32 choice) break; } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } void M_Connect(INT32 choice) @@ -6473,7 +6433,7 @@ static void M_ConnectMenu(INT32 choice) // first page of servers serverlistpage = 0; - M_SetupNextMenu(MN_MP_CONNECT); + M_EnterMenu(MN_MP_CONNECT, true); itemOn = 0; #if defined (MASTERSERVER) && defined (HAVE_THREADS) @@ -6555,7 +6515,7 @@ void M_StartServer(INT32 choice) (void)choice; - if (activeMenuId == MN_MP_OFFLINESERVER) + if (menustack[0] == MN_MP_OFFLINESERVER) netgame = false; else netgame = true; @@ -6584,7 +6544,7 @@ void M_StartServer(INT32 choice) SplitScreen_OnChange(); } - if (activeMenuId == MN_MP_OFFLINESERVER) // offline server + if (menustack[0] == MN_MP_OFFLINESERVER) // offline server { paused = false; SV_StartSinglePlayerServer(); @@ -6713,7 +6673,7 @@ void M_MapChange(INT32 choice) CV_SetValue(&cv_nextmap, gamemap); M_PrepareLevelSelect(); - M_SetupNextMenu(MN_CHANGELEVEL); + M_EnterMenu(MN_CHANGELEVEL, true); } void M_StartOfflineServerMenu(INT32 choice) @@ -6721,7 +6681,7 @@ void M_StartOfflineServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - M_SetupNextMenu(MN_MP_OFFLINESERVER); + M_EnterMenu(MN_MP_OFFLINESERVER, true); } void M_StartServerMenu(INT32 choice) @@ -6729,8 +6689,7 @@ void M_StartServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - M_SetupNextMenu(MN_MP_SERVER); - + M_EnterMenu(MN_MP_SERVER, true); } // ============== @@ -6887,12 +6846,7 @@ void M_SetupMultiHandler(INT32 choice) } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu (currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // Tails 11-19-2002 @@ -6987,12 +6941,7 @@ void M_HandleConnectIP(INT32 choice) } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu (currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // ======================== @@ -7515,12 +7464,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu (currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // start the multiplayer setup menu @@ -7564,8 +7508,7 @@ void M_SetupMultiPlayer(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER|IT_STRING); - menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_MP_PLAYERSETUP); + M_EnterMenu(MN_MP_PLAYERSETUP, true); } // start the multiplayer setup menu, for secondary player (splitscreen mode) @@ -7608,8 +7551,7 @@ void M_SetupMultiPlayer2(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_MP_PLAYERSETUP); + M_EnterMenu(MN_MP_PLAYERSETUP, true); } // start the multiplayer setup menu, for third player (splitscreen mode) @@ -7652,8 +7594,7 @@ void M_SetupMultiPlayer3(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_MP_PLAYERSETUP); + M_EnterMenu(MN_MP_PLAYERSETUP, true); } // start the multiplayer setup menu, for third player (splitscreen mode) @@ -7696,8 +7637,7 @@ void M_SetupMultiPlayer4(INT32 choice) else M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); - menudefs[MN_MP_PLAYERSETUP]->prevMenu = activeMenuId; - M_SetupNextMenu(MN_MP_PLAYERSETUP); + M_EnterMenu(MN_MP_PLAYERSETUP, true); } void M_QuitMultiPlayerMenu(INT32 choice) @@ -7946,7 +7886,7 @@ void M_ScreenshotOptions(INT32 choice) Screenshot_option_Onchange(); Moviemode_mode_Onchange(); - M_SetupNextMenu(MN_OP_SCREENSHOTS); + M_EnterMenu(MN_OP_SCREENSHOTS, true); } // ============= @@ -8014,7 +7954,7 @@ void M_SetupJoystickMenu(INT32 choice) #endif } - M_SetupNextMenu(MN_OP_JOYSTICKSET); + M_EnterMenu(MN_OP_JOYSTICKSET, true); } void M_Setup1PJoystickMenu(INT32 choice) @@ -8115,7 +8055,7 @@ void M_Setup1PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_CONTROL); // Center View */ - M_SetupNextMenu(MN_OP_CHANGECONTROLS); + M_EnterMenu(MN_OP_CHANGECONTROLS, true); } void M_Setup2PControlsMenu(INT32 choice) @@ -8148,7 +8088,7 @@ void M_Setup2PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(MN_OP_CHANGECONTROLS); + M_EnterMenu(MN_OP_CHANGECONTROLS, true); } void M_Setup3PControlsMenu(INT32 choice) @@ -8181,7 +8121,7 @@ void M_Setup3PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(MN_OP_CHANGECONTROLS); + M_EnterMenu(MN_OP_CHANGECONTROLS, true); } void M_Setup4PControlsMenu(INT32 choice) @@ -8214,7 +8154,7 @@ void M_Setup4PControlsMenu(INT32 choice) M_SetItemStatus(MN_OP_CHANGECONTROLS, "CENTER", IT_GRAYEDOUT2); // Center View */ - M_SetupNextMenu(MN_OP_CHANGECONTROLS); + M_EnterMenu(MN_OP_CHANGECONTROLS, true); } #define controlheight 18 @@ -8419,7 +8359,6 @@ static void M_ChangecontrolResponse(event_t *ev) { // This buffer assumes a 125-character message plus a 32-character control name (per controltochangetext buffer size) static char tmp[158]; - menutype_t prev = currentMenu->prevMenu; if (controltochange == gc_pause) sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), @@ -8429,7 +8368,6 @@ static void M_ChangecontrolResponse(event_t *ev) controltochangetext); M_StartMessage(tmp, FUNCPTRCAST(M_ChangecontrolResponse), MM_EVENTHANDLER); - currentMenu->prevMenu = prev; S_StartSound(NULL, sfx_s3k42); return; @@ -8563,7 +8501,7 @@ void M_VideoModeMenu(INT32 choice) vidm_column_size = (vidm_nummodes+2) / 3; - M_SetupNextMenu(MN_OP_VIDEOMODE); + M_EnterMenu(MN_OP_VIDEOMODE, true); } void M_DrawVideoMenu(void) @@ -8747,10 +8685,7 @@ void M_HandleVideoMode(INT32 ch) break; case KEY_ESCAPE: // this one same as M_Responder - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); + M_ExitMenu(); break; default: @@ -9025,12 +8960,7 @@ void M_HandleMonitorToggles(INT32 choice) } if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } + M_ExitMenu(); } // ========= @@ -9247,14 +9177,9 @@ void M_DrawDiscordRequests(void) // No other requests M_SetItemStatus(MN_MPAUSE, "DISCRQ", IT_GRAYEDOUT); - if (currentMenu->prevMenu) - { - M_SetupNextMenu(currentMenu->prevMenu); - if (activeMenuId == MN_MPAUSE) - M_SetItemOn(MN_MPAUSE, "CONTIN"); - } - else - M_ClearMenus(true); + M_ExitMenu(); + if (menustack[0] == MN_MPAUSE) + M_SetItemOn(MN_MPAUSE, "CONTIN"); return; } diff --git a/src/m_menu.h b/src/m_menu.h index 925f2f5e3..0d6abe086 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -34,10 +34,8 @@ extern "C" { // MENUS // -// If menu hierarchies go deeper, change this up to 5. -// Zero-based, inclusive. -#define NUMMENULEVELS 3 -#define MENUBITS 6 +// max size of menu stack +#define NUMMENULEVELS 8 // Menu IDs sectioned by numeric places to signify hierarchy /** @@ -170,11 +168,9 @@ typedef enum NUMMENUTYPES, } menutype_t; // up to 63 #define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT) -#define MTREE2(a,b) (a | (b<data1; - if (ch >= NUMKEYS && menuactive) // If it's not a keyboard key, then don't allow it in the menus! + if (ch >= NUMKEYS && menustack[0]) // If it's not a keyboard key, then don't allow it in the menus! return false; if (G_ControlBoundToKey(0, gc_screenshot, ch, true)) diff --git a/src/p_user.c b/src/p_user.c index c7d77af15..b99515828 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -49,6 +49,7 @@ #include "m_cheat.h" // Thok camera snap (ctrl-f "chalupa") #include "g_input.h" +#include "m_menu.h" // menustack // SRB2kart #include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems @@ -191,7 +192,7 @@ boolean P_AutoPause(void) if (netgame || modeattacking || gamestate == GS_TITLESCREEN) return false; - return ((menuactive && !demo.playback) || ( window_notinfocus && cv_pauseifunfocused.value )); + return ((menustack[0] && !demo.playback) || ( window_notinfocus && cv_pauseifunfocused.value )); } // diff --git a/src/screen.c b/src/screen.c index 01ff1559e..2d5670b23 100644 --- a/src/screen.c +++ b/src/screen.c @@ -478,13 +478,13 @@ void SCR_ChangeRenderer(void) if (M_CheckParm("-nogl")) { CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n"); - if (menuactive) + if (menustack[0]) M_StartMessage(M_GetText("OpenGL rendering was disabled!\n\n(Press a key)\n"), NULL, MM_NOTHING); } else { CONS_Alert(CONS_ERROR, "OpenGL never loaded\n"); - if (menuactive) + if (menustack[0]) M_StartMessage(M_GetText("OpenGL never loaded\n\n(Press a key)\n"), NULL, MM_NOTHING); } CV_SetValue(&cv_renderer, render_soft); diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 9f29b501e..9216777f9 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -121,7 +121,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) +#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menustack[0] && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS // first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT @@ -386,7 +386,7 @@ static boolean IgnoreMouse(void) { if (cv_alwaysgrabmouse.value) return false; - if (menuactive) + if (menustack[0]) return !M_MouseNeeded(); if (paused || con_destlines || chat_on) return true; @@ -1005,7 +1005,7 @@ void I_GetEvent(void) CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); // update the menu - if (activeMenuId == MN_OP_JOYSTICKSET) + if (menustack[0] == MN_OP_JOYSTICKSET) M_SetupJoystickMenu(0); for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) @@ -1065,7 +1065,7 @@ void I_GetEvent(void) CONS_Debug(DBG_GAMELOGIC, "Joystick%d device index: %d\n", i+1, JoyInfo[i].oldjoy); // update the menu - if (activeMenuId == MN_OP_JOYSTICKSET) + if (menustack[0] == MN_OP_JOYSTICKSET) M_SetupJoystickMenu(0); break; case SDL_DROPFILE: diff --git a/src/st_stuff.c b/src/st_stuff.c index d108a1c9c..6a3756de9 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -858,7 +858,7 @@ void ST_AskToJoinEnvelope(void) { const tic_t freq = TICRATE/2; - if (menuactive) + if (menustack[0]) return; if ((leveltime % freq) < freq/2) From eb481b6ac4c43536e3cf175f33f1f4ff23e57e74 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 24 Mar 2025 16:37:41 +0100 Subject: [PATCH 20/33] Remove unused SRB2 menutypes Also remove MP_OFFLINESERVER, since that's just MP_SPLITSCREEN (oops) --- src/deh_tables.c | 30 ------------------------------ src/m_menu.c | 12 +++--------- src/m_menu.h | 30 ------------------------------ 3 files changed, 3 insertions(+), 69 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index e96a47975..c2d5b3ae2 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -617,57 +617,32 @@ const char *const MENUTYPES_LIST[] = { // Single Player "SP_MAIN", - "SP_LOAD", - "SP_PLAYER", - - "SP_LEVELSELECT", "SP_LEVELSTATS", "SP_TIMEATTACK", - "SP_TIMEATTACK_LEVELSELECT", "SP_GUESTREPLAY", "SP_REPLAY", "SP_GHOST", - "SP_NIGHTSATTACK", - "SP_NIGHTS_LEVELSELECT", - "SP_NIGHTS_GUESTREPLAY", - "SP_NIGHTS_REPLAY", - "SP_NIGHTS_GHOST", - - "SP_MARATHON", - // Multiplayer "MP_MAIN", "MP_SPLITSCREEN", // SplitServer "MP_SERVER", "MP_CONNECT", - "MP_ROOM", "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET - "MP_SERVER_OPTIONS", // Options "OP_MAIN", - "OP_P1CONTROLS", "OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2 - "OP_P1MOUSE", - "OP_P1JOYSTICK", "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 "OP_P1CAMERA", - "OP_P2CONTROLS", - "OP_P2MOUSE", - "OP_P2JOYSTICK", "OP_P2CAMERA", - "OP_PLAYSTYLE", - "OP_VIDEO", "OP_VIDEOMODE", - "OP_COLOR", "OP_OPENGL", - "OP_OPENGL_LIGHTING", "OP_SOUND", @@ -682,10 +657,8 @@ const char *const MENUTYPES_LIST[] = { // Extras "SR_MAIN", "SR_PANDORA", - "SR_LEVELSELECT", "SR_UNLOCKCHECKLIST", "SR_EMBLEMHINT", - "SR_PLAYER", "SR_SOUNDTEST", // Addons (Part of MISC, but let's make it our own) @@ -713,7 +686,6 @@ const char *const MENUTYPES_LIST[] = { "OP_P3CAMERA", "OP_P4CAMERA", "MISC_REPLAYOPTIONS", - "MP_OFFLINESERVER", "SP_GRANDPRIX", "MISC_REPLAYHUT", "CHANGESPECTATE", @@ -727,8 +699,6 @@ const char *const MENUTYPES_LIST[] = { "OP_DISCORD", "MISC_DISCORDREQUESTS", #endif - - "SPECIAL" }; struct menu_routine_s const MENU_ROUTINES[] = { diff --git a/src/m_menu.c b/src/m_menu.c index 2ee97fe65..3a8f0da62 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -755,12 +755,6 @@ void M_InitMenuPresTables(void) } if (i == MN_SP_TIMEATTACK) strncpy(menupres[i].musname, "_recat", 7); - else if (i == MN_SP_NIGHTSATTACK) - strncpy(menupres[i].musname, "_nitat", 7); - else if (i == MN_SP_MARATHON) - strncpy(menupres[i].musname, "spec8", 6); - else if (i == MN_SP_PLAYER || i == MN_SR_PLAYER) - strncpy(menupres[i].musname, "_chsel", 7); else if (i == MN_SR_SOUNDTEST) { *menupres[i].musname = '\0'; @@ -6515,7 +6509,7 @@ void M_StartServer(INT32 choice) (void)choice; - if (menustack[0] == MN_MP_OFFLINESERVER) + if (menustack[0] == MN_MP_SPLITSCREEN) netgame = false; else netgame = true; @@ -6544,7 +6538,7 @@ void M_StartServer(INT32 choice) SplitScreen_OnChange(); } - if (menustack[0] == MN_MP_OFFLINESERVER) // offline server + if (menustack[0] == MN_MP_SPLITSCREEN) // offline server { paused = false; SV_StartSinglePlayerServer(); @@ -6681,7 +6675,7 @@ void M_StartOfflineServerMenu(INT32 choice) (void)choice; levellistmode = LLM_CREATESERVER; M_PrepareLevelSelect(); - M_EnterMenu(MN_MP_OFFLINESERVER, true); + M_EnterMenu(MN_MP_SPLITSCREEN, true); } void M_StartServerMenu(INT32 choice) diff --git a/src/m_menu.h b/src/m_menu.h index 0d6abe086..b570c3e50 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -50,57 +50,32 @@ typedef enum // Single Player MN_SP_MAIN, - MN_SP_LOAD, - MN_SP_PLAYER, - - MN_SP_LEVELSELECT, MN_SP_LEVELSTATS, MN_SP_TIMEATTACK, - MN_SP_TIMEATTACK_LEVELSELECT, MN_SP_GUESTREPLAY, MN_SP_REPLAY, MN_SP_GHOST, - MN_SP_NIGHTSATTACK, - MN_SP_NIGHTS_LEVELSELECT, - MN_SP_NIGHTS_GUESTREPLAY, - MN_SP_NIGHTS_REPLAY, - MN_SP_NIGHTS_GHOST, - - MN_SP_MARATHON, - // Multiplayer MN_MP_MAIN, MN_MP_SPLITSCREEN, // SplitServer MN_MP_SERVER, MN_MP_CONNECT, - MN_MP_ROOM, MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET - MN_MP_SERVER_OPTIONS, // Options MN_OP_MAIN, - MN_OP_P1CONTROLS, MN_OP_CHANGECONTROLS, // OP_ChangeControlsDef shared with P2 - MN_OP_P1MOUSE, - MN_OP_P1JOYSTICK, MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2 MN_OP_P1CAMERA, - - MN_OP_P2CONTROLS, - MN_OP_P2MOUSE, - MN_OP_P2JOYSTICK, MN_OP_P2CAMERA, - MN_OP_PLAYSTYLE, MN_OP_VIDEO, MN_OP_VIDEOMODE, - MN_OP_COLOR, MN_OP_OPENGL, - MN_OP_OPENGL_LIGHTING, MN_OP_SOUND, @@ -115,10 +90,8 @@ typedef enum // Extras MN_SR_MAIN, MN_SR_PANDORA, - MN_SR_LEVELSELECT, MN_SR_UNLOCKCHECKLIST, MN_SR_EMBLEMHINT, - MN_SR_PLAYER, MN_SR_SOUNDTEST, // Addons (Part of MISC, but let's make it our own) @@ -146,7 +119,6 @@ typedef enum MN_OP_P3CAMERA, MN_OP_P4CAMERA, MN_MISC_REPLAYOPTIONS, - MN_MP_OFFLINESERVER, MN_SP_GRANDPRIX, MN_MISC_REPLAYHUT, MN_CHANGESPECTATE, @@ -161,8 +133,6 @@ typedef enum MN_MISC_DISCORDREQUESTS, #endif - MN_SPECIAL, - MN_FIRSTFREESLOT, MN_LASTFREESLOT, NUMMENUTYPES, From 8a6a49ce03de149fb467b13251c69a7a95d91b6a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 24 Mar 2025 17:09:27 +0100 Subject: [PATCH 21/33] Menutype header Also add more than 1 freeslot --- src/deh_tables.c | 92 ++------------------------------------------ src/info/menus.h | 85 +++++++++++++++++++++++++++++++++++++++++ src/m_menu.h | 99 +++--------------------------------------------- 3 files changed, 93 insertions(+), 183 deletions(-) create mode 100644 src/info/menus.h diff --git a/src/deh_tables.c b/src/deh_tables.c index c2d5b3ae2..230ff3b6d 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -610,95 +610,9 @@ const char *const HUDITEMS_LIST[] = { }; const char *const MENUTYPES_LIST[] = { - "NONE", - - "MAIN", - - // Single Player - "SP_MAIN", - - "SP_LEVELSTATS", - - "SP_TIMEATTACK", - "SP_GUESTREPLAY", - "SP_REPLAY", - "SP_GHOST", - - // Multiplayer - "MP_MAIN", - "MP_SPLITSCREEN", // SplitServer - "MP_SERVER", - "MP_CONNECT", - "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET - - // Options - "OP_MAIN", - - "OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2 - "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 - "OP_P1CAMERA", - - "OP_P2CAMERA", - - "OP_VIDEO", - "OP_VIDEOMODE", - "OP_OPENGL", - - "OP_SOUND", - - "OP_SERVER", - "OP_MONITORTOGGLE", - - "OP_DATA", - "OP_ADDONS", - "OP_SCREENSHOTS", - "OP_ERASEDATA", - - // Extras - "SR_MAIN", - "SR_PANDORA", - "SR_UNLOCKCHECKLIST", - "SR_EMBLEMHINT", - "SR_SOUNDTEST", - - // Addons (Part of MISC, but let's make it our own) - "AD_MAIN", - - // MISC - // "MESSAGE", - "SPAUSE", - - "MPAUSE", - "SCRAMBLETEAM", - "CHANGETEAM", - "CHANGELEVEL", - - "MAPAUSE", - "HELP", - - // SRB2Kart - "OP_HUD", - "OP_CHAT", - "OP_GAME", - "OP_BLANKARTGAME", - "OP_ADVANCEDSERVER", - "OP_CAMERA", - "OP_P3CAMERA", - "OP_P4CAMERA", - "MISC_REPLAYOPTIONS", - "SP_GRANDPRIX", - "MISC_REPLAYHUT", - "CHANGESPECTATE", - "MISC_REPLAYSTART", - "PLAYBACK", - "OP_CONTROLSETUP", - "OP_GAMEHUD", - "OP_VISUAL", - -#ifdef HAVE_DISCORDRPC - "OP_DISCORD", - "MISC_DISCORDREQUESTS", -#endif +#define _(name, ...) #name, +#include "info/menus.h" +#undef _ }; struct menu_routine_s const MENU_ROUTINES[] = { diff --git a/src/info/menus.h b/src/info/menus.h new file mode 100644 index 000000000..59cc8338c --- /dev/null +++ b/src/info/menus.h @@ -0,0 +1,85 @@ +_(NONE) + +_(MAIN) +_(PLAYBACK) + +// Single Player +_(SP_MAIN) +_(SP_GRANDPRIX) +_(SP_TIMEATTACK) +_(SP_GUESTREPLAY) +_(SP_REPLAY) +_(SP_GHOST) + +// Multiplayer +_(MP_MAIN) +_(MP_SPLITSCREEN) // SplitServer +_(MP_SERVER) +_(MP_CONNECT) +_(MP_PLAYERSETUP) + +// Options +_(OP_MAIN) + +_(OP_CONTROLSETUP) +_(OP_CHANGECONTROLS) +_(OP_JOYSTICKSET) + +_(OP_VIDEO) +_(OP_VIDEOMODE) +_(OP_VISUAL) +_(OP_OPENGL) + +_(OP_SOUND) +_(SR_SOUNDTEST) + +_(OP_HUD) +_(OP_CHAT) +_(OP_GAMEHUD) + +_(OP_CAMERA) +_(OP_P1CAMERA) +_(OP_P2CAMERA) +_(OP_P3CAMERA) +_(OP_P4CAMERA) + +_(OP_GAME) +_(OP_BLANKARTGAME) + +_(OP_SERVER) +_(OP_MONITORTOGGLE) +_(OP_ADVANCEDSERVER) + +_(OP_DATA) +_(OP_SCREENSHOTS) +_(OP_ADDONS) +_(MISC_REPLAYOPTIONS) +_(OP_ERASEDATA) +#ifdef HAVE_DISCORDRPC +_(OP_DISCORD) +#endif + +// Extras +_(SR_MAIN) +_(SP_LEVELSTATS) +_(SR_UNLOCKCHECKLIST) +_(MISC_REPLAYHUT) +_(MISC_REPLAYSTART) +_(SR_PANDORA) +_(SR_EMBLEMHINT) + +// Addons (Part of MISC, but let's make it our own) +_(AD_MAIN) + +// MISC +_(HELP) +_(SPAUSE) +_(MPAUSE) +_(MAPAUSE) +_(SCRAMBLETEAM) +_(CHANGETEAM) +_(CHANGELEVEL) +_(CHANGESPECTATE) +#ifdef HAVE_DISCORDRPC +_(MISC_DISCORDREQUESTS) +#endif diff --git a/src/m_menu.h b/src/m_menu.h index b570c3e50..a1a155529 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -38,105 +38,16 @@ extern "C" { #define NUMMENULEVELS 8 // Menu IDs sectioned by numeric places to signify hierarchy -/** - * IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH. - */ typedef enum { - MN_NONE, - - MN_MAIN, - - // Single Player - MN_SP_MAIN, - - MN_SP_LEVELSTATS, - - MN_SP_TIMEATTACK, - MN_SP_GUESTREPLAY, - MN_SP_REPLAY, - MN_SP_GHOST, - - // Multiplayer - MN_MP_MAIN, - MN_MP_SPLITSCREEN, // SplitServer - MN_MP_SERVER, - MN_MP_CONNECT, - MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET - - // Options - MN_OP_MAIN, - - MN_OP_CHANGECONTROLS, // OP_ChangeControlsDef shared with P2 - MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2 - MN_OP_P1CAMERA, - MN_OP_P2CAMERA, - - - MN_OP_VIDEO, - MN_OP_VIDEOMODE, - MN_OP_OPENGL, - - MN_OP_SOUND, - - MN_OP_SERVER, - MN_OP_MONITORTOGGLE, - - MN_OP_DATA, - MN_OP_ADDONS, - MN_OP_SCREENSHOTS, - MN_OP_ERASEDATA, - - // Extras - MN_SR_MAIN, - MN_SR_PANDORA, - MN_SR_UNLOCKCHECKLIST, - MN_SR_EMBLEMHINT, - MN_SR_SOUNDTEST, - - // Addons (Part of MISC, but let's make it our own) - MN_AD_MAIN, - - // MISC - // MN_MESSAGE, - MN_SPAUSE, - - MN_MPAUSE, - MN_SCRAMBLETEAM, - MN_CHANGETEAM, - MN_CHANGELEVEL, - - MN_MAPAUSE, - MN_HELP, - - // SRB2Kart - MN_OP_HUD, - MN_OP_CHAT, - MN_OP_GAME, - MN_OP_BLANKARTGAME, - MN_OP_ADVANCEDSERVER, - MN_OP_CAMERA, - MN_OP_P3CAMERA, - MN_OP_P4CAMERA, - MN_MISC_REPLAYOPTIONS, - MN_SP_GRANDPRIX, - MN_MISC_REPLAYHUT, - MN_CHANGESPECTATE, - MN_MISC_REPLAYSTART, - MN_PLAYBACK, - MN_OP_CONTROLSETUP, - MN_OP_GAMEHUD, - MN_OP_VISUAL, - -#ifdef HAVE_DISCORDRPC - MN_OP_DISCORD, - MN_MISC_DISCORDREQUESTS, -#endif +#define _(name, ...) MN_##name, +#include "info/menus.h" +#undef _ MN_FIRSTFREESLOT, - MN_LASTFREESLOT, + MN_LASTFREESLOT = MN_FIRSTFREESLOT + 128, NUMMENUTYPES, -} menutype_t; // up to 63 +} menutype_t; #define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT) extern menu_t *menudefs[NUMMENUTYPES]; From 6235219a9f8546f579e4ea9924d815937705b168 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 24 Mar 2025 20:31:57 +0100 Subject: [PATCH 22/33] Move version info stuff so it doesn't draw when a message box is shown --- src/m_menu.c | 56 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3a8f0da62..b1d41be7f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1479,34 +1479,6 @@ void M_Drawer(void) M_GetGametypeColor(); currentMenu->drawroutine(); // call current menu Draw routine } - - if (menustack[0] == MN_MAIN) - { - INT32 texty = vid.height - 10*vid.dupy; -#define addtext(f, str) {\ - V_DrawThinString(vid.dupx, texty, V_NOSCALESTART|f, str);\ - texty -= 10*vid.dupy;\ -} - if (customversionstring[0] != '\0') - { - addtext(V_ALLOWLOWERCASE, customversionstring); - addtext(0, "Mod version:"); - } - else - { -// Development -- show revision / branch info -#if defined(DEVELOP) - addtext(V_ALLOWLOWERCASE|V_GREENMAP|V_TRANSLUCENT, comprevision); - addtext(V_ALLOWLOWERCASE|V_YELLOWMAP|V_TRANSLUCENT, compbranch); - V_DrawThinString(0, 0, V_ALLOWLOWERCASE|V_ORANGEMAP|V_TRANSLUCENT|V_SNAPTOTOP, va("%s", complast)); -#else // Regular build - addtext(V_ALLOWLOWERCASE|V_TRANSLUCENT, va("%s", VERSIONSTRING)); -#endif - if (compuncommitted) - addtext(V_REDMAP|V_STRINGDANCE|V_TRANSLUCENT, "! UNCOMMITTED CHANGES !"); - } -#undef addtext - } } // focus lost notification goes on top of everything, even the former everything @@ -2417,6 +2389,34 @@ void M_DrawCenteredMenu(void) W_CachePatchName("M_CURSOR", PU_CACHE)); V_DrawCenteredString(x, cursory, highlightflags, currentMenu->menuitems[itemOn].text); } + + if (menustack[0] == MN_MAIN) + { + INT32 texty = vid.height - 10*vid.dupy; +#define addtext(f, str) {\ +V_DrawThinString(vid.dupx, texty, V_NOSCALESTART|f, str);\ +texty -= 10*vid.dupy;\ +} + if (customversionstring[0] != '\0') + { + addtext(V_ALLOWLOWERCASE, customversionstring); + addtext(0, "Mod version:"); + } + else + { +// Development -- show revision / branch info +#if defined(DEVELOP) + addtext(V_ALLOWLOWERCASE|V_GREENMAP|V_TRANSLUCENT, comprevision); + addtext(V_ALLOWLOWERCASE|V_YELLOWMAP|V_TRANSLUCENT, compbranch); + V_DrawThinString(0, 0, V_ALLOWLOWERCASE|V_ORANGEMAP|V_TRANSLUCENT|V_SNAPTOTOP, va("%s", complast)); +#else // Regular build + addtext(V_ALLOWLOWERCASE|V_TRANSLUCENT, va("%s", VERSIONSTRING)); +#endif + if (compuncommitted) + addtext(V_REDMAP|V_STRINGDANCE|V_TRANSLUCENT, "! UNCOMMITTED CHANGES !"); + } +#undef addtext + } } // From 0a573d3c5cd19e5d9c7101b321f85b6ba36c1555 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 24 Mar 2025 21:38:49 +0100 Subject: [PATCH 23/33] Fix player setup menu checking the wrong menuitems The skin option is now grayed-out when forceskin is enabled for presumably the first time since 2017 --- src/m_menu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b1d41be7f..92c682c24 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7004,7 +7004,7 @@ void M_DrawSetupMultiPlayerMenu(void) // draw skin string st = V_StringWidth(skins[setupm_fakeskin].realname, 0); V_DrawString(BASEVIDWIDTH - mx - st, my + 16, - ((M_GetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW") & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|highlightflags|V_ALLOWLOWERCASE, + ((M_GetItemStatus(MN_MP_PLAYERSETUP, "SKIN") & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|highlightflags|V_ALLOWLOWERCASE, skins[setupm_fakeskin].realname); if (M_IsItemOn(MN_MP_PLAYERSETUP, "SKIN")) { @@ -7448,7 +7448,7 @@ void M_HandleSetupMultiPlayer(INT32 choice) } // check color - if (M_IsItemOn(MN_MP_PLAYERSETUP, "FOLLOW") && !skincolors[setupm_fakecolor->color].accessible) { + if (M_IsItemOn(MN_MP_PLAYERSETUP, "COLOR") && !skincolors[setupm_fakecolor->color].accessible) { if (choice == KEY_LEFTARROW) while (!skincolors[setupm_fakecolor->color].accessible) setupm_fakecolor = setupm_fakecolor->prev; @@ -7498,9 +7498,9 @@ void M_SetupMultiPlayer(INT32 choice) // disable skin changes if we can't actually change skins if (!CanChangeSkin(consoleplayer)) - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_GRAYEDOUT); else - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER|IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_KEYHANDLER|IT_STRING); M_EnterMenu(MN_MP_PLAYERSETUP, true); } @@ -7541,9 +7541,9 @@ void M_SetupMultiPlayer2(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen && !CanChangeSkin(g_localplayers[1])) - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_GRAYEDOUT); else - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_KEYHANDLER | IT_STRING); M_EnterMenu(MN_MP_PLAYERSETUP, true); } @@ -7584,9 +7584,9 @@ void M_SetupMultiPlayer3(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen > 1 && !CanChangeSkin(g_localplayers[2])) - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_GRAYEDOUT); else - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_KEYHANDLER | IT_STRING); M_EnterMenu(MN_MP_PLAYERSETUP, true); } @@ -7627,9 +7627,9 @@ void M_SetupMultiPlayer4(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen > 2 && !CanChangeSkin(g_localplayers[3])) - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_GRAYEDOUT); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_GRAYEDOUT); else - M_SetItemStatus(MN_MP_PLAYERSETUP, "FOLLOW", IT_KEYHANDLER | IT_STRING); + M_SetItemStatus(MN_MP_PLAYERSETUP, "SKIN", IT_KEYHANDLER | IT_STRING); M_EnterMenu(MN_MP_PLAYERSETUP, true); } From 0fda4cf0172991089e87ef0fc31fae60aca43b9b Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 24 Mar 2025 23:45:09 +0100 Subject: [PATCH 24/33] Add custom options menu A dedicated menu for addons to insert their own options submenus --- src/info/menus.h | 2 ++ src/m_menu.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/info/menus.h b/src/info/menus.h index 59cc8338c..77f87d715 100644 --- a/src/info/menus.h +++ b/src/info/menus.h @@ -59,6 +59,8 @@ _(OP_ERASEDATA) _(OP_DISCORD) #endif +_(OP_CUSTOM) + // Extras _(SR_MAIN) _(SP_LEVELSTATS) diff --git a/src/m_menu.c b/src/m_menu.c index 92c682c24..4784a3117 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4443,6 +4443,8 @@ void M_Options(INT32 choice) M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET); + M_SetItemStatus(MN_OP_MAIN, "CUSTOM", !menudefs[MN_OP_CUSTOM]->numitems ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU); + M_EnterMenu(MN_OP_MAIN, true); } From 784fc8f46cea5b8a842efd7489a8ad4203b9d8ee Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 01:35:07 +0100 Subject: [PATCH 25/33] Last-minute curse: no menus for dedis, empty item names instead of '.' --- src/deh_soc.c | 43 +++++++++++++++++++++---------------------- src/dehacked.c | 3 +++ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index d413e3651..26935bb7a 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2361,7 +2361,6 @@ void readmenu(MYFILE *f, INT32 num) char *word2; char *tmp; INT32 value; - boolean space = false; menu_t *menudef = allocmenu(num); @@ -2383,44 +2382,37 @@ void readmenu(MYFILE *f, INT32 num) if (s == tmp) continue; // Skip comment lines, but don't break. - space = false; - // Get the part before the " = " tmp = strchr(s, '='); if (tmp) *(tmp-1) = '\0'; else { - space = true; - tmp = strchr(s, ' '); - if (tmp) - *tmp-- = '\0'; // decrement after, so word2 is correct - else - break; - } - strupr(word); + // ...or get the word after the space. yay special syntax! + word2 = strchr(s, ' '); + if (word2) + { + *word2++ = '\0'; + if (*word2 == '\0' || *word2 == ' ') // trailing space(s) after MenuItem doesn't count + word2 = NULL; + else + strupr(word2); + } + strupr(word); - // Now get the part after - word2 = (tmp += 2); - strupr(word2); - - value = atoi(word2); // used for numerical settings - - if (space) - { if (fastcmp(word, "MENUITEM")) { - if (strlen(word2) > ITEMNAMELEN) + if (word2 && strlen(word2) > ITEMNAMELEN) { deh_warning("Menu %d: item name %s is too long (max %d characters)", num, word2, ITEMNAMELEN); continue; } - menuitem_t *item = word2[0] == '.' ? NULL : M_CheckMenuItem(num, word2); + menuitem_t *item = word2 ? M_CheckMenuItem(num, word2) : NULL; if (item == NULL) { menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL); item = menudef->menuitems + menudef->numitems++; - strncpy(item->itemname, word2, ITEMNAMELEN); + strncpy(item->itemname, word2 ? word2 : "", ITEMNAMELEN); item->text = ""; } readmenuitem(f, item); @@ -2429,6 +2421,13 @@ void readmenu(MYFILE *f, INT32 num) deh_warning("Menu %d: unknown word '%s'", num, word); continue; } + strupr(word); + + // Now get the part after + word2 = (tmp += 2); + strupr(word2); + + value = atoi(word2); // used for numerical settings if (fastcmp(word, "BACKGROUNDNAME")) { diff --git a/src/dehacked.c b/src/dehacked.c index 59c88267a..7a7604f85 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -471,6 +471,9 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } else if (fastcmp(word, "MENU")) { + if (dedicated) + continue; // dedis don't need menus, silly! + if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_menutype(word2); // find a huditem by name if (i >= 1 && i < NUMMENUTYPES) From 016435b3b9549fee56ad6098c71d3fb6308a86bc Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 15:55:56 +0100 Subject: [PATCH 26/33] Fix jank attack Consistently call D_StartTitle, don't glitch out on invalid replays etc --- src/f_finale.c | 1 - src/g_demo.c | 20 ++++++++++---------- src/g_game.c | 4 ++-- src/m_menu.c | 49 ++++++++++++++++++------------------------------- src/m_menu.h | 3 --- 5 files changed, 30 insertions(+), 47 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 683b5c9cb..f968c183f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1168,7 +1168,6 @@ void F_GameEndTicker(void) void F_InitMenuPresValues(void) { menuanimtimer = 0; - M_ClearMenus(false); // TODO maybe call exit funcs here? but that triggers an infinite loop in replay hut... // Set defaults for presentation values strncpy(curbgname, "TITLESKY", 9); diff --git a/src/g_demo.c b/src/g_demo.c index dc326811d..00489ec34 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -2992,11 +2992,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } demobuf.p += 12; // DEMOHEADER @@ -3012,11 +3012,11 @@ void G_DoPlayDemo(char *defdemoname) default: snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } @@ -3030,11 +3030,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } @@ -3094,12 +3094,12 @@ void G_DoPlayDemo(char *defdemoname) } CONS_Alert(CONS_ERROR, "%s", msg); - if (!CON_Ready()) // In the console they'll just see the notice there! No point pulling them out. - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + if (!CON_Ready()) // In the console they'll just see the notice there! No point pulling them out. + M_StartMessage(msg, NULL, MM_NOTHING); return; } } @@ -3138,11 +3138,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } @@ -3166,11 +3166,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } @@ -3217,11 +3217,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with %s, and is thus invalid.\n"), pdemoname, (bot ? "bots" : "spectators")); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } } @@ -3233,11 +3233,11 @@ void G_DoPlayDemo(char *defdemoname) { snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); P_SaveBufferFree(&demobuf); demo.playback = false; demo.title = false; + M_StartMessage(msg, NULL, MM_NOTHING); return; } @@ -4019,7 +4019,7 @@ boolean G_CheckDemoStatus(void) G_StopDemo(); if (modeattacking) - M_EndModeAttackRun(); + M_ModeAttackEndGame(0); else D_AdvanceDemo(); } diff --git a/src/g_game.c b/src/g_game.c index 2edfb01e2..f88cedf51 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -646,7 +646,7 @@ void G_SetGameModified(boolean silent, boolean major) // If in record attack recording, cancel it. if (modeattacking) - M_EndModeAttackRun(); + M_ModeAttackEndGame(0); else if (marathonmode) Command_ExitGame_f(); } @@ -4062,7 +4062,7 @@ void G_AfterIntermission(void) if (modeattacking) // End the run. { - M_EndModeAttackRun(); + M_ModeAttackEndGame(0); return; } diff --git a/src/m_menu.c b/src/m_menu.c index 4784a3117..4a70c7a59 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1315,22 +1315,15 @@ boolean M_Responder(event_t *ev) //case KEY_JOY1 + 2: noFurtherInput = true; currentMenu->lastOn = itemOn; - if (menustack[0] == MN_SP_TIMEATTACK) + + //If we entered the game search menu, but didn't enter a game, + //make sure the game doesn't still think we're in a netgame. + if (!Playing() && netgame && multiplayer) { - // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - D_StartTitle(); - } - else - { - //If we entered the game search menu, but didn't enter a game, - //make sure the game doesn't still think we're in a netgame. - if (!Playing() && netgame && multiplayer) - { - netgame = false; - multiplayer = false; - } - M_ExitMenu(); + netgame = false; + multiplayer = false; } + M_ExitMenu(); return true; @@ -1655,11 +1648,6 @@ void M_StartControlPanel(void) CON_ToggleOff(); // move away console } -void M_EndModeAttackRun(void) -{ - M_ModeAttackEndGame(0); -} - // // M_ClearMenus // @@ -1676,6 +1664,10 @@ void M_ClearMenus(boolean callexitmenufunc) memset(menustack, 0, sizeof(menustack)); currentMenu = NULL; hidetitlemap = false; + + // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. + if (gamestate == GS_TIMEATTACK) + D_StartTitle(); } // @@ -4004,8 +3996,7 @@ void M_QuitReplayHut(INT32 choice) { (void)choice; - // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - D_StartTitle(); + M_ClearMenus(false); if (demolist) Z_Free(demolist); @@ -4302,11 +4293,14 @@ void M_PlaybackQuit(INT32 choice) M_ReplayHut(choice); else if (modeattacking) { - M_EndModeAttackRun(); + M_ModeAttackEndGame(0); S_ChangeMusicInternal("racent", true); } else + { + M_ClearMenus(true); D_StartTitle(); + } } void M_PandorasBox(INT32 choice) @@ -5842,7 +5836,6 @@ void M_HandleStaffReplay(INT32 choice) if (l == LUMPERROR) break; M_ClearMenus(true); - modeattacking = (levellistmode == LLM_ITEMBREAKER ? ATTACKING_ITEMBREAK : ATTACKING_TIME); demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed G_DoPlayDemo(va("%sS%02u",G_BuildMapName(cv_nextmap.value),cv_dummystaff.value)); break; @@ -5859,7 +5852,6 @@ void M_ReplayTimeAttack(INT32 choice) const char *which; const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; M_ClearMenus(true); - modeattacking = (levellistmode == LLM_ITEMBREAKER ? ATTACKING_ITEMBREAK : ATTACKING_TIME); // set modeattacking before G_DoPlayDemo so the map loader knows demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed switch(choice) { @@ -5976,13 +5968,8 @@ void M_ModeAttackEndGame(INT32 choice) if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING) Command_ExitGame_f(); - M_StartControlPanel(); - - if (modeattacking) - { - M_ClearMenus(true); - M_EnterMenu(MN_SP_TIMEATTACK, true); - } + M_ClearMenus(true); + M_EnterMenu(MN_SP_TIMEATTACK, true); G_SetGamestate(GS_TIMEATTACK); modeattacking = ATTACKING_NONE; diff --git a/src/m_menu.h b/src/m_menu.h index a1a155529..71a9164d1 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -120,9 +120,6 @@ void M_InitCharacterTables(void); // does nothing if menu is already up. void M_StartControlPanel(void); -// Called upon end of a mode attack run -void M_EndModeAttackRun(void); - // Called on new server add, or other reasons void M_SortServerList(void); From 8c2803607d7242d47cf615c2ca09737ac6656bcd Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 17:11:52 +0100 Subject: [PATCH 27/33] Show names for menu/menuitem warnings --- src/deh_soc.c | 38 ++++++++++++++++++++++---------------- src/m_menu.h | 1 + 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 26935bb7a..f2a98a806 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2177,6 +2177,8 @@ static struct { const char *name; consvar_t *var; } HIDDENVARS[] = { { NULL, NULL } }; +#define WARN(str, ...) deh_warning("MenuItem " ITEMNAMEFMT ": " str, menuitem->itemname, __VA_ARGS__) +#define WARN0(str) deh_warning("MenuItem " ITEMNAMEFMT ": " str, menuitem->itemname) static void readmenuitem(MYFILE *f, menuitem_t *menuitem) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2237,13 +2239,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) flags = IT_STRING2; else if (word[4]) { - deh_warning("MenuItem %s: unknown word '%s'", "", word); + WARN("unknown word '%s'", word); continue; } if (textset) { - deh_warning("MenuItem %s: text already set!", ""); + WARN0("text already set!"); continue; } textset = true; @@ -2261,13 +2263,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) flags |= IT_CV_INTEGERSTEP; else if (word[4]) { - deh_warning("MenuItem %s: unknown word '%s'", "", word); + WARN("unknown word '%s'", word); continue; } if (actionset) { - deh_warning("MenuItem %s: action already set!", ""); + WARN0("action already set!"); continue; } consvar_t *cvar = CV_FindVar(word2); @@ -2280,7 +2282,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) } if (!cvar) { - deh_warning("MenuItem %s: unable to find cvar '%s'", "", word2); + WARN("unable to find cvar '%s'", word2); continue; } actionset = true; @@ -2291,13 +2293,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) { if (actionset) { - deh_warning("MenuItem %s: action already set!", ""); + WARN0("action already set!"); continue; } menutype_t mn = get_menutype(word2); if (mn == MN_NONE) { - deh_warning("MenuItem %s: unknown menu '%s'", "", word2); + WARN("unknown menu '%s'", word2); continue; } actionset = true; @@ -2315,7 +2317,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) flags |= IT_CALL_NOTMODIFIED; else if (word[4]) { - deh_warning("MenuItem %s: unknown word '%s'", "", word); + WARN("unknown word '%s'", word); continue; } } @@ -2328,13 +2330,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) if (actionset) { - deh_warning("MenuItem %s: action already set!", ""); + WARN0("action already set!"); continue; } void (*routine)(INT32) = get_menuroutine(word2); if (!routine) { - deh_warning("MenuItem %s: unknown call routine '%s'", "", word2); + WARN("unknown call routine '%s'", word2); continue; } actionset = true; @@ -2346,14 +2348,17 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) menuitem->alphaKey = get_number(word2); } else - deh_warning("MenuItem %s: unknown word '%s'", "", word); + WARN("unknown word '%s'", word); } while (!myfeof(f)); // finish when the line is empty menuitem->status = status; Z_Free(s); } +#undef WARN +#undef WARN0 +#define WARN(str, ...) deh_warning("Menu %s: " str, num < MN_FIRSTFREESLOT ? MENUTYPES_LIST[num] : FREE_MENUS[num - MN_FIRSTFREESLOT], __VA_ARGS__) void readmenu(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -2404,7 +2409,7 @@ void readmenu(MYFILE *f, INT32 num) { if (word2 && strlen(word2) > ITEMNAMELEN) { - deh_warning("Menu %d: item name %s is too long (max %d characters)", num, word2, ITEMNAMELEN); + WARN("item name %s is too long (max %d characters)", word2, ITEMNAMELEN); continue; } menuitem_t *item = word2 ? M_CheckMenuItem(num, word2) : NULL; @@ -2418,7 +2423,7 @@ void readmenu(MYFILE *f, INT32 num) readmenuitem(f, item); } else - deh_warning("Menu %d: unknown word '%s'", num, word); + WARN("unknown word '%s'", word); continue; } strupr(word); @@ -2579,7 +2584,7 @@ void readmenu(MYFILE *f, INT32 num) void (*drawer)(void) = get_menudrawer(word2); if (drawer == NULL) { - deh_warning("Menu %d: unknown draw routine '%s'", num, word2); + WARN("unknown draw routine '%s'", word2); continue; } menudef->drawroutine = drawer; @@ -2597,18 +2602,19 @@ void readmenu(MYFILE *f, INT32 num) void (*routine)(INT32) = get_menuroutine(word2); if (!routine) { - deh_warning("Menu %d: unknown quit routine '%s'", num, word2); + WARN("unknown quit routine '%s'", word2); continue; } menudef->quitroutine = routine; } else - deh_warning("Menu %d: unknown word '%s'", num, word); + WARN("unknown word '%s'", word); } } while (!myfeof(f)); // finish when the line is empty Z_Free(s); } +#undef WARN void readframe(MYFILE *f, INT32 num) { diff --git a/src/m_menu.h b/src/m_menu.h index 71a9164d1..997d718e3 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -218,6 +218,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define MAXSTRINGLENGTH 32 #define ITEMNAMELEN 6 +#define ITEMNAMEFMT "%.6s" typedef union { From f27e486f4b9c62a749a7c620dc243a7fa12c51e9 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 19:38:52 +0100 Subject: [PATCH 28/33] Fix M_GetGametypeColor crash --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 4a70c7a59..cc1c31bb3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -416,7 +416,7 @@ inline static void M_GetGametypeColor(void) return; } - if (currentMenu->drawroutine == M_DrawServerMenu) + if (currentMenu && currentMenu->drawroutine == M_DrawServerMenu) gt = cv_newgametype.value; else if (!Playing()) { From fd7eb9e06d7f500b888d20d7159cf8477022b198 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 21:08:56 +0100 Subject: [PATCH 29/33] Refined message box code, consistent DrawPatchFill M_StartMessage now takes a function pointer instead of an object pointer. No more FUNCPTRCAST --- src/d_clisrv.c | 6 +- src/m_menu.c | 213 ++++++++++++++++++------------------------------- src/m_menu.h | 4 +- 3 files changed, 80 insertions(+), 143 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c5039f9e0..966d1d364 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1588,7 +1588,7 @@ static boolean CL_FinishedFileList(void) "You may load server addons (if any), and wait for a slot.\n" "\n" "Press ACCEL to continue or BRAKE to cancel.\n\n" - ), FUNCPTRCAST (M_ConfirmConnect), MM_EVENTHANDLER); + ), M_ConfirmConnect, MM_EVENTHANDLER); cl_mode = CL_CONFIRMCONNECT; } else @@ -1649,13 +1649,13 @@ static boolean CL_FinishedFileList(void) "You may download, load server addons, and wait for a slot.\n" "\n" "Press ACCEL to continue or BRAKE to cancel.\n\n" - ), downloadsize), FUNCPTRCAST(M_ConfirmConnect), MM_EVENTHANDLER); + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); else M_StartMessage(va(M_GetText( "Download of %s additional content is required to join.\n" "\n" "Press ACCEL to continue or BRAKE to cancel.\n\n" - ), downloadsize), FUNCPTRCAST(M_ConfirmConnect), MM_EVENTHANDLER); + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); Z_Free(downloadsize); cl_mode = CL_CONFIRMCONNECT; diff --git a/src/m_menu.c b/src/m_menu.c index cc1c31bb3..d0be0c719 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -173,6 +173,16 @@ static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 skullAnimCounter = 10; // skull animation counter static tic_t followertimer = 0; // Used for smooth follower floating +static struct { + boolean active; + const char *text; + void (*routine)(); + menumessagetype_t messagetype; + INT16 x, y; + INT16 numlines; + INT16 maxlength; +} messagebox; + static UINT8 setupcontrolplayer; static INT32 (*setupcontrols)[MAXINPUTMAPPING]; // pointer to the gamecontrols of the player being edited @@ -183,12 +193,6 @@ static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -// -// PROTOTYPES -// - -static void M_StopMessage(INT32 choice); - // Prototyping is fun, innit? // ========================================================================== // NEEDED FUNCTION PROTOTYPES GO HERE @@ -197,9 +201,6 @@ static void M_StopMessage(INT32 choice); void M_SetWaitingMode(int mode); int M_GetWaitingMode(void); -// the haxor message menu -menu_t MessageDef; - #define lsheadingheight 16 // Sky Room @@ -216,7 +217,7 @@ static patch_t *addonsp[NUM_EXT+5]; static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked // Drawing functions -static void M_DrawGenericBackgroundMenu(void); +static void M_DrawMessageMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); // uhhhhhh hack? @@ -1049,6 +1050,27 @@ boolean M_Responder(event_t *ev) if (ch == -1) return false; + if (messagebox.active) + { + if (messagebox.messagetype != MM_EVENTHANDLER) + { + if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER) + { + if (messagebox.routine) + messagebox.routine(ch); + messagebox.active = false; + noFurtherInput = true; + } + } + else + { + // dirty hack: for customising controls, I want only buttons/keys/axes, not mouse + if (messagebox.routine && !(ev->type == ev_mouse || (ev->type == ev_joystick && messagebox.routine != M_ChangecontrolResponse))) + messagebox.routine(ev); + } + return true; + } + // F-Keys if (!menustack[0]) { @@ -1135,36 +1157,6 @@ boolean M_Responder(event_t *ev) return true; } - if (currentMenu->menuitems[itemOn].status == IT_MSGHANDLER) - { - if (currentMenu->menuitems[itemOn].alphaKey != MM_EVENTHANDLER) - { - if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER) - { - if (routine) - routine(ch); - M_StopMessage(0); - noFurtherInput = true; - return true; - } - return true; - } - else - { - // dirty hack: for customising controls, I want only buttons/keys/axes, not mouse - if (ev->type == ev_mouse || (ev->type == ev_joystick && currentMenu->menuitems[itemOn].itemaction.eventhandler != M_ChangecontrolResponse)) - { - return true; - } - - if (routine) - { - currentMenu->menuitems[itemOn].itemaction.eventhandler(ev); - } - return true; - } - } - // BP: one of the more big hack i have never made if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR) { @@ -1461,17 +1453,23 @@ boolean M_DemoResponder(event_t *ev) // void M_Drawer(void) { - if (menustack[0]) + if (menustack[0] || messagebox.active) { // now that's more readable with a faded background (yeah like Quake...) - if (!WipeInAction && menustack[0] != MN_PLAYBACK) // Replay playback has its own background + if (gamestate == GS_TIMEATTACK) + V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); + else if (!WipeInAction && menustack[0] != MN_PLAYBACK) // Replay playback has its own background V_DrawFadeScreen(0xFF00, 16); + } - if (currentMenu->drawroutine) - { - M_GetGametypeColor(); - currentMenu->drawroutine(); // call current menu Draw routine - } + if (messagebox.active) + { + M_DrawMessageMenu(); + } + else if (currentMenu && currentMenu->drawroutine) + { + M_GetGametypeColor(); + currentMenu->drawroutine(); // call current menu Draw routine } // focus lost notification goes on top of everything, even the former everything @@ -2227,12 +2225,6 @@ void M_DrawGenericMenu(void) } } -static void M_DrawGenericBackgroundMenu(void) -{ - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - M_DrawGenericMenu(); -} - void M_DrawPauseMenu(void) { #ifdef HAVE_DISCORDRPC @@ -2630,24 +2622,7 @@ static INT32 M_GetFirstLevelInList(void) // ================================================== // MESSAGE BOX (aka: a hacked, cobbled together menu) // ================================================== -static void M_DrawMessageMenu(void); - -// Because this is just a hack-ish 'menu', I'm not putting this with the others -static menuitem_t MessageMenu[] = {0}; - -menu_t MessageDef = -{ - NULL, // title - 1, // # of menu items - MessageMenu, // menuitem_t -> - M_DrawMessageMenu, // drawing routine -> - 0, 0, // x, y (TO HACK) - 0, // lastOn, flags (TO HACK) - NULL -}; - - -void M_StartMessage(const char *string, void *routine, +void M_StartMessage(const char *string, void (*routine)(), menumessagetype_t itemtype) { size_t max = 0, start = 0, i, strlines; @@ -2691,24 +2666,10 @@ void M_StartMessage(const char *string, void *routine, M_StartControlPanel(); // can't put menuactive to true - MessageDef.menuitems[0].text = message; - MessageDef.menuitems[0].alphaKey = (UINT8)itemtype; - if (!routine && itemtype != MM_NOTHING) itemtype = MM_NOTHING; - switch (itemtype) - { - case MM_NOTHING: - MessageDef.menuitems[0].status = IT_MSGHANDLER; - MessageDef.menuitems[0].itemaction.routine = M_StopMessage; - break; - case MM_YESNO: - MessageDef.menuitems[0].status = IT_MSGHANDLER; - *(void**)&MessageDef.menuitems[0].itemaction.routine = routine; - break; - case MM_EVENTHANDLER: - MessageDef.menuitems[0].status = IT_MSGHANDLER; - *(void**)&MessageDef.menuitems[0].itemaction.eventhandler = routine; - break; - } + messagebox.text = message; + messagebox.messagetype = itemtype; + messagebox.routine = routine; + //added : 06-02-98: now draw a textbox around the message // compute lenght max and the numbers of lines for (strlines = 0; *(message+start); strlines++) @@ -2730,34 +2691,25 @@ void M_StartMessage(const char *string, void *routine, start += i; } - MessageDef.x = (INT16)((BASEVIDWIDTH - 8*max-16)/2); - MessageDef.y = (INT16)((BASEVIDHEIGHT - M_StringHeight(message))/2); + messagebox.x = (BASEVIDWIDTH - 8*max-16)/2; + messagebox.y = (BASEVIDHEIGHT - M_StringHeight(message))/2; - MessageDef.lastOn = (INT16)((strlines<<8)+max); + messagebox.numlines = strlines; + messagebox.maxlength = max; - currentMenu = &MessageDef; - itemOn = 0; + messagebox.active = true; } #define MAXMSGLINELEN 256 static void M_DrawMessageMenu(void) { - INT32 y = currentMenu->y; + INT32 y = messagebox.y; size_t i, start = 0; - INT16 max; char string[MAXMSGLINELEN]; - INT32 mlines; - const char *msg = currentMenu->menuitems[0].text; + const char *msg = messagebox.text; - mlines = currentMenu->lastOn>>8; - max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8); - - // hack: draw RA background in RA menus - if (gamestate == GS_TIMEATTACK) - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - - M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines); + M_DrawTextBox(messagebox.x, y - 8, messagebox.maxlength, messagebox.numlines); while (*(msg+start)) { @@ -2804,16 +2756,6 @@ static void M_DrawMessageMenu(void) } } -// default message handler -static void M_StopMessage(INT32 choice) -{ - (void)choice; - if (menustack[0]) - M_SetupNextMenu(menustack[0], true); - else - M_ClearMenus(true); -} - // ========= // IMAGEDEFS // ========= @@ -3037,11 +2979,12 @@ static boolean prevmajormods = false; static void M_AddonsClearName(INT32 choice) { + (void)choice; if (!majormods || prevmajormods) { CLEARNAME; } - M_StopMessage(choice); + messagebox.active = false; } // returns whether to do message draw @@ -3090,7 +3033,7 @@ static boolean M_AddonsRefresh(void) if (message) { - M_StartMessage(message, FUNCPTRCAST(M_AddonsClearName), MM_EVENTHANDLER); + M_StartMessage(message, M_AddonsClearName, MM_EVENTHANDLER); return true; } @@ -3387,7 +3330,7 @@ void M_HandleAddons(INT32 choice) } break; case EXT_TXT: - M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), FUNCPTRCAST(M_AddonExec) ,MM_YESNO); + M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING), M_AddonExec ,MM_YESNO); break; case EXT_CFG: M_AddonExec(KEY_ENTER); @@ -3745,8 +3688,6 @@ void M_DrawReplayHut(void) static UINT16 replayhutmenuy = 0; - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - if (cv_vhseffect.value) V_DrawVhsEffect(false); @@ -3887,7 +3828,7 @@ void M_DrawReplayStartMenu(void) const char *warning; UINT8 i; - M_DrawGenericBackgroundMenu(); + M_DrawGenericMenu(); #define STARTY 62-(replayScrollTitle>>1) // Draw rankings beyond first @@ -4463,7 +4404,7 @@ static void M_RetryResponse(INT32 ch) void M_Retry(INT32 choice) { (void)choice; - M_StartMessage(va("Start this %s over?\n\n(Press 'Y' to confirm)\n", (gametyperules & GTR_CIRCUIT) ? "race" : "battle"),FUNCPTRCAST(M_RetryResponse),MM_YESNO); + M_StartMessage(va("Start this %s over?\n\n(Press 'Y' to confirm)\n", (gametyperules & GTR_CIRCUIT) ? "race" : "battle"),M_RetryResponse,MM_YESNO); } void M_SelectableClearMenus(INT32 choice) @@ -4521,7 +4462,7 @@ void M_DestroyRobots(INT32 choice) { (void)choice; - M_StartMessage(M_GetText("Do you want to destroy all\nrobots in the current level?\n\n(Press 'Y' to confirm)\n"), FUNCPTRCAST(M_DestroyRobotsResponse), MM_YESNO); + M_StartMessage(M_GetText("Do you want to destroy all\nrobots in the current level?\n\n(Press 'Y' to confirm)\n"), M_DestroyRobotsResponse, MM_YESNO); } // ======== @@ -5562,8 +5503,6 @@ void M_DrawTimeAttackMenu(void) //S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback - V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - M_DrawMenuTitle(); if (menustack[0] == MN_SP_TIMEATTACK) M_DrawLevelSelectOnly(true, false); @@ -5898,7 +5837,7 @@ static void M_OverwriteGuest(const char *which) return; } if (FIL_FileExists(rguest)) { - M_StopMessage(0); + messagebox.active = false; remove(rguest); } FIL_WriteFile(rguest, buf, len); @@ -5943,11 +5882,11 @@ void M_SetGuestReplay(INT32 choice) break; case 3: // guest default: - M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"), FUNCPTRCAST(M_EraseGuest), MM_YESNO); + M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"), M_EraseGuest, MM_YESNO); return; } if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) - M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"), FUNCPTRCAST(which), MM_YESNO); + M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"), which, MM_YESNO); else which(0); } @@ -6002,7 +5941,7 @@ void M_EndGame(INT32 choice) if (!Playing()) return; - M_StartMessage(M_GetText("Are you sure you want to end the game?\n\n(Press 'Y' to confirm)\n"), FUNCPTRCAST(M_ExitGameResponse), MM_YESNO); + M_StartMessage(M_GetText("Are you sure you want to end the game?\n\n(Press 'Y' to confirm)\n"), M_ExitGameResponse, MM_YESNO); } //=========================================================================== @@ -6456,7 +6395,7 @@ void M_ConnectMenuModChecks(INT32 choice) if (modifiedgame) { - M_StartMessage(M_GetText("You have addons loaded.\nYou won't be able to join netgames!\n\nTo play online, restart the game\nand don't load any addons.\nSRB2Kart will automatically add\neverything you need when you join.\n\n(Press a key)\n"), FUNCPTRCAST(M_ConnectMenu), MM_EVENTHANDLER); + M_StartMessage(M_GetText("You have addons loaded.\nYou won't be able to join netgames!\n\nTo play online, restart the game\nand don't load any addons.\nSRB2Kart will automatically add\neverything you need when you join.\n\n(Press a key)\n"), M_ConnectMenu, MM_EVENTHANDLER); return; } @@ -7860,7 +7799,7 @@ void M_EraseData(INT32 choice) else eschoice = M_GetText("ALL game data"); - M_StartMessage(va(esstr, eschoice), FUNCPTRCAST(M_EraseDataResponse), MM_YESNO); + M_StartMessage(va(esstr, eschoice), M_EraseDataResponse, MM_YESNO); } void M_ScreenshotOptions(INT32 choice) @@ -8350,7 +8289,7 @@ static void M_ChangecontrolResponse(event_t *ev) sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext); - M_StartMessage(tmp, FUNCPTRCAST(M_ChangecontrolResponse), MM_EVENTHANDLER); + M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); S_StartSound(NULL, sfx_s3k42); return; @@ -8358,7 +8297,7 @@ static void M_ChangecontrolResponse(event_t *ev) else S_StartSound(NULL, sfx_s224); - M_StopMessage(0); + messagebox.active = false; } void M_ChangeControl(INT32 choice) @@ -8372,7 +8311,7 @@ void M_ChangeControl(INT32 choice) currentMenu->menuitems[choice].text); strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33); - M_StartMessage(tmp, FUNCPTRCAST(M_ChangecontrolResponse), MM_EVENTHANDLER); + M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } static void M_ResetControlsResponse(INT32 ch) @@ -8401,7 +8340,7 @@ static void M_ResetControlsResponse(INT32 ch) void M_ResetControls(INT32 choice) { (void)choice; - M_StartMessage(va(M_GetText("Reset Player %d's controls to defaults?\n\n(Press 'Y' to confirm)\n"), setupcontrolplayer), FUNCPTRCAST(M_ResetControlsResponse), MM_YESNO); + M_StartMessage(va(M_GetText("Reset Player %d's controls to defaults?\n\n(Press 'Y' to confirm)\n"), setupcontrolplayer), M_ResetControlsResponse, MM_YESNO); } // =============== @@ -9014,7 +8953,7 @@ void M_QuitSRB2(INT32 choice) // We pick index 0 which is language sensitive, or one at random, // between 1 and maximum number. (void)choice; - M_StartMessage(quitmsg[M_RandomKey(NUM_QUITMESSAGES)], FUNCPTRCAST(M_QuitResponse), MM_YESNO); + M_StartMessage(quitmsg[M_RandomKey(NUM_QUITMESSAGES)], M_QuitResponse, MM_YESNO); } #ifdef HAVE_DISCORDRPC diff --git a/src/m_menu.h b/src/m_menu.h index 997d718e3..592dea54d 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -139,7 +139,7 @@ typedef enum MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction // and routine is void routine(event_t *) (ex: set control) } menumessagetype_t; -void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); +void M_StartMessage(const char *string, void (*routine)(), menumessagetype_t itemtype); typedef enum { @@ -168,7 +168,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define IT_SUBMENU 6 // go to sub menu #define IT_CVAR 8 // handle as a cvar #define IT_PAIR 11 // no handling, define both sides of text -#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) #define IT_DISPLAY (48+64+128) // 16+32+64+128 #define IT_NOTHING 0 // space @@ -225,7 +224,6 @@ typedef union menutype_t submenu; // IT_SUBMENU consvar_t *cvar; // IT_CVAR void (*routine)(INT32 choice); // IT_CALL, IT_KEYHANDLER, IT_ARROWS - void (*eventhandler)(event_t *ev); // MM_EVENTHANDLER } itemaction_t; // From eeeca0a6ba9a73c0da5f7c9e59243fe938696034 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 21:34:09 +0100 Subject: [PATCH 30/33] And maybe clear the message box when clearing menus... --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index d0be0c719..946eaa9f4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1661,6 +1661,7 @@ void M_ClearMenus(boolean callexitmenufunc) memset(menustack, 0, sizeof(menustack)); currentMenu = NULL; + messagebox.active = false; hidetitlemap = false; // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. From 68a29ad0dcd65af0e72249ad7af337e37d803a04 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 25 Mar 2025 23:25:31 +0100 Subject: [PATCH 31/33] Don't use K&R syntax for messagebox routines which was removed in C23 Yup, that's not just a function declaration thing... Starting to doubt if this is a net improvement --- src/m_menu.c | 20 ++++++++++++++------ src/m_menu.h | 4 +++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 946eaa9f4..0f6e1380e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -173,10 +173,15 @@ static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 skullAnimCounter = 10; // skull animation counter static tic_t followertimer = 0; // Used for smooth follower floating -static struct { +static struct +{ boolean active; const char *text; - void (*routine)(); + union + { + void (*routine)(INT32 choice); // MM_YESNO + void (*handler)(event_t *ev); // MM_EVENTHANDLER + }; menumessagetype_t messagetype; INT16 x, y; INT16 numlines; @@ -1065,8 +1070,8 @@ boolean M_Responder(event_t *ev) else { // dirty hack: for customising controls, I want only buttons/keys/axes, not mouse - if (messagebox.routine && !(ev->type == ev_mouse || (ev->type == ev_joystick && messagebox.routine != M_ChangecontrolResponse))) - messagebox.routine(ev); + if (messagebox.handler && !(ev->type == ev_mouse || (ev->type == ev_joystick && messagebox.handler != M_ChangecontrolResponse))) + messagebox.handler(ev); } return true; } @@ -2623,7 +2628,7 @@ static INT32 M_GetFirstLevelInList(void) // ================================================== // MESSAGE BOX (aka: a hacked, cobbled together menu) // ================================================== -void M_StartMessage(const char *string, void (*routine)(), +void M_StartMessage2(const char *string, void (*routine)(void), menumessagetype_t itemtype) { size_t max = 0, start = 0, i, strlines; @@ -2669,7 +2674,10 @@ void M_StartMessage(const char *string, void (*routine)(), messagebox.text = message; messagebox.messagetype = itemtype; - messagebox.routine = routine; + if (itemtype == MM_EVENTHANDLER) + messagebox.handler = (void (*)(event_t *))routine; + else + messagebox.routine = (void (*)(INT32))routine; //added : 06-02-98: now draw a textbox around the message // compute lenght max and the numbers of lines diff --git a/src/m_menu.h b/src/m_menu.h index 592dea54d..e73f6f47b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -139,7 +139,9 @@ typedef enum MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction // and routine is void routine(event_t *) (ex: set control) } menumessagetype_t; -void M_StartMessage(const char *string, void (*routine)(), menumessagetype_t itemtype); + +#define M_StartMessage(string, routine, itemtype) M_StartMessage2(string, (void (*)(void))routine, itemtype) +void M_StartMessage2(const char *string, void (*routine)(void), menumessagetype_t itemtype); typedef enum { From 3c3b509aa77506e00ef08418a0e97c6864f9da8d Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 26 Mar 2025 00:06:12 +0100 Subject: [PATCH 32/33] Remove M_MenuItemRange I don't like else-if chains, but I also don't like weird, unnecessary constraints --- src/m_menu.c | 110 ++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0f6e1380e..14c860168 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -273,18 +273,6 @@ static INT16 M_GetMenuIndex(menutype_t type, const char *name) #define M_GetItemY M_GetItemKey #define M_AdjustItemY(t, n, v) (M_GetMenuItem(t, n)->alphaKey += v) -// ensure there are numitems menuitems between name1 and name2 -// then return the index of name1 -static INT16 M_MenuItemRange(menutype_t type, const char *name1, const char *name2, INT16 numitems) -{ - INT16 index1 = M_GetMenuIndex(type, name1); - INT16 index2 = M_GetMenuIndex(type, name2); - INT16 range = index2 - index1 + 1; - if (range != numitems) - I_Error("Menu %d should have %d items between %s and %s inclusive, but %d were found", type, numitems, name1, name2, range); - return index1; -} - // bruh... static UINT32 M_ServersPerPage(void) { @@ -3974,7 +3962,6 @@ void M_SetPlaybackMenuPointer(void) void M_DrawPlaybackMenu(void) { INT16 i; - INT16 view1index = M_MenuItemRange(MN_PLAYBACK, "VIEW1", "VIEW4", 4); patch_t *icon; UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE); UINT32 transmap = max(0, (INT32)(leveltime - playback_last_menu_interaction_leveltime - 4*TICRATE)) / 5; @@ -3983,9 +3970,6 @@ void M_DrawPlaybackMenu(void) if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE) playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE; - INT16 rewindix = M_MenuItemRange(MN_PLAYBACK, "REWIND", "FASTFW", 3); - INT16 backix = M_MenuItemRange(MN_PLAYBACK, "REWFRA", "ADVFRA", 3); - // Toggle items if (paused && !demo.rewinding) { @@ -3996,12 +3980,12 @@ void M_DrawPlaybackMenu(void) M_SetItemStatus(MN_PLAYBACK, "ADVFRA", IT_CALL|IT_STRING); M_SetItemStatus(MN_PLAYBACK, "REWFRA", IT_CALL|IT_STRING); - if (itemOn >= rewindix && itemOn <= rewindix+2) - { - i = itemOn - rewindix; + if (M_IsItemOn(MN_PLAYBACK, "REWIND")) M_SetItemOn(MN_PLAYBACK, "REWFRA"); - itemOn += i; - } + else if (M_IsItemOn(MN_PLAYBACK, "PAUSE")) + M_SetItemOn(MN_PLAYBACK, "RESUME"); + else if (M_IsItemOn(MN_PLAYBACK, "FASTFW")) + M_SetItemOn(MN_PLAYBACK, "ADVFRA"); } else { @@ -4012,12 +3996,12 @@ void M_DrawPlaybackMenu(void) M_SetItemStatus(MN_PLAYBACK, "ADVFRA", IT_DISABLED); M_SetItemStatus(MN_PLAYBACK, "REWFRA", IT_DISABLED); - if (itemOn >= backix && itemOn <= backix+2) - { - i = itemOn - backix; + if (M_IsItemOn(MN_PLAYBACK, "REWFRA")) M_SetItemOn(MN_PLAYBACK, "REWIND"); - itemOn += i; - } + else if (M_IsItemOn(MN_PLAYBACK, "RESUME")) + M_SetItemOn(MN_PLAYBACK, "PAUSE"); + else if (M_IsItemOn(MN_PLAYBACK, "ADVFRA")) + M_SetItemOn(MN_PLAYBACK, "FASTFW"); } if (modeattacking) @@ -4053,7 +4037,11 @@ void M_DrawPlaybackMenu(void) { UINT8 *inactivemap = NULL; - INT16 splitnum = i - view1index; + INT16 splitnum = i == M_GetMenuIndex(MN_PLAYBACK, "VIEW1") ? 0 : + i == M_GetMenuIndex(MN_PLAYBACK, "VIEW2") ? 1 : + i == M_GetMenuIndex(MN_PLAYBACK, "VIEW3") ? 2 : + i == M_GetMenuIndex(MN_PLAYBACK, "VIEW4") ? 3 : -1; + if (splitnum >= 0 && splitnum < 4) { if (modeattacking) continue; @@ -4204,8 +4192,13 @@ void M_PlaybackSetViews(INT32 choice) void M_PlaybackAdjustView(INT32 choice) { - INT16 viewix = M_MenuItemRange(MN_PLAYBACK, "VIEW1", "VIEW4", 4); - G_AdjustView((itemOn - viewix)+1, (choice > 0) ? 1 : -1, true); + INT16 splitnum = M_IsItemOn(MN_PLAYBACK, "VIEW1") ? 1 : + M_IsItemOn(MN_PLAYBACK, "VIEW2") ? 2 : + M_IsItemOn(MN_PLAYBACK, "VIEW3") ? 3 : + M_IsItemOn(MN_PLAYBACK, "VIEW4") ? 4 : -1; + + if (splitnum >= 1 && splitnum <= 4) + G_AdjustView(splitnum, (choice > 0) ? 1 : -1, true); } // this one's rather tricky @@ -5504,6 +5497,32 @@ void M_StartGrandPrix(INT32 choice) // MODE ATTACK // =========== +// draw stuff "in the background" for time attack +static void M_DrawTimeAttackBackground(menuitem_t *item) +{ + INT16 x = currentMenu->x; + INT16 y = currentMenu->y+item->alphaKey; + consvar_t *ncv = item->itemaction.cvar; + V_DrawString(x, y, V_TRANSLUCENT, item->text); + if (item->status & IT_CV_STRING) + { + M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1); + V_DrawString(x + 40, y, V_TRANSLUCENT|V_ALLOWLOWERCASE, ncv->string); + } + else + { + const char *str = ((ncv == &cv_chooseskin) ? skins[cv_chooseskin.value-1].realname : ncv->string); + INT32 soffset = 40, strw = V_StringWidth(str, 0); + + // hack to keep the menu from overlapping the level icon + if (ncv == &cv_nextmap) + soffset = 0; + + // Should see nothing but strings + V_DrawString(BASEVIDWIDTH - x - soffset - strw, y, highlightflags|V_TRANSLUCENT, str); + } +} + // Drawing function for Time Attack void M_DrawTimeAttackMenu(void) { @@ -5616,37 +5635,12 @@ void M_DrawTimeAttackMenu(void) } // ALWAYS DRAW player name, level name, skin and color even when not on this menu! - // TODO: this whole thing needs to go - menu_t *tamenu = menudefs[MN_SP_TIMEATTACK]; if (menustack[0] != MN_SP_TIMEATTACK) { - consvar_t *ncv; - INT16 first = M_MenuItemRange(MN_SP_TIMEATTACK, "NAME", "LEVEL", 4); - menuitem_t *taitems = tamenu->menuitems; - - for (i = first; i < first+4; ++i) - { - y = currentMenu->y+taitems[i].alphaKey; - V_DrawString(x, y, V_TRANSLUCENT, taitems[i].text); - ncv = taitems[i].itemaction.cvar; - if (taitems[i].status & IT_CV_STRING) - { - M_DrawTextBox(x + 32, y - 8, MAXPLAYERNAME, 1); - V_DrawString(x + 40, y, V_TRANSLUCENT|V_ALLOWLOWERCASE, ncv->string); - } - else - { - const char *str = ((ncv == &cv_chooseskin) ? skins[cv_chooseskin.value-1].realname : ncv->string); - INT32 soffset = 40, strw = V_StringWidth(str, 0); - - // hack to keep the menu from overlapping the level icon - if (ncv == &cv_nextmap) - soffset = 0; - - // Should see nothing but strings - V_DrawString(BASEVIDWIDTH - x - soffset - strw, y, highlightflags|V_TRANSLUCENT, str); - } - } + M_DrawTimeAttackBackground(M_GetMenuItem(MN_SP_TIMEATTACK, "NAME")); + M_DrawTimeAttackBackground(M_GetMenuItem(MN_SP_TIMEATTACK, "SKIN")); + M_DrawTimeAttackBackground(M_GetMenuItem(MN_SP_TIMEATTACK, "COLOR")); + M_DrawTimeAttackBackground(M_GetMenuItem(MN_SP_TIMEATTACK, "LEVEL")); } } From 4b3b96536d59d1fd672b5d23029b77e0bee8dc2d Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Wed, 26 Mar 2025 18:53:21 +0100 Subject: [PATCH 33/33] Expose gc_respawn --- src/deh_tables.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 270fd2cd5..ab4f4d6fd 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1403,6 +1403,7 @@ struct int_const_s const INT_CONST[] = { {"GC_CUSTOM1",gc_custom1}, {"GC_CUSTOM2",gc_custom2}, {"GC_CUSTOM3",gc_custom3}, + {"GC_RESPAWN",gc_respawn}, {"NUM_GAMECONTROLS",num_gamecontrols}, // screen.h constants