diff options
author | Simon Howard | 2008-01-20 16:18:16 +0000 |
---|---|---|
committer | Simon Howard | 2008-01-20 16:18:16 +0000 |
commit | 63624d71c11fe8292466a5c06e6cc71a48bf98bc (patch) | |
tree | bfd070b6af15f0cbfd7263d018c34ca6f5b95d36 | |
parent | e29c27e31acb04e67a715b9a2722c09b9574d374 (diff) | |
download | chocolate-doom-63624d71c11fe8292466a5c06e6cc71a48bf98bc.tar.gz chocolate-doom-63624d71c11fe8292466a5c06e6cc71a48bf98bc.tar.bz2 chocolate-doom-63624d71c11fe8292466a5c06e6cc71a48bf98bc.zip |
Fix loading disk icon. Add back -1, -2, -3 command line options for
scale. Only allow 320x200, 640x400 special case for aspect ratio correct
when running fullscreen. Clean up "nearest mode" autoadjustment. Fix
crash with autoadjust when running windowed.
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1007
-rw-r--r-- | src/i_scale.c | 80 | ||||
-rw-r--r-- | src/i_video.c | 384 | ||||
-rw-r--r-- | src/i_video.h | 3 |
3 files changed, 309 insertions, 158 deletions
diff --git a/src/i_scale.c b/src/i_scale.c index e320e1cb..a42409e8 100644 --- a/src/i_scale.c +++ b/src/i_scale.c @@ -72,7 +72,7 @@ void I_InitScale(byte *_src_buffer, byte *_dest_buffer, int _dest_pitch) // 1x scale doesn't really do any scaling: it just copies the buffer // a line at a time for when pitch != SCREENWIDTH (!native_surface) -static void I_Scale1x(int x1, int y1, int x2, int y2) +static boolean I_Scale1x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -89,6 +89,8 @@ static void I_Scale1x(int x1, int y1, int x2, int y2) screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_scale_1x = { @@ -99,7 +101,7 @@ screen_mode_t mode_scale_1x = { // 2x scale (640x400) -static void I_Scale2x(int x1, int y1, int x2, int y2) +static boolean I_Scale2x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp, *screenp2; int x, y; @@ -127,6 +129,8 @@ static void I_Scale2x(int x1, int y1, int x2, int y2) screenp2 += multi_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_scale_2x = { @@ -137,7 +141,7 @@ screen_mode_t mode_scale_2x = { // 3x scale (960x600) -static void I_Scale3x(int x1, int y1, int x2, int y2) +static boolean I_Scale3x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp, *screenp2, *screenp3; int x, y; @@ -169,6 +173,8 @@ static void I_Scale3x(int x1, int y1, int x2, int y2) screenp3 += multi_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_scale_3x = { @@ -179,7 +185,7 @@ screen_mode_t mode_scale_3x = { // 4x scale (1280x800) -static void I_Scale4x(int x1, int y1, int x2, int y2) +static boolean I_Scale4x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp, *screenp2, *screenp3, *screenp4; int x, y; @@ -215,6 +221,8 @@ static void I_Scale4x(int x1, int y1, int x2, int y2) screenp4 += multi_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_scale_4x = { @@ -225,7 +233,7 @@ screen_mode_t mode_scale_4x = { // 5x scale (1600x1000) -static void I_Scale5x(int x1, int y1, int x2, int y2) +static boolean I_Scale5x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp, *screenp2, *screenp3, *screenp4, *screenp5; int x, y; @@ -265,6 +273,8 @@ static void I_Scale5x(int x1, int y1, int x2, int y2) screenp5 += multi_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_scale_5x = { @@ -396,7 +406,7 @@ static inline void WriteBlendedLine1x(byte *dest, byte *src1, byte *src2, // 1x stretch (320x240) -static void I_Stretch1x(int x1, int y1, int x2, int y2) +static boolean I_Stretch1x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -405,7 +415,7 @@ static void I_Stretch1x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } // Need to byte-copy from buffer into the screen buffer @@ -442,6 +452,8 @@ static void I_Stretch1x(int x1, int y1, int x2, int y2) memcpy(screenp, bufp, SCREENWIDTH); screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_stretch_1x = { @@ -483,7 +495,7 @@ static inline void WriteBlendedLine2x(byte *dest, byte *src1, byte *src2, // 2x stretch (640x480) -static void I_Stretch2x(int x1, int y1, int x2, int y2) +static boolean I_Stretch2x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -492,7 +504,7 @@ static void I_Stretch2x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } // Need to byte-copy from buffer into the screen buffer @@ -553,6 +565,8 @@ static void I_Stretch2x(int x1, int y1, int x2, int y2) WriteLine2x(screenp, bufp); screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_stretch_2x = { @@ -595,7 +609,7 @@ static inline void WriteBlendedLine3x(byte *dest, byte *src1, byte *src2, // 3x stretch (960x720) -static void I_Stretch3x(int x1, int y1, int x2, int y2) +static boolean I_Stretch3x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -604,7 +618,7 @@ static void I_Stretch3x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } // Need to byte-copy from buffer into the screen buffer @@ -689,6 +703,8 @@ static void I_Stretch3x(int x1, int y1, int x2, int y2) WriteLine3x(screenp, bufp); screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_stretch_3x = { @@ -733,7 +749,7 @@ static inline void WriteBlendedLine4x(byte *dest, byte *src1, byte *src2, // 4x stretch (1280x960) -static void I_Stretch4x(int x1, int y1, int x2, int y2) +static boolean I_Stretch4x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -742,7 +758,7 @@ static void I_Stretch4x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } // Need to byte-copy from buffer into the screen buffer @@ -851,6 +867,8 @@ static void I_Stretch4x(int x1, int y1, int x2, int y2) WriteLine4x(screenp, bufp); screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_stretch_4x = { @@ -877,7 +895,7 @@ static inline void WriteLine5x(byte *dest, byte *src) // 5x stretch (1600x1200) -static void I_Stretch5x(int x1, int y1, int x2, int y2) +static boolean I_Stretch5x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -886,7 +904,7 @@ static void I_Stretch5x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } // Need to byte-copy from buffer into the screen buffer @@ -923,6 +941,8 @@ static void I_Stretch5x(int x1, int y1, int x2, int y2) WriteLine5x(screenp, bufp); screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_stretch_5x = { @@ -978,7 +998,7 @@ static inline void WriteSquashedLine1x(byte *dest, byte *src) // 1x squashed (256x200) -static void I_Squash1x(int x1, int y1, int x2, int y2) +static boolean I_Squash1x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -987,7 +1007,7 @@ static void I_Squash1x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } bufp = src_buffer; @@ -1000,6 +1020,8 @@ static void I_Squash1x(int x1, int y1, int x2, int y2) screenp += dest_pitch; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_squash_1x = { @@ -1075,7 +1097,7 @@ static inline void WriteSquashedLine2x(byte *dest, byte *src) // 2x squash (512x400) -static void I_Squash2x(int x1, int y1, int x2, int y2) +static boolean I_Squash2x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -1084,7 +1106,7 @@ static void I_Squash2x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } bufp = src_buffer; @@ -1097,6 +1119,8 @@ static void I_Squash2x(int x1, int y1, int x2, int y2) screenp += dest_pitch * 2; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_squash_2x = { @@ -1155,7 +1179,7 @@ static inline void WriteSquashedLine3x(byte *dest, byte *src) // exactly. // -static void I_Squash3x(int x1, int y1, int x2, int y2) +static boolean I_Squash3x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -1164,7 +1188,7 @@ static void I_Squash3x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } bufp = src_buffer; @@ -1177,6 +1201,8 @@ static void I_Squash3x(int x1, int y1, int x2, int y2) screenp += dest_pitch * 3; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_squash_3x = { @@ -1263,7 +1289,7 @@ static inline void WriteSquashedLine4x(byte *dest, byte *src) // 4x squashed (1024x800) // -static void I_Squash4x(int x1, int y1, int x2, int y2) +static boolean I_Squash4x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -1272,7 +1298,7 @@ static void I_Squash4x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } bufp = src_buffer; @@ -1285,6 +1311,8 @@ static void I_Squash4x(int x1, int y1, int x2, int y2) screenp += dest_pitch * 4; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_squash_4x = { @@ -1325,7 +1353,7 @@ static inline void WriteSquashedLine5x(byte *dest, byte *src) // 5x squashed (1280x1000) // -static void I_Squash5x(int x1, int y1, int x2, int y2) +static boolean I_Squash5x(int x1, int y1, int x2, int y2) { byte *bufp, *screenp; int y; @@ -1334,7 +1362,7 @@ static void I_Squash5x(int x1, int y1, int x2, int y2) if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT) { - return; + return false; } bufp = src_buffer; @@ -1347,6 +1375,8 @@ static void I_Squash5x(int x1, int y1, int x2, int y2) screenp += dest_pitch * 5; bufp += SCREENWIDTH; } + + return true; } screen_mode_t mode_squash_5x = { 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) diff --git a/src/i_video.h b/src/i_video.h index 99107433..bd5de24a 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -46,8 +46,9 @@ typedef struct void (*InitMode)(byte *palette); // Function to call to draw the screen from the source buffer. + // Return true if draw was successful. - void (*DrawScreen)(int x1, int y1, int x2, int y2); + boolean (*DrawScreen)(int x1, int y1, int x2, int y2); // If true, this is a "poor quality" mode. The autoadjust // code should always attempt to use a different mode to this |