RNC in C
Moderator: BigEvilCorporation
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
RNC in C
I'm looking for some C code to unpack RNC2. I've got the assembly arc that was released, and I can translate that to C, but if someone has already done that, it would be less work (and less debugging).
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
I converted the 68000 code... it seems to be doing okay as far as I can tell. Here's the code in case anyone else runs into this.
Code: Select all
/*
* PRO-PACK Unpacker - Method 2
*/
unsigned char bitbuf;
unsigned char *input;
unsigned char *output;
unsigned char *temp;
int x, xx, pos, len;
void getbit(void)
{
x = bitbuf & 0x80 ? 1 : 0;
bitbuf = bitbuf << 1;
}
void reload(void)
{
xx = x;
bitbuf = *input++;
x = bitbuf & 0x80 ? 1 : 0;
bitbuf = (bitbuf << 1) + xx;
}
void getraw(void)
{
*output++ = *input++;
}
void getrawREP(void)
{
do
{
*output++ = *input++;
*output++ = *input++;
*output++ = *input++;
*output++ = *input++;
pos--;
} while (pos >= 0);
}
void RNC2_Unpack(void *in, void *out)
{
input = (unsigned char*)in;
output = (unsigned char*)out;
input += 18;
bitbuf = 0;
x = 1;
reload();
getbit();
goto GetBits2;
Raw:
len = 3;
x4Bits:
getbit();
if (!bitbuf)
reload();
pos = (pos << 1) + x;
len--;
if (len >= 0)
goto x4Bits;
pos += 2;
getrawREP();
goto GetBits2;
GetLen:
getbit();
if (!bitbuf)
reload();
len = (len << 1) + x;
getbit();
if (!bitbuf)
reload();
if (!x)
goto Copy;
len--;
getbit();
if (!bitbuf)
reload();
len = (len << 1) + x;
if (len == 9)
goto Raw;
Copy:
getbit();
if (!bitbuf)
reload();
if (!x)
goto ByteDisp2;
getbit();
if (!bitbuf)
reload();
pos = (pos << 1) + x;
getbit();
if (!bitbuf)
reload();
if (x)
goto BigDisp;
if (pos)
goto ByteDisp;
pos++;
Another:
getbit();
if (!bitbuf)
reload();
pos = (pos << 1) + x;
ByteDisp:
pos = (pos << 8) & 0xFF00;
ByteDisp2:
pos |= *input++;
temp = output - pos - 1;
if (len & 1)
*output++ = *temp++;
len = len >> 1;
ByteDisp3:
len--;
if (pos)
goto ByteDisp5;
pos = *temp;
ByteDisp4:
*output++ = pos;
*output++ = pos;
len--;
if (len >= 0)
goto ByteDisp4;
goto GetBits2;
ByteDisp5:
*output++ = *temp++;
*output++ = *temp++;
len--;
if (len >= 0)
goto ByteDisp5;
goto GetBits2;
GetBits:
reload();
if (x)
goto String;
xByte:
getraw();
GetBits2:
getbit();
if (x)
goto Chkz;
getraw();
getbit();
if (!x)
goto xByte;
Chkz:
if (!bitbuf)
goto GetBits;
String:
len = 2;
pos = 0;
getbit();
if (!bitbuf)
reload();
if (!x)
goto GetLen;
Smalls:
getbit();
if (!bitbuf)
reload();
if (!x)
goto ByteDisp2;
len++;
getbit();
if (!bitbuf)
reload();
if (!x)
goto Copy;
len = *input++;
if (!len)
goto OverNout;
len += 8;
goto Copy;
BigDisp:
getbit();
if (!bitbuf)
reload();
pos = (pos << 1) + x;
pos |= 4;
getbit();
if (!bitbuf)
reload();
if (x)
goto ByteDisp;
goto Another;
OverNout:
getbit();
if (bitbuf)
goto Check4end;
reload();
Check4end:
if (x)
goto GetBits2;
}