foxygit / doom Log in
commit 5d99eee5a4509f42d635156bfb1d6c495d8de221
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Jun 7 17:10:05 2009 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Jun 7 17:10:05 2009 +0000

    Make auto-adjust code switch to windowed mode if no fullscreen modes are
    available.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 1571
---
 src/i_video.c | 196 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 113 insertions(+), 83 deletions(-)

diff --git a/src/i_video.c b/src/i_video.c
index fa7dfff9..c3055b5d 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -964,125 +964,155 @@ static screen_mode_t *I_FindScreenMode(int w, int h)
     return best_mode;
 }

-// If the video mode set in the configuration file is not available,
-// try to choose a different mode.
+// Adjust to an appropriate fullscreen mode.
+// Returns true if successful.

-static void I_AutoAdjustSettings(void)
+static boolean AutoAdjustFullscreen(void)
 {
-    if (fullscreen)
-    {
-        SDL_Rect **modes;
-        SDL_Rect *best_mode;
-        screen_mode_t *screen_mode;
-        int target_pixels, diff, best_diff;
-        int i;
-
-        modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
-
-        // Find the best mode that matches the mode specified in the
-        // configuration file
-
-        best_mode = NULL;
-        best_diff = INT_MAX;
-        target_pixels = screen_width * screen_height;
+    SDL_Rect **modes;
+    SDL_Rect *best_mode;
+    screen_mode_t *screen_mode;
+    int target_pixels, diff, best_diff;
+    int i;

-        for (i=0; modes[i] != NULL; ++i)
-        {
-            //printf("%ix%i?\n", modes[i]->w, modes[i]->h);
+    modes = SDL_ListModes(NULL, SDL_FULLSCREEN);

-            // What screen_mode_t would be used for this video mode?
+    // No fullscreen modes available at all?

-            screen_mode = I_FindScreenMode(modes[i]->w, modes[i]->h);
+    if (modes == NULL || modes == (SDL_Rect **) -1 || *modes == NULL)
+    {
+        return false;
+    }

-            // Never choose a screen mode that we cannot run in, or
-            // is poor quality for fullscreen
+    // Find the best mode that matches the mode specified in the
+    // configuration file

-            if (screen_mode == NULL || screen_mode->poor_quality)
-            {
-            //    printf("\tUnsupported / poor quality\n");
-                continue;
-            }
+    best_mode = NULL;
+    best_diff = INT_MAX;
+    target_pixels = screen_width * screen_height;

-            // Do we have the exact mode?
-            // If so, no autoadjust needed
+    for (i=0; modes[i] != NULL; ++i)
+    {
+        //printf("%ix%i?\n", modes[i]->w, modes[i]->h);

-            if (screen_width == modes[i]->w && screen_height == modes[i]->h)
-            {
-            //    printf("\tExact mode!\n");
-                return;
-            }
+        // What screen_mode_t would be used for this video mode?

-            // Is this mode better than the current mode?
+        screen_mode = I_FindScreenMode(modes[i]->w, modes[i]->h);

-            diff = (screen_width - modes[i]->w)
-                     * (screen_width - modes[i]->w)
-                 + (screen_height - modes[i]->h)
-                     * (screen_height - modes[i]->h);
+        // Never choose a screen mode that we cannot run in, or
+        // is poor quality for fullscreen

-            if (diff < best_diff)
-            {
-            //    printf("\tA valid mode\n");
-                best_mode = modes[i];
-                best_diff = diff;
-            }
+        if (screen_mode == NULL || screen_mode->poor_quality)
+        {
+        //    printf("\tUnsupported / poor quality\n");
+            continue;
         }

-        if (best_mode == NULL)
-        {
-            // Unable to find a valid mode!
+        // Do we have the exact mode?
+        // If so, no autoadjust needed

-            I_Error("Unable to find any valid video mode at all!");
+        if (screen_width == modes[i]->w && screen_height == modes[i]->h)
+        {
+        //    printf("\tExact mode!\n");
+            return true;
         }

-        printf("I_InitGraphics: %ix%i mode not supported on this machine.\n",
-               screen_width, screen_height);
+        // Is this mode better than the current mode?

-        screen_width = best_mode->w;
-        screen_height = best_mode->h;
+        diff = (screen_width - modes[i]->w) * (screen_width - modes[i]->w)
+             + (screen_height - modes[i]->h) * (screen_height - modes[i]->h);

+        if (diff < best_diff)
+        {
+        //    printf("\tA valid mode\n");
+            best_mode = modes[i];
+            best_diff = diff;
+        }
     }
-    else
+
+    if (best_mode == NULL)
     {
-        screen_mode_t *best_mode;
+        // Unable to find a valid mode!

-        //
-        // Windowed mode.
-        //
-        // Find a screen_mode_t to fit within the current settings
-        //
+        return false;
+    }

-        best_mode = I_FindScreenMode(screen_width, screen_height);
+    printf("I_InitGraphics: %ix%i mode not supported on this machine.\n",
+           screen_width, screen_height);

-        if (best_mode == NULL)
-        {
-            // Nothing fits within the current settings.
-            // Pick the closest to 320x200 possible.
+    screen_width = best_mode->w;
+    screen_height = best_mode->h;

-            best_mode = I_FindScreenMode(SCREENWIDTH, SCREENHEIGHT_4_3);
-        }
+    return true;
+}

-        // Do we have the exact mode already?
+// Auto-adjust to a valid windowed mode.

-        if (best_mode->width == screen_width
-         && best_mode->height == screen_height)
-        {
-            return;
-        }
+static void AutoAdjustWindowed(void)
+{
+    screen_mode_t *best_mode;

+    // Find a screen_mode_t to fit within the current settings
+
+    best_mode = I_FindScreenMode(screen_width, screen_height);
+
+    if (best_mode == NULL)
+    {
+        // Nothing fits within the current settings.
+        // Pick the closest to 320x200 possible.
+
+        best_mode = I_FindScreenMode(SCREENWIDTH, SCREENHEIGHT_4_3);
+    }
+
+    // Switch to the best mode if necessary.
+
+    if (best_mode->width != screen_width || best_mode->height != screen_height)
+    {
         printf("I_InitGraphics: Cannot run at specified mode: %ix%i\n",
                screen_width, screen_height);

         screen_width = best_mode->width;
         screen_height = best_mode->height;
     }
+}

-    printf("I_InitGraphics: Auto-adjusted to %ix%i.\n",
-           screen_width, screen_height);
+// If the video mode set in the configuration file is not available,
+// try to choose a different mode.
+
+static void I_AutoAdjustSettings(void)
+{
+    int old_screen_w, old_screen_h;
+
+    old_screen_w = screen_width;
+    old_screen_h = screen_height;
+
+    // If we are running fullscreen, try to autoadjust to a valid fullscreen
+    // mode.  If this is impossible, switch to windowed.
+
+    if (fullscreen && !AutoAdjustFullscreen())
+    {
+        fullscreen = 0;
+    }

-    printf("NOTE: Your video settings have been adjusted.  "
-           "To disable this behavior,\n"
-           "set autoadjust_video_settings to 0 in your "
-           "configuration file.\n");
+    // If we are running windowed, pick a valid window size.
+
+    if (!fullscreen)
+    {
+        AutoAdjustWindowed();
+    }
+
+    // Have the settings changed?  Show a message.
+
+    if (screen_width != old_screen_w || screen_height != old_screen_h)
+    {
+        printf("I_InitGraphics: Auto-adjusted to %ix%i.\n",
+               screen_width, screen_height);
+
+        printf("NOTE: Your video settings have been adjusted.  "
+               "To disable this behavior,\n"
+               "set autoadjust_video_settings to 0 in your "
+               "configuration file.\n");
+    }
 }

 // Set video size to a particular scale factor (1x, 2x, 3x, etc.)