diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index 2b4bdbcd780bb781616bee2ad0f59c03f4e1529a..b780ff75f02b2eab69886c10575428cdb661dc97 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -1091,6 +1091,7 @@ linedeftypes
 		{
 			title = "Water, Opaque";
 			prefix = "(120)";
+			flags2text = "[1] Make lava intangible";
 			flags8text = "[3] Slope skew sides";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
@@ -1106,6 +1107,7 @@ linedeftypes
 		{
 			title = "Water, Translucent";
 			prefix = "(121)";
+			flags2text = "[1] Make lava intangible";
 			flags8text = "[3] Slope skew sides";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
@@ -1122,6 +1124,7 @@ linedeftypes
 		{
 			title = "Water, Opaque, No Sides";
 			prefix = "(122)";
+			flags2text = "[1] Make lava intangible";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
 			flags1024text = "[10] Ripple effect";
@@ -1136,6 +1139,7 @@ linedeftypes
 		{
 			title = "Water, Translucent, No Sides";
 			prefix = "(123)";
+			flags2text = "[1] Make lava intangible";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
 			flags1024text = "[10] Ripple effect";
@@ -1151,6 +1155,7 @@ linedeftypes
 		{
 			title = "Goo Water, Translucent";
 			prefix = "(124)";
+			flags2text = "[1] Make lava intangible";
 			flags8text = "[3] Slope skew sides";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
@@ -1167,6 +1172,7 @@ linedeftypes
 		{
 			title = "Goo Water, Translucent, No Sides";
 			prefix = "(125)";
+			flags2text = "[1] Make lava intangible";
 			flags64text = "[6] Use two light levels";
 			flags512text = "[9] Use target light level";
 			flags1024text = "[10] Ripple effect";
@@ -1669,12 +1675,14 @@ linedeftypes
 		{
 			title = "Continuous";
 			prefix = "(300)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		301
 		{
 			title = "Each Time";
 			prefix = "(301)";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Also trigger on exit";
 		}
 
@@ -1682,6 +1690,7 @@ linedeftypes
 		{
 			title = "Once";
 			prefix = "(302)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		303
@@ -1691,6 +1700,7 @@ linedeftypes
 			flags2text = "[1] Rings greater or equal";
 			flags64text = "[6] Rings less or equal";
 			flags512text = "[9] Consider all players";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		304
@@ -1700,18 +1710,21 @@ linedeftypes
 			flags2text = "[1] Rings greater or equal";
 			flags64text = "[6] Rings less or equal";
 			flags512text = "[9] Consider all players";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		305
 		{
 			title = "Character Ability - Continuous";
 			prefix = "(305)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		306
 		{
 			title = "Character Ability - Each Time";
 			prefix = "(306)";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Also trigger on exit";
 		}
 
@@ -1719,24 +1732,28 @@ linedeftypes
 		{
 			title = "Character Ability - Once";
 			prefix = "(307)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		308
 		{
 			title = "Race Only - Once";
 			prefix = "(308)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		309
 		{
 			title = "CTF Red Team - Continuous";
 			prefix = "(309)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		310
 		{
 			title = "CTF Red Team - Each Time";
 			prefix = "(310)";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Also trigger on exit";
 		}
 
@@ -1744,12 +1761,14 @@ linedeftypes
 		{
 			title = "CTF Blue Team - Continuous";
 			prefix = "(311)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		312
 		{
 			title = "CTF Blue Team - Each Time";
 			prefix = "(312)";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Also trigger on exit";
 		}
 
@@ -1757,6 +1776,7 @@ linedeftypes
 		{
 			title = "No More Enemies - Once";
 			prefix = "(313)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		314
@@ -1765,6 +1785,7 @@ linedeftypes
 			prefix = "(314)";
 			flags64text = "[6] Number greater or equal";
 			flags512text = "[9] Number less";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		315
@@ -1773,30 +1794,35 @@ linedeftypes
 			prefix = "(315)";
 			flags64text = "[6] Number greater or equal";
 			flags512text = "[9] Number less";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		317
 		{
 			title = "Condition Set Trigger - Continuous";
 			prefix = "(317)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		318
 		{
 			title = "Condition Set Trigger - Once";
 			prefix = "(318)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		319
 		{
 			title = "Unlockable - Continuous";
 			prefix = "(319)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		320
 		{
 			title = "Unlockable - Once";
 			prefix = "(320)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		321
@@ -1804,6 +1830,7 @@ linedeftypes
 			title = "Trigger After X Calls - Continuous";
 			prefix = "(321)";
 			flags64text = "[6] Trigger more than once";
+			flags1024text = "[10] Use faster, unordered execution";
 
 		}
 
@@ -1812,6 +1839,7 @@ linedeftypes
 			title = "Trigger After X Calls - Each Time";
 			prefix = "(322)";
 			flags64text = "[6] Trigger more than once";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		323
@@ -1826,6 +1854,7 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Run if no more mares";
 			flags32768text = "[15] Run if player is not NiGHTS";
 		}
@@ -1833,6 +1862,7 @@ linedeftypes
 		324
 		{
 			title = "NiGHTSerize - Once";
+			prefix = "(324)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags8text = "[3] Run only if player is NiGHTS";
 			flags16text = "[4] Count from lowest of players";
@@ -1841,14 +1871,15 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Run if no more mares";
 			flags32768text = "[15] Run if player is not NiGHTS";
-			prefix = "(324)";
 		}
 
 		325
 		{
 			title = "De-NiGHTSerize - Each Time";
+			prefix = "(325)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags8text = "[3] Run if anyone is NiGHTS";
 			flags16text = "[4] Count from lowest of players";
@@ -1857,13 +1888,14 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags32768text = "[15] Run if no one is NiGHTS";
-			prefix = "(325)";
 		}
 
 		326
 		{
 			title = "De-NiGHTSerize - Once";
+			prefix = "(326)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags8text = "[3] Run if anyone is NiGHTS";
 			flags16text = "[4] Count from lowest of players";
@@ -1872,13 +1904,14 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags32768text = "[15] Run if no one is NiGHTS";
-			prefix = "(326)";
 		}
 
 		327
 		{
 			title = "NiGHTS Lap - Each Time";
+			prefix = "(327)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags16text = "[4] Count from lowest of players";
 			flags32text = "[5] Lap <= Front Y Offset";
@@ -1886,12 +1919,13 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
-			prefix = "(327)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		328
 		{
 			title = "NiGHTS Lap - Once";
+			prefix = "(328)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags16text = "[4] Count from lowest of players";
 			flags32text = "[5] Lap <= Front Y Offset";
@@ -1899,12 +1933,13 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
-			prefix = "(328)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		329
 		{
 			title = "Ideya Capture Touch - Each Time";
+			prefix = "(329)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags8text = "[3] Run regardless of spheres";
 			flags16text = "[4] Count from lowest of players";
@@ -1913,14 +1948,15 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Only if not enough spheres";
 			flags32768text = "[15] Run when entering Capture";
-			prefix = "(329)";
 		}
 
 		330
 		{
 			title = "Ideya Capture Touch - Once";
+			prefix = "(330)";
 			flags2text = "[1] Mare >= Front X Offset";
 			flags8text = "[3] Run regardless of spheres";
 			flags16text = "[4] Count from lowest of players";
@@ -1929,57 +1965,64 @@ linedeftypes
 			flags128text = "[7] Lap >= Front Y Offset";
 			flags256text = "[8] Count laps from Bonus Time";
 			flags512text = "[9] Count from triggering player";
+			flags1024text = "[10] Use faster, unordered execution";
 			flags16384text = "[14] Only if not enough spheres";
 			flags32768text = "[15] Run when entering Capture";
-			prefix = "(330)";
 		}
 
 		331
 		{
 			title = "Player Skin - Continuous";
-			flags64text = "[6] Disable for this skin";
 			prefix = "(331)";
+			flags64text = "[6] Disable for this skin";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		332
 		{
 			title = "Player Skin - Each Time";
-			flags64text = "[6] Disable for this skin";
 			prefix = "(332)";
+			flags64text = "[6] Disable for this skin";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		333
 		{
 			title = "Player Skin - Once";
-			flags64text = "[6] Disable for this skin";
 			prefix = "(333)";
+			flags64text = "[6] Disable for this skin";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		334
 		{
 			title = "Object Dye - Continuous";
-			flags64text = "[6] Disable for this color";
 			prefix = "(334)";
+			flags64text = "[6] Disable for this color";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		335
 		{
 			title = "Object Dye - Each Time";
-			flags64text = "[6] Disable for this color";
 			prefix = "(335)";
+			flags64text = "[6] Disable for this color";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		336
 		{
 			title = "Object Dye - Once";
-			flags64text = "[6] Disable for this color";
 			prefix = "(336)";
+			flags64text = "[6] Disable for this color";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 
 		399
 		{
 			title = "Level Load";
 			prefix = "(399)";
+			flags1024text = "[10] Use faster, unordered execution";
 		}
 	}
 
@@ -2662,7 +2705,7 @@ linedeftypes
 
 		502
 		{
-			title = "Scroll Tagged Wall";
+			title = "Scroll Tagged Walls";
 			prefix = "(502)";
 			flags128text = "[7] Use texture offsets";
 			flags256text = "[8] Scroll back side";
@@ -2670,7 +2713,7 @@ linedeftypes
 
 		503
 		{
-			title = "Scroll Tagged Wall (Accelerative)";
+			title = "Scroll Tagged Walls (Accelerative)";
 			prefix = "(503)";
 			flags128text = "[7] Use texture offsets";
 			flags256text = "[8] Scroll back side";
@@ -2678,7 +2721,7 @@ linedeftypes
 
 		504
 		{
-			title = "Scroll Tagged Wall (Displacement)";
+			title = "Scroll Tagged Walls (Displacement)";
 			prefix = "(504)";
 			flags128text = "[7] Use texture offsets";
 			flags256text = "[8] Scroll back side";
@@ -3112,7 +3155,7 @@ linedeftypes
 		723
 		{
 			title = "Copy Backside Floor Slope from Line Tag";
-			prefix = "(720)";
+			prefix = "(723)";
 			slope = "copy";
 			slopeargs = 4;
 		}
@@ -3120,7 +3163,7 @@ linedeftypes
 		724
 		{
 			title = "Copy Backside Ceiling Slope from Line Tag";
-			prefix = "(721)";
+			prefix = "(724)";
 			slope = "copy";
 			slopeargs = 8;
 		}
@@ -3128,7 +3171,7 @@ linedeftypes
 		725
 		{
 			title = "Copy Backside Floor and Ceiling Slope from Line Tag";
-			prefix = "(722)";
+			prefix = "(725)";
 			slope = "copy";
 			slopeargs = 12;
 		}
@@ -3190,7 +3233,7 @@ linedeftypes
 
 	transwall
 	{
-		title = "Translucent Wall";
+		title = "Translucent Walls";
 
 		900
 		{
@@ -3966,6 +4009,7 @@ thingtypes
 			sprite = "BUMBA1";
 			width = 16;
 			height = 32;
+			flags8text = "[8] Cannot move";
 		}
 		124
 		{
@@ -3996,7 +4040,6 @@ thingtypes
 			width = 24;
 			height = 76;
 			flags4text = "[4] End level on death";
-			flags8text = "[8] Alternate laser attack";
 		}
 		201
 		{
@@ -4031,6 +4074,7 @@ thingtypes
 			height = 60;
 			flags1text = "[1] Grayscale mode";
 			flags4text = "[4] End level on death";
+			flags8text = "[8] Skip intro";
 		}
 		206
 		{
@@ -5232,7 +5276,7 @@ thingtypes
 			width = 8;
 			height = 16;
 			hangs = 1;
-			angletext = "Dripping interval";
+			angletext = "Dripping delay";
 			fixedrotation = 1;
 		}
 		1003
@@ -5574,6 +5618,8 @@ thingtypes
 			width = 20;
 			height = 72;
 			arrow = 1;
+			flags4text = "[4] Move right";
+			flags8text = "[8] Move left";
 		}
 		1128
 		{
@@ -5726,6 +5772,7 @@ thingtypes
 			width = 24;
 			height = 63;
 			arrow = 1;
+			flags8text = "[8] Not pushable";
 		}
 		1217
 		{
@@ -5861,6 +5908,7 @@ thingtypes
 			height = 32;
 			angletext = "Initial delay";
 			fixedrotation = 1;
+			hangs = 1;
 			flags8text = "[8] Double size";
 		}
 		1305
diff --git a/src/g_game.c b/src/g_game.c
index e671eb2d757196466abd0edfe14a8d4b363061f8..44860bbbc5a19190e5ef705dff024d70dc6d1445 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -346,8 +346,8 @@ consvar_t cv_analog[2] = {
 	CVAR_INIT ("sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange),
 };
 consvar_t cv_useranalog[2] = {
-	CVAR_INIT ("configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange),
-	CVAR_INIT ("configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange),
+	CVAR_INIT ("configanalog", "On", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange),
+	CVAR_INIT ("configanalog2", "On", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange),
 };
 
 // deez New User eXperiences
@@ -362,8 +362,8 @@ consvar_t cv_autobrake2 = CVAR_INIT ("autobrake2", "On", CV_SAVE|CV_CALL, CV_OnO
 // hi here's some new controls
 static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}};
 consvar_t cv_cam_shiftfacing[2] = {
-	CVAR_INIT ("cam_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
-	CVAR_INIT ("cam2_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam2_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
 };
 consvar_t cv_cam_turnfacing[2] = {
 	CVAR_INIT ("cam_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
@@ -374,12 +374,12 @@ consvar_t cv_cam_turnfacingability[2] = {
 	CVAR_INIT ("cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
 };
 consvar_t cv_cam_turnfacingspindash[2] = {
-	CVAR_INIT ("cam_turnfacingspindash", "0.5", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
-	CVAR_INIT ("cam2_turnfacingspindash", "0.5", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
 };
 consvar_t cv_cam_turnfacinginput[2] = {
-	CVAR_INIT ("cam_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
-	CVAR_INIT ("cam2_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
+	CVAR_INIT ("cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL),
 };
 
 static CV_PossibleValue_t centertoggle_cons_t[] = {{0, "Hold"}, {1, "Toggle"}, {2, "Sticky Hold"}, {0, NULL}};
@@ -403,28 +403,28 @@ static CV_PossibleValue_t lockedassist_cons_t[] = {
 	{0, NULL}
 };
 consvar_t cv_cam_lockonboss[2] = {
-	CVAR_INIT ("cam_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL),
-	CVAR_INIT ("cam2_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL),
+	CVAR_INIT ("cam_lockaimassist", "Full", CV_SAVE, lockedassist_cons_t, NULL),
+	CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE, lockedassist_cons_t, NULL),
 };
 
-consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
+consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
-consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL);
+consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
 consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
 
-consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
+consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
-consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL);
+consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
 consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
 consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
@@ -1551,8 +1551,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
 	{
 		// Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Strafe
 		cmd->angleturn = (INT16)((localangle - *myangle) >> 16);
-	}	
-	
+	}
+
 	*myangle += (cmd->angleturn<<16);
 
 	if (controlstyle == CS_LMAOGALOG) {
@@ -2335,7 +2335,7 @@ void G_Ticker(boolean run)
 			else if (players[i].bot == BOT_MPAI) {
 				B_BuildTiccmd(&players[i], &players[i].cmd);
 			}
-			
+
 			// Do angle adjustments.
 			if (players[i].bot == BOT_NONE || players[i].bot == BOT_2PHUMAN)
 			{
@@ -2350,7 +2350,7 @@ void G_Ticker(boolean run)
     				P_ForceLocalAngle(&players[i], players[i].angleturn << 16);
     			else
     				players[i].cmd.angleturn = players[i].angleturn;
-    
+
     			players[i].cmd.angleturn &= ~TICCMD_RECEIVED;
 				// Use the leveltime sent in the player's ticcmd to determine control lag
     			players[i].cmd.latency = min(((leveltime & 0xFF) - players[i].cmd.latency) & 0xFF, MAXPREDICTTICS-1);
@@ -3056,15 +3056,15 @@ void G_DoReborn(INT32 playernum)
 
 		return;
 	}
-	
+
 	// Additional players (e.g. independent bots) in Single Player
-	if (playernum != consoleplayer && !(netgame || multiplayer)) 
-	{		
+	if (playernum != consoleplayer && !(netgame || multiplayer))
+	{
 		mobj_t *oldmo = NULL;
 		// Do nothing if out of lives
 		if (player->lives <= 0)
 			return;
-		
+
 		// Otherwise do respawn, starting by removing the player object
 		if (player->mo)
 		{
@@ -3075,7 +3075,7 @@ void G_DoReborn(INT32 playernum)
 		G_SpawnPlayer(playernum);
 		if (oldmo)
 			G_ChangePlayerReferences(oldmo, players[playernum].mo);
-		
+
 		return; //Exit function to avoid proccing other SP related mechanics
 	}
 
diff --git a/src/g_input.c b/src/g_input.c
index 6383c3f0068a3c47007f6fc50422f46b9e4bbb2c..250a2477223659fe3bc9988aa9fa4010deb14f87 100644
--- a/src/g_input.c
+++ b/src/g_input.c
@@ -684,14 +684,18 @@ void G_DefineDefaultControls(void)
 	gamecontroldefault[gcs_fps][GC_LOOKDOWN   ][0] = KEY_DOWNARROW;
 	gamecontroldefault[gcs_fps][GC_TURNLEFT   ][0] = KEY_LEFTARROW;
 	gamecontroldefault[gcs_fps][GC_TURNRIGHT  ][0] = KEY_RIGHTARROW;
-	gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_END;
+	gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL;
 	gamecontroldefault[gcs_fps][GC_JUMP       ][0] = KEY_SPACE;
 	gamecontroldefault[gcs_fps][GC_SPIN       ][0] = KEY_LSHIFT;
 	gamecontroldefault[gcs_fps][GC_FIRE       ][0] = KEY_RCTRL;
 	gamecontroldefault[gcs_fps][GC_FIRE       ][1] = KEY_MOUSE1+0;
-	gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = 'c';
+	gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT;
+	gamecontroldefault[gcs_fps][GC_FIRENORMAL ][1] = KEY_MOUSE1+1;
+	gamecontroldefault[gcs_fps][GC_CUSTOM1    ][0] = 'z';
+	gamecontroldefault[gcs_fps][GC_CUSTOM2    ][0] = 'x';
+	gamecontroldefault[gcs_fps][GC_CUSTOM3    ][0] = 'c';
 
-	// Platform game controls (arrow keys)
+	// Platform game controls (arrow keys), currently unused
 	gamecontroldefault[gcs_platform][GC_FORWARD    ][0] = KEY_UPARROW;
 	gamecontroldefault[gcs_platform][GC_BACKWARD   ][0] = KEY_DOWNARROW;
 	gamecontroldefault[gcs_platform][GC_STRAFELEFT ][0] = 'a';
@@ -734,34 +738,36 @@ void G_DefineDefaultControls(void)
 		gamecontroldefault[i][GC_VIEWPOINT  ][0] = KEY_F12;
 
 		// Gamepad controls -- same for both schemes
-		gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_JOY1+1; // B
-		gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_JOY1+2; // X
-		gamecontroldefault[i][GC_TOSSFLAG   ][1] = KEY_JOY1+0; // A
-		gamecontroldefault[i][GC_SPIN       ][1] = KEY_JOY1+4; // LB
-		gamecontroldefault[i][GC_CAMTOGGLE  ][1] = KEY_HAT1+0; // D-Pad Up
-		gamecontroldefault[i][GC_CAMRESET   ][1] = KEY_JOY1+3; // Y
+		gamecontroldefault[i][GC_JUMP       ][1] = KEY_JOY1+0; // A
+		gamecontroldefault[i][GC_SPIN       ][1] = KEY_JOY1+2; // X
+		gamecontroldefault[i][GC_CUSTOM1    ][1] = KEY_JOY1+1; // B
+		gamecontroldefault[i][GC_CUSTOM2    ][1] = KEY_JOY1+3; // Y
+		gamecontroldefault[i][GC_CUSTOM3    ][1] = KEY_JOY1+8; // Left Stick
 		gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+9; // Right Stick
-		gamecontroldefault[i][GC_TALKKEY    ][1] = KEY_HAT1+2; // D-Pad Left
-		gamecontroldefault[i][GC_SCORES     ][1] = KEY_HAT1+3; // D-Pad Right
-		gamecontroldefault[i][GC_JUMP       ][1] = KEY_JOY1+5; // RB
-		gamecontroldefault[i][GC_PAUSE      ][1] = KEY_JOY1+6; // Back
-		gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_HAT1+1; // D-Pad Down
+		gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_JOY1+4; // LB
+		gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_JOY1+5; // RB
+		gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_JOY1+6; // Back
 		gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
+		gamecontroldefault[i][GC_CAMTOGGLE  ][1] = KEY_HAT1+0; // D-Pad Up
+		gamecontroldefault[i][GC_VIEWPOINT  ][1] = KEY_HAT1+1; // D-Pad Down
+		gamecontroldefault[i][GC_TOSSFLAG   ][1] = KEY_HAT1+2; // D-Pad Left
+		gamecontroldefault[i][GC_SCORES     ][1] = KEY_HAT1+3; // D-Pad Right
 
 		// Second player controls only have joypad defaults
-		gamecontrolbisdefault[i][GC_WEAPONNEXT][0] = KEY_2JOY1+1; // B
-		gamecontrolbisdefault[i][GC_WEAPONPREV][0] = KEY_2JOY1+2; // X
-		gamecontrolbisdefault[i][GC_TOSSFLAG  ][0] = KEY_2JOY1+0; // A
-		gamecontrolbisdefault[i][GC_SPIN      ][0] = KEY_2JOY1+4; // LB
-		gamecontrolbisdefault[i][GC_CAMRESET  ][0] = KEY_2JOY1+3; // Y
-		gamecontrolbisdefault[i][GC_CENTERVIEW][0] = KEY_2JOY1+9; // Right Stick
-		gamecontrolbisdefault[i][GC_JUMP      ][0] = KEY_2JOY1+5; // RB
-		//gamecontrolbisdefault[i][GC_PAUSE     ][0] = KEY_2JOY1+6; // Back
-		//gamecontrolbisdefault[i][GC_SYSTEMMENU][0] = KEY_2JOY1+7; // Start
-		gamecontrolbisdefault[i][GC_CAMTOGGLE ][0] = KEY_2HAT1+0; // D-Pad Up
-		gamecontrolbisdefault[i][GC_SCREENSHOT][0] = KEY_2HAT1+1; // D-Pad Down
-		//gamecontrolbisdefault[i][GC_TALKKEY   ][0] = KEY_2HAT1+2; // D-Pad Left
-		//gamecontrolbisdefault[i][GC_SCORES    ][0] = KEY_2HAT1+3; // D-Pad Right
+		gamecontrolbisdefault[i][GC_JUMP       ][1] = KEY_2JOY1+0; // A
+		gamecontrolbisdefault[i][GC_SPIN       ][1] = KEY_2JOY1+2; // X
+		gamecontrolbisdefault[i][GC_CUSTOM1    ][1] = KEY_2JOY1+1; // B
+		gamecontrolbisdefault[i][GC_CUSTOM2    ][1] = KEY_2JOY1+3; // Y
+		gamecontrolbisdefault[i][GC_CUSTOM3    ][1] = KEY_2JOY1+8; // Left Stick
+		gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+9; // Right Stick
+		gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2JOY1+4; // LB
+		gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2JOY1+5; // RB
+		gamecontrolbisdefault[i][GC_SCREENSHOT ][1] = KEY_2JOY1+6; // Back
+		//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
+		gamecontrolbisdefault[i][GC_CAMTOGGLE  ][1] = KEY_2HAT1+0; // D-Pad Up
+		gamecontrolbisdefault[i][GC_VIEWPOINT  ][1] = KEY_2HAT1+1; // D-Pad Down
+		gamecontrolbisdefault[i][GC_TOSSFLAG   ][1] = KEY_2HAT1+2; // D-Pad Left
+		//gamecontrolbisdefault[i][GC_SCORES     ][1] = KEY_2HAT1+3; // D-Pad Right
 	}
 }
 
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 13b2a39c3b8914408dc26b9fdf6adb8765633b57..d2982afe44eb1df1812e82a79eab25de87f0b31e 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -1454,13 +1454,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
 				case 221:
 				case 253:
 				case 256:
-					if (gl_linedef->blendmode != AST_FOG)
+					if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
 						blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
 					else
 						blendmode = PF_Translucent;
 					break;
 				default:
-					if (gl_linedef->blendmode != AST_FOG)
+					if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
 					{
 						if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
 							blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
diff --git a/src/m_menu.c b/src/m_menu.c
index 85d093b943e22a50add4bb3aa111b72fc7a8ef1f..3c1d8d7caa07ba20ec416afddf848a75324017ab 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -4438,22 +4438,21 @@ static void M_DrawGenericMenu(void)
 	}
 }
 
-const char *PlaystyleNames[4] = {"Strafe", "Standard", "Simple", "Old Analog??"};
+const char *PlaystyleNames[4] = {"\x86Strafe\x80", "Manual", "Automatic", "Old Analog??"};
 const char *PlaystyleDesc[4] = {
-	// Legacy
-	"The play style used for\n"
-	"old-school SRB2.\n"
+	// Strafe (or Legacy)
+	"A play style resembling\n"
+	"old-school SRB2 gameplay.\n"
 	"\n"
 	"This play style is identical\n"
-	"to Standard, except that the\n"
+	"to Manual, except that the\n"
 	"player always looks in the\n"
 	"direction of the camera."
 	,
 
-	// Standard
-	"The default play style,\n"
-	"designed for full control\n"
-	"with a keyboard and mouse.\n"
+	// Manual (formerly Standard)
+	"A play style made for full control,\n"
+	"using a keyboard and mouse.\n"
 	"\n"
 	"The camera rotates only when\n"
 	"you tell it to. The player\n"
@@ -4465,8 +4464,8 @@ const char *PlaystyleDesc[4] = {
 	"open up the highest level of play!"
 	,
 
-	// Simple
-	"A play style designed for\n"
+	// Automatic (formerly Simple)
+	"The default play style, designed for\n"
 	"gamepads and hassle-free play.\n"
 	"\n"
 	"The camera rotates automatically\n"
@@ -4475,7 +4474,8 @@ const char *PlaystyleDesc[4] = {
 	"they're moving.\n"
 	"\n"
 	"Hold \x82" "Center View\x80 to lock the\n"
-	"camera behind the player!\n"
+	"camera behind the player, or target\n"
+	"enemies, bosses and monitors!\n"
 	,
 
 	// Old Analog
@@ -4486,7 +4486,7 @@ const char *PlaystyleDesc[4] = {
 	"your config file and brought it back.\n"
 	"\n"
 	"That's absolutely valid, but I implore\n"
-	"you to try the new Simple play style\n"
+	"you to try the new Automatic play style\n"
 	"instead!"
 };
 
@@ -9062,7 +9062,7 @@ static void M_LoadGame(INT32 choice)
 
 	if (tutorialmap && cv_tutorialprompt.value)
 	{
-		M_StartMessage("Do you want to \x82play a brief Tutorial\x80?\n\nWe highly recommend this because \nthe controls are slightly different \nfrom other games.\n\nPress 'Y' or 'Enter' to go\nPress 'N' or any key to skip\n",
+		M_StartMessage("Do you want to \x82play a brief Tutorial\x80?\n\nWe highly recommend this because \nthe controls are slightly different \nfrom other games.\n\nPress the\x82 Y\x80 key or the\x83 A button\x80 to go\nPress the\x82 N\x80 key or the\x83 Y button\x80 to skip\n",
 			M_FirstTimeResponse, MM_YESNO);
 		return;
 	}
@@ -13008,6 +13008,7 @@ static void M_DrawPlaystyleMenu(void)
 
 		if (i == playstyle_currentchoice)
 		{
+			V_DrawFill(20, 40, 280, 150, 159);
 			V_DrawScaledPatch((i+1)*BASEVIDWIDTH/4 - 8, 10, 0, W_CachePatchName("M_CURSOR", PU_CACHE));
 			V_DrawString(30, 50, V_ALLOWLOWERCASE, PlaystyleDesc[i]);
 		}
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 39c6731b81ab41b378f748eb42fe28762642c350..87e20fd4ac5c9135394ed15ba238fad8ed262f85 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -7740,7 +7740,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
 		break;
 	case MT_WATERDROP:
 		P_SceneryCheckWater(mobj);
-		if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop)
+		if (((!(mobj->eflags & MFE_VERTICALFLIP) && (mobj->z <= mobj->floorz || mobj->z <= mobj->watertop))
+			|| (mobj->eflags & MFE_VERTICALFLIP && mobj->z + mobj->height >= mobj->ceilingz))
 			&& mobj->health > 0)
 		{
 			mobj->health = 0;
diff --git a/src/p_user.c b/src/p_user.c
index 9b48442fe2bf76c5adf9dffa84e262380a0dbe6b..0aff39949c2862bc4aa9321b50c09df78ae9d82b 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1191,7 +1191,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
 {
 	if (!player)
 		return;
-	
+
 	if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader)
 		player = player->botleader;
 
@@ -9624,7 +9624,7 @@ consvar_t cv_cam_still = CVAR_INIT ("cam_still", "Off", 0, CV_OnOff, NULL);
 consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL);
 consvar_t cv_cam_rotate = CVAR_INIT ("cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange);
 consvar_t cv_cam_rotspeed = CVAR_INIT ("cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL);
-consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL);
+consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL);
 consvar_t cv_cam_orbit = CVAR_INIT ("cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL);
 consvar_t cv_cam_adjust = CVAR_INIT ("cam_adjust", "On", CV_SAVE, CV_OnOff, NULL);
 consvar_t cv_cam2_dist = CVAR_INIT ("cam2_curdist", "160", CV_FLOAT, NULL, NULL);
@@ -9633,30 +9633,30 @@ consvar_t cv_cam2_still = CVAR_INIT ("cam2_still", "Off", 0, CV_OnOff, NULL);
 consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL);
 consvar_t cv_cam2_rotate = CVAR_INIT ("cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange);
 consvar_t cv_cam2_rotspeed = CVAR_INIT ("cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL);
-consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL);
+consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL);
 consvar_t cv_cam2_orbit = CVAR_INIT ("cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL);
 consvar_t cv_cam2_adjust = CVAR_INIT ("cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL);
 
 // [standard vs simple][p1 or p2]
 consvar_t cv_cam_savedist[2][2] = {
 	{ // standard
-		CVAR_INIT ("cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
-		CVAR_INIT ("cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
+		CVAR_INIT ("cam_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
+		CVAR_INIT ("cam2_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
 	},
 	{ // simple
-		CVAR_INIT ("cam_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
-		CVAR_INIT ("cam2_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
+		CVAR_INIT ("cam_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
+		CVAR_INIT ("cam2_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
 
 	}
 };
 consvar_t cv_cam_saveheight[2][2] = {
 	{ // standard
-		CVAR_INIT ("cam_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
-		CVAR_INIT ("cam2_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
+		CVAR_INIT ("cam_height", "40", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
+		CVAR_INIT ("cam2_height", "40", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
 	},
 	{ // simple
-		CVAR_INIT ("cam_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
-		CVAR_INIT ("cam2_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
+		CVAR_INIT ("cam_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist),
+		CVAR_INIT ("cam2_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist),
 
 	}
 };
@@ -9838,17 +9838,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 	if (P_CameraThinker(player, thiscam, resetcalled))
 		return true;
 
-	if (tutorialmode)
-	{
-		// force defaults because we have a camera look section
-		camspeed = (INT32)(atof(cv_cam_speed.defaultvalue) * FRACUNIT);
-		camstill = (!stricmp(cv_cam_still.defaultvalue, "off")) ? false : true;
-		camorbit = (!stricmp(cv_cam_orbit.defaultvalue, "off")) ? false : true;
-		camrotate = atoi(cv_cam_rotate.defaultvalue);
-		camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale);
-		camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), mo->scale);
-	}
-	else if (thiscam == &camera)
+	if (thiscam == &camera)
 	{
 		camspeed = cv_cam_speed.value;
 		camstill = cv_cam_still.value;
@@ -11619,7 +11609,7 @@ void P_PlayerThink(player_t *player)
 			INT32 i, total = 0, exiting = 0;
 
 			for (i = 0; i < MAXPLAYERS; i++)
-			{ 
+			{
 				if (!playeringame[i] || players[i].spectator || players[i].bot)
 					continue;
 				if (players[i].quittime > 30 * TICRATE)
@@ -12560,7 +12550,7 @@ void P_PlayerAfterThink(player_t *player)
 					player->mo->momy = tails->momy;
 					player->mo->momz = tails->momz;
 				}
-				
+
 				if (G_CoopGametype() && tails->player && tails->player->bot != BOT_2PAI)
 				{
 					player->mo->angle = tails->angle;
diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c
index dae3a7b53a6cab88c151e7d1605d99fc5972c321..5dbc30286630c4f51eee55bb7fe2a8d57f4a10e4 100644
--- a/src/r_patchrotation.c
+++ b/src/r_patchrotation.c
@@ -227,10 +227,10 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle
 
 	ox = (newwidth / 2) + (leftoffset - xpivot);
 	oy = (newheight / 2) + (patch->topoffset - ypivot);
-	width = (maxx+1 - minx);
-	height = (maxy+1 - miny);
+	width = (maxx - minx);
+	height = (maxy - miny);
 
-	if ((unsigned)(width * height) != size)
+	if ((unsigned)(width * height) > size)
 	{
 		UINT16 *src, *dest;
 
diff --git a/src/s_sound.c b/src/s_sound.c
index 30f24236923a45200f40ccddd5eff680f4e98c99..76f0d67c16e490777c3e9c6e59bdf625e221945c 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -74,9 +74,9 @@ consvar_t stereoreverse = CVAR_INIT ("stereoreverse", "Off", CV_SAVE, CV_OnOff,
 static consvar_t precachesound = CVAR_INIT ("precachesound", "Off", CV_SAVE, CV_OnOff, NULL);
 
 // actual general (maximum) sound & music volume, saved into the config
-consvar_t cv_soundvolume = CVAR_INIT ("soundvolume", "18", CV_SAVE, soundvolume_cons_t, NULL);
-consvar_t cv_digmusicvolume = CVAR_INIT ("digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL);
-consvar_t cv_midimusicvolume = CVAR_INIT ("midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL);
+consvar_t cv_soundvolume = CVAR_INIT ("soundvolume", "16", CV_SAVE, soundvolume_cons_t, NULL);
+consvar_t cv_digmusicvolume = CVAR_INIT ("digmusicvolume", "16", CV_SAVE, soundvolume_cons_t, NULL);
+consvar_t cv_midimusicvolume = CVAR_INIT ("midimusicvolume", "16", CV_SAVE, soundvolume_cons_t, NULL);
 
 static void Captioning_OnChange(void)
 {
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index 105e1def868b96e66c05302674a9a93e4f83e159..d79dde7662142d132271ed676bf5d1f2c5423f09 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -245,6 +245,7 @@
     <ClInclude Include="..\i_sound.h" />
     <ClInclude Include="..\i_system.h" />
     <ClInclude Include="..\i_tcp.h" />
+    <ClInclude Include="..\i_threads.h" />
     <ClInclude Include="..\i_video.h" />
     <ClInclude Include="..\keys.h" />
     <ClInclude Include="..\libdivide.h" />
@@ -304,6 +305,7 @@
     <ClInclude Include="..\st_stuff.h" />
     <ClInclude Include="..\s_sound.h" />
     <ClInclude Include="..\tables.h" />
+    <ClInclude Include="..\taglist.h" />
     <ClInclude Include="..\v_video.h" />
     <ClInclude Include="..\w_wad.h" />
     <ClInclude Include="..\y_inter.h" />
@@ -415,6 +417,7 @@
     <ClCompile Include="..\lua_polyobjlib.c" />
     <ClCompile Include="..\lua_script.c" />
     <ClCompile Include="..\lua_skinlib.c" />
+    <ClCompile Include="..\lua_taglib.c" />
     <ClCompile Include="..\lua_thinkerlib.c" />
     <ClCompile Include="..\lzf.c" />
     <ClCompile Include="..\md5.c" />
@@ -475,10 +478,12 @@
     <ClCompile Include="..\r_things.c" />
     <ClCompile Include="..\screen.c" />
     <ClCompile Include="..\sounds.c" />
+    <ClCompile Include="..\strcasestr.c" />
     <ClCompile Include="..\string.c" />
     <ClCompile Include="..\st_stuff.c" />
     <ClCompile Include="..\s_sound.c" />
     <ClCompile Include="..\tables.c" />
+    <ClCompile Include="..\taglist.c" />
     <ClCompile Include="..\t_facon.c">
       <ExcludedFromBuild>true</ExcludedFromBuild>
     </ClCompile>
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index 4048903976b57317d6be3ac77ff0f87a38b17f8c..4d2532ca4ef61adf61711cfc3affbc6b86e73f14 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -135,6 +135,16 @@
     <ClInclude Include="..\dehacked.h">
       <Filter>D_Doom</Filter>
     </ClInclude>
+    <ClInclude Include="..\deh_lua.h">
+      <Filter>D_Doom</Filter>
+    </ClInclude>
+    <ClInclude Include="..\deh_soc.h">
+      <Filter>D_Doom</Filter>
+    </ClInclude>
+    <ClInclude Include="..\deh_tables.h">
+      <Filter>D_Doom</Filter>
+    </ClInclude>
+
     <ClInclude Include="..\doomdata.h">
       <Filter>D_Doom</Filter>
     </ClInclude>
@@ -288,6 +298,9 @@
     <ClInclude Include="..\i_tcp.h">
       <Filter>I_Interface</Filter>
     </ClInclude>
+    <ClInclude Include="..\i_threads.h">
+      <Filter>I_Interface</Filter>
+    </ClInclude>
     <ClInclude Include="..\i_video.h">
       <Filter>I_Interface</Filter>
     </ClInclude>
@@ -402,6 +415,9 @@
     <ClInclude Include="..\tables.h">
       <Filter>P_Play</Filter>
     </ClInclude>
+    <ClInclude Include="..\taglist.h">
+      <Filter>P_Play</Filter>
+    </ClInclude>
     <ClInclude Include="..\libdivide.h">
       <Filter>R_Rend</Filter>
     </ClInclude>
@@ -600,6 +616,16 @@
     <ClCompile Include="..\dehacked.c">
       <Filter>D_Doom</Filter>
     </ClCompile>
+    <ClCompile Include="..\deh_lua.c">
+      <Filter>D_Doom</Filter>
+    </ClCompile>
+    <ClCompile Include="..\deh_soc.c">
+      <Filter>D_Doom</Filter>
+    </ClCompile>
+    <ClCompile Include="..\deh_tables.c">
+      <Filter>D_Doom</Filter>
+    </ClCompile>
+
     <ClCompile Include="..\d_clisrv.c">
       <Filter>D_Doom</Filter>
     </ClCompile>
@@ -747,6 +773,9 @@
     <ClCompile Include="..\lua_skinlib.c">
       <Filter>LUA</Filter>
     </ClCompile>
+    <ClCompile Include="..\lua_taglib.c">
+      <Filter>LUA</Filter>
+    </ClCompile>
     <ClCompile Include="..\lua_thinkerlib.c">
       <Filter>LUA</Filter>
     </ClCompile>
@@ -792,6 +821,9 @@
     <ClCompile Include="..\string.c">
       <Filter>M_Misc</Filter>
     </ClCompile>
+    <ClCompile Include="..\strcasestr.c">
+      <Filter>M_Misc</Filter>
+    </ClCompile>
     <ClCompile Include="..\comptime.c">
       <Filter>O_Other</Filter>
     </ClCompile>
@@ -852,6 +884,9 @@
     <ClCompile Include="..\tables.c">
       <Filter>P_Play</Filter>
     </ClCompile>
+    <ClCompile Include="..\taglist.c">
+      <Filter>P_Play</Filter>
+    </ClCompile>
     <ClCompile Include="..\t_facon.c">
       <Filter>P_Play</Filter>
     </ClCompile>
diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c
index c426e6792f6c8116c52615a27f997e63e9f2b275..bdc693ca5306fee0a6ea20c13dc12f4a190b0821 100644
--- a/src/sdl/ogl_sdl.c
+++ b/src/sdl/ogl_sdl.c
@@ -177,7 +177,9 @@ boolean OglSdlSurface(INT32 w, INT32 h)
 			// Also set the renderer variable back to software so the next launch won't
 			// repeat this error.
 			CV_StealthSet(&cv_renderer, "Software");
-			I_Error("OpenGL Error: Failed to access the GPU. There may be an issue with your graphics drivers.");
+			I_Error("OpenGL Error: Failed to access the GPU. Possible reasons include:\n"
+					"- GPU vendor has dropped OpenGL support on your GPU and OS. (Old GPU?)\n"
+					"- GPU drivers are missing or broken. You may need to update your drivers.");
 		}
 	}
 	first_init = true;
diff --git a/src/st_stuff.c b/src/st_stuff.c
index ebf188a06f78978e2039ff1ef053c65be38a72c9..f17b58fa62d0161d859c5371beb3d5c0a161c6da 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -1176,7 +1176,17 @@ static void ST_drawInput(void)
 			break;
 
 		case CS_SIMPLE:
-			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "SIMPLE");
+			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "AUTOMATIC");
+			y -= 8;
+			break;
+
+		case CS_STANDARD:
+			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "MANUAL");
+			y -= 8;
+			break;
+
+		case CS_LEGACY:
+			V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "STRAFE");
 			y -= 8;
 			break;
 
diff --git a/src/taglist.c b/src/taglist.c
index ad1b9dc4b52e2a6a8cf6d117a0bbff722ec07ccf..d08750f9b096a8e647bdec63e83feb2c7dc66c35 100644
--- a/src/taglist.c
+++ b/src/taglist.c
@@ -191,6 +191,38 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
 	group->elements[i] = id;
 }
 
+static void Taggroup_Add_Init(taggroup_t *garray[], const mtag_t tag, size_t id)
+{
+	taggroup_t *group;
+
+	if (tag == MTAG_GLOBAL)
+		return;
+
+	group = garray[(UINT16)tag];
+
+	if (! in_bit_array(tags_available, tag))
+	{
+		num_tags++;
+		set_bit_array(tags_available, tag);
+	}
+
+	// Create group if empty.
+	if (!group)
+		group = garray[(UINT16)tag] = Z_Calloc(sizeof(taggroup_t), PU_LEVEL, NULL);
+	else if (group->elements[group->count - 1] == id)
+		return; // Don't add duplicates
+
+	group->count++;
+
+	if (group->count > group->capacity)
+	{
+		group->capacity = 2 * group->count;
+		group->elements = Z_Realloc(group->elements, group->capacity * sizeof(size_t), PU_LEVEL, NULL);
+	}
+
+	group->elements[group->count - 1] = id;
+}
+
 static size_t total_elements_with_tag (const mtag_t tag)
 {
 	return
@@ -250,17 +282,17 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
 
 static void Taglist_AddToSectors (const mtag_t tag, const size_t itemid)
 {
-	Taggroup_Add(tags_sectors, tag, itemid);
+	Taggroup_Add_Init(tags_sectors, tag, itemid);
 }
 
 static void Taglist_AddToLines (const mtag_t tag, const size_t itemid)
 {
-	Taggroup_Add(tags_lines, tag, itemid);
+	Taggroup_Add_Init(tags_lines, tag, itemid);
 }
 
 static void Taglist_AddToMapthings (const mtag_t tag, const size_t itemid)
 {
-	Taggroup_Add(tags_mapthings, tag, itemid);
+	Taggroup_Add_Init(tags_mapthings, tag, itemid);
 }
 
 /// After all taglists have been built for each element (sectors, lines, things),
diff --git a/src/taglist.h b/src/taglist.h
index d045eb8276011c22d049111fca82869f0b3b857b..ae1a81c896dfb8bc19c348f50ef99eb258975d4f 100644
--- a/src/taglist.h
+++ b/src/taglist.h
@@ -41,6 +41,7 @@ typedef struct
 {
 	size_t *elements;
 	size_t count;
+	size_t capacity;
 } taggroup_t;
 
 extern bitarray_t tags_available[];