diff options
Diffstat (limited to 'src')
-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 |