diff --git a/source/common/audio/sound/oalsound.h b/source/common/audio/sound/oalsound.h
index a333d772d..13fa3e588 100644
--- a/source/common/audio/sound/oalsound.h
+++ b/source/common/audio/sound/oalsound.h
@@ -48,6 +48,8 @@
 #define ALC_NUM_HRTF_SPECIFIERS_SOFT             0x1994
 #define ALC_HRTF_SPECIFIER_SOFT                  0x1995
 #define ALC_HRTF_ID_SOFT                         0x1996
+#define ALC_OUTPUT_LIMITER_SOFT                  0x199A 
+
 typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
 typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
 #ifdef AL_ALEXT_PROTOTYPES
@@ -181,6 +183,7 @@ private:
         bool EXT_disconnect;
         bool SOFT_HRTF;
         bool SOFT_pause_device;
+		bool SOFT_output_limiter;
     } ALC;
     struct {
         bool EXT_source_distance_model;
diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp
index 269a49133..9c2ad6ab1 100644
--- a/source/common/audio/sound/s_sound.cpp
+++ b/source/common/audio/sound/s_sound.cpp
@@ -463,7 +463,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
 	}
 
 	// If this sound doesn't like playing near itself, don't play it if that's what would happen.
-	if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, source, channel))
+	if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, source, channel, attenuation))
 	{
 		chanflags |= CHANF_EVICTED;
 	}
@@ -675,7 +675,7 @@ void SoundEngine::RestartChannel(FSoundChan *chan)
 
 		// If this sound doesn't like playing near itself, don't play it if
 		// that's what would happen.
-		if (chan->NearLimit > 0 && CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange, 0, NULL, 0))
+		if (chan->NearLimit > 0 && CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange, 0, NULL, 0, chan->DistanceScale))
 		{
 			return;
 		}
@@ -816,7 +816,7 @@ bool SoundEngine::CheckSingular(int sound_id)
 //==========================================================================
 
 bool SoundEngine::CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range,
-	int sourcetype, const void *actor, int channel)
+	int sourcetype, const void *actor, int channel, float attenuation)
 {
 	FSoundChan *chan;
 	int count;
@@ -835,7 +835,9 @@ bool SoundEngine::CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_
 			}
 
 			CalcPosVel(chan, &chanorigin, NULL);
-			if ((chanorigin - pos).LengthSquared() <= limit_range)
+			// scale the limit distance with the attenuation. An attenuation of 0 means the limit distance is infinite and all sounds within the level are inside the limit.
+			float attn = std::min(chan->DistanceScale, attenuation);
+			if (attn <= 0 || (chanorigin - pos).LengthSquared() <= limit_range / attn)
 			{
 				count++;
 			}
diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h
index b3292637f..11dac776a 100644
--- a/source/common/audio/sound/s_soundinternal.h
+++ b/source/common/audio/sound/s_soundinternal.h
@@ -234,7 +234,7 @@ private:
 	bool CheckSingular(int sound_id);
 	virtual TArray<uint8_t> ReadSound(int lumpnum) = 0;
 protected:
-	virtual bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel);
+	virtual bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel, float attenuation);
 	virtual FSoundID ResolveSound(const void *ent, int srctype, FSoundID soundid, float &attenuation);
 
 public:
diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp
index bcbdfdfdb..0b4a74a53 100644
--- a/source/common/console/c_console.cpp
+++ b/source/common/console/c_console.cpp
@@ -614,7 +614,7 @@ void C_DrawConsole ()
 		}
 		else
 		{
-			if (conflat.isValid())
+			if (conflat.isValid() && gamestate != GS_FULLCONSOLE)
 			{
 				int conbright = 255 - APART(conshade);
 				PalEntry pe((uint8_t(255 * con_alpha)), conbright, conbright, conbright);
diff --git a/source/common/engine/startupinfo.h b/source/common/engine/startupinfo.h
index 5054a4507..f47fa351f 100644
--- a/source/common/engine/startupinfo.h
+++ b/source/common/engine/startupinfo.h
@@ -12,6 +12,7 @@ struct FStartupInfo
 	int Type;
 	int LoadLights = -1;
 	int LoadBrightmaps = -1;
+	int LoadWidescreen = -1;
 	int modern = 0;
 	enum
 	{
diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h
index 86db161ce..d6f200bfc 100644
--- a/source/common/menu/menu.h
+++ b/source/common/menu/menu.h
@@ -93,6 +93,7 @@ public:
 	bool mAnimatedTransition;
 	int mVirtWidth;
 	int mVirtHeight;
+	bool mCustomSizeSet;
 
 	void Reset();
 };
diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp
index ad89b6c27..f510b6d7a 100644
--- a/source/common/menu/menudef.cpp
+++ b/source/common/menu/menudef.cpp
@@ -267,10 +267,8 @@ static bool CheckSkipOptionBlock(FScanner &sc)
 //
 //=============================================================================
 
-static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
+static void DoParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc, bool &sizecompatible, int insertIndex)
 {
-	bool sizeset = false;
-	bool sizecompatible = true;
 	sc.MustGetStringName("{");
 	while (!sc.CheckString("}"))
 	{
@@ -284,7 +282,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 			if (!CheckSkipGameBlock(sc))
 			{
 				// recursively parse sub-block
-				ParseListMenuBody(sc, desc);
+				DoParseListMenuBody(sc, desc, sizecompatible, insertIndex);
 			}
 		}
 		else if (sc.Compare("ifnotgame"))
@@ -292,7 +290,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 			if (!CheckSkipGameBlock(sc, false))
 			{
 				// recursively parse sub-block
-				ParseListMenuBody(sc, desc);
+				DoParseListMenuBody(sc, desc, sizecompatible, insertIndex);
 			}
 		}
 		else if (sc.Compare("ifoption"))
@@ -300,7 +298,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 			if (!CheckSkipOptionBlock(sc))
 			{
 				// recursively parse sub-block
-				ParseListMenuBody(sc, desc);
+				DoParseListMenuBody(sc, desc, sizecompatible, insertIndex);
 			}
 		}
 		else if (sc.Compare("Class"))
@@ -382,6 +380,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 		}
 		else if (sc.Compare("size"))
 		{
+			desc->mCustomSizeSet = true;
 			if (sc.CheckNumber())
 			{
 				desc->mVirtWidth = sc.Number;
@@ -418,6 +417,17 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 			PClass *cls = PClass::FindClass(buildname);
 			if (cls != nullptr && cls->IsDescendantOf("ListMenuItem"))
 			{
+				bool inserting = insertIndex >= 0;
+				bool isSelectable = cls->IsDescendantOf("ListMenuItemSelectable");
+				double oldYpos = desc->mYpos;
+
+				// [Player701] If this is a selectable item and we're inserting in the middle,
+				// set the Y position of the descriptor to the Y of the item we're inserting before.
+				if (isSelectable && inserting)
+				{
+					desc->mYpos = desc->mItems[insertIndex]->mYpos;
+				}
+
 				auto func = dyn_cast<PFunction>(cls->FindSymbol("Init", true));
 				if (func != nullptr && !(func->Variants[0].Flags & (VARF_Protected | VARF_Private)))	// skip internal classes which have a protected init method.
 				{
@@ -528,11 +538,36 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 					DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
 					params[0] = item;
 					VMCallWithDefaults(func->Variants[0].Implementation, params, nullptr, 0);
-					desc->mItems.Push((DMenuItemBase*)item);
 
-					if (cls->IsDescendantOf("ListMenuItemSelectable"))
+					if (!inserting)
 					{
-						desc->mYpos += desc->mLinespacing;
+						desc->mItems.Push(item);
+					}
+					else
+					{
+						// [Player701] Insert item in between
+						desc->mItems.Insert(insertIndex, item);
+						insertIndex++;
+					}
+
+					if (isSelectable)
+					{
+						if (inserting)
+						{
+							// [Player701] If we've inserted a selectable item, 
+							// shift all following selectable items downwards
+							// NB: index has been incremented, so we're not affecting the newly inserted item here.
+							for (unsigned int i = insertIndex; i < desc->mItems.Size(); i++)
+							{
+								auto item = desc->mItems[i];
+								if (item->GetClass()->IsDescendantOf("ListMenuItemSelectable"))
+								{
+									desc->mItems[i]->mYpos += desc->mLinespacing;
+								}
+							}
+						}
+
+						desc->mYpos = oldYpos + desc->mLinespacing;
 						if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size() - 1;
 					}
 					success = true;
@@ -544,16 +579,24 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
 			}
 		}
 	}
-	if (!sizeset && sizecompatible) // allow unclean scaling on this menu
-	{
-		desc->mVirtWidth = -2;
-	}
 	for (auto &p : desc->mItems)
 	{
 		GC::WriteBarrier(p);
 	}
 }
 
+static void ParseListMenuBody(FScanner& sc, DListMenuDescriptor* desc, int insertIndex)
+{
+	bool sizecompatible = true;
+	DoParseListMenuBody(sc, desc, sizecompatible, insertIndex);
+	if (!desc->mCustomSizeSet && !sizecompatible)
+	{
+		// No custom size and incompatible items, 
+		// so force clean scaling for this menu
+		desc->mVirtWidth = -1;
+	}
+}
+
 //=============================================================================
 //
 //
@@ -700,11 +743,62 @@ static void ParseListMenu(FScanner &sc)
 	desc->mWRight = 0;
 	desc->mCenter = false;
 	desc->mFromEngine = fileSystem.GetFileContainer(sc.LumpNum) == 0;	// flags menu if the definition is from the IWAD.
+	desc->mVirtWidth = -2;
+	desc->mCustomSizeSet = false;
 
-	ParseListMenuBody(sc, desc);
+	ParseListMenuBody(sc, desc, -1);
 	ReplaceMenu(sc, desc);
 }
 
+//=============================================================================
+//
+// [Player701] Allow extending list menus
+//
+//=============================================================================
+
+static void ParseAddListMenu(FScanner& sc)
+{
+	sc.MustGetString();
+
+	DMenuDescriptor** pOld = MenuDescriptors.CheckKey(sc.String);
+	if (pOld == nullptr || *pOld == nullptr || !(*pOld)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
+	{
+		sc.ScriptError("%s is not a list menu that can be extended", sc.String);
+		return;
+	}
+
+	bool before = sc.CheckString("BEFORE");
+	bool after = sc.CheckString("AFTER");
+
+	int insertIndex = -1;
+
+	if (before || after)
+	{
+		// Find an existing menu item to use as insertion point
+		sc.MustGetString();
+
+		auto n = (*pOld)->mItems.Size();
+		for (unsigned int i = 0; i < n; i++)
+		{
+			auto item = (*pOld)->mItems[i];
+
+			if (item->mAction == sc.String)
+			{
+				insertIndex = before ? i : i + 1;
+				break;
+			}
+		}
+
+		// Inserting after the last item is the same as inserting at the end
+		if (insertIndex == n) insertIndex = -1;
+
+		// Don't error out if we haven't found a suitable item
+		// to avoid backwards compatibility issues.
+	}
+
+	ParseListMenuBody(sc, (DListMenuDescriptor*)(*pOld), insertIndex);
+}
+
 //=============================================================================
 //
 //
@@ -1048,6 +1142,7 @@ static void ParseAddOptionMenu(FScanner &sc)
 	if (pOld == nullptr || *pOld == nullptr || !(*pOld)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
 	{
 		sc.ScriptError("%s is not an option menu that can be extended", sc.String);
+		return;
 	}
 	ParseOptionMenuBody(sc, (DOptionMenuDescriptor*)(*pOld));
 }
@@ -1296,12 +1391,17 @@ void M_ParseMenuDefs()
 			}
 			else if (sc.Compare("DEFAULTLISTMENU"))
 			{
-				ParseListMenuBody(sc, DefaultListMenuSettings);
+				bool s = false;
+				DoParseListMenuBody(sc, DefaultListMenuSettings, s, -1);
 				if (DefaultListMenuSettings->mItems.Size() > 0)
 				{
 					I_FatalError("You cannot add menu items to the menu default settings.");
 				}
 			}
+			else if (sc.Compare("ADDLISTMENU"))
+			{
+				ParseAddListMenu(sc);
+			}
 			else if (sc.Compare("OPTIONVALUE"))
 			{
 				ParseOptionValue(sc);
diff --git a/source/common/platform/win32/i_system.cpp b/source/common/platform/win32/i_system.cpp
index 48bf64541..6a6119bf2 100644
--- a/source/common/platform/win32/i_system.cpp
+++ b/source/common/platform/win32/i_system.cpp
@@ -112,6 +112,7 @@ EXTERN_CVAR (Bool, queryiwad);
 EXTERN_CVAR (Bool, disableautoload)
 EXTERN_CVAR (Bool, autoloadlights)
 EXTERN_CVAR (Bool, autoloadbrightmaps)
+EXTERN_CVAR (Bool, autoloadwidescreen)
 EXTERN_CVAR (Int, vid_preferbackend)
 
 extern HWND Window, ConWindow, GameTitleWindow;
@@ -529,6 +530,7 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
 		SendDlgItemMessage( hDlg, IDC_WELCOME_NOAUTOLOAD, BM_SETCHECK, disableautoload ? BST_CHECKED : BST_UNCHECKED, 0 );
 		SendDlgItemMessage( hDlg, IDC_WELCOME_LIGHTS, BM_SETCHECK, autoloadlights ? BST_CHECKED : BST_UNCHECKED, 0 );
 		SendDlgItemMessage( hDlg, IDC_WELCOME_BRIGHTMAPS, BM_SETCHECK, autoloadbrightmaps ? BST_CHECKED : BST_UNCHECKED, 0 );
+		SendDlgItemMessage( hDlg, IDC_WELCOME_WIDESCREEN, BM_SETCHECK, autoloadwidescreen ? BST_CHECKED : BST_UNCHECKED, 0 );
 
 		// Set up our version string.
 		sprintf(szString, "Version %s.", GetVersionString());
@@ -583,6 +585,7 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
 			disableautoload = SendDlgItemMessage( hDlg, IDC_WELCOME_NOAUTOLOAD, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
 			autoloadlights = SendDlgItemMessage( hDlg, IDC_WELCOME_LIGHTS, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
 			autoloadbrightmaps = SendDlgItemMessage( hDlg, IDC_WELCOME_BRIGHTMAPS, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
+			autoloadwidescreen = SendDlgItemMessage( hDlg, IDC_WELCOME_WIDESCREEN, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
 			ctrl = GetDlgItem (hDlg, IDC_IWADLIST);
 			EndDialog(hDlg, SendMessage (ctrl, LB_GETCURSEL, 0, 0));
 		}
diff --git a/source/common/platform/win32/resource.h b/source/common/platform/win32/resource.h
index f6eff6188..f07a37083 100644
--- a/source/common/platform/win32/resource.h
+++ b/source/common/platform/win32/resource.h
@@ -153,6 +153,7 @@
 #define IDC_WELCOME_NOAUTOLOAD          4023
 #define IDC_WELCOME_LIGHTS              4024
 #define IDC_WELCOME_BRIGHTMAPS          4025
+#define IDC_WELCOME_WIDESCREEN          1087
 #define IDC_WELCOME_VULKAN              4026
 #define IDC_WELCOME_VULKAN1             4026