aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/he
diff options
context:
space:
mode:
authorTravis Howell2008-12-27 06:11:56 +0000
committerTravis Howell2008-12-27 06:11:56 +0000
commitf5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0 (patch)
tree39e34b7d248dc4cd0e4c007678c1291270034877 /engines/scumm/he
parent6187ec38fb05ce013e5be59a21acba8b03f7334e (diff)
downloadscummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.tar.gz
scummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.tar.bz2
scummvm-rg350-f5b61ffd03363c3d6e2b9a723f2d4e15cc6e33e0.zip
Add basic code for wizImage compression type 5.
svn-id: r35568
Diffstat (limited to 'engines/scumm/he')
-rw-r--r--engines/scumm/he/wiz_he.cpp212
-rw-r--r--engines/scumm/he/wiz_he.h8
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);