From e074c75609e6083c691d6a59d78212a72b73ab17 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@users.noreply.github.com>
Date: Sun, 2 Apr 2017 12:56:26 +0200
Subject: [PATCH] - added a generic TransformRect to the status bar so that the
 proper transformations can be applied to draw operations that require special
 parameters not supported by the stock functions.

---
 src/g_statusbar/sbar.h                        |  1 +
 src/g_statusbar/shared_sbar.cpp               | 86 ++++++++-----------
 wadsrc/static/zscript/statusbar/statusbar.txt |  1 +
 3 files changed, 37 insertions(+), 51 deletions(-)

diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h
index fd200c8d8..e4ca894ac 100644
--- a/src/g_statusbar/sbar.h
+++ b/src/g_statusbar/sbar.h
@@ -396,6 +396,7 @@ public:
 
 	void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
 	void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
+	void TransformRect(double &x, double &y, double &w, double &h, int flags = 0);
 	void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
 	void SetClipRect(double x, double y, double w, double h, int flags = 0);
 
diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp
index 3b3a900b1..2514cd8d2 100644
--- a/src/g_statusbar/shared_sbar.cpp
+++ b/src/g_statusbar/shared_sbar.cpp
@@ -1847,7 +1847,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
 //
 //============================================================================
 
-void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags)
+void DBaseStatusBar::TransformRect(double &x, double &y, double &w, double &h, int flags)
 {
 	// resolve auto-alignment before making any adjustments to the position values.
 	if (!(flags & DI_SCREEN_MANUAL_ALIGN))
@@ -1858,8 +1858,6 @@ void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h
 		else flags |= DI_SCREEN_TOP;
 	}
 
-	double Alpha = color.a * this->Alpha / 255;
-	if (Alpha <= 0) return;
 	x += drawOffset.X;
 	y += drawOffset.Y;
 
@@ -1897,10 +1895,42 @@ void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h
 		x += orgx;
 		y += orgy;
 	}
+}
+
+
+DEFINE_ACTION_FUNCTION(DBaseStatusBar, TransformRect)
+{
+	PARAM_SELF_PROLOGUE(DBaseStatusBar);
+	PARAM_FLOAT(x);
+	PARAM_FLOAT(y);
+	PARAM_FLOAT(w);
+	PARAM_FLOAT(h);
+	PARAM_INT_DEF(flags);
+	self->TransformRect(x, y, w, h, flags);
+	if (numret > 0) ret[0].SetFloat(x);
+	if (numret > 1) ret[1].SetFloat(y);
+	if (numret > 2) ret[2].SetFloat(w);
+	if (numret > 3) ret[3].SetFloat(h);
+	return MIN(4, numret);
+}
+
+//============================================================================
+//
+// draw stuff
+//
+//============================================================================
+
+void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags)
+{
+	double Alpha = color.a * this->Alpha / 255;
+	if (Alpha <= 0) return;
+
+	TransformRect(x, y, w, h, flags);
+
 	int x1 = int(x);
 	int y1 = int(y);
 	int ww = int(x + w - x1);	// account for scaling to non-integers. Truncating the values separately would fail for cases like 
-	int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
+	int hh = int(y + h - y1);	// y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
 
 	screen->Dim(color, float(Alpha), x1, y1, ww, hh);
 }
@@ -1928,57 +1958,11 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill)
 
 void DBaseStatusBar::SetClipRect(double x, double y, double w, double h, int flags)
 {
-	// resolve auto-alignment before making any adjustments to the position values.
-	if (!(flags & DI_SCREEN_MANUAL_ALIGN))
-	{
-		if (x < 0) flags |= DI_SCREEN_RIGHT;
-		else flags |= DI_SCREEN_LEFT;
-		if (y < 0) flags |= DI_SCREEN_BOTTOM;
-		else flags |= DI_SCREEN_TOP;
-	}
-
-	x += drawOffset.X;
-	y += drawOffset.Y;
-
-	if (!fullscreenOffsets)
-	{
-		StatusbarToRealCoords(x, y, w, h);
-	}
-	else
-	{
-		double orgx, orgy;
-
-		switch (flags & DI_SCREEN_HMASK)
-		{
-		default: orgx = 0; break;
-		case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
-		case DI_SCREEN_RIGHT:   orgx = screen->GetWidth(); break;
-		}
-
-		switch (flags & DI_SCREEN_VMASK)
-		{
-		default: orgy = 0; break;
-		case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
-		case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
-		}
-
-		// move stuff in the top right corner a bit down if the fps counter is on.
-		if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
-
-		DVector2 Scale = GetHUDScale();
-
-		x *= Scale.X;
-		y *= Scale.Y;
-		w *= Scale.X;
-		h *= Scale.Y;
-		x += orgx;
-		y += orgy;
-	}
+	TransformRect(x, y, w, h, flags);
 	int x1 = int(x);
 	int y1 = int(y);
 	int ww = int(x + w - x1);	// account for scaling to non-integers. Truncating the values separately would fail for cases like 
 	int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
-
 	screen->SetClipRect(x1, y1, ww, hh);
 }
 
diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt
index 7ea4ca39d..789e3cd8d 100644
--- a/wadsrc/static/zscript/statusbar/statusbar.txt
+++ b/wadsrc/static/zscript/statusbar/statusbar.txt
@@ -323,6 +323,7 @@ class BaseStatusBar native ui
 	native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
 	native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
 	native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4);
+	native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0);
 	native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
 	native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
 	native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);