aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2010-11-18 13:31:12 +0000
committerMatthew Hoops2010-11-18 13:31:12 +0000
commit48416a7f038dba69a72aa9de2fef1dc1e9087405 (patch)
treeb56a8dd064b259a571b545f7f3b25a04861f6349
parent51a954c1dd07c475b01c898ac8614f5a2a83185b (diff)
downloadscummvm-rg350-48416a7f038dba69a72aa9de2fef1dc1e9087405.tar.gz
scummvm-rg350-48416a7f038dba69a72aa9de2fef1dc1e9087405.tar.bz2
scummvm-rg350-48416a7f038dba69a72aa9de2fef1dc1e9087405.zip
MOHAWK: Implement the old Mohawk bitmap format (thanks to fuzzie)
svn-id: r54319
-rw-r--r--engines/mohawk/bitmap.cpp51
-rw-r--r--engines/mohawk/bitmap.h7
-rw-r--r--engines/mohawk/graphics.cpp38
3 files changed, 68 insertions, 28 deletions
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<int>(surface->w, 640);
- uint16 height = MIN<int>(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<int>(surface->w, _vm->_system->getWidth());
+ uint16 height = MIN<int>(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) {