sync resource unpacking code of cruise with cine

svn-id: r26933
This commit is contained in:
Gregory Montoir 2007-05-24 21:19:52 +00:00
parent 0c22443ed6
commit 659e7ed76e
7 changed files with 96 additions and 184 deletions

View File

@ -29,6 +29,14 @@
namespace Cine {
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;

View File

@ -30,14 +30,6 @@
namespace Cine {
struct UnpackCtx {
int size, datasize;
uint32 crc;
uint32 chk;
byte *dst;
const byte *src;
};
bool delphineUnpack(byte *dst, const byte *src, int len);
} // End of namespace Cine

View File

@ -23,6 +23,7 @@
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "common/events.h"
#include "cruise/cruise_main.h"
@ -384,27 +385,17 @@ int loadFileSub1(uint8 **ptr, uint8 *name, uint8 *ptr2) {
lastFileSize = unpackedSize;
if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) {
unsigned short int realUnpackedSize;
uint8 *tempBuffer;
uint8 *pakedBuffer =
(uint8 *) mallocAndZero(volumePtrToFileDescriptor[fileIdx].
size + 2);
loadPakedFileToMem(fileIdx, pakedBuffer);
realUnpackedSize =
*(uint16 *) (pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 2);
flipShort((int16 *) & realUnpackedSize);
uint32 realUnpackedSize = READ_BE_UINT32(pakedBuffer + volumePtrToFileDescriptor[fileIdx].size - 4);
lastFileSize = realUnpackedSize;
tempBuffer = (uint8 *) mallocAndZero(realUnpackedSize);
decomp((uint8 *) pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 4,
(uint8 *) unpackedBuffer + realUnpackedSize,
realUnpackedSize);
delphineUnpack(unpackedBuffer, pakedBuffer, volumePtrToFileDescriptor[fileIdx].size);
free(pakedBuffer);
} else {

View File

@ -66,7 +66,7 @@ namespace Cruise {
#define ASSERT_PTR assert
#define ASSERT assert
int32 decomp(uint8 * in, uint8 * out, int32 size);
bool delphineUnpack(byte *dst, const byte *src, int len);
ovlData3Struct *getOvlData3Entry(int32 scriptNumber, int32 param);
ovlData3Struct *scriptFunc1Sub2(int32 scriptNumber, int32 param);

View File

@ -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
struct UnpackCtx {
int size, datasize;
uint32 crc;
uint32 chk;
byte *dst;
const byte *src;
};
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;\
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);\
}
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;
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;
}
} 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 {
nbits = 8;
loadbits(in, var);
nbits = 12;
action = DO_UNPACK;
}
}
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;
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;
}
}
/*
int main(void) {
FILE * in, * out;
uint8 * bufin, * bufout;
uint32 isize, osize;
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;
}
}
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);
}*/
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 {
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 {
uc.size = getCode(&uc, 8);
unpackHelper2(&uc, 12);
}
}
} while (uc.datasize > 0);
return uc.crc == 0;
}
} // End of namespace Cruise

View File

@ -111,25 +111,13 @@ int loadOverlay(uint8 *scriptName) {
}
if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) {
char *tempBuffer;
uint16 realUnpackedSize;
char *pakedBuffer =
(char *)mallocAndZero(volumePtrToFileDescriptor[fileIdx].
size + 2);
loadPakedFileToMem(fileIdx, (uint8 *) pakedBuffer);
realUnpackedSize =
*(int16 *) (pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 2);
flipShort(&realUnpackedSize);
tempBuffer = (char *)mallocAndZero(realUnpackedSize);
decomp((uint8 *) pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 4,
(uint8 *) unpackedBuffer + realUnpackedSize,
realUnpackedSize);
delphineUnpack((uint8 *)unpackedBuffer, (const uint8 *)pakedBuffer, volumePtrToFileDescriptor[fileIdx].size);
free(pakedBuffer);
} else {
@ -559,7 +547,6 @@ int loadOverlay(uint8 *scriptName) {
if (volumePtrToFileDescriptor[fileIdx].size + 2 !=
unpackedSize) {
short int realUnpackedSize;
char *pakedBuffer =
(char *)
mallocAndZero(volumePtrToFileDescriptor[fileIdx].
@ -567,15 +554,7 @@ int loadOverlay(uint8 *scriptName) {
loadPakedFileToMem(fileIdx, (uint8 *) pakedBuffer);
realUnpackedSize =
*(int16 *) (pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 2);
flipShort(&realUnpackedSize);
decomp((uint8 *) pakedBuffer +
volumePtrToFileDescriptor[fileIdx].size - 4,
(uint8 *) unpackedBuffer + realUnpackedSize,
realUnpackedSize);
delphineUnpack((uint8 *) unpackedBuffer, (const uint8 *)pakedBuffer, volumePtrToFileDescriptor[fileIdx].size);
free(pakedBuffer);
} else {

View File

@ -426,13 +426,10 @@ int16 readVolCnf(void) {
(char *)mallocAndZero(buffer[j].unk2 +
500);
decomp((uint8 *) bufferLocal + buffer[j].size -
4,
(uint8 *) uncompBuffer + buffer[j].unk2 +
500, buffer[j].unk2);
delphineUnpack((uint8 *) uncompBuffer, (const uint8 *) bufferLocal, buffer[j].size);
FILE *fOut = fopen(nameBuffer, "wb+");
fwrite(uncompBuffer + 500, buffer[j].unk2, 1,
fwrite(uncompBuffer, buffer[j].unk2, 1,
fOut);
fclose(fOut);