From 8f89095bf086d4ef0aca9393342a8840450b4330 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 13:19:57 -0500 Subject: [PATCH 01/10] jpeg encoding/decoding utils --- Makefile | 2 ++ src/3FB0.c | 4 ++-- src/3FB0.h | 2 +- src/C970.c | 37 ++++++++++++++++--------------------- src/C970.h | 15 ++++++++------- src/CE80.c | 16 ++++++++-------- src/CE80.h | 12 ++++++------ 7 files changed, 43 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index 1ea59c0..164bb0c 100644 --- a/Makefile +++ b/Makefile @@ -274,6 +274,8 @@ build/src/hal_libc.o: CFLAGS += -signed build/src/libleo/%.o: CC := $(CC_OLD) +build/src/C970.o: CC := $(CC_OLD) + build/src/D470.o: CC := $(CC_OLD) build/src/D470.o: OPTFLAGS := -O0 build/src/D470.o: MIPS_VERSION := -mips1 diff --git a/src/3FB0.c b/src/3FB0.c index 80b1041..1f85f91 100644 --- a/src/3FB0.c +++ b/src/3FB0.c @@ -119,7 +119,7 @@ void func_80003558(UnkStruct80001380* arg0, unk_func_80003680_sp90* arg1) { osCreateMesgQueue(&arg0->queue, &arg0->mesg, 1); } -void func_80003608(unk_func_80003680_sp27* arg0, unk_func_80003680_spB0* arg1, unk_func_80003680_sp300* arg2) { +void func_80003608(unk_func_80003680_sp27* arg0, JpegHuffmanTable* arg1, unk_func_80003680_sp300* arg2) { arg0->unk_00 = arg2->start_of_scan; arg0->unk_04 = arg2->unk_00; arg0->unk_05 = 2; @@ -143,7 +143,7 @@ s32 func_80003680(u32 addr, s32 arg1, u8* arg2) { UnkStruct80001380 sp318; unk_func_80003680_sp300 sp300; u8 sp200[2][0x80]; - unk_func_80003680_spB0 spB0[4]; + JpegHuffmanTable spB0[4]; u16* temp_s0; u8* temp_s3; unk_func_80003680_sp90 sp90; diff --git a/src/3FB0.h b/src/3FB0.h index 9a73fd4..d4f5e7d 100644 --- a/src/3FB0.h +++ b/src/3FB0.h @@ -87,7 +87,7 @@ typedef void (*ret_func_80004454)(void); s32 func_800033B0(u8* arg0); void func_800033C8(unk_func_80003680_sp300* arg0, u8* arg1); void func_80003558(UnkStruct80001380* arg0, unk_func_80003680_sp90* arg1); -void func_80003608(unk_func_80003680_sp27* arg0, unk_func_80003680_spB0* arg1, unk_func_80003680_sp300* arg2); +void func_80003608(unk_func_80003680_sp27* arg0, JpegHuffmanTable* arg1, unk_func_80003680_sp300* arg2); void func_80003648(unk_func_80003680_sp90* arg0, u8(arg1)[2][0x80], unk_func_80003680_sp300* arg2); s32 func_80003680(u32 addr, s32 arg1, u8* arg2); void func_80003860(void); diff --git a/src/C970.c b/src/C970.c index 9284a98..e01b06d 100644 --- a/src/C970.c +++ b/src/C970.c @@ -102,32 +102,27 @@ s16 func_8000BE5C(u8* arg0, u16* arg1) { #pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BE5C.s") #endif -#ifdef NON_MATCHING -s8 func_8000BEC8(u8* arg0, unk_func_80003680_spB0* arg1, u16* arg2) { - s32 i; - s32 temp_t4; - s8 var_v1; +u16 func_8000BEC8(u8* data, JpegHuffmanTable* ht, u16* codes) { + u8 idx; + u16 codeOff = 0; - var_v1 = 0; - for (i = 0; i < 16; i = (i + 1) & 0xFF) { - if (arg0[i] != 0) { - arg1->unk_00[i] = var_v1; - arg1->unk_10[i] = arg2[var_v1]; - temp_t4 = ((var_v1 + arg0[i]) - 1) & 0xFFFF; - var_v1 = (temp_t4 + 1); - arg1->unk_30[i] = arg2[temp_t4]; + for (idx = 0; idx < 0x10; idx++) { + if (data[idx]) { + ht->codeOffs[idx] = codeOff; + ht->codesA[idx] = codes[codeOff]; + codeOff += data[idx] - 1; + ht->codesB[idx] = codes[codeOff]; + codeOff++; } else { - arg1->unk_30[i] = 0xFFFF; + ht->codesB[idx] = 0xFFFF; } } - return var_v1; + + return codeOff; } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BEC8.s") -#endif #ifdef NON_MATCHING -s16 func_8000BF70(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, u8 arg4) { +s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4) { s16 temp_v0; temp_v0 = func_8000BDD8(arg2, arg3); @@ -147,7 +142,7 @@ s16 func_8000BF70(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, u #endif #ifdef NON_MATCHING -s32 func_8000C02C(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, s32 arg4) { +s32 func_8000C02C(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, s32 arg4) { s32 temp_at; s32 temp_lo; s32 temp_t8; @@ -170,7 +165,7 @@ s32 func_8000C02C(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, s } temp_t8 = (var_s1 + 1) & 0xFF; temp_at = temp_t8 < (s32) arg4; - arg1[temp_lo].unk_50 = temp_s0_2; + arg1[temp_lo].symbols = temp_s0_2; var_s1 = temp_t8; var_s0 = temp_s0_2 + temp_v0; if (temp_at == 0) { diff --git a/src/C970.h b/src/C970.h index 24bfc0f..aa6b19d 100644 --- a/src/C970.h +++ b/src/C970.h @@ -3,14 +3,15 @@ #include "global.h" -typedef struct unk_func_80003680_spB0 { - /* 0x00 */ u8 unk_00[16]; - /* 0x10 */ u16 unk_10[16]; - /* 0x30 */ u16 unk_30[16]; - /* 0x50 */ s32 unk_50; -} unk_func_80003680_spB0; // size = 0x54 +typedef struct JpegHuffmanTable { + /* 0x00 */ u8 codeOffs[16]; + /* 0x10 */ u16 codesA[16]; + /* 0x30 */ u16 codesB[16]; + /* 0x50 */ u8* symbols; +} JpegHuffmanTable; // size = 0x54 void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables); -s32 func_8000C02C(u8*, unk_func_80003680_spB0*, u8*, u16*, s32); +s32 func_8000C02C(u8*, JpegHuffmanTable*, u8*, u16*, s32); +u16 func_8000BEC8(u8* data, JpegHuffmanTable* ht, u16* codes); #endif // _C970_H_ diff --git a/src/CE80.c b/src/CE80.c index dd7e639..9d4a1be 100644 --- a/src/CE80.c +++ b/src/CE80.c @@ -14,10 +14,10 @@ s32 func_8000C280(unk_func_80003680_sp27* arg0, u32 arg1, u32 arg2, u8 arg3, unk s16 sp60; u32 i; s32 sp58; - unk_func_80003680_spB0* temp_fp; - unk_func_80003680_spB0* temp_s4; - unk_func_80003680_spB0* temp_s5; - unk_func_80003680_spB0* temp_s7; + JpegHuffmanTable* temp_fp; + JpegHuffmanTable* temp_s4; + JpegHuffmanTable* temp_s5; + JpegHuffmanTable* temp_s7; sp58 = 0; D_800A82D0 = arg0->unk_00; @@ -93,7 +93,7 @@ s32 func_8000C280(unk_func_80003680_sp27* arg0, u32 arg1, u32 arg2, u8 arg3, unk #endif #ifdef NON_MATCHING -s32 func_8000C4A8(unk_func_80003680_spB0* arg0, unk_func_80003680_spB0* arg1, s16* arg2, s16* arg3) { +s32 func_8000C4A8(JpegHuffmanTable* arg0, JpegHuffmanTable* arg1, s16* arg2, s16* arg3) { s8 i; s8 sp36; s16 sp34; @@ -146,7 +146,7 @@ typedef struct sp24_func_8000C644 { } sp24_func_8000C644; #ifdef NON_MATCHING -s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) { +s32 func_8000C644(JpegHuffmanTable* arg0, s16* arg1, s8* arg2) { u8 i; sp24_func_8000C644 sp24; s16 temp_v0; @@ -157,7 +157,7 @@ s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) { for (i = 0; i < 16; i++) { sp24.unk_00 = temp_v0 >> (0xF - i); - if ((arg0->unk_30[i] != 0xFFFF) && !(arg0->unk_30[i] < sp24.unk_00)) { + if ((arg0->codesB[i] != 0xFFFF) && !(arg0->codesB[i] < sp24.unk_00)) { break; } } @@ -166,7 +166,7 @@ s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) { return 1; } - sp24.unk_02 = *(u8*)(((arg0->unk_00[i] + sp24.unk_00) - arg0->unk_10[i]) + arg0->unk_50); + sp24.unk_02 = *(u8*)(((arg0->codeOffs[i] + sp24.unk_00) - arg0->codesA[i]) + arg0->symbols); *arg2 = sp24.unk_02 >> 4; D_800A82D8 = (D_800A82D8 + i) - 0xF; diff --git a/src/CE80.h b/src/CE80.h index 478a2a2..5db1ce5 100644 --- a/src/CE80.h +++ b/src/CE80.h @@ -8,10 +8,10 @@ typedef struct unk_func_80003680_sp27 { /* 0x00 */ s32 unk_00; /* 0x04 */ u8 unk_04; /* 0x05 */ u8 unk_05; - /* 0x08 */ unk_func_80003680_spB0* unk_08; - /* 0x0C */ unk_func_80003680_spB0* unk_0C; - /* 0x10 */ unk_func_80003680_spB0* unk_10; - /* 0x14 */ unk_func_80003680_spB0* unk_14; + /* 0x08 */ JpegHuffmanTable* unk_08; + /* 0x0C */ JpegHuffmanTable* unk_0C; + /* 0x10 */ JpegHuffmanTable* unk_10; + /* 0x14 */ JpegHuffmanTable* unk_14; /* 0x18 */ s8 unk_18; } unk_func_80003680_sp27; // size == 0x1C @@ -26,8 +26,8 @@ typedef struct unk_func_80003680_sp60 { } unk_func_80003680_sp60; // size = 0x14 s32 func_8000C280(unk_func_80003680_sp27*, u32, u32, u8, unk_func_80003680_sp60*); -s32 func_8000C4A8(unk_func_80003680_spB0*, unk_func_80003680_spB0*, s16*, s16*); -s32 func_8000C644(unk_func_80003680_spB0*, s16*, s8*); +s32 func_8000C4A8(JpegHuffmanTable*, JpegHuffmanTable*, s16*, s16*); +s32 func_8000C644(JpegHuffmanTable*, s16*, s8*); u16 func_8000C780(u8); #endif // _CE80_H_ From f1fdf1adad97acd5186b9cad7f3d7217b19b3020 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 13:35:56 -0500 Subject: [PATCH 02/10] rename func --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 4 ++-- src/C970.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 6d813f8..851b589 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -308,7 +308,7 @@ __LeoBootGame3 = 0x8000BD10; // type:func func_8000BD70 = 0x8000BD70; // type:func func_8000BDD8 = 0x8000BDD8; // type:func func_8000BE5C = 0x8000BE5C; // type:func -func_8000BEC8 = 0x8000BEC8; // type:func +JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func func_8000BF70 = 0x8000BF70; // type:func func_8000C02C = 0x8000C02C; // type:func func_8000C104 = 0x8000C104; // type:func diff --git a/src/C970.c b/src/C970.c index e01b06d..fbe2b68 100644 --- a/src/C970.c +++ b/src/C970.c @@ -102,7 +102,7 @@ s16 func_8000BE5C(u8* arg0, u16* arg1) { #pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BE5C.s") #endif -u16 func_8000BEC8(u8* data, JpegHuffmanTable* ht, u16* codes) { +u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { u8 idx; u16 codeOff = 0; @@ -132,7 +132,7 @@ s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4 if (func_8000BE5C(arg2, arg3) != temp_v0) { return 0; } - if (temp_v0 != func_8000BEC8(arg0, arg1, arg3)) { + if (temp_v0 != JpegUtils_SetHuffmanTable(arg0, arg1, arg3)) { return 0; } return temp_v0; diff --git a/src/C970.h b/src/C970.h index aa6b19d..fefd132 100644 --- a/src/C970.h +++ b/src/C970.h @@ -12,6 +12,6 @@ typedef struct JpegHuffmanTable { void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables); s32 func_8000C02C(u8*, JpegHuffmanTable*, u8*, u16*, s32); -u16 func_8000BEC8(u8* data, JpegHuffmanTable* ht, u16* codes); +u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes); #endif // _C970_H_ From 4a065fe712acd105093a3cf06fc52070e5b20bd0 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 14:08:33 -0500 Subject: [PATCH 03/10] JpegUtils_ProcessQuantizationTable --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/3FB0.c | 2 +- src/C970.c | 26 +++++++------------------ src/C970.h | 6 +++++- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 851b589..4d667b7 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -305,7 +305,7 @@ abs_asm = 0x8000B8A0; // type:func LeoBootGame = 0x8000B8B0; // type:func __LeoBootGame2 = 0x8000B9EC; // type:func __LeoBootGame3 = 0x8000BD10; // type:func -func_8000BD70 = 0x8000BD70; // type:func +JpegUtils_ProcessQuantizationTable = 0x8000BD70; // type:func func_8000BDD8 = 0x8000BDD8; // type:func func_8000BE5C = 0x8000BE5C; // type:func JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func diff --git a/src/3FB0.c b/src/3FB0.c index 1f85f91..31c1ddb 100644 --- a/src/3FB0.c +++ b/src/3FB0.c @@ -159,7 +159,7 @@ s32 func_80003680(u32 addr, s32 arg1, u8* arg2) { temp_s0 = Util_Malloc(0x210); func_800033C8(&sp300, arg2); - func_8000BD70(sp300.quantization_table, sp200, 2); + JpegUtils_ProcessQuantizationTable(sp300.quantization_table, sp200, 2); func_8000C02C(sp300.huffman_table, spB0, temp_s3, temp_s0, 4); Util_Free(temp_s0); diff --git a/src/C970.c b/src/C970.c index fbe2b68..a07cdf0 100644 --- a/src/C970.c +++ b/src/C970.c @@ -8,30 +8,18 @@ typedef struct unk_func_8000C104_arg1 { /* 0x100 */ u16 unk_100; } unk_func_8000C104_arg1; // size >= 0x102 -#ifdef NON_MATCHING -void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables) { - u8* src; - u8* dst; - s32 i; - s32 j; - s32 count; +void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables) { + u8 i; - src = in_quantization_tables; - count = num_tables & 0xFF; + for (i = 0; i < num_tables; i++) { + u8 j; - for (i = 0; i < count; i++) { - src++; - - for (j = 0; j < 0x40; j++) { - dst = out_quantization_tables + (i << 7) + (j * 2); - *(s16*)dst = (s16)*src; - src++; + dqt++; + for (j = 0; j < 64; j++) { + qt[i].table[j] = *dqt++; } } } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BD70.s") -#endif #ifdef NON_MATCHING s16 func_8000BDD8(u8* arg0, u16* arg1) { diff --git a/src/C970.h b/src/C970.h index fefd132..6ab6d24 100644 --- a/src/C970.h +++ b/src/C970.h @@ -10,7 +10,11 @@ typedef struct JpegHuffmanTable { /* 0x50 */ u8* symbols; } JpegHuffmanTable; // size = 0x54 -void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables); +typedef struct JpegQuantizationTable { + /* 0x00 */ u16 table[8*8]; +} JpegQuantizationTable; // size = 0x80 + +void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables); s32 func_8000C02C(u8*, JpegHuffmanTable*, u8*, u16*, s32); u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes); From 67269da1f74be23567d51983129e887d29b217b1 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 14:35:07 -0500 Subject: [PATCH 04/10] JpegUtils_ParseHuffmanCodesLengths --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 42 +++++++++---------------- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 4d667b7..2996917 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -306,7 +306,7 @@ LeoBootGame = 0x8000B8B0; // type:func __LeoBootGame2 = 0x8000B9EC; // type:func __LeoBootGame3 = 0x8000BD10; // type:func JpegUtils_ProcessQuantizationTable = 0x8000BD70; // type:func -func_8000BDD8 = 0x8000BDD8; // type:func +JpegUtils_ParseHuffmanCodesLengths = 0x8000BDD8; // type:func func_8000BE5C = 0x8000BE5C; // type:func JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func func_8000BF70 = 0x8000BF70; // type:func diff --git a/src/C970.c b/src/C970.c index a07cdf0..1742522 100644 --- a/src/C970.c +++ b/src/C970.c @@ -21,35 +21,23 @@ void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 n } } -#ifdef NON_MATCHING -s16 func_8000BDD8(u8* arg0, u16* arg1) { - s16 var_a2; - s16 var_v1; - s8 i; - s8 var_v0; - u8* temp_a1; +s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) { + u8 off = 1; + s16 count = 0; + s16 idx = 1; - var_v0 = 1; - var_v1 = 0; - var_a2 = 1; - for (i = 1; i < 0x11; i = (var_v0 + 1) & 0xFF) { - temp_a1 = &arg0[i]; - if ((s32) temp_a1[-1] > 0) { - do { - arg1[var_v1] = var_v0; - var_a2 += 1; - var_v1 += 1; - } while ((s32) temp_a1[-1] >= var_a2); - var_a2 = 1; + while (off < 0x11) { + while (idx <= ptr[off - 1]) { + codesLengths[count++] = off; + idx++; } - var_v0 = i; + idx = 1; + off++; } - arg1[var_v1] = 0; - return var_v1; + + codesLengths[count] = 0; + return count; } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BDD8.s") -#endif #ifdef NON_MATCHING s16 func_8000BE5C(u8* arg0, u16* arg1) { @@ -113,7 +101,7 @@ u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4) { s16 temp_v0; - temp_v0 = func_8000BDD8(arg2, arg3); + temp_v0 = JpegUtils_GetHuffmanCodes(arg2, arg3); if ((temp_v0 == 0) || ((arg4 != 0) && (temp_v0 >= 0x101)) || ((arg4 == 0) && (temp_v0 >= 0x11))) { return 0; } @@ -196,7 +184,7 @@ s32 func_8000C1AC(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3) { temp_s0 = arg0 + 1; sp2F = (u8) ((s32) *arg0 >> 4); - temp_v0 = func_8000BDD8(temp_s0, arg2); + temp_v0 = JpegUtils_GetHuffmanCodes(temp_s0, arg2); if ((temp_v0 == 0) || ((sp2F != 0) && (temp_v0 >= 0x101)) || ((sp2F == 0) && (temp_v0 >= 0x11))) { return 1; } From b8e8c5caba5198ca6ffda445bfcc96c3129841d3 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 14:44:05 -0500 Subject: [PATCH 05/10] JpegUtils_ProcessHuffmanTable --- src/3FB0.c | 2 +- src/C970.c | 45 +++++++++++++-------------------------------- src/C970.h | 2 +- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/src/3FB0.c b/src/3FB0.c index 31c1ddb..10b6f88 100644 --- a/src/3FB0.c +++ b/src/3FB0.c @@ -160,7 +160,7 @@ s32 func_80003680(u32 addr, s32 arg1, u8* arg2) { func_800033C8(&sp300, arg2); JpegUtils_ProcessQuantizationTable(sp300.quantization_table, sp200, 2); - func_8000C02C(sp300.huffman_table, spB0, temp_s3, temp_s0, 4); + JpegUtils_ProcessHuffmanTable(sp300.huffman_table, spB0, temp_s3, temp_s0, 4); Util_Free(temp_s0); Util_Free(temp_s3); diff --git a/src/C970.c b/src/C970.c index 1742522..42698d2 100644 --- a/src/C970.c +++ b/src/C970.c @@ -117,43 +117,24 @@ s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4 #pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BF70.s") #endif -#ifdef NON_MATCHING -s32 func_8000C02C(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, s32 arg4) { - s32 temp_at; - s32 temp_lo; - s32 temp_t8; - s32 temp_v0; - s32 var_s1; - u8* var_s0; - u8* temp_s0; - u8* temp_s0_2; +s32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) { + u8 idx; + u32 codeCount; - var_s0 = arg0; - var_s1 = 0; - if ((s32) arg4 > 0) { - while(1) { - temp_lo = var_s1 * 0x54; - temp_s0 = var_s0 + 1; - temp_v0 = func_8000BF70(temp_s0, &arg1[temp_lo], arg2, arg3, (s32) *var_s0 >> 4); - temp_s0_2 = temp_s0 + 0x10; - if (temp_v0 == 0) { - return 1; - } - temp_t8 = (var_s1 + 1) & 0xFF; - temp_at = temp_t8 < (s32) arg4; - arg1[temp_lo].symbols = temp_s0_2; - var_s1 = temp_t8; - var_s0 = temp_s0_2 + temp_v0; - if (temp_at == 0) { - return 0; - } + for (idx = 0; idx < count; idx++) { + u32 ac = (*dht++ >> 4); + + codeCount = func_8000BF70(dht, &ht[idx], codesLengths, codes, ac); + if (codeCount == 0) { + return 1; } + + dht += 0x10; + ht[idx].symbols = dht; + dht += codeCount; } return 0; } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C02C.s") -#endif #ifdef NON_MATCHING void func_8000C104(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3, s16 arg4, u8 arg5) { diff --git a/src/C970.h b/src/C970.h index 6ab6d24..3c3df77 100644 --- a/src/C970.h +++ b/src/C970.h @@ -15,7 +15,7 @@ typedef struct JpegQuantizationTable { } JpegQuantizationTable; // size = 0x80 void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables); -s32 func_8000C02C(u8*, JpegHuffmanTable*, u8*, u16*, s32); +s32 JpegUtils_ProcessHuffmanTable(u8*, JpegHuffmanTable*, u8*, u16*, u8); u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes); #endif // _C970_H_ From 5e43fa88ffaf2e3b1df30982be566ba2f7acd5f2 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 14:48:01 -0500 Subject: [PATCH 06/10] JpegUtils_GetHuffmanCodes --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 57 ++++++++++--------------- 2 files changed, 24 insertions(+), 35 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 2996917..0da2d7c 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -307,7 +307,7 @@ __LeoBootGame2 = 0x8000B9EC; // type:func __LeoBootGame3 = 0x8000BD10; // type:func JpegUtils_ProcessQuantizationTable = 0x8000BD70; // type:func JpegUtils_ParseHuffmanCodesLengths = 0x8000BDD8; // type:func -func_8000BE5C = 0x8000BE5C; // type:func +JpegUtils_GetHuffmanCodes = 0x8000BE5C; // type:func JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func func_8000BF70 = 0x8000BF70; // type:func func_8000C02C = 0x8000C02C; // type:func diff --git a/src/C970.c b/src/C970.c index 42698d2..2e41505 100644 --- a/src/C970.c +++ b/src/C970.c @@ -39,44 +39,33 @@ s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) { return count; } -#ifdef NON_MATCHING -s16 func_8000BE5C(u8* arg0, u16* arg1) { - s16 var_v0; - s16 var_v1; - s32 temp_t6; - u8 temp_t0; - u8 var_a2; - u8 var_a3; +s16 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes) { + s16 idx = 0; + u16 code = 0; + u8 lastLen = codesLengths[0]; - var_a2 = *arg0; - var_v1 = 0; - var_v0 = 0; - var_a3 = var_a2; + while (true) { + while (true) { + codes[idx++] = code++; - while(1) { - temp_t6 = var_v1 * 2; - var_v1 += 1; - arg1[temp_t6] = var_v0; - temp_t0 = arg0[var_v1]; - var_v0 = (var_v0 + 1) & 0xFFFF; - if (var_a3 == temp_t0) { - continue; + if (codesLengths[idx] != lastLen) { + break; + } } - if (temp_t0 != 0) { - do { - var_a3 = (var_a2 + 1) & 0xFF; - var_v0 = (var_v0 * 2) & 0xFFFF; - var_a2 = var_a3; - } while (temp_t0 != var_a3); - continue; + + if (codesLengths[idx] == 0) { + break; + } + + while (true) { + if (code <<= 1, codesLengths[idx] == ++lastLen) { + break; + } } - break; } - return var_v1; + + return idx; } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BE5C.s") -#endif u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { u8 idx; @@ -105,7 +94,7 @@ s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4 if ((temp_v0 == 0) || ((arg4 != 0) && (temp_v0 >= 0x101)) || ((arg4 == 0) && (temp_v0 >= 0x11))) { return 0; } - if (func_8000BE5C(arg2, arg3) != temp_v0) { + if (JpegUtils_GetHuffmanCodes(arg2, arg3) != temp_v0) { return 0; } if (temp_v0 != JpegUtils_SetHuffmanTable(arg0, arg1, arg3)) { @@ -170,7 +159,7 @@ s32 func_8000C1AC(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3) { return 1; } sp2C = temp_v0; - if (func_8000BE5C(arg2, arg3) != temp_v0) { + if (JpegUtils_GetHuffmanCodes(arg2, arg3) != temp_v0) { return 1; } func_8000C104((u8*)temp_s0 + 0x10, arg1, arg2, arg3, temp_v0, sp2F); From 333811564add81270886bf6fd3903b8a6d37d674 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 15:05:21 -0500 Subject: [PATCH 07/10] JpegUtils_ProcessHuffmanTableImpl --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 0da2d7c..72c388e 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -309,7 +309,7 @@ JpegUtils_ProcessQuantizationTable = 0x8000BD70; // type:func JpegUtils_ParseHuffmanCodesLengths = 0x8000BDD8; // type:func JpegUtils_GetHuffmanCodes = 0x8000BE5C; // type:func JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func -func_8000BF70 = 0x8000BF70; // type:func +JpegUtils_ProcessHuffmanTableImpl = 0x8000BF70; // type:func func_8000C02C = 0x8000C02C; // type:func func_8000C104 = 0x8000C104; // type:func func_8000C1AC = 0x8000C1AC; // type:func diff --git a/src/C970.c b/src/C970.c index 2e41505..1fe5d53 100644 --- a/src/C970.c +++ b/src/C970.c @@ -86,25 +86,24 @@ u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { return codeOff; } -#ifdef NON_MATCHING -s16 func_8000BF70(u8* arg0, JpegHuffmanTable* arg1, u8* arg2, u16* arg3, u8 arg4) { - s16 temp_v0; +u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc) { + s16 ret; + s32 count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths); + s32 temp; - temp_v0 = JpegUtils_GetHuffmanCodes(arg2, arg3); - if ((temp_v0 == 0) || ((arg4 != 0) && (temp_v0 >= 0x101)) || ((arg4 == 0) && (temp_v0 >= 0x11))) { + ret = count; + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { return 0; } - if (JpegUtils_GetHuffmanCodes(arg2, arg3) != temp_v0) { + if (ret != JpegUtils_GetHuffmanCodes(codesLengths, codes)) { return 0; } - if (temp_v0 != JpegUtils_SetHuffmanTable(arg0, arg1, arg3)) { + if (temp = JpegUtils_SetHuffmanTable(data, ht, codes), temp != ret) { return 0; } - return temp_v0; + + return ret; } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BF70.s") -#endif s32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) { u8 idx; @@ -113,7 +112,7 @@ s32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLength for (idx = 0; idx < count; idx++) { u32 ac = (*dht++ >> 4); - codeCount = func_8000BF70(dht, &ht[idx], codesLengths, codes, ac); + codeCount = JpegUtils_ProcessHuffmanTableImpl(dht, &ht[idx], codesLengths, codes, ac); if (codeCount == 0) { return 1; } From c536feed7890b5ed80fd3d3916a6f7391798f815 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 15:18:03 -0500 Subject: [PATCH 08/10] JpegUtils_SetHuffmanTableOld --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 40 +++++++++++-------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index 72c388e..a6d75cc 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -311,7 +311,7 @@ JpegUtils_GetHuffmanCodes = 0x8000BE5C; // type:func JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func JpegUtils_ProcessHuffmanTableImpl = 0x8000BF70; // type:func func_8000C02C = 0x8000C02C; // type:func -func_8000C104 = 0x8000C104; // type:func +JpegUtils_SetHuffmanTableOld = 0x8000C104; // type:func func_8000C1AC = 0x8000C1AC; // type:func func_8000C280 = 0x8000C280; // type:func func_8000C4A8 = 0x8000C4A8; // type:func diff --git a/src/C970.c b/src/C970.c index 1fe5d53..3a729ac 100644 --- a/src/C970.c +++ b/src/C970.c @@ -1,12 +1,10 @@ #include "C970.h" -typedef struct unk_func_8000C104_arg1 { - /* 0x000 */ u8 value; - /* 0x001 */ u8 pad01[0x0F]; - /* 0x010 */ u16 unk_10; - /* 0x012 */ u8 pad12[0xEE]; - /* 0x100 */ u16 unk_100; -} unk_func_8000C104_arg1; // size >= 0x102 +typedef struct JpegHuffmanTableOld { + /* 0x000 */ u8 codeOffs[16]; + /* 0x010 */ u16 dcCodes[120]; + /* 0x100 */ u16 acCodes[256]; +} JpegHuffmanTableOld; // size >= 0x300 void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables) { u8 i; @@ -124,28 +122,24 @@ s32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLength return 0; } -#ifdef NON_MATCHING -void func_8000C104(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3, s16 arg4, u8 arg5) { - s16 i; - u8 temp_v1; +void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc) { + s16 idx; + u8 a; - for (i = 0; i < arg4; i++) { - temp_v1 = arg0[i]; - if (arg5 != 0) { - arg1[temp_v1 * 2].unk_100 = arg3[i]; - arg1[temp_v1].value = arg2[i]; + for (idx = 0; idx < count; idx++) { + a = data[idx]; + if (isAc) { + ht->acCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; } else { - arg1[temp_v1 * 2].unk_10 = arg3[i]; - arg1[temp_v1].value = arg2[i]; + ht->dcCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; } } } -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C104.s") -#endif #ifdef NON_MATCHING -s32 func_8000C1AC(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3) { +s32 func_8000C1AC(u8* arg0, JpegHuffmanTableOld* arg1, u8* arg2, u16* arg3) { u8 sp2F; s16 sp2C; s16 temp_v0; @@ -161,7 +155,7 @@ s32 func_8000C1AC(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3) { if (JpegUtils_GetHuffmanCodes(arg2, arg3) != temp_v0) { return 1; } - func_8000C104((u8*)temp_s0 + 0x10, arg1, arg2, arg3, temp_v0, sp2F); + JpegUtils_SetHuffmanTableOld((u8*)temp_s0 + 0x10, arg1, arg2, arg3, temp_v0, sp2F); return 0; } #else From cbbffad95b61e82d475e9a3d1fd77a0ce92a77ab Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 15:23:33 -0500 Subject: [PATCH 09/10] JpegUtils_ProcessHuffmanTableImplOld --- linker_scripts/us/symbol_addrs_code.txt | 2 +- src/C970.c | 30 +++++++++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/linker_scripts/us/symbol_addrs_code.txt b/linker_scripts/us/symbol_addrs_code.txt index a6d75cc..0d07c3b 100644 --- a/linker_scripts/us/symbol_addrs_code.txt +++ b/linker_scripts/us/symbol_addrs_code.txt @@ -312,7 +312,7 @@ JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func JpegUtils_ProcessHuffmanTableImpl = 0x8000BF70; // type:func func_8000C02C = 0x8000C02C; // type:func JpegUtils_SetHuffmanTableOld = 0x8000C104; // type:func -func_8000C1AC = 0x8000C1AC; // type:func +JpegUtils_ProcessHuffmanTableImplOld = 0x8000C1AC; // type:func func_8000C280 = 0x8000C280; // type:func func_8000C4A8 = 0x8000C4A8; // type:func func_8000C644 = 0x8000C644; // type:func diff --git a/src/C970.c b/src/C970.c index 3a729ac..426d0c0 100644 --- a/src/C970.c +++ b/src/C970.c @@ -138,26 +138,22 @@ void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLe } } -#ifdef NON_MATCHING -s32 func_8000C1AC(u8* arg0, JpegHuffmanTableOld* arg1, u8* arg2, u16* arg3) { - u8 sp2F; - s16 sp2C; - s16 temp_v0; - u8* temp_s0; +u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes) { + u8 isAc = *dht++ >> 4; + s16 count2; + s32 count; - temp_s0 = arg0 + 1; - sp2F = (u8) ((s32) *arg0 >> 4); - temp_v0 = JpegUtils_GetHuffmanCodes(temp_s0, arg2); - if ((temp_v0 == 0) || ((sp2F != 0) && (temp_v0 >= 0x101)) || ((sp2F == 0) && (temp_v0 >= 0x11))) { + count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths); + + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { return 1; } - sp2C = temp_v0; - if (JpegUtils_GetHuffmanCodes(arg2, arg3) != temp_v0) { + + if (JpegUtils_GetHuffmanCodes(codesLengths, codes) != count2) { return 1; } - JpegUtils_SetHuffmanTableOld((u8*)temp_s0 + 0x10, arg1, arg2, arg3, temp_v0, sp2F); + + JpegUtils_SetHuffmanTableOld(dht + 0x10, ht, codesLengths, codes, count2, isAc); + return 0; -} -#else -#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C1AC.s") -#endif +} \ No newline at end of file From 0379a7b95ef799286db37133d01c47cf69b9f525 Mon Sep 17 00:00:00 2001 From: alexanderkarlis Date: Fri, 27 Feb 2026 15:28:46 -0500 Subject: [PATCH 10/10] rename C970 -> jpegutils --- Makefile | 2 +- src/3FB0.h | 2 +- src/CE80.h | 2 +- src/{C970.c => jpegutils.c} | 2 +- src/{C970.h => jpegutils.h} | 6 +++--- yamls/us/rom.yaml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename src/{C970.c => jpegutils.c} (99%) rename src/{C970.h => jpegutils.h} (90%) diff --git a/Makefile b/Makefile index 164bb0c..60a0717 100644 --- a/Makefile +++ b/Makefile @@ -274,7 +274,7 @@ build/src/hal_libc.o: CFLAGS += -signed build/src/libleo/%.o: CC := $(CC_OLD) -build/src/C970.o: CC := $(CC_OLD) +build/src/jpegutils.o: CC := $(CC_OLD) build/src/D470.o: CC := $(CC_OLD) build/src/D470.o: OPTFLAGS := -O0 diff --git a/src/3FB0.h b/src/3FB0.h index d4f5e7d..a31a0a0 100644 --- a/src/3FB0.h +++ b/src/3FB0.h @@ -3,7 +3,7 @@ #include "global.h" #include "5580.h" -#include "C970.h" +#include "jpegutils.h" #include "CE80.h" #include "src/memmap.h" #include "src/memory.h" diff --git a/src/CE80.h b/src/CE80.h index 5db1ce5..db01d13 100644 --- a/src/CE80.h +++ b/src/CE80.h @@ -2,7 +2,7 @@ #define _CE80_H_ #include "global.h" -#include "C970.h" +#include "jpegutils.h" typedef struct unk_func_80003680_sp27 { /* 0x00 */ s32 unk_00; diff --git a/src/C970.c b/src/jpegutils.c similarity index 99% rename from src/C970.c rename to src/jpegutils.c index 426d0c0..b0f41de 100644 --- a/src/C970.c +++ b/src/jpegutils.c @@ -1,4 +1,4 @@ -#include "C970.h" +#include "jpegutils.h" typedef struct JpegHuffmanTableOld { /* 0x000 */ u8 codeOffs[16]; diff --git a/src/C970.h b/src/jpegutils.h similarity index 90% rename from src/C970.h rename to src/jpegutils.h index 3c3df77..e70efb5 100644 --- a/src/C970.h +++ b/src/jpegutils.h @@ -1,5 +1,5 @@ -#ifndef _C970_H_ -#define _C970_H_ +#ifndef JPEGUTILS_H +#define JPEGUTILS_H #include "global.h" @@ -18,4 +18,4 @@ void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 n s32 JpegUtils_ProcessHuffmanTable(u8*, JpegHuffmanTable*, u8*, u16*, u8); u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes); -#endif // _C970_H_ +#endif // JPEGUTILS_H diff --git a/yamls/us/rom.yaml b/yamls/us/rom.yaml index b107e9b..fbf0b71 100644 --- a/yamls/us/rom.yaml +++ b/yamls/us/rom.yaml @@ -47,7 +47,7 @@ - [0xC4A0, hasm, abs] # abs function - [0xC4B0, c, libleo/bootdisk] - [0xC910, hasm, ../../src/libleo/bootstrap] - - [0xC970, c] + - [0xC970, c, jpegutils] - [0xCE80, c] # - [0xD470, c] # - [0xDDC0, c]