From 522a2e7292a96008da4911bee580cfd02fa72537 Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 02:31:12 -0800
Subject: [PATCH 1/6] 21:9 aspect ratio support

 - vid_aspect 6 forces 21:9
---
 src/g_shared/shared_sbar.cpp |  4 ++--
 src/posix/sdl/hardware.cpp   |  4 ++--
 src/r_main.cpp               |  4 ++--
 src/r_utility.cpp            |  2 +-
 src/v_draw.cpp               |  2 +-
 src/v_video.cpp              | 19 ++++++++++++++-----
 src/v_video.h                |  8 +++++++-
 src/win32/hardware.cpp       |  4 ++--
 8 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp
index dabddba..d0153a9 100644
--- a/src/g_shared/shared_sbar.cpp
+++ b/src/g_shared/shared_sbar.cpp
@@ -1058,7 +1058,7 @@ void DBaseStatusBar::RefreshBackground () const
 	int x, x2, y, ratio;
 
 	ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT);
-	x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2);
+	x = (!IsRatioWidescreen(ratio) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2);
 	y = x == ST_X && x > 0 ? ST_Y : ::ST_Y;
 
 	if(!CompleteBorder)
@@ -1078,7 +1078,7 @@ void DBaseStatusBar::RefreshBackground () const
 	{
 		if(!CompleteBorder)
 		{
-			x2 = !(ratio & 3) || !Scaled ? ST_X+HorizontalResolution :
+			x2 = !IsRatioWidescreen(ratio) || !Scaled ? ST_X+HorizontalResolution :
 				SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2);
 		}
 		else
diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp
index 75d6632..213ca04 100644
--- a/src/posix/sdl/hardware.cpp
+++ b/src/posix/sdl/hardware.cpp
@@ -308,7 +308,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 
 CCMD (vid_listmodes)
 {
-	static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" };
+	static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", " - 21:9" };
 	int width, height, bits;
 	bool letterbox;
 
@@ -325,7 +325,7 @@ CCMD (vid_listmodes)
 			int ratio = CheckRatio (width, height);
 			Printf (thisMode ? PRINT_BOLD : PRINT_HIGH,
 				"%s%4d x%5d x%3d%s%s\n",
-				thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD,
+				thisMode || !IsRatioWidescreen(ratio) ? "" : TEXTCOLOR_GOLD,
 				width, height, bits,
 				ratios[ratio],
 				thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB"
diff --git a/src/r_main.cpp b/src/r_main.cpp
index 12dd391..ee557bb 100644
--- a/src/r_main.cpp
+++ b/src/r_main.cpp
@@ -363,7 +363,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
 	virtwidth = virtwidth2 = fullWidth;
 	virtheight = virtheight2 = fullHeight;
 
-	if (trueratio & 4)
+	if (Is54Aspect(trueratio))
 	{
 		virtheight2 = virtheight2 * BaseRatioSizes[trueratio][3] / 48;
 	}
@@ -372,7 +372,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
 		virtwidth2 = virtwidth2 * BaseRatioSizes[trueratio][3] / 48;
 	}
 
-	if (WidescreenRatio & 4)
+	if (Is54Aspect(WidescreenRatio))
 	{
 		virtheight = virtheight * BaseRatioSizes[WidescreenRatio][3] / 48;
 	}
diff --git a/src/r_utility.cpp b/src/r_utility.cpp
index 089c653..d301b45 100644
--- a/src/r_utility.cpp
+++ b/src/r_utility.cpp
@@ -434,7 +434,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
 
 	centery = viewheight/2;
 	centerx = viewwidth/2;
-	if (WidescreenRatio & 4)
+	if (Is54Aspect(WidescreenRatio))
 	{
 		centerxwide = centerx;
 	}
diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index de096e3..eeb1a7d 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -816,7 +816,7 @@ void DCanvas::FillBorder (FTexture *img)
 		return;
 	}
 	int bordtop, bordbottom, bordleft, bordright, bord;
-	if (myratio & 4)
+	if (Is54Aspect(myratio))
 	{ // Screen is taller than it is wide
 		bordleft = bordright = 0;
 		bord = Height - Height * BaseRatioSizes[myratio][3] / 48;
diff --git a/src/v_video.cpp b/src/v_video.cpp
index 73681fd..b69bba6 100644
--- a/src/v_video.cpp
+++ b/src/v_video.cpp
@@ -1397,7 +1397,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real
 	int cx1, cy1, cx2, cy2;
 
 	ratio = CheckRatio(realwidth, realheight);
-	if (ratio & 4)
+	if (Is54Aspect(ratio))
 	{
 		cwidth = realwidth;
 		cheight = realheight * BaseRatioSizes[ratio][3] / 48;
@@ -1645,12 +1645,14 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
 // 2: 16:10
 // 3: 17:10
 // 4: 5:4
+// 5: 17:10 (redundant)
+// 6: 21:9
 int CheckRatio (int width, int height, int *trueratio)
 {
 	int fakeratio = -1;
 	int ratio;
 
-	if ((vid_aspect >= 1) && (vid_aspect <= 5))
+	if ((vid_aspect >= 1) && (vid_aspect <= 6))
 	{
 		// [SP] User wants to force aspect ratio; let them.
 		fakeratio = int(vid_aspect);
@@ -1661,7 +1663,7 @@ int CheckRatio (int width, int height, int *trueratio)
 		else if (fakeratio == 5)
 		{
 			fakeratio = 3;
-		}
+		}        
 	}
 	if (vid_nowidescreen)
 	{
@@ -1702,6 +1704,11 @@ int CheckRatio (int width, int height, int *trueratio)
 	{
 		ratio = 4;
 	}
+    // test for 21:9 (actually 64:27, 21:9 is a semi-accurate ratio used in marketing)
+    else if (abs (height * 64/27 - width) < 30)
+    {
+        ratio = 6;
+    }
 	// Assume anything else is 4:3. (Which is probably wrong these days...)
 	else
 	{
@@ -1724,13 +1731,15 @@ int CheckRatio (int width, int height, int *trueratio)
 //     base_width = 240 * x / y
 //     multiplier = 320 / base_width
 //     base_height = 200 * multiplier
-const int BaseRatioSizes[5][4] =
+const int BaseRatioSizes[7][4] =
 {
 	{  960, 600, 0,                   48 },			//  4:3   320,      200,      multiplied by three
 	{ 1280, 450, 0,                   48*3/4 },		// 16:9   426.6667, 150,      multiplied by three
 	{ 1152, 500, 0,                   48*5/6 },		// 16:10  386,      166.6667, multiplied by three
 	{ 1224, 471, 0,                   48*40/51 },	// 17:10  408,		156.8627, multiplied by three
-	{  960, 640, (int)(6.5*FRACUNIT), 48*15/16 }	//  5:4   320,      213.3333, multiplied by three
+	{  960, 640, (int)(6.5*FRACUNIT), 48*15/16 },   //  5:4   320,      213.3333, multiplied by three
+    { 1224, 471, 0,                   48*40/51 },	// 17:10  408,		156.8627, multiplied by three (REDUNDANT)
+    {  568, 113, 0,                   48*5/8 }      //  21:9
 };
 
 void IVideo::DumpAdapters ()
diff --git a/src/v_video.h b/src/v_video.h
index 0497b60..7e0b092 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -503,8 +503,14 @@ extern "C" void ASM_PatchPitch (void);
 
 int CheckRatio (int width, int height, int *trueratio=NULL);
 static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); }
-extern const int BaseRatioSizes[5][4];
+extern const int BaseRatioSizes[7][4];
 
+inline bool IsRatioWidescreen(int ratio) {
+    return (ratio & 3)!=0;
+}
 
+inline bool Is54Aspect(int ratio) {
+    return ratio == 4;
+}
 
 #endif // __V_VIDEO_H__
diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp
index d8a4fa9..cb4250b 100644
--- a/src/win32/hardware.cpp
+++ b/src/win32/hardware.cpp
@@ -338,7 +338,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 
 CCMD (vid_listmodes)
 {
-	static const char *ratios[5] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4" };
+	static const char *ratios[6] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 21:9" };
 	int width, height, bits;
 	bool letterbox;
 
@@ -356,7 +356,7 @@ CCMD (vid_listmodes)
 			int ratio = CheckRatio (width, height);
 			Printf (thisMode ? PRINT_BOLD : PRINT_HIGH,
 				"%s%4d x%5d x%3d%s%s\n",
-				thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD,
+				thisMode || !IsRatioWidescreen(ratio) ? "" : TEXTCOLOR_GOLD,
 				width, height, bits,
 				ratios[ratio],
 				thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB"
-- 
2.5.3.windows.1


From 62a0e7b397fa59945a88a5fe34aced9311f4308e Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 12:07:11 -0800
Subject: [PATCH 2/6] fix: 21:9 AR stretching in intermission, end level
 screens

---
 src/v_draw.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index eeb1a7d..ca9f9ae 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -744,6 +744,13 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
 	double vwidth, double vheight, bool vbottom, bool handleaspect) const
 {
 	int myratio = handleaspect ? CheckRatio (Width, Height) : 0;
+
+    // if 21:9 AR, map to 16:9 for all callers.
+    // this allows for black bars and stops the stretching of fullscreen images
+    if (myratio == 6) {
+        myratio = 2;
+    }
+
 	double right = x + w;
 	double bottom = y + h;
 
-- 
2.5.3.windows.1


From 6a294fffdc3ba5d7e36ca66be592a71dbce405ea Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 12:33:06 -0800
Subject: [PATCH 3/6] 21:9 fix for black bars overlapping fullscreen images

---
 src/v_draw.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index ca9f9ae..bf3a65c 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -818,6 +818,13 @@ void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h,
 void DCanvas::FillBorder (FTexture *img)
 {
 	int myratio = CheckRatio (Width, Height);
+
+    // if 21:9 AR, fill borders akin to 16:9, since all fullscreen
+    // images are being drawn to that scale.
+    if (myratio == 6) {
+        myratio = 2;
+    }
+
 	if (myratio == 0)
 	{ // This is a 4:3 display, so no border to show
 		return;
-- 
2.5.3.windows.1


From c29f40b7849c3be658ba779e7f9f4627e1650420 Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 12:35:45 -0800
Subject: [PATCH 4/6] Slightly improve 21:9 ar

---
 src/v_video.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/v_video.cpp b/src/v_video.cpp
index b69bba6..c224023 100644
--- a/src/v_video.cpp
+++ b/src/v_video.cpp
@@ -1739,7 +1739,7 @@ const int BaseRatioSizes[7][4] =
 	{ 1224, 471, 0,                   48*40/51 },	// 17:10  408,		156.8627, multiplied by three
 	{  960, 640, (int)(6.5*FRACUNIT), 48*15/16 },   //  5:4   320,      213.3333, multiplied by three
     { 1224, 471, 0,                   48*40/51 },	// 17:10  408,		156.8627, multiplied by three (REDUNDANT)
-    {  568, 113, 0,                   48*5/8 }      //  21:9
+    {  568, 113, 0,                   48*9/16 }     //  21:9
 };
 
 void IVideo::DumpAdapters ()
-- 
2.5.3.windows.1


From 996c929b5acd4af470aa98c8be54bbd091ee6f24 Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 12:49:28 -0800
Subject: [PATCH 5/6] vid_listmodes crash fix

---
 src/posix/sdl/hardware.cpp | 2 +-
 src/win32/hardware.cpp     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp
index 213ca04..b066431 100644
--- a/src/posix/sdl/hardware.cpp
+++ b/src/posix/sdl/hardware.cpp
@@ -308,7 +308,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 
 CCMD (vid_listmodes)
 {
-	static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", " - 21:9" };
+	static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", "", " - 21:9" };
 	int width, height, bits;
 	bool letterbox;
 
diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp
index cb4250b..8cc7705 100644
--- a/src/win32/hardware.cpp
+++ b/src/win32/hardware.cpp
@@ -338,7 +338,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 
 CCMD (vid_listmodes)
 {
-	static const char *ratios[6] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 21:9" };
+	static const char *ratios[7] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 17:10", " - 21:9" };
 	int width, height, bits;
 	bool letterbox;
 
-- 
2.5.3.windows.1


From bfc5c10219b0e55e4c3f166e0122c99325abf410 Mon Sep 17 00:00:00 2001
From: Michael Labbe <mike@frogtoss.com>
Date: Wed, 2 Mar 2016 13:58:29 -0800
Subject: [PATCH 6/6] UI support for 21:9

 - Can specify aspect ratio 21:9 in video menu
 - menu_screenratios cvar can now force 21:9
---
 src/menu/videomenu.cpp    | 4 ++--
 wadsrc/static/menudef.txt | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp
index 59f794f..1328e2f 100644
--- a/src/menu/videomenu.cpp
+++ b/src/menu/videomenu.cpp
@@ -85,7 +85,7 @@ static BYTE BitTranslate[32];
 
 CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE)
 {
-	if (self < -1 || self > 4)
+	if (self < -1 || self > 6)
 	{
 		self = -1;
 	}
@@ -216,7 +216,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
 	bool letterbox=false;
 	int  ratiomatch;
 
-	if (menu_screenratios >= 0 && menu_screenratios <= 4)
+	if (menu_screenratios >= 0 && menu_screenratios <= 6)
 	{
 		ratiomatch = menu_screenratios;
 	}
diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt
index a36ecc7..164956d 100644
--- a/wadsrc/static/menudef.txt
+++ b/wadsrc/static/menudef.txt
@@ -1677,6 +1677,7 @@ OptionValue ForceRatios
 	5.0, "17:10"
 	2.0, "16:10"
 	4.0, "5:4"
+	6.0, "21:9"
 }
 OptionValue Ratios
 {
@@ -1684,6 +1685,7 @@ OptionValue Ratios
 	1.0, "16:9"
 	2.0, "16:10"
 	3.0, "17:10"
+	6.0, "21:9"
 	 -1, "$OPTVAL_ALL"
 }
 OptionValue RatiosTFT
@@ -1693,6 +1695,7 @@ OptionValue RatiosTFT
 	1.0, "16:9"
 	2.0, "16:10"
 	3.0, "17:10"
+	6.0, "21:9"
 	 -1, "$OPTVAL_ALL"
 }
 
-- 
2.5.3.windows.1

