diff options
Diffstat (limited to 'src/i_video.c')
-rw-r--r-- | src/i_video.c | 384 |
1 files changed, 252 insertions, 132 deletions
diff --git a/src/i_video.c b/src/i_video.c index 0d1b612b..568f0f7d 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -635,20 +635,23 @@ static void UpdateGrab(void) // Update a small portion of the screen // // Does stretching and buffer blitting if neccessary +// +// Return true if blit was successful. -static void BlitArea(int x1, int y1, int x2, int y2) +static boolean BlitArea(int x1, int y1, int x2, int y2) { - void (*scale_function)(int x1, int y1, int x2, int y2); int x_offset, y_offset; + boolean result; + + // No blit needed on native surface if (native_surface) { - return; + return true; } x_offset = (screen->w - screen_mode->width) / 2; y_offset = (screen->h - screen_mode->height) / 2; - scale_function = screen_mode->DrawScreen; if (SDL_LockSurface(screen) >= 0) { @@ -656,28 +659,37 @@ static void BlitArea(int x1, int y1, int x2, int y2) (byte *) screen->pixels + (y_offset * screen->pitch) + x_offset, screen->pitch); - scale_function(x1, y1, x2, y2); + result = screen_mode->DrawScreen(x1, y1, x2, y2); SDL_UnlockSurface(screen); } + else + { + result = false; + } + + return result; } static void UpdateRect(int x1, int y1, int x2, int y2) { - // Do stretching and blitting + int x1_scaled, x2_scaled, y1_scaled, y2_scaled; - BlitArea(x1, y1, x2, y2); + // Do stretching and blitting - // Update the area + if (BlitArea(x1, y1, x2, y2)) + { + // Update the area -/* - TODO: fix loading disk + x1_scaled = (x1 * screen_mode->width) / SCREENWIDTH; + y1_scaled = (y1 * screen_mode->height) / SCREENHEIGHT; + x2_scaled = (x2 * screen_mode->width) / SCREENWIDTH; + y2_scaled = (y2 * screen_mode->height) / SCREENHEIGHT; - SDL_UpdateRect(screen, - x1 * screenmultiply, - y1 * screenmultiply, - (x2-x1) * screenmultiply, - (y2-y1) * screenmultiply); -*/ + SDL_UpdateRect(screen, + x1_scaled, y1_scaled, + x2_scaled - x1_scaled, + y2_scaled - y1_scaled); + } } void I_BeginRead(void) @@ -852,92 +864,6 @@ void I_SetWindowIcon(void) SDL_FreeSurface(surface); } -static void CheckCommandLine(void) -{ - int i; - - //! - // @category video - // - // Grab the mouse when running in windowed mode. - // - - if (M_CheckParm("-grabmouse")) - { - grabmouse = true; - } - - //! - // @category video - // - // Don't grab the mouse when running in windowed mode. - // - - if (M_CheckParm("-nograbmouse")) - { - grabmouse = false; - } - - // default to fullscreen mode, allow override with command line - // nofullscreen because we love prboom - - //! - // @category video - // - // Run in a window. - // - - if (M_CheckParm("-window") || M_CheckParm("-nofullscreen")) - { - fullscreen = false; - } - - //! - // @category video - // - // Run in fullscreen mode. - // - - if (M_CheckParm("-fullscreen")) - { - fullscreen = true; - } - - //! - // @category video - // - // Disable the mouse. - // - - nomouse = M_CheckParm("-nomouse") > 0; - - //! - // @category video - // - // Specify the screen width, in pixels. - // - - i = M_CheckParm("-width"); - - if (i > 0) - { - screen_width = atoi(myargv[i + 1]); - } - - //! - // @category video - // - // Specify the screen height, in pixels. - // - - i = M_CheckParm("-height"); - - if (i > 0) - { - screen_height = atoi(myargv[i + 1]); - } -} - // Pick the modes list to use: static void GetScreenModes(screen_mode_t ***modes_list, int *num_modes) @@ -969,13 +895,16 @@ static screen_mode_t *I_FindScreenMode(int w, int h) // ratio correction is turned on. These modes have non-square // pixels. - if (w == SCREENWIDTH && h == SCREENHEIGHT) - { - return &mode_scale_1x; - } - else if (w == SCREENWIDTH*2 && h == SCREENHEIGHT*2) + if (fullscreen) { - return &mode_scale_2x; + if (w == SCREENWIDTH && h == SCREENHEIGHT) + { + return &mode_scale_1x; + } + else if (w == SCREENWIDTH*2 && h == SCREENHEIGHT*2) + { + return &mode_scale_2x; + } } GetScreenModes(&modes_list, &modes_list_length); @@ -1019,7 +948,7 @@ static void I_AutoAdjustSettings(void) SDL_Rect **modes; SDL_Rect *best_mode; screen_mode_t *screen_mode; - int num_pixels, best_num_pixels; + int target_pixels, num_pixels, best_num_pixels; int i; modes = SDL_ListModes(NULL, SDL_FULLSCREEN); @@ -1029,6 +958,7 @@ static void I_AutoAdjustSettings(void) best_mode = NULL; best_num_pixels = INT_MAX; + target_pixels = screen_width * screen_height; for (i=0; modes[i] != NULL; ++i) { @@ -1056,19 +986,12 @@ static void I_AutoAdjustSettings(void) return; } - // Only use modes bigger than the specified mode - - if (modes[i]->w < screen_width || modes[i]->h < screen_height) - { - // printf("\t< %ix%i\n", screen_width, screen_height); - continue; - } - // Is this mode better than the current mode? num_pixels = modes[i]->w * modes[i]->h; - if (num_pixels < best_num_pixels) + if (abs(num_pixels - target_pixels) + < abs(best_num_pixels - target_pixels)) { // printf("\tA valid mode\n"); best_num_pixels = num_pixels; @@ -1080,20 +1003,7 @@ static void I_AutoAdjustSettings(void) { // Unable to find a valid mode! - if (screen_width <= SCREENWIDTH && screen_height <= SCREENHEIGHT) - { - I_Error("Unable to find any valid video mode at all!"); - } - - // Reset back to the original defaults and try to find a - // mode - - screen_width = SCREENWIDTH; - screen_height = SCREENHEIGHT; - - I_AutoAdjustSettings(); - - return; + I_Error("Unable to find any valid video mode at all!"); } printf("I_InitGraphics: %ix%i mode not supported on this machine.\n", @@ -1115,6 +1025,14 @@ static void I_AutoAdjustSettings(void) 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); + } + // Do we have the exact mode already? if (best_mode->width == screen_width @@ -1139,6 +1057,208 @@ static void I_AutoAdjustSettings(void) "configuration file.\n"); } +// Set video size to a particular scale factor (1x, 2x, 3x, etc.) + +static void SetScaleFactor(int factor) +{ + if (fullscreen) + { + // In fullscreen, find a mode that will provide this scale factor + + SDL_Rect **modes; + SDL_Rect *best_mode; + screen_mode_t *scrmode; + int best_num_pixels, num_pixels; + int i; + + modes = SDL_ListModes(NULL, SDL_FULLSCREEN); + + best_mode = NULL; + best_num_pixels = INT_MAX; + + for (i=0; modes[i] != NULL; ++i) + { + // What screen_mode_t will this use? + + scrmode = I_FindScreenMode(modes[i]->w, modes[i]->h); + + if (scrmode == NULL) + { + continue; + } + + // Only choose modes that fit the requested scale factor. + // + // Note that this allows 320x240 as valid for 1x scale, as + // 240/200 is rounded down to 1 by integer division. + + if ((scrmode->width / SCREENWIDTH) != factor + || (scrmode->height / SCREENHEIGHT) != factor) + { + continue; + } + + // Is this a better mode than what we currently have? + + num_pixels = modes[i]->w * modes[i]->h; + + if (num_pixels < best_num_pixels) + { + best_num_pixels = num_pixels; + best_mode = modes[i]; + } + } + + if (best_mode == NULL) + { + I_Error("No fullscreen graphics mode available to support " + "%ix scale factor!", factor); + } + + screen_width = best_mode->w; + screen_height = best_mode->h; + } + else + { + int w, h; + + // Pick 320x200 or 320x240, depending on aspect ratio correct + + if (aspect_ratio_correct) + { + w = SCREENWIDTH; + h = SCREENHEIGHT_4_3; + } + else + { + w = SCREENWIDTH; + h = SCREENHEIGHT; + } + + screen_width = w * factor; + screen_height = h * factor; + } +} + +static void CheckCommandLine(void) +{ + int i; + + //! + // @category video + // + // Grab the mouse when running in windowed mode. + // + + if (M_CheckParm("-grabmouse")) + { + grabmouse = true; + } + + //! + // @category video + // + // Don't grab the mouse when running in windowed mode. + // + + if (M_CheckParm("-nograbmouse")) + { + grabmouse = false; + } + + // default to fullscreen mode, allow override with command line + // nofullscreen because we love prboom + + //! + // @category video + // + // Run in a window. + // + + if (M_CheckParm("-window") || M_CheckParm("-nofullscreen")) + { + fullscreen = false; + } + + //! + // @category video + // + // Run in fullscreen mode. + // + + if (M_CheckParm("-fullscreen")) + { + fullscreen = true; + } + + //! + // @category video + // + // Disable the mouse. + // + + nomouse = M_CheckParm("-nomouse") > 0; + + //! + // @category video + // + // Specify the screen width, in pixels. + // + + i = M_CheckParm("-width"); + + if (i > 0) + { + screen_width = atoi(myargv[i + 1]); + } + + //! + // @category video + // + // Specify the screen height, in pixels. + // + + i = M_CheckParm("-height"); + + if (i > 0) + { + screen_height = atoi(myargv[i + 1]); + } + + //! + // @category video + // + // Don't scale up the screen. + // + + if (M_CheckParm("-1")) + { + SetScaleFactor(1); + } + + //! + // @category video + // + // Double up the screen to 2x its normal size. + // + + if (M_CheckParm("-2")) + { + SetScaleFactor(2); + } + + //! + // @category video + // + // Double up the screen to 3x its normal size. + // + + if (M_CheckParm("-3")) + { + SetScaleFactor(3); + } +} + // Check if we have been invoked as a screensaver by xscreensaver. void I_CheckIsScreensaver(void) |