Cheats menu: press Y to switch between cvars and commands

- Show a subset of commands:
  - Commands registered by COM_AddDebugCommand
  - Commands registered by Lua
This commit is contained in:
James R 2023-08-27 01:25:45 -07:00 committed by toaster
parent 9dc277bc3d
commit f30763ce1d

View file

@ -19,22 +19,86 @@
#include "../../command.h" #include "../../command.h"
#include "../../doomtype.h" #include "../../doomtype.h"
#include "../../k_hud.h"
#include "../../k_menu.h" #include "../../k_menu.h"
#include "../../screen.h" #include "../../screen.h"
extern "C" void COM_Lua_f(void);
using srb2::Draw; using srb2::Draw;
namespace namespace
{ {
enum Mode
{
kCvars,
kCommands,
kNumModes
};
const char* mode_strings[kNumModes] = {
"Options",
"Commands",
};
std::vector<menuitem_t> g_menu; std::vector<menuitem_t> g_menu;
std::vector<INT32> g_menu_offsets; std::vector<INT32> g_menu_offsets;
int g_menu_cursors[kNumModes];
void sort_menu() int menu_mode()
{ {
std::sort(g_menu.begin(), g_menu.end(), return PAUSE_CheatsDef.extra1;
[](menuitem_t& a, menuitem_t& b) { return std::strcmp(a.text, b.text) < 0; }); }
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'; int old_key = '\0';
// Can't use range-for because iterators are invalidated // Can't use range-for because iterators are invalidated
@ -73,26 +137,21 @@ void menu_open()
g_menu = {}; g_menu = {};
g_menu_offsets = {}; g_menu_offsets = {};
for (consvar_t* var = consvar_vars; var; var = var->next) switch (menu_mode())
{ {
if (!(var->flags & CV_CHEAT)) case kCvars:
{ list_cvars();
continue; break;
}
UINT16 status = IT_STRING | IT_CVAR; case kCommands:
INT32 height = 8; list_commands();
break;
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});
} }
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; INT32 y = 0;
@ -117,26 +176,43 @@ boolean menu_close()
return true; 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() 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]; 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; draw.x(BASEVIDWIDTH/2).font(Draw::Font::kGamemode).text(mode_strings[menu_mode()]);
constexpr int kPad = 4; K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
int y = tooltip.y() + kTooltipHeight + kPad; draw = draw.y(32 + kMargin);
currentMenu->y = std::min(y, (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]); currentMenu->y = std::min(static_cast<int>(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(); M_DrawGenericMenu();
V_ClearClipRect(); V_ClearClipRect();
} }
@ -149,7 +225,7 @@ menu_t PAUSE_CheatsDef = {
0, 0,
nullptr, nullptr,
48, 0, 48, 0,
0, 0, kCvars, 0,
MBF_SOUNDLESS, MBF_SOUNDLESS,
nullptr, nullptr,
0, 0, 0, 0,
@ -157,5 +233,5 @@ menu_t PAUSE_CheatsDef = {
nullptr, nullptr,
menu_open, menu_open,
menu_close, menu_close,
nullptr, menu_input,
}; };