diff options
author | Matthew Hoops | 2010-04-05 19:41:30 +0000 |
---|---|---|
committer | Matthew Hoops | 2010-04-05 19:41:30 +0000 |
commit | 96ccd4abccc66a3ef11b8e7b0d5ab9792285eb2a (patch) | |
tree | aefe4bd40f90778c6c7001fd30b27c533a288553 /engines | |
parent | c5c40607194cb8ed598b371b62ca101c706d69b8 (diff) | |
download | scummvm-rg350-96ccd4abccc66a3ef11b8e7b0d5ab9792285eb2a.tar.gz scummvm-rg350-96ccd4abccc66a3ef11b8e7b0d5ab9792285eb2a.tar.bz2 scummvm-rg350-96ccd4abccc66a3ef11b8e7b0d5ab9792285eb2a.zip |
Add support for 32bpp DirectBitsRect in Myst ME PICT's. Fixes various cards, especially in the Myst observatory.
svn-id: r48558
Diffstat (limited to 'engines')
-rw-r--r-- | engines/mohawk/myst_pict.cpp | 75 | ||||
-rw-r--r-- | engines/mohawk/myst_pict.h | 4 |
2 files changed, 52 insertions, 27 deletions
diff --git a/engines/mohawk/myst_pict.cpp b/engines/mohawk/myst_pict.cpp index e305937951..794ec9b87f 100644 --- a/engines/mohawk/myst_pict.cpp +++ b/engines/mohawk/myst_pict.cpp @@ -66,7 +66,9 @@ Graphics::Surface *MystPICT::decodeImage(Common::SeekableReadStream *stream) { 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 @@ struct DirectBitsRectData { }; 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); - - Graphics::Surface buffer; - buffer.create(image->w, image->h, 2); + static const Graphics::PixelFormat directBitsFormat16 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); 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 @@ void MystPICT::decodeDirectBitsRect(Common::SeekableReadStream *stream, Graphics 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 @@ void MystPICT::decodeDirectBitsRect(Common::SeekableReadStream *stream, Graphics // 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; } diff --git a/engines/mohawk/myst_pict.h b/engines/mohawk/myst_pict.h index 087fd301cd..0684e3352a 100644 --- a/engines/mohawk/myst_pict.h +++ b/engines/mohawk/myst_pict.h @@ -48,10 +48,10 @@ private: 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 |