changeset 2610:a9aef6911f7b

Improve image size/window size handling in 64vw to be actually sane. Image now scales correctly (using PAL pixel aspect ratio) vs actual window size. Also toggling between windowed and fullscreen no longer messes up the window size.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 27 Nov 2023 10:14:07 +0200
parents 0f351e291319
children 97810e89cad5
files tools/64vw.c
diffstat 1 files changed, 43 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/tools/64vw.c	Mon Nov 27 09:21:29 2023 +0200
+++ b/tools/64vw.c	Mon Nov 27 10:14:07 2023 +0200
@@ -17,8 +17,8 @@
 #define SET_SKIP_AMOUNT 10
 
 
-int     optVFlags = 0;
-int     optScrWidth, optScrHeight;
+int     optWindowFlags = 0;
+int     optSetWindowWidth, optSetWindowHeight;
 int     optForcedFormat = -1;
 bool    optInfoOnly  = false,
         optProbeOnly = false,
@@ -54,8 +54,8 @@
 
 void dmSetScaleFactor(float factor)
 {
-    optScrWidth = (int) ((float) D64_SCR_WIDTH * factor * D64_SCR_PAR_XY);
-    optScrHeight = (int) ((float) D64_SCR_HEIGHT * factor);
+    optSetWindowWidth = (int) ((float) D64_SCR_WIDTH * factor * D64_SCR_PAR_XY);
+    optSetWindowHeight = (int) ((float) D64_SCR_HEIGHT * factor);
 }
 
 
@@ -102,7 +102,7 @@
             break;
 
         case 10:
-            optVFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+            optWindowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
             break;
 
         case 12:
@@ -273,8 +273,9 @@
     SDL_Texture *texture = NULL;
     SDL_Surface *surf = NULL;
     DMImage *bimage = NULL;
-    bool initSDL = false, exitFlag, needRedraw;
+    bool initSDL = false, exitFlag, needRedraw, allowResize;
     size_t currIndex, prevIndex;
+    int currWindowWidth, currWindowHeight;
     int res = DMERR_OK;
 
     // Initialize pre-requisites
@@ -427,8 +428,8 @@
     // Open window
     if ((window = SDL_CreateWindow(dmProgName,
         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
-        optScrWidth, optScrHeight,
-        optVFlags | SDL_WINDOW_RESIZABLE
+        optSetWindowWidth, optSetWindowHeight,
+        optWindowFlags | SDL_WINDOW_RESIZABLE
         //| SDL_WINDOW_HIDDEN
         )) == NULL)
     {
@@ -445,9 +446,12 @@
 //    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
 
     // Start main loop
+    currWindowWidth = optSetWindowWidth;
+    currWindowHeight = optSetWindowHeight;
     currIndex = 0;
     prevIndex = 1;
     needRedraw = true;
+    allowResize = true;
     exitFlag = false;
     while (!exitFlag)
     {
@@ -503,9 +507,16 @@
                         break;
 
                     case SDLK_f:
-                        optVFlags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
-                        if (SDL_SetWindowFullscreen(window, optVFlags) != 0)
+                        // If we switch to/from fullscreen, set a flag so we do not
+                        // use the fullscreen window size as new stored window size
+                        allowResize = false;
+                        optWindowFlags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
+
+                        if (SDL_SetWindowFullscreen(window, optWindowFlags) != 0)
                             goto out;
+
+                        if ((optWindowFlags & SDL_WINDOW_FULLSCREEN_DESKTOP) == 0)
+                            SDL_SetWindowSize(window, optSetWindowWidth, optSetWindowHeight);
                         break;
 
                     default:
@@ -523,9 +534,14 @@
                         break;
 
                     case SDL_WINDOWEVENT_RESIZED:
-                        optScrWidth  = event.window.data1;
-                        optScrHeight = event.window.data2;
-
+                        if (allowResize)
+                        {
+                            optSetWindowWidth  = event.window.data1;
+                            optSetWindowHeight = event.window.data2;
+                        }
+                        currWindowWidth = event.window.data1;
+                        currWindowHeight = event.window.data2;
+                        allowResize = true;
                         needRedraw = true;
                         break;
                 }
@@ -542,6 +558,7 @@
             DMC64Image *cimage = NULL;
             char *title = NULL;
 
+            // Delete previous surface if any
             if (surf != NULL)
             {
                 SDL_FreeSurface(surf);
@@ -570,7 +587,7 @@
                 goto fail;
             }
 
-            // Create surface (we are lazy and ugly)
+            // Convert image to surface (we are lazy and ugly)
             if (dmConvertC64ImageToSDLSurface(&bimage, &surf, cimage, &optSpec) == DMERR_OK)
             {
                 title = dm_strdup_printf("%s - [%d / %d] %s (%dx%d @ %s)",
@@ -591,6 +608,7 @@
 fail:
             dmC64ImageFree(cimage);
 
+            // Create or update surface and texture
             if (surf == NULL && (surf = SDL_CreateRGBSurfaceWithFormat(0,
                 D64_SCR_WIDTH, D64_SCR_HEIGHT, 8, SDL_PIXELFORMAT_INDEX8)) == NULL)
             {
@@ -607,6 +625,7 @@
                 goto out;
             }
 
+            // Create stub title string if we didn't manage to decode the image
             if (title == NULL)
             {
                 title = dm_strdup_printf("%s - [%d / %d] %s",
@@ -625,13 +644,20 @@
 
         if (needRedraw)
         {
+            // Calculate the render size
+            SDL_Rect dstRect;
+            dstRect.w = (((float) currWindowHeight) * D64_SCR_FULL_WIDTH / D64_SCR_FULL_HEIGHT / D64_SCR_PAR_XY);
+            dstRect.h = currWindowHeight;
+            dstRect.x = (currWindowWidth - dstRect.w) / 2;
+            dstRect.y = 0;
+
             SDL_RenderClear(renderer);
-            SDL_RenderCopy(renderer, texture, NULL, NULL);
+            SDL_RenderCopy(renderer, texture, NULL, &dstRect);
             SDL_RenderPresent(renderer);
             needRedraw = false;
         }
-
-        SDL_Delay(50);
+        else
+            SDL_Delay(50);
     }
 
 out: