From 0b5e4b1f1f097b019a3daf62de2cbedab7ad6611 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@zdoom.fake>
Date: Mon, 22 Jan 2007 23:14:00 +0000
Subject: [PATCH] - Changed the vertheight and rounding-error-checking code in 
  DCanvas::DrawTexture() to calculate off the actual bottom of the image  
 instead of the height, improving precision. Now the scaled status bar is  
 flush with the bottom of the screen at 1280x1024, for instance.

SVN r458 (trunk)
---
 docs/rh-log.txt              |  4 ++++
 src/g_shared/shared_sbar.cpp |  5 -----
 src/v_draw.cpp               | 23 +++++++++++++----------
 src/v_video.cpp              |  8 ++++----
 4 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 87c9699e9..3bfff59cf 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,4 +1,8 @@
 January 22, 2007
+- Changed the vertheight and rounding-error-checking code in
+  DCanvas::DrawTexture() to calculate off the actual bottom of the image
+  instead of the height, improving precision. Now the scaled status bar is
+  flush with the bottom of the screen at 1280x1024, for instance.
 - Added a new WIF_NO_AUTO_SWITCH flag for weapons that should never be
   switched to automatically when the player picks them up.
 
diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp
index 281db32ab..58e9cedbb 100644
--- a/src/g_shared/shared_sbar.cpp
+++ b/src/g_shared/shared_sbar.cpp
@@ -921,11 +921,6 @@ void FBaseStatusBar::RefreshBackground () const
 			R_DrawBorder (0, y, x, SCREENHEIGHT);
 			R_DrawBorder (x2, y, SCREENWIDTH, SCREENHEIGHT);
 
-			if (Scaled && ::ST_Y + RelTop*SCREENHEIGHT/200 != SCREENHEIGHT)
-			{ // Fill the thin line beneath the status bar that we got thanks to rounding error
-				R_DrawBorder (x, SCREENHEIGHT-1, x2, SCREENHEIGHT);
-			}
-
 			if (setblocks >= 10)
 			{
 				const gameborder_t *border = gameinfo.border;
diff --git a/src/v_draw.cpp b/src/v_draw.cpp
index 0adb37991..8a2eb908c 100644
--- a/src/v_draw.cpp
+++ b/src/v_draw.cpp
@@ -335,23 +335,24 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, int x0, int y0, int tags_fi
 	if (virtWidth != Width || virtHeight != Height)
 	{
 		int myratio = CheckRatio (Width, Height);
-		if (myratio != 0 && !keepratio)
+		int right = x0 + destwidth;
+		int bottom = y0 + destheight;
+
+		if (myratio != 0 && myratio != 4 && !keepratio)
 		{ // The target surface is not 4:3, 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
 		  // those if somebody expresses a desire to use them.
-			x0 = Scale (Width*960, x0-virtWidth*FRACUNIT/2, virtWidth*BaseRatioSizes[myratio][0]) + Width*FRACUNIT/2;
-			y0 = Scale (Height, y0, virtHeight);
-			destwidth = FixedDiv (Width*960 * (destwidth>>FRACBITS), virtWidth*BaseRatioSizes[myratio][0]);
-			destheight = FixedDiv (Height * (destheight>>FRACBITS), virtHeight);
+			x0 = Scale (x0-virtWidth*FRACUNIT/2, Width*960, virtWidth*BaseRatioSizes[myratio][0]) + Width*FRACUNIT/2;
+			destwidth = Scale (right-virtWidth*FRACUNIT/2, Width*960, virtWidth*BaseRatioSizes[myratio][0]) + Width*FRACUNIT/2 - x0;
 		}
 		else
 		{
-			x0 = Scale (Width, x0, virtWidth);
-			y0 = Scale (Height, y0, virtHeight);
-			destwidth = FixedDiv (Width * (destwidth>>FRACBITS), virtWidth);
-			destheight = FixedDiv (Height * (destheight>>FRACBITS), virtHeight);
+			x0 = Scale (x0, Width, virtWidth);
+			destwidth = Scale (right, Width, virtWidth) - x0;
 		}
+		y0 = Scale (y0, Height, virtHeight);
+		destheight = Scale (bottom, Height, virtHeight) - y0;
 	}
 
 	if (destwidth <= 0 || destheight <= 0)
@@ -428,8 +429,10 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, int x0, int y0, int tags_fi
 		spryscale = destheight / img->GetHeight();
 
 		// Fix precision errors that are noticeable at some resolutions
-		if ((spryscale * img->GetHeight()) >> FRACBITS != destheight >> FRACBITS)
+		if (((y0 + destheight) >> FRACBITS) > ((y0 + spryscale * img->GetHeight()) >> FRACBITS))
+		{
 			spryscale++;
+		}
 
 		sprflipvert = false;
 		dc_iscale = 0xffffffffu / (unsigned)spryscale;
diff --git a/src/v_video.cpp b/src/v_video.cpp
index 12bb76cbc..84f9bbe57 100644
--- a/src/v_video.cpp
+++ b/src/v_video.cpp
@@ -1065,9 +1065,9 @@ int CheckRatio (int width, int height)
 // Fourth column: Width or height multiplier
 const int BaseRatioSizes[5][4] =
 {
-	{  960, 600, 0,                   48 },			// 320,      200,      multiplied by three
-	{ 1280, 450, 0,                   48*3/4 },		// 426.6667, 150,      multiplied by three
-	{ 1152, 500, 0,                   48*5/6 },		// 386,      166.6667, multiplied by three
+	{  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
 	{  960, 600, 0,                   48 },
-	{  960, 640, (int)(6.5*FRACUNIT), 48*15/16 }	// 320,      213.3333, multiplied by three
+	{  960, 640, (int)(6.5*FRACUNIT), 48*15/16 }	//  5:4   320,      213.3333, multiplied by three
 };