From ca2f82e40fbb5187961f806b421e6216ad19c259 Mon Sep 17 00:00:00 2001 From: gewlitys Date: Sun, 29 Jul 2007 19:18:14 +0000 Subject: [PATCH] Added --keepaspectratio option to keep correct aspect ratio with custom resolutions git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2825 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 2 + sc2/doc/users/manual.txt | 4 ++ sc2/src/options.c | 1 + sc2/src/options.h | 1 + sc2/src/sc2code/libs/graphics/sdl/opengl.c | 79 ++++++++++++++++++---- sc2/src/starcon2.c | 14 +++- 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 0dca6d210..23be6eaaf 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,6 @@ Changes towards version 0.7: +- Added --keepaspectratio to keep correct aspect ratio when using + custom resolutions in OpenGL mode - Mika - Add /var/tmp as possible location for temporary files. Don't try /tmp and /var/tmp at all on MS Windows (Cygwin excepted) - SvdB - Added fullscreen/windowed toggle key F11 - Mika diff --git a/sc2/doc/users/manual.txt b/sc2/doc/users/manual.txt index 08d470813..80e57a4e3 100644 --- a/sc2/doc/users/manual.txt +++ b/sc2/doc/users/manual.txt @@ -74,6 +74,10 @@ poor or no 3D acceleration, and is often faster, especially on older or less well supported cards. Only the 320x240 and 640x480 resolutions are available when not using OpenGL. + -k (or --keepaspectratio) + +Keep 4:3 aspect ratio when using custom resolutions. + -c (or --scale=mode) Graphics scaling mode (bilinear, biadapt, biadv, triscan, hq or none). diff --git a/sc2/src/options.c b/sc2/src/options.c index ecfb11b28..3435c1eff 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -48,6 +48,7 @@ int optMeleeScale; BOOLEAN optSubtitles; BOOLEAN optStereoSFX; +BOOLEAN optKeepAspectRatio; uio_DirHandle *contentDir; uio_DirHandle *configDir; uio_DirHandle *saveDir; diff --git a/sc2/src/options.h b/sc2/src/options.h index 117b98393..a17e26468 100644 --- a/sc2/src/options.h +++ b/sc2/src/options.h @@ -41,6 +41,7 @@ extern int optMeleeScale; extern BOOLEAN optSubtitles; extern BOOLEAN optStereoSFX; +extern BOOLEAN optKeepAspectRatio; extern uio_DirHandle *contentDir; extern uio_DirHandle *configDir; diff --git a/sc2/src/sc2code/libs/graphics/sdl/opengl.c b/sc2/src/sc2code/libs/graphics/sdl/opengl.c index ae8b6b470..cf0e6bc1d 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/opengl.c +++ b/sc2/src/sc2code/libs/graphics/sdl/opengl.c @@ -21,6 +21,7 @@ #include "libs/graphics/sdl/opengl.h" #include "bbox.h" #include "scalers.h" +#include "options.h" #include "libs/log.h" typedef struct _gl_screeninfo { @@ -337,28 +338,77 @@ TFB_GL_ScanLines (void) static void TFB_GL_DrawQuad (SDL_Rect *r) { + BOOLEAN keep_aspect_ratio = optKeepAspectRatio; + int x1 = 0, y1 = 0, x2 = ScreenWidthActual, y2 = ScreenHeightActual; + int sx, sy, sw, sh; + float sx_multiplier, sy_multiplier; + + if (keep_aspect_ratio) + { + float threshold = 0.75f; + float ratio = ScreenHeightActual / (float)ScreenWidthActual; + + if (ratio > threshold) + { + // screen is narrower than 4:3 + int height = (int)(ScreenWidthActual * threshold); + y1 = (ScreenHeightActual - height) / 2; + y2 = ScreenHeightActual - y1; + + if (r != NULL) + { + sx_multiplier = ScreenWidthActual / (float)ScreenWidth; + sy_multiplier = height / (float)ScreenHeight; + sx = (int)(r->x * sx_multiplier); + sy = (int)(((ScreenHeight - (r->y + r->h)) * sy_multiplier) + y1); + } + } + else if (ratio < threshold) + { + // screen is wider than 4:3 + int width = (int)(ScreenHeightActual / threshold); + x1 = (ScreenWidthActual - width) / 2; + x2 = ScreenWidthActual - x1; + + if (r != NULL) + { + sx_multiplier = width / (float)ScreenWidth; + sy_multiplier = ScreenHeightActual / (float)ScreenHeight; + sx = (int)((r->x * sx_multiplier) + x1); + sy = (int)((ScreenHeight - (r->y + r->h)) * sy_multiplier); + } + } + else + { + // screen is 4:3 + keep_aspect_ratio = 0; + } + } + if (r != NULL) { - float scale_x = (ScreenWidthActual / (float)ScreenWidth); - float scale_y = (ScreenHeightActual / (float)ScreenHeight); - - glScissor ( - (GLint) (r->x * scale_x), - (GLint) ((ScreenHeight - (r->y + r->h)) * scale_y), - (GLsizei) (r->w * scale_x), - (GLsizei) (r->h * scale_y) - ); + if (!keep_aspect_ratio) + { + sx_multiplier = ScreenWidthActual / (float)ScreenWidth; + sy_multiplier = ScreenHeightActual / (float)ScreenHeight; + sx = (int)(r->x * sx_multiplier); + sy = (int)((ScreenHeight - (r->y + r->h)) * sy_multiplier); + } + sw = (int)(r->w * sx_multiplier); + sh = (int)(r->h * sy_multiplier); + glScissor (sx, sy, sw, sh); glEnable (GL_SCISSOR_TEST); } + glBegin (GL_TRIANGLE_FAN); glTexCoord2f (0, 0); - glVertex2i (0, 0); + glVertex2i (x1, y1); glTexCoord2f (ScreenWidth / 512.0f, 0); - glVertex2i (ScreenWidthActual, 0); + glVertex2i (x2, y1); glTexCoord2f (ScreenWidth / 512.0f, ScreenHeight / 256.0f); - glVertex2i (ScreenWidthActual, ScreenHeightActual); + glVertex2i (x2, y2); glTexCoord2f (0, ScreenHeight / 256.0f); - glVertex2i (0, ScreenHeightActual); + glVertex2i (x1, y2); glEnd (); if (r != NULL) { @@ -374,6 +424,9 @@ TFB_GL_Preprocess (int force_full_redraw, int transition_amount, int fade_amount glOrtho (0,ScreenWidthActual,ScreenHeightActual, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); + if (optKeepAspectRatio) + glClear (GL_COLOR_BUFFER_BIT); + (void) transition_amount; (void) fade_amount; diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index 8b2a53003..54be30334 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -67,6 +67,7 @@ struct options_struct { int soundFlags; int width; int height; + BOOLEAN keepAspectRatio; const char *configDir; const char *contentDir; const char **addons; @@ -115,6 +116,7 @@ main (int argc, char *argv[]) /* .soundFlags = */ audio_QUALITY_MEDIUM, /* .width = */ 640, /* .height = */ 480, + /* .keepAspectRatio = */ FALSE, /* .configDir = */ NULL, /* .contentDir = */ NULL, /* .addons = */ NULL, @@ -207,6 +209,10 @@ main (int argc, char *argv[]) { options.height = res_GetInteger ("config.resheight"); } + if (res_HasKey("config.keepaspectratio")) + { + options.keepAspectRatio = res_GetBoolean ("config.keepaspectratio"); + } if (res_HasKey ("config.alwaysgl")) { if (res_GetBoolean ("config.alwaysgl")) @@ -408,6 +414,7 @@ main (int argc, char *argv[]) optWhichShield = options.whichShield; optSmoothScroll = options.smoothScroll; optMeleeScale = options.meleeScale; + optKeepAspectRatio = options.keepAspectRatio; optSubtitles = options.subTitles; optStereoSFX = options.stereoSFX; musicVolumeScale = options.musicVolumeScale; @@ -488,7 +495,7 @@ enum #endif }; -static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:i:vwx"; +static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:i:vwxk"; static struct option longOptions[] = { {"res", 1, NULL, 'r'}, @@ -513,6 +520,7 @@ static struct option longOptions[] = {"version", 0, NULL, 'v'}, {"windowed", 0, NULL, 'w'}, {"nogl", 0, NULL, 'x'}, + {"keepaspectratio", 0, NULL, 'k'}, // options with no short equivalent: {"cscan", 1, NULL, CSCAN_OPT}, @@ -625,6 +633,9 @@ parseOptions (int argc, char *argv[], struct options_struct *options) case 'x': options->gfxDriver = TFB_GFXDRIVER_SDL_PURE; break; + case 'k': + options->keepAspectRatio = TRUE; + break; case 'c': // make sure whatever was set by saved config is cleared options->gfxFlags &= ~TFB_GFXFLAGS_SCALE_ANY; @@ -972,6 +983,7 @@ usage (FILE *out, const struct options_struct *defaultOptions) log_add (log_User, " -w, --windowed (default on)"); log_add (log_User, " -o, --opengl (default off)"); log_add (log_User, " -x, --nogl (default on)"); + log_add (log_User, " -k, --keepaspectratio (default off)"); log_add (log_User, " -c, --scale=MODE (bilinear, biadapt, biadv, triscan, " "hq or none (default) )"); log_add (log_User, " -b, --meleezoom=MODE (step, aka pc, or smooth, aka 3do; "