[Scummvm-cvs-logs] SF.net SVN: scummvm:[41153] scummvm/branches/gsoc2009-16bit

Kirben at users.sourceforge.net Kirben at users.sourceforge.net
Thu Jun 4 03:05:47 CEST 2009


Revision: 41153
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41153&view=rev
Author:   Kirben
Date:     2009-06-04 01:05:47 +0000 (Thu, 04 Jun 2009)

Log Message:
-----------
Add 16bit color support for later HE games.

Modified Paths:
--------------
    scummvm/branches/gsoc2009-16bit/Makefile.common
    scummvm/branches/gsoc2009-16bit/configure
    scummvm/branches/gsoc2009-16bit/engines/scumm/actor.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/akos.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/akos.h
    scummvm/branches/gsoc2009-16bit/engines/scumm/base-costume.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/charset.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.h
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.h
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/intern_he.h
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/palette_he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v100he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v60he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v80he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v90he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.h
    scummvm/branches/gsoc2009-16bit/engines/scumm/palette.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/saveload.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.cpp
    scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.h
    scummvm/branches/gsoc2009-16bit/graphics/scaler/thumbnail_intern.cpp

Modified: scummvm/branches/gsoc2009-16bit/Makefile.common
===================================================================
--- scummvm/branches/gsoc2009-16bit/Makefile.common	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/Makefile.common	2009-06-04 01:05:47 UTC (rev 41153)
@@ -37,6 +37,10 @@
 DEFINES += -DDISABLE_SCALERS
 endif
 
+ifdef ENABLE_16BIT
+DEFINES += -DENABLE_16BIT
+endif
+
 ifdef DISABLE_HQ_SCALERS
 DEFINES += -DDISABLE_HQ_SCALERS
 endif

Modified: scummvm/branches/gsoc2009-16bit/configure
===================================================================
--- scummvm/branches/gsoc2009-16bit/configure	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/configure	2009-06-04 01:05:47 UTC (rev 41153)
@@ -110,6 +110,7 @@
 _zlib=auto
 _mpeg2=no
 _fluidsynth=auto
+_16bit=no
 _mt32emu=yes
 # Default option behaviour yes/no
 _build_hq_scalers=yes
@@ -626,6 +627,8 @@
 
 for ac_option in $@; do
 	case "$ac_option" in
+	--enable-16bit)           _16bit=yes      ;;
+	--disable-16bit)          _16bit=no       ;;
 	--disable-hq-scalers)     _build_hq_scalers=no ;;
 	--disable-scalers)        _build_scalers=no ;;
 	--enable-alsa)            _alsa=yes       ;;
@@ -1513,6 +1516,11 @@
 add_to_config_mk_if_yes "$_mt32emu" 'USE_MT32EMU = 1'
 
 #
+# Check whether 16bit color support is requested
+#
+add_to_config_mk_if_yes "$_16bit" 'ENABLE_16BIT = 1'
+
+#
 # Check whether to enable the (hq) scalers
 #
 add_to_config_mk_if_no $_build_hq_scalers   'DISABLE_HQ_SCALERS = 1'
@@ -1823,6 +1831,10 @@
 	echo_n ", assembly routines"
 fi
 
+if test "$_16bit" = yes ; then
+	echo_n ", 16bit color"
+fi
+
 if test "$_build_hq_scalers" = yes ; then
 	echo_n ", HQ scalers"
 fi

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/actor.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/actor.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/actor.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -2384,7 +2384,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);

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/akos.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/akos.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/akos.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -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,13 +1294,15 @@
 	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;
 }
 
 byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
+	return 0;
+
 #ifdef ENABLE_HE
 	Common::Rect src, dst;
 
@@ -1335,18 +1353,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++)
+				_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/branches/gsoc2009-16bit/engines/scumm/akos.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/akos.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/akos.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -60,7 +60,7 @@
 	uint16 _codec;
 
 	// actor _palette
-	byte _palette[256];
+	uint16 _palette[256];
 	bool _useBompPalette;
 
 	// pointer to various parts of the costume resource

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/base-costume.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/base-costume.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/base-costume.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -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/branches/gsoc2009-16bit/engines/scumm/charset.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/charset.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/charset.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -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/branches/gsoc2009-16bit/engines/scumm/gfx.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -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);
@@ -341,8 +341,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 +586,7 @@
 		vsPitch = _screenWidth * m - width * m;
 
 	} else {
-		vsPitch = vs->pitch - width;
+		vsPitch = vs->pitch - width * vs->bytesPerPixel;
 	}
 
 
@@ -612,36 +612,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);
@@ -976,13 +989,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);
 	}
 }
 
@@ -1011,7 +1024,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
@@ -1047,34 +1060,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);
+		}
 	}
 }
 
@@ -1084,14 +1105,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;
@@ -1100,13 +1125,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);
@@ -1171,41 +1200,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);
 	}
 }
 
@@ -1243,7 +1272,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;
 	}
@@ -1290,7 +1319,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.
@@ -1599,7 +1628,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);
@@ -1632,9 +1661,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);
 
@@ -1643,11 +1672,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);
@@ -1875,7 +1904,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
@@ -1927,6 +1956,8 @@
 }
 
 void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h) {
+	assert(_vm->_bitDepth == 1);
+
 	const byte *bmap_ptr = _vm->findResourceData(MKID_BE('BMAP'), ptr);
 	assert(bmap_ptr);
 
@@ -1936,7 +1967,7 @@
 	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);
@@ -1986,7 +2017,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
@@ -2016,15 +2047,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);
 		}
 	}
 }
@@ -2774,13 +2805,17 @@
 
 	int x = width;
 	while (1) {
-		if (!transpCheck || color != _transparentColor)
-			*dst = _roomPalette[color];
-		dst++;
+		if (!transpCheck || color != _transparentColor) {
+			if (_vm->_game.features & GF_16BIT_COLOR)
+				WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+			else
+				*dst = _roomPalette[color];
+		}
+		dst += _vm->_bitDepth;
 		--x;
 		if (x == 0) {
 			x = width;
-			dst += dstPitch - width;
+			dst += dstPitch - width * _vm->_bitDepth;
 			--height;
 			if (height == 0)
 				return;
@@ -2863,9 +2898,13 @@
 		int x = 8;
 		do {
 			FILL_BITS;
-			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
-			dst++;
+			if (!transpCheck || color != _transparentColor) {
+				if (_vm->_game.features & GF_16BIT_COLOR)
+					WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+				else
+					*dst = _roomPalette[color] + _paletteMod;
+			}
+			dst += _vm->_bitDepth;
 
 		againPos:
 			if (!READ_BIT) {
@@ -2886,13 +2925,17 @@
 					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++;
+						if (!transpCheck || color != _transparentColor) {
+							if (_vm->_game.features & GF_16BIT_COLOR)
+								WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+							else
+								*dst = _roomPalette[color] + _paletteMod;
+						}
+						dst += _vm->_bitDepth;
 					} while (--reps);
 					bits >>= 8;
 					bits |= (*src++) << (cl - 8);
@@ -2900,7 +2943,7 @@
 				}
 			}
 		} while (--x);
-		dst += dstPitch - 8;
+		dst += dstPitch - 8 * _vm->_bitDepth;
 	} while (--height);
 }
 
@@ -2915,9 +2958,13 @@
 		int x = 8;
 		do {
 			FILL_BITS;
-			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
-			dst++;
+			if (!transpCheck || color != _transparentColor) {
+				if (_vm->_game.features & GF_16BIT_COLOR)
+					WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+				else
+					*dst = _roomPalette[color] + _paletteMod;
+			}
+			dst += _vm->_bitDepth;
 			if (!READ_BIT) {
 			} else if (!READ_BIT) {
 				FILL_BITS;
@@ -2932,7 +2979,7 @@
 				color += inc;
 			}
 		} while (--x);
-		dst += dstPitch - 8;
+		dst += dstPitch - 8 * _vm->_bitDepth;
 	} while (--height);
 }
 
@@ -2948,8 +2995,12 @@
 		int h = height;
 		do {
 			FILL_BITS;
-			if (!transpCheck || color != _transparentColor)
-				*dst = _roomPalette[color] + _paletteMod;
+			if (!transpCheck || color != _transparentColor) {
+				if (_vm->_game.features & GF_16BIT_COLOR)
+					WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+				else
+					*dst = _roomPalette[color] + _paletteMod;
+			}
 			dst += dstPitch;
 			if (!READ_BIT) {
 			} else if (!READ_BIT) {
@@ -3016,8 +3067,12 @@
 		do {
 			for (x = 0; x < 8; x ++) {
 				byte color = *src++;
-				if (!transpCheck || color != _transparentColor)
-					dst[x] = _roomPalette[color] + _paletteMod;
+				if (!transpCheck || color != _transparentColor) {
+					if (_vm->_game.features & GF_16BIT_COLOR)
+						WRITE_UINT16(dst + x * 2, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2));
+					else
+						dst[x] = _roomPalette[color] + _paletteMod;
+				}
 			}
 			dst += dstPitch;
 		} while (--height);

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/gfx.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -155,11 +155,11 @@
 	}
 
 	byte *getPixels(int x, int y) const {
-		return (byte *)pixels + xstart + y * pitch + x;
+		return (byte *)pixels + y * pitch + (xstart * 2 + x) * bytesPerPixel;
 	}
 
 	byte *getBackPixels(int x, int y) const {
-		return (byte *)backBuf + xstart + y * pitch + x;
+		return (byte *)backBuf + y * pitch + (xstart * 2 + x) * bytesPerPixel;
 	}
 };
 

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -66,6 +66,31 @@
 	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++)
+				WRITE_UINT16(dst + i * 2, src[i]);
+
+			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 +105,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/branches/gsoc2009-16bit/engines/scumm/he/animation_he.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/animation_he.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -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/branches/gsoc2009-16bit/engines/scumm/he/intern_he.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/intern_he.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/intern_he.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -455,6 +455,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);
@@ -463,7 +464,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/branches/gsoc2009-16bit/engines/scumm/he/palette_he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/palette_he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/palette_he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -31,6 +31,27 @@
 
 namespace Scumm {
 
+uint8 *ScummEngine::getHEPaletteSlot(uint16 palSlot) {
+	assertRange(0, palSlot, _numPalettes, "palette");
+
+	if (_game.heversion >= 99) {
+		if (palSlot)
+			return _hePalettes + palSlot * _hePaletteSlot + 768;
+		else
+			return _hePalettes + _hePaletteSlot + 768;
+	}
+
+	return NULL;
+}
+
+uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) {
+	uint16 ar = (r >> 3) << 10;
+	uint16 ag = (g >> 3) <<  5;
+	uint16 ab = (b >> 3) <<  0;
+	uint16 col = ar | ag | ab;
+	return col;
+}
+
 void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) {
 	int r, g, b, sum, bestitem, bestsum;
 	int ar, ag, ab;
@@ -38,7 +59,7 @@
 	src += 30;
 
 	if (_game.heversion >= 99) {
-		palPtr = _hePalettes + 1024 + 30;
+		palPtr = _hePalettes + _hePaletteSlot + 30;
 	} else {
 		palPtr = _currentPalette + 30;
 	}
@@ -73,9 +94,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;
 	}
 }
 
@@ -84,7 +105,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;
@@ -105,40 +126,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) {
@@ -176,8 +241,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);
 	}
 }
 
@@ -185,18 +251,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) {
@@ -209,7 +284,7 @@
 
 	assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor");
 
-	dest = _hePalettes + 1024;
+	dest = _hePalettes + _hePaletteSlot;
 
 	for (i = 0; i < numcolor; i++) {
 		r = *ptr++;
@@ -220,48 +295,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);
 	}
 }
@@ -272,26 +362,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/branches/gsoc2009-16bit/engines/scumm/he/script_v100he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v100he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v100he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -2152,8 +2152,9 @@
 }
 
 void ScummEngine_v100he::o100_cursorCommand() {
-	int a, i;
+	int a, b, i;
 	int args[16];
+
 	byte subOp = fetchScriptByte();
 
 	switch (subOp) {
@@ -2168,12 +2169,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;
@@ -2576,7 +2577,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();
@@ -2585,7 +2587,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();
@@ -2596,20 +2601,30 @@
 		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) {
+			uint32 ar = ((r >> 3) << 10) & 0xFFFF;
+			uint32 ag = ((g >> 3) <<  5) & 0xFFFF;
+			uint32 ab = ((b >> 3) <<  0) & 0xFFFF;
+			uint32 col = ar | ag | ab;
+			push(col);
+		} else {
+			push(getHEPaletteSimilarColor(1, r, g, 10, 245));
+		}
 		break;
 	case 73:
 		c = pop();

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v60he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v60he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v60he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -115,6 +115,8 @@
 	int r = 0;
 	if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
 		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)
 		r = 2;
 	} else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71)

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v80he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v80he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v80he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -241,7 +241,7 @@
 }
 
 void ScummEngine_v80he::o80_cursorCommand() {
-	int a, i;
+	int a, b, i;
 	int args[16];
 
 	byte subOp = fetchScriptByte();
@@ -250,12 +250,12 @@
 	case 0x13:
 	case 0x14:
 		a = pop();
-		_wiz->loadWizCursor(a);
+		_wiz->loadWizCursor(a, 0);
 		break;
 	case 0x3C:
-		pop();
+		b = pop();
 		a = pop();
-		_wiz->loadWizCursor(a);
+		_wiz->loadWizCursor(a, b);
 		break;
 	case 0x90:		// SO_CURSOR_ON Turn cursor on
 		_cursor.state = 1;

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v90he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v90he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/script_v90he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -1253,7 +1253,7 @@
 
 void ScummEngine_v90he::o90_getWizData() {
 	byte filename[4096];
-	int state, resId;
+	int resId, state, type;
 	int32 w, h;
 	int32 x, y;
 
@@ -1317,9 +1317,10 @@
 		push(computeWizHistogram(resId, state, x, y, w, h));
 		break;
 	case 139:
-		pop();
-		pop();
-		push(0);
+		type = pop();
+		state = pop();
+		resId = pop();
+		push(_wiz->getWizImageData(resId, state, type));
 		break;
 	case 141:
 		pop();
@@ -2099,7 +2100,8 @@
 }
 
 void ScummEngine_v90he::o90_getPaletteData() {
-	int b, c, d, e;
+	int c, d, e;
+	int r, g, b;
 	int palSlot, color;
 
 	byte subOp = fetchScriptByte();
@@ -2109,10 +2111,10 @@
 		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 52:
 		c = pop();
@@ -2128,17 +2130,31 @@
 	case 132:
 		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 217:
-		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) {
+			uint32 ar = ((r >> 3) << 10) & 0xFFFF;
+			uint32 ag = ((g >> 3) <<  5) & 0xFFFF;
+			uint32 ab = ((b >> 3) <<  0) & 0xFFFF;
+			uint32 col = ar | ag | ab;
+			push(col);
+		} else {
+			push(getHEPaletteSimilarColor(1, r, g, 10, 245));
+		}
 		break;
 	default:
 		error("o90_getPaletteData: Unknown case %d", subOp);

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -254,7 +254,9 @@
 	return r;
 }
 
-void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch) {
+void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitDepth) {
+	assert(bitDepth == 1);
+
 	Common::Rect dstRect(srcx, srcy, srcx + srcw, srcy + srch);
 	dstRect.clip(dstw, dsth);
 
@@ -263,8 +265,8 @@
 	if (rh <= 0 || rw <= 0)
 		return;
 
-	uint8 *dst1Ptr = dst1 + dstRect.left + dstRect.top * dstw;
-	uint8 *dst2Ptr = dst2 + dstRect.left + dstRect.top * dstw;
+	uint8 *dst1Ptr = dst1 + dstRect.top * dstw + dstRect.left;
+	uint8 *dst2Ptr = dst2 + dstRect.top * dstw + dstRect.left;
 	const uint8 *dataPtr = src;
 
 	while (rh--) {
@@ -353,12 +355,24 @@
 	return srcRect.isValidRect() && dstRect.isValidRect();
 }
 
-void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
-	// TODO: Compressed 16 bits in 555 format
+void Wiz::writeColor(uint8 *dstPtr, int dstType, uint16 color) {
+	switch (dstType) {
+	case kDstScreen:
+		WRITE_UINT16(dstPtr, color);
+		break;
+	case kDstMemory:
+	case kDstResource:
+		WRITE_LE_UINT16(dstPtr, color);
+		break;
+	default:
+		error("writeColor: Unknown dstType %d", dstType);
+	}
+}
 
+void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
 	Common::Rect r1, r2;
 	if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
-		dst += r2.top * dstw + r2.left;
+		dst += r2.top * dstPitch + r2.left * 2;
 		if (flags & kWIFFlipY) {
 			const int dy = (srcy < 0) ? srcy : (srch - r1.height());
 			r1.translate(0, dy);
@@ -368,17 +382,17 @@
 			r1.translate(dx, 0);
 		}
 		if (xmapPtr) {
-			decompress16BitWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr);
+			decompress16BitWizImage<kWizXMap>(dst, dstPitch, dstType, src, r1, flags, palPtr, xmapPtr);
 		} else {
-			decompress16BitWizImage<kWizCopy>(dst, dstw, src, r1, flags);
+			decompress16BitWizImage<kWizCopy>(dst, dstPitch, dstType, src, r1, flags);
 		}
 	}
 }
 
-void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
+void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) {
 	Common::Rect r1, r2;
 	if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
-		dst += r2.left + r2.top * dstw;
+		dst += r2.top * dstPitch + r2.left * bitDepth;
 		if (flags & kWIFFlipY) {
 			const int dy = (srcy < 0) ? srcy : (srch - r1.height());
 			r1.translate(0, dy);
@@ -388,11 +402,11 @@
 			r1.translate(dx, 0);
 		}
 		if (xmapPtr) {
-			decompressWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr);
+			decompressWizImage<kWizXMap>(dst, dstPitch, dstType, src, r1, flags, palPtr, xmapPtr, bitDepth);
 		} else if (palPtr) {
-			decompressWizImage<kWizRMap>(dst, dstw, src, r1, flags, palPtr);
+			decompressWizImage<kWizRMap>(dst, dstPitch, dstType, src, r1, flags, palPtr, NULL, bitDepth);
 		} else {
-			decompressWizImage<kWizCopy>(dst, dstw, src, r1, flags);
+			decompressWizImage<kWizCopy>(dst, dstPitch, dstType, src, r1, flags, NULL, NULL, bitDepth);
 		}
 	}
 }
@@ -431,13 +445,13 @@
 	}
 }
 
-void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP) {
+void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstPitch, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP) {
 	Common::Rect srcRect, dstRect;
 	if (!calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, srcRect, dstRect)) {
 		return;
 	}
 	dstw = dstw / 8;
-	dst += dstRect.top * dstw + dstRect.left / 8;
+	dst += dstRect.top * dstPitch + dstRect.left / 8;
 
 	const uint8 *dataPtr, *dataPtrNext;
 	uint8 code, mask, *dstPtr, *dstPtrNext;
@@ -462,7 +476,7 @@
 		w = srcRect.width();
 		mask = revBitMask(dstRect.left & 7);
 		off = READ_LE_UINT16(dataPtr); dataPtr += 2;
-		dstPtrNext = dstPtr + dstw;
+		dstPtrNext = dstPtr + dstPitch;
 		dataPtrNext = dataPtr + off;
 		if (off != 0) {
 			while (w > 0) {
@@ -520,7 +534,7 @@
 	}
 }
 
-void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) {
+void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitDepth) {
 	Common::Rect r1, r2;
 	if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
 		if (flags & kWIFFlipX) {
@@ -537,19 +551,17 @@
 		}
 		int h = r1.height();
 		int w = r1.width();
-		src += r1.left + r1.top * srcw;
-		dst += r2.left + r2.top * dstw;
+		src += r1.top * srcw + r1.left;
+		dst += r2.top * dstPitch + r2.left * bitDepth;
 		if (palPtr) {
-			decompressRawWizImage<kWizRMap>(dst, dstw, src, srcw, w, h, transColor, palPtr);
+			decompressRawWizImage<kWizRMap>(dst, dstPitch, dstType, src, srcw, w, h, transColor, palPtr, bitDepth);
 		} else {
-			decompressRawWizImage<kWizCopy>(dst, dstw, src, srcw, w, h, transColor);
+			decompressRawWizImage<kWizCopy>(dst, dstPitch, dstType, src, srcw, w, h, transColor, NULL, bitDepth);
 		}
 	}
 }
 
-void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) {
-	// TODO: RAW 16 bits in 555 format
-
+void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, int transColor) {
 	Common::Rect r1, r2;
 	if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
 		if (flags & kWIFFlipX) {
@@ -567,29 +579,39 @@
 		int h = r1.height();
 		int w = r1.width();
 		src += (r1.top * srcw + r1.left) * 2;
-		dst += r2.top * dstw + r2.left;
+		dst += r2.top * dstPitch + r2.left * 2;
 		while (h--) {
-			for (int i = 0; i < w; ++i) {
+			for (int i = 0; i < w; ++ i) {
 				uint16 col = READ_LE_UINT16(src + 2 * i);
-				uint8 r = ((col >> 10) & 0x1F) << 3;
-				uint8 g = ((col >>  5) & 0x1F) << 3;
-				uint8 b = ((col >>  0) & 0x1F) << 3;
-				uint8 color = _vm->convert16BitColor(col, r, g, b);
-
 				if (transColor == -1 || transColor != col) {
-					dst[i] = color;
+					writeColor(dst + i * 2, dstType, col);
 				}
 			}
 			src += srcw * 2;
-			dst += dstw;
+			dst += dstPitch;
 		}
 	}
 }
 
 template <int type>
-void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
+void Wiz::write16BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *xmapPtr) {
+	uint16 col = READ_LE_UINT16(dataPtr);
+	if (type == kWizXMap) {
+		uint16 srcColor = (col >> 1) & 0x7DEF;
+		uint16 dstColor = (READ_UINT16(dstPtr) >> 1) & 0x7DEF;
+		uint16 newColor = srcColor + dstColor;
+		writeColor(dstPtr, dstType, newColor);
+	}
+	if (type == kWizCopy) {
+		writeColor(dstPtr, dstType, col);
+	}
+}
+
+template <int type>
+void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
 	const uint8 *dataPtr, *dataPtrNext;
-	uint8 code, *dstPtr, *dstPtrNext;
+	uint8 code;
+	uint8 *dstPtr, *dstPtrNext;
 	int h, w, xoff, dstInc;
 
 	if (type == kWizXMap) {
@@ -616,10 +638,10 @@
 		dstPtr += (h - 1) * dstPitch;
 		dstPitch = -dstPitch;
 	}
-	dstInc = 1;
+	dstInc = 2;
 	if (flags & kWIFFlipX) {
-		dstPtr += w - 1;
-		dstInc = -1;
+		dstPtr += (w - 1) * 2;
+		dstInc = -2;
 	}
 
 	while (h--) {
@@ -640,7 +662,7 @@
 
 						code = -xoff;
 					}
-					dstPtr += dstInc * code;
+					dstPtr += dstInc;
 					w -= code;
 				} else if (code & 2) {
 					code = (code >> 2) + 1;
@@ -658,18 +680,7 @@
 						code += w;
 					}
 					while (code--) {
-						uint16 col = READ_LE_UINT16(dataPtr);
-						uint8 r = ((col >> 10) & 0x1F) << 3;
-						uint8 g = ((col >>  5) & 0x1F) << 3;
-						uint8 b = ((col >>  0) & 0x1F) << 3;
-						col = _vm->convert16BitColor(col, r, g, b);
-
-						if (type == kWizXMap) {
-							*dstPtr = xmapPtr[col * 256 + *dstPtr];
-						}
-						if (type == kWizCopy) {
-							*dstPtr = col;
-						}
+						write16BitColor<type>(dstPtr, dataPtr, dstType, xmapPtr);
 						dstPtr += dstInc;
 					}
 					dataPtr+= 2;
@@ -689,18 +700,7 @@
 						code += w;
 					}
 					while (code--) {
-						uint16 col = READ_LE_UINT16(dataPtr);
-						uint8 r = ((col >> 10) & 0x1F) << 3;
-						uint8 g = ((col >>  5) & 0x1F) << 3;
-						uint8 b = ((col >>  0) & 0x1F) << 3;
-						col = _vm->convert16BitColor(col, r, g, b);
-
-						if (type == kWizXMap) {
-							*dstPtr = xmapPtr[col * 256 + *dstPtr];
-						}
-						if (type == kWizCopy) {
-							*dstPtr = col;
-						}
+						write16BitColor<type>(dstPtr, dataPtr, dstType, xmapPtr);
 						dataPtr += 2;
 						dstPtr += dstInc;
 					}
@@ -713,7 +713,36 @@
 }
 
 template <int type>
-void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
+void Wiz::write8BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) {
+	if (bitDepth == 2) {
+		if (type == kWizXMap) {
+			uint16 color = READ_LE_UINT16(palPtr + *dataPtr * 2);
+			uint16 srcColor = (color >> 1) & 0x7DEF;
+			uint16 dstColor = (READ_UINT16(dstPtr) >> 1) & 0x7DEF;
+			uint16 newColor = srcColor + dstColor;
+			writeColor(dstPtr, dstType, newColor);
+		}
+		if (type == kWizRMap) {
+			writeColor(dstPtr, dstType, READ_LE_UINT16(palPtr + *dataPtr * 2));
+		}
+		if (type == kWizCopy) {
+			writeColor(dstPtr, dstType, *dataPtr);
+		}
+	} else {
+		if (type == kWizXMap) {
+			*dstPtr = xmapPtr[*dataPtr * 256 + *dstPtr];
+		}
+		if (type == kWizRMap) {
+			*dstPtr = palPtr[*dataPtr];
+		}
+		if (type == kWizCopy) {
+			*dstPtr = *dataPtr;
+		}
+	}
+}
+
+template <int type>
+void Wiz::decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) {
 	const uint8 *dataPtr, *dataPtrNext;
 	uint8 code, *dstPtr, *dstPtrNext;
 	int h, w, xoff, dstInc;
@@ -742,9 +771,9 @@
 		dstPtr += (h - 1) * dstPitch;
 		dstPitch = -dstPitch;
 	}
-	dstInc = 1;
+	dstInc = bitDepth;
 	if (flags & kWIFFlipX) {
-		dstPtr += w - 1;
+		dstPtr += (w - 1) * bitDepth;
 		dstInc = -1;
 	}
 
@@ -784,15 +813,7 @@
 						code += w;
 					}
 					while (code--) {
-						if (type == kWizXMap) {
-							*dstPtr = xmapPtr[*dataPtr * 256 + *dstPtr];
-						}
-						if (type == kWizRMap) {
-							*dstPtr = palPtr[*dataPtr];
-						}
-						if (type == kWizCopy) {
-							*dstPtr = *dataPtr;
-						}
+						write8BitColor<type>(dstPtr, dataPtr, dstType, palPtr, xmapPtr, bitDepth);
 						dstPtr += dstInc;
 					}
 					dataPtr++;
@@ -812,15 +833,8 @@
 						code += w;
 					}
 					while (code--) {
-						if (type == kWizXMap) {
-							*dstPtr = xmapPtr[*dataPtr++ * 256 + *dstPtr];
-						}
-						if (type == kWizRMap) {
-							*dstPtr = palPtr[*dataPtr++];
-						}
-						if (type == kWizCopy) {
-							*dstPtr = *dataPtr++;
-						}
+						write8BitColor<type>(dstPtr, dataPtr, dstType, palPtr, xmapPtr, bitDepth);
+						dataPtr++;
 						dstPtr += dstInc;
 					}
 				}
@@ -832,7 +846,7 @@
 }
 
 template <int type>
-void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr) {
+void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitDepth) {
 	if (type == kWizRMap) {
 		assert(palPtr != 0);
 	}
@@ -845,10 +859,18 @@
 			uint8 col = src[i];
 			if (transColor == -1 || transColor != col) {
 				if (type == kWizRMap) {
-					dst[i] = palPtr[col];
+					if (bitDepth == 2) {
+						writeColor(dst + i * 2, dstType, READ_LE_UINT16(palPtr + col * 2));
+					} else {
+						dst[i] = palPtr[col];
+					}
 				}
 				if (type == kWizCopy) {
-					dst[i] = col;
+					if (bitDepth == 2) {
+						writeColor(dst + i * 2, dstType, col);
+					} else {
+						dst[i] = col;
+					}
 				}
 			}
 		}
@@ -938,7 +960,7 @@
 	}
 
 	if (bitDepth == 2)
-		return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 1);
+		return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 2);
 	else
 		return (data[0] & 1) ? color : data[1];
 
@@ -949,7 +971,7 @@
 		return color;
 	}
 	if (bitDepth == 2)
-		return READ_LE_UINT16(data + y * w + x * 2);
+		return READ_LE_UINT16(data + (y * w + x) * 2);
 	else
 		return data[y * w + x];
 }
@@ -1038,6 +1060,22 @@
 	}
 }
 
+static int wizPackType2(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt) {
+	debug(9, "wizPackType2([%d,%d,%d,%d])", rCapt.left, rCapt.top, rCapt.right, rCapt.bottom);
+	int w = rCapt.width();
+	int h = rCapt.height();
+	int size = w * h * 2;
+	if (dst) {
+		src += rCapt.top * srcPitch + rCapt.left * 2;
+		while (h--) {
+			memcpy(dst, src, w * 2);
+			dst += w * 2;
+			src += srcPitch;
+		}
+	}
+	return size;
+}
+
 static int wizPackType1(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 transColor) {
 	debug(9, "wizPackType1(%d, [%d,%d,%d,%d])", transColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom);
 	src += rCapt.top * srcPitch + rCapt.left;
@@ -1174,7 +1212,7 @@
 }
 
 void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, int compType) {
-	debug(5, "ScummEngine_v72he::captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom);
+	debug(0, "captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom);
 	uint8 *src = NULL;
 	VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen];
 	if (backBuffer) {
@@ -1187,7 +1225,7 @@
 		rCapt.clip(r);
 		const uint8 *palPtr;
 		if (_vm->_game.heversion >= 99) {
-			palPtr = _vm->_hePalettes + 1024;
+			palPtr = _vm->_hePalettes + _vm->_hePaletteSlot;
 		} else {
 			palPtr = _vm->_currentPalette;
 		}
@@ -1196,6 +1234,9 @@
 		int h = rCapt.height();
 		int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5;
 
+		if (_vm->_game.features & GF_16BIT_COLOR)
+			compType = 2;
+
 		// compute compressed size
 		int dataSize = 0;
 		int headerSize = palPtr ? 1080 : 36;
@@ -1206,6 +1247,9 @@
 		case 1:
 			dataSize = wizPackType1(0, src, pvs->pitch, rCapt, transColor);
 			break;
+		case 2:
+			dataSize = wizPackType2(0, src, pvs->pitch, rCapt);
+			break;
 		default:
 			error("unhandled compression type %d", compType);
 			break;
@@ -1249,6 +1293,9 @@
 		case 1:
 			wizPackType1(wizImg + headerSize, src, pvs->pitch, rCapt, transColor);
 			break;
+		case 2:
+			wizPackType2(wizImg + headerSize, src, pvs->pitch, rCapt);
+			break;
 		default:
 			break;
 		}
@@ -1274,24 +1321,15 @@
 		drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, 0, 0, 0);
 	} else {
 		const Common::Rect *r = NULL;
-		drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, 0);
+		drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0));
 	}
 }
 
-uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette) {
-	debug(3, "drawWizImage(resNum %d, x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d palette %d)", resNum, x1, y1, flags, zorder, shadow, field_390, dstResNum, palette);
+uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr) {
+	debug(3, "drawWizImage(resNum %d, x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d)", resNum, x1, y1, flags, zorder, shadow, field_390, dstResNum);
 	uint8 *dataPtr;
 	uint8 *dst = NULL;
 
-	const uint8 *palPtr = NULL;
-	if (_vm->_game.heversion >= 99) {
-		if (palette) {
-			palPtr = _vm->_hePalettes + palette * 1024 + 768;
-		} else {
-			palPtr = _vm->_hePalettes + 1792;
-		}
-	}
-
 	const uint8 *xmapPtr = NULL;
 	if (shadow) {
 		dataPtr = _vm->getResourceAddress(rtImage, shadow);
@@ -1334,13 +1372,25 @@
 		error("WizImage printing is unimplemented");
 	}
 
-	int32 cw, ch;
+	int32 dstPitch, dstType, cw, ch;
 	if (flags & kWIFBlitToMemBuffer) {
-		dst = (uint8 *)malloc(width * height);
+		dst = (uint8 *)malloc(width * height * _vm->_bitDepth);
 		int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? (_vm->VAR(_vm->VAR_WIZ_TCOLOR)) : 5;
-		memset(dst, transColor, width * height);
+
+		if (_vm->_bitDepth == 2) {
+			uint8 *tmpPtr = dst;
+			for (uint i = 0; i < height; i++) {
+				for (uint j = 0; j < width; j++)
+					WRITE_LE_UINT16(tmpPtr + j * 2, transColor);
+				tmpPtr += width * 2;
+			}
+		} else {
+			memset(dst, transColor, width * height);
+		}
 		cw = width;
 		ch = height;
+		dstPitch = cw * _vm->_bitDepth;
+		dstType = kDstMemory;
 	} else {
 		if (dstResNum) {
 			uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum);
@@ -1348,6 +1398,8 @@
 			dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
 			assert(dst);
 			getWizImageDim(dstResNum, 0, cw, ch);
+			dstPitch = cw * _vm->_bitDepth;
+			dstType = kDstResource;
 		} else {
 			VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen];
 			if (flags & kWIFMarkBufferDirty) {
@@ -1357,6 +1409,8 @@
 			}
 			cw = pvs->w;
 			ch = pvs->h;
+			dstPitch = pvs->pitch;
+			dstType = kDstScreen;
 		}
 	}
 
@@ -1376,7 +1430,7 @@
 		}
 	}
 
-	if (flags & kWIFRemapPalette) {
+	if (flags & kWIFRemapPalette && _vm->_bitDepth == 1) {
 		palPtr = rmap + 4;
 	}
 
@@ -1388,28 +1442,27 @@
 
 	switch (comp) {
 	case 0:
-		copyRawWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor);
+		copyRawWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor, _vm->_bitDepth);
 		break;
 	case 1:
 		if (flags & 0x80) {
 			dst = _vm->getMaskBuffer(0, 0, 1);
-			copyWizImageWithMask(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, 0, 2);
+			copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 2);
 		} else if (flags & 0x100) {
 			dst = _vm->getMaskBuffer(0, 0, 1);
-			copyWizImageWithMask(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, 0, 1);
+			copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 1);
 		} else {
-			copyWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr);
+			copyWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr, _vm->_bitDepth);
 		}
 		break;
 	case 2:
-		copyRaw16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor);
+		copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, transColor);
 		break;
 	case 4:
 		// TODO: Unknown image type
 		break;
 	case 5:
-		// TODO: 16bit color compressed image
-		copy16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr);
+		copy16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr);
 		break;
 	default:
 		error("drawWizImage: Unhandled wiz compression type %d", comp);
@@ -1539,7 +1592,7 @@
 }
 
 void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette) {
-	debug(3, "drawWizPolygonTransform(resNum %d, flags 0x%X, shadow %d dstResNum %d palette %d)", resNum, flags, shadow, dstResNum, palette);
+	debug(0, "drawWizPolygonTransform(resNum %d, flags 0x%X, shadow %d dstResNum %d palette %d)", resNum, flags, shadow, dstResNum, palette);
 	const Common::Rect *r = NULL;
 	uint8 *srcWizBuf = NULL;
 	bool freeBuffer = true;
@@ -1552,8 +1605,10 @@
 			if (flags & 0x800000) {
 				debug(0, "drawWizPolygonTransform() unhandled flag 0x800000");
 			}
-			srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, flags, 0, palette);
+
+			srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette));
 		} else {
+			assert(_vm->_bitDepth == 1);
 			uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
 			assert(dataPtr);
 			srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
@@ -1562,7 +1617,7 @@
 		}
 	} else {
 		if (getWizImageData(resNum, state, 0) != 0) {
-			srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, palette);
+			srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
 		} else {
 			uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
 			assert(dataPtr);
@@ -1584,7 +1639,7 @@
 			dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
 			assert(dst);
 			getWizImageDim(dstResNum, 0, dstw, dsth);
-			dstpitch = dstw;
+			dstpitch = dstw * _vm->_bitDepth;
 		} else {
 			if (flags & kWIFMarkBufferDirty) {
 				dst = pvs->getPixels(0, 0);
@@ -1666,7 +1721,7 @@
 					int16 width = ppa->xmax - ppa->xmin + 1;
 					pra->x_step = ((ppa->x2 - ppa->x1) << 16) / width;
 					pra->y_step = ((ppa->y2 - ppa->y1) << 16) / width;
-					pra->dst_offs = yoff + x1;
+					pra->dst_offs = yoff + x1 * _vm->_bitDepth;
 					pra->w = w;
 					pra->x_s = ppa->x1 << 16;
 					pra->y_s = ppa->y1 << 16;
@@ -1695,10 +1750,14 @@
 				assert(src_offs < wizW * wizH);
 				x_acc += pra->x_step;
 				y_acc += pra->y_step;
-				if (transColor == -1 || transColor != srcWizBuf[src_offs]) {
-					*dstPtr = srcWizBuf[src_offs];
+				if (_vm->_bitDepth == 2) {
+					if (transColor == -1 || transColor != READ_LE_UINT16(srcWizBuf + src_offs * 2))
+						WRITE_LE_UINT16(dstPtr, READ_LE_UINT16(srcWizBuf + src_offs * 2));
+				} else {
+					if (transColor == -1 || transColor != srcWizBuf[src_offs])
+						*dstPtr = srcWizBuf[src_offs];
 				}
-				dstPtr++;
+				dstPtr += _vm->_bitDepth;
 			}
 		}
 
@@ -1721,13 +1780,13 @@
 			drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, pwi->shadow, 0, pwi->palette);
 		} else {
 			const Common::Rect *r = NULL;
-			drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, pwi->palette);
+			drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette));
 		}
 	}
 	_imagesNum = 0;
 }
 
-void Wiz::loadWizCursor(int resId) {
+void Wiz::loadWizCursor(int resId, int palette) {
 	int32 x, y;
 	getWizImageSpot(resId, 0, x, y);
 	if (x < 0) {
@@ -1742,7 +1801,10 @@
 	}
 
 	const Common::Rect *r = NULL;
-	uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0);
+	_vm->_bitDepth = 1;
+	uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette));
+	_vm->_bitDepth = (_vm->_game.features & GF_16BIT_COLOR) ? 2 : 1;
+
 	int32 cw, ch;
 	getWizImageDim(resId, 0, cw, ch);
 	_vm->setCursorHotspot(x, y);
@@ -1758,7 +1820,8 @@
 	int sourceImage = 0;
 	if (params->processFlags & kWPFMaskImg) {
 		sourceImage = params->sourceImage;
-		debug(0, "displayWizComplexImage() unhandled flag kWPFMaskImg");
+		debug(3, "displayWizComplexImage() unhandled flag kWPFMaskImg");
+		return;
 	}
 	int palette = 0;
 	if (params->processFlags & kWPFPaletteNum) {
@@ -1827,14 +1890,14 @@
 	} else {
 		if (sourceImage != 0) {
 			// TODO: Add support for kWPFMaskImg
-			drawWizImage(params->sourceImage, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette);
+			drawWizImage(params->sourceImage, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
 		} else if (params->processFlags & (kWPFScaled | kWPFRotate)) {
 			drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette);
 		} else {
 			if (flags & kWIFIsPolygon) {
 				drawWizPolygon(params->img.resNum, state, po_x, flags, shadow, dstResNum, palette);
 			} else {
-				drawWizImage(params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette);
+				drawWizImage(params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette));
 			}
 		}
 	}
@@ -1842,6 +1905,8 @@
 
 void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int img_h) {
 	const uint16 flags = 0xB;
+	const uint8 compType = (_vm->_game.features & GF_16BIT_COLOR) ? 2 : 0;
+	const uint8 bitDepth = (_vm->_game.features & GF_16BIT_COLOR) ? 2 : 1;
 	int res_size = 0x1C;
 	if (flags & 1) {
 		res_size += 0x308;
@@ -1852,11 +1917,11 @@
 	if (flags & 8) {
 		res_size += 0x10C;
 	}
-	res_size += 8 + img_w * img_h;
+	res_size += 8 + img_w * img_h * bitDepth;
 
 	const uint8 *palPtr;
 	if (_vm->_game.heversion >= 99) {
-		palPtr = _vm->_hePalettes + 1024;
+		palPtr = _vm->_hePalettes + _vm->_hePaletteSlot;
 	} else {
 		palPtr = _vm->_currentPalette;
 	}
@@ -1869,7 +1934,7 @@
 		WRITE_BE_UINT32(res_data, res_size); res_data += 4;
 		WRITE_BE_UINT32(res_data, 'WIZH'); res_data += 4;
 		WRITE_BE_UINT32(res_data, 0x14); res_data += 4;
-		WRITE_LE_UINT32(res_data, 0); res_data += 4;
+		WRITE_LE_UINT32(res_data, compType); res_data += 4;
 		WRITE_LE_UINT32(res_data, img_w); res_data += 4;
 		WRITE_LE_UINT32(res_data, img_h); res_data += 4;
 		if (flags & 1) {
@@ -1892,7 +1957,7 @@
 			}
 		}
 		WRITE_BE_UINT32(res_data, 'WIZD'); res_data += 4;
-		WRITE_BE_UINT32(res_data, 8 + img_w * img_h); res_data += 4;
+		WRITE_BE_UINT32(res_data, 8 + img_w * img_h * bitDepth); res_data += 4;
 	}
 	_vm->_res->setModified(rtImage, resNum);
 }
@@ -1909,7 +1974,8 @@
 		int c = READ_LE_UINT32(wizh + 0x0);
 		int w = READ_LE_UINT32(wizh + 0x4);
 		int h = READ_LE_UINT32(wizh + 0x8);
-		assert(c == 0);
+		assert(c == 0 || c == 2);
+		uint8 bitDepth = (c == 2) ? 2 : 1;
 		Common::Rect areaRect, imageRect(w, h);
 		if (params->processFlags & kWPFClipBox) {
 			if (!imageRect.intersects(params->box)) {
@@ -1932,10 +1998,15 @@
 			assert(wizd);
 			int dx = areaRect.width();
 			int dy = areaRect.height();
-			wizd += areaRect.top * w + areaRect.left;
+			wizd += (areaRect.top * w + areaRect.left) * bitDepth;
 			while (dy--) {
-				memset(wizd, color, dx);
-				wizd += w;
+				if (bitDepth == 2) {
+					for (int i = 0; i < dx; i++)
+						WRITE_LE_UINT16(wizd + i * 2, color);
+				} else {
+					memset(wizd, color, dx);
+				}
+				wizd += w * bitDepth;
 			}
 		}
 	}
@@ -1945,14 +2016,19 @@
 struct drawProcP {
 	Common::Rect *imageRect;
 	uint8 *wizd;
-	int width;
+	int pitch;
+	int depth;
 };
 
 static void drawProc(int x, int y, int c, void *data) {
 	drawProcP *param = (drawProcP *)data;
 
 	if (param->imageRect->contains(x, y)) {
-		*(param->wizd + y * param->width + x) = c;
+		uint32 offs = y * param->pitch + x * param->depth;
+		if (param->depth == 2)
+			WRITE_LE_UINT16(param->wizd + offs, c);
+		else
+			*(param->wizd + offs) = c;
 	}
 }
 
@@ -1969,7 +2045,8 @@
 			int c = READ_LE_UINT32(wizh + 0x0);
 			int w = READ_LE_UINT32(wizh + 0x4);
 			int h = READ_LE_UINT32(wizh + 0x8);
-			assert(c == 0);
+			assert(c == 0 || c == 2);
+			uint8 bitDepth = (c == 2) ? 2 : 1;
 			Common::Rect imageRect(w, h);
 			if (params->processFlags & kWPFClipBox) {
 				if (!imageRect.intersects(params->box)) {
@@ -1992,13 +2069,13 @@
 
 			lineP.imageRect = &imageRect;
 			lineP.wizd = wizd;
-			lineP.width = w;
+			lineP.pitch = w * bitDepth;
+			lineP.depth = bitDepth;
 
 			if (params->processFlags & kWPFParams) {
 				assert (params->params2 == 1); // Catch untested usage
 				Graphics::drawThickLine(x1, y1, x2, y2, params->params1, color, drawProc, &lineP);
 			} else {
-
 				Graphics::drawLine(x1, y1, x2, y2, color, drawProc, &lineP);
 			}
 		}
@@ -2167,6 +2244,9 @@
 				img_x = params->img.x1;
 				img_y = params->img.y1;
 			}
+			if (params->processFlags & kWPFParams) {
+				debug(0, "Compression %d Color Depth %d", params->params1, params->params2);
+			}
 			createWizEmptyImage(params->img.resNum, img_x, img_y, img_w, img_h);
 		}
 		break;
@@ -2304,7 +2384,7 @@
 			ret = isWizPixelNonTransparent(wizd, x, y, w, h, 1);
 			break;
 		case 2:
-				ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
+			ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
 			break;
 		case 4:
 			// TODO: Unknown image type

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/he/wiz_he.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -142,6 +142,12 @@
 	kWizCopy
 };
 
+enum DstSurface {
+	kDstScreen   = 0,
+	kDstMemory   = 1,
+	kDstResource = 2
+};
+
 class ScummEngine_v71he;
 
 class Wiz {
@@ -188,27 +194,32 @@
 	void flushWizBuffer();
 
 	void getWizImageSpot(int resId, int state, int32 &x, int32 &y);
-	void loadWizCursor(int resId);
+	void loadWizCursor(int resId, int palette);
 
 	void captureWizImage(int resNum, const Common::Rect& r, bool frontBuffer, int compType);
 	void displayWizComplexImage(const WizParameters *params);
 	void displayWizImage(WizImage *pwi);
 	void processWizImage(const WizParameters *params);
 
-	uint8 *drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette);
+	uint8 *drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr);
 	void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette);
 	void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette);
 	void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette);
 
-	static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch);
-	static void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
-	static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP);
-	void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
-	static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
-	void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
-	template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
-	template<int type> void decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
-	template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr = NULL);
+	static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitdepth);
+	static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstPitch, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP);
+	static void copyWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth);
+	static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitdepth);
+	static void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr);
+	static void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, int transColor);
+	template<int type> static void decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
+	template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth);
+	template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitdepth);
+
+	template<int type> static void write16BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *xmapPtr);
+	template<int type> static void write8BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth);
+	static void writeColor(uint8 *dstPtr, int dstType, uint16 color);
+
 	int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitdepth);
 	uint16 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);
 	uint16 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color);

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/palette.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/palette.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/palette.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -310,9 +310,6 @@
 		_palDirtyMin = min;
 	if (_palDirtyMax < max)
 		_palDirtyMax = max;
-
-	if (_hePaletteCache)
-		memset(_hePaletteCache, -1, 65536);
 }
 
 void ScummEngine::initCycl(const byte *ptr) {
@@ -813,16 +810,6 @@
 #endif
 
 
-int ScummEngine::convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b) {
-	// HACK: Find the closest matching color, and store in
-	// cache for faster access.
-	if (_hePaletteCache[color] == -1) {
-		_hePaletteCache[color] = remapPaletteColor(r, g, b, -1);
-	}
-
-	return _hePaletteCache[color];
-}
-
 int ScummEngine::remapPaletteColor(int r, int g, int b, int threshold) {
 	byte *pal;
 	int ar, ag, ab, i;

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/saveload.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/saveload.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/saveload.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -1505,7 +1505,7 @@
 void ScummEngine_v99he::saveOrLoad(Serializer *s) {
 	ScummEngine_v90he::saveOrLoad(s);
 
-	s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * 1024, sizeof(_hePalettes[0]), sleUint8);
+	s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * _hePaletteSlot, sizeof(_hePalettes[0]), sleUint8);
 }
 
 void ScummEngine_v100he::saveOrLoad(Serializer *s) {

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -248,6 +248,7 @@
 	_switchRoomEffect2 = 0;
 	_switchRoomEffect = 0;
 
+	_bitDepth = 0;
 	_doEffect = false;
 	_snapScroll = false;
 	_currentLights = 0;
@@ -264,8 +265,8 @@
 	_palManipPalette = NULL;
 	_palManipIntermediatePal = NULL;
 	memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
-	_hePaletteCache = NULL;
 	_hePalettes = NULL;
+	_hePaletteSlot = 0;
 	_shadowPalette = NULL;
 	_shadowPaletteSize = 0;
 	memset(_currentPalette, 0, sizeof(_currentPalette));
@@ -521,9 +522,11 @@
 		_screenHeight = 200;
 	}
 
+	_bitDepth = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+
 	// Allocate gfx compositing buffer (not needed for V7/V8 games).
 	if (_game.version < 7)
-		_compositeBuf = (byte *)malloc(_screenWidth * _screenHeight);
+		_compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * _bitDepth);
 	else
 		_compositeBuf = 0;
 
@@ -814,7 +817,6 @@
 		delete _logicHE;
 	}
 	if (_game.heversion >= 99) {
-		free(_hePaletteCache);
 		free(_hePalettes);
 	}
 }
@@ -1182,7 +1184,7 @@
 	int maxHeapThreshold = -1;
 
 	if (_game.features & GF_16BIT_COLOR) {
-		// 16Bit color games require double the memory, due to increased resource sizes.
+		// 16bit color games require double the memory, due to increased resource sizes.
 		maxHeapThreshold = 12 * 1024 * 1024;
 	} else if (_game.features & GF_NEW_COSTUMES) {
 		// Since the new costumes are very big, we increase the heap limit, to avoid having
@@ -1204,7 +1206,7 @@
 	}
 
 	free(_compositeBuf);
-	_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
+	_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bitDepth);
 }
 
 #ifdef ENABLE_SCUMM_7_8
@@ -1542,12 +1544,10 @@
 
 	ScummEngine_v90he::resetScumm();
 
-	_hePaletteCache = (int16 *)malloc(65536);
-	memset(_hePaletteCache, -1, 65536);
+	_hePaletteSlot = (_game.features & GF_16BIT_COLOR) ? 1280 : 1024;
+	_hePalettes = (uint8 *)malloc((_numPalettes + 1) * _hePaletteSlot);
+	memset(_hePalettes, 0, (_numPalettes + 1) * _hePaletteSlot);
 
-	_hePalettes = (uint8 *)malloc((_numPalettes + 1) * 1024);
-	memset(_hePalettes, 0, (_numPalettes + 1) * 1024);
-
 	// Array 129 is set to base name
 	len = strlen(_filenamePattern.pattern);
 	data = defineArray(129, kStringArray, 0, 0, 0, len);

Modified: scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.h
===================================================================
--- scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.h	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/engines/scumm/scumm.h	2009-06-04 01:05:47 UTC (rev 41153)
@@ -954,6 +954,7 @@
 	int _screenTop;
 
 	Common::RenderMode _renderMode;
+	uint8 _bitDepth;
 
 protected:
 	ColorCycle _colorCycle[16];	// Palette cycles
@@ -1039,7 +1040,8 @@
 	virtual void palManipulateInit(int resID, int start, int end, int time);
 	void palManipulate();
 public:
-	int convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b);
+	uint8 *getHEPaletteSlot(uint16 palSlot);
+	uint16 get16BitColor(uint8 r, uint8 g, uint8 b);
 	int remapPaletteColor(int r, int g, int b, int threshold);		// Used by Actor::remapActorPalette
 protected:
 	void moveMemInPalRes(int start, int end, byte direction);
@@ -1115,7 +1117,7 @@
 	// HE specific
 	byte _HEV7ActorPalette[256];
 	uint8 *_hePalettes;
-	int16 *_hePaletteCache;
+	uint16 _hePaletteSlot;
 
 protected:
 	int _shadowPaletteSize;

Modified: scummvm/branches/gsoc2009-16bit/graphics/scaler/thumbnail_intern.cpp
===================================================================
--- scummvm/branches/gsoc2009-16bit/graphics/scaler/thumbnail_intern.cpp	2009-06-03 23:36:23 UTC (rev 41152)
+++ scummvm/branches/gsoc2009-16bit/graphics/scaler/thumbnail_intern.cpp	2009-06-04 01:05:47 UTC (rev 41153)
@@ -23,6 +23,7 @@
  *
  */
 
+#include "common/endian.h"
 #include "common/scummsys.h"
 #include "common/system.h"
 
@@ -107,11 +108,17 @@
 
 	for (uint y = 0; y < screen->h; ++y) {
 		for (uint x = 0; x < screen->w; ++x) {
-			byte r, g, b;
-			r = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4];
-			g = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 1];
-			b = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 2];
-
+				byte r, g, b;
+			if (screen->bytesPerPixel == 2) {
+				uint16 col = READ_UINT16(screen->getBasePtr(x, y));
+				r = ((col >> 10) & 0x1F) << 3;
+				g = ((col >>  5) & 0x1F) << 3;
+				b = ((col >>  0) & 0x1F) << 3;
+			} else {
+				r = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4];
+				g = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 1];
+				b = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 2];
+			}
 			((uint16*)surf->pixels)[y * surf->w + x] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
 		}
 	}


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