mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
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:
parent
5608c4b4e7
commit
605580358d
3 changed files with 319 additions and 13 deletions
172
src/filesrch.c
172
src/filesrch.c
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
150
src/m_menu.c
150
src/m_menu.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue