diff --git a/src/menus/transient/pause-cheats.cpp b/src/menus/transient/pause-cheats.cpp index 92d9a1a1b..a12f3b235 100644 --- a/src/menus/transient/pause-cheats.cpp +++ b/src/menus/transient/pause-cheats.cpp @@ -19,22 +19,86 @@ #include "../../command.h" #include "../../doomtype.h" +#include "../../k_hud.h" #include "../../k_menu.h" #include "../../screen.h" +extern "C" void COM_Lua_f(void); + using srb2::Draw; namespace { +enum Mode +{ + kCvars, + kCommands, + kNumModes +}; + +const char* mode_strings[kNumModes] = { + "Options", + "Commands", +}; + std::vector g_menu; std::vector g_menu_offsets; +int g_menu_cursors[kNumModes]; -void sort_menu() +int menu_mode() { - std::sort(g_menu.begin(), g_menu.end(), - [](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; }); + return PAUSE_CheatsDef.extra1; +} +void menu_mode(int mode) +{ + g_menu_cursors[menu_mode()] = itemOn; + + PAUSE_CheatsDef.extra1 = mode; + + itemOn = g_menu_cursors[menu_mode()]; +} + +void list_cvars() +{ + for (consvar_t* var = consvar_vars; var; var = var->next) + { + if (!(var->flags & CV_CHEAT)) + { + continue; + } + + UINT16 status = IT_STRING | IT_CVAR; + INT32 height = 8; + + if (!var->PossibleValue && !(var->flags & CV_FLOAT)) + { + status |= IT_CV_STRING; + height += 16; + } + + g_menu.push_back(menuitem_t {status, var->name, var->description, nullptr, {.cvar = var}, 0, height}); + } +} + +void list_commands() +{ + static const auto call = [](INT32 idx) { COM_ImmedExecute(currentMenu->menuitems[idx].text); }; + + for (xcommand_t* cmd = com_commands; cmd; cmd = cmd->next) + { + if (!(cmd->debug || cmd->function == COM_Lua_f)) + { + continue; + } + + g_menu.push_back(menuitem_t {IT_STRING | IT_CALL, cmd->name, nullptr, nullptr, {.routine = call}, 0, 8}); + } +} + +void group_menu() +{ int old_key = '\0'; // Can't use range-for because iterators are invalidated @@ -73,26 +137,21 @@ void menu_open() g_menu = {}; g_menu_offsets = {}; - for (consvar_t* var = consvar_vars; var; var = var->next) + switch (menu_mode()) { - if (!(var->flags & CV_CHEAT)) - { - continue; - } + case kCvars: + list_cvars(); + break; - UINT16 status = IT_STRING | IT_CVAR; - INT32 height = 8; - - if (!var->PossibleValue && !(var->flags & CV_FLOAT)) - { - status |= IT_CV_STRING; - height += 16; - } - - g_menu.push_back(menuitem_t {status, var->name, nullptr, nullptr, {.cvar = var}, 0, height}); + case kCommands: + list_commands(); + break; } - sort_menu(); + std::sort(g_menu.begin(), g_menu.end(), + [](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; }); + + group_menu(); INT32 y = 0; @@ -117,26 +176,43 @@ boolean menu_close() return true; } +boolean menu_input(INT32) +{ + // C button: cycle through modes + if (M_MenuButtonPressed(0, MBT_Y)) + { + menu_mode((menu_mode() + 1) % kNumModes); + + // reload menu + menu_open(); + } + + return false; +} + void draw_menu() { - auto tooltip = Draw(0, 0); + constexpr int kMargin = 4; - tooltip.patch("MENUHINT"); + Draw draw = Draw(0, 0).align(Draw::Align::kCenter); + + draw.patch("MENUHINT"); const menuitem_t& item = currentMenu->menuitems[itemOn]; - if (const consvar_t* cvar = item.itemaction.cvar; cvar && cvar->description) + if (item.tooltip) { - tooltip.xy(BASEVIDWIDTH/2, 12).font(Draw::Font::kThin).align(Draw::Align::kCenter).text(cvar->description); + draw.xy(BASEVIDWIDTH/2, 12).font(Draw::Font::kThin).text(item.tooltip); } + draw = draw.y(27 + kMargin); - constexpr int kTooltipHeight = 27; - constexpr int kPad = 4; - int y = tooltip.y() + kTooltipHeight + kPad; + draw.x(BASEVIDWIDTH/2).font(Draw::Font::kGamemode).text(mode_strings[menu_mode()]); + K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y)); + draw = draw.y(32 + kMargin); - currentMenu->y = std::min(y, (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]); + currentMenu->y = std::min(static_cast(draw.y()), (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]); - V_SetClipRect(0, y * FRACUNIT, BASEVIDWIDTH * FRACUNIT, (BASEVIDHEIGHT - y - kPad) * FRACUNIT, 0); + V_SetClipRect(0, draw.y() * FRACUNIT, BASEVIDWIDTH * FRACUNIT, (BASEVIDHEIGHT - draw.y() - kMargin) * FRACUNIT, 0); M_DrawGenericMenu(); V_ClearClipRect(); } @@ -149,7 +225,7 @@ menu_t PAUSE_CheatsDef = { 0, nullptr, 48, 0, - 0, 0, + kCvars, 0, MBF_SOUNDLESS, nullptr, 0, 0, @@ -157,5 +233,5 @@ menu_t PAUSE_CheatsDef = { nullptr, menu_open, menu_close, - nullptr, + menu_input, };