diff options
Diffstat (limited to 'engines/cruise/delphine-unpack.cpp')
-rw-r--r-- | engines/cruise/delphine-unpack.cpp | 209 |
1 files changed, 77 insertions, 132 deletions
diff --git a/engines/cruise/delphine-unpack.cpp b/engines/cruise/delphine-unpack.cpp index fe32cbb018..611d1573fd 100644 --- a/engines/cruise/delphine-unpack.cpp +++ b/engines/cruise/delphine-unpack.cpp @@ -22,154 +22,99 @@ * */ -#include "cruise/cruise_main.h" +#include "common/stdafx.h" +#include "common/endian.h" namespace Cruise { -uint32 crc; // variable at 5C5A -uint32 bitbucket; // dx:bx - -uint16 swap16(uint16 r) { - return (r >> 8) | (r << 8); +struct UnpackCtx { + int size, datasize; + uint32 crc; + uint32 chk; + byte *dst; + const byte *src; +}; + +static int rcr(UnpackCtx *uc, int CF) { + int rCF = (uc->chk & 1); + uc->chk >>= 1; + if (CF) { + uc->chk |= 0x80000000; + } + return rCF; } -#define loadd(p, d) {\ - d = *(--p);\ - d |= (*(--p)) << 8;\ - d |= (*(--p)) << 16;\ - d |= (*(--p)) << 24;\ +static int nextChunk(UnpackCtx *uc) { + int CF = rcr(uc, 0); + if (uc->chk == 0) { + uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4; + uc->crc ^= uc->chk; + CF = rcr(uc, 1); + } + return CF; } -#define store(p, b) *(--p) = b -#define getbit(p, b) {\ - b = (uint8)(bitbucket & 1);\ - bitbucket >>= 1;\ - if (!bitbucket) {\ - loadd(p, bitbucket);\ - crc ^= bitbucket;\ - b = (uint8)(bitbucket & 1);\ - bitbucket >>= 1;\ - bitbucket |= 0x80000000;\ - }\ +static uint16 getCode(UnpackCtx *uc, byte numChunks) { + uint16 c = 0; + while (numChunks--) { + c <<= 1; + if (nextChunk(uc)) { + c |= 1; + } + } + return c; } -#define loadbits(p, b) {\ - b = 0;\ - do {\ - getbit(p, bit);\ - b <<= 1;\ - b |= bit;\ - nbits--;\ - } while (nbits);\ +static void unpackHelper1(UnpackCtx *uc, byte numChunks, byte addCount) { + uint16 count = getCode(uc, numChunks) + addCount + 1; + uc->datasize -= count; + while (count--) { + *uc->dst = (byte)getCode(uc, 8); + --uc->dst; + } } -int32 decomp(uint8 *in, uint8 *out, int32 size) { - uint8 bit = 0; // Carry flag - uint8 nbits = 0; // cl - uint8 byte = 0; // ch - uint16 counter = 0; // bp - uint16 var = 0; // variable at 5C58 - uint16 ptr = 0; - uint16 flags = 0; - enum { - DO_COPY, - DO_UNPACK - } action; - - loadd(in, crc); - loadd(in, bitbucket); - crc ^= bitbucket; +static void unpackHelper2(UnpackCtx *uc, byte numChunks) { + uint16 i = getCode(uc, numChunks); + uint16 count = uc->size + 1; + uc->datasize -= count; + while (count--) { + *uc->dst = *(uc->dst + i); + --uc->dst; + } +} - do { // 5A4C - getbit(in, bit); - if (!bit) { // 5A94 - getbit(in, bit); - if (!bit) { // 5AC8 - nbits = 3; - byte = 0; - action = DO_COPY; - } else { // 5ACA - var = 1; - nbits = 8; - action = DO_UNPACK; +bool delphineUnpack(byte *dst, const byte *src, int len) { + UnpackCtx uc; + uc.src = src + len - 4; + uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.dst = dst + uc.datasize - 1; + uc.size = 0; + uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.crc ^= uc.chk; + do { + if (!nextChunk(&uc)) { + uc.size = 1; + if (!nextChunk(&uc)) { + unpackHelper1(&uc, 3, 0); + } else { + unpackHelper2(&uc, 8); } - } else { // 5B4F - nbits = 2; - loadbits(in, flags); - if (flags < 2) { - nbits = flags + 9; // 5BC3 - var = flags + 2; - action = DO_UNPACK; - } else if (flags == 3) { - nbits = 8; // 5B4A - byte = 8; - action = DO_COPY; + } else { + uint16 c = getCode(&uc, 2); + if (c == 3) { + unpackHelper1(&uc, 8, 8); + } else if (c < 2) { + uc.size = c + 2; + unpackHelper2(&uc, c + 9); } else { - nbits = 8; - loadbits(in, var); - nbits = 12; - action = DO_UNPACK; + uc.size = getCode(&uc, 8); + unpackHelper2(&uc, 12); } } - - switch (action) { - case DO_COPY: - // 5AD1 - loadbits(in, counter); // 5AFD - counter += byte; - counter++; - size -= counter; - do { - nbits = 8; - loadbits(in, byte); // 5B3F - store(out, byte); - counter--; - } while (counter); // 5B45 - break; - case DO_UNPACK: - // 5BD3 - loadbits(in, ptr); // 5BFF - counter = var + 1; - size -= counter; - do { - byte = *(out + ptr - 1); - store(out, byte); - counter--; - } while (counter); - } - } while (size > 0); - // 5C32 - // ??? - - if (crc) { - return -1; - } else { - return 0; - } + } while (uc.datasize > 0); + return uc.crc == 0; } -/* -int main(void) { - FILE * in, * out; - uint8 * bufin, * bufout; - uint32 isize, osize; - - in = fopen("FIN.FR", "rb"); - out = fopen("FIN.FR.out", "wb"); - - fseek(in, -4, SEEK_END); - bufin = (uint8 *) mallocAndZero((isize = ftell(in))); - fread(&osize, 4, 1, in); - osize = (osize >> 24) | ((osize >> 8) & 0xff00) | ((osize << 8) & 0xff0000) | (osize << 24); - bufout = (uint8 *) mallocAndZero(osize); - fseek(in, 0, SEEK_SET); - fread(bufin, 1, isize, in); - - decomp(bufin + isize, bufout + osize, osize); - - fwrite(bufout, 1, osize, out); - fclose(out); - fclose(in); -}*/ - } // End of namespace Cruise |