diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index b6ad0e17e..7d9cd67ec 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -17,6 +17,11 @@ #include "byteptr.h" #include "z_zone.h" +#include "d_netfil.h" + +#include "m_menu.h" +#include "w_wad.h" + #include "lua_script.h" #include "lua_libs.h" #include "lua_hud.h" // hud_running errors @@ -186,8 +191,8 @@ static int lib_comAddCommand(lua_State *L) const char *luaname = luaL_checkstring(L, 1); // must store in all lowercase - char *name = Z_StrDup(luaname); - strlwr(name); + char *comname = Z_StrDup(luaname); + strlwr(comname); luaL_checktype(L, 2, LUA_TFUNCTION); NOHUD @@ -220,25 +225,26 @@ static int lib_comAddCommand(lua_State *L) lua_pushvalue(L, 3); lua_rawseti(L, -2, 2); - lua_setfield(L, -2, name); + lua_setfield(L, -2, comname); // Try to add the Lua command - com_return = COM_AddLuaCommand(name); + com_return = COM_AddLuaCommand(comname); if (com_return < 0) { // failed to add -- free the lowercased name and return error - Z_Free(name); + Z_Free(comname); return luaL_error(L, "Couldn't add a new console command \"%s\"", luaname); } else if (com_return == 1) { // command existed already -- free our name as the old string will continue to be used - CONS_Printf("Replaced command \"%s\"\n", name); - Z_Free(name); + CONS_Printf("Replaced command \"%s\"\n", comname); + Z_Free(comname); } else { // new command was added -- do NOT free the string as it will forever be used by the console - CONS_Printf("Added command \"%s\"\n", name); + CONS_Printf("Added command \"%s\"\n", comname); } + return 0; } @@ -314,6 +320,10 @@ static int lib_cvRegisterVar(lua_State *L) const char *k; lua_Integer i; consvar_t *cvar; + + const char* category = NULL; + const char* menu_name = NULL; + luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. NOHUD @@ -405,6 +415,18 @@ static int lib_cvRegisterVar(lua_State *L) lua_pop(L, 1); cvar->func = Lua_OnChange; } + else if (((i == 5 && !(cvar->flags & CV_CALL)) + || (cvar->flags & CV_CALL && i == 6)) + || (k && fasticmp(k, "category"))) + { + category = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4); + } + else if (((i == 6 && !(cvar->flags & CV_CALL)) + || (cvar->flags & CV_CALL && i == 7)) + || (k && fasticmp(k, "menuname"))) + { + menu_name = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4); + } lua_pop(L, 1); } #undef FIELDERROR @@ -429,6 +451,22 @@ static int lib_cvRegisterVar(lua_State *L) if (cvar->flags & CV_MODIFIED) return luaL_error(L, "failed to register cvar (probable conflict with internal variable/command names)"); + if (!(((cvar->flags & CV_HIDEN)) || (cvar->flags & CV_NOSHOWHELP)) && (cvar->PossibleValue || !(cvar->value == 0 && stricmp(cvar->string, "0")))) + { + if (!category) + { + char *temp = strdup(wadfiles[numwadfiles - 1]->filename); + nameonly(temp); + + category = temp; + } + + if (menu_name && menu_name[0] != '\0') + M_SlotCvarIntoModMenu(cvar, category, menu_name); + else + M_SlotCvarIntoModMenu(cvar, category, cvar->name); + } + // return cvar userdata return 1; } @@ -599,4 +637,4 @@ int LUA_ConsoleLib(lua_State *L) lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_register(L, NULL, lib); return 0; -} \ No newline at end of file +} diff --git a/src/m_menu.c b/src/m_menu.c index 10a3ca403..939d54fb6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -50,6 +50,10 @@ #include "p_setup.h" #include "f_finale.h" +#include "lua_libs.h" + +#include "fastcmp.h" + #include "qs22j.h" #ifdef HWRENDER @@ -304,6 +308,7 @@ static void M_SetupMultiHandler(INT32 choice); menu_t OP_ControlsDef, OP_AllControlsDef; menu_t OP_MouseOptionsDef, OP_Mouse2OptionsDef; menu_t OP_Joystick1Def, OP_Joystick2Def, OP_Joystick3Def, OP_Joystick4Def; +menu_t OP_CustomCvarMenuDef; static void M_VideoModeMenu(INT32 choice); static void M_Setup1PControlsMenu(INT32 choice); static void M_Setup2PControlsMenu(INT32 choice); @@ -348,6 +353,8 @@ static void M_AddonsInternal(); static void M_Addons(INT32 choice); static void M_LocalSkins(INT32 choice); static void M_AddonsOptions(INT32 choice); + +static void M_CustomCvarMenu(INT32 choice); static patch_t *addonsp[NUM_EXT+5]; static void M_DeleteProtocol(void); @@ -1098,6 +1105,8 @@ static menuitem_t OP_MainMenu[] = {IT_SUBMENU|IT_STRING, NULL, "Data Options...", &OP_DataOptionsDef, 90}, + {IT_CALL|IT_STRING, NULL, "Custom Options...", M_CustomCvarMenu, 100}, + {IT_CALL|IT_STRING, NULL, "Tricks & Secrets (F1)", M_Manual, 110}, {IT_CALL|IT_STRING, NULL, "Play Credits", M_Credits, 120}, @@ -2392,6 +2401,8 @@ enum syncspecialonly, }; +menuitem_t OP_CustomCvarMenu[MAXMENUCCVARS]; + // ========================================================================== // ALL MENU DEFINITIONS GO HERE // ========================================================================== @@ -2891,6 +2902,23 @@ menu_t OP_DriftGaugeDef = DEFAULTMENUSTYLE(NULL, OP_DriftGaugeMenu, &OP_SaturnDe menu_t OP_TiltDef = DEFAULTMENUSTYLE(NULL, OP_TiltMenu, &OP_BirdDef, 30, 60); menu_t OP_AdvancedBirdDef = DEFAULTMENUSTYLE(NULL, OP_AdvancedBirdMenu, &OP_BirdDef, 30, 60); +INT16 ccvarposition = 0; + +static void M_CustomCvarMenu(INT32 choice) +{ + (void)choice; + + if (ccvarposition) + M_SetupNextMenu(&OP_CustomCvarMenuDef); + else + M_StartMessage(M_GetText("No custom options were found\n"), NULL, MM_NOTHING); +} + +/*menu_t OP_CustomCvarMenuDef = DEFAULTSCROLLMENUSTYLE( + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS), + "M_ADDONS", OP_CustomCvarMenu, &OP_MainDef, 30, 30);*/ +menu_t OP_CustomCvarMenuDef = DEFAULTSCROLLSTYLE("M_ADDONS", OP_CustomCvarMenu, &OP_MainDef, 10, 30); + menu_t OP_ForkedBirdDef = { NULL, sizeof(OP_ForkedBirdMenu)/sizeof(menuitem_t), @@ -7777,6 +7805,54 @@ void M_PopupMasterServerRules(void) #endif } +#define CCVHEIGHT 5 +#define CCVHEIGHTHEADER 1 +#define CCVHEIGHTHEADERAFTER 6 + +UINT16 ccvaralphakey = 4; +INT16 ccvarlaststheader = 0; + +INT32 CVARSETUP; + +void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* name) +{ + if (ccvarposition == INT16_MAX) + return; + + if (ccvarposition >= MAXMENUCCVARS - 2) + { + CONS_Printf("failed to register cvar into custom settings menu as menu reached limit\n"); + ccvarposition = INT16_MAX; + return; + } + + if (!CVARSETUP) + { + CONS_Printf("custom settings menu initiation\n"); + for (CVARSETUP = 0; CVARSETUP < MAXMENUCCVARS; ++CVARSETUP) + OP_CustomCvarMenu[CVARSETUP] = (menuitem_t){IT_DISABLED, NULL, "", 0, INT16_MAX}; + } + + if (category && ((ccvarposition == 0 && category[0] != '\0') || !fasticmp(category, OP_CustomCvarMenu[ccvarlaststheader].text))) + { + ccvarlaststheader = ccvarposition; + ccvaralphakey += CCVHEIGHTHEADER; + + OP_CustomCvarMenu[ccvarposition] = (menuitem_t){IT_HEADER, NULL, Z_StrDup(category), NULL, ccvaralphakey}; + ccvaralphakey += CCVHEIGHTHEADERAFTER; + + ++ccvarposition; + } + + if (cvar->flags & CV_NETVAR) + OP_CustomCvarMenu[ccvarposition] = (menuitem_t){ IT_STRING | IT_CVAR , NULL, Z_StrDup(va("\x85 %s", name)), cvar, ccvaralphakey }; + else + OP_CustomCvarMenu[ccvarposition] = (menuitem_t){ IT_STRING | IT_CVAR, NULL, Z_StrDup(name), cvar, ccvaralphakey }; + + ccvaralphakey += CCVHEIGHT; + ++ccvarposition; +} + // ====== // CHEATS // ====== diff --git a/src/m_menu.h b/src/m_menu.h index 8d1ebb723..485f7f7a1 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -147,6 +147,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define MAXSTRINGLENGTH 32 +#define MAXMENUCCVARS 999 + #define MAXTOOLTIPS 255 typedef union @@ -171,7 +173,7 @@ typedef struct menuitem_s void *itemaction; // hotkey in menu or y of the item - UINT8 alphaKey; + UINT16 alphaKey; } menuitem_t; extern menuitem_t PlayerMenu[MAXSKINS]; @@ -289,6 +291,8 @@ void M_PopupMasterServerRules(void); void M_PopupMasterServerConnectError(void); #endif +void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* name); + // These defines make it a little easier to make menus #define DEFAULTMENUSTYLE(header, source, prev, x, y)\ {\ @@ -316,6 +320,7 @@ void M_PopupMasterServerConnectError(void); NULL\ } + #define PAUSEMENUSTYLE(source, x, y)\ {\ NULL,\