diff options
author | Nicola Mettifogo | 2009-03-15 08:17:57 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2009-03-15 08:17:57 +0000 |
commit | bcabf5e53f079eaf3babb5d4e81d7e2e6c3ac73e (patch) | |
tree | b110d3cf2be7b73964bba3f569bfc3cb46c3c34c /engines | |
parent | 13497da82e37f2e9c5c8c05ad66738c37131d6ab (diff) | |
download | scummvm-rg350-bcabf5e53f079eaf3babb5d4e81d7e2e6c3ac73e.tar.gz scummvm-rg350-bcabf5e53f079eaf3babb5d4e81d7e2e6c3ac73e.tar.bz2 scummvm-rg350-bcabf5e53f079eaf3babb5d4e81d7e2e6c3ac73e.zip |
Fixed regression from r39410, by reimplementing the decompression routine. The backgrounds in the DOS version of Nippon Safes are compressed by something that looks like PackBits, but is not PackBits. Hence, the change to make PackBitsReadStream behave as the standard broke it.
svn-id: r39412
Diffstat (limited to 'engines')
-rw-r--r-- | engines/parallaction/disk_ns.cpp | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp index 4cc3fb4fe1..beb0db4f22 100644 --- a/engines/parallaction/disk_ns.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -386,32 +386,50 @@ Frames* DosDisk_ns::loadFrames(const char* name) { return loadCnv(name); } -// -// slides (background images) are stored compressed by scanline in a rle fashion -// -// the uncompressed data must then be unpacked to get: -// * color data [bits 0-5] -// * mask data [bits 6-7] (z buffer) -// * path data [bit 8] (walkable areas) -// -void DosDisk_ns::unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path) { +/* + Background images are compressed using a RLE algorithm that resembles PackBits. - byte b; - uint32 i = 0; + The uncompressed data is then unpacked as following: + - color data [bits 0-5] + - mask data [bits 6-7] (z buffer) + - path data [bit 8] (walkable areas) +*/ +void DosDisk_ns::unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path) { + byte storage[127]; + uint32 storageLen = 0, len = 0; + uint32 j = 0; while (1) { - b = stream->readByte(); - - if (stream->eos()) - break; - - path[i/8] |= ((b & 0x80) >> 7) << (i & 7); - mask[i/4] |= ((b & 0x60) >> 5) << ((i & 3) << 1); - screen[i] = b & 0x1F; - i++; + // first extracts packbits variant data + do { + len = stream->readByte(); + if (stream->eos()) + return; + + if (len == 128) { + storageLen = 0; + } else if (len <= 127) { + len++; + for (uint32 i = 0; i < len; i++) { + storage[i] = stream->readByte(); + } + storageLen = len; + } else { + len = (256 - len) + 1; + byte v = stream->readByte(); + memset(storage, v, len); + storageLen = len; + } + } while (storageLen == 0); + + // then unpacks the bits to the destination buffers + for (uint32 i = 0; i < storageLen; i++, j++) { + byte b = storage[i]; + path[j/8] |= ((b & 0x80) >> 7) << (j & 7); + mask[j/4] |= ((b & 0x60) >> 5) << ((j & 3) << 1); + screen[j] = b & 0x1F; + } } - - return; } void DosDisk_ns::parseDepths(BackgroundInfo &info, Common::SeekableReadStream &stream) { @@ -465,8 +483,7 @@ void DosDisk_ns::loadBackground(BackgroundInfo& info, const char *filename) { info._path->create(info.width, info.height); info._path->bigEndian = true; - Graphics::PackBitsReadStream pbstream(*stream); - unpackBackground(&pbstream, (byte*)info.bg.pixels, info._mask->data, info._path->data); + unpackBackground(stream, (byte*)info.bg.pixels, info._mask->data, info._path->data); delete stream; } |