Addons menu refactor part 3

Search finally works again!
- Now uses a cvar which is copied into static memory to uppercase it, instead of a weird static string uppercased into zone memory.
- You have to scroll to the top of the menu to use it, one entry above the previous first file/folder/"UP...".
- Don't play menu sound if you've reached the end of an un-looping menu.
This commit is contained in:
toaster 2022-09-03 21:15:23 +01:00
parent 88f04da180
commit 26461d568c
5 changed files with 83 additions and 74 deletions

View file

@ -561,15 +561,15 @@ char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) pl
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
static boolean filemenucmp(char *haystack, char *needle)
static boolean filemenucmp(char *haystack)
{
static char localhaystack[128];
strlcpy(localhaystack, haystack, 128);
if (!cv_addons_search_case.value)
strupr(localhaystack);
if (cv_addons_search_type.value)
return (strstr(localhaystack, needle) != 0);
return (!strncmp(localhaystack, needle, menusearch[0]));
return (strstr(localhaystack, menusearch+1) != 0);
return (!strncmp(localhaystack, menusearch+1, menusearch[0]));
}
void closefilemenu(boolean validsize)
@ -616,7 +616,6 @@ void closefilemenu(boolean validsize)
void searchfilemenu(char *tempname)
{
size_t i, first;
char localmenusearch[MAXSTRINGLENGTH] = "";
if (dirmenu)
{
@ -662,14 +661,10 @@ void searchfilemenu(char *tempname)
return;
}
strcpy(localmenusearch, menusearch+1);
if (!cv_addons_search_case.value)
strupr(localmenusearch);
sizedirmenu = 0;
for (i = first; i < sizecoredirmenu; i++)
{
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
if (filemenucmp(coredirmenu[i]+DIR_STRING))
sizedirmenu++;
}
@ -691,7 +686,7 @@ void searchfilemenu(char *tempname)
sizedirmenu = 0;
for (i = first; i < sizecoredirmenu; i++)
{
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
if (filemenucmp(coredirmenu[i]+DIR_STRING))
{
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
{
@ -724,7 +719,10 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
}
else
{
menusearch[0] = menusearch[1] = 0; // clear search
CV_StealthSet(&cv_dummyaddonsearch, "");
}
if (!(dirhandle = opendir(menupath))) // get directory
{

View file

@ -966,6 +966,7 @@ void M_Addons(INT32 choice);
void M_AddonsRefresh(void);
void M_HandleAddons(INT32 choice);
char *M_AddonsHeaderPath(void);
extern consvar_t cv_dummyaddonsearch;
void M_Manual(INT32 choice);
void M_HandleImageDef(INT32 choice);

View file

@ -1726,9 +1726,11 @@ menuitem_t MISC_Manual[] = {
menu_t MISC_ManualDef = IMAGEDEF(MISC_Manual);
// Addons menu! (Just a straight port for now)
// Addons menu!
menuitem_t MISC_AddonsMenu[] =
{
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, NULL,
NULL, {.cvar = &cv_dummyaddonsearch}, 0, 0},
{IT_KEYHANDLER | IT_NOTHING, NULL, NULL,
NULL, {.routine = M_HandleAddons}, 0, 0}, // dummy menuitem for the control func
};

View file

@ -4191,7 +4191,7 @@ void M_DrawReplayStartMenu(void)
// Draw misc menus:
// Addons (this is merely copypasted, original code by toaster)
// Addons
#define lsheadingheight 16
@ -4318,16 +4318,23 @@ void M_DrawAddons(void)
y += 10;
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
if (menusearch[0])
V_DrawString(x - 18, y+8, V_ALLOWLOWERCASE, menusearch+1);
else
V_DrawString(x - 18, y+8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
{
const char *str = (menusearch[0] ? cv_dummyaddonsearch.string : "Search...");
INT32 tflag = (menusearch[0] ? 0 : V_TRANSLUCENT);
INT32 xoffs = 0;
if (itemOn == 0)
{
xoffs += 8;
V_DrawString(x + (skullAnimCounter/5) - 20, y+8, highlightflags, "\x1D");
}
V_DrawString(x + xoffs - 18, y+8, V_ALLOWLOWERCASE|tflag, str);
}
V_DrawSmallScaledPatch(x - (21 + 5 + 16), y+4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
y += 21;
m = (addonsseperation*(2*numaddonsshown + 1)) + 2*(16-addonsseperation);
m = (addonsseperation*(2*numaddonsshown + 1)) + 1 + 2*(16-addonsseperation);
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 159);
// scrollbar!
@ -4385,7 +4392,7 @@ void M_DrawAddons(void)
else
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[(type & ~EXT_LOADED)]);
if ((size_t)i == dir_on[menudepthleft])
if (itemOn == 1 && (size_t)i == dir_on[menudepthleft])
{
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, addonsp[NUM_EXT+1], flashcol);
flags = V_ALLOWLOWERCASE|highlightflags;

View file

@ -208,6 +208,9 @@ consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HI
consvar_t cv_dummykartspeed = CVAR_INIT ("dummykartspeed", "Auto", CV_HIDDEN, dummykartspeed_cons_t, NULL);
consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "No", CV_HIDDEN, CV_YesNo, NULL);
static void M_UpdateAddonsSearch(void);
consvar_t cv_dummyaddonsearch = CVAR_INIT ("dummyaddonsearch", "", CV_HIDDEN|CV_CALL|CV_NOINIT, NULL, M_UpdateAddonsSearch);
static CV_PossibleValue_t dummymatchbots_cons_t[] = {
{0, "Off"},
{1, "Lv.1"},
@ -719,7 +722,7 @@ static boolean M_ChangeStringCvar(INT32 choice)
return false;
}
static void M_NextOpt(void)
static boolean M_NextOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
@ -729,15 +732,24 @@ static void M_NextOpt(void)
do
{
if (itemOn + 1 > currentMenu->numitems - 1)
{
// Prevent looparound here
// If you're going to add any extra exceptions, DON'T.
// Add a "don't loop" flag to the menu_t struct instead.
if (currentMenu == &MISC_AddonsDef)
return false;
itemOn = 0;
}
else
itemOn++;
} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
M_UpdateMenuBGImage(false);
return true;
}
static void M_PrevOpt(void)
static boolean M_PrevOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
@ -747,12 +759,21 @@ static void M_PrevOpt(void)
do
{
if (!itemOn)
{
// Prevent looparound here
// If you're going to add any extra exceptions, DON'T.
// Add a "don't loop" flag to the menu_t struct instead.
if (currentMenu == &MISC_AddonsDef)
return false;
itemOn = currentMenu->numitems - 1;
}
else
itemOn--;
} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
M_UpdateMenuBGImage(false);
return true;
}
//
@ -1436,15 +1457,15 @@ static void M_HandleMenuInput(void)
// Keys usable within menu
if (ud > 0)
{
M_NextOpt();
S_StartSound(NULL, sfx_s3k5b);
if (M_NextOpt())
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
return;
}
else if (ud < 0)
{
M_PrevOpt();
S_StartSound(NULL, sfx_s3k5b);
if (M_PrevOpt())
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
return;
}
@ -1683,6 +1704,8 @@ void M_Init(void)
CV_RegisterVar(&cv_dummygpencore);
CV_RegisterVar(&cv_dummymatchbots);
CV_RegisterVar(&cv_dummyaddonsearch);
M_UpdateMenuBGImage(true);
#if 0
@ -6280,6 +6303,8 @@ void M_Addons(INT32 choice)
else
dir_on[menudepthleft] = 0;
MISC_AddonsDef.lastOn = 0; // Always start on search
MISC_AddonsDef.prevMenu = currentMenu;
M_SetupNextMenu(&MISC_AddonsDef, false);
}
@ -6387,43 +6412,23 @@ static void M_AddonExec(INT32 ch)
}
}
#define len menusearch[0]
static boolean M_ChangeStringAddons(INT32 choice)
static void M_UpdateAddonsSearch(void)
{
if (shiftdown && choice >= 32 && choice <= 127)
choice = shiftxform[choice];
menusearch[0] = strlen(cv_dummyaddonsearch.string);
strlcpy(menusearch+1, cv_dummyaddonsearch.string, MAXSTRINGLENGTH);
if (!cv_addons_search_case.value)
strupr(menusearch+1);
switch (choice)
#if 0 // much slower
if (!preparefilemenu(true, false))
{
case KEY_DEL:
if (len)
{
len = menusearch[1] = 0;
return true;
}
break;
case KEY_BACKSPACE:
if (len)
{
menusearch[1+--len] = 0;
return true;
}
break;
default:
if (choice >= 32 && choice <= 127)
{
if (len < MAXSTRINGLENGTH - 1)
{
menusearch[1+len++] = (char)choice;
menusearch[1+len] = 0;
return true;
}
}
break;
UNEXIST;
return;
}
return false;
#else // streamlined
searchfilemenu(NULL);
#endif
}
#undef len
void M_HandleAddons(INT32 choice)
{
@ -6432,34 +6437,30 @@ void M_HandleAddons(INT32 choice)
(void) choice;
if (M_ChangeStringAddons(choice))
{
char *tempname = NULL;
if (dirmenu && dirmenu[dir_on[menudepthleft]])
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
#if 0 // much slower
if (!preparefilemenu(true, false))
{
UNEXIST;
return;
}
#else // streamlined
searchfilemenu(tempname);
#endif
}
if (menucmd[pid].dpad_ud > 0)
{
if (dir_on[menudepthleft] < sizedirmenu-1)
{
dir_on[menudepthleft]++;
S_StartSound(NULL, sfx_s3k5b);
S_StartSound(NULL, sfx_s3k5b);
}
else if (M_NextOpt())
{
S_StartSound(NULL, sfx_s3k5b);
}
M_SetMenuDelay(pid);
}
else if (menucmd[pid].dpad_ud < 0)
{
if (dir_on[menudepthleft])
{
dir_on[menudepthleft]--;
S_StartSound(NULL, sfx_s3k5b);
S_StartSound(NULL, sfx_s3k5b);
}
else if (M_PrevOpt())
{
S_StartSound(NULL, sfx_s3k5b);
}
M_SetMenuDelay(pid);
}