From bd3e9cc067d3cba347ccd2bbdb84968b161087f3 Mon Sep 17 00:00:00 2001
From: toaster <rollerorbital@gmail.com>
Date: Mon, 18 Jun 2018 16:55:34 +0100
Subject: [PATCH] Major refinement of Add-ons menu!

* Kill addonsresponselimit, which was a hacky solution to a stupid problem. Instead...
* Allocate and consistently handle memory to store the name of an added file so we can reference it directly.
* Replace the choice between ./ and a custom folder with the full, standard assortment of Default (usehome ? SRB2HOME : SRB2PATH), HOME (SRB2HOME), SRB2 (SRB2PATH) or Custom (cv_addons_folder.string).
* Make these render as the name plus folder, since you can't go UP... from the top level.
* Make the path seperators consistently system-based re PATHSEP. (Quite frankly, I'm surprised it even worked in the first place...)
---
 src/d_netcmd.c |  6 ++++
 src/d_netfil.c |  9 +++---
 src/filesrch.c | 24 ++++++++++-----
 src/filesrch.h |  1 +
 src/m_menu.c   | 79 +++++++++++++++++++++++++-------------------------
 src/w_wad.c    | 10 +++++++
 6 files changed, 79 insertions(+), 50 deletions(-)

diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 89f01c161c..2ab0548a02 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -3318,6 +3318,9 @@ static void Command_Playintro_f(void)
 	if (netgame)
 		return;
 
+	if (dirmenu)
+		closefilemenu(true);
+
 	F_StartIntro();
 }
 
@@ -4076,6 +4079,9 @@ void Command_ExitGame_f(void)
 	cv_debug = 0;
 	emeralds = 0;
 
+	if (dirmenu)
+		closefilemenu(true);
+
 	if (!modeattacking)
 		D_StartTitle();
 }
diff --git a/src/d_netfil.c b/src/d_netfil.c
index ea95153b95..e43ad77e28 100644
--- a/src/d_netfil.c
+++ b/src/d_netfil.c
@@ -894,10 +894,11 @@ void nameonly(char *s)
 		{
 			ns = &(s[j+1]);
 			len = strlen(ns);
-			if (false)
-				M_Memcpy(s, ns, len+1);
-			else
-				memmove(s, ns, len+1);
+#if 0
+			M_Memcpy(s, ns, len+1);
+#else
+			memmove(s, ns, len+1);
+#endif
 			return;
 		}
 }
diff --git a/src/filesrch.c b/src/filesrch.c
index b80681306c..fe3fe240c1 100644
--- a/src/filesrch.c
+++ b/src/filesrch.c
@@ -306,9 +306,14 @@ 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_cons_t[] = {{0, "Default"},
+#if 1
+												{1, "HOME"}, {2, "SRB2"},
+#endif
+													{3, "CUSTOM"}, {0, NULL}};
+
+consvar_t cv_addons_option = {"addons_option", "Default", 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, "Contents"}, {0, NULL}};
 consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -330,6 +335,7 @@ char **dirmenu, **coredirmenu; // core only local for this file
 size_t sizedirmenu, sizecoredirmenu; // ditto
 size_t dir_on[menudepth];
 UINT8 refreshdirmenu = 0;
+char *refreshdirname = NULL;
 
 size_t packetsizetally = 0;
 size_t mainwadstally = 0;
@@ -362,9 +368,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
 		return FS_NOTFOUND;
 	}
 
-	if (searchpath[searchpathindex[depthleft]-2] != '/')
+	if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
 	{
-		searchpath[searchpathindex[depthleft]-1] = '/';
+		searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
 		searchpath[searchpathindex[depthleft]] = 0;
 	}
 	else
@@ -406,7 +412,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
 					depthleft++;
 			}
 
-			searchpath[searchpathindex[depthleft]-1]='/';
+			searchpath[searchpathindex[depthleft]-1]=PATHSEP[0];
 			searchpath[searchpathindex[depthleft]]=0;
 		}
 		else if (!strcasecmp(searchname, dent->d_name))
@@ -492,6 +498,10 @@ void closefilemenu(boolean validsize)
 		Z_Free(coredirmenu);
 		coredirmenu = NULL;
 	}
+
+	if (refreshdirname)
+		Z_Free(refreshdirname);
+	refreshdirname = NULL;
 }
 
 void searchfilemenu(char *tempname)
@@ -759,7 +769,7 @@ boolean preparefilemenu(boolean samedepth)
 			strlcpy(temp+DIR_STRING, dent->d_name, len);
 			if (folder)
 			{
-				strcpy(temp+len, "/");
+				strcpy(temp+len, PATHSEP);
 				coredirmenu[folderpos++] = temp;
 			}
 			else
diff --git a/src/filesrch.h b/src/filesrch.h
index 4cfa40e6c9..41dc80d137 100644
--- a/src/filesrch.h
+++ b/src/filesrch.h
@@ -40,6 +40,7 @@ extern char **dirmenu;
 extern size_t sizedirmenu;
 extern size_t dir_on[menudepth];
 extern UINT8 refreshdirmenu;
+extern char *refreshdirname;
 
 extern size_t packetsizetally;
 extern size_t mainwadstally;
diff --git a/src/m_menu.c b/src/m_menu.c
index d23d5640f9..bdeee16ed1 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -341,7 +341,6 @@ static void M_EraseData(INT32 choice);
 static void M_Addons(INT32 choice);
 static void M_AddonsOptions(INT32 choice);
 static patch_t *addonsp[NUM_EXT+6];
-static UINT8 addonsresponselimit = 0;
 
 #define numaddonsshown 4
 
@@ -2110,15 +2109,19 @@ static void M_GoBack(INT32 choice)
 		if (!Playing() && netgame && multiplayer)
 		{
 			MSCloseUDPSocket();		// Clean up so we can re-open the connection later.
-			netgame = false;
-			multiplayer = false;
+			netgame = multiplayer = false;
 		}
 
 		if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef))
 		{
 			// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
-			Z_Free(levelselect.rows);
-			levelselect.rows = NULL;
+
+			if (levelselect.rows)
+			{
+				Z_Free(levelselect.rows);
+				levelselect.rows = NULL;
+			}
+
 			menuactive = false;
 			D_StartTitle();
 		}
@@ -4759,22 +4762,24 @@ static void M_Addons(INT32 choice)
 
 	(void)choice;
 
-	/*if (cv_addons_option.value == 0)
-		pathname = srb2home; usehome ? srb2home : srb2path;
+#if 1
+	if (cv_addons_option.value == 0)
+		pathname = usehome ? srb2home : srb2path;
 	else if (cv_addons_option.value == 1)
 		pathname = srb2home;
 	else if (cv_addons_option.value == 2)
 		pathname = srb2path;
-	else*/
+	else
+#endif
 	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] != '/')
+	if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
 	{
-		menupath[menupathindex[menudepthleft]-1] = '/';
+		menupath[menupathindex[menudepthleft]-1] = PATHSEP[0];
 		menupath[menupathindex[menudepthleft]] = 0;
 	}
 	else
@@ -4868,11 +4873,7 @@ 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);
-
+	strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024);
 	len = strlen(header);
 	if (len > 34)
 	{
@@ -4889,6 +4890,15 @@ static char *M_AddonsHeaderPath(void)
 		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)
 
+#define CLEARNAME Z_Free(refreshdirname);\
+					refreshdirname = NULL
+
+static void M_AddonsClearName(INT32 choice)
+{
+	CLEARNAME;
+	M_StopMessage(choice);
+}
+
 // returns whether to do message draw
 static boolean M_AddonsRefresh(void)
 {
@@ -4900,35 +4910,35 @@ static boolean M_AddonsRefresh(void)
 
 	if (refreshdirmenu & REFRESHDIR_ADDFILE)
 	{
-		addonsresponselimit = 0;
+		char *message = NULL;
 
 		if (refreshdirmenu & REFRESHDIR_NOTLOADED)
 		{
-			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);
+				message = va("\x82%s\x80\nMaximum number of add-ons reached.\nA 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", refreshdirname);
 			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 true;
+				message = va("\x82%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname);
 		}
-
-		if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
+		else 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);
+			message = va("\x82%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
+		}
+
+		if (message)
+		{
+			M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER);
 			return true;
 		}
 
 		S_StartSound(NULL, sfx_strpst);
+		CLEARNAME;
 	}
 
 	return false;
 }
 
-#define offs 1
-
 #ifdef FIXUPO0
 #pragma GCC optimize ("0")
 #endif
@@ -4945,10 +4955,7 @@ static void M_DrawAddons(void)
 		return;
 	}
 
-	if (addonsresponselimit)
-		addonsresponselimit--;
-
-	V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing()
+	V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, (Playing()
 	? "\x85""Adding files mid-game may cause problems."
 	: LOCATIONSTRING));
 
@@ -4970,7 +4977,7 @@ static void M_DrawAddons(void)
 
 	// DRAW MENU
 	x = currentMenu->x;
-	y = currentMenu->y + offs;
+	y = currentMenu->y + 1;
 
 	//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());
@@ -4978,7 +4985,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 + offs) - (y - 1), 159);
+	V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1), 159);
 
 	// get bottom...
 	max = dir_on[menudepthleft] + numaddonsshown + 1;
@@ -5034,7 +5041,7 @@ static void M_DrawAddons(void)
 	if (max != (ssize_t)sizedirmenu)
 		V_DrawString(19, y-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
 
-	y = BASEVIDHEIGHT - currentMenu->y + offs;
+	y = BASEVIDHEIGHT - currentMenu->y + 1;
 
 	M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
 	if (menusearch[0])
@@ -5059,8 +5066,6 @@ static void M_DrawAddons(void)
 #pragma GCC reset_options
 #endif
 
-#undef offs
-
 static void M_AddonExec(INT32 ch)
 {
 	if (ch != 'y' && ch != KEY_ENTER)
@@ -5112,9 +5117,6 @@ static void M_HandleAddons(INT32 choice)
 {
 	boolean exitmenu = false; // exit to previous menu
 
-	if (addonsresponselimit)
-		return;
-
 	if (M_ChangeStringAddons(choice))
 	{
 		char *tempname = NULL;
@@ -5224,7 +5226,6 @@ static void M_HandleAddons(INT32 choice)
 						case EXT_WAD:
 						case EXT_PK3:
 							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/w_wad.c b/src/w_wad.c
index 46caef8477..320b65a3cd 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -340,6 +340,16 @@ UINT16 W_InitFile(const char *filename)
 	if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
 		refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
 
+	if (refreshdirname)
+		Z_Free(refreshdirname);
+	if (dirmenu)
+	{
+		refreshdirname = Z_StrDup(filename);
+		nameonly(refreshdirname);
+	}
+	else
+		refreshdirname = NULL;
+
 	//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
 	//
 	// check if limit of active wadfiles
-- 
GitLab