aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNicola Mettifogo2009-03-15 08:17:57 +0000
committerNicola Mettifogo2009-03-15 08:17:57 +0000
commitbcabf5e53f079eaf3babb5d4e81d7e2e6c3ac73e (patch)
treeb110d3cf2be7b73964bba3f569bfc3cb46c3c34c /engines
parent13497da82e37f2e9c5c8c05ad66738c37131d6ab (diff)
downloadscummvm-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.cpp65
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;
}