From f4bdfcd4b97c680d33252a5d29e52f83a08431eb Mon Sep 17 00:00:00 2001 From: David Benepe Date: Tue, 13 Jul 2021 23:23:54 -0500 Subject: [PATCH] Split out gzip code from unknown_0C4800.c into gzip.c --- .../unknown_0B8920/func_800C5168.s | 2 +- .../unknown_0B8920/func_800C5B58.s | 14 +- .../{func_800C580C.s => s32_to_string.s} | 10 +- src/gzip.c | 255 ++++++++++++++++++ src/unknown_0C4800.c | 130 +++------ 5 files changed, 310 insertions(+), 101 deletions(-) rename asm/non_matchings/unknown_0B8920/{func_800C580C.s => s32_to_string.s} (96%) create mode 100644 src/gzip.c diff --git a/asm/non_matchings/unknown_0B8920/func_800C5168.s b/asm/non_matchings/unknown_0B8920/func_800C5168.s index 6e031ab7..67eaf196 100644 --- a/asm/non_matchings/unknown_0B8920/func_800C5168.s +++ b/asm/non_matchings/unknown_0B8920/func_800C5168.s @@ -69,7 +69,7 @@ glabel func_800C5168 /* 0C5E5C 800C525C 27A50040 */ addiu $a1, $sp, 0x40 /* 0C5E60 800C5260 AFA7003C */ sw $a3, 0x3c($sp) /* 0C5E64 800C5264 AFA80030 */ sw $t0, 0x30($sp) -/* 0C5E68 800C5268 0C0317D8 */ jal func_800C5F60 +/* 0C5E68 800C5268 0C0317D8 */ jal parse_string_with_number /* 0C5E6C 800C526C AFA9002C */ sw $t1, 0x2c($sp) /* 0C5E70 800C5270 8FA80030 */ lw $t0, 0x30($sp) /* 0C5E74 800C5274 8FA5014C */ lw $a1, 0x14c($sp) diff --git a/asm/non_matchings/unknown_0B8920/func_800C5B58.s b/asm/non_matchings/unknown_0B8920/func_800C5B58.s index 018214fe..a26472c2 100644 --- a/asm/non_matchings/unknown_0B8920/func_800C5B58.s +++ b/asm/non_matchings/unknown_0B8920/func_800C5B58.s @@ -63,7 +63,7 @@ glabel func_800C5B58 /* 0C6840 800C5C40 256C0002 */ addiu $t4, $t3, 2 /* 0C6844 800C5C44 AFAC0010 */ sw $t4, 0x10($sp) /* 0C6848 800C5C48 25070002 */ addiu $a3, $t0, 2 -/* 0C684C 800C5C4C 0C0316A8 */ jal func_800C5AA0 +/* 0C684C 800C5C4C 0C0316A8 */ jal render_fill_rectangle /* 0C6850 800C5C50 24C6FFFE */ addiu $a2, $a2, -2 /* 0C6854 800C5C54 10000025 */ b .L800C5CEC /* 0C6858 800C5C58 8E620000 */ lw $v0, ($s3) @@ -71,7 +71,7 @@ glabel func_800C5B58 /* 0C685C 800C5C5C 244DFFFE */ addiu $t5, $v0, -2 /* 0C6860 800C5C60 AFAD0010 */ sw $t5, 0x10($sp) /* 0C6864 800C5C64 02602025 */ move $a0, $s3 -/* 0C6868 800C5C68 0C0316A8 */ jal func_800C5AA0 +/* 0C6868 800C5C68 0C0316A8 */ jal render_fill_rectangle /* 0C686C 800C5C6C 2525FFFE */ addiu $a1, $t1, -2 /* 0C6870 800C5C70 86300006 */ lh $s0, 6($s1) /* 0C6874 800C5C74 86250004 */ lh $a1, 4($s1) @@ -81,7 +81,7 @@ glabel func_800C5B58 /* 0C6884 800C5C84 02602025 */ move $a0, $s3 /* 0C6888 800C5C88 2606FFFE */ addiu $a2, $s0, -2 /* 0C688C 800C5C8C 24A5FFFE */ addiu $a1, $a1, -2 -/* 0C6890 800C5C90 0C0316A8 */ jal func_800C5AA0 +/* 0C6890 800C5C90 0C0316A8 */ jal render_fill_rectangle /* 0C6894 800C5C94 24E70002 */ addiu $a3, $a3, 2 /* 0C6898 800C5C98 86280008 */ lh $t0, 8($s1) /* 0C689C 800C5C9C 862F000A */ lh $t7, 0xa($s1) @@ -91,7 +91,7 @@ glabel func_800C5B58 /* 0C68AC 800C5CAC 02602025 */ move $a0, $s3 /* 0C68B0 800C5CB0 2505FFFE */ addiu $a1, $t0, -2 /* 0C68B4 800C5CB4 25070002 */ addiu $a3, $t0, 2 -/* 0C68B8 800C5CB8 0C0316A8 */ jal func_800C5AA0 +/* 0C68B8 800C5CB8 0C0316A8 */ jal render_fill_rectangle /* 0C68BC 800C5CBC 24C60002 */ addiu $a2, $a2, 2 /* 0C68C0 800C5CC0 8622000A */ lh $v0, 0xa($s1) /* 0C68C4 800C5CC4 86250004 */ lh $a1, 4($s1) @@ -101,7 +101,7 @@ glabel func_800C5B58 /* 0C68D4 800C5CD4 02602025 */ move $a0, $s3 /* 0C68D8 800C5CD8 2446FFFE */ addiu $a2, $v0, -2 /* 0C68DC 800C5CDC 24A5FFFE */ addiu $a1, $a1, -2 -/* 0C68E0 800C5CE0 0C0316A8 */ jal func_800C5AA0 +/* 0C68E0 800C5CE0 0C0316A8 */ jal render_fill_rectangle /* 0C68E4 800C5CE4 24E70002 */ addiu $a3, $a3, 2 /* 0C68E8 800C5CE8 8E620000 */ lw $v0, ($s3) .L800C5CEC: @@ -164,7 +164,7 @@ glabel func_800C5B58 /* 0C69BC 800C5DBC 00000000 */ nop /* 0C69C0 800C5DC0 01591021 */ addu $v0, $t2, $t9 .L800C5DC4: -/* 0C69C4 800C5DC4 0C0316A8 */ jal func_800C5AA0 +/* 0C69C4 800C5DC4 0C0316A8 */ jal render_fill_rectangle /* 0C69C8 800C5DC8 AFA20010 */ sw $v0, 0x10($sp) /* 0C69CC 800C5DCC 82020005 */ lb $v0, 5($s0) /* 0C69D0 800C5DD0 26100005 */ addiu $s0, $s0, 5 @@ -251,7 +251,7 @@ glabel func_800C5B58 /* 0C6B00 800C5F00 A22F001D */ sb $t7, 0x1d($s1) /* 0C6B04 800C5F04 92060001 */ lbu $a2, 1($s0) /* 0C6B08 800C5F08 8E040004 */ lw $a0, 4($s0) -/* 0C6B0C 800C5F0C 0C0317D8 */ jal func_800C5F60 +/* 0C6B0C 800C5F0C 0C0317D8 */ jal parse_string_with_number /* 0C6B10 800C5F10 00000000 */ nop /* 0C6B14 800C5F14 02602025 */ move $a0, $s3 /* 0C6B18 800C5F18 02202825 */ move $a1, $s1 diff --git a/asm/non_matchings/unknown_0B8920/func_800C580C.s b/asm/non_matchings/unknown_0B8920/s32_to_string.s similarity index 96% rename from asm/non_matchings/unknown_0B8920/func_800C580C.s rename to asm/non_matchings/unknown_0B8920/s32_to_string.s index fe4d0ea4..c0f25d3e 100644 --- a/asm/non_matchings/unknown_0B8920/func_800C580C.s +++ b/asm/non_matchings/unknown_0B8920/s32_to_string.s @@ -1,4 +1,4 @@ -glabel func_800C580C +glabel s32_to_string /* 0C640C 800C580C 8C820000 */ lw $v0, ($a0) /* 0C6410 800C5810 04A10005 */ bgez $a1, .L800C5828 /* 0C6414 800C5814 00001825 */ move $v1, $zero @@ -7,8 +7,8 @@ glabel func_800C580C /* 0C6420 800C5820 24420001 */ addiu $v0, $v0, 1 /* 0C6424 800C5824 00052823 */ negu $a1, $a1 .L800C5828: -/* 0C6428 800C5828 3C07800E */ lui $a3, %hi(D_800E36EC) # $a3, 0x800e -/* 0C642C 800C582C 8CE736EC */ lw $a3, %lo(D_800E36EC)($a3) +/* 0C6428 800C5828 3C07800E */ lui $a3, %hi(gDescPowsOf10) # $a3, 0x800e +/* 0C642C 800C582C 8CE736EC */ lw $a3, %lo(gDescPowsOf10)($a3) /* 0C6430 800C5830 24060001 */ li $a2, 1 /* 0C6434 800C5834 00A7082A */ slt $at, $a1, $a3 /* 0C6438 800C5838 14200015 */ bnez $at, .L800C5890 @@ -41,8 +41,8 @@ glabel func_800C580C /* 0C6498 800C5898 A0490000 */ sb $t1, ($v0) /* 0C649C 800C589C 24420001 */ addiu $v0, $v0, 1 .L800C58A0: -/* 0C64A0 800C58A0 3C0D800E */ lui $t5, %hi(D_800E36EC) # $t5, 0x800e -/* 0C64A4 800C58A4 25AD36EC */ addiu $t5, %lo(D_800E36EC) # addiu $t5, $t5, 0x36ec +/* 0C64A0 800C58A0 3C0D800E */ lui $t5, %hi(gDescPowsOf10) # $t5, 0x800e +/* 0C64A4 800C58A4 25AD36EC */ addiu $t5, %lo(gDescPowsOf10) # addiu $t5, $t5, 0x36ec /* 0C64A8 800C58A8 3C0C800E */ lui $t4, %hi(D_800E3710) # $t4, 0x800e /* 0C64AC 800C58AC 258C3710 */ addiu $t4, %lo(D_800E3710) # addiu $t4, $t4, 0x3710 /* 0C64B0 800C58B0 032D4021 */ addu $t0, $t9, $t5 diff --git a/src/gzip.c b/src/gzip.c new file mode 100644 index 00000000..63ac549d --- /dev/null +++ b/src/gzip.c @@ -0,0 +1,255 @@ +/* The comment below is needed for this file to be picked up by generate_ld */ +/* RAM_POS: 0x800C6170 */ + +#include "memory.h" +#include "types.h" +#include "macros.h" + +typedef struct huft { + u8 e; /* number of extra bits or operation */ + u8 b; /* number of bits in this code or subcode */ + union { + u16 n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; +} huft; + +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + +/************ .data ************/ + +huft* D_800E3760 = NULL; +u8* D_800E3764 = NULL; +u8* gzip_inflate_input = NULL; +u8* gzip_inflate_output = NULL; + +/*******************************/ + +/************ .bss ************/ + +u32 gzip_bit_buffer; +u32 gzip_num_bits; +s32 D_8012AAD8; + +/******************************/ + +void func_800C6170(void) { + D_800E3760 = (huft*)allocate_from_main_pool_safe(0x2800, COLOR_TAG_BLACK); + D_800E3764 = (u8*)allocate_from_main_pool_safe(0x10, COLOR_TAG_BLACK); +} + +/** + * Converts a little endian value to big endian. + */ +s32 byteswap32(u8* arg0) { + s32 value; + value = *arg0++; + value |= (*arg0++ << 8); + value |= (*arg0++ << 16); + value |= (*arg0++ << 24); + return value; +} + +/** + * Returns the uncompressed size of a gzip compressed asset. + */ +s32 get_asset_uncompressed_size(s32 assetIndex, s32 assetOffset) { + load_asset_to_address(assetIndex, D_800E3764, assetOffset, 8); + return byteswap32(D_800E3764); +} + +s32 gzip_inflate_block(void); + +/** + * Decompresses gzip data. + * Returns the pointer to the decompressed data. + */ +u8* gzip_inflate(u8* compressedInput, u8* decompressedOutput) { + gzip_inflate_input = compressedInput + 5; // The compression header is 5 bytes. + gzip_inflate_output = decompressedOutput; + gzip_num_bits = 0; + gzip_bit_buffer = 0; + while(gzip_inflate_block() != 0) {} // Keep calling gzip_inflate_block() until it returns 0. + return decompressedOutput; +} + +#if 0 + +// Work in progress. +// You can find the original huft_build function here: +// https://github.com/oscarlab/gcc_test_files/blob/master/gzip.c#L4933 + +void gzip_huft_build(u32 *b, u32 n, u32 s, u16 *d, u16 *e, huft **t, s32 *m) { + u32 a; /* counter for codes of length k */ + u32 c[BMAX+1]; /* bit length count table */ + u32 f; /* i repeats in table every f entries */ + s32 g; /* maximum code length */ + s32 h; /* table level */ + register u32 i; /* counter, current code */ + register u32 j; /* counter */ + register s32 k; /* number of bits in current code */ + s32 l; /* bits per table (returned in m) */ + register u32 *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + u32 v[N_MAX]; /* values in order of bit length */ + register s32 w; /* bits before this table == (l * h) */ + u32 x[BMAX+1]; /* bit offsets, then code stack */ + u32 *xp; /* pointer into x */ + s32 y; /* number of dummy codes added */ + u32 z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + memzero(c, sizeof(c)); + p = b; i = n; + do { + c[*p]++; /* assume all entries <= BMAX */ + p++; /* Can't combine with above line (Solaris bug) */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (huft *)NULL; + *m = 0; + return; + } + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((u32)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((u32)l > i) + l = i; + *m = l; + + // Something is missing here. + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + y -= c[j]; + y -= c[j]; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (huft *)NULL; /* just to keep compilers happy */ + q = (huft *)NULL; /* ditto */ + z = 0; /* ditto */ + + // D_800E3760 and D_8012AAD8 go in here somewhere. + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (u32)l ? l : z; /* upper limit on table size */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = (huft *)NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.b = (u8)l; /* bits to dump before this table */ + r.e = (u8)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (u8)(k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (u8)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = (u16)(*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } + else + { + r.e = (u8)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + return; +} +#else +GLOBAL_ASM("asm/non_matchings/unknown_0B8920/gzip_huft_build.s") +#endif diff --git a/src/unknown_0C4800.c b/src/unknown_0C4800.c index abea2bc1..10e6199c 100644 --- a/src/unknown_0C4800.c +++ b/src/unknown_0C4800.c @@ -36,7 +36,7 @@ Gfx D_800E36C8[][2] = { s8 D_800E36E8 = 0; // Descending powers of 10 -s32 D_800E36EC[9] = { +s32 gDescPowsOf10[9] = { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }; @@ -48,13 +48,6 @@ s8 D_800E3710[48] = { OSDevMgr __osPiDevMgr = { 0, NULL, NULL, NULL, NULL, NULL, NULL }; -s32 pad800E375C = 0; // File boundary? - -u8* D_800E3760 = NULL; -u8* D_800E3764 = NULL; -u8* gzip_inflate_input = NULL; -u8* gzip_inflate_output = NULL; - /*******************************/ /************ .bss ************/ @@ -224,9 +217,6 @@ OSThread piThread; //piThread s32 D_8012A9B0[64]; OSMesgQueue piEventQueue; //piEventQueue OSMesg piEventBuf[2]; //piEventBuf -u32 gzip_bit_buffer; -u32 gzip_num_bits; -s32 D_8012AAD8; /******************************/ @@ -281,19 +271,17 @@ void func_800C4404(s32 arg0, s32 arg1, s32 arg2) { func_800C45A4(arg0, *D_8012A7E8, arg1, arg2, 1.0f); } -void draw_text(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { +void draw_text(Gfx** displayList, s32 xpos, s32 ypos, char* text, s32 alignmentFlags) { unk8012A7E8 *temp = &(*D_8012A7E8)[0]; - temp->unk0 = (arg1 == -0x8000) ? temp->unkC >> 1 : arg1; - temp->unk2 = (arg2 == -0x8000) ? temp->unkE >> 1 : arg2; - func_800C45A4(arg0, temp, arg3, arg4, 1.0f); + temp->unk0 = (xpos == -0x8000) ? temp->unkC >> 1 : xpos; + temp->unk2 = (ypos == -0x8000) ? temp->unkE >> 1 : ypos; + func_800C45A4(displayList, temp, text, alignmentFlags, 1.0f); } void func_800C44C0(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { - if (arg1 >= 0) { - if(arg1 < 8){ - unk8012A7E8 *temp = &D_8012A7E8[arg1]; - func_800C45A4(arg0, temp, arg2, arg3, 1.0f); - } + if (arg1 >= 0 && arg1 < 8) { + unk8012A7E8 *temp = &D_8012A7E8[arg1]; + func_800C45A4(arg0, temp, arg2, arg3, 1.0f); } } @@ -306,8 +294,11 @@ void func_800C4510(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5) { } } -// Has a jump table +//#if 1 +// TODO +//#else GLOBAL_ASM("asm/non_matchings/unknown_0B8920/func_800C45A4.s") +//#endif GLOBAL_ASM("asm/non_matchings/unknown_0B8920/func_800C4DA0.s") @@ -499,13 +490,9 @@ void func_800C56FC(s32 arg0, s32 arg1, s32 arg2) { } } -#if 1 -GLOBAL_ASM("asm/non_matchings/unknown_0B8920/func_800C580C.s") -#else - -// sprintf like function, but only for decimal integers (%d). -void func_800C580C(char** outString, s32 number) { - char digit; +#ifdef NON_MATCHING +void s32_to_string(char** outString, s32 number) { + u8 digit; s32 i; s32 hasDigit; // boolean s32 div; @@ -519,13 +506,13 @@ void func_800C580C(char** outString, s32 number) { // Loop through digit places. for(i = 0; i < 9; i++){ - hasDigit = 0; + hasDigit = FALSE; digit = '0'; - if (number >= D_800E36EC[i]) { - div = number / D_800E36EC[i]; - hasDigit = 1; + if (number >= gDescPowsOf10[i]) { + div = number / gDescPowsOf10[i]; + hasDigit = TRUE; digit = '0' + div; - number -= div * D_800E36EC[i]; + number -= div * gDescPowsOf10[i]; } if (hasDigit) { **outString = digit; @@ -537,30 +524,40 @@ void func_800C580C(char** outString, s32 number) { **outString = '0' + number; (*outString)++; } +#else +void s32_to_string(char**, s32); +GLOBAL_ASM("asm/non_matchings/unknown_0B8920/s32_to_string.s") #endif -void func_800C5AA0(Gfx **dlist, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { +/** + * Draws a solid color rectangle at the coordinates specified. + * ulx, uly = upper-left position + * lrx, lry = lower-right position + */ +void render_fill_rectangle(Gfx **dlist, s32 ulx, s32 uly, s32 lrx, s32 lry) { u32 temp_v0 = get_video_width_and_height_as_s32(); - if (arg3 >= 0 && arg1 < (temp_v0 & 0xFFFF) && arg4 >= 0 && arg2 < (temp_v0 >> 16)) { - if (arg1 < 0) { - arg1 = 0; + if (lrx >= 0 && ulx < (temp_v0 & 0xFFFF) && lry >= 0 && uly < (temp_v0 >> 16)) { + if (ulx < 0) { + ulx = 0; } - if (arg2 < 0) { - arg2 = 0; + if (uly < 0) { + uly = 0; } - gDPFillRectangle((*dlist)++, arg1, arg2, arg3, arg4); + gDPFillRectangle((*dlist)++, ulx, uly, lrx, lry); } } GLOBAL_ASM("asm/non_matchings/unknown_0B8920/func_800C5B58.s") -void func_800C580C(char**, s32); - -void func_800C5F60(unsigned char *input, char *output, s32 number) { +/** + * Takes in a string and a number, and replaces each instance of the + * character '~' with the number. + */ +void parse_string_with_number(unsigned char *input, char *output, s32 number) { while (*input != '\0') { if ('~' == *input) { // ~ is equivalent to a %d. // output the number as part of the string - func_800C580C(&output, number); + s32_to_string(&output, number); input++; } else { *output = *input; @@ -571,6 +568,7 @@ void func_800C5F60(unsigned char *input, char *output, s32 number) { *output = '\0'; // null terminator } +// osCreatePiManager is compiled with -mips1, so it does probably belong here. void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt) { u32 savedMask; @@ -608,47 +606,3 @@ void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgC } } } - -// I would guess that there is a file boundary right here. - -void func_800C6170(void) { - D_800E3760 = allocate_from_main_pool_safe(0x2800, COLOR_TAG_BLACK); - D_800E3764 = allocate_from_main_pool_safe(0x10, COLOR_TAG_BLACK); -} - -/** - * Converts a little endian value to big endian. - */ -s32 byteswap32(u8* arg0) { - s32 value; - value = *arg0++; - value |= (*arg0++ << 8); - value |= (*arg0++ << 16); - value |= (*arg0++ << 24); - return value; -} - -/** - * Returns the uncompressed size of a gzip compressed asset. - */ -s32 get_asset_uncompressed_size(s32 assetIndex, s32 assetOffset) { - load_asset_to_address(assetIndex, D_800E3764, assetOffset, 8); - return byteswap32(D_800E3764); -} - -s32 gzip_inflate_block(void); - -/** - * Decompresses gzip data. - * Returns the pointer to the decompressed data. - */ -u8* gzip_inflate(u8* compressedInput, u8* decompressedOutput) { - gzip_inflate_input = compressedInput + 5; // The compression header is 5 bytes. - gzip_inflate_output = decompressedOutput; - gzip_num_bits = 0; - gzip_bit_buffer = 0; - while(gzip_inflate_block() != 0) {} // Keep calling gzip_inflate_block() until it returns 0. - return decompressedOutput; -} - -GLOBAL_ASM("asm/non_matchings/unknown_0B8920/gzip_huft_build.s")