From 265c0de3419b5123052a10cef276e1221cd0630c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 15 Dec 2006 19:35:46 +0000 Subject: Split off scaling code into i_scale.c. Add aspect ratio correction stretching (fullscreen 320x240, 640x480, etc)! Subversion-branch: /trunk/chocolate-doom Subversion-revision: 771 --- src/Makefile.am | 1 + src/i_scale.c | 404 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/i_scale.h | 43 ++++++ src/i_video.c | 269 +++++++++++++++---------------------- src/i_video.h | 1 + src/m_misc.c | 1 + 6 files changed, 558 insertions(+), 161 deletions(-) create mode 100644 src/i_scale.c create mode 100644 src/i_scale.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bb44f207..c27f2c35 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,7 @@ hu_lib.c hu_lib.h \ hu_stuff.c hu_stuff.h \ i_main.c \ info.c info.h \ +i_scale.c i_scale.h \ i_sound.c i_sound.h \ i_system.c i_system.h \ i_timer.c i_timer.h \ diff --git a/src/i_scale.c b/src/i_scale.c new file mode 100644 index 00000000..29bc8731 --- /dev/null +++ b/src/i_scale.c @@ -0,0 +1,404 @@ + +#include "doomdef.h" +#include "doomtype.h" + +#include "z_zone.h" + +// Should be screens[0] + +static byte *src_buffer; + +// Destination buffer, ie. screen->pixels. + +static byte *dest_buffer; + +// Pitch of destination buffer, ie. screen->pitch. + +static int dest_pitch; + +// Lookup tables used for aspect ratio correction stretching code. +// stretch_tables[0] : 20% / 80% +// stretch_tables[1] : 40% / 60% +// All other combinations can be reached from these two tables. + +static byte *stretch_tables[2]; + +void I_InitScale(byte *_src_buffer, byte *_dest_buffer, int _dest_pitch) +{ + src_buffer = _src_buffer; + dest_buffer = _dest_buffer; + dest_pitch = _dest_pitch; +} + +void I_Scale1x(int x1, int y1, int x2, int y2) +{ + byte *bufp, *screenp; + int y; + int w = x2 - x1; + + // Need to byte-copy from buffer into the screen buffer + + bufp = src_buffer + y1 * SCREENWIDTH + x1; + screenp = (byte *) dest_buffer + y1 * dest_pitch + x1; + + for (y=y1; y 240) + + for (y=0; y 480) + + for (y=0; yw / screenmultiply) - SCREENWIDTH) / 2; - y_offset = ((screen->h / screenmultiply) - SCREENHEIGHT) / 2; - - // Need to byte-copy from buffer into the screen buffer - - if (screenmultiply == 1 && !native_surface) + if (native_surface) { - byte *bufp, *screenp; - int y; - int pitch; - - if (SDL_LockSurface(screen) >= 0) - { - pitch = screen->pitch; - bufp = screens[0] + y1 * SCREENWIDTH + x1; - screenp = (byte *) screen->pixels + (y1 + y_offset) * pitch - + x1 + x_offset; - - for (y=y1; y= 0) - { - pitch = screen->pitch * 2; - bufp = screens[0] + y1 * SCREENWIDTH + x1; - screenp = (byte *) screen->pixels - + (y1 + y_offset) * pitch - + (x1 + x_offset) * 2; - screenp2 = screenp + screen->pitch; - - for (y=y1; yw - SCREENWIDTH * screenmultiply) / 2; + y_offset = (screen->h - SCREENHEIGHT * screenmultiply) / 2; } - - if (screenmultiply == 3) + else { - byte *bufp, *screenp, *screenp2, *screenp3; - int x, y; - int pitch; + x_offset = 0; + y_offset = 0; + } - if (SDL_LockSurface(screen) >= 0) + if (aspect_ratio_correct == RATIO_CORRECT_STRETCH) + { + if (screenmultiply == 1) { - pitch = screen->pitch * 3; - bufp = screens[0] + y1 * SCREENWIDTH + x1; - screenp = (byte *) screen->pixels - + (y1 + y_offset) * pitch - + (x1 + x_offset) * 3; - screenp2 = screenp + screen->pitch; - screenp3 = screenp2 + screen->pitch; - - for (y=y1; y= 0) { - byte *bufp, *screenp, *screenp2, *screenp3, *screenp4; - int x, y; - int pitch; - - if (SDL_LockSurface(screen) >= 0) - { - pitch = screen->pitch * 4; - bufp = screens[0] + y1 * SCREENWIDTH + x1; - screenp = (byte *) screen->pixels - + (y1 + y_offset) * pitch - + (x1 + x_offset) * 4; - screenp2 = screenp + screen->pitch; - screenp3 = screenp2 + screen->pitch; - screenp4 = screenp3 + screen->pitch; - - for (y=y1; ypixels + (y_offset * screen->pitch) + + x_offset, + screen->pitch); + scale_function(x1, y1, x2, y2); + SDL_UnlockSurface(screen); } } @@ -902,10 +825,10 @@ static void GetWindowDimensions(int *windowwidth, int *windowheight) { *windowwidth = SCREENWIDTH * screenmultiply; - if (fullscreen == FULLSCREEN_LETTERBOX) - *windowheight = LETTERBOX_SCREENHEIGHT * screenmultiply; - else + if (aspect_ratio_correct == RATIO_CORRECT_NONE) *windowheight = SCREENHEIGHT * screenmultiply; + else + *windowheight = SCREENHEIGHT_4_3 * screenmultiply; } // Check if the screen mode for the current settings is in the list available @@ -988,27 +911,28 @@ static void CheckCommandLine(void) static void AutoAdjustSettings(void) { int oldw, oldh; - int old_fullscreen, old_screenmultiply; + int old_ratio, old_screenmultiply; GetWindowDimensions(&oldw, &oldh); old_screenmultiply = screenmultiply; - old_fullscreen = fullscreen; + old_ratio = aspect_ratio_correct; if (!CheckValidFSMode() && screenmultiply == 1 - && fullscreen == FULLSCREEN_ON) + && fullscreen == FULLSCREEN_ON + && aspect_ratio_correct == RATIO_CORRECT_NONE) { // 320x200 is not valid. // Try turning on letterbox mode - avoid doubling up // the screen if possible - fullscreen = FULLSCREEN_LETTERBOX; + aspect_ratio_correct = RATIO_CORRECT_LETTERBOX; if (!CheckValidFSMode()) { // That doesn't work. Change it back. - fullscreen = FULLSCREEN_ON; + aspect_ratio_correct = RATIO_CORRECT_NONE; } } @@ -1019,14 +943,16 @@ static void AutoAdjustSettings(void) screenmultiply = 2; } - if (!CheckValidFSMode() && fullscreen == FULLSCREEN_ON) + if (!CheckValidFSMode() + && fullscreen == FULLSCREEN_ON + && aspect_ratio_correct == RATIO_CORRECT_NONE) { // This is not a valid mode. Try turning on letterbox mode - fullscreen = FULLSCREEN_LETTERBOX; + aspect_ratio_correct = RATIO_CORRECT_LETTERBOX; } - if (old_fullscreen != fullscreen + if (old_ratio != aspect_ratio_correct || old_screenmultiply != screenmultiply) { printf("I_InitGraphics: %ix%i resolution is not supported " @@ -1034,8 +960,8 @@ static void AutoAdjustSettings(void) printf("I_InitGraphics: Video settings adjusted to " "compensate:\n"); - if (fullscreen != old_fullscreen) - printf("\tletterbox mode on (fullscreen=2)\n"); + if (old_ratio != aspect_ratio_correct) + printf("\tletterbox mode on (aspect_ratio_correct=2)\n"); if (screenmultiply != old_screenmultiply) printf("\tscreenmultiply=%i\n", screenmultiply); @@ -1102,6 +1028,7 @@ static void SetBlankCursor(void) void I_InitGraphics(void) { SDL_Event dummy; + byte *doompal; int flags = 0; char *env; @@ -1155,6 +1082,13 @@ void I_InitGraphics(void) CheckCommandLine(); + // Don't allow letterbox mode when windowed + + if (!fullscreen && aspect_ratio_correct == RATIO_CORRECT_LETTERBOX) + { + aspect_ratio_correct = RATIO_CORRECT_NONE; + } + if (fullscreen && autoadjust_video_settings) { // Check that the fullscreen mode we are trying to use is valid; @@ -1163,6 +1097,17 @@ void I_InitGraphics(void) AutoAdjustSettings(); } + // Generate lookup tables before setting the video mode. + + doompal = W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE); + + if (aspect_ratio_correct == RATIO_CORRECT_STRETCH) + { + I_InitStretchTables(doompal); + } + + // Set the video mode. + GetWindowDimensions(&windowwidth, &windowheight); flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; @@ -1212,7 +1157,7 @@ void I_InitGraphics(void) // Set the palette - I_SetPalette (W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE)); + I_SetPalette(doompal); SDL_SetColors(screen, palette, 0, 256); // Setup title and icon @@ -1240,7 +1185,9 @@ void I_InitGraphics(void) native_surface = !SDL_MUSTLOCK(screen) && screenmultiply == 1 - && screen->pitch == SCREENWIDTH; + && screen->pitch == SCREENWIDTH + && (aspect_ratio_correct == RATIO_CORRECT_NONE + || aspect_ratio_correct == RATIO_CORRECT_LETTERBOX); // If not, allocate a buffer and copy from that buffer to the // screen when we do an update @@ -1249,9 +1196,9 @@ void I_InitGraphics(void) { screens[0] = (unsigned char *) (screen->pixels); - if (fullscreen == FULLSCREEN_LETTERBOX) + if (aspect_ratio_correct == RATIO_CORRECT_LETTERBOX) { - screens[0] += ((LETTERBOX_SCREENHEIGHT - SCREENHEIGHT) * screen->pitch) / 2; + screens[0] += ((SCREENHEIGHT_4_3 - SCREENHEIGHT) * screen->pitch) / 2; } } else diff --git a/src/i_video.h b/src/i_video.h index e9904fd8..e4e73041 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -64,6 +64,7 @@ extern int autoadjust_video_settings; extern boolean screenvisible; extern int screenmultiply; extern int fullscreen; +extern int aspect_ratio_correct; extern boolean grabmouse; extern float mouse_acceleration; extern int mouse_threshold; diff --git a/src/m_misc.c b/src/m_misc.c index ca67a03c..5930140c 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -348,6 +348,7 @@ static default_t extra_defaults_list[] = { {"autoadjust_video_settings", &autoadjust_video_settings, DEFAULT_INT, 0, 0}, {"fullscreen", &fullscreen, DEFAULT_INT, 0, 0}, + {"aspect_ratio_correct", &aspect_ratio_correct, DEFAULT_INT, 0, 0}, {"startup_delay", &startup_delay, DEFAULT_INT, 0, 0}, {"screenmultiply", &screenmultiply, DEFAULT_INT, 0, 0}, {"grabmouse", &grabmouse, DEFAULT_INT, 0, 0}, -- cgit v1.2.3