diff options
author | Travis Howell | 2008-12-27 06:11:56 +0000 |
---|---|---|
committer | Travis Howell | 2008-12-27 06:11:56 +0000 |
commit | f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0 (patch) | |
tree | 39e34b7d248dc4cd0e4c007678c1291270034877 | |
parent | 6187ec38fb05ce013e5be59a21acba8b03f7334e (diff) | |
download | scummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.tar.gz scummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.tar.bz2 scummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.zip |
Add basic code for wizImage compression type 5.
svn-id: r35568
-rw-r--r-- | engines/scumm/he/wiz_he.cpp | 212 | ||||
-rw-r--r-- | engines/scumm/he/wiz_he.h | 8 |
2 files changed, 189 insertions, 31 deletions
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 52732866fe..43611f16fe 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -353,6 +353,30 @@ 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 + + Common::Rect r1, r2; + if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { + dst += r2.left + r2.top * dstw; + if (flags & kWIFFlipY) { + const int dy = (srcy < 0) ? srcy : (srch - r1.height()); + r1.translate(0, dy); + } + if (flags & kWIFFlipX) { + const int dx = (srcx < 0) ? srcx : (srcw - r1.width()); + r1.translate(dx, 0); + } + if (xmapPtr) { + decompress16BitWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr); + } else if (palPtr) { + decompress16BitWizImage<kWizRMap>(dst, dstw, src, r1, flags, palPtr); + } else { + decompress16BitWizImage<kWizCopy>(dst, dstw, 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) { Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { @@ -528,7 +552,6 @@ void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int 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 - // HACK: Skip every second bit for now Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { if (flags & (kWIFFlipY | kWIFFlipX)) { @@ -547,7 +570,7 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, dst += r2.left + r2.top * dstw; while (h--) { for (int i = 0; i < w; ++i) { - uint8 col = src[2 * i]; + uint16 col = READ_LE_UINT16(src + 2 * i) / 256; if (transColor == -1 || transColor != col) { dst[i] = palPtr[col]; } @@ -559,6 +582,129 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, } 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) { + const uint8 *dataPtr, *dataPtrNext; + uint8 code, *dstPtr, *dstPtrNext; + int h, w, xoff, dstInc; + + if (type == kWizXMap) { + assert(xmapPtr != 0); + } + if (type == kWizRMap) { + assert(palPtr != 0); + } + + dstPtr = dst; + dataPtr = src; + + // Skip over the first 'srcRect->top' lines in the data + h = srcRect.top; + while (h--) { + dataPtr += READ_LE_UINT16(dataPtr) + 2; + } + h = srcRect.height(); + w = srcRect.width(); + if (h <= 0 || w <= 0) + return; + + if (flags & kWIFFlipY) { + dstPtr += (h - 1) * dstPitch; + dstPitch = -dstPitch; + } + dstInc = 1; + if (flags & kWIFFlipX) { + dstPtr += w - 1; + dstInc = -1; + } + + while (h--) { + xoff = srcRect.left; + w = srcRect.width(); + uint16 lineSize = READ_LE_UINT16(dataPtr); dataPtr += 2; + dstPtrNext = dstPtr + dstPitch; + dataPtrNext = dataPtr + lineSize; + if (lineSize != 0) { + while (w > 0) { + code = *dataPtr++; + if (code & 1) { + code >>= 1; + if (xoff > 0) { + xoff -= code; + if (xoff >= 0) + continue; + + code = -xoff; + } + dstPtr += dstInc * code; + w -= code; + } else if (code & 2) { + code = (code >> 2) + 1; + if (xoff > 0) { + xoff -= code; + ++dataPtr; + if (xoff >= 0) + continue; + + code = -xoff; + --dataPtr; + } + w -= code; + if (w < 0) { + code += w; + } + while (code--) { + uint16 col = READ_LE_UINT16(dataPtr) / 256; + if (type == kWizXMap) { + *dstPtr = xmapPtr[col * 256 + *dstPtr]; + } + if (type == kWizRMap) { + *dstPtr = palPtr[col]; + } + if (type == kWizCopy) { + *dstPtr = col; + } + dstPtr += dstInc; + } + dataPtr+= 2; + } else { + code = (code >> 2) + 1; + if (xoff > 0) { + xoff -= code; + dataPtr += code; + if (xoff >= 0) + continue; + + code = -xoff; + dataPtr += xoff; + } + w -= code; + if (w < 0) { + code += w; + } + while (code--) { + uint16 col = READ_LE_UINT16(dataPtr) / 256; + if (type == kWizXMap) { + *dstPtr = xmapPtr[col * 256 + *dstPtr]; + } + if (type == kWizRMap) { + *dstPtr = palPtr[col]; + } + if (type == kWizCopy) { + *dstPtr = col; + } + dataPtr += 2; + + dstPtr += dstInc; + } + } + } + } + dataPtr = dataPtrNext; + dstPtr = dstPtrNext; + } +} + +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) { const uint8 *dataPtr, *dataPtrNext; uint8 code, *dstPtr, *dstPtrNext; @@ -703,7 +849,7 @@ void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int } } -int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h) { +int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint bitDepth) { if (x < 0 || x >= w || y < 0 || y >= h) { return 0; } @@ -729,20 +875,24 @@ int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h) return 1; } x -= code; - ++data; + data += (bitDepth == 16) ? 2 : 1; } else { code = (code >> 2) + 1; if (code > x) { return 1; } x -= code; - data += code; + data += (bitDepth == 16) ? code * 2 : code; } } - return (~data[0]) & 1; + + if (bitDepth == 16) + return (~READ_LE_UINT16(data)) & 1; + else + return (~data[0]) & 1; } -uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) { +uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color) { if (x < 0 || x >= w || y < 0 || y >= h) { return color; } @@ -765,27 +915,35 @@ uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 } else if (code & 2) { code = (code >> 2) + 1; if (code > x) { - return data[0]; + return (bitDepth == 16) ? READ_LE_UINT16(data) : data[0]; } x -= code; - ++data; + data += (bitDepth == 16) ? 2 : 1; } else { code = (code >> 2) + 1; if (code > x) { - return data[x]; + return (bitDepth == 16) ? READ_LE_UINT16(data + x) : data[x]; } x -= code; - data += code; + data += (bitDepth == 16) ? code * 2 : code; } } - return (data[0] & 1) ? color : data[1]; + + if (bitDepth == 16) + return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 1); + else + return (data[0] & 1) ? color : data[1]; + } -uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) { +uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color) { if (x < 0 || x >= w || y < 0 || y >= h) { return color; } - return data[y * w + x]; + if (bitDepth == 16) + return READ_LE_UINT16(data + y * w + x * 2); + else + return data[y * w + x]; } void Wiz::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect &rCapt) { @@ -1243,6 +1401,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int break; case 5: // TODO: 16bit color compressed image + copy16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr); break; default: error("drawWizImage: Unhandled wiz compression type %d", comp); @@ -1634,7 +1793,8 @@ void Wiz::displayWizComplexImage(const WizParameters *params) { ++_imagesNum; } else { if (sourceImage != 0) { - // TODO + // TODO: Add support for kWPFMaskImg + drawWizImage(params->sourceImage, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette); } else if (params->processFlags & (kWPFScaled | kWPFRotate)) { drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette); } else { @@ -2102,32 +2262,30 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags switch (c) { case 0: if (_vm->_game.heversion >= 99) { - ret = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0; + ret = getRawWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0; } else { ret = 0; } break; case 1: - ret = isWizPixelNonTransparent(wizd, x, y, w, h); + ret = isWizPixelNonTransparent(wizd, x, y, w, h, 8); break; case 2: - // TODO: 16bit color uncompressed image type - debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c); + ret = getRawWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0; break; case 4: // TODO: Unknown image type debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c); break; case 5: - // TODO: 16bit color compressed image type - debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c); + ret = isWizPixelNonTransparent(wizd, x, y, w, h, 16); break; default: error("isWizPixelNonTransparent: Unhandled wiz compression type %d", c); break; } } - return ret; + return 1; } uint8 Wiz::getWizPixelColor(int resNum, int state, int x, int y, int flags) { @@ -2144,25 +2302,23 @@ uint8 Wiz::getWizPixelColor(int resNum, int state, int x, int y, int flags) { switch (c) { case 0: if (_vm->_game.heversion >= 99) { - color = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); + color = getRawWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); } else { color = _vm->VAR(_vm->VAR_WIZ_TCOLOR); } break; case 1: - color = getWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); + color = getWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; case 2: - // TODO: 16bit color uncompressed image type - debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c); + color = getRawWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; case 4: // TODO: Unknown image type debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c); break; case 5: - // TODO: 16bit color compressed image type - debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c); + color = getWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; default: error("getWizPixelColor: Unhandled wiz compression type %d", c); diff --git a/engines/scumm/he/wiz_he.h b/engines/scumm/he/wiz_he.h index 6887b45299..b2baf8f2b0 100644 --- a/engines/scumm/he/wiz_he.h +++ b/engines/scumm/he/wiz_he.h @@ -203,13 +203,15 @@ public: 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); + static 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); static 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> static 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); - int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h); - uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color); - uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color); + int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint bitdepth); + uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color); + uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color); void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect& rCapt); void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect& rCapt); |