[PATCH 2/2] Support floating point zoom factors with SDL2

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


---
 doc/hatari.1                 |  9 ++++++++-
 src/configuration.c          |  2 ++
 src/includes/configuration.h |  1 +
 src/options.c                | 38 ++++++++++++++++++++++++++++++++++--
 src/screen.c                 | 13 ++++++++++--
 5 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/doc/hatari.1 b/doc/hatari.1
index 99138ad8..10ae8711 100644
--- a/doc/hatari.1
+++ b/doc/hatari.1
@@ -160,7 +160,14 @@ the slower but more accurate Spectrum512 screen conversion functions
 (0 <= x <= 512, 0=disable)
 .TP
 .B \-z, \-\-zoom <x>
-Zoom (double) low resolution (1=no, 2=yes)
+With Hatari SDL1 build, this can be used only to zoom (double) low
+resolution (1=no, 2=yes), whereas with Hatari SDL2 build, any zoom
+factor can be used.
+
+Integer scaling factors will use linear interpolation for sharper
+output, and non-integer ones use bilinear one to smooth out uneven
+scaling.  Zooming with SDL2 enables SdlRenderer (configuration file
+option) use.
 .TP
 .B \-\-video-timing <x>
 Wakeup State for MMU/GLUE (x=ws1/ws2/ws3/ws4/random,
diff --git a/src/configuration.c b/src/configuration.c
index 87fe724d..62798053 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -99,6 +99,7 @@ static const struct Config_Tag configs_Screen[] =
 	{ "nMaxWidth", Int_Tag, &ConfigureParams.Screen.nMaxWidth },
 	{ "nMaxHeight", Int_Tag, &ConfigureParams.Screen.nMaxHeight },
 #if WITH_SDL2
+	{ "nZoomFactor", Float_Tag, &ConfigureParams.Screen.nZoomFactor },
 	{ "bUseSdlRenderer", Bool_Tag, &ConfigureParams.Screen.bUseSdlRenderer },
 	{ "nRenderScaleQuality", Int_Tag, &ConfigureParams.Screen.nRenderScaleQuality },
 	{ "bUseVsync", Bool_Tag, &ConfigureParams.Screen.bUseVsync },
@@ -840,6 +841,7 @@ void Configuration_SetDefault(void)
 	ConfigureParams.Screen.bForceMax = false;
 	ConfigureParams.Screen.DisableVideo = false;
 #if WITH_SDL2
+	ConfigureParams.Screen.nZoomFactor = 1.0;
 	ConfigureParams.Screen.bUseSdlRenderer = true;
 	ConfigureParams.Screen.nRenderScaleQuality = 0;
 	ConfigureParams.Screen.bUseVsync = false;
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index dbaf97ac..3c4f8868 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -304,6 +304,7 @@ typedef struct
   bool bResizable;
   bool bUseVsync;
   bool bUseSdlRenderer;
+  float nZoomFactor;
   int nRenderScaleQuality;
 #endif
   int nSpec512Threshold;
diff --git a/src/options.c b/src/options.c
index c40a1bd6..f207185a 100644
--- a/src/options.c
+++ b/src/options.c
@@ -265,7 +265,11 @@ static const opt_t HatariOptions[] = {
 	{ OPT_SPEC512, NULL, "--spec512",
 	  "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
 	{ OPT_ZOOM, "-z", "--zoom",
+#if WITH_SDL2
+	  "<x>", "Screen zoom factor (1.0 - 8.0)" },
+#else
 	  "<x>", "Double small resolutions (1=no, 2=yes)" },
+#endif
 	{ OPT_VIDEO_TIMING,   NULL, "--video-timing",
 	  "<x>", "Wakeup State for MMU/GLUE (x=ws1/ws2/ws3/ws4/random, default ws3)" },
 
@@ -1041,9 +1045,14 @@ static bool Opt_HandleArgument(const char *path)
  */
 bool Opt_ParseParameters(int argc, const char * const argv[])
 {
-	int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port, freq, temp, drive;
+	int ncpu, skips, planes, cpuclock, threshold, memsize, port, freq, temp, drive;
 	const char *errstr, *str;
 	int i, ok = true;
+#if WITH_SDL2
+	float zoom;
+#else
+	int zoom;
+#endif
 	int val;
 
 	/* Defaults for loading initial memory snap-shots */
@@ -1242,18 +1251,43 @@ bool Opt_ParseParameters(int argc, const char * const argv[])
 			break;
 
 		case OPT_ZOOM:
+#if WITH_SDL2
+			zoom = atof(argv[++i]);
+			if (zoom < 1.0 || zoom > 8.0)
+#else
 			zoom = atoi(argv[++i]);
-			if (zoom < 1)
+			if (zoom < 1 || zoom > 2)
+#endif
 			{
 				return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
 			}
 			ConfigureParams.Screen.nMaxWidth = NUM_VISIBLE_LINE_PIXELS;
 			ConfigureParams.Screen.nMaxHeight = NUM_VISIBLE_LINES;
+#if WITH_SDL2
+			ConfigureParams.Screen.nZoomFactor = zoom;
+			if (zoom >= 1.0)
+			{
+				ConfigureParams.Screen.bUseSdlRenderer = true;
+				if (zoom >= 2.0)
+				{
+					ConfigureParams.Screen.nMaxWidth *= 2;
+					ConfigureParams.Screen.nMaxHeight *= 2;
+				}
+				/* linear scaling for integer zoom factors,
+				 * blending/blurring bilinear scaling otherwise
+				 */
+				if (zoom == floorf(zoom))
+					ConfigureParams.Screen.nRenderScaleQuality = 0;
+				else
+					ConfigureParams.Screen.nRenderScaleQuality = 1;
+			}
+#else
 			if (zoom > 1)
 			{
 				ConfigureParams.Screen.nMaxWidth *= 2;
 				ConfigureParams.Screen.nMaxHeight *= 2;
 			}
+#endif
 			ConfigureParams.Screen.nMaxHeight += STATUSBAR_MAX_HEIGHT;
 			break;
 
diff --git a/src/screen.c b/src/screen.c
index 16249883..a62d2a3a 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -327,6 +327,7 @@ bool Screen_SetSDLVideoSize(int width, int height, int bitdepth, bool bForceChan
 	static bool bPrevUseVsync = false;
 	static bool bPrevInFullScreen;
 	int win_width, win_height;
+	float scale = 1.0;
 
 	if (bitdepth == 0 || bitdepth == 24)
 		bitdepth = 32;
@@ -355,6 +356,12 @@ bool Screen_SetSDLVideoSize(int width, int height, int bitdepth, bool bForceChan
 	/* SDL Video attributes: */
 	win_width = width;
 	win_height = height;
+	if (bUseSdlRenderer)
+	{
+		scale = ConfigureParams.Screen.nZoomFactor / nScreenZoomX;
+		win_width *= scale;
+		win_height *= scale;
+	}
 	if (bInFullScreen)
 	{
 		sdlVideoFlags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_INPUT_GRABBED;
@@ -412,8 +419,8 @@ bool Screen_SetSDLVideoSize(int width, int height, int bitdepth, bool bForceChan
 #endif
 
 	/* Set new video mode */
-	DEBUGPRINT(("SDL screen request: %d x %d @ %d (%s)\n", width, height,
-	        bitdepth, bInFullScreen?"fullscreen":"windowed"));
+	DEBUGPRINT(("SDL screen request: %d x %d @ %d (%s) -> window: %d x %d\n", width, height,
+	        bitdepth, (bInFullScreen ? "fullscreen" : "windowed"), win_width, win_height));
 
 	if (sdlWindow)
 	{
@@ -451,6 +458,8 @@ bool Screen_SetSDLVideoSize(int width, int height, int bitdepth, bool bForceChan
 
 		if (bInFullScreen)
 			SDL_RenderSetLogicalSize(sdlRenderer, width, height);
+		else
+			SDL_RenderSetScale(sdlRenderer, scale, scale);
 
 		if (bitdepth == 16)
 		{
-- 
2.20.1


--------------648D7304C4B2443A8158A44F
Content-Type: text/x-patch; charset=UTF-8;
 name="0001-Optimize-CNF-structs-by-grouping-ints-bools.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="0001-Optimize-CNF-structs-by-grouping-ints-bools.patch"



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/