[Scummvm-cvs-logs] SF.net SVN: scummvm:[43577] scummvm/trunk

upthorn at users.sourceforge.net upthorn at users.sourceforge.net
Fri Aug 21 11:37:51 CEST 2009


Revision: 43577
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43577&view=rev
Author:   upthorn
Date:     2009-08-21 09:37:51 +0000 (Fri, 21 Aug 2009)

Log Message:
-----------
Merged RGB color API and support in from /scummvm/branches/gsoc2009-16bit/

Modified Paths:
--------------
    scummvm/trunk/backends/platform/sdl/graphics.cpp
    scummvm/trunk/backends/platform/sdl/sdl.cpp
    scummvm/trunk/backends/platform/sdl/sdl.h
    scummvm/trunk/common/error.h
    scummvm/trunk/common/system.h
    scummvm/trunk/configure
    scummvm/trunk/dists/msvc8/ScummVM_Global.vsprops
    scummvm/trunk/dists/msvc8/groovie.vcproj
    scummvm/trunk/dists/msvc8/sci.vcproj
    scummvm/trunk/dists/msvc8/scumm.vcproj
    scummvm/trunk/dists/msvc8/scummvm.vcproj
    scummvm/trunk/engines/cine/pal.h
    scummvm/trunk/engines/engine.cpp
    scummvm/trunk/engines/engine.h
    scummvm/trunk/engines/sci/gfx/gfx_driver.cpp
    scummvm/trunk/engines/sci/gfx/gfx_driver.h
    scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.cpp
    scummvm/trunk/engines/sci/gfx/gfx_resmgr.cpp
    scummvm/trunk/engines/sci/gfx/gfx_system.h
    scummvm/trunk/engines/sci/gfx/gfx_tools.cpp
    scummvm/trunk/engines/sci/gfx/operations.cpp
    scummvm/trunk/engines/sci/gfx/operations.h
    scummvm/trunk/engines/sci/gfx/res_pic.cpp
    scummvm/trunk/engines/sci/sci.cpp
    scummvm/trunk/engines/scumm/actor.cpp
    scummvm/trunk/engines/scumm/actor.h
    scummvm/trunk/engines/scumm/akos.cpp
    scummvm/trunk/engines/scumm/akos.h
    scummvm/trunk/engines/scumm/base-costume.cpp
    scummvm/trunk/engines/scumm/base-costume.h
    scummvm/trunk/engines/scumm/charset.cpp
    scummvm/trunk/engines/scumm/costume.cpp
    scummvm/trunk/engines/scumm/costume.h
    scummvm/trunk/engines/scumm/cursor.cpp
    scummvm/trunk/engines/scumm/gfx.cpp
    scummvm/trunk/engines/scumm/gfx.h
    scummvm/trunk/engines/scumm/he/animation_he.cpp
    scummvm/trunk/engines/scumm/he/animation_he.h
    scummvm/trunk/engines/scumm/he/intern_he.h
    scummvm/trunk/engines/scumm/he/palette_he.cpp
    scummvm/trunk/engines/scumm/he/script_v100he.cpp
    scummvm/trunk/engines/scumm/he/script_v60he.cpp
    scummvm/trunk/engines/scumm/he/script_v72he.cpp
    scummvm/trunk/engines/scumm/he/script_v80he.cpp
    scummvm/trunk/engines/scumm/he/script_v90he.cpp
    scummvm/trunk/engines/scumm/he/wiz_he.cpp
    scummvm/trunk/engines/scumm/he/wiz_he.h
    scummvm/trunk/engines/scumm/palette.cpp
    scummvm/trunk/engines/scumm/resource.cpp
    scummvm/trunk/engines/scumm/saveload.cpp
    scummvm/trunk/engines/scumm/saveload.h
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/scumm.h
    scummvm/trunk/graphics/cursorman.cpp
    scummvm/trunk/graphics/cursorman.h
    scummvm/trunk/graphics/pixelformat.h
    scummvm/trunk/graphics/scaler.cpp
    scummvm/trunk/gui/ThemeEngine.cpp
    scummvm/trunk/gui/ThemeEngine.h

Modified: scummvm/trunk/backends/platform/sdl/graphics.cpp
===================================================================
--- scummvm/trunk/backends/platform/sdl/graphics.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/backends/platform/sdl/graphics.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -26,6 +26,9 @@
 #include "backends/platform/sdl/sdl.h"
 #include "common/mutex.h"
 #include "common/util.h"
+#ifdef ENABLE_RGB_COLOR
+#include "common/list.h"
+#endif
 #include "graphics/font.h"
 #include "graphics/fontman.h"
 #include "graphics/scaler.h"
@@ -97,6 +100,9 @@
 	_transactionDetails.needUpdatescreen = false;
 
 	_transactionDetails.normal1xScaler = false;
+#ifdef ENABLE_RGB_COLOR
+	_transactionDetails.formatChanged = false;
+#endif
 
 	_oldVideoMode = _videoMode;
 }
@@ -120,6 +126,13 @@
 
 			_videoMode.mode = _oldVideoMode.mode;
 			_videoMode.scaleFactor = _oldVideoMode.scaleFactor;
+#ifdef ENABLE_RGB_COLOR
+		} else if (_videoMode.format != _oldVideoMode.format) {
+			errors |= kTransactionFormatNotSupported;
+
+			_videoMode.format = _oldVideoMode.format;
+			_screenFormat = _videoMode.format;
+#endif
 		} else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) {
 			errors |= kTransactionSizeChangeFailed;
 
@@ -143,7 +156,11 @@
 		}
 	}
 
+#ifdef ENABLE_RGB_COLOR
+	if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) {
+#else
 	if (_transactionDetails.sizeChanged) {
+#endif
 		unloadGFXMode();
 		if (!loadGFXMode()) {
 			if (_oldVideoMode.setup) {
@@ -186,12 +203,94 @@
 	} else if (_transactionDetails.needUpdatescreen) {
 		setGraphicsModeIntern();
 		internUpdateScreen();
-	}
+	} 
 
 	_transactionMode = kTransactionNone;
 	return (TransactionError)errors;
 }
 
+#ifdef ENABLE_RGB_COLOR
+const Graphics::PixelFormat RGBList[] = {
+#ifdef ENABLE_32BIT
+	// RGBA8888, ARGB8888, RGB888
+	Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0),
+	Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24),
+	Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0),
+#endif
+	// RGB565, XRGB1555, RGB555, RGBA4444, ARGB4444
+	Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0),
+	Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15),
+	Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0),
+	Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0),
+	Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)
+};
+const Graphics::PixelFormat BGRList[] = {
+#ifdef ENABLE_32BIT
+	// ABGR8888, BGRA8888, BGR888
+	Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24),
+	Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0),
+	Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0),
+#endif
+	// BGR565, XBGR1555, BGR555, ABGR4444, BGRA4444
+	Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0),
+	Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15),
+	Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0),
+	Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12),
+	Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
+};
+
+// TODO: prioritize matching alpha masks
+Common::List<Graphics::PixelFormat> OSystem_SDL::getSupportedFormats() {
+	static Common::List<Graphics::PixelFormat> list;
+	static bool inited = false;
+
+	if (inited)
+		return list;
+
+	bool BGR = false;
+	int listLength = ARRAYSIZE(RGBList);
+
+	Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
+	if (_hwscreen) {
+		// Get our currently set hardware format
+		format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel, 
+			8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss, 
+			8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss, 
+			_hwscreen->format->Rshift, _hwscreen->format->Gshift, 
+			_hwscreen->format->Bshift, _hwscreen->format->Ashift);
+
+		// Workaround to MacOSX SDL not providing an accurate Aloss value.
+		if (_hwscreen->format->Amask == 0)
+			format.aLoss = 8;
+
+		// Push it first, as the prefered format.
+		list.push_back(format);
+
+		if (format.bShift > format.rShift)
+			BGR = true;
+
+		// Mark that we don't need to do this any more.
+		inited = true;
+	}
+
+	for (int i = 0; i < listLength; i++) {
+		if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
+			continue;
+		if (BGR) {
+			if (BGRList[i] != format)
+				list.push_back(BGRList[i]);
+			list.push_back(RGBList[i]);
+		} else {
+			if (RGBList[i] != format)
+				list.push_back(RGBList[i]);
+			list.push_back(BGRList[i]);
+		}
+	}
+	list.push_back(Graphics::PixelFormat::createFormatCLUT8());
+	return list;
+}
+#endif
+
 bool OSystem_SDL::setGraphicsMode(int mode) {
 	Common::StackLock lock(_graphicsMutex);
 
@@ -340,9 +439,27 @@
 	return _videoMode.mode;
 }
 
-void OSystem_SDL::initSize(uint w, uint h) {
+void OSystem_SDL::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
 	assert(_transactionMode == kTransactionActive);
 
+#ifdef ENABLE_RGB_COLOR
+	//avoid redundant format changes
+	Graphics::PixelFormat newFormat;
+	if (!format)
+		newFormat = Graphics::PixelFormat::createFormatCLUT8();
+	else
+		newFormat = *format;
+
+	assert(newFormat.bytesPerPixel > 0);
+
+	if (newFormat != _videoMode.format)
+	{
+		_videoMode.format = newFormat;
+		_transactionDetails.formatChanged = true;
+		_screenFormat = newFormat;
+	}
+#endif
+
 	// Avoid redundant res changes
 	if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
 		return;
@@ -426,9 +543,21 @@
 	//
 	// Create the surface that contains the 8 bit game data
 	//
+#ifdef ENABLE_RGB_COLOR
+	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 
+						_screenFormat.bytesPerPixel << 3, 
+						((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift ,
+						((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift ,
+						((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift ,
+						((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift );
+	if (_screen == NULL)
+		error("allocating _screen failed");
+
+#else
 	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
 	if (_screen == NULL)
 		error("allocating _screen failed");
+#endif
 
 	//
 	// Create the surface that contains the scaled graphics in 16 bit mode
@@ -571,8 +700,8 @@
 	// Keep around the old _screen & _overlayscreen so we can restore the screen data
 	// after the mode switch.
 	SDL_Surface *old_screen = _screen;
+	_screen = NULL;
 	SDL_Surface *old_overlayscreen = _overlayscreen;
-	_screen = NULL;
 	_overlayscreen = NULL;
 
 	// Release the HW screen surface
@@ -878,8 +1007,19 @@
 	if (SDL_LockSurface(_screen) == -1)
 		error("SDL_LockSurface failed: %s", SDL_GetError());
 
+#ifdef ENABLE_RGB_COLOR
+	byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth * _screenFormat.bytesPerPixel + x * _screenFormat.bytesPerPixel;
+	if (_videoMode.screenWidth == w && pitch == w * _screenFormat.bytesPerPixel) {
+		memcpy(dst, src, h*w*_screenFormat.bytesPerPixel);
+	} else {
+		do {
+			memcpy(dst, src, w * _screenFormat.bytesPerPixel);
+			src += pitch;
+			dst += _videoMode.screenWidth * _screenFormat.bytesPerPixel;
+		} while (--h);
+	}
+#else
 	byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
-
 	if (_videoMode.screenWidth == pitch && pitch == w) {
 		memcpy(dst, src, h*w);
 	} else {
@@ -889,6 +1029,7 @@
 			dst += _videoMode.screenWidth;
 		} while (--h);
 	}
+#endif
 
 	// Unlock the screen surface
 	SDL_UnlockSurface(_screen);
@@ -912,7 +1053,11 @@
 	_framebuffer.w = _screen->w;
 	_framebuffer.h = _screen->h;
 	_framebuffer.pitch = _screen->pitch;
+#ifdef ENABLE_RGB_COLOR
+	_framebuffer.bytesPerPixel = _screenFormat.bytesPerPixel;
+#else
 	_framebuffer.bytesPerPixel = 1;
+#endif
 
 	return &_framebuffer;
 }
@@ -1096,6 +1241,11 @@
 void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) {
 	assert(colors);
 
+#ifdef ENABLE_RGB_COLOR
+	if (_screenFormat.bytesPerPixel > 1)
+		return; //not using a paletted pixel format
+#endif
+
 	// Setting the palette before _screen is created is allowed - for now -
 	// since we don't actually set the palette until the screen is updated.
 	// But it could indicate a programming error, so let's warn about it.
@@ -1149,10 +1299,10 @@
 	}
 
 	_cursorPaletteDisabled = false;
-
 	blitCursor();
 }
 
+
 void OSystem_SDL::setShakePos(int shake_pos) {
 	assert (_transactionMode == kTransactionNone);
 
@@ -1357,7 +1507,17 @@
 	}
 }
 
-void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
+void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+#ifdef ENABLE_RGB_COLOR
+	if (!format)
+		_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+	else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel)
+		_cursorFormat = *format;
+	keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
+#else
+	keycolor &= 0xFF;
+#endif
+
 	if (w == 0 || h == 0)
 		return;
 
@@ -1391,16 +1551,26 @@
 	}
 
 	free(_mouseData);
-
+#ifdef ENABLE_RGB_COLOR
+	_mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
+	memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
+#else
 	_mouseData = (byte *)malloc(w * h);
 	memcpy(_mouseData, buf, w * h);
+#endif
+
 	blitCursor();
 }
 
 void OSystem_SDL::blitCursor() {
 	byte *dstPtr;
 	const byte *srcPtr = _mouseData;
+#ifdef ENABLE_RGB_COLOR
+	uint32 color;
+	uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1;
+#else
 	byte color;
+#endif
 	int w, h, i, j;
 
 	if (!_mouseOrigSurface || !_mouseData)
@@ -1434,13 +1604,29 @@
 
 	for (i = 0; i < h; i++) {
 		for (j = 0; j < w; j++) {
-			color = *srcPtr;
-			if (color != _mouseKeyColor) {	// transparent, don't draw
-				*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
-					palette[color].r, palette[color].g, palette[color].b);
+#ifdef ENABLE_RGB_COLOR
+			if (_cursorFormat.bytesPerPixel > 1) {
+				color = (*(uint32 *) srcPtr) & colormask;
+				if (color != _mouseKeyColor) {	// transparent, don't draw
+					uint8 r,g,b;
+					_cursorFormat.colorToRGB(color,r,g,b);
+					*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
+						r, g, b);
+				}
+				dstPtr += 2;
+				srcPtr += _cursorFormat.bytesPerPixel;
+			} else {
+#endif
+				color = *srcPtr;
+				if (color != _mouseKeyColor) {	// transparent, don't draw
+					*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
+						palette[color].r, palette[color].g, palette[color].b);
+				}
+				dstPtr += 2;
+				srcPtr++;
+#ifdef ENABLE_RGB_COLOR
 			}
-			dstPtr += 2;
-			srcPtr++;
+#endif
 		}
 		dstPtr += _mouseOrigSurface->pitch - w * 2;
 	}

Modified: scummvm/trunk/backends/platform/sdl/sdl.cpp
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/backends/platform/sdl/sdl.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -222,6 +222,10 @@
 	_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
 #endif
 	_hwscreen(0), _screen(0), _tmpscreen(0),
+#ifdef ENABLE_RGB_COLOR
+	_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
+	_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
+#endif
 	_overlayVisible(false),
 	_overlayscreen(0), _tmpscreen2(0),
 	_samplesPerSec(0),

Modified: scummvm/trunk/backends/platform/sdl/sdl.h
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/backends/platform/sdl/sdl.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -93,10 +93,18 @@
 	void beginGFXTransaction(void);
 	TransactionError endGFXTransaction(void);
 
-	// Set the size of the video bitmap.
-	// Typically, 320x200
-	virtual void initSize(uint w, uint h); // overloaded by CE backend
+#ifdef ENABLE_RGB_COLOR
+	// Game screen
+	virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
 
+	// Highest supported
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
+#endif
+
+	// Set the size and format of the video bitmap.
+	// Typically, 320x200 CLUT8
+	virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format); // overloaded by CE backend
+
 	virtual int getScreenChangeID() const { return _screenChangeCount; }
 
 	// Set colors of the palette
@@ -124,7 +132,7 @@
 	virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME)
 
 	// Set the bitmap that's used when drawing the cursor.
-	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME)
+	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME)
 
 	// Set colors of cursor palette
 	void setCursorPalette(const byte *colors, uint start, uint num);
@@ -186,6 +194,7 @@
 
 	// Overlay
 	virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
+
 	virtual void showOverlay();
 	virtual void hideOverlay();
 	virtual void clearOverlay();
@@ -239,6 +248,10 @@
 
 	// unseen game screen
 	SDL_Surface *_screen;
+#ifdef ENABLE_RGB_COLOR
+	Graphics::PixelFormat _screenFormat;
+	Graphics::PixelFormat _cursorFormat;
+#endif
 
 	// temporary screen (for scalers)
 	SDL_Surface *_tmpscreen;
@@ -272,6 +285,9 @@
 		bool needHotswap;
 		bool needUpdatescreen;
 		bool normal1xScaler;
+#ifdef ENABLE_RGB_COLOR
+		bool formatChanged;
+#endif
 	};
 	TransactionDetails _transactionDetails;
 
@@ -288,6 +304,9 @@
 		int screenWidth, screenHeight;
 		int overlayWidth, overlayHeight;
 		int hardwareWidth, hardwareHeight;
+#ifdef ENABLE_RGB_COLOR
+		Graphics::PixelFormat format;
+#endif
 	};
 	VideoState _videoMode, _oldVideoMode;
 

Modified: scummvm/trunk/common/error.h
===================================================================
--- scummvm/trunk/common/error.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/common/error.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -48,6 +48,7 @@
 	kInvalidPathError,			//!< Engine initialization: Invalid game path was passed
 	kNoGameDataFoundError,		//!< Engine initialization: No game data was found in the specified location
 	kUnsupportedGameidError,	//!< Engine initialization: Gameid not supported by this (Meta)Engine
+	kUnsupportedColorMode,		//!< Engine initialization: Engine does not support backend's color mode
 
 
 	kReadPermissionDenied,		//!< Unable to read data due to missing read permission

Modified: scummvm/trunk/common/system.h
===================================================================
--- scummvm/trunk/common/system.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/common/system.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -31,6 +31,9 @@
 #include "common/rect.h"
 
 #include "graphics/pixelformat.h"
+#ifdef ENABLE_RGB_COLOR
+#include "graphics/conversion.h"
+#endif
 
 namespace Audio {
 	class Mixer;
@@ -347,8 +350,52 @@
 	 */
 	virtual int getGraphicsMode() const = 0;
 
+#ifdef ENABLE_RGB_COLOR
 	/**
-	 * Set the size of the virtual screen. Typical sizes include:
+	 * Determine the pixel format currently in use for screen rendering.
+	 * @return the active screen pixel format.
+	 * @see Graphics::PixelFormat
+	 */
+	virtual Graphics::PixelFormat getScreenFormat() const = 0;
+
+	/**
+	 * Returns a list of all pixel formats supported by the backend. 
+	 * The first item in the list must be directly supported by hardware, 
+	 * and provide the largest color space of those formats with direct 
+	 * hardware support. It is also strongly recommended that remaining 
+	 * formats should be placed in order of descending preference for the 
+	 * backend to use.
+	 *
+	 * EG: a backend that supports 32-bit ABGR and 16-bit 555 BGR in hardware
+	 * and provides conversion from equivalent RGB(A) modes should order its list
+	 *    1) Graphics::PixelFormat(4, 0, 0, 0, 0, 0, 8, 16, 24)
+	 *    2) Graphics::PixelFormat(2, 3, 3, 3, 8, 0, 5, 10, 0)
+	 *    3) Graphics::PixelFormat(4, 0, 0, 0, 0, 24, 16, 8, 0)
+	 *    4) Graphics::PixelFormat(2, 3, 3, 3, 8, 10, 5, 0, 0)
+	 *    5) Graphics::PixelFormat::createFormatCLUT8()
+	 *
+	 * @see Graphics::PixelFormat
+	 *
+	 * @note Backends supporting RGB color should accept game data in RGB color 
+	 *       order, even if hardware uses BGR or some other color order.
+	 *
+	 * @see convertScreenRect
+	 */
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0;
+#else
+	inline Graphics::PixelFormat getScreenFormat() const {
+		return Graphics::PixelFormat::createFormatCLUT8();
+	};
+
+	inline Common::List<Graphics::PixelFormat> getSupportedFormats() const {
+		Common::List<Graphics::PixelFormat> list;
+		list.push_back(Graphics::PixelFormat::createFormatCLUT8());
+		return list;
+	};
+#endif
+
+	/**
+	 * Set the size and color format of the virtual screen. Typical sizes include:
 	 *  - 320x200 (e.g. for most SCUMM games, and Simon)
 	 *  - 320x240 (e.g. for FM-TOWN SCUMM games)
 	 *  - 640x480 (e.g. for Curse of Monkey Island)
@@ -359,10 +406,21 @@
 	 * GraphicsMode); stretch the data to perform aspect ratio correction;
 	 * or shrink it to fit on small screens (in cell phones).
 	 *
+	 * Typical formats include:
+	 *  CLUT8 (e.g. 256 color, for most games)
+	 *  RGB555 (e.g. 16-bit color, for later SCUMM HE games)
+	 *  RGB565 (e.g. 16-bit color, for Urban Runner)
+	 *
+	 * This is the pixel format for which the client code generates data;
+	 * this is not necessarily equal to the hardware pixel format. For example,
+	 * a backend may perform color lookup of 8-bit graphics before pushing
+	 * a screen to hardware, or correct the ARGB color order via convertScreenRect.
+	 *
 	 * @param width		the new virtual screen width
 	 * @param height	the new virtual screen height
+	 * @param format	the new virtual screen pixel format
 	 */
-	virtual void initSize(uint width, uint height) = 0;
+	virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0;
 
 	/**
 	 * Return an int value which is changed whenever any screen
@@ -411,7 +469,8 @@
 		kTransactionAspectRatioFailed = (1 << 0),	/**< Failed switching aspect ratio correction mode */
 		kTransactionFullscreenFailed = (1 << 1),	/**< Failed switching fullscreen mode */
 		kTransactionModeSwitchFailed = (1 << 2),	/**< Failed switching the GFX graphics mode (setGraphicsMode) */
-		kTransactionSizeChangeFailed = (1 << 3)		/**< Failed switching the screen dimensions (initSize) */
+		kTransactionSizeChangeFailed = (1 << 3),	/**< Failed switching the screen dimensions (initSize) */
+		kTransactionFormatNotSupported = (1 << 4)	/**< Failed setting the color format */
 	};
 
 	/**
@@ -705,8 +764,9 @@
 	 * @param hotspotY			vertical offset from the top side to the hotspot
 	 * @param keycolor			transparency color index
 	 * @param cursorTargetScale	scale factor which cursor is designed for
+	 * @param format			pointer to the pixel format which cursor graphic uses
 	 */
-	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0;
+	virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
 
 	/**
 	 * Replace the specified range of cursor the palette with new colors.

Modified: scummvm/trunk/configure
===================================================================
--- scummvm/trunk/configure	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/configure	2009-08-21 09:37:51 UTC (rev 43577)
@@ -110,7 +110,7 @@
 _zlib=auto
 _mpeg2=no
 _fluidsynth=auto
-_readline=auto
+_16bit=yes_readline=auto
 # Default option behaviour yes/no
 _text_console=no
 _mt32emu=yes

Modified: scummvm/trunk/dists/msvc8/ScummVM_Global.vsprops
===================================================================
--- scummvm/trunk/dists/msvc8/ScummVM_Global.vsprops	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/dists/msvc8/ScummVM_Global.vsprops	2009-08-21 09:37:51 UTC (rev 43577)
@@ -10,7 +10,7 @@
 		Name="VCCLCompilerTool"
 		DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996"
 		AdditionalIncludeDirectories="../..;../../engines"
-		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE"
+		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE;;ENABLE_RGB_COLOR"
 		ExceptionHandling="0"
 		RuntimeTypeInfo="false"
 		WarningLevel="4"

Modified: scummvm/trunk/dists/msvc8/groovie.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/groovie.vcproj	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/dists/msvc8/groovie.vcproj	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1,48 +1,244 @@
 <?xml version="1.0" encoding="windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="groovie"
 	ProjectGUID="{2C1EA540-0B09-11DD-BD00-000000000000}"
 	RootNamespace="groovie"
 	Keyword="Win32Proj"
 	>
 	<Platforms>
-		<Platform Name="Win32" />
+		<Platform
+			Name="Win32"
+		/>
 	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
 	<Configurations>
-		<Configuration Name="Debug|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Debug.vsprops" />
-		<Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="GROOVIE_EXPERIMENTAL"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\ScummVM_Release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
 	</Configurations>
+	<References>
+	</References>
 	<Files>
-		<File RelativePath="..\..\engines\groovie\cell.cpp" />
-		<File RelativePath="..\..\engines\groovie\cell.h" />
-		<File RelativePath="..\..\engines\groovie\cursor.cpp" />
-		<File RelativePath="..\..\engines\groovie\cursor.h" />
-		<File RelativePath="..\..\engines\groovie\debug.cpp" />
-		<File RelativePath="..\..\engines\groovie\debug.h" />
-		<File RelativePath="..\..\engines\groovie\detection.cpp" />
-		<File RelativePath="..\..\engines\groovie\font.cpp" />
-		<File RelativePath="..\..\engines\groovie\font.h" />
-		<File RelativePath="..\..\engines\groovie\graphics.cpp" />
-		<File RelativePath="..\..\engines\groovie\graphics.h" />
-		<File RelativePath="..\..\engines\groovie\groovie.cpp" />
-		<File RelativePath="..\..\engines\groovie\groovie.h" />
-		<File RelativePath="..\..\engines\groovie\lzss.cpp" />
-		<File RelativePath="..\..\engines\groovie\lzss.h" />
-		<File RelativePath="..\..\engines\groovie\music.cpp" />
-		<File RelativePath="..\..\engines\groovie\music.h" />
-		<File RelativePath="..\..\engines\groovie\player.cpp" />
-		<File RelativePath="..\..\engines\groovie\player.h" />
-		<File RelativePath="..\..\engines\groovie\resource.cpp" />
-		<File RelativePath="..\..\engines\groovie\resource.h" />
-		<File RelativePath="..\..\engines\groovie\roq.cpp" />
-		<File RelativePath="..\..\engines\groovie\roq.h" />
-		<File RelativePath="..\..\engines\groovie\saveload.cpp" />
-		<File RelativePath="..\..\engines\groovie\saveload.h" />		
-		<File RelativePath="..\..\engines\groovie\script.cpp" />
-		<File RelativePath="..\..\engines\groovie\script.h" />
-		<File RelativePath="..\..\engines\groovie\vdx.cpp" />
-		<File RelativePath="..\..\engines\groovie\vdx.h" />
+		<File
+			RelativePath="..\..\engines\groovie\cell.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\cell.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\cursor.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\cursor.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\debug.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\debug.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\detection.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\font.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\font.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\graphics.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\graphics.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\groovie.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\groovie.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\lzss.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\lzss.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\music.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\music.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\player.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\player.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\resource.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\resource.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\roq.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\roq.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\saveload.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\saveload.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\script.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\script.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\vdx.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\groovie\vdx.h"
+			>
+		</File>
 	</Files>
+	<Globals>
+	</Globals>
 </VisualStudioProject>

Modified: scummvm/trunk/dists/msvc8/sci.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/sci.vcproj	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/dists/msvc8/sci.vcproj	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="sci"
 	ProjectGUID="{53F17B2B-0412-4EC3-A999-ED0537BB5223}"
 	RootNamespace="sci"

Modified: scummvm/trunk/dists/msvc8/scumm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/scumm.vcproj	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/dists/msvc8/scumm.vcproj	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="scumm"
 	ProjectGUID="{B6AFD548-63D2-40CD-A652-E87095AFCBAF}"
 	RootNamespace="scumm"

Modified: scummvm/trunk/dists/msvc8/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/scummvm.vcproj	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/dists/msvc8/scummvm.vcproj	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="scummvm"
 	ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"
 	RootNamespace="scummvm"
@@ -47,6 +47,9 @@
 			<File RelativePath="..\..\common\debug.h" />
 			<File RelativePath="..\..\common\endian.h" />
 			<File RelativePath="..\..\common\error.h" />
+			<File RelativePath="..\..\common\EventDispatcher.cpp" />
+			<File RelativePath="..\..\common\EventRecorder.cpp" />
+			<File RelativePath="..\..\common\EventRecorder.h" />
 			<File RelativePath="..\..\common\events.h" />
 			<File RelativePath="..\..\common\file.cpp" />
 			<File RelativePath="..\..\common\file.h" />
@@ -347,6 +350,8 @@
 		</Filter>
 		<Filter Name="graphics">
 			<File RelativePath="..\..\graphics\colormasks.h" />
+			<File RelativePath="..\..\graphics\conversion.cpp" />
+			<File RelativePath="..\..\graphics\conversion.h" />
 			<File RelativePath="..\..\graphics\cursorman.cpp" />
 			<File RelativePath="..\..\graphics\cursorman.h" />
 			<File RelativePath="..\..\graphics\dither.cpp" />
@@ -357,6 +362,8 @@
 			<File RelativePath="..\..\graphics\fontman.h" />
 			<File RelativePath="..\..\graphics\iff.cpp" />
 			<File RelativePath="..\..\graphics\iff.h" />
+			<File RelativePath="..\..\graphics\jpeg.cpp" />
+			<File RelativePath="..\..\graphics\jpeg.h" />
 			<File RelativePath="..\..\graphics\imagedec.cpp" />
 			<File RelativePath="..\..\graphics\imagedec.h" />
 			<File RelativePath="..\..\graphics\pixelformat.h" />

Modified: scummvm/trunk/engines/cine/pal.h
===================================================================
--- scummvm/trunk/engines/cine/pal.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/cine/pal.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -36,18 +36,19 @@
 #define kLowPalNumBytes ((kLowPalNumColors) * (kLowPalBytesPerColor))
 
 /*! \brief Low resolution (9-bit) color format used in Cine's 16-color modes. */
-static const Graphics::PixelFormat kLowPalFormat  = {kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0};
+	static const Graphics::PixelFormat kLowPalFormat(kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0);
 
+
 // Constants related to kHighPalFormat
 #define kHighPalBytesPerColor 3
 #define kHighPalNumColors 256
 #define kHighPalNumBytes ((kHighPalNumColors) * (kHighPalBytesPerColor))
 
 /*! \brief High resolution (24-bit) color format used in Cine's 256-color modes. */
-static const Graphics::PixelFormat kHighPalFormat = {kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0};
+static const Graphics::PixelFormat kHighPalFormat(kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0);
 
 /*! \brief The color format used by OSystem's setPalette-function. */
-static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0};
+static const Graphics::PixelFormat kSystemPalFormat(4, 0, 0, 0, 8, 0, 8, 16, 0);
 
 /*! \brief Endian types. Used at least by Palette class's load and save functions.
  * TODO: Move somewhere more general as this is definitely not Cine-engine specific

Modified: scummvm/trunk/engines/engine.cpp
===================================================================
--- scummvm/trunk/engines/engine.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/engine.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -125,11 +125,21 @@
 		g_system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen"));
 }
 
-void initGraphics(int width, int height, bool defaultTo1xScaler) {
+void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format) {
+
 	g_system->beginGFXTransaction();
 
 		initCommonGFX(defaultTo1xScaler);
+#ifdef ENABLE_RGB_COLOR
+		if (format)
+			g_system->initSize(width, height, format);
+		else { 
+			Graphics::PixelFormat Format = g_system->getSupportedFormats().front();
+			g_system->initSize(width, height, &Format);
+		}
+#else
 		g_system->initSize(width, height);
+#endif
 
 	OSystem::TransactionError gfxError = g_system->endGFXTransaction();
 
@@ -150,6 +160,15 @@
 	}
 
 	// Just show warnings then these occur:
+#ifdef ENABLE_RGB_COLOR
+	if (gfxError & OSystem::kTransactionFormatNotSupported) {
+		Common::String message = "Could not initialize color format.";
+
+		GUI::MessageDialog dialog(message);
+		dialog.runModal();
+	}
+#endif
+
 	if (gfxError & OSystem::kTransactionModeSwitchFailed) {
 		Common::String message = "Could not switch to video mode: '";
 		message += ConfMan.get("gfx_mode");
@@ -169,6 +188,14 @@
 		dialog.runModal();
 	}
 }
+void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList) {
+	Graphics::PixelFormat format = Graphics::findCompatibleFormat(g_system->getSupportedFormats(),formatList);
+	initGraphics(width,height,defaultTo1xScaler,&format);
+}
+void initGraphics(int width, int height, bool defaultTo1xScaler) {
+	Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
+	initGraphics(width,height,defaultTo1xScaler,&format);
+}
 
 void GUIErrorMessage(const Common::String msg) {
 	g_system->setWindowCaption("Error");

Modified: scummvm/trunk/engines/engine.h
===================================================================
--- scummvm/trunk/engines/engine.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/engine.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -29,6 +29,7 @@
 #include "common/error.h"
 #include "common/fs.h"
 #include "common/str.h"
+#include "graphics/pixelformat.h"
 
 class OSystem;
 
@@ -58,8 +59,14 @@
  *
  * Errors out when backend is not able to switch to the specified
  * mode.
+ *
+ * Defaults to 256 color paletted mode if no graphics format is provided.
+ * Uses the backend's preferred format if graphics format pointer is NULL.
+ * Finds the best compatible format if a list of graphics formats is provided.
  */
 void initGraphics(int width, int height, bool defaultTo1xScaler);
+void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format);
+void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList);
 
 /**
  * Initializes graphics and shows error message.

Modified: scummvm/trunk/engines/sci/gfx/gfx_driver.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_driver.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_driver.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -27,18 +27,19 @@
 #include "common/system.h"
 #include "graphics/cursorman.h"
 #include "graphics/primitives.h"
+#include "graphics/surface.h"
 
 #include "sci/sci.h"
 #include "sci/gfx/gfx_driver.h"
 #include "sci/gfx/gfx_tools.h"
 
+
 namespace Sci {
 
-GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) {
+GfxDriver::GfxDriver(int xfact, int yfact, Graphics::PixelFormat format) {
 	int i;
 
-	Graphics::PixelFormat format = { bytespp, 0, 0, 0, 0, 0, 0, 0, 0 };
-	_mode = gfx_new_mode(xfact, yfact, format, new Palette(256), 0);
+	_mode = gfx_new_mode(xfact, yfact, format, format.bytesPerPixel == 1 ? new Palette(256) : 0, 0);
 	_mode->xsize = xfact * 320;
 	_mode->ysize = yfact * 200;
 
@@ -51,14 +52,15 @@
 	// create the visual buffers
 	for (i = 0; i < 2; i++) {
 		_visual[i] = NULL;
-		_visual[i] = new byte[_mode->xsize * _mode->ysize];
+		_visual[i] = new byte[_mode->xsize * _mode->ysize * _mode->bytespp];
 		if (!_visual[i]) {
 			error("Out of memory: Could not allocate visual buffers! (%dx%d)\n", _mode->xsize, _mode->ysize);
 		}
-		memset(_visual[i], 0, _mode->xsize * _mode->ysize);
+		memset(_visual[i], 0, _mode->xsize * _mode->ysize * _mode->bytespp);
 	}
 
-	_mode->palette->name = "global";
+	if (_mode->palette)
+		_mode->palette->name = "global";
 }
 
 GfxDriver::~GfxDriver() {
@@ -77,10 +79,12 @@
 
 // Drawing operations
 
+template<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET>
 static void drawProc(int x, int y, int c, void *data) {
 	GfxDriver *drv = (GfxDriver *)data;
 	byte *p = drv->getVisual0();
-	p[y * 320* drv->getMode()->xfact + x] = c;
+	SIZETYPE col = c << (EXTRA_BYTE_OFFSET * 8);
+	memcpy(p + (y * 320* drv->getMode()->xfact + x) * COPY_BYTES, &col, COPY_BYTES);
 }
 
 int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color, 
@@ -91,6 +95,28 @@
 	int xsize = _mode->xsize;
 	int ysize = _mode->ysize;
 
+	void (*modeDrawProc)(int,int,int,void*);
+	switch (_mode->bytespp) {
+	case 1:
+		modeDrawProc = drawProc<1, uint8, 0>;
+		break;
+	case 2:
+		modeDrawProc = drawProc<2, uint16, 0>;
+		break;
+	case 3:
+#ifdef SCUMM_BIG_ENDIAN
+		modeDrawProc = drawProc<3, uint32, 1>;
+#else
+		modeDrawProc = drawProc<3, uint32, 0>;
+#endif
+		break;
+	case 4:
+		modeDrawProc = drawProc<4, uint32, 0>;
+		break;
+	default:
+		error("Invalid mode->bytespp=%d", _mode->bytespp);
+	}
+
 	if (color.mask & GFX_MASK_VISUAL) {
 		Common::Point nstart, nend;
 
@@ -102,7 +128,7 @@
 				nend.x = CLIP<int16>(end.x + xc, 0, xsize - 1);
 				nend.y = CLIP<int16>(end.y + yc, 0, ysize - 1);
 
-				Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, drawProc, this);
+				Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, modeDrawProc, this);
 
 				if (color.mask & GFX_MASK_PRIORITY) {
 					gfx_draw_line_pixmap_i(_priority[0], nstart, nend, color.priority);
@@ -118,7 +144,8 @@
 	gfx_rectangle_fill_t shade_mode) {
 	if (color1.mask & GFX_MASK_VISUAL) {
 		for (int i = rect.y; i < rect.y + rect.height; i++) {
-			memset(_visual[0] + i * _mode->xsize + rect.x, color1.visual.parent_index, rect.width);
+			memset(_visual[0] + (i * _mode->xsize + rect.x) * _mode->bytespp,
+			       color1.visual.parent_index, rect.width * _mode->bytespp);
 		}
 	}
 
@@ -138,8 +165,10 @@
 		return GFX_ERROR;
 	}
 
-	gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr], _mode->xsize,
-	                     _priority[bufnr]->index_data, _priority[bufnr]->index_width, 1, 0);
+	gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr],
+	                     _mode->xsize * _mode->bytespp,
+	                     _priority[bufnr]->index_data,
+	                     _priority[bufnr]->index_width, 1, 0);
 
 	return GFX_OK;
 }
@@ -161,7 +190,9 @@
 		pxm->width = src.width;
 		pxm->height = src.height;
 		for (int i = 0; i < src.height; i++) {
-			memcpy(pxm->data + i * src.width, _visual[0] + (i + src.y) * _mode->xsize + src.x, src.width);
+			memcpy(pxm->data + i * src.width * _mode->bytespp,
+			       _visual[0] + _mode->bytespp * ((i + src.y) * _mode->xsize + src.x),
+			       src.width * _mode->bytespp);
 		}
 		break;
 
@@ -193,17 +224,18 @@
 	switch (buffer) {
 	case GFX_BUFFER_BACK:
 		for (int i = 0; i < src.height; i++) {
-			memcpy(_visual[0] + (dest.y + i) * _mode->xsize + dest.x,
-			       _visual[1] + (src.y + i) * _mode->xsize + src.x, src.width);
+			memcpy(_visual[0] + _mode->bytespp * ( (dest.y + i) * _mode->xsize + dest.x),
+			       _visual[1] + _mode->bytespp * ( (src.y + i) * _mode->xsize + src.x), src.width * _mode->bytespp );
 		}
 
 		if ((src.x == dest.x) && (src.y == dest.y))
 			gfx_copy_pixmap_box_i(_priority[0], _priority[1], src);
 		break;
-	case GFX_BUFFER_FRONT:
-		g_system->copyRectToScreen(_visual[0] + src.x + src.y * _mode->xsize, _mode->xsize, dest.x, dest.y, src.width, src.height);
+	case GFX_BUFFER_FRONT: {
+		g_system->copyRectToScreen(_visual[0] + _mode->bytespp * (src.x + src.y * _mode->xsize), _mode->xsize * _mode->bytespp, dest.x, dest.y, src.width, src.height);
 		g_system->updateScreen();
 		break;
+	}
 	default:
 		error("Invalid buffer %d in update", buffer);
 		return GFX_ERROR;
@@ -213,7 +245,7 @@
 }
 
 int GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) {
-	memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize);
+	memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize * _mode->bytespp);
 	gfx_copy_pixmap_box_i(_priority[1], priority, gfx_rect(0, 0, _mode->xsize, _mode->ysize));
 
 	return GFX_OK;

Modified: scummvm/trunk/engines/sci/gfx/gfx_driver.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_driver.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_driver.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -29,6 +29,8 @@
 #include "sci/gfx/gfx_system.h"
 #include "sci/uinput.h"
 
+#include "graphics/pixelformat.h"
+
 namespace Sci {
 
 enum gfx_buffer_t {
@@ -85,7 +87,7 @@
 	 * 						not be set, or GFX_FATAL if the graphics target
 	 * 						is unuseable.
 	 */
-	GfxDriver(int xfact, int yfact, int bytespp);
+	GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode);
 
 	/**
 	 * Uninitializes the current graphics mode.

Modified: scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -70,14 +70,11 @@
 	// Calculate all colors
 	for (i = 0; i < pxm->colors_nr(); i++) {
 		int col;
-
 		const PaletteEntry& color = pxm->palette->getColor(i);
 		if (mode->palette)
 			col = color.parent_index;
 		else {
-			col = mode->red_mask & ((EXTEND_COLOR(color.r)) >> mode->red_shift);
-			col |= mode->green_mask & ((EXTEND_COLOR(color.g)) >> mode->green_shift);
-			col |= mode->blue_mask & ((EXTEND_COLOR(color.b)) >> mode->blue_shift);
+			col = mode->format.ARGBToColor(0, color.r, color.g, color.b);
 			col |= alpha_ormask;
 		}
 		result_colors[i] = col;

Modified: scummvm/trunk/engines/sci/gfx/gfx_resmgr.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_resmgr.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_resmgr.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -269,7 +269,8 @@
 	_staticPalette = newPalette;
 	_staticPalette->name = "static palette";
 
-	_staticPalette->mergeInto(_driver->getMode()->palette);
+	if (_driver->getMode()->palette)
+		_staticPalette->mergeInto(_driver->getMode()->palette);
 }
 
 #if 0
@@ -320,7 +321,8 @@
 	/* palette */ NULL,
 
 	/* color masks */ 0, 0, 0, 0,
-	/* color shifts */ 0, 0, 0, 0
+	/* color shifts */ 0, 0, 0, 0,
+	Graphics::PixelFormat()
 };
 
 gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) {

Modified: scummvm/trunk/engines/sci/gfx/gfx_system.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_system.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_system.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -30,6 +30,7 @@
 #include "common/rect.h"
 #include "sci/tools.h"
 #include "sci/gfx/palette.h"
+#include "graphics/pixelformat.h"
 
 namespace Sci {
 
@@ -74,8 +75,10 @@
 	 */
 	Palette *palette;
 
+	// TODO: remove those
 	uint32 red_mask, green_mask, blue_mask, alpha_mask;
 	short red_shift, green_shift, blue_shift, alpha_shift;
+	Graphics::PixelFormat format;
 };
 
 

Modified: scummvm/trunk/engines/sci/gfx/gfx_tools.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_tools.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/gfx_tools.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -49,6 +49,7 @@
 	mode->xfact = xfact;
 	mode->yfact = yfact;
 	mode->bytespp = format.bytesPerPixel;
+	mode->format = format;
 
 	// FIXME: I am not sure whether the following assignments are quite right.
 	// The only code using these are the built-in scalers of the SCI engine.
@@ -60,10 +61,10 @@
 		mode->green_mask = format.ARGBToColor(0, 0, 0xFF, 0);
 		mode->blue_mask = format.ARGBToColor(0, 0, 0, 0xFF);
 		mode->alpha_mask = format.ARGBToColor(0xFF, 0, 0, 0);
-		mode->red_shift = format.rLoss;
-		mode->green_shift = format.gLoss;
-		mode->blue_shift = format.bLoss;
-		mode->alpha_shift = format.aLoss;
+		mode->red_shift = format.rShift;
+		mode->green_shift = format.gShift;
+		mode->blue_shift = format.bShift;
+		mode->alpha_shift = format.aShift;
 	} else {
 		mode->red_mask = mode->green_mask = mode->blue_mask = 0;
 		mode->alpha_mask = 0;

Modified: scummvm/trunk/engines/sci/gfx/operations.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/operations.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/operations.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -404,8 +404,9 @@
 	(*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR);
 }
 
-int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceManager *resManager,
-			   int xfact, int yfact, gfx_color_mode_t bpp) {
+int gfxop_init(int version, GfxState *state,
+				gfx_options_t *options, ResourceManager *resManager,
+				Graphics::PixelFormat mode, int xfact, int yfact) {
 	//int color_depth = bpp ? bpp : 1;
 	//int initialized = 0;
 
@@ -421,7 +422,7 @@
 	state->pic_port_bounds = gfx_rect(0, 10, 320, 190);
 	state->_dirtyRects.clear();
 
-	state->driver = new GfxDriver(xfact, yfact, bpp);
+	state->driver = new GfxDriver(xfact, yfact, mode);
 
 	state->gfxResMan = new GfxResManager(state->options, state->driver, resManager);
 	
@@ -1131,8 +1132,10 @@
 	// may change when a new PIC is loaded. The cursor has to be regenerated
 	// from this pxm at that point. (An alternative might be to ensure the
 	// cursor only uses colours in the static part of the palette?)
-	if (pxm && pxm->palette)
+	if (pxm && state->driver->getMode()->palette) {
+		assert(pxm->palette);
 		pxm->palette->mergeInto(state->driver->getMode()->palette);
+	}
 	state->driver->setPointer(pxm, hotspot);
 
 	return GFX_OK;
@@ -1736,7 +1739,7 @@
 	if (state->driver->getMode()->xfact == 1 && state->driver->getMode()->yfact == 1) {
 		state->pic_unscaled = state->pic;
 	} else {
-		state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false);
+		state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false);
 	}
 
 	if (!state->pic || !state->pic_unscaled) {

Modified: scummvm/trunk/engines/sci/gfx/operations.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/operations.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/operations.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -138,17 +138,16 @@
  * @param[in] state			The state to initialize
  * @param[in] xfact			Horizontal scale factor
  * @param[in] yfact			Vertical scale factors
- * @param[in] bpp			Bytes per pixel to initialize with, or 0
- * 							(GFX_COLOR_MODE_AUTO) to auto-detect
+ * @param[in] mode			Graphics mode to use
  * @param[in] options		Rendering options
  * @param[in] resManager	Resource manager to use
  * @return					GFX_OK on success, GFX_ERROR if that particular mode
  * 							is unavailable, or GFX_FATAL if the graphics driver
  * 							is unable to provide any useful graphics support
  */
-int gfxop_init(int version, GfxState *state, gfx_options_t *options,
-	ResourceManager *resManager, int xfact = 1, int yfact = 1,
-	gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX);
+int gfxop_init(int version, GfxState *state, 
+		gfx_options_t *options, ResourceManager *resManager,
+		Graphics::PixelFormat mode, int xfact = 1, int yfact = 1);
 
 /**
  * Deinitializes a currently active driver.

Modified: scummvm/trunk/engines/sci/gfx/res_pic.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/res_pic.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/gfx/res_pic.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1552,7 +1552,7 @@
 				view->index_height = CLIP<int>(view->index_height, 0, portBounds.height());
 
 				// Set up mode structure for resizing the view
-				Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1byte/p, which handles masks and the rest for us
+				Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1byte/p, which handles masks and the rest for us
 				gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320,
 				           pic->visual_map->index_height / 200, format, view->palette, 0);
 
@@ -1658,7 +1658,7 @@
 		view->palette = pic->visual_map->palette->getref();
 
 		// Set up mode structure for resizing the view
-		Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1 byte/p, which handles masks and the rest for us
+		Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1 byte/p, which handles masks and the rest for us
 		gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0);
 
 		gfx_xlate_pixmap(view, mode, GFX_XLATE_FILTER_NONE);

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -111,7 +111,13 @@
 }
 
 Common::Error SciEngine::run() {
+	Graphics::PixelFormat gfxmode;
+#ifdef ENABLE_RGB_COLOR
+	initGraphics(320, 200, false, NULL);
+#else
 	initGraphics(320, 200, false);
+#endif
+	gfxmode = _system->getScreenFormat();
 
 	// Create debugger console. It requires GFX to be initialized
 	_console = new Console(this);
@@ -190,7 +196,7 @@
 	// Default config ends
 #endif
 
-	if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr)) {
+	if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) {
 		warning("Graphics initialization failed. Aborting...");
 		return Common::kUnknownError;
 	}

Modified: scummvm/trunk/engines/scumm/actor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/actor.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/actor.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -2451,7 +2451,7 @@
 					uint8 *dst2 = pvs->getBackPixels(0, pvs->topline);
 					switch (comp) {
 					case 1:
-						Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->w, pvs->h, x, y, w, h);
+						Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->pitch, pvs->h, x, y, w, h, _bitDepth);
 						break;
 					default:
 						error("unimplemented compression type %d", comp);
@@ -2551,9 +2551,10 @@
 		MKLINE(Actor, _flip, sleByte, VER(32)),
 		MKLINE(Actor, _heSkipLimbs, sleByte, VER(32)),
 
-		// Actor palette grew from 64 to 256 bytes
+		// Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
 		MKARRAY_OLD(Actor, _palette[0], sleByte, 64, VER(8), VER(9)),
-		MKARRAY(Actor, _palette[0], sleByte, 256, VER(10)),
+		MKARRAY_OLD(Actor, _palette[0], sleByte, 256, VER(10), VER(79)),
+		MKARRAY(Actor, _palette[0], sleUint16, 256, VER(80)),
 
 		MK_OBSOLETE(Actor, _mask, sleByte, VER(8), VER(9)),
 		MKLINE(Actor, _shadowMode, sleByte, VER(8)),

Modified: scummvm/trunk/engines/scumm/actor.h
===================================================================
--- scummvm/trunk/engines/scumm/actor.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/actor.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -157,7 +157,7 @@
 	};
 
 
-	byte _palette[256];
+	uint16 _palette[256];
 	int _elevation;
 	uint16 _facing;
 	uint16 _targetFacing;

Modified: scummvm/trunk/engines/scumm/akos.cpp
===================================================================
--- scummvm/trunk/engines/scumm/akos.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/akos.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -289,7 +289,7 @@
 	} while ((uint16)mask);
 }
 
-void AkosRenderer::setPalette(byte *new_palette) {
+void AkosRenderer::setPalette(uint16 *new_palette) {
 	uint size, i;
 
 	size = _vm->getResourceDataSize(akpl);
@@ -299,22 +299,23 @@
 	if (size > 256)
 		error("akos_setPalette: %d is too many colors", size);
 
-	if (_vm->_game.heversion >= 99 && _paletteNum) {
-		for (i = 0; i < size; i++)
-			_palette[i] = (byte)_vm->_hePalettes[_paletteNum * 1024 + 768 + akpl[i]];
-	} else if ((_vm->_game.features & GF_16BIT_COLOR) && rgbs) {
-		for (i = 0; i < size; i++) {
-			if (new_palette[i] == 0xFF) {
-				uint8 col = akpl[i];
-				uint8 r = rgbs[col * 3 + 0];
-				uint8 g = rgbs[col * 3 + 1];
-				uint8 b = rgbs[col * 3 + 2];
-
-				_palette[i] = _vm->remapPaletteColor(r, g, b, -1);
-			} else {
-				_palette[i] = new_palette[i];
+	if (_vm->_game.features & GF_16BIT_COLOR) {
+		if (_paletteNum) {
+			for (i = 0; i < size; i++)
+				_palette[i] = READ_LE_UINT16(_vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768 + akpl[i] * 2);
+		} else if (rgbs) {
+			for (i = 0; i < size; i++) {
+				if (new_palette[i] == 0xFF) {
+					uint8 col = akpl[i];
+					_palette[i] = _vm->get16BitColor(rgbs[col * 3 + 0], rgbs[col * 3 + 1], rgbs[col * 3 + 2]);
+				} else {
+					_palette[i] = new_palette[i];
+				}
 			}
 		}
+	} else if (_vm->_game.heversion >= 99 && _paletteNum) {
+		for (i = 0; i < size; i++)
+			_palette[i] = (byte)_vm->_hePalettes[_paletteNum * _vm->_hePaletteSlot + 768 + akpl[i]];
 	} else {
 		for (i = 0; i < size; i++) {
 			_palette[i] = new_palette[i] != 0xFF ? new_palette[i] : akpl[i];
@@ -545,7 +546,7 @@
 	byte *dst;
 	byte len, maskbit;
 	int y;
-	uint color, height, pcolor;
+	uint16 color, height, pcolor;
 	const byte *scaleytab;
 	bool masked;
 	bool skip_column = false;
@@ -589,7 +590,11 @@
 						} else if (_shadow_mode == 2) {
 							error("codec1_spec2"); // TODO
 						} else if (_shadow_mode == 3) {
-							if (_vm->_game.heversion >= 90) {
+							if (_vm->_game.features & GF_16BIT_COLOR) {
+								uint16 srcColor = (pcolor >> 1) & 0x7DEF;
+								uint16 dstColor = (READ_UINT16(dst) >> 1) & 0x7DEF;
+								pcolor = srcColor + dstColor;
+							} else if (_vm->_game.heversion >= 90) {
 								pcolor = (pcolor << 8) + *dst;
 								pcolor = xmap[pcolor];
 							} else if (pcolor < 8) {
@@ -597,7 +602,11 @@
 								pcolor = _shadow_table[pcolor];
 							}
 						}
-						*dst = pcolor;
+						if (_vm->_bitDepth == 2) {
+							WRITE_UINT16(dst, pcolor);
+						} else {
+							*dst = pcolor;
+						}
 					}
 				}
 				dst += _out.pitch;
@@ -617,7 +626,7 @@
 					if (v1.x < 0 || v1.x >= v1.boundsRect.right)
 						return;
 					maskbit = revBitMask(v1.x & 7);
-					v1.destptr += v1.scaleXstep;
+					v1.destptr += v1.scaleXstep * _vm->_bitDepth;
 					skip_column = false;
 				} else
 					skip_column = true;
@@ -987,7 +996,7 @@
 	if (_draw_bottom < rect.bottom)
 		_draw_bottom = rect.bottom;
 
-	v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x;
+	v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x * _vm->_bitDepth;
 
 	codec1_genericDecode(v1);
 
@@ -1056,7 +1065,12 @@
 	bdd.shadowMode = _shadow_mode;
 	bdd.shadowPalette = _vm->_shadowPalette;
 
-	bdd.actorPalette = _useBompPalette ? _palette : 0;
+	bdd.actorPalette = 0;
+	if (_useBompPalette) {
+		for (uint i = 0; i < 256; i++)
+			bdd.actorPalette[i] = _palette[i];
+ 	}
+
 	bdd.mirror = !_mirror;
 
 	drawBomp(bdd);
@@ -1176,6 +1190,8 @@
 }
 
 byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
+	assert(_vm->_bitDepth == 1);
+
 	Common::Rect clip;
 	int32 minx, miny, maxw, maxh;
 	int32 skip_x, skip_y, cur_x, cur_y;
@@ -1278,7 +1294,7 @@
 	int32 numskip_before = skip_x + (skip_y * _width);
 	int32 numskip_after = _width - cur_x;
 
-	byte *dst = (byte *)_out.pixels + width_unk + height_unk * _out.pitch;
+	byte *dst = (byte *)_out.pixels + height_unk * _out.pitch + width_unk * _vm->_bitDepth;
 
 	akos16Decompress(dst, _out.pitch, _srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, clip.left, clip.top, _zbuf);
 	return 0;
@@ -1335,18 +1351,27 @@
 		_draw_bottom = dst.bottom;
 
 	const uint8 *palPtr = NULL;
-	if (_vm->_game.heversion >= 99) {
-		palPtr = _vm->_hePalettes + 1792;
+	if (_vm->_game.features & GF_16BIT_COLOR) {
+		palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
+		if (_paletteNum) {
+			palPtr = _vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768;
+		} else if (rgbs) {
+			for (uint i = 0; i < 256; i++)
+				WRITE_LE_UINT16(_palette + i, _vm->get16BitColor(rgbs[i * 3 + 0], rgbs[i * 3 + 1], rgbs[i * 3 + 2]));
+			palPtr = (uint8 *)_palette;
+		}
+	} else if (_vm->_game.heversion >= 99) {
+		palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
 	}
 
-	byte *dstPtr = (byte *)_out.pixels + dst.left + dst.top * _out.pitch;
+	byte *dstPtr = (byte *)_out.pixels + dst.top * _out.pitch + dst.left * _vm->_bitDepth;
 	if (_shadow_mode == 3) {
-		Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr, xmap);
+		Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, xmap, _vm->_bitDepth);
 	} else {
 		if (palPtr != NULL) {
-			Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr);
+			Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, NULL, _vm->_bitDepth);
 		} else {
-			Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, _srcptr, src, 0);
+			Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, NULL, NULL, _vm->_bitDepth);
 		}
 	}
 #endif

Modified: scummvm/trunk/engines/scumm/akos.h
===================================================================
--- scummvm/trunk/engines/scumm/akos.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/akos.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -60,7 +60,7 @@
 	uint16 _codec;
 
 	// actor _palette
-	byte _palette[256];
+	uint16 _palette[256];
 	bool _useBompPalette;
 
 	// pointer to various parts of the costume resource
@@ -107,7 +107,7 @@
 	int16 _actorHitX, _actorHitY;
 	bool _actorHitResult;
 
-	void setPalette(byte *_palette);
+	void setPalette(uint16 *_palette);
 	void setFacing(const Actor *a);
 	void setCostume(int costume, int shadow);
 

Modified: scummvm/trunk/engines/scumm/base-costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/base-costume.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/base-costume.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -40,7 +40,7 @@
 		_out.pixels = vs.getPixels(0, 0);
 
 	_actorX += _vm->_virtscr[kMainVirtScreen].xstart & 7;
-	_out.w = _out.pitch;
+	_out.w = _out.pitch / _vm->_bitDepth;
 	_out.pixels = (byte *)_out.pixels - (_vm->_virtscr[kMainVirtScreen].xstart & 7);
 
 	_numStrips = numStrips;

Modified: scummvm/trunk/engines/scumm/base-costume.h
===================================================================
--- scummvm/trunk/engines/scumm/base-costume.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/base-costume.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -145,7 +145,7 @@
 	}
 	virtual ~BaseCostumeRenderer() {}
 
-	virtual void setPalette(byte *palette) = 0;
+	virtual void setPalette(uint16 *palette) = 0;
 	virtual void setFacing(const Actor *a) = 0;
 	virtual void setCostume(int costume, int shadow) = 0;
 

Modified: scummvm/trunk/engines/scumm/charset.cpp
===================================================================
--- scummvm/trunk/engines/scumm/charset.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/charset.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -819,9 +819,9 @@
 			byte imagePalette[256];
 			memset(imagePalette, 0, sizeof(imagePalette));
 			memcpy(imagePalette, _vm->_charsetColorMap, 4);
-			Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette);
+			Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette, NULL, _vm->_bitDepth);
 		} else {
-			Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen);
+			Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, NULL, NULL, _vm->_bitDepth);
 		}
 
 		if (_blitAlso && vs->hasTwoBuffers) {

Modified: scummvm/trunk/engines/scumm/costume.cpp
===================================================================
--- scummvm/trunk/engines/scumm/costume.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/costume.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -791,7 +791,7 @@
 
 }
 
-void NESCostumeRenderer::setPalette(byte *palette) {
+void NESCostumeRenderer::setPalette(uint16 *palette) {
 	// TODO
 }
 
@@ -874,17 +874,20 @@
 	} while (mask&0xFFFF);
 }
 
-void ClassicCostumeRenderer::setPalette(byte *palette) {
+void ClassicCostumeRenderer::setPalette(uint16 *palette) {
 	int i;
 	byte color;
 
 	if (_loaded._format == 0x57) {
-		memcpy(_palette, palette, 13);
+		for (i = 0; i < 13; i++)
+			_palette[i] = palette[i];
 	} else if (_vm->_game.features & GF_OLD_BUNDLE) {
 		if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) {
-			memcpy(_palette, palette, 16);
+			for (i = 0; i < 16; i++)
+				_palette[i] = palette[i];
 		} else {
-			memset(_palette, 8, 16);
+			for (i = 0; i < 16; i++)
+				_palette[i] = 8;
 			_palette[12] = 0;
 		}
 		_palette[_loaded._palette[0]] = _palette[0];

Modified: scummvm/trunk/engines/scumm/costume.h
===================================================================
--- scummvm/trunk/engines/scumm/costume.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/costume.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -98,7 +98,7 @@
 public:
 	ClassicCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
 
-	void setPalette(byte *palette);
+	void setPalette(uint16 *palette);
 	void setFacing(const Actor *a);
 	void setCostume(int costume, int shadow);
 
@@ -120,7 +120,7 @@
 public:
 	NESCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
 
-	void setPalette(byte *palette);
+	void setPalette(uint16 *palette);
 	void setFacing(const Actor *a);
 	void setCostume(int costume, int shadow);
 
@@ -135,7 +135,7 @@
 public:
 	C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
 
-	void setPalette(byte *palette) {}
+	void setPalette(uint16 *palette) {}
 	void setFacing(const Actor *a) {}
 	void setCostume(int costume, int shadow);
 

Modified: scummvm/trunk/engines/scumm/cursor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/cursor.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/cursor.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -111,11 +111,20 @@
 }
 
 void ScummEngine::updateCursor() {
-	const int transColor = (_game.heversion >= 80) ? 5 : 255;
+	int transColor = (_game.heversion >= 80) ? 5 : 255;
+#ifdef ENABLE_RGB_COLOR
+	Graphics::PixelFormat format = _system->getScreenFormat();
 	CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
 							_cursor.hotspotX, _cursor.hotspotY,
 							(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
+							(_game.heversion == 70 ? 2 : 1),
+							&format);
+#else
+	CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
+							_cursor.hotspotX, _cursor.hotspotY,
+							(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
 							(_game.heversion == 70 ? 2 : 1));
+#endif
 }
 
 void ScummEngine_v6::grabCursor(int x, int y, int w, int h) {
@@ -138,7 +147,7 @@
 	uint size;
 	byte *dst;
 
-	size = width * height;
+	size = width * height * _bitDepth;
 	if (size > sizeof(_grabbedCursor))
 		error("grabCursor: grabbed cursor too big");
 
@@ -148,8 +157,8 @@
 
 	dst = _grabbedCursor;
 	for (; height; height--) {
-		memcpy(dst, ptr, width);
-		dst += width;
+		memcpy(dst, ptr, width * _bitDepth);
+		dst += width * _bitDepth;
 		ptr += pitch;
 	}
 
@@ -166,9 +175,14 @@
 	static const byte palette[] = {0,    0,    0,    0,
 								   0xff, 0xff, 0xff, 0,
 								   0,    0,    0,    0};
+	
+	if (_bitDepth == 2) {
+		for (i = 0; i < 1024; i++)
+			WRITE_UINT16(_grabbedCursor + i * 2, 5);
+	} else {
+		memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
+	}
 
-	memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
-
 	_cursor.hotspotX = _cursor.hotspotY = 2;
 	src = default_he_cursor;
 
@@ -180,10 +194,16 @@
 		for (j = 0; j < 32; j++) {
 			switch ((p & (0x3 << 14)) >> 14) {
 				case 1:
-					_grabbedCursor[32 * i + j] = 0xfe;
+					if (_bitDepth == 2)
+						WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[4], palette[5], palette[6]));
+					else
+						_grabbedCursor[32 * i + j] = 0xfe;
 					break;
 				case 2:
-					_grabbedCursor[32 * i + j] = 0xfd;
+					if (_bitDepth == 2)
+						WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[0], palette[1], palette[2]));
+					else
+						_grabbedCursor[32 * i + j] = 0xfd;
 					break;
 				default:
 					break;
@@ -195,9 +215,11 @@
 		}
 	}
 
-	// Since white color position is not guaranteed
-	// we setup our own palette if supported by backend
-	CursorMan.replaceCursorPalette(palette, 0xfd, 3);
+	if (_bitDepth == 1) {
+		// Since white color position is not guaranteed
+		// we setup our own palette if supported by backend
+		CursorMan.replaceCursorPalette(palette, 0xfd, 3);
+	}
 
 	updateCursor();
 }

Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/gfx.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -43,12 +43,12 @@
 
 namespace Scumm {
 
-static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
-static void fill(byte *dst, int dstPitch, byte color, int w, int h);
+static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth);
+static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth);
 #ifndef USE_ARM_GFX_ASM
-static void copy8Col(byte *dst, int dstPitch, const byte *src, int height);
+static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth);
 #endif
-static void clear8Col(byte *dst, int dstPitch, int height);
+static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth);
 
 static void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height);
 static void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
@@ -231,6 +231,9 @@
 	free(_roomStrips);
 }
 
+Gdi16Bit::Gdi16Bit(ScummEngine *vm) : Gdi(vm) {
+}
+
 void Gdi::init() {
 	_numStrips = _vm->_screenWidth / 8;
 
@@ -341,8 +344,8 @@
 	vs->hasTwoBuffers = twobufs;
 	vs->xstart = 0;
 	vs->backBuf = NULL;
-	vs->bytesPerPixel = 1;
-	vs->pitch = width;
+	vs->bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+	vs->pitch = width * vs->bytesPerPixel;
 
 	if (_game.version >= 7) {
 		// Increase the pitch by one; needed to accomodate the extra screen
@@ -586,7 +589,7 @@
 		vsPitch = _screenWidth * m - width * m;
 
 	} else {
-		vsPitch = vs->pitch - width;
+		vsPitch = vs->pitch - width * vs->bytesPerPixel;
 	}
 
 
@@ -612,36 +615,49 @@
 #else
 		// We blit four pixels at a time, for improved performance.
 		const uint32 *src32 = (const uint32 *)src;
-		const uint32 *text32 = (const uint32 *)text;
 		uint32 *dst32 = (uint32 *)_compositeBuf;
 
 		vsPitch >>= 2;
-		const int textPitch = (_textSurface.pitch - width * m) >> 2;
-		for (int h = height * m; h > 0; --h) {
-			for (int w = width*m; w > 0; w-=4) {
-				uint32 temp = *text32++;
 
-				// Generate a byte mask for those text pixels (bytes) with
-				// value CHARSET_MASK_TRANSPARENCY. In the end, each byte
-				// in mask will be either equal to 0x00 or 0xFF.
-				// Doing it this way avoids branches and bytewise operations,
-				// at the cost of readability ;).
-				uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32;
-				mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080;
-				mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080;
+		if (_bitDepth == 2) {
+			// Sprites always seem to be used for subtitles in 16Bit color HE games, and not
+			// the charset renderer, so charset masking isn't required.
+			for (int h = height * m; h > 0; --h) {
+				for (int w = width * m; w > 0; w -= 4) {
+					*dst32++ = *src32++;
+					*dst32++ = *src32++;
+				}
+				src32 += vsPitch;
+			}
+		} else {
+			const uint32 *text32 = (const uint32 *)text;
+			const int textPitch = (_textSurface.pitch - width * m) >> 2;
+			for (int h = height * m; h > 0; --h) {
+				for (int w = width * m; w > 0; w -= 4) {
+					uint32 temp = *text32++;
 
-				// The following line is equivalent to this code:
-				//   *dst32++ = (*src32++ & mask) | (temp & ~mask);
-				// However, some compilers can generate somewhat better
-				// machine code for this equivalent statement:
-				*dst32++ = ((temp ^ *src32++) & mask) ^ temp;
+					// Generate a byte mask for those text pixels (bytes) with
+					// value CHARSET_MASK_TRANSPARENCY. In the end, each byte
+					// in mask will be either equal to 0x00 or 0xFF.
+					// Doing it this way avoids branches and bytewise operations,
+					// at the cost of readability ;).
+					uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32;
+					mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080;
+					mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080;
+
+					// The following line is equivalent to this code:
+					//   *dst32++ = (*src32++ & mask) | (temp & ~mask);
+					// However, some compilers can generate somewhat better
+					// machine code for this equivalent statement:
+					*dst32++ = ((temp ^ *src32++) & mask) ^ temp;
+				}
+				src32 += vsPitch;
+				text32 += textPitch;
 			}
-			src32 += vsPitch;
-			text32 += textPitch;
 		}
 #endif
 		src = _compositeBuf;
-		pitch = width;
+		pitch = width * vs->bytesPerPixel;
 
 		if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
 			ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
@@ -986,13 +1002,13 @@
 		return;
 
 	if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) {
-		blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height);
+		blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->bytesPerPixel);
 		if (vs->number == kMainVirtScreen && _charset->_hasMask) {
 			byte *mask = (byte *)_textSurface.getBasePtr(rect.left, rect.top - _screenTop);
-			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height, _textSurface.bytesPerPixel);
 		}
 	} else {
-		fill(screenBuf, vs->pitch, backColor, width, height);
+		fill(screenBuf, vs->pitch, backColor, width, height, vs->bytesPerPixel);
 	}
 }
 
@@ -1021,7 +1037,7 @@
 			if (vs->number != kMainVirtScreen) {
 				// Restore from back buffer
 				const byte *backBuf = vs->getBackPixels(0, 0);
-				blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h);
+				blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h, vs->bytesPerPixel);
 			}
 		} else {
 			// Clear area
@@ -1057,34 +1073,42 @@
 #pragma mark --- Misc ---
 #pragma mark -
 
-static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
+static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth) {
 	assert(w > 0);
 	assert(h > 0);
 	assert(src != NULL);
 	assert(dst != NULL);
 
-	if (w == srcPitch && w == dstPitch) {
-		memcpy(dst, src, w*h);
+	if ((w * bitDepth == srcPitch) && (w * bitDepth == dstPitch)) {
+		memcpy(dst, src, w * h * bitDepth);
 	} else {
 		do {
-			memcpy(dst, src, w);
+			memcpy(dst, src, w * bitDepth);
 			dst += dstPitch;
 			src += srcPitch;
 		} while (--h);
 	}
 }
 
-static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
+static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth) {
 	assert(h > 0);
 	assert(dst != NULL);
 
-	if (w == dstPitch) {
-		memset(dst, color, w*h);
-	} else {
+	if (bitDepth == 2) {
 		do {
-			memset(dst, color, w);
+			for (int i = 0; i < w; i++)
+				WRITE_UINT16(dst + i * 2, color);
 			dst += dstPitch;
 		} while (--h);
+	} else {
+		if (w == dstPitch) {
+			memset(dst, color, w * h);
+		} else {
+			do {
+				memset(dst, color, w);
+				dst += dstPitch;
+			} while (--h);
+		}
 	}
 }
 
@@ -1094,14 +1118,18 @@
 
 #else
 
-static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
+static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth) {
 
 	do {
 #if defined(SCUMM_NEED_ALIGNMENT)
-		memcpy(dst, src, 8);
+		memcpy(dst, src, 8 * bitDepth);
 #else
 		((uint32 *)dst)[0] = ((const uint32 *)src)[0];
 		((uint32 *)dst)[1] = ((const uint32 *)src)[1];
+		if (bitDepth == 2) {
+			((uint32 *)dst)[2] = ((const uint32 *)src)[2];
+			((uint32 *)dst)[3] = ((const uint32 *)src)[3];
+		}
 #endif
 		dst += dstPitch;
 		src += dstPitch;
@@ -1110,13 +1138,17 @@
 
 #endif /* USE_ARM_GFX_ASM */
 
-static void clear8Col(byte *dst, int dstPitch, int height) {
+static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth) {
 	do {
 #if defined(SCUMM_NEED_ALIGNMENT)
-		memset(dst, 0, 8);
+		memset(dst, 0, 8 * bitDepth);
 #else
 		((uint32 *)dst)[0] = 0;
 		((uint32 *)dst)[1] = 0;
+		if (bitDepth == 2) {
+			((uint32 *)dst)[2] = 0;
+			((uint32 *)dst)[3] = 0;
+		}
 #endif
 		dst += dstPitch;
 	} while (--height);
@@ -1181,41 +1213,41 @@
 	if (color == -1) {
 		if (vs->number != kMainVirtScreen)
 			error("can only copy bg to main window");
-		blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
+		blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
 		if (_charset->_hasMask) {
 			byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier);
-			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier);
+			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel);
 		}
 	} else if (_game.heversion >= 72) {
 		// Flags are used for different methods in HE games
 		uint32 flags = color;
 		if ((flags & 0x2000) || (flags & 0x4000000)) {
-			blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
+			blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
 		} else if ((flags & 0x4000) || (flags & 0x2000000)) {
-			blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
+			blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel);
 		} else if ((flags & 0x8000) || (flags & 0x1000000)) {
 			flags &= (flags & 0x1000000) ? 0xFFFFFF : 0x7FFF;
-			fill(backbuff, vs->pitch, flags, width, height);
-			fill(bgbuff, vs->pitch, flags, width, height);
+			fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
+			fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
 		} else {
-			fill(backbuff, vs->pitch, flags, width, height);
+			fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
 		}
 	} else if (_game.heversion >= 60) {
 		// Flags are used for different methods in HE games
 		uint16 flags = color;
 		if (flags & 0x2000) {
-			blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
+			blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel);
 		} else if (flags & 0x4000) {
-			blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
+			blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel);
 		} else if (flags & 0x8000) {
 			flags &= 0x7FFF;
-			fill(backbuff, vs->pitch, flags, width, height);
-			fill(bgbuff, vs->pitch, flags, width, height);
+			fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
+			fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
 		} else {
-			fill(backbuff, vs->pitch, flags, width, height);
+			fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel);
 		}
 	} else {
-		fill(backbuff, vs->pitch, color, width, height);
+		fill(backbuff, vs->pitch, color, width, height, vs->bytesPerPixel);
 	}
 }
 
@@ -1253,7 +1285,7 @@
 										_flashlight.y, _flashlight.y + _flashlight.h, USAGE_BIT_DIRTY);
 
 		if (_flashlight.buffer) {
-			fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h);
+			fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h, vs->bytesPerPixel);
 		}
 		_flashlight.isDrawn = false;
 	}
@@ -1300,7 +1332,7 @@
 	_flashlight.buffer = vs->getPixels(_flashlight.x, _flashlight.y);
 	bgbak = vs->getBackPixels(_flashlight.x, _flashlight.y);
 
-	blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h);
+	blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h, vs->bytesPerPixel);
 
 	// Round the corners. To do so, we simply hard-code a set of nicely
 	// rounded corners.
@@ -1609,7 +1641,7 @@
 		warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", y + height, vs->h);
 	}
 
-	_vertStripNextInc = height * vs->pitch - 1;
+	_vertStripNextInc = height * vs->pitch - 1 * vs->bytesPerPixel;
 
 	_objectMode = (flag & dbObjectMode) == dbObjectMode;
 	prepareDrawBitmap(ptr, vs, x, y, width, height, stripnr, numstrip);
@@ -1642,9 +1674,9 @@
 		// In the case of a double buffered virtual screen, we draw to
 		// the backbuffer, otherwise to the primary surface memory.
 		if (vs->hasTwoBuffers)
-			dstPtr = vs->backBuf + y * vs->pitch + x * 8;
+			dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
 		else
-			dstPtr = (byte *)vs->pixels + y * vs->pitch + x * 8;
+			dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
 
 		transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr);
 
@@ -1653,11 +1685,11 @@
 			transpStrip = true;
 
 		if (vs->hasTwoBuffers) {
-			byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + x * 8;
+			byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel);
 			if (lightsOn)
-				copy8Col(frontBuf, vs->pitch, dstPtr, height);
+				copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->bytesPerPixel);
 			else
-				clear8Col(frontBuf, vs->pitch, height);
+				clear8Col(frontBuf, vs->pitch, height, vs->bytesPerPixel);
 		}
 
 		decodeMask(x, y, width, height, stripnr, numzbuf, zplane_list, transpStrip, flag, tmsk_ptr);
@@ -1885,7 +1917,7 @@
 		drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, true);
 		break;
 	case 150:
-		fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h);
+		fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h, vs->bytesPerPixel);
 		break;
 	default:
 		// Alternative russian freddi3 uses badly formatted bitmaps
@@ -1941,12 +1973,12 @@
 	assert(bmap_ptr);
 
 	byte code = *bmap_ptr++;
-	int scrX = _vm->_screenStartStrip * 8;
+	int scrX = _vm->_screenStartStrip * 8 * _vm->_bitDepth;
 
 	if (code == 8 || code == 9) {
 		Common::Rect rScreen(0, 0, vs->w, vs->h);
 		byte *dst = (byte *)_vm->_virtscr[kMainVirtScreen].backBuf + scrX;
-		Wiz::copyWizImage(dst, bmap_ptr, vs->w, vs->h, x - scrX, y, w, h, &rScreen);
+		Wiz::copyWizImage(dst, bmap_ptr, vs->pitch, kDstScreen, vs->w, vs->h, x - scrX, y, w, h, &rScreen, 0, 0, 0, _vm->_bitDepth);
 	}
 
 	Common::Rect rect1(x, y, x + w, y + h);
@@ -1996,7 +2028,7 @@
 
 	assert(rw <= _screenWidth && rw > 0);
 	assert(rh <= _screenHeight && rh > 0);
-	blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh);
+	blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh, vs->bytesPerPixel);
 	markRectAsDirty(kMainVirtScreen, rect, dirtybit);
 }
 #endif
@@ -2026,15 +2058,15 @@
 	if (bottom > vs->bdirty[strip])
 		vs->bdirty[strip] = bottom;
 
-	bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8;
-	backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8;
+	bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel;
+	backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel;
 
 	numLinesToProcess = bottom - top;
 	if (numLinesToProcess) {
 		if (_vm->isLightOn()) {
-			copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess);
+			copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess, vs->bytesPerPixel);
 		} else {
-			clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess);
+			clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess, vs->bytesPerPixel);
 		}
 	}
 }
@@ -2785,12 +2817,12 @@
 	int x = width;
 	while (1) {
 		if (!transpCheck || color != _transparentColor)
-			*dst = _roomPalette[color];
-		dst++;
+			writeRoomColor(dst, color);
+		dst += _vm->_bitDepth;
 		--x;
 		if (x == 0) {
 			x = width;
-			dst += dstPitch - width;
+			dst += dstPitch - width * _vm->_bitDepth;
 			--height;
 			if (height == 0)
 				return;
@@ -2874,8 +2906,8 @@
 		do {
 			FILL_BITS;
 			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
-			dst++;
+				writeRoomColor(dst, color);
+			dst += _vm->_bitDepth;
 
 		againPos:
 			if (!READ_BIT) {
@@ -2896,13 +2928,13 @@
 					do {
 						if (!--x) {
 							x = 8;
-							dst += dstPitch - 8;
+							dst += dstPitch - 8 * _vm->_bitDepth;
 							if (!--height)
 								return;
 						}
 						if (!transpCheck || color != _transparentColor)
-							*dst = _roomPalette[color] + _paletteMod;
-						dst++;
+							writeRoomColor(dst, color);
+						dst += _vm->_bitDepth;
 					} while (--reps);
 					bits >>= 8;
 					bits |= (*src++) << (cl - 8);
@@ -2910,7 +2942,7 @@
 				}
 			}
 		} while (--x);
-		dst += dstPitch - 8;
+		dst += dstPitch - 8 * _vm->_bitDepth;
 	} while (--height);
 }
 
@@ -2926,8 +2958,8 @@
 		do {
 			FILL_BITS;
 			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
-			dst++;
+				writeRoomColor(dst, color);
+			dst += _vm->_bitDepth;
 			if (!READ_BIT) {
 			} else if (!READ_BIT) {
 				FILL_BITS;
@@ -2942,7 +2974,7 @@
 				color += inc;
 			}
 		} while (--x);
-		dst += dstPitch - 8;
+		dst += dstPitch - 8 * _vm->_bitDepth;
 	} while (--height);
 }
 
@@ -2959,7 +2991,7 @@
 		do {
 			FILL_BITS;
 			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
+				writeRoomColor(dst, color);
 			dst += dstPitch;
 			if (!READ_BIT) {
 			} else if (!READ_BIT) {
@@ -3027,7 +3059,7 @@
 			for (x = 0; x < 8; x ++) {
 				byte color = *src++;
 				if (!transpCheck || color != _transparentColor)
-					dst[x] = _roomPalette[color] + _paletteMod;
+					writeRoomColor(dst + x * _vm->_bitDepth, color);
 			}
 			dst += dstPitch;
 		} while (--height);
@@ -3150,7 +3182,15 @@
 #undef NEXT_ROW
 #undef READ_BIT_256
 
+void Gdi16Bit::writeRoomColor(byte *dst, byte color) const {
+	WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+}
 
+void Gdi::writeRoomColor(byte *dst, byte color) const {
+	*dst = _roomPalette[color] + _paletteMod;
+}
+
+
 #pragma mark -
 #pragma mark --- Transition effects ---
 #pragma mark -

Modified: scummvm/trunk/engines/scumm/gfx.h
===================================================================
--- scummvm/trunk/engines/scumm/gfx.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/gfx.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -155,11 +155,11 @@
 	}
 
 	byte *getPixels(int x, int y) const {
-		return (byte *)pixels + xstart + y * pitch + x;
+		return (byte *)pixels + y * pitch + (xstart + x) * bytesPerPixel;
 	}
 
 	byte *getBackPixels(int x, int y) const {
-		return (byte *)backBuf + xstart + y * pitch + x;
+		return (byte *)backBuf + y * pitch + (xstart + x) * bytesPerPixel;
 	}
 };
 
@@ -215,6 +215,7 @@
 	void drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
 
 	void drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const;
+	virtual void writeRoomColor(byte *dst, byte color) const;
 
 	/* Mask decompressors */
 	void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const;
@@ -361,6 +362,13 @@
 	virtual void roomChanged(byte *roomptr);
 };
 
+class Gdi16Bit : public Gdi {
+protected:
+	virtual void writeRoomColor(byte *dst, byte color) const;
+public:
+	Gdi16Bit(ScummEngine *vm);
+};
+
 } // End of namespace Scumm
 
 #endif

Modified: scummvm/trunk/engines/scumm/he/animation_he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/animation_he.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/animation_he.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -66,6 +66,32 @@
 	return 0;
 }
 
+void MoviePlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
+	uint h = getHeight();
+	uint w = getWidth();
+
+	byte *src = _videoFrameBuffer;
+
+	if (_vm->_game.features & GF_16BIT_COLOR) {
+		dst += y * pitch + x * 2;
+		do {
+			for (uint i = 0; i < w; i++) {
+				uint16 col = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2);
+				WRITE_UINT16(dst + i * 2, col);
+			}
+			dst += pitch;
+			src += w;
+		} while (--h);
+	} else {
+		dst += y * pitch + x;
+		do {
+			memcpy(dst, src, w);
+			dst += pitch;
+			src += w;
+		} while (--h);
+	}
+}
+
 void MoviePlayer::handleNextFrame() {
 	if (!isVideoLoaded()) {
 		return;
@@ -80,14 +106,14 @@
 		assert(dstPtr);
 		uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
 		assert(dst);
-		copyFrameToBuffer(dst, 0, 0, _vm->_screenWidth);
+		copyFrameToBuffer(dst, 0, 0, _vm->_screenWidth * _vm->_bitDepth);
 	} else if (_flags & 1) {
-		copyFrameToBuffer(pvs->getBackPixels(0, 0), 0, 0, _vm->_screenWidth);
+		copyFrameToBuffer(pvs->getBackPixels(0, 0), 0, 0, pvs->pitch);
 
 		Common::Rect imageRect(getWidth(), getHeight());
 		_vm->restoreBackgroundHE(imageRect);
 	} else {
-		copyFrameToBuffer(pvs->getPixels(0, 0), 0, 0, _vm->_screenWidth);
+		copyFrameToBuffer(pvs->getPixels(0, 0), 0, 0, pvs->pitch);
 
 		Common::Rect imageRect(getWidth(), getHeight());
 		_vm->markRectAsDirty(kMainVirtScreen, imageRect);

Modified: scummvm/trunk/engines/scumm/he/animation_he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/animation_he.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/animation_he.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -54,6 +54,7 @@
 	int getImageNum();
 	int load(const char *filename, int flags, int image = 0);
 
+	void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
 	void handleNextFrame();
 
 protected:

Modified: scummvm/trunk/engines/scumm/he/intern_he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/intern_he.h	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/intern_he.h	2009-08-21 09:37:51 UTC (rev 43577)
@@ -458,6 +458,7 @@
 	uint8 *getHEPaletteIndex(int palSlot);
 	int getHEPaletteColor(int palSlot, int color);
 	int getHEPaletteSimilarColor(int palSlot, int red, int green, int start, int end);
+	int getHEPalette16BitColorComponent(int component, int type);
 	int getHEPaletteColorComponent(int palSlot, int color, int component);
 	void setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b);
 	void setHEPaletteFromPtr(int palSlot, const uint8 *palData);
@@ -466,7 +467,7 @@
 	void setHEPaletteFromRoom(int palSlot, int resId, int state);
 	void restoreHEPalette(int palSlot);
 	void copyHEPalette(int dstPalSlot, int srcPalSlot);
-	void copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor);
+	void copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor);
 
 protected:
 	/* HE version 90 script opcodes */

Modified: scummvm/trunk/engines/scumm/he/palette_he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/palette_he.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/palette_he.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -40,7 +40,7 @@
 	src += 30;
 
 	if (_game.heversion >= 99) {
-		palPtr = _hePalettes + 1024 + 30;
+		palPtr = _hePalettes + _hePaletteSlot + 30;
 	} else {
 		palPtr = _currentPalette + 30;
 	}
@@ -75,9 +75,9 @@
 uint8 *ScummEngine_v90he::getHEPaletteIndex(int palSlot) {
 	if (palSlot) {
 		assert(palSlot >= 1 && palSlot <= _numPalettes);
-		return _hePalettes + palSlot * 1024;
+		return _hePalettes + palSlot * _hePaletteSlot;
 	} else {
-		return _hePalettes + 1024;
+		return _hePalettes + _hePaletteSlot;
 	}
 }
 
@@ -86,7 +86,7 @@
 	assertRange(0, start, 255, "start palette slot");
 	assertRange(0, end, 255, "pend alette slot");
 
-	uint8 *pal = _hePalettes + palSlot * 1024 + start * 3;
+	uint8 *pal = _hePalettes + palSlot * _hePaletteSlot + start * 3;
 
 	int bestsum = 0x7FFFFFFF;
 	int bestitem = start;
@@ -107,40 +107,84 @@
 	return bestitem;
 }
 
+int ScummEngine_v90he::getHEPalette16BitColorComponent(int component, int type) {
+	uint16 col;
+	if (type == 2) {
+		col = (((component & 0xFFFF) >>  0) & 0x1F) << 3;;
+	} else if (type == 1) {
+		col = (((component & 0xFFFF) >>  5) & 0x1F) << 3;
+	} else {
+		col = (((component & 0xFFFF) >> 10) & 0x1F) << 3;
+	}
+	return col;
+}
+
 int ScummEngine_v90he::getHEPaletteColorComponent(int palSlot, int color, int component) {
 	assertRange(1, palSlot, _numPalettes, "palette");
 	assertRange(0, color, 255, "palette slot");
 
-	return _hePalettes[palSlot * 1024 + color * 3 + component % 3];
+	return _hePalettes[palSlot * _hePaletteSlot + color * 3 + component % 3];
 }
 
 int ScummEngine_v90he::getHEPaletteColor(int palSlot, int color) {
 	assertRange(1, palSlot, _numPalettes, "palette");
 	assertRange(0, color, 255, "palette slot");
 
-	return _hePalettes[palSlot * 1024 + 768 + color];
+	if (_game.features & GF_16BIT_COLOR)
+		return READ_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2);
+	else
+		return _hePalettes[palSlot * _hePaletteSlot + 768 + color];
 }
 
 void ScummEngine_v90he::setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b) {
 	debug(7, "setHEPaletteColor(%d, %d, %d, %d, %d)", palSlot, color, r, g, b);
 	assertRange(1, palSlot, _numPalettes, "palette");
-	uint8 *p = _hePalettes + palSlot * 1024 + color * 3;
+
+	uint8 *p = _hePalettes + palSlot * _hePaletteSlot + color * 3;
 	*(p + 0) = r;
 	*(p + 1) = g;
 	*(p + 2) = b;
-	_hePalettes[palSlot * 1024 + 768 + color] = color;
+	if (_game.features & GF_16BIT_COLOR) {
+		WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2, get16BitColor(r, g, b));
+	} else {
+		_hePalettes[palSlot * _hePaletteSlot + 768 + color] = color;
+	}
 }
 
 void ScummEngine_v90he::setHEPaletteFromPtr(int palSlot, const uint8 *palData) {
 	assertRange(1, palSlot, _numPalettes, "palette");
-	uint8 *pc = _hePalettes + palSlot * 1024;
+
+	uint8 *pc = _hePalettes + palSlot * _hePaletteSlot;
 	uint8 *pi = pc + 768;
-	for (int i = 0; i < 256; ++i) {
-		*pc++ = *palData++;
-		*pc++ = *palData++;
-		*pc++ = *palData++;
-		*pi++ = i;
+	if (_game.features & GF_16BIT_COLOR) {
+		for (int i = 0; i < 256; ++i) {
+			uint8 r = *pc++ = *palData++;
+			uint8 g = *pc++ = *palData++;
+			uint8 b = *pc++ = *palData++;
+			WRITE_LE_UINT16(pi, get16BitColor(r, g, b)); pi += 2;
+		}
+	} else {
+		for (int i = 0; i < 256; ++i) {
+			*pc++ = *palData++;
+			*pc++ = *palData++;
+			*pc++ = *palData++;
+			*pi++ = i;
+		}
 	}
+
+	int i;
+	uint8 *palPtr = _hePalettes + palSlot * _hePaletteSlot + 768;
+	if (_game.features & GF_16BIT_COLOR) {
+		for (i = 0; i < 10; ++i)
+			WRITE_LE_UINT16(palPtr + i * 2, i);
+		for (i = 246; i < 256; ++i)
+			WRITE_LE_UINT16(palPtr + i * 2, i);
+	} else {
+		for (i = 0; i < 10; ++i)
+			*(palPtr + i) = i;
+		for (i = 246; i < 256; ++i)
+			*(palPtr + i) = i;
+	}
 }
 
 void ScummEngine_v90he::setHEPaletteFromCostume(int palSlot, int resId) {
@@ -178,8 +222,9 @@
 void ScummEngine_v90he::restoreHEPalette(int palSlot) {
 	debug(7, "restoreHEPalette(%d)", palSlot);
 	assertRange(1, palSlot, _numPalettes, "palette");
+
 	if (palSlot != 1) {
-		memcpy(_hePalettes + palSlot * 1024, _hePalettes + 1024, 1024);
+		memcpy(_hePalettes + palSlot * _hePaletteSlot, _hePalettes + _hePaletteSlot, _hePaletteSlot);
 	}
 }
 
@@ -187,18 +232,27 @@
 	debug(7, "copyHEPalette(%d, %d)", dstPalSlot, srcPalSlot);
 	assert(dstPalSlot >= 1 && dstPalSlot <= _numPalettes);
 	assert(srcPalSlot >= 1 && srcPalSlot <= _numPalettes);
+
 	if (dstPalSlot != srcPalSlot) {
-		memcpy(_hePalettes + dstPalSlot * 1024, _hePalettes + srcPalSlot * 1024, 1024);
+		memcpy(_hePalettes + dstPalSlot * _hePaletteSlot, _hePalettes + srcPalSlot * _hePaletteSlot, _hePaletteSlot);
 	}
 }
 
-void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor) {
+void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor) {
 	debug(7, "copyHEPaletteColor(%d, %d, %d)", palSlot, dstColor, srcColor);
 	assertRange(1, palSlot, _numPalettes, "palette");
-	uint8 *dstPal = _hePalettes + palSlot * 1024 + dstColor * 3;
-	uint8 *srcPal = _hePalettes + 1024 + srcColor * 3;
-	memcpy(dstPal, srcPal, 3);
-	_hePalettes[palSlot * 1024 + 768 + dstColor] = srcColor;
+
+	uint8 *dstPal = _hePalettes + palSlot * _hePaletteSlot + dstColor * 3;
+	uint8 *srcPal = _hePalettes + _hePaletteSlot + srcColor * 3;
+	if (_game.features & GF_16BIT_COLOR) {
+		dstPal[0] = (srcColor >> 10) << 3;
+		dstPal[1] = (srcColor >>  5) << 3;
+		dstPal[2] = (srcColor >>  0) << 3;
+		WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + dstColor * 2, srcColor);
+	} else {
+		memcpy(dstPal, srcPal, 3);
+		_hePalettes[palSlot * _hePaletteSlot + 768 + dstColor] = srcColor;
+	}
 }
 
 void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
@@ -211,7 +265,7 @@
 
 	assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor");
 
-	dest = _hePalettes + 1024;
+	dest = _hePalettes + _hePaletteSlot;
 
 	for (i = 0; i < numcolor; i++) {
 		r = *ptr++;
@@ -222,48 +276,63 @@
 			*dest++ = r;
 			*dest++ = g;
 			*dest++ = b;
-			_hePalettes[1792 + i] = i;
+
+			if (_game.features & GF_16BIT_COLOR) {
+				WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, get16BitColor(r, g, b));
+			} else {
+				_hePalettes[1792 + i] = i;
+			}
 		} else {
 			dest += 3;
 		}
 	}
 
-	memcpy(_hePalettes, _hePalettes + 1024, 768);
+	memcpy(_hePalettes, _hePalettes + _hePaletteSlot, 768);
 
-	for (i = 0; i < 10; ++i)
-		_hePalettes[1792 + i] = i;
-	for (i = 246; i < 256; ++i)
-		_hePalettes[1792 + i] = i;
-
+	if (_game.features & GF_16BIT_COLOR) {
+		for (i = 0; i < 10; ++i)
+			WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i);
+		for (i = 246; i < 256; ++i)
+			WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i);
+	} else {
+		for (i = 0; i < 10; ++i)
+			_hePalettes[1792 + i] = i;
+		for (i = 246; i < 256; ++i)
+			_hePalettes[1792 + i] = i;
+	}
 	setDirtyColors(0, numcolor - 1);
 }
 
 void ScummEngine_v99he::darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor) {
 	uint8 *src, *dst;
-	int color, j;
+	int j, r, g, b;
 
 	src = _hePalettes + startColor * 3;
-	dst = _hePalettes + 1024 + startColor * 3;
+	dst = _hePalettes + _hePaletteSlot + startColor * 3;
 	for (j = startColor; j <= endColor; j++) {
-		color = *src++;
-		color = color * redScale / 0xFF;
-		if (color > 255)
-			color = 255;
-		*dst++ = color;
+		r = *src++;
+		r = r * redScale / 0xFF;
+		if (r > 255)
+			r = 255;
+		*dst++ = r;
 
-		color = *src++;
-		color = color * greenScale / 0xFF;
-		if (color > 255)
-			color = 255;
-		*dst++ = color;
+		g = *src++;
+		g = g * greenScale / 0xFF;
+		if (g > 255)
+			g = 255;
+		*dst++ = g;
 
-		color = *src++;
-		color = color * blueScale / 0xFF;
-		if (color > 255)
-			color = 255;
-		*dst++ = color;
+		b = *src++;
+		b = b * blueScale / 0xFF;
+		if (b > 255)
+			b = 255;
+		*dst++ = b;
 
-		_hePalettes[1792 + j] = j;
+		if (_game.features & GF_16BIT_COLOR) {
+			WRITE_LE_UINT16(_hePalettes + 2048 + j * 2, get16BitColor(r, g, b));
+		} else {
+			_hePalettes[1792 + j] = j;
+		}
 		setDirtyColors(j, endColor);
 	}
 }
@@ -274,26 +343,39 @@
 	if ((uint) dst >= 256 || (uint) src >= 256)
 		error("copyPalColor: invalid values, %d, %d", dst, src);
 
-	dp = &_hePalettes[1024 + dst * 3];
-	sp = &_hePalettes[1024 + src * 3];
+	dp = &_hePalettes[_hePaletteSlot + dst * 3];
+	sp = &_hePalettes[_hePaletteSlot + src * 3];
 
 	dp[0] = sp[0];
 	dp[1] = sp[1];
 	dp[2] = sp[2];
-	_hePalettes[1792 + dst] = dst;
 
+	if (_game.features & GF_16BIT_COLOR) {
+		WRITE_LE_UINT16(_hePalettes + 2048 + dst * 2, get16BitColor(sp[0], sp[1], sp[2]));
+	} else {
+		_hePalettes[1792 + dst] = dst;
+	}
+
 	setDirtyColors(dst, dst);
 }
 
 void ScummEngine_v99he::setPalColor(int idx, int r, int g, int b) {
-	_hePalettes[1024 + idx * 3 + 0] = r;
-	_hePalettes[1024 + idx * 3 + 1] = g;
-	_hePalettes[1024 + idx * 3 + 2] = b;
-	_hePalettes[1792 + idx] = idx;
+	_hePalettes[_hePaletteSlot + idx * 3 + 0] = r;
+	_hePalettes[_hePaletteSlot + idx * 3 + 1] = g;
+	_hePalettes[_hePaletteSlot + idx * 3 + 2] = b;
+
+	if (_game.features & GF_16BIT_COLOR) {
+		WRITE_LE_UINT16(_hePalettes + 2048 + idx * 2, get16BitColor(r, g, b));
+	} else {
+		_hePalettes[1792 + idx] = idx;
+	}
 	setDirtyColors(idx, idx);
 }
 
 void ScummEngine_v99he::updatePalette() {
+	if (_game.features & GF_16BIT_COLOR)
+		return;
+
 	if (_palDirtyMax == -1)
 		return;
 

Modified: scummvm/trunk/engines/scumm/he/script_v100he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v100he.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/script_v100he.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1576,7 +1576,10 @@
 	case 130:
 		a = pop();
 		b = pop();
-		copyPalColor(a, b);
+		if (_game.features & GF_16BIT_COLOR)
+			copyHEPaletteColor(1, a, b);
+		else
+			copyPalColor(a, b);
 		break;
 
 	case 131:		// SO_ROOM_FADE
@@ -2153,8 +2156,9 @@
 }
 
 void ScummEngine_v100he::o100_cursorCommand() {
-	int a, i;
+	int a, b, i;
 	int args[16];
+
 	byte subOp = fetchScriptByte();
 
 	switch (subOp) {
@@ -2169,12 +2173,12 @@
 	case 0x80:
 	case 0x81:
 		a = pop();
-		_wiz->loadWizCursor(a);
+		_wiz->loadWizCursor(a, 0);
 		break;
 	case 0x82:
-		pop();
+		b = pop();
 		a = pop();
-		_wiz->loadWizCursor(a);
+		_wiz->loadWizCursor(a, b);
 		break;
 	case 0x86:		// SO_CURSOR_ON Turn cursor on
 		_cursor.state = 1;
@@ -2577,7 +2581,8 @@
 }
 
 void ScummEngine_v100he::o100_getPaletteData() {
-	int b, c, d, e;
+	int c, d, e;
+	int r, g, b;
 	int palSlot, color;
 
 	byte subOp = fetchScriptByte();
@@ -2586,7 +2591,10 @@
 	case 13:
 		c = pop();
 		b = pop();
-		push(getHEPaletteColorComponent(1, b, c));
+		if (_game.features & GF_16BIT_COLOR)
+			push(getHEPalette16BitColorComponent(b, c));
+		else
+			push(getHEPaletteColorComponent(1, b, c));
 		break;
 	case 20:
 		color = pop();
@@ -2597,20 +2605,26 @@
 		e = pop();
 		d = pop();
 		palSlot = pop();
-		pop();
-		c = pop();
 		b = pop();
-		push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
+		g = pop();
+		r = pop();
+		push(getHEPaletteSimilarColor(palSlot, r, g, d, e));
 		break;
 	case 53:
-		pop();
-		c = pop();
-		c = MAX(0, c);
-		c = MIN(c, 255);
 		b = pop();
 		b = MAX(0, b);
 		b = MIN(b, 255);
-		push(getHEPaletteSimilarColor(1, b, c, 10, 245));
+		g = pop();
+		g = MAX(0, g);
+		g = MIN(g, 255);
+		r = pop();
+		r = MAX(0, r);
+		r = MIN(r, 255);
+		if (_game.features & GF_16BIT_COLOR) {
+			push(get16BitColor(r, g, b));
+		} else {
+			push(getHEPaletteSimilarColor(1, r, g, 10, 245));
+		}
 		break;
 	case 73:
 		c = pop();

Modified: scummvm/trunk/engines/scumm/he/script_v60he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v60he.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/script_v60he.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -122,6 +122,8 @@
 	} else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
 		// The default game data path is set to './' by ScummVM
 		r = 2;
+	} else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
+		r = 13;
 	} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100)
 		// The default save game path is set to '*/' by ScummVM
 		r = 2;

Modified: scummvm/trunk/engines/scumm/he/script_v72he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v72he.cpp	2009-08-21 03:31:34 UTC (rev 43576)
+++ scummvm/trunk/engines/scumm/he/script_v72he.cpp	2009-08-21 09:37:51 UTC (rev 43577)
@@ -1484,6 +1484,7 @@
 		fetchScriptByte();
 		size = pop();
 		slot = pop();
+		assert(_hInFileTable[slot]);
 		val = readFileToArray(slot, size);
 		push(val);
 		break;
@@ -1573,7 +1574,7 @@
 }
 
 void ScummEngine_v72he::o72_getPixel() {
-	byte area;
+	uint16 area;
 
 	int y = pop();
 	int x = pop();
@@ -1588,11 +1589,17 @@

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list