Three(!?) new methods for placing menu items
Relative: changes the coordinates relative to the current ones Temporary relative: displaces the coordinates temporarily Overlay: draws at absolute coordinates, no clipping Along with custom cursor offsets and Item Styles(tm), this eliminates M_DrawControl
This commit is contained in:
parent
fd48ecd4ca
commit
f30ddcfad2
4 changed files with 114 additions and 55 deletions
|
|
@ -1908,10 +1908,28 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
|
|||
{
|
||||
menuitem->x = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "OFSX"))
|
||||
{
|
||||
menuitem->x = get_number(word2);
|
||||
status |= IT_OFSX;
|
||||
}
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
menuitem->y = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "OFSY"))
|
||||
{
|
||||
menuitem->y = get_number(word2);
|
||||
status |= IT_OFSY;
|
||||
}
|
||||
else if (fastcmp(word, "OVERLAY"))
|
||||
{
|
||||
status |= IT_OVERLAY;
|
||||
}
|
||||
else if (fastcmp(word, "TEMPOFFSET"))
|
||||
{
|
||||
status |= IT_TEMPORARY;
|
||||
}
|
||||
else if (fastcmp(word, "ARGUMENT"))
|
||||
{
|
||||
menuitem->argument = get_number(word2);
|
||||
|
|
@ -1924,6 +1942,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
|
|||
{
|
||||
menuitem->tooltip = Z_StrDup(word2);
|
||||
}
|
||||
else if (fastcmp(word, "STYLE"))
|
||||
{
|
||||
if (fasticmp(word2, "CENTER"))
|
||||
status |= IT_CENTER;
|
||||
else
|
||||
WARN("unknown style '%s'", word2);
|
||||
}
|
||||
else if (fastncmp(word, "TEXT", 4))
|
||||
{
|
||||
UINT16 flags = IT_STRING;
|
||||
|
|
@ -1952,8 +1977,8 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
|
|||
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 (fastcmp(word+4, "INTEGER"))
|
||||
//flags |= IT_CV_INTEGERSTEP;
|
||||
else if (word[4])
|
||||
{
|
||||
WARN("unknown word '%s'", word);
|
||||
|
|
@ -1984,7 +2009,6 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
|
|||
WARN("unknown menu '%s'", word2);
|
||||
continue;
|
||||
}
|
||||
status |= IT_SUBMENU;
|
||||
menuitem->submenu = mn;
|
||||
}
|
||||
else if (fastcmp(word, "CALL") || fastcmp(word, "ARROWS"))
|
||||
|
|
@ -2256,6 +2280,14 @@ void readmenu(MYFILE *f, INT32 num)
|
|||
{
|
||||
menudef->scrollheight = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "CURSOROFFSET"))
|
||||
{
|
||||
menudef->cursoroffset = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "LINEHEIGHT"))
|
||||
{
|
||||
menudef->lineheight = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ENTERROUTINE"))
|
||||
{
|
||||
menufunc_f *routine = get_menuroutine(word2);
|
||||
|
|
@ -2291,6 +2323,10 @@ void readmenu(MYFILE *f, INT32 num)
|
|||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
// default line height
|
||||
if (!menudef->lineheight)
|
||||
menudef->lineheight = 8;
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
#undef WARN
|
||||
|
|
|
|||
|
|
@ -772,7 +772,6 @@ struct menu_drawer_s const MENU_DRAWERS[] = {
|
|||
{ "DRAWPLAYBACKMENU", &M_DrawPlaybackMenu },
|
||||
{ "DRAWIMAGEDEF", &M_DrawImageDef },
|
||||
{ "DRAWMUSICTEST", &M_DrawMusicTest },
|
||||
{ "DRAWCONTROL", &M_DrawControl },
|
||||
{ "DRAWJOYSTICK", &M_DrawJoystick },
|
||||
{ "DRAWMONITORTOGGLES", &M_DrawMonitorToggles },
|
||||
{ "DRAWCONNECTMENU", &M_DrawConnectMenu },
|
||||
|
|
|
|||
113
src/m_menu.c
113
src/m_menu.c
|
|
@ -102,7 +102,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
|
||||
#include "qs22j.h"
|
||||
|
||||
#define LINEHEIGHT 8
|
||||
#define SLIDER_RANGE 10
|
||||
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
|
||||
#define MAXIPADDRESSLEN 28
|
||||
|
|
@ -283,7 +282,7 @@ static void M_ChangeItemStatus(menutype_t type, const char *name, UINT16 flag, b
|
|||
|
||||
static boolean M_ItemSelectable(menuitem_t *item)
|
||||
{
|
||||
return !(item->status & (IT_HIDDEN|IT_GRAYEDOUT|IT_SECRET)) && (item->status & IT_TYPE);
|
||||
return !(item->status & (IT_HIDDEN|IT_GRAYEDOUT|IT_SECRET)) && (item->submenu || item->routine || item->cvar);
|
||||
}
|
||||
|
||||
// bruh...
|
||||
|
|
@ -832,14 +831,14 @@ static INT32 M_ChangeCvar(INT32 choice)
|
|||
}
|
||||
else if (cv->flags & CV_FLOAT)
|
||||
{
|
||||
if (!(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP))
|
||||
/*if (!(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP))
|
||||
{
|
||||
char s[20];
|
||||
float n = FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f);
|
||||
sprintf(s,"%ld%s",(long)n,M_Ftrim(n));
|
||||
CV_Set(cv,s);
|
||||
}
|
||||
else
|
||||
else*/
|
||||
CV_SetValue(cv,FIXED_TO_FLOAT(cv->value)+(choice));
|
||||
}
|
||||
else
|
||||
|
|
@ -2102,7 +2101,7 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo
|
|||
break;
|
||||
case IT_STRING:
|
||||
case IT_WHITESTRING:
|
||||
if (vflags & MDF_CENTERED)
|
||||
if (vflags & MDF_CENTERED || item->status & IT_CENTER)
|
||||
V_DrawCenteredString(x, y, vflags|highlight, string);
|
||||
else
|
||||
V_DrawString(x, y, vflags|highlight, string);
|
||||
|
|
@ -2225,7 +2224,7 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo
|
|||
}
|
||||
break;
|
||||
case IT_HEADERTEXT: // draws 16 pixels to the left, in yellow text
|
||||
V_DrawString(x - (vflags & MDF_CONTROLS ? 7 : 16), y - (vflags & MDF_CONTROLS ? 2 : 0), vflags|highlight, string);
|
||||
V_DrawString(x - 16, y, vflags|highlight, string);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -2234,12 +2233,22 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo
|
|||
return V_StringWidth(string, vflags);
|
||||
}
|
||||
|
||||
// gets the absolute Y coordinate where this menuitem should be drawn (in a broken way)
|
||||
// TODO: merge this with the actual drawing loop somehow
|
||||
static INT16 getheight(INT16 index)
|
||||
{
|
||||
// gotta skip overlay items...
|
||||
INT16 i = 0;
|
||||
while (index + i < currentMenu->numitems && currentMenu->menuitems[index + i].status & IT_OVERLAY)
|
||||
i++;
|
||||
index += i;
|
||||
if (index >= currentMenu->numitems)
|
||||
return 0;
|
||||
|
||||
INT16 y = currentMenu->menuitems[index].y;
|
||||
if (!y) for (INT16 i = 0; i < index; i++)
|
||||
if (!(currentMenu->menuitems[i].status & IT_HIDDEN))
|
||||
y += 8;
|
||||
if (!y) while (i < index)
|
||||
if (!(currentMenu->menuitems[i++].status & (IT_HIDDEN|IT_OVERLAY)))
|
||||
y += currentMenu->lineheight;
|
||||
return y;
|
||||
}
|
||||
|
||||
|
|
@ -2249,6 +2258,8 @@ static void M_DrawBaseMenu(INT32 flags)
|
|||
INT16 scrollheight = currentMenu->scrollheight;
|
||||
if (!scrollheight)
|
||||
scrollheight = INT16_MAX;
|
||||
if (!currentMenu->numitems)
|
||||
return;
|
||||
|
||||
INT16 topy = getheight(0);
|
||||
INT16 boty = getheight(currentMenu->numitems-1);
|
||||
|
|
@ -2275,48 +2286,68 @@ static void M_DrawBaseMenu(INT32 flags)
|
|||
|
||||
for (i = 0; i < currentMenu->numitems; i++)
|
||||
{
|
||||
INT16 dx, dy;
|
||||
INT32 vflags = flags;
|
||||
menuitem_t *item = ¤tMenu->menuitems[i];
|
||||
|
||||
if (currentMenu->menuitems[i].status & IT_HIDDEN)
|
||||
{
|
||||
if (!(vflags & MDF_CONTROLS)) // don't leave gaps when buttons are hidden for P2/P3/P4
|
||||
y += LINEHEIGHT;
|
||||
if (item->status & IT_HIDDEN)
|
||||
continue;
|
||||
|
||||
if (item->status & IT_OVERLAY)
|
||||
{
|
||||
// draw at absolute coordinates; no clipping needed
|
||||
dx = item->x;
|
||||
dy = item->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = x + item->x;
|
||||
if (item->x)
|
||||
{
|
||||
if (!(item->status & IT_OFSX))
|
||||
x = dx = item->x + scrollx;
|
||||
else if (!(item->status & IT_TEMPORARY))
|
||||
x = dx;
|
||||
}
|
||||
|
||||
dy = y + item->y;
|
||||
if (item->y)
|
||||
{
|
||||
if (!(item->status & IT_OFSY))
|
||||
y = dy = item->y + scrolly;
|
||||
else if (!(item->status & IT_TEMPORARY))
|
||||
y = dy;
|
||||
}
|
||||
|
||||
if (dy < currentMenu->y)
|
||||
{
|
||||
cliptop = true;
|
||||
goto nodraw;
|
||||
}
|
||||
else if (dy > currentMenu->y + scrollheight)
|
||||
{
|
||||
clipbot = true;
|
||||
goto nodraw;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMenu->menuitems[i].y)
|
||||
y = currentMenu->menuitems[i].y + scrolly;
|
||||
if (currentMenu->menuitems[i].x)
|
||||
x = currentMenu->menuitems[i].x + scrollx;
|
||||
|
||||
if (y < currentMenu->y)
|
||||
{
|
||||
cliptop = true;
|
||||
y += LINEHEIGHT;
|
||||
continue;
|
||||
}
|
||||
else if (y > currentMenu->y + scrollheight)
|
||||
{
|
||||
clipbot = true;
|
||||
y += LINEHEIGHT;
|
||||
continue;
|
||||
}
|
||||
|
||||
w = M_DrawMenuItem(¤tMenu->menuitems[i], x, y, vflags, i == itemOn);
|
||||
w = M_DrawMenuItem(item, dx, dy, vflags, i == itemOn);
|
||||
|
||||
if (i == itemOn)
|
||||
{
|
||||
cursory = y;
|
||||
cursorx = x - (vflags & MDF_CENTERED ? w/2 : 0) - (vflags & MDF_CONTROLS ? 18 : 24);
|
||||
cursorx = x - (vflags & MDF_CENTERED ? w/2 : 0) - 24 + currentMenu->cursoroffset;
|
||||
}
|
||||
|
||||
y += LINEHEIGHT;
|
||||
nodraw:
|
||||
if (!(item->status & IT_OVERLAY))
|
||||
y += currentMenu->lineheight;
|
||||
}
|
||||
|
||||
// DRAW THE SKULL CURSOR
|
||||
V_DrawScaledPatch(cursorx, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||
|
||||
x = currentMenu->x - (flags & MDF_CONTROLS ? 16 : 20);
|
||||
x = currentMenu->x - 20 + currentMenu->cursoroffset;
|
||||
if (cliptop)
|
||||
V_DrawCharacter(x, currentMenu->y - (skullAnimCounter/5), '\x1A' | highlightflags, false); // up arrow
|
||||
if (clipbot)
|
||||
|
|
@ -3963,7 +3994,7 @@ void M_DrawPlaybackMenu(void)
|
|||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 18, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE, currentMenu->menuitems[i].text);
|
||||
|
||||
if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS)
|
||||
if (currentMenu->menuitems[i].status & IT_ARROWS)
|
||||
{
|
||||
char *str = NULL;
|
||||
|
||||
|
|
@ -6999,16 +7030,6 @@ INT32 MR_HandleControlsMenu(INT32 ch)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Draws the Customise Controls menu
|
||||
void M_DrawControl(void)
|
||||
{
|
||||
M_CentreText(28,
|
||||
(setupcontrolplayer > 1 ? va("\x86""Set controls for ""\x82""Player %d", setupcontrolplayer) :
|
||||
"\x86""Press ""\x82""ENTER""\x86"" to change, ""\x82""BACKSPACE""\x86"" to clear"));
|
||||
|
||||
M_DrawBaseMenu(MDF_CONTROLS|MENUCAPS);
|
||||
}
|
||||
|
||||
static INT32 controltochange;
|
||||
static char controltochangetext[33];
|
||||
|
||||
|
|
|
|||
13
src/m_menu.h
13
src/m_menu.h
|
|
@ -157,10 +157,9 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
#define IT_TYPE (1+2+4+8192)
|
||||
#define IT_CALL 1 // call the function
|
||||
#define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param
|
||||
#define IT_SUBMENU 4 // go to sub menu
|
||||
//#define IT_SUBMENU 4 // go to sub menu
|
||||
#define IT_CVAR 8192 // handle as a cvar
|
||||
|
||||
// display flags
|
||||
|
|
@ -176,18 +175,21 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
//consvar specific
|
||||
#define IT_CV_SLIDER 64
|
||||
#define IT_CV_STRING 128
|
||||
#define IT_CV_INTEGERSTEP 256 // if cvar is CV_FLOAT, modify it by 1 instead of 0.0625
|
||||
//#define IT_CV_INTEGERSTEP 256 // if cvar is CV_FLOAT, modify it by 1 instead of 0.0625
|
||||
|
||||
// extra flags
|
||||
#define IT_CENTER 512 // if IT_PATCH, center it on screen
|
||||
#define IT_HIDDEN 1024 // invisible, unselectable
|
||||
#define IT_GRAYEDOUT 2048 // grayed out, unselectable
|
||||
#define IT_SECRET 4096 // ??????? ????????????
|
||||
#define IT_OFSX 16384 // x coordinate is relative
|
||||
#define IT_OFSY 32768 // ditto
|
||||
#define IT_TEMPORARY 4 // offset is only applied temporarily
|
||||
#define IT_OVERLAY 256 // no scrolling, draw at absolute coordinates
|
||||
|
||||
// carefully chosen to not conflict with V_ flags
|
||||
#define MDF_CENTERED 0x20
|
||||
#define MDF_TIMEATTACK 0x40
|
||||
#define MDF_CONTROLS 0x80
|
||||
|
||||
#define MAXSTRINGLENGTH 32
|
||||
|
||||
|
|
@ -226,6 +228,8 @@ struct menu_t
|
|||
INT16 x, y; // x, y of menu
|
||||
INT16 scrollheight; // height of scrolling area
|
||||
INT16 lastOn; // last item user was on in menu
|
||||
INT16 cursoroffset; // X offset of cursor
|
||||
INT16 lineheight; // default Y offset to add for each item
|
||||
menufunc_f *enterroutine; // called before enter a menu
|
||||
menufunc_f *quitroutine; // called before quit a menu
|
||||
menufunc_f *keyhandler; // called before key press is processed
|
||||
|
|
@ -333,7 +337,6 @@ 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);
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
|
|
|
|||
Loading…
Reference in a new issue