diff options
-rw-r--r-- | engines/parallaction/disk.cpp | 122 | ||||
-rw-r--r-- | engines/parallaction/disk.h | 4 |
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); |