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

View File

@ -25,13 +25,29 @@
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
boolean completepath, int maxsearchdepth); boolean completepath, int maxsearchdepth);
#define menudepth 20
extern char menupath[1024]; extern char menupath[1024];
extern size_t menupathindex[20]; extern size_t menupathindex[menudepth];
extern size_t menudepthleft; extern size_t menudepthleft;
extern char **dirmenu; extern char **dirmenu;
extern size_t sizedirmenu; 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); boolean preparefilemenu(void);

View File

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

View File

@ -4444,7 +4444,7 @@ static void M_Addons(INT32 choice)
(void)choice; (void)choice;
strlcpy(menupath, srb2home, 1024); strlcpy(menupath, srb2home, 1024);
menupathindex[(menudepthleft = 19)] = strlen(menupath) + 1; menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
if (menupath[menupathindex[menudepthleft]-2] != '/') if (menupath[menupathindex[menudepthleft]-2] != '/')
{ {
@ -4475,17 +4475,26 @@ static void M_DrawAddons(void)
x = currentMenu->x; x = currentMenu->x;
y = currentMenu->y; y = currentMenu->y;
V_DrawString(x, y, 0, menupath); V_DrawString(x, y, V_ALLOWLOWERCASE, menupath);
y += 2*SMALLLINEHEIGHT; y += 2*SMALLLINEHEIGHT;
for (i = dir_on[menudepthleft]; i < sizedirmenu; i++) for (i = dir_on[menudepthleft]; i < sizedirmenu; i++)
{ {
if (y > BASEVIDHEIGHT) break; 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; 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) static void M_HandleAddons(INT32 choice)
{ {
boolean exitmenu = false; // exit to previous menu boolean exitmenu = false; // exit to previous menu
@ -4503,48 +4512,71 @@ static void M_HandleAddons(INT32 choice)
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
break; break;
case KEY_ENTER: case KEY_ENTER:
if (dirmenu[dir_on[menudepthleft]][0] == 0) // folder
{ {
S_StartSound(NULL, sfx_strpst); boolean refresh = true;
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+2); switch (dirmenu[dir_on[menudepthleft]][0])
menupathindex[--menudepthleft] = strlen(menupath); {
menupath[menupathindex[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()) if (!preparefilemenu())
{ {
M_StartMessage(M_GetText("Folder is empty.\n\n(Press a key)\n"),NULL,MM_NOTHING); S_StartSound(NULL, sfx_skid);
menupath[menupathindex[++menudepthleft]] = 0; M_StartMessage(va("%s\nThis folder is empty.\n\n(Press a key)\n", menupath),NULL,MM_NOTHING);
if (!preparefilemenu()) menupath[menupathindex[++menudepthleft]] = 0;
{ }
M_StartMessage(M_GetText("Folder no longer exists!\n\n(Press a key)\n"),NULL,MM_NOTHING); else
M_SetupNextMenu(MISC_AddonsDef.prevMenu); {
return; 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 if (refresh && !preparefilemenu())
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())
{ {
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_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; return;
} }
break;
} }
// intentional fallthrough break;
case KEY_ESCAPE: case KEY_ESCAPE:
exitmenu = true; exitmenu = true;
break; break;