[Scummvm-cvs-logs] scummvm master -> 7e517b7808569f90d6257310702c6d52ca2d7699

bluegr md5 at scummvm.org
Wed Mar 9 14:08:55 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:
7e517b7808 SCI: Some cleanup and fixes to the view unpacking code


Commit: 7e517b7808569f90d6257310702c6d52ca2d7699
    https://github.com/scummvm/scummvm/commit/7e517b7808569f90d6257310702c6d52ca2d7699
Author: md5 (md5 at scummvm.org)
Date: 2011-03-09T05:06:42-08:00

Commit Message:
SCI: Some cleanup and fixes to the view unpacking code

- Added comments for all the different view unpacking algorithms
- Merged the SCI1 VGA and SCI1.1 VGA unpacking code
- Fixed views in Longbow Amiga (the palette is still broken, though)
- Used memset()/memcpy() instead of looping through
- Fixed a regression of rev. d2ad789 (LSL1 Spanish, bug #3135872)

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



diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index fd74714..870e3c9 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -375,116 +375,138 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo
 	byte *outPtr = celBitmap;
 	byte curByte, runLength;
 	byte *rlePtr = inBuffer + rlePos;
+	// The existence of a literal position pointer signifies data with two
+	// separate streams, most likely a SCI1.1 view
 	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;
+	// View unpacking:
+	//
+	// EGA:
+	// Each byte is like XXXXYYYY (XXXX: 0 - 15, YYYY: 0 - 15)
+	// Set the next XXXX pixels to YYYY
+	//
+	// Amiga:
+	// Each byte is like XXXXXYYY (XXXXX: 0 - 31, YYY: 0 - 7)
+	// - Case A: YYY != 0
+	//   Set the next YYY pixels to XXXXX
+	// - Case B: YYY == 0
+	//   Skip the next XXXXX pixels (i.e. transparency)
+	//
+	// Amiga 64:
+	// Each byte is like XXYYYYYY (XX: 0 - 3, YYYYYY: 0 - 63)
+	// - Case A: XX != 0
+	//   Set the next XX pixels to YYYYYY
+	// - Case B: XX == 0
+	//   Skip the next YYYYYY pixels (i.e. transparency)
+	//
+	// VGA:
+	// Each byte is like XXYYYYYY (YYYYY: 0 - 63)
+	// - Case A: XX == 00 (binary)
+	//   Copy next YYYYYY bytes as-is
+	// - Case B: XX == 01 (binary)
+	//   Same as above, copy YYYYYY + 64 bytes as-is
+	// - Case C: XX == 10 (binary)
+	//   Set the next YYYYY pixels to the next byte value
+	// - Case D: XX == 11 (binary)
+	//   Skip the next YYYYY pixels (i.e. transparency)
+
+	if (literalPos && 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;
 			}
-			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;
-				}
+
+			while (runLength-- && pixelNr < pixelCount)
+				outPtr[pixelNr++] = *literalPtr++;
+
+			pixelNr = pixelLine + width;
+		}
+		return;
+	}
+
+	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;
+				memset(outPtr + pixelNr, curByte, MIN<uint16>(runLength, pixelCount - pixelNr));
+			} else { // skip the next pixels (transparency)
+				runLength = curByte >> 3;
 			}
-			break;
-		case kViewAmiga64:
-			// TODO: This isn't 100% right. Implement it fully.
-			while (pixelNr < pixelCount) {
-				curByte = *rlePtr++;
+			pixelNr += runLength;
+		}
+		break;
+	case kViewAmiga64:
+		while (pixelNr < pixelCount) {
+			curByte = *rlePtr++;
+			if (curByte & 0xC0) { // fill with color
 				runLength = curByte >> 6;
 				memset(outPtr + pixelNr, curByte & 0x3F, MIN<uint16>(runLength, pixelCount - pixelNr));
-				pixelNr += runLength;
-			}
-			break;
-		case kViewVga:
-		case kViewVga11:
-			while (pixelNr < pixelCount) {
-				curByte = *rlePtr++;
+			} else { // skip the next pixels (transparency)
 				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");
+			pixelNr += runLength;
 		}
-	} else {
-		// decompression for data that has two separate streams (probably a SCI 1.1 view)
-		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++;
+		break;
+	case kViewVga:
+	case kViewVga11:
+		while (pixelNr < pixelCount) {
+			curByte = *rlePtr++;
+			runLength = curByte & 0x3F;
+
+			switch (curByte & 0xC0) {
+			case 0x40: // copy bytes as is (In copy case, runLength can go up to 127 i.e. pixel & 0x40). Fixes bug #3135872.
+				runLength += 64;
+			case 0x00: // copy bytes as-is
+				if (!literalPos) {
+					memcpy(outPtr + pixelNr, rlePtr, MIN<uint16>(runLength, pixelCount - pixelNr));
+					rlePtr += runLength;
 				} else {
-					pixelNr += READ_BE_UINT16(rlePtr);
-					runLength = READ_BE_UINT16(rlePtr + 2);
-					rlePtr += 4;
-				}
-
-				while (runLength-- && pixelNr < pixelCount)
-					outPtr[pixelNr++] = *literalPtr++;
-
-				pixelNr = pixelLine + width;
-			}
-		} else {
-			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
+					memcpy(outPtr + pixelNr, literalPtr, MIN<uint16>(runLength, pixelCount - pixelNr));
+					literalPtr += runLength;
+				}			
+				break;
+			case 0x80: // fill with color
+				if (!literalPos)
+					memset(outPtr + pixelNr,     *rlePtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
+				else
 					memset(outPtr + pixelNr, *literalPtr++, MIN<uint16>(runLength, pixelCount - pixelNr));
-					pixelNr += runLength;
-					break;
-				case 0xC0: // fill with transparent
-					pixelNr += runLength;
-					break;
-				}
+				break;
+			case 0xC0: // skip the next pixels (transparency)
+				break;
 			}
+
+			pixelNr += runLength;
 		}
+		break;
+	default:
+		error("Unsupported picture viewtype");
 	}
 }
 






More information about the Scummvm-git-logs mailing list