RNC in C

Talk about anything else you want

Moderator: BigEvilCorporation

Post Reply
Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

RNC in C

Post by Chilly Willy » Sat Apr 09, 2011 8:06 am

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).

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Apr 10, 2011 11:49 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;
}

Post Reply