More feature-rich and better engineered.

* Instead of needing to press backspace, going back is now handled via an "(up arrow) UP..." entry in the table.
* Maximum depth is now #define'd instead of dotted around everywhere.
* Enums!
* Exec for .txt (with confirmation dialog) and .cfg (without)!
* Complaints about folders and etc now mention the folder names.
* A shrinking folder now prevents dir_on[] from going beyond its end.
This commit is contained in:
toasterbabe 2017-04-29 16:40:07 +01:00
parent 881f5e70ce
commit 20fff0ef23
4 changed files with 115 additions and 55 deletions

View File

@ -288,12 +288,12 @@ closedir (DIR * dirp)
#endif
char menupath[1024];
size_t menupathindex[20];
size_t menudepthleft = 20;
size_t menupathindex[menudepth];
size_t menudepthleft = menudepth;
char **dirmenu;
size_t sizedirmenu;
size_t dir_on[20];
size_t dir_on[menudepth];
#if defined (_XBOX) && defined (_MSC_VER)
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
@ -473,8 +473,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
return retval;
}
#define MAXEXT 5
char ext[MAXEXT][5] = {
char exttable[NUM_EXT_TABLE][5] = {
".txt", ".cfg", // exec
".wad", ".soc", ".lua"}; // addfile
@ -518,10 +517,10 @@ boolean preparefilemenu(void)
if (!S_ISDIR(fsstat.st_mode))
{
size_t len = strlen(dent->d_name)+1;
UINT8 i;
for (i = 0; i < MAXEXT; i++)
if (!strcasecmp(ext[i], dent->d_name+len-5)) break;
if (i == MAXEXT) continue; // not an addfile-able (or exec-able) file
UINT8 ext;
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
}
else
numfolders++;
@ -534,6 +533,13 @@ boolean preparefilemenu(void)
if (!sizedirmenu)
return false;
if (menudepthleft != menudepth-1)
{
numfolders++;
sizedirmenu++;
folderpos++;
}
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
I_Error("Ran out of memory whilst preparing add-ons menu");
@ -560,15 +566,15 @@ boolean preparefilemenu(void)
{
char *temp;
size_t len = strlen(dent->d_name)+1;
UINT8 i = 0;
UINT8 ext = EXT_FOLDER;
size_t folder;
if (!S_ISDIR(fsstat.st_mode)) // file
{
for (; i < MAXEXT; i++)
if (!strcasecmp(ext[i], dent->d_name+len-5)) break;
if (i == MAXEXT) continue; // not an addfile-able (or exec-able) file
i++; // i goes up so zero-index is directory instead of .txt
for (; 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
ext += EXT_START; // moving to be appropriate position
folder = 0;
}
else
@ -579,7 +585,7 @@ boolean preparefilemenu(void)
if (!(temp = Z_Malloc((len+2+folder) * sizeof (char), PU_STATIC, NULL)))
I_Error("Ran out of memory whilst preparing add-ons menu");
temp[0] = i;
temp[0] = ext;
temp[1] = (UINT8)(len);
strlcpy(temp+2, dent->d_name, len);
if (folder)
@ -592,9 +598,15 @@ boolean preparefilemenu(void)
}
}
if (menudepthleft != menudepth-1)
dirmenu[0] = Z_StrDup("\1\7\x1A UP...");
menupath[menupathindex[menudepthleft]] = 0;
sizedirmenu = (pos+folderpos); // crash prevention if things change between openings somehow
if (dir_on[menudepthleft] >= sizedirmenu)
dir_on[menudepthleft] = sizedirmenu;
closedir(dirhandle);
return true;
}

View File

@ -25,13 +25,29 @@
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
boolean completepath, int maxsearchdepth);
#define menudepth 20
extern char menupath[1024];
extern size_t menupathindex[20];
extern size_t menupathindex[menudepth];
extern size_t menudepthleft;
extern char **dirmenu;
extern size_t sizedirmenu;
extern size_t dir_on[20];
extern size_t dir_on[menudepth];
typedef enum
{
EXT_FOLDER = 0,
EXT_UP,
EXT_START,
EXT_TXT = EXT_START,
EXT_CFG,
EXT_WAD,
EXT_SOC,
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
NUM_EXT,
NUM_EXT_TABLE = NUM_EXT-EXT_START
} ext_enum;
boolean preparefilemenu(void);

View File

@ -21,7 +21,7 @@
//------------------------------------
// heads up font
//------------------------------------
#define HU_FONTSTART '\x1F' // the first font character
#define HU_FONTSTART '\x19' // the first font character
#define HU_FONTEND '~'
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)

View File

@ -4444,7 +4444,7 @@ static void M_Addons(INT32 choice)
(void)choice;
strlcpy(menupath, srb2home, 1024);
menupathindex[(menudepthleft = 19)] = strlen(menupath) + 1;
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
if (menupath[menupathindex[menudepthleft]-2] != '/')
{
@ -4475,17 +4475,26 @@ static void M_DrawAddons(void)
x = currentMenu->x;
y = currentMenu->y;
V_DrawString(x, y, 0, menupath);
V_DrawString(x, y, V_ALLOWLOWERCASE, menupath);
y += 2*SMALLLINEHEIGHT;
for (i = dir_on[menudepthleft]; i < sizedirmenu; i++)
{
if (y > BASEVIDHEIGHT) break;
V_DrawString(x, y, 0, dirmenu[i]+2);
V_DrawString(x, y, ((dirmenu[dir_on[menudepthleft]][0] == EXT_UP) ? 0 : V_ALLOWLOWERCASE), dirmenu[i]+2);
y += SMALLLINEHEIGHT;
}
}
static void M_AddonExec(INT32 ch)
{
if (ch != 'y' && ch != KEY_ENTER)
return;
S_StartSound(NULL, sfx_strpst);
COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2));
}
static void M_HandleAddons(INT32 choice)
{
boolean exitmenu = false; // exit to previous menu
@ -4503,48 +4512,71 @@ static void M_HandleAddons(INT32 choice)
S_StartSound(NULL, sfx_menu1);
break;
case KEY_ENTER:
if (dirmenu[dir_on[menudepthleft]][0] == 0) // folder
{
S_StartSound(NULL, sfx_strpst);
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+2);
menupathindex[--menudepthleft] = strlen(menupath);
menupath[menupathindex[menudepthleft]] = 0;
boolean refresh = true;
switch (dirmenu[dir_on[menudepthleft]][0])
{
case EXT_FOLDER:
if (menudepthleft)
{
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+2);
menupathindex[--menudepthleft] = strlen(menupath);
menupath[menupathindex[menudepthleft]] = 0;
if (!preparefilemenu())
{
M_StartMessage(M_GetText("Folder is empty.\n\n(Press a key)\n"),NULL,MM_NOTHING);
menupath[menupathindex[++menudepthleft]] = 0;
if (!preparefilemenu())
{
M_StartMessage(M_GetText("Folder no longer exists!\n\n(Press a key)\n"),NULL,MM_NOTHING);
M_SetupNextMenu(MISC_AddonsDef.prevMenu);
return;
}
if (!preparefilemenu())
{
S_StartSound(NULL, sfx_skid);
M_StartMessage(va("%s\nThis folder is empty.\n\n(Press a key)\n", menupath),NULL,MM_NOTHING);
menupath[menupathindex[++menudepthleft]] = 0;
}
else
{
S_StartSound(NULL, sfx_strpst);
dir_on[menudepthleft] = 0;
refresh = false;
}
}
else
{
S_StartSound(NULL, sfx_lose);
M_StartMessage(va("%s%s\nThis folder is too deep to navigate to!\n\n(Press a key)\n", menupath, dirmenu[dir_on[menudepthleft]]+2),NULL,MM_NOTHING);
}
break;
case EXT_UP:
S_StartSound(NULL, sfx_skid);
menupath[menupathindex[++menudepthleft]] = 0;
break;
case EXT_TXT:
M_StartMessage(va("%s\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", dirmenu[dir_on[menudepthleft]]+2),M_AddonExec,MM_YESNO);
break;
case EXT_CFG:
M_AddonExec(KEY_ENTER);
break;
case EXT_LUA:
#ifdef HAVE_BLUA
S_StartSound(NULL, sfx_lose);
M_StartMessage(va("%s\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+2),NULL,MM_NOTHING);
break;
#endif
// else intentional fallthrough
case EXT_WAD:
case EXT_SOC:
S_StartSound(NULL, sfx_strpst);
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2));
break;
default:
S_StartSound(NULL, sfx_lose);
}
else
dir_on[menudepthleft] = 0;
}
else if (dirmenu[dir_on[menudepthleft]][0] >= 3) // wad/soc/lua
{
S_StartSound(NULL, sfx_strpst);
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2));
}
else
S_StartSound(NULL, sfx_lose);
break;
case KEY_BACKSPACE:
if (menudepthleft < 19)
{
menupath[menupathindex[++menudepthleft]] = 0;
if (!preparefilemenu())
if (refresh && !preparefilemenu())
{
M_StartMessage(M_GetText("Folder no longer exists!\n\n(Press a key)\n"),NULL,MM_NOTHING);
S_StartSound(NULL, sfx_lose);
M_SetupNextMenu(MISC_AddonsDef.prevMenu);
M_StartMessage(va("%s\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", menupath),NULL,MM_NOTHING);
return;
}
break;
}
// intentional fallthrough
break;
case KEY_ESCAPE:
exitmenu = true;
break;