Skip to content

Instantly share code, notes, and snippets.

@NWPlayer123
Created January 31, 2023 06:33
Show Gist options
  • Save NWPlayer123/72648a8f8d29ab48b4b070bebdb8d7f0 to your computer and use it in GitHub Desktop.
Save NWPlayer123/72648a8f8d29ab48b4b070bebdb8d7f0 to your computer and use it in GitHub Desktop.
decompression code from My Pokemon Ranch, seems similar to the ash used by the Wii Menu
//.bss
u16 left9[0x400]; //8067E830
u16 right9[0x400]; //8067F030
u16 left12[0x10000]; //8067F830
u16 right12[0x10000]; //8069F830
u32 stack[0x100]; //806BF830
//.sbss
s32 bitlen[2];
s32 ccnt[2];
s32 wptr[2];
u32 bitcode[2];
s32 getbitsc(u8* input, s32 size, s32 type) {
s32 k, m;
u32 i, j, g;
k = wptr[type];
m = bitlen[type];
g = bitcode[type];
if (m + size > 32) {
j = (input[k] << 24) | (input[k + 1] << 16) | (input[k + 2] << 8) | input[k + 3];
wptr[type] = k + 4;
bitlen[type] = m + size - 32;
bitcode[type] = j << bitlen[type];
i = (g >> (32 - size)) | (j >> (64 - size - m));
}
else if (m + size == 32) {
wptr[type] = k + 4;
bitlen[type] = 0;
bitcode[type] = (input[k] << 24) | (input[k + 1] << 16) | (input[k + 2] << 8) | input[k + 3];
i = g >> (32 - size);
}
else {
bitlen[type] = m + size;
bitcode[type] = g << size;
i = g >> (32 - size);
}
return i;
}
s32 readtree9(u8* input) {
s32 f, m, j, z, sp;
for (j = m = ccnt[0], sp = 0;;) {
if (getbitsc(input, 1, 0)) {
stack[sp] = j | 0x80000000;
stack[sp + 1] = j | 0x40000000;
j++;
m++;
sp += 2;
}
else {
z = getbitsc(input, 9, 0);
while (1) {
f = stack[--sp];
if (!(f & 0x80000000)) {
left9[f & 0x3FFFFFFF] = z;
j = m;
break;
}
else {
right9[f & 0x3FFFFFFF] = z;
z = f & 0x3FFFFFFF;
if (sp == 0) {
return z;
}
}
}
}
}
}
s32 readtree12(u8* input) {
s32 f, m, j, z, sp;
for (j = m = ccnt[1], sp = 0;;) {
if (getbitsc(input, 1, 1)) {
stack[sp] = j | 0x80000000;
stack[sp + 1] = j | 0x40000000;
j++;
m++;
sp += 2;
}
else {
z = getbitsc(input, 15, 1);
while (1) {
f = stack[--sp];
if (!(f & 0x80000000)) {
left12[f & 0x3FFFFFFF] = z;
j = m;
break;
}
else {
right12[f & 0x3FFFFFFF] = z;
z = f & 0x3FFFFFFF;
if (sp == 0) {
return z;
}
}
}
}
}
}
s32 decode_ash(u8* input, u8* output) {
s32 i, j, k, q, t, root9, root12;
t = (input[4] << 24) | (input[5] << 16) | (input[6] << 8) | input[7];
k = (input[8] << 24) | (input[9] << 16) | (input[10] << 8) | input[11];
wptr[0] = 12;
wptr[1] = k;
bitlen[0] = 0;
bitlen[1] = 0;
ccnt[0] = 0x200;
ccnt[1] = 0x8000;
getbitsc(input, 32, 0);
getbitsc(input, 32, 1);
root9 = readtree9(input);
root12 = readtree12(input);
for (q = 0; q < t;) {
j = root9;
while (j >= 0x200) {
if (getbitsc(input, 1, 0)) {
j = right9[j];
} else {
j = left9[j];
}
}
if (j < 0x100) {
output[q++] = j;
} else {
i = root12;
while (i >= 0x8000) {
if (getbitsc(input, 1, 1)) {
i = right12[i];
} else {
i = left12[i];
}
}
j -= 253;
i = q - i - 1;
for (; j > 0; j--, q++, i++) {
output[q] = output[i];
}
}
}
return q;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment