From 605580358db61796b58d6ada4501487fd1de6a68 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 01/51] 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 --- src/filesrch.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++--- src/filesrch.h | 10 +++ src/m_menu.c | 150 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 319 insertions(+), 13 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index acc176d6a..b90123d4b 100644 --- a/src/filesrch.c +++ b/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 #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 diff --git a/src/filesrch.h b/src/filesrch.h index 33b148d4b..c6d161597 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -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__ diff --git a/src/m_menu.c b/src/m_menu.c index fb8aeedad..a3ee63ecb 100644 --- a/src/m_menu.c +++ b/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; From 881f5e70ce027cebb4eda15f714bc3d4c9961e24 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 02/51] * Additional, better freeing. * Position remembering when going up a level. --- src/filesrch.c | 12 +++++------- src/filesrch.h | 2 +- src/m_menu.c | 34 ++++++++++++++++++++++++---------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index b90123d4b..ff389fa3d 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -293,7 +293,7 @@ size_t menudepthleft = 20; char **dirmenu; size_t sizedirmenu; -size_t dir_on; +size_t dir_on[20]; #if defined (_XBOX) && defined (_MSC_VER) filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, @@ -483,16 +483,14 @@ boolean preparefilemenu(void) DIR *dirhandle; struct dirent *dent; struct stat fsstat; - size_t pos, folderpos = 0, numfolders = 0; + size_t pos = 0, folderpos = 0, numfolders = 0; - for (pos = 0; pos < sizedirmenu; pos++) + for (; sizedirmenu > 0; sizedirmenu--) { - Z_Free(dirmenu[pos]); - dirmenu[pos] = NULL; + Z_Free(dirmenu[sizedirmenu-1]); + dirmenu[sizedirmenu-1] = NULL; } - sizedirmenu = dir_on = pos = 0; - dirhandle = opendir(menupath); if (dirhandle == NULL) diff --git a/src/filesrch.h b/src/filesrch.h index c6d161597..0ce7ff94c 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -31,7 +31,7 @@ extern size_t menudepthleft; extern char **dirmenu; extern size_t sizedirmenu; -extern size_t dir_on; +extern size_t dir_on[20]; boolean preparefilemenu(void); diff --git a/src/m_menu.c b/src/m_menu.c index a3ee63ecb..d491712ae 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4459,6 +4459,8 @@ static void M_Addons(INT32 choice) M_StartMessage(M_GetText("No files/folders found.\n\n(Press a key)\n"),NULL,MM_NOTHING); return; } + else + dir_on[menudepthleft] = 0; MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -4476,7 +4478,7 @@ static void M_DrawAddons(void) V_DrawString(x, y, 0, menupath); y += 2*SMALLLINEHEIGHT; - for (i = dir_on; i < sizedirmenu; i++) + for (i = dir_on[menudepthleft]; i < sizedirmenu; i++) { if (y > BASEVIDHEIGHT) break; V_DrawString(x, y, 0, dirmenu[i]+2); @@ -4491,21 +4493,21 @@ static void M_HandleAddons(INT32 choice) switch (choice) { case KEY_DOWNARROW: - if (dir_on < sizedirmenu-1) - dir_on++; + if (dir_on[menudepthleft] < sizedirmenu-1) + dir_on[menudepthleft]++; S_StartSound(NULL, sfx_menu1); break; case KEY_UPARROW: - if (dir_on) - dir_on--; + if (dir_on[menudepthleft]) + dir_on[menudepthleft]--; S_StartSound(NULL, sfx_menu1); break; case KEY_ENTER: - if (dirmenu[dir_on][0] == 0) // folder + if (dirmenu[dir_on[menudepthleft]][0] == 0) // folder { S_StartSound(NULL, sfx_strpst); - strcpy(&menupath[menupathindex[menudepthleft--]],dirmenu[dir_on]+2); - menupathindex[menudepthleft] = strlen(menupath); + strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+2); + menupathindex[--menudepthleft] = strlen(menupath); menupath[menupathindex[menudepthleft]] = 0; if (!preparefilemenu()) @@ -4519,11 +4521,13 @@ static void M_HandleAddons(INT32 choice) return; } } + else + dir_on[menudepthleft] = 0; } - else if (dirmenu[dir_on][0] >= 3) // wad/soc/lua + 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]+2)); + COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); } else S_StartSound(NULL, sfx_lose); @@ -4540,6 +4544,7 @@ static void M_HandleAddons(INT32 choice) } break; } + // intentional fallthrough case KEY_ESCAPE: exitmenu = true; break; @@ -4549,6 +4554,15 @@ static void M_HandleAddons(INT32 choice) } if (exitmenu) { + for (; sizedirmenu > 0; sizedirmenu--) + { + Z_Free(dirmenu[sizedirmenu-1]); + dirmenu[sizedirmenu-1] = NULL; + } + + Z_Free(dirmenu); + dirmenu = NULL; + if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); else From 20fff0ef23cf9dc68432df5288c986bfb97dba44 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 03/51] 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. --- src/filesrch.c | 42 +++++++++++++------- src/filesrch.h | 20 +++++++++- src/hu_stuff.h | 2 +- src/m_menu.c | 106 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 115 insertions(+), 55 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index ff389fa3d..2985e8373 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -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; } diff --git a/src/filesrch.h b/src/filesrch.h index 0ce7ff94c..84932fd60 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -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); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 5356ba8ac..c2654d209 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -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) diff --git a/src/m_menu.c b/src/m_menu.c index d491712ae..4cee61221 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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; From da003d61c343f625126e8b67569c0a95fb2e3643 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 04/51] Checking whether a file is loaded or not in the menu, and then forbidding multiple load attempts! Obviously this doesn't work for files you run using exec, but that is the nature of things. --- src/filesrch.c | 23 ++++++++++++++++++++++- src/filesrch.h | 14 ++++++++++++-- src/m_menu.c | 13 ++++++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 2985e8373..d3e5e5ec3 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -477,6 +477,8 @@ char exttable[NUM_EXT_TABLE][5] = { ".txt", ".cfg", // exec ".wad", ".soc", ".lua"}; // addfile +char filenamebuf[MAX_WADFILES][MAX_WADPATH]; + boolean preparefilemenu(void) { DIR *dirhandle; @@ -567,7 +569,7 @@ boolean preparefilemenu(void) char *temp; size_t len = strlen(dent->d_name)+1; UINT8 ext = EXT_FOLDER; - size_t folder; + UINT8 folder; if (!S_ISDIR(fsstat.st_mode)) // file { @@ -575,6 +577,25 @@ boolean preparefilemenu(void) 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 + + if (ext >= EXT_MD5) + { + size_t i; + for (i = 0; i < numwadfiles; i++) + { + if (!filenamebuf[i][0]) + { + strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH); + filenamebuf[i][MAX_WADPATH - 1] = '\0'; + nameonly(filenamebuf[i]); + } + if (strcasecmp(dent->d_name, filenamebuf[i])) + continue; + if (checkfilemd5(menupath, wadfiles[i]->md5sum)) + ext |= EXT_LOADED; + } + } + folder = 0; } else diff --git a/src/filesrch.h b/src/filesrch.h index 84932fd60..6bbabb9be 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -42,11 +42,21 @@ typedef enum EXT_START, EXT_TXT = EXT_START, EXT_CFG, - EXT_WAD, + EXT_MD5, + EXT_WAD = EXT_MD5, 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 + NUM_EXT_TABLE = NUM_EXT-EXT_START, + EXT_LOADED = 0x80 + /* + obviously there can only be 0x7F supported extensions in + addons menu because we're cramming this into a char out of + laziness/easy memory allocation (what's the difference?) + and have stolen a bit to show whether it's loaded or not + in practice the size of the data type is probably overkill + toast 02/05/17 + */ } ext_enum; boolean preparefilemenu(void); diff --git a/src/m_menu.c b/src/m_menu.c index 4cee61221..deda69616 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4480,8 +4480,15 @@ static void M_DrawAddons(void) for (i = dir_on[menudepthleft]; i < sizedirmenu; i++) { + UINT32 flags = 0; if (y > BASEVIDHEIGHT) break; - V_DrawString(x, y, ((dirmenu[dir_on[menudepthleft]][0] == EXT_UP) ? 0 : V_ALLOWLOWERCASE), dirmenu[i]+2); + + if ((dirmenu[i][0] & ~EXT_LOADED) != EXT_UP) + flags = V_ALLOWLOWERCASE; + if (dirmenu[i][0] & EXT_LOADED) + flags |= V_TRANSLUCENT; + + V_DrawString(x, y, flags, dirmenu[i]+2); y += SMALLLINEHEIGHT; } } @@ -4492,7 +4499,7 @@ static void M_AddonExec(INT32 ch) return; S_StartSound(NULL, sfx_strpst); - COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); + COM_ImmedExecute(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); } static void M_HandleAddons(INT32 choice) @@ -4562,7 +4569,7 @@ static void M_HandleAddons(INT32 choice) case EXT_WAD: case EXT_SOC: S_StartSound(NULL, sfx_strpst); - COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); + COM_ImmedExecute(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); break; default: S_StartSound(NULL, sfx_lose); From 66f56bbba31c1351f92c29d4ac7fa1bc1007787c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 05/51] * Menu always updates for file load... by doing the refresh in the drawing function, eep. Oh well. * M_StartMessages when file loading goes wrong! (Determined by CONS_Alerts of warning level CONS_WARNING and CONS_ERROR happening after W_LoadWadFile has been called.) * Now actively tries to keep your place on the menu if files are deleted between calls to preparefilemenu(). * More enums! DIR_ (for if you want to try embed more metadata in the dirmenu strings) and REFRESHDIR_ (for refreshing the menu and handling warnings). * Handle changing size menu between calls to opendir() better. * Don't crash on draw/enter attempt if one of the dirmenu's is null. * Moved the addons menu to OP_MainMenu instead of MainMenu for now so it can be tested in MP without needing to mess with several menus. * Display the amount of space used for serverinfo_pak's fileneeded on the addons menu, both visually and with a percentage. --- src/console.c | 4 ++ src/d_clisrv.h | 3 +- src/d_main.c | 3 + src/filesrch.c | 55 ++++++++++++--- src/filesrch.h | 21 +++++- src/m_menu.c | 178 ++++++++++++++++++++++++++++++++----------------- src/w_wad.c | 21 +++--- 7 files changed, 201 insertions(+), 84 deletions(-) diff --git a/src/console.c b/src/console.c index 3702dd560..dcff2d656 100644 --- a/src/console.c +++ b/src/console.c @@ -33,6 +33,7 @@ #include "i_system.h" #include "d_main.h" #include "m_menu.h" +#include "filesrch.h" #ifdef _WINDOWS #include "win32/win_main.h" @@ -1275,12 +1276,15 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...) switch (level) { case CONS_NOTICE: + // no notice for notices, hehe CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:")); break; case CONS_WARNING: + refreshdirmenu |= REFRESHDIR_WARNING; CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:")); break; case CONS_ERROR: + refreshdirmenu |= REFRESHDIR_ERROR; CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:")); break; } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ca82fdc5..da077c682 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -315,6 +315,7 @@ typedef struct } ATTRPACK clientconfig_pak; #define MAXSERVERNAME 32 +#define MAXFILENEEDED 915 // This packet is too large typedef struct { @@ -336,7 +337,7 @@ typedef struct unsigned char mapmd5[16]; UINT8 actnum; UINT8 iszone; - UINT8 fileneeded[915]; // is filled with writexxx (byteptr.h) + UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) } ATTRPACK serverinfo_pak; typedef struct diff --git a/src/d_main.c b/src/d_main.c index 0bba9dc06..94775557e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -74,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "m_cond.h" // condition initialization #include "fastcmp.h" #include "keys.h" +#include "filesrch.h" // refreshdirmenu #ifdef CMAKECONFIG #include "config.h" @@ -586,6 +587,8 @@ void D_SRB2Loop(void) realtics = entertic - oldentertics; oldentertics = entertic; + refreshdirmenu = 0; // not sure where to put this, here as good as any? + #ifdef DEBUGFILE if (!realtics) if (debugload) diff --git a/src/filesrch.c b/src/filesrch.c index d3e5e5ec3..9828c9f25 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -294,6 +294,9 @@ size_t menudepthleft = menudepth; char **dirmenu; size_t sizedirmenu; size_t dir_on[menudepth]; +UINT8 refreshdirmenu = 0; + +size_t packetsizetally = 0; #if defined (_XBOX) && defined (_MSC_VER) filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, @@ -479,12 +482,16 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -boolean preparefilemenu(void) +boolean preparefilemenu(boolean samemenu) { DIR *dirhandle; struct dirent *dent; struct stat fsstat; size_t pos = 0, folderpos = 0, numfolders = 0; + char *tempname = NULL; + + if (samemenu && 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 for (; sizedirmenu > 0; sizedirmenu--) { @@ -516,7 +523,7 @@ boolean preparefilemenu(void) ; // was the file (re)moved? can't stat it else // is a file or directory { - if (!S_ISDIR(fsstat.st_mode)) + if (!S_ISDIR(fsstat.st_mode)) // file { size_t len = strlen(dent->d_name)+1; UINT8 ext; @@ -524,7 +531,7 @@ boolean preparefilemenu(void) 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 + else // directory numfolders++; sizedirmenu++; } @@ -533,7 +540,11 @@ boolean preparefilemenu(void) 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) + { + if (tempname) + Z_Free(tempname); return false; + } if (menudepthleft != menudepth-1) { @@ -573,6 +584,7 @@ boolean preparefilemenu(void) if (!S_ISDIR(fsstat.st_mode)) // file { + if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention 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 @@ -598,17 +610,17 @@ boolean preparefilemenu(void) folder = 0; } - else + else // directory len += (folder = 1); if (len > 255) len = 255; - if (!(temp = Z_Malloc((len+2+folder) * sizeof (char), PU_STATIC, NULL))) + if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL))) I_Error("Ran out of memory whilst preparing add-ons menu"); - temp[0] = ext; - temp[1] = (UINT8)(len); - strlcpy(temp+2, dent->d_name, len); + temp[DIR_TYPE] = ext; + temp[DIR_LEN] = (UINT8)(len); + strlcpy(temp+DIR_STRING, dent->d_name, len); if (folder) { strcpy(temp+len, "/"); @@ -620,15 +632,36 @@ boolean preparefilemenu(void) } if (menudepthleft != menudepth-1) - dirmenu[0] = Z_StrDup("\1\7\x1A UP..."); + dirmenu[0] = Z_StrDup("\1\5UP..."); menupath[menupathindex[menudepthleft]] = 0; - sizedirmenu = (pos+folderpos); // crash prevention if things change between openings somehow + sizedirmenu = (numfolders+pos); // crash prevention if things change between openings somehow + + if (tempname) + { + size_t i; + for (i = 0; i < sizedirmenu; i++) + { + if (!strcmp(dirmenu[i]+DIR_STRING, tempname)) + { + dir_on[menudepthleft] = i; + break; + } + } + Z_Free(tempname); + } if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu; + dir_on[menudepthleft] = sizedirmenu-1; closedir(dirhandle); + + if (!sizedirmenu) + { + Z_Free(dirmenu); + return false; + } + return true; } #endif diff --git a/src/filesrch.h b/src/filesrch.h index 6bbabb9be..caa24f510 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -34,6 +34,9 @@ extern size_t menudepthleft; extern char **dirmenu; extern size_t sizedirmenu; extern size_t dir_on[menudepth]; +extern UINT8 refreshdirmenu; + +extern size_t packetsizetally; typedef enum { @@ -59,6 +62,22 @@ typedef enum */ } ext_enum; -boolean preparefilemenu(void); +typedef enum +{ + DIR_TYPE = 0, + DIR_LEN, + DIR_STRING +} dirname_enum; + +typedef enum +{ + REFRESHDIR_NORMAL = 1, + REFRESHDIR_ADDFILE = 2, + REFRESHDIR_WARNING = 4, + REFRESHDIR_ERROR = 8, + REFRESHDIR_MAX = 16 +} refreshdir_enum; + +boolean preparefilemenu(boolean samemenu); #endif // __FILESRCH_H__ diff --git a/src/m_menu.c b/src/m_menu.c index deda69616..a91f8b61a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -482,11 +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, 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, "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, "addons", M_Addons, 108}, {IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116}, }; @@ -1037,6 +1037,7 @@ static menuitem_t OP_MainMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70}, {IT_CALL | IT_STRING, NULL, "Server Options...", M_ServerOptions, 80}, + {IT_CALL | IT_STRING, NULL, "Add-ons...", M_Addons, 90}, }; static menuitem_t OP_ControlsMenu[] = @@ -4454,7 +4455,7 @@ static void M_Addons(INT32 choice) else --menupathindex[menudepthleft]; - if (!preparefilemenu()) + if (!preparefilemenu(false)) { M_StartMessage(M_GetText("No files/folders found.\n\n(Press a key)\n"),NULL,MM_NOTHING); return; @@ -4471,6 +4472,58 @@ static void M_DrawAddons(void) INT32 x, y; size_t i; + // hack - need to refresh at end of frame to handle addfile... + 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", menupath),NULL,MM_NOTHING); + return M_DrawMessageMenu(); + } + if (refreshdirmenu & REFRESHDIR_ADDFILE) + { + if (!(dirmenu[dir_on[menudepthleft]][DIR_TYPE] & EXT_LOADED)) + { + char *message = NULL; + S_StartSound(NULL, sfx_lose); + if (refreshdirmenu & REFRESHDIR_MAX) + message = va("\x82%s\x80\nMaximum number of add-ons reached.\nThis file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); + else + message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); + M_StartMessage(message,NULL,MM_NOTHING); + return M_DrawMessageMenu(); + } + + if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) + { + S_StartSound(NULL, sfx_skid); + M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING); + return M_DrawMessageMenu(); + } + + S_StartSound(NULL, sfx_strpst); + } + +#define padding 16 +#define h (BASEVIDHEIGHT-(2*padding)) + x = FixedDiv((packetsizetally<>FRACBITS)); + x = padding + (FixedMul(h<>FRACBITS); + V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding, 1, h, 3); + V_DrawFill(BASEVIDWIDTH - padding, padding, 1, h, 3); + V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding-1, padding/4+2, 1, 3); + V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding+h, padding/4+2, 1, 3); + for (y = h; y > 0; y--) + { + UINT8 colours[8] = {42, 40, 58, 65, 90, 97, 98, 113}; // when toast's coding it's british english hacker fucker + if (y < x) break; + V_DrawFill(BASEVIDWIDTH - 5*padding/4, y-1 + padding, padding/4, 1, colours[(8*(y-1))/h]); + } + if (y) + V_DrawFill(BASEVIDWIDTH - 5*padding/4, padding, padding/4, y, 27); +#undef padding +#undef h + // DRAW MENU x = currentMenu->x; y = currentMenu->y; @@ -4482,13 +4535,17 @@ static void M_DrawAddons(void) { UINT32 flags = 0; if (y > BASEVIDHEIGHT) break; + if (!dirmenu[i]) continue; // crash prevention - if ((dirmenu[i][0] & ~EXT_LOADED) != EXT_UP) + if ((dirmenu[i][DIR_TYPE] & ~EXT_LOADED) != EXT_UP) flags = V_ALLOWLOWERCASE; - if (dirmenu[i][0] & EXT_LOADED) + if (dirmenu[i][DIR_TYPE] & EXT_LOADED) flags |= V_TRANSLUCENT; - V_DrawString(x, y, flags, dirmenu[i]+2); + if (dirmenu[i][DIR_LEN] > 16) + V_DrawString(x, y, flags, va("%.13s...", dirmenu[i]+DIR_STRING)); + else + V_DrawString(x, y, flags, dirmenu[i]+DIR_STRING); y += SMALLLINEHEIGHT; } } @@ -4499,7 +4556,7 @@ static void M_AddonExec(INT32 ch) return; S_StartSound(NULL, sfx_strpst); - COM_ImmedExecute(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); + COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); } static void M_HandleAddons(INT32 choice) @@ -4521,66 +4578,65 @@ static void M_HandleAddons(INT32 choice) case KEY_ENTER: { boolean refresh = true; - switch (dirmenu[dir_on[menudepthleft]][0]) + if (!dirmenu[dir_on[menudepthleft]]) + S_StartSound(NULL, sfx_lose); + else { - case EXT_FOLDER: - if (menudepthleft) - { - strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+2); - menupathindex[--menudepthleft] = strlen(menupath); - menupath[menupathindex[menudepthleft]] = 0; - - if (!preparefilemenu()) + switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE]) + { + case EXT_FOLDER: + if (menudepthleft) { - 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; + strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING); + menupathindex[--menudepthleft] = strlen(menupath); + menupath[menupathindex[menudepthleft]] = 0; + + if (!preparefilemenu(false)) + { + S_StartSound(NULL, sfx_skid); + M_StartMessage(va("\x82%s\x80\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_strpst); - dir_on[menudepthleft] = 0; - refresh = false; + S_StartSound(NULL, sfx_lose); + M_StartMessage(va("\x82%s%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); } - } - else - { + break; + case EXT_UP: + S_StartSound(NULL, sfx_skid); + menupath[menupathindex[++menudepthleft]] = 0; + break; + case EXT_TXT: + M_StartMessage(va("\x82%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO); + break; + case EXT_CFG: + M_AddonExec(KEY_ENTER); + break; + case EXT_LUA: +#ifndef HAVE_BLUA 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; + M_StartMessage(va("\x82%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); + break; #endif - // else intentional fallthrough - case EXT_WAD: - case EXT_SOC: - S_StartSound(NULL, sfx_strpst); - COM_ImmedExecute(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+2)); - break; - default: - S_StartSound(NULL, sfx_lose); - } - if (refresh && !preparefilemenu()) - { - 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; + // else intentional fallthrough + case EXT_SOC: + case EXT_WAD: + COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); + break; + default: + S_StartSound(NULL, sfx_lose); + } } + if (refresh) + refreshdirmenu |= REFRESHDIR_NORMAL; } break; diff --git a/src/w_wad.c b/src/w_wad.c index b1b72eec1..1a6e7941a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -34,6 +34,8 @@ #include "z_zone.h" #include "fastcmp.h" +#include "filesrch.h" + #include "i_video.h" // rendermode #include "d_netfil.h" #include "dehacked.h" @@ -294,12 +296,11 @@ UINT16 W_LoadWadFile(const char *filename) UINT32 numlumps; size_t i; INT32 compressed = 0; - size_t packetsize = 0; - serverinfo_pak *dummycheck = NULL; + size_t packetsize; UINT8 md5sum[16]; - // Shut the compiler up. - (void)dummycheck; + if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) + refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier //CONS_Debug(DBG_SETUP, "Loading %s\n", filename); // @@ -308,6 +309,7 @@ UINT16 W_LoadWadFile(const char *filename) if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); + refreshdirmenu |= REFRESHDIR_MAX; return INT16_MAX; } @@ -317,23 +319,22 @@ UINT16 W_LoadWadFile(const char *filename) // Check if wad files will overflow fileneededbuffer. Only the filename part // is send in the packet; cf. - for (i = 0; i < numwadfiles; i++) - { - packetsize += nameonlylength(wadfiles[i]->filename); - packetsize += 22; // MD5, etc. - } + packetsize = packetsizetally; packetsize += nameonlylength(filename); packetsize += 22; - if (packetsize > sizeof(dummycheck->fileneeded)) + if (packetsize > MAXFILENEEDED*sizeof(UINT8)) { CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); + refreshdirmenu |= REFRESHDIR_MAX; if (handle) fclose(handle); return INT16_MAX; } + packetsizetally = packetsize; + // detect dehacked file with the "soc" extension if (!stricmp(&filename[strlen(filename) - 4], ".soc")) { From 055b59f6fbbc1fe371c961ae10ae2f6af978207f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 06/51] Did some research, discovered implementing rewinddir() was as easy as setting a value to zero! Now we don't have to open and close the same folder, but instead just jump back to the beginning. --- src/filesrch.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 9828c9f25..483950ff5 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -256,6 +256,28 @@ readdir (DIR * dirp) return (struct dirent *) 0; } +/* + * rewinddir + * + * Makes the next readdir start from the beginning. + */ +int +rewinddir (DIR * dirp) +{ + errno = 0; + + /* Check for valid DIR struct. */ + if (!dirp) + { + errno = EFAULT; + return -1; + } + + dirp->dd_stat = 0; + + return 0; +} + /* * closedir * @@ -537,12 +559,11 @@ boolean preparefilemenu(boolean samemenu) } } - 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) { if (tempname) Z_Free(tempname); + closedir(dirhandle); return false; } @@ -554,9 +575,12 @@ boolean preparefilemenu(boolean samemenu) } if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL))) + { + closedir(dirhandle); // just in case I_Error("Ran out of memory whilst preparing add-ons menu"); + } - dirhandle = opendir(menupath); + rewinddir(dirhandle); while ((pos+folderpos) < sizedirmenu) { @@ -635,7 +659,7 @@ boolean preparefilemenu(boolean samemenu) dirmenu[0] = Z_StrDup("\1\5UP..."); menupath[menupathindex[menudepthleft]] = 0; - sizedirmenu = (numfolders+pos); // crash prevention if things change between openings somehow + sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind if (tempname) { From 3521fbae4e95bfa7e4559595e1ee1be9055ad5df Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 07/51] Improved the temperature gauge for how close you are to hitting the wadlimit. * It now has a more natural colour graduation. https://cdn.discordapp.com/attachments/272849790285512717/309624385730379777/srb20009.png * It now considers the amount of space adding a file with a very short name would take up, and subtracts that from the total span to get a hopefully more accurate reading. --- src/m_menu.c | 66 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index a91f8b61a..eaf9063a6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4467,6 +4467,49 @@ static void M_Addons(INT32 choice) M_SetupNextMenu(&MISC_AddonsDef); } +#define padding 16 +#define h (BASEVIDHEIGHT-(2*padding)) +#define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker +static void M_DrawTemperature(INT32 x, fixed_t t) +{ + INT32 y; + + // bounds check + if (t > FRACUNIT) + t = FRACUNIT; + /*else if (t < 0) -- not needed + t = 0;*/ + + // scale + t = (FixedMul(h<>FRACBITS); + + // border + V_DrawFill(x - 1, padding, 1, h, 3); + V_DrawFill(x + padding/4, padding, 1, h, 3); + V_DrawFill(x - 1, padding-1, padding/4+2, 1, 3); + V_DrawFill(x - 1, padding+h, padding/4+2, 1, 3); + + // bar itself + for (y = h; y > 0; y--) + { + UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98}; + UINT8 c; + if (y < t) break; + if (y+padding > BASEVIDHEIGHT/2) + c = 113; + else + c = colours[(NUMCOLOURS*(y-1))/(h/2)]; + V_DrawFill(x, y-1 + padding, padding/4, 1, c); + } + + // fill the rest of the backing + if (y) + V_DrawFill(x, padding, padding/4, y, 27); +} +#undef padding +#undef h +#undef NUMCOLOURS + static void M_DrawAddons(void) { INT32 x, y; @@ -4504,25 +4547,12 @@ static void M_DrawAddons(void) S_StartSound(NULL, sfx_strpst); } -#define padding 16 -#define h (BASEVIDHEIGHT-(2*padding)) - x = FixedDiv((packetsizetally< FRACUNIT) + x = FRACUNIT; + V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); - x = padding + (FixedMul(h<>FRACBITS); - V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding, 1, h, 3); - V_DrawFill(BASEVIDWIDTH - padding, padding, 1, h, 3); - V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding-1, padding/4+2, 1, 3); - V_DrawFill(BASEVIDWIDTH - 5*padding/4 - 1, padding+h, padding/4+2, 1, 3); - for (y = h; y > 0; y--) - { - UINT8 colours[8] = {42, 40, 58, 65, 90, 97, 98, 113}; // when toast's coding it's british english hacker fucker - if (y < x) break; - V_DrawFill(BASEVIDWIDTH - 5*padding/4, y-1 + padding, padding/4, 1, colours[(8*(y-1))/h]); - } - if (y) - V_DrawFill(BASEVIDWIDTH - 5*padding/4, padding, padding/4, y, 27); -#undef padding -#undef h + M_DrawTemperature(BASEVIDWIDTH - 20, x); // DRAW MENU x = currentMenu->x; From ca038e8fb6bcf70e3fcb4dd42f21d35ca78b2fd5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 08/51] Split non-drawing functionality outside of M_DrawAddons. Also, make the bar full if you've somehow managed to hit MAX_WADFILES, so you're not susprised. --- src/m_menu.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b5ad8eee6..87c871e6b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4510,19 +4510,17 @@ static void M_DrawTemperature(INT32 x, fixed_t t) #undef h #undef NUMCOLOURS -static void M_DrawAddons(void) +// returns whether to stop addons draw and go to message draw (true), or not (false) +static boolean M_AddonsRefresh(void) { - INT32 x, y; - size_t i; - - // hack - need to refresh at end of frame to handle addfile... 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", menupath),NULL,MM_NOTHING); - return M_DrawMessageMenu(); + return true; } + if (refreshdirmenu & REFRESHDIR_ADDFILE) { if (!(dirmenu[dir_on[menudepthleft]][DIR_TYPE] & EXT_LOADED)) @@ -4534,21 +4532,34 @@ static void M_DrawAddons(void) else message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); M_StartMessage(message,NULL,MM_NOTHING); - return M_DrawMessageMenu(); + return true; } if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) { S_StartSound(NULL, sfx_skid); M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING); - return M_DrawMessageMenu(); + return true; } S_StartSound(NULL, sfx_strpst); } + return false; +} + +static void M_DrawAddons(void) +{ + INT32 x, y; + size_t i; + + // hack - need to refresh at end of frame to handle addfile... + if (refreshdirmenu & M_AddonsRefresh()) + return M_DrawMessageMenu(); + x = FixedDiv((packetsizetally< FRACUNIT) + if (x > FRACUNIT // happens because of how we're shrinkin' it a little + || (numwadfiles >= MAX_WADFILES)) // shouldn't happen unless MAX_WADFILES gets set lower x = FRACUNIT; V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); From 09b659c67a67aaad875324c1f7f40f1b6dc16399 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 09/51] Fix cross-platform preparefilemenu's function signatures, and rename the one input it takes over-all to make more sense. --- src/filesrch.c | 14 ++++++++------ src/filesrch.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 483950ff5..e5ab08f7d 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -332,8 +332,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return FS_NOTFOUND; } -boolean preparefilemenu(void) +boolean preparefilemenu(boolean samedepth) { + (void)samedepth; return false; } @@ -388,8 +389,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return FS_NOTFOUND; } -boolean preparefilemenu(void) +boolean preparefilemenu(boolean samedepth) { + (void)samedepth; return false; } #else @@ -504,7 +506,7 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -boolean preparefilemenu(boolean samemenu) +boolean preparefilemenu(boolean samedepth) { DIR *dirhandle; struct dirent *dent; @@ -512,7 +514,7 @@ boolean preparefilemenu(boolean samemenu) size_t pos = 0, folderpos = 0, numfolders = 0; char *tempname = NULL; - if (samemenu && dirmenu && dirmenu[dir_on[menudepthleft]]) + 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 for (; sizedirmenu > 0; sizedirmenu--) @@ -567,7 +569,7 @@ boolean preparefilemenu(boolean samemenu) return false; } - if (menudepthleft != menudepth-1) + if (menudepthleft != menudepth-1) // Make room for UP... entry { numfolders++; sizedirmenu++; @@ -655,7 +657,7 @@ boolean preparefilemenu(boolean samemenu) } } - if (menudepthleft != menudepth-1) + if (menudepthleft != menudepth-1) // now for UP... entry dirmenu[0] = Z_StrDup("\1\5UP..."); menupath[menupathindex[menudepthleft]] = 0; diff --git a/src/filesrch.h b/src/filesrch.h index caa24f510..34d6fac6f 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -78,6 +78,6 @@ typedef enum REFRESHDIR_MAX = 16 } refreshdir_enum; -boolean preparefilemenu(boolean samemenu); +boolean preparefilemenu(boolean samedepth); #endif // __FILESRCH_H__ From 0c565dc2f81f865a3bc2d3880e53a91015aaca3e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 10/51] Pretty! https://cdn.discordapp.com/attachments/293238104096112641/309741256618147841/srb20005.png Will upload patch.dta when I can. --- src/m_menu.c | 103 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 20 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 87c871e6b..827915b52 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -333,7 +333,9 @@ 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); +static patch_t *addonsp[NUM_EXT+3]; // Drawing functions static void M_DrawGenericMenu(void); @@ -496,7 +498,7 @@ typedef enum singleplr, multiplr, options, - addons, + //addons, quitdoom } main_e; @@ -1453,7 +1455,7 @@ menu_t MISC_AddonsDef = &MainDef, MISC_AddonsMenu, M_DrawAddons, - 0, 0, + 48, 36, 0, NULL }; @@ -4463,6 +4465,24 @@ static void M_Addons(INT32 choice) else dir_on[menudepthleft] = 0; + if (addonsp[0]) // never going to have some provided but not all, saves individually checking + { + size_t i; + for (i = 0; i < NUM_EXT+3; i++) + W_UnlockCachedPatch(addonsp[i]); + } + + addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC); + addonsp[EXT_UP] = W_CachePatchName("M_FBACK", 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); + addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); + addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); + addonsp[NUM_EXT] = W_CachePatchName("M_FLOAD", PU_STATIC); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL1", PU_STATIC); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC); + MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); } @@ -4551,44 +4571,79 @@ static boolean M_AddonsRefresh(void) static void M_DrawAddons(void) { INT32 x, y; - size_t i; + ssize_t i, max; // hack - need to refresh at end of frame to handle addfile... if (refreshdirmenu & M_AddonsRefresh()) return M_DrawMessageMenu(); x = FixedDiv((packetsizetally< FRACUNIT // happens because of how we're shrinkin' it a little - || (numwadfiles >= MAX_WADFILES)) // shouldn't happen unless MAX_WADFILES gets set lower + if ((x > FRACUNIT) // happens because of how we're shrinkin' it a little + || (numwadfiles >= MAX_WADFILES)) // difficult to happen with current limits, but still worth thinking of x = FRACUNIT; V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); - M_DrawTemperature(BASEVIDWIDTH - 20, x); + M_DrawTemperature(BASEVIDWIDTH - 10, x); // DRAW MENU x = currentMenu->x; y = currentMenu->y; - V_DrawString(x, y, V_ALLOWLOWERCASE, menupath); - y += 2*SMALLLINEHEIGHT; + M_DrawLevelPlatterHeader(y - 16, menupath, true); - for (i = dir_on[menudepthleft]; i < sizedirmenu; i++) + // get bottom... + max = dir_on[menudepthleft] + 5; + if (max > (ssize_t)sizedirmenu) + max = sizedirmenu; + + // then top... + i = max - 9; + + // then adjust! + if (i < 0) + { + if ((max -= i) > (ssize_t)sizedirmenu) + max = sizedirmenu; + i = 0; + } + + if (i != 0) + V_DrawCharacter(19, y+4, '\x1A', false); + + for (; i < max; i++) { UINT32 flags = 0; if (y > BASEVIDHEIGHT) break; - if (!dirmenu[i]) continue; // crash prevention + if (dirmenu[i]) + { + if ((UINT8)(dirmenu[i][DIR_TYPE]) != EXT_UP) + flags = V_ALLOWLOWERCASE; + if (dirmenu[i][DIR_TYPE] & EXT_LOADED) + flags |= V_TRANSLUCENT; - if ((dirmenu[i][DIR_TYPE] & ~EXT_LOADED) != EXT_UP) - flags = V_ALLOWLOWERCASE; - if (dirmenu[i][DIR_TYPE] & EXT_LOADED) - flags |= V_TRANSLUCENT; + V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); - if (dirmenu[i][DIR_LEN] > 16) - V_DrawString(x, y, flags, va("%.13s...", dirmenu[i]+DIR_STRING)); - else - V_DrawString(x, y, flags, dirmenu[i]+DIR_STRING); - y += SMALLLINEHEIGHT; + if (dirmenu[i][DIR_TYPE] & EXT_LOADED) + V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT]); + + if ((size_t)i == dir_on[menudepthleft]) + { + tic_t flash = ((skullAnimCounter & 4) ? 2 : 1); + V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+flash]); + } + +#define charsonside 8 + if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3)) + V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1))); +#undef charsonside + else + V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING); + } + y += 16; } + + if (max != (ssize_t)sizedirmenu) + V_DrawCharacter(19, y-12, '\x1B', false); } static void M_AddonExec(INT32 ch) @@ -4637,13 +4692,21 @@ static void M_HandleAddons(INT32 choice) S_StartSound(NULL, sfx_skid); M_StartMessage(va("\x82%s\x80\nThis folder is empty.\n\n(Press a key)\n", menupath),NULL,MM_NOTHING); menupath[menupathindex[++menudepthleft]] = 0; + + 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", menupath),NULL,MM_NOTHING); + return; + } } else { S_StartSound(NULL, sfx_strpst); dir_on[menudepthleft] = 0; - refresh = false; } + refresh = false; } else { From e2ca5b53a1c1d7a48b60f80ad0ba2469a44ea1e3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 11/51] Bonk. Thanks be to MI. https://cdn.discordapp.com/attachments/293238104096112641/309777511871545354/srb20006.png --- src/m_menu.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 827915b52..56745fa98 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3995,7 +3995,7 @@ static void M_HandleLevelPlatter(INT32 choice) static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight) { y += lsheadingheight - 12; - V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0), header); + V_DrawString(19, y, V_ALLOWLOWERCASE|(headerhighlight ? V_YELLOWMAP : 0), header); y += 9; if ((y >= 0) && (y < 200)) { @@ -4530,14 +4530,36 @@ static void M_DrawTemperature(INT32 x, fixed_t t) #undef h #undef NUMCOLOURS -// returns whether to stop addons draw and go to message draw (true), or not (false) +static char *M_AddonsHeaderPath(void) +{ + UINT32 len; + static char header[1024]; + + if (menupath[0] == '.') + strlcpy(header, va("SRB2 folder%s", menupath+1), 1024); + else + strcpy(header, menupath); + + len = strlen(header); + if (len > 35) + { + len = len-35; + header[len] = header[len+1] = header[len+2] = '.'; + } + else + len = 0; + + return header+len; +} + +// 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", menupath),NULL,MM_NOTHING); + 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); return true; } @@ -4583,13 +4605,13 @@ static void M_DrawAddons(void) x = FRACUNIT; V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); - M_DrawTemperature(BASEVIDWIDTH - 10, x); + M_DrawTemperature(BASEVIDWIDTH - 12, x); // DRAW MENU x = currentMenu->x; y = currentMenu->y; - M_DrawLevelPlatterHeader(y - 16, menupath, true); + M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true); // get bottom... max = dir_on[menudepthleft] + 5; @@ -4612,12 +4634,10 @@ static void M_DrawAddons(void) for (; i < max; i++) { - UINT32 flags = 0; + UINT32 flags = V_ALLOWLOWERCASE; if (y > BASEVIDHEIGHT) break; if (dirmenu[i]) { - if ((UINT8)(dirmenu[i][DIR_TYPE]) != EXT_UP) - flags = V_ALLOWLOWERCASE; if (dirmenu[i][DIR_TYPE] & EXT_LOADED) flags |= V_TRANSLUCENT; @@ -4632,7 +4652,7 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+flash]); } -#define charsonside 8 +#define charsonside 14 if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3)) V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1))); #undef charsonside @@ -4681,23 +4701,23 @@ static void M_HandleAddons(INT32 choice) switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE]) { case EXT_FOLDER: + strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING); if (menudepthleft) { - strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING); menupathindex[--menudepthleft] = strlen(menupath); menupath[menupathindex[menudepthleft]] = 0; if (!preparefilemenu(false)) { S_StartSound(NULL, sfx_skid); - M_StartMessage(va("\x82%s\x80\nThis folder is empty.\n\n(Press a key)\n", menupath),NULL,MM_NOTHING); + M_StartMessage(va("\x82%s\x80\nThis folder is empty.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING); menupath[menupathindex[++menudepthleft]] = 0; 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", menupath),NULL,MM_NOTHING); + 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); return; } } @@ -4711,7 +4731,8 @@ static void M_HandleAddons(INT32 choice) else { S_StartSound(NULL, sfx_lose); - M_StartMessage(va("\x82%s%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); + M_StartMessage(va("\x82%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING); + menupath[menupathindex[menudepthleft]] = 0; } break; case EXT_UP: From c7c88b7d99169383a54a05b0cd8568b2f0f43a40 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 12/51] Change sounds and start element for folder navigation. --- src/m_menu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 56745fa98..f03917895 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4723,8 +4723,8 @@ static void M_HandleAddons(INT32 choice) } else { - S_StartSound(NULL, sfx_strpst); - dir_on[menudepthleft] = 0; + S_StartSound(NULL, sfx_menu1); + dir_on[menudepthleft] = 1; } refresh = false; } @@ -4736,7 +4736,7 @@ static void M_HandleAddons(INT32 choice) } break; case EXT_UP: - S_StartSound(NULL, sfx_skid); + S_StartSound(NULL, sfx_menu1); menupath[menupathindex[++menudepthleft]] = 0; break; case EXT_TXT: From ba04e982b2bcc60b2e6ad9758f821d4cc115b77e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 13/51] Make the temperature gauge for added WADs start at zero, not however much the mainwads provided. Also, mainwads now accounts for music_new, and that's added via DEVELOP instead of something we might forget to remove later. --- src/d_main.c | 9 +++++++-- src/filesrch.c | 1 + src/filesrch.h | 1 + src/m_menu.c | 10 +++++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 94775557e..b386f1f2c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -74,7 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "m_cond.h" // condition initialization #include "fastcmp.h" #include "keys.h" -#include "filesrch.h" // refreshdirmenu +#include "filesrch.h" // mainwadstally #ifdef CMAKECONFIG #include "config.h" @@ -876,7 +876,7 @@ static void IdentifyVersion(void) } #endif -#if 1 // This section can be deleted when music_new is merged with music.dta +#ifdef DEVELOP // This section can be deleted when music_new is merged with music.dta { const char *musicfile = "music_new.dta"; const char *musicpath = va(pandf,srb2waddir,musicfile); @@ -1174,6 +1174,11 @@ void D_SRB2Main(void) #ifdef USE_PATCH_DTA ++mainwads; // patch.dta adds one more #endif +#ifdef DEVELOP + ++mainwads; // music_new, too +#endif + + mainwadstally = packetsizetally; cht_Init(); diff --git a/src/filesrch.c b/src/filesrch.c index e5ab08f7d..75ba18d94 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -319,6 +319,7 @@ size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; size_t packetsizetally = 0; +size_t mainwadstally = 0; #if defined (_XBOX) && defined (_MSC_VER) filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, diff --git a/src/filesrch.h b/src/filesrch.h index 34d6fac6f..3a5194571 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -37,6 +37,7 @@ extern size_t dir_on[menudepth]; extern UINT8 refreshdirmenu; extern size_t packetsizetally; +extern size_t mainwadstally; typedef enum { diff --git a/src/m_menu.c b/src/m_menu.c index f03917895..3267f08b7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4599,10 +4599,14 @@ static void M_DrawAddons(void) if (refreshdirmenu & M_AddonsRefresh()) return M_DrawMessageMenu(); - x = FixedDiv((packetsizetally< FRACUNIT) // happens because of how we're shrinkin' it a little - || (numwadfiles >= MAX_WADFILES)) // difficult to happen with current limits, but still worth thinking of + if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of x = FRACUNIT; + else + { + x = FixedDiv(((packetsizetally-mainwadstally)< FRACUNIT) // happens because of how we're shrinkin' it a little + x = FRACUNIT; + } V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); M_DrawTemperature(BASEVIDWIDTH - 12, x); From 8f2490d5889b8e6d52ed191cce0a5209b7ca6831 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 14/51] 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.) --- src/doomtype.h | 4 ++++ src/filesrch.c | 40 ++++++++++++++++++++++++++------ src/filesrch.h | 4 ++++ src/m_menu.c | 63 ++++++++++++++++++++++++++++++++++++++++++-------- src/m_menu.h | 2 ++ src/string.c | 38 ++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 17 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index a711b466d..6ef847cfc 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -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. diff --git a/src/filesrch.c b/src/filesrch.c index 75ba18d94..190913a5e 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -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 diff --git a/src/filesrch.h b/src/filesrch.h index 3a5194571..ff3a6ca50 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -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, diff --git a/src/m_menu.c b/src/m_menu.c index 3267f08b7..97234f199 100644 --- a/src/m_menu.c +++ b/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; } } diff --git a/src/m_menu.h b/src/m_menu.h index 2e20789ef..73da85de6 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -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 diff --git a/src/string.c b/src/string.c index d7f8b3679..5065553ae 100644 --- a/src/string.c +++ b/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 \ No newline at end of file From 308503d5b8eea137ccbbf3cbba4f676e40fd9de5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 15/51] Little polish things I forgot to tweak. --- src/d_main.c | 2 +- src/string.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index b386f1f2c..f2e9ed0c6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -74,7 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "m_cond.h" // condition initialization #include "fastcmp.h" #include "keys.h" -#include "filesrch.h" // mainwadstally +#include "filesrch.h" // refreshdirmenu, mainwadstally #ifdef CMAKECONFIG #include "config.h" diff --git a/src/string.c b/src/string.c index 5065553ae..1e2c14ac2 100644 --- a/src/string.c +++ b/src/string.c @@ -56,8 +56,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz) // stack overflow, eep... char* stristr(char* haystack, const char* needle) { - char* p1 = haystack ; - const char* p2 = needle ; + char* p1 = haystack; + const char* p2 = needle; char* r = ((*p2 == 0) ? haystack : 0); while (*p1 != 0 && *p2 != 0) From 0081fa839d73e5080db19da0cd2efdc8303ae78c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 16/51] Search box is now standardised in style, and the menu is jiggered around a little bit for cleanness! https://cdn.discordapp.com/attachments/293238104096112641/310143962440794114/srb20006.png --- src/m_menu.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 97234f199..7e2574669 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1454,7 +1454,7 @@ menu_t MISC_AddonsDef = &MainDef, MISC_AddonsMenu, M_DrawAddons, - 48, 36, + 50, 28, 0, NULL }; @@ -4620,15 +4620,14 @@ static void M_DrawAddons(void) M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true); - V_DrawString(0, 0, V_ALLOWLOWERCASE, menusearch+1); - +#define numaddonsshown 5 // get bottom... - max = dir_on[menudepthleft] + 5; + max = dir_on[menudepthleft] + numaddonsshown; if (max > (ssize_t)sizedirmenu) max = sizedirmenu; // then top... - i = max - 9; + i = max - (2*numaddonsshown - 1); // then adjust! if (i < 0) @@ -4637,6 +4636,7 @@ static void M_DrawAddons(void) max = sizedirmenu; i = 0; } +#undef numaddonsshown if (i != 0) V_DrawCharacter(19, y+4, '\x1A', false); @@ -4673,6 +4673,15 @@ static void M_DrawAddons(void) if (max != (ssize_t)sizedirmenu) V_DrawCharacter(19, y-12, '\x1B', false); + + y = BASEVIDHEIGHT - currentMenu->y; + + V_DrawSmallScaledPatch(x-(26 + 16), y + 4, 0, addonsp[EXT_SEARCH]); + M_DrawTextBox(x - 26, y, MAXSTRINGLENGTH, 1); + V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); + if (skullAnimCounter < 4) + V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8, + '_' | 0x80, false); } static void M_AddonExec(INT32 ch) From 03eb1a5d563336a047341d92086c5fb1e7994ff1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 17/51] * Make no results instead of generic search search message. https://cdn.discordapp.com/attachments/293238104096112641/310153659356938241/srb20007.png * Page up and page down now work! --- src/filesrch.c | 10 +++++++--- src/filesrch.h | 2 +- src/m_menu.c | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 190913a5e..e9e34e3e9 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -588,10 +588,11 @@ boolean preparefilemenu(boolean samedepth) return false; } - if (menusearch[0] || menudepthleft != menudepth-1) // Make room for UP... or search entry + if ((menusearch[0] && !sizedirmenu) + || (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry { - numfolders++; sizedirmenu++; + numfolders++; folderpos++; } @@ -683,7 +684,10 @@ boolean preparefilemenu(boolean samedepth) } if (menusearch[0]) - dirmenu[0] = Z_StrDup(va("%c\14Search results", EXT_SEARCH)); + { + if (!pos && folderpos == 1) + dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); + } else if (menudepthleft != menudepth-1) // now for UP... entry dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)); diff --git a/src/filesrch.h b/src/filesrch.h index ff3a6ca50..1e05750bd 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -46,7 +46,7 @@ typedef enum { EXT_FOLDER = 0, EXT_UP, - EXT_SEARCH, + EXT_NORESULTS, EXT_START, EXT_TXT = EXT_START, EXT_CFG, diff --git a/src/m_menu.c b/src/m_menu.c index 7e2574669..8688080ce 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -334,7 +334,9 @@ static void M_ScreenshotOptions(INT32 choice); static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); -static patch_t *addonsp[NUM_EXT+3]; +static patch_t *addonsp[NUM_EXT+4]; + +#define numaddonsshown 4 // Drawing functions static void M_DrawGenericMenu(void); @@ -4468,21 +4470,22 @@ static void M_Addons(INT32 choice) if (addonsp[0]) // never going to have some provided but not all, saves individually checking { size_t i; - for (i = 0; i < NUM_EXT+3; i++) + for (i = 0; i < NUM_EXT+4; i++) W_UnlockCachedPatch(addonsp[i]); } 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_NORESULTS] = W_CachePatchName("M_FNOPE", 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); addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL1", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC); + addonsp[NUM_EXT] = W_CachePatchName("M_FSEL1", PU_STATIC); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL2", PU_STATIC); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -4620,14 +4623,13 @@ static void M_DrawAddons(void) M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true); -#define numaddonsshown 5 // get bottom... - max = dir_on[menudepthleft] + numaddonsshown; + max = dir_on[menudepthleft] + numaddonsshown + 1; if (max > (ssize_t)sizedirmenu) max = sizedirmenu; // then top... - i = max - (2*numaddonsshown - 1); + i = max - (2*numaddonsshown + 1); // then adjust! if (i < 0) @@ -4636,7 +4638,6 @@ static void M_DrawAddons(void) max = sizedirmenu; i = 0; } -#undef numaddonsshown if (i != 0) V_DrawCharacter(19, y+4, '\x1A', false); @@ -4653,11 +4654,11 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); if (dirmenu[i][DIR_TYPE] & EXT_LOADED) - V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT]); + V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+2]); if ((size_t)i == dir_on[menudepthleft]) { - tic_t flash = ((skullAnimCounter & 4) ? 2 : 1); + tic_t flash = ((skullAnimCounter/4) ? 1 : 0); V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+flash]); } @@ -4676,7 +4677,7 @@ static void M_DrawAddons(void) y = BASEVIDHEIGHT - currentMenu->y; - V_DrawSmallScaledPatch(x-(26 + 16), y + 4, 0, addonsp[EXT_SEARCH]); + V_DrawSmallScaledPatch(x-(26 + 16), y + 4, 0, addonsp[NUM_EXT+3]); M_DrawTextBox(x - 26, y, MAXSTRINGLENGTH, 1); V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); if (skullAnimCounter < 4) @@ -4749,6 +4750,22 @@ static void M_HandleAddons(INT32 choice) dir_on[menudepthleft]--; S_StartSound(NULL, sfx_menu1); break; + case KEY_PGDN: + { + UINT8 i; + for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--) + dir_on[menudepthleft]++; + } + S_StartSound(NULL, sfx_menu1); + break; + case KEY_PGUP: + { + UINT8 i; + for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--) + dir_on[menudepthleft]--; + } + S_StartSound(NULL, sfx_menu1); + break; case KEY_ENTER: { boolean refresh = true; From 50db610fc8ce32ec9fc11f3951dde5d8740e940e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 18/51] Fixed bug for single folder search results. --- src/filesrch.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index e9e34e3e9..d0c97c498 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -523,6 +523,7 @@ boolean preparefilemenu(boolean samedepth) struct stat fsstat; size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0; char *tempname = NULL; + boolean noresults = false; if (samedepth) { @@ -588,7 +589,7 @@ boolean preparefilemenu(boolean samedepth) return false; } - if ((menusearch[0] && !sizedirmenu) + if (((noresults = (menusearch[0] && !sizedirmenu))) || (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry { sizedirmenu++; @@ -683,12 +684,9 @@ boolean preparefilemenu(boolean samedepth) } } - if (menusearch[0]) - { - if (!pos && folderpos == 1) - dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); - } - else if (menudepthleft != menudepth-1) // now for UP... entry + if (noresults) // no results + dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); + else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)); menupath[menupathindex[menudepthleft]] = 0; From b2cbbb63c6c90d6d37d201a86536b25709cfcb4f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 19/51] Prevent holding down one of the string change keys being free lag generation. --- src/m_menu.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8688080ce..f57059dfb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4703,12 +4703,19 @@ static boolean M_ChangeStringAddons(INT32 choice) switch (choice) { case KEY_DEL: - len = menusearch[1] = 0; - return true; + if (len) + { + len = menusearch[1] = 0; + return true; + } + break; case KEY_BACKSPACE: - if (len > 0) + if (len) + { menusearch[1+--len] = 0; - return true; + return true; + } + break; default: if (choice >= 32 && choice <= 127) { @@ -4716,8 +4723,8 @@ static boolean M_ChangeStringAddons(INT32 choice) { menusearch[1+len++] = (char)choice; menusearch[1+len] = 0; + return true; } - return true; } break; } From afe24bd4f0bf7a2db722d5d7c255676251f8c70a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 20/51] Get rid of stack overflow code because filesystem case insensitivity is Windows exlcusive, so we can just create a wrapper function for there instead of rolling our own. --- src/doomtype.h | 4 ---- src/filesrch.c | 25 +++++++++++++++++++++++-- src/string.c | 38 -------------------------------------- 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 6ef847cfc..a711b466d 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -170,10 +170,6 @@ 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. diff --git a/src/filesrch.c b/src/filesrch.c index d0c97c498..a0c9b8231 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -510,7 +510,19 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -#define searchdir if (menusearch[0] && !stristr(dent->d_name, menusearch+1))\ +#ifdef _WIN32 +static char *strsystemstr(char *haystack, char *needle) +{ + char uprhaystack[128]; + strlcpy(uprhaystack, haystack, 128); + strupr(uprhaystack); + return strstr(uprhaystack, needle); +} +#else +#define strsystemstr(haystack, needle) strstr(haystack, needle) +#endif + +#define searchdir if (menusearch[0] && !strsystemstr(dent->d_name, localmenusearch))\ {\ rejected++;\ continue;\ @@ -524,6 +536,7 @@ boolean preparefilemenu(boolean samedepth) size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0; char *tempname = NULL; boolean noresults = false; + char localmenusearch[MAXSTRINGLENGTH] = ""; if (samedepth) { @@ -544,6 +557,14 @@ boolean preparefilemenu(boolean samedepth) if (dirhandle == NULL) return false; + if (menusearch[0]) + { + strcpy(localmenusearch, menusearch+1); +#ifdef _WIN32 + strupr(localmenusearch); +#endif + } + while (true) { menupath[menupathindex[menudepthleft]] = 0; @@ -651,7 +672,7 @@ boolean preparefilemenu(boolean samedepth) filenamebuf[i][MAX_WADPATH - 1] = '\0'; nameonly(filenamebuf[i]); } - if (strcasecmp(dent->d_name, filenamebuf[i])) + if (strcmp(dent->d_name, filenamebuf[i])) continue; if (checkfilemd5(menupath, wadfiles[i]->md5sum)) ext |= EXT_LOADED; diff --git a/src/string.c b/src/string.c index 1e2c14ac2..5dcd9183c 100644 --- a/src/string.c +++ b/src/string.c @@ -49,42 +49,4 @@ size_t strlcpy(char *dst, const char *src, size_t siz) return strlcat(dst, src, 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 \ No newline at end of file From b1785e1f975438e65a1b9c8c3f22e685070bc88c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 21/51] Improved conditions for case insensitive filesystem support. --- src/filesrch.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index a0c9b8231..5b41f4f22 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -510,7 +510,11 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -#ifdef _WIN32 +#if defined(_WIN32) || defined(_WINDOWS) +#define CASEINSENSITIVE_FILESYSTEM +#endif + +#ifdef CASEINSENSITIVE_FILESYSTEM static char *strsystemstr(char *haystack, char *needle) { char uprhaystack[128]; @@ -560,7 +564,7 @@ boolean preparefilemenu(boolean samedepth) if (menusearch[0]) { strcpy(localmenusearch, menusearch+1); -#ifdef _WIN32 +#ifdef CASEINSENSITIVE_FILESYSTEM strupr(localmenusearch); #endif } From de46e72545d8e0bed047e657d61520442e086967 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 22/51] * "Type to search..." prompt. * Menu shuffling for addons. Shows up on main menu and MP pause menu if you're host/admin (not encouraged in SP). * The menu yells at you in red text if you're playing, warning of issues. --- src/m_menu.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f57059dfb..1a0e6e126 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -485,11 +485,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, "addons", M_Addons, 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}, }; @@ -499,7 +499,7 @@ typedef enum singleplr, multiplr, options, - //addons, + addons, quitdoom } main_e; @@ -530,27 +530,29 @@ typedef enum // --------------------- static menuitem_t MPauseMenu[] = { - {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24}, + {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 8}, + {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 16}, + {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 24}, - {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40}, - {IT_CALL | IT_STRING, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen - {IT_CALL | IT_STRING, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40}, + {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48}, - {IT_CALL | IT_STRING, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone - {IT_CALL | IT_STRING, NULL, "Options", M_Options, 64}, + {IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone + {IT_STRING | IT_CALL, NULL, "Options", M_Options, 64}, - {IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80}, - {IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88}, + {IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 80}, + {IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 88}, }; typedef enum { mpause_scramble = 0, mpause_switchmap, + mpause_addons, mpause_continue, mpause_psetupsplit, @@ -592,6 +594,7 @@ typedef enum spause_continue, spause_retry, spause_options, + spause_title, spause_quit } spause_e; @@ -1040,7 +1043,6 @@ static menuitem_t OP_MainMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70}, {IT_CALL | IT_STRING, NULL, "Server Options...", M_ServerOptions, 80}, - {IT_CALL | IT_STRING, NULL, "Add-ons...", M_Addons, 90}, }; static menuitem_t OP_ControlsMenu[] = @@ -2684,6 +2686,7 @@ void M_StartControlPanel(void) else // multiplayer { MPauseMenu[mpause_switchmap].status = IT_DISABLED; + MPauseMenu[mpause_addons].status = IT_DISABLED; MPauseMenu[mpause_scramble].status = IT_DISABLED; MPauseMenu[mpause_psetupsplit].status = IT_DISABLED; MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED; @@ -2695,6 +2698,7 @@ void M_StartControlPanel(void) if ((server || adminplayer == consoleplayer)) { MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL; + MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL; if (G_GametypeHasTeams()) MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU; } @@ -4605,6 +4609,9 @@ static void M_DrawAddons(void) if (refreshdirmenu & M_AddonsRefresh()) return M_DrawMessageMenu(); + if (Playing()) + V_DrawCenteredString(BASEVIDWIDTH/2, 4, V_REDMAP, "Adding files mid-game may cause problems."); + if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of x = FRACUNIT; else @@ -4679,7 +4686,10 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(26 + 16), y + 4, 0, addonsp[NUM_EXT+3]); M_DrawTextBox(x - 26, y, MAXSTRINGLENGTH, 1); - V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); + if (menusearch[0]) + V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); + else + V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search..."); if (skullAnimCounter < 4) V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8, '_' | 0x80, false); From da239d36e880fb1d0146c92563bb9223289c3aa3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 23/51] background https://cdn.discordapp.com/attachments/293238104096112641/310476917218344970/srb20012.png --- src/m_menu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1a0e6e126..14a922d05 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4630,6 +4630,8 @@ static void M_DrawAddons(void) M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true); + V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1) - (y - 1), 159); + // get bottom... max = dir_on[menudepthleft] + numaddonsshown + 1; if (max > (ssize_t)sizedirmenu) @@ -4684,8 +4686,8 @@ static void M_DrawAddons(void) y = BASEVIDHEIGHT - currentMenu->y; - V_DrawSmallScaledPatch(x-(26 + 16), y + 4, 0, addonsp[NUM_EXT+3]); - M_DrawTextBox(x - 26, y, MAXSTRINGLENGTH, 1); + V_DrawSmallScaledPatch(x-(21 + 5 + 16), y + 4, 0, addonsp[NUM_EXT+3]); + M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1); if (menusearch[0]) V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); else From bf740f60ccad412f6f38cac252d8ca9fae60aa2f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 24/51] Whitelist menu stuff so VAda can have his XP themed icon set without setting ismodified. ;P --- src/w_wad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/w_wad.c b/src/w_wad.c index 1a6e7941a..f51b49d4d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1240,6 +1240,7 @@ int W_VerifyNMUSlumps(const char *filename) {"TNYFN", 5}, // Tiny console font changes {"STT", 3}, // Acceptable HUD changes (Score Time Rings) {"YB_", 3}, // Intermission graphics, goes with the above + {"M_", 2}, // As does menu stuff {NULL, 0}, }; From a59dc43cfd6a1fd54bc7549400e05a558b897b6e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 25/51] Appropriate rename. (I would have done more in this commit, but I need to merge deez nux.) --- src/filesrch.c | 2 +- src/filesrch.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 5b41f4f22..68bc65ecf 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -665,7 +665,7 @@ boolean preparefilemenu(boolean samedepth) searchdir; - if (ext >= EXT_MD5) + if (ext >= EXT_LOADSTART) { size_t i; for (i = 0; i < numwadfiles; i++) diff --git a/src/filesrch.h b/src/filesrch.h index 1e05750bd..2a6657010 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -51,7 +51,7 @@ typedef enum EXT_TXT = EXT_START, EXT_CFG, EXT_MD5, - EXT_WAD = EXT_MD5, + EXT_WAD = EXT_LOADSTART, EXT_SOC, EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt NUM_EXT, From f3b054fc8f27b95d5c29da49e164b7292263c6cb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 26/51] Consistency with deeznux. --- src/m_menu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e26ebb5fd..9311c9e35 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4854,7 +4854,7 @@ static void M_DrawAddons(void) } if (i != 0) - V_DrawCharacter(19, y+4, '\x1A', false); + V_DrawString(19, y+4, V_YELLOWMAP, "\x1A"); for (; i < max; i++) { @@ -4874,6 +4874,7 @@ static void M_DrawAddons(void) { tic_t flash = ((skullAnimCounter/4) ? 1 : 0); V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+flash]); + flags = V_ALLOWLOWERCASE|V_YELLOWMAP; } #define charsonside 14 @@ -4887,7 +4888,7 @@ static void M_DrawAddons(void) } if (max != (ssize_t)sizedirmenu) - V_DrawCharacter(19, y-12, '\x1B', false); + V_DrawString(19, y-12, V_YELLOWMAP, "\x1B"); y = BASEVIDHEIGHT - currentMenu->y; @@ -5603,9 +5604,7 @@ static void M_DrawChecklist(void) finishchecklist: if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks. - { V_DrawString(10, currentMenu->y+(scrollareaheight*2), V_YELLOWMAP, "\x1B"); - } } #define NUMHINTS 5 From 4e0d01580321861f3afdf5b9edeb2e5a7c525bfe Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 27/51] Good: * Improved layout of addons menu. * Disabled input for 5 tics after a console-touching enter key command on the menu, so that weird stuff doesn't happen. * Added Add-on options. * cv_addons_option - chooses save location. A little smaller in scope than the weird Default/HOME/SRB2/Custom thing for screenshots - now it's SRB2 Folder and Custom. * cv_addons_folder - goes with Custom for above. * cv_addons_md5 - chooses whether to identify files on the addons menu with name comparison only, or with checksum comparison as well (more intensive hence not default). * cv_addons_showall - chooses whether to show just supported file extensions, or all * Some minor other refactors. Bad: * Screenshot options menu crashes on access for some reason (to do with itemOn not being valid?????) looking into --- src/d_netcmd.c | 7 +++ src/filesrch.c | 33 +++++++++---- src/filesrch.h | 2 + src/m_menu.c | 122 +++++++++++++++++++++++++++++++++---------------- src/m_menu.h | 15 ++++++ src/m_misc.c | 2 +- 6 files changed, 131 insertions(+), 50 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 125e9d2c3..f8c9e5251 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -37,6 +37,7 @@ #include "d_main.h" #include "m_random.h" #include "f_finale.h" +#include "filesrch.h" #include "mserv.h" #include "md5.h" #include "z_zone.h" @@ -714,6 +715,12 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_firenaxis); CV_RegisterVar(&cv_firenaxis2); + // filesrch.c + CV_RegisterVar(&cv_addons_option); + CV_RegisterVar(&cv_addons_folder); + CV_RegisterVar(&cv_addons_md5); + CV_RegisterVar(&cv_addons_showall); + // WARNING: the order is important when initialising mouse2 // we need the mouse2port CV_RegisterVar(&cv_mouse2port); diff --git a/src/filesrch.c b/src/filesrch.c index 68bc65ecf..8b6f99dad 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -32,7 +32,7 @@ #include "d_netfil.h" #include "m_misc.h" #include "z_zone.h" -#include "doomtype.h" +#include "m_menu.h" // Addons_option_Onchange #if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX) @@ -310,6 +310,15 @@ closedir (DIR * dirp) } #endif +static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, {2, "SRB2 Folder"},*/ {3, "CUSTOM"}, {0, NULL}}; +consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Checksum"}, {0, NULL}}; +consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + char menupath[1024]; size_t menupathindex[menudepth]; size_t menudepthleft = menudepth; @@ -590,11 +599,14 @@ boolean preparefilemenu(boolean samedepth) { if (!S_ISDIR(fsstat.st_mode)) // file { - size_t len = strlen(dent->d_name)+1; - 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 + if (!cv_addons_showall.value) + { + size_t len = strlen(dent->d_name)+1; + 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 + } searchdir; } else // directory @@ -660,7 +672,7 @@ boolean preparefilemenu(boolean samedepth) if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention 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 + if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file ext += EXT_START; // moving to be appropriate position searchdir; @@ -676,10 +688,13 @@ boolean preparefilemenu(boolean samedepth) filenamebuf[i][MAX_WADPATH - 1] = '\0'; nameonly(filenamebuf[i]); } + if (strcmp(dent->d_name, filenamebuf[i])) continue; - if (checkfilemd5(menupath, wadfiles[i]->md5sum)) - ext |= EXT_LOADED; + if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum)) + continue; + + ext |= EXT_LOADED; } } diff --git a/src/filesrch.h b/src/filesrch.h index fb2badd24..dafde07cd 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -8,6 +8,8 @@ #include "d_netfil.h" #include "m_menu.h" // MAXSTRINGLENGTH +extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall; + /** \brief The filesearch function This function search files, manly WADs and return back the status of the file diff --git a/src/m_menu.c b/src/m_menu.c index 9311c9e35..960cfe51d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -213,14 +213,13 @@ menu_t SPauseDef; // Level Select static levelselect_t levelselect = {0, NULL}; -static UINT8 levelselectselect[4]; +static UINT8 levelselectselect[3]; static patch_t *levselp[2][3]; static INT32 lsoffs[2]; #define lsrow levelselectselect[0] #define lscol levelselectselect[1] -#define lstic levelselectselect[2] -#define lshli levelselectselect[3] +#define lshli levelselectselect[2] #define lshseperation 101 #define lsbasevseperation 62 @@ -337,7 +336,9 @@ static void M_ScreenshotOptions(INT32 choice); static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); -static patch_t *addonsp[NUM_EXT+4]; +static void M_AddonsOptions(INT32 choice); +static patch_t *addonsp[NUM_EXT+5]; +static UINT8 addonsresponselimit = 0; #define numaddonsshown 4 @@ -1336,9 +1337,11 @@ static menuitem_t OP_SoundOptionsMenu[] = static menuitem_t OP_DataOptionsMenu[] = { - {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, + {IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 10}, - {IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 20}, + {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 30}, + + {IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 50}, }; static menuitem_t OP_ScreenshotOptionsMenu[] = @@ -1385,6 +1388,20 @@ static menuitem_t OP_EraseDataMenu[] = {IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40}, }; +static menuitem_t OP_AddonsOptionsMenu[] = +{ + {IT_HEADER, NULL, "Menu", NULL, 0}, + {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 6}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 11}, + {IT_STRING|IT_CVAR, NULL, "Identify loaded files via", &cv_addons_md5, 25}, + {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 30}, +}; + +enum +{ + op_addons_folder = 2, +}; + static menuitem_t OP_ServerOptionsMenu[] = { {IT_HEADER, NULL, "General", NULL, 0}, @@ -1834,17 +1851,7 @@ menu_t OP_SoundOptionsDef = NULL }; -menu_t OP_ServerOptionsDef = -{ - "M_SERVER", - sizeof (OP_ServerOptionsMenu)/sizeof (menuitem_t), - &OP_MainDef, - OP_ServerOptionsMenu, - M_DrawGenericScrollMenu, - 30, 30, - 0, - NULL -}; +menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); menu_t OP_MonitorToggleDef = { @@ -1886,7 +1893,7 @@ menu_t OP_OpenGLColorDef = NULL }; #endif -menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 30, 30); +menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); menu_t OP_ScreenshotOptionsDef = { @@ -1900,6 +1907,8 @@ menu_t OP_ScreenshotOptionsDef = NULL }; +menu_t OP_AddonsOptionsDef = DEFAULTSCROLLMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); + menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); // ========================================================================== @@ -2118,6 +2127,12 @@ void Moviemode_mode_Onchange(void) OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR; } +void Addons_option_Onchange(void) +{ + OP_AddonsOptionsMenu[op_addons_folder].status = + (cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED); +} + // ========================================================================== // END ORGANIZATION STUFF. // ========================================================================== @@ -3945,7 +3960,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt) I_Error("Insufficient memory to prepare level platter"); // done here so lsrow and lscol can be set if cv_nextmap is on the platter - lsrow = lscol = lstic = lshli = lsoffs[0] = lsoffs[1] = 0; + lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0; while (mapnum < NUMMAPS) { @@ -4216,9 +4231,7 @@ void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlig } y++; if ((y >= 0) && (y < 200)) - { V_DrawFill(19, y, 282, 1, 26); - } } static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight) @@ -4331,9 +4344,6 @@ static void M_DrawLevelPlatterMenu(void) INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow); const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation)); - if (++lstic == 32) - lstic = 0; - if (gamestate == GS_TIMEATTACK) V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); @@ -4353,7 +4363,7 @@ static void M_DrawLevelPlatterMenu(void) } // draw cursor box - V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, ((lstic & 8) ? levselp[sizeselect][0] : levselp[sizeselect][1])); + V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)])); if (levelselect.rows[lsrow].maplist[lscol]) V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE)); @@ -4653,11 +4663,31 @@ static void M_HandleImageDef(INT32 choice) // MISC MAIN MENU OPTIONS // ====================== -static void M_Addons(INT32 choice) +static void M_AddonsOptions(INT32 choice) { (void)choice; + Addons_option_Onchange(); - strlcpy(menupath, srb2home, 1024); + M_SetupNextMenu(&OP_AddonsOptionsDef); +} + +static void M_Addons(INT32 choice) +{ + const char *pathname = "."; + + (void)choice; + + /*if (cv_addons_option.value == 0) + pathname = srb2home; usehome ? srb2home : srb2path; + else if (cv_addons_option.value == 1) + pathname = srb2home; + else if (cv_addons_option.value == 2) + pathname = srb2path; + else*/ + if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0') + pathname = cv_addons_folder.string; + + strlcpy(menupath, pathname, 1024); menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1; if (menupath[menupathindex[menudepthleft]-2] != '/') @@ -4679,7 +4709,7 @@ static void M_Addons(INT32 choice) if (addonsp[0]) // never going to have some provided but not all, saves individually checking { size_t i; - for (i = 0; i < NUM_EXT+4; i++) + for (i = 0; i < NUM_EXT+5; i++) W_UnlockCachedPatch(addonsp[i]); } @@ -4691,10 +4721,11 @@ static void M_Addons(INT32 choice) addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FSEL1", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL2", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); + addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL1", PU_STATIC); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FLOAD", PU_STATIC); + addonsp[NUM_EXT+4] = W_CachePatchName("M_FSRCH", PU_STATIC); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -4754,9 +4785,9 @@ static char *M_AddonsHeaderPath(void) strcpy(header, menupath); len = strlen(header); - if (len > 35) + if (len > 34) { - len = len-35; + len = len-34; header[len] = header[len+1] = header[len+2] = '.'; } else @@ -4814,6 +4845,9 @@ static void M_DrawAddons(void) if (refreshdirmenu & M_AddonsRefresh()) return M_DrawMessageMenu(); + if (addonsresponselimit) + addonsresponselimit--; + if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 4, V_REDMAP, "Adding files mid-game may cause problems."); @@ -4827,13 +4861,17 @@ static void M_DrawAddons(void) } V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); - M_DrawTemperature(BASEVIDWIDTH - 12, x); + M_DrawTemperature(BASEVIDWIDTH - 16, x); // DRAW MENU x = currentMenu->x; y = currentMenu->y; - M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); + //M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width + V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath()); + V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), (MAXSTRINGLENGTH*8+6 - 1), 1, yellowmap[3]); + V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26); + V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26); V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1) - (y - 1), 159); @@ -4868,12 +4906,11 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); if (dirmenu[i][DIR_TYPE] & EXT_LOADED) - V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+2]); + V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]); if ((size_t)i == dir_on[menudepthleft]) { - tic_t flash = ((skullAnimCounter/4) ? 1 : 0); - V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+flash]); + V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+1+((skullAnimCounter/4) ? 1 : 0)]); flags = V_ALLOWLOWERCASE|V_YELLOWMAP; } @@ -4892,7 +4929,7 @@ static void M_DrawAddons(void) y = BASEVIDHEIGHT - currentMenu->y; - V_DrawSmallScaledPatch(x-(21 + 5 + 16), y + 4, 0, addonsp[NUM_EXT+3]); + V_DrawSmallScaledPatch(x-(21 + 5 + 16), y + 4, 0, addonsp[NUM_EXT+4]); M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1); if (menusearch[0]) V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); @@ -4910,6 +4947,7 @@ static void M_AddonExec(INT32 ch) S_StartSound(NULL, sfx_strpst); COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); + addonsresponselimit = 5; } #define len menusearch[0] @@ -4954,6 +4992,9 @@ static void M_HandleAddons(INT32 choice) { boolean exitmenu = false; // exit to previous menu + if (addonsresponselimit) + return; + if (M_ChangeStringAddons(choice)) { if (!preparefilemenu(true)) @@ -5053,6 +5094,7 @@ static void M_HandleAddons(INT32 choice) case EXT_SOC: case EXT_WAD: COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); + addonsresponselimit = 5; break; default: S_StartSound(NULL, sfx_lose); diff --git a/src/m_menu.h b/src/m_menu.h index 73da85de6..53dc266d1 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -251,6 +251,9 @@ void Nextmap_OnChange(void); void Moviemode_mode_Onchange(void); void Screenshot_option_Onchange(void); +// Addons menu updating +void Addons_option_Onchange(void); + // These defines make it a little easier to make menus #define DEFAULTMENUSTYLE(header, source, prev, x, y)\ {\ @@ -264,6 +267,18 @@ void Screenshot_option_Onchange(void); NULL\ } +#define DEFAULTSCROLLMENUSTYLE(header, source, prev, x, y)\ +{\ + header,\ + sizeof(source)/sizeof(menuitem_t),\ + prev,\ + source,\ + M_DrawGenericScrollMenu,\ + x, y,\ + 0,\ + NULL\ +} + #define PAUSEMENUSTYLE(source, x, y)\ {\ NULL,\ diff --git a/src/m_misc.c b/src/m_misc.c index f4e94189d..69fbd1a8f 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -100,7 +100,7 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2 consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}}; consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL}; From 59dfba967fc3a1e483c1dcd7372af4d707093a8a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 28/51] Change from "on/off" to "yes/no" - makes more sense here --- src/m_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_misc.c b/src/m_misc.c index 69fbd1a8f..d271558fb 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -100,7 +100,7 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2 consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}}; consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL}; From 4c495cafc98b9759b795b3028ca201d96e6aea1e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 29 Apr 2017 16:40:07 +0100 Subject: [PATCH 29/51] thanks mi for my life --- src/m_menu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 960cfe51d..6ba7fac37 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1338,10 +1338,9 @@ static menuitem_t OP_SoundOptionsMenu[] = static menuitem_t OP_DataOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 10}, + {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 20}, - {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 30}, - - {IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 50}, + {IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 40}, }; static menuitem_t OP_ScreenshotOptionsMenu[] = @@ -5232,7 +5231,7 @@ static void M_Options(INT32 choice) OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // if the player is playing _at all_, disable the erase data options - OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + OP_DataOptionsMenu[2].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); From 1fc835e4a36e829a16f99f23bc4c42de5aaf4ad9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 17:28:48 +0100 Subject: [PATCH 30/51] Made the refreshdirmenu stuff SLIGHTLY less hacky. --- src/filesrch.h | 3 ++- src/m_menu.c | 5 +++-- src/p_setup.c | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/filesrch.h b/src/filesrch.h index dafde07cd..e9092b590 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -82,7 +82,8 @@ typedef enum REFRESHDIR_ADDFILE = 2, REFRESHDIR_WARNING = 4, REFRESHDIR_ERROR = 8, - REFRESHDIR_MAX = 16 + REFRESHDIR_NOTLOADED = 16, + REFRESHDIR_MAX = 32 } refreshdir_enum; boolean preparefilemenu(boolean samedepth); diff --git a/src/m_menu.c b/src/m_menu.c index 6ba7fac37..3712c863f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4810,7 +4810,9 @@ static boolean M_AddonsRefresh(void) if (refreshdirmenu & REFRESHDIR_ADDFILE) { - if (!(dirmenu[dir_on[menudepthleft]][DIR_TYPE] & EXT_LOADED)) + addonsresponselimit = 0; + + if (refreshdirmenu & REFRESHDIR_NOTLOADED) { char *message = NULL; S_StartSound(NULL, sfx_lose); @@ -4946,7 +4948,6 @@ static void M_AddonExec(INT32 ch) S_StartSound(NULL, sfx_strpst); COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); - addonsresponselimit = 5; } #define len menusearch[0] diff --git a/src/p_setup.c b/src/p_setup.c index 02a621845..c7f247ccd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -54,6 +54,8 @@ #include "v_video.h" +#include "filesrch.h" // refreshdirmenu + // wipes #include "f_finale.h" @@ -3054,6 +3056,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) { + refreshdirmenu |= REFRESHDIR_NOTLOADED; CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); return false; } From 06721bd041d011e609afbd6c9775a8294d597bf1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 18:42:24 +0100 Subject: [PATCH 31/51] kill/resurrect secrets if to be changed --- src/m_menu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 3712c863f..dcebcfec3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5123,6 +5123,9 @@ static void M_HandleAddons(INT32 choice) Z_Free(dirmenu); dirmenu = NULL; + // secrets disabled by addfile... + MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); else From 54ac157c6c8c57981610dd1018d2bcbfc531fbe4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 21:04:26 +0100 Subject: [PATCH 32/51] Disable log.txt, errorlog.txt, and config.cfg from being "loadable" (exec-runnable) from the addfile menu. --- src/filesrch.c | 10 ++++++++++ src/m_menu.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/filesrch.c b/src/filesrch.c index 8b6f99dad..ed4254f80 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -697,6 +697,16 @@ boolean preparefilemenu(boolean samedepth) ext |= EXT_LOADED; } } + else if (ext == EXT_TXT) + { + if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt")) + ext |= EXT_LOADED; + } + else if (ext == EXT_CFG) + { + if (!strcmp(dent->d_name, "config.cfg")) + ext |= EXT_LOADED; + } folder = 0; } diff --git a/src/m_menu.c b/src/m_menu.c index dcebcfec3..af5b406c3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4906,7 +4906,7 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); - if (dirmenu[i][DIR_TYPE] & EXT_LOADED) + if ((dirmenu[i][DIR_TYPE] & EXT_LOADED) && dirmenu[i][DIR_TYPE] >= EXT_LOADSTART) V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]); if ((size_t)i == dir_on[menudepthleft]) From b5b5b983a5d854f576945d22ec3d28b40d10d64d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 21:43:56 +0100 Subject: [PATCH 33/51] re-order mpause menu addons to be at top --- src/m_menu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index af5b406c3..0163ff646 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -541,9 +541,9 @@ typedef enum // --------------------- static menuitem_t MPauseMenu[] = { - {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 8}, - {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 16}, - {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 24}, + {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, + {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, + {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24}, {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40}, {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen @@ -561,9 +561,9 @@ static menuitem_t MPauseMenu[] = typedef enum { - mpause_scramble = 0, + mpause_addons = 0, + mpause_scramble, mpause_switchmap, - mpause_addons, mpause_continue, mpause_psetupsplit, From 013da120885bbc93fdc8c48d348c3d084f959bc7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 22:57:14 +0100 Subject: [PATCH 34/51] Minor tweak - this probably makes more sense to the casual player, and doesn't obscure anything to people who would otherwise know what checksum means. --- src/filesrch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesrch.c b/src/filesrch.c index ed4254f80..0f53747d2 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -314,7 +314,7 @@ static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Checksum"}, {0, NULL}}; +static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}}; consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; From 90d21f5c39b4bb6862513ecc2fa1579cbb1b2a7d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 8 May 2017 23:08:40 +0100 Subject: [PATCH 35/51] woops broke little green loaded icon for all, fixed --- src/m_menu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0163ff646..a31efcf7d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4900,13 +4900,14 @@ static void M_DrawAddons(void) UINT32 flags = V_ALLOWLOWERCASE; if (y > BASEVIDHEIGHT) break; if (dirmenu[i]) +#define type (UINT8)(dirmenu[i][DIR_TYPE]) { - if (dirmenu[i][DIR_TYPE] & EXT_LOADED) + if (type & EXT_LOADED) flags |= V_TRANSLUCENT; V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); - if ((dirmenu[i][DIR_TYPE] & EXT_LOADED) && dirmenu[i][DIR_TYPE] >= EXT_LOADSTART) + if ((type & EXT_LOADED) && ((type &~ EXT_LOADED) >= EXT_LOADSTART)) V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]); if ((size_t)i == dir_on[menudepthleft]) @@ -4922,6 +4923,7 @@ static void M_DrawAddons(void) else V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING); } +#undef type y += 16; } From ba41d465877fbccdadbd9b3970002731b92fe088 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 May 2017 14:09:09 +0100 Subject: [PATCH 36/51] Thanks Alam for letting me know I was messing up! * Search case is now handled via cvar instead of assumed based on system. * filemenusearch (previously strsystemstr) uses static char[] to prevent stack suffering. * New cvar for searching from start of string instead of anywhere in it! * Menu tweaked for the above. * Reverted slash from pathsep. --- src/d_netcmd.c | 2 ++ src/filesrch.c | 34 +++++++++++++++++----------------- src/filesrch.h | 2 +- src/m_menu.c | 16 ++++++++++------ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f8c9e5251..eda6f8769 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -720,6 +720,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_addons_folder); CV_RegisterVar(&cv_addons_md5); CV_RegisterVar(&cv_addons_showall); + CV_RegisterVar(&cv_addons_search_type); + CV_RegisterVar(&cv_addons_search_case); // WARNING: the order is important when initialising mouse2 // we need the mouse2port diff --git a/src/filesrch.c b/src/filesrch.c index 0f53747d2..5fd118403 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -41,7 +41,7 @@ #include #define SUFFIX "*" -#define SLASH PATHSEP +#define SLASH "\\" #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #ifndef INVALID_FILE_ATTRIBUTES @@ -319,6 +319,11 @@ consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NUL consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}}; +consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + char menupath[1024]; size_t menupathindex[menudepth]; size_t menudepthleft = menudepth; @@ -519,23 +524,19 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -#if defined(_WIN32) || defined(_WINDOWS) -#define CASEINSENSITIVE_FILESYSTEM -#endif -#ifdef CASEINSENSITIVE_FILESYSTEM -static char *strsystemstr(char *haystack, char *needle) +static boolean filemenusearch(char *haystack, char *needle) { - char uprhaystack[128]; - strlcpy(uprhaystack, haystack, 128); - strupr(uprhaystack); - return strstr(uprhaystack, needle); + static char localhaystack[128]; + strlcpy(localhaystack, haystack, 128); + if (!cv_addons_search_case.value) + strupr(localhaystack); + return ((cv_addons_search_type.value) + ? (strstr(localhaystack, needle) != 0) + : (!strncmp(localhaystack, needle, menusearch[0]))); } -#else -#define strsystemstr(haystack, needle) strstr(haystack, needle) -#endif -#define searchdir if (menusearch[0] && !strsystemstr(dent->d_name, localmenusearch))\ +#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\ {\ rejected++;\ continue;\ @@ -573,9 +574,8 @@ boolean preparefilemenu(boolean samedepth) if (menusearch[0]) { strcpy(localmenusearch, menusearch+1); -#ifdef CASEINSENSITIVE_FILESYSTEM - strupr(localmenusearch); -#endif + if (!cv_addons_search_case.value) + strupr(localmenusearch); } while (true) diff --git a/src/filesrch.h b/src/filesrch.h index e9092b590..c2201b453 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -8,7 +8,7 @@ #include "d_netfil.h" #include "m_menu.h" // MAXSTRINGLENGTH -extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall; +extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type; /** \brief The filesearch function diff --git a/src/m_menu.c b/src/m_menu.c index a31efcf7d..c3d140d91 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1389,11 +1389,15 @@ static menuitem_t OP_EraseDataMenu[] = static menuitem_t OP_AddonsOptionsMenu[] = { - {IT_HEADER, NULL, "Menu", NULL, 0}, - {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 6}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 11}, - {IT_STRING|IT_CVAR, NULL, "Identify loaded files via", &cv_addons_md5, 25}, - {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 30}, + {IT_HEADER, NULL, "Menu", NULL, 0}, + {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 12}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 22}, + {IT_STRING|IT_CVAR, NULL, "Identify loaded files via", &cv_addons_md5, 50}, + {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 60}, + + {IT_HEADER, NULL, "Search", NULL, 78}, + {IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 90}, + {IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 100}, }; enum @@ -1906,7 +1910,7 @@ menu_t OP_ScreenshotOptionsDef = NULL }; -menu_t OP_AddonsOptionsDef = DEFAULTSCROLLMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); +menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); From cb9012c2ca2a659a219b6c48d0b6b9d1a8e28b5c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 May 2017 14:22:53 +0100 Subject: [PATCH 37/51] Accidentially removed newline --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 5dcd9183c..d7f8b3679 100644 --- a/src/string.c +++ b/src/string.c @@ -49,4 +49,4 @@ size_t strlcpy(char *dst, const char *src, size_t siz) return strlcat(dst, src, siz); } -#endif \ No newline at end of file +#endif From 3e9cc51953101d8be6c2007484c6d1ccc7fac872 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 May 2017 17:05:39 +0100 Subject: [PATCH 38/51] Change config recognition method --- src/filesrch.c | 8 +++----- src/m_menu.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 5fd118403..3e9a879cb 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -702,11 +702,9 @@ boolean preparefilemenu(boolean samedepth) if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt")) ext |= EXT_LOADED; } - else if (ext == EXT_CFG) - { - if (!strcmp(dent->d_name, "config.cfg")) - ext |= EXT_LOADED; - } + + if (!strcmp(dent->d_name, configfile)) + ext |= EXT_LOADED; folder = 0; } diff --git a/src/m_menu.c b/src/m_menu.c index cde2ae902..5682e8883 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4912,7 +4912,7 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]); - if ((type & EXT_LOADED) && ((type &~ EXT_LOADED) >= EXT_LOADSTART)) + if (type & EXT_LOADED) V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]); if ((size_t)i == dir_on[menudepthleft]) From 3e7377930f0e9d79078ec84a3d0f855eb98f3e70 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 May 2017 17:05:39 +0100 Subject: [PATCH 39/51] FIX FOR MI'S CRASH --- src/m_menu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 5682e8883..8a5ea3fa0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5084,6 +5084,11 @@ static void M_HandleAddons(INT32 choice) case EXT_UP: S_StartSound(NULL, sfx_menu1); menupath[menupathindex[++menudepthleft]] = 0; + if (!preparefilemenu(false)) + { + UNEXIST; + return; + } break; case EXT_TXT: M_StartMessage(va("\x82%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO); From 593416328a57ba3f3ca634244083639acecc2731 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 16 May 2017 23:43:21 +0100 Subject: [PATCH 40/51] String addition to the addfile menu suggesting to visit the modifications page! No change to actual functionality, just secondary utility. --- src/m_menu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8a5ea3fa0..7a3fdee12 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4675,6 +4675,8 @@ static void M_AddonsOptions(INT32 choice) M_SetupNextMenu(&OP_AddonsOptionsDef); } +#define LOCATIONSTRING "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" + static void M_Addons(INT32 choice) { const char *pathname = "."; @@ -4704,7 +4706,7 @@ static void M_Addons(INT32 choice) if (!preparefilemenu(false)) { - M_StartMessage(M_GetText("No files/folders found.\n\n(Press a key)\n"),NULL,MM_NOTHING); + M_StartMessage(M_GetText("No files/folders found.\n\n"LOCATIONSTRING"\n\n(Press a key)\n"),NULL,MM_NOTHING); return; } else @@ -4854,8 +4856,9 @@ static void M_DrawAddons(void) if (addonsresponselimit) addonsresponselimit--; - if (Playing()) - V_DrawCenteredString(BASEVIDWIDTH/2, 4, V_REDMAP, "Adding files mid-game may cause problems."); + V_DrawCenteredString(BASEVIDWIDTH/2, 4, 0, (Playing() + ? "\x85""Adding files mid-game may cause problems." + : LOCATIONSTRING)); if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of x = FRACUNIT; From e41976fb054b5341de7e9ec3d2475bea4b012042 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 May 2017 20:55:05 +0100 Subject: [PATCH 41/51] https://cdn.discordapp.com/attachments/293238104096112641/317023848493088779/srb20016.png * Visual Indicator of modifiedgame/savemoddata. * Other assorted improvements to layout. --- src/m_menu.c | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7a3fdee12..3245b6ef0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -337,7 +337,7 @@ static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); static void M_AddonsOptions(INT32 choice); -static patch_t *addonsp[NUM_EXT+5]; +static patch_t *addonsp[NUM_EXT+6]; static UINT8 addonsresponselimit = 0; #define numaddonsshown 4 @@ -4715,7 +4715,7 @@ static void M_Addons(INT32 choice) if (addonsp[0]) // never going to have some provided but not all, saves individually checking { size_t i; - for (i = 0; i < NUM_EXT+5; i++) + for (i = 0; i < NUM_EXT+6; i++) W_UnlockCachedPatch(addonsp[i]); } @@ -4732,13 +4732,15 @@ static void M_Addons(INT32 choice) addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC); addonsp[NUM_EXT+3] = W_CachePatchName("M_FLOAD", PU_STATIC); addonsp[NUM_EXT+4] = W_CachePatchName("M_FSRCH", PU_STATIC); + addonsp[NUM_EXT+5] = W_CachePatchName("M_FSAVE", PU_STATIC); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); } -#define padding 16 -#define h (BASEVIDHEIGHT-(2*padding)) +#define width 4 +#define vpadding 27 +#define h (BASEVIDHEIGHT-(2*vpadding)) #define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker static void M_DrawTemperature(INT32 x, fixed_t t) { @@ -4754,29 +4756,30 @@ static void M_DrawTemperature(INT32 x, fixed_t t) t = (FixedMul(h<>FRACBITS); // border - V_DrawFill(x - 1, padding, 1, h, 3); - V_DrawFill(x + padding/4, padding, 1, h, 3); - V_DrawFill(x - 1, padding-1, padding/4+2, 1, 3); - V_DrawFill(x - 1, padding+h, padding/4+2, 1, 3); + V_DrawFill(x - 1, vpadding, 1, h, 3); + V_DrawFill(x + width, vpadding, 1, h, 3); + V_DrawFill(x - 1, vpadding-1, width+2, 1, 3); + V_DrawFill(x - 1, vpadding+h, width+2, 1, 3); // bar itself for (y = h; y > 0; y--) { UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98}; UINT8 c; - if (y < t) break; - if (y+padding > BASEVIDHEIGHT/2) + if (y <= t) break; + if (y+vpadding >= BASEVIDHEIGHT/2) c = 113; else c = colours[(NUMCOLOURS*(y-1))/(h/2)]; - V_DrawFill(x, y-1 + padding, padding/4, 1, c); + V_DrawFill(x, y-1 + vpadding, width, 1, c); } // fill the rest of the backing if (y) - V_DrawFill(x, padding, padding/4, y, 27); + V_DrawFill(x, vpadding, width, y, 27); } -#undef padding +#undef width +#undef vpadding #undef h #undef NUMCOLOURS @@ -4844,6 +4847,8 @@ static boolean M_AddonsRefresh(void) return false; } +#define offs 1 + static void M_DrawAddons(void) { INT32 x, y; @@ -4856,25 +4861,24 @@ static void M_DrawAddons(void) if (addonsresponselimit) addonsresponselimit--; - V_DrawCenteredString(BASEVIDWIDTH/2, 4, 0, (Playing() + V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing() ? "\x85""Adding files mid-game may cause problems." : LOCATIONSTRING)); if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of - x = FRACUNIT; + y = FRACUNIT; else { - x = FixedDiv(((packetsizetally-mainwadstally)< FRACUNIT) // happens because of how we're shrinkin' it a little - x = FRACUNIT; + y = FixedDiv(((packetsizetally-mainwadstally)< FRACUNIT) // happens because of how we're shrinkin' it a little + y = FRACUNIT; } - V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-8, V_TRANSLUCENT, va("%d%%", (100*x)>>FRACBITS)); - M_DrawTemperature(BASEVIDWIDTH - 16, x); + M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y); // DRAW MENU x = currentMenu->x; - y = currentMenu->y; + y = currentMenu->y + offs; //M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath()); @@ -4882,7 +4886,7 @@ static void M_DrawAddons(void) V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26); V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26); - V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1) - (y - 1), 159); + V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1 + offs) - (y - 1), 159); // get bottom... max = dir_on[menudepthleft] + numaddonsshown + 1; @@ -4938,9 +4942,8 @@ static void M_DrawAddons(void) if (max != (ssize_t)sizedirmenu) V_DrawString(19, y-12, V_YELLOWMAP, "\x1B"); - y = BASEVIDHEIGHT - currentMenu->y; + y = BASEVIDHEIGHT - currentMenu->y + offs; - V_DrawSmallScaledPatch(x-(21 + 5 + 16), y + 4, 0, addonsp[NUM_EXT+4]); M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1); if (menusearch[0]) V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1); @@ -4949,8 +4952,21 @@ static void M_DrawAddons(void) if (skullAnimCounter < 4) V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8, '_' | 0x80, false); + + x -= (21 + 5 + 16); + V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); + +#define CANSAVE (!modifiedgame || savemoddata) + x = BASEVIDWIDTH - x - 16; + V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); + + if CANSAVE + V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]); +#undef CANSAVE } +#undef offs + static void M_AddonExec(INT32 ch) { if (ch != 'y' && ch != KEY_ENTER) From 74c4ad4bada7b635e596481d7e41c9c17bfc08f4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 May 2017 20:55:35 +0100 Subject: [PATCH 42/51] Minor refactor, plus cutting out a potential bug of setting dir_on[] to -1. --- src/filesrch.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 3e9a879cb..a28c4d83c 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -560,15 +560,13 @@ boolean preparefilemenu(boolean samedepth) else menusearch[0] = menusearch[1] = 0; // clear search - for (; sizedirmenu > 0; sizedirmenu--) + for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items { Z_Free(dirmenu[sizedirmenu-1]); dirmenu[sizedirmenu-1] = NULL; } - dirhandle = opendir(menupath); - - if (dirhandle == NULL) + if (!(dirhandle = opendir(menupath))) // get directory return false; if (menusearch[0]) @@ -604,7 +602,7 @@ boolean preparefilemenu(boolean samedepth) size_t len = strlen(dent->d_name)+1; UINT8 ext; for (ext = 0; ext < NUM_EXT_TABLE; ext++) - if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; + if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file } searchdir; @@ -671,7 +669,7 @@ boolean preparefilemenu(boolean samedepth) { if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention for (; ext < NUM_EXT_TABLE; ext++) - if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; + if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file ext += EXT_START; // moving to be appropriate position @@ -732,6 +730,8 @@ boolean preparefilemenu(boolean samedepth) } } + closedir(dirhandle); + if (noresults) // no results dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry @@ -754,16 +754,14 @@ boolean preparefilemenu(boolean samedepth) Z_Free(tempname); } - if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu-1; - - closedir(dirhandle); - if (!sizedirmenu) { + dir_on[menudepthleft] = 0; Z_Free(dirmenu); return false; } + else if (dir_on[menudepthleft] >= sizedirmenu) + dir_on[menudepthleft] = sizedirmenu-1; return true; } From c2705b4662dbc5b35f254868fbb9d3df85e51c59 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 May 2017 21:45:03 +0100 Subject: [PATCH 43/51] * Make wads that don't modify the game not count towards the internal packet size tally in w_wad.c, like they wouldn't in d_netfil.c. * Now that it's consistent, removed the redundant packet size tally check in d_netfil.c. --- src/d_netfil.c | 9 ++------- src/w_wad.c | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index bf4e59878..a6233f3f1 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -59,6 +59,7 @@ #include "m_menu.h" #include "md5.h" #include "filesrch.h" +#include "d_clisrv.h" #include @@ -103,6 +104,7 @@ INT32 lastfilenum = -1; /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. + * Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c * */ UINT8 *PutFileNeeded(void) @@ -111,7 +113,6 @@ UINT8 *PutFileNeeded(void) UINT8 *p = netbuffer->u.serverinfo.fileneeded; char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus; - size_t bytesused = 0; for (i = 0; i < numwadfiles; i++) { @@ -129,12 +130,6 @@ UINT8 *PutFileNeeded(void) else filestatus += (1 << 4); // Will send if requested - bytesused += (nameonlylength(wadfilename) + 22); - - // Don't write too far... - if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded)) - I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename); - WRITEUINT8(p, filestatus); count++; diff --git a/src/w_wad.c b/src/w_wad.c index f51b49d4d..32c2f3e6c 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -319,21 +319,24 @@ UINT16 W_LoadWadFile(const char *filename) // Check if wad files will overflow fileneededbuffer. Only the filename part // is send in the packet; cf. - packetsize = packetsizetally; - - packetsize += nameonlylength(filename); - packetsize += 22; - - if (packetsize > MAXFILENEEDED*sizeof(UINT8)) + // see PutFileNeeded in d_netfil.c + if (!W_VerifyNMUSlumps(filename)) { - CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); - refreshdirmenu |= REFRESHDIR_MAX; - if (handle) - fclose(handle); - return INT16_MAX; - } + packetsize = packetsizetally; - packetsizetally = packetsize; + packetsize += nameonlylength(filename) + 22; + + if (packetsize > MAXFILENEEDED*sizeof(UINT8)) + { + CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); + refreshdirmenu |= REFRESHDIR_MAX; + if (handle) + fclose(handle); + return INT16_MAX; + } + + packetsizetally = packetsize; + } // detect dehacked file with the "soc" extension if (!stricmp(&filename[strlen(filename) - 4], ".soc")) From e2f6366292038ed785c5b41dd08325f286e9c4e1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 May 2017 22:05:41 +0100 Subject: [PATCH 44/51] Minimum fill for temperature gauge if you have any wads loaded at all. --- src/m_menu.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3245b6ef0..8c04f1d12 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4753,7 +4753,8 @@ static void M_DrawTemperature(INT32 x, fixed_t t) t = 0;*/ // scale - t = (FixedMul(h<>FRACBITS); + if (t > 1) + t = (FixedMul(h<>FRACBITS); // border V_DrawFill(x - 1, vpadding, 1, h, 3); @@ -4762,17 +4763,19 @@ static void M_DrawTemperature(INT32 x, fixed_t t) V_DrawFill(x - 1, vpadding+h, width+2, 1, 3); // bar itself - for (y = h; y > 0; y--) - { - UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98}; - UINT8 c; - if (y <= t) break; - if (y+vpadding >= BASEVIDHEIGHT/2) - c = 113; - else - c = colours[(NUMCOLOURS*(y-1))/(h/2)]; - V_DrawFill(x, y-1 + vpadding, width, 1, c); - } + y = h; + if (t) + for (t = h - t; y > 0; y--) + { + UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98}; + UINT8 c; + if (y <= t) break; + if (y+vpadding >= BASEVIDHEIGHT/2) + c = 113; + else + c = colours[(NUMCOLOURS*(y-1))/(h/2)]; + V_DrawFill(x, y-1 + vpadding, width, 1, c); + } // fill the rest of the backing if (y) @@ -4865,11 +4868,13 @@ static void M_DrawAddons(void) ? "\x85""Adding files mid-game may cause problems." : LOCATIONSTRING)); - if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of + if (!numwadfiles) + y = 0; + else if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of y = FRACUNIT; else { - y = FixedDiv(((packetsizetally-mainwadstally)< FRACUNIT) // happens because of how we're shrinkin' it a little y = FRACUNIT; } From 9fcf40b5a36fa5682346afa1bd8dc1565aeee9b1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 May 2017 22:36:59 +0100 Subject: [PATCH 45/51] woops --- src/d_netfil.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index a6233f3f1..939a96921 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -59,7 +59,6 @@ #include "m_menu.h" #include "md5.h" #include "filesrch.h" -#include "d_clisrv.h" #include From fe9ebbd1caaaa993e22c541d20a27d75b1056d37 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 25 May 2017 17:58:32 +0100 Subject: [PATCH 46/51] Files which are unimportant are not sent in the fileneeded list. This removes exactly one feature in exchange for a greater number of files to be loaded. I asked around, and people don't actually like what it currently does (load unimportant server-side files if you can findfile it locally), so. Can be reverted if requested. --- src/d_netfil.c | 55 +++++++++++++------------------------------------- src/d_netfil.h | 1 - 2 files changed, 14 insertions(+), 42 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 939a96921..a6b37186a 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -115,19 +115,19 @@ UINT8 *PutFileNeeded(void) for (i = 0; i < numwadfiles; i++) { - // If it has only music/sound lumps, mark it as unimportant + // If it has only music/sound lumps, don't put it in the list if (W_VerifyNMUSlumps(wadfiles[i]->filename)) - filestatus = 0; + continue; else - filestatus = 1; // Important + filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS // Store in the upper four bits if (!cv_downloading.value) filestatus += (2 << 4); // Won't send - else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024)) - filestatus += (0 << 4); // Won't send - else + else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024)) filestatus += (1 << 4); // Will send if requested + // else + // filestatus += (0 << 4); -- Won't send, too big WRITEUINT8(p, filestatus); @@ -160,7 +160,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr) { fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet filestatus = READUINT8(p); // The first byte is the file status - fileneeded[i].important = (UINT8)(filestatus & 3); fileneeded[i].willsend = (UINT8)(filestatus >> 4); fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size fileneeded[i].file = NULL; // The file isn't open yet @@ -190,7 +189,7 @@ boolean CL_CheckDownloadable(void) UINT8 i,dlstatus = 0; for (i = 0; i < fileneedednum; i++) - if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important) + if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN) { if (fileneeded[i].willsend == 1) continue; @@ -211,7 +210,7 @@ boolean CL_CheckDownloadable(void) // not downloadable, put reason in console CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n")); for (i = 0; i < fileneedednum; i++) - if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important) + if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN) { CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10); @@ -264,7 +263,7 @@ boolean CL_SendRequestFile(void) for (i = 0; i < fileneedednum; i++) if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN - && fileneeded[i].important && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2)) + && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2)) { I_Error("Attempted to download files that were not sendable"); } @@ -273,8 +272,7 @@ boolean CL_SendRequestFile(void) netbuffer->packettype = PT_REQUESTFILE; p = (char *)netbuffer->u.textcmd; for (i = 0; i < fileneedednum; i++) - if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) - && fileneeded[i].important) + if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)) { totalfreespaceneeded += fileneeded[i].totalsize; nameonly(fileneeded[i].filename); @@ -341,15 +339,9 @@ INT32 CL_CheckFiles(void) CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n"); for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;) { - if (i < fileneedednum && !fileneeded[i].important) - { - // Eh whatever, don't care - ++i; - continue; - } if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename)) { - // Unimportant on our side. still don't care. + // Unimportant on our side. ++j; continue; } @@ -388,7 +380,7 @@ INT32 CL_CheckFiles(void) break; } } - if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important) + if (fileneeded[i].status != FS_NOTFOUND) continue; fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true); @@ -418,27 +410,8 @@ void CL_LoadServerFiles(void) fileneeded[i].status = FS_OPEN; } else if (fileneeded[i].status == FS_MD5SUMBAD) - { - // If the file is marked important, don't even bother proceeding. - if (fileneeded[i].important) - I_Error("Wrong version of important file %s", fileneeded[i].filename); - - // If it isn't, no need to worry the user with a console message, - // although it can't hurt to put something in the debug file. - - // ...but wait a second. What if the local version is "important"? - if (!W_VerifyNMUSlumps(fileneeded[i].filename)) - I_Error("File %s should only contain music and sound effects!", - fileneeded[i].filename); - - // Okay, NOW we know it's safe. Whew. - P_AddWadFile(fileneeded[i].filename, NULL); - if (fileneeded[i].important) - G_SetGameModified(true); - fileneeded[i].status = FS_OPEN; - DEBFILE(va("File %s found but with different md5sum\n", fileneeded[i].filename)); - } - else if (fileneeded[i].important) + I_Error("Wrong version of file %s", fileneeded[i].filename); + else { const char *s; switch(fileneeded[i].status) diff --git a/src/d_netfil.h b/src/d_netfil.h index c9085a5b0..1c19fe2f3 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -35,7 +35,6 @@ typedef enum typedef struct { - UINT8 important; UINT8 willsend; // Is the server willing to send it? char filename[MAX_WADPATH]; UINT8 md5sum[16]; From d3bd17d8626727704ec1e35cac7614508a1f37a8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 26 May 2017 16:04:10 +0100 Subject: [PATCH 47/51] Make the zeroed temperature gauge actually look right. --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8c04f1d12..24dffbdf2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4868,7 +4868,7 @@ static void M_DrawAddons(void) ? "\x85""Adding files mid-game may cause problems." : LOCATIONSTRING)); - if (!numwadfiles) + if (numwadfiles <= mainwads+1) y = 0; else if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of y = FRACUNIT; From cbe56b1b0682f6d58fcdef6a38befc54ee09d16e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 27 May 2017 12:36:33 +0100 Subject: [PATCH 48/51] Essentially - show how close the numwadfiles is getting to the maximum as WELL as the packetsizetally. --- src/m_menu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 24dffbdf2..9072dd5b0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4870,11 +4870,14 @@ static void M_DrawAddons(void) if (numwadfiles <= mainwads+1) y = 0; - else if (numwadfiles >= MAX_WADFILES) // difficult to happen with current limits, but still worth thinking of + else if (numwadfiles >= MAX_WADFILES) y = FRACUNIT; else { + x = FixedDiv((numwadfiles - mainwads+1)< y) + y = x; if (y > FRACUNIT) // happens because of how we're shrinkin' it a little y = FRACUNIT; } From 33d5373e84c27bbd05815cab56c1217f8e586714 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 27 May 2017 13:13:00 +0100 Subject: [PATCH 49/51] Don't need this addition any more. --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9072dd5b0..e4a8ef1a2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4875,7 +4875,7 @@ static void M_DrawAddons(void) else { x = FixedDiv((numwadfiles - mainwads+1)< y) y = x; if (y > FRACUNIT) // happens because of how we're shrinkin' it a little From d685060aef70ae5938170db2fd3810470dbf8a62 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 27 May 2017 14:01:26 +0100 Subject: [PATCH 50/51] Store importance (nmuslumps check) to prevent having to do it again when doing d_netfil stuff. --- src/d_netfil.c | 4 ++-- src/w_wad.c | 4 +++- src/w_wad.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index a6b37186a..ffd39eef9 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -116,7 +116,7 @@ UINT8 *PutFileNeeded(void) for (i = 0; i < numwadfiles; i++) { // If it has only music/sound lumps, don't put it in the list - if (W_VerifyNMUSlumps(wadfiles[i]->filename)) + if (!wadfiles[i]->important) continue; else filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS @@ -339,7 +339,7 @@ INT32 CL_CheckFiles(void) CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n"); for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;) { - if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename)) + if (j < numwadfiles && !wadfiles[j]->important) { // Unimportant on our side. ++j; diff --git a/src/w_wad.c b/src/w_wad.c index 32c2f3e6c..cf8e7aab0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -298,6 +298,7 @@ UINT16 W_LoadWadFile(const char *filename) INT32 compressed = 0; size_t packetsize; UINT8 md5sum[16]; + boolean important; if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier @@ -320,7 +321,7 @@ UINT16 W_LoadWadFile(const char *filename) // Check if wad files will overflow fileneededbuffer. Only the filename part // is send in the packet; cf. // see PutFileNeeded in d_netfil.c - if (!W_VerifyNMUSlumps(filename)) + if ((important = !W_VerifyNMUSlumps(filename))) { packetsize = packetsizetally; @@ -474,6 +475,7 @@ UINT16 W_LoadWadFile(const char *filename) wadfile->handle = handle; wadfile->numlumps = (UINT16)numlumps; wadfile->lumpinfo = lumpinfo; + wadfile->important = important; fseek(handle, 0, SEEK_END); wadfile->filesize = (unsigned)ftell(handle); diff --git a/src/w_wad.h b/src/w_wad.h index f7ea64a56..a9ca29b35 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -70,6 +70,7 @@ typedef struct wadfile_s FILE *handle; UINT32 filesize; // for network UINT8 md5sum[16]; + boolean important; // also network - !W_VerifyNMUSlumps } wadfile_t; #define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word From 2c7fb73432cf29ff40823e37667cf8c57efb454a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 27 May 2017 15:10:16 +0100 Subject: [PATCH 51/51] Minor optimisation. (I'm picking at this branch! I should stop doing that and work on something else.) --- src/d_netfil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index ffd39eef9..8cbcabc8c 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -118,8 +118,8 @@ UINT8 *PutFileNeeded(void) // If it has only music/sound lumps, don't put it in the list if (!wadfiles[i]->important) continue; - else - filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS + + filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS // Store in the upper four bits if (!cv_downloading.value)