[Scummvm-cvs-logs] SF.net SVN: scummvm:[48558] scummvm/trunk/engines/mohawk

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Mon Apr 5 21:41:33 CEST 2010


Revision: 48558
          http://scummvm.svn.sourceforge.net/scummvm/?rev=48558&view=rev
Author:   mthreepwood
Date:     2010-04-05 19:41:30 +0000 (Mon, 05 Apr 2010)

Log Message:
-----------
Add support for 32bpp DirectBitsRect in Myst ME PICT's. Fixes various cards, especially in the Myst observatory.

Modified Paths:
--------------
    scummvm/trunk/engines/mohawk/myst_pict.cpp
    scummvm/trunk/engines/mohawk/myst_pict.h

Modified: scummvm/trunk/engines/mohawk/myst_pict.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/myst_pict.cpp	2010-04-05 18:50:14 UTC (rev 48557)
+++ scummvm/trunk/engines/mohawk/myst_pict.cpp	2010-04-05 19:41:30 UTC (rev 48558)
@@ -66,7 +66,9 @@
 		else if (opNum == 1 && opcode != 0x0C00)
 			error ("Cannot find PICT header opcode");
 
-		if (opcode == 0x0001) {		   // Clip
+		if (opcode == 0x0000) {        // Nop
+			stream->readUint16BE(); // Unknown
+		} else if (opcode == 0x0001) { // Clip
 			// Ignore
 			uint16 clipSize = stream->readUint16BE();
 			stream->seek(clipSize - 2, SEEK_CUR);
@@ -136,15 +138,11 @@
 };
 
 void MystPICT::decodeDirectBitsRect(Common::SeekableReadStream *stream, Graphics::Surface *image) {
-	static const Graphics::PixelFormat directBitsFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+	static const Graphics::PixelFormat directBitsFormat16 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
 
-	Graphics::Surface buffer;
-	buffer.create(image->w, image->h, 2);
-
 	DirectBitsRectData directBitsData;
-
 	directBitsData.pixMap.baseAddr = stream->readUint32BE();
-	directBitsData.pixMap.rowBytes = stream->readUint16BE();
+	directBitsData.pixMap.rowBytes = stream->readUint16BE() & 0x3fff;
 	directBitsData.pixMap.bounds.top = stream->readUint16BE();
 	directBitsData.pixMap.bounds.left = stream->readUint16BE();
 	directBitsData.pixMap.bounds.bottom = stream->readUint16BE();
@@ -171,9 +169,12 @@
 	directBitsData.dstRect.right = stream->readUint16BE();
 	directBitsData.mode = stream->readUint16BE();
 
-	if (directBitsData.pixMap.pixelSize != 16)
+	if (directBitsData.pixMap.pixelSize != 16 && directBitsData.pixMap.pixelSize != 32)
 		error("Unhandled directBitsRect bitsPerPixel %d", directBitsData.pixMap.pixelSize);
 
+	byte bytesPerPixel = (directBitsData.pixMap.pixelSize == 16) ? 2 : 3;
+	byte *buffer = new byte[image->w * image->h * bytesPerPixel];
+
 	// Read in amount of data per row
 	for (uint16 i = 0; i < directBitsData.pixMap.bounds.height(); i++) {
 		if (directBitsData.pixMap.packType == 1 || directBitsData.pixMap.rowBytes < 8) { // Unpacked, Pad-Byte
@@ -184,45 +185,69 @@
 			// TODO
 		} else if (directBitsData.pixMap.packType > 2) { // Packed
 			uint16 byteCount = (directBitsData.pixMap.rowBytes > 250) ? stream->readUint16BE() : stream->readByte();
-			decodeDirectBitsLine((byte *)buffer.getBasePtr(0, i), directBitsData.pixMap.rowBytes, stream->readStream(byteCount));
+			decodeDirectBitsLine(buffer + i * image->w * bytesPerPixel, directBitsData.pixMap.rowBytes, stream->readStream(byteCount), bytesPerPixel);
 		}
 	}
-
-	// Convert from 16-bit to whatever surface we need
-	for (uint16 y = 0; y < buffer.h; y++) {
-		for (uint16 x = 0; x < buffer.w; x++) {
-			byte r = 0, g = 0, b = 0;
-			uint16 color = READ_BE_UINT16(buffer.getBasePtr(x, y));
-			directBitsFormat.colorToRGB(color, r, g, b);
-			*((uint16 *)image->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
+	
+	if (bytesPerPixel == 2) {
+		// Convert from 16-bit to whatever surface we need
+		for (uint16 y = 0; y < image->h; y++) {
+			for (uint16 x = 0; x < image->w; x++) {
+				byte r = 0, g = 0, b = 0;
+				uint32 color = READ_BE_UINT16(buffer + (y * image->w + x) * bytesPerPixel);
+				directBitsFormat16.colorToRGB(color, r, g, b);
+				*((uint16 *)image->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
+			}
 		}
+	} else {
+		// Convert from 24-bit (planar!) to whatever surface we need
+		for (uint16 y = 0; y < image->h; y++) {
+			for (uint16 x = 0; x < image->w; x++) {
+				byte r = *(buffer + y * image->w * 3 + x);
+				byte g = *(buffer + y * image->w * 3 + image->w + x);
+				byte b = *(buffer + y * image->w * 3 + image->w * 2 + x);
+				*((uint16 *)image->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
+			}
+		}
 	}
+
+	delete[] buffer;
 }
 
-void MystPICT::decodeDirectBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data) {
+void MystPICT::decodeDirectBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bytesPerPixel) {
 	uint32 dataDecoded = 0;
+	byte bytesPerDecode = (bytesPerPixel == 2) ? 2 : 1;
+
 	while (data->pos() < data->size() && dataDecoded < length) {
 		byte op = data->readByte();
 
 		if (op & 0x80) {
 			uint32 runSize = (op ^ 255) + 2;
-			byte value1 = data->readByte();
-			byte value2 = data->readByte();
+			uint16 value = (bytesPerDecode == 2) ? data->readUint16BE() : data->readByte();
+
 			for (uint32 i = 0; i < runSize; i++) {
-				*out++ = value1;
-				*out++ = value2;
+				if (bytesPerDecode == 2) {
+					WRITE_BE_UINT16(out, value);
+					out += 2;
+				} else
+					*out++ = value;
 			}
-			dataDecoded += runSize * 2;
+			dataDecoded += runSize * bytesPerDecode;
 		} else {
-			uint32 runSize = (op + 1) * 2;
+			uint32 runSize = (op + 1) * bytesPerDecode;
 			for (uint32 i = 0; i < runSize; i++)
 				*out++ = data->readByte();
 			dataDecoded += runSize;
 		}
 	}
 
+	// HACK: rowBytes is in 32-bit, but the data is 24-bit...
+	if (bytesPerPixel == 3)
+		dataDecoded += length / 4;
+
 	if (length != dataDecoded)
-		warning("Mismatched DirectBits read");
+		warning("Mismatched DirectBits read (%d/%d)", dataDecoded, length);
+
 	delete data;
 }
 

Modified: scummvm/trunk/engines/mohawk/myst_pict.h
===================================================================
--- scummvm/trunk/engines/mohawk/myst_pict.h	2010-04-05 18:50:14 UTC (rev 48557)
+++ scummvm/trunk/engines/mohawk/myst_pict.h	2010-04-05 19:41:30 UTC (rev 48558)
@@ -48,10 +48,10 @@
 	Graphics::PixelFormat _pixelFormat;
 
 	void decodeDirectBitsRect(Common::SeekableReadStream *stream, Graphics::Surface *image);
-	void decodeDirectBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data);
+	void decodeDirectBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bytesPerPixel);
 	void decodeCompressedQuickTime(Common::SeekableReadStream *stream, Graphics::Surface *image);
 };
 
-}
+} // End of namespace Mohawk
 
 #endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list