diff -ur ScummVM+orig/scummvm/README ScummVM+hack/scummvm/README
--- ScummVM+orig/scummvm/README	2003-06-22 17:00:33.000000000 +0200
+++ ScummVM+hack/scummvm/README	2003-06-30 16:40:14.000000000 +0200
@@ -346,6 +346,7 @@
         -x[<num>]      - Save game slot to load (default: autosave)
         -f             - Full-screen mode.
         -g<mode>       - Select graphics scaler. See below.
+        -r<mode>       - Select aspect ratio correction mode. See below.
         -e<mode>       - Select sound engine. See below.
         -a             - Enable amiga pal conversion, for playing Amiga
                          versions
@@ -367,7 +368,6 @@
                          current directory
         --multi-midi   - enable combination Adlib and native MIDI
         --native-mt32  - true Roland MT-32 (disable GM emulation)
-        --aspect-ratio - enable aspect ratio correction
 
 
 
@@ -383,12 +383,7 @@
         Ctrl-Alt 0-9           - Switch between graphics filters
         Ctrl-Alt b             - Switch beetwen bilinear and non-linear
                                  filtering [OpenGL backend]
-        Ctrl-Alt a             - Toggle aspect-ratio correction on/off.
-                                 Most of the games use a 320x200 pixel
-                                 resolution, which may look squashed on
-                                 modern monitors. Aspect-ratio correction
-                                 stretches the image to use 320x240 pixels
-                                 instead, or a multiple thereof.
+        Ctrl-Alt a             - Cycle between aspect ratio correction modes.
 
     Scumm:
         Ctrl 0-9 and Alt 0-9   - load and save game state
@@ -458,6 +453,26 @@
 
     scummvm -g advmame2x monkey2
 
+In addition ScummVM offers a few different methods for aspect ratio correction
+to stretch a 320x200 image to 320x240. This provides the correct aspect ratio
+on modern displays, and can be combined with any of the scalers listed above
+(except for opengl, which handles aspect ratio correction differently) to
+produce 640x480 or 960x720 resolutions.
+
+They are:
+        none   - No aspect ratio correction. (default)
+        sloppy - Every fifth screen line is doubled. This is fast, but will
+                 look ugly in some cases.
+        fast   - Approximated bilinear filtering. This is a little slower, but
+                 looks better than sloppy mode.
+        exact  - Exact bilinear filtering. This is much slower, but may look a
+                 little better than fast mode.
+
+To select an aspect ratio correction mode, pass its name via the '-r' option
+to scummvm, for example:
+
+    scummvm -g avdmame2x -r fast monkey2
+
 Note #1: Not all backends support all or any filters. The ones listed above
 are for the default SDL backend.
 
@@ -468,6 +483,10 @@
 Note #3: The FmTowns version of Zak (zak256 target) uses an original resolution
 of 320x240 - hence for this game scalers will scale to 640x480 or 960x720.
 
+Note #4: The Curse of Monkey Island uses an original resolution of 640x480 -
+hence for this game scalers will scale to 1280x960 or 1920x1440. However, the
+anti-aliasing filters are unlikely to improve the graphics much since they are
+already anti-aliased to begin with.
 
 Autosaves:
 ----------
diff -ur ScummVM+orig/scummvm/backends/sdl/sdl-common.cpp ScummVM+hack/scummvm/backends/sdl/sdl-common.cpp
--- ScummVM+orig/scummvm/backends/sdl/sdl-common.cpp	2003-06-22 17:00:33.000000000 +0200
+++ ScummVM+hack/scummvm/backends/sdl/sdl-common.cpp	2003-06-30 16:40:14.000000000 +0200
@@ -41,23 +41,23 @@
 #define JOY_BUT_SPACE 4
 #define JOY_BUT_F5 5
 
-OSystem *OSystem_SDL_create(int gfx_mode, bool full_screen, bool aspect_ratio) {
-	return OSystem_SDL_Common::create(gfx_mode, full_screen, aspect_ratio);
+OSystem *OSystem_SDL_create(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
+	return OSystem_SDL_Common::create(gfx_mode, full_screen, aspect_ratio_mode);
 }
 
-OSystem *OSystem_SDL_Common::create(int gfx_mode, bool full_screen, bool aspect_ratio) {
+OSystem *OSystem_SDL_Common::create(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
 	OSystem_SDL_Common *syst = OSystem_SDL_Common::create_intern();
 
-	syst->init_intern(gfx_mode, full_screen, aspect_ratio);
+	syst->init_intern(gfx_mode, full_screen, aspect_ratio_mode);
 
 	return syst;
 }
 
-void OSystem_SDL_Common::init_intern(int gfx_mode, bool full_screen, bool aspect_ratio) {
+void OSystem_SDL_Common::init_intern(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
 
 	_mode = gfx_mode;
 	_full_screen = full_screen;
-	_adjustAspectRatio = aspect_ratio;
+	_aspectRatioMode = aspect_ratio_mode;
 
 	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) ==-1) {
 		error("Could not initialize SDL: %s.\n", SDL_GetError());
@@ -132,7 +132,7 @@
 	_screenHeight = h;
 
 	if (h != 200)
-		_adjustAspectRatio = false;
+		_aspectRatioMode = ASPECT_NONE;
 
 	CKSUM_NUM = (_screenWidth * _screenHeight / (8 * 8));
 	if (_dirty_checksums)
@@ -287,7 +287,7 @@
 			h = _screenHeight - y;
 		}
 
-		if (_adjustAspectRatio)
+		if (_aspectRatioMode > ASPECT_SLOPPY)
 			makeRectStretchable(x, y, w, h);
 	
 		r->x = x;
@@ -586,7 +586,13 @@
 
 			// Ctr-Alt-a will change aspect ratio
 			if (b == (KBD_CTRL|KBD_ALT) && ev.key.keysym.sym=='a') {
-				property(PROP_TOGGLE_ASPECT_RATIO, NULL);
+				Property prop;
+
+				if (_aspectRatioMode >= ASPECT_MAX)
+					prop.aspect_ratio_mode = ASPECT_MIN;
+				else
+					prop.aspect_ratio_mode = _aspectRatioMode + 1;
+				property(PROP_SET_ASPECT_RATIO_MODE, &prop);
 				break;
 			}
 
@@ -704,7 +710,7 @@
 			event->mouse.x /= _scaleFactor;
 			event->mouse.y /= _scaleFactor;
 
-			if (_adjustAspectRatio)
+			if (_aspectRatioMode != ASPECT_NONE)
 				event->mouse.y = aspect2Real(event->mouse.y);
 			return true;
 
@@ -726,7 +732,7 @@
 			event->mouse.x /= _scaleFactor;
 			event->mouse.y /= _scaleFactor;
 
-			if (_adjustAspectRatio)
+			if (_aspectRatioMode != ASPECT_NONE)
 				event->mouse.y = aspect2Real(event->mouse.y);
 
 			return true;
@@ -743,7 +749,7 @@
 			event->mouse.x /= _scaleFactor;
 			event->mouse.y /= _scaleFactor;
 
-			if (_adjustAspectRatio)
+			if (_aspectRatioMode != ASPECT_NONE)
 				event->mouse.y = aspect2Real(event->mouse.y);
 
 			return true;
@@ -851,7 +857,7 @@
 			event->mouse.x /= _scaleFactor;
 			event->mouse.y /= _scaleFactor;
 
-			if (_adjustAspectRatio)
+			if (_aspectRatioMode != ASPECT_NONE)
 				event->mouse.y = aspect2Real(event->mouse.y);
 
 			return true;
diff -ur ScummVM+orig/scummvm/backends/sdl/sdl-common.h ScummVM+hack/scummvm/backends/sdl/sdl-common.h
--- ScummVM+orig/scummvm/backends/sdl/sdl-common.h	2003-06-22 16:27:15.000000000 +0200
+++ ScummVM+hack/scummvm/backends/sdl/sdl-common.h	2003-06-30 16:40:14.000000000 +0200
@@ -25,6 +25,7 @@
 #include "stdafx.h"
 #include "scummsys.h"
 #include "system.h"
+#include "common/scaler.h"
 
 #include <SDL.h>
 #include <SDL_thread.h>
@@ -123,7 +124,7 @@
 	virtual int16 RGBToColor(uint8 r, uint8 g, uint8 b);
 	virtual void colorToRGB(int16 color, uint8 &r, uint8 &g, uint8 &b);
 
-	static OSystem *create(int gfx_mode, bool full_screenm, bool aspect_ratio);
+	static OSystem *create(int gfx_mode, bool full_screenm, int aspect_ratio_mode);
 
 protected:
 	OSystem_SDL_Common();
@@ -131,7 +132,7 @@
 
 	static OSystem_SDL_Common *create_intern();
 
-	void init_intern(int gfx_mode, bool full_screen, bool aspect_ratio);
+	void init_intern(int gfx_mode, bool full_screen, int aspect_ratio_mode);
 
 	// unseen game screen
 	SDL_Surface *_screen;
@@ -142,7 +143,7 @@
 	int _tmpScreenWidth;
 	bool _overlayVisible;
 
-	bool _adjustAspectRatio;
+	int _aspectRatioMode;
 
 	// CD Audio
 	SDL_CD *_cdrom;
diff -ur ScummVM+orig/scummvm/backends/sdl/sdl.cpp ScummVM+hack/scummvm/backends/sdl/sdl.cpp
--- ScummVM+orig/scummvm/backends/sdl/sdl.cpp	2003-06-22 16:27:15.000000000 +0200
+++ ScummVM+hack/scummvm/backends/sdl/sdl.cpp	2003-06-30 16:40:14.000000000 +0200
@@ -16,12 +16,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v 1.37 2003/06/22 14:18:33 kirben Exp $
+ * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v 1.38 2003/06/30 14:31:09 eriktorbjorn Exp $
  *
  */
 
 #include "sdl-common.h"
-#include "common/scaler.h"
 #include "common/util.h"
 #include "common/engine.h"	// Only #included for error() and warning()
 
@@ -42,6 +41,7 @@
 	SDL_Surface *_hwscreen;    // hardware screen
 
 	ScalerProc *_scaler_proc;
+	StretcherProc *_stretcher_proc;
 
 	virtual void load_gfx_mode();
 	virtual void unload_gfx_mode();
@@ -53,7 +53,7 @@
 }
 
 OSystem_SDL::OSystem_SDL()
-	 : _hwscreen(0), _scaler_proc(0)
+	 : _hwscreen(0), _scaler_proc(0), _stretcher_proc(0)
 {
 }
 
@@ -119,23 +119,33 @@
 		break;
 
 	case GFX_TRIPLESIZE:
-		if (_full_screen) {
-			warning("full screen in useless in triplesize mode, reverting to normal mode");
-			goto normal_mode;
-		}
 		_scaleFactor = 3;
 		_scaler_proc = Normal3x;
 		break;
 
 	case GFX_NORMAL:
-normal_mode:;
 		_scaleFactor = 1;
 		_scaler_proc = Normal1x;
 		break;
 	default:
 		error("unknown gfx mode %d", _mode);
-		_scaleFactor = 1;
-		_scaler_proc = NULL;
+	}
+
+	switch (_aspectRatioMode) {
+	case ASPECT_NONE:
+		_stretcher_proc = NULL;
+		break;
+	case ASPECT_SLOPPY:
+		_stretcher_proc = stretch200To240Sloppy;
+		break;
+	case ASPECT_FAST:
+		_stretcher_proc = stretch200To240Fast;
+		break;
+	case ASPECT_EXACT:
+		_stretcher_proc = stretch200To240Exact;
+		break;
+	default:
+		error("unknown aspect ratio mode %d", _aspectRatioMode);
 	}
 
 	//
@@ -149,7 +159,7 @@
 	// Create the surface that contains the scaled graphics in 16 bit mode
 	//
 
-	_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16, 
+	_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16, 
 		_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
 	);
 	if (_hwscreen == NULL)
@@ -283,7 +293,7 @@
 		uint32 srcPitch, dstPitch;
 		SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects;
 
-		if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
+		if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
 			SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
 			for (r = _dirty_rect_list; r != last_rect; ++r) {
 				dst = *r;
@@ -325,7 +335,7 @@
 
 					dst_y *= _scaleFactor;
 
-					if (_adjustAspectRatio) {
+					if (_aspectRatioMode != ASPECT_NONE) {
 						orig_dst_y = dst_y;
 						dst_y = real2Aspect(dst_y);
 					}
@@ -339,8 +349,8 @@
 				r->w *= _scaleFactor;
 				r->h = dst_h * _scaleFactor;
 
-				if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
-					r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
+				if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
+					r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
 			}
 			SDL_UnlockSurface(_tmpscreen);
 			SDL_UnlockSurface(_hwscreen);
@@ -350,7 +360,7 @@
 		// This is necessary if shaking is active.
 		if (_forceFull) {
 			_dirty_rect_list[0].y = 0;
-			_dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
+			_dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
 		}
 
 		// Finally, blit all our changes to the screen
@@ -385,10 +395,9 @@
 		hotswap_gfx_mode();
 
 		return 1;
-	} else if (param == PROP_TOGGLE_ASPECT_RATIO) {
+	} else if (param == PROP_SET_ASPECT_RATIO_MODE) {
 		if (_screenHeight == 200) {
-			assert(_hwscreen != 0);
-			_adjustAspectRatio ^= true;
+			_aspectRatioMode = value->aspect_ratio_mode;
 			hotswap_gfx_mode();
 		}
 	}
diff -ur ScummVM+orig/scummvm/backends/sdl/sdl_gl.cpp ScummVM+hack/scummvm/backends/sdl/sdl_gl.cpp
--- ScummVM+orig/scummvm/backends/sdl/sdl_gl.cpp	2003-06-30 16:18:13.000000000 +0200
+++ ScummVM+hack/scummvm/backends/sdl/sdl_gl.cpp	2003-06-30 17:00:36.000000000 +0200
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl_gl.cpp,v 1.42 2003/06/30 02:38:56 kirben Exp $
+ * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl_gl.cpp,v 1.43 2003/06/30 14:31:09 eriktorbjorn Exp $
  *
  */
 
@@ -64,6 +64,7 @@
 	SDL_Surface *_hwscreen;  // hardware screen (=> _usingOpenGL == false)
 
 	ScalerProc *_scaler_proc;
+	StretcherProc *_stretcher_proc;
 	
 	virtual void load_gfx_mode();
 	virtual void unload_gfx_mode();
@@ -75,7 +76,7 @@
 }
 
 OSystem_SDL_OpenGL::OSystem_SDL_OpenGL()
-  : _hwscreen(0), _scaler_proc(0)
+  : _hwscreen(0), _scaler_proc(0), _stretcher_proc(0)
 {
   _glScreenStart = 0; 
   _glBilinearFilter = false;
@@ -159,16 +160,11 @@
 		break;
 
 	case GFX_TRIPLESIZE:
-		if (_full_screen) {
-			warning("full screen in useless in triplesize mode, reverting to normal mode");
-			goto normal_mode;
-		}
 		_scaleFactor = 3;
 		_scaler_proc = Normal3x;
 		break;
 
 	case GFX_NORMAL:
-normal_mode:;
 		_scaleFactor = 1; //_usingOpenGL ? 2 : 1;
 		_scaler_proc = Normal1x;
 		break;
@@ -180,9 +176,26 @@
 	}
 
 	if (_mode != GFX_NORMAL) {
-	  _usingOpenGL = false;
+		_usingOpenGL = false;
 	}
-  
+
+	switch (_aspectRatioMode) {
+	case ASPECT_NONE:
+		_stretcher_proc = NULL;
+		break;
+	case ASPECT_SLOPPY:
+		_stretcher_proc = stretch200To240Sloppy;
+		break;
+	case ASPECT_FAST:
+		_stretcher_proc = stretch200To240Fast;
+		break;
+	case ASPECT_EXACT:
+		_stretcher_proc = stretch200To240Exact;
+		break;
+	default:
+		error("unknown aspect ratio mode %d", _aspectRatioMode);
+	}
+
 	//
 	// Create the surface that contains the 8 bit game data
 	//
@@ -218,7 +231,7 @@
 		
 	} else { // SDL backend
 	  
-		_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16, 
+		_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16, 
 		_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
 		);
 		if (_hwscreen == NULL)
@@ -432,7 +445,7 @@
 
 			// Bottom black border height
 			tmpBlackRect.h = _glBottomOfTexture - _glBottomOfGameScreen;
-			if (_adjustAspectRatio && tmpBlackRect.h > 0) {
+			if (_aspectRatioMode != ASPECT_NONE && tmpBlackRect.h > 0) {
 				SDL_FillRect(tmpSurface, &tmpBlackRect, 0);
 				fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0,
 				  _glBottomOfGameScreen);
@@ -441,7 +454,7 @@
 			fb2gl.display();
 		} else { // SDL backend
 			
-			if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
+			if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
 				SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
 				for (r = _dirty_rect_list; r != last_rect; ++r) {
 					dst = *r;
@@ -483,7 +496,7 @@
 			
 							dst_y *= _scaleFactor;
 			
-							if (_adjustAspectRatio) {
+							if (_aspectRatioMode != ASPECT_NONE) {
 								orig_dst_y = dst_y;
 								dst_y = real2Aspect(dst_y);
 							}
@@ -497,8 +510,8 @@
 					r->w *= _scaleFactor;
 					r->h = dst_h * _scaleFactor;
 
-					if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
-						r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
+					if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
+						r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
 				}
 			
 				SDL_UnlockSurface(_tmpscreen);
@@ -509,7 +522,7 @@
 			// This is necessary if shaking is active.
 			if (_forceFull) {
 				_dirty_rect_list[0].y = 0;
-				_dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
+				_dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
 			}
 			
 			// Finally, blit all our changes to the screen
@@ -571,11 +584,14 @@
 #endif
 
 		return 1;
-	} else if (param == PROP_TOGGLE_ASPECT_RATIO) {
-
-		_adjustAspectRatio ^= true;
+	} else if (param == PROP_SET_ASPECT_RATIO_MODE) {
 		if (_usingOpenGL) {
-			if (_adjustAspectRatio) {
+			// OpenGL has only two aspect ratio correction modes.
+			if (value->aspect_ratio_mode == ASPECT_MIN)
+				_aspectRatioMode = ASPECT_MIN;
+			else
+				_aspectRatioMode = ASPECT_MAX;
+			if (_aspectRatioMode != ASPECT_NONE) {
 				// Don't use the whole screen (black borders)
 				fb2gl.init(0, 0, 0, 15, _glFlags);
 				_glScreenStart = _glBorderHeight;
@@ -611,7 +627,7 @@
 			fb2gl.display();
 		} else {
 			if (_screenHeight == 200) {
-				assert(_hwscreen != 0);
+				_aspectRatioMode = value->aspect_ratio_mode;
 				hotswap_gfx_mode();
 			}
 		}
diff -ur ScummVM+orig/scummvm/common/gameDetector.cpp ScummVM+hack/scummvm/common/gameDetector.cpp
--- ScummVM+orig/scummvm/common/gameDetector.cpp	2003-06-22 16:27:15.000000000 +0200
+++ ScummVM+hack/scummvm/common/gameDetector.cpp	2003-06-30 16:40:14.000000000 +0200
@@ -25,7 +25,7 @@
 #include "engine.h"
 #include "gameDetector.h"
 #include "config-file.h"
-#include "scaler.h"	// Only for gfx_modes
+#include "scaler.h"	// Only for gfx_modes and aspect ratio
 
 #if defined(HAVE_CONFIG_H)
 #include "config.h"
@@ -54,6 +54,7 @@
 	"\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-r<mode>       - aspect ratio correction (none,sloppy,fast,exact)\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"
@@ -82,7 +83,6 @@
 	"\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.
@@ -110,6 +110,14 @@
 	{0, 0, 0}
 };
 
+static const struct AspectRatioMode aspect_ratio_modes[] = {
+	{"none", "No correction", ASPECT_NONE},
+	{"sloppy", "Pixel doubling", ASPECT_SLOPPY},
+	{"fast", "Approximate bilinear filtering", ASPECT_FAST},
+	{"exact", "Exact bilinear filtering", ASPECT_EXACT},
+	{0, 0, 0}
+};
+
 static const struct Language languages[] = {
 	{"en", "English", EN_USA},
 	{"de", "German", DE_DEU},
@@ -150,7 +158,7 @@
 
 GameDetector::GameDetector() {
 	_fullScreen = false;
-	_aspectRatio = false;
+	_aspectRatioMode = ASPECT_NONE;
 
 	_use_adlib = false;
 
@@ -248,7 +256,13 @@
 		}
 
 	_fullScreen = g_config->getBool("fullscreen", _fullScreen);
-	_aspectRatio = g_config->getBool("aspect_ratio", _aspectRatio);
+
+	if ((val = g_config->get("aspect_ratio")))
+		if ((_aspectRatioMode = parseAspectRatioMode(val)) == -1) {
+			printf("Error in the config file: invalid aspect_ratio.\n");
+			printf(USAGE_STRING);
+			exit(-1);
+		}
 
 	if ((val = g_config->get("gfx_mode")))
 		if ((_gfx_mode = parseGraphicsMode(val)) == -1) {
@@ -404,7 +418,10 @@
 				break;
 			case 'r':
 				HANDLE_OPTION();
-				// Ignore -r for now, to ensure backward compatibility.
+				_aspectRatioMode = parseAspectRatioMode(option);
+				if (_aspectRatioMode == -1)
+					goto ShowHelpAndExit;
+				g_config->set("aspect_ratio", option, "scummvm");
 				break;
 			case 's':
 				HANDLE_OPTION();
@@ -457,9 +474,6 @@
 				} 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;
 				}
@@ -520,6 +534,17 @@
 	return -1;
 }
 
+int GameDetector::parseAspectRatioMode(const char *s) {
+	const AspectRatioMode *arm = aspect_ratio_modes;
+	while(arm->name) {
+		if (!scumm_stricmp(arm->name, s))
+			return arm->id;
+		arm++;
+	}
+
+	return -1;
+}
+
 int GameDetector::parseLanguage(const char *s) {
 	const Language *l = languages;
 	while(l->name) {
@@ -680,7 +705,7 @@
 	return OSystem_PALMOS_create(_gfx_mode);
 #else
 	/* SDL is the default driver for now */
-	return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatio);
+	return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatioMode);
 #endif
 }
 
diff -ur ScummVM+orig/scummvm/common/gameDetector.h ScummVM+hack/scummvm/common/gameDetector.h
--- ScummVM+orig/scummvm/common/gameDetector.h	2003-06-22 16:27:15.000000000 +0200
+++ ScummVM+hack/scummvm/common/gameDetector.h	2003-06-30 16:40:14.000000000 +0200
@@ -85,6 +85,12 @@
 	int id;
 };
 
+struct AspectRatioMode {
+	const char *name;
+	const char *description;
+	int id;
+};
+
 struct Language {
 	const char *name;
 	const char *description;
@@ -110,7 +116,7 @@
 	const String& getGameName(void);
 	
 	bool _fullScreen;
-	bool _aspectRatio;
+	int _aspectRatioMode;
 
 	bool _use_adlib;
 
@@ -151,6 +157,7 @@
 	int getMidiDriverType();
 
 	int parseGraphicsMode(const char *s);
+	int parseAspectRatioMode(const char *s);
 	void updateconfig();
 
 protected:
diff -ur ScummVM+orig/scummvm/common/scaler.cpp ScummVM+hack/scummvm/common/scaler.cpp
--- ScummVM+orig/scummvm/common/scaler.cpp	2003-06-23 11:30:11.000000000 +0200
+++ ScummVM+hack/scummvm/common/scaler.cpp	2003-06-30 16:40:14.000000000 +0200
@@ -658,13 +658,7 @@
 	return (uint16)((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
+static inline void interpolate5LineFast(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) {
 	// Not fully accurate, but a bit faster
 	
 	if (width & 1) {
@@ -693,7 +687,13 @@
 			*d++ = INTERPOLATE(*sA++, *sB++);
 		}
 	}
-#endif
+}
+
+static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) {
+	// Accurate but slightly slower code
+	while (width--) {
+		*dst++ = interpolate5(*srcA++, *srcB++, scale);
+	}
 }
 
 void makeRectStretchable(int &x, int &y, int &w, int &h) {
@@ -710,9 +710,9 @@
 
 /**
  * Stretch a 16bpp image vertically by factor 1.2. Used to correct the
- * aspect-ratio in games using 320x200 pixel graphics with non-qudratic
+ * 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.
+ * provides the correct aspect ratio on modern displays.
  *
  * The image would normally have occupied y coordinates origSrcY through
  * origSrcY + height - 1.
@@ -724,7 +724,7 @@
  * 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 stretch200To240Sloppy(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;
@@ -734,14 +734,60 @@
 	for (y = maxDstY; y >= srcY; y--) {
 		uint8 *srcPtr = buf + srcX * 2 + (aspect2Real(y) + off) * pitch;
 
-#if 0
-		// Don't use bilinear filtering, rather just duplicate pixel lines:
-		// a little bit faster, but looks ugly
+		// Don't use bilinear filtering, rather just duplicate pixel
+		// lines: a little bit faster, but looks ugly
 		if (srcPtr == dstPtr)
 			break;
 		
 		memcpy(dstPtr, srcPtr, width * 2);
-#else
+		dstPtr -= pitch;
+	}
+
+	return 1 + maxDstY - srcY;
+}
+
+int stretch200To240Fast(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;
+
+		// Bilinear filter
+		switch (y % 6) {
+		case 0:
+		case 5:
+			if (srcPtr != dstPtr)
+				memcpy(dstPtr, srcPtr, width * 2);
+			break;
+		case 1:
+		case 4:
+			interpolate5LineFast((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 1, width);
+			break;
+		case 2:
+		case 3:
+			interpolate5LineFast((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 2, width);
+			break;
+		}
+		dstPtr -= pitch;
+	}
+
+	return 1 + maxDstY - srcY;
+}
+
+int stretch200To240Exact(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;
+
 		// Bilinear filter
 		switch (y % 6) {
 		case 0:
@@ -758,7 +804,6 @@
 			interpolate5Line((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 2, width);
 			break;
 		}
-#endif
 		dstPtr -= pitch;
 	}
 
diff -ur ScummVM+orig/scummvm/common/scaler.h ScummVM+hack/scummvm/common/scaler.h
--- ScummVM+orig/scummvm/common/scaler.h	2003-06-22 17:00:34.000000000 +0200
+++ ScummVM+hack/scummvm/common/scaler.h	2003-06-30 16:40:14.000000000 +0200
@@ -51,7 +51,14 @@
 
 extern void makeRectStretchable(int &x, int &y, int &w, int &h);
 
-extern int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY);
+typedef int StretcherProc(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY);
+
+#define DECLARE_STRETCHER(x)	\
+	extern int x(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY)
+
+DECLARE_STRETCHER(stretch200To240Sloppy);
+DECLARE_STRETCHER(stretch200To240Fast);
+DECLARE_STRETCHER(stretch200To240Exact);
 
 enum {
 	GFX_NORMAL = 0,
@@ -73,5 +80,15 @@
 	
 };
 
+enum {
+	ASPECT_MIN = 0,
+
+	ASPECT_NONE = 0,
+	ASPECT_SLOPPY = 1,
+	ASPECT_FAST = 2,
+	ASPECT_EXACT = 3,
+
+	ASPECT_MAX = 3
+};
 
 #endif
diff -ur ScummVM+orig/scummvm/common/system.h ScummVM+hack/scummvm/common/system.h
--- ScummVM+orig/scummvm/common/system.h	2003-06-22 16:27:16.000000000 +0200
+++ ScummVM+hack/scummvm/common/system.h	2003-06-30 16:40:14.000000000 +0200
@@ -95,12 +95,13 @@
 		PROP_GET_FULLSCREEN = 7,
 		PROP_GET_FMOPL_ENV_BITS = 8,
 		PROP_GET_FMOPL_EG_ENT = 9,
-		PROP_TOGGLE_ASPECT_RATIO = 10
+		PROP_SET_ASPECT_RATIO_MODE = 10
 	};
 	union Property {
 		const char *caption;
 		int cd_num;
 		int gfx_mode;
+		int aspect_ratio_mode;
 		bool show_cursor;
 	};
 	
@@ -364,7 +365,7 @@
 /* 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, bool aspect_ratio);
+extern OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen, int aspect_ratio_mode);
 extern OSystem *OSystem_NULL_create();
 extern OSystem *OSystem_MorphOS_create(int game_id, int gfx_driver, bool full_screen);
 extern OSystem *OSystem_Dreamcast_create();
diff -ur ScummVM+orig/scummvm/scumm/scummvm.cpp ScummVM+hack/scummvm/scumm/scummvm.cpp
--- ScummVM+orig/scummvm/scumm/scummvm.cpp	2003-06-27 10:27:10.000000000 +0200
+++ ScummVM+hack/scummvm/scumm/scummvm.cpp	2003-06-30 16:40:14.000000000 +0200
@@ -586,17 +586,24 @@
 	_sound->_sound_volume_sfx = detector->_sfx_volume;
 	_sound->_sound_volume_music = detector->_music_volume;
 
+	/* Initialize backend */
+
+	syst->init_size(_screenWidth, _screenHeight);
+	prop.cd_num = detector->_cdrom;
+	if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
+		syst->property(OSystem::PROP_OPEN_CD, &prop);
+
 	// Override global scaler with any game-specific define
 	if (g_config->get("gfx_mode")) {
 		prop.gfx_mode = detector->parseGraphicsMode(g_config->get("gfx_mode"));
 		syst->property(OSystem::PROP_SET_GFX_MODE, &prop);
 	}
 
-	/* Initialize backend */
-	syst->init_size(_screenWidth, _screenHeight);
-	prop.cd_num = detector->_cdrom;
-	if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
-		syst->property(OSystem::PROP_OPEN_CD, &prop);
+	// Override global aspect ratio correction with any game-specific define
+	if (g_config->get("aspect_ratio")) {
+		prop.aspect_ratio_mode = detector->parseAspectRatioMode(g_config->get("aspect_ratio"));
+		syst->property(OSystem::PROP_SET_ASPECT_RATIO_MODE, &prop);
+	}
 
 	// Override global fullscreen setting with any game-specific define
 	if (g_config->getBool("fullscreen", false)) {
