diff options
author | Max Horn | 2003-06-22 11:55:40 +0000 |
---|---|---|
committer | Max Horn | 2003-06-22 11:55:40 +0000 |
commit | 11ff7fe9a347efe37e2bd8fefca7e8c130f81af0 (patch) | |
tree | 037c8edce6a559e5816b7733727305ff66cc49cf /common | |
parent | fa184730af2f2be094aa9f37cd3abf58d10f79ea (diff) | |
download | scummvm-rg350-11ff7fe9a347efe37e2bd8fefca7e8c130f81af0.tar.gz scummvm-rg350-11ff7fe9a347efe37e2bd8fefca7e8c130f81af0.tar.bz2 scummvm-rg350-11ff7fe9a347efe37e2bd8fefca7e8c130f81af0.zip |
Patch #757827: Aspect-ratio correction
svn-id: r8605
Diffstat (limited to 'common')
-rw-r--r-- | common/gameDetector.cpp | 56 | ||||
-rw-r--r-- | common/gameDetector.h | 1 | ||||
-rw-r--r-- | common/scaler.cpp | 102 | ||||
-rw-r--r-- | common/scaler.h | 10 | ||||
-rw-r--r-- | common/system.h | 5 |
5 files changed, 143 insertions, 31 deletions
diff --git a/common/gameDetector.cpp b/common/gameDetector.cpp index 3cd1a742cb..a4841ed72b 100644 --- a/common/gameDetector.cpp +++ b/common/gameDetector.cpp @@ -50,38 +50,39 @@ static const char USAGE_STRING[] = "Syntax:\n" "\tscummvm [-v] [-d[<num>]] [-n] [-b<num>] [-t<num>] [-s<num>] [-p<path>] [-m<num>] [-f] game\n" "Flags:\n" - "\t-p<path> - look for game in <path>\n" - "\t-x[<num>] - load this savegame (default: 0 - autosave)\n" - "\t-f - fullscreen mode\n" - "\t-g<mode> - graphics mode (normal,2x,3x,2xsai,super2xsai,supereagle,advmame2x,advmame3x,tv2x,dotmatrix)\n" - "\t-e<mode> - set music engine (see README for details)\n" - "\t-a - specify game is amiga version\n" - "\t-q<lang> - specify language (en,de,fr,it,pt,es,jp,zh,kr,hb)\n" + "\t-p<path> - look for game in <path>\n" + "\t-x[<num>] - load this savegame (default: 0 - autosave)\n" + "\t-f - fullscreen mode\n" + "\t-g<mode> - graphics mode (normal,2x,3x,2xsai,super2xsai,supereagle,advmame2x,advmame3x,tv2x,dotmatrix)\n" + "\t-e<mode> - set music engine (see README for details)\n" + "\t-a - specify game is amiga version\n" + "\t-q<lang> - specify language (en,de,fr,it,pt,es,jp,zh,kr,hb)\n" "\n" - "\t-c<num> - use cdrom <num> for cd audio\n" - "\t-m<num> - set music volume to <num> (0-255)\n" - "\t-o<num> - set master volume to <num> (0-255)\n" - "\t-s<num> - set sfx volume to <num> (0-255)\n" - "\t-t<num> - set music tempo (50-200, default 100%%)\n" + "\t-c<num> - use cdrom <num> for cd audio\n" + "\t-m<num> - set music volume to <num> (0-255)\n" + "\t-o<num> - set master volume to <num> (0-255)\n" + "\t-s<num> - set sfx volume to <num> (0-255)\n" + "\t-t<num> - set music tempo (50-200, default 100%%)\n" "\n" - "\t-n - no subtitles for speech\n" - "\t-y - set text speed (default: 60)\n" + "\t-n - no subtitles for speech\n" + "\t-y - set text speed (default: 60)\n" "\n" - "\t-l<file> - load config file instead of default\n" + "\t-l<file> - load config file instead of default\n" #if defined(UNIX) - "\t-w[<file>] - write to config file [~/.scummvmrc]\n" + "\t-w[<file>] - write to config file [~/.scummvmrc]\n" #else - "\t-w[<file>] - write to config file [scummvm.ini]\n" + "\t-w[<file>] - write to config file [scummvm.ini]\n" #endif - "\t-v - show version info and exit\n" - "\t-z - display list of games\n" + "\t-v - show version info and exit\n" + "\t-z - display list of games\n" "\n" - "\t-b<num> - start in room <num>\n" - "\t-d[<num>] - enable debug output (debug level [1])\n" - "\t-u - dump scripts\n" + "\t-b<num> - start in room <num>\n" + "\t-d[<num>] - enable debug output (debug level [1])\n" + "\t-u - dump scripts\n" "\n" - "\t--multi-midi - enable combination Adlib and native MIDI\n" - "\t--native-mt32 - true Roland MT-32 (disable GM emulation)\n" + "\t--multi-midi - enable combination Adlib and native MIDI\n" + "\t--native-mt32 - true Roland MT-32 (disable GM emulation)\n" + "\t--aspect-ratio - enable aspect ratio correction\n" ; #endif // This contains a pointer to a list of all supported games. @@ -148,6 +149,7 @@ static int countVersions(const VersionSettings *v) { GameDetector::GameDetector() { _fullScreen = false; + _aspectRatio = false; _use_adlib = false; @@ -245,6 +247,7 @@ void GameDetector::updateconfig() { } _fullScreen = g_config->getBool("fullscreen", _fullScreen); + _aspectRatio = g_config->getBool("aspect_ratio", _aspectRatio); if ((val = g_config->get("gfx_mode"))) if ((_gfx_mode = parseGraphicsMode(val)) == -1) { @@ -453,6 +456,9 @@ void GameDetector::parseCommandLine(int argc, char **argv) { } else if (!strcmp (s, "native-mt32")) { _native_mt32 = true; g_config->setBool ("native_mt32", true); + } else if (!strcmp (s, "aspect-ratio")) { + _aspectRatio = true; + g_config->setBool ("aspect_ratio", true); } else { goto ShowHelpAndExit; } @@ -673,7 +679,7 @@ OSystem *GameDetector::createSystem() { return OSystem_PALMOS_create(_gfx_mode); #else /* SDL is the default driver for now */ - return OSystem_SDL_create(_gfx_mode, _fullScreen); + return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatio); #endif } diff --git a/common/gameDetector.h b/common/gameDetector.h index f73f20cd56..d9e5b104a5 100644 --- a/common/gameDetector.h +++ b/common/gameDetector.h @@ -110,6 +110,7 @@ public: const String& getGameName(void); bool _fullScreen; + bool _aspectRatio; bool _use_adlib; diff --git a/common/scaler.cpp b/common/scaler.cpp index 1607fef214..0d952110c1 100644 --- a/common/scaler.cpp +++ b/common/scaler.cpp @@ -30,7 +30,9 @@ static uint32 lowPixelMask = 0x08210821; static uint32 qcolorMask = 0xE79CE79C; static uint32 qlowpixelMask = 0x18631863; static uint32 redblueMask = 0xF81F; -static uint32 greenMask = 0x7E0; +static uint32 redMask = 0xF800; +static uint32 greenMask = 0x07E0; +static uint32 blueMask = 0x001F; static const uint16 dotmatrix_565[16] = { 0x01E0, 0x0007, 0x3800, 0x0000, @@ -53,7 +55,9 @@ int Init_2xSaI(uint32 BitFormat) { qcolorMask = 0xE79CE79C; qlowpixelMask = 0x18631863; redblueMask = 0xF81F; - greenMask = 0x7E0; + redMask = 0xF800; + greenMask = 0x07E0; + blueMask = 0x001F; dotmatrix = dotmatrix_565; } else if (BitFormat == 555) { colorMask = 0x7BDE7BDE; @@ -61,7 +65,9 @@ int Init_2xSaI(uint32 BitFormat) { qcolorMask = 0x739C739C; qlowpixelMask = 0x0C630C63; redblueMask = 0x7C1F; - greenMask = 0x3E0; + redMask = 0x7C00; + greenMask = 0x03E0; + blueMask = 0x001F; dotmatrix = dotmatrix_555; } else { return 0; @@ -634,3 +640,93 @@ void DotMatrix(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPi q += nextlineDst << 1; } } + + +static inline uint32 interpolate5(uint16 A, uint16 B, int scale) { + uint16 r = ((A & redMask) * scale + (B & redMask) * (5 - scale)) / 5; + uint16 g = ((A & greenMask) * scale + (B & greenMask) * (5 - scale)) / 5; + uint16 b = ((A & blueMask) * scale + (B & blueMask) * (5 - scale)) / 5; + + return (r & redMask) | (g & greenMask) | (b & blueMask); +} + +static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) { +#if 1 + // Accurate but slightly slower code + while (width--) { + *dst++ = interpolate5(*srcA++, *srcB++, scale); + } +#else + // Not fully accurate, but a bit faster + width /= 2; + const uint32 *sA = (const uint32 *)srcA; + const uint32 *sB = (const uint32 *)srcB; + uint32 *d = (uint32 *)dst; + if (scale == 1) { + while (width--) { + uint32 B = *sB++; + *d++ = Q_INTERPOLATE(*sA++, B, B, B); + } + } else { + while (width--) { + *d++ = INTERPOLATE(*sA++, *sB++); + } + } +#endif +} + +/** + * Stretch a 16bpp image vertically by factor 1.2. Used to correct the + * aspect-ratio in games using 320x200 pixel graphics with non-qudratic + * pixels. Applying this method effectively turns that into 320x240, which + * provides the correct aspect-ratio on modern displays. + * + * The image would normally have occupied y coordinates origSrcY through + * origSrcY + height - 1. + * + * However, we have already placed it at srcY - the aspect-corrected y + * coordinate - to allow in-place stretching. + * + * Therefore, the source image now occupies Y coordinates srcY through + * srcY + height - 1, and it should be stretched to Y coordinates srcY + * through real2Aspect(srcY + height - 1). + */ +int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { + int maxDstY = real2Aspect(origSrcY + height - 1); + int off = srcY - origSrcY; + int y; + + uint8 *dstPtr = buf + srcX * 2 + maxDstY * pitch; + + for (y = maxDstY; y >= srcY; y--) { + uint8 *srcPtr = buf + srcX * 2 + (aspect2Real(y) + off) * pitch; + + if (srcPtr == dstPtr) + break; + +#if 0 + // Don't use bilinear filtering, rather just duplicate pixel lines: + // a little bit faster, but looks ugly + memcpy(dstPtr, srcPtr, width * 2); +#else + // Bilinear filter + switch (y % 6) { + case 0: + case 5: + memcpy(dstPtr, srcPtr, width * 2); + break; + case 1: + case 4: + interpolate5Line((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 1, width); + break; + case 2: + case 3: + interpolate5Line((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 2, width); + break; + } +#endif + dstPtr -= pitch; + } + + return 1 + maxDstY - srcY; +} diff --git a/common/scaler.h b/common/scaler.h index e3246587c9..b8000ddccd 100644 --- a/common/scaler.h +++ b/common/scaler.h @@ -41,6 +41,15 @@ DECLARE_SCALER(Normal3x); DECLARE_SCALER(TV2x); DECLARE_SCALER(DotMatrix); +FORCEINLINE int real2Aspect(int y) { + return y + (y + 1) / 5; +} + +FORCEINLINE int aspect2Real(int y) { + return (y * 5 + 3) / 6; +} + +extern int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY); enum { GFX_NORMAL = 0, @@ -54,7 +63,6 @@ enum { GFX_TV2X = 8, GFX_DOTMATRIX = 9, - GFX_ASPECTRATIO = 11, // OpenGL backend GFX_BILINEAR = 12, // OpenGL backend GFX_FLIPPING = 100, // Palmos diff --git a/common/system.h b/common/system.h index 68408a6a13..32e55e4879 100644 --- a/common/system.h +++ b/common/system.h @@ -94,7 +94,8 @@ public: PROP_GET_SAMPLE_RATE = 6, PROP_GET_FULLSCREEN = 7, PROP_GET_FMOPL_ENV_BITS = 8, - PROP_GET_FMOPL_EG_ENT = 9 + PROP_GET_FMOPL_EG_ENT = 9, + PROP_TOGGLE_ASPECT_RATIO = 10 }; union Property { const char *caption; @@ -363,7 +364,7 @@ public: /* Factory functions. This means we don't have to include the headers for * all backends. */ -extern OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen); +extern OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen, bool aspect_ratio); extern OSystem *OSystem_NULL_create(); extern OSystem *OSystem_MorphOS_create(int game_id, int gfx_driver, bool full_screen); extern OSystem *OSystem_Dreamcast_create(); |