diff --git a/src/m_menu.c b/src/m_menu.c
index 4f78d0adc8116716f7ba39ee5d80730acd8aaded..538e2ebf142ddc1dffadc3e464f1b00e1bc0d3eb 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -1000,12 +1000,13 @@ static menuitem_t OP_P1ControlsMenu[] =
 	{IT_SUBMENU | IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def  ,  30},
 
 	{IT_STRING  | IT_CVAR, NULL, "Third-person Camera"  , &cv_chasecam , 50},
-	{IT_STRING  | IT_CVAR, NULL, "Flip Camera with Gravity"  , &cv_flipcam , 60},
-	{IT_STRING  | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70},
+	{IT_STRING  | IT_CVAR, NULL, "Third-person Orbital"  , &cv_cam_orbit , 60},
+	{IT_STRING  | IT_CVAR, NULL, "Flip Camera with Gravity"  , &cv_flipcam , 70},
+	{IT_STRING  | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 80},
 
-	//{IT_STRING  | IT_CVAR, NULL, "Analog Control", &cv_useranalog,  90},
-	{IT_STRING  | IT_CVAR, NULL, "Character angle", &cv_directionchar,  90},
-	{IT_STRING  | IT_CVAR, NULL, "Automatic braking", &cv_autobrake,  100},
+	//{IT_STRING  | IT_CVAR, NULL, "Analog Control", &cv_useranalog,  100},
+	{IT_STRING  | IT_CVAR, NULL, "Character angle", &cv_directionchar,  100},
+	{IT_STRING  | IT_CVAR, NULL, "Automatic braking", &cv_autobrake,  110},
 };
 
 static menuitem_t OP_P2ControlsMenu[] =
@@ -1015,12 +1016,13 @@ static menuitem_t OP_P2ControlsMenu[] =
 	{IT_SUBMENU | IT_STRING, NULL, "Second Gamepad Options...", &OP_Joystick2Def  ,  30},
 
 	{IT_STRING  | IT_CVAR, NULL, "Third-person Camera"  , &cv_chasecam2 , 50},
-	{IT_STRING  | IT_CVAR, NULL, "Flip Camera with Gravity"  , &cv_flipcam2 , 60},
-	{IT_STRING  | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70},
+	{IT_STRING  | IT_CVAR, NULL, "Third-person Orbital"  , &cv_cam2_orbit , 60},
+	{IT_STRING  | IT_CVAR, NULL, "Flip Camera with Gravity"  , &cv_flipcam2 , 70},
+	{IT_STRING  | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 80},
 
-	//{IT_STRING  | IT_CVAR, NULL, "Analog Control", &cv_useranalog2,  90},
-	{IT_STRING  | IT_CVAR, NULL, "Character angle", &cv_directionchar2,  90},
-	{IT_STRING  | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2,  100},
+	//{IT_STRING  | IT_CVAR, NULL, "Analog Control", &cv_useranalog2,  100},
+	{IT_STRING  | IT_CVAR, NULL, "Character angle", &cv_directionchar2,  100},
+	{IT_STRING  | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2,  110},
 };
 
 static menuitem_t OP_ChangeControlsMenu[] =
diff --git a/src/p_local.h b/src/p_local.h
index b686b9f09ce13a43ff4230cf1976a59b72e3ace8..d094b63991e46d9b1cbbc348c1c470836ae96c9d 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -109,10 +109,10 @@ typedef struct camera_s
 
 extern camera_t camera, camera2;
 extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height;
-extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed;
+extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_orbit;
 
 extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height;
-extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed;
+extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_orbit;
 
 extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
 extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
diff --git a/src/p_user.c b/src/p_user.c
index ca14c64d4367a04e53b2afe60787885d21e6cd7b..c38514db9549c321947fa040a348eb79b885772e 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -8898,12 +8898,14 @@ consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL,
 consvar_t cv_cam_speed = {"cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_cam_orbit = {"cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_height = {"cam2_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_cam2_orbit = {"cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 fixed_t t_cam_dist = -42;
 fixed_t t_cam_height = -42;
@@ -8957,7 +8959,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
 boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled)
 {
 	angle_t angle = 0, focusangle = 0, focusaiming = 0;
-	fixed_t x, y, z, dist, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
+	fixed_t x, y, z, dist, distxy, distz, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
 	INT32 camrotate;
 	boolean camstill, cameranoclip;
 	mobj_t *mo;
@@ -9165,13 +9167,26 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 			dist <<= 1;
 	}
 
+
+
 	checkdist = (dist = FixedMul(dist, player->camerascale));
 
 	if (checkdist < 128*FRACUNIT)
 		checkdist = 128*FRACUNIT;
 
-	x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
-	y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
+	if ((thiscam == &camera && cv_cam_orbit.value) || (thiscam == &camera2 && cv_cam2_orbit.value))
+	{
+		distxy = FixedMul(dist, FINECOSINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK));
+		distz = -FixedMul(dist, FINESINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK));
+	}
+	else
+	{
+		distxy = dist;
+		distz = 0;
+	}
+
+	x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
+	y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
 
 #if 0
 	if (twodlevel || (mo->flags2 & MF2_TWOD))
@@ -9208,9 +9223,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 	pviewheight = FixedMul(41*player->height/48, mo->scale);
 
 	if (mo->eflags & MFE_VERTICALFLIP)
-		z = mo->z + mo->height - pviewheight - camheight;
+		z = mo->z + mo->height - pviewheight - camheight + distz;
 	else
-		z = mo->z + pviewheight + camheight;
+		z = mo->z + pviewheight + camheight + distz;
 
 	// move camera down to move under lower ceilings
 	newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
diff --git a/src/r_main.c b/src/r_main.c
index 273d13a56bb26165b8749f557898ae201009cf63..5ed4110460f6de9714976df5cc540ed81fd64a6d 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -1176,6 +1176,7 @@ void R_RegisterEngineStuff(void)
 	CV_RegisterVar(&cv_cam_speed);
 	CV_RegisterVar(&cv_cam_rotate);
 	CV_RegisterVar(&cv_cam_rotspeed);
+	CV_RegisterVar(&cv_cam_orbit);
 
 	CV_RegisterVar(&cv_cam2_dist);
 	CV_RegisterVar(&cv_cam2_still);
@@ -1183,6 +1184,7 @@ void R_RegisterEngineStuff(void)
 	CV_RegisterVar(&cv_cam2_speed);
 	CV_RegisterVar(&cv_cam2_rotate);
 	CV_RegisterVar(&cv_cam2_rotspeed);
+	CV_RegisterVar(&cv_cam2_orbit);
 
 	CV_RegisterVar(&cv_showhud);
 	CV_RegisterVar(&cv_translucenthud);