From 017d1cee29adf2b2b479cc26dbb8ac5f461f5f0a Mon Sep 17 00:00:00 2001
From: Magnus Norddahl <dpjudas@users.noreply.github.com>
Date: Tue, 13 Sep 2016 23:26:30 +0200
Subject: [PATCH] Change canvas rendering to use the aspect ratio of the canvas
 and generalize 5:4 rendering as AspectTallerThanWide

---
 src/g_shared/shared_sbar.cpp |  2 +-
 src/r_main.cpp               |  6 +++---
 src/r_utility.cpp            | 14 +++++++++++---
 src/r_utility.h              |  2 +-
 src/v_draw.cpp               |  6 +++---
 src/v_video.cpp              | 25 ++++++++++++++++---------
 src/v_video.h                |  2 +-
 7 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp
index 22171a4bb..f66ec187d 100644
--- a/src/g_shared/shared_sbar.cpp
+++ b/src/g_shared/shared_sbar.cpp
@@ -300,7 +300,7 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
 		ST_X = 0;
 		ST_Y = VirticalResolution - RelTop;
 		float aspect = ActiveRatio(SCREENWIDTH, SCREENHEIGHT);
-		if (!Is54Aspect(aspect))
+		if (!AspectTallerThanWide(aspect))
 		{ // Normal resolution
 			::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution);
 		}
diff --git a/src/r_main.cpp b/src/r_main.cpp
index 6094f70de..040b57b71 100644
--- a/src/r_main.cpp
+++ b/src/r_main.cpp
@@ -318,7 +318,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
 	virtwidth = virtwidth2 = fullWidth;
 	virtheight = virtheight2 = fullHeight;
 
-	if (Is54Aspect(trueratio))
+	if (AspectTallerThanWide(trueratio))
 	{
 		virtheight2 = virtheight2 * AspectMultiplier(trueratio) / 48;
 	}
@@ -327,7 +327,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
 		virtwidth2 = virtwidth2 * AspectMultiplier(trueratio) / 48;
 	}
 
-	if (Is54Aspect(WidescreenRatio))
+	if (AspectTallerThanWide(WidescreenRatio))
 	{
 		virtheight = virtheight * AspectMultiplier(WidescreenRatio) / 48;
 	}
@@ -948,7 +948,7 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas,
 	RenderTarget = canvas;
 	bRenderingToCanvas = true;
 
-	R_SetWindow (12, width, height, height);
+	R_SetWindow (12, width, height, height, true);
 	viewwindowx = x;
 	viewwindowy = y;
 	viewactive = true;
diff --git a/src/r_utility.cpp b/src/r_utility.cpp
index 76cf05e9b..ebe36dc9d 100644
--- a/src/r_utility.cpp
+++ b/src/r_utility.cpp
@@ -198,7 +198,7 @@ void R_SetViewSize (int blocks)
 //
 //==========================================================================
 
-void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
+void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas)
 {
 	float trueratio;
 
@@ -220,7 +220,15 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
 		freelookviewheight = ((setblocks*fullHeight)/10)&~7;
 	}
 
-	WidescreenRatio = ActiveRatio (fullWidth, fullHeight, &trueratio);
+	if (renderingToCanvas)
+	{
+		WidescreenRatio = fullWidth / (float)fullHeight;
+		trueratio = WidescreenRatio;
+	}
+	else
+	{
+		WidescreenRatio = ActiveRatio(fullWidth, fullHeight, &trueratio);
+	}
 
 	DrawFSHUD = (windowSize == 11);
 	
@@ -229,7 +237,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
 
 	centery = viewheight/2;
 	centerx = viewwidth/2;
-	if (Is54Aspect(WidescreenRatio))
+	if (AspectTallerThanWide(WidescreenRatio))
 	{
 		centerxwide = centerx;
 	}
diff --git a/src/r_utility.h b/src/r_utility.h
index e9fd436e5..09a8b5667 100644
--- a/src/r_utility.h
+++ b/src/r_utility.h
@@ -95,7 +95,7 @@ void R_ExecuteSetViewSize (void);
 
 // Called by M_Responder.
 void R_SetViewSize (int blocks);
-void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight);
+void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false);
 
 
 extern void R_FreePastViewers ();
diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index 3075cd92d..4677c4b08 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -874,7 +874,7 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
 	double right = x + w;
 	double bottom = y + h;
 
-	if (myratio > 1.4f)
+	if (myratio > 1.334f)
 	{ // The target surface is either 16:9 or 16:10, so expand the
 	  // specified virtual size to avoid undesired stretching of the
 	  // image. Does not handle non-4:3 virtual sizes. I'll worry about
@@ -887,7 +887,7 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
 		x = x * Width / vwidth;
 		w = right * Width / vwidth - x;
 	}
-	if (Is54Aspect(myratio))
+	if (AspectTallerThanWide(myratio))
 	{ // The target surface is 5:4
 		y = (y - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5;
 		h = (bottom - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5 - y;
@@ -950,7 +950,7 @@ void DCanvas::FillBorder (FTexture *img)
 		return;
 	}
 	int bordtop, bordbottom, bordleft, bordright, bord;
-	if (Is54Aspect(myratio))
+	if (AspectTallerThanWide(myratio))
 	{ // Screen is taller than it is wide
 		bordleft = bordright = 0;
 		bord = Height - Height * AspectMultiplier(myratio) / 48;
diff --git a/src/v_video.cpp b/src/v_video.cpp
index 710d8b1cf..af190d372 100644
--- a/src/v_video.cpp
+++ b/src/v_video.cpp
@@ -1362,7 +1362,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
 	int cx1, cy1, cx2, cy2;
 
 	ratio = ActiveRatio(realwidth, realheight);
-	if (Is54Aspect(ratio))
+	if (AspectTallerThanWide(ratio))
 	{
 		cwidth = realwidth;
 		cheight = realheight * AspectMultiplier(ratio) / 48;
@@ -1703,29 +1703,36 @@ int CheckRatio (int width, int height, int *trueratio)
 
 int AspectBaseWidth(float aspect)
 {
-	return !Is54Aspect(aspect) ? (int)round(240.0f * aspect * 3.0f) : 960;
+	return (int)round(240.0f * aspect * 3.0f);
 }
 
 int AspectBaseHeight(float aspect)
 {
-	return !Is54Aspect(aspect) ? (int)round(200.0f * (320.0f / (240.0f * aspect)) * 3.0f) : 640;
+	if (!AspectTallerThanWide(aspect))
+		return (int)round(200.0f * (320.0f / (AspectBaseWidth(aspect) / 3.0f)) * 3.0f);
+	else
+		return (int)round((200.0f * (4.0f / 3.0f)) / aspect * 3.0f);
 }
 
 double AspectPspriteOffset(float aspect)
 {
-	return !Is54Aspect(aspect) ? 0.0 : 6.5;
+	if (!AspectTallerThanWide(aspect))
+		return 0.0;
+	else
+		return ((4.0 / 3.0) / aspect - 1.0) * 97.5;
 }
 
 int AspectMultiplier(float aspect)
 {
-	return !Is54Aspect(aspect) ? (int)round(320.0f / (240.0f * aspect) * 48.0f) : 48 * 15 / 16;
+	if (!AspectTallerThanWide(aspect))
+		return (int)round(320.0f / (AspectBaseWidth(aspect) / 3.0f) * 48.0f);
+	else
+		return (int)round(200.0f / (AspectBaseHeight(aspect) / 3.0f) * 48.0f);
 }
 
-bool Is54Aspect(float aspect)
+bool AspectTallerThanWide(float aspect)
 {
-	// The 5:4 aspect ratio redefined all the values to mean something else..
-	// Limit the range this is active to try prevent square cam textures inheriting this madness.
-	return aspect > 1.1f && aspect < 1.3f;
+	return aspect < 1.333f;
 }
 
 void IVideo::DumpAdapters ()
diff --git a/src/v_video.h b/src/v_video.h
index 26d45d9a0..7317c9d1a 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -525,7 +525,7 @@ int AspectBaseWidth(float aspect);
 int AspectBaseHeight(float aspect);
 double AspectPspriteOffset(float aspect);
 int AspectMultiplier(float aspect);
-bool Is54Aspect(float aspect);
+bool AspectTallerThanWide(float aspect);
 
 EXTERN_CVAR(Int, uiscale);