shithub: choc

Download patch

ref: ad8d7a1efb8c61bb39568f76ab814919895cc501
parent: 4319d9cda4caab4a9c4d5f98a780ea8d9e3531f6
author: Simon Howard <[email protected]>
date: Tue Aug 3 16:12:36 EDT 2010

When in windowed mode, allow the screen size to be dynamically resized
by dragging the window borders.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1949

--- a/src/i_scale.c
+++ b/src/i_scale.c
@@ -53,11 +53,11 @@
 // stretch_tables[1] : 40% / 60%
 // All other combinations can be reached from these two tables.
 
-static byte *stretch_tables[2];
+static byte *stretch_tables[2] = { NULL, NULL };
 
 // 50%/50% stretch table, for 800x600 squash mode
 
-static byte *half_stretch_table;
+static byte *half_stretch_table = NULL;
 
 // Called to set the source and destination buffers before doing the
 // scale.
@@ -364,6 +364,11 @@
 
 static void I_InitStretchTables(byte *palette)
 {
+    if (stretch_tables[0] != NULL)
+    {
+        return;
+    }
+
     // We only actually need two lookup tables:
     //
     // mix 0%   =  just write line 1
@@ -385,6 +390,11 @@
 
 static void I_InitSquashTable(byte *palette)
 {
+    if (half_stretch_table != NULL)
+    {
+        return;
+    }
+
     printf("I_InitSquashTable: Generating lookup table..");
     fflush(stdout);
     half_stretch_table = GenerateStretchTable(palette, 50);
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -98,8 +98,6 @@
 static SDL_Color palette[256];
 static boolean palette_to_set;
 
-static int windowwidth, windowheight;
-
 // display has been set up?
 
 static boolean initialized = false;
@@ -160,6 +158,12 @@
 
 static screen_mode_t *screen_mode;
 
+// Window resize state.
+
+static boolean need_resize = false;
+static unsigned int resize_w, resize_h;
+static unsigned int last_resize_time;
+
 // If true, keyboard mapping is ignored, like in Vanilla Doom.
 // The sensible thing to do is to disable this if you have a non-US
 // keyboard.
@@ -178,6 +182,8 @@
 float mouse_acceleration = 2.0;
 int mouse_threshold = 10;
 
+static void ApplyWindowResize(unsigned int w, unsigned int h);
+
 static boolean MouseShouldBeGrabbed()
 {
     // never grab the mouse when in screensaver mode
@@ -580,6 +586,13 @@
                 palette_to_set = true;
                 break;
 
+            case SDL_RESIZABLE:
+                need_resize = true;
+                resize_w = sdlevent.resize.w;
+                resize_h = sdlevent.resize.h;
+                last_resize_time = SDL_GetTicks();
+                break;
+
             default:
                 break;
         }
@@ -815,7 +828,6 @@
     static int	lasttic;
     int		tics;
     int		i;
-    // UNUSED static unsigned char *bigscreen=0;
 
     if (!initialized)
         return;
@@ -822,7 +834,14 @@
 
     if (noblit)
         return;
-    
+
+    if (need_resize && SDL_GetTicks() > last_resize_time + 500)
+    {
+        ApplyWindowResize(resize_w, resize_h);
+        need_resize = false;
+        palette_to_set = true;
+    }
+
     UpdateGrab();
 
     // Don't update the screen if the window isn't visible.
@@ -1492,11 +1511,96 @@
     }
 }
 
+static void SetVideoMode(screen_mode_t *mode, int w, int h)
+{
+    byte *doompal;
+    int flags = 0;
+
+    doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
+
+    // Generate lookup tables before setting the video mode.
+
+    if (mode != NULL && mode->InitMode != NULL)
+    {
+        mode->InitMode(doompal);
+    }
+
+    // Set the video mode.
+
+    flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+
+    if (fullscreen)
+    {
+        flags |= SDL_FULLSCREEN;
+    }
+    else
+    {
+        flags |= SDL_RESIZABLE;
+    }
+
+    screen = SDL_SetVideoMode(w, h, 8, flags);
+
+    if (screen == NULL)
+    {
+        I_Error("Error setting video mode: %s\n", SDL_GetError());
+    }
+
+    // If mode was not set, it must be set now that we know the
+    // screen size.
+
+    if (mode == NULL)
+    {
+        mode = I_FindScreenMode(screen->w, screen->h);
+
+        if (mode == NULL)
+        {
+            I_Error("I_InitGraphics: Unable to find a screen mode small "
+                    "enough for %ix%i", screen->w, screen->h);
+        }
+
+        // Generate lookup tables before setting the video mode.
+
+        if (mode->InitMode != NULL)
+        {
+            mode->InitMode(doompal);
+        }
+    }
+
+    // Save screen mode.
+
+    screen_mode = mode;
+}
+
+static void ApplyWindowResize(unsigned int w, unsigned int h)
+{
+    screen_mode_t *mode;
+
+    // Find the biggest screen mode that will fall within these
+    // dimensions, falling back to the smallest mode possible if
+    // none is found.
+
+    mode = I_FindScreenMode(w, h);
+
+    if (mode == NULL)
+    {
+        mode = I_FindScreenMode(SCREENWIDTH, SCREENHEIGHT);
+    }
+
+    // Reset mode to resize window.
+
+    printf("Resize to %ix%i\n", mode->width, mode->height);
+    SetVideoMode(mode, mode->width, mode->height);
+
+    // Save settings.
+
+    screen_width = mode->width;
+    screen_height = mode->height;
+}
+
 void I_InitGraphics(void)
 {
     SDL_Event dummy;
     byte *doompal;
-    int flags = 0;
     char *env;
 
     // Pass through the XSCREENSAVER_WINDOW environment variable to 
@@ -1527,72 +1631,55 @@
 
     CheckCommandLine();
 
-    doompal = W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE);
+    // Set up title and icon.  Windows cares about the ordering; this
+    // has to be done before the call to SDL_SetVideoMode.
 
+    I_SetWindowCaption();
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+    I_SetWindowIcon();
+#endif
+
+    //
+    // Enter into graphics mode.
+    //
+    // When in screensaver mode, run full screen and auto detect
+    // screen dimensions (don't change video mode)
+    //
+
     if (screensaver_mode)
     {
-        windowwidth = 0;
-        windowheight = 0;
+        SetVideoMode(NULL, 0, 0);
     }
     else
     {
+        int w, h;
+
         if (autoadjust_video_settings)
         {
             I_AutoAdjustSettings();
         }
 
-        windowwidth = screen_width;
-        windowheight = screen_height;
+        w = screen_width;
+        h = screen_height;
 
-        screen_mode = I_FindScreenMode(windowwidth, windowheight);
+        screen_mode = I_FindScreenMode(w, h);
 
         if (screen_mode == NULL)
         {
             I_Error("I_InitGraphics: Unable to find a screen mode small "
-                    "enough for %ix%i", windowwidth, windowheight);
+                    "enough for %ix%i", w, h);
         }
 
-        if (windowwidth != screen_mode->width
-         || windowheight != screen_mode->height)
+        if (w != screen_mode->width || h != screen_mode->height)
         {
             printf("I_InitGraphics: %s (%ix%i within %ix%i)\n",
-                   WindowBoxType(screen_mode, windowwidth, windowheight),
-                   screen_mode->width, screen_mode->height,
-                   windowwidth, windowheight);
+                   WindowBoxType(screen_mode, w, h),
+                   screen_mode->width, screen_mode->height, w, h);
         }
 
-        // Generate lookup tables before setting the video mode.
-
-        if (screen_mode->InitMode != NULL)
-        {
-            screen_mode->InitMode(doompal);
-        }
+        SetVideoMode(screen_mode, w, h);
     }
 
-    // Set up title and icon.  Windows cares about the ordering; this
-    // has to be done before the call to SDL_SetVideoMode.
-
-    I_SetWindowCaption();
-#if !SDL_VERSION_ATLEAST(1, 3, 0)
-    I_SetWindowIcon();
-#endif
-
-    // Set the video mode.
-
-    flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
-
-    if (fullscreen)
-    {
-        flags |= SDL_FULLSCREEN;
-    }
-
-    screen = SDL_SetVideoMode(windowwidth, windowheight, 8, flags);
-
-    if (screen == NULL)
-    {
-        I_Error("Error setting video mode: %s\n", SDL_GetError());
-    }
-
     // Start with a clear black screen
     // (screen will be flipped after we set the palette)
 
@@ -1611,6 +1698,7 @@
 
     // Set the palette
 
+    doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
     I_SetPalette(doompal);
     SDL_SetColors(screen, palette, 0, 256);
 
@@ -1619,26 +1707,6 @@
     UpdateFocus();
     UpdateGrab();
 
-    // In screensaver mode, now find a screen_mode to use.
-
-    if (screensaver_mode)
-    {
-        screen_mode = I_FindScreenMode(screen->w, screen->h);
-
-        if (screen_mode == NULL)
-        {
-            I_Error("I_InitGraphics: Unable to find a screen mode small "
-                    "enough for %ix%i", screen->w, screen->h);
-        }
-
-        // Generate lookup tables before setting the video mode.
-
-        if (screen_mode->InitMode != NULL)
-        {
-            screen_mode->InitMode(doompal);
-        }
-    }
-    
     // On some systems, it takes a second or so for the screen to settle
     // after changing modes.  We include the option to add a delay when
     // setting the screen mode, so that the game doesn't start immediately
@@ -1654,12 +1722,12 @@
     // Likewise if the screen pitch is not the same as the width
     // If we have to multiply, drawing is done to a separate 320x200 buf
 
-    native_surface = !SDL_MUSTLOCK(screen) 
+    native_surface = !SDL_MUSTLOCK(screen)
                   && screen_mode == &mode_scale_1x
                   && screen->pitch == SCREENWIDTH
                   && aspect_ratio_correct;
 
-    // If not, allocate a buffer and copy from that buffer to the 
+    // If not, allocate a buffer and copy from that buffer to the
     // screen when we do an update
 
     if (native_surface)
@@ -1670,7 +1738,7 @@
     }
     else
     {
-	screens[0] = (unsigned char *) Z_Malloc (SCREENWIDTH * SCREENHEIGHT, 
+	screens[0] = (unsigned char *) Z_Malloc (SCREENWIDTH * SCREENHEIGHT,
                                                  PU_STATIC, NULL);
     }