From d54031c3a6a4ef543530c4336c6cf4280fab2357 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Tue, 25 Apr 2023 10:49:29 +0100 Subject: [PATCH] Document fog system, and label some object behaviour (#386) * identify transition bug * Document fog system * Label fogchanger attributes * and more * anti aliasing * name some object vars * block the racer inputs * Update unknown_0255E0.c * Update README.md * Update src/object_functions.c --- README.md | 54 ++-- asm/non_matchings/objects/func_8000CC7C.s | 2 +- asm/non_matchings/objects/func_8001A8F4.s | 6 +- asm/non_matchings/racer/func_80046524.s | 8 +- asm/non_matchings/racer/func_80049794.s | 4 +- asm/non_matchings/racer/func_8004F7F4.s | 6 +- .../unknown_005740/func_80008438.s | 2 +- .../unknown_0255E0/func_800249F0.s | 4 +- .../unknown_0255E0/func_80030664.s | 4 +- .../unknown_0255E0/func_80030DE0.s | 4 +- include/level_object_entries.h | 24 +- include/structs.h | 40 +-- src/camera.c | 8 +- src/camera.h | 2 +- src/fade_transition.c | 1 - src/game.c | 4 +- src/game_text.c | 2 +- src/object_functions.c | 286 +++++++++--------- src/object_functions.h | 6 + src/objects.c | 2 +- src/racer.c | 62 ++-- src/racer.h | 4 +- src/textures_sprites.h | 2 +- src/unknown_0255E0.c | 266 ++++++++-------- src/unknown_0255E0.h | 53 ++-- 25 files changed, 447 insertions(+), 409 deletions(-) diff --git a/README.md b/README.md index a0e97d27..720e38e2 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ This repo contains a work-in-progress decompilation of Diddy Kong Racing for the Currently, only the US 1.0 version of the game is supported. US 1.1, EU 1.0, EU 1.1, and JP are not supported at this time. -As of April 11, 2023, this is our current score: +As of April 24, 2023, this is our current score: -    Decomp progress: 51.01% +    Decomp progress: 51.18% -    Documentation progress: 23.43% +    Documentation progress: 24.34% --- @@ -128,31 +128,31 @@ s32 is_drumstick_unlocked(void) { ``` -As of April 11, 2023, this is our current score: +As of April 24, 2023, this is our current score: ``` - =================================================================== - ADVENTURE ONE (ASM -> C Decompilation) - ------------------------- 51.01% Complete ------------------------- - # Decompiled functions: 1498 - # GLOBAL_ASM remaining: 334 - # NON_MATCHING functions: 12 - # NON_EQUIVALENT WIP functions: 64 - --------------------------- Game Status --------------------------- - Balloons: 25/47, Keys: 3/4, Trophies: 2/5 - T.T. Amulets: 2/4, Wizpig Amulets: 2/4 - ------------------------------------------------------------------- - We are racing in Treasure Caves. (Lap 3/3) - =================================================================== - ADVENTURE TWO (Cleanup & Documentation) - ------------------------- 23.43% Complete ------------------------- - # Documented functions: 449 - # Undocumented remaining: 1118 - --------------------------- Game Status --------------------------- - Balloons: 12/47, Keys: 1/4, Trophies: 0/5 - T.T. Amulets: 1/4, Wizpig Amulets: 1/4 - ------------------------------------------------------------------- - We are participating in the Trophy Race of Dino Domain. (Round Two) - =================================================================== + ================================================= + ADVENTURE ONE (ASM -> C Decompilation) + ---------------- 51.18% Complete ---------------- + # Decompiled functions: 1501 + # GLOBAL_ASM remaining: 331 + # NON_MATCHING functions: 12 + # NON_EQUIVALENT WIP functions: 64 + ------------------ Game Status ------------------ + Balloons: 25/47, Keys: 3/4, Trophies: 2/5 + T.T. Amulets: 2/4, Wizpig Amulets: 2/4 + ------------------------------------------------- + We are racing in Treasure Caves. (Lap 3/3) + ================================================= + ADVENTURE TWO (Cleanup & Documentation) + ---------------- 24.34% Complete ---------------- + # Documented functions: 485 + # Undocumented remaining: 1079 + ------------------ Game Status ------------------ + Balloons: 12/47, Keys: 1/4, Trophies: 1/5 + T.T. Amulets: 1/4, Wizpig Amulets: 1/4 + ------------------------------------------------- + We are racing Taj in the Car Challenge. (Lap 1/3) + ================================================= ``` diff --git a/asm/non_matchings/objects/func_8000CC7C.s b/asm/non_matchings/objects/func_8000CC7C.s index e527bbca..9ffa9a21 100644 --- a/asm/non_matchings/objects/func_8000CC7C.s +++ b/asm/non_matchings/objects/func_8000CC7C.s @@ -71,7 +71,7 @@ glabel func_8000CC7C /* 00D954 8000CD54 00000000 */ nop /* 00D958 8000CD58 17000008 */ bnez $t8, .L8000CD7C /* 00D95C 8000CD5C 00000000 */ nop -/* 00D960 8000CD60 0C01A75F */ jal func_80069D7C +/* 00D960 8000CD60 0C01A75F */ jal get_cutscene_camera_segment /* 00D964 8000CD64 00000000 */ nop /* 00D968 8000CD68 AFA20074 */ sw $v0, 0x74($sp) /* 00D96C 8000CD6C 9059003B */ lbu $t9, 0x3b($v0) diff --git a/asm/non_matchings/objects/func_8001A8F4.s b/asm/non_matchings/objects/func_8001A8F4.s index e6d8e169..488d454d 100644 --- a/asm/non_matchings/objects/func_8001A8F4.s +++ b/asm/non_matchings/objects/func_8001A8F4.s @@ -283,7 +283,7 @@ glabel func_8001A8F4 /* 01B914 8001AD14 240B0004 */ li $t3, 4 /* 01B918 8001AD18 3C018012 */ lui $at, %hi(D_8011AD50) # $at, 0x8012 /* 01B91C 8001AD1C A02BAD50 */ sb $t3, %lo(D_8011AD50)($at) -/* 01B920 8001AD20 0C00A3E8 */ jal func_80028FA0 +/* 01B920 8001AD20 0C00A3E8 */ jal set_anti_aliasing /* 01B924 8001AD24 24040001 */ li $a0, 1 /* 01B928 8001AD28 3C028012 */ lui $v0, %hi(D_8011AD50) # $v0, 0x8012 /* 01B92C 8001AD2C 8042AD50 */ lb $v0, %lo(D_8011AD50)($v0) @@ -292,9 +292,9 @@ glabel func_8001A8F4 /* 01B934 8001AD34 24010004 */ li $at, 4 /* 01B938 8001AD38 1441003E */ bne $v0, $at, .L8001AE34 /* 01B93C 8001AD3C 8FBF001C */ lw $ra, 0x1c($sp) -/* 01B940 8001AD40 0C00A3E8 */ jal func_80028FA0 +/* 01B940 8001AD40 0C00A3E8 */ jal set_anti_aliasing /* 01B944 8001AD44 24040001 */ li $a0, 1 -/* 01B948 8001AD48 0C0168EC */ jal func_8005A3B0 +/* 01B948 8001AD48 0C0168EC */ jal disable_racer_input /* 01B94C 8001AD4C 00000000 */ nop /* 01B950 8001AD50 0C01AF66 */ jal get_current_level_race_type /* 01B954 8001AD54 00000000 */ nop diff --git a/asm/non_matchings/racer/func_80046524.s b/asm/non_matchings/racer/func_80046524.s index baf66223..6da2e554 100644 --- a/asm/non_matchings/racer/func_80046524.s +++ b/asm/non_matchings/racer/func_80046524.s @@ -1612,7 +1612,7 @@ glabel func_80046524 /* 0487E8 80047BE8 46104282 */ mul.s $f10, $f8, $f16 /* 0487EC 80047BEC C6280020 */ lwc1 $f8, 0x20($s1) /* 0487F0 80047BF0 3C014000 */ li $at, 0x40000000 # 2.000000 -/* 0487F4 80047BF4 3C0A8012 */ lui $t2, %hi(D_8011D584) # $t2, 0x8012 +/* 0487F4 80047BF4 3C0A8012 */ lui $t2, %hi(gRacerInputBlocked) # $t2, 0x8012 /* 0487F8 80047BF8 460A3101 */ sub.s $f4, $f6, $f10 /* 0487FC 80047BFC 3C0B8012 */ lui $t3, %hi(gCurrentRacerInput) # $t3, 0x8012 /* 048800 80047C00 E624001C */ swc1 $f4, 0x1c($s1) @@ -1675,7 +1675,7 @@ glabel func_80046524 /* 0488E4 80047CE4 00000000 */ nop /* 0488E8 80047CE8 13200031 */ beqz $t9, .L80047DB0 /* 0488EC 80047CEC 00000000 */ nop -/* 0488F0 80047CF0 814AD584 */ lb $t2, %lo(D_8011D584)($t2) +/* 0488F0 80047CF0 814AD584 */ lb $t2, %lo(gRacerInputBlocked)($t2) /* 0488F4 80047CF4 3C0C8012 */ lui $t4, %hi(gRaceStartTimer) # $t4, 0x8012 /* 0488F8 80047CF8 1540002D */ bnez $t2, .L80047DB0 /* 0488FC 80047CFC 00000000 */ nop @@ -1834,13 +1834,13 @@ glabel func_80046524 /* 048B44 80047F44 C630001C */ lwc1 $f16, 0x1c($s1) /* 048B48 80047F48 C62C0024 */ lwc1 $f12, 0x24($s1) /* 048B4C 80047F4C 13000005 */ beqz $t8, .L80047F64 -/* 048B50 80047F50 3C0D8012 */ lui $t5, %hi(D_8011D584) # $t5, 0x8012 +/* 048B50 80047F50 3C0D8012 */ lui $t5, %hi(gRacerInputBlocked) # $t5, 0x8012 /* 048B54 80047F54 C60A011C */ lwc1 $f10, 0x11c($s0) /* 048B58 80047F58 C6040120 */ lwc1 $f4, 0x120($s0) /* 048B5C 80047F5C 460A8400 */ add.s $f16, $f16, $f10 /* 048B60 80047F60 46046300 */ add.s $f12, $f12, $f4 .L80047F64: -/* 048B64 80047F64 81ADD584 */ lb $t5, %lo(D_8011D584)($t5) +/* 048B64 80047F64 81ADD584 */ lb $t5, %lo(gRacerInputBlocked)($t5) /* 048B68 80047F68 C7A8012C */ lwc1 $f8, 0x12c($sp) /* 048B6C 80047F6C 11A0002E */ beqz $t5, .L80048028 /* 048B70 80047F70 3C013FE0 */ li $at, 0x3FE00000 # 1.750000 diff --git a/asm/non_matchings/racer/func_80049794.s b/asm/non_matchings/racer/func_80049794.s index 0982a087..b64b628d 100644 --- a/asm/non_matchings/racer/func_80049794.s +++ b/asm/non_matchings/racer/func_80049794.s @@ -2363,7 +2363,7 @@ glabel func_80049794 /* 04C540 8004B940 C634001C */ lwc1 $f20, 0x1c($s1) /* 04C544 8004B944 C62C0024 */ lwc1 $f12, 0x24($s1) /* 04C548 8004B948 11C00010 */ beqz $t6, .L8004B98C -/* 04C54C 8004B94C 3C188012 */ lui $t8, %hi(D_8011D584) # $t8, 0x8012 +/* 04C54C 8004B94C 3C188012 */ lui $t8, %hi(gRacerInputBlocked) # $t8, 0x8012 /* 04C550 8004B950 C604011C */ lwc1 $f4, 0x11c($s0) /* 04C554 8004B954 3C013FE0 */ li $at, 0x3FE00000 # 1.750000 /* 04C558 8004B958 44811800 */ mtc1 $at, $f3 @@ -2380,7 +2380,7 @@ glabel func_80049794 /* 04C584 8004B984 46282180 */ add.d $f6, $f4, $f8 /* 04C588 8004B988 46203320 */ cvt.s.d $f12, $f6 .L8004B98C: -/* 04C58C 8004B98C 8318D584 */ lb $t8, %lo(D_8011D584)($t8) +/* 04C58C 8004B98C 8318D584 */ lb $t8, %lo(gRacerInputBlocked)($t8) /* 04C590 8004B990 3C013FE0 */ li $at, 0x3FE00000 # 1.750000 /* 04C594 8004B994 44811800 */ mtc1 $at, $f3 /* 04C598 8004B998 44801000 */ mtc1 $zero, $f2 diff --git a/asm/non_matchings/racer/func_8004F7F4.s b/asm/non_matchings/racer/func_8004F7F4.s index 8f938da2..22eed90f 100644 --- a/asm/non_matchings/racer/func_8004F7F4.s +++ b/asm/non_matchings/racer/func_8004F7F4.s @@ -599,7 +599,7 @@ glabel func_8004F7F4 /* 050C50 80050050 17000072 */ bnez $t8, .L8005021C /* 050C54 80050054 02202025 */ move $a0, $s1 /* 050C58 80050058 C630001C */ lwc1 $f16, 0x1c($s1) -/* 050C5C 8005005C 3C088012 */ lui $t0, %hi(D_8011D584) # $t0, 0x8012 +/* 050C5C 8005005C 3C088012 */ lui $t0, %hi(gRacerInputBlocked) # $t0, 0x8012 /* 050C60 80050060 E7B000B8 */ swc1 $f16, 0xb8($sp) /* 050C64 80050064 C6320024 */ lwc1 $f18, 0x24($s1) /* 050C68 80050068 C7A800B8 */ lwc1 $f8, 0xb8($sp) @@ -617,7 +617,7 @@ glabel func_8004F7F4 /* 050C98 80050098 46103480 */ add.s $f18, $f6, $f16 /* 050C9C 8005009C E7B200B4 */ swc1 $f18, 0xb4($sp) .L800500A0: -/* 050CA0 800500A0 8108D584 */ lb $t0, %lo(D_8011D584)($t0) +/* 050CA0 800500A0 8108D584 */ lb $t0, %lo(gRacerInputBlocked)($t0) /* 050CA4 800500A4 C7A800B8 */ lwc1 $f8, 0xb8($sp) /* 050CA8 800500A8 1100003C */ beqz $t0, .L8005019C /* 050CAC 800500AC 00000000 */ nop @@ -1057,7 +1057,7 @@ glabel func_8004F7F4 /* 051314 80050714 24010025 */ li $at, 37 /* 051318 80050718 11A10004 */ beq $t5, $at, .L8005072C /* 05131C 8005071C 83AC0053 */ lb $t4, 0x53($sp) -/* 051320 80050720 0C00A3E8 */ jal func_80028FA0 +/* 051320 80050720 0C00A3E8 */ jal set_anti_aliasing /* 051324 80050724 24040001 */ li $a0, 1 /* 051328 80050728 83AC0053 */ lb $t4, 0x53($sp) .L8005072C: diff --git a/asm/non_matchings/unknown_005740/func_80008438.s b/asm/non_matchings/unknown_005740/func_80008438.s index 78fa05df..746c92aa 100644 --- a/asm/non_matchings/unknown_005740/func_80008438.s +++ b/asm/non_matchings/unknown_005740/func_80008438.s @@ -30,7 +30,7 @@ glabel func_80008438 /* 009094 80008494 AFA0024C */ sw $zero, 0x24c($sp) /* 009098 80008498 0C01994B */ jal set_active_viewports_and_max /* 00909C 8000849C 00402025 */ move $a0, $v0 -/* 0090A0 800084A0 0C01A75F */ jal func_80069D7C +/* 0090A0 800084A0 0C01A75F */ jal get_cutscene_camera_segment /* 0090A4 800084A4 AFA200B0 */ sw $v0, 0xb0($sp) /* 0090A8 800084A8 3C15800E */ lui $s5, %hi(D_800DC6E0) # $s5, 0x800e /* 0090AC 800084AC 26B5C6E0 */ addiu $s5, %lo(D_800DC6E0) # addiu $s5, $s5, -0x3920 diff --git a/asm/non_matchings/unknown_0255E0/func_800249F0.s b/asm/non_matchings/unknown_0255E0/func_800249F0.s index a95dcf79..9c166954 100644 --- a/asm/non_matchings/unknown_0255E0/func_800249F0.s +++ b/asm/non_matchings/unknown_0255E0/func_800249F0.s @@ -152,12 +152,12 @@ glabel func_800249F0 /* 025818 80024C18 0C01994B */ jal set_active_viewports_and_max /* 02581C 80024C1C 00000000 */ nop /* 025820 80024C20 8E690000 */ lw $t1, ($s3) -/* 025824 80024C24 3C018012 */ lui $at, %hi(D_8011B0FC) # $at, 0x8012 +/* 025824 80024C24 3C018012 */ lui $at, %hi(gAntiAliasing) # $at, 0x8012 /* 025828 80024C28 3C13FFFF */ lui $s3, (0xFFFF00FF >> 16) # lui $s3, 0xffff /* 02582C 80024C2C 3C118012 */ lui $s1, %hi(D_8011D350) # $s1, 0x8012 /* 025830 80024C30 3C128012 */ lui $s2, %hi(D_8011D320) # $s2, 0x8012 /* 025834 80024C34 3C108012 */ lui $s0, %hi(D_8011D338) # $s0, 0x8012 -/* 025838 80024C38 AC20B0FC */ sw $zero, %lo(D_8011B0FC)($at) +/* 025838 80024C38 AC20B0FC */ sw $zero, %lo(gAntiAliasing)($at) /* 02583C 80024C3C 2610D338 */ addiu $s0, %lo(D_8011D338) # addiu $s0, $s0, -0x2cc8 /* 025840 80024C40 2652D320 */ addiu $s2, %lo(D_8011D320) # addiu $s2, $s2, -0x2ce0 /* 025844 80024C44 2631D350 */ addiu $s1, %lo(D_8011D350) # addiu $s1, $s1, -0x2cb0 diff --git a/asm/non_matchings/unknown_0255E0/func_80030664.s b/asm/non_matchings/unknown_0255E0/func_80030664.s index 5412d972..a524c013 100644 --- a/asm/non_matchings/unknown_0255E0/func_80030664.s +++ b/asm/non_matchings/unknown_0255E0/func_80030664.s @@ -34,8 +34,8 @@ glabel func_80030664 .L800306DC: /* 0312DC 800306DC 93A30013 */ lbu $v1, 0x13($sp) /* 0312E0 800306E0 93A80017 */ lbu $t0, 0x17($sp) -/* 0312E4 800306E4 3C0E8012 */ lui $t6, %hi(D_8011D388) # $t6, 0x8012 -/* 0312E8 800306E8 25CED388 */ addiu $t6, %lo(D_8011D388) # addiu $t6, $t6, -0x2c78 +/* 0312E4 800306E4 3C0E8012 */ lui $t6, %hi(gFogData) # $t6, 0x8012 +/* 0312E8 800306E8 25CED388 */ addiu $t6, %lo(gFogData) # addiu $t6, $t6, -0x2c78 /* 0312EC 800306EC 000D68C0 */ sll $t5, $t5, 3 /* 0312F0 800306F0 01AE1021 */ addu $v0, $t5, $t6 /* 0312F4 800306F4 00077C00 */ sll $t7, $a3, 0x10 diff --git a/asm/non_matchings/unknown_0255E0/func_80030DE0.s b/asm/non_matchings/unknown_0255E0/func_80030DE0.s index c336bdd8..f2f96c89 100644 --- a/asm/non_matchings/unknown_0255E0/func_80030DE0.s +++ b/asm/non_matchings/unknown_0255E0/func_80030DE0.s @@ -23,8 +23,8 @@ glabel func_80030DE0 /* 031A2C 80030E2C 000E70C0 */ sll $t6, $t6, 3 /* 031A30 80030E30 00408825 */ move $s1, $v0 .L80030E34: -/* 031A34 80030E34 3C0F8012 */ lui $t7, %hi(D_8011D388) # $t7, 0x8012 -/* 031A38 80030E38 25EFD388 */ addiu $t7, %lo(D_8011D388) # addiu $t7, $t7, -0x2c78 +/* 031A34 80030E34 3C0F8012 */ lui $t7, %hi(gFogData) # $t7, 0x8012 +/* 031A38 80030E38 25EFD388 */ addiu $t7, %lo(gFogData) # addiu $t7, $t7, -0x2c78 /* 031A3C 80030E3C 01CF1021 */ addu $v0, $t6, $t7 /* 031A40 80030E40 8C590000 */ lw $t9, ($v0) /* 031A44 80030E44 0005C400 */ sll $t8, $a1, 0x10 diff --git a/include/level_object_entries.h b/include/level_object_entries.h index cf0e09cb..b318705a 100644 --- a/include/level_object_entries.h +++ b/include/level_object_entries.h @@ -57,7 +57,7 @@ typedef struct LevelObjectEntry_Exit { /* 0x0A */ s8 overworldSpawnIndex; /* 0x0B */ u8 padB[5]; - /* 0x10 */ u8 unk10; + /* 0x10 */ u8 radius; // Activation radius. /* 0x11 */ u8 unk11; /* 0x12 */ u8 pad12[5]; @@ -119,9 +119,9 @@ typedef struct LevelObjectEntry_Dino_Whale { typedef struct LevelObjectEntry_Checkpoint { /* 0x00 */ LevelObjectEntryCommon common; - /* 0x08 */ u8 unk8; + /* 0x08 */ u8 scale; /* 0x09 */ u8 unk9; - /* 0x0A */ u8 unkA; + /* 0x0A */ u8 yRotation; /* 0x0B */ s8 unkB; /* 0x0C */ s8 unkC; /* 0x0D */ s8 unkD; @@ -156,13 +156,13 @@ typedef struct LevelObjectEntry_Door { typedef struct LevelObjectEntry_FogChanger { /* 0x00 */ LevelObjectEntryCommon common; - /* 0x08 */ u8 unk8; - /* 0x09 */ u8 unk9; - /* 0x0A */ u8 unkA; - /* 0x0B */ u8 unkB; - /* 0x0C */ s16 unkC; - /* 0x0E */ s16 unkE; - /* 0x10 */ s16 unk10; + /* 0x08 */ u8 distance; + /* 0x09 */ u8 r; + /* 0x0A */ u8 g; + /* 0x0B */ u8 b; + /* 0x0C */ s16 near; + /* 0x0E */ s16 far; + /* 0x10 */ s16 switchTimer; } LevelObjectEntry_FogChanger; typedef struct LevelObjectEntry_AiNode { @@ -474,9 +474,9 @@ typedef struct LevelObjectEntry_FlyCoin { typedef struct LevelObjectEntry_GoldenBalloon { /* 0x00 */ LevelObjectEntryCommon common; - /* 0x08 */ s8 unk8; + /* 0x08 */ s8 balloonID; /* 0x09 */ u8 scale; - /* 0x0A */ s8 unkA; + /* 0x0A */ s8 challengeID; } LevelObjectEntry_GoldenBalloon; typedef struct LevelObjectEntry_Laserbolt { diff --git a/include/structs.h b/include/structs.h index 9170c40d..36d112ee 100644 --- a/include/structs.h +++ b/include/structs.h @@ -1017,12 +1017,12 @@ typedef struct Object_Wizpig2 { } Object_Wizpig2; typedef struct Object_Exit { - /* 0x00 */ f32 unk0; - /* 0x04 */ f32 unk4; - /* 0x08 */ f32 unk8; - /* 0x0C */ f32 unkC; - /* 0x10 */ s32 unk10; - /* 0x14 */ s8 unk14; + /* 0x00 */ f32 directionX; + /* 0x04 */ f32 directionY; + /* 0x08 */ f32 directionZ; + /* 0x0C */ f32 rotationDiff; // Rotational offset, to test intersection when the exit is rotated. + /* 0x10 */ s32 radius; // Activation radius. + /* 0x14 */ s8 bossFlag; // Dictates boss level version. 0 is first encounter, 1 is rematch. -1 means no boss. } Object_Exit; /* Size: 0x224 - 548 bytes */ @@ -1088,7 +1088,7 @@ typedef struct Object_Racer { /* 0x0E4 */ Vec3f unkE4; /* 0x0F0 */ Vec3f unkF0; /* 0x0FC */ Vec3f unkFC; - /* 0x108 */ struct Object *unk108; + /* 0x108 */ struct Object *exitObj; /* 0x10C */ s32 unk10C; /* 0x110 */ s32 unk110; /* 0x114 */ s32 unk114; @@ -1260,17 +1260,6 @@ typedef struct Object_ModeChange { /* 0x14 */ u8 vehicleID; } Object_ModeChange; -typedef struct Object_GoldenBalloon { - /* 0x00 */ f32 unk0; - /* 0x04 */ u8 pad4[0x8]; - /* 0x0C */ u8 unkC; - /* 0x0D */ u8 unkD; - /* 0x0E */ u8 unkE; - /* 0x0F */ u8 unkF; - /* 0x10 */ s8 unk10; - /* 0x14 */ f32 unk14; -} Object_GoldenBalloon; - typedef struct Object_Door { /* 0x00 */ f32 unk0; /* 0x04 */ u8 pad4[0x4]; @@ -1353,22 +1342,22 @@ typedef struct Object_FogChanger { typedef struct Object_NPC { /* 0x00 */ f32 unk0; - /* 0x04 */ f32 unk4; + /* 0x04 */ f32 animFrameF; /* 0x08 */ s32 unk8; /* 0x0C */ s8 unkC; /* 0x0D */ u8 unkD; /* 0x0E */ u8 unkE; /* 0x0F */ u8 unkF; /* 0x10 */ u8 unk10; - /* 0x11 */ u8 unk11; - /* 0x12 */ u8 unk12; - /* 0x13 */ u8 unk13; - /* 0x14 */ f32 unk14; + /* 0x11 */ u8 fogR; + /* 0x12 */ u8 fogG; + /* 0x13 */ u8 fogB; + /* 0x14 */ f32 forwardVel; /* 0x18 */ f32 unk18; /* 0x1C */ s16 unk1C; /* 0x1E */ s16 unk1E; - /* 0x20 */ s16 unk20; - /* 0x22 */ s16 unk22; + /* 0x20 */ s16 fogNear; + /* 0x22 */ s16 fogFar; /* 0x24 */ s32 unk24; /* 0x28 */ s16 unk28; /* 0x2A */ s16 unk2A; @@ -1474,7 +1463,6 @@ typedef struct Object_64 { Object_Racer racer; Object_Bonus bonus; Object_ModeChange mode_change; - Object_GoldenBalloon golden_balloon; Object_Door door; Object_Trigger trigger; Object_Audio audio; diff --git a/src/camera.c b/src/camera.c index 251be267..ad118522 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1381,11 +1381,15 @@ ObjectSegment *get_active_camera_segment(void) { return &gActiveCameraStack[gActiveCameraID]; } -ObjectSegment *func_80069D7C(void) { +/** + * Returns the segment data of the active cutscene camera. + * If no cutscene is active, return player 1's camera. +*/ +ObjectSegment *get_cutscene_camera_segment(void) { if (gCutsceneCameraActive) { return &gActiveCameraStack[4]; } - return &gActiveCameraStack[0]; + return &gActiveCameraStack[PLAYER_ONE]; } Matrix *func_80069DA4(void) { diff --git a/src/camera.h b/src/camera.h index f3deb67f..85ce50af 100644 --- a/src/camera.h +++ b/src/camera.h @@ -113,7 +113,7 @@ void func_80068408(Gfx **dlist, MatrixS **mats); void func_80068508(s32 arg0); ObjectSegment *get_active_camera_segment_no_cutscenes(void); ObjectSegment *get_active_camera_segment(void); -ObjectSegment *func_80069D7C(void); +ObjectSegment *get_cutscene_camera_segment(void); Matrix *func_80069DA4(void); MatrixS *func_80069DB0(void); Matrix *func_80069DBC(void); diff --git a/src/fade_transition.c b/src/fade_transition.c index d5df14d8..4ab0c38f 100644 --- a/src/fade_transition.c +++ b/src/fade_transition.c @@ -308,7 +308,6 @@ s32 handle_transitions(s32 updateRate) { if (sTransitionFadeTimer == 0) { sTransitionStatus = TRANSITION_LEVELSWAP; } -//!@bug Not yet confirmed as a bug, but sTransitionFlags will not be zero when ingame, leaving stray transitions up. if ((sTransitionFadeTimer == 0) && (sTransitionFlags == 0)) { transition_end(); } else { diff --git a/src/game.c b/src/game.c index 3874293f..039306da 100644 --- a/src/game.c +++ b/src/game.c @@ -663,7 +663,7 @@ void load_level(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicl func_800249F0(gCurrentLevelHeader->geometry, gCurrentLevelHeader->skybox, numberOfPlayers, vehicleId, entranceId, gCurrentLevelHeader->collectables, gCurrentLevelHeader->unkBA); if (gCurrentLevelHeader->fogNear == 0 && gCurrentLevelHeader->fogFar == 0 && gCurrentLevelHeader->fogR == 0 && gCurrentLevelHeader->fogG == 0 && gCurrentLevelHeader->fogB == 0) { for (var_s0 = 0; var_s0 < 4; var_s0++) { - func_800307BC(var_s0); + reset_fog(var_s0); } } else { for (var_s0 = 0; var_s0 < 4; var_s0++) { @@ -1198,7 +1198,7 @@ void ingame_logic_loop(s32 updateRate) { } } } else { - func_80028FA0(1); + set_anti_aliasing(TRUE); } D_800DD398 -= updateRate; if (D_800DD398 < 0) { diff --git a/src/game_text.c b/src/game_text.c index c56297cd..b6e1fdde 100644 --- a/src/game_text.c +++ b/src/game_text.c @@ -312,7 +312,7 @@ void func_800C3440(s32 arg0) { } func_800C2F1C(arg0); if (D_8012A789 != 0) { - func_8005A3B0(); + disable_racer_input(); if (D_8012A786 != 0) { D_8012A785 -= arg0; while (D_8012A785 < 0) { diff --git a/src/object_functions.c b/src/object_functions.c index 7f41ad05..7a8c2719 100644 --- a/src/object_functions.c +++ b/src/object_functions.c @@ -666,7 +666,7 @@ void obj_loop_trophycab(Object *obj, s32 updateRate) { set_hud_visibility(1); } } - func_8005A3B0(); + disable_racer_input(); } obj->unk5C->unk100 = NULL; if (worldBalloons) { @@ -1090,8 +1090,8 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { } tt = (Object_NPC *) obj->unk64; if (obj->segment.animFrame == 0) { - if (tt->unk4 > 1.0) { - tt->unk4 = 0.0f; + if (tt->animFrameF > 1.0) { + tt->animFrameF = 0.0f; } } header = get_current_level_header(); @@ -1111,7 +1111,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { if (angleDiff < -0x8000) { angleDiff = 0xFFFF; } - if (racer->unk108 != NULL) { + if (racer->exitObj != NULL) { obj->action = TT_MODE_ROAM; obj->unk7C.word = 1; } @@ -1124,8 +1124,8 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { play_char_horn_sound(racerObj, racer); } obj->action = TT_MODE_APPROACH_PLAYER; - func_80030750(0, &tt->unk20, &tt->unk22, &tt->unk11, &tt->unk12, &tt->unk13); - func_80030DE0(0, 0x80, 0x80, 0xFF, 0x384, 0x3E6, 0xF0); + get_fog_settings(PLAYER_ONE, &tt->fogNear, &tt->fogFar, &tt->fogR, &tt->fogG, &tt->fogB); + func_80030DE0(PLAYER_ONE, 128, 128, 255, 900, 998, 240); func_800012E8(); play_music(SEQUENCE_TTS_THEME); if (racerObj != NULL) { @@ -1136,7 +1136,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { } } if (obj->action != TT_MODE_ROAM) { - func_8005A3B0(); + disable_racer_input(); func_800AB194(3); } if (obj->action >= TT_MODE_TURN_TOWARDS_PLAYER) { @@ -1150,7 +1150,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { obj->segment.unk38.byte.unk3B = 0; tt->unkD = 255; if (distance < 100.0) { - func_8005A3C0(); + racer_set_dialogue_camera(); } if (distance > 10.0) { angleDiff = (arctan2_f(diffX / distance, diffZ / distance) - (obj->segment.trans.y_rotation & 0xFFFF)) + 0x8000; @@ -1170,10 +1170,10 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { if (angleDiff > 0x800 || angleDiff < -0x800) { distance = -0.5f; } - tt->unk14 += (distance - tt->unk14) * 0.125; - obj->segment.x_velocity = sins_f(obj->segment.trans.y_rotation) * tt->unk14; - obj->segment.z_velocity = coss_f(obj->segment.trans.y_rotation) * tt->unk14; - tt->unk4 -= (tt->unk14 * 2 * updateRateF); + tt->forwardVel += (distance - tt->forwardVel) * 0.125; + obj->segment.x_velocity = sins_f(obj->segment.trans.y_rotation) * tt->forwardVel; + obj->segment.z_velocity = coss_f(obj->segment.trans.y_rotation) * tt->forwardVel; + tt->animFrameF -= (tt->forwardVel * 2 * updateRateF); } else { obj->action = TT_MODE_TURN_TOWARDS_PLAYER; } @@ -1181,9 +1181,9 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { func_8006F388(1); break; case TT_MODE_TURN_TOWARDS_PLAYER: - func_8005A3C0(); + racer_set_dialogue_camera(); obj->segment.unk38.byte.unk3B = 0; - tt->unk4 += 3.0 * updateRateF; + tt->animFrameF += 3.0 * updateRateF; angleDiff = (racerObj->segment.trans.y_rotation - (obj->segment.trans.y_rotation & 0xFFFF)) + 0x8000; if (angleDiff > 0x8000) { angleDiff -= 0xFFFF; @@ -1211,8 +1211,8 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { obj->segment.x_velocity = diffX * 0.05; obj->segment.z_velocity = diffZ * 0.05; obj->segment.unk38.byte.unk3B = 1; - tt->unk4 += 1.0 * updateRateF; - func_8005A3C0(); + tt->animFrameF += 1.0 * updateRateF; + racer_set_dialogue_camera(); if (index == 3) { obj->action = TT_MODE_DIALOGUE_END; if (is_time_trial_enabled()) { @@ -1220,7 +1220,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { } else { play_tt_voice_clip(SOUND_VOICE_TT_OK, 1); } - func_80030DE0(0, tt->unk11, tt->unk12, tt->unk13, tt->unk20, tt->unk22, 0xB4); + func_80030DE0(PLAYER_ONE, tt->fogR, tt->fogG, tt->fogB, tt->fogNear, tt->fogFar, 180); play_music(header->music); func_80001074(header->instruments); racer->unk118 = func_80004B40(racer->characterId, racer->vehicleID); @@ -1229,8 +1229,8 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { move_object(obj, obj->segment.x_velocity * updateRateF, obj->segment.y_velocity * updateRateF, obj->segment.z_velocity * updateRateF); break; case TT_MODE_DIALOGUE_END: - tt->unk4 += 1.0 * updateRateF; - func_8005A3C0(); + tt->animFrameF += 1.0 * updateRateF; + racer_set_dialogue_camera(); if (obj->unk7C.word < 140) { obj->unk7C.word += 60; obj->action = TT_MODE_ROAM; @@ -1239,7 +1239,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { break; default: obj->segment.unk38.byte.unk3B = 0; - tt->unk14 = 0.0f; + tt->forwardVel = 0.0f; if (tt->unkD == 0xFF) { tt->unkD = func_8001C524(obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position, 0); if (tt->unkD != 0xFF) { @@ -1250,7 +1250,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { } } else { diffZ = func_8001C6C4((Object_64 *) tt, obj, updateRateF, 1.0f, 0); - tt->unk4 += diffZ * 1.5; + tt->animFrameF += diffZ * 1.5; } break; } @@ -1270,7 +1270,7 @@ void obj_loop_stopwatchman(Object *obj, s32 updateRate) { if (obj->action != TT_MODE_ROAM) { D_8011D4D0 = obj->segment.trans.y_position; } - obj->segment.animFrame = 1.0 * tt->unk4; + obj->segment.animFrame = 1.0 * tt->animFrameF; func_80061C0C(obj); if (0) { } // Fakematch if (obj->unk7C.word > 0) { @@ -1884,25 +1884,25 @@ void obj_loop_teleport(Object *obj, UNUSED s32 updateRate) { } void obj_init_exit(Object *obj, LevelObjectEntry_Exit *entry) { - f32 phi_f0; - Object_Exit *obj64; - phi_f0 = entry->unk10 & 0xFF; - if (phi_f0 < 5) { - phi_f0 = 5; + f32 radius; + Object_Exit *exit; + radius = entry->radius & 0xFF; + if (radius < 5) { + radius = 5; } - obj64 = &obj->unk64->exit; - phi_f0 /= 128; - obj->segment.trans.scale = phi_f0; + exit = &obj->unk64->exit; + radius /= 128; + obj->segment.trans.scale = radius; obj->segment.trans.y_rotation = entry->unk11 << 6 << 4; - obj64->unk0 = sins_f(obj->segment.trans.y_rotation); - obj64->unk4 = 0.0f; - obj64->unk8 = coss_f(obj->segment.trans.y_rotation); - obj64->unkC = -((obj64->unk0 * obj->segment.trans.x_position) + (obj64->unk8 * obj->segment.trans.z_position)); - obj64->unk10 = entry->unk10; - obj64->unk14 = entry->bossFlag; + exit->directionX = sins_f(obj->segment.trans.y_rotation); + exit->directionY = 0.0f; + exit->directionZ = coss_f(obj->segment.trans.y_rotation); + exit->rotationDiff = -((exit->directionX * obj->segment.trans.x_position) + (exit->directionZ * obj->segment.trans.z_position)); + exit->radius = entry->radius; + exit->bossFlag = entry->bossFlag; obj->interactObj->unk14 = 2; obj->interactObj->unk11 = 0; - obj->interactObj->unk10 = entry->unk10; + obj->interactObj->unk10 = entry->radius; obj->interactObj->unk12 = 0; } @@ -1919,32 +1919,35 @@ void obj_loop_exit(Object *obj, UNUSED s32 updateRate) { s32 enableWarp; Object** racerObjects; s32 i; - f32 temp; + f32 rotDiff; obj64 = &obj->unk64->exit; enableWarp = TRUE; settings = get_settings(); - if ((obj64->unk14 == 0) && (settings->balloonsPtr[settings->worldId] == 8)) { + // Disable the warp if it's for the first boss encounter, having collected every balloon. + if ((obj64->bossFlag == WARP_BOSS_FIRST) && (settings->balloonsPtr[settings->worldId] == 8)) { enableWarp = FALSE; } - if ((obj64->unk14 == 1) && (settings->balloonsPtr[settings->worldId] < 8)) { + // Disable the warp if it's for the second boss encounter, having not collected every balloon. + if ((obj64->bossFlag == WARP_BOSS_REMATCH) && (settings->balloonsPtr[settings->worldId] < 8)) { enableWarp = FALSE; } + // The above ensures only one of the boss warps is active so they don't overlap. This could also probably have been done in the initialiser. if (enableWarp) { - if (obj->interactObj->distance < obj64->unk10) { - dist = obj64->unk10; + if (obj->interactObj->distance < obj64->radius) { + dist = obj64->radius; racerObjects = get_racer_objects(&numberOfRacers); for (i = 0; i < numberOfRacers; i++) { racerObj = racerObjects[i]; racer = &racerObj->unk64->racer; - if ((racer->playerIndex != PLAYER_COMPUTER) && (racer->unk108 == 0)) { + if ((racer->playerIndex != PLAYER_COMPUTER) && (racer->exitObj == NULL)) { diffX = racerObj->segment.trans.x_position - obj->segment.trans.x_position; diffY = racerObj->segment.trans.y_position - obj->segment.trans.y_position; diffZ = racerObj->segment.trans.z_position - obj->segment.trans.z_position; if ((sqrtf((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ)) < dist)) { - temp = (obj64->unk0 * racerObj->segment.trans.x_position) + (obj64->unk8 * racerObj->segment.trans.z_position) + obj64->unkC; - if (temp < 0.0f) { - racer->unk108 = obj; + rotDiff = (obj64->directionX * racerObj->segment.trans.x_position) + (obj64->directionZ * racerObj->segment.trans.z_position) + obj64->rotationDiff; + if (rotDiff < 0.0f) { + racer->exitObj = obj; racer->transitionTimer = -120; } } @@ -2020,7 +2023,6 @@ void func_80039320(s16 voiceClip) { //Set to SOUND_VOICE_TAJ_CHALLENGE_RACE in func_800CC7C D_8011D4E2 = voiceClip; } - /** * Hub world Taj loop behaviour. * Handles all the behaviour for the Taj NPC found in the overworld. @@ -2062,8 +2064,8 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { taj = (Object_NPC *) obj->unk64; levelHeader = get_current_level_header(); obj->unk74 = 0; - if (obj->segment.animFrame == 0 && taj->unk4 > 1.0) { - taj->unk4 = 0.0f; + if (obj->segment.animFrame == 0 && taj->animFrameF > 1.0) { + taj->animFrameF = 0.0f; } distance = 0.0f; obj->segment.x_velocity = 0.0f; @@ -2125,13 +2127,13 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { obj->action = 10; sp6B = 1; } - func_80030750(0, &taj->unk20, &taj->unk22, &taj->unk11, &taj->unk12, &taj->unk13); - func_80030DE0(0, 0xFF, 0, 0x78, 0x3C0, 0x44C, 0xF0); - taj->unk4 = 0.0f; + get_fog_settings(PLAYER_ONE, &taj->fogNear, &taj->fogFar, &taj->fogR, &taj->fogG, &taj->fogB); + func_80030DE0(PLAYER_ONE, 255, 0, 120, 960, 1100, 240); + taj->animFrameF = 0.0f; } if (!(obj->action == TAJ_MODE_ROAM || obj->action == TAJ_MODE_RACE || obj->action == TAJ_MODE_TELEPORT_AWAY_BEGIN || obj->action == TAJ_MODE_TELEPORT_AWAY_END)) { - func_8005A3B0(); + disable_racer_input(); func_800AB194(3); } @@ -2162,7 +2164,6 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { func_8006F388(1); break; } - if (obj->action != TAJ_MODE_ROAM && var_a2_2 != 0 && obj->action < 4) { obj->action = TAJ_MODE_DIALOGUE; } @@ -2171,7 +2172,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { obj->segment.unk38.byte.unk3B = 0; taj->unkD = 0xFF; if (distance < 100.0) { - func_8005A3C0(); + racer_set_dialogue_camera(); } if (distance > 10.0) { arctan = (arctan2_f(xPosDiff / distance, zPosDiff / distance) - (obj->segment.trans.y_rotation & 0xFFFF)) + 0x8000; @@ -2189,19 +2190,19 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { if (arctan > 0x800 || arctan < -0x800) { var_f2 = -0.5f; } - taj->unk14 += (var_f2 - taj->unk14) * 0.125; - obj->segment.x_velocity = sins_f(obj->segment.trans.y_rotation) * taj->unk14; - obj->segment.z_velocity = coss_f(obj->segment.trans.y_rotation) * taj->unk14; - taj->unk4 -= taj->unk14 * 2 * updateRateF; + taj->forwardVel += (var_f2 - taj->forwardVel) * 0.125; + obj->segment.x_velocity = sins_f(obj->segment.trans.y_rotation) * taj->forwardVel; + obj->segment.z_velocity = coss_f(obj->segment.trans.y_rotation) * taj->forwardVel; + taj->animFrameF -= taj->forwardVel * 2 * updateRateF; } else { obj->action = TAJ_MODE_TURN_TOWARDS_PLAYER; } move_object(obj, obj->segment.x_velocity * updateRateF, obj->segment.y_velocity * updateRateF, obj->segment.z_velocity * updateRateF); break; case TAJ_MODE_TURN_TOWARDS_PLAYER: - func_8005A3C0(); + racer_set_dialogue_camera(); obj->segment.unk38.byte.unk3B = 0; - taj->unk4 += updateRateF * 2.0; + taj->animFrameF += updateRateF * 2.0; arctan = (racerObj->segment.trans.y_rotation - (obj->segment.trans.y_rotation & 0xFFFF)) + 0x8000; if (arctan > 0x8000) { arctan -= 0xFFFF; @@ -2215,7 +2216,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { obj->segment.trans.y_rotation += arctan >> 3; if (arctan < 0x400 && arctan > -0x400 && distance < 2.0) { obj->action = TAJ_MODE_GREET_PLAYER; - taj->unk4 = 0; + taj->animFrameF = 0; play_taj_voice_clip(D_8011D4E2, 1); D_8011D4E2 = SOUND_VOICE_TAJ_HELLO; } @@ -2226,10 +2227,10 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { break; case TAJ_MODE_GREET_PLAYER: obj->segment.unk38.byte.unk3B = 1; - taj->unk14 = 0.0f; - taj->unk4 += updateRateF * 1.0; - if (taj->unk4 > 77.0) { - taj->unk4 = 77.0; + taj->forwardVel = 0.0f; + taj->animFrameF += updateRateF * 1.0; + if (taj->animFrameF > 77.0) { + taj->animFrameF = 77.0; taj->unk18 = -1.0f; obj->action = TAJ_MODE_DIALOGUE; } @@ -2244,19 +2245,19 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { arctan = 16; } obj->segment.trans.y_rotation = obj->segment.trans.y_rotation + (arctan >> 4); - func_8005A3C0(); + racer_set_dialogue_camera(); break; case TAJ_MODE_DIALOGUE: obj->segment.unk38.byte.unk3B = 4; - taj->unk4 += updateRateF * 1.0; - func_8005A3C0(); + taj->animFrameF += updateRateF * 1.0; + racer_set_dialogue_camera(); if (var_a2_2 == 3 || var_a2_2 == 4) { obj->action = (var_a2_2 == 4) ? TAJ_MODE_END_DIALOGUE_UNUSED : TAJ_MODE_END_DIALOGUE; - taj->unk4 = 0.1f; + taj->animFrameF = 0.1f; obj->segment.unk38.byte.unk3B = 2; taj->unk1C = 0; play_taj_voice_clip(SOUND_VOICE_TAJ_BYE, 1); - func_80030DE0(0, taj->unk11, taj->unk12, taj->unk13, taj->unk20, taj->unk22, 0xB4); + func_80030DE0(PLAYER_ONE, taj->fogR, taj->fogG, taj->fogB, taj->fogNear, taj->fogFar, 180); set_music_player_voice_limit(levelHeader->voiceLimit); play_music(levelHeader->music); func_80001074(levelHeader->instruments); @@ -2266,7 +2267,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { D_8011D4E0 = var_a2_2 & 0x7F; if (D_8011D4E0 != racer64->racer.vehicleID) { obj->action = TAJ_MODE_TRANSFORM_BEGIN; - taj->unk4 = 0; + taj->animFrameF = 0; // Voice clips: Abrakadabra, Alakazam, Alakazoom? play_taj_voice_clip((racer64->racer.vehicleID + SOUND_VOICE_TAJ_ABRAKADABRA), 1); } else { @@ -2278,7 +2279,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { if (D_8011D4E0 != racer64->racer.vehicleID) { D_8011D4E0 |= 0x80; obj->action = TAJ_MODE_TRANSFORM_BEGIN; - taj->unk4 = 0.0f; + taj->animFrameF = 0.0f; // Voice clips: Abrakadabra, Alakazam, Alakazoom? play_taj_voice_clip((racer64->racer.vehicleID + SOUND_VOICE_TAJ_ABRAKADABRA), 1); } else { @@ -2286,22 +2287,22 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { transition_begin(&D_800DC978); sp6B = 1; play_taj_voice_clip(SOUND_WHOOSH4, 1); - taj->unk4 = 0.0f; + taj->animFrameF = 0.0f; } } break; case TAJ_MODE_TRANSFORM_BEGIN: obj->segment.unk38.byte.unk3B = 5; - func_8005A3C0(); - taj->unk4 += updateRateF * 2.0; - if (taj->unk4 > 25.0) { + racer_set_dialogue_camera(); + taj->animFrameF += updateRateF * 2.0; + if (taj->animFrameF > 25.0) { obj->unk74 = 11; } - if (taj->unk4 > 50.0) { + if (taj->animFrameF > 50.0) { obj->unk74 = 0; } - if (taj->unk4 > 60.0) { - taj->unk4 = 60.0f; + if (taj->animFrameF > 60.0) { + taj->animFrameF = 60.0f; if (racer64->racer.transparency > (updateRate * 16)) { racer64->racer.transparency -= (updateRate * 16); } else { @@ -2314,10 +2315,10 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { } break; case TAJ_MODE_TRANSFORM_END: - func_8005A3C0(); + racer_set_dialogue_camera(); if (racerObj != NULL) { - if (taj->unk4 != 0.0f) { - taj->unk4 += 8.0; + if (taj->animFrameF != 0.0f) { + taj->animFrameF += 8.0; } var_a2 = updateRate; if (var_a2 > 4) { @@ -2328,13 +2329,13 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { racer64->racer.transparency += var_a2; } else { racer64->racer.transparency = 255; - if (taj->unk4 == 0.0) { + if (taj->animFrameF == 0.0) { if (D_8011D4E0 & 0x80) { transition_begin(&D_800DC978); sp6B = 1; obj->action = TAJ_MODE_SET_CHALLENGE; play_sound_global(SOUND_WHOOSH4, NULL); - taj->unk4 = 0.0f; + taj->animFrameF = 0.0f; } else { obj->action = TAJ_MODE_DIALOGUE; set_menu_id_if_option_equal(0x62, 2); @@ -2345,10 +2346,10 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { break; case TAJ_MODE_END_DIALOGUE: case TAJ_MODE_END_DIALOGUE_UNUSED: - if (taj->unk4 != 0.0) { - taj->unk4 = taj->unk4 + (0.5 * updateRateF); + if (taj->animFrameF != 0.0) { + taj->animFrameF = taj->animFrameF + (0.5 * updateRateF); } - if (taj->unk4 == 0) { + if (taj->animFrameF == 0) { sp6B = 1; if (obj->action == TAJ_MODE_END_DIALOGUE_UNUSED) { func_80022CFC( @@ -2366,14 +2367,14 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { case TAJ_MODE_TELEPORT_TO_PLAYER_BEGIN: obj->segment.unk38.byte.unk3B = 3; taj->unkD = 0xFF; - taj->unk14 = 0.0f; - taj->unk4 += updateRateF * 2.0; - if (taj->unk4 > 79.0f) { - taj->unk4 = 79.0f; + taj->forwardVel = 0.0f; + taj->animFrameF += updateRateF * 2.0; + if (taj->animFrameF > 79.0f) { + taj->animFrameF = 79.0f; } var_a2 = updateRate * 8; - if (taj->unk4 < 20.0f) { + if (taj->animFrameF < 20.0f) { var_a2 = 0; } if (obj->segment.unk38.byte.unk39 > var_a2) { @@ -2391,9 +2392,9 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { break; case TAJ_MODE_TELEPORT_TO_PLAYER_END: obj->segment.unk38.byte.unk3B = 3; - taj->unk4 -= updateRateF * 2.0; - if (taj->unk4 < 0.0f) { - taj->unk4 = 0.0f; + taj->animFrameF -= updateRateF * 2.0; + if (taj->animFrameF < 0.0f) { + taj->animFrameF = 0.0f; } var_a2 = updateRate * 4; if (obj->segment.unk38.byte.unk39 < (255 - var_a2)) { @@ -2406,20 +2407,20 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { case TAJ_MODE_SET_CHALLENGE: obj->segment.unk38.byte.unk3B = 3; taj->unkD = 0xFF; - taj->unk14 = 0.0f; - taj->unk4 += updateRateF * 2.0; - if (taj->unk4 > 79.0f) { - taj->unk4 = 79.0f; + taj->forwardVel = 0.0f; + taj->animFrameF += updateRateF * 2.0; + if (taj->animFrameF > 79.0f) { + taj->animFrameF = 79.0f; } var_a2 = updateRate * 8; - if (taj->unk4 < 20.0f) { + if (taj->animFrameF < 20.0f) { var_a2 = 0; } if (obj->segment.unk38.byte.unk39 > var_a2) { obj->segment.unk38.byte.unk39 -= var_a2; } else { racer64->racer.unk118 = func_80004B40(racer64->racer.characterId, racer64->racer.vehicleID); - func_80030DE0(0, taj->unk11, taj->unk12, taj->unk13, taj->unk20, taj->unk22, 0xB4); + func_80030DE0(PLAYER_ONE, taj->fogR, taj->fogG, taj->fogB, taj->fogNear, taj->fogFar, 180); set_music_player_voice_limit(levelHeader->voiceLimit); play_music(levelHeader->music); func_80001074(levelHeader->instruments); @@ -2437,13 +2438,13 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { case TAJ_MODE_TELEPORT_AWAY_BEGIN: obj->segment.unk38.byte.unk3B = 3; taj->unkD = 0xFF; - taj->unk14 = 0.0f; - taj->unk4 += updateRateF * 2.0; - if (taj->unk4 > 79.0f) { - taj->unk4 = 79.0f; + taj->forwardVel = 0.0f; + taj->animFrameF += updateRateF * 2.0; + if (taj->animFrameF > 79.0f) { + taj->animFrameF = 79.0f; } var_a2 = updateRate * 8; - if (taj->unk4 < 20.0f) { + if (taj->animFrameF < 20.0f) { var_a2 = 0; } if (obj->segment.unk38.byte.unk39 > var_a2) { @@ -2462,9 +2463,9 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { break; case TAJ_MODE_TELEPORT_AWAY_END: obj->segment.unk38.byte.unk3B = 3; - taj->unk4 -= updateRateF * 2.0; - if (taj->unk4 < 0.0f) { - taj->unk4 = 0.0f; + taj->animFrameF -= updateRateF * 2.0; + if (taj->animFrameF < 0.0f) { + taj->animFrameF = 0.0f; } var_a2 = updateRate * 4; if (obj->segment.unk38.byte.unk39 < (0xFF - var_a2)) { @@ -2478,11 +2479,11 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { obj->interactObj->unk14 = 0; obj->segment.unk38.byte.unk3B = 6; obj->segment.unk38.byte.unk39 = 0xFF; - taj->unk4 += updateRateF * 1.0; + taj->animFrameF += updateRateF * 1.0; break; default: obj->segment.unk38.byte.unk3B = 0; - taj->unk14 = 0.0f; + taj->forwardVel = 0.0f; if (taj->unkD == 0xFF) { taj->unkD = func_8001C524(obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position, 0); if (taj->unkD != 0xFF) { @@ -2502,7 +2503,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { taj->unk1C = 0; } if (taj->unk1C < 120) { - taj->unk4 += func_8001C6C4((Object_64*)taj, obj, updateRateF, 1.0f, 0); + taj->animFrameF += func_8001C6C4((Object_64*)taj, obj, updateRateF, 1.0f, 0); } else { var_a2 = taj->unk1E - (obj->segment.trans.y_rotation & 0xFFFF); if (var_a2 > 0x8000) { @@ -2520,7 +2521,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { 0.0f, (updateRateF2 * zPosDiff) * 1.1 ); - taj->unk4 += updateRate * 2.2; + taj->animFrameF += updateRate * 2.2; } } racerObjs = get_racer_objects(&numRacers); @@ -2532,7 +2533,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { if (var_f2 < 1000.0f) { var_f2 = 1000.0f - var_f2; sp3C = (127.0f * var_f2) / 1000.0f; - temp_v0_22 = func_80069D7C(); + temp_v0_22 = get_cutscene_camera_segment(); xPosDiff = obj->segment.trans.x_position - temp_v0_22->trans.x_position; zPosDiff = obj->segment.trans.z_position - temp_v0_22->trans.z_position; arctan = func_800090C0(xPosDiff, zPosDiff, temp_v0_22->trans.y_rotation); @@ -2620,7 +2621,7 @@ void obj_loop_parkwarden(Object *obj, s32 updateRate) { if (sp6B != 0) { func_8003FC44(obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position, 0xC, 0, 1.0f, 0); } - obj->segment.animFrame = taj->unk4 * 1.0; + obj->segment.animFrame = taj->animFrameF * 1.0; func_80061C0C(obj); func_800AFC3C(obj, updateRate); } @@ -2646,17 +2647,26 @@ f32 func_8003ACAC(void) { return D_8011D4D0; } +/** + * Checkpoint initialisation function. + * Sets direction and scale based off spawn info. + * Uses bit shifting to convert a u8 angle to an s16 angle. +*/ void obj_init_checkpoint(Object *obj, LevelObjectEntry_Checkpoint *entry, UNUSED s32 arg2) { - f32 phi_f0 = (s32)(entry->unk8 & 0xFF); - if (phi_f0 < 5.0f) { - phi_f0 = 5.0f; + f32 scale = (s32) (entry->scale & 0xFF); + if (scale < 5.0f) { + scale = 5.0f; } - phi_f0 /= 64; - obj->segment.trans.scale = phi_f0; - obj->segment.trans.y_rotation = entry->unkA << 6 << 4; // Not sure about the values here. + scale /= 64; + obj->segment.trans.scale = scale; + obj->segment.trans.y_rotation = entry->yRotation << 6 << 4; // Not sure about the values here. func_80011390(); } +/** + * Checkpoint initialisation function. + * Does nothing, since the racers themselves iterate checkpoints and use their data. +*/ void obj_loop_checkpoint(UNUSED Object *obj, UNUSED s32 updateRate) { } @@ -2812,15 +2822,15 @@ void obj_loop_bonus(Object *obj, UNUSED s32 updateRate) { } } void obj_init_goldenballoon(Object *obj, LevelObjectEntry_GoldenBalloon *entry) { - Object_GoldenBalloon *obj64; + Object_NPC *obj64; f32 scalef; - if (entry->unk8 == -1) { - entry->unk8 = func_8000CC20(obj); + if (entry->balloonID == -1) { + entry->balloonID = func_8000CC20(obj); } else { - func_8000CBF0(obj, entry->unk8); + func_8000CBF0(obj, entry->balloonID); } - if (entry->unk8 == -1) { + if (entry->balloonID == -1) { rmonPrintf("Illegal door no!!!\n"); // Did the devs just copy-paste the door init function? } obj->interactObj->unk14 = 2; @@ -2833,12 +2843,12 @@ void obj_init_goldenballoon(Object *obj, LevelObjectEntry_GoldenBalloon *entry) } scalef /= 64; obj->segment.trans.scale = obj->segment.header->scale * scalef; - obj64 = &obj->unk64->golden_balloon; + obj64 = &obj->unk64->npc; obj64->unkD = 255; obj64->unk0 = 0.0f; obj->action = 0; - if (entry->unkA != 0) { - if ((get_settings()->tajFlags & (1 << (entry->unkA + 2))) != 0) { + if (entry->challengeID) { + if (get_settings()->tajFlags & (1 << (entry->challengeID + 2))) { obj->action = 0; } else { obj->action = 1; @@ -2850,7 +2860,7 @@ void obj_loop_goldenballoon(Object *obj, s32 updateRate) { LevelObjectEntry *levelEntry; ObjectInteraction *obj4C; Object_Racer *racer; - Object_GoldenBalloon *obj64; + Object_NPC *obj64; Settings *settings; s32 flag; s32 doubleSpeed; @@ -2871,7 +2881,7 @@ void obj_loop_goldenballoon(Object *obj, s32 updateRate) { speedf = updateRateF; settings = get_settings(); levelEntry = obj->segment.unk3C_a.level_entry; - flag = 0x10000 << levelEntry->goldenBalloon.unk8; + flag = 0x10000 << levelEntry->goldenBalloon.balloonID; if (settings->courseFlagsPtr[settings->courseId] & flag) { if (obj->unk7C.word > 0) { obj->unk74 = 2; @@ -2911,9 +2921,9 @@ void obj_loop_goldenballoon(Object *obj, s32 updateRate) { } } } - obj64 = &obj->unk64->golden_balloon; + obj64 = &obj->unk64->npc; obj->segment.unk38.byte.unk3B = 0; - obj64->unk14 = 0.0f; + obj64->forwardVel = 0.0f; speedf = (obj->segment.unk38.byte.unk39 < 255) ? 0 : 1; if (obj64->unkD == 255) { obj64->unkD = func_8001C524(obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position, 0); @@ -3337,10 +3347,10 @@ void obj_loop_seamonster(UNUSED Object *obj, UNUSED s32 updateRate) { /* Official name: fogInit(?) */ void obj_init_fogchanger(Object *obj, LevelObjectEntry_FogChanger *entry) { - f32 temp_f0; - temp_f0 = entry->unk8 * 8.0f; - temp_f0 = temp_f0 * temp_f0; - obj->unk78f = temp_f0; + f32 dist; + dist = entry->distance * 8.0f; + dist = dist * dist; + obj->unk78f = dist; } void obj_init_skycontrol(Object *obj, LevelObjectEntry_SkyControl *entry) { diff --git a/src/object_functions.h b/src/object_functions.h index bb6c705d..1fe84e7a 100644 --- a/src/object_functions.h +++ b/src/object_functions.h @@ -12,6 +12,12 @@ #define TIME_JIFFIES_PER_SECOND 60 #define TIME_SECONDS(sec) sec * TIME_JIFFIES_PER_SECOND +enum BossRaceWarps { + WARP_STANDARD = -1, + WARP_BOSS_FIRST, + WARP_BOSS_REMATCH, +}; + enum TajBehaviours { TAJ_MODE_ROAM, TAJ_MODE_APPROACH_PLAYER, diff --git a/src/objects.c b/src/objects.c index 4f0cc895..8ace9506 100644 --- a/src/objects.c +++ b/src/objects.c @@ -2693,8 +2693,8 @@ s32 func_8001C48C(Object *obj) { s32 func_8001C524(f32 diffX, f32 diffY, f32 diffZ, s32 someFlag) { UNUSED f32 pad[6]; s32 sp64; - f32 x; f32 len; + f32 x; f32 z; f32 y; f32 dist; diff --git a/src/racer.c b/src/racer.c index 1454a8c7..9afd6dc3 100644 --- a/src/racer.c +++ b/src/racer.c @@ -196,8 +196,8 @@ f32 gRacerMagnetVelZ; u8 D_8011D580; s8 gCurrentSurfaceType; s8 D_8011D582; -s8 D_8011D583; -s8 D_8011D584; +s8 gRacerDialogueCamera; +s8 gRacerInputBlocked; s8 gStartBoostTime; s16 gDialogueCameraAngle; s8 D_8011D588[4]; @@ -822,7 +822,7 @@ void func_80046524(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *r } sp11C = sp11C * 3.0f; spF4 = (sp11C * sp11C) / 9.0f; - if (racer->unk108 != 0) { + if (racer->exitObj != 0) { racer->throttle = 0.5f; } if (racer->velocity > 0.0) { @@ -1177,7 +1177,7 @@ void func_80046524(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *r obj->segment.x_velocity += racer->ox1 * spF0; obj->segment.y_velocity += racer->oy1 * spF0; obj->segment.z_velocity += racer->oz1 * spF0; - if (((racer->unk1E2 != 0) && (D_8011D584 == 0)) && (gRaceStartTimer == 0)) { + if (((racer->unk1E2 != 0) && (gRacerInputBlocked == 0)) && (gRaceStartTimer == 0)) { temp_f2 = (gCurrentRacerWeightStat * updateRateF) * 0.25; sp11C = racer->pitch * temp_f2; temp_f2 = temp_f2 * racer->roll; @@ -1222,7 +1222,7 @@ void func_80046524(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *r var_f16 += racer->unk11C; var_f12 += racer->unk120; } - if (D_8011D584 != 0) { + if (gRacerInputBlocked != 0) { if ((var_f16 > 0.5) || (var_f16 < (-0.5))) { var_f16 *= 0.65; } else { @@ -2162,9 +2162,9 @@ void obj_init_racer(Object *obj, LevelObjectEntry_CharacterFlag *racer) { update_player_camera(obj, tempRacer, 1.0f); } if (!D_8011D582) { - D_8011D583 = 0; + gRacerDialogueCamera = FALSE; gDialogueCameraAngle = 0; - D_8011D584 = 0; + gRacerInputBlocked = FALSE; } obj->interactObj->unk14 = 5; obj->interactObj->unk11 = 0; @@ -2186,7 +2186,7 @@ void obj_init_racer(Object *obj, LevelObjectEntry_CharacterFlag *racer) { } if (1) {} if (1) {} // Fakematch func_80043ECC(NULL, NULL, 0); - D_8011D583 = i; + gRacerDialogueCamera = i; gStartBoostTime = 0; tempRacer->lightFlags = 0; } @@ -2360,7 +2360,7 @@ void update_player_racer(Object *obj, s32 updateRate) { } tempVar = tempRacer->playerIndex; if (tempRacer->playerIndex != PLAYER_COMPUTER) { - if (tempRacer->unk108 == 0) { + if (tempRacer->exitObj == 0) { if (func_8000E158()) { tempVar = 1 - tempVar; } @@ -2384,7 +2384,7 @@ void update_player_racer(Object *obj, s32 updateRate) { if (!(gCurrentRacerInput & A_BUTTON)) { tempRacer->throttleReleased = TRUE; } - if (check_if_showing_cutscene_camera() || gRaceStartTimer == 100 || tempRacer->unk1F1 || D_8011D584 || tempRacer->approachTarget || tempRacer->unk204 > 0) { + if (check_if_showing_cutscene_camera() || gRaceStartTimer == 100 || tempRacer->unk1F1 || gRacerInputBlocked || tempRacer->approachTarget || tempRacer->unk204 > 0) { gCurrentStickX = 0; gCurrentStickY = 0; gCurrentRacerInput = 0; @@ -2590,7 +2590,7 @@ void update_player_racer(Object *obj, s32 updateRate) { } tempRacer->playerIndex = gCurrentPlayerIndex; update_player_camera(obj, tempRacer, updateRateF); - D_8011D583 = 0; + gRacerDialogueCamera = FALSE; if (tempRacer->approachTarget) { tempRacer->approachTarget = NULL; tempRacer->velocity = 0.0f; @@ -2651,7 +2651,7 @@ void update_player_racer(Object *obj, s32 updateRate) { if (tempRacer->soundMask) { update_spatial_audio_position(tempRacer->soundMask, obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position); } - D_8011D584 = 0; + gRacerInputBlocked = 0; if (tempRacer->unk150 && gRaceStartTimer == 0) { s8 *yAsset; tempRacer->unk150->segment.trans.x_position = obj->segment.trans.x_position; @@ -4695,7 +4695,7 @@ void racer_activate_magnet(Object *obj, Object_Racer *racer, s32 updateRate) { */ void racer_play_sound(Object *obj, s32 soundID) { Object_Racer *racer = &obj->unk64->racer; - if (gCurrentPlayerIndex != PLAYER_COMPUTER && racer->unk108 == 0) { + if (gCurrentPlayerIndex != PLAYER_COMPUTER && racer->exitObj == 0) { play_sound_spatial(soundID, obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position, NULL); } } @@ -4717,7 +4717,7 @@ void play_random_character_voice(Object *obj, s32 soundID, s32 range, s32 flags) Object_Racer *tempRacer; tempRacer = (Object_Racer *) obj->unk64; - if (tempRacer->unk108 == 0 && (!(flags & 0x80) || gCurrentPlayerIndex != PLAYER_COMPUTER)) { + if (tempRacer->exitObj == 0 && (!(flags & 0x80) || gCurrentPlayerIndex != PLAYER_COMPUTER)) { if (flags == 2) { if (tempRacer->soundMask != NULL && soundID != tempRacer->unk2A) { func_800096F8(tempRacer->soundMask); @@ -4990,7 +4990,7 @@ void update_player_camera(Object *obj, Object_Racer *racer, f32 updateRateF) { if (racer->raceFinished == TRUE && gCameraObject->mode != CAMERA_FINISH_CHALLENGE) { gCameraObject->mode = CAMERA_FINISH_RACE; } - if (racer->unk108) { + if (racer->exitObj) { gCameraObject->mode = CAMERA_FIXED; } // Set the camera behaviour based on current mode. @@ -5048,7 +5048,7 @@ void update_player_camera(Object *obj, Object_Racer *racer, f32 updateRateF) { } angle = ((angle >> 4) + 4); tempUpdateRateF = updateRateF; - if (D_8011D583) { + if (gRacerDialogueCamera) { gDialogueCameraAngle += (tempUpdateRateF * angle); if (gDialogueCameraAngle > 0x2800) { gDialogueCameraAngle = 0x2800; @@ -5665,12 +5665,20 @@ s16 func_80059E20(void) { GLOBAL_ASM("asm/non_matchings/racer/set_ghost_position_and_rotation.s") -void func_8005A3B0(void) { - D_8011D584 = 1; +/** + * Blocks the player's movement until the end of their update cycle. + * Called for every frame the player shouldn't be able to drive. +*/ +void disable_racer_input(void) { + gRacerInputBlocked = TRUE; } -void func_8005A3C0(void) { - D_8011D583 = 1; +/** + * Tells the camera to start rotating to the side for the dialogue camera. + * Called for every frame the player should experience subtle cinematography. +*/ +void racer_set_dialogue_camera(void) { + gRacerDialogueCamera = TRUE; } /** @@ -5697,13 +5705,13 @@ void compare_balloon_checksums(void) { * After a timer hits 0, execute the transition. */ void racer_enter_door(Object_Racer* racer, s32 updateRate) { - struct Object_Exit *temp_a3; + struct Object_Exit *exit; f32 updateRateF; s32 angle; - temp_a3 = (struct Object_Exit *) racer->unk108->unk64; + exit = (struct Object_Exit *) racer->exitObj->unk64; racer->playerIndex = PLAYER_COMPUTER; - angle = (u16) arctan2_f(temp_a3->unk0, temp_a3->unk8) - (racer->steerVisualRotation & 0xFFFF); + angle = (u16) arctan2_f(exit->directionX, exit->directionZ) - (racer->steerVisualRotation & 0xFFFF); WRAP(angle, -0x8000, 0x8000); angle = -angle >> 5; gCurrentStickX = angle; @@ -5717,8 +5725,8 @@ void racer_enter_door(Object_Racer* racer, s32 updateRate) { gCurrentRacerInput |= B_BUTTON; } updateRateF = (f32) updateRate; - gCameraObject->trans.x_position += (temp_a3->unk0 * updateRateF) * 1.5; - gCameraObject->trans.z_position += (temp_a3->unk8 * updateRateF) * 1.5; + gCameraObject->trans.x_position += (exit->directionX * updateRateF) * 1.5; + gCameraObject->trans.z_position += (exit->directionZ * updateRateF) * 1.5; if (gCurrentStickX > 75) { gCurrentStickX = 75; gCurrentRacerInput |= A_BUTTON | B_BUTTON; } // Only matches if it's on the same line if (gCurrentStickX < -75) { gCurrentStickX = -75; @@ -5740,7 +5748,7 @@ void racer_enter_door(Object_Racer* racer, s32 updateRate) { if (racer->transitionTimer > 0) { racer->transitionTimer -= updateRate; if (racer->transitionTimer <= 0) { - func_8006D968((s8* ) racer->unk108->segment.unk3C_a.level_entry); + func_8006D968((s8* ) racer->exitObj->segment.unk3C_a.level_entry); racer->transitionTimer = 0; } } @@ -6018,7 +6026,7 @@ void update_AI_racer(Object *obj, Object_Racer *racer, s32 updateRate, f32 updat if (racer->soundMask != 0) { update_spatial_audio_position(racer->soundMask, obj->segment.trans.x_position, obj->segment.trans.y_position, obj->segment.trans.z_position); } - D_8011D584 = 0; + gRacerInputBlocked = FALSE; if ((racer->unk150 != NULL) && (gRaceStartTimer == 0)) { s8 *temp; racer->unk150->segment.trans.x_position = obj->segment.trans.x_position; diff --git a/src/racer.h b/src/racer.h index 2cd88855..91e94d88 100644 --- a/src/racer.h +++ b/src/racer.h @@ -172,8 +172,8 @@ s32 load_tt_ghost(s32 ghostOffset, s32 size, s16 *outTime); void free_tt_ghost_data(void); s32 func_80059B7C(s32 controllerIndex, s32 mapId, s16 arg2, s16 arg3, s16 arg4); s16 func_80059E20(void); -void func_8005A3B0(void); -void func_8005A3C0(void); +void disable_racer_input(void); +void racer_set_dialogue_camera(void); void compare_balloon_checksums(void); void antipiracy_modify_surface_traction_table(void); s32 turn_head_towards_object(Object *obj, Object_Racer *racer, Object *targetObj, f32 distance); diff --git a/src/textures_sprites.h b/src/textures_sprites.h index 29097d6b..88502a5c 100644 --- a/src/textures_sprites.h +++ b/src/textures_sprites.h @@ -49,7 +49,7 @@ extern s32 D_800DE7C4; extern Gfx D_800DF1A8[32][2]; extern Gfx *gSceneCurrDisplayList; -extern s32 D_8011B0FC; +extern s32 gAntiAliasing; extern u32 D_8011D384; extern LevelHeader *gCurrentLevelHeader2; extern s32 gCurrentRenderFlags; diff --git a/src/unknown_0255E0.c b/src/unknown_0255E0.c index ffc665a3..22f5b0c8 100644 --- a/src/unknown_0255E0.c +++ b/src/unknown_0255E0.c @@ -31,6 +31,7 @@ /************ .data ************/ s32 D_800DC870 = 0; // Currently unknown, might be a different type. +//!@bug These two transition effects are marked to not clear when done, meaning they stay active the whole time. unknown800DC874 D_800DC874 = { { -128 }, 40, -1 }; unknown800DC874 D_800DC87C = { { -125 }, 70, -1 }; @@ -96,7 +97,7 @@ f32 D_8011B0EC; s32 D_8011B0F0; s32 D_8011B0F4; s32 D_8011B0F8; -s32 D_8011B0FC; +s32 gAntiAliasing; s32 D_8011B100; s32 D_8011B104; s32 D_8011B108; @@ -158,7 +159,7 @@ s32 D_8011D378; s32 gScenePlayerViewports; UNUSED f32 gCurrBBoxDistanceToCamera; // Used in a comparison check, but functionally unused. u32 D_8011D384; -unk8011D388 D_8011D388[4]; +FogData gFogData[4]; Vec3i gScenePerspectivePos; unk8011D474 *D_8011D474; // 0x10 bytes struct? unk8011D478 *D_8011D478; // 0x8 bytes struct? @@ -244,7 +245,7 @@ void func_800249F0(u32 arg0, u32 arg1, s32 arg2, Vehicle vehicle, u32 arg4, u32 transition_begin(&D_800DC874); } set_active_viewports_and_max(gScenePlayerViewports); - D_8011B0FC = 0; + gAntiAliasing = 0; i = 0; do { D_8011D350[i] = allocate_from_main_pool_safe(3200, COLOUR_TAG_YELLOW); @@ -313,10 +314,10 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, gDrawLevelSegments = TRUE; if (gCurrentLevelHeader2->race_type == RACETYPE_CUTSCENE_2) { gDrawLevelSegments = FALSE; - D_8011B0FC = 1; + gAntiAliasing = TRUE; } if (gCurrentLevelHeader2->race_type == RACETYPE_CUTSCENE_1 || gCurrentLevelHeader2->unkBD) { - D_8011B0FC = 1; + gAntiAliasing = TRUE; } if (gCurrentLevelHeader2->unk49 == -1) { i = (gCurrentLevelHeader2->unkA4->width << 9) - 1; @@ -340,7 +341,7 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, gDPSetPrimColor(gSceneCurrDisplayList++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(gSceneCurrDisplayList++, 255, 255, 255, 0); func_800AD40C(); - func_80030838(numViewports, tempUpdateRate); + update_fog(numViewports, tempUpdateRate); func_800AF404(tempUpdateRate); if (gCurrentLevelModel->numberOfAnimatedTextures > 0) { func_80027E24(tempUpdateRate); @@ -355,7 +356,7 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, if (flip) { gSPSetGeometryMode(gSceneCurrDisplayList++, G_CULL_FRONT); } - func_8003093C(gSceneCurrentPlayerID); + apply_fog(gSceneCurrentPlayerID); gDPPipeSync(gSceneCurrDisplayList++); set_active_camera(gSceneCurrentPlayerID); func_80066CDC(&gSceneCurrDisplayList, &gSceneCurrMatrix); @@ -389,7 +390,7 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, if (flip) { gSPSetGeometryMode(gSceneCurrDisplayList++, G_CULL_FRONT); } - func_8003093C(3); + apply_fog(PLAYER_FOUR); gDPPipeSync(gSceneCurrDisplayList++); set_active_camera(3); disable_cutscene_camera(); @@ -806,8 +807,6 @@ void render_skydome(void) { } } -void func_800B8C04(s32, s32, s32, s32, s32); - /** * Sets up all of the required variables for the player's view perspective. * This includes setting up the camera index, viewport and @@ -851,9 +850,12 @@ void initialise_player_viewport_vars(s32 updateRate) { render_level_geometry_and_objects(); } - -void func_80028FA0(s32 arg0) { - D_8011B0FC = arg0; +/** + * Enable or disable anti aliasing. + * Improves visual quality at the cost of performance. +*/ +void set_anti_aliasing(s32 setting) { + gAntiAliasing = setting; } /** @@ -876,7 +878,7 @@ void render_level_geometry_and_objects(void) { func_80012C30(); if (get_settings()->courseId == ASSET_LEVEL_OPENINGSEQUENCE) { - D_8011B0FC = 1; + gAntiAliasing = 1; } sp160 = func_80014814(&sp16C); @@ -1012,7 +1014,7 @@ skip: if (D_800DC924 && func_80027568()) { func_8002581C(segmentIds, numberOfSegments, get_current_viewport()); } - D_8011B0FC = 0; + gAntiAliasing = FALSE; } /** @@ -1059,14 +1061,14 @@ void render_level_segment(s32 segmentId, s32 nonOpaque) { batchFlags = batchInfo->flags; renderBatch = 0; if (batchInfo->textureIndex == 0xFF) { - texture = 0; + texture = FALSE; } else { texture = gCurrentLevelModel->textures[batchInfo->textureIndex].texture; textureFlags = texture->flags; } batchFlags |= BATCH_FLAGS_UNK00000008 | BATCH_FLAGS_UNK00000002; if (!(batchFlags & BATCH_FLAGS_DEPTH_WRITE) && !(batchFlags & BATCH_FLAGS_UNK00000800)) { - batchFlags |= D_8011B0FC; + batchFlags |= gAntiAliasing; } if ((!(textureFlags & RENDER_SEMI_TRANSPARENT) && !(batchFlags & BATCH_FLAGS_UNK00002000)) || batchFlags & BATCH_FLAGS_UNK00000800) { renderBatch = TRUE; @@ -2259,80 +2261,95 @@ void func_80030664(s32 arg0, s16 arg1, s16 arg2, u8 arg3, u8 arg4, u8 arg5) { if (min >= max - 5) { min = max - 5; } - D_8011D388[arg0].unk20 = 0; - D_8011D388[arg0].unk24 = 0; - D_8011D388[arg0].unk14 = 0; - D_8011D388[arg0].unk18 = 0; - D_8011D388[arg0].unk1C = 0; - D_8011D388[arg0].unk0 = arg3 << 0x10; - D_8011D388[arg0].unk4 = arg4 << 0x10; - D_8011D388[arg0].unk8 = arg5 << 0x10; - D_8011D388[arg0].unkC = min << 0x10; - D_8011D388[arg0].unk10 = max << 0x10; - D_8011D388[arg0].unk28 = arg3; - D_8011D388[arg0].unk2C = min; - D_8011D388[arg0].unk2E = max; - D_8011D388[arg0].unk30 = 0; - D_8011D388[arg0].unk34 = 0; - D_8011D388[arg0].unk29 = arg4; - D_8011D388[arg0].unk2A = arg5; + gFogData[arg0].addFog.near = 0; + gFogData[arg0].addFog.far = 0; + gFogData[arg0].addFog.r = 0; + gFogData[arg0].addFog.g = 0; + gFogData[arg0].addFog.b = 0; + gFogData[arg0].fog.r = arg3 << 0x10; + gFogData[arg0].fog.g = arg4 << 0x10; + gFogData[arg0].fog.b = arg5 << 0x10; + gFogData[arg0].fog.near = min << 0x10; + gFogData[arg0].fog.far = max << 0x10; + gFogData[arg0].intendedFog.r = arg3; + gFogData[arg0].intendedFog.near = min; + gFogData[arg0].intendedFog.far = max; + gFogData[arg0].switchTimer = 0; + gFogData[arg0].fogChanger = 0; + gFogData[arg0].intendedFog.g = arg4; + gFogData[arg0].intendedFog.b = arg5; } #else GLOBAL_ASM("asm/non_matchings/unknown_0255E0/func_80030664.s") #endif -void func_80030750(s32 arg0, s16 *arg1, s16 *arg2, u8 *arg3, u8 *arg4, u8 *arg5) { - *arg1 = D_8011D388[arg0].unkC >> 0x10; - *arg2 = D_8011D388[arg0].unk10 >> 0x10; - *arg3 = D_8011D388[arg0].unk0 >> 0x10; - *arg4 = D_8011D388[arg0].unk4 >> 0x10; - *arg5 = D_8011D388[arg0].unk8 >> 0x10; +/** + * Writes the current fog settings to the arguments. + * Pre-shifts the data, so the raw values are correct. +*/ +void get_fog_settings(s32 playerID, s16 *near, s16 *far, u8 *r, u8 *g, u8 *b) { + *near = gFogData[playerID].fog.near >> 16; + *far = gFogData[playerID].fog.far >> 16; + *r = gFogData[playerID].fog.r >> 16; + *g = gFogData[playerID].fog.g >> 16; + *b = gFogData[playerID].fog.b >> 16; } -void func_800307BC(s32 arg0) { - D_8011D388[arg0].unk20 = 0; - D_8011D388[arg0].unk24 = 0; - D_8011D388[arg0].unk14 = 0; - D_8011D388[arg0].unk18 = 0; - D_8011D388[arg0].unk1C = 0; - D_8011D388[arg0].unkC = 0x03FA0000; - D_8011D388[arg0].unk10 = 0x03FF0000; - D_8011D388[arg0].unk28 = D_8011D388[arg0].unk0 >> 0x10; - D_8011D388[arg0].unk29 = D_8011D388[arg0].unk4 >> 0x10; - D_8011D388[arg0].unk2A = D_8011D388[arg0].unk8 >> 0x10; - D_8011D388[arg0].unk2C = 0x03FA; - D_8011D388[arg0].unk2E = 0x03FF; - D_8011D388[arg0].unk30 = 0; - D_8011D388[arg0].unk34 = 0; +/** + * Sets the fog of the player ID to the default values. + * Current fog attributes are rightshifted 16 bytes. +*/ +void reset_fog(s32 playerID) { + gFogData[playerID].addFog.near = 0; + gFogData[playerID].addFog.far = 0; + gFogData[playerID].addFog.r = 0; + gFogData[playerID].addFog.g = 0; + gFogData[playerID].addFog.b = 0; + gFogData[playerID].fog.near = 1018 << 16; + gFogData[playerID].fog.far = 1023 << 16; + gFogData[playerID].intendedFog.r = gFogData[playerID].fog.r >> 16; + gFogData[playerID].intendedFog.g = gFogData[playerID].fog.g >> 16; + gFogData[playerID].intendedFog.b = gFogData[playerID].fog.b >> 16; + gFogData[playerID].intendedFog.near = 1018; + gFogData[playerID].intendedFog.far = 1023; + gFogData[playerID].switchTimer = 0; + gFogData[playerID].fogChanger = NULL; } -void func_80030838(s32 arg0, s32 arg1) { +/** + * If the fog override timer is active, apply that and slowly degrade. + * Otherwise, set the current fog to the intended fog settings. +*/ +void update_fog(s32 viewportCount, s32 updateRate) { s32 i; - for (i = 0; i < arg0; i++) { - if (D_8011D388[i].unk30 > 0) { - if (arg1 < D_8011D388[i].unk30) { - D_8011D388[i].unk0 += D_8011D388[i].unk14 * arg1; - D_8011D388[i].unk4 += D_8011D388[i].unk18 * arg1; - D_8011D388[i].unk8 += D_8011D388[i].unk1C * arg1; - D_8011D388[i].unkC += D_8011D388[i].unk20 * arg1; - D_8011D388[i].unk10 += D_8011D388[i].unk24 * arg1; - D_8011D388[i].unk30 -= arg1; + for (i = 0; i < viewportCount; i++) { + if (gFogData[i].switchTimer > 0) { + if (updateRate < gFogData[i].switchTimer) { + gFogData[i].fog.r += gFogData[i].addFog.r * updateRate; + gFogData[i].fog.g += gFogData[i].addFog.g * updateRate; + gFogData[i].fog.b += gFogData[i].addFog.b * updateRate; + gFogData[i].fog.near += gFogData[i].addFog.near * updateRate; + gFogData[i].fog.far += gFogData[i].addFog.far * updateRate; + gFogData[i].switchTimer -= updateRate; } else { - D_8011D388[i].unk0 = D_8011D388[i].unk28 << 0x10; - D_8011D388[i].unk4 = D_8011D388[i].unk29 << 0x10; - D_8011D388[i].unk8 = D_8011D388[i].unk2A << 0x10; - D_8011D388[i].unkC = D_8011D388[i].unk2C << 0x10; - D_8011D388[i].unk10 = D_8011D388[i].unk2E << 0x10; - D_8011D388[i].unk30 = 0; + gFogData[i].fog.r = gFogData[i].intendedFog.r << 16; + gFogData[i].fog.g = gFogData[i].intendedFog.g << 16; + gFogData[i].fog.b = gFogData[i].intendedFog.b << 16; + gFogData[i].fog.near = gFogData[i].intendedFog.near << 16; + gFogData[i].fog.far = gFogData[i].intendedFog.far << 16; + gFogData[i].switchTimer = 0; } } } } -void func_8003093C(s32 arg0) { - gDPSetFogColor(gSceneCurrDisplayList++, D_8011D388[arg0].unk0 >> 0x10, D_8011D388[arg0].unk4 >> 0x10, D_8011D388[arg0].unk8 >> 0x10, 0xFF); - gSPFogPosition(gSceneCurrDisplayList++, D_8011D388[arg0].unkC >> 0x10, D_8011D388[arg0].unk10 >> 0x10); +/** + * Sets the fog settings for the active viewport based on the parameters of the environment data. +*/ +void apply_fog(s32 playerID) { + gDPSetFogColor(gSceneCurrDisplayList++, gFogData[playerID].fog.r >> 0x10, gFogData[playerID].fog.g >> 0x10, gFogData[playerID].fog.b >> 0x10, 0xFF); + gSPFogPosition(gSceneCurrDisplayList++, gFogData[playerID].fog.near >> 0x10, gFogData[playerID].fog.far >> 0x10); } /** @@ -2340,7 +2357,7 @@ void func_8003093C(s32 arg0) { * Used in courses to make less, or more dense. */ void obj_loop_fogchanger(Object *obj) { - s32 temp3; + s32 nearTemp; s32 fogNear; s32 views; s32 playerIndex; @@ -2353,20 +2370,20 @@ void obj_loop_fogchanger(Object *obj) { s32 fogB; f32 x; f32 z; - s32 temp_a1; - LevelObjectEntry_FogChanger *sp44; + s32 switchTimer; + LevelObjectEntry_FogChanger *fogChanger; Object **racers; Object_Racer *racer; UNUSED s32 pad2; - unk8011D388 *temp_v0_3; - ObjectSegment *phi_s3; + FogData *fog; + ObjectSegment *camera; racers = NULL; - sp44 = (LevelObjectEntry_FogChanger *) obj->segment.unk3C_a.level_entry; - phi_s3 = NULL; + fogChanger = (LevelObjectEntry_FogChanger *) obj->segment.unk3C_a.level_entry; + camera = NULL; if (check_if_showing_cutscene_camera()) { - phi_s3 = func_80069D7C(); + camera = get_cutscene_camera_segment(); views = get_viewport_count() + 1; } else { racers = get_racer_objects(&views); @@ -2377,31 +2394,32 @@ void obj_loop_fogchanger(Object *obj) { if (racers != NULL) { racer = &racers[i]->unk64->racer; playerIndex = racer->playerIndex; - if (playerIndex >= PLAYER_ONE && playerIndex <= PLAYER_FOUR && obj != D_8011D388[playerIndex].unk34) { + if (playerIndex >= PLAYER_ONE && playerIndex <= PLAYER_FOUR && obj != gFogData[playerIndex].fogChanger) { index = playerIndex; x = racers[i]->segment.trans.x_position; z = racers[i]->segment.trans.z_position; } - } else if (i <= PLAYER_FOUR && obj != D_8011D388[i].unk34) { + } else if (i <= PLAYER_FOUR && obj != gFogData[i].fogChanger) { index = i; - x = phi_s3[i].trans.x_position; - z = phi_s3[i].trans.z_position; + x = camera[i].trans.x_position; + z = camera[i].trans.z_position; } if (index != PLAYER_COMPUTER) { x -= obj->segment.trans.x_position; z -= obj->segment.trans.z_position; if (1) {} // Fakematch if ((x * x) + (z * z) < obj->unk78f) { - fogNear = sp44->unkC; - fogFar = sp44->unkE; - fogR = sp44->unk9; - fogG = sp44->unkA; - fogB = sp44->unkB; - temp_a1 = sp44->unk10; + fogNear = fogChanger->near; + fogFar = fogChanger->far; + fogR = fogChanger->r; + fogG = fogChanger->g; + fogB = fogChanger->b; + switchTimer = fogChanger->switchTimer; + // Swap near and far if they're the wrong way around. if (fogFar < fogNear) { - temp3 = fogNear; + nearTemp = fogNear; fogNear = fogFar; - fogFar = temp3; + fogFar = nearTemp; } if (fogFar > 1023) { fogFar = 1023; @@ -2409,19 +2427,19 @@ void obj_loop_fogchanger(Object *obj) { if (fogNear >= fogFar - 5) { fogNear = fogFar - 5; } - temp_v0_3 = &D_8011D388[index]; - temp_v0_3->unk28 = fogR; - temp_v0_3->unk29 = fogG; - temp_v0_3->unk2A = fogB; - temp_v0_3->unk2C = fogNear; - temp_v0_3->unk2E = fogFar; - temp_v0_3->unk14 = ((fogR << 16) - temp_v0_3->unk0) / temp_a1; - temp_v0_3->unk18 = ((fogG << 16) - temp_v0_3->unk4) / temp_a1; - temp_v0_3->unk1C = ((fogB << 16) - temp_v0_3->unk8) / temp_a1; - temp_v0_3->unk20 = ((fogNear << 16) - temp_v0_3->unkC) / temp_a1; - temp_v0_3->unk24 = ((fogFar << 16) - temp_v0_3->unk10) / temp_a1; - temp_v0_3->unk30 = temp_a1; - temp_v0_3->unk34 = obj; + fog = &gFogData[index]; + fog->intendedFog.r = fogR; + fog->intendedFog.g = fogG; + fog->intendedFog.b = fogB; + fog->intendedFog.near = fogNear; + fog->intendedFog.far = fogFar; + fog->addFog.r = ((fogR << 16) - fog->fog.r) / switchTimer; + fog->addFog.g = ((fogG << 16) - fog->fog.g) / switchTimer; + fog->addFog.b = ((fogB << 16) - fog->fog.b) / switchTimer; + fog->addFog.near = ((fogNear << 16) - fog->fog.near) / switchTimer; + fog->addFog.far = ((fogFar << 16) - fog->fog.far) / switchTimer; + fog->switchTimer = switchTimer; + fog->fogChanger = obj; } } } @@ -2430,9 +2448,9 @@ void obj_loop_fogchanger(Object *obj) { #ifdef NON_EQUIVALENT void func_80030DE0(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { s32 max, min; - unk8011D388 *entry; + FogData *entry; - entry = &D_8011D388[arg0]; + entry = &gFogData[arg0]; max = arg5; min = arg4; if (arg5 < arg4) { @@ -2445,18 +2463,18 @@ void func_80030DE0(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s if (min >= max - 5) { min = max - 5; } - entry->unk28 = arg1; - entry->unk29 = arg2; - entry->unk2A = arg3; - entry->unk2C = min; - entry->unk2E = max; - entry->unk14 = ((arg1 << 16) - entry->unk0) / arg6; - entry->unk18 = ((arg2 << 16) - entry->unk4) / arg6; - entry->unk1C = ((arg3 << 16) - entry->unk8) / arg6; - entry->unk20 = ((min << 16) - entry->unkC) / arg6; - entry->unk24 = ((max << 16) - entry->unk10) / arg6; - entry->unk30 = arg6; - entry->unk34 = 0; + entry->intendedFog.r = arg1; + entry->intendedFog.g = arg2; + entry->intendedFog.b = arg3; + entry->intendedFog.near = min; + entry->intendedFog.far = max; + entry->addFog.r = ((arg1 << 16) - entry->fog.r) / arg6; + entry->addFog.g = ((arg2 << 16) - entry->fog.g) / arg6; + entry->addFog.b = ((arg3 << 16) - entry->fog.b) / arg6; + entry->addFog.near = ((min << 16) - entry->fog.near) / arg6; + entry->addFog.far = ((max << 16) - entry->fog.far) / arg6; + entry->switchTimer = arg6; + entry->fogChanger = 0; } #else GLOBAL_ASM("asm/non_matchings/unknown_0255E0/func_80030DE0.s") @@ -2494,7 +2512,7 @@ void compute_scene_camera_transform_matrix(void) { guMtxXFMF(mtx, x, y, z, &x, &y, &z); //Store x/y/z as integers - gScenePerspectivePos.x = (s32)x; - gScenePerspectivePos.y = (s32)y; - gScenePerspectivePos.z = (s32)z; + gScenePerspectivePos.x = (s32) x; + gScenePerspectivePos.y = (s32) y; + gScenePerspectivePos.z = (s32) z; } diff --git a/src/unknown_0255E0.h b/src/unknown_0255E0.h index 3d72fcea..422c4964 100644 --- a/src/unknown_0255E0.h +++ b/src/unknown_0255E0.h @@ -88,26 +88,31 @@ typedef struct unk8011D478 { s32 unk8; } unk8011D478; +// In this struct, data is rightshifted 16 bytes, so make the smooth transition more precise. +typedef struct EnvironmentFog { + s32 r; + s32 g; + s32 b; + s32 near; + s32 far; +} EnvironmentFog; + +typedef struct EnvironmentFogCompact { + u8 r; + u8 g; + u8 b; + s16 near; + s16 far; +} EnvironmentFogCompact; + /* Size: 0x38 bytes */ -typedef struct unk8011D388 { - s32 unk0; - s32 unk4; - s32 unk8; - s32 unkC; - s32 unk10; - s32 unk14; - s32 unk18; - s32 unk1C; - s32 unk20; - s32 unk24; - u8 unk28; - u8 unk29; - u8 unk2A; - s16 unk2C; - s16 unk2E; - s32 unk30; - Object *unk34; -} unk8011D388; +typedef struct FogData { + EnvironmentFog fog; // Current fog properties. What you'll actually see ingame. + EnvironmentFog addFog; // Fog override. This will apply over the current fog to give a smooth transition effect. + EnvironmentFogCompact intendedFog; // Fog properties the game will try to be if the switch timer is 0. + s32 switchTimer; + Object *fogChanger; +} FogData; typedef struct WaterProperties { f32 waveHeight; @@ -141,7 +146,7 @@ void func_800257D0(void); void spawn_skydome(s32 arg0); void set_skydome_visbility(s32 renderSky); void render_skydome(void); -void func_80028FA0(s32 arg0); +void set_anti_aliasing(s32 settings); void add_segment_to_order(s32 segmentIndex, s32 *segmentsOrderIndex, u8 *segmentsOrder); s32 get_inside_segment_count_xz(s32 x, s32 z, s32 *arg2); s32 get_inside_segment_count_xyz(s32 *arg0, s16 xPos1, s16 yPos1, s16 zPos1, s16 xPos2, s16 yPos2, s16 zPos2); @@ -152,10 +157,10 @@ s32 func_8002ACD4(f32 *arg0, f32 *arg1, f32 *arg2); s32 func_8002B9BC(Object *obj, f32 *arg1, f32 *arg2, s32 arg3); void func_8002C71C(LevelModelSegment *segment); LevelModel *get_current_level_model(void); -void func_80030750(s32 arg0, s16 *arg1, s16 *arg2, u8 *arg3, u8 *arg4, u8 *arg5); -void func_800307BC(s32 arg0); -void func_80030838(s32 arg0, s32 arg1); -void func_8003093C(s32 arg0); +void get_fog_settings(s32 playerID, s16 *near, s16 *far, u8 *r, u8 *g, u8 *b); +void reset_fog(s32 playerID); +void update_fog(s32 playerID, s32 updateRate); +void apply_fog(s32 playerID); void compute_scene_camera_transform_matrix(void); void func_80027E24(s32 updateRate); s32 check_if_inside_segment(Object *obj, s32 segmentIndex);