mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 03:12:38 +00:00
Search!
https://gfycat.com/DizzyEnergeticCygnet I will make it prettier. (Also: stristr. Since the Windows (and others?) standard library doesn't have it for some reason, I modified code someone put on StackExchange as a stopgap; once I'm ready to get on IRC for the day, we'll discuss attribution/rewriting.)
This commit is contained in:
parent
ba04e982b2
commit
8f2490d588
6 changed files with 134 additions and 17 deletions
|
@ -170,6 +170,10 @@ size_t strlcat(char *dst, const char *src, size_t siz);
|
|||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
|
||||
#if 1 // don't know what systems don't have this
|
||||
char* stristr(char* haystack, const char* needle);
|
||||
#endif
|
||||
|
||||
// Macro for use with char foo[FOOSIZE+1] type buffers.
|
||||
// Never use this with a buffer that is a "char *" or passed
|
||||
// into the function as an argument.
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "d_netfil.h"
|
||||
#include "m_misc.h"
|
||||
#include "z_zone.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||
|
||||
|
@ -313,6 +314,8 @@ char menupath[1024];
|
|||
size_t menupathindex[menudepth];
|
||||
size_t menudepthleft = menudepth;
|
||||
|
||||
char menusearch[MAXSTRINGLENGTH+1];
|
||||
|
||||
char **dirmenu;
|
||||
size_t sizedirmenu;
|
||||
size_t dir_on[menudepth];
|
||||
|
@ -507,16 +510,27 @@ char exttable[NUM_EXT_TABLE][5] = {
|
|||
|
||||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||
|
||||
#define searchdir if (menusearch[0] && !stristr(dent->d_name, menusearch+1))\
|
||||
{\
|
||||
rejected++;\
|
||||
continue;\
|
||||
}\
|
||||
|
||||
boolean preparefilemenu(boolean samedepth)
|
||||
{
|
||||
DIR *dirhandle;
|
||||
struct dirent *dent;
|
||||
struct stat fsstat;
|
||||
size_t pos = 0, folderpos = 0, numfolders = 0;
|
||||
size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0;
|
||||
char *tempname = NULL;
|
||||
|
||||
if (samedepth && 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 (samedepth)
|
||||
{
|
||||
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
|
||||
}
|
||||
else
|
||||
menusearch[0] = menusearch[1] = 0; // clear search
|
||||
|
||||
for (; sizedirmenu > 0; sizedirmenu--)
|
||||
{
|
||||
|
@ -555,14 +569,18 @@ boolean preparefilemenu(boolean samedepth)
|
|||
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break;
|
||||
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||
searchdir;
|
||||
}
|
||||
else // directory
|
||||
{
|
||||
searchdir;
|
||||
numfolders++;
|
||||
}
|
||||
sizedirmenu++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizedirmenu)
|
||||
if (!rejected && !sizedirmenu)
|
||||
{
|
||||
if (tempname)
|
||||
Z_Free(tempname);
|
||||
|
@ -570,7 +588,7 @@ boolean preparefilemenu(boolean samedepth)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (menudepthleft != menudepth-1) // Make room for UP... entry
|
||||
if (menusearch[0] || menudepthleft != menudepth-1) // Make room for UP... or search entry
|
||||
{
|
||||
numfolders++;
|
||||
sizedirmenu++;
|
||||
|
@ -583,6 +601,7 @@ boolean preparefilemenu(boolean samedepth)
|
|||
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||
}
|
||||
|
||||
rejected = 0;
|
||||
rewinddir(dirhandle);
|
||||
|
||||
while ((pos+folderpos) < sizedirmenu)
|
||||
|
@ -617,6 +636,8 @@ boolean preparefilemenu(boolean samedepth)
|
|||
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||
ext += EXT_START; // moving to be appropriate position
|
||||
|
||||
searchdir;
|
||||
|
||||
if (ext >= EXT_MD5)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -638,7 +659,10 @@ boolean preparefilemenu(boolean samedepth)
|
|||
folder = 0;
|
||||
}
|
||||
else // directory
|
||||
{
|
||||
searchdir;
|
||||
len += (folder = 1);
|
||||
}
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
@ -658,8 +682,10 @@ boolean preparefilemenu(boolean samedepth)
|
|||
}
|
||||
}
|
||||
|
||||
if (menudepthleft != menudepth-1) // now for UP... entry
|
||||
dirmenu[0] = Z_StrDup("\1\5UP...");
|
||||
if (menusearch[0])
|
||||
dirmenu[0] = Z_StrDup(va("%c\14Search results", EXT_SEARCH));
|
||||
else if (menudepthleft != menudepth-1) // now for UP... entry
|
||||
dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP));
|
||||
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "d_netfil.h"
|
||||
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||
|
||||
/** \brief The filesearch function
|
||||
|
||||
|
@ -31,6 +32,8 @@ extern char menupath[1024];
|
|||
extern size_t menupathindex[menudepth];
|
||||
extern size_t menudepthleft;
|
||||
|
||||
extern char menusearch[MAXSTRINGLENGTH+1];
|
||||
|
||||
extern char **dirmenu;
|
||||
extern size_t sizedirmenu;
|
||||
extern size_t dir_on[menudepth];
|
||||
|
@ -43,6 +46,7 @@ typedef enum
|
|||
{
|
||||
EXT_FOLDER = 0,
|
||||
EXT_UP,
|
||||
EXT_SEARCH,
|
||||
EXT_START,
|
||||
EXT_TXT = EXT_START,
|
||||
EXT_CFG,
|
||||
|
|
63
src/m_menu.c
63
src/m_menu.c
|
@ -77,7 +77,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#define SMALLLINEHEIGHT 8
|
||||
#define SLIDER_RANGE 10
|
||||
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
|
||||
#define MAXSTRINGLENGTH 32
|
||||
#define SERVERS_PER_PAGE 11
|
||||
|
||||
typedef enum
|
||||
|
@ -2134,9 +2133,12 @@ static void M_ChangeCvar(INT32 choice)
|
|||
static boolean M_ChangeStringCvar(INT32 choice)
|
||||
{
|
||||
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
|
||||
char buf[255];
|
||||
char buf[MAXSTRINGLENGTH];
|
||||
size_t len;
|
||||
|
||||
if (shiftdown && choice >= 32 && choice <= 127)
|
||||
choice = shiftxform[choice];
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_BACKSPACE:
|
||||
|
@ -2434,8 +2436,6 @@ boolean M_Responder(event_t *ev)
|
|||
{
|
||||
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
|
||||
{
|
||||
if (shiftdown && ch >= 32 && ch <= 127)
|
||||
ch = shiftxform[ch];
|
||||
if (M_ChangeStringCvar(ch))
|
||||
return true;
|
||||
else
|
||||
|
@ -4474,6 +4474,7 @@ static void M_Addons(INT32 choice)
|
|||
|
||||
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC);
|
||||
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC);
|
||||
addonsp[EXT_SEARCH] = W_CachePatchName("M_FSRCH", PU_STATIC);
|
||||
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||
|
@ -4552,14 +4553,16 @@ static char *M_AddonsHeaderPath(void)
|
|||
return header+len;
|
||||
}
|
||||
|
||||
#define UNEXIST S_StartSound(NULL, sfx_lose);\
|
||||
M_SetupNextMenu(MISC_AddonsDef.prevMenu);\
|
||||
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING)
|
||||
|
||||
// returns whether to do message draw
|
||||
static boolean M_AddonsRefresh(void)
|
||||
{
|
||||
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
M_SetupNextMenu(MISC_AddonsDef.prevMenu);
|
||||
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
UNEXIST;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4617,6 +4620,8 @@ static void M_DrawAddons(void)
|
|||
|
||||
M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true);
|
||||
|
||||
V_DrawString(0, 0, V_ALLOWLOWERCASE, menusearch+1);
|
||||
|
||||
// get bottom...
|
||||
max = dir_on[menudepthleft] + 5;
|
||||
if (max > (ssize_t)sizedirmenu)
|
||||
|
@ -4679,10 +4684,50 @@ static void M_AddonExec(INT32 ch)
|
|||
COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||
}
|
||||
|
||||
#define len menusearch[0]
|
||||
static boolean M_ChangeStringAddons(INT32 choice)
|
||||
{
|
||||
if (shiftdown && choice >= 32 && choice <= 127)
|
||||
choice = shiftxform[choice];
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DEL:
|
||||
len = menusearch[1] = 0;
|
||||
return true;
|
||||
case KEY_BACKSPACE:
|
||||
if (len > 0)
|
||||
menusearch[1+--len] = 0;
|
||||
return true;
|
||||
default:
|
||||
if (choice >= 32 && choice <= 127)
|
||||
{
|
||||
if (len < MAXSTRINGLENGTH - 1)
|
||||
{
|
||||
menusearch[1+len++] = (char)choice;
|
||||
menusearch[1+len] = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#undef len
|
||||
|
||||
static void M_HandleAddons(INT32 choice)
|
||||
{
|
||||
boolean exitmenu = false; // exit to previous menu
|
||||
|
||||
if (M_ChangeStringAddons(choice))
|
||||
{
|
||||
if (!preparefilemenu(true))
|
||||
{
|
||||
UNEXIST;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DOWNARROW:
|
||||
|
@ -4719,9 +4764,7 @@ static void M_HandleAddons(INT32 choice)
|
|||
|
||||
if (!preparefilemenu(true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
M_SetupNextMenu(MISC_AddonsDef.prevMenu);
|
||||
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
UNEXIST;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||
|
||||
#define MAXSTRINGLENGTH 32
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct menu_s *submenu; // IT_SUBMENU
|
||||
|
|
38
src/string.c
38
src/string.c
|
@ -50,3 +50,41 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 1 // i don't know what specific OSes are missing this, oh well
|
||||
|
||||
// stack overflow, eep...
|
||||
char* stristr(char* haystack, const char* needle)
|
||||
{
|
||||
char* p1 = haystack ;
|
||||
const char* p2 = needle ;
|
||||
char* r = ((*p2 == 0) ? haystack : 0);
|
||||
|
||||
while (*p1 != 0 && *p2 != 0)
|
||||
{
|
||||
if (tolower(*p1) == tolower(*p2))
|
||||
{
|
||||
if (r == 0)
|
||||
r = p1;
|
||||
|
||||
p2++;
|
||||
}
|
||||
else
|
||||
{
|
||||
p2 = needle;
|
||||
if (tolower(*p1) == tolower(*p2))
|
||||
{
|
||||
r = p1;
|
||||
p2++;
|
||||
}
|
||||
else
|
||||
r = 0;
|
||||
}
|
||||
|
||||
p1++;
|
||||
}
|
||||
|
||||
return ((*p2 == 0) ? r : 0);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue