[Scummvm-cvs-logs] scummvm master -> d2ad7898d93fae702ec634af71c172bb3f1a6de9

bluegr md5 at scummvm.org
Sun Mar 6 18:23:38 CET 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
d2ad7898d9 SCI: Merged the cel data unpacking code for views and pictures


Commit: d2ad7898d93fae702ec634af71c172bb3f1a6de9
    https://github.com/scummvm/scummvm/commit/d2ad7898d93fae702ec634af71c172bb3f1a6de9
Author: md5 (md5 at scummvm.org)
Date: 2011-03-06T09:22:32-08:00

Commit Message:
SCI: Merged the cel data unpacking code for views and pictures

Changed paths:
    engines/sci/graphics/picture.cpp
    engines/sci/graphics/view.cpp



diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index d7d75ad..dbc3a88 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -224,19 +224,20 @@ void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictu
 }
 #endif
 
+extern void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCount, int rlePos, int literalPos, ViewType viewType, uint16 width, bool isMacSci11ViewData);
+
 void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX) {
 	byte *celBitmap = NULL;
 	byte *ptr = NULL;
 	byte *headerPtr = inbuffer + headerPos;
 	byte *rlePtr = inbuffer + rlePos;
-	byte *literalPtr = inbuffer + literalPos;
 	int16 displaceX, displaceY;
 	byte priority = _addToFlag ? _priority : 0;
 	byte clearColor;
 	bool compression = true;
-	byte curByte, runLength;
+	byte curByte;
 	int16 y, lastY, x, leftX, rightX;
-	int pixelNr, pixelCount;
+	int pixelCount;
 	uint16 width, height;
 
 #ifdef ENABLE_SCI32
@@ -247,12 +248,11 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
 		height = READ_LE_UINT16(headerPtr + 2);
 		displaceX = (signed char)headerPtr[4];
 		displaceY = (unsigned char)headerPtr[5];
-		if (_resourceType == SCI_PICTURE_TYPE_SCI11) {
+		if (_resourceType == SCI_PICTURE_TYPE_SCI11)
 			// SCI1.1 uses hardcoded clearcolor for pictures, even if cel header specifies otherwise
 			clearColor = _screen->getColorWhite();
-		} else {
+		else
 			clearColor = headerPtr[6];
-		}
 #ifdef ENABLE_SCI32
 	} else {
 		width = READ_SCI11ENDIAN_UINT16(headerPtr + 0);
@@ -268,91 +268,18 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
 	if (displaceX || displaceY)
 		error("unsupported embedded cel-data in picture");
 
+	// We will unpack cel-data into a temporary buffer and then plot it to screen
+	//  That needs to be done cause a mirrored picture may be requested
 	pixelCount = width * height;
 	celBitmap = new byte[pixelCount];
 	if (!celBitmap)
 		error("Unable to allocate temporary memory for picture drawing");
 
-	if (compression) {
-		// We will unpack cel-data into a temporary buffer and then plot it to screen
-		//  That needs to be done cause a mirrored picture may be requested
-		memset(celBitmap, clearColor, pixelCount);
-		pixelNr = 0;
-		ptr = celBitmap;
-		if (literalPos == 0) {
-			// decompression for data that has only one stream (vecor embedded view data)
-			switch (_resMan->getViewType()) {
-			case kViewEga:
-				while (pixelNr < pixelCount) {
-					curByte = *rlePtr++;
-					runLength = curByte >> 4;
-					memset(ptr + pixelNr, curByte & 0x0F, MIN<uint16>(runLength, pixelCount - pixelNr));
-					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)
-							ptr[pixelNr++] = *rlePtr++;
-						break;
-					case 0x80: // fill with color
-						memset(ptr + pixelNr, *rlePtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
-						pixelNr += runLength;
-						break;
-					case 0xC0: // fill with transparent
-						pixelNr += runLength;
-						break;
-					}
-				}
-				break;
-			case kViewAmiga:
-				while (pixelNr < pixelCount) {
-					curByte = *rlePtr++;
-					if (curByte & 0x07) { // fill with color
-						runLength = curByte & 0x07;
-						curByte = curByte >> 3;
-						while (runLength-- && pixelNr < pixelCount) {
-							ptr[pixelNr++] = curByte;
-						}
-					} else { // fill with transparent
-						runLength = curByte >> 3;
-						pixelNr += runLength;
-					}
-				}
-				break;
-
-			default:
-				error("Unsupported picture viewtype");
-			}
-		} else {
-			// decompression for data that has two separate streams (probably SCI 1.1 picture)
-			while (pixelNr < pixelCount) {
-				curByte = *rlePtr++;
-				runLength = curByte & 0x3F;
-				switch (curByte & 0xC0) {
-				case 0: // copy bytes as-is
-					while (runLength-- && pixelNr < pixelCount)
-						ptr[pixelNr++] = *literalPtr++;
-					break;
-				case 0x80: // fill with color
-					memset(ptr + pixelNr, *literalPtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
-					pixelNr += runLength;
-					break;
-				case 0xC0: // fill with transparent
-					pixelNr += runLength;
-					break;
-				}
-			}
-		}
-	} else {
+	if (compression)
+		unpackCelData(inbuffer, celBitmap, clearColor, pixelCount, rlePos, literalPos, _resMan->getViewType(), width, false);
+	else
 		// No compression (some SCI32 pictures)
 		memcpy(celBitmap, rlePtr, pixelCount);
-	}
 
 	Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea();
 
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 9e6854e..27fad19 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) {






More information about the Scummvm-git-logs mailing list