diff options
Diffstat (limited to 'engines/cine/unpack.cpp')
-rw-r--r-- | engines/cine/unpack.cpp | 180 |
1 files changed, 68 insertions, 112 deletions
diff --git a/engines/cine/unpack.cpp b/engines/cine/unpack.cpp index bd09180289..5eb8bc32fb 100644 --- a/engines/cine/unpack.cpp +++ b/engines/cine/unpack.cpp @@ -26,130 +26,86 @@ namespace Cine { -uint32 crc; // variable at 5C5A -uint32 bitbucket; // dx:bx - -uint16 swap16(uint16 r) { - return (r >> 8) | (r << 8); +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;\ -} -#define store(p, b) *(--p) = b -#define getbit(p, b) { \ - b = bitbucket & 1; \ - bitbucket >>= 1; \ - if (!bitbucket) { \ - loadd(p, bitbucket); \ - crc ^= bitbucket; \ - b = bitbucket & 1; \ - bitbucket >>= 1; \ - bitbucket |= 0x80000000;\ - } \ +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 loadbits(p, b) { \ - b = 0; \ - do { \ - getbit(p, bit); \ - b <<= 1; \ - b |= bit; \ - nbits--; \ - } while (nbits); \ +static uint16 getCode(UnpackCtx *uc, uint8 numChunks) { + uint16 c = 0; + while (numChunks--) { + c <<= 1; + if (nextChunk(uc)) { + c |= 1; + } + } + return c; } -int decomp(uint8 *in, uint8 *out, int size) { - uint8 bit; // Carry flag - uint8 nbits; // cl - uint8 byte = 0; // ch - uint16 counter; // bp - uint16 var = 0; // variable at 5C58 - uint16 ptr; - uint16 flags; - - enum { - DO_COPY, - DO_UNPACK - } action; +static void unpackHelper1(UnpackCtx *uc, uint8 numChunks, uint8 addCount) { + uint16 count = getCode(uc, numChunks) + addCount + 1; + uc->datasize -= count; + while (count--) { + *uc->dst = (uint8)getCode(uc, 8); + --uc->dst; + } +} - loadd(in, crc); - loadd(in, bitbucket); - crc ^= bitbucket; +static void unpackHelper2(UnpackCtx *uc, uint8 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(uint8 *dst, const uint8 *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; } } // End of namespace Cine |