diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 4961e1902..5ccfd185a 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,4 +1,7 @@
 June 6, 2009  (Changes by Graf Zahl)
+- Added Hirogen2's unlimited pickup patch.
+- Added railgun performance customization CVARs by Spleen.
+- Added aspect ratio override submission by SoulPriestess.
 - Added a 'resetinventory' MAPINFO option.
 - Added MF6_NOFEAR flag.
 - Added A_MonsterRefire(probability, jumptarget).
diff --git a/src/d_main.cpp b/src/d_main.cpp
index 8c694cee9..cc78ccb52 100644
--- a/src/d_main.cpp
+++ b/src/d_main.cpp
@@ -1740,7 +1740,6 @@ void D_DoomMain (void)
 	if (Args->CheckParm ("-nomonsters"))	flags |= DF_NO_MONSTERS;
 	if (Args->CheckParm ("-respawn"))		flags |= DF_MONSTERS_RESPAWN;
 	if (Args->CheckParm ("-fast"))			flags |= DF_FAST_MONSTERS;
-	if (Args->CheckParm("-ulp"))	sv_unlimited_pickup = true;
 
 	devparm = !!Args->CheckParm ("-devparm");
 
diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp
index 34a4a716f..bdff394f2 100644
--- a/src/g_shared/a_pickups.cpp
+++ b/src/g_shared/a_pickups.cpp
@@ -513,10 +513,10 @@ bool AInventory::HandlePickup (AInventory *item)
 {
 	if (item->GetClass() == GetClass())
 	{
-		if (Amount < MaxAmount)
+		if (Amount < MaxAmount || sv_unlimited_pickup)
 		{
 			Amount += item->Amount;
-			if (Amount > MaxAmount)
+			if (Amount > MaxAmount && !sv_unlimited_pickup)
 			{
 				Amount = MaxAmount;
 			}
diff --git a/src/m_options.cpp b/src/m_options.cpp
index 02d5fd822..660b18194 100644
--- a/src/m_options.cpp
+++ b/src/m_options.cpp
@@ -80,6 +80,8 @@
 #include "cmdlib.h"
 #include "d_event.h"
 
+#include "sbar.h"
+
 // Data.
 #include "m_menu.h"
 
@@ -105,6 +107,7 @@ EXTERN_CVAR (Int, crosshair)
 EXTERN_CVAR (Bool, freelook)
 EXTERN_CVAR (Int, sv_smartaim)
 EXTERN_CVAR (Int, am_colorset)
+EXTERN_CVAR (Int, vid_aspect)
 
 static void CalcIndent (menu_t *menu);
 
@@ -922,6 +925,14 @@ CUSTOM_CVAR (Int, menu_screenratios, 0, CVAR_ARCHIVE)
 	}
 }
 
+static value_t ForceRatios[] =
+{
+	{ 0.0, "Off" },
+	{ 3.0, "4:3" },
+	{ 1.0, "16:9" },
+	{ 2.0, "16:10" },
+	{ 4.0, "5:4" }
+};
 static value_t Ratios[] =
 {
 	{ 0.0, "4:3" },
@@ -943,6 +954,7 @@ static char VMTestText[] = "T to test mode for 5 seconds";
 
 static menuitem_t ModesItems[] = {
 //	{ discrete, "Screen mode",			{&DummyDepthCvar},		{0.0}, {0.0},	{0.0}, {Depths} },
+	{ discrete, "Force aspect ratio",	{&vid_aspect},			{5.0}, {0.0},	{0.0}, {ForceRatios} },
 	{ discrete, "Aspect ratio",			{&menu_screenratios},	{4.0}, {0.0},	{0.0}, {Ratios} },
 	{ discrete, "Fullscreen",			{&fullscreen},			{2.0}, {0.0},	{0.0}, {YesNo} },
 	{ discrete, "Enable 5:4 aspect ratio",{&vid_tft},			{2.0}, {0.0},	{0.0}, {YesNo} },
@@ -965,9 +977,9 @@ static menuitem_t ModesItems[] = {
 
 #define VM_DEPTHITEM	0
 #define VM_ASPECTITEM	0
-#define VM_RESSTART		4
-#define VM_ENTERLINE	14
-#define VM_TESTLINE		16
+#define VM_RESSTART		5
+#define VM_ENTERLINE	15
+#define VM_TESTLINE		17
 
 menu_t ModesMenu =
 {
@@ -994,6 +1006,11 @@ CUSTOM_CVAR (Bool, vid_tft, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 			menu_screenratios = 0;
 		}
 	}
+	setsizeneeded = true;
+	if (StatusBar != NULL)
+	{
+		StatusBar->ScreenSizeChanged();
+	}	
 }
 
 /*=======================================
diff --git a/src/p_effect.cpp b/src/p_effect.cpp
index 48a2bdd3e..a76412844 100644
--- a/src/p_effect.cpp
+++ b/src/p_effect.cpp
@@ -52,6 +52,9 @@
 #include "colormatcher.h"
 
 CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
+CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
+CVAR (Int, r_rail_spiralsparsity, 1, CVAR_ARCHIVE);
+CVAR (Int, r_rail_trailsparsity, 1, CVAR_ARCHIVE);
 
 #define FADEFROMTTL(a)	(255/(a))
 
@@ -512,12 +515,15 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
 	step = dir * 3;
 
 	// Create the outer spiral.
-	if (color1 != -1)
+	if (color1 != -1 && (!r_rail_smartspiral || color2 == -1) && r_rail_spiralsparsity > 0)
 	{
+		FVector3 spiral_step = step * r_rail_spiralsparsity;
+		int spiral_steps = steps * r_rail_spiralsparsity;
+		
 		color1 = color1 == 0 ? -1 : ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1));
 		pos = start;
 		deg = FAngle(270);
-		for (i = steps; i; i--)
+		for (i = spiral_steps; i; i--)
 		{
 			particle_t *p = NewParticle ();
 			FVector3 tempvec;
@@ -538,8 +544,8 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
 			p->x = FLOAT2FIXED(tempvec.X);
 			p->y = FLOAT2FIXED(tempvec.Y);
 			p->z = FLOAT2FIXED(tempvec.Z);
-			pos += step;
-			deg += FAngle(14);
+			pos += spiral_step;
+			deg += FAngle(r_rail_spiralsparsity * 14);
 
 			if (color1 == -1)
 			{
@@ -562,13 +568,16 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
 	}
 
 	// Create the inner trail.
-	if (color2 != -1)
+	if (color2 != -1 && r_rail_trailsparsity > 0)
 	{
+		FVector3 trail_step = step * r_rail_trailsparsity;
+		int trail_steps = steps * r_rail_trailsparsity;
+
 		color2 = color2 == 0 ? -1 : ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2));
 		FVector3 diff(0, 0, 0);
 
 		pos = start;
-		for (i = steps; i; i--)
+		for (i = trail_steps; i; i--)
 		{
 			particle_t *p = JitterParticle (33);
 
@@ -594,7 +603,7 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end
 			p->z = FLOAT2FIXED(postmp.Z);
 			if (color1 != -1)
 				p->accz -= FRACUNIT/4096;
-			pos += step;
+			pos += trail_step;
 
 			if (color2 == -1)
 			{
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 6b8d0d8ce..f838930f1 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -295,6 +295,7 @@ void AActor::Serialize (FArchive &arc)
 		<< smokecounter
 		<< BlockingMobj
 		<< BlockingLine
+		<< pushfactor
 		<< Species;
 
 	if (arc.IsStoring ())
diff --git a/src/v_video.cpp b/src/v_video.cpp
index c6710197c..5387613f7 100644
--- a/src/v_video.cpp
+++ b/src/v_video.cpp
@@ -1526,6 +1526,15 @@ CUSTOM_CVAR (Bool, vid_nowidescreen, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
 	}
 }
 
+CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
+{
+	setsizeneeded = true;
+	if (StatusBar != NULL)
+	{
+		StatusBar->ScreenSizeChanged();
+	}
+}
+
 // Tries to guess the physical dimensions of the screen based on the
 // screen's pixel dimensions. Can return:
 // 0: 4:3
@@ -1534,6 +1543,11 @@ CUSTOM_CVAR (Bool, vid_nowidescreen, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
 // 4: 5:4
 int CheckRatio (int width, int height)
 {
+	if ((vid_aspect >=1) && (vid_aspect <=4))
+	{
+		// [SP] User wants to force aspect ratio; let them.
+		return vid_aspect == 3? 0: int(vid_aspect);
+	}
 	if (vid_nowidescreen)
 	{
 		if (!vid_tft)
diff --git a/src/version.h b/src/version.h
index b2a16d8c5..d1ab275ed 100644
--- a/src/version.h
+++ b/src/version.h
@@ -75,7 +75,7 @@
 // SAVESIG should match SAVEVER.
 
 // MINSAVEVER is the minimum level snapshot version that can be loaded.
-#define MINSAVEVER 1636
+#define MINSAVEVER 1643
 
 #if SVN_REVISION_NUMBER < MINSAVEVER
 // Never write a savegame with a version lower than what we need