From b195ff5e190388f8598a7db4822d57f73f4b6b65 Mon Sep 17 00:00:00 2001 From: sluicebox Date: Sat, 30 Mar 2019 22:52:56 -0700 Subject: GRAPHICS: Add support for PICT opcode $90 BitsRect Add limited support for unpacked PICT bits which FPFP Mac requires. SCI games use packed PICT bits unless an image is less than 8 bytes per row in which case they can't be packed, like FPFP's shovel icon. Fixes bug #7059 which prevents the game from being completed. --- image/pict.cpp | 26 ++++++++++++++++++++++---- image/pict.h | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'image') diff --git a/image/pict.cpp b/image/pict.cpp index 1a1d03d7de..a82bba034e 100644 --- a/image/pict.cpp +++ b/image/pict.cpp @@ -75,6 +75,7 @@ void PICTDecoder::setupOpcodesCommon() { void PICTDecoder::setupOpcodesNormal() { setupOpcodesCommon(); + OPCODE(0x0090, on_bitsRect, "BitsRect"); OPCODE(0x0098, on_packBitsRect, "PackBitsRect"); OPCODE(0x009A, on_directBitsRect, "DirectBitsRect"); OPCODE(0x8200, on_compressedQuickTime, "CompressedQuickTime"); @@ -165,6 +166,11 @@ void PICTDecoder::o_headerOp(Common::SeekableReadStream &stream) { stream.readUint32BE(); // Reserved } +void PICTDecoder::on_bitsRect(Common::SeekableReadStream &stream) { + // Copy unpacked data with clipped rectangle (8bpp or lower) + unpackBitsRect(stream, true); +} + void PICTDecoder::on_packBitsRect(Common::SeekableReadStream &stream) { // Unpack data (8bpp or lower) unpackBitsRect(stream, true); @@ -344,13 +350,25 @@ void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool withPa // Read in amount of data per row for (uint16 i = 0; i < packBitsData.pixMap.bounds.height(); i++) { - // NOTE: Compression 0 is "default". The format in SCI games is packed when 0. - // In the future, we may need to have something to set the "default" packing + // NOTE: Compression 0 is "default". The format in SCI games is packed when 0 + // unless rowBytes is less than 8 in which case the pict can't be packed, + // such as the shovel inventory icon in FPFP Mac. (bug #7059) + // In the future, we may need to have something to set the "default" packing // format, but this is good for now. if (packBitsData.pixMap.packType == 1 || packBitsData.pixMap.rowBytes < 8) { // Unpacked, Pad-Byte (on 24-bit) - // TODO: Finish this. Hasn't been needed (yet). - error("Unpacked DirectBitsRect data (padded)"); + // only support 1 bpp for now as there is currently only one known + // SCI pict that requires any unpacked support. + if (bytesPerPixel == 1 && packBitsData.pixMap.pixelSize == 8) { + stream.read(&buffer[i * width], width); + if (width < packBitsData.pixMap.rowBytes) { + // skip padding and/or clipped bytes + stream.seek(packBitsData.pixMap.rowBytes - width, SEEK_CUR); + } + } else { + // TODO: Finish this. Hasn't been needed (yet). + error("Unpacked DirectBitsRect data (padded) with bytes per pixel: %d and pixel size: %d", bytesPerPixel, packBitsData.pixMap.pixelSize); + } } else if (packBitsData.pixMap.packType == 2) { // Unpacked, No Pad-Byte (on 24-bit) // TODO: Finish this. Hasn't been needed (yet). error("Unpacked DirectBitsRect data (not padded)"); diff --git a/image/pict.h b/image/pict.h index 77b450f4a2..7fd65c6052 100644 --- a/image/pict.h +++ b/image/pict.h @@ -123,6 +123,7 @@ private: // Regular-mode Opcodes void setupOpcodesNormal(); + DECLARE_OPCODE(on_bitsRect); DECLARE_OPCODE(on_packBitsRect); DECLARE_OPCODE(on_directBitsRect); DECLARE_OPCODE(on_compressedQuickTime); -- cgit v1.2.3