aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2010-04-05 19:41:30 +0000
committerMatthew Hoops2010-04-05 19:41:30 +0000
commit96ccd4abccc66a3ef11b8e7b0d5ab9792285eb2a (patch)
treeaefe4bd40f90778c6c7001fd30b27c533a288553 /engines
parentc5c40607194cb8ed598b371b62ca101c706d69b8 (diff)
downloadscummvm-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.cpp75
-rw-r--r--engines/mohawk/myst_pict.h4
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