diff --git a/CMakeLists.txt b/CMakeLists.txt index 46977c168..7414d7c8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,8 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/audio ${CMAKE_CURRENT_SOURCE_DIR}/src/debug ${CMAKE_CURRENT_SOURCE_DIR}/src/networking + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/courses ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements/freecam ) @@ -135,6 +137,10 @@ file(GLOB_RECURSE ALL_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "courses/*.h" "src/networking/*.c" "src/networking/*.h" + "src/engine/*.cpp" + "src/engine/*.h" + "src/engine/courses/*.c" + "src/engine/courses/*.h" "src/enhancements/*.c" "src/enhancements/*.h" "src/enhancements/freecam/*.c" diff --git a/asm/non_matchings/code_80091750/add_8018D9E0_entry.s b/asm/non_matchings/code_80091750/add_8018D9E0_entry.s index f24c3d8b9..49c372865 100644 --- a/asm/non_matchings/code_80091750/add_8018D9E0_entry.s +++ b/asm/non_matchings/code_80091750/add_8018D9E0_entry.s @@ -84,7 +84,7 @@ glabel D_800F15E0 .section .text -glabel add_8018D9E0_entry +glabel add_ui_element /* 09F250 8009E650 27BDFF80 */ addiu $sp, $sp, -0x80 /* 09F254 8009E654 AFBF001C */ sw $ra, 0x1c($sp) /* 09F258 8009E658 AFA7008C */ sw $a3, 0x8c($sp) @@ -240,7 +240,7 @@ glabel L8009E888 /* 09F488 8009E888 3C040200 */ lui $a0, %hi(D_020014C8) # $a0, 0x200 /* 09F48C 8009E88C AFBF007C */ sw $ra, 0x7c($sp) /* 09F490 8009E890 248414C8 */ addiu $a0, %lo(D_020014C8) # addiu $a0, $a0, 0x14c8 -/* 09F494 8009E894 0C0265AF */ jal func_800996BC +/* 09F494 8009E894 0C0265AF */ jal load_menu_img2 /* 09F498 8009E898 00002825 */ move $a1, $zero /* 09F49C 8009E89C 3C040200 */ lui $a0, %hi(D_020014C8) # $a0, 0x200 /* 09F4A0 8009E8A0 0C026E55 */ jal func_8009B954 @@ -264,7 +264,7 @@ glabel L8009E8E4 /* 09F4E4 8009E8E4 3C040200 */ lui $a0, %hi(D_02001540) # $a0, 0x200 /* 09F4E8 8009E8E8 AFBF007C */ sw $ra, 0x7c($sp) /* 09F4EC 8009E8EC 24841540 */ addiu $a0, %lo(D_02001540) # addiu $a0, $a0, 0x1540 -/* 09F4F0 8009E8F0 0C0265AF */ jal func_800996BC +/* 09F4F0 8009E8F0 0C0265AF */ jal load_menu_img2 /* 09F4F4 8009E8F4 00002825 */ move $a1, $zero /* 09F4F8 8009E8F8 3C040200 */ lui $a0, %hi(D_02001540) # $a0, 0x200 /* 09F4FC 8009E8FC 0C026E55 */ jal func_8009B954 @@ -289,10 +289,10 @@ glabel L8009E940 /* 09F544 8009E944 AFBF007C */ sw $ra, 0x7c($sp) /* 09F548 8009E948 2484157C */ addiu $a0, %lo(D_0200157C) # addiu $a0, $a0, 0x157c /* 09F54C 8009E94C 00002825 */ move $a1, $zero -/* 09F550 8009E950 0C0265AF */ jal func_800996BC +/* 09F550 8009E950 0C0265AF */ jal load_menu_img2 /* 09F554 8009E954 00001025 */ move $v0, $zero /* 09F558 8009E958 3C040200 */ lui $a0, %hi(D_02001874) # $a0, 0x200 -/* 09F55C 8009E95C 0C026461 */ jal func_80099184 +/* 09F55C 8009E95C 0C026461 */ jal load_menu_img /* 09F560 8009E960 24841874 */ addiu $a0, %lo(D_02001874) # addiu $a0, $a0, 0x1874 /* 09F564 8009E964 8FBF007C */ lw $ra, 0x7c($sp) /* 09F568 8009E968 24190069 */ li $t9, 105 @@ -303,7 +303,7 @@ glabel L8009E940 .L8009E97C: /* 09F57C 8009E97C 0C026449 */ jal segmented_to_virtual_dupe /* 09F580 8009E980 AFA30024 */ sw $v1, 0x24($sp) -/* 09F584 8009E984 0C026461 */ jal func_80099184 +/* 09F584 8009E984 0C026461 */ jal load_menu_img /* 09F588 8009E988 00402025 */ move $a0, $v0 /* 09F58C 8009E98C 8FA30024 */ lw $v1, 0x24($sp) /* 09F590 8009E990 3C0E800E */ lui $t6, %hi(D_800E7D0C) # $t6, 0x800e @@ -316,7 +316,7 @@ glabel L8009E940 glabel L8009E9AC /* 09F5AC 8009E9AC 3C040200 */ lui $a0, %hi(D_020015A4) # $a0, 0x200 /* 09F5B0 8009E9B0 AFBF007C */ sw $ra, 0x7c($sp) -/* 09F5B4 8009E9B4 0C026461 */ jal func_80099184 +/* 09F5B4 8009E9B4 0C026461 */ jal load_menu_img /* 09F5B8 8009E9B8 248415A4 */ addiu $a0, %lo(D_020015A4) # addiu $a0, $a0, 0x15a4 /* 09F5BC 8009E9BC 3C040200 */ lui $a0, %hi(D_020015A4) # $a0, 0x200 /* 09F5C0 8009E9C0 0C026E55 */ jal func_8009B954 @@ -419,7 +419,7 @@ glabel L8009E9AC /* 09F744 8009EB44 0C026E66 */ jal func_8009B998 /* 09F748 8009EB48 00000000 */ nop /* 09F74C 8009EB4C 3C040200 */ lui $a0, %hi(D_020015CC) # $a0, 0x200 -/* 09F750 8009EB50 0C026461 */ jal func_80099184 +/* 09F750 8009EB50 0C026461 */ jal load_menu_img /* 09F754 8009EB54 248415CC */ addiu $a0, %lo(D_020015CC) # addiu $a0, $a0, 0x15cc /* 09F758 8009EB58 3C040200 */ lui $a0, %hi(D_020015CC) # $a0, 0x200 /* 09F75C 8009EB5C 0C026E55 */ jal func_8009B954 @@ -438,7 +438,7 @@ glabel L8009E9AC /* 09F790 8009EB90 0C026E66 */ jal func_8009B998 /* 09F794 8009EB94 AD020000 */ sw $v0, ($t0) /* 09F798 8009EB98 3C040200 */ lui $a0, %hi(D_02001630) # $a0, 0x200 -/* 09F79C 8009EB9C 0C026461 */ jal func_80099184 +/* 09F79C 8009EB9C 0C026461 */ jal load_menu_img /* 09F7A0 8009EBA0 24841630 */ addiu $a0, %lo(D_02001630) # addiu $a0, $a0, 0x1630 /* 09F7A4 8009EBA4 3C040200 */ lui $a0, %hi(D_02001630) # $a0, 0x200 /* 09F7A8 8009EBA8 0C026E55 */ jal func_8009B954 @@ -457,7 +457,7 @@ glabel L8009E9AC /* 09F7DC 8009EBDC 0C026E66 */ jal func_8009B998 /* 09F7E0 8009EBE0 AD020000 */ sw $v0, ($t0) /* 09F7E4 8009EBE4 3C040200 */ lui $a0, %hi(D_02001658) # $a0, 0x200 -/* 09F7E8 8009EBE8 0C026461 */ jal func_80099184 +/* 09F7E8 8009EBE8 0C026461 */ jal load_menu_img /* 09F7EC 8009EBEC 24841658 */ addiu $a0, %lo(D_02001658) # addiu $a0, $a0, 0x1658 /* 09F7F0 8009EBF0 3C040200 */ lui $a0, %hi(D_02001658) # $a0, 0x200 /* 09F7F4 8009EBF4 0C026E55 */ jal func_8009B954 @@ -482,7 +482,7 @@ glabel L8009EC38 /* 09F83C 8009EC3C AFBF007C */ sw $ra, 0x7c($sp) /* 09F840 8009EC40 0C026455 */ jal segmented_to_virtual_dupe_2 /* 09F844 8009EC44 8C847D34 */ lw $a0, %lo(D_800E7D34)($a0) -/* 09F848 8009EC48 0C0268DD */ jal func_8009A374 +/* 09F848 8009EC48 0C0268DD */ jal animate_character_select_menu /* 09F84C 8009EC4C 00402025 */ move $a0, $v0 /* 09F850 8009EC50 8FBF007C */ lw $ra, 0x7c($sp) /* 09F854 8009EC54 1000025E */ b .L8009F5D0 @@ -494,7 +494,7 @@ glabel L8009EC5C .L8009EC68: /* 09F868 8009EC68 0C026449 */ jal segmented_to_virtual_dupe /* 09F86C 8009EC6C AFA30024 */ sw $v1, 0x24($sp) -/* 09F870 8009EC70 0C026461 */ jal func_80099184 +/* 09F870 8009EC70 0C026461 */ jal load_menu_img /* 09F874 8009EC74 00402025 */ move $a0, $v0 /* 09F878 8009EC78 8FA30024 */ lw $v1, 0x24($sp) /* 09F87C 8009EC7C 3C0F800E */ lui $t7, %hi(D_800E7D34) # $t7, 0x800e @@ -506,56 +506,56 @@ glabel L8009EC5C /* 09F894 8009EC94 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009EC98 /* 09F898 8009EC98 3C040200 */ lui $a0, %hi(D_0200184C) # $a0, 0x200 -/* 09F89C 8009EC9C 0C026461 */ jal func_80099184 +/* 09F89C 8009EC9C 0C026461 */ jal load_menu_img /* 09F8A0 8009ECA0 2484184C */ addiu $a0, %lo(D_0200184C) # addiu $a0, $a0, 0x184c /* 09F8A4 8009ECA4 1000024B */ b .L8009F5D4 /* 09F8A8 8009ECA8 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009ECAC -/* 09F8AC 8009ECAC 0C02D557 */ jal func_800B555C +/* 09F8AC 8009ECAC 0C02D557 */ jal has_unlocked_extra_mode /* 09F8B0 8009ECB0 00000000 */ nop /* 09F8B4 8009ECB4 0002C080 */ sll $t8, $v0, 2 /* 09F8B8 8009ECB8 3C04800E */ lui $a0, %hi(D_800E7D4C) /* 09F8BC 8009ECBC 00982021 */ addu $a0, $a0, $t8 /* 09F8C0 8009ECC0 8C847D4C */ lw $a0, %lo(D_800E7D4C)($a0) -/* 09F8C4 8009ECC4 0C0265AF */ jal func_800996BC +/* 09F8C4 8009ECC4 0C0265AF */ jal load_menu_img2 /* 09F8C8 8009ECC8 00002825 */ move $a1, $zero /* 09F8CC 8009ECCC 10000241 */ b .L8009F5D4 /* 09F8D0 8009ECD0 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009ECD4 -/* 09F8D4 8009ECD4 0C01BB91 */ jal func_8006EE44 +/* 09F8D4 8009ECD4 0C01BB91 */ jal load_mario_kart_64_logo /* 09F8D8 8009ECD8 00000000 */ nop -/* 09F8DC 8009ECDC 3C028019 */ lui $v0, %hi(gD_8018E118TotalSize) # $v0, 0x8019 -/* 09F8E0 8009ECE0 2442E110 */ addiu $v0, %lo(gD_8018E118TotalSize) # addiu $v0, $v0, -0x1ef0 +/* 09F8DC 8009ECDC 3C028019 */ lui $v0, %hi(gMenuTextureBufferIndex) # $v0, 0x8019 +/* 09F8E0 8009ECE0 2442E110 */ addiu $v0, %lo(gMenuTextureBufferIndex) # addiu $v0, $v0, -0x1ef0 /* 09F8E4 8009ECE4 8C590000 */ lw $t9, ($v0) /* 09F8E8 8009ECE8 3C010001 */ lui $at, 1 /* 09F8EC 8009ECEC 3C040200 */ lui $a0, %hi(D_020045E8) # $a0, 0x200 /* 09F8F0 8009ECF0 03217021 */ addu $t6, $t9, $at /* 09F8F4 8009ECF4 AC4E0000 */ sw $t6, ($v0) -/* 09F8F8 8009ECF8 0C026461 */ jal func_80099184 +/* 09F8F8 8009ECF8 0C026461 */ jal load_menu_img /* 09F8FC 8009ECFC 248445E8 */ addiu $a0, %lo(D_020045E8) # addiu $a0, $a0, 0x45e8 /* 09F900 8009ED00 10000234 */ b .L8009F5D4 /* 09F904 8009ED04 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009ED08 /* 09F908 8009ED08 3C040200 */ lui $a0, %hi(D_02004610) # $a0, 0x200 -/* 09F90C 8009ED0C 0C026461 */ jal func_80099184 +/* 09F90C 8009ED0C 0C026461 */ jal load_menu_img /* 09F910 8009ED10 24844610 */ addiu $a0, %lo(D_02004610) # addiu $a0, $a0, 0x4610 /* 09F914 8009ED14 1000022F */ b .L8009F5D4 /* 09F918 8009ED18 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009ED1C -/* 09F91C 8009ED1C 0C02D557 */ jal func_800B555C +/* 09F91C 8009ED1C 0C02D557 */ jal has_unlocked_extra_mode /* 09F920 8009ED20 00000000 */ nop /* 09F924 8009ED24 00027880 */ sll $t7, $v0, 2 /* 09F928 8009ED28 3C04800E */ lui $a0, %hi(D_800E7D4C) /* 09F92C 8009ED2C 008F2021 */ addu $a0, $a0, $t7 /* 09F930 8009ED30 8C847D4C */ lw $a0, %lo(D_800E7D4C)($a0) -/* 09F934 8009ED34 0C0265AF */ jal func_800996BC +/* 09F934 8009ED34 0C0265AF */ jal load_menu_img2 /* 09F938 8009ED38 00002825 */ move $a1, $zero /* 09F93C 8009ED3C 3C040200 */ lui $a0, %hi(D_02004B74) # $a0, 0x200 /* 09F940 8009ED40 24844B74 */ addiu $a0, %lo(D_02004B74) # addiu $a0, $a0, 0x4b74 -/* 09F944 8009ED44 0C0265AF */ jal func_800996BC +/* 09F944 8009ED44 0C0265AF */ jal load_menu_img2 /* 09F948 8009ED48 00002825 */ move $a1, $zero /* 09F94C 8009ED4C 00002025 */ move $a0, $zero -/* 09F950 8009ED50 0C026C29 */ jal func_8009B0A4 +/* 09F950 8009ED50 0C026C29 */ jal convert_img_to_greyscale /* 09F954 8009ED54 24050019 */ li $a1, 25 /* 09F958 8009ED58 8FB80080 */ lw $t8, 0x80($sp) /* 09F95C 8009ED5C 3C0E800E */ lui $t6, %hi(D_800E74E8) # $t6, 0x800e @@ -568,7 +568,7 @@ glabel L8009ED1C /* 09F978 8009ED78 9446FEE8 */ lhu $a2, -0x118($v0) /* 09F97C 8009ED7C 9447FEEA */ lhu $a3, -0x116($v0) /* 09F980 8009ED80 00002025 */ move $a0, $zero -/* 09F984 8009ED84 0C026D4E */ jal func_8009B538 +/* 09F984 8009ED84 0C026D4E */ jal adjust_img_colour /* 09F988 8009ED88 AFAF0010 */ sw $t7, 0x10($sp) /* 09F98C 8009ED8C 10000211 */ b .L8009F5D4 /* 09F990 8009ED90 8FBF001C */ lw $ra, 0x1c($sp) @@ -583,7 +583,7 @@ glabel L8009ED9C /* 09F9AC 8009EDAC 0C026449 */ jal segmented_to_virtual_dupe /* 09F9B0 8009EDB0 8C84822C */ lw $a0, %lo(D_800E822C)($a0) # -0x7dd4($a0) /* 09F9B4 8009EDB4 00402025 */ move $a0, $v0 -/* 09F9B8 8009EDB8 0C0265AF */ jal func_800996BC +/* 09F9B8 8009EDB8 0C0265AF */ jal load_menu_img2 /* 09F9BC 8009EDBC 00002825 */ move $a1, $zero /* 09F9C0 8009EDC0 10000204 */ b .L8009F5D4 /* 09F9C4 8009EDC4 8FBF001C */ lw $ra, 0x1c($sp) @@ -597,19 +597,19 @@ glabel L8009EDC8 /* 09F9E0 8009EDE0 0C026449 */ jal segmented_to_virtual_dupe /* 09F9E4 8009EDE4 AFA20024 */ sw $v0, 0x24($sp) /* 09F9E8 8009EDE8 00402025 */ move $a0, $v0 -/* 09F9EC 8009EDEC 0C0265AF */ jal func_800996BC +/* 09F9EC 8009EDEC 0C0265AF */ jal load_menu_img2 /* 09F9F0 8009EDF0 00002825 */ move $a1, $zero /* 09F9F4 8009EDF4 8FAF0024 */ lw $t7, 0x24($sp) /* 09F9F8 8009EDF8 0C026449 */ jal segmented_to_virtual_dupe /* 09F9FC 8009EDFC 8DE4FFAC */ lw $a0, -0x54($t7) -/* 09FA00 8009EE00 0C026461 */ jal func_80099184 +/* 09FA00 8009EE00 0C026461 */ jal load_menu_img /* 09FA04 8009EE04 00402025 */ move $a0, $v0 /* 09FA08 8009EE08 100001F2 */ b .L8009F5D4 /* 09FA0C 8009EE0C 8FBF001C */ lw $ra, 0x1c($sp) glabel L8009EE10 /* 09FA10 8009EE10 3C040200 */ lui $a0, %hi(D_02004B4C) # $a0, 0x200 /* 09FA14 8009EE14 24844B4C */ addiu $a0, %lo(D_02004B4C) # addiu $a0, $a0, 0x4b4c -/* 09FA18 8009EE18 0C0265AF */ jal func_800996BC +/* 09FA18 8009EE18 0C0265AF */ jal load_menu_img2 /* 09FA1C 8009EE1C 00002825 */ move $a1, $zero /* 09FA20 8009EE20 100001EC */ b .L8009F5D4 /* 09FA24 8009EE24 8FBF001C */ lw $ra, 0x1c($sp) @@ -617,7 +617,7 @@ glabel L8009EE28 /* 09FA28 8009EE28 3C040200 */ lui $a0, %hi(D_02004B74) # $a0, 0x200 /* 09FA2C 8009EE2C AFBF007C */ sw $ra, 0x7c($sp) /* 09FA30 8009EE30 24844B74 */ addiu $a0, %lo(D_02004B74) # addiu $a0, $a0, 0x4b74 -/* 09FA34 8009EE34 0C0265AF */ jal func_800996BC +/* 09FA34 8009EE34 0C0265AF */ jal load_menu_img2 /* 09FA38 8009EE38 00002825 */ move $a1, $zero /* 09FA3C 8009EE3C 8FBF007C */ lw $ra, 0x7c($sp) /* 09FA40 8009EE40 24180020 */ li $t8, 32 @@ -630,7 +630,7 @@ glabel L8009EE4C /* 09FA58 8009EE58 008E2021 */ addu $a0, $a0, $t6 /* 09FA5C 8009EE5C 0C026449 */ jal segmented_to_virtual_dupe /* 09FA60 8009EE60 8C8481E4 */ lw $a0, %lo(D_800E81E4)($a0) # -0x7e1c($a0) -/* 09FA64 8009EE64 0C026461 */ jal func_80099184 +/* 09FA64 8009EE64 0C026461 */ jal load_menu_img /* 09FA68 8009EE68 00402025 */ move $a0, $v0 /* 09FA6C 8009EE6C 100001D9 */ b .L8009F5D4 /* 09FA70 8009EE70 8FBF001C */ lw $ra, 0x1c($sp) @@ -644,7 +644,7 @@ glabel L8009EE74 /* 09FA8C 8009EE8C 01E03025 */ move $a2, $t7 /* 09FA90 8009EE90 0C026455 */ jal segmented_to_virtual_dupe_2 /* 09FA94 8009EE94 AFAF0024 */ sw $t7, 0x24($sp) -/* 09FA98 8009EE98 0C0268DD */ jal func_8009A374 +/* 09FA98 8009EE98 0C0268DD */ jal animate_character_select_menu /* 09FA9C 8009EE9C 00402025 */ move $a0, $v0 /* 09FAA0 8009EEA0 8FA60024 */ lw $a2, 0x24($sp) /* 09FAA4 8009EEA4 8FBF007C */ lw $ra, 0x7c($sp) @@ -654,7 +654,7 @@ glabel L8009EE74 /* 09FAB4 8009EEB4 0C026449 */ jal segmented_to_virtual_dupe /* 09FAB8 8009EEB8 8C847CA8 */ lw $a0, %lo(D_800E7D54 - 0xAC)($a0) /* 09FABC 8009EEBC 00402025 */ move $a0, $v0 -/* 09FAC0 8009EEC0 0C0265AF */ jal func_800996BC +/* 09FAC0 8009EEC0 0C0265AF */ jal load_menu_img2 /* 09FAC4 8009EEC4 00002825 */ move $a1, $zero /* 09FAC8 8009EEC8 100001C2 */ b .L8009F5D4 /* 09FACC 8009EECC 8FBF001C */ lw $ra, 0x1c($sp) @@ -666,7 +666,7 @@ glabel L8009EED0 /* 09FAE0 8009EEE0 00992021 */ addu $a0, $a0, $t9 /* 09FAE4 8009EEE4 0C026455 */ jal segmented_to_virtual_dupe_2 /* 09FAE8 8009EEE8 8C8480A0 */ lw $a0, %lo(D_800E80A0)($a0) # -0x7f60($a0) -/* 09FAEC 8009EEEC 0C0268DD */ jal func_8009A374 +/* 09FAEC 8009EEEC 0C0268DD */ jal animate_character_select_menu /* 09FAF0 8009EEF0 00402025 */ move $a0, $v0 /* 09FAF4 8009EEF4 8FBF007C */ lw $ra, 0x7c($sp) /* 09FAF8 8009EEF8 100001B5 */ b .L8009F5D0 @@ -682,7 +682,7 @@ glabel L8009EF08 /* 09FB18 8009EF18 0C026449 */ jal segmented_to_virtual_dupe /* 09FB1C 8009EF1C 8C84817C */ lw $a0, %lo(D_800E817C)($a0) # -0x7e84($a0) /* 09FB20 8009EF20 00402025 */ move $a0, $v0 -/* 09FB24 8009EF24 0C0265AF */ jal func_800996BC +/* 09FB24 8009EF24 0C0265AF */ jal load_menu_img2 /* 09FB28 8009EF28 00002825 */ move $a1, $zero /* 09FB2C 8009EF2C 100001A9 */ b .L8009F5D4 /* 09FB30 8009EF30 8FBF001C */ lw $ra, 0x1c($sp) @@ -698,7 +698,7 @@ glabel L8009EF34 /* 09FB54 8009EF54 00982021 */ addu $a0, $a0, $t8 /* 09FB58 8009EF58 0C026455 */ jal segmented_to_virtual_dupe_2 /* 09FB5C 8009EF5C 8C847E34 */ lw $a0, %lo(D_800E7E34)($a0) -/* 09FB60 8009EF60 0C0268DD */ jal func_8009A374 +/* 09FB60 8009EF60 0C0268DD */ jal animate_character_select_menu /* 09FB64 8009EF64 00402025 */ move $a0, $v0 /* 09FB68 8009EF68 8FBF007C */ lw $ra, 0x7c($sp) /* 09FB6C 8009EF6C 10000198 */ b .L8009F5D0 @@ -751,7 +751,7 @@ glabel L8009EFB8 /* 09FC18 8009F018 008E2021 */ addu $a0, $a0, $t6 /* 09FC1C 8009F01C 0C026455 */ jal segmented_to_virtual_dupe_2 /* 09FC20 8009F020 8C847E20 */ lw $a0, %lo(D_800E7E20)($a0) -/* 09FC24 8009F024 0C0268DD */ jal func_8009A374 +/* 09FC24 8009F024 0C0268DD */ jal animate_character_select_menu /* 09FC28 8009F028 00402025 */ move $a0, $v0 /* 09FC2C 8009F02C 8FBF007C */ lw $ra, 0x7c($sp) /* 09FC30 8009F030 3C03800E */ lui $v1, %hi(D_800E7268) # $v1, 0x800e @@ -772,7 +772,7 @@ glabel L8009F050 /* 09FC68 8009F068 0C026449 */ jal segmented_to_virtual_dupe /* 09FC6C 8009F06C 8C848294 */ lw $a0, %lo(D_800E8294)($a0) # -0x7d6c($a0) /* 09FC70 8009F070 00402025 */ move $a0, $v0 -/* 09FC74 8009F074 0C0265AF */ jal func_800996BC +/* 09FC74 8009F074 0C0265AF */ jal load_menu_img2 /* 09FC78 8009F078 00002825 */ move $a1, $zero /* 09FC7C 8009F07C 8FBF007C */ lw $ra, 0x7c($sp) /* 09FC80 8009F080 24180037 */ li $t8, 55 @@ -785,7 +785,7 @@ glabel L8009F094 /* 09FC98 8009F098 0C026449 */ jal segmented_to_virtual_dupe /* 09FC9C 8009F09C 24844A0C */ addiu $a0, %lo(D_02004A0C) # addiu $a0, $a0, 0x4a0c /* 09FCA0 8009F0A0 00402025 */ move $a0, $v0 -/* 09FCA4 8009F0A4 0C0265AF */ jal func_800996BC +/* 09FCA4 8009F0A4 0C0265AF */ jal load_menu_img2 /* 09FCA8 8009F0A8 00002825 */ move $a1, $zero /* 09FCAC 8009F0AC 0C02D6E5 */ jal controller_pak_1_status /* 09FCB0 8009F0B0 00000000 */ nop @@ -809,7 +809,7 @@ glabel L8009F0E0 /* 09FCF0 8009F0F0 0C026449 */ jal segmented_to_virtual_dupe /* 09FCF4 8009F0F4 8C848114 */ lw $a0, %lo(D_800E8114)($a0) # -0x7eec($a0) /* 09FCF8 8009F0F8 00402025 */ move $a0, $v0 -/* 09FCFC 8009F0FC 0C0265AF */ jal func_800996BC +/* 09FCFC 8009F0FC 0C0265AF */ jal load_menu_img2 /* 09FD00 8009F100 00002825 */ move $a1, $zero /* 09FD04 8009F104 10000133 */ b .L8009F5D4 /* 09FD08 8009F108 8FBF001C */ lw $ra, 0x1c($sp) @@ -818,7 +818,7 @@ glabel L8009F10C /* 09FD10 8009F110 0C026449 */ jal segmented_to_virtual_dupe /* 09FD14 8009F114 24844A34 */ addiu $a0, %lo(D_02004A34) # addiu $a0, $a0, 0x4a34 /* 09FD18 8009F118 00402025 */ move $a0, $v0 -/* 09FD1C 8009F11C 0C0265AF */ jal func_800996BC +/* 09FD1C 8009F11C 0C0265AF */ jal load_menu_img2 /* 09FD20 8009F120 00002825 */ move $a1, $zero /* 09FD24 8009F124 0C02D6E5 */ jal controller_pak_1_status /* 09FD28 8009F128 00000000 */ nop @@ -838,7 +838,7 @@ glabel L8009F158 /* 09FD58 8009F158 3C040200 */ lui $a0, %hi(D_02001FA4) # $a0, 0x200 /* 09FD5C 8009F15C 0C026449 */ jal segmented_to_virtual_dupe /* 09FD60 8009F160 24841FA4 */ addiu $a0, %lo(D_02001FA4) # addiu $a0, $a0, 0x1fa4 -/* 09FD64 8009F164 0C026461 */ jal func_80099184 +/* 09FD64 8009F164 0C026461 */ jal load_menu_img /* 09FD68 8009F168 00402025 */ move $a0, $v0 /* 09FD6C 8009F16C 10000119 */ b .L8009F5D4 /* 09FD70 8009F170 8FBF001C */ lw $ra, 0x1c($sp) @@ -869,7 +869,7 @@ glabel L8009F174 /* 09FDC8 8009F1C8 0C026449 */ jal segmented_to_virtual_dupe /* 09FDCC 8009F1CC 8C847D74 */ lw $a0, %lo(D_800E7D74)($a0) /* 09FDD0 8009F1D0 00402025 */ move $a0, $v0 -/* 09FDD4 8009F1D4 0C0265AF */ jal func_800996BC +/* 09FDD4 8009F1D4 0C0265AF */ jal load_menu_img2 /* 09FDD8 8009F1D8 2405FFFF */ li $a1, -1 /* 09FDDC 8009F1DC 8FBF007C */ lw $ra, 0x7c($sp) /* 09FDE0 8009F1E0 3C04800E */ lui $a0, %hi(D_800E7DC4) @@ -897,13 +897,13 @@ glabel L8009F174 /* 09FE30 8009F230 0C026449 */ jal segmented_to_virtual_dupe /* 09FE34 8009F234 8C847DC4 */ lw $a0, %lo(D_800E7DC4)($a0) /* 09FE38 8009F238 00402025 */ move $a0, $v0 -/* 09FE3C 8009F23C 0C0265AF */ jal func_800996BC +/* 09FE3C 8009F23C 0C0265AF */ jal load_menu_img2 /* 09FE40 8009F240 00002825 */ move $a1, $zero /* 09FE44 8009F244 3C040200 */ lui $a0, %hi(D_02004A0C) # $a0, 0x200 /* 09FE48 8009F248 0C026449 */ jal segmented_to_virtual_dupe /* 09FE4C 8009F24C 24844A0C */ addiu $a0, %lo(D_02004A0C) # addiu $a0, $a0, 0x4a0c /* 09FE50 8009F250 00402025 */ move $a0, $v0 -/* 09FE54 8009F254 0C0265AF */ jal func_800996BC +/* 09FE54 8009F254 0C0265AF */ jal load_menu_img2 /* 09FE58 8009F258 00002825 */ move $a1, $zero /* 09FE5C 8009F25C 100000DD */ b .L8009F5D4 /* 09FE60 8009F260 8FBF001C */ lw $ra, 0x1c($sp) @@ -975,14 +975,14 @@ glabel L8009F264 /* 09FF50 8009F350 0C026449 */ jal segmented_to_virtual_dupe /* 09FF54 8009F354 8C847D54 */ lw $a0, %lo(D_800E7D54)($a0) /* 09FF58 8009F358 00402025 */ move $a0, $v0 -/* 09FF5C 8009F35C 0C0265AF */ jal func_800996BC +/* 09FF5C 8009F35C 0C0265AF */ jal load_menu_img2 /* 09FF60 8009F360 00002825 */ move $a1, $zero /* 09FF64 8009F364 8FA60024 */ lw $a2, 0x24($sp) /* 09FF68 8009F368 3C04800E */ lui $a0, %hi(D_800E7FF0) /* 09FF6C 8009F36C 00862021 */ addu $a0, $a0, $a2 /* 09FF70 8009F370 0C026449 */ jal segmented_to_virtual_dupe /* 09FF74 8009F374 8C847FF0 */ lw $a0, %lo(D_800E7FF0)($a0) -/* 09FF78 8009F378 0C026461 */ jal func_80099184 +/* 09FF78 8009F378 0C026461 */ jal load_menu_img /* 09FF7C 8009F37C 00402025 */ move $a0, $v0 /* 09FF80 8009F380 10000094 */ b .L8009F5D4 /* 09FF84 8009F384 8FBF001C */ lw $ra, 0x1c($sp) @@ -1058,7 +1058,7 @@ glabel L8009F430 /* 0A0080 8009F480 008F2021 */ addu $a0, $a0, $t7 /* 0A0084 8009F484 0C026455 */ jal segmented_to_virtual_dupe_2 /* 0A0088 8009F488 8C847E34 */ lw $a0, %lo(D_800E7E34)($a0) -/* 0A008C 8009F48C 0C0268DD */ jal func_8009A374 +/* 0A008C 8009F48C 0C0268DD */ jal animate_character_select_menu /* 0A0090 8009F490 00402025 */ move $a0, $v0 /* 0A0094 8009F494 8FBF007C */ lw $ra, 0x7c($sp) /* 0A0098 8009F498 3C198019 */ lui $t9, %hi(gTimeTrialDataCourseIndex) # $t9, 0x8019 @@ -1070,7 +1070,7 @@ glabel L8009F430 /* 0A00B0 8009F4B0 0C026449 */ jal segmented_to_virtual_dupe /* 0A00B4 8009F4B4 00000000 */ nop /* 0A00B8 8009F4B8 00402025 */ move $a0, $v0 -/* 0A00BC 8009F4BC 0C0265AF */ jal func_800996BC +/* 0A00BC 8009F4BC 0C0265AF */ jal load_menu_img2 /* 0A00C0 8009F4C0 00002825 */ move $a1, $zero /* 0A00C4 8009F4C4 0C01BBD8 */ jal func_8006EF60 /* 0A00C8 8009F4C8 00000000 */ nop @@ -1098,7 +1098,7 @@ glabel L8009F510 /* 0A0114 8009F514 0C026449 */ jal segmented_to_virtual_dupe /* 0A0118 8009F518 24844638 */ addiu $a0, %lo(D_02004638) # addiu $a0, $a0, 0x4638 /* 0A011C 8009F51C 00402025 */ move $a0, $v0 -/* 0A0120 8009F520 0C0265AF */ jal func_800996BC +/* 0A0120 8009F520 0C0265AF */ jal load_menu_img2 /* 0A0124 8009F524 00002825 */ move $a1, $zero /* 0A0128 8009F528 1000002A */ b .L8009F5D4 /* 0A012C 8009F52C 8FBF001C */ lw $ra, 0x1c($sp) @@ -1146,7 +1146,7 @@ glabel L8009F530 /* 0A01BC 8009F5BC 0C026449 */ jal segmented_to_virtual_dupe /* 0A01C0 8009F5C0 8C847D54 */ lw $a0, %lo(D_800E7D54)($a0) /* 0A01C4 8009F5C4 00402025 */ move $a0, $v0 -/* 0A01C8 8009F5C8 0C0265AF */ jal func_800996BC +/* 0A01C8 8009F5C8 0C0265AF */ jal load_menu_img2 /* 0A01CC 8009F5CC 00002825 */ move $a1, $zero .L8009F5D0: glabel L8009F5D0 diff --git a/asm/non_matchings/code_80091750/func_80099184.s b/asm/non_matchings/code_80091750/func_80099184.s index 9df413353..2c09fe763 100644 --- a/asm/non_matchings/code_80091750/func_80099184.s +++ b/asm/non_matchings/code_80091750/func_80099184.s @@ -1,4 +1,4 @@ -glabel func_80099184 +glabel load_menu_img /* 099D84 80099184 27BDFFC8 */ addiu $sp, $sp, -0x38 /* 099D88 80099188 AFBF0034 */ sw $ra, 0x34($sp) /* 099D8C 8009918C AFB60030 */ sw $s6, 0x30($sp) @@ -16,10 +16,10 @@ glabel func_80099184 /* 099DBC 800991BC 3C158019 */ lui $s5, %hi(D_8018D9B0) # $s5, 0x8019 /* 099DC0 800991C0 3C148019 */ lui $s4, %hi(D_8018D9B4) # $s4, 0x8019 /* 099DC4 800991C4 3C138019 */ lui $s3, %hi(gNumD_8018E118Entries) # $s3, 0x8019 -/* 099DC8 800991C8 3C128019 */ lui $s2, %hi(gD_8018E118TotalSize) # $s2, 0x8019 +/* 099DC8 800991C8 3C128019 */ lui $s2, %hi(gMenuTextureBufferIndex) # $s2, 0x8019 /* 099DCC 800991CC 3C108019 */ lui $s0, %hi(D_8018E118) # $s0, 0x8019 /* 099DD0 800991D0 2610E118 */ addiu $s0, %lo(D_8018E118) # addiu $s0, $s0, -0x1ee8 -/* 099DD4 800991D4 2652E110 */ addiu $s2, %lo(gD_8018E118TotalSize) # addiu $s2, $s2, -0x1ef0 +/* 099DD4 800991D4 2652E110 */ addiu $s2, %lo(gMenuTextureBufferIndex) # addiu $s2, $s2, -0x1ef0 /* 099DD8 800991D8 2673E758 */ addiu $s3, %lo(gNumD_8018E118Entries) # addiu $s3, $s3, -0x18a8 /* 099DDC 800991DC 2694D9B4 */ addiu $s4, %lo(D_8018D9B4) # addiu $s4, $s4, -0x264c /* 099DE0 800991E0 26B5D9B0 */ addiu $s5, %lo(D_8018D9B0) # addiu $s5, $s5, -0x2650 diff --git a/asm/non_matchings/code_80091750/func_80099394.s b/asm/non_matchings/code_80091750/func_80099394.s index 947f8a697..85febe6cc 100644 --- a/asm/non_matchings/code_80091750/func_80099394.s +++ b/asm/non_matchings/code_80091750/func_80099394.s @@ -15,10 +15,10 @@ glabel func_80099394 /* 099FC8 800993C8 11C0004E */ beqz $t6, .L80099504 /* 099FCC 800993CC 26D6D9B0 */ addiu $s6, %lo(D_8018D9B0) # addiu $s6, $s6, -0x2650 /* 099FD0 800993D0 3C148019 */ lui $s4, %hi(gNumD_8018E118Entries) # $s4, 0x8019 -/* 099FD4 800993D4 3C138019 */ lui $s3, %hi(gD_8018E118TotalSize) # $s3, 0x8019 +/* 099FD4 800993D4 3C138019 */ lui $s3, %hi(gMenuTextureBufferIndex) # $s3, 0x8019 /* 099FD8 800993D8 3C118019 */ lui $s1, %hi(D_8018E118) # $s1, 0x8019 /* 099FDC 800993DC 2631E118 */ addiu $s1, %lo(D_8018E118) # addiu $s1, $s1, -0x1ee8 -/* 099FE0 800993E0 2673E110 */ addiu $s3, %lo(gD_8018E118TotalSize) # addiu $s3, $s3, -0x1ef0 +/* 099FE0 800993E0 2673E110 */ addiu $s3, %lo(gMenuTextureBufferIndex) # addiu $s3, $s3, -0x1ef0 /* 099FE4 800993E4 2694E758 */ addiu $s4, %lo(gNumD_8018E118Entries) # addiu $s4, $s4, -0x18a8 /* 099FE8 800993E8 24150005 */ li $s5, 5 /* 099FEC 800993EC 8E830000 */ lw $v1, ($s4) diff --git a/asm/non_matchings/code_80091750/func_8009952C.s b/asm/non_matchings/code_80091750/func_8009952C.s index de792ba29..57815908c 100644 --- a/asm/non_matchings/code_80091750/func_8009952C.s +++ b/asm/non_matchings/code_80091750/func_8009952C.s @@ -15,10 +15,10 @@ glabel func_8009952C /* 09A160 80099560 26B5D9B0 */ addiu $s5, %lo(D_8018D9B0) # addiu $s5, $s5, -0x2650 /* 09A164 80099564 3C148019 */ lui $s4, %hi(D_8018D9B4) # $s4, 0x8019 /* 09A168 80099568 3C138019 */ lui $s3, %hi(gNumD_8018E118Entries) # $s3, 0x8019 -/* 09A16C 8009956C 3C128019 */ lui $s2, %hi(gD_8018E118TotalSize) # $s2, 0x8019 +/* 09A16C 8009956C 3C128019 */ lui $s2, %hi(gMenuTextureBufferIndex) # $s2, 0x8019 /* 09A170 80099570 3C108019 */ lui $s0, %hi(D_8018E118) # $s0, 0x8019 /* 09A174 80099574 2610E118 */ addiu $s0, %lo(D_8018E118) # addiu $s0, $s0, -0x1ee8 -/* 09A178 80099578 2652E110 */ addiu $s2, %lo(gD_8018E118TotalSize) # addiu $s2, $s2, -0x1ef0 +/* 09A178 80099578 2652E110 */ addiu $s2, %lo(gMenuTextureBufferIndex) # addiu $s2, $s2, -0x1ef0 /* 09A17C 8009957C 2673E758 */ addiu $s3, %lo(gNumD_8018E118Entries) # addiu $s3, $s3, -0x18a8 /* 09A180 80099580 2694D9B4 */ addiu $s4, %lo(D_8018D9B4) # addiu $s4, $s4, -0x264c /* 09A184 80099584 8E630000 */ lw $v1, ($s3) diff --git a/asm/non_matchings/code_80091750/func_800996BC.s b/asm/non_matchings/code_80091750/func_800996BC.s index c38ba4f97..a35f144e1 100644 --- a/asm/non_matchings/code_80091750/func_800996BC.s +++ b/asm/non_matchings/code_80091750/func_800996BC.s @@ -1,4 +1,4 @@ -glabel func_800996BC +glabel load_menu_img2 /* 09A2BC 800996BC 27BDFFC0 */ addiu $sp, $sp, -0x40 /* 09A2C0 800996C0 AFBF003C */ sw $ra, 0x3c($sp) /* 09A2C4 800996C4 AFB20020 */ sw $s2, 0x20($sp) @@ -19,10 +19,10 @@ glabel func_800996BC /* 09A300 80099700 2417FFFF */ li $s7, -1 /* 09A304 80099704 3C158019 */ lui $s5, %hi(D_8018D9B4) # $s5, 0x8019 /* 09A308 80099708 3C148019 */ lui $s4, %hi(gNumD_8018E118Entries) # $s4, 0x8019 -/* 09A30C 8009970C 3C138019 */ lui $s3, %hi(gD_8018E118TotalSize) # $s3, 0x8019 +/* 09A30C 8009970C 3C138019 */ lui $s3, %hi(gMenuTextureBufferIndex) # $s3, 0x8019 /* 09A310 80099710 3C118019 */ lui $s1, %hi(D_8018E118) # $s1, 0x8019 /* 09A314 80099714 2631E118 */ addiu $s1, %lo(D_8018E118) # addiu $s1, $s1, -0x1ee8 -/* 09A318 80099718 2673E110 */ addiu $s3, %lo(gD_8018E118TotalSize) # addiu $s3, $s3, -0x1ef0 +/* 09A318 80099718 2673E110 */ addiu $s3, %lo(gMenuTextureBufferIndex) # addiu $s3, $s3, -0x1ef0 /* 09A31C 8009971C 2694E758 */ addiu $s4, %lo(gNumD_8018E118Entries) # addiu $s4, $s4, -0x18a8 /* 09A320 80099720 26B5D9B4 */ addiu $s5, %lo(D_8018D9B4) # addiu $s5, $s5, -0x264c /* 09A324 80099724 24160001 */ li $s6, 1 diff --git a/asm/non_matchings/code_80091750/func_8009F5E0.s b/asm/non_matchings/code_80091750/func_8009F5E0.s index 3cf6765e0..08dc2b827 100644 --- a/asm/non_matchings/code_80091750/func_8009F5E0.s +++ b/asm/non_matchings/code_80091750/func_8009F5E0.s @@ -195,7 +195,7 @@ glabel L8009F6CC glabel L8009F6E4 /* 0A02E4 8009F6E4 3C048015 */ lui $a0, %hi(gGfxPool) # $a0, 0x8015 /* 0A02E8 8009F6E8 8C84EF40 */ lw $a0, %lo(gGfxPool)($a0) -/* 0A02EC 8009F6EC 0C0251ED */ jal func_800947B4 +/* 0A02EC 8009F6EC 0C0251ED */ jal render_checkered_flag /* 0A02F0 8009F6F0 8E25001C */ lw $a1, 0x1c($s1) /* 0A02F4 8009F6F4 10000474 */ b .L800A08C8 /* 0A02F8 8009F6F8 8FBF0034 */ lw $ra, 0x34($sp) @@ -289,7 +289,7 @@ glabel L8009F830 /* 0A043C 8009F83C 10000422 */ b .L800A08C8 /* 0A0440 8009F840 8FBF0034 */ lw $ra, 0x34($sp) glabel L8009F844 -/* 0A0444 8009F844 0C02D557 */ jal func_800B555C +/* 0A0444 8009F844 0C02D557 */ jal has_unlocked_extra_mode /* 0A0448 8009F848 00000000 */ nop /* 0A044C 8009F84C 00025880 */ sll $t3, $v0, 2 /* 0A0450 8009F850 3C05800E */ lui $a1, %hi(D_800E7D4C) @@ -597,7 +597,7 @@ glabel L8009FB24 /* 0A08D0 8009FCD0 100002FD */ b .L800A08C8 /* 0A08D4 8009FCD4 8FBF0034 */ lw $ra, 0x34($sp) glabel L8009FCD8 -/* 0A08D8 8009FCD8 0C02D557 */ jal func_800B555C +/* 0A08D8 8009FCD8 0C02D557 */ jal has_unlocked_extra_mode /* 0A08DC 8009FCDC 00000000 */ nop /* 0A08E0 8009FCE0 00026880 */ sll $t5, $v0, 2 /* 0A08E4 8009FCE4 3C05800E */ lui $a1, %hi(D_800E7D4C) diff --git a/asm/non_matchings/menus/main_menu_act.s b/asm/non_matchings/menus/main_menu_act.s index f03d69c88..aaf78962e 100644 --- a/asm/non_matchings/menus/main_menu_act.s +++ b/asm/non_matchings/menus/main_menu_act.s @@ -463,7 +463,7 @@ glabel L800B2F70 # case 5, 8 /* 0B3C70 800B3070 00000000 */ nop /* 0B3C74 800B3074 AFA00024 */ sw $zero, 0x24($sp) /* 0B3C78 800B3078 AFA50028 */ sw $a1, 0x28($sp) -/* 0B3C7C 800B307C 0C02D557 */ jal func_800B555C +/* 0B3C7C 800B307C 0C02D557 */ jal has_unlocked_extra_mode /* 0B3C80 800B3080 AFA6001C */ sw $a2, 0x1c($sp) /* 0B3C84 800B3084 8FA30024 */ lw $v1, 0x24($sp) /* 0B3C88 800B3088 8FA50028 */ lw $a1, 0x28($sp) diff --git a/courses/test_course/data.c b/courses/test_course/data.c new file mode 100644 index 000000000..a39c05dc5 --- /dev/null +++ b/courses/test_course/data.c @@ -0,0 +1,75 @@ +#include "waypoints.h" +#include "course.h" +#include + +extern Gfx mario_Plane_001_mesh[]; + +Gfx test_course_data_dl[] = { + gsDPSetCombineMode(G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA), + gsDPSetRenderMode(G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2), + gsSPClearGeometryMode(G_CULL_BACK), + gsSPDisplayList(mario_Plane_001_mesh), +}; + +TrackWaypoint test_course_path[] = { + { 0, 0, 0, 0}, + { 0, 0, -100, 1}, + { 0, 0, -200, 1}, + { 0, 0, -300, 1}, + { 0, 0, -400, 1}, + { 0, 0, -500, 1}, + { 0, 0, -600, 1}, + { 0, 0, -700, 1}, + { 0, 0, -800, 1}, + { 0, 0, -900, 1}, + { 0, 0, -1000, 1}, + { 0, 0, -1096, 1}, // Main point 1 + { 100, 0, -1090, 2}, + { 200, 0, -1085, 2}, + { 300, 0, -1080, 2}, + { 400, 0, -1075, 2}, + { 500, 0, -1072, 2}, // Curve begins to smooth here + { 600, 0, -1068, 2}, + { 700, 0, -1065, 2}, + { 800, 0, -1063, 2}, + { 900, 0, -1061, 2}, + { 984, 0, -1060, 2}, // Main point 2 + { 990, 0, -900, 3}, + { 995, 0, -800, 3}, + { 997, 0, -700, 3}, + { 998, 0, -600, 3}, + { 999, 0, -500, 3}, + { 999, 0, -400, 3}, + { 999, 0, -300, 3}, + { 999, 0, -200, 3}, + { 999, 0, -100, 3}, + { 999, 0, 0,3}, + { 999, 0, 100, 3}, + { 999, 0, 200, 3}, + { 999, 0, 300, 3}, + { 999, 0, 400, 3}, + { 999, 0, 500, 3}, + { 999, 0, 600, 3}, + { 999, 0, 700, 3}, + { 999, 0, 800, 3}, + { 999, 0, 900, 3}, + { 999, 0, 940, 3}, // Main point 3 + { 900, 0, 945, 4}, + { 800, 0, 945, 4}, + { 700, 0, 947, 4}, + { 600, 0, 948, 4}, + { 500, 0, 949, 4}, + { 400, 0, 949, 4}, + { 300, 0, 949, 4}, + { 200, 0, 950, 4}, + { 100, 0, 950, 4}, + { 0, 0, 950, 1}, // Main point 4 + + // End of path + { -32768, -32768, -32768, 0 } // Terminator +}; + +TrackSections test_course_addr[] = { + { mario_Plane_001_mesh, 255, 255, 0x0000 }, + { 0x00000000, 0, 0, 0x00000 }, +}; diff --git a/courses/test_course/model.c b/courses/test_course/model.c new file mode 100644 index 000000000..61405fff1 --- /dev/null +++ b/courses/test_course/model.c @@ -0,0 +1,389 @@ +#include +#include +#include "assets/other_textures.h" + +Lights1 mario_f3dlite_material_009_lights = gdSPDefLights1( + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x49, 0x49, 0x49); + +Lights1 mario_f3dlite_material_lights = gdSPDefLights1( + 0x7F, 0x7F, 0x7F, + 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49); + +Vtx mario_Plane_001_mesh_vtx_cull[8] = { + {{ {-431, 0, -1544}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {-431, 0, 1394}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {-431, 9, 1394}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {-431, 9, -1544}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {1522, 0, -1544}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {1522, 0, 1394}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {1522, 9, 1394}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {1522, 9, -1544}, 0, {0, 0}, {0, 0, 0, 0} }}, +}; + +Vtx mario_Plane_001_mesh_vtx_0[114] = { + {{ {984, 0, -1177}, 0, {2037, -25}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1011, 0, -1164}, 0, {2025, 1009}, {0, 127, 0, 255} }}, + {{ {961, 0, -1184}, 0, {2035, -23}, {0, 127, 0, 255} }}, + {{ {984, 0, -1177}, 0, {2025, 999}, {0, 127, 0, 255} }}, + {{ {961, 0, -1184}, 0, {2036, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1188}, 0, {2031, -20}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {-20, -16}, {0, 127, 0, 255} }}, + {{ {-85, 0, 271}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, 271}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, -716}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {-85, 0, -716}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-85, 0, -716}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, -716}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, -1018}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {-85, 0, -1107}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-70, 0, -1146}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-51, 0, -1173}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, -1018}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {-26, 0, -1192}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {2, 0, -1205}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {30, 0, -1211}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {60, 0, -1214}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, -1217}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {124, 0, -1211}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {156, 0, -1188}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1188}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {156, 0, -1188}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {954, 0, 656}, 0, {-16, 880}, {0, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1095, 0, 895}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {1095, 0, 417}, 0, {2032, 752}, {0, 127, 0, 255} }}, + {{ {1095, 9, -62}, 0, {2032, 496}, {0, 127, 0, 255} }}, + {{ {1095, 6, 178}, 0, {2032, 624}, {0, 127, 0, 255} }}, + {{ {1095, 0, -540}, 0, {2032, 240}, {0, 127, 0, 255} }}, + {{ {1095, 5, -301}, 0, {2032, 368}, {0, 127, 0, 255} }}, + {{ {942, 9, -62}, 0, {-16, 496}, {0, 127, 0, 255} }}, + {{ {946, 5, 178}, 0, {-16, 624}, {0, 127, 0, 255} }}, + {{ {950, 0, 417}, 0, {-16, 752}, {0, 127, 0, 255} }}, + {{ {938, 7, -301}, 0, {-16, 368}, {0, 127, 0, 255} }}, + {{ {929, 0, -779}, 0, {-16, 112}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1095, 0, -1018}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {933, 0, -540}, 0, {-16, 240}, {0, 127, 0, 255} }}, + {{ {85, 0, 895}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {958, 0, 1065}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, 1065}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {51, 0, 1059}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {21, 0, 1053}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-9, 0, 1042}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-31, 0, 1029}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-50, 0, 1008}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-70, 0, 981}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-78, 0, 963}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-82, 0, 936}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 895}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, 271}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 271}, 0, {2032, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 895}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, 271}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 895}, 0, {2032, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, 895}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1095, 0, 895}, 0, {2032, 1008}, {0, 127, 252, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 252, 255} }}, + {{ {1090, 1, 933}, 0, {2032, 1008}, {0, 127, 252, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 252, 255} }}, + {{ {1090, 1, 933}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {1086, 1, 957}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {1086, 1, 957}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {1078, 1, 979}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {1078, 1, 979}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {1069, 1, 999}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {1069, 1, 999}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {1059, 1, 1019}, 0, {2032, 1008}, {255, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 0, 255} }}, + {{ {1059, 1, 1019}, 0, {2032, 1008}, {255, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {255, 127, 255, 255} }}, + {{ {1042, 1, 1035}, 0, {2032, 1008}, {255, 127, 255, 255} }}, + {{ {1059, 1, 1019}, 0, {2032, 1008}, {0, 129, 0, 255} }}, + {{ {1042, 1, 1035}, 0, {2032, 1008}, {0, 129, 0, 255} }}, + {{ {1020, 1, 1047}, 0, {2032, 1008}, {0, 129, 0, 255} }}, + {{ {1038, 1, 1031}, 0, {2032, 1008}, {0, 129, 0, 255} }}, + {{ {1042, 1, 1035}, 0, {2032, 1008}, {0, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 255, 255} }}, + {{ {1020, 1, 1047}, 0, {2032, 1008}, {0, 127, 255, 255} }}, + {{ {1020, 1, 1047}, 0, {2032, 1008}, {0, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 255, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {0, 127, 255, 255} }}, + {{ {991, 1, 1058}, 0, {2032, 1008}, {0, 127, 255, 255} }}, + {{ {991, 1, 1058}, 0, {2032, 1008}, {251, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {251, 127, 0, 255} }}, + {{ {958, 0, 1065}, 0, {2032, 1008}, {251, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {-16, 1008}, {251, 127, 0, 255} }}, + {{ {1095, 0, -1018}, 0, {2024, -19}, {0, 127, 0, 255} }}, + {{ {1098, 0, -1036}, 0, {2045, -12}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1098, 0, -1058}, 0, {2040, -24}, {0, 127, 0, 255} }}, + {{ {1090, 0, -1080}, 0, {2037, -18}, {0, 127, 0, 255} }}, + {{ {1077, 0, -1103}, 0, {2037, -27}, {0, 127, 0, 255} }}, + {{ {1059, 0, -1129}, 0, {2040, -13}, {0, 127, 0, 255} }}, + {{ {1036, 0, -1149}, 0, {2032, -15}, {0, 127, 0, 255} }}, + {{ {1011, 0, -1164}, 0, {2033, -15}, {0, 127, 0, 255} }}, +}; + +Gfx mario_Plane_001_mesh_tri_0[] = { + gsSPVertex(mario_Plane_001_mesh_vtx_0 + 0, 30, 0), + gsSP2Triangles(0, 1, 2, 0, 3, 1, 4, 0), + gsSP2Triangles(5, 6, 7, 0, 8, 9, 10, 0), + gsSP2Triangles(8, 10, 11, 0, 12, 13, 14, 0), + gsSP2Triangles(12, 14, 15, 0, 15, 14, 14, 0), + gsSP2Triangles(15, 14, 16, 0, 16, 14, 17, 0), + gsSP2Triangles(14, 18, 17, 0, 17, 18, 18, 0), + gsSP2Triangles(17, 18, 19, 0, 19, 18, 18, 0), + gsSP2Triangles(19, 18, 20, 0, 20, 18, 18, 0), + gsSP2Triangles(20, 18, 21, 0, 21, 18, 14, 0), + gsSP2Triangles(21, 14, 22, 0, 22, 14, 23, 0), + gsSP2Triangles(14, 18, 23, 0, 23, 18, 14, 0), + gsSP2Triangles(23, 14, 24, 0, 24, 14, 18, 0), + gsSP2Triangles(24, 18, 25, 0, 26, 27, 28, 0), + gsSP1Triangle(26, 28, 29, 0), + gsSPVertex(mario_Plane_001_mesh_vtx_0 + 30, 32, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSP2Triangles(0, 3, 4, 0, 3, 5, 4, 0), + gsSP2Triangles(0, 4, 6, 0, 4, 7, 6, 0), + gsSP2Triangles(8, 0, 6, 0, 8, 9, 0, 0), + gsSP2Triangles(9, 10, 0, 0, 6, 11, 8, 0), + gsSP2Triangles(6, 12, 11, 0, 6, 13, 12, 0), + gsSP2Triangles(6, 14, 13, 0, 12, 15, 11, 0), + gsSP2Triangles(16, 17, 18, 0, 16, 19, 17, 0), + gsSP2Triangles(19, 16, 16, 0, 19, 16, 20, 0), + gsSP2Triangles(20, 16, 16, 0, 20, 16, 21, 0), + gsSP2Triangles(21, 16, 16, 0, 21, 16, 22, 0), + gsSP2Triangles(22, 16, 16, 0, 22, 16, 23, 0), + gsSP2Triangles(23, 16, 16, 0, 23, 16, 24, 0), + gsSP2Triangles(24, 16, 16, 0, 24, 16, 25, 0), + gsSP2Triangles(25, 16, 16, 0, 25, 16, 26, 0), + gsSP2Triangles(26, 16, 16, 0, 26, 16, 27, 0), + gsSP2Triangles(27, 16, 28, 0, 16, 16, 28, 0), + gsSP1Triangle(29, 30, 31, 0), + gsSPVertex(mario_Plane_001_mesh_vtx_0 + 62, 31, 0), + gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0), + gsSP2Triangles(4, 6, 5, 0, 7, 8, 9, 0), + gsSP2Triangles(7, 9, 10, 0, 11, 12, 12, 0), + gsSP2Triangles(11, 12, 14, 0, 15, 16, 16, 0), + gsSP2Triangles(15, 16, 18, 0, 19, 20, 21, 0), + gsSP2Triangles(20, 22, 21, 0, 23, 24, 24, 0), + gsSP2Triangles(23, 24, 26, 0, 27, 28, 29, 0), + gsSP1Triangle(27, 29, 30, 0), + gsSPVertex(mario_Plane_001_mesh_vtx_0 + 93, 21, 0), + gsSP2Triangles(0, 1, 1, 0, 0, 1, 3, 0), + gsSP2Triangles(4, 5, 5, 0, 4, 5, 7, 0), + gsSP2Triangles(8, 9, 10, 0, 9, 11, 10, 0), + gsSP2Triangles(12, 13, 14, 0, 13, 15, 14, 0), + gsSP2Triangles(15, 16, 14, 0, 17, 14, 16, 0), + gsSP2Triangles(18, 14, 17, 0, 19, 14, 18, 0), + gsSP1Triangle(20, 14, 19, 0), + gsSPEndDisplayList(), +}; + +Vtx mario_Plane_001_mesh_vtx_1[92] = { + {{ {1090, 1, 933}, 0, {1008, 1008}, {32, 123, 0, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {32, 123, 0, 255} }}, + {{ {1095, 0, 895}, 0, {1008, 1008}, {32, 123, 0, 255} }}, + {{ {1086, 1, 957}, 0, {1008, 1008}, {6, 127, 1, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {6, 127, 1, 255} }}, + {{ {1090, 1, 933}, 0, {1008, 1008}, {6, 127, 1, 255} }}, + {{ {1078, 1, 979}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {3, 127, 1, 255} }}, + {{ {1086, 1, 957}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1069, 1, 999}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {3, 127, 1, 255} }}, + {{ {1078, 1, 979}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1059, 1, 1019}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {3, 127, 1, 255} }}, + {{ {1069, 1, 999}, 0, {1008, 1008}, {3, 127, 1, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {2, 127, 3, 255} }}, + {{ {1042, 1, 1035}, 0, {1008, 1008}, {2, 127, 3, 255} }}, + {{ {1020, 1, 1047}, 0, {1008, 1008}, {2, 127, 3, 255} }}, + {{ {1042, 1, 1035}, 0, {-16, 1008}, {2, 127, 2, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {2, 127, 2, 255} }}, + {{ {1059, 1, 1019}, 0, {-16, 1008}, {2, 127, 2, 255} }}, + {{ {991, 1, 1058}, 0, {1008, 1008}, {1, 127, 3, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {1, 127, 3, 255} }}, + {{ {1020, 1, 1047}, 0, {1008, 1008}, {1, 127, 3, 255} }}, + {{ {958, 0, 1065}, 0, {1008, 1008}, {0, 125, 23, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {0, 125, 23, 255} }}, + {{ {991, 1, 1058}, 0, {1008, 1008}, {0, 125, 23, 255} }}, + {{ {85, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, 895}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {958, 0, 895}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {942, 0, -62}, 0, {1008, 496}, {0, 127, 0, 255} }}, + {{ {925, 0, -1018}, 0, {1008, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, 1065}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 1065}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, -1217}, 0, {1008, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, -1217}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, 1394}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1522, 0, 1394}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {1522, 0, 1065}, 0, {1008, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, 1065}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1095, 0, 23}, 0, {-16, 496}, {0, 127, 0, 255} }}, + {{ {1095, 0, 1065}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1522, 0, 1065}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {1095, 0, -1018}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1522, 0, -1018}, 0, {1008, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, -1544}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-431, 0, -1217}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {156, 0, -1217}, 0, {240, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1217}, 0, {496, 1008}, {0, 127, 0, 255} }}, + {{ {1521, 0, -1544}, 0, {1008, -16}, {0, 127, 0, 255} }}, + {{ {1521, 0, -1217}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {85, 0, 1065}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {51, 0, 1059}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 1065}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {21, 0, 1053}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-9, 0, 1042}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-31, 0, 1029}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-50, 0, 1008}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-70, 0, 981}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-78, 0, 963}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-82, 0, 936}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {-85, 0, 895}, 0, {1008, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1188}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {961, 0, -1184}, 0, {1010, 1008}, {0, 127, 0, 255} }}, + {{ {156, 0, -1217}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1188}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {925, 0, -1217}, 0, {496, 1008}, {0, 127, 0, 255} }}, + {{ {156, 0, -1188}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {124, 0, -1211}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {85, 0, -1217}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {1098, 0, -1036}, 0, {1014, -12}, {0, 127, 0, 255} }}, + {{ {1095, 0, -1018}, 0, {1004, -19}, {0, 127, 0, 255} }}, + {{ {1522, 0, -1018}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1098, 0, -1058}, 0, {1012, -24}, {0, 127, 0, 255} }}, + {{ {1522, 0, -1058}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1098, 0, -1217}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1521, 0, -1217}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {1090, 0, -1080}, 0, {1010, -18}, {0, 127, 0, 255} }}, + {{ {1077, 0, -1103}, 0, {1010, -27}, {0, 127, 0, 255} }}, + {{ {1059, 0, -1129}, 0, {1012, -13}, {0, 127, 0, 255} }}, + {{ {1036, 0, -1149}, 0, {1008, -15}, {0, 127, 0, 255} }}, + {{ {1011, 0, -1164}, 0, {1008, -15}, {0, 127, 0, 255} }}, + {{ {984, 0, -1177}, 0, {1011, -25}, {0, 127, 0, 255} }}, + {{ {961, 0, -1184}, 0, {1010, -23}, {0, 127, 0, 255} }}, + {{ {-85, 0, -1107}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-70, 0, -1146}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-85, 0, -1217}, 0, {-16, 1008}, {0, 127, 0, 255} }}, + {{ {-51, 0, -1173}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {-26, 0, -1192}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {2, 0, -1205}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {30, 0, -1211}, 0, {-16, -16}, {0, 127, 0, 255} }}, + {{ {60, 0, -1214}, 0, {-16, -16}, {0, 127, 0, 255} }}, +}; + +Gfx mario_Plane_001_mesh_tri_1[] = { + gsSPVertex(mario_Plane_001_mesh_vtx_1 + 0, 32, 0), + gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0), + gsSP2Triangles(6, 7, 8, 0, 9, 10, 11, 0), + gsSP2Triangles(12, 13, 14, 0, 15, 16, 17, 0), + gsSP2Triangles(18, 19, 20, 0, 21, 22, 23, 0), + gsSP2Triangles(24, 25, 26, 0, 27, 28, 29, 0), + gsSP2Triangles(29, 30, 27, 0, 30, 31, 27, 0), + gsSPVertex(mario_Plane_001_mesh_vtx_1 + 32, 32, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSP2Triangles(4, 5, 6, 0, 4, 6, 7, 0), + gsSP2Triangles(8, 9, 10, 0, 10, 11, 8, 0), + gsSP2Triangles(10, 12, 11, 0, 13, 14, 15, 0), + gsSP2Triangles(13, 15, 16, 0, 16, 17, 13, 0), + gsSP2Triangles(16, 18, 17, 0, 19, 20, 21, 0), + gsSP2Triangles(20, 22, 21, 0, 22, 23, 21, 0), + gsSP2Triangles(24, 21, 23, 0, 24, 25, 21, 0), + gsSP2Triangles(25, 26, 21, 0, 26, 27, 21, 0), + gsSP2Triangles(27, 28, 21, 0, 28, 29, 21, 0), + gsSP1Triangle(30, 31, 16, 0), + gsSPVertex(mario_Plane_001_mesh_vtx_1 + 64, 28, 0), + gsSP2Triangles(0, 1, 2, 0, 3, 1, 0, 0), + gsSP2Triangles(3, 0, 4, 0, 5, 4, 0, 0), + gsSP2Triangles(6, 7, 8, 0, 9, 6, 8, 0), + gsSP2Triangles(9, 8, 10, 0, 11, 9, 10, 0), + gsSP2Triangles(11, 10, 12, 0, 9, 11, 13, 0), + gsSP2Triangles(13, 11, 14, 0, 14, 11, 15, 0), + gsSP2Triangles(15, 11, 16, 0, 16, 11, 17, 0), + gsSP2Triangles(17, 11, 18, 0, 18, 11, 19, 0), + gsSP2Triangles(2, 19, 11, 0, 20, 21, 22, 0), + gsSP2Triangles(23, 22, 21, 0, 23, 24, 22, 0), + gsSP2Triangles(24, 25, 22, 0, 25, 26, 22, 0), + gsSP2Triangles(26, 27, 22, 0, 27, 5, 22, 0), + gsSPEndDisplayList(), +}; + +Gfx mat_mario_f3dlite_material_009[] = { + gsSPClearGeometryMode(G_CLIPPING), + gsSPSetLights1(mario_f3dlite_material_009_lights), + gsDPPipeSync(), + gsDPSetCombineLERP(TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT, TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, ENVIRONMENT), + gsDPSetAlphaDither(G_AD_NOISE), + gsSPTexture(65535, 65535, 0, 0, 1), + gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 1, gTextureRoad2), + gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 0, 0, 7, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0), + gsDPLoadBlock(7, 0, 0, 1023, 256), + gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b, 8, 0, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 6, 0), + gsDPSetTileSize(0, 0, 0, 252, 124), + gsSPEndDisplayList(), +}; + +Gfx mat_revert_mario_f3dlite_material_009[] = { + gsSPSetGeometryMode(G_CLIPPING), + gsDPPipeSync(), + gsDPSetAlphaDither(G_AD_DISABLE), + gsSPEndDisplayList(), +}; + +Gfx mat_mario_f3dlite_material[] = { + gsSPClearGeometryMode(G_CLIPPING), + gsSPSetLights1(mario_f3dlite_material_lights), + gsDPPipeSync(), + gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT), + gsDPSetAlphaDither(G_AD_NOISE), + gsSPTexture(65535, 65535, 0, 0, 1), + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b_LOAD_BLOCK, 1, gTextureGrass1), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b_LOAD_BLOCK, 0, 0, 7, 0, G_TX_WRAP, 0, 0, G_TX_WRAP, 0, 0), + gsDPLoadBlock(7, 0, 0, 1023, 256), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, 0, 0, G_TX_WRAP, 5, 0, G_TX_WRAP, 5, 0), + gsDPSetTileSize(0, 0, 0, 32, 32), + gsSPEndDisplayList(), +}; + +Gfx mat_revert_mario_f3dlite_material[] = { + gsSPSetGeometryMode(G_CLIPPING), + gsDPPipeSync(), + gsDPSetAlphaDither(G_AD_DISABLE), + gsSPEndDisplayList(), +}; + +Gfx mario_Plane_001_mesh[] = { + gsSPClearGeometryMode(G_LIGHTING), + gsSPVertex(mario_Plane_001_mesh_vtx_cull + 0, 8, 0), + gsSPSetGeometryMode(G_LIGHTING), + gsSPCullDisplayList(0, 7), + gsSPDisplayList(mat_mario_f3dlite_material_009), + gsSPDisplayList(mario_Plane_001_mesh_tri_0), + gsSPDisplayList(mat_revert_mario_f3dlite_material_009), + gsSPDisplayList(mat_mario_f3dlite_material), + gsSPDisplayList(mario_Plane_001_mesh_tri_1), + gsSPDisplayList(mat_revert_mario_f3dlite_material), + gsDPPipeSync(), + gsSPSetGeometryMode(G_LIGHTING), + gsSPClearGeometryMode(G_TEXTURE_GEN), + gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT), + gsSPTexture(65535, 65535, 0, 0, 0), + gsSPEndDisplayList(), +}; + diff --git a/courses/test_course/vtx.c b/courses/test_course/vtx.c new file mode 100644 index 000000000..24a4cc07a --- /dev/null +++ b/courses/test_course/vtx.c @@ -0,0 +1,16 @@ +#include "mk64.h" +#include "common_structs.h" + +CourseVtx test_course_vertices[] = { + // Top-left vertex (x, y, z), texture coord (tc), color and alpha (ca) + {{ -100, 100, 0}, { 0, 0}, {MACRO_COLOR_FLAG(0xFF, 0x00, 0x00, 0), 0x00}}, // Red + + // Top-right vertex + {{ 100, 100, 0}, { 1024, 0}, {MACRO_COLOR_FLAG(0x00, 0xFF, 0x00, 0), 0x00}}, // Green + + // Bottom-right vertex + {{ 100, -100, 0}, { 1024, 1024}, {MACRO_COLOR_FLAG(0x00, 0x00, 0xFF, 0), 0x00}}, // Blue + + // Bottom-left vertex + {{ -100, -100, 0}, { 0, 1024}, {MACRO_COLOR_FLAG(0xFF, 0xFF, 0x00, 0), 0x00}}, // Yellow +}; diff --git a/include/common_structs.h b/include/common_structs.h index 46e3895da..db8e189c9 100644 --- a/include/common_structs.h +++ b/include/common_structs.h @@ -125,6 +125,15 @@ struct UnkStruct_800DDB68 { }; /*** Types.h end ***/ +struct Skybox { + s16 unk0; + s16 unk2; + s16 unk4; + s16 unk6; + s16 unk8; + s16 unkA; +}; + typedef struct { u8 button; s8 frameDuration; @@ -397,6 +406,11 @@ typedef struct { /* 0x7F */ u8 checksum; } struct_8018EE10_entry; // size = 0x80 +typedef struct { + uint8_t r, g, b; +} RGB8; + + typedef struct { /* 0x00 */ u16 red; /* 0x02 */ u16 green; diff --git a/include/course_offsets.h b/include/course_offsets.h index 5f5ddfec9..947ebbebf 100644 --- a/include/course_offsets.h +++ b/include/course_offsets.h @@ -8,7 +8,7 @@ #include "animation.h" typedef struct { - u8* addr; // segmented address texture file + const char* addr; // segmented address texture file u32 file_size; // compressed file size u32 data_size; // uncompressed texture size u32 padding; // always zero diff --git a/include/defines.h b/include/defines.h index 4172ae5a0..11394a6c2 100644 --- a/include/defines.h +++ b/include/defines.h @@ -199,7 +199,7 @@ enum { COURSE_ONE, COURSE_TWO, COURSE_THREE, COURSE_FOUR }; #define CONTROLLER_PAK_MENU 9 #define START_MENU 10 #define MAIN_MENU 11 -#define PLAYER_SELECT_MENU 12 +#define CHARACTER_SELECT_MENU 12 #define COURSE_SELECT_MENU 13 #define RACING_DUPLICATE 14 diff --git a/src/actors/falling_rock/update.inc.c b/src/actors/falling_rock/update.inc.c index c0e58f27d..b6a4f541b 100644 --- a/src/actors/falling_rock/update.inc.c +++ b/src/actors/falling_rock/update.inc.c @@ -29,9 +29,16 @@ void func_8029CF0C(struct ActorSpawnData* spawnData, struct FallingRock* rock) { * * @param spawnData */ -void spawn_falling_rocks(struct ActorSpawnData* spawnData) { +struct ActorSpawnData* rocks; +void spawn_falling_rocks(const char* spawnData) { #ifndef TARGET_N64 - struct ActorSpawnData* temp_s0 = (struct ActorSpawnData*) LOAD_ASSET(spawnData); + struct ActorSpawnData* temp_s0; + if (GetCourse() == GetTestCourse()) { + temp_s0 = (struct ActorSpawnData*) spawnData; + } else { + temp_s0 = (struct ActorSpawnData*) LOAD_ASSET(spawnData); + } + rocks = temp_s0; #else s32 addr = SEGMENT_NUMBER2(spawnData); s32 offset = SEGMENT_OFFSET(spawnData); @@ -75,7 +82,7 @@ void update_actor_falling_rocks(struct FallingRock* rock) { return; } if (rock->pos[1] < D_8015F8E4) { - func_8029CF0C(d_course_choco_mountain_falling_rock_spawns, rock); + func_8029CF0C(rocks, rock); } rock->rot[0] += (s16) ((rock->velocity[2] * 5461.0f) / 20.0f); rock->rot[2] += (s16) ((rock->velocity[0] * 5461.0f) / 20.0f); diff --git a/src/actors/piranha_plant/render.inc.c b/src/actors/piranha_plant/render.inc.c index 88838f603..42cc0fc23 100644 --- a/src/actors/piranha_plant/render.inc.c +++ b/src/actors/piranha_plant/render.inc.c @@ -120,7 +120,7 @@ void render_actor_piranha_plant(Camera* arg0, Mat4 arg1, struct PiranhaPlant* ar G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - if (gCurrentCourseId == COURSE_MARIO_RACEWAY) { + if (GetCourse() == GetMarioRaceway()) { gSPDisplayList(gDisplayListHead++, &d_course_mario_raceway_dl_piranha_plant); } else { gSPDisplayList(gDisplayListHead++, &d_course_royal_raceway_dl_piranha_plant); diff --git a/src/actors/trees/render.inc.c b/src/actors/trees/render.inc.c index e3042a8f3..9ae645199 100644 --- a/src/actors/trees/render.inc.c +++ b/src/actors/trees/render.inc.c @@ -202,14 +202,10 @@ void func_80299864(Camera* camera, Mat4 arg1, struct Actor* arg2) { // Unless both courses use this actor and use the same addr for the texture. // Just in-case changed the code into a switch to prevent future crashes. // This comment can be removed when this is confirmed to work. - - switch (gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FC70); - break; - case COURSE_MOO_MOO_FARM: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_mole_tlut); - break; + if (GetCourse() == GetLuigiRaceway()) { + gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FC70); + } else if (GetCourse() == GetMooMooFarm()) { + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_mole_tlut); } } } diff --git a/src/audio/external.c b/src/audio/external.c index 9afb13843..a992b3a51 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2646,11 +2646,11 @@ void func_800C847C(u8 playerId) { func_800C97C4(playerId); D_800E9F74[playerId] = 1; func_800C94A4(playerId); - if (((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_BOWSER_CASTLE) || - (gCurrentCourseId == COURSE_BANSHEE_BOARDWALK) || (gCurrentCourseId == COURSE_YOSHI_VALLEY) || - (gCurrentCourseId == COURSE_FRAPPE_SNOWLAND) || (gCurrentCourseId == COURSE_KOOPA_BEACH) || - (gCurrentCourseId == COURSE_ROYAL_RACEWAY) || (gCurrentCourseId == COURSE_SHERBET_LAND) || - (gCurrentCourseId == COURSE_DK_JUNGLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) && + if (((GetCourse() == GetChocoMountain()) || (GetCourse() == GetBowsersCastle()) || + (GetCourse() == GetBansheeBoardwalk()) || (GetCourse() == GetYoshiValley()) || + (GetCourse() == GetFrappeSnowland()) || (GetCourse() == GetKoopaTroopaBeach()) || + (GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetSherbetLand()) || + (GetCourse() == GetDkJungle()) || (GetCourse() == GetBigDonut())) && (D_800EA0EC[playerId] == 0)) { play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x05), &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4, @@ -2663,7 +2663,7 @@ void func_800C847C(u8 playerId) { D_800E9F74[playerId] = 2; func_800C94A4(playerId); D_800E9F74[playerId] = 0; - if ((gCurrentCourseId == COURSE_KOOPA_BEACH) && (D_800EA0EC[playerId] == 0)) { + if ((GetCourse() == GetKoopaTroopaBeach()) && (D_800EA0EC[playerId] == 0)) { play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x08), &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4, (u8*) &D_800E9F7C[playerId].unk_14); @@ -2745,7 +2745,7 @@ void func_800C89E4(void) { } void func_800C8AE4(void) { - if (gCurrentCourseId == COURSE_LUIGI_RACEWAY) { + if (GetCourse() == GetLuigiRaceway()) { if (D_800EA184 != 0) { if ((u8) D_800EA16C == 0) { // Has to be this way, can't be D_800EA184++ @@ -2823,11 +2823,11 @@ void func_800C8CCC() { } void play_sound2(s32 soundBits) { - if ((soundBits == SOUND_ACTION_REV_ENGINE) && (gCurrentCourseId == COURSE_DK_JUNGLE)) { + if ((soundBits == SOUND_ACTION_REV_ENGINE) && (GetCourse() == GetDkJungle())) { soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x27); } - if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (gCurrentCourseId == COURSE_DK_JUNGLE)) { + if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (GetCourse() == GetDkJungle())) { soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x28); } play_sound(soundBits, &D_800EA1C8, 4, &D_800EA1D4, &D_800EA1D4, &D_800EA1DC); diff --git a/src/camera.c b/src/camera.c index 91510e62c..d4ebd36cf 100644 --- a/src/camera.c +++ b/src/camera.c @@ -19,6 +19,8 @@ #include "enhancements/freecam/freecam_engine.h" #include "freecam.h" +#include "engine/GameAPI.h" + f32 D_800DDB30[] = { 0.4f, 0.6f, 0.275f, 0.3f }; Camera cameras[4]; @@ -235,7 +237,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3, arg2[2] = camera->lookAt[2]; calculate_orientation_matrix(sp74, 0, 1, 0, -0x00008000); mtxf_translate_vec3f_mat3(sp5C, sp74); - if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) { + if (GetCourse() == GetToadsTurnpike()) { var_f14 = sp5C[0]; } else { var_f14 = sp5C[0] + temp_s2->posX; @@ -246,7 +248,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3, arg2[1] += (temp_f18 - camera->lookAt[1]) * 1; arg2[2] += (temp_f16 - camera->lookAt[2]) * 1; mtxf_translate_vec3f_mat3(sp68, sp74); - if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) { + if (GetCourse() == GetToadsTurnpike()) { var_f14 = sp68[0]; } else { var_f14 = sp68[0] + temp_s2->posX; @@ -339,7 +341,7 @@ void func_8001CCEC(Player* player, Camera* camera, Vec3f arg2, f32* arg3, f32* a move_f32_towards(&D_80164AA0[index], 10, 0.02f); break; default: - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { move_f32_towards(&D_80164A90[index], 50, 0.04f); move_f32_towards(&D_80164AA0[index], 35, 0.04f); } else { diff --git a/src/code_800029B0.c b/src/code_800029B0.c index c319d3bef..4f2b7fe30 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -189,6 +189,10 @@ void setup_race(void) { } if (gModeSelection == GRAND_PRIX) { gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + // Skip for debug menu + if (gDebugMenuSelection < DEBUG_MENU) { + SetCourseFromCup(); + } } gActiveScreenMode = gScreenModeSelection; if (gCurrentCourseId != gCurrentlyLoadedCourseId) { @@ -220,9 +224,9 @@ void setup_race(void) { D_8015F8D0[1] = (f32) (D_80164490->posY - 15); ; D_8015F8D0[2] = D_80164490->posZ; - if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) { + if (GetCourse() == GetToadsTurnpike()) { D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; - } else if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + } else if (GetCourse() == GetWarioStadium()) { D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; } else { D_8015F8D0[0] = D_80164490->posX; @@ -245,40 +249,43 @@ void setup_race(void) { } void func_80002DAC(void) { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - vec3f_set(D_8015F748, -223.0f, 94.0f, -155.0f); - func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); - break; - case COURSE_ROYAL_RACEWAY: - vec3f_set(D_8015F748, 177.0f, 87.0f, -393.0f); - func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); - break; - case COURSE_LUIGI_RACEWAY: - vec3f_set(D_8015F748, 85.0f, 21.0f, -219.0f); - func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); - break; - case COURSE_WARIO_STADIUM: - vec3f_set(D_8015F748, 298.0f, 202.0f, -850.0f); - func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); - vec3f_set(D_8015F758, -1600.0f, 202.0f, -2430.0f); - func_800C9D80(D_8015F758, D_802B91C8, 0x5103700B); - vec3f_set(D_8015F768, -2708.0f, 202.0f, 1762.0f); - func_800C9D80(D_8015F768, D_802B91C8, 0x5103700B); - vec3f_set(D_8015F778, -775.0f, 202.0f, 1930.0f); - func_800C9D80(D_8015F778, D_802B91C8, 0x5103700B); - break; - case COURSE_KOOPA_BEACH: - vec3f_set(D_8015F738, 153.0f, 0.0f, 2319.0f); - func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); - break; - case COURSE_DK_JUNGLE: - vec3f_set(D_8015F738, -790.0f, -255.0f, -447.0f); - func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); - break; - default: - break; - } + + CourseManager_SomeSounds(); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // // vec3f_set(D_8015F748, -223.0f, 94.0f, -155.0f); + // // func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); + // break; + // case COURSE_ROYAL_RACEWAY: + // vec3f_set(D_8015F748, 177.0f, 87.0f, -393.0f); + // func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); + // break; + // case COURSE_LUIGI_RACEWAY: + // vec3f_set(D_8015F748, 85.0f, 21.0f, -219.0f); + // func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); + // break; + // case COURSE_WARIO_STADIUM: + // vec3f_set(D_8015F748, 298.0f, 202.0f, -850.0f); + // func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); + // vec3f_set(D_8015F758, -1600.0f, 202.0f, -2430.0f); + // func_800C9D80(D_8015F758, D_802B91C8, 0x5103700B); + // vec3f_set(D_8015F768, -2708.0f, 202.0f, 1762.0f); + // func_800C9D80(D_8015F768, D_802B91C8, 0x5103700B); + // vec3f_set(D_8015F778, -775.0f, 202.0f, 1930.0f); + // func_800C9D80(D_8015F778, D_802B91C8, 0x5103700B); + // break; + // case COURSE_KOOPA_BEACH: + // vec3f_set(D_8015F738, 153.0f, 0.0f, 2319.0f); + // func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); + // break; + // case COURSE_DK_JUNGLE: + // vec3f_set(D_8015F738, -790.0f, -255.0f, -447.0f); + // func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); + // break; + // default: + // break; + // } } /** @@ -305,86 +312,87 @@ void func_80003040(void) { gPlayerCountSelection1 = 1; set_segment_base_addr(0x3, (void*) (gNextFreeMemoryAddress + 0xFFFF7000)); destroy_all_actors(); - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: { - struct ActorSpawnData* a_d_course_mario_raceway_tree_spawns = - (struct ActorSpawnData*) LOAD_ASSET(d_course_mario_raceway_tree_spawns); - dma_textures(gTextureTrees1, 0x35B, 0x800); - spawn_foliage(a_d_course_mario_raceway_tree_spawns); - break; - } - case COURSE_BOWSER_CASTLE: - // d_course_bowsers_castle_packed_dl_1350 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001350), 0x32, 0, 0, 0); - break; - case COURSE_BANSHEE_BOARDWALK: - // d_course_banshee_boardwalk_packed_dl_878 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000878), -0x80, 0, 0, 0); - break; - case COURSE_YOSHI_VALLEY: - vec3f_set(position, -2300.0f, 0.0f, 634.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); - break; - case COURSE_MOO_MOO_FARM: - dma_textures(gTextureTrees4Left, 0x3E8, 0x800); - dma_textures(gTextureTrees4Right, 0x3E8, 0x800); - dma_textures(gTextureCow01Left, 0x400, 0x800); - dma_textures(gTextureCow01Right, 0x400, 0x800); - dma_textures(gTextureCow02Left, 0x400, 0x800); - dma_textures(gTextureCow02Right, 0x400, 0x800); - dma_textures(gTextureCow03Left, 0x400, 0x800); - dma_textures(gTextureCow03Right, 0x400, 0x800); - dma_textures(gTextureCow04Left, 0x400, 0x800); - dma_textures(gTextureCow04Right, 0x400, 0x800); - dma_textures(gTextureCow05Left, 0x400, 0x800); - dma_textures(gTextureCow05Right, 0x400, 0x800); - spawn_foliage(d_course_moo_moo_farm_tree_spawn); - break; - case COURSE_SHERBET_LAND: - // d_course_sherbet_land_packed_dl_1EB8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001EB8), -0x4C, 0xFF, 0xFF, 0xFF); - // d_course_sherbet_land_packed_dl_2308 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002308), -0x6A, 0xFF, 0xFF, 0xFF); - break; - case COURSE_RAINBOW_ROAD: - // d_course_rainbow_road_packed_dl_2068 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002068), -0x6A, 0xFF, 0xFF, 0xFF); - // d_course_rainbow_road_packed_dl_1E18 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001E18), -0x6A, 0xFF, 0xFF, 0xFF); - // d_course_rainbow_road_packed_dl_1318 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001318), -1, 0xFF, 0xFF, 0); - break; - case COURSE_WARIO_STADIUM: - vec3f_set(position, -131.0f, 83.0f, 286.0f); - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - vec3f_set(position, -2353.0f, 72.0f, -1608.0f); - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - vec3f_set(position, -2622.0f, 79.0f, 739.0f); - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - // d_course_wario_stadium_packed_dl_C50 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000C50), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_BD8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000BD8), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_B60 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000B60), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_AE8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000AE8), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_CC8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000CC8), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_D50 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000D50), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_DD0 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000DD0), 0x64, 0xFF, 0xFF, 0xFF); - // d_course_wario_stadium_packed_dl_E48 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000E48), 0x64, 0xFF, 0xFF, 0xFF); - break; - case COURSE_DK_JUNGLE: - // d_course_dks_jungle_parkway_packed_dl_3FA8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07003FA8), 0x78, 0xFF, 0xFF, 0xFF); - break; - default: - break; - } + + CourseManager_SetCourseVtxColours(); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: { + // dma_textures(gTextureTrees1, 0x35B, 0x800); + // spawn_foliage(d_course_mario_raceway_tree_spawns); + // break; + // } + // case COURSE_BOWSER_CASTLE: + // // d_course_bowsers_castle_packed_dl_1350 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001350), 0x32, 0, 0, 0); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // // d_course_banshee_boardwalk_packed_dl_878 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000878), -0x80, 0, 0, 0); + // break; + // case COURSE_YOSHI_VALLEY: + // vec3f_set(position, -2300.0f, 0.0f, 634.0f); + // position[0] *= gCourseDirection; + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); + // break; + // case COURSE_MOO_MOO_FARM: + // dma_textures(gTextureTrees4Left, 0x3E8, 0x800); + // dma_textures(gTextureTrees4Right, 0x3E8, 0x800); + // dma_textures(gTextureCow01Left, 0x400, 0x800); + // dma_textures(gTextureCow01Right, 0x400, 0x800); + // dma_textures(gTextureCow02Left, 0x400, 0x800); + // dma_textures(gTextureCow02Right, 0x400, 0x800); + // dma_textures(gTextureCow03Left, 0x400, 0x800); + // dma_textures(gTextureCow03Right, 0x400, 0x800); + // dma_textures(gTextureCow04Left, 0x400, 0x800); + // dma_textures(gTextureCow04Right, 0x400, 0x800); + // dma_textures(gTextureCow05Left, 0x400, 0x800); + // dma_textures(gTextureCow05Right, 0x400, 0x800); + // spawn_foliage(d_course_moo_moo_farm_tree_spawn); + // break; + // case COURSE_SHERBET_LAND: + // // d_course_sherbet_land_packed_dl_1EB8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001EB8), -0x4C, 0xFF, 0xFF, 0xFF); + // // d_course_sherbet_land_packed_dl_2308 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002308), -0x6A, 0xFF, 0xFF, 0xFF); + // break; + // case COURSE_RAINBOW_ROAD: + // // d_course_rainbow_road_packed_dl_2068 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002068), -0x6A, 0xFF, 0xFF, 0xFF); + // // d_course_rainbow_road_packed_dl_1E18 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001E18), -0x6A, 0xFF, 0xFF, 0xFF); + // // d_course_rainbow_road_packed_dl_1318 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001318), -1, 0xFF, 0xFF, 0); + // break; + // case COURSE_WARIO_STADIUM: + // vec3f_set(position, -131.0f, 83.0f, 286.0f); + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // vec3f_set(position, -2353.0f, 72.0f, -1608.0f); + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // vec3f_set(position, -2622.0f, 79.0f, 739.0f); + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // // d_course_wario_stadium_packed_dl_C50 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000C50), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_BD8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000BD8), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_B60 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000B60), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_AE8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000AE8), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_CC8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000CC8), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_D50 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000D50), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_DD0 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000DD0), 0x64, 0xFF, 0xFF, 0xFF); + // // d_course_wario_stadium_packed_dl_E48 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000E48), 0x64, 0xFF, 0xFF, 0xFF); + // break; + // case COURSE_DK_JUNGLE: + // // d_course_dks_jungle_parkway_packed_dl_3FA8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07003FA8), 0x78, 0xFF, 0xFF, 0xFF); + // break; + // default: + // break; + // } gNumPermanentActors = gNumActors; } diff --git a/src/code_80005FD0.c b/src/code_80005FD0.c index 669802699..30cc6862e 100644 --- a/src/code_80005FD0.c +++ b/src/code_80005FD0.c @@ -37,6 +37,9 @@ #include #include +#include "engine/Engine.h" +#include "engine/courses/Course.h" + s32 unk_code_80005FD0_pad[24]; Collision D_80162E70; s16 D_80162EB0; // Possibly a float. @@ -1072,7 +1075,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) { if (!(player->effects & 0x80) && !(player->effects & 0x40) && !(player->effects & 0x20000) && !(player->soundEffects & 0x400000) && !(player->soundEffects & 0x01000000) && !(player->soundEffects & 2) && !(player->soundEffects & 4)) { - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + if (GetCourse() == GetPodiumCeremony()) { func_80007FA4(playerId, player, var_f2); } else if ((bStopAICrossing[playerId] == 1) && !(player->effects & (STAR_EFFECT | BOO_EFFECT))) { decelerate_ai_player(player, 10.0f); @@ -1136,7 +1139,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) { } if (var_a1 != 1) { if (var_f2 < arg1) { - if ((gDemoMode == 1) && (gCurrentCourseId != 0x0014)) { + if ((gDemoMode == 1) && (GetCourse() != GetPodiumCeremony())) { player_speed(player); } else if (D_80163330[playerId] == 1) { func_80007D04(playerId, player); @@ -1222,7 +1225,7 @@ s32 func_800088D8(s32 playerId, s16 arg1, s16 arg2) { return true; } arg1_times_8 = arg1 * 8; - temp_a3 = &D_800DCBB4[gCurrentCourseId][arg1_times_8]; + temp_a3 = &CourseManager_GetProps()->SomePtr[arg1_times_8]; if (arg2 == 0) { if (gDemoMode == 1) { temp_a2 = D_80164450[playerId] - D_80164450[D_80164378[7]]; @@ -1444,15 +1447,15 @@ void func_8000929C(s32 playerId, Player* player) { D_801630E2 = 1; func_80008F38(playerId); } - if (gCurrentCourseId == 0x0014) { + if (GetCourse() == GetPodiumCeremony()) { func_8000B95C(playerId, sSomeNearestWaypoint, D_80163448); return; } if ((sSomeNearestWaypoint < 0x14) || ((gWaypointCountByPathIndex[D_80163448] - 0x14) < sSomeNearestWaypoint) || - (gCurrentCourseId == 0x000B)) { + (GetCourse() == GetKalimariDesert())) { var_v1 = 0; var_t0 = 0; - if (gCurrentCourseId == 0x000B) { + if (GetCourse() == GetKalimariDesert()) { D_801634EC = 0; if (player->effects & 0x200) { D_801634EC = 1; @@ -1506,7 +1509,7 @@ void func_8000929C(s32 playerId, Player* player) { } } D_80163450[playerId] = tempPos2; - if ((gCurrentCourseId == COURSE_YOSHI_VALLEY) && (D_801630E2 == 1)) { + if ((GetCourse() == GetYoshiValley()) && (D_801630E2 == 1)) { func_80009000(playerId); if (((player->type & 0x4000) == 0) || (player->type & 0x1000)) { func_800090F0(playerId, player); @@ -1535,7 +1538,7 @@ void update_vehicles(void) { generate_player_smoke(); D_8016337C++; - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + if (GetCourse() == GetPodiumCeremony()) { for (i = 0; i < 7; i++) { func_8000DF8C(i); } @@ -1549,20 +1552,7 @@ void update_vehicles(void) { } } - switch (gCurrentCourseId) { - case COURSE_KALAMARI_DESERT: - update_vehicle_trains(); - break; - case COURSE_DK_JUNGLE: - update_vehicle_paddle_boats(); - break; - case COURSE_TOADS_TURNPIKE: - update_vehicle_box_trucks(); - update_vehicle_school_bus(); - update_vehicle_tanker_trucks(); - update_vehicle_cars(); - break; - } + CourseManager_UpdateVehicles(); } } @@ -1656,7 +1646,7 @@ void func_80009B60(s32 playerId) { f32 athing = 1.5f; player = &gPlayers[playerId]; - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] >= 0) { + if (CourseManager_GetProps()->AIMaximumSeparation >= 0.0f) { D_80163100[playerId] += 1; if (playerId == 0) { D_80163378++; @@ -1687,33 +1677,29 @@ void func_80009B60(s32 playerId) { if (!(player->unk_0CA & 2) && !(player->unk_0CA & 8)) { D_80163448 = gPathIndexByPlayerId[playerId]; func_80008DC0(D_80163448); - switch (gCurrentCourseId) { /* irregular */ - case COURSE_KALAMARI_DESERT: - func_80012DC0(playerId, player); - if (playerId == 0) { - func_80013054(); - } - break; - case COURSE_DK_JUNGLE: - func_80013854(player); - break; - case COURSE_TOADS_TURNPIKE: - func_800148C4(playerId, player); - func_80014A18(playerId, player); - func_80014B6C(playerId, player); - func_80014CC0(playerId, player); - break; + if (GetCourse() == GetKalimariDesert()) { + func_80012DC0(playerId, player); + if (playerId == 0) { + func_80013054(); + } + } else if (GetCourse() == GetDkJungle()) { + func_80013854(player); + } else if (GetCourse() == GetToadsTurnpike()) { + func_800148C4(playerId, player); + func_80014A18(playerId, player); + func_80014B6C(playerId, player); + func_80014CC0(playerId, player); } if (player->type & 0x800) { player->effects &= ~0x00400000; player->unk_044 &= ~0x0001; } func_8000929C(playerId, player); - if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && ((D_80163240[playerId] == 1) || (playerId == 0))) { + if ((GetCourse() != GetPodiumCeremony()) && ((D_80163240[playerId] == 1) || (playerId == 0))) { set_places(); } if (player->type & 0x1000) { - if ((D_801630E2 == 1) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { + if ((D_801630E2 == 1) && (GetCourse() != GetPodiumCeremony())) { kart_ai_behaviour(playerId); } if ((playerId & 1) != (D_80163378 & 1)) { @@ -1730,11 +1716,11 @@ void func_80009B60(s32 playerId) { break; } D_801631E0[playerId] = 0; - if ((player->effects & 0x1000) && (gCurrentCourseId != 0x0014)) { + if ((player->effects & 0x1000) && (GetCourse() != GetPodiumCeremony())) { D_801631E0[playerId] = 1; } - if ((D_801646CC == 1) || (player->type & 0x800) || (gCurrentCourseId == 0x0014)) { - if (gCurrentCourseId != 0x000A) { + if ((D_801646CC == 1) || (player->type & 0x800) || (GetCourse() == GetPodiumCeremony())) { + if (GetCourse() != GetToadsTurnpike()) { D_801634F8[playerId].unk4 = 0.0f; } D_801634F8[playerId].unkC = 0.0f; @@ -1752,20 +1738,16 @@ void func_80009B60(s32 playerId) { player->pos[1] = D_80164510[playerId]; } D_801631F8[playerId] = D_801631E0[playerId]; - switch (gCurrentCourseId) { - case 4: - case 0x0014: - D_801634F8[playerId].unk4 = 0.0f; - break; - default: - break; - case 10: - func_8001490C(playerId); - func_80014A60(playerId); - func_80014BB4(playerId); - func_80014D08(playerId); - break; + + if ((GetCourse() == GetYoshiValley()) || (GetCourse() == GetPodiumCeremony())) { + D_801634F8[playerId].unk4 = 0.0f; + } else if (GetCourse() == GetToadsTurnpike()) { + func_8001490C(playerId); + func_80014A60(playerId); + func_80014BB4(playerId); + func_80014D08(playerId); } + if (D_801631E0[playerId] == 1) { D_801630E8[playerId] = 0; player->effects &= ~0x10; @@ -1778,12 +1760,12 @@ void func_80009B60(s32 playerId) { (D_8016334C[playerId] < gGPCurrentRaceRankByPlayerId[playerId])) { D_80163210[playerId] = 8.333333f; } else if (D_80162FD0 == (s16) 1U) { - D_80163210[playerId] = D_0D0096B8[gCurrentCourseId][gCCSelection]; + D_80163210[playerId] = CourseManager_GetProps()->D_0D0096B8[gCCSelection]; D_801634F8[playerId].unk4 = -0.5f; } else if (D_801645E0[sSomeNearestWaypoint] > 0) { - D_80163210[playerId] = D_0D009418[gCurrentCourseId][gCCSelection]; + D_80163210[playerId] = CourseManager_GetProps()->D_0D009418[gCCSelection]; } else { - D_80163210[playerId] = D_0D009568[gCurrentCourseId][gCCSelection]; + D_80163210[playerId] = CourseManager_GetProps()->D_0D009568[gCCSelection]; } check_ai_crossing_distance(playerId); func_8000D3B8(playerId); @@ -1865,10 +1847,10 @@ void func_80009B60(s32 playerId) { } D_801630B8[playerId] = func_8000B7E4(playerId, sSomeNearestWaypoint); func_8000D438(playerId, sSomeNearestWaypoint); - if (gCurrentCourseId != 0x0014) { + if (GetCourse() != GetPodiumCeremony()) { if (D_80164450[playerId] < 0xB) { stackPadding1A = D_801630E0; - if ((D_80164450[playerId] > 0) && (gCurrentCourseId == 0x000A)) { + if ((D_80164450[playerId] > 0) && (GetCourse() == GetToadsTurnpike())) { stackPadding1A += 0x14; stackPadding1A %= D_80164430; func_8000BBD8(stackPadding1A, 0.0f, 0); @@ -1902,7 +1884,7 @@ void func_80009B60(s32 playerId) { } } } - if (gCurrentCourseId == 0x0014) { + if (GetCourse() == GetPodiumCeremony()) { switch (D_80163410[playerId]) { /* switch 3; irregular */ case 3: /* switch 3 */ D_80162FA0[0] = D_80163418[playerId]; @@ -1935,7 +1917,10 @@ void func_80009B60(s32 playerId) { if (var_a2 < (s16) temp_f6) { var_a2 = temp_f6; } - var_v1 = gKartAISteeringSensitivity[gCurrentCourseId]; + + var_v1 = CourseManager_GetProps()->AISteeringSensitivity; + //var_v1 = gKartAISteeringSensitivity[gCurrentCourseId]; + switch (D_801631D8[playerId]) { /* switch 4; irregular */ case 2: /* switch 4 */ if (D_80163068[playerId] > (0.5f * 1.0f)) { @@ -1980,15 +1965,15 @@ void func_80009B60(s32 playerId) { D_80163050[playerId] = var_a1; if ((D_801630B8[playerId] == 1) || (D_801630E8[playerId] == 1) || (D_801630E8[playerId] == -1) || (player->effects & 0x1000000C)) { - D_80163028[playerId] = D_0D009418[gCurrentCourseId][gCCSelection]; + D_80163028[playerId] = CourseManager_GetProps()->D_0D009418[gCCSelection]; } else { - D_80163028[playerId] = D_0D009568[gCurrentCourseId][gCCSelection]; + D_80163028[playerId] = CourseManager_GetProps()->D_0D009568[gCCSelection]; } if ((D_80163068[playerId] > 0.9f) || (D_80163068[playerId] < -0.9f)) { - D_80163028[playerId] = D_0D009808[gCurrentCourseId][gCCSelection]; + D_80163028[playerId] = CourseManager_GetProps()->D_0D009808[gCCSelection]; } if (D_80162FD0 == 1) { - D_80163028[playerId] = D_0D0096B8[gCurrentCourseId][gCCSelection]; + D_80163028[playerId] = CourseManager_GetProps()->D_0D0096B8[gCCSelection]; } if ((D_801630E8[playerId] == 2) || (D_801630E8[playerId] == -2) || (D_801630E8[playerId] == 3)) { D_80163028[playerId] = 3.3333333f; @@ -2172,7 +2157,7 @@ f32 func_8000B874(f32 posX, f32 posZ, u16 waypointIndex, s32 pathIndex) { void func_8000B95C(s32 playerId, u16 waypointIndex, s32 pathIndex) { UNUSED Vec3f pad; D_80163068[playerId] = 0.0f; - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] >= 0) { + if (CourseManager_GetProps()->AIMaximumSeparation >= 0.0f) { if ((gPlayers[playerId].type & 0x8000) != 0) { D_80163068[playerId] = func_8000B874(gPlayers[playerId].pos[0], gPlayers[playerId].pos[2], waypointIndex, pathIndex); @@ -2319,7 +2304,7 @@ s16 find_closest_waypoint_track_section(f32 posX, f32 posY, f32 posZ, u16 trackS considerWaypoint = &pathWaypoints[0]; for (considerWaypointIndex = 0; considerWaypointIndex < pathWaypointCount; considerWaypointIndex++, considerWaypoint++) { - if ((considerWaypoint->trackSectionId == trackSectionId) || (gCurrentCourseId == COURSE_AWARD_CEREMONY)) { + if ((considerWaypoint->trackSectionId == trackSectionId) || (GetCourse() == GetPodiumCeremony())) { var_t1 = 1; x_dist = (f32) considerWaypoint->posX - posX; y_dist = (f32) considerWaypoint->posY - posY; @@ -2485,7 +2470,7 @@ void func_8000CBA4(UNUSED f32 posX, f32 posY, UNUSED f32 posZ, s16* waypointInde s16 var_v0; var_v0 = *waypointIndex; - if ((gCurrentCourseId == COURSE_WARIO_STADIUM) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) { + if ((GetCourse() == GetWarioStadium()) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) { var_v0 = 0x0398; } *waypointIndex = var_v0; @@ -2688,22 +2673,17 @@ void func_8000D438(s32 arg0, u16 arg1) { sp2C = func_8000D3B8(arg0); thing = arg1; - switch (gCurrentCourseId) { - case COURSE_AWARD_CEREMONY: - var_a2 = 1; - break; - case COURSE_TOADS_TURNPIKE: - var_a2 = 7; - break; - case COURSE_YOSHI_VALLEY: - break; - default: - if (temp_v1 < 6) { - var_a2 = 8; - } else if (temp_v1 >= 0x15) { - var_a2 = 20; - } - break; + if (GetCourse() == GetPodiumCeremony()) { + var_a2 = 1; + } else if (GetCourse() == GetToadsTurnpike()) { + var_a2 = 7; + } else if (GetCourse() == GetYoshiValley()) { + } else { + if (temp_v1 < 6) { + var_a2 = 8; + } else if (temp_v1 >= 0x15) { + var_a2 = 20; + } } if (var_a2 >= 8) { @@ -3044,7 +3024,7 @@ void func_8000DF8C(s32 bombKartId) { return; } - if (((bombKart->unk_4A != 1) || (gCurrentCourseId == COURSE_AWARD_CEREMONY))) { + if (((bombKart->unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) { var_f22 = bombKart->bombPos[0]; var_f20 = bombKart->bombPos[1]; var_f24 = bombKart->bombPos[2]; @@ -3055,7 +3035,7 @@ void func_8000DF8C(s32 bombKartId) { var_s1 = bombKart->circleTimer; if ((sp7E != 0) && (sp7E != 4)) { if (1) {} - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + if (GetCourse() == GetPodiumCeremony()) { if (D_8016347E == 1) { var_v0 = gPlayerFour; temp_f0 = var_f22 - var_v0->pos[0]; @@ -3079,7 +3059,7 @@ void func_8000DF8C(s32 bombKartId) { if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) { sp7E = 4; var_s1 = 0; - if (gCurrentCourseId == COURSE_FRAPPE_SNOWLAND) { + if (GetCourse() == GetFrappeSnowland()) { var_v0->soundEffects |= 0x01000000; } else { var_v0->soundEffects |= 0x400000; @@ -3423,7 +3403,7 @@ void func_8000F2BC(TrackWaypoint* arg0, size_t size) { // Appears to allocate memory for each course. void func_8000F2DC(void) { - struct _struct_gCoursePathSizes_0x10* ptr = &gCoursePathSizes[gCurrentCourseId]; + _struct_gCoursePathSizes_0x10* ptr = &CourseManager_GetProps()->PathSizes; s32 temp; s32 i; @@ -3474,22 +3454,20 @@ void func_8000F2DC(void) { } D_80164430 = *gWaypointCountByPathIndex; - switch (gCurrentCourseId) { - case COURSE_KALAMARI_DESERT: - generate_train_waypoints(); - init_vehicles_trains(); - break; - case COURSE_DK_JUNGLE: - generate_ferry_waypoints(); - init_vehicles_ferry(); - break; - case COURSE_TOADS_TURNPIKE: - init_vehicles_box_trucks(); - init_vehicles_school_buses(); - init_vehicles_trucks(); - init_vehicles_cars(); - break; + if (GetCourse() == GetKalimariDesert()) { + generate_train_waypoints(); + init_vehicles_trains(); + } else if (GetCourse() == GetDkJungle()) { + generate_ferry_waypoints(); + init_vehicles_ferry(); + } else if (GetCourse() == GetToadsTurnpike()) { + init_vehicles_box_trucks(); + init_vehicles_school_buses(); + init_vehicles_trucks(); + init_vehicles_cars(); } + + CourseManager_SpawnBombKarts(); set_bomb_kart_spawn_positions(); func_8000EEDC(); } @@ -3509,11 +3487,11 @@ void func_8000F628(void) { D_80163050[i] = 0; D_80162FF8[i] = 0; D_80163010[i] = 0; - if (gCurrentCourseId < (NUM_COURSES - 1)) { + if (GetCourse() != GetPodiumCeremony()) { func_8000B95C(i, 0, 0); } //! todo: @BUG this doesn't seem right. This variable is metadata. - D_80163028[i] = D_0D009418[gCurrentCourseId][gCCSelection]; + D_80163028[i] = CourseManager_GetProps()->D_0D009418[gCCSelection]; D_801630E8[i] = 0; D_80163100[i] = 0; D_80163178[i] = 0.0f; @@ -3545,7 +3523,7 @@ void func_8000F628(void) { D_80163068[i] = 0.0f; D_80163090[i] = 0.0f; var_s5 = &D_801634F8[i]; - var_s5->unkC = gKartAICourseMinimumSeparation[gCurrentCourseId] * (f32) (((i + 1) % 3) - 1); + var_s5->unkC = CourseManager_GetProps()->AIMinimumSeparation * (f32) (((i + 1) % 3) - 1); var_s5->unk4 = var_s5->unkC; var_s5->unk0 = 0.0f; var_s5->unk8 = 0.015f; @@ -3594,7 +3572,7 @@ void func_8000F628(void) { } } } - if ((D_8018EE08 == 1) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { + if ((D_8018EE08 == 1) && (GetCourse() != GetPodiumCeremony())) { for (i = 0; i < NUM_PLAYERS; i++) { D_80163330[i] = 0; } @@ -3659,6 +3637,8 @@ void func_8000F628(void) { copy_courses_kart_ai_behaviour(); } +extern TrackWaypoint test_course_path[17]; + // @arg index from 0 to 3. // Processes course path by index. @@ -3675,17 +3655,30 @@ void func_800100F0(s32 pathIndex) { s16 bInvalidPath; s32 i; - // cast required - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] >= 0) { + if (CourseManager_GetProps()->AIMaximumSeparation >= 1.0f) { pathDest = D_80164550[pathIndex]; bInvalidPath = 1; - if (gCurrentCourseId != COURSE_AWARD_CEREMONY) { - var_v0 = process_path_data(pathDest, LOAD_ASSET(gCoursePathTable2[gCurrentCourseId][pathIndex])); + if (GetCourse() != GetPodiumCeremony()) { + + if (GetCourse() == GetTestCourse()) { + var_v0 = process_path_data(pathDest, test_course_path); gWaypointCountByPathIndex[pathIndex] = (u16) var_v0; - } else { + } else { + + var_v0 = process_path_data(pathDest, LOAD_ASSET(CourseManager_GetProps()->PathTable2[pathIndex])); + gWaypointCountByPathIndex[pathIndex] = (u16) var_v0; + } + } + + else { // Course path included in course_data which has already been loaded into memory. // This is how we get the addr to our path data. - path = LOAD_ASSET(gCoursePathTable[gCurrentCourseId][pathIndex]); + + if (GetCourse() == GetTestCourse()) { + path = test_course_path; + } else { + path = LOAD_ASSET(CourseManager_GetProps()->PathTable[pathIndex]); + } ptr = path; for (i = 0; i < 3000; i++, ptr++) { @@ -3727,8 +3720,8 @@ void func_80010218(s32 pathIndex) { TrackWaypoint* var_s1; TrackWaypoint* var_s2; - if (((s32) gKartAICourseMaximumSeparation[gCurrentCourseId]) >= 0) { - waypointWidth = gKartAICourseMaximumSeparation[gCurrentCourseId]; + if (CourseManager_GetProps()->AIMaximumSeparation >= 0.0f) { + waypointWidth = CourseManager_GetProps()->AIMaximumSeparation; waypoint = &D_80164550[pathIndex][0]; var_s1 = &D_80164560[pathIndex][0]; var_s2 = &D_80164570[pathIndex][0]; @@ -3778,7 +3771,7 @@ f32 func_80010480(s32 pathIndex, u16 waypointIndex) { f32 root2; f32 root1; - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] < 0) { + if (CourseManager_GetProps()->AIMaximumSeparation <= -1.0f) { return 0.0f; } waypointCount = gWaypointCountByPathIndex[pathIndex]; @@ -3820,7 +3813,7 @@ void func_800107C4(s32 pathIndex) { s32 var_a3; s16* wut; - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] >= 0) { + if (CourseManager_GetProps()->AIMaximumSeparation >= 0.0f) { var_a3 = gWaypointCountByPathIndex[pathIndex]; var_t4 = &D_80164580[pathIndex][0]; for (var_s0 = 0; var_s0 < var_a3; var_s0++, var_t4++) { @@ -3888,7 +3881,7 @@ void func_80010DBC(s32 pathIndex) { s32 waypointIndex; u16* angle; - if ((s32) gKartAICourseMaximumSeparation[gCurrentCourseId] >= 0) { + if (CourseManager_GetProps()->AIMaximumSeparation >= 0.0f) { for (angle = (u16*) &D_80164590[pathIndex][0], waypointIndex = 0; waypointIndex < gWaypointCountByPathIndex[pathIndex]; waypointIndex++, angle++) { *angle = func_80010CB0(pathIndex, waypointIndex); @@ -3917,7 +3910,7 @@ void func_80010E6C(s32 pathIndex) { } else { break; } - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + if (GetCourse() == GetPodiumCeremony()) { break; } } @@ -4020,35 +4013,30 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint var_f20_2 = var_f28; } else { - switch (gCurrentCourseId) { - case 13: - if (var_f20_2 < (var_f28 - 15.0)) { - var_f20_2 = (f32) var_f28 - 15.0; - } - break; - case 14: - if ((var_s0 >= 1140) && (var_s0 <= 1152)) { - var_f20_2 = var_f28; - } else { - if (var_f20_2 < (var_f28 - 10.0)) { - var_f20_2 = (f32) (var_f28 - 4.0); - } - } - break; - case 18: - if ((var_s0 > 204) && (var_s0 < 220)) { - var_f20_2 = var_f28; - } else { - if (var_f20_2 < (var_f28 - 10.0)) { - var_f20_2 = (f32) (var_f28 - 4.0); - } - } - break; - default: + if (GetCourse() == GetRainbowRoad()) { + if (var_f20_2 < (var_f28 - 15.0)) { + var_f20_2 = (f32) var_f28 - 15.0; + } + } else if (GetCourse() == GetWarioStadium()) { + if ((var_s0 >= 1140) && (var_s0 <= 1152)) { + var_f20_2 = var_f28; + } else { if (var_f20_2 < (var_f28 - 10.0)) { - var_f20_2 = (f32) var_f28 - 10.0; + var_f20_2 = (f32) (var_f28 - 4.0); } - break; + } + } else if (GetCourse() == GetDkJungle()) { + if ((var_s0 > 204) && (var_s0 < 220)) { + var_f20_2 = var_f28; + } else { + if (var_f20_2 < (var_f28 - 10.0)) { + var_f20_2 = (f32) (var_f28 - 4.0); + } + } + } else { + if (var_f20_2 < (var_f28 - 10.0)) { + var_f20_2 = (f32) var_f28 - 10.0; + } } } var_f28 = var_f20_2; @@ -4172,7 +4160,7 @@ s32 generate_2d_path(Path2D* pathDest, TrackWaypoint* pathSrc, s32 numWaypoints) void copy_courses_kart_ai_behaviour(void) { s32 i; for (i = 0; i < NUM_COURSES - 1; i++) { - gCoursesKartAIBehaviour[i] = LOAD_ASSET(gKartAIBehaviourLUT[i]); + gCoursesKartAIBehaviour[i] = LOAD_ASSET(CourseManager_GetProps()->AIBehaviour); } } @@ -4195,7 +4183,11 @@ void kart_ai_behaviour_start(s32 playerId, Player* player) { s32 behaviourType; UNUSED s32 test; - sCurrentKartAIBehaviour = &gCoursesKartAIBehaviour[gCurrentCourseId][gCurrentKartAIBehaviourId[playerId]]; + KartAIBehaviour *beh = (KartAIBehaviour*)LOAD_ASSET(CourseManager_GetProps()->AIBehaviour); + + sCurrentKartAIBehaviour = &((KartAIBehaviour*)LOAD_ASSET(CourseManager_GetProps()->AIBehaviour))[gCurrentKartAIBehaviourId[playerId]]; + + playerWaypoint = gNearestWaypointByPlayerId[playerId]; @@ -4204,7 +4196,7 @@ void kart_ai_behaviour_start(s32 playerId, Player* player) { behaviourType = sCurrentKartAIBehaviour->type; if ((waypointStart == -1) && (waypointEnd == -1)) { - sCurrentKartAIBehaviour = &gCoursesKartAIBehaviour[gCurrentCourseId][0]; + sCurrentKartAIBehaviour = &((KartAIBehaviour*)LOAD_ASSET(CourseManager_GetProps()->AIBehaviour))[0]; reset_kart_ai_behaviour_none(playerId); return; } @@ -4259,7 +4251,7 @@ void kart_ai_behaviour_end(s32 playerIndex, Player* player) { u32 waypointEnd; s32 behaviourType; - sCurrentKartAIBehaviour = &gCoursesKartAIBehaviour[gCurrentCourseId][gPreviousKartAIBehaviourId[playerIndex]]; + sCurrentKartAIBehaviour = &((KartAIBehaviour*)LOAD_ASSET(CourseManager_GetProps()->AIBehaviour))[gPreviousKartAIBehaviourId[playerIndex]]; nearestWaypoint = gNearestWaypointByPlayerId[playerIndex]; behaviourType = sCurrentKartAIBehaviour->type; waypointEnd = sCurrentKartAIBehaviour->waypointEnd; @@ -4411,97 +4403,57 @@ void spawn_course_vehicles(void) { f32 origXPos; f32 origZPos; - switch (gCurrentCourseId) { - case COURSE_KALAMARI_DESERT: - for (loopIndex = 0; loopIndex < NUM_TRAINS; loopIndex++) { - tempLocomotive = &gTrainList[loopIndex].locomotive; - origXPos = tempLocomotive->position[0]; - origZPos = tempLocomotive->position[2]; - trainCarYRot = update_vehicle_following_waypoint( - tempLocomotive->position, (s16*) &tempLocomotive->waypointIndex, gTrainList[loopIndex].speed); - tempLocomotive->velocity[0] = tempLocomotive->position[0] - origXPos; - tempLocomotive->velocity[2] = tempLocomotive->position[2] - origZPos; - vec3s_set(trainCarRot, 0, trainCarYRot, 0); - tempLocomotive->actorIndex = add_actor_to_empty_slot(tempLocomotive->position, trainCarRot, - tempLocomotive->velocity, ACTOR_TRAIN_ENGINE); + CourseManager_SpawnVehicles(); - tempTender = &gTrainList[loopIndex].tender; - if (tempTender->isActive == 1) { - origXPos = tempTender->position[0]; - origZPos = tempTender->position[2]; - trainCarYRot = update_vehicle_following_waypoint( - tempTender->position, (s16*) &tempTender->waypointIndex, gTrainList[loopIndex].speed); - tempTender->velocity[0] = tempTender->position[0] - origXPos; - tempTender->velocity[2] = tempTender->position[2] - origZPos; - vec3s_set(trainCarRot, 0, trainCarYRot, 0); - tempTender->actorIndex = add_actor_to_empty_slot(tempTender->position, trainCarRot, - tempTender->velocity, ACTOR_TRAIN_TENDER); - } - - for (loopIndex2 = 0; loopIndex2 < NUM_PASSENGER_CAR_ENTRIES; loopIndex2++) { - tempPassengerCar = &gTrainList[loopIndex].passengerCars[loopIndex2]; - if (tempPassengerCar->isActive == 1) { - origXPos = tempPassengerCar->position[0]; - origZPos = tempPassengerCar->position[2]; - trainCarYRot = update_vehicle_following_waypoint(tempPassengerCar->position, - (s16*) &tempPassengerCar->waypointIndex, - gTrainList[loopIndex].speed); - tempPassengerCar->velocity[0] = tempPassengerCar->position[0] - origXPos; - tempPassengerCar->velocity[2] = tempPassengerCar->position[2] - origZPos; - vec3s_set(trainCarRot, 0, trainCarYRot, 0); - tempPassengerCar->actorIndex = - add_actor_to_empty_slot(tempPassengerCar->position, trainCarRot, tempPassengerCar->velocity, - ACTOR_TRAIN_PASSENGER_CAR); - } - } - } - break; - case COURSE_DK_JUNGLE: - for (loopIndex = 0; loopIndex < NUM_ACTIVE_PADDLE_BOATS; loopIndex++) { - tempPaddleWheelBoat = &gPaddleBoats[loopIndex]; - if (tempPaddleWheelBoat->isActive == 1) { - origXPos = tempPaddleWheelBoat->position[0]; - origZPos = tempPaddleWheelBoat->position[2]; - tempPaddleWheelBoat->rotY = update_vehicle_following_waypoint( - tempPaddleWheelBoat->position, (s16*) &tempPaddleWheelBoat->waypointIndex, - tempPaddleWheelBoat->speed); - tempPaddleWheelBoat->velocity[0] = tempPaddleWheelBoat->position[0] - origXPos; - tempPaddleWheelBoat->velocity[2] = tempPaddleWheelBoat->position[2] - origZPos; - vec3s_set(paddleWheelBoatRot, 0, tempPaddleWheelBoat->rotY, 0); - tempPaddleWheelBoat->actorIndex = - add_actor_to_empty_slot(tempPaddleWheelBoat->position, paddleWheelBoatRot, - tempPaddleWheelBoat->velocity, ACTOR_PADDLE_BOAT); - } - } - break; - case COURSE_TOADS_TURNPIKE: - for (loopIndex = 0; loopIndex < NUM_RACE_BOX_TRUCKS; loopIndex++) { - tempBoxTruck = &gBoxTruckList[loopIndex]; - spawn_vehicle_on_road(tempBoxTruck); - tempBoxTruck->actorIndex = add_actor_to_empty_slot(tempBoxTruck->position, tempBoxTruck->rotation, - tempBoxTruck->velocity, ACTOR_BOX_TRUCK); - } - for (loopIndex = 0; loopIndex < NUM_RACE_SCHOOL_BUSES; loopIndex++) { - tempSchoolBus = &gSchoolBusList[loopIndex]; - spawn_vehicle_on_road(tempSchoolBus); - tempSchoolBus->actorIndex = add_actor_to_empty_slot(tempSchoolBus->position, tempSchoolBus->rotation, - tempSchoolBus->velocity, ACTOR_SCHOOL_BUS); - } - for (loopIndex = 0; loopIndex < NUM_RACE_TANKER_TRUCKS; loopIndex++) { - tempTankerTruck = &gTankerTruckList[loopIndex]; - spawn_vehicle_on_road(tempTankerTruck); - tempTankerTruck->actorIndex = - add_actor_to_empty_slot(tempTankerTruck->position, tempTankerTruck->rotation, - tempTankerTruck->velocity, ACTOR_TANKER_TRUCK); - } - for (loopIndex = 0; loopIndex < NUM_RACE_CARS; loopIndex++) { - tempCar = &gCarList[loopIndex]; - spawn_vehicle_on_road(tempCar); - tempCar->actorIndex = - add_actor_to_empty_slot(tempCar->position, tempCar->rotation, tempCar->velocity, ACTOR_CAR); - } - break; - } + // switch (gCurrentCourseId) { + // case COURSE_KALAMARI_DESERT: + // break; + // case COURSE_DK_JUNGLE: + // for (loopIndex = 0; loopIndex < NUM_ACTIVE_PADDLE_BOATS; loopIndex++) { + // tempPaddleWheelBoat = &gPaddleBoats[loopIndex]; + // if (tempPaddleWheelBoat->isActive == 1) { + // origXPos = tempPaddleWheelBoat->position[0]; + // origZPos = tempPaddleWheelBoat->position[2]; + // tempPaddleWheelBoat->rotY = update_vehicle_following_waypoint( + // tempPaddleWheelBoat->position, (s16*) &tempPaddleWheelBoat->waypointIndex, + // tempPaddleWheelBoat->speed); + // tempPaddleWheelBoat->velocity[0] = tempPaddleWheelBoat->position[0] - origXPos; + // tempPaddleWheelBoat->velocity[2] = tempPaddleWheelBoat->position[2] - origZPos; + // vec3s_set(paddleWheelBoatRot, 0, tempPaddleWheelBoat->rotY, 0); + // tempPaddleWheelBoat->actorIndex = + // add_actor_to_empty_slot(tempPaddleWheelBoat->position, paddleWheelBoatRot, + // tempPaddleWheelBoat->velocity, ACTOR_PADDLE_BOAT); + // } + // } + // break; + // case COURSE_TOADS_TURNPIKE: + // for (loopIndex = 0; loopIndex < NUM_RACE_BOX_TRUCKS; loopIndex++) { + // tempBoxTruck = &gBoxTruckList[loopIndex]; + // spawn_vehicle_on_road(tempBoxTruck); + // tempBoxTruck->actorIndex = add_actor_to_empty_slot(tempBoxTruck->position, tempBoxTruck->rotation, + // tempBoxTruck->velocity, ACTOR_BOX_TRUCK); + // } + // for (loopIndex = 0; loopIndex < NUM_RACE_SCHOOL_BUSES; loopIndex++) { + // tempSchoolBus = &gSchoolBusList[loopIndex]; + // spawn_vehicle_on_road(tempSchoolBus); + // tempSchoolBus->actorIndex = add_actor_to_empty_slot(tempSchoolBus->position, tempSchoolBus->rotation, + // tempSchoolBus->velocity, ACTOR_SCHOOL_BUS); + // } + // for (loopIndex = 0; loopIndex < NUM_RACE_TANKER_TRUCKS; loopIndex++) { + // tempTankerTruck = &gTankerTruckList[loopIndex]; + // spawn_vehicle_on_road(tempTankerTruck); + // tempTankerTruck->actorIndex = + // add_actor_to_empty_slot(tempTankerTruck->position, tempTankerTruck->rotation, + // tempTankerTruck->velocity, ACTOR_TANKER_TRUCK); + // } + // for (loopIndex = 0; loopIndex < NUM_RACE_CARS; loopIndex++) { + // tempCar = &gCarList[loopIndex]; + // spawn_vehicle_on_road(tempCar); + // tempCar->actorIndex = + // add_actor_to_empty_slot(tempCar->position, tempCar->rotation, tempCar->velocity, ACTOR_CAR); + // } + // break; + // } } void set_vehicle_pos_waypoint(TrainCarStuff* trainCar, Path2D* posXZ, u16 waypoint) { @@ -4775,7 +4727,7 @@ void func_80013054(void) { void check_ai_crossing_distance(s32 playerId) { bStopAICrossing[playerId] = 0; - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { if ((!(D_801631E0[playerId] != 0)) || (set_vehicle_render_distance_flags(gPlayers[playerId].pos, TRAIN_CROSSING_AI_DISTANCE, 0))) { @@ -5428,7 +5380,7 @@ void func_80014DE4(s32 cameraIndex) { D_801646CC = 0; D_80164678[cameraIndex] = D_80164670[cameraIndex]; - if ((gModeSelection != 1) && ((gCourseIndexInCup == COURSE_ONE) || (gDemoMode == (u16) 1))) { + if ((gModeSelection != 1) && ((GetCupCursorPosition() == COURSE_ONE) || (gDemoMode == (u16) 1))) { D_80164678[cameraIndex] = 0; } else if ((D_80164678[cameraIndex] != 0) && (D_80164678[cameraIndex] != (s16) 1) && (D_80164678[cameraIndex] != 2) && (D_80164678[cameraIndex] != 3)) { @@ -5966,7 +5918,7 @@ void func_80016C3C(UNUSED s32 playerId, UNUSED f32 arg1, s32 cameraId) { D_80164688[cameraId] = -0.1f; } D_80163DD8[cameraId] = 0; - if (gCurrentCourseId == 4) { + if (GetCourse() == GetYoshiValley()) { D_80163DD8[cameraId] = random_int(4U); D_80164688[cameraId] = 0.0f; } @@ -6043,7 +5995,7 @@ void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32 sp56 = gNearestWaypointByCameraId[cameraId]; gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); - if (gCurrentCourseId == 4) { + if (GetCourse() == GetYoshiValley()) { if ((sp56 != gNearestWaypointByCameraId[cameraId]) && (gNearestWaypointByCameraId[cameraId] == 1)) { pathIndex = (D_80163DD8[cameraId] = random_int(4U)); gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], @@ -6719,7 +6671,7 @@ void func_80019D2C(Camera* camera, Player* player, s32 arg2) { s32 nearestWaypoint; playerId = camera->playerId; - if ((D_80163378 != 0) && (gCurrentCourseId == 8)) { + if ((D_80163378 != 0) && (GetCourse() == GetLuigiRaceway())) { calculate_camera_up_vector(camera, arg2); nearestWaypoint = gNearestWaypointByPlayerId[playerId]; if (((nearestWaypoint >= 0x65) && (nearestWaypoint < 0xFA)) || @@ -6864,7 +6816,7 @@ void func_8001A220(UNUSED s32 arg0, s32 cameraId) { } s32 func_8001A310(s32 waypoint, s32 arg1) { - if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) { + if ((GetCourse() == GetBowsersCastle()) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) { arg1 = 0; } return arg1; @@ -7645,6 +7597,7 @@ void func_8001BE78(void) { void func_8001C05C(void) { init_segment_racing(); gCurrentCourseId = COURSE_AWARD_CEREMONY; + SetCourseByClass(GetPodiumCeremony()); D_8016347C = 0; D_8016347E = 0; D_80163480 = 0; @@ -7717,7 +7670,7 @@ void func_8001C14C(void) { } void func_8001C3C4(s32 cameraId) { - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + if (GetCourse() == GetPodiumCeremony()) { if (gBombKarts[0].waypointIndex >= 16) { func_80057114(PLAYER_FOUR); } diff --git a/src/code_80005FD0.h b/src/code_80005FD0.h index 61dff3435..5a9d7e720 100644 --- a/src/code_80005FD0.h +++ b/src/code_80005FD0.h @@ -297,7 +297,6 @@ extern u16 D_80163240[]; extern u16 D_80163258[]; extern u16 D_80163270[]; extern s32 D_80163288[]; -// Exact pointer type unknown extern KartAIBehaviour* sCurrentKartAIBehaviour; extern u16 gCurrentKartAIBehaviourId[]; extern u16 gPreviousKartAIBehaviourId[]; diff --git a/src/code_8003DC40.c b/src/code_8003DC40.c index 218bedbe9..231c40e4b 100644 --- a/src/code_8003DC40.c +++ b/src/code_8003DC40.c @@ -231,30 +231,31 @@ void func_8003F46C(Player* player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4 player->kartHopVelocity = 0.0f; return; } else { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - case COURSE_CHOCO_MOUNTAIN: - case COURSE_KOOPA_BEACH: - func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - case COURSE_BOWSER_CASTLE: - func_8003E6EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - case COURSE_LUIGI_RACEWAY: - func_8003E9EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - case COURSE_WARIO_STADIUM: - func_8003EE2C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - case COURSE_DK_JUNGLE: - func_8003F138(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - default: - func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - break; - } + CourseManager_SomeCollisionThing(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // //func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // case COURSE_CHOCO_MOUNTAIN: + // case COURSE_KOOPA_BEACH: + // func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // case COURSE_BOWSER_CASTLE: + // func_8003E6EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // case COURSE_LUIGI_RACEWAY: + // func_8003E9EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // case COURSE_WARIO_STADIUM: + // func_8003EE2C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // case COURSE_DK_JUNGLE: + // func_8003F138(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // default: + // func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + // break; + // } if (player->effects & 0x10000) { player->unk_DAC = 0.5f; } diff --git a/src/code_80057C60.c b/src/code_80057C60.c index ceb0df519..09e33baf2 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -694,90 +694,92 @@ void render_player_snow_effect_four(void) { void render_object_for_player(s32 cameraId) { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - break; - case COURSE_CHOCO_MOUNTAIN: - break; - case COURSE_BOWSER_CASTLE: - render_object_thwomps(cameraId); - render_object_bowser_flame(cameraId); - break; - case COURSE_BANSHEE_BOARDWALK: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_trash_bin(cameraId); - render_object_bat(cameraId); - func_8005217C(cameraId); - render_object_boos(cameraId); - } - break; - case COURSE_YOSHI_VALLEY: - func_80055228(cameraId); - if (gGamestate != CREDITS_SEQUENCE) { - render_object_hedgehogs(cameraId); - } - break; - case COURSE_FRAPPE_SNOWLAND: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_snowmans(cameraId); - } - break; - case COURSE_KOOPA_BEACH: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_crabs(cameraId); - } - if (gGamestate != CREDITS_SEQUENCE) { + CourseManager_RenderCourseObjects(cameraId); - if ((gPlayerCount == 1) || (gPlayerCount == 2)) { - render_object_seagulls(cameraId); - } - } else { - render_object_seagulls(cameraId); - } - break; - case COURSE_ROYAL_RACEWAY: - break; - case COURSE_LUIGI_RACEWAY: - if (D_80165898 != 0) { - render_object_hot_air_balloon(cameraId); - } - break; - case COURSE_MOO_MOO_FARM: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_moles(cameraId); - } - break; - case COURSE_TOADS_TURNPIKE: - break; - case COURSE_KALAMARI_DESERT: - render_object_trains_smoke_particles(cameraId); - break; - case COURSE_SHERBET_LAND: - if (gGamestate != CREDITS_SEQUENCE) { - func_80052E30(cameraId); - } - render_object_train_penguins(cameraId); - break; - case COURSE_RAINBOW_ROAD: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_neon(cameraId); - render_object_chain_chomps(cameraId); - } - break; - case COURSE_WARIO_STADIUM: - break; - case COURSE_BLOCK_FORT: - break; - case COURSE_SKYSCRAPER: - break; - case COURSE_DOUBLE_DECK: - break; - case COURSE_DK_JUNGLE: - if (gGamestate != CREDITS_SEQUENCE) { - render_object_paddle_boat_smoke_particles(cameraId); - } - break; - } + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // break; + // case COURSE_CHOCO_MOUNTAIN: + // break; + // case COURSE_BOWSER_CASTLE: + // render_object_thwomps(cameraId); + // render_object_bowser_flame(cameraId); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_trash_bin(cameraId); + // render_object_bat(cameraId); + // func_8005217C(cameraId); + // render_object_boos(cameraId); + // } + // break; + // case COURSE_YOSHI_VALLEY: + // func_80055228(cameraId); + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_hedgehogs(cameraId); + // } + // break; + // case COURSE_FRAPPE_SNOWLAND: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_snowmans(cameraId); + // } + // break; + // case COURSE_KOOPA_BEACH: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_crabs(cameraId); + // } + // if (gGamestate != CREDITS_SEQUENCE) { + + // if ((gPlayerCount == 1) || (gPlayerCount == 2)) { + // render_object_seagulls(cameraId); + // } + // } else { + // render_object_seagulls(cameraId); + // } + // break; + // case COURSE_ROYAL_RACEWAY: + // break; + // case COURSE_LUIGI_RACEWAY: + // if (D_80165898 != 0) { + // render_object_hot_air_balloon(cameraId); + // } + // break; + // case COURSE_MOO_MOO_FARM: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_moles(cameraId); + // } + // break; + // case COURSE_TOADS_TURNPIKE: + // break; + // case COURSE_KALAMARI_DESERT: + // render_object_trains_smoke_particles(cameraId); + // break; + // case COURSE_SHERBET_LAND: + // if (gGamestate != CREDITS_SEQUENCE) { + // func_80052E30(cameraId); + // } + // render_object_train_penguins(cameraId); + // break; + // case COURSE_RAINBOW_ROAD: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_neon(cameraId); + // render_object_chain_chomps(cameraId); + // } + // break; + // case COURSE_WARIO_STADIUM: + // break; + // case COURSE_BLOCK_FORT: + // break; + // case COURSE_SKYSCRAPER: + // break; + // case COURSE_DOUBLE_DECK: + // break; + // case COURSE_DK_JUNGLE: + // if (gGamestate != CREDITS_SEQUENCE) { + // render_object_paddle_boat_smoke_particles(cameraId); + // } + // break; + // } render_object_smoke_particles(cameraId); render_object_leaf_particle(cameraId); @@ -791,19 +793,16 @@ void render_object_for_player(s32 cameraId) { } void render_snowing_effect(s32 arg0) { - switch (gCurrentCourseId) { - case COURSE_FRAPPE_SNOWLAND: - if (gGamestate != 9) { - if ((D_8015F894 == 0) && (gPlayerCountSelection1 == 1)) { - render_object_snowflakes_particles(); - } - } else { + if (GetCourse() == GetFrappeSnowland()) { + if (gGamestate != 9) { + if ((D_8015F894 == 0) && (gPlayerCountSelection1 == 1)) { render_object_snowflakes_particles(); } - break; - case COURSE_SHERBET_LAND: - render_ice_block(arg0); - break; + } else { + render_object_snowflakes_particles(); + } + } else if (GetCourse() == GetSherbetLand()) { + render_ice_block(arg0); } } @@ -1562,85 +1561,88 @@ void func_8005A3C0(void) { } void func_8005A71C(void) { - if (gCurrentCourseId == COURSE_BOWSER_CASTLE) { + if (GetCourse() == GetBowsersCastle()) { func_80081210(); } } void update_object(void) { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - case COURSE_CHOCO_MOUNTAIN: - break; - case COURSE_BOWSER_CASTLE: - func_80081208(); - update_flame_particle(); - break; - case COURSE_BANSHEE_BOARDWALK: - if (gGamestate != CREDITS_SEQUENCE) { - update_trash_bin(); - func_8007E4C4(); - if (gModeSelection != TIME_TRIALS) { - update_bat(); - } - wrapper_update_boos(); - update_cheep_cheep(0); - } - break; - case COURSE_YOSHI_VALLEY: - func_80083080(); - if (gGamestate != CREDITS_SEQUENCE) { - update_hedgehogs(); - } - break; - case COURSE_FRAPPE_SNOWLAND: - if (gGamestate != CREDITS_SEQUENCE) { - update_snowmen(); - } - update_snowflakes(); - break; - case COURSE_KOOPA_BEACH: - if (gGamestate != CREDITS_SEQUENCE) { - update_crabs(); - } - if ((gPlayerCount == 1) || (gPlayerCount == 2) || (gGamestate == CREDITS_SEQUENCE)) { - update_seagulls(); - } - break; - case COURSE_LUIGI_RACEWAY: - if (D_80165898 != 0) { - update_hot_air_balloon(); - } - break; - case COURSE_MOO_MOO_FARM: - if (gGamestate != CREDITS_SEQUENCE) { - update_moles(); - } - break; - case COURSE_KALAMARI_DESERT: - update_train_smoke(); - break; - case COURSE_SHERBET_LAND: - if (gGamestate != CREDITS_SEQUENCE) { - func_800842C8(); - } - update_penguins(); - break; - case COURSE_RAINBOW_ROAD: - if (gGamestate != CREDITS_SEQUENCE) { - update_neon(); - update_chain_chomps(); - } - break; - case COURSE_DK_JUNGLE: - update_ferries_smoke_particle(); - break; - } + + CourseManager_UpdateCourseObjects(); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // case COURSE_CHOCO_MOUNTAIN: + // break; + // case COURSE_BOWSER_CASTLE: + // func_80081208(); + // update_flame_particle(); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // if (gGamestate != CREDITS_SEQUENCE) { + // update_trash_bin(); + // func_8007E4C4(); + // if (gModeSelection != TIME_TRIALS) { + // update_bat(); + // } + // wrapper_update_boos(); + // update_cheep_cheep(0); + // } + // break; + // case COURSE_YOSHI_VALLEY: + // func_80083080(); + // if (gGamestate != CREDITS_SEQUENCE) { + // update_hedgehogs(); + // } + // break; + // case COURSE_FRAPPE_SNOWLAND: + // if (gGamestate != CREDITS_SEQUENCE) { + // update_snowmen(); + // } + // update_snowflakes(); + // break; + // case COURSE_KOOPA_BEACH: + // if (gGamestate != CREDITS_SEQUENCE) { + // update_crabs(); + // } + // if ((gPlayerCount == 1) || (gPlayerCount == 2) || (gGamestate == CREDITS_SEQUENCE)) { + // update_seagulls(); + // } + // break; + // case COURSE_LUIGI_RACEWAY: + // if (D_80165898 != 0) { + // update_hot_air_balloon(); + // } + // break; + // case COURSE_MOO_MOO_FARM: + // if (gGamestate != CREDITS_SEQUENCE) { + // update_moles(); + // } + // break; + // case COURSE_KALAMARI_DESERT: + // update_train_smoke(); + // break; + // case COURSE_SHERBET_LAND: + // if (gGamestate != CREDITS_SEQUENCE) { + // func_800842C8(); + // } + // update_penguins(); + // break; + // case COURSE_RAINBOW_ROAD: + // if (gGamestate != CREDITS_SEQUENCE) { + // update_neon(); + // update_chain_chomps(); + // } + // break; + // case COURSE_DK_JUNGLE: + // update_ferries_smoke_particle(); + // break; + // } if (D_80165730 != 0) { func_80074EE8(); } func_80076F2C(); - if ((s16) gCurrentCourseId != COURSE_FRAPPE_SNOWLAND) { + if ((s16) GetCourse() != GetFrappeSnowland()) { update_leaf(); } } @@ -2590,7 +2592,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { case 1: /* switch 1 */ func_80079084(playerId); func_800C9060(playerId, SOUND_ARG_LOAD(0x19, 0x00, 0xF0, 0x15)); - if ((gCurrentCourseId == 8) && (D_80165898 == 0) && (gModeSelection != (s32) 1)) { + if ((GetCourse() == GetLuigiRaceway()) && (D_80165898 == 0) && (gModeSelection != (s32) TIME_TRIALS)) { D_80165898 = 1; } break; @@ -2611,7 +2613,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { if (D_8018D114 == 2) { D_80165800[playerId] = 0; } - if (gCurrentCourseId == 4) { + if (GetCourse() == GetYoshiValley()) { playerHUD[playerId].unk_81 = 1; } playerHUD[playerId].lap1CompletionTimeX = 0x0140; @@ -2926,22 +2928,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType, (s8) var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f); - if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -2950,22 +2952,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType, (s8) var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f); - if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3192,44 +3194,44 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f); - if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080); } - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); } else if (player->unk_258[10 + arg2].unk_01E > 0) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f); - if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3385,50 +3387,52 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 var_f12 = player->pos[2]; surfaceType = player->tyres[BACK_RIGHT].surfaceType; } + + //! @todo This likely needs to be implemented for custom courses switch (surfaceType) { case DIRT: if ((arg1 == 0) && ((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f); - if ((gCurrentCourseId == 1) || (gCurrentCourseId == 7)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == 0x000B) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == 9) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == 0x000E) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == 4) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (gCurrentCourseId == 0x0012) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); } else if (player->unk_258[10 + arg2].unk_01E > 0) { func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f); - if ((gCurrentCourseId == 1) || (gCurrentCourseId == 7)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080); } - if (gCurrentCourseId == 0x000B) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080); } - if (gCurrentCourseId == 9) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080); } - if (gCurrentCourseId == 0x000E) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080); } - if (gCurrentCourseId == 4) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080); } - if (gCurrentCourseId == 0x0012) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080); } player->unk_258[10 + arg1].unk_03A = random_int(0x0010U); @@ -3627,13 +3631,13 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 var_f0 = 0.0f; } sp4C = (D_801652A0[arg3] - player->pos[1]) - 3.0f; - if ((player->unk_0DE & 1) && (gCurrentCourseId != COURSE_KOOPA_BEACH)) { + if ((player->unk_0DE & 1) && (GetCourse() != GetKoopaTroopaBeach())) { var_f0 = 2.5f; sp4C = (f32) ((f64) (D_801652A0[arg3] - player->pos[1]) + 0.1); } func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); func_8005D7D8(&player->unk_258[arg1], 3, var_f0); - if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { + if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { func_8005D800(&player->unk_258[arg1], 0, 0x00AF); } else { func_8005D800(&player->unk_258[arg1], 0x00FFFFFF, 0x00CF); @@ -3647,7 +3651,7 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 } void func_80060B14(Player* player, s16 arg1, s32 arg2, s8 arg3, s8 arg4) { - if ((gCurrentCourseId != COURSE_SKYSCRAPER) && (gCurrentCourseId != COURSE_RAINBOW_ROAD)) { + if ((GetCourse() != GetSkyscraper()) && (GetCourse() != GetRainbowRoad())) { if ((arg1 == 0) && ((player->unk_258[arg2].unk_01E > 0) || (player->unk_258[arg2].unk_01C == 0))) { func_800608E0(player, arg1, arg2, arg3, arg4); } else if (player->unk_258[arg2].unk_01E > 0) { @@ -3663,10 +3667,10 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 f32 sp48; f32 sp44; - if (gCurrentCourseId == COURSE_SKYSCRAPER) { + if (GetCourse() == GetSkyscraper()) { return; } - if (gCurrentCourseId == COURSE_RAINBOW_ROAD) { + if (GetCourse() == GetRainbowRoad()) { return; } sp54 = random_int(0x0168U) - 0xB4; @@ -3701,7 +3705,7 @@ void func_80060F50(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, 0, 0); func_8005D7D8(&player->unk_258[arg1], 5, 4.0f); - if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { + if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { func_8005D800(&player->unk_258[arg1], 0xFF0000, 0xFF); } else { func_8005D800(&player->unk_258[arg1], 0xFFFFFF, 0xFF); @@ -4047,22 +4051,22 @@ void func_800624D8(Player* player, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s8 a switch (player->surfaceType) { case DIRT: for (var_s1 = 0; var_s1 < 10; var_s1++) { - if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { + if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 1, 0, 0x00A8); } - if (gCurrentCourseId == COURSE_KALAMARI_DESERT) { + if (GetCourse() == GetKalimariDesert()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 7, 0, 0x00A8); } - if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + if (GetCourse() == GetMooMooFarm()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 8, 0, 0x00A8); } - if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + if (GetCourse() == GetWarioStadium()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 9, 0, 0x00A8); } - if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + if (GetCourse() == GetYoshiValley()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000A, 0, 0x00A8); } - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000B, 0, 0x00A8); } func_80062484(player, &player->unk_258[0x1E + var_s1], var_s1); @@ -4617,7 +4621,7 @@ void func_80064184(Player* player, s16 arg1, s8 arg2, UNUSED s8 arg3) { f32 sp3C; sp40 = D_801652A0[arg2] - player->pos[1] - 3.0f; - if (((player->unk_0DE & 1) != 0) && (gCurrentCourseId != COURSE_KOOPA_BEACH)) { + if (((player->unk_0DE & 1) != 0) && (GetCourse() != GetKoopaTroopaBeach())) { sp40 = D_801652A0[arg2] - player->pos[1] + 0.1; } diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index baf4e1aa1..9b2e69331 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -135,7 +135,7 @@ u8* func_8006ED94(u8* devAddr, u8* baseAddress, u32 size, u32 offset) { return baseAddress; } -void func_8006EE44(void) { +void load_mario_kart_64_logo(void) { u8* d_gTextureLogoMarioKart64 = LOAD_ASSET(gTextureLogoMarioKart64); D_8018D1E0 = func_8006ED94((u8*) d_gTextureLogoMarioKart64, (u8*) D_8018D9B0, 0x79E1, 0x20000); } @@ -190,151 +190,153 @@ void func_8006F008(void) { D_8018D308 = 255; D_8018D310 = 255; D_8018D318 = 255; - if (gCurrentCourseId < NUM_COURSES - 1) { + if (GetCourse() != GetPodiumCeremony()) { func_8006EEE8((s32) gCurrentCourseId); } + CourseManager_MinimapSettings(); + switch (gCurrentCourseId) { case COURSE_MARIO_RACEWAY: - D_8018D220 = (void*) dma_textures(gTextureExhaust5, 0x443, 0x1000); - D_8018D2A0 = 0.022f; - D_8018D2E0 = 6; - D_8018D2E8 = 28; - D_8018D2C0[0] = 260; - D_8018D2D8[0] = 170; - D_80165718 = 0; - D_80165720 = 5; - D_80165728 = -240; + // D_8018D220 = (void*) dma_textures(gTextureExhaust5, 0x443, 0x1000); + // D_8018D2A0 = 0.022f; + // D_8018D2E0 = 6; + // D_8018D2E8 = 28; + // D_8018D2C0[0] = 260; + // D_8018D2D8[0] = 170; + // D_80165718 = 0; + // D_80165720 = 5; + // D_80165728 = -240; break; - case COURSE_CHOCO_MOUNTAIN: - D_8018D2A0 = 0.022f; - D_8018D2C0[0] = 265; - D_8018D2E0 = 19; - D_8018D2E8 = 37; - break; - case COURSE_BOWSER_CASTLE: - D_8018D2C0[0] = 265; - D_8018D2A0 = 0.0174f; - D_8018D2E0 = 12; - D_8018D2E8 = 48; - break; - case COURSE_BANSHEE_BOARDWALK: - D_80165880 = (void*) dma_textures(gTextureGhosts, 0x4CC2, 0xD980); - D_8018D2A0 = 0.016f; - D_8018D2C0[0] = 0x0106; - D_8018D2E0 = 55; - D_8018D2E8 = 39; - break; - case COURSE_YOSHI_VALLEY: - D_8018D220 = (void*) dma_textures(gTextureExhaust0, 0x479, 0xC00); - D_8018D2A0 = 0.018f; - D_8018D2E0 = 61; - D_8018D2E8 = 38; - break; - case COURSE_FRAPPE_SNOWLAND: - D_8018D2C0[0] = 262; - D_8018D2A0 = 0.016f; - D_8018D2E0 = 36; - D_8018D2E8 = 40; - D_8018D300 = 72; - D_8018D308 = 100; - D_8018D310 = 255; - break; - case COURSE_KOOPA_BEACH: - D_8018D220 = (void*) dma_textures(gTextureExhaust3, 0x3C8U, 0x1000); - D_8018D2A0 = 0.014f; - D_8018D2C0[0] = 268; - D_8018D2E0 = 40; - D_8018D2E8 = 21; - break; - case COURSE_ROYAL_RACEWAY: - D_8018D220 = (void*) dma_textures(gTextureExhaust4, 0x3F8, 0x1000); - D_8018D2C0[0] = 262; - D_8018D2A0 = 0.014f; - D_8018D2E0 = 37; - D_8018D2E8 = 50; - D_80165718 = -64; - D_80165720 = 5; - D_80165728 = -330; - break; - case COURSE_LUIGI_RACEWAY: - D_8018D220 = (void*) dma_textures(gTextureExhaust2, 0x4F4U, 0xC00); - D_8018D2A0 = 0.0155f; - D_8018D2C0[0] = 271; - D_8018D2E0 = 45; - D_8018D2E8 = 60; - D_80165718 = -140; - D_80165720 = -44; - D_80165728 = -215; - break; - case COURSE_MOO_MOO_FARM: - D_8018D220 = (void*) dma_textures(gTextureExhaust0, 0x479, 0xC00); - D_8018D2A0 = 0.0155f; - D_8018D2C0[0] = 271; - D_8018D2E0 = 18; - D_8018D2E8 = 36; - break; - case COURSE_TOADS_TURNPIKE: - D_8018D2A0 = 0.013f; - D_8018D2C0[0] = 252; - D_8018D2E0 = 57; - D_8018D2E8 = 44; - break; - case COURSE_KALAMARI_DESERT: - D_8018D2C0[0] = 263; - D_8018D2D8[0] = 165; - D_8018D220 = (void*) dma_textures(gTextureExhaust5, 0x443, 0x1000); - D_8018D2A0 = 0.015f; - D_8018D2E0 = 55; - D_8018D2E8 = 27; - break; - case COURSE_SHERBET_LAND: - D_8018D220 = (void*) dma_textures(gTextureExhaust1, 0x485, 0xC00); - D_8018D2A0 = 0.015f; - D_8018D2C0[0] = 262; - D_8018D2E0 = 52; - D_8018D2E8 = 33; - D_8018D300 = 72; - D_8018D308 = 100; - D_8018D310 = 255; - break; - case COURSE_RAINBOW_ROAD: - D_8018D2A0 = 0.0103f; - D_8018D2C0[0] = 261; - D_8018D2D8[0] = 166; - D_8018D2E0 = 39; - D_8018D2E8 = 55; - break; - case COURSE_WARIO_STADIUM: - D_8018D2A0 = 0.0155f; - D_8018D2C0[0] = 0x0106; - D_8018D2E0 = 53; - D_8018D2E8 = 35; - break; - case COURSE_BLOCK_FORT: - D_8018D2A0 = 0.0335f; - D_8018D2E0 = 32; - D_8018D2E8 = 32; - break; - case COURSE_SKYSCRAPER: - D_8018D2A0 = 0.0445f; - D_8018D2E0 = 32; - D_8018D2E8 = 32; - break; - case COURSE_DOUBLE_DECK: - D_8018D2A0 = 0.0285f; - D_8018D2E0 = 32; - D_8018D2E8 = 32; - break; - case COURSE_DK_JUNGLE: - D_8018D2A0 = 0.0155f; - D_8018D2C0[0] = 255; - D_8018D2E0 = 29; - D_8018D2E8 = 47; - break; - case COURSE_BIG_DONUT: - D_8018D2A0 = 0.0257f; - D_8018D2E0 = 32; - D_8018D2E8 = 31; + // case COURSE_CHOCO_MOUNTAIN: + // D_8018D2A0 = 0.022f; + // D_8018D2C0[0] = 265; + // D_8018D2E0 = 19; + // D_8018D2E8 = 37; + // break; + // case COURSE_BOWSER_CASTLE: + // D_8018D2C0[0] = 265; + // D_8018D2A0 = 0.0174f; + // D_8018D2E0 = 12; + // D_8018D2E8 = 48; + // break; + // case COURSE_BANSHEE_BOARDWALK: + // D_80165880 = (void*) dma_textures(gTextureGhosts, 0x4CC2, 0xD980); + // D_8018D2A0 = 0.016f; + // D_8018D2C0[0] = 0x0106; + // D_8018D2E0 = 55; + // D_8018D2E8 = 39; + // break; + // case COURSE_YOSHI_VALLEY: + // D_8018D220 = (void*) dma_textures(gTextureExhaust0, 0x479, 0xC00); + // D_8018D2A0 = 0.018f; + // D_8018D2E0 = 61; + // D_8018D2E8 = 38; + // break; + // case COURSE_FRAPPE_SNOWLAND: + // D_8018D2C0[0] = 262; + // D_8018D2A0 = 0.016f; + // D_8018D2E0 = 36; + // D_8018D2E8 = 40; + // D_8018D300 = 72; + // D_8018D308 = 100; + // D_8018D310 = 255; + // break; + // case COURSE_KOOPA_BEACH: + // D_8018D220 = (void*) dma_textures(gTextureExhaust3, 0x3C8U, 0x1000); + // D_8018D2A0 = 0.014f; + // D_8018D2C0[0] = 268; + // D_8018D2E0 = 40; + // D_8018D2E8 = 21; + // break; + // case COURSE_ROYAL_RACEWAY: + // D_8018D220 = (void*) dma_textures(gTextureExhaust4, 0x3F8, 0x1000); + // D_8018D2C0[0] = 262; + // D_8018D2A0 = 0.014f; + // D_8018D2E0 = 37; + // D_8018D2E8 = 50; + // D_80165718 = -64; + // D_80165720 = 5; + // D_80165728 = -330; + // break; + // case COURSE_LUIGI_RACEWAY: + // D_8018D220 = (void*) dma_textures(gTextureExhaust2, 0x4F4U, 0xC00); + // D_8018D2A0 = 0.0155f; + // D_8018D2C0[0] = 271; + // D_8018D2E0 = 45; + // D_8018D2E8 = 60; + // D_80165718 = -140; + // D_80165720 = -44; + // D_80165728 = -215; + // break; + // case COURSE_MOO_MOO_FARM: + // D_8018D220 = (void*) dma_textures(gTextureExhaust0, 0x479, 0xC00); + // D_8018D2A0 = 0.0155f; + // D_8018D2C0[0] = 271; + // D_8018D2E0 = 18; + // D_8018D2E8 = 36; + // break; + // case COURSE_TOADS_TURNPIKE: + // D_8018D2A0 = 0.013f; + // D_8018D2C0[0] = 252; + // D_8018D2E0 = 57; + // D_8018D2E8 = 44; + // break; + // case COURSE_KALAMARI_DESERT: + // D_8018D2C0[0] = 263; + // D_8018D2D8[0] = 165; + // D_8018D220 = (void*) dma_textures(gTextureExhaust5, 0x443, 0x1000); + // D_8018D2A0 = 0.015f; + // D_8018D2E0 = 55; + // D_8018D2E8 = 27; + // break; + // case COURSE_SHERBET_LAND: + // D_8018D220 = (void*) dma_textures(gTextureExhaust1, 0x485, 0xC00); + // D_8018D2A0 = 0.015f; + // D_8018D2C0[0] = 262; + // D_8018D2E0 = 52; + // D_8018D2E8 = 33; + // D_8018D300 = 72; + // D_8018D308 = 100; + // D_8018D310 = 255; + // break; + // case COURSE_RAINBOW_ROAD: + // D_8018D2A0 = 0.0103f; + // D_8018D2C0[0] = 261; + // D_8018D2D8[0] = 166; + // D_8018D2E0 = 39; + // D_8018D2E8 = 55; + // break; + // case COURSE_WARIO_STADIUM: + // D_8018D2A0 = 0.0155f; + // D_8018D2C0[0] = 0x0106; + // D_8018D2E0 = 53; + // D_8018D2E8 = 35; + // break; + // case COURSE_BLOCK_FORT: + // D_8018D2A0 = 0.0335f; + // D_8018D2E0 = 32; + // D_8018D2E8 = 32; + // break; + // case COURSE_SKYSCRAPER: + // D_8018D2A0 = 0.0445f; + // D_8018D2E0 = 32; + // D_8018D2E8 = 32; + // break; + // case COURSE_DOUBLE_DECK: + // D_8018D2A0 = 0.0285f; + // D_8018D2E0 = 32; + // D_8018D2E8 = 32; + // break; + // case COURSE_DK_JUNGLE: + // D_8018D2A0 = 0.0155f; + // D_8018D2C0[0] = 255; + // D_8018D2E0 = 29; + // D_8018D2E8 = 47; + // break; + // case COURSE_BIG_DONUT: + // D_8018D2A0 = 0.0257f; + // D_8018D2E0 = 32; + // D_8018D2E8 = 31; } if (gIsMirrorMode != 0) { D_8018D2E0 = D_8018D2B0 - D_8018D2E0; @@ -350,7 +352,7 @@ void func_8006F008(void) { return; } if (gPlayerCount == 2) { - if (gCurrentCourseId != 10) { + if (GetCourse() != GetToadsTurnpike()) { D_8018D2C0[1] = 265; D_8018D2C0[0] = D_8018D2C0[1]; } else { @@ -697,53 +699,55 @@ void func_8007055C(void) { s32 var_s0; s32 var_s4; + CourseManager_InitClouds(); + switch (gCurrentCourseId) { case COURSE_MARIO_RACEWAY: // Uses Kalimari Desert's clouds for initialization? - init_clouds(gKalimariDesertClouds); - break; - case COURSE_YOSHI_VALLEY: - init_clouds(gYoshiValleyMooMooFarmClouds); - break; - case COURSE_FRAPPE_SNOWLAND: - if (gPlayerCount == 1) { - var_s4 = 0x32; - } else { - var_s4 = 0x19; - } - for (var_s0 = 0; var_s0 < var_s4; var_s0++) { - find_unused_obj_index(&D_8018CC80[D_8018D1F8 + var_s0]); - } - D_8018D1F8 += var_s0; - D_8018D1F0 = var_s0; - break; - case COURSE_KOOPA_BEACH: - init_clouds(gKoopaTroopaBeachClouds); - break; - case COURSE_ROYAL_RACEWAY: - init_clouds(gRoyalRacewayClouds); - break; - case COURSE_LUIGI_RACEWAY: - init_clouds(gLuigiRacewayClouds); - break; - case COURSE_MOO_MOO_FARM: - init_clouds(gYoshiValleyMooMooFarmClouds); - break; - case COURSE_TOADS_TURNPIKE: - init_stars(gToadsTurnpikeRainbowRoadStars); - break; - case COURSE_KALAMARI_DESERT: - init_clouds(gKalimariDesertClouds); - break; - case COURSE_SHERBET_LAND: - init_clouds(gSherbetLandClouds); - break; - case COURSE_RAINBOW_ROAD: - init_stars(gToadsTurnpikeRainbowRoadStars); - break; - case COURSE_WARIO_STADIUM: - init_stars(gWarioStadiumStars); + //init_clouds(gKalimariDesertClouds); break; + // case COURSE_YOSHI_VALLEY: + // init_clouds(gYoshiValleyMooMooFarmClouds); + // break; + // case COURSE_FRAPPE_SNOWLAND: + // if (gPlayerCount == 1) { + // var_s4 = 0x32; + // } else { + // var_s4 = 0x19; + // } + // for (var_s0 = 0; var_s0 < var_s4; var_s0++) { + // find_unused_obj_index(&D_8018CC80[D_8018D1F8 + var_s0]); + // } + // D_8018D1F8 += var_s0; + // D_8018D1F0 = var_s0; + // break; + // case COURSE_KOOPA_BEACH: + // init_clouds(gKoopaTroopaBeachClouds); + // break; + // case COURSE_ROYAL_RACEWAY: + // init_clouds(gRoyalRacewayClouds); + // break; + // case COURSE_LUIGI_RACEWAY: + // init_clouds(gLuigiRacewayClouds); + // break; + // case COURSE_MOO_MOO_FARM: + // init_clouds(gYoshiValleyMooMooFarmClouds); + // break; + // case COURSE_TOADS_TURNPIKE: + // init_stars(gToadsTurnpikeRainbowRoadStars); + // break; + // case COURSE_KALAMARI_DESERT: + // init_clouds(gKalimariDesertClouds); + // break; + // case COURSE_SHERBET_LAND: + // init_clouds(gSherbetLandClouds); + // break; + // case COURSE_RAINBOW_ROAD: + // init_stars(gToadsTurnpikeRainbowRoadStars); + // break; + // case COURSE_WARIO_STADIUM: + // init_stars(gWarioStadiumStars); + // break; } func_8008C23C(); } @@ -767,258 +771,260 @@ void init_course_object(void) { s32 objectId; s32 i; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - if (gGamestate != 9) { - if (gModeSelection == GRAND_PRIX) { - func_80070714(); - } - for (i = 0; i < D_80165738; i++) { - find_unused_obj_index(&gObjectParticle3[i]); - init_object(gObjectParticle3[i], 0); - } - } - break; - case COURSE_BOWSER_CASTLE: - gNumActiveThwomps = NUM_THWOMPS_100CC_EXTRA; - gThowmpSpawnList = gThwompSpawns100CCExtra; - switch (gCCSelection) { /* switch 1; irregular */ - case CC_100: /* switch 1 */ - case CC_EXTRA: /* switch 1 */ - break; - case CC_50: /* switch 1 */ - gNumActiveThwomps = NUM_THWOMPS_50CC; - gThowmpSpawnList = gThomwpSpawns50CC; - break; - case CC_150: /* switch 1 */ - gNumActiveThwomps = NUM_THWOMPS_150CC; - gThowmpSpawnList = gThomwpSpawns150CC; - break; - } - for (i = 0; i < gNumActiveThwomps; i++) { - objectId = indexObjectList1[i]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = gThowmpSpawnList[i].startX * xOrientation; - gObjectList[objectId].origin_pos[2] = gThowmpSpawnList[i].startZ; - gObjectList[objectId].unk_0D5 = gThowmpSpawnList[i].unk_4; - gObjectList[objectId].primAlpha = gThowmpSpawnList[i].unk_6; - } - // Handle the big statue's fire breath - objectId = indexObjectList2[0]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = -68.0 * xOrientation; - gObjectList[objectId].pos[1] = 80.0f; - gObjectList[objectId].pos[2] = -1840.0f; - // Handle the smaller statues' fire breath - for (i = 0; i < NUM_FIRE_BREATHS; i++) { - objectId = indexObjectList3[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gFireBreathsSpawns[i][0] * xOrientation; - gObjectList[objectId].pos[1] = gFireBreathsSpawns[i][1]; - gObjectList[objectId].pos[2] = gFireBreathsSpawns[i][2]; - gObjectList[objectId].direction_angle[1] = 0; - if (i % 2U) { - gObjectList[objectId].direction_angle[1] += 0x8000; - } - } - for (i = 0; i < 32; i++) { - delete_object(&indexObjectList4[i]); - } - break; - case COURSE_BANSHEE_BOARDWALK: - if (gGamestate != CREDITS_SEQUENCE) { - objectId = indexObjectList1[0]; - init_texture_object(objectId, d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, - (u16) 0x00000040); - gObjectList[objectId].orientation[0] = 0; - gObjectList[objectId].orientation[1] = 0; - gObjectList[objectId].orientation[2] = 0x8000; - init_object(indexObjectList1[1], 0); - init_object(indexObjectList1[2], 0); - } - break; - case COURSE_YOSHI_VALLEY: - for (i = 0; i < NUM_YV_FLAG_POLES; i++) { - init_object(indexObjectList1[i], 0); - } - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_HEDGEHOGS; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = - gHedgehogSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = - gHedgehogSpawns[i].pos[1] + 6.0; - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gHedgehogSpawns[i].pos[2]; - gObjectList[objectId].unk_0D5 = gHedgehogSpawns[i].unk_06; - gObjectList[objectId].unk_09C = gHedgehogPatrolPoints[i][0] * xOrientation; - gObjectList[objectId].unk_09E = gHedgehogPatrolPoints[i][2]; - } - } - break; - case COURSE_FRAPPE_SNOWLAND: - for (i = 0; i < NUM_SNOWFLAKES; i++) { - find_unused_obj_index(&gObjectParticle1[i]); - } - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_SNOWMEN; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 5.0 + 3.0; - gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; - objectId = indexObjectList1[i]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 3.0; - gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; - gObjectList[objectId].unk_0D5 = gSnowmanSpawns[i].unk_6; - } - } - break; - case COURSE_KOOPA_BEACH: - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_CRABS; i++) { - objectId = indexObjectList1[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = - gCrabSpawns[i].startX * xOrientation; - gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; + CourseManager_InitCourseObjects(); - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; - gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; - } - } - for (i = 0; i < NUM_SEAGULLS; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - if (i < (NUM_SEAGULLS / 2)) { - gObjectList[objectId].unk_0D5 = 0; - } else { - gObjectList[objectId].unk_0D5 = 1; - } - } - break; - case COURSE_ROYAL_RACEWAY: - if (gGamestate != CREDITS_SEQUENCE) { - if (gModeSelection == GRAND_PRIX) { - func_80070714(); - } - for (i = 0; i < D_80165738; i++) { - find_unused_obj_index(&gObjectParticle3[i]); - init_object(gObjectParticle3[i], 0); - } - } - break; - case COURSE_LUIGI_RACEWAY: - if (gGamestate != CREDITS_SEQUENCE) { - if (gModeSelection == GRAND_PRIX) { - func_80070714(); - } - D_80165898 = 0; - init_object(indexObjectList1[0], 0); - for (i = 0; i < D_80165738; i++) { - find_unused_obj_index(&gObjectParticle3[i]); - init_object(gObjectParticle3[i], 0); - } - } - break; - case COURSE_MOO_MOO_FARM: - if (gGamestate != CREDITS_SEQUENCE) { - if ((gPlayerCount == 1) || ((gPlayerCount == 2) && (gModeSelection == VERSUS))) { - switch (gCCSelection) { /* switch 2; irregular */ - case CC_50: /* switch 2 */ - D_8018D1C8 = 4; - D_8018D1D0 = 6; - D_8018D1D8 = 6; - break; - case CC_100: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 8; - break; - case CC_150: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 10; - break; - case CC_EXTRA: /* switch 2 */ - D_8018D1C8 = 5; - D_8018D1D0 = 8; - D_8018D1D8 = 8; - break; - } - } else { - D_8018D1C8 = 4; - D_8018D1D0 = 6; - D_8018D1D8 = 6; - } - for (i = 0; i < NUM_GROUP1_MOLES; i++) { - D_8018D198[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_GROUP2_MOLES; i++) { - D_8018D1A8[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_GROUP3_MOLES; i++) { - D_8018D1B8[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_TOTAL_MOLES; i++) { - find_unused_obj_index(&gObjectParticle1[i]); - objectId = gObjectParticle1[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; - gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; - func_800887C0(objectId); - gObjectList[objectId].sizeScaling = 0.7f; - } - for (i = 0; i < gObjectParticle2_SIZE; i++) { - find_unused_obj_index(&gObjectParticle2[i]); - } - } - break; - case COURSE_KALAMARI_DESERT: - if (gGamestate != CREDITS_SEQUENCE) { - find_unused_obj_index(&D_8018CF10); - init_object(D_8018CF10, 0); - for (i = 0; i < 50; i++) { - find_unused_obj_index(&gObjectParticle1[i]); - } - for (i = 0; i < 5; i++) { - find_unused_obj_index(&gObjectParticle2[i]); - } - for (i = 0; i < 32; i++) { - find_unused_obj_index(&gObjectParticle3[i]); - } - } - break; - case COURSE_SHERBET_LAND: - for (i = 0; i < NUM_PENGUINS; i++) { - init_object(indexObjectList1[i], 0); - } - break; - case COURSE_RAINBOW_ROAD: - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_NEON_SIGNS; i++) { - init_object(indexObjectList1[i], 0); - } - for (i = 0; i < NUM_CHAIN_CHOMPS; i++) { - init_object(indexObjectList2[i], 0); - } - } - break; - case COURSE_DK_JUNGLE: - for (i = 0; i < NUM_TORCHES; i++) { - init_smoke_particles(i); - // wtf? - if (D_8018CF10) {} - } - break; - default: - break; - } + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // // if (gGamestate != 9) { + // // if (gModeSelection == GRAND_PRIX) { + // // func_80070714(); + // // } + // // for (i = 0; i < D_80165738; i++) { + // // find_unused_obj_index(&gObjectParticle3[i]); + // // init_object(gObjectParticle3[i], 0); + // // } + // // } + // break; + // case COURSE_BOWSER_CASTLE: + // gNumActiveThwomps = NUM_THWOMPS_100CC_EXTRA; + // gThowmpSpawnList = gThwompSpawns100CCExtra; + // switch (gCCSelection) { /* switch 1; irregular */ + // case CC_100: /* switch 1 */ + // case CC_EXTRA: /* switch 1 */ + // break; + // case CC_50: /* switch 1 */ + // gNumActiveThwomps = NUM_THWOMPS_50CC; + // gThowmpSpawnList = gThomwpSpawns50CC; + // break; + // case CC_150: /* switch 1 */ + // gNumActiveThwomps = NUM_THWOMPS_150CC; + // gThowmpSpawnList = gThomwpSpawns150CC; + // break; + // } + // for (i = 0; i < gNumActiveThwomps; i++) { + // objectId = indexObjectList1[i]; + // init_object(objectId, 0); + // gObjectList[objectId].origin_pos[0] = gThowmpSpawnList[i].startX * xOrientation; + // gObjectList[objectId].origin_pos[2] = gThowmpSpawnList[i].startZ; + // gObjectList[objectId].unk_0D5 = gThowmpSpawnList[i].unk_4; + // gObjectList[objectId].primAlpha = gThowmpSpawnList[i].unk_6; + // } + // // Handle the big statue's fire breath + // objectId = indexObjectList2[0]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = -68.0 * xOrientation; + // gObjectList[objectId].pos[1] = 80.0f; + // gObjectList[objectId].pos[2] = -1840.0f; + // // Handle the smaller statues' fire breath + // for (i = 0; i < NUM_FIRE_BREATHS; i++) { + // objectId = indexObjectList3[i]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = gFireBreathsSpawns[i][0] * xOrientation; + // gObjectList[objectId].pos[1] = gFireBreathsSpawns[i][1]; + // gObjectList[objectId].pos[2] = gFireBreathsSpawns[i][2]; + // gObjectList[objectId].direction_angle[1] = 0; + // if (i % 2U) { + // gObjectList[objectId].direction_angle[1] += 0x8000; + // } + // } + // for (i = 0; i < 32; i++) { + // delete_object(&indexObjectList4[i]); + // } + // break; + // case COURSE_BANSHEE_BOARDWALK: + // if (gGamestate != CREDITS_SEQUENCE) { + // objectId = indexObjectList1[0]; + // init_texture_object(objectId, d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, + // (u16) 0x00000040); + // gObjectList[objectId].orientation[0] = 0; + // gObjectList[objectId].orientation[1] = 0; + // gObjectList[objectId].orientation[2] = 0x8000; + // init_object(indexObjectList1[1], 0); + // init_object(indexObjectList1[2], 0); + // } + // break; + // case COURSE_YOSHI_VALLEY: + // for (i = 0; i < NUM_YV_FLAG_POLES; i++) { + // init_object(indexObjectList1[i], 0); + // } + // if (gGamestate != CREDITS_SEQUENCE) { + // for (i = 0; i < NUM_HEDGEHOGS; i++) { + // objectId = indexObjectList2[i]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = + // gHedgehogSpawns[i].pos[0] * xOrientation; + // gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = + // gHedgehogSpawns[i].pos[1] + 6.0; + // gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gHedgehogSpawns[i].pos[2]; + // gObjectList[objectId].unk_0D5 = gHedgehogSpawns[i].unk_06; + // gObjectList[objectId].unk_09C = gHedgehogPatrolPoints[i][0] * xOrientation; + // gObjectList[objectId].unk_09E = gHedgehogPatrolPoints[i][2]; + // } + // } + // break; + // case COURSE_FRAPPE_SNOWLAND: + // for (i = 0; i < NUM_SNOWFLAKES; i++) { + // find_unused_obj_index(&gObjectParticle1[i]); + // } + // if (gGamestate != CREDITS_SEQUENCE) { + // for (i = 0; i < NUM_SNOWMEN; i++) { + // objectId = indexObjectList2[i]; + // init_object(objectId, 0); + // gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; + // gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 5.0 + 3.0; + // gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; + // objectId = indexObjectList1[i]; + // init_object(objectId, 0); + // gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; + // gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 3.0; + // gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; + // gObjectList[objectId].unk_0D5 = gSnowmanSpawns[i].unk_6; + // } + // } + // break; + // case COURSE_KOOPA_BEACH: + // if (gGamestate != CREDITS_SEQUENCE) { + // for (i = 0; i < NUM_CRABS; i++) { + // objectId = indexObjectList1[i]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = + // gCrabSpawns[i].startX * xOrientation; + // gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; + + // gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; + // gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; + // } + // } + // for (i = 0; i < NUM_SEAGULLS; i++) { + // objectId = indexObjectList2[i]; + // init_object(objectId, 0); + // if (i < (NUM_SEAGULLS / 2)) { + // gObjectList[objectId].unk_0D5 = 0; + // } else { + // gObjectList[objectId].unk_0D5 = 1; + // } + // } + // break; + // case COURSE_ROYAL_RACEWAY: + // if (gGamestate != CREDITS_SEQUENCE) { + // if (gModeSelection == GRAND_PRIX) { + // func_80070714(); + // } + // for (i = 0; i < D_80165738; i++) { + // find_unused_obj_index(&gObjectParticle3[i]); + // init_object(gObjectParticle3[i], 0); + // } + // } + // break; + // case COURSE_LUIGI_RACEWAY: + // if (gGamestate != CREDITS_SEQUENCE) { + // if (gModeSelection == GRAND_PRIX) { + // func_80070714(); + // } + // D_80165898 = 0; + // init_object(indexObjectList1[0], 0); + // for (i = 0; i < D_80165738; i++) { + // find_unused_obj_index(&gObjectParticle3[i]); + // init_object(gObjectParticle3[i], 0); + // } + // } + // break; + // case COURSE_MOO_MOO_FARM: + // if (gGamestate != CREDITS_SEQUENCE) { + // if ((gPlayerCount == 1) || ((gPlayerCount == 2) && (gModeSelection == VERSUS))) { + // switch (gCCSelection) { /* switch 2; irregular */ + // case CC_50: /* switch 2 */ + // D_8018D1C8 = 4; + // D_8018D1D0 = 6; + // D_8018D1D8 = 6; + // break; + // case CC_100: /* switch 2 */ + // D_8018D1C8 = 5; + // D_8018D1D0 = 8; + // D_8018D1D8 = 8; + // break; + // case CC_150: /* switch 2 */ + // D_8018D1C8 = 5; + // D_8018D1D0 = 8; + // D_8018D1D8 = 10; + // break; + // case CC_EXTRA: /* switch 2 */ + // D_8018D1C8 = 5; + // D_8018D1D0 = 8; + // D_8018D1D8 = 8; + // break; + // } + // } else { + // D_8018D1C8 = 4; + // D_8018D1D0 = 6; + // D_8018D1D8 = 6; + // } + // for (i = 0; i < NUM_GROUP1_MOLES; i++) { + // D_8018D198[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_GROUP2_MOLES; i++) { + // D_8018D1A8[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_GROUP3_MOLES; i++) { + // D_8018D1B8[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_TOTAL_MOLES; i++) { + // find_unused_obj_index(&gObjectParticle1[i]); + // objectId = gObjectParticle1[i]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; + // gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; + // func_800887C0(objectId); + // gObjectList[objectId].sizeScaling = 0.7f; + // } + // for (i = 0; i < gObjectParticle2_SIZE; i++) { + // find_unused_obj_index(&gObjectParticle2[i]); + // } + // } + // break; + // case COURSE_KALAMARI_DESERT: + // if (gGamestate != CREDITS_SEQUENCE) { + // find_unused_obj_index(&D_8018CF10); + // init_object(D_8018CF10, 0); + // for (i = 0; i < 50; i++) { + // find_unused_obj_index(&gObjectParticle1[i]); + // } + // for (i = 0; i < 5; i++) { + // find_unused_obj_index(&gObjectParticle2[i]); + // } + // for (i = 0; i < 32; i++) { + // find_unused_obj_index(&gObjectParticle3[i]); + // } + // } + // break; + // case COURSE_SHERBET_LAND: + // for (i = 0; i < NUM_PENGUINS; i++) { + // init_object(indexObjectList1[i], 0); + // } + // break; + // case COURSE_RAINBOW_ROAD: + // if (gGamestate != CREDITS_SEQUENCE) { + // for (i = 0; i < NUM_NEON_SIGNS; i++) { + // init_object(indexObjectList1[i], 0); + // } + // for (i = 0; i < NUM_CHAIN_CHOMPS; i++) { + // init_object(indexObjectList2[i], 0); + // } + // } + // break; + // case COURSE_DK_JUNGLE: + // for (i = 0; i < NUM_TORCHES; i++) { + // init_smoke_particles(i); + // // wtf? + // if (D_8018CF10) {} + // } + // break; + // default: + // break; + // } } void init_hud_one_player(void) { diff --git a/src/code_8006E9C0.h b/src/code_8006E9C0.h index 61f8ab4f9..b26dab556 100644 --- a/src/code_8006E9C0.h +++ b/src/code_8006E9C0.h @@ -9,7 +9,7 @@ void reset_object_variable(void); void func_8006EB10(void); void clear_object_list(void); u8* func_8006ED94(u8*, u8*, u32, u32); -void func_8006EE44(void); +void load_mario_kart_64_logo(void); void init_item_window(s32); void func_8006EEE8(s32); void func_8006EF60(void); diff --git a/src/code_80086E70.c b/src/code_80086E70.c index 6c94edee9..a7a2180ae 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -976,7 +976,7 @@ void func_80089020(s32 playerId, f32* arg1) { var_f2 = -*arg1; } if (player->effects & 0xC0) { - if (gCurrentCourseId == COURSE_SHERBET_LAND) { + if (GetCourse() == GetSherbetLand()) { if (var_f2 <= 0.5) { var_f0 = 0.025f; } else if (var_f2 <= 2.0) { @@ -997,7 +997,7 @@ void func_80089020(s32 playerId, f32* arg1) { var_f0 = 0.25f; } } - } else if (gCurrentCourseId == COURSE_SHERBET_LAND) { + } else if (GetCourse() == GetSherbetLand()) { if (var_f2 <= 0.5) { var_f0 = 0.025f; } else if (var_f2 <= 2.0) { diff --git a/src/code_80091750.c b/src/code_80091750.c index 6190642be..f0ad51099 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -43,6 +43,11 @@ #include "stdio.h" #include "port/Engine.h" +#include "engine/Engine.h" +#include "engine/courses/Course.h" + +const char* GetCupName(void); + u16* D_8018D9B0; u8* D_8018D9B4; u8* D_8018D9B8; @@ -61,7 +66,7 @@ struct_8018D9E0_entry D_8018D9E0[D_8018D9E0_SIZE]; struct_8018DEE0_entry D_8018DEE0[D_8018DEE0_SIZE]; struct_8018E060_entry D_8018E060[D_8018E060_SIZE + 1]; struct_8018E0E8_entry D_8018E0E8[D_8018E0E8_SIZE]; -s32 gD_8018E118TotalSize; +s32 gMenuTextureBufferIndex; struct_8018E118_entry D_8018E118[D_8018E118_SIZE]; s32 gNumD_8018E118Entries; Gfx* D_8018E75C; @@ -1195,7 +1200,7 @@ void func_80091B78(void) { D_800DC5EC->screenWidth = SCREEN_WIDTH; D_800DC5EC->screenHeight = SCREEN_HEIGHT; D_800E86A4 = 1; - func_80094C60(); + render_menus(); for (i = 0; i < 4; i++) { func_800C97C4((u8) i); @@ -1256,7 +1261,7 @@ void func_80091EE4(void) { tmp = func_800B5F30(); if ((D_8018EDFB != 0) && (tmp == 0)) { - temp_s2 = (gCupSelection * 4) + gCourseIndexInCup; + temp_s2 = (GetCupIndex() * 4) + GetCupCursorPosition(); func_800B6708(); for (temp_s0 = 0; temp_s0 < 2; ++temp_s0) { @@ -1290,19 +1295,19 @@ void func_80091FA4(void) { func_8009A344(); func_8009E620(); func_80092258(); - add_8018D9E0_entry(0x00000096, 0x00000064, 0x00000024, 1); - add_8018D9E0_entry(0x00000097, 0x00000064, 0x000000DD, 1); - add_8018D9E0_entry(0x00000098, 0, 0, 0); - add_8018D9E0_entry(0x000000C7, 0, 0, 0); + add_ui_element(0x00000096, 0x00000064, 0x00000024, 1); + add_ui_element(0x00000097, 0x00000064, 0x000000DD, 1); + add_ui_element(0x00000098, 0, 0, 0); + add_ui_element(0x000000C7, 0, 0, 0); if (gModeSelection == TIME_TRIALS) { - add_8018D9E0_entry(0x000000BE, 0, 0, 0); - add_8018D9E0_entry(0x0000010E, 0, 0, 0); + add_ui_element(0x000000BE, 0, 0, 0); + add_ui_element(0x0000010E, 0, 0, 0); } if ((D_8015F890 != 0) && (gModeSelection == TIME_TRIALS)) { - add_8018D9E0_entry(0x000000BD, 0, 0, 0); + add_ui_element(0x000000BD, 0, 0, 0); } if (!(gControllerBits & 1) && (D_8018EE08 != 0)) { - add_8018D9E0_entry(4, 0, 0, 2); + add_ui_element(4, 0, 0, 2); } func_800B5F30(); } @@ -1413,22 +1418,22 @@ void func_80092500(void) { switch (gModeSelection) { case GRAND_PRIX: - add_8018D9E0_entry(0xAA, 0, 0, 0); + add_ui_element(0xAA, 0, 0, 0); break; case TIME_TRIALS: - add_8018D9E0_entry(0xB9, 0, 0, 0); + add_ui_element(0xB9, 0, 0, 0); break; } } void func_80092564(void) { - add_8018D9E0_entry(0xAC, 0, 0, 0); + add_ui_element(0xAC, 0, 0, 0); func_8005D18C(); func_8001968C(); } void func_800925A0(void) { - add_8018D9E0_entry(0xAF, 0, 0, 0); + add_ui_element(0xAF, 0, 0, 0); } void func_800925CC(void) { @@ -1439,122 +1444,122 @@ void func_800925CC(void) { } void func_80092604(void) { - add_8018D9E0_entry(0xB0, 0, 0, 0); + add_ui_element(0xB0, 0, 0, 0); } void func_80092630(void) { - add_8018D9E0_entry(0xBC, 0, 0, 0); + add_ui_element(0xBC, 0, 0, 0); } void func_8009265C(void) { - add_8018D9E0_entry(0x12B, 0, 0, 2); + add_ui_element(0x12B, 0, 0, 2); } void func_80092688(void) { switch (D_800DC5E4) { case 0: - add_8018D9E0_entry(0x1CE, 0, 0, 2); + add_ui_element(0x1CE, 0, 0, 2); return; default: - add_8018D9E0_entry(0x190, 0, 0, 2); - add_8018D9E0_entry(0x191, 0, 0, 2); + add_ui_element(0x190, 0, 0, 2); + add_ui_element(0x191, 0, 0, 2); return; case 2: - add_8018D9E0_entry(0x192, 0, 0, 2); - add_8018D9E0_entry(0x193, 0, 0, 2); + add_ui_element(0x192, 0, 0, 2); + add_ui_element(0x193, 0, 0, 2); return; case 3: - add_8018D9E0_entry(0x194, 0, 0, 2); - add_8018D9E0_entry(0x195, 0, 0, 2); + add_ui_element(0x194, 0, 0, 2); + add_ui_element(0x195, 0, 0, 2); return; case 4: - add_8018D9E0_entry(0x196, 0, 0, 2); - add_8018D9E0_entry(0x197, 0, 0, 2); + add_ui_element(0x196, 0, 0, 2); + add_ui_element(0x197, 0, 0, 2); return; case 5: - add_8018D9E0_entry(0x198, 0, 0, 2); - add_8018D9E0_entry(0x199, 0, 0, 2); - add_8018D9E0_entry(0x19A, 0, 0, 2); - add_8018D9E0_entry(0x19B, 0, 0, 2); + add_ui_element(0x198, 0, 0, 2); + add_ui_element(0x199, 0, 0, 2); + add_ui_element(0x19A, 0, 0, 2); + add_ui_element(0x19B, 0, 0, 2); return; case 6: - add_8018D9E0_entry(0x198, 0, 0, 2); - add_8018D9E0_entry(0x19C, 0, 0, 2); - add_8018D9E0_entry(0x19D, 0, 0, 2); - add_8018D9E0_entry(0x19E, 0, 0, 2); + add_ui_element(0x198, 0, 0, 2); + add_ui_element(0x19C, 0, 0, 2); + add_ui_element(0x19D, 0, 0, 2); + add_ui_element(0x19E, 0, 0, 2); return; case 7: - add_8018D9E0_entry(0x19F, 0, 0, 2); - add_8018D9E0_entry(0x1A0, 0, 0, 2); - add_8018D9E0_entry(0x1A1, 0, 0, 2); - add_8018D9E0_entry(0x1A2, 0, 0, 2); + add_ui_element(0x19F, 0, 0, 2); + add_ui_element(0x1A0, 0, 0, 2); + add_ui_element(0x1A1, 0, 0, 2); + add_ui_element(0x1A2, 0, 0, 2); return; case 8: - add_8018D9E0_entry(0x1A3, 0, 0, 2); - add_8018D9E0_entry(0x1A4, 0, 0, 2); + add_ui_element(0x1A3, 0, 0, 2); + add_ui_element(0x1A4, 0, 0, 2); return; case 9: - add_8018D9E0_entry(0x1A5, 0, 0, 2); - add_8018D9E0_entry(0x1A6, 0, 0, 2); - add_8018D9E0_entry(0x1A7, 0, 0, 2); - add_8018D9E0_entry(0x1A8, 0, 0, 2); - add_8018D9E0_entry(0x1A9, 0, 0, 2); + add_ui_element(0x1A5, 0, 0, 2); + add_ui_element(0x1A6, 0, 0, 2); + add_ui_element(0x1A7, 0, 0, 2); + add_ui_element(0x1A8, 0, 0, 2); + add_ui_element(0x1A9, 0, 0, 2); return; case 10: - add_8018D9E0_entry(0x1A5, 0, 0, 2); - add_8018D9E0_entry(0x1A6, 0, 0, 2); - add_8018D9E0_entry(0x1AA, 0, 0, 2); - add_8018D9E0_entry(0x1AB, 0, 0, 2); - add_8018D9E0_entry(0x1AC, 0, 0, 2); + add_ui_element(0x1A5, 0, 0, 2); + add_ui_element(0x1A6, 0, 0, 2); + add_ui_element(0x1AA, 0, 0, 2); + add_ui_element(0x1AB, 0, 0, 2); + add_ui_element(0x1AC, 0, 0, 2); return; case 11: - add_8018D9E0_entry(0x1AD, 0, 0, 2); - add_8018D9E0_entry(0x1AE, 0, 0, 2); - add_8018D9E0_entry(0x1AF, 0, 0, 2); - add_8018D9E0_entry(0x1B0, 0, 0, 2); + add_ui_element(0x1AD, 0, 0, 2); + add_ui_element(0x1AE, 0, 0, 2); + add_ui_element(0x1AF, 0, 0, 2); + add_ui_element(0x1B0, 0, 0, 2); return; case 12: - add_8018D9E0_entry(0x1B1, 0, 0, 2); - add_8018D9E0_entry(0x1B2, 0, 0, 2); + add_ui_element(0x1B1, 0, 0, 2); + add_ui_element(0x1B2, 0, 0, 2); return; case 13: - add_8018D9E0_entry(0x1B3, 0, 0, 2); - add_8018D9E0_entry(0x1B4, 0, 0, 2); - add_8018D9E0_entry(0x1B5, 0, 0, 2); + add_ui_element(0x1B3, 0, 0, 2); + add_ui_element(0x1B4, 0, 0, 2); + add_ui_element(0x1B5, 0, 0, 2); return; case 14: - add_8018D9E0_entry(0x1B6, 0, 0, 2); - add_8018D9E0_entry(0x1B7, 0, 0, 2); - add_8018D9E0_entry(0x1B8, 0, 0, 2); - add_8018D9E0_entry(0x1B9, 0, 0, 2); - add_8018D9E0_entry(0x1BA, 0, 0, 2); - add_8018D9E0_entry(0x1BB, 0, 0, 2); - add_8018D9E0_entry(0x1BC, 0, 0, 2); + add_ui_element(0x1B6, 0, 0, 2); + add_ui_element(0x1B7, 0, 0, 2); + add_ui_element(0x1B8, 0, 0, 2); + add_ui_element(0x1B9, 0, 0, 2); + add_ui_element(0x1BA, 0, 0, 2); + add_ui_element(0x1BB, 0, 0, 2); + add_ui_element(0x1BC, 0, 0, 2); return; case 15: - add_8018D9E0_entry(0x1BD, 0, 0, 2); - add_8018D9E0_entry(0x1BE, 0, 0, 2); - add_8018D9E0_entry(0x1BF, 0, 0, 2); - add_8018D9E0_entry(0x1C0, 0, 0, 2); + add_ui_element(0x1BD, 0, 0, 2); + add_ui_element(0x1BE, 0, 0, 2); + add_ui_element(0x1BF, 0, 0, 2); + add_ui_element(0x1C0, 0, 0, 2); return; case 16: - add_8018D9E0_entry(0x1C1, 0, 0, 2); - add_8018D9E0_entry(0x1C2, 0, 0, 2); - add_8018D9E0_entry(0x1C3, 0, 0, 2); + add_ui_element(0x1C1, 0, 0, 2); + add_ui_element(0x1C2, 0, 0, 2); + add_ui_element(0x1C3, 0, 0, 2); return; case 17: - add_8018D9E0_entry(0x1C4, 0, 0, 2); - add_8018D9E0_entry(0x1C5, 0, 0, 2); - add_8018D9E0_entry(0x1C6, 0, 0, 2); - add_8018D9E0_entry(0x1C7, 0, 0, 2); - add_8018D9E0_entry(0x1C8, 0, 0, 2); - add_8018D9E0_entry(0x1C9, 0, 0, 2); - add_8018D9E0_entry(0x1CA, 0, 0, 2); - add_8018D9E0_entry(0x1CB, 0, 0, 2); - add_8018D9E0_entry(0x1CC, 0, 0, 2); + add_ui_element(0x1C4, 0, 0, 2); + add_ui_element(0x1C5, 0, 0, 2); + add_ui_element(0x1C6, 0, 0, 2); + add_ui_element(0x1C7, 0, 0, 2); + add_ui_element(0x1C8, 0, 0, 2); + add_ui_element(0x1C9, 0, 0, 2); + add_ui_element(0x1CA, 0, 0, 2); + add_ui_element(0x1CB, 0, 0, 2); + add_ui_element(0x1CC, 0, 0, 2); return; case 18: - add_8018D9E0_entry(0x1CD, 0, 0, 2); + add_ui_element(0x1CD, 0, 0, 2); return; } } @@ -1817,7 +1822,7 @@ void print_text0(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 do { glyphIndex = char_to_glyph_index(text); if (glyphIndex >= 0) { - func_80099184((MkTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex])); + load_menu_img((MkTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex])); gDisplayListHead = print_letter(gDisplayListHead, (MkTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex]), @@ -1896,7 +1901,7 @@ void print_text1(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 while (*text != 0) { glyphIndex = char_to_glyph_index(text); if (glyphIndex >= 0) { - func_80099184(segmented_to_virtual_dupe(gGlyphTextureLUT[glyphIndex])); + load_menu_img(segmented_to_virtual_dupe(gGlyphTextureLUT[glyphIndex])); gDisplayListHead = print_letter(gDisplayListHead, segmented_to_virtual_dupe(gGlyphTextureLUT[glyphIndex]), column, row, sp60, scaleX, scaleY); column = column + (s32) ((gGlyphDisplayWidth[glyphIndex] + tracking) * scaleX); @@ -1942,7 +1947,7 @@ void print_text2(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 glyphIndex = char_to_glyph_index(text); if (glyphIndex >= 0) { glyphTexture = (MkTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex]); - func_80099184(glyphTexture); + load_menu_img(glyphTexture); gDisplayListHead = print_letter(gDisplayListHead, glyphTexture, column - (gGlyphDisplayWidth[glyphIndex] / 2), row, arg6, scaleX, scaleY); @@ -2194,7 +2199,7 @@ void func_80094660(struct GfxPool* arg0, UNUSED s32 arg1) { gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); } -void func_800947B4(struct GfxPool* arg0, UNUSED s32 arg1) { +void render_checkered_flag(struct GfxPool* arg0, UNUSED s32 arg1) { u16 perspNorm; move_segment_table_to_dmem(); guPerspective(&arg0->mtxPersp[0], &perspNorm, 45.0f, 1.3333334f, 100.0f, 12800.0f, 1.0f); @@ -2225,7 +2230,7 @@ void func_80094A64(struct GfxPool* pool) { guOrtho(&pool->mtxScreen, 0.0f, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 0.0f, -100.0f, 100.0f, 1.0f); gSPMatrix(gDisplayListHead++, &pool->mtxScreen, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPDisplayList(gDisplayListHead++, D_02007650); - func_80094C60(); + render_menus(); func_80092290(4, D_8018E850, D_8018E858); func_80092290(5, (s32*) &D_8018E850[1], (s32*) &D_8018E858[1]); func_80099A70(); @@ -2241,7 +2246,7 @@ void func_80094A64(struct GfxPool* pool) { case LOGO_INTRO_MENU: case CONTROLLER_PAK_MENU: case MAIN_MENU: - case PLAYER_SELECT_MENU: + case CHARACTER_SELECT_MENU: case COURSE_SELECT_MENU: func_800A8230(); func_80099AEC(); @@ -2253,7 +2258,7 @@ void func_80094A64(struct GfxPool* pool) { gSPDisplayList(gDisplayListHead++, D_020076B0); } -void func_80094C60(void) { +void render_menus(void) { if (D_800E86A4 != 0) { func_80099110(); func_8009A344(); @@ -2265,133 +2270,133 @@ void func_80094C60(void) { func_800B3F74(gMenuSelection); switch (gMenuSelection) { case OPTIONS_MENU: - add_8018D9E0_entry(0x00000023, 0, 0, 2); - add_8018D9E0_entry(0x000000F1, 0, 0, 4); - add_8018D9E0_entry(0x000000F0, 0, 0, 2); + add_ui_element(0x00000023, 0, 0, 2); + add_ui_element(0x000000F1, 0, 0, 4); + add_ui_element(0x000000F0, 0, 0, 2); break; case DATA_MENU: - add_8018D9E0_entry(0x00000023, 0, 0, 2); - add_8018D9E0_entry(0x0000008C, 0, 0, 6); - add_8018D9E0_entry(0x0000007C, 0, 0, 6); - add_8018D9E0_entry(0x0000007D, 0, 0, 6); - add_8018D9E0_entry(0x0000007E, 0, 0, 6); - add_8018D9E0_entry(0x0000007F, 0, 0, 6); - add_8018D9E0_entry(0x00000080, 0, 0, 6); - add_8018D9E0_entry(0x00000081, 0, 0, 6); - add_8018D9E0_entry(0x00000082, 0, 0, 6); - add_8018D9E0_entry(0x00000083, 0, 0, 6); - add_8018D9E0_entry(0x00000084, 0, 0, 6); - add_8018D9E0_entry(0x00000085, 0, 0, 6); - add_8018D9E0_entry(0x00000086, 0, 0, 6); - add_8018D9E0_entry(0x00000087, 0, 0, 6); - add_8018D9E0_entry(0x00000088, 0, 0, 6); - add_8018D9E0_entry(0x00000089, 0, 0, 6); - add_8018D9E0_entry(0x0000008A, 0, 0, 6); - add_8018D9E0_entry(0x0000008B, 0, 0, 6); - add_8018D9E0_entry(0x0000008D, 0, 0, 8); + add_ui_element(0x00000023, 0, 0, 2); + add_ui_element(0x0000008C, 0, 0, 6); + add_ui_element(0x0000007C, 0, 0, 6); + add_ui_element(0x0000007D, 0, 0, 6); + add_ui_element(0x0000007E, 0, 0, 6); + add_ui_element(0x0000007F, 0, 0, 6); + add_ui_element(0x00000080, 0, 0, 6); + add_ui_element(0x00000081, 0, 0, 6); + add_ui_element(0x00000082, 0, 0, 6); + add_ui_element(0x00000083, 0, 0, 6); + add_ui_element(0x00000084, 0, 0, 6); + add_ui_element(0x00000085, 0, 0, 6); + add_ui_element(0x00000086, 0, 0, 6); + add_ui_element(0x00000087, 0, 0, 6); + add_ui_element(0x00000088, 0, 0, 6); + add_ui_element(0x00000089, 0, 0, 6); + add_ui_element(0x0000008A, 0, 0, 6); + add_ui_element(0x0000008B, 0, 0, 6); + add_ui_element(0x0000008D, 0, 0, 8); break; case COURSE_DATA_MENU: - add_8018D9E0_entry(0x000000E6, 0, 0, 8); - add_8018D9E0_entry(0x000000E7, 0, 0, 8); - add_8018D9E0_entry(0x000000E8, 0, 0, 8); - add_8018D9E0_entry(0x000000E9, 0, 0, 8); - add_8018D9E0_entry(0x000000EA, 0, 0, 8); + add_ui_element(0x000000E6, 0, 0, 8); + add_ui_element(0x000000E7, 0, 0, 8); + add_ui_element(0x000000E8, 0, 0, 8); + add_ui_element(0x000000E9, 0, 0, 8); + add_ui_element(0x000000EA, 0, 0, 8); break; case LOGO_INTRO_MENU: - add_8018D9E0_entry(0x000000FA, 0, 0, 0); + add_ui_element(0x000000FA, 0, 0, 0); break; case CONTROLLER_PAK_MENU: - add_8018D9E0_entry(0x000000DA, 0, 0, 0); - add_8018D9E0_entry(0x000000D2, 0, 0, 4); - add_8018D9E0_entry(0x000000D4, 0, 0, 6); - add_8018D9E0_entry(0x000000D3, 0, 0, 8); - add_8018D9E0_entry(0x000000D5, 0, 0, 0x0A); - add_8018D9E0_entry(0x000000D6, 0, 0, 0x0A); - add_8018D9E0_entry(0x000000D7, 0, 0, 0x0A); - add_8018D9E0_entry(0x000000D8, 0, 0, 0x0A); - add_8018D9E0_entry(0x000000D9, 0, 0, 0x0A); + add_ui_element(0x000000DA, 0, 0, 0); + add_ui_element(0x000000D2, 0, 0, 4); + add_ui_element(0x000000D4, 0, 0, 6); + add_ui_element(0x000000D3, 0, 0, 8); + add_ui_element(0x000000D5, 0, 0, 0x0A); + add_ui_element(0x000000D6, 0, 0, 0x0A); + add_ui_element(0x000000D7, 0, 0, 0x0A); + add_ui_element(0x000000D8, 0, 0, 0x0A); + add_ui_element(0x000000D9, 0, 0, 0x0A); break; case START_MENU: - add_8018D9E0_entry(2, 0, 0, 4); - add_8018D9E0_entry(1, 0, 0, 0); - add_8018D9E0_entry(0x000000FB, 0, 0, 0); + add_ui_element(2, 0, 0, 4); + add_ui_element(1, 0, 0, 0); + add_ui_element(0x000000FB, 0, 0, 0); if (gControllerBits & 1) { - add_8018D9E0_entry(3, 0, 0, 2); + add_ui_element(3, 0, 0, 2); } else { - add_8018D9E0_entry(4, 0, 0, 2); + add_ui_element(4, 0, 0, 2); } - add_8018D9E0_entry(5, 0, 0, 6); + add_ui_element(5, 0, 0, 6); gDemoMode = 0; D_8018EE08 = 0; break; case MAIN_MENU: - add_8018D9E0_entry(0x00000023, 0, 0, 2); - add_8018D9E0_entry(0x0000000A, 0x0000015E, 0x00000011, 6); - add_8018D9E0_entry(0x0000000E, 0x0000015E, 0x0000003E, 6); - add_8018D9E0_entry(0x0000000D, 0x0000015E, 0x0000003E, 6); - add_8018D9E0_entry(0x0000000C, 0x0000015E, 0x0000003E, 6); - add_8018D9E0_entry(0x0000000B, 0x0000015E, 0x0000003E, 6); - add_8018D9E0_entry(0x0000000F, 0x0000015E, 0x000000C8, 6); - add_8018D9E0_entry(0x00000011, 0x0000015E, 0x000000C8, 6); - add_8018D9E0_entry(0x00000010, 0x0000015E, 0x000000C8, 6); - if (func_800B555C() != 0) { - add_8018D9E0_entry(0x00000015, 0, 0, 6); + add_ui_element(0x00000023, 0, 0, 2); + add_ui_element(0x0000000A, 0x0000015E, 0x00000011, 6); + add_ui_element(0x0000000E, 0x0000015E, 0x0000003E, 6); + add_ui_element(0x0000000D, 0x0000015E, 0x0000003E, 6); + add_ui_element(0x0000000C, 0x0000015E, 0x0000003E, 6); + add_ui_element(0x0000000B, 0x0000015E, 0x0000003E, 6); + add_ui_element(0x0000000F, 0x0000015E, 0x000000C8, 6); + add_ui_element(0x00000011, 0x0000015E, 0x000000C8, 6); + add_ui_element(0x00000010, 0x0000015E, 0x000000C8, 6); + if (has_unlocked_extra_mode() != 0) { + add_ui_element(0x00000015, 0, 0, 6); } - add_8018D9E0_entry(0x00000014, 0, 0, 6); - add_8018D9E0_entry(0x00000013, 0, 0, 6); - add_8018D9E0_entry(0x00000012, 0, 0, 6); - add_8018D9E0_entry(0x00000019, 0, 0, 6); - add_8018D9E0_entry(0x00000018, 0, 0, 6); - add_8018D9E0_entry(0x0000001B, 0, 0, 0x0C); + add_ui_element(0x00000014, 0, 0, 6); + add_ui_element(0x00000013, 0, 0, 6); + add_ui_element(0x00000012, 0, 0, 6); + add_ui_element(0x00000019, 0, 0, 6); + add_ui_element(0x00000018, 0, 0, 6); + add_ui_element(0x0000001B, 0, 0, 0x0C); break; - case PLAYER_SELECT_MENU: - add_8018D9E0_entry(0x00000024, 0, 0, 2); - add_8018D9E0_entry(0x0000002A, 0, 0, 6); - add_8018D9E0_entry(0x00000033, 0, 0, 6); - add_8018D9E0_entry(0x0000002B, 0, 0, 8); - add_8018D9E0_entry(0x0000002C, 0, 0, 8); - add_8018D9E0_entry(0x0000002D, 0, 0, 6); - add_8018D9E0_entry(0x0000002E, 0, 0, 6); - add_8018D9E0_entry(0x0000002F, 0, 0, 6); - add_8018D9E0_entry(0x00000030, 0, 0, 6); - add_8018D9E0_entry(0x00000031, 0, 0, 6); - add_8018D9E0_entry(0x00000032, 0, 0, 8); - add_8018D9E0_entry(0x00000034, 0, 0, 0x0C); - add_8018D9E0_entry(0x00000035, 0, 0, 0x0C); - add_8018D9E0_entry(0x00000036, 0, 0, 0x0C); - add_8018D9E0_entry(0x00000037, 0, 0, 0x0C); + case CHARACTER_SELECT_MENU: + add_ui_element(0x00000024, 0, 0, 2); + add_ui_element(0x0000002A, 0, 0, 6); + add_ui_element(0x00000033, 0, 0, 6); + add_ui_element(0x0000002B, 0, 0, 8); + add_ui_element(0x0000002C, 0, 0, 8); + add_ui_element(0x0000002D, 0, 0, 6); + add_ui_element(0x0000002E, 0, 0, 6); + add_ui_element(0x0000002F, 0, 0, 6); + add_ui_element(0x00000030, 0, 0, 6); + add_ui_element(0x00000031, 0, 0, 6); + add_ui_element(0x00000032, 0, 0, 8); + add_ui_element(0x00000034, 0, 0, 0x0C); + add_ui_element(0x00000035, 0, 0, 0x0C); + add_ui_element(0x00000036, 0, 0, 0x0C); + add_ui_element(0x00000037, 0, 0, 0x0C); break; case COURSE_SELECT_MENU: - add_8018D9E0_entry(0x00000025, 0, 0, 2); - add_8018D9E0_entry(0x00000052, 0, 0, 6); + add_ui_element(0x00000025, 0, 0, 2); + add_ui_element(0x00000052, 0, 0, 6); if (gModeSelection != BATTLE) { - add_8018D9E0_entry(0x00000053, 0, 0, 4); - add_8018D9E0_entry(0x00000054, 0, 0, 4); - add_8018D9E0_entry(0x00000055, 0, 0, 4); - add_8018D9E0_entry(0x00000056, 0, 0, 4); - add_8018D9E0_entry(0x00000058, 0, 0, 6); - add_8018D9E0_entry(0x00000059, 0, 0, 6); - add_8018D9E0_entry(0x0000005A, 0, 0, 6); - add_8018D9E0_entry(0x0000005B, 0, 0, 6); + add_ui_element(0x00000053, 0, 0, 4); + add_ui_element(0x00000054, 0, 0, 4); + add_ui_element(0x00000055, 0, 0, 4); + add_ui_element(0x00000056, 0, 0, 4); + add_ui_element(0x00000058, 0, 0, 6); + add_ui_element(0x00000059, 0, 0, 6); + add_ui_element(0x0000005A, 0, 0, 6); + add_ui_element(0x0000005B, 0, 0, 6); } else { - add_8018D9E0_entry(0x0000005C, 0, 0, 6); - add_8018D9E0_entry(0x0000006E, 0, 0, 6); + add_ui_element(0x0000005C, 0, 0, 6); + add_ui_element(0x0000006E, 0, 0, 6); } - add_8018D9E0_entry(0x00000064, 0, 0, 6); - add_8018D9E0_entry(0x0000005F, 0, 0, 6); - add_8018D9E0_entry(0x00000060, 0, 0, 6); - add_8018D9E0_entry(0x00000061, 0, 0, 6); - add_8018D9E0_entry(0x00000062, 0, 0, 6); - add_8018D9E0_entry(0x0000005D, 0, 0, 6); - add_8018D9E0_entry(0x0000005E, 0, 0, 8); + add_ui_element(0x00000064, 0, 0, 6); + add_ui_element(0x0000005F, 0, 0, 6); + add_ui_element(0x00000060, 0, 0, 6); + add_ui_element(0x00000061, 0, 0, 6); + add_ui_element(0x00000062, 0, 0, 6); + add_ui_element(0x0000005D, 0, 0, 6); + add_ui_element(0x0000005E, 0, 0, 8); if (gModeSelection == TIME_TRIALS) { - add_8018D9E0_entry(0x00000065, 0, 0, 8); - add_8018D9E0_entry(0x00000066, 0, 0, 8); - add_8018D9E0_entry(0x00000069, 0, 0, 8); + add_ui_element(0x00000065, 0, 0, 8); + add_ui_element(0x00000066, 0, 0, 8); + add_ui_element(0x00000069, 0, 0, 8); } if (gModeSelection == GRAND_PRIX) { - add_8018D9E0_entry(0x00000068, 0, 0, 8); - add_8018D9E0_entry(0x00000067, 0, 0, 5); + add_ui_element(0x00000068, 0, 0, 8); + add_ui_element(0x00000067, 0, 0, 5); } break; case 0: @@ -2411,6 +2416,8 @@ void func_80094C60(void) { } } +CProperties* GetCoursePropsA(void); + void func_80095574(void) { s32 var_v0; @@ -2448,13 +2455,14 @@ void func_80095574(void) { if ((gCurrentCourseId >= (NUM_COURSES - 1)) || (gCurrentCourseId < 0)) { gCurrentCourseId = 0; } - print_str_num(0x00000050, 0x0000006E, "map_number", gCurrentCourseId); - if (gCurrentCourseId < 0xA) { + print_str_num(0x00000050, 0x0000006E, "map_number", GetCourseIndex()); + // This isn't functionally equivallent, but who cares. + if (gCurrentCourseId < COURSE_TOADS_TURNPIKE) { var_v0 = 0; } else { var_v0 = 8; } - debug_print_str2(var_v0 + 0xB9, 0x0000006E, gDebugCourseNames[gCurrentCourseId]); + debug_print_str2(var_v0 + 0xB9, 0x0000006E, GetCoursePropsA()->DebugName); debug_print_str2(0x00000050, 0x00000078, "screen_mode"); debug_print_str2(0x000000AA, 0x00000078, gDebugScreenModeNames[D_8018EDF1]); debug_print_str2(0x00000050, 0x00000082, "player"); @@ -3369,7 +3377,7 @@ void dma_copy_base_7fa3c0(u64* arg0, size_t nbytes, void* vaddr) { } void func_80099110(void) { - gD_8018E118TotalSize = 0; + gMenuTextureBufferIndex = 0; gNumD_8018E118Entries = 0; } @@ -3406,7 +3414,7 @@ void* segmented_to_virtual_dupe_2(const void* addr) { #ifdef NON_MATCHING // https://decomp.me/scratch/NAZ12 // Register allocation nonsense -void func_80099184(MkTexture* arg0) { +void load_menu_img(MkTexture* arg0) { u16 var_a1_2; s32 var_v0; s32 var_a1; @@ -3432,34 +3440,34 @@ void func_80099184(MkTexture* arg0) { if (var_a1_2 % 8) { var_a1_2 = ((var_a1_2 / 8) * 8) + 8; } -// mio0decode(D_8018D9B4, &D_8018D9B0[gD_8018E118TotalSize]); +// mio0decode(D_8018D9B4, &D_8018D9B0[gMenuTextureBufferIndex]); // size_t texSize = ResourceGetTexSizeByName(var_s1->textureData); -// memcpy(&D_8018D9B0[gD_8018E118TotalSize], var_s1->textureData, texSize); +// memcpy(&D_8018D9B0[gMenuTextureBufferIndex], var_s1->textureData, texSize); #ifdef TARGET_N64 dma_copy_base_729a30(var_s1->textureData, var_a1_2, D_8018D9B4); - mio0decode(D_8018D9B4, (u8*) &D_8018D9B0[gD_8018E118TotalSize]); + mio0decode(D_8018D9B4, (u8*) &D_8018D9B0[gMenuTextureBufferIndex]); #else - strcpy(&D_8018D9B0[gD_8018E118TotalSize], var_s1->textureData); + strcpy(&D_8018D9B0[gMenuTextureBufferIndex], var_s1->textureData); #endif } else { #ifdef TARGET_N64 dma_copy_base_729a30(var_s1->textureData, var_s1->height * var_s1->width * 2, - &D_8018D9B0[gD_8018E118TotalSize]); + &D_8018D9B0[gMenuTextureBufferIndex]); #else - strcpy(&D_8018D9B0[gD_8018E118TotalSize], var_s1->textureData); + strcpy(&D_8018D9B0[gMenuTextureBufferIndex], var_s1->textureData); #endif } thing[gNumD_8018E118Entries].textureData = var_s1->textureData; - thing[gNumD_8018E118Entries].offset = gD_8018E118TotalSize; - gD_8018E118TotalSize += var_s1->height * var_s1->width; - gD_8018E118TotalSize = ((gD_8018E118TotalSize / 8) * 8) + 8; + thing[gNumD_8018E118Entries].offset = gMenuTextureBufferIndex; + gMenuTextureBufferIndex += var_s1->height * var_s1->width; + gMenuTextureBufferIndex = ((gMenuTextureBufferIndex / 8) * 8) + 8; gNumD_8018E118Entries += 1; } var_s1++; } } #else -GLOBAL_ASM("asm/non_matchings/code_80091750/func_80099184.s") +GLOBAL_ASM("asm/non_matchings/code_80091750/load_menu_img.s") #endif #ifdef NON_MATCHING @@ -3487,21 +3495,21 @@ void func_80099394(MkTexture* arg0) { if (var_s1->type == 5) { #ifdef TARGET_N64 dma_copy_base_729a30(var_s1->textureData, (u32) ((s32) (var_s1->height * var_s1->width) / 2), - &D_8018D9B0[gD_8018E118TotalSize]); + &D_8018D9B0[gMenuTextureBufferIndex]); #else u8* tex = LOAD_ASSET(var_s1->textureData); size_t texSize = ResourceGetTexSizeByName(var_s1->textureData); - memcpy(&D_8018D9B0[gD_8018E118TotalSize], tex, texSize); + memcpy(&D_8018D9B0[gMenuTextureBufferIndex], tex, texSize); #endif } thing = &D_8018E118[gNumD_8018E118Entries]; thing->textureData = var_s1->textureData; thing = &D_8018E118[gNumD_8018E118Entries]; - thing->offset = gD_8018E118TotalSize; + thing->offset = gMenuTextureBufferIndex; - gD_8018E118TotalSize += (var_s1->height * var_s1->width); - gD_8018E118TotalSize = ((gD_8018E118TotalSize / 8) * 8) + 8; + gMenuTextureBufferIndex += (var_s1->height * var_s1->width); + gMenuTextureBufferIndex = ((gMenuTextureBufferIndex / 8) * 8) + 8; gNumD_8018E118Entries += 1; } var_s1++; @@ -3535,18 +3543,18 @@ void func_8009952C(MkTexture* arg0) { if (var_a1 == 0) { #ifdef TARGET_N64 dma_copy_base_729a30(var_s1->textureData, 0x00008000U, D_8018D9B4); - mio0decode(D_8018D9B4, (u8*) &D_8018D9B0[gD_8018E118TotalSize]); + mio0decode(D_8018D9B4, (u8*) &D_8018D9B0[gMenuTextureBufferIndex]); #else - memcpy(&D_8018D9B0[gD_8018E118TotalSize], var_s1->textureData, var_s1->width * var_s1->height * 2); + memcpy(&D_8018D9B0[gMenuTextureBufferIndex], var_s1->textureData, var_s1->width * var_s1->height * 2); #endif thing = &D_8018E118[gNumD_8018E118Entries]; thing->textureData = var_s1->textureData; thing = &D_8018E118[gNumD_8018E118Entries]; - thing->offset = gD_8018E118TotalSize; + thing->offset = gMenuTextureBufferIndex; - gD_8018E118TotalSize += (var_s1->height * var_s1->width); - gD_8018E118TotalSize = ((gD_8018E118TotalSize / 8) * 8) + 8; + gMenuTextureBufferIndex += (var_s1->height * var_s1->width); + gMenuTextureBufferIndex = ((gMenuTextureBufferIndex / 8) * 8) + 8; gNumD_8018E118Entries += 1; } var_s1++; @@ -3556,14 +3564,14 @@ void func_8009952C(MkTexture* arg0) { GLOBAL_ASM("asm/non_matchings/code_80091750/func_8009952C.s") #endif -void func_8009969C(MkTexture* arg0) { - func_800996BC(arg0, 1); +void load_img_wrap(MkTexture* arg0) { + load_menu_img2(arg0, 1); } #ifdef NON_MATCHING // Register allocation nonsense // https://decomp.me/scratch/hwAAp -void func_800996BC(MkTexture* arg0, s32 arg1) { +void load_menu_img2(MkTexture* arg0, s32 arg1) { u16 var_a1_2; s32 var_v0; s32 var_a1; @@ -3610,10 +3618,10 @@ void func_800996BC(MkTexture* arg0, s32 arg1) { switch (arg1) { /* switch 1; irregular */ case -1: /* switch 1 */ case 1: { - // mio0decode(D_8018D9B4, (u8*)&D_8018D9B0[gD_8018E118TotalSize]); + // mio0decode(D_8018D9B4, (u8*)&D_8018D9B0[gMenuTextureBufferIndex]); // printf("w: %d, h: %d", texture->width, texture->height); u8* tex = (u8*) LOAD_ASSET(texture->textureData); - memcpy(&D_8018D9B0[gD_8018E118TotalSize], tex, texture->width * texture->height * 2); + memcpy(&D_8018D9B0[gMenuTextureBufferIndex], tex, texture->width * texture->height * 2); break; } case 0: /* switch 1 */ @@ -3624,24 +3632,24 @@ void func_800996BC(MkTexture* arg0, s32 arg1) { var_v0_2 = 1; } if (1) {} - // D_8018D9B0[gD_8018E118TotalSize] = &gTextureBackgroundBlueSky; - // tkmk00decode(D_8018D9B4, texture->textureData, (u8*)&D_8018D9B0[gD_8018E118TotalSize], var_v0_2); + // D_8018D9B0[gMenuTextureBufferIndex] = &gTextureBackgroundBlueSky; + // tkmk00decode(D_8018D9B4, texture->textureData, (u8*)&D_8018D9B0[gMenuTextureBufferIndex], var_v0_2); u8* tex2 = (u8*) LOAD_ASSET(texture->textureData); - memcpy(&D_8018D9B0[gD_8018E118TotalSize], tex2, texture->width * texture->height * 2); + memcpy(&D_8018D9B0[gMenuTextureBufferIndex], tex2, texture->width * texture->height * 2); break; } thing[gNumD_8018E118Entries].textureData = texture->textureData; - thing[gNumD_8018E118Entries].offset = gD_8018E118TotalSize; - gD_8018E118TotalSize += texture->height * texture->width; - gD_8018E118TotalSize = ((gD_8018E118TotalSize / 8) * 8) + 8; + thing[gNumD_8018E118Entries].offset = gMenuTextureBufferIndex; + gMenuTextureBufferIndex += texture->height * texture->width; + gMenuTextureBufferIndex = ((gMenuTextureBufferIndex / 8) * 8) + 8; gNumD_8018E118Entries += 1; } texture++; } } #else -GLOBAL_ASM("asm/non_matchings/code_80091750/func_800996BC.s") +GLOBAL_ASM("asm/non_matchings/code_80091750/load_menu_img2.s") #endif void func_80099958(MkTexture* arg0, s32 arg1, s32 arg2) { @@ -3954,7 +3962,7 @@ void func_8009A2F0(struct_8018E0E8_entry* arg0) { if (var_a0 == NULL) { break; } - func_800996BC(var_a0, 0); + load_menu_img2(var_a0, 0); if (1) {} temp_v0++; var_a0 = temp_v0->mk64Texture; @@ -3968,7 +3976,7 @@ void func_8009A344(void) { } } -s32 func_8009A374(MkAnimation* anim) { +s32 animate_character_select_menu(MkAnimation* anim) { s32 i; struct_8018DEE0_entry* entry; @@ -3992,12 +4000,12 @@ s32 func_8009A374(MkAnimation* anim) { entry->D_8018E118_index = gNumD_8018E118Entries; if (anim[0].mk64Texture) { - func_8009969C(anim[0].mk64Texture); + load_img_wrap(anim[0].mk64Texture); } if (anim[1].mk64Texture) { - func_8009969C(anim[1].mk64Texture); + load_img_wrap(anim[1].mk64Texture); } else { - func_8009969C(anim[0].mk64Texture); + load_img_wrap(anim[0].mk64Texture); } entry->unk14 = 0; @@ -4253,7 +4261,7 @@ void func_8009AD78(s32 arg0, s32 arg1) { gSPInvalidateTexCache(gDisplayListHead++, D_8018E118[arg0].offset); } -void func_8009B0A4(s32 arg0, u32 arg1) { +void convert_img_to_greyscale(s32 arg0, u32 arg1) { u32 var_s0; s32 red; s32 green; @@ -4287,7 +4295,7 @@ void func_8009B0A4(s32 arg0, u32 arg1) { gSPInvalidateTexCache(gDisplayListHead++, D_8018E118[arg0].offset); } -void func_8009B538(s32 arg0, s32 screen_size, s32 arg2, s32 arg3, s32 arg4) { +void adjust_img_colour(s32 arg0, s32 screen_size, s32 arg2, s32 arg3, s32 arg4) { s32 red; s32 green; s32 blue; @@ -4790,7 +4798,7 @@ void func_8009CE64(s32 arg0) { goto func_8009CE64_label2; } func_8009CE64_label2: - if ((D_802874D8.unk1D < 3) && (gCupSelection == 3)) { + if ((D_802874D8.unk1D < 3) && (GetCupIndex() == SPECIAL_CUP)) { var_a1 = 1; } func_8009CE64_label1: @@ -4934,6 +4942,7 @@ void func_8009CE64(s32 arg0) { gCCSelection = (s32) 1; switch (gNextDemoId) { /* switch 4 */ case 0: /* switch 4 */ + SetCourseByClass(GetMarioRaceway()); gCurrentCourseId = 0; gScreenModeSelection = 0; gPlayerCountSelection1 = 1; @@ -4942,6 +4951,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 1: /* switch 4 */ + SetCourseByClass(GetLuigiRaceway()); gCurrentCourseId = (s16) 1; gScreenModeSelection = (s32) 1; gPlayerCountSelection1 = 2; @@ -4951,7 +4961,8 @@ void func_8009CE64(s32 arg0) { gModeSelection = 2; break; case 2: /* switch 4 */ - gCurrentCourseId = 0x000B; + SetCourseByClass(GetKalimariDesert()); + gCurrentCourseId = COURSE_KALAMARI_DESERT; gScreenModeSelection = 0; gPlayerCountSelection1 = (s32) 1; gPlayerCount = 1; @@ -4959,6 +4970,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 3: /* switch 4 */ + SetCourseByClass(GetWarioStadium()); gCurrentCourseId = 0x000E; gScreenModeSelection = 3; gPlayerCountSelection1 = 3; @@ -4969,6 +4981,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = (s32) 2; break; case 4: /* switch 4 */ + SetCourseByClass(GetBowsersCastle()); gCurrentCourseId = 2; gScreenModeSelection = 0; gPlayerCountSelection1 = (s32) 1; @@ -4977,6 +4990,7 @@ void func_8009CE64(s32 arg0) { gModeSelection = 0; break; case 5: /* switch 4 */ + SetCourseByClass(GetSherbetLand()); gCurrentCourseId = 0x000C; gScreenModeSelection = 3; gPlayerCountSelection1 = 4; @@ -4994,9 +5008,13 @@ void func_8009CE64(s32 arg0) { if (gNextDemoId >= 6) { gNextDemoId = 0; } - gCupSelection = gCupSelectionByCourseId[gCurrentCourseId]; - D_800DC540 = (s32) gCupSelection; - gCourseIndexInCup = (s8) gPerCupIndexByCourseId[gCurrentCourseId]; + printf("\nSELECTED!!!!!\n"); + //SetCupIndex(gCurrentCourseId); // World->GetCourse + gCupSelection = GetCupIndex(); //gCupSelectionByCourseId[gCurrentCourseId]; + D_800DC540 = (s32) GetCupIndex(); + gCourseIndexInCup = GetCupCursorPosition(); + //gCupCourseSelection = (s8) gPerCupIndexByCourseId[gCurrentCourseId]; + //SetCupCursorPosition(); // break; case 3: /* switch 3 */ switch (gMenuSelection) { @@ -5056,29 +5074,31 @@ void func_8009CE64(s32 arg0) { break; } } - switch (gCurrentCourseId) { - case COURSE_BLOCK_FORT: - case COURSE_SKYSCRAPER: - case COURSE_DOUBLE_DECK: - case COURSE_BIG_DONUT: - gModeSelection = 3; - if (gPlayerCountSelection1 == 1) { - gPlayerCount = 2; - gScreenModeSelection = 1; - gPlayerCountSelection1 = gPlayerCount; - } - break; - default: - if (gModeSelection == 3) { - gModeSelection = 0; - } - if ((gModeSelection == 2) && (gPlayerCountSelection1 == 1)) { - gModeSelection = 0; - } + + if (GetCourse() == GetBlockFort() || + GetCourse() == GetSkyscraper() || + GetCourse() == GetDoubleDeck() || + GetCourse() == GetBigDonut()) { + + gModeSelection = BATTLE; + if (gPlayerCountSelection1 == 1) { + gPlayerCount = 2; + gScreenModeSelection = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; + gPlayerCountSelection1 = gPlayerCount; + } + } else { + if (gModeSelection == 3) { + gModeSelection = 0; + } + if ((gModeSelection == 2) && (gPlayerCountSelection1 == 1)) { + gModeSelection = 0; + } } + gCupSelection = gCupSelectionByCourseId[gCurrentCourseId]; - D_800DC540 = gCupSelection; + D_800DC540 = GetCupIndex(); gCourseIndexInCup = gPerCupIndexByCourseId[gCurrentCourseId]; + switch (gDebugGotoScene) { /* switch 6; irregular */ case 1: /* switch 6 */ break; @@ -5468,7 +5488,7 @@ void func_8009E620(void) { #ifdef NON_MATCHING // https://decomp.me/scratch/1BHpa // Stack differences, can't figure out how to fix them -void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { +void add_ui_element(s32 type, s32 column, s32 row, s8 priority) { struct_8018D9E0_entry* var_ra; s32 stackPadding0; UNUSED s32 stackPadding1; @@ -5486,13 +5506,14 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { // ???????? // Credit to Vetri for the idea to mess around with this loop // to fix the issue near the 0xD4 case - while (1) { + while (true) { var_v0++; if (var_ra->type == 0) break; - if (var_v0 > 0x20) { - while (1) {} + if (var_v0 > D_8018D9E0_SIZE) { + printf("Ran out of buffer space for UI elements"); + while (true) {} } var_ra++; } @@ -5534,27 +5555,27 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { var_ra->unk20 = one; break; case 0xD2: - func_800996BC(D_020014C8, 0); + load_menu_img2(D_020014C8, 0); func_8009B954(D_020014C8); D_8018E75C = func_8009BA74(D_8018E75C, D_020014C8, var_ra->column, var_ra->row); func_8009B998(); break; case 0xD3: - func_800996BC(D_02001540, 0); + load_menu_img2(D_02001540, 0); func_8009B954(D_02001540); D_8018E75C = func_8009BA74(D_8018E75C, D_02001540, var_ra->column, var_ra->row); func_8009B998(); break; case 0xD4: - func_800996BC(D_0200157C, 0); - func_80099184(D_02001874); + load_menu_img2(D_0200157C, 0); + load_menu_img(D_02001874); var_ra->row = 0x00000069; for (var_v0 = 0; var_v0 < 133; var_v0++) { - func_80099184(segmented_to_virtual_dupe(D_800E7AF8[var_v0])); + load_menu_img(segmented_to_virtual_dupe(D_800E7AF8[var_v0])); } break; case 0xD5: - func_80099184(D_020015A4); + load_menu_img(D_020015A4); func_8009B954(D_020015A4); D_8018E75C = func_8009BA74(D_8018E75C, D_020015A4, var_ra->column, var_ra->row); gDPLoadTextureBlock(D_8018E75C++, func_8009B8C4(gTexture7ED50C), G_IM_FMT_IA, G_IM_SIZ_16b, 256, 5, 0, @@ -5562,49 +5583,49 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(D_8018E75C++, 0x80, 0x2C0, 0x480, 0x2D4, G_TX_RENDERTILE, 0, 0x80, 0x0400, 0xFC00); func_8009B998(); - func_80099184(D_020015CC); + load_menu_img(D_020015CC); func_8009B954(D_020015CC); D_8018E75C = func_8009BA74(D_8018E75C, D_020015CC, var_ra->column, var_ra->row); func_8009B998(); - func_80099184(D_02001630); + load_menu_img(D_02001630); func_8009B954(D_02001630); D_8018E75C = func_8009BA74(D_8018E75C, D_02001630, var_ra->column, var_ra->row); func_8009B998(); - func_80099184(D_02001658); + load_menu_img(D_02001658); func_8009B954(D_02001658); D_8018E75C = func_8009BA74(D_8018E75C, D_02001658, var_ra->column, var_ra->row); func_8009B998(); break; case 0xD6: - var_ra->D_8018DEE0_index = func_8009A374(segmented_to_virtual_dupe_2(D_800E7D34[0])); + var_ra->D_8018DEE0_index = animate_character_select_menu(segmented_to_virtual_dupe_2(D_800E7D34[0])); break; case 0xD7: for (var_v0 = 0; var_v0 < 10; var_v0++) { - func_80099184(segmented_to_virtual_dupe(D_800E7D0C[var_v0])); + load_menu_img(segmented_to_virtual_dupe(D_800E7D0C[var_v0])); } break; case 0xD8: case 0xD9: - func_80099184(D_0200184C); + load_menu_img(D_0200184C); break; case 0x1: - func_800996BC(D_800E7D4C[func_800B555C()], 0); + load_menu_img2(D_800E7D4C[has_unlocked_extra_mode()], 0); break; case 0x2: - func_8006EE44(); - gD_8018E118TotalSize += 0x10000; - func_80099184(D_020045E8); + load_mario_kart_64_logo(); + gMenuTextureBufferIndex += 0x10000; + load_menu_img(D_020045E8); break; case 0x3: - func_80099184(D_02004610); + load_menu_img(D_02004610); break; case 0x23: case 0x24: case 0x25: - func_800996BC(D_800E7D4C[func_800B555C()], 0); - func_800996BC(D_02004B74, 0); - func_8009B0A4(0, 0x00000019); - func_8009B538(0, SCREEN_WIDTH * SCREEN_HEIGHT, D_800E74E8[type - 0x23].red, D_800E74E8[type - 0x23].green, + load_menu_img2(D_800E7D4C[has_unlocked_extra_mode()], 0); + load_menu_img2(D_02004B74, 0); + convert_img_to_greyscale(0, 0x00000019); + adjust_img_colour(0, SCREEN_WIDTH * SCREEN_HEIGHT, D_800E74E8[type - 0x23].red, D_800E74E8[type - 0x23].green, D_800E74E8[type - 0x23].blue); break; case 0xF: @@ -5621,27 +5642,27 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { case 0x17: case 0x18: case 0x19: - func_800996BC(segmented_to_virtual_dupe(D_800E8274[type - 0x12]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E8274[type - 0x12]), 0); break; case 0xB: case 0xC: case 0xD: case 0xE: - func_800996BC(segmented_to_virtual_dupe(D_800E8234[((type - 0xB) * 2) + 0]), 0); - func_80099184(segmented_to_virtual_dupe(D_800E8234[((type - 0xB) * 2) + 1])); + load_menu_img2(segmented_to_virtual_dupe(D_800E8234[((type - 0xB) * 2) + 0]), 0); + load_menu_img(segmented_to_virtual_dupe(D_800E8234[((type - 0xB) * 2) + 1])); break; case 0x2A: - func_800996BC(D_02004B4C, 0); + load_menu_img2(D_02004B4C, 0); break; case 0x33: - func_800996BC(D_02004B74, 0); + load_menu_img2(D_02004B74, 0); var_ra->unk1C = 0x00000020; break; case 0x34: case 0x35: case 0x36: case 0x37: - func_80099184(segmented_to_virtual_dupe(D_800E82B4[type - 0x34])); + load_menu_img(segmented_to_virtual_dupe(D_800E82B4[type - 0x34])); break; case 0x2B: case 0x2C: @@ -5651,12 +5672,12 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { case 0x30: case 0x31: case 0x32: - var_ra->D_8018DEE0_index = func_8009A374(segmented_to_virtual_dupe_2(D_800E8320[type - 0x2B])); - func_800996BC(segmented_to_virtual_dupe(D_800E7D54[type - 0x2B]), 0); + var_ra->D_8018DEE0_index = animate_character_select_menu(segmented_to_virtual_dupe_2(D_800E8320[type - 0x2B])); + load_menu_img2(segmented_to_virtual_dupe(D_800E7D54[type - 0x2B]), 0); break; case 0xA0: case 0xA1: - var_ra->D_8018DEE0_index = func_8009A374(segmented_to_virtual_dupe_2(D_800E8320[type - 0xA0])); + var_ra->D_8018DEE0_index = animate_character_select_menu(segmented_to_virtual_dupe_2(D_800E8320[type - 0xA0])); break; case 0x5D: var_ra->unk1C = 0x00000020; @@ -5671,14 +5692,14 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { case 0x5A: case 0x5B: case 0x5C: - func_800996BC(segmented_to_virtual_dupe(D_800E82C4[type - 0x52]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E82C4[type - 0x52]), 0); break; case 0x5F: case 0x60: case 0x61: case 0x62: var_ra->D_8018DEE0_index = - func_8009A374(segmented_to_virtual_dupe_2(D_800E7E34[gCupCourseOrder[0][var_ra->type - 0x5F]])); + animate_character_select_menu(segmented_to_virtual_dupe_2(D_800E7E34[gCupCourseOrder[0][var_ra->type - 0x5F]])); break; case 0x5E: var_ra->unk20 = random_int(4U) + 2; @@ -5689,20 +5710,20 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { var_ra->row = D_800E7248[type - 0x65].row; break; case 0x67: - var_ra->unk1C = (s32) gCupSelection; - var_ra->unk20 = func_800B54C0(gCupSelection, gCCSelection); + var_ra->unk1C = (s32) GetCupIndex(); + var_ra->unk20 = func_800B54C0(GetCupIndex(), gCCSelection); var_ra->D_8018DEE0_index = - func_8009A374(segmented_to_virtual_dupe_2(D_800E7E20[((gCCSelection / 2) * 4) - var_ra->unk20])); + animate_character_select_menu(segmented_to_virtual_dupe_2(D_800E7E20[((gCCSelection / 2) * 4) - var_ra->unk20])); var_ra->column = D_800E7268[0].column; var_ra->row = D_800E7268[0].row; break; case 0x68: - func_800996BC(segmented_to_virtual_dupe(D_800E8294[gCCSelection]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E8294[gCCSelection]), 0); var_ra->column = 0x00000037; var_ra->row = 0x000000C3; break; case 0x69: - func_800996BC(segmented_to_virtual_dupe(D_02004A0C), 0); + load_menu_img2(segmented_to_virtual_dupe(D_02004A0C), 0); if (controller_pak_1_status() == 0) { func_800B6708(); } else { @@ -5714,10 +5735,10 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { case 0x79: case 0x7A: case 0x7B: - func_800996BC(segmented_to_virtual_dupe(D_800E82F4[type - 0x78]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E82F4[type - 0x78]), 0); break; case 0x8C: - func_800996BC(segmented_to_virtual_dupe(D_02004A34), 0); + load_menu_img2(segmented_to_virtual_dupe(D_02004A34), 0); if (controller_pak_1_status() == 0) { func_800B6708(); } else { @@ -5726,7 +5747,7 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { } break; case 0x8D: - func_80099184(segmented_to_virtual_dupe(D_02001FA4)); + load_menu_img(segmented_to_virtual_dupe(D_02001FA4)); break; case 0x7C: case 0x7D: @@ -5745,10 +5766,10 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { case 0x8A: case 0x8B: temp_v0_6 = var_ra->type - 0x7C; - func_800996BC(segmented_to_virtual_dupe(D_800E7D74[gCupCourseOrder[temp_v0_6 / 4][temp_v0_6 % 4]]), -1); + load_menu_img2(segmented_to_virtual_dupe(D_800E7D74[gCupCourseOrder[temp_v0_6 / 4][temp_v0_6 % 4]]), -1); temp_v0_6 = var_ra->type - 0x7C; - func_800996BC(segmented_to_virtual_dupe(D_800E7DC4[gCupCourseOrder[temp_v0_6 / 4][temp_v0_6 % 4]]), 0); - func_800996BC(segmented_to_virtual_dupe(D_02004A0C), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E7DC4[gCupCourseOrder[temp_v0_6 / 4][temp_v0_6 % 4]]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_02004A0C), 0); break; case 0xB1: case 0xB2: @@ -5777,8 +5798,8 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { var_a0 = D_800E8320[temp_a1]; } var_ra->D_8018DEE0_index = func_8009A478(segmented_to_virtual_dupe_2(var_a0), stackPadding0); - func_800996BC(segmented_to_virtual_dupe(D_800E7D54[temp_a1]), 0); - func_80099184(segmented_to_virtual_dupe(D_800E82B4[type - 0xB1])); + load_menu_img2(segmented_to_virtual_dupe(D_800E7D54[temp_a1]), 0); + load_menu_img(segmented_to_virtual_dupe(D_800E82B4[type - 0xB1])); break; case 0xBB: var_ra->unk1C = func_800B5020(playerHUD[0].someTimer, gCharacterSelections[0]); @@ -5789,14 +5810,14 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { } } if ((var_ra->unk1C == 0) || (var_ra->unk20 != 0)) { - func_800B559C((gCupSelection * 4) + gCourseIndexInCup); + func_800B559C((GetCupIndex() * 4) + GetCupCursorPosition()); } break; case 0xE6: - var_ra->D_8018DEE0_index = func_8009A374(segmented_to_virtual_dupe_2( + var_ra->D_8018DEE0_index = animate_character_select_menu(segmented_to_virtual_dupe_2( D_800E7E34[gCupCourseOrder[gTimeTrialDataCourseIndex / 4][gTimeTrialDataCourseIndex % 4]])); var_ra->unk1C = gTimeTrialDataCourseIndex; - func_800996BC(segmented_to_virtual_dupe(D_02004A0C), 0); + load_menu_img2(segmented_to_virtual_dupe(D_02004A0C), 0); func_8006EF60(); if (controller_pak_1_status() == 0) { func_800B6708(); @@ -5809,7 +5830,7 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { var_ra->cursor = (s32) gSoundMode; break; case 0xF1: - func_800996BC(segmented_to_virtual_dupe(D_02004638), 0); + load_menu_img2(segmented_to_virtual_dupe(D_02004638), 0); break; case 0xBE: D_8018ED90 = 0; @@ -5827,7 +5848,7 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { var_a0 = D_800E8320[temp_a1]; } var_ra->D_8018DEE0_index = func_8009A478(segmented_to_virtual_dupe_2(var_a0), 0); - func_800996BC(segmented_to_virtual_dupe(D_800E7D54[temp_a1]), 0); + load_menu_img2(segmented_to_virtual_dupe(D_800E7D54[temp_a1]), 0); break; case 0x190: case 0x191: @@ -5897,7 +5918,7 @@ void add_8018D9E0_entry(s32 type, s32 column, s32 row, s8 priority) { } } #else -GLOBAL_ASM("asm/non_matchings/code_80091750/add_8018D9E0_entry.s") +GLOBAL_ASM("asm/non_matchings/code_80091750/add_ui_element.s") #endif #ifdef NON_MATCHING @@ -5933,7 +5954,7 @@ void func_8009F5E0(struct_8018D9E0_entry* arg0) { func_80094660(gGfxPool, arg0->unk1C); break; case 0xFB: /* switch 6 */ - func_800947B4(gGfxPool, arg0->unk1C); + render_checkered_flag(gGfxPool, arg0->unk1C); break; case 0xD2: /* switch 6 */ gDisplayListHead = func_8009B9D0(gDisplayListHead, D_020014C8); @@ -5971,7 +5992,7 @@ void func_8009F5E0(struct_8018D9E0_entry* arg0) { break; case 0x1: /* switch 6 */ gDisplayListHead = - func_8009BA74(gDisplayListHead, D_800E7D4C[func_800B555C()], arg0->column, arg0->row); + func_8009BA74(gDisplayListHead, D_800E7D4C[has_unlocked_extra_mode()], arg0->column, arg0->row); break; case 0x2: /* switch 6 */ func_8004C8D4((arg0->column + 0xA0), (arg0->row + 0x47)); @@ -6025,7 +6046,7 @@ void func_8009F5E0(struct_8018D9E0_entry* arg0) { case 0x24: /* switch 6 */ case 0x25: /* switch 6 */ gDisplayListHead = - func_8009BC9C(gDisplayListHead, D_800E7D4C[func_800B555C()], arg0->column, arg0->row, 3, 0); + func_8009BC9C(gDisplayListHead, D_800E7D4C[has_unlocked_extra_mode()], arg0->column, arg0->row, 3, 0); break; case 0xA: /* switch 6 */ gDisplayListHead = func_8009BA74(gDisplayListHead, D_02004660, arg0->column, arg0->row); @@ -6277,7 +6298,7 @@ void func_8009F5E0(struct_8018D9E0_entry* arg0) { break; case 0x97: /* switch 6 */ set_text_color(5); - func_80093324(arg0->column, arg0->row, gCourseNames[gCurrentCourseId], arg0->unk1C, arg0->unk24, 1.0f); + func_80093324(arg0->column, arg0->row, CourseManager_GetProps()->Name, arg0->unk1C, arg0->unk24, 1.0f); break; case 0x98: /* switch 6 */ func_800A2D1C(arg0); @@ -7210,7 +7231,7 @@ void func_800A2EB8(struct_8018D9E0_entry* arg0) { func_80093324(arg0->column + 0x1E, arg0->row + 0x19, "results", 0, 1.0f, 1.0f); set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); func_80093324(arg0->column + 0x2C, arg0->row + 0x28, "round", 0, 0.7f, 0.7f); - convert_number_to_ascii(gCourseIndexInCup + 1, sp68); + convert_number_to_ascii(GetCupCursorPosition() + 1, sp68); func_80093324(arg0->column + 0x57, arg0->row + 0x28, &sp68[1], 0, 0.7f, 0.7f); for (var_s2 = 0; var_s2 < 4; var_s2++) { if (gGPCurrentRacePlayerIdByRank[var_s2] < gPlayerCount) { @@ -7231,7 +7252,7 @@ void func_800A2EB8(struct_8018D9E0_entry* arg0) { func_800A32B4(0xBE - arg0->column, arg0->row + (0x10 * var_s2) + 0x5A, sp70[var_s2], var_s2); } set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); - temp_s0 = (s32) (((f32) (get_string_width(gCupNames[gCupSelection]) + 8) * 0.6f) / 2); + temp_s0 = (s32) (((f32) (get_string_width(GetCupName()) + 8) * 0.6f) / 2);// gCupNames[GetCupIndex()]) + 8) * 0.6f) / 2); draw_text((-(s32) (((f32) (get_string_width(D_800E76CC[gCCSelection]) + 8) * 0.6f) / 2) - arg0->column) + 0xF5, arg0->row + 0xE1, gCupNames[D_800DC540], 0, 0.6f, 0.6f); draw_text((temp_s0 - arg0->column) + 0xF5, arg0->row + 0xE1, @@ -7289,7 +7310,7 @@ void func_800A34A8(struct_8018D9E0_entry* arg0) { func_80093324(arg0->column + 0x19, 0x19 - arg0->row, "driver's points", 0, 0.8f, 0.8f); set_text_color(5); func_80093324(arg0->column + 0x36, 0x28 - arg0->row, "round", 0, 0.7f, 0.7f); - convert_number_to_ascii(gCourseIndexInCup + 1, sp78); + convert_number_to_ascii(GetCupCursorPosition() + 1, sp78); func_80093324(arg0->column + 0x61, (0x28 & 0xFFFFFFFF) - arg0->row, &sp78[1], 0, 0.7f, 0.7f); for (rank = 0; rank < 4; rank++) { test = arg0->cursor; @@ -7347,7 +7368,7 @@ void func_800A34A8(struct_8018D9E0_entry* arg0) { } } set_text_color(5); - temp_s0_3 = ((get_string_width(gCupNames[gCupSelection]) + 8) * 0.6f) / 2; + temp_s0_3 = ((get_string_width(gCupNames[GetCupIndex()]) + 8) * 0.6f) / 2; draw_text((-(s32) (((get_string_width(D_800E76CC[gCCSelection]) + 8) * 0.6f) / 2) - arg0->column) + 0xE6, arg0->row + 0xE1, gCupNames[D_800DC540], 0, 0.6f, 0.6f); draw_text((temp_s0_3 - arg0->column) + 0xE6, arg0->row + 0xE1, @@ -7422,8 +7443,8 @@ void func_800A3C84(struct_8018D9E0_entry* arg0) { s32 rowOffset; set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_1); - draw_text(arg0->column + 0x43, arg0->row + 0x19, gCourseNamesDup[gCupCourseOrder[gCupSelection][gCourseIndexInCup]], - 0, 0.6f, 0.6f); + draw_text(arg0->column + 0x43, arg0->row + 0x19, CourseManager_GetProps()->Name + , 0, 0.6f, 0.6f); set_text_color(TEXT_YELLOW); draw_text(arg0->column + 0x46, arg0->row + 0x28, D_800E7730, 0, 0.75f, 0.75f); for (recordType = 0, rowOffset = 0; recordType < TIME_TRIAL_3LAP_RECORD_5; recordType += 1, rowOffset += 0xF) { @@ -7462,8 +7483,8 @@ void func_800A3E60(struct_8018D9E0_entry* arg0) { } set_text_color(4); - draw_text(arg0->column + 0x55, 0x19 - arg0->row, gCourseNamesDup[gCupCourseOrder[gCupSelection][gCourseIndexInCup]], - 0, 0.6f, 0.6f); + draw_text(arg0->column + 0x55, 0x19 - arg0->row, + gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 0.6f, 0.6f); set_text_color(3); draw_text(arg0->column + 0x55, 0x28 - arg0->row, D_800E7730, 0, 0.75f, 0.75f); for (var_s1 = 0; var_s1 < 4; var_s1++) { @@ -7760,7 +7781,7 @@ void render_pause_menu_time_trials(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, 0x0000008C); set_text_color(TEXT_YELLOW); - draw_text(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[gCupSelection][gCourseIndexInCup]], 0, 1.0f, + draw_text(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 1.0f, 1.0f); set_text_color(TEXT_RED); draw_text(0x0000009D, 0x00000060, D_800E7728[0], 0, 0.8f, 0.8f); @@ -7841,14 +7862,14 @@ void render_pause_grand_prix(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_box(gDisplayListHead, temp_v1 - temp_t3, temp_t0 - temp_t4, temp_v1 + temp_t3, temp_t0 + temp_t4, 0, 0, 0, 140); temp_s3 = &D_800E85C0[(gScreenModeSelection * 4) + (gIsGamePaused - 1)]; - temp_s0 = ((get_string_width(gCupNames[gCupSelection]) * one) + 10.0f) / 2; + temp_s0 = ((get_string_width(gCupNames[GetCupIndex()]) * one) + 10.0f) / 2; temp_s1 = ((get_string_width(D_800E76CC[gCCSelection]) * one) + 10.0f) / 2; set_text_color(TEXT_YELLOW); - draw_text(160 - temp_s1, temp_s3->row - 50, gCupNames[gCupSelection], 0, 1.0f, 1.0f); + draw_text(160 - temp_s1, temp_s3->row - 50, gCupNames[GetCupIndex()], 0, 1.0f, 1.0f); set_text_color(TEXT_YELLOW); draw_text(160 + temp_s0, temp_s3->row - 50, D_800E76CC[gCCSelection], 0, 1.0f, 1.0f); set_text_color(TEXT_YELLOW); - draw_text(160, temp_s3->row - 30, gCourseNamesDup[gCupCourseOrder[gCupSelection][gCourseIndexInCup]], 0, 1.0f, + draw_text(160, temp_s3->row - 30, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 1.0f, 1.0f); for (var_s0 = 0; var_s0 < 2; var_s0++) { text_rainbow_effect(arg0->cursor - 31, var_s0, TEXT_YELLOW); @@ -7963,7 +7984,7 @@ void func_800A5738(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, var_s1); gDPSetPrimColor(gDisplayListHead++, 0, 0, 0x00, 0x00, 0x00, var_s2); set_text_color(3); - func_80093754(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[gCupSelection][gCourseIndexInCup]], 0, + func_80093754(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 1.0f, 1.0f); switch (arg0->cursor) { /* switch 1 */ case 1: /* switch 1 */ @@ -8099,7 +8120,7 @@ void func_800A6034(struct_8018D9E0_entry* arg0) { text = gCupNames[D_800DC540]; set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); func_80093754(arg0->column + 0x41, arg0->row + 0xA0, text, 0, 0.85f, 1.0f); - text = gCourseNames[gCurrentCourseId]; + text = CourseManager_GetProps()->Name; set_text_color((s32) gCurrentCourseId % 4); func_80093754(arg0->column + 0x41, arg0->row + 0xC3, text, 0, 0.65f, 0.85f); } @@ -8407,11 +8428,11 @@ void func_800A7258(struct_8018D9E0_entry* arg0) { // Podium scene, top line void func_800A72FC(struct_8018D9E0_entry* arg0) { UNUSED s32 pad; - s32 cupNameLength = (((f32) get_string_width(gCupNames[gCupSelection]) * 1) + 10) / 2; + s32 cupNameLength = (((f32) get_string_width(GetCupName()) * 1) + 10) / 2; s32 ccNameLength = (((f32) get_string_width(D_800E76CC[gCCSelection]) * 1) + 10) / 2; set_text_color(TEXT_YELLOW); - draw_text(arg0->column - ccNameLength, arg0->row, gCupNames[gCupSelection], 0, 1, 1); + draw_text(arg0->column - ccNameLength, arg0->row, GetCupName(), 0, 1, 1); set_text_color(TEXT_YELLOW); draw_text(arg0->column + cupNameLength, arg0->row, D_800E76DC[gCCSelection], 0, 1, 1); } @@ -9103,7 +9124,7 @@ void func_800A890C(s32 arg0, struct_8018D9E0_entry* arg1) { gDPPipeSync(gDisplayListHead++); gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gDPSetCombineMode(gDisplayListHead++, G_CC_DECALRGBA, G_CC_DECALRGBA); - if (arg0 == gCupSelection) { + if (arg0 == GetCupIndex()) { if (D_8018EDEC == 1) { gDisplayListHead = draw_flash_select_case_slow(gDisplayListHead, temp_t1 + temp_t7, temp_a2, (temp_t1 - temp_t7) + 64, temp_a2 + 39); @@ -9128,8 +9149,8 @@ void func_800A8A98(struct_8018D9E0_entry* arg0) { gDPPipeSync(gDisplayListHead++); gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gDPSetCombineMode(gDisplayListHead++, G_CC_DECALRGBA, G_CC_DECALRGBA); - for (someIndex = 0; someIndex < NUM_COURSES_PER_CUP; someIndex++) { - if ((someIndex == gCourseIndexInCup) && (D_8018EDEC >= 2) && (gModeSelection != GRAND_PRIX)) { + for (someIndex = 0; someIndex < GetCupSize(); someIndex++) { + if ((someIndex == GetCupCursorPosition()) && (D_8018EDEC >= 2) && (gModeSelection != GRAND_PRIX)) { if ((D_8018EDEC == 2) || (D_8018EDEC == 4)) { gDisplayListHead = draw_flash_select_case_slow( gDisplayListHead, D_800E7208[someIndex][0].column + temp_s2, D_800E7208[someIndex][0].row + temp_s3, @@ -9201,7 +9222,7 @@ void func_800A8F48(UNUSED struct_8018D9E0_entry* arg0) { switch (D_8018EDEC) { /* irregular */ case 1: for (var_s1 = 0; var_s1 < 4; var_s1++) { - if (func_800B639C((gCupSelection * 4) + var_s1) >= 0) { + if (func_800B639C((GetCupIndex() * 4) + var_s1) >= 0) { temp_v0 = &D_800E7168[var_s1]; temp_v1 = temp_v0->column; temp_s0 = temp_v0->row; @@ -9215,7 +9236,7 @@ void func_800A8F48(UNUSED struct_8018D9E0_entry* arg0) { break; case 2: default: - if (func_800B639C((gCupSelection * 4) + gCourseIndexInCup) >= 0) { + if (func_800B639C((GetCupIndex() * 4) + GetCupCursorPosition()) >= 0) { gDisplayListHead = func_80098FC8(gDisplayListHead, 0x00000057, 0x00000070, 0x00000096, 0x00000081); gDisplayListHead = func_8009BA74(gDisplayListHead, D_02004A0C, 0x00000057, 0x00000070); } @@ -10303,14 +10324,14 @@ void func_800AB020(struct_8018D9E0_entry* arg0) { void func_800AB098(struct_8018D9E0_entry* arg0) { switch (arg0->cursor) { case 0: - if ((gCupSelection + 0x53) == arg0->type) { + if ((GetCupIndex() + 0x53) == arg0->type) { arg0->cursor = 2; } else { arg0->cursor = 1; } break; case 4: - if ((gCupSelection + 0x53) == arg0->type) { + if ((GetCupIndex() + 0x53) == arg0->type) { arg0->cursor = 2; arg0->unk1C = 0; break; @@ -10327,7 +10348,7 @@ void func_800AB098(struct_8018D9E0_entry* arg0) { } break; case 3: - if ((gCupSelection + 0x53) == arg0->type) { + if ((GetCupIndex() + 0x53) == arg0->type) { arg0->cursor = 2; } break; @@ -10340,7 +10361,7 @@ void func_800AB098(struct_8018D9E0_entry* arg0) { void func_800AB164(struct_8018D9E0_entry* arg0) { Unk_D_800E70A0* thing = &D_800E7148[arg0->type - 0x53]; - if ((gCupSelection + 0x53) == arg0->type) { + if ((GetCupIndex() + 0x53) == arg0->type) { arg0->priority = 0x0A; } else { arg0->priority = 4; @@ -10371,7 +10392,7 @@ void func_800AB164(struct_8018D9E0_entry* arg0) { void func_800AB260(struct_8018D9E0_entry* arg0) { s32 temp = (arg0->type - 0x58); - if (temp == gCupSelection) { + if (temp == GetCupIndex()) { arg0->visible = 1; } else { arg0->visible = 0; @@ -10379,10 +10400,10 @@ void func_800AB260(struct_8018D9E0_entry* arg0) { } void func_800AB290(struct_8018D9E0_entry* arg0) { - if (arg0->unk1C != gCupSelection) { - arg0->unk1C = gCupSelection; + if (arg0->unk1C != GetCupIndex()) { + arg0->unk1C = GetCupIndex(); func_8009A594(arg0->D_8018DEE0_index, 0, - segmented_to_virtual_dupe_2(D_800E7E34[gCupCourseOrder[gCupSelection][arg0->type - 0x5F]])); + segmented_to_virtual_dupe_2(D_800E7E34[gCupCourseOrder[GetCupIndex()][arg0->type - 0x5F]])); } } @@ -10404,8 +10425,8 @@ void func_800AB314(struct_8018D9E0_entry* arg0) { if (D_8018EDEC != one) { arg0->cursor = 0; arg0->unk20 = 0; - for (var_a1 = 0; var_a1 < 4; var_a1++) { - if (gCourseIndexInCup == var_a1) { + for (var_a1 = 0; var_a1 < GetCupSize(); var_a1++) { + if (GetCupCursorPosition() == var_a1) { sp24[var_a1]->visible = one; if (arg0->unk1C != var_a1) { arg0->unk1C = var_a1; @@ -10425,17 +10446,17 @@ void func_800AB314(struct_8018D9E0_entry* arg0) { case 0: switch (arg0->cursor) { /* irregular */ case 0: - if ((arg0->unk1C / 4) == gCupSelection) { + if ((arg0->unk1C / 4) == GetCupIndex()) { arg0->unk20++; if (arg0->unk20 >= 0x33) { arg0->cursor = one; arg0->unk20 = 0; - var_v0 = gCupSelection * 4; + var_v0 = GetCupIndex() * 4; arg0->unk1C = var_v0 + 1; } } else { arg0->unk20 = 0; - arg0->unk1C = gCupSelection * 4; + arg0->unk1C = GetCupIndex() * 4; } if (D_8018EDEC == 3) { arg0->cursor = 2; @@ -10443,7 +10464,7 @@ void func_800AB314(struct_8018D9E0_entry* arg0) { } break; case 1: - if ((arg0->unk1C / 4) != gCupSelection) { + if ((arg0->unk1C / 4) != GetCupIndex()) { arg0->cursor = 0; arg0->unk20 = 0; arg0->unk1C = 0; @@ -10451,7 +10472,7 @@ void func_800AB314(struct_8018D9E0_entry* arg0) { arg0->unk20++; if (arg0->unk20 >= 0x1F) { arg0->unk20 = 0; - arg0->unk1C = (gCupSelection * 4) + (((arg0->unk1C % 4) + one) % 4); + arg0->unk1C = (GetCupIndex() * 4) + (((arg0->unk1C % 4) + one) % 4); } else { if (D_8018EDEC == 3) { arg0->cursor = 2; @@ -10543,9 +10564,9 @@ void func_800AB904(struct_8018D9E0_entry* arg0) { void func_800AB9B0(struct_8018D9E0_entry* arg0) { Unk_D_800E70A0* temp_v1; - if (arg0->unk1C != gCupSelection) { - arg0->unk1C = gCupSelection; - arg0->unk20 = func_800B54C0((s32) gCupSelection, gCCSelection); + if (arg0->unk1C != GetCupIndex()) { + arg0->unk1C = GetCupIndex(); + arg0->unk20 = func_800B54C0((s32) GetCupIndex(), gCCSelection); func_8009A594(arg0->D_8018DEE0_index, 0, segmented_to_virtual_dupe_2(D_800E7E20[((gCCSelection / 2) * 4) - arg0->unk20])); arg0->column = (s32) D_800E7268->column; @@ -10700,7 +10721,7 @@ void func_800ABF68(struct_8018D9E0_entry* arg0) { case 0: arg0->column = 0x140; arg0->cursor = 1; - arg0->unk20 = 0xA0 - (get_string_width(gCourseNames[gCurrentCourseId]) / 2); + arg0->unk20 = 0xA0 - (get_string_width(CourseManager_GetProps()->Name) / 2); /* fallthrough */ case 1: func_800A9208(arg0, arg0->unk20); @@ -10789,7 +10810,7 @@ void func_800AC324(struct_8018D9E0_entry* arg0) { if (((D_8018D9D8 != 0) || (arg0->unk20 >= 0x5B)) && (D_800DDB24 != 0)) { arg0->cursor = 3; arg0->unk1C = arg0->column; - add_8018D9E0_entry(0xAB, 0, 0, 0); + add_ui_element(0xAB, 0, 0, 0); } break; case 3: @@ -11045,7 +11066,7 @@ void func_800ACC50(struct_8018D9E0_entry* arg0) { arg0->cursor = 1; arg0->unk1C = 0; for (var_s0 = 0; var_s0 < gPlayerCount; var_s0++) { - add_8018D9E0_entry(var_s0 + 0xB1, 0, 0, (s8) (5 - var_s0)); + add_ui_element(var_s0 + 0xB1, 0, 0, (s8) (5 - var_s0)); } } break; @@ -11178,7 +11199,7 @@ void func_800AD1A4(struct_8018D9E0_entry* arg0) { arg0->column = 0x0000014A; arg0->cursor = 1; func_800921B4(); - add_8018D9E0_entry(0x000000BB, 0, 0, 0); + add_ui_element(0x000000BB, 0, 0, 0); break; case 1: func_800A9208(arg0, 0x000000A0); @@ -11198,7 +11219,7 @@ void func_800AD1A4(struct_8018D9E0_entry* arg0) { func_800921B4(); arg0->cursor = 4; arg0->unk1C = arg0->column; - add_8018D9E0_entry(0x000000BA, 0, 0, 0); + add_ui_element(0x000000BA, 0, 0, 0); } break; case 4: @@ -11307,7 +11328,7 @@ void func_800AD2E8(struct_8018D9E0_entry* arg0) { break; case 0: /* switch 4 */ func_800B6708(); - arg0->cursor = func_800B6348((gCupSelection * 4) + gCourseIndexInCup) + 0x11; + arg0->cursor = func_800B6348((GetCupIndex() * 4) + GetCupCursorPosition()) + 0x11; var_v1 = 1; play_sound2(SOUND_MENU_SELECT); break; @@ -11354,7 +11375,7 @@ void func_800AD2E8(struct_8018D9E0_entry* arg0) { if (osPfsFindFile(&gControllerPak1FileHandle, gCompanyCode, gGameCode, (u8*) gGameName, (u8*) gExtCode, &gControllerPak1FileNote) == 0) { func_800B6708(); - arg0->cursor = func_800B6348((gCupSelection * 4) + gCourseIndexInCup) + 0x11; + arg0->cursor = func_800B6348((GetCupIndex() * 4) + GetCupCursorPosition()) + 0x11; play_sound2(SOUND_MENU_SELECT); return; } @@ -11404,7 +11425,7 @@ void func_800AD2E8(struct_8018D9E0_entry* arg0) { case 17: /* switch 1 */ case 18: /* switch 1 */ arg0->unk20 = arg0->cursor - 0x11; - if (func_800B639C((gCupSelection * 4) + gCourseIndexInCup) != arg0->unk20) { + if (func_800B639C((GetCupIndex() * 4) + GetCupCursorPosition()) != arg0->unk20) { if ((gControllerOne->buttonPressed | gControllerOne->stickPressed) & 0x800) { if (arg0->cursor >= 0x12) { arg0->cursor--; @@ -11711,7 +11732,7 @@ void func_800AE218(struct_8018D9E0_entry* arg0) { break; case PFS_NO_ERROR: /* switch 3 */ func_800B6708(); - arg0->cursor = func_800B6348((gCupSelection * 4) + gCourseIndexInCup) + 0x1E; + arg0->cursor = func_800B6348((GetCupIndex() * 4) + GetCupCursorPosition()) + 0x1E; var_v1 = 1; break; case PFS_ERR_NEW_PACK: /* switch 3 */ @@ -11760,7 +11781,7 @@ void func_800AE218(struct_8018D9E0_entry* arg0) { if (osPfsFindFile(&gControllerPak1FileHandle, gCompanyCode, gGameCode, (u8*) gGameName, (u8*) gExtCode, &gControllerPak1FileNote) == 0) { func_800B6708(); - arg0->cursor = func_800B6348((gCupSelection * 4) + gCourseIndexInCup) + 0x1E; + arg0->cursor = func_800B6348((GetCupIndex() * 4) + GetCupCursorPosition()) + 0x1E; play_sound2(SOUND_MENU_SELECT); return; } @@ -11806,7 +11827,7 @@ void func_800AE218(struct_8018D9E0_entry* arg0) { case 30: /* switch 1 */ case 31: /* switch 1 */ arg0->unk20 = (u32) arg0->cursor - 0x1E; - if (func_800B639C((gCupSelection * 4) + gCourseIndexInCup) != arg0->unk20) { + if (func_800B639C((GetCupIndex() * 4) + GetCupCursorPosition()) != arg0->unk20) { if ((gControllerOne->buttonPressed | gControllerOne->stickPressed) & 0x800) { if (arg0->cursor >= 0x1F) { arg0->cursor--; @@ -12035,9 +12056,9 @@ void func_800AF004(struct_8018D9E0_entry* arg0) { if (arg0->unk1C >= 0x65) { arg0->unk1C = 0; arg0->cursor = 1; - gCupSelection %= 4; - gCCSelection %= 4; - add_8018D9E0_entry(0x0000012C, 0, 0, 4); + //gCupSelection %= 4; + //gCCSelection %= 4; + add_ui_element(0x0000012C, 0, 0, 4); } break; case 1: @@ -12048,7 +12069,7 @@ void func_800AF004(struct_8018D9E0_entry* arg0) { if (arg0->unk1C >= 9) { arg0->unk1C = 0; arg0->cursor++; - add_8018D9E0_entry(arg0->cursor + 0x12B, 0, 0, 4); + add_ui_element(arg0->cursor + 0x12B, 0, 0, 4); } break; case 5: diff --git a/src/code_80091750.h b/src/code_80091750.h index 01c4ca8ee..95506c9bb 100644 --- a/src/code_80091750.h +++ b/src/code_80091750.h @@ -148,9 +148,9 @@ void func_80093F10(void); void func_800940EC(s32); void func_800942D0(void); void func_80094660(struct GfxPool*, s32); -void func_800947B4(struct GfxPool*, s32); +void render_checkered_flag(struct GfxPool*, s32); void func_80094A64(struct GfxPool*); -void func_80094C60(void); +void render_menus(void); void func_80095574(void); Gfx* draw_flash_select_case(Gfx*, s32, s32, s32, s32, s32); Gfx* draw_flash_select_case_slow(Gfx*, s32, s32, s32, s32); @@ -174,11 +174,11 @@ Gfx* func_80098FC8(Gfx*, s32, s32, s32, s32); void dma_copy_base_729a30(u64*, size_t, void*); void dma_copy_base_7fa3c0(u64*, size_t, void*); void func_80099110(void); -void func_80099184(MkTexture*); +void load_menu_img(MkTexture*); void* segmented_to_virtual_dupe(const void*); void* segmented_to_virtual_dupe_2(const void*); -void func_8009969C(MkTexture*); -void func_800996BC(MkTexture*, s32); +void load_img_wrap(MkTexture*); +void load_menu_img2(MkTexture*, s32); void func_80099958(MkTexture*, s32, s32); void func_80099E54(void); void func_80099E60(MkTexture*, s32, s32); @@ -189,7 +189,7 @@ void func_80099AEC(void); void func_8009A238(MkTexture*, s32); void func_8009A2F0(struct_8018E0E8_entry*); void func_8009A344(void); -s32 func_8009A374(MkAnimation*); +s32 animate_character_select_menu(MkAnimation*); s32 func_8009A478(MkAnimation*, s32); void func_8009A594(s32, s32, MkAnimation*); void func_8009A640(s32, s32, s32, MkAnimation*); @@ -201,8 +201,8 @@ MkTexture* func_8009A944(struct_8018DEE0_entry*, s32); void func_8009A9FC(s32, s32, u32, s32); void func_8009AB7C(s32); void func_8009AD78(s32, s32); -void func_8009B0A4(s32, u32); -void func_8009B538(s32, s32, s32, s32, s32); +void convert_img_to_greyscale(s32, u32); +void adjust_img_colour(s32, s32, s32, s32, s32); u16* func_8009B8C4(u64*); void func_8009B938(void); void func_8009B954(MkTexture*); @@ -248,7 +248,7 @@ void func_8009E2F0(s32); void func_8009E5BC(void); void func_8009E5FC(s32); void func_8009E620(void); -void add_8018D9E0_entry(s32, s32, s32, s8); +void add_ui_element(s32, s32, s32, s8); void func_8009F5E0(struct_8018D9E0_entry*); void func_800A08D8(u8, s32, s32); s32 func_800A095C(char*, s32, s32, s32); @@ -431,7 +431,7 @@ extern struct_8018D9E0_entry D_8018D9E0[D_8018D9E0_SIZE]; extern struct_8018DEE0_entry D_8018DEE0[D_8018DEE0_SIZE]; extern struct_8018E060_entry D_8018E060[]; extern struct_8018E0E8_entry D_8018E0E8[D_8018E0E8_SIZE]; -extern s32 gD_8018E118TotalSize; +extern s32 gMenuTextureBufferIndex; extern struct_8018E118_entry D_8018E118[D_8018E118_SIZE]; extern s32 gNumD_8018E118Entries; extern Gfx* D_8018E75C; diff --git a/src/data/path_spawn_metadata.c b/src/data/path_spawn_metadata.c index 7bc08dfb8..2157eae02 100644 --- a/src/data/path_spawn_metadata.c +++ b/src/data/path_spawn_metadata.c @@ -70,7 +70,7 @@ BombKartSpawn gBombKartSpawns[][NUM_BOMB_KARTS_MAX] = { #include "assets/course_metadata/gBombKartSpawns.inc.c" }; -struct _struct_gCoursePathSizes_0x10 gCoursePathSizes[] = { +_struct_gCoursePathSizes_0x10 gCoursePathSizes[] = { #include "assets/course_metadata/gCoursePathSizes.inc.c" }; diff --git a/src/data/path_spawn_metadata.h b/src/data/path_spawn_metadata.h index cbddae31f..d1fc5451f 100644 --- a/src/data/path_spawn_metadata.h +++ b/src/data/path_spawn_metadata.h @@ -6,14 +6,14 @@ #include #include "include/bomb_kart.h" -struct _struct_gCoursePathSizes_0x10 { +typedef struct { /* 0x00 */ u16 unk0; /* 0x02 */ u16 unk2; /* 0x04 */ u16 unk4; /* 0x06 */ u16 unk6; /* 0x08 */ u16 unk8; /* 0x0A */ char padA[6]; -}; // size 0x10 +} _struct_gCoursePathSizes_0x10; // size 0x10 extern KartAIBehaviour* gKartAIBehaviourLUT[]; extern TrackWaypoint nullPath; @@ -26,7 +26,7 @@ extern s16 D_800DCAF4[]; extern s16 D_800DCB34[]; extern s16* D_800DCBB4[]; extern BombKartSpawn gBombKartSpawns[][NUM_BOMB_KARTS_MAX]; -extern struct _struct_gCoursePathSizes_0x10 gCoursePathSizes[]; +extern _struct_gCoursePathSizes_0x10 gCoursePathSizes[]; extern s32 D_800DDB20; extern s32 D_800DDB24; diff --git a/src/effects.c b/src/effects.c index 69c24c654..fe0f35bab 100644 --- a/src/effects.c +++ b/src/effects.c @@ -1587,89 +1587,94 @@ void func_8008FEDC(Player* player, UNUSED s8 arg1) { player->kartHopAcceleration = 0.0f; } +void CourseManager_Waypoints(Player*, s8); + void func_8008FF08(Player* player, s8 playerId) { s16 waypoint; - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - waypoint = gNearestWaypointByPlayerId[playerId]; - if ((waypoint >= 0x235) && (waypoint < 0x247)) { - player->nearestWaypointId = 0x214; - } else if ((waypoint >= 0x267) && (waypoint < 0x277)) { - player->nearestWaypointId = 0x25B; - } else { - player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - } - break; - case COURSE_BANSHEE_BOARDWALK: - waypoint = gNearestWaypointByPlayerId[playerId]; - if ((waypoint >= 0x12C) && (waypoint < 0x13C)) { - player->nearestWaypointId = 0x12CU; - } else { - player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - } - break; - case COURSE_YOSHI_VALLEY: - case COURSE_RAINBOW_ROAD: - player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; - break; - case COURSE_FRAPPE_SNOWLAND: - waypoint = gNearestWaypointByPlayerId[playerId]; -#ifdef VERSION_EU - if (((waypoint >= 0xF0) && (waypoint < 0x11E)) || ((gCopyNearestWaypointByPlayerId[playerId] >= 0xF0) && - (gCopyNearestWaypointByPlayerId[playerId] < 0x11E))) -#else - if ((waypoint >= 0xF0) && (waypoint < 0x105)) -#endif - { - player->nearestWaypointId = 0xF0U; - } else { - player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - } - break; - case COURSE_ROYAL_RACEWAY: - waypoint = gNearestWaypointByPlayerId[playerId]; - if ((waypoint >= 0x258) && (waypoint < 0x2A4)) { - player->nearestWaypointId = 0x258U; - } else { - player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - } - break; - case COURSE_DK_JUNGLE: - waypoint = gNearestWaypointByPlayerId[playerId]; - if ((waypoint >= 0xB9) && (waypoint < 0x119)) { - player->nearestWaypointId = 0xB9U; - } else { - player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - } - break; - case COURSE_BLOCK_FORT: - case COURSE_SKYSCRAPER: - case COURSE_DOUBLE_DECK: - case COURSE_BIG_DONUT: - player->nearestWaypointId = 0U; - break; - default: - player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; - if (player->nearestWaypointId < 0) { - player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; - } - break; - } + + CourseManager_Waypoints(player, playerId); + +// switch (gCurrentCourseId) { +// case COURSE_BOWSER_CASTLE: +// waypoint = gNearestWaypointByPlayerId[playerId]; +// if ((waypoint >= 0x235) && (waypoint < 0x247)) { +// player->nearestWaypointId = 0x214; +// } else if ((waypoint >= 0x267) && (waypoint < 0x277)) { +// player->nearestWaypointId = 0x25B; +// } else { +// player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// } +// break; +// case COURSE_BANSHEE_BOARDWALK: +// waypoint = gNearestWaypointByPlayerId[playerId]; +// if ((waypoint >= 0x12C) && (waypoint < 0x13C)) { +// player->nearestWaypointId = 0x12CU; +// } else { +// player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// } +// break; +// case COURSE_YOSHI_VALLEY: +// case COURSE_RAINBOW_ROAD: +// player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; +// break; +// case COURSE_FRAPPE_SNOWLAND: +// waypoint = gNearestWaypointByPlayerId[playerId]; +// #ifdef VERSION_EU +// if (((waypoint >= 0xF0) && (waypoint < 0x11E)) || ((gCopyNearestWaypointByPlayerId[playerId] >= 0xF0) && +// (gCopyNearestWaypointByPlayerId[playerId] < 0x11E))) +// #else +// if ((waypoint >= 0xF0) && (waypoint < 0x105)) +// #endif +// { +// player->nearestWaypointId = 0xF0U; +// } else { +// player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// } +// break; +// case COURSE_ROYAL_RACEWAY: +// waypoint = gNearestWaypointByPlayerId[playerId]; +// if ((waypoint >= 0x258) && (waypoint < 0x2A4)) { +// player->nearestWaypointId = 0x258U; +// } else { +// player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// } +// break; +// case COURSE_DK_JUNGLE: +// waypoint = gNearestWaypointByPlayerId[playerId]; +// if ((waypoint >= 0xB9) && (waypoint < 0x119)) { +// player->nearestWaypointId = 0xB9U; +// } else { +// player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// } +// break; +// case COURSE_BLOCK_FORT: +// case COURSE_SKYSCRAPER: +// case COURSE_DOUBLE_DECK: +// case COURSE_BIG_DONUT: +// player->nearestWaypointId = 0U; +// break; +// default: +// player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; +// if (player->nearestWaypointId < 0) { +// player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; +// } +// break; +// } } void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) { @@ -1692,63 +1697,56 @@ void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) { f32 sp18[4] = { 10.0f, -10.0f, -575.0f, 575.0f }; f32 sp08[4] = { 575.0f, -575.0f, 10.0f, -10.0f }; - switch (gCurrentCourseId) { - case COURSE_YOSHI_VALLEY: - test = player->nearestWaypointId; - temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]][test]; - arg2[0] = temp_v1->posX; - arg2[1] = temp_v1->posY; - arg2[2] = temp_v1->posZ; - temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]] - [(player->nearestWaypointId + 5) % - (gWaypointCountByPathIndex[gCopyPathIndexByPlayerId[playerId]] + 1)]; - arg3[0] = temp_v1->posX; - arg3[1] = temp_v1->posY; - arg3[2] = temp_v1->posZ; - break; - case COURSE_BLOCK_FORT: - arg2[0] = spF8[playerId]; - arg2[1] = 0.0f; - arg2[2] = spE8[playerId]; - arg3[0] = spD8[playerId]; - arg3[1] = 0.0f; - arg3[2] = spC8[playerId]; - break; - case COURSE_SKYSCRAPER: - arg2[0] = spB8[playerId]; - arg2[1] = 480.0f; - arg2[2] = spA8[playerId]; - arg3[0] = sp98[playerId]; - arg3[1] = 480.0f; - arg3[2] = sp88[playerId]; - break; - case COURSE_DOUBLE_DECK: - arg2[0] = sp78[playerId]; - arg2[1] = 0.0f; - arg2[2] = sp68[playerId]; - arg3[0] = sp58[playerId]; - arg3[1] = 0.0f; - arg3[2] = sp48[playerId]; - break; - case COURSE_BIG_DONUT: - arg2[0] = sp38[playerId]; - arg2[1] = 200.0f; - arg2[2] = sp28[playerId]; - arg3[0] = sp18[playerId]; - arg3[1] = 200.0f; - arg3[2] = sp08[playerId]; - break; - default: - test = player->nearestWaypointId; - temp_v1 = &D_80164550[0][test]; - arg2[0] = temp_v1->posX; - arg2[1] = temp_v1->posY; - arg2[2] = temp_v1->posZ; - temp_v1 = &D_80164550[0][(player->nearestWaypointId + 5) % (gWaypointCountByPathIndex[0] + 1)]; - arg3[0] = temp_v1->posX; - arg3[1] = temp_v1->posY; - arg3[2] = temp_v1->posZ; - break; + if (GetCourse() == GetYoshiValley()) { + test = player->nearestWaypointId; + temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]][test]; + arg2[0] = temp_v1->posX; + arg2[1] = temp_v1->posY; + arg2[2] = temp_v1->posZ; + temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]] + [(player->nearestWaypointId + 5) % + (gWaypointCountByPathIndex[gCopyPathIndexByPlayerId[playerId]] + 1)]; + arg3[0] = temp_v1->posX; + arg3[1] = temp_v1->posY; + arg3[2] = temp_v1->posZ; + } else if (GetCourse() == GetBlockFort()) { + arg2[0] = spF8[playerId]; + arg2[1] = 0.0f; + arg2[2] = spE8[playerId]; + arg3[0] = spD8[playerId]; + arg3[1] = 0.0f; + arg3[2] = spC8[playerId]; + } else if (GetCourse() == GetSkyscraper()) { + arg2[0] = spB8[playerId]; + arg2[1] = 480.0f; + arg2[2] = spA8[playerId]; + arg3[0] = sp98[playerId]; + arg3[1] = 480.0f; + arg3[2] = sp88[playerId]; + } else if (GetCourse() == GetDoubleDeck()) { + arg2[0] = sp78[playerId]; + arg2[1] = 0.0f; + arg2[2] = sp68[playerId]; + arg3[0] = sp58[playerId]; + arg3[1] = 0.0f; + arg3[2] = sp48[playerId]; + } else if (GetCourse() == GetBigDonut()) { + arg2[0] = sp38[playerId]; + arg2[1] = 200.0f; + arg2[2] = sp28[playerId]; + arg3[0] = sp18[playerId]; + arg3[1] = 200.0f; + arg3[2] = sp08[playerId]; + } else { + test = player->nearestWaypointId; + temp_v1 = &D_80164550[0][test]; + arg2[0] = temp_v1->posX; + arg2[1] = temp_v1->posY; + arg2[2] = temp_v1->posZ; + temp_v1 = &D_80164550[0][(player->nearestWaypointId + 5) % (gWaypointCountByPathIndex[0] + 1)]; + arg3[0] = temp_v1->posX; + arg3[1] = temp_v1->posY; + arg3[2] = temp_v1->posZ; } } @@ -1800,14 +1798,14 @@ void func_80090868(Player* player) { player->unk_0CA |= 2; player->unk_0C8 = 0; if ((player->unk_0DE & 1) == 1) { - if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { + if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { player->unk_0CA |= 0x1000; } else { player->unk_0CA |= 0x2000; } - if ((gCurrentCourseId == COURSE_SHERBET_LAND) || (gCurrentCourseId == COURSE_SKYSCRAPER) || - (gCurrentCourseId == COURSE_RAINBOW_ROAD)) { + if ((GetCourse() == GetSherbetLand()) || (GetCourse() == GetSkyscraper()) || + (GetCourse() == GetRainbowRoad())) { player->unk_0CA &= ~0x3000; } } diff --git a/src/ending/code_80280000.c b/src/ending/code_80280000.c index a52372d7f..002ba2285 100644 --- a/src/ending/code_80280000.c +++ b/src/ending/code_80280000.c @@ -25,6 +25,9 @@ #include "main.h" #include "render_player.h" +#include "engine/Engine.h" +#include "engine/courses/Course.h" + s32 D_802874A0; // s32 D_802874A4[5]; @@ -50,7 +53,7 @@ void func_80280038(void) { func_80057FC4(0); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); diff --git a/src/ending/code_80281780.c b/src/ending/code_80281780.c index 3b7769ce9..2ac70325c 100644 --- a/src/ending/code_80281780.c +++ b/src/ending/code_80281780.c @@ -92,6 +92,7 @@ void load_ceremony_cutscene(void) { Camera* camera = &cameras[0]; gCurrentCourseId = COURSE_ROYAL_RACEWAY; + SetCourseByClass(GetPodiumCeremony()); D_800DC5B4 = (u16) 1; gIsMirrorMode = 0; gGotoMenu = 0xFFFF; diff --git a/src/ending/code_80281C40.c b/src/ending/code_80281C40.c index 5616040a5..ebdcd38f9 100644 --- a/src/ending/code_80281C40.c +++ b/src/ending/code_80281C40.c @@ -15,6 +15,9 @@ #include "defines.h" #include "memory.h" +#include "engine/Engine.h" +#include "engine/courses/Course.h" + struct UnkStruct80287560 { s16 unk0; s16 unk2; @@ -69,7 +72,7 @@ void func_80281D00(void) { } func_8028150C(); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); - guPerspective((Mtx*) &gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, + guPerspective((Mtx*) &gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), diff --git a/src/engine/Cup.cpp b/src/engine/Cup.cpp new file mode 100644 index 000000000..0e77ac9b8 --- /dev/null +++ b/src/engine/Cup.cpp @@ -0,0 +1,38 @@ +#include "Cup.h" +#include "courses/Course.h" + +Cup::Cup(const char* name, std::vector courses) { + this->Name = name; + this->Courses = courses; + + if (Courses.size() != 4) { + throw std::invalid_argument("A cup must contain exactly 4 courses."); + } +} + +void Cup::Next() { + if (CursorPosition < Courses.size() - 1) { + CursorPosition++; + } +} + +void Cup::Previous() { + if (CursorPosition > 0) { + CursorPosition--; + } +} + +Course* Cup::GetCourse() { + return Courses[CursorPosition]; +} + +size_t Cup::GetSize() { + return Courses.size(); +} + +// Function to shuffle the courses randomly +void Cup::ShuffleCourses() { + // std::random_device rd; + // std::mt19937 g(rd()); + //std::shuffle(Courses.begin(), Courses.end(), g); +} diff --git a/src/engine/Cup.h b/src/engine/Cup.h new file mode 100644 index 000000000..bd064a7a9 --- /dev/null +++ b/src/engine/Cup.h @@ -0,0 +1,25 @@ +#pragma once + +// Base Cup class +#include +#include +#include "courses/Course.h" + +class Course; // <-- Forward declare + +class Cup { +public: + const char* Name; + u8 *Thumbnail; + size_t CursorPosition = 0; // Course index in cup + std::vector Courses; + + explicit Cup(const char* name, std::vector courses); + + virtual void ShuffleCourses(); + + virtual void Next(); + virtual void Previous(); + virtual Course* GetCourse(); + virtual size_t GetSize(); +}; \ No newline at end of file diff --git a/src/engine/Engine.h b/src/engine/Engine.h new file mode 100644 index 000000000..497ee33b7 --- /dev/null +++ b/src/engine/Engine.h @@ -0,0 +1,46 @@ +#ifndef __ENGINE_H__ +#define __ENGINE_H__ + +#include "common_structs.h" +#include "bomb_kart.h" +#include "objects.h" +#include "path_spawn_metadata.h" + +typedef struct { + RGB8 TopRight; + RGB8 BottomRight; + RGB8 BottomLeft; + RGB8 TopLeft; + RGB8 FloorTopRight; + RGB8 FloorBottomRight; + RGB8 FloorBottomLeft; + RGB8 FloorTopLeft; +} SkyboxColours; + +typedef struct { + const char* Id; + const char* Name; + const char* DebugName; + const char* CourseLength; + const char* AIBehaviour; + float AIMaximumSeparation; + float AIMinimumSeparation; + float NearPersp; + float FarPersp; + s16 *SomePtr; + u32 AISteeringSensitivity; + _struct_gCoursePathSizes_0x10 PathSizes; + Vec4f D_0D009418; + Vec4f D_0D009568; + Vec4f D_0D0096B8; + Vec4f D_0D009808; + const char* PathTable[4]; + const char* PathTable2[4]; + CloudData *Clouds; + CloudData *CloudList; + s32 MinimapFinishlineX; + s32 MinimapFinishlineY; + SkyboxColours Skybox; +} CProperties; + +#endif // __ENGINE_H__ \ No newline at end of file diff --git a/src/engine/GameAPI.h b/src/engine/GameAPI.h new file mode 100644 index 000000000..2ac0c7511 --- /dev/null +++ b/src/engine/GameAPI.h @@ -0,0 +1,6 @@ +#ifndef GAME_API_H +#define GAME_API_H + +uintptr_t* GetCourse(void); + +#endif // GAME_API_H \ No newline at end of file diff --git a/src/engine/GameObject.cpp b/src/engine/GameObject.cpp new file mode 100644 index 000000000..691ec9e13 --- /dev/null +++ b/src/engine/GameObject.cpp @@ -0,0 +1,24 @@ +#include "GameObject.h" +#include + +#include "World.h" + +extern "C" { + #include "camera.h" +} + + + //GameActor() + +GameObject::GameObject() {} + + // Virtual functions to be overridden by derived classes +void GameObject::Init() { } +void GameObject::Update() { } +void GameObject::Render(Camera* camera) { } +void GameObject::Collision() {} +void GameObject::Expire() { } +void GameObject::Destroy() { } +// World* GameObject::GetWorld() { +// // return &gWorldInstance; +// } \ No newline at end of file diff --git a/src/engine/GameObject.h b/src/engine/GameObject.h new file mode 100644 index 000000000..ae5b530b4 --- /dev/null +++ b/src/engine/GameObject.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +extern "C" { + #include "camera.h" + #include "objects.h" +} + +class GameObject { +public: + uint8_t uuid[16]; + Object o; + + virtual ~GameObject() = default; + + explicit GameObject(); + + virtual void Init(); + virtual void Update(); + virtual void Render(Camera* camera); + virtual void Collision(); + virtual void Expire(); + virtual void Destroy(); +}; diff --git a/src/engine/World.cpp b/src/engine/World.cpp new file mode 100644 index 000000000..05a725aff --- /dev/null +++ b/src/engine/World.cpp @@ -0,0 +1,152 @@ +#include +#include "World.h" +#include "Cup.h" +#include "courses/Course.h" + +extern "C" { + #include "camera.h" + #include "objects.h" + #include "main.h" + #include "engine/Engine.h" + #include "defines.h" +} + +World::World() {} + +Course* CurrentCourse; +Cup* CurrentCup; + +Cup* World::AddCup(const char* name, std::vector courses) { + // Create a new unique_ptr for Cup + auto cup = std::make_shared(name, courses); + + // Get raw pointer before moving the ownership + Cup* tmp = cup.get(); + + // Add the Cup to the container + Cups.push_back(std::move(cup)); + + // Return the raw pointer to the Cup + return tmp; +} + +Cup* World::GetCup() { + return Cups[CupIndex].get(); +} + +void World::SetCourseFromCup() { + CurrentCourse = CurrentCup->GetCourse(); +} + +//const char* World::GetCupName() { +// //return this->Cups[CupIndex].Name; +//} + +void World::SetCupIndex(int16_t courseId) { + + this->CupIndex = courseId; +} + +u32 World::GetCupIndex() { + return this->CupIndex; +} + +u32 World::NextCup() { + s32 hack = 1; + + // Prevent battle mode + if (gModeSelection == GRAND_PRIX) { + hack = 2; + } + + if (this->CupIndex < Cups.size() - 2) { + CupIndex++; + CurrentCup = Cups[CupIndex].get(); + return CupIndex; + } +} + +u32 World::PreviousCup() { + if (CupIndex > 0) { + CupIndex--; + CurrentCup = Cups[CupIndex].get(); + return CupIndex; + } +} + +void World::SetCup() { + CurrentCup = Cups[CupIndex].get(); + CurrentCup->CursorPosition = 0; +} + +CProperties* World::GetCourseProps() { + if (Courses[CourseIndex]) { + return (CProperties*) &Courses[CourseIndex]->Props; + } + return nullptr; +} + +void World::SetCourse(const char*name) { + for (size_t i = 0; i < Courses.size(); i++) { + if (Courses[i]->Props.Name == name) { + CurrentCourse = Courses[i]; + break; + } + } + std::runtime_error("SetCourse() Course name not found in Courses list"); +} + +void World::NextCourse() { + if (CourseIndex < Courses.size() - 1) { + CourseIndex++; + } else { + CourseIndex = 0; + } + gWorldInstance.CurrentCourse = Courses[CourseIndex]; +} + +void World::PreviousCourse() { + if (CourseIndex > 0) { + CourseIndex--; + } else { + CourseIndex = Courses.size() - 1; + } + gWorldInstance.CurrentCourse = Courses[CourseIndex]; +} + +Object* World::SpawnObject(std::unique_ptr object) { + GameObject* rawPtr = object.get(); + this->GameObjects.push_back(std::move(object)); + return &rawPtr->o; +} + +void World::UpdateObjects() { + for (const auto& object : this->GameObjects) { + object->Update(); + } +} + +void World::RenderObjects(Camera *camera) { + for (const auto& object : this->GameObjects) { + object->Render(camera); + } +} + +void World::ExpiredObjects() { + this->GameObjects.erase( + std::remove_if(this->GameObjects.begin(), this->GameObjects.end(), + [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition + this->GameObjects.end()); +} + +void World::DestroyObjects() { + +} + +Object* World::GetObjectByIndex(size_t index) { + if (index < this->GameObjects.size()) { + // Assuming GameActor::a is accessible, use reinterpret_cast if needed + return reinterpret_cast(&this->GameObjects[index]->o); + } + return nullptr; // Or handle the error as needed +} diff --git a/src/engine/World.h b/src/engine/World.h new file mode 100644 index 000000000..45edd7646 --- /dev/null +++ b/src/engine/World.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include "GameObject.h" +#include "Cup.h" + +extern "C" { +#include "camera.h" +#include "objects.h" +#include "engine/Engine.h" +}; + +class Cup; // <-- Forward declaration +class Course; + +class World { + + typedef struct { + uint8_t r, g, b; + } RGB8; + + typedef struct { + RGB8 TopRight; + RGB8 BottomRight; + RGB8 BottomLeft; + RGB8 TopLeft; + RGB8 FloorTopRight; + RGB8 FloorBottomRight; + RGB8 FloorBottomLeft; + RGB8 FloorTopLeft; + } SkyboxColours; + + + typedef struct { + const char* Name; + const char* DebugName; + const char* CourseLength; + const char* AIBehaviour; + float AIMaximumSeparation; + float AIMinimumSeparation; + int16_t *SomePtr; + uint32_t AISteeringSensitivity; + _struct_gCoursePathSizes_0x10 PathSizes; + Vec4f D_0D009418; + Vec4f D_0D009568; + Vec4f D_0D0096B8; + Vec4f D_0D009808; + const char* PathTable[4]; + const char* PathTable2[4]; + CloudData *Clouds; + CloudData *CloudList; + int32_t MinimapFinishlineX; + int32_t MinimapFinishlineY; + SkyboxColours Skybox; + } Properties; + +public: + //Actor actors; + virtual ~World() = default; + explicit World(); + + // virtual Actor* SpawnActor(std::unique_ptr actor); + + virtual Object* SpawnObject(std::unique_ptr object); + + + virtual CProperties* GetCourseProps(); + virtual void UpdateObjects(); + virtual void RenderObjects(Camera *camera); + virtual void ExpiredObjects(); + virtual void DestroyObjects(); + virtual Object *GetObjectByIndex(size_t); + + Cup* AddCup(const char* name, std::vector courses); + Cup* GetCup(); + const char* GetCupName(); + virtual u32 GetCupIndex(); + virtual void SetCupIndex(int16_t courseId); + virtual u32 NextCup(); + virtual u32 PreviousCup(); + virtual void SetCourseFromCup(); + void SetCup(); + + World* GetWorld(); + + + // These are only for browsing through the course list + void SetCourse(const char*); + void NextCourse(void); + void PreviousCourse(void); + + // Holds all available courses + + Course* CurrentCourse; + Cup* CurrentCup; + + std::vector> Cups; + size_t CupIndex = 1; + + std::vector> GameObjects; + // std::vector> GameActors; + + std::vector Courses; + size_t CourseIndex = 0; // For browsing courses. +private: + +}; + +extern World gWorldInstance; + diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp new file mode 100644 index 000000000..854d2d3ab --- /dev/null +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -0,0 +1,312 @@ +#include +#include +#include +#include + +#include "BansheeBoardwalk.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/banshee_boardwalk_data.h" +#include "assets/boo_frames.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *banshee_boardwalk_dls[]; +} + +BansheeBoardwalk::BansheeBoardwalk() { + this->vtx = d_course_banshee_boardwalk_vertex; + this->gfx = d_course_banshee_boardwalk_packed_dls; + this->gfxSize = 3689; + this->textures = banshee_boardwalk_textures; + + Props.Id = "mk:banshee_boardwalk"; + Props.Name = "banshee boardwalk"; + Props.DebugName = "ghost"; + Props.CourseLength = "747m"; + Props.AIBehaviour = D_0D009058; + Props.AIMaximumSeparation = 40.0f; + Props.AIMinimumSeparation = 0.4f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 2700.0f; + + Props.PathSizes = {0x2EE, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_banshee_boardwalk_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_banshee_boardwalk_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 0, 0}; + Props.Skybox.BottomRight = {0, 0, 0}; + Props.Skybox.BottomLeft = {0, 0, 0}; + Props.Skybox.TopLeft = {0, 0, 0}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void BansheeBoardwalk::LoadTextures() { +} + +void BansheeBoardwalk::SpawnActors() { + spawn_all_item_boxes(d_course_banshee_boardwalk_item_box_spawns); +} + +void BansheeBoardwalk::Init() { } + +// Likely sets minimap boundaries +void BansheeBoardwalk::MinimapSettings() { + D_80165880 = dma_textures((const char*)gTextureGhosts, 0x4CC2, 0xD980); + D_8018D2A0 = 0.016f; + D_8018D2C0[0] = 0x0106; + D_8018D2E0 = 55; + D_8018D2E8 = 39; +} + +const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gTextureBat4 }; + +void BansheeBoardwalk::InitCourseObjects() { + size_t objectId = 0; + if (gGamestate != CREDITS_SEQUENCE) { + objectId = indexObjectList1[0]; + init_texture_object(objectId, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U, + (u16) 0x00000040); + gObjectList[objectId].orientation[0] = 0; + gObjectList[objectId].orientation[1] = 0; + gObjectList[objectId].orientation[2] = 0x8000; + init_object(indexObjectList1[1], 0); + init_object(indexObjectList1[2], 0); + } +} + +void BansheeBoardwalk::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + update_trash_bin(); + func_8007E4C4(); + if (gModeSelection != TIME_TRIALS) { + update_bat(); + } + wrapper_update_boos(); + update_cheep_cheep(0); + } +} + +void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_trash_bin(cameraId); + render_object_bat(cameraId); + func_8005217C(cameraId); + render_object_boos(cameraId); + } +} + +void BansheeBoardwalk::SomeSounds() { +} + +void BansheeBoardwalk::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void BansheeBoardwalk::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void BansheeBoardwalk::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void BansheeBoardwalk::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void BansheeBoardwalk::SetStaffGhost() { +} + +void BansheeBoardwalk::BeginPlay() { } + +void BansheeBoardwalk::Render(struct UnkStruct_800DC5EC* arg0) { + Camera* camera = arg0->camera; + Mat4 spCC; + UNUSED s32 pad[6]; + Vec3f spA8; + UNUSED s32 pad2[6]; + + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPSetCombineMode(gDisplayListHead++, G_CC_DECALRGBA, G_CC_DECALRGBA); + // d_course_banshee_boardwalk_packed_dl_7228 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07007228))); + + gSPFogPosition(gDisplayListHead++, D_802B87B0, D_802B87B4); + + gDPPipeSync(gDisplayListHead++); + + gSPClearGeometryMode(gDisplayListHead++, + G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // d_course_banshee_boardwalk_packed_dl_5CD0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07005CD0))); + // d_course_banshee_boardwalk_packed_dl_4E60 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07004E60))); + // d_course_banshee_boardwalk_packed_dl_69B0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x070069B0))); + + render_course_segments(banshee_boardwalk_dls, arg0); + + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH); + // d_course_banshee_boardwalk_packed_dl_580 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000580))); + // d_course_banshee_boardwalk_packed_dl_60 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000060))); + // d_course_banshee_boardwalk_packed_dl_540 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000540))); + + if (camera->pos[1] < -20.0f) { + // d_course_banshee_boardwalk_packed_dl_6310 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07006310))); + } + spA8[0] = camera->pos[0]; + spA8[1] = -82.0f; + spA8[2] = camera->pos[2]; + mtxf_translate(spCC, spA8); + render_set_position(spCC, 0); + + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_B278); + gDPPipeSync(gDisplayListHead++); +} + +void BansheeBoardwalk::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_banshee_boardwalk_dl_B308)); +} + +void BansheeBoardwalk::Collision() {} + +void BansheeBoardwalk::GenerateCollision() { + D_800DC5BC = 1; + D_801625EC = 0; + D_801625F4 = 0; + D_801625F0 = 0; + parse_course_displaylists(d_course_banshee_boardwalk_track_sections); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07000878)), 128, 0, 0, 0); + D_8015F8E4 = -80.0f; +} + +void BansheeBoardwalk::Water() { + D_802B87BC++; + + if (D_802B87BC >= 0x100) { + D_802B87BC = 0; + } + find_and_set_tile_size((uintptr_t) LOAD_ASSET_RAW(d_course_banshee_boardwalk_dl_B278), 0, D_802B87BC); +} + +void BansheeBoardwalk::Waypoints(Player* player, int8_t playerId) { + s16 waypoint = gNearestWaypointByPlayerId[playerId]; + if ((waypoint >= 0x12C) && (waypoint < 0x13C)) { + player->nearestWaypointId = 0x12CU; + } else { + player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } + } +} + +void BansheeBoardwalk::Destroy() { } diff --git a/src/engine/courses/BansheeBoardwalk.h b/src/engine/courses/BansheeBoardwalk.h new file mode 100644 index 000000000..7446c9af4 --- /dev/null +++ b/src/engine/courses/BansheeBoardwalk.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/banshee_boardwalk_vertices.h" + #include "assets/banshee_boardwalk_displaylists.h" + #include "assets/banshee_boardwalk_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture banshee_boardwalk_textures[]; +} + +class BansheeBoardwalk : public Course { +public: + virtual ~BansheeBoardwalk() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit BansheeBoardwalk(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Water() override; + virtual void Waypoints(Player*, int8_t) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/BigDonut.cpp b/src/engine/courses/BigDonut.cpp new file mode 100644 index 000000000..581472ca1 --- /dev/null +++ b/src/engine/courses/BigDonut.cpp @@ -0,0 +1,177 @@ +#include +#include +#include +#include + +#include "BigDonut.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/big_donut_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *big_donut_dls[]; + extern s16 currentScreenSection; +} + +BigDonut::BigDonut() { + this->vtx = d_course_big_donut_vertex; + this->gfx = d_course_big_donut_packed_dls; + this->gfxSize = 528; + this->textures = big_donut_textures; + + Props.Name = "big donut"; + Props.DebugName = "doughnut"; + Props.CourseLength = ""; + Props.AIBehaviour = D_0D008F18; + Props.AIMaximumSeparation = -1.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 40; + + Props.PathSizes = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = NULL; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = NULL; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 0, 0}; + Props.Skybox.BottomRight = {0, 0, 0}; + Props.Skybox.BottomLeft = {0, 0, 0}; + Props.Skybox.TopLeft = {0, 0, 0}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void BigDonut::LoadTextures() { +} + +void BigDonut::SpawnActors() {} + +void BigDonut::Init() { } + +// Likely sets minimap boundaries +void BigDonut::MinimapSettings() { + D_8018D2A0 = 0.0257f; + D_8018D2E0 = 32; + D_8018D2E8 = 31; +} + +void BigDonut::InitCourseObjects() {} + +void BigDonut::SomeSounds() {} + +void BigDonut::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void BigDonut::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void BigDonut::SpawnBombKarts() {} + +// Positions the finishline on the minimap +void BigDonut::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void BigDonut::SetStaffGhost() {} + +void BigDonut::BeginPlay() {} +void BigDonut::Render(struct UnkStruct_800DC5EC* arg0) { + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_big_donut_packed_dl_DE8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000DE8))); + } + // d_course_big_donut_packed_dl_450 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000450))); + // d_course_big_donut_packed_dl_AC0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000AC0))); + // d_course_big_donut_packed_dl_D20 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000D20))); + // d_course_big_donut_packed_dl_230 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000230))); +} + +void BigDonut::RenderCredits() {} + +void BigDonut::Collision() {} + +void BigDonut::GenerateCollision() { + // d_course_big_donut_packed_dl_1018 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001018), 6); + // d_course_big_donut_packed_dl_450 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000450), 6); + // d_course_big_donut_packed_dl_AC0 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000AC0), 6); + // d_course_big_donut_packed_dl_B58 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000B58), 6); + // d_course_big_donut_packed_dl_230 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000230), 6); + func_80295C6C(); + D_8015F8E4 = 100.0f; +} + +void BigDonut::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = 0; +} + +void BigDonut::Destroy() { } diff --git a/src/engine/courses/BigDonut.h b/src/engine/courses/BigDonut.h new file mode 100644 index 000000000..1c7865b47 --- /dev/null +++ b/src/engine/courses/BigDonut.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/big_donut_vertices.h" + #include "assets/big_donut_displaylists.h" + #include "assets/big_donut_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture big_donut_textures[]; +} + +class BigDonut : public Course { +public: + virtual ~BigDonut() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit BigDonut(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/BlockFort.cpp b/src/engine/courses/BlockFort.cpp new file mode 100644 index 000000000..fad4eceda --- /dev/null +++ b/src/engine/courses/BlockFort.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#include "BlockFort.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/block_fort_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *block_fort_dls[]; + extern s16 currentScreenSection; +} + +BlockFort::BlockFort() { + this->vtx = d_course_block_fort_vertex; + this->gfx = d_course_block_fort_packed_dls; + this->gfxSize = 699; + this->textures = block_fort_textures; + + Props.Name = "block fort"; + Props.DebugName = "block"; + Props.CourseLength = ""; + Props.AIBehaviour = D_0D008F18; + Props.AIMaximumSeparation = -1.0f; + Props.AIMinimumSeparation = 0.1f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 2700.0f; + + Props.PathSizes = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = NULL; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = NULL; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {128, 184, 248}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {128, 184, 248}; + Props.Skybox.FloorTopRight = {216, 232, 248}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {216, 232, 248}; +} + +void BlockFort::LoadTextures() { +} + +void BlockFort::SpawnActors() {} + +void BlockFort::Init() { } + +// Likely sets minimap boundaries +void BlockFort::MinimapSettings() { + D_8018D2A0 = 0.0335f; + D_8018D2E0 = 32; + D_8018D2E8 = 32; +} + +void BlockFort::InitCourseObjects() {} + +void BlockFort::SomeSounds() {} + +void BlockFort::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void BlockFort::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void BlockFort::SpawnBombKarts() {} + +// Positions the finishline on the minimap +void BlockFort::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void BlockFort::SetStaffGhost() {} + +void BlockFort::BeginPlay() { } +void BlockFort::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // d_course_block_fort_packed_dl_15C0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x070015C0))); +} + +void BlockFort::RenderCredits() {} + +void BlockFort::Collision() {} + +void BlockFort::GenerateCollision() { + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x070015C0), 1); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void BlockFort::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = 0; +} + +void BlockFort::Destroy() { } diff --git a/src/engine/courses/BlockFort.h b/src/engine/courses/BlockFort.h new file mode 100644 index 000000000..60755878f --- /dev/null +++ b/src/engine/courses/BlockFort.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/block_fort_vertices.h" + #include "assets/block_fort_displaylists.h" + #include "assets/block_fort_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture block_fort_textures[]; +} + +class BlockFort : public Course { +public: + virtual ~BlockFort() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit BlockFort(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player*, int8_t) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/BombKart.cpp b/src/engine/courses/BombKart.cpp new file mode 100644 index 000000000..1cbbd7477 --- /dev/null +++ b/src/engine/courses/BombKart.cpp @@ -0,0 +1,28 @@ +#include "BombKart.h" + +extern "C" { + #include "bomb_kart.h" +} + +/** + * BombKarts derive their Y position from the waypoint Y value or 'spawn_actor_on_surface' function + */ + +OBombKart::OBombKart(uint16_t waypoint, uint16_t state, float unk_04, float x, float z, float unk_10, float unk_14) {} + +void OBombKart::Init() { + // BombKarts.emplace_back(this); + //BombKarts.push_back(BombKarts(waypoint, state, unk_04, x, z, unk_10, unk_14)); +} + +void OBombKart::Update() { + +} + +void OBombKart::Render() { + +} + +void OBombKart::Explode() { + +} \ No newline at end of file diff --git a/src/engine/courses/BombKart.h b/src/engine/courses/BombKart.h new file mode 100644 index 000000000..e11bf6820 --- /dev/null +++ b/src/engine/courses/BombKart.h @@ -0,0 +1,38 @@ +#ifndef BOMBKART_H +#define BOMBKART_H + +#include + + +#ifdef __cplusplus +#include "GameObject.h" +extern "C" { +#endif + + #include "bomb_kart.h" + #include "Engine.h" + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +class OBombKart : public GameObject { + +public: + virtual ~OBombKart() = default; + + // Constructor + explicit OBombKart(uint16_t waypoint, uint16_t state, float unk_04, float x, float z, float unk_10, float unk_14); + + BombKart vehicle; + virtual void Init(); + virtual void Update(); + virtual void Render(); + virtual void Explode(); +}; + +#endif + +#endif // BOMBKART_H \ No newline at end of file diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp new file mode 100644 index 000000000..33179e739 --- /dev/null +++ b/src/engine/courses/BowsersCastle.cpp @@ -0,0 +1,291 @@ +#include +#include +#include +#include + +#include "BowsersCastle.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "bowsers_castle_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *bowsers_castle_dls[]; +} + +BowsersCastle::BowsersCastle() { + this->vtx = d_course_bowsers_castle_vertex; + this->gfx = d_course_bowsers_castle_packed_dls; + this->gfxSize = 4900; + this->textures = bowsers_castle_textures; + + Props.Id = "mk:bowsers_castle"; + Props.Name = "bowser's castle"; + Props.DebugName = "castle"; + Props.CourseLength = "777m"; + Props.AIBehaviour = D_0D008FB8; + Props.AIMaximumSeparation = 35.0f; + Props.AIMinimumSeparation = 0.2f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 2700.0f; + + Props.PathSizes = {0x30C, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_bowsers_castle_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_bowsers_castle_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {48, 8, 120}; + Props.Skybox.BottomRight = {0, 0, 0}; + Props.Skybox.BottomLeft = {0, 0, 0}; + Props.Skybox.TopLeft = {48, 8, 120}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void BowsersCastle::LoadTextures() { + dma_textures(gTextureShrub, 0x000003FFU, 0x00000800U); +} + +void BowsersCastle::SpawnActors() { + spawn_foliage(d_course_bowsers_castle_tree_spawn); + spawn_all_item_boxes(d_course_bowsers_castle_item_box_spawns); +} + +void BowsersCastle::Init() { } + +// Likely sets minimap boundaries +void BowsersCastle::MinimapSettings() { + D_8018D2C0[0] = 265; + D_8018D2A0 = 0.0174f; + D_8018D2E0 = 12; + D_8018D2E8 = 48; +} + +void BowsersCastle::InitCourseObjects() { + size_t objectId; + size_t i; + + gNumActiveThwomps = NUM_THWOMPS_100CC_EXTRA; + gThowmpSpawnList = gThwompSpawns100CCExtra; + switch (gCCSelection) { /* switch 1; irregular */ + case CC_100: /* switch 1 */ + case CC_EXTRA: /* switch 1 */ + break; + case CC_50: /* switch 1 */ + gNumActiveThwomps = NUM_THWOMPS_50CC; + gThowmpSpawnList = gThomwpSpawns50CC; + break; + case CC_150: /* switch 1 */ + gNumActiveThwomps = NUM_THWOMPS_150CC; + gThowmpSpawnList = gThomwpSpawns150CC; + break; + } + for (i = 0; i < gNumActiveThwomps; i++) { + objectId = indexObjectList1[i]; + init_object(objectId, 0); + gObjectList[objectId].origin_pos[0] = gThowmpSpawnList[i].startX * xOrientation; + gObjectList[objectId].origin_pos[2] = gThowmpSpawnList[i].startZ; + gObjectList[objectId].unk_0D5 = gThowmpSpawnList[i].unk_4; + gObjectList[objectId].primAlpha = gThowmpSpawnList[i].unk_6; + } + // Handle the big statue's fire breath + objectId = indexObjectList2[0]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = -68.0 * xOrientation; + gObjectList[objectId].pos[1] = 80.0f; + gObjectList[objectId].pos[2] = -1840.0f; + // Handle the smaller statues' fire breath + for (i = 0; i < NUM_FIRE_BREATHS; i++) { + objectId = indexObjectList3[i]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gFireBreathsSpawns[i][0] * xOrientation; + gObjectList[objectId].pos[1] = gFireBreathsSpawns[i][1]; + gObjectList[objectId].pos[2] = gFireBreathsSpawns[i][2]; + gObjectList[objectId].direction_angle[1] = 0; + if (i % 2U) { + gObjectList[objectId].direction_angle[1] += 0x8000; + } + } + for (i = 0; i < 32; i++) { + delete_object(&indexObjectList4[i]); + } +} + +void BowsersCastle::UpdateCourseObjects() { + func_80081208(); + update_flame_particle(); +} + +void BowsersCastle::RenderCourseObjects(s32 cameraId) { + render_object_thwomps(cameraId); + render_object_bowser_flame(cameraId); +} + +void BowsersCastle::SomeSounds() { +} + +void BowsersCastle::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void BowsersCastle::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void BowsersCastle::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void BowsersCastle::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void BowsersCastle::SetStaffGhost() { +} + +void BowsersCastle::BeginPlay() { } +void BowsersCastle::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_bowsers_castle_packed_dl_6A80 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07006A80))); + } + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + + D_802B87BC++; + if (D_802B87BC > 255) { + D_802B87BC = 0; + } + render_course_segments(bowsers_castle_dls, arg0); + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + // d_course_bowsers_castle_packed_dl_248 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000248))); +} + +void BowsersCastle::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_bowsers_castle_dl_9148)); +} + +void BowsersCastle::Collision() {} + +void BowsersCastle::GenerateCollision() { + parse_course_displaylists(d_course_bowsers_castle_addr); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07001350)), 0x32, 0, 0, 0); + D_8015F8E4 = -50.0f; +} + +void BowsersCastle::Waypoints(Player* player, int8_t playerId) { + s16 waypoint = gNearestWaypointByPlayerId[playerId]; + if ((waypoint >= 0x235) && (waypoint < 0x247)) { + player->nearestWaypointId = 0x214; + } else if ((waypoint >= 0x267) && (waypoint < 0x277)) { + player->nearestWaypointId = 0x25B; + } else { + player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } + } +} + +void BowsersCastle::Destroy() { } diff --git a/src/engine/courses/BowsersCastle.h b/src/engine/courses/BowsersCastle.h new file mode 100644 index 000000000..f949303c2 --- /dev/null +++ b/src/engine/courses/BowsersCastle.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/bowsers_castle_vertices.h" + #include "assets/bowsers_castle_displaylists.h" + #include "assets/bowsers_castle_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture bowsers_castle_textures[]; +} + +class BowsersCastle : public Course { +public: + virtual ~BowsersCastle() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit BowsersCastle(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player*, int8_t) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp new file mode 100644 index 000000000..f2f008fba --- /dev/null +++ b/src/engine/courses/ChocoMountain.cpp @@ -0,0 +1,275 @@ +#include +#include +#include +#include + +#include "ChocoMountain.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "choco_mountain_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *choco_mountain_dls[]; +} + +ChocoMountain::ChocoMountain() { + this->vtx = d_course_choco_mountain_vertex; + this->gfx = d_course_choco_mountain_packed_dls; + this->gfxSize = 2910; + this->textures = choco_mountain_textures; + + Props.Id = "mk:choco_mountain"; + Props.Name = "choco mountain"; + Props.DebugName = "mountain"; + Props.CourseLength = "687m"; + Props.AIBehaviour = D_0D008F80; + Props.AIMaximumSeparation = 35.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 1500.0f; + + Props.PathSizes = {0x2BC, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_choco_mountain_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_choco_mountain_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {255, 255, 255}; + Props.Skybox.BottomRight = {255, 255, 255}; + Props.Skybox.BottomLeft = {255, 255, 255}; + Props.Skybox.TopLeft = {255, 255, 255}; + Props.Skybox.FloorTopRight = {255, 255, 255}; + Props.Skybox.FloorBottomRight = {255, 255, 255}; + Props.Skybox.FloorBottomLeft = {255, 255, 255}; + Props.Skybox.FloorTopLeft = {255, 255, 255}; +} + +void ChocoMountain::LoadTextures() { +} + +void ChocoMountain::SpawnActors() { + spawn_all_item_boxes(d_course_choco_mountain_item_box_spawns); + spawn_falling_rocks(d_course_choco_mountain_falling_rock_spawns); +} + +void ChocoMountain::Init() { } + +// Likely sets minimap boundaries +void ChocoMountain::MinimapSettings() { + D_8018D2A0 = 0.022f; + D_8018D2C0[0] = 265; + D_8018D2E0 = 19; + D_8018D2E8 = 37; +} + +void ChocoMountain::InitCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == GRAND_PRIX) { + func_80070714(); + } + for (size_t i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + } +} + +void ChocoMountain::SomeSounds() { + vec3f_set(D_8015F748, -223.0f, 94.0f, -155.0f); + func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); +} + +void ChocoMountain::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void ChocoMountain::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void ChocoMountain::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void ChocoMountain::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void ChocoMountain::SetStaffGhost() { +} + +void ChocoMountain::BeginPlay() { } +void ChocoMountain::Render(struct UnkStruct_800DC5EC* arg0) { + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_choco_mountain_packed_dl_4608 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07004608))); + } + gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE); + gDPSetFogColor(gDisplayListHead++, D_801625EC, D_801625F4, D_801625F0, 0xFF); + gSPFogPosition(gDisplayListHead++, D_802B87B0, D_802B87B4); + + gDPPipeSync(gDisplayListHead++); + gSPSetGeometryMode(gDisplayListHead++, G_FOG); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATERGB, G_CC_PASS2); + + gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // d_course_choco_mountain_packed_dl_5A70 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07005A70))); + // d_course_choco_mountain_packed_dl_828 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000828))); + // d_course_choco_mountain_packed_dl_8E0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x070008E0))); + // d_course_choco_mountain_packed_dl_5868 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07005868))); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + render_course_segments(choco_mountain_dls, arg0); + + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2); + gDPSetCombineMode(gDisplayListHead++, G_CC_DECALRGBA, G_CC_PASS2); + // d_course_choco_mountain_packed_dl_448 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000448))); + // d_course_choco_mountain_packed_dl_5D8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x070005D8))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_choco_mountain_packed_dl_718 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07000718))); + gSPClearGeometryMode(gDisplayListHead++, G_FOG); + gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); + gDPPipeSync(gDisplayListHead++); +} + +void ChocoMountain::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_choco_mountain_dl_71B8)); +} + +void ChocoMountain::Collision() {} + +void ChocoMountain::GenerateCollision() { + D_800DC5BC = 1; + D_801625EC = 255; + D_801625F4 = 255; + D_801625F0 = 255; + D_802B87B0 = 0x3E3; + D_802B87B4 = 0x3E8; + D_802B87D4 = 0x71C; + D_802B87D0 = 0xE38; + + // Spawn guardrail only for CC_50 and time trials. + if ((gCCSelection != CC_50) && (gModeSelection != TIME_TRIALS)) { + // d_course_choco_mountain_packed_dl_0 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000000))); + // d_course_choco_mountain_packed_dl_98 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000098))); + // d_course_choco_mountain_packed_dl_178 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000178))); + // d_course_choco_mountain_packed_dl_280 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000280))); + // d_course_choco_mountain_packed_dl_340 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000340))); + // d_course_choco_mountain_packed_dl_3C8 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x070003C8))); + } + + parse_course_displaylists(d_course_choco_mountain_addr); + func_802B5CAC(0x238E, 0x31C7, D_8015F590); + func_80295C6C(); + D_8015F8E4 = -80.0f; +} + +void ChocoMountain::Destroy() { } diff --git a/src/engine/courses/ChocoMountain.h b/src/engine/courses/ChocoMountain.h new file mode 100644 index 000000000..c57f18e52 --- /dev/null +++ b/src/engine/courses/ChocoMountain.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/choco_mountain_vertices.h" + #include "assets/choco_mountain_displaylists.h" + #include "assets/choco_mountain_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture choco_mountain_textures[]; +} + +class ChocoMountain : public Course { +public: + virtual ~ChocoMountain() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit ChocoMountain(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp new file mode 100644 index 000000000..b3f9248bb --- /dev/null +++ b/src/engine/courses/Course.cpp @@ -0,0 +1,227 @@ +#include + +#include "Course.h" +#include "MarioRaceway.h" +#include "ChocoMountain.h" + +extern "C" { + #include "main.h" + #include "memory.h" + #include "common_structs.h" + #include "course_offsets.h" + #include "some_data.h" + #include "code_8006E9C0.h" + #include "code_8003DC40.h" + #include "assets/common_data.h" + #include "render_objects.h" + #include "save.h" + #include "staff_ghosts.h" + #include "Engine.h" + extern StaffGhost* d_mario_raceway_staff_ghost; +} + +Course::Course() { + // Props.Name = "Course Name"; + // Props.DebugName = "CName"; + // Props.CourseLength = "567m"; + // Props.Cup = FLOWER_CUP; + // Props.CupIndex = 3; + Props.AIBehaviour = D_0D008F28; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCB34; + Props.AISteeringSensitivity = 48; + + Props.NearPersp = 3.0f; + Props.FarPersp = 6800.0f; + + Props.PathSizes = {600, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = NULL; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = NULL; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; +} + +void Course::Load(Vtx* vtx, Gfx* gfx) { + gSegmentTable[4] = reinterpret_cast(&vtx[0]); + gSegmentTable[7] = reinterpret_cast(&gfx[0]); +} + +void Course::Load() { + + size_t vtxSize = (ResourceGetSizeByName(this->vtx) / sizeof(CourseVtx)) * sizeof(Vtx); + size_t texSegSize; + + // Convert course vtx to vtx + Vtx* vtx = reinterpret_cast(allocate_memory(vtxSize)); + gSegmentTable[4] = reinterpret_cast(&vtx[0]); + printf("\nVtxsize: 0x%X\n\n",vtxSize); + func_802A86A8(reinterpret_cast(LOAD_ASSET_RAW(this->vtx)), vtx, vtxSize / sizeof(Vtx)); + + // Load and allocate memory for course textures + const course_texture* asset = this->textures; + u8* freeMemory = NULL; + u8* texture = NULL; + size_t size = 0; + texSegSize = 0; + while (asset->addr) { + size = ResourceGetTexSizeByName(asset->addr); + freeMemory = (u8*) allocate_memory(size); + + texture = reinterpret_cast(LOAD_ASSET_RAW(asset->addr)); + if (texture) { + if (asset == &textures[0]) { + gSegmentTable[5] = reinterpret_cast(&freeMemory[0]); + } + memcpy(freeMemory, texture, size); + texSegSize += size; + // printf("Texture Addr: 0x%llX, size 0x%X\n", &freeMemory[0], size); + } + asset++; + } + + // Extract packed DLs + u8* packed = reinterpret_cast(LOAD_ASSET_RAW(this->gfx)); + Gfx* gfx = (Gfx*) allocate_memory(sizeof(Gfx) * this->gfxSize); // Size of unpacked DLs + assert(gfx != NULL); + gSegmentTable[7] = reinterpret_cast(&gfx[0]); + displaylist_unpack(reinterpret_cast(gfx), reinterpret_cast(packed), 0); +} + +void Course::LoadTextures() { } + +void Course::SpawnActors() { + +} + +void Course::Init() { +} +void Course::InitClouds() { + if (this->Props.Clouds) { + init_clouds(this->Props.Clouds); + } +} + +void Course::UpdateClouds(s32 arg0, Camera* camera) { + s32 cloudIndex; + s32 objectIndex; + CloudData* cloud; + + if (this->Props.CloudList) { + for (cloudIndex = 0; cloudIndex < D_8018D1F0; cloudIndex++) { + cloud = &this->Props.CloudList[cloudIndex]; + objectIndex = D_8018CC80[arg0 + cloudIndex]; + func_800788F8(objectIndex, cloud->rotY, camera); + } + } +} + +void Course::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) { + func_8003E048(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); +} + + +void Course::MinimapSettings() { + +} + +void Course::InitCourseObjects() { + +} + +void Course::UpdateCourseObjects() { + +} + +void Course::RenderCourseObjects(s32 cameraId) { + +} + +// Implemented for the first cup of each course plus Koopa Beach +void Course::SomeSounds() { + +} + +void Course::SetCourseVtxColours() { + +} + +void Course::WhatDoesThisDo(Player* player, int8_t playerId) { + +} + +void Course::WhatDoesThisDoAI(Player* player, int8_t playerId) { + +} + +// Positions the finishline on the minimap +void Course::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void Course::SetStaffGhost() { + D_80162DD6 = 1; + D_80162DF4 = 1; +} + +void Course::SpawnBombKarts() { +// GetWorld()->SpawnBombKarts(); +} + +World* Course::GetWorld() { + return nullptr; + //&gWorldInstance; +} + +void Course::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } +} + +void Course::SpawnVehicles() {} +void Course::UpdateVehicles() {} + +void Course::BeginPlay() {} +void Course::Render(struct UnkStruct_800DC5EC* arg0) {} +void Course::RenderCredits() {} +void Course::Collision() {} +void Course::GenerateCollision() {} +void Course::Water() {} + +void Course::Destroy() { } + +Course* currentCourse = nullptr; diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h new file mode 100644 index 000000000..bc817c73a --- /dev/null +++ b/src/engine/courses/Course.h @@ -0,0 +1,126 @@ +#ifndef COURSE_H +#define COURSE_H + +#include + + +// C-compatible function declaration +#ifdef __cplusplus +//#include "World.h" +extern "C" { +#endif + + #include "camera.h" + #include "course_offsets.h" + #include "data/some_data.h" + #include "defines.h" + #include "bomb_kart.h" + #include "path_spawn_metadata.h" + #include "Engine.h" + +CProperties *CourseManager_GetProps(); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +class World; // <-- Forward declare + + +class Course { + +public: + typedef struct { + uint8_t r, g, b; + } RGB8; + + typedef struct { + RGB8 TopRight; + RGB8 BottomRight; + RGB8 BottomLeft; + RGB8 TopLeft; + RGB8 FloorTopRight; + RGB8 FloorBottomRight; + RGB8 FloorBottomLeft; + RGB8 FloorTopLeft; + } SkyboxColours; + + + typedef struct { + const char* Id; + const char* Name; + const char* DebugName; + const char* CourseLength; + const char* AIBehaviour; + float AIMaximumSeparation; + float AIMinimumSeparation; + float NearPersp; + float FarPersp; + int16_t *SomePtr; + uint32_t AISteeringSensitivity; + _struct_gCoursePathSizes_0x10 PathSizes; + Vec4f D_0D009418; + Vec4f D_0D009568; + Vec4f D_0D0096B8; + Vec4f D_0D009808; + const char* PathTable[4]; + const char* PathTable2[4]; + CloudData *Clouds; + CloudData *CloudList; + int32_t MinimapFinishlineX; + int32_t MinimapFinishlineY; + SkyboxColours Skybox; + } Properties; + + Properties Props; + + const char* vtx = nullptr; + const char* gfx = nullptr; + size_t gfxSize = 0; + const course_texture* textures = nullptr; + + virtual ~Course() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit Course(); // UUID should be passed in constructor + + // Virtual functions to be overridden by derived classes + virtual void Load(); + virtual void Load(Vtx* vtx, Gfx *gfx); + // This function may not be needed due to otr system. + virtual void LoadTextures(); + virtual void SpawnActors(); + virtual void Init(); + virtual void InitClouds(); + virtual void UpdateClouds(s32, Camera*); + virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7); + virtual void MinimapSettings(); + virtual void InitCourseObjects(); + virtual void UpdateCourseObjects(); + virtual void RenderCourseObjects(s32 cameraId); + virtual void SomeSounds(); + virtual void SetCourseVtxColours(); + virtual void WhatDoesThisDo(Player*, int8_t); + virtual void WhatDoesThisDoAI(Player*, int8_t); + virtual void MinimapFinishlinePosition(); + virtual void SetStaffGhost(); + virtual void SpawnBombKarts(); + virtual void BeginPlay(); + virtual void Render(struct UnkStruct_800DC5EC*); + virtual void RenderCredits(); + virtual void SpawnVehicles(); + virtual void UpdateVehicles(); + virtual void Waypoints(Player* player, int8_t playerId); + virtual void Collision(); + virtual void GenerateCollision(); + virtual void Water(); + virtual void Destroy(); + virtual World* GetWorld(); + +}; + +#endif + +#endif // COURSE_H \ No newline at end of file diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp new file mode 100644 index 000000000..ba3842e6e --- /dev/null +++ b/src/engine/courses/DKJungle.cpp @@ -0,0 +1,304 @@ +#include +#include +#include +#include + +#include "DKJungle.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/dks_jungle_parkway_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + #include "sounds.h" + extern const char *d_course_dks_jungle_parkway_unknown_dl_list[]; + extern s16 currentScreenSection; +} + +DKJungle::DKJungle() { + this->vtx = d_course_dks_jungle_parkway_vertex; + this->gfx = d_course_dks_jungle_parkway_packed_dls; + this->gfxSize = 4997; + this->textures = dks_jungle_parkway_textures; + + Props.Name = "d.k.'s jungle parkway"; + Props.DebugName = "jungle"; + Props.CourseLength = "893m"; + Props.AIBehaviour = D_0D0093C0; + Props.AIMaximumSeparation = 40.0f; + Props.AIMinimumSeparation = 0.1f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x370, 1, 1, 1, 0x1F4, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_dks_jungle_parkway_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_dks_jungle_parkway_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {255, 174, 0}; + Props.Skybox.BottomRight = {255, 229, 124}; + Props.Skybox.BottomLeft = {255, 229, 124}; + Props.Skybox.TopLeft = {255, 174, 0}; + Props.Skybox.FloorTopRight = {22, 145, 22}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {22, 145, 22}; +} + +void DKJungle::LoadTextures() { + dma_textures(gTextureDksJungleParkwayKiwanoFruit1, 0x0000032FU, 0x00000400U); + dma_textures(gTextureDksJungleParkwayKiwanoFruit2, 0x00000369U, 0x00000400U); + dma_textures(gTextureDksJungleParkwayKiwanoFruit3, 0x00000364U, 0x00000400U); +} + +void DKJungle::SpawnActors() { + spawn_all_item_boxes(d_course_dks_jungle_parkway_item_box_spawns); + init_kiwano_fruit(); + func_80298D10(); +} + +void DKJungle::Init() { } + +// Likely sets minimap boundaries +void DKJungle::MinimapSettings() { + D_8018D2A0 = 0.0155f; + D_8018D2C0[0] = 255; + D_8018D2E0 = 29; + D_8018D2E8 = 47; +} + +void DKJungle::InitCourseObjects() { + for (size_t i = 0; i < NUM_TORCHES; i++) { + init_smoke_particles(i); + // wtf? + if (D_8018CF10) {} + } +} + +void DKJungle::UpdateCourseObjects() { + update_ferries_smoke_particle(); +} + +void DKJungle::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_paddle_boat_smoke_particles(cameraId); + } +} + +void DKJungle::SomeSounds() { + vec3f_set(D_8015F738, -790.0f, -255.0f, -447.0f); + func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); +} + +void DKJungle::WhatDoesThisDo(Player* player, int8_t playerId) { + if ((((s16) gNearestWaypointByPlayerId[playerId] >= 0) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x65)) || + (((s16) gNearestWaypointByPlayerId[playerId] >= 0x14A) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x21F))) { + if (D_80165300[playerId] != 2) { + func_800C8F80(playerId, 0x0170802D); + } + D_80165300[playerId] = 2; + } else { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + if (D_80165300[playerId] == 1) { + func_800CA2B8(playerId); + } + if (D_80165300[playerId] == 2) { + func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x70, 0x80, 0x2D)); + } + D_80165300[playerId] = 0; + } + } + } +} + +void DKJungle::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void DKJungle::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void DKJungle::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void DKJungle::SetStaffGhost() {} + +void DKJungle::BeginPlay() { } +void DKJungle::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + func_802B5D64(&D_800DC610[1], D_802B87D4, D_802B87D0, 1); + + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_dks_jungle_parkway_packed_dl_92D8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x070092D8))); + } + + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + render_course_segments(d_course_dks_jungle_parkway_unknown_dl_list, arg0); + + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); +} + +void DKJungle::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_dks_jungle_parkway_dl_13C30)); +} + +void DKJungle::Collision() {} + +void DKJungle::SpawnVehicles() { + s16 trainCarYRot; + UNUSED Vec3f pad; + TrainCarStuff* tempLocomotive; + TrainCarStuff* tempTender; + TrainCarStuff* tempPassengerCar; + Vec3s trainCarRot; + VehicleStuff* tempBoxTruck; + VehicleStuff* tempSchoolBus; + VehicleStuff* tempTankerTruck; + VehicleStuff* tempCar; + PaddleBoatStuff* tempPaddleWheelBoat; + Vec3s paddleWheelBoatRot; + s32 loopIndex; + s32 loopIndex2; + f32 origXPos; + f32 origZPos; + + for (loopIndex = 0; loopIndex < NUM_ACTIVE_PADDLE_BOATS; loopIndex++) { + tempPaddleWheelBoat = &gPaddleBoats[loopIndex]; + if (tempPaddleWheelBoat->isActive == 1) { + origXPos = tempPaddleWheelBoat->position[0]; + origZPos = tempPaddleWheelBoat->position[2]; + tempPaddleWheelBoat->rotY = update_vehicle_following_waypoint( + tempPaddleWheelBoat->position, (s16*) &tempPaddleWheelBoat->waypointIndex, + tempPaddleWheelBoat->speed); + tempPaddleWheelBoat->velocity[0] = tempPaddleWheelBoat->position[0] - origXPos; + tempPaddleWheelBoat->velocity[2] = tempPaddleWheelBoat->position[2] - origZPos; + vec3s_set(paddleWheelBoatRot, 0, tempPaddleWheelBoat->rotY, 0); + tempPaddleWheelBoat->actorIndex = + add_actor_to_empty_slot(tempPaddleWheelBoat->position, paddleWheelBoatRot, + tempPaddleWheelBoat->velocity, ACTOR_PADDLE_BOAT); + } + } +} + +void DKJungle::UpdateVehicles() { + update_vehicle_paddle_boats(); +} + +void DKJungle::GenerateCollision() { + parse_course_displaylists(d_course_dks_jungle_parkway_addr); + func_80295C6C(); + D_8015F8E4 = -475.0f; + // d_course_dks_jungle_parkway_packed_dl_3FA8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07003FA8), 120, 255, 255, 255); +} + +void DKJungle::Waypoints(Player* player, int8_t playerId) { + s16 waypoint = gNearestWaypointByPlayerId[playerId]; + if ((waypoint >= 0xB9) && (waypoint < 0x119)) { + player->nearestWaypointId = 0xB9U; + } else { + player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } + } +} + +void DKJungle::Destroy() { } diff --git a/src/engine/courses/DKJungle.h b/src/engine/courses/DKJungle.h new file mode 100644 index 000000000..747a7d738 --- /dev/null +++ b/src/engine/courses/DKJungle.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/dks_jungle_parkway_vertices.h" + #include "assets/dks_jungle_parkway_displaylists.h" + #include "assets/dks_jungle_parkway_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture dks_jungle_parkway_textures[]; +} + +class DKJungle : public Course { +public: + virtual ~DKJungle() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit DKJungle(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void SpawnVehicles() override; + virtual void UpdateVehicles() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/DoubleDeck.cpp b/src/engine/courses/DoubleDeck.cpp new file mode 100644 index 000000000..8dd3e1725 --- /dev/null +++ b/src/engine/courses/DoubleDeck.cpp @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#include "DoubleDeck.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/double_deck_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *double_deck_dls[]; + extern s16 currentScreenSection; +} + +DoubleDeck::DoubleDeck() { + this->vtx = d_course_double_deck_vertex; + this->gfx = d_course_double_deck_packed_dls; + this->gfxSize = 699; + this->textures = double_deck_textures; + + Props.Name = "double deck"; + Props.DebugName = "deck"; + Props.CourseLength = ""; + Props.AIBehaviour = D_0D008F18; + Props.AIMaximumSeparation = -1.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 1500.0f; + + Props.PathSizes = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = NULL; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = NULL; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {113, 70, 255}; + Props.Skybox.BottomRight = {255, 184, 99}; + Props.Skybox.BottomLeft = {255, 184, 99}; + Props.Skybox.TopLeft = {113, 70, 255}; + Props.Skybox.FloorTopRight = {255, 224, 240}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {255, 224, 240}; +} + +void DoubleDeck::LoadTextures() { +} + +void DoubleDeck::SpawnActors() {} + +void DoubleDeck::Init() { } + +// Likely sets minimap boundaries +void DoubleDeck::MinimapSettings() { + D_8018D2A0 = 0.0285f; + D_8018D2E0 = 32; + D_8018D2E8 = 32; +} + +void DoubleDeck::InitCourseObjects() {} + +void DoubleDeck::SomeSounds() {} + +void DoubleDeck::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void DoubleDeck::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void DoubleDeck::SpawnBombKarts() {} + +// Positions the finishline on the minimap +void DoubleDeck::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void DoubleDeck::SetStaffGhost() {} + +void DoubleDeck::BeginPlay() { } +void DoubleDeck::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_double_deck_packed_dl_738 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000738))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); +} + +void DoubleDeck::RenderCredits() {} + +void DoubleDeck::Collision() {} + +void DoubleDeck::GenerateCollision() { + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000738), 1); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void DoubleDeck::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = 0; +} + +void DoubleDeck::Destroy() { } diff --git a/src/engine/courses/DoubleDeck.h b/src/engine/courses/DoubleDeck.h new file mode 100644 index 000000000..989f6eec7 --- /dev/null +++ b/src/engine/courses/DoubleDeck.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/double_deck_vertices.h" + #include "assets/double_deck_displaylists.h" + #include "assets/double_deck_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture double_deck_textures[]; +} + +class DoubleDeck : public Course { +public: + virtual ~DoubleDeck() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit DoubleDeck(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp new file mode 100644 index 000000000..01b6a7cc4 --- /dev/null +++ b/src/engine/courses/FrappeSnowland.cpp @@ -0,0 +1,257 @@ +#include +#include +#include +#include + +#include "FrappeSnowland.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/frappe_snowland_data.h" +#include "assets/boo_frames.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + #include "update_objects.h" + extern const char *d_course_frappe_snowland_dl_list[]; + extern s8 gPlayerCount; +} + +FrappeSnowland::FrappeSnowland() { + this->vtx = d_course_frappe_snowland_vertex; + this->gfx = d_course_frappe_snowland_packed_dls; + this->gfxSize = 4140; + this->textures = frappe_snowland_textures; + + Props.Name = "frappe snowland"; + Props.DebugName = "snow"; + Props.CourseLength = "734m"; + Props.AIBehaviour = D_0D0090F8; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x2EE, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_frappe_snowland_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_frappe_snowland_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // not used for frappe + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {28, 11, 90}; + Props.Skybox.BottomRight = {0, 99, 164}; + Props.Skybox.BottomLeft = {0, 9, 164}; + Props.Skybox.TopLeft = {28, 11, 90}; + Props.Skybox.FloorTopRight = {0, 99, 164}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 99, 164}; +} + +void FrappeSnowland::LoadTextures() { + dma_textures(gTextureFrappeSnowlandTreeLeft, 0x00000454U, 0x00000800U); + dma_textures(gTextureFrappeSnowlandTreeRight, 0x00000432U, 0x00000800U); +} + +void FrappeSnowland::SpawnActors() { + spawn_foliage(d_course_frappe_snowland_tree_spawns); + spawn_all_item_boxes(d_course_frappe_snowland_item_box_spawns); +} + +void FrappeSnowland::Init() { } +void FrappeSnowland::InitClouds() { + s32 var_s0; + s32 var_s4; + + if (gPlayerCount == 1) { + var_s4 = 0x32; + } else { + var_s4 = 0x19; + } + for (var_s0 = 0; var_s0 < var_s4; var_s0++) { + find_unused_obj_index(&D_8018CC80[D_8018D1F8 + var_s0]); + } + D_8018D1F8 += var_s0; + D_8018D1F0 = var_s0; +} + +void FrappeSnowland::UpdateClouds(s32 sp1C, Camera* camera) { + func_80078170(sp1C, camera); +} + +// Likely sets minimap boundaries +void FrappeSnowland::MinimapSettings() { + D_8018D2C0[0] = 262; + D_8018D2A0 = 0.016f; + D_8018D2E0 = 36; + D_8018D2E8 = 40; + D_8018D300 = 72; + D_8018D308 = 100; + D_8018D310 = 255; +} + +void FrappeSnowland::InitCourseObjects() { + size_t objectId; + size_t i; + for (i = 0; i < NUM_SNOWFLAKES; i++) { + find_unused_obj_index(&gObjectParticle1[i]); + } + if (gGamestate != CREDITS_SEQUENCE) { + for (i = 0; i < NUM_SNOWMEN; i++) { + objectId = indexObjectList2[i]; + init_object(objectId, 0); + gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; + gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 5.0 + 3.0; + gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; + objectId = indexObjectList1[i]; + init_object(objectId, 0); + gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; + gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 3.0; + gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; + gObjectList[objectId].unk_0D5 = gSnowmanSpawns[i].unk_6; + } + } +} + +void FrappeSnowland::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + update_snowmen(); + } + update_snowflakes(); +} + +void FrappeSnowland::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_snowmans(cameraId); + } +} + +void FrappeSnowland::SomeSounds() { +} + +void FrappeSnowland::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void FrappeSnowland::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void FrappeSnowland::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void FrappeSnowland::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void FrappeSnowland::SetStaffGhost() { +} + +void FrappeSnowland::BeginPlay() { } + +void FrappeSnowland::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_frappe_snowland_packed_dl_65E0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x070065E0))); + } + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + render_course_segments(d_course_frappe_snowland_dl_list, arg0); +} + +void FrappeSnowland::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_frappe_snowland_dl_76A0)); +} + +void FrappeSnowland::Collision() {} + +void FrappeSnowland::GenerateCollision() { + parse_course_displaylists(d_course_frappe_snowland_addr); + func_80295C6C(); + D_8015F8E4 = -50.0f; +} + +void FrappeSnowland::Waypoints(Player* player, int8_t playerId) { + s16 waypoint = gNearestWaypointByPlayerId[playerId]; + + if ((waypoint >= 0xF0) && (waypoint < 0x105)) { + player->nearestWaypointId = 0xF0U; + } else { + player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } + } +} + +void FrappeSnowland::Water() {} + +void FrappeSnowland::Destroy() {} diff --git a/src/engine/courses/FrappeSnowland.h b/src/engine/courses/FrappeSnowland.h new file mode 100644 index 000000000..cc9af2f3e --- /dev/null +++ b/src/engine/courses/FrappeSnowland.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/frappe_snowland_vertices.h" + #include "assets/frappe_snowland_displaylists.h" + #include "assets/frappe_snowland_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture frappe_snowland_textures[]; +} + +class FrappeSnowland : public Course { +public: + virtual ~FrappeSnowland() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit FrappeSnowland(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void InitClouds() override; + virtual void UpdateClouds(s32 sp1C, Camera* camera) override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Water() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp new file mode 100644 index 000000000..625cba353 --- /dev/null +++ b/src/engine/courses/KalimariDesert.cpp @@ -0,0 +1,316 @@ +#include +#include +#include +#include + +#include "KalimariDesert.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "kalimari_desert_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *kalimari_desert_dls[]; +} + +KalimariDesert::KalimariDesert() { + this->vtx = d_course_kalimari_desert_vertex; + this->gfx = d_course_kalimari_desert_packed_dls; + this->gfxSize = 5328; + this->textures = kalimari_desert_textures; + + Props.Name = "kalimari desert"; + Props.DebugName = "desert"; + Props.CourseLength = "753m"; + Props.AIBehaviour = D_0D009260; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 10.0f; + Props.FarPersp = 7000.0f; + + Props.PathSizes = {0x2BC, 1, 1, 1, 0x226, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_kalimari_desert_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_kalimari_desert_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gKalimariDesertClouds; + Props.CloudList = gKalimariDesertClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {195, 231, 255}; + Props.Skybox.BottomRight = {255, 192, 0}; + Props.Skybox.BottomLeft = {255, 192, 0}; + Props.Skybox.TopLeft = {195, 231, 255}; + Props.Skybox.FloorTopRight = {255, 192, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {255, 192, 0}; +} + +void KalimariDesert::LoadTextures() { + dma_textures(gTextureCactus1Left, 0x0000033EU, 0x00000800U); + dma_textures(gTextureCactus1Right, 0x000002FBU, 0x00000800U); + dma_textures(gTextureCactus2Left, 0x000002A8U, 0x00000800U); + dma_textures(gTextureCactus2Right, 0x00000374U, 0x00000800U); + dma_textures(gTextureCactus3, 0x000003AFU, 0x00000800U); +} + +void KalimariDesert::SpawnActors() { + struct RailroadCrossing* rrxing; + Vec3f position; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3s rotation = { 0, 0, 0 }; + + spawn_foliage(d_course_kalimari_desert_cactus_spawn); + spawn_all_item_boxes(d_course_kalimari_desert_item_box_spawns); + vec3f_set(position, -1680.0f, 2.0f, 35.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)]; + rrxing->crossingId = 1; + vec3f_set(position, -1600.0f, 2.0f, 35.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)]; + rrxing->crossingId = 1; + vec3s_set(rotation, 0, -0x2000, 0); + vec3f_set(position, -2459.0f, 2.0f, 2263.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)]; + rrxing->crossingId = 0; + vec3f_set(position, -2467.0f, 2.0f, 2375.0f); + position[0] *= gCourseDirection; + rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)]; + rrxing->crossingId = 0; +} + +void KalimariDesert::Init() {} + +// Likely sets minimap boundaries +void KalimariDesert::MinimapSettings() { + D_8018D2C0[0] = 263; + D_8018D2D8[0] = 165; + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); + D_8018D2A0 = 0.015f; + D_8018D2E0 = 55; + D_8018D2E8 = 27; +} + +void KalimariDesert::InitCourseObjects() { + size_t i; + if (gGamestate != CREDITS_SEQUENCE) { + find_unused_obj_index(&D_8018CF10); + init_object(D_8018CF10, 0); + for (i = 0; i < 50; i++) { + find_unused_obj_index(&gObjectParticle1[i]); + } + for (i = 0; i < 5; i++) { + find_unused_obj_index(&gObjectParticle2[i]); + } + for (i = 0; i < 32; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + } + } +} + +void KalimariDesert::UpdateCourseObjects() { + update_train_smoke(); +} + +void KalimariDesert::RenderCourseObjects(s32 cameraId) { + render_object_trains_smoke_particles(cameraId); +} + +void KalimariDesert::SomeSounds() {} + +void KalimariDesert::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void KalimariDesert::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void KalimariDesert::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void KalimariDesert::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void KalimariDesert::SetStaffGhost() {} + +void KalimariDesert::SpawnVehicles() { + s16 trainCarYRot; + UNUSED Vec3f pad; + TrainCarStuff* tempLocomotive; + TrainCarStuff* tempTender; + TrainCarStuff* tempPassengerCar; + Vec3s trainCarRot; + VehicleStuff* tempBoxTruck; + VehicleStuff* tempSchoolBus; + VehicleStuff* tempTankerTruck; + VehicleStuff* tempCar; + PaddleBoatStuff* tempPaddleWheelBoat; + Vec3s paddleWheelBoatRot; + s32 loopIndex; + s32 loopIndex2; + f32 origXPos; + f32 origZPos; + + for (loopIndex = 0; loopIndex < NUM_TRAINS; loopIndex++) { + tempLocomotive = &gTrainList[loopIndex].locomotive; + origXPos = tempLocomotive->position[0]; + origZPos = tempLocomotive->position[2]; + trainCarYRot = update_vehicle_following_waypoint( + tempLocomotive->position, (s16*) &tempLocomotive->waypointIndex, gTrainList[loopIndex].speed); + tempLocomotive->velocity[0] = tempLocomotive->position[0] - origXPos; + tempLocomotive->velocity[2] = tempLocomotive->position[2] - origZPos; + vec3s_set(trainCarRot, 0, trainCarYRot, 0); + tempLocomotive->actorIndex = add_actor_to_empty_slot(tempLocomotive->position, trainCarRot, + tempLocomotive->velocity, ACTOR_TRAIN_ENGINE); + + tempTender = &gTrainList[loopIndex].tender; + if (tempTender->isActive == 1) { + origXPos = tempTender->position[0]; + origZPos = tempTender->position[2]; + trainCarYRot = update_vehicle_following_waypoint( + tempTender->position, (s16*) &tempTender->waypointIndex, gTrainList[loopIndex].speed); + tempTender->velocity[0] = tempTender->position[0] - origXPos; + tempTender->velocity[2] = tempTender->position[2] - origZPos; + vec3s_set(trainCarRot, 0, trainCarYRot, 0); + tempTender->actorIndex = add_actor_to_empty_slot(tempTender->position, trainCarRot, + tempTender->velocity, ACTOR_TRAIN_TENDER); + } + + for (loopIndex2 = 0; loopIndex2 < NUM_PASSENGER_CAR_ENTRIES; loopIndex2++) { + tempPassengerCar = &gTrainList[loopIndex].passengerCars[loopIndex2]; + if (tempPassengerCar->isActive == 1) { + origXPos = tempPassengerCar->position[0]; + origZPos = tempPassengerCar->position[2]; + trainCarYRot = update_vehicle_following_waypoint(tempPassengerCar->position, + (s16*) &tempPassengerCar->waypointIndex, + gTrainList[loopIndex].speed); + tempPassengerCar->velocity[0] = tempPassengerCar->position[0] - origXPos; + tempPassengerCar->velocity[2] = tempPassengerCar->position[2] - origZPos; + vec3s_set(trainCarRot, 0, trainCarYRot, 0); + tempPassengerCar->actorIndex = + add_actor_to_empty_slot(tempPassengerCar->position, trainCarRot, tempPassengerCar->velocity, + ACTOR_TRAIN_PASSENGER_CAR); + } + } + } +} + +void KalimariDesert::UpdateVehicles() { + update_vehicle_trains(); +} + +void KalimariDesert::BeginPlay() { } +void KalimariDesert::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_kalimari_desert_packed_dl_71C8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x070071C8))); + } + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + render_course_segments(kalimari_desert_dls, arg0); + // d_course_kalimari_desert_packed_dl_1ED8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07001ED8))); + // d_course_kalimari_desert_packed_dl_1B18 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07001B18))); + // d_course_kalimari_desert_packed_dl_8330 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07008330))); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + // d_course_kalimari_desert_packed_dl_998 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000998))); + // d_course_kalimari_desert_packed_dl_270 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000270))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); +} + +void KalimariDesert::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_kalimari_desert_dl_22E00)); +} + +void KalimariDesert::Collision() {} + +void KalimariDesert::GenerateCollision() { + parse_course_displaylists(d_course_kalimari_desert_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void KalimariDesert::Destroy() { } diff --git a/src/engine/courses/KalimariDesert.h b/src/engine/courses/KalimariDesert.h new file mode 100644 index 000000000..09baf9265 --- /dev/null +++ b/src/engine/courses/KalimariDesert.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/kalimari_desert_vertices.h" + #include "assets/kalimari_desert_displaylists.h" + #include "assets/kalimari_desert_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture kalimari_desert_textures[]; +} + +class KalimariDesert : public Course { +public: + virtual ~KalimariDesert() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit KalimariDesert(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void SpawnVehicles() override; + virtual void UpdateVehicles() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp new file mode 100644 index 000000000..d22c8da35 --- /dev/null +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -0,0 +1,282 @@ +#include +#include +#include +#include + +#include "KoopaTroopaBeach.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/koopa_troopa_beach_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *koopa_troopa_beach_dls[]; + extern s8 gPlayerCount; +} + +KoopaTroopaBeach::KoopaTroopaBeach() { + this->vtx = d_course_koopa_troopa_beach_vertex; + this->gfx = d_course_koopa_troopa_beach_packed_dls; + this->gfxSize = 5720; + this->textures = koopa_troopa_beach_textures; + + Props.Id = "mk:koopa_beach"; + Props.Name = "koopa troopa beach"; + Props.DebugName = "beach"; + Props.CourseLength = "691m"; + Props.AIBehaviour = D_0D009158; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 1.0f; + Props.FarPersp = 5000.0f; + + Props.PathSizes = {0x2BC, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_koopa_troopa_beach_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_koopa_troopa_beach_track_waypoints; + Props.PathTable2[1] = d_course_koopa_troopa_beach_track_waypoints_2; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gKoopaTroopaBeachClouds; + Props.CloudList = gKoopaTroopaBeachClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {48, 152, 120}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {48, 152, 120}; + Props.Skybox.FloorTopRight = {48, 152, 120}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {48, 152, 120}; +} + +void KoopaTroopaBeach::LoadTextures() { +} + +void KoopaTroopaBeach::SpawnActors() { + init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f); + spawn_all_item_boxes(d_course_koopa_troopa_beach_item_box_spawns); + spawn_palm_trees(d_course_koopa_troopa_beach_tree_spawn); +} + +void KoopaTroopaBeach::Init() {} + +// Likely sets minimap boundaries +void KoopaTroopaBeach::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust3, 0x3C8U, 0x1000)); + D_8018D2A0 = 0.014f; + D_8018D2C0[0] = 268; + D_8018D2E0 = 40; + D_8018D2E8 = 21; +} + +void KoopaTroopaBeach::InitCourseObjects() { + size_t objectId; + size_t i; + + if (gGamestate != CREDITS_SEQUENCE) { + for (i = 0; i < NUM_CRABS; i++) { + objectId = indexObjectList1[i]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = + gCrabSpawns[i].startX * xOrientation; + gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; + + gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; + gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; + } + } + for (i = 0; i < NUM_SEAGULLS; i++) { + objectId = indexObjectList2[i]; + init_object(objectId, 0); + if (i < (NUM_SEAGULLS / 2)) { + gObjectList[objectId].unk_0D5 = 0; + } else { + gObjectList[objectId].unk_0D5 = 1; + } + } +} + +void KoopaTroopaBeach::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + update_crabs(); + } + if ((gPlayerCount == 1) || (gPlayerCount == 2) || (gGamestate == CREDITS_SEQUENCE)) { + update_seagulls(); + } +} + +void KoopaTroopaBeach::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_crabs(cameraId); + } + if (gGamestate != CREDITS_SEQUENCE) { + + if ((gPlayerCount == 1) || (gPlayerCount == 2)) { + render_object_seagulls(cameraId); + } + } else { + render_object_seagulls(cameraId); + } +} + +void KoopaTroopaBeach::SomeSounds() { + vec3f_set(D_8015F738, 153.0f, 0.0f, 2319.0f); + func_800C9D80(D_8015F738, D_802B91C8, 0x51028001); +} + +void KoopaTroopaBeach::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void KoopaTroopaBeach::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void KoopaTroopaBeach::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void KoopaTroopaBeach::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void KoopaTroopaBeach::SetStaffGhost() { +} + +void KoopaTroopaBeach::BeginPlay() { } + +void KoopaTroopaBeach::Render(struct UnkStruct_800DC5EC* arg0) { + gDPPipeSync(gDisplayListHead++); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_koopa_troopa_beach_packed_dl_9CC0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07009CC0))); + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_koopa_troopa_beach_packed_dl_9688 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x07009688))); + render_course_segments((const char**)d_course_koopa_troopa_beach_dl_list1, arg0); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + // d_course_koopa_troopa_beach_packed_dl_2C0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(reinterpret_cast(0x070002C0))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPPipeSync(gDisplayListHead++); +} + +void KoopaTroopaBeach::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_koopa_troopa_beach_dl_18D68)); +} + +void KoopaTroopaBeach::Collision() {} + +void KoopaTroopaBeach::GenerateCollision() { + parse_course_displaylists(d_course_koopa_troopa_beach_addr); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x0700ADE0)), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x0700A540)), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07009E70)), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000358), -0x6A, 255, 255, 255); +} + +void KoopaTroopaBeach::Water() { + // clang-format off + if (D_8015F8E8 < 0.0f) { + if (D_8015F8E4 < -20.0f) { D_8015F8E8 *= -1.0f; } + } else { + if (D_8015F8E4 > 0.0f) { D_8015F8E8 *= -1.0f; } + } + // clang-format on + D_8015F8E4 += D_8015F8E8; + + D_802B87BC += 9; + if (D_802B87BC > 255) { + D_802B87BC = 0; + } + D_802B87C4 += 3; + if (D_802B87C4 > 255) { + D_802B87C4 = 0; + } + // waterfall animation + // d_course_koopa_troopa_beach_packed_dl_9D58 + find_and_set_tile_size((uintptr_t)segmented_gfx_to_virtual(reinterpret_cast(0x07009D58)), 0, D_802B87BC); + // d_course_koopa_troopa_beach_packed_dl_9CD0 + find_and_set_tile_size((uintptr_t)segmented_gfx_to_virtual(reinterpret_cast(0x07009CD0)), 0, D_802B87C4); + D_802B87CC = random_int(300) / 40; + if (D_802B87C8 < 0) { + D_802B87C8 = random_int(300) / 40; + } else { + D_802B87C8 = -(random_int(300) / 40); + } + // Waterfall bubbling effect? (unused) + // d_course_koopa_troopa_beach_packed_dl_2E8 + find_and_set_tile_size((uintptr_t)segmented_gfx_to_virtual(reinterpret_cast(0x070002E8)), D_802B87C8, D_802B87CC); + +} + +void KoopaTroopaBeach::Destroy() {} diff --git a/src/engine/courses/KoopaTroopaBeach.h b/src/engine/courses/KoopaTroopaBeach.h new file mode 100644 index 000000000..df4c77f9f --- /dev/null +++ b/src/engine/courses/KoopaTroopaBeach.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/koopa_troopa_beach_vertices.h" + #include "assets/koopa_troopa_beach_displaylists.h" + #include "assets/koopa_troopa_beach_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture koopa_troopa_beach_textures[]; +} + +class KoopaTroopaBeach : public Course { +public: + virtual ~KoopaTroopaBeach() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit KoopaTroopaBeach(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Water() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp new file mode 100644 index 000000000..79e7cadb0 --- /dev/null +++ b/src/engine/courses/LuigiRaceway.cpp @@ -0,0 +1,337 @@ +#include +#include +#include +#include + +#include "LuigiRaceway.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/luigi_raceway_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *luigi_raceway_dls[]; + extern s16 currentScreenSection; +} + +LuigiRaceway::LuigiRaceway() { + this->vtx = d_course_luigi_raceway_vertex; + this->gfx = d_course_luigi_raceway_packed_dls; + this->gfxSize = 6377; + this->textures = luigi_raceway_textures; + + Props.Id = "mk:luigi_raceway"; + Props.Name = "luigi raceway"; + Props.DebugName = "l circuit"; + Props.CourseLength = "717m"; + Props.AIBehaviour = D_0D0091E8; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.7f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 48; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x2DA, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_luigi_raceway_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_luigi_raceway_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gLuigiRacewayClouds; + Props.CloudList = gLuigiRacewayClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {128, 184, 248}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {128, 184, 248}; + Props.Skybox.FloorTopRight = {216, 232, 248}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {216, 232, 248}; +} + +void LuigiRaceway::LoadTextures() { + dma_textures(gTextureTrees5Left, 0x000003E8U, 0x00000800U); + dma_textures(gTextureTrees5Right, 0x000003E8U, 0x00000800U); +} + +void LuigiRaceway::SpawnActors() { + spawn_foliage(d_course_luigi_raceway_tree_spawn); + spawn_all_item_boxes(d_course_luigi_raceway_item_box_spawns); +} + +void LuigiRaceway::Init() {} + +// Likely sets minimap boundaries +void LuigiRaceway::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust2, 0x4F4U, 0xC00)); + D_8018D2A0 = 0.0155f; + D_8018D2C0[0] = 271; + D_8018D2E0 = 45; + D_8018D2E8 = 60; + D_80165718 = -140; + D_80165720 = -44; + D_80165728 = -215; +} + +void LuigiRaceway::InitCourseObjects() { + size_t i; + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == GRAND_PRIX) { + func_80070714(); + } + D_80165898 = 0; + init_object(indexObjectList1[0], 0); + for (i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + } +} + +void LuigiRaceway::UpdateCourseObjects() { + if (D_80165898 != 0) { + update_hot_air_balloon(); + } +} + +void LuigiRaceway::RenderCourseObjects(s32 cameraId) { + if (D_80165898 != 0) { + render_object_hot_air_balloon(cameraId); + } +} + +void LuigiRaceway::SomeSounds() { + vec3f_set(D_8015F748, 85.0f, 21.0f, -219.0f); + func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); +} + +void LuigiRaceway::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void LuigiRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void LuigiRaceway::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void LuigiRaceway::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void LuigiRaceway::SetStaffGhost() { + u32 temp_v0 = func_800B4E24(0) & 0xfffff; + if (temp_v0 <= 11200) { + D_80162DD6 = 0; + D_80162DF4 = 0; + } else { + D_80162DD6 = 1; + D_80162DF4 = 1; + } + D_80162DC4 = d_luigi_raceway_staff_ghost; + D_80162DE4 = 1; +} + +void LuigiRaceway::BeginPlay() {} + +void LuigiRaceway::Render(struct UnkStruct_800DC5EC* arg0) { + UNUSED s32 pad; + u16 sp22 = (u16) arg0->pathCounter; + s16 prevFrame; + + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_luigi_raceway_packed_dl_9EC0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07009EC0)))); + } + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + + render_course_segments(luigi_raceway_dls, arg0); + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + // d_course_luigi_raceway_packed_dl_E0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070000E0)))); + // d_course_luigi_raceway_packed_dl_68 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07000068)))); + + D_800DC5DC = 88; + D_800DC5E0 = 72; + + // Render only the first player camera onto the television billboard. Screen agnostic screens of other players). + if ((gActiveScreenMode == SCREEN_MODE_1P) && (sp22 >= 10) && (sp22 < 17)) { + + prevFrame = (s16) sRenderedFramebuffer - 1; + + if (prevFrame < 0) { + prevFrame = 2; + } else if (prevFrame >= 3) { + prevFrame = 0; + } + currentScreenSection++; + if (currentScreenSection >= 6) { + currentScreenSection = 0; + } + + u16* fb = (u16*) gSegmentTable[5] + 0xF800; + + // FB_WriteFramebufferSliceToCPU(gDisplayListHead, fb, true); + // FB_DrawFromFramebuffer(gDisplayListHead, 0, fb, true); + // FB_CopyToFramebuffer(gDisplayListHead, 0, fb, false, NULL); + /** + * The jumbo television screen is split into six sections each section is copied one at a time. + * This is done to fit within the n64's texture size requirements; 64x32 + */ + switch (currentScreenSection) { + case 0: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xF800)); +#endif + break; + case 1: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x10800)); +#endif + break; + case 2: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0 + 32, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x11800)); +#endif + break; + case 3: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 32, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x12800)); +#endif + break; + case 4: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0 + 64, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x13800)); +#endif + break; + case 5: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 64, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x14800)); +#endif + break; + } + } +} + +void LuigiRaceway::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_luigi_raceway_dl_FD40)); +} + +void LuigiRaceway::Collision() {} + +void LuigiRaceway::GenerateCollision() { + parse_course_displaylists(d_course_luigi_raceway_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void LuigiRaceway::Destroy() { } diff --git a/src/engine/courses/LuigiRaceway.h b/src/engine/courses/LuigiRaceway.h new file mode 100644 index 000000000..7bab671b7 --- /dev/null +++ b/src/engine/courses/LuigiRaceway.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/luigi_raceway_vertices.h" + #include "assets/luigi_raceway_displaylists.h" + #include "assets/luigi_raceway_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture luigi_raceway_textures[]; +} + +class LuigiRaceway : public Course { +public: + virtual ~LuigiRaceway() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit LuigiRaceway(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp new file mode 100644 index 000000000..575c6300b --- /dev/null +++ b/src/engine/courses/MarioRaceway.cpp @@ -0,0 +1,354 @@ +#include +#include +#include +#include + +#include "MarioRaceway.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "mario_raceway_data.h" + #include "collision.h" + #include "memory.h" + extern const char *mario_raceway_dls[]; +} + +MarioRaceway::MarioRaceway() { + this->vtx = d_course_mario_raceway_vertex; + this->gfx = d_course_mario_raceway_packed_dls; + this->gfxSize = 3367; + this->textures = mario_raceway_textures; + + Props.Id = "mk:mario_raceway"; + Props.Name = "Mario Raceway"; + Props.DebugName = "m circuit"; + Props.CourseLength = "567m"; + + Props.AIBehaviour = D_0D008F28; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCB34; + Props.AISteeringSensitivity = 48; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {600, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_mario_raceway_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_mario_raceway_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gKalimariDesertClouds; + Props.CloudList = gLuigiRacewayClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 184, 248}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {0, 184, 248}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void MarioRaceway::LoadTextures() { + dma_textures(gTextureTrees1, 0x0000035BU, 0x00000800U); + D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant2, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant3, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant4, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant5, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant6, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant7, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant8, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); +} + +void MarioRaceway::SpawnActors() { + struct Actor* actor; + Vec3f position; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3s rotation = { 0, 0, 0 }; + spawn_foliage(d_course_mario_raceway_tree_spawns); + spawn_piranha_plants(d_course_mario_raceway_piranha_plant_spawns); + spawn_all_item_boxes(d_course_mario_raceway_item_box_spawns); + vec3f_set(position, 150.0f, 40.0f, -1300.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); + vec3f_set(position, 2520.0f, 0.0f, 1240.0f); + position[0] *= gCourseDirection; + actor = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)]; + actor->flags |= 0x4000; +} + +void MarioRaceway::Init() {} + +// Likely sets minimap boundaries +void MarioRaceway::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); + D_8018D2A0 = 0.022f; + D_8018D2E0 = 6; + D_8018D2E8 = 28; + D_8018D2C0[0] = 260; + D_8018D2D8[0] = 170; + D_80165718 = 0; + D_80165720 = 5; + D_80165728 = -240; +} + +void MarioRaceway::InitCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == GRAND_PRIX) { + func_80070714(); + } + for (size_t i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + } +} + +void MarioRaceway::SomeSounds() { + vec3f_set(D_8015F748, -223.0f, 94.0f, -155.0f); + func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); +} + +void MarioRaceway::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void MarioRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void MarioRaceway::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void MarioRaceway::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void MarioRaceway::SetStaffGhost() { + u32 temp_v0 = func_800B4E24(0) & 0xfffff; + if (temp_v0 <= 9000) { + D_80162DD6 = 0; + D_80162DF4 = 0; + } else { + D_80162DD6 = 1; + D_80162DF4 = 1; + } + D_80162DC4 = d_mario_raceway_staff_ghost; + D_80162DE4 = 0; +} + +void MarioRaceway::BeginPlay() { } +void MarioRaceway::Render(struct UnkStruct_800DC5EC* arg0) { + u16 sp22 = arg0->pathCounter; + u16 temp_t0 = arg0->playerDirection; + + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_mario_raceway_packed_dl_3050 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07003050)))); + } + + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + gDPPipeSync(gDisplayListHead++); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + + switch (sp22) { + case 1: + case 2: + case 17: + if ((temp_t0 == 2) || (temp_t0 == 1)) { + func_802911C4(); + } + break; + case 3: + if (temp_t0 != 0) { + func_802911C4(); + } + break; + case 4: + if (temp_t0 == 0) { + func_80291198(); + } else { + if (temp_t0 == 1) { + func_80291198(); + } + func_802911C4(); + } + break; + case 5: + case 6: + if ((temp_t0 == 2) || (temp_t0 == 3)) { + func_802911C4(); + } else { + func_80291198(); + } + break; + case 7: + func_80291198(); + if ((temp_t0 == 2) || (temp_t0 == 3)) { + func_802911C4(); + } + break; + case 8: + case 9: + if (temp_t0 != 1) { + func_802911C4(); + } + /* fallthrough */ + case 10: + if (temp_t0 != 2) { + func_80291198(); + } + break; + case 11: + if (temp_t0 == 0) { + func_802911C4(); + func_80291198(); + } else if (temp_t0 == 3) { + func_802911C4(); + } + break; + case 12: + if ((temp_t0 == 0) || (temp_t0 == 3)) { + func_802911C4(); + } + break; + case 13: + case 14: + if (temp_t0 != 1) { + case 15: + case 16: + func_802911C4(); + } + break; + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07003508)))); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07003240)))); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070014A0)))); + render_course_segments(mario_raceway_dls, arg0); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07000450)))); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07000240)))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070000E0)))); + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x07000160)))); +} + +void MarioRaceway::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_mario_raceway_dl_9348)); +} + +void MarioRaceway::Collision() {} + +void MarioRaceway::GenerateCollision() { + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07001140))); + if (gScreenModeSelection == SCREEN_MODE_1P) { + // d_course_mario_raceway_packed_dl_8E8 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x070008E8))); + } else { + // d_course_mario_raceway_packed_dl_2D68 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07002D68))); + } + + parse_course_displaylists(d_course_mario_raceway_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void MarioRaceway::Destroy() { } diff --git a/src/engine/courses/MarioRaceway.h b/src/engine/courses/MarioRaceway.h new file mode 100644 index 000000000..9c4f94b24 --- /dev/null +++ b/src/engine/courses/MarioRaceway.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "mario_raceway_vertices.h" + #include "mario_raceway_displaylists.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + #include "mario_raceway_data.h" + extern const course_texture mario_raceway_textures[]; +} + +class MarioRaceway : public Course { +public: + virtual ~MarioRaceway() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit MarioRaceway(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp new file mode 100644 index 000000000..75d7c0dc5 --- /dev/null +++ b/src/engine/courses/MooMooFarm.cpp @@ -0,0 +1,348 @@ +#include +#include +#include +#include + +#include "MooMooFarm.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/moo_moo_farm_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + #include "code_80086E70.h" + extern const char *moo_moo_farm_dls[]; + extern s16 currentScreenSection; + extern s8 gPlayerCount; +} + +MooMooFarm::MooMooFarm() { + this->vtx = d_course_moo_moo_farm_vertex; + this->gfx = d_course_moo_moo_farm_packed_dls; + this->gfxSize = 3304; + this->textures = moo_moo_farm_textures; + + Props.Name = "moo moo farm"; + Props.DebugName = "farm"; + Props.CourseLength = "527m"; + Props.AIBehaviour = D_0D009210; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 48; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x230, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_moo_moo_farm_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_moo_moo_farm_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gYoshiValleyMooMooFarmClouds; + Props.CloudList = gYoshiValleyMooMooFarmClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 18, 255}; + Props.Skybox.BottomRight = {197, 211, 255}; + Props.Skybox.BottomLeft = {197, 211, 255}; + Props.Skybox.TopLeft = {0, 18, 255}; + Props.Skybox.FloorTopRight = {255, 184, 99}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {255, 184, 99}; +} + +void MooMooFarm::LoadTextures() { + dma_textures(gTextureTrees4Left, 0x000003E8U, 0x00000800U); + dma_textures(gTextureTrees4Right, 0x000003E8U, 0x00000800U); + dma_textures(gTextureCow01Left, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow01Right, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow02Left, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow02Right, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow03Left, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow03Right, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow04Left, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow04Right, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow05Left, 0x00000400U, 0x00000800U); + dma_textures(gTextureCow05Right, 0x00000400U, 0x00000800U); +} + +void MooMooFarm::SpawnActors() { + if (gPlayerCountSelection1 != 4) { + spawn_foliage(d_course_moo_moo_farm_tree_spawn); + } + spawn_all_item_boxes(d_course_moo_moo_farm_item_box_spawns); +} + +void MooMooFarm::Init() {} + +// Likely sets minimap boundaries +void MooMooFarm::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust0, 0x479, 0xC00)); + D_8018D2A0 = 0.0155f; + D_8018D2C0[0] = 271; + D_8018D2E0 = 18; + D_8018D2E8 = 36; +} + +void MooMooFarm::InitCourseObjects() { + size_t objectId; + size_t i; + if (gGamestate != CREDITS_SEQUENCE) { + if ((gPlayerCount == 1) || ((gPlayerCount == 2) && (gModeSelection == VERSUS))) { + switch (gCCSelection) { /* switch 2; irregular */ + case CC_50: /* switch 2 */ + D_8018D1C8 = 4; + D_8018D1D0 = 6; + D_8018D1D8 = 6; + break; + case CC_100: /* switch 2 */ + D_8018D1C8 = 5; + D_8018D1D0 = 8; + D_8018D1D8 = 8; + break; + case CC_150: /* switch 2 */ + D_8018D1C8 = 5; + D_8018D1D0 = 8; + D_8018D1D8 = 10; + break; + case CC_EXTRA: /* switch 2 */ + D_8018D1C8 = 5; + D_8018D1D0 = 8; + D_8018D1D8 = 8; + break; + } + } else { + D_8018D1C8 = 4; + D_8018D1D0 = 6; + D_8018D1D8 = 6; + } + for (i = 0; i < NUM_GROUP1_MOLES; i++) { + D_8018D198[i] = 0; + find_unused_obj_index(&indexObjectList1[i]); + } + for (i = 0; i < NUM_GROUP2_MOLES; i++) { + D_8018D1A8[i] = 0; + find_unused_obj_index(&indexObjectList1[i]); + } + for (i = 0; i < NUM_GROUP3_MOLES; i++) { + D_8018D1B8[i] = 0; + find_unused_obj_index(&indexObjectList1[i]); + } + for (i = 0; i < NUM_TOTAL_MOLES; i++) { + find_unused_obj_index(&gObjectParticle1[i]); + objectId = gObjectParticle1[i]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; + gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; + func_800887C0(objectId); + gObjectList[objectId].sizeScaling = 0.7f; + } + for (i = 0; i < gObjectParticle2_SIZE; i++) { + find_unused_obj_index(&gObjectParticle2[i]); + } + } +} + +void MooMooFarm::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + update_moles(); + } +} + +void MooMooFarm::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_moles(cameraId); + } +} + +void MooMooFarm::SomeSounds() {} + +void MooMooFarm::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void MooMooFarm::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void MooMooFarm::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void MooMooFarm::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void MooMooFarm::SetStaffGhost() {} + +void MooMooFarm::BeginPlay() {} + +void MooMooFarm::Render(struct UnkStruct_800DC5EC* arg0) { + s16 temp_s0 = arg0->pathCounter; + s16 temp_s1 = arg0->playerDirection; + + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_moo_moo_farm_packed_dl_4DF8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07004DF8)); + // d_course_moo_moo_farm_packed_dl_5640 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07005640)); + gSPFogPosition(gDisplayListHead++, D_802B87B0, D_802B87B4); + + render_course_segments(moo_moo_farm_dls, arg0); + + if ((temp_s0 < 14) && (temp_s0 > 10)) { + if ((temp_s1 == 2) || (temp_s1 == 3) || (temp_s1 == 1)) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_13FF8); + } + + } else if (temp_s0 < 16) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_13FF8); + } else if (temp_s0 < 19) { + if (temp_s1 != 2) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_13FF8); + } + + } else if (temp_s0 < 20) { + if (temp_s1 == 0) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_13FF8); + } + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + + if ((temp_s0 >= 16) && (temp_s0 < 24)) { + if ((temp_s1 == 2) || (temp_s1 == 3)) { + // d_course_moo_moo_farm_packed_dl_5410 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07005410)); + } + + } else if (temp_s0 < 9) { + if (temp_s1 == 2) { + // d_course_moo_moo_farm_packed_dl_5410 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07005410)); + } + } + if (temp_s0 < 4) { + if (temp_s1 != 0) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_14060); + } + + } else if (temp_s0 < 8) { + if (temp_s1 == 2) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_14060); + } + + } else if (temp_s0 >= 22) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_14060); + } else if (temp_s0 >= 18) { + if ((temp_s1 == 0) || (temp_s1 == 3)) { + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_moo_moo_farm_dl_14060); + } + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + // d_course_moo_moo_farm_packed_dl_10C0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070010C0)); +} + +void MooMooFarm::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_moo_moo_farm_dl_14088)); +} + +void MooMooFarm::Collision() {} + +void MooMooFarm::GenerateCollision() { + parse_course_displaylists(d_course_moo_moo_farm_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void MooMooFarm::Destroy() { } diff --git a/src/engine/courses/MooMooFarm.h b/src/engine/courses/MooMooFarm.h new file mode 100644 index 000000000..70c3f51b2 --- /dev/null +++ b/src/engine/courses/MooMooFarm.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/moo_moo_farm_vertices.h" + #include "assets/moo_moo_farm_displaylists.h" + #include "assets/moo_moo_farm_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture moo_moo_farm_textures[]; +} + +class MooMooFarm : public Course { +public: + virtual ~MooMooFarm() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit MooMooFarm(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp new file mode 100644 index 000000000..ab641524a --- /dev/null +++ b/src/engine/courses/PodiumCeremony.cpp @@ -0,0 +1,241 @@ +#include +#include +#include +#include + +#include "PodiumCeremony.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/royal_raceway_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *royal_raceway_dls[]; +} + +PodiumCeremony::PodiumCeremony() { + this->vtx = d_course_royal_raceway_vertex; + this->gfx = d_course_royal_raceway_packed_dls; + this->gfxSize = 5670; + this->textures = royal_raceway_textures; + + Props.Name = "royal raceway"; + Props.DebugName = "p circuit"; + Props.CourseLength = "1025m"; + Props.AIBehaviour = D_0D009188; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.4f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.PathSizes = {0x3E8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_royal_raceway_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_royal_raceway_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {238, 144, 255}; + Props.Skybox.BottomRight = {255, 224, 240}; + Props.Skybox.BottomLeft = {255, 224, 240}; + Props.Skybox.TopLeft = {238, 144, 255}; + Props.Skybox.FloorTopRight = {255, 224, 240}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {255, 224, 240}; +} + +void PodiumCeremony::LoadTextures() { +} + +void PodiumCeremony::SpawnActors() { + spawn_foliage(d_course_royal_raceway_tree_spawn); + spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns); + spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn); +} + +void PodiumCeremony::Init() { } + +// Likely sets minimap boundaries +void PodiumCeremony::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust4, 0x3F8, 0x1000)); + D_8018D2C0[0] = 262; + D_8018D2A0 = 0.014f; + D_8018D2E0 = 37; + D_8018D2E8 = 50; + D_80165718 = -64; + D_80165720 = 5; + D_80165728 = -330; +} + +void PodiumCeremony::InitCourseObjects() { + size_t i; + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == GRAND_PRIX) { + func_80070714(); + } + for (i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + } +} + +void PodiumCeremony::SomeSounds() { +} + +void PodiumCeremony::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void PodiumCeremony::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void PodiumCeremony::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void PodiumCeremony::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void PodiumCeremony::SetStaffGhost() { + u32 temp_v0 = func_800B4E24(0) & 0xfffff; + if (temp_v0 <= 16000) { + D_80162DD6 = 0; + D_80162DF4 = 0; + } else { + D_80162DD6 = 1; + D_80162DF4 = 1; + } + D_80162DC4 = d_royal_raceway_staff_ghost; + D_80162DE4 = 6; +} + +void PodiumCeremony::BeginPlay() { } +void PodiumCeremony::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_royal_raceway_packed_dl_B030 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x0700B030)))); + } + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_royal_raceway_packed_dl_A648 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x0700A648)))); + + render_course_segments(royal_raceway_dls, arg0); + + // d_course_royal_raceway_packed_dl_11A8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070011A8)))); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_royal_raceway_packed_dl_8A0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070008A0)))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); +} + +void PodiumCeremony::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_royal_raceway_dl_D8E8)); +} + +void PodiumCeremony::Collision() {} + +void PodiumCeremony::GenerateCollision() { + parse_course_displaylists(d_course_royal_raceway_addr); + func_80295C6C(); + D_8015F8E4 = -60.0f; +} + +void PodiumCeremony::Destroy() { } diff --git a/src/engine/courses/PodiumCeremony.h b/src/engine/courses/PodiumCeremony.h new file mode 100644 index 000000000..c2abc3dc8 --- /dev/null +++ b/src/engine/courses/PodiumCeremony.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/royal_raceway_vertices.h" + #include "assets/royal_raceway_displaylists.h" + #include "assets/royal_raceway_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture royal_raceway_textures[]; +} + +class PodiumCeremony : public Course { +public: + virtual ~PodiumCeremony() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit PodiumCeremony(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp new file mode 100644 index 000000000..949ac705d --- /dev/null +++ b/src/engine/courses/RainbowRoad.cpp @@ -0,0 +1,217 @@ +#include +#include +#include +#include + +#include "RainbowRoad.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/rainbow_road_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *rainbow_road_dls[]; +} + +RainbowRoad::RainbowRoad() { + this->vtx = d_course_rainbow_road_vertex; + this->gfx = d_course_rainbow_road_packed_dls; + this->gfxSize = 5670; + this->textures = rainbow_road_textures; + + Props.Name = "rainbow road"; + Props.DebugName = "rainbow"; + Props.CourseLength = "2000m"; + Props.AIBehaviour = D_0D0092C8; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.4f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 38; + + Props.NearPersp = 2.0f; + Props.FarPersp = 2700.0f; + + Props.PathSizes = {0x76C, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_rainbow_road_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_rainbow_road_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gToadsTurnpikeRainbowRoadStars; + Props.CloudList = gToadsTurnpikeRainbowRoadStars; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 0, 0}; + Props.Skybox.BottomRight = {0, 0, 0}; + Props.Skybox.BottomLeft = {0, 0, 0}; + Props.Skybox.TopLeft = {0, 0, 0}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void RainbowRoad::LoadTextures() { +} + +void RainbowRoad::SpawnActors() { + spawn_all_item_boxes(d_course_rainbow_road_item_box_spawns); +} + +void RainbowRoad::Init() {} + +void RainbowRoad::InitClouds() { + init_stars(this->Props.Clouds); +} + +void RainbowRoad::UpdateClouds(s32 sp1C, Camera* camera) { + update_stars(sp1C, camera, this->Props.CloudList); +} + +// Likely sets minimap boundaries +void RainbowRoad::MinimapSettings() { + D_8018D2A0 = 0.0103f; + D_8018D2C0[0] = 261; + D_8018D2D8[0] = 166; + D_8018D2E0 = 39; + D_8018D2E8 = 55; +} + +void RainbowRoad::InitCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + size_t i; + for (i = 0; i < NUM_NEON_SIGNS; i++) { + init_object(indexObjectList1[i], 0); + } + for (i = 0; i < NUM_CHAIN_CHOMPS; i++) { + init_object(indexObjectList2[i], 0); + } + } +} + +void RainbowRoad::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + update_neon(); + update_chain_chomps(); + } +} + +void RainbowRoad::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + render_object_neon(cameraId); + render_object_chain_chomps(cameraId); + } +} + +void RainbowRoad::SomeSounds() { +} + +void RainbowRoad::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void RainbowRoad::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void RainbowRoad::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void RainbowRoad::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void RainbowRoad::SetStaffGhost() {} + +void RainbowRoad::BeginPlay() {} +void RainbowRoad::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); +} + +void RainbowRoad::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_rainbow_road_dl_16220)); +} + +void RainbowRoad::Collision() {} + +void RainbowRoad::GenerateCollision() { + D_800DC5C8 = 1; + parse_course_displaylists(d_course_rainbow_road_addr); + func_80295C6C(); + D_8015F8E4 = 0.0f; + // d_course_rainbow_road_packed_dl_2068 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002068), -0x6A, 255, 255, 255); + // d_course_rainbow_road_packed_dl_1E18 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001E18), -0x6A, 255, 255, 255); + // d_course_rainbow_road_packed_dl_1318 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001318), 255, 255, 255, 0); + if (gGamestate != CREDITS_SEQUENCE) { + // d_course_rainbow_road_packed_dl_1FB8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001FB8), -0x6A, 255, 255, 255); + } +} + +void RainbowRoad::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; +} + +void RainbowRoad::Destroy() {} diff --git a/src/engine/courses/RainbowRoad.h b/src/engine/courses/RainbowRoad.h new file mode 100644 index 000000000..3fd3a0333 --- /dev/null +++ b/src/engine/courses/RainbowRoad.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/rainbow_road_vertices.h" + #include "assets/rainbow_road_displaylists.h" + #include "assets/rainbow_road_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture rainbow_road_textures[]; +} + +class RainbowRoad : public Course { +public: + virtual ~RainbowRoad() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit RainbowRoad(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void InitClouds() override; + virtual void UpdateClouds(s32, Camera*) override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp new file mode 100644 index 000000000..ee6d645cb --- /dev/null +++ b/src/engine/courses/RoyalRaceway.cpp @@ -0,0 +1,267 @@ +#include +#include +#include +#include + +#include "RoyalRaceway.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/royal_raceway_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *royal_raceway_dls[]; +} + +RoyalRaceway::RoyalRaceway() { + this->vtx = d_course_royal_raceway_vertex; + this->gfx = d_course_royal_raceway_packed_dls; + this->gfxSize = 5670; + this->textures = royal_raceway_textures; + + Props.Name = "royal raceway"; + Props.DebugName = "p circuit"; + Props.CourseLength = "1025m"; + Props.AIBehaviour = D_0D009188; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.4f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x3E8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_royal_raceway_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_royal_raceway_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gRoyalRacewayClouds; + Props.CloudList = gRoyalRacewayClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {238, 144, 255}; + Props.Skybox.BottomRight = {255, 224, 240}; + Props.Skybox.BottomLeft = {255, 224, 240}; + Props.Skybox.TopLeft = {238, 144, 255}; + Props.Skybox.FloorTopRight = {255, 224, 240}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {255, 224, 240}; +} + +void RoyalRaceway::LoadTextures() { + dma_textures(gTextureTrees3, 0x000003E8U, 0x00000800U); + dma_textures(gTextureTrees7, 0x000003E8U, 0x00000800U); + D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant2, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant3, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant4, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant5, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant6, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant7, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant8, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); +} + +void RoyalRaceway::SpawnActors() { + spawn_foliage(d_course_royal_raceway_tree_spawn); + spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns); + spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn); +} + +void RoyalRaceway::Init() {} + +// Likely sets minimap boundaries +void RoyalRaceway::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust4, 0x3F8, 0x1000)); + D_8018D2C0[0] = 262; + D_8018D2A0 = 0.014f; + D_8018D2E0 = 37; + D_8018D2E8 = 50; + D_80165718 = -64; + D_80165720 = 5; + D_80165728 = -330; +} + +void RoyalRaceway::InitCourseObjects() { + size_t i; + if (gGamestate != CREDITS_SEQUENCE) { + if (gModeSelection == GRAND_PRIX) { + func_80070714(); + } + for (i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + } +} + +void RoyalRaceway::SomeSounds() { +} + +void RoyalRaceway::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void RoyalRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x41); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void RoyalRaceway::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void RoyalRaceway::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void RoyalRaceway::SetStaffGhost() { + u32 temp_v0 = func_800B4E24(0) & 0xfffff; + if (temp_v0 <= 16000) { + D_80162DD6 = 0; + D_80162DF4 = 0; + } else { + D_80162DD6 = 1; + D_80162DF4 = 1; + } + D_80162DC4 = d_royal_raceway_staff_ghost; + D_80162DE4 = 6; +} + +void RoyalRaceway::BeginPlay() { } +void RoyalRaceway::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_royal_raceway_packed_dl_B030 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x0700B030)))); + } + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_royal_raceway_packed_dl_A648 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x0700A648)))); + + render_course_segments(royal_raceway_dls, arg0); + + // d_course_royal_raceway_packed_dl_11A8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070011A8)))); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_royal_raceway_packed_dl_8A0 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual(reinterpret_cast(0x070008A0)))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); +} + +void RoyalRaceway::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_royal_raceway_dl_D8E8)); +} + +void RoyalRaceway::Collision() {} + +void RoyalRaceway::GenerateCollision() { + parse_course_displaylists(d_course_royal_raceway_addr); + func_80295C6C(); + D_8015F8E4 = -60.0f; +} + +void RoyalRaceway::Waypoints(Player* player, int8_t playerId) { + s16 waypoint = gNearestWaypointByPlayerId[playerId]; + if ((waypoint >= 0x258) && (waypoint < 0x2A4)) { + player->nearestWaypointId = 0x258U; + } else { + player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; + if (player->nearestWaypointId < 0) { + player->nearestWaypointId = gWaypointCountByPathIndex[0] + player->nearestWaypointId; + } + } +} + +void RoyalRaceway::Destroy() { } diff --git a/src/engine/courses/RoyalRaceway.h b/src/engine/courses/RoyalRaceway.h new file mode 100644 index 000000000..219f7c2f5 --- /dev/null +++ b/src/engine/courses/RoyalRaceway.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/royal_raceway_vertices.h" + #include "assets/royal_raceway_displaylists.h" + #include "assets/royal_raceway_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture royal_raceway_textures[]; +} + +class RoyalRaceway : public Course { +public: + virtual ~RoyalRaceway() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit RoyalRaceway(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp new file mode 100644 index 000000000..947f74b69 --- /dev/null +++ b/src/engine/courses/SherbetLand.cpp @@ -0,0 +1,196 @@ +#include +#include +#include +#include + +#include "SherbetLand.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/sherbet_land_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *sherbet_land_dls[]; +} + +SherbetLand::SherbetLand() { + this->vtx = d_course_sherbet_land_vertex; + this->gfx = d_course_sherbet_land_packed_dls; + this->gfxSize = 1803; + this->textures = sherbet_land_textures; + + Props.Name = "sherbet land"; + Props.DebugName = "sherbet"; + Props.CourseLength = "756m"; + Props.AIBehaviour = D_0D009280; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x2BC, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_sherbet_land_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_sherbet_land_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gSherbetLandClouds; + Props.CloudList = gSherbetLandClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {128, 184, 248}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {128, 184, 248}; + Props.Skybox.FloorTopRight = {216, 232, 248}; + Props.Skybox.FloorBottomRight = {128, 184, 248}; + Props.Skybox.FloorBottomLeft = {128, 184, 248}; + Props.Skybox.FloorTopLeft = {216, 232, 248}; +} + +void SherbetLand::LoadTextures() { +} + +void SherbetLand::SpawnActors() { + spawn_all_item_boxes(d_course_sherbet_land_item_box_spawns); +} + +void SherbetLand::Init() {} + +// Likely sets minimap boundaries +void SherbetLand::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust1, 0x485, 0xC00)); + D_8018D2A0 = 0.015f; + D_8018D2C0[0] = 262; + D_8018D2E0 = 52; + D_8018D2E8 = 33; + D_8018D300 = 72; + D_8018D308 = 100; + D_8018D310 = 255; +} + +void SherbetLand::InitCourseObjects() { + for (size_t i = 0; i < NUM_PENGUINS; i++) { + init_object(indexObjectList1[i], 0); + } +} + +void SherbetLand::UpdateCourseObjects() { + if (gGamestate != CREDITS_SEQUENCE) { + func_800842C8(); + } + update_penguins(); +} + +void SherbetLand::RenderCourseObjects(s32 cameraId) { + if (gGamestate != CREDITS_SEQUENCE) { + func_80052E30(cameraId); + } + render_object_train_penguins(cameraId); +} + +void SherbetLand::SomeSounds() { +} + +void SherbetLand::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void SherbetLand::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void SherbetLand::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void SherbetLand::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void SherbetLand::SetStaffGhost() {} + +void SherbetLand::BeginPlay() { } +void SherbetLand::Render(struct UnkStruct_800DC5EC* arg0) { + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + render_course_segments(sherbet_land_dls, arg0); +} + +void SherbetLand::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_sherbet_land_dl_9AE8)); +} + +void SherbetLand::Collision() {} + +void SherbetLand::GenerateCollision() { + parse_course_displaylists(d_course_sherbet_land_addr); + func_80295C6C(); + D_8015F8E4 = -18.0f; + // d_course_sherbet_land_packed_dl_1EB8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001EB8), -0x4C, 255, 255, 255); + // d_course_sherbet_land_packed_dl_2308 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002308), -0x6A, 255, 255, 255); +} + +void SherbetLand::Destroy() { } diff --git a/src/engine/courses/SherbetLand.h b/src/engine/courses/SherbetLand.h new file mode 100644 index 000000000..769adef85 --- /dev/null +++ b/src/engine/courses/SherbetLand.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/sherbet_land_vertices.h" + #include "assets/sherbet_land_displaylists.h" + #include "assets/sherbet_land_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture sherbet_land_textures[]; +} + +class SherbetLand : public Course { +public: + virtual ~SherbetLand() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit SherbetLand(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/Skyscraper.cpp b/src/engine/courses/Skyscraper.cpp new file mode 100644 index 000000000..1a565fbbf --- /dev/null +++ b/src/engine/courses/Skyscraper.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include + +#include "Skyscraper.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/skyscraper_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *skyscraper_dls[]; + extern s16 currentScreenSection; +} + +Skyscraper::Skyscraper() { + this->vtx = d_course_skyscraper_vertex; + this->gfx = d_course_skyscraper_packed_dls; + this->gfxSize = 548; + this->textures = skyscraper_textures; + + Props.Name = "skyscraper"; + Props.DebugName = "skyscraper"; + Props.CourseLength = ""; + Props.AIBehaviour = D_0D008F18; + Props.AIMaximumSeparation = -1.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 2.0f; + Props.FarPersp = 2700.0f; + + Props.PathSizes = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = NULL; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = NULL; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = NULL; // no clouds + Props.CloudList = NULL; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 0, 0}; + Props.Skybox.BottomRight = {0, 0, 0}; + Props.Skybox.BottomLeft = {0, 0, 0}; + Props.Skybox.TopLeft = {0, 0, 0}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void Skyscraper::LoadTextures() { +} + +void Skyscraper::SpawnActors() {} + +void Skyscraper::Init() { } + +// Likely sets minimap boundaries +void Skyscraper::MinimapSettings() { + D_8018D2A0 = 0.0445f; + D_8018D2E0 = 32; + D_8018D2E8 = 32; +} + +void Skyscraper::InitCourseObjects() {} + +void Skyscraper::SomeSounds() {} + +void Skyscraper::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void Skyscraper::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void Skyscraper::SpawnBombKarts() {} + +// Positions the finishline on the minimap +void Skyscraper::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void Skyscraper::SetStaffGhost() {} + +void Skyscraper::BeginPlay() { } +void Skyscraper::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // d_course_skyscraper_packed_dl_FE8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000FE8))); + // d_course_skyscraper_packed_dl_C60 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000C60))); + // d_course_skyscraper_packed_dl_B70 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000B70))); + // d_course_skyscraper_packed_dl_6B8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x070006B8))); + // d_course_skyscraper_packed_dl_570 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000570))); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_skyscraper_packed_dl_10C8 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x070010C8))); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_skyscraper_packed_dl_258 + gSPDisplayList(gDisplayListHead++, (segmented_gfx_to_virtual((void*)0x07000258))); +} + +void Skyscraper::RenderCredits() {} + +void Skyscraper::Collision() {} + +void Skyscraper::GenerateCollision() { + // d_course_skyscraper_packed_dl_1110 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001110), 1); + // d_course_skyscraper_packed_dl_258 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000258), 1); + func_80295C6C(); + + D_8015F8E4 = -480.0f; +} + +void Skyscraper::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = 0; +} + +void Skyscraper::Destroy() { } diff --git a/src/engine/courses/Skyscraper.h b/src/engine/courses/Skyscraper.h new file mode 100644 index 000000000..a7b49d4bc --- /dev/null +++ b/src/engine/courses/Skyscraper.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/skyscraper_vertices.h" + #include "assets/skyscraper_displaylists.h" + #include "assets/skyscraper_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture skyscraper_textures[]; +} + +class Skyscraper : public Course { +public: + virtual ~Skyscraper() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit Skyscraper(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + //virtual void InitClouds() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp new file mode 100644 index 000000000..f999457fd --- /dev/null +++ b/src/engine/courses/TestCourse.cpp @@ -0,0 +1,250 @@ +#include +#include +#include +#include + +#include "TestCourse.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + typedef struct { + Gfx* addr; + u8 surfaceType; + u8 sectionId; + u16 flags; + } TrackSections; + extern Gfx test_course_dls[]; + extern Vtx mario_Plane_001_mesh_vtx_1[]; + extern Gfx mario_Plane_001_mesh[]; + extern TrackWaypoint test_course_path[]; + extern TrackSections test_course_addr[]; +} + +TestCourse::TestCourse() { + this->gfxSize = 100; + this->textures = NULL; + + Props.Id = "mk:test_course"; + Props.Name = "Test Course"; + Props.DebugName = "test track"; + Props.CourseLength = "100m"; + + Props.AIBehaviour = D_0D008F28; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.3f; + Props.SomePtr = D_800DCB34; + Props.AISteeringSensitivity = 48; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {52, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + //Props.PathTable[0] = test_course_path; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + //Props.PathTable2[0] = test_course_path; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gKalimariDesertClouds; + Props.CloudList = gLuigiRacewayClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {120, 140, 188}; + Props.Skybox.BottomRight = {216, 232, 248}; + Props.Skybox.BottomLeft = {216, 232, 248}; + Props.Skybox.TopLeft = {40, 184, 208}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void TestCourse::Load() { + gSegmentTable[4] = reinterpret_cast(&mario_Plane_001_mesh_vtx_1[0]); + //gSegmentTable[7] = reinterpret_cast(&gfx[0]); +} + +void TestCourse::LoadTextures() { + dma_textures(gTextureTrees1, 0x0000035BU, 0x00000800U); + D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant2, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant3, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant4, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant5, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant6, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant7, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant8, 0x000003E8U, 0x00000800U); + dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); +} + +void TestCourse::SpawnActors() { +struct ActorSpawnData itemboxes[] = { + { 40, 0, -800, 0}, + { -40, 0, -800, 0}, + { 0, 0, -800, 0}, + { 999, 6, 482, 0}, + { 1064, 8, 275, {0}}, + { 1028, 5, -39 , {0}}, + { 320, 0, 1020, {0}}, + { 293, 0, 950, {0}}, + {{ -32768, 0, 0 }, {0}}, +}; + +struct ActorSpawnData rocks[] = { + {{ 200, 3000, 200 }, {0}}, + {{ 350, 2500, 300 }, {1}}, + {{ 400, 2000, 350 }, {2}}, + {{ -32768, 0, 0 }, {0}}, +}; + spawn_all_item_boxes((const char*)itemboxes); + spawn_falling_rocks((const char*)rocks); +} + +void TestCourse::Init() {} + +// Likely sets minimap boundaries +void TestCourse::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust5, 0x443, 0x1000)); + D_8018D2A0 = 0.022f; + D_8018D2E0 = 6; + D_8018D2E8 = 28; + D_8018D2C0[0] = 260; + D_8018D2D8[0] = 170; + D_80165718 = 0; + D_80165720 = 5; + D_80165728 = -240; +} + +void TestCourse::InitCourseObjects() {} + +void TestCourse::SomeSounds() {} + +void TestCourse::WhatDoesThisDo(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void TestCourse::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x55); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void TestCourse::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void TestCourse::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void TestCourse::SetStaffGhost() {} + +void TestCourse::BeginPlay() { } +void TestCourse::Render(struct UnkStruct_800DC5EC* arg0) { + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + + if (func_80290C20(arg0->camera) == 1) { + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_big_donut_packed_dl_DE8 + } + gSPDisplayList(gDisplayListHead++, mario_Plane_001_mesh); +} + +void TestCourse::RenderCredits() { +} + +void TestCourse::Collision() {} + +void TestCourse::GenerateCollision() { + generate_collision_mesh_with_defaults(mario_Plane_001_mesh); + + parse_course_displaylists((const char*)test_course_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void TestCourse::Destroy() { } diff --git a/src/engine/courses/TestCourse.h b/src/engine/courses/TestCourse.h new file mode 100644 index 000000000..91b279d2e --- /dev/null +++ b/src/engine/courses/TestCourse.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "mario_raceway_vertices.h" + #include "mario_raceway_displaylists.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + #include "mario_raceway_data.h" + extern const course_texture test_course_textures[]; +} + +class TestCourse : public Course { +public: + virtual ~TestCourse() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit TestCourse(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp new file mode 100644 index 000000000..77d8dff33 --- /dev/null +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -0,0 +1,283 @@ +#include +#include +#include +#include + +#include "ToadsTurnpike.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/toads_turnpike_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + #include "code_80086E70.h" + extern const char *d_course_toads_turnpike_dl_list[]; + extern s16 currentScreenSection; + extern s8 gPlayerCount; +} + +ToadsTurnpike::ToadsTurnpike() { + this->vtx = d_course_toads_turnpike_vertex; + this->gfx = d_course_toads_turnpike_packed_dls; + this->gfxSize = 3427; + this->textures = toads_turnpike_textures; + + Props.Name = "toad's turnpike"; + Props.DebugName = "highway"; + Props.CourseLength = "1036m"; + Props.AIBehaviour = D_0D009238; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.5f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 40; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x3E8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_toads_turnpike_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_toads_turnpike_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gToadsTurnpikeRainbowRoadStars; + Props.CloudList = gToadsTurnpikeRainbowRoadStars; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {0, 2, 94}; + Props.Skybox.BottomRight = {209, 65, 23}; + Props.Skybox.BottomLeft = {209, 65, 23}; + Props.Skybox.TopLeft = {0, 2, 94}; + Props.Skybox.FloorTopRight = {209, 65, 23}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {209, 65, 23}; +} + +void ToadsTurnpike::LoadTextures() { +} + +void ToadsTurnpike::SpawnActors() { + D_801625EC = 43; + D_801625F4 = 13; + D_801625F0 = 4; + D_802B87B0 = 993; + D_802B87B4 = 1000; + parse_course_displaylists(d_course_toads_turnpike_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void ToadsTurnpike::Init() {} +void ToadsTurnpike::InitClouds() { + init_stars(this->Props.Clouds); +} + +void ToadsTurnpike::UpdateClouds(s32 sp1C, Camera* camera) { + update_stars(sp1C, camera, this->Props.CloudList); +} + +// Likely sets minimap boundaries +void ToadsTurnpike::MinimapSettings() { + D_8018D2A0 = 0.013f; + D_8018D2C0[0] = 252; + D_8018D2E0 = 57; + D_8018D2E8 = 44; +} + +void ToadsTurnpike::SomeSounds() {} + +void ToadsTurnpike::WhatDoesThisDo(Player* player, int8_t playerId) { + if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { + if (D_80165300[playerId] != 1) { + func_800CA288(playerId, 0x1e); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA2B8(playerId); + D_80165300[playerId] = 0; + } + } +} + +void ToadsTurnpike::WhatDoesThisDoAI(Player* player, int8_t playerId) { + if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { + if (D_80165300[playerId] != 1) { + func_800CA2E4(playerId, 0x1E); + } + D_80165300[playerId] = 1; + } else { + if (D_80165300[playerId] != 0) { + func_800CA30C(playerId); + D_80165300[playerId] = 0; + } + } +} + +void ToadsTurnpike::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void ToadsTurnpike::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void ToadsTurnpike::SetStaffGhost() {} + +void ToadsTurnpike::BeginPlay() {} + +void ToadsTurnpike::Render(struct UnkStruct_800DC5EC* arg0) { + func_802B5D64(D_800DC610, D_802B87D4, 0, 1); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetFogColor(gDisplayListHead++, D_801625EC, D_801625F4, D_801625F0, 0xFF); + gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE); + gSPFogPosition(gDisplayListHead++, D_802B87B0, D_802B87B4); + gSPSetGeometryMode(gDisplayListHead++, G_FOG); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_PASS2); + gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + + render_course_segments(d_course_toads_turnpike_dl_list, arg0); + + gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2); + gDPSetCombineMode(gDisplayListHead++, G_CC_DECALRGBA, G_CC_PASS2); + // d_course_toads_turnpike_packed_dl_0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07000000)); + // d_course_toads_turnpike_packed_dl_68 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07000068)); + // d_course_toads_turnpike_packed_dl_D8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070000D8)); + gSPClearGeometryMode(gDisplayListHead++, G_FOG); + gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); +} + +void ToadsTurnpike::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_toads_turnpike_dl_23930)); +} + +void ToadsTurnpike::Collision() {} + +void ToadsTurnpike::SpawnVehicles() { + s16 trainCarYRot; + UNUSED Vec3f pad; + TrainCarStuff* tempLocomotive; + TrainCarStuff* tempTender; + TrainCarStuff* tempPassengerCar; + Vec3s trainCarRot; + VehicleStuff* tempBoxTruck; + VehicleStuff* tempSchoolBus; + VehicleStuff* tempTankerTruck; + VehicleStuff* tempCar; + PaddleBoatStuff* tempPaddleWheelBoat; + Vec3s paddleWheelBoatRot; + s32 loopIndex; + s32 loopIndex2; + f32 origXPos; + f32 origZPos; + + for (loopIndex = 0; loopIndex < NUM_RACE_BOX_TRUCKS; loopIndex++) { + tempBoxTruck = &gBoxTruckList[loopIndex]; + spawn_vehicle_on_road(tempBoxTruck); + tempBoxTruck->actorIndex = add_actor_to_empty_slot(tempBoxTruck->position, tempBoxTruck->rotation, + tempBoxTruck->velocity, ACTOR_BOX_TRUCK); + } + for (loopIndex = 0; loopIndex < NUM_RACE_SCHOOL_BUSES; loopIndex++) { + tempSchoolBus = &gSchoolBusList[loopIndex]; + spawn_vehicle_on_road(tempSchoolBus); + tempSchoolBus->actorIndex = add_actor_to_empty_slot(tempSchoolBus->position, tempSchoolBus->rotation, + tempSchoolBus->velocity, ACTOR_SCHOOL_BUS); + } + for (loopIndex = 0; loopIndex < NUM_RACE_TANKER_TRUCKS; loopIndex++) { + tempTankerTruck = &gTankerTruckList[loopIndex]; + spawn_vehicle_on_road(tempTankerTruck); + tempTankerTruck->actorIndex = + add_actor_to_empty_slot(tempTankerTruck->position, tempTankerTruck->rotation, + tempTankerTruck->velocity, ACTOR_TANKER_TRUCK); + } + for (loopIndex = 0; loopIndex < NUM_RACE_CARS; loopIndex++) { + tempCar = &gCarList[loopIndex]; + spawn_vehicle_on_road(tempCar); + tempCar->actorIndex = + add_actor_to_empty_slot(tempCar->position, tempCar->rotation, tempCar->velocity, ACTOR_CAR); + } +} + +void ToadsTurnpike::UpdateVehicles() { + update_vehicle_box_trucks(); + update_vehicle_school_bus(); + update_vehicle_tanker_trucks(); + update_vehicle_cars(); +} + +void ToadsTurnpike::GenerateCollision() { + D_801625EC = 43; + D_801625F4 = 13; + D_801625F0 = 4; + D_802B87B0 = 993; + D_802B87B4 = 1000; + parse_course_displaylists(d_course_toads_turnpike_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void ToadsTurnpike::Destroy() { } diff --git a/src/engine/courses/ToadsTurnpike.h b/src/engine/courses/ToadsTurnpike.h new file mode 100644 index 000000000..9e25a288f --- /dev/null +++ b/src/engine/courses/ToadsTurnpike.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/toads_turnpike_vertices.h" + #include "assets/toads_turnpike_displaylists.h" + #include "assets/toads_turnpike_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture toads_turnpike_textures[]; +} + +class ToadsTurnpike : public Course { +public: + virtual ~ToadsTurnpike() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit ToadsTurnpike(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void InitClouds() override; + virtual void UpdateClouds(s32, Camera*) override; + virtual void MinimapSettings() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnVehicles() override; + virtual void UpdateVehicles() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp new file mode 100644 index 000000000..5dc500d29 --- /dev/null +++ b/src/engine/courses/WarioStadium.cpp @@ -0,0 +1,294 @@ +#include +#include +#include +#include + +#include "WarioStadium.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/wario_stadium_data.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *wario_stadium_dls[]; + extern s16 currentScreenSection; +} + +WarioStadium::WarioStadium() { + this->vtx = d_course_wario_stadium_vertex; + this->gfx = d_course_wario_stadium_packed_dls; + this->gfxSize = 5272; + this->textures = wario_stadium_textures; + + Props.Name = "wario stadium"; + Props.DebugName = "stadium"; + Props.CourseLength = "1591m"; + Props.AIBehaviour = D_0D009310; + Props.AIMaximumSeparation = 50.0f; + Props.AIMinimumSeparation = 0.6f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 10.0f; + Props.FarPersp = 4800.0f; + + Props.PathSizes = {0x640, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_wario_stadium_unknown_waypoints; + Props.PathTable[1] = NULL; + Props.PathTable[2] = NULL; + Props.PathTable[3] = NULL; + + Props.PathTable2[0] = d_course_wario_stadium_track_waypoints; + Props.PathTable2[1] = NULL; + Props.PathTable2[2] = NULL; + Props.PathTable2[3] = NULL; + + Props.Clouds = gWarioStadiumStars; + Props.CloudList = gWarioStadiumStars; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {20, 30, 56}; + Props.Skybox.BottomRight = {40, 60, 110}; + Props.Skybox.BottomLeft = {40, 60, 110}; + Props.Skybox.TopLeft = {20, 30, 56}; + Props.Skybox.FloorTopRight = {0, 0, 0}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {0, 0, 0}; +} + +void WarioStadium::LoadTextures() { +} + +void WarioStadium::SpawnActors() { + Vec3f position; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3s rotation = { 0, 0, 0 }; + + spawn_all_item_boxes(d_course_wario_stadium_item_box_spawns); + vec3f_set(position, -131.0f, 83.0f, 286.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + vec3f_set(position, -2353.0f, 72.0f, -1608.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + vec3f_set(position, -2622.0f, 79.0f, 739.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); +} + +void WarioStadium::Init() {} +void WarioStadium::InitClouds() { + init_stars(this->Props.Clouds); +} + +void WarioStadium::UpdateClouds(s32 sp1C, Camera* camera) { + update_stars(sp1C, camera, this->Props.CloudList); +} + +// Likely sets minimap boundaries +void WarioStadium::MinimapSettings() { + D_8018D2A0 = 0.0155f; + D_8018D2C0[0] = 0x0106; + D_8018D2E0 = 53; + D_8018D2E8 = 35; +} + +void WarioStadium::InitCourseObjects() {} + +void WarioStadium::SomeSounds() { + vec3f_set(D_8015F748, 298.0f, 202.0f, -850.0f); + func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B); + vec3f_set(D_8015F758, -1600.0f, 202.0f, -2430.0f); + func_800C9D80(D_8015F758, D_802B91C8, 0x5103700B); + vec3f_set(D_8015F768, -2708.0f, 202.0f, 1762.0f); + func_800C9D80(D_8015F768, D_802B91C8, 0x5103700B); + vec3f_set(D_8015F778, -775.0f, 202.0f, 1930.0f); + func_800C9D80(D_8015F778, D_802B91C8, 0x5103700B); +} + +void WarioStadium::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void WarioStadium::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void WarioStadium::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void WarioStadium::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void WarioStadium::SetStaffGhost() {} + +void WarioStadium::BeginPlay() { } +void WarioStadium::Render(struct UnkStruct_800DC5EC* arg0) { + s16 prevFrame; + + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (func_80290C20(arg0->camera) == 1) { + + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_wario_stadium_packed_dl_A0C8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x0700A0C8)); + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATERGBA, G_CC_MODULATERGBA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + + render_course_segments(wario_stadium_dls, arg0); + + // d_course_wario_stadium_packed_dl_A228 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x0700A228)); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_wario_stadium_packed_dl_A88 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07000A88)); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + + D_800DC5DC = 88; + D_800DC5E0 = 72; + if (gActiveScreenMode == SCREEN_MODE_1P) { + prevFrame = (s16) sRenderedFramebuffer - 1; + if (prevFrame < 0) { + prevFrame = 2; + } else if (prevFrame >= 3) { + prevFrame = 0; + } + currentScreenSection++; + if (currentScreenSection > 5) { + currentScreenSection = 0; + } + switch (currentScreenSection) { + case 0: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x8800)); +#endif + break; + case 1: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x9800)); +#endif + break; + case 2: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0 + 32, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xA800)); +#endif + break; + case 3: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 32, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xB800)); +#endif + break; + case 4: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC, D_800DC5E0 + 64, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xC800)); +#endif + break; + case 5: +#ifdef TARGET_N64 + copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 64, 64, 32, + (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[prevFrame]), + (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xD800)); +#endif + break; + } + } +} + +void WarioStadium::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_wario_stadium_dl_CA78)); +} + +void WarioStadium::Collision() {} + +void WarioStadium::GenerateCollision() { + parse_course_displaylists(d_course_wario_stadium_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; + // d_course_wario_stadium_packed_dl_C50 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000C50), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_BD8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000BD8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_B60 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000B60), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_AE8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000AE8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_CC8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000CC8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_D50 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000D50), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_DD0 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000DD0), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_E48 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000E48), 100, 255, 255, 255); +} + +void WarioStadium::Destroy() { } diff --git a/src/engine/courses/WarioStadium.h b/src/engine/courses/WarioStadium.h new file mode 100644 index 000000000..388e39c7f --- /dev/null +++ b/src/engine/courses/WarioStadium.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/wario_stadium_vertices.h" + #include "assets/wario_stadium_displaylists.h" + #include "assets/wario_stadium_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture wario_stadium_textures[]; +} + +class WarioStadium : public Course { +public: + virtual ~WarioStadium() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit WarioStadium(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void InitClouds() override; + virtual void UpdateClouds(s32,Camera*) override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Destroy() override; +}; diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp new file mode 100644 index 000000000..d7c142743 --- /dev/null +++ b/src/engine/courses/YoshiValley.cpp @@ -0,0 +1,224 @@ +#include +#include +#include +#include + +#include "YoshiValley.h" +#include "GameObject.h" +#include "World.h" +#include "BombKart.h" +#include "assets/yoshi_valley_data.h" +#include "assets/boo_frames.h" + +extern "C" { + #include "main.h" + #include "camera.h" + #include "course_offsets.h" + #include "code_800029B0.h" + #include "render_courses.h" + #include "code_8006E9C0.h" + #include "code_80057C60.h" + #include "defines.h" + #include "math_util.h" + #include "external.h" + #include "code_80005FD0.h" + #include "spawn_players.h" + #include "render_objects.h" + #include "assets/common_data.h" + #include "save.h" + #include "staff_ghosts.h" + #include "actors.h" + #include "collision.h" + #include "memory.h" + extern const char *d_course_yoshi_valley_dl_list[]; +} + +YoshiValley::YoshiValley() { + this->vtx = d_course_yoshi_valley_vertex; + this->gfx = d_course_yoshi_valley_packed_dls; + this->gfxSize = 4140; + this->textures = yoshi_valley_textures; + + Props.Name = "yoshi valley"; + Props.DebugName = "maze"; + Props.CourseLength = "772m"; + Props.AIBehaviour = D_0D0090B8; + Props.AIMaximumSeparation = 35.0f; + Props.AIMinimumSeparation = 0.0f; + Props.SomePtr = D_800DCAF4; + Props.AISteeringSensitivity = 53; + + Props.NearPersp = 9.0f; + Props.FarPersp = 4500.0f; + + Props.PathSizes = {0x02B2, 0x02A8, 0x02B2, 0x0320, 1, 0, 0, 0, 0, 0, 0}; + + Props.D_0D009418[0] = 4.1666665f; + Props.D_0D009418[1] = 5.5833334f; + Props.D_0D009418[2] = 6.1666665f; + Props.D_0D009418[3] = 6.75f; + + Props.D_0D009568[0] = 3.75f; + Props.D_0D009568[1] = 5.1666665f; + Props.D_0D009568[2] = 5.75f; + Props.D_0D009568[3] = 6.3333334f; + + Props.D_0D0096B8[0] = 3.3333332f; + Props.D_0D0096B8[1] = 3.9166667f; + Props.D_0D0096B8[2] = 4.5f; + Props.D_0D0096B8[3] = 5.0833334f; + + Props.D_0D009808[0] = 3.75f; + Props.D_0D009808[1] = 5.1666665f; + Props.D_0D009808[2] = 5.75f; + Props.D_0D009808[3] = 6.3333334f; + + Props.PathTable[0] = d_course_yoshi_valley_unknown_waypoints; + Props.PathTable[1] = d_course_yoshi_valley_unknown_waypoints_2; + Props.PathTable[2] = d_course_yoshi_valley_unknown_waypoints_3; + Props.PathTable[3] = d_course_yoshi_valley_unknown_waypoints_4; + + Props.PathTable2[0] = d_course_yoshi_valley_track_waypoints; + Props.PathTable2[1] = d_course_yoshi_valley_track_waypoints_2; + Props.PathTable2[2] = d_course_yoshi_valley_track_waypoints_3; + Props.PathTable2[3] = d_course_yoshi_valley_track_waypoints_4; + + Props.Clouds = gYoshiValleyMooMooFarmClouds; + Props.CloudList = gYoshiValleyMooMooFarmClouds; + Props.MinimapFinishlineX = 0; + Props.MinimapFinishlineY = 0; + + Props.Skybox.TopRight = {113, 70, 255}; + Props.Skybox.BottomRight = {255, 184, 99}; + Props.Skybox.BottomLeft = {255, 184, 99}; + Props.Skybox.TopLeft = {113, 70, 255}; + Props.Skybox.FloorTopRight = {95, 40, 15}; + Props.Skybox.FloorBottomRight = {0, 0, 0}; + Props.Skybox.FloorBottomLeft = {0, 0, 0}; + Props.Skybox.FloorTopLeft = {95, 40, 15}; +} + +void YoshiValley::LoadTextures() { + dma_textures(gTextureTrees2, 0x000003E8U, 0x00000800U); +} + +void YoshiValley::SpawnActors() { + Vec3f position; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3s rotation = { 0, 0, 0 }; + + spawn_foliage(d_course_yoshi_valley_tree_spawn); + spawn_all_item_boxes(d_course_yoshi_valley_item_box_spawns); + vec3f_set(position, -2300.0f, 0.0f, 634.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); +} + +void YoshiValley::Init() {} + +// Likely sets minimap boundaries +void YoshiValley::MinimapSettings() { + D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust0, 0x479, 0xC00)); + D_8018D2A0 = 0.018f; + D_8018D2E0 = 61; + D_8018D2E8 = 38; +} + +void YoshiValley::InitCourseObjects() { + size_t objectId; + size_t i; + for (i = 0; i < NUM_YV_FLAG_POLES; i++) { + init_object(indexObjectList1[i], 0); + } + if (gGamestate != CREDITS_SEQUENCE) { + for (i = 0; i < NUM_HEDGEHOGS; i++) { + objectId = indexObjectList2[i]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = + gHedgehogSpawns[i].pos[0] * xOrientation; + gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = + gHedgehogSpawns[i].pos[1] + 6.0; + gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gHedgehogSpawns[i].pos[2]; + gObjectList[objectId].unk_0D5 = gHedgehogSpawns[i].unk_06; + gObjectList[objectId].unk_09C = gHedgehogPatrolPoints[i][0] * xOrientation; + gObjectList[objectId].unk_09E = gHedgehogPatrolPoints[i][2]; + } + } +} + +void YoshiValley::UpdateCourseObjects() { + func_80083080(); + if (gGamestate != CREDITS_SEQUENCE) { + update_hedgehogs(); + } +} + +void YoshiValley::RenderCourseObjects(s32 cameraId) { + func_80055228(cameraId); + if (gGamestate != CREDITS_SEQUENCE) { + render_object_hedgehogs(cameraId); + } +} + +void YoshiValley::SomeSounds() { +} + +void YoshiValley::WhatDoesThisDo(Player* player, int8_t playerId) {} + +void YoshiValley::WhatDoesThisDoAI(Player* player, int8_t playerId) {} + +void YoshiValley::SpawnBombKarts() { + World* world = GetWorld(); + + if (world) { + world->SpawnObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + world->SpawnObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); + } +} + +// Positions the finishline on the minimap +void YoshiValley::MinimapFinishlinePosition() { + //! todo: Place hard-coded values here. + draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); +} + +void YoshiValley::SetStaffGhost() { +} + +void YoshiValley::BeginPlay() { } + +void YoshiValley::Render(struct UnkStruct_800DC5EC* arg0) { + gDPPipeSync(gDisplayListHead++); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + render_course_segments(d_course_yoshi_valley_dl_list, arg0); + gDPPipeSync(gDisplayListHead++); +} + +void YoshiValley::RenderCredits() { + gSPDisplayList(gDisplayListHead++, (Gfx*)(d_course_yoshi_valley_dl_18020)); +} + +void YoshiValley::Collision() {} + +void YoshiValley::GenerateCollision() { + Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120); + func_802B5D64(&lights4, -0x38F0, 0x1C70, 1); + parse_course_displaylists(d_course_yoshi_valley_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + +void YoshiValley::Waypoints(Player* player, int8_t playerId) { + player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; +} + +void YoshiValley::Water() {} + +void YoshiValley::Destroy() {} diff --git a/src/engine/courses/YoshiValley.h b/src/engine/courses/YoshiValley.h new file mode 100644 index 000000000..a0976968d --- /dev/null +++ b/src/engine/courses/YoshiValley.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "Course.h" + +extern "C" { + #include "assets/yoshi_valley_vertices.h" + #include "assets/yoshi_valley_displaylists.h" + #include "assets/yoshi_valley_data.h" + #include "course_offsets.h" + #include "camera.h" + #include "data/some_data.h" + #include "objects.h" + #include "path_spawn_metadata.h" + extern const course_texture yoshi_valley_textures[]; +} + +class YoshiValley : public Course { +public: + virtual ~YoshiValley() = default; // Virtual destructor for proper cleanup in derived classes + + // Constructor + explicit YoshiValley(); + +// virtual void Load(const char* courseVtx, +// course_texture* textures, const char* displaylists, size_t dlSize); + virtual void LoadTextures() override; + virtual void SpawnActors() override; + virtual void Init() override; + virtual void MinimapSettings() override; + virtual void InitCourseObjects() override; + virtual void UpdateCourseObjects() override; + virtual void RenderCourseObjects(s32 cameraId) override; + virtual void SomeSounds() override; + virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; + virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; + virtual void MinimapFinishlinePosition() override; + virtual void SetStaffGhost() override; + virtual void BeginPlay() override; + virtual void Render(struct UnkStruct_800DC5EC*) override; + virtual void RenderCredits() override; + virtual void Collision() override; + virtual void SpawnBombKarts() override; + virtual void GenerateCollision() override; + virtual void Water() override; + virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void Destroy() override; +}; diff --git a/src/engine/structs.h b/src/engine/structs.h new file mode 100644 index 000000000..7b9b8f5c9 --- /dev/null +++ b/src/engine/structs.h @@ -0,0 +1,92 @@ +#pragma once + +#include + +typedef float Vec3f[3]; +typedef unsigned short Vec3su[3]; + +typedef struct { + /* 0x00 */ u16 unk30; + /* 0x02 */ u16 unk32; + /* 0x04 */ u16 unk34; + /* 0x06 */ u16 meshIndexYX; + /* 0x08 */ u16 meshIndexZY; + // This may be an index to the tilemap? + /* 0x0A */ u16 meshIndexZX; + /* 0x0C */ float surfaceDistance[3]; // Appears to be distance from actor to surface for zx, yx, and zy planes. + /* 0x18 */ float unk48[3]; + /* 0x24 */ float unk54[3]; + /* 0x30 */ float orientationVector[3]; + /* 0x3C */ f32 unk6C; +} Collision; + +struct Actor { + /* 0x00 */ s16 type; + /* 0x02 */ s16 flags; + /* 0x04 */ s16 unk_04; + /* 0x06 */ s16 state; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 boundingBoxSize; + /* 0x10 */ s16 rot[3]; + /* 0x16 */ s16 unk_16; + /* 0x18 */ Vec3f pos; + /* 0x24 */ Vec3f velocity; + /* 0x30 */ Collision unk30; +}; // size = 0x70 + +struct BananaActor { + /* 0x00 */ s16 type; + /* 0x02 */ s16 flags; + /* 0x04 */ s16 unk_04; + /* 0x06 */ s16 state; + /* 0x08 */ s16 parentIndex; + /* 0x0A */ s16 bananaId; // ? Appears to indiciate which banana of the bunch this one is + /* 0x0C */ f32 boundingBoxSize; + /* 0x10 */ s16 playerId; // Id of the player that owns this banana + /* 0x12 */ s16 elderIndex; // Index in gActorList of the next-oldest banana in the bunch + /* 0x14 */ s16 youngerIndex; // Index in gActorList of the next-youngest banana in the bunch + /* 0x16 */ s16 unk_16; + /* 0x18 */ float pos[3]; + /* 0x24 */ float velocity[3]; + /* 0x30 */ Collision unk30; +}; // size = 0x70 + +typedef struct { + f32 unk_0; + s16 unk_4; + s16 unk_6; + s16 unk_8; +} UnkCameraInner; + +typedef struct { + /* 0x00 */ float pos[3]; + /* 0x0C */ Vec3f lookAt; + // This is expected to be a normalized vector, indicates what direction is "up" for the camera + /* 0x18 */ Vec3f up; + // I think these are the "nautical angles" between pos and lookAt + // rot[0] = roll? Does nothing?, rot[1] = yaw, rot[2] = pitch + /* 0x24 */ s16 rot[3]; + /* 0x2A */ u16 someBitFlags; + /* 0x2C */ s16 unk_2C; + /* 0x2E */ s16 unk_2E; + /* 0x30 */ Vec3f unk_30; + /* 0x3C */ Vec3f unk_3C; + /* 0x48 */ s32 unk_48; + /* 0x4C */ s32 unk_4C; + /* 0x50 */ s32 unk_50; + /* 0x54 */ Collision collision; + // When you hit a wall (or another driver) the camera's pos and lookAt bounce up and down. This is the velocity(?) + // of that bouncing + /* 0x94 */ UnkCameraInner unk_94; + // Timer for wall-hit bounce. Counts up instead of down + /* 0xA0 */ f32 unk_A0; + /* 0xA4 */ s32 unk_A4; + /* 0xA8 */ s32 unk_A8; + /* 0xAC */ s16 unk_AC; + // Id of the player the camera is following. + /* 0xAE */ s16 playerId; + // Seems related to camera movement during drifting + /* 0xB0 */ s16 unk_B0; + /* 0xB2 */ s16 unk_B2; + /* 0xB4 */ f32 unk_B4; +} Camera; /* size = 0xB8 */ diff --git a/src/enhancements/freecam/freecam.c b/src/enhancements/freecam/freecam.c index bb9522185..ef9df134c 100644 --- a/src/enhancements/freecam/freecam.c +++ b/src/enhancements/freecam/freecam.c @@ -17,6 +17,9 @@ #include "skybox_and_splitscreen.h" #include "freecam.h" +#include "engine/Engine.h" +#include "engine/courses/Course.h" + typedef struct { Vec3f pos; Vec3f lookAt; @@ -358,7 +361,7 @@ void freecam_render_setup(void) { func_80057FC4(0); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_CULL_BOTH | G_CULL_FRONT); - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); guLookAt(&gGfxPool->mtxLookAt[0], camera1->pos[0], camera1->pos[1], camera1->pos[2], camera1->lookAt[0], diff --git a/src/main.c b/src/main.c index a47eeefe9..4844c8022 100644 --- a/src/main.c +++ b/src/main.c @@ -712,7 +712,7 @@ void race_logic_loop(void) { break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { gTickSpeed = 3; } else { gTickSpeed = 2; @@ -757,7 +757,7 @@ void race_logic_loop(void) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - if (gCurrentCourseId == COURSE_DK_JUNGLE) { + if (GetCourse() == GetDkJungle()) { gTickSpeed = 3; } else { gTickSpeed = 2; diff --git a/src/menus.c b/src/menus.c index dffd6c47b..f772f87cc 100644 --- a/src/menus.c +++ b/src/menus.c @@ -158,7 +158,7 @@ void update_menus(void) { func_800CA330(0x19); // deliberate (?) fallthru case MAIN_MENU: - case PLAYER_SELECT_MENU: + case CHARACTER_SELECT_MENU: play_sound2(SOUND_MENU_OK_CLICKED); break; } @@ -199,7 +199,7 @@ void update_menus(void) { main_menu_act(&gControllers[controllerIdx], controllerIdx); break; case PLAYER_SELECT_MENU_FROM_QUIT: - case PLAYER_SELECT_MENU: + case CHARACTER_SELECT_MENU: player_select_menu_act(&gControllers[controllerIdx], controllerIdx); break; case COURSE_SELECT_MENU_FROM_QUIT: @@ -1018,7 +1018,7 @@ void splash_menu_act(struct Controller* controller, u16 arg1) { if (btnAndStick & (R_JPAD | L_JPAD)) { play_sound2(SOUND_MENU_CURSOR_MOVE); if (gEnableDebugMode) { - gEnableDebugMode = DEBUG_MODE; + gEnableDebugMode = CVarGetInteger("gEnableDebugMode", 0); } else { gEnableDebugMode = true; } @@ -1032,19 +1032,23 @@ void splash_menu_act(struct Controller* controller, u16 arg1) { case DEBUG_MENU_COURSE: { if (btnAndStick & R_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); - if (gCurrentCourseId < (NUM_COURSES - 2)) { - gCurrentCourseId += 1; - } else { - gCurrentCourseId = 0; - } + NextCourse(); + gCurrentCourseId = GetCourseIndex(); + // if (gCurrentCourseId < (NUM_COURSES - 2)) { + // gCurrentCourseId += 1; + // } else { + // gCurrentCourseId = 0; + // } } if (btnAndStick & L_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); - if (gCurrentCourseId > 0) { - gCurrentCourseId -= 1; - } else { - gCurrentCourseId = (NUM_COURSES - 2); - } + PreviousCourse(); + gCurrentCourseId = GetCourseIndex(); + // if (gCurrentCourseId > 0) { + // gCurrentCourseId -= 1; + // } else { + // gCurrentCourseId = (NUM_COURSES - 2); + // } } if (btnAndStick & U_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); @@ -1381,7 +1385,7 @@ void main_menu_act(struct Controller* controller, u16 arg1) { // L800B3068 if (btnAndStick & D_JPAD) { sp24 = false; - if (func_800B555C()) { + if (has_unlocked_extra_mode()) { if (sp28 < gGameModePlayerColumnExtra[gPlayerCount - 1][D_800E86AC[gPlayerCount - 1] + 1]) { sp24 = true; } @@ -1676,6 +1680,11 @@ void player_select_menu_act(struct Controller* controller, u16 arg1) { GLOBAL_ASM("asm/non_matchings/menus/player_select_menu_act.s") #endif +u32 WorldNextCup(void); +u32 WorldPreviousCup(void); +u32 GetCupIndex(void); +void SetCup(void); + // Handle navigating the course menu interface void course_select_menu_act(struct Controller* arg0, u16 arg1) { u16 buttonAndStickPress = (arg0->buttonPressed | arg0->stickPressed); @@ -1688,22 +1697,25 @@ void course_select_menu_act(struct Controller* arg0, u16 arg1) { switch (D_8018EDEC) { case 1: if ((buttonAndStickPress & R_JPAD) != 0) { - if (gCupSelection < SPECIAL_CUP) { - D_8018EE0A = gCupSelection; - ++gCupSelection; + //if (GetCupIndex() < SPECIAL_CUP) { + D_8018EE0A = WorldNextCup(); + //++gCupSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); - } + //} } - if (((buttonAndStickPress & L_JPAD) != 0) && (gCupSelection > MUSHROOM_CUP)) { - D_8018EE0A = gCupSelection; - --gCupSelection; + if (((buttonAndStickPress & L_JPAD) != 0)) { + D_8018EE0A = WorldPreviousCup(); + //--gCupSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } - D_800DC540 = gCupSelection; + D_800DC540 = GetCupIndex(); + //! @todo SetCourse(); + SetCup(); gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + SetCourseFromCup(); if ((buttonAndStickPress & B_BUTTON) != 0) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); @@ -1714,6 +1726,9 @@ void course_select_menu_act(struct Controller* arg0, u16 arg1) { } else { D_8018EDEC = 3; play_sound2(SOUND_MENU_SELECT); + //! @todo SetCourse() to course one; + SetCupCursorPosition(COURSE_ONE); + SetCourseFromCup(); gCurrentCourseId = gCupCourseOrder[gCupSelection][COURSE_ONE]; gMenuTimingCounter = 0; } @@ -1722,18 +1737,21 @@ void course_select_menu_act(struct Controller* arg0, u16 arg1) { break; case 2: case 4: - if (((buttonAndStickPress & D_JPAD) != 0) && (gCourseIndexInCup < COURSE_FOUR)) { + if (((buttonAndStickPress & D_JPAD) != 0) && (GetCupCursorPosition() < GetCupSize())) { ++gCourseIndexInCup; + SetCupCursorPosition(GetCupCursorPosition() + 1); func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } - if (((buttonAndStickPress & U_JPAD) != 0) && (gCourseIndexInCup > COURSE_ONE)) { + if (((buttonAndStickPress & U_JPAD) != 0) && (GetCupCursorPosition() > COURSE_ONE)) { --gCourseIndexInCup; + SetCupCursorPosition(GetCupCursorPosition() - 1); func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + SetCourseFromCup(); if ((buttonAndStickPress & B_BUTTON) != 0) { if (D_8018EDEC == 2) { D_8018EDEC = 1; @@ -1786,7 +1804,7 @@ void course_select_menu_act(struct Controller* arg0, u16 arg1) { void func_800B3F74(s32 menuSelection) { s32 i; - gDebugMenuSelection = DEBUG_MENU; + gDebugMenuSelection = CVarGetInteger("gEnableDebugMode", 0) + 1; gMenuTimingCounter = 0; gMenuDelayTimer = 0; D_8018EE08 = 0; @@ -1822,7 +1840,8 @@ void func_800B3F74(s32 menuSelection) { case 0: case 10: { gIsMirrorMode = 0; - gEnableDebugMode = DEBUG_MODE; + gEnableDebugMode = CVarGetInteger("gEnableDebugMode", 0); + SetCupIndex(MUSHROOM_CUP); gCupSelection = MUSHROOM_CUP; gCourseIndexInCup = 0; gTimeTrialDataCourseIndex = 0; @@ -1840,7 +1859,7 @@ void func_800B3F74(s32 menuSelection) { } case 1: case 11: { - gEnableDebugMode = DEBUG_MODE; + gEnableDebugMode = CVarGetInteger("gEnableDebugMode", 0); gIsMirrorMode = 0; D_8018EDFC = 0; func_800B5F30(); @@ -1933,12 +1952,14 @@ void func_800B3F74(s32 menuSelection) { case 3: case 13: { if (gModeSelection == BATTLE) { - gCupSelection = BATTLE_CUP; + SetCupIndex(BATTLE_CUP); + //gCupSelection = BATTLE_CUP; D_800DC540 = 4; D_8018EDEC = 4; } else { - if (gCupSelection == BATTLE_CUP) { - gCupSelection = MUSHROOM_CUP; + if (GetCupIndex() == BATTLE_CUP) { + SetCupIndex(MUSHROOM_CUP); + //gCupSelection = MUSHROOM_CUP; } D_8018EDEC = 1; } diff --git a/src/menus.h b/src/menus.h index bcab9e809..6e3ef6d6b 100644 --- a/src/menus.h +++ b/src/menus.h @@ -28,7 +28,7 @@ void splash_menu_act(struct Controller*, u16); void func_800B28C8(void); void main_menu_act(struct Controller*, u16); bool is_character_spot_free(s32); -void player_select_menu_act(struct Controller*, u16); +void player_select_menu_act(struct Controller* controller, u16 arg1); void course_select_menu_act(struct Controller*, u16); void func_800B3F74(s32); void func_800B44AC(void); diff --git a/src/networking/start_game.c b/src/networking/start_game.c index 668367f74..02c2ec9dc 100644 --- a/src/networking/start_game.c +++ b/src/networking/start_game.c @@ -52,8 +52,10 @@ void network_cup_vote(uint32_t course) { void set_course(const char* data) { if (data != NULL) { + SetCupIndex(data[0]); gCupSelection = data[0]; - gCurrentCourseId = gCupCourseOrder[gCupSelection][COURSE_ONE]; + //gCurrentCourseId = gCupCourseOrder[gCupSelection][COURSE_ONE]; + //! @todo SetCourse(); } } diff --git a/src/player_controller.c b/src/player_controller.c index 3bee6c89c..cf4683c24 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -245,252 +245,258 @@ void func_80027EDC(Player* player, s8 playerId) { UNUSED s32 pad; if (((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) && ((player->type & PLAYER_INVISIBLE_OR_BOMB) != PLAYER_INVISIBLE_OR_BOMB)) { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_CHOCO_MOUNTAIN: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_BOWSER_CASTLE: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x41); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_BANSHEE_BOARDWALK: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x41); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_LUIGI_RACEWAY: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_TOADS_TURNPIKE: - if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x1e); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_SHERBET_LAND: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x11C) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x209)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA2B8(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_DK_JUNGLE: - if ((((s16) gNearestWaypointByPlayerId[playerId] >= 0) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x65)) || - (((s16) gNearestWaypointByPlayerId[playerId] >= 0x14A) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x21F))) { - if (D_80165300[playerId] != 2) { - func_800C8F80(playerId, 0x0170802D); - } - D_80165300[playerId] = 2; - } else { - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { - if (D_80165300[playerId] != 1) { - func_800CA288(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - if (D_80165300[playerId] == 1) { - func_800CA2B8(playerId); - } - if (D_80165300[playerId] == 2) { - func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x70, 0x80, 0x2D)); - } - D_80165300[playerId] = 0; - } - } - } - break; - default: - break; - } + + CourseManager_WhatDoesThisDo(player, playerId); + + // switch (gCurrentCourseId) { + // // case COURSE_MARIO_RACEWAY: + // // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + // // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + // // if (D_80165300[playerId] != 1) { + // // func_800CA288(playerId, 0x55); + // // } + // // D_80165300[playerId] = 1; + // // } else { + // // if (D_80165300[playerId] != 0) { + // // func_800CA2B8(playerId); + // // D_80165300[playerId] = 0; + // // } + // // } + // break; + // case COURSE_CHOCO_MOUNTAIN: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_BOWSER_CASTLE: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x41); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_BANSHEE_BOARDWALK: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x41); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_LUIGI_RACEWAY: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_TOADS_TURNPIKE: + // if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x1e); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_SHERBET_LAND: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x11C) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x209)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA2B8(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_DK_JUNGLE: + // if ((((s16) gNearestWaypointByPlayerId[playerId] >= 0) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x65)) || + // (((s16) gNearestWaypointByPlayerId[playerId] >= 0x14A) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x21F))) { + // if (D_80165300[playerId] != 2) { + // func_800C8F80(playerId, 0x0170802D); + // } + // D_80165300[playerId] = 2; + // } else { + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { + // if (D_80165300[playerId] != 1) { + // func_800CA288(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // if (D_80165300[playerId] == 1) { + // func_800CA2B8(playerId); + // } + // if (D_80165300[playerId] == 2) { + // func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x70, 0x80, 0x2D)); + // } + // D_80165300[playerId] = 0; + // } + // } + // } + // break; + // default: + // break; + // } } else { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_CHOCO_MOUNTAIN: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_BOWSER_CASTLE: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x41); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_BANSHEE_BOARDWALK: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x41); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_LUIGI_RACEWAY: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_TOADS_TURNPIKE: - if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x1E); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_SHERBET_LAND: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x11C) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x209)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - case COURSE_DK_JUNGLE: - if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && - ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { - if (D_80165300[playerId] != 1) { - func_800CA2E4(playerId, 0x55); - } - D_80165300[playerId] = 1; - } else { - if (D_80165300[playerId] != 0) { - func_800CA30C(playerId); - D_80165300[playerId] = 0; - } - } - break; - default: - break; - } + + CourseManager_WhatDoesThisDoAI(player, playerId); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x19B) && + // // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1B9)) { + // // if (D_80165300[playerId] != 1) { + // // func_800CA2E4(playerId, 0x55); + // // } + // // D_80165300[playerId] = 1; + // // } else { + // // if (D_80165300[playerId] != 0) { + // // func_800CA30C(playerId); + // // D_80165300[playerId] = 0; + // // } + // // } + // break; + // case COURSE_CHOCO_MOUNTAIN: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0xA0) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0xB4)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_BOWSER_CASTLE: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x29) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1D2)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x41); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_BANSHEE_BOARDWALK: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x180) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x1E1)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x41); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_LUIGI_RACEWAY: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x145) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x18B)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_TOADS_TURNPIKE: + // if ((player->type & PLAYER_CINEMATIC_MODE) != PLAYER_CINEMATIC_MODE) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x1E); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_SHERBET_LAND: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x11C) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x209)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // case COURSE_DK_JUNGLE: + // if (((s16) gNearestWaypointByPlayerId[playerId] >= 0x288) && + // ((s16) gNearestWaypointByPlayerId[playerId] < 0x305)) { + // if (D_80165300[playerId] != 1) { + // func_800CA2E4(playerId, 0x55); + // } + // D_80165300[playerId] = 1; + // } else { + // if (D_80165300[playerId] != 0) { + // func_800CA30C(playerId); + // D_80165300[playerId] = 0; + // } + // } + // break; + // default: + // break; + // } } } @@ -1699,59 +1705,53 @@ void func_8002C11C(Player* player) { } void func_8002C17C(Player* player, s8 playerId) { - switch (gCurrentCourseId) { /* irregular */ - case COURSE_YOSHI_VALLEY: - if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { - D_80165330[playerId] = 1; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (D_80165330[playerId] == 0) { - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (!(player->effects & 8)) { - if (func_802ABDF4(player->collision.meshIndexZX) == 0) { - D_80165330[playerId] = 0; - } - } - break; - case COURSE_FRAPPE_SNOWLAND: - if ((player->surfaceType == SNOW_OFFROAD) && (D_80165330[playerId] == 0)) { - D_80165330[playerId] = 1; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (player->surfaceType != SNOW_OFFROAD) { - D_80165330[playerId] = 0; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } - break; - case COURSE_ROYAL_RACEWAY: - if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) != 0) && (D_80165330[playerId] == 0)) { - D_80165330[playerId] = 1; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) == 0) && !(player->effects & 8)) { - D_80165330[playerId] = 0; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } - break; - case COURSE_RAINBOW_ROAD: - if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { - D_80165330[playerId] = 1; - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (D_80165330[playerId] == 0) { - gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; - gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; - } else if (!((player->effects & 8) || (player->unk_0CA & 1))) { + if (GetCourse() == GetYoshiValley()) { + if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { + D_80165330[playerId] = 1; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (D_80165330[playerId] == 0) { + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (!(player->effects & 8)) { + if (func_802ABDF4(player->collision.meshIndexZX) == 0) { D_80165330[playerId] = 0; } - break; - default: + } + } else if (GetCourse() == GetFrappeSnowland()) { + if ((player->surfaceType == SNOW_OFFROAD) && (D_80165330[playerId] == 0)) { + D_80165330[playerId] = 1; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (player->surfaceType != SNOW_OFFROAD) { D_80165330[playerId] = 0; - if (1) {} - break; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } + } else if (GetCourse() == GetRoyalRaceway()) { + if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) != 0) && (D_80165330[playerId] == 0)) { + D_80165330[playerId] = 1; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) == 0) && !(player->effects & 8)) { + D_80165330[playerId] = 0; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } + } else if (GetCourse() == GetRainbowRoad()) { + if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) { + D_80165330[playerId] = 1; + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (D_80165330[playerId] == 0) { + gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId]; + gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId]; + } else if (!((player->effects & 8) || (player->unk_0CA & 1))) { + D_80165330[playerId] = 0; + } + } else { + D_80165330[playerId] = 0; + if (1) {} } } @@ -1772,9 +1772,9 @@ void func_8002C4F8(Player* player, s8 arg1) { if ((player->unk_0DE & 4) != 4) { player->unk_0DE |= 8; player->unk_0DE |= 4; - if ((gCurrentCourseId != COURSE_KOOPA_BEACH) && (gCurrentCourseId != COURSE_SKYSCRAPER) && - (gCurrentCourseId != COURSE_RAINBOW_ROAD) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) { - if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { + if ((GetCourse() != GetKoopaTroopaBeach()) && (GetCourse() != GetSkyscraper()) && + (GetCourse() != GetRainbowRoad()) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) { + if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) { func_800C9060((u8) arg1, 0x1900801CU); } else { func_800C9060((u8) arg1, 0x19008008U); @@ -1782,8 +1782,8 @@ void func_8002C4F8(Player* player, s8 arg1) { } } } - if ((gCurrentCourseId == COURSE_KOOPA_BEACH) || (gCurrentCourseId == COURSE_SKYSCRAPER) || - (gCurrentCourseId == COURSE_RAINBOW_ROAD)) { + if ((GetCourse() == GetKoopaTroopaBeach()) || (GetCourse() == GetSkyscraper()) || + (GetCourse() == GetRainbowRoad())) { player->unk_0DE &= ~0x000C; } if ((player->boundingBoxSize < (D_801652A0[arg1] - player->pos[1])) && @@ -2248,7 +2248,7 @@ void func_8002D268(Player* player, UNUSED Camera* camera, s8 screenId, s8 player player->unk_DB4.unkC = 1.5f; if (((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) && ((player->type & PLAYER_INVISIBLE_OR_BOMB) != PLAYER_INVISIBLE_OR_BOMB)) { - if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (gCurrentCourseId == COURSE_BOWSER_CASTLE)) { + if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (GetCourse() == GetBowsersCastle())) { func_800CADD0((u8) playerId, player->unk_0C2 / 14.0f); } else { func_800CADD0((u8) playerId, player->unk_0C2 / 25.0f); diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 20f5bdc76..354958a1f 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -2,6 +2,30 @@ #include #include "Engine.h" +#include "engine/World.h" +#include "engine/courses/MarioRaceway.h" +#include "engine/courses/ChocoMountain.h" +#include "engine/courses/BowsersCastle.h" +#include "engine/courses/BansheeBoardwalk.h" +#include "engine/courses/YoshiValley.h" +#include "engine/courses/FrappeSnowland.h" +#include "engine/courses/KoopaTroopaBeach.h" +#include "engine/courses/RoyalRaceway.h" +#include "engine/courses/LuigiRaceway.h" +#include "engine/courses/MooMooFarm.h" +#include "engine/courses/ToadsTurnpike.h" +#include "engine/courses/KalimariDesert.h" +#include "engine/courses/SherbetLand.h" +#include "engine/courses/RainbowRoad.h" +#include "engine/courses/WarioStadium.h" +#include "engine/courses/BlockFort.h" +#include "engine/courses/Skyscraper.h" +#include "engine/courses/DoubleDeck.h" +#include "engine/courses/DKJungle.h" +#include "engine/courses/BigDonut.h" +#include "engine/courses/TestCourse.h" + +#include "engine/courses/PodiumCeremony.h" extern "C" { #include "main.h" @@ -16,6 +40,407 @@ extern "C" void Graphics_PushFrame(Gfx* data) { extern "C" void Timer_Update(); +// Create the world instance +World gWorldInstance; + +MarioRaceway* gMarioRaceway; +ChocoMountain* gChocoMountain; +BowsersCastle* gBowsersCastle; +BansheeBoardwalk* gBansheeBoardwalk; +YoshiValley* gYoshiValley; +FrappeSnowland* gFrappeSnowland; +KoopaTroopaBeach* gKoopaTroopaBeach; +RoyalRaceway* gRoyalRaceway; +LuigiRaceway* gLuigiRaceway; +MooMooFarm* gMooMooFarm; +ToadsTurnpike* gToadsTurnpike; +KalimariDesert* gKalimariDesert; +SherbetLand* gSherbetLand; +RainbowRoad* gRainbowRoad; +WarioStadium* gWarioStadium; +BlockFort* gBlockFort; +Skyscraper* gSkyscraper; +DoubleDeck* gDoubleDeck; +DKJungle* gDkJungle; +BigDonut* gBigDonut; +PodiumCeremony* gPodiumCeremony; +TestCourse* gTestCourse; + + void CustomEngineInit() { + + gMarioRaceway = new MarioRaceway(); + gChocoMountain = new ChocoMountain(); + gBowsersCastle = new BowsersCastle(); + gBansheeBoardwalk = new BansheeBoardwalk(); + gYoshiValley = new YoshiValley(); + gFrappeSnowland = new FrappeSnowland(); + gKoopaTroopaBeach = new KoopaTroopaBeach(); + gRoyalRaceway = new RoyalRaceway(); + gLuigiRaceway = new LuigiRaceway(); + gMooMooFarm = new MooMooFarm(); + gToadsTurnpike = new ToadsTurnpike(); + gKalimariDesert = new KalimariDesert(); + gSherbetLand = new SherbetLand(); + gRainbowRoad = new RainbowRoad(); + gWarioStadium = new WarioStadium(); + gBlockFort = new BlockFort(); + gSkyscraper = new Skyscraper(); + gDoubleDeck = new DoubleDeck(); + gDkJungle = new DKJungle(); + gBigDonut = new BigDonut(); + gPodiumCeremony = new PodiumCeremony(); + gTestCourse = new TestCourse(); + + /* Add all courses to the global course list */ + gWorldInstance.Courses.push_back(gMarioRaceway); + gWorldInstance.Courses.push_back(gChocoMountain); + gWorldInstance.Courses.push_back(gBowsersCastle); + gWorldInstance.Courses.push_back(gBansheeBoardwalk); + gWorldInstance.Courses.push_back(gYoshiValley); + gWorldInstance.Courses.push_back(gFrappeSnowland); + gWorldInstance.Courses.push_back(gKoopaTroopaBeach); + gWorldInstance.Courses.push_back(gRoyalRaceway); + gWorldInstance.Courses.push_back(gLuigiRaceway); + gWorldInstance.Courses.push_back(gMooMooFarm); + gWorldInstance.Courses.push_back(gToadsTurnpike); + gWorldInstance.Courses.push_back(gKalimariDesert); + gWorldInstance.Courses.push_back(gSherbetLand); + gWorldInstance.Courses.push_back(gRainbowRoad); + gWorldInstance.Courses.push_back(gWarioStadium); + gWorldInstance.Courses.push_back(gBlockFort); + gWorldInstance.Courses.push_back(gSkyscraper); + gWorldInstance.Courses.push_back(gDoubleDeck); + gWorldInstance.Courses.push_back(gDkJungle); + gWorldInstance.Courses.push_back(gBigDonut); + gWorldInstance.Courses.push_back(gTestCourse); + + /* Instantiate Cups */ + Cup* mushroom = gWorldInstance.AddCup("mushroom cup", std::vector{ + gLuigiRaceway, gMooMooFarm, gKoopaTroopaBeach, gKalimariDesert}); + Cup* flower = gWorldInstance.AddCup("flower cup", std::vector{ + gToadsTurnpike, gFrappeSnowland, gChocoMountain, gMarioRaceway}); + Cup* star = gWorldInstance.AddCup("star cup", std::vector{ + gWarioStadium, gSherbetLand, gRoyalRaceway, gBowsersCastle}); + Cup* special = gWorldInstance.AddCup("special cup", std::vector{ + gDkJungle, gYoshiValley, gBansheeBoardwalk, gRainbowRoad}); + Cup* battle = gWorldInstance.AddCup("battle", std::vector{ + gBigDonut, gBlockFort, gDoubleDeck, gSkyscraper}); + + /* Set default course; mario raceway */ + gWorldInstance.CurrentCourse = gMarioRaceway; + gWorldInstance.CurrentCup = flower; + gWorldInstance.CurrentCup->CursorPosition = 3; +} + +extern "C" { + u32 WorldNextCup(void) { + return gWorldInstance.NextCup(); + } + + u32 WorldPreviousCup(void) { + return gWorldInstance.PreviousCup(); + } + + void SetCupIndex(int16_t courseId) { + gWorldInstance.SetCupIndex(courseId); + } + + void SetCup() { + gWorldInstance.SetCup(); + } + + u32 GetCupIndex(void) { + printf("Cup Index: %d\n", gWorldInstance.GetCupIndex()); + return gWorldInstance.GetCupIndex(); + } + + const char* GetCupName(void) { + return gWorldInstance.Cups[gWorldInstance.CupIndex]->Name; + } + + void LoadCourse() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->Load(); + } + } + + CProperties* GetCoursePropsA() { + return (CProperties*) gWorldInstance.GetCourseProps(); + } + + size_t GetCourseIndex() { + return gWorldInstance.CourseIndex; + } + + void SetCourse(const char* name) { + gWorldInstance.SetCourse(name); + } + + void NextCourse() { + gWorldInstance.NextCourse(); + } + + void PreviousCourse() { + gWorldInstance.PreviousCourse(); + } + + void CourseManager_SpawnVehicles() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SpawnVehicles(); + } + } + + void CourseManager_UpdateVehicles() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->UpdateVehicles(); + } + } + + void CourseManager_LoadTextures() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->LoadTextures(); + } + } + + void CourseManager_RenderCourse(struct UnkStruct_800DC5EC* arg0) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->Render(arg0); + } + } + + void CourseManager_RenderCredits() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->RenderCredits(); + } + } + + void CourseManager_SpawnActors() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SpawnActors(); + } + } + + void CourseManager_InitClouds() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->InitClouds(); + } + } + + void CourseManager_UpdateClouds(s32 arg0, Camera* camera) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->UpdateClouds(arg0, camera); + } + } + + void CourseManager_Waypoints(Player* player, int8_t playerId) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->Waypoints(player, playerId); + } + } + + void CourseManager_GenerateCollision() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->GenerateCollision(); + } + } + + void CourseManager_SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SomeCollisionThing(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + } + + void CourseManager_MinimapSettings() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->MinimapSettings(); + } + } + + void CourseManager_InitCourseObjects() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->InitCourseObjects(); + } + } + + void CourseManager_UpdateCourseObjects() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->UpdateCourseObjects(); + } + } + + void CourseManager_RenderCourseObjects(s32 cameraId) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->RenderCourseObjects(cameraId); + } + } + + void CourseManager_SomeSounds() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SomeSounds(); + } + } + + void CourseManager_SetCourseVtxColours() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SetCourseVtxColours(); + } + } + + void CourseManager_WhatDoesThisDo(Player* player, int8_t playerId) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->WhatDoesThisDo(player, playerId); + } + } + + void CourseManager_WhatDoesThisDoAI(Player* player, int8_t playerId) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->WhatDoesThisDoAI(player, playerId); + } + } + + void CourseManager_MinimapFinishlinePosition() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->MinimapFinishlinePosition(); + } + } + + void CourseManager_SetStaffGhost() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SetStaffGhost(); + } + } + + CProperties *CourseManager_GetProps() { + if (gWorldInstance.CurrentCourse) { + return (CProperties*) &gWorldInstance.CurrentCourse->Props; + } + } + + void CourseManager_SpawnBombKarts() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->SpawnBombKarts(); + } + } + + void CourseManager_Water() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.CurrentCourse->Water(); + } + } + + size_t GetCupCursorPosition() { + return gWorldInstance.CurrentCup->CursorPosition; + } + + void SetCupCursorPosition(size_t position) { + gWorldInstance.CurrentCup->CursorPosition = position; + } + + size_t GetCupSize() { + return gWorldInstance.CurrentCup->GetSize(); + } + + void SetCourseFromCup() { + gWorldInstance.CurrentCourse = gWorldInstance.CurrentCup->GetCourse(); + } + + Course* GetCourse(void) { + return gWorldInstance.CurrentCourse; + } + + void SetCourseByClass(void* course) { + gWorldInstance.CurrentCourse = (Course*) course; + } + + void* GetMarioRaceway(void) { + return gMarioRaceway; + } + + void* GetLuigiRaceway(void) { + return gLuigiRaceway; + } + + void* GetChocoMountain(void) { + return gChocoMountain; + } + + void* GetBowsersCastle(void) { + return gBowsersCastle; + } + + void* GetBansheeBoardwalk(void) { + return gBansheeBoardwalk; + } + + void* GetYoshiValley(void) { + return gYoshiValley; + } + + void* GetFrappeSnowland(void) { + return gFrappeSnowland; + } + + void* GetKoopaTroopaBeach(void) { + return gKoopaTroopaBeach; + } + + void* GetRoyalRaceway(void) { + return gRoyalRaceway; + } + + void* GetMooMooFarm(void) { + return gMooMooFarm; + } + + void* GetToadsTurnpike(void) { + return gToadsTurnpike; + } + + void* GetKalimariDesert(void) { + return gKalimariDesert; + } + + void* GetSherbetLand(void) { + return gSherbetLand; + } + + void* GetRainbowRoad(void) { + return gRainbowRoad; + } + + void* GetWarioStadium(void) { + return gWarioStadium; + } + + void* GetBlockFort(void) { + return gBlockFort; + } + + void* GetSkyscraper(void) { + return gSkyscraper; + } + + void* GetDoubleDeck(void) { + return gDoubleDeck; + } + + void* GetDkJungle(void) { + return gDkJungle; + } + + void* GetBigDonut(void) { + return gBigDonut; + } + + void* GetPodiumCeremony(void) { + return gPodiumCeremony; + } + + void* GetTestCourse(void) { + return gTestCourse; + } +} + void push_frame() { // GameEngine::StartAudioFrame(); GameEngine::Instance->StartFrame(); @@ -38,6 +463,8 @@ extern "C" GameEngine::Create(); // audio_init(); // sound_init(); + + CustomEngineInit(); thread5_game_loop(); while (WindowIsRunning()) { push_frame(); diff --git a/src/port/resource/importers/TrackSectionsFactory.cpp b/src/port/resource/importers/TrackSectionsFactory.cpp index c8f106e49..3a5f781b4 100644 --- a/src/port/resource/importers/TrackSectionsFactory.cpp +++ b/src/port/resource/importers/TrackSectionsFactory.cpp @@ -4,7 +4,8 @@ #include "libultraship/libultra/gbi.h" extern "C" { -#include "memory.h" +//#include "memory.h" // Removed to prevent C linkage errors likely related with #include common_structs.h +void* segmented_uintptr_t_to_virtual(uintptr_t); } namespace MK64 { diff --git a/src/port/ui/GameInfoWindow.cpp b/src/port/ui/GameInfoWindow.cpp index a27531918..d7a9ecf2d 100644 --- a/src/port/ui/GameInfoWindow.cpp +++ b/src/port/ui/GameInfoWindow.cpp @@ -72,6 +72,8 @@ void GameInfoWindow::DrawElement() { if (gGamestate == RACING) { + ImGui::Text("Player %f, %f, %f", gPlayers[0].pos[0], gPlayers[0].pos[1], gPlayers[0].pos[2]); + for (int i = 0; i < NUM_PLAYERS; i++) { ImGui::Text("Player %d: type: %X, char: %d, rank: %d, hasAuthority: %d", i, gPlayers[i].type, gPlayers[i].characterId, gPlayers[i].currentRank, gPlayers[i].nHasAuthority); diff --git a/src/racing/actors.c b/src/racing/actors.c index 38a4b5438..0b043f519 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -846,7 +846,7 @@ void spawn_piranha_plants(const char* spawnData) { } } -void spawn_palm_trees(struct ActorSpawnData* spawnData) { +void spawn_palm_trees(const char* spawnData) { struct ActorSpawnData* temp_s0 = (struct ActorSpawnData*) LOAD_ASSET(spawnData); struct PalmTree* temp_v1; Vec3f startingPos; @@ -874,13 +874,14 @@ void spawn_palm_trees(struct ActorSpawnData* spawnData) { #include "actors/falling_rock/update.inc.c" // Trees, cacti, shrubs, etc. +//! @todo actorType needs to be passed into this function for flexibility void spawn_foliage(const char* actor) { UNUSED s32 pad[4]; Vec3f position; Vec3f velocity; Vec3s rotation; UNUSED s16 pad2; - s16 actorType; + s16 actorType = 0; struct Actor* temp_s0; struct ActorSpawnData* var_s3; @@ -895,48 +896,39 @@ void spawn_foliage(const char* actor) { position[2] = var_s3->pos[2]; position[1] = var_s3->pos[1]; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - actorType = 2; - break; - case COURSE_BOWSER_CASTLE: - actorType = 0x0021; - break; - case COURSE_YOSHI_VALLEY: - actorType = 3; - break; - case COURSE_FRAPPE_SNOWLAND: - actorType = 0x001D; - break; - case COURSE_ROYAL_RACEWAY: - switch (var_s3->signedSomeId) { - case 6: - actorType = 0x001C; - break; - case 7: - actorType = 4; - break; - } - break; - case COURSE_LUIGI_RACEWAY: - actorType = 0x001A; - break; - case COURSE_MOO_MOO_FARM: - actorType = 0x0013; - break; - case COURSE_KALAMARI_DESERT: - switch (var_s3->signedSomeId) { - case 5: - actorType = 0x001E; - break; - case 6: - actorType = 0x001F; - break; - case 7: - actorType = 0x0020; - break; - } - break; + if (GetCourse() == GetMarioRaceway()) { + actorType = 2; + } else if (GetCourse() == GetBowsersCastle()) { + actorType = 0x0021; + } else if (GetCourse() == GetYoshiValley()) { + actorType = 3; + } else if (GetCourse() == GetFrappeSnowland()) { + actorType = 0x001D; + } else if (GetCourse() == GetRoyalRaceway()) { + switch (var_s3->signedSomeId) { + case 6: + actorType = 0x001C; + break; + case 7: + actorType = 4; + break; + } + } else if (GetCourse() == GetLuigiRaceway()) { + actorType = 0x001A; + } else if (GetCourse() == GetMooMooFarm()) { + actorType = 0x0013; + } else if (GetCourse() == GetKalimariDesert()) { + switch (var_s3->signedSomeId) { + case 5: + actorType = 0x001E; + break; + case 6: + actorType = 0x001F; + break; + case 7: + actorType = 0x0020; + break; + } } temp_s0 = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, actorType)]; @@ -960,7 +952,12 @@ void spawn_all_item_boxes(const char* spawnData) { Vec3f startingPos; Vec3f startingVelocity; Vec3s startingRot; - struct ActorSpawnData* temp_s0 = (struct ActorSpawnData*) LOAD_ASSET(spawnData); + struct ActorSpawnData* temp_s0; + if (GetCourse() == GetTestCourse()) { + temp_s0 = (struct ActorSpawnData*) spawnData; + } else { + temp_s0 = (struct ActorSpawnData*) LOAD_ASSET(spawnData); + } // struct ItemBox *itemBox; if ((gModeSelection == TIME_TRIALS) || (gPlaceItemBoxes == 0)) { @@ -1048,125 +1045,127 @@ void spawn_course_actors(void) { struct RailroadCrossing* rrxing; gNumPermanentActors = 0; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - spawn_foliage(d_course_mario_raceway_tree_spawns); - spawn_piranha_plants(d_course_mario_raceway_piranha_plant_spawns); - spawn_all_item_boxes(d_course_mario_raceway_item_box_spawns); - vec3f_set(position, 150.0f, 40.0f, -1300.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); - vec3f_set(position, 2520.0f, 0.0f, 1240.0f); - position[0] *= gCourseDirection; - actor = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)]; - actor->flags |= 0x4000; - break; - case COURSE_CHOCO_MOUNTAIN: - spawn_all_item_boxes(d_course_choco_mountain_item_box_spawns); - spawn_falling_rocks(d_course_choco_mountain_falling_rock_spawns); - break; - case COURSE_BOWSER_CASTLE: - spawn_foliage(d_course_bowsers_castle_tree_spawn); - spawn_all_item_boxes(d_course_bowsers_castle_item_box_spawns); - break; - case COURSE_BANSHEE_BOARDWALK: - spawn_all_item_boxes(d_course_banshee_boardwalk_item_box_spawns); - break; - case COURSE_YOSHI_VALLEY: - spawn_foliage(d_course_yoshi_valley_tree_spawn); - spawn_all_item_boxes(d_course_yoshi_valley_item_box_spawns); - vec3f_set(position, -2300.0f, 0.0f, 634.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); - break; - case COURSE_FRAPPE_SNOWLAND: - spawn_foliage(d_course_frappe_snowland_tree_spawns); - spawn_all_item_boxes(d_course_frappe_snowland_item_box_spawns); - break; - case COURSE_KOOPA_BEACH: - init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f); - spawn_all_item_boxes(d_course_koopa_troopa_beach_item_box_spawns); - spawn_palm_trees(d_course_koopa_troopa_beach_tree_spawn); - break; - case COURSE_ROYAL_RACEWAY: - spawn_foliage(d_course_royal_raceway_tree_spawn); - spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns); - spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn); - break; - case COURSE_LUIGI_RACEWAY: - spawn_foliage(d_course_luigi_raceway_tree_spawn); - spawn_all_item_boxes(d_course_luigi_raceway_item_box_spawns); - break; - case COURSE_MOO_MOO_FARM: - if (gPlayerCountSelection1 != 4) { - spawn_foliage(d_course_moo_moo_farm_tree_spawn); - } - spawn_all_item_boxes(d_course_moo_moo_farm_item_box_spawns); - break; - case COURSE_TOADS_TURNPIKE: - spawn_all_item_boxes(d_course_toads_turnpike_item_box_spawns); - break; - case COURSE_KALAMARI_DESERT: - spawn_foliage(d_course_kalimari_desert_cactus_spawn); - spawn_all_item_boxes(d_course_kalimari_desert_item_box_spawns); - vec3f_set(position, -1680.0f, 2.0f, 35.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; - rrxing->crossingId = 1; - vec3f_set(position, -1600.0f, 2.0f, 35.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; - rrxing->crossingId = 1; - vec3s_set(rotation, 0, -0x2000, 0); - vec3f_set(position, -2459.0f, 2.0f, 2263.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; - rrxing->crossingId = 0; - vec3f_set(position, -2467.0f, 2.0f, 2375.0f); - position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; - rrxing->crossingId = 0; - break; - case COURSE_SHERBET_LAND: - spawn_all_item_boxes(d_course_sherbet_land_item_box_spawns); - break; - case COURSE_RAINBOW_ROAD: - spawn_all_item_boxes(d_course_rainbow_road_item_box_spawns); - break; - case COURSE_WARIO_STADIUM: - spawn_all_item_boxes(d_course_wario_stadium_item_box_spawns); - vec3f_set(position, -131.0f, 83.0f, 286.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - vec3f_set(position, -2353.0f, 72.0f, -1608.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - vec3f_set(position, -2622.0f, 79.0f, 739.0f); - position[0] *= gCourseDirection; - add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - break; - case COURSE_BLOCK_FORT: - spawn_all_item_boxes(d_course_block_fort_item_box_spawns); - break; - case COURSE_SKYSCRAPER: - spawn_all_item_boxes(d_course_skyscraper_item_box_spawns); - break; - case COURSE_DOUBLE_DECK: - spawn_all_item_boxes(d_course_double_deck_item_box_spawns); - break; - case COURSE_DK_JUNGLE: - spawn_all_item_boxes(d_course_dks_jungle_parkway_item_box_spawns); - init_kiwano_fruit(); - func_80298D10(); - break; - case COURSE_BIG_DONUT: - spawn_all_item_boxes(d_course_big_donut_item_box_spawns); - break; - } + CourseManager_SpawnActors(); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // // spawn_foliage(d_course_mario_raceway_tree_spawns); + // // spawn_piranha_plants(d_course_mario_raceway_piranha_plant_spawns); + // // spawn_all_item_boxes(d_course_mario_raceway_item_box_spawns); + // // vec3f_set(position, 150.0f, 40.0f, -1300.0f); + // // position[0] *= gCourseDirection; + // // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); + // // vec3f_set(position, 2520.0f, 0.0f, 1240.0f); + // // position[0] *= gCourseDirection; + // // actor = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)]; + // // actor->flags |= 0x4000; + // break; + // case COURSE_CHOCO_MOUNTAIN: + // spawn_all_item_boxes(d_course_choco_mountain_item_box_spawns); + // spawn_falling_rocks(d_course_choco_mountain_falling_rock_spawns); + // break; + // case COURSE_BOWSER_CASTLE: + // spawn_foliage(d_course_bowsers_castle_tree_spawn); + // spawn_all_item_boxes(d_course_bowsers_castle_item_box_spawns); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // spawn_all_item_boxes(d_course_banshee_boardwalk_item_box_spawns); + // break; + // case COURSE_YOSHI_VALLEY: + // spawn_foliage(d_course_yoshi_valley_tree_spawn); + // spawn_all_item_boxes(d_course_yoshi_valley_item_box_spawns); + // vec3f_set(position, -2300.0f, 0.0f, 634.0f); + // position[0] *= gCourseDirection; + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); + // break; + // case COURSE_FRAPPE_SNOWLAND: + // spawn_foliage(d_course_frappe_snowland_tree_spawns); + // spawn_all_item_boxes(d_course_frappe_snowland_item_box_spawns); + // break; + // case COURSE_KOOPA_BEACH: + // init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f); + // spawn_all_item_boxes(d_course_koopa_troopa_beach_item_box_spawns); + // spawn_palm_trees(d_course_koopa_troopa_beach_tree_spawn); + // break; + // case COURSE_ROYAL_RACEWAY: + // spawn_foliage(d_course_royal_raceway_tree_spawn); + // spawn_all_item_boxes(d_course_royal_raceway_item_box_spawns); + // spawn_piranha_plants(d_course_royal_raceway_piranha_plant_spawn); + // break; + // case COURSE_LUIGI_RACEWAY: + // spawn_foliage(d_course_luigi_raceway_tree_spawn); + // spawn_all_item_boxes(d_course_luigi_raceway_item_box_spawns); + // break; + // case COURSE_MOO_MOO_FARM: + // if (gPlayerCountSelection1 != 4) { + // spawn_foliage(d_course_moo_moo_farm_tree_spawn); + // } + // spawn_all_item_boxes(d_course_moo_moo_farm_item_box_spawns); + // break; + // case COURSE_TOADS_TURNPIKE: + // spawn_all_item_boxes(d_course_toads_turnpike_item_box_spawns); + // break; + // case COURSE_KALAMARI_DESERT: + // spawn_foliage(d_course_kalimari_desert_cactus_spawn); + // spawn_all_item_boxes(d_course_kalimari_desert_item_box_spawns); + // vec3f_set(position, -1680.0f, 2.0f, 35.0f); + // position[0] *= gCourseDirection; + // rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + // ACTOR_RAILROAD_CROSSING)]; + // rrxing->crossingId = 1; + // vec3f_set(position, -1600.0f, 2.0f, 35.0f); + // position[0] *= gCourseDirection; + // rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + // ACTOR_RAILROAD_CROSSING)]; + // rrxing->crossingId = 1; + // vec3s_set(rotation, 0, -0x2000, 0); + // vec3f_set(position, -2459.0f, 2.0f, 2263.0f); + // position[0] *= gCourseDirection; + // rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + // ACTOR_RAILROAD_CROSSING)]; + // rrxing->crossingId = 0; + // vec3f_set(position, -2467.0f, 2.0f, 2375.0f); + // position[0] *= gCourseDirection; + // rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, + // ACTOR_RAILROAD_CROSSING)]; + // rrxing->crossingId = 0; + // break; + // case COURSE_SHERBET_LAND: + // spawn_all_item_boxes(d_course_sherbet_land_item_box_spawns); + // break; + // case COURSE_RAINBOW_ROAD: + // spawn_all_item_boxes(d_course_rainbow_road_item_box_spawns); + // break; + // case COURSE_WARIO_STADIUM: + // spawn_all_item_boxes(d_course_wario_stadium_item_box_spawns); + // vec3f_set(position, -131.0f, 83.0f, 286.0f); + // position[0] *= gCourseDirection; + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // vec3f_set(position, -2353.0f, 72.0f, -1608.0f); + // position[0] *= gCourseDirection; + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // vec3f_set(position, -2622.0f, 79.0f, 739.0f); + // position[0] *= gCourseDirection; + // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + // break; + // case COURSE_BLOCK_FORT: + // spawn_all_item_boxes(d_course_block_fort_item_box_spawns); + // break; + // case COURSE_SKYSCRAPER: + // spawn_all_item_boxes(d_course_skyscraper_item_box_spawns); + // break; + // case COURSE_DOUBLE_DECK: + // spawn_all_item_boxes(d_course_double_deck_item_box_spawns); + // break; + // case COURSE_DK_JUNGLE: + // spawn_all_item_boxes(d_course_dks_jungle_parkway_item_box_spawns); + // init_kiwano_fruit(); + // func_80298D10(); + // break; + // case COURSE_BIG_DONUT: + // spawn_all_item_boxes(d_course_big_donut_item_box_spawns); + // break; + // } gNumPermanentActors = gNumActors; } @@ -1203,73 +1202,9 @@ void init_actors_and_load_textures(void) { dma_textures(gTextureFinishLineBanner8, 0x0000025BU, 0x00000800U); dma_textures(gTexture671A88, 0x00000400U, 0x00000800U); dma_textures(gTexture6774D8, 0x00000400U, 0x00000800U); - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - dma_textures(gTextureTrees1, 0x0000035BU, 0x00000800U); - D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant2, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant3, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant4, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant5, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant6, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant7, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant8, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); - break; - case COURSE_BOWSER_CASTLE: - dma_textures(gTextureShrub, 0x000003FFU, 0x00000800U); - break; - case COURSE_YOSHI_VALLEY: - dma_textures(gTextureTrees2, 0x000003E8U, 0x00000800U); - break; - case COURSE_FRAPPE_SNOWLAND: - dma_textures(gTextureFrappeSnowlandTreeLeft, 0x00000454U, 0x00000800U); - dma_textures(gTextureFrappeSnowlandTreeRight, 0x00000432U, 0x00000800U); - break; - case COURSE_ROYAL_RACEWAY: - dma_textures(gTextureTrees3, 0x000003E8U, 0x00000800U); - dma_textures(gTextureTrees7, 0x000003E8U, 0x00000800U); - D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant2, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant3, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant4, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant5, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant6, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant7, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant8, 0x000003E8U, 0x00000800U); - dma_textures(gTexturePiranhaPlant9, 0x000003E8U, 0x00000800U); - break; - case COURSE_LUIGI_RACEWAY: - dma_textures(gTextureTrees5Left, 0x000003E8U, 0x00000800U); - dma_textures(gTextureTrees5Right, 0x000003E8U, 0x00000800U); - break; - case COURSE_MOO_MOO_FARM: - dma_textures(gTextureTrees4Left, 0x000003E8U, 0x00000800U); - dma_textures(gTextureTrees4Right, 0x000003E8U, 0x00000800U); - dma_textures(gTextureCow01Left, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow01Right, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow02Left, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow02Right, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow03Left, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow03Right, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow04Left, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow04Right, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow05Left, 0x00000400U, 0x00000800U); - dma_textures(gTextureCow05Right, 0x00000400U, 0x00000800U); - break; - case COURSE_KALAMARI_DESERT: - dma_textures(gTextureCactus1Left, 0x0000033EU, 0x00000800U); - dma_textures(gTextureCactus1Right, 0x000002FBU, 0x00000800U); - dma_textures(gTextureCactus2Left, 0x000002A8U, 0x00000800U); - dma_textures(gTextureCactus2Right, 0x00000374U, 0x00000800U); - dma_textures(gTextureCactus3, 0x000003AFU, 0x00000800U); - break; - case COURSE_DK_JUNGLE: - dma_textures(gTextureDksJungleParkwayKiwanoFruit1, 0x0000032FU, 0x00000400U); - dma_textures(gTextureDksJungleParkwayKiwanoFruit2, 0x00000369U, 0x00000400U); - dma_textures(gTextureDksJungleParkwayKiwanoFruit3, 0x00000364U, 0x00000400U); - break; - } + + CourseManager_LoadTextures(); + init_red_shell_texture(); destroy_all_actors(); spawn_course_actors(); @@ -1719,8 +1654,8 @@ bool collision_tree(Player* player, struct Actor* actor) { actorPos[0] = actor->pos[0]; actorPos[1] = actor->pos[1]; actorPos[2] = actor->pos[2]; - if (((gCurrentCourseId == COURSE_MARIO_RACEWAY) || (gCurrentCourseId == COURSE_YOSHI_VALLEY) || - (gCurrentCourseId == COURSE_ROYAL_RACEWAY) || (gCurrentCourseId == COURSE_LUIGI_RACEWAY)) && + if (((GetCourse() == GetMarioRaceway()) || (GetCourse() == GetYoshiValley()) || + (GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetLuigiRaceway())) && (player->unk_094 > 1.0f)) { spawn_leaf(actorPos, 0); } @@ -2574,13 +2509,10 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { break; } } - switch (gCurrentCourseId) { - case COURSE_MOO_MOO_FARM: - render_cows(camera, D_801502C0, actor); - break; - case COURSE_DK_JUNGLE: - render_palm_trees(camera, D_801502C0, actor); - break; + if (GetCourse() == GetMooMooFarm()) { + render_cows(camera, D_801502C0, actor); + } else if (GetCourse() == GetDkJungle()) { + render_palm_trees(camera, D_801502C0, actor); } } diff --git a/src/racing/actors.h b/src/racing/actors.h index 1df2d08d4..38ccb5c2a 100644 --- a/src/racing/actors.h +++ b/src/racing/actors.h @@ -68,9 +68,9 @@ void render_actor_train_tender(Camera*, struct TrainCar*); void render_actor_train_passenger_car(Camera*, struct TrainCar*); void render_actor_falling_rock(Camera*, struct FallingRock*); void spawn_piranha_plants(const char*); -void spawn_palm_trees(struct ActorSpawnData*); +void spawn_palm_trees(const char*); void func_8029CF0C(struct ActorSpawnData*, struct FallingRock*); -void spawn_falling_rocks(struct ActorSpawnData*); +void spawn_falling_rocks(const char*); void update_actor_falling_rocks(struct FallingRock*); void spawn_foliage(const char*); void spawn_all_item_boxes(const char*); diff --git a/src/racing/collision.c b/src/racing/collision.c index 2f688810c..19f1c730a 100644 --- a/src/racing/collision.c +++ b/src/racing/collision.c @@ -45,69 +45,68 @@ f32 func_802AAB4C(Player* player) { playerX = player->pos[0]; playerZ = player->pos[2]; - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - if (playerX > 1859.0f) { - return D_8015F8E4; - } - if (playerX < 1549.0f) { - return D_8015F8E4; - } - if (playerZ > -1102.0f) { - return D_8015F8E4; - } - if (playerZ < -1402.0f) { - return D_8015F8E4; - } - return 20.0f; - case COURSE_KOOPA_BEACH: - if (playerX > 239.0f) { - return D_8015F8E4; - } - if (playerX < 67.0f) { - return D_8015F8E4; - } - if (playerZ > 2405.0f) { - return D_8015F8E4; - } - if (playerZ < 2233.0f) { - return D_8015F8E4; - } - return 0.8f; - case COURSE_SHERBET_LAND: - if ((get_surface_type(player->collision.meshIndexZX) & 0xFF) == SNOW) { - return (f32) (gCourseMinY - 0xA); - } + if (GetCourse() == GetBowsersCastle()) { + if (playerX > 1859.0f) { return D_8015F8E4; - case COURSE_DK_JUNGLE: - temp_v1 = get_track_section_id(player->collision.meshIndexZX) & 0xFF; - if (temp_v1 == 0xFF) { - if ((get_surface_type(player->collision.meshIndexZX) & 0xFF) == CAVE) { - return -475.0f; - } - if (playerX > -478.0f) { - return -33.9f; - } - if (playerX < -838.0f) { - return -475.0f; - } - if (playerZ > -436.0f) { - return -475.0f; - } - if (playerZ < -993.0f) { - return -33.9f; - } - if (playerZ < playerX) { - return -475.0f; - } + } + if (playerX < 1549.0f) { + return D_8015F8E4; + } + if (playerZ > -1102.0f) { + return D_8015F8E4; + } + if (playerZ < -1402.0f) { + return D_8015F8E4; + } + return 20.0f; + } else if (GetCourse() == GetKoopaTroopaBeach()) { + if (playerX > 239.0f) { + return D_8015F8E4; + } + if (playerX < 67.0f) { + return D_8015F8E4; + } + if (playerZ > 2405.0f) { + return D_8015F8E4; + } + if (playerZ < 2233.0f) { + return D_8015F8E4; + } + return 0.8f; + } else if (GetCourse() == GetSherbetLand()) { + if ((get_surface_type(player->collision.meshIndexZX) & 0xFF) == SNOW) { + return (f32) (gCourseMinY - 0xA); + } + return D_8015F8E4; + } else if (GetCourse() == GetDkJungle()) { + temp_v1 = get_track_section_id(player->collision.meshIndexZX) & 0xFF; + if (temp_v1 == 0xFF) { + if ((get_surface_type(player->collision.meshIndexZX) & 0xFF) == CAVE) { + return -475.0f; + } + if (playerX > -478.0f) { return -33.9f; } - if (temp_v1 >= 0x14) { + if (playerX < -838.0f) { + return -475.0f; + } + if (playerZ > -436.0f) { + return -475.0f; + } + if (playerZ < -993.0f) { + return -33.9f; + } + if (playerZ < playerX) { return -475.0f; } return -33.9f; - default: - return D_8015F8E4; + } + if (temp_v1 >= 0x14) { + return -475.0f; + } + return -33.9f; + } else { + return D_8015F8E4; } } @@ -1596,7 +1595,7 @@ void add_collision_triangle(Vtx* vtx1, Vtx* vtx2, Vtx* vtx3, s8 surfaceType, u16 triangle->vtx1 = vtx1; triangle->vtx2 = vtx2; triangle->vtx3 = vtx3; - if ((triangle->vtx1->v.flag == 4) && (triangle->vtx2->v.flag == 4) && (triangle->vtx3->v.flag == 4)) { + if ((triangle->vtx1->v.flag == 4) && (triangle->vtx2->v.flag == 4) && (triangle->vtx3->v.flag == 4)) { return; } @@ -2124,7 +2123,7 @@ void set_vertex_colours(uintptr_t addr, u32 vertexCount, UNUSED s32 vert3, s8 al /** * Recursive search for vertices and set their colour values. */ -void find_vtx_and_set_colours(uintptr_t displayList, s8 alpha, u8 red, u8 green, u8 blue) { +void find_vtx_and_set_colours(Gfx *displayList, s8 alpha, u8 red, u8 green, u8 blue) { Gfx* gfx = (Gfx*) displayList; uintptr_t lo; uintptr_t hi; @@ -2137,7 +2136,7 @@ void find_vtx_and_set_colours(uintptr_t displayList, s8 alpha, u8 red, u8 green, if (opcode == (G_ENDDL << 24)) { break; } else if (opcode == (G_DL << 24)) { - find_vtx_and_set_colours(hi, alpha, red, green, blue); + find_vtx_and_set_colours((Gfx *)hi, alpha, red, green, blue); } else if (opcode == (G_VTX << 24)) { // G_VTX contains an addr hi set_vertex_colours(hi, (lo >> 10) & 0x3F, ((lo >> 16) & 0xFF) >> 1, alpha, red, green, blue); diff --git a/src/racing/collision.h b/src/racing/collision.h index dd1b6dfda..a6c3aca29 100644 --- a/src/racing/collision.h +++ b/src/racing/collision.h @@ -36,7 +36,7 @@ void generate_collision_mesh_with_default_section_id(Gfx*, s8); void generate_collision_mesh(Gfx*, s8, u16); void find_and_set_tile_size(uintptr_t, s32, s32); void set_vertex_colours(uintptr_t, u32, s32, s8, u8, u8, u8); -void find_vtx_and_set_colours(uintptr_t, s8, u8, u8, u8); +void find_vtx_and_set_colours(Gfx*, s8, u8, u8, u8); void subtract_scaled_vector(Vec3f, f32, Vec3f); #endif diff --git a/src/racing/framebuffer_effects.c b/src/racing/framebuffer_effects.c index 7e70ea53c..be1b917a7 100644 --- a/src/racing/framebuffer_effects.c +++ b/src/racing/framebuffer_effects.c @@ -18,21 +18,21 @@ s32 gReusableFrameBuffer = -1; s32 gN64ResFrameBuffer = -1; void FB_CreateFramebuffers(void) { - if (gPauseFrameBuffer == -1) { - gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); - } + // if (gPauseFrameBuffer == -1) { + // gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); + // } - if (gBlurFrameBuffer == -1) { - gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); - } + // if (gBlurFrameBuffer == -1) { + // gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); + // } - if (gReusableFrameBuffer == -1) { - gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); - } + // if (gReusableFrameBuffer == -1) { + // gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); + // } - if (gN64ResFrameBuffer == -1) { - gN64ResFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, false); - } + // if (gN64ResFrameBuffer == -1) { + // gN64ResFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, false); + // } } // Fixed point macros @@ -69,26 +69,26 @@ void FB_CreateFramebuffers(void) { */ void FB_CopyToFramebuffer(Gfx* gfx, s32 fb_src, s32 fb_dest, u8 oncePerFrame, u8* hasCopied) { - gSPMatrix(gfx++, LOAD_ASSET(D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gfx++, LOAD_ASSET(D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPSetOtherMode(gfx++, - G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); + // gDPSetOtherMode(gfx++, + // G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + // G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + // G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); - gSPClearGeometryMode(gfx++, G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); - gSPSetGeometryMode(gfx++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + // gSPClearGeometryMode(gfx++, G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + // gSPSetGeometryMode(gfx++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); - gDPSetBlendColor(gfx++, 255, 255, 255, 8); - gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF); + // gDPSetBlendColor(gfx++, 255, 255, 255, 8); + // gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF); - gDPSetEnvColor(gfx++, 255, 255, 255, 255); - gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, - ENVIRONMENT); + // gDPSetEnvColor(gfx++, 255, 255, 255, 255); + // gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, + // ENVIRONMENT); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + // gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - gDPCopyFB(gfx++, fb_dest, fb_src, oncePerFrame, hasCopied); + // gDPCopyFB(gfx++, fb_dest, fb_src, oncePerFrame, hasCopied); } /** @@ -99,40 +99,40 @@ void FB_CopyToFramebuffer(Gfx* gfx, s32 fb_src, s32 fb_dest, u8 oncePerFrame, u8 */ void FB_WriteFramebufferSliceToCPU(Gfx* gfx, void* buffer, u8 byteSwap) { // Gfx* gfx = *gfxp; - printf("write!\n"); - FB_CopyToFramebuffer(gfx, 0, gReusableFrameBuffer, false, NULL); + // printf("write!\n"); + // FB_CopyToFramebuffer(gfx, 0, gReusableFrameBuffer, false, NULL); - // Set the N64 resolution framebuffer as the draw target (320x240) - gsSPSetFB(gfx++, gN64ResFrameBuffer); - // Reset scissor for new framebuffer - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + // // Set the N64 resolution framebuffer as the draw target (320x240) + // gsSPSetFB(gfx++, gN64ResFrameBuffer); + // // Reset scissor for new framebuffer + // gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - int16_t s0 = 0, t0 = 0; - int16_t s1 = OTRGetGameRenderWidth(); - int16_t t1 = OTRGetGameRenderHeight(); - printf("half!\n"); - float aspectRatio = OTRGetAspectRatio(); - float fourByThree = 4.0f / 3.0f; + // int16_t s0 = 0, t0 = 0; + // int16_t s1 = OTRGetGameRenderWidth(); + // int16_t t1 = OTRGetGameRenderHeight(); + // printf("half!\n"); + // float aspectRatio = OTRGetAspectRatio(); + // float fourByThree = 4.0f / 3.0f; - // Adjust the texture coordinates so that only a 4:3 region from the center is drawn - // to the N64 resolution buffer. Currently ratios smaller than 4:3 will just stretch to fill. - if (aspectRatio > fourByThree) { - int16_t adjustedWidth = OTRGetGameRenderWidth() / (aspectRatio / fourByThree); - s0 = (OTRGetGameRenderWidth() - adjustedWidth) / 2; - s1 -= s0; - } - printf("Aspect!\n"); - gDPSetTextureImageFB(gfx++, 0, 0, 0, gReusableFrameBuffer); - gDPImageRectangle(gfx++, 0 << 2, 0 << 2, s0, t0, SCREEN_WIDTH << 2, SCREEN_HEIGHT << 2, s1, t1, G_TX_RENDERTILE, - OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); + // // Adjust the texture coordinates so that only a 4:3 region from the center is drawn + // // to the N64 resolution buffer. Currently ratios smaller than 4:3 will just stretch to fill. + // if (aspectRatio > fourByThree) { + // int16_t adjustedWidth = OTRGetGameRenderWidth() / (aspectRatio / fourByThree); + // s0 = (OTRGetGameRenderWidth() - adjustedWidth) / 2; + // s1 -= s0; + // } + // printf("Aspect!\n"); + // gDPSetTextureImageFB(gfx++, 0, 0, 0, gReusableFrameBuffer); + // gDPImageRectangle(gfx++, 0 << 2, 0 << 2, s0, t0, SCREEN_WIDTH << 2, SCREEN_HEIGHT << 2, s1, t1, G_TX_RENDERTILE, + // OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); - // Read the final N64 framebuffer back as rgba16 into the CPU-side buffer - gDPReadFB(gfx++, gN64ResFrameBuffer, buffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, byteSwap); + // // Read the final N64 framebuffer back as rgba16 into the CPU-side buffer + // gDPReadFB(gfx++, gN64ResFrameBuffer, buffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, byteSwap); - gsSPResetFB(gfx++); - // Reset scissor for original framebuffer - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - printf("Complete!\n"); + // gsSPResetFB(gfx++); + // // Reset scissor for original framebuffer + // gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + // printf("Complete!\n"); } /** @@ -140,27 +140,27 @@ void FB_WriteFramebufferSliceToCPU(Gfx* gfx, void* buffer, u8 byteSwap) { */ void FB_DrawFromFramebuffer(Gfx* gfx, s32 fb, u8 alpha) { - gSPMatrix(gfx++, LOAD_ASSET(D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gfx++, LOAD_ASSET(D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + // gDPSetEnvColor(gfx++, 255, 255, 255, alpha); - gDPSetOtherMode(gfx++, - G_AD_NOISE | G_CD_NOISE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | - G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2); + // gDPSetOtherMode(gfx++, + // G_AD_NOISE | G_CD_NOISE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | + // G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + // G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2); - gSPClearGeometryMode(gfx++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); - gSPSetGeometryMode(gfx++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + // gSPClearGeometryMode(gfx++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + // gSPSetGeometryMode(gfx++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); - gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, - ENVIRONMENT); + // gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, + // ENVIRONMENT); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + // gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - gDPSetTextureImageFB(gfx++, 0, 0, 0, fb); - gDPImageRectangle(gfx++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0 << 2, 0, 0, - OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, SCREEN_HEIGHT << 2, OTRGetGameRenderWidth(), - OTRGetGameRenderHeight(), G_TX_RENDERTILE, OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); + // gDPSetTextureImageFB(gfx++, 0, 0, 0, fb); + // gDPImageRectangle(gfx++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0 << 2, 0, 0, + // OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, SCREEN_HEIGHT << 2, OTRGetGameRenderWidth(), + // OTRGetGameRenderHeight(), G_TX_RENDERTILE, OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); } /** @@ -170,25 +170,25 @@ void FB_DrawFromFramebuffer(Gfx* gfx, s32 fb, u8 alpha) { */ void FB_DrawFromFramebufferScaled(Gfx* gfx, s32 fb, u8 alpha, float scaleX, float scaleY) { - gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + // gDPSetEnvColor(gfx++, 255, 255, 255, alpha); - gDPSetOtherMode(gfx++, - G_AD_NOISE | G_CD_NOISE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | - G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2); + // gDPSetOtherMode(gfx++, + // G_AD_NOISE | G_CD_NOISE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | + // G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + // G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2); - gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, - ENVIRONMENT); + // gDPSetCombineLERP(gfx++, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, ENVIRONMENT, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, + // ENVIRONMENT); - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + // gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - gDPSetTextureImageFB(gfx++, 0, 0, 0, fb); + // gDPSetTextureImageFB(gfx++, 0, 0, 0, fb); - float x0 = SCREEN_WIDTH * 0.5f * scaleX; - float y0 = SCREEN_HEIGHT * 0.5f * scaleY; + // float x0 = SCREEN_WIDTH * 0.5f * scaleX; + // float y0 = SCREEN_HEIGHT * 0.5f * scaleY; - gDPImageRectangle(gfx++, OTRGetRectDimensionFromLeftEdge(x0) << 2, (int) (y0) << 2, 0, 0, - OTRGetRectDimensionFromRightEdge((float) (SCREEN_WIDTH - x0)) << 2, - (int) ((float) (SCREEN_HEIGHT - y0)) << 2, OTRGetGameRenderWidth(), OTRGetGameRenderHeight(), - G_TX_RENDERTILE, OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); + // gDPImageRectangle(gfx++, OTRGetRectDimensionFromLeftEdge(x0) << 2, (int) (y0) << 2, 0, 0, + // OTRGetRectDimensionFromRightEdge((float) (SCREEN_WIDTH - x0)) << 2, + // (int) ((float) (SCREEN_HEIGHT - y0)) << 2, OTRGetGameRenderWidth(), OTRGetGameRenderHeight(), + // G_TX_RENDERTILE, OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); } diff --git a/src/racing/memory.c b/src/racing/memory.c index 310a89a5b..845dbc645 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -22,6 +22,8 @@ #include #include +#include "engine/courses/Course.h" + #include s32 sGfxSeekPosition; @@ -59,7 +61,7 @@ void* get_next_available_memory_addr(uintptr_t size) { if (gNextFreeMemoryAddress > sPoolEnd) { printf("[memory.c] get_next_available_memory_addr(): Memory Pool Out of Bounds! Out of memory!\n"); PRINT_MEMPOOL; - assert(false); + assert(true); } return (void*) freeSpace; @@ -140,7 +142,7 @@ void* segmented_uintptr_t_to_virtual(uintptr_t addr) { return (void*) ((gSegmentTable[segment] + offset)); } -void* segmented_gfx_to_virtual(const void* addr) { +Gfx* segmented_gfx_to_virtual(const void* addr) { size_t segment = (uintptr_t) addr >> 24; size_t offset = (uintptr_t) addr & 0x00FFFFFF; @@ -149,7 +151,7 @@ void* segmented_gfx_to_virtual(const void* addr) { // printf("seg_gfx_to_virt: 0x%llX to 0x%llX\n", addr, (gSegmentTable[segment] + offset)); - return (void*) ((gSegmentTable[segment] + offset)); + return (Gfx*) ((gSegmentTable[segment] + offset)); } void move_segment_table_to_dmem(void) { @@ -1642,51 +1644,6 @@ u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { } void load_course(s32 courseId) { - printf("Loading Course Data\n"); - - char* data = gNewCourseTable[courseId].data; - char* vtxData = gNewCourseTable[courseId].vtx; - size_t vtxSize = gNewCourseTable[courseId].vtxSize; - course_texture* textures = gNewCourseTable[courseId].textures; - char* displaylists = gNewCourseTable[courseId].displaylists; - size_t dlSize = gNewCourseTable[courseId].dlSize; - - // Convert course vtx to vtx - CourseVtx* cvtx = (CourseVtx*) LOAD_ASSET(vtxData); - Vtx* vtx = (Vtx*) allocate_memory(sizeof(Vtx) * vtxSize); - gSegmentTable[4] = &vtx[0]; - func_802A86A8(cvtx, vtx, vtxSize); - vtxSegEnd = &vtx[vtxSize]; - - // Load and allocate memory for course textures - course_texture* asset = textures; - u8* freeMemory = NULL; - u8* texture = NULL; - size_t size = 0; - texSegSize = 0; - while (asset->addr) { - size = ResourceGetTexSizeByName(asset->addr); - freeMemory = (u8*) allocate_memory(size); - - texture = (u8*) LOAD_ASSET(asset->addr); - if (texture) { - if (asset == &textures[0]) { - gSegmentTable[5] = &freeMemory[0]; - } - memcpy(freeMemory, texture, size); - texSegSize += size; - // printf("Texture Addr: 0x%llX, size 0x%X\n", &freeMemory[0], size); - } - asset++; - } - - texSegEnd = &((u8*) gSegmentTable[5])[texSegSize]; - - // Extract packed DLs - u8* packed = (u8*) LOAD_ASSET(displaylists); - Gfx* gfx = (Gfx*) allocate_memory(sizeof(Gfx) * dlSize); // Size of unpacked DLs - assert(gfx != NULL); - gSegmentTable[7] = &gfx[0]; - displaylist_unpack(gfx, packed, 0); - dlSegEnd = &gfx[dlSize]; + printf("Loading Course %d\n", courseId); + LoadCourse(); } diff --git a/src/racing/memory.h b/src/racing/memory.h index 8e39d08cd..9fbcd2e6d 100644 --- a/src/racing/memory.h +++ b/src/racing/memory.h @@ -1,6 +1,8 @@ #ifndef MEMORY_H #define MEMORY_H +#include "common_structs.h" + struct MainPoolBlock { struct MainPoolBlock* prev; struct MainPoolBlock* next; @@ -50,7 +52,7 @@ void* segment_offset_to_virtual(uint32_t, uint32_t); void* segment_vtx_to_virtual(size_t offset); void* segmented_texture_to_virtual(uintptr_t addr); void* segmented_uintptr_t_to_virtual(uintptr_t); -void* segmented_gfx_to_virtual(const void*); +Gfx* segmented_gfx_to_virtual(const void*); void move_segment_table_to_dmem(void); void initialize_memory_pool(void); void* decompress_segments(u8*, u8*); @@ -58,6 +60,9 @@ void* allocate_memory(size_t); void* load_data(uintptr_t, uintptr_t); void func_802A7D54(s32, s32); +void func_802A86A8(CourseVtx* data, Vtx* vtx, size_t arg1); +void displaylist_unpack(uintptr_t* data, uintptr_t finalDisplaylistOffset, u32 arg2); + void main_pool_init(uintptr_t, uintptr_t); void* main_pool_alloc(uintptr_t, uintptr_t); uintptr_t main_pool_free(void*); diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 4f7ea8c50..3d233087e 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -143,17 +143,18 @@ void func_8028E298(void) { void func_8028E3A0(void) { if (D_80150120) { - - if (gCourseIndexInCup == COURSE_FOUR) { + if (GetCupCursorPosition() == GetCupSize()) {// CUP_COURSE_FOUR) { gGotoMode = ENDING; } else { D_800DC544++; + SetCupCursorPosition(GetCupCursorPosition() + 1); gCourseIndexInCup++; gGotoMode = RACING; } } else { D_800DC544++; gCourseIndexInCup++; + SetCupCursorPosition(GetCupCursorPosition() + 1); gGotoMode = RACING; } } @@ -421,51 +422,38 @@ void func_8028EC98(s32 arg0) { func_800029B0(); - switch (arg0) { - case 0: - case 7: - case 8: - case 14: - func_800C8EAC(3); - break; - case 10: - func_800C8EAC(21); - break; - case 4: - case 9: - func_800C8EAC(4); - break; - case 1: - case 15: - case 17: - func_800C8EAC(5); - break; - case 11: - func_800C8EAC(10); - break; - case 6: - func_800C8EAC(6); - break; - case 2: - func_800C8EAC(9); - break; - case 3: - func_800C8EAC(7); - break; - case 5: - case 12: - func_800C8EAC(8); - break; - case 13: - func_800C8EAC(18); - break; - case 18: - func_800C8EAC(19); - break; - case 16: - case 19: - func_800C8EAC(25); - break; + if (GetCourse() == GetMarioRaceway() || + GetCourse() == GetRoyalRaceway() || + GetCourse() == GetLuigiRaceway() || + GetCourse() == GetWarioStadium()) { + func_800C8EAC(3); + } else if (GetCourse() == GetToadsTurnpike()) { + func_800C8EAC(21); + } else if (GetCourse() == GetYoshiValley() || + GetCourse() == GetMooMooFarm()) { + func_800C8EAC(4); + } else if (GetCourse() == GetChocoMountain() || + GetCourse() == GetBlockFort() || + GetCourse() == GetDoubleDeck()) { + func_800C8EAC(5); + } else if (GetCourse() == GetKalimariDesert()) { + func_800C8EAC(10); + } else if (GetCourse() == GetKoopaTroopaBeach()) { + func_800C8EAC(6); + } else if (GetCourse() == GetBowsersCastle()) { + func_800C8EAC(9); + } else if (GetCourse() == GetBansheeBoardwalk()) { + func_800C8EAC(7); + } else if (GetCourse() == GetFrappeSnowland() || + GetCourse() == GetSherbetLand()) { + func_800C8EAC(8); + } else if (GetCourse() == GetRainbowRoad()) { + func_800C8EAC(18); + } else if (GetCourse() == GetDkJungle()) { + func_800C8EAC(19); + } else if (GetCourse() == GetSkyscraper() || + GetCourse() == GetBigDonut()) { + func_800C8EAC(25); } } @@ -933,9 +921,9 @@ void func_8028FCBC(void) { func_8028F914(); if (D_802BA034 == 1.0f) { if (gActiveScreenMode != SCREEN_MODE_1P) { - if (gCurrentCourseId == COURSE_LUIGI_RACEWAY) { + if (GetCourse() == GetLuigiRaceway()) { func_802A7940(); - } else if (gCurrentCourseId == COURSE_WARIO_STADIUM) { + } else if (GetCourse() == GetWarioStadium()) { func_802A7728(); } } diff --git a/src/racing/render_courses.c b/src/racing/render_courses.c index 00283ca8c..ef9111d1b 100644 --- a/src/racing/render_courses.c +++ b/src/racing/render_courses.c @@ -50,7 +50,13 @@ s32 func_80290C20(Camera* camera) { } void parse_course_displaylists(const char* asset) { - TrackSections* section = (TrackSections*) LOAD_ASSET(asset); + TrackSections* section; + + if (GetCourse() == GetTestCourse()) { + section = (TrackSections*) asset; + } else { + section = (TrackSections*) LOAD_ASSET(asset); + } while (section->addr != 0) { if (section->flags & 0x8000) { @@ -131,39 +137,34 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1) index = sp1E; } } else { - - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - if ((temp_v0_3 >= 0x11) && (temp_v0_3 < 0x18)) { - index = temp_v0_3; - } else if ((temp_v0_3 == 255) && (sp1E != 255)) { - index = sp1E; - } else if ((temp_v0_3 != 255) && (sp1E == 255)) { - index = temp_v0_3; - } else { - index = arg1->pathCounter; - } - break; - case COURSE_CHOCO_MOUNTAIN: - if ((temp_v0_3 >= 0xE) && (temp_v0_3 < 0x16)) { - index = temp_v0_3; - } else if ((temp_v0_3 == 255) && (sp1E != 255)) { - index = sp1E; - } else if ((temp_v0_3 != 255) && (sp1E == 255)) { - index = temp_v0_3; - } else { - index = arg1->pathCounter; - } - break; - default: - if (temp_v0_3 == 255) { - index = arg1->pathCounter; - } else if (player->collision.surfaceDistance[2] > 30.0f) { - index = arg1->pathCounter; - } else { - index = temp_v0_3; - } - break; + if (GetCourse() == GetBowsersCastle()) { + if ((temp_v0_3 >= 0x11) && (temp_v0_3 < 0x18)) { + index = temp_v0_3; + } else if ((temp_v0_3 == 255) && (sp1E != 255)) { + index = sp1E; + } else if ((temp_v0_3 != 255) && (sp1E == 255)) { + index = temp_v0_3; + } else { + index = arg1->pathCounter; + } + } else if (GetCourse() == GetChocoMountain()) { + if ((temp_v0_3 >= 0xE) && (temp_v0_3 < 0x16)) { + index = temp_v0_3; + } else if ((temp_v0_3 == 255) && (sp1E != 255)) { + index = sp1E; + } else if ((temp_v0_3 != 255) && (sp1E == 255)) { + index = temp_v0_3; + } else { + index = arg1->pathCounter; + } + } else { + if (temp_v0_3 == 255) { + index = arg1->pathCounter; + } else if (player->collision.surfaceDistance[2] > 30.0f) { + index = arg1->pathCounter; + } else { + index = temp_v0_3; + } } } } else { @@ -179,7 +180,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1) index = ((index - 1) * 4) + direction; gSPDisplayList(gDisplayListHead++, addr[index]); - if (CVarGetInteger("gDisableLod", 0) == 1 && gCurrentCourseId == COURSE_BOWSER_CASTLE && + if (CVarGetInteger("gDisableLod", 0) == 1 && (GetCourse() == GetBowsersCastle()) && (index < 20 || index > 99)) { // always render higher version of bowser statue gDisplayListHead--; gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9148); // use credit version of the course @@ -835,7 +836,6 @@ void render_koopa_troopa_beach(struct UnkStruct_800DC5EC* arg0) { } void render_royal_raceway(struct UnkStruct_800DC5EC* arg0) { - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); @@ -1302,68 +1302,71 @@ void render_big_donut(struct UnkStruct_800DC5EC* arg0) { } void func_8029569C(void) { - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_9348); - break; - case COURSE_CHOCO_MOUNTAIN: - gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_71B8); - break; - case COURSE_BOWSER_CASTLE: - gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9148); - break; - case COURSE_BANSHEE_BOARDWALK: - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_B308); - break; - case COURSE_YOSHI_VALLEY: - gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_18020); - break; - case COURSE_FRAPPE_SNOWLAND: - gSPDisplayList(gDisplayListHead++, d_course_frappe_snowland_dl_76A0); - break; - case COURSE_KOOPA_BEACH: - gSPDisplayList(gDisplayListHead++, d_course_koopa_troopa_beach_dl_18D68); - break; - case COURSE_ROYAL_RACEWAY: - gSPDisplayList(gDisplayListHead++, d_course_royal_raceway_dl_D8E8); - break; - case COURSE_LUIGI_RACEWAY: - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FD40); - break; - case COURSE_MOO_MOO_FARM: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_14088); - break; - case COURSE_TOADS_TURNPIKE: - gSPDisplayList(gDisplayListHead++, d_course_toads_turnpike_dl_23930); - break; - case COURSE_KALAMARI_DESERT: - gSPDisplayList(gDisplayListHead++, d_course_kalimari_desert_dl_22E00); - break; - case COURSE_SHERBET_LAND: - gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_9AE8); - break; - case COURSE_RAINBOW_ROAD: - gSPDisplayList(gDisplayListHead++, d_course_rainbow_road_dl_16220); - break; - case COURSE_WARIO_STADIUM: - gSPDisplayList(gDisplayListHead++, d_course_wario_stadium_dl_CA78); - break; - case COURSE_BLOCK_FORT: - gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); - break; - case COURSE_SKYSCRAPER: - gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); - break; - case COURSE_DOUBLE_DECK: - gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); - break; - case COURSE_DK_JUNGLE: - gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_13C30); - break; - case COURSE_BIG_DONUT: - gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); - break; - } + + CourseManager_RenderCredits(); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // //gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_9348); + // break; + // case COURSE_CHOCO_MOUNTAIN: + // gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_71B8); + // break; + // case COURSE_BOWSER_CASTLE: + // gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9148); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_B308); + // break; + // case COURSE_YOSHI_VALLEY: + // gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_18020); + // break; + // case COURSE_FRAPPE_SNOWLAND: + // gSPDisplayList(gDisplayListHead++, d_course_frappe_snowland_dl_76A0); + // break; + // case COURSE_KOOPA_BEACH: + // gSPDisplayList(gDisplayListHead++, d_course_koopa_troopa_beach_dl_18D68); + // break; + // case COURSE_ROYAL_RACEWAY: + // gSPDisplayList(gDisplayListHead++, d_course_royal_raceway_dl_D8E8); + // break; + // case COURSE_LUIGI_RACEWAY: + // gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FD40); + // break; + // case COURSE_MOO_MOO_FARM: + // gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_14088); + // break; + // case COURSE_TOADS_TURNPIKE: + // gSPDisplayList(gDisplayListHead++, d_course_toads_turnpike_dl_23930); + // break; + // case COURSE_KALAMARI_DESERT: + // gSPDisplayList(gDisplayListHead++, d_course_kalimari_desert_dl_22E00); + // break; + // case COURSE_SHERBET_LAND: + // gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_9AE8); + // break; + // case COURSE_RAINBOW_ROAD: + // gSPDisplayList(gDisplayListHead++, d_course_rainbow_road_dl_16220); + // break; + // case COURSE_WARIO_STADIUM: + // gSPDisplayList(gDisplayListHead++, d_course_wario_stadium_dl_CA78); + // break; + // case COURSE_BLOCK_FORT: + // gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); + // break; + // case COURSE_SKYSCRAPER: + // gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); + // break; + // case COURSE_DOUBLE_DECK: + // gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); + // break; + // case COURSE_DK_JUNGLE: + // gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_13C30); + // break; + // case COURSE_BIG_DONUT: + // gSPDisplayList(gDisplayListHead++, d_course_sherbet_land_dl_0); + // break; + // } } void render_course(struct UnkStruct_800DC5EC* arg0) { @@ -1386,68 +1389,70 @@ void render_course(struct UnkStruct_800DC5EC* arg0) { return; } - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - render_mario_raceway(arg0); - break; - case COURSE_CHOCO_MOUNTAIN: - render_choco_mountain(arg0); - break; - case COURSE_BOWSER_CASTLE: - render_bowsers_castle(arg0); - break; - case COURSE_BANSHEE_BOARDWALK: - render_banshee_boardwalk(arg0); - break; - case COURSE_YOSHI_VALLEY: - render_yoshi_valley(arg0); - break; - case COURSE_FRAPPE_SNOWLAND: - render_frappe_snowland(arg0); - break; - case COURSE_KOOPA_BEACH: - render_koopa_troopa_beach(arg0); - break; - case COURSE_ROYAL_RACEWAY: - render_royal_raceway(arg0); - break; - case COURSE_LUIGI_RACEWAY: - render_luigi_raceway(arg0); - break; - case COURSE_MOO_MOO_FARM: - render_moo_moo_farm(arg0); - break; - case COURSE_TOADS_TURNPIKE: - render_toads_turnpike(arg0); - break; - case COURSE_KALAMARI_DESERT: - render_kalimari_desert(arg0); - break; - case COURSE_SHERBET_LAND: - render_sherbet_land(arg0); - break; - case COURSE_RAINBOW_ROAD: - render_rainbow_road(arg0); - break; - case COURSE_WARIO_STADIUM: - render_wario_stadium(arg0); - break; - case COURSE_BLOCK_FORT: - render_block_fort(arg0); - break; - case COURSE_SKYSCRAPER: - render_skyscraper(arg0); - break; - case COURSE_DOUBLE_DECK: - render_double_deck(arg0); - break; - case COURSE_DK_JUNGLE: - render_dks_jungle_parkway(arg0); - break; - case COURSE_BIG_DONUT: - render_big_donut(arg0); - break; - } + CourseManager_RenderCourse(arg0); + + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // //render_mario_raceway(arg0); + // break; + // case COURSE_CHOCO_MOUNTAIN: + // //render_choco_mountain(arg0); + // break; + // case COURSE_BOWSER_CASTLE: + // //render_bowsers_castle(arg0); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // //render_banshee_boardwalk(arg0); + // break; + // case COURSE_YOSHI_VALLEY: + // render_yoshi_valley(arg0); + // break; + // case COURSE_FRAPPE_SNOWLAND: + // render_frappe_snowland(arg0); + // break; + // case COURSE_KOOPA_BEACH: + // render_koopa_troopa_beach(arg0); + // break; + // case COURSE_ROYAL_RACEWAY: + // render_royal_raceway(arg0); + // break; + // case COURSE_LUIGI_RACEWAY: + // render_luigi_raceway(arg0); + // break; + // case COURSE_MOO_MOO_FARM: + // render_moo_moo_farm(arg0); + // break; + // case COURSE_TOADS_TURNPIKE: + // render_toads_turnpike(arg0); + // break; + // case COURSE_KALAMARI_DESERT: + // render_kalimari_desert(arg0); + // break; + // case COURSE_SHERBET_LAND: + // render_sherbet_land(arg0); + // break; + // case COURSE_RAINBOW_ROAD: + // render_rainbow_road(arg0); + // break; + // case COURSE_WARIO_STADIUM: + // render_wario_stadium(arg0); + // break; + // case COURSE_BLOCK_FORT: + // render_block_fort(arg0); + // break; + // case COURSE_SKYSCRAPER: + // render_skyscraper(arg0); + // break; + // case COURSE_DOUBLE_DECK: + // render_double_deck(arg0); + // break; + // case COURSE_DK_JUNGLE: + // render_dks_jungle_parkway(arg0); + // break; + // case COURSE_BIG_DONUT: + // render_big_donut(arg0); + // break; + // } } void func_80295BF8(s32 playerIndex) { @@ -1507,301 +1512,301 @@ void func_80295D88(void) { D_800DC5BC = 0; D_800DC5C8 = 0; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - // d_course_mario_raceway_packed_dl_1140 - generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x07001140)); - if (gScreenModeSelection == SCREEN_MODE_1P) { - // d_course_mario_raceway_packed_dl_8E8 - generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x070008E8)); - } else { - // d_course_mario_raceway_packed_dl_2D68 - generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x07002D68)); - } + CourseManager_GenerateCollision(); - parse_course_displaylists(d_course_mario_raceway_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_CHOCO_MOUNTAIN: - D_800DC5BC = 1; - D_801625EC = 255; - D_801625F4 = 255; - D_801625F0 = 255; - D_802B87B0 = 0x3E3; - D_802B87B4 = 0x3E8; - D_802B87D4 = 0x71C; - D_802B87D0 = 0xE38; + // switch (gCurrentCourseId) { + // case COURSE_MARIO_RACEWAY: + // // // d_course_mario_raceway_packed_dl_1140 + // // generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x07001140)); + // // if (gScreenModeSelection == SCREEN_MODE_1P) { + // // // d_course_mario_raceway_packed_dl_8E8 + // // generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x070008E8)); + // // } else { + // // // d_course_mario_raceway_packed_dl_2D68 + // // generate_collision_mesh_with_defaults((Gfx*) segmented_gfx_to_virtual(0x07002D68)); + // // } - // Spawn guardrail only for CC_50 and time trials. - if ((gCCSelection != CC_50) && (gModeSelection != TIME_TRIALS)) { - // d_course_choco_mountain_packed_dl_0 - nullify_displaylist(segmented_gfx_to_virtual(0x07000000)); - // d_course_choco_mountain_packed_dl_98 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000098)); - // d_course_choco_mountain_packed_dl_178 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000178)); - // d_course_choco_mountain_packed_dl_280 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000280)); - // d_course_choco_mountain_packed_dl_340 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000340)); - // d_course_choco_mountain_packed_dl_3C8 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x070003C8)); - } + // // parse_course_displaylists(d_course_mario_raceway_addr); + // // func_80295C6C(); + // // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_CHOCO_MOUNTAIN: + // D_800DC5BC = 1; + // D_801625EC = 255; + // D_801625F4 = 255; + // D_801625F0 = 255; + // D_802B87B0 = 0x3E3; + // D_802B87B4 = 0x3E8; + // D_802B87D4 = 0x71C; + // D_802B87D0 = 0xE38; - parse_course_displaylists(d_course_choco_mountain_addr); - func_802B5CAC(0x238E, 0x31C7, D_8015F590); - func_80295C6C(); - D_8015F8E4 = -80.0f; - break; - case COURSE_BOWSER_CASTLE: - parse_course_displaylists(d_course_bowsers_castle_addr); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001350), 0x32, 0, 0, 0); - D_8015F8E4 = -50.0f; - break; - case COURSE_BANSHEE_BOARDWALK: - D_800DC5BC = 1; - D_801625EC = 0; - D_801625F4 = 0; - D_801625F0 = 0; - parse_course_displaylists(d_course_banshee_boardwalk_track_sections); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000878), 128, 0, 0, 0); - D_8015F8E4 = -80.0f; - break; - case COURSE_YOSHI_VALLEY: { - Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120); - func_802B5D64(&lights4, -0x38F0, 0x1C70, 1); - parse_course_displaylists(d_course_yoshi_valley_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - } - case COURSE_FRAPPE_SNOWLAND: - parse_course_displaylists(d_course_frappe_snowland_addr); - func_80295C6C(); - D_8015F8E4 = -50.0f; - break; - case COURSE_KOOPA_BEACH: - parse_course_displaylists(d_course_koopa_troopa_beach_addr); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x0700ADE0), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x0700A540), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07009E70), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000358), -0x6A, 255, 255, 255); - break; - case COURSE_ROYAL_RACEWAY: - parse_course_displaylists(d_course_royal_raceway_addr); - func_80295C6C(); - D_8015F8E4 = -60.0f; - break; - case COURSE_LUIGI_RACEWAY: - parse_course_displaylists(d_course_luigi_raceway_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_MOO_MOO_FARM: - parse_course_displaylists(d_course_moo_moo_farm_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_TOADS_TURNPIKE: - D_801625EC = 43; - D_801625F4 = 13; - D_801625F0 = 4; - D_802B87B0 = 993; - D_802B87B4 = 1000; - parse_course_displaylists(d_course_toads_turnpike_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_KALAMARI_DESERT: - parse_course_displaylists(d_course_kalimari_desert_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_SHERBET_LAND: - parse_course_displaylists(d_course_sherbet_land_addr); - func_80295C6C(); - D_8015F8E4 = -18.0f; - // d_course_sherbet_land_packed_dl_1EB8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001EB8), -0x4C, 255, 255, 255); - // d_course_sherbet_land_packed_dl_2308 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002308), -0x6A, 255, 255, 255); - break; - case COURSE_RAINBOW_ROAD: - D_800DC5C8 = 1; - parse_course_displaylists(d_course_rainbow_road_addr); - func_80295C6C(); - D_8015F8E4 = 0.0f; - // d_course_rainbow_road_packed_dl_2068 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002068), -0x6A, 255, 255, 255); - // d_course_rainbow_road_packed_dl_1E18 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001E18), -0x6A, 255, 255, 255); - // d_course_rainbow_road_packed_dl_1318 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001318), 255, 255, 255, 0); - if (gGamestate != CREDITS_SEQUENCE) { - // d_course_rainbow_road_packed_dl_1FB8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001FB8), -0x6A, 255, 255, 255); - } - break; - case COURSE_WARIO_STADIUM: - parse_course_displaylists(d_course_wario_stadium_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - // d_course_wario_stadium_packed_dl_C50 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000C50), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_BD8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000BD8), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_B60 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000B60), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_AE8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000AE8), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_CC8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000CC8), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_D50 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000D50), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_DD0 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000DD0), 100, 255, 255, 255); - // d_course_wario_stadium_packed_dl_E48 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000E48), 100, 255, 255, 255); - break; - case COURSE_BLOCK_FORT: - // d_course_block_fort_packed_dl_15C0 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x070015C0), 1); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_SKYSCRAPER: - // d_course_skyscraper_packed_dl_1110 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07001110), 1); - // d_course_skyscraper_packed_dl_258 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000258), 1); - func_80295C6C(); + // // Spawn guardrail only for CC_50 and time trials. + // if ((gCCSelection != CC_50) && (gModeSelection != TIME_TRIALS)) { + // // d_course_choco_mountain_packed_dl_0 + // nullify_displaylist(segmented_gfx_to_virtual(0x07000000)); + // // d_course_choco_mountain_packed_dl_98 + // nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000098)); + // // d_course_choco_mountain_packed_dl_178 + // nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000178)); + // // d_course_choco_mountain_packed_dl_280 + // nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000280)); + // // d_course_choco_mountain_packed_dl_340 + // nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x07000340)); + // // d_course_choco_mountain_packed_dl_3C8 + // nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(0x070003C8)); + // } - D_8015F8E4 = -480.0f; - break; - case COURSE_DOUBLE_DECK: - // d_course_double_deck_packed_dl_738 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000738), 1); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; - break; - case COURSE_DK_JUNGLE: - parse_course_displaylists(d_course_dks_jungle_parkway_addr); - func_80295C6C(); - D_8015F8E4 = -475.0f; - // d_course_dks_jungle_parkway_packed_dl_3FA8 - find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07003FA8), 120, 255, 255, 255); - break; - case COURSE_BIG_DONUT: - // d_course_big_donut_packed_dl_1018 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07001018), 6); - // d_course_big_donut_packed_dl_450 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000450), 6); - // d_course_big_donut_packed_dl_AC0 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000AC0), 6); - // d_course_big_donut_packed_dl_B58 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000B58), 6); - // d_course_big_donut_packed_dl_230 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000230), 6); - func_80295C6C(); - D_8015F8E4 = 100.0f; - break; - } + // parse_course_displaylists(d_course_choco_mountain_addr); + // func_802B5CAC(0x238E, 0x31C7, D_8015F590); + // func_80295C6C(); + // D_8015F8E4 = -80.0f; + // break; + // case COURSE_BOWSER_CASTLE: + // parse_course_displaylists(d_course_bowsers_castle_addr); + // func_80295C6C(); + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001350), 0x32, 0, 0, 0); + // D_8015F8E4 = -50.0f; + // break; + // case COURSE_BANSHEE_BOARDWALK: + // // D_800DC5BC = 1; + // // D_801625EC = 0; + // // D_801625F4 = 0; + // // D_801625F0 = 0; + // // parse_course_displaylists(d_course_banshee_boardwalk_track_sections); + // // func_80295C6C(); + // // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000878), 128, 0, 0, 0); + // // D_8015F8E4 = -80.0f; + // break; + // case COURSE_YOSHI_VALLEY: { + // Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120); + // func_802B5D64(&lights4, -0x38F0, 0x1C70, 1); + // parse_course_displaylists(d_course_yoshi_valley_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // } + // case COURSE_FRAPPE_SNOWLAND: + // parse_course_displaylists(d_course_frappe_snowland_addr); + // func_80295C6C(); + // D_8015F8E4 = -50.0f; + // break; + // case COURSE_KOOPA_BEACH: + // parse_course_displaylists(d_course_koopa_troopa_beach_addr); + // func_80295C6C(); + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x0700ADE0), -0x6A, 255, 255, 255); + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x0700A540), -0x6A, 255, 255, 255); + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07009E70), -0x6A, 255, 255, 255); + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000358), -0x6A, 255, 255, 255); + // break; + // case COURSE_ROYAL_RACEWAY: + // parse_course_displaylists(d_course_royal_raceway_addr); + // func_80295C6C(); + // D_8015F8E4 = -60.0f; + // break; + // case COURSE_LUIGI_RACEWAY: + // parse_course_displaylists(d_course_luigi_raceway_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_MOO_MOO_FARM: + // parse_course_displaylists(d_course_moo_moo_farm_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_TOADS_TURNPIKE: + // D_801625EC = 43; + // D_801625F4 = 13; + // D_801625F0 = 4; + // D_802B87B0 = 993; + // D_802B87B4 = 1000; + // parse_course_displaylists(d_course_toads_turnpike_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_KALAMARI_DESERT: + // parse_course_displaylists(d_course_kalimari_desert_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_SHERBET_LAND: + // parse_course_displaylists(d_course_sherbet_land_addr); + // func_80295C6C(); + // D_8015F8E4 = -18.0f; + // // d_course_sherbet_land_packed_dl_1EB8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001EB8), -0x4C, 255, 255, 255); + // // d_course_sherbet_land_packed_dl_2308 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002308), -0x6A, 255, 255, 255); + // break; + // case COURSE_RAINBOW_ROAD: + // D_800DC5C8 = 1; + // parse_course_displaylists(d_course_rainbow_road_addr); + // func_80295C6C(); + // D_8015F8E4 = 0.0f; + // // d_course_rainbow_road_packed_dl_2068 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002068), -0x6A, 255, 255, 255); + // // d_course_rainbow_road_packed_dl_1E18 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001E18), -0x6A, 255, 255, 255); + // // d_course_rainbow_road_packed_dl_1318 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001318), 255, 255, 255, 0); + // if (gGamestate != CREDITS_SEQUENCE) { + // // d_course_rainbow_road_packed_dl_1FB8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001FB8), -0x6A, 255, 255, 255); + // } + // break; + // case COURSE_WARIO_STADIUM: + // parse_course_displaylists(d_course_wario_stadium_addr); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // // d_course_wario_stadium_packed_dl_C50 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000C50), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_BD8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000BD8), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_B60 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000B60), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_AE8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000AE8), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_CC8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000CC8), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_D50 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000D50), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_DD0 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000DD0), 100, 255, 255, 255); + // // d_course_wario_stadium_packed_dl_E48 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000E48), 100, 255, 255, 255); + // break; + // case COURSE_BLOCK_FORT: + // // d_course_block_fort_packed_dl_15C0 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x070015C0), 1); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_SKYSCRAPER: + // // d_course_skyscraper_packed_dl_1110 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07001110), 1); + // // d_course_skyscraper_packed_dl_258 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000258), 1); + // func_80295C6C(); + + // D_8015F8E4 = -480.0f; + // break; + // case COURSE_DOUBLE_DECK: + // // d_course_double_deck_packed_dl_738 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000738), 1); + // func_80295C6C(); + // D_8015F8E4 = gCourseMinY - 10.0f; + // break; + // case COURSE_DK_JUNGLE: + // parse_course_displaylists(d_course_dks_jungle_parkway_addr); + // func_80295C6C(); + // D_8015F8E4 = -475.0f; + // // d_course_dks_jungle_parkway_packed_dl_3FA8 + // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07003FA8), 120, 255, 255, 255); + // break; + // case COURSE_BIG_DONUT: + // // d_course_big_donut_packed_dl_1018 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07001018), 6); + // // d_course_big_donut_packed_dl_450 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000450), 6); + // // d_course_big_donut_packed_dl_AC0 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000AC0), 6); + // // d_course_big_donut_packed_dl_B58 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000B58), 6); + // // d_course_big_donut_packed_dl_230 + // generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual(0x07000230), 6); + // func_80295C6C(); + // D_8015F8E4 = 100.0f; + // break; + // } } void func_802966A0(void) { - switch (gCurrentCourseId) { - case COURSE_KOOPA_BEACH: - // clang-format off - if (D_8015F8E8 < 0.0f) { - if (D_8015F8E4 < -20.0f) { D_8015F8E8 *= -1.0f; } - } else { - if (D_8015F8E4 > 0.0f) { D_8015F8E8 *= -1.0f; } - } - // clang-format on - D_8015F8E4 += D_8015F8E8; + CourseManager_Water(); - D_802B87BC += 9; - if (D_802B87BC > 255) { - D_802B87BC = 0; - } - D_802B87C4 += 3; - if (D_802B87C4 > 255) { - D_802B87C4 = 0; - } - // waterfall animation - // d_course_koopa_troopa_beach_packed_dl_9D58 - find_and_set_tile_size(segmented_gfx_to_virtual(0x07009D58), 0, D_802B87BC); - // d_course_koopa_troopa_beach_packed_dl_9CD0 - find_and_set_tile_size(segmented_gfx_to_virtual(0x07009CD0), 0, D_802B87C4); - D_802B87CC = random_int(300) / 40; - if (D_802B87C8 < 0) { - D_802B87C8 = random_int(300) / 40; - } else { - D_802B87C8 = -(random_int(300) / 40); - } - // Waterfall bubbling effect? (unused) - // d_course_koopa_troopa_beach_packed_dl_2E8 - find_and_set_tile_size(segmented_gfx_to_virtual(0x070002E8), D_802B87C8, D_802B87CC); - break; - case COURSE_BANSHEE_BOARDWALK: - D_802B87BC++; + // switch (gCurrentCourseId) { + // case COURSE_KOOPA_BEACH: + // // clang-format off + // if (D_8015F8E8 < 0.0f) { + // if (D_8015F8E4 < -20.0f) { D_8015F8E8 *= -1.0f; } + // } else { + // if (D_8015F8E4 > 0.0f) { D_8015F8E8 *= -1.0f; } + // } + // // clang-format on + // D_8015F8E4 += D_8015F8E8; - if (D_802B87BC >= 0x100) { - D_802B87BC = 0; - } - find_and_set_tile_size((uintptr_t) LOAD_ASSET(d_course_banshee_boardwalk_dl_B278), 0, D_802B87BC); - break; - case COURSE_ROYAL_RACEWAY: - D_802B87BC -= 20; - if (D_802B87BC < 0) { - D_802B87BC = 0xFF; - } - // d_course_royal_raceway_packed_dl_A6A8 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x0700A6A8), 0, D_802B87BC); - // d_course_royal_raceway_packed_dl_A648 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x0700A648), 0, D_802B87BC); - break; - case COURSE_DK_JUNGLE: - D_802B87BC += 2; - if (D_802B87BC > 255) { - D_802B87BC = 0; - } - // d_course_dks_jungle_parkway_packed_dl_3DD0 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003DD0), 0, D_802B87BC); - // d_course_dks_jungle_parkway_packed_dl_3E40 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003E40), 0, D_802B87BC); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003EB0), 0, D_802B87BC); - // d_course_dks_jungle_parkway_packed_dl_3F30 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003F30), 0, D_802B87BC); - // d_course_dks_jungle_parkway_packed_dl_36A8 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x070036A8), 0, D_802B87BC); - D_802B87C4 -= 20; - if (D_802B87C4 < 0) { - D_802B87C4 = 0xFF; - } - // d_course_dks_jungle_parkway_packed_dl_9880 - find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07009880), 0, D_802B87C4); - evaluate_collision_players_palm_trees(); - break; - } + // D_802B87BC += 9; + // if (D_802B87BC > 255) { + // D_802B87BC = 0; + // } + // D_802B87C4 += 3; + // if (D_802B87C4 > 255) { + // D_802B87C4 = 0; + // } + // // waterfall animation + // // d_course_koopa_troopa_beach_packed_dl_9D58 + // find_and_set_tile_size(segmented_gfx_to_virtual(0x07009D58), 0, D_802B87BC); + // // d_course_koopa_troopa_beach_packed_dl_9CD0 + // find_and_set_tile_size(segmented_gfx_to_virtual(0x07009CD0), 0, D_802B87C4); + // D_802B87CC = random_int(300) / 40; + // if (D_802B87C8 < 0) { + // D_802B87C8 = random_int(300) / 40; + // } else { + // D_802B87C8 = -(random_int(300) / 40); + // } + // // Waterfall bubbling effect? (unused) + // // d_course_koopa_troopa_beach_packed_dl_2E8 + // find_and_set_tile_size(segmented_gfx_to_virtual(0x070002E8), D_802B87C8, D_802B87CC); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // // D_802B87BC++; + + // // if (D_802B87BC >= 0x100) { + // // D_802B87BC = 0; + // // } + // // find_and_set_tile_size((uintptr_t) LOAD_ASSET(d_course_banshee_boardwalk_dl_B278), 0, D_802B87BC); + // break; + // case COURSE_ROYAL_RACEWAY: + // D_802B87BC -= 20; + // if (D_802B87BC < 0) { + // D_802B87BC = 0xFF; + // } + // // d_course_royal_raceway_packed_dl_A6A8 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x0700A6A8), 0, D_802B87BC); + // // d_course_royal_raceway_packed_dl_A648 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x0700A648), 0, D_802B87BC); + // break; + // case COURSE_DK_JUNGLE: + // D_802B87BC += 2; + // if (D_802B87BC > 255) { + // D_802B87BC = 0; + // } + // // d_course_dks_jungle_parkway_packed_dl_3DD0 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003DD0), 0, D_802B87BC); + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003E40), 0, D_802B87BC); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003EB0), 0, D_802B87BC); + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07003F30), 0, D_802B87BC); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x070036A8), 0, D_802B87BC); + // D_802B87C4 -= 20; + // if (D_802B87C4 < 0) { + // D_802B87C4 = 0xFF; + // } + // // d_course_dks_jungle_parkway_packed_dl_9880 + // find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual(0x07009880), 0, D_802B87C4); + // evaluate_collision_players_palm_trees(); + // break; + // } } void func_802969F8(void) { - - switch (gCurrentCourseId) { - case COURSE_MOO_MOO_FARM: - D_8015F702 = 0; - D_8015F700 = 200; - break; - case COURSE_KOOPA_BEACH: - D_8015F8E8 = -0.1f; - D_8015F8E4 = 0.0f; - break; + if (GetCourse() == GetMooMooFarm()) { + D_8015F702 = 0; + D_8015F700 = 200; + } else if (GetCourse() == GetKoopaTroopaBeach()) { + D_8015F8E8 = -0.1f; + D_8015F8E4 = 0.0f; } } diff --git a/src/racing/render_courses.h b/src/racing/render_courses.h index 0aa20f053..3ae4d5337 100644 --- a/src/racing/render_courses.h +++ b/src/racing/render_courses.h @@ -13,11 +13,10 @@ typedef struct { void func_8029122C(struct UnkStruct_800DC5EC*, s32); s32 func_80290C20(Camera*); -void parse_course_displaylists(const char*); +void parse_course_displaylists(const char* asset); void render_course_segments(const char*[], struct UnkStruct_800DC5EC*); void func_80291198(void); void func_802911C4(void); -void render_mario_raceway(struct UnkStruct_800DC5EC*); void render_choco_mountain(struct UnkStruct_800DC5EC*); void render_bowsers_castle(struct UnkStruct_800DC5EC*); void render_banshee_boardwalk(struct UnkStruct_800DC5EC*); @@ -53,9 +52,12 @@ extern s32 D_802B87C8; extern s32 D_802B87CC; extern s32 D_802B87BC; -extern Lights1 D_800DC610[]; +extern s16 D_802B87B0; +extern s16 D_802B87B4; +extern s16 D_802B87D0; +extern s16 D_802B87D4; -extern Lights1 D_800DC610[]; // Light data? +extern Lights1 D_800DC610[]; extern u16 gNumCollisionTriangles; diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 43539036e..bc6068f24 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -18,6 +18,8 @@ #include "main.h" #include "menus.h" #include "port/Engine.h" +#include "engine/courses/Course.h" +#include "engine/Engine.h" Vp D_802B8880[] = { { { { 640, 480, 511, 0 }, { 640, 480, 511, 0 } } }, @@ -140,7 +142,7 @@ void func_802A38B4(void) { gMenuSelection = MAIN_MENU; break; case PLAYER_SELECT_MENU_FROM_QUIT: - gMenuSelection = PLAYER_SELECT_MENU; + gMenuSelection = CHARACTER_SELECT_MENU; break; case COURSE_SELECT_MENU_FROM_QUIT: gMenuSelection = COURSE_SELECT_MENU; @@ -311,15 +313,6 @@ void func_802A4300(void) { gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); } -struct Skybox { - s16 unk0; - s16 unk2; - s16 unk4; - s16 unk6; - s16 unk8; - s16 unkA; -}; - UNUSED Gfx D_802B8A90[] = { gsDPPipeSync(), gsDPSetRenderMode(G_RM_OPA_SURF, G_RM_OPA_SURF2), @@ -331,39 +324,6 @@ UNUSED Gfx D_802B8A90[] = { gsSPEndDisplayList(), }; -struct Skybox sSkyColors[] = { -#include "assets/course_metadata/sSkyColors.inc.c" - -}; - -// struct Skybox sSkyColors[] = { -// {128, 4280, 6136, 216, 7144, 32248}, -// {255, 255, 255, 255, 255, 255}, -// {48, 1544, 49528, 0, 0, 0}, -// {0, 0, 0, 0, 0, 0}, -// {113, 70, 255, 255, 184, 99}, -// {28, 11, 90, 0, 99, 164}, -// {48, 1688, 54136, 216, 7144, 32248}, -// {238, 144, 255, 255, 224, 240}, -// {128, 4280, 6136, 216, 7144, 32248}, -// {0, 18, 255, 197, 211, 255}, -// {0, 2, 94, 209, 65, 23}, -// {195, 231, 255, 255, 0xc0, 0}, -// {128, 4280, 6136, 216, 7144, 32248}, -// {0, 0, 0, 0, 0, 0}, -// {20, 30, 56, 40, 60, 110}, -// {128, 4280, 6136, 216, 7144, 32248}, -// {0, 0, 0, 0, 0, 0}, -// {113, 70, 255, 255, 184, 99}, -// {255, 174, 0, 255, 229, 124}, -// {0, 0, 0, 0, 0, 0}, -// {238, 144, 255, 255, 224, 240}, -// }; - -struct Skybox sSkyColors2[] = { -#include "assets/course_metadata/sSkyColors2.inc.c" -}; - void func_802A450C(Vtx* skybox) { s32 i; @@ -394,44 +354,53 @@ void func_802A450C(Vtx* skybox) { } for (i = 0; i < 8; i++) { - skybox[i].v.cn[0] = (s16) D_801625EC; skybox[i].v.cn[1] = (s16) D_801625F4; skybox[i].v.cn[2] = (s16) D_801625F0; } return; } - skybox[0].v.cn[0] = sSkyColors[gCurrentCourseId].unk0; - skybox[0].v.cn[1] = sSkyColors[gCurrentCourseId].unk2; - skybox[0].v.cn[2] = sSkyColors[gCurrentCourseId].unk4; - skybox[1].v.cn[0] = sSkyColors[gCurrentCourseId].unk6; - skybox[1].v.cn[1] = sSkyColors[gCurrentCourseId].unk8; - skybox[1].v.cn[2] = sSkyColors[gCurrentCourseId].unkA; - skybox[2].v.cn[0] = sSkyColors[gCurrentCourseId].unk6; - skybox[2].v.cn[1] = sSkyColors[gCurrentCourseId].unk8; - skybox[2].v.cn[2] = sSkyColors[gCurrentCourseId].unkA; - skybox[3].v.cn[0] = sSkyColors[gCurrentCourseId].unk0; - skybox[3].v.cn[1] = sSkyColors[gCurrentCourseId].unk2; - skybox[3].v.cn[2] = sSkyColors[gCurrentCourseId].unk4; - skybox[4].v.cn[0] = sSkyColors2[gCurrentCourseId].unk0; - skybox[4].v.cn[1] = sSkyColors2[gCurrentCourseId].unk2; - skybox[4].v.cn[2] = sSkyColors2[gCurrentCourseId].unk4; - skybox[5].v.cn[0] = sSkyColors2[gCurrentCourseId].unk6; - skybox[5].v.cn[1] = sSkyColors2[gCurrentCourseId].unk8; - skybox[5].v.cn[2] = sSkyColors2[gCurrentCourseId].unkA; - skybox[6].v.cn[0] = sSkyColors2[gCurrentCourseId].unk6; - skybox[6].v.cn[1] = sSkyColors2[gCurrentCourseId].unk8; - skybox[6].v.cn[2] = sSkyColors2[gCurrentCourseId].unkA; - skybox[7].v.cn[0] = sSkyColors2[gCurrentCourseId].unk0; - skybox[7].v.cn[1] = sSkyColors2[gCurrentCourseId].unk2; - skybox[7].v.cn[2] = sSkyColors2[gCurrentCourseId].unk4; + + SkyboxColours *prop = (SkyboxColours *)&CourseManager_GetProps()->Skybox; + + skybox[0].v.cn[0] = prop->TopRight.r; + skybox[0].v.cn[1] = prop->TopRight.g; + skybox[0].v.cn[2] = prop->TopRight.b; + + skybox[1].v.cn[0] = prop->BottomRight.r; + skybox[1].v.cn[1] = prop->BottomRight.g; + skybox[1].v.cn[2] = prop->BottomRight.b; + + skybox[2].v.cn[0] = prop->BottomLeft.r; + skybox[2].v.cn[1] = prop->BottomLeft.g; + skybox[2].v.cn[2] = prop->BottomLeft.b; + + skybox[3].v.cn[0] = prop->TopLeft.r; + skybox[3].v.cn[1] = prop->TopLeft.g; + skybox[3].v.cn[2] = prop->TopLeft.b; + + skybox[4].v.cn[0] = prop->FloorTopRight.r; + skybox[4].v.cn[1] = prop->FloorTopRight.g; + skybox[4].v.cn[2] = prop->FloorTopRight.b; + + skybox[5].v.cn[0] = prop->FloorBottomRight.r; + skybox[5].v.cn[1] = prop->FloorBottomRight.g; + skybox[5].v.cn[2] = prop->FloorBottomRight.b; + + skybox[6].v.cn[0] = prop->FloorBottomLeft.r; + skybox[6].v.cn[1] = prop->FloorBottomLeft.g; + skybox[6].v.cn[2] = prop->FloorBottomLeft.b; + + skybox[7].v.cn[0] = prop->FloorTopLeft.r; + skybox[7].v.cn[1] = prop->FloorTopLeft.g; + skybox[7].v.cn[2] = prop->FloorTopLeft.b; } void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) { init_rdp(); - if (gCurrentCourseId != COURSE_RAINBOW_ROAD) { + if (GetCourse() != GetRainbowRoad()) { gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING); @@ -474,7 +443,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U sp5C[0] = 0.0f; sp5C[1] = 0.0f; sp5C[2] = 30000.0f; - func_802B5564(matrix1, &sp128, camera->unk_B4, gScreenAspect, D_80150150, D_8015014C, 1.0f); + func_802B5564(matrix1, &sp128, camera->unk_B4, gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); func_802B5794(matrix2, camera->pos, camera->lookAt); mtxf_multiplication(matrix3, matrix1, matrix2); @@ -507,60 +476,60 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U gSPMatrix(gDisplayListHead++, LOAD_ASSET(D_0D008E98), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPVertex(gDisplayListHead++, &vtx[0], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); - if (gCurrentCourseId == COURSE_RAINBOW_ROAD) { + if (GetCourse() == GetRainbowRoad()) { gSPVertex(gDisplayListHead++, &vtx[4], 4, 0); gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); } } void func_802A4D18(void) { - if (gGamestate != 4) { + if (gGamestate != RACING) { D_8015014C = 6800.0f; D_80150150 = 3.0f; } else { - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - case COURSE_BANSHEE_BOARDWALK: - case COURSE_RAINBOW_ROAD: - case COURSE_BLOCK_FORT: - case COURSE_SKYSCRAPER: - D_8015014C = 2700.0f; - D_80150150 = 2.0f; - break; - case COURSE_CHOCO_MOUNTAIN: - case COURSE_DOUBLE_DECK: - D_8015014C = 1500.0f; - D_80150150 = 2.0f; - break; - case COURSE_KOOPA_BEACH: - D_8015014C = 5000.0f; - D_80150150 = 1.0f; - break; - case COURSE_WARIO_STADIUM: - D_8015014C = 4800.0f; - D_80150150 = 10.0f; - break; - case COURSE_MARIO_RACEWAY: - case COURSE_YOSHI_VALLEY: - case COURSE_FRAPPE_SNOWLAND: - case COURSE_ROYAL_RACEWAY: - case COURSE_LUIGI_RACEWAY: - case COURSE_MOO_MOO_FARM: - case COURSE_TOADS_TURNPIKE: - case COURSE_SHERBET_LAND: - case COURSE_DK_JUNGLE: - D_8015014C = 4500.0f; - D_80150150 = 9.0f; - break; - case COURSE_KALAMARI_DESERT: - D_8015014C = 7000.0f; - D_80150150 = 10.0f; - break; - default: - D_8015014C = 6800.0f; - D_80150150 = 3.0f; - break; - } + // switch (gCurrentCourseId) { + // case COURSE_BOWSER_CASTLE: + // case COURSE_BANSHEE_BOARDWALK: + // case COURSE_RAINBOW_ROAD: + // case COURSE_BLOCK_FORT: + // case COURSE_SKYSCRAPER: + // D_8015014C = 2700.0f; + // D_80150150 = 2.0f; + // break; + // case COURSE_CHOCO_MOUNTAIN: + // case COURSE_DOUBLE_DECK: + // D_8015014C = 1500.0f; + // D_80150150 = 2.0f; + // break; + // case COURSE_KOOPA_BEACH: + // D_8015014C = 5000.0f; + // D_80150150 = 1.0f; + // break; + // case COURSE_WARIO_STADIUM: + // D_8015014C = 4800.0f; + // D_80150150 = 10.0f; + // break; + // case COURSE_MARIO_RACEWAY: + // case COURSE_YOSHI_VALLEY: + // case COURSE_FRAPPE_SNOWLAND: + // case COURSE_ROYAL_RACEWAY: + // case COURSE_LUIGI_RACEWAY: + // case COURSE_MOO_MOO_FARM: + // case COURSE_TOADS_TURNPIKE: + // case COURSE_SHERBET_LAND: + // case COURSE_DK_JUNGLE: + // D_8015014C = 4500.0f; + // D_80150150 = 9.0f; + // break; + // case COURSE_KALAMARI_DESERT: + // D_8015014C = 7000.0f; + // D_80150150 = 10.0f; + // break; + // default: + // D_8015014C = 6800.0f; + // D_80150150 = 3.0f; + // break; + // } } switch (gScreenModeSelection) { /* switch 1; irregular */ case SCREEN_MODE_1P: /* switch 1 */ @@ -798,9 +767,9 @@ void render_player_one_1p_screen(void) { gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -860,9 +829,9 @@ void render_player_one_2p_screen_vertical(void) { func_802A3730(D_800DC5EC); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -926,9 +895,9 @@ void render_player_two_2p_screen_vertical(void) { #endif gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), @@ -988,9 +957,9 @@ void render_player_one_2p_screen_horizontal(void) { #endif gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -1051,9 +1020,9 @@ void render_player_two_2p_screen_horizontal(void) { #endif gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), @@ -1110,9 +1079,9 @@ void render_player_one_3p_4p_screen(void) { func_802A3730(D_800DC5EC); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -1169,9 +1138,9 @@ void render_player_two_3p_4p_screen(void) { func_802A3730(D_800DC5F0); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), @@ -1229,9 +1198,9 @@ void render_player_three_3p_4p_screen(void) { gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[2]), @@ -1298,9 +1267,9 @@ void render_player_four_3p_4p_screen(void) { gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); #ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], sp9C, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], sp9C, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #else - guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], gScreenAspect, D_80150150, D_8015014C, 1.0f); + guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); #endif gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[3]), diff --git a/src/render_objects.c b/src/render_objects.c index f85072faa..f34bd9119 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2481,19 +2481,19 @@ void func_8004F020(s32 arg0) { f32 var_f0; f32 var_f2; + //! @todo: Hardcode these x and y values. Because why not? + CourseManager_MinimapFinishlinePosition(); + var_f2 = ((D_8018D2C0[arg0] + D_8018D2F0) - (D_8018D2B0 / 2)) + D_8018D2E0; var_f0 = ((D_8018D2D8[arg0] + D_8018D2F8) - (D_8018D2B8 / 2)) + D_8018D2E8; - switch (gCurrentCourseId) { /* irregular */ - case COURSE_MARIO_RACEWAY: - var_f0 = var_f0 - 2.0; - break; - case COURSE_CHOCO_MOUNTAIN: - var_f0 = var_f0 - 16.0; - break; - case COURSE_KALAMARI_DESERT: - var_f0 = var_f0 + 4.0; - break; + if (GetCourse() == GetMarioRaceway()) { + var_f0 = var_f0 - 2.0; + } else if (GetCourse() == GetChocoMountain()) { + var_f0 = var_f0 - 16.0; + } else if (GetCourse() == GetKalimariDesert()) { + var_f0 = var_f0 + 4.0; } + draw_hud_2d_texture_8x8(var_f2, var_f0, (u8*) common_texture_minimap_finish_line); } @@ -2736,7 +2736,7 @@ void draw_lap_count(s16 lapX, s16 lapY, s8 lap) { } void func_8004FDB4(f32 arg0, f32 arg1, s16 arg2, s16 arg3, s16 characterId, s32 arg5, s32 arg6, s32 arg7, s32 arg8) { - if ((gCurrentCourseId == COURSE_YOSHI_VALLEY) && (arg3 < 3) && (arg8 == 0)) { + if ((GetCourse() == GetYoshiValley()) && (arg3 < 3) && (arg8 == 0)) { func_80042330((s32) arg0, (s32) arg1, 0U, 1.0f); gSPDisplayList(gDisplayListHead++, D_0D007DB8); func_8004B35C(0x000000FF, 0x000000FF, 0x000000FF, D_8018D3E0); @@ -3033,7 +3033,7 @@ void func_80050E34(s32 playerId, s32 arg1) { spB8 = 0; } - if ((gCurrentCourseId == COURSE_YOSHI_VALLEY) && (lapCount < 3)) { + if ((GetCourse() == GetYoshiValley()) && (lapCount < 3)) { gSPDisplayList(gDisplayListHead++, D_0D007DB8); gDPLoadTLUT_pal256(gDisplayListHead++, common_tlut_portrait_bomb_kart_and_question_mark); rsp_load_texture(common_texture_portrait_question_mark, 0x00000020, 0x00000020); @@ -3211,16 +3211,16 @@ void func_80051C60(s16 arg0, s32 arg1) { Object* object; if (D_801658FE == 0) { - if (gCurrentCourseId == 6) { + if (GetCourse() == GetKoopaTroopaBeach()) { var_s5 = arg0; - } else if (gCurrentCourseId == 9) { + } else if (GetCourse() == GetMooMooFarm()) { var_s5 = arg0 - 0x10; - } else if (gCurrentCourseId == 4) { + } else if (GetCourse() == GetYoshiValley()) { var_s5 = arg0 - 0x10; } else { var_s5 = arg0 + 0x10; } - } else if (gCurrentCourseId == 6) { + } else if (GetCourse() == GetKoopaTroopaBeach()) { var_s5 = arg0 * 2; } else { var_s5 = arg0 + 0x20; @@ -3252,11 +3252,11 @@ void func_80051EF8(void) { s16 temp_a0; temp_a0 = 0xF0 - D_800DC5EC->cameraHeight; - if (gCurrentCourseId == COURSE_KOOPA_BEACH) { + if (GetCourse() == GetKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; - } else if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + } else if (GetCourse() == GetMooMooFarm()) { temp_a0 = temp_a0 - 0x40; - } else if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + } else if (GetCourse() == GetYoshiValley()) { temp_a0 = temp_a0 - 0x40; } else { temp_a0 = temp_a0 - 0x30; @@ -3268,11 +3268,11 @@ void func_80051F9C(void) { s16 temp_a0; temp_a0 = 0xF0 - D_800DC5F0->cameraHeight; - if (gCurrentCourseId == COURSE_KOOPA_BEACH) { + if (GetCourse() == GetKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; - } else if (gCurrentCourseId == COURSE_MOO_MOO_FARM) { + } else if (GetCourse() == GetMooMooFarm()) { temp_a0 = temp_a0 - 0x40; - } else if (gCurrentCourseId == COURSE_YOSHI_VALLEY) { + } else if (GetCourse() == GetYoshiValley()) { temp_a0 = temp_a0 - 0x40; } else { temp_a0 = temp_a0 - 0x30; @@ -3702,7 +3702,7 @@ void render_object_thwomps_model(s32 objectIndex) { } void render_object_thwomps(s32 cameraId) { - s32 objectIndex; + s32 objectIndex = 0; s32 i; UNUSED s32 stackPadding0; s16 minusone, plusone; diff --git a/src/render_player.c b/src/render_player.c index 990be011d..b59f8e7c2 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1262,86 +1262,80 @@ void change_player_color_effect_cmy(UNUSED Player* player, s8 arg1, s32 arg2, f3 * Sort of an atmospheric effect. */ bool is_player_under_light_luigi_raceway(Player* player, s8 arg1) { - switch (gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - if (((gNearestWaypointByPlayerId[arg1] >= 0x14F) && (gNearestWaypointByPlayerId[arg1] < 0x158)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x15E) && (gNearestWaypointByPlayerId[arg1] < 0x164)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x169) && (gNearestWaypointByPlayerId[arg1] < 0x170)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x174) && (gNearestWaypointByPlayerId[arg1] < 0x17A)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x17E) && - (gNearestWaypointByPlayerId[arg1] < 0x184))) { // under a light in the tunnel - change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); - change_player_color_effect_cmy(player, arg1, 0xE0, 0.3f); - D_80164B80[arg1] = 0; - return true; - } - return false; + if (GetCourse() == GetLuigiRaceway()) { + if (((gNearestWaypointByPlayerId[arg1] >= 0x14F) && (gNearestWaypointByPlayerId[arg1] < 0x158)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x15E) && (gNearestWaypointByPlayerId[arg1] < 0x164)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x169) && (gNearestWaypointByPlayerId[arg1] < 0x170)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x174) && (gNearestWaypointByPlayerId[arg1] < 0x17A)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x17E) && + (gNearestWaypointByPlayerId[arg1] < 0x184))) { // under a light in the tunnel + change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); + change_player_color_effect_cmy(player, arg1, 0xE0, 0.3f); + D_80164B80[arg1] = 0; + return true; + } + return false; - default: - return false; } + return false; } void render_light_environment_on_player(Player* player, s8 arg1) { - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - if (((gNearestWaypointByPlayerId[arg1] >= 0x15) && (gNearestWaypointByPlayerId[arg1] < 0x2A)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x14D) && (gNearestWaypointByPlayerId[arg1] < 0x15C)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x1D1) && (gNearestWaypointByPlayerId[arg1] < 0x1E4)) || - (player->collision.surfaceDistance[2] >= 500.0f)) { // over lava - change_player_color_effect_rgb(player, arg1, COLOR_LAVA, 0.3f); - change_player_color_effect_cmy(player, arg1, 0x004040, 0.3f); - D_80164B80[arg1] = 0; - } else if (((gNearestWaypointByPlayerId[arg1] >= 0xF1) && (gNearestWaypointByPlayerId[arg1] < 0xF5)) || - ((gNearestWaypointByPlayerId[arg1] >= 0xFB) && (gNearestWaypointByPlayerId[arg1] < 0xFF)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x105) && (gNearestWaypointByPlayerId[arg1] < 0x109)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x10F) && (gNearestWaypointByPlayerId[arg1] < 0x113)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x145) && (gNearestWaypointByPlayerId[arg1] < 0x14A)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x15E) && - (gNearestWaypointByPlayerId[arg1] < 0x163))) { // under a lamp - change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); - change_player_color_effect_cmy(player, arg1, 0xE0, 0.3f); - D_80164B80[arg1] = 0; - } else { // normal color - change_player_color_effect_rgb(player, arg1, COLOR_BLACK, 0.3f); - change_player_color_effect_cmy(player, arg1, 0, 0.3f); - D_80164B80[arg1] = 0; - } - break; - case COURSE_BANSHEE_BOARDWALK: - if (((gNearestWaypointByPlayerId[arg1] >= 0xD) && (gNearestWaypointByPlayerId[arg1] < 0x15)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x29) && (gNearestWaypointByPlayerId[arg1] < 0x39)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x46) && (gNearestWaypointByPlayerId[arg1] < 0x4E)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x5F) && (gNearestWaypointByPlayerId[arg1] < 0x67)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x7B) && (gNearestWaypointByPlayerId[arg1] < 0x86)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x9D) && (gNearestWaypointByPlayerId[arg1] < 0xA6)) || - ((gNearestWaypointByPlayerId[arg1] >= 0xB9) && (gNearestWaypointByPlayerId[arg1] < 0xC3)) || - ((gNearestWaypointByPlayerId[arg1] >= 0xB9) && (gNearestWaypointByPlayerId[arg1] < 0xC3)) || - ((gNearestWaypointByPlayerId[arg1] >= 0xD7) && (gNearestWaypointByPlayerId[arg1] < 0xE1)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x10E) && (gNearestWaypointByPlayerId[arg1] < 0x119)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x154) && (gNearestWaypointByPlayerId[arg1] < 0x15F)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x1EF) && (gNearestWaypointByPlayerId[arg1] < 0x1F7)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x202) && (gNearestWaypointByPlayerId[arg1] < 0x209)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x216) && (gNearestWaypointByPlayerId[arg1] < 0x21D)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x230) && (gNearestWaypointByPlayerId[arg1] < 0x23A)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x24C) && (gNearestWaypointByPlayerId[arg1] < 0x256)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x288) && (gNearestWaypointByPlayerId[arg1] < 0x269)) || - ((gNearestWaypointByPlayerId[arg1] >= 0x274) && - (gNearestWaypointByPlayerId[arg1] < 0x27E))) { // under a lamp - change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); - change_player_color_effect_cmy(player, arg1, 0x0000E0, 0.3f); - D_80164B80[arg1] = 0; - } else { - change_player_color_effect_rgb(player, arg1, COLOR_BLACK, 0.3f); - change_player_color_effect_cmy(player, arg1, 0, 0.3f); - D_80164B80[arg1] = 0; - } - break; - default: + if (GetCourse() == GetBowsersCastle()) { + if (((gNearestWaypointByPlayerId[arg1] >= 0x15) && (gNearestWaypointByPlayerId[arg1] < 0x2A)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x14D) && (gNearestWaypointByPlayerId[arg1] < 0x15C)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x1D1) && (gNearestWaypointByPlayerId[arg1] < 0x1E4)) || + (player->collision.surfaceDistance[2] >= 500.0f)) { // over lava + change_player_color_effect_rgb(player, arg1, COLOR_LAVA, 0.3f); + change_player_color_effect_cmy(player, arg1, 0x004040, 0.3f); + D_80164B80[arg1] = 0; + } else if (((gNearestWaypointByPlayerId[arg1] >= 0xF1) && (gNearestWaypointByPlayerId[arg1] < 0xF5)) || + ((gNearestWaypointByPlayerId[arg1] >= 0xFB) && (gNearestWaypointByPlayerId[arg1] < 0xFF)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x105) && (gNearestWaypointByPlayerId[arg1] < 0x109)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x10F) && (gNearestWaypointByPlayerId[arg1] < 0x113)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x145) && (gNearestWaypointByPlayerId[arg1] < 0x14A)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x15E) && + (gNearestWaypointByPlayerId[arg1] < 0x163))) { // under a lamp + change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); + change_player_color_effect_cmy(player, arg1, 0xE0, 0.3f); + D_80164B80[arg1] = 0; + } else { // normal color change_player_color_effect_rgb(player, arg1, COLOR_BLACK, 0.3f); change_player_color_effect_cmy(player, arg1, 0, 0.3f); D_80164B80[arg1] = 0; - break; + } + } else if (GetCourse() == GetBansheeBoardwalk()) { + if (((gNearestWaypointByPlayerId[arg1] >= 0xD) && (gNearestWaypointByPlayerId[arg1] < 0x15)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x29) && (gNearestWaypointByPlayerId[arg1] < 0x39)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x46) && (gNearestWaypointByPlayerId[arg1] < 0x4E)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x5F) && (gNearestWaypointByPlayerId[arg1] < 0x67)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x7B) && (gNearestWaypointByPlayerId[arg1] < 0x86)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x9D) && (gNearestWaypointByPlayerId[arg1] < 0xA6)) || + ((gNearestWaypointByPlayerId[arg1] >= 0xB9) && (gNearestWaypointByPlayerId[arg1] < 0xC3)) || + ((gNearestWaypointByPlayerId[arg1] >= 0xB9) && (gNearestWaypointByPlayerId[arg1] < 0xC3)) || + ((gNearestWaypointByPlayerId[arg1] >= 0xD7) && (gNearestWaypointByPlayerId[arg1] < 0xE1)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x10E) && (gNearestWaypointByPlayerId[arg1] < 0x119)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x154) && (gNearestWaypointByPlayerId[arg1] < 0x15F)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x1EF) && (gNearestWaypointByPlayerId[arg1] < 0x1F7)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x202) && (gNearestWaypointByPlayerId[arg1] < 0x209)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x216) && (gNearestWaypointByPlayerId[arg1] < 0x21D)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x230) && (gNearestWaypointByPlayerId[arg1] < 0x23A)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x24C) && (gNearestWaypointByPlayerId[arg1] < 0x256)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x288) && (gNearestWaypointByPlayerId[arg1] < 0x269)) || + ((gNearestWaypointByPlayerId[arg1] >= 0x274) && + (gNearestWaypointByPlayerId[arg1] < 0x27E))) { // under a lamp + change_player_color_effect_rgb(player, arg1, COLOR_LIGHT, 0.3f); + change_player_color_effect_cmy(player, arg1, 0x0000E0, 0.3f); + D_80164B80[arg1] = 0; + } else { + change_player_color_effect_rgb(player, arg1, COLOR_BLACK, 0.3f); + change_player_color_effect_cmy(player, arg1, 0, 0.3f); + D_80164B80[arg1] = 0; + } + } else { + change_player_color_effect_rgb(player, arg1, COLOR_BLACK, 0.3f); + change_player_color_effect_cmy(player, arg1, 0, 0.3f); + D_80164B80[arg1] = 0; } } diff --git a/src/save.c b/src/save.c index fb52a9e9f..e6d773d21 100644 --- a/src/save.c +++ b/src/save.c @@ -246,8 +246,8 @@ u32 func_800B4DF4(u8* arr) { // Get a time trial record, infer course index s32 func_800B4E24(s32 recordIndex) { - return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((gCupSelection * 4) + gCourseIndexInCup) / 4)] - .courseRecords[(((gCupSelection * 4) + gCourseIndexInCup) % 4)] + return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) / 4)] + .courseRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) % 4)] .records[recordIndex]); } @@ -260,8 +260,8 @@ u32 func_800B4EB4(s32 recordIndex, s32 courseIndex) { // Get Best Lap record of the inferred course index s32 func_800B4F2C(void) { - return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((gCupSelection * 4) + gCourseIndexInCup) / 4)] - .courseRecords[(((gCupSelection * 4) + gCourseIndexInCup) % 4)] + return func_800B4DF4(gSaveData.allCourseTimeTrialRecords.cupRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) / 4)] + .courseRecords[(((GetCupIndex() * 4) + gCourseIndexInCup) % 4)] .records[TIME_TRIAL_1LAP_RECORD]); } @@ -279,7 +279,7 @@ s32 func_800B5020(u32 time, s32 charId) { s32 j; CourseTimeTrialRecords* tt; - course = gCupSelection * 4 + gCourseIndexInCup; + course = GetCupIndex() * 4 + gCourseIndexInCup; tt = &gSaveData.allCourseTimeTrialRecords.cupRecords[course / 4].courseRecords[course % 4]; i = 0; @@ -326,7 +326,7 @@ s32 func_800B5218(void) { s32 checkLapIndex; s32 character; s32 lapBitmask; - recordIndex = (gCupSelection * 4) + gCourseIndexInCup; + recordIndex = (GetCupIndex() * 4) + gCourseIndexInCup; recordPointer = &gSaveData.allCourseTimeTrialRecords.cupRecords[recordIndex / 4].courseRecords[recordIndex % 4].records[0][0]; lapBitmask = 1; @@ -363,10 +363,10 @@ void func_800B536C(s32 arg0) { if (arg0 >= 0) { points = &gSaveData.main.saveInfo.grandPrixPoints[gCCSelection]; - tmp = func_800B54EC(gCupSelection, *points); + tmp = func_800B54EC(GetCupIndex(), *points); tmp2 = 3 - arg0; if ((arg0 < 3) && (tmp < (3 - arg0))) { - *points = func_800B5508(gCupSelection, *points, tmp2); + *points = func_800B5508(GetCupIndex(), *points, tmp2); write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); } @@ -432,12 +432,12 @@ s32 func_800B5530(s32 cc_mode) { } // Check if the 150CC mode has all 4 gold cups -s32 func_800B555C(void) { +s32 has_unlocked_extra_mode(void) { return func_800B5530(CC_150); } // Check if the Extra mode has all 4 gold cups -s32 func_800B557C(void) { +s32 has_completed_extra_mode(void) { return func_800B5530(CC_EXTRA); } @@ -785,7 +785,7 @@ s32 func_800B6178(s32 arg0) { if (var_v0 == 0) { temp_s3->ghostDataSaved = 1; if (gGamestate == 4) { - temp_s3->courseIndex = (gCupSelection * 4) + gCourseIndexInCup; + temp_s3->courseIndex = (GetCupIndex() * 4) + gCourseIndexInCup; } temp_s3->unk_00 = D_80162DFC; temp_s3->characterId = (u8) D_80162DE0; @@ -834,7 +834,7 @@ s32 func_800B63F0(s32 arg0) { func_80005AE8(gPlayerThree); phi_s3 = 0; - if (((gCupSelection * 4) + gCourseIndexInCup) != D_8018EE10[arg0].courseIndex) { + if (((GetCupIndex() * 4) + gCourseIndexInCup) != D_8018EE10[arg0].courseIndex) { phi_s3 = 2; } else if (D_80162DFC != D_8018EE10[arg0].unk_00) { phi_s3 = 3; diff --git a/src/save.h b/src/save.h index bccc0c428..090d16704 100644 --- a/src/save.h +++ b/src/save.h @@ -55,8 +55,8 @@ u8 func_800B54C0(s32, s32); u8 func_800B54EC(s32, s32); u8 func_800B5508(s32, s32, s32); s32 func_800B5530(s32); -s32 func_800B555C(void); -s32 func_800B557C(void); +s32 has_unlocked_extra_mode(void); +s32 has_completed_extra_mode(void); void func_800B559C(s32); s32 func_800B578C(s32); s32 func_800B5888(s32); diff --git a/src/spawn_players.c b/src/spawn_players.c index 480707f47..fd1d4ef88 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -486,7 +486,7 @@ void func_80039DA4(void) { 0, 1, 2, 3, 4, 5, 6, 7, }; - if (((gCourseIndexInCup == COURSE_ONE) && (D_8016556E == 0)) || (gDemoMode == 1) || + if (((GetCupCursorPosition() == COURSE_ONE) && (D_8016556E == 0)) || (gDemoMode == 1) || (gDebugMenuSelection == DEBUG_MENU_EXITED)) { for (i = 0; i < NUM_PLAYERS; i++) { D_80165270[i] = sp2C[i]; @@ -504,7 +504,7 @@ UNUSED s16 D_800E43A8 = 0; void spawn_players_gp_one_player(f32* arg0, f32* arg1, f32 arg2) { func_80039DA4(); - if (((gCourseIndexInCup == COURSE_ONE) && (D_8016556E == 0)) || (gDemoMode == 1) || + if (((GetCupCursorPosition() == COURSE_ONE) && (D_8016556E == 0)) || (gDemoMode == 1) || (gDebugMenuSelection == DEBUG_MENU_EXITED)) { s16 rand; s16 i; @@ -638,7 +638,7 @@ void spawn_players_versus_one_player(f32* arg0, f32* arg1, f32 arg2) { void spawn_players_gp_two_player(f32* arg0, f32* arg1, f32 arg2) { func_80039DA4(); - if ((gCourseIndexInCup == COURSE_ONE) || (gDemoMode == 1) || (gDebugMenuSelection == DEBUG_MENU_EXITED)) { + if ((GetCupCursorPosition() == COURSE_ONE) || (gDemoMode == 1) || (gDebugMenuSelection == DEBUG_MENU_EXITED)) { s16 rand; s16 i; @@ -728,7 +728,7 @@ void spawn_players_versus_two_player(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_2p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (gCurrentCourseId == COURSE_BIG_DONUT) { + if (GetCourse() == GetBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -777,7 +777,7 @@ void func_8003B318(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_3p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (gCurrentCourseId == COURSE_BIG_DONUT) { + if (GetCourse() == GetBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -829,7 +829,7 @@ void func_8003B870(f32* arg0, f32* arg1, f32 arg2) { } void spawn_players_4p_battle(f32* arg0, f32* arg1, f32 arg2) { - if (gCurrentCourseId == COURSE_BIG_DONUT) { + if (GetCourse() == GetBigDonut()) { spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1], @@ -884,310 +884,262 @@ void func_8003C0F0(void) { s16 sp5A; s32 temp; UNUSED s32 pad[4]; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - case COURSE_CHOCO_MOUNTAIN: - case COURSE_BOWSER_CASTLE: - case COURSE_BANSHEE_BOARDWALK: - case COURSE_YOSHI_VALLEY: - case COURSE_FRAPPE_SNOWLAND: - case COURSE_KOOPA_BEACH: - case COURSE_ROYAL_RACEWAY: - case COURSE_LUIGI_RACEWAY: - case COURSE_MOO_MOO_FARM: - case COURSE_TOADS_TURNPIKE: - case COURSE_KALAMARI_DESERT: - case COURSE_SHERBET_LAND: - case COURSE_RAINBOW_ROAD: - case COURSE_WARIO_STADIUM: - case COURSE_DK_JUNGLE: - func_8000F2DC(); - sp5E = (f32) D_80164550[0][0].posX; - sp5C = (f32) D_80164550[0][0].posZ; - sp5A = (f32) D_80164550[0][0].posY; - if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) { - sp5E = 0; - } - break; - case COURSE_BLOCK_FORT: - case COURSE_SKYSCRAPER: - case COURSE_DOUBLE_DECK: - case COURSE_BIG_DONUT: - func_8000EEDC(); - break; + if (gModeSelection == BATTLE) { + func_8000EEDC(); + } else if (GetCourse() != GetPodiumCeremony()) { + func_8000F2DC(); + sp5E = (f32) D_80164550[0][0].posX; + sp5C = (f32) D_80164550[0][0].posZ; + sp5A = (f32) D_80164550[0][0].posY; + if (GetCourse() == GetToadsTurnpike()) { + sp5E = 0; + } } - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - case COURSE_CHOCO_MOUNTAIN: - case COURSE_BOWSER_CASTLE: - case COURSE_BANSHEE_BOARDWALK: - case COURSE_YOSHI_VALLEY: - case COURSE_FRAPPE_SNOWLAND: - case COURSE_KOOPA_BEACH: - case COURSE_ROYAL_RACEWAY: - case COURSE_LUIGI_RACEWAY: - case COURSE_MOO_MOO_FARM: - case COURSE_TOADS_TURNPIKE: - case COURSE_KALAMARI_DESERT: - case COURSE_SHERBET_LAND: - case COURSE_RAINBOW_ROAD: - case COURSE_WARIO_STADIUM: - case COURSE_DK_JUNGLE: - switch (gActiveScreenMode) { - case SCREEN_MODE_1P: - switch (gModeSelection) { - case GRAND_PRIX: - D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0x14))); - D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0x14))); - D_80165230[0] = sp5C + 0x1E; - D_80165230[1] = sp5C + 0x32; - D_80165230[2] = sp5C + 0x46; - D_80165230[3] = sp5C + 0x5A; - D_80165230[4] = sp5C + 0x6E; - D_80165230[5] = sp5C + 0x82; - D_80165230[6] = sp5C + 0x96; - D_80165230[7] = sp5C + 0xAA; - spawn_players_gp_one_player(D_80165210, D_80165230, sp5A); - break; + if ((gModeSelection != BATTLE) && (GetCourse() != GetPodiumCeremony())) { + switch (gActiveScreenMode) { + case SCREEN_MODE_1P: + switch (gModeSelection) { + case GRAND_PRIX: + D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0x14))); + D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0x14))); + D_80165230[0] = sp5C + 0x1E; + D_80165230[1] = sp5C + 0x32; + D_80165230[2] = sp5C + 0x46; + D_80165230[3] = sp5C + 0x5A; + D_80165230[4] = sp5C + 0x6E; + D_80165230[5] = sp5C + 0x82; + D_80165230[6] = sp5C + 0x96; + D_80165230[7] = sp5C + 0xAA; + spawn_players_gp_one_player(D_80165210, D_80165230, sp5A); + break; - case TIME_TRIALS: - D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E))); - D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E))); - D_80165230[0] = sp5C + 0x1E; - D_80165230[1] = sp5C + 0x1E; - D_80165230[2] = sp5C + 0x1E; - D_80165230[3] = sp5C + 0x1E; - D_80165230[4] = sp5C + 0x1E; - D_80165230[5] = sp5C + 0x1E; - D_80165230[6] = sp5C + 0x1E; - D_80165230[7] = sp5C + 0x1E; - spawn_players_versus_one_player(D_80165210, D_80165230, sp5A); - break; - } - break; + case TIME_TRIALS: + D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E))); + D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E))); + D_80165230[0] = sp5C + 0x1E; + D_80165230[1] = sp5C + 0x1E; + D_80165230[2] = sp5C + 0x1E; + D_80165230[3] = sp5C + 0x1E; + D_80165230[4] = sp5C + 0x1E; + D_80165230[5] = sp5C + 0x1E; + D_80165230[6] = sp5C + 0x1E; + D_80165230[7] = sp5C + 0x1E; + spawn_players_versus_one_player(D_80165210, D_80165230, sp5A); + break; + } + break; - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - switch (gModeSelection) { - case GRAND_PRIX: - D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0x14))); - D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0x14))); - D_80165230[0] = sp5C + 0x1E; - D_80165230[1] = sp5C + 0x32; - D_80165230[2] = sp5C + 0x46; - D_80165230[3] = sp5C + 0x5A; - D_80165230[4] = sp5C + 0x6E; - D_80165230[5] = sp5C + 0x82; - D_80165230[6] = sp5C + 0x96; - D_80165230[7] = sp5C + 0xAA; - spawn_players_gp_two_player(D_80165210, D_80165230, sp5A); - break; + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + switch (gModeSelection) { + case GRAND_PRIX: + D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0x14))); + D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0x14))); + D_80165230[0] = sp5C + 0x1E; + D_80165230[1] = sp5C + 0x32; + D_80165230[2] = sp5C + 0x46; + D_80165230[3] = sp5C + 0x5A; + D_80165230[4] = sp5C + 0x6E; + D_80165230[5] = sp5C + 0x82; + D_80165230[6] = sp5C + 0x96; + D_80165230[7] = sp5C + 0xAA; + spawn_players_gp_two_player(D_80165210, D_80165230, sp5A); + break; - case VERSUS: - D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0xA))); - D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0xA))); - D_80165230[0] = sp5C + 0x1E; - D_80165230[1] = sp5C + 0x1E; - D_80165230[2] = sp5C + 0x1E; - D_80165230[3] = sp5C + 0x1E; - D_80165230[4] = sp5C + 0x1E; - D_80165230[5] = sp5C + 0x1E; - D_80165230[6] = sp5C + 0x1E; - D_80165230[7] = sp5C + 0x1E; - spawn_players_versus_two_player(D_80165210, D_80165230, sp5A); - break; - } - break; + case VERSUS: + D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = sp5E + 0xA))); + D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = sp5E - 0xA))); + D_80165230[0] = sp5C + 0x1E; + D_80165230[1] = sp5C + 0x1E; + D_80165230[2] = sp5C + 0x1E; + D_80165230[3] = sp5C + 0x1E; + D_80165230[4] = sp5C + 0x1E; + D_80165230[5] = sp5C + 0x1E; + D_80165230[6] = sp5C + 0x1E; + D_80165230[7] = sp5C + 0x1E; + spawn_players_versus_two_player(D_80165210, D_80165230, sp5A); + break; + } + break; - case SCREEN_MODE_3P_4P_SPLITSCREEN: - switch (gModeSelection) { - case VERSUS: - D_80165210[0] = sp5E + 0x1E; - D_80165210[6] = sp5E - 0xA; - D_80165210[1] = sp5E + 0xA; - D_80165210[7] = sp5E - 0x1E; - D_80165210[4] = sp5E - 0xA; - D_80165210[2] = sp5E - 0xA; - D_80165210[5] = sp5E - 0x1E; - D_80165210[3] = sp5E - 0x1E; - D_80165230[0] = sp5C + 0x1E; - D_80165230[1] = sp5C + 0x1E; - D_80165230[2] = sp5C + 0x1E; - D_80165230[3] = sp5C + 0x1E; - D_80165230[4] = sp5C + 0x1E; - D_80165230[5] = sp5C + 0x1E; - D_80165230[6] = sp5C + 0x1E; - D_80165230[7] = sp5C + 0x1E; - if (gPlayerCountSelection1 == 4) { - func_8003B870(D_80165210, D_80165230, sp5A); - } else { - func_8003B318(D_80165210, D_80165230, sp5A); - } - break; - } - break; - } - break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + switch (gModeSelection) { + case VERSUS: + D_80165210[0] = sp5E + 0x1E; + D_80165210[6] = sp5E - 0xA; + D_80165210[1] = sp5E + 0xA; + D_80165210[7] = sp5E - 0x1E; + D_80165210[4] = sp5E - 0xA; + D_80165210[2] = sp5E - 0xA; + D_80165210[5] = sp5E - 0x1E; + D_80165210[3] = sp5E - 0x1E; + D_80165230[0] = sp5C + 0x1E; + D_80165230[1] = sp5C + 0x1E; + D_80165230[2] = sp5C + 0x1E; + D_80165230[3] = sp5C + 0x1E; + D_80165230[4] = sp5C + 0x1E; + D_80165230[5] = sp5C + 0x1E; + D_80165230[6] = sp5C + 0x1E; + D_80165230[7] = sp5C + 0x1E; + if (gPlayerCountSelection1 == 4) { + func_8003B870(D_80165210, D_80165230, sp5A); + } else { + func_8003B318(D_80165210, D_80165230, sp5A); + } + break; + } + break; + } + } else if (GetCourse() == GetBlockFort()) { + switch (gActiveScreenMode) { + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + temp = 5; + if (1) {}; + D_80165210[0] = 0; + D_80165210[1] = 0; + D_80165230[1] = -200.0f; + D_80165230[0] = 200.0f; + spawn_players_2p_battle(D_80165210, D_80165230, temp); + break; - case COURSE_BLOCK_FORT: - switch (gActiveScreenMode) { - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - temp = 5; - if (1) {}; - D_80165210[0] = 0; - D_80165210[1] = 0; - D_80165230[1] = -200.0f; - D_80165230[0] = 200.0f; - spawn_players_2p_battle(D_80165210, D_80165230, temp); - break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + temp = 5; + D_80165210[2] = -200.0f; + D_80165230[1] = -200.0f; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165230[2] = 0.0f; + D_80165230[3] = 0.0f; + D_80165210[3] = 200.0f; + D_80165230[0] = 200.0f; + if (gPlayerCountSelection1 == 4) { + spawn_players_4p_battle(D_80165210, D_80165230, temp); + } else { + spawn_players_3p_battle(D_80165210, D_80165230, temp); + } + break; + } + } else if (GetCourse() == GetSkyscraper()) { + switch (gActiveScreenMode) { + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + temp = 0x1E0; + if (1) {}; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165230[1] = -400.0f; + D_80165230[0] = 400.0f; + spawn_players_2p_battle(D_80165210, D_80165230, temp); + break; - case SCREEN_MODE_3P_4P_SPLITSCREEN: - temp = 5; - D_80165210[2] = -200.0f; - D_80165230[1] = -200.0f; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165230[2] = 0.0f; - D_80165230[3] = 0.0f; - D_80165210[3] = 200.0f; - D_80165230[0] = 200.0f; - if (gPlayerCountSelection1 == 4) { - spawn_players_4p_battle(D_80165210, D_80165230, temp); - } else { - spawn_players_3p_battle(D_80165210, D_80165230, temp); - } - break; - } - break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + temp = 0x1E0; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165210[2] = -400.0f; + D_80165210[3] = 400.0f; + D_80165230[0] = 400.0f; + D_80165230[1] = -400.0f; + D_80165230[2] = 0.0f; + D_80165230[3] = 0.0f; + if (gPlayerCountSelection1 == 4) { + spawn_players_4p_battle(D_80165210, D_80165230, temp); + } else { + spawn_players_3p_battle(D_80165210, D_80165230, temp); + } + break; + } + } else if (GetCourse() == GetDoubleDeck()) { + switch (gActiveScreenMode) { + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + temp = 0x37; + if (1) {}; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165230[1] = -160.0f; + D_80165230[0] = 160.0f; + spawn_players_2p_battle(D_80165210, D_80165230, temp); + break; - case COURSE_SKYSCRAPER: - switch (gActiveScreenMode) { - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - temp = 0x1E0; - if (1) {}; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165230[1] = -400.0f; - D_80165230[0] = 400.0f; - spawn_players_2p_battle(D_80165210, D_80165230, temp); - break; + case 3: + temp = 0x37; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165210[2] = -160.0f; + D_80165210[3] = 160.0f; + D_80165230[0] = 160.0f; + D_80165230[1] = -160.0f; + D_80165230[2] = 0.0f; + D_80165230[3] = 0.0f; + if (gPlayerCountSelection1 == 4) { + spawn_players_4p_battle(D_80165210, D_80165230, temp); + } else { + spawn_players_3p_battle(D_80165210, D_80165230, temp); + } + break; + } + } else if (GetCourse() == GetBigDonut()) { + switch (gActiveScreenMode) { + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + temp = 0xC8; + if (1) {}; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165230[1] = -575.0f; + D_80165230[0] = 575.0f; + spawn_players_2p_battle(D_80165210, D_80165230, temp); + break; - case SCREEN_MODE_3P_4P_SPLITSCREEN: - temp = 0x1E0; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165210[2] = -400.0f; - D_80165210[3] = 400.0f; - D_80165230[0] = 400.0f; - D_80165230[1] = -400.0f; - D_80165230[2] = 0.0f; - D_80165230[3] = 0.0f; - if (gPlayerCountSelection1 == 4) { - spawn_players_4p_battle(D_80165210, D_80165230, temp); - } else { - spawn_players_3p_battle(D_80165210, D_80165230, temp); - } - break; - } - break; - - case COURSE_DOUBLE_DECK: - switch (gActiveScreenMode) { - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - temp = 0x37; - if (1) {}; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165230[1] = -160.0f; - D_80165230[0] = 160.0f; - spawn_players_2p_battle(D_80165210, D_80165230, temp); - break; - - case 3: - temp = 0x37; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165210[2] = -160.0f; - D_80165210[3] = 160.0f; - D_80165230[0] = 160.0f; - D_80165230[1] = -160.0f; - D_80165230[2] = 0.0f; - D_80165230[3] = 0.0f; - if (gPlayerCountSelection1 == 4) { - spawn_players_4p_battle(D_80165210, D_80165230, temp); - } else { - spawn_players_3p_battle(D_80165210, D_80165230, temp); - } - break; - } - break; - - case COURSE_BIG_DONUT: - switch (gActiveScreenMode) { - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - temp = 0xC8; - if (1) {}; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165230[1] = -575.0f; - D_80165230[0] = 575.0f; - spawn_players_2p_battle(D_80165210, D_80165230, temp); - break; - - case SCREEN_MODE_3P_4P_SPLITSCREEN: - temp = 0xC8; - D_80165210[0] = 0.0f; - D_80165210[1] = 0.0f; - D_80165210[2] = -575.0f; - D_80165210[3] = 575.0f; - D_80165230[0] = 575.0f; - D_80165230[1] = -575.0f; - D_80165230[2] = 0.0f; - D_80165230[3] = 0.0f; - if (gPlayerCountSelection1 == 4) { - spawn_players_4p_battle(D_80165210, D_80165230, temp); - } else { - spawn_players_3p_battle(D_80165210, D_80165230, temp); - } - break; - } - break; - - default: - D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = 20.0f))); - D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = -20.0f))); - D_80165230[0] = 30.0f; - D_80165230[1] = 50.0f; - D_80165230[2] = 70.0f; - D_80165230[3] = 90.0f; - D_80165230[4] = 110.0f; - D_80165230[5] = 130.0f; - D_80165230[6] = 150.0f; - D_80165230[7] = 170.0f; - spawn_player(gPlayerOneCopy, 0, D_80165210[0], D_80165230[0], sp5A, 32768.0f, gCharacterSelections[0], - PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); - spawn_player(gPlayerTwo, 1, D_80165210[1], D_80165230[1], sp5A, 32768.0f, 1, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerThree, 2, D_80165210[2], D_80165230[2], sp5A, 32768.0f, 2, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerFour, 3, D_80165210[3], D_80165230[3], sp5A, 32768.0f, 3, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerFive, 4, D_80165210[4], D_80165230[4], sp5A, 32768.0f, 4, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerSix, 5, D_80165210[5], D_80165230[5], sp5A, 32768.0f, 5, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerSeven, 6, D_80165210[6], D_80165230[6], sp5A, 32768.0f, 6, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - spawn_player(gPlayerEight, 7, D_80165210[7], D_80165230[7], sp5A, 32768.0f, 7, - PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); - D_80164A28 = 0; - break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + temp = 0xC8; + D_80165210[0] = 0.0f; + D_80165210[1] = 0.0f; + D_80165210[2] = -575.0f; + D_80165210[3] = 575.0f; + D_80165230[0] = 575.0f; + D_80165230[1] = -575.0f; + D_80165230[2] = 0.0f; + D_80165230[3] = 0.0f; + if (gPlayerCountSelection1 == 4) { + spawn_players_4p_battle(D_80165210, D_80165230, temp); + } else { + spawn_players_3p_battle(D_80165210, D_80165230, temp); + } + break; + } + } else { + D_80165210[0] = (D_80165210[2] = (D_80165210[4] = (D_80165210[6] = 20.0f))); + D_80165210[1] = (D_80165210[3] = (D_80165210[5] = (D_80165210[7] = -20.0f))); + D_80165230[0] = 30.0f; + D_80165230[1] = 50.0f; + D_80165230[2] = 70.0f; + D_80165230[3] = 90.0f; + D_80165230[4] = 110.0f; + D_80165230[5] = 130.0f; + D_80165230[6] = 150.0f; + D_80165230[7] = 170.0f; + spawn_player(gPlayerOneCopy, 0, D_80165210[0], D_80165230[0], sp5A, 32768.0f, gCharacterSelections[0], + PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN); + spawn_player(gPlayerTwo, 1, D_80165210[1], D_80165230[1], sp5A, 32768.0f, 1, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerThree, 2, D_80165210[2], D_80165230[2], sp5A, 32768.0f, 2, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerFour, 3, D_80165210[3], D_80165230[3], sp5A, 32768.0f, 3, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerFive, 4, D_80165210[4], D_80165230[4], sp5A, 32768.0f, 4, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerSix, 5, D_80165210[5], D_80165230[5], sp5A, 32768.0f, 5, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerSeven, 6, D_80165210[6], D_80165230[6], sp5A, 32768.0f, 6, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + spawn_player(gPlayerEight, 7, D_80165210[7], D_80165230[7], sp5A, 32768.0f, 7, + PLAYER_EXISTS | PLAYER_KART_AI | PLAYER_START_SEQUENCE); + D_80164A28 = 0; } if (gModeSelection != BATTLE) { @@ -1246,7 +1198,7 @@ void func_8003D080(void) { case SCREEN_MODE_1P: switch (gModeSelection) { case GRAND_PRIX: - if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) { + if (GetCourse() == GetToadsTurnpike()) { camera_init(0.0f, player->pos[1], D_80165230[7], player->rotation[1], 8, 0); } else { camera_init((D_80165210[7] + D_80165210[6]) / 2, player->pos[1], D_80165230[7], diff --git a/src/staff_ghosts.c b/src/staff_ghosts.c index e90a5ee49..4b5c4fa23 100644 --- a/src/staff_ghosts.c +++ b/src/staff_ghosts.c @@ -62,10 +62,6 @@ u32* D_800DC714 = (u32*) &D_802BFB80.arraySize8[1][1][3]; extern s32 gLapCountByPlayerId[]; -extern StaffGhost* d_mario_raceway_staff_ghost; -extern StaffGhost* d_royal_raceway_staff_ghost; -extern StaffGhost* d_luigi_raceway_staff_ghost; - void func_80004EF0(void) { D_80162DA4 = (u32*) &D_802BFB80.arraySize8[0][2][3]; u8* dest = (u8*) D_80162DA4; @@ -113,49 +109,7 @@ void func_80004FF8(void) { #endif void set_staff_ghost(void) { - u32 temp_v0; // Appears to be player total lap time. - - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - temp_v0 = func_800B4E24(0) & 0xfffff; - if (temp_v0 <= BLAH) { - D_80162DD6 = 0; - D_80162DF4 = 0; - } else { - D_80162DD6 = 1; - D_80162DF4 = 1; - } - D_80162DC4 = &d_mario_raceway_staff_ghost; - D_80162DE4 = 0; - break; - case COURSE_ROYAL_RACEWAY: - temp_v0 = func_800B4E24(0) & 0xfffff; - if (temp_v0 <= BLAH2) { - D_80162DD6 = 0; - D_80162DF4 = 0; - } else { - D_80162DD6 = 1; - D_80162DF4 = 1; - } - D_80162DC4 = &d_royal_raceway_staff_ghost; - D_80162DE4 = 6; - break; - case COURSE_LUIGI_RACEWAY: - temp_v0 = func_800B4E24(0) & 0xfffff; - if (temp_v0 <= BLAH3) { - D_80162DD6 = 0; - D_80162DF4 = 0; - } else { - D_80162DD6 = 1; - D_80162DF4 = 1; - } - D_80162DC4 = &d_luigi_raceway_staff_ghost; - D_80162DE4 = 1; - break; - default: - D_80162DD6 = 1; - D_80162DF4 = 1; - } + CourseManager_SetStaffGhost(); } s32 func_800051C4(void) { diff --git a/src/staff_ghosts.h b/src/staff_ghosts.h index 1ee48bc83..a58bb3291 100644 --- a/src/staff_ghosts.h +++ b/src/staff_ghosts.h @@ -21,10 +21,15 @@ void func_80005AE8(Player*); void func_80005E6C(void); void staff_ghosts_loop(void); +extern StaffGhost* d_mario_raceway_staff_ghost; +extern StaffGhost* d_royal_raceway_staff_ghost; +extern StaffGhost* d_luigi_raceway_staff_ghost; + // mi0decode extern s32 mio0encode(s32 input, s32, s32); +extern StaffGhost* D_80162DC4; extern s32 D_80162DC8; extern s32 D_80162DCC; extern u16 D_80162DD4; @@ -35,6 +40,7 @@ extern s32 D_80162DE0; extern s32 D_80162DE4; extern s32 D_80162DE8; extern s32 D_80162DF0; +extern s32 D_80162DF4; extern s32 D_80162DF8; #endif /* STAFF_GHOSTS_H */ diff --git a/src/update_objects.c b/src/update_objects.c index a0ea003c8..fcd8cc2bf 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -458,7 +458,7 @@ void func_800729EC(s32 objectIndex) { D_8018D2BC = 1; D_8018D2A4 = 1; - if (gCurrentCourseId != COURSE_YOSHI_VALLEY) { + if (GetCourse() != GetYoshiValley()) { for (i = 0; i < gPlayerCount; i++) { playerHUD[i].unk_81 = temp_v1; } @@ -1326,46 +1326,42 @@ void func_800748F4(s32 objectIndex, const char** lakituTexturePtr) { } void func_80074924(s32 objectIndex) { - s32 sp2C; + s32 sp2C = 0; s32 sp28; s32 sp24; - s32 sp20; - s16 temp_v0; + s32 sp20 = 0; s32 temp_a0; Object* object; object = &gObjectList[objectIndex]; object->sizeScaling = 0.15f; - temp_v0 = gCurrentCourseId; - switch (temp_v0) { /* irregular */ - case COURSE_MARIO_RACEWAY: - sp2C = random_int(0x00C8U); - sp28 = random_int(D_80165748); - sp24 = random_int(0x0096U); - sp20 = random_int(0x2000U); - object->origin_pos[0] = (f32) ((((f64) D_80165718 + 100.0) - (f64) sp2C) * (f64) xOrientation); - object->origin_pos[1] = (f32) (D_80165720 + sp28); - object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); - break; - case COURSE_ROYAL_RACEWAY: - sp2C = random_int(0x0168U); - sp28 = random_int(D_80165748); - sp24 = random_int(0x00B4U); - sp20 = random_int(0x2000U); - object->origin_pos[0] = (f32) ((((f64) D_80165718 + 180.0) - (f64) sp2C) * (f64) xOrientation); - object->origin_pos[1] = (f32) (D_80165720 + sp28); - object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); - break; - case COURSE_LUIGI_RACEWAY: - sp2C = random_int(0x012CU); - sp28 = random_int(D_80165748); - sp24 = random_int(0x0096U); - sp20 = random_int(0x2000U); - object->origin_pos[0] = (f32) ((((f64) D_80165718 + 150.0) - (f64) sp2C) * (f64) xOrientation); - object->origin_pos[1] = (f32) (D_80165720 + sp28); - object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); - break; + + if (GetCourse() == GetMarioRaceway()) { + sp2C = random_int(0x00C8U); + sp28 = random_int(D_80165748); + sp24 = random_int(0x0096U); + sp20 = random_int(0x2000U); + object->origin_pos[0] = (f32) ((((f64) D_80165718 + 100.0) - (f64) sp2C) * (f64) xOrientation); + object->origin_pos[1] = (f32) (D_80165720 + sp28); + object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); + } else if (GetCourse() == GetRoyalRaceway()) { + sp2C = random_int(0x0168U); + sp28 = random_int(D_80165748); + sp24 = random_int(0x00B4U); + sp20 = random_int(0x2000U); + object->origin_pos[0] = (f32) ((((f64) D_80165718 + 180.0) - (f64) sp2C) * (f64) xOrientation); + object->origin_pos[1] = (f32) (D_80165720 + sp28); + object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); + } else if (GetCourse() == GetLuigiRaceway()) { + sp2C = random_int(0x012CU); + sp28 = random_int(D_80165748); + sp24 = random_int(0x0096U); + sp20 = random_int(0x2000U); + object->origin_pos[0] = (f32) ((((f64) D_80165718 + 150.0) - (f64) sp2C) * (f64) xOrientation); + object->origin_pos[1] = (f32) (D_80165720 + sp28); + object->origin_pos[2] = (f32) (((f64) D_80165728 + 200.0) - (f64) sp24); } + set_obj_origin_offset(objectIndex, 0, 0, 0); if (gPlayerCount == 1) { object->velocity[1] = (f32) (((f64) (f32) (sp2C % 4) * 0.25) + 0.8); @@ -2429,28 +2425,25 @@ void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) { gObjectList[objectIndex].tlutList = (u8*) common_texture_particle_leaf; gObjectList[objectIndex].sizeScaling = 0.1f; gObjectList[objectIndex].surfaceHeight = arg1[1]; - switch (gCurrentCourseId) { - case COURSE_MARIO_RACEWAY: - object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); - gObjectList[objectIndex].unk_034 = 1.5f; - gObjectList[objectIndex].velocity[1] = 1.5f; - break; - case COURSE_YOSHI_VALLEY: - object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); - gObjectList[objectIndex].unk_034 = 2.0f; - gObjectList[objectIndex].velocity[1] = 2.0f; - break; - case COURSE_ROYAL_RACEWAY: - object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 30.0, arg1[2], 0x10, 0x28, 0x10); - gObjectList[objectIndex].unk_034 = 2.0f; - gObjectList[objectIndex].velocity[1] = 2.0f; - break; - case COURSE_LUIGI_RACEWAY: - object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); - gObjectList[objectIndex].unk_034 = 1.5f; - gObjectList[objectIndex].velocity[1] = 1.0f; - break; + + if (GetCourse() == GetMarioRaceway()) { + object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); + gObjectList[objectIndex].unk_034 = 1.5f; + gObjectList[objectIndex].velocity[1] = 1.5f; + } else if (GetCourse() == GetYoshiValley()) { + object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); + gObjectList[objectIndex].unk_034 = 2.0f; + gObjectList[objectIndex].velocity[1] = 2.0f; + } else if (GetCourse() == GetRoyalRaceway()) { + object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 30.0, arg1[2], 0x10, 0x28, 0x10); + gObjectList[objectIndex].unk_034 = 2.0f; + gObjectList[objectIndex].velocity[1] = 2.0f; + } else if (GetCourse() == GetLuigiRaceway()) { + object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14); + gObjectList[objectIndex].unk_034 = 1.5f; + gObjectList[objectIndex].velocity[1] = 1.0f; } + temp_s0 = random_int(0x0010U) << 0xC; sp3E = random_int(0x0010U) << 0xC; sp3C = random_int(0x0010U) << 0xC; @@ -2885,45 +2878,48 @@ void func_80078C70(s32 arg0) { D_8018D210 = (-(D_8018D200 / 2) * 0xB6) - 0x71C; D_8018D1E8 = 1.7578125 / D_8018D200; D_8018D218 = 0xA0; - switch (gCurrentCourseId) { /* switch 2 */ - case COURSE_MARIO_RACEWAY: /* switch 2 */ - // Uses Luigi Raceway's clouds for display purposes? - update_clouds(sp1C, camera, gLuigiRacewayClouds); - break; - case COURSE_YOSHI_VALLEY: /* switch 2 */ - update_clouds(sp1C, camera, gYoshiValleyMooMooFarmClouds); - break; - case COURSE_FRAPPE_SNOWLAND: /* switch 2 */ - func_80078170(sp1C, camera); - break; - case COURSE_KOOPA_BEACH: /* switch 2 */ - update_clouds(sp1C, camera, gKoopaTroopaBeachClouds); - break; - case COURSE_ROYAL_RACEWAY: /* switch 2 */ - update_clouds(sp1C, camera, gRoyalRacewayClouds); - break; - case COURSE_LUIGI_RACEWAY: /* switch 2 */ - update_clouds(sp1C, camera, gLuigiRacewayClouds); - break; - case COURSE_MOO_MOO_FARM: /* switch 2 */ - update_clouds(sp1C, camera, gYoshiValleyMooMooFarmClouds); - break; - case COURSE_TOADS_TURNPIKE: /* switch 2 */ - update_stars(sp1C, camera, gToadsTurnpikeRainbowRoadStars); - break; - case COURSE_KALAMARI_DESERT: /* switch 2 */ - update_clouds(sp1C, camera, gKalimariDesertClouds); - break; - case COURSE_SHERBET_LAND: /* switch 2 */ - update_clouds(sp1C, camera, gSherbetLandClouds); - break; - case COURSE_RAINBOW_ROAD: /* switch 2 */ - update_stars(sp1C, camera, gToadsTurnpikeRainbowRoadStars); - break; - case COURSE_WARIO_STADIUM: /* switch 2 */ - update_stars(sp1C, camera, gWarioStadiumStars); - break; - } + + CourseManager_UpdateClouds(sp1C, camera); + + // switch (gCurrentCourseId) { /* switch 2 */ + // case COURSE_MARIO_RACEWAY: /* switch 2 */ + // // Uses Luigi Raceway's clouds for display purposes? + // //update_clouds(sp1C, camera, gLuigiRacewayClouds); + // break; + // case COURSE_YOSHI_VALLEY: /* switch 2 */ + // update_clouds(sp1C, camera, gYoshiValleyMooMooFarmClouds); + // break; + // case COURSE_FRAPPE_SNOWLAND: /* switch 2 */ + // func_80078170(sp1C, camera); + // break; + // case COURSE_KOOPA_BEACH: /* switch 2 */ + // update_clouds(sp1C, camera, gKoopaTroopaBeachClouds); + // break; + // case COURSE_ROYAL_RACEWAY: /* switch 2 */ + // update_clouds(sp1C, camera, gRoyalRacewayClouds); + // break; + // case COURSE_LUIGI_RACEWAY: /* switch 2 */ + // update_clouds(sp1C, camera, gLuigiRacewayClouds); + // break; + // case COURSE_MOO_MOO_FARM: /* switch 2 */ + // update_clouds(sp1C, camera, gYoshiValleyMooMooFarmClouds); + // break; + // case COURSE_TOADS_TURNPIKE: /* switch 2 */ + // update_stars(sp1C, camera, gToadsTurnpikeRainbowRoadStars); + // break; + // case COURSE_KALAMARI_DESERT: /* switch 2 */ + // update_clouds(sp1C, camera, gKalimariDesertClouds); + // break; + // case COURSE_SHERBET_LAND: /* switch 2 */ + // update_clouds(sp1C, camera, gSherbetLandClouds); + // break; + // case COURSE_RAINBOW_ROAD: /* switch 2 */ + // update_stars(sp1C, camera, gToadsTurnpikeRainbowRoadStars); + // break; + // case COURSE_WARIO_STADIUM: /* switch 2 */ + // update_stars(sp1C, camera, gWarioStadiumStars); + // break; + //} } } @@ -2998,13 +2994,13 @@ void func_800791F0(s32 objectIndex, s32 playerId) { if ((gObjectList[objectIndex].unk_0D8 != 3) && (gObjectList[objectIndex].unk_0D8 != 7)) { func_800722CC(objectIndex, 1); - if (gCurrentCourseId == COURSE_SHERBET_LAND) { + if (GetCourse() == GetSherbetLand()) { player->unk_0CA &= 0xFFEF; } } else { // ????? } - if (gCurrentCourseId == COURSE_SHERBET_LAND) { + if (GetCourse() == GetSherbetLand()) { func_800722CC(objectIndex, 0x00000010); player->unk_0CA &= 0xFFDF; } @@ -3183,7 +3179,7 @@ void func_800797AC(s32 playerId) { objectIndex = gIndexLakituList[playerId]; player = &gPlayerOne[playerId]; - if ((gCurrentCourseId == COURSE_SHERBET_LAND) && (player->unk_0CA & 1)) { + if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) { init_object(objectIndex, 7); player->unk_0CA |= 0x10; } else { diff --git a/src/update_objects.h b/src/update_objects.h index a50f05e04..6bb8c09b5 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -8,6 +8,7 @@ /** @cond */ +void func_80078170(s32 arg0, Camera* arg1); void func_80077D5C(s32); s32 find_unused_obj_index(s32*); void delete_object(s32*); @@ -88,7 +89,7 @@ bool func_80073D0C(s32, s16*, s32, s32, s32, s32, s32); void func_80073D68(s32, s16*, s16, s32); void func_80073DC0(s32, s16*, s16, s32); bool func_80073E18(s32, u16*, u16, s32); -UNUSED bool func_80073ED4(s32, u16*, u16, s32); +bool func_80073ED4(s32, u16*, u16, s32); // unused void func_80073F90(s32, s32); void func_80073FAC(s32); void func_80073FD4(s32); diff --git a/torch b/torch index b9560339d..298578677 160000 --- a/torch +++ b/torch @@ -1 +1 @@ -Subproject commit b9560339d3aae8739ed237c8418acb444fdfe67b +Subproject commit 298578677e28ef1fe0d3a425f2856930c6cc4ef1