Expanded styles (ITF_THIN2 and IT_RIGHT), rename CvarSlider to Slider

This commit is contained in:
GenericHeroGuy 2025-06-16 21:11:14 +02:00
parent 955da518ca
commit 11b9cd993d
3 changed files with 95 additions and 68 deletions

View file

@ -1863,6 +1863,38 @@ static struct { const char *name; consvar_t *var; } HIDDENVARS[] = {
{ NULL, NULL }
};
// parses an item style in the form of "<font>-SMALL-<align>-HIGHLIGHT"
// each component is optional, and the style cannot be written in arbitrary order
// returns IT_HIDDEN if style is invalid
static menuitemflags_t parsestyle(const char *p)
{
menuitemflags_t style = 0;
// yeah yeah, macro hell, but it's more economical than 100 entries in a table
#define STYLE(string, flag) \
(!strncmp(p, string, sizeof(string)-1)) { \
style |= flag; \
p += sizeof(string)-1; \
if (*p == '\0') return style; \
if (*p++ != '-') return IT_HIDDEN; \
}
if STYLE("THIN2", ITF_THIN2)
else if STYLE("THIN", ITF_THIN)
else if STYLE("HEADER", ITF_HEADER|IT_HIGHLIGHT)
else if STYLE("PATCH", IT_PATCH)
if STYLE("SMALL", IT_SMALL)
if STYLE("CENTER", IT_CENTER)
else if STYLE("RIGHT", IT_RIGHT)
if STYLE("HIGHLIGHT", IT_HIGHLIGHT)
return IT_HIDDEN;
#undef STYLE
}
#define WARN(str, ...) deh_warning("MenuItem %s: " str, strbuf_get(menunames, menuitem->info.nameofs), __VA_ARGS__)
#define WARN0(str) deh_warning("MenuItem %s: " str, strbuf_get(menunames, menuitem->info.nameofs))
static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
@ -1872,7 +1904,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
char *word2;
char *tmp;
UINT16 status = 0;
menuitemflags_t status = 0;
// taking quite possibly the only opportunity i'll ever get
// to avoid three tabs of indentation...
@ -1948,46 +1980,21 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
}
else if (fastcmp(word, "STYLE"))
{
menuitemflags_t style = 0;
if (status & IT_STYLE)
{
WARN0("style already set!");
continue;
}
if (fasticmp(word2, "HEADER"))
status |= IT_HEADER|IT_HIGHLIGHT;
else if (fasticmp(word2, "HIGHLIGHT"))
status |= IT_HIGHLIGHT;
else if (fasticmp(word2, "CENTER"))
status |= IT_CENTER;
else if (fasticmp(word2, "CENTER-HIGHLIGHT"))
status |= IT_CENTER|IT_HIGHLIGHT;
else if (fasticmp(word2, "THIN"))
status |= IT_THIN;
else if (fasticmp(word2, "THIN-HIGHLIGHT"))
status |= IT_THIN|IT_HIGHLIGHT;
else if (fasticmp(word2, "PATCH"))
status |= IT_PATCH;
else if (fasticmp(word2, "PATCH-CENTER"))
status |= IT_PATCH|IT_CENTER;
else if (fasticmp(word2, "PATCH-SMALL"))
status |= IT_PATCH|IT_SMALL;
else if (fasticmp(word2, "PATCH-HIGHLIGHT"))
status |= IT_PATCH|IT_HIGHLIGHT;
else
strupr(word2);
style = parsestyle(word2);
if (style == IT_HIDDEN)
WARN("unknown style '%s'", word2);
else
status |= style;
}
else if (fastncmp(word, "CVAR", 4))
else if (fastcmp(word, "CVAR") || fastcmp(word, "SLIDER"))
{
UINT16 flags = IT_INTERACT;
if (fastcmp(word+4, "SLIDER"))
flags |= IT_SLIDER;
else if (word[4])
{
WARN("unknown word '%s'", word);
continue;
}
consvar_t *cvar = CV_FindVar(word2);
if (!cvar)
for (size_t i = 0; HIDDENVARS[i].name; i++)
@ -2001,7 +2008,9 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
WARN("unable to find cvar '%s'", word2);
continue;
}
status |= flags;
status |= IT_INTERACT;
if (word[0] == 'S')
status |= IT_SLIDER;
menuitem->cvar = cvar;
}
else if (fastcmp(word, "SUBMENU"))
@ -2017,17 +2026,15 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
}
else if (fastcmp(word, "CALL") || fastcmp(word, "ARROWS"))
{
UINT16 flags = IT_INTERACT;
if (word[0] == 'A')
flags |= IT_ARROWS;
menufunc_f *routine = get_menuroutine(word2);
if (!routine)
{
WARN("unknown call routine '%s'", word2);
continue;
}
status |= flags;
status |= IT_INTERACT;
if (word[0] == 'A')
status |= IT_ARROWS;
menuitem->routine = routine;
}
else

View file

@ -268,7 +268,7 @@ static INT16 M_GetMenuIndex(menutype_t type, const char *name)
#define M_SetItemY(t, n, v) (M_GetMenuItem(t, n)->y = v)
#define M_GetItemY(t, n) (M_GetMenuItem(t, n)->y)
static void M_ChangeItemStatus(menutype_t type, const char *name, UINT16 flag, boolean cond)
static void M_ChangeItemStatus(menutype_t type, const char *name, menuitemflags_t flag, boolean cond)
{
if (cond)
M_GetMenuItem(type, name)->status |= flag;
@ -2204,12 +2204,14 @@ static void M_DrawRightString(menuitem_t *item, INT16 x, INT16 y, INT32 vflags,
}
}
static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, boolean selected)
// draws a menu item, returns cursor offset
static INT32 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, boolean selected)
{
INT32 width = 0;
const char *string = item->text ? item->text : "";
fixed_t scale = item->status & IT_SMALL ? FRACUNIT/2 : FRACUNIT;
int font = HU_FONT;
INT32 (*widthfunc)(const char *string, INT32 option) = V_StringWidth;
int font;
INT32 (*widthfunc)(const char *string, INT32 option);
if (item->status & IT_SECRET)
{
@ -2229,32 +2231,45 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo
UINT8 *cmap = NULL;
if (item->status & IT_CENTER)
x -= SHORT(p->width)/2;
width = SHORT(p->width)/2;
else if (item->status & IT_RIGHT)
width = SHORT(p->width);
if (item->status & IT_HIGHLIGHT)
cmap = V_GetStringColormap(highlightflags);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, vflags & ~V_FLIP, p, cmap);
return SHORT(p->width);
V_DrawFixedPatch((x - width)<<FRACBITS, y<<FRACBITS, scale, vflags & ~V_FLIP, p, cmap);
return width;
}
if (item->status & IT_THIN)
switch (item->status & ITF_MASK)
{
case ITF_THIN2:
vflags |= V_6WIDTHSPACE; // FALLTHRU
case ITF_THIN:
font = TINY_FONT;
vflags |= V_6WIDTHSPACE; // TODO: make this a style?
widthfunc = V_ThinStringWidth;
break;
case ITF_HEADER:
x -= 16; // FALLTHRU
default:
font = HU_FONT;
widthfunc = V_StringWidth;
break;
}
if (item->status & IT_CENTER)
x -= widthfunc(string, vflags)/2;
if (item->status & IT_HEADER)
x -= 16;
width = widthfunc(string, vflags)/2;
else if (item->status & IT_RIGHT)
width = widthfunc(string, vflags);
V_DrawStringScaled(x<<FRACBITS, y<<FRACBITS, scale, FRACUNIT, FRACUNIT, (selected || item->status & IT_HIGHLIGHT ? highlightflags : 0)|vflags, font, string);
V_DrawStringScaled((x - width)<<FRACBITS, y<<FRACBITS, scale, FRACUNIT, FRACUNIT, (selected || item->status & IT_HIGHLIGHT ? highlightflags : 0)|vflags, font, string);
if (!(item->status & (IT_SECRET|IT_GRAYEDOUT)))
M_DrawRightString(item, x, y, vflags, selected);
return widthfunc(string, vflags);
return width;
}
// gets the absolute Y coordinate where this menuitem should be drawn (in a broken way)
@ -2359,7 +2374,7 @@ void M_DrawGenericMenu(void)
if (i == itemOn)
{
cursory = y;
cursorx = x - (item->status & IT_CENTER ? w/2 : 0) - 24 + currentMenu->cursoroffset;
cursorx = x - w - 24 + currentMenu->cursoroffset;
}
nodraw:

View file

@ -172,11 +172,17 @@ typedef enum
IT_PATCH = 1<<10, // display a patch instead of text
IT_CENTER = 1<<11, // center the text/patch
IT_SMALL = 1<<12, // draw at half scale
IT_THIN = 1<<13, // thin font
IT_RIGHT = 1<<12, // right-align the text/patch
IT_SMALL = 1<<13, // draw at half scale
IT_HIGHLIGHT = 1<<14, // add highlightflags to text/patch
IT_HEADER = 1<<15, // draw with an offset to the left
IT_STYLE = IT_PATCH|IT_CENTER|IT_SMALL|IT_THIN|IT_HIGHLIGHT|IT_HEADER,
ITF_STANDARD = 0<<15, // standard font
ITF_HEADER = 1<<15, // standard font, with an offset to the left
ITF_THIN = 2<<15, // thin font
ITF_THIN2 = 3<<15, // thin font with tighter spacing
ITF_MASK = 3<<15,
IT_STYLE = IT_PATCH|IT_CENTER|IT_RIGHT|IT_SMALL|IT_HIGHLIGHT|ITF_MASK,
} menuitemflags_t;
#define MAXSTRINGLENGTH 32
@ -191,19 +197,18 @@ struct menuitem_t
{
dehinfo_t info;
// show IT_xxx
UINT16 status;
char *text; // left-side string
char *patch; // name of patch lump to draw, OR right-side string
char *tooltip; // help text displayed at bottom
menutype_t submenu; // IT_SUBMENU
consvar_t *cvar; // IT_CVAR
menufunc_f *routine; // IT_CALL, IT_ARROWS
consvar_t *cvar; // console variable to modify
menufunc_f *routine; // menu routine to call
menutype_t submenu; // navigate to another menu
const char *patch;
const char *text; // used when FONTBxx lump is found
const char *tooltip;
menuitemflags_t status; // show IT_xxx
INT32 argument;
INT16 x, y;
INT32 argument; // passed to routine/submenu, OR step size for cvars
INT16 x, y; // coordinates, see menuitemflags
};
struct menu_t