mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-22 11:51:41 +00:00
Revamp of addons menu search!
* Instead of iterating through the folder every time you change the search query by one letter, iterate through the "coredirmenu" (the game's interpretation of the folder) instead. MUCH, much less likely to lag to fuck and back. * Hide a bit of complexity in filesrch.c instead of having the entire thing exposed to mess with. For example, closefilemenu() instead of manually freeing the struct each time. * Refactor some stuff.
This commit is contained in:
parent
f0618d5780
commit
f3baf608a2
3 changed files with 155 additions and 78 deletions
210
src/filesrch.c
210
src/filesrch.c
|
@ -326,8 +326,8 @@ size_t menudepthleft = menudepth;
|
||||||
|
|
||||||
char menusearch[MAXSTRINGLENGTH+1];
|
char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
char **dirmenu;
|
char **dirmenu, **coredirmenu; // core only local for this file
|
||||||
size_t sizedirmenu;
|
size_t sizedirmenu, sizecoredirmenu; // ditto
|
||||||
size_t dir_on[menudepth];
|
size_t dir_on[menudepth];
|
||||||
UINT8 refreshdirmenu = 0;
|
UINT8 refreshdirmenu = 0;
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ char exttable[NUM_EXT_TABLE][5] = {
|
||||||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||||
|
|
||||||
|
|
||||||
static boolean filemenusearch(char *haystack, char *needle)
|
static boolean filemenucmp(char *haystack, char *needle)
|
||||||
{
|
{
|
||||||
static char localhaystack[128];
|
static char localhaystack[128];
|
||||||
strlcpy(localhaystack, haystack, 128);
|
strlcpy(localhaystack, haystack, 128);
|
||||||
|
@ -457,21 +457,126 @@ static boolean filemenusearch(char *haystack, char *needle)
|
||||||
: (!strncmp(localhaystack, needle, menusearch[0])));
|
: (!strncmp(localhaystack, needle, menusearch[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\
|
void closefilemenu(boolean validsize)
|
||||||
{\
|
{
|
||||||
rejected++;\
|
// search
|
||||||
continue;\
|
if (dirmenu)
|
||||||
}\
|
{
|
||||||
|
if (dirmenu != coredirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[0]);
|
||||||
|
dirmenu[0] = NULL;
|
||||||
|
}
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
}
|
||||||
|
dirmenu = NULL;
|
||||||
|
sizedirmenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coredirmenu)
|
||||||
|
{
|
||||||
|
// core
|
||||||
|
if (validsize)
|
||||||
|
{
|
||||||
|
for (; sizecoredirmenu > 0; sizecoredirmenu--)
|
||||||
|
{
|
||||||
|
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||||
|
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sizecoredirmenu = 0;
|
||||||
|
|
||||||
|
Z_Free(coredirmenu);
|
||||||
|
coredirmenu = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchfilemenu(char *tempname)
|
||||||
|
{
|
||||||
|
size_t i, first;
|
||||||
|
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||||
|
|
||||||
|
if (dirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu != coredirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[0]);
|
||||||
|
dirmenu[0] = NULL;
|
||||||
|
}
|
||||||
|
//Z_Free(dirmenu); -- Z_Realloc later tho...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dirmenu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menusearch[0])
|
||||||
|
{
|
||||||
|
if (dirmenu)
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
dirmenu = coredirmenu;
|
||||||
|
sizedirmenu = sizecoredirmenu;
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(localmenusearch, menusearch+1);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localmenusearch);
|
||||||
|
|
||||||
|
first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP...
|
||||||
|
|
||||||
|
sizedirmenu = 0;
|
||||||
|
for (i = first; i < sizecoredirmenu; i++)
|
||||||
|
{
|
||||||
|
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||||
|
sizedirmenu++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizedirmenu) // no results...
|
||||||
|
{
|
||||||
|
if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
|| !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS))))
|
||||||
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
|
sizedirmenu = 1;
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
|
|
||||||
|
sizedirmenu = 0;
|
||||||
|
for (i = first; i < sizecoredirmenu; i++)
|
||||||
|
{
|
||||||
|
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||||
|
{
|
||||||
|
dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse
|
||||||
|
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
|
||||||
|
dir_on[menudepthleft] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir_on[menudepthleft] >= sizedirmenu)
|
||||||
|
dir_on[menudepthleft] = sizedirmenu-1;
|
||||||
|
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
}
|
||||||
|
|
||||||
boolean preparefilemenu(boolean samedepth)
|
boolean preparefilemenu(boolean samedepth)
|
||||||
{
|
{
|
||||||
DIR *dirhandle;
|
DIR *dirhandle;
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
struct stat fsstat;
|
struct stat fsstat;
|
||||||
size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0;
|
size_t pos = 0, folderpos = 0, numfolders = 0;
|
||||||
char *tempname = NULL;
|
char *tempname = NULL;
|
||||||
boolean noresults = false;
|
|
||||||
char localmenusearch[MAXSTRINGLENGTH] = "";
|
|
||||||
|
|
||||||
if (samedepth)
|
if (samedepth)
|
||||||
{
|
{
|
||||||
|
@ -481,20 +586,16 @@ boolean preparefilemenu(boolean samedepth)
|
||||||
else
|
else
|
||||||
menusearch[0] = menusearch[1] = 0; // clear search
|
menusearch[0] = menusearch[1] = 0; // clear search
|
||||||
|
|
||||||
for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items
|
if (!(dirhandle = opendir(menupath))) // get directory
|
||||||
{
|
{
|
||||||
Z_Free(dirmenu[sizedirmenu-1]);
|
closefilemenu(true);
|
||||||
dirmenu[sizedirmenu-1] = NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dirhandle = opendir(menupath))) // get directory
|
for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items
|
||||||
return false;
|
|
||||||
|
|
||||||
if (menusearch[0])
|
|
||||||
{
|
{
|
||||||
strcpy(localmenusearch, menusearch+1);
|
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||||
if (!cv_addons_search_case.value)
|
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||||
strupr(localmenusearch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -526,43 +627,42 @@ boolean preparefilemenu(boolean samedepth)
|
||||||
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
||||||
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||||
}
|
}
|
||||||
searchdir;
|
|
||||||
}
|
}
|
||||||
else // directory
|
else // directory
|
||||||
{
|
|
||||||
searchdir;
|
|
||||||
numfolders++;
|
numfolders++;
|
||||||
}
|
|
||||||
sizedirmenu++;
|
sizecoredirmenu++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rejected && !sizedirmenu)
|
if (!sizecoredirmenu)
|
||||||
{
|
{
|
||||||
|
closedir(dirhandle);
|
||||||
|
closefilemenu(false);
|
||||||
if (tempname)
|
if (tempname)
|
||||||
Z_Free(tempname);
|
Z_Free(tempname);
|
||||||
closedir(dirhandle);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((noresults = (menusearch[0] && !sizedirmenu)))
|
if (menudepthleft != menudepth-1) // Make room for UP...
|
||||||
|| (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry
|
|
||||||
{
|
{
|
||||||
sizedirmenu++;
|
sizecoredirmenu++;
|
||||||
numfolders++;
|
numfolders++;
|
||||||
folderpos++;
|
folderpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
|
if (dirmenu && dirmenu == coredirmenu)
|
||||||
|
dirmenu = NULL;
|
||||||
|
|
||||||
|
if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||||
{
|
{
|
||||||
closedir(dirhandle); // just in case
|
closedir(dirhandle); // just in case
|
||||||
I_Error("Ran out of memory whilst preparing add-ons menu");
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
rejected = 0;
|
|
||||||
rewinddir(dirhandle);
|
rewinddir(dirhandle);
|
||||||
|
|
||||||
while ((pos+folderpos) < sizedirmenu)
|
while ((pos+folderpos) < sizecoredirmenu)
|
||||||
{
|
{
|
||||||
menupath[menupathindex[menudepthleft]] = 0;
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
dent = readdir(dirhandle);
|
dent = readdir(dirhandle);
|
||||||
|
@ -588,14 +688,12 @@ boolean preparefilemenu(boolean samedepth)
|
||||||
|
|
||||||
if (!S_ISDIR(fsstat.st_mode)) // file
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
{
|
{
|
||||||
if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention
|
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
|
||||||
for (; ext < NUM_EXT_TABLE; ext++)
|
for (; ext < NUM_EXT_TABLE; ext++)
|
||||||
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
||||||
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
||||||
ext += EXT_START; // moving to be appropriate position
|
ext += EXT_START; // moving to be appropriate position
|
||||||
|
|
||||||
searchdir;
|
|
||||||
|
|
||||||
if (ext >= EXT_LOADSTART)
|
if (ext >= EXT_LOADSTART)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -628,10 +726,7 @@ boolean preparefilemenu(boolean samedepth)
|
||||||
folder = 0;
|
folder = 0;
|
||||||
}
|
}
|
||||||
else // directory
|
else // directory
|
||||||
{
|
|
||||||
searchdir;
|
|
||||||
len += (folder = 1);
|
len += (folder = 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 255)
|
if (len > 255)
|
||||||
len = 255;
|
len = 255;
|
||||||
|
@ -644,45 +739,30 @@ boolean preparefilemenu(boolean samedepth)
|
||||||
if (folder)
|
if (folder)
|
||||||
{
|
{
|
||||||
strcpy(temp+len, "/");
|
strcpy(temp+len, "/");
|
||||||
dirmenu[folderpos++] = temp;
|
coredirmenu[folderpos++] = temp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dirmenu[numfolders + pos++] = temp;
|
coredirmenu[numfolders + pos++] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dirhandle);
|
closedir(dirhandle);
|
||||||
|
|
||||||
if (noresults) // no results
|
if ((menudepthleft != menudepth-1) // now for UP... entry
|
||||||
dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS));
|
&& !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP))))
|
||||||
else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP));
|
|
||||||
|
|
||||||
menupath[menupathindex[menudepthleft]] = 0;
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
||||||
|
|
||||||
if (tempname)
|
if (!sizecoredirmenu)
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < sizedirmenu; i++)
|
|
||||||
{
|
|
||||||
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
|
|
||||||
{
|
|
||||||
dir_on[menudepthleft] = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z_Free(tempname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sizedirmenu)
|
|
||||||
{
|
{
|
||||||
dir_on[menudepthleft] = 0;
|
dir_on[menudepthleft] = 0;
|
||||||
Z_Free(dirmenu);
|
closefilemenu(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (dir_on[menudepthleft] >= sizedirmenu)
|
|
||||||
dir_on[menudepthleft] = sizedirmenu-1;
|
searchfilemenu(tempname);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,8 @@ typedef enum
|
||||||
REFRESHDIR_MAX = 32
|
REFRESHDIR_MAX = 32
|
||||||
} refreshdir_enum;
|
} refreshdir_enum;
|
||||||
|
|
||||||
|
void closefilemenu(boolean validsize);
|
||||||
|
void searchfilemenu(char *tempname);
|
||||||
boolean preparefilemenu(boolean samedepth);
|
boolean preparefilemenu(boolean samedepth);
|
||||||
|
|
||||||
#endif // __FILESRCH_H__
|
#endif // __FILESRCH_H__
|
||||||
|
|
21
src/m_menu.c
21
src/m_menu.c
|
@ -5048,13 +5048,11 @@ static void M_DrawAddons(void)
|
||||||
x -= (21 + 5 + 16);
|
x -= (21 + 5 + 16);
|
||||||
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||||
|
|
||||||
#define CANSAVE (!modifiedgame || savemoddata)
|
|
||||||
x = BASEVIDWIDTH - x - 16;
|
x = BASEVIDWIDTH - x - 16;
|
||||||
V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]);
|
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]);
|
||||||
|
|
||||||
if (modifiedgame)
|
if (modifiedgame)
|
||||||
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]);
|
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]);
|
||||||
#undef CANSAVE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FIXUPO0
|
#ifdef FIXUPO0
|
||||||
|
@ -5119,11 +5117,15 @@ static void M_HandleAddons(INT32 choice)
|
||||||
|
|
||||||
if (M_ChangeStringAddons(choice))
|
if (M_ChangeStringAddons(choice))
|
||||||
{
|
{
|
||||||
if (!preparefilemenu(true))
|
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
|
||||||
|
searchfilemenu(tempname);
|
||||||
|
/*if (!preparefilemenu(true))
|
||||||
{
|
{
|
||||||
UNEXIST;
|
UNEXIST;
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (choice)
|
switch (choice)
|
||||||
|
@ -5242,14 +5244,7 @@ static void M_HandleAddons(INT32 choice)
|
||||||
}
|
}
|
||||||
if (exitmenu)
|
if (exitmenu)
|
||||||
{
|
{
|
||||||
for (; sizedirmenu > 0; sizedirmenu--)
|
closefilemenu(true);
|
||||||
{
|
|
||||||
Z_Free(dirmenu[sizedirmenu-1]);
|
|
||||||
dirmenu[sizedirmenu-1] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z_Free(dirmenu);
|
|
||||||
dirmenu = NULL;
|
|
||||||
|
|
||||||
// secrets disabled by addfile...
|
// secrets disabled by addfile...
|
||||||
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||||
|
|
Loading…
Reference in a new issue