aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/view.cpp
diff options
context:
space:
mode:
authormd52011-03-06 19:22:32 +0200
committermd52011-03-06 19:22:32 +0200
commitd2ad7898d93fae702ec634af71c172bb3f1a6de9 (patch)
tree6d727c6401d08520de1617b9c770428aacb3c477 /engines/sci/graphics/view.cpp
parent0b24fc3accc2ce232377a5828871dd408d594e8f (diff)
downloadscummvm-rg350-d2ad7898d93fae702ec634af71c172bb3f1a6de9.tar.gz
scummvm-rg350-d2ad7898d93fae702ec634af71c172bb3f1a6de9.tar.bz2
scummvm-rg350-d2ad7898d93fae702ec634af71c172bb3f1a6de9.zip
SCI: Merged the cel data unpacking code for views and pictures
Diffstat (limited to 'engines/sci/graphics/view.cpp')
-rw-r--r--engines/sci/graphics/view.cpp216
1 files changed, 111 insertions, 105 deletions
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 9e6854e3b9..27fad19eca 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -370,22 +370,120 @@ void GfxView::getCelScaledRect(int16 loopNo, int16 celNo, int16 x, int16 y, int1
outRect.top = outRect.bottom - scaledHeight;
}
+void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCount, int rlePos, int literalPos, ViewType viewType, uint16 width, bool isMacSci11ViewData) {
+ byte *outPtr = celBitmap;
+ byte curByte, runLength;
+ byte *rlePtr = inBuffer + rlePos;
+ byte *literalPtr = inBuffer + literalPos;
+ int pixelNr = 0;
+
+ memset(celBitmap, clearColor, pixelCount);
+
+ if (!literalPos) {
+ // decompression for data that has only one combined stream
+ switch (viewType) {
+ case kViewEga:
+ while (pixelNr < pixelCount) {
+ curByte = *rlePtr++;
+ runLength = curByte >> 4;
+ memset(outPtr + pixelNr, curByte & 0x0F, MIN<uint16>(runLength, pixelCount - pixelNr));
+ pixelNr += runLength;
+ }
+ break;
+ case kViewAmiga:
+ while (pixelNr < pixelCount) {
+ curByte = *rlePtr++;
+ if (curByte & 0x07) { // fill with color
+ runLength = curByte & 0x07;
+ curByte = curByte >> 3;
+ while (runLength-- && pixelNr < pixelCount) {
+ outPtr[pixelNr++] = curByte;
+ }
+ } else { // fill with transparent
+ runLength = curByte >> 3;
+ pixelNr += runLength;
+ }
+ }
+ break;
+ case kViewVga:
+ case kViewVga11:
+ while (pixelNr < pixelCount) {
+ curByte = *rlePtr++;
+ runLength = curByte & 0x3F;
+ switch (curByte & 0xC0) {
+ case 0: // copy bytes as-is
+ while (runLength-- && pixelNr < pixelCount)
+ outPtr[pixelNr++] = *rlePtr++;
+ break;
+ case 0x40: // copy bytes as is (In copy case, runLength can go upto 127 i.e. pixel & 0x40). Fixes bug #3135872.
+ runLength += 64;
+ break;
+ case 0x80: // fill with color
+ memset(outPtr + pixelNr, *rlePtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
+ pixelNr += runLength;
+ break;
+ case 0xC0: // fill with transparent
+ pixelNr += runLength;
+ break;
+ }
+ }
+ break;
+ default:
+ error("Unsupported picture viewtype");
+ }
+ } else {
+ if (isMacSci11ViewData) {
+ // KQ6/Freddy Pharkas use byte lengths, all others use uint16
+ // The SCI devs must have realized that a max of 255 pixels wide
+ // was not very good for 320 or 640 width games.
+ bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS);
+
+ // compression for SCI1.1+ Mac
+ while (pixelNr < pixelCount) {
+ uint32 pixelLine = pixelNr;
+
+ if (hasByteLengths) {
+ pixelNr += *rlePtr++;
+ runLength = *rlePtr++;
+ } else {
+ pixelNr += READ_BE_UINT16(rlePtr);
+ runLength = READ_BE_UINT16(rlePtr + 2);
+ rlePtr += 4;
+ }
+
+ while (runLength-- && pixelNr < pixelCount)
+ outPtr[pixelNr++] = *literalPtr++;
+
+ pixelNr = pixelLine + width;
+ }
+ }
+ // decompression for data that has two separate streams (probably SCI 1.1 view)
+ while (pixelNr < pixelCount) {
+ curByte = *rlePtr++;
+ runLength = curByte & 0x3F;
+ switch (curByte & 0xC0) {
+ case 0: // copy bytes as-is
+ while (runLength-- && pixelNr < pixelCount)
+ outPtr[pixelNr++] = *literalPtr++;
+ break;
+ case 0x80: // fill with color
+ memset(outPtr + pixelNr, *literalPtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
+ pixelNr += runLength;
+ break;
+ case 0xC0: // fill with transparent
+ pixelNr += runLength;
+ break;
+ }
+ }
+ }
+}
+
void GfxView::unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCount) {
const CelInfo *celInfo = getCelInfo(loopNo, celNo);
- byte *rlePtr;
- byte *literalPtr;
- uint32 pixelNo = 0, runLength;
- byte pixel;
if (celInfo->offsetEGA) {
// decompression for EGA views
- literalPtr = _resourceData + _loop[loopNo].cel[celNo].offsetEGA;
- while (pixelNo < pixelCount) {
- pixel = *literalPtr++;
- runLength = pixel >> 4;
- memset(outPtr + pixelNo, pixel & 0x0F, MIN<uint32>(runLength, pixelCount - pixelNo));
- pixelNo += runLength;
- }
+ unpackCelData(_resourceData, outPtr, 0, pixelCount, celInfo->offsetEGA, 0, _resMan->getViewType(), celInfo->width, false);
} else {
// We fill the buffer with transparent pixels, so that we can later skip
// over pixels to automatically have them transparent
@@ -408,100 +506,8 @@ void GfxView::unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCou
clearColor = 0;
}
- memset(outPtr, clearColor, pixelCount);
-
- rlePtr = _resourceData + celInfo->offsetRLE;
- if (!celInfo->offsetLiteral) { // no additional literal data
- if (_resMan->getViewType() == kViewAmiga) {
- // decompression for amiga views
- while (pixelNo < pixelCount) {
- pixel = *rlePtr++;
- if (pixel & 0x07) { // fill with color
- runLength = pixel & 0x07;
- pixel = pixel >> 3;
- while (runLength-- && pixelNo < pixelCount) {
- outPtr[pixelNo++] = pixel;
- }
- } else { // fill with transparent
- runLength = pixel >> 3;
- pixelNo += runLength;
- }
- }
- } else {
- // decompression for data that has just one combined stream
- while (pixelNo < pixelCount) {
- pixel = *rlePtr++;
- runLength = pixel & 0x3F;
- switch (pixel & 0xC0) {
- case 0x40: // copy bytes as is (In copy case, runLength can go upto 127 i.e. pixel & 0x40)
- runLength += 64;
- case 0x00: // copy bytes as-is
- while (runLength-- && pixelNo < pixelCount)
- outPtr[pixelNo++] = *rlePtr++;
- break;
- case 0x80: // fill with color
- memset(outPtr + pixelNo, *rlePtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
- pixelNo += runLength;
- break;
- case 0xC0: // fill with transparent
- pixelNo += runLength;
- break;
- }
- }
- }
- } else {
- literalPtr = _resourceData + celInfo->offsetLiteral;
- if (celInfo->offsetRLE) {
- if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() == SCI_VERSION_1_1) {
- // KQ6/Freddy Pharkas use byte lengths, all others use uint16
- // The SCI devs must have realized that a max of 255 pixels wide
- // was not very good for 320 or 640 width games.
- bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS);
-
- // compression for SCI1.1+ Mac
- while (pixelNo < pixelCount) {
- uint32 pixelLine = pixelNo;
-
- if (hasByteLengths) {
- pixelNo += *rlePtr++;
- runLength = *rlePtr++;
- } else {
- pixelNo += READ_BE_UINT16(rlePtr);
- runLength = READ_BE_UINT16(rlePtr + 2);
- rlePtr += 4;
- }
-
- while (runLength-- && pixelNo < pixelCount)
- outPtr[pixelNo++] = *literalPtr++;
-
- pixelNo = pixelLine + celInfo->width;
- }
- } else {
- // decompression for data that has separate rle and literal streams
- while (pixelNo < pixelCount) {
- pixel = *rlePtr++;
- runLength = pixel & 0x3F;
- switch (pixel & 0xC0) {
- case 0: // copy bytes as-is
- while (runLength-- && pixelNo < pixelCount)
- outPtr[pixelNo++] = *literalPtr++;
- break;
- case 0x80: // fill with color
- memset(outPtr + pixelNo, *literalPtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
- pixelNo += runLength;
- break;
- case 0xC0: // fill with transparent
- pixelNo += runLength;
- break;
- }
- }
- }
- } else {
- // literal stream only, so no compression
- memcpy(outPtr, literalPtr, pixelCount);
- pixelNo = pixelCount;
- }
- }
+ bool isMacSci11ViewData = g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() == SCI_VERSION_1_1;
+ unpackCelData(_resourceData, outPtr, clearColor, pixelCount, celInfo->offsetRLE, celInfo->offsetLiteral, _resMan->getViewType(), celInfo->width, isMacSci11ViewData);
// Swap 0 and 0xff pixels for Mac SCI1.1+ games (see above)
if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1) {