diff --git a/asm/math_util/sins_2.s b/asm/math_util/sins_2.s index ece436a5..cd64d912 100644 --- a/asm/math_util/sins_2.s +++ b/asm/math_util/sins_2.s @@ -1,4 +1,4 @@ -glabel coss_2 +glabel coss_2 /* Official name: mathCos */ /* 07148C 8007088C 24844000 */ addiu $a0, $a0, 0x4000 glabel sins_2 /* Official name: mathSin */ /* 071490 80070890 00041440 */ sll $v0, $a0, 0x11 diff --git a/asm/non_matchings/fade_transition/render_fade_circle.s b/asm/non_matchings/fade_transition/render_fade_circle.s deleted file mode 100644 index 27cce9bc..00000000 --- a/asm/non_matchings/fade_transition/render_fade_circle.s +++ /dev/null @@ -1,99 +0,0 @@ -glabel render_fade_circle -/* 0C2E74 800C2274 27BDFFE8 */ addiu $sp, $sp, -0x18 -/* 0C2E78 800C2278 AFBF0014 */ sw $ra, 0x14($sp) -/* 0C2E7C 800C227C AFA40018 */ sw $a0, 0x18($sp) -/* 0C2E80 800C2280 AFA5001C */ sw $a1, 0x1c($sp) -/* 0C2E84 800C2284 0C01ECF4 */ jal reset_render_settings -/* 0C2E88 800C2288 AFA60020 */ sw $a2, 0x20($sp) -/* 0C2E8C 800C228C 3C03800E */ lui $v1, %hi(sTransitionTaskNum) # $v1, 0x800e -/* 0C2E90 800C2290 8C6331D0 */ lw $v1, %lo(sTransitionTaskNum)($v1) -/* 0C2E94 800C2294 8FAE0018 */ lw $t6, 0x18($sp) -/* 0C2E98 800C2298 3C07800E */ lui $a3, %hi(sTransitionVtx) # $a3, 0x800e -/* 0C2E9C 800C229C 00037880 */ sll $t7, $v1, 2 -/* 0C2EA0 800C22A0 8DC20000 */ lw $v0, ($t6) -/* 0C2EA4 800C22A4 00EF3821 */ addu $a3, $a3, $t7 -/* 0C2EA8 800C22A8 3C08800E */ lui $t0, %hi(sTransitionTris) # $t0, 0x800e -/* 0C2EAC 800C22AC 8CE731C0 */ lw $a3, %lo(sTransitionVtx)($a3) -/* 0C2EB0 800C22B0 010F4021 */ addu $t0, $t0, $t7 -/* 0C2EB4 800C22B4 8D0831C8 */ lw $t0, %lo(sTransitionTris)($t0) -/* 0C2EB8 800C22B8 3C19800E */ lui $t9, %hi(dTransitionShapeSettings) # $t9, 0x800e -/* 0C2EBC 800C22BC 00402025 */ move $a0, $v0 -/* 0C2EC0 800C22C0 27393648 */ addiu $t9, %lo(dTransitionShapeSettings) # addiu $t9, $t9, 0x3648 -/* 0C2EC4 800C22C4 3C180600 */ lui $t8, 0x600 -/* 0C2EC8 800C22C8 AC980000 */ sw $t8, ($a0) -/* 0C2ECC 800C22CC AC990004 */ sw $t9, 4($a0) -/* 0C2ED0 800C22D0 3C068000 */ lui $a2, 0x8000 -/* 0C2ED4 800C22D4 00E62021 */ addu $a0, $a3, $a2 -/* 0C2ED8 800C22D8 308B0006 */ andi $t3, $a0, 6 -/* 0C2EDC 800C22DC 356C0088 */ ori $t4, $t3, 0x88 -/* 0C2EE0 800C22E0 318D00FF */ andi $t5, $t4, 0xff -/* 0C2EE4 800C22E4 24430008 */ addiu $v1, $v0, 8 -/* 0C2EE8 800C22E8 3C090400 */ lui $t1, 0x400 -/* 0C2EEC 800C22EC AC640004 */ sw $a0, 4($v1) -/* 0C2EF0 800C22F0 000D7400 */ sll $t6, $t5, 0x10 -/* 0C2EF4 800C22F4 24E700B4 */ addiu $a3, $a3, 0xb4 -/* 0C2EF8 800C22F8 00E62021 */ addu $a0, $a3, $a2 -/* 0C2EFC 800C22FC 01C97825 */ or $t7, $t6, $t1 -/* 0C2F00 800C2300 308B0006 */ andi $t3, $a0, 6 -/* 0C2F04 800C2304 35F8014C */ ori $t8, $t7, 0x14c -/* 0C2F08 800C2308 24650008 */ addiu $a1, $v1, 8 -/* 0C2F0C 800C230C 356C0088 */ ori $t4, $t3, 0x88 -/* 0C2F10 800C2310 3C0A05F0 */ lui $t2, (0x05F00100 >> 16) # lui $t2, 0x5f0 -/* 0C2F14 800C2314 AC780000 */ sw $t8, ($v1) -/* 0C2F18 800C2318 354A0100 */ ori $t2, (0x05F00100 & 0xFFFF) # ori $t2, $t2, 0x100 -/* 0C2F1C 800C231C 318D00FF */ andi $t5, $t4, 0xff -/* 0C2F20 800C2320 0106C821 */ addu $t9, $t0, $a2 -/* 0C2F24 800C2324 000D7400 */ sll $t6, $t5, 0x10 -/* 0C2F28 800C2328 ACB90004 */ sw $t9, 4($a1) -/* 0C2F2C 800C232C ACAA0000 */ sw $t2, ($a1) -/* 0C2F30 800C2330 24A20008 */ addiu $v0, $a1, 8 -/* 0C2F34 800C2334 AC440004 */ sw $a0, 4($v0) -/* 0C2F38 800C2338 01C97825 */ or $t7, $t6, $t1 -/* 0C2F3C 800C233C 24E700B4 */ addiu $a3, $a3, 0xb4 -/* 0C2F40 800C2340 00E62021 */ addu $a0, $a3, $a2 -/* 0C2F44 800C2344 35F8014C */ ori $t8, $t7, 0x14c -/* 0C2F48 800C2348 24450008 */ addiu $a1, $v0, 8 -/* 0C2F4C 800C234C AC580000 */ sw $t8, ($v0) -/* 0C2F50 800C2350 308B0006 */ andi $t3, $a0, 6 -/* 0C2F54 800C2354 25080100 */ addiu $t0, $t0, 0x100 -/* 0C2F58 800C2358 0106C821 */ addu $t9, $t0, $a2 -/* 0C2F5C 800C235C 356C0088 */ ori $t4, $t3, 0x88 -/* 0C2F60 800C2360 318D00FF */ andi $t5, $t4, 0xff -/* 0C2F64 800C2364 ACB90004 */ sw $t9, 4($a1) -/* 0C2F68 800C2368 ACAA0000 */ sw $t2, ($a1) -/* 0C2F6C 800C236C 24A30008 */ addiu $v1, $a1, 8 -/* 0C2F70 800C2370 AC640004 */ sw $a0, 4($v1) -/* 0C2F74 800C2374 000D7400 */ sll $t6, $t5, 0x10 -/* 0C2F78 800C2378 24E700B4 */ addiu $a3, $a3, 0xb4 -/* 0C2F7C 800C237C 00E62021 */ addu $a0, $a3, $a2 -/* 0C2F80 800C2380 01C97825 */ or $t7, $t6, $t1 -/* 0C2F84 800C2384 35F8014C */ ori $t8, $t7, 0x14c -/* 0C2F88 800C2388 308B0006 */ andi $t3, $a0, 6 -/* 0C2F8C 800C238C 356C0088 */ ori $t4, $t3, 0x88 -/* 0C2F90 800C2390 AC780000 */ sw $t8, ($v1) -/* 0C2F94 800C2394 24620008 */ addiu $v0, $v1, 8 -/* 0C2F98 800C2398 25080100 */ addiu $t0, $t0, 0x100 -/* 0C2F9C 800C239C 0106C821 */ addu $t9, $t0, $a2 -/* 0C2FA0 800C23A0 318D00FF */ andi $t5, $t4, 0xff -/* 0C2FA4 800C23A4 000D7400 */ sll $t6, $t5, 0x10 -/* 0C2FA8 800C23A8 AC590004 */ sw $t9, 4($v0) -/* 0C2FAC 800C23AC 24430008 */ addiu $v1, $v0, 8 -/* 0C2FB0 800C23B0 01C97825 */ or $t7, $t6, $t1 -/* 0C2FB4 800C23B4 AC4A0000 */ sw $t2, ($v0) -/* 0C2FB8 800C23B8 35F8014C */ ori $t8, $t7, 0x14c -/* 0C2FBC 800C23BC AC780000 */ sw $t8, ($v1) -/* 0C2FC0 800C23C0 AC640004 */ sw $a0, 4($v1) -/* 0C2FC4 800C23C4 24650008 */ addiu $a1, $v1, 8 -/* 0C2FC8 800C23C8 25080100 */ addiu $t0, $t0, 0x100 -/* 0C2FCC 800C23CC 0106C821 */ addu $t9, $t0, $a2 -/* 0C2FD0 800C23D0 ACB90004 */ sw $t9, 4($a1) -/* 0C2FD4 800C23D4 ACAA0000 */ sw $t2, ($a1) -/* 0C2FD8 800C23D8 8FA40018 */ lw $a0, 0x18($sp) -/* 0C2FDC 800C23DC 24A20008 */ addiu $v0, $a1, 8 -/* 0C2FE0 800C23E0 0C01ECF4 */ jal reset_render_settings -/* 0C2FE4 800C23E4 AC820000 */ sw $v0, ($a0) -/* 0C2FE8 800C23E8 8FBF0014 */ lw $ra, 0x14($sp) -/* 0C2FEC 800C23EC 27BD0018 */ addiu $sp, $sp, 0x18 -/* 0C2FF0 800C23F0 03E00008 */ jr $ra -/* 0C2FF4 800C23F4 00000000 */ nop - diff --git a/asm/non_matchings/fade_transition/render_fade_waves.s b/asm/non_matchings/fade_transition/render_fade_waves.s deleted file mode 100644 index 9e918905..00000000 --- a/asm/non_matchings/fade_transition/render_fade_waves.s +++ /dev/null @@ -1,90 +0,0 @@ -glabel render_fade_waves -/* 0C2FF8 800C23F8 27BDFFE0 */ addiu $sp, $sp, -0x20 -/* 0C2FFC 800C23FC AFBF001C */ sw $ra, 0x1c($sp) -/* 0C3000 800C2400 AFB00018 */ sw $s0, 0x18($sp) -/* 0C3004 800C2404 AFA40020 */ sw $a0, 0x20($sp) -/* 0C3008 800C2408 AFA50024 */ sw $a1, 0x24($sp) -/* 0C300C 800C240C 0C01ECF4 */ jal reset_render_settings -/* 0C3010 800C2410 AFA60028 */ sw $a2, 0x28($sp) -/* 0C3014 800C2414 3C03800E */ lui $v1, %hi(sTransitionTaskNum) # $v1, 0x800e -/* 0C3018 800C2418 8FAE0020 */ lw $t6, 0x20($sp) -/* 0C301C 800C241C 8C6331D0 */ lw $v1, %lo(sTransitionTaskNum)($v1) -/* 0C3020 800C2420 8DC20000 */ lw $v0, ($t6) -/* 0C3024 800C2424 00037880 */ sll $t7, $v1, 2 -/* 0C3028 800C2428 3C06800E */ lui $a2, %hi(sTransitionVtx) # $a2, 0x800e -/* 0C302C 800C242C 3C07800E */ lui $a3, %hi(sTransitionTris) # $a3, 0x800e -/* 0C3030 800C2430 00CF3021 */ addu $a2, $a2, $t7 -/* 0C3034 800C2434 00EF3821 */ addu $a3, $a3, $t7 -/* 0C3038 800C2438 00402025 */ move $a0, $v0 -/* 0C303C 800C243C 8CC631C0 */ lw $a2, %lo(sTransitionVtx)($a2) -/* 0C3040 800C2440 8CE731C8 */ lw $a3, %lo(sTransitionTris)($a3) -/* 0C3044 800C2444 3C19800E */ lui $t9, %hi(dTransitionShapeSettings) # $t9, 0x800e -/* 0C3048 800C2448 27393648 */ addiu $t9, %lo(dTransitionShapeSettings) # addiu $t9, $t9, 0x3648 -/* 0C304C 800C244C 3C180600 */ lui $t8, 0x600 -/* 0C3050 800C2450 3C1005D0 */ lui $s0, (0x05D000E0 >> 16) # lui $s0, 0x5d0 -/* 0C3054 800C2454 3C0D05B0 */ lui $t5, (0x05B000C0 >> 16) # lui $t5, 0x5b0 -/* 0C3058 800C2458 AC980000 */ sw $t8, ($a0) -/* 0C305C 800C245C AC990004 */ sw $t9, 4($a0) -/* 0C3060 800C2460 35AD00C0 */ ori $t5, (0x05B000C0 & 0xFFFF) # ori $t5, $t5, 0xc0 -/* 0C3064 800C2464 361000E0 */ ori $s0, (0x05D000E0 & 0xFFFF) # ori $s0, $s0, 0xe0 -/* 0C3068 800C2468 00004025 */ move $t0, $zero -/* 0C306C 800C246C 241F0006 */ li $ra, 6 -/* 0C3070 800C2470 240C0004 */ li $t4, 4 -/* 0C3074 800C2474 240B0001 */ li $t3, 1 -/* 0C3078 800C2478 3C0A0400 */ lui $t2, 0x400 -/* 0C307C 800C247C 3C098000 */ lui $t1, 0x8000 -/* 0C3080 800C2480 24420008 */ addiu $v0, $v0, 8 -.L800C2484: -/* 0C3084 800C2484 110B0003 */ beq $t0, $t3, .L800C2494 -/* 0C3088 800C2488 00401825 */ move $v1, $v0 -/* 0C308C 800C248C 150C0013 */ bne $t0, $t4, .L800C24DC -/* 0C3090 800C2490 00C92021 */ addu $a0, $a2, $t1 -.L800C2494: -/* 0C3094 800C2494 00C92021 */ addu $a0, $a2, $t1 -/* 0C3098 800C2498 308E0006 */ andi $t6, $a0, 6 -/* 0C309C 800C249C 35CF0068 */ ori $t7, $t6, 0x68 -/* 0C30A0 800C24A0 31F800FF */ andi $t8, $t7, 0xff -/* 0C30A4 800C24A4 0018CC00 */ sll $t9, $t8, 0x10 -/* 0C30A8 800C24A8 032A7025 */ or $t6, $t9, $t2 -/* 0C30AC 800C24AC 24420008 */ addiu $v0, $v0, 8 -/* 0C30B0 800C24B0 35CF0104 */ ori $t7, $t6, 0x104 -/* 0C30B4 800C24B4 00402825 */ move $a1, $v0 -/* 0C30B8 800C24B8 AC6F0000 */ sw $t7, ($v1) -/* 0C30BC 800C24BC AC640004 */ sw $a0, 4($v1) -/* 0C30C0 800C24C0 00E9C021 */ addu $t8, $a3, $t1 -/* 0C30C4 800C24C4 ACB80004 */ sw $t8, 4($a1) -/* 0C30C8 800C24C8 ACAD0000 */ sw $t5, ($a1) -/* 0C30CC 800C24CC 24420008 */ addiu $v0, $v0, 8 -/* 0C30D0 800C24D0 24C6008C */ addiu $a2, $a2, 0x8c -/* 0C30D4 800C24D4 10000012 */ b .L800C2520 -/* 0C30D8 800C24D8 24E700C0 */ addiu $a3, $a3, 0xc0 -.L800C24DC: -/* 0C30DC 800C24DC 30990006 */ andi $t9, $a0, 6 -/* 0C30E0 800C24E0 372E0078 */ ori $t6, $t9, 0x78 -/* 0C30E4 800C24E4 31CF00FF */ andi $t7, $t6, 0xff -/* 0C30E8 800C24E8 000FC400 */ sll $t8, $t7, 0x10 -/* 0C30EC 800C24EC 00401825 */ move $v1, $v0 -/* 0C30F0 800C24F0 24420008 */ addiu $v0, $v0, 8 -/* 0C30F4 800C24F4 030AC825 */ or $t9, $t8, $t2 -/* 0C30F8 800C24F8 372E0128 */ ori $t6, $t9, 0x128 -/* 0C30FC 800C24FC 00402825 */ move $a1, $v0 -/* 0C3100 800C2500 AC6E0000 */ sw $t6, ($v1) -/* 0C3104 800C2504 AC640004 */ sw $a0, 4($v1) -/* 0C3108 800C2508 00E97821 */ addu $t7, $a3, $t1 -/* 0C310C 800C250C ACAF0004 */ sw $t7, 4($a1) -/* 0C3110 800C2510 ACB00000 */ sw $s0, ($a1) -/* 0C3114 800C2514 24420008 */ addiu $v0, $v0, 8 -/* 0C3118 800C2518 24C600A0 */ addiu $a2, $a2, 0xa0 -/* 0C311C 800C251C 24E700E0 */ addiu $a3, $a3, 0xe0 -.L800C2520: -/* 0C3120 800C2520 25080001 */ addiu $t0, $t0, 1 -/* 0C3124 800C2524 151FFFD7 */ bne $t0, $ra, .L800C2484 -/* 0C3128 800C2528 00000000 */ nop -/* 0C312C 800C252C 8FA40020 */ lw $a0, 0x20($sp) -/* 0C3130 800C2530 0C01ECF4 */ jal reset_render_settings -/* 0C3134 800C2534 AC820000 */ sw $v0, ($a0) -/* 0C3138 800C2538 8FBF001C */ lw $ra, 0x1c($sp) -/* 0C313C 800C253C 8FB00018 */ lw $s0, 0x18($sp) -/* 0C3140 800C2540 03E00008 */ jr $ra -/* 0C3144 800C2544 27BD0020 */ addiu $sp, $sp, 0x20 - diff --git a/asm/non_matchings/objects/func_800143A8.s b/asm/non_matchings/objects/func_800143A8.s deleted file mode 100644 index a561cbf4..00000000 --- a/asm/non_matchings/objects/func_800143A8.s +++ /dev/null @@ -1,304 +0,0 @@ -glabel func_800143A8 -/* 014FA8 800143A8 27BDFF50 */ addiu $sp, $sp, -0xb0 -/* 014FAC 800143AC 3C0E8012 */ lui $t6, %hi(gObjectCurrDisplayList) # $t6, 0x8012 -/* 014FB0 800143B0 8DCEAE8C */ lw $t6, %lo(gObjectCurrDisplayList)($t6) -/* 014FB4 800143B4 AFBF003C */ sw $ra, 0x3c($sp) -/* 014FB8 800143B8 AFBE0038 */ sw $fp, 0x38($sp) -/* 014FBC 800143BC AFB70034 */ sw $s7, 0x34($sp) -/* 014FC0 800143C0 AFB60030 */ sw $s6, 0x30($sp) -/* 014FC4 800143C4 AFB5002C */ sw $s5, 0x2c($sp) -/* 014FC8 800143C8 AFB40028 */ sw $s4, 0x28($sp) -/* 014FCC 800143CC AFB30024 */ sw $s3, 0x24($sp) -/* 014FD0 800143D0 AFB20020 */ sw $s2, 0x20($sp) -/* 014FD4 800143D4 AFB1001C */ sw $s1, 0x1c($sp) -/* 014FD8 800143D8 AFB00018 */ sw $s0, 0x18($sp) -/* 014FDC 800143DC AFA500B4 */ sw $a1, 0xb4($sp) -/* 014FE0 800143E0 AFA700BC */ sw $a3, 0xbc($sp) -/* 014FE4 800143E4 AFAE0074 */ sw $t6, 0x74($sp) -/* 014FE8 800143E8 84890028 */ lh $t1, 0x28($a0) -/* 014FEC 800143EC 0080B825 */ move $s7, $a0 -/* 014FF0 800143F0 00C9082A */ slt $at, $a2, $t1 -/* 014FF4 800143F4 00C05025 */ move $t2, $a2 -/* 014FF8 800143F8 102000F2 */ beqz $at, .L800147C4 -/* 014FFC 800143FC 0000F825 */ move $ra, $zero -/* 015000 80014400 00065880 */ sll $t3, $a2, 2 -/* 015004 80014404 01665823 */ subu $t3, $t3, $a2 -/* 015008 80014408 000B5880 */ sll $t3, $t3, 2 -/* 01500C 8001440C 3C1E0400 */ lui $fp, 0x400 -/* 015010 80014410 3C148000 */ lui $s4, 0x8000 -/* 015014 80014414 00E06825 */ move $t5, $a3 -.L80014418: -/* 015018 80014418 8EEF0038 */ lw $t7, 0x38($s7) -/* 01501C 8001441C 31B90004 */ andi $t9, $t5, 4 -/* 015020 80014420 01EB1021 */ addu $v0, $t7, $t3 -/* 015024 80014424 8C480008 */ lw $t0, 8($v0) -/* 015028 80014428 00000000 */ nop -/* 01502C 8001442C 31180004 */ andi $t8, $t0, 4 -/* 015030 80014430 13000003 */ beqz $t8, .L80014440 -/* 015034 80014434 31030100 */ andi $v1, $t0, 0x100 -/* 015038 80014438 132000DC */ beqz $t9, .L800147AC -/* 01503C 8001443C 00000000 */ nop -.L80014440: -/* 015040 80014440 146000D7 */ bnez $v1, .L800147A0 -/* 015044 80014444 240100FF */ li $at, 255 -/* 015048 80014448 84440002 */ lh $a0, 2($v0) -/* 01504C 8001444C 844E000E */ lh $t6, 0xe($v0) -/* 015050 80014450 8FAF00C0 */ lw $t7, 0xc0($sp) -/* 015054 80014454 84450004 */ lh $a1, 4($v0) -/* 015058 80014458 31A90004 */ andi $t1, $t5, 4 -/* 01505C 8001445C 11E00004 */ beqz $t7, .L80014470 -/* 015060 80014460 01C48823 */ subu $s1, $t6, $a0 -/* 015064 80014464 80500001 */ lb $s0, 1($v0) -/* 015068 80014468 10000003 */ b .L80014478 -/* 01506C 8001446C 84580010 */ lh $t8, 0x10($v0) -.L80014470: -/* 015070 80014470 02208025 */ move $s0, $s1 -/* 015074 80014474 84580010 */ lh $t8, 0x10($v0) -.L80014478: -/* 015078 80014478 8EF90008 */ lw $t9, 8($s7) -/* 01507C 8001447C 00057100 */ sll $t6, $a1, 4 -/* 015080 80014480 0305A823 */ subu $s5, $t8, $a1 -/* 015084 80014484 032E7821 */ addu $t7, $t9, $t6 -/* 015088 80014488 8FB800B4 */ lw $t8, 0xb4($sp) -/* 01508C 8001448C AFAF007C */ sw $t7, 0x7c($sp) -/* 015090 80014490 00047080 */ sll $t6, $a0, 2 -/* 015094 80014494 90430000 */ lbu $v1, ($v0) -/* 015098 80014498 8F190044 */ lw $t9, 0x44($t8) -/* 01509C 8001449C 01C47021 */ addu $t6, $t6, $a0 -/* 0150A0 800144A0 000E7040 */ sll $t6, $t6, 1 -/* 0150A4 800144A4 14610005 */ bne $v1, $at, .L800144BC -/* 0150A8 800144A8 032E9821 */ addu $s3, $t9, $t6 -/* 0150AC 800144AC 00003825 */ move $a3, $zero -/* 0150B0 800144B0 00009025 */ move $s2, $zero -/* 0150B4 800144B4 10000009 */ b .L800144DC -/* 0150B8 800144B8 0000B025 */ move $s6, $zero -.L800144BC: -/* 0150BC 800144BC 8EF80000 */ lw $t8, ($s7) -/* 0150C0 800144C0 90470007 */ lbu $a3, 7($v0) -/* 0150C4 800144C4 0003C8C0 */ sll $t9, $v1, 3 -/* 0150C8 800144C8 03197021 */ addu $t6, $t8, $t9 -/* 0150CC 800144CC 00077B80 */ sll $t7, $a3, 0xe -/* 0150D0 800144D0 8DD20000 */ lw $s2, ($t6) -/* 0150D4 800144D4 01E03825 */ move $a3, $t7 -/* 0150D8 800144D8 24160001 */ li $s6, 1 -.L800144DC: -/* 0150DC 800144DC 11200007 */ beqz $t1, .L800144FC -/* 0150E0 800144E0 35060008 */ ori $a2, $t0, 8 -/* 0150E4 800144E4 2401FFFB */ li $at, -5 -/* 0150E8 800144E8 01A17824 */ and $t7, $t5, $at -/* 0150EC 800144EC 010FC024 */ and $t8, $t0, $t7 -/* 0150F0 800144F0 17000002 */ bnez $t8, .L800144FC -/* 0150F4 800144F4 34D90004 */ ori $t9, $a2, 4 -/* 0150F8 800144F8 03203025 */ move $a2, $t9 -.L800144FC: -/* 0150FC 800144FC 3C0E800E */ lui $t6, %hi(D_800DC720) # $t6, 0x800e -/* 015100 80014500 8DCEC720 */ lw $t6, %lo(D_800DC720)($t6) -/* 015104 80014504 02402025 */ move $a0, $s2 -/* 015108 80014508 15C0000E */ bnez $t6, .L80014544 -/* 01510C 8001450C 00E02825 */ move $a1, $a3 -/* 015110 80014510 AFBF009C */ sw $ra, 0x9c($sp) -/* 015114 80014514 27A40074 */ addiu $a0, $sp, 0x74 -/* 015118 80014518 02402825 */ move $a1, $s2 -/* 01511C 8001451C AFAA00AC */ sw $t2, 0xac($sp) -/* 015120 80014520 0C01ED3A */ jal load_and_set_texture -/* 015124 80014524 AFAB0048 */ sw $t3, 0x48($sp) -/* 015128 80014528 8FAA00AC */ lw $t2, 0xac($sp) -/* 01512C 8001452C 8FAB0048 */ lw $t3, 0x48($sp) -/* 015130 80014530 3C0CBC00 */ lui $t4, (0xBC00000A >> 16) # lui $t4, 0xbc00 -/* 015134 80014534 8FAD00BC */ lw $t5, 0xbc($sp) -/* 015138 80014538 8FBF009C */ lw $ra, 0x9c($sp) -/* 01513C 8001453C 1000001C */ b .L800145B0 -/* 015140 80014540 358C000A */ ori $t4, (0xBC00000A & 0xFFFF) # ori $t4, $t4, 0xa -.L80014544: -/* 015144 80014544 AFBF009C */ sw $ra, 0x9c($sp) -/* 015148 80014548 AFAA00AC */ sw $t2, 0xac($sp) -/* 01514C 8001454C 0C01ED1B */ jal func_8007B46C -/* 015150 80014550 AFAB0048 */ sw $t3, 0x48($sp) -/* 015154 80014554 3C068012 */ lui $a2, %hi(gObjectCurrDisplayList) # $a2, 0x8012 -/* 015158 80014558 24C6AE8C */ addiu $a2, %lo(gObjectCurrDisplayList) # addiu $a2, $a2, -0x5174 -/* 01515C 8001455C 8CC30000 */ lw $v1, ($a2) -/* 015160 80014560 3C010700 */ lui $at, 0x700 -/* 015164 80014564 246F0008 */ addiu $t7, $v1, 8 -/* 015168 80014568 ACCF0000 */ sw $t7, ($a2) -/* 01516C 8001456C 8445000A */ lh $a1, 0xa($v0) -/* 015170 80014570 8FAA00AC */ lw $t2, 0xac($sp) -/* 015174 80014574 30B800FF */ andi $t8, $a1, 0xff -/* 015178 80014578 0018CC00 */ sll $t9, $t8, 0x10 -/* 01517C 8001457C 000578C0 */ sll $t7, $a1, 3 -/* 015180 80014580 31F8FFFF */ andi $t8, $t7, 0xffff -/* 015184 80014584 03217025 */ or $t6, $t9, $at -/* 015188 80014588 8FAB0048 */ lw $t3, 0x48($sp) -/* 01518C 8001458C 8FAD00BC */ lw $t5, 0xbc($sp) -/* 015190 80014590 8FBF009C */ lw $ra, 0x9c($sp) -/* 015194 80014594 01D8C825 */ or $t9, $t6, $t8 -/* 015198 80014598 AC790000 */ sw $t9, ($v1) -/* 01519C 8001459C 8C4F000C */ lw $t7, 0xc($v0) -/* 0151A0 800145A0 3C0CBC00 */ lui $t4, (0xBC00000A >> 16) # lui $t4, 0xbc00 -/* 0151A4 800145A4 01F47021 */ addu $t6, $t7, $s4 -/* 0151A8 800145A8 358C000A */ ori $t4, (0xBC00000A & 0xFFFF) # ori $t4, $t4, 0xa -/* 0151AC 800145AC AC6E0004 */ sw $t6, 4($v1) -.L800145B0: -/* 0151B0 800145B0 16110015 */ bne $s0, $s1, .L80014608 -/* 0151B4 800145B4 3C010500 */ lui $at, 0x500 -/* 0151B8 800145B8 8FA30074 */ lw $v1, 0x74($sp) -/* 0151BC 800145BC 02741021 */ addu $v0, $s3, $s4 -/* 0151C0 800145C0 262FFFFF */ addiu $t7, $s1, -1 -/* 0151C4 800145C4 24790008 */ addiu $t9, $v1, 8 -/* 0151C8 800145C8 AFB90074 */ sw $t9, 0x74($sp) -/* 0151CC 800145CC 000F70C0 */ sll $t6, $t7, 3 -/* 0151D0 800145D0 30580006 */ andi $t8, $v0, 6 -/* 0151D4 800145D4 01D8C825 */ or $t9, $t6, $t8 -/* 0151D8 800145D8 332F00FF */ andi $t7, $t9, 0xff -/* 0151DC 800145DC 000F7400 */ sll $t6, $t7, 0x10 -/* 0151E0 800145E0 0011C8C0 */ sll $t9, $s1, 3 -/* 0151E4 800145E4 03317821 */ addu $t7, $t9, $s1 -/* 0151E8 800145E8 01DEC025 */ or $t8, $t6, $fp -/* 0151EC 800145EC 000F7040 */ sll $t6, $t7, 1 -/* 0151F0 800145F0 25D90008 */ addiu $t9, $t6, 8 -/* 0151F4 800145F4 332FFFFF */ andi $t7, $t9, 0xffff -/* 0151F8 800145F8 030F7025 */ or $t6, $t8, $t7 -/* 0151FC 800145FC AC6E0000 */ sw $t6, ($v1) -/* 015200 80014600 10000054 */ b .L80014754 -/* 015204 80014604 AC620004 */ sw $v0, 4($v1) -.L80014608: -/* 015208 80014608 1A000034 */ blez $s0, .L800146DC -/* 01520C 8001460C 24180080 */ li $t8, 128 -/* 015210 80014610 8FA40074 */ lw $a0, 0x74($sp) -/* 015214 80014614 02741021 */ addu $v0, $s3, $s4 -/* 015218 80014618 260FFFFF */ addiu $t7, $s0, -1 -/* 01521C 8001461C 24980008 */ addiu $t8, $a0, 8 -/* 015220 80014620 AFB80074 */ sw $t8, 0x74($sp) -/* 015224 80014624 000F70C0 */ sll $t6, $t7, 3 -/* 015228 80014628 30590006 */ andi $t9, $v0, 6 -/* 01522C 8001462C 01D9C025 */ or $t8, $t6, $t9 -/* 015230 80014630 330F00FF */ andi $t7, $t8, 0xff -/* 015234 80014634 000F7400 */ sll $t6, $t7, 0x10 -/* 015238 80014638 0010C0C0 */ sll $t8, $s0, 3 -/* 01523C 8001463C 03107821 */ addu $t7, $t8, $s0 -/* 015240 80014640 01DEC825 */ or $t9, $t6, $fp -/* 015244 80014644 000F7040 */ sll $t6, $t7, 1 -/* 015248 80014648 25D80008 */ addiu $t8, $t6, 8 -/* 01524C 8001464C 330FFFFF */ andi $t7, $t8, 0xffff -/* 015250 80014650 032F7025 */ or $t6, $t9, $t7 -/* 015254 80014654 AC8E0000 */ sw $t6, ($a0) -/* 015258 80014658 AC820004 */ sw $v0, 4($a0) -/* 01525C 8001465C 8FB80074 */ lw $t8, 0x74($sp) -/* 015260 80014660 240F0080 */ li $t7, 128 -/* 015264 80014664 27190008 */ addiu $t9, $t8, 8 -/* 015268 80014668 AFB90074 */ sw $t9, 0x74($sp) -/* 01526C 8001466C 0010C880 */ sll $t9, $s0, 2 -/* 015270 80014670 AF0F0004 */ sw $t7, 4($t8) -/* 015274 80014674 AF0C0000 */ sw $t4, ($t8) -/* 015278 80014678 8FA60074 */ lw $a2, 0x74($sp) -/* 01527C 8001467C 0330C821 */ addu $t9, $t9, $s0 -/* 015280 80014680 0019C840 */ sll $t9, $t9, 1 -/* 015284 80014684 02797821 */ addu $t7, $s3, $t9 -/* 015288 80014688 02301823 */ subu $v1, $s1, $s0 -/* 01528C 8001468C 24D80008 */ addiu $t8, $a2, 8 -/* 015290 80014690 AFB80074 */ sw $t8, 0x74($sp) -/* 015294 80014694 246EFFFF */ addiu $t6, $v1, -1 -/* 015298 80014698 01F43821 */ addu $a3, $t7, $s4 -/* 01529C 8001469C 30F90006 */ andi $t9, $a3, 6 -/* 0152A0 800146A0 000EC0C0 */ sll $t8, $t6, 3 -/* 0152A4 800146A4 03197825 */ or $t7, $t8, $t9 -/* 0152A8 800146A8 35EE0001 */ ori $t6, $t7, 1 -/* 0152AC 800146AC 31D800FF */ andi $t8, $t6, 0xff -/* 0152B0 800146B0 0018CC00 */ sll $t9, $t8, 0x10 -/* 0152B4 800146B4 000370C0 */ sll $t6, $v1, 3 -/* 0152B8 800146B8 01C3C021 */ addu $t8, $t6, $v1 -/* 0152BC 800146BC 033E7825 */ or $t7, $t9, $fp -/* 0152C0 800146C0 0018C840 */ sll $t9, $t8, 1 -/* 0152C4 800146C4 272E0008 */ addiu $t6, $t9, 8 -/* 0152C8 800146C8 31D8FFFF */ andi $t8, $t6, 0xffff -/* 0152CC 800146CC 01F8C825 */ or $t9, $t7, $t8 -/* 0152D0 800146D0 ACD90000 */ sw $t9, ($a2) -/* 0152D4 800146D4 10000019 */ b .L8001473C -/* 0152D8 800146D8 ACC70004 */ sw $a3, 4($a2) -.L800146DC: -/* 0152DC 800146DC 8FAE0074 */ lw $t6, 0x74($sp) -/* 0152E0 800146E0 02741021 */ addu $v0, $s3, $s4 -/* 0152E4 800146E4 25CF0008 */ addiu $t7, $t6, 8 -/* 0152E8 800146E8 AFAF0074 */ sw $t7, 0x74($sp) -/* 0152EC 800146EC ADD80004 */ sw $t8, 4($t6) -/* 0152F0 800146F0 ADCC0000 */ sw $t4, ($t6) -/* 0152F4 800146F4 8FA40074 */ lw $a0, 0x74($sp) -/* 0152F8 800146F8 262FFFFF */ addiu $t7, $s1, -1 -/* 0152FC 800146FC 248E0008 */ addiu $t6, $a0, 8 -/* 015300 80014700 AFAE0074 */ sw $t6, 0x74($sp) -/* 015304 80014704 000FC0C0 */ sll $t8, $t7, 3 -/* 015308 80014708 30590006 */ andi $t9, $v0, 6 -/* 01530C 8001470C 03197025 */ or $t6, $t8, $t9 -/* 015310 80014710 31CF00FF */ andi $t7, $t6, 0xff -/* 015314 80014714 000FC400 */ sll $t8, $t7, 0x10 -/* 015318 80014718 001170C0 */ sll $t6, $s1, 3 -/* 01531C 8001471C 01D17821 */ addu $t7, $t6, $s1 -/* 015320 80014720 031EC825 */ or $t9, $t8, $fp -/* 015324 80014724 000FC040 */ sll $t8, $t7, 1 -/* 015328 80014728 270E0008 */ addiu $t6, $t8, 8 -/* 01532C 8001472C 31CFFFFF */ andi $t7, $t6, 0xffff -/* 015330 80014730 032FC025 */ or $t8, $t9, $t7 -/* 015334 80014734 AC980000 */ sw $t8, ($a0) -/* 015338 80014738 AC820004 */ sw $v0, 4($a0) -.L8001473C: -/* 01533C 8001473C 8FAE0074 */ lw $t6, 0x74($sp) -/* 015340 80014740 240F0040 */ li $t7, 64 -/* 015344 80014744 25D90008 */ addiu $t9, $t6, 8 -/* 015348 80014748 AFB90074 */ sw $t9, 0x74($sp) -/* 01534C 8001474C ADCF0004 */ sw $t7, 4($t6) -/* 015350 80014750 ADCC0000 */ sw $t4, ($t6) -.L80014754: -/* 015354 80014754 8FA20074 */ lw $v0, 0x74($sp) -/* 015358 80014758 26B9FFFF */ addiu $t9, $s5, -1 -/* 01535C 8001475C 00197900 */ sll $t7, $t9, 4 -/* 015360 80014760 244E0008 */ addiu $t6, $v0, 8 -/* 015364 80014764 AFAE0074 */ sw $t6, 0x74($sp) -/* 015368 80014768 01F6C025 */ or $t8, $t7, $s6 -/* 01536C 8001476C 330E00FF */ andi $t6, $t8, 0xff -/* 015370 80014770 000ECC00 */ sll $t9, $t6, 0x10 -/* 015374 80014774 0015C100 */ sll $t8, $s5, 4 -/* 015378 80014778 330EFFFF */ andi $t6, $t8, 0xffff -/* 01537C 8001477C 03217825 */ or $t7, $t9, $at -/* 015380 80014780 01EEC825 */ or $t9, $t7, $t6 -/* 015384 80014784 AC590000 */ sw $t9, ($v0) -/* 015388 80014788 8FB8007C */ lw $t8, 0x7c($sp) -/* 01538C 8001478C 00000000 */ nop -/* 015390 80014790 03147821 */ addu $t7, $t8, $s4 -/* 015394 80014794 AC4F0004 */ sw $t7, 4($v0) -/* 015398 80014798 86E90028 */ lh $t1, 0x28($s7) -/* 01539C 8001479C 00000000 */ nop -.L800147A0: -/* 0153A0 800147A0 254A0001 */ addiu $t2, $t2, 1 -/* 0153A4 800147A4 10000002 */ b .L800147B0 -/* 0153A8 800147A8 256B000C */ addiu $t3, $t3, 0xc -.L800147AC: -/* 0153AC 800147AC 241F0001 */ li $ra, 1 -.L800147B0: -/* 0153B0 800147B0 0149082A */ slt $at, $t2, $t1 -/* 0153B4 800147B4 10200004 */ beqz $at, .L800147C8 -/* 0153B8 800147B8 0149082A */ slt $at, $t2, $t1 -/* 0153BC 800147BC 13E0FF16 */ beqz $ra, .L80014418 -/* 0153C0 800147C0 00000000 */ nop -.L800147C4: -/* 0153C4 800147C4 0149082A */ slt $at, $t2, $t1 -.L800147C8: -/* 0153C8 800147C8 14200003 */ bnez $at, .L800147D8 -/* 0153CC 800147CC 8FAE0074 */ lw $t6, 0x74($sp) -/* 0153D0 800147D0 240AFFFF */ li $t2, -1 -/* 0153D4 800147D4 8FAE0074 */ lw $t6, 0x74($sp) -.L800147D8: -/* 0153D8 800147D8 8FBF003C */ lw $ra, 0x3c($sp) -/* 0153DC 800147DC 3C018012 */ lui $at, %hi(gObjectCurrDisplayList) # $at, 0x8012 -/* 0153E0 800147E0 8FB00018 */ lw $s0, 0x18($sp) -/* 0153E4 800147E4 8FB1001C */ lw $s1, 0x1c($sp) -/* 0153E8 800147E8 8FB20020 */ lw $s2, 0x20($sp) -/* 0153EC 800147EC 8FB30024 */ lw $s3, 0x24($sp) -/* 0153F0 800147F0 8FB40028 */ lw $s4, 0x28($sp) -/* 0153F4 800147F4 8FB5002C */ lw $s5, 0x2c($sp) -/* 0153F8 800147F8 8FB60030 */ lw $s6, 0x30($sp) -/* 0153FC 800147FC 8FB70034 */ lw $s7, 0x34($sp) -/* 015400 80014800 8FBE0038 */ lw $fp, 0x38($sp) -/* 015404 80014804 27BD00B0 */ addiu $sp, $sp, 0xb0 -/* 015408 80014808 01401025 */ move $v0, $t2 -/* 01540C 8001480C 03E00008 */ jr $ra -/* 015410 80014810 AC2EAE8C */ sw $t6, %lo(gObjectCurrDisplayList)($at) - diff --git a/asm/non_matchings/particles/func_800B3740.s b/asm/non_matchings/particles/func_800B3740.s deleted file mode 100644 index bde4601c..00000000 --- a/asm/non_matchings/particles/func_800B3740.s +++ /dev/null @@ -1,476 +0,0 @@ -glabel func_800B3740 -/* 0B4340 800B3740 27BDFFC0 */ addiu $sp, $sp, -0x40 -/* 0B4344 800B3744 AFBF0024 */ sw $ra, 0x24($sp) -/* 0B4348 800B3748 AFB10020 */ sw $s1, 0x20($sp) -/* 0B434C 800B374C AFB0001C */ sw $s0, 0x1c($sp) -/* 0B4350 800B3750 AFA60048 */ sw $a2, 0x48($sp) -/* 0B4354 800B3754 AFA7004C */ sw $a3, 0x4c($sp) -/* 0B4358 800B3758 8C8E0040 */ lw $t6, 0x40($a0) -/* 0B435C 800B375C 8FAF0050 */ lw $t7, 0x50($sp) -/* 0B4360 800B3760 00A08025 */ move $s0, $a1 -/* 0B4364 800B3764 01CFC024 */ and $t8, $t6, $t7 -/* 0B4368 800B3768 00808825 */ move $s1, $a0 -/* 0B436C 800B376C 13000007 */ beqz $t8, .L800B378C -/* 0B4370 800B3770 240B000A */ li $t3, 10 -/* 0B4374 800B3774 3C19800E */ lui $t9, %hi(D_800E2CDC) # $t9, 0x800e -/* 0B4378 800B3778 8F392CDC */ lw $t9, %lo(D_800E2CDC)($t9) -/* 0B437C 800B377C 00000000 */ nop -/* 0B4380 800B3780 2B210200 */ slti $at, $t9, 0x200 -/* 0B4384 800B3784 142001B2 */ bnez $at, .L800B3E50 -/* 0B4388 800B3788 00000000 */ nop -.L800B378C: -/* 0B438C 800B378C 862A005C */ lh $t2, 0x5c($s1) -/* 0B4390 800B3790 00000000 */ nop -/* 0B4394 800B3794 000A6203 */ sra $t4, $t2, 8 -/* 0B4398 800B3798 318A00FF */ andi $t2, $t4, 0xff -/* 0B439C 800B379C 194001AC */ blez $t2, .L800B3E50 -/* 0B43A0 800B37A0 00000000 */ nop -/* 0B43A4 800B37A4 8623002C */ lh $v1, 0x2c($s1) -/* 0B43A8 800B37A8 24050004 */ li $a1, 4 -/* 0B43AC 800B37AC 10A300B3 */ beq $a1, $v1, .L800B3A7C -/* 0B43B0 800B37B0 24010003 */ li $at, 3 -/* 0B43B4 800B37B4 106100B1 */ beq $v1, $at, .L800B3A7C -/* 0B43B8 800B37B8 240900FF */ li $t1, 255 -/* 0B43BC 800B37BC 8E020000 */ lw $v0, ($s0) -/* 0B43C0 800B37C0 3C0FFB00 */ lui $t7, 0xfb00 -/* 0B43C4 800B37C4 244E0008 */ addiu $t6, $v0, 8 -/* 0B43C8 800B37C8 AE0E0000 */ sw $t6, ($s0) -/* 0B43CC 800B37CC AC4F0000 */ sw $t7, ($v0) -/* 0B43D0 800B37D0 922E006D */ lbu $t6, 0x6d($s1) -/* 0B43D4 800B37D4 9239006C */ lbu $t9, 0x6c($s1) -/* 0B43D8 800B37D8 922D006E */ lbu $t5, 0x6e($s1) -/* 0B43DC 800B37DC 000E7C00 */ sll $t7, $t6, 0x10 -/* 0B43E0 800B37E0 00196600 */ sll $t4, $t9, 0x18 -/* 0B43E4 800B37E4 9239006F */ lbu $t9, 0x6f($s1) -/* 0B43E8 800B37E8 018FC025 */ or $t8, $t4, $t7 -/* 0B43EC 800B37EC 000D7200 */ sll $t6, $t5, 8 -/* 0B43F0 800B37F0 030E6025 */ or $t4, $t8, $t6 -/* 0B43F4 800B37F4 01996825 */ or $t5, $t4, $t9 -/* 0B43F8 800B37F8 11490012 */ beq $t2, $t1, .L800B3844 -/* 0B43FC 800B37FC AC4D0004 */ sw $t5, 4($v0) -/* 0B4400 800B3800 8E040000 */ lw $a0, ($s0) -/* 0B4404 800B3804 3C0EFA00 */ lui $t6, 0xfa00 -/* 0B4408 800B3808 24980008 */ addiu $t8, $a0, 8 -/* 0B440C 800B380C AE180000 */ sw $t8, ($s0) -/* 0B4410 800B3810 AC8E0000 */ sw $t6, ($a0) -/* 0B4414 800B3814 8623004A */ lh $v1, 0x4a($s1) -/* 0B4418 800B3818 240B010E */ li $t3, 270 -/* 0B441C 800B381C 306F00FF */ andi $t7, $v1, 0xff -/* 0B4420 800B3820 000F6600 */ sll $t4, $t7, 0x18 -/* 0B4424 800B3824 000FCC00 */ sll $t9, $t7, 0x10 -/* 0B4428 800B3828 000FC200 */ sll $t8, $t7, 8 -/* 0B442C 800B382C 01996825 */ or $t5, $t4, $t9 -/* 0B4430 800B3830 01B87025 */ or $t6, $t5, $t8 -/* 0B4434 800B3834 314F00FF */ andi $t7, $t2, 0xff -/* 0B4438 800B3838 01CF6025 */ or $t4, $t6, $t7 -/* 0B443C 800B383C 10000008 */ b .L800B3860 -/* 0B4440 800B3840 AC8C0004 */ sw $t4, 4($a0) -.L800B3844: -/* 0B4444 800B3844 8E020000 */ lw $v0, ($s0) -/* 0B4448 800B3848 3C0DFA00 */ lui $t5, 0xfa00 -/* 0B444C 800B384C 24590008 */ addiu $t9, $v0, 8 -/* 0B4450 800B3850 AE190000 */ sw $t9, ($s0) -/* 0B4454 800B3854 2418FFFF */ li $t8, -1 -/* 0B4458 800B3858 AC580004 */ sw $t8, 4($v0) -/* 0B445C 800B385C AC4D0000 */ sw $t5, ($v0) -.L800B3860: -/* 0B4460 800B3860 862E002C */ lh $t6, 0x2c($s1) -/* 0B4464 800B3864 24010080 */ li $at, 128 -/* 0B4468 800B3868 15C10026 */ bne $t6, $at, .L800B3904 -/* 0B446C 800B386C 00000000 */ nop -/* 0B4470 800B3870 86230018 */ lh $v1, 0x18($s1) -/* 0B4474 800B3874 8E280044 */ lw $t0, 0x44($s1) -/* 0B4478 800B3878 00037A03 */ sra $t7, $v1, 8 -/* 0B447C 800B387C A62F0018 */ sh $t7, 0x18($s1) -/* 0B4480 800B3880 862C0018 */ lh $t4, 0x18($s1) -/* 0B4484 800B3884 850D0000 */ lh $t5, ($t0) -/* 0B4488 800B3888 01890019 */ multu $t4, $t1 -/* 0B448C 800B388C 00601025 */ move $v0, $v1 -/* 0B4490 800B3890 02002025 */ move $a0, $s0 -/* 0B4494 800B3894 02203825 */ move $a3, $s1 -/* 0B4498 800B3898 0000C812 */ mflo $t9 -/* 0B449C 800B389C 00000000 */ nop -/* 0B44A0 800B38A0 00000000 */ nop -/* 0B44A4 800B38A4 032D001A */ div $zero, $t9, $t5 -/* 0B44A8 800B38A8 15A00002 */ bnez $t5, .L800B38B4 -/* 0B44AC 800B38AC 00000000 */ nop -/* 0B44B0 800B38B0 0007000D */ break 7 -.L800B38B4: -/* 0B44B4 800B38B4 2401FFFF */ li $at, -1 -/* 0B44B8 800B38B8 15A10004 */ bne $t5, $at, .L800B38CC -/* 0B44BC 800B38BC 3C018000 */ lui $at, 0x8000 -/* 0B44C0 800B38C0 17210002 */ bne $t9, $at, .L800B38CC -/* 0B44C4 800B38C4 00000000 */ nop -/* 0B44C8 800B38C8 0006000D */ break 6 -.L800B38CC: -/* 0B44CC 800B38CC 0000C012 */ mflo $t8 -/* 0B44D0 800B38D0 A6380018 */ sh $t8, 0x18($s1) -/* 0B44D4 800B38D4 8FA6004C */ lw $a2, 0x4c($sp) -/* 0B44D8 800B38D8 8FA50048 */ lw $a1, 0x48($sp) -/* 0B44DC 800B38DC AFAA0038 */ sw $t2, 0x38($sp) -/* 0B44E0 800B38E0 AFA20034 */ sw $v0, 0x34($sp) -/* 0B44E4 800B38E4 AFAB0014 */ sw $t3, 0x14($sp) -/* 0B44E8 800B38E8 0C01A145 */ jal render_sprite_billboard -/* 0B44EC 800B38EC AFA80010 */ sw $t0, 0x10($sp) -/* 0B44F0 800B38F0 8FA20034 */ lw $v0, 0x34($sp) -/* 0B44F4 800B38F4 8FAA0038 */ lw $t2, 0x38($sp) -/* 0B44F8 800B38F8 240900FF */ li $t1, 255 -/* 0B44FC 800B38FC 10000048 */ b .L800B3A20 -/* 0B4500 800B3900 A6220018 */ sh $v0, 0x18($s1) -.L800B3904: -/* 0B4504 800B3904 8E230044 */ lw $v1, 0x44($s1) -/* 0B4508 800B3908 8FA50048 */ lw $a1, 0x48($sp) -/* 0B450C 800B390C 8C6E0000 */ lw $t6, ($v1) -/* 0B4510 800B3910 02002025 */ move $a0, $s0 -/* 0B4514 800B3914 11C00042 */ beqz $t6, .L800B3A20 -/* 0B4518 800B3918 02203025 */ move $a2, $s1 -/* 0B451C 800B391C 44802000 */ mtc1 $zero, $f4 -/* 0B4520 800B3920 3C073F80 */ lui $a3, 0x3f80 -/* 0B4524 800B3924 AFA30030 */ sw $v1, 0x30($sp) -/* 0B4528 800B3928 AFAA0038 */ sw $t2, 0x38($sp) -/* 0B452C 800B392C AFAB003C */ sw $t3, 0x3c($sp) -/* 0B4530 800B3930 0C01A521 */ jal camera_push_model_mtx -/* 0B4534 800B3934 E7A40010 */ swc1 $f4, 0x10($sp) -/* 0B4538 800B3938 8FA30030 */ lw $v1, 0x30($sp) -/* 0B453C 800B393C 86270018 */ lh $a3, 0x18($s1) -/* 0B4540 800B3940 8FA6003C */ lw $a2, 0x3c($sp) -/* 0B4544 800B3944 8C650000 */ lw $a1, ($v1) -/* 0B4548 800B3948 00077A00 */ sll $t7, $a3, 8 -/* 0B454C 800B394C 01E03825 */ move $a3, $t7 -/* 0B4550 800B3950 0C01ED3A */ jal load_and_set_texture -/* 0B4554 800B3954 02002025 */ move $a0, $s0 -/* 0B4558 800B3958 8E020000 */ lw $v0, ($s0) -/* 0B455C 800B395C 8FA30030 */ lw $v1, 0x30($sp) -/* 0B4560 800B3960 244C0008 */ addiu $t4, $v0, 8 -/* 0B4564 800B3964 AE0C0000 */ sw $t4, ($s0) -/* 0B4568 800B3968 8C780008 */ lw $t8, 8($v1) -/* 0B456C 800B396C 84650004 */ lh $a1, 4($v1) -/* 0B4570 800B3970 3C078000 */ lui $a3, 0x8000 -/* 0B4574 800B3974 03077021 */ addu $t6, $t8, $a3 -/* 0B4578 800B3978 24B9FFFF */ addiu $t9, $a1, -1 -/* 0B457C 800B397C 001968C0 */ sll $t5, $t9, 3 -/* 0B4580 800B3980 31CF0006 */ andi $t7, $t6, 6 -/* 0B4584 800B3984 01AF6025 */ or $t4, $t5, $t7 -/* 0B4588 800B3988 319900FF */ andi $t9, $t4, 0xff -/* 0B458C 800B398C 000568C0 */ sll $t5, $a1, 3 -/* 0B4590 800B3990 0019C400 */ sll $t8, $t9, 0x10 -/* 0B4594 800B3994 01A57821 */ addu $t7, $t5, $a1 -/* 0B4598 800B3998 000F6040 */ sll $t4, $t7, 1 -/* 0B459C 800B399C 3C010400 */ lui $at, 0x400 -/* 0B45A0 800B39A0 03017025 */ or $t6, $t8, $at -/* 0B45A4 800B39A4 25990008 */ addiu $t9, $t4, 8 -/* 0B45A8 800B39A8 3338FFFF */ andi $t8, $t9, 0xffff -/* 0B45AC 800B39AC 01D86825 */ or $t5, $t6, $t8 -/* 0B45B0 800B39B0 AC4D0000 */ sw $t5, ($v0) -/* 0B45B4 800B39B4 8C6F0008 */ lw $t7, 8($v1) -/* 0B45B8 800B39B8 3C010500 */ lui $at, 0x500 -/* 0B45BC 800B39BC 01E76021 */ addu $t4, $t7, $a3 -/* 0B45C0 800B39C0 AC4C0004 */ sw $t4, 4($v0) -/* 0B45C4 800B39C4 8E020000 */ lw $v0, ($s0) -/* 0B45C8 800B39C8 02002025 */ move $a0, $s0 -/* 0B45CC 800B39CC 24590008 */ addiu $t9, $v0, 8 -/* 0B45D0 800B39D0 AE190000 */ sw $t9, ($s0) -/* 0B45D4 800B39D4 84660006 */ lh $a2, 6($v1) -/* 0B45D8 800B39D8 00000000 */ nop -/* 0B45DC 800B39DC 24CEFFFF */ addiu $t6, $a2, -1 -/* 0B45E0 800B39E0 000EC100 */ sll $t8, $t6, 4 -/* 0B45E4 800B39E4 370D0001 */ ori $t5, $t8, 1 -/* 0B45E8 800B39E8 31AF00FF */ andi $t7, $t5, 0xff -/* 0B45EC 800B39EC 000F6400 */ sll $t4, $t7, 0x10 -/* 0B45F0 800B39F0 00067100 */ sll $t6, $a2, 4 -/* 0B45F4 800B39F4 31D8FFFF */ andi $t8, $t6, 0xffff -/* 0B45F8 800B39F8 0181C825 */ or $t9, $t4, $at -/* 0B45FC 800B39FC 03386825 */ or $t5, $t9, $t8 -/* 0B4600 800B3A00 AC4D0000 */ sw $t5, ($v0) -/* 0B4604 800B3A04 8C6F000C */ lw $t7, 0xc($v1) -/* 0B4608 800B3A08 00000000 */ nop -/* 0B460C 800B3A0C 01E76021 */ addu $t4, $t7, $a3 -/* 0B4610 800B3A10 0C01A690 */ jal func_80069A40 -/* 0B4614 800B3A14 AC4C0004 */ sw $t4, 4($v0) -/* 0B4618 800B3A18 8FAA0038 */ lw $t2, 0x38($sp) -/* 0B461C 800B3A1C 240900FF */ li $t1, 255 -.L800B3A20: -/* 0B4620 800B3A20 15490005 */ bne $t2, $t1, .L800B3A38 -/* 0B4624 800B3A24 3C18FA00 */ lui $t8, 0xfa00 -/* 0B4628 800B3A28 862E004A */ lh $t6, 0x4a($s1) -/* 0B462C 800B3A2C 00000000 */ nop -/* 0B4630 800B3A30 112E0007 */ beq $t1, $t6, .L800B3A50 -/* 0B4634 800B3A34 00000000 */ nop -.L800B3A38: -/* 0B4638 800B3A38 8E020000 */ lw $v0, ($s0) -/* 0B463C 800B3A3C 240DFFFF */ li $t5, -1 -/* 0B4640 800B3A40 24590008 */ addiu $t9, $v0, 8 -/* 0B4644 800B3A44 AE190000 */ sw $t9, ($s0) -/* 0B4648 800B3A48 AC4D0004 */ sw $t5, 4($v0) -/* 0B464C 800B3A4C AC580000 */ sw $t8, ($v0) -.L800B3A50: -/* 0B4650 800B3A50 922F006F */ lbu $t7, 0x6f($s1) -/* 0B4654 800B3A54 3C0EFB00 */ lui $t6, 0xfb00 -/* 0B4658 800B3A58 11E000FE */ beqz $t7, .L800B3E54 -/* 0B465C 800B3A5C 8FBF0024 */ lw $ra, 0x24($sp) -/* 0B4660 800B3A60 8E020000 */ lw $v0, ($s0) -/* 0B4664 800B3A64 2419FF00 */ li $t9, -256 -/* 0B4668 800B3A68 244C0008 */ addiu $t4, $v0, 8 -/* 0B466C 800B3A6C AE0C0000 */ sw $t4, ($s0) -/* 0B4670 800B3A70 AC590004 */ sw $t9, 4($v0) -/* 0B4674 800B3A74 100000F6 */ b .L800B3E50 -/* 0B4678 800B3A78 AC4E0000 */ sw $t6, ($v0) -.L800B3A7C: -/* 0B467C 800B3A7C 8E020000 */ lw $v0, ($s0) -/* 0B4680 800B3A80 3C0DFB00 */ lui $t5, 0xfb00 -/* 0B4684 800B3A84 24580008 */ addiu $t8, $v0, 8 -/* 0B4688 800B3A88 AE180000 */ sw $t8, ($s0) -/* 0B468C 800B3A8C 240FFF00 */ li $t7, -256 -/* 0B4690 800B3A90 AC4F0004 */ sw $t7, 4($v0) -/* 0B4694 800B3A94 AC4D0000 */ sw $t5, ($v0) -/* 0B4698 800B3A98 8623002C */ lh $v1, 0x2c($s1) -/* 0B469C 800B3A9C 24010003 */ li $at, 3 -/* 0B46A0 800B3AA0 14A30063 */ bne $a1, $v1, .L800B3C30 -/* 0B46A4 800B3AA4 00000000 */ nop -/* 0B46A8 800B3AA8 862C003A */ lh $t4, 0x3a($s1) -/* 0B46AC 800B3AAC 00000000 */ nop -/* 0B46B0 800B3AB0 198000E8 */ blez $t4, .L800B3E54 -/* 0B46B4 800B3AB4 8FBF0024 */ lw $ra, 0x24($sp) -/* 0B46B8 800B3AB8 8E020000 */ lw $v0, ($s0) -/* 0B46BC 800B3ABC 3C19FA00 */ lui $t9, 0xfa00 -/* 0B46C0 800B3AC0 244E0008 */ addiu $t6, $v0, 8 -/* 0B46C4 800B3AC4 AE0E0000 */ sw $t6, ($s0) -/* 0B46C8 800B3AC8 AC590000 */ sw $t9, ($v0) -/* 0B46CC 800B3ACC 8623004A */ lh $v1, 0x4a($s1) -/* 0B46D0 800B3AD0 00000000 */ nop -/* 0B46D4 800B3AD4 307800FF */ andi $t8, $v1, 0xff -/* 0B46D8 800B3AD8 00186E00 */ sll $t5, $t8, 0x18 -/* 0B46DC 800B3ADC 00187C00 */ sll $t7, $t8, 0x10 -/* 0B46E0 800B3AE0 01AF6025 */ or $t4, $t5, $t7 -/* 0B46E4 800B3AE4 00187200 */ sll $t6, $t8, 8 -/* 0B46E8 800B3AE8 018EC825 */ or $t9, $t4, $t6 -/* 0B46EC 800B3AEC 373800FF */ ori $t8, $t9, 0xff -/* 0B46F0 800B3AF0 AC580004 */ sw $t8, 4($v0) -/* 0B46F4 800B3AF4 822D0077 */ lb $t5, 0x77($s1) -/* 0B46F8 800B3AF8 00000000 */ nop -/* 0B46FC 800B3AFC 15A00003 */ bnez $t5, .L800B3B0C -/* 0B4700 800B3B00 00000000 */ nop -/* 0B4704 800B3B04 0C02CF99 */ jal func_800B3E64 -/* 0B4708 800B3B08 02202025 */ move $a0, $s1 -.L800B3B0C: -/* 0B470C 800B3B0C 92220075 */ lbu $v0, 0x75($s1) -/* 0B4710 800B3B10 8E230044 */ lw $v1, 0x44($s1) -/* 0B4714 800B3B14 000278C0 */ sll $t7, $v0, 3 -/* 0B4718 800B3B18 000F7080 */ sll $t6, $t7, 2 -/* 0B471C 800B3B1C 8C6C0008 */ lw $t4, 8($v1) -/* 0B4720 800B3B20 01CF7021 */ addu $t6, $t6, $t7 -/* 0B4724 800B3B24 000E7040 */ sll $t6, $t6, 1 -/* 0B4728 800B3B28 018EC821 */ addu $t9, $t4, $t6 -/* 0B472C 800B3B2C AFB9002C */ sw $t9, 0x2c($sp) -/* 0B4730 800B3B30 86270018 */ lh $a3, 0x18($s1) -/* 0B4734 800B3B34 3C060800 */ lui $a2, (0x0800010B >> 16) # lui $a2, 0x800 -/* 0B4738 800B3B38 8C650000 */ lw $a1, ($v1) -/* 0B473C 800B3B3C 0007C200 */ sll $t8, $a3, 8 -/* 0B4740 800B3B40 03003825 */ move $a3, $t8 -/* 0B4744 800B3B44 34C6010B */ ori $a2, (0x0800010B & 0xFFFF) # ori $a2, $a2, 0x10b -/* 0B4748 800B3B48 02002025 */ move $a0, $s0 -/* 0B474C 800B3B4C 0C01ED3A */ jal load_and_set_texture -/* 0B4750 800B3B50 AFA30030 */ sw $v1, 0x30($sp) -/* 0B4754 800B3B54 8E020000 */ lw $v0, ($s0) -/* 0B4758 800B3B58 8FA30030 */ lw $v1, 0x30($sp) -/* 0B475C 800B3B5C 244D0008 */ addiu $t5, $v0, 8 -/* 0B4760 800B3B60 AE0D0000 */ sw $t5, ($s0) -/* 0B4764 800B3B64 8FAF002C */ lw $t7, 0x2c($sp) -/* 0B4768 800B3B68 84650004 */ lh $a1, 4($v1) -/* 0B476C 800B3B6C 3C078000 */ lui $a3, 0x8000 -/* 0B4770 800B3B70 01E74021 */ addu $t0, $t7, $a3 -/* 0B4774 800B3B74 24ACFFFF */ addiu $t4, $a1, -1 -/* 0B4778 800B3B78 000C70C0 */ sll $t6, $t4, 3 -/* 0B477C 800B3B7C 31190006 */ andi $t9, $t0, 6 -/* 0B4780 800B3B80 01D9C025 */ or $t8, $t6, $t9 -/* 0B4784 800B3B84 330D00FF */ andi $t5, $t8, 0xff -/* 0B4788 800B3B88 000570C0 */ sll $t6, $a1, 3 -/* 0B478C 800B3B8C 000D7C00 */ sll $t7, $t5, 0x10 -/* 0B4790 800B3B90 01C5C821 */ addu $t9, $t6, $a1 -/* 0B4794 800B3B94 0019C040 */ sll $t8, $t9, 1 -/* 0B4798 800B3B98 3C010400 */ lui $at, 0x400 -/* 0B479C 800B3B9C 01E16025 */ or $t4, $t7, $at -/* 0B47A0 800B3BA0 270D0008 */ addiu $t5, $t8, 8 -/* 0B47A4 800B3BA4 31AFFFFF */ andi $t7, $t5, 0xffff -/* 0B47A8 800B3BA8 018F7025 */ or $t6, $t4, $t7 -/* 0B47AC 800B3BAC AC4E0000 */ sw $t6, ($v0) -/* 0B47B0 800B3BB0 AC480004 */ sw $t0, 4($v0) -/* 0B47B4 800B3BB4 8E020000 */ lw $v0, ($s0) -/* 0B47B8 800B3BB8 3C010500 */ lui $at, 0x500 -/* 0B47BC 800B3BBC 24590008 */ addiu $t9, $v0, 8 -/* 0B47C0 800B3BC0 AE190000 */ sw $t9, ($s0) -/* 0B47C4 800B3BC4 84660006 */ lh $a2, 6($v1) -/* 0B47C8 800B3BC8 00000000 */ nop -/* 0B47CC 800B3BCC 24D8FFFF */ addiu $t8, $a2, -1 -/* 0B47D0 800B3BD0 00186900 */ sll $t5, $t8, 4 -/* 0B47D4 800B3BD4 35AC0001 */ ori $t4, $t5, 1 -/* 0B47D8 800B3BD8 318F00FF */ andi $t7, $t4, 0xff -/* 0B47DC 800B3BDC 000F7400 */ sll $t6, $t7, 0x10 -/* 0B47E0 800B3BE0 0006C100 */ sll $t8, $a2, 4 -/* 0B47E4 800B3BE4 330DFFFF */ andi $t5, $t8, 0xffff -/* 0B47E8 800B3BE8 01C1C825 */ or $t9, $t6, $at -/* 0B47EC 800B3BEC 032D6025 */ or $t4, $t9, $t5 -/* 0B47F0 800B3BF0 AC4C0000 */ sw $t4, ($v0) -/* 0B47F4 800B3BF4 8C6F000C */ lw $t7, 0xc($v1) -/* 0B47F8 800B3BF8 240100FF */ li $at, 255 -/* 0B47FC 800B3BFC 01E77021 */ addu $t6, $t7, $a3 -/* 0B4800 800B3C00 AC4E0004 */ sw $t6, 4($v0) -/* 0B4804 800B3C04 8638004A */ lh $t8, 0x4a($s1) -/* 0B4808 800B3C08 3C0DFA00 */ lui $t5, 0xfa00 -/* 0B480C 800B3C0C 13010091 */ beq $t8, $at, .L800B3E54 -/* 0B4810 800B3C10 8FBF0024 */ lw $ra, 0x24($sp) -/* 0B4814 800B3C14 8E020000 */ lw $v0, ($s0) -/* 0B4818 800B3C18 240CFFFF */ li $t4, -1 -/* 0B481C 800B3C1C 24590008 */ addiu $t9, $v0, 8 -/* 0B4820 800B3C20 AE190000 */ sw $t9, ($s0) -/* 0B4824 800B3C24 AC4C0004 */ sw $t4, 4($v0) -/* 0B4828 800B3C28 10000089 */ b .L800B3E50 -/* 0B482C 800B3C2C AC4D0000 */ sw $t5, ($v0) -.L800B3C30: -/* 0B4830 800B3C30 14610088 */ bne $v1, $at, .L800B3E54 -/* 0B4834 800B3C34 8FBF0024 */ lw $ra, 0x24($sp) -/* 0B4838 800B3C38 8E020000 */ lw $v0, ($s0) -/* 0B483C 800B3C3C 3C0EFA00 */ lui $t6, 0xfa00 -/* 0B4840 800B3C40 244F0008 */ addiu $t7, $v0, 8 -/* 0B4844 800B3C44 AE0F0000 */ sw $t7, ($s0) -/* 0B4848 800B3C48 AC4E0000 */ sw $t6, ($v0) -/* 0B484C 800B3C4C 8623004A */ lh $v1, 0x4a($s1) -/* 0B4850 800B3C50 3C060800 */ lui $a2, (0x0800010B >> 16) # lui $a2, 0x800 -/* 0B4854 800B3C54 307800FF */ andi $t8, $v1, 0xff -/* 0B4858 800B3C58 0018CE00 */ sll $t9, $t8, 0x18 -/* 0B485C 800B3C5C 00186C00 */ sll $t5, $t8, 0x10 -/* 0B4860 800B3C60 00187A00 */ sll $t7, $t8, 8 -/* 0B4864 800B3C64 032D6025 */ or $t4, $t9, $t5 -/* 0B4868 800B3C68 018F7025 */ or $t6, $t4, $t7 -/* 0B486C 800B3C6C 315800FF */ andi $t8, $t2, 0xff -/* 0B4870 800B3C70 01D8C825 */ or $t9, $t6, $t8 -/* 0B4874 800B3C74 AC590004 */ sw $t9, 4($v0) -/* 0B4878 800B3C78 92250068 */ lbu $a1, 0x68($s1) -/* 0B487C 800B3C7C 34C6010B */ ori $a2, (0x0800010B & 0xFFFF) # ori $a2, $a2, 0x10b -/* 0B4880 800B3C80 28A10002 */ slti $at, $a1, 2 -/* 0B4884 800B3C84 1420003A */ bnez $at, .L800B3D70 -/* 0B4888 800B3C88 02002025 */ move $a0, $s0 -/* 0B488C 800B3C8C 8E230044 */ lw $v1, 0x44($s1) -/* 0B4890 800B3C90 86270018 */ lh $a3, 0x18($s1) -/* 0B4894 800B3C94 8C650000 */ lw $a1, ($v1) -/* 0B4898 800B3C98 00076A00 */ sll $t5, $a3, 8 -/* 0B489C 800B3C9C 01A03825 */ move $a3, $t5 -/* 0B48A0 800B3CA0 AFAA0038 */ sw $t2, 0x38($sp) -/* 0B48A4 800B3CA4 0C01ED3A */ jal load_and_set_texture -/* 0B48A8 800B3CA8 AFA30030 */ sw $v1, 0x30($sp) -/* 0B48AC 800B3CAC 8E020000 */ lw $v0, ($s0) -/* 0B48B0 800B3CB0 8FA30030 */ lw $v1, 0x30($sp) -/* 0B48B4 800B3CB4 8FAA0038 */ lw $t2, 0x38($sp) -/* 0B48B8 800B3CB8 244C0008 */ addiu $t4, $v0, 8 -/* 0B48BC 800B3CBC AE0C0000 */ sw $t4, ($s0) -/* 0B48C0 800B3CC0 8C780008 */ lw $t8, 8($v1) -/* 0B48C4 800B3CC4 84650004 */ lh $a1, 4($v1) -/* 0B48C8 800B3CC8 3C078000 */ lui $a3, 0x8000 -/* 0B48CC 800B3CCC 0307C821 */ addu $t9, $t8, $a3 -/* 0B48D0 800B3CD0 24AFFFFF */ addiu $t7, $a1, -1 -/* 0B48D4 800B3CD4 000F70C0 */ sll $t6, $t7, 3 -/* 0B48D8 800B3CD8 332D0006 */ andi $t5, $t9, 6 -/* 0B48DC 800B3CDC 01CD6025 */ or $t4, $t6, $t5 -/* 0B48E0 800B3CE0 318F00FF */ andi $t7, $t4, 0xff -/* 0B48E4 800B3CE4 000570C0 */ sll $t6, $a1, 3 -/* 0B48E8 800B3CE8 000FC400 */ sll $t8, $t7, 0x10 -/* 0B48EC 800B3CEC 01C56821 */ addu $t5, $t6, $a1 -/* 0B48F0 800B3CF0 000D6040 */ sll $t4, $t5, 1 -/* 0B48F4 800B3CF4 3C010400 */ lui $at, 0x400 -/* 0B48F8 800B3CF8 0301C825 */ or $t9, $t8, $at -/* 0B48FC 800B3CFC 258F0008 */ addiu $t7, $t4, 8 -/* 0B4900 800B3D00 31F8FFFF */ andi $t8, $t7, 0xffff -/* 0B4904 800B3D04 03387025 */ or $t6, $t9, $t8 -/* 0B4908 800B3D08 AC4E0000 */ sw $t6, ($v0) -/* 0B490C 800B3D0C 8C6D0008 */ lw $t5, 8($v1) -/* 0B4910 800B3D10 3C010500 */ lui $at, 0x500 -/* 0B4914 800B3D14 01A76021 */ addu $t4, $t5, $a3 -/* 0B4918 800B3D18 AC4C0004 */ sw $t4, 4($v0) -/* 0B491C 800B3D1C 8E020000 */ lw $v0, ($s0) -/* 0B4920 800B3D20 00000000 */ nop -/* 0B4924 800B3D24 244F0008 */ addiu $t7, $v0, 8 -/* 0B4928 800B3D28 AE0F0000 */ sw $t7, ($s0) -/* 0B492C 800B3D2C 84660006 */ lh $a2, 6($v1) -/* 0B4930 800B3D30 00000000 */ nop -/* 0B4934 800B3D34 24D9FFFF */ addiu $t9, $a2, -1 -/* 0B4938 800B3D38 0019C100 */ sll $t8, $t9, 4 -/* 0B493C 800B3D3C 370E0001 */ ori $t6, $t8, 1 -/* 0B4940 800B3D40 31CD00FF */ andi $t5, $t6, 0xff -/* 0B4944 800B3D44 000D6400 */ sll $t4, $t5, 0x10 -/* 0B4948 800B3D48 0006C900 */ sll $t9, $a2, 4 -/* 0B494C 800B3D4C 3338FFFF */ andi $t8, $t9, 0xffff -/* 0B4950 800B3D50 01817825 */ or $t7, $t4, $at -/* 0B4954 800B3D54 01F87025 */ or $t6, $t7, $t8 -/* 0B4958 800B3D58 AC4E0000 */ sw $t6, ($v0) -/* 0B495C 800B3D5C 8C6D000C */ lw $t5, 0xc($v1) -/* 0B4960 800B3D60 00000000 */ nop -/* 0B4964 800B3D64 01A76021 */ addu $t4, $t5, $a3 -/* 0B4968 800B3D68 1000002C */ b .L800B3E1C -/* 0B496C 800B3D6C AC4C0004 */ sw $t4, 4($v0) -.L800B3D70: -/* 0B4970 800B3D70 18A0002A */ blez $a1, .L800B3E1C -/* 0B4974 800B3D74 02002025 */ move $a0, $s0 -/* 0B4978 800B3D78 8E230044 */ lw $v1, 0x44($s1) -/* 0B497C 800B3D7C 86270018 */ lh $a3, 0x18($s1) -/* 0B4980 800B3D80 8C650000 */ lw $a1, ($v1) -/* 0B4984 800B3D84 3C060800 */ lui $a2, (0x0800010B >> 16) # lui $a2, 0x800 -/* 0B4988 800B3D88 0007CA00 */ sll $t9, $a3, 8 -/* 0B498C 800B3D8C 03203825 */ move $a3, $t9 -/* 0B4990 800B3D90 34C6010B */ ori $a2, (0x0800010B & 0xFFFF) # ori $a2, $a2, 0x10b -/* 0B4994 800B3D94 AFAA0038 */ sw $t2, 0x38($sp) -/* 0B4998 800B3D98 0C01ED3A */ jal load_and_set_texture -/* 0B499C 800B3D9C AFA30030 */ sw $v1, 0x30($sp) -/* 0B49A0 800B3DA0 8E020000 */ lw $v0, ($s0) -/* 0B49A4 800B3DA4 8FA30030 */ lw $v1, 0x30($sp) -/* 0B49A8 800B3DA8 8FAA0038 */ lw $t2, 0x38($sp) -/* 0B49AC 800B3DAC 244F0008 */ addiu $t7, $v0, 8 -/* 0B49B0 800B3DB0 AE0F0000 */ sw $t7, ($s0) -/* 0B49B4 800B3DB4 8C780008 */ lw $t8, 8($v1) -/* 0B49B8 800B3DB8 3C078000 */ lui $a3, 0x8000 -/* 0B49BC 800B3DBC 03077021 */ addu $t6, $t8, $a3 -/* 0B49C0 800B3DC0 31CD0006 */ andi $t5, $t6, 6 -/* 0B49C4 800B3DC4 35AC0018 */ ori $t4, $t5, 0x18 -/* 0B49C8 800B3DC8 319900FF */ andi $t9, $t4, 0xff -/* 0B49CC 800B3DCC 00197C00 */ sll $t7, $t9, 0x10 -/* 0B49D0 800B3DD0 3C010400 */ lui $at, 0x400 -/* 0B49D4 800B3DD4 01E1C025 */ or $t8, $t7, $at -/* 0B49D8 800B3DD8 370E0050 */ ori $t6, $t8, 0x50 -/* 0B49DC 800B3DDC AC4E0000 */ sw $t6, ($v0) -/* 0B49E0 800B3DE0 8C6D0008 */ lw $t5, 8($v1) -/* 0B49E4 800B3DE4 3C0F0501 */ lui $t7, (0x05010010 >> 16) # lui $t7, 0x501 -/* 0B49E8 800B3DE8 01A76021 */ addu $t4, $t5, $a3 -/* 0B49EC 800B3DEC AC4C0004 */ sw $t4, 4($v0) -/* 0B49F0 800B3DF0 8E020000 */ lw $v0, ($s0) -/* 0B49F4 800B3DF4 35EF0010 */ ori $t7, (0x05010010 & 0xFFFF) # ori $t7, $t7, 0x10 -/* 0B49F8 800B3DF8 24590008 */ addiu $t9, $v0, 8 -/* 0B49FC 800B3DFC AE190000 */ sw $t9, ($s0) -/* 0B4A00 800B3E00 AC4F0000 */ sw $t7, ($v0) -/* 0B4A04 800B3E04 846E0006 */ lh $t6, 6($v1) -/* 0B4A08 800B3E08 8C78000C */ lw $t8, 0xc($v1) -/* 0B4A0C 800B3E0C 000E6900 */ sll $t5, $t6, 4 -/* 0B4A10 800B3E10 030D6021 */ addu $t4, $t8, $t5 -/* 0B4A14 800B3E14 0187C821 */ addu $t9, $t4, $a3 -/* 0B4A18 800B3E18 AC590004 */ sw $t9, 4($v0) -.L800B3E1C: -/* 0B4A1C 800B3E1C 240100FF */ li $at, 255 -/* 0B4A20 800B3E20 15410005 */ bne $t2, $at, .L800B3E38 -/* 0B4A24 800B3E24 3C18FA00 */ lui $t8, 0xfa00 -/* 0B4A28 800B3E28 862F004A */ lh $t7, 0x4a($s1) -/* 0B4A2C 800B3E2C 240100FF */ li $at, 255 -/* 0B4A30 800B3E30 11E10008 */ beq $t7, $at, .L800B3E54 -/* 0B4A34 800B3E34 8FBF0024 */ lw $ra, 0x24($sp) -.L800B3E38: -/* 0B4A38 800B3E38 8E020000 */ lw $v0, ($s0) -/* 0B4A3C 800B3E3C 240DFFFF */ li $t5, -1 -/* 0B4A40 800B3E40 244E0008 */ addiu $t6, $v0, 8 -/* 0B4A44 800B3E44 AE0E0000 */ sw $t6, ($s0) -/* 0B4A48 800B3E48 AC4D0004 */ sw $t5, 4($v0) -/* 0B4A4C 800B3E4C AC580000 */ sw $t8, ($v0) -.L800B3E50: -/* 0B4A50 800B3E50 8FBF0024 */ lw $ra, 0x24($sp) -.L800B3E54: -/* 0B4A54 800B3E54 8FB0001C */ lw $s0, 0x1c($sp) -/* 0B4A58 800B3E58 8FB10020 */ lw $s1, 0x20($sp) -/* 0B4A5C 800B3E5C 03E00008 */ jr $ra -/* 0B4A60 800B3E60 27BD0040 */ addiu $sp, $sp, 0x40 - diff --git a/generate_ctx.sh b/generate_ctx.sh index 85c20430..0937326d 100755 --- a/generate_ctx.sh +++ b/generate_ctx.sh @@ -1,2 +1,4 @@ #!/bin/bash -python3 tools/python/m2ctx.py \ No newline at end of file +python3 tools/python/m2ctx.py + +#Remove: if(segment->numberOfBatches >); \ No newline at end of file diff --git a/include/sched.h b/include/sched.h index f0b76a2c..f5534f0f 100644 --- a/include/sched.h +++ b/include/sched.h @@ -3,7 +3,6 @@ #include "types.h" #include "macros.h" -#include "f3ddkr.h" #include "libultra_internal.h" #define OS_SC_RETRACE_MSG 1 diff --git a/include/structs.h b/include/structs.h index f41aa713..7d4cbdbd 100644 --- a/include/structs.h +++ b/include/structs.h @@ -77,8 +77,8 @@ typedef struct TextureHeader { // 6 = IA4 // 7 = CI4 (16 colors) // 8 = CI8 (64 colors) - /* 0x03 */ u8 unk3; - /* 0x04 */ u8 unk4; + /* 0x03 */ s8 unk3; + /* 0x04 */ s8 unk4; /* 0x05 */ u8 numberOfInstances; // Always 1 in the ROM. /* 0x06 */ s16 flags; // 0x04 = Interlaced texture @@ -86,7 +86,7 @@ typedef struct TextureHeader { // 0x80 = V clamp flag. 0 = Wrap, 1 = Clamp /* 0x08 */ s16 ciPaletteOffset; /* 0x0A */ s16 numberOfCommands; // initialized in RAM; Number of commands in the texture display list. (Usually 0x07) - /* 0x0C */ s32* cmd; // initialized in RAM; Pointer to texture display list. + /* 0x0C */ s32 *cmd; // initialized in RAM; Pointer to texture display list. /* 0x10 */ u8 unk10; /* 0x11 */ u8 unk11; /* 0x12 */ u16 numOfTextures; // For animated textures, static textures are just 0x01. Each texture has it's own header. @@ -496,6 +496,7 @@ typedef struct Triangle { /* Size: 12 bytes */ typedef struct TriangleBatchInfo { /* 0x00 */ u8 textureIndex; // 0xFF = No texture +/* 0x01 */ s8 unk1; /* 0x02 */ s16 verticesOffset; /* 0x04 */ s16 facesOffset; /* 0x06 */ u8 unk6; // 0xFF = vertex colors, otherwise use dynamic lighting normals (Objects only) @@ -1645,8 +1646,13 @@ typedef struct ObjectSegment { } ObjectSegment; typedef struct unk800B0698_44_0 { - u8 pad0[0x12]; - u16 unk12; + u8 pad0[0x3]; + /* 0x04 */ s16 unk4; + /* 0x06 */ s16 unk6; + /* 0x08 */ Vertex *unk8; + /* 0x0C */ Triangle *unkC; + /* 0x10 */ u16 unk10; + /* 0x12 */ u16 unk12; } unk800B0698_44_0; typedef struct unk800B0698_44 { diff --git a/lib/asm/non_matchings/unknown_0CF330/__ll_lshift.s b/lib/asm/non_matchings/unknown_0CF330/__ll_lshift.s index 7b6e759f..3886e09a 100644 --- a/lib/asm/non_matchings/unknown_0CF330/__ll_lshift.s +++ b/lib/asm/non_matchings/unknown_0CF330/__ll_lshift.s @@ -11,6 +11,7 @@ glabel __ll_lshift /* 0CF728 800CEB28 03E00008 */ jr $ra /* 0CF72C 800CEB2C 0002103F */ dsra32 $v0, $v0, 0 +glabel func_800CEB30 /* 0CF730 800CEB30 AFA40000 */ sw $a0, ($sp) /* 0CF734 800CEB34 AFA50004 */ sw $a1, 4($sp) /* 0CF738 800CEB38 AFA60008 */ sw $a2, 8($sp) diff --git a/lib/asm/non_matchings/unknown_0CF330/__ull_divremi.s b/lib/asm/non_matchings/unknown_0CF330/__ull_divremi.s index 7dc095a6..6424ac4c 100644 --- a/lib/asm/non_matchings/unknown_0CF330/__ull_divremi.s +++ b/lib/asm/non_matchings/unknown_0CF330/__ull_divremi.s @@ -26,6 +26,7 @@ glabel __ull_divremi /* 0CF850 800CEC50 03E00008 */ jr $ra /* 0CF854 800CEC54 00000000 */ nop +glabel func_800CEC58 /* 0CF858 800CEC58 27BDFFF8 */ addiu $sp, $sp, -8 /* 0CF85C 800CEC5C AFA40008 */ sw $a0, 8($sp) /* 0CF860 800CEC60 AFA5000C */ sw $a1, 0xc($sp) @@ -71,6 +72,7 @@ glabel __ull_divremi /* 0CF8EC 800CECEC 03E00008 */ jr $ra /* 0CF8F0 800CECF0 27BD0008 */ addiu $sp, $sp, 8 +glabel func_800CECF4 /* 0CF8F4 800CECF4 AFA40000 */ sw $a0, ($sp) /* 0CF8F8 800CECF8 AFA50004 */ sw $a1, 4($sp) /* 0CF8FC 800CECFC AFA60008 */ sw $a2, 8($sp) diff --git a/lib/asm/non_matchings/unknown_0D3020/ldiv.s b/lib/asm/non_matchings/unknown_0D3020/ldiv.s index f5c86145..2d22aed9 100644 --- a/lib/asm/non_matchings/unknown_0D3020/ldiv.s +++ b/lib/asm/non_matchings/unknown_0D3020/ldiv.s @@ -36,7 +36,7 @@ glabel ldiv /* 0D81EC 800D75EC 03E00008 */ jr $ra /* 0D81F0 800D75F0 AC880004 */ sw $t0, 4($a0) -/* 0D81F4 800D75F0 00000000 */ nop +/* 0D81F4 800D75F4 00000000 */ nop /* 0D81F8 800D75F8 00000000 */ nop /* 0D81FC 800D75FC 00000000 */ nop diff --git a/lib/src/mips1/sc/sched.c b/lib/src/mips1/sc/sched.c index a9d0ae6f..4ba4f51d 100644 --- a/lib/src/mips1/sc/sched.c +++ b/lib/src/mips1/sc/sched.c @@ -5,7 +5,6 @@ #include "sched.h" #include "types.h" #include "macros.h" -#include "f3ddkr.h" #include "libultra_internal.h" #include "viint.h" diff --git a/lib/src/os/osInitialize.c b/lib/src/os/osInitialize.c index c09ba98f..f2dbe602 100644 --- a/lib/src/os/osInitialize.c +++ b/lib/src/os/osInitialize.c @@ -21,15 +21,13 @@ s32 gLeoFound = FALSE; s32 __osLeoInterrupt(void); extern s32 osViClock; //This is defined in another file somehow -extern u64 *gThread30StackPointer; //TODO: This should be __osFinalrom. Is this reused? -//u32 __osFinalrom; +extern u32 __osFinalrom; //This is defined in another file somehow void osInitialize() { u32 pifdata; u32 clock = 0; u32 leostatus; u32 pistatus; - //__osFinalrom = TRUE; - gThread30StackPointer = (u64 *) TRUE; //TODO: This should be __osFinalrom. Is this reused? + __osFinalrom = TRUE; __osSetSR(__osGetSR() | SR_CU1); //enable fpu __osSetFpcCsr(FPCSR_FS | FPCSR_EV); //flush denorm to zero, enable invalid operation diff --git a/lib/src/os/osViMgr.c b/lib/src/os/osViMgr.c index ad12faaf..c26ee69a 100644 --- a/lib/src/os/osViMgr.c +++ b/lib/src/os/osViMgr.c @@ -13,7 +13,7 @@ extern u32 __osViIntrCount; OSDevMgr __osViDevMgr = {0}; u64 gThread30Stack[0x400]; -u64 *gThread30StackPointer; +u32 __osFinalrom; extern OSThread viThread; extern OSMesgQueue viEventQueue; diff --git a/src/camera.c b/src/camera.c index 69e816fd..61c4391d 100644 --- a/src/camera.c +++ b/src/camera.c @@ -612,32 +612,42 @@ UNUSED void copy_framebuffer_size_to_coords(s32 *x1, s32 *y1, s32 *x2, s32 *y2) } #ifdef NON_EQUIVALENT - +//Alternative attempt: https://decomp.me/scratch/rcJYo // Still a work-in-progress but it doesn't seem to cause any problems, // which is why it is labeled under NON_EQUIVALENT #define SCISSOR_INTERLACE G_SC_NON_INTERLACE void func_80066CDC(Gfx **dlist, MatrixS **mats) { - u32 sp58_vidHeight; - u32 sp54_vidWidth; + u32 sp58_y; + u32 sp54_x; u32 sp50_altPosY; u32 sp4C_altPosX; u32 posX; u32 posY; - u32 videoWidthHalf; - u32 videoHeightHalf; + u32 x; + u32 y; u32 videoHeight; u32 videoWidth; u32 widthAndHeight; + s32 savedCameraID; + s32 originalCameraID; + s32 tempCameraID; + s32 viewports; - if (func_8000E184() && gNumberOfViewports == 0) { + originalCameraID = gActiveCameraID; + savedCameraID = gActiveCameraID; + + if (func_8000E184() && gNumberOfViewports == VIEWPORTS_COUNT_1_PLAYER) { gActiveCameraID = 1; + savedCameraID = 0; } widthAndHeight = get_video_width_and_height_as_s32(); videoHeight = GET_VIDEO_HEIGHT(widthAndHeight); videoWidth = GET_VIDEO_WIDTH(widthAndHeight); - if (gScreenViewports[gActiveCameraID].flags & VIEWPORT_EXTRA_BG) { + if (gScreenViewports[savedCameraID].flags & VIEWPORT_EXTRA_BG) { + tempCameraID = gActiveCameraID; + gActiveCameraID = savedCameraID; gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, gScreenViewports[gActiveCameraID].scissorX1, gScreenViewports[gActiveCameraID].scissorY1, @@ -645,30 +655,33 @@ void func_80066CDC(Gfx **dlist, MatrixS **mats) { gScreenViewports[gActiveCameraID].scissorY2 ); func_80068158(dlist, 0, 0, 0, 0); + gActiveCameraID = tempCameraID; if (mats != 0) { func_80067D3C(dlist, mats); } + gActiveCameraID = originalCameraID; return; } - if (gNumberOfViewports == VIEWPORTS_COUNT_3_PLAYERS) { - gNumberOfViewports = VIEWPORTS_COUNT_4_PLAYERS; + viewports = gNumberOfViewports; + if (viewports == VIEWPORTS_COUNT_3_PLAYERS) { + viewports = VIEWPORTS_COUNT_4_PLAYERS; } - videoHeightHalf = videoHeight >> 1; - videoWidthHalf = videoWidth >> 1; - sp54_vidWidth = videoWidthHalf; - sp58_vidHeight = videoHeightHalf; + y = videoHeight >> 1; + x = videoWidth >> 1; + sp54_x = x; + sp58_y = y; if (osTvType == TV_TYPE_PAL) { - sp58_vidHeight = 145; + sp58_y = 145; } - switch (gNumberOfViewports) { + switch (viewports) { case VIEWPORTS_COUNT_1_PLAYER: - posY = sp58_vidHeight; + posY = sp58_y; if (osTvType == TV_TYPE_PAL) { posY -= 18; } gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, videoWidth, videoHeight); - posX = videoWidthHalf; + posX = x; break; case VIEWPORTS_COUNT_2_PLAYERS: if (gActiveCameraID == 0) { @@ -676,58 +689,58 @@ void func_80066CDC(Gfx **dlist, MatrixS **mats) { if (osTvType == TV_TYPE_PAL) { posY -= 12; } - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, videoWidth, (videoHeightHalf - (videoHeight >> 7))); + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, videoWidth, (y - (videoHeight >> 7))); } else { - posY = videoHeightHalf; + posY = y; posY += videoHeight >> 2; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, (videoHeightHalf + (videoHeight >> 7)), videoWidth, (videoHeight - (videoHeight >> 7))); + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, (y + (videoHeight >> 7)), videoWidth, (videoHeight - (videoHeight >> 7))); } - posX = videoWidthHalf; + posX = x; break; case VIEWPORTS_COUNT_3_PLAYERS: if (gActiveCameraID == 0) { - posY = sp58_vidHeight; + posY = sp58_y; posX = videoWidth >> 2; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, videoWidthHalf - (videoWidth >> 8), videoHeight); + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, 0, x - (videoWidth >> 8), videoHeight); } else { - posY = sp58_vidHeight; - posX = videoWidthHalf; - posX += videoWidth >> 2; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, videoWidthHalf + (videoWidth >> 8), 0, videoWidth - (videoWidth >> 8), videoHeight); + posY = sp58_y; + //posX = x; + posX = x + (videoWidth >> 2); + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, x + (videoWidth >> 8), 0, videoWidth - (videoWidth >> 8), videoHeight); } break; case VIEWPORTS_COUNT_4_PLAYERS: - sp58_vidHeight >>= 1; - sp54_vidWidth = videoWidthHalf >> 1; + sp58_y >>= 1; + sp54_x = x >> 1; posY = 0; posX = 0; switch (gActiveCameraID) { case 0: //Using posX and posY here is not smart since IDO can't optimize out the zero now. //Why here of all places did they do this instead of just setting zero like everywhere else? - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, posX, posY, (videoWidthHalf - (videoWidth >> 8)), (videoHeightHalf - (videoHeight >> 7))); + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, posX, posY, (x - (videoWidth >> 8)), (y - (videoHeight >> 7))); + break; case 1: - posX += videoWidthHalf; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, (videoWidthHalf + (videoWidth >> 8)), 0, ((videoWidthHalf * 2) - (videoWidth >> 8)), (videoHeightHalf - (videoHeight >> 7))); + posX = x; + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, (sp54_x + (videoWidth >> 8)), 0, ((sp54_x + sp54_x) - (videoWidth >> 8)), (y - (videoHeight >> 7))); break; case 2: - posY += videoHeightHalf; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, videoHeightHalf + (videoHeight >> 7), videoWidthHalf - (videoWidth >> 8), (videoHeightHalf * 2) - (videoHeight >> 7)); + posY = y; + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, 0, y + (videoHeight >> 7), x - (videoWidth >> 8), (y + y) - (videoHeight >> 7)); break; case 3: - posY += videoHeightHalf; - posX += videoWidthHalf; - gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, videoWidthHalf + (videoWidth >> 8), videoHeightHalf + (videoHeight >> 7), (videoWidthHalf * 2) - (videoWidth >> 8), (videoHeightHalf * 2) - (videoHeight >> 7)); - break; - default: + posY = y; + posX = x; + gDPSetScissor((*dlist)++, SCISSOR_INTERLACE, (sp54_x + (videoWidth >> 8)), y + (videoHeight >> 7), (x + x) - (videoWidth >> 8), (y + y) - (videoHeight >> 7)); break; } - posY += sp58_vidHeight; - posX += sp54_vidWidth; + posY += sp58_y; + posX += sp54_x; if (osTvType == TV_TYPE_PAL) { - posY -= 6; - if (gActiveCameraID < 2) { + if (gActiveCameraID <= VIEWPORTS_COUNT_2_PLAYERS) { posY -= 20; + } else { + posY -= 6; } } break; @@ -741,10 +754,11 @@ void func_80066CDC(Gfx **dlist, MatrixS **mats) { if (osTvType == TV_TYPE_PAL) { posX -= 4; } - func_80068158(dlist, sp54_vidWidth, sp58_vidHeight, posX, posY); + func_80068158(dlist, sp54_x, sp58_y, posX, posY); if (mats != NULL) { func_80067D3C(dlist, mats); } + gActiveCameraID = originalCameraID; } #else GLOBAL_ASM("asm/non_matchings/camera/func_80066CDC.s") diff --git a/src/fade_transition.c b/src/fade_transition.c index 4ab0c38f..efa51163 100644 --- a/src/fade_transition.c +++ b/src/fade_transition.c @@ -476,7 +476,7 @@ void render_fade_barndoor_horizontal(Gfx **dList, UNUSED MatrixS **mats, UNUSED /** * Renders a transition effect on screen that will close in from both sides vertically. - * Codewase, exactly the same as above, but uses a different vertex layout to make the difference. + * Codewise, exactly the same as above, but uses a different vertex layout to make the difference. */ void render_fade_barndoor_vertical(Gfx **dList, UNUSED MatrixS **mats, UNUSED Vertex **verts) { reset_render_settings(dList); @@ -489,57 +489,66 @@ void render_fade_barndoor_vertical(Gfx **dList, UNUSED MatrixS **mats, UNUSED Ve GLOBAL_ASM("asm/non_matchings/fade_transition/func_800C15D4.s") GLOBAL_ASM("asm/non_matchings/fade_transition/func_800C1EE8.s") -#ifdef NON_EQUIVALENT #define NUM_OF_VERTS 18 #define NUM_OF_TRIS 16 void render_fade_circle(Gfx **dList, UNUSED MatrixS **mats, UNUSED Vertex **verts) { Vertex *vertsToRender; Triangle *trisToRender; + Gfx *gfx; + s32 i; + reset_render_settings(dList); + gfx = *dList; + vertsToRender = (Vertex *) sTransitionVtx[sTransitionTaskNum[0]]; trisToRender = (Triangle *) sTransitionTris[sTransitionTaskNum[0]]; - gSPDisplayList((*dList)++, dTransitionShapeSettings); - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(vertsToRender), NUM_OF_VERTS, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(trisToRender), NUM_OF_TRIS, TRIN_DISABLE_TEXTURE); - vertsToRender += NUM_OF_VERTS; - trisToRender += NUM_OF_TRIS; - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(vertsToRender), NUM_OF_VERTS, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(trisToRender), NUM_OF_TRIS, TRIN_DISABLE_TEXTURE); - vertsToRender += NUM_OF_VERTS; - trisToRender += NUM_OF_TRIS; - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(vertsToRender), NUM_OF_VERTS, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(trisToRender), NUM_OF_TRIS, TRIN_DISABLE_TEXTURE); - vertsToRender += NUM_OF_VERTS; - trisToRender += NUM_OF_TRIS; - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(vertsToRender), NUM_OF_VERTS, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(trisToRender), NUM_OF_TRIS, TRIN_DISABLE_TEXTURE); + gSPDisplayList(gfx++, dTransitionShapeSettings); + + for (i = 0; i < 4; i++) { + gSPVertexDKR(gfx++, OS_PHYSICAL_TO_K0(vertsToRender), NUM_OF_VERTS, 0); + gSPPolygon(gfx++, OS_PHYSICAL_TO_K0(trisToRender), NUM_OF_TRIS, TRIN_DISABLE_TEXTURE); + vertsToRender += NUM_OF_VERTS; + trisToRender += NUM_OF_TRIS; + } + + *dList = gfx; reset_render_settings(dList); } -#else -GLOBAL_ASM("asm/non_matchings/fade_transition/render_fade_circle.s") -#endif -#ifdef NON_EQUIVALENT -// This doesn't work properly. -void render_fade_waves(Gfx **dList, MatrixS **mats, Vertex **verts) { +void render_fade_waves(Gfx **dlist, UNUSED MatrixS **mats, UNUSED Vertex **verts) { + Gfx *gfx; s32 i; - reset_render_settings(dList); - gSPDisplayList((*dList)++, dTransitionShapeSettings); - for(i = 0; i < 6; i++) { - s32 index = sTransitionTaskNum[0] + i; - if(i != 1 && i != 4) { - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(sTransitionVtx[index]), 16, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(sTransitionTris[index]), 14, TRIN_DISABLE_TEXTURE); + Vertex *v; + Triangle *t; + reset_render_settings(dlist); + gfx = *dlist; + v = (Vertex *)sTransitionVtx[sTransitionTaskNum[0]]; + t = (Triangle *)sTransitionTris[sTransitionTaskNum[0]]; + gSPDisplayList(gfx++, dTransitionShapeSettings); + /* + i == 0 -> Left third wave? + i == 1 -> Middle third wave? + i == 2 -> Right third wave? + i == 3 -> Left third mask? ("mask" being pure black square in this context) + i == 4 -> Middle third mask? + i == 5 -> Right third mask? + */ + for (i = 0; i < 6; i++) { + if (i == 1 || i == 4) { // Is middle third? + gSPVertexDKR(gfx++, OS_PHYSICAL_TO_K0(v), 14, 0); + gSPPolygon(gfx++, OS_PHYSICAL_TO_K0(t), 12, TRIN_DISABLE_TEXTURE); + v += 14; + t += 12; } else { - gSPVertexDKR((*dList)++, OS_PHYSICAL_TO_K0(sTransitionVtx[index]), 14, 0); - gSPPolygon((*dList)++, OS_PHYSICAL_TO_K0(sTransitionTris[index]), 12, TRIN_DISABLE_TEXTURE); + gSPVertexDKR(gfx++, OS_PHYSICAL_TO_K0(v), 16, 0); + gSPPolygon(gfx++, OS_PHYSICAL_TO_K0(t), 14, TRIN_DISABLE_TEXTURE); + v += 16; + t += 14; } } - reset_render_settings(dList); + *dlist = gfx; + reset_render_settings(dlist); } -#else -GLOBAL_ASM("asm/non_matchings/fade_transition/render_fade_waves.s") -#endif /** * Renders a transition effect on screen that will close in from the opposite corners of the screen. diff --git a/src/fade_transition.h b/src/fade_transition.h index e70f833b..d02f081b 100644 --- a/src/fade_transition.h +++ b/src/fade_transition.h @@ -58,9 +58,9 @@ void func_800C2640(FadeTransition *transition); void func_800C0834(s32 updateRate); void func_800C27A0(s32 updateRate); s32 transition_begin(FadeTransition *transition); +void render_fade_circle(Gfx **dList, MatrixS **mats, Vertex **verts); -void render_fade_circle(Gfx **dList, MatrixS **mats, Vertex **verts); //Non Matching -void render_fade_waves(Gfx **dList, MatrixS **mats, Vertex **verts); //Non Matching +void render_fade_waves(Gfx **dlist, UNUSED MatrixS **mats, UNUSED Vertex **verts); //Non Matching void func_800C1130(s32); //Non Matching void func_800C1EE8(s32); //Non Matching void func_800C0B00(FadeTransition *transition, s32, s32, s16*, s8*, s8*, s8*, s8*, s8*); //Non Matching diff --git a/src/game.c b/src/game.c index 0b0f8ade..8841b10d 100644 --- a/src/game.c +++ b/src/game.c @@ -45,23 +45,6 @@ #include "math_util.h" #include "controller.h" -/************ .rodata ************/ - -UNUSED const char sLevelErrorString[] = "LOADLEVEL Error: Level out of range\n"; -UNUSED const char sBossErrorString[] = "BossLev problem\n"; -UNUSED const char sAITableErrorString[] = "AITABLE Error: Table out of range\n"; -UNUSED const char sDebugVersionInfoString[] = "1.1605"; -UNUSED const char sDebugBuildDateString[] = "02/10/97 16:03"; -UNUSED const char sDebugUsernameString[] = "pmountain"; - -const char D_800E7134[] = "BBB\n"; // Functionally unused. -UNUSED const char sDebugCarString[] = "CAR"; -UNUSED const char sDebugHovercraftString[] = "HOV"; -UNUSED const char sDebugPlaneString[] = "PLN"; -UNUSED const char sDebugVehicleSwapString[] = "Swapping\n"; - -/*********************************/ - /************ .data ************/ char *gTempLevelNames = NULL; @@ -78,44 +61,6 @@ s16 D_800DD32C = 0; s8 D_800DD330 = 0; -UNUSED char *sDebugRomBuildInfo[6] = { - NULL, NULL, NULL, // These could be a file boundary. - (char *)sDebugVersionInfoString, - (char *)sDebugBuildDateString, - (char *)sDebugUsernameString -}; - -UNUSED char gBuildString[40] = "Version 7.7 29/09/97 15.00 L.Schuneman"; - -s8 sAntiPiracyTriggered = 0; -UNUSED s32 D_800DD378 = 1; -s32 gSaveDataFlags = 0; //Official Name: load_save_flags -s32 gScreenStatus = OSMESG_SWAP_BUFFER; -s32 sControllerStatus = 0; -UNUSED s32 D_800DD388 = 0; -s8 gSkipGfxTask = FALSE; -s8 D_800DD390 = 0; -s16 gLevelLoadTimer = 0; -s8 D_800DD398 = 0; -s8 gFutureFunLandLevelTarget = FALSE; -s8 gDmemInvalid = FALSE; -UNUSED s32 D_800DD3A4 = 0; -UNUSED s32 D_800DD3A8 = 0; -UNUSED s32 D_800DD3AC = 0; -s32 gNumF3dCmdsPerPlayer[4] = { 4500, 7000, 11000, 11000 }; -s32 gNumHudVertsPerPlayer[4] = { 300, 600, 850, 900 }; -s32 gNumHudMatPerPlayer[4] = { 300, 400, 550, 600 }; -s32 gNumHudTrisPerPlayer[4] = { 20, 30, 40, 50 }; -s8 gDrawFrameTimer = 0; -FadeTransition D_800DD3F4 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_UNK2, FADE_COLOR_BLACK, 20, 0); -UNUSED FadeTransition D_800DD3FC = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_WHITE, 20, -1); -s32 sLogicUpdateRate = LOGIC_5FPS; -FadeTransition D_800DD408 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_WHITE, 30, -1); -UNUSED char *D_800DD410[3] = { - (char *)sDebugCarString, (char *)sDebugHovercraftString, (char *)sDebugPlaneString -}; -FadeTransition gLevelFadeOutTransition = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_BLACK, 30, -1); -FadeTransition D_800DD424 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_BLACK, 260, -1); /*******************************/ /************ .bss ************/ @@ -134,49 +79,6 @@ s32 D_80121180[16]; TempStruct5 *D_801211C0; s16 gLevelPropertyStack[5 * 4]; // Stores level info for cutscenes. 5 sets of four properties. -Gfx *gDisplayLists[2]; -Gfx *gCurrDisplayList; -UNUSED s32 D_801211FC; -MatrixS *gMatrixHeap[2]; -MatrixS *gGameCurrMatrix; -Vertex *gVertexHeap[2]; -Vertex *gGameCurrVertexList; -TriangleList *gTriangleHeap[2]; -TriangleList *gGameCurrTriList; -UNUSED s32 D_80121230[8]; -s8 D_80121250[16]; //Settings4C -OSSched gMainSched; // 0x288 / 648 bytes -u64 gSchedStack[0x400]; -s32 gSPTaskNum; -s32 sRenderContext; -s32 gRenderMenu; // I don't think this is ever not 1 -// Similar to gMapId, but is 0 if not currently playing a level (e.g. start menu). -s32 gPlayableMapId; -s32 D_801234F8; -s32 D_801234FC; -s32 gGameNumPlayers; -s32 gGameCurrentEntrance; -s32 gGameCurrentCutscene; -s32 gPrevPlayerCount; -Settings *gSettingsPtr; -s8 gIsLoading; -s8 gIsPaused; -s8 gPostRaceViewPort; -Vehicle gLevelDefaultVehicleID; -Vehicle D_8012351C; // Looks to be the current level's vehicle ID. -s32 sBootDelayTimer; -s8 gLevelLoadType; -s8 gNextMap; -UNUSED s8 D_80123526; // Set to 0 then never used. -s32 gCurrNumF3dCmdsPerPlayer; -s32 gCurrNumHudMatPerPlayer; -s32 gCurrNumHudTrisPerPlayer; -s32 gCurrNumHudVertsPerPlayer; -OSScClient *gNMISched[3]; -OSMesg gNMIOSMesg; -OSMesgQueue gNMIMesgQueue; -s32 gNMIMesgBuf; //Official Name: resetPressed -s32 D_80123568[6]; // BSS Padding /******************************/ @@ -911,1410 +813,3 @@ s32 func_8006C300(void) { return D_800DD330; } } - -/** - * Main looping function for the main thread. - * Official Name: mainThread - */ -void thread3_main(UNUSED void *unused) { - init_game(); - gSaveDataFlags = handle_save_data_and_read_controller(gSaveDataFlags, 0); - sBootDelayTimer = 0; - sRenderContext = DRAW_INTRO; - while (1) { - if (is_reset_pressed()) { - func_80072708(); - audioStopThread(); - stop_thread30(); - __osSpSetStatus(SP_SET_HALT | SP_CLR_INTR_BREAK | SP_CLR_YIELD | SP_CLR_YIELDED | SP_CLR_TASKDONE | SP_CLR_RSPSIGNAL - | SP_CLR_CPUSIGNAL | SP_CLR_SIG5 | SP_CLR_SIG6 | SP_CLR_SIG7); - osDpSetStatus(DPC_SET_XBUS_DMEM_DMA | DPC_CLR_FREEZE | DPC_CLR_FLUSH | DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR - | DPC_CLR_CMD_CTR | DPC_CLR_CMD_CTR); - while (1); // Infinite loop - } - main_game_loop(); - thread3_verify_stack(); - } -} - -/** - * Setup all of the necessary pieces required for the game to function. - * This includes the memory pool. controllers, video, audio, core assets and more. - * Official Name: mainInitGame - */ -void init_game(void) { - s32 viMode; - - init_main_memory_pool(); - rzipInit(); // Initialise gzip decompression related things - sAntiPiracyTriggered = TRUE; - if (check_imem_validity()) { - sAntiPiracyTriggered = FALSE; - } - gIsLoading = FALSE; - gLevelDefaultVehicleID = VEHICLE_CAR; - - if (osTvType == TV_TYPE_PAL) { - viMode = OS_VI_PAL_LPN1; - } else if (osTvType == TV_TYPE_NTSC) { - viMode = OS_VI_NTSC_LPN1; - } else if (osTvType == TV_TYPE_MPAL) { - viMode = OS_VI_MPAL_LPN1; - } - - osCreateScheduler(&gMainSched, &gSchedStack[0x400], /*priority*/ 13, viMode, 1); - // Antipiracy measure. - gDmemInvalid = FALSE; - if (check_dmem_validity() == FALSE) { - gDmemInvalid = TRUE; - } - init_video(VIDEO_MODE_LOWRES_LPN, &gMainSched); - init_PI_mesg_queue(); - setup_gfx_mesg_queues(&gMainSched); - audio_init(&gMainSched); - func_80008040(); // Should be very similar to allocate_object_model_pools - sControllerStatus = init_controllers(); - tex_init_textures(); - allocate_object_model_pools(); - allocate_object_pools(); - diPrintfInit(); - allocate_ghost_data(); - init_particle_assets(); - init_weather(); - calc_and_alloc_heap_for_settings(); - default_alloc_displaylist_heap(); - load_fonts(); - init_controller_paks(); - func_80081218(); // init_save_data - create_and_start_thread30(); - osCreateMesgQueue(&gNMIMesgQueue, &gNMIOSMesg, 1); - osScAddClient(&gMainSched, (OSScClient*) gNMISched, &gNMIMesgQueue, OS_SC_ID_PRENMI); - gNMIMesgBuf = 0; - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0; - gSPTaskNum = 0; - - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - - osSetTime(0); -} - -/** - * The main gameplay loop. - * Contains all game logic, audio and graphics processing. - */ -void main_game_loop(void) { - s32 debugLoopCounter; - s32 framebufferSize; - s32 tempLogicUpdateRate, tempLogicUpdateRateMax; - - osSetTime(0); - - if (gScreenStatus == MESG_SKIP_BUFFER_SWAP) { - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - set_rsp_segment(&gCurrDisplayList, 0, 0); - set_rsp_segment(&gCurrDisplayList, 1, (s32) gVideoCurrFramebuffer); - set_rsp_segment(&gCurrDisplayList, 2, (s32) gVideoLastDepthBuffer); - set_rsp_segment(&gCurrDisplayList, 4, (s32) gVideoCurrFramebuffer - 0x500); - } - if (gDrawFrameTimer == 0) { - setup_ostask_xbus(gDisplayLists[gSPTaskNum], gCurrDisplayList, 0); - gSPTaskNum += 1; - gSPTaskNum &= 1; - } - if (gDrawFrameTimer) { - gDrawFrameTimer--; - } - - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gGameCurrMatrix = gMatrixHeap[gSPTaskNum]; - gGameCurrVertexList = gVertexHeap[gSPTaskNum]; - gGameCurrTriList = gTriangleHeap[gSPTaskNum]; - - set_rsp_segment(&gCurrDisplayList, 0, 0); - set_rsp_segment(&gCurrDisplayList, 1, (s32) gVideoLastFramebuffer); - set_rsp_segment(&gCurrDisplayList, 2, (s32) gVideoLastDepthBuffer); - set_rsp_segment(&gCurrDisplayList, 4, (s32) gVideoLastFramebuffer - 0x500); - init_rsp(&gCurrDisplayList); - init_rdp_and_framebuffer(&gCurrDisplayList); - render_background(&gCurrDisplayList, (Matrix *) &gGameCurrMatrix, TRUE); - gSaveDataFlags = handle_save_data_and_read_controller(gSaveDataFlags, sLogicUpdateRate); - if (get_lockup_status()) { - render_epc_lock_up_display(); - sRenderContext = DRAW_CRASH_SCREEN; - } - if (gDmemInvalid) { - debugLoopCounter = 0; - while (debugLoopCounter != 10000000) { - debugLoopCounter++; - } - if (debugLoopCounter > 20000000) { // This shouldn't ever be true? - render_printf(D_800E7134 /* "BBB\n" */); - } - } - - switch (sRenderContext) { - case DRAW_INTRO: // Pre-boot screen - pre_intro_loop(); - break; - case DRAW_MENU: // In a menu - func_8006DCF8(sLogicUpdateRate); - break; - case DRAW_GAME: // In game (Controlling a character) - ingame_logic_loop(sLogicUpdateRate); - break; - case DRAW_CRASH_SCREEN: // EPC (lockup display) - lockup_screen_loop(sLogicUpdateRate); - break; - } - - // This is a good spot to place custom text if you want it to overlay it over ALL the - // menus & gameplay. - - handle_music_fade(sLogicUpdateRate); - print_debug_strings(&gCurrDisplayList); - render_dialogue_boxes(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList); - close_dialogue_box(4); - assign_dialogue_box_id(4); - // handle_transitions will perform the logic of transitions and return the transition ID. - if (handle_transitions(sLogicUpdateRate)) { - render_fade_transition(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList); - } - if ((sBootDelayTimer >= 8) && (is_controller_missing())) { - print_missing_controller_text(&gCurrDisplayList, sLogicUpdateRate); - } - - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - - copy_viewports_to_stack(); - if (gDrawFrameTimer != 1) { - if (gSkipGfxTask == FALSE) { - gScreenStatus = wait_for_gfx_task(); - } - } else { - gDrawFrameTimer = 0; - } - gSkipGfxTask = FALSE; - clear_free_queue(); - if (!gIsPaused) { - disable_cutscene_camera(); - } - if (gDrawFrameTimer == 2) { - framebufferSize = SCREEN_WIDTH * SCREEN_HEIGHT * 2; - if (osTvType == TV_TYPE_PAL) { - framebufferSize = (s32)((SCREEN_WIDTH * SCREEN_HEIGHT * 2) * 1.1f); - } - dmacopy_doubleword(gVideoLastFramebuffer, gVideoCurrFramebuffer, (s32) gVideoCurrFramebuffer + framebufferSize); - } - // tempLogicUpdateRate will be set to a value 2 or higher, based on the framerate. - // the mul factor is hardcapped at 6, which happens at 10FPS. The mul factor - // affects frameskipping, to maintain consistent game speed, through the (many) - // dropped frames in DKR. - tempLogicUpdateRate = swap_framebuffer_when_ready(gScreenStatus); - sLogicUpdateRate = tempLogicUpdateRate; - tempLogicUpdateRateMax = LOGIC_10FPS; - if (tempLogicUpdateRate > tempLogicUpdateRateMax) { - sLogicUpdateRate = tempLogicUpdateRateMax; - } -} - -void func_8006CAE4(s32 numPlayers, s32 trackID, Vehicle vehicle) { - gGameNumPlayers = numPlayers - 1; - if (trackID == -1) { - gPlayableMapId = get_track_id_to_load(); - } else { - gPlayableMapId = trackID; // Unused, because arg1 is always -1. - } - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, vehicle); -} - -/** - * Calls load_level() with the same arguments except for the cutsceneId, - * which is the value at gGameCurrentCutscene. Also does some other stuff. - * Used when ingame. - */ -void load_level_game(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId) { - alloc_displaylist_heap(numberOfPlayers); - set_free_queue_state(0); - func_80065EA0(); - func_800C3048(); - load_level(levelId, numberOfPlayers, entranceId, vehicleId, gGameCurrentCutscene); - func_8009ECF0(get_viewport_count()); - func_800AE728(8, 0x10, 0x96, 0x64, 0x32, 0); - func_8001BF20(); - osSetTime(0); - set_free_queue_state(2); - func_80072298(1); -} - -/** - * Call numerous functions to clear data in RAM. - * Then call to free particles, HUD and text. - * Waits for a GFX task before unloading. -*/ -void unload_level_game(void) { - set_free_queue_state(0); - if (gSkipGfxTask == FALSE) { - if (gDrawFrameTimer != 1) { - wait_for_gfx_task(); - } - gSkipGfxTask = TRUE; - } - clear_audio_and_track(); - transition_begin(&D_800DD3F4); - func_800AE270(); - func_800A003C(); - func_800C30CC(); - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - set_free_queue_state(2); -} - -/** - * The main behaviour function involving all of the ingame stuff. - * Involves the updating of all objects and setting up the render scene. -*/ -void ingame_logic_loop(s32 updateRate) { - s32 buttonPressedInputs, buttonHeldInputs, i, sp40, sp3C; - - sp40 = 0; - buttonHeldInputs = 0; - buttonPressedInputs = 0; - - // Get input data for all 4 players. - for (i = 0; i < get_active_player_count(); i++) { - buttonHeldInputs |= get_buttons_held_from_player(i); - buttonPressedInputs |= get_buttons_pressed_from_player(i); - } - // Spam the start button, making the game unplayable because it's constantly paused. - if (sAntiPiracyTriggered) { - buttonPressedInputs |= START_BUTTON; - } - // Update all objects - if (!gIsPaused) { - func_80010994(updateRate); - if (check_if_showing_cutscene_camera() == 0 || func_8001139C()) { - if ((buttonPressedInputs & START_BUTTON) && (get_level_property_stack_pos() == 0) && (D_800DD390 == 0) - && (sRenderContext == DRAW_GAME) && (gPostRaceViewPort == NULL) && (gLevelLoadTimer == 0) && (D_800DD398 == 0)) { - buttonPressedInputs = 0; - gIsPaused = TRUE; - func_80093A40(); - } - } - } else { - set_anti_aliasing(TRUE); - } - D_800DD398 -= updateRate; - if (D_800DD398 < 0) { - D_800DD398 = 0; - } - if (gPostRaceViewPort) { - gIsPaused = FALSE; - } - gParticlePtrList_flush(); - func_8001BF20(); - render_scene(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); - if (sRenderContext == DRAW_GAME) { - // Ignore the user's L/R/Z buttons. - buttonHeldInputs &= ~(L_TRIG | R_TRIG | Z_TRIG); - } - if (gPostRaceViewPort) { - i = func_80095728(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, updateRate); - switch (i) { - case 2: - buttonHeldInputs |= (L_TRIG | Z_TRIG); - break; - case 1: - gPostRaceViewPort = NULL; - func_8006D8F0(-1); - break; - case 4: - clear_level_property_stack(); - D_800DD390 = 0; - buttonHeldInputs |= (L_TRIG | R_TRIG); - break; - case 5: - buttonHeldInputs |= L_TRIG, - sp40 = 1; - break; - case 8: - buttonHeldInputs |= L_TRIG, - sp40 = 2; - break; - case 9: - buttonHeldInputs |= L_TRIG, - sp40 = 3; - break; - case 10: - buttonHeldInputs |= L_TRIG, - sp40 = 4; - break; - case 11: - buttonHeldInputs |= L_TRIG, - sp40 = 5; - break; - case 12: - buttonHeldInputs |= L_TRIG, - sp40 = 6; - break; - case 13: - buttonHeldInputs |= L_TRIG, - sp40 = 7; - break; - } - } - func_800C3440(updateRate); - i = func_800C3400(); - if (i != 0) { - if (i == 2) { - gIsPaused = TRUE; - } - if (func_800C3400() != 2) { - gIsPaused = FALSE; - n_alSeqpDelete(); - } - } - if (gIsPaused) { - i = render_pause_menu(&gCurrDisplayList, updateRate); - switch (i - 1) { - case 0: - gIsPaused = FALSE; - break; - case 1: - func_80001050(); - func_800C314C(); - if (func_80023568() != 0 && is_in_two_player_adventure()) { - func_8006F398(); - } - buttonHeldInputs |= (L_TRIG | Z_TRIG); - break; - case 2: - func_80001050(); - func_800C314C(); - if (func_80023568() != 0 && is_in_two_player_adventure()) { - func_8006F398(); - } - buttonHeldInputs |= L_TRIG; - break; - case 4: - sp40 = 1; - func_800C314C(); - buttonHeldInputs |= L_TRIG; - break; - case 11: - sp40 = 6; - func_800C314C(); - buttonHeldInputs |= L_TRIG; - break; - case 5: - gIsPaused = FALSE; - break; - case 6: - func_80022E18(1); - gIsPaused = FALSE; - break; - case 3: - D_800DD390 = 0; - func_80001050(); - func_800C314C(); - clear_level_property_stack(); - buttonHeldInputs |= (L_TRIG | R_TRIG); - break; - } - } - init_rdp_and_framebuffer(&gCurrDisplayList); - render_borders_for_multiplayer(&gCurrDisplayList); - render_minimap_and_misc_hud(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, updateRate); - render_second_multiplayer_borders(&gCurrDisplayList); - if (gFutureFunLandLevelTarget) { - if (func_800214C4() != 0) { - gPlayableMapId = ASSET_LEVEL_FUTUREFUNLANDHUB; - D_801234F8 = 1; - gGameCurrentEntrance = 0; - gFutureFunLandLevelTarget = FALSE; - } - } - sp3C = FALSE; - if (D_800DD390 != 0) { - D_800DD390 -= updateRate; - if (D_800DD390 <= 0) { - D_800DD390 = 0; - push_level_property_stack(ASSET_LEVEL_CENTRALAREAHUB, 0, VEHICLE_CAR, CUTSCENE_ID_NONE); - push_level_property_stack(ASSET_LEVEL_WIZPIGAMULETSEQUENCE, 0, -1, CUTSCENE_ID_UNK_A); - sp3C = TRUE; - } - } - if (gLevelLoadTimer > 0) { - gLevelLoadTimer -= updateRate; - if (gLevelLoadTimer <= 0) { - buttonHeldInputs = L_TRIG; - sp3C = TRUE; - switch (gLevelLoadType) { - case LEVEL_LOAD_UNK1: - buttonHeldInputs = (L_TRIG | Z_TRIG); - break; - case LEVEL_LOAD_TROPHY_RACE: - sp40 = 3; - func_80098208(); - D_801234FC = 2; - break; - case LEVEL_LOAD_LIGHTHOUSE_CUTSCENE: - gFutureFunLandLevelTarget = TRUE; - // fall-through - case LEVEL_LOAD_FUTURE_FUN_LAND: - D_801234F8 = 1; - gPlayableMapId = gNextMap; - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0; - buttonHeldInputs = 0; - break; - } - gLevelLoadType = LEVEL_LOAD_NORMAL; - gLevelLoadTimer = 0; - } - } - if (sp3C) { - if (get_level_property_stack_pos() != 0) { - pop_level_property_stack(&gPlayableMapId, &gGameCurrentEntrance, &i, &gGameCurrentCutscene); - set_frame_blackout_timer(); - if (gPlayableMapId < 0) { - if (gPlayableMapId == (s32)SPECIAL_MAP_ID_NO_LEVEL || gPlayableMapId == (s32)SPECIAL_MAP_ID_UNK_NEG10) { - if (gPlayableMapId == (s32)SPECIAL_MAP_ID_UNK_NEG10 && is_in_two_player_adventure()) { - func_8006F398(); - } - buttonHeldInputs |= L_TRIG; - D_801234FC = 2; - } else { - buttonHeldInputs = 0; - D_801234FC = 1; - sp40 = 8; - } - } else { - D_801234FC = 0; - D_801234F8 = 1; - buttonHeldInputs = 0; - } - } - } else { - sp3C = func_8006C300(); - if (get_level_property_stack_pos()) { - if (gLevelLoadTimer == 0) { - i = func_800214C4(); - if ((i != 0) || ((buttonPressedInputs & A_BUTTON) && (sp3C != 0))) { - if (sp3C != 0) { - func_80000B28(); - } - set_frame_blackout_timer(); - pop_level_property_stack(&gPlayableMapId, &gGameCurrentEntrance, &i, &gGameCurrentCutscene); - if (gPlayableMapId < 0) { - if (gPlayableMapId == -1 || gPlayableMapId == -10) { - if (gPlayableMapId == -10 && is_in_two_player_adventure()) { - func_8006F398(); - } - buttonHeldInputs |= L_TRIG; - D_801234FC = 2; - } else { - buttonHeldInputs = 0; - D_801234FC = 1; - sp40 = 8; - } - } else { - D_801234F8 = 1; - } - } - } - } - } - if (((buttonHeldInputs & L_TRIG) && (sRenderContext == DRAW_GAME)) || (D_801234FC != 0)) { - gIsPaused = FALSE; - gLevelLoadTimer = 0; - gPostRaceViewPort = NULL; - unload_level_game(); - safe_mark_write_save_file(get_save_file_index()); - if (sp40 != 0) { - gIsLoading = FALSE; - switch (sp40) { - case 1: - // Go to track select menu from "Select Track" option in tracks menu. - load_menu_with_level_background(MENU_TRACK_SELECT, -1, 1); - break; - case 2: - load_menu_with_level_background(MENU_RESULTS, 0x22, 0); - break; - case 3: - load_menu_with_level_background(MENU_TROPHY_RACE_ROUND, 0x22, 0); - break; - case 4: - load_menu_with_level_background(MENU_TROPHY_RACE_RANKINGS, 0x22, 0); - break; - case 5: - // Trophy race related? - load_menu_with_level_background(MENU_UNUSED_22, 0x22, 0); - break; - case 6: - // Go to character select menu from "Select Character" option in tracks menu. - i = 0; - if (is_drumstick_unlocked()) { - i ^= 1; - } - if (is_tt_unlocked()) { - i ^= 3; - } - func_8008AEB4(1, 0); - load_menu_with_level_background(MENU_CHARACTER_SELECT, 0x16, i); - break; - case 7: - gIsLoading = TRUE; - load_menu_with_level_background(MENU_UNKNOWN_23, -1, 0); - gIsLoading = FALSE; - break; - case 8: - load_menu_with_level_background(MENU_CREDITS, -1, 0); - break; - } - } else if (D_801234FC == 1) { - if (D_80121250[2] == -1) { - load_menu_with_level_background(MENU_UNUSED_8, -1, 0); - } else { - gIsLoading = TRUE; - load_menu_with_level_background(MENU_TRACK_SELECT_ADVENTURE, -1, -1); - } - } else if (!(buttonHeldInputs & R_TRIG)) { - if (!(buttonHeldInputs & Z_TRIG)) { - gPlayableMapId = D_80121250[0]; - gGameCurrentEntrance = D_80121250[15]; - gGameCurrentCutscene = D_80121250[D_80121250[1] + 8]; - gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); - if (gGameCurrentCutscene < 0) { - gGameCurrentCutscene = 0x64; - } - } - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - } else { - safe_mark_write_save_file(get_save_file_index()); - load_menu_with_level_background(MENU_TITLE, -1, 0); - } - D_801234FC = 0; - } - if (D_801234F8 != 0) { - gPostRaceViewPort = NULL; - unload_level_game(); - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - safe_mark_write_save_file(get_save_file_index()); - D_801234F8 = 0; - } -} - -void func_8006D8A4(void) { - D_800DD390 = 0x2C; - gIsPaused = 0; - n_alSeqpDelete(); - transition_begin(&D_800DD408); -} - -void func_8006D8E0(s32 arg0) { - gPostRaceViewPort = arg0 + 1; -} - -void func_8006D8F0(UNUSED s32 arg0) { - s32 temp; - if (sRenderContext != DRAW_UNK_04) { - gPlayableMapId = D_80121250[0]; - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0x64; - temp = D_80121250[1]; - if (D_80121250[15] >= 0) { - gGameCurrentEntrance = D_80121250[15]; - } - if (D_80121250[temp + 8] >= 0) { - gGameCurrentCutscene = D_80121250[temp + 8]; - } - D_801234F8 = 1; - } -} - -void func_8006D968(s8 *arg0) { - s32 i; - if (sRenderContext != DRAW_UNK_04) { - D_80121250[0] = gPlayableMapId; - for (i = 0; i < 2; i++) { - D_80121250[i + 2] = arg0[i + 8]; - D_80121250[i + 4] = arg0[i + 10]; - D_80121250[i + 6] = arg0[i + 12]; - D_80121250[i + 8] = arg0[i + 14]; - D_80121250[i + 10] = arg0[i + 18]; - D_80121250[i + 12] = arg0[i + 20]; - } - D_80121250[14] = arg0[22]; - D_80121250[15] = arg0[23]; - D_801234FC = 1; - } -} - -/** - * Gets the render context from outside this file - */ -RenderContext get_render_context(void) { - return sRenderContext; -} - -/** - * Unused function used to set the render context from outside this file - * Official Name: mainSetMode? - */ -UNUSED void set_render_context(s32 changeTo) { - sRenderContext = changeTo; -} - -/** - * Sets up and loads a level to be used in the background of the menu that's about to be set up. - * Used for every kind of menu that's not ingame. -*/ -void load_menu_with_level_background(s32 menuId, s32 levelId, s32 cutsceneId) { - alloc_displaylist_heap(PLAYER_ONE); - sRenderContext = DRAW_MENU; - gRenderMenu = TRUE; - set_sound_channel_volume(0, 32767); - set_sound_channel_volume(1, 32767); - set_sound_channel_volume(2, 32767); - func_80065EA0(); - - if (!gIsLoading) { - gIsLoading = FALSE; - if (levelId < 0) { - gIsLoading = TRUE; - } else { - load_level_menu(levelId, -1, 0, VEHICLE_PLANE, cutsceneId); - } - } - if (menuId == MENU_UNUSED_2 || menuId == MENU_LOGOS || menuId == MENU_TITLE) { - reset_title_logo_scale(); - } - menu_init(menuId); - gGameCurrentEntrance = 0; -} - -/** - * Set the default vehicle option from the current loaded level. - */ -void set_level_default_vehicle(Vehicle vehicleID) { - gLevelDefaultVehicleID = vehicleID; -} - -void func_8006DB20(Vehicle vehicleId) { - D_8012351C = vehicleId; -} - -/** - * Get the default vehicle option, set by a loaded level. - */ -Vehicle get_level_default_vehicle(void) { - return gLevelDefaultVehicleID; -} - -/** - * Calls load_level() with the same arguments, but also does some other stuff. - * Used for menus. - */ -void load_level_menu(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId) { - set_free_queue_state(0); - func_80065EA0(); - func_800C3048(); - load_level(levelId, numberOfPlayers, entranceId, vehicleId, cutsceneId); - func_8009ECF0(get_viewport_count()); - func_800AE728(4, 4, 0x6E, 0x30, 0x20, 0); - func_8001BF20(); - osSetTime(0); - set_free_queue_state(2); -} - -/** - * Call numerous functions to clear data in RAM. - * Then call to free particles, HUD and text. -*/ -void unload_level_menu(void) { - if (!gIsLoading) { - gIsLoading = TRUE; - set_free_queue_state(0); - clear_audio_and_track(); - transition_begin(&D_800DD3F4); - func_800AE270(); - func_800A003C(); - func_800C30CC(); - set_free_queue_state(2); - } - gIsLoading = FALSE; -} - -/** - * Used in menus, update objects and draw the game. - * In the tracks menu, this only runs if there's a track actively loaded. -*/ -void update_menu_scene(s32 updateRate) { - if (get_thread30_level_id_to_load() == 0) { - func_80010994(updateRate); - gParticlePtrList_flush(); - func_8001BF20(); - render_scene(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); - func_800C3440(updateRate); - init_rdp_and_framebuffer(&gCurrDisplayList); - render_borders_for_multiplayer(&gCurrDisplayList); - render_second_multiplayer_borders(&gCurrDisplayList); - } -} - -#ifdef NON_EQUIVALENT -// Minor & regalloc issues. -void func_8006DCF8(s32 updateRate) { - s32 menuLoopResult, temp, temp2, tempResult; - - gIsPaused = FALSE; - gPostRaceViewPort = NULL; - if (!gIsLoading && gRenderMenu) { - update_menu_scene(updateRate); - } - menuLoopResult = menu_loop(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); - gRenderMenu = TRUE; - if (menuLoopResult == -2) { - gRenderMenu = FALSE; - return; - } - if ((menuLoopResult != -1) && (menuLoopResult & 0x200)) { - unload_level_menu(); - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - gPlayableMapId = menuLoopResult & 0x7F; - gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0x64; - sRenderContext = DRAW_GAME; - gIsPaused = FALSE; - gPostRaceViewPort = NULL; - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - safe_mark_write_save_file(get_save_file_index()); - return; - } - if ((menuLoopResult != -1) && (menuLoopResult & 0x100)) { - unload_level_game(); - gIsPaused = FALSE; - gPostRaceViewPort = NULL; - switch (menuLoopResult & 0x7F) { - case 5: - load_menu_with_level_background(MENU_TRACK_SELECT, -1, 1); - break; - case 14: - gPlayableMapId = ASSET_LEVEL_CENTRALAREAHUB; - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0x64; - sRenderContext = DRAW_GAME; - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - safe_mark_write_save_file(get_save_file_index()); - break; - case 1: - gGameCurrentEntrance = 0; - gGameCurrentCutscene = 0x64; - gPlayableMapId = D_80121250[0]; - sRenderContext = DRAW_GAME; - // Minor issue with these 2 if statements - temp2 = D_80121250[D_80121250[1] + 8]; - temp = D_80121250[15]; - if (temp >= 0) { - gGameCurrentEntrance = temp; - } - if (temp2 >= 0) { - gGameCurrentCutscene = temp2; - } - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - safe_mark_write_save_file(get_save_file_index()); - break; - case 2: - sRenderContext = DRAW_GAME; - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - break; - case 3: - sRenderContext = DRAW_GAME; - gPlayableMapId = D_80121250[0]; - gGameCurrentEntrance = D_80121250[15]; - gGameCurrentCutscene = D_80121250[D_80121250[1] + 8]; - gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); - break; - default: - load_menu_with_level_background(MENU_TITLE, -1, 0); - break; - } - return; - } - if ((menuLoopResult & 0x80) && (menuLoopResult != -1)) { - unload_level_menu(); - // Minor issue here. - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - temp = menuLoopResult & 0x7F; - D_80121250[1] = temp; - D_80121250[0] = gPlayableMapId; - gPlayableMapId = D_80121250[temp + 2]; - gGameCurrentEntrance = D_80121250[temp + 4]; - sRenderContext = DRAW_GAME; - gGameCurrentCutscene = D_80121250[temp + 12]; - temp = get_player_selected_vehicle(0); - gGameNumPlayers = gSettingsPtr->gNumRacers - 1; - load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, temp); - D_801234FC = 0; - gLevelDefaultVehicleID = D_8012351C; - return; - } - if (menuLoopResult > 0) { - unload_level_menu(); - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - sRenderContext = DRAW_GAME; - func_8006CAE4(menuLoopResult, -1, gLevelDefaultVehicleID); - if (gSettingsPtr->newGame && !is_in_tracks_mode()) { - func_80000B28(); - gSettingsPtr->newGame = FALSE; - } - } -} - -#else -GLOBAL_ASM("asm/non_matchings/game/func_8006DCF8.s") -#endif - -void load_level_for_menu(s32 levelId, s32 numberOfPlayers, s32 cutsceneId) { - if (!gIsLoading) { - unload_level_menu(); - if (get_thread30_level_id_to_load() == 0) { - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); - } - } - if (levelId != (s32) SPECIAL_MAP_ID_NO_LEVEL) { - //!@bug: Forcing the plane here makes all AI use plane paths. This can be seen most evidently in the Ancient Lake demo. - load_level_menu(levelId, numberOfPlayers, 0, VEHICLE_PLANE, cutsceneId); - gIsLoading = FALSE; - return; - } - gIsLoading = TRUE; -} - -void calc_and_alloc_heap_for_settings(void) { - s32 dataSize; - u32 sizes[15]; - s32 numWorlds, numLevels; - - init_level_globals(); - reset_character_id_slots(); - get_number_of_levels_and_worlds(&numLevels, &numWorlds); - sizes[0] = sizeof(Settings); - sizes[1] = sizes[0] + (numLevels * 4); // balloonsPtr - sizes[2] = sizes[1] + (numWorlds * 2); // flapInitialsPtr[0] - dataSize = (numLevels * 2); - sizes[3] = sizes[2] + dataSize; // flapInitialsPtr[1] - sizes[4] = sizes[3] + dataSize; // flapInitialsPtr[2] - sizes[5] = sizes[4] + dataSize; // flapTimesPtr[0] - sizes[6] = sizes[5] + dataSize; // flapTimesPtr[1] - sizes[7] = sizes[6] + dataSize; // flapTimesPtr[2] - sizes[8] = sizes[7] + dataSize; // courseInitialsPtr[0] - sizes[9] = sizes[8] + dataSize; // courseInitialsPtr[1] - sizes[10] = sizes[9] + dataSize; // courseInitialsPtr[2] - sizes[11] = sizes[10] + dataSize; // courseTimesPtr[0] - sizes[12] = sizes[11] + dataSize; // courseTimesPtr[1] - sizes[13] = sizes[12] + dataSize; // courseTimesPtr[2] - sizes[14] = sizes[13] + dataSize; // total size - - gSettingsPtr = allocate_from_main_pool_safe(sizes[14], COLOUR_TAG_WHITE); - gSettingsPtr->courseFlagsPtr = (s32 *)((u8 *)gSettingsPtr + sizes[0]); - gSettingsPtr->balloonsPtr = (s16 *)((u8 *)gSettingsPtr + sizes[1]); - gSettingsPtr->tajFlags = 0; - gSettingsPtr->flapInitialsPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[2]); - gSettingsPtr->flapInitialsPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[3]); - gSettingsPtr->flapInitialsPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[4]); - gSettingsPtr->flapTimesPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[5]); - gSettingsPtr->flapTimesPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[6]); - gSettingsPtr->flapTimesPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[7]); - gSettingsPtr->courseInitialsPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[8]); - gSettingsPtr->courseInitialsPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[9]); - gSettingsPtr->courseInitialsPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[10]); - gSettingsPtr->courseTimesPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[11]); - gSettingsPtr->courseTimesPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[12]); - gSettingsPtr->courseTimesPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[13]); - gSettingsPtr->unk4C = (Settings4C *) &D_80121250; - gSaveDataFlags = // Set bits 0/1/2/8 and wipe out all others - SAVE_DATA_FLAG_READ_FLAP_TIMES | - SAVE_DATA_FLAG_READ_COURSE_TIMES | - SAVE_DATA_FLAG_READ_SAVE_DATA | - SAVE_DATA_FLAG_READ_EEPROM_SETTINGS; -} - -void func_8006E5BC(void) { - s32 i, j; - gSettingsPtr->gNumRacers = get_number_of_active_players(); - for (i = 0; i < 8; i++) { - gSettingsPtr->racers[i].best_times = 0; - gSettingsPtr->racers[i].character = get_character_id_from_slot(i); - if (gSettingsPtr->gNumRacers >= 2) { - gSettingsPtr->racers[i].starting_position = i; - } else if (is_in_two_player_adventure()) { - gSettingsPtr->racers[i].starting_position = 5 - i; - } else { - gSettingsPtr->racers[i].starting_position = 7 - i; - } - gSettingsPtr->racers[i].unk7 = 0; - for (j = 0; j < 4; j++) { - gSettingsPtr->racers[i].placements[j] = 0; - } - gSettingsPtr->racers[i].course_time = 0; - for (j = 0; j < 3; j++) { - gSettingsPtr->racers[i].lap_times[j] = 0; - } - } - gSettingsPtr->timeTrialRacer = 0; - gSettingsPtr->unk115[0] = 0; - gSettingsPtr->unk115[1] = 0; - gSettingsPtr->display_times = 0; - gSettingsPtr->worldId = 0; - gSettingsPtr->courseId = 0; -} - -void func_8006E770(Settings *settings, s32 arg1) { - s32 i, j; - s32 numWorlds, numLevels; - s32 index; - u16 *temp_v0; - - get_number_of_levels_and_worlds(&numLevels, &numWorlds); - temp_v0 = (u16 *)get_misc_asset(MISC_ASSET_UNK17); - for (i = 0; i < NUMBER_OF_SAVE_FILES; i++) { - for (j = 0; j < numLevels; j++) { - index = (j * 12) + (i * 4); - if (arg1 & 1) { - settings->flapInitialsPtr[i][j] = temp_v0[index + 3]; - settings->flapTimesPtr[i][j] = temp_v0[index + 2]; - } - if (arg1 & 2) { - settings->courseInitialsPtr[i][j] = temp_v0[index + 1]; - settings->courseTimesPtr[i][j] = temp_v0[index]; - } - } - } -} - -void func_8006E994(Settings *settings) { - s32 i; - s32 sp20; - s32 sp1C; - - get_number_of_levels_and_worlds(&sp1C, &sp20); - settings->newGame = TRUE; - - for (i = 0; i < sp20; i++) { - settings->balloonsPtr[i] = 0; - } - for (i = 0; i < sp1C; i++) { - settings->courseFlagsPtr[i] = 0; - } - - settings->keys = 0; - settings->unkA = 0; - settings->bosses = 0; - settings->trophies = 0; - settings->cutsceneFlags = CUTSCENE_NONE; - settings->tajFlags = 0; - settings->ttAmulet = 0; - settings->wizpigAmulet = 0; -} - -UNUSED void func_8006EA58(void) { - func_8006E770(gSettingsPtr, 3); - func_8006E994(gSettingsPtr); -} - -/** - * Return the global game settings. - * This is where global game records and perferences are stored. -*/ -Settings *get_settings(void) { - return gSettingsPtr; -} - -/** - * Returns the value in gIsPaused. - */ -s8 is_game_paused(void) { - return gIsPaused; -} - -/** - * Returns the status of the post-race shrunken viewport. -*/ -s8 is_postrace_viewport_active(void) { - return gPostRaceViewPort; -} - -/** - * Sets and returns (nonzero) the message set when pressing the reset button. - * Official name: mainResetPressed - */ -s32 is_reset_pressed(void) { - if (gNMIMesgBuf == 0) { - gNMIMesgBuf = (s32)((osRecvMesg(&gNMIMesgQueue, NULL, OS_MESG_NOBLOCK) + 1) != 0); - } - return gNMIMesgBuf; -} - -/** - * Returns the current map ID if ingame, since this var is only set ingame. -*/ -s32 get_ingame_map_id(void) { - return gPlayableMapId; -} - -/** - * Marks a flag to read flap times from the eeprom - */ -UNUSED void mark_to_read_flap_times(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_READ_FLAP_TIMES; -} - -/** - * Marks a flag to read course times from the eeprom - */ -UNUSED void mark_to_read_course_times(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_READ_COURSE_TIMES; -} - -/** - * Marks a flag to read both flap times and course times from the eeprom - */ -void mark_to_read_flap_and_course_times(void) { - gSaveDataFlags |= (SAVE_DATA_FLAG_READ_FLAP_TIMES | SAVE_DATA_FLAG_READ_COURSE_TIMES); -} - -/** - * Marks a flag to read the save file from the passed index from flash. - */ -void mark_read_save_file(s32 saveFileIndex) { - //Wipe out bits 8 and 9 - gSaveDataFlags &= ~(SAVE_DATA_FLAG_READ_EEPROM_SETTINGS | SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS); - //Place saveFileIndex at bits 8 and 9 and set bit 2 - gSaveDataFlags |= (SAVE_DATA_FLAG_READ_SAVE_DATA | ((saveFileIndex & SAVE_DATA_FLAG_INDEX_VALUE) << 8)); -} - -/** - * Marks a flag to read all save file data from flash. - */ -void mark_read_all_save_files(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_READ_ALL_SAVE_DATA; //Set bit 3 -} - -/** - * Marks a flag to write flap times to the eeprom - */ -void mark_to_write_flap_times(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_FLAP_TIMES; -} - -/** - * Marks a flag to write course times to the eeprom - */ -void mark_to_write_course_times(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_COURSE_TIMES; -} - -/** - * Marks a flag to write both flap times and course times to the eeprom - */ -void mark_to_write_flap_and_course_times(void) { - gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_FLAP_TIMES | SAVE_DATA_FLAG_WRITE_COURSE_TIMES); -} - -/** - * Forcefully marks a flag to write a save file to flash. - * Official Name: mainSaveGame - */ -void force_mark_write_save_file(s32 saveFileIndex) { - gSaveDataFlags &= ~SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS; //Wipe out bits 10 and 11 - gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_SAVE_DATA | ((saveFileIndex & 3) << 10)); //Set bit 6 and place saveFileIndex into bits 10 and 11 -} - -/** - * Marks a flag to write a save file to flash as long as we're not in tracks mode, and we're in the draw game render context. - * This should prevent save data from being overwritten outside of Adventure Mode. - * Official Name: mainSaveGame2 - */ -void safe_mark_write_save_file(s32 saveFileIndex) { - if (sRenderContext == DRAW_GAME && !is_in_tracks_mode()) { - gSaveDataFlags &= ~SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS; //Wipe out bits 10 and 11 - gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_SAVE_DATA | ((saveFileIndex & 3) << 10));; //Set bit 6 and place saveFileIndex into bits 10 and 11 - } -} - -/** - * Marks a flag to erase a save file from flash later - */ -void mark_save_file_to_erase(s32 saveFileIndex) { - //Set bit 7 and and place saveFileIndex into bits 10 and 11 while wiping everything else - gSaveDataFlags = SAVE_DATA_FLAG_ERASE_SAVE_DATA | ((saveFileIndex & 3) << 10); -} - -/** - * Marks a flag to read eeprom settings from flash later - * @bug: Because this is the same bit used for reading save files, - * it will change the save file number to read from - */ -UNUSED void mark_read_eeprom_settings(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_READ_EEPROM_SETTINGS; // Set bit 8 -} - -/** - * Marks a flag to write eeprom settings to flash later - * @bug: Because this is the same bit used for reading save files, - * it will change the save file number to read from - */ -void mark_write_eeprom_settings(void) { - gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS; // Set bit 9 -} - -/** - * Allocates an amount of memory for the number of players passed in. - */ -void alloc_displaylist_heap(s32 numberOfPlayers) { - s32 num; - s32 totalSize; - - if (numberOfPlayers != gPrevPlayerCount) { - gPrevPlayerCount = numberOfPlayers; - num = numberOfPlayers; - set_free_queue_state(0); - free_from_memory_pool(gDisplayLists[0]); - free_from_memory_pool(gDisplayLists[1]); - totalSize = - ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords))) - + ((gNumHudMatPerPlayer[num] * sizeof(Matrix))) - + ((gNumHudVertsPerPlayer[num] * sizeof(Vertex))) - + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle))); - gDisplayLists[0] = (Gfx *) allocate_at_address_in_main_pool(totalSize, (u8 *) gDisplayLists[0], COLOUR_TAG_RED); - gDisplayLists[1] = (Gfx *) allocate_at_address_in_main_pool(totalSize, (u8 *) gDisplayLists[1], COLOUR_TAG_YELLOW); - if ((gDisplayLists[0] == NULL) || gDisplayLists[1] == NULL) { - if (gDisplayLists[0] != NULL) { - free_from_memory_pool(gDisplayLists[0]); - gDisplayLists[0] = NULL; - } - if (gDisplayLists[1] != NULL) { - free_from_memory_pool(gDisplayLists[1]); - gDisplayLists[1] = NULL; - } - default_alloc_displaylist_heap(); - } - gMatrixHeap[0] = (MatrixS *)((u8 *) gDisplayLists[0] + ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords)))); - gTriangleHeap[0] = (TriangleList *)((u8 *) gMatrixHeap[0] + ((gNumHudMatPerPlayer[num] * sizeof(Matrix)))); - gVertexHeap[0] = (Vertex *)((u8 *) gTriangleHeap[0] + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle)))); - gMatrixHeap[1] = (MatrixS *)((u8 *) gDisplayLists[1] + ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords)))); - gTriangleHeap[1] = (TriangleList *)((u8 *) gMatrixHeap[1] + ((gNumHudMatPerPlayer[num] * sizeof(Matrix)))); - gVertexHeap[1] = (Vertex *)((u8 *) gTriangleHeap[1] + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle)))); - gCurrNumF3dCmdsPerPlayer = gNumF3dCmdsPerPlayer[num]; - gCurrNumHudMatPerPlayer = gNumHudMatPerPlayer[num]; - gCurrNumHudTrisPerPlayer = gNumHudTrisPerPlayer[num]; - gCurrNumHudVertsPerPlayer = gNumHudVertsPerPlayer[num]; - set_free_queue_state(2); - } - gCurrDisplayList = gDisplayLists[gSPTaskNum]; - gGameCurrMatrix = gMatrixHeap[gSPTaskNum]; - gGameCurrTriList = gTriangleHeap[gSPTaskNum]; - gGameCurrVertexList = gVertexHeap[gSPTaskNum]; - - gDPFullSync(gCurrDisplayList++); - gSPEndDisplayList(gCurrDisplayList++); -} - -/** - * Returns FALSE if dmem doesn't begin with a -1. This is checked on every main game loop iteration. - */ -s32 check_dmem_validity(void) { - if (IO_READ(SP_DMEM_START) != -1U) { - return FALSE; - } - return TRUE; -} - -/** - * Defaults allocations for 4 players - */ -void default_alloc_displaylist_heap(void) { - s32 numberOfPlayers; - s32 totalSize; - - numberOfPlayers = FOUR_PLAYERS; - gPrevPlayerCount = numberOfPlayers; - totalSize = (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords)) - + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix)) - + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex)) - + (gNumHudTrisPerPlayer[numberOfPlayers] * sizeof(Triangle)); - - gDisplayLists[0] = (Gfx *) allocate_from_main_pool_safe(totalSize, COLOUR_TAG_RED); - gMatrixHeap[0] = (MatrixS *) ((u8 *) gDisplayLists[0] + (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords))); - gVertexHeap[0] = (Vertex *) ((u8 *) gMatrixHeap[0] + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix))); - gTriangleHeap[0] = (TriangleList *) ((u8 *) gVertexHeap[0] + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex))); - - gDisplayLists[1] = (Gfx *) allocate_from_main_pool_safe(totalSize, COLOUR_TAG_YELLOW); - gMatrixHeap[1] = (MatrixS *) ((u8 *) gDisplayLists[1] + (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords))); - gVertexHeap[1] = (Vertex *) ((u8 *) gMatrixHeap[1] + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix))); - gTriangleHeap[1] = (TriangleList *) ((u8 *) gVertexHeap[1] + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex))); - - gCurrNumF3dCmdsPerPlayer = gNumF3dCmdsPerPlayer[numberOfPlayers]; - gCurrNumHudMatPerPlayer = gNumHudMatPerPlayer[numberOfPlayers]; - gCurrNumHudTrisPerPlayer = gNumHudTrisPerPlayer[numberOfPlayers]; - gCurrNumHudVertsPerPlayer = gNumHudVertsPerPlayer[numberOfPlayers]; -} - -void func_8006F140(s32 arg0) { - if (gLevelLoadTimer == 0) { - gLevelLoadTimer = 40; - gLevelLoadType = LEVEL_LOAD_NORMAL; - D_80123526 = 0; - if (arg0 == 1) { //FADE_BARNDOOR_HORIZONTAL? - transition_begin(&gLevelFadeOutTransition); - } - if (arg0 == 3) { //FADE_CIRCLE? - gLevelLoadTimer = 282; - transition_begin(&D_800DD424); - } - if (arg0 == 4) { //FADE_WAVES? - gLevelLoadTimer = 360; - transition_begin(&D_800DD424); - } - if (arg0 == 0) { //FADE_FULLSCREEN? - gLevelLoadTimer = 2; - } - } -} - -UNUSED void func_8006F20C(void) { - if (gLevelLoadTimer == 0) { - transition_begin(&gLevelFadeOutTransition); - gLevelLoadTimer = 40; - gLevelLoadType = LEVEL_LOAD_UNK1; - } -} - -/** - * Begins a fade transition, then signals to the level loading that it wants to be a trophy race. -*/ -void begin_trophy_race_teleport(void) { - if (gLevelLoadTimer == 0) { - transition_begin(&gLevelFadeOutTransition); - gLevelLoadTimer = 40; - gLevelLoadType = LEVEL_LOAD_TROPHY_RACE; - } -} - -/** - * Check if all available trophy races and Wizpig 1 has been beaten, and if the cutscene has not yet played. -*/ -void begin_lighthouse_rocket_cutscene(void) { - if (gLevelLoadTimer == 0) { - if ((gSettingsPtr->trophies & 0xFF) == 0xFF && !(gSettingsPtr->cutsceneFlags & CUTSCENE_LIGHTHOUSE_ROCKET) && gSettingsPtr->bosses & 1) { - gSettingsPtr->cutsceneFlags |= CUTSCENE_LIGHTHOUSE_ROCKET; - transition_begin(&gLevelFadeOutTransition); - gLevelLoadTimer = 40; - gNextMap = ASSET_LEVEL_ROCKETSEQUENCE; - gLevelLoadType = LEVEL_LOAD_LIGHTHOUSE_CUTSCENE; - } - } -} - -/** - * Begin a transition, then set the next level to the passed argument. - * This is used only to warp to Future Fun Land from the hub area. -*/ -void begin_level_teleport(s32 levelID) { - if (gLevelLoadTimer == 0) { - gNextMap = levelID; - transition_begin(&gLevelFadeOutTransition); - gLevelLoadTimer = 40; - gLevelLoadType = LEVEL_LOAD_FUTURE_FUN_LAND; - } -} - -void func_8006F388(u8 time) { - D_800DD398 = time; -} - -void func_8006F398(void) { - s32 i; - u8 temp; - u8 *first_racer_data; - u8 *second_racer_data; - - swap_player_1_and_2_ids(); - func_8000E194(); - - first_racer_data = (u8 *)(gSettingsPtr->racers); - second_racer_data = (u8 *)(gSettingsPtr->racers + 1); - - for (i = 0; i < (s32)sizeof(Racer); i++) { - temp = first_racer_data[i]; - first_racer_data[i] = second_racer_data[i]; - second_racer_data[i] = temp; - } -} - -/** - * Sets the timer to delay drawing new frames. - * When set to 2, the game will copy the previous framebuffer over to the next. -*/ -void set_frame_blackout_timer(void) { - gDrawFrameTimer = 2; -} - -/** - * Give the player 8 frames to enter the CPak menu with start, then load the intro sequence. - */ -void pre_intro_loop(void) { - s32 i; - s32 buttonInputs = 0; - - for (i = 0; i < MAXCONTROLLERS; i++) { - buttonInputs |= get_buttons_held_from_player(i); - } - if (buttonInputs & START_BUTTON) { - gShowControllerPakMenu = TRUE; - } - sBootDelayTimer++; - if (sBootDelayTimer >= 8) { - load_menu_with_level_background(MENU_BOOT, 0x27, 2); - } -} - -/** - * Returns TRUE if the game doesn't detect any controllers. - * Official name: mainDemoOnly - */ -s32 is_controller_missing(void) { - if (sControllerStatus == CONTROLLER_MISSING) { - return TRUE; - } else { - return FALSE; - } -} - -/** - * Ran on boot, will make sure the CIC chip (CIC6103) is to spec. Will return true if it's all good, otherwise it returns false. - * The intention of this function, is an attempt to check that the cartridge is a legitimate copy. - * A false read, meaning you're caught running an illegitimate copy, will force the game to pause when you enter the world. - */ -s32 check_imem_validity(void) { - if (IO_READ(SP_IMEM_START) != CIC_ID) { - return FALSE; - } - return TRUE; -} diff --git a/src/game.h b/src/game.h index 5685cba7..5b33c227 100644 --- a/src/game.h +++ b/src/game.h @@ -1,22 +1,11 @@ -#ifndef _UNKNOWN_06B2B0_H_ -#define _UNKNOWN_06B2B0_H_ +#ifndef _GAME_H_ +#define _GAME_H_ #include "types.h" -#include "video.h" #include "structs.h" #include "fade_transition.h" -#include "libc/math.h" #include "racer.h" - -typedef enum RenderContext { - DRAW_INTRO = -1, - DRAW_GAME, - DRAW_MENU, - DRAW_UNK_02, - DRAW_UNK_03, - DRAW_UNK_04, - DRAW_CRASH_SCREEN -} RenderContext; +#include "thread3_main.h" /* Size: 6 bytes */ typedef struct LevelGlobalData { @@ -44,49 +33,6 @@ enum CutsceneIDs { CUTSCENE_ID_UNK_64 = 0x64 }; -enum LevelLoadType { - LEVEL_LOAD_NORMAL, - LEVEL_LOAD_UNK1, - LEVEL_LOAD_TROPHY_RACE, - LEVEL_LOAD_LIGHTHOUSE_CUTSCENE, - LEVEL_LOAD_FUTURE_FUN_LAND, -}; - -/** - * Bit 00: Read Eeprom Data flap times - * Bit 01: Read Eeprom Data course times - * Bit 02: Read Save File from bits 8 and 9 - * Bit 03: Read All Save Files - * Bit 04: Write Eeprom Data flap times - * Bit 05: Write Eeprom Data course times - * Bit 06: Write Save Data from bits 10 and 11 - * Bit 07: Erase Save File from bits 10 and 11 - * Bit 08: Read Save File Number Part 1 @bug Also Read Eeprom settings - * Bit 09: Read Save File Number Part 2 @bug Also Write Eeprom Settings - * Bit 10: Write Save File Number Part 1 - * Bit 11: Write Save File Number Part 2 - */ -extern s32 gSaveDataFlags; -#define SAVE_DATA_FLAG_INDEX_VALUE (1 << 0 | 1 << 1) //2 bits for 4 different values - -#define SAVE_DATA_FLAG_READ_FLAP_TIMES (1 << 0) -#define SAVE_DATA_FLAG_READ_COURSE_TIMES (1 << 1) -#define SAVE_DATA_FLAG_READ_SAVE_DATA (1 << 2) -#define SAVE_DATA_FLAG_READ_ALL_SAVE_DATA (1 << 3) -#define SAVE_DATA_FLAG_WRITE_FLAP_TIMES (1 << 4) -#define SAVE_DATA_FLAG_WRITE_COURSE_TIMES (1 << 5) -#define SAVE_DATA_FLAG_WRITE_SAVE_DATA (1 << 6) -#define SAVE_DATA_FLAG_ERASE_SAVE_DATA (1 << 7) -#define SAVE_DATA_FLAG_READ_EEPROM_SETTINGS (1 << 8) //@bug Bits 8 and 9 are reused for checking the read save file number -#define SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS (1 << 9) // ^^ -#define SAVE_DATA_FLAG_READ_SAVE_FILE_NUMBER_BITS (1 << 8 | 1 << 9) //These are reused as above -#define SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS (1 << 10 | 1 << 11) - -#define SAVE_DATA_FLAG_READ_EEPROM_INDEX(flags) (flags & (SAVE_DATA_FLAG_READ_FLAP_TIMES | SAVE_DATA_FLAG_READ_COURSE_TIMES)) -#define SAVE_DATA_FLAG_WRITE_EEPROM_INDEX(flags) ((flags & (SAVE_DATA_FLAG_WRITE_FLAP_TIMES | SAVE_DATA_FLAG_WRITE_COURSE_TIMES)) >> 4) -#define SAVE_DATA_FLAG_READ_SAVE_FILE_NUMBER(flags) ((flags >> 8) & SAVE_DATA_FLAG_INDEX_VALUE) -#define SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER(flags) ((flags >> 10) & SAVE_DATA_FLAG_INDEX_VALUE) - Vehicle get_map_default_vehicle(s32 mapId); s32 get_map_available_vehicles(s32 mapId); s8 get_map_race_type(s32 mapId); @@ -110,68 +56,5 @@ void pop_level_property_stack(s32 *levelId, s32 *entranceId, s32 *vehicleId, s32 void clear_level_property_stack(void); s16 get_level_property_stack_pos(void); s32 func_8006C300(void); -void thread3_main(UNUSED void *unused); -void init_game(void); -void main_game_loop(void); -void func_8006CAE4(s32 numPlayers, s32 trackID, Vehicle vehicle); -void load_level_game(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId); -void unload_level_game(void); -void func_8006D8A4(void); -void func_8006D8E0(s32 arg0); -void func_8006D8F0(s32 arg0); -void func_8006D968(s8 *arg0); -RenderContext get_render_context(void); -UNUSED void func_8006DA1C(s32 arg0); -void load_menu_with_level_background(s32 menuId, s32 levelId, s32 cutsceneId); -void set_level_default_vehicle(Vehicle arg0); -void func_8006DB20(Vehicle vehicleId); -Vehicle get_level_default_vehicle(void); -void load_level_menu(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId); -void unload_level_menu(void); -void update_menu_scene(s32 arg0); -void load_level_for_menu(s32 levelId, s32 numberOfPlayers, s32 cutsceneId); -void calc_and_alloc_heap_for_settings(void); -void func_8006E5BC(void); -void func_8006E770(Settings *settings, s32 arg1); -void func_8006E994(Settings *settings); -void func_8006EA58(void); -Settings *get_settings(void); -s8 is_game_paused(void); -s8 is_postrace_viewport_active(void); -s32 is_reset_pressed(void); -s32 get_ingame_map_id(void); -void mark_to_read_flap_times(void); -void mark_to_read_course_times(void); -void mark_to_read_flap_and_course_times(void); -void mark_read_save_file(s32 saveFileIndex); -void mark_read_all_save_files(void); -void mark_to_write_flap_times(void); -void mark_to_write_course_times(void); -void mark_to_write_flap_and_course_times(void); -void force_mark_write_save_file(s32 saveFileIndex); -void safe_mark_write_save_file(s32 saveFileIndex); -void mark_save_file_to_erase(s32 saveFileIndex); -void mark_read_eeprom_settings(void); -void mark_write_eeprom_settings(void); -s32 check_dmem_validity(void); -void func_8006F140(s32 arg0); -void func_8006F20C(void); -void begin_trophy_race_teleport(void); -void begin_lighthouse_rocket_cutscene(void); -void begin_level_teleport(s32 arg0); -void func_8006F388(u8 arg0); -void func_8006F398(void); -void set_frame_blackout_timer(void); -void pre_intro_loop(void); -s32 is_controller_missing(void); -s32 check_imem_validity(void); -void ingame_logic_loop(s32 updateRate); -void load_level(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId); -void init_level_globals(void); -void alloc_displaylist_heap(s32 numberOfPlayers); -void default_alloc_displaylist_heap(void); - -//Non Matching -void func_8006DCF8(s32 updateRate); #endif diff --git a/src/game_ui.c b/src/game_ui.c index 19dae1db..779f8079 100644 --- a/src/game_ui.c +++ b/src/game_ui.c @@ -715,6 +715,7 @@ void render_hud_hubworld(Object *obj, s32 updateRate) { } // render_hud_time_trial +//https://decomp.me/scratch/nZxsE GLOBAL_ASM("asm/non_matchings/game_ui/func_800A277C.s") GLOBAL_ASM("asm/non_matchings/game_ui/func_800A36CC.s") diff --git a/src/menu.c b/src/menu.c index 02549e25..23459742 100644 --- a/src/menu.c +++ b/src/menu.c @@ -263,7 +263,7 @@ char **D_80126C1C; s32 D_80126C20; s32 D_80126C24; s8 D_80126C28; -s32 *D_80126C2C; +unk80080BC8 (*D_80126C2C)[2]; u16 (*gCheatsAssetData)[30]; // Cheat table. s32 D_80126C34; s32 gNumberOfCheats; @@ -1438,31 +1438,36 @@ s8 D_800E1CD0[32] = { 16, 17, 18, 16, 18, 19, 0, 0 }; -s8 D_800E1CF0[60] = { - 0, 0, 3, 0, 2, 1, 0, 0, - 2, 1, 1, 1, 2, 1, 3, 0, - 3, 3, 2, 1, 3, 3, 2, 2, - 1, 2, 2, 2, 3, 3, 1, 2, - 3, 3, 0, 3, 0, 0, 1, 1, - 1, 2, 0, 0, 1, 2, 0, 3, - 1, 1, 2, 1, 2, 2, 1, 1, - 2, 2, 1, 2 +// UV coordinate indices +u8 D_800E1CF0[5][12] = { + { 0, 0, 3, 0, 2, 1, 0, 0, 2, 1, 1, 1 }, + { 2, 1, 3, 0, 3, 3, 2, 1, 3, 3, 2, 2 }, + { 1, 2, 2, 2, 3, 3, 1, 2, 3, 3, 0, 3 }, + { 0, 0, 1, 1, 1, 2, 0, 0, 1, 2, 0, 3 }, + { 1, 1, 2, 1, 2, 2, 1, 1, 2, 2, 1, 2 } }; -u16 D_800E1D2C[40] = { - 0x0000, 0x0000, 0x0100, 0x0000, 0x01FF, 0x00FF, 0x0001, 0x00FF, - 0x01FF, 0x00FF, 0x0100, 0x0000, 0x0100, 0xFF00, 0x01FF, 0xFF01, - 0x0001, 0xFF01, 0x01FF, 0xFF01, 0x0100, 0xFF00, 0x0000, 0xFF00, - 0x0000, 0x0000, 0x0001, 0x00FF, 0x0001, 0xFF01, 0x0000, 0xFF00, - 0x0001, 0x00FF, 0x01FF, 0x00FF, 0x01FF, 0xFF01, 0x0001, 0xFF01 +// Position offsets, why are there 10? +u16 D_800E1D2C[10][4] = { + { 0, 0, 256, 0 }, + { 511, 255, 1, 255 }, + { 511, 255, 256, 0 }, + { 256, -256, 511, -255 }, + { 1, -255, 511, -255 }, + { 256, -256, 0, -256 }, + { 0, 0, 1, 255 }, + { 1, -255, 0, -256 }, + { 1, 255, 511, 255 }, + { 511, -255, 1, -255 } }; -s16 D_800E1D7C[20] = { - 0x00D8, 0x00D8, 0x00D8, 0x0100, - 0x00B0, 0x00B0, 0x00B0, 0x0100, - 0x0060, 0x0060, 0x0060, 0x0100, - 0x0088, 0x0088, 0x0088, 0x0100, - 0x0100, 0x0100, 0x0100, 0x0100 +// Colours +s16 D_800E1D7C[5][4] = { + { 216, 216, 216, 256 }, + { 176, 176, 176, 256 }, + { 96, 96, 96, 256 }, + { 136, 136, 136, 256 }, + { 256, 256, 256, 256 } }; s32 *D_800E1DA4[2] = { @@ -1712,14 +1717,147 @@ void func_80080518(f32 arg0, f32 arg1) { D_800E1DC4 = (s32) (arg1 * 32.0f); } +//https://decomp.me/scratch/W0adv +#ifdef NON_EQUIVALENT +void func_80080580(Gfx** dlist, s32 x, s32 y, s32 x0, s32 y0, s32 x1, s32 y1, s32 colour, TextureHeader* tex) { + s32 uVals[4]; + s32 vVals[4]; + Vertex* verts; + Triangle* tris; + s32 j; + s32 i; + s32 texEnabled; + + //((unk80080BC8*)((u8*)D_80126C2C[D_800E1DB8] + (D_800E1DB4 * 4)))->texture = tex; + ((unk80080BC8*)((u8*)D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)))->texture = tex; + //(&(*D_80126C2C)[D_800E1DB8] + (D_800E1DB4 * 4))->texture = tex; + //D_80126C2C[D_800E1DB8][D_800E1DB4].texture = tex; + if (tex != NULL) { + uVals[0] = 0; + vVals[0] = 0; + uVals[1] = D_800E1DC0 * x1; + uVals[2] = (x0 - x1) * D_800E1DC0; + uVals[3] = D_800E1DC0 * x0; + vVals[1] = D_800E1DC4 * y1; + vVals[2] = (y0 - y1) * D_800E1DC4; + vVals[3] = D_800E1DC4 * y0; + tris = ((unk80080BC8*)((u8*)D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)))->triangles; + for (i = 0; i < 5; i++) { + tris[i*2].uv0.u = uVals[D_800E1CF0[i][0]]; + tris[i*2].uv0.v = vVals[D_800E1CF0[i][1]]; + tris[i*2].uv1.u = uVals[D_800E1CF0[i][2]]; + tris[i*2].uv1.v = vVals[D_800E1CF0[i][3]]; + tris[i*2].uv2.u = uVals[D_800E1CF0[i][4]]; + tris[i*2].uv2.v = vVals[D_800E1CF0[i][5]]; + tris[i*2+1].uv0.u = uVals[D_800E1CF0[i][6]]; + tris[i*2+1].uv0.v = vVals[D_800E1CF0[i][7]]; + tris[i*2+1].uv1.u = uVals[D_800E1CF0[i][8]]; + tris[i*2+1].uv1.v = vVals[D_800E1CF0[i][9]]; + tris[i*2+1].uv2.u = uVals[D_800E1CF0[i][10]]; + tris[i*2+1].uv2.v = vVals[D_800E1CF0[i][11]]; + } + } + verts = ((unk80080BC8*)((u8*)D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)))->vertices; + for (i = 0; i < 5; i++) { + for(j = 0; j < 4; j++) { + verts[j].x = x; + verts[j].y = y; + verts[j].x += (D_800E1D2C[j][0] * x0); + verts[j].x += (D_800E1D2C[j][1] * x1); + verts[j].y += (D_800E1D2C[j][2] * y0); + verts[j].y += (D_800E1D2C[j][3] * y1); + verts[j].z = 0; + verts[j].r = (s32) (D_800E1D7C[i][0] * ((colour >> 0x18) & 0xFF)) >> 8; + verts[j].g = (s32) (D_800E1D7C[i][1] * ((colour >> 0x10) & 0xFF)) >> 8; + verts[j].b = (s32) (D_800E1D7C[i][2] * ((colour >> 8) & 0xFF)) >> 8; + verts[j].a = (s32) (D_800E1D7C[i][3] * (colour & 0xFF)) >> 8; + } + } + if (dlist != NULL) { + ((unk80080BC8*)((u8*)D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)))->unk18 = 1; + gSPDisplayList((*dlist)++, &dMenuHudSettings); + if (tex != NULL) { + texEnabled = TRUE; + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(&dMenuHudSettings[8]), 2); + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(tex->cmd), tex->numberOfCommands); + } else { + texEnabled = FALSE; + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(&dMenuHudSettings[6]), 2); + } + gDPPipeSync((*dlist)++); + /* + temp_v0_6 = *dlist; + *dlist = temp_v0_6 + 8; + temp_v0_6->words.w0 = (((((*(D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)) + 0x80000000) & 6) | 0x98) & 0xFF) << 0x10) | 0x04000000 | 0x170; + temp_v0_6->words.w1 = *(D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4)) + 0x80000000; + */ + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(((unk80080BC8*)((u8*)D_80126C2C + (i * 32) + (D_800E1DB4 * 4)))->vertices), 20, 0); + /* + temp_v0_7 = *dlist; + *dlist = temp_v0_7 + 8; + temp_v0_7->words.w0 = (((texEnabled | 0x90) & 0xFF) << 0x10) | 0x05000000 | 0xA0; + temp_v0_7->words.w1 = (D_80126C2C + (D_800E1DB8 << 5) + (D_800E1DB4 * 4))->unk8 + 0x80000000; + */ + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL(((unk80080BC8*)((u8*)D_80126C2C + (i * 32) + (D_800E1DB4 * 4)))->triangles), 10, texEnabled); + reset_render_settings(dlist); + } else { + ((unk80080BC8*)((u8*)D_80126C2C + (D_800E1DB8 * 32) + (D_800E1DB4 * 4)))->unk18 = 0; + } + D_800E1DB8++; +} +#else GLOBAL_ASM("asm/non_matchings/menu/func_80080580.s") +#endif + +//https://decomp.me/scratch/lS3f5 +#ifdef NON_EQUIVALENT +void func_80080BC8(Gfx** dlist) { + s16 temp_a1; + s32 i; + s32 var_t0; + TextureHeader *tex; + TextureHeader *lastTex; + + gSPDisplayList((*dlist)++, &dMenuHudSettings); + var_t0 = -1; + lastTex = NULL; + + for (i = 0; i < D_800E1DB8; i++) { + //((unk80080BC8*)((u8*)D_80126C2C + (i << 5) + (D_800E1DB4 * 4)))->texture + if (!D_80126C2C[i][D_800E1DB4].unk18) { + tex = D_80126C2C[i][D_800E1DB4].texture; + if (tex != NULL) { + if (var_t0 != 1) { + var_t0 = 1; + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(&dMenuHudSettings[8]), 2); + } + if (lastTex != tex) { + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(tex->cmd), tex->numberOfCommands); + lastTex = tex; + } + } else if (var_t0 != 0) { + var_t0 = 0; + gDkrDmaDisplayList((*dlist)++, OS_K0_TO_PHYSICAL(&dMenuHudSettings[6]), 2); + } + gDPPipeSync((*dlist)++); + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL((&D_80126C2C[i][D_800E1DB4])->vertices), 20, 0); + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL((&D_80126C2C[i][D_800E1DB4])->triangles), 10, 0); + } + } + D_800E1DB8 = 0; + D_800E1DB4 = 1 - D_800E1DB4; + reset_render_settings(dlist); +} +#else GLOBAL_ASM("asm/non_matchings/menu/func_80080BC8.s") +#endif void func_80080E6C(void) { D_800E1DB8 = 0; D_800E1DB4 = (s32)(1 - D_800E1DB4); } +//https://decomp.me/scratch/IZ1Gq GLOBAL_ASM("asm/non_matchings/menu/func_80080E90.s") // init_save_data @@ -5833,6 +5971,7 @@ void func_8008F534(void) { set_D_800DD430(0); } +//https://decomp.me/scratch/ubeU1 GLOBAL_ASM("asm/non_matchings/menu/func_8008F618.s") GLOBAL_ASM("asm/non_matchings/menu/renderTrackSelect.s") @@ -8406,6 +8545,7 @@ void allocate_and_set_menu_image_properties(s32 imageID) { void func_8009CA58(void) { } +//https://decomp.me/scratch/rfLCI GLOBAL_ASM("asm/non_matchings/menu/func_8009CA60.s") /** diff --git a/src/menu.h b/src/menu.h index 64caa825..2d8af0bb 100644 --- a/src/menu.h +++ b/src/menu.h @@ -121,6 +121,17 @@ typedef struct unk800DF510 { u8 pad1E[2]; } unk800DF510; +typedef struct unk80080BC8 { + Vertex *vertices; + s32 *unk4; + Triangle *triangles; + s32 *unkC; + TextureHeader *texture; + s32 *unk14; + s32 unk18; + s32 unk1C; +} unk80080BC8; + typedef struct unk80126460 { MenuElement elem[2]; } unk80126460; @@ -632,12 +643,6 @@ extern Gfx dMenuHudSettings[6]; extern s8 D_800E1CD0[32]; -extern s8 D_800E1CF0[60]; - -extern u16 D_800E1D2C[40]; - -extern s16 D_800E1D7C[20]; - extern s32 *D_800E1DA4[2]; extern s32 *D_800E1DAC[2]; @@ -678,7 +683,6 @@ extern u64 sEepromSettings; extern char *sInsertControllerPakMenuText[3]; extern char *sNoControllerPakMenuText[5]; extern char *sInsertRumblePakMenuText[4]; -extern s32 *D_80126C2C; extern Settings *gSavefileData[4]; extern DrawTexture D_800DFC10[2]; @@ -923,7 +927,7 @@ void set_D_800DD430(s8 arg0); void func_80099E8C(s32 updateRate); s32 func_800998E0(s32 arg0); void func_80081218(void); -void func_80080580(Gfx **arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7, void *arg8); +void func_80080580(Gfx** dlist, s32 x, s32 y, s32 x0, s32 y0, s32 x1, s32 y1, s32 colour, TextureHeader* tex); void func_800853D0(unk800861C8 *arg0, s32 arg1, s32 arg2); void render_enter_filename_ui(UNUSED s32 unused); void func_8008D8BC(s32 updateRate); diff --git a/src/objects.c b/src/objects.c index 8bee4dc3..18cfbf1e 100644 --- a/src/objects.c +++ b/src/objects.c @@ -2167,7 +2167,87 @@ void func_800142B8(void) { } } -GLOBAL_ASM("asm/non_matchings/objects/func_800143A8.s") +s32 func_800143A8(ObjectModel *objModel, Object *obj, s32 startIndex, s32 flags, s32 someBool) { + s32 i; + s32 textureIndex; + s32 triOffset; + TextureHeader *texToSet; + s32 endLoop; + s32 numTris; + s32 texEnabled; + s32 texOffset; + s32 numVertices; + Vertex *vtx; + s32 offsetStartVertex; + s32 texToSetFlags; + Triangle *tris; + s32 vertOffset; + Gfx *dlist; + + dlist = gObjectCurrDisplayList; + i = startIndex; + endLoop = FALSE; + while (i < objModel->numberOfBatches && !endLoop) { + if ((objModel->batches[i].flags & 4) == 0 || (flags & 4)) { + //Hidden/Invisible geometry + textureIndex = objModel->batches[i].flags & BATCH_FLAGS_HIDDEN; + //Probably a fakematch to use textureIndex here, but it works. + if (!textureIndex) { + vertOffset = objModel->batches[i].verticesOffset; + triOffset = objModel->batches[i].facesOffset; + numVertices = objModel->batches[i + 1].verticesOffset - vertOffset; + offsetStartVertex = (someBool) ? objModel->batches[i].unk1 : numVertices; + numTris = objModel->batches[i + 1].facesOffset - triOffset; + tris = &objModel->triangles[triOffset]; + vtx = &obj->unk44[vertOffset]; + textureIndex = objModel->batches[i].textureIndex; + //textureIndex of 0xFF is no texture + if (textureIndex == 0xFF) { + texOffset = 0; + texToSet = NULL; + texEnabled = FALSE; + } else { + texOffset = objModel->batches[i].unk7 << 14; + texEnabled = TRUE; + texToSet = objModel->textures[textureIndex].texture; + } + texToSetFlags = objModel->batches[i].flags | BATCH_FLAGS_UNK00000008; + if (flags & RENDER_SEMI_TRANSPARENT && !(objModel->batches[i].flags & (flags & ~RENDER_SEMI_TRANSPARENT))) { + texToSetFlags |= RENDER_SEMI_TRANSPARENT; + } + if (D_800DC720 == 0) { + load_and_set_texture(&dlist, texToSet, texToSetFlags, texOffset); + } else { + texToSet = func_8007B46C(texToSet, texOffset); + gDkrDmaDisplayList(gObjectCurrDisplayList++, OS_K0_TO_PHYSICAL(texToSet->cmd), texToSet->numberOfCommands); + } + if (offsetStartVertex == numVertices) { + gSPVertexDKR(dlist++, OS_K0_TO_PHYSICAL(vtx), numVertices, 0); + } else { + if (offsetStartVertex > 0) { + gSPVertexDKR(dlist++, OS_K0_TO_PHYSICAL(vtx), offsetStartVertex, 0); + gDkrInsertMatrix(dlist++, 0, G_MTX_DKR_INDEX_2); + gSPVertexDKR(dlist++, OS_K0_TO_PHYSICAL(&vtx[offsetStartVertex]), (numVertices - offsetStartVertex), 1); + } else { + gDkrInsertMatrix(dlist++, 0, G_MTX_DKR_INDEX_2); + gSPVertexDKR(dlist++, OS_K0_TO_PHYSICAL(vtx), numVertices, 0); + } + gDkrInsertMatrix(dlist++, 0, G_MTX_DKR_INDEX_1); + } + gSPPolygon(dlist++, OS_K0_TO_PHYSICAL(tris), numTris, texEnabled); + } + i++; + } else { + endLoop = TRUE; + } + } + if (i >= objModel->numberOfBatches) { + i = -1; + } + gObjectCurrDisplayList = dlist; + return i; +} + GLOBAL_ASM("asm/non_matchings/objects/func_80014814.s") GLOBAL_ASM("asm/non_matchings/objects/func_80014B50.s") GLOBAL_ASM("asm/non_matchings/objects/func_80015348.s") diff --git a/src/objects.h b/src/objects.h index 15bf888e..a8573159 100644 --- a/src/objects.h +++ b/src/objects.h @@ -430,6 +430,7 @@ s32 func_800113CC(Object *obj, s32 arg1, s32 frame, s32 oddSoundId, s32 evenSoun void func_80011AD0(Object *this); Object *func_8001BDD4(Object *obj, s32 *cameraID); s32 init_object_shadow(Object *obj, ShadowData *shadow); +s32 func_800143A8(ObjectModel *objModel, Object *obj, s32 startIndex, s32 flags, s32 someBool); //Non Matching void calc_dynamic_lighting_for_object_1(Object *, ObjectModel *, s16, Object *, f32, f32); @@ -447,7 +448,6 @@ void func_80022E18(s32); /* extern */ void func_80018CE0(Object* obj, f32 xPos, f32 yPos, f32 zPos, s32 updateRate); /* extern */ s32 func_800185E4(s8, Object* obj, f32 xPos, f32 yPos, f32 zPos, f32* checkpointDistance, u8*); /* extern */ void func_80011134(Object *, s32); -s32 func_800143A8(ObjectModel*, Object*, s32, s32, s32); /* extern */ void func_800138A8(ObjectTransform*, unk80068514_arg4*, Object *, s32); Object *func_8002342C(f32 x, f32 z); void func_8006017C(s32); diff --git a/src/particles.c b/src/particles.c index 708c5da2..8f12244c 100644 --- a/src/particles.c +++ b/src/particles.c @@ -15,12 +15,6 @@ /************ .rodata ************/ -// Need to move this to the correct file when we figure out where the lens flare code is. -const char D_800E87F0[] = "\nMaximum limit of %d lens flare switches, per level, has been exceeded."; - -// This is most likely a file boundary. Not sure where the split occurs though. -const int D_800E8838[2] = { 0, 0 }; - const char D_800E8840[] = "\n\nUnknown trigger type in initParticleTrigger %d, Max %d.\n\n"; const char D_800E887C[] = "\n\nUnknown particle type in initParticleTrigger %d, Max %d.\n\n"; const char D_800E88BC[] = "\n\nUnknown trigger type in initParticleTrigger %d, Max %d.\n\n"; @@ -1432,7 +1426,93 @@ UNUSED void func_800B3678(Gfx **arg0, MatrixS **arg1, Vertex **arg2) { } } -GLOBAL_ASM("asm/non_matchings/particles/func_800B3740.s") +void func_800B3740(Particle *particle, Gfx **dlist, MatrixS **mtx, Vertex **vtx, s32 flags) { + s32 renderFlags; + s32 alpha; + s32 temp; + unk800B0698_44 *sp30; + Vertex *tempvtx; + + renderFlags = (RENDER_FOG_ACTIVE | RENDER_Z_COMPARE); + + if ((particle->segment.unk40 & flags) && (D_800E2CDC < 0x200)) { + return; + } + alpha = (particle->unk5C >> 8) & 0xFF; + if(alpha <= 0) { + return; + } + if ((particle->segment.object.unk2C != 4) && (particle->segment.object.unk2C != 3)) { + gDPSetEnvColor((*dlist)++, particle->colour.r, particle->colour.g, particle->colour.b, particle->colour.a); + if (alpha != 255) { + renderFlags = (RENDER_Z_UPDATE | RENDER_FOG_ACTIVE | RENDER_SEMI_TRANSPARENT | RENDER_Z_COMPARE); + gDPSetPrimColor((*dlist)++, 0, 0, particle->unk4A, particle->unk4A, particle->unk4A, alpha); + } else { + gDPSetPrimColor((*dlist)++, 0, 0, 255, 255, 255, 255); + } + if (particle->segment.object.unk2C == 0x80) { + temp = particle->segment.unk18; + particle->segment.unk18 >>= 8; + particle->segment.unk18 = (particle->segment.unk18 * 255) / (particle->unk44->unk0); + render_sprite_billboard(dlist, mtx, vtx, (Object *) particle, (unk80068514_arg4 *) particle->unk44, renderFlags); + particle->segment.unk18 = temp; + } else { + sp30 = particle->unk44; + if (sp30->unk0Ptr != 0) { + camera_push_model_mtx(dlist, mtx, &particle->segment.trans, 1.0f, 0.0f); + load_and_set_texture(dlist, (TextureHeader *) sp30->unk0Ptr, renderFlags, particle->segment.unk18 << 8); + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unk8), sp30->unk0struct.unk4, 0); + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unkC), sp30->unk0struct.unk6, 1); + func_80069A40(dlist); + } + } + if ((alpha != 255) || (particle->unk4A != 255)) { + gDPSetPrimColor((*dlist)++, 0, 0, 255, 255, 255, 255); + } + if (particle->colour.a != 0) { + gDPSetEnvColor((*dlist)++, 255, 255, 255, 0); + } + } else { + renderFlags = (RENDER_VTX_ALPHA | RENDER_Z_UPDATE | RENDER_FOG_ACTIVE | RENDER_Z_COMPARE | RENDER_ANTI_ALIASING); + gDPSetEnvColor((*dlist)++, 255, 255, 255, 0); + if (particle->segment.object.unk2C == 4) { + if (particle->segment.camera.unk3A > 0) { + gDPSetPrimColor((*dlist)++, 0, 0, particle->unk4A, particle->unk4A, particle->unk4A, 255); + if (particle->unk77 == 0) { + func_800B3E64(particle); + } + sp30 = (unk800B0698_44 *) particle->unk44_0; + temp = particle->unk75; + temp <<= 3; + tempvtx = &sp30->unk0struct.unk8[temp]; + load_and_set_texture(dlist, (TextureHeader *) sp30->unk0Ptr, renderFlags, particle->segment.unk18 << 8); + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(tempvtx), sp30->unk0struct.unk4, 0); + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unkC), sp30->unk0struct.unk6, 1); + if (particle->unk4A != 255) { + gDPSetPrimColor((*dlist)++, 0, 0, 255, 255, 255, 255); + } + } + } else if (particle->segment.object.unk2C == 3) { + gDPSetPrimColor((*dlist)++, 0, 0, particle->unk4A, particle->unk4A, particle->unk4A, alpha); + if (particle->unk68b >= 2) { + sp30 = (unk800B0698_44 *) particle->unk44_0; + load_and_set_texture(dlist, (TextureHeader *) sp30->unk0Ptr, renderFlags, particle->segment.unk18 << 8); + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unk8), sp30->unk0struct.unk4, 0); + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unkC), sp30->unk0struct.unk6, 1); + } else if (particle->unk68b > 0) { + sp30 = (unk800B0698_44 *) particle->unk44_0; + load_and_set_texture(dlist, (TextureHeader *) sp30->unk0Ptr, renderFlags, particle->segment.unk18 << 8); + gSPVertexDKR((*dlist)++, OS_K0_TO_PHYSICAL(sp30->unk0struct.unk8), 4, 0); + gSPPolygon((*dlist)++, OS_K0_TO_PHYSICAL(&sp30->unk0struct.unkC[sp30->unk0struct.unk6]), 1, 1); + } + if ((alpha != 255) || (particle->unk4A != 255)) { + gDPSetPrimColor((*dlist)++, 0, 0, 255, 255, 255, 255); + } + } + } +} + + GLOBAL_ASM("asm/non_matchings/particles/func_800B3E64.s") UNUSED unk800E2CF0 *func_800B4488(s32 idx) { diff --git a/src/particles.h b/src/particles.h index 6be99579..c1cfb1dd 100644 --- a/src/particles.h +++ b/src/particles.h @@ -199,6 +199,7 @@ void func_800AFE5C(Particle *arg0, Particle *arg1); Particle *func_800B1130(Particle *arg0, Particle *arg1); void func_800AF52C(Object *obj, s32 arg1); void func_800AF134(Particle *arg0, s32 arg1, s32 arg2, s16 arg3, s16 arg4, s16 arg5); +void func_800B3740(Particle *particle, Gfx **dlist, MatrixS **mtx, Vertex **vtx, s32 flags); void func_800AF404(s32 arg0); // Non Matching void func_800AFC3C(Object *, s32); // Non Matching @@ -211,8 +212,8 @@ void func_800B3240(Particle *); void func_800B3358(Particle *); void func_800B34B0(Particle *); void func_800B3564(Particle *); -void func_800B3740(Particle *, Gfx **, MatrixS **, Vertex **, s32); // Non Matching void func_800B4668(Object*, s32, s32, s32); void func_800B46BC(Object*, s32, s32, s32); +void func_800B3E64(Object *); // Non Matching #endif diff --git a/src/save_data.c b/src/save_data.c index 73f2ce70..30511168 100644 --- a/src/save_data.c +++ b/src/save_data.c @@ -10,6 +10,7 @@ #include "camera.h" #include "objects.h" #include "game.h" +#include "thread3_main.h" #include "unknown_0CEC50.h" #include "controller.h" diff --git a/src/textures_sprites.c b/src/textures_sprites.c index 794c2aed..113d40d6 100644 --- a/src/textures_sprites.c +++ b/src/textures_sprites.c @@ -281,9 +281,9 @@ Sprite *gCurrentSprite; s32 D_80126354; s32 D_80126358; s32 D_8012635C; -s32 D_80126360; -s32 D_80126364; -s32 D_80126368; +Vertex *D_80126360; +Gfx *D_80126364; +Triangle *D_80126368; TempTexHeader *gTempTextureHeader; u8 *D_80126370; @@ -553,26 +553,18 @@ void func_8007B454(void) { gForceFlags = TRUE; } -typedef struct Struct_Unk_8007B46C { - u8 pad0[0x12]; - u16 unk12; - u8 pad14[2]; - s16 unk16; - u8 pad17[3]; -} Struct_Unk_8007B46C; - /** * Official Name: texFrame */ -Struct_Unk_8007B46C *func_8007B46C(Struct_Unk_8007B46C *arg0, s32 arg1) { +TextureHeader *func_8007B46C(TextureHeader *texHead, s32 arg1) { if (arg1 > 0) { - if (arg1 < arg0->unk12 << 8) { - arg0 = (Struct_Unk_8007B46C *) (((u8*)arg0) + ((arg1 >> 16) * arg0->unk16)); + if (arg1 < texHead->numOfTextures << 8) { + texHead = (TextureHeader *) (((u8 *)texHead) + ((arg1 >> 16) * texHead->textureSize)); } else { - arg0 = (Struct_Unk_8007B46C *) (((u8*)arg0) + ((arg0->unk12 >> 8) - 1) * arg0->unk16); + texHead = (TextureHeader *) (((u8 *)texHead) + ((texHead->numOfTextures >> 8) - 1) * texHead->textureSize); } } - return arg0; + return texHead; } /** @@ -975,10 +967,136 @@ void free_sprite(Sprite *sprite) { GLOBAL_ASM("asm/non_matchings/textures_sprites/free_sprite.s") #endif +#ifdef NON_MATCHING +void func_8007CDC0(Sprite *sprite1, Sprite *sprite2, s32 arg2) { + UNUSED s32 pad[2]; + s32 sprUnk4; + s32 sprUnk6; + s32 y0; + s32 x0; + s32 x1; + s32 y1; + s32 xTemp; + s32 yTemp; + s32 left; + s32 var_t5; + s32 curVertIndex; + s32 j; + s32 texWidth; + s32 texHeight; + s32 i; + Vertex *vertices; + Vertex *curVerts; + Triangle *triangles; + u8 *temp_a3; + Gfx *dlptr; + TextureHeader *tex; + + temp_a3 = &sprite1->unkC.val[arg2]; + sprUnk4 = sprite1->numberOfInstances; + sprUnk6 = sprite1->unk6; + i = temp_a3[0]; + j = temp_a3[1]; + dlptr = D_80126364; + vertices = D_80126360; + triangles = D_80126368; + if (i < j) { + tex = sprite2->frames[i]; + sprite2->unk6 = ((tex->flags & 0xFFFF) & 0x3B); + } + curVertIndex = 0; + var_t5 = 0; + while (i < j) { + tex = sprite2->frames[i]; + texWidth = tex->width; + texHeight = tex->height; + xTemp = (tex->unk3 - sprUnk4); + x0 = xTemp; + x1 = (xTemp + texWidth) - 1; + yTemp = (sprUnk6 - tex->unk4); + y0 = yTemp - 1; + y1 = (yTemp - texHeight); + curVerts = vertices; + vertices[0].x = x0; + vertices[0].y = y0; + vertices[0].z = 0; + vertices[0].r = 255; + vertices[0].g = 255; + vertices[0].b = 255; + vertices[0].a = 255; + vertices[1].x = x1; + vertices[1].y = y0; + vertices[1].z = 0; + vertices[1].r = 255; + vertices[1].g = 255; + vertices[1].b = 255; + vertices[1].a = 255; + vertices[2].x = x1; + vertices[2].y = y1; + vertices[2].z = 0; + vertices[2].r = 255; + vertices[2].g = 255; + vertices[2].b = 255; + vertices[2].a = 255; + vertices[3].x = x0; + vertices[3].y = y1; + vertices[3].z = 0; + vertices[3].r = 255; + vertices[3].g = 255; + vertices[3].b = 255; + vertices[3].a = 255; + vertices += 4; + gDkrDmaDisplayList(dlptr++, OS_K0_TO_PHYSICAL(tex->cmd), tex->numberOfCommands); + if (var_t5 == 0) { + left = j - i; + if (left >= 6) { + left = 5; + } + gSPVertexDKR(dlptr++, OS_K0_TO_PHYSICAL(curVerts), (left * 4), 1); + } + gSPPolygon(dlptr++, OS_K0_TO_PHYSICAL(triangles), 2, 1); + triangles[0].flags = 0x40; + triangles[0].vi0 = curVertIndex + 3; + triangles[0].vi1 = curVertIndex + 2; + triangles[0].vi2 = curVertIndex + 1; + triangles[0].uv0.u = (texWidth - 1) << 5; + triangles[0].uv0.v = (texHeight - 1) << 5; + triangles[0].uv1.u = (texWidth - 1) << 5; + triangles[0].uv1.v = 0; + triangles[0].uv2.u = 1; + triangles[0].uv2.v = 0; + triangles[1].flags = 0x40; + triangles[1].vi0 = curVertIndex + 4; + triangles[1].vi1 = curVertIndex + 3; + triangles[1].vi2 = curVertIndex + 1; + triangles[1].uv0.u = 1; + triangles[1].uv0.v = (texHeight - 1) << 5; + triangles[1].uv1.u = (texWidth - 1) << 5; + triangles[1].uv1.v = (texHeight - 1) << 5; + triangles[1].uv2.u = 1; + triangles[1].uv2.v = 0; + triangles += 2; + curVertIndex += 4; + var_t5 += 1; + i += 1; + if (var_t5 >= 5) { + var_t5 = 0; + curVertIndex = 0; + } + } + gDPPipeSync(dlptr++); + gSPEndDisplayList(dlptr++); + D_80126364 = dlptr; + D_80126360 = vertices; + D_80126368 = triangles; +} +#else GLOBAL_ASM("asm/non_matchings/textures_sprites/func_8007CDC0.s") +#endif #ifdef NON_EQUIVALENT //HEAVILY WIP +//Alternative attempt: https://decomp.me/scratch/TbR8j void build_tex_display_list(TextureHeader *tex, Gfx *dlist) { s32 texFlags; s32 cms; diff --git a/src/textures_sprites.h b/src/textures_sprites.h index e3596a1a..8ffc9141 100644 --- a/src/textures_sprites.h +++ b/src/textures_sprites.h @@ -153,6 +153,7 @@ void tex_animate_texture(TextureHeader *texture, u32 *triangleBatchInfoFlags, s3 void func_8007F1E8(unk8007F1E8 *arg0); void init_pulsating_light_data(PulsatingLightData *data); void update_pulsating_light_data(PulsatingLightData *data, s32 timeDelta); +TextureHeader *func_8007B46C(TextureHeader *arg0, s32 arg1); TextureHeader *load_texture(s32 arg0); // Non Matching void free_texture(TextureHeader *tex); // Non Matching @@ -168,6 +169,7 @@ MemoryPoolSlot *func_8007C12C(s32 spriteID, s32 arg1); // Non Matching void tex_init_textures(void); // Non Matching void func_8007BF34(Gfx **dlist, s32 arg1); // Non Matching void load_blinking_lights_texture(Gfx **dlist, TextureHeader *arg1, u32 flags, s32 arg3); // Non Matching -void build_tex_display_list(TextureHeader *tex, Gfx *dlist); //Non Matching +void build_tex_display_list(TextureHeader *tex, Gfx *dlist); // Non Matching +void func_8007CDC0(Sprite *sprite1, Sprite *sprite2, s32 arg2); // Non Matching #endif diff --git a/src/thread3_main.c b/src/thread3_main.c new file mode 100644 index 00000000..31249b58 --- /dev/null +++ b/src/thread3_main.c @@ -0,0 +1,1561 @@ +/* The comment below is needed for this file to be picked up by generate_ld */ +/* RAM_POS: 0x8006C330 */ + +#include "thread3_main.h" + +#include +#include +#include +#include "memory.h" +#include "types.h" +#include "macros.h" +#include "structs.h" +#include "f3ddkr.h" +#include "asset_enums.h" +#include "asset_loading.h" +#include "menu.h" +#include "video.h" +#include "set_rsp_segment.h" +#include "gzip.h" +#include "printf.h" +#include "thread0_epc.h" +#include "thread30_track_loading.h" +#include "weather.h" +#include "audio.h" +#include "objects.h" +#include "camera.h" +#include "save_data.h" +#include "unknown_078050.h" +#include "audiosfx.h" +#include "audiomgr.h" +#include "unknown_032760.h" +#include "textures_sprites.h" +#include "PR/os_internal.h" +#include "printf.h" +#include "fade_transition.h" +#include "borders.h" +#include "unknown_008C40.h" +#include "unknown_0255E0.h" +#include "game_text.h" +#include "game_ui.h" +#include "main.h" +#include "object_models.h" +#include "racer.h" +#include "particles.h" +#include "math_util.h" +#include "controller.h" + +/************ .rodata ************/ + +UNUSED const char sLevelErrorString[] = "LOADLEVEL Error: Level out of range\n"; +UNUSED const char sBossErrorString[] = "BossLev problem\n"; +UNUSED const char sAITableErrorString[] = "AITABLE Error: Table out of range\n"; +UNUSED const char sDebugVersionInfoString[] = "1.1605"; +UNUSED const char sDebugBuildDateString[] = "02/10/97 16:03"; +UNUSED const char sDebugUsernameString[] = "pmountain"; + +const char D_800E7134[] = "BBB\n"; // Functionally unused. +UNUSED const char sDebugCarString[] = "CAR"; +UNUSED const char sDebugHovercraftString[] = "HOV"; +UNUSED const char sDebugPlaneString[] = "PLN"; +UNUSED const char sDebugVehicleSwapString[] = "Swapping\n"; + +/*********************************/ + +/************ .data ************/ + +UNUSED char *sDebugRomBuildInfo[3] = { + (char *)sDebugVersionInfoString, + (char *)sDebugBuildDateString, + (char *)sDebugUsernameString +}; + +UNUSED char gBuildString[40] = "Version 7.7 29/09/97 15.00 L.Schuneman"; + +s8 sAntiPiracyTriggered = 0; +UNUSED s32 D_800DD378 = 1; +s32 gSaveDataFlags = 0; //Official Name: load_save_flags +s32 gScreenStatus = OSMESG_SWAP_BUFFER; +s32 sControllerStatus = 0; +UNUSED s32 D_800DD388 = 0; +s8 gSkipGfxTask = FALSE; +s8 D_800DD390 = 0; +s16 gLevelLoadTimer = 0; +s8 D_800DD398 = 0; +s8 gFutureFunLandLevelTarget = FALSE; +s8 gDmemInvalid = FALSE; +UNUSED s32 D_800DD3A4 = 0; +UNUSED s32 D_800DD3A8 = 0; +UNUSED s32 D_800DD3AC = 0; +s32 gNumF3dCmdsPerPlayer[4] = { 4500, 7000, 11000, 11000 }; +s32 gNumHudVertsPerPlayer[4] = { 300, 600, 850, 900 }; +s32 gNumHudMatPerPlayer[4] = { 300, 400, 550, 600 }; +s32 gNumHudTrisPerPlayer[4] = { 20, 30, 40, 50 }; +s8 gDrawFrameTimer = 0; +FadeTransition D_800DD3F4 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_UNK2, FADE_COLOR_BLACK, 20, 0); +UNUSED FadeTransition D_800DD3FC = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_WHITE, 20, -1); +s32 sLogicUpdateRate = LOGIC_5FPS; +FadeTransition D_800DD408 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_WHITE, 30, -1); +UNUSED char *D_800DD410[3] = { + (char *)sDebugCarString, (char *)sDebugHovercraftString, (char *)sDebugPlaneString +}; +FadeTransition gLevelFadeOutTransition = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_BLACK, 30, -1); +FadeTransition D_800DD424 = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_NONE, FADE_COLOR_BLACK, 260, -1); + +/*******************************/ + +/************ .bss ************/ + +Gfx *gDisplayLists[2]; +Gfx *gCurrDisplayList; +UNUSED s32 D_801211FC; +MatrixS *gMatrixHeap[2]; +MatrixS *gGameCurrMatrix; +Vertex *gVertexHeap[2]; +Vertex *gGameCurrVertexList; +TriangleList *gTriangleHeap[2]; +TriangleList *gGameCurrTriList; +UNUSED s32 D_80121230[8]; +s8 D_80121250[16]; //Settings4C +OSSched gMainSched; // 0x288 / 648 bytes +u64 gSchedStack[0x400]; +s32 gSPTaskNum; +s32 sRenderContext; +s32 gRenderMenu; // I don't think this is ever not 1 +// Similar to gMapId, but is 0 if not currently playing a level (e.g. start menu). +s32 gPlayableMapId; +s32 D_801234F8; +s32 D_801234FC; +s32 gGameNumPlayers; +s32 gGameCurrentEntrance; +s32 gGameCurrentCutscene; +s32 gPrevPlayerCount; +Settings *gSettingsPtr; +s8 gIsLoading; +s8 gIsPaused; +s8 gPostRaceViewPort; +Vehicle gLevelDefaultVehicleID; +Vehicle D_8012351C; // Looks to be the current level's vehicle ID. +s32 sBootDelayTimer; +s8 gLevelLoadType; +s8 gNextMap; +UNUSED s8 D_80123526; // Set to 0 then never used. +s32 gCurrNumF3dCmdsPerPlayer; +s32 gCurrNumHudMatPerPlayer; +s32 gCurrNumHudTrisPerPlayer; +s32 gCurrNumHudVertsPerPlayer; +OSScClient *gNMISched[3]; +OSMesg gNMIOSMesg; +OSMesgQueue gNMIMesgQueue; +s32 gNMIMesgBuf; //Official Name: resetPressed +s32 D_80123568[6]; // BSS Padding + +/******************************/ + + +/** + * Main looping function for the main thread. + * Official Name: mainThread + */ +void thread3_main(UNUSED void *unused) { + init_game(); + gSaveDataFlags = handle_save_data_and_read_controller(gSaveDataFlags, 0); + sBootDelayTimer = 0; + sRenderContext = DRAW_INTRO; + while (1) { + if (is_reset_pressed()) { + func_80072708(); + audioStopThread(); + stop_thread30(); + __osSpSetStatus(SP_SET_HALT | SP_CLR_INTR_BREAK | SP_CLR_YIELD | SP_CLR_YIELDED | SP_CLR_TASKDONE | SP_CLR_RSPSIGNAL + | SP_CLR_CPUSIGNAL | SP_CLR_SIG5 | SP_CLR_SIG6 | SP_CLR_SIG7); + osDpSetStatus(DPC_SET_XBUS_DMEM_DMA | DPC_CLR_FREEZE | DPC_CLR_FLUSH | DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR + | DPC_CLR_CMD_CTR | DPC_CLR_CMD_CTR); + while (1); // Infinite loop + } + main_game_loop(); + thread3_verify_stack(); + } +} + +/** + * Setup all of the necessary pieces required for the game to function. + * This includes the memory pool. controllers, video, audio, core assets and more. + * Official Name: mainInitGame + */ +void init_game(void) { + s32 viMode; + + init_main_memory_pool(); + rzipInit(); // Initialise gzip decompression related things + sAntiPiracyTriggered = TRUE; + if (check_imem_validity()) { + sAntiPiracyTriggered = FALSE; + } + gIsLoading = FALSE; + gLevelDefaultVehicleID = VEHICLE_CAR; + + if (osTvType == TV_TYPE_PAL) { + viMode = OS_VI_PAL_LPN1; + } else if (osTvType == TV_TYPE_NTSC) { + viMode = OS_VI_NTSC_LPN1; + } else if (osTvType == TV_TYPE_MPAL) { + viMode = OS_VI_MPAL_LPN1; + } + + osCreateScheduler(&gMainSched, &gSchedStack[0x400], /*priority*/ 13, viMode, 1); + // Antipiracy measure. + gDmemInvalid = FALSE; + if (check_dmem_validity() == FALSE) { + gDmemInvalid = TRUE; + } + init_video(VIDEO_MODE_LOWRES_LPN, &gMainSched); + init_PI_mesg_queue(); + setup_gfx_mesg_queues(&gMainSched); + audio_init(&gMainSched); + func_80008040(); // Should be very similar to allocate_object_model_pools + sControllerStatus = init_controllers(); + tex_init_textures(); + allocate_object_model_pools(); + allocate_object_pools(); + diPrintfInit(); + allocate_ghost_data(); + init_particle_assets(); + init_weather(); + calc_and_alloc_heap_for_settings(); + default_alloc_displaylist_heap(); + load_fonts(); + init_controller_paks(); + func_80081218(); // init_save_data + create_and_start_thread30(); + osCreateMesgQueue(&gNMIMesgQueue, &gNMIOSMesg, 1); + osScAddClient(&gMainSched, (OSScClient*) gNMISched, &gNMIMesgQueue, OS_SC_ID_PRENMI); + gNMIMesgBuf = 0; + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0; + gSPTaskNum = 0; + + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + + osSetTime(0); +} + +/** + * The main gameplay loop. + * Contains all game logic, audio and graphics processing. + */ +void main_game_loop(void) { + s32 debugLoopCounter; + s32 framebufferSize; + s32 tempLogicUpdateRate, tempLogicUpdateRateMax; + + osSetTime(0); + + if (gScreenStatus == MESG_SKIP_BUFFER_SWAP) { + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + set_rsp_segment(&gCurrDisplayList, 0, 0); + set_rsp_segment(&gCurrDisplayList, 1, (s32) gVideoCurrFramebuffer); + set_rsp_segment(&gCurrDisplayList, 2, (s32) gVideoLastDepthBuffer); + set_rsp_segment(&gCurrDisplayList, 4, (s32) gVideoCurrFramebuffer - 0x500); + } + if (gDrawFrameTimer == 0) { + setup_ostask_xbus(gDisplayLists[gSPTaskNum], gCurrDisplayList, 0); + gSPTaskNum += 1; + gSPTaskNum &= 1; + } + if (gDrawFrameTimer) { + gDrawFrameTimer--; + } + + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gGameCurrMatrix = gMatrixHeap[gSPTaskNum]; + gGameCurrVertexList = gVertexHeap[gSPTaskNum]; + gGameCurrTriList = gTriangleHeap[gSPTaskNum]; + + set_rsp_segment(&gCurrDisplayList, 0, 0); + set_rsp_segment(&gCurrDisplayList, 1, (s32) gVideoLastFramebuffer); + set_rsp_segment(&gCurrDisplayList, 2, (s32) gVideoLastDepthBuffer); + set_rsp_segment(&gCurrDisplayList, 4, (s32) gVideoLastFramebuffer - 0x500); + init_rsp(&gCurrDisplayList); + init_rdp_and_framebuffer(&gCurrDisplayList); + render_background(&gCurrDisplayList, (Matrix *) &gGameCurrMatrix, TRUE); + gSaveDataFlags = handle_save_data_and_read_controller(gSaveDataFlags, sLogicUpdateRate); + if (get_lockup_status()) { + render_epc_lock_up_display(); + sRenderContext = DRAW_CRASH_SCREEN; + } + if (gDmemInvalid) { + debugLoopCounter = 0; + while (debugLoopCounter != 10000000) { + debugLoopCounter++; + } + if (debugLoopCounter > 20000000) { // This shouldn't ever be true? + render_printf(D_800E7134 /* "BBB\n" */); + } + } + + switch (sRenderContext) { + case DRAW_INTRO: // Pre-boot screen + pre_intro_loop(); + break; + case DRAW_MENU: // In a menu + func_8006DCF8(sLogicUpdateRate); + break; + case DRAW_GAME: // In game (Controlling a character) + ingame_logic_loop(sLogicUpdateRate); + break; + case DRAW_CRASH_SCREEN: // EPC (lockup display) + lockup_screen_loop(sLogicUpdateRate); + break; + } + + // This is a good spot to place custom text if you want it to overlay it over ALL the + // menus & gameplay. + + handle_music_fade(sLogicUpdateRate); + print_debug_strings(&gCurrDisplayList); + render_dialogue_boxes(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList); + close_dialogue_box(4); + assign_dialogue_box_id(4); + // handle_transitions will perform the logic of transitions and return the transition ID. + if (handle_transitions(sLogicUpdateRate)) { + render_fade_transition(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList); + } + if ((sBootDelayTimer >= 8) && (is_controller_missing())) { + print_missing_controller_text(&gCurrDisplayList, sLogicUpdateRate); + } + + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + + copy_viewports_to_stack(); + if (gDrawFrameTimer != 1) { + if (gSkipGfxTask == FALSE) { + gScreenStatus = wait_for_gfx_task(); + } + } else { + gDrawFrameTimer = 0; + } + gSkipGfxTask = FALSE; + clear_free_queue(); + if (!gIsPaused) { + disable_cutscene_camera(); + } + if (gDrawFrameTimer == 2) { + framebufferSize = SCREEN_WIDTH * SCREEN_HEIGHT * 2; + if (osTvType == TV_TYPE_PAL) { + framebufferSize = (s32)((SCREEN_WIDTH * SCREEN_HEIGHT * 2) * 1.1f); + } + dmacopy_doubleword(gVideoLastFramebuffer, gVideoCurrFramebuffer, (s32) gVideoCurrFramebuffer + framebufferSize); + } + // tempLogicUpdateRate will be set to a value 2 or higher, based on the framerate. + // the mul factor is hardcapped at 6, which happens at 10FPS. The mul factor + // affects frameskipping, to maintain consistent game speed, through the (many) + // dropped frames in DKR. + tempLogicUpdateRate = swap_framebuffer_when_ready(gScreenStatus); + sLogicUpdateRate = tempLogicUpdateRate; + tempLogicUpdateRateMax = LOGIC_10FPS; + if (tempLogicUpdateRate > tempLogicUpdateRateMax) { + sLogicUpdateRate = tempLogicUpdateRateMax; + } +} + +void func_8006CAE4(s32 numPlayers, s32 trackID, Vehicle vehicle) { + gGameNumPlayers = numPlayers - 1; + if (trackID == -1) { + gPlayableMapId = get_track_id_to_load(); + } else { + gPlayableMapId = trackID; // Unused, because arg1 is always -1. + } + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, vehicle); +} + +/** + * Calls load_level() with the same arguments except for the cutsceneId, + * which is the value at gGameCurrentCutscene. Also does some other stuff. + * Used when ingame. + */ +void load_level_game(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId) { + alloc_displaylist_heap(numberOfPlayers); + set_free_queue_state(0); + func_80065EA0(); + func_800C3048(); + load_level(levelId, numberOfPlayers, entranceId, vehicleId, gGameCurrentCutscene); + func_8009ECF0(get_viewport_count()); + func_800AE728(8, 0x10, 0x96, 0x64, 0x32, 0); + func_8001BF20(); + osSetTime(0); + set_free_queue_state(2); + func_80072298(1); +} + +/** + * Call numerous functions to clear data in RAM. + * Then call to free particles, HUD and text. + * Waits for a GFX task before unloading. +*/ +void unload_level_game(void) { + set_free_queue_state(0); + if (gSkipGfxTask == FALSE) { + if (gDrawFrameTimer != 1) { + wait_for_gfx_task(); + } + gSkipGfxTask = TRUE; + } + clear_audio_and_track(); + transition_begin(&D_800DD3F4); + func_800AE270(); + func_800A003C(); + func_800C30CC(); + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + set_free_queue_state(2); +} + +/** + * The main behaviour function involving all of the ingame stuff. + * Involves the updating of all objects and setting up the render scene. +*/ +void ingame_logic_loop(s32 updateRate) { + s32 buttonPressedInputs, buttonHeldInputs, i, sp40, sp3C; + + sp40 = 0; + buttonHeldInputs = 0; + buttonPressedInputs = 0; + + // Get input data for all 4 players. + for (i = 0; i < get_active_player_count(); i++) { + buttonHeldInputs |= get_buttons_held_from_player(i); + buttonPressedInputs |= get_buttons_pressed_from_player(i); + } + // Spam the start button, making the game unplayable because it's constantly paused. + if (sAntiPiracyTriggered) { + buttonPressedInputs |= START_BUTTON; + } + // Update all objects + if (!gIsPaused) { + func_80010994(updateRate); + if (check_if_showing_cutscene_camera() == 0 || func_8001139C()) { + if ((buttonPressedInputs & START_BUTTON) && (get_level_property_stack_pos() == 0) && (D_800DD390 == 0) + && (sRenderContext == DRAW_GAME) && (gPostRaceViewPort == NULL) && (gLevelLoadTimer == 0) && (D_800DD398 == 0)) { + buttonPressedInputs = 0; + gIsPaused = TRUE; + func_80093A40(); + } + } + } else { + set_anti_aliasing(TRUE); + } + D_800DD398 -= updateRate; + if (D_800DD398 < 0) { + D_800DD398 = 0; + } + if (gPostRaceViewPort) { + gIsPaused = FALSE; + } + gParticlePtrList_flush(); + func_8001BF20(); + render_scene(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); + if (sRenderContext == DRAW_GAME) { + // Ignore the user's L/R/Z buttons. + buttonHeldInputs &= ~(L_TRIG | R_TRIG | Z_TRIG); + } + if (gPostRaceViewPort) { + i = func_80095728(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, updateRate); + switch (i) { + case 2: + buttonHeldInputs |= (L_TRIG | Z_TRIG); + break; + case 1: + gPostRaceViewPort = NULL; + func_8006D8F0(-1); + break; + case 4: + clear_level_property_stack(); + D_800DD390 = 0; + buttonHeldInputs |= (L_TRIG | R_TRIG); + break; + case 5: + buttonHeldInputs |= L_TRIG, + sp40 = 1; + break; + case 8: + buttonHeldInputs |= L_TRIG, + sp40 = 2; + break; + case 9: + buttonHeldInputs |= L_TRIG, + sp40 = 3; + break; + case 10: + buttonHeldInputs |= L_TRIG, + sp40 = 4; + break; + case 11: + buttonHeldInputs |= L_TRIG, + sp40 = 5; + break; + case 12: + buttonHeldInputs |= L_TRIG, + sp40 = 6; + break; + case 13: + buttonHeldInputs |= L_TRIG, + sp40 = 7; + break; + } + } + func_800C3440(updateRate); + i = func_800C3400(); + if (i != 0) { + if (i == 2) { + gIsPaused = TRUE; + } + if (func_800C3400() != 2) { + gIsPaused = FALSE; + n_alSeqpDelete(); + } + } + if (gIsPaused) { + i = render_pause_menu(&gCurrDisplayList, updateRate); + switch (i - 1) { + case 0: + gIsPaused = FALSE; + break; + case 1: + func_80001050(); + func_800C314C(); + if (func_80023568() != 0 && is_in_two_player_adventure()) { + func_8006F398(); + } + buttonHeldInputs |= (L_TRIG | Z_TRIG); + break; + case 2: + func_80001050(); + func_800C314C(); + if (func_80023568() != 0 && is_in_two_player_adventure()) { + func_8006F398(); + } + buttonHeldInputs |= L_TRIG; + break; + case 4: + sp40 = 1; + func_800C314C(); + buttonHeldInputs |= L_TRIG; + break; + case 11: + sp40 = 6; + func_800C314C(); + buttonHeldInputs |= L_TRIG; + break; + case 5: + gIsPaused = FALSE; + break; + case 6: + func_80022E18(1); + gIsPaused = FALSE; + break; + case 3: + D_800DD390 = 0; + func_80001050(); + func_800C314C(); + clear_level_property_stack(); + buttonHeldInputs |= (L_TRIG | R_TRIG); + break; + } + } + init_rdp_and_framebuffer(&gCurrDisplayList); + render_borders_for_multiplayer(&gCurrDisplayList); + render_minimap_and_misc_hud(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, updateRate); + render_second_multiplayer_borders(&gCurrDisplayList); + if (gFutureFunLandLevelTarget) { + if (func_800214C4() != 0) { + gPlayableMapId = ASSET_LEVEL_FUTUREFUNLANDHUB; + D_801234F8 = 1; + gGameCurrentEntrance = 0; + gFutureFunLandLevelTarget = FALSE; + } + } + sp3C = FALSE; + if (D_800DD390 != 0) { + D_800DD390 -= updateRate; + if (D_800DD390 <= 0) { + D_800DD390 = 0; + push_level_property_stack(ASSET_LEVEL_CENTRALAREAHUB, 0, VEHICLE_CAR, CUTSCENE_ID_NONE); + push_level_property_stack(ASSET_LEVEL_WIZPIGAMULETSEQUENCE, 0, -1, CUTSCENE_ID_UNK_A); + sp3C = TRUE; + } + } + if (gLevelLoadTimer > 0) { + gLevelLoadTimer -= updateRate; + if (gLevelLoadTimer <= 0) { + buttonHeldInputs = L_TRIG; + sp3C = TRUE; + switch (gLevelLoadType) { + case LEVEL_LOAD_UNK1: + buttonHeldInputs = (L_TRIG | Z_TRIG); + break; + case LEVEL_LOAD_TROPHY_RACE: + sp40 = 3; + func_80098208(); + D_801234FC = 2; + break; + case LEVEL_LOAD_LIGHTHOUSE_CUTSCENE: + gFutureFunLandLevelTarget = TRUE; + // fall-through + case LEVEL_LOAD_FUTURE_FUN_LAND: + D_801234F8 = 1; + gPlayableMapId = gNextMap; + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0; + buttonHeldInputs = 0; + break; + } + gLevelLoadType = LEVEL_LOAD_NORMAL; + gLevelLoadTimer = 0; + } + } + if (sp3C) { + if (get_level_property_stack_pos() != 0) { + pop_level_property_stack(&gPlayableMapId, &gGameCurrentEntrance, &i, &gGameCurrentCutscene); + set_frame_blackout_timer(); + if (gPlayableMapId < 0) { + if (gPlayableMapId == (s32)SPECIAL_MAP_ID_NO_LEVEL || gPlayableMapId == (s32)SPECIAL_MAP_ID_UNK_NEG10) { + if (gPlayableMapId == (s32)SPECIAL_MAP_ID_UNK_NEG10 && is_in_two_player_adventure()) { + func_8006F398(); + } + buttonHeldInputs |= L_TRIG; + D_801234FC = 2; + } else { + buttonHeldInputs = 0; + D_801234FC = 1; + sp40 = 8; + } + } else { + D_801234FC = 0; + D_801234F8 = 1; + buttonHeldInputs = 0; + } + } + } else { + sp3C = func_8006C300(); + if (get_level_property_stack_pos()) { + if (gLevelLoadTimer == 0) { + i = func_800214C4(); + if ((i != 0) || ((buttonPressedInputs & A_BUTTON) && (sp3C != 0))) { + if (sp3C != 0) { + func_80000B28(); + } + set_frame_blackout_timer(); + pop_level_property_stack(&gPlayableMapId, &gGameCurrentEntrance, &i, &gGameCurrentCutscene); + if (gPlayableMapId < 0) { + if (gPlayableMapId == -1 || gPlayableMapId == -10) { + if (gPlayableMapId == -10 && is_in_two_player_adventure()) { + func_8006F398(); + } + buttonHeldInputs |= L_TRIG; + D_801234FC = 2; + } else { + buttonHeldInputs = 0; + D_801234FC = 1; + sp40 = 8; + } + } else { + D_801234F8 = 1; + } + } + } + } + } + if (((buttonHeldInputs & L_TRIG) && (sRenderContext == DRAW_GAME)) || (D_801234FC != 0)) { + gIsPaused = FALSE; + gLevelLoadTimer = 0; + gPostRaceViewPort = NULL; + unload_level_game(); + safe_mark_write_save_file(get_save_file_index()); + if (sp40 != 0) { + gIsLoading = FALSE; + switch (sp40) { + case 1: + // Go to track select menu from "Select Track" option in tracks menu. + load_menu_with_level_background(MENU_TRACK_SELECT, -1, 1); + break; + case 2: + load_menu_with_level_background(MENU_RESULTS, 0x22, 0); + break; + case 3: + load_menu_with_level_background(MENU_TROPHY_RACE_ROUND, 0x22, 0); + break; + case 4: + load_menu_with_level_background(MENU_TROPHY_RACE_RANKINGS, 0x22, 0); + break; + case 5: + // Trophy race related? + load_menu_with_level_background(MENU_UNUSED_22, 0x22, 0); + break; + case 6: + // Go to character select menu from "Select Character" option in tracks menu. + i = 0; + if (is_drumstick_unlocked()) { + i ^= 1; + } + if (is_tt_unlocked()) { + i ^= 3; + } + func_8008AEB4(1, 0); + load_menu_with_level_background(MENU_CHARACTER_SELECT, 0x16, i); + break; + case 7: + gIsLoading = TRUE; + load_menu_with_level_background(MENU_UNKNOWN_23, -1, 0); + gIsLoading = FALSE; + break; + case 8: + load_menu_with_level_background(MENU_CREDITS, -1, 0); + break; + } + } else if (D_801234FC == 1) { + if (D_80121250[2] == -1) { + load_menu_with_level_background(MENU_UNUSED_8, -1, 0); + } else { + gIsLoading = TRUE; + load_menu_with_level_background(MENU_TRACK_SELECT_ADVENTURE, -1, -1); + } + } else if (!(buttonHeldInputs & R_TRIG)) { + if (!(buttonHeldInputs & Z_TRIG)) { + gPlayableMapId = D_80121250[0]; + gGameCurrentEntrance = D_80121250[15]; + gGameCurrentCutscene = D_80121250[D_80121250[1] + 8]; + gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); + if (gGameCurrentCutscene < 0) { + gGameCurrentCutscene = 0x64; + } + } + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + } else { + safe_mark_write_save_file(get_save_file_index()); + load_menu_with_level_background(MENU_TITLE, -1, 0); + } + D_801234FC = 0; + } + if (D_801234F8 != 0) { + gPostRaceViewPort = NULL; + unload_level_game(); + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + safe_mark_write_save_file(get_save_file_index()); + D_801234F8 = 0; + } +} + +void func_8006D8A4(void) { + D_800DD390 = 0x2C; + gIsPaused = 0; + n_alSeqpDelete(); + transition_begin(&D_800DD408); +} + +void func_8006D8E0(s32 arg0) { + gPostRaceViewPort = arg0 + 1; +} + +void func_8006D8F0(UNUSED s32 arg0) { + s32 temp; + if (sRenderContext != DRAW_UNK_04) { + gPlayableMapId = D_80121250[0]; + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0x64; + temp = D_80121250[1]; + if (D_80121250[15] >= 0) { + gGameCurrentEntrance = D_80121250[15]; + } + if (D_80121250[temp + 8] >= 0) { + gGameCurrentCutscene = D_80121250[temp + 8]; + } + D_801234F8 = 1; + } +} + +void func_8006D968(s8 *arg0) { + s32 i; + if (sRenderContext != DRAW_UNK_04) { + D_80121250[0] = gPlayableMapId; + for (i = 0; i < 2; i++) { + D_80121250[i + 2] = arg0[i + 8]; + D_80121250[i + 4] = arg0[i + 10]; + D_80121250[i + 6] = arg0[i + 12]; + D_80121250[i + 8] = arg0[i + 14]; + D_80121250[i + 10] = arg0[i + 18]; + D_80121250[i + 12] = arg0[i + 20]; + } + D_80121250[14] = arg0[22]; + D_80121250[15] = arg0[23]; + D_801234FC = 1; + } +} + +/** + * Gets the render context from outside this file + */ +RenderContext get_render_context(void) { + return sRenderContext; +} + +/** + * Unused function used to set the render context from outside this file + * Official Name: mainSetMode? + */ +UNUSED void set_render_context(s32 changeTo) { + sRenderContext = changeTo; +} + +/** + * Sets up and loads a level to be used in the background of the menu that's about to be set up. + * Used for every kind of menu that's not ingame. +*/ +void load_menu_with_level_background(s32 menuId, s32 levelId, s32 cutsceneId) { + alloc_displaylist_heap(PLAYER_ONE); + sRenderContext = DRAW_MENU; + gRenderMenu = TRUE; + set_sound_channel_volume(0, 32767); + set_sound_channel_volume(1, 32767); + set_sound_channel_volume(2, 32767); + func_80065EA0(); + + if (!gIsLoading) { + gIsLoading = FALSE; + if (levelId < 0) { + gIsLoading = TRUE; + } else { + load_level_menu(levelId, -1, 0, VEHICLE_PLANE, cutsceneId); + } + } + if (menuId == MENU_UNUSED_2 || menuId == MENU_LOGOS || menuId == MENU_TITLE) { + reset_title_logo_scale(); + } + menu_init(menuId); + gGameCurrentEntrance = 0; +} + +/** + * Set the default vehicle option from the current loaded level. + */ +void set_level_default_vehicle(Vehicle vehicleID) { + gLevelDefaultVehicleID = vehicleID; +} + +void func_8006DB20(Vehicle vehicleId) { + D_8012351C = vehicleId; +} + +/** + * Get the default vehicle option, set by a loaded level. + */ +Vehicle get_level_default_vehicle(void) { + return gLevelDefaultVehicleID; +} + +/** + * Calls load_level() with the same arguments, but also does some other stuff. + * Used for menus. + */ +void load_level_menu(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId) { + set_free_queue_state(0); + func_80065EA0(); + func_800C3048(); + load_level(levelId, numberOfPlayers, entranceId, vehicleId, cutsceneId); + func_8009ECF0(get_viewport_count()); + func_800AE728(4, 4, 0x6E, 0x30, 0x20, 0); + func_8001BF20(); + osSetTime(0); + set_free_queue_state(2); +} + +/** + * Call numerous functions to clear data in RAM. + * Then call to free particles, HUD and text. +*/ +void unload_level_menu(void) { + if (!gIsLoading) { + gIsLoading = TRUE; + set_free_queue_state(0); + clear_audio_and_track(); + transition_begin(&D_800DD3F4); + func_800AE270(); + func_800A003C(); + func_800C30CC(); + set_free_queue_state(2); + } + gIsLoading = FALSE; +} + +/** + * Used in menus, update objects and draw the game. + * In the tracks menu, this only runs if there's a track actively loaded. +*/ +void update_menu_scene(s32 updateRate) { + if (get_thread30_level_id_to_load() == 0) { + func_80010994(updateRate); + gParticlePtrList_flush(); + func_8001BF20(); + render_scene(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); + func_800C3440(updateRate); + init_rdp_and_framebuffer(&gCurrDisplayList); + render_borders_for_multiplayer(&gCurrDisplayList); + render_second_multiplayer_borders(&gCurrDisplayList); + } +} + +#ifdef NON_EQUIVALENT +// Minor & regalloc issues. +void func_8006DCF8(s32 updateRate) { + s32 menuLoopResult, temp, temp2, tempResult; + + gIsPaused = FALSE; + gPostRaceViewPort = NULL; + if (!gIsLoading && gRenderMenu) { + update_menu_scene(updateRate); + } + menuLoopResult = menu_loop(&gCurrDisplayList, &gGameCurrMatrix, &gGameCurrVertexList, &gGameCurrTriList, updateRate); + gRenderMenu = TRUE; + if (menuLoopResult == -2) { + gRenderMenu = FALSE; + return; + } + if ((menuLoopResult != -1) && (menuLoopResult & 0x200)) { + unload_level_menu(); + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + gPlayableMapId = menuLoopResult & 0x7F; + gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0x64; + sRenderContext = DRAW_GAME; + gIsPaused = FALSE; + gPostRaceViewPort = NULL; + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + safe_mark_write_save_file(get_save_file_index()); + return; + } + if ((menuLoopResult != -1) && (menuLoopResult & 0x100)) { + unload_level_game(); + gIsPaused = FALSE; + gPostRaceViewPort = NULL; + switch (menuLoopResult & 0x7F) { + case 5: + load_menu_with_level_background(MENU_TRACK_SELECT, -1, 1); + break; + case 14: + gPlayableMapId = ASSET_LEVEL_CENTRALAREAHUB; + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0x64; + sRenderContext = DRAW_GAME; + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + safe_mark_write_save_file(get_save_file_index()); + break; + case 1: + gGameCurrentEntrance = 0; + gGameCurrentCutscene = 0x64; + gPlayableMapId = D_80121250[0]; + sRenderContext = DRAW_GAME; + // Minor issue with these 2 if statements + temp2 = D_80121250[D_80121250[1] + 8]; + temp = D_80121250[15]; + if (temp >= 0) { + gGameCurrentEntrance = temp; + } + if (temp2 >= 0) { + gGameCurrentCutscene = temp2; + } + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + safe_mark_write_save_file(get_save_file_index()); + break; + case 2: + sRenderContext = DRAW_GAME; + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + break; + case 3: + sRenderContext = DRAW_GAME; + gPlayableMapId = D_80121250[0]; + gGameCurrentEntrance = D_80121250[15]; + gGameCurrentCutscene = D_80121250[D_80121250[1] + 8]; + gLevelDefaultVehicleID = get_map_default_vehicle(gPlayableMapId); + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, gLevelDefaultVehicleID); + break; + default: + load_menu_with_level_background(MENU_TITLE, -1, 0); + break; + } + return; + } + if ((menuLoopResult & 0x80) && (menuLoopResult != -1)) { + unload_level_menu(); + // Minor issue here. + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + temp = menuLoopResult & 0x7F; + D_80121250[1] = temp; + D_80121250[0] = gPlayableMapId; + gPlayableMapId = D_80121250[temp + 2]; + gGameCurrentEntrance = D_80121250[temp + 4]; + sRenderContext = DRAW_GAME; + gGameCurrentCutscene = D_80121250[temp + 12]; + temp = get_player_selected_vehicle(0); + gGameNumPlayers = gSettingsPtr->gNumRacers - 1; + load_level_game(gPlayableMapId, gGameNumPlayers, gGameCurrentEntrance, temp); + D_801234FC = 0; + gLevelDefaultVehicleID = D_8012351C; + return; + } + if (menuLoopResult > 0) { + unload_level_menu(); + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + sRenderContext = DRAW_GAME; + func_8006CAE4(menuLoopResult, -1, gLevelDefaultVehicleID); + if (gSettingsPtr->newGame && !is_in_tracks_mode()) { + func_80000B28(); + gSettingsPtr->newGame = FALSE; + } + } +} + +#else +GLOBAL_ASM("asm/non_matchings/game/func_8006DCF8.s") +#endif + +void load_level_for_menu(s32 levelId, s32 numberOfPlayers, s32 cutsceneId) { + if (!gIsLoading) { + unload_level_menu(); + if (get_thread30_level_id_to_load() == 0) { + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); + } + } + if (levelId != (s32) SPECIAL_MAP_ID_NO_LEVEL) { + //!@bug: Forcing the plane here makes all AI use plane paths. This can be seen most evidently in the Ancient Lake demo. + load_level_menu(levelId, numberOfPlayers, 0, VEHICLE_PLANE, cutsceneId); + gIsLoading = FALSE; + return; + } + gIsLoading = TRUE; +} + +void calc_and_alloc_heap_for_settings(void) { + s32 dataSize; + u32 sizes[15]; + s32 numWorlds, numLevels; + + init_level_globals(); + reset_character_id_slots(); + get_number_of_levels_and_worlds(&numLevels, &numWorlds); + sizes[0] = sizeof(Settings); + sizes[1] = sizes[0] + (numLevels * 4); // balloonsPtr + sizes[2] = sizes[1] + (numWorlds * 2); // flapInitialsPtr[0] + dataSize = (numLevels * 2); + sizes[3] = sizes[2] + dataSize; // flapInitialsPtr[1] + sizes[4] = sizes[3] + dataSize; // flapInitialsPtr[2] + sizes[5] = sizes[4] + dataSize; // flapTimesPtr[0] + sizes[6] = sizes[5] + dataSize; // flapTimesPtr[1] + sizes[7] = sizes[6] + dataSize; // flapTimesPtr[2] + sizes[8] = sizes[7] + dataSize; // courseInitialsPtr[0] + sizes[9] = sizes[8] + dataSize; // courseInitialsPtr[1] + sizes[10] = sizes[9] + dataSize; // courseInitialsPtr[2] + sizes[11] = sizes[10] + dataSize; // courseTimesPtr[0] + sizes[12] = sizes[11] + dataSize; // courseTimesPtr[1] + sizes[13] = sizes[12] + dataSize; // courseTimesPtr[2] + sizes[14] = sizes[13] + dataSize; // total size + + gSettingsPtr = allocate_from_main_pool_safe(sizes[14], COLOUR_TAG_WHITE); + gSettingsPtr->courseFlagsPtr = (s32 *)((u8 *)gSettingsPtr + sizes[0]); + gSettingsPtr->balloonsPtr = (s16 *)((u8 *)gSettingsPtr + sizes[1]); + gSettingsPtr->tajFlags = 0; + gSettingsPtr->flapInitialsPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[2]); + gSettingsPtr->flapInitialsPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[3]); + gSettingsPtr->flapInitialsPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[4]); + gSettingsPtr->flapTimesPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[5]); + gSettingsPtr->flapTimesPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[6]); + gSettingsPtr->flapTimesPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[7]); + gSettingsPtr->courseInitialsPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[8]); + gSettingsPtr->courseInitialsPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[9]); + gSettingsPtr->courseInitialsPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[10]); + gSettingsPtr->courseTimesPtr[0] = (u16 *)((u8 *)gSettingsPtr + sizes[11]); + gSettingsPtr->courseTimesPtr[1] = (u16 *)((u8 *)gSettingsPtr + sizes[12]); + gSettingsPtr->courseTimesPtr[2] = (u16 *)((u8 *)gSettingsPtr + sizes[13]); + gSettingsPtr->unk4C = (Settings4C *) &D_80121250; + gSaveDataFlags = // Set bits 0/1/2/8 and wipe out all others + SAVE_DATA_FLAG_READ_FLAP_TIMES | + SAVE_DATA_FLAG_READ_COURSE_TIMES | + SAVE_DATA_FLAG_READ_SAVE_DATA | + SAVE_DATA_FLAG_READ_EEPROM_SETTINGS; +} + +void func_8006E5BC(void) { + s32 i, j; + gSettingsPtr->gNumRacers = get_number_of_active_players(); + for (i = 0; i < 8; i++) { + gSettingsPtr->racers[i].best_times = 0; + gSettingsPtr->racers[i].character = get_character_id_from_slot(i); + if (gSettingsPtr->gNumRacers >= 2) { + gSettingsPtr->racers[i].starting_position = i; + } else if (is_in_two_player_adventure()) { + gSettingsPtr->racers[i].starting_position = 5 - i; + } else { + gSettingsPtr->racers[i].starting_position = 7 - i; + } + gSettingsPtr->racers[i].unk7 = 0; + for (j = 0; j < 4; j++) { + gSettingsPtr->racers[i].placements[j] = 0; + } + gSettingsPtr->racers[i].course_time = 0; + for (j = 0; j < 3; j++) { + gSettingsPtr->racers[i].lap_times[j] = 0; + } + } + gSettingsPtr->timeTrialRacer = 0; + gSettingsPtr->unk115[0] = 0; + gSettingsPtr->unk115[1] = 0; + gSettingsPtr->display_times = 0; + gSettingsPtr->worldId = 0; + gSettingsPtr->courseId = 0; +} + +void func_8006E770(Settings *settings, s32 arg1) { + s32 i, j; + s32 numWorlds, numLevels; + s32 index; + u16 *temp_v0; + + get_number_of_levels_and_worlds(&numLevels, &numWorlds); + temp_v0 = (u16 *)get_misc_asset(MISC_ASSET_UNK17); + for (i = 0; i < NUMBER_OF_SAVE_FILES; i++) { + for (j = 0; j < numLevels; j++) { + index = (j * 12) + (i * 4); + if (arg1 & 1) { + settings->flapInitialsPtr[i][j] = temp_v0[index + 3]; + settings->flapTimesPtr[i][j] = temp_v0[index + 2]; + } + if (arg1 & 2) { + settings->courseInitialsPtr[i][j] = temp_v0[index + 1]; + settings->courseTimesPtr[i][j] = temp_v0[index]; + } + } + } +} + +void func_8006E994(Settings *settings) { + s32 i; + s32 sp20; + s32 sp1C; + + get_number_of_levels_and_worlds(&sp1C, &sp20); + settings->newGame = TRUE; + + for (i = 0; i < sp20; i++) { + settings->balloonsPtr[i] = 0; + } + for (i = 0; i < sp1C; i++) { + settings->courseFlagsPtr[i] = 0; + } + + settings->keys = 0; + settings->unkA = 0; + settings->bosses = 0; + settings->trophies = 0; + settings->cutsceneFlags = CUTSCENE_NONE; + settings->tajFlags = 0; + settings->ttAmulet = 0; + settings->wizpigAmulet = 0; +} + +UNUSED void func_8006EA58(void) { + func_8006E770(gSettingsPtr, 3); + func_8006E994(gSettingsPtr); +} + +/** + * Return the global game settings. + * This is where global game records and perferences are stored. +*/ +Settings *get_settings(void) { + return gSettingsPtr; +} + +/** + * Returns the value in gIsPaused. + */ +s8 is_game_paused(void) { + return gIsPaused; +} + +/** + * Returns the status of the post-race shrunken viewport. +*/ +s8 is_postrace_viewport_active(void) { + return gPostRaceViewPort; +} + +/** + * Sets and returns (nonzero) the message set when pressing the reset button. + * Official name: mainResetPressed + */ +s32 is_reset_pressed(void) { + if (gNMIMesgBuf == 0) { + gNMIMesgBuf = (s32)((osRecvMesg(&gNMIMesgQueue, NULL, OS_MESG_NOBLOCK) + 1) != 0); + } + return gNMIMesgBuf; +} + +/** + * Returns the current map ID if ingame, since this var is only set ingame. +*/ +s32 get_ingame_map_id(void) { + return gPlayableMapId; +} + +/** + * Marks a flag to read flap times from the eeprom + */ +UNUSED void mark_to_read_flap_times(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_READ_FLAP_TIMES; +} + +/** + * Marks a flag to read course times from the eeprom + */ +UNUSED void mark_to_read_course_times(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_READ_COURSE_TIMES; +} + +/** + * Marks a flag to read both flap times and course times from the eeprom + */ +void mark_to_read_flap_and_course_times(void) { + gSaveDataFlags |= (SAVE_DATA_FLAG_READ_FLAP_TIMES | SAVE_DATA_FLAG_READ_COURSE_TIMES); +} + +/** + * Marks a flag to read the save file from the passed index from flash. + */ +void mark_read_save_file(s32 saveFileIndex) { + //Wipe out bits 8 and 9 + gSaveDataFlags &= ~(SAVE_DATA_FLAG_READ_EEPROM_SETTINGS | SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS); + //Place saveFileIndex at bits 8 and 9 and set bit 2 + gSaveDataFlags |= (SAVE_DATA_FLAG_READ_SAVE_DATA | ((saveFileIndex & SAVE_DATA_FLAG_INDEX_VALUE) << 8)); +} + +/** + * Marks a flag to read all save file data from flash. + */ +void mark_read_all_save_files(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_READ_ALL_SAVE_DATA; //Set bit 3 +} + +/** + * Marks a flag to write flap times to the eeprom + */ +void mark_to_write_flap_times(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_FLAP_TIMES; +} + +/** + * Marks a flag to write course times to the eeprom + */ +void mark_to_write_course_times(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_COURSE_TIMES; +} + +/** + * Marks a flag to write both flap times and course times to the eeprom + */ +void mark_to_write_flap_and_course_times(void) { + gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_FLAP_TIMES | SAVE_DATA_FLAG_WRITE_COURSE_TIMES); +} + +/** + * Forcefully marks a flag to write a save file to flash. + * Official Name: mainSaveGame + */ +void force_mark_write_save_file(s32 saveFileIndex) { + gSaveDataFlags &= ~SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS; //Wipe out bits 10 and 11 + gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_SAVE_DATA | ((saveFileIndex & 3) << 10)); //Set bit 6 and place saveFileIndex into bits 10 and 11 +} + +/** + * Marks a flag to write a save file to flash as long as we're not in tracks mode, and we're in the draw game render context. + * This should prevent save data from being overwritten outside of Adventure Mode. + * Official Name: mainSaveGame2 + */ +void safe_mark_write_save_file(s32 saveFileIndex) { + if (sRenderContext == DRAW_GAME && !is_in_tracks_mode()) { + gSaveDataFlags &= ~SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS; //Wipe out bits 10 and 11 + gSaveDataFlags |= (SAVE_DATA_FLAG_WRITE_SAVE_DATA | ((saveFileIndex & 3) << 10));; //Set bit 6 and place saveFileIndex into bits 10 and 11 + } +} + +/** + * Marks a flag to erase a save file from flash later + */ +void mark_save_file_to_erase(s32 saveFileIndex) { + //Set bit 7 and and place saveFileIndex into bits 10 and 11 while wiping everything else + gSaveDataFlags = SAVE_DATA_FLAG_ERASE_SAVE_DATA | ((saveFileIndex & 3) << 10); +} + +/** + * Marks a flag to read eeprom settings from flash later + * @bug: Because this is the same bit used for reading save files, + * it will change the save file number to read from + */ +UNUSED void mark_read_eeprom_settings(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_READ_EEPROM_SETTINGS; // Set bit 8 +} + +/** + * Marks a flag to write eeprom settings to flash later + * @bug: Because this is the same bit used for reading save files, + * it will change the save file number to read from + */ +void mark_write_eeprom_settings(void) { + gSaveDataFlags |= SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS; // Set bit 9 +} + +/** + * Allocates an amount of memory for the number of players passed in. + */ +void alloc_displaylist_heap(s32 numberOfPlayers) { + s32 num; + s32 totalSize; + + if (numberOfPlayers != gPrevPlayerCount) { + gPrevPlayerCount = numberOfPlayers; + num = numberOfPlayers; + set_free_queue_state(0); + free_from_memory_pool(gDisplayLists[0]); + free_from_memory_pool(gDisplayLists[1]); + totalSize = + ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords))) + + ((gNumHudMatPerPlayer[num] * sizeof(Matrix))) + + ((gNumHudVertsPerPlayer[num] * sizeof(Vertex))) + + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle))); + gDisplayLists[0] = (Gfx *) allocate_at_address_in_main_pool(totalSize, (u8 *) gDisplayLists[0], COLOUR_TAG_RED); + gDisplayLists[1] = (Gfx *) allocate_at_address_in_main_pool(totalSize, (u8 *) gDisplayLists[1], COLOUR_TAG_YELLOW); + if ((gDisplayLists[0] == NULL) || gDisplayLists[1] == NULL) { + if (gDisplayLists[0] != NULL) { + free_from_memory_pool(gDisplayLists[0]); + gDisplayLists[0] = NULL; + } + if (gDisplayLists[1] != NULL) { + free_from_memory_pool(gDisplayLists[1]); + gDisplayLists[1] = NULL; + } + default_alloc_displaylist_heap(); + } + gMatrixHeap[0] = (MatrixS *)((u8 *) gDisplayLists[0] + ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords)))); + gTriangleHeap[0] = (TriangleList *)((u8 *) gMatrixHeap[0] + ((gNumHudMatPerPlayer[num] * sizeof(Matrix)))); + gVertexHeap[0] = (Vertex *)((u8 *) gTriangleHeap[0] + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle)))); + gMatrixHeap[1] = (MatrixS *)((u8 *) gDisplayLists[1] + ((gNumF3dCmdsPerPlayer[num] * sizeof(Gwords)))); + gTriangleHeap[1] = (TriangleList *)((u8 *) gMatrixHeap[1] + ((gNumHudMatPerPlayer[num] * sizeof(Matrix)))); + gVertexHeap[1] = (Vertex *)((u8 *) gTriangleHeap[1] + ((gNumHudTrisPerPlayer[num] * sizeof(Triangle)))); + gCurrNumF3dCmdsPerPlayer = gNumF3dCmdsPerPlayer[num]; + gCurrNumHudMatPerPlayer = gNumHudMatPerPlayer[num]; + gCurrNumHudTrisPerPlayer = gNumHudTrisPerPlayer[num]; + gCurrNumHudVertsPerPlayer = gNumHudVertsPerPlayer[num]; + set_free_queue_state(2); + } + gCurrDisplayList = gDisplayLists[gSPTaskNum]; + gGameCurrMatrix = gMatrixHeap[gSPTaskNum]; + gGameCurrTriList = gTriangleHeap[gSPTaskNum]; + gGameCurrVertexList = gVertexHeap[gSPTaskNum]; + + gDPFullSync(gCurrDisplayList++); + gSPEndDisplayList(gCurrDisplayList++); +} + +/** + * Returns FALSE if dmem doesn't begin with a -1. This is checked on every main game loop iteration. + */ +s32 check_dmem_validity(void) { + if (IO_READ(SP_DMEM_START) != -1U) { + return FALSE; + } + return TRUE; +} + +/** + * Defaults allocations for 4 players + */ +void default_alloc_displaylist_heap(void) { + s32 numberOfPlayers; + s32 totalSize; + + numberOfPlayers = FOUR_PLAYERS; + gPrevPlayerCount = numberOfPlayers; + totalSize = (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords)) + + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix)) + + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex)) + + (gNumHudTrisPerPlayer[numberOfPlayers] * sizeof(Triangle)); + + gDisplayLists[0] = (Gfx *) allocate_from_main_pool_safe(totalSize, COLOUR_TAG_RED); + gMatrixHeap[0] = (MatrixS *) ((u8 *) gDisplayLists[0] + (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords))); + gVertexHeap[0] = (Vertex *) ((u8 *) gMatrixHeap[0] + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix))); + gTriangleHeap[0] = (TriangleList *) ((u8 *) gVertexHeap[0] + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex))); + + gDisplayLists[1] = (Gfx *) allocate_from_main_pool_safe(totalSize, COLOUR_TAG_YELLOW); + gMatrixHeap[1] = (MatrixS *) ((u8 *) gDisplayLists[1] + (gNumF3dCmdsPerPlayer[numberOfPlayers] * sizeof(Gwords))); + gVertexHeap[1] = (Vertex *) ((u8 *) gMatrixHeap[1] + (gNumHudMatPerPlayer[numberOfPlayers] * sizeof(Matrix))); + gTriangleHeap[1] = (TriangleList *) ((u8 *) gVertexHeap[1] + (gNumHudVertsPerPlayer[numberOfPlayers] * sizeof(Vertex))); + + gCurrNumF3dCmdsPerPlayer = gNumF3dCmdsPerPlayer[numberOfPlayers]; + gCurrNumHudMatPerPlayer = gNumHudMatPerPlayer[numberOfPlayers]; + gCurrNumHudTrisPerPlayer = gNumHudTrisPerPlayer[numberOfPlayers]; + gCurrNumHudVertsPerPlayer = gNumHudVertsPerPlayer[numberOfPlayers]; +} + +void func_8006F140(s32 arg0) { + if (gLevelLoadTimer == 0) { + gLevelLoadTimer = 40; + gLevelLoadType = LEVEL_LOAD_NORMAL; + D_80123526 = 0; + if (arg0 == 1) { //FADE_BARNDOOR_HORIZONTAL? + transition_begin(&gLevelFadeOutTransition); + } + if (arg0 == 3) { //FADE_CIRCLE? + gLevelLoadTimer = 282; + transition_begin(&D_800DD424); + } + if (arg0 == 4) { //FADE_WAVES? + gLevelLoadTimer = 360; + transition_begin(&D_800DD424); + } + if (arg0 == 0) { //FADE_FULLSCREEN? + gLevelLoadTimer = 2; + } + } +} + +UNUSED void func_8006F20C(void) { + if (gLevelLoadTimer == 0) { + transition_begin(&gLevelFadeOutTransition); + gLevelLoadTimer = 40; + gLevelLoadType = LEVEL_LOAD_UNK1; + } +} + +/** + * Begins a fade transition, then signals to the level loading that it wants to be a trophy race. +*/ +void begin_trophy_race_teleport(void) { + if (gLevelLoadTimer == 0) { + transition_begin(&gLevelFadeOutTransition); + gLevelLoadTimer = 40; + gLevelLoadType = LEVEL_LOAD_TROPHY_RACE; + } +} + +/** + * Check if all available trophy races and Wizpig 1 has been beaten, and if the cutscene has not yet played. +*/ +void begin_lighthouse_rocket_cutscene(void) { + if (gLevelLoadTimer == 0) { + if ((gSettingsPtr->trophies & 0xFF) == 0xFF && !(gSettingsPtr->cutsceneFlags & CUTSCENE_LIGHTHOUSE_ROCKET) && gSettingsPtr->bosses & 1) { + gSettingsPtr->cutsceneFlags |= CUTSCENE_LIGHTHOUSE_ROCKET; + transition_begin(&gLevelFadeOutTransition); + gLevelLoadTimer = 40; + gNextMap = ASSET_LEVEL_ROCKETSEQUENCE; + gLevelLoadType = LEVEL_LOAD_LIGHTHOUSE_CUTSCENE; + } + } +} + +/** + * Begin a transition, then set the next level to the passed argument. + * This is used only to warp to Future Fun Land from the hub area. +*/ +void begin_level_teleport(s32 levelID) { + if (gLevelLoadTimer == 0) { + gNextMap = levelID; + transition_begin(&gLevelFadeOutTransition); + gLevelLoadTimer = 40; + gLevelLoadType = LEVEL_LOAD_FUTURE_FUN_LAND; + } +} + +void func_8006F388(u8 time) { + D_800DD398 = time; +} + +void func_8006F398(void) { + s32 i; + u8 temp; + u8 *first_racer_data; + u8 *second_racer_data; + + swap_player_1_and_2_ids(); + func_8000E194(); + + first_racer_data = (u8 *)(gSettingsPtr->racers); + second_racer_data = (u8 *)(gSettingsPtr->racers + 1); + + for (i = 0; i < (s32)sizeof(Racer); i++) { + temp = first_racer_data[i]; + first_racer_data[i] = second_racer_data[i]; + second_racer_data[i] = temp; + } +} + +/** + * Sets the timer to delay drawing new frames. + * When set to 2, the game will copy the previous framebuffer over to the next. +*/ +void set_frame_blackout_timer(void) { + gDrawFrameTimer = 2; +} + +/** + * Give the player 8 frames to enter the CPak menu with start, then load the intro sequence. + */ +void pre_intro_loop(void) { + s32 i; + s32 buttonInputs = 0; + + for (i = 0; i < MAXCONTROLLERS; i++) { + buttonInputs |= get_buttons_held_from_player(i); + } + if (buttonInputs & START_BUTTON) { + gShowControllerPakMenu = TRUE; + } + sBootDelayTimer++; + if (sBootDelayTimer >= 8) { + load_menu_with_level_background(MENU_BOOT, 0x27, 2); + } +} + +/** + * Returns TRUE if the game doesn't detect any controllers. + * Official name: mainDemoOnly + */ +s32 is_controller_missing(void) { + if (sControllerStatus == CONTROLLER_MISSING) { + return TRUE; + } else { + return FALSE; + } +} + +/** + * Ran on boot, will make sure the CIC chip (CIC6103) is to spec. Will return true if it's all good, otherwise it returns false. + * The intention of this function, is an attempt to check that the cartridge is a legitimate copy. + * A false read, meaning you're caught running an illegitimate copy, will force the game to pause when you enter the world. + */ +s32 check_imem_validity(void) { + if (IO_READ(SP_IMEM_START) != CIC_ID) { + return FALSE; + } + return TRUE; +} diff --git a/src/thread3_main.h b/src/thread3_main.h new file mode 100644 index 00000000..edf8e118 --- /dev/null +++ b/src/thread3_main.h @@ -0,0 +1,126 @@ +#ifndef _THREAD3_MAIN_H_ +#define _THREAD3_MAIN_H_ + +#include "types.h" +#include "macros.h" +#include "structs.h" +#include "game.h" + +typedef enum RenderContext { + DRAW_INTRO = -1, + DRAW_GAME, + DRAW_MENU, + DRAW_UNK_02, + DRAW_UNK_03, + DRAW_UNK_04, + DRAW_CRASH_SCREEN +} RenderContext; + +enum LevelLoadType { + LEVEL_LOAD_NORMAL, + LEVEL_LOAD_UNK1, + LEVEL_LOAD_TROPHY_RACE, + LEVEL_LOAD_LIGHTHOUSE_CUTSCENE, + LEVEL_LOAD_FUTURE_FUN_LAND, +}; + +/** + * Bit 00: Read Eeprom Data flap times + * Bit 01: Read Eeprom Data course times + * Bit 02: Read Save File from bits 8 and 9 + * Bit 03: Read All Save Files + * Bit 04: Write Eeprom Data flap times + * Bit 05: Write Eeprom Data course times + * Bit 06: Write Save Data from bits 10 and 11 + * Bit 07: Erase Save File from bits 10 and 11 + * Bit 08: Read Save File Number Part 1 @bug Also Read Eeprom settings + * Bit 09: Read Save File Number Part 2 @bug Also Write Eeprom Settings + * Bit 10: Write Save File Number Part 1 + * Bit 11: Write Save File Number Part 2 + */ +extern s32 gSaveDataFlags; +#define SAVE_DATA_FLAG_INDEX_VALUE (1 << 0 | 1 << 1) //2 bits for 4 different values + +#define SAVE_DATA_FLAG_READ_FLAP_TIMES (1 << 0) +#define SAVE_DATA_FLAG_READ_COURSE_TIMES (1 << 1) +#define SAVE_DATA_FLAG_READ_SAVE_DATA (1 << 2) +#define SAVE_DATA_FLAG_READ_ALL_SAVE_DATA (1 << 3) +#define SAVE_DATA_FLAG_WRITE_FLAP_TIMES (1 << 4) +#define SAVE_DATA_FLAG_WRITE_COURSE_TIMES (1 << 5) +#define SAVE_DATA_FLAG_WRITE_SAVE_DATA (1 << 6) +#define SAVE_DATA_FLAG_ERASE_SAVE_DATA (1 << 7) +#define SAVE_DATA_FLAG_READ_EEPROM_SETTINGS (1 << 8) //@bug Bits 8 and 9 are reused for checking the read save file number +#define SAVE_DATA_FLAG_WRITE_EEPROM_SETTINGS (1 << 9) // ^^ +#define SAVE_DATA_FLAG_READ_SAVE_FILE_NUMBER_BITS (1 << 8 | 1 << 9) //These are reused as above +#define SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER_BITS (1 << 10 | 1 << 11) + +#define SAVE_DATA_FLAG_READ_EEPROM_INDEX(flags) (flags & (SAVE_DATA_FLAG_READ_FLAP_TIMES | SAVE_DATA_FLAG_READ_COURSE_TIMES)) +#define SAVE_DATA_FLAG_WRITE_EEPROM_INDEX(flags) ((flags & (SAVE_DATA_FLAG_WRITE_FLAP_TIMES | SAVE_DATA_FLAG_WRITE_COURSE_TIMES)) >> 4) +#define SAVE_DATA_FLAG_READ_SAVE_FILE_NUMBER(flags) ((flags >> 8) & SAVE_DATA_FLAG_INDEX_VALUE) +#define SAVE_DATA_FLAG_WRITE_SAVE_FILE_NUMBER(flags) ((flags >> 10) & SAVE_DATA_FLAG_INDEX_VALUE) + +void thread3_main(UNUSED void *unused); +void init_game(void); +void main_game_loop(void); +void func_8006CAE4(s32 numPlayers, s32 trackID, Vehicle vehicle); +void load_level_game(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId); +void unload_level_game(void); +void func_8006D8A4(void); +void func_8006D8E0(s32 arg0); +void func_8006D8F0(s32 arg0); +void func_8006D968(s8 *arg0); +RenderContext get_render_context(void); +UNUSED void func_8006DA1C(s32 arg0); +void load_menu_with_level_background(s32 menuId, s32 levelId, s32 cutsceneId); +void set_level_default_vehicle(Vehicle arg0); +void func_8006DB20(Vehicle vehicleId); +Vehicle get_level_default_vehicle(void); +void load_level_menu(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId); +void unload_level_menu(void); +void update_menu_scene(s32 arg0); +void load_level_for_menu(s32 levelId, s32 numberOfPlayers, s32 cutsceneId); +void calc_and_alloc_heap_for_settings(void); +void func_8006E5BC(void); +void func_8006E770(Settings *settings, s32 arg1); +void func_8006E994(Settings *settings); +void func_8006EA58(void); +Settings *get_settings(void); +s8 is_game_paused(void); +s8 is_postrace_viewport_active(void); +s32 is_reset_pressed(void); +s32 get_ingame_map_id(void); +void mark_to_read_flap_times(void); +void mark_to_read_course_times(void); +void mark_to_read_flap_and_course_times(void); +void mark_read_save_file(s32 saveFileIndex); +void mark_read_all_save_files(void); +void mark_to_write_flap_times(void); +void mark_to_write_course_times(void); +void mark_to_write_flap_and_course_times(void); +void force_mark_write_save_file(s32 saveFileIndex); +void safe_mark_write_save_file(s32 saveFileIndex); +void mark_save_file_to_erase(s32 saveFileIndex); +void mark_read_eeprom_settings(void); +void mark_write_eeprom_settings(void); +s32 check_dmem_validity(void); +void func_8006F140(s32 arg0); +void func_8006F20C(void); +void begin_trophy_race_teleport(void); +void begin_lighthouse_rocket_cutscene(void); +void begin_level_teleport(s32 arg0); +void func_8006F388(u8 arg0); +void func_8006F398(void); +void set_frame_blackout_timer(void); +void pre_intro_loop(void); +s32 is_controller_missing(void); +s32 check_imem_validity(void); +void ingame_logic_loop(s32 updateRate); +void load_level(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicleId, s32 cutsceneId); +void init_level_globals(void); +void alloc_displaylist_heap(s32 numberOfPlayers); +void default_alloc_displaylist_heap(void); + +//Non Matching +void func_8006DCF8(s32 updateRate); + +#endif diff --git a/src/unknown_0255E0.c b/src/unknown_0255E0.c index 3920a04e..556fbfcb 100644 --- a/src/unknown_0255E0.c +++ b/src/unknown_0255E0.c @@ -449,7 +449,7 @@ void func_80026070(LevelModelSegmentBoundingBox *, f32, f32, f32); void func_80026430(LevelModelSegment *, f32, f32, f32); void func_80026C14(s16 arg0, s16 arg1, s32 arg2); void func_80026E54(s16 arg0, s8 *arg1, f32 arg2, f32 arg3); - +//Alternative Attempt: https://decomp.me/scratch/2C6dJ void func_8002581C(u8 *segmentIds, s32 numberOfSegments, s32 viewportIndex) { Vertex *spAC; s8 *spA8; @@ -687,6 +687,7 @@ void set_skydome_visbility(s32 renderSky) { gSceneRenderSkyDome = renderSky; } +//https://decomp.me/scratch/jmbc1 GLOBAL_ASM("asm/non_matchings/unknown_0255E0/func_80028050.s") /** diff --git a/src/waves.c b/src/waves.c index fa643c95..27d286ff 100644 --- a/src/waves.c +++ b/src/waves.c @@ -251,6 +251,7 @@ GLOBAL_ASM("asm/non_matchings/waves/func_800B92F4.s") GLOBAL_ASM("asm/non_matchings/waves/func_800B97A8.s") GLOBAL_ASM("asm/non_matchings/waves/func_800B9C18.s") GLOBAL_ASM("asm/non_matchings/waves/func_800BA288.s") +//https://decomp.me/scratch/h4uac GLOBAL_ASM("asm/non_matchings/waves/func_800BA4B8.s") GLOBAL_ASM("asm/non_matchings/waves/func_800BA8E4.s") GLOBAL_ASM("asm/non_matchings/waves/func_800BB2F4.s") diff --git a/src/weather.c b/src/weather.c index 36efd268..31cc22f7 100644 --- a/src/weather.c +++ b/src/weather.c @@ -13,6 +13,12 @@ #include "textures_sprites.h" #include "math_util.h" +/************ .rodata ************/ + +const char D_800E87F0[] = "\nMaximum limit of %d lens flare switches, per level, has been exceeded."; + +/*********************************/ + /************ .data ************/ unk800E2850 D_800E2850[3] = { @@ -394,6 +400,8 @@ void func_800AC880(s32 arg0) { } GLOBAL_ASM("asm/non_matchings/game_ui/func_800AC8A8.s") + +//https://decomp.me/scratch/mYuMJ GLOBAL_ASM("asm/non_matchings/game_ui/func_800ACA20.s") void cameraAddOverrideObject(Object *arg0) { @@ -580,4 +588,5 @@ void handle_rain_sound(UNUSED s32 updateRate) { } } +//https://decomp.me/scratch/PDAZs GLOBAL_ASM("asm/non_matchings/game_ui/render_rain_overlay.s")