From 132db50245f670d8492b5671b53f243981336d1d Mon Sep 17 00:00:00 2001 From: tehzz Date: Wed, 22 Jun 2022 22:21:29 -0400 Subject: [PATCH] Split and Decompile Code_800AF9B0 (#228) * change return type of func_8000546C * try to fix submodules * update asm_processor for new ASM directives * split code_800AF8B0 into 3 files; move rodata into files/asm * move rodata into code_800AF9B0 asm funcs * decomp func_800AF9E4 * match 800AFF58 * merge in master (renamed code_800AF9B0.c to menus.c) * revert menus.c back to code_800AF9B0.c * add bss to code_800AF9B0 * rename code_800B0350.c to menus.c * remove unused ALIGN macros --- .gitmodules | 2 +- asm/bss_8001C4D0.s | 261 --- asm/bss_8018EDC0.s | 249 +++ .../code_80091750/func_800A9E58.s | 8 +- asm/non_matchings/menus/func_800AF9E4.s | 170 -- asm/non_matchings/menus/func_800AFC54.s | 8 + asm/non_matchings/menus/func_800AFF58.s | 46 - asm/non_matchings/menus/func_800B0004.s | 5 + asm/non_matchings/menus/func_800B0350.s | 8 + asm/non_matchings/menus/func_800B053C.s | 54 + asm/non_matchings/menus/func_800B15AC.s | 17 + asm/non_matchings/menus/func_800B1C90.s | 7 + asm/non_matchings/menus/func_800B20F4.s | 7 + asm/non_matchings/menus/func_800B29D8.s | 20 +- asm/non_matchings/menus/func_800B3554.s | 8 +- asm/non_matchings/menus/func_800B3F74.s | 12 +- asm/non_matchings/menus/func_800B4560.s | 14 + data/data_0DD0A0_3_0.s | 734 +------ data/rodata_audio.s | 564 +++++ include/macros.h | 2 +- include/variables.h | 2 +- mk64.ld | 8 + progress.py | 2 +- src/audio/external.h | 3 + src/code_800029B0.c | 1 - src/code_80005FD0.h | 1 + src/code_80091750.c | 11 +- src/code_80091750.h | 5 +- src/code_800AF9B0.c | 239 ++ src/code_800AF9B0.h | 22 + src/code_800B45E0.c | 1514 +++++++++++++ src/code_800B45E0.h | 108 + src/main.h | 1 + src/memory.c | 4 +- src/memory.h | 2 - src/menus.c | 1936 +---------------- src/menus.h | 140 +- src/staff_ghosts.h | 12 + tools/.gitignore | 3 + tools/asm_processor/asm_processor.py | 1330 +++++++++++ tools/asm_processor/build.py | 115 +- tools/asm_processor/prelude.inc | 40 +- 42 files changed, 4428 insertions(+), 3267 deletions(-) create mode 100644 asm/bss_8018EDC0.s delete mode 100644 asm/non_matchings/menus/func_800AF9E4.s delete mode 100644 asm/non_matchings/menus/func_800AFF58.s create mode 100644 data/rodata_audio.s create mode 100644 src/code_800AF9B0.c create mode 100644 src/code_800AF9B0.h create mode 100644 src/code_800B45E0.c create mode 100644 src/code_800B45E0.h create mode 100644 src/staff_ghosts.h create mode 100644 tools/asm_processor/asm_processor.py diff --git a/.gitmodules b/.gitmodules index 4c5047f35..b7beef885 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "asm-differ"] +[submodule "tools/asm-differ"] path = tools/asm-differ url = https://github.com/simonlindholm/asm-differ [submodule "tools/decomp-permuter"] diff --git a/asm/bss_8001C4D0.s b/asm/bss_8001C4D0.s index 411e9f623..5e75295f7 100644 --- a/asm/bss_8001C4D0.s +++ b/asm/bss_8001C4D0.s @@ -2003,264 +2003,3 @@ glabel D_8018EDA8 glabel D_8018EDAC .skip 4 - -glabel D_8018EDB0 -.skip 2 - -glabel D_8018EDB2 -.skip 2 - -glabel D_8018EDB4 -.skip 4 - -glabel D_8018EDB8 -.skip 4 - -glabel D_8018EDBC -.skip 4 - -glabel D_8018EDC0 -.skip 4 - -glabel D_8018EDC4 -.skip 4 - -glabel D_8018EDC8 -.skip 4 - -glabel D_8018EDCC -.skip 4 - -glabel D_8018EDD0 -.skip 4 - -glabel D_8018EDD4 -.skip 4 - -glabel D_8018EDD8 -.skip 4 - -glabel D_8018EDDC -.skip 4 - -glabel D_8018EDE0 -.skip 4 - -glabel gCharacterGridSelections # 0x8018EDE4 -.skip 1 - -glabel D_8018EDE5 -.skip 1 - -glabel D_8018EDE6 -.skip 1 - -glabel D_8018EDE7 -.skip 1 - -glabel D_8018EDE8 -.skip 1 - -glabel D_8018EDE9 -.skip 1 - -glabel D_8018EDEA -.skip 1 - -glabel D_8018EDEB -.skip 1 - -glabel D_8018EDEC -.skip 1 - -glabel gMainMenuSelectionDepth -.skip 1 - -glabel D_8018EDEE -.skip 1 - -glabel gDebugMenuSelection -.skip 1 - -glabel gControllerPakMenuSelection # 0x8018EDF0 -.skip 1 - -glabel D_8018EDF1 -.skip 1 - -glabel gSoundMode -.skip 1 - -glabel D_8018EDF3 -.skip 1 - -glabel D_8018EDF4 -.skip 1 - -glabel D_8018EDF5 -.skip 1 - -glabel D_8018EDF6 -.skip 1 - -glabel gTimeTrialDataCourseIndex -.skip 1 - -glabel gCourseRecordsMenuSelection -.skip 1 - -glabel D_8018EDF9 -.skip 1 - -glabel gDebugGotoScene -.skip 1 - -glabel D_8018EDFB -.skip 1 - -glabel D_8018EDFC -.skip 4 - -glabel gMenuTimingCounter -.skip 4 - -glabel D_8018EE04 -.skip 4 - -glabel D_8018EE08 -.skip 1 - -glabel gCupSelection # 0x8018EE09 -.skip 1 - -glabel D_8018EE0A -.skip 1 - -glabel gCupCourseSelection # 0x8018EE0B -.skip 1 - -glabel D_8018EE0C -.skip 4 - -glabel D_8018EE10 -.skip 4 - -glabel D_8018EE14 -.skip 1 - -glabel D_8018EE15 -.skip 1 - -glabel D_8018EE16 -.skip 126 - -glabel D_8018EE94 -.skip 1 - -glabel D_8018EE95 -.skip 123 - -glabel D_8018EF10 -.skip 8 - -glabel D_8018EF18 -.skip 192 - -glabel D_8018EFD8 -.skip 3000 - -glabel D_8018FB90 -.skip 1 - -glabel D_8018FB91 -.skip 7 - -glabel D_8018FB98 -.skip 16 - -glabel D_8018FBA8 -.skip 48 - -glabel D_8018FBD8 -.skip 48 - -glabel D_8018FC08 -.skip 8 - -glabel D_8018FC10 -.skip 16 - -glabel D_8018FC20 -.skip 6144 - -glabel D_80191420 -.skip 36 - -glabel D_80191444 -.skip 5724 - -glabel D_80192AA0 -.skip 8 - -glabel D_80192AA8 -.skip 8 - -glabel D_80192AB0 -.skip 8 - -glabel D_80192AB8 -.skip 384 - -glabel D_80192C38 -.skip 4 - -glabel D_80192C3C -.skip 12 - -glabel D_80192C48 -.skip 96 - -glabel D_80192CA8 -.skip 30 - -glabel D_80192CC6 -.skip 10 - -glabel D_80192CD0 -.skip 1024 - -glabel D_801930D0 -.skip 584 - -glabel D_80193318 -.skip 1192 - -glabel D_801937C0 -.skip 24 - -glabel D_801937D8 -.skip 24 - -glabel D_801937F0 -.skip 24 - -glabel D_80193808 -.skip 24 - -glabel D_80193820 -.skip 2048 - -glabel D_80194020 -.skip 8 - -glabel D_80194028 -.skip 16 - -glabel D_80194038 -.skip 4 - -glabel D_8019403C -.skip 4 - -glabel D_80194040 -.skip 16 diff --git a/asm/bss_8018EDC0.s b/asm/bss_8018EDC0.s new file mode 100644 index 000000000..20bf258cd --- /dev/null +++ b/asm/bss_8018EDC0.s @@ -0,0 +1,249 @@ +.include "macros.inc" + +.section .bss + +glabel D_8018EDC0 +.skip 4 + +glabel D_8018EDC4 +.skip 4 + +glabel D_8018EDC8 +.skip 4 + +glabel D_8018EDCC +.skip 4 + +glabel D_8018EDD0 +.skip 4 + +glabel D_8018EDD4 +.skip 4 + +glabel D_8018EDD8 +.skip 4 + +glabel D_8018EDDC +.skip 4 + +glabel D_8018EDE0 +.skip 4 + +glabel gCharacterGridSelections # 0x8018EDE4 +.skip 1 + +glabel D_8018EDE5 +.skip 1 + +glabel D_8018EDE6 +.skip 1 + +glabel D_8018EDE7 +.skip 1 + +glabel D_8018EDE8 +.skip 1 + +glabel D_8018EDE9 +.skip 1 + +glabel D_8018EDEA +.skip 1 + +glabel D_8018EDEB +.skip 1 + +glabel D_8018EDEC +.skip 1 + +glabel gMainMenuSelectionDepth +.skip 1 + +glabel D_8018EDEE +.skip 1 + +glabel gDebugMenuSelection +.skip 1 + +glabel gControllerPakMenuSelection # 0x8018EDF0 +.skip 1 + +glabel D_8018EDF1 +.skip 1 + +glabel gSoundMode +.skip 1 + +glabel D_8018EDF3 +.skip 1 + +glabel D_8018EDF4 +.skip 1 + +glabel D_8018EDF5 +.skip 1 + +glabel D_8018EDF6 +.skip 1 + +glabel gTimeTrialDataCourseIndex +.skip 1 + +glabel gCourseRecordsMenuSelection +.skip 1 + +glabel D_8018EDF9 +.skip 1 + +glabel gDebugGotoScene +.skip 1 + +glabel D_8018EDFB +.skip 1 + +glabel D_8018EDFC +.skip 4 + +glabel gMenuTimingCounter +.skip 4 + +glabel D_8018EE04 +.skip 4 + +glabel D_8018EE08 +.skip 1 + +glabel gCupSelection # 0x8018EE09 +.skip 1 + +glabel D_8018EE0A +.skip 1 + +glabel gCupCourseSelection # 0x8018EE0B +.skip 1 + +glabel D_8018EE0C +.skip 4 + +glabel D_8018EE10 +.skip 4 + +glabel D_8018EE14 +.skip 1 + +glabel D_8018EE15 +.skip 1 + +glabel D_8018EE16 +.skip 126 + +glabel D_8018EE94 +.skip 1 + +glabel D_8018EE95 +.skip 123 + +glabel D_8018EF10 +.skip 8 + +glabel D_8018EF18 +.skip 192 + +glabel D_8018EFD8 +.skip 3000 + +glabel D_8018FB90 +.skip 1 + +glabel D_8018FB91 +.skip 7 + +glabel D_8018FB98 +.skip 16 + +glabel D_8018FBA8 +.skip 48 + +glabel D_8018FBD8 +.skip 48 + +glabel D_8018FC08 +.skip 8 + +glabel D_8018FC10 +.skip 16 + +glabel D_8018FC20 +.skip 6144 + +glabel D_80191420 +.skip 36 + +glabel D_80191444 +.skip 5724 + +glabel D_80192AA0 +.skip 8 + +glabel D_80192AA8 +.skip 8 + +glabel D_80192AB0 +.skip 8 + +glabel D_80192AB8 +.skip 384 + +glabel D_80192C38 +.skip 4 + +glabel D_80192C3C +.skip 12 + +glabel D_80192C48 +.skip 96 + +glabel D_80192CA8 +.skip 30 + +glabel D_80192CC6 +.skip 10 + +glabel D_80192CD0 +.skip 1024 + +glabel D_801930D0 +.skip 584 + +glabel D_80193318 +.skip 1192 + +glabel D_801937C0 +.skip 24 + +glabel D_801937D8 +.skip 24 + +glabel D_801937F0 +.skip 24 + +glabel D_80193808 +.skip 24 + +glabel D_80193820 +.skip 2048 + +glabel D_80194020 +.skip 8 + +glabel D_80194028 +.skip 16 + +glabel D_80194038 +.skip 4 + +glabel D_8019403C +.skip 4 + +glabel D_80194040 +.skip 16 diff --git a/asm/non_matchings/code_80091750/func_800A9E58.s b/asm/non_matchings/code_80091750/func_800A9E58.s index bab58d7d5..4932efa4e 100644 --- a/asm/non_matchings/code_80091750/func_800A9E58.s +++ b/asm/non_matchings/code_80091750/func_800A9E58.s @@ -40,11 +40,11 @@ glabel L800A9EBC /* 0AAAE0 800A9EE0 8C830004 */ lw $v1, 4($a0) /* 0AAAE4 800A9EE4 00C23021 */ addu $a2, $a2, $v0 /* 0AAAE8 800A9EE8 80C686AB */ lb $a2, %lo(gGameModeRowSelectionForNumPlayers)($a2) # -0x7955($a2) -/* 0AAAEC 800A9EEC 00025080 */ sll $t2, $v0, 2 -/* 0AAAF0 800A9EF0 01425023 */ subu $t2, $t2, $v0 -/* 0AAAF4 800A9EF4 000A5080 */ sll $t2, $t2, 2 +/* 0AAAEC 800A9EEC 00025080 */ sll $t2, $v0, 2 # playerCount * 4 +/* 0AAAF0 800A9EF0 01425023 */ subu $t2, $t2, $v0 # playerCount * 3 +/* 0AAAF4 800A9EF4 000A5080 */ sll $t2, $t2, 2 # playerCount * 12 /* 0AAAF8 800A9EF8 00065880 */ sll $t3, $a2, 2 -/* 0AAAFC 800A9EFC 014B6021 */ addu $t4, $t2, $t3 +/* 0AAAFC 800A9EFC 014B6021 */ addu $t4, $t2, $t3 # a2 * 4 + playerCount * 12 /* 0AAB00 800A9F00 3C05800F */ lui $a1, %hi(gGameModeFromNumPlayersAndRowSelection) # 0x800f /* 0AAB04 800A9F04 00AC2821 */ addu $a1, $a1, $t4 /* 0AAB08 800A9F08 8FA70020 */ lw $a3, 0x20($sp) diff --git a/asm/non_matchings/menus/func_800AF9E4.s b/asm/non_matchings/menus/func_800AF9E4.s deleted file mode 100644 index 808c623a1..000000000 --- a/asm/non_matchings/menus/func_800AF9E4.s +++ /dev/null @@ -1,170 +0,0 @@ -glabel func_800AF9E4 -/* 0B05E4 800AF9E4 00C70019 */ multu $a2, $a3 -/* 0B05E8 800AF9E8 27BDFFF0 */ addiu $sp, $sp, -0x10 -/* 0B05EC 800AF9EC AFB00004 */ sw $s0, 4($sp) -/* 0B05F0 800AF9F0 00E08025 */ move $s0, $a3 -/* 0B05F4 800AF9F4 AFB2000C */ sw $s2, 0xc($sp) -/* 0B05F8 800AF9F8 AFB10008 */ sw $s1, 8($sp) -/* 0B05FC 800AF9FC AFA60018 */ sw $a2, 0x18($sp) -/* 0B0600 800AFA00 3C01800F */ lui $at, %hi(D_800F2B30) # $at, 0x800f -/* 0B0604 800AFA04 00A08825 */ move $s1, $a1 -/* 0B0608 800AFA08 C4202B30 */ lwc1 $f0, %lo(D_800F2B30)($at) -/* 0B060C 800AFA0C 00004012 */ mflo $t0 -/* 0B0610 800AFA10 8FA6002C */ lw $a2, 0x2c($sp) -/* 0B0614 800AFA14 24120004 */ li $s2, 4 -/* 0B0618 800AFA18 8FA70028 */ lw $a3, 0x28($sp) -/* 0B061C 800AFA1C 87AB0026 */ lh $t3, 0x26($sp) -/* 0B0620 800AFA20 87AA0022 */ lh $t2, 0x22($sp) -/* 0B0624 800AFA24 00001025 */ move $v0, $zero -/* 0B0628 800AFA28 240D00FF */ li $t5, 255 -/* 0B062C 800AFA2C 240C0078 */ li $t4, 120 -/* 0B0630 800AFA30 00027900 */ sll $t7, $v0, 4 -.L800AFA34: -/* 0B0634 800AFA34 008F1821 */ addu $v1, $a0, $t7 -/* 0B0638 800AFA38 04410004 */ bgez $v0, .L800AFA4C -/* 0B063C 800AFA3C 30450001 */ andi $a1, $v0, 1 -/* 0B0640 800AFA40 10A00002 */ beqz $a1, .L800AFA4C -/* 0B0644 800AFA44 00000000 */ nop -/* 0B0648 800AFA48 24A5FFFE */ addiu $a1, $a1, -2 -.L800AFA4C: -/* 0B064C 800AFA4C 00A60019 */ multu $a1, $a2 -/* 0B0650 800AFA50 26290001 */ addiu $t1, $s1, 1 -/* 0B0654 800AFA54 0000C012 */ mflo $t8 -/* 0B0658 800AFA58 0307C821 */ addu $t9, $t8, $a3 -/* 0B065C 800AFA5C 272EFE08 */ addiu $t6, $t9, -0x1f8 -/* 0B0660 800AFA60 A46E0000 */ sh $t6, ($v1) -/* 0B0664 800AFA64 04410003 */ bgez $v0, .L800AFA74 -/* 0B0668 800AFA68 00027843 */ sra $t7, $v0, 1 -/* 0B066C 800AFA6C 24410001 */ addiu $at, $v0, 1 -/* 0B0670 800AFA70 00017843 */ sra $t7, $at, 1 -.L800AFA74: -/* 0B0674 800AFA74 15E00004 */ bnez $t7, .L800AFA88 -/* 0B0678 800AFA78 24420001 */ addiu $v0, $v0, 1 -/* 0B067C 800AFA7C 2518FE5C */ addiu $t8, $t0, -0x1a4 -/* 0B0680 800AFA80 10000004 */ b .L800AFA94 -/* 0B0684 800AFA84 A4780002 */ sh $t8, 2($v1) -.L800AFA88: -/* 0B0688 800AFA88 0110C821 */ addu $t9, $t0, $s0 -/* 0B068C 800AFA8C 272EFE5C */ addiu $t6, $t9, -0x1a4 -/* 0B0690 800AFA90 A46E0002 */ sh $t6, 2($v1) -.L800AFA94: -/* 0B0694 800AFA94 14A00010 */ bnez $a1, .L800AFAD8 -/* 0B0698 800AFA98 00000000 */ nop -/* 0B069C 800AFA9C 02310019 */ multu $s1, $s1 -/* 0B06A0 800AFAA0 846F0002 */ lh $t7, 2($v1) -/* 0B06A4 800AFAA4 448F2000 */ mtc1 $t7, $f4 -/* 0B06A8 800AFAA8 00000000 */ nop -/* 0B06AC 800AFAAC 468021A0 */ cvt.s.w $f6, $f4 -/* 0B06B0 800AFAB0 0000C012 */ mflo $t8 -/* 0B06B4 800AFAB4 44984000 */ mtc1 $t8, $f8 -/* 0B06B8 800AFAB8 00000000 */ nop -/* 0B06BC 800AFABC 468042A0 */ cvt.s.w $f10, $f8 -/* 0B06C0 800AFAC0 46005402 */ mul.s $f16, $f10, $f0 -/* 0B06C4 800AFAC4 46103480 */ add.s $f18, $f6, $f16 -/* 0B06C8 800AFAC8 4600910D */ trunc.w.s $f4, $f18 -/* 0B06CC 800AFACC 440E2000 */ mfc1 $t6, $f4 -/* 0B06D0 800AFAD0 10000010 */ b .L800AFB14 -/* 0B06D4 800AFAD4 A46E0002 */ sh $t6, 2($v1) -.L800AFAD8: -/* 0B06D8 800AFAD8 01290019 */ multu $t1, $t1 -/* 0B06DC 800AFADC 846F0002 */ lh $t7, 2($v1) -/* 0B06E0 800AFAE0 448F4000 */ mtc1 $t7, $f8 -/* 0B06E4 800AFAE4 00000000 */ nop -/* 0B06E8 800AFAE8 468042A0 */ cvt.s.w $f10, $f8 -/* 0B06EC 800AFAEC 0000C012 */ mflo $t8 -/* 0B06F0 800AFAF0 44983000 */ mtc1 $t8, $f6 -/* 0B06F4 800AFAF4 00000000 */ nop -/* 0B06F8 800AFAF8 46803420 */ cvt.s.w $f16, $f6 -/* 0B06FC 800AFAFC 46008482 */ mul.s $f18, $f16, $f0 -/* 0B0700 800AFB00 46125100 */ add.s $f4, $f10, $f18 -/* 0B0704 800AFB04 4600220D */ trunc.w.s $f8, $f4 -/* 0B0708 800AFB08 440E4000 */ mfc1 $t6, $f8 -/* 0B070C 800AFB0C 00000000 */ nop -/* 0B0710 800AFB10 A46E0002 */ sh $t6, 2($v1) -.L800AFB14: -/* 0B0714 800AFB14 A060000C */ sb $zero, 0xc($v1) -/* 0B0718 800AFB18 A060000D */ sb $zero, 0xd($v1) -/* 0B071C 800AFB1C A06C000E */ sb $t4, 0xe($v1) -/* 0B0720 800AFB20 14A00003 */ bnez $a1, .L800AFB30 -/* 0B0724 800AFB24 A06D000F */ sb $t5, 0xf($v1) -/* 0B0728 800AFB28 10000002 */ b .L800AFB34 -/* 0B072C 800AFB2C A46A0004 */ sh $t2, 4($v1) -.L800AFB30: -/* 0B0730 800AFB30 A46B0004 */ sh $t3, 4($v1) -.L800AFB34: -/* 0B0734 800AFB34 5452FFBF */ bnel $v0, $s2, .L800AFA34 -/* 0B0738 800AFB38 00027900 */ sll $t7, $v0, 4 -/* 0B073C 800AFB3C 06210003 */ bgez $s1, .L800AFB4C -/* 0B0740 800AFB40 00117843 */ sra $t7, $s1, 1 -/* 0B0744 800AFB44 26210001 */ addiu $at, $s1, 1 -/* 0B0748 800AFB48 00017843 */ sra $t7, $at, 1 -.L800AFB4C: -/* 0B074C 800AFB4C 8FB80018 */ lw $t8, 0x18($sp) -/* 0B0750 800AFB50 3C0C8015 */ lui $t4, %hi(gDisplayListHead) # $t4, 0x8015 -/* 0B0754 800AFB54 258C0298 */ addiu $t4, %lo(gDisplayListHead) # addiu $t4, $t4, 0x298 -/* 0B0758 800AFB58 07010003 */ bgez $t8, .L800AFB68 -/* 0B075C 800AFB5C 0018C843 */ sra $t9, $t8, 1 -/* 0B0760 800AFB60 27010001 */ addiu $at, $t8, 1 -/* 0B0764 800AFB64 0001C843 */ sra $t9, $at, 1 -.L800AFB68: -/* 0B0768 800AFB68 01F97021 */ addu $t6, $t7, $t9 -/* 0B076C 800AFB6C 31D80001 */ andi $t8, $t6, 1 -/* 0B0770 800AFB70 17000005 */ bnez $t8, .L800AFB88 -/* 0B0774 800AFB74 3C0DBF00 */ lui $t5, 0xbf00 -/* 0B0778 800AFB78 00001025 */ move $v0, $zero -/* 0B077C 800AFB7C 00001825 */ move $v1, $zero -/* 0B0780 800AFB80 10000004 */ b .L800AFB94 -/* 0B0784 800AFB84 00002825 */ move $a1, $zero -.L800AFB88: -/* 0B0788 800AFB88 240200FF */ li $v0, 255 -/* 0B078C 800AFB8C 240300FF */ li $v1, 255 -/* 0B0790 800AFB90 240500FF */ li $a1, 255 -.L800AFB94: -/* 0B0794 800AFB94 8D870000 */ lw $a3, ($t4) -/* 0B0798 800AFB98 3C19FA00 */ lui $t9, 0xfa00 -/* 0B079C 800AFB9C 0005C600 */ sll $t8, $a1, 0x18 -/* 0B07A0 800AFBA0 24EF0008 */ addiu $t7, $a3, 8 -/* 0B07A4 800AFBA4 AD8F0000 */ sw $t7, ($t4) -/* 0B07A8 800AFBA8 306F00FF */ andi $t7, $v1, 0xff -/* 0B07AC 800AFBAC ACF90000 */ sw $t9, ($a3) -/* 0B07B0 800AFBB0 000FCC00 */ sll $t9, $t7, 0x10 -/* 0B07B4 800AFBB4 03197025 */ or $t6, $t8, $t9 -/* 0B07B8 800AFBB8 304F00FF */ andi $t7, $v0, 0xff -/* 0B07BC 800AFBBC 000FC200 */ sll $t8, $t7, 8 -/* 0B07C0 800AFBC0 01D8C825 */ or $t9, $t6, $t8 -/* 0B07C4 800AFBC4 372F00FF */ ori $t7, $t9, 0xff -/* 0B07C8 800AFBC8 ACEF0004 */ sw $t7, 4($a3) -/* 0B07CC 800AFBCC 8D870000 */ lw $a3, ($t4) -/* 0B07D0 800AFBD0 3C18E700 */ lui $t8, 0xe700 -/* 0B07D4 800AFBD4 3C0F0400 */ lui $t7, (0x0400103F >> 16) # lui $t7, 0x400 -/* 0B07D8 800AFBD8 24EE0008 */ addiu $t6, $a3, 8 -/* 0B07DC 800AFBDC AD8E0000 */ sw $t6, ($t4) -/* 0B07E0 800AFBE0 ACE00004 */ sw $zero, 4($a3) -/* 0B07E4 800AFBE4 ACF80000 */ sw $t8, ($a3) -/* 0B07E8 800AFBE8 8D870000 */ lw $a3, ($t4) -/* 0B07EC 800AFBEC 3C018000 */ lui $at, 0x8000 -/* 0B07F0 800AFBF0 00817021 */ addu $t6, $a0, $at -/* 0B07F4 800AFBF4 24F90008 */ addiu $t9, $a3, 8 -/* 0B07F8 800AFBF8 AD990000 */ sw $t9, ($t4) -/* 0B07FC 800AFBFC 35EF103F */ ori $t7, (0x0400103F & 0xFFFF) # ori $t7, $t7, 0x103f -/* 0B0800 800AFC00 ACEF0000 */ sw $t7, ($a3) -/* 0B0804 800AFC04 ACEE0004 */ sw $t6, 4($a3) -/* 0B0808 800AFC08 8D870000 */ lw $a3, ($t4) -/* 0B080C 800AFC0C 3C190002 */ lui $t9, (0x00020400 >> 16) # lui $t9, 2 -/* 0B0810 800AFC10 37390400 */ ori $t9, (0x00020400 & 0xFFFF) # ori $t9, $t9, 0x400 -/* 0B0814 800AFC14 24F80008 */ addiu $t8, $a3, 8 -/* 0B0818 800AFC18 AD980000 */ sw $t8, ($t4) -/* 0B081C 800AFC1C ACF90004 */ sw $t9, 4($a3) -/* 0B0820 800AFC20 ACED0000 */ sw $t5, ($a3) -/* 0B0824 800AFC24 8D870000 */ lw $a3, ($t4) -/* 0B0828 800AFC28 3C0E0006 */ lui $t6, (0x00060402 >> 16) # lui $t6, 6 -/* 0B082C 800AFC2C 35CE0402 */ ori $t6, (0x00060402 & 0xFFFF) # ori $t6, $t6, 0x402 -/* 0B0830 800AFC30 24EF0008 */ addiu $t7, $a3, 8 -/* 0B0834 800AFC34 AD8F0000 */ sw $t7, ($t4) -/* 0B0838 800AFC38 ACEE0004 */ sw $t6, 4($a3) -/* 0B083C 800AFC3C ACED0000 */ sw $t5, ($a3) -/* 0B0840 800AFC40 8FB2000C */ lw $s2, 0xc($sp) -/* 0B0844 800AFC44 8FB10008 */ lw $s1, 8($sp) -/* 0B0848 800AFC48 8FB00004 */ lw $s0, 4($sp) -/* 0B084C 800AFC4C 03E00008 */ jr $ra -/* 0B0850 800AFC50 27BD0010 */ addiu $sp, $sp, 0x10 diff --git a/asm/non_matchings/menus/func_800AFC54.s b/asm/non_matchings/menus/func_800AFC54.s index f7bfa7515..a3598c6db 100644 --- a/asm/non_matchings/menus/func_800AFC54.s +++ b/asm/non_matchings/menus/func_800AFC54.s @@ -1,3 +1,11 @@ +.section .late_rodata +glabel D_800F2B38 +.double 0.001 + +glabel D_800F2B40 +.float 0.001 + +.section .text glabel func_800AFC54 /* 0B0854 800AFC54 27BDFFA8 */ addiu $sp, $sp, -0x58 /* 0B0858 800AFC58 AFBF0014 */ sw $ra, 0x14($sp) diff --git a/asm/non_matchings/menus/func_800AFF58.s b/asm/non_matchings/menus/func_800AFF58.s deleted file mode 100644 index 4a3338d76..000000000 --- a/asm/non_matchings/menus/func_800AFF58.s +++ /dev/null @@ -1,46 +0,0 @@ -glabel func_800AFF58 -/* 0B0B58 800AFF58 27BDFF08 */ addiu $sp, $sp, -0xf8 -/* 0B0B5C 800AFF5C AFB3002C */ sw $s3, 0x2c($sp) -/* 0B0B60 800AFF60 AFB20028 */ sw $s2, 0x28($sp) -/* 0B0B64 800AFF64 AFB10024 */ sw $s1, 0x24($sp) -/* 0B0B68 800AFF68 AFB00020 */ sw $s0, 0x20($sp) -/* 0B0B6C 800AFF6C 00809825 */ move $s3, $a0 -/* 0B0B70 800AFF70 AFBF0034 */ sw $ra, 0x34($sp) -/* 0B0B74 800AFF74 AFB40030 */ sw $s4, 0x30($sp) -/* 0B0B78 800AFF78 27B00088 */ addiu $s0, $sp, 0x88 -/* 0B0B7C 800AFF7C 00008825 */ move $s1, $zero -/* 0B0B80 800AFF80 27B20040 */ addiu $s2, $sp, 0x40 -.L800AFF84: -/* 0B0B84 800AFF84 00117100 */ sll $t6, $s1, 4 -/* 0B0B88 800AFF88 01D32021 */ addu $a0, $t6, $s3 -/* 0B0B8C 800AFF8C 24050001 */ li $a1, 1 -/* 0B0B90 800AFF90 24060002 */ li $a2, 2 -/* 0B0B94 800AFF94 00003825 */ move $a3, $zero -/* 0B0B98 800AFF98 0C02BF15 */ jal func_800AFC54 -/* 0B0B9C 800AFF9C AFB20010 */ sw $s2, 0x10($sp) -/* 0B0BA0 800AFFA0 26520006 */ addiu $s2, $s2, 6 -/* 0B0BA4 800AFFA4 0250082B */ sltu $at, $s2, $s0 -/* 0B0BA8 800AFFA8 1420FFF6 */ bnez $at, .L800AFF84 -/* 0B0BAC 800AFFAC 26310004 */ addiu $s1, $s1, 4 -/* 0B0BB0 800AFFB0 00008025 */ move $s0, $zero -/* 0B0BB4 800AFFB4 00008825 */ move $s1, $zero -/* 0B0BB8 800AFFB8 2414000C */ li $s4, 12 -/* 0B0BBC 800AFFBC 27B20040 */ addiu $s2, $sp, 0x40 -.L800AFFC0: -/* 0B0BC0 800AFFC0 00117900 */ sll $t7, $s1, 4 -/* 0B0BC4 800AFFC4 01F32021 */ addu $a0, $t7, $s3 -/* 0B0BC8 800AFFC8 02402825 */ move $a1, $s2 -/* 0B0BCC 800AFFCC 02003025 */ move $a2, $s0 -/* 0B0BD0 800AFFD0 0C02BF80 */ jal func_800AFE00 -/* 0B0BD4 800AFFD4 2407000B */ li $a3, 11 -/* 0B0BD8 800AFFD8 26100001 */ addiu $s0, $s0, 1 -/* 0B0BDC 800AFFDC 1614FFF8 */ bne $s0, $s4, .L800AFFC0 -/* 0B0BE0 800AFFE0 26310004 */ addiu $s1, $s1, 4 -/* 0B0BE4 800AFFE4 8FBF0034 */ lw $ra, 0x34($sp) -/* 0B0BE8 800AFFE8 8FB00020 */ lw $s0, 0x20($sp) -/* 0B0BEC 800AFFEC 8FB10024 */ lw $s1, 0x24($sp) -/* 0B0BF0 800AFFF0 8FB20028 */ lw $s2, 0x28($sp) -/* 0B0BF4 800AFFF4 8FB3002C */ lw $s3, 0x2c($sp) -/* 0B0BF8 800AFFF8 8FB40030 */ lw $s4, 0x30($sp) -/* 0B0BFC 800AFFFC 03E00008 */ jr $ra -/* 0B0C00 800B0000 27BD00F8 */ addiu $sp, $sp, 0xf8 diff --git a/asm/non_matchings/menus/func_800B0004.s b/asm/non_matchings/menus/func_800B0004.s index 24349627e..0479386a6 100644 --- a/asm/non_matchings/menus/func_800B0004.s +++ b/asm/non_matchings/menus/func_800B0004.s @@ -1,3 +1,8 @@ +.section .late_rodata +glabel D_800F2B44 +.float 0.18 + +.section .text glabel func_800B0004 /* 0B0C04 800B0004 27BDFF40 */ addiu $sp, $sp, -0xc0 /* 0B0C08 800B0008 3C038015 */ lui $v1, %hi(gDisplayListHead) # $v1, 0x8015 diff --git a/asm/non_matchings/menus/func_800B0350.s b/asm/non_matchings/menus/func_800B0350.s index d0bb45c25..4f0738951 100644 --- a/asm/non_matchings/menus/func_800B0350.s +++ b/asm/non_matchings/menus/func_800B0350.s @@ -1,3 +1,11 @@ +.section .late_rodata +glabel jpt_800F2C20 +.word L800B04B8, L800B04D0, L800B04E8, L800B0500 +.word L800B0510, L800B043C, L800B0454, L800B046C +.word L800B0484, L800B049C, L800B04B8, L800B04D0 +.word L800B04E8, L800B0500 + +.section .text glabel func_800B0350 /* 0B0F50 800B0350 3C0E800F */ lui $t6, %hi(D_800E86A4) # $t6, 0x800f /* 0B0F54 800B0354 8DCE86A4 */ lw $t6, %lo(D_800E86A4)($t6) diff --git a/asm/non_matchings/menus/func_800B053C.s b/asm/non_matchings/menus/func_800B053C.s index 90676fc9f..968cea447 100644 --- a/asm/non_matchings/menus/func_800B053C.s +++ b/asm/non_matchings/menus/func_800B053C.s @@ -1,3 +1,57 @@ +.section .late_rodata +glabel jpt_800F2C58 +.word L800B05E0, L800B05E0 +.word L800B05E0, L800B05E0, L800B13A0, L800B13A0 +.word L800B13A0, L800B13A0, L800B13A0, L800B0AF4 +.word L800B0AF4, L800B0C88, L800B13A0, L800B13A0 +.word L800B13A0, L800B13A0, L800B13A0, L800B13A0 +.word L800B13A0, L800B0CAC, L800B0CAC, L800B1020 +.word L800B1020, L800B1020, L800B1020, L800B13A0 +.word L800B13A0, L800B13A0, L800B13A0, L800B0E5C +.word L800B0E5C, L800B1020, L800B1020, L800B13A0 +.word L800B1020, L800B1044, L800B1044, L800B11C8 +.word L800B11FC, L800B1020, L800B13A0, L800B13A0 +.word L800B13A0, L800B13A0, L800B1020, L800B1020 +.word L800B13A0, L800B13A0, L800B13A0, L800B1318 +.word L800B134C + +.word 0x00000000 + +glabel D_800F2D28 +.double 4.2 + +glabel D_800F2D30 +.double 4.2 + +glabel jpt_800F2D38 # jump table +.word L800B0948, L800B096C, L800B0980, L800B09C0 +.word L800B09C0, L800B09A0 + +glabel D_800F2D50 +.double 4.2 + +glabel D_800F2D58 +.double 4.2 + +glabel D_800F2D60 +.double 4.2 + +glabel D_800F2D68 +.double 4.2 + +glabel D_800F2D70 +.double 4.2 + +glabel D_800F2D78 +.double 4.2 + +glabel D_800F2D80 +.double 4.2 + +glabel D_800F2D88 +.double 4.2 + +.section .text glabel func_800B053C /* 0B113C 800B053C 27BDFFC0 */ addiu $sp, $sp, -0x40 /* 0B1140 800B0540 AFBF001C */ sw $ra, 0x1c($sp) diff --git a/asm/non_matchings/menus/func_800B15AC.s b/asm/non_matchings/menus/func_800B15AC.s index 00c620d16..4af248e1c 100644 --- a/asm/non_matchings/menus/func_800B15AC.s +++ b/asm/non_matchings/menus/func_800B15AC.s @@ -1,3 +1,20 @@ +.section .late_rodata +glabel D_800F2D90 +.double 4.2 + +glabel D_800F2D98 +.double 4.2 + +glabel D_800F2DA0 +.double 4.2 + +glabel D_800F2DA8 +.double 4.2 + +glabel D_800F2DB0 +.double 4.2 + +.section .text glabel func_800B15AC /* 0B21AC 800B15AC 27BDFFD0 */ addiu $sp, $sp, -0x30 /* 0B21B0 800B15B0 AFBF0014 */ sw $ra, 0x14($sp) diff --git a/asm/non_matchings/menus/func_800B1C90.s b/asm/non_matchings/menus/func_800B1C90.s index 660029148..6fc018b28 100644 --- a/asm/non_matchings/menus/func_800B1C90.s +++ b/asm/non_matchings/menus/func_800B1C90.s @@ -1,3 +1,10 @@ +.section .late_rodata +glabel jpt_800F2DB8 +.word L800B1CE8, L800B1D34, L800B1F78, L800B1F2C +.word L800B1D84, L800B1FE8, L800B1FF4, L800B20D4 +.word L800B20D4, L800B20D4 + +.section .text glabel func_800B1C90 /* 0B2890 800B1C90 27BDFFC8 */ addiu $sp, $sp, -0x38 /* 0B2894 800B1C94 AFBF001C */ sw $ra, 0x1c($sp) diff --git a/asm/non_matchings/menus/func_800B20F4.s b/asm/non_matchings/menus/func_800B20F4.s index c0a5c938c..3c87222bb 100644 --- a/asm/non_matchings/menus/func_800B20F4.s +++ b/asm/non_matchings/menus/func_800B20F4.s @@ -1,3 +1,10 @@ +.section .late_rodata +glabel jpt_800F2DE0 +.word L800B2178, L800B21CC +.word L800B2240, L800B231C, L800B2414, L800B24DC +.word L800B2604 + +.section .text glabel func_800B20F4 /* 0B2CF4 800B20F4 27BDFFD0 */ addiu $sp, $sp, -0x30 /* 0B2CF8 800B20F8 240E0001 */ li $t6, 1 diff --git a/asm/non_matchings/menus/func_800B29D8.s b/asm/non_matchings/menus/func_800B29D8.s index f71a939aa..0567935da 100644 --- a/asm/non_matchings/menus/func_800B29D8.s +++ b/asm/non_matchings/menus/func_800B29D8.s @@ -1,3 +1,11 @@ +.section .late_rodata + +glabel jpt_800F2DFC +.word L800B2A6C, L800B3468, L800B3468, L800B2AA4 +.word L800B2D30, L800B2F70, L800B32B4 +.word L800B32B4, L800B2F70 + +.section .text glabel func_800B29D8 /* 0B35D8 800B29D8 27BDFFD0 */ addiu $sp, $sp, -0x30 /* 0B35DC 800B29DC AFBF0014 */ sw $ra, 0x14($sp) @@ -236,11 +244,11 @@ glabel L800B2D30 /* 0B3940 800B2D40 8042EDF3 */ lb $v0, %lo(D_8018EDF3)($v0) /* 0B3944 800B2D44 3C09800F */ lui $t1, %hi(D_800E86AC) # $t1, 0x800f /* 0B3948 800B2D48 252986AC */ addiu $t1, %lo(D_800E86AC) # addiu $t1, $t1, -0x7954 -/* 0B394C 800B2D4C 3C19800F */ lui $t9, %hi(D_800F2B5F) # 0x800f +/* 0B394C 800B2D4C 3C19800F */ lui $t9, %hi((D_800F2B58 + 7)) # 0x800f /* 0B3950 800B2D50 0322C821 */ addu $t9, $t9, $v0 /* 0B3954 800B2D54 00491821 */ addu $v1, $v0, $t1 /* 0B3958 800B2D58 8064FFFF */ lb $a0, -1($v1) -/* 0B395C 800B2D5C 83392B5F */ lb $t9, %lo(D_800F2B5F)($t9) # 0x2b5f($t9) +/* 0B395C 800B2D5C 83392B5F */ lb $t9, %lo((D_800F2B58 + 7))($t9) # 0x2b5f($t9) /* 0B3960 800B2D60 248B0001 */ addiu $t3, $a0, 1 /* 0B3964 800B2D64 0099082A */ slt $at, $a0, $t9 /* 0B3968 800B2D68 5020000B */ beql $at, $zero, .L800B2D98 @@ -464,14 +472,14 @@ glabel L800B2F70 /* 0B3C94 800B3094 3C028019 */ lui $v0, %hi(D_8018EDF3) # $v0, 0x8019 /* 0B3C98 800B3098 8042EDF3 */ lb $v0, %lo(D_8018EDF3)($v0) /* 0B3C9C 800B309C 3C04800F */ lui $a0, %hi(gGameModeRowSelectionForNumPlayers) # 0x800f -/* 0B3CA0 800B30A0 3C09800F */ lui $t1, %hi(D_800F2B6D) # 0x800f +/* 0B3CA0 800B30A0 3C09800F */ lui $t1, %hi((D_800F2B60 + 0xD)) # 0x800f /* 0B3CA4 800B30A4 00822021 */ addu $a0, $a0, $v0 /* 0B3CA8 800B30A8 808486AB */ lb $a0, %lo(gGameModeRowSelectionForNumPlayers)($a0) # -0x7955($a0) /* 0B3CAC 800B30AC 00027080 */ sll $t6, $v0, 2 /* 0B3CB0 800B30B0 01C27023 */ subu $t6, $t6, $v0 /* 0B3CB4 800B30B4 01C4C821 */ addu $t9, $t6, $a0 /* 0B3CB8 800B30B8 01394821 */ addu $t1, $t1, $t9 -/* 0B3CBC 800B30BC 81292B6D */ lb $t1, %lo(D_800F2B6D)($t1) # 0x2b6d($t1) +/* 0B3CBC 800B30BC 81292B6D */ lb $t1, %lo((D_800F2B60 + 0xD))($t1) # 0x2b6d($t1) /* 0B3CC0 800B30C0 00A9082A */ slt $at, $a1, $t1 /* 0B3CC4 800B30C4 10200012 */ beqz $at, .L800B3110 /* 0B3CC8 800B30C8 00000000 */ nop @@ -481,14 +489,14 @@ glabel L800B2F70 /* 0B3CD4 800B30D4 3C028019 */ lui $v0, %hi(D_8018EDF3) # $v0, 0x8019 /* 0B3CD8 800B30D8 8042EDF3 */ lb $v0, %lo(D_8018EDF3)($v0) /* 0B3CDC 800B30DC 3C04800F */ lui $a0, %hi(gGameModeRowSelectionForNumPlayers) # 0x800f -/* 0B3CE0 800B30E0 3C0F800F */ lui $t7, %hi(D_800F2B61) # 0x800f +/* 0B3CE0 800B30E0 3C0F800F */ lui $t7, %hi((D_800F2B60 + 1)) # 0x800f /* 0B3CE4 800B30E4 00822021 */ addu $a0, $a0, $v0 /* 0B3CE8 800B30E8 808486AB */ lb $a0, %lo(gGameModeRowSelectionForNumPlayers)($a0) # -0x7955($a0) /* 0B3CEC 800B30EC 00025880 */ sll $t3, $v0, 2 /* 0B3CF0 800B30F0 01625823 */ subu $t3, $t3, $v0 /* 0B3CF4 800B30F4 01645021 */ addu $t2, $t3, $a0 /* 0B3CF8 800B30F8 01EA7821 */ addu $t7, $t7, $t2 -/* 0B3CFC 800B30FC 81EF2B61 */ lb $t7, %lo(D_800F2B61)($t7) # 0x2b61($t7) +/* 0B3CFC 800B30FC 81EF2B61 */ lb $t7, %lo((D_800F2B60 + 1))($t7) # 0x2b61($t7) /* 0B3D00 800B3100 00AF082A */ slt $at, $a1, $t7 /* 0B3D04 800B3104 10200002 */ beqz $at, .L800B3110 /* 0B3D08 800B3108 00000000 */ nop diff --git a/asm/non_matchings/menus/func_800B3554.s b/asm/non_matchings/menus/func_800B3554.s index e0b15d02b..8cc23bb33 100644 --- a/asm/non_matchings/menus/func_800B3554.s +++ b/asm/non_matchings/menus/func_800B3554.s @@ -88,7 +88,7 @@ glabel func_800B3554 /* 0B4298 800B3698 00693821 */ addu $a3, $v1, $t1 /* 0B429C 800B369C 80EB0000 */ lb $t3, ($a3) /* 0B42A0 800B36A0 240C0001 */ li $t4, 1 -/* 0B42A4 800B36A4 3C05800F */ lui $a1, %hi(D_800F2BAB) # 0x800f +/* 0B42A4 800B36A4 3C05800F */ lui $a1, %hi((D_800F2BAC - 1)) # 0x800f /* 0B42A8 800B36A8 55600013 */ bnel $t3, $zero, .L800B36F8 /* 0B42AC 800B36AC 00002025 */ move $a0, $zero /* 0B42B0 800B36B0 8FAD0028 */ lw $t5, 0x28($sp) @@ -98,7 +98,7 @@ glabel func_800B3554 /* 0B42C0 800B36C0 3421800E */ ori $at, (0x2900800E & 0xFFFF) # ori $at, $at, 0x800e /* 0B42C4 800B36C4 AFA70020 */ sw $a3, 0x20($sp) /* 0B42C8 800B36C8 00AE2821 */ addu $a1, $a1, $t6 -/* 0B42CC 800B36CC 80A52BAB */ lb $a1, %lo(D_800F2BAB)($a1) # 0x2bab($a1) +/* 0B42CC 800B36CC 80A52BAB */ lb $a1, %lo((D_800F2BAC - 1))($a1) # 0x2bab($a1) /* 0B42D0 800B36D0 AFA6002C */ sw $a2, 0x2c($sp) /* 0B42D4 800B36D4 93A40047 */ lbu $a0, 0x47($sp) /* 0B42D8 800B36D8 00057900 */ sll $t7, $a1, 4 @@ -407,10 +407,10 @@ glabel func_800B3554 /* 0B4720 800B3B20 8063EDE4 */ lb $v1, %lo(gCharacterGridSelections)($v1) # -0x121c($v1) .L800B3B24: /* 0B4724 800B3B24 10600007 */ beqz $v1, .L800B3B44 -/* 0B4728 800B3B28 3C0A800F */ lui $t2, %hi(D_800F2BAB) # 0x800f +/* 0B4728 800B3B28 3C0A800F */ lui $t2, %hi((D_800F2BAC - 1)) # 0x800f /* 0B472C 800B3B2C 97AB0046 */ lhu $t3, 0x46($sp) /* 0B4730 800B3B30 01435021 */ addu $t2, $t2, $v1 -/* 0B4734 800B3B34 814A2BAB */ lb $t2, %lo(D_800F2BAB)($t2) # 0x2bab($t2) +/* 0B4734 800B3B34 814A2BAB */ lb $t2, %lo((D_800F2BAC - 1))($t2) # 0x2bab($t2) /* 0B4738 800B3B38 3C01800F */ lui $at, %hi(gCharacterSelections) # 0x800f /* 0B473C 800B3B3C 002B0821 */ addu $at, $at, $t3 /* 0B4740 800B3B40 A02A86A8 */ sb $t2, %lo(gCharacterSelections)($at) # -0x7958($at) diff --git a/asm/non_matchings/menus/func_800B3F74.s b/asm/non_matchings/menus/func_800B3F74.s index c361143ec..d4c86fd48 100644 --- a/asm/non_matchings/menus/func_800B3F74.s +++ b/asm/non_matchings/menus/func_800B3F74.s @@ -1,3 +1,11 @@ +.section .late_rodata +glabel jpt_800F2E20 +.word L800B4070, L800B4100 +.word L800B4230, L800B43B0, L800B4494, L800B4014 +.word L800B4024, L800B4030, L800B4040, L800B4054 +.word L800B4070, L800B4100, L800B4230, L800B43B0 + +.section .text glabel func_800B3F74 /* 0B4B74 800B3F74 24030001 */ li $v1, 1 /* 0B4B78 800B3F78 3C018019 */ lui $at, %hi(gDebugMenuSelection) # $at, 0x8019 @@ -83,7 +91,7 @@ glabel L800B4070 /* 0B4CA0 800B40A0 A020EDF7 */ sb $zero, %lo(gTimeTrialDataCourseIndex)($at) /* 0B4CA4 800B40A4 80870000 */ lb $a3, ($a0) /* 0B4CA8 800B40A8 24080004 */ li $t0, 4 -/* 0B4CAC 800B40AC 3C19800F */ lui $t9, %hi(D_800F2BDF) # 0x800f +/* 0B4CAC 800B40AC 3C19800F */ lui $t9, %hi((D_800F2BDC + 3)) # 0x800f /* 0B4CB0 800B40B0 1CE00003 */ bgtz $a3, .L800B40C0 /* 0B4CB4 800B40B4 00002825 */ move $a1, $zero /* 0B4CB8 800B40B8 A0830000 */ sb $v1, ($a0) @@ -96,7 +104,7 @@ glabel L800B4070 /* 0B4CD0 800B40D0 80870000 */ lb $a3, ($a0) /* 0B4CD4 800B40D4 0327C821 */ addu $t9, $t9, $a3 .L800B40D8: -/* 0B4CD8 800B40D8 83392BDF */ lb $t9, %lo(D_800F2BDF)($t9) # 0x2bdf($t9) +/* 0B4CD8 800B40D8 83392BDF */ lb $t9, %lo((D_800F2BDC + 3))($t9) # 0x2bdf($t9) /* 0B4CDC 800B40DC 3C018019 */ lui $at, %hi(D_8018EDF1) # $at, 0x8019 /* 0B4CE0 800B40E0 00002025 */ move $a0, $zero /* 0B4CE4 800B40E4 0C032802 */ jal func_800CA008 diff --git a/asm/non_matchings/menus/func_800B4560.s b/asm/non_matchings/menus/func_800B4560.s index 80afe253b..8b2d9cd74 100644 --- a/asm/non_matchings/menus/func_800B4560.s +++ b/asm/non_matchings/menus/func_800B4560.s @@ -1,3 +1,17 @@ +.section .rodata +glabel D_800F2BE8 +.asciiz "ghost_kart=%d," +.balign 4 + +glabel D_800F2BF8 +.asciiz "pak1_ghost_kart=%d," +.balign 4 + +glabel D_800F2C0C +.asciiz "pak2_ghost_kart=%d\n" +.balign 4 + +.section .text glabel func_800B4560 /* 0B5160 800B4560 27BDFFE0 */ addiu $sp, $sp, -0x20 /* 0B5164 800B4564 3C0E8019 */ lui $t6, %hi(D_8018D9C0) # $t6, 0x8019 diff --git a/data/data_0DD0A0_3_0.s b/data/data_0DD0A0_3_0.s index ccc9e19f8..284bb3798 100644 --- a/data/data_0DD0A0_3_0.s +++ b/data/data_0DD0A0_3_0.s @@ -33,6 +33,7 @@ #.word L80058E8C, L80058F38, L80058F38, L80058F38 #.word L80058EAC, L80058ECC, L80058EEC, L80058F0C +# start code_80057C60 .late_rodata glabel D_800EE1E0 .float 0.6 @@ -485,6 +486,7 @@ glabel D_800EE948 glabel D_800EE94C .float 1.6 +# start code_8006E9C0 .late_rodata glabel jpt_800EE950 .word L8006F0E4, L8006F174, L8006F1AC, L8006F1E4 .word L8006F248, L8006F2A4, L8006F2FC, L8006F360 @@ -570,6 +572,7 @@ glabel D_800EEA78 .float 0.7 .word 0x00000000 +# start code_80071F00 .late_rodata glabel D_800EEA80 .float 0.15 .word 0x00000000 @@ -4034,735 +4037,4 @@ glabel D_800F2B20 glabel D_800F2B28 .double 0.4 -glabel D_800F2B30 -.float -0.07 -.word 0x00000000 - -glabel D_800F2B38 -.double 0.001 - -glabel D_800F2B40 -.float 0.001 - -glabel D_800F2B44 -.float 0.18 -.word 0x00000000, 0x00000000 - -glabel D_800F2B50 -.word 0x00010203 -.word 0x03000000 - -glabel D_800F2B58 -.byte 0x01, 0x02, 0x02, 0x03, 0x04, 0x00, 0x00 - -glabel D_800F2B5F -.byte 0x00 - -glabel D_800F2B60 -.byte 0x01 - -glabel D_800F2B61 -.byte 0x02, 0x01, 0x01, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x00, 0x00 - -glabel D_800F2B6D -.byte 0x02, 0x00, 0x00 - -glabel gGameModeFromNumPlayersAndRowSelection -.byte 0x03, 0x01, 0x00, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -.byte 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 -.byte 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 -.byte 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 - -glabel D_800F2BAB -.byte 0x00, 0x00, 0x01, 0x06, 0x03 -.byte 0x02, 0x04, 0x05, 0x07 - -glabel gCupCourseOrder -.hword 0x0008, 0x0009, 0x0006, 0x000b # mushroom cup: LR, MMF, KTB, KD -.hword 0x000a, 0x0005, 0x0001, 0x0000 # flower cup: TT, FS, CM, MR -.hword 0x000e, 0x000c, 0x0007, 0x0002 # star cup: WS, SL, RRy, BC -.hword 0x0012, 0x0004, 0x0003, 0x000d # special cup: DKJP, YV, BB, RRd -.hword 0x0013, 0x000f, 0x0011, 0x0010 # battle mode: BD, BF, DD, Sky -.byte 0x01, 0x00 -.byte 0x00 - -glabel D_800F2BDF -.byte 0x00, 0x00, 0x01, 0x03, 0x04 - -glabel D_800F2BE4 -.word 0x00010203 - -glabel D_800F2BE8 -.asciiz "ghost_kart=%d," -.balign 4 - -glabel D_800F2BF8 -.asciiz "pak1_ghost_kart=%d," -.balign 4 - -glabel D_800F2C0C -.asciiz "pak2_ghost_kart=%d\n" -.balign 4 - -glabel jpt_800F2C20 -.word L800B04B8, L800B04D0, L800B04E8, L800B0500 -.word L800B0510, L800B043C, L800B0454, L800B046C -.word L800B0484, L800B049C, L800B04B8, L800B04D0 -.word L800B04E8, L800B0500 - -glabel jpt_800F2C58 -.word L800B05E0, L800B05E0 -.word L800B05E0, L800B05E0, L800B13A0, L800B13A0 -.word L800B13A0, L800B13A0, L800B13A0, L800B0AF4 -.word L800B0AF4, L800B0C88, L800B13A0, L800B13A0 -.word L800B13A0, L800B13A0, L800B13A0, L800B13A0 -.word L800B13A0, L800B0CAC, L800B0CAC, L800B1020 -.word L800B1020, L800B1020, L800B1020, L800B13A0 -.word L800B13A0, L800B13A0, L800B13A0, L800B0E5C -.word L800B0E5C, L800B1020, L800B1020, L800B13A0 -.word L800B1020, L800B1044, L800B1044, L800B11C8 -.word L800B11FC, L800B1020, L800B13A0, L800B13A0 -.word L800B13A0, L800B13A0, L800B1020, L800B1020 -.word L800B13A0, L800B13A0, L800B13A0, L800B1318 -.word L800B134C - -.word 0x00000000 - -glabel D_800F2D28 -.double 4.2 - -glabel D_800F2D30 -.double 4.2 - -glabel jpt_800F2D38 # jump table -.word L800B0948, L800B096C, L800B0980, L800B09C0 -.word L800B09C0, L800B09A0 - -glabel D_800F2D50 -.double 4.2 - -glabel D_800F2D58 -.double 4.2 - -glabel D_800F2D60 -.double 4.2 - -glabel D_800F2D68 -.double 4.2 - -glabel D_800F2D70 -.double 4.2 - -glabel D_800F2D78 -.double 4.2 - -glabel D_800F2D80 -.double 4.2 - -glabel D_800F2D88 -.double 4.2 - -glabel D_800F2D90 -.double 4.2 - -glabel D_800F2D98 -.double 4.2 - -glabel D_800F2DA0 -.double 4.2 - -glabel D_800F2DA8 -.double 4.2 - -glabel D_800F2DB0 -.double 4.2 - -glabel jpt_800F2DB8 -.word L800B1CE8, L800B1D34, L800B1F78, L800B1F2C -.word L800B1D84, L800B1FE8, L800B1FF4, L800B20D4 -.word L800B20D4, L800B20D4 - -glabel jpt_800F2DE0 -.word L800B2178, L800B21CC -.word L800B2240, L800B231C, L800B2414, L800B24DC -.word L800B2604 - -glabel jpt_800F2DFC -.word L800B2A6C, L800B3468, L800B3468, L800B2AA4 -.word L800B2D30, L800B2F70, L800B32B4 -.word L800B32B4, L800B2F70 - -glabel jpt_800F2E20 -.word L800B4070, L800B4100 -.word L800B4230, L800B43B0, L800B4494, L800B4014 -.word L800B4024, L800B4030, L800B4040, L800B4054 -.word L800B4070, L800B4100, L800B4230, L800B43B0 - .balign 16 - -glabel D_800F2E60 -.byte 0xc0, 0x27, 0x09, 0x00 - -glabel D_800F2E64 # u8* game_name param to osPfsFindFile -.byte 0x26, 0x1a, 0x2b, 0x22, 0x28, 0x24, 0x1a, 0x2b, 0x2d, 0x16, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 - -glabel D_800F2E74 # u8* ext_name param to osPfsFindFile -.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -glabel D_800F2E80 -.float 262159.0 - -glabel jpt_800F2E84 -.word L800BA210, L800BA1E4, L800BA14C, L800BA094 -.word L800BA050 - -glabel D_800F2E98 -.float 0.001171875 - -glabel D_800F2E9C -.float 2880000.0 - -glabel D_800F2EA0 -.float 20.0304203 - -glabel D_800F2EA4 -.float 16.546 - -glabel D_800F2EA8 -.float 16.713 -.word 0x00000000 - -glabel D_800F2EB0 -.float 0.707 - -glabel D_800F2EB4 -.float 4095.999 - -glabel D_800F2EB8 -.float 1.9999599 - -glabel D_800F2EBC -.float 3.9999199 - -glabel D_800F2EC0 -.float 1.9999599 - -glabel D_800F2EC4 -.float 1.0465 - -glabel D_800F2EC8 -.float 0.52325 - -glabel D_800F2ECC -.float 0.26263 - -glabel D_800F2ED0 -.float 0.13081 - -.word 0x00000000, 0x00000000, 0x00000000 - -glabel jpt_800F2EE0 -.word L800BE60C, L800BE618, L800BE62C, L800BE638 -.word L800BE794, L800BE864, L800BE7C4, L800BE7C4 -.word L800BE844 - -glabel D_800F2F04 -.float 32767.0 - -glabel D_800F2F08 -.float 0.00001 -.word 0x00000000 - -glabel jpt_800F2F10 -.word L800BF3E8, L800BF600, L800BF600, L800BF380 -.word L800BF348, L800BF600, L800BF600, L800BF3C8 -.word L800BF308, L800BF600, L800BF600, L800BF2D0 - -glabel jpt_800F2F40 -.word L800BF408, L800BF450, L800BF4B0, L800BF478 -.word L800BF478, L800BF4C4, L800BF534, L800BF5BC -.word L800BF450, L800BF408, L800BF5C4, L800BF5F0 - -glabel D_800F2F70 -.float 16129.0 - -glabel D_800F2F74 -.float 16129.0 - -glabel D_800F2F78 -.float 16129.0 - -glabel jpt_800F2F7C -.word L800BFA20, L800BFA28, L800BFA20, L800BFA28 -.word L800BFA20 - - - - - - - - - - - - - - - - - - - - - -glabel jpt_800F2F90 -.word L800C0124, L800C0078, L800C0140, L800C0150 -.word L800C0094, L800C035C, L800C03B4, L800C03EC -.word L800C03EC, L800C0438, L800C0448, L800C03EC -.word L800BFE40, L800BFE40, L800BFE40, L800C0468 -.word L800C048C, L800C049C, L800C01E8, L800C034C -.word L800BFE40, L800BFE40, L800C02B4, L800C0298 -.word L800C0288, L800C026C, L800C0254, L800C0238 -.word L800C021C, L800C01B4, L800C0160, L800C0184 -.word L800C0304, L800C02D0, L800C0338, L800C04BC -.word L800C04AC, L800C0518, L800C0528, L800C0590 -.word L800C0630, L800BFEC4, L800C00D0, L800C0608 -.word L800BFE40, L800BFE40, L800C0640, L800C0068 -.word L800C0040, L800BFFF8, L800BFFF8, L800BFFF8 -.word L800BFFA0, L800BFF90, L800BFF48, L800BFF10 -.word L800BFFA0, L800BFFA0, L800BFFA0, L800BFED4 -.word L800BFEB4, L800C0880, L800BFE7C - -glabel jpt_800F308C -.word L800C0684, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C07E4, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0814, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0830, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0858, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C06EC, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0708, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C06BC, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C06CC, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0714, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C0760, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 -.word L800C077C - -glabel jpt_800F3350 -.word L800C0FF4, L800C0FE4, L800C0AE8, L800C0AE8 -.word L800C0FD4, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0FC4, L800C0F98, L800C0F98, L800C0F88 -.word L800C0F78, L800C0F4C, L800C0F30, L800C0F14 -.word L800C0AE8, L800C0EE8, L800C0DD4, L800C0E50 -.word L800C0D50, L800C0D50, L800C0D30, L800C0D2C -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0D1C, L800C0CF4, L800C0CAC, L800C0CAC -.word L800C0CAC, L800C0C54, L800C0AE8, L800C0C0C -.word L800C0BD4, L800C0C54, L800C0C54, L800C0C54 -.word L800C0B90, L800C0AE8, L800C0AE8, L800C0AE8 - -glabel jpt_800F3430 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C1084, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C1090, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C1098, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C10A0, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 -.word L800C0AE8 - -.word 0x00000000, 0x00000000, 0x00000000 - -glabel D_800F35C0 -.float 3.333333333 - -glabel jpt_800F35C4 -.word L800C1A34, L800C1A34, L800C1A34, L800C1A34 -.word L800C1AEC, L800C1A34 - -glabel D_800F35DC -.float 0.1 - -glabel D_800F35E0 -.float 100000.0 - -glabel D_800F35E4 -.float 100000.0 - -glabel D_800F35E8 -.float 0.85 - -glabel jpt_800F35EC -.word L800C2A80, L800C2AB8, L800C2AD8, L800C2CDC -.word L800C2E40, L800C2F04, L800C3008, L800C3118 -.word L800C3154, L800C31E4, L800C3218, L800C32B8 -.word L800C32EC, L800C3430, L800C3390, L800C33E0 - -glabel jpt_800F362C -.word L800C3DEC, L800C3E10, L800C3E30, L800C3E70 -.word L800C3E98, L800C3EBC, L800C3F04 - -glabel D_800F3648 -.float 100000.0 - -glabel jpt_800F364C -.word L800C423C, L800C4268, L800C42A4, L800C42C8 -.word L800C42FC, L800C4330 - -glabel D_800F3664 -.float 100000.0 - -glabel D_800F3668 -.float 100000.0 - -glabel D_800F366C -.float 4000000.0 - -glabel D_800F3670 -.float 10000000000.0 - -glabel D_800F3674 -.float 0.6 - -glabel D_800F3678 -.float 0.4 - -glabel D_800F367C -.float 0.005000 - -glabel D_800F3680 -.float 0.01 - -glabel D_800F3684 -.float 12000.0 - -glabel D_800F3688 -.float 0.03 - -glabel D_800F368C -.float 0.03 - -glabel D_800F3690 -.float 0.4 - -glabel jpt_800F3694 -.word L800C6544, L800C6618, L800C64E4, L800C65B8 -.word L800C65B8, L800C65B8, L800C65B8, L800C65B8 -.word L800C65B8, L800C65B8, L800C65B8, L800C65B8 -.word L800C6544, L800C6544, L800C6618, L800C6618 -.word L800C6544, L800C6618, L800C6618, L800C6618 -.word L800C6618, L800C65B8, L800C65B8, L800C65B8 -.word L800C6618, L800C6618, L800C6618, L800C6618 -.word L800C65B8, L800C65B8, L800C65B8 - -glabel D_800F3710 -.float 0.2 - -glabel D_800F3714 -.float 3500.0 - -glabel D_800F3718 -.float 3000.0 - -glabel D_800F371C -.float 0.4 - -glabel D_800F3720 -.float 0.2 - -glabel D_800F3724 -.float 0.06 - -glabel D_800F3728 -.float 0.56 - -glabel D_800F372C -.float 0.9 - -glabel D_800F3730 -.float 0.6 - -glabel D_800F3734 -.float 13000.0 - -glabel D_800F3738 -.float 0.95 - -glabel jpt_800F373C -.word L800C69C8, L800C6A0C, L800C6910, L800C6C74 -.word L800C6CB8, L800C6CFC, L800C6D40, L800C6D84 -.word L800C6DC8, L800C6E0C, L800C6E50, L800C6E94 -.word L800C6FA4, L800C6E0C, L800C6A98, L800C6ADC -.word L800C6A50, L800C6958, L800C6990, L800C6B20 -.word L800C7070, L800C6FA4, L800C6FE8, L800C702C -.word L800C6B64, L800C6BA8, L800C6BEC, L800C6C30 -.word L800C6ED8, L800C6F1C, L800C6F60 - -glabel D_800F37B8 -.float 3500.0 - -glabel jpt_800F37BC -.word L800C718C, L800C7198, L800C71B0, L800C71BC -.word L800C71A4, L800C71F4, L800C71F4, L800C71C8 -.word L800C71F4, L800C71F4, L800C71F4, L800C71F4 -.word L800C71EC, L800C71F4, L800C71D4, L800C71E0 - -glabel jpt_800F37FC -.word L800C7238, L800C7244, L800C725C, L800C7268 -.word L800C7250, L800C7294, L800C7294, L800C7274 -.word L800C7294, L800C7294, L800C7294, L800C7294 -.word L800C7290, L800C7294, L800C7280, L800C7288 - -glabel jpt_800F383C -.word L800C72F8, L800C72B8, L800C742C, L800C73B8 -.word L800C7378, L800C742C, L800C7338, L800C7428 -.word L800C742C, L800C7418, L800C7420 - -glabel jpt_800F3868 -.word L800C7494, L800C7454, L800C75C8, L800C7554 -.word L800C7514, L800C75C8, L800C74D4, L800C75C4 -.word L800C75C8, L800C75B4, L800C75BC - -glabel D_800F3894 -.float 0.7 - -glabel D_800F3898 -.float 0.1 - -glabel D_800F389C -.float 0.03 - -glabel D_800F38A0 -.float 0.16 - -glabel D_800F38A4 -.float 0.15 - -glabel D_800F38A8 -.float 0.03 - -glabel D_800F38AC -.float 0.012000 - -glabel D_800F38B0 -.float 0.85 - -glabel D_800F38B4 -.float 0.85 - -glabel jpt_800F38B8 -.word L800C9560, L800C9560, L800C95BC, L800C9618 -.word L800C9674, L800C96D0, L800C95BC, L800C96D0 - -glabel D_800F38D8 -.float 0.35 - -glabel D_800F38DC -.float 2.800000 - -glabel D_800F38E0 -.float 3844.0 - -glabel D_800F38E4 -.float -0.8 - -glabel D_800F38E8 -.float 1568.979614 - -glabel D_800F38EC -.float 1067.777832 - -glabel D_800F38F0 -.float 2766.064941 - -glabel D_800F38F4 -.float 0.6 - -glabel D_800F38F8 -.float 3.200000 - -glabel D_800F38FC -.float 3844.0 - -glabel D_800F3900 -.float -1.700000 - -glabel D_800F3904 -.float 1478.461548 - -glabel D_800F3908 -.float 784.489807 - -glabel D_800F390C -.float 12813.334961 - -glabel D_800F3910 -.float 0.6 - -glabel D_800F3914 -.float 2.800000 - -glabel D_800F3918 -.float 3844.0 - -glabel D_800F391C -.float -0.6 - -glabel D_800F3920 -.float 1747.272827 - -glabel D_800F3924 -.float 1130.588257 - -glabel D_800F3928 -.float 3844.000977 - -glabel D_800F392C -.float 0.2 - -glabel D_800F3930 -.float 3844.0 - -glabel D_800F3934 -.float -0.4 - -glabel D_800F3938 -.float 2135.555664 - -glabel D_800F393C -.float 1601.666626 - -glabel D_800F3940 -.float 3203.333008 - -glabel D_800F3944 -.float 0.4 - -glabel D_800F3948 -.float 2.400000 - -glabel D_800F394C -.float 3844.0 - -glabel D_800F3950 -.float -0.8 - -glabel D_800F3954 -.float 1922.0 - -glabel D_800F3958 -.float 1201.250000 - -glabel D_800F395C -.float 4805.0 - -glabel jpt_800F3960 -.word L800C9B3C, L800C9B3C, L800C9B68, L800C9B94 -.word L800C9BC0, L800C9BEC, L800C9B68, L800C9BEC - -glabel D_800F3980 -.float 0.35 - -glabel D_800F3984 -.float 1568.979614 - -glabel D_800F3988 -.float 0.6 - -glabel D_800F398C -.float 1478.461548 - -glabel D_800F3990 -.float 0.6 - -glabel D_800F3994 -.float 1747.272827 - -glabel D_800F3998 -.float 0.2 - -glabel D_800F399C -.float 2135.555664 - -glabel D_800F39A0 -.float 0.4 - -glabel D_800F39A4 -.float 1922.0 - -glabel D_800F39A8 -.float 0.55 - -glabel D_800F39AC -.float 0.45 - -glabel D_800F39B0 -.float 0.7 - -glabel D_800F39B4 -.float 0.1 - -.balign 16 - -glabel jpt_800F39C0 -.word L800CBE60, L800CBE78, L800CBE90, L800CBEA8 -.word L800CBEC0, L800CBECC, L800CBF08, L800CBEEC - - -# guRotateF rodata -#glabel D_800F39E0 -#.float 0.017453292 -#.balign 16 diff --git a/data/rodata_audio.s b/data/rodata_audio.s new file mode 100644 index 000000000..87aa05f73 --- /dev/null +++ b/data/rodata_audio.s @@ -0,0 +1,564 @@ +.include "macros.inc" + +.section .rodata + +# start audio data +# start heap.o +glabel D_800F2E80 +.float 262159.0 + +glabel jpt_800F2E84 +.word L800BA210, L800BA1E4, L800BA14C, L800BA094 +.word L800BA050 + +glabel D_800F2E98 +.float 0.001171875 + +glabel D_800F2E9C +.float 2880000.0 + +glabel D_800F2EA0 +.float 20.0304203 + +glabel D_800F2EA4 +.float 16.546 + +glabel D_800F2EA8 +.float 16.713 +.word 0x00000000 + +glabel D_800F2EB0 +.float 0.707 + +glabel D_800F2EB4 +.float 4095.999 + +glabel D_800F2EB8 +.float 1.9999599 + +glabel D_800F2EBC +.float 3.9999199 + +glabel D_800F2EC0 +.float 1.9999599 + +glabel D_800F2EC4 +.float 1.0465 + +glabel D_800F2EC8 +.float 0.52325 + +glabel D_800F2ECC +.float 0.26263 + +glabel D_800F2ED0 +.float 0.13081 + +.word 0x00000000, 0x00000000, 0x00000000 + +# new file audio/effects.c +glabel jpt_800F2EE0 +.word L800BE60C, L800BE618, L800BE62C, L800BE638 +.word L800BE794, L800BE864, L800BE7C4, L800BE7C4 +.word L800BE844 + +glabel D_800F2F04 +.float 32767.0 + +glabel D_800F2F08 +.float 0.00001 +.word 0x00000000 + +glabel jpt_800F2F10 +.word L800BF3E8, L800BF600, L800BF600, L800BF380 +.word L800BF348, L800BF600, L800BF600, L800BF3C8 +.word L800BF308, L800BF600, L800BF600, L800BF2D0 + +glabel jpt_800F2F40 +.word L800BF408, L800BF450, L800BF4B0, L800BF478 +.word L800BF478, L800BF4C4, L800BF534, L800BF5BC +.word L800BF450, L800BF408, L800BF5C4, L800BF5F0 + +glabel D_800F2F70 +.float 16129.0 + +glabel D_800F2F74 +.float 16129.0 + +glabel D_800F2F78 +.float 16129.0 + +glabel jpt_800F2F7C +.word L800BFA20, L800BFA28, L800BFA20, L800BFA28 +.word L800BFA20 + + + + + + + + + + + + + + + + + + + + + +glabel jpt_800F2F90 +.word L800C0124, L800C0078, L800C0140, L800C0150 +.word L800C0094, L800C035C, L800C03B4, L800C03EC +.word L800C03EC, L800C0438, L800C0448, L800C03EC +.word L800BFE40, L800BFE40, L800BFE40, L800C0468 +.word L800C048C, L800C049C, L800C01E8, L800C034C +.word L800BFE40, L800BFE40, L800C02B4, L800C0298 +.word L800C0288, L800C026C, L800C0254, L800C0238 +.word L800C021C, L800C01B4, L800C0160, L800C0184 +.word L800C0304, L800C02D0, L800C0338, L800C04BC +.word L800C04AC, L800C0518, L800C0528, L800C0590 +.word L800C0630, L800BFEC4, L800C00D0, L800C0608 +.word L800BFE40, L800BFE40, L800C0640, L800C0068 +.word L800C0040, L800BFFF8, L800BFFF8, L800BFFF8 +.word L800BFFA0, L800BFF90, L800BFF48, L800BFF10 +.word L800BFFA0, L800BFFA0, L800BFFA0, L800BFED4 +.word L800BFEB4, L800C0880, L800BFE7C + +glabel jpt_800F308C +.word L800C0684, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C07E4, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0814, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0830, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0858, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C06EC, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0708, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C06BC, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C06CC, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0714, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C0760, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800BFE40, L800BFE40, L800BFE40, L800BFE40 +.word L800C077C + +glabel jpt_800F3350 +.word L800C0FF4, L800C0FE4, L800C0AE8, L800C0AE8 +.word L800C0FD4, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0FC4, L800C0F98, L800C0F98, L800C0F88 +.word L800C0F78, L800C0F4C, L800C0F30, L800C0F14 +.word L800C0AE8, L800C0EE8, L800C0DD4, L800C0E50 +.word L800C0D50, L800C0D50, L800C0D30, L800C0D2C +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0D1C, L800C0CF4, L800C0CAC, L800C0CAC +.word L800C0CAC, L800C0C54, L800C0AE8, L800C0C0C +.word L800C0BD4, L800C0C54, L800C0C54, L800C0C54 +.word L800C0B90, L800C0AE8, L800C0AE8, L800C0AE8 + +glabel jpt_800F3430 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C1084, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C1090, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C1098, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C10A0, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8, L800C0AE8, L800C0AE8, L800C0AE8 +.word L800C0AE8 + +.word 0x00000000, 0x00000000, 0x00000000 + +glabel D_800F35C0 +.float 3.333333333 + +glabel jpt_800F35C4 +.word L800C1A34, L800C1A34, L800C1A34, L800C1A34 +.word L800C1AEC, L800C1A34 + +glabel D_800F35DC +.float 0.1 + +glabel D_800F35E0 +.float 100000.0 + +glabel D_800F35E4 +.float 100000.0 + +glabel D_800F35E8 +.float 0.85 + +glabel jpt_800F35EC +.word L800C2A80, L800C2AB8, L800C2AD8, L800C2CDC +.word L800C2E40, L800C2F04, L800C3008, L800C3118 +.word L800C3154, L800C31E4, L800C3218, L800C32B8 +.word L800C32EC, L800C3430, L800C3390, L800C33E0 + +glabel jpt_800F362C +.word L800C3DEC, L800C3E10, L800C3E30, L800C3E70 +.word L800C3E98, L800C3EBC, L800C3F04 + +glabel D_800F3648 +.float 100000.0 + +glabel jpt_800F364C +.word L800C423C, L800C4268, L800C42A4, L800C42C8 +.word L800C42FC, L800C4330 + +glabel D_800F3664 +.float 100000.0 + +glabel D_800F3668 +.float 100000.0 + +glabel D_800F366C +.float 4000000.0 + +glabel D_800F3670 +.float 10000000000.0 + +glabel D_800F3674 +.float 0.6 + +glabel D_800F3678 +.float 0.4 + +glabel D_800F367C +.float 0.005000 + +glabel D_800F3680 +.float 0.01 + +glabel D_800F3684 +.float 12000.0 + +glabel D_800F3688 +.float 0.03 + +glabel D_800F368C +.float 0.03 + +glabel D_800F3690 +.float 0.4 + +glabel jpt_800F3694 +.word L800C6544, L800C6618, L800C64E4, L800C65B8 +.word L800C65B8, L800C65B8, L800C65B8, L800C65B8 +.word L800C65B8, L800C65B8, L800C65B8, L800C65B8 +.word L800C6544, L800C6544, L800C6618, L800C6618 +.word L800C6544, L800C6618, L800C6618, L800C6618 +.word L800C6618, L800C65B8, L800C65B8, L800C65B8 +.word L800C6618, L800C6618, L800C6618, L800C6618 +.word L800C65B8, L800C65B8, L800C65B8 + +glabel D_800F3710 +.float 0.2 + +glabel D_800F3714 +.float 3500.0 + +glabel D_800F3718 +.float 3000.0 + +glabel D_800F371C +.float 0.4 + +glabel D_800F3720 +.float 0.2 + +glabel D_800F3724 +.float 0.06 + +glabel D_800F3728 +.float 0.56 + +glabel D_800F372C +.float 0.9 + +glabel D_800F3730 +.float 0.6 + +glabel D_800F3734 +.float 13000.0 + +glabel D_800F3738 +.float 0.95 + +glabel jpt_800F373C +.word L800C69C8, L800C6A0C, L800C6910, L800C6C74 +.word L800C6CB8, L800C6CFC, L800C6D40, L800C6D84 +.word L800C6DC8, L800C6E0C, L800C6E50, L800C6E94 +.word L800C6FA4, L800C6E0C, L800C6A98, L800C6ADC +.word L800C6A50, L800C6958, L800C6990, L800C6B20 +.word L800C7070, L800C6FA4, L800C6FE8, L800C702C +.word L800C6B64, L800C6BA8, L800C6BEC, L800C6C30 +.word L800C6ED8, L800C6F1C, L800C6F60 + +glabel D_800F37B8 +.float 3500.0 + +glabel jpt_800F37BC +.word L800C718C, L800C7198, L800C71B0, L800C71BC +.word L800C71A4, L800C71F4, L800C71F4, L800C71C8 +.word L800C71F4, L800C71F4, L800C71F4, L800C71F4 +.word L800C71EC, L800C71F4, L800C71D4, L800C71E0 + +glabel jpt_800F37FC +.word L800C7238, L800C7244, L800C725C, L800C7268 +.word L800C7250, L800C7294, L800C7294, L800C7274 +.word L800C7294, L800C7294, L800C7294, L800C7294 +.word L800C7290, L800C7294, L800C7280, L800C7288 + +glabel jpt_800F383C +.word L800C72F8, L800C72B8, L800C742C, L800C73B8 +.word L800C7378, L800C742C, L800C7338, L800C7428 +.word L800C742C, L800C7418, L800C7420 + +glabel jpt_800F3868 +.word L800C7494, L800C7454, L800C75C8, L800C7554 +.word L800C7514, L800C75C8, L800C74D4, L800C75C4 +.word L800C75C8, L800C75B4, L800C75BC + +glabel D_800F3894 +.float 0.7 + +glabel D_800F3898 +.float 0.1 + +glabel D_800F389C +.float 0.03 + +glabel D_800F38A0 +.float 0.16 + +glabel D_800F38A4 +.float 0.15 + +glabel D_800F38A8 +.float 0.03 + +glabel D_800F38AC +.float 0.012000 + +glabel D_800F38B0 +.float 0.85 + +glabel D_800F38B4 +.float 0.85 + +glabel jpt_800F38B8 +.word L800C9560, L800C9560, L800C95BC, L800C9618 +.word L800C9674, L800C96D0, L800C95BC, L800C96D0 + +glabel D_800F38D8 +.float 0.35 + +glabel D_800F38DC +.float 2.800000 + +glabel D_800F38E0 +.float 3844.0 + +glabel D_800F38E4 +.float -0.8 + +glabel D_800F38E8 +.float 1568.979614 + +glabel D_800F38EC +.float 1067.777832 + +glabel D_800F38F0 +.float 2766.064941 + +glabel D_800F38F4 +.float 0.6 + +glabel D_800F38F8 +.float 3.200000 + +glabel D_800F38FC +.float 3844.0 + +glabel D_800F3900 +.float -1.700000 + +glabel D_800F3904 +.float 1478.461548 + +glabel D_800F3908 +.float 784.489807 + +glabel D_800F390C +.float 12813.334961 + +glabel D_800F3910 +.float 0.6 + +glabel D_800F3914 +.float 2.800000 + +glabel D_800F3918 +.float 3844.0 + +glabel D_800F391C +.float -0.6 + +glabel D_800F3920 +.float 1747.272827 + +glabel D_800F3924 +.float 1130.588257 + +glabel D_800F3928 +.float 3844.000977 + +glabel D_800F392C +.float 0.2 + +glabel D_800F3930 +.float 3844.0 + +glabel D_800F3934 +.float -0.4 + +glabel D_800F3938 +.float 2135.555664 + +glabel D_800F393C +.float 1601.666626 + +glabel D_800F3940 +.float 3203.333008 + +glabel D_800F3944 +.float 0.4 + +glabel D_800F3948 +.float 2.400000 + +glabel D_800F394C +.float 3844.0 + +glabel D_800F3950 +.float -0.8 + +glabel D_800F3954 +.float 1922.0 + +glabel D_800F3958 +.float 1201.250000 + +glabel D_800F395C +.float 4805.0 + +glabel jpt_800F3960 +.word L800C9B3C, L800C9B3C, L800C9B68, L800C9B94 +.word L800C9BC0, L800C9BEC, L800C9B68, L800C9BEC + +glabel D_800F3980 +.float 0.35 + +glabel D_800F3984 +.float 1568.979614 + +glabel D_800F3988 +.float 0.6 + +glabel D_800F398C +.float 1478.461548 + +glabel D_800F3990 +.float 0.6 + +glabel D_800F3994 +.float 1747.272827 + +glabel D_800F3998 +.float 0.2 + +glabel D_800F399C +.float 2135.555664 + +glabel D_800F39A0 +.float 0.4 + +glabel D_800F39A4 +.float 1922.0 + +glabel D_800F39A8 +.float 0.55 + +glabel D_800F39AC +.float 0.45 + +glabel D_800F39B0 +.float 0.7 + +glabel D_800F39B4 +.float 0.1 + +.balign 16 + +glabel jpt_800F39C0 +.word L800CBE60, L800CBE78, L800CBE90, L800CBEA8 +.word L800CBEC0, L800CBECC, L800CBF08, L800CBEEC + + +# guRotateF rodata +#glabel D_800F39E0 +#.float 0.017453292 +#.balign 16 diff --git a/include/macros.h b/include/macros.h index 9132d668c..39dcefd7b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -62,6 +62,6 @@ #define VIRTUAL_TO_PHYSICAL2(addr) ((u8 *)(addr) - 0x80000000U) // aligns an address to the next 16 bytes -#define ALIGN16(x) (((x) + 0xF) & -0x10) +#define ALIGN16(val) (((val) + 0xF) & ~0xF) #endif diff --git a/include/variables.h b/include/variables.h index f100a6503..f4aaa3f05 100644 --- a/include/variables.h +++ b/include/variables.h @@ -18,7 +18,7 @@ extern f32 gCourseCompletionPercentByPlayerId[8]; // D_801644D0 extern f32 gCourseCompletionPercentByRank[8]; // D_80162FD8 extern s8 gCourseRecordsMenuSelection; // D_8018EDF8 extern f32 gCourseTimer; // D_800DC598 -extern s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; // D_800F2BB4 +extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; // D_800F2BB4 extern s8 gCupCourseSelection; // D_8018EE0B extern char *gCupNames[]; // D_800E7500 extern s8 gCupSelection; // D_8018EE09 diff --git a/mk64.ld b/mk64.ld index 03253ce7b..fb46da980 100644 --- a/mk64.ld +++ b/mk64.ld @@ -87,7 +87,9 @@ SECTIONS BUILD_DIR/src/code_80086E70.o(.text); BUILD_DIR/src/code_8008C1D0.o(.text); BUILD_DIR/src/code_80091750.o(.text); + BUILD_DIR/src/code_800AF9B0.o(.text); BUILD_DIR/src/menus.o(.text); + BUILD_DIR/src/code_800B45E0.o(.text); BUILD_DIR/src/audio/synthesis.o(.text); BUILD_DIR/src/audio/heap.o(.text); BUILD_DIR/src/audio/load.o(.text); @@ -253,6 +255,10 @@ SECTIONS BUILD_DIR/data/data_0DD0A0_3_0_1.o(.rodata); BUILD_DIR/src/code_80057C60.o(.rodata); BUILD_DIR/data/data_0DD0A0_3_0.o(.rodata); + BUILD_DIR/src/code_800AF9B0.o(.rodata); + BUILD_DIR/src/menus.o(.rodata); + BUILD_DIR/src/code_800B45E0.o(.rodata); + BUILD_DIR/data/rodata_audio.o(.rodata); BUILD_DIR/src/os/guRotateF.o(.rodata); BUILD_DIR/src/os/guPerspectiveF.o(.rodata); BUILD_DIR/data/data_0DD0A0_3_1.o(.rodata); @@ -280,6 +286,8 @@ SECTIONS BUILD_DIR/asm/bss_MainSeg.o(.bss); BUILD_DIR/src/camera.o(.bss); BUILD_DIR/asm/bss_8001C4D0.o(.bss); + BUILD_DIR/src/code_800AF9B0.o(.bss); + BUILD_DIR/asm/bss_8018EDC0.o(.bss); BUILD_DIR/src/os/osCreateViManager.o(.bss); BUILD_DIR/src/os/osCreatePiManager.o(.bss); BUILD_DIR/src/os/osSetEventMesg.o(.bss); diff --git a/progress.py b/progress.py index cdc88a6a7..8dabb472f 100644 --- a/progress.py +++ b/progress.py @@ -74,7 +74,7 @@ mainSegFiles2 = [ "asm/non_matchings/code_80057C60", "asm/non_matchings/code_8006E9C0", "asm/non_matchings/code_80071F00", "asm/non_matchings/code_80086E70", "asm/non_matchings/code_8008C1D0", "asm/non_matchings/code_80091750", - "asm/non_matchings/code_800AF9B0" + "asm/non_matchings/menus" ] seg2Files2 = [ "asm/non_matchings/code_8028DF00", "asm/non_matchings/code_80290C20", diff --git a/src/audio/external.h b/src/audio/external.h index ccb4f86c6..7adcfa842 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -3,10 +3,13 @@ #include "common_structs.h" +void play_sound2(s32); void func_800CA0A0(); void func_800CA0B8(); void func_800CA0CC(); void func_800CA270(); +void func_800CA330(s32); +void func_800CA388(s32); void func_800CB134(); extern s8 D_800EA0F4; diff --git a/src/code_800029B0.c b/src/code_800029B0.c index 5860c69a8..61a90297f 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -47,7 +47,6 @@ extern u32 D_8015F730; extern u32 D_8015F734; extern u32 gPrevLoadedAddress; extern s32 D_80150120; -extern s16 gCupCourseOrder[][4]; void func_800CA008(u8, u8); diff --git a/src/code_80005FD0.h b/src/code_80005FD0.h index a0787d98f..1255f5a00 100644 --- a/src/code_80005FD0.h +++ b/src/code_80005FD0.h @@ -6,6 +6,7 @@ /* Function Prototypes */ s16 func_80005FD0(); +void func_8001968C(void); // math_util.c u32 func_802B5224(); diff --git a/src/code_80091750.c b/src/code_80091750.c index cf438fbd3..053a94e28 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -1,15 +1,22 @@ #include #include #include + #include "code_80091750.h" + +#include "code_80005FD0.h" #include "menus.h" +#include "code_800B45E0.h" +#include "code_80057C60.h" #include "credits_01.h" #include "data_segment2.h" +#include "code_800AF9B0.h" #include "variables.h" // TODO: Move gGfxPool out of main.h // Unfortunately that's not a small effort due to weird import structure in this project #include "main.h" + f64 exponent_by_squaring(f64 base, s32 exponent) { s32 positive_exponent; f64 result; @@ -848,8 +855,8 @@ s32 char_to_glyph_index(char *character) { GLOBAL_ASM("asm/non_matchings/code_80091750/char_to_glyph_index.s") #endif -s32 func_80092DF8(void) { - return func_80092E1C() + 0x50; +s32 func_80092DF8(s8 *arg) { + return func_80092E1C(arg) + 0x50; } #ifdef MIPS_TO_C diff --git a/src/code_80091750.h b/src/code_80091750.h index b18533bb6..b5d9d6109 100644 --- a/src/code_80091750.h +++ b/src/code_80091750.h @@ -68,7 +68,9 @@ void func_80092630(); void func_8009265C(); void func_80092C80(); s32 char_to_glyph_index(char*); -s32 func_80092DF8(); +s32 func_80092DF8(s8 *); +s32 func_80092E1C(s8 *); +s32 func_80092EE4(s8 *); s32 get_string_width(char*); void set_text_color(s32); void func_800930E4(s32, s32, s32*); @@ -113,6 +115,7 @@ void func_8009CA2C(); void func_8009CA6C(s32); void func_80099A94(MkTexture *, s32); void func_80099AEC(); +void func_8009E1E4(void); void func_80099E54(); void func_80099E60(MkTexture *, s32, s32); void func_80099EC4(); diff --git a/src/code_800AF9B0.c b/src/code_800AF9B0.c new file mode 100644 index 000000000..308bfb751 --- /dev/null +++ b/src/code_800AF9B0.c @@ -0,0 +1,239 @@ +#include +#include +#include +#include "global.h" + +#include "code_800AF9B0.h" + +#include "code_80091750.h" +#include "memory.h" +#include "main.h" +#include "math_util.h" + +extern Light D_800E8680; +extern Light D_800E8688; + +/* BSS */ +s16 D_8018EDB0; +s16 D_8018EDB2; +s16 D_8018EDB4; +Vtx *D_8018EDB8; +Vtx *D_8018EDBC; + +/* utils */ +#define SQ(x) ((x) * (x)) + +void func_800AF9B0(void) { + D_8018EDB8 = (void *)func_802A7B70(480 * sizeof(Vtx)); + D_8018EDBC = (void *)func_802A7B70(480 * sizeof(Vtx)); +} + +// could be a normal vertex, not a color... +void func_800AF9E4(Vtx *arg0, s32 arg1, s32 arg2, s32 arg3, s16 arg4, s16 arg5, s32 arg6, s32 arg7) { + s32 r, g, b; + s32 i; + + for (i = 0; i < 4; i++) { + (arg0 + i)->v.ob[0] = ((i % 2) * arg7) + arg6 - 504; + if (i / 2 == 0) { + (arg0 + i)->v.ob[1] = (arg2 * arg3) - 420; + } else { + (arg0 + i)->v.ob[1] = (arg2 * arg3) + arg3 - 420; + } + if (i % 2 == 0) { + (arg0 + i)->v.ob[1] += (f32)SQ(arg1) * -0.07f; + } else { + (arg0 + i)->v.ob[1] += (f32)SQ(arg1 + 1) * -0.07f; + } + + (arg0 + i)->v.cn[0] = 0; + (arg0 + i)->v.cn[1] = 0; + (arg0 + i)->v.cn[2] = 120; + (arg0 + i)->v.cn[3] = 255; + + if (i % 2 == 0) { + (arg0 + i)->v.ob[2] = arg4; + } else { + (arg0 + i)->v.ob[2] = arg5; + } + } + + if ((((arg1 / 2) + (arg2 / 2)) & 1) == 0) { + r = g = b = 0; + } else { + r = g = b = 255; + } + + gDPSetPrimColor(gDisplayListHead++, 0, 0, r, g, b, 255); + gDPPipeSync(gDisplayListHead++); + gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL2(arg0), 4, 0); + gSP1Triangle(gDisplayListHead++, 1, 2, 0, 0); + gSP1Triangle(gDisplayListHead++, 3, 2, 1, 0); +} + +void func_800AFC54(Vtx *arg0, s32 arg1, s32 arg2, s32 arg3, s16 arg4[3]); +#ifdef NON_MATCHING +// guess on Vtx type? +void func_800AFC54(Vtx *arg0, s32 arg1, s32 arg2, s32 arg3, s16 arg4[3]) { + Vtx *a1, *a2, *a3; + s32 saved1, saved2, saved3; + f32 res; + s32 a, b, c, d, e, f; + f32 f14, f16, f18; + + a1 = &arg0[arg1]; + a2 = &arg0[arg2]; + a3 = &arg0[arg3]; + + saved1 = a2->v.ob[0]; + saved2 = a2->v.ob[1]; + saved3 = a2->v.ob[2]; + + + a = saved2 - a1->v.ob[1]; + e = saved3 - a1->v.ob[2]; + d = a3->v.ob[1] - saved2; + b = a3->v.ob[2] - saved3; + f = a3->v.ob[0] - saved1; + c = saved1 - a1->v.ob[0]; + + + f14 = ((a) * (b)) - ((e) * (d)); + f16 = ((e) * (f)) - ((c) * (b)); + f18 = ((c) * (d)) - ((a) * (f)); + + + res = sqrtf(SQ(f14) + SQ(f16) + SQ(f18)); + + if (res < 0.001) { + res = 0.001; + } + + arg4[0] = f14 * (f32)(1.0 / res) * 120.0f; + arg4[1] = f16 * (f32)(1.0 / res) * 120.0f; + arg4[2] = f18 * (f32)(1.0 / res) * 120.0f; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800AFC54.s") +#endif + +void func_800AFE00(Vtx *arg0, s16 (*arg1)[3], s32 arg2, s32 arg3); +#ifdef MIPS_TO_C +// guessing on the Vtx kind again +void func_800AFE00(Vtx *arg0, s16 (*arg1)[3], s32 arg2, s32 arg3) { + s32 idx1; // v0 + s32 idx2; // v0 + s16 sp14[6]; + Vtx *sec, *third, *fourth; + s32 i; + + if (arg2 == 0) { + idx1 = 0; + } else { + idx1 = arg2 - 1; + } + + if (arg2 == arg3) { + idx2 = arg3; + } else { + idx2 = arg2 + 1; + } + + for (i = 0; i < 3; i++) { + sp14[i + 0] = (arg1[arg2][i] + arg1[idx1][i]) / 2; + sp14[i + 3] = (arg1[arg2][i] + arg1[idx2][i]) / 2; + // L800AFEB4 + } + + + i = 0; + sec = arg0 + 1; + third = arg0 + 2; + fourth = arg0 + 3; + + while (i != 480) { + (arg0 + i)->v.cn[0] = sp14[0]; + (arg0 + i)->v.cn[1] = sp14[1]; + (arg0 + i)->v.cn[2] = sp14[2]; + (sec + i)->v.cn[0] = sp14[3]; + (sec + i)->v.cn[1] = sp14[4]; + (sec + i)->v.cn[2] = sp14[5]; + (third + i)->v.cn[0] = sp14[0]; + (third + i)->v.cn[1] = sp14[1]; + (third + i)->v.cn[2] = sp14[2]; + (fourth + i)->v.cn[0] = sp14[3]; + (fourth + i)->v.cn[1] = sp14[4]; + (fourth + i)->v.cn[2] = sp14[5]; + + i += 3 * sizeof(Vtx); + i++;i--; + } +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800AFE00.s") +#endif + +void func_800AFF58(Vtx *arg0) { + UNUSED u32 pad88[26]; + s32 i, j; + s16 sp40[12][3]; + + for (i = 0, j = 0; i < ARRAY_COUNT(sp40); i++, j += 4) { + func_800AFC54(&arg0[j], 1, 2, 0, sp40[i]); + } + + for (i = 0, j = 0; i < ARRAY_COUNT(sp40); i++, j += 4) { + func_800AFE00(&arg0[j], sp40, i, 11); + } +} + +#ifdef NON_MATCHING +void func_800B0004(void) { + s32 i, j; + Vtx *spBC; + UNUSED u32 pad[0x10]; + u32 sp64; // offset? + + gSPLight(gDisplayListHead++, VIRTUAL_TO_PHYSICAL2(&D_800E8688), LIGHT_1); + gSPLight(gDisplayListHead++, VIRTUAL_TO_PHYSICAL2(&D_800E8680), LIGHT_2); + gSPNumLights(gDisplayListHead++, NUMLIGHTS_1); + gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH); + gDPSetCombineLERP(gDisplayListHead++, PRIMITIVE, 0, SHADE, 0, 0, 0, 0, SHADE, PRIMITIVE, 0, SHADE, 0, 0, 0, 0, SHADE); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING); + + spBC = D_8018EDB4 % 2 ? (void *)D_8018EDB8 : (void *)D_8018EDBC; + + D_8018EDB2 = 0x9C0; + + for (i = 0, sp64 = 0; i < 10; i++, sp64 += 0x30) { + // L800B018C + for (j = 0; j < 12; j++) { + f32 res1, res2; + // L800B01A0 + res1 = sins((u16)(D_8018EDB0 - (j * D_8018EDB2))) * 84.0f * (f32)j * 0.18f; + res2 = sins((u16)(D_8018EDB0 - ((j+1) * D_8018EDB2))) * 84.0f * (f32)(j+1) * 0.18f; + func_800AF9E4( + spBC + j + sp64, + j, + i, + 84, + res1, + res2, + j * 84, + 84 + ); + } + } + // will probably have to retype this function + func_800AFF58((void *)spBC); + D_8018EDB0 += D_8018EDB2; + D_8018EDB4 += 1; + + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gSPNumLights(gDisplayListHead++, NUMLIGHTS_1); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B0004.s") +#endif diff --git a/src/code_800AF9B0.h b/src/code_800AF9B0.h new file mode 100644 index 000000000..a5bff659b --- /dev/null +++ b/src/code_800AF9B0.h @@ -0,0 +1,22 @@ +#ifndef CODE_800AF9B0_H +#define CODE_800AF9B0_H + +#include "common_structs.h" +#include + +/* Function Prototypes */ +void func_800AF9B0(void); +void func_800B0004(void); + +/* This is where I'd put my static data, if I had any */ + +extern s32 gCCSelection; // D_800DC538 in main.c +extern s32 gModeSelection; // D_800DC53C +extern s32 D_800DC540; +extern s16 gCurrentCourseId; // D_800DC5A0 +extern s32 gIsMirrorMode; // D_800DC5F4 +extern s32 D_800E86A4; +extern s8 gDisplayedControllerPakTableRows[5]; // D_800E86C6 +extern s32 D_800E86E4; + +#endif /* CODE_800AF9B0_H */ diff --git a/src/code_800B45E0.c b/src/code_800B45E0.c new file mode 100644 index 000000000..e436ddb8e --- /dev/null +++ b/src/code_800B45E0.c @@ -0,0 +1,1514 @@ +#include +#include +#include +#include "global.h" + +#include "code_800B45E0.h" + +#include "code_80091750.h" +#include "menus.h" +#include "staff_ghosts.h" + +// rodata +const u8 D_800F2E60[4] = {0xc0, 0x27, 0x09, 0x00}; +// game_name param to osPfsFindFile +const char D_800F2E64[] = {0x26, 0x1a, 0x2b, 0x22, 0x28, 0x24, 0x1a, 0x2b, 0x2d, 0x16, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00}; +// ext_name param to osPfsFindFile +const char D_800F2E74[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +// new file start? +void func_800B45E0(s32 arg0) { + CourseTimeTrialRecords* courseTimeTrialRecordsPtr = &D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[arg0 / 4] \ + .courseRecords[arg0 % 4]; + + courseTimeTrialRecordsPtr->unknownBytes[5] = func_800B4874(arg0); + osEepromLongWrite(&gSIEventMesgQueue, ((u32)courseTimeTrialRecordsPtr - (u32)&D_8018EB90) >> 3, (u8*) courseTimeTrialRecordsPtr, sizeof(CourseTimeTrialRecords)); +} + +void write_save_data_grand_prix_points_and_sound_mode(void) { + D_8018ED16 = compute_save_data_checksum_1(); + D_8018ED17 = compute_save_data_checksum_2(); + osEepromLongWrite(&gSIEventMesgQueue, (((u32)&D_8018ED10 - (u32)&D_8018EB90) >> 3), (u8*) &D_8018ED10, 8); +} + +void func_800B46D0(void) { + s32 temp_s0; + s32 phi_s0; + + phi_s0 = 0; + do { + func_800B4728(phi_s0); + func_800B559C(phi_s0); + temp_s0 = phi_s0 + 1; + phi_s0 = temp_s0; + } while (phi_s0 != 0x10); + reset_save_data_grand_prix_points_and_sound_mode(); + update_save_data_backup(); +} + +void func_800B4728(s32 arg0) { + s32 temp_a2; + s32 temp_v0; + CourseTimeTrialRecords* courseTimeTrialRecords; + + courseTimeTrialRecords = &D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[arg0 / 4] \ + .courseRecords[arg0 % 4]; + + for (temp_a2 = 0; temp_a2 < 5; ++temp_a2) + { + for (temp_v0 = 0; temp_v0 < 3; ++temp_v0) + { + courseTimeTrialRecords->records[temp_a2][temp_v0] = D_800F2E60[temp_v0]; + } + } + + for (temp_a2 = 0; temp_a2 < 3; ++temp_a2) + { + courseTimeTrialRecords->records[5][temp_a2] = D_800F2E60[temp_a2]; + } + + courseTimeTrialRecords->unknownBytes[0] = 0; + courseTimeTrialRecords->unknownBytes[5] = func_800B4874(arg0); + func_800B45E0(arg0); +} + +void reset_save_data_grand_prix_points_and_sound_mode(void) { + D_8018ED10.grandPrixPointsMushroomCup = 0; + D_8018ED11 = 0; + D_8018ED12 = 0; + D_8018ED13 = 0; + gSaveDataSoundMode = SOUND_STEREO; + gSoundMode = SOUND_STEREO; + func_800B44BC(); + write_save_data_grand_prix_points_and_sound_mode(); +} + +s32 func_800B4874(s32 arg0) { + s32 temp_a0; + s32 temp_a1; + s32 temp_v1; + u8* records = &D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[arg0 / 4] \ + .courseRecords[arg0 % 4] \ + .records[0][0]; + + temp_v1 = 0; + temp_a1 = 0; + while (temp_a1 < 7) + { + temp_a0 = 0; + while (temp_a0 < 3) + { + temp_v1 += (*((records + 3*temp_a1 + temp_a0)) * (temp_a0 + 1)) + temp_a1; + ++temp_a0; + } + ++temp_a1; + } + + return (temp_v1 % 256) & 0xFF; +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern union GrandPrixPointsUnion D_8018ED10; + +s32 compute_save_data_checksum_1(void) { + void *temp_a0; + + temp_a0 = &D_8018ED10 + 1; + return ((D_8018ED10.grandPrixPointsMushroomCup + 1 + ((temp_a0->unk0 + 1) * 2) + 1 + ((temp_a0->unk1 + 1) * 3) + 1 + 1 + ((temp_a0->unk2 + 1) * 4) + 1 + 2 + ((temp_a0->unk3 + 1) * 5) + 1 + 3) % 0x100) & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B492C.s") +#endif + +s32 compute_save_data_checksum_2(void) { + s32 tmp = D_8018ED16 + 90; + return (tmp % 256) & 0xFF; +} + +void load_save_data(void) { + s32 temp_s0; + + osEepromLongRead(&gSIEventMesgQueue, 0, (u8*) &D_8018EB90, sizeof(SaveData)); + temp_s0 = 0; + while (temp_s0 < 16) // 16: 4 cup records * 4 course records? + { + func_800B4A9C(temp_s0); + ++temp_s0; + } + + validate_save_data(); + + gSoundMode = gSaveDataSoundMode; + if (gSoundMode >= NUM_SOUND_MODES) { + gSoundMode = SOUND_MONO; + } +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +? func_800B45E0(s32, u8 *, u8, s32); // extern +? func_800B4728(s32); // extern +s32 func_800B4874(s32); // extern +s32 func_800B4EB4(?, s32); // extern +? func_800B4FB0(s32); // extern +? func_800B559C(s32); // extern +s32 func_800B58C4(s32); // extern +extern u8 D_800F2E60; +extern ? D_8018EB90; +extern ? D_8018EBA2; + +void func_800B4A9C(s32 arg0) { + void *sp24; + s32 temp_v1; + u8 *temp_a1; + u8 temp_a2; + u8 temp_t6; + u8 temp_t8; + void *temp_a0; + void *temp_t2; + void *temp_v0; + s32 phi_v1; + u8 *phi_a1; + s32 phi_a3; + s32 phi_a3_2; + + if ((func_800B4EB4(0, arg0) & 0xFFFFF) < MAX_TIME) { + *(&D_8018EBA2 + (((arg0 / 4) * 0x60) + ((arg0 % 4) * 0x18))) = 1; + } + temp_t2 = ((arg0 / 4) * 0x60) + ((arg0 % 4) * 0x18) + &D_8018EB90; + sp24 = temp_t2; + func_800B4FB0(arg0); + sp24 = temp_t2; + if (temp_t2->unk17 != func_800B4874(arg0)) { + sp24 = temp_t2; + func_800B4728(arg0); + if (func_800B58C4(arg0) == 0) { + phi_v1 = 0; + phi_a1 = &D_800F2E60; + phi_a3_2 = 0; + do { + temp_v0 = ((arg0 / 8) * 0x38) + ((arg0 % 8) * 3) + 0x188 + &D_8018EB90 + phi_v1; + temp_t6 = temp_v0->unk0; + temp_a0 = temp_t2 + phi_v1; + temp_v1 = phi_v1 + 1; + temp_a0->unk0 = temp_t6; + temp_t8 = temp_v0->unk18; + temp_a0->unkF = temp_t8; + temp_a2 = *phi_a1; + phi_v1 = temp_v1; + phi_a3 = phi_a3_2; + if (((temp_t6 & 0xFF) == temp_a2) && ((temp_t8 & 0xFF) == temp_a2)) { + phi_a3 = phi_a3_2 + 1; + } + temp_a1 = phi_a1 + 1; + phi_a1 = temp_a1; + phi_a3_2 = phi_a3; + } while (temp_v1 != 3); + if (phi_a3 == 3) { + temp_t2->unk12 = 0; + } else { + temp_t2->unk12 = 1; + } + func_800B45E0(arg0, temp_a1, temp_a2, phi_a3); + } + func_800B559C(arg0); + return; + } + if (func_800B58C4(arg0) != 0) { + func_800B559C(arg0); + } +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B4A9C.s") +#endif + +void validate_save_data(void) { + if ((D_8018ED16 != (compute_save_data_checksum_1() & 0xFFFFFFFF)) || (D_8018ED17 != (compute_save_data_checksum_2() & 0xFFFFFFFF))) { + + reset_save_data_grand_prix_points_and_sound_mode(); + + if (validate_save_data_checksum_backup() == 0) { + D_8018ED10.grandPrixPointsMushroomCup = D_8018ED88.grandPrixPointsMushroomCup; + if ((D_8018ED16 && D_8018ED16) && D_8018ED16) + { + } + + D_8018ED11 = D_8018ED89; + if ((D_8018ED16 && D_8018ED16) && D_8018ED16) + { + } + + D_8018ED12 = D_8018ED8A; + if ((D_8018ED16 && D_8018ED16) && D_8018ED16) + { + } + + D_8018ED13 = D_8018ED8B; + if ((D_8018ED16 && D_8018ED16) && D_8018ED16) + { + } + + gSaveDataSoundMode = gSaveDataSoundModeBackup; + D_8018ED16 = compute_save_data_checksum_backup_1(); + D_8018ED17 = compute_save_data_checksum_backup_2(); + osEepromLongWrite(&gSIEventMesgQueue, (((u32) &D_8018ED10 - (u32) &D_8018EB90) >> 3), (u8*) &D_8018ED10, 8); + } + update_save_data_backup(); + return; + } + + if (validate_save_data_checksum_backup() != 0) { + update_save_data_backup(); + } +} + +void populate_time_trial_record(u8 *timeTrialRecord, u32 time, s32 characterId) +{ + u32 timeRightShift8 = time >> 8; + u32 timeRightShift16 = timeRightShift8 >> 8; + s16 timeRightShift8Duplicate; + u16 timeRightShift16Duplicate; + + timeRightShift16Duplicate = timeRightShift16; + + timeTrialRecord[0] = time & 0xFF; + timeTrialRecord[1] = (timeRightShift8Duplicate = timeRightShift8); + timeTrialRecord[2] = (timeRightShift16Duplicate & 0xF) + ((characterId & 7) << 4); +} + +#ifdef NON_MATCHING +//generated by mips_to_c commit 99fec197b8c557ea7cc0d78f1b263a0de6e59168 +s32 func_800B4DF4(u8 *arg0) { + return ((arg0[1] << 8) + arg0[0] + (arg0[2] << 0x10)) & 0xFFFFFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B4DF4.s") +#endif + +// Get a time trial record, infer course index +s32 func_800B4E24(s32 recordIndex) { + return func_800B4DF4( + D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[(((gCupSelection * 4) + gCupCourseSelection) / 4)] \ + .courseRecords[(((gCupSelection * 4) + gCupCourseSelection) % 4)] \ + .records[recordIndex] + ); +} + +// Get a time trial record, but take the course index as an argument +s32 func_800B4EB4(s32 recordIndex, s32 courseIndex) { + return func_800B4DF4( + D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[(courseIndex / 4)] \ + .courseRecords[(courseIndex % 4)] \ + .records[recordIndex] + ); +} + +// Get Best Lap record of the inferred course index +s32 func_800B4F2C(void) { + return func_800B4DF4( + D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[(((gCupSelection * 4) + gCupCourseSelection) / 4)] \ + .courseRecords[(((gCupSelection * 4) + gCupCourseSelection) % 4)] \ + .records[TIME_TRIAL_1LAP_RECORD] + ); +} + +// Get the best single lap time record of the given course index +s32 func_800B4FB0(s32 courseIndex) { + return func_800B4DF4( + D_8018EB90.allCourseTimeTrialRecords \ + .cupRecords[(courseIndex / 4)] \ + .courseRecords[(courseIndex % 4)] \ + .records[TIME_TRIAL_1LAP_RECORD] + ); +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +? func_800B45E0(s32); // extern +? populate_time_trial_record(void *, u32, s32, void *); // extern +s32 func_800B4DF4(void *); // extern +extern ? D_8018EB90; +extern s8 gCupSelection; + +s32 func_800B5020(u32 arg0, s32 arg1) { + s32 sp30; + s32 temp_a0; + s32 temp_s0; + s32 temp_s1; + s32 temp_v0; + s32 temp_v0_2; + s32 temp_v1; + u8 temp_t3; + u8 temp_t8; + u8 temp_t9; + void *temp_a3; + void *temp_s2; + void *temp_v0_3; + void *temp_v0_4; + s32 phi_s0; + s32 phi_s1; + s32 phi_s1_2; + s32 phi_v1; + s32 phi_a0; + s32 phi_v1_2; + s32 phi_s0_2; + s32 phi_a0_2; + + temp_v0 = (gCupSelection * 4) + gCupCourseSelection; + temp_s2 = ((temp_v0 / 4) * 0x60) + ((temp_v0 % 4) * 0x18) + &D_8018EB90; + sp30 = temp_v0; + phi_s0 = 0; + phi_s1 = 0; +loop_1: + phi_s1_2 = phi_s1; + phi_s0_2 = phi_s0; + if (arg0 >= (func_800B4DF4(temp_s2 + phi_s0) & 0xFFFFF)) { + temp_s1 = phi_s1 + 1; + temp_s0 = phi_s0 + 3; + phi_s0 = temp_s0; + phi_s1 = temp_s1; + phi_s1_2 = temp_s1; + phi_s0_2 = temp_s0; + if (temp_s1 != 5) { + goto loop_1; + } + } + phi_a0 = 4; + phi_a0_2 = 4; + if (phi_s1_2 >= 5) { + return -1; + } + temp_a3 = temp_s2 + phi_s0_2; + if (phi_s1_2 < 4) { + temp_v0_2 = -((4 - phi_s1_2) & 3); + if (temp_v0_2 != 0) { + phi_v1 = 4 * 3; + do { + temp_v0_3 = temp_s2 + phi_v1; + temp_a0 = phi_a0 - 1; + temp_v0_3->unk0 = temp_v0_3->unk-3; + temp_v0_3->unk1 = temp_v0_3->unk-2; + temp_v0_3->unk2 = temp_v0_3->unk-1; + phi_v1 += -3; + phi_a0 = temp_a0; + phi_a0_2 = temp_a0; + } while ((temp_v0_2 + 4) != temp_a0); + if (phi_s1_2 != temp_a0) { + goto block_10; + } + } else { +block_10: + phi_v1_2 = phi_a0_2 * 3; + do { + temp_v0_4 = temp_s2 + phi_v1_2; + temp_v0_4->unk0 = temp_v0_4->unk-3; + temp_v0_4->unk1 = temp_v0_4->unk-2; + temp_t8 = temp_v0_4->unk-8; + temp_t9 = temp_v0_4->unk-7; + temp_t3 = temp_v0_4->unk-1; + temp_v1 = phi_v1_2 - 0xC; + temp_v0_4->unk-3 = temp_v0_4->unk-6; + temp_v0_4->unk-7 = temp_v0_4->unk-A; + temp_v0_4->unk-8 = temp_v0_4->unk-B; + temp_v0_4->unk-2 = temp_v0_4->unk-5; + temp_v0_4->unk-1 = temp_v0_4->unk-4; + temp_v0_4->unk-6 = temp_v0_4->unk-9; + temp_v0_4->unk-5 = temp_t8; + temp_v0_4->unk-4 = temp_t9; + temp_v0_4->unk-9 = temp_v0_4->unk-C; + temp_v0_4->unk2 = temp_t3; + phi_v1_2 = temp_v1; + } while ((phi_s1_2 * 3) != temp_v1); + } + } + populate_time_trial_record(temp_a3, arg0, arg1, temp_a3); + temp_s2->unk12 = 1; + func_800B45E0(sp30); + return phi_s1_2; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B5020.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 792017ad9d422c2467bd42686f383a5c41f41c75 +? populate_time_trial_record(u8 *, u32, s32, s32); /* extern */ +extern ? D_8018CA74; +s8 gCharacterSelections[4]; /* unable to generate initializer; const */ + +s32 func_800B5218(void) { + s32 sp38; + s32 sp28; + s32 sp24; + u8 *sp20; + struct_8018CA70_entry *sp18; + ? *temp_a1; + s32 temp_a0; + s32 temp_v0; + s32 temp_v1; + u32 temp_a1_2; + u8 *temp_v0_2; + ? *phi_a1; + struct_8018CA70_entry *phi_a2; + s32 phi_v0; + struct_8018CA70_entry *phi_a2_2; + s32 phi_a3; + s32 phi_v0_2; + s32 phi_a3_2; + + sp38 = (gCupSelection * 4) + gCupCourseSelection; + sp28 = (s32) *gCharacterSelections; + phi_a1 = &D_8018CA74; + phi_a2 = D_8018CA70; + phi_v0 = 1; + phi_a3_2 = 1; + do { + temp_v1 = phi_a1->unk20; + temp_a0 = phi_a2->lap1Duration; + phi_a2_2 = phi_a2; + phi_a3 = phi_a3_2; + if (temp_v1 < temp_a0) { + phi_a2_2 = (phi_v0 * 4) + D_8018CA70; + phi_a3 = 1 << phi_v0; + } else if (temp_a0 == temp_v1) { + phi_a3 = phi_a3_2 | (1 << phi_v0); + } + temp_v0 = phi_v0 + 1; + temp_a1 = phi_a1 + 4; + phi_a1 = temp_a1; + phi_a2 = phi_a2_2; + phi_v0 = temp_v0; + phi_a3_2 = phi_a3; + } while (temp_v0 != 3); + sp18 = phi_a2_2; + sp24 = phi_a3; + temp_a1_2 = phi_a2_2->lap1Duration; + phi_v0_2 = 0; + if (temp_a1_2 < (u32) (func_800B4F2C(temp_a0, temp_a1, phi_a2_2, phi_a3) & 0xFFFFF)) { + temp_v0_2 = &D_8018EB90.allCourseTimeTrialRecords.cupRecords[sp38].courseRecords[sp38].records[0]; + sp20 = temp_v0_2; + sp24 = phi_a3; + populate_time_trial_record(temp_v0_2 + 0xF, temp_a1_2, sp28, phi_a3); + temp_v0_2->unk12 = 1; + func_800B45E0(sp38); + phi_v0_2 = sp24; + } + return phi_v0_2; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B5218.s") +#endif + +void func_800B536C(s32 arg0) { + u8* points; + u8 tmp; + s32 tmp2; + + if (arg0 >= 0) { + points = &D_8018EB90.grandPrixPoints[gCCSelection]; + + tmp = func_800B54EC(gCupSelection, *points); + tmp2 = 3 - arg0; + if ((arg0 < 3) && (tmp < (3-arg0))) { + *points = func_800B5508(gCupSelection, *points, tmp2); + write_save_data_grand_prix_points_and_sound_mode(); + update_save_data_backup(); + } + } +} + +void func_800B5404(s32 arg0, s32 arg1) +{ + u8 *points; + s32 temp_a0; + s32 temp; + int temp2; + UNUSED s32 pad; + + if (arg0 >= 0) { + temp2 = arg1 / 4; + points = &D_8018EB90.grandPrixPoints[arg1 % 4]; + temp = func_800B54EC(temp2, *points); + + if ((arg0 < 3) && (temp < (temp_a0 = 3 - arg0))) { + *points = func_800B5508(temp2, *points, temp_a0); + + write_save_data_grand_prix_points_and_sound_mode(); + update_save_data_backup(); + } + } +} + +// Get Grand Prix points for a given cup and CC mode +u8 func_800B54C0(s32 cup, s32 cc_mode) { + return func_800B54EC(cup, D_8018ED10.grandPrixPointsArray[cc_mode]); +} + +// Get Grand Prix points scored for a given cup +u8 func_800B54EC(s32 cup, s32 ccGrandPrixPoints) { + s32 cup_index = cup * 2; + u32 cup_points = ccGrandPrixPoints; + + cup_points &= (3 << cup_index); + cup_points >>= cup_index; + cup_points &= 0xFF; + + return cup_points; +} + +// Generate a new CC Grand Prix Points entry with points_scored +// placed in the given cup's location +u8 func_800B5508(s32 cup, s32 ccGrandPrixPoints, s32 points_scored) { + s32 cup_index = cup * 2; + + points_scored <<= cup_index; + ccGrandPrixPoints &= ~(3 << cup_index); + + return (ccGrandPrixPoints | points_scored); +} + +// Check if all 4 cups have gold cups scored +// for a given CC mode +s32 func_800B5530(s32 cc_mode) { + if (D_8018ED10.grandPrixPointsArray[cc_mode] == 0xFF) { + return 1; + } + return 0; +} + +// Check if the 150CC mode has all 4 gold cups +s32 func_800B555C(void) { + return func_800B5530(CC_150); +} + +// Check if the Extra mode has all 4 gold cups +s32 func_800B557C(void) { + return func_800B5530(CC_EXTRA); +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s32 func_800B4874(s32, void *, void *); // extern +s8 func_800B578C(s32, void *, void *); // extern +s8 func_800B5888(s32); // extern +extern u8 D_800F2E60; +extern ? D_8018EB90; +extern OSMesgQueue gSIEventMesgQueue; + +void func_800B559C(s32 arg0, void *arg1, void *arg2) { + s32 temp_s1; + s32 temp_s1_2; + s32 temp_s6; + s32 temp_v0; + s32 temp_v0_2; + u8 *temp_s2_2; + void *temp_a0; + void *temp_a1; + void *temp_a1_2; + void *temp_a2; + void *temp_s2; + void *temp_v1; + void *temp_v1_2; + s32 phi_s1; + void *phi_a1; + void *phi_a2; + u8 *phi_a0; + s32 phi_v0; + s32 phi_v0_2; + void *phi_a1_2; + void *phi_a2_2; + void *phi_a1_3; + + temp_s6 = arg0 / 8; + temp_s1 = temp_s6 * 8; + phi_s1 = temp_s1; + phi_a1 = arg1; + phi_a2 = arg2; + phi_a1_2 = arg1; + phi_a2_2 = arg2; + if (temp_s1 < (temp_s1 + 8)) { + temp_s2 = (temp_s6 * 0x38) + 0x188 + &D_8018EB90; + do { + temp_a2 = &D_8018EB90 + ((phi_s1 / 4) * 0x60) + ((phi_s1 % 4) * 0x18); + phi_a2 = temp_a2; + phi_a0 = &D_800F2E60; + phi_v0 = 0; + phi_v0_2 = 0; + phi_a2_2 = temp_a2; + if (temp_a2->unk17 != func_800B4874(phi_s1, phi_a1, phi_a2)) { + temp_a1 = temp_s2 + ((phi_s1 % 8) * 3); + phi_a1_3 = temp_a1; + do { + temp_v1 = temp_a1 + phi_v0; + temp_v0 = phi_v0 + 1; + temp_v1->unk0 = *phi_a0; + temp_v1->unk18 = *phi_a0; + phi_a0 += 1; + phi_v0 = temp_v0; + } while (temp_v0 != 3); + } else { + temp_a1_2 = temp_s2 + ((phi_s1 % 8) * 3); + phi_a1_3 = temp_a1_2; + do { + temp_a0 = temp_a2 + phi_v0_2; + temp_v1_2 = temp_a1_2 + phi_v0_2; + temp_v0_2 = phi_v0_2 + 1; + temp_v1_2->unk0 = temp_a0->unk0; + temp_v1_2->unk18 = temp_a0->unkF; + phi_v0_2 = temp_v0_2; + } while (temp_v0_2 != 3); + } + temp_s1_2 = phi_s1 + 1; + phi_s1 = temp_s1_2; + phi_a1 = phi_a1_3; + phi_a1_2 = phi_a1_3; + } while (temp_s1_2 < ((temp_s6 * 8) + 8)); + } + temp_s2_2 = &D_8018EB90 + (temp_s6 * 0x38) + 0x188; + temp_s2_2->unk36 = func_800B578C(temp_s6, phi_a1_2, phi_a2_2); + temp_s2_2->unk37 = func_800B5888(temp_s6); + osEepromLongWrite(&gSIEventMesgQueue, ((temp_s2_2 - &D_8018EB90) >> 3) & 0xFF, temp_s2_2, 0x38); +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B559C.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern ? D_8018EB90; + +s32 func_800B578C(s32 arg0) { + s32 temp_a0; + s32 temp_a1; + s32 temp_v1; + u8 *temp_a2; + void *temp_a3; + s32 phi_a0; + s32 phi_v0; + s32 phi_v1; + void *phi_a3; + s32 phi_v1_2; + u8 *phi_t0; + u8 *phi_a2; + + temp_a2 = (arg0 * 0x38) + 0x188 + &D_8018EB90; + phi_v0 = 0; + phi_v1_2 = 0; + phi_t0 = temp_a2; + phi_a2 = temp_a2; + do { + temp_a1 = phi_v0 + 1; + phi_a0 = 1; + phi_v0 = temp_a1; + phi_v1 = phi_v1_2 + ((*phi_t0 + 1) * temp_a1); + phi_a3 = phi_a2 + 1; + phi_a2 += 0x11; +loop_2: + temp_a3 = phi_a3 + 4; + temp_a0 = phi_a0 + 4; + temp_v1 = phi_v1 + ((phi_a3->unk0 + 1) * temp_a1) + phi_a0 + ((phi_a3->unk1 + 1) * temp_a1) + phi_a0 + 1 + ((temp_a3->unk-2 + 1) * temp_a1) + phi_a0 + 2 + ((temp_a3->unk-1 + 1) * temp_a1) + phi_a0 + 3; + phi_a0 = temp_a0; + phi_v1 = temp_v1; + phi_a3 = temp_a3; + phi_v1_2 = temp_v1; + if (temp_a0 != 0x11) { + goto loop_2; + } + phi_t0 += 0x11; + } while (temp_a1 != 3); + return (temp_v1 % 0x100) & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B578C.s") +#endif + +s32 func_800B5888(s32 arg0) { + s32 tmp = ((*(&D_8018ED4E + (arg0 * sizeof(OnlyBestTimeTrialRecords))) + 90)); + return (tmp % 256) & 0xFF; +} + +s32 func_800B58C4(s32 arg0) +{ + UNUSED s32 pad1; + OnlyBestTimeTrialRecords *temp_v1; + UNUSED s32 pad2; + UNUSED s32 pad3; + + temp_v1 = &D_8018EB90.onlyBestTimeTrialRecords[arg0 / 8]; + if ((temp_v1->unknownBytes[6] != (func_800B578C(arg0 / 8) ^ 0)) || (temp_v1->unknownBytes[7] != (func_800B5888(arg0 / 8) ^ 0))) + { + return 1; + } + + return 0; +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s8 compute_save_data_checksum_backup_1(); // extern +s8 compute_save_data_checksum_backup_2(); // extern +extern ? D_8018EB90; +extern union GrandPrixPointsUnion D_8018ED10; +extern u8 D_8018ED11; +extern u8 D_8018ED12; +extern u8 D_8018ED13; +extern u8 gSaveDataSoundMode; +extern union GrandPrixPointsUnion D_8018ED88; +extern u8 D_8018ED89; +extern u8 D_8018ED8A; +extern u8 D_8018ED8B; +extern u8 gSaveDataSoundModeBackup; +extern s8 D_8018ED8E; +extern s8 D_8018ED8F; +extern OSMesgQueue gSIEventMesgQueue; + +void update_save_data_backup(void) { + D_8018ED88.grandPrixPointsMushroomCup = D_8018ED10.grandPrixPointsMushroomCup; + D_8018ED89 = D_8018ED11; + D_8018ED8A = D_8018ED12; + D_8018ED8B = D_8018ED13; + gSaveDataSoundModeBackup = gSaveDataSoundMode; + D_8018ED8E = compute_save_data_checksum_backup_1(); + D_8018ED8F = compute_save_data_checksum_backup_2(); + osEepromLongWrite(&gSIEventMesgQueue, ((&D_8018ED88 - &D_8018EB90) >> 3) & 0xFF, &D_8018ED88, 8); +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B5948.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern union GrandPrixPointsUnion D_8018ED88; + +s32 compute_save_data_checksum_backup_1(void) { + void *temp_a0; + + temp_a0 = &D_8018ED88 + 1; + return ((D_8018ED88.grandPrixPointsMushroomCup + 1 + ((temp_a0->unk0 + 1) * 2) + 1 + ((temp_a0->unk1 + 1) * 3) + 1 + 1 + ((temp_a0->unk2 + 1) * 4) + 1 + 2 + ((temp_a0->unk3 + 1) * 5) + 1 + 3) % 0x100) & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B59F4.s") +#endif + +s32 compute_save_data_checksum_backup_2(void) { + s32 tmp = D_8018ED8E + 90; + return (tmp % 256) & 0xFF; +} + +s32 validate_save_data_checksum_backup(void) +{ + if ((D_8018ED8E != (compute_save_data_checksum_backup_1() ^ 0)) || (D_8018ED8F != (compute_save_data_checksum_backup_2() ^ 0))) { + return 1; + } + + return 0; +} + +// Check if controller has a Controller Pak connected. +// Return 1 if it does, otherwise return 0. +s32 check_for_controller_pak(s32 controller) { + u8 sp1F; + UNUSED s32 phi_v0; + + if ((controller >= 4) || (controller < 0)) { + return 0; + } + + osPfsIsPlug(&gSIEventMesgQueue, &sp1F); + + if ((sp1F & (1 << controller)) != 0) { + return 1; + } + + return 0; +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s32 check_for_controller_pak(s32); // extern +s32 osPfsInit(? *, OSPfs *, ?); // extern +extern u16 D_800E86F0; +extern u32 D_800E86F4; +extern s8 D_800E86F8; +extern u8 D_800F2E64; +extern u8 D_800F2E74; +extern OSPfs D_8018E868; +extern s32 D_8018EB78; +extern s32 D_8018EB7C; +extern s32 gControllerPakNumPagesFree; +extern s32 D_8018EB84; +extern ? gSIEventMesgQueue; + +? func_800B5B94(void) { + s32 temp_v0_2; + s32 temp_v0_3; + s8 temp_v0; + s8 phi_v0; + ? phi_v0_2; + + temp_v0 = D_800E86F8; + phi_v0 = temp_v0; + if (temp_v0 != 0) { + temp_v0_2 = osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84); + if (temp_v0_2 != 0) { + if (temp_v0_2 != 2) { + if (temp_v0_2 != 5) { + D_800E86F8 = 0; + goto block_8; + } + phi_v0 = D_800E86F8; + } else { + D_800E86F8 = 0; +block_8: + phi_v0 = 0; + } + goto block_9; + } + return 0; + } +block_9: + if (phi_v0 == 0) { + if (check_for_controller_pak(0) == 0) { + return 1; + } + temp_v0_3 = osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0); + if (temp_v0_3 != 0) { + if (temp_v0_3 != 1) { + if (temp_v0_3 != 4) { + if (temp_v0_3 != 0xA) { + if (temp_v0_3 == 0xB) { + goto block_17; + } + goto block_19; + } + return 2; + } +block_19: + return 2; + } +block_17: + return 1; + } + D_800E86F8 = 1; + if (osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84) == 0) { + return 0; + } + if (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) != 0) { + return 2; + } + if (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) != 0) { + return 2; + } + gControllerPakNumPagesFree = gControllerPakNumPagesFree >> 8; + goto block_27; + } +block_27: + if (D_8018EB7C >= D_8018EB78) { + return 4; + } + phi_v0_2 = 4; + if (gControllerPakNumPagesFree >= 0x79) { + phi_v0_2 = -1; + } + return phi_v0_2; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B5B94.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s32 check_for_controller_pak(?); // extern +s32 osPfsInit(? *, OSPfs *, ?); // extern +extern u16 D_800E86F0; +extern u32 D_800E86F4; +extern s8 D_800E86FC; +extern u8 D_800F2E64; +extern u8 D_800F2E74; +extern OSPfs D_8018E8D0; +extern s32 D_8018EB88; +extern ? gSIEventMesgQueue; + +s8 func_800B5DA4(void) { + s32 temp_v0_2; + s32 temp_v0_3; + s32 temp_v0_4; + s8 temp_v0; + s8 phi_v0; + s8 phi_v0_2; + + temp_v0 = D_800E86FC; + phi_v0 = temp_v0; + if (temp_v0 != 0) { + temp_v0_2 = osPfsFindFile(&D_8018E8D0, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB88); + if (temp_v0_2 != 0) { + if (temp_v0_2 != 2) { + if (temp_v0_2 != 5) { + goto block_7; + } + return -1; + } +block_7: + D_800E86FC = 0; + phi_v0 = 0; + goto block_8; + } + return 0; + } +block_8: + phi_v0_2 = phi_v0; + if (phi_v0 == 0) { + if (check_for_controller_pak(1) == 0) { + return 1; + } + temp_v0_3 = osPfsInit(&gSIEventMesgQueue, &D_8018E8D0, 1); + if (temp_v0_3 != 0) { + if (temp_v0_3 != 1) { + if (temp_v0_3 != 4) { + if (temp_v0_3 != 0xA) { + if (temp_v0_3 == 0xB) { + goto block_16; + } + goto block_18; + } + goto block_25; + } +block_18: + goto block_25; + } +block_16: + return 1; + } + D_800E86FC = 1; + temp_v0_4 = osPfsFindFile(&D_8018E8D0, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB88); + if (temp_v0_4 != 0) { + if (temp_v0_4 != 2) { + if (temp_v0_4 != 5) { + goto block_25; + } + return -1; + } +block_25: + phi_v0_2 = 2; + // Duplicate return node #26. Try simplifying control flow for better match + return phi_v0_2; + } + return 0; + } + return phi_v0_2; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B5DA4.s") +#endif + +s32 func_800B5F30(void) { + s32 sp1C; + + if (D_800E86F8 != 0) { + return -4; + } + if (check_for_controller_pak(0) != 0) { + sp1C = osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0); + if (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) != 0) { + D_800E86F8 = 0; + return -2; + } + if (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) != 0) { + D_800E86F8 = 0; + return -3; + } + gControllerPakNumPagesFree = gControllerPakNumPagesFree >> 8; + if (sp1C == 0) { + D_800E86F8 = 1; + } + return sp1C; + } + return -1; +} + +s32 func_800B6014(void) { + s32 temp_v0; + + if (D_800E86FC != 0) { + return -4; + } + if (check_for_controller_pak(1) != 0) { + temp_v0 = osPfsInit(&gSIEventMesgQueue, &D_8018E8D0, 1); + if (temp_v0 == 0) { + D_800E86FC = 1; + } + return temp_v0; + } + return -1; +} + +s32 func_800B6088(s32 arg0) { + struct_8018EE10_entry* temp_v1; + + temp_v1 = &D_8018EE10[arg0]; + temp_v1->checksum = func_800B6828(arg0); + return osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_WRITE, arg0 * 0x80 /* 0x80 == sizeof(struct_8018EE10_entry) */, sizeof(struct_8018EE10_entry), (u8*) temp_v1); +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern s32 D_800DC714; + +s32 func_800B60E8(s32 arg0) { + s32 temp_a2; + s32 temp_v0; + s32 temp_v1; + s32 phi_v0; + s32 phi_v1; + void *phi_a1; + + temp_a2 = arg0 + 1; + phi_v0 = 0; + phi_v1 = 0; + phi_a1 = D_800DC714 + (arg0 << 8); + do { + temp_v0 = phi_v0 + 4; + temp_v1 = phi_v1 + ((phi_a1->unk0 * temp_a2) + phi_v0) + ((phi_a1->unk1 * temp_a2) + phi_v0) + 1 + ((phi_a1->unk2 * temp_a2) + phi_v0) + 2 + ((phi_a1->unk3 * temp_a2) + phi_v0) + 3; + phi_v0 = temp_v0; + phi_v1 = temp_v1; + phi_a1 += 4; + } while (temp_v0 != 0x100); + return temp_v1 & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B60E8.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +? func_800051C4(); // extern +s32 func_800B6088(s32); // extern +s8 func_800B60E8(s32); // extern +extern u8 *D_800DC714; +extern s32 D_80162DFC; +extern OSPfs D_8018E868; +extern s32 D_8018EB84; +extern ? D_8018EE10; +extern s8 gCupSelection; + +s32 func_800B6178(s32 arg0) { + s32 temp_s0_2; + s32 temp_v0; + s32 temp_v0_2; + s32 temp_v0_3; + s32 temp_v1; + s8 temp_s0; + s8 temp_s0_3; + void *temp_s1; + void *temp_s3; + s8 phi_s0; + void *phi_s1; + s32 phi_s0_2; + void *phi_s1_2; + s32 phi_v0; + s8 phi_s0_3; + void *phi_s1_3; + s32 phi_v1; + + if ((arg0 != 0) && (arg0 != 1)) { + return -1; + } + if (D_800DC50C == RACING) { + func_800051C4(); + } + temp_s3 = (arg0 << 7) + &D_8018EE10; + temp_s3->unk4 = 0; + temp_v0 = func_800B6088(arg0); + temp_v1 = temp_v0; + phi_v1 = temp_v1; + if (temp_v0 != 0) { + temp_s3->unk4 = 0; + phi_s0 = 0; + phi_s1 = temp_s3; + do { + phi_s1->unk7 = phi_s0; + temp_s0 = phi_s0 + 4; + phi_s1->unkA = phi_s0 + 3; + phi_s1->unk9 = phi_s0 + 2; + phi_s1->unk8 = phi_s0 + 1; + phi_s0 = temp_s0; + phi_s1 += 4; + } while (temp_s0 != 0x3C); + } else { + temp_v0_2 = osPfsReadWriteFile(&D_8018E868, D_8018EB84, 1, (arg0 * 0x3C00) + 0x100, 0x3C00, D_800DC714); + phi_v0 = temp_v0_2; + phi_v1 = temp_v0_2; + if (temp_v0_2 == 0) { + temp_s3->unk4 = 1; + if (D_800DC50C == RACING) { + temp_s3->unk5 = (gCupSelection * 4) + gCupCourseSelection; + } + temp_s3->unk0 = D_80162DFC; + temp_s3->unk6 = D_80162DE0; + phi_s0_2 = 0; + phi_s1_2 = temp_s3; + do { + temp_s0_2 = phi_s0_2 + 1; + temp_s1 = phi_s1_2 + 1; + temp_s1->unk6 = func_800B60E8(phi_s0_2); + phi_s0_2 = temp_s0_2; + phi_s1_2 = temp_s1; + } while (temp_s0_2 != 0x3C); + temp_v0_3 = func_800B6088(arg0); + phi_v0 = temp_v0_3; + phi_v1 = temp_v0_3; + } + if (phi_v0 != 0) { + temp_s3->unk4 = 0; + phi_s0_3 = 0; + phi_s1_3 = temp_s3; + do { + phi_s1_3->unk7 = phi_s0_3; + temp_s0_3 = phi_s0_3 + 4; + phi_s1_3->unkA = phi_s0_3 + 3; + phi_s1_3->unk9 = phi_s0_3 + 2; + phi_s1_3->unk8 = phi_s0_3 + 1; + phi_s0_3 = temp_s0_3; + phi_s1_3 += 4; + } while (temp_s0_3 != 0x3C); + } + } + return phi_v1; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B6178.s") +#endif + +s32 func_800B6348(s32 arg0) { + if ((D_8018EE10[0].ghostDataSaved != 0) && (arg0 == D_8018EE10[0].courseIndex)) { + return 0; + } + if ((D_8018EE10[1].ghostDataSaved != 0) && (arg0 == D_8018EE10[1].courseIndex)) { + return 1; + } + return 0; +} + +s32 func_800B639C(s32 arg0) { + if ((D_8018EE10[0].ghostDataSaved != 0) && (arg0 == D_8018EE10[0].courseIndex)) { + return 0; + } + if ((D_8018EE10[1].ghostDataSaved != 0) && (arg0 == D_8018EE10[1].courseIndex)) { + return 1; + } + return -1; +} + +s32 func_800B63F0(s32 arg0) { + s32 temp_s0; + u8* phi_s1; + s32 phi_s3; + + func_800051C4(); + D_80162DD6 = 1; + func_80005AE8(gPlayerThree); + + phi_s3 = 0; + if (((gCupSelection * 4) + gCupCourseSelection) != D_8018EE10[arg0].courseIndex) { + phi_s3 = 2; + } else if (D_80162DFC != D_8018EE10[arg0].unk_00) { + phi_s3 = 3; + } else { + if (D_80162DE0 != (u8) D_8018EE10[arg0].characterId) { + phi_s3 = 4; + } else { + temp_s0 = 0; + phi_s1 = (u8*) &D_8018EE10[arg0]; + + while (temp_s0 < 0x3C) + { + if (phi_s1[7] != func_800B60E8(temp_s0)) { + phi_s3 = 1; + break; + } + + ++phi_s1; + ++temp_s0; + } + } + } + + return phi_s3; +} + +s32 func_800B64EC(s32 arg0) { + s32 temp_s0; + s32 temp_v0; + u8 *phi_s1; + + if ((arg0 != 0) && (arg0 != 1)) + { + return -1; + } + + temp_v0 = osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_READ, (arg0 * 0x3C00) + 0x100, 0x3C00, (u8 *) D_800DC714); + if (temp_v0 == 0) + { + phi_s1 = (u8 *) &D_8018EE10[arg0]; temp_s0 = 0; while (1) { + + if (phi_s1[7] != func_800B60E8(temp_s0)) { + D_8018EE10[arg0].ghostDataSaved = 0; + return -2; + } + + ++phi_s1; + if ((++temp_s0) == 0x3C) { + func_8000522C(); + D_80162DD4[0] = 0; + D_80162DE0 = (s32) D_8018EE10[arg0].characterId; + D_80162DFC = D_8018EE10[arg0].unk_00; + break; + } + } + + } + + return temp_v0; +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s32 func_800B60E8(s32); // extern +extern u8 *D_800DC714; +extern s32 D_80162DFC; +extern s32 D_8018D9C0; +extern OSPfs D_8018E8D0; +extern s32 D_8018EB88; +extern ? D_8018EE15; + +s32 func_800B65F4(s32 arg0, s32 arg1) { + s32 sp34; + s32 temp_s0; + s32 temp_v0; + void *temp_s3; + s32 phi_s0; + void *phi_s1; + + if ((arg0 != 0) && (arg0 != 1)) { + return -1; + } + temp_v0 = osPfsReadWriteFile(&D_8018E8D0, D_8018EB88, 0, (arg0 * 0x3C00) + 0x100, 0x3C00, D_800DC714); + sp34 = temp_v0; + if (temp_v0 == 0) { + temp_s3 = D_8018D9C0 + (arg0 << 7); + phi_s0 = 0; + phi_s1 = temp_s3; +loop_5: + temp_s0 = phi_s0 + 1; + phi_s0 = temp_s0; + if (phi_s1->unk7 != func_800B60E8(phi_s0)) { + temp_s3->unk4 = 0; + return -2; + } + phi_s1 += 1; + if (temp_s0 == 0x3C) { + D_80162DE0 = temp_s3->unk6; + D_80162DFC = temp_s3->unk0; + *(&D_8018EE15 + (arg1 << 7)) = temp_s3->unk5; + goto block_9; + } + goto loop_5; + } +block_9: + return sp34; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B65F4.s") +#endif + +void func_800B6708(void) { + s32 temp_s0; + + osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_READ, 0, 0x100 /* 2*sizeof(struct_8018EE10_entry) ? */, (u8*) &D_8018EE10); + + for (temp_s0 = 0; temp_s0 < 2; ++temp_s0) { + if (D_8018EE10[temp_s0].checksum != func_800B6828(temp_s0)) { + D_8018EE10[temp_s0].ghostDataSaved = 0; + } + } +} + +void func_800B6798(void) { + s32 temp_s0; + u8* tmp; + + tmp = (u8*) D_8018D9C0; + + osPfsReadWriteFile(&D_8018E8D0, D_8018EB88, PFS_READ, 0, 0x100 /* 2*sizeof(struct_8018EE10_entry) ? */, tmp); + + for (temp_s0 = 0; temp_s0 < 2; ++temp_s0) { + // if (D_8018D9C0[temp_s0]->checksum != func_800B68F4(temp_s0)) { + // D_8018D9C0[temp_s0]->ghostDataSaved = 0; + // } + if ( ((struct_8018EE10_entry*) (tmp + (temp_s0 << 7)))->checksum != func_800B68F4(temp_s0)) { + ((struct_8018EE10_entry*) (tmp + (temp_s0 << 7)))->ghostDataSaved = 0; + } + } +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern ? D_8018EE10; + +s32 func_800B6828(s32 arg0) { + s32 temp_a1; + s32 temp_a2; + s32 temp_v1; + void *temp_v0; + s32 phi_a1; + s32 phi_v1; + void *phi_a3; + + temp_v0 = (arg0 << 7) + &D_8018EE10; + temp_a2 = arg0 + 1; + phi_a1 = 3; + phi_v1 = (temp_v0->unk0 * temp_a2) + (temp_v0->unk1 * temp_a2) + 1 + (temp_v0->unk2 * temp_a2) + 2; + phi_a3 = temp_v0 + 3; + do { + temp_a1 = phi_a1 + 4; + temp_v1 = phi_v1 + ((phi_a3->unk0 * temp_a2) + phi_a1) + ((phi_a3->unk1 * temp_a2) + phi_a1) + 1 + ((phi_a3->unk2 * temp_a2) + phi_a1) + 2 + ((phi_a3->unk3 * temp_a2) + phi_a1) + 3; + phi_a1 = temp_a1; + phi_v1 = temp_v1; + phi_a3 += 4; + } while (temp_a1 != 0x43); + return temp_v1 & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B6828.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +extern s32 D_8018D9C0; + +s32 func_800B68F4(s32 arg0) { + s32 temp_a1; + s32 temp_a2; + s32 temp_a3; + void *temp_v0; + void *temp_v1; + s32 phi_a2; + s32 phi_a1; + + temp_a3 = arg0 + 1; + temp_v1 = (arg0 << 7) + D_8018D9C0; + phi_a2 = 3; + phi_a1 = (temp_v1->unk0 * temp_a3) + (temp_v1->unk1 * temp_a3) + 1 + (temp_v1->unk2 * temp_a3) + 2; + do { + temp_v0 = temp_v1 + phi_a2; + temp_a2 = phi_a2 + 4; + temp_a1 = phi_a1 + ((temp_v0->unk0 * temp_a3) + phi_a2) + ((temp_v0->unk1 * temp_a3) + phi_a2) + 1 + ((temp_v0->unk2 * temp_a3) + phi_a2) + 2 + ((temp_v0->unk3 * temp_a3) + phi_a2) + 3; + phi_a2 = temp_a2; + phi_a1 = temp_a1; + } while (temp_a2 != 0x43); + return temp_a1 & 0xFF; +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B68F4.s") +#endif + +#ifdef MIPS_TO_C +//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 +s8 func_800B6828(s32, s32, s32); // extern +extern OSPfs D_8018E868; +extern s32 D_8018EB84; +extern ? D_8018EE10; + +void func_800B69BC(s32 arg0) { + s32 sp24; + u8 *sp20; + s32 temp_a3; + s8 temp_v0; + u8 *temp_t0; + s8 phi_v0; + u8 *phi_v1; + + temp_a3 = arg0 << 7; + temp_t0 = temp_a3 + &D_8018EE10; + temp_t0->unk4 = 0; + temp_t0->unk5 = 0; + temp_t0->unk6 = 0; + phi_v0 = 0; + phi_v1 = temp_t0; + do { + phi_v1->unk7 = phi_v0; + temp_v0 = phi_v0 + 4; + phi_v1->unkA = phi_v0 + 3; + phi_v1->unk9 = phi_v0 + 2; + phi_v1->unk8 = phi_v0 + 1; + phi_v0 = temp_v0; + phi_v1 += 4; + } while (temp_v0 != 0x3C); + sp24 = temp_a3; + sp20 = temp_t0; + temp_t0->unk7F = func_800B6828(arg0, arg0, temp_a3); + osPfsReadWriteFile(&D_8018E868, D_8018EB84, 1, temp_a3, 0x80, temp_t0); +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B69BC.s") +#endif + +s32 func_800B6A68(void) { + UNUSED s32 pad; + s32 sp30; + s32 temp_s0; + + sp30 = osPfsAllocateFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, 0x7900, &D_8018EB84); + if (sp30 == 0) { + temp_s0 = 0; + while (temp_s0 < 2) + { + func_800B69BC(temp_s0); + ++temp_s0; + } + } + + return sp30; +} + +#ifdef MIPS_TO_C +//generated by mips_to_c commit cc33060578851a93591ed035e96ffd1f15c765f1 +s32 check_for_controller_pak(?); /* extern */ +? func_800B6A68(); /* extern */ +s32 osPfsInit(? *, ? *, ?); /* extern */ +s32 osPfsFindFile(? *, u16, s32, ? *, ? *, ? *); /* extern */ +s32 osPfsFreeBlocks(? *, s32 *); /* extern */ +s32 osPfsNumFiles(? *, s32 *, s32 *); /* extern */ +extern u16 D_800E86F0; +extern s32 D_800E86F4; +extern ? D_800F2E64; +extern ? D_800F2E74; +extern ? D_8018E868; +extern s32 D_8018EB78; +extern s32 D_8018EB7C; +extern ? D_8018EB84; +extern s32 gControllerPakNumPagesFree; +extern ? gSIEventMesgQueue; + +// Separated from assembly in code_800AF9B0/func_800B6A68.s +UNUSED void func_800B6AF8(void) { + s32 temp_t1; + + if ((check_for_controller_pak(0) != 0) && (osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0) == 0) && (osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84) != 0) && (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) == 0) && (D_8018EB7C < D_8018EB78) && (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) == 0)) { + temp_t1 = (s32) gControllerPakNumPagesFree >> 8; + gControllerPakNumPagesFree = temp_t1; + if (temp_t1 >= 0x79) { + func_800B6A68(); + } + } +} +#else +GLOBAL_ASM("asm/non_matchings/menus/func_800B6AF8.s") +#endif diff --git a/src/code_800B45E0.h b/src/code_800B45E0.h new file mode 100644 index 000000000..e45ec98e0 --- /dev/null +++ b/src/code_800B45E0.h @@ -0,0 +1,108 @@ +#ifndef CODE_800B045E0_H +#define CODE_800B045E0_H + +#include "PR/os.h" +#include "common_structs.h" +#include + +union GrandPrixPointsUnion +{ + u8 grandPrixPointsArray[4]; + u8 grandPrixPointsMushroomCup; +}; + +/* Function Prototypes */ +void func_800B45E0(s32); +void write_save_data_grand_prix_points_and_sound_mode(); +void func_800B46D0(); +void func_800B4728(s32); +void reset_save_data_grand_prix_points_and_sound_mode(); +s32 func_800B4874(s32); +s32 func_800B639C(s32); +s32 compute_save_data_checksum_1(); +s32 compute_save_data_checksum_2(); +void func_800B4A10(); +void func_800B4A9C(s32); +void validate_save_data(void); +s32 func_800B4E24(s32); +s32 func_800B4EB4(s32, s32); +s32 func_800B4F2C(); +s32 func_800B4FB0(s32); +u8 func_800B54C0(s32, s32); +u8 func_800B54EC(s32, s32); +u8 func_800B5508(s32, s32, s32); +s32 func_800B5530(s32); +s32 func_800B555C(); +s32 func_800B557C(); +void func_800B559C(s32); +s32 func_800B578C(s32); +s32 func_800B5888(s32); +void update_save_data_backup(); +s32 compute_save_data_checksum_backup_1(void); +s32 compute_save_data_checksum_backup_2(void); +s32 validate_save_data_checksum_backup(); +s32 func_800B5B2C(s32); +s32 func_800B5F30(); +s32 func_800B6014(); +u8 func_800B60E8(s32); +s32 func_800B64EC(s32); +void func_800B6708(void); +u8 func_800B6828(s32); +u8 func_800B68F4(s32); +void func_800B69BC(s32); +s32 func_800B6A68(); + +/* data */ +// these might not be in this file, but for now... + +extern u32* D_800DC714; + +extern u16 D_800E86F0; +extern s32 D_800E86F4; +extern s8 D_800E86F8; +extern struct_8018EE10_entry D_8018EE10[]; +extern struct_8018EE10_entry *D_8018D9C0; +extern u8 D_8018ED16; // D_8018EB90.checksum[1] +extern u8 D_8018ED17; // D_8018EB90.checksum[2] +extern u8 D_8018ED4E; // D_8018EB90.onlyBestTimeTrialRecords[0].unknownBytes[6] +extern union GrandPrixPointsUnion D_8018ED10; // Direct reference to the grandPrixPoints section of save data +extern union GrandPrixPointsUnion D_8018ED88; // D_8018EB90.grandPrixPointsBackup[0] + +extern s8 D_800E86FC; +extern const u8 D_800F2E60[]; +extern const char D_800F2E64[]; +extern const char D_800F2E74[]; +extern OSMesgQueue gSIEventMesgQueue; // D_8014F0B8 +extern u16 D_80162DD6; +extern s32 D_80162DE0; +extern s32 D_80162DFC; +extern OSPfs D_8018E868; +extern OSPfs D_8018E8D0; +extern OSPfsState D_8018E938[]; +extern s32 D_8018EB38[16]; +extern s32 D_8018EB78; +extern s32 D_8018EB7C; +extern s32 D_8018EB84; +extern s32 D_8018EB88; +extern SaveData D_8018EB90; +extern u8 D_8018ED11; +extern u8 D_8018ED12; +extern u8 D_8018ED13; +extern u8 gSaveDataSoundMode; // D_8018ED14 +extern u8 D_8018ED89; +extern u8 D_8018ED8A; +extern u8 D_8018ED8B; +extern u8 D_8018ED8E; // D_8018EB90.checksumBackup[1] +extern u8 D_8018ED8F; // D_8018EB90.checksumBackup[2] +extern s8 D_8018EDE5; +extern s8 D_8018EDE6; +extern s8 D_8018EDE7; +extern u8 gSoundMode; // D_8018EDF2 +extern s8 gTimeTrialDataCourseIndex; // D_8018EDF7 +extern s8 gCourseRecordsMenuSelection; // D_8018EDF8 +extern s32 gMenuTimingCounter; // D_8018EE00 +extern s8 gCupSelection; // D_8018EE09 +extern s8 gCupCourseSelection; // D_8018EE0B + + +#endif /* CODE_800B045E0_H */ diff --git a/src/main.h b/src/main.h index 1889f350a..2afe0826e 100644 --- a/src/main.h +++ b/src/main.h @@ -58,6 +58,7 @@ void thread5_game_logic(s32); void thread4_audio(s32); extern struct GfxPool *gGfxPool; +extern Gfx *gDisplayListHead; extern OSIoMesg gDmaIoMesg; extern OSMesg gMainReceivedMesg; diff --git a/src/memory.c b/src/memory.c index b65512e41..3d956ef79 100644 --- a/src/memory.c +++ b/src/memory.c @@ -60,7 +60,7 @@ void move_segment_table_to_dmem(void) { void func_802A7CF0(s32 start, s32 end) { - start = ALIGN32(start); + start = ALIGN16(start); end &= ~0xF; D_8015F724 = (end - start) - 0x10; @@ -70,7 +70,7 @@ void func_802A7CF0(s32 start, s32 end) { s32 func_802A7D1C(s32 arg0) { s32 addr; - arg0 = ALIGN32(arg0); + arg0 = ALIGN16(arg0); D_8015F724 -= arg0; addr = gPrevLoadedAddress; gPrevLoadedAddress += arg0; diff --git a/src/memory.h b/src/memory.h index efdcb75ad..9cf97ef17 100644 --- a/src/memory.h +++ b/src/memory.h @@ -34,8 +34,6 @@ struct AllocOnlyPool { #define MEMORY_POOL_RIGHT 1 #define ALIGN4(val) (((val) + 0x3) & ~0x3) -#define ALIGN16(val) (((val) + 0xF) & ~0xF) -#define ALIGN32(val) (((val) + 0xF) & ~0xF) s32 func_802A7B70(s32); uintptr_t set_segment_base_addr(s32, void*); diff --git a/src/menus.c b/src/menus.c index 2b043c1a7..e64ac0be3 100644 --- a/src/menus.c +++ b/src/menus.c @@ -3,395 +3,63 @@ #include #include "global.h" -#include "code_80091750.h" #include "menus.h" -void func_800AF9B0(void) { - D_8018EDB8 = func_802A7B70(7680); - D_8018EDBC = func_802A7B70(7680); -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f32 D_800F2B30; -extern void *gDisplayListHead; - -void func_800AF9E4(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s16 arg4, s16 arg5, s32 arg6, s32 arg7) { - f32 temp_f0; - s32 temp_a1; - s32 temp_lo; - s32 temp_t1; - s32 temp_v0; - void *temp_a3; - void *temp_a3_2; - void *temp_a3_3; - void *temp_a3_4; - void *temp_a3_5; - void *temp_v1; - s32 phi_v0; - s16 phi_t6; - s32 phi_a1; - s32 phi_v1; - s32 phi_v0_2; - - temp_lo = arg2 * arg3; - temp_f0 = D_800F2B30; - phi_v0 = 0; - phi_v0_2 = 0; - do { - temp_v1 = arg0 + (phi_v0 * 0x10); - temp_a1 = phi_v0 % 2; - temp_t1 = arg1 + 1; - temp_v1->unk0 = ((temp_a1 * arg7) + arg6) - 0x1F8; - temp_v0 = phi_v0 + 1; - phi_v0 = temp_v0; - if ((phi_v0 / 2) == 0) { - temp_v1->unk2 = temp_lo - 0x1A4; - } else { - temp_v1->unk2 = (temp_lo + arg3) - 0x1A4; - } - if (temp_a1 == 0) { - phi_t6 = temp_v1->unk2 + ((arg1 * arg1) * temp_f0); - } else { - phi_t6 = temp_v1->unk2 + ((temp_t1 * temp_t1) * temp_f0); - } - temp_v1->unk2 = phi_t6; - temp_v1->unkC = 0; - temp_v1->unkD = 0; - temp_v1->unkE = 0x78; - temp_v1->unkF = 0xFF; - if (temp_a1 == 0) { - temp_v1->unk4 = arg4; - } else { - temp_v1->unk4 = arg5; - } - } while (temp_v0 != 4); - if ((((arg1 / 2) + (arg2 / 2)) & 1) == 0) { - phi_a1 = 0; - phi_v1 = 0; - } else { - phi_a1 = 0xFF; - phi_v1 = 0xFF; - phi_v0_2 = 0xFF; - } - temp_a3 = gDisplayListHead; - gDisplayListHead = temp_a3 + 8; - temp_a3->unk0 = 0xFA000000; - temp_a3->unk4 = (phi_a1 << 0x18) | ((phi_v1 & 0xFF) << 0x10) | ((phi_v0_2 & 0xFF) << 8) | 0xFF; - temp_a3_2 = gDisplayListHead; - gDisplayListHead = temp_a3_2 + 8; - temp_a3_2->unk4 = 0; - temp_a3_2->unk0 = 0xE7000000; - temp_a3_3 = gDisplayListHead; - gDisplayListHead = temp_a3_3 + 8; - temp_a3_3->unk0 = 0x400103F; - temp_a3_3->unk4 = arg0 + 0x80000000; - temp_a3_4 = gDisplayListHead; - gDisplayListHead = temp_a3_4 + 8; - temp_a3_4->unk4 = 0x20400; - temp_a3_4->unk0 = 0xBF000000; - temp_a3_5 = gDisplayListHead; - gDisplayListHead = temp_a3_5 + 8; - temp_a3_5->unk4 = 0x60402; - temp_a3_5->unk0 = 0xBF000000; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800AF9E4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern f64 D_800F2B38; -extern f32 D_800F2B40; - -void func_800AFC54(s32 arg0, s32 arg1, s32 arg2, s32 arg3, void *arg4) { - s32 sp3C; - s32 sp38; - s32 sp34; - f32 sp20; - f32 sp1C; - f32 sp18; - f32 temp_f0; - f32 temp_f14; - f32 temp_f16; - f32 temp_f18; - f32 temp_f2; - s16 temp_t1; - s16 temp_t2; - s16 temp_t3; - s16 temp_t6; - s16 temp_t7; - s16 temp_t9; - s32 temp_a0; - s32 temp_a1; - s32 temp_a2; - s32 temp_a3; - s32 temp_v0_2; - s32 temp_v1_2; - void *temp_t0; - void *temp_v0; - void *temp_v1; - f32 phi_f2; - - temp_v0 = (arg1 * 0x10) + arg0; - temp_v1 = (arg2 * 0x10) + arg0; - temp_t0 = (arg3 * 0x10) + arg0; - temp_t9 = temp_t0->unk0; - temp_t1 = temp_v1->unk0; - temp_t2 = temp_v1->unk2; - temp_t3 = temp_v1->unk4; - sp3C = temp_t9; - temp_t6 = temp_t0->unk2; - temp_v0_2 = temp_t2 - temp_v0->unk2; - temp_a0 = temp_t3 - temp_v0->unk4; - sp38 = temp_t6; - temp_t7 = temp_t0->unk4; - temp_a1 = temp_t6 - temp_t2; - temp_v1_2 = temp_t7 - temp_t3; - sp34 = temp_t7; - temp_a2 = temp_t9 - temp_t1; - temp_a3 = temp_t1 - temp_v0->unk0; - temp_f14 = (temp_v0_2 * temp_v1_2) - (temp_a0 * temp_a1); - sp20 = temp_f14; - temp_f16 = (temp_a0 * temp_a2) - (temp_a3 * temp_v1_2); - sp1C = temp_f16; - temp_f18 = (temp_a3 * temp_a1) - (temp_v0_2 * temp_a2); - sp18 = temp_f18; - temp_f0 = sqrtf((temp_f14 * temp_f14) + (temp_f16 * temp_f16) + (temp_f18 * temp_f18)); - phi_f2 = temp_f0; - if (temp_f0 < D_800F2B38) { - phi_f2 = D_800F2B40; - } - temp_f2 = 1.0 / phi_f2; - arg4->unk0 = temp_f14 * temp_f2 * 120.0f; - arg4->unk2 = temp_f16 * temp_f2 * 120.0f; - arg4->unk4 = temp_f18 * temp_f2 * 120.0f; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800AFC54.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -void func_800AFE00(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { - s16 sp1A; - s16 sp14; - s16 *temp_a1; - s16 *temp_a3; - s32 temp_v0; - s32 temp_v1; - void *temp_a1_2; - void *temp_a3_2; - void *temp_t1; - void *temp_t3; - s16 *phi_a3; - s16 *phi_t0; - s16 *phi_a1; - s16 *phi_t1; - s32 phi_v1; - s32 phi_v0; - s32 phi_v1_2; - - if (arg2 == 0) { - phi_v0 = 0; - } else { - phi_v0 = arg2 - 1; - } - phi_a1 = &sp14; - if (arg2 == arg3) { - phi_v1_2 = arg3; - } else { - phi_v1_2 = arg2 + 1; - } - phi_a3 = arg1 + (arg2 * 6); - phi_t0 = arg1 + (phi_v0 * 6); - phi_t1 = arg1 + (phi_v1_2 * 6); - do { - temp_a1 = phi_a1 + 2; - temp_a3 = phi_a3 + 2; - temp_a1->unk-2 = (*phi_a3 + *phi_t0) / 2; - temp_a1->unk4 = (temp_a3->unk-2 + *phi_t1) / 2; - phi_a3 = temp_a3; - phi_t0 += 2; - phi_a1 = temp_a1; - phi_t1 += 2; - } while (temp_a1 != &sp1A); - phi_v1 = 0; - do { - temp_v0 = phi_v1 * 0x10; - temp_a1_2 = arg0 + temp_v0; - temp_a1_2->unkC = sp14; - temp_a3_2 = arg0 + 0x10 + temp_v0; - temp_t1 = arg0 + 0x20 + temp_v0; - temp_a1_2->unkD = sp16; - temp_t3 = arg0 + 0x30 + temp_v0; - temp_v1 = phi_v1 + 0x30; - temp_a1_2->unkE = sp18; - temp_a3_2->unkC = sp1A; - temp_a3_2->unkD = sp1C; - temp_a3_2->unkE = sp1E; - temp_t1->unkC = sp14; - temp_t1->unkD = sp16; - temp_t1->unkE = sp18; - temp_t3->unkC = sp1A; - temp_t3->unkD = sp1C; - temp_t3->unkE = sp1E; - phi_v1 = temp_v1; - } while (temp_v1 != 0x1E0); -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800AFE00.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_800AFC54(s32, ?, ?, ?, ? *); // extern -? func_800AFE00(s32, ? *, s32, ?); // extern - -void func_800AFF58(s32 arg0) { - ? sp88; - ? sp40; - s32 temp_s0; - u32 temp_s2; - s32 phi_s1; - ? *phi_s2; - s32 phi_s1_2; - s32 phi_s0; - - phi_s1 = 0; - phi_s2 = &sp40; - phi_s1_2 = 0; - do { - func_800AFC54((phi_s1 * 0x10) + arg0, 1, 2, 0, phi_s2); - temp_s2 = phi_s2 + 6; - phi_s1 += 4; - phi_s2 = temp_s2; - } while (temp_s2 < &sp88); - phi_s0 = 0; - do { - func_800AFE00((phi_s1_2 * 0x10) + arg0, &sp40, phi_s0, 0xB); - temp_s0 = phi_s0 + 1; - phi_s1_2 += 4; - phi_s0 = temp_s0; - } while (temp_s0 != 0xC); -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800AFF58.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_800AF9E4(s32, s32, s32, ?, s32, s32, s32, s32); // extern -? func_800AFF58(s32); // extern -f32 sins(s32); // extern -extern ? D_800E8680; -extern ? D_800E8688; -extern f32 D_800F2B44; -extern s16 D_8018EDB0; -extern s16 D_8018EDB2; -extern s16 D_8018EDB4; -extern s32 D_8018EDB8; -extern s32 D_8018EDBC; -extern void *gDisplayListHead; - -void func_800B0004(void) { - s32 spBC; - s32 sp64; - f32 temp_f22; - s32 temp_fp; - s32 temp_s1; - s32 temp_s4; - void *temp_a0; - void *temp_a1; - void *temp_a2; - void *temp_a3; - void *temp_t0; - void *temp_t1; - void *temp_v0; - void *temp_v0_2; - void *temp_v0_3; - void *temp_v0_4; - s32 phi_s0; - s32 phi_s3; - s32 phi_fp; - s32 phi_s2; - - temp_a0 = gDisplayListHead; - gDisplayListHead = temp_a0 + 8; - temp_a0->unk0 = 0x3860010; - temp_a0->unk4 = &D_800E8688 - 0x80000000; - temp_a1 = gDisplayListHead; - gDisplayListHead = temp_a1 + 8; - temp_a1->unk0 = 0x3880010; - temp_a1->unk4 = &D_800E8680 - 0x80000000; - temp_a2 = gDisplayListHead; - gDisplayListHead = temp_a2 + 8; - temp_a2->unk4 = 0x80000040; - temp_a2->unk0 = 0xBC000002; - temp_a3 = gDisplayListHead; - gDisplayListHead = temp_a3 + 8; - temp_a3->unk4 = 0x204; - temp_a3->unk0 = 0xB7000000; - temp_t0 = gDisplayListHead; - gDisplayListHead = temp_t0 + 8; - temp_t0->unk4 = -0x604; - temp_t0->unk0 = 0xFC327E64; - temp_t1 = gDisplayListHead; - gDisplayListHead = temp_t1 + 8; - temp_t1->unk4 = 0x2000; - temp_t1->unk0 = 0xB6000000; - temp_v0 = gDisplayListHead; - gDisplayListHead = temp_v0 + 8; - temp_v0->unk4 = 0x20000; - temp_v0->unk0 = 0xB7000000; - if ((D_8018EDB4 % 2) != 0) { - spBC = D_8018EDB8; - } else { - spBC = D_8018EDBC; - } - D_8018EDB2 = 0x9C0; - temp_f22 = D_800F2B44; - sp64 = 0; - phi_fp = 0; - do { - phi_s0 = 0; - phi_s3 = 0; - phi_s2 = 0; -loop_5: - temp_s1 = phi_s0 + 1; - temp_s4 = sins((D_8018EDB0 - (phi_s0 * D_8018EDB2)) & 0xFFFF) * 84.0f * phi_s0 * temp_f22; - func_800AF9E4((phi_s3 * 0x10) + spBC + (sp64 * 0x10), phi_s0, phi_fp, 0x54, temp_s4, sins((D_8018EDB0 - (temp_s1 * D_8018EDB2)) & 0xFFFF) * 84.0f * temp_s1 * temp_f22, phi_s2, 0x54); - phi_s0 = temp_s1; - phi_s3 += 4; - phi_s2 += 0x54; - if (temp_s1 != 0xC) { - goto loop_5; - } - temp_fp = phi_fp + 1; - sp64 += 0x30; - phi_fp = temp_fp; - } while (temp_fp != 0xA); - func_800AFF58(spBC); - D_8018EDB0 = D_8018EDB0 + D_8018EDB2; - D_8018EDB4 = D_8018EDB4 + 1; - temp_v0_2 = gDisplayListHead; - gDisplayListHead = temp_v0_2 + 8; - temp_v0_2->unk0 = 0xB7000000; - temp_v0_2->unk4 = 0x2000; - temp_v0_3 = gDisplayListHead; - gDisplayListHead = temp_v0_3 + 8; - temp_v0_3->unk4 = 0x80000040; - temp_v0_3->unk0 = 0xBC000002; - temp_v0_4 = gDisplayListHead; - gDisplayListHead = temp_v0_4 + 8; - temp_v0_4->unk4 = 0x20000; - temp_v0_4->unk0 = 0xB6000000; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B0004.s") -#endif +#include "audio/external.h" +#include "code_80091750.h" +#include +/* const/rodata data */ +// used to set gScreenModeSelection; might be smaller; could be function static data +const s8 D_800F2B50[] = {0, 1, 2, 3, 3, 0, 0, 0}; + +// set to D_8018EDF3, then that sets gPlayerCountSelection1 +const s8 D_800F2B58[] = {1, 2, 2, 3, 4, 0, 0, 0}; +//const s8 D_800F2B5F = 0; // probably part of above array; terminator? + +// probably combined... +//const s8 D_800F2B60 = 1; +//const s8 D_800F2B61[] = {2, 1, 1, 2, 1, 0, 2, 2, 0, 2, 0, 0}; +//const s8 D_800F2B6D[] = {2, 0, 0}; +const s8 D_800F2B60[] = {1, 2, 1, 1, 2, 1, 0, 2, 2, 0, 2, 0, 0, 2, 0, 0}; + +// is this another union GameModePack? Figure out when decomping. +const s32 gGameModeFromNumPlayersAndRowSelection[5][3] = { + { 0x03010003, 0x03000300, 0x00030000 }, + { 0x00000000, 0x00000001, 0x00000000 }, + { 0x00000000, 0x00000002, 0x00000003 }, + { 0x00000002, 0x00000003, 0x00000000 }, + { 0x00000002, 0x00000003, 0x00000000 }, +}; + +const s8 D_800F2BAC[] = { 0x00, 0x01, 0x06, 0x03, 0x02, 0x04, 0x05, 0x07 }; + +const s16 gCupCourseOrder[5][4] = { + // mushroom cup + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + // flower cup + { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, + // star cup + { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + // special cup + { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, + // battle mode + { COURSE_BIG_DONUT, COURSE_BLOCK_FORT, COURSE_DOUBLE_DECK, COURSE_SKYSCRAPER }, +}; + +const s8 D_800F2BDC[] = {1, 0, 0, 0, 0, 1, 3, 4}; + +// terrible for endianness... Best guess as to what this is for.. +union GameModePack { + s8 modes[4]; + s32 word; +}; + +// needs to be a union (or array...?) to go into rodata as a const +const union GameModePack D_800F2BE4 = { {0, 1, 2, 3} }; + +// new file start #if NEEDS_RODATA void func_800B0350(void) { u16 controllerIdx; @@ -2603,7 +2271,7 @@ extern s32 D_80162DE0; extern s32 D_8018D9C0; extern ? D_8018EE16; -// Separated from assembly in menus/func_800B4520.s +// Separated from assembly in code_800AF9B0/func_800B4520.s UNUSED void func_800B4560(s32 arg0, s32 arg1) { s32 sp18; @@ -2615,1499 +2283,3 @@ UNUSED void func_800B4560(s32 arg0, s32 arg1) { #else GLOBAL_ASM("asm/non_matchings/menus/func_800B4560.s") #endif - -void func_800B45E0(s32 arg0) { - CourseTimeTrialRecords* courseTimeTrialRecordsPtr = &D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[arg0 / 4] \ - .courseRecords[arg0 % 4]; - - courseTimeTrialRecordsPtr->unknownBytes[5] = func_800B4874(arg0); - osEepromLongWrite(&gSIEventMesgQueue, ((u32)courseTimeTrialRecordsPtr - (u32)&D_8018EB90) >> 3, (u8*) courseTimeTrialRecordsPtr, sizeof(CourseTimeTrialRecords)); -} - -void write_save_data_grand_prix_points_and_sound_mode(void) { - D_8018ED16 = compute_save_data_checksum_1(); - D_8018ED17 = compute_save_data_checksum_2(); - osEepromLongWrite(&gSIEventMesgQueue, (((u32)&D_8018ED10 - (u32)&D_8018EB90) >> 3), (u8*) &D_8018ED10, 8); -} - -void func_800B46D0(void) { - s32 temp_s0; - s32 phi_s0; - - phi_s0 = 0; - do { - func_800B4728(phi_s0); - func_800B559C(phi_s0); - temp_s0 = phi_s0 + 1; - phi_s0 = temp_s0; - } while (phi_s0 != 0x10); - reset_save_data_grand_prix_points_and_sound_mode(); - update_save_data_backup(); -} - -void func_800B4728(s32 arg0) { - s32 temp_a2; - s32 temp_v0; - CourseTimeTrialRecords* courseTimeTrialRecords; - - courseTimeTrialRecords = &D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[arg0 / 4] \ - .courseRecords[arg0 % 4]; - - for (temp_a2 = 0; temp_a2 < 5; ++temp_a2) - { - for (temp_v0 = 0; temp_v0 < 3; ++temp_v0) - { - courseTimeTrialRecords->records[temp_a2][temp_v0] = D_800F2E60[temp_v0]; - } - } - - for (temp_a2 = 0; temp_a2 < 3; ++temp_a2) - { - courseTimeTrialRecords->records[5][temp_a2] = D_800F2E60[temp_a2]; - } - - courseTimeTrialRecords->unknownBytes[0] = 0; - courseTimeTrialRecords->unknownBytes[5] = func_800B4874(arg0); - func_800B45E0(arg0); -} - -void reset_save_data_grand_prix_points_and_sound_mode(void) { - D_8018ED10.grandPrixPointsMushroomCup = 0; - D_8018ED11 = 0; - D_8018ED12 = 0; - D_8018ED13 = 0; - gSaveDataSoundMode = SOUND_STEREO; - gSoundMode = SOUND_STEREO; - func_800B44BC(); - write_save_data_grand_prix_points_and_sound_mode(); -} - -s32 func_800B4874(s32 arg0) { - s32 temp_a0; - s32 temp_a1; - s32 temp_v1; - u8* records = &D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[arg0 / 4] \ - .courseRecords[arg0 % 4] \ - .records[0][0]; - - temp_v1 = 0; - temp_a1 = 0; - while (temp_a1 < 7) - { - temp_a0 = 0; - while (temp_a0 < 3) - { - temp_v1 += (*((records + 3*temp_a1 + temp_a0)) * (temp_a0 + 1)) + temp_a1; - ++temp_a0; - } - ++temp_a1; - } - - return (temp_v1 % 256) & 0xFF; -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern union GrandPrixPointsUnion D_8018ED10; - -s32 compute_save_data_checksum_1(void) { - void *temp_a0; - - temp_a0 = &D_8018ED10 + 1; - return ((D_8018ED10.grandPrixPointsMushroomCup + 1 + ((temp_a0->unk0 + 1) * 2) + 1 + ((temp_a0->unk1 + 1) * 3) + 1 + 1 + ((temp_a0->unk2 + 1) * 4) + 1 + 2 + ((temp_a0->unk3 + 1) * 5) + 1 + 3) % 0x100) & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B492C.s") -#endif - -s32 compute_save_data_checksum_2(void) { - s32 tmp = D_8018ED16 + 90; - return (tmp % 256) & 0xFF; -} - -void load_save_data(void) { - s32 temp_s0; - - osEepromLongRead(&gSIEventMesgQueue, 0, (u8*) &D_8018EB90, sizeof(SaveData)); - temp_s0 = 0; - while (temp_s0 < 16) // 16: 4 cup records * 4 course records? - { - func_800B4A9C(temp_s0); - ++temp_s0; - } - - validate_save_data(); - - gSoundMode = gSaveDataSoundMode; - if (gSoundMode >= NUM_SOUND_MODES) { - gSoundMode = SOUND_MONO; - } -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_800B45E0(s32, u8 *, u8, s32); // extern -? func_800B4728(s32); // extern -s32 func_800B4874(s32); // extern -s32 func_800B4EB4(?, s32); // extern -? func_800B4FB0(s32); // extern -? func_800B559C(s32); // extern -s32 func_800B58C4(s32); // extern -extern u8 D_800F2E60; -extern ? D_8018EB90; -extern ? D_8018EBA2; - -void func_800B4A9C(s32 arg0) { - void *sp24; - s32 temp_v1; - u8 *temp_a1; - u8 temp_a2; - u8 temp_t6; - u8 temp_t8; - void *temp_a0; - void *temp_t2; - void *temp_v0; - s32 phi_v1; - u8 *phi_a1; - s32 phi_a3; - s32 phi_a3_2; - - if ((func_800B4EB4(0, arg0) & 0xFFFFF) < MAX_TIME) { - *(&D_8018EBA2 + (((arg0 / 4) * 0x60) + ((arg0 % 4) * 0x18))) = 1; - } - temp_t2 = ((arg0 / 4) * 0x60) + ((arg0 % 4) * 0x18) + &D_8018EB90; - sp24 = temp_t2; - func_800B4FB0(arg0); - sp24 = temp_t2; - if (temp_t2->unk17 != func_800B4874(arg0)) { - sp24 = temp_t2; - func_800B4728(arg0); - if (func_800B58C4(arg0) == 0) { - phi_v1 = 0; - phi_a1 = &D_800F2E60; - phi_a3_2 = 0; - do { - temp_v0 = ((arg0 / 8) * 0x38) + ((arg0 % 8) * 3) + 0x188 + &D_8018EB90 + phi_v1; - temp_t6 = temp_v0->unk0; - temp_a0 = temp_t2 + phi_v1; - temp_v1 = phi_v1 + 1; - temp_a0->unk0 = temp_t6; - temp_t8 = temp_v0->unk18; - temp_a0->unkF = temp_t8; - temp_a2 = *phi_a1; - phi_v1 = temp_v1; - phi_a3 = phi_a3_2; - if (((temp_t6 & 0xFF) == temp_a2) && ((temp_t8 & 0xFF) == temp_a2)) { - phi_a3 = phi_a3_2 + 1; - } - temp_a1 = phi_a1 + 1; - phi_a1 = temp_a1; - phi_a3_2 = phi_a3; - } while (temp_v1 != 3); - if (phi_a3 == 3) { - temp_t2->unk12 = 0; - } else { - temp_t2->unk12 = 1; - } - func_800B45E0(arg0, temp_a1, temp_a2, phi_a3); - } - func_800B559C(arg0); - return; - } - if (func_800B58C4(arg0) != 0) { - func_800B559C(arg0); - } -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B4A9C.s") -#endif - -void validate_save_data(void) { - if ((D_8018ED16 != (compute_save_data_checksum_1() & 0xFFFFFFFF)) || (D_8018ED17 != (compute_save_data_checksum_2() & 0xFFFFFFFF))) { - - reset_save_data_grand_prix_points_and_sound_mode(); - - if (validate_save_data_checksum_backup() == 0) { - D_8018ED10.grandPrixPointsMushroomCup = D_8018ED88.grandPrixPointsMushroomCup; - if ((D_8018ED16 && D_8018ED16) && D_8018ED16) - { - } - - D_8018ED11 = D_8018ED89; - if ((D_8018ED16 && D_8018ED16) && D_8018ED16) - { - } - - D_8018ED12 = D_8018ED8A; - if ((D_8018ED16 && D_8018ED16) && D_8018ED16) - { - } - - D_8018ED13 = D_8018ED8B; - if ((D_8018ED16 && D_8018ED16) && D_8018ED16) - { - } - - gSaveDataSoundMode = gSaveDataSoundModeBackup; - D_8018ED16 = compute_save_data_checksum_backup_1(); - D_8018ED17 = compute_save_data_checksum_backup_2(); - osEepromLongWrite(&gSIEventMesgQueue, (((u32) &D_8018ED10 - (u32) &D_8018EB90) >> 3), (u8*) &D_8018ED10, 8); - } - update_save_data_backup(); - return; - } - - if (validate_save_data_checksum_backup() != 0) { - update_save_data_backup(); - } -} - -void populate_time_trial_record(u8 *timeTrialRecord, u32 time, s32 characterId) -{ - u32 timeRightShift8 = time >> 8; - u32 timeRightShift16 = timeRightShift8 >> 8; - s16 timeRightShift8Duplicate; - u16 timeRightShift16Duplicate; - - timeRightShift16Duplicate = timeRightShift16; - - timeTrialRecord[0] = time & 0xFF; - timeTrialRecord[1] = (timeRightShift8Duplicate = timeRightShift8); - timeTrialRecord[2] = (timeRightShift16Duplicate & 0xF) + ((characterId & 7) << 4); -} - -#ifdef NON_MATCHING -//generated by mips_to_c commit 99fec197b8c557ea7cc0d78f1b263a0de6e59168 -s32 func_800B4DF4(u8 *arg0) { - return ((arg0[1] << 8) + arg0[0] + (arg0[2] << 0x10)) & 0xFFFFFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B4DF4.s") -#endif - -// Get a time trial record, infer course index -s32 func_800B4E24(s32 recordIndex) { - return func_800B4DF4( - D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[(((gCupSelection * 4) + gCupCourseSelection) / 4)] \ - .courseRecords[(((gCupSelection * 4) + gCupCourseSelection) % 4)] \ - .records[recordIndex] - ); -} - -// Get a time trial record, but take the course index as an argument -s32 func_800B4EB4(s32 recordIndex, s32 courseIndex) { - return func_800B4DF4( - D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[(courseIndex / 4)] \ - .courseRecords[(courseIndex % 4)] \ - .records[recordIndex] - ); -} - -// Get Best Lap record of the inferred course index -s32 func_800B4F2C(void) { - return func_800B4DF4( - D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[(((gCupSelection * 4) + gCupCourseSelection) / 4)] \ - .courseRecords[(((gCupSelection * 4) + gCupCourseSelection) % 4)] \ - .records[TIME_TRIAL_1LAP_RECORD] - ); -} - -// Get the best single lap time record of the given course index -s32 func_800B4FB0(s32 courseIndex) { - return func_800B4DF4( - D_8018EB90.allCourseTimeTrialRecords \ - .cupRecords[(courseIndex / 4)] \ - .courseRecords[(courseIndex % 4)] \ - .records[TIME_TRIAL_1LAP_RECORD] - ); -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_800B45E0(s32); // extern -? populate_time_trial_record(void *, u32, s32, void *); // extern -s32 func_800B4DF4(void *); // extern -extern ? D_8018EB90; -extern s8 gCupSelection; - -s32 func_800B5020(u32 arg0, s32 arg1) { - s32 sp30; - s32 temp_a0; - s32 temp_s0; - s32 temp_s1; - s32 temp_v0; - s32 temp_v0_2; - s32 temp_v1; - u8 temp_t3; - u8 temp_t8; - u8 temp_t9; - void *temp_a3; - void *temp_s2; - void *temp_v0_3; - void *temp_v0_4; - s32 phi_s0; - s32 phi_s1; - s32 phi_s1_2; - s32 phi_v1; - s32 phi_a0; - s32 phi_v1_2; - s32 phi_s0_2; - s32 phi_a0_2; - - temp_v0 = (gCupSelection * 4) + gCupCourseSelection; - temp_s2 = ((temp_v0 / 4) * 0x60) + ((temp_v0 % 4) * 0x18) + &D_8018EB90; - sp30 = temp_v0; - phi_s0 = 0; - phi_s1 = 0; -loop_1: - phi_s1_2 = phi_s1; - phi_s0_2 = phi_s0; - if (arg0 >= (func_800B4DF4(temp_s2 + phi_s0) & 0xFFFFF)) { - temp_s1 = phi_s1 + 1; - temp_s0 = phi_s0 + 3; - phi_s0 = temp_s0; - phi_s1 = temp_s1; - phi_s1_2 = temp_s1; - phi_s0_2 = temp_s0; - if (temp_s1 != 5) { - goto loop_1; - } - } - phi_a0 = 4; - phi_a0_2 = 4; - if (phi_s1_2 >= 5) { - return -1; - } - temp_a3 = temp_s2 + phi_s0_2; - if (phi_s1_2 < 4) { - temp_v0_2 = -((4 - phi_s1_2) & 3); - if (temp_v0_2 != 0) { - phi_v1 = 4 * 3; - do { - temp_v0_3 = temp_s2 + phi_v1; - temp_a0 = phi_a0 - 1; - temp_v0_3->unk0 = temp_v0_3->unk-3; - temp_v0_3->unk1 = temp_v0_3->unk-2; - temp_v0_3->unk2 = temp_v0_3->unk-1; - phi_v1 += -3; - phi_a0 = temp_a0; - phi_a0_2 = temp_a0; - } while ((temp_v0_2 + 4) != temp_a0); - if (phi_s1_2 != temp_a0) { - goto block_10; - } - } else { -block_10: - phi_v1_2 = phi_a0_2 * 3; - do { - temp_v0_4 = temp_s2 + phi_v1_2; - temp_v0_4->unk0 = temp_v0_4->unk-3; - temp_v0_4->unk1 = temp_v0_4->unk-2; - temp_t8 = temp_v0_4->unk-8; - temp_t9 = temp_v0_4->unk-7; - temp_t3 = temp_v0_4->unk-1; - temp_v1 = phi_v1_2 - 0xC; - temp_v0_4->unk-3 = temp_v0_4->unk-6; - temp_v0_4->unk-7 = temp_v0_4->unk-A; - temp_v0_4->unk-8 = temp_v0_4->unk-B; - temp_v0_4->unk-2 = temp_v0_4->unk-5; - temp_v0_4->unk-1 = temp_v0_4->unk-4; - temp_v0_4->unk-6 = temp_v0_4->unk-9; - temp_v0_4->unk-5 = temp_t8; - temp_v0_4->unk-4 = temp_t9; - temp_v0_4->unk-9 = temp_v0_4->unk-C; - temp_v0_4->unk2 = temp_t3; - phi_v1_2 = temp_v1; - } while ((phi_s1_2 * 3) != temp_v1); - } - } - populate_time_trial_record(temp_a3, arg0, arg1, temp_a3); - temp_s2->unk12 = 1; - func_800B45E0(sp30); - return phi_s1_2; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B5020.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 792017ad9d422c2467bd42686f383a5c41f41c75 -? populate_time_trial_record(u8 *, u32, s32, s32); /* extern */ -extern ? D_8018CA74; -s8 gCharacterSelections[4]; /* unable to generate initializer; const */ - -s32 func_800B5218(void) { - s32 sp38; - s32 sp28; - s32 sp24; - u8 *sp20; - struct_8018CA70_entry *sp18; - ? *temp_a1; - s32 temp_a0; - s32 temp_v0; - s32 temp_v1; - u32 temp_a1_2; - u8 *temp_v0_2; - ? *phi_a1; - struct_8018CA70_entry *phi_a2; - s32 phi_v0; - struct_8018CA70_entry *phi_a2_2; - s32 phi_a3; - s32 phi_v0_2; - s32 phi_a3_2; - - sp38 = (gCupSelection * 4) + gCupCourseSelection; - sp28 = (s32) *gCharacterSelections; - phi_a1 = &D_8018CA74; - phi_a2 = D_8018CA70; - phi_v0 = 1; - phi_a3_2 = 1; - do { - temp_v1 = phi_a1->unk20; - temp_a0 = phi_a2->lap1Duration; - phi_a2_2 = phi_a2; - phi_a3 = phi_a3_2; - if (temp_v1 < temp_a0) { - phi_a2_2 = (phi_v0 * 4) + D_8018CA70; - phi_a3 = 1 << phi_v0; - } else if (temp_a0 == temp_v1) { - phi_a3 = phi_a3_2 | (1 << phi_v0); - } - temp_v0 = phi_v0 + 1; - temp_a1 = phi_a1 + 4; - phi_a1 = temp_a1; - phi_a2 = phi_a2_2; - phi_v0 = temp_v0; - phi_a3_2 = phi_a3; - } while (temp_v0 != 3); - sp18 = phi_a2_2; - sp24 = phi_a3; - temp_a1_2 = phi_a2_2->lap1Duration; - phi_v0_2 = 0; - if (temp_a1_2 < (u32) (func_800B4F2C(temp_a0, temp_a1, phi_a2_2, phi_a3) & 0xFFFFF)) { - temp_v0_2 = &D_8018EB90.allCourseTimeTrialRecords.cupRecords[sp38].courseRecords[sp38].records[0]; - sp20 = temp_v0_2; - sp24 = phi_a3; - populate_time_trial_record(temp_v0_2 + 0xF, temp_a1_2, sp28, phi_a3); - temp_v0_2->unk12 = 1; - func_800B45E0(sp38); - phi_v0_2 = sp24; - } - return phi_v0_2; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B5218.s") -#endif - -void func_800B536C(s32 arg0) { - u8* points; - u8 tmp; - s32 tmp2; - - if (arg0 >= 0) { - points = &D_8018EB90.grandPrixPoints[gCCSelection]; - - tmp = func_800B54EC(gCupSelection, *points); - tmp2 = 3 - arg0; - if ((arg0 < 3) && (tmp < (3-arg0))) { - *points = func_800B5508(gCupSelection, *points, tmp2); - write_save_data_grand_prix_points_and_sound_mode(); - update_save_data_backup(); - } - } -} - -void func_800B5404(s32 arg0, s32 arg1) -{ - u8 *points; - s32 temp_a0; - s32 temp; - int temp2; - UNUSED s32 pad; - - if (arg0 >= 0) { - temp2 = arg1 / 4; - points = &D_8018EB90.grandPrixPoints[arg1 % 4]; - temp = func_800B54EC(temp2, *points); - - if ((arg0 < 3) && (temp < (temp_a0 = 3 - arg0))) { - *points = func_800B5508(temp2, *points, temp_a0); - - write_save_data_grand_prix_points_and_sound_mode(); - update_save_data_backup(); - } - } -} - -// Get Grand Prix points for a given cup and CC mode -u8 func_800B54C0(s32 cup, s32 cc_mode) { - return func_800B54EC(cup, D_8018ED10.grandPrixPointsArray[cc_mode]); -} - -// Get Grand Prix points scored for a given cup -u8 func_800B54EC(s32 cup, s32 ccGrandPrixPoints) { - s32 cup_index = cup * 2; - u32 cup_points = ccGrandPrixPoints; - - cup_points &= (3 << cup_index); - cup_points >>= cup_index; - cup_points &= 0xFF; - - return cup_points; -} - -// Generate a new CC Grand Prix Points entry with points_scored -// placed in the given cup's location -u8 func_800B5508(s32 cup, s32 ccGrandPrixPoints, s32 points_scored) { - s32 cup_index = cup * 2; - - points_scored <<= cup_index; - ccGrandPrixPoints &= ~(3 << cup_index); - - return (ccGrandPrixPoints | points_scored); -} - -// Check if all 4 cups have gold cups scored -// for a given CC mode -s32 func_800B5530(s32 cc_mode) { - if (D_8018ED10.grandPrixPointsArray[cc_mode] == 0xFF) { - return 1; - } - return 0; -} - -// Check if the 150CC mode has all 4 gold cups -s32 func_800B555C(void) { - return func_800B5530(CC_150); -} - -// Check if the Extra mode has all 4 gold cups -s32 func_800B557C(void) { - return func_800B5530(CC_EXTRA); -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B4874(s32, void *, void *); // extern -s8 func_800B578C(s32, void *, void *); // extern -s8 func_800B5888(s32); // extern -extern u8 D_800F2E60; -extern ? D_8018EB90; -extern OSMesgQueue gSIEventMesgQueue; - -void func_800B559C(s32 arg0, void *arg1, void *arg2) { - s32 temp_s1; - s32 temp_s1_2; - s32 temp_s6; - s32 temp_v0; - s32 temp_v0_2; - u8 *temp_s2_2; - void *temp_a0; - void *temp_a1; - void *temp_a1_2; - void *temp_a2; - void *temp_s2; - void *temp_v1; - void *temp_v1_2; - s32 phi_s1; - void *phi_a1; - void *phi_a2; - u8 *phi_a0; - s32 phi_v0; - s32 phi_v0_2; - void *phi_a1_2; - void *phi_a2_2; - void *phi_a1_3; - - temp_s6 = arg0 / 8; - temp_s1 = temp_s6 * 8; - phi_s1 = temp_s1; - phi_a1 = arg1; - phi_a2 = arg2; - phi_a1_2 = arg1; - phi_a2_2 = arg2; - if (temp_s1 < (temp_s1 + 8)) { - temp_s2 = (temp_s6 * 0x38) + 0x188 + &D_8018EB90; - do { - temp_a2 = &D_8018EB90 + ((phi_s1 / 4) * 0x60) + ((phi_s1 % 4) * 0x18); - phi_a2 = temp_a2; - phi_a0 = &D_800F2E60; - phi_v0 = 0; - phi_v0_2 = 0; - phi_a2_2 = temp_a2; - if (temp_a2->unk17 != func_800B4874(phi_s1, phi_a1, phi_a2)) { - temp_a1 = temp_s2 + ((phi_s1 % 8) * 3); - phi_a1_3 = temp_a1; - do { - temp_v1 = temp_a1 + phi_v0; - temp_v0 = phi_v0 + 1; - temp_v1->unk0 = *phi_a0; - temp_v1->unk18 = *phi_a0; - phi_a0 += 1; - phi_v0 = temp_v0; - } while (temp_v0 != 3); - } else { - temp_a1_2 = temp_s2 + ((phi_s1 % 8) * 3); - phi_a1_3 = temp_a1_2; - do { - temp_a0 = temp_a2 + phi_v0_2; - temp_v1_2 = temp_a1_2 + phi_v0_2; - temp_v0_2 = phi_v0_2 + 1; - temp_v1_2->unk0 = temp_a0->unk0; - temp_v1_2->unk18 = temp_a0->unkF; - phi_v0_2 = temp_v0_2; - } while (temp_v0_2 != 3); - } - temp_s1_2 = phi_s1 + 1; - phi_s1 = temp_s1_2; - phi_a1 = phi_a1_3; - phi_a1_2 = phi_a1_3; - } while (temp_s1_2 < ((temp_s6 * 8) + 8)); - } - temp_s2_2 = &D_8018EB90 + (temp_s6 * 0x38) + 0x188; - temp_s2_2->unk36 = func_800B578C(temp_s6, phi_a1_2, phi_a2_2); - temp_s2_2->unk37 = func_800B5888(temp_s6); - osEepromLongWrite(&gSIEventMesgQueue, ((temp_s2_2 - &D_8018EB90) >> 3) & 0xFF, temp_s2_2, 0x38); -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B559C.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern ? D_8018EB90; - -s32 func_800B578C(s32 arg0) { - s32 temp_a0; - s32 temp_a1; - s32 temp_v1; - u8 *temp_a2; - void *temp_a3; - s32 phi_a0; - s32 phi_v0; - s32 phi_v1; - void *phi_a3; - s32 phi_v1_2; - u8 *phi_t0; - u8 *phi_a2; - - temp_a2 = (arg0 * 0x38) + 0x188 + &D_8018EB90; - phi_v0 = 0; - phi_v1_2 = 0; - phi_t0 = temp_a2; - phi_a2 = temp_a2; - do { - temp_a1 = phi_v0 + 1; - phi_a0 = 1; - phi_v0 = temp_a1; - phi_v1 = phi_v1_2 + ((*phi_t0 + 1) * temp_a1); - phi_a3 = phi_a2 + 1; - phi_a2 += 0x11; -loop_2: - temp_a3 = phi_a3 + 4; - temp_a0 = phi_a0 + 4; - temp_v1 = phi_v1 + ((phi_a3->unk0 + 1) * temp_a1) + phi_a0 + ((phi_a3->unk1 + 1) * temp_a1) + phi_a0 + 1 + ((temp_a3->unk-2 + 1) * temp_a1) + phi_a0 + 2 + ((temp_a3->unk-1 + 1) * temp_a1) + phi_a0 + 3; - phi_a0 = temp_a0; - phi_v1 = temp_v1; - phi_a3 = temp_a3; - phi_v1_2 = temp_v1; - if (temp_a0 != 0x11) { - goto loop_2; - } - phi_t0 += 0x11; - } while (temp_a1 != 3); - return (temp_v1 % 0x100) & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B578C.s") -#endif - -s32 func_800B5888(s32 arg0) { - s32 tmp = ((*(&D_8018ED4E + (arg0 * sizeof(OnlyBestTimeTrialRecords))) + 90)); - return (tmp % 256) & 0xFF; -} - -s32 func_800B58C4(s32 arg0) -{ - UNUSED s32 pad1; - OnlyBestTimeTrialRecords *temp_v1; - UNUSED s32 pad2; - UNUSED s32 pad3; - - temp_v1 = &D_8018EB90.onlyBestTimeTrialRecords[arg0 / 8]; - if ((temp_v1->unknownBytes[6] != (func_800B578C(arg0 / 8) ^ 0)) || (temp_v1->unknownBytes[7] != (func_800B5888(arg0 / 8) ^ 0))) - { - return 1; - } - - return 0; -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s8 compute_save_data_checksum_backup_1(); // extern -s8 compute_save_data_checksum_backup_2(); // extern -extern ? D_8018EB90; -extern union GrandPrixPointsUnion D_8018ED10; -extern u8 D_8018ED11; -extern u8 D_8018ED12; -extern u8 D_8018ED13; -extern u8 gSaveDataSoundMode; -extern union GrandPrixPointsUnion D_8018ED88; -extern u8 D_8018ED89; -extern u8 D_8018ED8A; -extern u8 D_8018ED8B; -extern u8 gSaveDataSoundModeBackup; -extern s8 D_8018ED8E; -extern s8 D_8018ED8F; -extern OSMesgQueue gSIEventMesgQueue; - -void update_save_data_backup(void) { - D_8018ED88.grandPrixPointsMushroomCup = D_8018ED10.grandPrixPointsMushroomCup; - D_8018ED89 = D_8018ED11; - D_8018ED8A = D_8018ED12; - D_8018ED8B = D_8018ED13; - gSaveDataSoundModeBackup = gSaveDataSoundMode; - D_8018ED8E = compute_save_data_checksum_backup_1(); - D_8018ED8F = compute_save_data_checksum_backup_2(); - osEepromLongWrite(&gSIEventMesgQueue, ((&D_8018ED88 - &D_8018EB90) >> 3) & 0xFF, &D_8018ED88, 8); -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B5948.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern union GrandPrixPointsUnion D_8018ED88; - -s32 compute_save_data_checksum_backup_1(void) { - void *temp_a0; - - temp_a0 = &D_8018ED88 + 1; - return ((D_8018ED88.grandPrixPointsMushroomCup + 1 + ((temp_a0->unk0 + 1) * 2) + 1 + ((temp_a0->unk1 + 1) * 3) + 1 + 1 + ((temp_a0->unk2 + 1) * 4) + 1 + 2 + ((temp_a0->unk3 + 1) * 5) + 1 + 3) % 0x100) & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B59F4.s") -#endif - -s32 compute_save_data_checksum_backup_2(void) { - s32 tmp = D_8018ED8E + 90; - return (tmp % 256) & 0xFF; -} - -s32 validate_save_data_checksum_backup(void) -{ - if ((D_8018ED8E != (compute_save_data_checksum_backup_1() ^ 0)) || (D_8018ED8F != (compute_save_data_checksum_backup_2() ^ 0))) { - return 1; - } - - return 0; -} - -// Check if controller has a Controller Pak connected. -// Return 1 if it does, otherwise return 0. -s32 check_for_controller_pak(s32 controller) { - u8 sp1F; - UNUSED s32 phi_v0; - - if ((controller >= 4) || (controller < 0)) { - return 0; - } - - osPfsIsPlug(&gSIEventMesgQueue, &sp1F); - - if ((sp1F & (1 << controller)) != 0) { - return 1; - } - - return 0; -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 check_for_controller_pak(s32); // extern -s32 osPfsInit(? *, OSPfs *, ?); // extern -extern u16 D_800E86F0; -extern u32 D_800E86F4; -extern s8 D_800E86F8; -extern u8 D_800F2E64; -extern u8 D_800F2E74; -extern OSPfs D_8018E868; -extern s32 D_8018EB78; -extern s32 D_8018EB7C; -extern s32 gControllerPakNumPagesFree; -extern s32 D_8018EB84; -extern ? gSIEventMesgQueue; - -? func_800B5B94(void) { - s32 temp_v0_2; - s32 temp_v0_3; - s8 temp_v0; - s8 phi_v0; - ? phi_v0_2; - - temp_v0 = D_800E86F8; - phi_v0 = temp_v0; - if (temp_v0 != 0) { - temp_v0_2 = osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84); - if (temp_v0_2 != 0) { - if (temp_v0_2 != 2) { - if (temp_v0_2 != 5) { - D_800E86F8 = 0; - goto block_8; - } - phi_v0 = D_800E86F8; - } else { - D_800E86F8 = 0; -block_8: - phi_v0 = 0; - } - goto block_9; - } - return 0; - } -block_9: - if (phi_v0 == 0) { - if (check_for_controller_pak(0) == 0) { - return 1; - } - temp_v0_3 = osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0); - if (temp_v0_3 != 0) { - if (temp_v0_3 != 1) { - if (temp_v0_3 != 4) { - if (temp_v0_3 != 0xA) { - if (temp_v0_3 == 0xB) { - goto block_17; - } - goto block_19; - } - return 2; - } -block_19: - return 2; - } -block_17: - return 1; - } - D_800E86F8 = 1; - if (osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84) == 0) { - return 0; - } - if (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) != 0) { - return 2; - } - if (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) != 0) { - return 2; - } - gControllerPakNumPagesFree = gControllerPakNumPagesFree >> 8; - goto block_27; - } -block_27: - if (D_8018EB7C >= D_8018EB78) { - return 4; - } - phi_v0_2 = 4; - if (gControllerPakNumPagesFree >= 0x79) { - phi_v0_2 = -1; - } - return phi_v0_2; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B5B94.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 check_for_controller_pak(?); // extern -s32 osPfsInit(? *, OSPfs *, ?); // extern -extern u16 D_800E86F0; -extern u32 D_800E86F4; -extern s8 D_800E86FC; -extern u8 D_800F2E64; -extern u8 D_800F2E74; -extern OSPfs D_8018E8D0; -extern s32 D_8018EB88; -extern ? gSIEventMesgQueue; - -s8 func_800B5DA4(void) { - s32 temp_v0_2; - s32 temp_v0_3; - s32 temp_v0_4; - s8 temp_v0; - s8 phi_v0; - s8 phi_v0_2; - - temp_v0 = D_800E86FC; - phi_v0 = temp_v0; - if (temp_v0 != 0) { - temp_v0_2 = osPfsFindFile(&D_8018E8D0, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB88); - if (temp_v0_2 != 0) { - if (temp_v0_2 != 2) { - if (temp_v0_2 != 5) { - goto block_7; - } - return -1; - } -block_7: - D_800E86FC = 0; - phi_v0 = 0; - goto block_8; - } - return 0; - } -block_8: - phi_v0_2 = phi_v0; - if (phi_v0 == 0) { - if (check_for_controller_pak(1) == 0) { - return 1; - } - temp_v0_3 = osPfsInit(&gSIEventMesgQueue, &D_8018E8D0, 1); - if (temp_v0_3 != 0) { - if (temp_v0_3 != 1) { - if (temp_v0_3 != 4) { - if (temp_v0_3 != 0xA) { - if (temp_v0_3 == 0xB) { - goto block_16; - } - goto block_18; - } - goto block_25; - } -block_18: - goto block_25; - } -block_16: - return 1; - } - D_800E86FC = 1; - temp_v0_4 = osPfsFindFile(&D_8018E8D0, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB88); - if (temp_v0_4 != 0) { - if (temp_v0_4 != 2) { - if (temp_v0_4 != 5) { - goto block_25; - } - return -1; - } -block_25: - phi_v0_2 = 2; - // Duplicate return node #26. Try simplifying control flow for better match - return phi_v0_2; - } - return 0; - } - return phi_v0_2; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B5DA4.s") -#endif - -s32 func_800B5F30(void) { - s32 sp1C; - - if (D_800E86F8 != 0) { - return -4; - } - if (check_for_controller_pak(0) != 0) { - sp1C = osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0); - if (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) != 0) { - D_800E86F8 = 0; - return -2; - } - if (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) != 0) { - D_800E86F8 = 0; - return -3; - } - gControllerPakNumPagesFree = gControllerPakNumPagesFree >> 8; - if (sp1C == 0) { - D_800E86F8 = 1; - } - return sp1C; - } - return -1; -} - -s32 func_800B6014(void) { - s32 temp_v0; - - if (D_800E86FC != 0) { - return -4; - } - if (check_for_controller_pak(1) != 0) { - temp_v0 = osPfsInit(&gSIEventMesgQueue, &D_8018E8D0, 1); - if (temp_v0 == 0) { - D_800E86FC = 1; - } - return temp_v0; - } - return -1; -} - -s32 func_800B6088(s32 arg0) { - struct_8018EE10_entry* temp_v1; - - temp_v1 = &D_8018EE10[arg0]; - temp_v1->checksum = func_800B6828(arg0); - return osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_WRITE, arg0 * 0x80 /* 0x80 == sizeof(struct_8018EE10_entry) */, sizeof(struct_8018EE10_entry), (u8*) temp_v1); -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern s32 D_800DC714; - -s32 func_800B60E8(s32 arg0) { - s32 temp_a2; - s32 temp_v0; - s32 temp_v1; - s32 phi_v0; - s32 phi_v1; - void *phi_a1; - - temp_a2 = arg0 + 1; - phi_v0 = 0; - phi_v1 = 0; - phi_a1 = D_800DC714 + (arg0 << 8); - do { - temp_v0 = phi_v0 + 4; - temp_v1 = phi_v1 + ((phi_a1->unk0 * temp_a2) + phi_v0) + ((phi_a1->unk1 * temp_a2) + phi_v0) + 1 + ((phi_a1->unk2 * temp_a2) + phi_v0) + 2 + ((phi_a1->unk3 * temp_a2) + phi_v0) + 3; - phi_v0 = temp_v0; - phi_v1 = temp_v1; - phi_a1 += 4; - } while (temp_v0 != 0x100); - return temp_v1 & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B60E8.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_800051C4(); // extern -s32 func_800B6088(s32); // extern -s8 func_800B60E8(s32); // extern -extern u8 *D_800DC714; -extern s32 D_80162DFC; -extern OSPfs D_8018E868; -extern s32 D_8018EB84; -extern ? D_8018EE10; -extern s8 gCupSelection; - -s32 func_800B6178(s32 arg0) { - s32 temp_s0_2; - s32 temp_v0; - s32 temp_v0_2; - s32 temp_v0_3; - s32 temp_v1; - s8 temp_s0; - s8 temp_s0_3; - void *temp_s1; - void *temp_s3; - s8 phi_s0; - void *phi_s1; - s32 phi_s0_2; - void *phi_s1_2; - s32 phi_v0; - s8 phi_s0_3; - void *phi_s1_3; - s32 phi_v1; - - if ((arg0 != 0) && (arg0 != 1)) { - return -1; - } - if (D_800DC50C == RACING) { - func_800051C4(); - } - temp_s3 = (arg0 << 7) + &D_8018EE10; - temp_s3->unk4 = 0; - temp_v0 = func_800B6088(arg0); - temp_v1 = temp_v0; - phi_v1 = temp_v1; - if (temp_v0 != 0) { - temp_s3->unk4 = 0; - phi_s0 = 0; - phi_s1 = temp_s3; - do { - phi_s1->unk7 = phi_s0; - temp_s0 = phi_s0 + 4; - phi_s1->unkA = phi_s0 + 3; - phi_s1->unk9 = phi_s0 + 2; - phi_s1->unk8 = phi_s0 + 1; - phi_s0 = temp_s0; - phi_s1 += 4; - } while (temp_s0 != 0x3C); - } else { - temp_v0_2 = osPfsReadWriteFile(&D_8018E868, D_8018EB84, 1, (arg0 * 0x3C00) + 0x100, 0x3C00, D_800DC714); - phi_v0 = temp_v0_2; - phi_v1 = temp_v0_2; - if (temp_v0_2 == 0) { - temp_s3->unk4 = 1; - if (D_800DC50C == RACING) { - temp_s3->unk5 = (gCupSelection * 4) + gCupCourseSelection; - } - temp_s3->unk0 = D_80162DFC; - temp_s3->unk6 = D_80162DE0; - phi_s0_2 = 0; - phi_s1_2 = temp_s3; - do { - temp_s0_2 = phi_s0_2 + 1; - temp_s1 = phi_s1_2 + 1; - temp_s1->unk6 = func_800B60E8(phi_s0_2); - phi_s0_2 = temp_s0_2; - phi_s1_2 = temp_s1; - } while (temp_s0_2 != 0x3C); - temp_v0_3 = func_800B6088(arg0); - phi_v0 = temp_v0_3; - phi_v1 = temp_v0_3; - } - if (phi_v0 != 0) { - temp_s3->unk4 = 0; - phi_s0_3 = 0; - phi_s1_3 = temp_s3; - do { - phi_s1_3->unk7 = phi_s0_3; - temp_s0_3 = phi_s0_3 + 4; - phi_s1_3->unkA = phi_s0_3 + 3; - phi_s1_3->unk9 = phi_s0_3 + 2; - phi_s1_3->unk8 = phi_s0_3 + 1; - phi_s0_3 = temp_s0_3; - phi_s1_3 += 4; - } while (temp_s0_3 != 0x3C); - } - } - return phi_v1; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B6178.s") -#endif - -s32 func_800B6348(s32 arg0) { - if ((D_8018EE10[0].ghostDataSaved != 0) && (arg0 == D_8018EE10[0].courseIndex)) { - return 0; - } - if ((D_8018EE10[1].ghostDataSaved != 0) && (arg0 == D_8018EE10[1].courseIndex)) { - return 1; - } - return 0; -} - -s32 func_800B639C(s32 arg0) { - if ((D_8018EE10[0].ghostDataSaved != 0) && (arg0 == D_8018EE10[0].courseIndex)) { - return 0; - } - if ((D_8018EE10[1].ghostDataSaved != 0) && (arg0 == D_8018EE10[1].courseIndex)) { - return 1; - } - return -1; -} - -s32 func_800B63F0(s32 arg0) { - s32 temp_s0; - u8* phi_s1; - s32 phi_s3; - - func_800051C4(); - D_80162DD6 = 1; - func_80005AE8(gPlayerThree); - - phi_s3 = 0; - if (((gCupSelection * 4) + gCupCourseSelection) != D_8018EE10[arg0].courseIndex) { - phi_s3 = 2; - } else if (D_80162DFC != D_8018EE10[arg0].unk_00) { - phi_s3 = 3; - } else { - if (D_80162DE0 != (u8) D_8018EE10[arg0].characterId) { - phi_s3 = 4; - } else { - temp_s0 = 0; - phi_s1 = (u8*) &D_8018EE10[arg0]; - - while (temp_s0 < 0x3C) - { - if (phi_s1[7] != func_800B60E8(temp_s0)) { - phi_s3 = 1; - break; - } - - ++phi_s1; - ++temp_s0; - } - } - } - - return phi_s3; -} - -s32 func_800B64EC(s32 arg0) { - s32 temp_s0; - s32 temp_v0; - u8 *phi_s1; - - if ((arg0 != 0) && (arg0 != 1)) - { - return -1; - } - - temp_v0 = osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_READ, (arg0 * 0x3C00) + 0x100, 0x3C00, (u8 *) D_800DC714); - if (temp_v0 == 0) - { - phi_s1 = (u8 *) &D_8018EE10[arg0]; temp_s0 = 0; while (1) { - - if (phi_s1[7] != func_800B60E8(temp_s0)) { - D_8018EE10[arg0].ghostDataSaved = 0; - return -2; - } - - ++phi_s1; - if ((++temp_s0) == 0x3C) { - func_8000522C(); - D_80162DD4[0] = 0; - D_80162DE0 = (s32) D_8018EE10[arg0].characterId; - D_80162DFC = D_8018EE10[arg0].unk_00; - break; - } - } - - } - - return temp_v0; -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s32 func_800B60E8(s32); // extern -extern u8 *D_800DC714; -extern s32 D_80162DFC; -extern s32 D_8018D9C0; -extern OSPfs D_8018E8D0; -extern s32 D_8018EB88; -extern ? D_8018EE15; - -s32 func_800B65F4(s32 arg0, s32 arg1) { - s32 sp34; - s32 temp_s0; - s32 temp_v0; - void *temp_s3; - s32 phi_s0; - void *phi_s1; - - if ((arg0 != 0) && (arg0 != 1)) { - return -1; - } - temp_v0 = osPfsReadWriteFile(&D_8018E8D0, D_8018EB88, 0, (arg0 * 0x3C00) + 0x100, 0x3C00, D_800DC714); - sp34 = temp_v0; - if (temp_v0 == 0) { - temp_s3 = D_8018D9C0 + (arg0 << 7); - phi_s0 = 0; - phi_s1 = temp_s3; -loop_5: - temp_s0 = phi_s0 + 1; - phi_s0 = temp_s0; - if (phi_s1->unk7 != func_800B60E8(phi_s0)) { - temp_s3->unk4 = 0; - return -2; - } - phi_s1 += 1; - if (temp_s0 == 0x3C) { - D_80162DE0 = temp_s3->unk6; - D_80162DFC = temp_s3->unk0; - *(&D_8018EE15 + (arg1 << 7)) = temp_s3->unk5; - goto block_9; - } - goto loop_5; - } -block_9: - return sp34; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B65F4.s") -#endif - -void func_800B6708(void) { - s32 temp_s0; - - osPfsReadWriteFile(&D_8018E868, D_8018EB84, PFS_READ, 0, 0x100 /* 2*sizeof(struct_8018EE10_entry) ? */, (u8*) &D_8018EE10); - - for (temp_s0 = 0; temp_s0 < 2; ++temp_s0) { - if (D_8018EE10[temp_s0].checksum != func_800B6828(temp_s0)) { - D_8018EE10[temp_s0].ghostDataSaved = 0; - } - } -} - -void func_800B6798(void) { - s32 temp_s0; - u8* tmp; - - tmp = (u8*) D_8018D9C0; - - osPfsReadWriteFile(&D_8018E8D0, D_8018EB88, PFS_READ, 0, 0x100 /* 2*sizeof(struct_8018EE10_entry) ? */, tmp); - - for (temp_s0 = 0; temp_s0 < 2; ++temp_s0) { - // if (D_8018D9C0[temp_s0]->checksum != func_800B68F4(temp_s0)) { - // D_8018D9C0[temp_s0]->ghostDataSaved = 0; - // } - if ( ((struct_8018EE10_entry*) (tmp + (temp_s0 << 7)))->checksum != func_800B68F4(temp_s0)) { - ((struct_8018EE10_entry*) (tmp + (temp_s0 << 7)))->ghostDataSaved = 0; - } - } -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern ? D_8018EE10; - -s32 func_800B6828(s32 arg0) { - s32 temp_a1; - s32 temp_a2; - s32 temp_v1; - void *temp_v0; - s32 phi_a1; - s32 phi_v1; - void *phi_a3; - - temp_v0 = (arg0 << 7) + &D_8018EE10; - temp_a2 = arg0 + 1; - phi_a1 = 3; - phi_v1 = (temp_v0->unk0 * temp_a2) + (temp_v0->unk1 * temp_a2) + 1 + (temp_v0->unk2 * temp_a2) + 2; - phi_a3 = temp_v0 + 3; - do { - temp_a1 = phi_a1 + 4; - temp_v1 = phi_v1 + ((phi_a3->unk0 * temp_a2) + phi_a1) + ((phi_a3->unk1 * temp_a2) + phi_a1) + 1 + ((phi_a3->unk2 * temp_a2) + phi_a1) + 2 + ((phi_a3->unk3 * temp_a2) + phi_a1) + 3; - phi_a1 = temp_a1; - phi_v1 = temp_v1; - phi_a3 += 4; - } while (temp_a1 != 0x43); - return temp_v1 & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B6828.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -extern s32 D_8018D9C0; - -s32 func_800B68F4(s32 arg0) { - s32 temp_a1; - s32 temp_a2; - s32 temp_a3; - void *temp_v0; - void *temp_v1; - s32 phi_a2; - s32 phi_a1; - - temp_a3 = arg0 + 1; - temp_v1 = (arg0 << 7) + D_8018D9C0; - phi_a2 = 3; - phi_a1 = (temp_v1->unk0 * temp_a3) + (temp_v1->unk1 * temp_a3) + 1 + (temp_v1->unk2 * temp_a3) + 2; - do { - temp_v0 = temp_v1 + phi_a2; - temp_a2 = phi_a2 + 4; - temp_a1 = phi_a1 + ((temp_v0->unk0 * temp_a3) + phi_a2) + ((temp_v0->unk1 * temp_a3) + phi_a2) + 1 + ((temp_v0->unk2 * temp_a3) + phi_a2) + 2 + ((temp_v0->unk3 * temp_a3) + phi_a2) + 3; - phi_a2 = temp_a2; - phi_a1 = temp_a1; - } while (temp_a2 != 0x43); - return temp_a1 & 0xFF; -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B68F4.s") -#endif - -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -s8 func_800B6828(s32, s32, s32); // extern -extern OSPfs D_8018E868; -extern s32 D_8018EB84; -extern ? D_8018EE10; - -void func_800B69BC(s32 arg0) { - s32 sp24; - u8 *sp20; - s32 temp_a3; - s8 temp_v0; - u8 *temp_t0; - s8 phi_v0; - u8 *phi_v1; - - temp_a3 = arg0 << 7; - temp_t0 = temp_a3 + &D_8018EE10; - temp_t0->unk4 = 0; - temp_t0->unk5 = 0; - temp_t0->unk6 = 0; - phi_v0 = 0; - phi_v1 = temp_t0; - do { - phi_v1->unk7 = phi_v0; - temp_v0 = phi_v0 + 4; - phi_v1->unkA = phi_v0 + 3; - phi_v1->unk9 = phi_v0 + 2; - phi_v1->unk8 = phi_v0 + 1; - phi_v0 = temp_v0; - phi_v1 += 4; - } while (temp_v0 != 0x3C); - sp24 = temp_a3; - sp20 = temp_t0; - temp_t0->unk7F = func_800B6828(arg0, arg0, temp_a3); - osPfsReadWriteFile(&D_8018E868, D_8018EB84, 1, temp_a3, 0x80, temp_t0); -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B69BC.s") -#endif - -s32 func_800B6A68(void) { - UNUSED s32 pad; - s32 sp30; - s32 temp_s0; - - sp30 = osPfsAllocateFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, 0x7900, &D_8018EB84); - if (sp30 == 0) { - temp_s0 = 0; - while (temp_s0 < 2) - { - func_800B69BC(temp_s0); - ++temp_s0; - } - } - - return sp30; -} - -#ifdef MIPS_TO_C -//generated by mips_to_c commit cc33060578851a93591ed035e96ffd1f15c765f1 -s32 check_for_controller_pak(?); /* extern */ -? func_800B6A68(); /* extern */ -s32 osPfsInit(? *, ? *, ?); /* extern */ -s32 osPfsFindFile(? *, u16, s32, ? *, ? *, ? *); /* extern */ -s32 osPfsFreeBlocks(? *, s32 *); /* extern */ -s32 osPfsNumFiles(? *, s32 *, s32 *); /* extern */ -extern u16 D_800E86F0; -extern s32 D_800E86F4; -extern ? D_800F2E64; -extern ? D_800F2E74; -extern ? D_8018E868; -extern s32 D_8018EB78; -extern s32 D_8018EB7C; -extern ? D_8018EB84; -extern s32 gControllerPakNumPagesFree; -extern ? gSIEventMesgQueue; - -// Separated from assembly in menus/func_800B6A68.s -UNUSED void func_800B6AF8(void) { - s32 temp_t1; - - if ((check_for_controller_pak(0) != 0) && (osPfsInit(&gSIEventMesgQueue, &D_8018E868, 0) == 0) && (osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, &D_800F2E64, &D_800F2E74, &D_8018EB84) != 0) && (osPfsNumFiles(&D_8018E868, &D_8018EB78, &D_8018EB7C) == 0) && (D_8018EB7C < D_8018EB78) && (osPfsFreeBlocks(&D_8018E868, &gControllerPakNumPagesFree) == 0)) { - temp_t1 = (s32) gControllerPakNumPagesFree >> 8; - gControllerPakNumPagesFree = temp_t1; - if (temp_t1 >= 0x79) { - func_800B6A68(); - } - } -} -#else -GLOBAL_ASM("asm/non_matchings/menus/func_800B6AF8.s") -#endif diff --git a/src/menus.h b/src/menus.h index 6d5d97a5e..817924e92 100644 --- a/src/menus.h +++ b/src/menus.h @@ -4,17 +4,9 @@ #include "PR/os.h" #include "common_structs.h" #include - -union GrandPrixPointsUnion -{ - u8 grandPrixPointsArray[4]; - u8 grandPrixPointsMushroomCup; -}; +#include /* Function Prototypes */ - -void func_800AF9B0(); -void func_800B0004(); void func_800B053C(struct Controller*, u16); void func_800B13B0(struct Controller*, u16); void func_800B15AC(struct Controller*, u16); @@ -25,131 +17,21 @@ void func_800B29D8(struct Controller*, u16); s32 func_800B34E8(s32); void func_800B3554(struct Controller*, u16); void func_800B3B58(struct Controller*, u16); -void func_800B44AC(); -void func_800B44BC(); -s32 func_800B4520(); -void func_800B45E0(s32); -void write_save_data_grand_prix_points_and_sound_mode(); -void func_800B46D0(); -void func_800B4728(s32); -void reset_save_data_grand_prix_points_and_sound_mode(); -s32 func_800B4874(s32); -s32 func_800B639C(s32); -s32 compute_save_data_checksum_1(); -s32 compute_save_data_checksum_2(); -void func_800B4A10(); -void func_800B4A9C(s32); -void validate_save_data(void); -s32 func_800B4E24(s32); -s32 func_800B4EB4(s32, s32); -s32 func_800B4F2C(); -s32 func_800B4FB0(s32); -u8 func_800B54C0(s32, s32); -u8 func_800B54EC(s32, s32); -u8 func_800B5508(s32, s32, s32); -s32 func_800B5530(s32); -s32 func_800B555C(); -s32 func_800B557C(); -void func_800B559C(s32); -s32 func_800B578C(s32); -s32 func_800B5888(s32); -void update_save_data_backup(); -s32 compute_save_data_checksum_backup_1(void); -s32 compute_save_data_checksum_backup_2(void); -s32 validate_save_data_checksum_backup(); -s32 func_800B5B2C(s32); -s32 func_800B5F30(); -s32 func_800B6014(); -u8 func_800B60E8(s32); -u8 func_800B6828(s32); -u8 func_800B68F4(s32); -void func_800B69BC(s32); -s32 func_800B6A68(); +void func_800B44AC(void); +void func_800B44BC(void); +s32 func_800B4520(void); -// staff_ghosts.c -s32 func_800051C4(); -void func_8000522C(); -void func_80005AE8(Player*); - -// audio/external.c -void play_sound2(s32); -void func_800CA330(s32); -void func_800CA388(s32); - -// os -s32 osPfsInit(OSMesgQueue*, OSPfs*, s32); - -// memory.c -u32 func_802A7B70(u16); - - -/* This is where I'd put my static data, if I had any */ - -extern u16 gEnableDebugMode; // D_800DC520 -extern s32 gCCSelection; // D_800DC538 -extern s32 gModeSelection; // D_800DC53C -extern s32 D_800DC540; -extern s16 gCurrentCourseId; // D_800DC5A0 -extern s32 gIsMirrorMode; // D_800DC5F4 -extern s16 gPlaceItemBoxes; // D_800DC638 -extern u32* D_800DC714; -extern s8 gGameModeRowSelectionForNumPlayers[SELECTED_PLAYER_DEFINES_TOTAL]; // D_800E869B. 0-4 players, game type row selected for each player amoun +/* data */ +// these might not be in this file, but for now... extern s8 gGameModeSubMenuRowSelectionForNumPlayers[SELECTED_PLAYER_DEFINES_TOTAL][MAX_NUM_MAIN_MENU_GAME_TYPES]; // D_800E869D. 0-4 players, 3 possible game types per player amouunt -extern s32 D_800E86A4; -extern s8 gDisplayedControllerPakTableRows[5]; // D_800E86C6 -extern s32 D_800E86E4; -extern u16 D_800E86F0; -extern s32 D_800E86F4; -extern s8 D_800E86F8; -extern s8 D_800E86FC; -extern s32 gGameModeFromNumPlayersAndRowSelection[SELECTED_PLAYER_DEFINES_TOTAL][MAX_NUM_MAIN_MENU_GAME_TYPES]; // D_800F2B60. 0-4 players, 3 possible game types per player amount -extern u8 D_800F2E60[]; -extern u8 D_800F2E64; -extern u8 D_800F2E74; -extern OSMesgQueue gSIEventMesgQueue; // D_8014F0B8 -extern u16 D_80162DD6; -extern s32 D_80162DE0; -extern s32 D_80162DFC; -extern struct_8018EE10_entry* D_8018D9C0; +extern s8 gGameModeRowSelectionForNumPlayers[SELECTED_PLAYER_DEFINES_TOTAL]; // D_800E869B. 0-4 players, game type row selected for each player amoun +extern const s32 gGameModeFromNumPlayersAndRowSelection[SELECTED_PLAYER_DEFINES_TOTAL][MAX_NUM_MAIN_MENU_GAME_TYPES]; // D_800F2B60. 0-4 players, 3 possible game types per player amount +extern s16 gPlaceItemBoxes; // D_800DC638 + extern s32 D_8018E7A8; extern s8 D_8018E7B0; -extern OSPfs D_8018E868; -extern OSPfs D_8018E8D0; -extern OSPfsState D_8018E938[]; -extern s32 D_8018EB38[16]; -extern s32 D_8018EB78; -extern s32 D_8018EB7C; -extern s32 D_8018EB84; -extern s32 D_8018EB88; -extern SaveData D_8018EB90; -extern union GrandPrixPointsUnion D_8018ED10; // Direct reference to the grandPrixPoints section of save data -extern u8 D_8018ED11; -extern u8 D_8018ED12; -extern u8 D_8018ED13; -extern u8 gSaveDataSoundMode; // D_8018ED14 -extern u8 D_8018ED16; // D_8018EB90.checksum[1] -extern u8 D_8018ED17; // D_8018EB90.checksum[2] -extern u8 D_8018ED4E; // D_8018EB90.onlyBestTimeTrialRecords[0].unknownBytes[6] -extern union GrandPrixPointsUnion D_8018ED88; // D_8018EB90.grandPrixPointsBackup[0] -extern u8 D_8018ED89; -extern u8 D_8018ED8A; -extern u8 D_8018ED8B; -extern u8 D_8018ED8E; // D_8018EB90.checksumBackup[1] -extern u8 D_8018ED8F; // D_8018EB90.checksumBackup[2] -extern u32 D_8018EDB8; -extern u32 D_8018EDBC; -extern s8 D_8018EDE5; -extern s8 D_8018EDE6; -extern s8 D_8018EDE7; -extern u8 gSoundMode; // D_8018EDF2 extern s8 D_8018EDF3; -extern s8 gTimeTrialDataCourseIndex; // D_8018EDF7 -extern s8 gCourseRecordsMenuSelection; // D_8018EDF8 extern s8 D_8018EDFB; -extern s32 gMenuTimingCounter; // D_8018EE00 -extern s8 gCupSelection; // D_8018EE09 extern s8 D_8018EE0A; -extern s8 gCupCourseSelection; // D_8018EE0B -extern struct_8018EE10_entry D_8018EE10[]; -#endif // MENUS_H +#endif /* MENUS_H */ diff --git a/src/staff_ghosts.h b/src/staff_ghosts.h new file mode 100644 index 000000000..4d7176450 --- /dev/null +++ b/src/staff_ghosts.h @@ -0,0 +1,12 @@ +#ifndef STAFF_GHOSTS_H +#define STAFF_GHOSTS_H + +#include "PR/os.h" +#include "common_structs.h" +#include + +s32 func_800051C4(); +void func_8000522C(); +void func_80005AE8(Player *); + +#endif /* STAFF_GHOSTS_H */ diff --git a/tools/.gitignore b/tools/.gitignore index fb1b91b63..2d86cf0d5 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -4,3 +4,6 @@ /n64graphics /tkmk00 /extract_data_for_mio + +__pycache__ +*.pyc diff --git a/tools/asm_processor/asm_processor.py b/tools/asm_processor/asm_processor.py new file mode 100644 index 000000000..c750890d6 --- /dev/null +++ b/tools/asm_processor/asm_processor.py @@ -0,0 +1,1330 @@ +#!/usr/bin/env python3 +import argparse +import tempfile +import struct +import copy +import sys +import re +import os +from collections import namedtuple +from io import StringIO + +MAX_FN_SIZE = 100 +SLOW_CHECKS = False + +EI_NIDENT = 16 +EI_CLASS = 4 +EI_DATA = 5 +EI_VERSION = 6 +EI_OSABI = 7 +EI_ABIVERSION = 8 +STN_UNDEF = 0 + +SHN_UNDEF = 0 +SHN_ABS = 0xfff1 +SHN_COMMON = 0xfff2 +SHN_XINDEX = 0xffff +SHN_LORESERVE = 0xff00 + +STT_NOTYPE = 0 +STT_OBJECT = 1 +STT_FUNC = 2 +STT_SECTION = 3 +STT_FILE = 4 +STT_COMMON = 5 +STT_TLS = 6 + +STB_LOCAL = 0 +STB_GLOBAL = 1 +STB_WEAK = 2 + +STV_DEFAULT = 0 +STV_INTERNAL = 1 +STV_HIDDEN = 2 +STV_PROTECTED = 3 + +SHT_NULL = 0 +SHT_PROGBITS = 1 +SHT_SYMTAB = 2 +SHT_STRTAB = 3 +SHT_RELA = 4 +SHT_HASH = 5 +SHT_DYNAMIC = 6 +SHT_NOTE = 7 +SHT_NOBITS = 8 +SHT_REL = 9 +SHT_SHLIB = 10 +SHT_DYNSYM = 11 +SHT_INIT_ARRAY = 14 +SHT_FINI_ARRAY = 15 +SHT_PREINIT_ARRAY = 16 +SHT_GROUP = 17 +SHT_SYMTAB_SHNDX = 18 +SHT_MIPS_GPTAB = 0x70000003 +SHT_MIPS_DEBUG = 0x70000005 +SHT_MIPS_REGINFO = 0x70000006 +SHT_MIPS_OPTIONS = 0x7000000d + +SHF_WRITE = 0x1 +SHF_ALLOC = 0x2 +SHF_EXECINSTR = 0x4 +SHF_MERGE = 0x10 +SHF_STRINGS = 0x20 +SHF_INFO_LINK = 0x40 +SHF_LINK_ORDER = 0x80 +SHF_OS_NONCONFORMING = 0x100 +SHF_GROUP = 0x200 +SHF_TLS = 0x400 + +R_MIPS_32 = 2 +R_MIPS_26 = 4 +R_MIPS_HI16 = 5 +R_MIPS_LO16 = 6 + +MIPS_DEBUG_ST_STATIC = 2 +MIPS_DEBUG_ST_STATIC_PROC = 14 + + +class ElfFormat: + def __init__(self, is_big_endian): + self.is_big_endian = is_big_endian + self.struct_char = ">" if is_big_endian else "<" + + def pack(self, fmt, *args): + return struct.pack(self.struct_char + fmt, *args) + + def unpack(self, fmt, data): + return struct.unpack(self.struct_char + fmt, data) + + +class ElfHeader: + """ + typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; + } Elf32_Ehdr; + """ + + def __init__(self, data): + self.e_ident = data[:EI_NIDENT] + assert self.e_ident[EI_CLASS] == 1 # 32-bit + self.fmt = ElfFormat(is_big_endian=(self.e_ident[EI_DATA] == 2)) + self.e_type, self.e_machine, self.e_version, self.e_entry, self.e_phoff, self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx = self.fmt.unpack('HHIIIIIHHHHHH', data[EI_NIDENT:]) + assert self.e_type == 1 # relocatable + assert self.e_machine == 8 # MIPS I Architecture + assert self.e_phoff == 0 # no program header + assert self.e_shoff != 0 # section header + assert self.e_shstrndx != SHN_UNDEF + + def to_bin(self): + return self.e_ident + self.fmt.pack('HHIIIIIHHHHHH', self.e_type, + self.e_machine, self.e_version, self.e_entry, self.e_phoff, + self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, + self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx) + + +class Symbol: + """ + typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; + } Elf32_Sym; + """ + + def __init__(self, fmt, data, strtab, name=None): + self.fmt = fmt + self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = fmt.unpack('IIIBBH', data) + assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)" + self.bind = st_info >> 4 + self.type = st_info & 15 + self.name = name if name is not None else strtab.lookup_str(self.st_name) + self.visibility = self.st_other & 3 + + @staticmethod + def from_parts(fmt, st_name, st_value, st_size, st_info, st_other, st_shndx, strtab, name): + header = fmt.pack('IIIBBH', st_name, st_value, st_size, st_info, st_other, st_shndx) + return Symbol(fmt, header, strtab, name) + + def to_bin(self): + st_info = (self.bind << 4) | self.type + return self.fmt.pack('IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx) + + +class Relocation: + def __init__(self, fmt, data, sh_type): + self.fmt = fmt + self.sh_type = sh_type + if sh_type == SHT_REL: + self.r_offset, self.r_info = fmt.unpack('II', data) + else: + self.r_offset, self.r_info, self.r_addend = fmt.unpack('III', data) + self.sym_index = self.r_info >> 8 + self.rel_type = self.r_info & 0xff + + def to_bin(self): + self.r_info = (self.sym_index << 8) | self.rel_type + if self.sh_type == SHT_REL: + return self.fmt.pack('II', self.r_offset, self.r_info) + else: + return self.fmt.pack('III', self.r_offset, self.r_info, self.r_addend) + + +class Section: + """ + typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; + } Elf32_Shdr; + """ + + def __init__(self, fmt, header, data, index): + self.fmt = fmt + self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize = fmt.unpack('IIIIIIIIII', header) + assert not self.sh_flags & SHF_LINK_ORDER + if self.sh_entsize != 0: + assert self.sh_size % self.sh_entsize == 0 + if self.sh_type == SHT_NOBITS: + self.data = b'' + else: + self.data = data[self.sh_offset:self.sh_offset + self.sh_size] + self.index = index + self.relocated_by = [] + + @staticmethod + def from_parts(fmt, sh_name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data, index): + header = fmt.pack('IIIIIIIIII', sh_name, sh_type, sh_flags, 0, 0, len(data), sh_link, sh_info, sh_addralign, sh_entsize) + return Section(fmt, header, data, index) + + def lookup_str(self, index): + assert self.sh_type == SHT_STRTAB + to = self.data.find(b'\0', index) + assert to != -1 + return self.data[index:to].decode('latin1') + + def add_str(self, string): + assert self.sh_type == SHT_STRTAB + ret = len(self.data) + self.data += string.encode('latin1') + b'\0' + return ret + + def is_rel(self): + return self.sh_type == SHT_REL or self.sh_type == SHT_RELA + + def header_to_bin(self): + if self.sh_type != SHT_NOBITS: + self.sh_size = len(self.data) + return self.fmt.pack('IIIIIIIIII', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize) + + def late_init(self, sections): + if self.sh_type == SHT_SYMTAB: + self.init_symbols(sections) + elif self.is_rel(): + self.rel_target = sections[self.sh_info] + self.rel_target.relocated_by.append(self) + self.init_relocs() + + def find_symbol(self, name): + assert self.sh_type == SHT_SYMTAB + for s in self.symbol_entries: + if s.name == name: + return (s.st_shndx, s.st_value) + return None + + def find_symbol_in_section(self, name, section): + pos = self.find_symbol(name) + assert pos is not None + assert pos[0] == section.index + return pos[1] + + def init_symbols(self, sections): + assert self.sh_type == SHT_SYMTAB + assert self.sh_entsize == 16 + self.strtab = sections[self.sh_link] + entries = [] + for i in range(0, self.sh_size, self.sh_entsize): + entries.append(Symbol(self.fmt, self.data[i:i+self.sh_entsize], self.strtab)) + self.symbol_entries = entries + + def init_relocs(self): + assert self.is_rel() + entries = [] + for i in range(0, self.sh_size, self.sh_entsize): + entries.append(Relocation(self.fmt, self.data[i:i+self.sh_entsize], self.sh_type)) + self.relocations = entries + + def local_symbols(self): + assert self.sh_type == SHT_SYMTAB + return self.symbol_entries[:self.sh_info] + + def global_symbols(self): + assert self.sh_type == SHT_SYMTAB + return self.symbol_entries[self.sh_info:] + + def relocate_mdebug(self, original_offset): + assert self.sh_type == SHT_MIPS_DEBUG + new_data = bytearray(self.data) + shift_by = self.sh_offset - original_offset + + # Update the file-relative offsets in the Symbolic HDRR + hdrr_magic, hdrr_vstamp, hdrr_ilineMax, hdrr_cbLine, \ + hdrr_cbLineOffset, hdrr_idnMax, hdrr_cbDnOffset, hdrr_ipdMax, \ + hdrr_cbPdOffset, hdrr_isymMax, hdrr_cbSymOffset, hdrr_ioptMax, \ + hdrr_cbOptOffset, hdrr_iauxMax, hdrr_cbAuxOffset, hdrr_issMax, \ + hdrr_cbSsOffset, hdrr_issExtMax, hdrr_cbSsExtOffset, hdrr_ifdMax, \ + hdrr_cbFdOffset, hdrr_crfd, hdrr_cbRfdOffset, hdrr_iextMax, \ + hdrr_cbExtOffset = self.fmt.unpack("HHIIIIIIIIIIIIIIIIIIIIIII", self.data[0:0x60]) + + assert hdrr_magic == 0x7009, "Invalid magic value for .mdebug symbolic header" + + hdrr_cbLineOffset += shift_by + hdrr_cbDnOffset += shift_by + hdrr_cbPdOffset += shift_by + hdrr_cbSymOffset += shift_by + hdrr_cbOptOffset += shift_by + hdrr_cbAuxOffset += shift_by + hdrr_cbSsOffset += shift_by + hdrr_cbSsExtOffset += shift_by + hdrr_cbFdOffset += shift_by + hdrr_cbRfdOffset += shift_by + hdrr_cbExtOffset += shift_by + + new_data[0:0x60] = self.fmt.pack("HHIIIIIIIIIIIIIIIIIIIIIII", hdrr_magic, hdrr_vstamp, hdrr_ilineMax, hdrr_cbLine, \ + hdrr_cbLineOffset, hdrr_idnMax, hdrr_cbDnOffset, hdrr_ipdMax, \ + hdrr_cbPdOffset, hdrr_isymMax, hdrr_cbSymOffset, hdrr_ioptMax, \ + hdrr_cbOptOffset, hdrr_iauxMax, hdrr_cbAuxOffset, hdrr_issMax, \ + hdrr_cbSsOffset, hdrr_issExtMax, hdrr_cbSsExtOffset, hdrr_ifdMax, \ + hdrr_cbFdOffset, hdrr_crfd, hdrr_cbRfdOffset, hdrr_iextMax, \ + hdrr_cbExtOffset) + + self.data = bytes(new_data) + +class ElfFile: + def __init__(self, data): + self.data = data + assert data[:4] == b'\x7fELF', "not an ELF file" + + self.elf_header = ElfHeader(data[0:52]) + self.fmt = self.elf_header.fmt + + offset, size = self.elf_header.e_shoff, self.elf_header.e_shentsize + null_section = Section(self.fmt, data[offset:offset + size], data, 0) + num_sections = self.elf_header.e_shnum or null_section.sh_size + + self.sections = [null_section] + for i in range(1, num_sections): + ind = offset + i * size + self.sections.append(Section(self.fmt, data[ind:ind + size], data, i)) + + symtab = None + for s in self.sections: + if s.sh_type == SHT_SYMTAB: + assert not symtab + symtab = s + assert symtab is not None + self.symtab = symtab + + shstr = self.sections[self.elf_header.e_shstrndx] + for s in self.sections: + s.name = shstr.lookup_str(s.sh_name) + s.late_init(self.sections) + + def find_section(self, name): + for s in self.sections: + if s.name == name: + return s + return None + + def add_section(self, name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data): + shstr = self.sections[self.elf_header.e_shstrndx] + sh_name = shstr.add_str(name) + s = Section.from_parts(self.fmt, sh_name=sh_name, sh_type=sh_type, + sh_flags=sh_flags, sh_link=sh_link, sh_info=sh_info, + sh_addralign=sh_addralign, sh_entsize=sh_entsize, data=data, + index=len(self.sections)) + self.sections.append(s) + s.name = name + s.late_init(self.sections) + return s + + def drop_mdebug_gptab(self): + # We can only drop sections at the end, since otherwise section + # references might be wrong. Luckily, these sections typically are. + while self.sections[-1].sh_type in [SHT_MIPS_DEBUG, SHT_MIPS_GPTAB]: + self.sections.pop() + + def write(self, filename): + outfile = open(filename, 'wb') + outidx = 0 + def write_out(data): + nonlocal outidx + outfile.write(data) + outidx += len(data) + def pad_out(align): + if align and outidx % align: + write_out(b'\0' * (align - outidx % align)) + + self.elf_header.e_shnum = len(self.sections) + write_out(self.elf_header.to_bin()) + + for s in self.sections: + if s.sh_type != SHT_NOBITS and s.sh_type != SHT_NULL: + pad_out(s.sh_addralign) + old_offset = s.sh_offset + s.sh_offset = outidx + if s.sh_type == SHT_MIPS_DEBUG and s.sh_offset != old_offset: + # The .mdebug section has moved, relocate offsets + s.relocate_mdebug(old_offset) + write_out(s.data) + + pad_out(4) + self.elf_header.e_shoff = outidx + for s in self.sections: + write_out(s.header_to_bin()) + + outfile.seek(0) + outfile.write(self.elf_header.to_bin()) + outfile.close() + + +def is_temp_name(name): + return name.startswith('_asmpp_') + + +# https://stackoverflow.com/a/241506 +def re_comment_replacer(match): + s = match.group(0) + if s[0] in "/#": + return " " + else: + return s + + +re_comment_or_string = re.compile( + r'#.*|/\*.*?\*/|"(?:\\.|[^\\"])*"' +) + + +class Failure(Exception): + def __init__(self, message): + self.message = message + + def __str__(self): + return self.message + + +class GlobalState: + def __init__(self, min_instr_count, skip_instr_count, use_jtbl_for_rodata, mips1): + # A value that hopefully never appears as a 32-bit rodata constant (or we + # miscompile late rodata). Increases by 1 in each step. + self.late_rodata_hex = 0xE0123456 + self.namectr = 0 + self.min_instr_count = min_instr_count + self.skip_instr_count = skip_instr_count + self.use_jtbl_for_rodata = use_jtbl_for_rodata + self.mips1 = mips1 + + def next_late_rodata_hex(self): + dummy_bytes = struct.pack('>I', self.late_rodata_hex) + if (self.late_rodata_hex & 0xffff) == 0: + # Avoid lui + self.late_rodata_hex += 1 + self.late_rodata_hex += 1 + return dummy_bytes + + def make_name(self, cat): + self.namectr += 1 + return '_asmpp_{}{}'.format(cat, self.namectr) + + +Function = namedtuple('Function', ['text_glabels', 'asm_conts', 'late_rodata_dummy_bytes', 'jtbl_rodata_size', 'late_rodata_asm_conts', 'fn_desc', 'data']) + + +class GlobalAsmBlock: + def __init__(self, fn_desc): + self.fn_desc = fn_desc + self.cur_section = '.text' + self.asm_conts = [] + self.late_rodata_asm_conts = [] + self.late_rodata_alignment = 0 + self.late_rodata_alignment_from_content = False + self.text_glabels = [] + self.fn_section_sizes = { + '.text': 0, + '.data': 0, + '.bss': 0, + '.rodata': 0, + '.late_rodata': 0, + } + self.fn_ins_inds = [] + self.glued_line = '' + self.num_lines = 0 + + def fail(self, message, line=None): + context = self.fn_desc + if line: + context += ", at line \"" + line + "\"" + raise Failure(message + "\nwithin " + context) + + def count_quoted_size(self, line, z, real_line, output_enc): + line = line.encode(output_enc).decode('latin1') + in_quote = False + has_comma = True + num_parts = 0 + ret = 0 + i = 0 + digits = "0123456789" # 0-7 would be more sane, but this matches GNU as + while i < len(line): + c = line[i] + i += 1 + if not in_quote: + if c == '"': + in_quote = True + if z and not has_comma: + self.fail(".asciiz with glued strings is not supported due to GNU as version diffs") + num_parts += 1 + elif c == ',': + has_comma = True + else: + if c == '"': + in_quote = False + has_comma = False + continue + ret += 1 + if c != '\\': + continue + if i == len(line): + self.fail("backslash at end of line not supported", real_line) + c = line[i] + i += 1 + # (if c is in "bfnrtv", we have a real escaped literal) + if c == 'x': + # hex literal, consume any number of hex chars, possibly none + while i < len(line) and line[i] in digits + "abcdefABCDEF": + i += 1 + elif c in digits: + # octal literal, consume up to two more digits + it = 0 + while i < len(line) and line[i] in digits and it < 2: + i += 1 + it += 1 + + if in_quote: + self.fail("unterminated string literal", real_line) + if num_parts == 0: + self.fail(".ascii with no string", real_line) + return ret + num_parts if z else ret + + def align2(self): + while self.fn_section_sizes[self.cur_section] % 2 != 0: + self.fn_section_sizes[self.cur_section] += 1 + + def align4(self): + while self.fn_section_sizes[self.cur_section] % 4 != 0: + self.fn_section_sizes[self.cur_section] += 1 + + def add_sized(self, size, line): + if self.cur_section in ['.text', '.late_rodata']: + if size % 4 != 0: + self.fail("size must be a multiple of 4", line) + if size < 0: + self.fail("size cannot be negative", line) + self.fn_section_sizes[self.cur_section] += size + if self.cur_section == '.text': + if not self.text_glabels: + self.fail(".text block without an initial glabel", line) + self.fn_ins_inds.append((self.num_lines - 1, size // 4)) + + def process_line(self, line, output_enc): + self.num_lines += 1 + if line.endswith('\\'): + self.glued_line += line[:-1] + return + line = self.glued_line + line + self.glued_line = '' + + real_line = line + line = re.sub(re_comment_or_string, re_comment_replacer, line) + line = line.strip() + line = re.sub(r'^[a-zA-Z0-9_]+:\s*', '', line) + changed_section = False + emitting_double = False + if line.startswith('glabel ') and self.cur_section == '.text': + self.text_glabels.append(line.split()[1]) + if not line: + pass # empty line + elif line.startswith('glabel ') or line.startswith('dlabel ') or line.startswith('endlabel ') or (' ' not in line and line.endswith(':')): + pass # label + elif line.startswith('.section') or line in ['.text', '.data', '.rdata', '.rodata', '.bss', '.late_rodata']: + # section change + self.cur_section = '.rodata' if line == '.rdata' else line.split(',')[0].split()[-1] + if self.cur_section not in ['.data', '.text', '.rodata', '.late_rodata', '.bss']: + self.fail("unrecognized .section directive", real_line) + changed_section = True + elif line.startswith('.late_rodata_alignment'): + if self.cur_section != '.late_rodata': + self.fail(".late_rodata_alignment must occur within .late_rodata section", real_line) + value = int(line.split()[1]) + if value not in [4, 8]: + self.fail(".late_rodata_alignment argument must be 4 or 8", real_line) + if self.late_rodata_alignment and self.late_rodata_alignment != value: + self.fail(".late_rodata_alignment alignment assumption conflicts with earlier .double directive. Make sure to provide explicit alignment padding.") + self.late_rodata_alignment = value + changed_section = True + elif line.startswith('.incbin'): + self.add_sized(int(line.split(',')[-1].strip(), 0), real_line) + elif line.startswith('.word') or line.startswith('.float'): + self.align4() + self.add_sized(4 * len(line.split(',')), real_line) + elif line.startswith('.double'): + self.align4() + if self.cur_section == '.late_rodata': + align8 = self.fn_section_sizes[self.cur_section] % 8 + # Automatically set late_rodata_alignment, so the generated C code uses doubles. + # This gives us correct alignment for the transferred doubles even when the + # late_rodata_alignment is wrong, e.g. for non-matching compilation. + if not self.late_rodata_alignment: + self.late_rodata_alignment = 8 - align8 + self.late_rodata_alignment_from_content = True + elif self.late_rodata_alignment != 8 - align8: + if self.late_rodata_alignment_from_content: + self.fail("found two .double directives with different start addresses mod 8. Make sure to provide explicit alignment padding.", real_line) + else: + self.fail(".double at address that is not 0 mod 8 (based on .late_rodata_alignment assumption). Make sure to provide explicit alignment padding.", real_line) + self.add_sized(8 * len(line.split(',')), real_line) + emitting_double = True + elif line.startswith('.space'): + self.add_sized(int(line.split()[1], 0), real_line) + elif line.startswith('.balign') or line.startswith('.align'): + align = int(line.split()[1]) + if align != 4: + self.fail("only .balign 4 is supported", real_line) + self.align4() + elif line.startswith('.asci'): + z = (line.startswith('.asciz') or line.startswith('.asciiz')) + self.add_sized(self.count_quoted_size(line, z, real_line, output_enc), real_line) + elif line.startswith('.byte'): + self.add_sized(len(line.split(',')), real_line) + elif line.startswith('.half'): + self.align2() + self.add_sized(2*len(line.split(',')), real_line) + elif line.startswith('.'): + # .macro, ... + self.fail("asm directive not supported", real_line) + else: + # Unfortunately, macros are hard to support for .rodata -- + # we don't know how how space they will expand to before + # running the assembler, but we need that information to + # construct the C code. So if we need that we'll either + # need to run the assembler twice (at least in some rare + # cases), or change how this program is invoked. + # Similarly, we can't currently deal with pseudo-instructions + # that expand to several real instructions. + if self.cur_section != '.text': + self.fail("instruction or macro call in non-.text section? not supported", real_line) + self.add_sized(4, real_line) + if self.cur_section == '.late_rodata': + if not changed_section: + if emitting_double: + self.late_rodata_asm_conts.append(".align 0") + self.late_rodata_asm_conts.append(real_line) + if emitting_double: + self.late_rodata_asm_conts.append(".align 2") + else: + self.asm_conts.append(real_line) + + def finish(self, state): + src = [''] * (self.num_lines + 1) + late_rodata_dummy_bytes = [] + jtbl_rodata_size = 0 + late_rodata_fn_output = [] + + num_instr = self.fn_section_sizes['.text'] // 4 + + if self.fn_section_sizes['.late_rodata'] > 0: + # Generate late rodata by emitting unique float constants. + # This requires 3 instructions for each 4 bytes of rodata. + # If we know alignment, we can use doubles, which give 3 + # instructions for 8 bytes of rodata. + size = self.fn_section_sizes['.late_rodata'] // 4 + skip_next = False + needs_double = (self.late_rodata_alignment != 0) + extra_mips1_nop = False + jtbl_size = 11 if state.mips1 else 9 + for i in range(size): + if skip_next: + skip_next = False + continue + # Jump tables give 9 instructions (11 with -mips1) for >= 5 words of rodata, + # and should be emitted when: + # - -O2 or -O2 -g3 are used, which give the right codegen + # - we have emitted our first .float/.double (to ensure that we find the + # created rodata in the binary) + # - we have emitted our first .double, if any (to ensure alignment of doubles + # in shifted rodata sections) + # - we have at least 5 words of rodata left to emit (otherwise IDO does not + # generate a jump table) + # - we have at least 10 more instructions to go in this function (otherwise our + # function size computation will be wrong since the delay slot goes unused) + if (not needs_double and state.use_jtbl_for_rodata and i >= 1 and + size - i >= 5 and num_instr - len(late_rodata_fn_output) >= jtbl_size + 1): + cases = " ".join("case {}:".format(case) for case in range(size - i)) + late_rodata_fn_output.append("switch (*(volatile int*)0) { " + cases + " ; }") + late_rodata_fn_output.extend([""] * (jtbl_size - 1)) + jtbl_rodata_size = (size - i) * 4 + extra_mips1_nop = i != 2 + break + dummy_bytes = state.next_late_rodata_hex() + late_rodata_dummy_bytes.append(dummy_bytes) + if self.late_rodata_alignment == 4 * ((i + 1) % 2 + 1) and i + 1 < size: + dummy_bytes2 = state.next_late_rodata_hex() + late_rodata_dummy_bytes.append(dummy_bytes2) + fval, = struct.unpack('>d', dummy_bytes + dummy_bytes2) + late_rodata_fn_output.append('*(volatile double*)0 = {};'.format(fval)) + skip_next = True + needs_double = False + if state.mips1: + # mips1 does not have ldc1/sdc1 + late_rodata_fn_output.append('') + late_rodata_fn_output.append('') + extra_mips1_nop = False + else: + fval, = struct.unpack('>f', dummy_bytes) + late_rodata_fn_output.append('*(volatile float*)0 = {}f;'.format(fval)) + extra_mips1_nop = True + late_rodata_fn_output.append('') + late_rodata_fn_output.append('') + if state.mips1 and extra_mips1_nop: + late_rodata_fn_output.append('') + + text_name = None + if self.fn_section_sizes['.text'] > 0 or late_rodata_fn_output: + text_name = state.make_name('func') + src[0] = 'void {}(void) {{'.format(text_name) + src[self.num_lines] = '}' + instr_count = self.fn_section_sizes['.text'] // 4 + if instr_count < state.min_instr_count: + self.fail("too short .text block") + tot_emitted = 0 + tot_skipped = 0 + fn_emitted = 0 + fn_skipped = 0 + rodata_stack = late_rodata_fn_output[::-1] + for (line, count) in self.fn_ins_inds: + for _ in range(count): + if (fn_emitted > MAX_FN_SIZE and instr_count - tot_emitted > state.min_instr_count and + (not rodata_stack or rodata_stack[-1])): + # Don't let functions become too large. When a function reaches 284 + # instructions, and -O2 -framepointer flags are passed, the IRIX + # compiler decides it is a great idea to start optimizing more. + fn_emitted = 0 + fn_skipped = 0 + src[line] += ' }} void {}(void) {{ '.format(state.make_name('large_func')) + if fn_skipped < state.skip_instr_count: + fn_skipped += 1 + tot_skipped += 1 + elif rodata_stack: + src[line] += rodata_stack.pop() + else: + src[line] += '*(volatile int*)0 = 0;' + tot_emitted += 1 + fn_emitted += 1 + if rodata_stack: + size = len(late_rodata_fn_output) // 3 + available = instr_count - tot_skipped + self.fail( + "late rodata to text ratio is too high: {} / {} must be <= 1/3\n" + "add .late_rodata_alignment (4|8) to the .late_rodata " + "block to double the allowed ratio." + .format(size, available)) + + rodata_name = None + if self.fn_section_sizes['.rodata'] > 0: + rodata_name = state.make_name('rodata') + src[self.num_lines] += ' const char {}[{}] = {{1}};'.format(rodata_name, self.fn_section_sizes['.rodata']) + + data_name = None + if self.fn_section_sizes['.data'] > 0: + data_name = state.make_name('data') + src[self.num_lines] += ' char {}[{}] = {{1}};'.format(data_name, self.fn_section_sizes['.data']) + + bss_name = None + if self.fn_section_sizes['.bss'] > 0: + bss_name = state.make_name('bss') + src[self.num_lines] += ' char {}[{}];'.format(bss_name, self.fn_section_sizes['.bss']) + + fn = Function( + text_glabels=self.text_glabels, + asm_conts=self.asm_conts, + late_rodata_dummy_bytes=late_rodata_dummy_bytes, + jtbl_rodata_size=jtbl_rodata_size, + late_rodata_asm_conts=self.late_rodata_asm_conts, + fn_desc=self.fn_desc, + data={ + '.text': (text_name, self.fn_section_sizes['.text']), + '.data': (data_name, self.fn_section_sizes['.data']), + '.rodata': (rodata_name, self.fn_section_sizes['.rodata']), + '.bss': (bss_name, self.fn_section_sizes['.bss']), + }) + return src, fn + +cutscene_data_regexpr = re.compile(r"CutsceneData (.|\n)*\[\] = {") +float_regexpr = re.compile(r"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f") + +def repl_float_hex(m): + return str(struct.unpack(">I", struct.pack(">f", float(m.group(0).strip().rstrip("f"))))[0]) + +def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, print_source=None): + if opt in ['O2', 'O1']: + if framepointer: + min_instr_count = 6 + skip_instr_count = 5 + else: + min_instr_count = 2 + skip_instr_count = 1 + elif opt == 'O0': + if framepointer: + min_instr_count = 8 + skip_instr_count = 8 + else: + min_instr_count = 4 + skip_instr_count = 4 + elif opt == 'g': + if framepointer: + min_instr_count = 7 + skip_instr_count = 7 + else: + min_instr_count = 4 + skip_instr_count = 4 + else: + if opt != 'g3': + raise Failure("must pass one of -g, -O0, -O1, -O2, -O2 -g3") + if framepointer: + min_instr_count = 4 + skip_instr_count = 4 + else: + min_instr_count = 2 + skip_instr_count = 2 + + use_jtbl_for_rodata = False + if opt in ['O2', 'g3'] and not framepointer: + use_jtbl_for_rodata = True + + state = GlobalState(min_instr_count, skip_instr_count, use_jtbl_for_rodata, mips1) + + global_asm = None + asm_functions = [] + output_lines = [ + '#line 1 "' + f.name + '"' + ] + + is_cutscene_data = False + is_early_include = False + + for line_no, raw_line in enumerate(f, 1): + raw_line = raw_line.rstrip() + line = raw_line.lstrip() + + # Print exactly one output line per source line, to make compiler + # errors have correct line numbers. These will be overridden with + # reasonable content further down. + output_lines.append('') + + if global_asm is not None: + if line.startswith(')'): + src, fn = global_asm.finish(state) + for i, line2 in enumerate(src): + output_lines[start_index + i] = line2 + asm_functions.append(fn) + global_asm = None + else: + global_asm.process_line(raw_line, output_enc) + elif line in ['GLOBAL_ASM(', '#pragma GLOBAL_ASM(']: + global_asm = GlobalAsmBlock("GLOBAL_ASM block at line " + str(line_no)) + start_index = len(output_lines) + elif ((line.startswith('GLOBAL_ASM("') or line.startswith('#pragma GLOBAL_ASM("')) + and line.endswith('")')): + fname = line[line.index('(') + 2 : -2] + out_dependencies.append(fname) + global_asm = GlobalAsmBlock(fname) + with open(fname, encoding=input_enc) as f: + for line2 in f: + global_asm.process_line(line2.rstrip(), output_enc) + src, fn = global_asm.finish(state) + output_lines[-1] = ''.join(src) + asm_functions.append(fn) + global_asm = None + elif line == '#pragma asmproc recurse': + # C includes qualified as + # #pragma asmproc recurse + # #include "file.c" + # will be processed recursively when encountered + is_early_include = True + elif is_early_include: + # Previous line was a #pragma asmproc recurse + is_early_include = False + if not line.startswith("#include "): + raise Failure("#pragma asmproc recurse must be followed by an #include ") + fpath = os.path.dirname(f.name) + fname = os.path.join(fpath, line[line.index(' ') + 2 : -1]) + out_dependencies.append(fname) + include_src = StringIO() + with open(fname, encoding=input_enc) as include_file: + parse_source(include_file, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, include_src) + include_src.write('#line ' + str(line_no + 1) + ' "' + f.name + '"') + output_lines[-1] = include_src.getvalue() + include_src.close() + else: + # This is a hack to replace all floating-point numbers in an array of a particular type + # (in this case CutsceneData) with their corresponding IEEE-754 hexadecimal representation + if cutscene_data_regexpr.search(line) is not None: + is_cutscene_data = True + elif line.endswith("};"): + is_cutscene_data = False + if is_cutscene_data: + raw_line = re.sub(float_regexpr, repl_float_hex, raw_line) + output_lines[-1] = raw_line + + if print_source: + if isinstance(print_source, StringIO): + for line in output_lines: + print_source.write(line + '\n') + else: + newline_encoded = "\n".encode(output_enc) + for line in output_lines: + try: + line_encoded = line.encode(output_enc) + except UnicodeEncodeError: + print("Failed to encode a line to", output_enc) + print("The line:", line) + print("The line, utf-8-encoded:", line.encode("utf-8")) + raise + print_source.write(line_encoded) + print_source.write(newline_encoded) + print_source.flush() + + return asm_functions + +def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, drop_mdebug_gptab): + SECTIONS = ['.data', '.text', '.rodata', '.bss'] + + with open(objfile_name, 'rb') as f: + objfile = ElfFile(f.read()) + fmt = objfile.fmt + + prev_locs = { + '.text': 0, + '.data': 0, + '.rodata': 0, + '.bss': 0, + } + to_copy = { + '.text': [], + '.data': [], + '.rodata': [], + '.bss': [], + } + asm = [] + all_late_rodata_dummy_bytes = [] + all_jtbl_rodata_size = [] + late_rodata_asm = [] + late_rodata_source_name_start = None + late_rodata_source_name_end = None + + # Generate an assembly file with all the assembly we need to fill in. For + # simplicity we pad with nops/.space so that addresses match exactly, so we + # don't have to fix up relocations/symbol references. + all_text_glabels = set() + func_sizes = {} + for function in functions: + ifdefed = False + for sectype, (temp_name, size) in function.data.items(): + if temp_name is None: + continue + assert size > 0 + loc = objfile.symtab.find_symbol(temp_name) + if loc is None: + ifdefed = True + break + loc = loc[1] + prev_loc = prev_locs[sectype] + if loc < prev_loc: + raise Failure("Wrongly computed size for section {} (diff {}). This is an asm-processor bug!".format(sectype, prev_loc- loc)) + if loc != prev_loc: + asm.append('.section ' + sectype) + if sectype == '.text': + for i in range((loc - prev_loc) // 4): + asm.append('nop') + else: + asm.append('.space {}'.format(loc - prev_loc)) + to_copy[sectype].append((loc, size, temp_name, function.fn_desc)) + if function.text_glabels: + func_sizes[function.text_glabels[0]] = size + prev_locs[sectype] = loc + size + if not ifdefed: + all_text_glabels.update(function.text_glabels) + all_late_rodata_dummy_bytes.append(function.late_rodata_dummy_bytes) + all_jtbl_rodata_size.append(function.jtbl_rodata_size) + late_rodata_asm.append(function.late_rodata_asm_conts) + for sectype, (temp_name, size) in function.data.items(): + if temp_name is not None: + asm.append('.section ' + sectype) + asm.append('glabel ' + temp_name + '_asm_start') + asm.append('.text') + for line in function.asm_conts: + asm.append(line) + for sectype, (temp_name, size) in function.data.items(): + if temp_name is not None: + asm.append('.section ' + sectype) + asm.append('glabel ' + temp_name + '_asm_end') + if any(late_rodata_asm): + late_rodata_source_name_start = '_asmpp_late_rodata_start' + late_rodata_source_name_end = '_asmpp_late_rodata_end' + asm.append('.rdata') + asm.append('glabel {}'.format(late_rodata_source_name_start)) + for conts in late_rodata_asm: + asm.extend(conts) + asm.append('glabel {}'.format(late_rodata_source_name_end)) + + o_file = tempfile.NamedTemporaryFile(prefix='asm-processor', suffix='.o', delete=False) + o_name = o_file.name + o_file.close() + s_file = tempfile.NamedTemporaryFile(prefix='asm-processor', suffix='.s', delete=False) + s_name = s_file.name + try: + s_file.write(asm_prelude + b'\n') + for line in asm: + s_file.write(line.encode(output_enc) + b'\n') + s_file.close() + ret = os.system(assembler + " " + s_name + " -o " + o_name) + if ret != 0: + raise Failure("failed to assemble") + with open(o_name, 'rb') as f: + asm_objfile = ElfFile(f.read()) + + # Remove clutter from objdump output for tests, and make the tests + # portable by avoiding absolute paths. Outside of tests .mdebug is + # useful for showing source together with asm, though. + mdebug_section = objfile.find_section('.mdebug') + if drop_mdebug_gptab: + objfile.drop_mdebug_gptab() + + # Unify reginfo sections + target_reginfo = objfile.find_section('.reginfo') + source_reginfo_data = list(asm_objfile.find_section('.reginfo').data) + data = list(target_reginfo.data) + for i in range(20): + data[i] |= source_reginfo_data[i] + target_reginfo.data = bytes(data) + + # Move over section contents + modified_text_positions = set() + jtbl_rodata_positions = set() + last_rodata_pos = 0 + for sectype in SECTIONS: + if not to_copy[sectype]: + continue + source = asm_objfile.find_section(sectype) + assert source is not None, "didn't find source section: " + sectype + for (pos, count, temp_name, fn_desc) in to_copy[sectype]: + loc1 = asm_objfile.symtab.find_symbol_in_section(temp_name + '_asm_start', source) + loc2 = asm_objfile.symtab.find_symbol_in_section(temp_name + '_asm_end', source) + assert loc1 == pos, "assembly and C files don't line up for section " + sectype + ", " + fn_desc + if loc2 - loc1 != count: + raise Failure("incorrectly computed size for section " + sectype + ", " + fn_desc + ". If using .double, make sure to provide explicit alignment padding.") + if sectype == '.bss': + continue + target = objfile.find_section(sectype) + assert target is not None, "missing target section of type " + sectype + data = list(target.data) + for (pos, count, _, _) in to_copy[sectype]: + data[pos:pos + count] = source.data[pos:pos + count] + if sectype == '.text': + assert count % 4 == 0 + assert pos % 4 == 0 + for i in range(count // 4): + modified_text_positions.add(pos + 4 * i) + elif sectype == '.rodata': + last_rodata_pos = pos + count + target.data = bytes(data) + + # Move over late rodata. This is heuristic, sadly, since I can't think + # of another way of doing it. + moved_late_rodata = {} + if any(all_late_rodata_dummy_bytes) or any(all_jtbl_rodata_size): + source = asm_objfile.find_section('.rodata') + target = objfile.find_section('.rodata') + source_pos = asm_objfile.symtab.find_symbol_in_section(late_rodata_source_name_start, source) + source_end = asm_objfile.symtab.find_symbol_in_section(late_rodata_source_name_end, source) + if source_end - source_pos != sum(map(len, all_late_rodata_dummy_bytes)) * 4 + sum(all_jtbl_rodata_size): + raise Failure("computed wrong size of .late_rodata") + new_data = list(target.data) + for dummy_bytes_list, jtbl_rodata_size in zip(all_late_rodata_dummy_bytes, all_jtbl_rodata_size): + for index, dummy_bytes in enumerate(dummy_bytes_list): + if not fmt.is_big_endian: + dummy_bytes = dummy_bytes[::-1] + pos = target.data.index(dummy_bytes, last_rodata_pos) + # This check is nice, but makes time complexity worse for large files: + if SLOW_CHECKS and target.data.find(dummy_bytes, pos + 4) != -1: + raise Failure("multiple occurrences of late_rodata hex magic. Change asm-processor to use something better than 0xE0123456!") + if index == 0 and len(dummy_bytes_list) > 1 and target.data[pos+4:pos+8] == b'\0\0\0\0': + # Ugly hack to handle double alignment for non-matching builds. + # We were told by .late_rodata_alignment (or deduced from a .double) + # that a function's late_rodata started out 4 (mod 8), and emitted + # a float and then a double. But it was actually 0 (mod 8), so our + # double was moved by 4 bytes. To make them adjacent to keep jump + # tables correct, move the float by 4 bytes as well. + new_data[pos:pos+4] = b'\0\0\0\0' + pos += 4 + new_data[pos:pos+4] = source.data[source_pos:source_pos+4] + moved_late_rodata[source_pos] = pos + last_rodata_pos = pos + 4 + source_pos += 4 + if jtbl_rodata_size > 0: + assert dummy_bytes_list, "should always have dummy bytes before jtbl data" + pos = last_rodata_pos + new_data[pos : pos + jtbl_rodata_size] = \ + source.data[source_pos : source_pos + jtbl_rodata_size] + for i in range(0, jtbl_rodata_size, 4): + moved_late_rodata[source_pos + i] = pos + i + jtbl_rodata_positions.add(pos + i) + last_rodata_pos += jtbl_rodata_size + source_pos += jtbl_rodata_size + target.data = bytes(new_data) + + # Merge strtab data. + strtab_adj = len(objfile.symtab.strtab.data) + objfile.symtab.strtab.data += asm_objfile.symtab.strtab.data + + # Find relocated symbols + relocated_symbols = set() + for sectype in SECTIONS: + for obj in [asm_objfile, objfile]: + sec = obj.find_section(sectype) + if sec is None: + continue + for reltab in sec.relocated_by: + for rel in reltab.relocations: + relocated_symbols.add(obj.symtab.symbol_entries[rel.sym_index]) + + # Move over symbols, deleting the temporary function labels. + # Sometimes this naive procedure results in duplicate symbols, or UNDEF + # symbols that are also defined the same .o file. Hopefully that's fine. + # Skip over local symbols that aren't relocated against, to avoid + # conflicts. + new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)] + new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)] + for i, s in enumerate(asm_objfile.symtab.symbol_entries): + is_local = (i < asm_objfile.symtab.sh_info) + if is_local and s not in relocated_symbols: + continue + if is_temp_name(s.name): + continue + if s.st_shndx not in [SHN_UNDEF, SHN_ABS]: + section_name = asm_objfile.sections[s.st_shndx].name + if section_name not in SECTIONS: + raise Failure("generated assembly .o must only have symbols for .text, .data, .rodata, ABS and UNDEF, but found " + section_name) + s.st_shndx = objfile.find_section(section_name).index + # glabel's aren't marked as functions, making objdump output confusing. Fix that. + if s.name in all_text_glabels: + s.type = STT_FUNC + if s.name in func_sizes: + s.st_size = func_sizes[s.name] + if objfile.sections[s.st_shndx].name == '.rodata' and s.st_value in moved_late_rodata: + s.st_value = moved_late_rodata[s.st_value] + s.st_name += strtab_adj + if is_local: + new_local_syms.append(s) + else: + new_global_syms.append(s) + + # Add static symbols from .mdebug, so they can be referred to from GLOBAL_ASM + local_sym_replacements = {} + if mdebug_section: + strtab_index = len(objfile.symtab.strtab.data) + new_strtab_data = [] + ifd_max, cb_fd_offset = fmt.unpack('II', mdebug_section.data[18*4 : 20*4]) + cb_sym_offset, = fmt.unpack('I', mdebug_section.data[9*4 : 10*4]) + cb_ss_offset, = fmt.unpack('I', mdebug_section.data[15*4 : 16*4]) + for i in range(ifd_max): + offset = cb_fd_offset + 18*4*i + iss_base, _, isym_base, csym = fmt.unpack('IIII', objfile.data[offset + 2*4 : offset + 6*4]) + for j in range(csym): + offset2 = cb_sym_offset + 12 * (isym_base + j) + iss, value, st_sc_index = fmt.unpack('III', objfile.data[offset2 : offset2 + 12]) + st = (st_sc_index >> 26) + sc = (st_sc_index >> 21) & 0x1f + if st in [MIPS_DEBUG_ST_STATIC, MIPS_DEBUG_ST_STATIC_PROC]: + symbol_name_offset = cb_ss_offset + iss_base + iss + symbol_name_offset_end = objfile.data.find(b'\0', symbol_name_offset) + assert symbol_name_offset_end != -1 + symbol_name = objfile.data[symbol_name_offset : symbol_name_offset_end + 1] + symbol_name_str = symbol_name[:-1].decode('latin1') + section_name = {1: '.text', 2: '.data', 3: '.bss', 15: '.rodata'}[sc] + section = objfile.find_section(section_name) + symtype = STT_FUNC if sc == 1 else STT_OBJECT + sym = Symbol.from_parts( + fmt, + st_name=strtab_index, + st_value=value, + st_size=0, + st_info=(STB_LOCAL << 4 | symtype), + st_other=STV_DEFAULT, + st_shndx=section.index, + strtab=objfile.symtab.strtab, + name=symbol_name_str) + local_sym_replacements[symbol_name_str] = len(new_local_syms) + strtab_index += len(symbol_name) + new_strtab_data.append(symbol_name) + new_local_syms.append(sym) + objfile.symtab.strtab.data += b''.join(new_strtab_data) + + # To get the linker to use the local symbols, we have to get rid of UNDEF + # global ones. + newer_global_syms = [] + for s in new_global_syms: + if s.st_shndx == SHN_UNDEF and s.name in local_sym_replacements: + s.new_index = local_sym_replacements[s.name] + else: + newer_global_syms.append(s) + new_global_syms = newer_global_syms + + new_syms = new_local_syms + new_global_syms + for i, s in enumerate(new_syms): + s.new_index = i + objfile.symtab.data = b''.join(s.to_bin() for s in new_syms) + objfile.symtab.sh_info = len(new_local_syms) + + # Move over relocations + for sectype in SECTIONS: + source = asm_objfile.find_section(sectype) + target = objfile.find_section(sectype) + + if target is not None: + # fixup relocation symbol indices, since we butchered them above + for reltab in target.relocated_by: + nrels = [] + for rel in reltab.relocations: + if (sectype == '.text' and rel.r_offset in modified_text_positions or + sectype == '.rodata' and rel.r_offset in jtbl_rodata_positions): + # don't include relocations for late_rodata dummy code + continue + # hopefully we don't have relocations for local or + # temporary symbols, so new_index exists + rel.sym_index = objfile.symtab.symbol_entries[rel.sym_index].new_index + nrels.append(rel) + reltab.relocations = nrels + reltab.data = b''.join(rel.to_bin() for rel in nrels) + + if not source: + continue + + target_reltab = objfile.find_section('.rel' + sectype) + target_reltaba = objfile.find_section('.rela' + sectype) + for reltab in source.relocated_by: + for rel in reltab.relocations: + rel.sym_index = asm_objfile.symtab.symbol_entries[rel.sym_index].new_index + if sectype == '.rodata' and rel.r_offset in moved_late_rodata: + rel.r_offset = moved_late_rodata[rel.r_offset] + new_data = b''.join(rel.to_bin() for rel in reltab.relocations) + if reltab.sh_type == SHT_REL: + if not target_reltab: + target_reltab = objfile.add_section('.rel' + sectype, + sh_type=SHT_REL, sh_flags=0, + sh_link=objfile.symtab.index, sh_info=target.index, + sh_addralign=4, sh_entsize=8, data=b'') + target_reltab.data += new_data + else: + if not target_reltaba: + target_reltaba = objfile.add_section('.rela' + sectype, + sh_type=SHT_RELA, sh_flags=0, + sh_link=objfile.symtab.index, sh_info=target.index, + sh_addralign=4, sh_entsize=12, data=b'') + target_reltaba.data += new_data + + objfile.write(objfile_name) + finally: + s_file.close() + os.remove(s_name) + try: + os.remove(o_name) + except: + pass + +def run_wrapped(argv, outfile, functions): + parser = argparse.ArgumentParser(description="Pre-process .c files and post-process .o files to enable embedding assembly into C.") + parser.add_argument('filename', help="path to .c code") + parser.add_argument('--post-process', dest='objfile', help="path to .o file to post-process") + parser.add_argument('--assembler', dest='assembler', help="assembler command (e.g. \"mips-linux-gnu-as -march=vr4300 -mabi=32\")") + parser.add_argument('--asm-prelude', dest='asm_prelude', help="path to a file containing a prelude to the assembly file (with .set and .macro directives, e.g.)") + parser.add_argument('--input-enc', default='latin1', help="input encoding (default: %(default)s)") + parser.add_argument('--output-enc', default='latin1', help="output encoding (default: %(default)s)") + parser.add_argument('--drop-mdebug-gptab', dest='drop_mdebug_gptab', action='store_true', help="drop mdebug and gptab sections") + parser.add_argument('-framepointer', dest='framepointer', action='store_true') + parser.add_argument('-mips1', dest='mips1', action='store_true') + parser.add_argument('-g3', dest='g3', action='store_true') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-O0', dest='opt', action='store_const', const='O0') + group.add_argument('-O1', dest='opt', action='store_const', const='O1') + group.add_argument('-O2', dest='opt', action='store_const', const='O2') + group.add_argument('-g', dest='opt', action='store_const', const='g') + args = parser.parse_args(argv) + opt = args.opt + if args.g3: + if opt != 'O2': + raise Failure("-g3 is only supported together with -O2") + opt = 'g3' + if args.mips1 and (opt != 'O2' or args.framepointer): + raise Failure("-mips1 is only supported together with -O2") + + if args.objfile is None: + with open(args.filename, encoding=args.input_enc) as f: + deps = [] + functions = parse_source(f, opt=opt, framepointer=args.framepointer, mips1=args.mips1, input_enc=args.input_enc, output_enc=args.output_enc, out_dependencies=deps, print_source=outfile) + return functions, deps + else: + if args.assembler is None: + raise Failure("must pass assembler command") + if functions is None: + with open(args.filename, encoding=args.input_enc) as f: + functions = parse_source(f, opt=opt, framepointer=args.framepointer, mips1=args.mips1, input_enc=args.input_enc, out_dependencies=[], output_enc=args.output_enc) + if not functions: + return + asm_prelude = b'' + if args.asm_prelude: + with open(args.asm_prelude, 'rb') as f: + asm_prelude = f.read() + fixup_objfile(args.objfile, functions, asm_prelude, args.assembler, args.output_enc, args.drop_mdebug_gptab) + +def run(argv, outfile=sys.stdout.buffer, functions=None): + try: + return run_wrapped(argv, outfile, functions) + except Failure as e: + print("Error:", e, file=sys.stderr) + sys.exit(1) + +if __name__ == "__main__": + run(sys.argv[1:]) diff --git a/tools/asm_processor/build.py b/tools/asm_processor/build.py index eb16c7bc1..a8638fd76 100644 --- a/tools/asm_processor/build.py +++ b/tools/asm_processor/build.py @@ -1,37 +1,114 @@ #!/usr/bin/env python3 import sys -import os +from pathlib import Path import shlex import subprocess import tempfile +import uuid +import asm_processor -dir_path = os.path.dirname(os.path.realpath(__file__)) -asm_processor = ['python3', os.path.join(dir_path, "asm-processor.py")] -prelude = os.path.join(dir_path, "prelude.inc") +# Boolean for debugging purposes +# Preprocessed files are temporary, set to True to keep a copy +keep_preprocessed_files = False + +dir_path = Path(__file__).resolve().parent +asm_prelude_path = dir_path / "prelude.inc" all_args = sys.argv[1:] -sep1 = all_args.index('--') -sep2 = all_args.index('--', sep1+1) +sep0 = next(index for index, arg in enumerate(all_args) if not arg.startswith("-")) +sep1 = all_args.index("--") +sep2 = all_args.index("--", sep1 + 1) -compiler = all_args[:sep1] +asmproc_flags = all_args[:sep0] +compiler = all_args[sep0:sep1] -assembler = all_args[sep1+1:sep2] -assembler_sh = ' '.join(shlex.quote(x) for x in assembler) +assembler_args = all_args[sep1 + 1 : sep2] +assembler_sh = " ".join(shlex.quote(x) for x in assembler_args) -compile_args = all_args[sep2+1:] -in_file = compile_args[-1] -out_ind = compile_args.index('-o') -out_file = compile_args[out_ind + 1] + +compile_args = all_args[sep2 + 1 :] + +in_file = Path(compile_args[-1]) del compile_args[-1] + +out_ind = compile_args.index("-o") +out_file = Path(compile_args[out_ind + 1]) del compile_args[out_ind + 1] del compile_args[out_ind] -in_dir = os.path.split(os.path.realpath(in_file))[0] -opt_flags = [x for x in compile_args if x in ['-g', '-O2', '-framepointer']] +in_dir = in_file.resolve().parent +opt_flags = [ + x for x in compile_args if x in {"-g3", "-g", "-O0", "-O1", "-O2", "-framepointer"} +] +if "-mips2" not in compile_args: + opt_flags.append("-mips1") -preprocessed_file = tempfile.NamedTemporaryFile(prefix='preprocessed', suffix='.c', delete=False) +asmproc_flags += opt_flags + [str(in_file)] -subprocess.check_call(asm_processor + opt_flags + [in_file], stdout=preprocessed_file) -subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, preprocessed_file.name]) -subprocess.check_call(asm_processor + opt_flags + [in_file, '--post-process', out_file, '--assembler', assembler_sh, '--asm-prelude', prelude]) +# Drop .mdebug and .gptab sections from resulting binaries. This makes +# resulting .o files much smaller and speeds up builds, but loses line +# number debug data. +# asmproc_flags += ["--drop-mdebug-gptab"] + +# Convert encoding before compiling. +# asmproc_flags += ["--input-enc", "utf-8", "--output-enc", "euc-jp"] + +with tempfile.TemporaryDirectory(prefix="asm_processor") as tmpdirname: + tmpdir_path = Path(tmpdirname) + preprocessed_filename = "preprocessed_" + uuid.uuid4().hex + ".c" + preprocessed_path = tmpdir_path / preprocessed_filename + + with preprocessed_path.open("wb") as f: + functions, deps = asm_processor.run(asmproc_flags, outfile=f) + + if keep_preprocessed_files: + import shutil + + keep_output_dir = Path("./asm_processor_preprocessed") + keep_output_dir.mkdir(parents=True, exist_ok=True) + + shutil.copy( + preprocessed_path, + keep_output_dir / (in_file.stem + "_" + preprocessed_filename), + ) + + compile_cmdline = ( + compiler + + compile_args + + ["-I", str(in_dir), "-o", str(out_file), str(preprocessed_path)] + ) + + try: + subprocess.check_call(compile_cmdline) + except subprocess.CalledProcessError as e: + print("Failed to compile file " + str(in_file) + ". Command line:") + print() + print(" ".join(shlex.quote(x) for x in compile_cmdline)) + print() + sys.exit(55) + + asm_processor.run( + asmproc_flags + + [ + "--post-process", + str(out_file), + "--assembler", + assembler_sh, + "--asm-prelude", + str(asm_prelude_path), + ], + functions=functions, + ) + + deps_file = out_file.with_suffix(".asmproc.d") + if deps: + with deps_file.open("w") as f: + f.write(str(out_file) + ": " + " \\\n ".join(deps) + "\n") + for dep in deps: + f.write("\n" + dep + ":\n") + else: + try: + deps_file.unlink() + except OSError: + pass diff --git a/tools/asm_processor/prelude.inc b/tools/asm_processor/prelude.inc index 0c111a2a9..3e58ff149 100644 --- a/tools/asm_processor/prelude.inc +++ b/tools/asm_processor/prelude.inc @@ -1,5 +1,43 @@ .set noat .set noreorder .set gp=64 -.include "macros.inc" +.macro glabel label + .global \label + \label: +.endm + +# Float register aliases (o32 ABI, odd ones are rarely used) + +.set $fv0, $f0 +.set $fv0f, $f1 +.set $fv1, $f2 +.set $fv1f, $f3 +.set $ft0, $f4 +.set $ft0f, $f5 +.set $ft1, $f6 +.set $ft1f, $f7 +.set $ft2, $f8 +.set $ft2f, $f9 +.set $ft3, $f10 +.set $ft3f, $f11 +.set $fa0, $f12 +.set $fa0f, $f13 +.set $fa1, $f14 +.set $fa1f, $f15 +.set $ft4, $f16 +.set $ft4f, $f17 +.set $ft5, $f18 +.set $ft5f, $f19 +.set $fs0, $f20 +.set $fs0f, $f21 +.set $fs1, $f22 +.set $fs1f, $f23 +.set $fs2, $f24 +.set $fs2f, $f25 +.set $fs3, $f26 +.set $fs3f, $f27 +.set $fs4, $f28 +.set $fs4f, $f29 +.set $fs5, $f30 +.set $fs5f, $f31