Addfile menu!

Basic as fuck UI, and the controls for manipulating it suck, but the basic elements of the feature set I'm looking for have been implemented in some form or another. More at a later time.

MI, be glad I didn't do this in deeznux ;P
This commit is contained in:
toasterbabe 2017-04-29 16:40:07 +01:00
parent 5608c4b4e7
commit 605580358d
3 changed files with 319 additions and 13 deletions

View File

@ -31,6 +31,7 @@
#include "filesrch.h"
#include "d_netfil.h"
#include "m_misc.h"
#include "z_zone.h"
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
@ -39,7 +40,7 @@
#include <tchar.h>
#define SUFFIX "*"
#define SLASH "\\"
#define SLASH PATHSEP
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#ifndef INVALID_FILE_ATTRIBUTES
@ -285,6 +286,15 @@ closedir (DIR * dirp)
return rc;
}
#endif
char menupath[1024];
size_t menupathindex[20];
size_t menudepthleft = 20;
char **dirmenu;
size_t sizedirmenu;
size_t dir_on;
#if defined (_XBOX) && defined (_MSC_VER)
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
boolean completepath, int maxsearchdepth)
@ -296,6 +306,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
completepath = false;
return FS_NOTFOUND;
}
boolean preparefilemenu(void)
{
return false;
}
#elif defined (_WIN32_WCE)
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
boolean completepath, int maxsearchdepth)
@ -346,6 +362,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
#endif
return FS_NOTFOUND;
}
boolean preparefilemenu(void)
{
return false;
}
#else
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
{
@ -387,25 +408,29 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
{
searchpath[searchpathindex[depthleft]]=0;
dent = readdir(dirhandle[depthleft]);
if (dent)
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
if (!dent)
{
closedir(dirhandle[depthleft++]);
else if (dent->d_name[0]=='.' &&
continue;
}
if (dent->d_name[0]=='.' &&
(dent->d_name[1]=='\0' ||
(dent->d_name[1]=='.' &&
dent->d_name[2]=='\0')))
{
// we don't want to scan uptree
continue;
}
else if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
{
// was the file (re)moved? can't stat it
}
// okay, now we actually want searchpath to incorporate d_name
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
; // was the file (re)moved? can't stat it
else if (S_ISDIR(fsstat.st_mode) && depthleft)
{
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
searchpathindex[--depthleft] = strlen(searchpath) + 1;
dirhandle[depthleft] = opendir(searchpath);
if (!dirhandle[depthleft])
@ -444,6 +469,135 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
free(searchname);
free(searchpathindex);
free(dirhandle);
return retval;
}
#define MAXEXT 5
char ext[MAXEXT][5] = {
".txt", ".cfg", // exec
".wad", ".soc", ".lua"}; // addfile
boolean preparefilemenu(void)
{
DIR *dirhandle;
struct dirent *dent;
struct stat fsstat;
size_t pos, folderpos = 0, numfolders = 0;
for (pos = 0; pos < sizedirmenu; pos++)
{
Z_Free(dirmenu[pos]);
dirmenu[pos] = NULL;
}
sizedirmenu = dir_on = pos = 0;
dirhandle = opendir(menupath);
if (dirhandle == NULL)
return false;
while (true)
{
menupath[menupathindex[menudepthleft]] = 0;
dent = readdir(dirhandle);
if (!dent)
break;
else if (dent->d_name[0]=='.' &&
(dent->d_name[1]=='\0' ||
(dent->d_name[1]=='.' &&
dent->d_name[2]=='\0')))
continue; // we don't want to scan uptree
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
; // was the file (re)moved? can't stat it
else // is a file or directory
{
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
}
else
numfolders++;
sizedirmenu++;
}
}
closedir(dirhandle); // I don't know how to go back to the start of the folder without just opening and closing... if there's a way, it doesn't appear to be easily manipulatable
if (!sizedirmenu)
return false;
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
I_Error("Ran out of memory whilst preparing add-ons menu");
dirhandle = opendir(menupath);
while ((pos+folderpos) < sizedirmenu)
{
menupath[menupathindex[menudepthleft]] = 0;
dent = readdir(dirhandle);
if (!dent)
break;
else if (dent->d_name[0]=='.' &&
(dent->d_name[1]=='\0' ||
(dent->d_name[1]=='.' &&
dent->d_name[2]=='\0')))
continue; // we don't want to scan uptree
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
; // was the file (re)moved? can't stat it
else // is a file or directory
{
char *temp;
size_t len = strlen(dent->d_name)+1;
UINT8 i = 0;
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
folder = 0;
}
else
len += (folder = 1);
if (len > 255)
len = 255;
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[1] = (UINT8)(len);
strlcpy(temp+2, dent->d_name, len);
if (folder)
{
strcpy(temp+len, "/");
dirmenu[folderpos++] = temp;
}
else
dirmenu[numfolders + pos++] = temp;
}
}
menupath[menupathindex[menudepthleft]] = 0;
sizedirmenu = (pos+folderpos); // crash prevention if things change between openings somehow
closedir(dirhandle);
return true;
}
#endif

View File

@ -25,4 +25,14 @@
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
boolean completepath, int maxsearchdepth);
extern char menupath[1024];
extern size_t menupathindex[20];
extern size_t menudepthleft;
extern char **dirmenu;
extern size_t sizedirmenu;
extern size_t dir_on;
boolean preparefilemenu(void);
#endif // __FILESRCH_H__

View File

@ -33,6 +33,9 @@
#include "s_sound.h"
#include "i_system.h"
// Addfile
#include "filesrch.h"
#include "v_video.h"
#include "i_video.h"
#include "keys.h"
@ -330,10 +333,12 @@ menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef;
menu_t OP_MonitorToggleDef;
static void M_ScreenshotOptions(INT32 choice);
static void M_EraseData(INT32 choice);
static void M_Addons(INT32 choice);
// Drawing functions
static void M_DrawGenericMenu(void);
static void M_DrawCenteredMenu(void);
static void M_DrawAddons(void);
static void M_DrawSkyRoom(void);
static void M_DrawChecklist(void);
static void M_DrawEmblemHints(void);
@ -369,6 +374,7 @@ static boolean M_CancelConnect(void);
#endif
static boolean M_ExitPandorasBox(void);
static boolean M_QuitMultiPlayerMenu(void);
static void M_HandleAddons(INT32 choice);
static void M_HandleLevelPlatter(INT32 choice);
static void M_HandleSoundTest(INT32 choice);
static void M_HandleImageDef(INT32 choice);
@ -476,10 +482,11 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum
// ---------
static menuitem_t MainMenu[] =
{
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 84},
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 92},
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 100},
{IT_CALL |IT_STRING, NULL, "options", M_Options, 108},
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 76},
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 84},
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 92},
{IT_CALL |IT_STRING, NULL, "options", M_Options, 100},
{IT_CALL |IT_STRING, NULL, "addons", M_Addons, 108},
{IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116},
};
@ -489,9 +496,15 @@ typedef enum
singleplr,
multiplr,
options,
addons,
quitdoom
} main_e;
static menuitem_t MISC_AddonsMenu[] =
{
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleAddons, 0}, // dummy menuitem for the control func
};
// ---------------------------------
// Pause Menu Mode Attacking Edition
// ---------------------------------
@ -1432,6 +1445,18 @@ static menuitem_t OP_MonitorToggleMenu[] =
// Main Menu and related
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
menu_t MISC_AddonsDef =
{
NULL,
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
&MainDef,
MISC_AddonsMenu,
M_DrawAddons,
0, 0,
0,
NULL
};
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
@ -4414,6 +4439,123 @@ static void M_HandleImageDef(INT32 choice)
// MISC MAIN MENU OPTIONS
// ======================
static void M_Addons(INT32 choice)
{
(void)choice;
strlcpy(menupath, srb2home, 1024);
menupathindex[(menudepthleft = 19)] = strlen(menupath) + 1;
if (menupath[menupathindex[menudepthleft]-2] != '/')
{
menupath[menupathindex[menudepthleft]-1] = '/';
menupath[menupathindex[menudepthleft]] = 0;
}
else
--menupathindex[menudepthleft];
if (!preparefilemenu())
{
M_StartMessage(M_GetText("No files/folders found.\n\n(Press a key)\n"),NULL,MM_NOTHING);
return;
}
MISC_AddonsDef.prevMenu = currentMenu;
M_SetupNextMenu(&MISC_AddonsDef);
}
static void M_DrawAddons(void)
{
INT32 x, y;
size_t i;
// DRAW MENU
x = currentMenu->x;
y = currentMenu->y;
V_DrawString(x, y, 0, menupath);
y += 2*SMALLLINEHEIGHT;
for (i = dir_on; i < sizedirmenu; i++)
{
if (y > BASEVIDHEIGHT) break;
V_DrawString(x, y, 0, dirmenu[i]+2);
y += SMALLLINEHEIGHT;
}
}
static void M_HandleAddons(INT32 choice)
{
boolean exitmenu = false; // exit to previous menu
switch (choice)
{
case KEY_DOWNARROW:
if (dir_on < sizedirmenu-1)
dir_on++;
S_StartSound(NULL, sfx_menu1);
break;
case KEY_UPARROW:
if (dir_on)
dir_on--;
S_StartSound(NULL, sfx_menu1);
break;
case KEY_ENTER:
if (dirmenu[dir_on][0] == 0) // folder
{
S_StartSound(NULL, sfx_strpst);
strcpy(&menupath[menupathindex[menudepthleft--]],dirmenu[dir_on]+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;
}
}
}
else if (dirmenu[dir_on][0] >= 3) // wad/soc/lua
{
S_StartSound(NULL, sfx_strpst);
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on]+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);
M_SetupNextMenu(MISC_AddonsDef.prevMenu);
return;
}
break;
}
case KEY_ESCAPE:
exitmenu = true;
break;
default:
break;
}
if (exitmenu)
{
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
}
}
static void M_PandorasBox(INT32 choice)
{
(void)choice;