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.
This commit is contained in:
sluicebox 2019-03-30 22:52:56 -07:00 committed by Filippos Karapetis
parent 20d77710c9
commit b195ff5e19
2 changed files with 23 additions and 4 deletions

View file

@ -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)");

View file

@ -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);