From 48416a7f038dba69a72aa9de2fef1dc1e9087405 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 18 Nov 2010 13:31:12 +0000 Subject: MOHAWK: Implement the old Mohawk bitmap format (thanks to fuzzie) svn-id: r54319 --- engines/mohawk/bitmap.cpp | 51 ++++++++++++++++++++++++++++++++++++++------- engines/mohawk/bitmap.h | 7 ++++++- engines/mohawk/graphics.cpp | 38 ++++++++++++++++----------------- 3 files changed, 68 insertions(+), 28 deletions(-) (limited to 'engines/mohawk') diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp index b622b3efbf..29186c4b91 100644 --- a/engines/mohawk/bitmap.cpp +++ b/engines/mohawk/bitmap.cpp @@ -687,19 +687,54 @@ ImageData* MystBitmap::decodeImage(Common::SeekableReadStream* stream) { ImageData *OldMohawkBitmap::decodeImage(Common::SeekableReadStream *stream) { Common::SeekableSubReadStreamEndian *endianStream = (Common::SeekableSubReadStreamEndian *)stream; - // The format part is just a guess at this point. Note that the width and height roles have been reversed! - - _header.height = endianStream->readUint16() & 0x3FF; - _header.width = endianStream->readUint16() & 0x3FF; - _header.bytesPerRow = endianStream->readUint16() & 0x3FE; + // 12 bytes header for the image _header.format = endianStream->readUint16(); + _header.bytesPerRow = endianStream->readUint16(); + _header.width = endianStream->readUint16(); + _header.height = endianStream->readUint16(); + uint16 unknown0 = endianStream->readUint16(); // TODO + uint16 unknown1 = endianStream->readUint16(); // TODO + + debug(2, "Decoding Old Mohawk Bitmap (%dx%d, %d bytesPerRow, %04x Format)", _header.width, _header.height, _header.bytesPerRow, _header.format); + debug(2, "Unknowns %04x, %04x", unknown0, unknown1); // TODO + + if ((_header.format & 0xf0) != kOldPackLZ) + error("tried to decode non-LZ encoded OldMohawkBitmap"); + + // 12 bytes header for the compressed data + uint32 uncompressedSize = endianStream->readUint32(); + uint32 compressedSize = endianStream->readUint32(); + uint16 posBits = endianStream->readUint16(); + uint16 lengthBits = endianStream->readUint16(); + + if (compressedSize != (uint32)endianStream->size() - 24) + error("More bytes (%d) remaining in stream than header says there should be (%d)", endianStream->size() - 24, compressedSize); + + // These two errors are really just sanity checks and should never go off + if (posBits != POS_BITS) + error("Position bits modified to %d", posBits); + if (lengthBits != LEN_BITS) + error("Length bits modified to %d", lengthBits); - debug(2, "Decoding Old Mohawk Bitmap (%dx%d, %04x Format)", _header.width, _header.height, _header.format); + _data = decompressLZ(stream, uncompressedSize); - warning("Unhandled old Mohawk Bitmap decoding"); + if (endianStream->pos() != endianStream->size()) + error("OldMohawkBitmap decompression failed"); + _surface = new Graphics::Surface(); + if ((_header.format & 0xf00) == kOldDrawRLE8) { + _surface->create(_header.width, _header.height, 1); + drawRLE8(); + } else { + assert(uncompressedSize >= (uint32)_header.bytesPerRow * _header.height); + _surface->create(_header.bytesPerRow, _header.height, 1); + _surface->w = _header.width; + _data->read(_surface->pixels, _header.bytesPerRow * _header.height); + } + + delete _data; delete stream; - return new ImageData(NULL, NULL); + return new ImageData(_surface); } } // End of namespace Mohawk diff --git a/engines/mohawk/bitmap.h b/engines/mohawk/bitmap.h index f1fde92f33..7e1ddcc573 100644 --- a/engines/mohawk/bitmap.h +++ b/engines/mohawk/bitmap.h @@ -60,6 +60,11 @@ enum BitmapFormat { kFlag24_MAC = 0x1000 // 24 bit pixel data has been converted to MAC 32 bit format }; +enum OldBitmapFormat { + kOldPackLZ = 0x0020, + kOldDrawRLE8 = 0x0100 +}; + struct BitmapHeader { uint16 width; uint16 height; @@ -99,10 +104,10 @@ protected: // The actual LZ decoder static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream *stream, uint32 uncompressedSize); -private: Common::SeekableReadStream *_data; Graphics::Surface *_surface; +private: const char *getPackName(); void unpackImage(); const char *getDrawName(); diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp index e0dce6369a..c1c41e21e7 100644 --- a/engines/mohawk/graphics.cpp +++ b/engines/mohawk/graphics.cpp @@ -759,26 +759,26 @@ LBGraphics::~LBGraphics() { } void LBGraphics::copyImageToScreen(uint16 image, uint16 left, uint16 right) { - if (_vm->getGameType() == GType_LIVINGBOOKSV1) { - // Drawing images in the old format isn't supported (yet) - ImageData *imageData = _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, image)); - delete imageData; - } else { - ImageData *imageData = _bmpDecoder->decodeImage(_vm->getRawData(ID_TBMP, image)); - imageData->_palette = _palette; - Graphics::Surface *surface = imageData->getSurface(); - imageData->_palette = NULL; // Unset the palette so it doesn't get deleted - delete imageData; - - uint16 width = MIN(surface->w, 640); - uint16 height = MIN(surface->h, 480); - _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, left, right, width, height); - surface->free(); - delete surface; + ImageData *imageData; - // FIXME: Remove this and update only at certain points - _vm->_system->updateScreen(); - } + if (_vm->getGameType() == GType_LIVINGBOOKSV1) + imageData = _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, image)); + else + imageData = _bmpDecoder->decodeImage(_vm->getRawData(ID_TBMP, image)); + + imageData->_palette = _palette; + Graphics::Surface *surface = imageData->getSurface(); + imageData->_palette = NULL; // Unset the palette so it doesn't get deleted + delete imageData; + + uint16 width = MIN(surface->w, _vm->_system->getWidth()); + uint16 height = MIN(surface->h, _vm->_system->getHeight()); + _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, left, right, width, height); + surface->free(); + delete surface; + + // FIXME: Remove this and update only at certain points + _vm->_system->updateScreen(); } void LBGraphics::setPalette(uint16 id) { -- cgit v1.2.3