aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2007-07-07 14:56:30 +0000
committerNicola Mettifogo2007-07-07 14:56:30 +0000
commitd87e8c81aaf66dbba0b33ebeff124b49d051a688 (patch)
tree381ecf4777eb0d00cc7a851768478012fe0787c2
parenta43eb567ccc2860326bb3dd8a1ce0247390c6b36 (diff)
downloadscummvm-rg350-d87e8c81aaf66dbba0b33ebeff124b49d051a688.tar.gz
scummvm-rg350-d87e8c81aaf66dbba0b33ebeff124b49d051a688.tar.bz2
scummvm-rg350-d87e8c81aaf66dbba0b33ebeff124b49d051a688.zip
DLTA tags in multi-frame images are now supported.
svn-id: r27949
-rw-r--r--engines/parallaction/disk.cpp122
-rw-r--r--engines/parallaction/disk.h4
2 files changed, 100 insertions, 26 deletions
diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp
index 99b1d32f40..f97ec4c8de 100644
--- a/engines/parallaction/disk.cpp
+++ b/engines/parallaction/disk.cpp
@@ -693,39 +693,106 @@ AmigaDisk::~AmigaDisk() {
#define NUM_PLANES 5
-// FIXME: no mask is loaded
-void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize) {
+/*
+ unpackFrame transforms images from 5-bitplanes format to
+ 8-bit color-index mode
+*/
+void AmigaDisk::unpackFrame(byte *dst, byte *src, uint16 planeSize) {
byte s0, s1, s2, s3, s4, mask, t0, t1, t2, t3, t4;
+ for (uint32 j = 0; j < planeSize; j++) {
+ s0 = src[j];
+ s1 = src[j+planeSize];
+ s2 = src[j+planeSize*2];
+ s3 = src[j+planeSize*3];
+ s4 = src[j+planeSize*4];
+
+ for (uint32 k = 0; k < 8; k++) {
+ mask = 1 << (7 - k);
+ t0 = (s0 & mask ? 1 << 0 : 0);
+ t1 = (s1 & mask ? 1 << 1 : 0);
+ t2 = (s2 & mask ? 1 << 2 : 0);
+ t3 = (s3 & mask ? 1 << 3 : 0);
+ t4 = (s4 & mask ? 1 << 4 : 0);
+ *dst++ = t0 | t1 | t2 | t3 | t4;
+ }
+
+ }
+
+}
+
+/*
+ patchFrame applies DLTA data (dlta) to specified buffer (dst)
+*/
+void AmigaDisk::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height) {
+
+ uint32 *dataIndex = (uint32*)dlta;
+ uint32 *ofslenIndex = (uint32*)dlta + 8;
+
+ uint16 *base = (uint16*)dlta;
+ uint16 wordsPerLine = bytesPerPlane >> 1;
+
+ for (uint j = 0; j < NUM_PLANES; j++) {
+ uint16 *dst16 = (uint16*)(dst + j * bytesPerPlane * height);
+
+ uint16 *data = base + READ_BE_UINT32(dataIndex);
+ dataIndex++;
+ uint16 *ofslen = base + READ_BE_UINT32(ofslenIndex);
+ ofslenIndex++;
+
+ while (*ofslen != 0xFFFF) {
+
+ uint16 ofs = READ_BE_UINT16(ofslen);
+ ofslen++;
+ uint16 size = READ_BE_UINT16(ofslen);
+ ofslen++;
+
+ while (size > 0) {
+ dst16[ofs] ^= *data++;
+ ofs += wordsPerLine;
+ size--;
+ }
+
+ }
+
+ }
+
+}
+
+// FIXME: no mask is loaded
+void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height) {
+
+ byte *baseFrame = src;
+ byte *tempBuffer = 0;
+
+ uint16 planeSize = bytesPerPlane * height;
+
for (uint32 i = 0; i < numFrames; i++) {
if (READ_BE_UINT32(src) == MKID_BE('DLTA')) {
- // TODO: Add support for delta encoding
- uint32 size = READ_BE_UINT32(src + 4);
- src += size + 8;
- } else {
- for (uint32 j = 0; j < planeSize; j++) {
- s0 = src[j];
- s1 = src[j+planeSize];
- s2 = src[j+planeSize*2];
- s3 = src[j+planeSize*3];
- s4 = src[j+planeSize*4];
-
- for (uint32 k = 0; k < 8; k++) {
- mask = 1 << (7 - k);
- t0 = (s0 & mask ? 1 << 0 : 0);
- t1 = (s1 & mask ? 1 << 1 : 0);
- t2 = (s2 & mask ? 1 << 2 : 0);
- t3 = (s3 & mask ? 1 << 3 : 0);
- t4 = (s4 & mask ? 1 << 4 : 0);
- *dst++ = t0 | t1 | t2 | t3 | t4;
- }
+ uint size = READ_BE_UINT32(src + 4);
- }
+ if (tempBuffer == 0)
+ tempBuffer = (byte*)malloc(planeSize * NUM_PLANES);
+
+ memcpy(tempBuffer, baseFrame, planeSize * NUM_PLANES);
+
+ patchFrame(tempBuffer, src + 8, bytesPerPlane, height);
+ unpackFrame(dst, tempBuffer, planeSize);
+
+ src += (size + 8);
+ dst += planeSize * 8;
+ } else {
+ unpackFrame(dst, src, planeSize);
src += planeSize * NUM_PLANES;
+ dst += planeSize * 8;
}
}
+
+ if (tempBuffer)
+ free(tempBuffer);
+
}
StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) {
@@ -745,7 +812,7 @@ StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) {
uint32 decsize = width * height;
byte *data = (byte*)calloc(decsize, 1);
- unpackBitmap(data, buf, 1, height * bytesPerPlane);
+ unpackBitmap(data, buf, 1, bytesPerPlane, height);
free(buf);
@@ -775,7 +842,7 @@ Cnv* AmigaDisk::makeCnv(Common::SeekableReadStream &stream) {
uint32 decsize = numFrames * width * height;
byte *data = (byte*)calloc(decsize, 1);
- unpackBitmap(data, buf, numFrames, height * bytesPerPlane);
+ unpackBitmap(data, buf, numFrames, bytesPerPlane, height);
free(buf);
@@ -1111,6 +1178,11 @@ Cnv* AmigaDisk::loadTalk(const char *name) {
Cnv *cnv = makeCnv(*s);
delete s;
+ FILE *f = fopen(name, "wb");
+ fwrite(cnv->_data, cnv->_height*cnv->_width, cnv->_count, f);
+ fclose(f);
+
+
return cnv;
}
diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h
index 408e1f7c6b..14ea4f0e16 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -166,7 +166,9 @@ class AmigaDisk : public Disk {
protected:
Cnv* makeCnv(Common::SeekableReadStream &stream);
StaticCnv* makeStaticCnv(Common::SeekableReadStream &stream);
- void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize);
+ void patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height);
+ void unpackFrame(byte *dst, byte *src, uint16 planeSize);
+ void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height);
Common::SeekableReadStream *openArchivedFile(const char* name, bool errorOnFileNotFound = false);
Font *createFont(const char *name, Common::SeekableReadStream &stream);
void loadMask(const char *name);