aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/akos.cpp81
-rw-r--r--engines/scumm/akos.h2
-rw-r--r--engines/scumm/base-costume.cpp2
-rw-r--r--engines/scumm/charset.cpp4
-rw-r--r--engines/scumm/gfx.cpp245
-rw-r--r--engines/scumm/gfx.h4
-rw-r--r--engines/scumm/he/animation_he.cpp31
-rw-r--r--engines/scumm/he/animation_he.h1
-rw-r--r--engines/scumm/he/intern_he.h3
-rw-r--r--engines/scumm/he/palette_he.cpp217
-rw-r--r--engines/scumm/he/script_v100he.cpp43
-rw-r--r--engines/scumm/he/script_v60he.cpp2
-rw-r--r--engines/scumm/he/script_v80he.cpp8
-rw-r--r--engines/scumm/he/script_v90he.cpp44
-rw-r--r--engines/scumm/he/wiz_he.cpp364
-rw-r--r--engines/scumm/he/wiz_he.h33
-rw-r--r--engines/scumm/palette.cpp13
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/scumm.cpp20
-rw-r--r--engines/scumm/scumm.h6
21 files changed, 726 insertions, 401 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index cf90094112..eea1ec070b 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -2384,7 +2384,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
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);
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp
index ab7db2c4a7..edfbe5730d 100644
--- a/engines/scumm/akos.cpp
+++ b/engines/scumm/akos.cpp
@@ -299,22 +299,23 @@ void AkosRenderer::setPalette(byte *new_palette) {
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 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
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 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
} 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 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
pcolor = _shadow_table[pcolor];
}
}
- *dst = pcolor;
+ if (_vm->_bitDepth == 2) {
+ WRITE_UINT16(dst, pcolor);
+ } else {
+ *dst = pcolor;
+ }
}
}
dst += _out.pitch;
@@ -617,7 +626,7 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
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 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {
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 @@ byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) {
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 @@ void AkosRenderer::akos16Decompress(byte *dest, int32 pitch, const byte *src, in
}
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 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
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 @@ byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
_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
diff --git a/engines/scumm/akos.h b/engines/scumm/akos.h
index be532b804d..17576e5869 100644
--- a/engines/scumm/akos.h
+++ b/engines/scumm/akos.h
@@ -60,7 +60,7 @@ protected:
uint16 _codec;
// actor _palette
- byte _palette[256];
+ uint16 _palette[256];
bool _useBompPalette;
// pointer to various parts of the costume resource
diff --git a/engines/scumm/base-costume.cpp b/engines/scumm/base-costume.cpp
index 795abb8685..ef706afaac 100644
--- a/engines/scumm/base-costume.cpp
+++ b/engines/scumm/base-costume.cpp
@@ -40,7 +40,7 @@ byte BaseCostumeRenderer::drawCostume(const VirtScreen &vs, int numStrips, const
_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;
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 193fc434e4..d6dfa4c5bb 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -819,9 +819,9 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
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) {
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 62e18561d3..a141d51735 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -43,12 +43,12 @@ extern "C" void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height
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 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int
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 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
vsPitch = _screenWidth * m - width * m;
} else {
- vsPitch = vs->pitch - width;
+ vsPitch = vs->pitch - width * vs->bytesPerPixel;
}
@@ -612,36 +612,49 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
#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;
-
- // 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;
+
+ 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++;
+
+ // 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 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
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 @@ void ScummEngine::restoreCharsetBg() {
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 @@ byte *Gdi::getMaskBuffer(int x, int y, int z) {
#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 @@ static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
#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 @@ static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
#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 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
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 @@ void ScummEngine_v5::drawFlashlight() {
_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 @@ void ScummEngine_v5::drawFlashlight() {
_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 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
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 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
// 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 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
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 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
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::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
}
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 @@ void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y,
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 @@ void ScummEngine_v70he::restoreBackgroundHE(Common::Rect rect, int dirtybit) {
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 @@ void Gdi::resetBackground(int top, int bottom, int strip) {
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 @@ void Gdi::drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int h
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 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
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 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
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 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height,
}
}
} while (--x);
- dst += dstPitch - 8;
+ dst += dstPitch - 8 * _vm->_bitDepth;
} while (--height);
}
@@ -2915,9 +2958,13 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height,
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 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height,
color += inc;
}
} while (--x);
- dst += dstPitch - 8;
+ dst += dstPitch - 8 * _vm->_bitDepth;
} while (--height);
}
@@ -2948,8 +2995,12 @@ void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height,
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 @@ void Gdi::drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, con
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);
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index e4c1054450..88852c8388 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -155,11 +155,11 @@ struct VirtScreen : Graphics::Surface {
}
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;
}
};
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp
index 0cc4419778..5983df2308 100644
--- a/engines/scumm/he/animation_he.cpp
+++ b/engines/scumm/he/animation_he.cpp
@@ -66,6 +66,31 @@ int MoviePlayer::load(const char *filename, int flags, int image) {
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 @@ void MoviePlayer::handleNextFrame() {
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);
diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h
index 39f03960c4..e2fc1d04b7 100644
--- a/engines/scumm/he/animation_he.h
+++ b/engines/scumm/he/animation_he.h
@@ -54,6 +54,7 @@ public:
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:
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index c2079fa5fe..949113aeeb 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -455,6 +455,7 @@ protected:
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 @@ protected:
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 */
diff --git a/engines/scumm/he/palette_he.cpp b/engines/scumm/he/palette_he.cpp
index d055b77ee2..812c39d173 100644
--- a/engines/scumm/he/palette_he.cpp
+++ b/engines/scumm/he/palette_he.cpp
@@ -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 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) {
src += 30;
if (_game.heversion >= 99) {
- palPtr = _hePalettes + 1024 + 30;
+ palPtr = _hePalettes + _hePaletteSlot + 30;
} else {
palPtr = _currentPalette + 30;
}
@@ -73,9 +94,9 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) {
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 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green,
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,39 +126,83 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green,
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;
}
}
@@ -176,8 +241,9 @@ void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state)
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 @@ void ScummEngine_v90he::copyHEPalette(int dstPalSlot, int srcPalSlot) {
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 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor");
- dest = _hePalettes + 1024;
+ dest = _hePalettes + _hePaletteSlot;
for (i = 0; i < numcolor; i++) {
r = *ptr++;
@@ -220,48 +295,63 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
*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);
-
- for (i = 0; i < 10; ++i)
- _hePalettes[1792 + i] = i;
- for (i = 246; i < 256; ++i)
- _hePalettes[1792 + i] = i;
+ memcpy(_hePalettes, _hePalettes + _hePaletteSlot, 768);
+ 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;
-
- color = *src++;
- color = color * greenScale / 0xFF;
- if (color > 255)
- color = 255;
- *dst++ = color;
-
- color = *src++;
- color = color * blueScale / 0xFF;
- if (color > 255)
- color = 255;
- *dst++ = color;
-
- _hePalettes[1792 + j] = j;
+ r = *src++;
+ r = r * redScale / 0xFF;
+ if (r > 255)
+ r = 255;
+ *dst++ = r;
+
+ g = *src++;
+ g = g * greenScale / 0xFF;
+ if (g > 255)
+ g = 255;
+ *dst++ = g;
+
+ b = *src++;
+ b = b * blueScale / 0xFF;
+ if (b > 255)
+ b = 255;
+ *dst++ = b;
+
+ 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 @@ void ScummEngine_v99he::copyPalColor(int dst, int src) {
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;
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 5912e3d528..d588c26a77 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2152,8 +2152,9 @@ void ScummEngine_v100he::o100_systemOps() {
}
void ScummEngine_v100he::o100_cursorCommand() {
- int a, i;
+ int a, b, i;
int args[16];
+
byte subOp = fetchScriptByte();
switch (subOp) {
@@ -2168,12 +2169,12 @@ void ScummEngine_v100he::o100_cursorCommand() {
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_getWizData() {
}
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 @@ void ScummEngine_v100he::o100_getPaletteData() {
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 @@ void ScummEngine_v100he::o100_getPaletteData() {
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();
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index 5ad447b1c7..b416a0e75d 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -115,6 +115,8 @@ int ScummEngine_v60he::convertFilePath(byte *dst) {
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)
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index b71a0f9e10..4b759dec53 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -241,7 +241,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
}
void ScummEngine_v80he::o80_cursorCommand() {
- int a, i;
+ int a, b, i;
int args[16];
byte subOp = fetchScriptByte();
@@ -250,12 +250,12 @@ void ScummEngine_v80he::o80_cursorCommand() {
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;
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index cdfef1a5e5..212ba69bdc 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -1253,7 +1253,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
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 @@ void ScummEngine_v90he::o90_getWizData() {
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_getObjectData() {
}
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 @@ void ScummEngine_v90he::o90_getPaletteData() {
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 @@ void ScummEngine_v90he::o90_getPaletteData() {
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);
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index 6038433847..1c3867b980 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -254,7 +254,9 @@ bool Wiz::polygonContains(const WizPolygon &pol, int x, int y) {
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 @@ void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int
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 @@ static bool calcClipRects(int dst_w, int dst_h, int src_x, int src_y, int src_w,
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 @@ void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, in
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 @@ void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int src
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 @@ static void decodeWizMask(uint8 *&dst, uint8 &mask, int w, int maskType) {
}
}
-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 @@ void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth,
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::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth,
}
}
-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 @@ void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int
}
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 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth,
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 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co
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 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co
code = -xoff;
}
- dstPtr += dstInc * code;
+ dstPtr += dstInc;
w -= code;
} else if (code & 2) {
code = (code >> 2) + 1;
@@ -658,18 +680,7 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co
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 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co
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 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co
}
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 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C
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 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C
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 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C
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 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C
}
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 @@ void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int
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 @@ uint16 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint
}
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 @@ uint16 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, u
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 @@ void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPi
}
}
+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 @@ static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common
}
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 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in
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 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in
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 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in
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 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in
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 @@ void Wiz::displayWizImage(WizImage *pwi) {
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 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
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 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
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 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
}
cw = pvs->w;
ch = pvs->h;
+ dstPitch = pvs->pitch;
+ dstType = kDstScreen;
}
}
@@ -1376,7 +1430,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
}
}
- if (flags & kWIFRemapPalette) {
+ if (flags & kWIFRemapPalette && _vm->_bitDepth == 1) {
palPtr = rmap + 4;
}
@@ -1388,28 +1442,27 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
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::drawWizPolygon(int resNum, int state, int id, int flags, int shadow, i
}
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 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
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 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
}
} 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 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
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 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
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 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
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 @@ void Wiz::flushWizBuffer() {
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 @@ void Wiz::loadWizCursor(int resId) {
}
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 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
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 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
} 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::displayWizComplexImage(const WizParameters *params) {
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 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i
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 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i
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 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i
}
}
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 @@ void Wiz::fillWizRect(const WizParameters *params) {
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 @@ void Wiz::fillWizRect(const WizParameters *params) {
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 @@ void Wiz::fillWizRect(const WizParameters *params) {
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 @@ void Wiz::fillWizLine(const WizParameters *params) {
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 @@ void Wiz::fillWizLine(const WizParameters *params) {
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 @@ void Wiz::processWizImage(const WizParameters *params) {
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 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags
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
diff --git a/engines/scumm/he/wiz_he.h b/engines/scumm/he/wiz_he.h
index e6ea0fe57e..edc42e8788 100644
--- a/engines/scumm/he/wiz_he.h
+++ b/engines/scumm/he/wiz_he.h
@@ -142,6 +142,12 @@ enum {
kWizCopy
};
+enum DstSurface {
+ kDstScreen = 0,
+ kDstMemory = 1,
+ kDstResource = 2
+};
+
class ScummEngine_v71he;
class Wiz {
@@ -188,27 +194,32 @@ public:
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);
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index a2cd4a0d4d..c6ec85cd88 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -310,9 +310,6 @@ void ScummEngine::setDirtyColors(int min, int max) {
_palDirtyMin = min;
if (_palDirtyMax < max)
_palDirtyMax = max;
-
- if (_hePaletteCache)
- memset(_hePaletteCache, -1, 65536);
}
void ScummEngine::initCycl(const byte *ptr) {
@@ -813,16 +810,6 @@ void ScummEngine_v8::desaturatePalette(int hueScale, int satScale, int lightScal
#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;
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index cef13341b5..051873e147 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1505,7 +1505,7 @@ void ScummEngine_v90he::saveOrLoad(Serializer *s) {
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) {
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index cbfa720e79..17ffc6e5b0 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -248,6 +248,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_switchRoomEffect2 = 0;
_switchRoomEffect = 0;
+ _bitDepth = 0;
_doEffect = false;
_snapScroll = false;
_currentLights = 0;
@@ -264,8 +265,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_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 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_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 @@ ScummEngine_v90he::~ScummEngine_v90he() {
delete _logicHE;
}
if (_game.heversion >= 99) {
- free(_hePaletteCache);
free(_hePalettes);
}
}
@@ -1182,7 +1184,7 @@ void ScummEngine::setupScumm() {
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 @@ void ScummEngine::setupScumm() {
}
free(_compositeBuf);
- _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
+ _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bitDepth);
}
#ifdef ENABLE_SCUMM_7_8
@@ -1542,11 +1544,9 @@ void ScummEngine_v99he::resetScumm() {
ScummEngine_v90he::resetScumm();
- _hePaletteCache = (int16 *)malloc(65536);
- memset(_hePaletteCache, -1, 65536);
-
- _hePalettes = (uint8 *)malloc((_numPalettes + 1) * 1024);
- memset(_hePalettes, 0, (_numPalettes + 1) * 1024);
+ _hePaletteSlot = (_game.features & GF_16BIT_COLOR) ? 1280 : 1024;
+ _hePalettes = (uint8 *)malloc((_numPalettes + 1) * _hePaletteSlot);
+ memset(_hePalettes, 0, (_numPalettes + 1) * _hePaletteSlot);
// Array 129 is set to base name
len = strlen(_filenamePattern.pattern);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index ff3852ee83..c4b2ab9e56 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -954,6 +954,7 @@ public:
int _screenTop;
Common::RenderMode _renderMode;
+ uint8 _bitDepth;
protected:
ColorCycle _colorCycle[16]; // Palette cycles
@@ -1039,7 +1040,8 @@ protected:
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 @@ public:
// HE specific
byte _HEV7ActorPalette[256];
uint8 *_hePalettes;
- int16 *_hePaletteCache;
+ uint16 _hePaletteSlot;
protected:
int _shadowPaletteSize;