From 9273f38df135273d905ac14e7a090ebac4ba3ae9 Mon Sep 17 00:00:00 2001 From: n64 <> Date: Fri, 3 Jan 2020 10:38:57 -0500 Subject: [PATCH] refresh 5 --- CHANGES | 15 + Makefile | 7 +- assets.json | 14 +- bin/cave.c | 5 - bin/inside.c | 5 - bin/mountain.c | 10 - bin/segment2.c | 8 +- charmap.txt | 53 +- charmap_menu.txt | 2 +- data/behavior_data.c | 5527 ++++---- enhancements/debug_box.h | 23 + enhancements/debug_box.inc.c | 248 + enhancements/mem_error_screen.inc.c | 92 +- extract_assets.py | 8 +- include/behavior_data.h | 2 +- include/course_table.h | 5 +- include/geo_commands.h | 12 +- include/surface_terrains.h | 2 +- include/text_menu_strings.h.in | 2 +- include/text_strings.h.in | 78 +- include/textures.h | 4 - include/types.h | 2 +- levels/bbh/areas/1/geo.inc.c | 2 +- levels/bitdw/areas/1/geo.inc.c | 2 +- levels/bitfs/areas/1/geo.inc.c | 2 +- levels/bits/areas/1/geo.inc.c | 2 +- levels/bob/areas/1/geo.inc.c | 2 +- levels/bowser_1/areas/1/geo.inc.c | 2 +- levels/bowser_2/areas/1/geo.inc.c | 2 +- levels/bowser_3/areas/1/geo.inc.c | 2 +- levels/castle_courtyard/areas/1/geo.inc.c | 2 +- levels/castle_grounds/areas/1/geo.inc.c | 2 +- levels/castle_inside/areas/1/geo.inc.c | 2 +- levels/castle_inside/areas/2/geo.inc.c | 2 +- levels/castle_inside/areas/3/geo.inc.c | 2 +- levels/ccm/areas/1/geo.inc.c | 2 +- levels/ccm/areas/2/geo.inc.c | 2 +- levels/cotmc/areas/1/geo.inc.c | 2 +- levels/course_defines.h | 66 +- levels/ddd/areas/1/geo.inc.c | 2 +- levels/ddd/areas/2/geo.inc.c | 2 +- levels/ending/geo.c | 2 +- levels/hmc/areas/1/geo.inc.c | 2 +- levels/jrb/areas/1/geo.inc.c | 2 +- levels/jrb/areas/2/geo.inc.c | 2 +- levels/level_defines.h | 26 +- levels/lll/areas/1/geo.inc.c | 2 +- levels/lll/areas/2/geo.inc.c | 2 +- levels/pss/areas/1/geo.inc.c | 2 +- levels/rr/areas/1/geo.inc.c | 2 +- levels/sa/areas/1/geo.inc.c | 2 +- levels/sl/areas/1/geo.inc.c | 2 +- levels/sl/areas/2/geo.inc.c | 2 +- levels/ssl/areas/1/geo.inc.c | 2 +- levels/ssl/areas/2/geo.inc.c | 2 +- levels/ssl/areas/3/geo.inc.c | 2 +- levels/thi/areas/1/collision.inc.c | 2 +- levels/thi/areas/1/geo.inc.c | 2 +- levels/thi/areas/2/collision.inc.c | 2 +- levels/thi/areas/2/geo.inc.c | 2 +- levels/thi/areas/3/geo.inc.c | 2 +- levels/totwc/areas/1/geo.inc.c | 2 +- levels/ttc/areas/1/geo.inc.c | 2 +- levels/ttm/areas/1/geo.inc.c | 2 +- levels/ttm/areas/2/geo.inc.c | 2 +- levels/ttm/areas/3/geo.inc.c | 2 +- levels/ttm/areas/4/geo.inc.c | 2 +- levels/vcutm/areas/1/geo.inc.c | 2 +- levels/wdw/areas/1/geo.inc.c | 2 +- levels/wdw/areas/2/geo.inc.c | 2 +- levels/wf/areas/1/geo.inc.c | 2 +- levels/wmotr/areas/1/geo.inc.c | 2 +- src/engine/behavior_script.c | 178 +- src/engine/geo_layout.c | 28 +- src/engine/graph_node.c | 10 +- src/engine/graph_node.h | 14 +- src/engine/level_script.c | 2 +- src/engine/math_util.c | 1 + src/engine/math_util.h | 7 +- src/game/area.h | 54 +- src/game/behavior_actions.c | 4 +- src/game/behavior_actions.h | 6 +- src/game/behaviors/amp.inc.c | 6 +- src/game/behaviors/bobomb.inc.c | 6 +- src/game/behaviors/bowling_ball.inc.c | 6 +- src/game/behaviors/bowser.inc.c | 8 +- src/game/behaviors/bowser_bomb.inc.c | 2 +- src/game/behaviors/bullet_bill.inc.c | 2 +- src/game/behaviors/bully.inc.c | 2 +- src/game/behaviors/camera_lakitu.inc.c | 18 +- src/game/behaviors/capswitch.inc.c | 2 +- src/game/behaviors/chain_chomp.inc.c | 4 +- src/game/behaviors/door.inc.c | 6 +- src/game/behaviors/elevator.inc.c | 6 +- src/game/behaviors/end_birds_1.inc.c | 2 +- src/game/behaviors/end_birds_2.inc.c | 6 +- src/game/behaviors/explosion.inc.c | 2 +- src/game/behaviors/eyerok.inc.c | 6 +- src/game/behaviors/falling_pillar.inc.c | 2 +- src/game/behaviors/grand_star.inc.c | 2 +- src/game/behaviors/hoot.inc.c | 4 +- src/game/behaviors/horizontal_grindel.inc.c | 2 +- src/game/behaviors/intro_lakitu.inc.c | 37 +- src/game/behaviors/intro_peach.inc.c | 4 +- src/game/behaviors/intro_scene.inc.c | 16 +- src/game/behaviors/kickable_board.inc.c | 2 +- src/game/behaviors/king_bobomb.inc.c | 14 +- src/game/behaviors/koopa.inc.c | 2 +- src/game/behaviors/mips.inc.c | 4 +- src/game/behaviors/purple_switch.inc.c | 2 +- src/game/behaviors/racing_penguin.inc.c | 4 +- src/game/behaviors/rolling_log.inc.c | 2 +- src/game/behaviors/snowman.inc.c | 2 +- src/game/behaviors/sound_ambient.inc.c | 2 +- src/game/behaviors/sound_birds.inc.c | 2 +- src/game/behaviors/sound_sand.inc.c | 2 +- src/game/behaviors/sparkle_spawn_star.inc.c | 12 +- src/game/behaviors/spawn_star.inc.c | 6 +- src/game/behaviors/spindel.inc.c | 2 +- src/game/behaviors/thwomp.inc.c | 2 +- src/game/behaviors/tox_box.inc.c | 2 +- src/game/behaviors/treasure_chest.inc.c | 2 +- src/game/behaviors/tuxie.inc.c | 4 +- src/game/behaviors/ukiki.inc.c | 2 +- src/game/behaviors/water_bomb.inc.c | 4 +- src/game/behaviors/water_bomb_cannon.inc.c | 2 +- src/game/behaviors/whomp.inc.c | 12 +- src/game/behaviors/wiggler.inc.c | 4 +- src/game/behaviors/yoshi.inc.c | 7 +- src/game/camera.c | 11886 +++++++++++------- src/game/camera.h | 1190 +- src/game/envfx_bubbles.c | 3 +- src/game/envfx_snow.c | 5 +- src/game/hud.c | 4 +- src/game/ingame_menu.c | 48 +- src/game/ingame_menu.h | 8 +- src/game/interaction.c | 10 +- src/game/level_geo.c | 14 +- src/game/level_update.c | 7 +- src/game/main.c | 2 +- src/game/mario.c | 33 +- src/game/mario_actions_airborne.c | 48 +- src/game/mario_actions_automatic.c | 4 +- src/game/mario_actions_cutscene.c | 33 +- src/game/mario_actions_stationary.c | 9 +- src/game/mario_actions_submerged.c | 2 +- src/game/mario_misc.c | 16 +- src/game/memory.c | 6 +- src/game/memory.h | 2 +- src/game/moving_texture.c | 2 +- src/game/obj_behaviors.c | 2 +- src/game/obj_behaviors_2.c | 2 +- src/game/object_helpers.c | 10 +- src/game/object_helpers.h | 2 +- src/game/object_helpers2.h | 2 +- src/game/object_list_processor.h | 2 +- src/game/paintings.c | 10 +- src/game/paintings.h | 4 +- src/game/print.c | 11 +- src/game/rendering_graph_node.c | 2 +- src/game/screen_transition.c | 3 +- text/define_text.inc.c | 22 +- text/jp/courses.h | 126 +- text/jp/dialogs.h | 2248 ++-- tools/patch_libultra_math.c | 124 +- 165 files changed, 12516 insertions(+), 10252 deletions(-) create mode 100644 enhancements/debug_box.h create mode 100644 enhancements/debug_box.inc.c diff --git a/CHANGES b/CHANGES index a6d7102..193c0b8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,18 @@ +Refresh #5 +1.) mem_error_screen.inc.c updated for C (#775) +2.) updated patch_libultra_math to work directly on libultra.a (#781) +3.) Enhancement: Debug boxes (#783) +4.) Label effects MemoryPool (#784) +5.) Use full-width characters for JP text and rename mislabeled stuff (#772) +6.) Small asset extraction fixes (#785) +7.) Fix incremental asset extraction after the last PR (#790) +8.) Labelled behavior script commands, tidied up behavior scripts and ren… +9.) Document camera.c (#741) +10.) Fix a HMC texture asset (#795) +11.) Fix UB in angle conversion for paintings. Needed for pc-port. (#796) +12.) Fix PSS texture assets (#801) +13.) Fix some camera typos (#802) + Refresh #4 1.) Label screen_transition.c (#737) 2.) Revamp macros (#738) diff --git a/Makefile b/Makefile index e3b89b0..26c76d3 100644 --- a/Makefile +++ b/Makefile @@ -441,6 +441,7 @@ $(BUILD_DIR)/assets/mario_anim_data.c: $(wildcard assets/anims/*.inc.c) $(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/*.bin) $(PYTHON) tools/demo_data_converter.py assets/demo_data.json $(VERSION_CFLAGS) > $@ + # Source code $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1 @@ -471,11 +472,6 @@ $(GLOBAL_ASM_DEP).$(NON_MATCHING): @rm -f $(GLOBAL_ASM_DEP).* touch $@ -$(BUILD_DIR)/lib/src/math/%.o: lib/src/math/%.c - @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/src/math/$*.d $< - $(CC) -c $(CFLAGS) -o $@ $< - tools/patch_libultra_math $@ - $(BUILD_DIR)/%.o: %.c @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< $(CC) -c $(CFLAGS) -o $@ $< @@ -493,6 +489,7 @@ $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) $(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES) $(AR) rcs -o $@ $(ULTRA_O_FILES) + tools/patch_libultra_math $@ $(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES) $(AR) rcs -o $@ $(GODDARD_O_FILES) diff --git a/assets.json b/assets.json index 17cd87b..c64b3b8 100644 --- a/assets.json +++ b/assets.json @@ -188,7 +188,7 @@ "actors/haunted_cage/bbh_cage_floor.rgba16.png": [32,32,2048,{"jp":[1462368,49800],"us":[1469536,49800],"eu":[1341504,49800]}], "actors/haunted_cage/bbh_cage_ornament.rgba16.png": [32,16,1024,{"jp":[1462368,53896],"us":[1469536,53896],"eu":[1341504,53896]}], "actors/haunted_cage/bbh_cage_wooden_base.rgba16.png": [32,16,1024,{"jp":[1462368,54920],"us":[1469536,54920],"eu":[1341504,54920]}], -"actors/haunted_cage/bbh_cage_garbage.rgba16.png": [32,32,2048,{"jp:":[1462368,57992],"us":[1469536,57992],"eu":[1341504,57992]}], +"actors/haunted_cage/bbh_cage_garbage.rgba16.png": [32,32,2048,{"jp":[1462368,57992],"us":[1469536,57992],"eu":[1341504,57992]}], "actors/heart/spinning_heart.rgba16.png": [32,32,2048,{"jp":[2032944,55264],"us":[2040320,55264],"eu":[1912288,55264]}], "actors/heave_ho/heave-ho_arm_ornament.rgba16.png": [32,32,2048,{"jp":[1215456,68040],"us":[1222624,68040],"eu":[1094592,68040]}], "actors/heave_ho/heave-ho_face.rgba16.png": [32,32,2048,{"jp":[1215456,59848],"us":[1222624,59848],"eu":[1094592,59848]}], @@ -1031,8 +1031,7 @@ "sound/sequences/us/22_cutscene_lakitu.m64": [313,{"us":[8176864]}], "textures/cave/hmc_textures.00000.rgba16.png": [32,64,4096,{"jp":[3432432,0],"us":[3439184,0],"eu":[3312784,0]}], "textures/cave/hmc_textures.01000.rgba16.png": [32,32,2048,{"jp":[3432432,4096],"us":[3439184,4096],"eu":[3312784,4096]}], -"textures/cave/hmc_textures.01800.rgba16.png": [32,32,2048,{"jp":[3432432,6144],"us":[3439184,6144],"eu":[3312784,6144]}], -"textures/cave/hmc_textures.02000.rgba16.png": [32,32,2048,{"jp":[3432432,8192],"us":[3439184,8192],"eu":[3312784,8192]}], +"textures/cave/hmc_textures.01800.rgba16.png": [32,64,4096,{"jp":[3432432,6144],"us":[3439184,6144],"eu":[3312784,6144]}], "textures/cave/hmc_textures.02800.rgba16.png": [32,32,2048,{"jp":[3432432,10240],"us":[3439184,10240],"eu":[3312784,10240]}], "textures/cave/hmc_textures.03000.rgba16.png": [32,32,2048,{"jp":[3432432,12288],"us":[3439184,12288],"eu":[3312784,12288]}], "textures/cave/hmc_textures.03800.rgba16.png": [32,64,4096,{"jp":[3432432,14336],"us":[3439184,14336],"eu":[3312784,14336]}], @@ -1155,8 +1154,7 @@ "textures/inside/inside_castle_textures.07000.rgba16.png": [32,64,4096,{"jp":[3555104,28672],"us":[3561856,28672],"eu":[3435456,28672]}], "textures/inside/inside_castle_textures.08000.rgba16.png": [32,32,2048,{"jp":[3555104,32768],"us":[3561856,32768],"eu":[3435456,32768]}], "textures/inside/inside_castle_textures.08800.rgba16.png": [32,32,2048,{"jp":[3555104,34816],"us":[3561856,34816],"eu":[3435456,34816]}], -"textures/inside/inside_castle_textures.09000.rgba16.png": [32,32,2048,{"jp":[3555104,36864],"us":[3561856,36864],"eu":[3435456,36864]}], -"textures/inside/inside_castle_textures.09800.rgba16.png": [32,32,2048,{"jp":[3555104,38912],"us":[3561856,38912],"eu":[3435456,38912]}], +"textures/inside/inside_castle_textures.09000.rgba16.png": [32,64,4096,{"jp":[3555104,36864],"us":[3561856,36864],"eu":[3435456,36864]}], "textures/inside/inside_castle_textures.0A000.rgba16.png": [32,64,4096,{"jp":[3555104,40960],"us":[3561856,40960],"eu":[3435456,40960]}], "textures/inside/inside_castle_textures.0B000.rgba16.png": [32,32,2048,{"jp":[3555104,45056],"us":[3561856,45056],"eu":[3435456,45056]}], "textures/inside/inside_castle_textures.0B800.rgba16.png": [64,32,4096,{"jp":[3555104,47104],"us":[3561856,47104],"eu":[3435456,47104]}], @@ -1204,16 +1202,14 @@ "textures/machine/ttc_textures.08400.rgba16.png": [32,32,2048,{"jp":[3460352,33792],"us":[3467104,33792],"eu":[3340704,33792]}], "textures/mountain/ttm_textures.00000.rgba16.png": [32,32,2048,{"jp":[3473152,0],"us":[3479904,0],"eu":[3353504,0]}], "textures/mountain/ttm_textures.00800.rgba16.png": [64,32,4096,{"jp":[3473152,2048],"us":[3479904,2048],"eu":[3353504,2048]}], -"textures/mountain/ttm_textures.01800.rgba16.png": [32,32,2048,{"jp":[3473152,6144],"us":[3479904,6144],"eu":[3353504,6144]}], -"textures/mountain/ttm_textures.02000.rgba16.png": [32,32,2048,{"jp":[3473152,8192],"us":[3479904,8192],"eu":[3353504,8192]}], +"textures/mountain/ttm_textures.01800.rgba16.png": [32,64,4096,{"jp":[3473152,6144],"us":[3479904,6144],"eu":[3353504,6144]}], "textures/mountain/ttm_textures.02800.rgba16.png": [32,32,2048,{"jp":[3473152,10240],"us":[3479904,10240],"eu":[3353504,10240]}], "textures/mountain/ttm_textures.03000.rgba16.png": [32,32,2048,{"jp":[3473152,12288],"us":[3479904,12288],"eu":[3353504,12288]}], "textures/mountain/ttm_textures.03800.rgba16.png": [32,32,2048,{"jp":[3473152,14336],"us":[3479904,14336],"eu":[3353504,14336]}], "textures/mountain/ttm_textures.04000.rgba16.png": [32,32,2048,{"jp":[3473152,16384],"us":[3479904,16384],"eu":[3353504,16384]}], "textures/mountain/ttm_textures.04800.rgba16.png": [32,32,2048,{"jp":[3473152,18432],"us":[3479904,18432],"eu":[3353504,18432]}], "textures/mountain/ttm_textures.05000.rgba16.png": [32,32,2048,{"jp":[3473152,20480],"us":[3479904,20480],"eu":[3353504,20480]}], -"textures/mountain/ttm_textures.05800.rgba16.png": [32,32,2048,{"jp":[3473152,22528],"us":[3479904,22528],"eu":[3353504,22528]}], -"textures/mountain/ttm_textures.06000.rgba16.png": [32,32,2048,{"jp":[3473152,24576],"us":[3479904,24576],"eu":[3353504,24576]}], +"textures/mountain/ttm_textures.05800.rgba16.png": [32,64,4096,{"jp":[3473152,22528],"us":[3479904,22528],"eu":[3353504,22528]}], "textures/mountain/ttm_textures.06800.rgba16.png": [32,32,2048,{"jp":[3473152,26624],"us":[3479904,26624],"eu":[3353504,26624]}], "textures/mountain/ttm_textures.07000.rgba16.png": [32,32,2048,{"jp":[3473152,28672],"us":[3479904,28672],"eu":[3353504,28672]}], "textures/mountain/ttm_textures.07800.rgba16.png": [32,32,2048,{"jp":[3473152,30720],"us":[3479904,30720],"eu":[3353504,30720]}], diff --git a/bin/cave.c b/bin/cave.c index 4a2c0e1..56658cd 100644 --- a/bin/cave.c +++ b/bin/cave.c @@ -17,11 +17,6 @@ ALIGNED8 const u8 cave_09001800[] = { #include "textures/cave/hmc_textures.01800.rgba16.inc.c" }; -// 0x09002000 -ALIGNED8 const u8 cave_09002000[] = { -#include "textures/cave/hmc_textures.02000.rgba16.inc.c" -}; - // 0x09002800 ALIGNED8 const u8 cave_09002800[] = { #include "textures/cave/hmc_textures.02800.rgba16.inc.c" diff --git a/bin/inside.c b/bin/inside.c index 72fb38f..d668af3 100644 --- a/bin/inside.c +++ b/bin/inside.c @@ -72,11 +72,6 @@ ALIGNED8 const u8 inside_09009000[] = { #include "textures/inside/inside_castle_textures.09000.rgba16.inc.c" }; -// 0x09009800 -ALIGNED8 const u8 inside_09009800[] = { -#include "textures/inside/inside_castle_textures.09800.rgba16.inc.c" -}; - // 0x0900A000 ALIGNED8 const u8 inside_0900A000[] = { #include "textures/inside/inside_castle_textures.0A000.rgba16.inc.c" diff --git a/bin/mountain.c b/bin/mountain.c index fc2789d..8a675c3 100644 --- a/bin/mountain.c +++ b/bin/mountain.c @@ -17,11 +17,6 @@ ALIGNED8 const u8 mountain_09001800[] = { #include "textures/mountain/ttm_textures.01800.rgba16.inc.c" }; -// 0x09002000 -ALIGNED8 const u8 mountain_09002000[] = { -#include "textures/mountain/ttm_textures.02000.rgba16.inc.c" -}; - // 0x09002800 ALIGNED8 const u8 mountain_09002800[] = { #include "textures/mountain/ttm_textures.02800.rgba16.inc.c" @@ -57,11 +52,6 @@ ALIGNED8 const u8 mountain_09005800[] = { #include "textures/mountain/ttm_textures.05800.rgba16.inc.c" }; -// 0x09006000 -ALIGNED8 const u8 mountain_09006000[] = { -#include "textures/mountain/ttm_textures.06000.rgba16.inc.c" -}; - // 0x09006800 ALIGNED8 const u8 mountain_09006800[] = { #include "textures/mountain/ttm_textures.06800.rgba16.inc.c" diff --git a/bin/segment2.c b/bin/segment2.c index 5bcd359..97763d9 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -738,7 +738,7 @@ ALIGNED8 static const u8 texture_font_char_jp_hiragana_small_tsu[] = { #include "textures/segment2/segment2.07710.ia1.inc.c" }; -ALIGNED8 static const u8 texture_font_char_jp_hiragana_small_ka[] = { +ALIGNED8 static const u8 texture_font_char_jp_hiragana_small_ya[] = { #include "textures/segment2/segment2.07720.ia1.inc.c" }; @@ -962,7 +962,7 @@ ALIGNED8 static const u8 texture_font_char_jp_katakana_small_tsu[] = { #include "textures/segment2/segment2.07A90.ia1.inc.c" }; -ALIGNED8 static const u8 texture_font_char_jp_katakana_small_ka[] = { +ALIGNED8 static const u8 texture_font_char_jp_katakana_small_ya[] = { #include "textures/segment2/segment2.07AA0.ia1.inc.c" }; @@ -2028,7 +2028,7 @@ const u8 *const main_font_lut[] = { texture_font_char_jp_katakana_yu, texture_font_char_jp_katakana_yo, texture_font_char_jp_katakana_ra, texture_font_char_jp_katakana_ri, texture_font_char_jp_katakana_ru, texture_font_char_jp_katakana_re, texture_font_char_jp_katakana_ro, texture_font_char_jp_katakana_wa, 0x0, texture_font_char_jp_katakana_n, 0x0, texture_font_char_jp_long_vowel, - texture_font_char_jp_hiragana_small_e, texture_font_char_jp_hiragana_small_tsu, texture_font_char_jp_hiragana_small_ka, texture_font_char_jp_hiragana_small_yu, + texture_font_char_jp_hiragana_small_e, texture_font_char_jp_hiragana_small_tsu, texture_font_char_jp_hiragana_small_ya, texture_font_char_jp_hiragana_small_yu, texture_font_char_jp_hiragana_small_yo, texture_font_char_jp_hiragana_small_a, texture_font_char_jp_hiragana_small_i, texture_font_char_jp_hiragana_small_u, texture_font_char_jp_hiragana_small_o, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -2040,7 +2040,7 @@ const u8 *const main_font_lut[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - texture_font_char_jp_katakana_small_e, texture_font_char_jp_katakana_small_tsu, texture_font_char_jp_katakana_small_ka, texture_font_char_jp_katakana_small_yu, + texture_font_char_jp_katakana_small_e, texture_font_char_jp_katakana_small_tsu, texture_font_char_jp_katakana_small_ya, texture_font_char_jp_katakana_small_yu, texture_font_char_jp_katakana_small_yo, texture_font_char_jp_katakana_small_a, texture_font_char_jp_katakana_small_i, texture_font_char_jp_katakana_small_u, texture_font_char_jp_katakana_small_o, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, diff --git a/charmap.txt b/charmap.txt index a1e8b4f..49aaee5 100644 --- a/charmap.txt +++ b/charmap.txt @@ -1,39 +1,75 @@ '0' = 0x00 +'0' = 0x00 '1' = 0x01 +'1' = 0x01 '2' = 0x02 +'2' = 0x02 '3' = 0x03 +'3' = 0x03 '4' = 0x04 +'4' = 0x04 '5' = 0x05 +'5' = 0x05 '6' = 0x06 +'6' = 0x06 '7' = 0x07 +'7' = 0x07 '8' = 0x08 +'8' = 0x08 '9' = 0x09 +'9' = 0x09 'A' = 0x0A +'A' = 0x0A 'B' = 0x0B +'B' = 0x0B 'C' = 0x0C +'C' = 0x0C 'D' = 0x0D +'D' = 0x0D 'E' = 0x0E +'E' = 0x0E 'F' = 0x0F +'F' = 0x0F 'G' = 0x10 +'G' = 0x10 'H' = 0x11 +'H' = 0x11 'I' = 0x12 +'I' = 0x12 'J' = 0x13 +'J' = 0x13 'K' = 0x14 +'K' = 0x14 'L' = 0x15 +'L' = 0x15 'M' = 0x16 +'M' = 0x16 'N' = 0x17 +'N' = 0x17 'O' = 0x18 +'O' = 0x18 'P' = 0x19 +'P' = 0x19 'Q' = 0x1A +'Q' = 0x1A 'R' = 0x1B +'R' = 0x1B 'S' = 0x1C +'S' = 0x1C 'T' = 0x1D +'T' = 0x1D 'U' = 0x1E +'U' = 0x1E 'V' = 0x1F +'V' = 0x1F 'W' = 0x20 +'W' = 0x20 'X' = 0x21 +'X' = 0x21 'Y' = 0x22 +'Y' = 0x22 'Z' = 0x23 +'Z' = 0x23 'a' = 0x24 'b' = 0x25 'c' = 0x26 @@ -114,6 +150,7 @@ 'ん' = 0x6D '。' = 0x6E ',' = 0x6F +'、' = 0x6F 'ア' = 0x70 'イ' = 0x71 'ウ' = 0x72 @@ -162,7 +199,9 @@ 'ヲ' = 0x9C 'ン' = 0x9D ' ' = 0x9E +' ' = 0x9E '-' = 0x9F +'ー' = 0x9F 'ぇ' = 0xA0 'っ' = 0xA1 'ゃ' = 0xA2 @@ -183,17 +222,27 @@ 'ォ' = 0xD8 '[%]' = 0xE0 '(' = 0xE1 +'(' = 0xE1 ')(' = 0xE2 +')(' = 0xE2 ')' = 0xE3 +')' = 0xE3 '+' = 0xE4 +'↔' = 0xE4 '&' = 0xE5 ':' = 0xE6 +'゛' = 0xF0 +'゜' = 0xF1 '!' = 0xF2 +'!' = 0xF2 '%' = 0xF3 +'%' = 0xF3 '?' = 0xF4 +'?' = 0xF4 '『' = 0xF5 '』' = 0xF6 '~' = 0xF7 +'~' = 0xF7 '…' = 0xF8 '$' = 0xF9 '★' = 0xFA @@ -202,7 +251,7 @@ '☆' = 0xFD '\n' = 0xFE -# kana or hira with dakuten +# hiragana or katakana with dakuten 'が' = 0xF0, 0x45 'ぎ' = 0xF0, 0x46 'ぐ' = 0xF0, 0x47 @@ -244,7 +293,7 @@ 'ベ' = 0xF0, 0x8C 'ボ' = 0xF0, 0x8D -# kana or hira with handakuten +# hiragana or katakana with handakuten 'ぱ' = 0xF1, 0x59 'ぴ' = 0xF1, 0x5A 'ぷ' = 0xF1, 0x5B diff --git a/charmap_menu.txt b/charmap_menu.txt index 60a14d6..7642e73 100644 --- a/charmap_menu.txt +++ b/charmap_menu.txt @@ -23,7 +23,7 @@ 'み' = 0x14 'ど' = 0x15 'の' = 0x16 -'?' = 0x17 +'?' = 0x17 'サ' = 0x18 'ウ' = 0x19 'ン' = 0x1A diff --git a/data/behavior_data.c b/data/behavior_data.c index d0b5571..73bb9ae 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -67,3251 +67,3041 @@ #define BC_W(a) ((uintptr_t)(u32)(a)) #define BC_PTR(a) ((uintptr_t)(a)) -// TODO: Go through these and rename a bunch of them, some of these names are really bad. -#define BEGIN(arg1) \ - BC_BB(0x00, arg1) +// Defines the start of the behavior script as well as the object list the object belongs to. +// Has some special behavior for certain BBH objects. +#define BEGIN(objList) \ + BC_BB(0x00, objList) +// Delays the behavior script for a certain number of frames. #define DELAY(frames) \ BC_B0H(0x01, frames) +// Jumps to a new behavior command and stores the return address in the object's stack. #define CALL(addr) \ BC_B(0x02), \ BC_PTR(addr) +// Jumps back to the behavior command stored in the object's stack. #define RETURN() \ BC_B(0x03) +// Jumps to a new behavior script without saving anything. #define GOTO(addr) \ BC_B(0x04), \ BC_PTR(addr) +// Marks the start of a loop that will repeat a certain number of times. #define BEGIN_REPEAT(times) \ BC_B0H(0x05, times) +// Marks the end of a repeating loop. #define END_REPEAT() \ BC_B(0x06) -#define END_REPEAT_NOBREAK() \ +// Also marks the end of a repeating loop, but continues executing commands following the loop on the same frame. +#define END_REPEAT_CONTINUE() \ BC_B(0x07) +// Marks the beginning of an infinite loop. #define BEGIN_LOOP() \ BC_B(0x08) +// Marks the end of an infinite loop. #define END_LOOP() \ BC_B(0x09) +// Exits the behavior script. +// Often used to end behavior scripts that do not contain an infinite loop. #define BREAK() \ BC_B(0x0A) -#define CALLNATIVE(addr) \ +// Executes a native game function. +#define CALL_NATIVE(addr) \ BC_B(0x0C), \ BC_PTR(addr) -#define OBJ_ADD_FLOAT(field, value) \ +// Adds a float to the specified field. +#define ADD_FLOAT(field, value) \ BC_BBH(0x0D, field, value) -#define OBJ_SET_FLOAT(field, value) \ +// Sets the specified field to a float. +#define SET_FLOAT(field, value) \ BC_BBH(0x0E, field, value) -#define OBJ_ADD_INT(field, value) \ +// Adds an integer to the specified field. +#define ADD_INT(field, value) \ BC_BBH(0x0F, field, value) -#define OBJ_SET_INT(field, value) \ +// Sets the specified field to an integer. +#define SET_INT(field, value) \ BC_BBH(0x10, field, value) -#define OBJ_OR_INT(field, value) \ +// Performs a bitwise OR with the specified field and the given integer. +// Usually used to set an object's flags. +#define OR_INT(field, value) \ BC_BBH(0x11, field, value) -#define OBJ_BIT_CLEAR_INT(field, value) \ +// Performs a bit clear with the specified short. Unused in favor of the 32-bit version. +#define BIT_CLEAR_INT(field, value) \ BC_BBH(0x12, field, value) -#define OBJ_SET_INT_RAND_RSHIFT(field, min, rshift) \ +// TODO: this one needs a better name / labelling +// Gets a random short, right shifts it the specified amount and adds min to it, then sets the specified field to that value. +#define SET_INT_RAND_RSHIFT(field, min, rshift) \ BC_BBH(0x13, field, min), \ BC_H(rshift) -#define OBJ_SET_FLOAT_RAND(field, min, max) \ +// Sets the specified field to a random float in the given range. +#define SET_RANDOM_FLOAT(field, min, max) \ BC_BBH(0x14, field, min), \ BC_H(max) -#define OBJ_SET_INT_RAND(field, min, max) \ +// Sets the specified field to a random integer in the given range. +#define SET_RANDOM_INT(field, min, max) \ BC_BBH(0x15, field, min), \ BC_H(max) -#define OBJ_ADD_FLOAT_RAND(field, min, max) \ +// Adds a random float in the given range to the specified field. +#define ADD_RANDOM_FLOAT(field, min, max) \ BC_BBH(0x16, field, min), \ BC_H(max) -#define OBJ_ADD_INT_RAND_RSHIFT(field, min, rshift) \ +// TODO: better name (unused anyway) +// Gets a random short, right shifts it the specified amount and adds min to it, then adds the value to the specified field. Unused. +#define ADD_INT_RAND_RSHIFT(field, min, rshift) \ BC_BBH(0x17, field, min), \ BC_H(rshift) -#define GEO_LAYOUT(model_id) \ - BC_B0H(0x1B, model_id) +// Sets the current model ID of the object. +#define SET_MODEL(modelID) \ + BC_B0H(0x1B, modelID) -#define OBJ_CHILD(model_id, beh) \ +// Spawns a child object with the specified model and behavior. +#define SPAWN_CHILD(modelID, bhv) \ BC_B(0x1C), \ - BC_W(model_id), \ - BC_PTR(beh) + BC_W(modelID), \ + BC_PTR(bhv) +// Exits the behavior script and despawns the object. +// Often used to end behavior scripts that do not contain an infinite loop. #define DEACTIVATE() \ BC_B(0x1D) -#define DROP_FLOOR() \ +// Finds the floor triangle directly under the object and moves the object down to it. +#define DROP_TO_FLOOR() \ BC_B(0x1E) -#define OBJ_SUM_FLOAT(fieldDest, fieldSrc1, fieldSrc2) \ +// Sets the destination float field to the sum of the values of the given float fields. +#define SUM_FLOAT(fieldDest, fieldSrc1, fieldSrc2) \ BC_BBBB(0x1F, fieldDest, fieldSrc1, fieldSrc2) -#define OBJ_SUM_INT(fieldDest, fieldSrc1, fieldSrc2) \ +// Sets the destination integer field to the sum of the values of the given integer fields. +#define SUM_INT(fieldDest, fieldSrc1, fieldSrc2) \ BC_BBBB(0x20, fieldDest, fieldSrc1, fieldSrc2) +// Billboards the current object, making it always face the camera. #define BILLBOARD() \ BC_B(0x21) -#define UNHIDE() \ +// Hides the current object. +#define HIDE() \ BC_B(0x22) +// Sets the size of the object's cylindrical hitbox. #define SET_HITBOX(radius, height) \ BC_B(0x23), \ BC_HH(radius, height) +// Delays the behavior script for the number of frames given by the value of the specified field.. #define DELAY_VAR(field) \ BC_BB(0x25, field) -#define OBJ_SET_ANIMS(field, value) \ +// Loads the animations for the object. +#define LOAD_ANIMATIONS(field, value) \ BC_BB(0x27, field), \ BC_PTR(value) +// Begins animation and sets the object's current animation index to the specified value. #define ANIMATE(animIndex) \ BC_BB(0x28, animIndex) -#define OBJ_CHILD_PARAM(behParam, model_id, beh) \ +// Spawns a child object with the specified model and behavior, plus a behavior param. +#define SPAWN_CHILD_WITH_PARAM(behParam, modelID, bhv) \ BC_B0H(0x29, behParam), \ - BC_W(model_id), \ - BC_PTR(beh) + BC_W(modelID), \ + BC_PTR(bhv) -#define COLLISION_DATA(addr) \ +// Loads collision data for the object. +#define LOAD_COLLISION_DATA(addr) \ BC_B(0x2A), \ BC_PTR(addr) -#define COLLISION_SPHERE(radius, height, arg3) \ +// Sets the size of the object's cylindrical hitbox, and applies a downwards offset. +#define SET_HITBOX_WITH_OFFSET(radius, height, downOffset) \ BC_B(0x2B), \ BC_HH(radius, height), \ - BC_H(arg3) + BC_H(downOffset) -#define OBJ_SPAWN(model_id, beh) \ +// Spawns a new object with the specified model and behavior. +#define SPAWN_OBJ(modelID, bhv) \ BC_B(0x2C), \ - BC_W(model_id), \ - BC_PTR(beh) + BC_W(modelID), \ + BC_PTR(bhv) -#define OBJ_SET_POS() \ +// Sets the home position of the object to its current position. +#define SET_HOME() \ BC_B(0x2D) -#define OBJ_SET_FLOAT2(arg1, arg2) \ +// Sets the size of the object's cylindrical hurtbox. +#define SET_HURTBOX(radius, height) \ BC_B(0x2E), \ - BC_HH(arg1, arg2) + BC_HH(radius, height) -#define INTERACT_TYPE(type) \ +// Sets the object's interaction type. +#define SET_INTERACT_TYPE(type) \ BC_B(0x2F), \ BC_PTR(type) -#define OBJ_PHYSICS(wallHitboxRadius, gravity, bounciness, drag, friction, buoyancy, unused1, unused2) \ +// Sets various parameters that the object uses for calculating physics. +#define SET_OBJ_PHYSICS(wallHitboxRadius, gravity, bounciness, drag, friction, buoyancy, unused1, unused2) \ BC_B(0x30), \ BC_HH(wallHitboxRadius, gravity), \ BC_HH(bounciness, drag), \ BC_HH(friction, buoyancy), \ BC_HH(unused1, unused2) +// Sets the object's size to the specified percentage. #define SCALE(percent) \ BC_B0H(0x32, percent) -#define OBJ_BIT_CLEAR_INT32(field, value) \ +// Performs a bit clear with the specified integer. +#define BIT_CLEAR_INT32(field, value) \ BC_BB(0x33, field), \ BC_W(value) -#define TEXT_ANIM_RATE(field, arg2) \ - BC_BBH(0x34, field, arg2) +// Adds 1 to the specified field every frames. Only used for animation. +#define TEX_ANIM_RATE(field, rate) \ + BC_BBH(0x34, field, rate) -#define GRAPH_CLEAR() \ +// Disables rendering for the object. +#define DISABLE_RENDERING() \ BC_B(0x35) -#define SPAWN_ADDR(arg1) \ +// Spawns a water splash with the given parameters. +#define SPAWN_WATER_SPLASH(params) \ BC_B(0x37), \ - BC_PTR(arg1) + BC_PTR(params) + -// 0000 const BehaviorScript bhvStarDoor[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oInteractType, INTERACT_DOOR), - COLLISION_DATA(inside_castle_seg7_collision_star_door), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_STAR_DOOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - SET_HITBOX(80, 100), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oDrawingDistance, 20000), - CALLNATIVE(bhv_door_init), - OBJ_SET_INT(oIntangibleTimer, 0), + SET_INT(oInteractType, INTERACT_DOOR), + LOAD_COLLISION_DATA(inside_castle_seg7_collision_star_door), + SET_INT(oInteractionSubtype, INT_SUBTYPE_STAR_DOOR), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 100), + SET_HOME(), + SET_FLOAT(oDrawingDistance, 20000), + CALL_NATIVE(bhv_door_init), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_star_door_loop), - CALLNATIVE(bhv_star_door_loop_2), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_star_door_loop), + CALL_NATIVE(bhv_star_door_loop_2), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0054 const BehaviorScript bhvMrI[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_CHILD(MODEL_MR_I_IRIS, bhvMrIBody), - GEO_LAYOUT(MODEL_MR_I), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SPAWN_CHILD(/*Model*/ MODEL_MR_I_IRIS, /*Behavior*/ bhvMrIBody), + SET_MODEL(MODEL_MR_I), BILLBOARD(), - CALLNATIVE(bhv_init_room), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_mr_i_loop), + CALL_NATIVE(bhv_mr_i_loop), END_LOOP(), }; -// 008C const BehaviorScript bhvMrIBody[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_mr_i_body_loop), + CALL_NATIVE(bhv_mr_i_body_loop), END_LOOP(), }; -// 00AC const BehaviorScript bhvMrIParticle[] = { BEGIN(OBJ_LIST_LEVEL), BILLBOARD(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oIntangibleTimer, 0), SET_HITBOX(50, 50), - OBJ_SET_INT(oDamageOrCoinValue, 1), - OBJ_SET_INT(oInteractType, INTERACT_DAMAGE), - OBJ_PHYSICS(0x001E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), + SET_INT(oDamageOrCoinValue, 1), + SET_INT(oInteractType, INTERACT_DAMAGE), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_mr_i_particle_loop), + CALL_NATIVE(bhv_mr_i_particle_loop), END_LOOP(), }; -// 00F8 const BehaviorScript bhvPurpleParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(10), - CALLNATIVE(bhv_piranha_particle_loop), + CALL_NATIVE(bhv_piranha_particle_loop), END_REPEAT(), DEACTIVATE(), }; -// 0118 const BehaviorScript bhvGiantPole[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oInteractType, INTERACT_POLE), - SET_HITBOX(0x0050, 0x0834), - OBJ_SET_POS(), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oInteractType, INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 2100), + SET_HOME(), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_giant_pole_loop), + CALL_NATIVE(bhv_giant_pole_loop), END_LOOP(), }; -// 0144 const BehaviorScript bhvPoleGrabbing[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oInteractType, INTERACT_POLE), - SET_HITBOX(0x0050, 0x05DC), - CALLNATIVE(bhv_pole_init), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oInteractType, INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 1500), + CALL_NATIVE(bhv_pole_init), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(BehClimbDetectLoop), + CALL_NATIVE(BehClimbDetectLoop), END_LOOP(), }; -// 0174 const BehaviorScript bhvThiHugeIslandTop[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(thi_seg7_collision_top_trap), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(thi_seg7_collision_top_trap), BEGIN_LOOP(), - CALLNATIVE(bhv_thi_huge_island_top_loop), + CALL_NATIVE(bhv_thi_huge_island_top_loop), END_LOOP(), }; -// 0194 const BehaviorScript bhvThiTinyIslandTop[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_thi_tiny_island_top_loop), + CALL_NATIVE(bhv_thi_tiny_island_top_loop), END_LOOP(), }; -// 01AC const BehaviorScript bhvCapSwitchBase[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(capswitch_collision_05003448), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(capswitch_collision_05003448), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 01CC const BehaviorScript bhvCapSwitch[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(capswitch_collision_050033D0), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(capswitch_collision_050033D0), BEGIN_LOOP(), - CALLNATIVE(bhv_cap_switch_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_cap_switch_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 01F4 const BehaviorScript bhvKingBobomb[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, king_bobomb_seg5_anims_0500FE30), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - SET_HITBOX(0x0064, 0x0064), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_INT(oIntangibleTimer, 0), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_SPAWN(MODEL_NONE, bhvBobombAnchorMario), - OBJ_SET_INT(oHealth, 0x0003), - OBJ_SET_INT(oDamageOrCoinValue, 1), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, king_bobomb_seg5_anims_0500FE30), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 100), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_INT(oIntangibleTimer, 0), + DROP_TO_FLOOR(), + SET_HOME(), + SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvBobombAnchorMario), + SET_INT(oHealth, 3), + SET_INT(oDamageOrCoinValue, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_king_bobomb_loop), + CALL_NATIVE(bhv_king_bobomb_loop), END_LOOP(), }; -// 0254 const BehaviorScript bhvBobombAnchorMario[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_FLOAT(oParentRelativePosX, 0x0064), - OBJ_SET_FLOAT(oParentRelativePosZ, 0x0096), + SET_FLOAT(oParentRelativePosX, 100), + SET_FLOAT(oParentRelativePosZ, 150), BEGIN_LOOP(), - CALLNATIVE(bhv_bobomb_anchor_mario_loop), + CALL_NATIVE(bhv_bobomb_anchor_mario_loop), END_LOOP(), }; -// 0278 const BehaviorScript bhvBetaChestBottom[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - CALLNATIVE(bhv_beta_chest_bottom_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_beta_chest_bottom_init), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_chest_bottom_loop), + CALL_NATIVE(bhv_beta_chest_bottom_loop), END_LOOP(), }; -// 029C const BehaviorScript bhvBetaChestLid[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_chest_lid_loop), + CALL_NATIVE(bhv_beta_chest_lid_loop), END_LOOP(), }; -// 02B8 const BehaviorScript bhvBubbleMario[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - OBJ_SET_INT_RAND(oWaterObjUnkF4, 0x0002, 0x0009), + DISABLE_RENDERING(), + SET_RANDOM_INT(oWaterObjUnkF4, /*Minimum*/ 2, /*Maximum*/ 9), DELAY_VAR(oWaterObjUnkF4), - OBJ_CHILD(MODEL_BUBBLE, bhvSmallWaterWave), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000020), + SPAWN_CHILD(/*Model*/ MODEL_BUBBLE, /*Behavior*/ bhvSmallWaterWave), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_5), DEACTIVATE(), }; -// 02E4 const BehaviorScript bhvBubbleMaybe[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - CALLNATIVE(bhv_bubble_wave_init), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF4, 0xFFB5, 0x0096), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF8, 0xFFB5, 0x0096), - OBJ_SET_FLOAT_RAND(oWaterObjUnkFC, 0xFFB5, 0x0096), - OBJ_SUM_FLOAT(oPosX, oPosX, oWaterObjUnkF4), - OBJ_SUM_FLOAT(oPosZ, oPosZ, oWaterObjUnkF8), - OBJ_SUM_FLOAT(oPosY, oPosY, oWaterObjUnkFC), - OBJ_SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_bubble_wave_init), + SET_RANDOM_FLOAT(oWaterObjUnkF4, /*Minimum*/ -75, /*Maximum*/ 150), + SET_RANDOM_FLOAT(oWaterObjUnkF8, /*Minimum*/ -75, /*Maximum*/ 150), + SET_RANDOM_FLOAT(oWaterObjUnkFC, /*Minimum*/ -75, /*Maximum*/ 150), + SUM_FLOAT(/*Dest*/ oPosX, /*Value 1*/ oPosX, /*Value 2*/ oWaterObjUnkF4), + SUM_FLOAT(/*Dest*/ oPosZ, /*Value 1*/ oPosZ, /*Value 2*/ oWaterObjUnkF8), + SUM_FLOAT(/*Dest*/ oPosY, /*Value 1*/ oPosY, /*Value 2*/ oWaterObjUnkFC), + SET_INT(oAnimState, -1), BEGIN_REPEAT(60), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_bubble_maybe_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_bubble_maybe_loop), END_REPEAT(), DEACTIVATE(), }; -// 0338 const BehaviorScript bhvSmallWaterWave[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - CALLNATIVE(bhv_bubble_wave_init), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF4, 0xFFCE, 0x0064), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF8, 0xFFCE, 0x0064), - OBJ_SUM_FLOAT(oPosX, oPosX, oWaterObjUnkF4), - OBJ_SUM_FLOAT(oPosZ, oPosZ, oWaterObjUnkF8), - OBJ_SET_FLOAT_RAND(oWaterObjUnkFC, 0x0000, 0x0032), - OBJ_SUM_FLOAT(oPosY, oPosY, oWaterObjUnkFC), - OBJ_SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_bubble_wave_init), + SET_RANDOM_FLOAT(oWaterObjUnkF4, /*Minimum*/ -50, /*Maximum*/ 100), + SET_RANDOM_FLOAT(oWaterObjUnkF8, /*Minimum*/ -50, /*Maximum*/ 100), + SUM_FLOAT(/*Dest*/ oPosX, /*Value 1*/ oPosX, /*Value 2*/ oWaterObjUnkF4), + SUM_FLOAT(/*Dest*/ oPosZ, /*Value 1*/ oPosZ, /*Value 2*/ oWaterObjUnkF8), + SET_RANDOM_FLOAT(oWaterObjUnkFC, /*Minimum*/ 0, /*Maximum*/ 50), + SUM_FLOAT(/*Dest*/ oPosY, /*Value 1*/ oPosY, /*Value 2*/ oWaterObjUnkFC), + SET_INT(oAnimState, -1), CALL(bhvSmallWaterWave398), BEGIN_REPEAT(60), CALL(bhvSmallWaterWave398), - CALLNATIVE(bhv_small_water_wave_loop), + CALL_NATIVE(bhv_small_water_wave_loop), END_REPEAT(), DEACTIVATE(), }; -// 0398 const BehaviorScript bhvSmallWaterWave398[] = { - OBJ_ADD_INT(oAnimState, 1), - OBJ_ADD_FLOAT(oPosY, 7), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF4, -2, 5), - OBJ_SET_FLOAT_RAND(oWaterObjUnkF8, -2, 5), - OBJ_SUM_FLOAT(oPosX, oPosX, oWaterObjUnkF4), - OBJ_SUM_FLOAT(oPosZ, oPosZ, oWaterObjUnkF8), + ADD_INT(oAnimState, 1), + ADD_FLOAT(oPosY, 7), + SET_RANDOM_FLOAT(oWaterObjUnkF4, /*Minimum*/ -2, /*Maximum*/ 5), + SET_RANDOM_FLOAT(oWaterObjUnkF8, /*Minimum*/ -2, /*Maximum*/ 5), + SUM_FLOAT(/*Dest*/ oPosX, /*Value 1*/ oPosX, /*Value 2*/ oWaterObjUnkF4), + SUM_FLOAT(/*Dest*/ oPosZ, /*Value 1*/ oPosZ, /*Value 2*/ oWaterObjUnkF8), RETURN(), }; -// 03BC const BehaviorScript bhvWaterAirBubble[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - COLLISION_SPHERE(0x0190, 0x0096, 0xFF6A), - OBJ_SET_INT(oIntangibleTimer, 0), - INTERACT_TYPE(INTERACT_WATER_RING), - OBJ_SET_INT(oDamageOrCoinValue, 5), - CALLNATIVE(bhv_water_air_bubble_init), - OBJ_SET_INT(oAnimState, -1), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 400, /*Height*/ 150, /*Downwards offset*/ -150), + SET_INT(oIntangibleTimer, 0), + SET_INTERACT_TYPE(INTERACT_WATER_RING), + SET_INT(oDamageOrCoinValue, 5), + CALL_NATIVE(bhv_water_air_bubble_init), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_water_air_bubble_loop), + CALL_NATIVE(bhv_water_air_bubble_loop), END_LOOP(), }; -// 0400 const BehaviorScript bhvSmallParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_particle_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_particle_init), BEGIN_REPEAT(70), - CALLNATIVE(bhv_particle_loop), + CALL_NATIVE(bhv_particle_loop), END_REPEAT(), DEACTIVATE(), }; -// 0428 const BehaviorScript bhvWaterWaves[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000200), - GRAPH_CLEAR(), - CALLNATIVE(bhv_water_waves_init), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_9), + DISABLE_RENDERING(), + CALL_NATIVE(bhv_water_waves_init), DEACTIVATE(), }; -// 0444 const BehaviorScript bhvSmallParticleSnow[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_particle_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_particle_init), BEGIN_REPEAT(30), - CALLNATIVE(bhv_particle_loop), + CALL_NATIVE(bhv_particle_loop), END_REPEAT(), DEACTIVATE(), }; -// 046C const BehaviorScript bhvSmallParticleBubbles[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_particle_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_particle_init), BEGIN_REPEAT(70), - CALLNATIVE(bhv_small_bubbles_loop), + CALL_NATIVE(bhv_small_bubbles_loop), END_REPEAT(), DEACTIVATE(), }; -// 0494 const BehaviorScript bhvFishGroup[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_fish_group_loop), + CALL_NATIVE(bhv_fish_group_loop), END_LOOP(), }; -// 04A8 const BehaviorScript bhvCannon[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_CHILD(MODEL_CANNON_BARREL, bhvCannonBarrel), - OBJ_SET_INT(oInteractType, INTERACT_CANNON_BASE), - OBJ_ADD_FLOAT(oPosY, -340), - OBJ_SET_POS(), - SET_HITBOX(0x0096, 0x0096), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SPAWN_CHILD(/*Model*/ MODEL_CANNON_BARREL, /*Behavior*/ bhvCannonBarrel), + SET_INT(oInteractType, INTERACT_CANNON_BASE), + ADD_FLOAT(oPosY, -340), + SET_HOME(), + SET_HITBOX(/*Radius*/ 150, /*Height*/ 150), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_cannon_base_loop), + CALL_NATIVE(bhv_cannon_base_loop), END_LOOP(), }; -// 04E4 const BehaviorScript bhvCannonBarrel[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), BEGIN_LOOP(), - CALLNATIVE(bhv_cannon_barrel_loop), + CALL_NATIVE(bhv_cannon_barrel_loop), END_LOOP(), }; -// 0500 const BehaviorScript bhvCannonBaseUnused[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_REPEAT(8), - CALLNATIVE(bhv_cannon_base_unused_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_cannon_base_unused_loop), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 0528 const BehaviorScript bhvChuckya[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, chuckya_seg8_anims_0800C070), - ANIMATE(0x05), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - SET_HITBOX(0x0096, 0x0064), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SPAWN(MODEL_NONE, bhvChuckyaAnchorMario), - OBJ_SET_INT(oNumLootCoins, 5), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, chuckya_seg8_anims_0800C070), + ANIMATE(5), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_HITBOX(/*Radius*/ 150, /*Height*/ 100), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvChuckyaAnchorMario), + SET_INT(oNumLootCoins, 5), + SET_INT(oIntangibleTimer, 0), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_chuckya_loop), + CALL_NATIVE(bhv_chuckya_loop), END_LOOP(), }; -// 0584 const BehaviorScript bhvChuckyaAnchorMario[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_FLOAT(oParentRelativePosY, 0xFFC4), - OBJ_SET_FLOAT(oParentRelativePosZ, 0x0096), + SET_FLOAT(oParentRelativePosY, -60), + SET_FLOAT(oParentRelativePosZ, 150), BEGIN_LOOP(), - CALLNATIVE(bhv_chuckya_anchor_mario_loop), + CALL_NATIVE(bhv_chuckya_anchor_mario_loop), END_LOOP(), }; -// 05A8 const BehaviorScript bhvUnused05A8[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BREAK(), }; -// 05B4 const BehaviorScript bhvRotatingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_rotating_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_rotating_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 05D8 const BehaviorScript bhvTower[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(wf_seg7_collision_tower), - OBJ_SET_FLOAT(oCollisionDistance, 0x0BB8), - OBJ_SET_FLOAT(oDrawingDistance, 0x4E20), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(wf_seg7_collision_tower), + SET_FLOAT(oCollisionDistance, 3000), + SET_FLOAT(oDrawingDistance, 20000), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0600 const BehaviorScript bhvBulletBillCannon[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(wf_seg7_collision_bullet_bill_cannon), - OBJ_SET_FLOAT(oCollisionDistance, 0x012C), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(wf_seg7_collision_bullet_bill_cannon), + SET_FLOAT(oCollisionDistance, 300), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0624 const BehaviorScript bhvWfBreakableWallRight[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(wf_seg7_collision_breakable_wall), + LOAD_COLLISION_DATA(wf_seg7_collision_breakable_wall), GOTO(bhvWfBreakableWallLeft + 1 + 2), }; -// 0638 const BehaviorScript bhvWfBreakableWallLeft[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(wf_seg7_collision_breakable_wall_2), - // .L13000644: - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - SET_HITBOX(0x012C, 0x0190), - OBJ_SET_INT(oIntangibleTimer, 0), + LOAD_COLLISION_DATA(wf_seg7_collision_breakable_wall_2), + // WF breakable walls - common: + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HITBOX(/*Radius*/ 300, /*Height*/ 400), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_breakable_wall_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_breakable_wall_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 066C const BehaviorScript bhvKickableBoard[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_kickable_board), - SET_HITBOX(0x0064, 0x04B0), - OBJ_SET_FLOAT2(0x0001, 0x0001), - OBJ_SET_FLOAT(oCollisionDistance, 0x05DC), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_kickable_board), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 1200), + SET_HURTBOX(/*Radius*/ 1, /*Height*/ 1), + SET_FLOAT(oCollisionDistance, 1500), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_kickable_board_loop), + CALL_NATIVE(bhv_kickable_board_loop), END_LOOP(), }; -// 06A4 const BehaviorScript bhvTowerDoor[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_tower_door), - SET_HITBOX(0x0064, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_tower_door), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_tower_door_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_tower_door_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 06D8 const BehaviorScript bhvRotatingCounterClockwise[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 06E0 const BehaviorScript bhvWfRotatingWoodenPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(wf_seg7_collision_clocklike_rotation), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(wf_seg7_collision_clocklike_rotation), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_rotating_wooden_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_rotating_wooden_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0708 const BehaviorScript bhvKoopaShellUnderwater[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_koopa_shell_underwater_loop), + CALL_NATIVE(bhv_koopa_shell_underwater_loop), END_LOOP(), }; -// 0720 const BehaviorScript bhvExitPodiumWarp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_WARP), - DROP_FLOOR(), - OBJ_SET_FLOAT(oCollisionDistance, 0x1F40), - COLLISION_DATA(ttm_seg7_collision_podium_warp), - OBJ_SET_INT(oIntangibleTimer, 0), - SET_HITBOX(0x0032, 0x0032), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_WARP), + DROP_TO_FLOOR(), + SET_FLOAT(oCollisionDistance, 8000), + LOAD_COLLISION_DATA(ttm_seg7_collision_podium_warp), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX(/*Radius*/ 50, /*Height*/ 50), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), - OBJ_SET_INT(oInteractStatus, 0), + CALL_NATIVE(load_object_collision_model), + SET_INT(oInteractStatus, 0), END_LOOP(), }; -// 075C const BehaviorScript bhvFadingWarp[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_FADING_WARP), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_WARP), - OBJ_SET_INT(oIntangibleTimer, 0), + SET_INT(oInteractionSubtype, INT_SUBTYPE_FADING_WARP), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_WARP), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(BehFadingWarpLoop), + CALL_NATIVE(BehFadingWarpLoop), END_LOOP(), }; -// 0780 const BehaviorScript bhvWarp[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_WARP), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_WARP), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_warp_loop), + CALL_NATIVE(bhv_warp_loop), END_LOOP(), }; -// 07A0 const BehaviorScript bhvWarpPipe[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_WARP), - COLLISION_DATA(warp_pipe_seg3_collision_03009AC8), - OBJ_SET_FLOAT(oDrawingDistance, 0x3E80), - OBJ_SET_INT(oIntangibleTimer, 0), - SET_HITBOX(0x0046, 0x0032), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_WARP), + LOAD_COLLISION_DATA(warp_pipe_seg3_collision_03009AC8), + SET_FLOAT(oDrawingDistance, 16000), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX(/*Radius*/ 70, /*Height*/ 50), BEGIN_LOOP(), - CALLNATIVE(bhv_warp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_warp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 07DC const BehaviorScript bhvWhitePuffExplosion[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_white_puff_exploding_loop), + CALL_NATIVE(bhv_white_puff_exploding_loop), END_LOOP(), }; -// 07F8 const BehaviorScript bhvSpawnedStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oBehParams2ndByte, 1), - GOTO(bhvUnused080C + 1 + 1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oBehParams2ndByte, 1), + GOTO(bhvSpawnedStarNoLevelExit + 1 + 1), }; -// 080C -const BehaviorScript bhvUnused080C[] = { +const BehaviorScript bhvSpawnedStarNoLevelExit[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - // .L13000814: - OBJ_SET_POS(), - CALLNATIVE(bhv_unused_080c_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + // Spawned star - common: + SET_HOME(), + CALL_NATIVE(bhv_spawned_star_init), BEGIN_LOOP(), - CALLNATIVE(bhv_unused_080c_loop), + CALL_NATIVE(bhv_spawned_star_loop), END_LOOP(), }; -// 0830 const BehaviorScript bhvMrIBlueCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_SET_INT(oInteractType, INTERACT_COIN), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oInteractType, INTERACT_COIN), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_FLOAT(oMrIUnk110, 0x0014), - OBJ_SET_INT(oAnimState, -1), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_coin_init), - OBJ_SET_INT(oDamageOrCoinValue, 0x0005), - SET_HITBOX(0x0078, 0x0040), + SET_INT(oIntangibleTimer, 0), + SET_FLOAT(oMrIUnk110, 20), + SET_INT(oAnimState, -1), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_coin_init), + SET_INT(oDamageOrCoinValue, 5), + SET_HITBOX(/*Radius*/ 120, /*Height*/ 64), BEGIN_LOOP(), - CALLNATIVE(bhv_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 0888 const BehaviorScript bhvCoinInsideBoo[] = { BEGIN(OBJ_LIST_LEVEL), - SET_HITBOX(0x0064, 0x0040), - OBJ_SET_INT(oInteractType, INTERACT_COIN), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 64), + SET_INT(oInteractType, INTERACT_COIN), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BILLBOARD(), - CALLNATIVE(bhv_init_room), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_coin_inside_boo_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_coin_inside_boo_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 08D0 const BehaviorScript bhvCoinFormationSpawn[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_coin_formation_spawn_loop), + CALL_NATIVE(bhv_coin_formation_spawn_loop), END_LOOP(), }; -// 08EC const BehaviorScript bhvCoinFormation[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_coin_formation_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_coin_formation_init), BEGIN_LOOP(), - CALLNATIVE(bhv_coin_formation_loop), + CALL_NATIVE(bhv_coin_formation_loop), END_LOOP(), }; -// 090C const BehaviorScript bhvOneCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_SET_INT(oBehParams2ndByte, 1), + SET_INT(oBehParams2ndByte, 1), GOTO(bhvYellowCoin + 1), }; -// 091C const BehaviorScript bhvYellowCoin[] = { BEGIN(OBJ_LIST_LEVEL), - // .L13000920: + // Yellow coin - common: BILLBOARD(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_yellow_coin_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_yellow_coin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_yellow_coin_loop), + CALL_NATIVE(bhv_yellow_coin_loop), END_LOOP(), }; -// 0940 const BehaviorScript bhvTemporaryYellowCoin[] = { BEGIN(OBJ_LIST_LEVEL), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_yellow_coin_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_yellow_coin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_temp_coin_loop), + CALL_NATIVE(bhv_temp_coin_loop), END_LOOP(), }; -// 0964 const BehaviorScript bhvThreeCoinsSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(3), - OBJ_CHILD(MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned), + SPAWN_CHILD(/*Model*/ MODEL_YELLOW_COIN, /*Behavior*/ bhvSingleCoinGetsSpawned), END_REPEAT(), DEACTIVATE(), }; -// 0984 const BehaviorScript bhvTenCoinsSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(10), - OBJ_CHILD(MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned), + SPAWN_CHILD(/*Model*/ MODEL_YELLOW_COIN, /*Behavior*/ bhvSingleCoinGetsSpawned), END_REPEAT(), DEACTIVATE(), }; -// 09A4 const BehaviorScript bhvSingleCoinGetsSpawned[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - CALLNATIVE(bhv_coin_init), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + CALL_NATIVE(bhv_coin_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 09E0 const BehaviorScript bhvCoinSparkles[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 25), - OBJ_SET_INT(oAnimState, -1), + SET_FLOAT(oGraphYOffset, 25), + SET_INT(oAnimState, -1), BEGIN_REPEAT(8), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), BEGIN_REPEAT(2), - CALLNATIVE(bhv_coin_sparkles_loop), + CALL_NATIVE(bhv_coin_sparkles_loop), END_REPEAT(), DEACTIVATE(), }; -// 0A14 const BehaviorScript bhvGoldenCoinSparkles[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GRAPH_CLEAR(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), BEGIN_REPEAT(3), - CALLNATIVE(bhv_golden_coin_sparkles_loop), + CALL_NATIVE(bhv_golden_coin_sparkles_loop), END_REPEAT(), DEACTIVATE(), }; -// 0A34 const BehaviorScript bhvWallTinyStarParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_REPEAT(10), - CALLNATIVE(bhv_wall_tiny_star_particle_loop), + CALL_NATIVE(bhv_wall_tiny_star_particle_loop), END_REPEAT(), DEACTIVATE(), }; -// 0A54 const BehaviorScript bhvWallTinyStarParticleSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00040000), - CALLNATIVE(bhv_tiny_star_particles_init), + DISABLE_RENDERING(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_18), + CALL_NATIVE(bhv_tiny_star_particles_init), DELAY(1), DEACTIVATE(), }; -// 0A78 const BehaviorScript bhvPoundTinyStarParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_REPEAT(10), - CALLNATIVE(bhv_pound_tiny_star_particle_loop), + CALL_NATIVE(bhv_pound_tiny_star_particle_loop), END_REPEAT(), DEACTIVATE(), }; -// 0A98 const BehaviorScript bhvPoundTinyStarParticleSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000010), - CALLNATIVE(bhv_pound_tiny_star_particle_init), + DISABLE_RENDERING(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_4), + CALL_NATIVE(bhv_pound_tiny_star_particle_init), DELAY(1), DEACTIVATE(), }; -// 0ABC const BehaviorScript bhvPunchTinyTriangle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_punch_tiny_triangle_loop), + CALL_NATIVE(bhv_punch_tiny_triangle_loop), END_LOOP(), }; -// 0AD8 const BehaviorScript bhvPunchTinyTriangleSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00080000), - CALLNATIVE(bhv_punch_tiny_triangle_init), + DISABLE_RENDERING(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_19), + CALL_NATIVE(bhv_punch_tiny_triangle_init), DELAY(1), DEACTIVATE(), }; -// 0AFC const BehaviorScript bhvDoorWarp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oInteractType, INTERACT_WARP_DOOR), + SET_INT(oInteractType, INTERACT_WARP_DOOR), GOTO(bhvDoor + 1 + 1), }; -// 0B0C const BehaviorScript bhvDoor[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oInteractType, INTERACT_DOOR), - // .L13000B14: - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, door_seg3_anims_030156C0), - ANIMATE(0x00), - COLLISION_DATA(door_seg3_collision_0301CE78), - SET_HITBOX(0x0050, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_FLOAT(oCollisionDistance, 0x03E8), - OBJ_SET_POS(), - CALLNATIVE(bhv_door_init), + SET_INT(oInteractType, INTERACT_DOOR), + // Door - common: + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, door_seg3_anims_030156C0), + ANIMATE(0), + LOAD_COLLISION_DATA(door_seg3_collision_0301CE78), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), + SET_FLOAT(oCollisionDistance, 1000), + SET_HOME(), + CALL_NATIVE(bhv_door_init), BEGIN_LOOP(), - CALLNATIVE(bhv_door_loop), + CALL_NATIVE(bhv_door_loop), END_LOOP(), }; -// 0B58 const BehaviorScript bhvGrindel[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(ssl_seg7_collision_grindel), - DROP_FLOOR(), - OBJ_ADD_FLOAT(oPosY, 1), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(ssl_seg7_collision_grindel), + DROP_TO_FLOOR(), + ADD_FLOAT(oPosY, 1), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_grindel_thwomp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_grindel_thwomp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0B8C const BehaviorScript bhvThwomp2[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(thwomp_seg5_collision_0500B92C), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_ADD_FLOAT(oPosY, 1), - OBJ_SET_POS(), + LOAD_COLLISION_DATA(thwomp_seg5_collision_0500B92C), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + ADD_FLOAT(oPosY, 1), + SET_HOME(), SCALE(140), - OBJ_SET_FLOAT(oDrawingDistance, 0x0FA0), + SET_FLOAT(oDrawingDistance, 4000), BEGIN_LOOP(), - CALLNATIVE(bhv_grindel_thwomp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_grindel_thwomp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0BC8 const BehaviorScript bhvThwomp[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(thwomp_seg5_collision_0500B7D0), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_ADD_FLOAT(oPosY, 1), + LOAD_COLLISION_DATA(thwomp_seg5_collision_0500B7D0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + ADD_FLOAT(oPosY, 1), SCALE(140), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oDrawingDistance, 0x0FA0), + SET_HOME(), + SET_FLOAT(oDrawingDistance, 4000), BEGIN_LOOP(), - CALLNATIVE(bhv_grindel_thwomp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_grindel_thwomp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0C04 const BehaviorScript bhvTumblingBridgePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oCollisionDistance, 0x012C), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oCollisionDistance, 300), BEGIN_LOOP(), - CALLNATIVE(bhv_tumbling_bridge_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_tumbling_bridge_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0C28 const BehaviorScript bhvWfTumblingBridge[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_tumbling_bridge_loop), + CALL_NATIVE(bhv_tumbling_bridge_loop), END_LOOP(), }; -// 0C44 const BehaviorScript bhvBbhTumblingBridge[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_INT(oBehParams2ndByte, 1), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_INT(oBehParams2ndByte, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_tumbling_bridge_loop), + CALL_NATIVE(bhv_tumbling_bridge_loop), END_LOOP(), }; -// 0C64 const BehaviorScript bhvLllTumblingBridge[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_INT(oBehParams2ndByte, 2), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_INT(oBehParams2ndByte, 2), BEGIN_LOOP(), - CALLNATIVE(bhv_tumbling_bridge_loop), + CALL_NATIVE(bhv_tumbling_bridge_loop), END_LOOP(), }; -// 0C84 const BehaviorScript bhvFlame[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_POS(), + SET_HOME(), SCALE(700), - INTERACT_TYPE(INTERACT_FLAME), - COLLISION_SPHERE(0x0032, 0x0019, 0x0019), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_init_room), + SET_INTERACT_TYPE(INTERACT_FLAME), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 50, /*Height*/ 25, /*Downwards offset*/ 25), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - OBJ_SET_INT(oInteractStatus, 0), - TEXT_ANIM_RATE(oAnimState, 0x0002), + SET_INT(oInteractStatus, 0), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 0CC8 const BehaviorScript bhvAnotherElavator[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(hmc_seg7_collision_elevator), - OBJ_SET_POS(), - CALLNATIVE(bhv_elevator_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(hmc_seg7_collision_elevator), + SET_HOME(), + CALL_NATIVE(bhv_elevator_init), BEGIN_LOOP(), - CALLNATIVE(bhv_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0CFC const BehaviorScript bhvRrElevatorPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(rr_seg7_collision_elevator_platform), - OBJ_SET_POS(), - CALLNATIVE(bhv_elevator_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(rr_seg7_collision_elevator_platform), + SET_HOME(), + CALL_NATIVE(bhv_elevator_init), BEGIN_LOOP(), - CALLNATIVE(bhv_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0D30 const BehaviorScript bhvHmcElevatorPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(hmc_seg7_collision_elevator), - OBJ_SET_POS(), - CALLNATIVE(bhv_elevator_init), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(hmc_seg7_collision_elevator), + SET_HOME(), + CALL_NATIVE(bhv_elevator_init), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0D6C const BehaviorScript bhvWaterMist[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oOpacity, 0xFE), - OBJ_SET_FLOAT(oForwardVel, 0x0014), - OBJ_SET_FLOAT(oVelY, 0xFFF8), - OBJ_ADD_FLOAT(oPosY, 62), + SET_INT(oOpacity, 254), + SET_FLOAT(oForwardVel, 20), + SET_FLOAT(oVelY, -8), + ADD_FLOAT(oPosY, 62), BEGIN_LOOP(), - CALLNATIVE(bhv_water_mist_loop), + CALL_NATIVE(bhv_water_mist_loop), END_LOOP(), }; -// 0D98 const BehaviorScript bhvWaterMistSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(8), - CALLNATIVE(bhv_water_mist_spawn_loop), + CALL_NATIVE(bhv_water_mist_spawn_loop), END_REPEAT(), DEACTIVATE(), }; -// 0DB4 const BehaviorScript bhvBreakBoxTriangle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(18), - CALLNATIVE(obj_rotate_face_angle_using_vel), - CALLNATIVE(obj_move_using_fvel_and_gravity), + CALL_NATIVE(obj_rotate_face_angle_using_vel), + CALL_NATIVE(obj_move_using_fvel_and_gravity), END_REPEAT(), DEACTIVATE(), }; -// 0DD8 const BehaviorScript bhvWaterMist2[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_INT(oFaceAnglePitch, 0xC000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_INT(oFaceAnglePitch, 0xC000), SCALE(2100), BEGIN_LOOP(), - CALLNATIVE(bhv_water_mist_2_loop), + CALL_NATIVE(bhv_water_mist_2_loop), END_LOOP(), }; -// 0DFC const BehaviorScript bhvUnused0DFC[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oAnimState, -1), - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oAnimState, -1), + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), BEGIN_REPEAT(6), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 0E24 const BehaviorScript bhvPoundWhitePuffs[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_pound_white_puffs_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_pound_white_puffs_init), DELAY(1), DEACTIVATE(), }; -// 0E3C const BehaviorScript bhvGroundSand[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_unused_0e40_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_unused_0e40_init), DELAY(1), DEACTIVATE(), }; -// 0E58 const BehaviorScript bhvGroundSnow[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_ground_snow_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_ground_snow_init), DELAY(1), DEACTIVATE(), }; -// 0E70 const BehaviorScript bhvWind[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_wind_loop), + CALL_NATIVE(bhv_wind_loop), END_LOOP(), }; -// 0E88 const BehaviorScript bhvEndToad[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, toad_seg6_anims_0600FB58), - ANIMATE(0x00), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, toad_seg6_anims_0600FB58), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(BehEndToadLoop), + CALL_NATIVE(BehEndToadLoop), END_LOOP(), }; -// 0EAC const BehaviorScript bhvEndPeach[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, peach_seg5_anims_0501C41C), - ANIMATE(0x00), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, peach_seg5_anims_0501C41C), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(BehEndPeachLoop), + CALL_NATIVE(BehEndPeachLoop), END_LOOP(), }; -// 0ED0 const BehaviorScript bhvUnusedParticleSpawn[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_INT(oIntangibleTimer, 0), - SET_HITBOX(0x0028, 0x0028), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX(/*Radius*/ 40, /*Height*/ 40), BEGIN_LOOP(), - CALLNATIVE(bhv_unused_particle_spawn_loop), + CALL_NATIVE(bhv_unused_particle_spawn_loop), END_LOOP(), }; -// 0F08 const BehaviorScript bhvUkiki[] = { BEGIN(OBJ_LIST_GENACTOR), GOTO(bhvMacroUkiki + 1), }; -// 0F14 const BehaviorScript bhvUkikiCageChild[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oPosX, 0x0A00), - OBJ_SET_FLOAT(oPosY, 0x05B1), - OBJ_SET_FLOAT(oPosZ, 0x076A), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oPosX, 2560), + SET_FLOAT(oPosY, 1457), + SET_FLOAT(oPosZ, 1898), BREAK(), }; -// 0F2C const BehaviorScript bhvUkikiCageStar[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_ukiki_cage_star_loop), + CALL_NATIVE(bhv_ukiki_cage_star_loop), END_LOOP(), }; -// 0F48 const BehaviorScript bhvUkikiCage[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - COLLISION_DATA(ttm_seg7_collision_ukiki_cage), - OBJ_CHILD(MODEL_STAR, bhvUkikiCageStar), - OBJ_CHILD(MODEL_NONE, bhvUkikiCageChild), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + LOAD_COLLISION_DATA(ttm_seg7_collision_ukiki_cage), + SPAWN_CHILD(/*Model*/ MODEL_STAR, /*Behavior*/ bhvUkikiCageStar), + SPAWN_CHILD(/*Model*/ MODEL_NONE, /*Behavior*/ bhvUkikiCageChild), + SET_FLOAT(oCollisionDistance, 20000), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_ukiki_cage_loop), + CALL_NATIVE(bhv_ukiki_cage_loop), END_LOOP(), }; -// 0F9C const BehaviorScript bhvBitfsSinkingPlatforms[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bitfs_seg7_collision_sinking_platform), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bitfs_seg7_collision_sinking_platform), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_bitfs_sinking_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_bitfs_sinking_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 0FC8 const BehaviorScript bhvBitfsSinkingCagePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bitfs_seg7_collision_sinking_cage_platform), - OBJ_SET_POS(), - OBJ_CHILD(MODEL_BITFS_BLUE_POLE, bhvDddMovingPole), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bitfs_seg7_collision_sinking_cage_platform), + SET_HOME(), + SPAWN_CHILD(/*Model*/ MODEL_BITFS_BLUE_POLE, /*Behavior*/ bhvDddMovingPole), BEGIN_LOOP(), - CALLNATIVE(bhv_bitfs_sinking_cage_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_bitfs_sinking_cage_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1000 const BehaviorScript bhvDddMovingPole[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oInteractType, INTERACT_POLE), - SET_HITBOX(0x0050, 0x02C6), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oInteractType, INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 710), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_ddd_moving_pole_loop), - CALLNATIVE(BehClimbDetectLoop), + CALL_NATIVE(bhv_ddd_moving_pole_loop), + CALL_NATIVE(BehClimbDetectLoop), END_LOOP(), }; -// 1030 const BehaviorScript bhvBitfsTiltingInvertedPyramid[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(bitfs_seg7_collision_inverted_pyramid), - OBJ_SET_POS(), - CALLNATIVE(bhv_platform_normals_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(bitfs_seg7_collision_inverted_pyramid), + SET_HOME(), + CALL_NATIVE(bhv_platform_normals_init), BEGIN_LOOP(), - CALLNATIVE(bhv_tilting_inverted_pyramid_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_tilting_inverted_pyramid_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1064 const BehaviorScript bhvSquishablePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(bitfs_seg7_collision_squishable_platform), - OBJ_SET_FLOAT(oCollisionDistance, 0x2710), - CALLNATIVE(bhv_platform_normals_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(bitfs_seg7_collision_squishable_platform), + SET_FLOAT(oCollisionDistance, 10000), + CALL_NATIVE(bhv_platform_normals_init), BEGIN_LOOP(), - CALLNATIVE(bhv_squishable_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_squishable_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1098 const BehaviorScript bhvCutOutObject[] = { BEGIN(OBJ_LIST_GENACTOR), - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BREAK(), }; -// 10A8 const BehaviorScript bhvBetaMovingFlamesSpawn[] = { BEGIN_LOOP(), - CALLNATIVE(bhv_beta_moving_flames_spawn_loop), + CALL_NATIVE(bhv_beta_moving_flames_spawn_loop), END_LOOP(), }; -// 10B8 const BehaviorScript bhvBetaMovingFlames[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_moving_flames_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_beta_moving_flames_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 10D8 const BehaviorScript bhvRrRotatingBridgePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(rr_seg7_collision_rotating_platform_with_fire), - OBJ_SET_FLOAT(oCollisionDistance, 0x05DC), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(rr_seg7_collision_rotating_platform_with_fire), + SET_FLOAT(oCollisionDistance, 1500), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_rr_rotating_bridge_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_rr_rotating_bridge_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1108 const BehaviorScript bhvFlamethrower[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_flamethrower_loop), + CALL_NATIVE(bhv_flamethrower_loop), END_LOOP(), }; -// 1124 const BehaviorScript bhvFlamethrowerFlame[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), - COLLISION_SPHERE(0x0032, 0x0019, 0x0019), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 50, /*Height*/ 25, /*Downwards offset*/ 25), BILLBOARD(), - OBJ_SET_POS(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_init_room), + SET_HOME(), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_flamethrower_flame_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_flamethrower_flame_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 1168 const BehaviorScript bhvBouncingFireball[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - GRAPH_CLEAR(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DISABLE_RENDERING(), BEGIN_LOOP(), - CALLNATIVE(bhv_bouncing_fireball_loop), + CALL_NATIVE(bhv_bouncing_fireball_loop), END_LOOP(), }; -// 1184 const BehaviorScript bhvBouncingFireballFlame[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), - OBJ_SET_FLOAT(oGraphYOffset, 30), - COLLISION_SPHERE(0x0032, 0x0019, 0x0019), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), + SET_FLOAT(oGraphYOffset, 30), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 50, /*Height*/ 25, /*Downwards offset*/ 25), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_bouncing_fireball_flame_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_bouncing_fireball_flame_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 11D0 const BehaviorScript bhvBowserShockWave[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oOpacity, 0x00FF), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oOpacity, 255), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_shock_wave_loop), + CALL_NATIVE(bhv_bowser_shock_wave_loop), END_LOOP(), }; -// 11EC const BehaviorScript bhvFlameMario[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 0x0046), - OBJ_SET_INT(oAnimState, -1), + SET_FLOAT(oGraphYOffset, 70), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_flame_mario_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_flame_mario_loop), END_LOOP(), }; -// 1214 const BehaviorScript bhvBlackSmokeMario[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oAnimState, 0x0004), - OBJ_SET_FLOAT(oGraphYOffset, 0x0032), + SET_INT(oAnimState, 4), + SET_FLOAT(oGraphYOffset, 50), BEGIN_REPEAT(8), - CALLNATIVE(bhv_black_smoke_mario_loop), + CALL_NATIVE(bhv_black_smoke_mario_loop), DELAY(1), - CALLNATIVE(bhv_black_smoke_mario_loop), + CALL_NATIVE(bhv_black_smoke_mario_loop), DELAY(1), - CALLNATIVE(bhv_black_smoke_mario_loop), + CALL_NATIVE(bhv_black_smoke_mario_loop), END_REPEAT(), DEACTIVATE(), }; -// 1254 const BehaviorScript bhvBlackSmokeBowser[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 0x0000), + SET_FLOAT(oGraphYOffset, 0), BEGIN_REPEAT(8), - CALLNATIVE(bhv_black_smoke_bowser_loop), - TEXT_ANIM_RATE(oAnimState, 0x0004), + CALL_NATIVE(bhv_black_smoke_bowser_loop), + TEX_ANIM_RATE(oAnimState, 4), END_REPEAT(), DEACTIVATE(), }; -// 127C const BehaviorScript bhvBlackSmokeUpward[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_REPEAT(4), - CALLNATIVE(bhv_black_smoke_upward_loop), + CALL_NATIVE(bhv_black_smoke_upward_loop), END_REPEAT(), DEACTIVATE(), }; -// 1298 const BehaviorScript bhvBetaFishSplashSpawner[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - GRAPH_CLEAR(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DISABLE_RENDERING(), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_fish_splash_spawner_loop), + CALL_NATIVE(bhv_beta_fish_splash_spawner_loop), END_LOOP(), }; -// 12B4 const BehaviorScript bhvSpindrift[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, spindrift_seg5_anims_05002D68), - ANIMATE(0x00), - OBJ_PHYSICS(0x001E, 0xFE70, 0x0000, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_TWIRL_BOUNCE), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, spindrift_seg5_anims_05002D68), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + SET_INT(oInteractionSubtype, INT_SUBTYPE_TWIRL_BOUNCE), BEGIN_LOOP(), - CALLNATIVE(bhv_spindrift_loop), + CALL_NATIVE(bhv_spindrift_loop), END_LOOP(), }; -// 12F4 const BehaviorScript bhvTowerPlatformGroup[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GRAPH_CLEAR(), - OBJ_ADD_FLOAT(oPosY, 300), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), + ADD_FLOAT(oPosY, 300), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_tower_platform_group_loop), + CALL_NATIVE(bhv_tower_platform_group_loop), END_LOOP(), }; -// 1318 const BehaviorScript bhvWfSlidingTowerPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_platform), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_platform), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_sliding_tower_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_sliding_tower_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1340 const BehaviorScript bhvWfElevatorTowerPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_platform), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_platform), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_elevator_tower_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_elevator_tower_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1368 const BehaviorScript bhvWfSolidTowerPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_platform), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_platform), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_solid_tower_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_solid_tower_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1390 const BehaviorScript bhvSnowLeafParticleSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_snow_leaf_particle_spawn_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_snow_leaf_particle_spawn_init), DELAY(1), DEACTIVATE(), }; -// 13A8 const BehaviorScript bhvTreeSnow[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_tree_snow_or_leaf_loop), + CALL_NATIVE(bhv_tree_snow_or_leaf_loop), END_LOOP(), }; -// 13C4 const BehaviorScript bhvTreeLeaf[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_tree_snow_or_leaf_loop), + CALL_NATIVE(bhv_tree_snow_or_leaf_loop), END_LOOP(), }; -// 13DC const BehaviorScript bhvAnotherTiltingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - CALLNATIVE(bhv_platform_normals_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + CALL_NATIVE(bhv_platform_normals_init), BEGIN_LOOP(), - CALLNATIVE(bhv_tilting_inverted_pyramid_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_tilting_inverted_pyramid_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1408 const BehaviorScript bhvSquarishPathMoving[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bitdw_seg7_collision_moving_pyramid), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bitdw_seg7_collision_moving_pyramid), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_squarish_path_moving_loop), + CALL_NATIVE(bhv_squarish_path_moving_loop), END_LOOP(), }; -// 142C const BehaviorScript bhvPiranhaPlantBubble[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_piranha_plant_bubble_loop), + CALL_NATIVE(bhv_piranha_plant_bubble_loop), END_LOOP(), }; -// 1448 const BehaviorScript bhvPiranhaPlantWakingBubbles[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_REPEAT(10), - CALLNATIVE(bhv_piranha_plant_waking_bubbles_loop), + CALL_NATIVE(bhv_piranha_plant_waking_bubbles_loop), END_REPEAT(), DEACTIVATE(), }; -// 1468 const BehaviorScript bhvFloorSwitchAnimatesObject[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oBehParams2ndByte, 1), + SET_INT(oBehParams2ndByte, 1), GOTO(bhvFloorSwitchHardcodedModel + 1), }; -// 1478 const BehaviorScript bhvFloorSwitchGrills[] = { BEGIN(OBJ_LIST_SURFACE), GOTO(bhvFloorSwitchHardcodedModel + 1), }; -// 1484 const BehaviorScript bhvFloorSwitchHardcodedModel[] = { BEGIN(OBJ_LIST_SURFACE), - // .Lbeh_floor_switch_1488: # 1488 - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(purple_switch_seg8_collision_0800C7A8), + // Floor switch - common: + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(purple_switch_seg8_collision_0800C7A8), BEGIN_LOOP(), - CALLNATIVE(bhv_purple_switch_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_purple_switch_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 14AC const BehaviorScript bhvFloorSwitchHiddenObjects[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oBehParams2ndByte, 2), + SET_INT(oBehParams2ndByte, 2), GOTO(bhvFloorSwitchHardcodedModel + 1), }; -// 14BC const BehaviorScript bhvHiddenObject[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(breakable_box_seg8_collision_08012D70), - OBJ_SET_FLOAT(oCollisionDistance, 0x012C), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(breakable_box_seg8_collision_08012D70), + SET_FLOAT(oCollisionDistance, 300), BEGIN_LOOP(), - CALLNATIVE(bhv_hidden_object_loop), + CALL_NATIVE(bhv_hidden_object_loop), END_LOOP(), }; -// 14E0 const BehaviorScript bhvBreakableBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(breakable_box_seg8_collision_08012D70), - OBJ_SET_FLOAT(oCollisionDistance, 0x01F4), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(breakable_box_seg8_collision_08012D70), + SET_FLOAT(oCollisionDistance, 500), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_breakable_box_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_breakable_box_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), BREAK(), }; -// 1518 const BehaviorScript bhvPushableMetalBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(metal_box_seg8_collision_08024C28), - OBJ_SET_FLOAT(oCollisionDistance, 0x01F4), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(metal_box_seg8_collision_08024C28), + SET_FLOAT(oCollisionDistance, 500), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_pushable_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_pushable_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1548 const BehaviorScript bhvHeaveHo[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, heave_ho_seg5_anims_0501534C), - ANIMATE(0x00), - OBJ_PHYSICS(0x00C8, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x0258, 0x0000, 0x0000), - OBJ_SPAWN(MODEL_NONE, bhvHeaveHoThrowMario), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_NOT_GRABBABLE | INT_SUBTYPE_GRABS_MARIO), - SET_HITBOX(0x0078, 0x0064), - OBJ_SET_POS(), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, heave_ho_seg5_anims_0501534C), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 200, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 600, /*Unused*/ 0, 0), + SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvHeaveHoThrowMario), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_INT(oInteractionSubtype, INT_SUBTYPE_NOT_GRABBABLE | INT_SUBTYPE_GRABS_MARIO), + SET_HITBOX(/*Radius*/ 120, /*Height*/ 100), + SET_HOME(), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_heave_ho_loop), + CALL_NATIVE(bhv_heave_ho_loop), END_LOOP(), }; -// 15A4 const BehaviorScript bhvHeaveHoThrowMario[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_heave_ho_throw_mario_loop), + CALL_NATIVE(bhv_heave_ho_throw_mario_loop), END_LOOP(), }; -// 15C0 const BehaviorScript bhvCcmTouchedStarSpawn[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - SET_HITBOX(0x01F4, 0x01F4), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HITBOX(/*Radius*/ 500, /*Height*/ 500), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_ccm_touched_star_spawn_loop), + CALL_NATIVE(bhv_ccm_touched_star_spawn_loop), END_LOOP(), }; -// 15E4 const BehaviorScript bhvUnusedPoundablePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(sl_seg7_collision_pound_explodes), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(sl_seg7_collision_pound_explodes), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_unused_poundable_platform), + CALL_NATIVE(bhv_unused_poundable_platform), END_LOOP(), }; -// 1608 const BehaviorScript bhvBetaTrampolineTop[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(springboard_collision_05001A28), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(springboard_collision_05001A28), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_trampoline_top_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_beta_trampoline_top_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1634 const BehaviorScript bhvBetaTrampolineSpring[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_trampoline_spring_loop), + CALL_NATIVE(bhv_beta_trampoline_spring_loop), END_LOOP(), }; -// 1650 const BehaviorScript bhvJumpingBox[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x0258, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 600, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_jumping_box_loop), + CALL_NATIVE(bhv_jumping_box_loop), END_LOOP(), }; -// 167C const BehaviorScript bhvBooCage[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oGraphYOffset, 0x000A), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oGraphYOffset, 10), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_boo_cage_loop), + CALL_NATIVE(bhv_boo_cage_loop), END_LOOP(), }; -// 16AC const BehaviorScript bhvStub[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), + DISABLE_RENDERING(), BREAK(), }; -// 16B8 const BehaviorScript bhvIgloo[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_IGLOO_BARRIER), - SET_HITBOX(0x0064, 0x00C8), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_IGLOO_BARRIER), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 200), + SET_INT(oIntangibleTimer, 0), + SET_HOME(), BEGIN_LOOP(), - OBJ_SET_INT(oInteractStatus, 0), + SET_INT(oInteractStatus, 0), END_LOOP(), }; -// 16E4 const BehaviorScript bhvBowserKey[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_key_loop), + CALL_NATIVE(bhv_bowser_key_loop), END_LOOP(), }; -// 1714 const BehaviorScript bhvGrandStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_STAR_OR_KEY), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_GRAND_STAR), - SET_HITBOX(0x00A0, 0x0064), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_STAR_OR_KEY), + SET_INT(oInteractionSubtype, INT_SUBTYPE_GRAND_STAR), + SET_HITBOX(/*Radius*/ 160, /*Height*/ 100), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_grand_star_loop), + CALL_NATIVE(bhv_grand_star_loop), END_LOOP(), }; -// 1744 const BehaviorScript bhvBetaBooKey[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0020, 0x0040), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 32, /*Height*/ 64), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_beta_boo_key_loop), + CALL_NATIVE(bhv_beta_boo_key_loop), END_LOOP(), }; -// 1778 const BehaviorScript bhvAlphaBooKey[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0020, 0x0040), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 32, /*Height*/ 64), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_alpha_boo_key_loop), + CALL_NATIVE(bhv_alpha_boo_key_loop), END_LOOP(), }; -// 179C const BehaviorScript bhvBulletBill[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - COLLISION_SPHERE(0x0032, 0x0032, 0x0032), - INTERACT_TYPE(INTERACT_DAMAGE), - OBJ_SET_INT(oDamageOrCoinValue, 3), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 50, /*Height*/ 50, /*Downwards offset*/ 50), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_INT(oDamageOrCoinValue, 3), SCALE(40), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_PHYSICS(0x001E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), - CALLNATIVE(bhv_bullet_bill_init), + SET_INT(oIntangibleTimer, 0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_bullet_bill_init), BEGIN_LOOP(), - CALLNATIVE(bhv_bullet_bill_loop), + CALL_NATIVE(bhv_bullet_bill_loop), END_LOOP(), }; -// 17F4 const BehaviorScript bhvWhitePuffSmoke[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_ADD_FLOAT(oPosY, -100), - CALLNATIVE(bhv_white_puff_smoke_init), - OBJ_SET_INT(oAnimState, -1), + ADD_FLOAT(oPosY, -100), + CALL_NATIVE(bhv_white_puff_smoke_init), + SET_INT(oAnimState, -1), BEGIN_REPEAT(10), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 1820 const BehaviorScript bhvUnused1820[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 1828 const BehaviorScript bhvBowserTailAnchor[] = { BEGIN(OBJ_LIST_GENACTOR), - COLLISION_SPHERE(0x0064, 0x0032, 0xFFCE), - OBJ_SET_INT(oIntangibleTimer, 0), - GRAPH_CLEAR(), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 100, /*Height*/ 50, /*Downwards offset*/ -50), + SET_INT(oIntangibleTimer, 0), + DISABLE_RENDERING(), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_tail_anchor_loop), + CALL_NATIVE(bhv_bowser_tail_anchor_loop), END_LOOP(), }; -// 1850 const BehaviorScript bhvBowser[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - SET_HITBOX(0x0190, 0x0190), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_SET_ANIMS(oAnimations, bowser_seg6_anims_06057690), - OBJ_CHILD(MODEL_NONE, bhvBowserBodyAnchor), - OBJ_CHILD(MODEL_BOWSER_BOMB_CHILD_OBJ, bhvBowserFlameSpawn), - OBJ_SPAWN(MODEL_NONE, bhvBowserTailAnchor), - OBJ_SET_INT(oNumLootCoins, 0x0032), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_bowser_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_HITBOX(/*Radius*/ 400, /*Height*/ 400), + DROP_TO_FLOOR(), + SET_HOME(), + LOAD_ANIMATIONS(oAnimations, bowser_seg6_anims_06057690), + SPAWN_CHILD(/*Model*/ MODEL_NONE, /*Behavior*/ bhvBowserBodyAnchor), + SPAWN_CHILD(/*Model*/ MODEL_BOWSER_BOMB_CHILD_OBJ, /*Behavior*/ bhvBowserFlameSpawn), + SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvBowserTailAnchor), + SET_INT(oNumLootCoins, 50), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + CALL_NATIVE(bhv_bowser_init), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_loop), + CALL_NATIVE(bhv_bowser_loop), END_LOOP(), }; -// 18CC const BehaviorScript bhvBowserBodyAnchor[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0064, 0x012C), - INTERACT_TYPE(INTERACT_DAMAGE), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_BIG_KNOCKBACK), - GRAPH_CLEAR(), - OBJ_SET_INT(oDamageOrCoinValue, 2), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 300), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_INT(oInteractionSubtype, INT_SUBTYPE_BIG_KNOCKBACK), + DISABLE_RENDERING(), + SET_INT(oDamageOrCoinValue, 2), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_body_anchor_loop), + CALL_NATIVE(bhv_bowser_body_anchor_loop), END_LOOP(), }; -// 1904 const BehaviorScript bhvBowserFlameSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GEO_LAYOUT(MODEL_NONE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_MODEL(MODEL_NONE), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_flame_spawn_loop), + CALL_NATIVE(bhv_bowser_flame_spawn_loop), END_LOOP(), }; -// 1920 const BehaviorScript bhvTiltingBowserLavaPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(bowser_2_seg7_collision_tilting_platform), - OBJ_SET_FLOAT(oDrawingDistance, 0x4E20), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - OBJ_SET_INT(oFaceAngleYaw, 0x0000), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(bowser_2_seg7_collision_tilting_platform), + SET_FLOAT(oDrawingDistance, 20000), + SET_FLOAT(oCollisionDistance, 20000), + SET_INT(oFaceAngleYaw, 0), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(obj_rotate_face_angle_using_vel), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(obj_rotate_face_angle_using_vel), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1958 const BehaviorScript bhvFallingBowserPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oDrawingDistance, 0x4E20), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oDrawingDistance, 20000), + SET_FLOAT(oCollisionDistance, 20000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_falling_bowser_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_falling_bowser_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1984 const BehaviorScript bhvBlueBowserFlame[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_blue_bowser_flame_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_blue_bowser_flame_init), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_bowser_flame_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_blue_bowser_flame_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 19C8 const BehaviorScript bhvFlameFloatingLanding[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_flame_floating_landing_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_flame_floating_landing_init), BEGIN_LOOP(), - CALLNATIVE(bhv_flame_floating_landing_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_flame_floating_landing_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1A0C const BehaviorScript bhvBlueFlamesGroup[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_flames_group_loop), + CALL_NATIVE(bhv_blue_flames_group_loop), END_LOOP(), }; -// 1A30 const BehaviorScript bhvFlameBouncing[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - CALLNATIVE(bhv_flame_bouncing_init), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), + CALL_NATIVE(bhv_flame_bouncing_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_flame_bouncing_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_flame_bouncing_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1A74 const BehaviorScript bhvFlameMovingForwardGrowing[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - CALLNATIVE(bhv_flame_moving_forward_growing_init), + CALL_NATIVE(bhv_flame_moving_forward_growing_init), BEGIN_LOOP(), - CALLNATIVE(bhv_flame_moving_forward_growing_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_flame_moving_forward_growing_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1AA4 const BehaviorScript bhvFlameBowser[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - CALLNATIVE(bhv_flame_bowser_init), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + CALL_NATIVE(bhv_flame_bowser_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_flame_bowser_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_flame_bowser_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1AE8 const BehaviorScript bhvFlameLargeBurningOut[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), - CALLNATIVE(bhv_flame_large_burning_out_init), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + CALL_NATIVE(bhv_flame_large_burning_out_init), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_flame_bowser_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_flame_bowser_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1B2C const BehaviorScript bhvBlueFish[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_ANIMS(oAnimations, blue_fish_seg3_anims_0301C2B0), - ANIMATE(0x00), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + LOAD_ANIMATIONS(oAnimations, blue_fish_seg3_anims_0301C2B0), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_fish_loop), + CALL_NATIVE(bhv_blue_fish_loop), END_LOOP(), }; -// 1B54 const BehaviorScript bhvTankFishGroup[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_tank_fish_group_loop), + CALL_NATIVE(bhv_tank_fish_group_loop), END_LOOP(), }; -// 1B70 const BehaviorScript bhvCheckerboardElevatorGroup[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_checkerboard_elevator_group_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_checkerboard_elevator_group_init), DELAY(1), DEACTIVATE(), }; -// 1B88 const BehaviorScript bhvCheckerboardPlatformSub[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(checkerboard_platform_seg8_collision_0800D710), - CALLNATIVE(bhv_checkerboard_platform_init), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(checkerboard_platform_seg8_collision_0800D710), + CALL_NATIVE(bhv_checkerboard_platform_init), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_checkerboard_platform_loop), + CALL_NATIVE(bhv_checkerboard_platform_loop), END_LOOP(), }; -// 1BB4 const BehaviorScript bhvBowserKeyUnlockDoor[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_ANIMS(oAnimations, bowser_key_seg3_anims_list), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, bowser_key_seg3_anims_list), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_key_unlock_door_loop), + CALL_NATIVE(bhv_bowser_key_unlock_door_loop), END_LOOP(), }; -// 1BD4 const BehaviorScript bhvBowserKeyCourseExit[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_ANIMS(oAnimations, bowser_key_seg3_anims_list), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, bowser_key_seg3_anims_list), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_key_course_exit_loop), + CALL_NATIVE(bhv_bowser_key_course_exit_loop), END_LOOP(), }; -// 1BF4 const BehaviorScript bhvInvisibleObjectsUnderBridge[] = { BEGIN(OBJ_LIST_DEFAULT), - CALLNATIVE(bhv_invisible_objects_under_bridge_init), + CALL_NATIVE(bhv_invisible_objects_under_bridge_init), BREAK(), }; -// 1C04 const BehaviorScript bhvWaterLevelPillar[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(inside_castle_seg7_collision_water_level_pillar), - CALLNATIVE(bhv_water_level_pillar_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(inside_castle_seg7_collision_water_level_pillar), + CALL_NATIVE(bhv_water_level_pillar_init), BEGIN_LOOP(), - CALLNATIVE(bhv_water_level_pillar_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_water_level_pillar_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1C34 const BehaviorScript bhvDddWarp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x7530), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 30000), BEGIN_LOOP(), - CALLNATIVE(bhv_ddd_warp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ddd_warp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1C58 const BehaviorScript bhvMoatGrills[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(castle_grounds_seg7_collision_moat_grills), - OBJ_SET_FLOAT(oCollisionDistance, 0x7530), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(castle_grounds_seg7_collision_moat_grills), + SET_FLOAT(oCollisionDistance, 30000), BEGIN_LOOP(), - CALLNATIVE(bhv_moat_grills_loop), + CALL_NATIVE(bhv_moat_grills_loop), END_LOOP(), }; -// 1C7C const BehaviorScript bhvClockMinuteHand[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_INT(oAngleVelRoll, 0xFE80), + SET_INT(oAngleVelRoll, -0x180), GOTO(bhvClockHourHand + 1 + 1), }; -// 1C8C const BehaviorScript bhvClockHourHand[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_INT(oAngleVelRoll, 0xFFE0), - //.L13001C94: - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_init_room), + SET_INT(oAngleVelRoll, -0x20), + // Clock hand - common: + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_rotating_clock_arm_loop), + CALL_NATIVE(bhv_rotating_clock_arm_loop), END_LOOP(), }; -// 1CB0 const BehaviorScript bhvMacroUkiki[] = { BEGIN(OBJ_LIST_GENACTOR), - // ukikiData: - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_HOLDABLE_NPC), - SET_HITBOX(0x0028, 0x0028), - OBJ_SET_INT(oIntangibleTimer, 0), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, ukiki_seg5_anims_05015784), - ANIMATE(0x00), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_ukiki_init), + // Ukiki - common: + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_INT(oInteractionSubtype, INT_SUBTYPE_HOLDABLE_NPC), + SET_HITBOX(/*Radius*/ 40, /*Height*/ 40), + SET_INT(oIntangibleTimer, 0), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, ukiki_seg5_anims_05015784), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + CALL_NATIVE(bhv_ukiki_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ukiki_loop), + CALL_NATIVE(bhv_ukiki_loop), END_LOOP(), }; -// 1D0C const BehaviorScript bhvStub1D0C[] = { BEGIN(OBJ_LIST_DEFAULT), DEACTIVATE(), }; -// 1D14 const BehaviorScript bhvLllRotatingHexagonalPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_hexagonal_platform), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_hexagonal_platform), + SET_HOME(), BEGIN_LOOP(), - OBJ_SET_INT(oAngleVelYaw, 0x100), - OBJ_ADD_INT(oMoveAngleYaw, 0x100), - CALLNATIVE(load_object_collision_model), + SET_INT(oAngleVelYaw, 0x100), + ADD_INT(oMoveAngleYaw, 0x100), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1D40 const BehaviorScript bhvLllSinkingRockBlock[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_floating_block), - OBJ_ADD_FLOAT(oPosY, -50), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_floating_block), + ADD_FLOAT(oPosY, -50), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_sinking_rock_block_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_sinking_rock_block_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1D70 const BehaviorScript bhvStub1D70[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 1D78 const BehaviorScript bhvLllMovingOctagonalMeshPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_ADD_FLOAT(oPosY, -50), - COLLISION_DATA(lll_seg7_collision_octagonal_moving_platform), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + ADD_FLOAT(oPosY, -50), + LOAD_COLLISION_DATA(lll_seg7_collision_octagonal_moving_platform), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_moving_octagonal_mesh_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_moving_octagonal_mesh_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1DA4 const BehaviorScript bhvSnowBall[] = { BREAK(), }; -// 1DA8 const BehaviorScript bhvLllRotatingBlockWithFireBars[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_rotating_fire_bars), - OBJ_SET_FLOAT(oCollisionDistance, 0x0FA0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_rotating_fire_bars), + SET_FLOAT(oCollisionDistance, 4000), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_rotating_block_fire_bars_loop), + CALL_NATIVE(bhv_lll_rotating_block_fire_bars_loop), END_LOOP(), }; -// 1DCC const BehaviorScript bhvLllRotatingHexFlame[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - INTERACT_TYPE(INTERACT_FLAME), - COLLISION_SPHERE(0x0032, 0x0064, 0x0032), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INTERACT_TYPE(INTERACT_FLAME), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 50, /*Height*/ 100, /*Downwards offset*/ 50), + SET_INT(oIntangibleTimer, 0), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_rotating_hex_flame_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_lll_rotating_hex_flame_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 1E04 const BehaviorScript bhvLllWoodPiece[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_wood_piece), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_wood_piece), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_wood_piece_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_wood_piece_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1E30 const BehaviorScript bhvLllFloatingWoodBridge[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - GEO_LAYOUT(MODEL_NONE), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_MODEL(MODEL_NONE), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_floating_wood_bridge_loop), + CALL_NATIVE(bhv_lll_floating_wood_bridge_loop), END_LOOP(), }; -// 1E4C const BehaviorScript bhvVolcanoFlames[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_volcano_flames_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_volcano_flames_loop), END_LOOP(), }; -// 1E6C const BehaviorScript bhvLllRotatingHexagonalRing[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_rotating_platform), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_rotating_platform), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_rotating_hexagonal_ring_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_rotating_hexagonal_ring_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1E94 const BehaviorScript bhvLllSinkingRectangularPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_slow_tilting_platform), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_slow_tilting_platform), + SET_FLOAT(oCollisionDistance, 2000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_sinking_rectangular_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_sinking_rectangular_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1EC4 const BehaviorScript bhvLllSinkingSquarePlatforms[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_sinking_pyramids), - OBJ_ADD_FLOAT(oPosY, 5), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_sinking_pyramids), + ADD_FLOAT(oPosY, 5), + SET_FLOAT(oCollisionDistance, 2000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_sinking_square_platforms_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_sinking_square_platforms_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1EF8 const BehaviorScript bhvLllTiltingInvertedPyramid[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_inverted_pyramid), - OBJ_ADD_FLOAT(oPosY, 5), - OBJ_SET_POS(), - CALLNATIVE(bhv_platform_normals_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_inverted_pyramid), + ADD_FLOAT(oPosY, 5), + SET_HOME(), + CALL_NATIVE(bhv_platform_normals_init), BEGIN_LOOP(), - CALLNATIVE(bhv_tilting_inverted_pyramid_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_tilting_inverted_pyramid_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 1F30 const BehaviorScript bhvUnused1F30[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BREAK(), }; -// 1F3C const BehaviorScript bhvKoopaShell[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_koopa_shell_loop), + CALL_NATIVE(bhv_koopa_shell_loop), END_LOOP(), }; -// 1F68 const BehaviorScript bhvKoopaShellFlame[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_FLAME), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_FLAME), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_koopa_shell_flame_loop), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_koopa_shell_flame_loop), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 1F90 const BehaviorScript bhvToxBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(ssl_seg7_collision_tox_box), - OBJ_ADD_FLOAT(oPosY, 256), - OBJ_SET_FLOAT(oDrawingDistance, 0x1F40), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(ssl_seg7_collision_tox_box), + ADD_FLOAT(oPosY, 256), + SET_FLOAT(oDrawingDistance, 8000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_tox_box_loop), + CALL_NATIVE(bhv_tox_box_loop), END_LOOP(), }; -// 1FBC const BehaviorScript bhvPiranhaPlant[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, piranha_plant_seg6_anims_0601C31C), - ANIMATE(0x00), - INTERACT_TYPE(INTERACT_DAMAGE), - SET_HITBOX(0x0064, 0x00C8), - OBJ_SET_FLOAT2(0x0032, 0x00C8), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oDamageOrCoinValue, 3), - OBJ_SET_INT(oNumLootCoins, 5), - OBJ_CHILD(MODEL_BUBBLE, bhvPiranhaPlantBubble), - OBJ_SET_FLOAT(oDrawingDistance, 0x07D0), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, piranha_plant_seg6_anims_0601C31C), + ANIMATE(0), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 200), + SET_HURTBOX(/*Radius*/ 50, /*Height*/ 200), + SET_INT(oIntangibleTimer, 0), + SET_INT(oDamageOrCoinValue, 3), + SET_INT(oNumLootCoins, 5), + SPAWN_CHILD(/*Model*/ MODEL_BUBBLE, /*Behavior*/ bhvPiranhaPlantBubble), + SET_FLOAT(oDrawingDistance, 2000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_piranha_plant_loop), + CALL_NATIVE(bhv_piranha_plant_loop), END_LOOP(), }; -// 2018 const BehaviorScript bhvLllHexagonalMesh[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(lll_hexagonal_mesh_seg3_collision_0301CECC), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(lll_hexagonal_mesh_seg3_collision_0301CECC), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2038 const BehaviorScript bhvLllBowserPuzzlePiece[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_puzzle_piece), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x0BB8), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_puzzle_piece), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 3000), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_bowser_puzzle_piece_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_bowser_puzzle_piece_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2068 const BehaviorScript bhvLllBowserPuzzle[] = { BEGIN(OBJ_LIST_SPAWNER), - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_ADD_FLOAT(oPosZ, -50), + DISABLE_RENDERING(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + ADD_FLOAT(oPosZ, -50), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_bowser_puzzle_loop), + CALL_NATIVE(bhv_lll_bowser_puzzle_loop), END_LOOP(), }; -// 2088 const BehaviorScript bhvTuxiesMother[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, penguin_seg5_anims_05008B74), - ANIMATE(0x03), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), - OBJ_SET_POS(), - INTERACT_TYPE(INTERACT_TEXT), - SET_HITBOX(0x00C8, 0x012C), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, penguin_seg5_anims_05008B74), + ANIMATE(3), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + SET_HOME(), + SET_INTERACT_TYPE(INTERACT_TEXT), + SET_HITBOX(/*Radius*/ 200, /*Height*/ 300), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_tuxies_mother_loop), + CALL_NATIVE(bhv_tuxies_mother_loop), END_LOOP(), }; -// 20D8 const BehaviorScript bhvPenguinBaby[] = { BEGIN(OBJ_LIST_GENACTOR), BREAK(), }; -// 20E0 const BehaviorScript bhvUnused20E0[] = { BEGIN(OBJ_LIST_GENACTOR), BREAK(), }; -// 20E8 const BehaviorScript bhvSmallPenguin[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, penguin_seg5_anims_05008B74), - ANIMATE(0x00), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_HOLDABLE_NPC), - OBJ_SET_INT(oIntangibleTimer, 0), - SET_HITBOX(0x0028, 0x0028), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, penguin_seg5_anims_05008B74), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_INT(oInteractType, INTERACT_GRABBABLE), + SET_INT(oInteractionSubtype, INT_SUBTYPE_HOLDABLE_NPC), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX(/*Radius*/ 40, /*Height*/ 40), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_small_penguin_loop), + CALL_NATIVE(bhv_small_penguin_loop), END_LOOP(), }; -// 213C const BehaviorScript bhvFish2[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_INT(oBehParams2ndByte, 0x0000), + SET_INT(oBehParams2ndByte, 0), GOTO(bhvLargeFishGroup + 1), }; -// 214C const BehaviorScript bhvFish3[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_INT(oBehParams2ndByte, 1), + SET_INT(oBehParams2ndByte, 1), GOTO(bhvLargeFishGroup + 1), }; -// 215C const BehaviorScript bhvLargeFishGroup[] = { BEGIN(OBJ_LIST_DEFAULT), - // bhvFishCommon: - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + // Large fish group - common: + DISABLE_RENDERING(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_fish_loop), + CALL_NATIVE(bhv_fish_loop), END_LOOP(), }; -// 2178 const BehaviorScript bhvFishGroup2[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_fish_group_2_loop), + CALL_NATIVE(bhv_fish_group_2_loop), END_LOOP(), }; -// 2194 const BehaviorScript bhvWdwExpressElevator[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wdw_seg7_collision_express_elevator_platform), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wdw_seg7_collision_express_elevator_platform), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_wdw_express_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wdw_express_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 21C0 const BehaviorScript bhvWdwExpressElevatorPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wdw_seg7_collision_express_elevator_platform), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wdw_seg7_collision_express_elevator_platform), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 21E4 const BehaviorScript bhvChirpChirp[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_SET_INT(oBirdChirpChirpUnkF4, 1), + SET_INT(oBirdChirpChirpUnkF4, 1), GOTO(bhvChirpChirpUnused), }; -// 21F4 const BehaviorScript bhvChirpChirpUnused[] = { - GRAPH_CLEAR(), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DISABLE_RENDERING(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_bird_chirp_chirp_loop), + CALL_NATIVE(bhv_bird_chirp_chirp_loop), END_LOOP(), }; -// 220C const BehaviorScript bhvBub[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bub_seg6_anims_06012354), - ANIMATE(0x00), - COLLISION_SPHERE(0x0014, 0x000A, 0x000A), - INTERACT_TYPE(INTERACT_DAMAGE), - OBJ_SET_INT(oDamageOrCoinValue, 1), - OBJ_SET_POS(), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bub_seg6_anims_06012354), + ANIMATE(0), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 20, /*Height*/ 10, /*Downwards offset*/ 10), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_INT(oDamageOrCoinValue, 1), + SET_HOME(), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_cheep_cheep_loop), + CALL_NATIVE(bhv_cheep_cheep_loop), END_LOOP(), }; -// 2250 const BehaviorScript bhvExclamationBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(exclamation_box_outline_seg8_collision_08025F78), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x012C), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(exclamation_box_outline_seg8_collision_08025F78), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 300), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_exclamation_box_loop), + CALL_NATIVE(bhv_exclamation_box_loop), END_LOOP(), }; -// 227C const BehaviorScript bhvRotatingExclamationMark[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), SCALE(200), BEGIN_LOOP(), - CALLNATIVE(bhv_rotatin_exclamation_box_loop), - OBJ_ADD_INT(oMoveAngleYaw, 0x800), + CALL_NATIVE(bhv_rotatin_exclamation_box_loop), + ADD_INT(oMoveAngleYaw, 0x800), END_LOOP(), }; -// 229C const BehaviorScript bhvSoundSpawner[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), DELAY(3), - CALLNATIVE(bhv_sound_spawner_init), + CALL_NATIVE(bhv_sound_spawner_init), DELAY(30), DEACTIVATE(), }; -// 22B8 const BehaviorScript bhvRockSolid[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(jrb_seg7_collision_rock_solid), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(jrb_seg7_collision_rock_solid), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 22D8 const BehaviorScript bhvBowserSubDoor[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(ddd_seg7_collision_bowser_sub_door), - OBJ_SET_FLOAT(oDrawingDistance, 0x4E20), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(ddd_seg7_collision_bowser_sub_door), + SET_FLOAT(oDrawingDistance, 20000), + SET_FLOAT(oCollisionDistance, 20000), BEGIN_LOOP(), - CALLNATIVE(bhv_bowsers_sub_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_bowsers_sub_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2308 const BehaviorScript bhvBowsersSub[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oDrawingDistance, 0x4E20), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - COLLISION_DATA(ddd_seg7_collision_submarine), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oDrawingDistance, 20000), + SET_FLOAT(oCollisionDistance, 20000), + LOAD_COLLISION_DATA(ddd_seg7_collision_submarine), BEGIN_LOOP(), - CALLNATIVE(bhv_bowsers_sub_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_bowsers_sub_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2338 const BehaviorScript bhvSushiShark[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, sushi_seg5_anims_0500AE54), - OBJ_SPAWN(MODEL_NONE, bhvSushiSharkCollisionChild), - COLLISION_SPHERE(0x0064, 0x0032, 0x0032), - INTERACT_TYPE(INTERACT_DAMAGE), - OBJ_SET_INT(oDamageOrCoinValue, 3), - OBJ_SET_POS(), - ANIMATE(0x00), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, sushi_seg5_anims_0500AE54), + SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvSushiSharkCollisionChild), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 100, /*Height*/ 50, /*Downwards offset*/ 50), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_INT(oDamageOrCoinValue, 3), + SET_HOME(), + ANIMATE(0), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_sushi_shark_loop), + CALL_NATIVE(bhv_sushi_shark_loop), END_LOOP(), }; -// 2388 const BehaviorScript bhvSushiSharkCollisionChild[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GRAPH_CLEAR(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), BEGIN_LOOP(), - CALLNATIVE(bhv_sushi_shark_collision_loop), + CALL_NATIVE(bhv_sushi_shark_collision_loop), END_LOOP(), }; -// 23A4 const BehaviorScript bhvJrbSlidingBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(jrb_seg7_collision_floating_box), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(jrb_seg7_collision_floating_box), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_jrb_sliding_box_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_jrb_sliding_box_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 23D0 const BehaviorScript bhvShipPart3[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_ship_part_3_loop), + CALL_NATIVE(bhv_ship_part_3_loop), END_LOOP(), }; -// 23EC const BehaviorScript bhvInSunkenShip3[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(jrb_seg7_collision_in_sunken_ship_3), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x0FA0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(jrb_seg7_collision_in_sunken_ship_3), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 4000), BEGIN_LOOP(), - CALLNATIVE(bhv_ship_part_3_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ship_part_3_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 241C const BehaviorScript bhvSunkenShipPart[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), SCALE(50), - OBJ_SET_POS(), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_sunken_ship_part_loop), + CALL_NATIVE(bhv_sunken_ship_part_loop), END_LOOP(), }; -// 243C -const BehaviorScript bhvUnused243C[] = { - OBJ_SET_INT(oFaceAnglePitch, 0xE958), - OBJ_SET_INT(oFaceAngleYaw, 0xEE6C), - OBJ_SET_INT(oFaceAngleRoll, 0x0C80), +const BehaviorScript bhvSunkenShipSetRotation[] = { + SET_INT(oFaceAnglePitch, 0xE958), + SET_INT(oFaceAngleYaw, 0xEE6C), + SET_INT(oFaceAngleRoll, 0x0C80), RETURN(), }; -// 244C const BehaviorScript bhvSunkenShipPart2[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), SCALE(100), - OBJ_SET_FLOAT(oDrawingDistance, 0x1770), - OBJ_SET_POS(), - CALL(bhvUnused243C), + SET_FLOAT(oDrawingDistance, 6000), + SET_HOME(), + CALL(bhvSunkenShipSetRotation), BREAK(), }; -// 246C const BehaviorScript bhvInSunkenShip[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(jrb_seg7_collision_in_sunken_ship), + LOAD_COLLISION_DATA(jrb_seg7_collision_in_sunken_ship), GOTO(bhvInSunkenShip2 + 1 + 2), }; -// 2480 const BehaviorScript bhvInSunkenShip2[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(jrb_seg7_collision_in_sunken_ship_2), - // .LbhvInSunkenShip248C: - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x0FA0), - CALL(bhvUnused243C), + LOAD_COLLISION_DATA(jrb_seg7_collision_in_sunken_ship_2), + // Sunken ship - common: + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 4000), + CALL(bhvSunkenShipSetRotation), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 24AC const BehaviorScript bhvMarioDustGenerator[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000001), - GRAPH_CLEAR(), - OBJ_CHILD(MODEL_MIST, bhvWhitePuff1), - OBJ_CHILD(MODEL_SMOKE, bhvWhitePuff2), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_0), + DISABLE_RENDERING(), + SPAWN_CHILD(/*Model*/ MODEL_MIST, /*Behavior*/ bhvWhitePuff1), + SPAWN_CHILD(/*Model*/ MODEL_SMOKE, /*Behavior*/ bhvWhitePuff2), DELAY(1), DEACTIVATE(), }; -// 24DC const BehaviorScript bhvWhitePuff1[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000001), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_white_puff_1_loop), + CALL_NATIVE(bhv_white_puff_1_loop), END_LOOP(), }; -// 2500 const BehaviorScript bhvWhitePuff2[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_REPEAT(7), - CALLNATIVE(bhv_white_puff_2_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_white_puff_2_loop), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2528 const BehaviorScript bhvWhitePuffSmoke2[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_REPEAT(7), - CALLNATIVE(bhv_white_puff_2_loop), - CALLNATIVE(obj_move_using_fvel_and_gravity), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_white_puff_2_loop), + CALL_NATIVE(obj_move_using_fvel_and_gravity), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2558 const BehaviorScript bhvPurpleSwitchHiddenBoxes[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oBehParams2ndByte, 2), + SET_INT(oBehParams2ndByte, 2), GOTO(bhvFloorSwitchHardcodedModel + 1), }; -// 2568 const BehaviorScript bhvBlueCoinSwitch[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(blue_coin_switch_seg8_collision_08000E98), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(blue_coin_switch_seg8_collision_08000E98), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_coin_switch_loop), + CALL_NATIVE(bhv_blue_coin_switch_loop), END_LOOP(), }; -// 2588 const BehaviorScript bhvHiddenBlueCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_SET_INT(oInteractType, INTERACT_COIN), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_COIN), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - SET_HITBOX(0x0064, 0x0040), - OBJ_SET_INT(oDamageOrCoinValue, 0x0005), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 64), + SET_INT(oDamageOrCoinValue, 5), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_hidden_blue_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_hidden_blue_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 25C0 const BehaviorScript bhvOpenableCageDoor[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_openable_cage_door_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_openable_cage_door_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 25E0 const BehaviorScript bhvOpenableGrill[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_openable_grill_loop), + CALL_NATIVE(bhv_openable_grill_loop), END_LOOP(), }; -// 25F8 const BehaviorScript bhvWaterLevelDiamond[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0046, 0x001E), - OBJ_SET_FLOAT(oCollisionDistance, 0x00C8), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 70, /*Height*/ 30), + SET_FLOAT(oCollisionDistance, 200), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_water_level_diamond_loop), + CALL_NATIVE(bhv_water_level_diamond_loop), END_LOOP(), }; -// 2620 const BehaviorScript bhvInitializeChangingWaterLevel[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_init_changing_water_level_loop), + CALL_NATIVE(bhv_init_changing_water_level_loop), END_LOOP(), }; -// 2634 const BehaviorScript bhvTornadoSandParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_tweester_sand_particle_loop), + CALL_NATIVE(bhv_tweester_sand_particle_loop), END_LOOP(), }; -// 2650 const BehaviorScript bhvTornado[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x001E, 0xFE70, 0x0000, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - DROP_FLOOR(), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + DROP_TO_FLOOR(), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_tweester_loop), + CALL_NATIVE(bhv_tweester_loop), END_LOOP(), }; -// 2684 const BehaviorScript bhvMerryGoRoundBooManager[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_merry_go_round_boo_manager_loop), + CALL_NATIVE(bhv_merry_go_round_boo_manager_loop), END_LOOP(), }; -// 269C const BehaviorScript bhvAnimatedTexture[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFBA, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_animated_texture_loop), - OBJ_ADD_INT(oAnimState, 1), - TEXT_ANIM_RATE(oAnimState, 0x0002), + CALL_NATIVE(bhv_animated_texture_loop), + ADD_INT(oAnimState, 1), + TEX_ANIM_RATE(oAnimState, 2), END_LOOP(), }; -// 26D4 const BehaviorScript bhvBooInCastle[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oGraphYOffset, 0x003C), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oGraphYOffset, 60), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_boo_in_castle_loop), + CALL_NATIVE(bhv_boo_in_castle_loop), END_LOOP(), }; -// 2710 const BehaviorScript bhvBooWithCage[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_INT(oDamageOrCoinValue, 3), - OBJ_SET_FLOAT2(0x0050, 0x0078), - SET_HITBOX(0x00B4, 0x008C), - OBJ_SET_FLOAT(oGraphYOffset, 0x003C), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_boo_with_cage_init), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_INT(oDamageOrCoinValue, 3), + SET_HURTBOX(/*Radius*/ 80, /*Height*/ 120), + SET_HITBOX(/*Radius*/ 180, /*Height*/ 140), + SET_FLOAT(oGraphYOffset, 60), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_boo_with_cage_init), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_boo_with_cage_loop), + CALL_NATIVE(bhv_boo_with_cage_loop), END_LOOP(), }; -// 2768 const BehaviorScript bhvBalconyBigBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_SET_INT(oBehParams2ndByte, 2), - OBJ_SET_INT(oBigBooNumMinionBoosKilled, 10), + SET_INT(oBehParams2ndByte, 2), + SET_INT(oBigBooNumMinionBoosKilled, 10), GOTO(bhvGhostHuntBigBoo + 1), }; -// 277C const BehaviorScript bhvMerryGoRoundBigBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_SET_INT(oBehParams2ndByte, 1), + SET_INT(oBehParams2ndByte, 1), // Set number of minion boos killed to 10, which is greater than 5 so that the boo always loads without needing to kill any boos. - OBJ_SET_INT(oBigBooNumMinionBoosKilled, 10), + SET_INT(oBigBooNumMinionBoosKilled, 10), GOTO(bhvGhostHuntBigBoo + 1), }; -// 2790 const BehaviorScript bhvGhostHuntBigBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - // common_big_boo_bhv: - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_boo_init), + // Big boo - common: + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_boo_init), BEGIN_LOOP(), - CALLNATIVE(bhv_big_boo_loop), + CALL_NATIVE(bhv_big_boo_loop), END_LOOP(), }; -// 27D0 const BehaviorScript bhvCourtyardBooTriplet[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - CALLNATIVE(bhv_courtyard_boo_triplet_init), + DISABLE_RENDERING(), + CALL_NATIVE(bhv_courtyard_boo_triplet_init), DEACTIVATE(), }; -// 27E4 const BehaviorScript bhvBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_SET_INT(oBehParams2ndByte, 1), + SET_INT(oBehParams2ndByte, 1), GOTO(bhvGhostHuntBoo + 1), }; -// 27F4 const BehaviorScript bhvMerryGoRoundBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_SET_INT(oBehParams2ndByte, 2), + SET_INT(oBehParams2ndByte, 2), GOTO(bhvGhostHuntBoo + 1), }; -// 2804 const BehaviorScript bhvGhostHuntBoo[] = { BEGIN(OBJ_LIST_GENACTOR), - // common_boo_bhv: # 2808 - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_POS(), - OBJ_SET_INT(oDamageOrCoinValue, 2), - SET_HITBOX(0x008C, 0x0050), - OBJ_SET_FLOAT2(0x0028, 0x003C), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_init_room), - OBJ_CHILD(MODEL_YELLOW_COIN, bhvCoinInsideBoo), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_boo_init), + // Boo - common: + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oIntangibleTimer, 0), + SET_HOME(), + SET_INT(oDamageOrCoinValue, 2), + SET_HITBOX(/*Radius*/ 140, /*Height*/ 80), + SET_HURTBOX(/*Radius*/ 40, /*Height*/ 60), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_init_room), + SPAWN_CHILD(/*Model*/ MODEL_YELLOW_COIN, /*Behavior*/ bhvCoinInsideBoo), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_boo_init), BEGIN_LOOP(), - CALLNATIVE(bhv_boo_loop), + CALL_NATIVE(bhv_boo_loop), END_LOOP(), }; -// 286C const BehaviorScript bhvHiddenStaircaseStep[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bbh_seg7_collision_staircase_step), - OBJ_SET_INT(oRoom, 0x0001), - OBJ_SET_FLOAT(oCollisionDistance, 0x03E8), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bbh_seg7_collision_staircase_step), + SET_INT(oRoom, 1), + SET_FLOAT(oCollisionDistance, 1000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2898 const BehaviorScript bhvBooBossSpawnedBridge[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bbh_seg7_collision_staircase_step), - OBJ_SET_INT(oRoom, 0x0001), - OBJ_SET_FLOAT(oCollisionDistance, 0x03E8), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bbh_seg7_collision_staircase_step), + SET_INT(oRoom, 1), + SET_FLOAT(oCollisionDistance, 1000), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_boo_boss_spawned_bridge_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_boo_boss_spawned_bridge_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 28CC const BehaviorScript bhvBbhTiltingTrapPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(bbh_seg7_collision_tilt_floor_platform), - OBJ_SET_POS(), - OBJ_SET_INT(oRoom, 0x0002), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(bbh_seg7_collision_tilt_floor_platform), + SET_HOME(), + SET_INT(oRoom, 2), BEGIN_LOOP(), - CALLNATIVE(bhv_bbh_tilting_trap_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_bbh_tilting_trap_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 28FC const BehaviorScript bhvHauntedBookshelf[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bbh_seg7_collision_haunted_bookshelf), - OBJ_SET_POS(), - OBJ_SET_INT(oRoom, 0x0006), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bbh_seg7_collision_haunted_bookshelf), + SET_HOME(), + SET_INT(oRoom, 6), BEGIN_LOOP(), - CALLNATIVE(bhv_haunted_bookshelf_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_haunted_bookshelf_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 292C const BehaviorScript bhvMeshElevator[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(bbh_seg7_collision_mesh_elevator), - OBJ_SET_POS(), - OBJ_SET_INT(oRoom, 0x000C), - OBJ_SET_INT(oBehParams2ndByte, 0x0004), - CALLNATIVE(bhv_elevator_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(bbh_seg7_collision_mesh_elevator), + SET_HOME(), + SET_INT(oRoom, 12), + SET_INT(oBehParams2ndByte, 4), + CALL_NATIVE(bhv_elevator_init), BEGIN_LOOP(), - CALLNATIVE(bhv_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2968 const BehaviorScript bhvMerryGoRound[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(bbh_seg7_collision_merry_go_round), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - OBJ_SET_INT(oRoom, 0x000A), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(bbh_seg7_collision_merry_go_round), + SET_FLOAT(oCollisionDistance, 2000), + SET_INT(oRoom, 10), BEGIN_LOOP(), - CALLNATIVE(bhv_merry_go_round_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_merry_go_round_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; #ifndef VERSION_JP -// 2998 const BehaviorScript bhvPlaysMusicTrackWhenTouched[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_play_music_track_when_touched_loop), + CALL_NATIVE(bhv_play_music_track_when_touched_loop), END_LOOP(), }; #endif -// 2998 const BehaviorScript bhvInsideCannon[] = { BREAK(), }; -// 299C const BehaviorScript bhvBetaBowserAnchor[] = { BEGIN(OBJ_LIST_DESTRUCTIVE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_POS(), - SET_HITBOX(0x0064, 0x012C), - OBJ_SET_INT(oIntangibleTimer, 0), + SET_HOME(), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 300), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_beta_bowser_anchor_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_beta_bowser_anchor_loop), END_LOOP(), }; -// 29CC const BehaviorScript bhvStaticCheckeredPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(checkerboard_platform_seg8_collision_0800D710), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(checkerboard_platform_seg8_collision_0800D710), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_static_checkered_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_static_checkered_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 29F8 const BehaviorScript bhvUnused2A10[] = { BEGIN(OBJ_LIST_DEFAULT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BREAK(), }; -// 2A08 const BehaviorScript bhvUnusedFakeStar[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - OBJ_ADD_INT(oFaceAnglePitch, 256), - OBJ_ADD_INT(oFaceAngleYaw, 256), + ADD_INT(oFaceAnglePitch, 0x100), + ADD_INT(oFaceAngleYaw, 0x100), END_LOOP(), }; @@ -3323,3210 +3113,2941 @@ static const BehaviorScript unused_1[] = { BREAK(), }; -// 2A30 const BehaviorScript bhvStaticObject[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BREAK(), }; -// 2A3C const BehaviorScript bhvUnused2A54[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 2A44 const BehaviorScript bhvCastleFloorTrap[] = { BEGIN(OBJ_LIST_DEFAULT), - GRAPH_CLEAR(), - CALLNATIVE(bhv_castle_floor_trap_init), + DISABLE_RENDERING(), + CALL_NATIVE(bhv_castle_floor_trap_init), BEGIN_LOOP(), - CALLNATIVE(bhv_castle_floor_trap_loop), + CALL_NATIVE(bhv_castle_floor_trap_loop), END_LOOP(), }; -// 2A64 const BehaviorScript bhvFloorTrapInCastle[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(inside_castle_seg7_collision_floor_trap), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(inside_castle_seg7_collision_floor_trap), BEGIN_LOOP(), - CALLNATIVE(bhv_floor_trap_in_castle_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_floor_trap_in_castle_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2A8C const BehaviorScript bhvTree[] = { BEGIN(OBJ_LIST_POLELIKE), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oInteractType, INTERACT_POLE), - SET_HITBOX(0x0050, 0x01F4), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oInteractType, INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 500), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(BehClimbDetectLoop), + CALL_NATIVE(BehClimbDetectLoop), END_LOOP(), }; -// 2AB8 const BehaviorScript bhvSparkle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oAnimState, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oAnimState, -1), BEGIN_REPEAT(9), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2AD8 const BehaviorScript bhvSparkleSpawn[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_sparkle_spawn_loop), + CALL_NATIVE(bhv_sparkle_spawn_loop), END_LOOP(), }; -// 2AF0 const BehaviorScript bhvSpecialTripleJumpSparkles[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000008), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_3), BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oGraphYOffset, 25), - OBJ_SET_FLOAT_RAND(oMarioParticleFlags, 0xFFCE, 0x0064), - OBJ_SUM_FLOAT(oPosX, oPosX, oMarioParticleFlags), - OBJ_SET_FLOAT_RAND(oMarioParticleFlags, 0xFFCE, 0x0064), - OBJ_SUM_FLOAT(oPosZ, oPosZ, oMarioParticleFlags), - OBJ_SET_FLOAT_RAND(oMarioParticleFlags, 0xFFCE, 0x0064), - OBJ_SUM_FLOAT(oPosY, oPosY, oMarioParticleFlags), - OBJ_SET_INT(oAnimState, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oGraphYOffset, 25), + SET_RANDOM_FLOAT(oMarioParticleFlags, /*Minimum*/ -50, /*Maximum*/ 100), + SUM_FLOAT(/*Dest*/ oPosX, /*Value 1*/ oPosX, /*Value 2*/ oMarioParticleFlags), + SET_RANDOM_FLOAT(oMarioParticleFlags, /*Minimum*/ -50, /*Maximum*/ 100), + SUM_FLOAT(/*Dest*/ oPosZ, /*Value 1*/ oPosZ, /*Value 2*/ oMarioParticleFlags), + SET_RANDOM_FLOAT(oMarioParticleFlags, /*Minimum*/ -50, /*Maximum*/ 100), + SUM_FLOAT(/*Dest*/ oPosY, /*Value 1*/ oPosY, /*Value 2*/ oMarioParticleFlags), + SET_INT(oAnimState, -1), BEGIN_REPEAT(12), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2B44 const BehaviorScript bhvScuttlebug[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, scuttlebug_seg6_anims_06015064), - ANIMATE(0x00), - OBJ_PHYSICS(0x0050, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, scuttlebug_seg6_anims_06015064), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 80, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_scuttlebug_loop), + CALL_NATIVE(bhv_scuttlebug_loop), END_LOOP(), }; -// 2B88 const BehaviorScript bhvScuttlebugSpawn[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_scuttlebug_spawn_loop), + CALL_NATIVE(bhv_scuttlebug_spawn_loop), END_LOOP(), }; -// 2BA0 const BehaviorScript bhvWhompKingBoss[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oBehParams2ndByte, 1), - OBJ_SET_INT(oHealth, 0x0003), + SET_INT(oBehParams2ndByte, 1), + SET_INT(oHealth, 3), GOTO(bhvSmallWhomp + 1 + 1), }; -// 2BB4 const BehaviorScript bhvSmallWhomp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_SET_INT(oNumLootCoins, 5), - // .Lbeh_whomp_2BD4: - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, whomp_seg6_anims_06020A04), - COLLISION_DATA(whomp_seg6_collision_06020A0C), - ANIMATE(0x00), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), + SET_INT(oNumLootCoins, 5), + // Whomp - common: + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, whomp_seg6_anims_06020A04), + LOAD_COLLISION_DATA(whomp_seg6_collision_06020A0C), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_whomp_loop), + CALL_NATIVE(bhv_whomp_loop), END_LOOP(), }; -// 2BFC const BehaviorScript bhvWaterSplash[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_REPEAT(3), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_water_splash_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_water_splash_loop), DELAY(1), - CALLNATIVE(bhv_water_splash_loop), + CALL_NATIVE(bhv_water_splash_loop), END_REPEAT(), BEGIN_REPEAT(5), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), DELAY(1), END_REPEAT(), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000040), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_6), DEACTIVATE(), }; -// 2C48 const BehaviorScript bhvWaterDrops[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_water_drops_loop), + CALL_NATIVE(bhv_water_drops_loop), END_LOOP(), }; -// 2C64 const BehaviorScript bhvWaterSurfaceWhiteWave[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), #ifndef VERSION_JP - OBJ_SET_INT(oFaceAnglePitch, 0), - OBJ_SET_INT(oFaceAngleYaw, 0), - OBJ_SET_INT(oFaceAngleRoll, 0), + SET_INT(oFaceAnglePitch, 0), + SET_INT(oFaceAngleYaw, 0), + SET_INT(oFaceAngleRoll, 0), #endif - CALLNATIVE(bhv_water_surface_white_wave_init), - OBJ_ADD_FLOAT(oPosY, 5), - OBJ_SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_water_surface_white_wave_init), + ADD_FLOAT(oPosY, 5), + SET_INT(oAnimState, -1), BEGIN_REPEAT(6), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2C8C const BehaviorScript bhvObjectBubbleRipples[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), #ifdef VERSION_JP - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), #endif #ifndef VERSION_JP - OBJ_SET_INT(oFaceAnglePitch, 0), - OBJ_SET_INT(oFaceAngleYaw, 0), - OBJ_SET_INT(oFaceAngleRoll, 0), + SET_INT(oFaceAnglePitch, 0), + SET_INT(oFaceAngleYaw, 0), + SET_INT(oFaceAngleRoll, 0), #endif - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_object_bubble_ripples_init), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_object_bubble_ripples_init), BEGIN_REPEAT(6), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2CBC const BehaviorScript bhvSurfaceWaves[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), #ifdef VERSION_JP - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), #endif #ifndef VERSION_JP - OBJ_SET_INT(oFaceAnglePitch, 0), - OBJ_SET_INT(oFaceAngleYaw, 0), - OBJ_SET_INT(oFaceAngleRoll, 0), + SET_INT(oFaceAnglePitch, 0), + SET_INT(oFaceAngleYaw, 0), + SET_INT(oFaceAngleRoll, 0), #endif - OBJ_SET_INT(oAnimState, -1), - OBJ_ADD_INT(oAnimState, 1), + SET_INT(oAnimState, -1), + ADD_INT(oAnimState, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_surface_waves_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_surface_waves_loop), + ADD_INT(oAnimState, 1), BEGIN_REPEAT(6), - CALLNATIVE(bhv_surface_waves_loop), + CALL_NATIVE(bhv_surface_waves_loop), END_REPEAT(), - CALLNATIVE(bhv_surface_waves_loop), + CALL_NATIVE(bhv_surface_waves_loop), END_LOOP(), }; -// 2D04 const BehaviorScript bhvWaterSurfaceWhiteWave2[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), #ifdef VERSION_JP - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), #endif #ifndef VERSION_JP - OBJ_SET_INT(oFaceAnglePitch, 0), - OBJ_SET_INT(oFaceAngleYaw, 0), - OBJ_SET_INT(oFaceAngleRoll, 0), + SET_INT(oFaceAnglePitch, 0), + SET_INT(oFaceAngleYaw, 0), + SET_INT(oFaceAngleRoll, 0), #endif - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_REPEAT(6), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_REPEAT(), DEACTIVATE(), }; -// 2D2C const BehaviorScript bhvWavesGenerator[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GRAPH_CLEAR(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), BEGIN_REPEAT(5), - SPAWN_ADDR(&D_8032FE18), - END_REPEAT_NOBREAK(), + SPAWN_WATER_SPLASH(&D_8032FE18), + END_REPEAT_CONTINUE(), DELAY(1), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000100), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_8), DEACTIVATE(), }; -// 2D58 const BehaviorScript bhvSurfaceWaveShrinking[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - GRAPH_CLEAR(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DISABLE_RENDERING(), BEGIN_REPEAT(18), - SPAWN_ADDR(&D_8032FDD0), - END_REPEAT_NOBREAK(), - CALLNATIVE(bhv_surface_wave_shrinking_init), + SPAWN_WATER_SPLASH(&D_8032FDD0), + END_REPEAT_CONTINUE(), + CALL_NATIVE(bhv_surface_wave_shrinking_init), DELAY(1), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00001000), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_12), DEACTIVATE(), }; -// 2D8C const BehaviorScript bhvWaterType[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), GOTO(bhvWaveTrailOnSurface + 1 + 1 + 2), }; -// 2D9C const BehaviorScript bhvWaveTrailOnSurface[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_BIT_CLEAR_INT32(oActiveParticleFlags, 0x00000400), - // .Lbeh_wave_trail_2DD0: # 2DAC - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), - OBJ_SET_INT(oAnimState, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + BIT_CLEAR_INT32(oActiveParticleFlags, ACTIVE_PARTICLE_10), + // Wave trail - common: + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), + SET_INT(oAnimState, -1), BEGIN_REPEAT(8), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_wave_trail_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_wave_trail_loop), DELAY(1), - CALLNATIVE(bhv_wave_trail_loop), + CALL_NATIVE(bhv_wave_trail_loop), END_REPEAT(), DEACTIVATE(), }; -// 2DE0 const BehaviorScript bhvTinyWhiteWindParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_white_wind_particle_loop), + CALL_NATIVE(bhv_white_wind_particle_loop), END_LOOP(), }; -// 2DFC const BehaviorScript bhvWindParticle[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_white_wind_particle_loop), + CALL_NATIVE(bhv_white_wind_particle_loop), END_LOOP(), }; -// 2E18 const BehaviorScript bhvSnowmanWindBlowing[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_snowman_wind_blowing_loop), + CALL_NATIVE(bhv_snowman_wind_blowing_loop), END_LOOP(), }; -// 2E34 const BehaviorScript bhvWalkingPenguin[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(penguin_seg5_collision_05008B88), - OBJ_SET_ANIMS(oAnimations, penguin_seg5_anims_05008B74), - ANIMATE(0x00), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(penguin_seg5_collision_05008B88), + LOAD_ANIMATIONS(oAnimations, penguin_seg5_anims_05008B74), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SCALE(600), - OBJ_SET_POS(), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_walking_penguin_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_walking_penguin_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 2E84 const BehaviorScript bhvYellowBall[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BREAK(), }; UNUSED static const u64 behavior_data_unused_0 = 0; -// 2EA0 const BehaviorScript bhvMario[] = { BEGIN(OBJ_LIST_PLAYER), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_OR_INT(oFlags, OBJ_FLAG_0100), - OBJ_OR_INT(oUnk94, 0x0001), - SET_HITBOX(0x0025, 0x00A0), + SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_0100), + OR_INT(oUnk94, 0x0001), + SET_HITBOX(/*Radius*/ 37, /*Height*/ 160), BEGIN_LOOP(), - CALLNATIVE(try_print_debug_mario_level_info), - CALLNATIVE(bhv_mario_update), - CALLNATIVE(try_do_mario_debug_object_spawn), + CALL_NATIVE(try_print_debug_mario_level_info), + CALL_NATIVE(bhv_mario_update), + CALL_NATIVE(try_do_mario_debug_object_spawn), END_LOOP(), }; -// 2ED8 const BehaviorScript bhvToadMessage[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, toad_seg6_anims_0600FB58), - ANIMATE(0x06), - INTERACT_TYPE(INTERACT_TEXT), - SET_HITBOX(0x0050, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhvToadMessage_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, toad_seg6_anims_0600FB58), + ANIMATE(6), + SET_INTERACT_TYPE(INTERACT_TEXT), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhvToadMessage_init), BEGIN_LOOP(), - CALLNATIVE(bhvToadMessage_loop), + CALL_NATIVE(bhvToadMessage_loop), END_LOOP(), }; -// 2F20 const BehaviorScript bhvUnlockDoorStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhvUnlockDoorStar_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhvUnlockDoorStar_init), BEGIN_LOOP(), - CALLNATIVE(bhvUnlockDoorStar_loop), + CALL_NATIVE(bhvUnlockDoorStar_loop), END_LOOP(), }; -// 2F40 const BehaviorScript bhvWarps60[] = { BREAK(), }; -// 2F44 const BehaviorScript bhvWarps64[] = { BREAK(), }; -// 2F48 const BehaviorScript bhvWarps68[] = { BREAK(), }; -// 2F4C const BehaviorScript bhvWarps6C[] = { BREAK(), }; -// 2F50 const BehaviorScript bhvWarps70[] = { BREAK(), }; -// 2F54 const BehaviorScript bhvWarps74[] = { BREAK(), }; -// 2F58 const BehaviorScript bhvWarps78[] = { BREAK(), }; -// 2F5C const BehaviorScript bhvWarps7C[] = { BREAK(), }; -// 2F60 const BehaviorScript bhvWarps80[] = { BREAK(), }; -// 2F64 const BehaviorScript bhvWarps84[] = { BREAK(), }; -// 2F68 const BehaviorScript bhvWarps88[] = { BREAK(), }; -// 2F6C const BehaviorScript bhvWarps8C[] = { BREAK(), }; -// 2F70 const BehaviorScript bhvWarps90[] = { BREAK(), }; -// 2F74 const BehaviorScript bhvWarps94[] = { BREAK(), }; UNUSED static const u64 behavior_data_unused_1 = 0; -// 2F80 const BehaviorScript bhvRandomAnimatedTexture[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oGraphYOffset, 0xFFF0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oGraphYOffset, -16), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 2FA0 const BehaviorScript bhvYellowBackgroundInMenu[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(beh_yellow_background_menu_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(beh_yellow_background_menu_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(beh_yellow_background_menu_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(beh_yellow_background_menu_loop), END_LOOP(), }; -// 2FC4 const BehaviorScript bhvMenuButton[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_menu_button_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_menu_button_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_menu_button_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_menu_button_loop), END_LOOP(), }; -// 2FE8 const BehaviorScript bhvMenuButtonManager[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0800 | OBJ_FLAG_0020 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_menu_button_manager_init), + OR_INT(oFlags, (OBJ_FLAG_0800 | OBJ_FLAG_0020 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_menu_button_manager_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_menu_button_manager_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_menu_button_manager_loop), END_LOOP(), }; -// 300C const BehaviorScript bhvActSelectorStarType[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_act_selector_star_type_loop), + CALL_NATIVE(bhv_act_selector_star_type_loop), END_LOOP(), }; -// 3028 const BehaviorScript bhvActSelector[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_act_selector_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_act_selector_init), BEGIN_LOOP(), - CALLNATIVE(bhv_act_selector_loop), + CALL_NATIVE(bhv_act_selector_loop), END_LOOP(), }; -// 3048 const BehaviorScript bhvMovingYellowCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - SET_HITBOX(0x0064, 0x0040), - OBJ_SET_INT(oInteractType, INTERACT_COIN), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_moving_yellow_coin_init), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 64), + SET_INT(oInteractType, INTERACT_COIN), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_moving_yellow_coin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_moving_yellow_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_moving_yellow_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3084 const BehaviorScript bhvMovingBlueCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_moving_blue_coin_init), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_moving_blue_coin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_moving_blue_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_moving_blue_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 30B4 const BehaviorScript bhvBlueCoinSliding[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_blue_coin_sliding_jumping_init), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_blue_coin_sliding_jumping_init), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_coin_sliding_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_blue_coin_sliding_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 30E4 const BehaviorScript bhvBlueCoinJumping[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_blue_coin_sliding_jumping_init), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_blue_coin_sliding_jumping_init), BEGIN_LOOP(), - CALLNATIVE(bhv_blue_coin_jumping_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_blue_coin_jumping_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3114 const BehaviorScript bhvSeaweed[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, seaweed_seg6_anims_0600A4D4), - ANIMATE(0x00), - CALLNATIVE(bhv_seaweed_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, seaweed_seg6_anims_0600A4D4), + ANIMATE(0), + CALL_NATIVE(bhv_seaweed_init), BEGIN_LOOP(), END_LOOP(), }; -// 3138 const BehaviorScript bhvSeaweedBundle[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - CALLNATIVE(bhv_seaweed_bundle_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_seaweed_bundle_init), BEGIN_LOOP(), END_LOOP(), }; -// 3154 const BehaviorScript bhvBobomb[] = { BEGIN(OBJ_LIST_DESTRUCTIVE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bobomb_seg8_anims_0802396C), - DROP_FLOOR(), - ANIMATE(0x00), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_POS(), - CALLNATIVE(bhv_bobomb_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bobomb_seg8_anims_0802396C), + DROP_TO_FLOOR(), + ANIMATE(0), + SET_INT(oIntangibleTimer, 0), + SET_HOME(), + CALL_NATIVE(bhv_bobomb_init), BEGIN_LOOP(), - CALLNATIVE(bhv_bobomb_loop), + CALL_NATIVE(bhv_bobomb_loop), END_LOOP(), }; -// 318C const BehaviorScript bhvBobombFuseSmoke[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_bobomb_fuse_smoke_init), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_bobomb_fuse_smoke_init), DELAY(1), BEGIN_LOOP(), - CALLNATIVE(BehDustSmokeLoop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(BehDustSmokeLoop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 31BC const BehaviorScript bhvBobombBuddy[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bobomb_seg8_anims_0802396C), - INTERACT_TYPE(INTERACT_TEXT), - DROP_FLOOR(), - SET_HITBOX(0x0064, 0x003C), - ANIMATE(0x00), - OBJ_SET_INT(oBobombBuddyRole, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_bobomb_buddy_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bobomb_seg8_anims_0802396C), + SET_INTERACT_TYPE(INTERACT_TEXT), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 60), + ANIMATE(0), + SET_INT(oBobombBuddyRole, 0), + SET_HOME(), + CALL_NATIVE(bhv_bobomb_buddy_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bobomb_buddy_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bobomb_buddy_loop), END_LOOP(), }; -// The only difference between this and the previous behavior are what objFlags and objVarFC are set to, why didn't they just use a jump? -// 3208 +// The only difference between this and the previous behavior are what oFlags and oBobombBuddyRole are set to, why didn't they just use a jump? const BehaviorScript bhvBobombBuddyOpensCannon[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bobomb_seg8_anims_0802396C), - INTERACT_TYPE(INTERACT_TEXT), - DROP_FLOOR(), - SET_HITBOX(0x0064, 0x003C), - ANIMATE(0x00), - OBJ_SET_INT(oBobombBuddyRole, 0x0001), - OBJ_SET_POS(), - CALLNATIVE(bhv_bobomb_buddy_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bobomb_seg8_anims_0802396C), + SET_INTERACT_TYPE(INTERACT_TEXT), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 60), + ANIMATE(0), + SET_INT(oBobombBuddyRole, 1), + SET_HOME(), + CALL_NATIVE(bhv_bobomb_buddy_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bobomb_buddy_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bobomb_buddy_loop), END_LOOP(), }; -// 3254 const BehaviorScript bhvCannonClosed[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(cannon_lid_seg8_collision_08004950), - OBJ_SET_POS(), - CALLNATIVE(bhv_cannon_closed_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(cannon_lid_seg8_collision_08004950), + SET_HOME(), + CALL_NATIVE(bhv_cannon_closed_init), BEGIN_LOOP(), - CALLNATIVE(bhv_cannon_closed_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_cannon_closed_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3288 const BehaviorScript bhvWhirlpool[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_whirlpool_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_whirlpool_init), BEGIN_LOOP(), - CALLNATIVE(bhv_whirlpool_loop), + CALL_NATIVE(bhv_whirlpool_loop), END_LOOP(), }; -// 32A8 const BehaviorScript bhvJetStream[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_jet_stream_loop), + CALL_NATIVE(bhv_jet_stream_loop), END_LOOP(), }; -// 32C0 const BehaviorScript bhvMessagePanel[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(wooden_signpost_seg3_collision_0302DD80), - INTERACT_TYPE(INTERACT_TEXT), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_SIGN), - DROP_FLOOR(), - SET_HITBOX(0x0096, 0x0050), - OBJ_SET_INT(oWoodenPostTotalMarioAngle, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(wooden_signpost_seg3_collision_0302DD80), + SET_INTERACT_TYPE(INTERACT_TEXT), + SET_INT(oInteractionSubtype, INT_SUBTYPE_SIGN), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 150, /*Height*/ 80), + SET_INT(oWoodenPostTotalMarioAngle, 0), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(load_object_collision_model), - OBJ_SET_INT(oInteractStatus, 0), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(load_object_collision_model), + SET_INT(oInteractStatus, 0), END_LOOP(), }; -// 3304 const BehaviorScript bhvSignOnWall[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - INTERACT_TYPE(INTERACT_TEXT), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_SIGN), - SET_HITBOX(0x0096, 0x0050), - OBJ_SET_INT(oWoodenPostTotalMarioAngle, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INTERACT_TYPE(INTERACT_TEXT), + SET_INT(oInteractionSubtype, INT_SUBTYPE_SIGN), + SET_HITBOX(/*Radius*/ 150, /*Height*/ 80), + SET_INT(oWoodenPostTotalMarioAngle, 0), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oInteractStatus, 0), + SET_INT(oIntangibleTimer, 0), + SET_INT(oInteractStatus, 0), END_LOOP(), }; -// 3334 const BehaviorScript bhvHomingAmp[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, amp_seg8_anims_08004034), - ANIMATE(0x00), - OBJ_SET_FLOAT(oGraphYOffset, 0x0028), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_homing_amp_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, amp_seg8_anims_08004034), + ANIMATE(0), + SET_FLOAT(oGraphYOffset, 40), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_homing_amp_init), BEGIN_LOOP(), - CALLNATIVE(bhv_homing_amp_loop), + CALL_NATIVE(bhv_homing_amp_loop), END_LOOP(), }; -// 3368 const BehaviorScript bhvCirclingAmp[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, amp_seg8_anims_08004034), - ANIMATE(0x00), - OBJ_SET_FLOAT(oGraphYOffset, 0x0028), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_circling_amp_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, amp_seg8_anims_08004034), + ANIMATE(0), + SET_FLOAT(oGraphYOffset, 40), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_circling_amp_init), BEGIN_LOOP(), - CALLNATIVE(bhv_circling_amp_loop), + CALL_NATIVE(bhv_circling_amp_loop), END_LOOP(), }; -// 339C const BehaviorScript bhvButterfly[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, butterfly_seg3_anims_030056B0), - DROP_FLOOR(), - OBJ_SET_FLOAT(oGraphYOffset, 0x0005), - CALLNATIVE(bhv_butterfly_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, butterfly_seg3_anims_030056B0), + DROP_TO_FLOOR(), + SET_FLOAT(oGraphYOffset, 5), + CALL_NATIVE(bhv_butterfly_init), BEGIN_LOOP(), - CALLNATIVE(bhv_butterfly_loop), + CALL_NATIVE(bhv_butterfly_loop), END_LOOP(), }; -// 33CC const BehaviorScript bhvHoot[] = { BEGIN(OBJ_LIST_POLELIKE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, hoot_seg5_anims_05005768), - OBJ_SET_INT(oInteractType, INTERACT_HOOT), - SET_HITBOX(0x004B, 0x004B), - CALLNATIVE(bhv_hoot_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, hoot_seg5_anims_05005768), + SET_INT(oInteractType, INTERACT_HOOT), + SET_HITBOX(/*Radius*/ 75, /*Height*/ 75), + CALL_NATIVE(bhv_hoot_init), BEGIN_LOOP(), - CALLNATIVE(bhv_hoot_loop), + CALL_NATIVE(bhv_hoot_loop), END_LOOP(), }; -// 3400 const BehaviorScript bhvBetaHoldableObject[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - DROP_FLOOR(), - SET_HITBOX(0x0028, 0x0032), - CALLNATIVE(bhv_beta_holdable_object_init), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_INT(oInteractType, INTERACT_GRABBABLE), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 40, /*Height*/ 50), + CALL_NATIVE(bhv_beta_holdable_object_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_beta_holdable_object_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_beta_holdable_object_loop), END_LOOP(), }; -// 3434 const BehaviorScript bhvCarrySomething1[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 343C const BehaviorScript bhvCarrySomething2[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 3444 const BehaviorScript bhvCarrySomething3[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 344C const BehaviorScript bhvCarrySomething4[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 3454 const BehaviorScript bhvCarrySomething5[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 345C const BehaviorScript bhvCarrySomething6[] = { BEGIN(OBJ_LIST_DEFAULT), BREAK(), }; -// 3464 const BehaviorScript bhvObjectBubble[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_object_bubble_init), - OBJ_SET_FLOAT_RAND(oVelY, 0x0003, 0x0006), - OBJ_SET_INT_RAND_RSHIFT(oMoveAngleYaw, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_object_bubble_init), + SET_RANDOM_FLOAT(oVelY, /*Minimum*/ 3, /*Maximum*/ 6), + SET_INT_RAND_RSHIFT(oMoveAngleYaw, /*Minimum*/ 0, /*Right shift*/ 0), DELAY(1), BEGIN_LOOP(), - CALLNATIVE(bhv_object_bubble_loop), + CALL_NATIVE(bhv_object_bubble_loop), END_LOOP(), }; -// 34A4 const BehaviorScript bhvObjectWaterWave[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oFaceAnglePitch, 0), - OBJ_SET_FLOAT(oFaceAngleYaw, 0), - OBJ_SET_FLOAT(oFaceAngleRoll, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_object_water_wave_init), - OBJ_ADD_INT(oAnimState, 1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oFaceAnglePitch, 0), + SET_FLOAT(oFaceAngleYaw, 0), + SET_FLOAT(oFaceAngleRoll, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_object_water_wave_init), + ADD_INT(oAnimState, 1), DELAY(6), BEGIN_LOOP(), - CALLNATIVE(bhv_object_water_wave_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_object_water_wave_loop), + ADD_INT(oAnimState, 1), BEGIN_REPEAT(6), - CALLNATIVE(bhv_object_water_wave_loop), + CALL_NATIVE(bhv_object_water_wave_loop), END_REPEAT(), END_LOOP(), }; -// 34F0 const BehaviorScript bhvExplosion[] = { BEGIN(OBJ_LIST_DESTRUCTIVE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - INTERACT_TYPE(INTERACT_DAMAGE), - OBJ_SET_INT(oDamageOrCoinValue, 2), - OBJ_SET_INT(oIntangibleTimer, 0), - COLLISION_SPHERE(0x0096, 0x0096, 0x0096), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_explosion_init), + SET_INTERACT_TYPE(INTERACT_DAMAGE), + SET_INT(oDamageOrCoinValue, 2), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 150, /*Height*/ 150, /*Downwards offset*/ 150), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_explosion_init), BEGIN_LOOP(), - CALLNATIVE(bhv_explosion_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_explosion_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3538 const BehaviorScript bhvBobombBullyDeathSmoke[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_bobomb_bully_death_smoke_init), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_bobomb_bully_death_smoke_init), DELAY(1), BEGIN_LOOP(), - CALLNATIVE(BehDustSmokeLoop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(BehDustSmokeLoop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3568 const BehaviorScript bhvSmoke[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_MOVE_Y_WITH_TERMINAL_VEL | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_INT(oAnimState, -1), + SET_INT(oAnimState, -1), DELAY(1), BEGIN_LOOP(), - CALLNATIVE(BehDustSmokeLoop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(BehDustSmokeLoop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3590 const BehaviorScript bhvBobombExplosionBubble[] = { BEGIN(OBJ_LIST_DEFAULT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_bobomb_explosion_bubble_init), - OBJ_ADD_FLOAT_RAND(oPosX, -50, 100), - OBJ_ADD_FLOAT_RAND(oPosY, -50, 100), - OBJ_ADD_FLOAT_RAND(oPosZ, -50, 100), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_bobomb_explosion_bubble_init), + ADD_RANDOM_FLOAT(oPosX, /*Minimum*/ -50, /*Maximum*/ 100), + ADD_RANDOM_FLOAT(oPosY, /*Minimum*/ -50, /*Maximum*/ 100), + ADD_RANDOM_FLOAT(oPosZ, /*Minimum*/ -50, /*Maximum*/ 100), CALL(bhvBobombExplosionBubble3600), DELAY(1), BEGIN_LOOP(), CALL(bhvBobombExplosionBubble3600), - CALLNATIVE(bhv_bobomb_explosion_bubble_loop), + CALL_NATIVE(bhv_bobomb_explosion_bubble_loop), END_LOOP(), }; -// 35E0 const BehaviorScript bhvBobombExplosionBubble3600[] = { - OBJ_ADD_FLOAT_RAND(oPosX, -2, 4), - OBJ_ADD_FLOAT_RAND(oPosZ, -2, 4), + ADD_RANDOM_FLOAT(oPosX, /*Minimum*/ -2, /*Maximum*/ 4), + ADD_RANDOM_FLOAT(oPosZ, /*Minimum*/ -2, /*Maximum*/ 4), RETURN(), }; -// 35F4 const BehaviorScript bhvRespawner[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_respawner_loop), + CALL_NATIVE(bhv_respawner_loop), END_LOOP(), }; -// 360C const BehaviorScript bhvSmallBully[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bully_seg5_anims_0500470C), - DROP_FLOOR(), - OBJ_SET_POS(), - CALLNATIVE(bhv_small_bully_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bully_seg5_anims_0500470C), + DROP_TO_FLOOR(), + SET_HOME(), + CALL_NATIVE(bhv_small_bully_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bully_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bully_loop), END_LOOP(), }; -// 3640 const BehaviorScript bhvBigBully[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bully_seg5_anims_0500470C), - DROP_FLOOR(), - OBJ_SET_POS(), - CALLNATIVE(bhv_big_bully_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bully_seg5_anims_0500470C), + DROP_TO_FLOOR(), + SET_HOME(), + CALL_NATIVE(bhv_big_bully_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bully_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bully_loop), END_LOOP(), }; -// 3674 const BehaviorScript bhvBigBullyWithMinions[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bully_seg5_anims_0500470C), - OBJ_SET_POS(), - CALLNATIVE(bhv_big_bully_init), - CALLNATIVE(bhv_big_bully_with_minions_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bully_seg5_anims_0500470C), + SET_HOME(), + CALL_NATIVE(bhv_big_bully_init), + CALL_NATIVE(bhv_big_bully_with_minions_init), BEGIN_LOOP(), - CALLNATIVE(bhv_big_bully_with_minions_loop), + CALL_NATIVE(bhv_big_bully_with_minions_loop), END_LOOP(), }; -// 36A8 const BehaviorScript bhvSmallChillBully[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, chilly_chief_seg6_anims_06003994), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_SET_INT(oBullySubtype, 0x0010), - CALLNATIVE(bhv_small_bully_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, chilly_chief_seg6_anims_06003994), + DROP_TO_FLOOR(), + SET_HOME(), + SET_INT(oBullySubtype, 0x0010), + CALL_NATIVE(bhv_small_bully_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bully_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bully_loop), END_LOOP(), }; -// 36E0 const BehaviorScript bhvBigChillBully[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, chilly_chief_seg6_anims_06003994), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_SET_INT(oBullySubtype, 0x0010), - CALLNATIVE(bhv_big_bully_init), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, chilly_chief_seg6_anims_06003994), + DROP_TO_FLOOR(), + SET_HOME(), + SET_INT(oBullySubtype, 0x0010), + CALL_NATIVE(bhv_big_bully_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bully_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bully_loop), END_LOOP(), }; -// 3718 const BehaviorScript bhvJetStreamRingSpawner[] = { BEGIN(OBJ_LIST_DEFAULT), - UNHIDE(), + HIDE(), BEGIN_LOOP(), - CALLNATIVE(bhv_jet_stream_ring_spawner_loop), + CALL_NATIVE(bhv_jet_stream_ring_spawner_loop), END_LOOP(), }; -// 3730 const BehaviorScript bhvJetStreamWaterRing[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, water_ring_seg6_anims_06013F7C), - COLLISION_SPHERE(0x004B, 0x0014, 0x0014), - INTERACT_TYPE(INTERACT_WATER_RING), - OBJ_SET_INT(oDamageOrCoinValue, 2), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_jet_stream_water_ring_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, water_ring_seg6_anims_06013F7C), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 75, /*Height*/ 20, /*Downwards offset*/ 20), + SET_INTERACT_TYPE(INTERACT_WATER_RING), + SET_INT(oDamageOrCoinValue, 2), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_jet_stream_water_ring_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_jet_stream_water_ring_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_jet_stream_water_ring_loop), END_LOOP(), }; -// 3778 const BehaviorScript bhvMantaRayWaterRing[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, water_ring_seg6_anims_06013F7C), - COLLISION_SPHERE(0x004B, 0x0014, 0x0014), - INTERACT_TYPE(INTERACT_WATER_RING), - OBJ_SET_INT(oDamageOrCoinValue, 2), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_manta_ray_water_ring_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, water_ring_seg6_anims_06013F7C), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 75, /*Height*/ 20, /*Downwards offset*/ 20), + SET_INTERACT_TYPE(INTERACT_WATER_RING), + SET_INT(oDamageOrCoinValue, 2), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_manta_ray_water_ring_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_manta_ray_water_ring_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_manta_ray_water_ring_loop), END_LOOP(), }; -// 37C0 const BehaviorScript bhvMantaRayRingManager[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), END_LOOP(), }; -// 37CC const BehaviorScript bhvBowserBomb[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oIntangibleTimer, 0), - COLLISION_SPHERE(0x0028, 0x0028, 0x0028), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oIntangibleTimer, 0), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 40, /*Height*/ 40, /*Downwards offset*/ 40), DELAY(1), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_bowser_bomb_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_bowser_bomb_loop), END_LOOP(), }; -// 37FC const BehaviorScript bhvBowserBombExplosion[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 0xFEE0), - OBJ_SET_INT(oAnimState, -1), + SET_FLOAT(oGraphYOffset, -288), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_bomb_explosion_loop), + CALL_NATIVE(bhv_bowser_bomb_explosion_loop), END_LOOP(), }; -// 3820 const BehaviorScript bhvBowserBombSmoke[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 0xFEE0), - OBJ_SET_INT(oOpacity, 0x00FF), - OBJ_SET_INT(oAnimState, -1), + SET_FLOAT(oGraphYOffset, -288), + SET_INT(oOpacity, 255), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_bomb_smoke_loop), + CALL_NATIVE(bhv_bowser_bomb_smoke_loop), END_LOOP(), }; -// 3848 const BehaviorScript bhvCelebrationStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_celebration_star_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_celebration_star_init), BEGIN_LOOP(), - CALLNATIVE(bhv_celebration_star_loop), + CALL_NATIVE(bhv_celebration_star_loop), END_LOOP(), }; -// 3868 const BehaviorScript bhvCelebrationStarSparkle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oGraphYOffset, 25), - OBJ_SET_INT(oAnimState, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oGraphYOffset, 25), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_celebration_star_sparkle_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_celebration_star_sparkle_loop), END_LOOP(), }; -// 3890 const BehaviorScript bhvStarKeyCollectionPuffSpawner[] = { BEGIN(OBJ_LIST_DEFAULT), BILLBOARD(), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oAnimState, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_star_key_collection_puff_spawner_loop), + CALL_NATIVE(bhv_star_key_collection_puff_spawner_loop), END_LOOP(), }; -// 38B0 const BehaviorScript bhvLllDrawbridgeSpawner[] = { BEGIN(OBJ_LIST_DEFAULT), - UNHIDE(), + HIDE(), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_drawbridge_spawner_loop), + CALL_NATIVE(bhv_lll_drawbridge_spawner_loop), END_LOOP(), }; -// 38C8 const BehaviorScript bhvLllDrawbridge[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(lll_seg7_collision_drawbridge), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(lll_seg7_collision_drawbridge), BEGIN_LOOP(), - CALLNATIVE(bhv_lll_drawbridge_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_lll_drawbridge_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 38F0 const BehaviorScript bhvSmallBomp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_small_bomp), - CALLNATIVE(bhv_small_bomp_init), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_small_bomp), + CALL_NATIVE(bhv_small_bomp_init), BEGIN_LOOP(), - CALLNATIVE(bhv_small_bomp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_small_bomp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3920 const BehaviorScript bhvLargeBomp[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_large_bomp), - CALLNATIVE(bhv_large_bomp_init), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_large_bomp), + CALL_NATIVE(bhv_large_bomp_init), BEGIN_LOOP(), - CALLNATIVE(bhv_large_bomp_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_large_bomp_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3950 const BehaviorScript bhvWfSlidingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wf_seg7_collision_sliding_brick_platform), - CALLNATIVE(bhv_wf_sliding_platform_init), + OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wf_seg7_collision_sliding_brick_platform), + CALL_NATIVE(bhv_wf_sliding_platform_init), BEGIN_LOOP(), - CALLNATIVE(bhv_wf_sliding_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wf_sliding_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3980 const BehaviorScript bhvMoneybag[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, moneybag_seg6_anims_06005E5C), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_SET_INT(oIntangibleTimer, -1), - CALLNATIVE(bhv_moneybag_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, moneybag_seg6_anims_06005E5C), + DROP_TO_FLOOR(), + SET_HOME(), + SET_INT(oIntangibleTimer, -1), + CALL_NATIVE(bhv_moneybag_init), BEGIN_LOOP(), - CALLNATIVE(bhv_moneybag_loop), + CALL_NATIVE(bhv_moneybag_loop), END_LOOP(), }; -// 39B4 const BehaviorScript bhvMoneybagHidden[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oGraphYOffset, 0x001B), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oGraphYOffset, 27), BILLBOARD(), - SET_HITBOX(0x006E, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), + SET_HITBOX(/*Radius*/ 110, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), BEGIN_LOOP(), - OBJ_ADD_INT(oAnimState, 1), - CALLNATIVE(bhv_moneybag_hidden_loop), + ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_moneybag_hidden_loop), END_LOOP(), }; -// 39E8 const BehaviorScript bhvPitBowlingBall[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 130), - CALLNATIVE(bhv_bob_pit_bowling_ball_init), + SET_FLOAT(oGraphYOffset, 130), + CALL_NATIVE(bhv_bob_pit_bowling_ball_init), BEGIN_LOOP(), - CALLNATIVE(bhv_bob_pit_bowling_ball_loop), + CALL_NATIVE(bhv_bob_pit_bowling_ball_loop), END_LOOP(), }; -// 3A10 const BehaviorScript bhvFreeBowlingBall[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 130), - CALLNATIVE(bhv_free_bowling_ball_init), + SET_FLOAT(oGraphYOffset, 130), + CALL_NATIVE(bhv_free_bowling_ball_init), BEGIN_LOOP(), - CALLNATIVE(bhv_free_bowling_ball_loop), + CALL_NATIVE(bhv_free_bowling_ball_loop), END_LOOP(), }; -// 3A38 const BehaviorScript bhvBowlingBall[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_FLOAT(oGraphYOffset, 130), - CALLNATIVE(bhv_bowling_ball_init), + SET_FLOAT(oGraphYOffset, 130), + CALL_NATIVE(bhv_bowling_ball_init), BEGIN_LOOP(), - CALLNATIVE(bhv_bowling_ball_loop), + CALL_NATIVE(bhv_bowling_ball_loop), END_LOOP(), }; -// 3A60 const BehaviorScript bhvTtmBowlingBallSpawner[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oBBallSpawnerPeriodMinus1, 0x003F), - CALLNATIVE(bhv_generic_bowling_ball_spawner_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oBBallSpawnerPeriodMinus1, 63), + CALL_NATIVE(bhv_generic_bowling_ball_spawner_init), BEGIN_LOOP(), - CALLNATIVE(bhv_generic_bowling_ball_spawner_loop), + CALL_NATIVE(bhv_generic_bowling_ball_spawner_loop), END_LOOP(), }; -// 3A84 const BehaviorScript bhvBobBowlingBallSpawner[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oBBallSpawnerPeriodMinus1, 0x007F), - CALLNATIVE(bhv_generic_bowling_ball_spawner_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oBBallSpawnerPeriodMinus1, 127), + CALL_NATIVE(bhv_generic_bowling_ball_spawner_init), BEGIN_LOOP(), - CALLNATIVE(bhv_generic_bowling_ball_spawner_loop), + CALL_NATIVE(bhv_generic_bowling_ball_spawner_loop), END_LOOP(), }; -// 3AA8 const BehaviorScript bhvThiBowlingBallSpawner[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_thi_bowling_ball_spawner_loop), + CALL_NATIVE(bhv_thi_bowling_ball_spawner_loop), END_LOOP(), }; -// 3AC0 const BehaviorScript bhvRrCruiserWing[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_rr_cruiser_wing_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_rr_cruiser_wing_init), BEGIN_LOOP(), - CALLNATIVE(bhv_rr_cruiser_wing_loop), + CALL_NATIVE(bhv_rr_cruiser_wing_loop), END_LOOP(), }; -// 3AE0 const BehaviorScript bhvSpindel[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(ssl_seg7_collision_spindel), - CALLNATIVE(bhv_spindel_init), + OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(ssl_seg7_collision_spindel), + CALL_NATIVE(bhv_spindel_init), BEGIN_LOOP(), - CALLNATIVE(bhv_spindel_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_spindel_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3B10 const BehaviorScript bhvSslMovingPyramidWall[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(ssl_seg7_collision_0702808C), - CALLNATIVE(bhv_ssl_moving_pyramid_wall_init), + OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(ssl_seg7_collision_0702808C), + CALL_NATIVE(bhv_ssl_moving_pyramid_wall_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ssl_moving_pyramid_wall_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ssl_moving_pyramid_wall_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3B40 const BehaviorScript bhvPyramidElevator[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(ssl_seg7_collision_pyramid_elevator), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - CALLNATIVE(bhv_pyramid_elevator_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(ssl_seg7_collision_pyramid_elevator), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 20000), + CALL_NATIVE(bhv_pyramid_elevator_init), BEGIN_LOOP(), - CALLNATIVE(bhv_pyramid_elevator_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_pyramid_elevator_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3B78 const BehaviorScript bhvPyramidElevatorTrajectoryMarkerBall[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_pyramid_elevator_trajectory_marker_ball_loop), + CALL_NATIVE(bhv_pyramid_elevator_trajectory_marker_ball_loop), END_LOOP(), }; -// 3B94 const BehaviorScript bhvPyramidTop[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(ssl_seg7_collision_pyramid_top), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), - CALLNATIVE(bhv_pyramid_top_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(ssl_seg7_collision_pyramid_top), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 20000), + CALL_NATIVE(bhv_pyramid_top_init), BEGIN_LOOP(), - CALLNATIVE(bhv_pyramid_top_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_pyramid_top_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3BCC const BehaviorScript bhvPyramidTopFragment[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_pyramid_top_fragment_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_pyramid_top_fragment_init), BEGIN_LOOP(), - CALLNATIVE(bhv_pyramid_top_fragment_loop), + CALL_NATIVE(bhv_pyramid_top_fragment_loop), END_LOOP(), }; -// 3BEC const BehaviorScript bhvPyramidPillarTouchDetector[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0032, 0x0032), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 50, /*Height*/ 50), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_pyramid_pillar_touch_detector_loop), + CALL_NATIVE(bhv_pyramid_pillar_touch_detector_loop), END_LOOP(), }; -// 3C10 const BehaviorScript bhvWaterfallSoundLoop[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_waterfall_sound_loop), + CALL_NATIVE(bhv_waterfall_sound_loop), END_LOOP(), }; -// 3C24 const BehaviorScript bhvVolcanoSoundLoop[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_volcano_sound_loop), + CALL_NATIVE(bhv_volcano_sound_loop), END_LOOP(), }; -// 3C38 const BehaviorScript bhvCastleFlagWaving[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, castle_grounds_seg7_anims_flags), - ANIMATE(0x00), - CALLNATIVE(bhv_castle_flag_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, castle_grounds_seg7_anims_flags), + ANIMATE(0), + CALL_NATIVE(bhv_castle_flag_init), BEGIN_LOOP(), END_LOOP(), }; -// 3C5C const BehaviorScript bhvBirdsSoundLoop[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_birds_sound_loop), + CALL_NATIVE(bhv_birds_sound_loop), END_LOOP(), }; -// 3C70 const BehaviorScript bhvAmbientSounds[] = { BEGIN(OBJ_LIST_DEFAULT), - CALLNATIVE(bhv_ambient_sounds_init), + CALL_NATIVE(bhv_ambient_sounds_init), BEGIN_LOOP(), END_LOOP(), }; -// 3C84 const BehaviorScript bhvSandSoundLoop[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_sand_sound_loop), + CALL_NATIVE(bhv_sand_sound_loop), END_LOOP(), }; -// 3C98 const BehaviorScript bhvHiddenAt120Stars[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(castle_grounds_seg7_collision_cannon_grill), - OBJ_SET_FLOAT(oCollisionDistance, 0x0FA0), - CALLNATIVE(bhv_castle_cannon_grate_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(castle_grounds_seg7_collision_cannon_grill), + SET_FLOAT(oCollisionDistance, 4000), + CALL_NATIVE(bhv_castle_cannon_grate_init), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3CC4 const BehaviorScript bhvSnowmansBottom[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_snowmans_bottom_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_snowmans_bottom_init), BEGIN_LOOP(), - CALLNATIVE(bhv_snowmans_bottom_loop), + CALL_NATIVE(bhv_snowmans_bottom_loop), END_LOOP(), }; -// 3CEC const BehaviorScript bhvSnowmansHead[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_FLOAT(oGraphYOffset, 0x006E), - CALLNATIVE(bhv_snowmans_head_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + SET_FLOAT(oGraphYOffset, 110), + CALL_NATIVE(bhv_snowmans_head_init), BEGIN_LOOP(), - CALLNATIVE(bhv_snowmans_head_loop), + CALL_NATIVE(bhv_snowmans_head_loop), END_LOOP(), }; -// 3D14 const BehaviorScript bhvSnowmansBodyCheckpoint[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_snowmans_body_checkpoint_loop), + CALL_NATIVE(bhv_snowmans_body_checkpoint_loop), END_LOOP(), }; -// 3D2C const BehaviorScript bhvBigSnowmanWhole[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oGraphYOffset, 0x00B4), - INTERACT_TYPE(INTERACT_TEXT), - SET_HITBOX(0x00D2, 0x0226), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oGraphYOffset, 180), + SET_INTERACT_TYPE(INTERACT_TEXT), + SET_HITBOX(/*Radius*/ 210, /*Height*/ 550), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), + SET_INT(oIntangibleTimer, 0), END_LOOP(), }; -// 3D54 const BehaviorScript bhvBigBoulder[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oGraphYOffset, 0x00B4), - CALLNATIVE(bhv_big_boulder_init), - OBJ_SET_FLOAT(oCollisionDistance, 0x4E20), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oGraphYOffset, 180), + CALL_NATIVE(bhv_big_boulder_init), + SET_FLOAT(oCollisionDistance, 20000), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_big_boulder_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_big_boulder_loop), END_LOOP(), }; -// 3D80 const BehaviorScript bhvBigBoulderGenerator[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_big_boulder_generator_loop), + CALL_NATIVE(bhv_big_boulder_generator_loop), END_LOOP(), }; -// 3D98 const BehaviorScript bhvWingCap[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_wing_cap_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_wing_cap_init), BEGIN_LOOP(), - CALLNATIVE(bhv_wing_vanish_cap_loop), + CALL_NATIVE(bhv_wing_vanish_cap_loop), END_LOOP(), }; -// 3DB8 const BehaviorScript bhvMetalCap[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_metal_cap_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_metal_cap_init), BEGIN_LOOP(), - CALLNATIVE(bhv_metal_cap_loop), + CALL_NATIVE(bhv_metal_cap_loop), END_LOOP(), }; -// 3DD8 const BehaviorScript bhvNormalCap[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_normal_cap_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_normal_cap_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_normal_cap_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_normal_cap_loop), END_LOOP(), }; -// 3DFC const BehaviorScript bhvVanishCap[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_vanish_cap_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_vanish_cap_init), BEGIN_LOOP(), - CALLNATIVE(bhv_wing_vanish_cap_loop), + CALL_NATIVE(bhv_wing_vanish_cap_loop), END_LOOP(), }; -// 3E1C const BehaviorScript bhvStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_collect_star_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_collect_star_init), BEGIN_LOOP(), - CALLNATIVE(bhv_collect_star_loop), + CALL_NATIVE(bhv_collect_star_loop), END_LOOP(), }; -// 3E44 const BehaviorScript bhvStarSpawnCoordinates[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_collect_star_init), - CALLNATIVE(bhv_star_spawn_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_collect_star_init), + CALL_NATIVE(bhv_star_spawn_init), BEGIN_LOOP(), - CALLNATIVE(bhv_star_spawn_loop), + CALL_NATIVE(bhv_star_spawn_loop), END_LOOP(), }; -// 3E6C const BehaviorScript bhvHiddenRedCoinStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_hidden_red_coin_star_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_hidden_red_coin_star_init), BEGIN_LOOP(), - CALLNATIVE(bhv_hidden_red_coin_star_loop), + CALL_NATIVE(bhv_hidden_red_coin_star_loop), END_LOOP(), }; -// 3E8C const BehaviorScript bhvRedCoin[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_SET_INT(oAnimState, -1), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_red_coin_init), + SET_INT(oIntangibleTimer, 0), + SET_INT(oAnimState, -1), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_red_coin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_red_coin_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_red_coin_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 3EC4 const BehaviorScript bhvBowserCourseRedCoinStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_bowser_course_red_coin_star_loop), + CALL_NATIVE(bhv_bowser_course_red_coin_star_loop), END_LOOP(), }; -// 3EDC const BehaviorScript bhvHiddenStar[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_hidden_star_init), + OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_hidden_star_init), BEGIN_LOOP(), - CALLNATIVE(bhv_hidden_star_loop), + CALL_NATIVE(bhv_hidden_star_loop), END_LOOP(), }; -// 3EFC const BehaviorScript bhvHiddenStarTrigger[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0064, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_hidden_star_trigger_loop), + CALL_NATIVE(bhv_hidden_star_trigger_loop), END_LOOP(), }; -// 3F20 const BehaviorScript bhvTtmRollingLog[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(ttm_seg7_collision_pitoune_2), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - CALLNATIVE(bhv_ttm_rolling_log_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(ttm_seg7_collision_pitoune_2), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 2000), + CALL_NATIVE(bhv_ttm_rolling_log_init), BEGIN_LOOP(), - CALLNATIVE(bhv_rolling_log_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_rolling_log_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3F58 const BehaviorScript bhvLllVolcanoFallingTrap[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(lll_seg7_collision_falling_wall), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(lll_seg7_collision_falling_wall), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhvLllVolcanoFallingTrap_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhvLllVolcanoFallingTrap_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3F84 const BehaviorScript bhvLllRollingLog[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(lll_seg7_collision_pitoune), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - CALLNATIVE(bhv_lll_rolling_log_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(lll_seg7_collision_pitoune), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 2000), + CALL_NATIVE(bhv_lll_rolling_log_init), BEGIN_LOOP(), - CALLNATIVE(bhv_rolling_log_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_rolling_log_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 3FBC const BehaviorScript bhv1upWalking[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - CALLNATIVE(bhv_1up_walking_loop), + CALL_NATIVE(bhv_1up_walking_loop), END_LOOP(), }; -// 3FF0 const BehaviorScript bhv1upRunningAway[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - CALLNATIVE(bhv_1up_running_away_loop), + CALL_NATIVE(bhv_1up_running_away_loop), END_LOOP(), }; -// 4024 const BehaviorScript bhv1upSliding[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_1up_sliding_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_1up_sliding_loop), END_LOOP(), }; -// 405C const BehaviorScript bhv1Up[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_1up_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_1up_loop), END_LOOP(), }; -// 4094 const BehaviorScript bhv1upJumpOnApproach[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_1up_jump_on_approach_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_1up_jump_on_approach_loop), END_LOOP(), }; -// 40CC const BehaviorScript bhvHidden1up[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_1up_hidden_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_1up_hidden_loop), END_LOOP(), }; -// 4104 const BehaviorScript bhvHidden1upTrigger[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0064, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_1up_hidden_trigger_loop), + CALL_NATIVE(bhv_1up_hidden_trigger_loop), END_LOOP(), }; -// 4128 const BehaviorScript bhvHidden1upInPole[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - COLLISION_SPHERE(0x001E, 0x001E, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 30), - CALLNATIVE(bhv_1up_common_init), + SET_HITBOX_WITH_OFFSET(/*Radius*/ 30, /*Height*/ 30, /*Downwards offset*/ 0), + SET_FLOAT(oGraphYOffset, 30), + CALL_NATIVE(bhv_1up_common_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_1up_hidden_in_pole_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_1up_hidden_in_pole_loop), END_LOOP(), }; -// 4160 const BehaviorScript bhvHidden1upInPoleTrigger[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - SET_HITBOX(0x0064, 0x0064), - OBJ_SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HITBOX(/*Radius*/ 100, /*Height*/ 100), + SET_INT(oIntangibleTimer, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_1up_hidden_in_pole_trigger_loop), + CALL_NATIVE(bhv_1up_hidden_in_pole_trigger_loop), END_LOOP(), }; -// 4184 const BehaviorScript bhvHidden1upInPoleSpawner[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_1up_hidden_in_pole_spawner_loop), + CALL_NATIVE(bhv_1up_hidden_in_pole_spawner_loop), END_LOOP(), }; -// 419C const BehaviorScript bhvControllablePlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0800 | OBJ_FLAG_0020 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(hmc_seg7_collision_controllable_platform), - OBJ_SET_POS(), - CALLNATIVE(bhv_controllable_platform_init), + OR_INT(oFlags, (OBJ_FLAG_0800 | OBJ_FLAG_0020 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(hmc_seg7_collision_controllable_platform), + SET_HOME(), + CALL_NATIVE(bhv_controllable_platform_init), BEGIN_LOOP(), - CALLNATIVE(bhv_controllable_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_controllable_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 41D0 const BehaviorScript bhvControllablePlatformSub[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(hmc_seg7_collision_controllable_platform_sub), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(hmc_seg7_collision_controllable_platform_sub), BEGIN_LOOP(), - CALLNATIVE(bhv_controllable_platform_sub_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_controllable_platform_sub_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 41F8 const BehaviorScript bhvBreakableBoxSmall[] = { BEGIN(OBJ_LIST_DESTRUCTIVE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_POS(), - CALLNATIVE(bhv_breakable_box_small_init), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + SET_HOME(), + CALL_NATIVE(bhv_breakable_box_small_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_breakable_box_small_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_breakable_box_small_loop), END_LOOP(), }; -// 4224 const BehaviorScript bhvSlidingSnowMound[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(sl_seg7_collision_sliding_snow_mound), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(sl_seg7_collision_sliding_snow_mound), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_sliding_snow_mound_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_sliding_snow_mound_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4250 const BehaviorScript bhvSnowMoundSpawn[] = { BEGIN(OBJ_LIST_DEFAULT), BEGIN_LOOP(), - CALLNATIVE(bhv_snow_mound_spawn_loop), + CALL_NATIVE(bhv_snow_mound_spawn_loop), END_LOOP(), }; -// 4264 const BehaviorScript bhvWdwSquareFloatingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wdw_seg7_collision_square_floating_platform), - OBJ_SET_FLOAT(oFloatingPlatformUnkFC, 0x0040), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wdw_seg7_collision_square_floating_platform), + SET_FLOAT(oFloatingPlatformUnkFC, 64), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_floating_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_floating_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4294 const BehaviorScript bhvWdwRectangularFloatingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(wdw_seg7_collision_rect_floating_platform), - OBJ_SET_FLOAT(oFloatingPlatformUnkFC, 0x0040), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(wdw_seg7_collision_rect_floating_platform), + SET_FLOAT(oFloatingPlatformUnkFC, 64), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_floating_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_floating_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 42C4 const BehaviorScript bhvJrbFloatingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - COLLISION_DATA(jrb_seg7_collision_floating_platform), - OBJ_SET_FLOAT(oFloatingPlatformUnkFC, 0x0040), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_COLLISION_DATA(jrb_seg7_collision_floating_platform), + SET_FLOAT(oFloatingPlatformUnkFC, 64), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_floating_platform_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_floating_platform_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 42F4 const BehaviorScript bhvArrowLift[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(wdw_seg7_collision_arrow_lift), - OBJ_SET_INT_RAND_RSHIFT(oArrowLiftUnk100, 0x0001, 0x0020), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(wdw_seg7_collision_arrow_lift), + SET_INT_RAND_RSHIFT(oArrowLiftUnk100, /*Minimum*/ 1, /*Right shift*/ 32), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_arrow_lift_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_arrow_lift_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4328 const BehaviorScript bhvOrangeNumber[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_SET_POS(), - CALLNATIVE(bhv_orange_number_init), + SET_HOME(), + CALL_NATIVE(bhv_orange_number_init), BEGIN_LOOP(), - CALLNATIVE(bhv_orange_number_loop), + CALL_NATIVE(bhv_orange_number_loop), END_LOOP(), }; -// 4350 const BehaviorScript bhvMantaRay[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, manta_seg5_anims_05008EB4), - ANIMATE(0x00), - CALLNATIVE(bhv_manta_ray_init), + OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, manta_seg5_anims_05008EB4), + ANIMATE(0), + CALL_NATIVE(bhv_manta_ray_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_manta_ray_loop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_manta_ray_loop), END_LOOP(), }; -// 4380 const BehaviorScript bhvFallingPillar[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - CALLNATIVE(bhv_falling_pillar_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + CALL_NATIVE(bhv_falling_pillar_init), BEGIN_LOOP(), - CALLNATIVE(bhv_falling_pillar_loop), + CALL_NATIVE(bhv_falling_pillar_loop), END_LOOP(), }; -// 43A4 const BehaviorScript bhvFallingPillarHitbox[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_falling_pillar_hitbox_loop), + CALL_NATIVE(bhv_falling_pillar_hitbox_loop), END_LOOP(), }; -// 43C0 const BehaviorScript bhvPillarBase[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(jrb_seg7_collision_pillar_base), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(jrb_seg7_collision_pillar_base), BEGIN_LOOP(), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 43E0 const BehaviorScript bhvJrbFloatingBox[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - COLLISION_DATA(jrb_seg7_collision_floating_box), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_COLLISION_DATA(jrb_seg7_collision_floating_box), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_jrb_floating_box_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_jrb_floating_box_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 440C const BehaviorScript bhvDecorativePendulum[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_decorative_pendulum_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_decorative_pendulum_init), BEGIN_LOOP(), - CALLNATIVE(bhv_decorative_pendulum_loop), + CALL_NATIVE(bhv_decorative_pendulum_loop), END_LOOP(), }; -// 442C const BehaviorScript bhvTreasureChestsShip[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - CALLNATIVE(bhv_treasure_chest_ship_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_treasure_chest_ship_init), BEGIN_LOOP(), - CALLNATIVE(bhv_treasure_chest_ship_loop), + CALL_NATIVE(bhv_treasure_chest_ship_loop), END_LOOP(), }; -// 4450 const BehaviorScript bhvTreasureChestsJrb[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - CALLNATIVE(bhv_treasure_chest_jrb_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_treasure_chest_jrb_init), BEGIN_LOOP(), - CALLNATIVE(bhv_treasure_chest_jrb_loop), + CALL_NATIVE(bhv_treasure_chest_jrb_loop), END_LOOP(), }; -// 4474 const BehaviorScript bhvTreasureChests[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - CALLNATIVE(bhv_treasure_chest_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_treasure_chest_init), BEGIN_LOOP(), - CALLNATIVE(bhv_treasure_chest_loop), + CALL_NATIVE(bhv_treasure_chest_loop), END_LOOP(), }; -// 4498 const BehaviorScript bhvTreasureChestBottom[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - CALLNATIVE(bhv_treasure_chest_bottom_init), - OBJ_SET_INT(oIntangibleTimer, -1), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + CALL_NATIVE(bhv_treasure_chest_bottom_init), + SET_INT(oIntangibleTimer, -1), BEGIN_LOOP(), - CALLNATIVE(bhv_treasure_chest_bottom_loop), + CALL_NATIVE(bhv_treasure_chest_bottom_loop), END_LOOP(), }; -// 44C0 const BehaviorScript bhvTreasureChestTop[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_treasure_chest_top_loop), + CALL_NATIVE(bhv_treasure_chest_top_loop), END_LOOP(), }; -// 44DC const BehaviorScript bhvMips[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, mips_seg6_anims_06015634), - OBJ_SET_INT(oInteractType, INTERACT_GRABBABLE), - DROP_FLOOR(), - SET_HITBOX(0x0032, 0x004B), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(bhv_mips_init), + OR_INT(oFlags, (OBJ_FLAG_HOLDABLE | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, mips_seg6_anims_06015634), + SET_INT(oInteractType, INTERACT_GRABBABLE), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 50, /*Height*/ 75), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(bhv_mips_init), BEGIN_LOOP(), - CALLNATIVE(bhv_mips_loop), + CALL_NATIVE(bhv_mips_loop), END_LOOP(), }; -// 4518 const BehaviorScript bhvYoshi[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, yoshi_seg5_anims_05024100), - INTERACT_TYPE(INTERACT_TEXT), - DROP_FLOOR(), - SET_HITBOX(0x00A0, 0x0096), - ANIMATE(0x00), - OBJ_SET_POS(), - CALLNATIVE(bhv_yoshi_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, yoshi_seg5_anims_05024100), + SET_INTERACT_TYPE(INTERACT_TEXT), + DROP_TO_FLOOR(), + SET_HITBOX(/*Radius*/ 160, /*Height*/ 150), + ANIMATE(0), + SET_HOME(), + CALL_NATIVE(bhv_yoshi_init), BEGIN_LOOP(), - OBJ_SET_INT(oIntangibleTimer, 0), - CALLNATIVE(BehYoshiLoop), + SET_INT(oIntangibleTimer, 0), + CALL_NATIVE(BehYoshiLoop), END_LOOP(), }; -// 4560 const BehaviorScript bhvKoopa[] = { BEGIN(OBJ_LIST_PUSHABLE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, koopa_seg6_anims_06011364), - ANIMATE(0x09), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0032, 0xFE70, 0x0000, 0x0000, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, koopa_seg6_anims_06011364), + ANIMATE(9), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 50, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SCALE(150), - OBJ_SET_FLOAT(oKoopaAgility, 1), - CALLNATIVE(bhv_koopa_init), + SET_FLOAT(oKoopaAgility, 1), + CALL_NATIVE(bhv_koopa_init), BEGIN_LOOP(), - CALLNATIVE(bhv_koopa_update), + CALL_NATIVE(bhv_koopa_update), END_LOOP(), }; -// 45B0 const BehaviorScript bhvKoopaRaceEndpoint[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_CHILD_PARAM(0x0000, MODEL_KOOPA_FLAG, bhvKoopaFlag), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + SPAWN_CHILD_WITH_PARAM(/*Bhv param*/ 0, /*Model*/ MODEL_KOOPA_FLAG, /*Behavior*/ bhvKoopaFlag), BEGIN_LOOP(), - CALLNATIVE(bhv_koopa_race_endpoint_update), + CALL_NATIVE(bhv_koopa_race_endpoint_update), END_LOOP(), }; -// 45D8 const BehaviorScript bhvKoopaFlag[] = { BEGIN(OBJ_LIST_POLELIKE), - INTERACT_TYPE(INTERACT_POLE), - SET_HITBOX(0x0050, 0x02BC), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, koopa_flag_seg6_anims_06001028), - ANIMATE(0x00), + SET_INTERACT_TYPE(INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 700), + SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, koopa_flag_seg6_anims_06001028), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(BehClimbDetectLoop), + CALL_NATIVE(BehClimbDetectLoop), END_LOOP(), }; -// 4614 const BehaviorScript bhvPokey[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_PHYSICS(0x003C, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 60, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_pokey_update), + CALL_NATIVE(bhv_pokey_update), END_LOOP(), }; -// 4648 const BehaviorScript bhvPokeyBodyPart[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x003C, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 60, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BILLBOARD(), BEGIN_LOOP(), - CALLNATIVE(bhv_pokey_body_part_update), + CALL_NATIVE(bhv_pokey_body_part_update), END_LOOP(), }; -// 4678 const BehaviorScript bhvSwoop[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, swoop_seg6_anims_060070D0), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0032, 0x0000, 0xFFCE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, swoop_seg6_anims_060070D0), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 50, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), SCALE(0), BEGIN_LOOP(), - CALLNATIVE(bhv_swoop_update), + CALL_NATIVE(bhv_swoop_update), END_LOOP(), }; -// 46BC const BehaviorScript bhvFlyGuy[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, flyguy_seg8_anims_08011A64), - ANIMATE(0x00), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0032, 0x0000, 0x0000, 0x0000, 0x03E8, 0x0258, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), - OBJ_SET_INT(oInteractionSubtype, INT_SUBTYPE_TWIRL_BOUNCE), - OBJ_SET_FLOAT(oGraphYOffset, 30), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, flyguy_seg8_anims_08011A64), + ANIMATE(0), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 50, /*Gravity*/ 0, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 1000, /*Buoyancy*/ 600, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), + SET_INT(oInteractionSubtype, INT_SUBTYPE_TWIRL_BOUNCE), + SET_FLOAT(oGraphYOffset, 30), SCALE(150), BEGIN_LOOP(), - CALLNATIVE(bhv_fly_guy_update), + CALL_NATIVE(bhv_fly_guy_update), END_LOOP(), }; -// 470C const BehaviorScript bhvGoomba[] = { BEGIN(OBJ_LIST_PUSHABLE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, goomba_seg8_anims_0801DA4C), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0028, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x0000, 0x0000, 0x0000), - CALLNATIVE(bhv_goomba_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, goomba_seg8_anims_0801DA4C), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_goomba_init), BEGIN_LOOP(), - CALLNATIVE(bhv_goomba_update), + CALL_NATIVE(bhv_goomba_update), END_LOOP(), }; -// 4750 const BehaviorScript bhvGoombaTripletSpawner[] = { BEGIN(OBJ_LIST_PUSHABLE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), BEGIN_LOOP(), - CALLNATIVE(bhv_goomba_triplet_spawner_update), + CALL_NATIVE(bhv_goomba_triplet_spawner_update), END_LOOP(), }; -// 476C const BehaviorScript bhvChainChomp[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, chain_chomp_seg6_anims_06025178), - ANIMATE(0x00), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFCE, 0x0000, 0x03E8, 0x00C8, 0x0000, 0x0000), - UNHIDE(), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oGraphYOffset, 0x00F0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, chain_chomp_seg6_anims_06025178), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + HIDE(), + SET_HOME(), + SET_FLOAT(oGraphYOffset, 240), SCALE(200), - OBJ_CHILD_PARAM(0x0000, MODEL_WOODEN_POST, bhvWoodenPost), + SPAWN_CHILD_WITH_PARAM(/*Bhv param*/ 0, /*Model*/ MODEL_WOODEN_POST, /*Behavior*/ bhvWoodenPost), BEGIN_LOOP(), - CALLNATIVE(bhv_chain_chomp_update), + CALL_NATIVE(bhv_chain_chomp_update), END_LOOP(), }; -// 47C4 const BehaviorScript bhvChainChompChainPart[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 0x0028), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_FLOAT(oGraphYOffset, 40), SCALE(200), BEGIN_LOOP(), - CALLNATIVE(bhv_chain_chomp_chain_part_update), + CALL_NATIVE(bhv_chain_chomp_chain_part_update), END_LOOP(), }; -// 47FC const BehaviorScript bhvWoodenPost[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(poundable_pole_collision_06002490), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x0000, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_INT(oNumLootCoins, 5), - DROP_FLOOR(), - OBJ_SET_POS(), + LOAD_COLLISION_DATA(poundable_pole_collision_06002490), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_INT(oNumLootCoins, 5), + DROP_TO_FLOOR(), + SET_HOME(), SCALE(50), BEGIN_LOOP(), - CALLNATIVE(bhv_wooden_post_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_wooden_post_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4848 const BehaviorScript bhvChainChompGate[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(bob_seg7_collision_chain_chomp_gate), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_chain_chomp_gate_init), + LOAD_COLLISION_DATA(bob_seg7_collision_chain_chomp_gate), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_chain_chomp_gate_init), BEGIN_LOOP(), - CALLNATIVE(bhv_chain_chomp_gate_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_chain_chomp_gate_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4878 const BehaviorScript bhvWigglerHead[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, wiggler_seg5_anims_0500EC8C), - OBJ_SET_POS(), - OBJ_PHYSICS(0x003C, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - UNHIDE(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, wiggler_seg5_anims_0500EC8C), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 60, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + HIDE(), SCALE(400), - OBJ_SET_FLOAT(oWigglerFallThroughFloorsHeight, 5000), + SET_FLOAT(oWigglerFallThroughFloorsHeight, 5000), BEGIN_LOOP(), - CALLNATIVE(bhv_wiggler_update), + CALL_NATIVE(bhv_wiggler_update), END_LOOP(), }; -// 48C0 const BehaviorScript bhvWigglerBody[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, wiggler_seg5_anims_0500C874), - OBJ_PHYSICS(0x0000, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, wiggler_seg5_anims_0500C874), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SCALE(400), BEGIN_LOOP(), - CALLNATIVE(bhv_wiggler_body_part_update), + CALL_NATIVE(bhv_wiggler_body_part_update), END_LOOP(), }; -// 48F8 const BehaviorScript bhvEnemyLakitu[] = { BEGIN(OBJ_LIST_PUSHABLE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, lakitu_enemy_seg5_anims_050144D4), - ANIMATE(0x00), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0028, 0x0000, 0xFFCE, 0x0000, 0x0000, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, lakitu_enemy_seg5_anims_050144D4), + ANIMATE(0), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_enemy_lakitu_update), + CALL_NATIVE(bhv_enemy_lakitu_update), END_LOOP(), }; -// 4934 const BehaviorScript bhvCameraLakitu[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, lakitu_seg6_anims_060058F8), - ANIMATE(0x00), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_camera_lakitu_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, lakitu_seg6_anims_060058F8), + ANIMATE(0), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_camera_lakitu_init), BEGIN_LOOP(), - CALLNATIVE(bhv_camera_lakitu_update), + CALL_NATIVE(bhv_camera_lakitu_update), END_LOOP(), }; -// 4968 const BehaviorScript bhvCloud[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_SET_POS(), - OBJ_SET_INT(oOpacity, 0x00F0), + SET_HOME(), + SET_INT(oOpacity, 240), BEGIN_LOOP(), - CALLNATIVE(bhv_cloud_update), + CALL_NATIVE(bhv_cloud_update), END_LOOP(), }; -// 498C const BehaviorScript bhvCloudPart[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_INT(oOpacity, 0x00F0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_INT(oOpacity, 240), BEGIN_LOOP(), - CALLNATIVE(bhv_cloud_part_update), + CALL_NATIVE(bhv_cloud_part_update), END_LOOP(), }; -// 49A8 const BehaviorScript bhvSpiny[] = { BEGIN(OBJ_LIST_PUSHABLE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, spiny_seg5_anims_05016EAC), - ANIMATE(0x00), - OBJ_PHYSICS(0x0028, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, spiny_seg5_anims_05016EAC), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_spiny_update), + CALL_NATIVE(bhv_spiny_update), END_LOOP(), }; -// 49E0 const BehaviorScript bhvMontyMole[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, monty_mole_seg5_anims_05007248), - ANIMATE(0x03), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - UNHIDE(), - OBJ_SET_INT(oIntangibleTimer, -1), - OBJ_SET_FLOAT(oGraphYOffset, 0xFFC4), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, monty_mole_seg5_anims_05007248), + ANIMATE(3), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + HIDE(), + SET_INT(oIntangibleTimer, -1), + SET_FLOAT(oGraphYOffset, -60), SCALE(150), DELAY(1), - CALLNATIVE(bhv_monty_mole_init), + CALL_NATIVE(bhv_monty_mole_init), BEGIN_LOOP(), - CALLNATIVE(bhv_monty_mole_update), + CALL_NATIVE(bhv_monty_mole_update), END_LOOP(), }; -// 4A38 const BehaviorScript bhvMontyMoleHole[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), SCALE(150), BEGIN_LOOP(), - CALLNATIVE(bhv_monty_mole_hole_update), + CALL_NATIVE(bhv_monty_mole_hole_update), END_LOOP(), }; -// 4A58 const BehaviorScript bhvMontyMoleRock[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_PHYSICS(0x001E, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_FLOAT(oGraphYOffset, 0x000A), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_FLOAT(oGraphYOffset, 10), SCALE(200), BEGIN_LOOP(), - CALLNATIVE(bhv_monty_mole_rock_update), + CALL_NATIVE(bhv_monty_mole_rock_update), END_LOOP(), }; -// 4A90 const BehaviorScript bhvPlatformOnTrack[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x0032, 0xFF9C, 0xFFCE, 0x0064, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_platform_on_track_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 50, /*Gravity*/ -100, /*Bounciness*/ -50, /*Drag*/ 100, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_platform_on_track_init), BEGIN_LOOP(), - CALLNATIVE(bhv_platform_on_track_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_platform_on_track_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4AD4 const BehaviorScript bhvTrackBall[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - CALLNATIVE(bhv_init_room), + CALL_NATIVE(bhv_init_room), SCALE(15), BEGIN_LOOP(), - CALLNATIVE(bhv_track_ball_update), + CALL_NATIVE(bhv_track_ball_update), END_LOOP(), }; -// 4AFC const BehaviorScript bhvSeesawPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_seesaw_platform_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_seesaw_platform_init), BEGIN_LOOP(), - CALLNATIVE(bhv_seesaw_platform_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_seesaw_platform_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4B24 const BehaviorScript bhvFerrisWheelAxle[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_ADD_INT(oMoveAngleYaw, 0x4000), - CALLNATIVE(bhv_ferris_wheel_axle_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + ADD_INT(oMoveAngleYaw, 0x4000), + CALL_NATIVE(bhv_ferris_wheel_axle_init), BEGIN_LOOP(), - OBJ_ADD_INT(oFaceAngleRoll, 400), - CALLNATIVE(load_object_collision_model), + ADD_INT(oFaceAngleRoll, 400), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4B4C const BehaviorScript bhvFerrisWheelPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_ferris_wheel_platform_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ferris_wheel_platform_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4B6C const BehaviorScript bhvWaterBombSpawner[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), BEGIN_LOOP(), - CALLNATIVE(bhv_water_bomb_spawner_update), + CALL_NATIVE(bhv_water_bomb_spawner_update), END_LOOP(), }; -// 4B88 const BehaviorScript bhvWaterBomb[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_PHYSICS(0x0078, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 120, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_water_bomb_update), + CALL_NATIVE(bhv_water_bomb_update), END_LOOP(), }; -// 4BB4 const BehaviorScript bhvWaterBombShadow[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), SCALE(150), BEGIN_LOOP(), - CALLNATIVE(bhv_water_bomb_shadow_update), + CALL_NATIVE(bhv_water_bomb_shadow_update), END_LOOP(), }; -// 4BD0 const BehaviorScript bhvTTCRotatingSolid[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x01C2), - CALLNATIVE(bhv_ttc_rotating_solid_init), - OBJ_SET_INT(oTTCRotatingSolidNumTurns, 1), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 450), + CALL_NATIVE(bhv_ttc_rotating_solid_init), + SET_INT(oTTCRotatingSolidNumTurns, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_rotating_solid_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_rotating_solid_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4C04 const BehaviorScript bhvTTCPendulum[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ttc_seg7_collision_clock_pendulum), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oCollisionDistance, 0x05DC), - CALLNATIVE(bhv_ttc_pendulum_init), - OBJ_SET_FLOAT(oTTCPendulumAccelDir, 1), + LOAD_COLLISION_DATA(ttc_seg7_collision_clock_pendulum), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oCollisionDistance, 1500), + CALL_NATIVE(bhv_ttc_pendulum_init), + SET_FLOAT(oTTCPendulumAccelDir, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_pendulum_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_pendulum_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4C3C const BehaviorScript bhvTTCTreadmill[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oCollisionDistance, 0x02EE), - CALLNATIVE(bhv_ttc_treadmill_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oCollisionDistance, 750), + CALL_NATIVE(bhv_ttc_treadmill_init), DELAY(1), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_treadmill_update), - CALLNATIVE(obj_compute_vel_xz), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_treadmill_update), + CALL_NATIVE(obj_compute_vel_xz), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4C74 const BehaviorScript bhvTTCMovingBar[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ttc_seg7_collision_sliding_surface), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x0226), - CALLNATIVE(bhv_ttc_moving_bar_init), + LOAD_COLLISION_DATA(ttc_seg7_collision_sliding_surface), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 550), + CALL_NATIVE(bhv_ttc_moving_bar_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_moving_bar_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_moving_bar_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4CAC const BehaviorScript bhvTTCCog[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oCollisionDistance, 0x0190), - CALLNATIVE(bhv_ttc_cog_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oCollisionDistance, 400), + CALL_NATIVE(bhv_ttc_cog_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_cog_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_cog_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4CD8 const BehaviorScript bhvTTCPitBlock[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x015E), - CALLNATIVE(bhv_ttc_pit_block_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 350), + CALL_NATIVE(bhv_ttc_pit_block_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_pit_block_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_pit_block_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4D08 const BehaviorScript bhvTTCElevator[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ttc_seg7_collision_clock_platform), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x0190), - CALLNATIVE(bhv_ttc_elevator_init), - OBJ_SET_FLOAT(oTTCElevatorDir, 1), + LOAD_COLLISION_DATA(ttc_seg7_collision_clock_platform), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 400), + CALL_NATIVE(bhv_ttc_elevator_init), + SET_FLOAT(oTTCElevatorDir, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_elevator_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_elevator_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4D44 const BehaviorScript bhvTTC2DRotator[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ttc_seg7_collision_clock_main_rotation), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x0708), - CALLNATIVE(bhv_ttc_2d_rotator_init), + LOAD_COLLISION_DATA(ttc_seg7_collision_clock_main_rotation), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 1800), + CALL_NATIVE(bhv_ttc_2d_rotator_init), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_2d_rotator_update), + CALL_NATIVE(bhv_ttc_2d_rotator_update), END_LOOP(), }; -// 4D70 const BehaviorScript bhvTTCSpinner[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ttc_seg7_collision_rotating_clock_platform2), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x01C2), + LOAD_COLLISION_DATA(ttc_seg7_collision_rotating_clock_platform2), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 450), BEGIN_LOOP(), - CALLNATIVE(bhv_ttc_spinner_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_ttc_spinner_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4D9C const BehaviorScript bhvMrBlizzard[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, snowman_seg5_anims_0500D118), - ANIMATE(0x00), - OBJ_SET_POS(), - OBJ_PHYSICS(0x001E, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_mr_blizzard_init), - OBJ_SET_FLOAT(oMrBlizzardUnkF4, 1), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, snowman_seg5_anims_0500D118), + ANIMATE(0), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_mr_blizzard_init), + SET_FLOAT(oMrBlizzardUnkF4, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_mr_blizzard_update), + CALL_NATIVE(bhv_mr_blizzard_update), END_LOOP(), }; -// 4DE8 const BehaviorScript bhvMrBlizzardSnowball[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_PHYSICS(0x001E, 0xFED4, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -300, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SCALE(200), - OBJ_ADD_INT(oMoveAngleYaw, -0x5B58), - OBJ_SET_FLOAT(oForwardVel, 5), - OBJ_SET_FLOAT(oVelY, -1), - OBJ_SET_FLOAT(oGraphYOffset, 10), + ADD_INT(oMoveAngleYaw, -0x5B58), + SET_FLOAT(oForwardVel, 5), + SET_FLOAT(oVelY, -1), + SET_FLOAT(oGraphYOffset, 10), BEGIN_LOOP(), - CALLNATIVE(bhv_mr_blizzard_snowball), + CALL_NATIVE(bhv_mr_blizzard_snowball), END_LOOP(), }; -// 4E2C const BehaviorScript bhvSlidingPlatform2[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - CALLNATIVE(bhv_sliding_plat_2_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + CALL_NATIVE(bhv_sliding_plat_2_init), BEGIN_LOOP(), - CALLNATIVE(bhv_sliding_plat_2_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_sliding_plat_2_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4E58 const BehaviorScript bhvOctagonalPlatformRotating[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - CALLNATIVE(bhv_rotating_octagonal_plat_init), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + CALL_NATIVE(bhv_rotating_octagonal_plat_init), BEGIN_LOOP(), - CALLNATIVE(bhv_rotating_octagonal_plat_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_rotating_octagonal_plat_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4E80 const BehaviorScript bhvAnimatesOnFloorSwitchPress[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_FLOAT(oCollisionDistance, 0x1F40), - CALLNATIVE(bhv_animates_on_floor_switch_press_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_FLOAT(oCollisionDistance, 8000), + CALL_NATIVE(bhv_animates_on_floor_switch_press_init), BEGIN_LOOP(), - CALLNATIVE(bhv_animates_on_floor_switch_press_loop), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_animates_on_floor_switch_press_loop), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4EAC const BehaviorScript bhvActivatedBackAndForthPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - CALLNATIVE(bhv_activated_back_and_forth_platform_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + CALL_NATIVE(bhv_activated_back_and_forth_platform_init), BEGIN_LOOP(), - CALLNATIVE(bhv_activated_back_and_forth_platform_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_activated_back_and_forth_platform_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4ED8 const BehaviorScript bhvRecoveryHeart[] = { BEGIN(OBJ_LIST_LEVEL), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_recovery_heart_loop), + CALL_NATIVE(bhv_recovery_heart_loop), END_LOOP(), }; -// 4EF0 const BehaviorScript bhvWaterBombCannon[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_water_bomb_cannon_loop), + CALL_NATIVE(bhv_water_bomb_cannon_loop), END_LOOP(), }; -// 4F08 const BehaviorScript bhvCannonBarrelBubbles[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_bubble_cannon_barrel_loop), + CALL_NATIVE(bhv_bubble_cannon_barrel_loop), END_LOOP(), }; -// 4F20 const BehaviorScript bhvUnagi[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, unagi_seg5_anims_05012824), - ANIMATE(0x06), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, unagi_seg5_anims_05012824), + ANIMATE(6), + SET_HOME(), SCALE(300), - OBJ_SET_FLOAT(oDrawingDistance, 0x1770), - CALLNATIVE(bhv_unagi_init), + SET_FLOAT(oDrawingDistance, 6000), + CALL_NATIVE(bhv_unagi_init), BEGIN_LOOP(), - CALLNATIVE(bhv_unagi_loop), + CALL_NATIVE(bhv_unagi_loop), END_LOOP(), }; -// 4F58 const BehaviorScript bhvUnagiSubobject[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_unagi_subobject_loop), + CALL_NATIVE(bhv_unagi_subobject_loop), END_LOOP(), }; -// 4F70 const BehaviorScript bhvDorrie[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(dorrie_seg6_collision_0600F644), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, dorrie_seg6_anims_0600F638), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oCollisionDistance, 0x7530), - OBJ_ADD_FLOAT(oPosX, 2000), - CALLNATIVE(bhv_init_room), + LOAD_COLLISION_DATA(dorrie_seg6_collision_0600F644), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, dorrie_seg6_anims_0600F638), + SET_HOME(), + SET_FLOAT(oCollisionDistance, 30000), + ADD_FLOAT(oPosX, 2000), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_dorrie_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_dorrie_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 4FB4 const BehaviorScript bhvHauntedChair[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, chair_seg5_anims_05005784), - ANIMATE(0x00), - OBJ_PHYSICS(0x0028, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_init_room), - CALLNATIVE(bhv_haunted_chair_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, chair_seg5_anims_05005784), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + CALL_NATIVE(bhv_init_room), + CALL_NATIVE(bhv_haunted_chair_init), BEGIN_LOOP(), - CALLNATIVE(bhv_haunted_chair_loop), + CALL_NATIVE(bhv_haunted_chair_loop), END_LOOP(), }; -// 5004 const BehaviorScript bhvMadPiano[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, mad_piano_seg5_anims_05009B14), - OBJ_PHYSICS(0x0028, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - OBJ_ADD_INT(oMoveAngleYaw, 0x4000), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, mad_piano_seg5_anims_05009B14), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + ADD_INT(oMoveAngleYaw, 0x4000), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_mad_piano_update), + CALL_NATIVE(bhv_mad_piano_update), END_LOOP(), }; -// 504C const BehaviorScript bhvFlyingBookend[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, bookend_seg5_anims_05002540), - ANIMATE(0x00), - OBJ_PHYSICS(0x003C, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_INT(oMoveFlags, 0), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, bookend_seg5_anims_05002540), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 60, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_INT(oMoveFlags, 0), SCALE(70), - CALLNATIVE(bhv_init_room), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_flying_bookend_loop), + CALL_NATIVE(bhv_flying_bookend_loop), END_LOOP(), }; -// 5094 const BehaviorScript bhvBookendSpawn[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_bookend_spawn_loop), + CALL_NATIVE(bhv_bookend_spawn_loop), END_LOOP(), }; -// 50B4 const BehaviorScript bhvHauntedBookshelfManager[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_haunted_bookshelf_manager_loop), + CALL_NATIVE(bhv_haunted_bookshelf_manager_loop), END_LOOP(), }; -// 50D4 const BehaviorScript bhvBookSwitch[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_SET_FLOAT(oGraphYOffset, 30), - OBJ_ADD_INT(oMoveAngleYaw, 0x4000), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_FLOAT(oGraphYOffset, 30), + ADD_INT(oMoveAngleYaw, 0x4000), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_book_switch_loop), + CALL_NATIVE(bhv_book_switch_loop), END_LOOP(), }; -// 5100 const BehaviorScript bhvFirePiranhaPlant[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, piranha_plant_seg6_anims_0601C31C), - ANIMATE(0x00), - OBJ_SET_POS(), - UNHIDE(), - CALLNATIVE(bhv_fire_piranha_plant_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, piranha_plant_seg6_anims_0601C31C), + ANIMATE(0), + SET_HOME(), + HIDE(), + CALL_NATIVE(bhv_fire_piranha_plant_init), BEGIN_LOOP(), - CALLNATIVE(bhv_fire_piranha_plant_update), + CALL_NATIVE(bhv_fire_piranha_plant_update), END_LOOP(), }; -// 5138 const BehaviorScript bhvSmallPiranhaFlame[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_small_piranha_flame_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_small_piranha_flame_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 516C const BehaviorScript bhvFireSpitter[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), SCALE(40), BEGIN_LOOP(), - CALLNATIVE(bhv_fire_spitter_update), + CALL_NATIVE(bhv_fire_spitter_update), END_LOOP(), }; -// 518C const BehaviorScript bhvFlyguyFlame[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BILLBOARD(), - OBJ_PHYSICS(0x0000, 0x00C8, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ 200, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_fly_guy_flame_loop), - OBJ_ADD_INT(oAnimState, 1), + CALL_NATIVE(bhv_fly_guy_flame_loop), + ADD_INT(oAnimState, 1), END_LOOP(), }; -// 51C0 const BehaviorScript bhvSnufit[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_PHYSICS(0x001E, 0x0000, 0xFFCE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - OBJ_SET_INT(oSnufitUnkF4, 0), - CALLNATIVE(bhv_snufit_loop), + SET_INT(oSnufitUnkF4, 0), + CALL_NATIVE(bhv_snufit_loop), END_LOOP(), }; -// 51FC const BehaviorScript bhvSnufitBalls[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), - OBJ_PHYSICS(0x000A, 0x0000, 0xFFCE, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - CALLNATIVE(bhv_init_room), - OBJ_SET_FLOAT(oGraphYOffset, 0x000A), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 10, /*Gravity*/ 0, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_init_room), + SET_FLOAT(oGraphYOffset, 10), SCALE(10), BEGIN_LOOP(), - CALLNATIVE(bhv_snufit_balls_loop), + CALL_NATIVE(bhv_snufit_balls_loop), END_LOOP(), }; -// 523C const BehaviorScript bhvHorizontalGrindel[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(ssl_seg7_collision_grindel), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0028, 0xFE70, 0x0000, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), + LOAD_COLLISION_DATA(ssl_seg7_collision_grindel), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 40, /*Gravity*/ -400, /*Bounciness*/ 0, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SCALE(90), - CALLNATIVE(bhv_horizontal_grindel_init), + CALL_NATIVE(bhv_horizontal_grindel_init), BEGIN_LOOP(), - CALLNATIVE(obj_update_floor_and_walls), - CALLNATIVE(bhv_horizontal_grindel_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(obj_update_floor_and_walls), + CALL_NATIVE(bhv_horizontal_grindel_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 5294 const BehaviorScript bhvEyerokBoss[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_eyerok_boss_loop), + CALL_NATIVE(bhv_eyerok_boss_loop), END_LOOP(), }; -// 52B0 const BehaviorScript bhvEyerokHand[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, eyerok_seg5_anims_050116E4), - ANIMATE(0x06), - OBJ_PHYSICS(0x0096, 0x0000, 0x0000, 0x0000, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - OBJ_SET_INT(oAnimState, 3), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, eyerok_seg5_anims_050116E4), + ANIMATE(6), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 150, /*Gravity*/ 0, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + SET_INT(oAnimState, 3), BEGIN_LOOP(), - CALLNATIVE(bhv_eyerok_hand_loop), + CALL_NATIVE(bhv_eyerok_hand_loop), END_LOOP(), }; -// 52F0 const BehaviorScript bhvKlepto[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, klepto_seg5_anims_05008CFC), - ANIMATE(0x00), - OBJ_PHYSICS(0x0064, 0x0000, 0xFFEC, 0x03E8, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_POS(), - CALLNATIVE(bhv_klepto_init), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, klepto_seg5_anims_05008CFC), + ANIMATE(0), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 100, /*Gravity*/ 0, /*Bounciness*/ -20, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_HOME(), + CALL_NATIVE(bhv_klepto_init), BEGIN_LOOP(), - CALLNATIVE(bhv_klepto_update), + CALL_NATIVE(bhv_klepto_update), END_LOOP(), }; -// 5334 const BehaviorScript bhvBird[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, birds_seg5_anims_050009E8), - ANIMATE(0x00), - UNHIDE(), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, birds_seg5_anims_050009E8), + ANIMATE(0), + HIDE(), SCALE(70), BEGIN_LOOP(), - CALLNATIVE(bhv_bird_update), + CALL_NATIVE(bhv_bird_update), END_LOOP(), }; -// 5360 const BehaviorScript bhvRacingPenguin[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, penguin_seg5_anims_05008B74), - ANIMATE(0x03), - OBJ_PHYSICS(0x012C, 0xFCE0, 0xFFFB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, penguin_seg5_anims_05008B74), + ANIMATE(3), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 300, /*Gravity*/ -800, /*Bounciness*/ -5, /*Drag*/ 0, /*Friction*/ 0, /*Buoyancy*/ 0, /*Unused*/ 0, 0), SCALE(400), - CALLNATIVE(bhv_racing_penguin_init), + CALL_NATIVE(bhv_racing_penguin_init), BEGIN_LOOP(), - CALLNATIVE(bhv_racing_penguin_update), + CALL_NATIVE(bhv_racing_penguin_update), END_LOOP(), }; -// 53A4 const BehaviorScript bhvPenguinRaceFinishLine[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_ACTIVE_FROM_AFAR | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_penguin_race_finish_line_update), + CALL_NATIVE(bhv_penguin_race_finish_line_update), END_LOOP(), }; -// 53BC const BehaviorScript bhvPenguinRaceShortcutCheck[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BEGIN_LOOP(), - CALLNATIVE(bhv_penguin_race_shortcut_check_update), + CALL_NATIVE(bhv_penguin_race_shortcut_check_update), END_LOOP(), }; -// 53D4 const BehaviorScript bhvCoffinManager[] = { BEGIN(OBJ_LIST_SURFACE), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - CALLNATIVE(bhv_init_room), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_coffin_manager_loop), + CALL_NATIVE(bhv_coffin_manager_loop), END_LOOP(), }; -// 53F4 const BehaviorScript bhvCoffin[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(bbh_seg7_collision_coffin), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - CALLNATIVE(bhv_init_room), + LOAD_COLLISION_DATA(bbh_seg7_collision_coffin), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALLNATIVE(bhv_coffin_loop), + CALL_NATIVE(bhv_coffin_loop), END_LOOP(), }; -// 5420 const BehaviorScript bhvClamShell[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - DROP_FLOOR(), - OBJ_SET_ANIMS(oAnimations, clam_shell_seg5_anims_05001744), - OBJ_SET_FLOAT(oGraphYOffset, 0x000A), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + DROP_TO_FLOOR(), + LOAD_ANIMATIONS(oAnimations, clam_shell_seg5_anims_05001744), + SET_FLOAT(oGraphYOffset, 10), BEGIN_LOOP(), - CALLNATIVE(bhv_clam_loop), + CALL_NATIVE(bhv_clam_loop), END_LOOP(), }; -// 5448 const BehaviorScript bhvSkeeter[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, skeeter_seg6_anims_06007DE0), - OBJ_SET_POS(), - OBJ_PHYSICS(0x00B4, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x04B0, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, skeeter_seg6_anims_06007DE0), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 180, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 1200, /*Unused*/ 0, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_skeeter_update), + CALL_NATIVE(bhv_skeeter_update), END_LOOP(), }; -// 5480 const BehaviorScript bhvSkeeterWave[] = { BEGIN(OBJ_LIST_UNIMPORTANT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_skeeter_wave_update), + CALL_NATIVE(bhv_skeeter_wave_update), END_LOOP(), }; -// 5498 const BehaviorScript bhvSwingPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(rr_seg7_collision_pendulum), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_FLOAT(oCollisionDistance, 0x07D0), - CALLNATIVE(bhv_swing_platform_init), + LOAD_COLLISION_DATA(rr_seg7_collision_pendulum), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_FLOAT(oCollisionDistance, 2000), + CALL_NATIVE(bhv_swing_platform_init), BEGIN_LOOP(), - CALLNATIVE(bhv_swing_platform_update), - CALLNATIVE(load_object_collision_model), + CALL_NATIVE(bhv_swing_platform_update), + CALL_NATIVE(load_object_collision_model), END_LOOP(), }; -// 54CC const BehaviorScript bhvDonutPlatformSpawner[] = { BEGIN(OBJ_LIST_SPAWNER), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_donut_platform_spawner_update), + CALL_NATIVE(bhv_donut_platform_spawner_update), END_LOOP(), }; -// 54E4 const BehaviorScript bhvDonutPlatform[] = { BEGIN(OBJ_LIST_SURFACE), - COLLISION_DATA(rr_seg7_collision_donut_platform), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), + LOAD_COLLISION_DATA(rr_seg7_collision_donut_platform), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), BEGIN_LOOP(), - CALLNATIVE(bhv_donut_platform_update), + CALL_NATIVE(bhv_donut_platform_update), END_LOOP(), }; -// 5508 const BehaviorScript bhvDDDPole[] = { BEGIN(OBJ_LIST_POLELIKE), - INTERACT_TYPE(INTERACT_POLE), - SET_HITBOX(0x0050, 0x0320), - OBJ_SET_INT(oIntangibleTimer, 0), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_POS(), - CALLNATIVE(bhv_ddd_pole_init), - OBJ_SET_FLOAT(oDDDPoleVel, 10), + SET_INTERACT_TYPE(INTERACT_POLE), + SET_HITBOX(/*Radius*/ 80, /*Height*/ 800), + SET_INT(oIntangibleTimer, 0), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + SET_HOME(), + CALL_NATIVE(bhv_ddd_pole_init), + SET_FLOAT(oDDDPoleVel, 10), BEGIN_LOOP(), - CALLNATIVE(bhv_ddd_pole_update), - CALLNATIVE(BehClimbDetectLoop), + CALL_NATIVE(bhv_ddd_pole_update), + CALL_NATIVE(BehClimbDetectLoop), END_LOOP(), }; -// 554C const BehaviorScript bhvRedCoinStarMarker[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - DROP_FLOOR(), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + DROP_TO_FLOOR(), SCALE(150), - OBJ_SET_INT(oFaceAnglePitch, 0x4000), - OBJ_ADD_FLOAT(oPosY, 60), - CALLNATIVE(bhv_red_coin_star_marker_init), + SET_INT(oFaceAnglePitch, 0x4000), + ADD_FLOAT(oPosY, 60), + CALL_NATIVE(bhv_red_coin_star_marker_init), BEGIN_LOOP(), - OBJ_ADD_INT(oFaceAngleYaw, 0x100), + ADD_INT(oFaceAngleYaw, 0x100), END_LOOP(), }; -// 5578 const BehaviorScript bhvTripletButterfly[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, butterfly_seg3_anims_030056B0), - ANIMATE(0x00), - UNHIDE(), - OBJ_SET_POS(), - OBJ_PHYSICS(0x0000, 0x0000, 0x0000, 0x0000, 0x03E8, 0x00C8, 0x0000, 0x0000), - OBJ_SET_FLOAT(oTripletButterflyScale, 1), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, butterfly_seg3_anims_030056B0), + ANIMATE(0), + HIDE(), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ 0, /*Bounciness*/ 0, /*Drag*/ 0, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + SET_FLOAT(oTripletButterflyScale, 1), BEGIN_LOOP(), - CALLNATIVE(bhv_triplet_butterfly_update), + CALL_NATIVE(bhv_triplet_butterfly_update), END_LOOP(), }; -// 55BC const BehaviorScript bhvBubba[] = { BEGIN(OBJ_LIST_GENACTOR), - OBJ_OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_POS(), - OBJ_PHYSICS(0x00C8, 0xFE70, 0xFFCE, 0x03E8, 0x03E8, 0x0000, 0x0000, 0x0000), + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + SET_HOME(), + SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 200, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 0, /*Unused*/ 0, 0), SCALE(50), BEGIN_LOOP(), - CALLNATIVE(bhv_bubba_loop), + CALL_NATIVE(bhv_bubba_loop), END_LOOP(), }; -// 55F0 const BehaviorScript bhvBeginningLakitu[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, lakitu_seg6_anims_060058F8), - ANIMATE(0x00), - OBJ_SET_FLOAT(oOpacity, 0x0000), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, lakitu_seg6_anims_060058F8), + ANIMATE(0), + SET_FLOAT(oOpacity, 0), BEGIN_LOOP(), - CALLNATIVE(bhv_intro_lakitu_loop), + CALL_NATIVE(bhv_intro_lakitu_loop), END_LOOP(), }; -// 5618 const BehaviorScript bhvBeginningPeach[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), - OBJ_SET_ANIMS(oAnimations, peach_seg5_anims_0501C41C), - ANIMATE(0x00), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + LOAD_ANIMATIONS(oAnimations, peach_seg5_anims_0501C41C), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(bhv_intro_peach_loop), + CALL_NATIVE(bhv_intro_peach_loop), END_LOOP(), }; -// 563C const BehaviorScript bhvEndBirds1[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, birds_seg5_anims_050009E8), - ANIMATE(0x00), + OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, birds_seg5_anims_050009E8), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(bhv_end_birds_1_loop), + CALL_NATIVE(bhv_end_birds_1_loop), END_LOOP(), }; -// 5660 const BehaviorScript bhvEndBirds2[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - OBJ_SET_ANIMS(oAnimations, birds_seg5_anims_050009E8), - ANIMATE(0x00), + OR_INT(oFlags, (OBJ_FLAG_0010 | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), + LOAD_ANIMATIONS(oAnimations, birds_seg5_anims_050009E8), + ANIMATE(0), BEGIN_LOOP(), - CALLNATIVE(bhv_end_birds_2_loop), + CALL_NATIVE(bhv_end_birds_2_loop), END_LOOP(), }; -// 5684 const BehaviorScript bhvIntroScene[] = { BEGIN(OBJ_LIST_DEFAULT), - OBJ_OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), + OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), BEGIN_LOOP(), - CALLNATIVE(bhv_intro_scene_loop), + CALL_NATIVE(bhv_intro_scene_loop), END_LOOP(), }; diff --git a/enhancements/debug_box.h b/enhancements/debug_box.h new file mode 100644 index 0000000..ae70a02 --- /dev/null +++ b/enhancements/debug_box.h @@ -0,0 +1,23 @@ +#ifndef _DEBUG_DRAW_CUBE_H +#define _DEBUG_DRAW_CUBE_H + +/** + * @file debug_box.h + * Draws debug boxes, see debug_box.inc.c for details + */ + +#include "types.h" + +/** + * The max amount of debug boxes before debug_box() just returns. + * You can set this to something higher like 1000, but things like text will stop rendering. + */ +#define MAX_DEBUG_BOXES 100 + +void debug_box(Vec3f center, Vec3f bounds); +void debug_box_rot(Vec3f center, Vec3f bounds, s16 yaw); + +void debug_box_pos(Vec3f pMin, Vec3f pMax); +void debug_box_pos_rot(Vec3f pMin, Vec3f pMax, s16 yaw); + +#endif /* _DEBUG_DRAW_CUBE_H */ diff --git a/enhancements/debug_box.inc.c b/enhancements/debug_box.inc.c new file mode 100644 index 0000000..1f13054 --- /dev/null +++ b/enhancements/debug_box.inc.c @@ -0,0 +1,248 @@ +#include + +#include "sm64.h" +#include "game/game.h" +#include "game/geo_misc.h" +#include "engine/math_util.h" + +#include "debug_box.h" + +/** + * @file debug_box.inc.c + * Draws 3D boxes for debugging purposes. + * + * How to use: + * + * In area.c, add this to the list of includes: + * + * #include "enhancements/debug_box.inc.c" + * + * Then in render_game() in the same file, add a call to render_debug_boxes(): + * + * void render_game(void) { + * if (gCurrentArea != NULL && !gWarpTransition.pauseRendering) { + * geo_process_root(...); + * + * render_debug_boxes(); // add here + * + * gSPViewport(...); + * gDPSetScissor(...); + * //... + * + * Now just call debug_box() whenever you want to draw one! + * + * debug_box by default takes two arguments: a center and bounds vec3f. + * This will draw a box starting from the point (center - bounds) to (center + bounds). + * + * Use debug_box_rot to draw a box rotated in the xz-plane. + * + * If you want to draw a box by specifying min and max points, use debug_box_pos() instead. + */ + +/** + * Internal struct containing box info + */ +struct DebugBox { + Vec3s center; + Vec3s bounds; + s16 yaw; +}; + +struct DebugBox *sBoxes[MAX_DEBUG_BOXES]; +s16 sNumBoxes = 0; + +extern Mat4 gMatStack[32]; //XXX: Hack + +/** + * The debug boxes' transparency + */ +#define DBG_BOX_ALPHA 0x7F +/** + * The debug boxes' color + */ +#define DBG_BOX_COL 0xFF, 0x00, 0x00, DBG_BOX_ALPHA + +/** + * Sets up the RCP for drawing the boxes + */ +static const Gfx dl_debug_box_begin[] = { + gsDPPipeSync(), +#if DBG_BOX_ALPHA < 0xFF + gsDPSetRenderMode(G_RM_ZB_XLU_SURF, G_RM_NOOP2), +#else + gsDPSetRenderMode(G_RM_ZB_OPA_SURF, G_RM_NOOP2), +#endif + gsSPClearGeometryMode(G_LIGHTING | G_CULL_BACK), + gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH), + gsSPTexture(0, 0, 0, 0, G_OFF), + gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), + gsSPEndDisplayList(), +}; + +/** + * Actually draws the box + */ +static const Gfx dl_debug_draw_box[] = { + gsSP2Triangles( 0, 1, 2, 0x0, 2, 1, 3, 0x0), + gsSP2Triangles( 2, 3, 6, 0x0, 6, 3, 7, 0x0), + + gsSP2Triangles( 4, 0, 2, 0x0, 2, 6, 4, 0x0), + gsSP2Triangles( 1, 5, 3, 0x0, 3, 5, 7, 0x0), + + gsSP2Triangles( 1, 0, 4, 0x0, 1, 4, 5, 0x0), + gsSP2Triangles( 5, 4, 6, 0x0, 5, 6, 7, 0x0), + + gsSPEndDisplayList(), +}; + +/** + * Adds a box to the list to be rendered this frame. + * + * If there are already MAX_DEBUG_BOXES boxes, does nothing. + */ +static void append_debug_box(Vec3f center, Vec3f bounds, s16 yaw) +{ + if (sNumBoxes >= MAX_DEBUG_BOXES || + (sBoxes[sNumBoxes] = mem_pool_alloc(gEffectsMemoryPool, sizeof(struct DebugBox))) == NULL) { + return; + } + + vec3f_to_vec3s(sBoxes[sNumBoxes]->center, center); + vec3f_to_vec3s(sBoxes[sNumBoxes]->bounds, bounds); + + sBoxes[sNumBoxes]->yaw = yaw; + + ++sNumBoxes; +} + +/** + * Draws a debug box from (center - bounds) to (center + bounds) + * To draw a rotated box, use debug_box_rot() + * + * @see debug_box_rot() + */ +void debug_box(Vec3f center, Vec3f bounds) +{ + append_debug_box(center, bounds, 0); +} + +/** + * Draws a debug box from (center - bounds) to (center + bounds), rotating it by `yaw` + */ +void debug_box_rot(Vec3f center, Vec3f bounds, s16 yaw) +{ + append_debug_box(center, bounds, yaw); +} + +/** + * Draws a debug box from pMin to pMax + * To draw a rotated box this way, use debug_box_pos_rot() + * + * @see debug_box_pos_rot() + */ +void debug_box_pos(Vec3f pMin, Vec3f pMax) +{ + debug_box_pos_rot(pMin, pMax, 0); +} + +/** + * Draws a debug box from pMin to pMax, rotating it in the xz-plane by `yaw` + */ +void debug_box_pos_rot(Vec3f pMin, Vec3f pMax, s16 yaw) +{ + Vec3f center, bounds; + + bounds[0] = pMax[0] - pMin[0] / 2.0f; + bounds[1] = pMax[1] - pMin[1] / 2.0f; + bounds[2] = pMax[2] - pMin[2] / 2.0f; + + center[0] = pMin[0] + bounds[0]; + center[1] = pMin[1] + bounds[1]; + center[2] = pMin[2] + bounds[2]; + + append_debug_box(center, bounds, yaw); +} + +static void render_box(struct DebugBox *box) +{ + Vtx *verts = alloc_display_list(8 * sizeof(Vtx)); + Mtx *translate; + Mtx *rotate; + Mtx *translateback; + s32 x0 = box->center[0], + y0 = box->center[1], + z0 = box->center[2]; + + s32 xb = box->bounds[0], + yb = box->bounds[1], + zb = box->bounds[2]; + + if (verts != NULL) { + if (box->yaw != 0) { + // Translate to the origin, rotate, then translate back, effectively rotating the box about + // its center + translate = alloc_display_list(sizeof(Mtx)); + rotate = alloc_display_list(sizeof(Mtx)); + translateback = alloc_display_list(sizeof(Mtx)); + + guTranslate(translate, box->center[0], box->center[1], box->center[2]); + guRotate(rotate, box->yaw / (float)0x10000 * 360.0f, 0, 1.0f, 0); + guTranslate(translateback, -box->center[0], -box->center[1], -box->center[2]); + + gSPMatrix(gDisplayListHead++, translate, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH); + gSPMatrix(gDisplayListHead++, rotate, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); + gSPMatrix(gDisplayListHead++, translateback, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); + } + +#define DBG_BOX_VTX(i, x, y, z) make_vertex(verts, i, x, y, z, 0, 0, DBG_BOX_COL) + DBG_BOX_VTX(0, x0 - xb, y0 + yb, z0 - zb); + DBG_BOX_VTX(1, x0 + xb, y0 + yb, z0 - zb); + DBG_BOX_VTX(2, x0 - xb, y0 - yb, z0 - zb); + DBG_BOX_VTX(3, x0 + xb, y0 - yb, z0 - zb); + DBG_BOX_VTX(4, x0 - xb, y0 + yb, z0 + zb); + DBG_BOX_VTX(5, x0 + xb, y0 + yb, z0 + zb); + DBG_BOX_VTX(6, x0 - xb, y0 - yb, z0 + zb); + DBG_BOX_VTX(7, x0 + xb, y0 - yb, z0 + zb); +#undef DBG_BOX_VTX + + gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(verts), 8, 0); + + gSPDisplayList(gDisplayListHead++, dl_debug_draw_box); + + if (box->yaw != 0) { + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + } + } +} + +void render_debug_boxes() +{ + s32 i; + Mtx *mtx; + + if (sNumBoxes == 0) { + return; + } + + mtx = alloc_display_list(sizeof(Mtx)); + if (mtx == NULL) { + for (i = 0; i < sNumBoxes; ++i) { + mem_pool_free(gEffectsMemoryPool, sBoxes[i]); + } + sNumBoxes = 0; + return; + } + + //XXX: This is hacky. Ths camera's look-at matrix is stored in gMatStack[1], so this is a simple way + // of using it without reconstructing the matrix. + mtxf_to_mtx(mtx, gMatStack[1]); + gSPMatrix(gDisplayListHead++, mtx, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); + gSPDisplayList(gDisplayListHead++, dl_debug_box_begin); + + for (i = 0; i < sNumBoxes; ++i) { + render_box(sBoxes[i]); + mem_pool_free(gEffectsMemoryPool, sBoxes[i]); + } + + sNumBoxes = 0; +} diff --git a/enhancements/mem_error_screen.inc.c b/enhancements/mem_error_screen.inc.c index 47e0f33..68b80a3 100644 --- a/enhancements/mem_error_screen.inc.c +++ b/enhancements/mem_error_screen.inc.c @@ -9,13 +9,14 @@ * Make sure that USE_EXT_RAM is defined in include/segments.h #define USE_EXT_RAM * - * There are 6 files you will need to edit: + * There are 7 files you will need to edit: * src/game/main.c * src/engine/level_script.h * include/text_strings.h.in - * levels/entry.s - * levels/intro/script.s - * levels/intro/geo.s + * levels/entry.c + * levels/intro/script.c + * levels/intro/geo.c + * levels/intro/header.h * * First, in main.c, you will need to add this line below the includes: #include "../enhancements/mem_error_screen.inc.c" @@ -45,48 +46,55 @@ #define TEXT_PJ64 _("If you are using PJ64 1.6, go to:\nOptions > Settings > Rom Settings Tab > Memory Size\nthen select 8 MB from the drop-down box.") #define TEXT_PJ64_2 _("If you are using PJ64 2.X, go to:\nOptions > Settings > Config: > Memory Size, select 8 MB") * - * In levels/entry.s, simply append the following to the file: - glabel level_script_entry_error_screen - init_level - sleep 2 - blackout FALSE - set_reg 0 - execute 0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen - jump level_script_entry_error_screen - .align 4 + * In levels/entry.c, simply append the following to the file: + const LevelScript level_script_entry_error_screen[] { + INIT_LEVEL(), + SLEEP(2), + BLACKOUT(FALSE), + SET_REG(0), + EXECUTE(0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen), + JUMP(level_script_entry_error_screen), + }; * - * In levels/intro/script.s, add the following to the top of the file: - glabel level_intro_entry_error_screen - init_level - fixed_load _goddardSegmentStart, _goddardSegmentRomStart, _goddardSegmentRomEnd - load_mio0 0x07, _intro_segment_7SegmentRomStart, _intro_segment_7SegmentRomEnd - alloc_level_pool + * In levels/intro/script.c, add the following to the top of the file: + const LevelScript level_intro_entry_error_screen[] { + INIT_LEVEL(), + FIXED_LOAD(_goddardSegmentStart, _goddardSegmentRomStart, _goddardSegmentRomEnd), + LOAD_MIO0(0x07, _intro_segment_7SegmentRomStart, _intro_segment_7SegmentRomEnd), + ALLOC_LEVEL_POOL(), - area 1, intro_geo_error_screen - end_area + AREA(1, intro_geo_error_screen), + END_AREA(), - free_level_pool - load_area 1 - sleep 32767 - exit_and_execute 0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen + FREE_LEVEL_POOL(), + LOAD_AREA(1), + SLEEP(32767), + EXIT_AND_EXECUTE(0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen), + }; * - * Finally, add the following to the top of levels/intro/geo.s: - glabel intro_geo_error_screen - geo_node_screen_area 0, 160, 120, 160, 120 - geo_open_node - geo_zbuffer 0 - geo_open_node - geo_node_ortho 100 - geo_open_node - geo_background 0x0001 - geo_close_node - geo_close_node - geo_zbuffer 0 - geo_open_node - geo_asm 0, geo18_display_error_message - geo_close_node - geo_close_node - geo_end + * Add the following to the top of levels/intro/geo.c: + const GeoLayout intro_geo_error_screen[] { + GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2), + GEO_OPEN_NODE(), + GEO_ZBUFFER(0), + GEO_OPEN_NODE(), + GEO_NODE_ORTHO(100), + GEO_OPEN_NODE(), + GEO_BACKGROUND_COLOR(0x0001), + GEO_CLOSE_NODE(), + GEO_CLOSE_NODE(), + GEO_ZBUFFER(0), + GEO_OPEN_NODE(), + GEO_ASM(0, geo18_display_error_message), + GEO_CLOSE_NODE(), + GEO_CLOSE_NODE(), + GEO_END(), + }; + + * Finally, add the following to the bottom of levels/intro/header.h: + extern const GeoLayout intro_geo_error_screen[]; + extern const LevelScript level_intro_entry_error_screen[]; + extern Gfx *geo18_display_error_message(u32 run, UNUSED struct GraphNode *sp44, UNUSED u32 sp48); */ /* clang-format on */ diff --git a/extract_assets.py b/extract_assets.py index 9ee2806..512767d 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -20,6 +20,12 @@ def read_local_asset_list(f): def asset_needs_update(asset, version): + if version <= 4 and asset in ["textures/mountain/ttm_textures.01800.rgba16.png", "textures/mountain/ttm_textures.05800.rgba16.png"]: + return True + if version <= 3 and asset == "textures/cave/hmc_textures.01800.rgba16.png": + return True + if version <= 2 and asset == "textures/inside/inside_castle_textures.09000.rgba16.png": + return True if version <= 1 and asset.endswith(".m64"): return True if version <= 0 and asset.endswith(".aiff"): @@ -51,7 +57,7 @@ def clean_assets(local_asset_file): def main(): # In case we ever need to change formats of generated files, we keep a # revision ID in the local asset file. - new_version = 2 + new_version = 5 try: local_asset_file = open(".assets-local.txt") diff --git a/include/behavior_data.h b/include/behavior_data.h index 132e3ff..d347d09 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -50,7 +50,7 @@ extern const BehaviorScript bhvWarp[]; extern const BehaviorScript bhvWarpPipe[]; extern const BehaviorScript bhvWhitePuffExplosion[]; extern const BehaviorScript bhvSpawnedStar[]; -extern const BehaviorScript bhvUnused080C[]; +extern const BehaviorScript bhvSpawnedStarNoLevelExit[]; extern const BehaviorScript bhvMrIBlueCoin[]; extern const BehaviorScript bhvCoinInsideBoo[]; extern const BehaviorScript bhvCoinFormationSpawn[]; diff --git a/include/course_table.h b/include/course_table.h index c39775f..58b3090 100644 --- a/include/course_table.h +++ b/include/course_table.h @@ -4,17 +4,16 @@ // Start of the 3 cap courses in a row. #define COURSE_CAP_COURSES COURSE_COTMC -#define DEFINE_COURSE(courseenum, _1, _2, _3, _4) courseenum, +#define DEFINE_COURSE(courseenum, _1) courseenum, #define DEFINE_COURSES_END() \ COURSE_BONUS_STAGES, \ COURSE_STAGES_MAX = COURSE_BONUS_STAGES - 1, \ COURSE_STAGES_COUNT = COURSE_STAGES_MAX, -#define DEFINE_BONUS_COURSE(courseenum, _1, _2, _3, _4) courseenum, +#define DEFINE_BONUS_COURSE(courseenum, _1) courseenum, enum CourseNum { - COURSE_NONE, // (0) Overworld (Castle Grounds, etc) #include "levels/course_defines.h" COURSE_END, // To mark end + 1 for marking max and count. // Todo: clean this up. This is still bad. Which diff --git a/include/geo_commands.h b/include/geo_commands.h index bf89d46..c83d043 100644 --- a/include/geo_commands.h +++ b/include/geo_commands.h @@ -163,12 +163,12 @@ * 0x0F: Create a camera scene graph node. * 0x01: unused * 0x02: s16 camera type - * 0x04: s16 fromX - * 0x06: s16 fromY - * 0x08: s16 fromZ - * 0x0A: s16 toX - * 0x0C: s16 toY - * 0x0E: s16 toZ + * 0x04: s16 posX + * 0x06: s16 posY + * 0x08: s16 posZ + * 0x0A: s16 focusX + * 0x0C: s16 focusY + * 0x0E: s16 focusZ * 0x10: GraphNodeFunc function */ #define GEO_CAMERA(type, x1, y1, z1, x2, y2, z2, function) \ diff --git a/include/surface_terrains.h b/include/surface_terrains.h index 296b835..bae4df2 100644 --- a/include/surface_terrains.h +++ b/include/surface_terrains.h @@ -46,7 +46,7 @@ #define SURFACE_BOSS_FIGHT_CAMERA 0x0065 // Wide camera for BOB and WF bosses #define SURFACE_CAMERA_FREE_ROAM 0x0066 // Free roam camera for THI and TTC #define SURFACE_THI3_WALLKICK 0x0068 // Surface where there's a wall kick section in THI 3rd area, has no action defined -#define SURFACE_CAMERA_PLATFORM 0x0069 // Surface that enables far camera for platforms, used in THI +#define SURFACE_CAMERA_8_DIR 0x0069 // Surface that enables far camera for platforms, used in THI #define SURFACE_CAMERA_MIDDLE 0x006E // Surface camera that returns to the middle, used on the 4 pillars of SSL #define SURFACE_CAMERA_ROTATE_RIGHT 0x006F // Surface camera that rotates to the right (Bowser 1 & THI) #define SURFACE_CAMERA_ROTATE_LEFT 0x0070 // Surface camera that rotates to the left (BOB & TTM) diff --git a/include/text_menu_strings.h.in b/include/text_menu_strings.h.in index 7015a8e..04cb329 100644 --- a/include/text_menu_strings.h.in +++ b/include/text_menu_strings.h.in @@ -10,7 +10,7 @@ */ #define TEXT_JPHUD_MARIO _("マリオ") #define TEXT_JPHUD_SELECT_FILE _("ファイルセレクト") -#define TEXT_JPHUD_CHECK_FILE _("どのスコアをみる?") +#define TEXT_JPHUD_CHECK_FILE _("どのスコアをみる?") #define TEXT_JPHUD_COPY_FILE _("ファイルコピーする") #define TEXT_JPHUD_ERASE_FILE _("ファイルけす") #define TEXT_JPHUD_SOUND_SELECT _("サウンドセレクト") diff --git a/include/text_strings.h.in b/include/text_strings.h.in index 6a5e9a2..2fda11d 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -39,14 +39,14 @@ #define TEXT_ERASE_FILE TEXT_JPHUD_ERASE_FILE #define TEXT_SOUND_SELECT TEXT_JPHUD_SOUND_SELECT -#define TEXT_FILE_MARIO_A _("マリオA") -#define TEXT_FILE_MARIO_B _("マリオB") -#define TEXT_FILE_MARIO_C _("マリオC") -#define TEXT_FILE_MARIO_D _("マリオD") +#define TEXT_FILE_MARIO_A _("マリオA") +#define TEXT_FILE_MARIO_B _("マリオB") +#define TEXT_FILE_MARIO_C _("マリオC") +#define TEXT_FILE_MARIO_D _("マリオD") // Menu Options #define TEXT_SCORE _("スコア") -#define TEXT_COPY _("コピ-") +#define TEXT_COPY _("コピー") #define TEXT_ERASE _("けす") // Sound Options @@ -55,72 +55,72 @@ #define TEXT_HEADSET _("ヘッドホン") // Misc Menu Text -#define TEXT_SAVED_DATA_EXISTS _("ファイルにデ-タがはいってます") -#define TEXT_NO_SAVED_DATA_EXISTS _("ファイルにデ-タがありません") +#define TEXT_SAVED_DATA_EXISTS _("ファイルにデータがはいってます") +#define TEXT_NO_SAVED_DATA_EXISTS _("ファイルにデータがありません") // Inside a Menu #define TEXT_RETURN _("もどる") #define TEXT_CHECK_SCORE _("スコアをみる") -#define TEXT_COPY_FILE_BUTTON _("ファイルコピ-") +#define TEXT_COPY_FILE_BUTTON _("ファイルコピー") #define TEXT_ERASE_FILE_BUTTON _("ファイルけす") // Score Menu #define TEXT_HI_SCORE _("ハイスコア") #define TEXT_MY_SCORE _("マイスコア") -#define TEXT_SCORE_MARIO_A _("マリオA") -#define TEXT_SCORE_MARIO_B _("マリオB") -#define TEXT_SCORE_MARIO_C _("マリオC") -#define TEXT_SCORE_MARIO_D _("マリオD") +#define TEXT_SCORE_MARIO_A _("マリオA") +#define TEXT_SCORE_MARIO_B _("マリオB") +#define TEXT_SCORE_MARIO_C _("マリオC") +#define TEXT_SCORE_MARIO_D _("マリオD") // Copy Menu -#define TEXT_COPY_IT_TO_WHERE _("どこにコピ-しますか?") -#define TEXT_COPYING_COMPLETED _("コピ-おわりました") +#define TEXT_COPY_IT_TO_WHERE _("どこにコピーしますか?") +#define TEXT_COPYING_COMPLETED _("コピーおわりました") #define TEXT_NO_FILE_TO_COPY_FROM _("からのファイルがありません") // Erase Menu -#define TEXT_SURE _("ほんと?") +#define TEXT_SURE _("ほんと?") #define TEXT_YES _("はい") #define TEXT_NO _("いいえ") -#define TEXT_FILE_MARIO_A_JUST_ERASED _("マリオAをけしました") +#define TEXT_FILE_MARIO_A_JUST_ERASED _("マリオAをけしました") /** * Menus Text (Pause, Course Completed) */ // Main Courses -#define TEXT_COURSE _("コ-ス") +#define TEXT_COURSE _("コース") #define TEXT_MYSCORE _("マイスコア") -#define TEXT_CONTINUE _("つづけて マリオする?") -#define TEXT_EXIT_COURSE _("コ-スからでる?") -#define TEXT_CAMERA_ANGLE_R _("Rボタンのカメラきりかえ") +#define TEXT_CONTINUE _("つづけて マリオする?") +#define TEXT_EXIT_COURSE _("コースからでる?") +#define TEXT_CAMERA_ANGLE_R _("Rボタンのカメラきりかえ") // Camera Options -#define TEXT_LAKITU_MARIO _("ジュゲム+マリオ") -#define TEXT_LAKITU_STOP _("ジュゲム+ストップ") -#define TEXT_NORMAL_UPCLOSE _("(おすすめ)(リアル)") -#define TEXT_NORMAL_FIXED _("(おすすめ)(とまる)") +#define TEXT_LAKITU_MARIO _("ジュゲム↔マリオ") +#define TEXT_LAKITU_STOP _("ジュゲム↔ストップ") +#define TEXT_NORMAL_UPCLOSE _("(おすすめ)(リアル)") +#define TEXT_NORMAL_FIXED _("(おすすめ)(とまる)") // Course Completed Misc Text -#define TEXT_CATCH _("キャッチ!") -#define TEXT_CLEAR _("クリア!") -#define TEXT_HUD_HI_SCORE _("HISCORE") +#define TEXT_CATCH _("キャッチ!") +#define TEXT_CLEAR _("クリア!") +#define TEXT_HUD_HI_SCORE _("HISCORE") // Save Options -#define TEXT_SAVE_AND_CONTINUE _("セ-ブしてつづける?") -#define TEXT_SAVE_AND_QUIT _("セ-ブしておわる?") -#define TEXT_CONTINUE_WITHOUT_SAVING _("セ-ブしないでつづける?") +#define TEXT_SAVE_AND_CONTINUE _("セーブしてつづける?") +#define TEXT_SAVE_AND_QUIT _("セーブしておわる?") +#define TEXT_CONTINUE_WITHOUT_SAVING _("セーブしないでつづける?") /** * Ending Peach cutscene text. */ -#define TEXT_FILE_MARIO_EXCLAMATION _("マリオ!!") -#define TEXT_POWER_STARS_RESTORED _("おしろにスタ-が もどったのね") -#define TEXT_THANKS_TO_YOU _("みんな あなたのおかげだわ!") -#define TEXT_THANK_YOU_MARIO _("ありがとう マリオ") -#define TEXT_SOMETHING_SPECIAL _("なにか おれいをしなくちゃ・・") -#define TEXT_LISTEN_EVERYBODY _("さあ みんな") -#define TEXT_LETS_HAVE_CAKE _("おいしいケ-キを やきましょう") -#define TEXT_FOR_MARIO _("マリオの ために・・・") -#define TEXT_FILE_MARIO_QUESTION _("マリオ?") +#define TEXT_FILE_MARIO_EXCLAMATION _("マリオ!!") +#define TEXT_POWER_STARS_RESTORED _("おしろにスターが もどったのね") +#define TEXT_THANKS_TO_YOU _("みんな あなたのおかげだわ!") +#define TEXT_THANK_YOU_MARIO _("ありがとう マリオ") +#define TEXT_SOMETHING_SPECIAL _("なにか おれいをしなくちゃ・・") +#define TEXT_LISTEN_EVERYBODY _("さあ みんな") +#define TEXT_LETS_HAVE_CAKE _("おいしいケーキを やきましょう") +#define TEXT_FOR_MARIO _("マリオの ために・・・") +#define TEXT_FILE_MARIO_QUESTION _("マリオ?") #endif diff --git a/include/textures.h b/include/textures.h index 2a76f2c..a558d19 100644 --- a/include/textures.h +++ b/include/textures.h @@ -7,7 +7,6 @@ extern const u8 cave_09000000[]; extern const u8 cave_09001000[]; extern const u8 cave_09001800[]; -extern const u8 cave_09002000[]; extern const u8 cave_09002800[]; extern const u8 cave_09003000[]; extern const u8 cave_09003800[]; @@ -114,7 +113,6 @@ extern const u8 inside_09007000[]; extern const u8 inside_09008000[]; extern const u8 inside_09008800[]; extern const u8 inside_09009000[]; -extern const u8 inside_09009800[]; extern const u8 inside_0900A000[]; extern const u8 inside_0900B000[]; extern const u8 inside_0900B800[]; @@ -142,7 +140,6 @@ extern const u8 machine_09008400[]; extern const u8 mountain_09000000[]; extern const u8 mountain_09000800[]; extern const u8 mountain_09001800[]; -extern const u8 mountain_09002000[]; extern const u8 mountain_09002800[]; extern const u8 mountain_09003000[]; extern const u8 mountain_09003800[]; @@ -150,7 +147,6 @@ extern const u8 mountain_09004000[]; extern const u8 mountain_09004800[]; extern const u8 mountain_09005000[]; extern const u8 mountain_09005800[]; -extern const u8 mountain_09006000[]; extern const u8 mountain_09006800[]; extern const u8 mountain_09007000[]; extern const u8 mountain_09007800[]; diff --git a/include/types.h b/include/types.h index 3f844b6..a66afef 100644 --- a/include/types.h +++ b/include/types.h @@ -309,7 +309,7 @@ struct MarioState /*0x88*/ struct Object *marioObj; /*0x8C*/ struct SpawnInfo *spawnInfo; /*0x90*/ struct Area *area; - /*0x94*/ struct CameraPlayerStatus *statusForCamera; + /*0x94*/ struct PlayerCameraState *statusForCamera; /*0x98*/ struct MarioBodyState *marioBodyState; /*0x9C*/ struct Controller *controller; /*0xA0*/ struct MarioAnimation *animation; diff --git a/levels/bbh/areas/1/geo.inc.c b/levels/bbh/areas/1/geo.inc.c index ff39e31..d1f6522 100644 --- a/levels/bbh/areas/1/geo.inc.c +++ b/levels/bbh/areas/1/geo.inc.c @@ -479,7 +479,7 @@ const GeoLayout geo_bbh_000F00[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 50, 10000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SWITCH_CASE(32, geo_switch_area), GEO_OPEN_NODE(), diff --git a/levels/bitdw/areas/1/geo.inc.c b/levels/bitdw/areas/1/geo.inc.c index cc35efb..4bddd60 100644 --- a/levels/bitdw/areas/1/geo.inc.c +++ b/levels/bitdw/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout geo_bitdw_000618[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(14, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(14, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, bitdw_seg7_dl_070020C8), GEO_RENDER_OBJ(), diff --git a/levels/bitfs/areas/1/geo.inc.c b/levels/bitfs/areas/1/geo.inc.c index 2ccbbfa..82b61ad 100644 --- a/levels/bitfs/areas/1/geo.inc.c +++ b/levels/bitfs/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bitfs_geo_0007A0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(14, 0, 2000, 6000, 0, -4500, -8000, geo_camera_preset_and_pos), + GEO_CAMERA(14, 0, 2000, 6000, 0, -4500, -8000, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, bitfs_seg7_dl_07002118), GEO_ASM( 0, geo_movtex_pause_control), diff --git a/levels/bits/areas/1/geo.inc.c b/levels/bits/areas/1/geo.inc.c index 85e6cce..0638a81 100644 --- a/levels/bits/areas/1/geo.inc.c +++ b/levels/bits/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bits_geo_000718[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(14, 0, 2000, 6000, 0, -4500, -8000, geo_camera_preset_and_pos), + GEO_CAMERA(14, 0, 2000, 6000, 0, -4500, -8000, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, bits_seg7_dl_07002918), GEO_RENDER_OBJ(), diff --git a/levels/bob/areas/1/geo.inc.c b/levels/bob/areas/1/geo.inc.c index 4fa24ec..c5b1c97 100644 --- a/levels/bob/areas/1/geo.inc.c +++ b/levels/bob/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bob_geo_000488[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 30000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 3072, 0, -4608, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 3072, 0, -4608, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, bob_seg7_dl_07004390), GEO_DISPLAY_LIST(LAYER_OPAQUE, bob_seg7_dl_07009D80), diff --git a/levels/bowser_1/areas/1/geo.inc.c b/levels/bowser_1/areas/1/geo.inc.c index f14e3a9..1257abf 100644 --- a/levels/bowser_1/areas/1/geo.inc.c +++ b/levels/bowser_1/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bowser_1_geo_0000D0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, bowser_1_seg7_dl_07002768), GEO_RENDER_OBJ(), diff --git a/levels/bowser_2/areas/1/geo.inc.c b/levels/bowser_2/areas/1/geo.inc.c index b57756e..78523fe 100644 --- a/levels/bowser_2/areas/1/geo.inc.c +++ b/levels/bowser_2/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bowser_2_geo_000188[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, bowser_2_seg7_dl_07001930), GEO_RENDER_OBJ(), diff --git a/levels/bowser_3/areas/1/geo.inc.c b/levels/bowser_3/areas/1/geo.inc.c index 95f7399..75c90f6 100644 --- a/levels/bowser_3/areas/1/geo.inc.c +++ b/levels/bowser_3/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout bowser_3_geo_000398[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(11, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, bowser_3_seg7_dl_070046B0), GEO_RENDER_OBJ(), diff --git a/levels/castle_courtyard/areas/1/geo.inc.c b/levels/castle_courtyard/areas/1/geo.inc.c index c2f306b..8df1993 100644 --- a/levels/castle_courtyard/areas/1/geo.inc.c +++ b/levels/castle_courtyard/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout castle_courtyard_geo_000218[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, castle_courtyard_seg7_dl_070048B8), GEO_DISPLAY_LIST(LAYER_TRANSPARENT_DECAL, castle_courtyard_seg7_dl_07005698), diff --git a/levels/castle_grounds/areas/1/geo.inc.c b/levels/castle_grounds/areas/1/geo.inc.c index 4ccd2d1..309cc73 100644 --- a/levels/castle_grounds/areas/1/geo.inc.c +++ b/levels/castle_grounds/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout castle_grounds_geo_00073C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 1500, 2500, 0, 1500, -12000, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 1500, 2500, 0, 1500, -12000, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, castle_grounds_seg7_dl_07006D70), GEO_DISPLAY_LIST(LAYER_OPAQUE, castle_grounds_seg7_dl_070095F0), diff --git a/levels/castle_inside/areas/1/geo.inc.c b/levels/castle_inside/areas/1/geo.inc.c index e50cc13..c864dc8 100644 --- a/levels/castle_inside/areas/1/geo.inc.c +++ b/levels/castle_inside/areas/1/geo.inc.c @@ -269,7 +269,7 @@ const GeoLayout castle_geo_001400[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(64, 50, 7000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(13, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(13, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SWITCH_CASE(17, geo_switch_area), GEO_OPEN_NODE(), diff --git a/levels/castle_inside/areas/2/geo.inc.c b/levels/castle_inside/areas/2/geo.inc.c index bcb9b9d..b8af3df 100644 --- a/levels/castle_inside/areas/2/geo.inc.c +++ b/levels/castle_inside/areas/2/geo.inc.c @@ -174,7 +174,7 @@ const GeoLayout castle_geo_001858[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(64, 50, 8000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SWITCH_CASE(11, geo_switch_area), GEO_OPEN_NODE(), diff --git a/levels/castle_inside/areas/3/geo.inc.c b/levels/castle_inside/areas/3/geo.inc.c index 40a886f..1e32262 100644 --- a/levels/castle_inside/areas/3/geo.inc.c +++ b/levels/castle_inside/areas/3/geo.inc.c @@ -160,7 +160,7 @@ const GeoLayout castle_geo_001C10[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(64, 50, 6400, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SWITCH_CASE(10, geo_switch_area), GEO_OPEN_NODE(), diff --git a/levels/ccm/areas/1/geo.inc.c b/levels/ccm/areas/1/geo.inc.c index a6ea532..8832d45 100644 --- a/levels/ccm/areas/1/geo.inc.c +++ b/levels/ccm/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ccm_geo_00051C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ccm_seg7_dl_0700B090), GEO_DISPLAY_LIST(LAYER_OPAQUE, ccm_seg7_dl_0700B1D8), diff --git a/levels/ccm/areas/2/geo.inc.c b/levels/ccm/areas/2/geo.inc.c index 38bc087..fdb3f06 100644 --- a/levels/ccm/areas/2/geo.inc.c +++ b/levels/ccm/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ccm_geo_0005E8[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ccm_seg7_dl_0701CE30), GEO_DISPLAY_LIST(LAYER_OPAQUE, ccm_seg7_dl_0701E558), diff --git a/levels/cotmc/areas/1/geo.inc.c b/levels/cotmc/areas/1/geo.inc.c index 5d581b0..25d022f 100644 --- a/levels/cotmc/areas/1/geo.inc.c +++ b/levels/cotmc/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout cotmc_geo_0001A0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, cotmc_seg7_dl_07007D48), GEO_DISPLAY_LIST(LAYER_OPAQUE, cotmc_seg7_dl_0700A160), diff --git a/levels/course_defines.h b/levels/course_defines.h index ee41e71..600cead 100644 --- a/levels/course_defines.h +++ b/levels/course_defines.h @@ -1,29 +1,39 @@ -// Define lists for list of course for macros. Each of the following fields are described: -// Argument 1: Course macro for define. -// Argument 2, 3, 4, 5: Each hex digit is an index into D_8032E8A4 which is for a table of cutscene dance indexes. Defined by course index so we must define these. -DEFINE_COURSE(COURSE_BOB, 0x00, 0x20, 0x22, 0x04) // (1) Bob Omb Battlefield -DEFINE_COURSE(COURSE_WF, 0x00, 0x00, 0x02, 0x04) // (2) Whomp's Fortress -DEFINE_COURSE(COURSE_JRB, 0x22, 0x22, 0x22, 0x04) // (3) Jolly Rodger's Bay -DEFINE_COURSE(COURSE_CCM, 0x00, 0x22, 0x00, 0x04) // (4) Cool Cool Mountain -DEFINE_COURSE(COURSE_BBH, 0x22, 0x22, 0x22, 0x04) // (5) Big Boo's Haunt -DEFINE_COURSE(COURSE_HMC, 0x22, 0x22, 0x22, 0x04) // (6) Hazy Maze Cave -DEFINE_COURSE(COURSE_LLL, 0x12, 0x12, 0x12, 0x04) // (7) Lethal Lava Land -DEFINE_COURSE(COURSE_SSL, 0x02, 0x22, 0x22, 0x04) // (8) Shifting Sand Land -DEFINE_COURSE(COURSE_DDD, 0x22, 0x22, 0x22, 0x04) // (9) Dire Dire Docks -DEFINE_COURSE(COURSE_SL, 0x20, 0x20, 0x20, 0x04) // (10) Snowman's Land -DEFINE_COURSE(COURSE_WDW, 0x22, 0x01, 0x22, 0x04) // (11) Wet Dry World -DEFINE_COURSE(COURSE_TTM, 0x00, 0x00, 0x00, 0x04) // (12) Tall Tall Mountain -DEFINE_COURSE(COURSE_THI, 0x11, 0x11, 0x12, 0x04) // (13) Tiny Huge Island -DEFINE_COURSE(COURSE_TTC, 0x22, 0x22, 0x22, 0x04) // (14) Tick Tock Clock -DEFINE_COURSE(COURSE_RR, 0x00, 0x00, 0x00, 0x04) // (15) Rainbow Ride +/* Define lists for list of course for macros. Each of the following fields are described: + * Argument 1: Course macro for define. + * Argument 2: Star collection dance cutscenes + * Each hex digit determines what dance cutscene to play for the stars in the course. The last digit is + * unused. See determine_dance_cutscene() in camera.c for details. + * Cutscene Digits: + * 0: Lakitu flies away after the dance + * 1: The camera rotates around mario + * 2: The camera goes to a closeup of mario + * 3: Bowser keys and the grand star + * 4: Default, used for 100 coin stars, 8 red coin stars in bowser levels, and secret stars + */ +DEFINE_COURSE(COURSE_NONE, 0x44444440) // (0) Course Hub (Castle Grounds) +DEFINE_COURSE(COURSE_BOB, 0x00022240) // (1) Bob Omb Battlefield +DEFINE_COURSE(COURSE_WF, 0x00002040) // (2) Whomp's Fortress +DEFINE_COURSE(COURSE_JRB, 0x22222240) // (3) Jolly Rodger's Bay +DEFINE_COURSE(COURSE_CCM, 0x00220040) // (4) Cool Cool Mountain +DEFINE_COURSE(COURSE_BBH, 0x22222240) // (5) Big Boo's Haunt +DEFINE_COURSE(COURSE_HMC, 0x22222240) // (6) Hazy Maze Cave +DEFINE_COURSE(COURSE_LLL, 0x21212140) // (7) Lethal Lava Land +DEFINE_COURSE(COURSE_SSL, 0x20222240) // (8) Shifting Sand Land +DEFINE_COURSE(COURSE_DDD, 0x22222240) // (9) Dire Dire Docks +DEFINE_COURSE(COURSE_SL, 0x02020240) // (10) Snowman's Land +DEFINE_COURSE(COURSE_WDW, 0x22102240) // (11) Wet Dry World +DEFINE_COURSE(COURSE_TTM, 0x00000040) // (12) Tall Tall Mountain +DEFINE_COURSE(COURSE_THI, 0x11112140) // (13) Tiny Huge Island +DEFINE_COURSE(COURSE_TTC, 0x22222240) // (14) Tick Tock Clock +DEFINE_COURSE(COURSE_RR, 0x00000040) // (15) Rainbow Ride DEFINE_COURSES_END() -DEFINE_BONUS_COURSE(COURSE_BITDW, 0x43, 0x44, 0x44, 0x04) // (16) Bowser in the Dark World -DEFINE_BONUS_COURSE(COURSE_BITFS, 0x43, 0x44, 0x44, 0x04) // (17) Bowser in the Fire Sea -DEFINE_BONUS_COURSE(COURSE_BITS, 0x43, 0x44, 0x44, 0x04) // (18) Bowser in the Sky -DEFINE_BONUS_COURSE(COURSE_PSS, 0x42, 0x44, 0x44, 0x04) // (19) Princess's Secret Slide -DEFINE_BONUS_COURSE(COURSE_COTMC, 0x44, 0x44, 0x44, 0x04) // (20) Cavern of the Metal Cap -DEFINE_BONUS_COURSE(COURSE_TOTWC, 0x40, 0x44, 0x44, 0x04) // (21) Tower of the Wing Cap -DEFINE_BONUS_COURSE(COURSE_VCUTM, 0x42, 0x44, 0x44, 0x04) // (22) Vanish Cap Under the Moat -DEFINE_BONUS_COURSE(COURSE_WMOTR, 0x40, 0x44, 0x44, 0x04) // (23) Winged Mario over the Rainbow -DEFINE_BONUS_COURSE(COURSE_SA, 0x42, 0x44, 0x44, 0x04) // (24) Secret Aquarium -DEFINE_BONUS_COURSE(COURSE_CAKE_END, 0x44, 0x44, 0x44, 0x04) // (25) The End (Cake Scene) +DEFINE_BONUS_COURSE(COURSE_BITDW, 0x34444440) // (16) Bowser in the Dark World +DEFINE_BONUS_COURSE(COURSE_BITFS, 0x34444440) // (17) Bowser in the Fire Sea +DEFINE_BONUS_COURSE(COURSE_BITS, 0x34444440) // (18) Bowser in the Sky +DEFINE_BONUS_COURSE(COURSE_PSS, 0x24444440) // (19) Princess's Secret Slide +DEFINE_BONUS_COURSE(COURSE_COTMC, 0x44444440) // (20) Cavern of the Metal Cap +DEFINE_BONUS_COURSE(COURSE_TOTWC, 0x04444440) // (21) Tower of the Wing Cap +DEFINE_BONUS_COURSE(COURSE_VCUTM, 0x24444440) // (22) Vanish Cap Under the Moat +DEFINE_BONUS_COURSE(COURSE_WMOTR, 0x04444440) // (23) Winged Mario over the Rainbow +DEFINE_BONUS_COURSE(COURSE_SA, 0x24444440) // (24) Secret Aquarium +DEFINE_BONUS_COURSE(COURSE_CAKE_END, 0x44444440) // (25) The End (Cake Scene) diff --git a/levels/ddd/areas/1/geo.inc.c b/levels/ddd/areas/1/geo.inc.c index 4b8775e..0453c73 100644 --- a/levels/ddd/areas/1/geo.inc.c +++ b/levels/ddd/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ddd_geo_0004C0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(2, 0, 2000, 6000, 2560, 0, 512, geo_camera_preset_and_pos), + GEO_CAMERA(2, 0, 2000, 6000, 2560, 0, 512, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ddd_seg7_dl_07004D48), GEO_DISPLAY_LIST(LAYER_OPAQUE, ddd_seg7_dl_070057E8), diff --git a/levels/ddd/areas/2/geo.inc.c b/levels/ddd/areas/2/geo.inc.c index 479a929..efcac70 100644 --- a/levels/ddd/areas/2/geo.inc.c +++ b/levels/ddd/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ddd_geo_000570[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 2560, 0, 512, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 2560, 0, 512, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ddd_seg7_dl_07007408), GEO_DISPLAY_LIST(LAYER_OPAQUE, ddd_seg7_dl_07007CB8), diff --git a/levels/ending/geo.c b/levels/ending/geo.c index 918f779..fafda47 100644 --- a/levels/ending/geo.c +++ b/levels/ending/geo.c @@ -26,7 +26,7 @@ const GeoLayout ending_geo_000050[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), diff --git a/levels/hmc/areas/1/geo.inc.c b/levels/hmc/areas/1/geo.inc.c index f2c1a86..9bca4d1 100644 --- a/levels/hmc/areas/1/geo.inc.c +++ b/levels/hmc/areas/1/geo.inc.c @@ -302,7 +302,7 @@ const GeoLayout hmc_geo_000B90[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SWITCH_CASE(18, geo_switch_area), GEO_OPEN_NODE(), diff --git a/levels/jrb/areas/1/geo.inc.c b/levels/jrb/areas/1/geo.inc.c index 0b3d269..adb1f96 100644 --- a/levels/jrb/areas/1/geo.inc.c +++ b/levels/jrb/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout jrb_geo_000A18[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 25000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, jrb_seg7_dl_07002FD0), GEO_DISPLAY_LIST(LAYER_OPAQUE, jrb_seg7_dl_07004940), diff --git a/levels/jrb/areas/2/geo.inc.c b/levels/jrb/areas/2/geo.inc.c index f722a9e..e0868a6 100644 --- a/levels/jrb/areas/2/geo.inc.c +++ b/levels/jrb/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout jrb_geo_000AFC[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 10000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, jrb_seg7_dl_0700EF00), GEO_DISPLAY_LIST(LAYER_ALPHA, jrb_seg7_dl_0700FE48), diff --git a/levels/level_defines.h b/levels/level_defines.h index 3af6444..c14f252 100644 --- a/levels/level_defines.h +++ b/levels/level_defines.h @@ -15,25 +15,23 @@ // Argument 10: Specify dynamic music tables for levels, if specified. _ for none. // Argument 11: Specify level camera table, if specified. _ for none. -// NOTE: Be sure to edit zoomOutAreaMasks in camera.c, as there isnt a good way to macro those right now. -// TODO: Figure something out for zoomOutAreaMasks? -#ifndef SKIP_FIRST_LAST_STUBS // this is needed for the zoomOutAreaMasks array which has a weird way of doing the bit array packs. +// NOTE: Be sure to edit sZoomOutAreaMasks in camera.c, as there isnt a good way to macro those right now. +// TODO: Figure something out for sZoomOutAreaMasks? STUB_LEVEL( "", LEVEL_UNKNOWN_1, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _) -#endif STUB_LEVEL( "", LEVEL_UNKNOWN_2, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _) STUB_LEVEL( "", LEVEL_UNKNOWN_3, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _) -DEFINE_LEVEL("TERESA OBAKE", LEVEL_BBH, COURSE_BBH, bbh, spooky, 28000, 0x28, 0x28, 0x28, sDynBbh, TableCameraBBH) -DEFINE_LEVEL("YYAMA1 % YSLD1", LEVEL_CCM, COURSE_CCM, ccm, snow, 17000, 0x10, 0x38, 0x38, _, TableCameraCCM) -DEFINE_LEVEL("SELECT ROOM", LEVEL_CASTLE, COURSE_NONE, castle_inside, inside, 20000, 0x20, 0x20, 0x30, _, TableCameraInside) -DEFINE_LEVEL("HORROR DUNGEON", LEVEL_HMC, COURSE_HMC, hmc, cave, 16000, 0x28, 0x28, 0x28, sDynHmc, TableCameraHMC) -DEFINE_LEVEL("SABAKU % PYRMD", LEVEL_SSL, COURSE_SSL, ssl, generic, 15000, 0x08, 0x30, 0x30, _, TableCameraSSL) +DEFINE_LEVEL("TERESA OBAKE", LEVEL_BBH, COURSE_BBH, bbh, spooky, 28000, 0x28, 0x28, 0x28, sDynBbh, sCamBBH) +DEFINE_LEVEL("YYAMA1 % YSLD1", LEVEL_CCM, COURSE_CCM, ccm, snow, 17000, 0x10, 0x38, 0x38, _, sCamCCM) +DEFINE_LEVEL("SELECT ROOM", LEVEL_CASTLE, COURSE_NONE, castle_inside, inside, 20000, 0x20, 0x20, 0x30, _, sCamCastle) +DEFINE_LEVEL("HORROR DUNGEON", LEVEL_HMC, COURSE_HMC, hmc, cave, 16000, 0x28, 0x28, 0x28, sDynHmc, sCamHMC) +DEFINE_LEVEL("SABAKU % PYRMD", LEVEL_SSL, COURSE_SSL, ssl, generic, 15000, 0x08, 0x30, 0x30, _, sCamSSL) DEFINE_LEVEL("BATTLE FIELD", LEVEL_BOB, COURSE_BOB, bob, generic, 15000, 0x08, 0x08, 0x08, _, _) -DEFINE_LEVEL("YUKIYAMA2", LEVEL_SL, COURSE_SL, sl, snow, 14000, 0x10, 0x28, 0x28, _, TableCameraSL) +DEFINE_LEVEL("YUKIYAMA2", LEVEL_SL, COURSE_SL, sl, snow, 14000, 0x10, 0x28, 0x28, _, sCamSL) DEFINE_LEVEL("POOL KAI", LEVEL_WDW, COURSE_WDW, wdw, grass, 17000, 0x10, 0x18, 0x18, sDynWdw, _) DEFINE_LEVEL("WTDG % TINBOTU", LEVEL_JRB, COURSE_JRB, jrb, water, 20000, 0x10, 0x18, 0x18, sDynJrb, _) -DEFINE_LEVEL("BIG WORLD", LEVEL_THI, COURSE_THI, thi, grass, 20000, 0x0c, 0x0c, 0x20, _, TableCameraTHI) +DEFINE_LEVEL("BIG WORLD", LEVEL_THI, COURSE_THI, thi, grass, 20000, 0x0c, 0x0c, 0x20, _, sCamTHI) DEFINE_LEVEL("CLOCK TOWER", LEVEL_TTC, COURSE_TTC, ttc, machine, 18000, 0x18, 0x18, 0x18, _, _) -DEFINE_LEVEL("RAINBOW CRUISE", LEVEL_RR, COURSE_RR, rr, sky, 20000, 0x20, 0x20, 0x20, _, TableCameraRR) +DEFINE_LEVEL("RAINBOW CRUISE", LEVEL_RR, COURSE_RR, rr, sky, 20000, 0x20, 0x20, 0x20, _, sCamRR) DEFINE_LEVEL("MAIN MAP", LEVEL_CASTLE_GROUNDS, COURSE_NONE, castle_grounds, outside, 25000, 0x08, 0x08, 0x08, _, _) DEFINE_LEVEL("EXT1 YOKO SCRL", LEVEL_BITDW, COURSE_BITDW, bitdw, sky, 16000, 0x28, 0x28, 0x28, _, _) DEFINE_LEVEL("EXT7 HORI MINI", LEVEL_VCUTM, COURSE_VCUTM, vcutm, outside, 30000, 0x28, 0x28, 0x28, _, _) @@ -46,7 +44,7 @@ DEFINE_LEVEL("MOUNTAIN", LEVEL_WF, COURSE_WF, wf, DEFINE_LEVEL("ENDING", LEVEL_ENDING, COURSE_CAKE_END, ending, generic, 20000, 0x00, 0x00, 0x00, _, _) DEFINE_LEVEL("URANIWA", LEVEL_CASTLE_COURTYARD, COURSE_NONE, castle_courtyard, outside, 20000, 0x08, 0x08, 0x08, _, _) DEFINE_LEVEL("EXT4 MINI SLID", LEVEL_PSS, COURSE_PSS, pss, mountain, 20000, 0x28, 0x28, 0x28, _, _) -DEFINE_LEVEL("IN THE FALL", LEVEL_COTMC, COURSE_COTMC, cotmc, cave, 18000, 0x28, 0x28, 0x28, _, TableCameraCotMC) +DEFINE_LEVEL("IN THE FALL", LEVEL_COTMC, COURSE_COTMC, cotmc, cave, 18000, 0x28, 0x28, 0x28, _, sCamCotMC) DEFINE_LEVEL("EXT6 MARIO FLY", LEVEL_TOTWC, COURSE_TOTWC, totwc, sky, 20000, 0x20, 0x20, 0x20, _, _) DEFINE_LEVEL("KUPPA1", LEVEL_BOWSER_1, COURSE_BITDW, bowser_1, generic, VAL_DIFF, 0x40, 0x40, 0x40, _, _) DEFINE_LEVEL("EXT8 BLUE SKY", LEVEL_WMOTR, COURSE_WMOTR, wmotr, generic, 20000, 0x28, 0x28, 0x28, _, _) @@ -56,6 +54,4 @@ DEFINE_LEVEL("KUPPA3", LEVEL_BOWSER_3, COURSE_BITS, bowser_3 STUB_LEVEL( "", LEVEL_UNKNOWN_35, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _) DEFINE_LEVEL("DONKEY % SLID2", LEVEL_TTM, COURSE_TTM, ttm, mountain, 15000, 0x08, 0x08, 0x08, _, _) STUB_LEVEL( "", LEVEL_UNKNOWN_37, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _) -#ifndef SKIP_FIRST_LAST_STUBS STUB_LEVEL( "", LEVEL_UNKNOWN_38, COURSE_NONE, 20000, 0x00, 0x00, 0x00, sDynUnk38, _) -#endif diff --git a/levels/lll/areas/1/geo.inc.c b/levels/lll/areas/1/geo.inc.c index cf421ac..db1d325 100644 --- a/levels/lll/areas/1/geo.inc.c +++ b/levels/lll/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout lll_geo_000E00[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(64, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, -8192, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, -8192, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, lll_seg7_dl_070134E0), GEO_DISPLAY_LIST(LAYER_ALPHA, lll_seg7_dl_070138F8), diff --git a/levels/lll/areas/2/geo.inc.c b/levels/lll/areas/2/geo.inc.c index c0fabc9..07b845c 100644 --- a/levels/lll/areas/2/geo.inc.c +++ b/levels/lll/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout lll_geo_000EC0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(2, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(2, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, lll_seg7_dl_070235C8), GEO_DISPLAY_LIST(LAYER_OPAQUE, lll_seg7_dl_07024C18), diff --git a/levels/pss/areas/1/geo.inc.c b/levels/pss/areas/1/geo.inc.c index 0268c3c..dafecd5 100644 --- a/levels/pss/areas/1/geo.inc.c +++ b/levels/pss/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout pss_geo_000100[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, pss_seg7_dl_0700A7C0), GEO_DISPLAY_LIST(LAYER_OPAQUE, pss_seg7_dl_0700AFA8), diff --git a/levels/rr/areas/1/geo.inc.c b/levels/rr/areas/1/geo.inc.c index cd7f015..00d99f2 100644 --- a/levels/rr/areas/1/geo.inc.c +++ b/levels/rr/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout rr_geo_0009D0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(14, 0, 2000, 6000, 0, 0, -8000, geo_camera_preset_and_pos), + GEO_CAMERA(14, 0, 2000, 6000, 0, 0, -8000, geo_camera_main), GEO_OPEN_NODE(), GEO_ASM(0, geo_exec_flying_carpet_timer_update), GEO_DISPLAY_LIST(LAYER_ALPHA, dl_cruiser_metal_holes), diff --git a/levels/sa/areas/1/geo.inc.c b/levels/sa/areas/1/geo.inc.c index 0d0e4a0..43f0e51 100644 --- a/levels/sa/areas/1/geo.inc.c +++ b/levels/sa/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout sa_geo_000170[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, sa_seg7_dl_07002DE8), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, sa_seg7_dl_07002FD0), diff --git a/levels/sl/areas/1/geo.inc.c b/levels/sl/areas/1/geo.inc.c index 1cb0e24..537513b 100644 --- a/levels/sl/areas/1/geo.inc.c +++ b/levels/sl/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout sl_geo_0003A8[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 4400, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 4400, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, sl_seg7_dl_07005478), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, sl_seg7_dl_070056B0), diff --git a/levels/sl/areas/2/geo.inc.c b/levels/sl/areas/2/geo.inc.c index 95b401a..37d72c1 100644 --- a/levels/sl/areas/2/geo.inc.c +++ b/levels/sl/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout sl_geo_000484[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, sl_seg7_dl_0700BAE8), GEO_DISPLAY_LIST(LAYER_OPAQUE, sl_seg7_dl_0700BCF8), diff --git a/levels/ssl/areas/1/geo.inc.c b/levels/ssl/areas/1/geo.inc.c index dee32a8..a746675 100644 --- a/levels/ssl/areas/1/geo.inc.c +++ b/levels/ssl/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ssl_geo_000648[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, -2048, 0, -1024, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, -2048, 0, -1024, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ssl_seg7_dl_07009F48), GEO_DISPLAY_LIST(LAYER_OPAQUE, ssl_seg7_dl_0700BA78), diff --git a/levels/ssl/areas/2/geo.inc.c b/levels/ssl/areas/2/geo.inc.c index 846ae58..dd1d30f 100644 --- a/levels/ssl/areas/2/geo.inc.c +++ b/levels/ssl/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ssl_geo_0007CC[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ssl_seg7_dl_0701EE80), GEO_DISPLAY_LIST(LAYER_ALPHA, ssl_seg7_dl_0701F920), diff --git a/levels/ssl/areas/3/geo.inc.c b/levels/ssl/areas/3/geo.inc.c index f3a46a6..0dfa476 100644 --- a/levels/ssl/areas/3/geo.inc.c +++ b/levels/ssl/areas/3/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ssl_geo_00088C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(4, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ssl_seg7_dl_07021A08), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, ssl_seg7_dl_07021DE8), diff --git a/levels/thi/areas/1/collision.inc.c b/levels/thi/areas/1/collision.inc.c index 46fa520..3e1f44f 100644 --- a/levels/thi/areas/1/collision.inc.c +++ b/levels/thi/areas/1/collision.inc.c @@ -1232,7 +1232,7 @@ const Collision thi_seg7_area_1_collision[] = { COL_TRI_INIT(SURFACE_CAMERA_FREE_ROAM, 2), COL_TRI(326, 328, 141), COL_TRI(326, 141, 327), - COL_TRI_INIT(SURFACE_CAMERA_PLATFORM, 4), + COL_TRI_INIT(SURFACE_CAMERA_8_DIR, 4), COL_TRI(288, 86, 193), COL_TRI(256, 288, 193), COL_TRI(256, 193, 27), diff --git a/levels/thi/areas/1/geo.inc.c b/levels/thi/areas/1/geo.inc.c index 8bf493b..b8c45ce 100644 --- a/levels/thi/areas/1/geo.inc.c +++ b/levels/thi/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout thi_geo_000608[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, thi_seg7_dl_07005260), GEO_DISPLAY_LIST(LAYER_OPAQUE, thi_seg7_dl_07006968), diff --git a/levels/thi/areas/2/collision.inc.c b/levels/thi/areas/2/collision.inc.c index 226e0bd..e47fe1c 100644 --- a/levels/thi/areas/2/collision.inc.c +++ b/levels/thi/areas/2/collision.inc.c @@ -963,7 +963,7 @@ const Collision thi_seg7_area_2_collision[] = { COL_TRI_INIT(SURFACE_VERTICAL_WIND, 2), COL_TRI(353, 354, 355), COL_TRI(353, 355, 356), - COL_TRI_INIT(SURFACE_CAMERA_PLATFORM, 4), + COL_TRI_INIT(SURFACE_CAMERA_8_DIR, 4), COL_TRI(243, 242, 46), COL_TRI(242, 148, 46), COL_TRI(242, 244, 148), diff --git a/levels/thi/areas/2/geo.inc.c b/levels/thi/areas/2/geo.inc.c index 214dc77..ee90554 100644 --- a/levels/thi/areas/2/geo.inc.c +++ b/levels/thi/areas/2/geo.inc.c @@ -15,7 +15,7 @@ const GeoLayout thi_geo_0006D4[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_SCALE(0x00, 19660), GEO_OPEN_NODE(), diff --git a/levels/thi/areas/3/geo.inc.c b/levels/thi/areas/3/geo.inc.c index 4e77207..2440471 100644 --- a/levels/thi/areas/3/geo.inc.c +++ b/levels/thi/areas/3/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout thi_geo_00079C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, thi_seg7_dl_07007C20), GEO_DISPLAY_LIST(LAYER_OPAQUE, thi_seg7_dl_07009670), diff --git a/levels/totwc/areas/1/geo.inc.c b/levels/totwc/areas/1/geo.inc.c index a1eadf9..dfd16ac 100644 --- a/levels/totwc/areas/1/geo.inc.c +++ b/levels/totwc/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout totwc_geo_000188[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 25000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, totwc_seg7_dl_07005D28), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, totwc_seg7_dl_07007048), diff --git a/levels/ttc/areas/1/geo.inc.c b/levels/ttc/areas/1/geo.inc.c index f86cfec..95a1351 100644 --- a/levels/ttc/areas/1/geo.inc.c +++ b/levels/ttc/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ttc_geo_0003B8[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(2, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(2, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_ASM( 0, geo_movtex_pause_control), GEO_ASM(0x1400, geo_movtex_update_horizontal), diff --git a/levels/ttm/areas/1/geo.inc.c b/levels/ttm/areas/1/geo.inc.c index 7e92647..5be9bbe 100644 --- a/levels/ttm/areas/1/geo.inc.c +++ b/levels/ttm/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ttm_geo_000A70[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, -2200, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, -2200, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0700A120), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0700A2E0), diff --git a/levels/ttm/areas/2/geo.inc.c b/levels/ttm/areas/2/geo.inc.c index bc6a107..f41c79c 100644 --- a/levels/ttm/areas/2/geo.inc.c +++ b/levels/ttm/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ttm_geo_000B5C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0701D798), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0701DBB8), diff --git a/levels/ttm/areas/3/geo.inc.c b/levels/ttm/areas/3/geo.inc.c index 575a455..840096a 100644 --- a/levels/ttm/areas/3/geo.inc.c +++ b/levels/ttm/areas/3/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ttm_geo_000BEC[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_070249A0), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_07024C78), diff --git a/levels/ttm/areas/4/geo.inc.c b/levels/ttm/areas/4/geo.inc.c index 3318211..7e59def 100644 --- a/levels/ttm/areas/4/geo.inc.c +++ b/levels/ttm/areas/4/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout ttm_geo_000C84[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(9, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0702A1B8), GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0702A8A0), diff --git a/levels/vcutm/areas/1/geo.inc.c b/levels/vcutm/areas/1/geo.inc.c index 16f53f5..756e4a5 100644 --- a/levels/vcutm/areas/1/geo.inc.c +++ b/levels/vcutm/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout vcutm_geo_000208[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 25000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(14, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(14, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, vcutm_seg7_dl_07007E88), GEO_DISPLAY_LIST(LAYER_OPAQUE, vcutm_seg7_dl_07008E10), diff --git a/levels/wdw/areas/1/geo.inc.c b/levels/wdw/areas/1/geo.inc.c index d7e4377..112be12 100644 --- a/levels/wdw/areas/1/geo.inc.c +++ b/levels/wdw/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout wdw_geo_000658[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, -4352, 0, -4352, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, -4352, 0, -4352, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, wdw_seg7_dl_07009AB0), GEO_DISPLAY_LIST(LAYER_ALPHA, wdw_seg7_dl_0700A138), diff --git a/levels/wdw/areas/2/geo.inc.c b/levels/wdw/areas/2/geo.inc.c index 830aaee..b1f70c4 100644 --- a/levels/wdw/areas/2/geo.inc.c +++ b/levels/wdw/areas/2/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout wdw_geo_000724[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, -4352, 0, -4352, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, -4352, 0, -4352, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, wdw_seg7_dl_07011E48), GEO_DISPLAY_LIST(LAYER_ALPHA, wdw_seg7_dl_07012258), diff --git a/levels/wf/areas/1/geo.inc.c b/levels/wf/areas/1/geo.inc.c index 3c38a90..7f4fcc8 100644 --- a/levels/wf/areas/1/geo.inc.c +++ b/levels/wf/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout wf_geo_000BF8[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 12800, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(1, 0, 2000, 6000, 0, 2000, 0, geo_camera_preset_and_pos), + GEO_CAMERA(1, 0, 2000, 6000, 0, 2000, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, wf_seg7_dl_070050C8), GEO_DISPLAY_LIST(LAYER_OPAQUE_DECAL, wf_seg7_dl_070052B8), diff --git a/levels/wmotr/areas/1/geo.inc.c b/levels/wmotr/areas/1/geo.inc.c index d1709bb..915ea20 100644 --- a/levels/wmotr/areas/1/geo.inc.c +++ b/levels/wmotr/areas/1/geo.inc.c @@ -13,7 +13,7 @@ const GeoLayout wmotr_geo_0001F0[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM_WITH_FUNC(45, 100, 20000, geo_camera_fov), GEO_OPEN_NODE(), - GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_preset_and_pos), + GEO_CAMERA(16, 0, 2000, 6000, 0, 0, 0, geo_camera_main), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, wmotr_seg7_dl_0700C1F8), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, wmotr_seg7_dl_0700EFD8), diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 584fa3a..d8b5ac2 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -91,13 +91,13 @@ static void Unknown80383E44(void) // ? } } -static s32 beh_cmd_unhide(void) { +static s32 beh_cmd_hide(void) { obj_hide(); gBehCommand++; return BEH_CONTINUE; } -static s32 beh_cmd_graph_clear(void) { +static s32 beh_cmd_disable_rendering(void) { gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; gBehCommand++; return BEH_CONTINUE; @@ -109,26 +109,26 @@ static s32 beh_cmd_billboard(void) { return BEH_CONTINUE; } -static s32 beh_cmd_graph_node(void) { - s32 index = (s16)(gBehCommand[0] & 0xFFFF); - gCurrentObject->header.gfx.sharedChild = gLoadedGraphNodes[index]; +static s32 beh_cmd_set_model(void) { + s32 modelID = (s16)(gBehCommand[0] & 0xFFFF); + gCurrentObject->header.gfx.sharedChild = gLoadedGraphNodes[modelID]; gBehCommand++; return BEH_CONTINUE; } -static s32 beh_cmd_obj_load_chill(void) { +static s32 beh_cmd_spawn_child(void) { u32 model = (u32) gBehCommand[1]; const BehaviorScript *behavior = (const BehaviorScript *) gBehCommand[2]; - struct Object *object = spawn_object_at_origin(gCurrentObject, 0, model, behavior); + struct Object *child = spawn_object_at_origin(gCurrentObject, 0, model, behavior); - copy_object_pos_and_angle(object, gCurrentObject); + copy_object_pos_and_angle(child, gCurrentObject); gBehCommand += 3; return BEH_CONTINUE; } -static s32 beh_cmd_obj_spawn(void) { +static s32 beh_cmd_spawn_obj(void) { u32 model = (u32) gBehCommand[1]; const BehaviorScript *behavior = (const BehaviorScript *) gBehCommand[2]; @@ -142,16 +142,16 @@ static s32 beh_cmd_obj_spawn(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_load_chill_param(void) { +static s32 beh_cmd_spawn_child_with_param(void) { u32 behParam = (s16)(gBehCommand[0] & 0xFFFF); u32 model = (u32) gBehCommand[1]; const BehaviorScript *behavior = (const BehaviorScript *) gBehCommand[2]; - struct Object *object = spawn_object_at_origin(gCurrentObject, 0, model, behavior); + struct Object *child = spawn_object_at_origin(gCurrentObject, 0, model, behavior); - copy_object_pos_and_angle(object, gCurrentObject); + copy_object_pos_and_angle(child, gCurrentObject); - object->oBehParams2ndByte = behParam; + child->oBehParams2ndByte = behParam; gBehCommand += 3; return BEH_CONTINUE; @@ -259,7 +259,7 @@ static s32 beh_cmd_end_repeat(void) { return BEH_BREAK; } -static s32 beh_cmd_end_repeat_nobreak(void) { +static s32 beh_cmd_end_repeat_continue(void) { u32 count = (u32) cur_object_stack_pop(); count--; @@ -291,7 +291,7 @@ static s32 beh_cmd_end_loop(void) { typedef void (*BehaviorCallProc)(void); -static s32 beh_cmd_callnative(void) { +static s32 beh_cmd_call_native(void) { BehaviorCallProc behavior_proc = (BehaviorCallProc) gBehCommand[1]; behavior_proc(); @@ -300,7 +300,7 @@ static s32 beh_cmd_callnative(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_float(void) { +static s32 beh_cmd_set_float(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); f32 value = (s16)(gBehCommand[0] & 0xFFFF); @@ -310,7 +310,7 @@ static s32 beh_cmd_obj_set_float(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_int(void) { +static s32 beh_cmd_set_int(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s16 value = (s16)(gBehCommand[0] & 0xFFFF); @@ -331,7 +331,7 @@ static s32 Behavior36(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_float_rand(void) { +static s32 beh_cmd_set_random_float(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); f32 min = (s16)(gBehCommand[0] & 0xFFFF); f32 max = (s16)(gBehCommand[1] >> 16); @@ -342,7 +342,7 @@ static s32 beh_cmd_obj_set_float_rand(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_int_rand(void) { +static s32 beh_cmd_set_random_int(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 min = (s16)(gBehCommand[0] & 0xFFFF); s32 max = (s16)(gBehCommand[1] >> 16); @@ -353,7 +353,7 @@ static s32 beh_cmd_obj_set_int_rand(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_int_rand_rshift(void) { +static s32 beh_cmd_set_int_rand_rshift(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 min = (s16)(gBehCommand[0] & 0xFFFF); s32 rshift = (s16)(gBehCommand[1] >> 16); @@ -364,7 +364,7 @@ static s32 beh_cmd_obj_set_int_rand_rshift(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_add_float_rand(void) { +static s32 beh_cmd_add_random_float(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); f32 min = (s16)(gBehCommand[0] & 0xFFFF); f32 max = (s16)(gBehCommand[1] >> 16); @@ -377,7 +377,7 @@ static s32 beh_cmd_obj_add_float_rand(void) { } // unused -static s32 beh_cmd_obj_add_int_rand_rshift(void) { +static s32 beh_cmd_add_int_rand_rshift(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 min = (s16)(gBehCommand[0] & 0xFFFF); s32 rshift = (s16)(gBehCommand[1] >> 16); @@ -389,7 +389,7 @@ static s32 beh_cmd_obj_add_int_rand_rshift(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_add_float(void) { +static s32 beh_cmd_add_float(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); f32 value = (s16)(gBehCommand[0] & 0xFFFF); @@ -399,7 +399,7 @@ static s32 beh_cmd_obj_add_float(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_add_int(void) { +static s32 beh_cmd_add_int(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s16 value = gBehCommand[0] & 0xFFFF; @@ -409,7 +409,7 @@ static s32 beh_cmd_obj_add_int(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_or_int(void) { +static s32 beh_cmd_or_int(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 value = (s16)(gBehCommand[0] & 0xFFFF); @@ -421,7 +421,7 @@ static s32 beh_cmd_obj_or_int(void) { } // unused -static s32 beh_cmd_obj_bit_clear_int(void) { +static s32 beh_cmd_bit_clear_int(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 value = (s16)(gBehCommand[0] & 0xFFFF); @@ -432,7 +432,7 @@ static s32 beh_cmd_obj_bit_clear_int(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_anims(void) { +static s32 beh_cmd_load_animations(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); cur_object_set_vptr(objectOffset, gBehCommand[1]); @@ -441,7 +441,7 @@ static s32 beh_cmd_obj_set_anims(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_animate(void) { +static s32 beh_cmd_animate(void) { s32 animIndex = (u8)((gBehCommand[0] >> 16) & 0xFF); struct Animation **animations = gCurrentObject->oAnimations; @@ -451,7 +451,7 @@ static s32 beh_cmd_obj_animate(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_drop_floor(void) { +static s32 beh_cmd_drop_to_floor(void) { f32 x = gCurrentObject->oPosX; f32 y = gCurrentObject->oPosY; f32 z = gCurrentObject->oPosZ; @@ -491,7 +491,7 @@ static s32 Behavior19(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_sum_float(void) { +static s32 beh_cmd_sum_float(void) { u32 objectOffsetDst = (u8)((gBehCommand[0] >> 16) & 0xFF); u32 objectOffsetSrc1 = (u8)((gBehCommand[0] >> 8) & 0xFF); u32 objectOffsetSrc2 = (u8)((gBehCommand[0]) & 0xFF); @@ -504,7 +504,7 @@ static s32 beh_cmd_obj_sum_float(void) { } // unused -static s32 beh_cmd_obj_sum_int(void) { +static s32 beh_cmd_sum_int(void) { u32 objectOffsetDst = (u8)((gBehCommand[0] >> 16) & 0xFF); u32 objectOffsetSrc1 = (u8)((gBehCommand[0] >> 8) & 0xFF); u32 objectOffsetSrc2 = (u8)((gBehCommand[0]) & 0xFF); @@ -517,35 +517,35 @@ static s32 beh_cmd_obj_sum_int(void) { } static s32 beh_cmd_set_hitbox(void) { - s16 colSphereX = (s16)(gBehCommand[1] >> 16); - s16 colSphereY = (s16)(gBehCommand[1] & 0xFFFF); + s16 radius = (s16)(gBehCommand[1] >> 16); + s16 height = (s16)(gBehCommand[1] & 0xFFFF); - gCurrentObject->hitboxRadius = colSphereX; - gCurrentObject->hitboxHeight = colSphereY; + gCurrentObject->hitboxRadius = radius; + gCurrentObject->hitboxHeight = height; gBehCommand += 2; return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_float2(void) { - s16 arg0 = (s16)(gBehCommand[1] >> 16); - s16 arg1 = (s16)(gBehCommand[1] & 0xFFFF); +static s32 beh_cmd_set_hurtbox(void) { + s16 radius = (s16)(gBehCommand[1] >> 16); + s16 height = (s16)(gBehCommand[1] & 0xFFFF); - gCurrentObject->hurtboxRadius = arg0; - gCurrentObject->hurtboxHeight = arg1; + gCurrentObject->hurtboxRadius = radius; + gCurrentObject->hurtboxHeight = height; gBehCommand += 2; return BEH_CONTINUE; } -static s32 beh_cmd_collision_sphere(void) { - s16 colSphereX = (s16)(gBehCommand[1] >> 16); - s16 colSphereY = (s16)(gBehCommand[1] & 0xFFFF); - s16 unknown = (s16)(gBehCommand[2] >> 16); +static s32 beh_cmd_set_hitbox_with_offset(void) { + s16 radius = (s16)(gBehCommand[1] >> 16); + s16 height = (s16)(gBehCommand[1] & 0xFFFF); + s16 downOffset = (s16)(gBehCommand[2] >> 16); - gCurrentObject->hitboxRadius = colSphereX; - gCurrentObject->hitboxHeight = colSphereY; - gCurrentObject->hitboxDownOffset = unknown; + gCurrentObject->hitboxRadius = radius; + gCurrentObject->hitboxHeight = height; + gCurrentObject->hitboxDownOffset = downOffset; gBehCommand += 3; return BEH_CONTINUE; @@ -588,14 +588,14 @@ static void Unknown8038556C(s32 lastIndex) { cur_object_set_int(objectOffset, table[(s32)(lastIndex * RandomFloat())]); } -static s32 beh_cmd_collision_data(void) { +static s32 beh_cmd_load_collision_data(void) { u32 *collisionData = segmented_to_virtual((void *) gBehCommand[1]); gCurrentObject->collisionData = collisionData; gBehCommand += 2; return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_pos(void) { +static s32 beh_cmd_set_home(void) { gCurrentObject->oHomeX = gCurrentObject->oPosX; gCurrentObject->oHomeY = gCurrentObject->oPosY; gCurrentObject->oHomeZ = gCurrentObject->oPosZ; @@ -603,7 +603,7 @@ static s32 beh_cmd_obj_set_pos(void) { return BEH_CONTINUE; } -static s32 beh_cmd_interact_type(void) { +static s32 beh_cmd_set_interact_type(void) { gCurrentObject->oInteractType = (u32) gBehCommand[1]; gBehCommand += 2; @@ -628,7 +628,7 @@ static s32 beh_cmd_scale(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_set_physics(void) { +static s32 beh_cmd_set_obj_physics(void) { UNUSED f32 sp04, sp00; gCurrentObject->oWallHitboxRadius = (f32)(s16)(gBehCommand[1] >> 16); @@ -646,7 +646,7 @@ static s32 beh_cmd_obj_set_physics(void) { return BEH_CONTINUE; } -static s32 beh_cmd_obj_bit_clear_int32(void) { +static s32 beh_cmd_bit_clear_int32(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); s32 flags = gBehCommand[1]; @@ -658,18 +658,18 @@ static s32 beh_cmd_obj_bit_clear_int32(void) { return BEH_CONTINUE; } -static s32 beh_cmd_spawn_addr(void) { +static s32 beh_cmd_spawn_water_splash(void) { struct WaterSplashParams *arg0 = (struct WaterSplashParams *) gBehCommand[1]; spawn_water_splash(gCurrentObject, arg0); gBehCommand += 2; return BEH_CONTINUE; } -static s32 beh_cmd_text_anim_rate(void) { +static s32 beh_cmd_tex_anim_rate(void) { u8 objectOffset = (u8)((gBehCommand[0] >> 16) & 0xFF); - s16 arg1 = (gBehCommand[0] & 0xFFFF); + s16 rate = (gBehCommand[0] & 0xFFFF); - if ((gGlobalTimer % arg1) == 0) { + if ((gGlobalTimer % rate) == 0) { cur_object_add_int(objectOffset, 1); } @@ -690,55 +690,55 @@ static BehCommandProc BehaviorJumpTable[] = { beh_cmd_goto, beh_cmd_begin_repeat, beh_cmd_end_repeat, - beh_cmd_end_repeat_nobreak, + beh_cmd_end_repeat_continue, beh_cmd_begin_loop, beh_cmd_end_loop, beh_cmd_break, beh_cmd_break2, - beh_cmd_callnative, - beh_cmd_obj_add_float, - beh_cmd_obj_set_float, - beh_cmd_obj_add_int, - beh_cmd_obj_set_int, - beh_cmd_obj_or_int, - beh_cmd_obj_bit_clear_int, - beh_cmd_obj_set_int_rand_rshift, - beh_cmd_obj_set_float_rand, - beh_cmd_obj_set_int_rand, - beh_cmd_obj_add_float_rand, - beh_cmd_obj_add_int_rand_rshift, + beh_cmd_call_native, + beh_cmd_add_float, + beh_cmd_set_float, + beh_cmd_add_int, + beh_cmd_set_int, + beh_cmd_or_int, + beh_cmd_bit_clear_int, + beh_cmd_set_int_rand_rshift, + beh_cmd_set_random_float, + beh_cmd_set_random_int, + beh_cmd_add_random_float, + beh_cmd_add_int_rand_rshift, Behavior18, Behavior19, Behavior1A, - beh_cmd_graph_node, - beh_cmd_obj_load_chill, + beh_cmd_set_model, + beh_cmd_spawn_child, beh_cmd_deactivate, - beh_cmd_obj_drop_floor, - beh_cmd_obj_sum_float, - beh_cmd_obj_sum_int, + beh_cmd_drop_to_floor, + beh_cmd_sum_float, + beh_cmd_sum_int, beh_cmd_billboard, - beh_cmd_unhide, + beh_cmd_hide, beh_cmd_set_hitbox, Behavior24, beh_cmd_delay_var, Behavior26, - beh_cmd_obj_set_anims, - beh_cmd_obj_animate, - beh_cmd_obj_load_chill_param, - beh_cmd_collision_data, - beh_cmd_collision_sphere, - beh_cmd_obj_spawn, - beh_cmd_obj_set_pos, - beh_cmd_obj_set_float2, - beh_cmd_interact_type, - beh_cmd_obj_set_physics, + beh_cmd_load_animations, + beh_cmd_animate, + beh_cmd_spawn_child_with_param, + beh_cmd_load_collision_data, + beh_cmd_set_hitbox_with_offset, + beh_cmd_spawn_obj, + beh_cmd_set_home, + beh_cmd_set_hurtbox, + beh_cmd_set_interact_type, + beh_cmd_set_obj_physics, Behavior31, beh_cmd_scale, - beh_cmd_obj_bit_clear_int32, - beh_cmd_text_anim_rate, - beh_cmd_graph_clear, + beh_cmd_bit_clear_int32, + beh_cmd_tex_anim_rate, + beh_cmd_disable_rendering, Behavior36, - beh_cmd_spawn_addr, + beh_cmd_spawn_water_splash, }; void cur_object_exec_behavior(void) { diff --git a/src/engine/geo_layout.c b/src/engine/geo_layout.c index 5ad2149..3f450fd 100644 --- a/src/engine/geo_layout.c +++ b/src/engine/geo_layout.c @@ -65,20 +65,20 @@ UNUSED s32 D_8038BCA8; * might be for Mario and Luigi, and the other 10 could be different cameras for * different rooms / boss fights. An area might be structured like this: * - * geo_camera preset_player //Mario cam + * geo_camera mode_player //Mario cam * geo_open_node * geo_render_obj * geo_assign_as_view 1 // currently unused geo command * geo_close_node * - * geo_camera preset_player //Luigi cam + * geo_camera mode_player //Luigi cam * geo_open_node * geo_render_obj * geo_copy_view 1 // currently unused geo command * geo_assign_as_view 2 * geo_close_node * - * geo_camera preset_boss //boss fight cam + * geo_camera mode_boss //boss fight cam * geo_assign_as_view 3 * ... * @@ -348,26 +348,26 @@ void geo_layout_cmd_node_switch_case(void) { } /* - 0x0F: Create a camera scene graph node (GraphNodeCamera) + 0x0F: Create a camera scene graph node (GraphNodeCamera). The focus sets the Camera's areaCen position. cmd+0x02: s16 camera type (changes from course to course) - cmd+0x04: s16 fromX - cmd+0x06: s16 fromY - cmd+0x08: s16 fromZ - cmd+0x0A: s16 toX - cmd+0x0C: s16 toY - cmd+0x0E: s16 toZ + cmd+0x04: s16 posX + cmd+0x06: s16 posY + cmd+0x08: s16 posZ + cmd+0x0A: s16 focusX + cmd+0x0C: s16 focusY + cmd+0x0E: s16 focusZ cmd+0x10: GraphNodeFunc func */ void geo_layout_cmd_node_camera(void) { struct GraphNodeCamera *graphNode; s16 *cmdPos = (s16 *) &gGeoLayoutCommand[4]; - Vec3f fromPos, toPos; + Vec3f pos, focus; - cmdPos = read_vec3s_to_vec3f(fromPos, cmdPos); - cmdPos = read_vec3s_to_vec3f(toPos, cmdPos); + cmdPos = read_vec3s_to_vec3f(pos, cmdPos); + cmdPos = read_vec3s_to_vec3f(focus, cmdPos); - graphNode = init_graph_node_camera(gGraphNodePool, NULL, fromPos, toPos, + graphNode = init_graph_node_camera(gGraphNodePool, NULL, pos, focus, (GraphNodeFunc) cur_geo_cmd_ptr(0x10), cur_geo_cmd_s16(0x02)); register_scene_graph_node(&graphNode->fnNode.node); diff --git a/src/engine/graph_node.c b/src/engine/graph_node.c index 75e48bf..4a6495c 100644 --- a/src/engine/graph_node.c +++ b/src/engine/graph_node.c @@ -187,18 +187,18 @@ struct GraphNodeSwitchCase *init_graph_node_switch_case(struct AllocOnlyPool *po * Allocates and returns a newly created camera node */ struct GraphNodeCamera *init_graph_node_camera(struct AllocOnlyPool *pool, - struct GraphNodeCamera *graphNode, f32 *fromPos, - f32 *toPos, GraphNodeFunc func, s32 preset) { + struct GraphNodeCamera *graphNode, f32 *pos, + f32 *focus, GraphNodeFunc func, s32 mode) { if (pool != NULL) { graphNode = alloc_only_pool_alloc(pool, sizeof(struct GraphNodeCamera)); } if (graphNode != NULL) { init_scene_graph_node_links(&graphNode->fnNode.node, GRAPH_NODE_TYPE_CAMERA); - vec3f_copy(graphNode->from, fromPos); - vec3f_copy(graphNode->to, toPos); + vec3f_copy(graphNode->pos, pos); + vec3f_copy(graphNode->focus, focus); graphNode->fnNode.func = func; - graphNode->config.preset = preset; + graphNode->config.mode = mode; graphNode->roll = 0; graphNode->rollScreen = 0; diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index c99b9d0..ac05ed1 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -192,15 +192,15 @@ struct GraphNodeCamera { /*0x00*/ struct FnGraphNode fnNode; /*0x18*/ union { - // When the node is created, a preset is assigned to the node. - // Later in geo_camera_preset_and_pos a LevelCamera is allocated, - // the preset is passed to the struct, and the field is overridden + // When the node is created, a mode is assigned to the node. + // Later in geo_camera_main a Camera is allocated, + // the mode is passed to the struct, and the field is overridden // by a pointer to the struct. Gotta save those 4 bytes. - s32 preset; - struct LevelCamera *levelCamera; + s32 mode; + struct Camera *camera; } config; - /*0x1C*/ Vec3f from; - /*0x28*/ Vec3f to; + /*0x1C*/ Vec3f pos; + /*0x28*/ Vec3f focus; /*0x34*/ void *matrixPtr; // pointer to look-at matrix of this camera as a Mat4 /*0x38*/ s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen. /*0x3A*/ s16 rollScreen; // rolls screen while keeping the light direction consistent diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 1f09d3c..bad25cf 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -356,7 +356,7 @@ static void level_cmd_begin_area(void) { gAreas[areaIndex].unk04 = (struct GraphNode *) screenArea; if (node != NULL) { - gAreas[areaIndex].camera = (struct LevelCamera *) node->config.levelCamera; + gAreas[areaIndex].camera = (struct Camera *) node->config.camera; } else { gAreas[areaIndex].camera = NULL; } diff --git a/src/engine/math_util.c b/src/engine/math_util.c index 78418ba..beb60c5 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -625,6 +625,7 @@ void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) { /** * Take the vector starting at 'from' pointed at 'to' an retrieve the length * of that vector, as well as the yaw and pitch angles. + * Basically it converts the direction to spherical coordinates. */ void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) { register f32 x = to[0] - from[0]; diff --git a/src/engine/math_util.h b/src/engine/math_util.h index d068e63..b36498c 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -1,5 +1,6 @@ #ifndef _MATH_UTIL_H_ #define _MATH_UTIL_H_ +#include "types.h" /* * The sine and cosine tables overlap, but "#define gCosineTable (gSineTable + @@ -58,9 +59,9 @@ void mtxf_to_mtx(Mtx *a, f32 b[4][4]); void mtxf_rotate_xy(Mtx *a, s16 b); void get_pos_from_transform_mtx(Vec3f a, f32 b[4][4], f32 c[4][4]); void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw); -void vec3f_set_dist_and_angle(Vec3f a, Vec3f b, f32 c, s16 d, s16 e); -s32 approach_s32(s32 a, s32 b, s32 c, s32 d); -f32 approach_f32(f32 a, f32 b, f32 c, f32 d); +void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw); +s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec); +f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec); s16 atan2s(f32 a, f32 b); f32 atan2f(f32 a, f32 b); void spline_get_weights(Vec4f a, f32 b, UNUSED s32 c); diff --git a/src/game/area.h b/src/game/area.h index 8a5048d..67c02d9 100644 --- a/src/game/area.h +++ b/src/game/area.h @@ -41,43 +41,6 @@ struct SpawnInfo /*0x1C*/ struct SpawnInfo *next; }; -// Some of these might need to be renamed at some point. -#define CAMERA_PRESET_NONE 0x00 -#define CAMERA_PRESET_OPEN_CAMERA 0x01 -#define CAMERA_PRESET_REVERSE_TOWER 0x02 -#define CAMERA_PRESET_BEHIND_MARIO 0x03 -#define CAMERA_PRESET_CLOSE 0x04 // Inside Castle / Big Boo's Haunt -#define CAMERA_PRESET_C_UP_LOOK 0x06 -#define CAMERA_PRESET_WATER_SURFACE 0x08 -#define CAMERA_PRESET_SLIDE_HOOT 0x09 -#define CAMERA_PRESET_INSIDE_CANNON 0x0A -#define CAMERA_PRESET_BOSS_FIGHT 0x0B -#define CAMERA_PRESET_PARALLEL_TRACKING 0x0C -#define CAMERA_PRESET_FIXED_REF_POINT 0x0D -#define CAMERA_PRESET_PLATFORM_LEVEL 0x0E // Bowser Courses / Rainbow Road -#define CAMERA_PRESET_FREE_ROAM 0x10 -#define CAMERA_PRESET_SPIRAL_STAIRS 0x11 - -// Used mostly in camera.c -struct LevelCamera -{ - /*0x00*/ u8 currPreset; // What type of preset the camera uses (see defines above) - /*0x01*/ u8 defPreset; - /*0x02*/ s16 trueYaw; - /*0x04*/ Vec3f focus; - /*0x10*/ Vec3f pos; - /*0x1C*/ u8 filler1C[0x28-0x1C]; - /*0x28*/ f32 xFocus; - /*0x2C*/ f32 zFocus; - /*0x30*/ u8 cutscene; - /*0x31*/ u8 filler31[0x9]; - /*0x3A*/ s16 storedYaw; - /*0x3C*/ u8 filler3C[0x64-0x3C]; - /*0x64*/ u8 unk64; - /*0x65*/ u8 filler65[3]; - /*0x68*/ f32 unk68; -}; - struct UnusedArea28 { /*0x00*/ s16 unk00; @@ -106,7 +69,7 @@ struct Area /*0x18*/ struct WarpNode *paintingWarpNodes; /*0x1C*/ struct InstantWarp *instantWarps; /*0x20*/ struct SpawnInfo *objectSpawnInfos; - /*0x24*/ struct LevelCamera *camera; + /*0x24*/ struct Camera *camera; /*0x28*/ struct UnusedArea28 *unused28; // Filled by level script 0x3A, but is unused. /*0x2C*/ struct Whirlpool *whirlpools[2]; /*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30) @@ -114,21 +77,6 @@ struct Area /*0x38*/ u16 musicParam2; }; -/** - * Helper macro for defining which areas of a level should zoom out the camera when the game is paused. - * Because a mask is used by two levels, the pattern will repeat when more than 4 areas are used by a level. - */ -#define ZOOMOUT_AREA_MASK(level1Area1, level1Area2, level1Area3, level1Area4, \ - level2Area1, level2Area2, level2Area3, level2Area4) \ - ((level2Area4) << 7 | \ - (level2Area3) << 6 | \ - (level2Area2) << 5 | \ - (level2Area1) << 4 | \ - (level1Area4) << 3 | \ - (level1Area3) << 2 | \ - (level1Area2) << 1 | \ - (level1Area1) << 0) - // All the transition data to be used in screen_transition.c struct WarpTransitionData { diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index 0aefcef..5975679 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -100,8 +100,8 @@ extern s8 gDoorAdjacentRooms[][2]; extern u8 inside_castle_seg7_collision_ddd_warp_2[]; extern u8 inside_castle_seg7_collision_ddd_warp[]; extern s32 gDialogResponse; -extern s32 gCutsceneActive; -extern u8 gCutsceneNumber; +extern s32 gObjCutsceneDone; +extern u8 gRecentCutscene; extern s8 *D_8032F96C[]; extern s16 bowser_seg6_unkmoveshorts_060576FC[]; extern struct Animation *blue_fish_seg3_anims_0301C2B0[]; diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 671eb4d..b6b1d2a 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -2,7 +2,7 @@ #define _BEHAVIOR_ACTIONS_H extern void func_802AA618(s32,s32,f32); -extern void bhv_spawn_star_objects(u32); +extern void bhv_spawn_star_no_level_exit(u32); extern void bhv_star_door_loop_2(); extern void spawn_triangle_break_particles(s16,s16,f32,s16); extern void func_802ADA94(void); @@ -61,8 +61,8 @@ void bhv_koopa_shell_underwater_loop(void); void BehFadingWarpLoop(void); void bhv_warp_loop(void); void bhv_white_puff_exploding_loop(void); -void bhv_unused_080c_init(void); -void bhv_unused_080c_loop(void); +void bhv_spawned_star_init(void); +void bhv_spawned_star_loop(void); void bhv_coin_init(void); void bhv_coin_loop(void); void bhv_coin_inside_boo_loop(void); diff --git a/src/game/behaviors/amp.inc.c b/src/game/behaviors/amp.inc.c index b48100b..2faa47a 100644 --- a/src/game/behaviors/amp.inc.c +++ b/src/game/behaviors/amp.inc.c @@ -66,12 +66,12 @@ static void check_amp_attack(void) { * Unhide the amp and grow until normal size, then begin chasing Mario. */ static void homing_amp_appear_loop(void) { - // gCameraStatus.camFocAndPosCurrAndGoal[3] is the camera's goal position. + // gLakituState.goalPos is the position lakitu is moving towards. // In Lakitu and Mario cam, it is usually very close to the current camera position. // In Fixed cam, it is the point behind Mario the camera will go to when transitioning // to Lakitu cam. Homing amps will point themselves towards this point when appearing. - f32 relativeTargetX = gCameraStatus.camFocAndPosCurrAndGoal[3][0] - o->oPosX; - f32 relativeTargetZ = gCameraStatus.camFocAndPosCurrAndGoal[3][2] - o->oPosZ; + f32 relativeTargetX = gLakituState.goalPos[0] - o->oPosX; + f32 relativeTargetZ = gLakituState.goalPos[2] - o->oPosZ; s16 targetYaw = atan2s(relativeTargetZ, relativeTargetX); o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, targetYaw, 0x1000); diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c index 0ca74e3..5a257ad 100644 --- a/src/game/behaviors/bobomb.inc.c +++ b/src/game/behaviors/bobomb.inc.c @@ -319,7 +319,7 @@ void BobombBuddyCannonLoop(s16 dialogFirstText, s16 dialogSecondText) { switch (o->oBobombBuddyCannonStatus) { case BOBOMB_BUDDY_CANNON_UNOPENED: - buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, dialogFirstText); + buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogFirstText); if (buddyText != 0) { save_file_set_cannon_unlocked(); cannonClosed = obj_nearest_object_with_behavior(bhvCannonClosed); @@ -338,7 +338,7 @@ void BobombBuddyCannonLoop(s16 dialogFirstText, s16 dialogSecondText) { break; case BOBOMB_BUDDY_CANNON_OPENED: - buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, dialogSecondText); + buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogSecondText); if (buddyText != 0) o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_STOP_TALKING; break; @@ -361,7 +361,7 @@ void BobombBuddyTalkLoop(void) { switch (o->oBobombBuddyRole) { case BOBOMB_BUDDY_ROLE_ADVICE: - if (cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, o->oBehParams2ndByte) != BOBOMB_BUDDY_BP_STYPE_GENERIC) { + if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, o->oBehParams2ndByte) != BOBOMB_BUDDY_BP_STYPE_GENERIC) { set_mario_npc_dialog(0); o->activeFlags &= ~0x20; /* bit 5 */ diff --git a/src/game/behaviors/bowling_ball.inc.c b/src/game/behaviors/bowling_ball.inc.c index 4f7a5a3..00ff840 100644 --- a/src/game/behaviors/bowling_ball.inc.c +++ b/src/game/behaviors/bowling_ball.inc.c @@ -142,7 +142,7 @@ void bhv_bowling_ball_loop(void) { } if (o->oBehParams2ndByte != 4) - func_8027F440(4, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ); set_object_visibility(o, 4000); } @@ -222,7 +222,7 @@ void bhv_bob_pit_bowling_ball_loop(void) { o->oForwardVel = 28.0f; func_802EDA14(); - func_8027F440(4, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ); PlaySound(SOUND_ENV_UNKNOWN2); set_object_visibility(o, 3000); } @@ -243,7 +243,7 @@ void bhv_free_bowling_ball_roll_loop(void) { func_802EDA14(); if (o->oForwardVel > 10.0f) { - func_8027F440(4, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ); PlaySound(SOUND_ENV_UNKNOWN2); } diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index 4e774b2..fe75441 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -109,7 +109,7 @@ void func_802B392C(s32 *a) { if (o->oMoveFlags & 1) { a[0]++; if (a[0] < 4) { - func_802A11B4(o, 8); + obj_start_cam_event(o, CAM_EVENT_BOWSER_THROW_BOUNCE); func_802AA618(0, 0, 60.0f); PlaySound2(SOUND_OBJ_BOWSER_WALK); } @@ -459,7 +459,7 @@ s32 func_802B4A94(void) { func_802AA618(0, 0, 60.0f); set_obj_animation_and_sound_state(8); o->header.gfx.unk38.animFrame = 0; - func_802A11B4(o, 7); + obj_start_cam_event(o, CAM_EVENT_BOWSER_JUMP); if (BITDW) { if (o->oDistanceToMario < 850.0f) gMarioObject->oInteractStatus |= INTERACT_GRABBABLE; @@ -1161,7 +1161,7 @@ void bhv_bowser_init(void) { o->oBehParams2ndByte = level; o->oBowserUnk1B2 = D_8032F690[level]; o->oHealth = D_8032F694[level]; - func_802A11B4(o, 4); + obj_start_cam_event(o, CAM_EVENT_BOWSER_INIT); o->oAction = 5; o->oBowserUnk1AE = 0; o->oBowserEyesShut = 0; @@ -1325,7 +1325,7 @@ void ActionFallingBowserPlatform2(void) { if (o->oTimer == 0 || o->oTimer == 22) PlaySound2(SOUND_GENERAL_BOWSER_PLATFORM_2); if (o->oTimer < 22) { - set_camera_shake_2(SHAKE_2_FALLING_BITS_PLAT); + set_environmental_camera_shake(SHAKE_ENV_FALLING_BITS_PLAT); o->oVelY = 8.0f; o->oGravity = 0.0f; } else diff --git a/src/game/behaviors/bowser_bomb.inc.c b/src/game/behaviors/bowser_bomb.inc.c index 5efb184..e342048 100644 --- a/src/game/behaviors/bowser_bomb.inc.c +++ b/src/game/behaviors/bowser_bomb.inc.c @@ -11,7 +11,7 @@ void bhv_bowser_bomb_loop(void) { { spawn_object(o, MODEL_BOWSER_FLAMES, bhvBowserBombExplosion); create_sound_spawner(SOUND_GENERAL_BOWSER_BOMB_EXPLOSION); - func_8027F440(3, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_LARGE, o->oPosX, o->oPosY, o->oPosZ); o->activeFlags = 0; } diff --git a/src/game/behaviors/bullet_bill.inc.c b/src/game/behaviors/bullet_bill.inc.c index 1c61ab2..02d8725 100644 --- a/src/game/behaviors/bullet_bill.inc.c +++ b/src/game/behaviors/bullet_bill.inc.c @@ -43,7 +43,7 @@ void ActionBulletBill2(void) { obj_rotate_yaw_toward(o->oAngleToMario, 0x100); if (o->oTimer == 50) { PlaySound2(SOUND_OBJ_POUNDING_CANNON); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); } if (o->oTimer > 150 || o->oMoveFlags & 0x200) { o->oAction = 3; diff --git a/src/game/behaviors/bully.inc.c b/src/game/behaviors/bully.inc.c index 4b7bed4..e06de12 100644 --- a/src/game/behaviors/bully.inc.c +++ b/src/game/behaviors/bully.inc.c @@ -349,7 +349,7 @@ void bhv_big_bully_with_minions_loop(void) { if (collisionFlags == 1) { PlaySound2(SOUND_OBJ_THWOMP); - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); func_802A3004(); } diff --git a/src/game/behaviors/camera_lakitu.inc.c b/src/game/behaviors/camera_lakitu.inc.c index e4eacf7..d1af453 100644 --- a/src/game/behaviors/camera_lakitu.inc.c +++ b/src/game/behaviors/camera_lakitu.inc.c @@ -115,7 +115,7 @@ static void camera_lakitu_intro_act_show_dialog(void) { } } } - } else if (obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0, CUTSCENE_DIALOG_1, DIALOG_034) != 0) { + } else if (obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0, CUTSCENE_DIALOG, DIALOG_034) != 0) { o->oCameraLakituFinishedDialog = TRUE; } } @@ -151,22 +151,22 @@ void bhv_camera_lakitu_update(void) { break; } } else { - f32 val0C = (f32) 0x875C3D / 0x800 - gCameraStatus.camFocAndPosCurrAndGoal[1][0]; - if (gCameraStatus.camFocAndPosCurrAndGoal[1][0] < 1700.0f || val0C < 0.0f) { + f32 val0C = (f32) 0x875C3D / 0x800 - gLakituState.curPos[0]; + if (gLakituState.curPos[0] < 1700.0f || val0C < 0.0f) { obj_hide(); } else { obj_unhide(); - o->oPosX = gCameraStatus.camFocAndPosCurrAndGoal[1][0]; - o->oPosY = gCameraStatus.camFocAndPosCurrAndGoal[1][1]; - o->oPosZ = gCameraStatus.camFocAndPosCurrAndGoal[1][2]; + o->oPosX = gLakituState.curPos[0]; + o->oPosY = gLakituState.curPos[1]; + o->oPosZ = gLakituState.curPos[2]; - o->oHomeX = gCameraStatus.camFocAndPosCurrAndGoal[0][0]; - o->oHomeZ = gCameraStatus.camFocAndPosCurrAndGoal[0][2]; + o->oHomeX = gLakituState.curFocus[0]; + o->oHomeZ = gLakituState.curFocus[2]; o->oFaceAngleYaw = -obj_angle_to_home(); o->oFaceAnglePitch = atan2s(obj_lateral_dist_to_home(), - o->oPosY - gCameraStatus.camFocAndPosCurrAndGoal[0][1]); + o->oPosY - gLakituState.curFocus[1]); o->oPosX = (f32) 0x875C3D / 0x800 + val0C; } diff --git a/src/game/behaviors/capswitch.inc.c b/src/game/behaviors/capswitch.inc.c index 651a9f4..a417f22 100644 --- a/src/game/behaviors/capswitch.inc.c +++ b/src/game/behaviors/capswitch.inc.c @@ -28,7 +28,7 @@ void ActionActivateCapSwitch2(void) { if (o->oTimer < 5) { func_802A3398(2, 4, 0.5f, 0.1f); if (o->oTimer == 4) { - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); func_802A3004(); spawn_triangle_break_particles(60, 139, 0.3f, o->oBehParams2ndByte); } diff --git a/src/game/behaviors/chain_chomp.inc.c b/src/game/behaviors/chain_chomp.inc.c index cf02757..6763402 100644 --- a/src/game/behaviors/chain_chomp.inc.c +++ b/src/game/behaviors/chain_chomp.inc.c @@ -336,7 +336,7 @@ static void chain_chomp_released_break_gate(void) { */ static void chain_chomp_released_jump_away(void) { if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { - gCutsceneActive = TRUE; + gObjCutsceneDone = TRUE; o->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_END_CUTSCENE; } } @@ -538,7 +538,7 @@ void bhv_chain_chomp_gate_init(void) { void bhv_chain_chomp_gate_update(void) { if (o->parentObj->oChainChompHitGate) { func_802A3034(SOUND_GENERAL_WALL_EXPLOSION); - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); func_802AA618(0, 0x7F, 200.0f); spawn_triangle_break_particles(30, 0x8A, 3.0f, 4); mark_object_for_deletion(o); diff --git a/src/game/behaviors/door.inc.c b/src/game/behaviors/door.inc.c index 4b30dbb..a9cf4b9 100644 --- a/src/game/behaviors/door.inc.c +++ b/src/game/behaviors/door.inc.c @@ -14,10 +14,10 @@ void func_802AC070(s32 sp18) { void func_802AC0B8(void) { if (segmented_to_virtual(bhvDoor) == o->behavior) - gPlayerStatusForCamera->unk1C[1] = 6; + gPlayerCameraState->cameraEvent = CAM_EVENT_DOOR; else - gPlayerStatusForCamera->unk1C[1] = 5; - gPlayerStatusForCamera->usedObj = o; + gPlayerCameraState->cameraEvent = CAM_EVENT_DOOR_WARP; + gPlayerCameraState->usedObj = o; } void func_802AC130(void) { diff --git a/src/game/behaviors/elevator.inc.c b/src/game/behaviors/elevator.inc.c index d0c8bd4..6782c2c 100644 --- a/src/game/behaviors/elevator.inc.c +++ b/src/game/behaviors/elevator.inc.c @@ -2,7 +2,7 @@ void func_802AD01C(void) { PlaySound2(SOUND_GENERAL_QUIET_POUND1); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); } void ActionElevator0(void) { @@ -65,7 +65,7 @@ void ActionElevator2() // Pretty similar code to action 1 void ActionElevator4() { o->oVelY = 0; if (o->oTimer == 0) { - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); PlaySound2(SOUND_GENERAL_METAL_POUND); } if (!mario_is_in_air_action() && !obj_is_mario_on_platform()) @@ -76,7 +76,7 @@ void ActionElevator3() // nearly identical to action 2 { o->oVelY = 0; if (o->oTimer == 0) { - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); PlaySound2(SOUND_GENERAL_METAL_POUND); } if (!mario_is_in_air_action() && !obj_is_mario_on_platform()) diff --git a/src/game/behaviors/end_birds_1.inc.c b/src/game/behaviors/end_birds_1.inc.c index 16c9ea8..1aa75c3 100644 --- a/src/game/behaviors/end_birds_1.inc.c +++ b/src/game/behaviors/end_birds_1.inc.c @@ -17,7 +17,7 @@ void bhv_end_birds_1_loop(void) { gCurrentObject->oIntroLakituUnk108); if (gCurrentObject->oTimer < 100) - func_8029A7DC(gCurrentObject, sp34, 0, 0, 0x20, 0x20); + obj_rotate_towards_point(gCurrentObject, sp34, 0, 0, 0x20, 0x20); if ((gCurrentObject->oEndBirdUnk104 == 0.f) && (gCurrentObject->oTimer == 0)) PlaySound2(SOUND_GENERAL_BIRDS_FLY_AWAY); if (gCutsceneTimer == 0) diff --git a/src/game/behaviors/end_birds_2.inc.c b/src/game/behaviors/end_birds_2.inc.c index 25b39d0..3a7580c 100644 --- a/src/game/behaviors/end_birds_2.inc.c +++ b/src/game/behaviors/end_birds_2.inc.c @@ -15,12 +15,12 @@ void bhv_end_birds_2_loop(void) { gCurrentObject->oAction += 1; break; case 1: - vec3f_get_dist_and_angle(gCurrLevelCamera->pos, gCurrLevelCamera->focus, &sp34, &sp32, + vec3f_get_dist_and_angle(gCamera->pos, gCamera->focus, &sp34, &sp32, &sp30); sp30 += 0x1000; sp32 += 0; // nice work, Nintendo - vec3f_set_dist_and_angle(gCurrLevelCamera->pos, sp3C, 14000.f, sp32, sp30); - func_8029A7DC(gCurrentObject, sp3C, 0, 0, 8, 8); + vec3f_set_dist_and_angle(gCamera->pos, sp3C, 14000.f, sp32, sp30); + obj_rotate_towards_point(gCurrentObject, sp3C, 0, 0, 8, 8); if ((gCurrentObject->oEndBirdUnk104 == 0.f) && (gCurrentObject->oTimer == 0)) PlaySound2(SOUND_GENERAL_BIRDS_FLY_AWAY); diff --git a/src/game/behaviors/explosion.inc.c b/src/game/behaviors/explosion.inc.c index 6c56892..921df6d 100644 --- a/src/game/behaviors/explosion.inc.c +++ b/src/game/behaviors/explosion.inc.c @@ -2,7 +2,7 @@ void bhv_explosion_init(void) { create_sound_spawner(SOUND_GENERAL2_BOBOMB_EXPLOSION); - set_camera_shake_2(SHAKE_2_UNKNOWN_1); + set_environmental_camera_shake(SHAKE_ENV_EXPLOSION); o->oOpacity = 255; } diff --git a/src/game/behaviors/eyerok.inc.c b/src/game/behaviors/eyerok.inc.c index 0179925..c0f2f46 100644 --- a/src/game/behaviors/eyerok.inc.c +++ b/src/game/behaviors/eyerok.inc.c @@ -63,7 +63,7 @@ static void eyerok_boss_act_wake_up(void) { } static void eyerok_boss_act_show_intro_text(void) { - if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG_1, DIALOG_117)) { + if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_117)) { o->oAction = EYEROK_BOSS_ACT_FIGHT; } } @@ -117,7 +117,7 @@ static void eyerok_boss_act_fight(void) { static void eyerok_boss_act_die(void) { if (o->oTimer == 60) { - if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG_1, DIALOG_118)) { + if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_118)) { create_star(0.0f, -900.0f, -3700.0f); } else { o->oTimer -= 1; @@ -175,7 +175,7 @@ static s32 eyerok_hand_check_attacked(void) { static void func_8030DBA8(void) { PlaySound2(SOUND_OBJ_POUNDING_LOUD); - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); func_802ADA94(); } diff --git a/src/game/behaviors/falling_pillar.inc.c b/src/game/behaviors/falling_pillar.inc.c index a9960c2..d5c0e02 100644 --- a/src/game/behaviors/falling_pillar.inc.c +++ b/src/game/behaviors/falling_pillar.inc.c @@ -105,7 +105,7 @@ void bhv_falling_pillar_loop(void) { o->oPosZ += coss(o->oFaceAngleYaw) * 500.0f; // Make the camera shake and spawn dust clouds. - func_8027F440(2, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_MEDIUM, o->oPosX, o->oPosY, o->oPosZ); func_802AA618(0, 0, 92.0f); // Go invisible. diff --git a/src/game/behaviors/grand_star.inc.c b/src/game/behaviors/grand_star.inc.c index b980fe3..bb8d6e3 100644 --- a/src/game/behaviors/grand_star.inc.c +++ b/src/game/behaviors/grand_star.inc.c @@ -50,7 +50,7 @@ void bhv_grand_star_loop(void) { } else if (o->oVelY < 0.0f && o->oPosY < o->oHomeY + 200.0f) { o->oPosY = o->oHomeY + 200.0f; func_802B29B0(); - gCutsceneActive = 1; + gObjCutsceneDone = 1; set_mario_npc_dialog(0); o->oAction++; o->oInteractStatus = 0; diff --git a/src/game/behaviors/hoot.inc.c b/src/game/behaviors/hoot.inc.c index b3f753d..551a763 100644 --- a/src/game/behaviors/hoot.inc.c +++ b/src/game/behaviors/hoot.inc.c @@ -188,7 +188,7 @@ void HootActionLoop(void) { if (o->oPosY < 2700.0f) { set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); - if (cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, DIALOG_045)) { + if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_045)) { clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); o->oAction = HOOT_ACT_TIRED; @@ -255,7 +255,7 @@ void bhv_hoot_loop(void) { case HOOT_AVAIL_WANTS_TO_TALK: HootAwakeLoop(); - if (set_mario_npc_dialog(2) == 2 && cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, DIALOG_044)) { + if (set_mario_npc_dialog(2) == 2 && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_044)) { set_mario_npc_dialog(0); obj_become_tangible(); diff --git a/src/game/behaviors/horizontal_grindel.inc.c b/src/game/behaviors/horizontal_grindel.inc.c index 2ace6ab..e864d0b 100644 --- a/src/game/behaviors/horizontal_grindel.inc.c +++ b/src/game/behaviors/horizontal_grindel.inc.c @@ -8,7 +8,7 @@ void bhv_horizontal_grindel_update(void) { if (!o->oHorizontalGrindelOnGround) { PlaySound2(SOUND_OBJ_THWOMP); o->oHorizontalGrindelOnGround = TRUE; - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); o->oHorizontalGrindelDistToHome = obj_lateral_dist_to_home(); o->oForwardVel = 0.0f; diff --git a/src/game/behaviors/intro_lakitu.inc.c b/src/game/behaviors/intro_lakitu.inc.c index a17e519..b117fec 100644 --- a/src/game/behaviors/intro_lakitu.inc.c +++ b/src/game/behaviors/intro_lakitu.inc.c @@ -14,11 +14,11 @@ void intro_lakitu_set_offset_from_camera(struct Object *o, Vec3f offset) { Vec3s focusAngles; s16 offsetPitch, offsetYaw; - vec3f_add(offset, gCurrLevelCamera->pos); - vec3f_get_dist_and_angle(gCurrLevelCamera->pos, gCurrLevelCamera->focus, + vec3f_add(offset, gCamera->pos); + vec3f_get_dist_and_angle(gCamera->pos, gCamera->focus, &dist, &focusAngles[0], &focusAngles[1]); - vec3f_get_dist_and_angle(gCurrLevelCamera->pos, offset, &dist, &offsetPitch, &offsetYaw); - vec3f_set_dist_and_angle(gCurrLevelCamera->pos, offset, dist, + vec3f_get_dist_and_angle(gCamera->pos, offset, &dist, &offsetPitch, &offsetYaw); + vec3f_set_dist_and_angle(gCamera->pos, offset, dist, focusAngles[0] + offsetPitch, focusAngles[1] + offsetYaw); vec3f_to_object_pos(o, offset); } @@ -68,7 +68,7 @@ void bhv_intro_lakitu_loop(void) { gCurrentObject->oIntroLakituSplineSegmentProgress = 0.f; gCurrentObject->oIntroLakituCloud = spawn_object_relative_with_scale(1, 0, 0, 0, 2.f, gCurrentObject, MODEL_MIST, bhvCloud); - if (gCurrLevelCamera->cutscene == CUTSCENE_END_WAVING) + if (gCamera->cutscene == CUTSCENE_END_WAVING) gCurrentObject->oAction = 100; else gCurrentObject->oAction += 1; @@ -77,9 +77,9 @@ void bhv_intro_lakitu_loop(void) { case 1: obj_enable_rendering(); if ((gCutsceneTimer > 350) && (gCutsceneTimer < 458)) { - gCurrentObject->oPosX = gCurrLevelCamera->pos[0]; - gCurrentObject->oPosY = gCurrLevelCamera->pos[1] + 500.f; - gCurrentObject->oPosZ = gCurrLevelCamera->pos[2]; + gCurrentObject->oPosX = gCamera->pos[0]; + gCurrentObject->oPosY = gCamera->pos[1] + 500.f; + gCurrentObject->oPosZ = gCamera->pos[2]; } if (gCutsceneTimer > 52) PlaySound(SOUND_AIR_LAKITU_FLY_HIGHPRIO); @@ -136,19 +136,19 @@ void bhv_intro_lakitu_loop(void) { vec3f_set(sp58, -1128.f, 560.f, 4664.f); gCurrentObject->oMoveAngleYaw += 0x200; gCurrentObject->oIntroLakituUnk100 = - approach_f32_exponential(gCurrentObject->oIntroLakituUnk100, 100.f, 0.03f); + approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk100, 100.f, 0.03f); gCurrentObject->oFaceAnglePitch = atan2s(200.f, gCurrentObject->oPosY - 400.f); - gCurrentObject->oFaceAngleYaw = approach_s16_exponential( + gCurrentObject->oFaceAngleYaw = approach_s16_asymptotic( gCurrentObject->oFaceAngleYaw, gCurrentObject->oMoveAngleYaw + 0x8000, 4); vec3f_set_dist_and_angle(sp58, sp4C, gCurrentObject->oIntroLakituUnk100, 0, gCurrentObject->oMoveAngleYaw); sp4C[1] += 150.f * coss((s16) gCurrentObject->oIntroLakituUnk104); gCurrentObject->oIntroLakituUnk104 += gCurrentObject->oIntroLakituUnk108; gCurrentObject->oIntroLakituUnk108 = - approach_f32_exponential(gCurrentObject->oIntroLakituUnk108, 512.f, 0.05f); + approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk108, 512.f, 0.05f); sp4C[0] += gCurrentObject->oIntroLakituUnk10C; gCurrentObject->oIntroLakituUnk10C = - approach_f32_exponential(gCurrentObject->oIntroLakituUnk10C, 0.f, 0.05f); + approach_f32_asymptotic(gCurrentObject->oIntroLakituUnk10C, 0.f, 0.05f); vec3f_to_object_pos(gCurrentObject, sp4C); if (gCurrentObject->oTimer == 31) { @@ -175,8 +175,7 @@ void bhv_intro_lakitu_loop(void) { case 100: obj_enable_rendering(); vec3f_set(sp64, -100.f, 100.f, 300.f); - set_pos_from_face_angle_and_vec3f(sp4C, gCurrLevelCamera->pos, sp64, - sMarioStatusForCamera->faceAngle); + offset_rotated(sp4C, gCamera->pos, sp64, sMarioCamState->faceAngle); vec3f_to_object_pos(gCurrentObject, sp4C); gCurrentObject->oMoveAnglePitch = 0x1000; gCurrentObject->oMoveAngleYaw = 0x9000; @@ -189,11 +188,11 @@ void bhv_intro_lakitu_loop(void) { object_pos_to_vec3f(sp4C, gCurrentObject); if (gCurrentObject->oTimer > 60) { gCurrentObject->oForwardVel = - approach_f32_exponential(gCurrentObject->oForwardVel, -10.f, 0.05f); + approach_f32_asymptotic(gCurrentObject->oForwardVel, -10.f, 0.05f); gCurrentObject->oMoveAngleYaw += 0x78; gCurrentObject->oMoveAnglePitch += 0x40; gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric( - gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCurrLevelCamera->pos), + gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCamera->pos), 0x200); } if (gCurrentObject->oTimer > 105) { @@ -207,12 +206,12 @@ void bhv_intro_lakitu_loop(void) { case 102: object_pos_to_vec3f(sp4C, gCurrentObject); gCurrentObject->oForwardVel = - approach_f32_exponential(gCurrentObject->oForwardVel, 60.f, 0.05f); + approach_f32_asymptotic(gCurrentObject->oForwardVel, 60.f, 0.05f); gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric( - gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCurrLevelCamera->pos), 0x200); + gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(sp4C, gCamera->pos), 0x200); if (gCurrentObject->oTimer < 62) gCurrentObject->oMoveAngleYaw = - approach_s16_exponential(gCurrentObject->oMoveAngleYaw, 0x1800, 0x1E); + approach_s16_asymptotic(gCurrentObject->oMoveAngleYaw, 0x1800, 0x1E); gCurrentObject->oMoveAnglePitch = camera_approach_s16_symmetric(gCurrentObject->oMoveAnglePitch, -0x2000, 0x5A); gCurrentObject->oFaceAnglePitch = 0; diff --git a/src/game/behaviors/intro_peach.inc.c b/src/game/behaviors/intro_peach.inc.c index c88ad16..dfbd833 100644 --- a/src/game/behaviors/intro_peach.inc.c +++ b/src/game/behaviors/intro_peach.inc.c @@ -9,8 +9,8 @@ void intro_peach_set_pos_and_opacity(struct Object *o, f32 targetOpacity, f32 in s16 focusPitch, focusYaw; f32 UNUSED dist, newOpacity; - vec3f_get_dist_and_angle(gCameraStatus.pos, gCameraStatus.focus, &dist, &focusPitch, &focusYaw); - vec3f_set_dist_and_angle(gCameraStatus.pos, newPos, o->oIntroPeachDistToCamera, o->oIntroPeachPitchFromFocus + focusPitch, + vec3f_get_dist_and_angle(gLakituState.pos, gLakituState.focus, &dist, &focusPitch, &focusYaw); + vec3f_set_dist_and_angle(gLakituState.pos, newPos, o->oIntroPeachDistToCamera, o->oIntroPeachPitchFromFocus + focusPitch, o->oIntroPeachYawFromFocus + focusYaw); vec3f_to_object_pos(o, newPos); newOpacity = o->oOpacity; diff --git a/src/game/behaviors/intro_scene.inc.c b/src/game/behaviors/intro_scene.inc.c index f91183a..02a8da9 100644 --- a/src/game/behaviors/intro_scene.inc.c +++ b/src/game/behaviors/intro_scene.inc.c @@ -6,8 +6,8 @@ void func_8029B964(struct Object *parent, s16 xOffset, s16 yOffset, s16 zOffset, struct Object *sp1C = spawn_object(parent, model, behavior); sp1C->header.gfx.unk38.animFrame = RandomFloat() * 6.f; - sp1C->oEndBirdUnk104 = D_8033B6F0[9].unk4[0]; - D_8033B6F0[9].unk4[0] += 1.f; + sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0]; + sCutsceneVars[9].point[0] += 1.f; sp1C->oPosX += xOffset; sp1C->oPosY += yOffset; if (gCutsceneTimer > 700) @@ -22,14 +22,14 @@ void func_8029B964(struct Object *parent, s16 xOffset, s16 yOffset, s16 zOffset, void bhv_intro_scene_loop(void) { UNUSED struct Object *sp34; - if (sCutscenePhase != 0) { - gCurrentObject->oPosX = gCurrLevelCamera->pos[0]; - gCurrentObject->oPosY = gCurrLevelCamera->pos[1]; - gCurrentObject->oPosZ = gCurrLevelCamera->pos[2]; + if (gCutsceneObjSpawn != 0) { + gCurrentObject->oPosX = gCamera->pos[0]; + gCurrentObject->oPosY = gCamera->pos[1]; + gCurrentObject->oPosZ = gCamera->pos[2]; gCurrentObject->oMoveAnglePitch = 0; gCurrentObject->oMoveAngleYaw = 0; - switch (sCutscenePhase) { + switch (gCutsceneObjSpawn) { case 6: sp34 = spawn_object(gCurrentObject, MODEL_LAKITU, bhvBeginningLakitu); break; @@ -71,6 +71,6 @@ void bhv_intro_scene_loop(void) { break; } - sCutscenePhase = 0; + gCutsceneObjSpawn = 0; } } diff --git a/src/game/behaviors/kickable_board.inc.c b/src/game/behaviors/kickable_board.inc.c index 38dee84..ee56370 100644 --- a/src/game/behaviors/kickable_board.inc.c +++ b/src/game/behaviors/kickable_board.inc.c @@ -66,7 +66,7 @@ void bhv_kickable_board_loop(void) { o->oFaceAnglePitch = -0x4000; o->oAngleVelPitch = 0; o->oAction++; - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); PlaySound2(SOUND_GENERAL_UNKNOWN4); } load_object_collision_model(); diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index 5cc3669..d1665a9 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -19,7 +19,7 @@ void ActionKingBobomb0(void) { o->oSubAction++; func_8031FFB4(0, 60, 40); } - } else if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, DIALOG_017)) { + } else if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_017)) { o->oAction = 2; o->oFlags |= OBJ_FLAG_HOLDABLE; } @@ -40,7 +40,7 @@ void ActionKingBobomb2(void) { } if (o->oKingBobombUnk100 == 0) { if (obj_check_anim_frame(15)) - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); if (func_802A4AB0(4)) o->oKingBobombUnk100++; } else { @@ -126,7 +126,7 @@ void ActionKingBobomb6(void) { o->oKingBobombUnk104 = 0; PlaySound2(SOUND_OBJ_KING_BOBOMB); PlaySound2(SOUND_OBJ2_KING_BOBOMB_DAMAGE); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); func_802AA618(0, 0, 100.0f); o->oInteractType = 8; obj_become_tangible(); @@ -154,13 +154,13 @@ void ActionKingBobomb6(void) { void ActionKingBobomb7(void) { set_obj_animation_and_sound_state(2); - if (obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG_1, DIALOG_116)) { + if (obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG, DIALOG_116)) { create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH); obj_hide(); obj_become_intangible(); func_802AA618(0, 0, 200.0f); spawn_triangle_break_particles(20, 138, 3.0f, 4); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); #ifndef VERSION_JP obj_spawn_star_at_y_offset(2000.0f, 4500.0f, -4500.0f, 200.0f); #else @@ -229,7 +229,7 @@ void ActionKingBobomb5() { // bobomb returns home o->oKingBobombUnkF8 = 0; set_obj_animation_and_sound_state(7); PlaySound2(SOUND_OBJ_KING_BOBOMB); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); o->oSubAction++; } break; @@ -246,7 +246,7 @@ void ActionKingBobomb5() { // bobomb returns home o->oSubAction++; break; case 4: - if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, DIALOG_128)) + if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_128)) o->oAction = 2; break; } diff --git a/src/game/behaviors/koopa.inc.c b/src/game/behaviors/koopa.inc.c index 88d4268..30a92f0 100644 --- a/src/game/behaviors/koopa.inc.c +++ b/src/game/behaviors/koopa.inc.c @@ -731,7 +731,7 @@ static void koopa_the_quick_act_after_race(void) { o->oFlags &= ~OBJ_FLAG_ACTIVE_FROM_AFAR; } } else if (o->parentObj->oKoopaRaceEndpointUnk100 > 0) { - s32 dialogResponse = obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, o->parentObj->oKoopaRaceEndpointUnk100); + s32 dialogResponse = obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, o->parentObj->oKoopaRaceEndpointUnk100); if (dialogResponse != 0) { o->parentObj->oKoopaRaceEndpointUnk100 = -1; o->oTimer = 0; diff --git a/src/game/behaviors/mips.inc.c b/src/game/behaviors/mips.inc.c index a3b7f19..06b094b 100644 --- a/src/game/behaviors/mips.inc.c +++ b/src/game/behaviors/mips.inc.c @@ -191,7 +191,7 @@ void bhv_mips_act_idle(void) { // Spawn a star if he was just picked up for the first time. if (o->oMipsStarStatus == MIPS_STAR_STATUS_SHOULD_SPAWN_STAR) { - bhv_spawn_star_objects(o->oBehParams2ndByte + 3); + bhv_spawn_star_no_level_exit(o->oBehParams2ndByte + 3); o->oMipsStarStatus = MIPS_STAR_STATUS_ALREADY_SPAWNED_STAR; } } @@ -244,7 +244,7 @@ void bhv_mips_held(void) { if (set_mario_npc_dialog(1) == 2) { o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; - if (cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, dialogID)) { + if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID)) { o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; o->oMipsStarStatus = MIPS_STAR_STATUS_SHOULD_SPAWN_STAR; diff --git a/src/game/behaviors/purple_switch.inc.c b/src/game/behaviors/purple_switch.inc.c index 47cfe77..0a1c464 100644 --- a/src/game/behaviors/purple_switch.inc.c +++ b/src/game/behaviors/purple_switch.inc.c @@ -31,7 +31,7 @@ void bhv_purple_switch_loop(void) { if (o->oTimer == 3) { PlaySound2(SOUND_GENERAL2_PURPLE_SWITCH); o->oAction = PURPLE_SWITCH_TICKING; - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); } break; /** diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c index c6c6877..85f4a3a 100644 --- a/src/game/behaviors/racing_penguin.inc.c +++ b/src/game/behaviors/racing_penguin.inc.c @@ -106,7 +106,7 @@ static void racing_penguin_act_finish_race(void) { if (o->oForwardVel != 0.0f) { if (o->oTimer > 5 && (o->oMoveFlags & 0x00000200)) { PlaySound2(SOUND_OBJ_POUNDING_LOUD); - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); o->oForwardVel = 0.0f; } } else if (func_802F92B0(2) != 0) { @@ -144,7 +144,7 @@ static void racing_penguin_act_show_final_text(void) { o->oForwardVel = 4.0f; } } else if (o->oRacingPenguinFinalTextbox > 0) { - if ((textResult = obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, o->oRacingPenguinFinalTextbox)) != 0) { + if ((textResult = obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, o->oRacingPenguinFinalTextbox)) != 0) { o->oRacingPenguinFinalTextbox = -1; o->oTimer = 0; } diff --git a/src/game/behaviors/rolling_log.inc.c b/src/game/behaviors/rolling_log.inc.c index f13908b..473e499 100644 --- a/src/game/behaviors/rolling_log.inc.c +++ b/src/game/behaviors/rolling_log.inc.c @@ -97,7 +97,7 @@ void func_802F2820(void) { o->oRollingLogUnkF4 = 0; o->oAction = 2; PlaySound2(SOUND_GENERAL_BIG_POUND); - func_8027F440(3, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_LARGE, o->oPosX, o->oPosY, o->oPosZ); } } diff --git a/src/game/behaviors/snowman.inc.c b/src/game/behaviors/snowman.inc.c index 95b601c..01008b7 100644 --- a/src/game/behaviors/snowman.inc.c +++ b/src/game/behaviors/snowman.inc.c @@ -125,7 +125,7 @@ void bhv_snowmans_bottom_loop(void) { case 0: if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1 && set_mario_npc_dialog(1) == 2) { - sp1E = cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, DIALOG_110); + sp1E = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_110); if (sp1E) { o->oForwardVel = 10.0f; o->oAction = 1; diff --git a/src/game/behaviors/sound_ambient.inc.c b/src/game/behaviors/sound_ambient.inc.c index e8f708d..9c349c1 100644 --- a/src/game/behaviors/sound_ambient.inc.c +++ b/src/game/behaviors/sound_ambient.inc.c @@ -1,7 +1,7 @@ // sound_ambient.inc.c void bhv_ambient_sounds_init(void) { - if (gCurrLevelCamera->currPreset == CAMERA_PRESET_BEHIND_MARIO) + if (gCamera->mode == CAMERA_MODE_BEHIND_MARIO) return; play_sound(SOUND_AIR_CASTLE_OUTDOORS_AMBIENT, gDefaultSoundArgs); diff --git a/src/game/behaviors/sound_birds.inc.c b/src/game/behaviors/sound_birds.inc.c index a62c3aa..96cd8d8 100644 --- a/src/game/behaviors/sound_birds.inc.c +++ b/src/game/behaviors/sound_birds.inc.c @@ -1,7 +1,7 @@ // sound_birds.inc.c void bhv_birds_sound_loop(void) { - if (gCurrLevelCamera->currPreset == CAMERA_PRESET_BEHIND_MARIO) + if (gCamera->mode == CAMERA_MODE_BEHIND_MARIO) return; switch (o->oBehParams2ndByte) { diff --git a/src/game/behaviors/sound_sand.inc.c b/src/game/behaviors/sound_sand.inc.c index 11d2d50..33b52c2 100644 --- a/src/game/behaviors/sound_sand.inc.c +++ b/src/game/behaviors/sound_sand.inc.c @@ -1,7 +1,7 @@ // sound_sand.inc.c void bhv_sand_sound_loop(void) { - if (gCurrLevelCamera->currPreset == CAMERA_PRESET_BEHIND_MARIO) + if (gCamera->mode == CAMERA_MODE_BEHIND_MARIO) return; PlaySound(SOUND_ENV_MOVINGSAND); diff --git a/src/game/behaviors/sparkle_spawn_star.inc.c b/src/game/behaviors/sparkle_spawn_star.inc.c index d0126ae..bbde5b1 100644 --- a/src/game/behaviors/sparkle_spawn_star.inc.c +++ b/src/game/behaviors/sparkle_spawn_star.inc.c @@ -12,7 +12,7 @@ struct ObjectHitbox sSparkleSpawnStarHitbox = { /* hurtboxHeight: */ 0, }; -void bhv_unused_080c_init(void) { +void bhv_spawned_star_init(void) { s32 sp24; if (!(o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT)) o->oBehParams = o->parentObj->oBehParams; @@ -53,7 +53,7 @@ void func_802AA918(void) { o->oAngleVelYaw -= 0x40; } -void bhv_unused_080c_loop(void) { +void bhv_spawned_star_loop(void) { if (o->oAction == 0) { if (o->oTimer == 0) { cutscene_object(CUTSCENE_STAR_SPAWN, o); @@ -89,14 +89,14 @@ void bhv_unused_080c_loop(void) { if (o->oVelY < -4.0f) o->oVelY = -4.0f; if (o->oVelY < 0 && o->oPosY < o->oHomeY) { - gCutsceneActive = 1; + gObjCutsceneDone = TRUE; o->oVelY = 0; o->oGravity = 0; o->oAction++; } spawn_object(o, MODEL_NONE, bhvSparkleSpawn); } else if (o->oAction == 2) { - if (gCurrLevelCamera->cutscene == 0 && gCutsceneNumber == 0) { + if (gCamera->cutscene == 0 && gRecentCutscene == 0) { clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); o->activeFlags &= ~0x20; o->oAction++; @@ -110,8 +110,8 @@ void bhv_unused_080c_loop(void) { o->oInteractStatus = 0; } -void bhv_spawn_star_objects(u32 sp20) { - struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvUnused080C); +void bhv_spawn_star_no_level_exit(u32 sp20) { + struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit); sp1C->oBehParams = sp20 << 24; sp1C->oInteractionSubtype = INT_SUBTYPE_NO_EXIT; set_object_angle(sp1C, 0, 0, 0); diff --git a/src/game/behaviors/spawn_star.inc.c b/src/game/behaviors/spawn_star.inc.c index 276ffae..3054f3f 100644 --- a/src/game/behaviors/spawn_star.inc.c +++ b/src/game/behaviors/spawn_star.inc.c @@ -42,10 +42,10 @@ void bhv_star_spawn_init(void) { o->oVelY = (o->oHomeY - o->oPosY) / 30.0f; o->oForwardVel = o->oStarSpawnDisFromHome / 30.0f; o->oStarSpawnUnkFC = o->oPosY; - if (o->oBehParams2ndByte == 0 || gCurrCourseNum == 5) + if (o->oBehParams2ndByte == 0 || gCurrCourseNum == COURSE_BBH) cutscene_object(CUTSCENE_STAR_SPAWN, o); else - cutscene_object(CUTSCENE_SPECIAL_STAR_SPAWN, o); + cutscene_object(CUTSCENE_RED_COIN_STAR_SPAWN, o); set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); o->activeFlags |= 0x20; @@ -96,7 +96,7 @@ void bhv_star_spawn_loop(void) { case 3: o->oFaceAngleYaw += 0x800; if (o->oTimer == 20) { - gCutsceneActive = 1; + gObjCutsceneDone = TRUE; clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_MARIO_AND_DOORS); o->activeFlags &= ~0x20; } diff --git a/src/game/behaviors/spindel.inc.c b/src/game/behaviors/spindel.inc.c index 641a49e..6fc6567 100644 --- a/src/game/behaviors/spindel.inc.c +++ b/src/game/behaviors/spindel.inc.c @@ -74,6 +74,6 @@ void bhv_spindel_loop(void) { o->oPosY = o->oHomeY + sp1C; if (o->oTimer + 1 == sp18 * 8) - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); } } diff --git a/src/game/behaviors/thwomp.inc.c b/src/game/behaviors/thwomp.inc.c index 99a28d4..27b5884 100644 --- a/src/game/behaviors/thwomp.inc.c +++ b/src/game/behaviors/thwomp.inc.c @@ -20,7 +20,7 @@ void ActionGrindelThwomp2(void) { void ActionGrindelThwomp3(void) { if (o->oTimer == 0) if (o->oDistanceToMario < 1500.0f) { - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); PlaySound2(SOUND_OBJ_THWOMP); } if (o->oTimer > 9) diff --git a/src/game/behaviors/tox_box.inc.c b/src/game/behaviors/tox_box.inc.c index 98f4d5e..da28ded 100644 --- a/src/game/behaviors/tox_box.inc.c +++ b/src/game/behaviors/tox_box.inc.c @@ -10,7 +10,7 @@ s8 *D_8032F96C[] = { D_8032F8F0, D_8032F924, D_8032F948 }; void func_802BCF78(void) { if (o->oDistanceToMario < 3000.0f) - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); } void func_802BCFC4(f32 a0, f32 a1, s16 a2, s16 a3) // 0x18 0x1c 0x22 0x26 diff --git a/src/game/behaviors/treasure_chest.inc.c b/src/game/behaviors/treasure_chest.inc.c index 571ad6f..cc54cdc 100644 --- a/src/game/behaviors/treasure_chest.inc.c +++ b/src/game/behaviors/treasure_chest.inc.c @@ -131,7 +131,7 @@ void bhv_treasure_chest_ship_loop(void) { if (gEnvironmentRegions != NULL) { gEnvironmentRegions[6] += -5; play_sound(SOUND_ENV_WATER_DRAIN, gDefaultSoundArgs); - set_camera_shake_2(SHAKE_2_JRB_SHIP_DRAIN); + set_environmental_camera_shake(SHAKE_ENV_JRB_SHIP_DRAIN); if (gEnvironmentRegions[6] < -335) { gEnvironmentRegions[6] = -335; o->activeFlags = 0; diff --git a/src/game/behaviors/tuxie.inc.c b/src/game/behaviors/tuxie.inc.c index 2a28b1b..89f2d0f 100644 --- a/src/game/behaviors/tuxie.inc.c +++ b/src/game/behaviors/tuxie.inc.c @@ -65,7 +65,7 @@ void ActionTuxiesMother1(void) { dialogID = DIALOG_058; else dialogID = DIALOG_059; - if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, dialogID)) { + if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, dialogID)) { if (dialogID == DIALOG_058) o->oSubAction = 1; else @@ -128,7 +128,7 @@ void ActionTuxiesMother0(void) { o->oSubAction++; break; case 1: - if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, DIALOG_057)) + if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_057)) o->oSubAction++; break; case 2: diff --git a/src/game/behaviors/ukiki.inc.c b/src/game/behaviors/ukiki.inc.c index 589241f..b9db0c7 100644 --- a/src/game/behaviors/ukiki.inc.c +++ b/src/game/behaviors/ukiki.inc.c @@ -384,7 +384,7 @@ void ukiki_act_go_to_cage(void) { case UKIKI_SUB_ACT_CAGE_TALK_TO_MARIO: set_obj_animation_and_sound_state(UKIKI_ANIM_HANDSTAND); - if (obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG_1, DIALOG_080)) { + if (obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG, DIALOG_080)) { o->oSubAction++; } break; diff --git a/src/game/behaviors/water_bomb.inc.c b/src/game/behaviors/water_bomb.inc.c index 0f33293..be79408 100644 --- a/src/game/behaviors/water_bomb.inc.c +++ b/src/game/behaviors/water_bomb.inc.c @@ -127,7 +127,7 @@ static void water_bomb_act_drop(void) { // Explode if touched or if hit water if ((o->oInteractStatus & INT_STATUS_INTERACTED) || (o->oMoveFlags & OBJ_MOVE_ENTERED_WATER)) { create_sound_spawner(SOUND_OBJ_DIVING_IN_WATER); - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); o->oAction = WATER_BOMB_ACT_EXPLODE; } else if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { // On impact with the ground, begin getting squished @@ -140,7 +140,7 @@ static void water_bomb_act_drop(void) { create_sound_spawner(SOUND_OBJ_DIVING_IN_WATER); } - func_8027F440(1, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); // Move toward mario o->oMoveAngleYaw = o->oAngleToMario; diff --git a/src/game/behaviors/water_bomb_cannon.inc.c b/src/game/behaviors/water_bomb_cannon.inc.c index ea8be82..20395eb 100644 --- a/src/game/behaviors/water_bomb_cannon.inc.c +++ b/src/game/behaviors/water_bomb_cannon.inc.c @@ -28,7 +28,7 @@ void bhv_bubble_cannon_barrel_loop(void) { val04->header.gfx.scale[1] = 1.7f; } - func_8027F440(2, o->oPosX, o->oPosY, o->oPosZ); + set_camera_shake_from_point(SHAKE_POS_MEDIUM, o->oPosX, o->oPosY, o->oPosZ); } } else { o->oForwardVel = 0.0f; diff --git a/src/game/behaviors/whomp.inc.c b/src/game/behaviors/whomp.inc.c index e64855c..1c0a19e 100644 --- a/src/game/behaviors/whomp.inc.c +++ b/src/game/behaviors/whomp.inc.c @@ -28,7 +28,7 @@ void ActionWhomp0(void) { obj_set_pos_to_home(); o->oHealth = 3; } - } else if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG_1, DIALOG_114)) + } else if (obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_114)) o->oAction = 2; } else if (o->oDistanceToMario < 500.0f) o->oAction = 1; @@ -124,7 +124,7 @@ void ActionWhomp4(void) { void ActionWhomp5(void) { if (o->oSubAction == 0 && o->oMoveFlags & 1) { PlaySound2(SOUND_OBJ_WHOMP_LOWPRIO); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); o->oVelY = 0.0f; o->oSubAction++; } @@ -146,7 +146,7 @@ void func_802C6954(void) { func_802B8F7C(&o->oPosX, &gMarioObject->oPosX); func_802AA618(0, 0, 100.0f); spawn_triangle_break_particles(20, 138, 3.0f, 4); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); func_802B8F7C(&o->oPosX, pos); } o->oSubAction++; @@ -209,13 +209,13 @@ void ActionWhomp6(void) { void ActionWhomp8(void) { if (o->oBehParams2ndByte != 0) { - if (obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG_1, DIALOG_115)) { + if (obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG, DIALOG_115)) { set_object_angle(o, 0, 0, 0); obj_hide(); obj_become_intangible(); func_802AA618(0, 0, 200.0f); spawn_triangle_break_particles(20, 138, 3.0f, 4); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); o->oPosY += 100.0f; create_star(180.0f, 3880.0f, 340.0f); PlaySound2(SOUND_OBJ_KING_WHOMP_DEATH); @@ -224,7 +224,7 @@ void ActionWhomp8(void) { } else { func_802AA618(0, 0, 100.0f); spawn_triangle_break_particles(20, 138, 3.0f, 4); - ShakeScreen(1); + ShakeScreen(SHAKE_POS_SMALL); create_sound_spawner(SOUND_OBJ_THWOMP); mark_object_for_deletion(o); } diff --git a/src/game/behaviors/wiggler.inc.c b/src/game/behaviors/wiggler.inc.c index fee539e..b0eba77 100644 --- a/src/game/behaviors/wiggler.inc.c +++ b/src/game/behaviors/wiggler.inc.c @@ -224,7 +224,7 @@ static void wiggler_act_walk(void) { // If Mario is positioned below the wiggler, assume he entered through the // lower cave entrance, so don't display text. - if (gMarioObject->oPosY < o->oPosY || obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG_1, DIALOG_150) != 0) { + if (gMarioObject->oPosY < o->oPosY || obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_150) != 0) { o->oWigglerTextStatus = WIGGLER_TEXT_STATUS_COMPLETED_DIALOG; } } else { @@ -301,7 +301,7 @@ static void wiggler_act_jumped_on(void) { // defeated) or go back to walking if (o->header.gfx.scale[1] >= 4.0f) { if (o->oTimer > 30) { - if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG_1, attackText[o->oHealth - 2]) != 0) { + if (obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, attackText[o->oHealth - 2]) != 0) { // Because we don't want the wiggler to disappear after being // defeated, we leave its health at 1 if (--o->oHealth == 1) { diff --git a/src/game/behaviors/yoshi.inc.c b/src/game/behaviors/yoshi.inc.c index f31f037..1c129c9 100644 --- a/src/game/behaviors/yoshi.inc.c +++ b/src/game/behaviors/yoshi.inc.c @@ -63,7 +63,8 @@ void yoshi_idle_loop(void) { o->oAction = YOSHI_ACT_TALK; // Credits; Yoshi appears at this position overlooking the castle near the end of the credits - if (gPlayerStatusForCamera->unk1C[1] == 11 || gPlayerStatusForCamera->unk1C[1] == 12) { + if (gPlayerCameraState->cameraEvent == CAM_EVENT_START_ENDING || + gPlayerCameraState->cameraEvent == CAM_EVENT_START_END_WAVING) { o->oAction = YOSHI_ACT_CREDITS; o->oPosX = -1798.0f; o->oPosY = 3174.0f; @@ -76,7 +77,7 @@ void yoshi_talk_loop(void) { SetObjAnimation(0); if (set_mario_npc_dialog(1) == 2) { o->activeFlags |= 0x20; - if (cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, DIALOG_161)) { + if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_161)) { o->activeFlags &= ~0x20; o->oInteractStatus = 0; o->oHomeX = sYoshiHomeLocations[2]; @@ -122,7 +123,7 @@ void yoshi_finish_jumping_and_despawn_loop(void) { o->oVelY -= 2.0; if (o->oPosY < 2100.0f) { set_mario_npc_dialog(0); - gCutsceneActive = 1; + gObjCutsceneDone = TRUE; sYoshiDead = 1; o->activeFlags = 0; } diff --git a/src/game/camera.c b/src/game/camera.c index 7ad207a..af8dc34 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -33,66 +33,261 @@ #define CBUTTON_MASK (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS) +/** + * @file camera.c + * Implements the camera system, including C-button input, camera modes, camera triggers, and cutscenes. + * + * When working with the camera, you should be familiar with sm64's coordinate system. + * Relative to the camera, the coordinate system follows the right hand rule: + * +X points right. + * +Y points up. + * +Z points out of the screen. + * + * You should also be familiar with Euler angles: 'pitch', 'yaw', and 'roll'. + * pitch: rotation about the X-axis, measured from +Y. + * Unlike yaw and roll, pitch is bounded in +-0x4000 (90 degrees). + * Pitch is 0 when the camera points parallel to the xz-plane (+Y points straight up). + * + * yaw: rotation about the Y-axis, measured from (absolute) +Z. + * Positive yaw rotates clockwise, towards +X. + * + * roll: rotation about the Z-axis, measured from the camera's right direction. + * Unfortunately, it's weird: For some reason, roll is flipped. Positive roll makes the camera + * rotate counterclockwise, which means the WORLD rotates clockwise. Luckily roll is rarely + * used. + * + * Remember the right hand rule: make a thumbs-up with your right hand, stick your thumb in the + * +direction (except for roll), and the angle follows the rotation of your curled fingers. + * + * Illustrations: + * Following the right hand rule, each hidden axis's positive direction points out of the screen. + * + * YZ-Plane (pitch) XZ-Plane (yaw) XY-Plane (roll -- Note flipped) + * +Y -Z +Y + * ^ ^ (into the ^ + * --|-- | screen) |<- + * +pitch / | \ -pitch | | \ -roll + * v | v | | | + * +Z <------O------> -Z -X <------O------> +X -X <------O------> +X + * | ^ | ^ | | + * | \ | / | / +roll + * | -yaw --|-- +yaw |<- + * v v v + * -Y +Z -Y + * + */ + // BSS -struct CameraPlayerStatus gPlayerStatusForCamera[2]; -Vec3f sCameraPosition; -Vec3f sCameraFocus; -Vec3f D_8033B218; -s16 sCreditsCameraPitch; -s16 sCreditsCameraYaw; -u8 gFramesPaused; -struct Struct8033B230 D_8033B230; -struct TransitionCamera sCameraTransition; -struct PlayerGeometry sGeometryForMario; -s16 unused_8033B2AC; -s16 sCameraYawVelocity; + +/** + * Global array of PlayerCameraState. + * L is real. + */ +struct PlayerCameraState gPlayerCameraState[2]; +/** + * Stores lakitu's position from the last frame, used for transitioning in next_lakitu_state() + */ +Vec3f sOldPosition; +/** + * Stores lakitu's focus from the last frame, used for transitioning in next_lakitu_state() + */ +Vec3f sOldFocus; +/** + * Direction controlled by player 2, moves the focus during the credits. + */ +Vec3f sPlayer2FocusOffset; +/** + * The pitch used for the credits easter egg. + */ +s16 sCreditsPlayer2Pitch; +/** + * The yaw used for the credits easter egg. + */ +s16 sCreditsPlayer2Yaw; +/** + * Used to decide when to zoom out in the pause menu. + */ +u8 sFramesPaused; + +struct CameraFOVStatus sFOVState; +struct TransitionInfo sModeTransition; +struct PlayerGeometry sMarioGeometry; +s16 unusedFreeRoamWallYaw; +s16 sAvoidYawVel; s16 sCameraYawAfterDoorCutscene; -s16 unused_spline_pitch; -s16 unused_spline_yaw; -struct Struct8033B2B8 sSplineParameters[4]; -s16 sSplineParameterMax; -f32 sPositionAlongSpline; -f32 sSplinePositionLimit; -s16 sCameraCutscenePitchOffset; -s16 sCameraCutsceneYawOffset; -s16 sCameraCutsceneRollOffset; -u32 unused_8033B30C; -u32 unused_8033B310; -s16 gCameraModeFlags; -s16 unused_8033B316; -s16 sCameraSideCFlags; -s16 unused_8033B31A; -s16 gCameraFlags1; -u16 gCButtonsPressed; -s16 D_8033B320; -struct CameraState gCameraStatus; -s16 unused_8033B3E8; -s16 sYawFocToMario; -s16 D_8033B3EC; -s16 D_8033B3EE; -s16 D_8033B3F0; -f32 D_8033B3F4; + +s16 unusedSplinePitch; +s16 unusedSplineYaw; + +// Shaky Hand-held Camera effect variables +struct HandheldShakePoint sHandheldShakeSpline[4]; +s16 sHandheldShakeMag; +f32 sHandheldShakeTimer; +f32 sHandheldShakeInc; +s16 sHandheldShakePitch; +s16 sHandheldShakeYaw; +s16 sHandheldShakeRoll; + +u32 unused8033B30C; +u32 unused8033B310; +/** + * Determines which R-Trigger mode is selected in the pause menu. + */ +s16 sSelectionFlags; +s16 unused8033B316; +/** + * Flags that determine whether the player has already rotated left or right. Used in radial mode to + * determine whether to rotate all the way, or just to 60 degrees. + */ +s16 s2ndRotateFlags; +s16 unused8033B31A; +/** + * Flags that control buzzes and sounds that play, mostly for C-button input. + */ +s16 sCameraSoundFlags; +/** + * Stores what C-Buttons are pressed this frame. + */ +u16 sCButtonsPressed; +/** + * A copy of gDialogID, the dialog displayed during the cutscene. + */ +s16 sCutsceneDialogID; +/** + * Lakitu's position and focus. + * @see LakituState + */ +struct LakituState gLakituState; +s16 unused8033B3E8; +/** + * The angle of the direction vector from the area's center to mario's position. + */ +s16 sAreaYaw; + +/** + * How much sAreaYaw changed when mario moved. + */ +s16 sAreaYawChange; + +/** + * Lakitu's distance from mario in C-Down mode + */ +s16 sLakituDist; + +/** + * How much lakitu looks down in C-Down mode + */ +s16 sLakituPitch; + +/** + * The amount of distance left to zoom out + */ +f32 sZoomAmount; + s16 sCSideButtonYaw; -s16 D_8033B3FA; -f32 D_8033B3FC; -s16 sFirstPersonCameraPitch; -s16 sFirstPersonCameraYaw; -s16 D_8033B404; -s16 sPlatformLevelPresetBaseYaw; -s16 gPlatformLevelYawOffset; -f32 D_8033B40C; -f32 D_8033B410; -struct Struct8033B418 D_8033B418; -Vec3f sFixedPresetBasePositionOffset; -u32 D_8033B46C; -struct ParallelTrackingTable *D_8033B470; -struct Struct8033B4B8 D_8033B478; -struct Struct8033B4B8 D_8033B498; -struct Struct8033B4B8 D_8033B4B8; + +/** + * Sound timer used to space out sounds in behind mario mode + */ +s16 sBehindMarioSoundTimer; + +/** + * Virtually unused aside being set to 0 and compared with gCameraZoomDist (which is never < 0) + */ +f32 sZeroZoomDist; + +/** + * The camera's pitch in C-Up mode. Mainly controls mario's head rotation. + */ +s16 sCUpCameraPitch; +/** + * The current mode's yaw, which gets added to the camera's yaw. + */ +s16 sModeOffsetYaw; + +/** + * Stores mario's yaw around the stairs, relative to the camera's position. + * + * Used in update_spiral_stairs_camera() + */ +s16 sSpiralStairsYawOffset; + +/** + * The constant offset to 8-direction mode's yaw. + */ +s16 s8DirModeBaseYaw; +/** + * Player-controlled yaw offset in 8-direction mode, a multiple of 45 degrees. + */ +s16 s8DirModeYawOffset; + +/** + * The distance that the camera will look ahead of mario in the direction mario is facing. + */ +f32 sPanDistance; + +/** + * When mario gets in the cannon, it is pointing straight up and rotates down. + * This is used to make the camera start up and rotate down, like the cannon. + */ +f32 sCannonYOffset; +struct ModeTransitionInfo sModeInfo; + +/** + * Offset added to sFixedModeBasePosition when mario is inside, near the castle lobby entrance + */ +Vec3f sCastleEntranceOffset; + +/** + * The index into the current parallel tracking path + */ +u32 sParTrackIndex; + +/** + * The current list of ParallelTrackingPoints used in update_parallel_tracking_camera() + */ +struct ParallelTrackingPoint *sParTrackPath; + +/** + * On the first frame after the camera changes to a different parallel tracking path, this stores the + * displacement between the camera's calculated new position and its previous positions + * + * This transition offset is then used to smoothly interpolate the camera's position between the two + * paths + */ +struct CameraStoredInfo sParTrackTransOff; + +/** + * The information stored when C-Up is active, used to update lakitu's rotation when exiting C-Up + */ +struct CameraStoredInfo sCameraStoreCUp; + +/** + * The information stored during cutscenes + */ +struct CameraStoredInfo sCameraStoreCutscene; + +/** + * Flags that determine what movements the camera should start / do this frame. + */ s16 gCameraMovementFlags; -s16 gCameraFlags2; -struct CutsceneSplinePoint D_8033B4E0[32]; -struct CutsceneSplinePoint D_8033B5E0[32]; + +/** + * Flags that change how modes operate and how lakitu moves. + * The most commonly used flag is CAM_FLAG_SMOOTH_MOVEMENT, which makes lakitu fly to the next position, + * instead of warping. + */ +s16 sStatusFlags; + +/** + * The current spline that controls the camera's position during the credits. + */ +struct CutsceneSplinePoint sCurCreditsSplinePos[32]; + +/** + * The current spline that controls the camera's focus during the credits. + */ +struct CutsceneSplinePoint sCurCreditsSplineFocus[32]; /** * The current segment of the CutsceneSplinePoint[] being used. @@ -104,100 +299,138 @@ s16 sCutsceneSplineSegment; * When it becomes >= 1, 1.0 is subtracted from it and sCutsceneSplineSegment is increased. */ f32 sCutsceneSplineSegmentProgress; -s16 D_8033B6E8; -s16 D_8033B6EA; +s16 unused8033B6E8; +/** + * The currently playing shot in the cutscene. + */ +s16 sCutsceneShot; +/** + * The current frame of the cutscene shot. + */ s16 gCutsceneTimer; -struct Struct8033B6F0 D_8033B6F0[10]; -s32 gCutsceneActive; -u32 sCutscenePhase; -struct LevelCamera *gCurrLevelCamera; + +/** + * These structs are used by the cutscenes. Most of the fields are unused, and some (all?) of the used + * ones have multiple uses. + * Check the cutscene_start functions for documentation on the cvars used by a specific cutscene. + */ +struct CutsceneVariable sCutsceneVars[10]; +/** + * Controls when an object-based cutscene should end. It's only used in the star spawn cutscenes, but + * yoshi also toggles this. + */ +s32 gObjCutsceneDone; +/** + * Controls which object to spawn in the intro and ending cutscenes. + */ +u32 gCutsceneObjSpawn; +struct Camera *gCamera; // first iteration of data -u32 unused_8032CFC0 = 0; // unused +u32 unused8032CFC0 = 0; struct Object *gCutsceneFocus = NULL; -u32 unused_8032CFC8 = 0; -u32 unused_8032CFCC = 0; +// other camera focuses? +u32 unused8032CFC8 = 0; +u32 unused8032CFCC = 0; struct Object *gSecondCameraFocus = NULL; -s16 D_8032CFD4 = 1024; + +/** + * How fast the camera's yaw should approach the next yaw. + */ +s16 sYawSpeed = 0x400; s32 gCurrLevelArea = 0; u32 gPrevLevel = 0; -f32 D_8032CFE0 = 1000.0f; // unused -f32 D_8032CFE4 = 800.0f; // unused -u32 D_8032CFE8 = 0; // unused + +f32 unused8032CFE0 = 1000.0f; +f32 unused8032CFE4 = 800.0f; +u32 unused8032CFE8 = 0; f32 gCameraZoomDist = 800.0f; -u8 sTempCutsceneNumber = 0; -u8 gCutsceneNumber = 0; -u8 sCutsceneTransitionTimer = 0; -u8 D_8032CFFC = 0; -struct CameraPlayerStatus *sMarioStatusForCamera = &gPlayerStatusForCamera[0]; -struct CameraPlayerStatus *sLuigiStatusForCamera = &gPlayerStatusForCamera[1]; -u32 D_8032D008 = 0; // unused -Vec3f sFixedPresetBasePosition = { 646.0f, 143.0f, -1513.0f }; -Vec3f D_8032D00C_2 = { 646.0f, 143.0f, -1513.0f }; // unused -Vec3f D_8032D00C_3 = { 646.0f, 143.0f, -1513.0f }; // unused -Vec3f D_8032D00C_4 = { 646.0f, 143.0f, -1513.0f }; // unused -Vec3f D_8032D00C_5 = { 646.0f, 143.0f, -1513.0f }; // unused -s32 return_open_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_reverse_tower_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_behind_mario_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_mario_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 unused_return_mode_5_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_first_person_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_mario_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 nop_return_water_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_slide_or_0f_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_cannon_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_boss_fight_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_parallel_tracking_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_fixed_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_platform_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_slide_or_0f_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_mario_yaw(struct LevelCamera *, Vec3f, Vec3f); -s32 return_spiral_stairs_camera_yaw(struct LevelCamera *, Vec3f, Vec3f); +/** + * A cutscene that plays when the player interacts with an object + */ +u8 sObjectCutscene = 0; -s32 (*TableCameraTransitions[])(struct LevelCamera *, Vec3f, - Vec3f) = { NULL, - return_open_camera_yaw, - return_reverse_tower_camera_yaw, - return_behind_mario_camera_yaw, - return_mario_yaw, - unused_return_mode_5_camera_yaw, - return_first_person_camera_yaw, - return_mario_yaw, - nop_return_water_camera_yaw, - return_slide_or_0f_camera_yaw, - return_cannon_camera_yaw, - return_boss_fight_camera_yaw, - return_parallel_tracking_camera_yaw, - return_fixed_camera_yaw, - return_platform_camera_yaw, - return_slide_or_0f_camera_yaw, - return_mario_yaw, - return_spiral_stairs_camera_yaw }; +/** + * The ID of the cutscene that ended. It's set to 0 if no cutscene ended less than 8 frames ago. + * + * It is only used to prevent the same cutscene from playing twice before 8 frames have passed. + */ +u8 gRecentCutscene = 0; -extern f32 unused_8033B3CC; -extern f32 unused_8033B3D4; -extern s16 unused_8033B3A2; -extern f32 unused_80336074; -extern s16 unused_8033B3A4; -extern s16 unused_8033B3A6; +/** + * A timer that increments for 8 frames when a cutscene ends. + * When it reaches 8, it sets gRecentCutscene to 0. + */ +u8 sFramesSinceCutsceneEnded = 0; +/** + * Mario's response to a dialog. + * 0 = No response yet + * 1 = Yes + * 2 = No + * 3 = Dialog doesn't have a response + */ +u8 sCutsceneDialogResponse = 0; +struct PlayerCameraState *sMarioCamState = &gPlayerCameraState[0]; +struct PlayerCameraState *sLuigiCamState = &gPlayerCameraState[1]; +u32 unused8032D008 = 0; +Vec3f sFixedModeBasePosition = { 646.0f, 143.0f, -1513.0f }; +Vec3f sUnusedModeBasePosition_2 = { 646.0f, 143.0f, -1513.0f }; +Vec3f sUnusedModeBasePosition_3 = { 646.0f, 143.0f, -1513.0f }; +Vec3f sUnusedModeBasePosition_4 = { 646.0f, 143.0f, -1513.0f }; +Vec3f sUnusedModeBasePosition_5 = { 646.0f, 143.0f, -1513.0f }; -extern u32 gPrevLevel; +s32 update_radial_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_outward_radial_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_behind_mario_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_mario_camera(struct Camera *c, Vec3f, Vec3f); +s32 unused_update_mode_5_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_c_up(struct Camera *c, Vec3f, Vec3f); +s32 nop_update_water_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_slide_or_0f_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_in_cannon(struct Camera *c, Vec3f, Vec3f); +s32 update_boss_fight_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_parallel_tracking_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_fixed_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_8_directions_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_slide_or_0f_camera(struct Camera *c, Vec3f, Vec3f); +s32 update_spiral_stairs_camera(struct Camera *c, Vec3f, Vec3f); -extern f32 unused_8033B3D8; -extern f32 unused_8033B3D0; +typedef s32 (*CameraTransition)(struct Camera *c, Vec3f, Vec3f); +CameraTransition sModeTransitions[] = { + NULL, + update_radial_camera, + update_outward_radial_camera, + update_behind_mario_camera, + update_mario_camera, + unused_update_mode_5_camera, + update_c_up, + update_mario_camera, + nop_update_water_camera, + update_slide_or_0f_camera, + update_in_cannon, + update_boss_fight_camera, + update_parallel_tracking_camera, + update_fixed_camera, + update_8_directions_camera, + update_slide_or_0f_camera, + update_mario_camera, + update_spiral_stairs_camera +}; -extern f32 unused_803365D0; -extern f32 unused_803365D4; -extern f32 unused_803365D8; -extern f32 unused_803365DC; +// Move these two tables to another include file? +extern u8 sDanceCutsceneIndexTable[][4]; +extern u8 sZoomOutAreaMasks[]; -void set_camera_shake(s16 shake) { +/** + * Starts a camera shake triggered by an interaction + */ +void set_camera_shake_from_hit(s16 shake) { switch (shake) { + // Makes the camera stop for a bit case SHAKE_ATTACK: - gCameraStatus.unkA4 = 0; - gCameraStatus.unkAC = 0; + gLakituState.focHSpeed = 0; + gLakituState.posHSpeed = 0; break; case SHAKE_FALL_DAMAGE: @@ -210,53 +443,53 @@ void set_camera_shake(s16 shake) { break; case SHAKE_SMALL_DAMAGE: - if (sMarioStatusForCamera->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { + if (sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { set_camera_yaw_shake(0x200, 0x10, 0x1000); set_camera_roll_shake(0x400, 0x20, 0x1000); - func_80299C98(0x100, 0x30, -0x8000); + set_fov_shake(0x100, 0x30, 0x8000); } else { set_camera_yaw_shake(0x80, 0x8, 0x4000); set_camera_roll_shake(0x80, 0x8, 0x4000); - func_80299C98(0x100, 0x30, -0x8000); + set_fov_shake(0x100, 0x30, 0x8000); } - gCameraStatus.unkA4 = 0; - gCameraStatus.unkAC = 0; + gLakituState.focHSpeed = 0; + gLakituState.posHSpeed = 0; break; case SHAKE_MED_DAMAGE: - if (sMarioStatusForCamera->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { + if (sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { set_camera_yaw_shake(0x400, 0x20, 0x1000); set_camera_roll_shake(0x600, 0x30, 0x1000); - func_80299C98(0x180, 0x40, -0x8000); + set_fov_shake(0x180, 0x40, 0x8000); } else { set_camera_yaw_shake(0x100, 0x10, 0x4000); set_camera_roll_shake(0x100, 0x10, 0x4000); - func_80299C98(0x180, 0x40, -0x8000); + set_fov_shake(0x180, 0x40, 0x8000); } - gCameraStatus.unkA4 = 0; - gCameraStatus.unkAC = 0; + gLakituState.focHSpeed = 0; + gLakituState.posHSpeed = 0; break; case SHAKE_LARGE_DAMAGE: - if (sMarioStatusForCamera->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { + if (sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) { set_camera_yaw_shake(0x600, 0x30, 0x1000); set_camera_roll_shake(0x800, 0x40, 0x1000); - func_80299C98(0x200, 0x50, -0x8000); + set_fov_shake(0x200, 0x50, 0x8000); } else { set_camera_yaw_shake(0x180, 0x20, 0x4000); set_camera_roll_shake(0x200, 0x20, 0x4000); - func_80299C98(0x200, 0x50, -0x8000); + set_fov_shake(0x200, 0x50, 0x8000); } - gCameraStatus.unkA4 = 0; - gCameraStatus.unkAC = 0; + gLakituState.focHSpeed = 0; + gLakituState.posHSpeed = 0; break; case SHAKE_HIT_FROM_BELOW: - gCameraStatus.unkA4 = 0.07; - gCameraStatus.unkAC = 0.07; + gLakituState.focHSpeed = 0.07; + gLakituState.posHSpeed = 0.07; break; case SHAKE_SHOCK: @@ -266,175 +499,199 @@ void set_camera_shake(s16 shake) { } } -void set_camera_shake_2(s16 shake) { +/** + * Start a shake from the environment + */ +void set_environmental_camera_shake(s16 shake) { switch (shake) { - case SHAKE_2_UNKNOWN_1: + case SHAKE_ENV_EXPLOSION: set_camera_pitch_shake(0x60, 0x8, 0x4000); break; - case SHAKE_2_UNKNOWN_2: + case SHAKE_ENV_BOWSER_THROW_BOUNCE: set_camera_pitch_shake(0xC0, 0x8, 0x4000); break; - case SHAKE_2_UNKNOWN_3: + case SHAKE_ENV_BOWSER_JUMP: set_camera_pitch_shake(0x100, 0x8, 0x3000); break; - case SHAKE_2_UNKNOWN_6: + case SHAKE_ENV_UNUSED_6: set_camera_roll_shake(0x80, 0x10, 0x3000); break; - case SHAKE_2_UNKNOWN_7: + case SHAKE_ENV_UNUSED_7: set_camera_pitch_shake(0x20, 0x8, 0x8000); break; - case SHAKE_2_UNKNOWN_8: + case SHAKE_ENV_PYRAMID_EXPLODE: set_camera_pitch_shake(0x40, 0x8, 0x8000); break; - case SHAKE_2_JRB_SHIP_DRAIN: + case SHAKE_ENV_JRB_SHIP_DRAIN: set_camera_pitch_shake(0x20, 0x8, 0x8000); set_camera_roll_shake(0x400, 0x10, 0x100); break; - case SHAKE_2_FALLING_BITS_PLAT: - set_camera_pitch_shake(64, 0x2, 0x8000); + case SHAKE_ENV_FALLING_BITS_PLAT: + set_camera_pitch_shake(0x40, 0x2, 0x8000); break; - case SHAKE_2_UNKNOWN_5: + case SHAKE_ENV_UNUSED_5: set_camera_yaw_shake(-0x200, 0x80, 0x200); break; } } -void func_8027F440(s16 a, f32 b, f32 c, f32 d) { - switch (a) { - case 4: - func_8028AA80(0x28, 0x8, 0x4000, 2000.f, b, c, d); +/** + * Starts a camera shake, but scales the amplitude by the point's distance from the camera + */ +void set_camera_shake_from_point(s16 shake, f32 posX, f32 posY, f32 posZ) { + switch (shake) { + case SHAKE_POS_BOWLING_BALL: + set_pitch_shake_from_point(0x28, 0x8, 0x4000, 2000.f, posX, posY, posZ); break; - case 1: - func_8028AA80(0x80, 0x8, 0x4000, 4000.f, b, c, d); - func_8029A514(1, b, c, d); + case SHAKE_POS_SMALL: + set_pitch_shake_from_point(0x80, 0x8, 0x4000, 4000.f, posX, posY, posZ); + set_fov_shake_from_point_preset(SHAKE_FOV_SMALL, posX, posY, posZ); break; - case 2: - func_8028AA80(0xC0, 0x8, 0x4000, 6000.f, b, c, d); - func_8029A514(3, b, c, d); + case SHAKE_POS_MEDIUM: + set_pitch_shake_from_point(0xC0, 0x8, 0x4000, 6000.f, posX, posY, posZ); + set_fov_shake_from_point_preset(SHAKE_FOV_MEDIUM, posX, posY, posZ); break; - case 3: - func_8028AA80(0x100, 0x8, 0x3000, 8000.f, b, c, d); - func_8029A514(4, b, c, d); + case SHAKE_POS_LARGE: + set_pitch_shake_from_point(0x100, 0x8, 0x3000, 8000.f, posX, posY, posZ); + set_fov_shake_from_point_preset(SHAKE_FOV_LARGE, posX, posY, posZ); break; } } -void unused_set_camera_shake(s16 a) { - switch (a) { - case 1: +/** + * Start a camera shake from an environmental source, but only shake the camera's pitch. + */ +void unused_set_camera_pitch_shake_env(s16 shake) { + switch (shake) { + case SHAKE_ENV_EXPLOSION: set_camera_pitch_shake(0x60, 0x8, 0x4000); break; - case 2: + case SHAKE_ENV_BOWSER_THROW_BOUNCE: set_camera_pitch_shake(0xC0, 0x8, 0x4000); break; - case 3: + case SHAKE_ENV_BOWSER_JUMP: set_camera_pitch_shake(0x100, 0x8, 0x3000); break; } } -void return_height_above_floor(f32 *a, f32 b, f32 c, f32 *d, f32 e, f32 f) { - f32 floorHeight = sGeometryForMario.currFloorHeight; +/** + * Calculates mario's distance to the floor, or the water level if it is above the floor. Then: + * `posOff` is set to the distance multiplied by posMul and bounded to [-posBound, posBound] + * `focOff` is set to the distance multiplied by focMul and bounded to [-focBound, focBound] + * + * Notes: + * posMul is always 1.0f, focMul is always 0.9f + * both ranges are always 200.f + * Since focMul is 0.9, `focOff` is closer to the floor than `posOff` + * posOff and focOff are sometimes the same address, which just ignores the pos calculation + */ +void calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 focMul, f32 focBound) { + f32 floorHeight = sMarioGeometry.currFloorHeight; f32 waterHeight; UNUSED s32 filler; - if (!(sMarioStatusForCamera->action & ACT_FLAG_METAL_WATER)) { - if (floorHeight < (waterHeight = find_water_level(sMarioStatusForCamera->pos[0], - sMarioStatusForCamera->pos[2]))) { + if (!(sMarioCamState->action & ACT_FLAG_METAL_WATER)) { + //! @bug this should use sMarioGeometry.waterHeight + if (floorHeight < (waterHeight = find_water_level(sMarioCamState->pos[0], sMarioCamState->pos[2]))) { floorHeight = waterHeight; } } - if (sMarioStatusForCamera->action & ACT_FLAG_ON_POLE) { - if (sGeometryForMario.currFloorHeight >= gMarioStates[0].usedObj->oPosY - && sMarioStatusForCamera->pos[1] + if (sMarioCamState->action & ACT_FLAG_ON_POLE) { + if (sMarioGeometry.currFloorHeight >= gMarioStates[0].usedObj->oPosY && sMarioCamState->pos[1] < 0.7f * gMarioStates[0].usedObj->hitboxHeight + gMarioStates[0].usedObj->oPosY) { - c = 1200; + posBound = 1200; } } - *a = (floorHeight - sMarioStatusForCamera->pos[1]) * b; + *posOff = (floorHeight - sMarioCamState->pos[1]) * posMul; - if (*a > c) { - *a = c; + if (*posOff > posBound) { + *posOff = posBound; } - if (*a < -c) { - *a = -c; + if (*posOff < -posBound) { + *posOff = -posBound; } - *d = (floorHeight - sMarioStatusForCamera->pos[1]) * e; + *focOff = (floorHeight - sMarioCamState->pos[1]) * focMul; - if (*d > f) { - *d = f; + if (*focOff > focBound) { + *focOff = focBound; } - if (*d < -f) { - *d = -f; + if (*focOff < -focBound) { + *focOff = -focBound; } } -void set_cam_focus_and_pos_rel_mario(Vec3f a, Vec3f b, f32 c, f32 d, f32 e, s16 f, s16 g) { - Vec3f sp24; +void focus_on_mario(Vec3f focus, Vec3f pos, f32 posYOff, f32 focYOff, f32 dist, s16 pitch, s16 yaw) { + Vec3f marioPos; - sp24[0] = sMarioStatusForCamera->pos[0]; - sp24[1] = sMarioStatusForCamera->pos[1] + c; - sp24[2] = sMarioStatusForCamera->pos[2]; + marioPos[0] = sMarioCamState->pos[0]; + marioPos[1] = sMarioCamState->pos[1] + posYOff; + marioPos[2] = sMarioCamState->pos[2]; - vec3f_set_dist_and_angle(sp24, b, e, f + D_8033B3F0, g); + vec3f_set_dist_and_angle(marioPos, pos, dist, pitch + sLakituPitch, yaw); - a[0] = sMarioStatusForCamera->pos[0]; - a[1] = sMarioStatusForCamera->pos[1] + d; - a[2] = sMarioStatusForCamera->pos[2]; + focus[0] = sMarioCamState->pos[0]; + focus[1] = sMarioCamState->pos[1] + focYOff; + focus[2] = sMarioCamState->pos[2]; } -static void unused_8027F950(Vec3f a, Vec3f b, f32 c, f32 d, f32 e, s16 f, s16 g) { - Vec3f sp34; - f32 sp30; - f32 sp2C; - s16 sp2A; - s16 sp28; - s16 sp26; - s16 sp24; +static UNUSED void set_pos_to_mario(Vec3f foc, Vec3f pos, f32 yOff, f32 focYOff, f32 dist, s16 pitch, s16 yaw) { + Vec3f marioPos; + f32 posDist; + f32 focDist; - vec3f_copy(sp34, sMarioStatusForCamera->pos); - sp34[1] += c; + s16 posPitch; + s16 posYaw; + s16 focPitch; + s16 focYaw; - vec3f_set_dist_and_angle(sp34, b, e, f + D_8033B3F0, g); - vec3f_get_dist_and_angle(b, sMarioStatusForCamera->pos, &sp30, &sp2A, &sp28); - vec3f_get_dist_and_angle(b, a, &sp2C, &sp26, &sp24); - vec3f_set_dist_and_angle(b, a, sp2C, sp26, sp24); + vec3f_copy(marioPos, sMarioCamState->pos); + marioPos[1] += yOff; - a[1] = sMarioStatusForCamera->pos[1] + d; + vec3f_set_dist_and_angle(marioPos, pos, dist, pitch + sLakituPitch, yaw); + vec3f_get_dist_and_angle(pos, sMarioCamState->pos, &posDist, &posPitch, &posYaw); + + //! Useless get and set + vec3f_get_dist_and_angle(pos, foc, &focDist, &focPitch, &focYaw); + vec3f_set_dist_and_angle(pos, foc, focDist, focPitch, focYaw); + + foc[1] = sMarioCamState->pos[1] + focYOff; } -void set_camera_height(struct LevelCamera *c, f32 goalHeight) { +/** + * Set the camera's y coordinate to goalHeight, respecting floors and ceilings in the way + */ +void set_camera_height(struct Camera *c, f32 goalHeight) { struct Surface *surface; f32 marioFloorHeight; f32 marioCeilHeight; f32 camFloorHeight; UNUSED u8 filler[8]; - UNUSED s16 action = sMarioStatusForCamera->action; - f32 sp28 = 125.f; - f32 camCeilHeight = - find_ceil(c->pos[0], gCameraStatus.camFocAndPosCurrAndGoal[3][1] - 50.f, c->pos[2], &surface); + UNUSED s16 action = sMarioCamState->action; + f32 baseOff = 125.f; + f32 camCeilHeight = find_ceil(c->pos[0], gLakituState.goalPos[1] - 50.f, c->pos[2], &surface); - if (sMarioStatusForCamera->action & ACT_FLAG_HANGING) { - marioCeilHeight = sGeometryForMario.currCeilHeight; - marioFloorHeight = sGeometryForMario.currFloorHeight; + if (sMarioCamState->action & ACT_FLAG_HANGING) { + marioCeilHeight = sMarioGeometry.currCeilHeight; + marioFloorHeight = sMarioGeometry.currFloorHeight; if (marioFloorHeight < marioCeilHeight - 400.f) { marioFloorHeight = marioCeilHeight - 400.f; @@ -442,14 +699,14 @@ void set_camera_height(struct LevelCamera *c, f32 goalHeight) { goalHeight = marioFloorHeight + (marioCeilHeight - marioFloorHeight) * 0.4f; - if (sMarioStatusForCamera->pos[1] - 400 > goalHeight) { - goalHeight = sMarioStatusForCamera->pos[1] - 400; + if (sMarioCamState->pos[1] - 400 > goalHeight) { + goalHeight = sMarioCamState->pos[1] - 400; } approach_camera_height(c, goalHeight, 5.f); } else { - camFloorHeight = find_floor(c->pos[0], c->pos[1] + 100.f, c->pos[2], &surface) + sp28; - marioFloorHeight = sp28 + sGeometryForMario.currFloorHeight; + camFloorHeight = find_floor(c->pos[0], c->pos[1] + 100.f, c->pos[2], &surface) + baseOff; + marioFloorHeight = baseOff + sMarioGeometry.currFloorHeight; if (camFloorHeight < marioFloorHeight) { camFloorHeight = marioFloorHeight; @@ -458,539 +715,667 @@ void set_camera_height(struct LevelCamera *c, f32 goalHeight) { goalHeight = camFloorHeight; c->pos[1] = goalHeight; } - if (sMarioStatusForCamera->action == ACT_BUTT_STUCK_IN_GROUND - || sMarioStatusForCamera->action == ACT_HEAD_STUCK_IN_GROUND - || sMarioStatusForCamera->action == ACT_FEET_STUCK_IN_GROUND) { + // Warp camera to goalHeight if further than 1000 and mario is stuck in the ground + if (sMarioCamState->action == ACT_BUTT_STUCK_IN_GROUND || + sMarioCamState->action == ACT_HEAD_STUCK_IN_GROUND || + sMarioCamState->action == ACT_FEET_STUCK_IN_GROUND) { if (ABS(c->pos[1] - goalHeight) > 1000.f) { c->pos[1] = goalHeight; } } approach_camera_height(c, goalHeight, 20.f); if (camCeilHeight != 20000.f) { - camCeilHeight -= sp28; - if ((c->pos[1] > camCeilHeight && sGeometryForMario.currFloorHeight + sp28 < camCeilHeight) - || (sGeometryForMario.currCeilHeight != 20000.f - && sGeometryForMario.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) { + camCeilHeight -= baseOff; + if ((c->pos[1] > camCeilHeight && sMarioGeometry.currFloorHeight + baseOff < camCeilHeight) + || (sMarioGeometry.currCeilHeight != 20000.f + && sMarioGeometry.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) { c->pos[1] = camCeilHeight; } } } } -s16 return_pitch_parallel_floor(s16 yaw) { +/** + * Pitch the camera down when the camera is facing down a slope + */ +s16 look_down_slopes(s16 camYaw) { struct Surface *floor; - f32 floorHeight; + f32 floorDY; + // Default pitch s16 pitch = 0x05B0; - f32 xPos = sMarioStatusForCamera->pos[0] + sins(yaw) * 40.f; - f32 zPos = sMarioStatusForCamera->pos[2] + coss(yaw) * 40.f; + // x and z offsets towards the camera + f32 xOff = sMarioCamState->pos[0] + sins(camYaw) * 40.f; + f32 zOff = sMarioCamState->pos[2] + coss(camYaw) * 40.f; - floorHeight = - find_floor(xPos, sMarioStatusForCamera->pos[1], zPos, &floor) - sMarioStatusForCamera->pos[1]; + floorDY = find_floor(xOff, sMarioCamState->pos[1], zOff, &floor) - sMarioCamState->pos[1]; if (floor != NULL) { - if (floor->type != SURFACE_WALL_MISC && floorHeight > 0) { - if (floor->normal.z == 0.f && floorHeight < 100.f) { + if (floor->type != SURFACE_WALL_MISC && floorDY > 0) { + if (floor->normal.z == 0.f && floorDY < 100.f) { pitch = 0x05B0; } else { - pitch += atan2s(40.f, floorHeight); + // Add the slope's angle of declination to the pitch + pitch += atan2s(40.f, floorDY); } } } + return pitch; } -void func_8027FF44(struct LevelCamera *c) { - f32 camDistToMario; - s16 camPitchToMario; - s16 camYawToMario; - Vec3f sp24 = { 0, 0, 0 }; +/** + * Look ahead to the left or right in the direction the player is facing + * The calculation for pan[0] could be simplified to: + * yaw = -yaw; + * pan[0] = sins(sMarioCamState->faceAngle[1] + yaw) * sins(0xC00) * dist; + * Perhaps, early in development, the pan used to be calculated for both the x and z directions + * + * Since this function only affects the camera's focus, mario's movement direction isn't affected. + */ +void pan_ahead_of_player(struct Camera *c) { + f32 dist; + s16 pitch; + s16 yaw; + Vec3f pan = { 0, 0, 0 }; - vec3f_get_dist_and_angle(c->pos, sMarioStatusForCamera->pos, &camDistToMario, &camPitchToMario, - &camYawToMario); + // Get distance and angle from camera to mario. + vec3f_get_dist_and_angle(c->pos, sMarioCamState->pos, &dist, &pitch, &yaw); - sp24[2] = sins(0xC00) * camDistToMario; + // The camera will pan ahead up to about 30% of the camera's distance to mario. + pan[2] = sins(0xC00) * dist; - rotate_in_xz(sp24, sp24, sMarioStatusForCamera->faceAngle[1]); - camYawToMario = -camYawToMario; - rotate_in_xz(sp24, sp24, camYawToMario); - sp24[2] = 0.f; + rotate_in_xz(pan, pan, sMarioCamState->faceAngle[1]); + // rotate in the opposite direction + yaw = -yaw; + rotate_in_xz(pan, pan, yaw); + // Only pan left or right + pan[2] = 0.f; - if (sMarioStatusForCamera->action == ACT_LONG_JUMP - || (sMarioStatusForCamera->action != ACT_TOP_OF_POLE - && (sMarioStatusForCamera->action & ACT_FLAG_ON_POLE))) { - sp24[0] = -sp24[0]; + // If mario is long jumping, or on a flag pole (but not at the top), then pan in the opposite direction + if (sMarioCamState->action == ACT_LONG_JUMP || + (sMarioCamState->action != ACT_TOP_OF_POLE && (sMarioCamState->action & ACT_FLAG_ON_POLE))) { + pan[0] = -pan[0]; } - if (gCameraFlags2 & CAM_FLAG_2_SLEEPING) { - approach_f32_exponential_bool(&D_8033B40C, 0.f, 0.025f); + + // Slowly make the actual pan, sPanDistance, approach the calculated pan + // If mario is sleeping, then don't pan + if (sStatusFlags & CAM_FLAG_SLEEPING) { + approach_f32_asymptotic_bool(&sPanDistance, 0.f, 0.025f); } else { - approach_f32_exponential_bool(&D_8033B40C, sp24[0], 0.025f); + approach_f32_asymptotic_bool(&sPanDistance, pan[0], 0.025f); } - sp24[0] = D_8033B40C; - camYawToMario = -camYawToMario; - rotate_in_xz(sp24, sp24, camYawToMario); - vec3f_add(c->focus, sp24); + + // Now apply the pan. It's a dir vector to the left or right, rotated by the camera's yaw to mario + pan[0] = sPanDistance; + yaw = -yaw; + rotate_in_xz(pan, pan, yaw); + vec3f_add(c->focus, pan); } s16 find_in_bounds_yaw_wdw_bob_thi(Vec3f pos, Vec3f origin, s16 yaw) { switch (gCurrLevelArea) { case AREA_WDW_MAIN: - yaw = clamp_positions_and_find_yaw_angle(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f); + yaw = clamp_positions_and_find_yaw(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f); break; case AREA_BOB: - yaw = clamp_positions_and_find_yaw_angle(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f); + yaw = clamp_positions_and_find_yaw(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f); break; case AREA_THI_HUGE: - yaw = clamp_positions_and_find_yaw_angle(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f); + yaw = clamp_positions_and_find_yaw(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f); break; case AREA_THI_TINY: - yaw = clamp_positions_and_find_yaw_angle(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f); + yaw = clamp_positions_and_find_yaw(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f); break; } return yaw; } -s32 return_open_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { - f32 xDistFocToMario = sMarioStatusForCamera->pos[0] - c->xFocus; - f32 zDistFocToMario = sMarioStatusForCamera->pos[2] - c->zFocus; - s16 yaw = atan2s(zDistFocToMario, xDistFocToMario) + sFirstPersonCameraYaw; - s16 pitch = return_pitch_parallel_floor(yaw); +/** + * Rotates the camera around the area's center point. + */ +s32 update_radial_camera(struct Camera *c, Vec3f focus, Vec3f pos) { + f32 cenDistX = sMarioCamState->pos[0] - c->areaCenX; + f32 cenDistZ = sMarioCamState->pos[2] - c->areaCenZ; + s16 camYaw = atan2s(cenDistZ, cenDistX) + sModeOffsetYaw; + s16 pitch = look_down_slopes(camYaw); UNUSED f32 unused1; - f32 posHeightAboveFloor; - f32 focusHeightAboveFloor; + f32 posY; + f32 focusY; UNUSED f32 unused2; UNUSED f32 unused3; - f32 yOffset = 125.f; - f32 sp28 = 1000.f; + f32 yOff = 125.f; + f32 baseDist = 1000.f; - sYawFocToMario = yaw - sFirstPersonCameraYaw; - return_height_above_floor(&posHeightAboveFloor, 1.f, 200.f, &focusHeightAboveFloor, 0.9f, 200.f); - set_cam_focus_and_pos_rel_mario(focus, pos, posHeightAboveFloor + yOffset, - focusHeightAboveFloor + yOffset, D_8033B3EE + sp28, pitch, yaw); - yaw = find_in_bounds_yaw_wdw_bob_thi(pos, focus, yaw); + sAreaYaw = camYaw - sModeOffsetYaw; + calc_y_to_curr_floor(&posY, 1.f, 200.f, &focusY, 0.9f, 200.f); + focus_on_mario(focus, pos, posY + yOff, focusY + yOff, sLakituDist + baseDist, pitch, camYaw); + camYaw = find_in_bounds_yaw_wdw_bob_thi(pos, focus, camYaw); - return yaw; + return camYaw; } -s32 return_platform_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { - UNUSED f32 xDistFocToMario = sMarioStatusForCamera->pos[0] - c->xFocus; - UNUSED f32 zDistFocToMario = sMarioStatusForCamera->pos[2] - c->zFocus; - s16 yaw = sPlatformLevelPresetBaseYaw + gPlatformLevelYawOffset; - s16 pitch = return_pitch_parallel_floor(yaw); - f32 posHeightAboveFloor; - f32 focusHeightAboveFloor; +/** + * Update the camera during 8 directional mode + */ +s32 update_8_directions_camera(struct Camera *c, Vec3f focus, Vec3f pos) { + UNUSED f32 cenDistX = sMarioCamState->pos[0] - c->areaCenX; + UNUSED f32 cenDistZ = sMarioCamState->pos[2] - c->areaCenZ; + s16 camYaw = s8DirModeBaseYaw + s8DirModeYawOffset; + s16 pitch = look_down_slopes(camYaw); + f32 posY; + f32 focusY; UNUSED f32 unused1; UNUSED f32 unused2; UNUSED f32 unused3; - f32 yOffset = 125.f; - f32 sp28 = 1000.f; + f32 yOff = 125.f; + f32 baseDist = 1000.f; - sYawFocToMario = yaw; - return_height_above_floor(&posHeightAboveFloor, 1.f, 200.f, &focusHeightAboveFloor, 0.9f, 200.f); - set_cam_focus_and_pos_rel_mario(focus, pos, posHeightAboveFloor + yOffset, - focusHeightAboveFloor + yOffset, D_8033B3EE + sp28, pitch, yaw); - func_8027FF44(c); + sAreaYaw = camYaw; + calc_y_to_curr_floor(&posY, 1.f, 200.f, &focusY, 0.9f, 200.f); + focus_on_mario(focus, pos, posY + yOff, focusY + yOff, sLakituDist + baseDist, pitch, camYaw); + pan_ahead_of_player(c); if (gCurrLevelArea == AREA_DDD_SUB) { - yaw = clamp_positions_and_find_yaw_angle(pos, focus, 6839.f, 995.f, 5994.f, -3945.f); + camYaw = clamp_positions_and_find_yaw(pos, focus, 6839.f, 995.f, 5994.f, -3945.f); } - return yaw; + return camYaw; } -void func_80280550(struct LevelCamera *c) { - s16 sp46 = 10922; - s16 sp44 = -10922; - s16 sp42 = 4096; - s16 sp40; - s32 sp3C; - UNUSED s16 sp3A = 0; - UNUSED s32 sp34 = 0; - f32 xDistFocToMario = sMarioStatusForCamera->pos[0] - c->xFocus; - f32 zDistFocToMario = sMarioStatusForCamera->pos[2] - c->zFocus; +/** + * Moves the camera for the radial and outward radial camera modes. + * + * If sModeOffsetYaw is 0, the camera points directly at the area center point. + */ +void radial_camera_move(struct Camera *c) { + s16 maxAreaYaw = DEGREES(60); + s16 minAreaYaw = DEGREES(-60); + s16 rotateSpeed = 0x1000; + s16 avoidYaw; + s32 avoidStatus; + UNUSED s16 unused1 = 0; + UNUSED s32 unused2 = 0; + f32 areaDistX = sMarioCamState->pos[0] - c->areaCenX; + f32 areaDistZ = sMarioCamState->pos[2] - c->areaCenZ; UNUSED s32 filler; - s16 sp26 = - calculate_yaw(sMarioStatusForCamera->pos, c->pos) - atan2s(zDistFocToMario, xDistFocToMario); - if (sp26 > sp46) { - sp26 = sp46; + // How much the camera's yaw changed + s16 yawOffset = calculate_yaw(sMarioCamState->pos, c->pos) - atan2s(areaDistZ, areaDistX); + + if (yawOffset > maxAreaYaw) { + yawOffset = maxAreaYaw; } - if (sp26 < sp44) { - sp26 = sp44; + if (yawOffset < minAreaYaw) { + yawOffset = minAreaYaw; } - if (!(gCameraMovementFlags - & (CAM_MOVE_RETURN_TO_MIDDLE | CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ROTATE_LEFT))) { - if (sGeometryForMario.currFloorType == SURFACE_CAMERA_MIDDLE - && sGeometryForMario.prevFloorType != SURFACE_CAMERA_MIDDLE) { - gCameraMovementFlags |= (CAM_MOVE_RETURN_TO_MIDDLE | CAM_MOVE_UNKNOWN_5); + // Check if mario stepped on a surface that rotates the camera. For example, when mario enters the + // gate in BoB, the camera turns right to face up the hill path + if (!(gCameraMovementFlags & CAM_MOVE_ROTATE)) { + if (sMarioGeometry.currFloorType == SURFACE_CAMERA_MIDDLE + && sMarioGeometry.prevFloorType != SURFACE_CAMERA_MIDDLE) { + gCameraMovementFlags |= (CAM_MOVE_RETURN_TO_MIDDLE | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if (sGeometryForMario.currFloorType == SURFACE_CAMERA_ROTATE_RIGHT - && sGeometryForMario.prevFloorType != SURFACE_CAMERA_ROTATE_RIGHT) { - gCameraMovementFlags |= (CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_UNKNOWN_5); + if (sMarioGeometry.currFloorType == SURFACE_CAMERA_ROTATE_RIGHT + && sMarioGeometry.prevFloorType != SURFACE_CAMERA_ROTATE_RIGHT) { + gCameraMovementFlags |= (CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if (sGeometryForMario.currFloorType == SURFACE_CAMERA_ROTATE_LEFT - && sGeometryForMario.prevFloorType != SURFACE_CAMERA_ROTATE_LEFT) { - gCameraMovementFlags |= (CAM_MOVE_ROTATE_LEFT | CAM_MOVE_UNKNOWN_5); + if (sMarioGeometry.currFloorType == SURFACE_CAMERA_ROTATE_LEFT + && sMarioGeometry.prevFloorType != SURFACE_CAMERA_ROTATE_LEFT) { + gCameraMovementFlags |= (CAM_MOVE_ROTATE_LEFT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } } - if (gCameraMovementFlags & CAM_MOVE_UNKNOWN_5) { - sp42 = 512; + if (gCameraMovementFlags & CAM_MOVE_ENTERED_ROTATE_SURFACE) { + rotateSpeed = 0x200; } - if (c->currPreset == CAMERA_PRESET_REVERSE_TOWER) { - xDistFocToMario = -xDistFocToMario; - zDistFocToMario = -zDistFocToMario; + if (c->mode == CAMERA_MODE_OUTWARD_RADIAL) { + areaDistX = -areaDistX; + areaDistZ = -areaDistZ; } - sp3C = func_8028F2F0(c, c->pos, &sp40, 1024); - if (sp3C == 3) { - if (sp40 - atan2s(zDistFocToMario, xDistFocToMario) + 0x4000 < 0) { - sp40 += 32768; + // Avoid obstructing walls + avoidStatus = rotate_camera_around_walls(c, c->pos, &avoidYaw, 0x400); + if (avoidStatus == 3) { + if (avoidYaw - atan2s(areaDistZ, areaDistX) + DEGREES(90) < 0) { + avoidYaw += DEGREES(180); } - sp40 -= atan2s(zDistFocToMario, xDistFocToMario); - if (sp40 >= 0x4AAB) { - sp40 = 19114; + + // We want to change sModeOffsetYaw so that the player is no longer obstructed by the wall. + // So, we make avoidYaw relative to the yaw around the area center + avoidYaw -= atan2s(areaDistZ, areaDistX); + + // Bound avoid yaw to radial mode constraints + if (avoidYaw > DEGREES(105)) { + avoidYaw = DEGREES(105); } - if (sp40 <= -0x4AAB) { - sp40 = -19114; + if (avoidYaw < DEGREES(-105)) { + avoidYaw = DEGREES(-105); } } if (gCameraMovementFlags & CAM_MOVE_RETURN_TO_MIDDLE) { - if (camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, 0, sp42) == 0) { + if (camera_approach_s16_symmetric_bool(&sModeOffsetYaw, 0, rotateSpeed) == 0) { gCameraMovementFlags &= ~CAM_MOVE_RETURN_TO_MIDDLE; } } else { - if ((gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) && sp3C == 3 - && sp40 + 16 < sFirstPersonCameraYaw) { - sFirstPersonCameraYaw = sp40; - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_UNKNOWN_5); + // Prevent the player from rotating into obstructing walls + if ((gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) && avoidStatus == 3 + && avoidYaw + 0x10 < sModeOffsetYaw) { + sModeOffsetYaw = avoidYaw; + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if ((gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) && sp3C == 3 - && sp40 - 16 > sFirstPersonCameraYaw) { - sFirstPersonCameraYaw = sp40; - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_UNKNOWN_5); + if ((gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) && avoidStatus == 3 + && avoidYaw - 0x10 > sModeOffsetYaw) { + sModeOffsetYaw = avoidYaw; + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if (!(sCameraSideCFlags & 4) && (gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) - && camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, sp46, sp42) == 0) { - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_UNKNOWN_5); + + // If it's the first time rotating, just rotate to +-60 degrees + if (!(s2ndRotateFlags & CAM_MOVE_ROTATE_RIGHT) && (gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) + && camera_approach_s16_symmetric_bool(&sModeOffsetYaw, maxAreaYaw, rotateSpeed) == 0) { + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if (!(sCameraSideCFlags & 8) && (gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) - && camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, sp44, sp42) == 0) { - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_UNKNOWN_5); + if (!(s2ndRotateFlags & CAM_MOVE_ROTATE_LEFT) && (gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) + && camera_approach_s16_symmetric_bool(&sModeOffsetYaw, minAreaYaw, rotateSpeed) == 0) { + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_ENTERED_ROTATE_SURFACE); } - if ((sCameraSideCFlags & 4) && (gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) - && camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, 19114, sp42) == 0) { - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_UNKNOWN_5); - sCameraSideCFlags &= ~4; + + // If it's the second time rotating, rotate all the way to +-105 degrees. + if ((s2ndRotateFlags & CAM_MOVE_ROTATE_RIGHT) && (gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT) + && camera_approach_s16_symmetric_bool(&sModeOffsetYaw, DEGREES(105), rotateSpeed) == 0) { + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ENTERED_ROTATE_SURFACE); + s2ndRotateFlags &= ~CAM_MOVE_ROTATE_RIGHT; } - if ((sCameraSideCFlags & 8) && (gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) - && camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, -19114, sp42) == 0) { - gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_UNKNOWN_5); - sCameraSideCFlags &= ~8; + if ((s2ndRotateFlags & CAM_MOVE_ROTATE_LEFT) && (gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) + && camera_approach_s16_symmetric_bool(&sModeOffsetYaw, DEGREES(-105), rotateSpeed) == 0) { + gCameraMovementFlags &= ~(CAM_MOVE_ROTATE_LEFT | CAM_MOVE_ENTERED_ROTATE_SURFACE); + s2ndRotateFlags &= ~CAM_MOVE_ROTATE_LEFT; } } - if (!(gCameraMovementFlags - & (CAM_MOVE_RETURN_TO_MIDDLE | CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ROTATE_LEFT))) { - if (sp3C == 3) { - approach_s16_exponential_bool(&sFirstPersonCameraYaw, sp40, 10); + if (!(gCameraMovementFlags & CAM_MOVE_ROTATE)) { + // If not rotating, rotate away from walls obscuring mario from view + if (avoidStatus == 3) { + approach_s16_asymptotic_bool(&sModeOffsetYaw, avoidYaw, 10); } else { - if (c->currPreset == CAMERA_PRESET_OPEN_CAMERA) { - sp42 = gMarioStates[0].forwardVel / 32.f * 128.f; - camera_approach_s16_symmetric_bool(&sFirstPersonCameraYaw, sp26, sp42); + if (c->mode == CAMERA_MODE_RADIAL) { + // sModeOffsetYaw only updates when mario is moving + rotateSpeed = gMarioStates[0].forwardVel / 32.f * 128.f; + camera_approach_s16_symmetric_bool(&sModeOffsetYaw, yawOffset, rotateSpeed); } - if (c->currPreset == CAMERA_PRESET_REVERSE_TOWER) { - sFirstPersonCameraYaw = func_8028AF24(c, atan2s(zDistFocToMario, xDistFocToMario)); + if (c->mode == CAMERA_MODE_OUTWARD_RADIAL) { + sModeOffsetYaw = offset_yaw_outward_radial(c, atan2s(areaDistZ, areaDistX)); } } } - if (sFirstPersonCameraYaw >= 0x5555) { - sFirstPersonCameraYaw = 21844; + // Bound sModeOffsetYaw within (-120, 120) degrees + if (sModeOffsetYaw > 0x5554) { + sModeOffsetYaw = 0x5554; } - if (sFirstPersonCameraYaw < -0x5554) { - sFirstPersonCameraYaw = -21844; + if (sModeOffsetYaw < -0x5554) { + sModeOffsetYaw = -0x5554; } } -void func_80280BD8(f32 a, s16 b) { - if (D_8033B3EE < 0) { - if ((D_8033B3EE += 30) > 0) { - D_8033B3EE = 0; +/** + * Moves lakitu from zoomed in to zoomed out and vice versa. + * When C-Down mode is not active, sLakituDist and sLakituPitch decrease to 0. + */ +void lakitu_zoom(f32 rangeDist, s16 rangePitch) { + if (sLakituDist < 0) { + if ((sLakituDist += 30) > 0) { + sLakituDist = 0; } - } else if (a < D_8033B3EE) { - if ((D_8033B3EE -= 30) < a) { - D_8033B3EE = a; + } else if (rangeDist < sLakituDist) { + if ((sLakituDist -= 30) < rangeDist) { + sLakituDist = rangeDist; } } else if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - if ((D_8033B3EE += 30) > a) { - D_8033B3EE = a; + if ((sLakituDist += 30) > rangeDist) { + sLakituDist = rangeDist; } } else { - if ((D_8033B3EE -= 30) < 0) { - D_8033B3EE = 0; + if ((sLakituDist -= 30) < 0) { + sLakituDist = 0; } } - if (gCurrLevelArea == AREA_SSL_PYRAMID - && gCurrLevelCamera->currPreset == CAMERA_PRESET_REVERSE_TOWER) { - b /= 2; + if (gCurrLevelArea == AREA_SSL_PYRAMID && gCamera->mode == CAMERA_MODE_OUTWARD_RADIAL) { + rangePitch /= 2; } if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - if ((D_8033B3F0 += b / 13) > b) { - D_8033B3F0 = b; + if ((sLakituPitch += rangePitch / 13) > rangePitch) { + sLakituPitch = rangePitch; } } else { - if ((D_8033B3F0 -= b / 13) < 0) { - D_8033B3F0 = 0; + if ((sLakituPitch -= rangePitch / 13) < 0) { + sLakituPitch = 0; } } } -void func_80280E0C(struct LevelCamera *c) { - func_8028B3DC(c, 0.f); +void radial_camera_input_default(struct Camera *c) { + radial_camera_input(c, 0.f); } -void func_80280E3C(UNUSED struct LevelCamera *c) { - f32 sp4 = 1000.f; +/** + * Makes lakitu cam's yaw match the angle turned towards in C-Up mode, and makes lakitu slowly fly back + * to the distance he was at before C-Up + */ +void update_yaw_and_dist_from_c_up(UNUSED struct Camera *c) { + f32 dist = 1000.f; - sFirstPersonCameraYaw = D_8033B418.unk8.unk1E - sYawFocToMario; - D_8033B3EE = D_8033B418.unk8.unk18 - sp4; - gCameraMovementFlags &= ~CAM_MOVE_INTO_C_UP; + sModeOffsetYaw = sModeInfo.transitionStart.yaw - sAreaYaw; + sLakituDist = sModeInfo.transitionStart.dist - dist; + // No longer in C-Up + gCameraMovementFlags &= ~CAM_MOVING_INTO_MODE; } -void update_open_camera(struct LevelCamera *c) { +/** + * Handles input and updates for the radial camera mode + */ +void mode_radial_camera(struct Camera *c) { Vec3f pos; UNUSED u8 unused1[8]; - s16 sp22 = sYawFocToMario; + s16 oldAreaYaw = sAreaYaw; UNUSED u8 unused2[4]; - if (gCameraMovementFlags & CAM_MOVE_INTO_C_UP) { - func_80280E3C(c); + if (gCameraMovementFlags & CAM_MOVING_INTO_MODE) { + update_yaw_and_dist_from_c_up(c); } - func_80280E0C(c); - func_80280550(c); + radial_camera_input_default(c); + radial_camera_move(c); - if (c->currPreset == CAMERA_PRESET_OPEN_CAMERA) { - func_80280BD8(400.f, 0x0900); + if (c->mode == CAMERA_MODE_RADIAL) { + lakitu_zoom(400.f, 0x900); } - c->storedYaw = return_open_camera_yaw(c, c->focus, pos); + c->nextYaw = update_radial_camera(c, c->focus, pos); c->pos[0] = pos[0]; c->pos[2] = pos[2]; - D_8033B3EC = sYawFocToMario - sp22; - if (sMarioStatusForCamera->action == ACT_RIDING_HOOT) { + sAreaYawChange = sAreaYaw - oldAreaYaw; + if (sMarioCamState->action == ACT_RIDING_HOOT) { pos[1] += 500.f; } set_camera_height(c, pos[1]); - func_8027FF44(c); + pan_ahead_of_player(c); } -void update_platform_level_camera(struct LevelCamera *c) { +/** + * A mode that only has 8 camera angles, 45 degrees apart + */ +void mode_8_directions_camera(struct Camera *c) { Vec3f pos; UNUSED u8 unused[8]; - s16 sp1A = sYawFocToMario; + s16 oldAreaYaw = sAreaYaw; - func_8028B3DC(c, 0.f); + radial_camera_input(c, 0.f); if (gPlayer1Controller->buttonPressed & R_CBUTTONS) { - gPlatformLevelYawOffset += 0x2000; + s8DirModeYawOffset += DEGREES(45); play_sound_cbutton_side(); } if (gPlayer1Controller->buttonPressed & L_CBUTTONS) { - gPlatformLevelYawOffset -= 0x2000; + s8DirModeYawOffset -= DEGREES(45); play_sound_cbutton_side(); } - func_80280BD8(400.f, 2304); - c->storedYaw = return_platform_camera_yaw(c, c->focus, pos); + lakitu_zoom(400.f, 0x900); + c->nextYaw = update_8_directions_camera(c, c->focus, pos); c->pos[0] = pos[0]; c->pos[2] = pos[2]; - D_8033B3EC = sYawFocToMario - sp1A; + sAreaYawChange = sAreaYaw - oldAreaYaw; set_camera_height(c, pos[1]); } -s32 return_reverse_tower_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { - f32 xDistFocToMario = sMarioStatusForCamera->pos[0] - c->xFocus; - f32 zDistFocToMario = sMarioStatusForCamera->pos[2] - c->zFocus; - s16 yaw = atan2s(zDistFocToMario, xDistFocToMario) + sFirstPersonCameraYaw + 0x8000; - s16 pitch = return_pitch_parallel_floor(yaw); - f32 sp38 = 1000.f; - f32 yOffset = 125.f; - f32 posHeightAboveFloor; - f32 focusHeightAboveFloor; +/** + * Updates the camera in outward radial mode. + * sModeOffsetYaw is calculated in radial_camera_move, which calls offset_yaw_outward_radial + */ +s32 update_outward_radial_camera(struct Camera *c, Vec3f focus, Vec3f pos) { + f32 xDistFocToMario = sMarioCamState->pos[0] - c->areaCenX; + f32 zDistFocToMario = sMarioCamState->pos[2] - c->areaCenZ; + s16 camYaw = atan2s(zDistFocToMario, xDistFocToMario) + sModeOffsetYaw + DEGREES(180); + s16 pitch = look_down_slopes(camYaw); + f32 baseDist = 1000.f; + // A base offset of 125.f is ~= mario's eye height + f32 yOff = 125.f; + f32 posY; + f32 focusY; - sYawFocToMario = yaw - sFirstPersonCameraYaw - 0x8000; - return_height_above_floor(&posHeightAboveFloor, 1.f, 200.f, &focusHeightAboveFloor, 0.9f, 200.f); - set_cam_focus_and_pos_rel_mario(focus, pos, posHeightAboveFloor + yOffset, - focusHeightAboveFloor + yOffset, D_8033B3EE + sp38, pitch, yaw); + sAreaYaw = camYaw - sModeOffsetYaw - DEGREES(180); + calc_y_to_curr_floor(&posY, 1.f, 200.f, &focusY, 0.9f, 200.f); + focus_on_mario(focus, pos, posY + yOff, focusY + yOff, sLakituDist + baseDist, pitch, camYaw); - return yaw; + return camYaw; } -void update_reverse_tower_camera(struct LevelCamera *c) { +/** + * Input and updates for the outward radial mode. + */ +void mode_outward_radial_camera(struct Camera *c) { Vec3f pos; - s16 sp1A = sYawFocToMario; + s16 oldAreaYaw = sAreaYaw; - if (gCameraMovementFlags & CAM_MOVE_INTO_C_UP) { - func_80280E3C(c); + if (gCameraMovementFlags & CAM_MOVING_INTO_MODE) { + update_yaw_and_dist_from_c_up(c); } - func_80280E0C(c); - func_80280550(c); - func_80280BD8(400.f, 0x0900); - c->storedYaw = return_reverse_tower_camera_yaw(c, c->focus, pos); + radial_camera_input_default(c); + radial_camera_move(c); + lakitu_zoom(400.f, 0x900); + c->nextYaw = update_outward_radial_camera(c, c->focus, pos); c->pos[0] = pos[0]; c->pos[2] = pos[2]; - D_8033B3EC = sYawFocToMario - sp1A; - if (sMarioStatusForCamera->action == ACT_RIDING_HOOT) { + sAreaYawChange = sAreaYaw - oldAreaYaw; + if (sMarioCamState->action == ACT_RIDING_HOOT) { pos[1] += 500.f; } set_camera_height(c, pos[1]); - func_8027FF44(c); + pan_ahead_of_player(c); } -s32 return_parallel_tracking_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { - Vec3f spE8[2]; - Vec3f spDC; - Vec3f spD0; - Vec3f spC4; - Vec3f spB8; - s16 spB6; - s16 spB4; +/** + * Move the camera in parallel tracking mode + * + * Uses the line between the next two points in sParTrackPath + * The camera can move forward/back and side to side, but it will face perpendicular to that line + * + * Although, annoyingly, it's not truly parallel, the function returns the yaw from the camera to mario, + * so mario will run slightly towards the camera. + */ +s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { + Vec3f path[2]; + Vec3f parMidPoint; + Vec3f marioOffset; + Vec3f camOffset; + /// Adjusts the focus to look where mario is facing. Unused since marioOffset is copied to focus + Vec3f focOffset; + s16 pathPitch; + s16 pathYaw; UNUSED u8 filler[4]; - f32 spAC; - f32 spA8; - f32 spA4; + f32 distThresh; + f32 zoom; + f32 camParDist; UNUSED u8 filler2[8]; - f32 sp98; + f32 pathLength; UNUSED u8 filler3[8]; - UNUSED f32 sp8C = 0.5f; - f32 sp88 = 0.5f; - f32 sp84; - Vec3f sp78; + UNUSED f32 unusedScale = 0.5f; + f32 parScale = 0.5f; + f32 marioFloorDist; + Vec3f marioPos; UNUSED u8 filler4[12]; - UNUSED Vec3f sp60; - Vec3s sp58; - Vec3f sp4C; - Vec3f sp40; - Vec3f sp34; - f32 sp30; - f32 sp2C; - s16 sp2A; - s16 sp28; - s16 sp26; - s16 sp24; + UNUSED Vec3f unused4; + Vec3s pathAngle; + // Variables for changing to the next/prev path in the list + Vec3f oldPos; + Vec3f prevPathPos; + Vec3f nextPathPos; + f32 distToNext; + f32 distToPrev; + s16 prevPitch; + s16 nextPitch; + s16 prevYaw; + s16 nextYaw; - sp60[0] = 0.f; - sp60[1] = 0.f; - sp60[2] = 0.f; - vec3f_copy(sp4C, pos); - vec3f_copy(spE8[0], D_8033B470[D_8033B46C].unk4); - vec3f_copy(spE8[1], D_8033B470[D_8033B46C + 1].unk4); - spAC = D_8033B470[D_8033B46C].unk10; - spA8 = D_8033B470[D_8033B46C].unk14; - return_height_above_floor(&sp84, 1.f, 200.f, &sp84, 0.9f, 200.f); - sp78[0] = sMarioStatusForCamera->pos[0]; - sp78[1] = sMarioStatusForCamera->pos[1] + 150.f + sp84; - sp78[2] = sMarioStatusForCamera->pos[2]; - spDC[0] = spE8[0][0] + (spE8[1][0] - spE8[0][0]) * sp88; - spDC[1] = spE8[0][1] + (spE8[1][1] - spE8[0][1]) * sp88; - spDC[2] = spE8[0][2] + (spE8[1][2] - spE8[0][2]) * sp88; - vec3f_get_dist_and_angle(spE8[0], spE8[1], &sp98, &spB6, &spB4); - spD0[0] = sp78[0] - spDC[0]; - spD0[1] = sp78[1] - spDC[1]; - spD0[2] = sp78[2] - spDC[2]; - spB4 = -spB4; - rotate_in_xz(spD0, spD0, spB4); - spB4 = -spB4; - spB6 = -spB6; - rotate_in_yz(spD0, spD0, spB6); - spB6 = -spB6; - vec3f_copy(spB8, spD0); - spB8[0] = -spB8[0] * 0.f; - spB8[1] = spB8[1] * 0.f; - spC4[0] = pos[0] - spDC[0]; - spC4[1] = pos[1] - spDC[1]; - spC4[2] = pos[2] - spDC[2]; - spB4 = -spB4; - rotate_in_xz(spC4, spC4, spB4); - spB4 = -spB4; - spB6 = -spB6; - rotate_in_yz(spC4, spC4, spB6); - spB6 = -spB6; + unused4[0] = 0.f; + unused4[1] = 0.f; + unused4[2] = 0.f; - if (spD0[2] > spC4[2]) { - if (spD0[2] - spC4[2] > spAC) { - spC4[2] = spD0[2] - spAC; + // Store camera pos, for changing between paths + vec3f_copy(oldPos, pos); + + vec3f_copy(path[0], sParTrackPath[sParTrackIndex].pos); + vec3f_copy(path[1], sParTrackPath[sParTrackIndex + 1].pos); + + distThresh = sParTrackPath[sParTrackIndex].distThresh; + zoom = sParTrackPath[sParTrackIndex].zoom; + calc_y_to_curr_floor(&marioFloorDist, 1.f, 200.f, &marioFloorDist, 0.9f, 200.f); + + marioPos[0] = sMarioCamState->pos[0]; + // Mario's y pos + ~mario's height + mario's height above the floor + marioPos[1] = sMarioCamState->pos[1] + 150.f + marioFloorDist; + marioPos[2] = sMarioCamState->pos[2]; + + // Calculate middle of the path (parScale is 0.5f) + parMidPoint[0] = path[0][0] + (path[1][0] - path[0][0]) * parScale; + parMidPoint[1] = path[0][1] + (path[1][1] - path[0][1]) * parScale; + parMidPoint[2] = path[0][2] + (path[1][2] - path[0][2]) * parScale; + + // Get direction of path + vec3f_get_dist_and_angle(path[0], path[1], &pathLength, &pathPitch, &pathYaw); + + marioOffset[0] = marioPos[0] - parMidPoint[0]; + marioOffset[1] = marioPos[1] - parMidPoint[1]; + marioOffset[2] = marioPos[2] - parMidPoint[2]; + + // Make marioOffset point from the midpoint -> the start of the path + // Rotating by -yaw then -pitch moves the hor dist from the midpoint into marioOffset's z coordinate + // marioOffset[0] = the (perpendicular) horizontal distance from the path + // marioOffset[1] = the vertical distance from the path + // marioOffset[2] = the (parallel) horizontal distance from the path's midpoint + pathYaw = -pathYaw; + rotate_in_xz(marioOffset, marioOffset, pathYaw); + pathYaw = -pathYaw; + pathPitch = -pathPitch; + rotate_in_yz(marioOffset, marioOffset, pathPitch); + pathPitch = -pathPitch; + vec3f_copy(focOffset, marioOffset); + + // OK + focOffset[0] = -focOffset[0] * 0.f; + focOffset[1] = focOffset[1] * 0.f; + + // Repeat above calcs with camOffset + camOffset[0] = pos[0] - parMidPoint[0]; + camOffset[1] = pos[1] - parMidPoint[1]; + camOffset[2] = pos[2] - parMidPoint[2]; + pathYaw = -pathYaw; + rotate_in_xz(camOffset, camOffset, pathYaw); + pathYaw = -pathYaw; + pathPitch = -pathPitch; + rotate_in_yz(camOffset, camOffset, pathPitch); + pathPitch = -pathPitch; + + // If mario is distThresh units away from the camera along the path, move the camera + //! When distThresh != 0, it causes mario to move slightly towards the camera when running sideways + //! Set each ParallelTrackingPoint's distThresh to 0 to make Mario truly run parallel to the path + if (marioOffset[2] > camOffset[2]) { + if (marioOffset[2] - camOffset[2] > distThresh) { + camOffset[2] = marioOffset[2] - distThresh; } } else { - if (spD0[2] - spC4[2] < -spAC) { - spC4[2] = spD0[2] + spAC; + if (marioOffset[2] - camOffset[2] < -distThresh) { + camOffset[2] = marioOffset[2] + distThresh; } } - spD0[0] = -spD0[0] * spA8; - spD0[1] = spD0[1] * spA8; - spD0[2] = spC4[2]; - spB8[0] *= 0.3f; - spB8[1] *= 0.3f; - sp58[0] = spB6; - sp58[1] = spB4; - spD0[2] = sp98 / 2.f - spD0[2]; - sp58[1] = spB4 + 32768; - sp58[2] = 0; - set_pos_from_face_angle_and_vec3f(pos, spE8[0], spD0, sp58); - vec3f_get_dist_and_angle(spE8[0], c->pos, &spA4, &spB6, &spB4); - spB8[2] = sp98 / 2.f - spB8[2]; - set_pos_from_face_angle_and_vec3f(c->focus, spE8[0], spB8, sp58); + // If zoom != 0.0, the camera will move zoom% closer to mario + marioOffset[0] = -marioOffset[0] * zoom; + marioOffset[1] = marioOffset[1] * zoom; + marioOffset[2] = camOffset[2]; - if (gCameraFlags2 & CAM_FLAG_2_UNKNOWN_3) { - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_3; - D_8033B478.pos[0] = sp4C[0] - c->pos[0]; - D_8033B478.pos[1] = sp4C[1] - c->pos[1]; - D_8033B478.pos[2] = sp4C[2] - c->pos[2]; + //! Does nothing because focOffset[0] is always 0 + focOffset[0] *= 0.3f; + //! Does nothing because focOffset[1] is always 0 + focOffset[1] *= 0.3f; + + pathAngle[0] = pathPitch; + pathAngle[1] = pathYaw; //! No effect + + // make marioOffset[2] == distance from the start of the path + marioOffset[2] = pathLength / 2.f - marioOffset[2]; + + pathAngle[1] = pathYaw + DEGREES(180); + pathAngle[2] = 0; + + // Rotate the offset in the direction of the path again + offset_rotated(pos, path[0], marioOffset, pathAngle); + vec3f_get_dist_and_angle(path[0], c->pos, &camParDist, &pathPitch, &pathYaw); + + // Adjust the focus. Does nothing, focus is set to mario at the end + focOffset[2] = pathLength / 2.f - focOffset[2]; + offset_rotated(c->focus, path[0], focOffset, pathAngle); + + // Changing paths, update the stored position offset + if (sStatusFlags & CAM_FLAG_CHANGED_PARTRACK_INDEX) { + sStatusFlags &= ~CAM_FLAG_CHANGED_PARTRACK_INDEX; + sParTrackTransOff.pos[0] = oldPos[0] - c->pos[0]; + sParTrackTransOff.pos[1] = oldPos[1] - c->pos[1]; + sParTrackTransOff.pos[2] = oldPos[2] - c->pos[2]; } - approach_f32_exponential_bool(&D_8033B478.pos[0], 0.f, 0.025f); - approach_f32_exponential_bool(&D_8033B478.pos[1], 0.f, 0.025f); - approach_f32_exponential_bool(&D_8033B478.pos[2], 0.f, 0.025f); - vec3f_add(c->pos, D_8033B478.pos); + // Slowly transition to the next path + approach_f32_asymptotic_bool(&sParTrackTransOff.pos[0], 0.f, 0.025f); + approach_f32_asymptotic_bool(&sParTrackTransOff.pos[1], 0.f, 0.025f); + approach_f32_asymptotic_bool(&sParTrackTransOff.pos[2], 0.f, 0.025f); + vec3f_add(c->pos, sParTrackTransOff.pos); - if (D_8033B470[D_8033B46C + 1].unk0 != 0) { - calculate_angles(D_8033B470[D_8033B46C + 1].unk4, D_8033B470[D_8033B46C + 2].unk4, &sp28, - &sp24); - vec3f_set_dist_and_angle(D_8033B470[D_8033B46C + 1].unk4, sp34, 400.f, sp28, sp24); - sp2C = calc_abs_dist(sp78, sp34); - calculate_angles(D_8033B470[D_8033B46C + 1].unk4, D_8033B470[D_8033B46C].unk4, &sp2A, &sp26); - vec3f_set_dist_and_angle(D_8033B470[D_8033B46C + 1].unk4, sp40, 400.f, sp2A, sp26); - sp30 = calc_abs_dist(sp78, sp40); - if (sp2C < sp30) { - D_8033B46C++; - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_3; + // Check if the camera should go to the next path + if (sParTrackPath[sParTrackIndex + 1].startOfPath != 0) { + // get Mario's distance to the next path + calculate_angles(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex + 2].pos, &nextPitch, &nextYaw); + vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex + 1].pos, nextPathPos, 400.f, nextPitch, nextYaw); + distToPrev = calc_abs_dist(marioPos, nextPathPos); + + // get Mario's distance to the previous path + calculate_angles(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex].pos, &prevPitch, &prevYaw); + vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex + 1].pos, prevPathPos, 400.f, prevPitch, prevYaw); + distToNext = calc_abs_dist(marioPos, prevPathPos); + if (distToPrev < distToNext) { + sParTrackIndex++; + sStatusFlags |= CAM_FLAG_CHANGED_PARTRACK_INDEX; } } - if (D_8033B46C != 0) { - calculate_angles(D_8033B470[D_8033B46C].unk4, D_8033B470[D_8033B46C + 1].unk4, &sp28, &sp24); - vec3f_set_dist_and_angle(D_8033B470[D_8033B46C].unk4, sp34, 700.f, sp28, sp24); - sp2C = calc_abs_dist(sp78, sp34); - calculate_angles(D_8033B470[D_8033B46C].unk4, D_8033B470[D_8033B46C - 1].unk4, &sp2A, &sp26); - vec3f_set_dist_and_angle(D_8033B470[D_8033B46C].unk4, sp40, 700.f, sp2A, sp26); - sp30 = calc_abs_dist(sp78, sp40); - if (sp2C > sp30) { - D_8033B46C--; - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_3; + // Check if the camera should go to the previous path + if (sParTrackIndex != 0) { + // get Mario's distance to the next path + calculate_angles(sParTrackPath[sParTrackIndex].pos, sParTrackPath[sParTrackIndex + 1].pos, &nextPitch, &nextYaw); + vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex].pos, nextPathPos, 700.f, nextPitch, nextYaw); + distToPrev = calc_abs_dist(marioPos, nextPathPos); + + // get Mario's distance to the previous path + calculate_angles(sParTrackPath[sParTrackIndex].pos, sParTrackPath[sParTrackIndex - 1].pos, &prevPitch, &prevYaw); + vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex].pos, prevPathPos, 700.f, prevPitch, prevYaw); + distToNext = calc_abs_dist(marioPos, prevPathPos); + if (distToPrev > distToNext) { + sParTrackIndex--; + sStatusFlags |= CAM_FLAG_CHANGED_PARTRACK_INDEX; } } - vec3f_copy(focus, sp78); - vec3f_get_dist_and_angle(focus, pos, &spA4, &spB6, &spB4); - - return spB4; + // Update the camera focus and return the camera's yaw + vec3f_copy(focus, marioPos); + vec3f_get_dist_and_angle(focus, pos, &camParDist, &pathPitch, &pathYaw); + return pathYaw; } -s32 return_fixed_camera_yaw(struct LevelCamera *c, Vec3f focus, UNUSED Vec3f pos) { - f32 heightAboveFloor; +/** + * Updates the camera during fixed mode. + */ +s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) { + f32 focusFloorOff; f32 goalHeight; f32 ceilHeight; f32 heightOffset; @@ -1006,6 +1391,7 @@ s32 return_fixed_camera_yaw(struct LevelCamera *c, Vec3f focus, UNUSED Vec3f pos play_camera_buzz_if_c_sideways(); + // Don't move closer to mario in these areas switch (gCurrLevelArea) { case AREA_RR: scaleToMario = 0.f; @@ -1026,20 +1412,20 @@ s32 return_fixed_camera_yaw(struct LevelCamera *c, Vec3f focus, UNUSED Vec3f pos handle_c_button_movement(c); play_camera_buzz_if_cdown(); - return_height_above_floor(&heightAboveFloor, 1.f, 200.f, &heightAboveFloor, 0.9f, 200.f); - vec3f_copy(focus, sMarioStatusForCamera->pos); - focus[1] += heightAboveFloor + 125.f; + calc_y_to_curr_floor(&focusFloorOff, 1.f, 200.f, &focusFloorOff, 0.9f, 200.f); + vec3f_copy(focus, sMarioCamState->pos); + focus[1] += focusFloorOff + 125.f; vec3f_get_dist_and_angle(focus, c->pos, &distCamToFocus, &faceAngle[0], &faceAngle[1]); faceAngle[2] = 0; - vec3f_copy(basePos, sFixedPresetBasePosition); - vec3f_add(basePos, sFixedPresetBasePositionOffset); + vec3f_copy(basePos, sFixedModeBasePosition); + vec3f_add(basePos, sCastleEntranceOffset); - if (sGeometryForMario.currFloorType != SURFACE_DEATH_PLANE - && sGeometryForMario.currFloorHeight != -11000.f) { - goalHeight = sGeometryForMario.currFloorHeight + basePos[1] + heightOffset; + if (sMarioGeometry.currFloorType != SURFACE_DEATH_PLANE + && sMarioGeometry.currFloorHeight != -11000.f) { + goalHeight = sMarioGeometry.currFloorHeight + basePos[1] + heightOffset; } else { - goalHeight = gCameraStatus.camFocAndPosCurrAndGoal[3][1]; + goalHeight = gLakituState.goalPos[1]; } if (300 > distCamToFocus) { @@ -1053,17 +1439,17 @@ s32 return_fixed_camera_yaw(struct LevelCamera *c, Vec3f focus, UNUSED Vec3f pos } } - if (gCameraFlags2 & CAM_FLAG_2_SMOOTH_MOVEMENT) { + if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { camera_approach_f32_symmetric_bool(&c->pos[1], goalHeight, 15.f); } else { - if (goalHeight < sMarioStatusForCamera->pos[1] - 500.f) { - goalHeight = sMarioStatusForCamera->pos[1] - 500.f; + if (goalHeight < sMarioCamState->pos[1] - 500.f) { + goalHeight = sMarioCamState->pos[1] - 500.f; } c->pos[1] = goalHeight; } - c->pos[0] = basePos[0] + (sMarioStatusForCamera->pos[0] - basePos[0]) * scaleToMario; - c->pos[2] = basePos[2] + (sMarioStatusForCamera->pos[2] - basePos[2]) * scaleToMario; + c->pos[0] = basePos[0] + (sMarioCamState->pos[0] - basePos[0]) * scaleToMario; + c->pos[2] = basePos[2] + (sMarioCamState->pos[2] - basePos[2]) * scaleToMario; if (scaleToMario != 0.f) { vec3f_get_dist_and_angle(c->focus, c->pos, &distCamToFocus, &pitch, &yaw); @@ -1076,47 +1462,55 @@ s32 return_fixed_camera_yaw(struct LevelCamera *c, Vec3f focus, UNUSED Vec3f pos return faceAngle[1]; } -s32 return_boss_fight_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { +/** + * Updates the camera during a boss fight + */ +s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { struct Object *o; UNUSED u8 filler2[12]; f32 focusDistance; UNUSED u8 filler3[4]; + // Floor normal values f32 nx; f32 ny; f32 nz; + /// Floor originOffset f32 oo; UNUSED u8 filler4[4]; - UNUSED s16 sp62; + UNUSED s16 unused; s16 yaw; s16 heldState; struct Surface *floor; UNUSED u8 filler[20]; Vec3f secondFocus; - Vec3f sp2C = { 0.f, -150.f, -125.f }; + Vec3f holdFocOffset = { 0.f, -150.f, -125.f }; handle_c_button_movement(c); - if (sMarioStatusForCamera->unk1C[1] == 7) { - set_camera_shake_2(SHAKE_2_UNKNOWN_3); - sMarioStatusForCamera->unk1C[1] = 0; + // Start camera shakes if bowser jumps or gets thrown. + if (sMarioCamState->cameraEvent == CAM_EVENT_BOWSER_JUMP) { + set_environmental_camera_shake(SHAKE_ENV_BOWSER_JUMP); + sMarioCamState->cameraEvent = 0; } - if (sMarioStatusForCamera->unk1C[1] == 8) { - set_camera_shake_2(SHAKE_2_UNKNOWN_2); - sMarioStatusForCamera->unk1C[1] = 0; + if (sMarioCamState->cameraEvent == CAM_EVENT_BOWSER_THROW_BOUNCE) { + set_environmental_camera_shake(SHAKE_ENV_BOWSER_THROW_BOUNCE); + sMarioCamState->cameraEvent = 0; } - yaw = sFirstPersonCameraYaw + 0x2000; + yaw = sModeOffsetYaw + DEGREES(45); + // Get boss's position and whether mario is holding it. if ((o = gSecondCameraFocus) != NULL) { object_pos_to_vec3f(secondFocus, o); heldState = o->oHeldState; } else { - secondFocus[0] = c->xFocus; - secondFocus[1] = sMarioStatusForCamera->pos[1]; - secondFocus[2] = c->zFocus; + // If no boss is there, just rotate around the area's center point. + secondFocus[0] = c->areaCenX; + secondFocus[1] = sMarioCamState->pos[1]; + secondFocus[2] = c->areaCenZ; heldState = 0; } - focusDistance = calc_abs_dist(sMarioStatusForCamera->pos, secondFocus) * 1.6f; + focusDistance = calc_abs_dist(sMarioCamState->pos, secondFocus) * 1.6f; if (focusDistance < 800.f) { focusDistance = 800.f; } @@ -1124,17 +1518,21 @@ s32 return_boss_fight_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) focusDistance = 5000.f; } + // If holding the boss, add a slight offset to secondFocus so that the spinning is more pronounced. if (heldState == 1) { - set_pos_from_face_angle_and_vec3f(secondFocus, sMarioStatusForCamera->pos, sp2C, - sMarioStatusForCamera->faceAngle); + offset_rotated(secondFocus, sMarioCamState->pos, holdFocOffset, sMarioCamState->faceAngle); } - focus[0] = (sMarioStatusForCamera->pos[0] + secondFocus[0]) / 2.f; - focus[1] = (sMarioStatusForCamera->pos[1] + secondFocus[1]) / 2.f + 125.f; - focus[2] = (sMarioStatusForCamera->pos[2] + secondFocus[2]) / 2.f; + // Set the camera focus to the average of mario and secondFocus + focus[0] = (sMarioCamState->pos[0] + secondFocus[0]) / 2.f; + focus[1] = (sMarioCamState->pos[1] + secondFocus[1]) / 2.f + 125.f; + focus[2] = (sMarioCamState->pos[2] + secondFocus[2]) / 2.f; + // Calculate the camera's position as an offset from the focus + // When C-Down is not active, this vec3f_set_dist_and_angle(focus, pos, focusDistance, 0x1000, yaw); - pos[1] = find_floor(c->xFocus, 20000.f, c->zFocus, &floor); + // Find the floor of the arena + pos[1] = find_floor(c->areaCenX, 20000.f, c->areaCenZ, &floor); if (floor != NULL) { nx = floor->normal.x; ny = floor->normal.y; @@ -1144,229 +1542,302 @@ s32 return_boss_fight_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) switch (gCurrLevelArea) { case AREA_BOB: pos[1] += 125.f; - // fall through + //! fall through, makes the BoB boss fight camera move up twice as high as it should case AREA_WF: pos[1] += 125.f; } } + // Prevent the camera from going to the ground in the outside boss fight if (gCurrLevelNum == LEVEL_BBH) { pos[1] = 2047.f; } + // Rotate from C-Button input if (sCSideButtonYaw < 0) { - sFirstPersonCameraYaw += 0x200; + sModeOffsetYaw += 0x200; if ((sCSideButtonYaw += 0x100) > 0) { sCSideButtonYaw = 0; } } if (sCSideButtonYaw > 0) { - sFirstPersonCameraYaw -= 0x200; + sModeOffsetYaw -= 0x200; if ((sCSideButtonYaw -= 0x100) < 0) { sCSideButtonYaw = 0; } } - focus[1] = (sMarioStatusForCamera->pos[1] + secondFocus[1]) / 2.f + 100.f; + focus[1] = (sMarioCamState->pos[1] + secondFocus[1]) / 2.f + 100.f; if (heldState == 1) { - focus[1] += 300.f - * sins((gMarioStates[0].angleVel[1] > 0.f) ? gMarioStates[0].angleVel[1] - : -gMarioStates[0].angleVel[1]); + focus[1] += 300.f * sins((gMarioStates[0].angleVel[1] > 0.f) ? gMarioStates[0].angleVel[1] + : -gMarioStates[0].angleVel[1]); } + //! Unnecessary conditional, focusDistance is already bounded to 800 if (focusDistance < 400.f) { focusDistance = 400.f; } - func_80280BD8(focusDistance, 6144); - vec3f_set_dist_and_angle(pos, pos, D_8033B3EE, D_8033B3F0 + 0x1000, yaw); + + // Set C-Down distance and pitch. + // C-Down will essentially double the distance from the center. + // sLakituPitch approaches 33.75 degrees. + lakitu_zoom(focusDistance, 0x1800); + + // Move the camera position back as sLakituDist and sLakituPitch increase. + // This doesn't zoom out of bounds because pos is set above each frame. + // The constant 0x1000 doubles the pitch from the center when sLakituPitch is 0 + // When lakitu is fully zoomed out, the pitch comes to 0x3800, or 78.75 degrees, up from the focus. + vec3f_set_dist_and_angle(pos, pos, sLakituDist, sLakituPitch + 0x1000, yaw); return yaw; } // 2nd iteration of data -s16 unused_8032D0A8[] = { 14, 1, 2, 4 }; -s16 unused_8032D0B0[] = { 16, 9, 17, 0 }; -u8 D_8032D0B8[] = { 0xA5, 0x8F, 0xA6, 0xA7, 0xAF, 0, 0, 0, 0, 1, 0, 0, 0xC5, 0x3D, - 0x20, 0, 0x44, 0x64, 0, 0, 0xC5, 6, 0x40, 0, 0x44, 0x16, 0, 0, - 0x3E, 0x99, 0x99, 0x9A, 0, 0, 0, 0, 0xC5, 0x92, 0x20, 0, 0x44, 0x65, - 0x40, 0, 0xC5, 0x6D, 0xA0, 0, 0x44, 0x16, 0, 0, 0x3E, 0x99, 0x99, 0x9A }; +s16 unused8032D0A8[] = { 14, 1, 2, 4 }; +s16 unused8032D0B0[] = { 16, 9, 17, 0 }; + +/** + * Maps cutscene to numbers in [0,4]. Used in determine_dance_cutscene() with sDanceCutsceneIndexTable. + * + * Only the first 5 entries are used. Perhaps the last 5 were bools used to indicate whether the star + * type exits the course or not. + */ +u8 sDanceCutsceneTable[] = { + CUTSCENE_DANCE_FLY_AWAY, CUTSCENE_DANCE_ROTATE, CUTSCENE_DANCE_CLOSEUP, CUTSCENE_KEY_DANCE, CUTSCENE_DANCE_DEFAULT, + FALSE, FALSE, FALSE, FALSE, TRUE, +}; + +/** + * Perhaps used by different dance cutscenes. + */ +struct UnusedDanceInfo { + Vec3f point; + f32 distTarget; + f32 distMultiplier; +}; + +struct UnusedDanceInfo unusedDanceInfo1 = { + {-3026.0f, 912.0f, -2148.0f}, + 600.0f, + 0.3f +}; + +u32 unusedDanceType = 0; +struct UnusedDanceInfo unusedDanceInfo2 = { + {-4676.0f, 917.0f, -3802.0f}, + 600.0f, + 0.3f +}; + /** * Table that dictates camera movement in bookend room. - * Due to only the X being varied in the, this only moves along the X axis linearly. + * Due to only the X being varied in the table, this only moves along the X axis linearly. * Third entry is seemingly unused. */ -struct ParallelTrackingTable BBHRoom6ParallelTrackingTable[3] = { +struct ParallelTrackingPoint sBBHLibraryParTrackPath[] = { { 1, { -929.0f, 1619.0f, -1490.0f }, 50.0f, 0.0f }, { 0, { -2118.0f, 1619.0f, -1490.0f }, 50.0f, 0.0f }, { 0, { 0.0f, 0.0f, 0.0f }, 0.0f, 0.0f }, }; -s32 unused_return_mode_5_camera_yaw(UNUSED struct LevelCamera *c, UNUSED Vec3f focus, - UNUSED Vec3f pos) { +s32 unused_update_mode_5_camera(UNUSED struct Camera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { } void unused_80282678(UNUSED s32 unused) { } -void update_boss_fight_camera(struct LevelCamera *c) { - c->storedYaw = return_boss_fight_camera_yaw(c, c->focus, c->pos); +void mode_boss_fight_camera(struct Camera *c) { + c->nextYaw = update_boss_fight_camera(c, c->focus, c->pos); } -void update_parallel_tracking_camera(struct LevelCamera *c) { +/** + * Parallel tracking mode, the camera faces perpendicular to a line defined by sParTrackPath + * + * @see update_parallel_tracking_camera + */ +void mode_parallel_tracking_camera(struct Camera *c) { s16 dummy; - func_8028B3DC(c, 0.f); - set_fov_function(2); - c->storedYaw = return_parallel_tracking_camera_yaw(c, c->focus, c->pos); + radial_camera_input(c, 0.f); + set_fov_function(CAM_FOV_DEFAULT); + c->nextYaw = update_parallel_tracking_camera(c, c->focus, c->pos); camera_approach_s16_symmetric_bool(&dummy, 0, 0x0400); } -void update_fixed_camera(struct LevelCamera *c) { +/** + * Fixed camera mode, the camera rotates around a point and looks and zooms toward mario. + */ +void mode_fixed_camera(struct Camera *c) { UNUSED u8 unused[8]; if (gCurrLevelNum == LEVEL_BBH) { - set_fov_function(7); + set_fov_function(CAM_FOV_BBH); } else { - set_fov_function(4); + set_fov_function(CAM_FOV_APP_45); } - c->storedYaw = return_fixed_camera_yaw(c, c->focus, c->pos); - c->trueYaw = c->storedYaw; - func_8027FF44(c); - vec3f_set(sFixedPresetBasePositionOffset, 0.f, 0.f, 0.f); + c->nextYaw = update_fixed_camera(c, c->focus, c->pos); + c->yaw = c->nextYaw; + pan_ahead_of_player(c); + vec3f_set(sCastleEntranceOffset, 0.f, 0.f, 0.f); } -s32 return_behind_mario_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { +/** + * Updates the camera in BEHIND_MARIO mode. + * + * The C-Buttons rotate the camera 90 degrees left/right and 67.5 degrees up/down. + */ +s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) { UNUSED u8 unused2[12]; - f32 sp48; + f32 dist; UNUSED u8 unused3[4]; - s16 sp42; - s16 sp40; + s16 absPitch; + s16 pitch; s16 yaw; - s16 sp3C = -sMarioStatusForCamera->faceAngle[0]; - s16 sp3A = sMarioStatusForCamera->faceAngle[1] + 32768; - s16 sp38 = 0; - s16 sp36; - s16 sp34 = 32; + s16 goalPitch = -sMarioCamState->faceAngle[0]; + s16 marioYaw = sMarioCamState->faceAngle[1] + DEGREES(180); + s16 goalYawOff = 0; + s16 yawSpeed; + s16 pitchInc = 32; UNUSED u8 unused[12]; - f32 sp24 = 800.f; - f32 sp20 = 125.f; + f32 maxDist = 800.f; + f32 focYOff = 125.f; - if (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE) { - sp24 = 350.f; - sp20 = 120.f; + // Zoom in when mario R_TRIG mode is active + if (sSelectionFlags & CAM_MODE_MARIO_ACTIVE) { + maxDist = 350.f; + focYOff = 120.f; } - if (!(sMarioStatusForCamera->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) { - sp34 = 128; + if (!(sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) { + pitchInc = 128; } - vec3f_copy(focus, sMarioStatusForCamera->pos); - c->focus[1] += sp20; - sp48 = calc_abs_dist(focus, pos); - sp40 = calculate_verticle_angle(focus, pos); - vec3f_get_dist_and_angle(focus, pos, &sp48, &sp40, &yaw); - if (sp48 > sp24) { - sp48 = sp24; + + // Focus on mario + vec3f_copy(focus, sMarioCamState->pos); + c->focus[1] += focYOff; + //! @bug unnecessary + dist = calc_abs_dist(focus, pos); + //! @bug unnecessary + pitch = calculate_pitch(focus, pos); + vec3f_get_dist_and_angle(focus, pos, &dist, &pitch, &yaw); + if (dist > maxDist) { + dist = maxDist; } - if ((sp42 = sp40) < 0) { - sp42 = -sp42; + if ((absPitch = pitch) < 0) { + absPitch = -absPitch; } - sp36 = 32 - sp42 / 0x200; - if (sp36 < 1) { - sp36 = 1; + + // Determine the yaw speed based on absPitch. A higher absPitch (further away from looking straight) + // translates to a slower speed + // Note: Pitch is always within +- 90 degrees or +-0x4000, and 0x4000 / 0x200 = 32 + yawSpeed = 32 - absPitch / 0x200; + if (yawSpeed < 1) { + yawSpeed = 1; } - if (sp36 > 32) { - sp36 = 32; + if (yawSpeed > 32) { + yawSpeed = 32; } if (sCSideButtonYaw != 0) { camera_approach_s16_symmetric_bool(&sCSideButtonYaw, 0, 1); - sp36 = 8; + yawSpeed = 8; } - if (D_8033B3FA != 0) { - sp3C = 0; - camera_approach_s16_symmetric_bool(&D_8033B3FA, 0, 1); - sp34 = 2048; + if (sBehindMarioSoundTimer != 0) { + goalPitch = 0; + camera_approach_s16_symmetric_bool(&sBehindMarioSoundTimer, 0, 1); + pitchInc = 0x800; } - if (D_8033B3FA == 28) { + if (sBehindMarioSoundTimer == 28) { if (sCSideButtonYaw < 5 || sCSideButtonYaw > 28) { play_sound_cbutton_up(); } } if (sCSideButtonYaw == 28) { - if (D_8033B3FA < 5 || D_8033B3FA > 28) { + if (sBehindMarioSoundTimer < 5 || sBehindMarioSoundTimer > 28) { play_sound_cbutton_up(); } } - if (gCButtonsPressed & 2) { + // C-Button input. Note: Camera rotates in the opposite direction of the button (airplane controls) + //! @bug C-Right and C-Up take precedence due to the way input is handled here + + // Rotate right + if (sCButtonsPressed & L_CBUTTONS) { if (gPlayer1Controller->buttonPressed & L_CBUTTONS) { play_sound_cbutton_side(); } - if (sp48 < sp24) { - camera_approach_f32_symmetric_bool(&sp48, sp24, 5.f); + if (dist < maxDist) { + camera_approach_f32_symmetric_bool(&dist, maxDist, 5.f); } - sp38 = -16376; + goalYawOff = -0x3FF8; sCSideButtonYaw = 30; - sp36 = 2; + yawSpeed = 2; } - if (gCButtonsPressed & 1) { + // Rotate left + if (sCButtonsPressed & R_CBUTTONS) { if (gPlayer1Controller->buttonPressed & R_CBUTTONS) { play_sound_cbutton_side(); } - if (sp48 < sp24) { - camera_approach_f32_symmetric_bool(&sp48, sp24, 5.f); + if (dist < maxDist) { + camera_approach_f32_symmetric_bool(&dist, maxDist, 5.f); } - sp38 = 16376; + goalYawOff = 0x3FF8; sCSideButtonYaw = 30; - sp36 = 2; + yawSpeed = 2; } - if (gCButtonsPressed & 4) { + // Rotate up + if (sCButtonsPressed & D_CBUTTONS) { if (gPlayer1Controller->buttonPressed & (U_CBUTTONS | D_CBUTTONS)) { play_sound_cbutton_side(); } - if (sp48 < sp24) { - camera_approach_f32_symmetric_bool(&sp48, sp24, 5.f); + if (dist < maxDist) { + camera_approach_f32_symmetric_bool(&dist, maxDist, 5.f); } - sp3C = -12288; - D_8033B3FA = 30; - sp34 = 2048; + goalPitch = -0x3000; + sBehindMarioSoundTimer = 30; + pitchInc = 0x800; } - if (gCButtonsPressed & 8) { + // Rotate down + if (sCButtonsPressed & U_CBUTTONS) { if (gPlayer1Controller->buttonPressed & (U_CBUTTONS | D_CBUTTONS)) { play_sound_cbutton_side(); } - if (sp48 < sp24) { - camera_approach_f32_symmetric_bool(&sp48, sp24, 5.f); + if (dist < maxDist) { + camera_approach_f32_symmetric_bool(&dist, maxDist, 5.f); } - sp3C = 12288; - D_8033B3FA = 30; - sp34 = 2048; + goalPitch = 0x3000; + sBehindMarioSoundTimer = 30; + pitchInc = 0x800; } - approach_s16_exponential_bool(&yaw, sp3A + sp38, sp36); - camera_approach_s16_symmetric_bool(&sp40, sp3C, sp34); - if (sp48 < 300.f) { - sp48 = 300.f; + approach_s16_asymptotic_bool(&yaw, marioYaw + goalYawOff, yawSpeed); + camera_approach_s16_symmetric_bool(&pitch, goalPitch, pitchInc); + if (dist < 300.f) { + dist = 300.f; } - vec3f_set_dist_and_angle(focus, pos, sp48, sp40, yaw); + vec3f_set_dist_and_angle(focus, pos, dist, pitch, yaw); if (gCurrLevelArea == AREA_WDW_MAIN) { - yaw = clamp_positions_and_find_yaw_angle(pos, focus, 4508.f, -3739.f, 4508.f, -3739.f); + yaw = clamp_positions_and_find_yaw(pos, focus, 4508.f, -3739.f, 4508.f, -3739.f); } if (gCurrLevelArea == AREA_THI_HUGE) { - yaw = clamp_positions_and_find_yaw_angle(pos, focus, 8192.f, -8192.f, 8192.f, -8192.f); + yaw = clamp_positions_and_find_yaw(pos, focus, 8192.f, -8192.f, 8192.f, -8192.f); } if (gCurrLevelArea == AREA_THI_TINY) { - yaw = clamp_positions_and_find_yaw_angle(pos, focus, 2458.f, -2458.f, 2458.f, -2458.f); + yaw = clamp_positions_and_find_yaw(pos, focus, 2458.f, -2458.f, 2458.f, -2458.f); } return yaw; } -s32 return_behind_mario_water_camera_yaw(struct LevelCamera *c) { +/** + * "Behind Mario" mode: used when mario is flying, on the water's surface, or shot from a cannon + */ +s32 mode_behind_mario(struct Camera *c) { struct MarioState *marioState = &gMarioStates[0]; struct Surface *floor; Vec3f newPos; + //! @bug oldPos is unused, see resolve_geometry_collisions Vec3f oldPos; f32 waterHeight; f32 floorHeight; @@ -1376,12 +1847,14 @@ s32 return_behind_mario_water_camera_yaw(struct LevelCamera *c) { s16 yaw; vec3f_copy(oldPos, c->pos); - gCameraMovementFlags &= ~CAM_MOVE_INTO_C_UP; + gCameraMovementFlags &= ~CAM_MOVING_INTO_MODE; vec3f_copy(newPos, c->pos); - yaw = return_behind_mario_camera_yaw(c, c->focus, newPos); + yaw = update_behind_mario_camera(c, c->focus, newPos); c->pos[0] = newPos[0]; c->pos[2] = newPos[2]; - if (c->currPreset == CAMERA_PRESET_WATER_SURFACE) { + + // Keep the camera above the water surface if swimming + if (c->mode == CAMERA_MODE_WATER_SURFACE) { floorHeight = find_floor(c->pos[0], c->pos[1], c->pos[2], &floor); newPos[1] = marioState->waterLevel + 120; if (newPos[1] < (floorHeight += 120.f)) { @@ -1395,72 +1868,92 @@ s32 return_behind_mario_water_camera_yaw(struct LevelCamera *c) { } else { gCameraMovementFlags &= ~CAM_MOVE_SUBMERGED; } + resolve_geometry_collisions(c->pos, oldPos); + // Prevent camera getting too far away vec3f_get_dist_and_angle(c->focus, c->pos, &distCamToFocus, &camPitch, &camYaw); if (distCamToFocus > 800.f) { distCamToFocus = 800.f; vec3f_set_dist_and_angle(c->focus, c->pos, distCamToFocus, camPitch, camYaw); } - func_8027FF44(c); + pan_ahead_of_player(c); return yaw; } -s16 return_slide_camera_yaw(struct LevelCamera *c) { +/** + * Update the camera in slide and hoot mode. + * + * In slide mode, keep the camera 800 units from mario + */ +s16 update_slide_camera(struct Camera *c) { struct Surface *floor; f32 floorHeight; Vec3f pos; f32 distCamToFocus; - f32 distToFocusOffset; + f32 maxCamDist; f32 pitchScale; s16 camPitch; s16 camYaw; UNUSED struct MarioState *marioState = &gMarioStates[0]; s16 goalPitch = 0x1555; - s16 goalYaw = sMarioStatusForCamera->faceAngle[1] + 0x8000; + s16 goalYaw = sMarioCamState->faceAngle[1] + DEGREES(180); - if (gCameraFlags2 & CAM_FLAG_2_CCM_SLIDE_SHORTCUT) { - D_8033B3EE = approach_f32(D_8033B3EE, -600.f, 20.f, 20.f); + // Zoom in when inside the CCM shortcut + if (sStatusFlags & CAM_FLAG_CCM_SLIDE_SHORTCUT) { + sLakituDist = approach_f32(sLakituDist, -600.f, 20.f, 20.f); } else { - D_8033B3EE = approach_f32(D_8033B3EE, 0.f, 20.f, 20.f); + sLakituDist = approach_f32(sLakituDist, 0.f, 20.f, 20.f); } + // No C-Button input in this mode, notify the player with a buzzer play_camera_buzz_if_cbutton(); - vec3f_copy(c->focus, sMarioStatusForCamera->pos); + + // Focus on mario + vec3f_copy(c->focus, sMarioCamState->pos); c->focus[1] += 50.f; + vec3f_get_dist_and_angle(c->focus, c->pos, &distCamToFocus, &camPitch, &camYaw); - distToFocusOffset = 800.f; - if (sMarioStatusForCamera->action == ACT_RIDING_HOOT) { - distToFocusOffset = 1000.f; + maxCamDist = 800.f; + + // In hoot mode, zoom further out and rotate faster + if (sMarioCamState->action == ACT_RIDING_HOOT) { + maxCamDist = 1000.f; goalPitch = 0x2800; - camera_approach_s16_symmetric_bool(&camYaw, goalYaw, 0x0100); + camera_approach_s16_symmetric_bool(&camYaw, goalYaw, 0x100); } else { camera_approach_s16_symmetric_bool(&camYaw, goalYaw, 0x80); } - camera_approach_s16_symmetric_bool(&camPitch, goalPitch, 0x0100); - if (sMarioStatusForCamera->action != ACT_RIDING_HOOT - && sGeometryForMario.currFloorType == SURFACE_DEATH_PLANE) { - vec3f_set_dist_and_angle(c->focus, pos, distToFocusOffset + D_8033B3EE, camPitch, camYaw); + camera_approach_s16_symmetric_bool(&camPitch, goalPitch, 0x100); + + // Hoot mode + if (sMarioCamState->action != ACT_RIDING_HOOT && sMarioGeometry.currFloorType == SURFACE_DEATH_PLANE) { + vec3f_set_dist_and_angle(c->focus, pos, maxCamDist + sLakituDist, camPitch, camYaw); c->pos[0] = pos[0]; c->pos[2] = pos[2]; camera_approach_f32_symmetric_bool(&c->pos[1], c->focus[1], 30.f); vec3f_get_dist_and_angle(c->pos, c->focus, &distCamToFocus, &camPitch, &camYaw); - pitchScale = (distCamToFocus - distToFocusOffset + D_8033B3EE) / 10000.f; + pitchScale = (distCamToFocus - maxCamDist + sLakituDist) / 10000.f; if (pitchScale > 1.f) { pitchScale = 1.f; } - camPitch += 4096.f * pitchScale; + camPitch += 0x1000 * pitchScale; vec3f_set_dist_and_angle(c->pos, c->focus, distCamToFocus, camPitch, camYaw); + + // Slide mode } else { - vec3f_set_dist_and_angle(c->focus, c->pos, distToFocusOffset + D_8033B3EE, camPitch, camYaw); - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_1; + vec3f_set_dist_and_angle(c->focus, c->pos, maxCamDist + sLakituDist, camPitch, camYaw); + sStatusFlags |= CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; + + // Stay above the slide floor floorHeight = find_floor(c->pos[0], c->pos[1] + 200.f, c->pos[2], &floor) + 125.f; if (c->pos[1] < floorHeight) { c->pos[1] = floorHeight; } + // Stay closer than maxCamDist vec3f_get_dist_and_angle(c->focus, c->pos, &distCamToFocus, &camPitch, &camYaw); - if (distCamToFocus > distToFocusOffset + D_8033B3EE) { - distCamToFocus = distToFocusOffset + D_8033B3EE; + if (distCamToFocus > maxCamDist + sLakituDist) { + distCamToFocus = maxCamDist + sLakituDist; vec3f_set_dist_and_angle(c->focus, c->pos, distCamToFocus, camPitch, camYaw); } } @@ -1469,67 +1962,79 @@ s16 return_slide_camera_yaw(struct LevelCamera *c) { return camYaw; } -void update_behind_mario_camera(struct LevelCamera *c) { - c->storedYaw = return_behind_mario_water_camera_yaw(c); +void mode_behind_mario_camera(struct Camera *c) { + c->nextYaw = mode_behind_mario(c); } -s32 nop_return_water_camera_yaw(UNUSED struct LevelCamera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { +s32 nop_update_water_camera(UNUSED struct Camera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { } -void update_water_surface_camera(struct LevelCamera *c) { - c->storedYaw = return_behind_mario_water_camera_yaw(c); +/** + * Exactly the same as BEHIND_MARIO + */ +void mode_water_surface_camera(struct Camera *c) { + c->nextYaw = mode_behind_mario(c); } -s32 return_mario_yaw(UNUSED struct LevelCamera *c, Vec3f focus, Vec3f pos) { - s16 yaw = sMarioStatusForCamera->faceAngle[1] + sFirstPersonCameraYaw + 0x8000; - set_cam_focus_and_pos_rel_mario(focus, pos, 125.f, 125.f, gCameraZoomDist, 0x05B0, yaw); +/** + * Used in sModeTransitions for CLOSE and FREE_ROAM mode + */ +s32 update_mario_camera(UNUSED struct Camera *c, Vec3f focus, Vec3f pos) { + s16 yaw = sMarioCamState->faceAngle[1] + sModeOffsetYaw + DEGREES(180); + focus_on_mario(focus, pos, 125.f, 125.f, gCameraZoomDist, 0x05B0, yaw); - return sMarioStatusForCamera->faceAngle[1]; + return sMarioCamState->faceAngle[1]; } -extern f32 unused_80336070; -s16 return_close_or_free_roam_cam_yaw(struct LevelCamera *c) { - Vec3f spBC; - Vec3f spB0; +/** + * Update the camera in default, close, and free roam mode + * + * The camera moves behind mario, and can rotate all the way around + */ +s16 update_default_camera(struct Camera *c) { + Vec3f tempPos; + Vec3f cPos; UNUSED u8 unused1[12]; struct Surface *marioFloor; - struct Surface *sp9C; - struct Surface *sp98; + struct Surface *cFloor; + struct Surface *tempFloor; struct Surface *ceil; - f32 sp90; - f32 sp8C; - f32 sp88; + f32 camFloorHeight; + f32 tempFloorHeight; + f32 marioFloorHeight; UNUSED u8 unused2[4]; - f32 distFocusToCam; + f32 dist; f32 zoomDist; - f32 sp78; - f32 sp74; - s16 sp72; - s16 sp70; + f32 waterHeight; + f32 gasHeight; + s16 avoidYaw; + s16 pitch; s16 yaw; - s16 sp6C = sMarioStatusForCamera->faceAngle[1] + 32768; - f32 sp68; - f32 sp64; - f32 sp60; - s16 sp5E; - s16 sp5C; - f32 sp58; + s16 yawGoal = sMarioCamState->faceAngle[1] + DEGREES(180); + f32 posHeight; + f32 focHeight; + f32 distFromWater; + s16 tempPitch; + s16 tempYaw; + f32 xzDist; UNUSED u8 unused4[4]; - s16 sp52; - s16 sp50 = 0; - f32 sp4C; - s32 sp48 = 0; - s32 sp44 = 0; - f32 ceilHeight = find_ceil(gCameraStatus.camFocAndPosCurrAndGoal[3][0], - gCameraStatus.camFocAndPosCurrAndGoal[3][1], - gCameraStatus.camFocAndPosCurrAndGoal[3][2], &ceil); - s16 sp3E; + s16 nextYawVel; + s16 yawVel = 0; + f32 scale; + s32 avoidStatus = 0; + s32 closeToMario = 0; + f32 ceilHeight = find_ceil(gLakituState.goalPos[0], + gLakituState.goalPos[1], + gLakituState.goalPos[2], &ceil); + s16 yawDir; handle_c_button_movement(c); - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &distFocusToCam, &sp70, &yaw); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + // If C-Down is active, determine what distance the camera should be from mario if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - if (test_or_set_mario_cam_active(0) == CAM_ANGLE_LAKITU_MARIO) { + //! In Mario mode, the camera is zoomed out further than in lakitu mode (1400 vs 1200) + if (set_cam_angle(0) == CAM_ANGLE_MARIO) { zoomDist = gCameraZoomDist + 1050; } else { zoomDist = gCameraZoomDist + 400; @@ -1538,41 +2043,44 @@ s16 return_close_or_free_roam_cam_yaw(struct LevelCamera *c) { zoomDist = gCameraZoomDist; } - if ((sMarioStatusForCamera->action & ACT_FLAG_HANGING) - || sMarioStatusForCamera->action == ACT_RIDING_HOOT) { + if (sMarioCamState->action & ACT_FLAG_HANGING || + sMarioCamState->action == ACT_RIDING_HOOT) { zoomDist *= 0.8f; - set_spline_values(3); + set_handheld_shake(HAND_CAM_SHAKE_HANG_OWL); } - if (D_8033B3F4 == 0.f) { - if (distFocusToCam > zoomDist) { - if ((distFocusToCam -= 50.f) < zoomDist) { - distFocusToCam = zoomDist; + // If not zooming out, only allow dist to decrease + if (sZoomAmount == 0.f) { + if (dist > zoomDist) { + if ((dist -= 50.f) < zoomDist) { + dist = zoomDist; } } } else { - if ((D_8033B3F4 -= 30.f) < 0.f) { - D_8033B3F4 = 0.f; + if ((sZoomAmount -= 30.f) < 0.f) { + sZoomAmount = 0.f; } - if (distFocusToCam > zoomDist) { - if ((distFocusToCam -= 30.f) < zoomDist) { - distFocusToCam = zoomDist; + if (dist > zoomDist) { + if ((dist -= 30.f) < zoomDist) { + dist = zoomDist; } } - if (distFocusToCam < zoomDist) { - if ((distFocusToCam += 30.f) > zoomDist) { - distFocusToCam = zoomDist; + if (dist < zoomDist) { + if ((dist += 30.f) > zoomDist) { + dist = zoomDist; } } } + + // Determine how fast to rotate the camera if (sCSideButtonYaw == 0) { - if (c->currPreset == CAMERA_PRESET_FREE_ROAM) { - sp52 = 192; + if (c->mode == CAMERA_MODE_FREE_ROAM) { + nextYawVel = 0xC0; } else { - sp52 = 256; + nextYawVel = 0x100; } if ((gPlayer1Controller->stickX != 0.f || gPlayer1Controller->stickY != 0.f) != 0) { - sp52 = 32; + nextYawVel = 0x20; } } else { if (sCSideButtonYaw < 0) { @@ -1581,1152 +2089,1387 @@ s16 return_close_or_free_roam_cam_yaw(struct LevelCamera *c) { if (sCSideButtonYaw > 0) { yaw -= 0x200; } - camera_approach_s16_symmetric_bool(&sCSideButtonYaw, 0, 256); - sp52 = 0; + camera_approach_s16_symmetric_bool(&sCSideButtonYaw, 0, 0x100); + nextYawVel = 0; } - D_8032CFD4 = 1024; - sp58 = calc_hor_dist(sMarioStatusForCamera->pos, c->pos); + sYawSpeed = 0x400; + xzDist = calc_hor_dist(sMarioCamState->pos, c->pos); - if (gCameraFlags2 & CAM_FLAG_2_BEHIND_MARIO_POST_DOOR) { - if (sp58 >= 250) { - gCameraFlags2 &= ~CAM_FLAG_2_BEHIND_MARIO_POST_DOOR; + if (sStatusFlags & CAM_FLAG_BEHIND_MARIO_POST_DOOR) { + if (xzDist >= 250) { + sStatusFlags &= ~CAM_FLAG_BEHIND_MARIO_POST_DOOR; } - if (ABS((sMarioStatusForCamera->faceAngle[1] - yaw) / 2) < 0x1800) { - gCameraFlags2 &= ~CAM_FLAG_2_BEHIND_MARIO_POST_DOOR; - yaw = sCameraYawAfterDoorCutscene + 32768; - distFocusToCam = 800.f; - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_1; + if (ABS((sMarioCamState->faceAngle[1] - yaw) / 2) < 0x1800) { + sStatusFlags &= ~CAM_FLAG_BEHIND_MARIO_POST_DOOR; + yaw = sCameraYawAfterDoorCutscene + DEGREES(180); + dist = 800.f; + sStatusFlags |= CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; } - } else if (sp58 < 250) { - c->pos[0] += (250 - sp58) * sins(yaw); - c->pos[2] += (250 - sp58) * coss(yaw); + } else if (xzDist < 250) { + // Turn rapidly if very close to mario + c->pos[0] += (250 - xzDist) * sins(yaw); + c->pos[2] += (250 - xzDist) * coss(yaw); if (sCSideButtonYaw == 0) { - sp52 = 4096; - D_8032CFD4 = 0; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &distFocusToCam, &sp70, &yaw); + nextYawVel = 0x1000; + sYawSpeed = 0; + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); } - sp44 |= 1; + closeToMario |= 1; } if (-16 < gPlayer1Controller->stickY) { - c->trueYaw = yaw; + c->yaw = yaw; } - return_height_above_floor(&sp68, 1, 200, &sp64, 0.9f, 200); - vec3f_copy(spB0, c->pos); - sp48 = func_8028F2F0(c, spB0, &sp72, 1536); - if (sp48 == 3) { - unused_8033B2AC = sp72; - sCameraYawVelocity = yaw; - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_9; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, spB0, &sp58, &sp5E, &sp5C); - approach_s16_exponential_bool(&yaw, sp72, 10); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, spB0, sp58, sp5E, sp5C); - sCameraYawVelocity = (sCameraYawVelocity - yaw) / 256; + calc_y_to_curr_floor(&posHeight, 1, 200, &focHeight, 0.9f, 200); + vec3f_copy(cPos, c->pos); + avoidStatus = rotate_camera_around_walls(c, cPos, &avoidYaw, 0x600); + // If a wall is blocking the view of mario, then rotate in the calculated direction + if (avoidStatus == 3) { + unusedFreeRoamWallYaw = avoidYaw; + sAvoidYawVel = yaw; + sStatusFlags |= CAM_FLAG_COLLIDED_WITH_WALL; + //! Does nothing + vec3f_get_dist_and_angle(sMarioCamState->pos, cPos, &xzDist, &tempPitch, &tempYaw); + // Rotate to avoid the wall + approach_s16_asymptotic_bool(&yaw, avoidYaw, 10); + //! Does nothing + vec3f_set_dist_and_angle(sMarioCamState->pos, cPos, xzDist, tempPitch, tempYaw); + sAvoidYawVel = (sAvoidYawVel - yaw) / 0x100; } else { if (gMarioStates[0].forwardVel == 0.f) { - if (gCameraFlags2 & CAM_FLAG_2_UNKNOWN_9) { - if ((sp6C - yaw) / 256 >= 0) { - sp3E = -1; + if (sStatusFlags & CAM_FLAG_COLLIDED_WITH_WALL) { + if ((yawGoal - yaw) / 0x100 >= 0) { + yawDir = -1; } else { - sp3E = 1; + yawDir = 1; } - if ((sCameraYawVelocity > 0 && sp3E > 0) || (sCameraYawVelocity < 0 && sp3E < 0)) { - sp50 = sp52; + if ((sAvoidYawVel > 0 && yawDir > 0) || (sAvoidYawVel < 0 && yawDir < 0)) { + yawVel = nextYawVel; } } else { - sp50 = sp52; + yawVel = nextYawVel; } } else { - if (sp52 == 4096) { - sp50 = sp52; + if (nextYawVel == 0x1000) { + yawVel = nextYawVel; } - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_9; + sStatusFlags &= ~CAM_FLAG_COLLIDED_WITH_WALL; } - if (sp48 != 0) { - sp50 += sp50; + + // If a wall is near the camera, turn twice as fast + if (avoidStatus != 0) { + yawVel += yawVel; } - if ((sp44 & 1) && sp48 != 0) { - sp50 = 0; + // ...Unless the camera already rotated from being close to mario + if ((closeToMario & 1) && avoidStatus != 0) { + yawVel = 0; } - if (sp50 != 0 && get_dialog_id() == -1) { - camera_approach_s16_symmetric_bool(&yaw, sp6C, sp50); + if (yawVel != 0 && get_dialog_id() == -1) { + camera_approach_s16_symmetric_bool(&yaw, yawGoal, yawVel); } } - if (sp48 == 0 && !(gCameraFlags2 & CAM_FLAG_2_UNKNOWN_9)) { - approach_f32_exponential_bool(&distFocusToCam, zoomDist - 100.f, 0.05f); - } - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, spB0, distFocusToCam, sp70, yaw); - spB0[1] += sp68 + 125.f; - if (find_and_return_count_wall_collisions(spB0, 10.f, 80.f) != 0) { - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_9; - } - c->focus[0] = sMarioStatusForCamera->pos[0]; - c->focus[1] = sMarioStatusForCamera->pos[1] + 125.f + sp64; - c->focus[2] = sMarioStatusForCamera->pos[2]; - sp88 = 125.f + sGeometryForMario.currFloorHeight; - marioFloor = sGeometryForMario.currFloor; - sp90 = find_floor(spB0[0], spB0[1] + 50.f, spB0[2], &sp9C) + 125.f; - for (sp4C = 0.1f; sp4C < 1.f; sp4C += 0.2f) { - scale_along_line(spBC, spB0, sMarioStatusForCamera->pos, sp4C); - sp8C = find_floor(spBC[0], spBC[1], spBC[2], &sp98) + 125.f; - if (sp98 != NULL && sp8C > sp88) { - sp88 = sp8C; - marioFloor = sp98; - } - } - if (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE) { - sp88 -= 35.f; - sp90 -= 35.f; - c->focus[1] -= 25.f; - } - sp78 = find_water_level(spB0[0], spB0[2]); - if (sp78 != -11000.f) { - sp78 += 125.f; - sp60 = sp78 - sp88; - if (!(gCameraMovementFlags & CAM_MOVE_UNKNOWN_6)) { - if (sp60 > 800.f && (sMarioStatusForCamera->action & ACT_FLAG_METAL_WATER)) { - gCameraMovementFlags |= CAM_MOVE_UNKNOWN_6; - } - } else { - if (sp60 < 400.f || !(sMarioStatusForCamera->action & ACT_FLAG_METAL_WATER)) { - gCameraMovementFlags &= ~CAM_MOVE_UNKNOWN_6; - } - } - if (!(gCameraMovementFlags & CAM_MOVE_UNKNOWN_6) && sp90 < sp78) { - sp90 = sp78; - } - } else { - gCameraMovementFlags &= ~CAM_MOVE_UNKNOWN_6; - } - spB0[1] = sp90; - vec3f_copy(spBC, spB0); - spBC[1] -= 125.f; - if (marioFloor != NULL && sp90 <= sp88) { - sp48 = func_8028A0D4(c->focus, spBC, marioFloor, 0, -1); - if (sp48 != 1 && ceilHeight > sp88) { - sp90 = sp88; + // Only zoom out if not obstructed by walls and lakitu hasn't collided with any + if (avoidStatus == 0 && !(sStatusFlags & CAM_FLAG_COLLIDED_WITH_WALL)) { + approach_f32_asymptotic_bool(&dist, zoomDist - 100.f, 0.05f); + } + vec3f_set_dist_and_angle(sMarioCamState->pos, cPos, dist, pitch, yaw); + cPos[1] += posHeight + 125.f; + + // Move the camera away from walls and set the collision flag + if (collide_with_walls(cPos, 10.f, 80.f) != 0) { + sStatusFlags |= CAM_FLAG_COLLIDED_WITH_WALL; + } + + c->focus[0] = sMarioCamState->pos[0]; + c->focus[1] = sMarioCamState->pos[1] + 125.f + focHeight; + c->focus[2] = sMarioCamState->pos[2]; + + marioFloorHeight = 125.f + sMarioGeometry.currFloorHeight; + marioFloor = sMarioGeometry.currFloor; + camFloorHeight = find_floor(cPos[0], cPos[1] + 50.f, cPos[2], &cFloor) + 125.f; + for (scale = 0.1f; scale < 1.f; scale += 0.2f) { + scale_along_line(tempPos, cPos, sMarioCamState->pos, scale); + tempFloorHeight = find_floor(tempPos[0], tempPos[1], tempPos[2], &tempFloor) + 125.f; + if (tempFloor != NULL && tempFloorHeight > marioFloorHeight) { + marioFloorHeight = tempFloorHeight; + marioFloor = tempFloor; } } - sp68 = 0.f; - if (c->currPreset == CAMERA_PRESET_FREE_ROAM) { - if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - sp68 = 375.f; - if (gCurrLevelArea == AREA_SSL_PYRAMID) { - sp68 /= 2; + + // Lower the camera in mario mode + if (sSelectionFlags & CAM_MODE_MARIO_ACTIVE) { + marioFloorHeight -= 35.f; + camFloorHeight -= 35.f; + c->focus[1] -= 25.f; + } + + // If there's water below the camera, decide whether to keep the camera above the water surface + waterHeight = find_water_level(cPos[0], cPos[2]); + if (waterHeight != -11000.f) { + waterHeight += 125.f; + distFromWater = waterHeight - marioFloorHeight; + if (!(gCameraMovementFlags & CAM_MOVE_METAL_BELOW_WATER)) { + if (distFromWater > 800.f && (sMarioCamState->action & ACT_FLAG_METAL_WATER)) { + gCameraMovementFlags |= CAM_MOVE_METAL_BELOW_WATER; } } else { - sp68 = 100.f; + if (distFromWater < 400.f || !(sMarioCamState->action & ACT_FLAG_METAL_WATER)) { + gCameraMovementFlags &= ~CAM_MOVE_METAL_BELOW_WATER; + } + } + // If not wearing the metal cap, always stay above + if (!(gCameraMovementFlags & CAM_MOVE_METAL_BELOW_WATER) && camFloorHeight < waterHeight) { + camFloorHeight = waterHeight; + } + } else { + gCameraMovementFlags &= ~CAM_MOVE_METAL_BELOW_WATER; + } + + cPos[1] = camFloorHeight; + vec3f_copy(tempPos, cPos); + tempPos[1] -= 125.f; + if (marioFloor != NULL && camFloorHeight <= marioFloorHeight) { + avoidStatus = is_range_behind_surface(c->focus, tempPos, marioFloor, 0, -1); + if (avoidStatus != 1 && ceilHeight > marioFloorHeight) { + camFloorHeight = marioFloorHeight; } } - if ((gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) && (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE)) { - sp68 = 610.f; + + posHeight = 0.f; + if (c->mode == CAMERA_MODE_FREE_ROAM) { + if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { + posHeight = 375.f; + if (gCurrLevelArea == AREA_SSL_PYRAMID) { + posHeight /= 2; + } + } else { + posHeight = 100.f; + } + } + if ((gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) && (sSelectionFlags & CAM_MODE_MARIO_ACTIVE)) { + posHeight = 610.f; if (gCurrLevelArea == AREA_SSL_PYRAMID || gCurrLevelNum == LEVEL_CASTLE) { - sp68 /= 2; + posHeight /= 2; } } - sp74 = find_poison_gas_level(spB0[0], spB0[2]); - if (sp74 != -11000.f) { - if ((sp74 += 130.f) > c->pos[1]) { - c->pos[1] = sp74; + + // Make lakitu fly above the gas + gasHeight = find_poison_gas_level(cPos[0], cPos[2]); + if (gasHeight != -11000.f) { + if ((gasHeight += 130.f) > c->pos[1]) { + c->pos[1] = gasHeight; } } - if ((sMarioStatusForCamera->action & ACT_FLAG_HANGING) - || sMarioStatusForCamera->action == ACT_RIDING_HOOT) { - sp90 = sMarioStatusForCamera->pos[1] + 400.f; - if (c->currPreset == CAMERA_PRESET_FREE_ROAM) { - sp90 -= 100.f; + + if (sMarioCamState->action & ACT_FLAG_HANGING || sMarioCamState->action == ACT_RIDING_HOOT) { + camFloorHeight = sMarioCamState->pos[1] + 400.f; + if (c->mode == CAMERA_MODE_FREE_ROAM) { + camFloorHeight -= 100.f; } ceilHeight = 20000.f; - vec3f_copy(c->focus, sMarioStatusForCamera->pos); + vec3f_copy(c->focus, sMarioCamState->pos); } - if (sMarioStatusForCamera->action & ACT_FLAG_ON_POLE) { - sp90 = gMarioStates[0].usedObj->oPosY + 125.f; - if (sMarioStatusForCamera->pos[1] - 100.f > sp90) { - sp90 = sMarioStatusForCamera->pos[1] - 100.f; + + if (sMarioCamState->action & ACT_FLAG_ON_POLE) { + camFloorHeight = gMarioStates[0].usedObj->oPosY + 125.f; + if (sMarioCamState->pos[1] - 100.f > camFloorHeight) { + camFloorHeight = sMarioCamState->pos[1] - 100.f; } ceilHeight = 20000.f; - vec3f_copy(c->focus, sMarioStatusForCamera->pos); + vec3f_copy(c->focus, sMarioCamState->pos); } - if (sp90 != -11000.f) { - sp90 += sp68; - approach_camera_height(c, sp90, 20.f); + if (camFloorHeight != -11000.f) { + camFloorHeight += posHeight; + approach_camera_height(c, camFloorHeight, 20.f); } - c->pos[0] = spB0[0]; - c->pos[2] = spB0[2]; - spB0[0] = gCameraStatus.camFocAndPosCurrAndGoal[3][0]; - spB0[1] = c->pos[1]; - spB0[2] = gCameraStatus.camFocAndPosCurrAndGoal[3][2]; - vec3f_get_dist_and_angle(spB0, c->pos, &distFocusToCam, &sp5E, &sp5C); - if (distFocusToCam > 50.f) { - distFocusToCam = 50.f; - vec3f_set_dist_and_angle(spB0, c->pos, distFocusToCam, sp5E, sp5C); + c->pos[0] = cPos[0]; + c->pos[2] = cPos[2]; + cPos[0] = gLakituState.goalPos[0]; + cPos[1] = c->pos[1]; + cPos[2] = gLakituState.goalPos[2]; + vec3f_get_dist_and_angle(cPos, c->pos, &dist, &tempPitch, &tempYaw); + // Prevent the camera from lagging behind too much + if (dist > 50.f) { + dist = 50.f; + vec3f_set_dist_and_angle(cPos, c->pos, dist, tempPitch, tempYaw); } - if (sGeometryForMario.currFloorType != SURFACE_DEATH_PLANE) { - vec3f_get_dist_and_angle(c->focus, c->pos, &distFocusToCam, &sp5E, &sp5C); - if (distFocusToCam > zoomDist) { - distFocusToCam = zoomDist; - vec3f_set_dist_and_angle(c->focus, c->pos, distFocusToCam, sp5E, sp5C); + if (sMarioGeometry.currFloorType != SURFACE_DEATH_PLANE) { + vec3f_get_dist_and_angle(c->focus, c->pos, &dist, &tempPitch, &tempYaw); + if (dist > zoomDist) { + dist = zoomDist; + vec3f_set_dist_and_angle(c->focus, c->pos, dist, tempPitch, tempYaw); } } if (ceilHeight != 20000.f) { if (c->pos[1] > (ceilHeight -= 150.f) - && (sp48 = func_8028A0D4(c->pos, sMarioStatusForCamera->pos, ceil, 0, -1)) == 1) { + && (avoidStatus = is_range_behind_surface(c->pos, sMarioCamState->pos, ceil, 0, -1)) == 1) { c->pos[1] = ceilHeight; } } if (gCurrLevelArea == AREA_WDW_TOWN) { - yaw = clamp_positions_and_find_yaw_angle(c->pos, c->focus, 2254.f, -3789.f, 3790.f, -2253.f); + yaw = clamp_positions_and_find_yaw(c->pos, c->focus, 2254.f, -3789.f, 3790.f, -2253.f); } return yaw; } -void update_close_or_free_roam_camera(struct LevelCamera *c) { - set_fov_function(2); - c->storedYaw = return_close_or_free_roam_cam_yaw(c); - func_8027FF44(c); +/** + * The default camera mode + * Used by close and free roam modes + */ +void mode_default_camera(struct Camera *c) { + set_fov_function(CAM_FOV_DEFAULT); + c->nextYaw = update_default_camera(c); + pan_ahead_of_player(c); } -void camera_lakitu_zoom_distance(struct LevelCamera *c) { +/** + * The mode used by close and free roam + */ +void mode_lakitu_camera(struct Camera *c) { gCameraZoomDist = 800.f; - update_close_or_free_roam_camera(c); + mode_default_camera(c); } -void camera_mario_zoom_distance(struct LevelCamera *c) { +/** + * When no other mode is active and the current R button mode is mario + */ +void mode_mario_camera(struct Camera *c) { gCameraZoomDist = 350.f; - update_close_or_free_roam_camera(c); + mode_default_camera(c); } -s32 return_spiral_stairs_camera_yaw(struct LevelCamera *c, Vec3f focus, Vec3f pos) { +/** + * Rotates the camera around the spiral staircase. + */ +s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) { UNUSED s16 unused1; - s16 sp5C; - s16 sp5A; - s16 sp58; - s16 sp56; - s16 sp54; + /// The returned yaw + s16 camYaw; + // unused + s16 focPitch; + /// The focus (mario)'s yaw around the stairs + s16 focYaw; + // unused + s16 posPitch; + /// The camera's yaw around the stairs + s16 posYaw; UNUSED s32 unused2; - Vec3f sp44; - Vec3f sp38; + Vec3f cPos; + Vec3f checkPos; struct Surface *floor; - f32 sp30; - f32 sp2C; - f32 sp28; - f32 sp24; + // unused + f32 dist; + f32 focusHeight; + f32 floorHeight; + f32 focY; handle_c_button_movement(c); - vec3f_set(sFixedPresetBasePosition, -1280.f, 614.f, 1740.f); - return_height_above_floor(&sp2C, 1.f, 200.f, &sp2C, 0.9f, 200.f); - focus[0] = sMarioStatusForCamera->pos[0]; - sp24 = sMarioStatusForCamera->pos[1] + 125.f + sp2C; - focus[2] = sMarioStatusForCamera->pos[2]; - vec3f_copy(sp44, pos); - vec3f_get_dist_and_angle(sFixedPresetBasePosition, focus, &sp30, &sp5A, &sp58); - vec3f_get_dist_and_angle(sFixedPresetBasePosition, sp44, &sp30, &sp56, &sp54); - D_8033B404 = sp54 - sp58; - if (D_8033B404 < -0x4000) { - D_8033B404 = -0x4000; - } - if (D_8033B404 > 0x4000) { - D_8033B404 = 0x4000; - } - sp58 += D_8033B404; - sp54 = sp58; - camera_approach_s16_symmetric_bool(&sp54, sp58, 4096); - vec3f_set_dist_and_angle(sFixedPresetBasePosition, sp44, 300.f, 0, sp54); - sp38[0] = focus[0] + (sp44[0] - focus[0]) * 0.7f; - sp38[1] = focus[1] + (sp44[1] - focus[1]) * 0.7f + 300.f; - sp38[2] = focus[2] + (sp44[2] - focus[2]) * 0.7f; - sp28 = find_floor(sp38[0], sp38[1] + 50.f, sp38[2], &floor); + // Set base pos to the center of the staircase + vec3f_set(sFixedModeBasePosition, -1280.f, 614.f, 1740.f); - if (sp28 != -11000.f) { - if (sp28 < sGeometryForMario.currFloorHeight) { - sp28 = sGeometryForMario.currFloorHeight; + // Focus on mario, and move the focus up the staircase with him + calc_y_to_curr_floor(&focusHeight, 1.f, 200.f, &focusHeight, 0.9f, 200.f); + focus[0] = sMarioCamState->pos[0]; + focY = sMarioCamState->pos[1] + 125.f + focusHeight; + focus[2] = sMarioCamState->pos[2]; + + vec3f_copy(cPos, pos); + vec3f_get_dist_and_angle(sFixedModeBasePosition, focus, &dist, &focPitch, &focYaw); + vec3f_get_dist_and_angle(sFixedModeBasePosition, cPos, &dist, &posPitch, &posYaw); + + sSpiralStairsYawOffset = posYaw - focYaw; + // posYaw will change if mario is more than 90 degrees around the stairs, relative to the camera + if (sSpiralStairsYawOffset < DEGREES(-90)) { + sSpiralStairsYawOffset = DEGREES(-90); + } + if (sSpiralStairsYawOffset > DEGREES(90)) { + sSpiralStairsYawOffset = DEGREES(90); + } + focYaw += sSpiralStairsYawOffset; + posYaw = focYaw; + //! @bug unnecessary + camera_approach_s16_symmetric_bool(&posYaw, focYaw, 0x1000); + + vec3f_set_dist_and_angle(sFixedModeBasePosition, cPos, 300.f, 0, posYaw); + + // Move the camera's y coord up/down the staircase + checkPos[0] = focus[0] + (cPos[0] - focus[0]) * 0.7f; + checkPos[1] = focus[1] + (cPos[1] - focus[1]) * 0.7f + 300.f; + checkPos[2] = focus[2] + (cPos[2] - focus[2]) * 0.7f; + floorHeight = find_floor(checkPos[0], checkPos[1] + 50.f, checkPos[2], &floor); + + if (floorHeight != -11000.f) { + if (floorHeight < sMarioGeometry.currFloorHeight) { + floorHeight = sMarioGeometry.currFloorHeight; } - pos[1] = approach_f32(pos[1], (sp28 += 125.f), 30.f, 30.f); + pos[1] = approach_f32(pos[1], (floorHeight += 125.f), 30.f, 30.f); } - camera_approach_f32_symmetric_bool(&focus[1], sp24, 30.f); - pos[0] = sp44[0]; - pos[2] = sp44[2]; - sp5C = calculate_yaw(focus, pos); + camera_approach_f32_symmetric_bool(&focus[1], focY, 30.f); + pos[0] = cPos[0]; + pos[2] = cPos[2]; + camYaw = calculate_yaw(focus, pos); - return sp5C; + return camYaw; } -void update_spiral_stairs_camera(struct LevelCamera *c) { - c->storedYaw = return_spiral_stairs_camera_yaw(c, c->focus, c->pos); +/** + * The mode used in the spiral staircase in the castle + */ +void mode_spiral_stairs_camera(struct Camera *c) { + c->nextYaw = update_spiral_stairs_camera(c, c->focus, c->pos); } -s32 return_slide_or_0f_camera_yaw(UNUSED struct LevelCamera *c, Vec3f focus, Vec3f pos) { - s16 sp2E = sMarioStatusForCamera->faceAngle[1] + sFirstPersonCameraYaw + 32768; +s32 update_slide_or_0f_camera(UNUSED struct Camera *c, Vec3f focus, Vec3f pos) { + s16 yaw = sMarioCamState->faceAngle[1] + sModeOffsetYaw + DEGREES(180); - set_cam_focus_and_pos_rel_mario(focus, pos, 125.f, 125.f, 800.f, 5461, sp2E); - return sMarioStatusForCamera->faceAngle[1]; + focus_on_mario(focus, pos, 125.f, 125.f, 800.f, 5461, yaw); + return sMarioCamState->faceAngle[1]; } -static void unused_update_mode_0f_camera(struct LevelCamera *c) { +static UNUSED void unused_mode_0f_camera(struct Camera *c) { if (gPlayer1Controller->buttonPressed & U_CBUTTONS) { gCameraMovementFlags |= CAM_MOVE_C_UP_MODE; } - c->storedYaw = return_slide_camera_yaw(c); + c->nextYaw = update_slide_camera(c); } -void update_slide_camera(struct LevelCamera *c) { - if (sGeometryForMario.currFloorType == SURFACE_CLOSE_CAMERA - || sGeometryForMario.currFloorType == SURFACE_NO_CAM_COL_SLIPPERY) { - camera_lakitu_zoom_distance(c); +/** + * Slide/hoot mode. + * In this mode, the camera is always at the back of mario, because mario generally only moves forward. + */ +void mode_slide_camera(struct Camera *c) { + if (sMarioGeometry.currFloorType == SURFACE_CLOSE_CAMERA || + sMarioGeometry.currFloorType == SURFACE_NO_CAM_COL_SLIPPERY) { + mode_lakitu_camera(c); } else { if (gPlayer1Controller->buttonPressed & U_CBUTTONS) { gCameraMovementFlags |= CAM_MOVE_C_UP_MODE; } - c->storedYaw = return_slide_camera_yaw(c); + c->nextYaw = update_slide_camera(c); } } -void func_80284CBC(struct LevelCamera *c) { - vec3f_copy(D_8033B498.pos, c->pos); - vec3f_sub(D_8033B498.pos, sMarioStatusForCamera->pos); - vec3f_set(D_8033B498.focus, 0.f, c->focus[1] - sMarioStatusForCamera->pos[1], 0.f); +void store_lakitu_cam_info_for_c_up(struct Camera *c) { + vec3f_copy(sCameraStoreCUp.pos, c->pos); + vec3f_sub(sCameraStoreCUp.pos, sMarioCamState->pos); + // Only store the y value, and as an offset from mario, for some reason + vec3f_set(sCameraStoreCUp.focus, 0.f, c->focus[1] - sMarioCamState->pos[1], 0.f); } -s32 func_80284D44(struct LevelCamera *c) { +/** + * Start C-Up mode. The actual mode change is handled in update_mario_inputs() in mario.c + * + * @see update_mario_inputs + */ +s32 set_mode_c_up(struct Camera *c) { if (!(gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) { gCameraMovementFlags |= CAM_MOVE_C_UP_MODE; - func_80284CBC(c); - gCameraFlags1 &= ~CAM_FLAG_1_UNKNOWN_0; + store_lakitu_cam_info_for_c_up(c); + sCameraSoundFlags &= ~CAM_SOUND_C_UP_PLAYED; return 1; } return 0; } -s32 exit_c_up_mode(struct LevelCamera *c) { +/** + * Zoom the camera out of C-Up mode, avoiding moving into a wall, if possible, by searching for an open + * direction. + */ +s32 exit_c_up(struct Camera *c) { struct Surface *surface; - Vec3f sp68; - Vec3f sp5C; - s32 sp58 = 0; - s32 i; - f32 sp50; - f32 sp4C; - f32 sp48; - f32 sp44; - s16 sp42; - s16 sp40; - s16 sp3E = 0; - Vec3f sp30; - Vec3f sp24; + Vec3f checkFoc; + Vec3f curPos; + // Variables for searching for an open direction + s32 searching = 0; + /// The current sector of the circle that we are checking + s32 sector; + f32 ceilHeight; + f32 floorHeight; + f32 curDist; + f32 d; + s16 curPitch; + s16 curYaw; + s16 checkYaw = 0; + Vec3f storePos; // unused + Vec3f storeFoc; // unused - if ((gCameraMovementFlags & CAM_MOVE_C_UP_MODE) && !(gCameraMovementFlags & CAM_MOVE_UNKNOWN_10)) { - vec3f_copy(sp30, D_8033B498.pos); - vec3f_add(sp30, sMarioStatusForCamera->pos); - vec3f_copy(sp24, D_8033B498.focus); - vec3f_add(sp24, sMarioStatusForCamera->pos); - vec3f_copy(sp68, c->focus); - sp68[0] = sMarioStatusForCamera->pos[0]; - sp68[2] = sMarioStatusForCamera->pos[2]; - vec3f_get_dist_and_angle(sp68, c->pos, &sp48, &sp42, &sp40); - vec3f_copy(sp5C, c->pos); - sp48 = 80.f; - if (D_8033B418.unk2 == CAMERA_PRESET_SPIRAL_STAIRS || D_8033B418.unk2 == CAMERA_PRESET_CLOSE - || D_8033B418.unk2 == CAMERA_PRESET_FREE_ROAM) { - sp58 = 1; - for (i = 0; i < 16 && sp58 == 1; i++) { - vec3f_set_dist_and_angle(sp68, sp5C, sp48, 0, sp40 + sp3E); - if (f32_find_wall_collision(&sp5C[0], &sp5C[1], &sp5C[2], 20.f, 50.f) == 0) { - for (sp44 = sp48; sp44 < gCameraZoomDist; sp44 += 20.f) { - vec3f_set_dist_and_angle(sp68, sp5C, sp44, 0, sp40 + sp3E); - sp50 = find_ceil(sp5C[0], sp5C[1] - 150.f, sp5C[2], &surface) + -10.f; - if (surface != NULL && sp50 < sp5C[1]) { + if ((gCameraMovementFlags & CAM_MOVE_C_UP_MODE) && !(gCameraMovementFlags & CAM_MOVE_STARTED_EXITING_C_UP)) { + // Copy the stored pos and focus. This is unused. + vec3f_copy(storePos, sCameraStoreCUp.pos); + vec3f_add(storePos, sMarioCamState->pos); + vec3f_copy(storeFoc, sCameraStoreCUp.focus); + vec3f_add(storeFoc, sMarioCamState->pos); + + vec3f_copy(checkFoc, c->focus); + checkFoc[0] = sMarioCamState->pos[0]; + checkFoc[2] = sMarioCamState->pos[2]; + vec3f_get_dist_and_angle(checkFoc, c->pos, &curDist, &curPitch, &curYaw); + vec3f_copy(curPos, c->pos); + curDist = 80.f; + + // Search for an open direction to zoom out in, if the camera is changing to close, free roam, + // or spiral-stairs mode + if (sModeInfo.lastMode == CAMERA_MODE_SPIRAL_STAIRS || sModeInfo.lastMode == CAMERA_MODE_CLOSE + || sModeInfo.lastMode == CAMERA_MODE_FREE_ROAM) { + searching = 1; + // Check the whole circle around mario for an open direction to zoom out to + for (sector = 0; sector < 16 && searching == 1; sector++) { + vec3f_set_dist_and_angle(checkFoc, curPos, curDist, 0, curYaw + checkYaw); + + // If there are no walls this way, + if (f32_find_wall_collision(&curPos[0], &curPos[1], &curPos[2], 20.f, 50.f) == 0) { + + // Start close to mario, check for walls, floors, and ceilings all the way to the + // zoomed out distance + for (d = curDist; d < gCameraZoomDist; d += 20.f) { + vec3f_set_dist_and_angle(checkFoc, curPos, d, 0, curYaw + checkYaw); + + // Check if we're zooming out into a floor or ceiling + ceilHeight = find_ceil(curPos[0], curPos[1] - 150.f, curPos[2], &surface) + -10.f; + if (surface != NULL && ceilHeight < curPos[1]) { break; } - sp4C = find_floor(sp5C[0], sp5C[1] + 150.f, sp5C[2], &surface) + 10.f; - if (surface != NULL && sp4C > sp5C[1]) { + floorHeight = find_floor(curPos[0], curPos[1] + 150.f, curPos[2], &surface) + 10.f; + if (surface != NULL && floorHeight > curPos[1]) { break; } - if (f32_find_wall_collision(&sp5C[0], &sp5C[1], &sp5C[2], 20.f, 50.f) == 1) { + + // Stop checking this direction if there is a wall blocking the way + if (f32_find_wall_collision(&curPos[0], &curPos[1], &curPos[2], 20.f, 50.f) == 1) { break; } } - if (sp44 >= gCameraZoomDist) { - sp58 = 0; + + // If there was no collision found all the way to the max distance, it's an opening + if (d >= gCameraZoomDist) { + searching = 0; } } - if (sp58 == 1) { - sp3E = -sp3E; - if (sp3E < 0) { - sp3E -= 0x1000; + + // Alternate left and right, checking each 1/16th (22.5 degrees) of the circle + if (searching == 1) { + checkYaw = -checkYaw; + if (checkYaw < 0) { + checkYaw -= 0x1000; } else { - sp3E += 0x1000; + checkYaw += 0x1000; } } } - if (sp58 == 0) { - vec3f_set_dist_and_angle(sp68, D_8033B498.pos, gCameraZoomDist, 0, sp40 + sp3E); - vec3f_copy(D_8033B498.focus, sp68); - vec3f_sub(D_8033B498.pos, sMarioStatusForCamera->pos); - vec3f_sub(D_8033B498.focus, sMarioStatusForCamera->pos); + + // Update the stored focus and pos to the direction found in the search + if (searching == 0) { + vec3f_set_dist_and_angle(checkFoc, sCameraStoreCUp.pos, gCameraZoomDist, 0, curYaw + checkYaw); + vec3f_copy(sCameraStoreCUp.focus, checkFoc); + vec3f_sub(sCameraStoreCUp.pos, sMarioCamState->pos); + vec3f_sub(sCameraStoreCUp.focus, sMarioCamState->pos); } - gCameraMovementFlags |= CAM_MOVE_UNKNOWN_10; - init_transitional_movement(c, 15); + + gCameraMovementFlags |= CAM_MOVE_STARTED_EXITING_C_UP; + transition_next_state(c, 15); } else { - gCameraMovementFlags &= ~(CAM_MOVE_UNKNOWN_10 | CAM_MOVE_C_UP_MODE); - vec3f_set_dist_and_angle(sp68, c->pos, sp48, sp42, sp40 + sp3E); + // Let the next camera mode handle it + gCameraMovementFlags &= ~(CAM_MOVE_STARTED_EXITING_C_UP | CAM_MOVE_C_UP_MODE); + vec3f_set_dist_and_angle(checkFoc, c->pos, curDist, curPitch, curYaw + checkYaw); } play_sound_cbutton_down(); } return 0; } -s32 return_first_person_camera_yaw(UNUSED struct LevelCamera *c, Vec3f focus, Vec3f pos) { - s16 pitch = sFirstPersonCameraPitch; - s16 yaw = sMarioStatusForCamera->faceAngle[1] + sFirstPersonCameraYaw + 32768; +/** + * The mode used when C-Up is pressed. + */ +s32 update_c_up(UNUSED struct Camera *c, Vec3f focus, Vec3f pos) { + s16 pitch = sCUpCameraPitch; + s16 yaw = sMarioCamState->faceAngle[1] + sModeOffsetYaw + DEGREES(180); - set_cam_focus_and_pos_rel_mario(focus, pos, 125.f, 125.f, 250.f, pitch, yaw); - return sMarioStatusForCamera->faceAngle[1]; + focus_on_mario(focus, pos, 125.f, 125.f, 250.f, pitch, yaw); + return sMarioCamState->faceAngle[1]; } -void operate_c_up_looking(UNUSED struct LevelCamera *c) { - UNUSED s16 pitch = sFirstPersonCameraPitch; - UNUSED s16 yaw = sFirstPersonCameraYaw; +/** + * Make mario's head move in C-Up mode. + */ +void move_mario_head_c_up(UNUSED struct Camera *c) { + UNUSED s16 pitch = sCUpCameraPitch; + UNUSED s16 yaw = sModeOffsetYaw; - sFirstPersonCameraPitch += (s16)(gPlayer1Controller->stickY * 10.f); - sFirstPersonCameraYaw -= (s16)(gPlayer1Controller->stickX * 10.f); + sCUpCameraPitch += (s16)(gPlayer1Controller->stickY * 10.f); + sModeOffsetYaw -= (s16)(gPlayer1Controller->stickX * 10.f); - if (sFirstPersonCameraPitch > 14563) { - sFirstPersonCameraPitch = 14563; + // Bound looking up to nearly 80 degrees. + if (sCUpCameraPitch > 0x38E3) { + sCUpCameraPitch = 0x38E3; } - if (sFirstPersonCameraPitch < -8192) { - sFirstPersonCameraPitch = -8192; - } - if (sFirstPersonCameraYaw > 21845) { - sFirstPersonCameraYaw = 21845; - } - if (sFirstPersonCameraYaw < -21845) { - sFirstPersonCameraYaw = -21845; + // Bound looking down to -45 degrees + if (sCUpCameraPitch < -0x2000) { + sCUpCameraPitch = -0x2000; } - // Set mario's head angles maybe? - sMarioStatusForCamera->unk16[0] = sFirstPersonCameraPitch * 3 / 4; - sMarioStatusForCamera->unk16[1] = sFirstPersonCameraYaw * 3 / 4; + // Bound the camera yaw to +-120 degrees + if (sModeOffsetYaw > 0x5555) { + sModeOffsetYaw = 0x5555; + } + if (sModeOffsetYaw < -0x5555) { + sModeOffsetYaw = -0x5555; + } + + // Give mario's neck natural-looking constraints + sMarioCamState->headRotation[0] = sCUpCameraPitch * 3 / 4; + sMarioCamState->headRotation[1] = sModeOffsetYaw * 3 / 4; } -void func_8028547C(struct LevelCamera *c) { - struct Struct8033B418_sub *sp2C = &D_8033B418.unk8; - struct Struct8033B418_sub *sp28 = &D_8033B418.unk28; - f32 sp24 = sp28->unk18 - sp2C->unk18; - s16 sp22 = sp28->unk1C - sp2C->unk1C; - s16 sp20 = sp28->unk1E - sp2C->unk1E; +/** + * Zooms the camera in for C-Up mode + */ +void move_into_c_up(struct Camera *c) { + struct LinearTransitionPoint *start = &sModeInfo.transitionStart; + struct LinearTransitionPoint *end = &sModeInfo.transitionEnd; - sp24 = sp2C->unk18 + sp24 * D_8033B418.unk6 / D_8033B418.unk4; - sp22 = sp2C->unk1C + sp22 * D_8033B418.unk6 / D_8033B418.unk4; - sp20 = sp2C->unk1E + sp20 * D_8033B418.unk6 / D_8033B418.unk4; - c->focus[0] = sp2C->unk0[0] + (sp28->unk0[0] - sp2C->unk0[0]) * D_8033B418.unk6 / D_8033B418.unk4; - c->focus[1] = sp2C->unk0[1] + (sp28->unk0[1] - sp2C->unk0[1]) * D_8033B418.unk6 / D_8033B418.unk4; - c->focus[2] = sp2C->unk0[2] + (sp28->unk0[2] - sp2C->unk0[2]) * D_8033B418.unk6 / D_8033B418.unk4; - vec3f_add(c->focus, sMarioStatusForCamera->pos); - vec3f_set_dist_and_angle(c->focus, c->pos, sp24, sp22, sp20); - sMarioStatusForCamera->unk16[0] = 0; - sMarioStatusForCamera->unk16[1] = 0; - if (++D_8033B418.unk6 == D_8033B418.unk4) { - gCameraMovementFlags &= ~CAM_MOVE_INTO_C_UP; - } -} + f32 dist = end->dist - start->dist; + s16 pitch = end->pitch - start->pitch; + s16 yaw = end->yaw - start->yaw; -s32 update_c_up_camera(struct LevelCamera *c) { - UNUSED u8 unused[16]; + // Linearly interpolate from start to end position's polar coordinates + dist = start->dist + dist * sModeInfo.frame / sModeInfo.max; + pitch = start->pitch + pitch * sModeInfo.frame / sModeInfo.max; + yaw = start->yaw + yaw * sModeInfo.frame / sModeInfo.max; - if (!(gCameraFlags1 & CAM_FLAG_1_UNKNOWN_0)) { - play_sound_cbutton_up(); - gCameraFlags1 |= CAM_FLAG_1_UNKNOWN_0; - } - if (gCameraMovementFlags & CAM_MOVE_INTO_C_UP) { - gCameraMovementFlags |= CAM_MOVE_C_UP_MODE; - func_8028547C(c); - return 1; - } - if (!(gCameraMovementFlags & CAM_MOVE_UNKNOWN_10)) { - operate_c_up_looking(c); - return_first_person_camera_yaw(c, c->focus, c->pos); - } else { - if (gCameraFlags2 & CAM_FLAG_2_UNKNOWN_11) { - vec3f_copy(c->pos, D_8033B498.pos); - vec3f_add(c->pos, sMarioStatusForCamera->pos); - vec3f_copy(c->focus, D_8033B498.focus); - vec3f_add(c->focus, sMarioStatusForCamera->pos); - camera_approach_s16_symmetric_bool(&sMarioStatusForCamera->unk16[0], 0, 1024); - camera_approach_s16_symmetric_bool(&sMarioStatusForCamera->unk16[1], 0, 1024); - } else { - gCameraMovementFlags &= ~(CAM_MOVE_UNKNOWN_10 | CAM_MOVE_C_UP_MODE); - } - } - D_8033B40C = 0.f; - if (gPlayer1Controller->buttonPressed - & (A_BUTTON | B_BUTTON | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS)) { - exit_c_up_mode(c); - } - return 0; -} + // Linearly interpolate the focus from start to end + c->focus[0] = start->focus[0] + (end->focus[0] - start->focus[0]) * sModeInfo.frame / sModeInfo.max; + c->focus[1] = start->focus[1] + (end->focus[1] - start->focus[1]) * sModeInfo.frame / sModeInfo.max; + c->focus[2] = start->focus[2] + (end->focus[2] - start->focus[2]) * sModeInfo.frame / sModeInfo.max; -s32 return_cannon_camera_yaw(UNUSED struct LevelCamera *c, Vec3f focus, Vec3f pos) { - set_cam_focus_and_pos_rel_mario(pos, focus, 125.f + D_8033B410, 125.f, 800.f, - sMarioStatusForCamera->faceAngle[0], - sMarioStatusForCamera->faceAngle[1]); - return sMarioStatusForCamera->faceAngle[1]; -} + vec3f_add(c->focus, sMarioCamState->pos); + vec3f_set_dist_and_angle(c->focus, c->pos, dist, pitch, yaw); -void update_cannon_camera(struct LevelCamera *c) { - UNUSED u8 unused[24]; + sMarioCamState->headRotation[0] = 0; + sMarioCamState->headRotation[1] = 0; - D_8033B3F0 = 0; - gCameraMovementFlags &= ~CAM_MOVE_INTO_C_UP; - c->storedYaw = return_cannon_camera_yaw(c, c->focus, c->pos); - if (gPlayer1Controller->buttonPressed & A_BUTTON) { - func_80285BD8(c, 3, 1); - D_8033B40C = 0; - D_8033B410 = 0; - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_1; - } else { - D_8033B410 = approach_f32(D_8033B410, 0.f, 100.f, 100.f); - } -} - -void init_transitional_movement(UNUSED struct LevelCamera *c, s16 timerLength) { - if (!(gCameraFlags2 & CAM_FLAG_2_FRAME_AFTER_CAM_INIT)) { - gCameraFlags2 |= (CAM_FLAG_2_UNKNOWN_10 | CAM_FLAG_2_UNKNOWN_11); - sCameraTransition.timer = timerLength; + // Finished zooming in + if (++sModeInfo.frame == sModeInfo.max) { + gCameraMovementFlags &= ~CAM_MOVING_INTO_MODE; } } /** - * If the camera preset is not the new preset, set it to be so and initialize. - * If the new preset is -1, keep the old and only do the initialization. + * The main update function for C-Up mode */ -void set_camera_preset(struct LevelCamera *c, s16 newPreset, s16 transitionTimer) { - if (c->currPreset != newPreset) { - D_8033B418.unk0 = (newPreset != -1) ? newPreset : D_8033B418.unk2; - D_8033B418.unk2 = c->currPreset; - c->currPreset = D_8033B418.unk0; - gCameraMovementFlags &= 0xFF02; - if (!(gCameraFlags2 & CAM_FLAG_2_FRAME_AFTER_CAM_INIT)) { - init_transitional_movement(c, transitionTimer); - sFirstPersonCameraPitch = 0; - sFirstPersonCameraYaw = 0; - D_8033B3EE = 0; - D_8033B3F0 = 0; - D_8033B3EC = 0; - D_8033B40C = 0.f; - D_8033B410 = 0.f; - } +s32 mode_c_up_camera(struct Camera *c) { + UNUSED u8 unused[16]; + + // Play a sound when entering C-Up mode + if (!(sCameraSoundFlags & CAM_SOUND_C_UP_PLAYED)) { + play_sound_cbutton_up(); + sCameraSoundFlags |= CAM_SOUND_C_UP_PLAYED; } -} -void func_80285BD8(struct LevelCamera *a, s16 b, s16 c) { - struct Struct8033B418_sub *sp24 = &D_8033B418.unk8; - struct Struct8033B418_sub *sp20 = &D_8033B418.unk28; + // Zoom in first + if (gCameraMovementFlags & CAM_MOVING_INTO_MODE) { + gCameraMovementFlags |= CAM_MOVE_C_UP_MODE; + move_into_c_up(c); + return 1; + } - if (b == 8 && gCurrLevelArea == AREA_TTM_OUTSIDE) { + if (!(gCameraMovementFlags & CAM_MOVE_STARTED_EXITING_C_UP)) { + // Normal update + move_mario_head_c_up(c); + update_c_up(c, c->focus, c->pos); } else { - gCameraMovementFlags &= 0xFF02; - gCameraMovementFlags |= CAM_MOVE_INTO_C_UP; - if (b == 0) { - b = 4; + // Exiting C-Up + if (sStatusFlags & CAM_FLAG_TRANSITION_OUT_OF_C_UP) { + // Retrieve the previous position and focus + vec3f_copy(c->pos, sCameraStoreCUp.pos); + vec3f_add(c->pos, sMarioCamState->pos); + vec3f_copy(c->focus, sCameraStoreCUp.focus); + vec3f_add(c->focus, sMarioCamState->pos); + // Make mario look forward + camera_approach_s16_symmetric_bool(&sMarioCamState->headRotation[0], 0, 1024); + camera_approach_s16_symmetric_bool(&sMarioCamState->headRotation[1], 0, 1024); + } else { + // Finished exiting C-Up + gCameraMovementFlags &= ~(CAM_MOVE_STARTED_EXITING_C_UP | CAM_MOVE_C_UP_MODE); } - sFirstPersonCameraPitch = 0; - sFirstPersonCameraYaw = 0; - D_8033B3EE = 0; - D_8033B3F0 = 0; - D_8033B3EC = 0; - D_8033B418.unk0 = (b != -1) ? b : D_8033B418.unk2; - D_8033B418.unk2 = a->currPreset; - D_8033B418.unk4 = c; - D_8033B418.unk6 = 1; - a->currPreset = D_8033B418.unk0; - gCameraStatus.modeActive = a->currPreset; - vec3f_copy(sp20->unk0, a->focus); - vec3f_sub(sp20->unk0, sMarioStatusForCamera->pos); - vec3f_copy(sp20->unkC, a->pos); - vec3f_sub(sp20->unkC, sMarioStatusForCamera->pos); - sYawFocToMario = TableCameraTransitions[D_8033B418.unk0](a, sp20->unk0, sp20->unkC); - vec3f_sub(sp20->unk0, sMarioStatusForCamera->pos); - vec3f_sub(sp20->unkC, sMarioStatusForCamera->pos); - vec3f_copy(sp24->unk0, gCameraStatus.camFocAndPosCurrAndGoal[0]); - vec3f_sub(sp24->unk0, sMarioStatusForCamera->pos); - vec3f_copy(sp24->unkC, gCameraStatus.camFocAndPosCurrAndGoal[1]); - vec3f_sub(sp24->unkC, sMarioStatusForCamera->pos); - vec3f_get_dist_and_angle(sp24->unk0, sp24->unkC, &sp24->unk18, &sp24->unk1C, &sp24->unk1E); - vec3f_get_dist_and_angle(sp20->unk0, sp20->unkC, &sp20->unk18, &sp20->unk1C, &sp20->unk1E); + } + sPanDistance = 0.f; + + // Exit C-Up mode + if (gPlayer1Controller->buttonPressed & (A_BUTTON | B_BUTTON | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS)) { + exit_c_up(c); + } + return 0; +} + +/** + * Used when mario is in a cannon. + */ +s32 update_in_cannon(UNUSED struct Camera *c, Vec3f focus, Vec3f pos) { + focus_on_mario(pos, focus, 125.f + sCannonYOffset, 125.f, 800.f, + sMarioCamState->faceAngle[0], sMarioCamState->faceAngle[1]); + return sMarioCamState->faceAngle[1]; +} + +/** + * Updates the camera when mario is in a cannon. + * sCannonYOffset is used to make the camera rotate down when mario has just entered the cannon + */ +void mode_cannon_camera(struct Camera *c) { + UNUSED u8 unused[24]; + + sLakituPitch = 0; + gCameraMovementFlags &= ~CAM_MOVING_INTO_MODE; + c->nextYaw = update_in_cannon(c, c->focus, c->pos); + if (gPlayer1Controller->buttonPressed & A_BUTTON) { + set_camera_mode(c, CAMERA_MODE_BEHIND_MARIO, 1); + sPanDistance = 0; + sCannonYOffset = 0; + sStatusFlags &= ~CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; + } else { + sCannonYOffset = approach_f32(sCannonYOffset, 0.f, 100.f, 100.f); } } -void func_80285E70(struct LevelCamera *c) { +/** + * Cause lakitu to fly to the next Camera position and focus over a number of frames. + * + * At the end of each frame, lakitu's position and focus ("state") are stored. + * Calling this function makes next_lakitu_state() fly from the last frame's state to the + * current frame's calculated state. + * + * @see next_lakitu_state() + */ +void transition_next_state(UNUSED struct Camera *c, s16 frames) { + if (!(sStatusFlags & CAM_FLAG_FRAME_AFTER_CAM_INIT)) { + sStatusFlags |= (CAM_FLAG_START_TRANSITION | CAM_FLAG_TRANSITION_OUT_OF_C_UP); + sModeTransition.framesLeft = frames; + } +} + +/** + * Sets the camera mode to `newMode` and initializes sModeTransition with `numFrames` frames + * + * Used to change the camera mode to 'level-oriented' modes + * namely: RADIAL/OUTWARD_RADIAL, 8_DIRECTIONS, FREE_ROAM, CLOSE, SPIRAL_STAIRS, and SLIDE_HOOT + */ +void transition_to_camera_mode(struct Camera *c, s16 newMode, s16 numFrames) { + if (c->mode != newMode) { + sModeInfo.newMode = (newMode != -1) ? newMode : sModeInfo.lastMode; + sModeInfo.lastMode = c->mode; + c->mode = sModeInfo.newMode; + + // Clear movement flags that would affect the transition + gCameraMovementFlags &= (u16)~(CAM_MOVE_RESTRICT | CAM_MOVE_ROTATE); + if (!(sStatusFlags & CAM_FLAG_FRAME_AFTER_CAM_INIT)) { + transition_next_state(c, numFrames); + sCUpCameraPitch = 0; + sModeOffsetYaw = 0; + sLakituDist = 0; + sLakituPitch = 0; + sAreaYawChange = 0; + sPanDistance = 0.f; + sCannonYOffset = 0.f; + } + } +} + +/** + * Used to change the camera mode between its default/previous and certain mario-oriented modes, + * namely: C_UP, WATER_SURFACE, CLOSE, and BEHIND_MARIO + * + * Stores the current pos and focus in sModeInfo->transitionStart, and + * stores the next pos and focus into sModeInfo->transitionEnd. These two fields are used in + * move_into_c_up(). + * + * @param mode the mode to change to, or -1 to switch to the previous mode + * @param frames number of frames the transition should last, only used when entering C_UP + */ +void set_camera_mode(struct Camera *c, s16 mode, s16 frames) { + struct LinearTransitionPoint *start = &sModeInfo.transitionStart; + struct LinearTransitionPoint *end = &sModeInfo.transitionEnd; + + if (mode == CAMERA_MODE_WATER_SURFACE && gCurrLevelArea == AREA_TTM_OUTSIDE) { + } else { + // Clear movement flags that would affect the transition + gCameraMovementFlags &= (u16)~(CAM_MOVE_RESTRICT | CAM_MOVE_ROTATE); + gCameraMovementFlags |= CAM_MOVING_INTO_MODE; + if (mode == CAMERA_MODE_NONE) { + mode = CAMERA_MODE_CLOSE; + } + sCUpCameraPitch = 0; + sModeOffsetYaw = 0; + sLakituDist = 0; + sLakituPitch = 0; + sAreaYawChange = 0; + + sModeInfo.newMode = (mode != -1) ? mode : sModeInfo.lastMode; + sModeInfo.lastMode = c->mode; + sModeInfo.max = frames; + sModeInfo.frame = 1; + + c->mode = sModeInfo.newMode; + gLakituState.mode = c->mode; + + vec3f_copy(end->focus, c->focus); + vec3f_sub(end->focus, sMarioCamState->pos); + + vec3f_copy(end->pos, c->pos); + vec3f_sub(end->pos, sMarioCamState->pos); + + sAreaYaw = sModeTransitions[sModeInfo.newMode](c, end->focus, end->pos); + + // End was updated by sModeTransitions + vec3f_sub(end->focus, sMarioCamState->pos); + vec3f_sub(end->pos, sMarioCamState->pos); + + vec3f_copy(start->focus, gLakituState.curFocus); + vec3f_sub(start->focus, sMarioCamState->pos); + + vec3f_copy(start->pos, gLakituState.curPos); + vec3f_sub(start->pos, sMarioCamState->pos); + + vec3f_get_dist_and_angle(start->focus, start->pos, &start->dist, &start->pitch, &start->yaw); + vec3f_get_dist_and_angle(end->focus, end->pos, &end->dist, &end->pitch, &end->yaw); + } +} + +/** + * Updates lakitu's position/focus and applies camera shakes. + */ +void update_lakitu(struct Camera *c) { struct Surface *floor = NULL; - Vec3f sp50; - Vec3f sp44; - UNUSED u8 unused1[12]; - f32 sp34; - s16 sp32; - UNUSED u8 unused2[8]; + Vec3f newPos; + Vec3f newFoc; + UNUSED Vec3f unusedVec3f; + f32 distToFloor; + s16 newYaw; + UNUSED u8 unused1[8]; if (gCameraMovementFlags & CAM_MOVE_PAUSE_SCREEN) { } else { if (c->cutscene) { } - if (1) { - sp32 = func_8028C824(sp50, sp44, c->pos, c->focus, sCameraPosition, sCameraFocus, - c->storedYaw); - set_or_approach_s16_symmetric(&c->trueYaw, sp32, D_8032CFD4); - gCameraFlags2 &= ~CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + if (TRUE) { + newYaw = next_lakitu_state(newPos, newFoc, c->pos, c->focus, sOldPosition, sOldFocus, + c->nextYaw); + set_or_approach_s16_symmetric(&c->yaw, newYaw, sYawSpeed); + sStatusFlags &= ~CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } else { - //! dead code - vec3f_copy(sp50, c->pos); - vec3f_copy(sp44, c->focus); + //! dead code, moved to next_lakitu_state() + vec3f_copy(newPos, c->pos); + vec3f_copy(newFoc, c->focus); } - vec3f_copy(sCameraPosition, sp50); - vec3f_copy(sCameraFocus, sp44); - gCameraStatus.trueYaw = c->trueYaw; - gCameraStatus.storedYaw = c->storedYaw; - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[3], c->pos); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[2], c->focus); - set_or_approach_vec3f_exponential(gCameraStatus.camFocAndPosCurrAndGoal[1], sp50, - gCameraStatus.unkAC, gCameraStatus.unkB0, - gCameraStatus.unkAC); - set_or_approach_vec3f_exponential(gCameraStatus.camFocAndPosCurrAndGoal[0], sp44, - gCameraStatus.unkA4, gCameraStatus.unkA8, - gCameraStatus.unkA4); - set_or_approach_f32_exponential(&gCameraStatus.unkA4, 0.8f, 0.05f); - set_or_approach_f32_exponential(&gCameraStatus.unkA8, 0.3f, 0.05f); - set_or_approach_f32_exponential(&gCameraStatus.unkAC, 0.3f, 0.05f); - set_or_approach_f32_exponential(&gCameraStatus.unkB0, 0.3f, 0.05f); - if (gCameraFlags2 & CAM_FLAG_2_UNKNOWN_1) { - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_1; + + // Update old state + vec3f_copy(sOldPosition, newPos); + vec3f_copy(sOldFocus, newFoc); + + gLakituState.yaw = c->yaw; + gLakituState.nextYaw = c->nextYaw; + vec3f_copy(gLakituState.goalPos, c->pos); + vec3f_copy(gLakituState.goalFocus, c->focus); + + // Simulate lakitu flying to the new position and turning towards the new focus + set_or_approach_vec3f_asymptotic(gLakituState.curPos, newPos, + gLakituState.posHSpeed, gLakituState.posVSpeed, + gLakituState.posHSpeed); + set_or_approach_vec3f_asymptotic(gLakituState.curFocus, newFoc, + gLakituState.focHSpeed, gLakituState.focVSpeed, + gLakituState.focHSpeed); + // Adjust lakitu's speed back to normal + set_or_approach_f32_asymptotic(&gLakituState.focHSpeed, 0.8f, 0.05f); + set_or_approach_f32_asymptotic(&gLakituState.focVSpeed, 0.3f, 0.05f); + set_or_approach_f32_asymptotic(&gLakituState.posHSpeed, 0.3f, 0.05f); + set_or_approach_f32_asymptotic(&gLakituState.posVSpeed, 0.3f, 0.05f); + + // Turn on smooth movement when it hasn't been blocked for 2 frames + if (sStatusFlags & CAM_FLAG_BLOCK_SMOOTH_MOVEMENT) { + sStatusFlags &= ~CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; } else { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } - vec3f_copy(gCameraStatus.pos, gCameraStatus.camFocAndPosCurrAndGoal[1]); - vec3f_copy(gCameraStatus.focus, gCameraStatus.camFocAndPosCurrAndGoal[0]); + + vec3f_copy(gLakituState.pos, gLakituState.curPos); + vec3f_copy(gLakituState.focus, gLakituState.curFocus); + if (c->cutscene) { - vec3f_add(gCameraStatus.focus, D_8033B218); - vec3f_set(D_8033B218, 0, 0, 0); + vec3f_add(gLakituState.focus, sPlayer2FocusOffset); + vec3f_set(sPlayer2FocusOffset, 0, 0, 0); } - vec3f_get_dist_and_angle(gCameraStatus.pos, gCameraStatus.focus, &gCameraStatus.focusDistance, - &gCameraStatus.pitch, &gCameraStatus.yaw); + vec3f_get_dist_and_angle(gLakituState.pos, gLakituState.focus, &gLakituState.focusDistance, + &gLakituState.oldPitch, &gLakituState.oldYaw); - gCameraStatus.roll = 0; + gLakituState.roll = 0; - shake_camera_pitch(gCameraStatus.pos, gCameraStatus.focus); - shake_camera_yaw(gCameraStatus.pos, gCameraStatus.focus); - shake_camera_roll(&gCameraStatus.roll); + // Apply camera shakes + shake_camera_pitch(gLakituState.pos, gLakituState.focus); + shake_camera_yaw(gLakituState.pos, gLakituState.focus); + shake_camera_roll(&gLakituState.roll); + shake_camera_handheld(gLakituState.pos, gLakituState.focus); - set_face_angle_from_spline(gCameraStatus.pos, gCameraStatus.focus); - - if (sMarioStatusForCamera->action == ACT_DIVE && gCameraStatus.lastFrameAction != ACT_DIVE) { - set_camera_shake(SHAKE_HIT_FROM_BELOW); + if (sMarioCamState->action == ACT_DIVE && gLakituState.lastFrameAction != ACT_DIVE) { + set_camera_shake_from_hit(SHAKE_HIT_FROM_BELOW); } - gCameraStatus.roll += sCameraCutsceneRollOffset; - gCameraStatus.roll += gCameraStatus.cameraKeyCutsceneRollOffset; + gLakituState.roll += sHandheldShakeRoll; + gLakituState.roll += gLakituState.keyDanceRoll; - if (c->currPreset != CAMERA_PRESET_C_UP_LOOK && c->cutscene == 0) { - gCheckingSurfaceCollisionsForCamera = 1; - sp34 = find_floor(gCameraStatus.pos[0], gCameraStatus.pos[1] + 20.0f, gCameraStatus.pos[2], - &floor); - if (sp34 != -11000.f) { - if (gCameraStatus.pos[1] < (sp34 += 100.0f)) { - gCameraStatus.pos[1] = sp34; + if (c->mode != CAMERA_MODE_C_UP && c->cutscene == 0) { + gCheckingSurfaceCollisionsForCamera = TRUE; + distToFloor = find_floor(gLakituState.pos[0], + gLakituState.pos[1] + 20.0f, + gLakituState.pos[2], &floor); + if (distToFloor != -11000.f) { + if (gLakituState.pos[1] < (distToFloor += 100.0f)) { + gLakituState.pos[1] = distToFloor; } else { - gCheckingSurfaceCollisionsForCamera = 0; + gCheckingSurfaceCollisionsForCamera = FALSE; } } } - vec3f_copy(sCameraTransition.marioPos, sMarioStatusForCamera->pos); + + vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos); } - clamp_pitch(gCameraStatus.pos, gCameraStatus.focus, 15872, -15872); - gCameraStatus.modeActive = c->currPreset; - gCameraStatus.modeDefault = c->defPreset; + clamp_pitch(gLakituState.pos, gLakituState.focus, 0x3E00, -0x3E00); + gLakituState.mode = c->mode; + gLakituState.defMode = c->defMode; } -void update_camera(struct LevelCamera *c) { + +/** + * The main camera update function. + * Gets controller input, checks for cutscenes, handles mode changes, and moves the camera + */ +void update_camera(struct Camera *c) { UNUSED u8 unused[24]; - gCurrLevelCamera = c; - update_camera_status(c); + gCamera = c; + update_camera_hud_status(c); if (c->cutscene == 0) { - if (select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_MARIO) { + // Only process R_TRIG if 'fixed' is not selected in the menu + if (cam_select_alt_mode(0) == CAM_SELECTION_MARIO) { if (gPlayer1Controller->buttonPressed & R_TRIG) { - if (test_or_set_mario_cam_active(0) == CAM_ANGLE_LAKITU_FIXED) { - test_or_set_mario_cam_active(1); + if (set_cam_angle(0) == CAM_ANGLE_LAKITU) { + set_cam_angle(CAM_ANGLE_MARIO); } else { - test_or_set_mario_cam_active(2); + set_cam_angle(CAM_ANGLE_LAKITU); } } } - func_8028B36C(); + play_sound_if_cam_switched_to_lakitu_or_mario(); } - gCameraFlags2 &= ~CAM_FLAG_2_FRAME_AFTER_CAM_INIT; + + // Initialize the camera + sStatusFlags &= ~CAM_FLAG_FRAME_AFTER_CAM_INIT; if (gCameraMovementFlags & CAM_MOVE_INIT_CAMERA) { init_camera(c); gCameraMovementFlags &= ~CAM_MOVE_INIT_CAMERA; - gCameraFlags2 |= CAM_FLAG_2_FRAME_AFTER_CAM_INIT; + sStatusFlags |= CAM_FLAG_FRAME_AFTER_CAM_INIT; } - sGeometryForMario.prevFloorHeight = sGeometryForMario.currFloorHeight; - sGeometryForMario.prevCeilHeight = sGeometryForMario.currCeilHeight; - sGeometryForMario.prevFloor = sGeometryForMario.currFloor; - sGeometryForMario.prevCeil = sGeometryForMario.currCeil; - sGeometryForMario.prevFloorType = sGeometryForMario.currFloorType; - sGeometryForMario.prevCeilType = sGeometryForMario.currCeilType; + // Store previous geometry information + sMarioGeometry.prevFloorHeight = sMarioGeometry.currFloorHeight; + sMarioGeometry.prevCeilHeight = sMarioGeometry.currCeilHeight; + sMarioGeometry.prevFloor = sMarioGeometry.currFloor; + sMarioGeometry.prevCeil = sMarioGeometry.currCeil; + sMarioGeometry.prevFloorType = sMarioGeometry.currFloorType; + sMarioGeometry.prevCeilType = sMarioGeometry.currCeilType; - find_mario_relative_geometry(&sGeometryForMario); - gCheckingSurfaceCollisionsForCamera = 1; - vec3f_copy(c->pos, gCameraStatus.camFocAndPosCurrAndGoal[3]); - vec3f_copy(c->focus, gCameraStatus.camFocAndPosCurrAndGoal[2]); + find_mario_floor_and_ceil(&sMarioGeometry); + gCheckingSurfaceCollisionsForCamera = TRUE; + vec3f_copy(c->pos, gLakituState.goalPos); + vec3f_copy(c->focus, gLakituState.goalFocus); - c->trueYaw = gCameraStatus.trueYaw; - c->storedYaw = gCameraStatus.storedYaw; - c->currPreset = gCameraStatus.modeActive; - c->defPreset = gCameraStatus.modeDefault; + c->yaw = gLakituState.yaw; + c->nextYaw = gLakituState.nextYaw; + c->mode = gLakituState.mode; + c->defMode = gLakituState.defMode; - level_specific_camera_update(c); + camera_course_processing(c); dummy_802877EC(c); - gCButtonsPressed = find_c_buttons_pressed(gCButtonsPressed, gPlayer1Controller->buttonPressed, + sCButtonsPressed = find_c_buttons_pressed(sCButtonsPressed, gPlayer1Controller->buttonPressed, gPlayer1Controller->buttonDown); + if (c->cutscene != 0) { - D_8032CFD4 = 0; - handle_cutscenes(c); - sCutsceneTransitionTimer = 0; + sYawSpeed = 0; + play_cutscene(c); + sFramesSinceCutsceneEnded = 0; } else { - if (gCutsceneNumber != 0 && sCutsceneTransitionTimer < 8) { - sCutsceneTransitionTimer++; - if (sCutsceneTransitionTimer >= 8) { - gCutsceneNumber = 0; - sCutsceneTransitionTimer = 0; + // Clear the recent cutscene after 8 frames + if (gRecentCutscene != 0 && sFramesSinceCutsceneEnded < 8) { + sFramesSinceCutsceneEnded++; + if (sFramesSinceCutsceneEnded >= 8) { + gRecentCutscene = 0; + sFramesSinceCutsceneEnded = 0; } } } + // If not in a cutscene, do mode processing if (c->cutscene == 0) { - D_8032CFD4 = 0x400; + sYawSpeed = 0x400; - if (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE) { - switch (c->currPreset) { - case CAMERA_PRESET_BEHIND_MARIO: - update_behind_mario_camera(c); + if (sSelectionFlags & CAM_MODE_MARIO_ACTIVE) { + switch (c->mode) { + case CAMERA_MODE_BEHIND_MARIO: + mode_behind_mario_camera(c); break; - case CAMERA_PRESET_C_UP_LOOK: - update_c_up_camera(c); + case CAMERA_MODE_C_UP: + mode_c_up_camera(c); break; - case CAMERA_PRESET_WATER_SURFACE: - update_water_surface_camera(c); + case CAMERA_MODE_WATER_SURFACE: + mode_water_surface_camera(c); break; - case CAMERA_PRESET_INSIDE_CANNON: - update_cannon_camera(c); + case CAMERA_MODE_INSIDE_CANNON: + mode_cannon_camera(c); break; default: - camera_mario_zoom_distance(c); + mode_mario_camera(c); } } else { - switch (c->currPreset) { - case CAMERA_PRESET_BEHIND_MARIO: - update_behind_mario_camera(c); + switch (c->mode) { + case CAMERA_MODE_BEHIND_MARIO: + mode_behind_mario_camera(c); break; - case CAMERA_PRESET_C_UP_LOOK: - update_c_up_camera(c); + case CAMERA_MODE_C_UP: + mode_c_up_camera(c); break; - case CAMERA_PRESET_WATER_SURFACE: - update_water_surface_camera(c); + case CAMERA_MODE_WATER_SURFACE: + mode_water_surface_camera(c); break; - case CAMERA_PRESET_INSIDE_CANNON: - update_cannon_camera(c); + case CAMERA_MODE_INSIDE_CANNON: + mode_cannon_camera(c); break; - case CAMERA_PRESET_PLATFORM_LEVEL: - update_platform_level_camera(c); + case CAMERA_MODE_8_DIRECTIONS: + mode_8_directions_camera(c); break; - case CAMERA_PRESET_OPEN_CAMERA: - update_open_camera(c); + case CAMERA_MODE_RADIAL: + mode_radial_camera(c); break; - case CAMERA_PRESET_REVERSE_TOWER: - update_reverse_tower_camera(c); + case CAMERA_MODE_OUTWARD_RADIAL: + mode_outward_radial_camera(c); break; - case CAMERA_PRESET_CLOSE: - camera_lakitu_zoom_distance(c); + case CAMERA_MODE_CLOSE: + mode_lakitu_camera(c); break; - case CAMERA_PRESET_FREE_ROAM: - camera_lakitu_zoom_distance(c); + case CAMERA_MODE_FREE_ROAM: + mode_lakitu_camera(c); break; - case CAMERA_PRESET_BOSS_FIGHT: - update_boss_fight_camera(c); + case CAMERA_MODE_BOSS_FIGHT: + mode_boss_fight_camera(c); break; - case CAMERA_PRESET_PARALLEL_TRACKING: - update_parallel_tracking_camera(c); + case CAMERA_MODE_PARALLEL_TRACKING: + mode_parallel_tracking_camera(c); break; - case CAMERA_PRESET_SLIDE_HOOT: - update_slide_camera(c); + case CAMERA_MODE_SLIDE_HOOT: + mode_slide_camera(c); break; - case CAMERA_PRESET_FIXED_REF_POINT: - update_fixed_camera(c); + case CAMERA_MODE_FIXED: + mode_fixed_camera(c); break; - case CAMERA_PRESET_SPIRAL_STAIRS: - update_spiral_stairs_camera(c); + case CAMERA_MODE_SPIRAL_STAIRS: + mode_spiral_stairs_camera(c); break; } } } - set_camera_cutscene_table(c, return_cutscene_table(c)); + // Start any mario-related cutscenes + start_cutscene(c, get_cutscene_from_mario_status(c)); dummy_802877D8(c); - gCheckingSurfaceCollisionsForCamera = 0; + gCheckingSurfaceCollisionsForCamera = FALSE; if (gCurrLevelNum != LEVEL_CASTLE) { - if ((c->cutscene == 0 && (gPlayer1Controller->buttonDown & R_TRIG) - && select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_FIXED) - || (gCameraMovementFlags & CAM_MOVE_UNKNOWN_7) - || (sMarioStatusForCamera->action) == ACT_GETTING_BLOWN) { + // If fixed camera is selected as the alternate mode, then fix the camera as long as the right + // trigger is held + if ((c->cutscene == 0 && + (gPlayer1Controller->buttonDown & R_TRIG) && cam_select_alt_mode(0) == CAM_SELECTION_FIXED) + || (gCameraMovementFlags & CAM_MOVE_FIX_IN_PLACE) + || (sMarioCamState->action) == ACT_GETTING_BLOWN) { + + // If this is the first frame that R_TRIG is held, play the "click" sound if (c->cutscene == 0 && (gPlayer1Controller->buttonPressed & R_TRIG) - && select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_FIXED) { - gCameraFlags1 |= CAM_FLAG_1_UNKNOWN_5; + && cam_select_alt_mode(0) == CAM_SELECTION_FIXED) { + sCameraSoundFlags |= CAM_SOUND_FIXED_ACTIVE; play_sound_rbutton_changed(); } - gCameraStatus.unkAC = 0.f; - gCameraStatus.unkB0 = 0.f; - c->storedYaw = calculate_yaw(gCameraStatus.focus, gCameraStatus.pos); - c->trueYaw = c->storedYaw; - gCameraMovementFlags &= ~CAM_MOVE_UNKNOWN_7; + + // Fixed mode only prevents lakitu from moving. The camera pos still updates, so + // lakitu will fly to his next position as normal whenever R_TRIG is released. + gLakituState.posHSpeed = 0.f; + gLakituState.posVSpeed = 0.f; + + c->nextYaw = calculate_yaw(gLakituState.focus, gLakituState.pos); + c->yaw = c->nextYaw; + gCameraMovementFlags &= ~CAM_MOVE_FIX_IN_PLACE; } else { - if (gCameraFlags1 & CAM_FLAG_1_UNKNOWN_5) { + // Play the "click" sound when fixed mode is released + if (sCameraSoundFlags & CAM_SOUND_FIXED_ACTIVE) { play_sound_rbutton_changed(); - gCameraFlags1 &= ~CAM_FLAG_1_UNKNOWN_5; + sCameraSoundFlags &= ~CAM_SOUND_FIXED_ACTIVE; } } } else { - if ((gPlayer1Controller->buttonPressed & R_TRIG) && select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_FIXED) { + if ((gPlayer1Controller->buttonPressed & R_TRIG) && cam_select_alt_mode(0) == CAM_SELECTION_FIXED) { play_sound_button_change_blocked(); } } - func_80285E70(c); - gCameraStatus.lastFrameAction = sMarioStatusForCamera->action; + + update_lakitu(c); + + gLakituState.lastFrameAction = sMarioCamState->action; } -void reset_camera(struct LevelCamera *c) { - UNUSED s32 sp34 = 0; - UNUSED u8 unused[16]; - UNUSED struct Struct8033B418_sub *sp20 = &D_8033B418.unk8; - UNUSED struct Struct8033B418_sub *sp1C = &D_8033B418.unk28; +/** + * Reset all the camera variables to their arcane defaults + */ +void reset_camera(struct Camera *c) { + UNUSED s32 unused = 0; + UNUSED u8 unused1[16]; + UNUSED struct LinearTransitionPoint *start = &sModeInfo.transitionStart; + UNUSED struct LinearTransitionPoint *end = &sModeInfo.transitionEnd; - gCurrLevelCamera = c; + gCamera = c; gCameraMovementFlags = 0; - sCameraSideCFlags = 0; - gCameraFlags2 = 0; + s2ndRotateFlags = 0; + sStatusFlags = 0; gCutsceneTimer = 0; - D_8033B6EA = 0; - sCutscenePhase = 0; - gCutsceneActive = FALSE; + sCutsceneShot = 0; + gCutsceneObjSpawn = 0; + gObjCutsceneDone = FALSE; gCutsceneFocus = NULL; - unused_8032CFC8 = 0; - unused_8032CFCC = 0; + unused8032CFC8 = 0; + unused8032CFCC = 0; gSecondCameraFocus = NULL; - gCButtonsPressed = 0; - vec3f_copy(sCameraTransition.marioPos, sMarioStatusForCamera->pos); - sCameraTransition.timer = 0; - unused_8032CFCC = -1; - unused_8032CFC8 = -1; + sCButtonsPressed = 0; + vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos); + sModeTransition.framesLeft = 0; + unused8032CFCC = -1; + unused8032CFC8 = -1; gCameraMovementFlags = 0; gCameraMovementFlags |= CAM_MOVE_INIT_CAMERA; - unused_8033B316 = 0; - gCameraFlags2 = 0; - unused_8033B31A = 0; - gCameraFlags1 = 0; - sFirstPersonCameraPitch = 0; - sFirstPersonCameraYaw = 0; - D_8033B404 = 0; - D_8033B3EE = 0; - D_8033B3F0 = 0; - sYawFocToMario = 0; - D_8033B3EC = 0.f; - D_8033B40C = 0.f; - D_8033B410 = 0.f; - D_8033B3F4 = 0.f; - D_8033B3FC = 0.f; - D_8033B3FA = 0; + unused8033B316 = 0; + sStatusFlags = 0; + unused8033B31A = 0; + sCameraSoundFlags = 0; + sCUpCameraPitch = 0; + sModeOffsetYaw = 0; + sSpiralStairsYawOffset = 0; + sLakituDist = 0; + sLakituPitch = 0; + sAreaYaw = 0; + sAreaYawChange = 0.f; + sPanDistance = 0.f; + sCannonYOffset = 0.f; + sZoomAmount = 0.f; + sZeroZoomDist = 0.f; + sBehindMarioSoundTimer = 0; sCSideButtonYaw = 0; - sPlatformLevelPresetBaseYaw = 0; - gPlatformLevelYawOffset = 0; - c->unk64 = 0; - sMarioStatusForCamera->unk16[0] = 0; - sMarioStatusForCamera->unk16[1] = 0; - sLuigiStatusForCamera->unk16[0] = 0; - sLuigiStatusForCamera->unk16[1] = 0; - sMarioStatusForCamera->unk1C[1] = 0; - sMarioStatusForCamera->usedObj = NULL; - gCameraStatus.shakeMagnitude[0] = 0; - gCameraStatus.shakeMagnitude[1] = 0; - gCameraStatus.shakeMagnitude[2] = 0; - gCameraStatus.unk6C[0] = 0; - gCameraStatus.unk6C[1] = 0; - gCameraStatus.unk6C[2] = 0; - gCameraStatus.unk60[0] = 0.f; - gCameraStatus.unk60[1] = 0.f; - gCameraStatus.unk60[2] = 0.f; - gCameraStatus.lastFrameAction = 0; - set_fov_function(2); - D_8033B230.fieldOfView = 45.f; - D_8033B230.unk8 = 0.f; - D_8033B230.unkC = 0; - D_8033B230.unk10 = 0.f; - D_8033B230.unk14 = 0; - sTempCutsceneNumber = 0; - gCutsceneNumber = 0; - unused_8033B30C = 0; - unused_8033B310 = 0; + s8DirModeBaseYaw = 0; + s8DirModeYawOffset = 0; + c->doorStatus = DOOR_DEFAULT; + sMarioCamState->headRotation[0] = 0; + sMarioCamState->headRotation[1] = 0; + sLuigiCamState->headRotation[0] = 0; + sLuigiCamState->headRotation[1] = 0; + sMarioCamState->cameraEvent = 0; + sMarioCamState->usedObj = NULL; + gLakituState.shakeMagnitude[0] = 0; + gLakituState.shakeMagnitude[1] = 0; + gLakituState.shakeMagnitude[2] = 0; + gLakituState.unusedVec2[0] = 0; + gLakituState.unusedVec2[1] = 0; + gLakituState.unusedVec2[2] = 0; + gLakituState.unusedVec1[0] = 0.f; + gLakituState.unusedVec1[1] = 0.f; + gLakituState.unusedVec1[2] = 0.f; + gLakituState.lastFrameAction = 0; + set_fov_function(CAM_FOV_DEFAULT); + sFOVState.fov = 45.f; + sFOVState.fovOffset = 0.f; + sFOVState.unusedIsSleeping = 0; + sFOVState.shakeAmplitude = 0.f; + sFOVState.shakePhase = 0; + sObjectCutscene = 0; + gRecentCutscene = 0; + unused8033B30C = 0; + unused8033B310 = 0; } -void init_camera(struct LevelCamera *c) { +void init_camera(struct Camera *c) { struct Surface *floor = 0; - Vec3f relativePosition; + Vec3f marioOffset; s32 i; - sCreditsCameraPitch = 0; - sCreditsCameraYaw = 0; + sCreditsPlayer2Pitch = 0; + sCreditsPlayer2Yaw = 0; gPrevLevel = gCurrLevelArea / 16; gCurrLevelArea = gCurrLevelNum * 16 + gCurrentArea->index; - gCameraModeFlags &= CAM_MODE_MARIO_SELECTED; - gFramesPaused = 0; - gCameraStatus.modeActive = c->currPreset; - gCameraStatus.modeDefault = c->defPreset; - gCameraStatus.unkAC = 0.3f; - gCameraStatus.unkB0 = 0.3f; - gCameraStatus.unkA4 = 0.8f; - gCameraStatus.unkA4 = 0.3f; // @bug set unkA4 back-to-back - gCameraStatus.roll = 0; - gCameraStatus.cameraKeyCutsceneRollOffset = 0; - gCameraStatus.unkBC = 0; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - vec3f_set(sFixedPresetBasePositionOffset, 0.f, 0.f, 0.f); - vec3f_set(D_8033B218, 0.f, 0.f, 0.f); - find_mario_relative_geometry(&sGeometryForMario); - sGeometryForMario.prevFloorHeight = sGeometryForMario.currFloorHeight; - sGeometryForMario.prevCeilHeight = sGeometryForMario.currCeilHeight; - sGeometryForMario.prevFloor = sGeometryForMario.currFloor; - sGeometryForMario.prevCeil = sGeometryForMario.currCeil; - sGeometryForMario.prevFloorType = sGeometryForMario.currFloorType; - sGeometryForMario.prevCeilType = sGeometryForMario.currCeilType; + sSelectionFlags &= CAM_MODE_MARIO_SELECTED; + sFramesPaused = 0; + gLakituState.mode = c->mode; + gLakituState.defMode = c->defMode; + gLakituState.posHSpeed = 0.3f; + gLakituState.posVSpeed = 0.3f; + gLakituState.focHSpeed = 0.8f; + gLakituState.focHSpeed = 0.3f; // @bug set focHSpeed back-to-back + gLakituState.roll = 0; + gLakituState.keyDanceRoll = 0; + gLakituState.unused = 0; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + vec3f_set(sCastleEntranceOffset, 0.f, 0.f, 0.f); + vec3f_set(sPlayer2FocusOffset, 0.f, 0.f, 0.f); + find_mario_floor_and_ceil(&sMarioGeometry); + sMarioGeometry.prevFloorHeight = sMarioGeometry.currFloorHeight; + sMarioGeometry.prevCeilHeight = sMarioGeometry.currCeilHeight; + sMarioGeometry.prevFloor = sMarioGeometry.currFloor; + sMarioGeometry.prevCeil = sMarioGeometry.currCeil; + sMarioGeometry.prevFloorType = sMarioGeometry.currFloorType; + sMarioGeometry.prevCeilType = sMarioGeometry.currCeilType; for (i = 0; i < 32; i++) { - D_8033B4E0[i].index = -1; - D_8033B5E0[i].index = -1; + sCurCreditsSplinePos[i].index = -1; + sCurCreditsSplineFocus[i].index = -1; } sCutsceneSplineSegment = 0; sCutsceneSplineSegmentProgress = 0.f; - D_8033B6E8 = 0; - sSplinePositionLimit = 0.f; - sPositionAlongSpline = 0.f; - sSplineParameterMax = 0; + unused8033B6E8 = 0; + sHandheldShakeInc = 0.f; + sHandheldShakeTimer = 0.f; + sHandheldShakeMag = 0; for (i = 0; i < 4; i++) { - sSplineParameters[i].unk0 = -1; + sHandheldShakeSpline[i].index = -1; } - sCameraCutscenePitchOffset = 0; - sCameraCutsceneYawOffset = 0; - sCameraCutsceneRollOffset = 0; + sHandheldShakePitch = 0; + sHandheldShakeYaw = 0; + sHandheldShakeRoll = 0; c->cutscene = 0; - relativePosition[0] = 0.f; - relativePosition[1] = 125.f; - relativePosition[2] = 400.f; + marioOffset[0] = 0.f; + marioOffset[1] = 125.f; + marioOffset[2] = 400.f; + + // Set the camera's starting position or start a cutscene for certain levels switch (gCurrLevelNum) { case LEVEL_BOWSER_1: #ifndef VERSION_JP if (gCurrDemoInput == NULL) { - set_camera_cutscene_table(c, CUTSCENE_ENTER_BOWSER_ARENA); + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); } else if (gSecondCameraFocus != NULL) { gSecondCameraFocus->oBowserUnk88 = 2; } #else - set_camera_cutscene_table(c, CUTSCENE_ENTER_BOWSER_ARENA); + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); #endif break; case LEVEL_BOWSER_2: - set_camera_cutscene_table(c, CUTSCENE_ENTER_BOWSER_ARENA); + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); break; case LEVEL_BOWSER_3: - set_camera_cutscene_table(c, CUTSCENE_ENTER_BOWSER_ARENA); + start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); break; + + //! Hardcoded position checks determine which cutscene to play when mario enters castle grounds. case LEVEL_CASTLE_GROUNDS: if (is_within_100_units_of_mario(-1328.f, 260.f, 4664.f) != 1) { - relativePosition[0] = -400.f; - relativePosition[2] = -800.f; + marioOffset[0] = -400.f; + marioOffset[2] = -800.f; } if (is_within_100_units_of_mario(-6901.f, 2376.f, -6509.f) == 1) { - set_camera_cutscene_table(c, CUTSCENE_EXIT_WATERFALL); + start_cutscene(c, CUTSCENE_EXIT_WATERFALL); } if (is_within_100_units_of_mario(5408.f, 4500.f, 3637.f) == 1) { - set_camera_cutscene_table(c, CUTSCENE_EXIT_FALL_WMOTR); + start_cutscene(c, CUTSCENE_EXIT_FALL_WMOTR); } - gCameraStatus.modeActive = 16; + gLakituState.mode = CAMERA_MODE_FREE_ROAM; break; case LEVEL_SA: - relativePosition[2] = 200.f; + marioOffset[2] = 200.f; break; case LEVEL_CASTLE_COURTYARD: - relativePosition[2] = -300.f; + marioOffset[2] = -300.f; break; case LEVEL_LLL: gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT; break; case LEVEL_CASTLE: - relativePosition[2] = 150.f; + marioOffset[2] = 150.f; break; case LEVEL_RR: - vec3f_set(sFixedPresetBasePosition, -2985.f, 478.f, -5568.f); + vec3f_set(sFixedModeBasePosition, -2985.f, 478.f, -5568.f); break; } - if (c->currPreset == CAMERA_PRESET_PLATFORM_LEVEL) { + if (c->mode == CAMERA_MODE_8_DIRECTIONS) { gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT; } switch (gCurrLevelArea) { case AREA_SSL_EYEROK: - vec3f_set(relativePosition, 0.f, 500.f, -100.f); + vec3f_set(marioOffset, 0.f, 500.f, -100.f); break; case AREA_CCM_SLIDE: - relativePosition[2] = -300.f; + marioOffset[2] = -300.f; break; case AREA_THI_WIGGLER: - relativePosition[2] = -300.f; + marioOffset[2] = -300.f; break; case AREA_SL_IGLOO: - relativePosition[2] = -300.f; + marioOffset[2] = -300.f; break; case AREA_SL_OUTSIDE: if (is_within_100_units_of_mario(257.f, 2150.f, 1399.f) == 1) { - relativePosition[2] = -300.f; + marioOffset[2] = -300.f; } break; case AREA_CCM_OUTSIDE: gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT; break; case AREA_TTM_OUTSIDE: - gCameraStatus.modeActive = CAMERA_PRESET_OPEN_CAMERA; + gLakituState.mode = CAMERA_MODE_RADIAL; break; } - set_pos_from_face_angle_and_vec3f(c->pos, sMarioStatusForCamera->pos, relativePosition, - sMarioStatusForCamera->faceAngle); - if (c->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - c->pos[1] = find_floor(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 100.f, - sMarioStatusForCamera->pos[2], &floor) - + 125.f; + + // Set the camera pos to marioOffset (relative to mario), added to mario's position + offset_rotated(c->pos, sMarioCamState->pos, marioOffset, sMarioCamState->faceAngle); + if (c->mode != CAMERA_MODE_BEHIND_MARIO) { + c->pos[1] = find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 100.f, + sMarioCamState->pos[2], &floor) + 125.f; } - vec3f_copy(c->focus, sMarioStatusForCamera->pos); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[1], c->pos); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[0], c->focus); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[3], c->pos); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[2], c->focus); - vec3f_copy(gCameraStatus.pos, c->pos); - vec3f_copy(gCameraStatus.focus, c->focus); - if (c->currPreset == CAMERA_PRESET_FIXED_REF_POINT) { - set_fixed_cam_axis_sa_lobby(c->currPreset); + vec3f_copy(c->focus, sMarioCamState->pos); + vec3f_copy(gLakituState.curPos, c->pos); + vec3f_copy(gLakituState.curFocus, c->focus); + vec3f_copy(gLakituState.goalPos, c->pos); + vec3f_copy(gLakituState.goalFocus, c->focus); + vec3f_copy(gLakituState.pos, c->pos); + vec3f_copy(gLakituState.focus, c->focus); + if (c->mode == CAMERA_MODE_FIXED) { + set_fixed_cam_axis_sa_lobby(c->mode); } - func_80284CBC(c); - gCameraStatus.trueYaw = calculate_yaw(c->focus, c->pos); - gCameraStatus.storedYaw = gCameraStatus.trueYaw; - c->trueYaw = gCameraStatus.trueYaw; - c->storedYaw = gCameraStatus.trueYaw; + store_lakitu_cam_info_for_c_up(c); + gLakituState.yaw = calculate_yaw(c->focus, c->pos); + gLakituState.nextYaw = gLakituState.yaw; + c->yaw = gLakituState.yaw; + c->nextYaw = gLakituState.yaw; } -extern u8 zoomOutAreaMasks[20]; - -void func_80287404(struct GraphNodeCamera *a) { +/** + * Zooms out the camera if paused and the level is 'outside', as determined by sZoomOutAreaMasks. + * + * Because gCurrLevelArea is assigned gCurrLevelNum * 16 + gCurrentArea->index, + * dividing by 32 maps 2 levels to one index. + * + * areaBit definition: + * (gCurrLevelArea & 0x10) / 4): + * This adds 4 to the shift if the level is an odd multiple of 16 + * + * ((gCurrLevelArea & 0xF) - 1) & 3): + * This isolates the lower 16 'area' bits, subtracts 1 because areas are 1-indexed, and effectively + * modulo-4's the result, because each 8-bit mask only has 4 area bits for each level + */ +void zoom_out_if_paused_and_outside(struct GraphNodeCamera *camera) { UNUSED u8 unused1[8]; - f32 sp34; - s16 sp32; - s16 sp30; + UNUSED f32 dist; + UNUSED s16 pitch; + s16 yaw; UNUSED u8 unused2[4]; - s32 sp28 = gCurrLevelArea / 32; - s32 sp24 = 1 << (((gCurrLevelArea & 0x10) / 4) + (((gCurrLevelArea & 0xF) - 1) & 3)); + s32 areaMaskIndex = gCurrLevelArea / 32; + s32 areaBit = 1 << (((gCurrLevelArea & 0x10) / 4) + (((gCurrLevelArea & 0xF) - 1) & 3)); - if (sp28 >= ARRAY_COUNT(zoomOutAreaMasks) - 1) { - sp28 = 0; - sp24 = 0; + if (areaMaskIndex >= LEVEL_MAX / 2) { + areaMaskIndex = 0; + areaBit = 0; } if (gCameraMovementFlags & CAM_MOVE_PAUSE_SCREEN) { - if (gFramesPaused >= 2) { - if (zoomOutAreaMasks[sp28] & sp24) { - a->to[0] = gCurrLevelCamera->xFocus; - a->to[1] = (sMarioStatusForCamera->pos[1] + gCurrLevelCamera->unk68) / 2.f; - a->to[2] = gCurrLevelCamera->zFocus; - vec3f_get_dist_and_angle(a->to, sMarioStatusForCamera->pos, &sp34, &sp32, &sp30); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, a->from, 6000.f, 4096, sp30); + if (sFramesPaused > 1) { + if (sZoomOutAreaMasks[areaMaskIndex] & areaBit) { + + camera->focus[0] = gCamera->areaCenX; + camera->focus[1] = (sMarioCamState->pos[1] + gCamera->areaCenY) / 2.f; + camera->focus[2] = gCamera->areaCenZ; + vec3f_get_dist_and_angle(camera->focus, sMarioCamState->pos, &dist, &pitch, &yaw); + vec3f_set_dist_and_angle(sMarioCamState->pos, camera->pos, 6000.f, 0x1000, yaw); if (gCurrLevelNum != LEVEL_THI) { - find_in_bounds_yaw_wdw_bob_thi(a->from, a->to, 0); + find_in_bounds_yaw_wdw_bob_thi(camera->pos, camera->focus, 0); } } } else { - gFramesPaused++; + sFramesPaused++; } } else { - gFramesPaused = 0; + sFramesPaused = 0; } } void select_mario_cam_mode(void) { - gCameraModeFlags = CAM_MODE_MARIO_SELECTED; + sSelectionFlags = CAM_MODE_MARIO_SELECTED; } -void func_802875F8(struct GraphNodeCamera *a, struct AllocOnlyPool *b) { - s16 preset = a->config.preset; - struct LevelCamera *c = alloc_only_pool_alloc(b, sizeof(struct LevelCamera)); +/** + * Allocate the GraphNodeCamera's config.camera, and copy `c`'s focus to the Camera's area center point. + */ +void create_camera(struct GraphNodeCamera *gc, struct AllocOnlyPool *pool) { + s16 mode = gc->config.mode; + struct Camera *c = alloc_only_pool_alloc(pool, sizeof(struct Camera)); - a->config.levelCamera = c; - c->currPreset = preset; - c->defPreset = preset; + gc->config.camera = c; + c->mode = mode; + c->defMode = mode; c->cutscene = 0; - c->unk64 = 0; - c->xFocus = a->to[0]; - c->unk68 = a->to[1]; - c->zFocus = a->to[2]; - c->trueYaw = 0; - vec3f_copy(c->pos, a->from); - vec3f_copy(c->focus, a->to); + c->doorStatus = DOOR_DEFAULT; + c->areaCenX = gc->focus[0]; + c->areaCenY = gc->focus[1]; + c->areaCenZ = gc->focus[2]; + c->yaw = 0; + vec3f_copy(c->pos, gc->pos); + vec3f_copy(c->focus, gc->focus); } -void func_802876D0(struct GraphNodeCamera *a) { +/** + * Copy lakitu's pos and foc into `gc` + */ +void update_graph_node_camera(struct GraphNodeCamera *gc) { UNUSED u8 unused[8]; - UNUSED struct LevelCamera *c = a->config.levelCamera; + UNUSED struct Camera *c = gc->config.camera; - a->rollScreen = gCameraStatus.roll; - vec3f_copy(a->from, gCameraStatus.pos); - vec3f_copy(a->to, gCameraStatus.focus); - func_80287404(a); + gc->rollScreen = gLakituState.roll; + vec3f_copy(gc->pos, gLakituState.pos); + vec3f_copy(gc->focus, gLakituState.focus); + zoom_out_if_paused_and_outside(gc); } -Gfx *geo_camera_preset_and_pos(s32 a, struct GraphNode *b, struct AllocOnlyPool *c) { - struct GraphNodeCamera *sp2C = (struct GraphNodeCamera *) b; - UNUSED struct AllocOnlyPool *sp28 = c; +Gfx *geo_camera_main(s32 callContext, struct GraphNode *g, void *context) { + struct GraphNodeCamera *gc = (struct GraphNodeCamera *) g; + UNUSED Mat4 *unusedMat = context; - switch (a) { + switch (callContext) { case GEO_CONTEXT_CREATE: - func_802875F8(sp2C, c); + create_camera(gc, context); break; case GEO_CONTEXT_RENDER: - func_802876D0(sp2C); + update_graph_node_camera(gc); break; } return NULL; } -void dummy_802877D8(UNUSED struct LevelCamera *c) { +void dummy_802877D8(UNUSED struct Camera *c) { } -void dummy_802877EC(UNUSED struct LevelCamera *c) { +void dummy_802877EC(UNUSED struct Camera *c) { } void vec3f_sub(Vec3f dst, Vec3f src) { @@ -2753,8 +3496,6 @@ void unused_object_angle_to_vec3s(Vec3s dst, struct Object *o) { dst[2] = o->oMoveAngleRoll; } -extern f32 unused_80336160; - /** * Produces values using a cubic b-spline curve. Basically Q is the used output, * u is a value between 0 and 1 that represents the position along the spline, @@ -2792,15 +3533,15 @@ void evaluate_cubic_spline(f32 u, Vec3f Q, Vec3f a0, Vec3f a1, Vec3f a2, Vec3f a y = B[0] * a0[1] + B[1] * a1[1] + B[2] * a2[1] + B[3] * a3[1]; z = B[0] * a0[2] + B[1] * a1[2] + B[2] * a2[2] + B[3] * a3[2]; - unused_spline_pitch = atan2s(sqrtf(x * x + z * z), y); - unused_spline_yaw = atan2s(z, x); + unusedSplinePitch = atan2s(sqrtf(x * x + z * z), y); + unusedSplineYaw = atan2s(z, x); } /** * Computes the point that is `progress` percent of the way through segment `splineSegment` of `spline`, * and stores the result in `p`. `progress` and `splineSegment` are updated if `progress` becomes >= 1.0. * - * When neither of next two points' speeds == 0, the number of frames is between 1 and 255. Otherwise + * When neither of the next two points' speeds == 0, the number of frames is between 1 and 255. Otherwise * it's infinite. * * To calculate the number of frames it will take to progress through a spline segment: @@ -2851,13 +3592,13 @@ s32 move_point_along_spline(Vec3f p, struct CutsceneSplinePoint spline[], s16 *s progressChange = (secondSpeed - firstSpeed) * *progress + firstSpeed; #ifdef VERSION_EU - if (gCurrLevelCamera->cutscene == CUTSCENE_INTRO_PEACH) { + if (gCamera->cutscene == CUTSCENE_INTRO_PEACH) { progressChange += progressChange * 0.19f; } - if (gCurrLevelCamera->cutscene == CUTSCENE_CREDITS) { + if (gCamera->cutscene == CUTSCENE_CREDITS) { progressChange += progressChange * 0.15f; } - if (gCurrLevelCamera->cutscene == CUTSCENE_PEACH_END) { + if (gCamera->cutscene == CUTSCENE_ENDING) { progressChange += progressChange * 0.1f; } #endif @@ -2873,183 +3614,223 @@ s32 move_point_along_spline(Vec3f p, struct CutsceneSplinePoint spline[], s16 *s return finished; } -s32 select_or_activate_mario_cam(s32 angle) { - s32 sp1C = 2; +/** + * If `selection` is 0, just get the current selection + * If `selection` is 1, select 'mario' as the alt mode. + * If `selection` is 2, select 'fixed' as the alt mode. + * + * @return the current selection + */ +s32 cam_select_alt_mode(s32 selection) { + s32 mode = CAM_SELECTION_FIXED; - if (angle == CAM_ANGLE_LAKITU_MARIO) { - if (!(gCameraModeFlags & CAM_MODE_MARIO_SELECTED)) { - gCameraModeFlags |= CAM_MODE_MARIO_SELECTED; + if (selection == CAM_SELECTION_MARIO) { + if (!(sSelectionFlags & CAM_MODE_MARIO_SELECTED)) { + sSelectionFlags |= CAM_MODE_MARIO_SELECTED; } - gCameraFlags1 |= CAM_FLAG_1_UNUSED_3; + sCameraSoundFlags |= CAM_SOUND_UNUSED_SELECT_MARIO; } - if (angle == CAM_ANGLE_LAKITU_FIXED && (gCameraModeFlags & CAM_MODE_MARIO_SELECTED)) { - test_or_set_mario_cam_active(2); - gCameraModeFlags &= ~CAM_MODE_MARIO_SELECTED; - gCameraFlags1 |= CAM_FLAG_1_UNUSED_4; + + // The alternate mode is up-close, but the player just selected fixed in the pause menu + if (selection == CAM_SELECTION_FIXED && (sSelectionFlags & CAM_MODE_MARIO_SELECTED)) { + // So change to normal mode in case the user paused in up-close mode + set_cam_angle(CAM_ANGLE_LAKITU); + sSelectionFlags &= ~CAM_MODE_MARIO_SELECTED; + sCameraSoundFlags |= CAM_SOUND_UNUSED_SELECT_FIXED; } - if (gCameraModeFlags & CAM_MODE_MARIO_SELECTED) { - sp1C = 1; + + if (sSelectionFlags & CAM_MODE_MARIO_SELECTED) { + mode = CAM_SELECTION_MARIO; } - return sp1C; + return mode; } -s32 test_or_set_mario_cam_active(s32 a) { - s32 sp4 = 2; +/** + * Sets the camera angle to either lakitu or mario mode. Returns the current mode. + * + * If `mode` is 0, just returns the current mode. + * If `mode` is 1, start mario mode + * If `mode` is 2, start lakitu mode + */ +s32 set_cam_angle(s32 mode) { + s32 curMode = CAM_ANGLE_LAKITU; - if (a == 1 && !(gCameraModeFlags & CAM_MODE_MARIO_ACTIVE)) { - gCameraModeFlags |= CAM_MODE_MARIO_ACTIVE; + // Switch to mario mode + if (mode == CAM_ANGLE_MARIO && !(sSelectionFlags & CAM_MODE_MARIO_ACTIVE)) { + sSelectionFlags |= CAM_MODE_MARIO_ACTIVE; if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - gCameraModeFlags |= CAM_MODE_LAKITU_WAS_ZOOMED_OUT; + sSelectionFlags |= CAM_MODE_LAKITU_WAS_ZOOMED_OUT; gCameraMovementFlags &= ~CAM_MOVE_ZOOMED_OUT; } - gCameraFlags1 |= CAM_FLAG_1_UNKNOWN_1; + sCameraSoundFlags |= CAM_SOUND_MARIO_ACTIVE; } - if (a == 2 && (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE)) { - gCameraModeFlags &= ~CAM_MODE_MARIO_ACTIVE; - if (gCameraModeFlags & CAM_MODE_LAKITU_WAS_ZOOMED_OUT) { - gCameraModeFlags &= ~CAM_MODE_LAKITU_WAS_ZOOMED_OUT; + + // Switch back to normal mode + if (mode == CAM_ANGLE_LAKITU && (sSelectionFlags & CAM_MODE_MARIO_ACTIVE)) { + sSelectionFlags &= ~CAM_MODE_MARIO_ACTIVE; + if (sSelectionFlags & CAM_MODE_LAKITU_WAS_ZOOMED_OUT) { + sSelectionFlags &= ~CAM_MODE_LAKITU_WAS_ZOOMED_OUT; gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT; } else { gCameraMovementFlags &= ~CAM_MOVE_ZOOMED_OUT; } - gCameraFlags1 |= CAM_FLAG_1_UNKNOWN_2; + sCameraSoundFlags |= CAM_SOUND_NORMAL_ACTIVE; } - if (gCameraModeFlags & CAM_MODE_MARIO_ACTIVE) { - sp4 = 1; + if (sSelectionFlags & CAM_MODE_MARIO_ACTIVE) { + curMode = CAM_ANGLE_MARIO; } - return sp4; + return curMode; } -void set_spline_values(u8 a) { - switch (a) { - case 1: - sSplineParameterMax = 1536; - sSplinePositionLimit = 0.04f; +/** + * Enables the handheld shake effect for this frame. + * + * @see shake_camera_handheld() + */ +void set_handheld_shake(u8 mode) { + switch (mode) { + // They're not in numerical order because that would be too simple... + case HAND_CAM_SHAKE_CUTSCENE: // Lowest increment + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.04f; break; - case 6: - sSplineParameterMax = 768; - sSplinePositionLimit = 0.06f; + case HAND_CAM_SHAKE_LOW: // Lowest magnitude + sHandheldShakeMag = 0x300; + sHandheldShakeInc = 0.06f; break; - case 4: - sSplineParameterMax = 4096; - sSplinePositionLimit = 0.1f; + case HAND_CAM_SHAKE_HIGH: // Highest mag and inc + sHandheldShakeMag = 0x1000; + sHandheldShakeInc = 0.1f; break; - case 2: - sSplineParameterMax = 1536; - sSplinePositionLimit = 0.07f; + case HAND_CAM_SHAKE_UNUSED: // Never used + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.07f; break; - case 3: - sSplineParameterMax = 1536; - sSplinePositionLimit = 0.07f; + case HAND_CAM_SHAKE_HANG_OWL: // exactly the same as UNUSED... + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.07f; break; - case 5: - sSplineParameterMax = 1024; - sSplinePositionLimit = 0.07f; + case HAND_CAM_SHAKE_STAR_DANCE: // Slightly steadier than HANG_OWL and UNUSED + sHandheldShakeMag = 0x400; + sHandheldShakeInc = 0.07f; break; default: - sSplineParameterMax = 0; - sSplinePositionLimit = 0.f; + sHandheldShakeMag = 0x0; + sHandheldShakeInc = 0.f; } } -extern s16 unused_8033B2C0[][8]; - -void set_face_angle_from_spline(Vec3f pos, Vec3f focus) { +/** + * When sHandheldShakeMag is nonzero, this function adds small random offsets to `focus` every time + * sHandheldShakeTimer increases above 1.0, simulating the camera shake caused by unsteady hands. + * + * This function must be called every frame in order to actually apply the effect, since the effect's + * mag and inc are set to 0 every frame at the end of this function. + */ +void shake_camera_handheld(Vec3f pos, Vec3f focus) { s32 i; - Vec3f faceAngleOffsetGoal; - Vec3f splineParameters[4]; + Vec3f shakeOffset; + Vec3f shakeSpline[4]; f32 dist; s16 pitch; s16 yaw; UNUSED u8 unused[8]; - if (sSplineParameterMax == 0) { - vec3f_set(faceAngleOffsetGoal, 0.f, 0.f, 0.f); + if (sHandheldShakeMag == 0) { + vec3f_set(shakeOffset, 0.f, 0.f, 0.f); } else { for (i = 0; i < 4; i++) { - splineParameters[i][0] = sSplineParameters[i].myUnion.unk8[0]; - splineParameters[i][1] = sSplineParameters[i].myUnion.unk8[1]; - splineParameters[i][2] = sSplineParameters[i].myUnion.unk8[2]; + shakeSpline[i][0] = sHandheldShakeSpline[i].point[0]; + shakeSpline[i][1] = sHandheldShakeSpline[i].point[1]; + shakeSpline[i][2] = sHandheldShakeSpline[i].point[2]; } - evaluate_cubic_spline(sPositionAlongSpline, faceAngleOffsetGoal, splineParameters[0], - splineParameters[1], splineParameters[2], splineParameters[3]); - if (1.f <= (sPositionAlongSpline += sSplinePositionLimit)) { + evaluate_cubic_spline(sHandheldShakeTimer, shakeOffset, shakeSpline[0], + shakeSpline[1], shakeSpline[2], shakeSpline[3]); + if (1.f <= (sHandheldShakeTimer += sHandheldShakeInc)) { + // The first 3 control points are always (0,0,0), so the random spline is always just a + // straight line for (i = 0; i < 3; i++) { - vec3s_copy(sSplineParameters[i].myUnion.unk8, sSplineParameters[i + 1].myUnion.unk8); + vec3s_copy(sHandheldShakeSpline[i].point, sHandheldShakeSpline[i + 1].point); } - random_vec3s(sSplineParameters[3].myUnion.unk8, sSplineParameterMax, sSplineParameterMax, - sSplineParameterMax / 2); - sPositionAlongSpline -= 1.f; + random_vec3s(sHandheldShakeSpline[3].point, sHandheldShakeMag, sHandheldShakeMag, sHandheldShakeMag / 2); + sHandheldShakeTimer -= 1.f; // Code dead, this is set to be 0 before it is used. - sSplinePositionLimit = RandomFloat() * 0.5f; - if (sSplinePositionLimit < 0.02f) { - sSplinePositionLimit = 0.02f; + sHandheldShakeInc = RandomFloat() * 0.5f; + if (sHandheldShakeInc < 0.02f) { + sHandheldShakeInc = 0.02f; } } } - approach_s16_exponential_bool(&sCameraCutscenePitchOffset, faceAngleOffsetGoal[0], 0x08); - approach_s16_exponential_bool(&sCameraCutsceneYawOffset, faceAngleOffsetGoal[1], 0x08); - approach_s16_exponential_bool(&sCameraCutsceneRollOffset, faceAngleOffsetGoal[2], 0x08); + approach_s16_asymptotic_bool(&sHandheldShakePitch, shakeOffset[0], 0x08); + approach_s16_asymptotic_bool(&sHandheldShakeYaw, shakeOffset[1], 0x08); + approach_s16_asymptotic_bool(&sHandheldShakeRoll, shakeOffset[2], 0x08); - if (sCameraCutscenePitchOffset | sCameraCutsceneYawOffset) { + if (sHandheldShakePitch | sHandheldShakeYaw) { vec3f_get_dist_and_angle(pos, focus, &dist, &pitch, &yaw); - pitch += sCameraCutscenePitchOffset; - yaw += sCameraCutsceneYawOffset; + pitch += sHandheldShakePitch; + yaw += sHandheldShakeYaw; vec3f_set_dist_and_angle(pos, focus, dist, pitch, yaw); } - sSplineParameterMax = 0; - sSplinePositionLimit = 0.f; + // Unless called every frame, the effect will stop after the first time. + sHandheldShakeMag = 0; + sHandheldShakeInc = 0.f; } -s32 find_c_buttons_pressed(u16 a, u16 buttonsPressed, u16 buttonsDown) { +/** + * Updates C Button input state and stores it in `currentState` + */ +s32 find_c_buttons_pressed(u16 currentState, u16 buttonsPressed, u16 buttonsDown) { buttonsPressed &= CBUTTON_MASK; buttonsDown &= CBUTTON_MASK; if (buttonsPressed & L_CBUTTONS) { - a |= 2; - a &= ~1; + currentState |= L_CBUTTONS; + currentState &= ~R_CBUTTONS; } if (!(buttonsDown & L_CBUTTONS)) { - a &= ~2; + currentState &= ~L_CBUTTONS; } if (buttonsPressed & R_CBUTTONS) { - a |= 1; - a &= ~2; + currentState |= R_CBUTTONS; + currentState &= ~L_CBUTTONS; } if (!(buttonsDown & R_CBUTTONS)) { - a &= ~1; + currentState &= ~R_CBUTTONS; } if (buttonsPressed & U_CBUTTONS) { - a |= 8; - a &= ~4; + currentState |= U_CBUTTONS; + currentState &= ~D_CBUTTONS; } if (!(buttonsDown & U_CBUTTONS)) { - a &= ~8; + currentState &= ~U_CBUTTONS; } if (buttonsPressed & D_CBUTTONS) { - a |= 4; - a &= ~8; + currentState |= D_CBUTTONS; + currentState &= ~U_CBUTTONS; } if (!(buttonsDown & D_CBUTTONS)) { - a &= ~4; + currentState &= ~D_CBUTTONS; } - return a; + return currentState; } -s32 update_camera_status(struct LevelCamera *c) { +/** + * Determine which icon to show on the HUD + */ +s32 update_camera_hud_status(struct Camera *c) { s16 status = CAM_STATUS_NONE; if (c->cutscene != 0 - || ((gPlayer1Controller->buttonDown & R_TRIG) && select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_FIXED)) { + || ((gPlayer1Controller->buttonDown & R_TRIG) && cam_select_alt_mode(0) == CAM_SELECTION_FIXED)) { status |= CAM_STATUS_FIXED; - } else if (test_or_set_mario_cam_active(0) == CAM_ANGLE_LAKITU_MARIO) { + } else if (set_cam_angle(0) == CAM_ANGLE_MARIO) { status |= CAM_STATUS_MARIO; } else { status |= CAM_STATUS_LAKITU; @@ -3064,7 +3845,12 @@ s32 update_camera_status(struct LevelCamera *c) { return status; } -s32 find_and_return_count_wall_collisions(Vec3f pos, f32 offsetY, f32 radius) { +/** + * Check `pos` for collisions within `radius`, and update `pos` + * + * @return the number of collisions found + */ +s32 collide_with_walls(Vec3f pos, f32 offsetY, f32 radius) { struct WallCollisionData collisionData; struct Surface *wall = NULL; f32 normX; @@ -3115,23 +3901,23 @@ s32 vec3f_compare(Vec3f pos, f32 posX, f32 posY, f32 posZ) { return equal; } -s32 clamp_pitch(Vec3f a, Vec3f b, s16 maxPitch, s16 minPitch) { - s32 pitchChanged = 0; +s32 clamp_pitch(Vec3f from, Vec3f to, s16 maxPitch, s16 minPitch) { + s32 outOfRange = 0; s16 pitch; s16 yaw; f32 dist; - vec3f_get_dist_and_angle(a, b, &dist, &pitch, &yaw); + vec3f_get_dist_and_angle(from, to, &dist, &pitch, &yaw); if (pitch > maxPitch) { pitch = maxPitch; - pitchChanged++; + outOfRange++; } if (pitch < minPitch) { pitch = minPitch; - pitchChanged++; + outOfRange++; } - vec3f_set_dist_and_angle(a, b, dist, pitch, yaw); - return pitchChanged; + vec3f_set_dist_and_angle(from, to, dist, pitch, yaw); + return outOfRange; } s32 is_within_100_units_of_mario(f32 posX, f32 posY, f32 posZ) { @@ -3139,15 +3925,15 @@ s32 is_within_100_units_of_mario(f32 posX, f32 posY, f32 posZ) { Vec3f pos; vec3f_set(pos, posX, posY, posZ); - if (calc_abs_dist(sMarioStatusForCamera->pos, pos) < 100.f) { + if (calc_abs_dist(sMarioCamState->pos, pos) < 100.f) { isCloseToMario = 1; } return isCloseToMario; } -s32 set_or_approach_f32_exponential(f32 *dst, f32 goal, f32 scale) { - if (gCameraFlags2 & CAM_FLAG_2_SMOOTH_MOVEMENT) { - approach_f32_exponential_bool(dst, goal, scale); +s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale) { + if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { + approach_f32_asymptotic_bool(dst, goal, scale); } else { *dst = goal; } @@ -3163,7 +3949,7 @@ s32 set_or_approach_f32_exponential(f32 *dst, f32 goal, f32 scale) { * and adding a fraction of that to the current value. * Edits the current value directly, returns TRUE if the target has been reached, FALSE otherwise. */ -s32 approach_f32_exponential_bool(f32 *current, f32 target, f32 multiplier) { +s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier) { if (multiplier > 1.f) { multiplier = 1.f; } @@ -3178,17 +3964,17 @@ s32 approach_f32_exponential_bool(f32 *current, f32 target, f32 multiplier) { /** * Nearly the same as the above function, returns new value instead. */ -f32 approach_f32_exponential(f32 current, f32 target, f32 multiplier) { +f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier) { current = current + (target - current) * multiplier; return current; } /** - * Approaches an s16 value in the same fashion as approach_f32_exponential_bool, returns TRUE if target + * Approaches an s16 value in the same fashion as approach_f32_asymptotic_bool, returns TRUE if target * is reached. Note: Since this function takes integers as parameters, the last argument is the * reciprocal of what it would be in the previous two functions. */ -s32 approach_s16_exponential_bool(s16 *current, s16 target, s16 divisor) { +s32 approach_s16_asymptotic_bool(s16 *current, s16 target, s16 divisor) { s16 temp = *current; if (divisor == 0) { @@ -3207,10 +3993,10 @@ s32 approach_s16_exponential_bool(s16 *current, s16 target, s16 divisor) { } /** - * Approaches an s16 value in the same fashion as approach_f32_exponential, returns the new value. + * Approaches an s16 value in the same fashion as approach_f32_asymptotic, returns the new value. * Note: last parameter is the reciprocal of what it would be in the f32 functions */ -s32 approach_s16_exponential(s16 current, s16 target, s16 divisor) { +s32 approach_s16_asymptotic(s16 current, s16 target, s16 divisor) { s16 temp = current; if (divisor == 0) { @@ -3225,35 +4011,37 @@ s32 approach_s16_exponential(s16 current, s16 target, s16 divisor) { } /** - * Applies the approach_f32_exponential_bool function to each of the X, Y, & Z components of the given + * Applies the approach_f32_asymptotic_bool function to each of the X, Y, & Z components of the given * vector. */ -void approach_vec3f_exponential(Vec3f current, Vec3f target, f32 x_multiplier, f32 y_multiplier, - f32 z_multiplier) { - approach_f32_exponential_bool(¤t[0], target[0], x_multiplier); - approach_f32_exponential_bool(¤t[1], target[1], y_multiplier); - approach_f32_exponential_bool(¤t[2], target[2], z_multiplier); -} - -void set_or_approach_vec3f_exponential(Vec3f dst, Vec3f goal, f32 xScale, f32 yScale, f32 zScale) { - set_or_approach_f32_exponential(&dst[0], goal[0], xScale); - set_or_approach_f32_exponential(&dst[1], goal[1], yScale); - set_or_approach_f32_exponential(&dst[2], goal[2], zScale); +void approach_vec3f_asymptotic(Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul) { + approach_f32_asymptotic_bool(¤t[0], target[0], xMul); + approach_f32_asymptotic_bool(¤t[1], target[1], yMul); + approach_f32_asymptotic_bool(¤t[2], target[2], zMul); } /** - * Applies the approach_s32_exponential function to each of the X, Y, & Z components of the given - * vector. + * Applies the set_or_approach_f32_asymptotic_bool function to each of the X, Y, & Z components of the + * given vector. */ -void approach_vec3s_exponential(Vec3s current, Vec3s target, s16 x_multiplier, s16 y_multiplier, - s16 z_multiplier) { - approach_s16_exponential_bool(¤t[0], target[0], x_multiplier); - approach_s16_exponential_bool(¤t[1], target[1], y_multiplier); - approach_s16_exponential_bool(¤t[2], target[2], z_multiplier); +void set_or_approach_vec3f_asymptotic(Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul) { + set_or_approach_f32_asymptotic(&dst[0], goal[0], xMul); + set_or_approach_f32_asymptotic(&dst[1], goal[1], yMul); + set_or_approach_f32_asymptotic(&dst[2], goal[2], zMul); } -s32 camera_approach_s16_symmetric_bool(s16 *value, s16 target, s16 increment) { - s16 dist = target - *value; +/** + * Applies the approach_s32_asymptotic function to each of the X, Y, & Z components of the given + * vector. + */ +void approach_vec3s_asymptotic(Vec3s current, Vec3s target, s16 xMul, s16 yMul, s16 zMul) { + approach_s16_asymptotic_bool(¤t[0], target[0], xMul); + approach_s16_asymptotic_bool(¤t[1], target[1], yMul); + approach_s16_asymptotic_bool(¤t[2], target[2], zMul); +} + +s32 camera_approach_s16_symmetric_bool(s16 *current, s16 target, s16 increment) { + s16 dist = target - *current; if (increment < 0) { increment = -1 * increment; @@ -3261,27 +4049,27 @@ s32 camera_approach_s16_symmetric_bool(s16 *value, s16 target, s16 increment) { if (dist > 0) { dist -= increment; if (dist >= 0) { - *value = target - dist; + *current = target - dist; } else { - *value = target; + *current = target; } } else { dist += increment; if (dist <= 0) { - *value = target - dist; + *current = target - dist; } else { - *value = target; + *current = target; } } - if (*value == target) { + if (*current == target) { return FALSE; } else { return TRUE; } } -s32 camera_approach_s16_symmetric(s16 value, s16 target, s16 increment) { - s16 dist = target - value; +s32 camera_approach_s16_symmetric(s16 current, s16 target, s16 increment) { + s16 dist = target - current; if (increment < 0) { increment = -1 * increment; @@ -3289,28 +4077,28 @@ s32 camera_approach_s16_symmetric(s16 value, s16 target, s16 increment) { if (dist > 0) { dist -= increment; if (dist >= 0) { - value = target - dist; + current = target - dist; } else { - value = target; + current = target; } } else { dist += increment; if (dist <= 0) { - value = target - dist; + current = target - dist; } else { - value = target; + current = target; } } - return value; + return current; } -s32 set_or_approach_s16_symmetric(s16 *value, s16 target, s16 increment) { - if (gCameraFlags2 & CAM_FLAG_2_SMOOTH_MOVEMENT) { - camera_approach_s16_symmetric_bool(value, target, increment); +s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment) { + if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { + camera_approach_s16_symmetric_bool(current, target, increment); } else { - *value = target; + *current = target; } - if (*value == target) { + if (*current == target) { return FALSE; } else { return TRUE; @@ -3401,49 +4189,55 @@ void random_vec3s(Vec3s dst, s16 xRange, s16 yRange, s16 zRange) { dst[2] = randomFloat * tempZRange - tempZRange / 2; } -s16 func_80289738(s16 a, f32 b, f32 c, f32 d, f32 e) { - Vec3f sp3C; - f32 sp38; - s16 sp36; - s16 sp34; - s16 sp32; - s16 sp30; - s16 sp2E = 0; - f32 sp28 = gCameraStatus.camFocAndPosCurrAndGoal[3][0] - c; - f32 sp24 = gCameraStatus.camFocAndPosCurrAndGoal[3][1] - d; - f32 sp20 = gCameraStatus.camFocAndPosCurrAndGoal[3][2] - e; +/** + * Decrease value by multiplying it by the distance from (`posX`, `posY`, `posZ`) to + * the camera divided by `maxDist` + * + * @return the reduced value + */ +s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 posZ) { + Vec3f pos; + f32 dist; + s16 pitch; + s16 yaw; + s16 goalPitch; + s16 goalYaw; + s16 result = 0; + // Direction from pos to (lakitu's) goalPos + f32 goalDX = gLakituState.goalPos[0] - posX; + f32 goalDY = gLakituState.goalPos[1] - posY; + f32 goalDZ = gLakituState.goalPos[2] - posZ; - sp38 = sqrtf(sp28 * sp28 + sp24 * sp24 + sp20 * sp20); - if (b > sp38) { - sp3C[0] = c; - sp3C[1] = d; - sp3C[2] = e; - vec3f_get_dist_and_angle(gCameraStatus.camFocAndPosCurrAndGoal[3], sp3C, &sp38, &sp36, &sp34); - if (sp38 < b) { - calculate_angles(gCameraStatus.camFocAndPosCurrAndGoal[3], - gCameraStatus.camFocAndPosCurrAndGoal[2], &sp32, &sp30); - sp36 -= sp32; - sp34 -= sp30; - sp38 -= 2000.f; - if (sp38 < 0.f) { - sp38 = 0.f; + dist = sqrtf(goalDX * goalDX + goalDY * goalDY + goalDZ * goalDZ); + if (maxDist > dist) { + pos[0] = posX; + pos[1] = posY; + pos[2] = posZ; + vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &pitch, &yaw); + if (dist < maxDist) { + calculate_angles(gLakituState.goalPos, gLakituState.goalFocus, &goalPitch, &goalYaw); + pitch -= goalPitch; + yaw -= goalYaw; + dist -= 2000.f; + if (dist < 0.f) { + dist = 0.f; } - b -= 2000.f; - if (b < 2000.f) { - b = 2000.f; + maxDist -= 2000.f; + if (maxDist < 2000.f) { + maxDist = 2000.f; } - sp2E = a * (1.f - sp38 / b); - if (sp36 < -0x1800 || sp36 > 0x400 || sp34 < -0x1800 || sp34 > 0x1800) { - sp2E /= 2; + result = value * (1.f - dist / maxDist); + if (pitch < -0x1800 || pitch > 0x400 || + yaw < -0x1800 || yaw > 0x1800) { + result /= 2; } } } - return sp2E; + return result; } -s32 clamp_positions_and_find_yaw_angle(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, - f32 zMin) { - s16 yaw = gCurrLevelCamera->storedYaw; +s32 clamp_positions_and_find_yaw(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin) { + s16 yaw = gCamera->nextYaw; if (pos[0] >= xMax) { pos[0] = xMax; @@ -3461,123 +4255,159 @@ s32 clamp_positions_and_find_yaw_angle(Vec3f pos, Vec3f origin, f32 xMax, f32 xM return yaw; } -s32 func_80289A98(s16 a, s16 b) { - s16 sp2E; - UNUSED u8 unused[34]; - UNUSED s32 sp8 = 0; - UNUSED s32 sp4 = 0; +/** + * The yaw passed here is the yaw of the direction FROM mario TO lakitu. + * + * wallYaw always has 90 degrees added to it before this is called -- it's parallel to the wall. + * + * @return the new yaw from mario to rotate towards. + * + * @warning this is jank. It actually returns the yaw that will rotate further INTO the wall. So, the + * developers just add 180 degrees to the result. + */ +s32 calc_avoid_yaw(s16 yawFromMario, s16 wallYaw) { + s16 yawDiff; + UNUSED u8 unused[34]; // Debug print buffer? ;) + UNUSED s32 unused1 = 0; + UNUSED s32 unused2 = 0; - sp2E = b - a + 0x4000; - if (sp2E < 0) { - a = b; + yawDiff = wallYaw - yawFromMario + DEGREES(90); + + if (yawDiff < 0) { + // Deflect to the right + yawFromMario = wallYaw; } else { - a = b + 0x8000; + // Note: this favors the left side if the wall is exactly perpendicular to the camera. + // Deflect to the left + yawFromMario = wallYaw + DEGREES(180); } - return a; + return yawFromMario; } -s32 is_pos_less_than_bounds(struct Surface *surf, f32 xMax, f32 yMax, f32 zMax) { - Vec3s posX; - Vec3s posY; - Vec3s posZ; - s16 testX = 0; - s16 testY = 0; - s16 testZ = 0; +/** + * Checks if `surf` is within the rect prism defined by xMax, yMax, and zMax + * + * @param surf surface to check + * @param xMax absolute-value max size in x, set to -1 to ignore + * @param yMax absolute-value max size in y, set to -1 to ignore + * @param zMax absolute-value max size in z, set to -1 to ignore + */ +s32 is_surf_within_bounding_box(struct Surface *surf, f32 xMax, f32 yMax, f32 zMax) { + // Surface vertex coordinates + Vec3s sx; + Vec3s sy; + Vec3s sz; + // Max delta between x, y, and z + s16 dxMax = 0; + s16 dyMax = 0; + s16 dzMax = 0; + // Current deltas between x, y, and z f32 dx; f32 dy; f32 dz; UNUSED u8 unused[4]; s32 i; s32 j; - s32 isWithinBounds = FALSE; + // result + s32 smaller = FALSE; + + sx[0] = surf->vertex1[0]; + sx[1] = surf->vertex2[0]; + sx[2] = surf->vertex3[0]; + sy[0] = surf->vertex1[1]; + sy[1] = surf->vertex2[1]; + sy[2] = surf->vertex3[1]; + sz[0] = surf->vertex1[2]; + sz[1] = surf->vertex2[2]; + sz[2] = surf->vertex3[2]; - posX[0] = surf->vertex1[0]; - posX[1] = surf->vertex2[0]; - posX[2] = surf->vertex3[0]; - posY[0] = surf->vertex1[1]; - posY[1] = surf->vertex2[1]; - posY[2] = surf->vertex3[1]; - posZ[0] = surf->vertex1[2]; - posZ[1] = surf->vertex2[2]; - posZ[2] = surf->vertex3[2]; for (i = 0; i < 3; i++) { j = i + 1; if (j >= 3) { j = 0; } - dx = ABS(posX[i] - posX[j]); - if (dx > testX) { - testX = dx; + dx = ABS(sx[i] - sx[j]); + if (dx > dxMax) { + dxMax = dx; } - dy = ABS(posY[i] - posY[j]); - if (dy > testY) { - testY = dy; + dy = ABS(sy[i] - sy[j]); + if (dy > dyMax) { + dyMax = dy; } - dz = ABS(posZ[i] - posZ[j]); - if (dz > testZ) { - testZ = dz; + dz = ABS(sz[i] - sz[j]); + if (dz > dzMax) { + dzMax = dz; } } if (yMax != -1.f) { - if (testY < yMax) { - isWithinBounds = TRUE; + if (dyMax < yMax) { + smaller = TRUE; } } if (xMax != -1.f && zMax != -1.f) { - if (testX < xMax && testZ < zMax) { - isWithinBounds = TRUE; + if (dxMax < xMax && dzMax < zMax) { + smaller = TRUE; } } - return isWithinBounds; + return smaller; } +/** + * Checks if `pos` is behind the surface, using the dot product. + * + * Because the function only uses `surf`s first vertex, some surfaces can shadow others. + */ s32 is_behind_surface(Vec3f pos, struct Surface *surf) { s32 behindSurface = 0; - f32 normX = (surf->vertex2[1] - surf->vertex1[1]) * (surf->vertex3[2] - surf->vertex2[2]) - - (surf->vertex3[1] - surf->vertex2[1]) * (surf->vertex2[2] - surf->vertex1[2]); - f32 normY = (surf->vertex2[2] - surf->vertex1[2]) * (surf->vertex3[0] - surf->vertex2[0]) - - (surf->vertex3[2] - surf->vertex2[2]) * (surf->vertex2[0] - surf->vertex1[0]); - f32 normZ = (surf->vertex2[0] - surf->vertex1[0]) * (surf->vertex3[1] - surf->vertex2[1]) - - (surf->vertex3[0] - surf->vertex2[0]) * (surf->vertex2[1] - surf->vertex1[1]); - f32 posX = surf->vertex1[0] - pos[0]; - f32 posY = surf->vertex1[1] - pos[1]; - f32 posZ = surf->vertex1[2] - pos[2]; + // Surface normal + f32 normX = (surf->vertex2[1] - surf->vertex1[1]) * (surf->vertex3[2] - surf->vertex2[2]) - + (surf->vertex3[1] - surf->vertex2[1]) * (surf->vertex2[2] - surf->vertex1[2]); + f32 normY = (surf->vertex2[2] - surf->vertex1[2]) * (surf->vertex3[0] - surf->vertex2[0]) - + (surf->vertex3[2] - surf->vertex2[2]) * (surf->vertex2[0] - surf->vertex1[0]); + f32 normZ = (surf->vertex2[0] - surf->vertex1[0]) * (surf->vertex3[1] - surf->vertex2[1]) - + (surf->vertex3[0] - surf->vertex2[0]) * (surf->vertex2[1] - surf->vertex1[1]); + f32 dirX = surf->vertex1[0] - pos[0]; + f32 dirY = surf->vertex1[1] - pos[1]; + f32 dirZ = surf->vertex1[2] - pos[2]; - if (posX * normX + posY * normY + posZ * normZ < 0) { + if (dirX * normX + dirY * normY + dirZ * normZ < 0) { behindSurface = 1; } return behindSurface; } -s32 func_8028A0D4(Vec3f a, Vec3f b, struct Surface *surf, s16 d, s16 surfType) { +/** + * Checks if the whole circular sector is behind the surface. + */ +s32 is_range_behind_surface(Vec3f from, Vec3f to, struct Surface *surf, s16 range, s16 surfType) { s32 behindSurface = TRUE; - s32 sp50 = 0; - s32 sp4C = 0; + s32 leftBehind = 0; + s32 rightBehind = 0; UNUSED u8 unused[20]; - f32 sp34; - s16 sp32; - s16 sp30; - Vec3f sp24; + f32 checkDist; + s16 checkPitch; + s16 checkYaw; + Vec3f checkPos; if (surf != NULL) { if (surfType == -1 || surf->type != surfType) { - if (d == 0) { - behindSurface = is_behind_surface(b, surf); + if (range == 0) { + behindSurface = is_behind_surface(to, surf); } else { - vec3f_get_dist_and_angle(a, b, &sp34, &sp32, &sp30); - vec3f_set_dist_and_angle(a, sp24, sp34, sp32, sp30 + d); - sp50 = is_behind_surface(sp24, surf); - vec3f_set_dist_and_angle(a, sp24, sp34, sp32, sp30 - d); - sp4C = is_behind_surface(sp24, surf); - behindSurface = sp50 * sp4C; + vec3f_get_dist_and_angle(from, to, &checkDist, &checkPitch, &checkYaw); + vec3f_set_dist_and_angle(from, checkPos, checkDist, checkPitch, checkYaw + range); + leftBehind = is_behind_surface(checkPos, surf); + vec3f_set_dist_and_angle(from, checkPos, checkDist, checkPitch, checkYaw - range); + rightBehind = is_behind_surface(checkPos, surf); + behindSurface = leftBehind * rightBehind; } } } return behindSurface; } -s32 is_mario_behind_surface(UNUSED struct LevelCamera *c, struct Surface *surf) { - s32 behindSurface = is_behind_surface(sMarioStatusForCamera->pos, surf); +s32 is_mario_behind_surface(UNUSED struct Camera *c, struct Surface *surf) { + s32 behindSurface = is_behind_surface(sMarioCamState->pos, surf); return behindSurface; } @@ -3586,57 +4416,61 @@ s32 is_mario_behind_surface(UNUSED struct LevelCamera *c, struct Surface *surf) * Calculates the distance between two points and sets a vector to a point * scaled along a line between them. Typically, somewhere in the middle. */ -void scale_along_line(Vec3f dest, Vec3f b, Vec3f c, f32 scale) { +void scale_along_line(Vec3f dst, Vec3f from, Vec3f to, f32 scale) { Vec3f tempVec; - tempVec[0] = (c[0] - b[0]) * scale + b[0]; - tempVec[1] = (c[1] - b[1]) * scale + b[1]; - tempVec[2] = (c[2] - b[2]) * scale + b[2]; - vec3f_copy(dest, tempVec); + tempVec[0] = (to[0] - from[0]) * scale + from[0]; + tempVec[1] = (to[1] - from[1]) * scale + from[1]; + tempVec[2] = (to[2] - from[2]) * scale + from[2]; + vec3f_copy(dst, tempVec); } /** * Effectively created a rectangular prism defined by a vector starting at the center * and extending to the corners. If the position is in this box, the function returns true. */ -s32 check_if_vector_fits_in_bounds(Vec3f pos, Vec3f center, Vec3f bounds, s16 angle) { +s32 is_pos_in_bounds(Vec3f pos, Vec3f center, Vec3f bounds, s16 boundsYaw) { s32 inBound = FALSE; - Vec3f vec; + Vec3f rel; - vec[0] = center[0] - pos[0]; - vec[1] = center[1] - pos[1]; - vec[2] = center[2] - pos[2]; + rel[0] = center[0] - pos[0]; + rel[1] = center[1] - pos[1]; + rel[2] = center[2] - pos[2]; - rotate_in_xz(vec, vec, angle); + rotate_in_xz(rel, rel, boundsYaw); - if (-bounds[0] < vec[0] && vec[0] < bounds[0] && -bounds[1] < vec[1] && vec[1] < bounds[1] - && -bounds[2] < vec[2] && vec[2] < bounds[2]) { + if (-bounds[0] < rel[0] && rel[0] < bounds[0] && + -bounds[1] < rel[1] && rel[1] < bounds[1] && + -bounds[2] < rel[2] && rel[2] < bounds[2]) { inBound = TRUE; } return inBound; } -s16 calculate_verticle_angle(Vec3f startPos, Vec3f endPos) { - f32 dx = endPos[0] - startPos[0]; - f32 dy = endPos[1] - startPos[1]; - f32 dz = endPos[2] - startPos[2]; +s16 calculate_pitch(Vec3f from, Vec3f to) { + f32 dx = to[0] - from[0]; + f32 dy = to[1] - from[1]; + f32 dz = to[2] - from[2]; s16 pitch = atan2s(sqrtf(dx * dx + dz * dz), dy); return pitch; } -s16 calculate_yaw(Vec3f startPos, Vec3f endPos) { - f32 dx = endPos[0] - startPos[0]; - UNUSED f32 dy = endPos[1] - startPos[1]; - f32 dz = endPos[2] - startPos[2]; +s16 calculate_yaw(Vec3f from, Vec3f to) { + f32 dx = to[0] - from[0]; + UNUSED f32 dy = to[1] - from[1]; + f32 dz = to[2] - from[2]; s16 yaw = atan2s(dz, dx); return yaw; } -void calculate_angles(Vec3f a, Vec3f b, s16 *pitch, s16 *yaw) { - f32 dx = b[0] - a[0]; - f32 dy = b[1] - a[1]; - f32 dz = b[2] - a[2]; +/** + * Calculates the pitch and yaw between two vectors. + */ +void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw) { + f32 dx = to[0] - from[0]; + f32 dy = to[1] - from[1]; + f32 dz = to[2] - from[2]; *pitch = atan2s(sqrtf(dx * dx + dz * dz), dy); *yaw = atan2s(dz, dx); @@ -3668,160 +4502,193 @@ f32 calc_hor_dist(Vec3f a, Vec3f b) { /** * Rotates a vector in the horizontal plane and copies it to a new vector. */ -void rotate_in_xz(Vec3f dest, Vec3f src, s16 angle) { +void rotate_in_xz(Vec3f dst, Vec3f src, s16 yaw) { Vec3f tempVec; vec3f_copy(tempVec, src); - dest[0] = tempVec[2] * sins(angle) + tempVec[0] * coss(angle); - dest[1] = tempVec[1]; - dest[2] = tempVec[2] * coss(angle) - tempVec[0] * sins(angle); + dst[0] = tempVec[2] * sins(yaw) + tempVec[0] * coss(yaw); + dst[1] = tempVec[1]; + dst[2] = tempVec[2] * coss(yaw) - tempVec[0] * sins(yaw); } /** * Rotates a vector in the YZ plane and copies it to a new vector. + * + * Note: This function also flips the Z axis, so +Z moves forward, not backward like it would in world + * space. If possible, use vec3f_set_dist_and_angle() */ -void rotate_in_yz(Vec3f dest, Vec3f src, s16 angle) { +void rotate_in_yz(Vec3f dst, Vec3f src, s16 pitch) { Vec3f tempVec; vec3f_copy(tempVec, src); - dest[2] = -(tempVec[2] * coss(angle) - tempVec[1] * sins(angle)); - dest[1] = tempVec[2] * sins(angle) + tempVec[1] * coss(angle); - dest[0] = tempVec[0]; + dst[2] = -(tempVec[2] * coss(pitch) - tempVec[1] * sins(pitch)); + dst[1] = tempVec[2] * sins(pitch) + tempVec[1] * coss(pitch); + dst[0] = tempVec[0]; } -void set_camera_pitch_shake(s16 a, s16 b, s16 c) { - if (gCameraStatus.shakeMagnitude[0] < a) { - gCameraStatus.shakeMagnitude[0] = a; - gCameraStatus.shakePitchMagIncrement = b; - gCameraStatus.shakePitchIncrement = c; +/** + * Start shaking the camera's pitch (up and down) + */ +void set_camera_pitch_shake(s16 mag, s16 decay, s16 inc) { + if (gLakituState.shakeMagnitude[0] < mag) { + gLakituState.shakeMagnitude[0] = mag; + gLakituState.shakePitchDecay = decay; + gLakituState.shakePitchVel = inc; } } -void set_camera_yaw_shake(s16 a, s16 b, s16 c) { - if (ABS(a) > ABS(gCameraStatus.shakeMagnitude[1])) { - gCameraStatus.shakeMagnitude[1] = a; - gCameraStatus.shakeYawMagIncrement = b; - gCameraStatus.shakeYawIncrement = c; +/** + * Start shaking the camera's yaw (side to side) + */ +void set_camera_yaw_shake(s16 mag, s16 decay, s16 inc) { + if (ABS(mag) > ABS(gLakituState.shakeMagnitude[1])) { + gLakituState.shakeMagnitude[1] = mag; + gLakituState.shakeYawDecay = decay; + gLakituState.shakeYawVel = inc; } } -void set_camera_roll_shake(s16 a, s16 b, s16 c) { - if (gCameraStatus.shakeMagnitude[2] < a) { - gCameraStatus.shakeMagnitude[2] = a; - gCameraStatus.shakeRollMagIncrement = b; - gCameraStatus.shakeRollIncrement = c; +/** + * Start shaking the camera's roll (rotate screen clockwise and counterclockwise) + */ +void set_camera_roll_shake(s16 mag, s16 decay, s16 inc) { + if (gLakituState.shakeMagnitude[2] < mag) { + gLakituState.shakeMagnitude[2] = mag; + gLakituState.shakeRollDecay = decay; + gLakituState.shakeRollVel = inc; } } -void func_8028AA80(s16 a, s16 b, s16 c, f32 d, f32 e, f32 f, f32 g) { - Vec3f sp2C; - f32 sp28; - s16 sp26; - s16 sp24; +/** + * Start shaking the camera's pitch, but reduce `mag` by it's distance from the camera + */ +void set_pitch_shake_from_point(s16 mag, s16 decay, s16 inc, f32 maxDist, f32 posX, f32 posY, f32 posZ) { + Vec3f pos; + f32 dist; + s16 dummyPitch; + s16 dummyYaw; - sp2C[0] = e; - sp2C[1] = f; - sp2C[2] = g; - vec3f_get_dist_and_angle(gCameraStatus.camFocAndPosCurrAndGoal[3], sp2C, &sp28, &sp26, &sp24); - a = func_80289738(a, d, e, f, g); - if (a != 0) { - set_camera_pitch_shake(a, b, c); + pos[0] = posX; + pos[1] = posY; + pos[2] = posZ; + vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &dummyPitch, &dummyYaw); + mag = reduce_by_dist_from_camera(mag, maxDist, posX, posY, posZ); + if (mag != 0) { + set_camera_pitch_shake(mag, decay, inc); } } -void Unknown8028AB34(s16 a, s16 b, s16 c, f32 d, f32 e, f32 f, f32 g) { - Vec3f sp2C; - f32 sp28; - s16 sp26; - s16 sp24; +/** + * Start shaking the camera's yaw, but reduce `mag` by it's distance from the camera + */ +void set_yaw_shake_from_point(s16 mag, s16 decay, s16 inc, f32 maxDist, f32 posX, f32 posY, f32 posZ) { + Vec3f pos; + f32 dist; + s16 dummyPitch; + s16 dummyYaw; - sp2C[0] = e; - sp2C[1] = f; - sp2C[2] = g; - vec3f_get_dist_and_angle(gCameraStatus.camFocAndPosCurrAndGoal[3], sp2C, &sp28, &sp26, &sp24); - a = func_80289738(a, d, e, f, g); - if (a != 0) { - set_camera_yaw_shake(a, b, c); + pos[0] = posX; + pos[1] = posY; + pos[2] = posZ; + vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &dummyPitch, &dummyYaw); + mag = reduce_by_dist_from_camera(mag, maxDist, posX, posY, posZ); + if (mag != 0) { + set_camera_yaw_shake(mag, decay, inc); } } -void increment_shake_offset(s16 *a, s16 b) { - if (b == -0x8000) { - *a = (*a & 0x8000) + 0xC000; +/** + * Update the shake offset by `increment` + */ +void increment_shake_offset(s16 *offset, s16 increment) { + if (increment == -0x8000) { + *offset = (*offset & 0x8000) + 0xC000; } else { - *a += b; + *offset += increment; } } +/** + * Apply a vertical shake to the camera by adjusting its pitch + */ void shake_camera_pitch(Vec3f pos, Vec3f focus) { f32 dist; s16 pitch; s16 yaw; - if (gCameraStatus.shakeMagnitude[0] | gCameraStatus.shakeMagnitude[1]) { + if (gLakituState.shakeMagnitude[0] | gLakituState.shakeMagnitude[1]) { vec3f_get_dist_and_angle(pos, focus, &dist, &pitch, &yaw); - pitch += gCameraStatus.shakeMagnitude[0] * sins(gCameraStatus.shakePitchOffset); + pitch += gLakituState.shakeMagnitude[0] * sins(gLakituState.shakePitchPhase); vec3f_set_dist_and_angle(pos, focus, dist, pitch, yaw); - increment_shake_offset(&gCameraStatus.shakePitchOffset, gCameraStatus.shakePitchIncrement); - if (camera_approach_s16_symmetric_bool(&gCameraStatus.shakeMagnitude[0], 0, - gCameraStatus.shakePitchMagIncrement) - == 0) { - gCameraStatus.shakePitchOffset = 0; + increment_shake_offset(&gLakituState.shakePitchPhase, gLakituState.shakePitchVel); + if (camera_approach_s16_symmetric_bool(&gLakituState.shakeMagnitude[0], 0, + gLakituState.shakePitchDecay) == 0) { + gLakituState.shakePitchPhase = 0; } } } +/** + * Apply a horizontal shake to the camera by adjusting its yaw + */ void shake_camera_yaw(Vec3f pos, Vec3f focus) { f32 dist; s16 pitch; s16 yaw; - if (gCameraStatus.shakeMagnitude[1] != 0) { + if (gLakituState.shakeMagnitude[1] != 0) { vec3f_get_dist_and_angle(pos, focus, &dist, &pitch, &yaw); - yaw += gCameraStatus.shakeMagnitude[1] * sins(gCameraStatus.shakeYawOffset); + yaw += gLakituState.shakeMagnitude[1] * sins(gLakituState.shakeYawPhase); vec3f_set_dist_and_angle(pos, focus, dist, pitch, yaw); - increment_shake_offset(&gCameraStatus.shakeYawOffset, gCameraStatus.shakeYawIncrement); - if (camera_approach_s16_symmetric_bool(&gCameraStatus.shakeMagnitude[1], 0, - gCameraStatus.shakeYawMagIncrement) - == 0) { - gCameraStatus.shakeYawOffset = 0; + increment_shake_offset(&gLakituState.shakeYawPhase, gLakituState.shakeYawVel); + if (camera_approach_s16_symmetric_bool(&gLakituState.shakeMagnitude[1], 0, + gLakituState.shakeYawDecay) == 0) { + gLakituState.shakeYawPhase = 0; } } } +/** + * Apply a rotational shake to the camera by adjusting its roll + */ void shake_camera_roll(s16 *roll) { UNUSED u8 unused[8]; - if (gCameraStatus.shakeMagnitude[2] != 0) { - increment_shake_offset(&gCameraStatus.shakeRollOffset, gCameraStatus.shakeRollIncrement); - *roll += gCameraStatus.shakeMagnitude[2] * sins(gCameraStatus.shakeRollOffset); - if (camera_approach_s16_symmetric_bool(&gCameraStatus.shakeMagnitude[2], 0, - gCameraStatus.shakeRollMagIncrement) - == 0) { - gCameraStatus.shakeRollOffset = 0; + if (gLakituState.shakeMagnitude[2] != 0) { + increment_shake_offset(&gLakituState.shakeRollPhase, gLakituState.shakeRollVel); + *roll += gLakituState.shakeMagnitude[2] * sins(gLakituState.shakeRollPhase); + if (camera_approach_s16_symmetric_bool(&gLakituState.shakeMagnitude[2], 0, + gLakituState.shakeRollDecay) == 0) { + gLakituState.shakeRollPhase = 0; } } } -s32 func_8028AF24(struct LevelCamera *c, s16 b) { - s16 yawGoal = 0x2AAA; - s16 yaw = sFirstPersonCameraYaw; - f32 horDistFocusToMario; - Vec3f focus; - s16 sp2A; - +/** + * Add an offset to the camera's yaw, used in levels that are inside a rectangular building, like the + * pyramid or TTC. + */ +s32 offset_yaw_outward_radial(struct Camera *c, s16 areaYaw) { + s16 yawGoal = DEGREES(60); + s16 yaw = sModeOffsetYaw; + f32 distFromAreaCenter; + Vec3f areaCenter; + s16 dYaw; switch (gCurrLevelArea) { case AREA_TTC: - focus[0] = c->xFocus; - focus[1] = sMarioStatusForCamera->pos[1]; - focus[2] = c->zFocus; - horDistFocusToMario = calc_abs_dist(focus, sMarioStatusForCamera->pos); - if (800.f > horDistFocusToMario) { + areaCenter[0] = c->areaCenX; + areaCenter[1] = sMarioCamState->pos[1]; + areaCenter[2] = c->areaCenZ; + distFromAreaCenter = calc_abs_dist(areaCenter, sMarioCamState->pos); + if (800.f > distFromAreaCenter) { yawGoal = 0x3800; } break; case AREA_SSL_PYRAMID: - yawGoal = (b & 0xC000) - b + 0x2000; + // This mask splits the 360 degrees of yaw into 4 corners. It adds 45 degrees so that the yaw + // offset at the corner will be 0, but the yaw offset near the center will face more towards + // the direction mario is running in. + yawGoal = (areaYaw & 0xC000) - areaYaw + DEGREES(45); if (yawGoal < 0) { yawGoal = -yawGoal; } @@ -3831,27 +4698,38 @@ s32 func_8028AF24(struct LevelCamera *c, s16 b) { yawGoal = 0; break; } - sp2A = gMarioStates[0].forwardVel / 32.f * 128.f; - if (D_8033B3EC < 0) { - camera_approach_s16_symmetric_bool(&yaw, -yawGoal, sp2A); + dYaw = gMarioStates[0].forwardVel / 32.f * 128.f; + + if (sAreaYawChange < 0) { + camera_approach_s16_symmetric_bool(&yaw, -yawGoal, dYaw); } - if (D_8033B3EC > 0) { - camera_approach_s16_symmetric_bool(&yaw, yawGoal, sp2A); + if (sAreaYawChange > 0) { + camera_approach_s16_symmetric_bool(&yaw, yawGoal, dYaw); } - if (yaw < -0x2AAA) { + // When the final yaw is out of [-60,60] degrees, approach yawGoal faster than dYaw will ever be, + // making the camera lock in one direction until yawGoal drops below 60 (or mario presses a C button) + if (yaw < -DEGREES(60)) { + //! Maybe they meant to reverse yawGoal's sign? camera_approach_s16_symmetric_bool(&yaw, -yawGoal, 0x200); } - if (yaw > 0x2AAA) { + if (yaw > DEGREES(60)) { + //! Maybe they meant to reverse yawGoal's sign? camera_approach_s16_symmetric_bool(&yaw, yawGoal, 0x200); } return yaw; } -void func_8028B13C(void) { +/** + * Plays the background music that starts while peach reads the intro message. + */ +void cutscene_intro_peach_play_message_music(void) { play_music(0, SEQUENCE_ARGS(4, SEQ_EVENT_PEACH_MESSAGE), 0); } -void func_8028B16C(void) { +/** + * Plays the music that starts after peach fades and lakitu appears. + */ +void cutscene_intro_peach_play_lakitu_flying_music(void) { play_music(0, SEQUENCE_ARGS(15, SEQ_EVENT_CUTSCENE_INTRO), 0); } @@ -3894,44 +4772,54 @@ void play_sound_rbutton_changed(void) { play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gDefaultSoundArgs); } -void func_8028B36C(void) { - if (gCameraFlags1 & CAM_FLAG_1_UNKNOWN_1) { +void play_sound_if_cam_switched_to_lakitu_or_mario(void) { + if (sCameraSoundFlags & CAM_SOUND_MARIO_ACTIVE) { play_sound_rbutton_changed(); } - if (gCameraFlags1 & CAM_FLAG_1_UNKNOWN_2) { + if (sCameraSoundFlags & CAM_SOUND_NORMAL_ACTIVE) { play_sound_rbutton_changed(); } - gCameraFlags1 &= ~(CAM_FLAG_1_UNKNOWN_1 | CAM_FLAG_1_UNKNOWN_2); + sCameraSoundFlags &= ~(CAM_SOUND_MARIO_ACTIVE | CAM_SOUND_NORMAL_ACTIVE); } -s32 func_8028B3DC(struct LevelCamera *c, UNUSED f32 b) { +/** + * Handles input for radial, outwards radial, parallel tracking, and 8 direction mode. + */ +s32 radial_camera_input(struct Camera *c, UNUSED f32 unused) { s16 dummy; - if ((gCameraMovementFlags & CAM_MOVE_UNKNOWN_5) - || !(gCameraMovementFlags - & (CAM_MOVE_RETURN_TO_MIDDLE | CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ROTATE_LEFT))) { + if ((gCameraMovementFlags & CAM_MOVE_ENTERED_ROTATE_SURFACE) || !(gCameraMovementFlags & CAM_MOVE_ROTATE)) { + + // If C-L or C-R are pressed, the camera is rotating if (gPlayer1Controller->buttonPressed & (L_CBUTTONS | R_CBUTTONS)) { - gCameraMovementFlags &= ~CAM_MOVE_UNKNOWN_5; + gCameraMovementFlags &= ~CAM_MOVE_ENTERED_ROTATE_SURFACE; + // @bug this does not clear the rotation flags set by the surface. It's possible to set + // both ROTATE_LEFT and ROTATE_RIGHT, locking the camera. + // Ex: If a surface set CAM_MOVE_ROTATE_RIGHT and the user presses C-R, it locks the + // camera until a different mode is activated } + // Rotate Right and left if (gPlayer1Controller->buttonPressed & R_CBUTTONS) { - if (sFirstPersonCameraYaw > -0x800) { + if (sModeOffsetYaw > -0x800) { + // The camera is now rotating right if (!(gCameraMovementFlags & CAM_MOVE_ROTATE_RIGHT)) { gCameraMovementFlags |= CAM_MOVE_ROTATE_RIGHT; } - if (c->currPreset == CAMERA_PRESET_OPEN_CAMERA) { - if (sFirstPersonCameraYaw > 0x22AA) { - sCameraSideCFlags |= 4; + if (c->mode == CAMERA_MODE_RADIAL) { + // if > ~48 degrees, we're rotating for the second time. + if (sModeOffsetYaw > 0x22AA) { + s2ndRotateFlags |= CAM_MOVE_ROTATE_RIGHT; } - if (sFirstPersonCameraYaw == 0x4AAA) { + if (sModeOffsetYaw == DEGREES(105)) { play_sound_button_change_blocked(); } else { play_sound_cbutton_side(); } } else { - if (sFirstPersonCameraYaw == 0x2AAA) { + if (sModeOffsetYaw == DEGREES(60)) { play_sound_button_change_blocked(); } else { play_sound_cbutton_side(); @@ -3943,23 +4831,24 @@ s32 func_8028B3DC(struct LevelCamera *c, UNUSED f32 b) { } } if (gPlayer1Controller->buttonPressed & L_CBUTTONS) { - if (sFirstPersonCameraYaw < 0x800) { + if (sModeOffsetYaw < 0x800) { if (!(gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT)) { gCameraMovementFlags |= CAM_MOVE_ROTATE_LEFT; } - if (c->currPreset == CAMERA_PRESET_OPEN_CAMERA) { - if (sFirstPersonCameraYaw < -0x22AA) { - sCameraSideCFlags |= 8; + if (c->mode == CAMERA_MODE_RADIAL) { + // if < ~48 degrees, we're rotating for the second time. + if (sModeOffsetYaw < -0x22AA) { + s2ndRotateFlags |= CAM_MOVE_ROTATE_LEFT; } - if (sFirstPersonCameraYaw == -19114) { + if (sModeOffsetYaw == DEGREES(-105)) { play_sound_button_change_blocked(); } else { play_sound_cbutton_side(); } } else { - if (sFirstPersonCameraYaw == -10922) { + if (sModeOffsetYaw == DEGREES(-60)) { play_sound_button_change_blocked(); } else { play_sound_cbutton_side(); @@ -3971,17 +4860,21 @@ s32 func_8028B3DC(struct LevelCamera *c, UNUSED f32 b) { } } } + + // Zoom in / enter C-Up if (gPlayer1Controller->buttonPressed & U_CBUTTONS) { if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { gCameraMovementFlags &= ~CAM_MOVE_ZOOMED_OUT; play_sound_cbutton_up(); } else { - func_80284D44(c); + set_mode_c_up(c); } } + + // Zoom out if (gPlayer1Controller->buttonPressed & D_CBUTTONS) { if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - gCameraMovementFlags |= CAM_MOVE_UNK1000; + gCameraMovementFlags |= CAM_MOVE_ALREADY_ZOOMED_OUT; #ifndef VERSION_JP play_camera_buzz_if_cdown(); #endif @@ -3995,50 +4888,59 @@ s32 func_8028B3DC(struct LevelCamera *c, UNUSED f32 b) { return dummy; } -s32 stop_mario(s32 a) { - s32 sp1C = 0; - UNUSED struct LevelCamera *c = gCurrLevelCamera; +/** + * Starts a cutscene dialog. Only has an effect when `trigger` is 1 + */ +s32 trigger_cutscene_dialog(s32 trigger) { + s32 result = 0; + UNUSED struct Camera *c = gCamera; - if (a == 1) { - func_8028F834(CUTSCENE_READ_MESSAGE); + if (trigger == 1) { + start_object_cutscene_without_focus(CUTSCENE_READ_MESSAGE); } - if (a == 2) { + if (trigger == 2) { } - return sp1C; + return result; } -void handle_c_button_movement(struct LevelCamera *a) { - s16 sp1E; +/** + * Updates the camera based on which C buttons are pressed this frame + */ +void handle_c_button_movement(struct Camera *c) { + s16 cSideYaw; + // Zoom in if (gPlayer1Controller->buttonPressed & U_CBUTTONS) { - if (a->currPreset != CAMERA_PRESET_FIXED_REF_POINT - && (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT)) { + if (c->mode != CAMERA_MODE_FIXED && (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT)) { gCameraMovementFlags &= ~CAM_MOVE_ZOOMED_OUT; play_sound_cbutton_up(); } else { - func_80284D44(a); - if (D_8033B3FC > gCameraZoomDist) { - D_8033B3F4 = -gCameraZoomDist; + set_mode_c_up(c); + if (sZeroZoomDist > gCameraZoomDist) { + sZoomAmount = -gCameraZoomDist; } else { - D_8033B3F4 = gCameraZoomDist; + sZoomAmount = gCameraZoomDist; } } } - if (a->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { + if (c->mode != CAMERA_MODE_FIXED) { + // Zoom out if (gPlayer1Controller->buttonPressed & D_CBUTTONS) { if (gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) { - gCameraMovementFlags |= CAM_MOVE_UNK1000; - D_8033B3F4 = gCameraZoomDist + 400.f; + gCameraMovementFlags |= CAM_MOVE_ALREADY_ZOOMED_OUT; + sZoomAmount = gCameraZoomDist + 400.f; #ifndef VERSION_JP play_camera_buzz_if_cdown(); #endif } else { gCameraMovementFlags |= CAM_MOVE_ZOOMED_OUT; - D_8033B3F4 = gCameraZoomDist + 400.f; + sZoomAmount = gCameraZoomDist + 400.f; play_sound_cbutton_down(); } } - sp1E = 4096; + + // Rotate left or right + cSideYaw = 0x1000; if (gPlayer1Controller->buttonPressed & R_CBUTTONS) { if (gCameraMovementFlags & CAM_MOVE_ROTATE_LEFT) { gCameraMovementFlags &= ~CAM_MOVE_ROTATE_LEFT; @@ -4047,7 +4949,7 @@ void handle_c_button_movement(struct LevelCamera *a) { if (sCSideButtonYaw == 0) { play_sound_cbutton_side(); } - sCSideButtonYaw = -sp1E; + sCSideButtonYaw = -cSideYaw; } } if (gPlayer1Controller->buttonPressed & L_CBUTTONS) { @@ -4058,40 +4960,49 @@ void handle_c_button_movement(struct LevelCamera *a) { if (sCSideButtonYaw == 0) { play_sound_cbutton_side(); } - sCSideButtonYaw = sp1E; + sCSideButtonYaw = cSideYaw; } } } } -void func_8028BA38(UNUSED struct LevelCamera *a) { +/** + * Zero the 10 cvars. + */ +void clear_cutscene_vars(UNUSED struct Camera *c) { s32 i; for (i = 0; i < 10; i++) { - D_8033B6F0[i].unk0 = 0; - vec3f_set(D_8033B6F0[i].unk4, 0.f, 0.f, 0.f); - vec3f_set(D_8033B6F0[i].unk10, 0.f, 0.f, 0.f); - vec3s_set(D_8033B6F0[i].unk1C, 0, 0, 0); - D_8033B6F0[i].unk22 = 0; + sCutsceneVars[i].unused1 = 0; + vec3f_set(sCutsceneVars[i].point, 0.f, 0.f, 0.f); + vec3f_set(sCutsceneVars[i].unusedPoint, 0.f, 0.f, 0.f); + vec3s_set(sCutsceneVars[i].angle, 0, 0, 0); + sCutsceneVars[i].unused2 = 0; } } /** - * If camera's cutscene table is not already set to a value, - * set it to that value. + * Start the cutscene, `cutscene`, if it is not already playing. */ -void set_camera_cutscene_table(struct LevelCamera *camera, u8 cutsceneTable) { - if (camera->cutscene != cutsceneTable) { - camera->cutscene = cutsceneTable; - func_8028BA38(camera); +void start_cutscene(struct Camera *c, u8 cutscene) { + if (c->cutscene != cutscene) { + c->cutscene = cutscene; + clear_cutscene_vars(c); } } -extern u8 D_8032E8A4[27][4]; - -s32 determine_star_fadeout_cutscene_table(UNUSED struct LevelCamera *c) { - u8 sp7 = 0; - u8 sp6 = 0; +/** + * Look up the victory dance cutscene in sDanceCutsceneTable + * + * First the index entry is determined based on the course and the star that was just picked up + * Like the entries in sZoomOutAreaMasks, each entry represents two stars + * The current courses's 4 bits of the index entry are used as the actual index into sDanceCutsceneTable + * + * @return the victory cutscene to use + */ +s32 determine_dance_cutscene(UNUSED struct Camera *c) { + u8 cutscene = 0; + u8 cutsceneIndex = 0; u8 starIndex = (gLastCompletedStarNum - 1) / 2; u8 courseIndex = gCurrCourseNum; @@ -4101,68 +5012,85 @@ s32 determine_star_fadeout_cutscene_table(UNUSED struct LevelCamera *c) { if (courseIndex > COURSE_MAX) { courseIndex = COURSE_NONE; } - sp6 = D_8032E8A4[courseIndex][starIndex]; + cutsceneIndex = sDanceCutsceneIndexTable[courseIndex][starIndex]; + if (gLastCompletedStarNum & 1) { - sp6 &= 0xF; + // Odd stars take the lower four bytes + cutsceneIndex &= 0xF; } else { - sp6 = sp6 >> 4; + // Even stars use the upper four bytes + cutsceneIndex = cutsceneIndex >> 4; } - sp7 = D_8032D0B8[sp6]; - return sp7; + cutscene = sDanceCutsceneTable[cutsceneIndex]; + return cutscene; } -u8 return_table_door_push_or_pull(u8 pullResult, u8 pushResult) { +/** + * @return `pullResult` or `pushResult` depending on mario's door action + */ +u8 open_door_cutscene(u8 pullResult, u8 pushResult) { s16 result; - if (sMarioStatusForCamera->action == ACT_PULLING_DOOR) { + if (sMarioCamState->action == ACT_PULLING_DOOR) { result = pullResult; } - if (sMarioStatusForCamera->action == ACT_PUSHING_DOOR) { + if (sMarioCamState->action == ACT_PUSHING_DOOR) { result = pushResult; } return result; } -u8 return_cutscene_table(struct LevelCamera *c) { +/** + * If no cutscenes are playing, determines if a cutscene should play based on mario's action and + * cameraEvent + * + * @return the cutscene that should start, 0 if none + */ +u8 get_cutscene_from_mario_status(struct Camera *c) { UNUSED u8 unused1[4]; u8 cutscene = c->cutscene; UNUSED u8 unused2[12]; if (cutscene == 0) { - cutscene = sTempCutsceneNumber; - sTempCutsceneNumber = 0; - if (sMarioStatusForCamera->unk1C[1] == 6) { + // A cutscene started by an object, if any, will start if nothing else happened + cutscene = sObjectCutscene; + sObjectCutscene = 0; + if (sMarioCamState->cameraEvent == CAM_EVENT_DOOR) { switch (gCurrLevelArea) { case AREA_CASTLE_LOBBY: - if (c->currPreset == CAMERA_PRESET_SPIRAL_STAIRS - || c->currPreset == CAMERA_PRESET_CLOSE || c->unk64 == 2) { - cutscene = return_table_door_push_or_pull(CUTSCENE_DOOR_A, CUTSCENE_DOOR_B); + //! doorStatus is never DOOR_ENTER_LOBBY when cameraEvent == 6, because + //! doorStatus is only used for the star door in the lobby, which uses + //! ACT_ENTERING_STAR_DOOR + if (c->mode == CAMERA_MODE_SPIRAL_STAIRS || c->mode == CAMERA_MODE_CLOSE + || c->doorStatus == DOOR_ENTER_LOBBY) { + cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL_MODE, CUTSCENE_DOOR_PUSH_MODE); } else { - cutscene = return_table_door_push_or_pull(CUTSCENE_DOOR_0, CUTSCENE_DOOR_1); + cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL, CUTSCENE_DOOR_PUSH); } break; case AREA_BBH: - if (c->unk64 == 1) { - cutscene = return_table_door_push_or_pull(CUTSCENE_DOOR_0, CUTSCENE_DOOR_1); + //! Castle Lobby uses 0 to mean 'no special modes', but BBH uses 1... + if (c->doorStatus == DOOR_LEAVING_SPECIAL) { + cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL, CUTSCENE_DOOR_PUSH); } else { - cutscene = return_table_door_push_or_pull(CUTSCENE_DOOR_A, CUTSCENE_DOOR_B); + cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL_MODE, CUTSCENE_DOOR_PUSH_MODE); } break; default: - cutscene = return_table_door_push_or_pull(CUTSCENE_DOOR_0, CUTSCENE_DOOR_1); + cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL, CUTSCENE_DOOR_PUSH); break; } } - if (sMarioStatusForCamera->unk1C[1] == 5) { + if (sMarioCamState->cameraEvent == CAM_EVENT_DOOR_WARP) { cutscene = CUTSCENE_DOOR_WARP; } - if (sMarioStatusForCamera->unk1C[1] == 1) { + if (sMarioCamState->cameraEvent == CAM_EVENT_CANNON) { cutscene = CUTSCENE_ENTER_CANNON; } - if (SURFACE_IS_PAINTING_WARP(sGeometryForMario.currFloorType)) { + if (SURFACE_IS_PAINTING_WARP(sMarioGeometry.currFloorType)) { cutscene = CUTSCENE_ENTER_PAINTING; } - switch (sMarioStatusForCamera->action) { + switch (sMarioCamState->action) { case ACT_DEATH_EXIT: cutscene = CUTSCENE_DEATH_EXIT; break; @@ -4174,22 +5102,22 @@ u8 return_cutscene_table(struct LevelCamera *c) { || gPrevLevel == LEVEL_BOWSER_3) { cutscene = CUTSCENE_EXIT_BOWSER_SUCC; } else { - cutscene = CUTSCENE_EXIT_BBH_SUCC; + cutscene = CUTSCENE_EXIT_SPECIAL_SUCC; } break; case ACT_SPECIAL_DEATH_EXIT: if (gPrevLevel == LEVEL_BOWSER_1 || gPrevLevel == LEVEL_BOWSER_2 || gPrevLevel == LEVEL_BOWSER_3) { - cutscene = CUTSCENE_1C_TODO; + cutscene = CUTSCENE_EXIT_BOWSER_DEATH; } else { cutscene = CUTSCENE_NONPAINTING_DEATH; } break; case ACT_ENTERING_STAR_DOOR: - if (c->unk64 == 0) { + if (c->doorStatus == DOOR_DEFAULT) { cutscene = CUTSCENE_SLIDING_DOORS_OPEN; } else { - cutscene = CUTSCENE_DOOR_A; + cutscene = CUTSCENE_DOOR_PULL_MODE; } break; case ACT_UNLOCKING_KEY_DOOR: @@ -4202,7 +5130,7 @@ u8 return_cutscene_table(struct LevelCamera *c) { cutscene = CUTSCENE_DEATH_ON_BACK; break; case ACT_DEATH_ON_STOMACH: - cutscene = CUTSCENE_DEATH_2; + cutscene = CUTSCENE_DEATH_ON_STOMACH; break; case ACT_STANDING_DEATH: cutscene = CUTSCENE_STANDING_DEATH; @@ -4217,60 +5145,70 @@ u8 return_cutscene_table(struct LevelCamera *c) { cutscene = CUTSCENE_STANDING_DEATH; break; case ACT_STAR_DANCE_EXIT: - cutscene = determine_star_fadeout_cutscene_table(c); + cutscene = determine_dance_cutscene(c); break; case ACT_STAR_DANCE_WATER: - cutscene = determine_star_fadeout_cutscene_table(c); + cutscene = determine_dance_cutscene(c); break; case ACT_STAR_DANCE_NO_EXIT: - cutscene = CUTSCENE_STAR_DANCE_1_2; + cutscene = CUTSCENE_DANCE_DEFAULT; break; } - switch (sMarioStatusForCamera->unk1C[1]) { - case 9: + switch (sMarioCamState->cameraEvent) { + case CAM_EVENT_START_INTRO: cutscene = CUTSCENE_INTRO_PEACH; break; - case 10: + case CAM_EVENT_START_GRAND_STAR: cutscene = CUTSCENE_GRAND_STAR; break; - case 11: - cutscene = CUTSCENE_PEACH_END; + case CAM_EVENT_START_ENDING: + cutscene = CUTSCENE_ENDING; break; - case 12: + case CAM_EVENT_START_END_WAVING: cutscene = CUTSCENE_END_WAVING; break; - case 13: + case CAM_EVENT_START_CREDITS: cutscene = CUTSCENE_CREDITS; break; } } - c->unk64 = 0; + //! doorStatus is reset every frame. CameraTriggers need to constantly set doorStatus + c->doorStatus = DOOR_DEFAULT; + return cutscene; } -void instant_warp_camera_update(f32 displacementX, f32 displacementY, f32 displacementZ) { +/** + * Moves the camera when mario has triggered a warp + */ +void warp_camera(f32 displacementX, f32 displacementY, f32 displacementZ) { Vec3f displacement; struct MarioState *marioStates = &gMarioStates[0]; - struct Struct8033B418_sub *sp1C = &D_8033B418.unk8; - struct Struct8033B418_sub *sp28 = &D_8033B418.unk28; + struct LinearTransitionPoint *start = &sModeInfo.transitionStart; + struct LinearTransitionPoint *end = &sModeInfo.transitionEnd; gCurrLevelArea = gCurrLevelNum * 16 + gCurrentArea->index; displacement[0] = displacementX; displacement[1] = displacementY; displacement[2] = displacementZ; - vec3f_add(gCameraStatus.camFocAndPosCurrAndGoal[1], displacement); - vec3f_add(gCameraStatus.camFocAndPosCurrAndGoal[0], displacement); - vec3f_add(gCameraStatus.camFocAndPosCurrAndGoal[3], displacement); - vec3f_add(gCameraStatus.camFocAndPosCurrAndGoal[2], displacement); + vec3f_add(gLakituState.curPos, displacement); + vec3f_add(gLakituState.curFocus, displacement); + vec3f_add(gLakituState.goalPos, displacement); + vec3f_add(gLakituState.goalFocus, displacement); marioStates->waterLevel += displacementY; - vec3f_add(sp1C->unk0, displacement); - vec3f_add(sp1C->unkC, displacement); - vec3f_add(sp28->unk0, displacement); - vec3f_add(sp28->unkC, displacement); + + vec3f_add(start->focus, displacement); + vec3f_add(start->pos, displacement); + vec3f_add(end->focus, displacement); + vec3f_add(end->pos, displacement); } -void approach_camera_height(struct LevelCamera *c, f32 goal, f32 inc) { - if (gCameraFlags2 & CAM_FLAG_2_SMOOTH_MOVEMENT) { +/** + * Make the camera's y coordinate approach `goal`, + * unless smooth movement is off, in which case the y coordinate is simply set to `goal` + */ +void approach_camera_height(struct Camera *c, f32 goal, f32 inc) { + if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { if (c->pos[1] < goal) { if ((c->pos[1] += inc) > goal) { c->pos[1] = goal; @@ -4285,860 +5223,1087 @@ void approach_camera_height(struct LevelCamera *c, f32 goal, f32 inc) { } } -void Unknown8028C3AC(UNUSED s32 a, UNUSED s32 b, UNUSED s32 c, UNUSED s32 d) { +void unused_8028C3AC(UNUSED s32 a, UNUSED s32 b, UNUSED s32 c, UNUSED s32 d) { } -void set_focus_position(struct LevelCamera *c, f32 b, f32 heightOffset, f32 d, s16 yawOffset) { +/** + * Set the camera's focus to mario's position, and add several relative offsets. + * + * @param leftRight offset to mario's left/right, relative to his faceAngle + * @param yOff y offset + * @param forwBack offset to mario's front/back, relative to his faceAngle + * @param yawOff offset to mario's faceAngle, changes the direction of `leftRight` and `forwBack` + */ +void set_focus_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, f32 forwBack, s16 yawOff) { s16 yaw; UNUSED u16 unused; - f32 heightAboveFloor; + f32 focFloorYOff; - return_height_above_floor(&heightAboveFloor, 1.f, 200.f, &heightAboveFloor, 0.9f, 200.f); - yaw = sMarioStatusForCamera->faceAngle[1] + yawOffset; - c->focus[2] = sMarioStatusForCamera->pos[2] + d * coss(yaw) - b * sins(yaw); - c->focus[0] = sMarioStatusForCamera->pos[0] + d * sins(yaw) + b * coss(yaw); - c->focus[1] = sMarioStatusForCamera->pos[1] + heightOffset + heightAboveFloor; + calc_y_to_curr_floor(&focFloorYOff, 1.f, 200.f, &focFloorYOff, 0.9f, 200.f); + yaw = sMarioCamState->faceAngle[1] + yawOff; + c->focus[2] = sMarioCamState->pos[2] + forwBack * coss(yaw) - leftRight * sins(yaw); + c->focus[0] = sMarioCamState->pos[0] + forwBack * sins(yaw) + leftRight * coss(yaw); + c->focus[1] = sMarioCamState->pos[1] + yOff + focFloorYOff; } -static void unused_set_camera_position(struct LevelCamera *c, f32 b, f32 heightOffset, f32 d, - s16 yawOffset) { - u16 yaw = sMarioStatusForCamera->faceAngle[1] + yawOffset; +/** + * Set the camera's position to mario's position, and add several relative offsets. Unused. + * + * @param leftRight offset to mario's left/right, relative to his faceAngle + * @param yOff y offset + * @param forwBack offset to mario's front/back, relative to his faceAngle + * @param yawOff offset to mario's faceAngle, changes the direction of `leftRight` and `forwBack` + */ +static void unused_set_pos_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, f32 forwBack, s16 yawOff) { + u16 yaw = sMarioCamState->faceAngle[1] + yawOff; - c->pos[0] = sMarioStatusForCamera->pos[0] + d * sins(yaw) + b * coss(yaw); - c->pos[1] = sMarioStatusForCamera->pos[1] + heightOffset; - c->pos[2] = sMarioStatusForCamera->pos[2] + d * coss(yaw) - b * sins(yaw); + c->pos[0] = sMarioCamState->pos[0] + forwBack * sins(yaw) + leftRight * coss(yaw); + c->pos[1] = sMarioCamState->pos[1] + yOff; + c->pos[2] = sMarioCamState->pos[2] + forwBack * coss(yaw) - leftRight * sins(yaw); } -void set_pos_from_face_angle_and_vec3f(Vec3f dst, Vec3f base, Vec3f posRelative, Vec3s faceAngle) { +/** + * Rotates the offset `to` according to the pitch and yaw values in `rotation`. + * Adds `from` to the rotated offset, and stores the result in `dst`. + * + * @warning Flips the Z axis, so that relative to `rotation`, -Z moves forwards and +Z moves backwards. + */ +void offset_rotated(Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation) { Vec3f unusedCopy; - Vec3f yzRotatedPos; + Vec3f pitchRotated; - vec3f_copy(unusedCopy, base); + vec3f_copy(unusedCopy, from); - yzRotatedPos[2] = -(posRelative[2] * coss(faceAngle[0]) - posRelative[1] * sins(faceAngle[0])); - yzRotatedPos[1] = posRelative[2] * sins(faceAngle[0]) + posRelative[1] * coss(faceAngle[0]); - yzRotatedPos[0] = posRelative[0]; + // First rotate the direction by rotation's pitch + //! The Z axis is flipped here. + pitchRotated[2] = -(to[2] * coss(rotation[0]) - to[1] * sins(rotation[0])); + pitchRotated[1] = to[2] * sins(rotation[0]) + to[1] * coss(rotation[0]); + pitchRotated[0] = to[0]; - dst[0] = base[0] + yzRotatedPos[2] * sins(faceAngle[1]) + yzRotatedPos[0] * coss(faceAngle[1]); - dst[1] = base[1] + yzRotatedPos[1]; - dst[2] = base[2] + yzRotatedPos[2] * coss(faceAngle[1]) - yzRotatedPos[0] * sins(faceAngle[1]); + // Rotate again by rotation's yaw + dst[0] = from[0] + pitchRotated[2] * sins(rotation[1]) + pitchRotated[0] * coss(rotation[1]); + dst[1] = from[1] + pitchRotated[1]; + dst[2] = from[2] + pitchRotated[2] * coss(rotation[1]) - pitchRotated[0] * sins(rotation[1]); } -void set_pos_from_face_angle_and_rel_coords(Vec3f dst, Vec3f base, Vec3s faceAngle, f32 xRelative, - f32 yRelative, f32 zRelative) { - Vec3f posRelative; +/** + * Rotates the offset defined by (`xTo`, `yTo`, `zTo`) according to the pitch and yaw values in `rotation`. + * Adds `from` to the rotated offset, and stores the result in `dst`. + * + * @warning Flips the Z axis, so that relative to `rotation`, -Z moves forwards and +Z moves backwards. + */ +void offset_rotated_coords(Vec3f dst, Vec3f from, Vec3s rotation, f32 xTo, f32 yTo, f32 zTo) { + Vec3f to; - vec3f_set(posRelative, xRelative, yRelative, zRelative); - set_pos_from_face_angle_and_vec3f(dst, base, posRelative, faceAngle); + vec3f_set(to, xTo, yTo, zTo); + offset_rotated(dst, from, to, rotation); } -void determine_pushing_or_pulling_door(s16 *a) { - if (sMarioStatusForCamera->action == ACT_PULLING_DOOR) { - *a = 0; +void determine_pushing_or_pulling_door(s16 *rotation) { + if (sMarioCamState->action == ACT_PULLING_DOOR) { + *rotation = 0; } else { - *a = -0x8000; - } -} - -s16 func_8028C824(Vec3f a, Vec3f b, Vec3f c, Vec3f d, Vec3f e, Vec3f f, s16 yaw) { - s16 yawVelocity; - s16 pitchVelocity; - f32 distVelocity; - f32 goalDist; - UNUSED u8 unused1[4]; - s16 goalPitch; - s16 goalYaw; - UNUSED u8 unused2[4]; - f32 f32Timer = sCameraTransition.timer; - s16 s16Timer = sCameraTransition.timer; - UNUSED s16 sp78 = 0; - Vec3f sp6C; - Vec3f sp60; - Vec3f sp54; - Vec3f sp48; - s32 i; - f32 floorHeight; - struct Surface *floor; - - vec3f_copy(a, c); - vec3f_copy(b, d); - if (gCameraFlags2 & CAM_FLAG_2_UNKNOWN_10) { - for (i = 0; i < 3; i++) { - sp54[i] = e[i] + sMarioStatusForCamera->pos[i] - sCameraTransition.marioPos[i]; - sp48[i] = f[i] + sMarioStatusForCamera->pos[i] - sCameraTransition.marioPos[i]; - } - - vec3f_get_dist_and_angle(d, sp48, &sCameraTransition.dist2, &sCameraTransition.pitch2, - &sCameraTransition.yaw2); - vec3f_get_dist_and_angle(d, sp54, &sCameraTransition.dist1, &sCameraTransition.pitch1, - &sCameraTransition.yaw1); - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_10; - } - if (sCameraTransition.timer > 0) { - sp78 = 1; - - vec3f_get_dist_and_angle(d, c, &goalDist, &goalPitch, &goalYaw); - distVelocity = ABS(goalDist - sCameraTransition.dist1) / f32Timer; - pitchVelocity = ABS(goalPitch - sCameraTransition.pitch1) / s16Timer; - yawVelocity = ABS(goalYaw - sCameraTransition.yaw1) / s16Timer; - camera_approach_f32_symmetric_bool(&sCameraTransition.dist1, goalDist, distVelocity); - camera_approach_s16_symmetric_bool(&sCameraTransition.yaw1, goalYaw, yawVelocity); - camera_approach_s16_symmetric_bool(&sCameraTransition.pitch1, goalPitch, pitchVelocity); - vec3f_set_dist_and_angle(d, sp6C, sCameraTransition.dist1, sCameraTransition.pitch1, - sCameraTransition.yaw1); - - vec3f_get_dist_and_angle(c, d, &goalDist, &goalPitch, &goalYaw); - pitchVelocity = sCameraTransition.pitch2 / (s16) sCameraTransition.timer; - yawVelocity = sCameraTransition.yaw2 / (s16) sCameraTransition.timer; - distVelocity = sCameraTransition.dist2 / sCameraTransition.timer; - camera_approach_s16_symmetric_bool(&sCameraTransition.pitch2, goalPitch, pitchVelocity); - camera_approach_s16_symmetric_bool(&sCameraTransition.yaw2, goalYaw, yawVelocity); - camera_approach_f32_symmetric_bool(&sCameraTransition.dist2, 0, distVelocity); - vec3f_set_dist_and_angle(d, sp60, sCameraTransition.dist2, sCameraTransition.pitch2, - sCameraTransition.yaw2); - - vec3f_copy(b, sp60); - vec3f_copy(a, sp6C); - - if (gCurrLevelCamera->cutscene != 0 || !(gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) { - floorHeight = find_floor(a[0], a[1], a[2], &floor); - if (floorHeight != -11000.f) { - if ((floorHeight += 125.f) > a[1]) { - a[1] = floorHeight; - } - } - f32_find_wall_collision(&a[0], &a[1], &a[2], 0.f, 100.f); - } - sCameraTransition.timer--; - yaw = calculate_yaw(b, a); - } else { - sCameraTransition.dist1 = 0.f; - sCameraTransition.pitch1 = 0; - sCameraTransition.yaw1 = 0; - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_11; - } - vec3f_copy(sCameraTransition.marioPos, sMarioStatusForCamera->pos); - return yaw; -} - -static void Unknown8028CE1C(void) { - gCameraFlags2 &= ~(CAM_FLAG_2_UNKNOWN_10 | CAM_FLAG_2_UNKNOWN_11); - sCameraTransition.timer = 0; -} - -s32 set_camera_preset_fixed_ref_point(struct LevelCamera *c, s16 x, s16 y, s16 z) { - s32 camPosSet = FALSE; - f32 posX = x; - f32 posY = y; - f32 posZ = z; - - if (sFixedPresetBasePosition[0] != posX || sFixedPresetBasePosition[1] != posY - || sFixedPresetBasePosition[2] != posZ) { - camPosSet = TRUE; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - } - vec3f_set(sFixedPresetBasePosition, posX, posY, posZ); - if (c->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - c->currPreset = CAMERA_PRESET_FIXED_REF_POINT; - vec3f_set(c->pos, sFixedPresetBasePosition[0], sMarioStatusForCamera->pos[1], - sFixedPresetBasePosition[2]); - } - return camPosSet; -} - -void set_camera_preset_platform_level(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_PLATFORM_LEVEL) { - c->currPreset = CAMERA_PRESET_PLATFORM_LEVEL; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - sPlatformLevelPresetBaseYaw = 0; - gPlatformLevelYawOffset = 0; + *rotation = DEGREES(180); } } /** - * If the camera preset is not already the boss fight camera (camera with two foci) + * Calculate lakitu's next position and focus, according to gCamera's state, + * and store them in `newPos` and `newFoc`. + * + * @param newPos where lakitu should fly towards this frame + * @param newFoc where lakitu should look towards this frame + * + * @param curPos gCamera's pos this frame + * @param curFoc gCamera's foc this frame + * + * @param oldPos gCamera's pos last frame + * @param oldFoc gCamera's foc last frame + * + * @return lakitu's next yaw, which is the same as the yaw passed in if no transition happened + */ +s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc, + Vec3f oldPos, Vec3f oldFoc, s16 yaw) { + s16 yawVelocity; + s16 pitchVelocity; + f32 distVelocity; + f32 goalDist; + UNUSED f32 unusedDist; + s16 goalPitch; + s16 goalYaw; + UNUSED s16 unusedPitch; + UNUSED s16 unusedYaw; + f32 distTimer = sModeTransition.framesLeft; + s16 angleTimer = sModeTransition.framesLeft; + UNUSED s16 inTransition = 0; + Vec3f nextPos; + Vec3f nextFoc; + Vec3f startPos; + Vec3f startFoc; + s32 i; + f32 floorHeight; + struct Surface *floor; + + // If not transitioning, just use gCamera's current pos and foc + vec3f_copy(newPos, curPos); + vec3f_copy(newFoc, curFoc); + + if (sStatusFlags & CAM_FLAG_START_TRANSITION) { + for (i = 0; i < 3; i++) { + // Add mario's displacement from this frame to the last frame's pos and focus + // Makes the transition start from where the camera would have moved + startPos[i] = oldPos[i] + sMarioCamState->pos[i] - sModeTransition.marioPos[i]; + startFoc[i] = oldFoc[i] + sMarioCamState->pos[i] - sModeTransition.marioPos[i]; + } + + + vec3f_get_dist_and_angle(curFoc, startFoc, &sModeTransition.focDist, &sModeTransition.focPitch, + &sModeTransition.focYaw); + vec3f_get_dist_and_angle(curFoc, startPos, &sModeTransition.posDist, &sModeTransition.posPitch, + &sModeTransition.posYaw); + sStatusFlags &= ~CAM_FLAG_START_TRANSITION; + } + + // Transition from the last mode to the current one + if (sModeTransition.framesLeft > 0) { + inTransition = 1; + + vec3f_get_dist_and_angle(curFoc, curPos, &goalDist, &goalPitch, &goalYaw); + distVelocity = ABS(goalDist - sModeTransition.posDist) / distTimer; + pitchVelocity = ABS(goalPitch - sModeTransition.posPitch) / angleTimer; + yawVelocity = ABS(goalYaw - sModeTransition.posYaw) / angleTimer; + + camera_approach_f32_symmetric_bool(&sModeTransition.posDist, goalDist, distVelocity); + camera_approach_s16_symmetric_bool(&sModeTransition.posYaw, goalYaw, yawVelocity); + camera_approach_s16_symmetric_bool(&sModeTransition.posPitch, goalPitch, pitchVelocity); + vec3f_set_dist_and_angle(curFoc, nextPos, sModeTransition.posDist, sModeTransition.posPitch, + sModeTransition.posYaw); + + vec3f_get_dist_and_angle(curPos, curFoc, &goalDist, &goalPitch, &goalYaw); + pitchVelocity = sModeTransition.focPitch / (s16) sModeTransition.framesLeft; + yawVelocity = sModeTransition.focYaw / (s16) sModeTransition.framesLeft; + distVelocity = sModeTransition.focDist / sModeTransition.framesLeft; + + camera_approach_s16_symmetric_bool(&sModeTransition.focPitch, goalPitch, pitchVelocity); + camera_approach_s16_symmetric_bool(&sModeTransition.focYaw, goalYaw, yawVelocity); + camera_approach_f32_symmetric_bool(&sModeTransition.focDist, 0, distVelocity); + vec3f_set_dist_and_angle(curFoc, nextFoc, sModeTransition.focDist, sModeTransition.focPitch, + sModeTransition.focYaw); + + vec3f_copy(newFoc, nextFoc); + vec3f_copy(newPos, nextPos); + + if (gCamera->cutscene != 0 || !(gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) { + floorHeight = find_floor(newPos[0], newPos[1], newPos[2], &floor); + if (floorHeight != -11000.f) { + if ((floorHeight += 125.f) > newPos[1]) { + newPos[1] = floorHeight; + } + } + f32_find_wall_collision(&newPos[0], &newPos[1], &newPos[2], 0.f, 100.f); + } + sModeTransition.framesLeft--; + yaw = calculate_yaw(newFoc, newPos); + } else { + sModeTransition.posDist = 0.f; + sModeTransition.posPitch = 0; + sModeTransition.posYaw = 0; + sStatusFlags &= ~CAM_FLAG_TRANSITION_OUT_OF_C_UP; + } + vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos); + return yaw; +} + +static UNUSED void stop_transitional_movement(void) { + sStatusFlags &= ~(CAM_FLAG_START_TRANSITION | CAM_FLAG_TRANSITION_OUT_OF_C_UP); + sModeTransition.framesLeft = 0; +} + +/** + * Start fixed camera mode, setting the base position to (`x`, `y`, `z`) + * + * @return TRUE if the base pos was updated + */ +s32 set_camera_mode_fixed(struct Camera *c, s16 x, s16 y, s16 z) { + s32 basePosSet = FALSE; + f32 posX = x; + f32 posY = y; + f32 posZ = z; + + if (sFixedModeBasePosition[0] != posX || sFixedModeBasePosition[1] != posY + || sFixedModeBasePosition[2] != posZ) { + basePosSet = TRUE; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + } + vec3f_set(sFixedModeBasePosition, posX, posY, posZ); + if (c->mode != CAMERA_MODE_FIXED) { + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + c->mode = CAMERA_MODE_FIXED; + vec3f_set(c->pos, sFixedModeBasePosition[0], sMarioCamState->pos[1], + sFixedModeBasePosition[2]); + } + return basePosSet; +} + +void set_camera_mode_8_directions(struct Camera *c) { + if (c->mode != CAMERA_MODE_8_DIRECTIONS) { + c->mode = CAMERA_MODE_8_DIRECTIONS; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + s8DirModeBaseYaw = 0; + s8DirModeYawOffset = 0; + } +} + +/** + * If the camera mode is not already the boss fight camera (camera with two foci) * set it to be so. */ -void set_camera_preset_boss_fight(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_BOSS_FIGHT) { - set_camera_preset(c, CAMERA_PRESET_BOSS_FIGHT, 15); - sFirstPersonCameraYaw = c->storedYaw - 0x2000; +void set_camera_mode_boss_fight(struct Camera *c) { + if (c->mode != CAMERA_MODE_BOSS_FIGHT) { + transition_to_camera_mode(c, CAMERA_MODE_BOSS_FIGHT, 15); + sModeOffsetYaw = c->nextYaw - DEGREES(45); } } -void set_camera_preset_close_cam(u8 *preset) { - if (*preset != CAMERA_PRESET_CLOSE) { - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - *preset = CAMERA_PRESET_CLOSE; +void set_camera_mode_close_cam(u8 *mode) { + if (*mode != CAMERA_MODE_CLOSE) { + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + *mode = CAMERA_MODE_CLOSE; } } -void set_camera_preset_open_camera(struct LevelCamera *c, s16 b) { +/** + * Change to radial mode. + * If the difference in yaw between pos -> mario and pos > focus is < 90 degrees, transition. + * Otherwise jump to radial mode. + */ +void set_camera_mode_radial(struct Camera *c, s16 transitionTime) { Vec3f focus; s16 yaw; - focus[0] = c->xFocus; - focus[1] = sMarioStatusForCamera->pos[1]; - focus[2] = c->zFocus; - if (c->currPreset != CAMERA_PRESET_OPEN_CAMERA) { - yaw = - calculate_yaw(focus, sMarioStatusForCamera->pos) - calculate_yaw(c->focus, c->pos) + 0x4000; + focus[0] = c->areaCenX; + focus[1] = sMarioCamState->pos[1]; + focus[2] = c->areaCenZ; + if (c->mode != CAMERA_MODE_RADIAL) { + yaw = calculate_yaw(focus, sMarioCamState->pos) - calculate_yaw(c->focus, c->pos) + DEGREES(90); if (yaw > 0) { - set_camera_preset(c, CAMERA_PRESET_OPEN_CAMERA, b); + transition_to_camera_mode(c, CAMERA_MODE_RADIAL, transitionTime); } else { - c->currPreset = CAMERA_PRESET_OPEN_CAMERA; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; + c->mode = CAMERA_MODE_RADIAL; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } - sFirstPersonCameraYaw = 0; + sModeOffsetYaw = 0; } } -void parallel_tracking_init(struct LevelCamera *a, struct ParallelTrackingTable *b) { - if (a->currPreset != CAMERA_PRESET_PARALLEL_TRACKING) { - D_8033B470 = b; - D_8033B46C = 0; - D_8033B478.pos[0] = 0.f; - D_8033B478.pos[1] = 0.f; - D_8033B478.pos[2] = 0.f; - a->pos[0] = (D_8033B470[0].unk4[0] + D_8033B470[1].unk4[0]) / 2.f; - a->pos[1] = (D_8033B470[0].unk4[1] + D_8033B470[1].unk4[1]) / 2.f; - a->pos[2] = (D_8033B470[0].unk4[2] + D_8033B470[1].unk4[2]) / 2.f; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - a->currPreset = CAMERA_PRESET_PARALLEL_TRACKING; +/** + * Start parallel tracking mode using the path `path` + */ +void parallel_tracking_init(struct Camera *c, struct ParallelTrackingPoint *path) { + if (c->mode != CAMERA_MODE_PARALLEL_TRACKING) { + sParTrackPath = path; + sParTrackIndex = 0; + sParTrackTransOff.pos[0] = 0.f; + sParTrackTransOff.pos[1] = 0.f; + sParTrackTransOff.pos[2] = 0.f; + // Place the camera in the middle of the path + c->pos[0] = (sParTrackPath[0].pos[0] + sParTrackPath[1].pos[0]) / 2.f; + c->pos[1] = (sParTrackPath[0].pos[1] + sParTrackPath[1].pos[1]) / 2.f; + c->pos[2] = (sParTrackPath[0].pos[2] + sParTrackPath[1].pos[2]) / 2.f; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + c->mode = CAMERA_MODE_PARALLEL_TRACKING; } } +/** + * Set the fixed camera base pos depending on the current level area + */ void set_fixed_cam_axis_sa_lobby(UNUSED s16 preset) { switch (gCurrLevelArea) { case AREA_SA: - vec3f_set(sFixedPresetBasePosition, 646.f, 143.f, -1513.f); + vec3f_set(sFixedModeBasePosition, 646.f, 143.f, -1513.f); break; case AREA_CASTLE_LOBBY: - vec3f_set(sFixedPresetBasePosition, -577.f, 143.f, 1443.f); + vec3f_set(sFixedModeBasePosition, -577.f, 143.f, 1443.f); break; } } -void func_8028D32C(u8 *preset) { - if ((sMarioStatusForCamera->action & ACT_FLAG_METAL_WATER) || *preset == CAMERA_PRESET_BEHIND_MARIO - || *preset == CAMERA_PRESET_WATER_SURFACE) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; +/** + * Block area-specific CameraTrigger and special surface modes. + * Generally, block area mode changes if: + * Mario is wearing the metal cap, or at the water's surface, or the camera is in mario mode + * + * However, if the level is WDW, DDD, or COTMC (levels that have metal cap and water): + * Only block area mode changes if mario is in a cannon, + * or if the camera is in mario mode and mario is not swimming or in water with the metal cap + */ +void check_blocking_area_processing(const u8 *mode) { + if (sMarioCamState->action & ACT_FLAG_METAL_WATER || + *mode == CAMERA_MODE_BEHIND_MARIO || *mode == CAMERA_MODE_WATER_SURFACE) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; } if (gCurrLevelNum == LEVEL_DDD || gCurrLevelNum == LEVEL_WDW || gCurrLevelNum == LEVEL_COTMC) { - gCameraFlags2 &= ~CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; + sStatusFlags &= ~CAM_FLAG_BLOCK_AREA_PROCESSING; } - if ((*preset == CAMERA_PRESET_BEHIND_MARIO - && !(sMarioStatusForCamera->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) - || *preset == CAMERA_PRESET_INSIDE_CANNON) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; + if ((*mode == CAMERA_MODE_BEHIND_MARIO && + !(sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) || + *mode == CAMERA_MODE_INSIDE_CANNON) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; } } -CmdRet CameraRR00(struct LevelCamera *c) { - set_camera_preset_platform_level(c); - sPlatformLevelPresetBaseYaw = 0x4000; +CmdRet cam_rr_exit_building_side(struct Camera *c) { + set_camera_mode_8_directions(c); + s8DirModeBaseYaw = DEGREES(90); } -CmdRet CameraRR04(struct LevelCamera *c) { - set_camera_preset_platform_level(c); +CmdRet cam_rr_exit_building_top(struct Camera *c) { + set_camera_mode_8_directions(c); if (c->pos[1] < 6343.f) { c->pos[1] = 7543.f; - gCameraStatus.camFocAndPosCurrAndGoal[3][1] = c->pos[1]; - gCameraStatus.camFocAndPosCurrAndGoal[1][1] = c->pos[1]; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; + gLakituState.goalPos[1] = c->pos[1]; + gLakituState.curPos[1] = c->pos[1]; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } } -CmdRet CameraRR02(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { - set_camera_preset_fixed_ref_point(c, -2974, 478, -3975); +CmdRet cam_rr_enter_building_window(struct Camera *c) { + if (c->mode != CAMERA_MODE_FIXED) { + set_camera_mode_fixed(c, -2974, 478, -3975); } } -CmdRet CameraRR0305(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { - set_camera_preset_fixed_ref_point(c, -2953, 798, -3943); +CmdRet cam_rr_enter_building(struct Camera *c) { + if (c->mode != CAMERA_MODE_FIXED) { + set_camera_mode_fixed(c, -2953, 798, -3943); } + // Prevent the camera from being above the roof if (c->pos[1] > 6043.f) { c->pos[1] = 6043.f; } } -CmdRet CameraRR01(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - c->currPreset = CAMERA_PRESET_FIXED_REF_POINT; +CmdRet cam_rr_enter_building_side(struct Camera *c) { + if (c->mode != CAMERA_MODE_FIXED) { + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + c->mode = CAMERA_MODE_FIXED; } } -CmdRet CameraCotMC00(UNUSED struct LevelCamera *c) { - gCameraMovementFlags |= CAM_MOVE_UNKNOWN_7; +/** + * Fix the camera in place as mario gets exits out the MC cave into the waterfall. + */ +CmdRet cam_cotmc_exit_waterfall(UNUSED struct Camera *c) { + gCameraMovementFlags |= CAM_MOVE_FIX_IN_PLACE; } -CmdRet CameraSL00(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; - set_camera_preset(c, CAMERA_PRESET_PLATFORM_LEVEL, 60); - sPlatformLevelPresetBaseYaw = 0x1D27; +/** + * Sets 8 directional mode and blocks the next trigger from processing. + * Activated when mario is walking in front of the snowman's head. + */ +CmdRet cam_sl_snowman_head_8dir(struct Camera *c) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; + transition_to_camera_mode(c, CAMERA_MODE_8_DIRECTIONS, 60); + s8DirModeBaseYaw = 0x1D27; } -CmdRet camera_change_set_free_roam_mode(struct LevelCamera *c) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 60); +/** + * Sets free roam mode in SL, called by a trigger that covers a large area and surrounds the 8 direction + * trigger. + */ +CmdRet cam_sl_free_roam(struct Camera *c) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 60); } -void move_camera_through_floor_while_descending(struct LevelCamera *c, f32 height) { +/** + * Warps the camera underneath the floor, used in HMC to move under the elevator platforms + */ +void move_camera_through_floor_while_descending(struct Camera *c, f32 height) { UNUSED f32 pad; - if ((sGeometryForMario.currFloorHeight < height - 100.f) - && (sGeometryForMario.prevFloorHeight > sGeometryForMario.currFloorHeight)) { + if ((sMarioGeometry.currFloorHeight < height - 100.f) + && (sMarioGeometry.prevFloorHeight > sMarioGeometry.currFloorHeight)) { c->pos[1] = height - 400.f; - gCameraStatus.camFocAndPosCurrAndGoal[1][1] = height - 400.f; - gCameraStatus.camFocAndPosCurrAndGoal[3][1] = height - 400.f; + gLakituState.curPos[1] = height - 400.f; + gLakituState.goalPos[1] = height - 400.f; } } -CmdRet camera_change_hmc_maze_entrance(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +CmdRet cam_hmc_enter_maze(struct Camera *c) { + s16 pitch, yaw; + f32 dist; if (c->pos[1] > -102.f) { - vec3f_get_dist_and_angle(c->focus, gCameraStatus.camFocAndPosCurrAndGoal[3], &sp20, &sp26, - &sp24); - vec3f_set_dist_and_angle(c->focus, gCameraStatus.camFocAndPosCurrAndGoal[3], 300.f, sp26, sp24); - gCameraStatus.camFocAndPosCurrAndGoal[3][1] = -800.f; + vec3f_get_dist_and_angle(c->focus, gLakituState.goalPos, &dist, &pitch, &yaw); + vec3f_set_dist_and_angle(c->focus, gLakituState.goalPos, 300.f, pitch, yaw); + gLakituState.goalPos[1] = -800.f; #ifndef VERSION_JP - c->pos[1] = gCameraStatus.camFocAndPosCurrAndGoal[3][1]; - gCameraStatus.camFocAndPosCurrAndGoal[1][1] = gCameraStatus.camFocAndPosCurrAndGoal[3][1]; + c->pos[1] = gLakituState.goalPos[1]; + gLakituState.curPos[1] = gLakituState.goalPos[1]; #endif - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } } -CmdRet CameraHMC02(struct LevelCamera *c) { +CmdRet cam_hmc_elevator_black_hole(struct Camera *c) { move_camera_through_floor_while_descending(c, 1536.f); } -CmdRet CameraHMC03(struct LevelCamera *c) { +CmdRet cam_hmc_elevator_maze_emergency_exit(struct Camera *c) { move_camera_through_floor_while_descending(c, 2355.f); } -CmdRet CameraHMC04(struct LevelCamera *c) { +CmdRet cam_hmc_elevator_lake(struct Camera *c) { move_camera_through_floor_while_descending(c, 1843.f); } -CmdRet CameraHMC05(struct LevelCamera *c) { +CmdRet cam_hmc_elevator_maze(struct Camera *c) { move_camera_through_floor_while_descending(c, 1843.f); } -CmdRet CameraSSL00(UNUSED struct LevelCamera *c) { - func_8028F834(CUTSCENE_ENTER_PYRAMID_TOP); +/** + * Starts the "Enter Pyramid Top" cutscene. + */ +CmdRet cam_ssl_enter_pyramid_top(UNUSED struct Camera *c) { + start_object_cutscene_without_focus(CUTSCENE_ENTER_PYRAMID_TOP); } -CmdRet CameraSSL0102(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; - set_camera_preset(c, CAMERA_PRESET_CLOSE, 90); +/** + * Change to close mode in the center of the pyramid. Outside this trigger, the default mode is outwards + * radial. + */ +CmdRet cam_ssl_pyramid_center(struct Camera *c) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; + transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 90); } -CmdRet CameraSSL03(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; - set_camera_preset(c, CAMERA_PRESET_REVERSE_TOWER, 90); +/** + * Changes the mode back to outward radial in the boss room inside the pyramid. + */ +CmdRet cam_ssl_boss_room(struct Camera *c) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; + transition_to_camera_mode(c, CAMERA_MODE_OUTWARD_RADIAL, 90); } -CmdRet CameraTHI00(UNUSED struct LevelCamera *c) { - if (sFirstPersonCameraYaw < 0x2AAA) { - sFirstPersonCameraYaw = 0x2AAA; +/** + * Moves the camera to through the tunnel by forcing sModeOffsetYaw + */ +CmdRet cam_thi_move_cam_through_tunnel(UNUSED struct Camera *c) { + if (sModeOffsetYaw < DEGREES(60)) { + sModeOffsetYaw = DEGREES(60); } } -CmdRet CameraTHI01(UNUSED struct LevelCamera *c) { - if (sFirstPersonCameraYaw > 0x3AAA) { - sFirstPersonCameraYaw = 0x3AAA; +/** + * Aligns the camera to look through the tunnel + */ +CmdRet cam_thi_look_through_tunnel(UNUSED struct Camera *c) { + // ~82.5 degrees + if (sModeOffsetYaw > 0x3AAA) { + sModeOffsetYaw = 0x3AAA; } } -CmdRet CameraRR07(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; - set_camera_preset(c, CAMERA_PRESET_OPEN_CAMERA, 90); +/** + * Unused. Changes the camera to radial mode when mario is on the tower. + * + * @see sCamBOB for bounds. + */ +CmdRet cam_bob_tower(struct Camera *c) { + sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; + transition_to_camera_mode(c, CAMERA_MODE_RADIAL, 90); } -CmdRet CameraRR08(struct LevelCamera *c) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 90); +/** + * Unused. Changes the camera to free roam mode when mario is not climbing the tower. + * + * This is the only CameraTrigger event that uses the area == -1 feature: + * If this was used, it would be called by default in BoB. + * + * @see sCamBOB + */ +CmdRet cam_bob_default_free_roam(struct Camera *c) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); } -CmdRet camera_change_hmc_cotmc_pool_entry(struct LevelCamera *c) { - if ((sMarioStatusForCamera->action != ACT_SPECIAL_DEATH_EXIT) - && (sMarioStatusForCamera->action != ACT_SPECIAL_EXIT_AIRBORNE)) { - set_camera_cutscene_table(c, CUTSCENE_ENTER_POOL); +/** + * Starts the pool entrance cutscene if mario is not exiting the pool. + * Used in both the castle and HMC. + */ +CmdRet cam_castle_hmc_start_pool_cutscene(struct Camera *c) { + if ((sMarioCamState->action != ACT_SPECIAL_DEATH_EXIT) + && (sMarioCamState->action != ACT_SPECIAL_EXIT_AIRBORNE)) { + start_cutscene(c, CUTSCENE_ENTER_POOL); } } -CmdRet CameraInside20(UNUSED struct LevelCamera *c) { - vec3f_set(sFixedPresetBasePositionOffset, -813.f - sFixedPresetBasePosition[0], - 378.f - sFixedPresetBasePosition[1], 1103.f - sFixedPresetBasePosition[2]); +/** + * Sets the fixed mode pos offset so that the camera faces the doorway when mario is near the entrance + * to the castle lobby + */ +CmdRet cam_castle_lobby_entrance(UNUSED struct Camera *c) { + vec3f_set(sCastleEntranceOffset, -813.f - sFixedModeBasePosition[0], + 378.f - sFixedModeBasePosition[1], 1103.f - sFixedModeBasePosition[2]); } -CmdRet CameraInside1E(struct LevelCamera *c) { +/** + * Make the camera look up the stairs from the 2nd to 3rd floor of the castle + */ +CmdRet cam_castle_look_upstairs(struct Camera *c) { struct Surface *floor; f32 floorHeight = find_floor(c->pos[0], c->pos[1], c->pos[2], &floor); - if ((sGeometryForMario.currFloorHeight > 1229.f) && (floorHeight < 1229.f) + // If mario is on the first few steps, fix the camera pos, making it look up + if ((sMarioGeometry.currFloorHeight > 1229.f) && (floorHeight < 1229.f) && (sCSideButtonYaw == 0)) { vec3f_set(c->pos, -227.f, 1425.f, 1533.f); } } -CmdRet CameraInside1F(struct LevelCamera *c) { +/** + * Make the camera look down the stairs towards the basement star door + */ +CmdRet cam_castle_basement_look_downstairs(struct Camera *c) { struct Surface *floor; f32 floorHeight = find_floor(c->pos[0], c->pos[1], c->pos[2], &floor); + // Fix the camera pos, making it look downwards. Only active on the top few steps if ((floorHeight > -110.f) && (sCSideButtonYaw == 0)) { vec3f_set(c->pos, -980.f, 249.f, -1398.f); } } -CmdRet CameraInside01(struct LevelCamera *c) { - if (c->currPreset != CAMERA_PRESET_FIXED_REF_POINT) { - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - set_fixed_cam_axis_sa_lobby(c->currPreset); - c->currPreset = CAMERA_PRESET_FIXED_REF_POINT; +/** + * Enter the fixed-mode castle lobby. A trigger for this is placed in every entrance so that the camera + * changes to fixed mode. + */ +CmdRet cam_castle_enter_lobby(struct Camera *c) { + if (c->mode != CAMERA_MODE_FIXED) { + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + set_fixed_cam_axis_sa_lobby(c->mode); + c->mode = CAMERA_MODE_FIXED; } } -CmdRet CameraInside1213(struct LevelCamera *c) { - set_camera_preset(c, CAMERA_PRESET_SPIRAL_STAIRS, 20); +/** + * Starts spiral stairs mode. + */ +CmdRet cam_castle_enter_spiral_stairs(struct Camera *c) { + transition_to_camera_mode(c, CAMERA_MODE_SPIRAL_STAIRS, 20); } -static CmdRet CameraUnused(struct LevelCamera *c) { - if (c->currPreset == CAMERA_PRESET_SPIRAL_STAIRS) { - set_camera_preset(c, CAMERA_PRESET_CLOSE, 30); +/** + * unused, starts close mode if the camera is in spiral stairs mode. + * This was replaced with cam_castle_close_mode + */ +static UNUSED CmdRet cam_castle_leave_spiral_stairs(struct Camera *c) { + if (c->mode == CAMERA_MODE_SPIRAL_STAIRS) { + transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 30); } else { - set_camera_preset_close_cam(&c->currPreset); + set_camera_mode_close_cam(&c->mode); } } -CmdRet CameraInside00(struct LevelCamera *c) { - set_camera_preset_close_cam(&c->currPreset); +/** + * The default mode when outside of the lobby and spiral staircase. A trigger for this is placed at + * every door leaving the lobby and spiral staircase. + */ +CmdRet cam_castle_close_mode(struct Camera *c) { + set_camera_mode_close_cam(&c->mode); } -CmdRet CameraInside0E(struct LevelCamera *c) { - CameraInside00(c); - c->unk64 = 2; +/** + * Functions the same as cam_castle_close_mode, but sets doorStatus so that the camera will enter + * fixed-mode when mario leaves the room. + */ +CmdRet cam_castle_leave_lobby_sliding_door(struct Camera *c) { + cam_castle_close_mode(c); + c->doorStatus = DOOR_ENTER_LOBBY; } -CmdRet CameraInside0F(struct LevelCamera *c) { - CameraInside01(c); +/** + * Just calls cam_castle_enter_lobby + */ +CmdRet cam_castle_enter_lobby_sliding_door(struct Camera *c) { + cam_castle_enter_lobby(c); } -CmdRet bbh_room_6_camera(struct LevelCamera *c) { - parallel_tracking_init(c, BBHRoom6ParallelTrackingTable); +CmdRet cam_bbh_room_6(struct Camera *c) { + parallel_tracking_init(c, sBBHLibraryParTrackPath); } -CmdRet CameraBBH24(struct LevelCamera *c) { - set_camera_preset_close_cam(&c->currPreset); +CmdRet cam_bbh_fall_off_roof(struct Camera *c) { + set_camera_mode_close_cam(&c->mode); } -CmdRet CameraBBH2E2F(struct LevelCamera *c) { - Vec3f relativePosition; - set_camera_preset_close_cam(&c->currPreset); - vec3f_set(relativePosition, 0.f, 0.f, 300.f); - set_pos_from_face_angle_and_vec3f(gCameraStatus.camFocAndPosCurrAndGoal[3], - sMarioStatusForCamera->pos, relativePosition, - sMarioStatusForCamera->faceAngle); - gCameraStatus.camFocAndPosCurrAndGoal[3][1] = -2300.f; - vec3f_copy(c->pos, gCameraStatus.camFocAndPosCurrAndGoal[3]); - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; +CmdRet cam_bbh_fall_into_pool(struct Camera *c) { + Vec3f dir; + set_camera_mode_close_cam(&c->mode); + vec3f_set(dir, 0.f, 0.f, 300.f); + offset_rotated(gLakituState.goalPos, sMarioCamState->pos, dir, sMarioCamState->faceAngle); + gLakituState.goalPos[1] = -2300.f; + vec3f_copy(c->pos, gLakituState.goalPos); + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet bbh_room_1_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 956, 440, 1994); +CmdRet cam_bbh_room_1(struct Camera *c) { + set_camera_mode_fixed(c, 956, 440, 1994); } -CmdRet CameraBBH01(struct LevelCamera *c) { - c->unk64 = 1; - bbh_room_1_camera(c); +CmdRet cam_bbh_leave_front_door(struct Camera *c) { + c->doorStatus = DOOR_LEAVING_SPECIAL; + cam_bbh_room_1(c); } -CmdRet bbh_room_2_lower_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 2591, 400, 1284); +CmdRet cam_bbh_room_2_lower(struct Camera *c) { + set_camera_mode_fixed(c, 2591, 400, 1284); } -CmdRet bbh_room_4_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 3529, 340, -1384); +CmdRet cam_bbh_room_4(struct Camera *c) { + set_camera_mode_fixed(c, 3529, 340, -1384); } -CmdRet bbh_room_8_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, -500, 740, -1306); +CmdRet cam_bbh_room_8(struct Camera *c) { + set_camera_mode_fixed(c, -500, 740, -1306); } /** * In BBH's room 5's library (the first floor room with the vanish cap/boo painting) - * set the camera preset to fixed and position to (-2172, 200, 675) + * set the camera mode to fixed and position to (-2172, 200, 675) */ -CmdRet bbh_room_5_library_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, -2172, 200, 675); +CmdRet cam_bbh_room_5_library(struct Camera *c) { + set_camera_mode_fixed(c, -2172, 200, 675); } /** * In BBH's room 5 (the first floor room with the vanish cap/boo painting) - * set the camera preset to to the hidden room's position + * set the camera mode to to the hidden room's position * if coming from the library. */ -CmdRet bbh_room_5_library_to_hidden_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, -2172, 200, 675) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_5_library_to_hidden_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, -2172, 200, 675) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_5_hidden_to_library_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, -1542, 320, -307) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_5_hidden_to_library_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, -1542, 320, -307) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_5_hidden_camera(struct LevelCamera *c) { - c->unk64 = 1; - set_camera_preset_fixed_ref_point(c, -1542, 320, -307); +CmdRet cam_bbh_room_5_hidden(struct Camera *c) { + c->doorStatus = DOOR_LEAVING_SPECIAL; + set_camera_mode_fixed(c, -1542, 320, -307); } -CmdRet bbh_room_3_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, -1893, 320, 2327); +CmdRet cam_bbh_room_3(struct Camera *c) { + set_camera_mode_fixed(c, -1893, 320, 2327); } -CmdRet bbh_room_7_mr_i_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 1371, 360, -1302); +CmdRet cam_bbh_room_7_mr_i(struct Camera *c) { + set_camera_mode_fixed(c, 1371, 360, -1302); } -CmdRet bbh_room_7_mr_i_to_coffins_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, 1371, 360, -1302) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_7_mr_i_to_coffins_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, 1371, 360, -1302) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_7_coffins_to_mr_i_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, 2115, 260, -772) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_7_coffins_to_mr_i_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, 2115, 260, -772) == 1) { + transition_next_state(c, 20); } } -CmdRet CameraBBH3033(struct LevelCamera *c) { - c->unk64 = 1; - set_camera_preset_close_cam(&c->currPreset); +CmdRet cam_bbh_elevator_room_lower(struct Camera *c) { + c->doorStatus = DOOR_LEAVING_SPECIAL; + set_camera_mode_close_cam(&c->mode); } -CmdRet CameraBBH34(struct LevelCamera *c) { - set_camera_preset_close_cam(&c->currPreset); +CmdRet cam_bbh_room_0_back_entrance(struct Camera *c) { + set_camera_mode_close_cam(&c->mode); } -CmdRet CameraBBH38(struct LevelCamera *c) { - if (c->currPreset == CAMERA_PRESET_FIXED_REF_POINT) { - set_camera_preset_close_cam(&c->currPreset); +CmdRet cam_bbh_elevator(struct Camera *c) { + if (c->mode == CAMERA_MODE_FIXED) { + set_camera_mode_close_cam(&c->mode); c->pos[1] = -405.f; - gCameraStatus.camFocAndPosCurrAndGoal[3][1] = -405.f; + gLakituState.goalPos[1] = -405.f; } } -CmdRet bbh_room_12_upper_camera(struct LevelCamera *c) { - c->unk64 = 1; - set_camera_preset_fixed_ref_point(c, -2932, 296, 4429); +CmdRet cam_bbh_room_12_upper(struct Camera *c) { + c->doorStatus = DOOR_LEAVING_SPECIAL; + set_camera_mode_fixed(c, -2932, 296, 4429); } -CmdRet CameraBBH00(struct LevelCamera *c) { - set_camera_preset_close_cam(&c->currPreset); +CmdRet cam_bbh_enter_front_door(struct Camera *c) { + set_camera_mode_close_cam(&c->mode); } -CmdRet bbh_room_2_library_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 3493, 440, 617); +CmdRet cam_bbh_room_2_library(struct Camera *c) { + set_camera_mode_fixed(c, 3493, 440, 617); } -CmdRet bbh_room_2_library_to_trapdoor_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, 3493, 440, 617) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_2_library_to_trapdoor_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, 3493, 440, 617) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_2_trapdoor_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 3502, 440, 1217); +CmdRet cam_bbh_room_2_trapdoor(struct Camera *c) { + set_camera_mode_fixed(c, 3502, 440, 1217); } -CmdRet bbh_room_2_trapdoor_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, 3502, 440, 1217) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_2_trapdoor_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, 3502, 440, 1217) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_9_attic_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, -670, 460, 372); +CmdRet cam_bbh_room_9_attic(struct Camera *c) { + set_camera_mode_fixed(c, -670, 460, 372); } -CmdRet bbh_room_9_attic_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, -670, 460, 372) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_9_attic_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, -670, 460, 372) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_9_mr_i_transition(struct LevelCamera *c) { - if (set_camera_preset_fixed_ref_point(c, 131, 380, -263) == 1) { - init_transitional_movement(c, 20); +CmdRet cam_bbh_room_9_mr_i_transition(struct Camera *c) { + if (set_camera_mode_fixed(c, 131, 380, -263) == 1) { + transition_next_state(c, 20); } } -CmdRet bbh_room_13_balcony_camera(struct LevelCamera *c) { - set_camera_preset_fixed_ref_point(c, 210, 420, 3109); +CmdRet cam_bbh_room_13_balcony(struct Camera *c) { + set_camera_mode_fixed(c, 210, 420, 3109); } -CmdRet bbh_room_0_camera(struct LevelCamera *c) { - c->unk64 = 1; - set_camera_preset_fixed_ref_point(c, -204, 807, 204); +CmdRet cam_bbh_room_0(struct Camera *c) { + c->doorStatus = DOOR_LEAVING_SPECIAL; + set_camera_mode_fixed(c, -204, 807, 204); } -CmdRet camera_change_activate_ccm_slide_flag(UNUSED struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_CCM_SLIDE_SHORTCUT; +CmdRet cam_ccm_enter_slide_shortcut(UNUSED struct Camera *c) { + sStatusFlags |= CAM_FLAG_CCM_SLIDE_SHORTCUT; } -CmdRet camera_change_deactivate_ccm_slide_flag(UNUSED struct LevelCamera *c) { - gCameraFlags2 &= ~CAM_FLAG_2_CCM_SLIDE_SHORTCUT; +CmdRet cam_ccm_leave_slide_shortcut(UNUSED struct Camera *c) { + sStatusFlags &= ~CAM_FLAG_CCM_SLIDE_SHORTCUT; } -u32 surface_type_presets(struct LevelCamera *c) { - u32 presetChanged = 0; +/** + * Apply any modes that are triggered by special floor surface types + */ +u32 surface_type_modes(struct Camera *c) { + u32 modeChanged = 0; - switch (sGeometryForMario.currFloorType) { + switch (sMarioGeometry.currFloorType) { case SURFACE_CLOSE_CAMERA: - set_camera_preset(c, CAMERA_PRESET_CLOSE, 90); - presetChanged += 1; + transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 90); + modeChanged += 1; break; case SURFACE_CAMERA_FREE_ROAM: - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 90); - presetChanged += 1; + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); + modeChanged += 1; break; case SURFACE_NO_CAM_COL_SLIPPERY: - set_camera_preset(c, CAMERA_PRESET_CLOSE, 90); - presetChanged += 1; + transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 90); + modeChanged += 1; break; } - return presetChanged; + return modeChanged; } -u32 set_preset_via_surface_or_input(struct LevelCamera *c, u8 preset) { - u32 sp1C = 0; - sp1C = surface_type_presets(c); +/** + * Set the camera mode to `mode` if mario is not standing on a special surface + */ +u32 set_mode_if_not_set_by_surface(struct Camera *c, u8 mode) { + u32 modeChanged = 0; + modeChanged = surface_type_modes(c); - if ((sp1C == 0) && (preset != 0)) { - set_camera_preset(c, preset, 90); + if ((modeChanged == 0) && (mode != 0)) { + transition_to_camera_mode(c, mode, 90); } - return sp1C; + return modeChanged; } -void surface_type_presets_thi(struct LevelCamera *c) { - switch (sGeometryForMario.currFloorType) { +/** + * Used in THI, check if mario is standing on any of the special surfaces in that area + */ +void surface_type_modes_thi(struct Camera *c) { + switch (sMarioGeometry.currFloorType) { case SURFACE_CLOSE_CAMERA: - if (c->currPreset != CAMERA_PRESET_CLOSE) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 90); + if (c->mode != CAMERA_MODE_CLOSE) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); } break; case SURFACE_CAMERA_FREE_ROAM: - if (c->currPreset != CAMERA_PRESET_CLOSE) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 90); + if (c->mode != CAMERA_MODE_CLOSE) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); } break; case SURFACE_NO_CAM_COL_SLIPPERY: - if (c->currPreset != CAMERA_PRESET_CLOSE) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 90); + if (c->mode != CAMERA_MODE_CLOSE) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); } break; - case SURFACE_CAMERA_PLATFORM: - set_camera_preset(c, CAMERA_PRESET_PLATFORM_LEVEL, 90); + case SURFACE_CAMERA_8_DIR: + transition_to_camera_mode(c, CAMERA_MODE_8_DIRECTIONS, 90); break; default: - set_camera_preset(c, CAMERA_PRESET_OPEN_CAMERA, 90); + transition_to_camera_mode(c, CAMERA_MODE_RADIAL, 90); } } -#define TABLE_EMPTY \ +/** + * Terminates a list of CameraTriggers. + */ +#define NULL_TRIGGER \ { 0, NULL, 0, 0, 0, 0, 0, 0, 0 } /** - * The SL Table operates camera behavior in front of the snowman who blows air. - * The first sets a special preset, while the latter (which encompasses the former) - * sets it back. + * The SL triggers operate camera behavior in front of the snowman who blows air. + * The first sets a 8 direction mode, while the latter (which encompasses the former) + * sets free roam mode. * * This behavior is exploitable, since the ranges assume that Mario must pass through the latter on * exit. Using hyperspeed, the earlier area can be directly exited from, keeping the changes it applies. */ -struct TableCamera TableCameraSL[3] = { { 1, CameraSL00, 1119, 3584, 1125, 1177, 358, 358, -7463 }, - { 1, camera_change_set_free_roam_mode, 1119, 3584, 1125, 4096, - 4096, 4096, -7463 }, - TABLE_EMPTY }; +struct CameraTrigger sCamSL[] = { + { 1, cam_sl_snowman_head_8dir, 1119, 3584, 1125, 1177, 358, 358, -0x1D27 }, + // This trigger surrounds the previous one + { 1, cam_sl_free_roam, 1119, 3584, 1125, 4096, 4096, 4096, -0x1D27 }, + NULL_TRIGGER +}; /** - * The THI table is specifically for the tunnel near the start of the Huge Island. - * The first aligns with the tunnel, the latter helps the camera from getting stuck on the - * starting side. Both sides achieve their effect by editing the camera yaw. + * The THI triggers are specifically for the tunnel near the start of the Huge Island. + * The first helps the camera from getting stuck on the starting side, the latter aligns with the + * tunnel. Both sides achieve their effect by editing the camera yaw. */ -struct TableCamera TableCameraTHI[3] = { { 1, CameraTHI00, -4609, -2969, 6448, 100, 300, 300, 0 }, - { 1, CameraTHI01, -4809, -2969, 6448, 100, 300, 300, 0 }, - TABLE_EMPTY }; - -struct TableCamera TableCameraHMC[7] = { - { 1, camera_change_hmc_maze_entrance, 1996, 102, 0, 205, 100, 205, 0 }, - { 1, camera_change_hmc_cotmc_pool_entry, 3350, -4689, 4800, 600, 50, 600, 0 }, - { 1, CameraHMC02, -3278, 1236, 1379, 358, 200, 358, 0 }, - { 1, CameraHMC03, -2816, 2055, -2560, 358, 200, 358, 0 }, - { 1, CameraHMC04, -3532, 1543, -7040, 358, 200, 358, 0 }, - { 1, CameraHMC05, -972, 1543, -7347, 358, 200, 358, 0 }, - TABLE_EMPTY +struct CameraTrigger sCamTHI[] = { + { 1, cam_thi_move_cam_through_tunnel, -4609, -2969, 6448, 100, 300, 300, 0 }, + { 1, cam_thi_look_through_tunnel, -4809, -2969, 6448, 100, 300, 300, 0 }, + NULL_TRIGGER }; -struct TableCamera TableCameraSSL[5] = { { 1, CameraSSL00, -2048, 1080, -1024, 150, 150, 150, 0 }, - { 2, CameraSSL0102, 0, -104, -104, 1248, 1536, 2950, 0 }, - { 2, CameraSSL0102, 0, 2500, 256, 515, 5000, 515, 0 }, - { 3, CameraSSL03, 0, -1534, -2040, 1000, 800, 1000, 0 }, - TABLE_EMPTY }; - -struct TableCamera TableCameraRR[10] = { { 1, CameraRR00, -4197, 3819, -3087, 1769, 1490, 342, 0 }, - { 1, CameraRR01, -4197, 3819, -3771, 769, 490, 342, 0 }, - { 1, CameraRR02, -5603, 4834, -5209, 300, 600, 591, 0 }, - { 1, CameraRR0305, -2609, 3730, -5463, 300, 650, 577, 0 }, - { 1, CameraRR04, -4196, 7343, -5155, 4500, 1000, 4500, 0 }, - { 1, CameraRR0305, -4196, 6043, -5155, 500, 300, 500, 0 }, - TABLE_EMPTY, - { 1, CameraRR07, 2468, 2720, -4608, 3263, 1696, 3072, 0 }, - { -1, CameraRR08, 0, 0, 0, 0, 0, 0, 0 }, - TABLE_EMPTY }; - -struct TableCamera TableCameraCotMC[2] = { { 1, CameraCotMC00, 0, 1500, 3500, 550, 10000, 1500, 0 }, - TABLE_EMPTY }; - -struct TableCamera TableCameraCCM[3] = { - { 2, camera_change_activate_ccm_slide_flag, -4846, 2061, 27, 1229, 1342, 396, 0 }, - { 2, camera_change_deactivate_ccm_slide_flag, -6412, -3917, -6246, 307, 185, 132, 0 }, - TABLE_EMPTY +/** + * The HMC triggers are mostly for warping the camera below platforms, but the second trigger is used to + * start the cutscene for entering the CotMC pool. + */ +struct CameraTrigger sCamHMC[] = { + { 1, cam_hmc_enter_maze, 1996, 102, 0, 205, 100, 205, 0 }, + { 1, cam_castle_hmc_start_pool_cutscene, 3350, -4689, 4800, 600, 50, 600, 0 }, + { 1, cam_hmc_elevator_black_hole, -3278, 1236, 1379, 358, 200, 358, 0 }, + { 1, cam_hmc_elevator_maze_emergency_exit, -2816, 2055, -2560, 358, 200, 358, 0 }, + { 1, cam_hmc_elevator_lake, -3532, 1543, -7040, 358, 200, 358, 0 }, + { 1, cam_hmc_elevator_maze, -972, 1543, -7347, 358, 200, 358, 0 }, + NULL_TRIGGER }; -struct TableCamera TableCameraInside[35] = { - { 1, CameraInside00, -1100, 657, -1346, 300, 150, 300, 0 }, - { 1, CameraInside01, -1099, 657, -803, 300, 150, 300, 0 }, - { 1, CameraInside00, -2304, -264, -4072, 140, 150, 140, 0 }, - { 1, CameraInside00, -2304, 145, -1344, 140, 150, 140, 0 }, - { 1, CameraInside01, -2304, 145, -802, 140, 150, 140, 0 }, - { 1, CameraInside00, 2816, 1200, -256, 100, 100, 100, 0 }, - { 1, CameraInside00, 256, -161, -4226, 140, 150, 140, 0 }, - { 1, CameraInside00, 256, 145, -1344, 140, 150, 140, 0 }, - { 1, CameraInside01, 256, 145, -802, 140, 150, 140, 0 }, - { 1, CameraInside00, -1023, 44, -4870, 140, 150, 140, 0 }, - { 1, CameraInside00, -459, 145, -1020, 140, 150, 140, 24576 }, - { 1, CameraInside01, -85, 145, -627, 140, 150, 140, 0 }, - { 1, CameraInside00, -1589, 145, -1020, 140, 150, 140, -24576 }, - { 1, CameraInside01, -1963, 145, -627, 140, 150, 140, 0 }, - { 1, CameraInside0E, -2838, 657, -1659, 200, 150, 150, 8192 }, - { 1, CameraInside0F, -2319, 512, -1266, 300, 150, 300, 8192 }, - { 1, CameraInside00, 844, 759, -1657, 40, 150, 40, -8192 }, - { 1, CameraInside01, 442, 759, -1292, 140, 150, 140, -8192 }, - { 2, CameraInside1213, -1000, 657, 1740, 200, 300, 200, 0 }, - { 2, CameraInside1213, -996, 1348, 1814, 200, 300, 200, 0 }, - { 2, CameraInside00, -946, 657, 2721, 50, 150, 50, 0 }, - { 2, CameraInside00, -996, 1348, 907, 50, 150, 50, 0 }, - { 2, CameraInside00, -997, 1348, 1450, 140, 150, 140, 0 }, - { 1, CameraInside00, -4942, 452, -461, 140, 150, 140, 16384 }, - { 1, CameraInside00, -3393, 350, -793, 140, 150, 140, 16384 }, - { 1, CameraInside01, -2851, 350, -792, 140, 150, 140, 16384 }, - { 1, CameraInside01, 803, 350, -228, 140, 150, 140, -16384 }, - { 1, CameraInside01, 803, 350, -228, 140, 150, 140, -16384 }, - { 1, CameraInside00, 1345, 350, -229, 140, 150, 140, 16384 }, - { 1, CameraInside00, -946, -929, 622, 300, 150, 300, 0 }, - { 2, CameraInside1E, -205, 1456, 2508, 210, 928, 718, 0 }, - { 1, CameraInside1F, -1027, -587, -718, 318, 486, 577, 0 }, - { 1, CameraInside20, -1023, 376, 1830, 300, 400, 300, 0 }, - { 3, camera_change_hmc_cotmc_pool_entry, 2485, -1689, -2659, 600, 50, 600, 0 }, - TABLE_EMPTY +/** + * The SSL triggers are for starting the enter pyramid top cutscene, + * setting close mode in the middle of the pyramid, and setting the boss fight camera mode to outward + * radial. + */ +struct CameraTrigger sCamSSL[] = { + { 1, cam_ssl_enter_pyramid_top, -2048, 1080, -1024, 150, 150, 150, 0 }, + { 2, cam_ssl_pyramid_center, 0, -104, -104, 1248, 1536, 2950, 0 }, + { 2, cam_ssl_pyramid_center, 0, 2500, 256, 515, 5000, 515, 0 }, + { 3, cam_ssl_boss_room, 0, -1534, -2040, 1000, 800, 1000, 0 }, + NULL_TRIGGER }; -struct TableCamera TableCameraBBH[61] = { - { 1, CameraBBH00, 742, 0, 2369, 200, 200, 200, 0 }, - { 1, CameraBBH01, 741, 0, 1827, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 222, 0, 1458, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 222, 0, 639, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 435, 0, 222, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1613, 0, 222, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1827, 0, 1459, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, -495, 819, 1407, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, -495, 819, 640, 250, 200, 200, 0 }, - { 1, bbh_room_1_camera, 179, 819, 222, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1613, 819, 222, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1827, 819, 486, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1827, 819, 1818, 200, 200, 200, 0 }, - { 1, bbh_room_2_lower_camera, 2369, 0, 1459, 200, 200, 200, 0 }, - { 1, bbh_room_2_lower_camera, 3354, 0, 1347, 200, 200, 200, 0 }, - { 1, bbh_room_2_lower_camera, 2867, 514, 1843, 512, 102, 409, 0 }, - { 1, bbh_room_4_camera, 3354, 0, 804, 200, 200, 200, 0 }, - { 1, bbh_room_4_camera, 1613, 0, -320, 200, 200, 200, 0 }, - { 1, bbh_room_8_camera, 435, 0, -320, 200, 200, 200, 0 }, - { 1, bbh_room_5_library_camera, -2021, 0, 803, 200, 200, 200, 0 }, - { 1, bbh_room_5_library_camera, -320, 0, 640, 200, 200, 200, 0 }, - { 1, bbh_room_5_library_to_hidden_transition, -1536, 358, -254, 716, 363, 102, 0 }, - { 1, bbh_room_5_hidden_to_library_transition, -1536, 358, -459, 716, 363, 102, 0 }, - { 1, bbh_room_5_hidden_camera, -1560, 0, -1314, 200, 200, 200, 0 }, - { 1, bbh_room_3_camera, -320, 0, 1459, 200, 200, 200, 0 }, - { 1, bbh_room_3_camera, -2021, 0, 1345, 200, 200, 200, 0 }, - { 1, bbh_room_2_library_camera, 2369, 819, 486, 200, 200, 200, 0 }, - { 1, bbh_room_2_library_camera, 2369, 1741, 486, 200, 200, 200, 0 }, - { 1, bbh_room_2_library_to_trapdoor_transition, 2867, 1228, 1174, 716, 414, 102, 0 }, - { 1, bbh_room_2_trapdoor_transition, 2867, 1228, 1378, 716, 414, 102, 0 }, - { 1, bbh_room_2_trapdoor_camera, 2369, 819, 1818, 200, 200, 200, 0 }, - { 1, bbh_room_9_attic_camera, 1829, 1741, 486, 200, 200, 200, 0 }, - { 1, bbh_room_9_attic_camera, 741, 1741, 1587, 200, 200, 200, 0 }, - { 1, bbh_room_9_attic_transition, 102, 2048, -191, 100, 310, 307, 0 }, - { 1, bbh_room_9_mr_i_transition, 409, 2048, -191, 100, 310, 307, 0 }, - { 1, bbh_room_13_balcony_camera, 742, 1922, 2164, 200, 200, 200, 0 }, - { 1, CameraBBH24, 587, 1322, 2677, 1000, 400, 600, 0 }, - { 1, bbh_room_3_camera, -1037, 819, 1408, 200, 200, 200, 0 }, - { 1, bbh_room_3_camera, -1970, 1024, 1345, 200, 200, 200, 0 }, - { 1, bbh_room_8_camera, 179, 819, -320, 200, 200, 200, 0 }, - { 1, bbh_room_7_mr_i_camera, 1613, 819, -320, 200, 200, 200, 0 }, - { 1, bbh_room_7_mr_i_to_coffins_transition, 2099, 1228, -819, 102, 414, 716, 0 }, - { 1, bbh_room_7_coffins_to_mr_i_transition, 2304, 1228, -819, 102, 414, 716, 0 }, - { 1, bbh_room_6_camera, -1037, 819, 640, 200, 200, 200, 0 }, - { 1, bbh_room_6_camera, -1970, 1024, 803, 200, 200, 200, 0 }, - { 1, bbh_room_1_camera, 1827, 819, 1818, 200, 200, 200, 0 }, - { 1, CameraBBH2E2F, 2355, -1112, -193, 1228, 500, 1343, 0 }, - { 1, CameraBBH2E2F, 2355, -1727, 1410, 1228, 500, 705, 0 }, - { 1, CameraBBH3033, 0, -2457, 1827, 250, 200, 250, 0 }, - { 1, CameraBBH3033, 0, -2457, 2369, 250, 200, 250, 0 }, - { 1, CameraBBH3033, 0, -2457, 4929, 250, 200, 250, 0 }, - { 1, CameraBBH3033, 0, -2457, 4387, 250, 200, 250, 0 }, - { 1, CameraBBH34, 1887, -2457, 204, 250, 200, 250, 0 }, - { 1, bbh_room_0_camera, 1272, -2457, 204, 250, 200, 250, 0 }, - { 1, bbh_room_0_camera, -1681, -2457, 204, 250, 200, 250, 0 }, - { 1, CameraBBH34, -2296, -2457, 204, 250, 200, 250, 0 }, - { 1, CameraBBH38, -2939, -605, 5367, 800, 100, 800, 0 }, - { 1, bbh_room_12_upper_camera, -2939, -205, 5367, 300, 100, 300, 0 }, - { 1, bbh_room_12_upper_camera, -2332, -204, 4714, 250, 200, 250, 24576 }, - { 1, CameraBBH34, -1939, -204, 4340, 250, 200, 250, 24576 }, - TABLE_EMPTY +/** + * The RR triggers are for changing between fixed and 8 direction mode when entering / leaving the building at + * the end of the ride. + */ +struct CameraTrigger sCamRR[] = { + { 1, cam_rr_exit_building_side, -4197, 3819, -3087, 1769, 1490, 342, 0 }, + { 1, cam_rr_enter_building_side, -4197, 3819, -3771, 769, 490, 342, 0 }, + { 1, cam_rr_enter_building_window, -5603, 4834, -5209, 300, 600, 591, 0 }, + { 1, cam_rr_enter_building, -2609, 3730, -5463, 300, 650, 577, 0 }, + { 1, cam_rr_exit_building_top, -4196, 7343, -5155, 4500, 1000, 4500, 0 }, + { 1, cam_rr_enter_building, -4196, 6043, -5155, 500, 300, 500, 0 }, + NULL_TRIGGER, +}; + +/** + * These triggers are unused, but because the first trigger surrounds the BoB tower and activates radial + * mode (which is called "tower mode" in the patent), it's speculated they belonged to BoB. + * + * This table contains the only instance of a CameraTrigger with an area set to -1, and it sets the mode + * to free_roam when mario is not walking up the tower. + */ +struct CameraTrigger sCamBOB[] = { + { 1, cam_bob_tower, 2468, 2720, -4608, 3263, 1696, 3072, 0 }, + { -1, cam_bob_default_free_roam, 0, 0, 0, 0, 0, 0, 0 }, + NULL_TRIGGER +}; + +/** + * The CotMC trigger is only used to prevent fix lakitu in place when mario exits through the waterfall. + */ +struct CameraTrigger sCamCotMC[] = { + { 1, cam_cotmc_exit_waterfall, 0, 1500, 3500, 550, 10000, 1500, 0 }, + NULL_TRIGGER +}; + +/** + * The CCM triggers are used to set the flag that says when Mario is in the slide shortcut. + */ +struct CameraTrigger sCamCCM[] = { + { 2, cam_ccm_enter_slide_shortcut, -4846, 2061, 27, 1229, 1342, 396, 0 }, + { 2, cam_ccm_leave_slide_shortcut, -6412, -3917, -6246, 307, 185, 132, 0 }, + NULL_TRIGGER +}; + +/** + * The Castle triggers are used to set the camera to fixed mode when entering the lobby, and to set it + * to close mode when leaving it. They also set the mode to spiral staircase. + * + * There are two triggers for looking up and down straight staircases when mario is at the start, + * and one trigger that starts the enter pool cutscene when mario enters HMC. + */ +struct CameraTrigger sCamCastle[] = { + { 1, cam_castle_close_mode, -1100, 657, -1346, 300, 150, 300, 0 }, + { 1, cam_castle_enter_lobby, -1099, 657, -803, 300, 150, 300, 0 }, + { 1, cam_castle_close_mode, -2304, -264, -4072, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, -2304, 145, -1344, 140, 150, 140, 0 }, + { 1, cam_castle_enter_lobby, -2304, 145, -802, 140, 150, 140, 0 }, + //! Sets the camera mode when leaving secret aquarium + { 1, cam_castle_close_mode, 2816, 1200, -256, 100, 100, 100, 0 }, + { 1, cam_castle_close_mode, 256, -161, -4226, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, 256, 145, -1344, 140, 150, 140, 0 }, + { 1, cam_castle_enter_lobby, 256, 145, -802, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, -1023, 44, -4870, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, -459, 145, -1020, 140, 150, 140, 0x6000 }, + { 1, cam_castle_enter_lobby, -85, 145, -627, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, -1589, 145, -1020, 140, 150, 140, -0x6000 }, + { 1, cam_castle_enter_lobby, -1963, 145, -627, 140, 150, 140, 0 }, + { 1, cam_castle_leave_lobby_sliding_door, -2838, 657, -1659, 200, 150, 150, 0x2000 }, + { 1, cam_castle_enter_lobby_sliding_door, -2319, 512, -1266, 300, 150, 300, 0x2000 }, + { 1, cam_castle_close_mode, 844, 759, -1657, 40, 150, 40, -0x2000 }, + { 1, cam_castle_enter_lobby, 442, 759, -1292, 140, 150, 140, -0x2000 }, + { 2, cam_castle_enter_spiral_stairs, -1000, 657, 1740, 200, 300, 200, 0 }, + { 2, cam_castle_enter_spiral_stairs, -996, 1348, 1814, 200, 300, 200, 0 }, + { 2, cam_castle_close_mode, -946, 657, 2721, 50, 150, 50, 0 }, + { 2, cam_castle_close_mode, -996, 1348, 907, 50, 150, 50, 0 }, + { 2, cam_castle_close_mode, -997, 1348, 1450, 140, 150, 140, 0 }, + { 1, cam_castle_close_mode, -4942, 452, -461, 140, 150, 140, 0x4000 }, + { 1, cam_castle_close_mode, -3393, 350, -793, 140, 150, 140, 0x4000 }, + { 1, cam_castle_enter_lobby, -2851, 350, -792, 140, 150, 140, 0x4000 }, + { 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 }, + //! Duplicate camera trigger outside JRB door + { 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 }, + { 1, cam_castle_close_mode, 1345, 350, -229, 140, 150, 140, 0x4000 }, + { 1, cam_castle_close_mode, -946, -929, 622, 300, 150, 300, 0 }, + { 2, cam_castle_look_upstairs, -205, 1456, 2508, 210, 928, 718, 0 }, + { 1, cam_castle_basement_look_downstairs, -1027, -587, -718, 318, 486, 577, 0 }, + { 1, cam_castle_lobby_entrance, -1023, 376, 1830, 300, 400, 300, 0 }, + { 3, cam_castle_hmc_start_pool_cutscene, 2485, -1689, -2659, 600, 50, 600, 0 }, + NULL_TRIGGER +}; + +/** + * The BBH triggers are the most complex, they cause the camera to enter fixed mode for each room, + * transition between rooms, and enter free roam when outside. + * + * The triggers are also responsible for warping the camera below platforms. + */ +struct CameraTrigger sCamBBH[] = { + { 1, cam_bbh_enter_front_door, 742, 0, 2369, 200, 200, 200, 0 }, + { 1, cam_bbh_leave_front_door, 741, 0, 1827, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 222, 0, 1458, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 222, 0, 639, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 435, 0, 222, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1613, 0, 222, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1827, 0, 1459, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, -495, 819, 1407, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, -495, 819, 640, 250, 200, 200, 0 }, + { 1, cam_bbh_room_1, 179, 819, 222, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1613, 819, 222, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1827, 819, 486, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1827, 819, 1818, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_lower, 2369, 0, 1459, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_lower, 3354, 0, 1347, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_lower, 2867, 514, 1843, 512, 102, 409, 0 }, + { 1, cam_bbh_room_4, 3354, 0, 804, 200, 200, 200, 0 }, + { 1, cam_bbh_room_4, 1613, 0, -320, 200, 200, 200, 0 }, + { 1, cam_bbh_room_8, 435, 0, -320, 200, 200, 200, 0 }, + { 1, cam_bbh_room_5_library, -2021, 0, 803, 200, 200, 200, 0 }, + { 1, cam_bbh_room_5_library, -320, 0, 640, 200, 200, 200, 0 }, + { 1, cam_bbh_room_5_library_to_hidden_transition, -1536, 358, -254, 716, 363, 102, 0 }, + { 1, cam_bbh_room_5_hidden_to_library_transition, -1536, 358, -459, 716, 363, 102, 0 }, + { 1, cam_bbh_room_5_hidden, -1560, 0, -1314, 200, 200, 200, 0 }, + { 1, cam_bbh_room_3, -320, 0, 1459, 200, 200, 200, 0 }, + { 1, cam_bbh_room_3, -2021, 0, 1345, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_library, 2369, 819, 486, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_library, 2369, 1741, 486, 200, 200, 200, 0 }, + { 1, cam_bbh_room_2_library_to_trapdoor_transition, 2867, 1228, 1174, 716, 414, 102, 0 }, + { 1, cam_bbh_room_2_trapdoor_transition, 2867, 1228, 1378, 716, 414, 102, 0 }, + { 1, cam_bbh_room_2_trapdoor, 2369, 819, 1818, 200, 200, 200, 0 }, + { 1, cam_bbh_room_9_attic, 1829, 1741, 486, 200, 200, 200, 0 }, + { 1, cam_bbh_room_9_attic, 741, 1741, 1587, 200, 200, 200, 0 }, + { 1, cam_bbh_room_9_attic_transition, 102, 2048, -191, 100, 310, 307, 0 }, + { 1, cam_bbh_room_9_mr_i_transition, 409, 2048, -191, 100, 310, 307, 0 }, + { 1, cam_bbh_room_13_balcony, 742, 1922, 2164, 200, 200, 200, 0 }, + { 1, cam_bbh_fall_off_roof, 587, 1322, 2677, 1000, 400, 600, 0 }, + { 1, cam_bbh_room_3, -1037, 819, 1408, 200, 200, 200, 0 }, + { 1, cam_bbh_room_3, -1970, 1024, 1345, 200, 200, 200, 0 }, + { 1, cam_bbh_room_8, 179, 819, -320, 200, 200, 200, 0 }, + { 1, cam_bbh_room_7_mr_i, 1613, 819, -320, 200, 200, 200, 0 }, + { 1, cam_bbh_room_7_mr_i_to_coffins_transition, 2099, 1228, -819, 102, 414, 716, 0 }, + { 1, cam_bbh_room_7_coffins_to_mr_i_transition, 2304, 1228, -819, 102, 414, 716, 0 }, + { 1, cam_bbh_room_6, -1037, 819, 640, 200, 200, 200, 0 }, + { 1, cam_bbh_room_6, -1970, 1024, 803, 200, 200, 200, 0 }, + { 1, cam_bbh_room_1, 1827, 819, 1818, 200, 200, 200, 0 }, + { 1, cam_bbh_fall_into_pool, 2355, -1112, -193, 1228, 500, 1343, 0 }, + { 1, cam_bbh_fall_into_pool, 2355, -1727, 1410, 1228, 500, 705, 0 }, + { 1, cam_bbh_elevator_room_lower, 0, -2457, 1827, 250, 200, 250, 0 }, + { 1, cam_bbh_elevator_room_lower, 0, -2457, 2369, 250, 200, 250, 0 }, + { 1, cam_bbh_elevator_room_lower, 0, -2457, 4929, 250, 200, 250, 0 }, + { 1, cam_bbh_elevator_room_lower, 0, -2457, 4387, 250, 200, 250, 0 }, + { 1, cam_bbh_room_0_back_entrance, 1887, -2457, 204, 250, 200, 250, 0 }, + { 1, cam_bbh_room_0, 1272, -2457, 204, 250, 200, 250, 0 }, + { 1, cam_bbh_room_0, -1681, -2457, 204, 250, 200, 250, 0 }, + { 1, cam_bbh_room_0_back_entrance, -2296, -2457, 204, 250, 200, 250, 0 }, + { 1, cam_bbh_elevator, -2939, -605, 5367, 800, 100, 800, 0 }, + { 1, cam_bbh_room_12_upper, -2939, -205, 5367, 300, 100, 300, 0 }, + { 1, cam_bbh_room_12_upper, -2332, -204, 4714, 250, 200, 250, 0x6000 }, + { 1, cam_bbh_room_0_back_entrance, -1939, -204, 4340, 250, 200, 250, 0x6000 }, + NULL_TRIGGER }; #define _ NULL - #define STUB_LEVEL(_0, _1, _2, _3, _4, _5, _6, _7, cameratable) cameratable, #define DEFINE_LEVEL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, cameratable) cameratable, /* * This table has an extra 2 levels after the last unknown_38 stub level. What I think - * the programmer was thinking was that the table is null terminated and so used the - * level count as a coorespondance to the ID of the final level, but the enum represents - * an ID *after* the last stub lebel, not before or during it. + * the programmer was thinking was that the table is null terminated and so used the + * level count as a correspondence to the ID of the final level, but the enum represents + * an ID *after* the last stub level, not before or during it. + * + * Each table is terminated with NULL_TRIGGER */ -struct TableCamera *TableLevelCinematicCamera[LEVEL_COUNT + 1] = { +struct CameraTrigger *sCameraTriggers[LEVEL_COUNT + 1] = { NULL, #include "levels/level_defines.h" }; @@ -5146,7 +6311,7 @@ struct TableCamera *TableLevelCinematicCamera[LEVEL_COUNT + 1] = { #undef STUB_LEVEL #undef DEFINE_LEVEL -struct CutsceneSplinePoint sIntroStartToPipePosition[23] = { +struct CutsceneSplinePoint sIntroStartToPipePosition[] = { { 0, 0, { 2122, 8762, 9114 } }, { 0, 0, { 2122, 8762, 9114 } }, { 1, 0, { 2122, 7916, 9114 } }, { 1, 0, { 2122, 7916, 9114 } }, { 2, 0, { 957, 5166, 8613 } }, { 3, 0, { 589, 4338, 7727 } }, { 4, 0, { 690, 3366, 6267 } }, { 5, 0, { -1600, 2151, 4955 } }, { 6, 0, { -1557, 232, 1283 } }, @@ -5157,7 +6322,7 @@ struct CutsceneSplinePoint sIntroStartToPipePosition[23] = { { 0, 0, { 448, 136, 564 } }, { -1, 0, { 448, 136, 564 } } }; -struct CutsceneSplinePoint sIntroStartToPipeFocus[23] = { +struct CutsceneSplinePoint sIntroStartToPipeFocus[] = { { 0, 50, { 1753, 29800, 8999 } }, { 0, 50, { 1753, 29800, 8999 } }, { 1, 50, { 1753, 8580, 8999 } }, { 1, 100, { 1753, 8580, 8999 } }, { 2, 50, { 520, 5400, 8674 } }, { 3, 50, { 122, 4437, 7875 } }, @@ -5177,7 +6342,7 @@ struct CutsceneSplinePoint sIntroStartToPipeFocus[23] = { * mario jumps out of the pipe when the first dialog opens. This table specifically updates the * camera's position. */ -struct CutsceneSplinePoint sIntroPipeToDialogPosition[14] = { +struct CutsceneSplinePoint sIntroPipeToDialogPosition[] = { { 0, 0, { -785, 625, 4527 } }, { 1, 0, { -785, 625, 4527 } }, { 2, 0, { -1286, 644, 4376 } }, { 3, 0, { -1286, 623, 4387 } }, { 4, 0, { -1286, 388, 3963 } }, { 5, 0, { -1286, 358, 4093 } }, { 6, 0, { -1386, 354, 4159 } }, { 7, 0, { -1477, 306, 4223 } }, { 8, 0, { -1540, 299, 4378 } }, @@ -5188,7 +6353,7 @@ struct CutsceneSplinePoint sIntroPipeToDialogPosition[14] = { /** * Describes the spline that the camera's focus follows, during the same part of the intro as the above. */ -struct CutsceneSplinePoint sIntroPipeToDialogFocus[14] = { +struct CutsceneSplinePoint sIntroPipeToDialogFocus[] = { { 0, 20, { -1248, 450, 4596 } }, { 1, 59, { -1258, 485, 4606 } }, { 2, 59, { -1379, 344, 4769 } }, { 3, 20, { -1335, 366, 4815 } }, { 4, 23, { -1315, 370, 4450 } }, { 5, 40, { -1322, 333, 4591 } }, { 6, 25, { -1185, 329, 4616 } }, { 7, 21, { -1059, 380, 4487 } }, { 8, 14, { -1086, 421, 4206 } }, @@ -5196,21 +6361,21 @@ struct CutsceneSplinePoint sIntroPipeToDialogFocus[14] = { { 0, 0, { -1328, 385, 4354 } }, { -1, 0, { -1328, 385, 4354 } } }; -struct CutsceneSplinePoint D_8032E040[10] = { +struct CutsceneSplinePoint sEndingFlyToWindowPos[] = { { 0, 0, { -86, 876, 640 } }, { 1, 0, { -86, 876, 610 } }, { 2, 0, { -66, 945, 393 } }, { 3, 0, { -80, 976, 272 } }, { 4, 0, { -66, 1306, -36 } }, { 5, 0, { -70, 1869, -149 } }, { 6, 0, { -10, 2093, -146 } }, { 7, 0, { -10, 2530, -248 } }, { 8, 0, { -10, 2530, -263 } }, { 9, 0, { -10, 2530, -273 } } }; -struct CutsceneSplinePoint D_8032E090[11] = { +struct CutsceneSplinePoint sEndingFlyToWindowFocus[] = { { 0, 50, { -33, 889, -7 } }, { 1, 35, { -33, 889, -7 } }, { 2, 31, { -17, 1070, -193 } }, { 3, 25, { -65, 1182, -272 } }, { 4, 20, { -64, 1559, -542 } }, { 5, 25, { -68, 2029, -677 } }, { 6, 25, { -9, 2204, -673 } }, { 7, 25, { -8, 2529, -772 } }, { 8, 0, { -8, 2529, -772 } }, { 9, 0, { -8, 2529, -772 } }, { -1, 0, { -8, 2529, -772 } } }; -struct CutsceneSplinePoint D_8032E0E8[20] = { +struct CutsceneSplinePoint sEndingPeachDescentCamPos[] = { { 0, 50, { 1, 120, -1150 } }, { 1, 50, { 1, 120, -1150 } }, { 2, 40, { 118, 121, -1199 } }, { 3, 40, { 147, 74, -1306 } }, { 4, 40, { 162, 95, -1416 } }, { 5, 40, { 25, 111, -1555 } }, { 6, 40, { -188, 154, -1439 } }, { 7, 40, { -203, 181, -1242 } }, { 8, 40, { 7, 191, -1057 } }, @@ -5220,203 +6385,226 @@ struct CutsceneSplinePoint D_8032E0E8[20] = { { 8, 0, { -6, 72, 574 } }, { -1, 0, { -6, 72, 574 } } }; -struct CutsceneSplinePoint D_8032E188[9] = { +struct CutsceneSplinePoint sEndingMarioToPeachPos[] = { { 0, 0, { -130, 1111, -1815 } }, { 1, 0, { -131, 1052, -1820 } }, { 2, 0, { -271, 1008, -1651 } }, { 3, 0, { -439, 1043, -1398 } }, { 4, 0, { -433, 1040, -1120 } }, { 5, 0, { -417, 1040, -1076 } }, { 6, 0, { -417, 1040, -1076 } }, { 7, 0, { -417, 1040, -1076 } }, { -1, 0, { -417, 1040, -1076 } } }; -struct CutsceneSplinePoint D_8032E1D0[9] = { +struct CutsceneSplinePoint sEndingMarioToPeachFocus[] = { { 0, 50, { -37, 1020, -1332 } }, { 1, 20, { -36, 1012, -1330 } }, { 2, 20, { -24, 1006, -1215 } }, { 3, 20, { 28, 1002, -1224 } }, { 4, 24, { 45, 1013, -1262 } }, { 5, 35, { 34, 1000, -1287 } }, { 6, 0, { 34, 1000, -1287 } }, { 7, 0, { 34, 1000, -1287 } }, { -1, 0, { 34, 1000, -1287 } } }; -struct CutsceneSplinePoint D_8032E218[8] = { +struct CutsceneSplinePoint sEndingLookUpAtCastle[] = { { 0, 50, { 200, 1066, -1414 } }, { 0, 50, { 200, 1066, -1414 } }, { 0, 30, { 198, 1078, -1412 } }, { 0, 33, { 15, 1231, -1474 } }, { 0, 39, { -94, 1381, -1368 } }, { 0, 0, { -92, 1374, -1379 } }, { 0, 0, { -92, 1374, -1379 } }, { -1, 0, { -92, 1374, -1379 } } }; -struct CutsceneSplinePoint D_8032E258[7] = { +struct CutsceneSplinePoint sEndingLookAtSkyFocus[] = { { 0, 50, { 484, 1368, -888 } }, { 0, 72, { 479, 1372, -892 } }, { 0, 50, { 351, 1817, -918 } }, { 0, 50, { 351, 1922, -598 } }, { 0, 0, { 636, 2027, -415 } }, { 0, 0, { 636, 2027, -415 } }, { -1, 0, { 636, 2027, -415 } } }; -s16 level_specific_camera_update(struct LevelCamera *c) { - s16 currLevelNum = gCurrLevelNum; - s16 currPreset; +/** + * Activates any CameraTriggers that mario is inside. + * Then, applies area-specific processing to the camera, such as setting the default mode, or changing + * the mode based on the terrain type mario is standing on. + * + * @return the camera's mode after processing, although this is unused in the code + */ +s16 camera_course_processing(struct Camera *c) { + s16 level = gCurrLevelNum; + s16 mode; s8 area = gCurrentArea->index; - u32 i; - Vec3f sp50, sp44; - u32 sp40 = 0; - UNUSED struct TableCamera sp28; - u8 preset = c->currPreset; + // Bounds iterator + u32 b; + // Camera trigger's bounding box + Vec3f center, bounds; + u32 insideBounds = FALSE; + UNUSED struct CameraTrigger unused; + u8 oldMode = c->mode; - if (c->currPreset == CAMERA_PRESET_C_UP_LOOK) { - c->currPreset = (u8) D_8033B418.unk2; + if (c->mode == CAMERA_MODE_C_UP) { + c->mode = sModeInfo.lastMode; } - func_8028D32C(&c->currPreset); - if (currLevelNum > 40) { - currLevelNum = 40; + check_blocking_area_processing(&c->mode); + if (level > LEVEL_COUNT + 1) { + level = LEVEL_COUNT + 1; } - if (TableLevelCinematicCamera[currLevelNum] != 0) { - i = 0; + if (sCameraTriggers[level] != NULL) { + b = 0; - while ((TableLevelCinematicCamera[currLevelNum])[i].unk4 != 0) { - if ((TableLevelCinematicCamera[currLevelNum])[i].area == area) { - vec3f_set(sp50, (TableLevelCinematicCamera[currLevelNum])[i].unk8, - (TableLevelCinematicCamera[currLevelNum])[i].unkA, - (TableLevelCinematicCamera[currLevelNum])[i].unkC); - vec3f_set(sp44, (TableLevelCinematicCamera[currLevelNum])[i].unkE, - (TableLevelCinematicCamera[currLevelNum])[i].unk10, - (TableLevelCinematicCamera[currLevelNum])[i].unk12); + // Process positional triggers. + // All triggered events are called, not just the first one. + while (sCameraTriggers[level][b].event != NULL) { - if (check_if_vector_fits_in_bounds(sMarioStatusForCamera->pos, sp50, sp44, - (TableLevelCinematicCamera[currLevelNum])[i].unk14) - == 1) { - if ((gCameraFlags2 & CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES) == 0) { - ((TableLevelCinematicCamera[currLevelNum])[i].unk4)(c); - sp40 = 1; + // Check only the current area's triggers + if (sCameraTriggers[level][b].area == area) { + // Copy the bounding box into center and bounds + vec3f_set(center, sCameraTriggers[level][b].centerX, + sCameraTriggers[level][b].centerY, + sCameraTriggers[level][b].centerZ); + vec3f_set(bounds, sCameraTriggers[level][b].boundsX, + sCameraTriggers[level][b].boundsY, + sCameraTriggers[level][b].boundsZ); + + // Check if mario is inside the bounds + if (is_pos_in_bounds(sMarioCamState->pos, center, bounds, + sCameraTriggers[level][b].boundsYaw) == TRUE) { + //! This should be checked before calling is_pos_in_bounds. (It doesn't belong + //! outside the while loop because some events disable area processing) + if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) { + sCameraTriggers[level][b].event(c); + insideBounds = TRUE; } } } - if ((TableLevelCinematicCamera[currLevelNum])[i].area == -1) { - if (sp40 == 0) { - if ((gCameraFlags2 & CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES) == 0) { - ((TableLevelCinematicCamera[currLevelNum])[i].unk4)(c); + if ((sCameraTriggers[level])[b].area == -1) { + // Default triggers are only active if mario is not already inside another trigger + if (!insideBounds) { + if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) { + sCameraTriggers[level][b].event(c); } } } - i += 1; + b += 1; } } - if ((gCameraFlags2 & CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES) == 0) { + // Area-specific camera processing + if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) { switch (gCurrLevelArea) { case AREA_WF: - if (sMarioStatusForCamera->action == ACT_RIDING_HOOT) { - set_camera_preset(c, CAMERA_PRESET_SLIDE_HOOT, 60); - + if (sMarioCamState->action == ACT_RIDING_HOOT) { + transition_to_camera_mode(c, CAMERA_MODE_SLIDE_HOOT, 60); } else { - switch (sGeometryForMario.currFloorType) { - case SURFACE_CAMERA_PLATFORM: - set_camera_preset(c, CAMERA_PRESET_PLATFORM_LEVEL, 90); - sPlatformLevelPresetBaseYaw = 0x4000; + switch (sMarioGeometry.currFloorType) { + case SURFACE_CAMERA_8_DIR: + transition_to_camera_mode(c, CAMERA_MODE_8_DIRECTIONS, 90); + s8DirModeBaseYaw = DEGREES(90); break; case SURFACE_BOSS_FIGHT_CAMERA: if (gCurrActNum == 1) { - set_camera_preset_boss_fight(c); + set_camera_mode_boss_fight(c); } else { - set_camera_preset_open_camera(c, 60); + set_camera_mode_radial(c, 60); } break; default: - set_camera_preset_open_camera(c, 60); + set_camera_mode_radial(c, 60); } } break; case AREA_BBH: - if (vec3f_compare(sFixedPresetBasePosition, 210.f, 420.f, 3109.f) - == 1) // if camera is fixed at bbh_room_13_balcony_camera (but as floats) + // if camera is fixed at bbh_room_13_balcony_camera (but as floats) + if (vec3f_compare(sFixedModeBasePosition, 210.f, 420.f, 3109.f) == 1) { - if (sMarioStatusForCamera->pos[1] < 1800.f) { - set_camera_preset(c, CAMERA_PRESET_CLOSE, 30); + if (sMarioCamState->pos[1] < 1800.f) { + transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 30); } } break; case AREA_SSL_PYRAMID: - set_preset_via_surface_or_input(c, 2); + set_mode_if_not_set_by_surface(c, CAMERA_MODE_OUTWARD_RADIAL); break; case AREA_SSL_OUTSIDE: - set_preset_via_surface_or_input(c, 1); + set_mode_if_not_set_by_surface(c, CAMERA_MODE_RADIAL); break; case AREA_THI_HUGE: break; case AREA_THI_TINY: - surface_type_presets_thi(c); + surface_type_modes_thi(c); break; case AREA_TTC: - set_preset_via_surface_or_input(c, 2); + set_mode_if_not_set_by_surface(c, CAMERA_MODE_OUTWARD_RADIAL); break; case AREA_BOB: - if (set_preset_via_surface_or_input(c, 0) == 0) { - if (sGeometryForMario.currFloorType == SURFACE_BOSS_FIGHT_CAMERA) { - set_camera_preset_boss_fight(c); + if (set_mode_if_not_set_by_surface(c, CAMERA_MODE_NONE) == 0) { + if (sMarioGeometry.currFloorType == SURFACE_BOSS_FIGHT_CAMERA) { + set_camera_mode_boss_fight(c); } else { - if (c->currPreset == CAMERA_PRESET_CLOSE) { - set_camera_preset(c, CAMERA_PRESET_OPEN_CAMERA, 60); + if (c->mode == CAMERA_MODE_CLOSE) { + transition_to_camera_mode(c, CAMERA_MODE_RADIAL, 60); } else { - set_camera_preset_open_camera(c, 60); + set_camera_mode_radial(c, 60); } } } break; case AREA_WDW_MAIN: - if (sGeometryForMario.currFloorType == SURFACE_INSTANT_WARP_1B) { + if (sMarioGeometry.currFloorType == SURFACE_INSTANT_WARP_1B) { if (0) { } - c->defPreset = CAMERA_PRESET_OPEN_CAMERA; + c->defMode = CAMERA_MODE_RADIAL; if (0) { } } break; case AREA_WDW_TOWN: - if (sGeometryForMario.currFloorType == SURFACE_INSTANT_WARP_1C) { + if (sMarioGeometry.currFloorType == SURFACE_INSTANT_WARP_1C) { if (0) { } - c->defPreset = CAMERA_PRESET_CLOSE; + c->defMode = CAMERA_MODE_CLOSE; if (0) { } } break; case AREA_DDD_WHIRLPOOL: - gCameraStatus.modeDefault = CAMERA_PRESET_REVERSE_TOWER; + //! @bug this does nothing + gLakituState.defMode = CAMERA_MODE_OUTWARD_RADIAL; break; case AREA_DDD_SUB: - if ((c->currPreset != CAMERA_PRESET_BEHIND_MARIO) - && (c->currPreset != CAMERA_PRESET_WATER_SURFACE)) { - if (((sMarioStatusForCamera->action & ACT_FLAG_ON_POLE) != 0) - || (sGeometryForMario.currFloorHeight > 800.f)) { - set_camera_preset(c, CAMERA_PRESET_PLATFORM_LEVEL, 60); + if ((c->mode != CAMERA_MODE_BEHIND_MARIO) + && (c->mode != CAMERA_MODE_WATER_SURFACE)) { + if (((sMarioCamState->action & ACT_FLAG_ON_POLE) != 0) + || (sMarioGeometry.currFloorHeight > 800.f)) { + transition_to_camera_mode(c, CAMERA_MODE_8_DIRECTIONS, 60); } else { - if (sMarioStatusForCamera->pos[1] < 800.f) { - set_camera_preset(c, CAMERA_PRESET_FREE_ROAM, 60); + if (sMarioCamState->pos[1] < 800.f) { + transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 60); } } } - gCameraStatus.modeDefault = CAMERA_PRESET_FREE_ROAM; + //! @bug this does nothing + gLakituState.defMode = CAMERA_MODE_FREE_ROAM; break; } } - gCameraFlags2 &= ~CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES; - if (preset == CAMERA_PRESET_C_UP_LOOK) { - D_8033B418.unk2 = c->currPreset; - c->currPreset = preset; + sStatusFlags &= ~CAM_FLAG_BLOCK_AREA_PROCESSING; + if (oldMode == CAMERA_MODE_C_UP) { + sModeInfo.lastMode = c->mode; + c->mode = oldMode; } - currPreset = c->currPreset; - return currPreset; + mode = c->mode; + return mode; } -void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f b) { +/** + * Move `pos` between the nearest floor and ceiling + * @param lastGood unused, passed as the last position the camera was in + */ +void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f lastGood) { f32 ceilY, floorY; struct Surface *surf; @@ -5452,271 +6640,349 @@ void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f b) { } } -s32 func_8028F2F0(struct LevelCamera *a, Vec3f pos, s16 *c, s16 d) { - UNUSED f32 sp84; - struct WallCollisionData wallData; +/** + * Checks for any walls obstructing mario from view, and calculates a new yaw that the camera should + * rotate towards. + * + * @param[out] avoidYaw the angle (from mario) that the camera should rotate towards to avoid the wall. + * The camera then approaches avoidYaw until mario is no longer obstructed. + * avoidYaw is always parallel to the wall. + * @param yawRange how wide of an arc to check for walls obscuring mario. + * + * @return 3 if a wall is covering mario, 1 if a wall is only near the camera. + */ +s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16 yawRange) { + UNUSED f32 unused1; + struct WallCollisionData colData; struct Surface *wall; - UNUSED Vec3f sp4C; - f32 distToMario, sp44; - UNUSED f32 sp40; - f32 wallThickness, sp38; - s16 sp36, horWallNorm; - UNUSED s16 sp32; - s16 pitchToMario, yawToMario; - UNUSED s16 sp2C; - s32 sp28 = 0; - s32 i = 0; - UNUSED s32 sp20; + UNUSED Vec3f unused2; + f32 dummyDist, checkDist; + UNUSED f32 unused3; + f32 coarseRadius; + f32 fineRadius; + s16 wallYaw, horWallNorm; + UNUSED s16 unused4; + s16 dummyPitch; + // The yaw of the vector from mario to the camera. + s16 yawFromMario; + UNUSED s16 unused5; + s32 status = 0; + /// The current iteration. The algorithm takes 8 equal steps from mario back to the camera. + s32 step = 0; + UNUSED s32 unused6; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, pos, &distToMario, &pitchToMario, &yawToMario); - gCameraFlags2 &= ~CAM_FLAG_2_COLLIDING_WITH_WALL; - wallData.offsetY = 100.0f; - sp44 = 0.0f; - wallThickness = 150.0f; - sp38 = 100.0f; + vec3f_get_dist_and_angle(sMarioCamState->pos, cPos, &dummyDist, &dummyPitch, &yawFromMario); + sStatusFlags &= ~CAM_FLAG_CAM_NEAR_WALL; + colData.offsetY = 100.0f; + // The distance from mario to lakitu + checkDist = 0.0f; + /// The radius used to find potential walls to avoid. + /// @bug Increases to 250.f, but the max collision radius is 200.f + coarseRadius = 150.0f; + /// This only increases when there is a wall collision found in the coarse pass + fineRadius = 100.0f; - for (i = 0; i < 8; i++) { - wallData.x = sMarioStatusForCamera->pos[0] + ((pos[0] - sMarioStatusForCamera->pos[0]) * sp44); - wallData.y = sMarioStatusForCamera->pos[1] + ((pos[1] - sMarioStatusForCamera->pos[1]) * sp44); - wallData.z = sMarioStatusForCamera->pos[2] + ((pos[2] - sMarioStatusForCamera->pos[2]) * sp44); - wallData.radius = wallThickness; - camera_approach_f32_symmetric_bool(&wallThickness, 250.f, 30.f); + for (step = 0; step < 8; step++) { + // Start at mario, move backwards to lakitu's position + colData.x = sMarioCamState->pos[0] + ((cPos[0] - sMarioCamState->pos[0]) * checkDist); + colData.y = sMarioCamState->pos[1] + ((cPos[1] - sMarioCamState->pos[1]) * checkDist); + colData.z = sMarioCamState->pos[2] + ((cPos[2] - sMarioCamState->pos[2]) * checkDist); + colData.radius = coarseRadius; + // Increase the coarse check radius + camera_approach_f32_symmetric_bool(&coarseRadius, 250.f, 30.f); - if (find_wall_collisions(&wallData) != 0) { - wall = wallData.walls[wallData.numWalls - 1]; - if (i >= 5) { - gCameraFlags2 |= CAM_FLAG_2_COLLIDING_WITH_WALL; - if (sp28 <= 0) { - sp28 = 1; - wall = wallData.walls[wallData.numWalls - 1]; - sp36 = atan2s(wall->normal.z, wall->normal.x) + 0x4000; - *c = func_80289A98(yawToMario, sp36) + 0x8000; + if (find_wall_collisions(&colData) != 0) { + wall = colData.walls[colData.numWalls - 1]; + + // If we're over halfway from mario to lakitu, then there's a wall near the camera, but + // not necessarily obstructing mario + if (step >= 5) { + sStatusFlags |= CAM_FLAG_CAM_NEAR_WALL; + if (status <= 0) { + status = 1; + wall = colData.walls[colData.numWalls - 1]; + // wallYaw is parallel to the wall, not perpendicular + wallYaw = atan2s(wall->normal.z, wall->normal.x) + DEGREES(90); + // Calculate the avoid direction. The function returns the opposite direction so add 180 + // degrees. + *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw) + DEGREES(180); } } - wallData.x = - sMarioStatusForCamera->pos[0] + ((pos[0] - sMarioStatusForCamera->pos[0]) * sp44); - wallData.y = - sMarioStatusForCamera->pos[1] + ((pos[1] - sMarioStatusForCamera->pos[1]) * sp44); - wallData.z = - sMarioStatusForCamera->pos[2] + ((pos[2] - sMarioStatusForCamera->pos[2]) * sp44); - wallData.radius = sp38; - camera_approach_f32_symmetric_bool(&sp38, 200.f, 20.f); + colData.x = sMarioCamState->pos[0] + ((cPos[0] - sMarioCamState->pos[0]) * checkDist); + colData.y = sMarioCamState->pos[1] + ((cPos[1] - sMarioCamState->pos[1]) * checkDist); + colData.z = sMarioCamState->pos[2] + ((cPos[2] - sMarioCamState->pos[2]) * checkDist); + colData.radius = fineRadius; + // Increase the fine check radius + camera_approach_f32_symmetric_bool(&fineRadius, 200.f, 20.f); - if (find_wall_collisions(&wallData) != 0) { - wall = wallData.walls[wallData.numWalls - 1]; + if (find_wall_collisions(&colData) != 0) { + wall = colData.walls[colData.numWalls - 1]; horWallNorm = atan2s(wall->normal.z, wall->normal.x); - sp36 = horWallNorm + 0x4000; - if ((func_8028A0D4(sMarioStatusForCamera->pos, pos, wall, d, SURFACE_WALL_MISC) == 0) - && (is_mario_behind_surface(a, wall) == 1) - && (is_pos_less_than_bounds(wall, -1.f, 150.f, -1.f) == 0)) { - *c = func_80289A98(yawToMario, sp36) + 0x8000; - camera_approach_s16_symmetric_bool(c, horWallNorm, d); - sp28 = 3; - i = 8; + wallYaw = horWallNorm + DEGREES(90); + // If mario would be blocked by the surface, then avoid it + if ((is_range_behind_surface(sMarioCamState->pos, cPos, wall, yawRange, SURFACE_WALL_MISC) == 0) + && (is_mario_behind_surface(c, wall) == TRUE) + // Also check if the wall is tall enough to cover mario + && (is_surf_within_bounding_box(wall, -1.f, 150.f, -1.f) == FALSE)) { + // Calculate the avoid direction. The function returns the opposite direction so add 180 + // degrees. + *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw) + DEGREES(180); + camera_approach_s16_symmetric_bool(avoidYaw, horWallNorm, yawRange); + status = 3; + step = 8; } } } - sp44 += 0.125f; + checkDist += 0.125f; } - return sp28; + + return status; } -void find_mario_relative_geometry(struct PlayerGeometry *a) { +/** + * Stores type and height of the nearest floor and ceiling to mario in `pg` + * + * Note: Also finds the water level, but waterHeight is unused + */ +void find_mario_floor_and_ceil(struct PlayerGeometry *pg) { struct Surface *surf; s16 tempCheckingSurfaceCollisionsForCamera = gCheckingSurfaceCollisionsForCamera; - gCheckingSurfaceCollisionsForCamera = 1; + gCheckingSurfaceCollisionsForCamera = TRUE; - if (find_floor(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 10.f, - sMarioStatusForCamera->pos[2], &surf) - != -11000.f) { - a->currFloorType = surf->type; + if (find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 10.f, + sMarioCamState->pos[2], &surf) != -11000.f) { + pg->currFloorType = surf->type; } else { - a->currFloorType = 0; + pg->currFloorType = 0; } - if (find_ceil(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] - 10.f, - sMarioStatusForCamera->pos[2], &surf) - != 20000.f) { - a->currCeilType = surf->type; + if (find_ceil(sMarioCamState->pos[0], sMarioCamState->pos[1] - 10.f, + sMarioCamState->pos[2], &surf) != 20000.f) { + pg->currCeilType = surf->type; } else { - a->currCeilType = 0; + pg->currCeilType = 0; } - gCheckingSurfaceCollisionsForCamera = 0; - a->currFloorHeight = find_floor(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 10.f, - sMarioStatusForCamera->pos[2], &a->currFloor); - a->currCeilHeight = find_ceil(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] - 10.f, - sMarioStatusForCamera->pos[2], &a->currCeil); - a->waterHeight = find_water_level(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[2]); + gCheckingSurfaceCollisionsForCamera = FALSE; + pg->currFloorHeight = find_floor(sMarioCamState->pos[0], + sMarioCamState->pos[1] + 10.f, + sMarioCamState->pos[2], &pg->currFloor); + pg->currCeilHeight = find_ceil(sMarioCamState->pos[0], + sMarioCamState->pos[1] - 10.f, + sMarioCamState->pos[2], &pg->currCeil); + pg->waterHeight = find_water_level(sMarioCamState->pos[0], sMarioCamState->pos[2]); gCheckingSurfaceCollisionsForCamera = tempCheckingSurfaceCollisionsForCamera; } -void func_8028F800(u8 cutsceneTable, struct Object *o) { - sTempCutsceneNumber = cutsceneTable; - gCutsceneNumber = 0; +/** + * Start a cutscene focusing on an object + * This will play if nothing else happened in the same frame, like exiting or warping. + */ +void start_object_cutscene(u8 cutscene, struct Object *o) { + sObjectCutscene = cutscene; + gRecentCutscene = 0; gCutsceneFocus = o; - gCutsceneActive = FALSE; + gObjCutsceneDone = FALSE; } -u8 func_8028F834(u8 a) { - sTempCutsceneNumber = a; - D_8032CFFC = 0; +/** + * Start a low-priority cutscene without focusing on an object + * This will play if nothing else happened in the same frame, like exiting or warping. + */ +u8 start_object_cutscene_without_focus(u8 cutscene) { + sObjectCutscene = cutscene; + sCutsceneDialogResponse = 0; return 0; } -s32 unused_8028F860(u8 a) { - if ((gCurrLevelCamera->cutscene == 0) && (sTempCutsceneNumber == 0)) { - sTempCutsceneNumber = a; +s32 unused_dialog_cutscene_response(u8 cutscene) { + // if not in a cutscene, start this one + if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { + sObjectCutscene = cutscene; } - if ((gCurrLevelCamera->cutscene == a) && (D_8032CFFC != 0)) { - return (s16) D_8032CFFC; + // if playing this cutscene and mario responded, return the response + if ((gCamera->cutscene == cutscene) && (sCutsceneDialogResponse != 0)) { + return (s16) sCutsceneDialogResponse; } else { return 0; } } -s16 cutscene_object_with_dialog(u8 cutsceneTable, struct Object *o, s16 dialogID) { - s16 sp1E = 0; +s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID) { + s16 response = 0; - if ((gCurrLevelCamera->cutscene == 0) && (sTempCutsceneNumber == 0)) { - if (gCutsceneNumber != cutsceneTable) { - func_8028F800(cutsceneTable, o); + if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { + if (gRecentCutscene != cutscene) { + start_object_cutscene(cutscene, o); if (dialogID != -1) { - D_8033B320 = dialogID; + sCutsceneDialogID = dialogID; } else { - D_8033B320 = DIALOG_001; + sCutsceneDialogID = DIALOG_001; } } else { - sp1E = D_8032CFFC; + response = sCutsceneDialogResponse; } - gCutsceneNumber = 0; + gRecentCutscene = 0; } - return sp1E; + return response; } -s16 cutscene_object_without_dialog(u8 cutsceneTable, struct Object *o) { - s16 sp1E = cutscene_object_with_dialog(cutsceneTable, o, -1); - return sp1E; +s16 cutscene_object_without_dialog(u8 cutscene, struct Object *o) { + s16 response = cutscene_object_with_dialog(cutscene, o, -1); + return response; } -s16 cutscene_object(u8 cutsceneTable, struct Object *o) { - s16 sp1E = 0; +/** + * @return 0 if not started, 1 if started, and -1 if finished + */ +s16 cutscene_object(u8 cutscene, struct Object *o) { + s16 status = 0; - if ((gCurrLevelCamera->cutscene == 0) && (sTempCutsceneNumber == 0)) { - if (gCutsceneNumber != cutsceneTable) { - func_8028F800(cutsceneTable, o); - sp1E = 1; + if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { + if (gRecentCutscene != cutscene) { + start_object_cutscene(cutscene, o); + status = 1; } else { - sp1E = -1; + status = -1; } } - return sp1E; + return status; } -void set_cam_yaw_from_focus_and_pos(struct LevelCamera *c) { - c->storedYaw = calculate_yaw(c->focus, c->pos); - c->trueYaw = c->storedYaw; +/** + * Update the camera's yaw and nextYaw. This is called from cutscenes to ignore the camera mode's yaw. + */ +void update_camera_yaw(struct Camera *c) { + c->nextYaw = calculate_yaw(c->focus, c->pos); + c->yaw = c->nextYaw; } -void func_8028FABC(void) { +void cutscene_reset_spline(void) { sCutsceneSplineSegment = 0; sCutsceneSplineSegmentProgress = 0; } -void func_8028FAE0(struct LevelCamera *c) { - gCutsceneTimer = 0x8000; +void stop_cutscene_and_retrieve_stored_info(struct Camera *c) { + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; - vec3f_copy(c->focus, D_8033B4B8.focus); - vec3f_copy(c->pos, D_8033B4B8.pos); + vec3f_copy(c->focus, sCameraStoreCutscene.focus); + vec3f_copy(c->pos, sCameraStoreCutscene.pos); } void cap_switch_save(s16 dummy) { - UNUSED s16 sp1E = dummy; + UNUSED s16 unused = dummy; save_file_do_save(gCurrSaveFileNum - 1); } -void func_8028FB80(struct CutsceneSplinePoint *a, s8 b, u8 c, Vec3s d) { - a->index = b; - a->speed = c; - vec3s_copy(a->point, d); +void init_spline_point(struct CutsceneSplinePoint *splinePoint, s8 index, u8 speed, Vec3s point) { + splinePoint->index = index; + splinePoint->speed = speed; + vec3s_copy(splinePoint->point, point); } -void func_8028FBD8(struct CutsceneSplinePoint a[], struct CutsceneSplinePoint b[]) { +void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSplinePoint src[]) { s32 j = 0; s32 i = 0; UNUSED s32 pad[2]; - func_8028FB80(&a[i], b[j].index, b[j].speed, b[j].point); + init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point); i += 1; do { do { - func_8028FB80(&a[i], b[j].index, b[j].speed, b[j].point); + init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point); i += 1; j += 1; - } while ((b[j].index != -1) && (b[j].index != -1)); //! same comparison performed twice + } while ((src[j].index != -1) && (src[j].index != -1)); //! same comparison performed twice } while (j > 16); - func_8028FB80(&a[i], 0, b[j].speed, b[j].point); - func_8028FB80(&a[i + 1], 0, 0, b[j].point); - func_8028FB80(&a[i + 2], 0, 0, b[j].point); - func_8028FB80(&a[i + 3], -1, 0, b[j].point); + // Create the end of the spline by duplicating the last point + init_spline_point(&dst[i], 0, src[j].speed, src[j].point); + init_spline_point(&dst[i + 1], 0, 0, src[j].point); + init_spline_point(&dst[i + 2], 0, 0, src[j].point); + init_spline_point(&dst[i + 3], -1, 0, src[j].point); } -s16 func_8028FD94(s32 a) { +/** + * Triggers mario to enter a dialog state. This is used to make mario look at the focus of a cutscene, + * for example, bowser. + * @param state 0 = stop, 1 = start, 2 = start and look up, and 3 = start and look down + * + * @return if mario left the dialog state, return CUTSCENE_LOOP, else return gCutsceneTimer + */ +s16 cutscene_common_set_dialog_state(s32 state) { s16 timer = gCutsceneTimer; - if (set_mario_npc_dialog(a) == 2) { - timer = 0x7FFF; + // If the dialog ended, return CUTSCENE_LOOP, which would end the cutscene shot + if (set_mario_npc_dialog(state) == 2) { + timer = CUTSCENE_LOOP; } return timer; } -static void unused_8028FDE8(UNUSED struct LevelCamera *a) { - gCutsceneTimer = func_8028FD94(3); +/// Unused SSL cutscene? +static UNUSED void unused_cutscene_mario_dialog_looking_down(UNUSED struct Camera *c) { + gCutsceneTimer = cutscene_common_set_dialog_state(3); } -static CmdRet Cutscene26Todo0(UNUSED struct LevelCamera *a) { - gCutsceneTimer = func_8028FD94(1); +/** + * Cause mario to enter the normal dialog state. + */ +static CmdRet cutscene_mario_dialog(UNUSED struct Camera *c) { + gCutsceneTimer = cutscene_common_set_dialog_state(1); } -static void unused_8028FE50(UNUSED struct LevelCamera *a) { - gCutsceneTimer = func_8028FD94(2); +/// Unused SSL cutscene? +static UNUSED void unused_cutscene_mario_dialog_looking_up(UNUSED struct Camera *c) { + gCutsceneTimer = cutscene_common_set_dialog_state(2); } -// Lower the volume and start the peach letter background music -CmdRet CutsceneIntroPeach0_2(UNUSED struct LevelCamera *a) { +/** + * Lower the volume (US only) and start the peach letter background music + */ +CmdRet cutscene_intro_peach_start_letter_music(UNUSED struct Camera *c) { #ifdef VERSION_US func_8031FFB4(0, 60, 40); #endif - func_8028B13C(); + cutscene_intro_peach_play_message_music(); } -CmdRet CutsceneIntroPeach2_1(UNUSED struct LevelCamera *a) { +/** + * Raise the volume (not in JP) and start the flying music. + */ +CmdRet cutscene_intro_peach_start_flying_music(UNUSED struct Camera *c) { #ifndef VERSION_JP sequence_player_unlower(0, 60); #endif - func_8028B16C(); + cutscene_intro_peach_play_lakitu_flying_music(); } #ifdef VERSION_EU -CmdRet CutsceneIntroPeach_unkEU(UNUSED struct LevelCamera *a) { +/** + * Lower the volume for the letter background music. In US, this happens on the same frame as the music + * starts. + */ +CmdRet cutscene_intro_peach_eu_lower_volume(UNUSED struct Camera *c) { func_8031FFB4(0, 60, 40); } #endif -void func_8028FEDC(UNUSED struct LevelCamera *a) { - D_8033B40C = 0; +void reset_pan_distance(UNUSED struct Camera *c) { + sPanDistance = 0; } -void move_credits_camera(struct LevelCamera *c, s16 minPitch, s16 maxPitch, s16 minYaw, s16 maxYaw) { +/** + * Easter egg: the player 2 controller can move the camera's focus in the ending and credits. + */ +void player2_rotate_cam(struct Camera *c, s16 minPitch, s16 maxPitch, s16 minYaw, s16 maxYaw) { f32 distCamToFocus; s16 pitch, yaw, pitchCap; - approach_s16_exponential_bool(&sCreditsCameraYaw, -(s16)(gPlayer2Controller->stickX * 250.f), 4); - approach_s16_exponential_bool(&sCreditsCameraPitch, -(s16)(gPlayer2Controller->stickY * 265.f), 4); + // Change the camera rotation to match the 2nd player's stick + approach_s16_asymptotic_bool(&sCreditsPlayer2Yaw, -(s16)(gPlayer2Controller->stickX * 250.f), 4); + approach_s16_asymptotic_bool(&sCreditsPlayer2Pitch, -(s16)(gPlayer2Controller->stickY * 265.f), 4); vec3f_get_dist_and_angle(c->pos, c->focus, &distCamToFocus, &pitch, &yaw); pitchCap = 0x3800 - pitch; @@ -5735,60 +7001,72 @@ void move_credits_camera(struct LevelCamera *c, s16 minPitch, s16 maxPitch, s16 minPitch = pitchCap; } - if (sCreditsCameraPitch > maxPitch) { - sCreditsCameraPitch = maxPitch; + if (sCreditsPlayer2Pitch > maxPitch) { + sCreditsPlayer2Pitch = maxPitch; } - if (sCreditsCameraPitch < minPitch) { - sCreditsCameraPitch = minPitch; + if (sCreditsPlayer2Pitch < minPitch) { + sCreditsPlayer2Pitch = minPitch; } - if (sCreditsCameraYaw > maxYaw) { - sCreditsCameraYaw = maxYaw; + if (sCreditsPlayer2Yaw > maxYaw) { + sCreditsPlayer2Yaw = maxYaw; } - if (sCreditsCameraYaw < minYaw) { - sCreditsCameraYaw = minYaw; + if (sCreditsPlayer2Yaw < minYaw) { + sCreditsPlayer2Yaw = minYaw; } - pitch += sCreditsCameraPitch; - yaw += sCreditsCameraYaw; - vec3f_set_dist_and_angle(c->pos, D_8033B218, distCamToFocus, pitch, yaw); - vec3f_sub(D_8033B218, c->focus); + pitch += sCreditsPlayer2Pitch; + yaw += sCreditsPlayer2Yaw; + vec3f_set_dist_and_angle(c->pos, sPlayer2FocusOffset, distCamToFocus, pitch, yaw); + vec3f_sub(sPlayer2FocusOffset, c->focus); } -void func_80290144(struct LevelCamera *c) { - vec3f_copy(D_8033B4B8.pos, c->pos); - vec3f_copy(D_8033B4B8.focus, c->focus); - D_8033B4B8.unk18 = D_8033B40C; - D_8033B4B8.unk1C = D_8033B410; +/** + * Store camera info for the cannon opening cutscene + */ +void store_info_cannon(struct Camera *c) { + vec3f_copy(sCameraStoreCutscene.pos, c->pos); + vec3f_copy(sCameraStoreCutscene.focus, c->focus); + sCameraStoreCutscene.panDist = sPanDistance; + sCameraStoreCutscene.cannonYOffset = sCannonYOffset; } -void func_802901B4(struct LevelCamera *c) { - vec3f_copy(c->pos, D_8033B4B8.pos); - vec3f_copy(c->focus, D_8033B4B8.focus); - D_8033B40C = D_8033B4B8.unk18; - D_8033B410 = D_8033B4B8.unk1C; +/** + * Retrieve camera info for the cannon opening cutscene + */ +void retrieve_info_cannon(struct Camera *c) { + vec3f_copy(c->pos, sCameraStoreCutscene.pos); + vec3f_copy(c->focus, sCameraStoreCutscene.focus); + sPanDistance = sCameraStoreCutscene.panDist; + sCannonYOffset = sCameraStoreCutscene.cannonYOffset; } -void func_80290224(struct LevelCamera *c) { - func_8028FEDC(c); - vec3f_copy(D_8033B4B8.pos, c->pos); - D_8033B4B8.focus[0] = sMarioStatusForCamera->pos[0]; - D_8033B4B8.focus[1] = c->focus[1]; - D_8033B4B8.focus[2] = sMarioStatusForCamera->pos[2]; +/** + * Store camera info for the star spawn cutscene + */ +void store_info_star(struct Camera *c) { + reset_pan_distance(c); + vec3f_copy(sCameraStoreCutscene.pos, c->pos); + sCameraStoreCutscene.focus[0] = sMarioCamState->pos[0]; + sCameraStoreCutscene.focus[1] = c->focus[1]; + sCameraStoreCutscene.focus[2] = sMarioCamState->pos[2]; } -void func_802902A8(struct LevelCamera *c) { - vec3f_copy(c->pos, D_8033B4B8.pos); - vec3f_copy(c->focus, D_8033B4B8.focus); +/** + * Retrieve camera info for the star spawn cutscene + */ +void retrieve_info_star(struct Camera *c) { + vec3f_copy(c->pos, sCameraStoreCutscene.pos); + vec3f_copy(c->focus, sCameraStoreCutscene.focus); } -static void unused_vec3s_to_vec3f(Vec3f dst, Vec3s src) { +static UNUSED void unused_vec3s_to_vec3f(Vec3f dst, Vec3s src) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; } -static void unused_vec3f_to_vec3s(Vec3s dst, Vec3f src) { +static UNUSED void unused_vec3f_to_vec3s(Vec3s dst, Vec3f src) { // note: unlike vec3f_to_vec3s(), this function doesn't round the numbers and instead simply // truncates them dst[0] = src[0]; @@ -5796,11 +7074,14 @@ static void unused_vec3f_to_vec3s(Vec3s dst, Vec3f src) { dst[2] = src[2]; } -void rotate_camera(struct LevelCamera *c, s16 incPitch, s16 incYaw) { - UNUSED Vec3f sp2C; +/** + * Rotate the camera's focus around the camera's position by incYaw and incPitch + */ +void pan_camera(struct Camera *c, s16 incPitch, s16 incYaw) { + UNUSED Vec3f unused1; f32 distCamToFocus; s16 pitch, yaw; - UNUSED f32 sp20; + UNUSED f32 unused2; vec3f_get_dist_and_angle(c->pos, c->focus, &distCamToFocus, &pitch, &yaw); pitch += incPitch; @@ -5808,705 +7089,968 @@ void rotate_camera(struct LevelCamera *c, s16 incPitch, s16 incYaw) { vec3f_set_dist_and_angle(c->pos, c->focus, distCamToFocus, pitch, yaw); } -CmdRet CutsceneEnterSomething8029041C(UNUSED struct LevelCamera *c) { - set_camera_shake_2(SHAKE_2_UNKNOWN_1); - func_8029A494(1); +CmdRet cutscene_shake_explosion(UNUSED struct Camera *c) { + set_environmental_camera_shake(SHAKE_ENV_EXPLOSION); + cutscene_set_fov_shake_preset(1); } -static void unused_80290450(UNUSED struct LevelCamera *c) { - set_camera_shake_2(SHAKE_2_UNKNOWN_2); +static UNUSED void unused_start_bowser_bounce_shake(UNUSED struct Camera *c) { + set_environmental_camera_shake(SHAKE_ENV_BOWSER_THROW_BOUNCE); } -void rotate_and_move_vec3f(Vec3f dst, Vec3f src, f32 incDist, s16 incPitch, s16 incYaw) { +/** + * Change the spherical coordinates of `to` relative to `from` by `incDist`, `incPitch`, and `incYaw` + * + * @param from the base position + * @param[out] to the destination position + */ +void rotate_and_move_vec3f(Vec3f to, Vec3f from, f32 incDist, s16 incPitch, s16 incYaw) { f32 dist; s16 pitch, yaw; - vec3f_get_dist_and_angle(src, dst, &dist, &pitch, &yaw); + vec3f_get_dist_and_angle(from, to, &dist, &pitch, &yaw); pitch += incPitch; yaw += incYaw; dist += incDist; - vec3f_set_dist_and_angle(src, dst, dist, pitch, yaw); + vec3f_set_dist_and_angle(from, to, dist, pitch, yaw); } -void func_80290514(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_BEHIND_MARIO_POST_DOOR; +void set_flag_post_door(struct Camera *c) { + sStatusFlags |= CAM_FLAG_BEHIND_MARIO_POST_DOOR; sCameraYawAfterDoorCutscene = calculate_yaw(c->focus, c->pos); } -void func_80290564(UNUSED struct LevelCamera *c) { +void cutscene_soften_music(UNUSED struct Camera *c) { func_8031FFB4(0, 60, 40); } -void func_80290598(UNUSED struct LevelCamera *c) { +void cutscene_unsoften_music(UNUSED struct Camera *c) { sequence_player_unlower(0, 60); } -void unused_802905C8(UNUSED struct LevelCamera *c) { +void unused_802905C8(UNUSED struct Camera *c) { } -CmdRet Cutscene0FTodo0(UNUSED struct LevelCamera *c) { +CmdRet cutscene_unused_start(UNUSED struct Camera *c) { } -CmdRet Cutscene0FTodo1(UNUSED struct LevelCamera *c) { +CmdRet cutscene_unused_loop(UNUSED struct Camera *c) { } -CmdRet CutscenePeachEnd0_1(struct LevelCamera *c) { +/** + * Set the camera position and focus for when mario falls from the sky. + */ +CmdRet cutscene_ending_mario_fall_start(struct Camera *c) { vec3f_set(c->focus, -26.f, 0.f, -137.f); vec3f_set(c->pos, 165.f, 4725.f, 324.f); } -CmdRet CutscenePeachEnd0_2(struct LevelCamera *c) { - Vec3f sp24; - vec3f_set(sp24, 0.f, 80.f, 0.f); +/** + * Focus on mario when he's falling from the sky. + */ +CmdRet cutscene_ending_mario_fall_focus_mario(struct Camera *c) { + Vec3f offset; + vec3f_set(offset, 0.f, 80.f, 0.f); - sp24[2] = ABS(sMarioStatusForCamera->pos[1] - c->pos[1]) * -0.1f; - if (sp24[2] > -100.f) { - sp24[2] = -100.f; + offset[2] = ABS(sMarioCamState->pos[1] - c->pos[1]) * -0.1f; + if (offset[2] > -100.f) { + offset[2] = -100.f; } - set_pos_from_face_angle_and_vec3f(c->focus, sMarioStatusForCamera->pos, sp24, - sMarioStatusForCamera->faceAngle); + offset_rotated(c->focus, sMarioCamState->pos, offset, sMarioCamState->faceAngle); } -CmdRet CutscenePeachEnd0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEnd0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd0_2, c, 0, -1); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); +/** + * Mario falls from the sky after the grand star cutscene. + */ +CmdRet cutscene_ending_mario_fall(struct Camera *c) { + cutscene_event(cutscene_ending_mario_fall_start, c, 0, 0); + cutscene_event(cutscene_ending_mario_fall_focus_mario, c, 0, -1); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd2(struct LevelCamera *c) { +/** + * Closeup of mario as the wing cap fades and mario looks up. + */ +CmdRet cutscene_ending_mario_land_closeup(struct Camera *c) { vec3f_set(c->focus, 85.f, 826.f, 250.f); vec3f_set(c->pos, -51.f, 988.f, -202.f); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEndCommon367A(UNUSED struct LevelCamera *c) { - D_8033B6F0[9].unk4[0] = 0.f; - func_8028FABC(); +/** + * Reset the spline progress and cvar9. + */ +CmdRet cutscene_ending_reset_spline(UNUSED struct Camera *c) { + sCutsceneVars[9].point[0] = 0.f; + cutscene_reset_spline(); } -CmdRet CutscenePeachEnd3_1(struct LevelCamera *c) { - move_point_along_spline(c->pos, D_8032E040, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_point_along_spline(c->focus, D_8032E090, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); +/** + * Follow sEndingFlyToWindowPos/Focus up to the window. + */ +CmdRet cutscene_ending_fly_up_to_window(struct Camera *c) { + move_point_along_spline(c->pos, sEndingFlyToWindowPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + move_point_along_spline(c->focus, sEndingFlyToWindowFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); } -CmdRet CutscenePeachEnd3(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEndCommon367A, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd3_1, c, 0, -1); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); +/** + * Move the camera up to the window as the star power frees peach. + */ +CmdRet cutscene_ending_stars_free_peach(struct Camera *c) { + cutscene_event(cutscene_ending_reset_spline, c, 0, 0); + cutscene_event(cutscene_ending_fly_up_to_window, c, 0, -1); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd1(struct LevelCamera *c) { - vec3f_set(c->focus, D_8032E090[0].point[0], D_8032E090[0].point[1] + 80.f, D_8032E090[0].point[2]); - vec3f_set(c->pos, D_8032E040[0].point[0], D_8032E040[0].point[1], D_8032E040[0].point[2] + 150.f); - move_credits_camera(c, -0x800, 0x2000, -0x2000, 0x2000); +/** + * Move the camera to the ground as mario lands. + */ +CmdRet cutscene_ending_mario_land(struct Camera *c) { + vec3f_set(c->focus, sEndingFlyToWindowFocus[0].point[0], sEndingFlyToWindowFocus[0].point[1] + 80.f, sEndingFlyToWindowFocus[0].point[2]); + vec3f_set(c->pos, sEndingFlyToWindowPos[0].point[0], sEndingFlyToWindowPos[0].point[1], sEndingFlyToWindowPos[0].point[2] + 150.f); + player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd4_1(struct LevelCamera *c) { +/** + * Move the camera closer to peach appearing. + */ +CmdRet cutscene_ending_peach_appear_closeup(struct Camera *c) { vec3f_set(c->pos, 179.f, 2463.f, -1216.f); c->pos[1] = gCutsceneFocus->oPosY + 35.f; vec3f_set(c->focus, gCutsceneFocus->oPosX, gCutsceneFocus->oPosY + 125.f, gCutsceneFocus->oPosZ); } -CmdRet CutscenePeachEnd4(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEnd4_1, c, 0, 0); - approach_f32_exponential_bool(&c->pos[1], gCutsceneFocus->oPosY + 35.f, 0.02f); - approach_f32_exponential_bool(&c->focus[1], gCutsceneFocus->oPosY + 125.f, 0.15f); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); +/** + * Peach fades in, the camera focuses on her. + */ +CmdRet cutscene_ending_peach_appears(struct Camera *c) { + cutscene_event(cutscene_ending_peach_appear_closeup, c, 0, 0); + approach_f32_asymptotic_bool(&c->pos[1], gCutsceneFocus->oPosY + 35.f, 0.02f); + approach_f32_asymptotic_bool(&c->focus[1], gCutsceneFocus->oPosY + 125.f, 0.15f); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd5_1(UNUSED struct LevelCamera *c) { - func_8028FABC(); - D_8033B6F0[2].unk4[1] = 150.f; +/** + * Reset spline progress, set cvar2 y offset. + */ +CmdRet cutscene_ending_peach_descends_start(UNUSED struct Camera *c) { + cutscene_reset_spline(); + sCutsceneVars[2].point[1] = 150.f; } -CmdRet CutscenePeachEnd5_2(struct LevelCamera *c) { - move_point_along_spline(c->pos, D_8032E0E8, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - c->pos[1] += gCutsceneFocus->oPosY + D_8033B6F0[3].unk4[1]; +/** + * Follow the sEndingPeachDescentCamPos spline, which rotates around peach. + */ +CmdRet cutscene_ending_follow_peach_descent(struct Camera *c) { + move_point_along_spline(c->pos, sEndingPeachDescentCamPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + c->pos[1] += gCutsceneFocus->oPosY + sCutsceneVars[3].point[1]; } -CmdRet CutscenePeachEnd5_3(UNUSED struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&(D_8033B6F0[2].unk4[1]), 90.f, 0.5f); +/** + * Decrease cvar2's y offset while the camera flies backwards to mario. + */ +CmdRet cutscene_ending_peach_descent_lower_focus(UNUSED struct Camera *c) { + camera_approach_f32_symmetric_bool(&(sCutsceneVars[2].point[1]), 90.f, 0.5f); } -CmdRet CutscenePeachEnd5_4(struct LevelCamera *c) { - Vec3f sp1C; +/** + * Keep following the sEndingPeachDescentCamPos spline, which leads back to mario. + */ +CmdRet cutscene_ending_peach_descent_back_to_mario(struct Camera *c) { + Vec3f pos; - move_point_along_spline(sp1C, D_8032E0E8, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - c->pos[0] = sp1C[0]; - c->pos[2] = sp1C[2]; - approach_f32_exponential_bool(&c->pos[1], (sp1C[1] += gCutsceneFocus->oPosY), 0.07f); + move_point_along_spline(pos, sEndingPeachDescentCamPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + c->pos[0] = pos[0]; + c->pos[2] = pos[2]; + approach_f32_asymptotic_bool(&c->pos[1], (pos[1] += gCutsceneFocus->oPosY), 0.07f); } -CmdRet CutscenePeachEnd5(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEnd5_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd5_2, c, 0, 299); - call_cutscene_func_in_time_range(CutscenePeachEnd5_4, c, 300, -1); - call_cutscene_func_in_time_range(CutscenePeachEnd5_3, c, 300, -1); - vec3f_set(c->focus, gCutsceneFocus->oPosX, D_8033B6F0[2].unk4[1] + gCutsceneFocus->oPosY, +/** + * Peach starts floating to the ground. Rotate the camera around her, then fly backwards to mario when + * she lands. + */ +CmdRet cutscene_ending_peach_descends(struct Camera *c) { + cutscene_event(cutscene_ending_peach_descends_start, c, 0, 0); + cutscene_event(cutscene_ending_follow_peach_descent, c, 0, 299); + cutscene_event(cutscene_ending_peach_descent_back_to_mario, c, 300, -1); + cutscene_event(cutscene_ending_peach_descent_lower_focus, c, 300, -1); + vec3f_set(c->focus, gCutsceneFocus->oPosX, sCutsceneVars[2].point[1] + gCutsceneFocus->oPosY, gCutsceneFocus->oPosZ); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd6(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEndCommon367A, c, 0, 0); - move_point_along_spline(c->pos, D_8032E188, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_point_along_spline(c->focus, D_8032E1D0, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_credits_camera(c, -0x2000, 0x2000, -0x2000, 0x2000); +/** + * Mario runs across the bridge to peach, and takes off his hat. + * Follow the sEndingMarioToPeach* splines while mario runs across. + */ +CmdRet cutscene_ending_mario_to_peach(struct Camera *c) { + cutscene_event(cutscene_ending_reset_spline, c, 0, 0); + move_point_along_spline(c->pos, sEndingMarioToPeachPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + move_point_along_spline(c->focus, sEndingMarioToPeachFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd7_1(UNUSED struct LevelCamera *c) { - move_point_along_spline(c->focus, D_8032E218, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); +/** + * Make the focus follow the sEndingLookUpAtCastle spline. + */ +CmdRet cutscene_ending_look_up_at_castle(UNUSED struct Camera *c) { + move_point_along_spline(c->focus, sEndingLookUpAtCastle, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); } -CmdRet CutscenePeachEnd7(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEndCommon367A, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd7_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd7_1, c, 250, -1); - set_cutscene_phase_at_frame(7, 300); - set_cutscene_phase_at_frame(9, 340); +/** + * Peach opens her eyes and the camera looks at the castle window again. + */ +CmdRet cutscene_ending_peach_wakeup(struct Camera *c) { + cutscene_event(cutscene_ending_reset_spline, c, 0, 0); + cutscene_event(cutscene_ending_look_up_at_castle, c, 0, 0); + cutscene_event(cutscene_ending_look_up_at_castle, c, 250, -1); + cutscene_spawn_obj(7, 300); + cutscene_spawn_obj(9, 340); vec3f_set(c->pos, -163.f, 978.f, -1082.f); - move_credits_camera(c, -0x800, 0x2000, -0x2000, 0x2000); + player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd8(struct LevelCamera *c) { +/** + * Side view of peach and mario. Peach thanks mario for saving her. + */ +CmdRet cutscene_ending_dialog(struct Camera *c) { vec3f_set(c->focus, 11.f, 983.f, -1273.f); vec3f_set(c->pos, -473.f, 970.f, -1152.f); - move_credits_camera(c, -0x800, 0x2000, -0x2000, 0x2000); + player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEnd9_1(struct LevelCamera *c) { - set_fov_function(13); +/** + * Zoom in and move the camera close to mario and peach. + */ +CmdRet cutscene_ending_kiss_closeup(struct Camera *c) { + set_fov_function(CAM_FOV_SET_29); vec3f_set(c->focus, 350.f, 1034.f, -1216.f); vec3f_set(c->pos, -149.f, 1021.f, -1216.f); } -CmdRet CutscenePeachEnd9_2(struct LevelCamera *c) { - Vec3f sp2C, sp20; +/** + * Fly back and zoom out for mario's spin after the kiss. + */ +CmdRet cutscene_ending_kiss_here_we_go(struct Camera *c) { + Vec3f pos, foc; - set_fov_function(2); - vec3f_set(sp20, 233.f, 1068.f, -1298.f); - vec3f_set(sp2C, -250.f, 966.f, -1111.f); + set_fov_function(CAM_FOV_DEFAULT); + vec3f_set(foc, 233.f, 1068.f, -1298.f); + vec3f_set(pos, -250.f, 966.f, -1111.f); //! another double typo - approach_vec3f_exponential(c->pos, sp2C, 0.2, 0.1f, 0.2f); - approach_vec3f_exponential(c->focus, sp20, 0.2, 0.1f, 0.2f); + approach_vec3f_asymptotic(c->pos, pos, 0.2, 0.1f, 0.2f); + approach_vec3f_asymptotic(c->focus, foc, 0.2, 0.1f, 0.2f); } -CmdRet CutscenePeachEnd9(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEnd9_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEnd9_2, c, 155, -1); - move_credits_camera(c, -0x800, 0x2000, -0x2000, 0x2000); +/** + * Peach kisses mario on the nose. + */ +CmdRet cutscene_ending_kiss(struct Camera *c) { + cutscene_event(cutscene_ending_kiss_closeup, c, 0, 0); + cutscene_event(cutscene_ending_kiss_here_we_go, c, 155, -1); + player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } -CmdRet CutscenePeachEndA_1(struct LevelCamera *c) { - move_point_along_spline(c->focus, D_8032E258, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); +/** + * Make the focus follow sEndingLookAtSkyFocus. + */ +CmdRet cutscene_ending_look_at_sky(struct Camera *c) { + move_point_along_spline(c->focus, sEndingLookAtSkyFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); vec3f_set(c->pos, 699.f, 1680.f, -703.f); } -CmdRet CutscenePeachEndA_2(UNUSED struct LevelCamera *c) { - D_8033B230.fieldOfView = 37.f; +/** + * Zoom in the fov. The fovFunc was just set to default, so it wants to approach 45. But while this is + * called, it will stay at about 37.26f + */ +CmdRet cutscene_ending_zoom_fov(UNUSED struct Camera *c) { + sFOVState.fov = 37.f; } -CmdRet CutscenePeachEndA(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutscenePeachEndCommon367A, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEndA_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePeachEndA_2, c, 0, 499); - call_cutscene_func_in_time_range(CutscenePeachEndA_1, c, 500, -1); - set_cutscene_phase_at_frame(8, 600); - set_cutscene_phase_at_frame(8, 608); - set_cutscene_phase_at_frame(8, 624); - set_cutscene_phase_at_frame(8, 710); +/** + * Peach suggests baking a cake for mario. Mario looks back at the camera before going inside the castle. + */ +CmdRet cutscene_ending_cake_for_mario(struct Camera *c) { + cutscene_event(cutscene_ending_reset_spline, c, 0, 0); + cutscene_event(cutscene_ending_look_at_sky, c, 0, 0); + cutscene_event(cutscene_ending_zoom_fov, c, 0, 499); + cutscene_event(cutscene_ending_look_at_sky, c, 500, -1); + cutscene_spawn_obj(8, 600); + cutscene_spawn_obj(8, 608); + cutscene_spawn_obj(8, 624); + cutscene_spawn_obj(8, 710); } -CmdRet CutscenePeachEndB(struct LevelCamera *c) { - set_fov_function(1); +/** + * Stop the ending cutscene, reset the fov. + */ +CmdRet cutscene_ending_stop(struct Camera *c) { + set_fov_function(CAM_FOV_SET_45); c->cutscene = 0; - gCutsceneTimer = -0x8000; + gCutsceneTimer = CUTSCENE_STOP; } -CmdRet CutsceneGrandStar0_1(UNUSED struct LevelCamera *c) { - vec3f_set(D_8033B6F0[0].unk4, 0.f, 150.f, -600.f); - set_pos_from_face_angle_and_vec3f(D_8033B6F0[1].unk4, sMarioStatusForCamera->pos, - D_8033B6F0[0].unk4, sMarioStatusForCamera->faceAngle); - D_8033B6F0[1].unk4[1] = 457.f; +/** + * Start the grand star cutscene. + * cvar0 is a relative offset from mario. + * cvar1 is the is the camera's goal position. + */ +CmdRet cutscene_grand_star_start(UNUSED struct Camera *c) { + vec3f_set(sCutsceneVars[0].point, 0.f, 150.f, -600.f); + offset_rotated(sCutsceneVars[1].point, sMarioCamState->pos, sCutsceneVars[0].point, sMarioCamState->faceAngle); + sCutsceneVars[1].point[1] = 457.f; } -CmdRet CutsceneGrandStar0_2(struct LevelCamera *c) { - f32 sp2C; - s16 sp2A, sp28; - f32 sp24; - s16 sp22, sp20; +/** + * Make the camera fly to the front of mario. + */ +CmdRet cutscene_grand_star_front_of_mario(struct Camera *c) { + f32 goalDist; + s16 goalPitch, goalYaw; + f32 dist; + s16 pitch, yaw; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, D_8033B6F0[1].unk4, &sp2C, &sp2A, &sp28); - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp24, &sp22, &sp20); - approach_f32_exponential_bool(&sp24, sp2C, 0.1f); - approach_s16_exponential_bool(&sp22, sp2A, 32); - approach_s16_exponential_bool(&sp20, sp28 + 0x1200, 20); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp24, sp22, sp20); + vec3f_get_dist_and_angle(sMarioCamState->pos, sCutsceneVars[1].point, &goalDist, &goalPitch, &goalYaw); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, goalDist, 0.1f); + approach_s16_asymptotic_bool(&pitch, goalPitch, 32); + approach_s16_asymptotic_bool(&yaw, goalYaw + 0x1200, 20); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneGrandStar0_4(UNUSED struct LevelCamera *c) { - vec3s_set(D_8033B6F0[0].unk1C, 0, sMarioStatusForCamera->faceAngle[1], 0); - vec3f_set(D_8033B6F0[2].unk4, 0.f, 0.f, 0.f); +/** + * Started shortly after mario starts the triple jump. Stores mario's face angle and zeros cvar2. + */ +CmdRet cutscene_grand_star_mario_jump(UNUSED struct Camera *c) { + vec3s_set(sCutsceneVars[0].angle, 0, sMarioCamState->faceAngle[1], 0); + vec3f_set(sCutsceneVars[2].point, 0.f, 0.f, 0.f); } -CmdRet CutsceneGrandStar0_5(UNUSED struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&D_8033B6F0[2].unk4[2], -40.f, 2.0f); - D_8033B6F0[2].unk4[0] = 5.0f; +/** + * Accelerate cvar2 to point back and to the left (relative to the camera). + */ +CmdRet cutscene_grand_star_accel_cvar2(UNUSED struct Camera *c) { + camera_approach_f32_symmetric_bool(&sCutsceneVars[2].point[2], -40.f, 2.0f); + sCutsceneVars[2].point[0] = 5.0f; } -CmdRet CutsceneGrandStar0_6(struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&D_8033B6F0[2].unk4[2], 0.f, 2.f); - D_8033B6F0[2].unk4[0] = 0.f; - approach_f32_exponential_bool(&c->pos[0], sMarioStatusForCamera->pos[0], 0.01f); - approach_f32_exponential_bool(&c->pos[2], sMarioStatusForCamera->pos[2], 0.01f); +/** + * Decrease cvar2 offset, follow mario by directly updating the camera's pos. + */ +CmdRet cutscene_grand_star_approach_mario(struct Camera *c) { + camera_approach_f32_symmetric_bool(&sCutsceneVars[2].point[2], 0.f, 2.f); + sCutsceneVars[2].point[0] = 0.f; + approach_f32_asymptotic_bool(&c->pos[0], sMarioCamState->pos[0], 0.01f); + approach_f32_asymptotic_bool(&c->pos[2], sMarioCamState->pos[2], 0.01f); } -CmdRet CutsceneGrandStar0_7(struct LevelCamera *c) { - set_pos_from_face_angle_and_vec3f(c->pos, c->pos, D_8033B6F0[2].unk4, D_8033B6F0[0].unk1C); +/** + * Offset the camera's position by cvar2. Before mario triple jumps, this moves back and to the left. + * After the triple jump, cvar2 decelerates to 0. + */ +CmdRet cutscene_grand_star_move_cvar2(struct Camera *c) { + offset_rotated(c->pos, c->pos, sCutsceneVars[2].point, sCutsceneVars[0].angle); } -CmdRet CutsceneGrandStar0_3(struct LevelCamera *c) { - Vec3f sp24; +CmdRet cutscene_grand_star_focus_mario(struct Camera *c) { + Vec3f foc; - vec3f_set(sp24, sMarioStatusForCamera->pos[0], - (sMarioStatusForCamera->pos[1] - 307.f) * 0.5f + 407.f, sMarioStatusForCamera->pos[2]); - approach_vec3f_exponential(c->focus, sp24, 0.5f, 0.8f, 0.5f); + vec3f_set(foc, sMarioCamState->pos[0], (sMarioCamState->pos[1] - 307.f) * 0.5f + 407.f, sMarioCamState->pos[2]); + approach_vec3f_asymptotic(c->focus, foc, 0.5f, 0.8f, 0.5f); } -CmdRet CutsceneGrandStar0(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - call_cutscene_func_in_time_range(CutsceneGrandStar0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneGrandStar0_2, c, 0, 109); - call_cutscene_func_in_time_range(CutsceneGrandStar0_3, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneGrandStar0_4, c, 110, 110); - call_cutscene_func_in_time_range(CutsceneGrandStar0_5, c, 110, 159); - call_cutscene_func_in_time_range(CutsceneGrandStar0_6, c, 160, -1); - call_cutscene_func_in_time_range(CutsceneGrandStar0_7, c, 110, -1); +/** + * The first part of the grand star cutscene, after mario has collected the grand star. + */ +CmdRet cutscene_grand_star(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + cutscene_event(cutscene_grand_star_start, c, 0, 0); + cutscene_event(cutscene_grand_star_front_of_mario, c, 0, 109); + cutscene_event(cutscene_grand_star_focus_mario, c, 0, -1); + cutscene_event(cutscene_grand_star_mario_jump, c, 110, 110); + cutscene_event(cutscene_grand_star_accel_cvar2, c, 110, 159); + cutscene_event(cutscene_grand_star_approach_mario, c, 160, -1); + cutscene_event(cutscene_grand_star_move_cvar2, c, 110, -1); } -CmdRet CutsceneGrandStar1_1(struct LevelCamera *c) { - vec3f_set(D_8033B6F0[7].unk4, 0.5f, 0.5f, 0.5f); - vec3f_set(D_8033B6F0[6].unk4, 0.01f, 0.01f, 0.01f); - vec3f_set(D_8033B6F0[4].unk4, 0.f, 0.f, 0.f); - vec3f_set(D_8033B6F0[5].unk4, 0.f, c->focus[1] - sMarioStatusForCamera->pos[1], 0.f); - D_8033B6F0[8].unk4[2] = 0.f; - D_8033B6F0[8].unk4[0] = 0.f; +/** + * Zero the cvars that are used when mario is flying. + */ +CmdRet cutscene_grand_star_fly_start(struct Camera *c) { + //! cvar7 is unused in grand star + vec3f_set(sCutsceneVars[7].point, 0.5f, 0.5f, 0.5f); + //! cvar6 is unused in grand star + vec3f_set(sCutsceneVars[6].point, 0.01f, 0.01f, 0.01f); + vec3f_set(sCutsceneVars[4].point, 0.f, 0.f, 0.f); + vec3f_set(sCutsceneVars[5].point, 0.f, c->focus[1] - sMarioCamState->pos[1], 0.f); + sCutsceneVars[8].point[2] = 0.f; + sCutsceneVars[8].point[0] = 0.f; } -CmdRet CutsceneGrandStar1_2(UNUSED struct LevelCamera *c) { - Vec3f sp24; +/** + * Decrease the cvar offsets so that lakitu flies closer to mario. + */ +CmdRet cutscene_grand_star_fly_move_to_mario(UNUSED struct Camera *c) { + Vec3f posOff; - vec3f_set(sp24, -600.f, 0.f, -400.f); - approach_vec3f_exponential(D_8033B6F0[4].unk4, sp24, 0.05f, 0.05f, 0.05f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[5].unk4[1], 0.f, 2.f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[5].unk4[2], -200.f, 6.f); + vec3f_set(posOff, -600.f, 0.f, -400.f); + approach_vec3f_asymptotic(sCutsceneVars[4].point, posOff, 0.05f, 0.05f, 0.05f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[1], 0.f, 2.f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[2], -200.f, 6.f); } -CmdRet CutsceneGrandStar1_3(UNUSED struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&D_8033B6F0[8].unk4[0], 15.f, 0.1f); +/** + * Gradually increase the cvar offsets so lakitu flies away. Mario flies offscreen to the right. + * + * cvar4 is the position offset from mario. + * cvar5 is the focus offset from mario. + * cvar8.point[0] is the approach velocity. + */ +CmdRet cutscene_grand_star_fly_mario_offscreen(UNUSED struct Camera *c) { + camera_approach_f32_symmetric_bool(&sCutsceneVars[8].point[0], 15.f, 0.1f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[4].unk4[0], -2000.f, D_8033B6F0[8].unk4[0]); - camera_approach_f32_symmetric_bool(&D_8033B6F0[4].unk4[1], 1200.f, D_8033B6F0[8].unk4[0] / 10.f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[4].unk4[2], 1000.f, D_8033B6F0[8].unk4[0] / 10.f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[4].point[0], -2000.f, sCutsceneVars[8].point[0]); + camera_approach_f32_symmetric_bool(&sCutsceneVars[4].point[1], 1200.f, sCutsceneVars[8].point[0] / 10.f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[4].point[2], 1000.f, sCutsceneVars[8].point[0] / 10.f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[5].unk4[0], 0.f, D_8033B6F0[8].unk4[0]); - camera_approach_f32_symmetric_bool(&D_8033B6F0[5].unk4[1], 1200.f, D_8033B6F0[8].unk4[0] / 2.f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[5].unk4[2], 1000.f, D_8033B6F0[8].unk4[0] / 1.5f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[0], 0.f, sCutsceneVars[8].point[0]); + camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[1], 1200.f, sCutsceneVars[8].point[0] / 2.f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[2], 1000.f, sCutsceneVars[8].point[0] / 1.5f); } -CmdRet CutsceneGrandStar1_4(struct LevelCamera *c) { - Vec3f sp34, sp28; - f32 sp24; - s16 sp22, sp20; +/** + * Make lakitu approach the cvars. + * cvar4 is the position offset. + * cvar5 is the focus offset. + */ +CmdRet cutscene_grand_star_fly_app_cvars(struct Camera *c) { + Vec3f goalPos, goalFoc; + f32 dist; + s16 pitch, yaw; - camera_approach_f32_symmetric_bool(&D_8033B6F0[8].unk4[2], 90.f, 2.5f); - set_pos_from_face_angle_and_vec3f(sp34, sMarioStatusForCamera->pos, D_8033B6F0[4].unk4, - sMarioStatusForCamera->faceAngle); - set_pos_from_face_angle_and_vec3f(sp28, sMarioStatusForCamera->pos, D_8033B6F0[5].unk4, - sMarioStatusForCamera->faceAngle); + camera_approach_f32_symmetric_bool(&sCutsceneVars[8].point[2], 90.f, 2.5f); + offset_rotated(goalPos, sMarioCamState->pos, sCutsceneVars[4].point, sMarioCamState->faceAngle); + offset_rotated(goalFoc, sMarioCamState->pos, sCutsceneVars[5].point, sMarioCamState->faceAngle); - vec3f_get_dist_and_angle(sp34, c->pos, &sp24, &sp22, &sp20); - camera_approach_f32_symmetric_bool(&sp24, 0, D_8033B6F0[8].unk4[2]); - vec3f_set_dist_and_angle(sp34, c->pos, sp24, sp22, sp20); + // Move towards goalPos by cvar8's Z speed + vec3f_get_dist_and_angle(goalPos, c->pos, &dist, &pitch, &yaw); + camera_approach_f32_symmetric_bool(&dist, 0, sCutsceneVars[8].point[2]); + vec3f_set_dist_and_angle(goalPos, c->pos, dist, pitch, yaw); - approach_vec3f_exponential(c->pos, sp34, 0.01f, 0.01f, 0.01f); - approach_vec3f_exponential(c->focus, sp28, 0.5f, 0.8f, 0.5f); + approach_vec3f_asymptotic(c->pos, goalPos, 0.01f, 0.01f, 0.01f); + approach_vec3f_asymptotic(c->focus, goalFoc, 0.5f, 0.8f, 0.5f); } -CmdRet CutsceneGrandStar1(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - call_cutscene_func_in_time_range(CutsceneGrandStar1_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneGrandStar1_2, c, 0, 140); - call_cutscene_func_in_time_range(CutsceneGrandStar1_3, c, 141, -1); - call_cutscene_func_in_time_range(CutsceneGrandStar1_4, c, 0, -1); +/** + * Part of the grand star cutscene, starts after mario is flying. + * + * cvar4 and cvar5 are directions, relative to mario: + * cvar4 is used as the camera position's offset from mario. + * cvar5 is used as the camera focus's offset from mario. + * + * cvar8.point[2] is lakitu's speed. + */ +CmdRet cutscene_grand_star_fly(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + cutscene_event(cutscene_grand_star_fly_start, c, 0, 0); + cutscene_event(cutscene_grand_star_fly_move_to_mario, c, 0, 140); + cutscene_event(cutscene_grand_star_fly_mario_offscreen, c, 141, -1); + cutscene_event(cutscene_grand_star_fly_app_cvars, c, 0, -1); } -void func_80291BBC(struct LevelCamera *a, f32 b, f32 c) { - Vec3f sp2C, sp20; +/** + * Adjust the camera focus towards a point `dist` units in front of mario. + * @param dist distance in mario's forward direction. Note that this is relative to mario, so a negative + * distance will focus in front of mario, and a positive distance will focus behind him. + */ +void focus_in_front_of_mario(struct Camera *c, f32 dist, f32 speed) { + Vec3f goalFocus, offset; - sp20[0] = 0.f; - sp20[2] = b; - sp20[1] = 100.f; + offset[0] = 0.f; + offset[2] = dist; + offset[1] = 100.f; - set_pos_from_face_angle_and_vec3f(sp2C, sMarioStatusForCamera->pos, sp20, - sMarioStatusForCamera->faceAngle); - approach_vec3f_exponential(a->focus, sp2C, c, c, c); + offset_rotated(goalFocus, sMarioCamState->pos, offset, sMarioCamState->faceAngle); + approach_vec3f_asymptotic(c->focus, goalFocus, speed, speed, speed); } -CmdRet CutsceneDanceCommon(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +/** + * Approach mario and look up. Since mario faces the camera when he collects the star, there's no need + * to worry about the camera's yaw. + */ +CmdRet cutscene_dance_move_to_mario(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp20, &sp26, &sp24); - approach_f32_exponential_bool(&sp20, 600.f, 0.3f); - approach_s16_exponential_bool(&sp26, 0x1000, 0x10); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp20, sp26, sp24); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 600.f, 0.3f); + approach_s16_asymptotic_bool(&pitch, 0x1000, 0x10); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneStarDance1_4(struct LevelCamera *c) { - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, 0, 0, 0x200); +CmdRet cutscene_dance_rotate(struct Camera *c) { + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, 0, 0x200); } -CmdRet CutsceneStarDance1_5(struct LevelCamera *c) { - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, -15.f, 0, 0); +CmdRet cutscene_dance_rotate_move_back(struct Camera *c) { + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, -15.f, 0, 0); } -CmdRet CutsceneStarDance1_6(struct LevelCamera *c) { - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, 20.f, 0, 0); +CmdRet cutscene_dance_rotate_move_towards_mario(struct Camera *c) { + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 20.f, 0, 0); } -void dummy_80291DC0(UNUSED struct LevelCamera *c) { +/** + * Speculated to be dance-related due to its proximity to the other dance functions + */ +CmdRet cutscene_dance_unused(UNUSED struct Camera *c) { } -CmdRet CutsceneStarDance1_1(struct LevelCamera *c) { - func_80291BBC(c, -100.f, 0.2f); +/** + * Slowly turn to the point 100 units in front of mario + */ +CmdRet cutscene_dance_default_focus_mario(struct Camera *c) { + focus_in_front_of_mario(c, -100.f, 0.2f); } -CmdRet CutsceneStarDance1_3(struct LevelCamera *c) { - func_80291BBC(c, -200.f, 0.03f); +/** + * Focus twice as far away as default dance, and move faster. + */ +CmdRet cutscene_dance_rotate_focus_mario(struct Camera *c) { + focus_in_front_of_mario(c, -200.f, 0.03f); } -CmdRet CutsceneStarDance1_2(UNUSED struct LevelCamera *c) { - func_80299C98(0x200, 40, -0x8000); +CmdRet cutscene_dance_shake_fov(UNUSED struct Camera *c) { + set_fov_shake(0x200, 0x28, 0x8000); } -CmdRet CutsceneStarDance1(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - D_8032CFD4 = 0; - set_fov_function(2); - call_cutscene_func_in_time_range(CutsceneStarDance1_1, c, 0, 20); - call_cutscene_func_in_time_range(CutsceneDanceCommon, c, 0, 39); - call_cutscene_func_in_time_range(CutsceneStarDance1_2, c, 40, 40); - if (c->cutscene != CUTSCENE_STAR_DANCE_1_2) { - call_cutscene_func_in_time_range(CutsceneStarDance1_3, c, 75, 102); - call_cutscene_func_in_time_range(CutsceneStarDance1_4, c, 50, -1); - call_cutscene_func_in_time_range(CutsceneStarDance1_5, c, 50, 80); - call_cutscene_func_in_time_range(CutsceneStarDance1_6, c, 70, 90); +/** + * Handles both the default and rotate dance cutscenes. + * In the default dance: the camera moves closer to mario, then stays in place. + * In the rotate dance: the camera moves closer and rotates clockwise around mario. + */ +CmdRet cutscene_dance_default_rotate(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sYawSpeed = 0; + set_fov_function(CAM_FOV_DEFAULT); + cutscene_event(cutscene_dance_default_focus_mario, c, 0, 20); + cutscene_event(cutscene_dance_move_to_mario, c, 0, 39); + // Shake the camera on the 4th beat of the music, when mario gives the peace sign. + cutscene_event(cutscene_dance_shake_fov, c, 40, 40); + + if (c->cutscene != CUTSCENE_DANCE_DEFAULT) { // CUTSCENE_DANCE_ROTATE + cutscene_event(cutscene_dance_rotate_focus_mario, c, 75, 102); + cutscene_event(cutscene_dance_rotate, c, 50, -1); + // These two functions move the camera away and then towards mario. + cutscene_event(cutscene_dance_rotate_move_back, c, 50, 80); + cutscene_event(cutscene_dance_rotate_move_towards_mario, c, 70, 90); } else { - if ((sMarioStatusForCamera->action != ACT_STAR_DANCE_NO_EXIT) - && (sMarioStatusForCamera->action != ACT_STAR_DANCE_WATER) - && (sMarioStatusForCamera->action != ACT_STAR_DANCE_EXIT)) { - gCutsceneTimer = 0x8000; + // secret star, 100 coin star, or bowser red coin star. + if ((sMarioCamState->action != ACT_STAR_DANCE_NO_EXIT) + && (sMarioCamState->action != ACT_STAR_DANCE_WATER) + && (sMarioCamState->action != ACT_STAR_DANCE_EXIT)) { + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; - init_transitional_movement(c, 20); - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + transition_next_state(c, 20); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } } } -CmdRet func_80291FE8(struct LevelCamera *a, s16 b, s16 c) { - s16 pitch, yaw; +/** + * If the camera's yaw is out of the range of `absYaw` +- `yawMax`, then set the yaw to `absYaw` + */ +CmdRet star_dance_bound_yaw(struct Camera *c, s16 absYaw, s16 yawMax) { + s16 dummyPitch, yaw; f32 distCamToMario; - s16 sp26; + s16 yawFromAbs; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, a->pos, &distCamToMario, &pitch, &yaw); - sp26 = yaw - b; + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &distCamToMario, &dummyPitch, &yaw); + yawFromAbs = yaw - absYaw; - if ((sp26 & 0x8000) != 0) { - sp26 = -sp26; + // Because angles are s16, this checks if yaw is negative + if ((yawFromAbs & 0x8000) != 0) { + yawFromAbs = -yawFromAbs; } - if (sp26 > c) { - yaw = b; - a->storedYaw = yaw; - a->trueYaw = yaw; + if (yawFromAbs > yawMax) { + yaw = absYaw; + c->nextYaw = yaw; + c->yaw = yaw; } } -CmdRet CutsceneStarDance3_1(struct LevelCamera *c) { +/** + * Start the closeup dance cutscene by restricting the camera's yaw in certain areas. + * Store the camera's focus in cvar9. + */ +CmdRet cutscene_dance_closeup_start(struct Camera *c) { UNUSED s32 pad[2]; if ((gLastCompletedStarNum == 4) && (gCurrCourseNum == COURSE_JRB)) { - func_80291FE8(c, 0, 0x4000); + star_dance_bound_yaw(c, 0x0, 0x4000); } if ((gLastCompletedStarNum == 1) && (gCurrCourseNum == COURSE_DDD)) { - func_80291FE8(c, -0x8000, 0x5000); + star_dance_bound_yaw(c, 0x8000, 0x5000); } if ((gLastCompletedStarNum == 5) && (gCurrCourseNum == COURSE_WDW)) { - func_80291FE8(c, -0x8000, 0x800); + star_dance_bound_yaw(c, 0x8000, 0x800); } - vec3f_copy(D_8033B6F0[9].unk4, c->focus); - D_8033B6F0[8].unk1C[0] = 0x2000; + vec3f_copy(sCutsceneVars[9].point, c->focus); + //! cvar8 is unused in the closeup cutscene + sCutsceneVars[8].angle[0] = 0x2000; } -CmdRet CutsceneStarDance3_2(struct LevelCamera *c) { - Vec3f sp24; +/** + * Focus the camera on mario eye height. + */ +CmdRet cutscene_dance_closeup_focus_mario(struct Camera *c) { + Vec3f marioPos; - vec3f_set(sp24, sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 125.f, - sMarioStatusForCamera->pos[2]); - approach_vec3f_exponential(D_8033B6F0[9].unk4, sp24, 0.2f, 0.2f, 0.2f); - vec3f_copy(c->focus, D_8033B6F0[9].unk4); + vec3f_set(marioPos, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); + approach_vec3f_asymptotic(sCutsceneVars[9].point, marioPos, 0.2f, 0.2f, 0.2f); + vec3f_copy(c->focus, sCutsceneVars[9].point); } -CmdRet CutsceneStarDance3_3(struct LevelCamera *c) { - s16 sp2E, sp2C; - f32 sp28; - s16 sp26 = 0x1800; +/** + * Fly above mario, looking down. + */ +CmdRet cutscene_dance_closeup_fly_above(struct Camera *c) { + s16 pitch, yaw; + f32 dist; + s16 goalPitch = 0x1800; - if (((gLastCompletedStarNum == 6) && (gCurrCourseNum == COURSE_SL)) - || ((gLastCompletedStarNum == 4) && (gCurrCourseNum == COURSE_TTC))) { - sp26 = 0x800; + if ((gLastCompletedStarNum == 6 && gCurrCourseNum == COURSE_SL) || + (gLastCompletedStarNum == 4 && gCurrCourseNum == COURSE_TTC)) { + goalPitch = 0x800; } - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp28, &sp2E, &sp2C); - approach_f32_exponential_bool(&sp28, 800.f, 0.05f); - approach_s16_exponential_bool(&sp2E, sp26, 16); - approach_s16_exponential_bool(&sp2C, c->trueYaw, 8); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp28, sp2E, sp2C); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 800.f, 0.05f); + approach_s16_asymptotic_bool(&pitch, goalPitch, 16); + approach_s16_asymptotic_bool(&yaw, c->yaw, 8); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneStarDance3_4(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +/** + * Fly closer right when mario gives the peace sign. + */ +CmdRet cutscene_dance_closeup_fly_closer(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp20, &sp26, &sp24); - approach_f32_exponential_bool(&sp20, 240.f, 0.4f); - approach_s16_exponential_bool(&sp24, c->trueYaw, 8); - approach_s16_exponential_bool(&sp26, 0x1000, 5); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp20, sp26, sp24); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 240.f, 0.4f); + approach_s16_asymptotic_bool(&yaw, c->yaw, 8); + approach_s16_asymptotic_bool(&pitch, 0x1000, 5); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneStarDance3_5(UNUSED struct LevelCamera *c) { - set_fov_function(9); +/** + * Zoom in by increasing fov to 80 degrees. Most dramatic zoom in the game. + */ +CmdRet cutscene_dance_closeup_zoom(UNUSED struct Camera *c) { + set_fov_function(CAM_FOV_APP_80); } -CmdRet CutsceneStarDance3_6(UNUSED struct LevelCamera *c) { - func_80299C98(0x300, 48, -0x8000); +/** + * Shake fov, starts on the first frame mario has the peace sign up. + */ +CmdRet cutscene_dance_closeup_shake_fov(UNUSED struct Camera *c) { + set_fov_shake(0x300, 0x30, 0x8000); } -CmdRet CutsceneStarDance3(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * The camera moves in for a closeup on mario. Used for stars that are underwater or in tight places. + */ +CmdRet cutscene_dance_closeup(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; - if (sMarioStatusForCamera->action == ACT_STAR_DANCE_WATER) { - call_cutscene_func_in_time_range(CutsceneStarDance3_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneStarDance3_2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneStarDance3_3, c, 0, 62); - call_cutscene_func_in_time_range(CutsceneStarDance3_4, c, 63, -1); - call_cutscene_func_in_time_range(CutsceneStarDance3_5, c, 63, 63); - call_cutscene_func_in_time_range(CutsceneStarDance3_6, c, 70, 70); + if (sMarioCamState->action == ACT_STAR_DANCE_WATER) { + cutscene_event(cutscene_dance_closeup_start, c, 0, 0); + cutscene_event(cutscene_dance_closeup_focus_mario, c, 0, -1); + cutscene_event(cutscene_dance_closeup_fly_above, c, 0, 62); + cutscene_event(cutscene_dance_closeup_fly_closer, c, 63, -1); + cutscene_event(cutscene_dance_closeup_zoom, c, 63, 63); + cutscene_event(cutscene_dance_closeup_shake_fov, c, 70, 70); } else { - call_cutscene_func_in_time_range(CutsceneStarDance3_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneStarDance3_2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneStarDance3_3, c, 0, 32); - call_cutscene_func_in_time_range(CutsceneStarDance3_4, c, 33, -1); - call_cutscene_func_in_time_range(CutsceneStarDance3_5, c, 33, 33); - call_cutscene_func_in_time_range(CutsceneStarDance3_6, c, 40, 40); + cutscene_event(cutscene_dance_closeup_start, c, 0, 0); + cutscene_event(cutscene_dance_closeup_focus_mario, c, 0, -1); + // Almost twice as fast as under water + cutscene_event(cutscene_dance_closeup_fly_above, c, 0, 32); + cutscene_event(cutscene_dance_closeup_fly_closer, c, 33, -1); + cutscene_event(cutscene_dance_closeup_zoom, c, 33, 33); + cutscene_event(cutscene_dance_closeup_shake_fov, c, 40, 40); } - set_spline_values(1); + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet CutsceneStarDance2_1(struct LevelCamera *c) { - Vec3f sp1C; +/** + * cvar8.point[2] is the amount to increase distance from mario + */ +CmdRet cutscene_dance_fly_away_start(struct Camera *c) { + Vec3f areaCenter; - vec3f_copy(D_8033B6F0[9].unk4, c->focus); - D_8033B6F0[8].unk4[2] = 65.f; + vec3f_copy(sCutsceneVars[9].point, c->focus); + sCutsceneVars[8].point[2] = 65.f; - if (c->currPreset == CAMERA_PRESET_OPEN_CAMERA) { - vec3f_set(sp1C, c->xFocus, c->unk68, c->zFocus); - c->trueYaw = calculate_yaw(sp1C, c->pos); - c->storedYaw = c->trueYaw; + if (c->mode == CAMERA_MODE_RADIAL) { + vec3f_set(areaCenter, c->areaCenX, c->areaCenY, c->areaCenZ); + c->yaw = calculate_yaw(areaCenter, c->pos); + c->nextYaw = c->yaw; } + // Restrict the camera yaw in tight spaces if ((gLastCompletedStarNum == 6) && (gCurrCourseNum == COURSE_CCM)) { - func_80291FE8(c, 0x5600, 0x800); + star_dance_bound_yaw(c, 0x5600, 0x800); } if ((gLastCompletedStarNum == 2) && (gCurrCourseNum == COURSE_TTM)) { - func_80291FE8(c, 0, 0x800); + star_dance_bound_yaw(c, 0x0, 0x800); } if ((gLastCompletedStarNum == 1) && (gCurrCourseNum == COURSE_SL)) { - func_80291FE8(c, 0x2000, 0x800); + star_dance_bound_yaw(c, 0x2000, 0x800); } if ((gLastCompletedStarNum == 3) && (gCurrCourseNum == COURSE_RR)) { - func_80291FE8(c, 0, 0x800); + star_dance_bound_yaw(c, 0x0, 0x800); } } -CmdRet CutsceneStarDance2_3(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +CmdRet cutscene_dance_fly_away_approach_mario(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp20, &sp26, &sp24); - approach_f32_exponential_bool(&sp20, 600.f, 0.3f); - approach_s16_exponential_bool(&sp26, 0x1000, 16); - approach_s16_exponential_bool(&sp24, c->trueYaw, 8); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp20, sp26, sp24); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 600.f, 0.3f); + approach_s16_asymptotic_bool(&pitch, 0x1000, 16); + approach_s16_asymptotic_bool(&yaw, c->yaw, 8); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneStarDance2_2(struct LevelCamera *c) { - Vec3f sp24; +CmdRet cutscene_dance_fly_away_focus_mario(struct Camera *c) { + Vec3f marioPos; - vec3f_set(sp24, sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 125.f, - sMarioStatusForCamera->pos[2]); - approach_vec3f_exponential(D_8033B6F0[9].unk4, sp24, 0.2f, 0.2f, 0.2f); - vec3f_copy(c->focus, D_8033B6F0[9].unk4); + vec3f_set(marioPos, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); + approach_vec3f_asymptotic(sCutsceneVars[9].point, marioPos, 0.2f, 0.2f, 0.2f); + vec3f_copy(c->focus, sCutsceneVars[9].point); } -void func_80292884(struct LevelCamera *c) { - vec3f_copy(c->focus, D_8033B6F0[9].unk4); - D_8033B6F0[9].unk1C[0] -= 29; - D_8033B6F0[9].unk1C[1] += 29; - rotate_camera(c, D_8033B6F0[9].unk1C[0], D_8033B6F0[9].unk1C[1]); +/** + * Slowly pan the camera downwards and to the camera's right, using cvar9's angle. + */ +void cutscene_pan_cvar9(struct Camera *c) { + vec3f_copy(c->focus, sCutsceneVars[9].point); + sCutsceneVars[9].angle[0] -= 29; + sCutsceneVars[9].angle[1] += 29; + pan_camera(c, sCutsceneVars[9].angle[0], sCutsceneVars[9].angle[1]); } -CmdRet CutsceneStarDance2_4(struct LevelCamera *c) { - func_80292884(c); - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, D_8033B6F0[8].unk4[2], 0, 0); +/** + * Move backwards and rotate slowly around mario. + */ +CmdRet cutscene_dance_fly_rotate_around_mario(struct Camera *c) { + cutscene_pan_cvar9(c); + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, sCutsceneVars[8].point[2], 0, 0); } -CmdRet CutsceneStarDance2_5(struct LevelCamera *c) { - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, 0, 0, 0x80); +/** + * Rotate quickly while lakitu flies up. + */ +CmdRet cutscene_dance_fly_away_rotate_while_flying(struct Camera *c) { + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, 0, 0x80); } -CmdRet CutsceneStarDance2_6(UNUSED struct LevelCamera *c) { - func_80299C98(0x400, 48, -0x8000); +CmdRet cutscene_dance_fly_away_shake_fov(UNUSED struct Camera *c) { + set_fov_shake(0x400, 0x30, 0x8000); } -CmdRet CutsceneStarDance2(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - call_cutscene_func_in_time_range(CutsceneStarDance2_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneStarDance2_2, c, 0, 30); - call_cutscene_func_in_time_range(CutsceneStarDance2_3, c, 0, 30); - call_cutscene_func_in_time_range(CutsceneStarDance2_4, c, 55, 124); - call_cutscene_func_in_time_range(CutsceneStarDance2_5, c, 55, 124); - call_cutscene_func_in_time_range(CutsceneStarDance2_6, c, 40, 40); - set_fov_function(2); - set_spline_values(5); +/** + * After collecting the star, lakitu flies upwards out of the course. + */ +CmdRet cutscene_dance_fly_away(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + cutscene_event(cutscene_dance_fly_away_start, c, 0, 0); + cutscene_event(cutscene_dance_fly_away_focus_mario, c, 0, 30); + cutscene_event(cutscene_dance_fly_away_approach_mario, c, 0, 30); + cutscene_event(cutscene_dance_fly_rotate_around_mario, c, 55, 124); + cutscene_event(cutscene_dance_fly_away_rotate_while_flying, c, 55, 124); + cutscene_event(cutscene_dance_fly_away_shake_fov, c, 40, 40); + set_fov_function(CAM_FOV_DEFAULT); + set_handheld_shake(HAND_CAM_SHAKE_STAR_DANCE); } -CmdRet CutsceneKeyDance0_6(struct LevelCamera *c) { - set_pos_from_face_angle_and_vec3f(c->pos, sMarioStatusForCamera->pos, D_8033B6F0[8].unk4, - sMarioStatusForCamera->faceAngle); - set_pos_from_face_angle_and_vec3f(c->focus, sMarioStatusForCamera->pos, D_8033B6F0[7].unk4, - sMarioStatusForCamera->faceAngle); +/** + * Jump the camera pos and focus to cvar 8 and 7. + * Called every frame, starting after 10, so when these cvars are updated, the camera will jump. + */ +CmdRet cutscene_key_dance_jump_cvar(struct Camera *c) { + offset_rotated(c->pos, sMarioCamState->pos, sCutsceneVars[8].point, sMarioCamState->faceAngle); + offset_rotated(c->focus, sMarioCamState->pos, sCutsceneVars[7].point, sMarioCamState->faceAngle); } -CmdRet CutsceneKeyDance0_2(UNUSED struct LevelCamera *c) { - vec3f_set(D_8033B6F0[8].unk4, 38.f, 171.f, -248.f); - vec3f_set(D_8033B6F0[7].unk4, -57.f, 51.f, 187.f); +/** + * Jump to a closeup view of mario and the key. + */ +CmdRet cutscene_key_dance_jump_closeup(UNUSED struct Camera *c) { + vec3f_set(sCutsceneVars[8].point, 38.f, 171.f, -248.f); + vec3f_set(sCutsceneVars[7].point, -57.f, 51.f, 187.f); } -CmdRet CutsceneKeyDance0_3(UNUSED struct LevelCamera *c) { - vec3f_set(D_8033B6F0[8].unk4, -178.f, 62.f, -132.f); - vec3f_set(D_8033B6F0[7].unk4, 299.f, 91.f, 58.f); +/** + * Jump to a view from the lower left (mario's right). + */ +CmdRet cutscene_key_dance_jump_lower_left(UNUSED struct Camera *c) { + vec3f_set(sCutsceneVars[8].point, -178.f, 62.f, -132.f); + vec3f_set(sCutsceneVars[7].point, 299.f, 91.f, 58.f); } -CmdRet CutsceneKeyDance0_4(UNUSED struct LevelCamera *c) { - gCameraStatus.cameraKeyCutsceneRollOffset = 0x2800; - vec3f_set(D_8033B6F0[8].unk4, 89.f, 373.f, -304.f); - vec3f_set(D_8033B6F0[7].unk4, 0.f, 127.f, 0.f); +/** + * Jump to a rotated view from above. + */ +CmdRet cutscene_key_dance_jump_above(UNUSED struct Camera *c) { + gLakituState.keyDanceRoll = 0x2800; + vec3f_set(sCutsceneVars[8].point, 89.f, 373.f, -304.f); + vec3f_set(sCutsceneVars[7].point, 0.f, 127.f, 0.f); } -CmdRet CutsceneKeyDance0_5(UNUSED struct LevelCamera *c) { - gCameraStatus.cameraKeyCutsceneRollOffset = 0; - vec3f_set(D_8033B6F0[8].unk4, 135.f, 158.f, -673.f); - vec3f_set(D_8033B6F0[7].unk4, -20.f, 135.f, -198.f); +/** + * Finally, jump to a further view, slightly to mario's left. + */ +CmdRet cutscene_key_dance_jump_last(UNUSED struct Camera *c) { + gLakituState.keyDanceRoll = 0; + vec3f_set(sCutsceneVars[8].point, 135.f, 158.f, -673.f); + vec3f_set(sCutsceneVars[7].point, -20.f, 135.f, -198.f); } -CmdRet CutsceneKeyDance0_7(UNUSED struct LevelCamera *c) { - func_80299C98(0x180, 48, -0x8000); +CmdRet cutscene_key_dance_shake_fov(UNUSED struct Camera *c) { + set_fov_shake(0x180, 0x30, 0x8000); } -CmdRet CutsceneKeyDance0_8(UNUSED struct LevelCamera *c) { - set_spline_values(1); +CmdRet cutscene_key_dance_handheld_shake(UNUSED struct Camera *c) { + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet CutsceneKeyDance0_1(struct LevelCamera *c) { - func_80291BBC(c, 0, 0.2f); +CmdRet cutscene_key_dance_focus_mario(struct Camera *c) { + focus_in_front_of_mario(c, 0, 0.2f); } -CmdRet CutsceneKeyDance0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneDanceCommon, c, 0, 10); - call_cutscene_func_in_time_range(CutsceneKeyDance0_1, c, 0, 10); - call_cutscene_func_in_time_range(CutsceneKeyDance0_2, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneKeyDance0_3, c, 20, 20); - call_cutscene_func_in_time_range(CutsceneKeyDance0_4, c, 35, 35); - call_cutscene_func_in_time_range(CutsceneKeyDance0_5, c, 52, 52); - call_cutscene_func_in_time_range(CutsceneKeyDance0_6, c, 11, -1); - call_cutscene_func_in_time_range(CutsceneKeyDance0_7, c, 54, 54); - call_cutscene_func_in_time_range(CutsceneKeyDance0_8, c, 52, -1); +/** + * Cutscene that plays when mario collects a key from bowser. It's basically a sequence of four jump + * cuts. + */ +CmdRet cutscene_key_dance(struct Camera *c) { + cutscene_event(cutscene_dance_move_to_mario, c, 0, 10); + cutscene_event(cutscene_key_dance_focus_mario, c, 0, 10); + cutscene_event(cutscene_key_dance_jump_closeup, c, 0, 0); + cutscene_event(cutscene_key_dance_jump_lower_left, c, 20, 20); + cutscene_event(cutscene_key_dance_jump_above, c, 35, 35); + cutscene_event(cutscene_key_dance_jump_last, c, 52, 52); + cutscene_event(cutscene_key_dance_jump_cvar, c, 11, -1); + cutscene_event(cutscene_key_dance_shake_fov, c, 54, 54); + cutscene_event(cutscene_key_dance_handheld_shake, c, 52, -1); } -CmdRet CutsceneEnterBowserPlatform0_4(UNUSED struct LevelCamera *c) { - func_8029A494(2); +CmdRet cutscene_bowser_area_shake_fov(UNUSED struct Camera *c) { + cutscene_set_fov_shake_preset(2); } -CmdRet CutsceneEnterBowserPlatform0_3(UNUSED struct LevelCamera *c) { +/** + * Set oBowserUnk88 to 1, which causes bowser to start walking. + */ +CmdRet cutscene_bowser_area_start_bowser_walking(UNUSED struct Camera *c) { gSecondCameraFocus->oBowserUnk88 = 1; } -CmdRet CutsceneEnterBowserPlatform0_5(struct LevelCamera *c) { - vec3f_set_dist_and_angle(D_8033B6F0[2].unk4, c->pos, D_8033B6F0[3].unk4[2], D_8033B6F0[3].unk1C[0], - D_8033B6F0[3].unk1C[1]); - vec3f_set(D_8033B6F0[2].unk4, gSecondCameraFocus->oPosX, gSecondCameraFocus->oPosY, +/** + * Offset the camera from bowser using cvar2 and cvar3 + * @bug cvar2.point is (0,0,0) on the first frame, but because of the warp transition, this behavior + * isn't seen. After the first frame, cvar2.point is bowser's position. + */ +CmdRet cutscene_bowser_arena_set_pos(struct Camera *c) { + vec3f_set_dist_and_angle(sCutsceneVars[2].point, c->pos, sCutsceneVars[3].point[2], + sCutsceneVars[3].angle[0], sCutsceneVars[3].angle[1]); + vec3f_set(sCutsceneVars[2].point, gSecondCameraFocus->oPosX, gSecondCameraFocus->oPosY, gSecondCameraFocus->oPosZ); } -CmdRet CutsceneEnterBowserPlatform0_8(UNUSED struct LevelCamera *c) { - f32 sp1C = 150.0f; +/** + * Apply a sine wave to the focus's y coordinate. + * The y offset starts at 120, then decreases to 0 before reaching ~240 on the last frame. + */ +CmdRet cutscene_bowser_arena_focus_sine(UNUSED struct Camera *c) { + //! unused initialization + f32 yOff = 150.0f; - sp1C = sins(D_8033B6F0[4].unk1C[1]) * 120.0f + 120.0f; - D_8033B6F0[4].unk1C[1] -= 0x200; - approach_f32_exponential_bool(&D_8033B6F0[0].unk4[1], sp1C, 0.5f); + // cvar4 was zeroed when the cutscene started. + yOff = sins(sCutsceneVars[4].angle[1]) * 120.0f + 120.0f; + sCutsceneVars[4].angle[1] -= 0x200; + approach_f32_asymptotic_bool(&sCutsceneVars[0].point[1], yOff, 0.5f); } -CmdRet CutsceneEnterBowserPlatform0_9(struct LevelCamera *c) { - set_pos_from_face_angle_and_vec3f(c->focus, D_8033B6F0[2].unk4, D_8033B6F0[0].unk4, - D_8033B6F0[2].unk1C); +/** + * Set the camera focus according to cvar0 and cvar2. + */ +CmdRet cutscene_bowser_arena_set_focus(struct Camera *c) { + offset_rotated(c->focus, sCutsceneVars[2].point, sCutsceneVars[0].point, sCutsceneVars[2].angle); } -CmdRet CutsceneEnterBowserPlatform0_7(UNUSED struct LevelCamera *c) { - approach_s16_exponential_bool(&D_8033B6F0[3].unk1C[0], 1736, 30); - approach_f32_exponential_bool(&D_8033B6F0[0].unk4[2], -200.f, 0.02f); - approach_f32_exponential_bool(&D_8033B6F0[3].unk4[2], 550.f, 0.02f); +/** + * Adjust the cvar offsets, making the camera look up, move slightly further back, and focus a little + * further in front of bowser. + */ +CmdRet cutscene_bowser_arena_adjust_offsets(UNUSED struct Camera *c) { + approach_s16_asymptotic_bool(&sCutsceneVars[3].angle[0], 0x6C8, 30); + approach_f32_asymptotic_bool(&sCutsceneVars[0].point[2], -200.f, 0.02f); + approach_f32_asymptotic_bool(&sCutsceneVars[3].point[2], 550.f, 0.02f); } -CmdRet CutsceneEnterBowserPlatform0_6(UNUSED struct LevelCamera *c) { - approach_f32_exponential_bool(&D_8033B6F0[0].unk4[2], 0.f, 0.05f); +/** + * Decrease cvar0's z offset, making the camera focus pan left towards bowser. + */ +CmdRet cutscene_bowser_arena_pan_left(UNUSED struct Camera *c) { + approach_f32_asymptotic_bool(&sCutsceneVars[0].point[2], 0.f, 0.05f); } -CmdRet CutsceneEnterBowserPlatform0_1(UNUSED struct LevelCamera *c) { - func_8028FD94(1); +/** + * Duplicate of cutscene_mario_dialog(). + */ +CmdRet cutscene_bowser_arena_mario_dialog(UNUSED struct Camera *c) { + cutscene_common_set_dialog_state(1); } -void func_802930C8(UNUSED struct LevelCamera *c) { - func_8028FD94(0); +void cutscene_stop_dialog(UNUSED struct Camera *c) { + cutscene_common_set_dialog_state(0); } -CmdRet CutsceneEnterBowserPlatform0_2(struct LevelCamera *c) { - D_8033B6F0[3].unk4[2] = 430.f; - D_8033B6F0[3].unk1C[1] = gSecondCameraFocus->oMoveAngleYaw - 0x2000; - D_8033B6F0[3].unk1C[0] = 3472; +/** + * Active for the first 5 frames of the cutscene. + * cvar3 is the camera's polar offset from bowser + * cvar2.angle is bowser's move angle + * + * cvar0 is the focus offset from bowser + */ +CmdRet cutscene_bowser_arena_start(struct Camera *c) { + sCutsceneVars[3].point[2] = 430.f; + sCutsceneVars[3].angle[1] = gSecondCameraFocus->oMoveAngleYaw - DEGREES(45); + sCutsceneVars[3].angle[0] = 0xD90; - vec3f_set(D_8033B6F0[0].unk4, 0.f, 120.f, -800.f); - vec3s_set(D_8033B6F0[2].unk1C, gSecondCameraFocus->oMoveAnglePitch, + //! Tricky math: Bowser starts at (0, 307, -1000), with a moveAngle of (0,0,0). A sane person would + //! expect this offset to move the focus to (0, 427, -1800). + //! BUT because offset_rotated() flips the Z direction (to match sm64's coordinate system), this + //! offset actually moves the focus to (0, 427, -200) + vec3f_set(sCutsceneVars[0].point, 0.f, 120.f, -800.f); + vec3s_set(sCutsceneVars[2].angle, gSecondCameraFocus->oMoveAnglePitch, gSecondCameraFocus->oMoveAngleYaw, gSecondCameraFocus->oMoveAngleRoll); - CutsceneEnterBowserPlatform0_5(c); - CutsceneEnterBowserPlatform0_9(c); + // Set the camera's position and focus. + cutscene_bowser_arena_set_pos(c); + cutscene_bowser_arena_set_focus(c); } -CmdRet bowser_fight_intro_dialog(UNUSED struct LevelCamera *c) { +/** + * Create the dialog box depending on which bowser fight mario is in. + */ +CmdRet bowser_fight_intro_dialog(UNUSED struct Camera *c) { s16 dialog; switch (gCurrLevelNum) { @@ -6523,734 +8067,974 @@ CmdRet bowser_fight_intro_dialog(UNUSED struct LevelCamera *c) { create_dialog_box(dialog); } -CmdRet CutsceneEnterBowserPlatform1(struct LevelCamera *c) { - call_cutscene_func_in_time_range(bowser_fight_intro_dialog, c, 0, 0); +/** + * Create the dialog box and wait until it's gone. + */ +CmdRet cutscene_bowser_arena_dialog(struct Camera *c) { + cutscene_event(bowser_fight_intro_dialog, c, 0, 0); if (get_dialog_id() == -1) { - gCutsceneTimer = 0x7FFF; + gCutsceneTimer = CUTSCENE_LOOP; } } -CmdRet CutsceneEnterBowserPlatform2(struct LevelCamera *c) { - func_802930C8(c); +/** + * End the bowser arena cutscene. + */ +CmdRet cutscene_bowser_arena_end(struct Camera *c) { + cutscene_stop_dialog(c); c->cutscene = 0; - init_transitional_movement(c, 20); - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; - sFirstPersonCameraYaw = sMarioStatusForCamera->faceAngle[1] + 0x4000; + transition_next_state(c, 20); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; + sModeOffsetYaw = sMarioCamState->faceAngle[1] + DEGREES(90); + //! This appears to do nothing gSecondCameraFocus->oBowserUnk88 = 2; } -CmdRet CutsceneEnterBowserPlatform0(struct LevelCamera *c) { - set_cutscene_phase_at_frame(2, 0); +/** + * Cutscene that plays when mario enters a bowser fight. + */ +CmdRet cutscene_bowser_arena(struct Camera *c) { + //! This does nothing, but may have been used in development + cutscene_spawn_obj(2, 0); if (gSecondCameraFocus != NULL) { - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_1, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_2, c, 0, 5); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_3, c, 40, 40); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_4, c, 145, 145); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_5, c, 40, -1); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_6, c, 40, 99); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_7, c, 100, -1); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_8, c, 40, 140); - call_cutscene_func_in_time_range(CutsceneEnterBowserPlatform0_9, c, 40, -1); - call_cutscene_func_in_time_range(CutsceneEnterSomething8029041C, c, 60, 60); - call_cutscene_func_in_time_range(CutsceneEnterSomething8029041C, c, 82, 82); - call_cutscene_func_in_time_range(CutsceneEnterSomething8029041C, c, 109, 109); - call_cutscene_func_in_time_range(CutsceneEnterSomething8029041C, c, 127, 127); + cutscene_event(cutscene_bowser_arena_mario_dialog, c, 0, -1); + cutscene_event(cutscene_bowser_arena_start, c, 0, 5); + cutscene_event(cutscene_bowser_area_start_bowser_walking, c, 40, 40); + cutscene_event(cutscene_bowser_area_shake_fov, c, 145, 145); + cutscene_event(cutscene_bowser_arena_set_pos, c, 40, -1); + cutscene_event(cutscene_bowser_arena_pan_left, c, 40, 99); + cutscene_event(cutscene_bowser_arena_adjust_offsets, c, 100, -1); + cutscene_event(cutscene_bowser_arena_focus_sine, c, 40, 140); + cutscene_event(cutscene_bowser_arena_set_focus, c, 40, -1); + cutscene_event(cutscene_shake_explosion, c, 60, 60); + cutscene_event(cutscene_shake_explosion, c, 82, 82); + cutscene_event(cutscene_shake_explosion, c, 109, 109); + cutscene_event(cutscene_shake_explosion, c, 127, 127); } } -CmdRet CutsceneStarSpawn0_1(struct LevelCamera *c) { - func_80290224(c); +CmdRet cutscene_star_spawn_store_info(struct Camera *c) { + store_info_star(c); } -CmdRet CutsceneStarSpawn0_2(struct LevelCamera *c) { - UNUSED f32 sp34; - Vec3f pos; - UNUSED f32 sp24; +/** + * Focus on the top of the star. + */ +CmdRet cutscene_star_spawn_focus_star(struct Camera *c) { + UNUSED f32 hMul; + Vec3f starPos; + UNUSED f32 vMul; if (gCutsceneFocus != NULL) { - object_pos_to_vec3f(pos, gCutsceneFocus); - pos[1] += gCutsceneFocus->hitboxHeight; - approach_vec3f_exponential(c->focus, pos, 0.1f, 0.1f, 0.1f); + object_pos_to_vec3f(starPos, gCutsceneFocus); + starPos[1] += gCutsceneFocus->hitboxHeight; + approach_vec3f_asymptotic(c->focus, starPos, 0.1f, 0.1f, 0.1f); } } -CmdRet CutsceneStarSpawn1_1(struct LevelCamera *c) { - Vec3f sp2C, sp20; +/** + * Use boss fight mode's update function to move the focus back. + */ +CmdRet cutscene_star_spawn_update_boss_fight(struct Camera *c) { + Vec3f pos, focus; - return_boss_fight_camera_yaw(c, sp20, sp2C); - approach_vec3f_exponential(c->focus, sp20, 0.2f, 0.2f, 0.2f); - approach_vec3f_exponential(c->pos, sp2C, 0.2f, 0.2f, 0.2f); + update_boss_fight_camera(c, focus, pos); + approach_vec3f_asymptotic(c->focus, focus, 0.2f, 0.2f, 0.2f); + approach_vec3f_asymptotic(c->pos, pos, 0.2f, 0.2f, 0.2f); } -CmdRet CutsceneStarSpawn1_2(struct LevelCamera *c) { - func_802902A8(c); - init_transitional_movement(c, 15); +/** + * Fly back to the camera's previous pos and focus. + */ +CmdRet cutscene_star_spawn_fly_back(struct Camera *c) { + retrieve_info_star(c); + transition_next_state(c, 15); } -CmdRet CutsceneStarSpawn0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneStarSpawn0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneStarSpawn0_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * Plays when a star spawns (ie from a box). + */ +CmdRet cutscene_star_spawn(struct Camera *c) { + cutscene_event(cutscene_star_spawn_store_info, c, 0, 0); + cutscene_event(cutscene_star_spawn_focus_star, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; - if (gCutsceneActive) { - gCutsceneTimer = 0x7FFF; + if (gObjCutsceneDone) { + // Set the timer to CUTSCENE_LOOP, which start the next shot. + gCutsceneTimer = CUTSCENE_LOOP; } } -CmdRet CutsceneStarSpawn1(struct LevelCamera *c) { - if ((c->currPreset == CAMERA_PRESET_BOSS_FIGHT) && (test_or_set_mario_cam_active(0) == 2)) { - call_cutscene_func_in_time_range(CutsceneStarSpawn1_1, c, 0, -1); +/** + * Move the camera back to mario. + */ +CmdRet cutscene_star_spawn_back(struct Camera *c) { + if ((c->mode == CAMERA_MODE_BOSS_FIGHT) && (set_cam_angle(0) == CAM_ANGLE_LAKITU)) { + cutscene_event(cutscene_star_spawn_update_boss_fight, c, 0, -1); } else { - call_cutscene_func_in_time_range(CutsceneStarSpawn1_2, c, 0, 0); + cutscene_event(cutscene_star_spawn_fly_back, c, 0, 0); } - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneStarSpawn2(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCutsceneTimer = -0x8000; +CmdRet cutscene_star_spawn_end(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; } -CmdRet CutsceneExitWaterfall0_1(struct LevelCamera *c) { +CmdRet cutscene_exit_waterfall_warp(struct Camera *c) { + //! hardcoded position vec3f_set(c->pos, -3899.f, 39.f, -5671.f); } -CmdRet Cutscene80293794(struct LevelCamera *c) { - vec3f_copy(c->focus, sMarioStatusForCamera->pos); - c->focus[1] = c->pos[1] + (sMarioStatusForCamera->pos[1] + 125.f - c->pos[1]) * 0.5f; - approach_vec3f_exponential(c->focus, sMarioStatusForCamera->pos, 0.05f, 0.4f, 0.05f); +/** + * Look at mario, used by cutscenes that play when mario exits a course to castle grounds. + */ +CmdRet cutscene_exit_to_castle_grounds_focus_mario(struct Camera *c) { + vec3f_copy(c->focus, sMarioCamState->pos); + c->focus[1] = c->pos[1] + (sMarioCamState->pos[1] + 125.f - c->pos[1]) * 0.5f; + approach_vec3f_asymptotic(c->focus, sMarioCamState->pos, 0.05f, 0.4f, 0.05f); } -CmdRet CutsceneExitWaterfall0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneExitWaterfall0_1, c, 0, 0); - call_cutscene_func_in_time_range(Cutscene80293794, c, 0, -1); - set_cam_yaw_from_focus_and_pos(c); +/** + * Cutscene that plays when mario leaves CotMC through the waterfall. + */ +CmdRet cutscene_exit_waterfall(struct Camera *c) { + cutscene_event(cutscene_exit_waterfall_warp, c, 0, 0); + cutscene_event(cutscene_exit_to_castle_grounds_focus_mario, c, 0, -1); + update_camera_yaw(c); } -CmdRet CutsceneFallCommon1(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCutsceneTimer = -0x8000; +/** + * End the cutscene, used by cutscenes that play when mario exits a course to castle grounds. + */ +CmdRet cutscene_exit_to_castle_grounds_end(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; - set_cam_yaw_from_focus_and_pos(c); + update_camera_yaw(c); } -CmdRet CutsceneFallToCastleGrounds0_1(struct LevelCamera *c) { +CmdRet cutscene_exit_fall_to_castle_grounds_warp(struct Camera *c) { + //! hardcoded position vec3f_set(c->pos, 5830.f, 32.f, 3985.f); } -CmdRet CutsceneFallToCastleGrounds0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneFallToCastleGrounds0_1, c, 0, 0); - call_cutscene_func_in_time_range(Cutscene80293794, c, 0, -1); - set_cam_yaw_from_focus_and_pos(c); +/** + * Cutscene that plays when mario falls from WMOTR. + */ +CmdRet cutscene_exit_fall_to_castle_grounds(struct Camera *c) { + cutscene_event(cutscene_exit_fall_to_castle_grounds_warp, c, 0, 0); + cutscene_event(cutscene_exit_to_castle_grounds_focus_mario, c, 0, -1); + update_camera_yaw(c); } -CmdRet CutsceneSpecialStarSpawn0_1(struct LevelCamera *c) { - object_pos_to_vec3f(D_8033B6F0[1].unk4, gCutsceneFocus); - func_80290224(c); - D_8033B6F0[2].unk4[2] = D_8033B230.fieldOfView; +/** + * Start the red coin star spawning cutscene. + */ +CmdRet cutscene_red_coin_star_start(struct Camera *c) { + object_pos_to_vec3f(sCutsceneVars[1].point, gCutsceneFocus); + store_info_star(c); + // Store the default fov for after the cutscene + sCutsceneVars[2].point[2] = sFOVState.fov; } -CmdRet CutsceneSpecialStarSpawn0_3(struct LevelCamera *c) { - approach_f32_exponential_bool(&c->focus[0], gCutsceneFocus->oPosX, 0.15f); - approach_f32_exponential_bool(&c->focus[2], gCutsceneFocus->oPosZ, 0.15f); +/** + * Look towards the star's x and z position + */ +CmdRet cutscene_red_coin_star_focus_xz(struct Camera *c) { + approach_f32_asymptotic_bool(&c->focus[0], gCutsceneFocus->oPosX, 0.15f); + approach_f32_asymptotic_bool(&c->focus[2], gCutsceneFocus->oPosZ, 0.15f); } -CmdRet CutsceneSpecialStarSpawn0_4(struct LevelCamera *c) { - approach_f32_exponential_bool(&c->focus[1], gCutsceneFocus->oPosY, 0.1f); +/** + * Look towards the star's y position. Only active before the camera warp. + */ +CmdRet cutscene_red_coin_star_focus_y(struct Camera *c) { + approach_f32_asymptotic_bool(&c->focus[1], gCutsceneFocus->oPosY, 0.1f); } -CmdRet CutsceneSpecialStarSpawn0_5(struct LevelCamera *c) { - c->focus[1] = D_8033B6F0[1].unk4[1] + (gCutsceneFocus->oPosY - D_8033B6F0[1].unk4[1]) * 0.8f; +/** + * Look 80% up towards the star. Only active after the camera warp. + */ +CmdRet cutscene_red_coin_star_look_up_at_star(struct Camera *c) { + c->focus[1] = sCutsceneVars[1].point[1] + (gCutsceneFocus->oPosY - sCutsceneVars[1].point[1]) * 0.8f; } -CmdRet CutsceneSpecialStarSpawn0_2(struct LevelCamera *c) { - f32 sp3C; - s16 sp3A, sp38, sp36; +/** + * Warp the camera near the star's spawn point + */ +CmdRet cutscene_red_coin_star_warp(struct Camera *c) { + f32 dist; + s16 pitch, yaw, posYaw; struct Object *o = gCutsceneFocus; - vec3f_set(D_8033B6F0[1].unk4, o->oHomeX, o->oHomeY, o->oHomeZ); - vec3f_get_dist_and_angle(D_8033B6F0[1].unk4, c->pos, &sp3C, &sp3A, &sp38); - sp36 = calculate_yaw(D_8033B6F0[1].unk4, c->pos); - sp38 = calculate_yaw(D_8033B6F0[1].unk4, sMarioStatusForCamera->pos); + vec3f_set(sCutsceneVars[1].point, o->oHomeX, o->oHomeY, o->oHomeZ); + vec3f_get_dist_and_angle(sCutsceneVars[1].point, c->pos, &dist, &pitch, &yaw); + posYaw = calculate_yaw(sCutsceneVars[1].point, c->pos); + yaw = calculate_yaw(sCutsceneVars[1].point, sMarioCamState->pos); - if (ABS(sp38 - sp36 + 0x4000) < ABS(sp38 - sp36 - 0x4000)) { - sp38 += 0x4000; + if (ABS(yaw - posYaw + DEGREES(90)) < ABS(yaw - posYaw - DEGREES(90))) { + yaw += DEGREES(90); } else { - sp38 -= 0x4000; + yaw -= DEGREES(90); } - vec3f_set_dist_and_angle(D_8033B6F0[1].unk4, c->pos, 400.f, 0x1000, sp38); - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; + vec3f_set_dist_and_angle(sCutsceneVars[1].point, c->pos, 400.f, 0x1000, yaw); + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet CutsceneSpecialStarSpawn0_6(UNUSED struct LevelCamera *c) { - D_8033B230.fieldOfView = 60.f; +/** + * Zoom out while looking at the star. + */ +CmdRet cutscene_red_coin_star_set_fov(UNUSED struct Camera *c) { + sFOVState.fov = 60.f; } -CmdRet CutsceneSpecialStarSpawn0(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_2, c, 30, 30); - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_3, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_4, c, 0, 29); - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_5, c, 30, -1); - call_cutscene_func_in_time_range(CutsceneSpecialStarSpawn0_6, c, 30, -1); +CmdRet cutscene_red_coin_star(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + cutscene_event(cutscene_red_coin_star_start, c, 0, 0); + cutscene_event(cutscene_red_coin_star_warp, c, 30, 30); + cutscene_event(cutscene_red_coin_star_focus_xz, c, 0, -1); + cutscene_event(cutscene_red_coin_star_focus_y, c, 0, 29); + cutscene_event(cutscene_red_coin_star_look_up_at_star, c, 30, -1); + cutscene_event(cutscene_red_coin_star_set_fov, c, 30, -1); - if (gCutsceneActive) { - gCutsceneTimer = 0x7FFF; + if (gObjCutsceneDone) { + // Set the timer to CUTSCENE_LOOP, which start the next shot. + gCutsceneTimer = CUTSCENE_LOOP; } } -CmdRet CutsceneSpecialStarSpawn1(struct LevelCamera *c) { - func_802902A8(c); - gCutsceneTimer = -0x8000; +/** + * End the red coin star spawning cutscene + */ +CmdRet cutscene_red_coin_star_end(struct Camera *c) { + retrieve_info_star(c); + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; - D_8033B230.fieldOfView = D_8033B6F0[2].unk4[2]; + // Restore the default fov + sFOVState.fov = sCutsceneVars[2].point[2]; } -void func_80293DE8(struct LevelCamera *a, f32 b, s16 c, s16 d, s16 e) { - UNUSED f32 sp44; - f32 sp40; - s16 sp3E, sp3C; - f32 sp38; - s16 sp36, sp34; - f32 sp30; - s16 sp2E, sp2C; - UNUSED f32 sp28, sp24; - - vec3f_get_dist_and_angle(D_8033B6F0[3].unk4, a->pos, &sp40, &sp3E, &sp3C); - - if ((sp40 > 8000.f) && (a->cutscene == CUTSCENE_PREPARE_CANNON)) { - sp40 = b * 4.f; - sp3E = c; - vec3f_copy(D_8033B6F0[0].unk4, D_8033B6F0[3].unk4); - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * Moves the camera towards the cutscene's focus, stored in sCutsceneVars[3].point + * + * sCutsceneVars[3].point is used as the target point + * sCutsceneVars[0].point is used as the current camera focus during the transition + * + * @param rotPitch constant pitch offset to add to the camera's focus + * @param rotYaw constant yaw offset to add to the camera's focus + */ +void cutscene_goto_cvar_pos(struct Camera *c, f32 goalDist, s16 goalPitch, s16 rotPitch, s16 rotYaw) { + UNUSED f32 unused1; + f32 nextDist; + s16 nextPitch, nextYaw; + // The next 2 polar coord points are only used in CUTSCENE_PREPARE_CANNON + f32 cannonDist; + s16 cannonPitch, cannonYaw; + f32 curDist; + s16 curPitch, curYaw; + UNUSED f32 unused2, unused3; + vec3f_get_dist_and_angle(sCutsceneVars[3].point, c->pos, &nextDist, &nextPitch, &nextYaw); + // If over 8000 units away from the cannon, just teleport there + if ((nextDist > 8000.f) && (c->cutscene == CUTSCENE_PREPARE_CANNON)) { + nextDist = goalDist * 4.f; + nextPitch = goalPitch; + vec3f_copy(sCutsceneVars[0].point, sCutsceneVars[3].point); + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; if (gCurrLevelNum == LEVEL_TTM) { - sp3C = atan2s(D_8033B6F0[3].unk4[2] - a->zFocus, D_8033B6F0[3].unk4[0] - a->xFocus); + nextYaw = atan2s(sCutsceneVars[3].point[2] - c->areaCenZ, + sCutsceneVars[3].point[0] - c->areaCenX); } } else { - if (a->cutscene == CUTSCENE_PREPARE_CANNON) { - vec3f_get_dist_and_angle(a->pos, D_8033B6F0[0].unk4, &sp30, &sp2E, &sp2C); - vec3f_get_dist_and_angle(a->pos, D_8033B6F0[3].unk4, &sp38, &sp36, &sp34); - approach_f32_exponential_bool(&sp30, sp38, 0.1f); - approach_s16_exponential_bool(&sp2E, sp36, 15); - approach_s16_exponential_bool(&sp2C, sp34, 15); - vec3f_set_dist_and_angle(a->pos, D_8033B6F0[0].unk4, sp30, sp2E, sp2C); + if (c->cutscene == CUTSCENE_PREPARE_CANNON) { + vec3f_get_dist_and_angle(c->pos, sCutsceneVars[0].point, &curDist, &curPitch, &curYaw); + vec3f_get_dist_and_angle(c->pos, sCutsceneVars[3].point, &cannonDist, &cannonPitch, &cannonYaw); + approach_f32_asymptotic_bool(&curDist, cannonDist, 0.1f); + approach_s16_asymptotic_bool(&curPitch, cannonPitch, 15); + approach_s16_asymptotic_bool(&curYaw, cannonYaw, 15); + // Move the current focus, sCutsceneVars[0].point, in the direction towards the cannon + vec3f_set_dist_and_angle(c->pos, sCutsceneVars[0].point, curDist, curPitch, curYaw); } else { - approach_vec3f_exponential(D_8033B6F0[0].unk4, D_8033B6F0[3].unk4, 0.1f, 0.1f, 0.1f); + approach_vec3f_asymptotic(sCutsceneVars[0].point, sCutsceneVars[3].point, 0.1f, 0.1f, 0.1f); } } - approach_f32_exponential_bool(&sp40, b, 0.05f); - approach_s16_exponential_bool(&sp3E, c, 0x20); - vec3f_set_dist_and_angle(D_8033B6F0[3].unk4, a->pos, sp40, sp3E, sp3C); - vec3f_copy(a->focus, D_8033B6F0[0].unk4); - rotate_camera(a, d, e); - vec3f_get_dist_and_angle(a->pos, a->focus, &sp40, &sp3E, &sp3C); + approach_f32_asymptotic_bool(&nextDist, goalDist, 0.05f); + approach_s16_asymptotic_bool(&nextPitch, goalPitch, 0x20); - if (sp3E < -0x3000) { - sp3E = -0x3000; + vec3f_set_dist_and_angle(sCutsceneVars[3].point, c->pos, nextDist, nextPitch, nextYaw); + vec3f_copy(c->focus, sCutsceneVars[0].point); + + // Apply the constant rotation given + pan_camera(c, rotPitch, rotYaw); + vec3f_get_dist_and_angle(c->pos, c->focus, &nextDist, &nextPitch, &nextYaw); + + if (nextPitch < -0x3000) { + nextPitch = -0x3000; } - if (sp3E > 0x3000) { - sp3E = 0x3000; + if (nextPitch > 0x3000) { + nextPitch = 0x3000; } - vec3f_set_dist_and_angle(a->pos, a->focus, sp40, sp3E, sp3C); + vec3f_set_dist_and_angle(c->pos, c->focus, nextDist, nextPitch, nextYaw); } -CmdRet CutscenePrepareCannon0_1(struct LevelCamera *c) { - func_80290144(c); - vec3f_copy(D_8033B6F0[0].unk4, c->focus); - D_8033B6F0[2].unk4[0] = 30.f; - object_pos_to_vec3f(D_8033B6F0[3].unk4, gCutsceneFocus); - vec3s_set(D_8033B6F0[5].unk1C, 0, 0, 0); +/** + * Store the camera's pos and focus, and copy the cannon's position to cvars. + */ +CmdRet cutscene_prepare_cannon_start(struct Camera *c) { + store_info_cannon(c); + vec3f_copy(sCutsceneVars[0].point, c->focus); + sCutsceneVars[2].point[0] = 30.f; + // Store the cannon door's position in sCutsceneVars[3]'s point + object_pos_to_vec3f(sCutsceneVars[3].point, gCutsceneFocus); + vec3s_set(sCutsceneVars[5].angle, 0, 0, 0); } -CmdRet CutscenePrepareCannon0_2(struct LevelCamera *c) { - func_80293DE8(c, 300.f, 0x2000, 0, D_8033B6F0[5].unk1C[1]); - camera_approach_s16_symmetric_bool(&D_8033B6F0[5].unk1C[1], 0x400, 17); - set_spline_values(1); +/** + * Fly towards the cannon door. + */ +CmdRet cutscene_prepare_cannon_fly_to_cannon(struct Camera *c) { + cutscene_goto_cvar_pos(c, 300.f, 0x2000, 0, sCutsceneVars[5].angle[1]); + camera_approach_s16_symmetric_bool(&sCutsceneVars[5].angle[1], 0x400, 17); + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -void func_802941CC(f32 *a, f32 b) { - f32 sp24 = ABS(b - *a) / D_8033B6F0[2].unk4[0]; - camera_approach_f32_symmetric_bool(a, b, sp24); +/** + * Used in the cannon opening cutscene to fly back to the camera's last position and focus + */ +void cannon_approach_prev(f32 *value, f32 target) { + f32 inc = ABS(target - *value) / sCutsceneVars[2].point[0]; + camera_approach_f32_symmetric_bool(value, target, inc); } -CmdRet CutscenePrepareCannon0_3(struct LevelCamera *c) { - f32 sp1C = calc_abs_dist(c->pos, D_8033B4B8.pos); +/** + * Fly or warp back to the previous pos and focus, stored in sCameraStoreCutscene. + */ +CmdRet cutscene_prepare_cannon_fly_back(struct Camera *c) { + f32 distToPrevPos = calc_abs_dist(c->pos, sCameraStoreCutscene.pos); - if (sp1C < 8000.f) { - func_802941CC(&c->pos[0], D_8033B4B8.pos[0]); - func_802941CC(&c->pos[1], D_8033B4B8.pos[1]); - func_802941CC(&c->pos[2], D_8033B4B8.pos[2]); - func_802941CC(&c->focus[0], D_8033B4B8.focus[0]); - func_802941CC(&c->focus[1], D_8033B4B8.focus[1]); - func_802941CC(&c->focus[2], D_8033B4B8.focus[2]); + if (distToPrevPos < 8000.f) { + cannon_approach_prev(&c->pos[0], sCameraStoreCutscene.pos[0]); + cannon_approach_prev(&c->pos[1], sCameraStoreCutscene.pos[1]); + cannon_approach_prev(&c->pos[2], sCameraStoreCutscene.pos[2]); + cannon_approach_prev(&c->focus[0], sCameraStoreCutscene.focus[0]); + cannon_approach_prev(&c->focus[1], sCameraStoreCutscene.focus[1]); + cannon_approach_prev(&c->focus[2], sCameraStoreCutscene.focus[2]); } else { - vec3f_copy(c->focus, D_8033B4B8.focus); - vec3f_copy(c->pos, D_8033B4B8.pos); - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; + // If too far away, just warp back + vec3f_copy(c->focus, sCameraStoreCutscene.focus); + vec3f_copy(c->pos, sCameraStoreCutscene.pos); + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } - if (D_8033B6F0[2].unk4[0] > 1.f) { - D_8033B6F0[2].unk4[0] -= 1.f; + if (sCutsceneVars[2].point[0] > 1.f) { + sCutsceneVars[2].point[0] -= 1.f; } } -CmdRet CutscenePrepareCannon0(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - call_cutscene_func_in_time_range(CutscenePrepareCannon0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutscenePrepareCannon0_2, c, 0, 140); - call_cutscene_func_in_time_range(CutscenePrepareCannon0_3, c, 141, -1); +/** + * Cutscene that plays when the cannon is opened. + */ +CmdRet cutscene_prepare_cannon(struct Camera *c) { + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + cutscene_event(cutscene_prepare_cannon_start, c, 0, 0); + cutscene_event(cutscene_prepare_cannon_fly_to_cannon, c, 0, 140); + cutscene_event(cutscene_prepare_cannon_fly_back, c, 141, -1); } -CmdRet CutscenePrepareCannon1(struct LevelCamera *c) { - gCutsceneTimer = -0x8000; +/** + * Stop the cannon opening cutscene. + */ +CmdRet cutscene_prepare_cannon_end(struct Camera *c) { + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; - func_802901B4(c); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + retrieve_info_cannon(c); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -void func_802944A8(struct LevelCamera *c) { - f32 sp24; - s16 sp22, sp20; +/** + * Moves the camera to mario's side when mario starts ACT_WATER_DEATH + * Note that ACT_WATER_DEATH only starts when mario gets hit by an enemy under water. It does not start + * when mario drowns. + */ +void water_death_move_to_mario_side(struct Camera *c) { + f32 dist; + s16 pitch, yaw; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp24, &sp22, &sp20); - approach_s16_exponential_bool(&sp20, (sMarioStatusForCamera->faceAngle[1] - 0x3000), 8); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp24, sp22, sp20); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_s16_asymptotic_bool(&yaw, (sMarioCamState->faceAngle[1] - 0x3000), 8); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -void func_80294538(struct LevelCamera *c) { - func_80293DE8(c, 400.f, 0x1000, 0x300, 0); +/** + * Unnecessary, only used in cutscene_death_standing_goto_mario() + */ +void death_goto_mario(struct Camera *c) { + cutscene_goto_cvar_pos(c, 400.f, 0x1000, 0x300, 0); } -CmdRet CutsceneDeath1_1(struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[0].unk4, c->focus); - vec3f_copy(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos); - D_8033B6F0[3].unk4[1] += 70.f; +CmdRet cutscene_death_standing_start(struct Camera *c) { + vec3f_copy(sCutsceneVars[0].point, c->focus); + vec3f_copy(sCutsceneVars[3].point, sMarioCamState->pos); + sCutsceneVars[3].point[1] += 70.f; } -CmdRet CutsceneDeath1_2(struct LevelCamera *c) { - func_80294538(c); - set_spline_values(4); +/** + * Fly to mario and turn on handheld shake. + */ +CmdRet cutscene_death_standing_goto_mario(struct Camera *c) { + death_goto_mario(c); + set_handheld_shake(HAND_CAM_SHAKE_HIGH); } -CmdRet CutsceneDeath1(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneDeath1_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneDeath1_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * Cutscene that plays when mario dies while standing. + */ +CmdRet cutscene_death_standing(struct Camera *c) { + cutscene_event(cutscene_death_standing_start, c, 0, 0); + cutscene_event(cutscene_death_standing_goto_mario, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet CutsceneDeath2_1(struct LevelCamera *c) { - Vec3f sp1C = { 0, 40.f, -60.f }; +CmdRet cutscene_death_stomach_start(struct Camera *c) { + Vec3f offset = { 0, 40.f, -60.f }; - set_pos_from_face_angle_and_vec3f(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos, sp1C, - sMarioStatusForCamera->faceAngle); - vec3f_copy(D_8033B6F0[0].unk4, c->focus); + offset_rotated(sCutsceneVars[3].point, sMarioCamState->pos, offset, sMarioCamState->faceAngle); + vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet CutsceneDeath2_2(struct LevelCamera *c) { - func_80293DE8(c, 400.f, 0x1800, 0, -0x400); +CmdRet cutscene_death_stomach_goto_mario(struct Camera *c) { + cutscene_goto_cvar_pos(c, 400.f, 0x1800, 0, -0x400); } -static void unused_80294748(struct LevelCamera *c) { - func_802944A8(c); +/** + * Ah, yes + */ +static void unused_water_death_move_to_side_of_mario(struct Camera *c) { + water_death_move_to_mario_side(c); } -CmdRet CutsceneDeath2(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneDeath2_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneDeath2_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - set_spline_values(1); +/** + * Cutscene that plays when mario dies on his stomach. + */ +CmdRet cutscene_death_stomach(struct Camera *c) { + cutscene_event(cutscene_death_stomach_start, c, 0, 0); + cutscene_event(cutscene_death_stomach_goto_mario, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet CutsceneBBHDeath0_1(struct LevelCamera *c) { - Vec3f sp1C = { 0, 40.f, 60.f }; +CmdRet cutscene_bbh_death_start(struct Camera *c) { + Vec3f dir = { 0, 40.f, 60.f }; - set_pos_from_face_angle_and_vec3f(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos, sp1C, - sMarioStatusForCamera->faceAngle); - vec3f_copy(D_8033B6F0[0].unk4, c->focus); + offset_rotated(sCutsceneVars[3].point, sMarioCamState->pos, dir, sMarioCamState->faceAngle); + vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet CutsceneBBHDeath0_2(struct LevelCamera *c) { - func_80293DE8(c, 400.f, 0x1800, 0, 0x400); +CmdRet cutscene_bbh_death_goto_mario(struct Camera *c) { + cutscene_goto_cvar_pos(c, 400.f, 0x1800, 0, 0x400); } -CmdRet CutsceneBBHDeath0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneBBHDeath0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneBBHDeath0_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - set_spline_values(1); +/** + * Cutscene that plays when mario dies in BBH. + */ +CmdRet cutscene_bbh_death(struct Camera *c) { + cutscene_event(cutscene_bbh_death_start, c, 0, 0); + cutscene_event(cutscene_bbh_death_goto_mario, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet CutsceneQuicksandDeath0_1(struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[0].unk4, c->focus); +/** + * Copy the camera's focus to cvar0 + */ +CmdRet cutscene_quicksand_death_start(struct Camera *c) { + vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet CutsceneQuicksandDeath0_2(struct LevelCamera *c) { - func_80293DE8(c, 400.f, 0x2800, 0x200, 0); +/** + * Fly closer to mario. In WATER_DEATH, move to mario's side. + */ +CmdRet cutscene_quicksand_death_goto_mario(struct Camera *c) { + cutscene_goto_cvar_pos(c, 400.f, 0x2800, 0x200, 0); if (c->cutscene == CUTSCENE_WATER_DEATH) { - func_802944A8(c); + water_death_move_to_mario_side(c); } } -CmdRet CutsceneQuicksandDeath0(struct LevelCamera *c) { - D_8033B6F0[3].unk4[0] = sMarioStatusForCamera->pos[0]; - D_8033B6F0[3].unk4[1] = sMarioStatusForCamera->pos[1] + 20.f; - D_8033B6F0[3].unk4[2] = sMarioStatusForCamera->pos[2]; +/** + * Cutscene that plays when mario dies in quicksand. + */ +CmdRet cutscene_quicksand_death(struct Camera *c) { + sCutsceneVars[3].point[0] = sMarioCamState->pos[0]; + sCutsceneVars[3].point[1] = sMarioCamState->pos[1] + 20.f; + sCutsceneVars[3].point[2] = sMarioCamState->pos[2]; - call_cutscene_func_in_time_range(CutsceneQuicksandDeath0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneQuicksandDeath0_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - set_spline_values(4); + cutscene_event(cutscene_quicksand_death_start, c, 0, 0); + cutscene_event(cutscene_quicksand_death_goto_mario, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + set_handheld_shake(HAND_CAM_SHAKE_HIGH); } -CmdRet Cutscene1ATodo0_3(UNUSED struct LevelCamera *c) { - Vec3f sp2C; - Vec3f sp20 = { 0, 20.f, 120.f }; +/** + * Fly away from mario near the end of the cutscene. + */ +CmdRet cutscene_suffocation_fly_away(UNUSED struct Camera *c) { + Vec3f target; + Vec3f offset = { 0, 20.f, 120.f }; - set_pos_from_face_angle_and_vec3f(sp2C, sMarioStatusForCamera->pos, sp20, - sMarioStatusForCamera->faceAngle); - approach_vec3f_exponential(D_8033B6F0[3].unk4, sp2C, 0.1f, 0.1f, 0.1f); + offset_rotated(target, sMarioCamState->pos, offset, sMarioCamState->faceAngle); + approach_vec3f_asymptotic(sCutsceneVars[3].point, target, 0.1f, 0.1f, 0.1f); } -CmdRet Cutscene1ATodo0_2(struct LevelCamera *c) { - UNUSED f32 sp34; - f32 sp30; - UNUSED f32 sp2C; +/** + * Keep lakitu above the gas level. + */ +CmdRet cutscene_suffocation_stay_above_gas(struct Camera *c) { + UNUSED f32 unused1; + f32 gasLevel; + UNUSED f32 unused2; - func_80293DE8(c, 400.f, 0x2800, 0x200, 0); - sp30 = find_poison_gas_level(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[2]); + cutscene_goto_cvar_pos(c, 400.f, 0x2800, 0x200, 0); + gasLevel = find_poison_gas_level(sMarioCamState->pos[0], sMarioCamState->pos[2]); - if (sp30 != -11000.f) { - if ((sp30 += 130.f) > c->pos[1]) { - c->pos[1] = sp30; + if (gasLevel != -11000.f) { + if ((gasLevel += 130.f) > c->pos[1]) { + c->pos[1] = gasLevel; } } } -CmdRet Cutscene1ATodo0_1(struct LevelCamera *c) { - f32 sp24; - s16 sp22, sp20; +/** + * Quickly rotate around mario. + */ +CmdRet cutscene_suffocation_rotate(struct Camera *c) { + f32 dist; + s16 pitch, yaw; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp24, &sp22, &sp20); - sp20 += 0x100; - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp24, sp22, sp20); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + yaw += 0x100; + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet Cutscene1ATodo0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneDeath2_1, c, 0, 0); - call_cutscene_func_in_time_range(Cutscene1ATodo0_1, c, 0, -1); - call_cutscene_func_in_time_range(Cutscene1ATodo0_2, c, 0, -1); - call_cutscene_func_in_time_range(Cutscene1ATodo0_3, c, 50, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - set_spline_values(4); +/** + * Cutscene that plays when mario dies from suffocation (ie due to HMC gas). + */ +CmdRet cutscene_suffocation(struct Camera *c) { + cutscene_event(cutscene_death_stomach_start, c, 0, 0); + cutscene_event(cutscene_suffocation_rotate, c, 0, -1); + cutscene_event(cutscene_suffocation_stay_above_gas, c, 0, -1); + cutscene_event(cutscene_suffocation_fly_away, c, 50, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + set_handheld_shake(HAND_CAM_SHAKE_HIGH); } -CmdRet CutsceneEnterPool0_1(struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos); +CmdRet cutscene_enter_pool_start(struct Camera *c) { + vec3f_copy(sCutsceneVars[3].point, sMarioCamState->pos); if (gCurrLevelNum == LEVEL_CASTLE) { // entering HMC - vec3f_set(D_8033B6F0[3].unk4, 2485.f, -1589.f, -2659.f); + vec3f_set(sCutsceneVars[3].point, 2485.f, -1589.f, -2659.f); } if (gCurrLevelNum == LEVEL_HMC) { // entering CotMC - vec3f_set(D_8033B6F0[3].unk4, 3350.f, -4589.f, 4800.f); + vec3f_set(sCutsceneVars[3].point, 3350.f, -4589.f, 4800.f); } - vec3f_copy(D_8033B6F0[0].unk4, c->focus); + vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet CutsceneEnterPool0_2(struct LevelCamera *c) { +CmdRet cutscene_enter_pool_loop(struct Camera *c) { UNUSED u32 pad[2]; - func_80293DE8(c, 1200.f, 0x2000, 0x200, 0); + cutscene_goto_cvar_pos(c, 1200.f, 0x2000, 0x200, 0); } -CmdRet CutsceneEnterPool0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneEnterPool0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneEnterPool0_2, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +CmdRet cutscene_enter_pool(struct Camera *c) { + cutscene_event(cutscene_enter_pool_start, c, 0, 0); + cutscene_event(cutscene_enter_pool_loop, c, 0, -1); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet Cutscene26Todo1_1(struct LevelCamera *c) { - func_8028FEDC(c); - func_80290144(c); +/** + * Store the camera focus in cvar1. + * Store the area's center position (which happens to be the pyramid, in SSL) in cvar3. + */ +CmdRet cutscene_pyramid_top_explode_start(struct Camera *c) { + reset_pan_distance(c); + store_info_cannon(c); - vec3f_copy(D_8033B6F0[1].unk4, c->focus); - vec3f_set(D_8033B6F0[3].unk4, c->xFocus, 1280.f, c->zFocus); + vec3f_copy(sCutsceneVars[1].point, c->focus); + vec3f_set(sCutsceneVars[3].point, c->areaCenX, 1280.f, c->areaCenZ); } -CmdRet Cutscene26Todo1_5(UNUSED struct LevelCamera *c) { - set_fov_function(10); +/** + * Zoom in on the pyramid. + */ +CmdRet cutscene_pyramid_top_explode_zoom_in(UNUSED struct Camera *c) { + set_fov_function(CAM_FOV_APP_30); } -CmdRet Cutscene26Todo1_2(struct LevelCamera *c) { - approach_vec3f_exponential(c->focus, D_8033B6F0[3].unk4, 0.02f, 0.02f, 0.02f); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * Look at the pyramid top. + */ +CmdRet cutscene_pyramid_top_explode_focus(struct Camera *c) { + approach_vec3f_asymptotic(c->focus, sCutsceneVars[3].point, 0.02f, 0.02f, 0.02f); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet Cutscene26Todo1_3(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +/** + * Store the old pos and focus, then warp to the pyramid top. + */ +CmdRet cutscene_pyramid_top_explode_warp(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - set_fov_function(2); - D_8033B230.fieldOfView = 45.f; + set_fov_function(CAM_FOV_DEFAULT); + sFOVState.fov = 45.f; - vec3f_copy(D_8033B6F0[4].unk4, c->pos); - vec3f_copy(D_8033B6F0[5].unk4, c->focus); - vec3f_copy(c->focus, D_8033B6F0[3].unk4); + vec3f_copy(sCutsceneVars[4].point, c->pos); + vec3f_copy(sCutsceneVars[5].point, c->focus); + vec3f_copy(c->focus, sCutsceneVars[3].point); - vec3f_get_dist_and_angle(D_8033B6F0[3].unk4, sMarioStatusForCamera[0].pos, &sp20, &sp26, &sp24); - vec3f_set_dist_and_angle(D_8033B6F0[3].unk4, c->pos, 2000.f, 0, sp24); + vec3f_get_dist_and_angle(sCutsceneVars[3].point, sMarioCamState[0].pos, &dist, &pitch, &yaw); + vec3f_set_dist_and_angle(sCutsceneVars[3].point, c->pos, 2000.f, 0, yaw); c->pos[1] += 500.f; } -CmdRet Cutscene26Todo1_4(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +/** + * Close up view of the spinning pyramid top as it rises. + */ +CmdRet cutscene_pyramid_top_explode_closeup(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - vec3f_get_dist_and_angle(D_8033B6F0[3].unk4, c->pos, &sp20, &sp26, &sp24); - approach_f32_exponential_bool(&sp20, 2000.f, 0.1f); - vec3f_set_dist_and_angle(D_8033B6F0[3].unk4, c->pos, sp20, sp26, sp24); + vec3f_get_dist_and_angle(sCutsceneVars[3].point, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 2000.f, 0.1f); + vec3f_set_dist_and_angle(sCutsceneVars[3].point, c->pos, dist, pitch, yaw); c->focus[1] += 4.f; c->pos[1] -= 5.f; - D_8033B230.fieldOfView = 45.f; - set_spline_values(1); + sFOVState.fov = 45.f; + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet Cutscene26Todo1_7(UNUSED struct LevelCamera *c) { - set_camera_shake_2(8); +/** + * Shake the camera during the closeup. + */ +CmdRet cutscene_pyramid_top_explode_cam_shake(UNUSED struct Camera *c) { + set_environmental_camera_shake(SHAKE_ENV_PYRAMID_EXPLODE); } -CmdRet Cutscene26Todo1_6(struct LevelCamera *c) { +/** + * Warp back to the old position, and start a heavy camera shake. + */ +CmdRet cutscene_pyramid_top_explode_warp_back(struct Camera *c) { UNUSED u32 pad[2]; - vec3f_copy(c->pos, D_8033B6F0[4].unk4); - vec3f_copy(c->focus, D_8033B6F0[5].unk4); - set_camera_shake_2(SHAKE_2_UNKNOWN_3); + vec3f_copy(c->pos, sCutsceneVars[4].point); + vec3f_copy(c->focus, sCutsceneVars[5].point); + set_environmental_camera_shake(SHAKE_ENV_BOWSER_JUMP); } -CmdRet Cutscene26Todo1(struct LevelCamera *c) { - call_cutscene_func_in_time_range(Cutscene26Todo1_1, c, 0, 0); - call_cutscene_func_in_time_range(Cutscene26Todo1_2, c, 0, 30); - call_cutscene_func_in_time_range(Cutscene26Todo1_3, c, 31, 31); - call_cutscene_func_in_time_range(Cutscene26Todo1_4, c, 31, 139); - call_cutscene_func_in_time_range(Cutscene26Todo1_5, c, 23, 23); - call_cutscene_func_in_time_range(Cutscene26Todo1_6, c, 140, 140); - call_cutscene_func_in_time_range(Cutscene26Todo1_7, c, 31, 139); +/** + * An unused cutscene for when the pyramid explodes. + */ +CmdRet cutscene_pyramid_top_explode(struct Camera *c) { + cutscene_event(cutscene_pyramid_top_explode_start, c, 0, 0); + cutscene_event(cutscene_pyramid_top_explode_focus, c, 0, 30); + cutscene_event(cutscene_pyramid_top_explode_warp, c, 31, 31); + cutscene_event(cutscene_pyramid_top_explode_closeup, c, 31, 139); + cutscene_event(cutscene_pyramid_top_explode_zoom_in, c, 23, 23); + cutscene_event(cutscene_pyramid_top_explode_warp_back, c, 140, 140); + cutscene_event(cutscene_pyramid_top_explode_cam_shake, c, 31, 139); } -CmdRet Cutscene26Todo2(struct LevelCamera *c) { - func_802930C8(c); - func_8028FAE0(c); - init_transitional_movement(c, 30); +/** + * End the pyramid top explosion cutscene. + */ +CmdRet cutscene_pyramid_top_explode_end(struct Camera *c) { + cutscene_stop_dialog(c); + stop_cutscene_and_retrieve_stored_info(c); + // Move the camera back to mario + transition_next_state(c, 30); } -CmdRet CutsceneEnterPyramidTop0_1(struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[0].unk4, c->focus); - vec3f_set(D_8033B6F0[3].unk4, c->xFocus, 1280.f, c->zFocus); +/** + * Store the camera focus in cvar0, and store the top of the pyramid in cvar3. + */ +CmdRet cutscene_enter_pyramid_top_start(struct Camera *c) { + vec3f_copy(sCutsceneVars[0].point, c->focus); + vec3f_set(sCutsceneVars[3].point, c->areaCenX, 1280.f, c->areaCenZ); } -CmdRet CutsceneEnterPyramidTop0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneEnterPyramidTop0_1, c, 0, 0); - func_80293DE8(c, 200.f, 0x3000, 0, 0); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - set_spline_values(1); +/** + * Cutscene that plays when mario enters the top of the pyramid. + */ +CmdRet cutscene_enter_pyramid_top(struct Camera *c) { + cutscene_event(cutscene_enter_pyramid_top_start, c, 0, 0); + // Move to cvar3 + cutscene_goto_cvar_pos(c, 200.f, 0x3000, 0, 0); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); - if (sMarioStatusForCamera->pos[1] > 1250.f) { - CutsceneFallCommon1(c); + if (sMarioCamState->pos[1] > 1250.f) { + // End the cutscene early if mario ledge-grabbed. + // This only works because of the janky way that ledge-grabbing is implemented. + cutscene_exit_to_castle_grounds_end(c); } } -static void unused_8029538C(struct LevelCamera *c) { - f32 sp24; +static void unused_cutscene_goto_cvar(struct Camera *c) { + f32 dist; - sp24 = calc_abs_dist(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos); - sp24 = calc_abs_dist(D_8033B6F0[9].unk4, sMarioStatusForCamera->pos) + 200.f; - func_80293DE8(c, sp24, 0x1000, 0x300, 0); + dist = calc_abs_dist(sCutsceneVars[3].point, sMarioCamState->pos); + dist = calc_abs_dist(sCutsceneVars[9].point, sMarioCamState->pos) + 200.f; + cutscene_goto_cvar_pos(c, dist, 0x1000, 0x300, 0); } -CmdRet CutsceneDialog0_1(struct LevelCamera *c) { - UNUSED f32 sp1C; - UNUSED s16 sp1A; - s16 sp18; +/** + * cvar8 is mario's position and faceAngle + * + * cvar9.point is gCutsceneFocus's position + * cvar9.angle[1] is the yaw between mario and the gCutsceneFocus + */ +CmdRet cutscene_dialog_start(struct Camera *c) { + UNUSED f32 unused1; + UNUSED s16 unused2; + s16 yaw; - func_80290564(c); - set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_UNKNOWN_2); + + cutscene_soften_music(c); + set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); #ifndef VERSION_JP - if (c->currPreset == CAMERA_PRESET_BOSS_FIGHT) { - vec3f_copy(D_8033B4B8.focus, c->focus); - vec3f_copy(D_8033B4B8.pos, c->pos); + if (c->mode == CAMERA_MODE_BOSS_FIGHT) { + vec3f_copy(sCameraStoreCutscene.focus, c->focus); + vec3f_copy(sCameraStoreCutscene.pos, c->pos); } else { #endif - func_80290224(c); + store_info_star(c); #ifndef VERSION_JP } #endif - D_8033B6F0[8].unk1C[0] = 0; - vec3f_copy(D_8033B6F0[8].unk4, sMarioStatusForCamera->pos); - D_8033B6F0[8].unk4[1] += 125.f; - object_pos_to_vec3f(D_8033B6F0[9].unk4, gCutsceneFocus); - D_8033B6F0[9].unk4[1] += gCutsceneFocus->hitboxHeight + 200.f; - D_8033B6F0[9].unk1C[1] = calculate_yaw(D_8033B6F0[8].unk4, D_8033B6F0[9].unk4); + // Store mario's position and faceAngle + sCutsceneVars[8].angle[0] = 0; + vec3f_copy(sCutsceneVars[8].point, sMarioCamState->pos); + sCutsceneVars[8].point[1] += 125.f; - sp18 = calculate_yaw(sMarioStatusForCamera->pos, gCameraStatus.camFocAndPosCurrAndGoal[1]); - if ((sp18 - D_8033B6F0[9].unk1C[1]) & 0x8000) { - D_8033B6F0[9].unk1C[1] -= 0x6000; + // Store gCutsceneFocus's position and yaw + object_pos_to_vec3f(sCutsceneVars[9].point, gCutsceneFocus); + sCutsceneVars[9].point[1] += gCutsceneFocus->hitboxHeight + 200.f; + sCutsceneVars[9].angle[1] = calculate_yaw(sCutsceneVars[8].point, sCutsceneVars[9].point); + + yaw = calculate_yaw(sMarioCamState->pos, gLakituState.curPos); + if ((yaw - sCutsceneVars[9].angle[1]) & 0x8000) { + sCutsceneVars[9].angle[1] -= 0x6000; } else { - D_8033B6F0[9].unk1C[1] += 0x6000; + sCutsceneVars[9].angle[1] += 0x6000; } } -CmdRet CutsceneDialog0_2(struct LevelCamera *c) { - f32 sp4C; - s16 sp4A, sp48; - Vec3f sp3C, sp30; +/** + * Move closer to mario and the object, adjusting to their difference in height. + * The camera's generally ends up looking over mario's shoulder. + */ +CmdRet cutscene_dialog_move_mario_shoulder(struct Camera *c) { + f32 dist; + s16 pitch, yaw; + Vec3f focus, pos; - scale_along_line(sp3C, D_8033B6F0[9].unk4, sMarioStatusForCamera->pos, 0.7f); - vec3f_get_dist_and_angle(c->pos, sp3C, &sp4C, &sp4A, &sp48); - sp4A = calculate_verticle_angle(c->pos, D_8033B6F0[9].unk4); - vec3f_set_dist_and_angle(c->pos, sp30, sp4C, sp4A, sp48); - sp3C[1] = sp3C[1] + (D_8033B6F0[9].unk4[1] - sp3C[1]) * 0.1f; - approach_vec3f_exponential(c->focus, sp3C, 0.2f, 0.2f, 0.2f); - vec3f_copy(sp30, c->pos); - sp30[1] = D_8033B6F0[8].unk4[1]; - vec3f_get_dist_and_angle(D_8033B6F0[8].unk4, sp30, &sp4C, &sp4A, &sp48); - approach_s16_exponential_bool(&sp48, D_8033B6F0[9].unk1C[1], 0x10); - approach_f32_exponential_bool(&sp4C, 180.f, 0.05f); - vec3f_set_dist_and_angle(D_8033B6F0[8].unk4, sp30, sp4C, sp4A, sp48); - sp30[1] = D_8033B6F0[8].unk4[1] - + sins(calculate_verticle_angle(D_8033B6F0[9].unk4, D_8033B6F0[8].unk4)) * 100.f; - approach_f32_exponential_bool(&c->pos[1], sp30[1], 0.05f); - c->pos[0] = sp30[0]; - c->pos[2] = sp30[2]; + scale_along_line(focus, sCutsceneVars[9].point, sMarioCamState->pos, 0.7f); + vec3f_get_dist_and_angle(c->pos, focus, &dist, &pitch, &yaw); + pitch = calculate_pitch(c->pos, sCutsceneVars[9].point); + vec3f_set_dist_and_angle(c->pos, pos, dist, pitch, yaw); + + focus[1] = focus[1] + (sCutsceneVars[9].point[1] - focus[1]) * 0.1f; + approach_vec3f_asymptotic(c->focus, focus, 0.2f, 0.2f, 0.2f); + + vec3f_copy(pos, c->pos); + + // Set y pos to cvar8's y (top of focus object) + pos[1] = sCutsceneVars[8].point[1]; + vec3f_get_dist_and_angle(sCutsceneVars[8].point, pos, &dist, &pitch, &yaw); + approach_s16_asymptotic_bool(&yaw, sCutsceneVars[9].angle[1], 0x10); + approach_f32_asymptotic_bool(&dist, 180.f, 0.05f); + vec3f_set_dist_and_angle(sCutsceneVars[8].point, pos, dist, pitch, yaw); + + // Move up if mario is below the focus object, down is mario is above + pos[1] = sCutsceneVars[8].point[1] + + sins(calculate_pitch(sCutsceneVars[9].point, sCutsceneVars[8].point)) * 100.f; + + approach_f32_asymptotic_bool(&c->pos[1], pos[1], 0.05f); + c->pos[0] = pos[0]; + c->pos[2] = pos[2]; } -CmdRet CutsceneDialog0_3(struct LevelCamera *c) { - if (c->cutscene == CUTSCENE_DIALOG_2) { - create_dialog_box_with_response(D_8033B320); +/** + * Create the dialog with sCutsceneDialogID + */ +CmdRet cutscene_dialog_create_dialog_box(struct Camera *c) { + if (c->cutscene == CUTSCENE_RACE_DIALOG) { + create_dialog_box_with_response(sCutsceneDialogID); } else { - create_dialog_box(D_8033B320); + create_dialog_box(sCutsceneDialogID); } - D_8033B6F0[8].unk1C[0] = 3; + //! Unused. This may have been used before sCutsceneDialogResponse was implemented. + sCutsceneVars[8].angle[0] = 3; } -CmdRet CutsceneDialog0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneDialog0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneDialog0_2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneDialog0_3, c, 10, 10); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; +/** + * Cutscene that plays when mario talks to an object. + */ +CmdRet cutscene_dialog(struct Camera *c) { + cutscene_event(cutscene_dialog_start, c, 0, 0); + cutscene_event(cutscene_dialog_move_mario_shoulder, c, 0, -1); + cutscene_event(cutscene_dialog_create_dialog_box, c, 10, 10); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; if (gDialogResponse != 0) { - D_8032CFFC = gDialogResponse; + sCutsceneDialogResponse = gDialogResponse; } - if ((get_dialog_id() == -1) && (D_8033B6F0[8].unk1C[0] != 0)) { - if (c->cutscene != CUTSCENE_DIALOG_2) { - D_8032CFFC = 3; + if ((get_dialog_id() == -1) && (sCutsceneVars[8].angle[0] != 0)) { + if (c->cutscene != CUTSCENE_RACE_DIALOG) { + sCutsceneDialogResponse = 3; } - gCutsceneTimer = 0x7FFF; - func_802902A8(c); - init_transitional_movement(c, 15); - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; - func_80290598(c); + gCutsceneTimer = CUTSCENE_LOOP; + retrieve_info_star(c); + transition_next_state(c, 15); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; + cutscene_unsoften_music(c); } } -CmdRet CutsceneDialog1(UNUSED struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; +/** + * Sets the CAM_FLAG_UNUSED_CUTSCENE_ACTIVE flag, which does nothing. + */ +CmdRet cutscene_dialog_set_flag(UNUSED struct Camera *c) { + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneDialog2(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; +/** + * Ends the dialog cutscene. + */ +CmdRet cutscene_dialog_end(struct Camera *c) { + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; c->cutscene = 0; - clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_UNKNOWN_2); + clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); } -CmdRet CutsceneReadMessage0_1(struct LevelCamera *c) { - func_80290564(c); - init_transitional_movement(c, 30); - func_8028FEDC(c); - func_80290224(c); +/** + * Soften the music, clear cvar0 + * + * In this cutscene, cvar0.angle[0] is used as a state variable. + */ +CmdRet cutscene_read_message_start(struct Camera *c) { + cutscene_soften_music(c); + transition_next_state(c, 30); + reset_pan_distance(c); + store_info_star(c); - D_8033B6F0[1].unk1C[0] = sFirstPersonCameraPitch; - D_8033B6F0[1].unk1C[1] = sFirstPersonCameraYaw; - sFirstPersonCameraPitch = -2096; - sFirstPersonCameraYaw = 0; - D_8033B6F0[0].unk1C[0] = 0; + sCutsceneVars[1].angle[0] = sCUpCameraPitch; + sCutsceneVars[1].angle[1] = sModeOffsetYaw; + sCUpCameraPitch = -0x830; + sModeOffsetYaw = 0; + sCutsceneVars[0].angle[0] = 0; } -static void unused_80295A28(struct LevelCamera *c) { - Vec3s sp20; +static void unused_cam_to_mario(struct Camera *c) { + Vec3s dir; - vec3s_set(sp20, 0, sMarioStatusForCamera->faceAngle[1], 0); - set_pos_from_face_angle_and_rel_coords(c->pos, sMarioStatusForCamera->pos, sp20, 0, 100.f, 190.f); - set_pos_from_face_angle_and_rel_coords(c->focus, sMarioStatusForCamera->pos, sp20, 0, 70.f, -20.f); + vec3s_set(dir, 0, sMarioCamState->faceAngle[1], 0); + offset_rotated_coords(c->pos, sMarioCamState->pos, dir, 0, 100.f, 190.f); + offset_rotated_coords(c->focus, sMarioCamState->pos, dir, 0, 70.f, -20.f); } -CmdRet CutsceneReadMessage0(struct LevelCamera *c) { +/** + * Cutscene that plays when mario is reading a message (a sign or message on the wall) + */ +CmdRet cutscene_read_message(struct Camera *c) { UNUSED u32 pad[2]; - call_cutscene_func_in_time_range(CutsceneReadMessage0_1, c, 0, 0); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + cutscene_event(cutscene_read_message_start, c, 0, 0); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; - switch (D_8033B6F0[0].unk1C[0]) { + switch (sCutsceneVars[0].angle[0]) { + // Do nothing until message is gone. case 0: if (get_dialog_id() != -1) { - D_8033B6F0[0].unk1C[0] += 1; - set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_UNKNOWN_2); + sCutsceneVars[0].angle[0] += 1; + set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); } break; + // Leave the dialog. case 1: - operate_c_up_looking(c); - return_first_person_camera_yaw(c, c->focus, c->pos); + move_mario_head_c_up(c); + update_c_up(c, c->focus, c->pos); + // This could cause softlocks. If a message starts one frame after another one closes, the + // cutscene will never end. if (get_dialog_id() == -1) { - gCutsceneTimer = 0x7FFF; - func_802902A8(c); - init_transitional_movement(c, 15); - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; - clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_UNKNOWN_2); - sFirstPersonCameraPitch = D_8033B6F0[1].unk1C[0]; - sFirstPersonCameraYaw = D_8033B6F0[1].unk1C[1]; - func_80290598(c); + gCutsceneTimer = CUTSCENE_LOOP; + retrieve_info_star(c); + transition_next_state(c, 15); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; + clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); + // Retrieve previous state + sCUpCameraPitch = sCutsceneVars[1].angle[0]; + sModeOffsetYaw = sCutsceneVars[1].angle[1]; + cutscene_unsoften_music(c); } } - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneReadMessage1(UNUSED struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; +/** + * Set CAM_FLAG_UNUSED_CUTSCENE_ACTIVE, which does nothing. + */ +CmdRet cutscene_read_message_set_flag(UNUSED struct Camera *c) { + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneReadMessage2(struct LevelCamera *c) { - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; +/** + * End the message cutscene. + */ +CmdRet cutscene_read_message_end(struct Camera *c) { + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; c->cutscene = 0; } -CmdRet CutsceneExitSuccess1(UNUSED struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[7].unk4, sMarioStatusForCamera->pos); - vec3s_copy(D_8033B6F0[7].unk1C, sMarioStatusForCamera->faceAngle); - vec3f_set(D_8033B6F0[6].unk4, 6.f, 363.f, 543.f); - vec3f_set(D_8033B6F0[5].unk4, 137.f, 226.f, 995.f); +/** + * Set cvars: + * cvar7 is mario's pos and angle + * cvar6 is the focus offset + * cvar5 is the position offset + */ +CmdRet cutscene_exit_succ_start(UNUSED struct Camera *c) { + vec3f_copy(sCutsceneVars[7].point, sMarioCamState->pos); + vec3s_copy(sCutsceneVars[7].angle, sMarioCamState->faceAngle); + vec3f_set(sCutsceneVars[6].point, 6.f, 363.f, 543.f); + vec3f_set(sCutsceneVars[5].point, 137.f, 226.f, 995.f); } -CmdRet CutsceneExitSuccess2(struct LevelCamera *c) { - UNUSED u32 sp34; +/** + * Set the camera pos depending on which level mario exited. + */ +CmdRet cutscene_non_painting_set_cam_pos(struct Camera *c) { + UNUSED u32 unused1; struct Surface *floor; - UNUSED Vec3f sp24; + UNUSED Vec3f unused2; switch (gPrevLevel) { case LEVEL_HMC: @@ -7270,257 +9054,353 @@ CmdRet CutsceneExitSuccess2(struct LevelCamera *c) { break; default: - set_pos_from_face_angle_and_vec3f(c->pos, D_8033B6F0[7].unk4, D_8033B6F0[5].unk4, - D_8033B6F0[7].unk1C); + offset_rotated(c->pos, sCutsceneVars[7].point, sCutsceneVars[5].point, sCutsceneVars[7].angle); c->pos[1] = find_floor(c->pos[0], c->pos[1] + 1000.f, c->pos[2], &floor) + 125.f; break; } } -CmdRet CutsceneExitSuccess4(struct LevelCamera *c) { - set_pos_from_face_angle_and_vec3f(c->focus, D_8033B6F0[7].unk4, D_8033B6F0[6].unk4, - D_8033B6F0[7].unk1C); +/** + * Update the camera focus depending on which level mario exited. + */ +CmdRet cutscene_non_painting_set_cam_focus(struct Camera *c) { + offset_rotated(c->focus, sCutsceneVars[7].point, sCutsceneVars[6].point, sCutsceneVars[7].angle); if ((gPrevLevel == LEVEL_COTMC) || (gPrevLevel == LEVEL_HMC) || (gPrevLevel == LEVEL_RR) || (gPrevLevel == LEVEL_WMOTR)) { - c->focus[0] = c->pos[0] + (sMarioStatusForCamera->pos[0] - c->pos[0]) * 0.7f; - c->focus[1] = c->pos[1] + (sMarioStatusForCamera->pos[1] - c->pos[1]) * 0.4f; - c->focus[2] = c->pos[2] + (sMarioStatusForCamera->pos[2] - c->pos[2]) * 0.7f; + c->focus[0] = c->pos[0] + (sMarioCamState->pos[0] - c->pos[0]) * 0.7f; + c->focus[1] = c->pos[1] + (sMarioCamState->pos[1] - c->pos[1]) * 0.4f; + c->focus[2] = c->pos[2] + (sMarioCamState->pos[2] - c->pos[2]) * 0.7f; } else { - c->focus[1] = c->pos[1] + (sMarioStatusForCamera->pos[1] - c->pos[1]) * 0.2f; + c->focus[1] = c->pos[1] + (sMarioCamState->pos[1] - c->pos[1]) * 0.2f; } } -CmdRet CutsceneExitSuccess3(UNUSED struct LevelCamera *c) { - approach_f32_exponential_bool(&D_8033B6F0[6].unk4[0], -24.f, 0.05f); +/** + * Focus slightly left of mario. Perhaps to keep the bowser painting in view? + */ +CmdRet cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *c) { + approach_f32_asymptotic_bool(&sCutsceneVars[6].point[0], -24.f, 0.05f); } -CmdRet CutsceneExitBowserSuccess0_1(struct LevelCamera *c) { +/** + * Instead of focusing on the key, just start a pitch shake. Clever! + * The shake lasts 32 frames. + */ +CmdRet cutscene_exit_bowser_key_toss_shake(struct Camera *c) { + //! Unnecessary check. if (c->cutscene == CUTSCENE_EXIT_BOWSER_SUCC) { set_camera_pitch_shake(0x800, 0x40, 0x800); } } -CmdRet CutsceneExitSuccess5(UNUSED struct LevelCamera *c) { - set_camera_shake_2(SHAKE_2_UNKNOWN_1); +/** + * Start a camera shake when mario lands on the ground. + */ +CmdRet cutscene_exit_succ_shake_landing(UNUSED struct Camera *c) { + set_environmental_camera_shake(SHAKE_ENV_EXPLOSION); } -CmdRet CutsceneExitBowserSuccess0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneExitSuccess1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneExitSuccess2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess3, c, 18, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess4, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitBowserSuccess0_1, c, 125, 125); - call_cutscene_func_in_time_range(CutsceneExitSuccess5, c, 41, 41); +/** + * Cutscene that plays when mario beats bowser and exits the level. + */ +CmdRet cutscene_exit_bowser_succ(struct Camera *c) { + cutscene_event(cutscene_exit_succ_start, c, 0, 0); + cutscene_event(cutscene_non_painting_set_cam_pos, c, 0, -1); + cutscene_event(cutscene_exit_bowser_succ_focus_left, c, 18, -1); + cutscene_event(cutscene_non_painting_set_cam_focus, c, 0, -1); + cutscene_event(cutscene_exit_bowser_key_toss_shake, c, 125, 125); + cutscene_event(cutscene_exit_succ_shake_landing, c, 41, 41); } -CmdRet CutsceneExitNonPainting1(struct LevelCamera *c) { +/** + * End a non-painting exit cutscene. Used by BBH and bowser courses. + */ +CmdRet cutscene_non_painting_end(struct Camera *c) { c->cutscene = 0; - if (c->defPreset == CAMERA_PRESET_CLOSE) { - c->currPreset = CAMERA_PRESET_CLOSE; + if (c->defMode == CAMERA_MODE_CLOSE) { + c->mode = CAMERA_MODE_CLOSE; } else { - c->currPreset = CAMERA_PRESET_FREE_ROAM; + c->mode = CAMERA_MODE_FREE_ROAM; } - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - init_transitional_movement(c, 60); - set_cam_yaw_from_focus_and_pos(c); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + transition_next_state(c, 60); + update_camera_yaw(c); } -CmdRet CutsceneBBHExitSuccess0_1(UNUSED struct LevelCamera *c) { - vec3f_set(D_8033B6F0[5].unk4, 137.f, 246.f, 1115.f); +/** + * Override the position offset. + */ +CmdRet cutscene_exit_non_painting_succ_override_cvar(UNUSED struct Camera *c) { + vec3f_set(sCutsceneVars[5].point, 137.f, 246.f, 1115.f); } -CmdRet CutsceneBBHExitSuccess0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneExitSuccess1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneBBHExitSuccess0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneExitSuccess2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess3, c, 18, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess4, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess5, c, 41, 41); - set_cam_yaw_from_focus_and_pos(c); +/** + * Cutscene that plays when mario collects a star and leaves a non-painting course, like HMC or BBH. + */ +CmdRet cutscene_exit_non_painting_succ(struct Camera *c) { + cutscene_event(cutscene_exit_succ_start, c, 0, 0); + cutscene_event(cutscene_exit_non_painting_succ_override_cvar, c, 0, 0); + cutscene_event(cutscene_non_painting_set_cam_pos, c, 0, -1); + cutscene_event(cutscene_exit_bowser_succ_focus_left, c, 18, -1); + cutscene_event(cutscene_non_painting_set_cam_focus, c, 0, -1); + cutscene_event(cutscene_exit_succ_shake_landing, c, 41, 41); + update_camera_yaw(c); } -CmdRet CutsceneNonPaintingDeath0_1(UNUSED struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[7].unk4, sMarioStatusForCamera->pos); - vec3s_copy(D_8033B6F0[7].unk1C, sMarioStatusForCamera->faceAngle); - vec3f_set(D_8033B6F0[6].unk4, -42.f, 350.f, 727.f); - vec3f_set(D_8033B6F0[5].unk4, 107.f, 226.f, 1187.f); +/** + * Set cvar7 to mario's pos and faceAngle + * Set cvar6 to the focus offset from mario. + * set cvar5 to the pos offset from mario. (This is always overwritten) + */ +CmdRet cutscene_non_painting_death_start(UNUSED struct Camera *c) { + vec3f_copy(sCutsceneVars[7].point, sMarioCamState->pos); + vec3s_copy(sCutsceneVars[7].angle, sMarioCamState->faceAngle); + vec3f_set(sCutsceneVars[6].point, -42.f, 350.f, 727.f); + // This is always overwritten, except in the unused cutscene_exit_bowser_death() + vec3f_set(sCutsceneVars[5].point, 107.f, 226.f, 1187.f); } -CmdRet Cutscene1CTodo_0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneNonPaintingDeath0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneExitSuccess2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess4, c, 0, -1); +/** + * This cutscene is the same as non_painting_death, but the camera is closer to mario and lower. + * Because it it doesn't call cutscene_non_painting_death_override_offset, the value from + * cutscene_non_painting_death_start is used. + * + * This cutscene is unused, dying in bowser's arena spawns mario near the warp pipe, not back in the + * hub. + */ +CmdRet cutscene_exit_bowser_death(struct Camera *c) { + cutscene_event(cutscene_non_painting_death_start, c, 0, 0); + cutscene_event(cutscene_non_painting_set_cam_pos, c, 0, -1); + cutscene_event(cutscene_non_painting_set_cam_focus, c, 0, -1); } -CmdRet CutsceneNonPaintingDeath0_2(UNUSED struct LevelCamera *c) { +/** + * Set the offset from mario depending on the course mario exited. + * This overrides cutscene_non_painting_death_start() + */ +CmdRet cutscene_non_painting_death_override_offset(UNUSED struct Camera *c) { switch (gPrevLevel) { case LEVEL_HMC: - vec3f_set(D_8033B6F0[5].unk4, 187.f, 369.f, -197.f); + vec3f_set(sCutsceneVars[5].point, 187.f, 369.f, -197.f); break; case LEVEL_COTMC: - vec3f_set(D_8033B6F0[5].unk4, 187.f, 369.f, -197.f); + vec3f_set(sCutsceneVars[5].point, 187.f, 369.f, -197.f); break; default: - vec3f_set(D_8033B6F0[5].unk4, 107.f, 246.f, 1307.f); + vec3f_set(sCutsceneVars[5].point, 107.f, 246.f, 1307.f); break; } } -CmdRet CutsceneNonPaintingDeath0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneNonPaintingDeath0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneNonPaintingDeath0_2, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneExitSuccess2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneExitSuccess4, c, 0, -1); - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; +/** + * Cutscene played when mario dies in a non-painting course, like HMC or BBH. + */ +CmdRet cutscene_non_painting_death(struct Camera *c) { + cutscene_event(cutscene_non_painting_death_start, c, 0, 0); + cutscene_event(cutscene_non_painting_death_override_offset, c, 0, 0); + cutscene_event(cutscene_non_painting_set_cam_pos, c, 0, -1); + cutscene_event(cutscene_non_painting_set_cam_focus, c, 0, -1); + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneCapSwitchPress0_1(struct LevelCamera *c) { - UNUSED s16 sp26; - s16 sp24; - UNUSED u32 sp1C[2]; +/** + * Set cvars: + * cvar3 is an offset applied to the camera's rotation around mario. It starts at 0x1200 + * cvar 1 is more complicated: + * First the yaw from mario to the camera is calculated. cvar1 is the high byte of the difference + * between that yaw and mario's faceAngle plus 0x1200. The reason for taking the high byte is + * because cvar1 rotates until is reaches 0, so it's important that it's a multiple of 0x100. + */ +CmdRet cutscene_cap_switch_press_start(struct Camera *c) { + UNUSED s16 unused1; + s16 yaw; + UNUSED u32 pad[2]; - func_80290224(c); - sp24 = calculate_yaw(sMarioStatusForCamera->pos, c->pos); - D_8033B6F0[3].unk1C[1] = 0x1200; - D_8033B6F0[1].unk1C[1] = - (sp24 - (sMarioStatusForCamera->faceAngle[1] + D_8033B6F0[3].unk1C[1])) & 0xFF00; + store_info_star(c); + yaw = calculate_yaw(sMarioCamState->pos, c->pos); + sCutsceneVars[3].angle[1] = 0x1200; + // Basically the amount of rotation to get from behind mario to in front of mario + sCutsceneVars[1].angle[1] = (yaw - (sMarioCamState->faceAngle[1] + sCutsceneVars[3].angle[1])) & 0xFF00; } -CmdRet CutsceneCapSwitchPress0_4(struct LevelCamera *c) { - f32 sp2C; - s16 sp2A, sp28; - UNUSED s16 sp26 = sMarioStatusForCamera->faceAngle[1] + 0x1000; - UNUSED s16 sp24; - UNUSED s32 sp20 = D_8033B6F0[1].unk1C[1]; +/** + * Rotate around mario. As each cvar stops updating, the rotation slows until the camera ends up in + * front of mario. + */ +CmdRet cutscene_cap_switch_press_rotate_around_mario(struct Camera *c) { + f32 dist; + s16 pitch, yaw; + UNUSED s16 unusedYaw = sMarioCamState->faceAngle[1] + 0x1000; + UNUSED s16 unused; + UNUSED s32 cvar1Yaw = sCutsceneVars[1].angle[1]; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp2C, &sp2A, &sp28); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); - if (D_8033B6F0[3].unk1C[1] != 0x1000) { - D_8033B6F0[3].unk1C[1] += 0x100; - } - if (D_8033B6F0[1].unk1C[1] != 0) { - D_8033B6F0[1].unk1C[1] += 0x100; + // cvar3 wraps around until it reaches 0x1000 + if (sCutsceneVars[3].angle[1] != 0x1000) { + sCutsceneVars[3].angle[1] += 0x100; } - sp28 = sMarioStatusForCamera->faceAngle[1] + D_8033B6F0[3].unk1C[1] + D_8033B6F0[1].unk1C[1]; - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp2C, sp2A, sp28); + // cvar1 wraps until 0 + if (sCutsceneVars[1].angle[1] != 0) { + sCutsceneVars[1].angle[1] += 0x100; + } + + yaw = sMarioCamState->faceAngle[1] + sCutsceneVars[3].angle[1] + sCutsceneVars[1].angle[1]; + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneCapSwitchPress0_5(struct LevelCamera *c) { - rotate_and_move_vec3f(c->pos, sMarioStatusForCamera->pos, 0, -0x20, 0); +/** + * Move the camera slightly downwards. + */ +CmdRet cutscene_cap_switch_press_lower_cam(struct Camera *c) { + rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, -0x20, 0); } -CmdRet CutsceneCapSwitchPress0_2(struct LevelCamera *c) { - s16 sp26, sp24; - f32 sp20; +/** + * Move the camera closer to mario. + */ +CmdRet cutscene_cap_switch_press_approach_mario(struct Camera *c) { + s16 pitch, yaw; + f32 dist; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp20, &sp26, &sp24); - approach_f32_exponential_bool(&sp20, 195.f, 0.2f); - approach_s16_exponential_bool(&sp26, 0, 0x10); - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, sp20, sp26, sp24); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + approach_f32_asymptotic_bool(&dist, 195.f, 0.2f); + approach_s16_asymptotic_bool(&pitch, 0, 0x10); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); - approach_f32_exponential_bool(&c->focus[0], sMarioStatusForCamera->pos[0], 0.1f); - approach_f32_exponential_bool(&c->focus[1], sMarioStatusForCamera->pos[1] + 110.f, 0.1f); - approach_f32_exponential_bool(&c->focus[2], sMarioStatusForCamera->pos[2], 0.1f); + approach_f32_asymptotic_bool(&c->focus[0], sMarioCamState->pos[0], 0.1f); + approach_f32_asymptotic_bool(&c->focus[1], sMarioCamState->pos[1] + 110.f, 0.1f); + approach_f32_asymptotic_bool(&c->focus[2], sMarioCamState->pos[2], 0.1f); } -CmdRet CutsceneCapSwitchPress0_3(struct LevelCamera *c) { - vec3f_copy(c->focus, sMarioStatusForCamera->pos); +/** + * Pan the camera left so that mario is on the right side of the screen when the camera stops spinning. + */ +CmdRet cutscene_cap_switch_press_pan_left(struct Camera *c) { + vec3f_copy(c->focus, sMarioCamState->pos); c->focus[1] += 110.f; - camera_approach_s16_symmetric_bool(&D_8033B6F0[0].unk1C[1], 0x800, 0x20); - rotate_camera(c, D_8033B6F0[0].unk1C[0], D_8033B6F0[0].unk1C[1]); + camera_approach_s16_symmetric_bool(&sCutsceneVars[0].angle[1], 0x800, 0x20); + pan_camera(c, sCutsceneVars[0].angle[0], sCutsceneVars[0].angle[1]); } -CmdRet CutsceneCapSwitchPress0_6(UNUSED struct LevelCamera *c) { +/** + * Create a dialog box with the cap switch's text. + */ +CmdRet cutscene_cap_switch_press_create_dialog(UNUSED struct Camera *c) { create_dialog_box_with_response(gCutsceneFocus->oBehParams2ndByte + DIALOG_010); } -static void unused_802968E8(struct LevelCamera *c) { - func_802902A8(c); - init_transitional_movement(c, 30); +static UNUSED CmdRet unused_cap_switch_retrieve_info(struct Camera *c) { + retrieve_info_star(c); + transition_next_state(c, 30); } -CmdRet CutsceneCapSwitchPress0(struct LevelCamera *c) { - f32 sp24; - s16 sp22, sp20; +/** + * Cutscene that plays when mario presses a cap switch. + */ +CmdRet cutscene_cap_switch_press(struct Camera *c) { + f32 dist; + s16 pitch, yaw; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_2, c, 0, 30); - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_3, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_4, c, 30, -1); - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_5, c, 10, 70); - call_cutscene_func_in_time_range(CutsceneCapSwitchPress0_6, c, 10, 10); - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &sp24, &sp22, &sp20); + cutscene_event(cutscene_cap_switch_press_start, c, 0, 0); + cutscene_event(cutscene_cap_switch_press_approach_mario, c, 0, 30); + cutscene_event(cutscene_cap_switch_press_pan_left, c, 0, -1); + cutscene_event(cutscene_cap_switch_press_rotate_around_mario, c, 30, -1); + cutscene_event(cutscene_cap_switch_press_lower_cam, c, 10, 70); + cutscene_event(cutscene_cap_switch_press_create_dialog, c, 10, 10); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); if (gDialogResponse != 0) { - D_8033B6F0[4].unk1C[0] = gDialogResponse; + sCutsceneVars[4].angle[0] = gDialogResponse; } - if ((get_dialog_id() == -1) && (D_8033B6F0[4].unk1C[0] != 0)) { - D_8032CFFC = D_8033B6F0[4].unk1C[0]; - if (D_8033B6F0[4].unk1C[0] == 1) { + if ((get_dialog_id() == -1) && (sCutsceneVars[4].angle[0] != 0)) { + sCutsceneDialogResponse = sCutsceneVars[4].angle[0]; + if (sCutsceneVars[4].angle[0] == 1) { cap_switch_save(gCutsceneFocus->oBehParams2ndByte); } - func_8028FAE0(c); - init_transitional_movement(c, 30); + stop_cutscene_and_retrieve_stored_info(c); + transition_next_state(c, 30); } } -CmdRet CutsceneUnlockKeyDoor0_1(struct LevelCamera *c) { - Vec3f sp24, sp18; +/** + * Sets cvars: + * cvar0 is the camera's position + * cvar1 is the camera's focus + * cvar2 is the goal position + * cvar3 is the goal focus + */ +CmdRet cutscene_unlock_key_door_start(struct Camera *c) { + Vec3f posOff, focusOff; - vec3f_copy(D_8033B6F0[0].unk4, c->pos); - vec3f_copy(D_8033B6F0[1].unk4, c->focus); - vec3f_set(sp24, -206.f, 108.f, 234.f); - vec3f_set(sp18, 48.f, 104.f, -193.f); - set_pos_from_face_angle_and_vec3f(D_8033B6F0[2].unk4, sMarioStatusForCamera->pos, sp24, - sMarioStatusForCamera->faceAngle); - set_pos_from_face_angle_and_vec3f(D_8033B6F0[3].unk4, sMarioStatusForCamera->pos, sp18, - sMarioStatusForCamera->faceAngle); + vec3f_copy(sCutsceneVars[0].point, c->pos); + vec3f_copy(sCutsceneVars[1].point, c->focus); + vec3f_set(posOff, -206.f, 108.f, 234.f); + vec3f_set(focusOff, 48.f, 104.f, -193.f); + offset_rotated(sCutsceneVars[2].point, sMarioCamState->pos, posOff, sMarioCamState->faceAngle); + offset_rotated(sCutsceneVars[3].point, sMarioCamState->pos, focusOff, sMarioCamState->faceAngle); } -CmdRet CutsceneUnlockKeyDoor0_2(struct LevelCamera *c) { - approach_vec3f_exponential(c->pos, D_8033B6F0[2].unk4, 0.1f, 0.1f, 0.1f); - approach_vec3f_exponential(c->focus, D_8033B6F0[3].unk4, 0.1f, 0.1f, 0.1f); +/** + * Move the camera to the cvars position and focus, closer to mario. + * Gives a better view of the key. + */ +CmdRet cutscene_unlock_key_door_approach_mario(struct Camera *c) { + approach_vec3f_asymptotic(c->pos, sCutsceneVars[2].point, 0.1f, 0.1f, 0.1f); + approach_vec3f_asymptotic(c->focus, sCutsceneVars[3].point, 0.1f, 0.1f, 0.1f); } -CmdRet CutsceneUnlockKeyDoor0_5(UNUSED struct LevelCamera *c) { - approach_f32_exponential_bool(&D_8033B6F0[3].unk4[1], sMarioStatusForCamera->pos[1] + 140.f, 0.07f); +/** + * Move the camera focus up a bit, focusing on the key in the lock. + */ +CmdRet cutscene_unlock_key_door_focus_lock(UNUSED struct Camera *c) { + approach_f32_asymptotic_bool(&sCutsceneVars[3].point[1], sMarioCamState->pos[1] + 140.f, 0.07f); } -CmdRet CutsceneUnlockKeyDoor0_6(UNUSED struct LevelCamera *c) { +CmdRet cutscene_unlock_key_door_stub(UNUSED struct Camera *c) { } -CmdRet CutsceneUnlockKeyDoor0_3(struct LevelCamera *c) { - approach_vec3f_exponential(c->pos, D_8033B6F0[0].unk4, 0.1f, 0.1f, 0.1f); - approach_vec3f_exponential(c->focus, D_8033B6F0[1].unk4, 0.1f, 0.1f, 0.1f); +/** + * Move back to the previous pos and focus, stored in cvar0 and cvar1. + */ +CmdRet cutscene_unlock_key_door_fly_back(struct Camera *c) { + approach_vec3f_asymptotic(c->pos, sCutsceneVars[0].point, 0.1f, 0.1f, 0.1f); + approach_vec3f_asymptotic(c->focus, sCutsceneVars[1].point, 0.1f, 0.1f, 0.1f); } -CmdRet CutsceneUnlockKeyDoor0_4(UNUSED struct LevelCamera *c) { - func_8029A494(1); +/** + * Shake the camera's fov when the key is put in the lock. + */ +CmdRet cutscene_unlock_key_door_fov_shake(UNUSED struct Camera *c) { + cutscene_set_fov_shake_preset(1); } -CmdRet CutsceneUnlockKeyDoor0(UNUSED struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_2, c, 0, 123); - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_3, c, 124, -1); - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_4, c, 79, 79); - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_5, c, 70, 110); - call_cutscene_func_in_time_range(CutsceneUnlockKeyDoor0_6, c, 112, 112); +/** + * Cutscene that plays when mario unlocks a key door. + */ +CmdRet cutscene_unlock_key_door(UNUSED struct Camera *c) { + cutscene_event(cutscene_unlock_key_door_start, c, 0, 0); + cutscene_event(cutscene_unlock_key_door_approach_mario, c, 0, 123); + cutscene_event(cutscene_unlock_key_door_fly_back, c, 124, -1); + cutscene_event(cutscene_unlock_key_door_fov_shake, c, 79, 79); + cutscene_event(cutscene_unlock_key_door_focus_lock, c, 70, 110); + cutscene_event(cutscene_unlock_key_door_stub, c, 112, 112); } /** * Move the camera along `positionSpline` and point its focus at the corresponding point along * `focusSpline`. sCutsceneSplineSegmentProgress is updated after pos and focus are calculated. */ -s32 intro_peach_move_camera_start_to_pipe(struct LevelCamera *c, struct CutsceneSplinePoint positionSpline[], +s32 intro_peach_move_camera_start_to_pipe(struct Camera *c, struct CutsceneSplinePoint positionSpline[], struct CutsceneSplinePoint focusSpline[]) { Vec3f offset; s32 posReturn = 0; @@ -7536,8 +9416,8 @@ s32 intro_peach_move_camera_start_to_pipe(struct LevelCamera *c, struct Cutscene // The two splines used by this function are reflected in the horizontal plane for some reason, // so they are rotated every frame. Why do this, Nintendo? - rotate_in_xz(c->focus, c->focus, -0x8000); - rotate_in_xz(c->pos, c->pos, -0x8000); + rotate_in_xz(c->focus, c->focus, DEGREES(180)); + rotate_in_xz(c->pos, c->pos, DEGREES(180)); vec3f_set(offset, -1328.f, 260.f, 4664.f); vec3f_add(c->focus, offset); @@ -7547,131 +9427,167 @@ s32 intro_peach_move_camera_start_to_pipe(struct LevelCamera *c, struct Cutscene return focusReturn; } -CmdRet peach_letter_text(UNUSED struct LevelCamera *c) { +/** + * Create a dialog box with the letter text + */ +CmdRet peach_letter_text(UNUSED struct Camera *c) { create_dialog_box(DIALOG_020); } #ifndef VERSION_JP -CmdRet play_sound_peach_reading_letter(UNUSED struct LevelCamera *c) { +CmdRet play_sound_peach_reading_letter(UNUSED struct Camera *c) { play_sound(SOUND_PEACH_DEAR_MARIO, gDefaultSoundArgs); } #endif -CmdRet CutsceneIntroPeachCommon(struct LevelCamera *c) { +/** + * Move the camera from peach reading the letter all the way to mario's warp pipe. Follow the + * sIntroStartToPipe splines. + */ +CmdRet cutscene_intro_peach_start_to_pipe_spline(struct Camera *c) { if (intro_peach_move_camera_start_to_pipe(c, sIntroStartToPipePosition, sIntroStartToPipeFocus) != 0) { gCameraMovementFlags &= ~CAM_MOVE_C_UP_MODE; - gCutsceneTimer = 0x7FFF; + gCutsceneTimer = CUTSCENE_LOOP; } } -CmdRet CutsceneIntroPeach4(struct LevelCamera *c) { +/** + * Loop the cutscene until mario exits the dialog. + */ +CmdRet cutscene_intro_peach_dialog(struct Camera *c) { if (get_dialog_id() == -1) { - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[3], c->pos); - vec3f_copy(gCameraStatus.camFocAndPosCurrAndGoal[2], c->focus); - gCameraFlags2 |= (CAM_FLAG_2_SMOOTH_MOVEMENT | CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE); - gCutsceneTimer = 0x8000; + vec3f_copy(gLakituState.goalPos, c->pos); + vec3f_copy(gLakituState.goalFocus, c->focus); + sStatusFlags |= (CAM_FLAG_SMOOTH_MOVEMENT | CAM_FLAG_UNUSED_CUTSCENE_ACTIVE); + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; } } -CmdRet CutsceneIntroPeach3_2(struct LevelCamera *c) { +CmdRet cutscene_intro_peach_follow_pipe_spline(struct Camera *c) { move_point_along_spline(c->pos, sIntroPipeToDialogPosition, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); move_point_along_spline(c->focus, sIntroPipeToDialogFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); } -CmdRet CutsceneIntroPeach2_2(UNUSED struct LevelCamera *c) { - sMarioStatusForCamera->unk1C[1] = 0; +CmdRet cutscene_intro_peach_clear_cutscene_status(UNUSED struct Camera *c) { + sMarioCamState->cameraEvent = 0; } -CmdRet CutsceneIntroPeach0_1(UNUSED struct LevelCamera *c) { - D_8033B230.fieldOfView = 8.f; - set_fov_function(12); +/** + * Set fov to 8 degrees, then zoom out to 30. + */ +CmdRet cutscene_intro_peach_zoom_fov(UNUSED struct Camera *c) { + sFOVState.fov = 8.f; + set_fov_function(CAM_FOV_ZOOM_30); } -CmdRet CutsceneIntroPeach3_1(UNUSED struct LevelCamera *c) { +/** + * Reset the spline progress, turn on handheld shake. + */ +CmdRet cutscene_intro_peach_reset_spline(UNUSED struct Camera *c) { sCutsceneSplineSegment = 0; sCutsceneSplineSegmentProgress = 0.1f; - set_spline_values(4); + //! @bug since this event is only called for one frame, this handheld shake is turned off on the + //! next frame. + set_handheld_shake(HAND_CAM_SHAKE_HIGH); } -CmdRet CutsceneIntroPeach3_3(UNUSED struct LevelCamera *c) { - set_spline_values(0); +/** + * Turn off handheld shake. This was likely written before handheld shake was changed to turn off every + * frame, as it's the only instance of HAND_CAM_SHAKE_OFF. + */ +CmdRet cutscene_intro_peach_handheld_shake_off(UNUSED struct Camera *c) { + set_handheld_shake(HAND_CAM_SHAKE_OFF); } -CmdRet intro_pipe_exit_text(UNUSED struct LevelCamera *c) { +CmdRet intro_pipe_exit_text(UNUSED struct Camera *c) { create_dialog_box(DIALOG_033); } #ifndef VERSION_JP -CmdRet play_sound_intro_turn_on_hud(UNUSED struct LevelCamera *c) { +CmdRet play_sound_intro_turn_on_hud(UNUSED struct Camera *c) { play_sound_rbutton_changed(); } #endif -CmdRet CutsceneIntroPeach2(struct LevelCamera *c) { +/** + * Fly to the pipe. Near the end, the camera jumps to lakitu's position and the hud turns on. + */ +CmdRet cutscene_intro_peach_fly_to_pipe(struct Camera *c) { #ifndef VERSION_JP - call_cutscene_func_in_time_range(play_sound_intro_turn_on_hud, c, 818, 818); + cutscene_event(play_sound_intro_turn_on_hud, c, 818, 818); #endif - set_cutscene_phase_at_frame(6, 1); - call_cutscene_func_in_time_range(CutsceneIntroPeach2_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneIntroPeachCommon, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneIntroPeach2_2, c, 717, 717); + cutscene_spawn_obj(6, 1); + cutscene_event(cutscene_intro_peach_start_flying_music, c, 0, 0); + cutscene_event(cutscene_intro_peach_start_to_pipe_spline, c, 0, -1); + cutscene_event(cutscene_intro_peach_clear_cutscene_status, c, 717, 717); clamp_pitch(c->pos, c->focus, 0x3B00, -0x3B00); - D_8033B6F0[1].unk4[1] = 400.f; + sCutsceneVars[1].point[1] = 400.f; } -CmdRet CutsceneIntroPeach3(struct LevelCamera *c) { +/** + * Lakitu flies around the warp pipe, then mario jumps out. + */ +CmdRet cutscene_intro_peach_mario_appears(struct Camera *c) { UNUSED u32 pad[2]; - sMarioStatusForCamera->unk1C[1] = 0; - call_cutscene_func_in_time_range(CutsceneIntroPeach3_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneIntroPeach3_2, c, 0, -1); - call_cutscene_func_in_time_range(CutsceneIntroPeach3_3, c, 70, 70); - call_cutscene_func_in_time_range(intro_pipe_exit_text, c, 250, 250); - approach_f32_exponential_bool( - &D_8033B6F0[1].unk4[1], - 80.f + sGeometryForMario.currFloorHeight - + (sMarioStatusForCamera->pos[1] - sGeometryForMario.currFloorHeight) * 1.1f, - 0.4f); + sMarioCamState->cameraEvent = 0; + cutscene_event(cutscene_intro_peach_reset_spline, c, 0, 0); + cutscene_event(cutscene_intro_peach_follow_pipe_spline, c, 0, -1); + cutscene_event(cutscene_intro_peach_handheld_shake_off, c, 70, 70); + cutscene_event(intro_pipe_exit_text, c, 250, 250); + + approach_f32_asymptotic_bool(&sCutsceneVars[1].point[1], 80.f + sMarioGeometry.currFloorHeight + + (sMarioCamState->pos[1] - sMarioGeometry.currFloorHeight) * 1.1f, 0.4f); // Make the camera look up as mario jumps out of the pipe - if (c->focus[1] < D_8033B6F0[1].unk4[1]) { - c->focus[1] = D_8033B6F0[1].unk4[1]; + if (c->focus[1] < sCutsceneVars[1].point[1]) { + c->focus[1] = sCutsceneVars[1].point[1]; } - gCameraFlags2 |= CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE; + sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet CutsceneIntroPeach1(UNUSED struct LevelCamera *c) { - set_fov_function(2); +/** + * Reset the fov. This gives the effect of peach zooming out as she fades. + */ +CmdRet cutscene_intro_peach_reset_fov(UNUSED struct Camera *c) { + set_fov_function(CAM_FOV_DEFAULT); } -CmdRet CutsceneIntroPeach0(struct LevelCamera *c) { - set_cutscene_phase_at_frame(5, 0); - call_cutscene_func_in_time_range(CutsceneIntroPeach0_1, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneIntroPeach0_2, c, 65, 65); +/** + * Peach reads the letter to mario. + */ +CmdRet cutscene_intro_peach_letter(struct Camera *c) { + cutscene_spawn_obj(5, 0); + cutscene_event(cutscene_intro_peach_zoom_fov, c, 0, 0); + cutscene_event(cutscene_intro_peach_start_letter_music, c, 65, 65); #ifdef VERSION_EU - call_cutscene_func_in_time_range(CutsceneIntroPeach_unkEU, c, 68, 68); + cutscene_event(cutscene_intro_peach_eu_lower_volume, c, 68, 68); #endif - call_cutscene_func_in_time_range(CutsceneIntroPeachCommon, c, 0, 0); - call_cutscene_func_in_time_range(peach_letter_text, c, 65, 65); + cutscene_event(cutscene_intro_peach_start_to_pipe_spline, c, 0, 0); + cutscene_event(peach_letter_text, c, 65, 65); #ifndef VERSION_JP - call_cutscene_func_in_time_range(play_sound_peach_reading_letter, c, 83, 83); + cutscene_event(play_sound_peach_reading_letter, c, 83, 83); #endif if ((gCutsceneTimer > 120) && (get_dialog_id() == -1)) { - gCutsceneTimer = 0x7FFF; + // Start the next scene + gCutsceneTimer = CUTSCENE_LOOP; } clamp_pitch(c->pos, c->focus, 0x3B00, -0x3B00); } -CmdRet CutsceneEndWaving0_1(UNUSED struct LevelCamera *c) { - func_8028FABC(); +/** + * Reset the spline progress. + */ +CmdRet cutscene_end_waving_start(UNUSED struct Camera *c) { + cutscene_reset_spline(); } // 3rd part of data -struct CutsceneSplinePoint gIntroLakituStartToPipeFocus[35] = { +struct CutsceneSplinePoint gIntroLakituStartToPipeFocus[] = { { 0, 32, { 58, -250, 346 } }, { 1, 50, { -159, -382, 224 } }, { 2, 37, { 0, -277, 237 } }, { 3, 15, { 1, -44, 245 } }, { 4, 35, { 0, -89, 228 } }, { 5, 15, { 28, 3, 259 } }, { 6, 25, { -38, -201, 371 } }, { 7, 20, { -642, 118, 652 } }, { 8, 25, { 103, -90, 861 } }, @@ -7686,7 +9602,7 @@ struct CutsceneSplinePoint gIntroLakituStartToPipeFocus[35] = { { 0, 15, { -227, 511, 1550 } }, { -1, 15, { -227, 511, 1600 } } }; -struct CutsceneSplinePoint gIntroLakituStartToPipeOffsetFromCamera[35] = { +struct CutsceneSplinePoint gIntroLakituStartToPipeOffsetFromCamera[] = { { 0, 0, { -46, 87, -15 } }, { 1, 0, { -38, 91, -11 } }, { 2, 0, { -31, 93, -13 } }, { 3, 0, { -50, 84, -16 } }, { 4, 0, { -52, 83, -17 } }, { 5, 0, { -10, 99, 3 } }, { 6, 0, { -54, 83, -10 } }, { 7, 0, { -31, 85, -40 } }, { 8, 0, { -34, 91, 19 } }, @@ -7701,262 +9617,311 @@ struct CutsceneSplinePoint gIntroLakituStartToPipeOffsetFromCamera[35] = { { 33, 0, { 51, -11, 84 } }, { -1, 0, { 51, -11, 84 } } }; -struct CutsceneSplinePoint D_8032E4E4[9] = { +struct CutsceneSplinePoint gEndWavingPos[] = { { 0, 0, { -5, 975, -917 } }, { 0, 0, { -5, 975, -917 } }, { 0, 0, { -5, 975, -917 } }, { 0, 0, { -76, 1067, 742 } }, { 0, 0, { -105, 1576, 3240 } }, { 0, 0, { -177, 1709, 5586 } }, { 0, 0, { -177, 1709, 5586 } }, { 0, 0, { -177, 1709, 5586 } }, { 0, 0, { -177, 1709, 5586 } } }; -struct CutsceneSplinePoint D_8032E52C[9] = { +struct CutsceneSplinePoint gEndWavingFocus[] = { { 0, 50, { 18, 1013, -1415 } }, { 0, 100, { 17, 1037, -1412 } }, { 0, 100, { 16, 1061, -1408 } }, { 0, 100, { -54, 1053, 243 } }, { 0, 100, { -84, 1575, 2740 } }, { 0, 50, { -156, 1718, 5086 } }, { 0, 0, { -156, 1718, 5086 } }, { 0, 0, { -156, 1718, 5086 } }, { 0, 0, { -156, 1718, 5086 } } }; -CmdRet CutsceneEndWaving0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneEndWaving0_1, c, 0, 0); - move_point_along_spline(c->pos, D_8032E4E4, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_point_along_spline(c->focus, D_8032E52C, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - set_cutscene_phase_at_frame(6, 120); +CmdRet cutscene_end_waving(struct Camera *c) { + cutscene_event(cutscene_end_waving_start, c, 0, 0); + move_point_along_spline(c->pos, gEndWavingPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + move_point_along_spline(c->focus, gEndWavingFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + cutscene_spawn_obj(6, 120); } -CmdRet CutsceneCredits0_1(UNUSED struct LevelCamera *c) { - func_8028FABC(); +/** + * Called on the first frame of the credits. Resets the spline progress. + */ +CmdRet cutscene_credits_reset_spline(UNUSED struct Camera *c) { + cutscene_reset_spline(); } -extern struct CutsceneSplinePoint sBobCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sBobCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sWfCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sWfCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sJrbCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sJrbCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sCcmSlideCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sCcmSlideCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sBbhCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sBbhCreditsCameraFocus[4]; -extern struct CutsceneSplinePoint sHmcCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sHmcCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sThiWigglerCreditsCameraPositions[3]; -extern struct CutsceneSplinePoint sThiWigglerCreditsCameraFocus[3]; -extern struct CutsceneSplinePoint sVolcanoCreditsCameraPositions[6]; -extern struct CutsceneSplinePoint sVolcanoCreditsCameraFocus[6]; -extern struct CutsceneSplinePoint sSslCreditsCameraPositions[6]; -extern struct CutsceneSplinePoint sSslCreditsCameraFocus[6]; -extern struct CutsceneSplinePoint sDddCreditsCameraPositions[7]; -extern struct CutsceneSplinePoint sDddCreditsCameraFocus[7]; -extern struct CutsceneSplinePoint sSlCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sSlCreditsCameraFocus[4]; -extern struct CutsceneSplinePoint sWdwCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sWdwCreditsCameraFocus[4]; -extern struct CutsceneSplinePoint sTtmCreditsCameraPositions[6]; -extern struct CutsceneSplinePoint sTtmCreditsCameraFocus[6]; -extern struct CutsceneSplinePoint sThiHugeCreditsCameraPositions[7]; -extern struct CutsceneSplinePoint sThiHugeCreditsCameraFocus[7]; -extern struct CutsceneSplinePoint sTtcCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sTtcCreditsCameraFocus[4]; -extern struct CutsceneSplinePoint sRrCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sRrCreditsCameraFocus[4]; -extern struct CutsceneSplinePoint sSaCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sSaCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sCotmcCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sCotmcCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sDddSubCreditsCameraPositions[5]; -extern struct CutsceneSplinePoint sDddSubCreditsCameraFocus[5]; -extern struct CutsceneSplinePoint sCcmOutsideCreditsCameraPositions[4]; -extern struct CutsceneSplinePoint sCcmOutsideCreditsCameraFocus[4]; +extern struct CutsceneSplinePoint sBobCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sBobCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sWfCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sWfCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sJrbCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sJrbCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sCcmSlideCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sCcmSlideCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sBbhCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sBbhCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sHmcCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sHmcCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sThiWigglerCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sThiWigglerCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sVolcanoCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sVolcanoCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sSslCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sSslCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sDddCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sDddCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sSlCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sSlCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sWdwCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sWdwCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sTtmCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sTtmCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sThiHugeCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sThiHugeCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sTtcCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sTtcCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sRrCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sRrCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sSaCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sSaCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sCotmcCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sCotmcCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sDddSubCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sDddSubCreditsSplineFocus[]; +extern struct CutsceneSplinePoint sCcmOutsideCreditsSplinePositions[]; +extern struct CutsceneSplinePoint sCcmOutsideCreditsSplineFocus[]; -CmdRet CutsceneCredits0(struct LevelCamera *c) { +/** + * Follow splines through the courses of the game. + */ +CmdRet cutscene_credits(struct Camera *c) { struct CutsceneSplinePoint *focus, *pos; - call_cutscene_func_in_time_range(CutsceneCredits0_1, c, 0, 0); + cutscene_event(cutscene_credits_reset_spline, c, 0, 0); -#define SET_CREDITS_PRESET(casenum, arg1, arg2) \ +#define SET_CREDITS_SPLINE(casenum, spline) \ case casenum: \ - pos = arg1; \ - focus = arg2; \ + pos = spline ## Positions; \ + focus = spline ## Focus; \ break; switch (gCurrLevelArea) { - SET_CREDITS_PRESET(AREA_BOB, sBobCreditsCameraPositions, sBobCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_WF, sWfCreditsCameraPositions, sWfCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_JRB_MAIN, sJrbCreditsCameraPositions, sJrbCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_CCM_SLIDE, sCcmSlideCreditsCameraPositions, - sCcmSlideCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_BBH, sBbhCreditsCameraPositions, sBbhCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_HMC, sHmcCreditsCameraPositions, sHmcCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_THI_WIGGLER, sThiWigglerCreditsCameraPositions, - sThiWigglerCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_LLL_VOLCANO, sVolcanoCreditsCameraPositions, - sVolcanoCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_SSL_OUTSIDE, sSslCreditsCameraPositions, sSslCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_DDD_WHIRLPOOL, sDddCreditsCameraPositions, sDddCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_SL_OUTSIDE, sSlCreditsCameraPositions, sSlCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_WDW_MAIN, sWdwCreditsCameraPositions, sWdwCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_TTM_OUTSIDE, sTtmCreditsCameraPositions, sTtmCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_THI_HUGE, sThiHugeCreditsCameraPositions, sThiHugeCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_TTC, sTtcCreditsCameraPositions, sTtcCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_RR, sRrCreditsCameraPositions, sRrCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_SA, sSaCreditsCameraPositions, sSaCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_COTMC, sCotmcCreditsCameraPositions, sCotmcCreditsCameraFocus); - SET_CREDITS_PRESET(AREA_DDD_SUB, sDddSubCreditsCameraPositions, sDddSubCreditsCameraFocus); + SET_CREDITS_SPLINE(AREA_BOB, sBobCreditsSpline); + SET_CREDITS_SPLINE(AREA_WF, sWfCreditsSpline); + SET_CREDITS_SPLINE(AREA_JRB_MAIN, sJrbCreditsSpline); + SET_CREDITS_SPLINE(AREA_CCM_SLIDE, sCcmSlideCreditsSpline); + SET_CREDITS_SPLINE(AREA_BBH, sBbhCreditsSpline); + SET_CREDITS_SPLINE(AREA_HMC, sHmcCreditsSpline); + SET_CREDITS_SPLINE(AREA_THI_WIGGLER, sThiWigglerCreditsSpline); + SET_CREDITS_SPLINE(AREA_LLL_VOLCANO, sVolcanoCreditsSpline); + SET_CREDITS_SPLINE(AREA_SSL_OUTSIDE, sSslCreditsSpline); + SET_CREDITS_SPLINE(AREA_DDD_WHIRLPOOL, sDddCreditsSpline); + SET_CREDITS_SPLINE(AREA_SL_OUTSIDE, sSlCreditsSpline); + SET_CREDITS_SPLINE(AREA_WDW_MAIN, sWdwCreditsSpline); + SET_CREDITS_SPLINE(AREA_TTM_OUTSIDE, sTtmCreditsSpline); + SET_CREDITS_SPLINE(AREA_THI_HUGE, sThiHugeCreditsSpline); + SET_CREDITS_SPLINE(AREA_TTC, sTtcCreditsSpline); + SET_CREDITS_SPLINE(AREA_RR, sRrCreditsSpline); + SET_CREDITS_SPLINE(AREA_SA, sSaCreditsSpline); + SET_CREDITS_SPLINE(AREA_COTMC, sCotmcCreditsSpline); + SET_CREDITS_SPLINE(AREA_DDD_SUB, sDddSubCreditsSpline); case AREA_CCM_OUTSIDE: + //! Checks if the "Snowman's Lost His Head" star was collected. The credits likely would + //! have avoided the snowman if the player didn't collect that star, but in the end the + //! developers decided against it. if (save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1) & 0x10) { - pos = sCcmOutsideCreditsCameraPositions; - focus = sCcmOutsideCreditsCameraFocus; + pos = sCcmOutsideCreditsSplinePositions; + focus = sCcmOutsideCreditsSplineFocus; } else { - pos = sCcmOutsideCreditsCameraPositions; - focus = sCcmOutsideCreditsCameraFocus; + pos = sCcmOutsideCreditsSplinePositions; + focus = sCcmOutsideCreditsSplineFocus; } break; default: - pos = sCcmOutsideCreditsCameraPositions; - focus = sCcmOutsideCreditsCameraFocus; + pos = sCcmOutsideCreditsSplinePositions; + focus = sCcmOutsideCreditsSplineFocus; } +#undef SET_CREDITS_SPLINE -#undef SET_CREDITS_PRESET - - func_8028FBD8(D_8033B4E0, pos); - func_8028FBD8(D_8033B5E0, focus); - move_point_along_spline(c->pos, D_8033B4E0, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_point_along_spline(c->focus, D_8033B5E0, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); - move_credits_camera(c, -0x2000, 0x2000, -0x4000, 0x4000); + copy_spline_segment(sCurCreditsSplinePos, pos); + copy_spline_segment(sCurCreditsSplineFocus, focus); + move_point_along_spline(c->pos, sCurCreditsSplinePos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + move_point_along_spline(c->focus, sCurCreditsSplineFocus, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); + player2_rotate_cam(c, -0x2000, 0x2000, -0x4000, 0x4000); } -CmdRet CutsceneSlidingDoorsOpen0_1(struct LevelCamera *c) { +/** + * Set the camera pos relative to mario. + */ +CmdRet cutscene_sliding_doors_open_start(struct Camera *c) { f32 dist; s16 pitch, yaw; - vec3f_get_dist_and_angle(sMarioStatusForCamera->pos, c->pos, &dist, &pitch, &yaw); + vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); + // If the camera is too close, warp it backwards set it to a better angle. if (dist < 500.f) { dist = 500.f; - yaw = sMarioStatusForCamera->faceAngle[1] + 0x8800; + yaw = sMarioCamState->faceAngle[1] + 0x8800; pitch = 0x800; } - vec3f_set_dist_and_angle(sMarioStatusForCamera->pos, c->pos, dist, pitch, yaw); + vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet CutsceneSlidingDoorsOpen0_2(UNUSED struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[1].unk4, sMarioStatusForCamera->pos); - vec3s_copy(D_8033B6F0[0].unk1C, sMarioStatusForCamera->faceAngle); - vec3f_set(D_8033B6F0[0].unk4, 80.f, 325.f, 200.f); +/** + * cvar1: mario's position + * cvar0.angle: mario's angle + * cvar0.point: offset from mario + */ +CmdRet cutscene_sliding_doors_open_set_cvars(UNUSED struct Camera *c) { + vec3f_copy(sCutsceneVars[1].point, sMarioCamState->pos); + vec3s_copy(sCutsceneVars[0].angle, sMarioCamState->faceAngle); + vec3f_set(sCutsceneVars[0].point, 80.f, 325.f, 200.f); } -CmdRet CutsceneSlidingDoorsOpen0_3(UNUSED struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&D_8033B6F0[0].unk4[1], 75.f, 10.f); +/** + * Decrease the cvar0 y offset to 75, which would simulate lakitu flying under the doorway. + * However, the initial y offset is too high for lakitu to reach 75 in time. + */ +CmdRet cutscene_sliding_doors_go_under_doorway(UNUSED struct Camera *c) { + camera_approach_f32_symmetric_bool(&sCutsceneVars[0].point[1], 75.f, 10.f); } -CmdRet CutsceneSlidingDoorsOpen0_4(UNUSED struct LevelCamera *c) { - camera_approach_f32_symmetric_bool(&D_8033B6F0[0].unk4[1], 125.f, 10.f); +/** + * Approach a y offset of 125 again. + */ +CmdRet cutscene_sliding_doors_fly_back_up(UNUSED struct Camera *c) { + camera_approach_f32_symmetric_bool(&sCutsceneVars[0].point[1], 125.f, 10.f); } -CmdRet CutsceneSlidingDoorsOpen0_5(struct LevelCamera *c) { - Vec3f sp34; +/** + * Follow mario through the door, by approaching cvar1.point. + */ +CmdRet cutscene_sliding_doors_follow_mario(struct Camera *c) { + Vec3f pos; UNUSED u32 pad[4]; - vec3f_copy(sp34, c->pos); - D_8033B6F0[1].unk4[0] = sMarioStatusForCamera->pos[0]; - D_8033B6F0[1].unk4[2] = sMarioStatusForCamera->pos[2]; - approach_f32_exponential_bool(&D_8033B6F0[0].unk4[0], 0, 0.1f); - camera_approach_f32_symmetric_bool(&D_8033B6F0[0].unk4[2], 125.f, 50.f); - approach_vec3s_exponential(D_8033B6F0[0].unk1C, sMarioStatusForCamera->faceAngle, 16, 16, 16); - set_pos_from_face_angle_and_vec3f(sp34, D_8033B6F0[1].unk4, D_8033B6F0[0].unk4, - D_8033B6F0[0].unk1C); - approach_vec3f_exponential(c->pos, sp34, 0.15f, 0.05f, 0.15f); - set_focus_position(c, 0, 125.f, 0, 0); + vec3f_copy(pos, c->pos); + // Update cvar1 with mario's position (the y value doesn't change) + sCutsceneVars[1].point[0] = sMarioCamState->pos[0]; + sCutsceneVars[1].point[2] = sMarioCamState->pos[2]; + + // Decrease cvar0's offsets, moving the camera behind mario at his eye height. + approach_f32_asymptotic_bool(&sCutsceneVars[0].point[0], 0, 0.1f); + camera_approach_f32_symmetric_bool(&sCutsceneVars[0].point[2], 125.f, 50.f); + // Update cvar0's angle + approach_vec3s_asymptotic(sCutsceneVars[0].angle, sMarioCamState->faceAngle, 16, 16, 16); + + // Apply the offset to the camera's position + offset_rotated(pos, sCutsceneVars[1].point, sCutsceneVars[0].point, sCutsceneVars[0].angle); + approach_vec3f_asymptotic(c->pos, pos, 0.15f, 0.05f, 0.15f); + + // Focus on mario's eye height + set_focus_rel_mario(c, 0, 125.f, 0, 0); } -CmdRet CutsceneSlidingDoorsOpen0(struct LevelCamera *c) { +/** + * Plays when mario opens the sliding doors. + * Note: the star door unlocking event is not a cutscene, it's handled by mario separately. + */ +CmdRet cutscene_sliding_doors_open(struct Camera *c) { UNUSED u32 pad[2]; - func_8028FEDC(c); - call_cutscene_func_in_time_range(CutsceneSlidingDoorsOpen0_1, c, 0, 8); - call_cutscene_func_in_time_range(CutsceneSlidingDoorsOpen0_2, c, 8, 8); - call_cutscene_func_in_time_range(CutsceneSlidingDoorsOpen0_3, c, 8, 28); - call_cutscene_func_in_time_range(CutsceneSlidingDoorsOpen0_4, c, 29, -1); - call_cutscene_func_in_time_range(CutsceneSlidingDoorsOpen0_5, c, 8, -1); + reset_pan_distance(c); + cutscene_event(cutscene_sliding_doors_open_start, c, 0, 8); + cutscene_event(cutscene_sliding_doors_open_set_cvars, c, 8, 8); + cutscene_event(cutscene_sliding_doors_go_under_doorway, c, 8, 28); + cutscene_event(cutscene_sliding_doors_fly_back_up, c, 29, -1); + cutscene_event(cutscene_sliding_doors_follow_mario, c, 8, -1); } -CmdRet CutsceneDoubleDoorsOpen1(struct LevelCamera *c) { - func_80290514(c); +/** + * Ends the double door cutscene. + */ +CmdRet cutscene_double_doors_end(struct Camera *c) { + set_flag_post_door(c); c->cutscene = 0; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet CutsceneEnterPainting0_1(UNUSED struct LevelCamera *c) { +CmdRet cutscene_enter_painting_stub(UNUSED struct Camera *c) { } -CmdRet CutsceneEnterPainting0(struct LevelCamera *c) { +/** + * Plays when mario enters a painting. The camera flies up to the painting's center, then it slowly + * zooms in until the star select screen appears. + */ +CmdRet cutscene_enter_painting(struct Camera *c) { struct Surface *floor, *highFloor; - Vec3f sp44, sp38, sp2C; - Vec3s sp24; + Vec3f paintingPos, focus, focusOffset; + Vec3s paintingAngle; f32 floorHeight; - call_cutscene_func_in_time_range(CutsceneEnterPainting0_1, c, 0, 0); - set_fov_function(6); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + cutscene_event(cutscene_enter_painting_stub, c, 0, 0); + // Zoom in + set_fov_function(CAM_FOV_APP_20); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; if (ripplingPainting != NULL) { - sp24[0] = 0; - sp24[1] = (ripplingPainting->vYRotation / 360.f) * 65536.f; // convert degrees to IAU - sp24[2] = 0; + paintingAngle[0] = 0; + paintingAngle[1] = (s32)((ripplingPainting->vYRotation / 360.f) * 65536.f); // convert degrees to IAU + paintingAngle[2] = 0; - sp2C[0] = ripplingPainting->vSize / 2.0f; - sp2C[1] = sp2C[0]; - sp2C[2] = 0; + focusOffset[0] = ripplingPainting->vSize / 2.0f; + focusOffset[1] = focusOffset[0]; + focusOffset[2] = 0; - sp44[0] = ripplingPainting->vXPos; - sp44[1] = ripplingPainting->vYPos; - sp44[2] = ripplingPainting->vZPos; + paintingPos[0] = ripplingPainting->vXPos; + paintingPos[1] = ripplingPainting->vYPos; + paintingPos[2] = ripplingPainting->vZPos; - set_pos_from_face_angle_and_vec3f(sp38, sp44, sp2C, sp24); - approach_vec3f_exponential(c->focus, sp38, 0.1f, 0.1f, 0.1f); - sp2C[2] = -(((ripplingPainting->vSize * 1000.f) / 2.0f) / 307.f); - set_pos_from_face_angle_and_vec3f(sp38, sp44, sp2C, sp24); - floorHeight = find_floor(sp38[0], sp38[1] + 500.f, sp38[2], &highFloor) + 125.f; + offset_rotated(focus, paintingPos, focusOffset, paintingAngle); + approach_vec3f_asymptotic(c->focus, focus, 0.1f, 0.1f, 0.1f); + focusOffset[2] = -(((ripplingPainting->vSize * 1000.f) / 2.0f) / 307.f); + offset_rotated(focus, paintingPos, focusOffset, paintingAngle); + floorHeight = find_floor(focus[0], focus[1] + 500.f, focus[2], &highFloor) + 125.f; - if (sp38[1] < floorHeight) { - sp38[1] = floorHeight; + if (focus[1] < floorHeight) { + focus[1] = floorHeight; } if (c->cutscene == CUTSCENE_ENTER_PAINTING) { - approach_vec3f_exponential(c->pos, sp38, 0.2f, 0.1f, 0.2f); + approach_vec3f_asymptotic(c->pos, focus, 0.2f, 0.1f, 0.2f); } else { - approach_vec3f_exponential(c->pos, sp38, 0.9f, 0.9f, 0.9f); + approach_vec3f_asymptotic(c->pos, focus, 0.9f, 0.9f, 0.9f); } - find_floor(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 50.f, - sMarioStatusForCamera->pos[2], &floor); + find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 50.f, sMarioCamState->pos[2], &floor); if ((floor->type < SURFACE_PAINTING_WOBBLE_A6) || (floor->type > SURFACE_PAINTING_WARP_F9)) { c->cutscene = 0; - gCutsceneTimer = 0x8000; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; + gCutsceneTimer = CUTSCENE_STOP; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } } - c->currPreset = CAMERA_PRESET_CLOSE; + c->mode = CAMERA_MODE_CLOSE; } -CmdRet CutsceneExitPainting80298094(struct LevelCamera *c) { +/** + * Warp the camera to mario, then use his faceAngle to calculate the right relative position. + * + * cvar0.point is mario's position + * cvar0.angle is mario's faceAngle + * + * cvar1 is the camera's position relative to mario + * cvar2 is the camera's focus relative to mario + */ +CmdRet cutscene_exit_painting_start(struct Camera *c) { struct Surface *floor; f32 floorHeight; - vec3f_set(D_8033B6F0[2].unk4, 258.f, -352.f, 1189.f); - vec3f_set(D_8033B6F0[1].unk4, 65.f, -155.f, 444.f); + vec3f_set(sCutsceneVars[2].point, 258.f, -352.f, 1189.f); + vec3f_set(sCutsceneVars[1].point, 65.f, -155.f, 444.f); if (gPrevLevel == LEVEL_TTM) { - D_8033B6F0[1].unk4[1] = 0.f; - D_8033B6F0[1].unk4[2] = 0.f; + sCutsceneVars[1].point[1] = 0.f; + sCutsceneVars[1].point[2] = 0.f; } - vec3f_copy(D_8033B6F0[0].unk4, sMarioStatusForCamera->pos); - D_8033B6F0[0].unk1C[0] = 0; - D_8033B6F0[0].unk1C[1] = sMarioStatusForCamera->faceAngle[1]; - D_8033B6F0[0].unk1C[2] = 0; - set_pos_from_face_angle_and_vec3f(c->focus, D_8033B6F0[0].unk4, D_8033B6F0[1].unk4, - D_8033B6F0[0].unk1C); - set_pos_from_face_angle_and_vec3f(c->pos, D_8033B6F0[0].unk4, D_8033B6F0[2].unk4, - D_8033B6F0[0].unk1C); + vec3f_copy(sCutsceneVars[0].point, sMarioCamState->pos); + sCutsceneVars[0].angle[0] = 0; + sCutsceneVars[0].angle[1] = sMarioCamState->faceAngle[1]; + sCutsceneVars[0].angle[2] = 0; + offset_rotated(c->focus, sCutsceneVars[0].point, sCutsceneVars[1].point, sCutsceneVars[0].angle); + offset_rotated(c->pos, sCutsceneVars[0].point, sCutsceneVars[2].point, sCutsceneVars[0].angle); floorHeight = find_floor(c->pos[0], c->pos[1] + 10.f, c->pos[2], &floor); if (floorHeight != -11000.f) { @@ -7966,118 +9931,147 @@ CmdRet CutsceneExitPainting80298094(struct LevelCamera *c) { } } -CmdRet CutsceneExitPainting80298230(struct LevelCamera *c) { - Vec3f sp1C; +/** + * Decrease cvar2's x and z offset, moving closer to mario. + */ +CmdRet cutscene_exit_painting_move_to_mario(struct Camera *c) { + Vec3f pos; - approach_f32_exponential_bool(&D_8033B6F0[2].unk4[0], 178.f, 0.05f); - approach_f32_exponential_bool(&D_8033B6F0[2].unk4[2], 889.f, 0.05f); - set_pos_from_face_angle_and_vec3f(sp1C, D_8033B6F0[0].unk4, D_8033B6F0[2].unk4, - D_8033B6F0[0].unk1C); - c->pos[0] = sp1C[0]; - c->pos[2] = sp1C[2]; + //! Tricky math: Since offset_rotated() flips Z offsets, you'd expect a positive Z offset to move + //! the camera into the wall. However, mario's faceAngle always points into the painting, so a + //! positive Z offset moves the camera "behind" mario, away from the painting. + //! + //! In the success cutscene, when mario jumps out face-first, only his gfx angle is updated. His + //! actual face angle isn't updated until after the cutscene. + approach_f32_asymptotic_bool(&sCutsceneVars[2].point[0], 178.f, 0.05f); + approach_f32_asymptotic_bool(&sCutsceneVars[2].point[2], 889.f, 0.05f); + offset_rotated(pos, sCutsceneVars[0].point, sCutsceneVars[2].point, sCutsceneVars[0].angle); + c->pos[0] = pos[0]; + c->pos[2] = pos[2]; } -CmdRet CutsceneExitPainting802982CC(struct LevelCamera *c) { +/** + * Move the camera down to the floor mario lands on. + */ +CmdRet cutscene_exit_painting_move_to_floor(struct Camera *c) { struct Surface *floor; Vec3f floorHeight; - vec3f_copy(floorHeight, sMarioStatusForCamera->pos); - floorHeight[1] = find_floor(sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 10.f, - sMarioStatusForCamera->pos[2], &floor); + vec3f_copy(floorHeight, sMarioCamState->pos); + floorHeight[1] = find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 10.f, sMarioCamState->pos[2], &floor); if (floor != NULL) { - floorHeight[1] = - floorHeight[1] + (sMarioStatusForCamera->pos[1] - floorHeight[1]) * 0.7f + 125.f; - approach_vec3f_exponential(c->focus, floorHeight, 0.2f, 0.2f, 0.2f); + floorHeight[1] = floorHeight[1] + (sMarioCamState->pos[1] - floorHeight[1]) * 0.7f + 125.f; + approach_vec3f_asymptotic(c->focus, floorHeight, 0.2f, 0.2f, 0.2f); if (floorHeight[1] < c->pos[1]) { - approach_f32_exponential_bool(&c->pos[1], floorHeight[1], 0.05f); + approach_f32_asymptotic_bool(&c->pos[1], floorHeight[1], 0.05f); } } } -CmdRet CutsceneExitPainting0(struct LevelCamera *c) { - call_cutscene_func_in_time_range(CutsceneExitPainting80298094, c, 0, 0); - call_cutscene_func_in_time_range(CutsceneExitPainting80298230, c, 5, -1); - call_cutscene_func_in_time_range(CutsceneExitPainting802982CC, c, 5, -1); +/** + * Cutscene played when mario leaves a painting, either due to death or collecting a star. + */ +CmdRet cutscene_exit_painting(struct Camera *c) { + cutscene_event(cutscene_exit_painting_start, c, 0, 0); + cutscene_event(cutscene_exit_painting_move_to_mario, c, 5, -1); + cutscene_event(cutscene_exit_painting_move_to_floor, c, 5, -1); + //! Hardcoded position. TTM's painting is close to an opposite wall, so just fix the pos. if (gPrevLevel == LEVEL_TTM) { vec3f_set(c->pos, -296.f, 1261.f, 3521.f); } - set_cam_yaw_from_focus_and_pos(c); + update_camera_yaw(c); } -CmdRet Cutscene11Todo_0(struct LevelCamera *c) { - UNUSED Vec3f sp3C; - UNUSED Vec3s sp34; - Vec3f sp28; - Vec3s sp20; +/** + * Unused. Warp the camera to mario. + */ +CmdRet cutscene_unused_exit_start(struct Camera *c) { + UNUSED Vec3f unused1; + UNUSED Vec3s unused2; + Vec3f offset; + Vec3s marioAngle; - vec3f_set(sp28, 200.f, 300.f, 200.f); - vec3s_set(sp20, 0, sMarioStatusForCamera->faceAngle[1], 0); - set_pos_from_face_angle_and_vec3f(c->pos, sMarioStatusForCamera->pos, sp28, sp20); - set_focus_position(c, 0.f, 125.f, 0.f, 0); + vec3f_set(offset, 200.f, 300.f, 200.f); + vec3s_set(marioAngle, 0, sMarioCamState->faceAngle[1], 0); + offset_rotated(c->pos, sMarioCamState->pos, offset, marioAngle); + set_focus_rel_mario(c, 0.f, 125.f, 0.f, 0); } -CmdRet Cutscene11Todo_1(struct LevelCamera *c) { - Vec3f sp24; +/** + * Unused. Focus on mario as he exits. + */ +CmdRet cutscene_unused_exit_focus_mario(struct Camera *c) { + Vec3f focus; - vec3f_set(sp24, sMarioStatusForCamera->pos[0], sMarioStatusForCamera->pos[1] + 125.f, - sMarioStatusForCamera->pos[2]); - set_focus_position(c, 0.f, 125.f, 0.f, 0); - approach_vec3f_exponential(c->focus, sp24, 0.02f, 0.001f, 0.02f); - set_cam_yaw_from_focus_and_pos(c); + vec3f_set(focus, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); + set_focus_rel_mario(c, 0.f, 125.f, 0.f, 0); + approach_vec3f_asymptotic(c->focus, focus, 0.02f, 0.001f, 0.02f); + update_camera_yaw(c); } -CmdRet CutsceneExitPainting1(struct LevelCamera *c) { - c->currPreset = CAMERA_PRESET_CLOSE; +/** + * Give control back to the player. + */ +CmdRet cutscene_exit_painting_end(struct Camera *c) { + c->mode = CAMERA_MODE_CLOSE; c->cutscene = 0; - gCutsceneTimer = 0x8000; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_1; - set_cam_yaw_from_focus_and_pos(c); + gCutsceneTimer = CUTSCENE_STOP; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sStatusFlags &= ~CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; + update_camera_yaw(c); } -CmdRet CutsceneEnterCannon2(struct LevelCamera *c) { - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraFlags2 |= CAM_FLAG_2_UNKNOWN_1; - c->currPreset = CAMERA_PRESET_INSIDE_CANNON; +/** + * End the cutscene, starting cannon mode. + */ +CmdRet cutscene_enter_cannon_end(struct Camera *c) { + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + sStatusFlags |= CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; + c->mode = CAMERA_MODE_INSIDE_CANNON; c->cutscene = 0; - D_8033B410 = 800.f; + sCannonYOffset = 800.f; } -CmdRet CutsceneEnterCannon1(struct LevelCamera *c) { +/** + * Rotate around the cannon as it rises out of the hole. + */ +CmdRet cutscene_enter_cannon_raise(struct Camera *c) { struct Object *o; UNUSED u32 pad[2]; f32 floorHeight; struct Surface *floor; - Vec3f pitch; - Vec3s yaw; + Vec3f cannonFocus; + Vec3s cannonAngle; - call_cutscene_func_in_time_range(CutsceneEnterSomething8029041C, c, 70, 70); - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - camera_approach_s16_symmetric_bool(&D_8033B6F0[1].unk1C[0], 0, 0x80); - camera_approach_s16_symmetric_bool(&D_8033B6F0[2].unk1C[0], 0, 0x80); - vec3f_set_dist_and_angle(D_8033B6F0[0].unk4, c->pos, D_8033B6F0[1].unk4[2], D_8033B6F0[1].unk1C[0], - D_8033B6F0[1].unk1C[1]); - D_8033B6F0[1].unk4[2] = approach_f32(D_8033B6F0[1].unk4[2], 400.f, 5.f, 5.f); - D_8033B6F0[1].unk1C[1] += 0x40; - D_8033B6F0[3].unk4[1] += 2.f; - c->pos[1] += D_8033B6F0[3].unk4[1]; + // Shake the camera when the cannon is fully raised + cutscene_event(cutscene_shake_explosion, c, 70, 70); + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + camera_approach_s16_symmetric_bool(&sCutsceneVars[1].angle[0], 0, 0x80); + camera_approach_s16_symmetric_bool(&sCutsceneVars[2].angle[0], 0, 0x80); + // Move the camera around the cannon, gradually rotating and moving closer + vec3f_set_dist_and_angle(sCutsceneVars[0].point, c->pos, sCutsceneVars[1].point[2], sCutsceneVars[1].angle[0], + sCutsceneVars[1].angle[1]); + sCutsceneVars[1].point[2] = approach_f32(sCutsceneVars[1].point[2], 400.f, 5.f, 5.f); + sCutsceneVars[1].angle[1] += 0x40; + sCutsceneVars[3].point[1] += 2.f; + c->pos[1] += sCutsceneVars[3].point[1]; - if ((o = sMarioStatusForCamera->usedObj) != NULL) { - D_8033B6F0[0].unk4[1] = o->oPosY; - yaw[0] = o->oMoveAnglePitch; - yaw[1] = o->oMoveAngleYaw; - yaw[2] = o->oMoveAngleRoll; + if ((o = sMarioCamState->usedObj) != NULL) { + sCutsceneVars[0].point[1] = o->oPosY; + cannonAngle[0] = o->oMoveAnglePitch; + cannonAngle[1] = o->oMoveAngleYaw; + cannonAngle[2] = o->oMoveAngleRoll; c->focus[0] = o->oPosX; c->focus[1] = o->oPosY; c->focus[2] = o->oPosZ; - pitch[0] = 0.f; - pitch[1] = 100.f; - pitch[2] = 0.f; - set_pos_from_face_angle_and_vec3f(c->focus, c->focus, pitch, yaw); + cannonFocus[0] = 0.f; + cannonFocus[1] = 100.f; + cannonFocus[2] = 0.f; + offset_rotated(c->focus, c->focus, cannonFocus, cannonAngle); } floorHeight = find_floor(c->pos[0], c->pos[1] + 500.f, c->pos[2], &floor) + 100.f; @@ -8087,269 +10081,555 @@ CmdRet CutsceneEnterCannon1(struct LevelCamera *c) { } } -CmdRet CutsceneEnterCannon0(struct LevelCamera *c) { - UNUSED u32 pad[2]; +/** + * Start the cannon entering cutscene + */ +CmdRet cutscene_enter_cannon_start(struct Camera *c) { + UNUSED u32 cvar3Start; + UNUSED u32 cvar4Start; struct Object *o; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - sMarioStatusForCamera->unk1C[1] = 0; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sMarioCamState->cameraEvent = 0; - if ((o = sMarioStatusForCamera->usedObj) != NULL) { - D_8033B6F0[0].unk4[0] = o->oPosX; - D_8033B6F0[0].unk4[1] = o->oPosY; - D_8033B6F0[0].unk4[2] = o->oPosZ; - D_8033B6F0[0].unk1C[0] = o->oMoveAnglePitch; - D_8033B6F0[0].unk1C[1] = o->oMoveAngleYaw; - D_8033B6F0[0].unk1C[2] = o->oMoveAngleRoll; + // Store the cannon's position and angle in cvar0 + if ((o = sMarioCamState->usedObj) != NULL) { + sCutsceneVars[0].point[0] = o->oPosX; + sCutsceneVars[0].point[1] = o->oPosY; + sCutsceneVars[0].point[2] = o->oPosZ; + sCutsceneVars[0].angle[0] = o->oMoveAnglePitch; + sCutsceneVars[0].angle[1] = o->oMoveAngleYaw; + sCutsceneVars[0].angle[2] = o->oMoveAngleRoll; } - vec3f_get_dist_and_angle(D_8033B6F0[0].unk4, c->pos, &D_8033B6F0[1].unk4[2], - &D_8033B6F0[1].unk1C[0], &D_8033B6F0[1].unk1C[1]); - D_8033B6F0[3].unk4[1] = 0.f; - D_8033B6F0[4].unk4[1] = 0.f; + // Store the camera's polar offset from the cannon in cvar1 + vec3f_get_dist_and_angle(sCutsceneVars[0].point, c->pos, &sCutsceneVars[1].point[2], + &sCutsceneVars[1].angle[0], &sCutsceneVars[1].angle[1]); + sCutsceneVars[3].point[1] = 0.f; + //! cvar4 is unused in this cutscene + sCutsceneVars[4].point[1] = 0.f; } -CmdRet CutsceneDoor0(struct LevelCamera *c) { - vec3f_copy(D_8033B6F0[0].unk4, c->pos); - vec3f_copy(D_8033B6F0[1].unk4, c->focus); +/** + * Store the camera's pos and focus for the door cutscene + */ +CmdRet cutscene_door_start(struct Camera *c) { + vec3f_copy(sCutsceneVars[0].point, c->pos); + vec3f_copy(sCutsceneVars[1].point, c->focus); } -CmdRet CutsceneDoor1(struct LevelCamera *c) { - vec3f_copy(c->pos, D_8033B6F0[0].unk4); - vec3f_copy(c->focus, D_8033B6F0[1].unk4); +/** + * Fix the camera in place while the door opens. + */ +CmdRet cutscene_door_fix_cam(struct Camera *c) { + vec3f_copy(c->pos, sCutsceneVars[0].point); + vec3f_copy(c->focus, sCutsceneVars[1].point); } -CmdRet CutsceneDoorWarp1(struct LevelCamera *c) { - if ((sMarioStatusForCamera->action != ACT_PULLING_DOOR) - & (sMarioStatusForCamera->action != ACT_PUSHING_DOOR)) //! bitwise AND instead of boolean - { - gCutsceneTimer = 0x8000; +/** + * Loop until mario is no longer using the door. + */ +CmdRet cutscene_door_loop(struct Camera *c) { + //! bitwise AND instead of boolean + if ((sMarioCamState->action != ACT_PULLING_DOOR) & (sMarioCamState->action != ACT_PUSHING_DOOR)) { + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; } } -CmdRet CutsceneDoor2(struct LevelCamera *c) { - Vec3f sp24; - s16 sp22; +/** + * Warp the camera behind mario. + */ +CmdRet cutscene_door_move_behind_mario(struct Camera *c) { + Vec3f camOffset; + s16 doorRotation; - func_8028FEDC(c); - determine_pushing_or_pulling_door(&sp22); - set_focus_position(c, 0.f, 125.f, 0.f, 0); - vec3s_set(D_8033B6F0[0].unk1C, 0, sMarioStatusForCamera->faceAngle[1] + sp22, 0); - vec3f_set(sp24, 0.f, 125.f, 250.f); + reset_pan_distance(c); + determine_pushing_or_pulling_door(&doorRotation); + set_focus_rel_mario(c, 0.f, 125.f, 0.f, 0); + vec3s_set(sCutsceneVars[0].angle, 0, sMarioCamState->faceAngle[1] + doorRotation, 0); + vec3f_set(camOffset, 0.f, 125.f, 250.f); - if (sp22 == 0) { //! useless code - sp24[0] = 0.f; + if (doorRotation == 0) { //! useless code + camOffset[0] = 0.f; } else { - sp24[0] = 0.f; + camOffset[0] = 0.f; } - set_pos_from_face_angle_and_vec3f(c->pos, sMarioStatusForCamera->pos, sp24, D_8033B6F0[0].unk1C); + offset_rotated(c->pos, sMarioCamState->pos, camOffset, sCutsceneVars[0].angle); } -CmdRet CutsceneDoor3(struct LevelCamera *c) { +/** + * Follow mario through the door. + */ +CmdRet cutscene_door_follow_mario(struct Camera *c) { s16 pitch, yaw; f32 dist; - set_focus_position(c, 0.f, 125.f, 0.f, 0); + set_focus_rel_mario(c, 0.f, 125.f, 0.f, 0); vec3f_get_dist_and_angle(c->focus, c->pos, &dist, &pitch, &yaw); camera_approach_f32_symmetric_bool(&dist, 150.f, 7.f); vec3f_set_dist_and_angle(c->focus, c->pos, dist, pitch, yaw); - set_cam_yaw_from_focus_and_pos(c); + update_camera_yaw(c); } -CmdRet CutsceneDoor4(struct LevelCamera *c) { - if (c->defPreset == CAMERA_PRESET_FREE_ROAM) { - c->currPreset = CAMERA_PRESET_FREE_ROAM; +/** + * Ends the door cutscene. Sets the camera mode to close mode unless the default is free roam. + */ +CmdRet cutscene_door_end(struct Camera *c) { + if (c->defMode == CAMERA_MODE_FREE_ROAM) { + c->mode = CAMERA_MODE_FREE_ROAM; } else { - c->currPreset = CAMERA_PRESET_CLOSE; + c->mode = CAMERA_MODE_CLOSE; } c->cutscene = 0; - gCutsceneTimer = 0x8000; - gCameraFlags2 |= CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraFlags2 &= ~CAM_FLAG_2_UNKNOWN_1; - func_80290514(c); - set_cam_yaw_from_focus_and_pos(c); + gCutsceneTimer = CUTSCENE_STOP; + sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; + sStatusFlags &= ~CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; + set_flag_post_door(c); + update_camera_yaw(c); } -CmdRet CutsceneDoorAB_2(struct LevelCamera *c) { +/** + * Used for entering a room that uses a specific camera mode, like the castle lobby or BBH + */ +CmdRet cutscene_door_mode(struct Camera *c) { UNUSED u32 pad[2]; - func_8028FEDC(c); - level_specific_camera_update(c); + reset_pan_distance(c); + camera_course_processing(c); - if (c->currPreset == CAMERA_PRESET_FIXED_REF_POINT) { - c->storedYaw = return_fixed_camera_yaw(c, c->focus, c->pos); + if (c->mode == CAMERA_MODE_FIXED) { + c->nextYaw = update_fixed_camera(c, c->focus, c->pos); } - if (c->currPreset == CAMERA_PRESET_PARALLEL_TRACKING) { - c->storedYaw = return_parallel_tracking_camera_yaw(c, c->focus, c->pos); + if (c->mode == CAMERA_MODE_PARALLEL_TRACKING) { + c->nextYaw = update_parallel_tracking_camera(c, c->focus, c->pos); } - c->trueYaw = c->storedYaw; + c->yaw = c->nextYaw; - if ((sMarioStatusForCamera->action != ACT_ENTERING_STAR_DOOR) - && (sMarioStatusForCamera->action != ACT_PULLING_DOOR) - && (sMarioStatusForCamera->action != ACT_PUSHING_DOOR)) { - gCutsceneTimer = 0x8000; + // Loop until mario is no longer using the door + if (sMarioCamState->action != ACT_ENTERING_STAR_DOOR && + sMarioCamState->action != ACT_PULLING_DOOR && + sMarioCamState->action != ACT_PUSHING_DOOR) { + gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; } } -// Cutscene Tables -struct CutsceneTableEntry TableCutscenePeachEnd[12] = { - { CutscenePeachEnd0, 170 }, { CutscenePeachEnd1, 70 }, { CutscenePeachEnd2, 75 }, - { CutscenePeachEnd3, 386 }, { CutscenePeachEnd4, 139 }, { CutscenePeachEnd5, 590 }, - { CutscenePeachEnd6, 95 }, { CutscenePeachEnd7, 425 }, { CutscenePeachEnd8, 236 }, - { CutscenePeachEnd9, 245 }, { CutscenePeachEndA, 32767 }, { CutscenePeachEndB, 0 } +/****************************************************************************************************** + * Cutscenes + ******************************************************************************************************/ + +/** + * Cutscene that plays when mario beats the game. + */ +struct Cutscene sCutsceneEnding[] = { + { cutscene_ending_mario_fall, 170 }, + { cutscene_ending_mario_land, 70 }, + { cutscene_ending_mario_land_closeup, 75 }, + { cutscene_ending_stars_free_peach, 386 }, + { cutscene_ending_peach_appears, 139 }, + { cutscene_ending_peach_descends, 590 }, + { cutscene_ending_mario_to_peach, 95 }, + { cutscene_ending_peach_wakeup, 425 }, + { cutscene_ending_dialog, 236 }, + { cutscene_ending_kiss, 245 }, + { cutscene_ending_cake_for_mario, CUTSCENE_LOOP }, + { cutscene_ending_stop, 0 } }; -struct CutsceneTableEntry TableCutsceneGrandStar[2] = { { CutsceneGrandStar0, 360 }, - { CutsceneGrandStar1, 32767 } }; +/** + * Cutscene that plays when mario collects the grand star from bowser. + */ +struct Cutscene sCutsceneGrandStar[] = { + { cutscene_grand_star, 360 }, + { cutscene_grand_star_fly, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutscene0FTodo[2] = { { Cutscene0FTodo0, 1 }, - { Cutscene0FTodo1, 32767 } }; +struct Cutscene sCutsceneUnused[] = { + { cutscene_unused_start, 1 }, + { cutscene_unused_loop, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneDoorWarp[2] = { { CutsceneDoor0, 1 }, - { CutsceneDoorWarp1, 32767 } }; +/** + * Cutscene that plays when mario enters a door that warps to another area. + */ +struct Cutscene sCutsceneDoorWarp[] = { + { cutscene_door_start, 1 }, + { cutscene_door_loop, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneEndWaving[1] = { { CutsceneEndWaving0, 32767 } }; +/** + * Cutscene that plays after the credits, when lakitu is flying away from the castle. + */ +struct Cutscene sCutsceneEndWaving[] = { + { cutscene_end_waving, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneCredits[1] = { { CutsceneCredits0, 32767 } }; +/** + * The game's credits. + */ +struct Cutscene sCutsceneCredits[] = { + { cutscene_credits, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneDoor00[5] = { { CutsceneDoor0, 1 }, - { CutsceneDoor1, 30 }, - { CutsceneDoor2, 1 }, - { CutsceneDoor3, 50 }, - { CutsceneDoor4, 0 } }; +/** + * Cutscene that plays when mario pulls open a door. + */ +struct Cutscene sCutsceneDoorPull[] = { + { cutscene_door_start, 1 }, + { cutscene_door_fix_cam, 30 }, + { cutscene_door_move_behind_mario, 1 }, + { cutscene_door_follow_mario, 50 }, + { cutscene_door_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneDoor01[5] = { { CutsceneDoor0, 1 }, - { CutsceneDoor1, 20 }, - { CutsceneDoor2, 1 }, - { CutsceneDoor3, 50 }, - { CutsceneDoor4, 0 } }; +/** + * Cutscene that plays when mario pushes open a door. + */ +struct Cutscene sCutsceneDoorPush[] = { + { cutscene_door_start, 1 }, + { cutscene_door_fix_cam, 20 }, + { cutscene_door_move_behind_mario, 1 }, + { cutscene_door_follow_mario, 50 }, + { cutscene_door_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneDoor0A[3] = { { CutsceneDoor0, 1 }, - { CutsceneDoor1, 30 }, - { CutsceneDoorAB_2, 32767 } }; +/** + * Cutscene that plays when mario pulls open a door that has some special mode requirement on the other + * side. + */ +struct Cutscene sCutsceneDoorPullMode[] = { + { cutscene_door_start, 1 }, + { cutscene_door_fix_cam, 30 }, + { cutscene_door_mode, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneDoor0B[3] = { { CutsceneDoor0, 1 }, - { CutsceneDoor1, 20 }, - { CutsceneDoorAB_2, 32767 } }; +/** + * Cutscene that plays when mario pushes open a door that has some special mode requirement on the other + * side. + */ +struct Cutscene sCutsceneDoorPushMode[] = { + { cutscene_door_start, 1 }, + { cutscene_door_fix_cam, 20 }, + { cutscene_door_mode, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneEnterCannon[3] = { { CutsceneEnterCannon0, 1 }, - { CutsceneEnterCannon1, 121 }, - { CutsceneEnterCannon2, 0 } }; +/** + * Cutscene that plays when mario enters the cannon and it rises out of the hole. + */ +struct Cutscene sCutsceneEnterCannon[] = { + { cutscene_enter_cannon_start, 1 }, + { cutscene_enter_cannon_raise, 121 }, + { cutscene_enter_cannon_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneStarSpawn[3] = { { CutsceneStarSpawn0, 32767 }, - { CutsceneStarSpawn1, 15 }, - { CutsceneStarSpawn2, 0 } }; +/** + * Cutscene that plays when a star spawns from ie a box or after a boss fight. + */ +struct Cutscene sCutsceneStarSpawn[] = { + { cutscene_star_spawn, CUTSCENE_LOOP }, + { cutscene_star_spawn_back, 15 }, + { cutscene_star_spawn_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneSpecialStarSpawn[2] = { { CutsceneSpecialStarSpawn0, 32767 }, - { CutsceneSpecialStarSpawn1, 0 } }; +/** + * Cutscene for the red coin star spawning. Compared to a regular star, this cutscene can warp long + * distances. + */ +struct Cutscene sCutsceneRedCoinStarSpawn[] = { + { cutscene_red_coin_star, CUTSCENE_LOOP }, + { cutscene_red_coin_star_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneEnterPainting[1] = { { CutsceneEnterPainting0, 32767 } }; +/** + * Cutscene that plays when mario enters a course painting. + */ +struct Cutscene sCutsceneEnterPainting[] = { + { cutscene_enter_painting, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneDeathExit[2] = { { CutsceneExitPainting0, 118 }, - { CutsceneExitPainting1, 0 } }; +/** + * Cutscene that plays when mario dies and warps back to the castle. + */ +struct Cutscene sCutsceneDeathExit[] = { + { cutscene_exit_painting, 118 }, + { cutscene_exit_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneExitPaintingSuccess[2] = { { CutsceneExitPainting0, 180 }, - { CutsceneExitPainting1, 0 } }; +/** + * Cutscene that plays when mario warps to the castle after collecting a star. + */ +struct Cutscene sCutsceneExitPaintingSuccess[] = { + { cutscene_exit_painting, 180 }, + { cutscene_exit_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutscene11Todo[3] = { { Cutscene11Todo_0, 1 }, - { Cutscene11Todo_1, 60 }, - { CutsceneExitPainting1, 0 } }; +struct Cutscene sCutsceneUnusedExit[] = { + { cutscene_unused_exit_start, 1 }, + { cutscene_unused_exit_focus_mario, 60 }, + { cutscene_exit_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneIntroPeach[5] = { { CutsceneIntroPeach0, 32767 }, - { CutsceneIntroPeach1, 35 }, - { CutsceneIntroPeach2, 820 }, - { CutsceneIntroPeach3, 270 }, - { CutsceneIntroPeach4, 32767 } }; +/** + * The intro of the game. Peach reads her letter and lakitu flies down to mario's warp pipe. + */ +struct Cutscene sCutsceneIntroPeach[] = { + { cutscene_intro_peach_letter, CUTSCENE_LOOP }, + { cutscene_intro_peach_reset_fov, 35 }, + { cutscene_intro_peach_fly_to_pipe, 820 }, + { cutscene_intro_peach_mario_appears, 270 }, + { cutscene_intro_peach_dialog, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutscenePrepareCannon[2] = { { CutscenePrepareCannon0, 170 }, - { CutscenePrepareCannon1, 0 } }; +/** + * Cutscene that plays when a cannon door is opened. + */ +struct Cutscene sCutscenePrepareCannon[] = { + { cutscene_prepare_cannon, 170 }, + { cutscene_prepare_cannon_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneExitWaterfall[2] = { { CutsceneExitWaterfall0, 52 }, - { CutsceneFallCommon1, 0 } }; +/** + * Cutscene that plays when mario enters the castle grounds after leaving CotMC through the waterfall. + */ +struct Cutscene sCutsceneExitWaterfall[] = { + { cutscene_exit_waterfall, 52 }, + { cutscene_exit_to_castle_grounds_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneFallToCastleGrounds[2] = { { CutsceneFallToCastleGrounds0, 73 }, - { CutsceneFallCommon1, 0 } }; +/** + * Cutscene that plays when mario falls from WMOTR. + */ +struct Cutscene sCutsceneFallToCastleGrounds[] = { + { cutscene_exit_fall_to_castle_grounds, 73 }, + { cutscene_exit_to_castle_grounds_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneEnterPyramidTop[2] = { { CutsceneEnterPyramidTop0, 90 }, - { CutsceneFallCommon1, 0 } }; +/** + * Cutscene that plays when mario enters the pyramid through the hole at the top. + */ +struct Cutscene sCutsceneEnterPyramidTop[] = { + { cutscene_enter_pyramid_top, 90 }, + { cutscene_exit_to_castle_grounds_end, 0 } +}; -struct CutsceneTableEntry TableCutscene26Todo[3] = { { Cutscene26Todo0, 32767 }, - { Cutscene26Todo1, 150 }, - { Cutscene26Todo2, 0 } }; +/** + * Unused cutscene for when the pyramid explodes. + */ +struct Cutscene sCutscenePyramidTopExplode[] = { + { cutscene_mario_dialog, CUTSCENE_LOOP }, + { cutscene_pyramid_top_explode, 150 }, + { cutscene_pyramid_top_explode_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneStandingDeath[1] = { { CutsceneDeath1, 32767 } }; +/** + * Cutscene that plays when mario dies while standing, or from electrocution. + */ +struct Cutscene sCutsceneStandingDeath[] = { + { cutscene_death_standing, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneEnterPool[2] = { { CutsceneEnterPool0, 100 }, - { CutsceneFallCommon1, 0 } }; +/** + * Cutscene that plays when mario enters HMC or CotMC. + */ +struct Cutscene sCutsceneEnterPool[] = { + { cutscene_enter_pool, 100 }, + { cutscene_exit_to_castle_grounds_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneDeath2[1] = { { CutsceneDeath2, 32767 } }; +/** + * Cutscene that plays when mario dies on his stomach. + */ +struct Cutscene sCutsceneDeathStomach[] = { + { cutscene_death_stomach, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneDeathOnBack[1] = { { CutsceneBBHDeath0, 32767 } }; +/** + * Cutscene that plays when mario dies on his back. + */ +struct Cutscene sCutsceneDeathOnBack[] = { + { cutscene_bbh_death, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneQuicksandDeath[2] = { { CutsceneQuicksandDeath0, 32767 }, - { CutsceneQuicksandDeath0, 32767 } }; +/** + * Cutscene that plays when mario dies in quicksand. + */ +struct Cutscene sCutsceneQuicksandDeath[] = { + { cutscene_quicksand_death, CUTSCENE_LOOP }, +}; -struct CutsceneTableEntry TableCutsceneSuffocationDeath[1] = { { Cutscene1ATodo0, 32767 } }; +/** + * Unused cutscene for ACT_WATER_DEATH, which happens when mario gets hit by an enemy under water. + */ +struct Cutscene sCutsceneWaterDeath[] = { + { cutscene_quicksand_death, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneEnterBowserPlatform[3] = { { CutsceneEnterBowserPlatform0, 180 }, - { CutsceneEnterBowserPlatform1, - 32767 }, - { CutsceneEnterBowserPlatform2, 0 } }; +/** + * Cutscene that plays when mario suffocates. + */ +struct Cutscene sCutsceneSuffocation[] = { + { cutscene_suffocation, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneStarDance1[1] = { { CutsceneStarDance1, 32767 } }; +/** + * Cutscene that plays when entering bowser's arenas. + */ +struct Cutscene sCutsceneEnterBowserArena[] = { + { cutscene_bowser_arena, 180 }, + { cutscene_bowser_arena_dialog, CUTSCENE_LOOP }, + { cutscene_bowser_arena_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneStarDance2[1] = { { CutsceneStarDance2, 32767 } }; +// The dance cutscenes are automatically stopped since reset_camera() is called after mario warps. -struct CutsceneTableEntry TableCutsceneStarDance3[1] = { { CutsceneStarDance3, 32767 } }; +/** + * Star dance cutscene. + * For the default dance, the camera moves closer to mario, then stays in place. + * For the rotate dance, the camera moves closer and rotates clockwise around mario. + */ +struct Cutscene sCutsceneDanceDefaultRotate[] = { + { cutscene_dance_default_rotate, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneKeyDance[1] = { { CutsceneKeyDance0, 32767 } }; +/** + * Star dance cutscene. + * The camera moves closer and rotates clockwise around mario. + */ +struct Cutscene sCutsceneDanceFlyAway[] = { + { cutscene_dance_fly_away, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneCapSwitchPress[1] = { { CutsceneCapSwitchPress0, 32767 } }; +/** + * Star dance cutscene. + * The camera moves in for a closeup on mario. Used in tight spaces and underwater. + */ +struct Cutscene sCutsceneDanceCloseup[] = { + { cutscene_dance_closeup, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneSlidingDoorsOpen[2] = { { CutsceneSlidingDoorsOpen0, 50 }, - { CutsceneDoubleDoorsOpen1, 0 } }; +/** + * Star dance cutscene. + * The camera moves closer and rotates clockwise around mario. + */ +struct Cutscene sCutsceneKeyDance[] = { + { cutscene_key_dance, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneUnlockKeyDoor[2] = { { CutsceneUnlockKeyDoor0, 200 }, - { CutsceneDoubleDoorsOpen1, 0 } }; +/** + * Cutscene that plays when mario presses a cap switch. + */ +struct Cutscene sCutsceneCapSwitchPress[] = { + { cutscene_cap_switch_press, CUTSCENE_LOOP } +}; -struct CutsceneTableEntry TableCutsceneExitBowserSuccess[2] = { { CutsceneExitBowserSuccess0, 190 }, - { CutsceneExitNonPainting1, 0 } }; +/** + * Cutscene that plays when mario opens a sliding star door. + */ +struct Cutscene sCutsceneSlidingDoorsOpen[] = { + { cutscene_sliding_doors_open, 50 }, + { cutscene_double_doors_end, 0 } +}; -struct CutsceneTableEntry TableCutscene1CTodo[2] = { { Cutscene1CTodo_0, 120 }, - { CutsceneExitNonPainting1, 0 } }; +/** + * Cutscene that plays when mario unlocks the basement or upstairs key door. + */ +struct Cutscene sCutsceneUnlockKeyDoor[] = { + { cutscene_unlock_key_door, 200 }, + { cutscene_double_doors_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneBBHExitSuccess[2] = { { CutsceneBBHExitSuccess0, 163 }, - { CutsceneExitNonPainting1, 0 } }; +/** + * Cutscene that plays when mario exits bowser's arena after getting the key. + */ +struct Cutscene sCutsceneExitBowserSuccess[] = { + { cutscene_exit_bowser_succ, 190 }, + { cutscene_non_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneNonPaintingDeath[2] = { { CutsceneNonPaintingDeath0, 120 }, - { CutsceneExitNonPainting1, 0 } }; +/** + * Unused cutscene for when mario dies in bowser's arena. Instead, mario just respawns at the warp pipe. + */ +struct Cutscene sCutsceneExitBowserDeath[] = { + { cutscene_exit_bowser_death, 120 }, + { cutscene_non_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneDialog[3] = { { CutsceneDialog0, 32767 }, - { CutsceneDialog1, 12 }, - { CutsceneDialog2, 0 } }; +/** + * Cutscene that plays when mario exits a non-painting course, like HMC. + */ +struct Cutscene sCutsceneExitSpecialSuccess[] = { + { cutscene_exit_non_painting_succ, 163 }, + { cutscene_non_painting_end, 0 } +}; -struct CutsceneTableEntry TableCutsceneReadMessage[3] = { { CutsceneReadMessage0, 32767 }, - { CutsceneReadMessage1, 15 }, - { CutsceneReadMessage2, 0 } }; +/** + * Cutscene that plays when mario exits from dying in a non-painting course, like HMC. + */ +struct Cutscene sCutsceneNonPaintingDeath[] = { + { cutscene_non_painting_death, 120 }, + { cutscene_non_painting_end, 0 } +}; -#define DEFINE_COURSE(_0, i1, i2, i3, i4) { i1, i2, i3, i4 }, +/** + * Cutscene that plays when mario talks to a creature. + */ +struct Cutscene sCutsceneDialog[] = { + { cutscene_dialog, CUTSCENE_LOOP }, + { cutscene_dialog_set_flag, 12 }, + { cutscene_dialog_end, 0 } +}; + +/** + * Cutscene that plays when mario reads a sign or message. + */ +struct Cutscene sCutsceneReadMessage[] = { + { cutscene_read_message, CUTSCENE_LOOP }, + { cutscene_read_message_set_flag, 15 }, + { cutscene_read_message_end, 0 } +}; + +/* TODO: + * The next two arrays are both related to levels, and they look generated. + * These should be split into their own file. + */ + +/** + * Converts the u32 given in DEFINE_COURSE to a u8 with the odd and even digits rotated into the right + * order for sDanceCutsceneIndexTable + */ +#define DROT(value, index) ((value >> (32 - (index + 1) * 8)) & 0xF0) >> 4 | \ + ((value >> (32 - (index + 1) * 8)) & 0x0F) << 4 + +#define DANCE_ENTRY(c) { DROT(c, 0), DROT(c, 1), DROT(c, 2), DROT(c, 3) }, + +#define DEFINE_COURSE(_0, cutscenes) DANCE_ENTRY(cutscenes) #define DEFINE_COURSES_END() -#define DEFINE_BONUS_COURSE(_0, i1, i2, i3, i4) { i1, i2, i3, i4 }, +#define DEFINE_BONUS_COURSE(_0, cutscenes) DANCE_ENTRY(cutscenes) -u8 D_8032E8A4[27][4] = { - { 0x44, 0x44, 0x44, 0x04 }, // (0) Course Hub (Castle Grounds) +/** + * Each hex digit is an index into sDanceCutsceneTable. + * + * 0: Lakitu flies away after the dance + * 1: Only rotates the camera, doesn't zoom out + * 2: The camera goes to a close up of mario + * 3: Bowser keys and the grand star + * 4: Default, used for 100 coin stars, 8 red coin stars in bowser levels, and secret stars + */ +u8 sDanceCutsceneIndexTable[][4] = { #include "levels/course_defines.h" - { 0x44, 0x44, 0x44, 0x04 } // an extra course, hmm... + { 0x44, 0x44, 0x44, 0x04 }, // (26) Why go to all this trouble to save bytes and do this?! }; #undef DEFINE_COURSE #undef DEFINE_COURSES_END #undef DEFINE_BONUS_COURSE +#undef DANCE_ENTRY +#undef DROT + /** * These masks set whether or not the camera zooms out when game is paused. * @@ -8360,7 +10640,7 @@ u8 D_8032E8A4[27][4] = { * Then the value of (1 << shift) is &'d with the level's mask, * and if the result is non-zero, the camera will zoom out. */ -u8 zoomOutAreaMasks[20] = { +u8 sZoomOutAreaMasks[] = { ZOOMOUT_AREA_MASK(0,0,0,0, 0,0,0,0), // Unused | Unused ZOOMOUT_AREA_MASK(0,0,0,0, 0,0,0,0), // Unused | Unused ZOOMOUT_AREA_MASK(0,0,0,0, 1,0,0,0), // BBH | CCM @@ -8383,557 +10663,719 @@ u8 zoomOutAreaMasks[20] = { ZOOMOUT_AREA_MASK(0,0,0,0, 0,0,0,0), // Unused | Unused }; -struct CutsceneSplinePoint sBobCreditsCameraPositions[5] = { { 1, 0, { 5984, 3255, 4975 } }, - { 2, 0, { 4423, 3315, 1888 } }, - { 3, 0, { 776, 2740, -1825 } }, - { 4, 0, { -146, 3894, -3167 } }, - { -1, 0, { 741, 4387, -5474 } } }; +STATIC_ASSERT(ARRAY_COUNT(sZoomOutAreaMasks) - 1 == LEVEL_MAX / 2, "Make sure you edit sZoomOutAreaMasks when adding / removing courses."); -struct CutsceneSplinePoint sBobCreditsCameraFocus[5] = { { 0, 30, { 5817, 3306, 4507 } }, - { 0, 40, { 4025, 3378, 1593 } }, - { 0, 50, { 1088, 2652, -2205 } }, - { 0, 60, { 205, 3959, -3517 } }, - { -1, 60, { 1231, 4400, -5649 } } }; +/* + * credits spline paths. + * TODO: Separate these into their own file(s) + */ -struct CutsceneSplinePoint sWfCreditsCameraPositions[5] = { { 0, 0, { -301, 1399, 2643 } }, - { 0, 0, { -182, 2374, 4572 } }, - { 0, 0, { 4696, 3864, 413 } }, - { 0, 0, { 1738, 4891, -1516 } }, - { -1, 0, { 1783, 4891, -1516 } } }; - -struct CutsceneSplinePoint sWfCreditsCameraFocus[5] = { { 1, 30, { -249, 1484, 2153 } }, - { 2, 40, { -200, 2470, 4082 } }, - { 3, 40, { 4200, 3916, 370 } }, - { 4, 40, { 1523, 4976, -1072 } }, - { -1, 40, { 1523, 4976, -1072 } } }; - -struct CutsceneSplinePoint sJrbCreditsCameraPositions[5] = { { 0, 0, { 5538, -4272, 2376 } }, - { 0, 0, { 5997, -3303, 2261 } }, - { 0, 0, { 6345, -3255, 2179 } }, - { 0, 0, { 6345, -3255, 2179 } }, - { -1, 0, { 6694, -3203, 2116 } } }; - -struct CutsceneSplinePoint sJrbCreditsCameraFocus[5] = { { 0, 50, { 5261, -4683, 2443 } }, - { 0, 50, { 5726, -3675, 2456 } }, - { 0, 50, { 6268, -2817, 2409 } }, - { 0, 50, { 6596, -2866, 2369 } }, - { -1, 50, { 7186, -3153, 2041 } } }; - -struct CutsceneSplinePoint sCcmSlideCreditsCameraPositions[5] = { { 0, 0, { -6324, 6745, -5626 } }, - { 1, 0, { -6324, 6745, -5626 } }, - { 2, 0, { -6108, 6762, -5770 } }, - { 3, 0, { -5771, 6787, -5962 } }, - { -1, 0, { -5672, 6790, -5979 } } }; - -struct CutsceneSplinePoint sCcmSlideCreditsCameraFocus[5] = { { 0, 50, { -5911, 6758, -5908 } }, - { 1, 50, { -5911, 6758, -5908 } }, - { 2, 50, { -5652, 6814, -5968 } }, - { 3, 50, { -5277, 6801, -6043 } }, - { -1, 50, { -5179, 6804, -6060 } } }; - -struct CutsceneSplinePoint sBbhCreditsCameraPositions[4] = { { 1, 0, { 1088, 341, 2447 } }, - { 2, 0, { 1338, 610, 2808 } }, - { 3, 0, { 2267, 1612, 2966 } }, - { -1, 0, { 2296, 1913, 2990 } } }; - -struct CutsceneSplinePoint sBbhCreditsCameraFocus[4] = { { 1, 50, { 1160, 263, 1958 } }, - { 2, 50, { 1034, 472, 2436 } }, - { 3, 50, { 1915, 1833, 2688 } }, - { -1, 50, { 2134, 2316, 2742 } } }; - -struct CutsceneSplinePoint sHmcCreditsCameraPositions[5] = { { 1, 0, { -5952, 1807, -5882 } }, - { 2, 0, { -5623, 1749, -4863 } }, - { 3, 0, { -5472, 1955, -2520 } }, - { 4, 0, { -5544, 1187, -1085 } }, - { -1, 0, { -5547, 391, -721 } } }; - -struct CutsceneSplinePoint sHmcCreditsCameraFocus[5] = { { 1, 210, { -5952, 1884, -6376 } }, - { 2, 58, { -5891, 1711, -5283 } }, - { 3, 30, { -5595, 1699, -2108 } }, - { 4, 31, { -5546, 794, -777 } }, - { -1, 31, { -5548, -85, -572 } } }; - -struct CutsceneSplinePoint sThiWigglerCreditsCameraPositions[3] = { { 1, 0, { -1411, 2474, -1276 } }, - { 2, 0, { -1606, 2479, -434 } }, - { -1, 0, { -1170, 2122, 1337 } } }; - -struct CutsceneSplinePoint sThiWigglerCreditsCameraFocus[3] = { { 1, 50, { -1053, 2512, -928 } }, - { 2, 50, { -1234, 2377, -114 } }, - { -1, 50, { -758, 2147, 1054 } } }; - -struct CutsceneSplinePoint sVolcanoCreditsCameraPositions[6] = { - { 0, 0, { -1445, 1094, 1617 } }, { 0, 0, { -1509, 649, 871 } }, { 0, 0, { -1133, 420, -248 } }, - { 0, 0, { -778, 359, -1052 } }, { 0, 0, { -565, 260, -1730 } }, { -1, 0, { 1274, 473, -275 } } +struct CutsceneSplinePoint sBobCreditsSplinePositions[] = { + { 1, 0, { 5984, 3255, 4975 } }, + { 2, 0, { 4423, 3315, 1888 } }, + { 3, 0, { 776, 2740, -1825 } }, + { 4, 0, { -146, 3894, -3167 } }, + { -1, 0, { 741, 4387, -5474 } } }; -struct CutsceneSplinePoint sVolcanoCreditsCameraFocus[6] = { - { 0, 50, { -1500, 757, 1251 } }, { 0, 50, { -1401, 439, 431 } }, { 0, 50, { -749, 270, -532 } }, - { 0, 50, { -396, 270, -1363 } }, { 0, 50, { -321, 143, -2151 } }, { -1, 50, { 1002, 460, -694 } } +struct CutsceneSplinePoint sBobCreditsSplineFocus[] = { + { 0, 30, { 5817, 3306, 4507 } }, + { 0, 40, { 4025, 3378, 1593 } }, + { 0, 50, { 1088, 2652, -2205 } }, + { 0, 60, { 205, 3959, -3517 } }, + { -1, 60, { 1231, 4400, -5649 } } }; -struct CutsceneSplinePoint sSslCreditsCameraPositions[6] = { - { 0, 0, { -4262, 4658, -5015 } }, { 0, 0, { -3274, 2963, -4661 } }, { 0, 0, { -2568, 812, -6528 } }, - { 0, 0, { -414, 660, -7232 } }, { 0, 0, { 1466, 660, -6898 } }, { -1, 0, { 2724, 660, -6298 } } +struct CutsceneSplinePoint sWfCreditsSplinePositions[] = { + { 0, 0, { -301, 1399, 2643 } }, + { 0, 0, { -182, 2374, 4572 } }, + { 0, 0, { 4696, 3864, 413 } }, + { 0, 0, { 1738, 4891, -1516 } }, + { -1, 0, { 1783, 4891, -1516 } } }; -struct CutsceneSplinePoint sSslCreditsCameraFocus[6] = { - { 0, 50, { -4083, 4277, -4745 } }, { 0, 50, { -2975, 2574, -4759 } }, - { 0, 50, { -2343, 736, -6088 } }, { 0, 50, { -535, 572, -6755 } }, - { 0, 50, { 1311, 597, -6427 } }, { -1, 50, { 2448, 612, -5884 } } +struct CutsceneSplinePoint sWfCreditsSplineFocus[] = { + { 1, 30, { -249, 1484, 2153 } }, + { 2, 40, { -200, 2470, 4082 } }, + { 3, 40, { 4200, 3916, 370 } }, + { 4, 40, { 1523, 4976, -1072 } }, + { -1, 40, { 1523, 4976, -1072 } } }; -struct CutsceneSplinePoint sDddCreditsCameraPositions[7] = { - { 0, 0, { -874, -4933, 366 } }, { 0, 0, { -1463, -4782, 963 } }, { 0, 0, { -1893, -4684, 1303 } }, - { 0, 0, { -2818, -4503, 1583 } }, { 0, 0, { -4095, -2924, 730 } }, { 0, 0, { -4737, -1594, -63 } }, +struct CutsceneSplinePoint sJrbCreditsSplinePositions[] = { + { 0, 0, { 5538, -4272, 2376 } }, + { 0, 0, { 5997, -3303, 2261 } }, + { 0, 0, { 6345, -3255, 2179 } }, + { 0, 0, { 6345, -3255, 2179 } }, + { -1, 0, { 6694, -3203, 2116 } } +}; + +struct CutsceneSplinePoint sJrbCreditsSplineFocus[] = { + { 0, 50, { 5261, -4683, 2443 } }, + { 0, 50, { 5726, -3675, 2456 } }, + { 0, 50, { 6268, -2817, 2409 } }, + { 0, 50, { 6596, -2866, 2369 } }, + { -1, 50, { 7186, -3153, 2041 } } +}; + +struct CutsceneSplinePoint sCcmSlideCreditsSplinePositions[] = { + { 0, 0, { -6324, 6745, -5626 } }, + { 1, 0, { -6324, 6745, -5626 } }, + { 2, 0, { -6108, 6762, -5770 } }, + { 3, 0, { -5771, 6787, -5962 } }, + { -1, 0, { -5672, 6790, -5979 } } +}; + +struct CutsceneSplinePoint sCcmSlideCreditsSplineFocus[] = { + { 0, 50, { -5911, 6758, -5908 } }, + { 1, 50, { -5911, 6758, -5908 } }, + { 2, 50, { -5652, 6814, -5968 } }, + { 3, 50, { -5277, 6801, -6043 } }, + { -1, 50, { -5179, 6804, -6060 } } +}; + +struct CutsceneSplinePoint sBbhCreditsSplinePositions[] = { + { 1, 0, { 1088, 341, 2447 } }, + { 2, 0, { 1338, 610, 2808 } }, + { 3, 0, { 2267, 1612, 2966 } }, + { -1, 0, { 2296, 1913, 2990 } } +}; + +struct CutsceneSplinePoint sBbhCreditsSplineFocus[] = { + { 1, 50, { 1160, 263, 1958 } }, + { 2, 50, { 1034, 472, 2436 } }, + { 3, 50, { 1915, 1833, 2688 } }, + { -1, 50, { 2134, 2316, 2742 } } +}; + +struct CutsceneSplinePoint sHmcCreditsSplinePositions[] = { + { 1, 0, { -5952, 1807, -5882 } }, + { 2, 0, { -5623, 1749, -4863 } }, + { 3, 0, { -5472, 1955, -2520 } }, + { 4, 0, { -5544, 1187, -1085 } }, + { -1, 0, { -5547, 391, -721 } } +}; + +struct CutsceneSplinePoint sHmcCreditsSplineFocus[] = { + { 1, 210, { -5952, 1884, -6376 } }, + { 2, 58, { -5891, 1711, -5283 } }, + { 3, 30, { -5595, 1699, -2108 } }, + { 4, 31, { -5546, 794, -777 } }, + { -1, 31, { -5548, -85, -572 } } +}; + +struct CutsceneSplinePoint sThiWigglerCreditsSplinePositions[] = { + { 1, 0, { -1411, 2474, -1276 } }, + { 2, 0, { -1606, 2479, -434 } }, + { -1, 0, { -1170, 2122, 1337 } } +}; + +struct CutsceneSplinePoint sThiWigglerCreditsSplineFocus[] = { + { 1, 50, { -1053, 2512, -928 } }, + { 2, 50, { -1234, 2377, -114 } }, + { -1, 50, { -758, 2147, 1054 } } +}; + +struct CutsceneSplinePoint sVolcanoCreditsSplinePositions[] = { + { 0, 0, { -1445, 1094, 1617 } }, + { 0, 0, { -1509, 649, 871 } }, + { 0, 0, { -1133, 420, -248 } }, + { 0, 0, { -778, 359, -1052 } }, + { 0, 0, { -565, 260, -1730 } }, + { -1, 0, { 1274, 473, -275 } } +}; + +struct CutsceneSplinePoint sVolcanoCreditsSplineFocus[] = { + { 0, 50, { -1500, 757, 1251 } }, + { 0, 50, { -1401, 439, 431 } }, + { 0, 50, { -749, 270, -532 } }, + { 0, 50, { -396, 270, -1363 } }, + { 0, 50, { -321, 143, -2151 } }, + { -1, 50, { 1002, 460, -694 } } +}; + +struct CutsceneSplinePoint sSslCreditsSplinePositions[] = { + { 0, 0, { -4262, 4658, -5015 } }, + { 0, 0, { -3274, 2963, -4661 } }, + { 0, 0, { -2568, 812, -6528 } }, + { 0, 0, { -414, 660, -7232 } }, + { 0, 0, { 1466, 660, -6898 } }, + { -1, 0, { 2724, 660, -6298 } } +}; + +struct CutsceneSplinePoint sSslCreditsSplineFocus[] = { + { 0, 50, { -4083, 4277, -4745 } }, + { 0, 50, { -2975, 2574, -4759 } }, + { 0, 50, { -2343, 736, -6088 } }, + { 0, 50, { -535, 572, -6755 } }, + { 0, 50, { 1311, 597, -6427 } }, + { -1, 50, { 2448, 612, -5884 } } +}; + +struct CutsceneSplinePoint sDddCreditsSplinePositions[] = { + { 0, 0, { -874, -4933, 366 } }, + { 0, 0, { -1463, -4782, 963 } }, + { 0, 0, { -1893, -4684, 1303 } }, + { 0, 0, { -2818, -4503, 1583 } }, + { 0, 0, { -4095, -2924, 730 } }, + { 0, 0, { -4737, -1594, -63 } }, { -1, 0, { -4681, -1084, -623 } } }; -struct CutsceneSplinePoint sDddCreditsCameraFocus[7] = { - { 0, 50, { -1276, -4683, 622 } }, { 0, 50, { -1858, -4407, 1097 } }, - { 0, 50, { -2324, -4332, 1318 } }, { 0, 50, { -3138, -4048, 1434 } }, - { 0, 50, { -4353, -2444, 533 } }, { 0, 50, { -4807, -1169, -436 } }, +struct CutsceneSplinePoint sDddCreditsSplineFocus[] = { + { 0, 50, { -1276, -4683, 622 } }, + { 0, 50, { -1858, -4407, 1097 } }, + { 0, 50, { -2324, -4332, 1318 } }, + { 0, 50, { -3138, -4048, 1434 } }, + { 0, 50, { -4353, -2444, 533 } }, + { 0, 50, { -4807, -1169, -436 } }, { -1, 50, { -4665, -664, -1007 } } }; -struct CutsceneSplinePoint sSlCreditsCameraPositions[4] = { { 0, 0, { 939, 6654, 6196 } }, - { 0, 0, { 1873, 5160, 3714 } }, - { 0, 0, { 3120, 3564, 1314 } }, - { -1, 0, { 2881, 4231, 573 } } }; - -struct CutsceneSplinePoint sSlCreditsCameraFocus[4] = { { 0, 50, { 875, 6411, 5763 } }, - { 0, 50, { 1659, 4951, 3313 } }, - { 0, 50, { 2630, 3565, 1215 } }, - { -1, 50, { 2417, 4056, 639 } } }; - -struct CutsceneSplinePoint sWdwCreditsCameraPositions[4] = { { 0, 0, { 3927, 2573, 3685 } }, - { 0, 0, { 2389, 2054, 1210 } }, - { 0, 0, { 2309, 2069, 22 } }, - { -1, 0, { 2122, 2271, -979 } } }; - -struct CutsceneSplinePoint sWdwCreditsCameraFocus[4] = { { 0, 50, { 3637, 2460, 3294 } }, - { 0, 50, { 1984, 2067, 918 } }, - { 0, 50, { 1941, 2255, -261 } }, - { -1, 50, { 1779, 2587, -1158 } } }; - -struct CutsceneSplinePoint sTtmCreditsCameraPositions[6] = { - { 0, 0, { 386, 2535, 644 } }, { 0, 0, { 1105, 2576, 918 } }, { 0, 0, { 3565, 2261, 2098 } }, - { 0, 0, { 6715, -2791, 4554 } }, { 0, 0, { 3917, -3130, 3656 } }, { -1, 0, { 3917, -3130, 3656 } } +struct CutsceneSplinePoint sSlCreditsSplinePositions[] = { + { 0, 0, { 939, 6654, 6196 } }, + { 0, 0, { 1873, 5160, 3714 } }, + { 0, 0, { 3120, 3564, 1314 } }, + { -1, 0, { 2881, 4231, 573 } } }; -struct CutsceneSplinePoint sTtmCreditsCameraFocus[6] = { - { 1, 50, { 751, 2434, 318 } }, { 2, 50, { 768, 2382, 603 } }, - { 3, 60, { 3115, 2086, 1969 } }, { 4, 30, { 6370, -3108, 4727 } }, - { 5, 50, { 4172, -3385, 4001 } }, { -1, 50, { 4172, -3385, 4001 } } +struct CutsceneSplinePoint sSlCreditsSplineFocus[] = { + { 0, 50, { 875, 6411, 5763 } }, + { 0, 50, { 1659, 4951, 3313 } }, + { 0, 50, { 2630, 3565, 1215 } }, + { -1, 50, { 2417, 4056, 639 } } }; -struct CutsceneSplinePoint sThiHugeCreditsCameraPositions[7] = { - { 0, 0, { 6990, -1000, -4858 } }, { 0, 0, { 7886, -1055, 2878 } }, { 0, 0, { 1952, -1481, 10920 } }, - { 0, 0, { -1684, -219, 2819 } }, { 0, 0, { -2427, -131, 2755 } }, { 0, 0, { -3246, 416, 3286 } }, +struct CutsceneSplinePoint sWdwCreditsSplinePositions[] = { + { 0, 0, { 3927, 2573, 3685 } }, + { 0, 0, { 2389, 2054, 1210 } }, + { 0, 0, { 2309, 2069, 22 } }, + { -1, 0, { 2122, 2271, -979 } } +}; + +struct CutsceneSplinePoint sWdwCreditsSplineFocus[] = { + { 0, 50, { 3637, 2460, 3294 } }, + { 0, 50, { 1984, 2067, 918 } }, + { 0, 50, { 1941, 2255, -261 } }, + { -1, 50, { 1779, 2587, -1158 } } +}; + +struct CutsceneSplinePoint sTtmCreditsSplinePositions[] = { + { 0, 0, { 386, 2535, 644 } }, + { 0, 0, { 1105, 2576, 918 } }, + { 0, 0, { 3565, 2261, 2098 } }, + { 0, 0, { 6715, -2791, 4554 } }, + { 0, 0, { 3917, -3130, 3656 } }, + { -1, 0, { 3917, -3130, 3656 } } +}; + +struct CutsceneSplinePoint sTtmCreditsSplineFocus[] = { + { 1, 50, { 751, 2434, 318 } }, + { 2, 50, { 768, 2382, 603 } }, + { 3, 60, { 3115, 2086, 1969 } }, + { 4, 30, { 6370, -3108, 4727 } }, + { 5, 50, { 4172, -3385, 4001 } }, + { -1, 50, { 4172, -3385, 4001 } } +}; + +struct CutsceneSplinePoint sThiHugeCreditsSplinePositions[] = { + { 0, 0, { 6990, -1000, -4858 } }, + { 0, 0, { 7886, -1055, 2878 } }, + { 0, 0, { 1952, -1481, 10920 } }, + { 0, 0, { -1684, -219, 2819 } }, + { 0, 0, { -2427, -131, 2755 } }, + { 0, 0, { -3246, 416, 3286 } }, { -1, 0, { -3246, 416, 3286 } } }; -struct CutsceneSplinePoint sThiHugeCreditsCameraFocus[7] = { - { 1, 70, { 7022, -965, -5356 } }, { 2, 40, { 7799, -915, 2405 } }, - { 3, 60, { 1878, -1137, 10568 } }, { 4, 50, { -1931, -308, 2394 } }, - { 5, 50, { -2066, -386, 2521 } }, { 6, 50, { -2875, 182, 3045 } }, +struct CutsceneSplinePoint sThiHugeCreditsSplineFocus[] = { + { 1, 70, { 7022, -965, -5356 } }, + { 2, 40, { 7799, -915, 2405 } }, + { 3, 60, { 1878, -1137, 10568 } }, + { 4, 50, { -1931, -308, 2394 } }, + { 5, 50, { -2066, -386, 2521 } }, + { 6, 50, { -2875, 182, 3045 } }, { -1, 50, { -2875, 182, 3045 } } }; -struct CutsceneSplinePoint sTtcCreditsCameraPositions[4] = { { 1, 0, { -1724, 277, -994 } }, - { 2, 0, { -1720, 456, -995 } }, - { 3, 0, { -1655, 810, -1014 } }, - { -1, 0, { -1753, 883, -1009 } } }; +struct CutsceneSplinePoint sTtcCreditsSplinePositions[] = { + { 1, 0, { -1724, 277, -994 } }, + { 2, 0, { -1720, 456, -995 } }, + { 3, 0, { -1655, 810, -1014 } }, + { -1, 0, { -1753, 883, -1009 } } +}; -struct CutsceneSplinePoint sTtcCreditsCameraFocus[4] = { { 1, 50, { -1554, 742, -1063 } }, - { 2, 50, { -1245, 571, -1102 } }, - { 3, 50, { -1220, 603, -1151 } }, - { -1, 50, { -1412, 520, -1053 } } }; +struct CutsceneSplinePoint sTtcCreditsSplineFocus[] = { + { 1, 50, { -1554, 742, -1063 } }, + { 2, 50, { -1245, 571, -1102 } }, + { 3, 50, { -1220, 603, -1151 } }, + { -1, 50, { -1412, 520, -1053 } } +}; -struct CutsceneSplinePoint sRrCreditsCameraPositions[4] = { { 0, 0, { -1818, 4036, 97 } }, - { 0, 0, { -575, 3460, -505 } }, - { 0, 0, { 1191, 3611, -1134 } }, - { -1, 0, { 2701, 3777, -3686 } } }; +struct CutsceneSplinePoint sRrCreditsSplinePositions[] = { + { 0, 0, { -1818, 4036, 97 } }, + { 0, 0, { -575, 3460, -505 } }, + { 0, 0, { 1191, 3611, -1134 } }, + { -1, 0, { 2701, 3777, -3686 } } +}; -struct CutsceneSplinePoint sRrCreditsCameraFocus[4] = { { 0, 50, { -1376, 3885, -81 } }, - { 0, 50, { -146, 3343, -734 } }, - { 0, 50, { 1570, 3446, -1415 } }, - { -1, 50, { 2794, 3627, -3218 } } }; +struct CutsceneSplinePoint sRrCreditsSplineFocus[] = { + { 0, 50, { -1376, 3885, -81 } }, + { 0, 50, { -146, 3343, -734 } }, + { 0, 50, { 1570, 3446, -1415 } }, + { -1, 50, { 2794, 3627, -3218 } } +}; -struct CutsceneSplinePoint sSaCreditsCameraPositions[5] = { { 0, 0, { -295, -396, -585 } }, - { 1, 0, { -295, -396, -585 } }, - { 2, 0, { -292, -856, -573 } }, - { 3, 0, { -312, -856, -541 } }, - { -1, 0, { 175, -856, -654 } } }; +struct CutsceneSplinePoint sSaCreditsSplinePositions[] = { + { 0, 0, { -295, -396, -585 } }, + { 1, 0, { -295, -396, -585 } }, + { 2, 0, { -292, -856, -573 } }, + { 3, 0, { -312, -856, -541 } }, + { -1, 0, { 175, -856, -654 } } +}; -struct CutsceneSplinePoint sSaCreditsCameraFocus[5] = { { 0, 50, { -175, -594, -142 } }, - { 1, 50, { -175, -594, -142 } }, - { 2, 50, { -195, -956, -92 } }, - { 3, 50, { -572, -956, -150 } }, - { -1, 50, { -307, -956, -537 } } }; +struct CutsceneSplinePoint sSaCreditsSplineFocus[] = { + { 0, 50, { -175, -594, -142 } }, + { 1, 50, { -175, -594, -142 } }, + { 2, 50, { -195, -956, -92 } }, + { 3, 50, { -572, -956, -150 } }, + { -1, 50, { -307, -956, -537 } } +}; -struct CutsceneSplinePoint sCotmcCreditsCameraPositions[5] = { { 0, 0, { -296, 495, 1607 } }, - { 0, 0, { -430, 541, 654 } }, - { 0, 0, { -466, 601, -359 } }, - { 0, 0, { -217, 433, -1549 } }, - { -1, 0, { -95, 366, -2922 } } }; +struct CutsceneSplinePoint sCotmcCreditsSplinePositions[] = { + { 0, 0, { -296, 495, 1607 } }, + { 0, 0, { -430, 541, 654 } }, + { 0, 0, { -466, 601, -359 } }, + { 0, 0, { -217, 433, -1549 } }, + { -1, 0, { -95, 366, -2922 } } +}; -struct CutsceneSplinePoint sCotmcCreditsCameraFocus[5] = { { 0, 50, { -176, 483, 2092 } }, - { 0, 50, { -122, 392, 1019 } }, - { 0, 50, { -268, 450, -792 } }, - { 0, 50, { -172, 399, -2046 } }, - { -1, 50, { -51, 355, -3420 } } }; +struct CutsceneSplinePoint sCotmcCreditsSplineFocus[] = { + { 0, 50, { -176, 483, 2092 } }, + { 0, 50, { -122, 392, 1019 } }, + { 0, 50, { -268, 450, -792 } }, + { 0, 50, { -172, 399, -2046 } }, + { -1, 50, { -51, 355, -3420 } } +}; -struct CutsceneSplinePoint sDddSubCreditsCameraPositions[5] = { { 0, 0, { 4656, 2171, 5028 } }, - { 0, 0, { 4548, 1182, 4596 } }, - { 0, 0, { 5007, 813, 3257 } }, - { 0, 0, { 5681, 648, 1060 } }, - { -1, 0, { 4644, 774, 113 } } }; +struct CutsceneSplinePoint sDddSubCreditsSplinePositions[] = { + { 0, 0, { 4656, 2171, 5028 } }, + { 0, 0, { 4548, 1182, 4596 } }, + { 0, 0, { 5007, 813, 3257 } }, + { 0, 0, { 5681, 648, 1060 } }, + { -1, 0, { 4644, 774, 113 } } +}; -struct CutsceneSplinePoint sDddSubCreditsCameraFocus[5] = { { 0, 50, { 4512, 2183, 4549 } }, - { 0, 50, { 4327, 838, 4308 } }, - { 0, 50, { 4774, 749, 2819 } }, - { 0, 50, { 5279, 660, 763 } }, - { -1, 50, { 4194, 885, -75 } } }; +struct CutsceneSplinePoint sDddSubCreditsSplineFocus[] = { + { 0, 50, { 4512, 2183, 4549 } }, + { 0, 50, { 4327, 838, 4308 } }, + { 0, 50, { 4774, 749, 2819 } }, + { 0, 50, { 5279, 660, 763 } }, + { -1, 50, { 4194, 885, -75 } } +}; -struct CutsceneSplinePoint sCcmOutsideCreditsCameraPositions[4] = { +struct CutsceneSplinePoint sCcmOutsideCreditsSplinePositions[] = { { 1, 0, { 1427, -1387, 5409 } }, { 2, 0, { -1646, -1536, 4526 } }, { 3, 0, { -3852, -1448, 3913 } }, { -1, 0, { -5199, -1366, 1886 } } }; -struct CutsceneSplinePoint sCcmOutsideCreditsCameraFocus[4] = { { 1, 50, { 958, -1481, 5262 } }, - { 2, 50, { -2123, -1600, 4391 } }, - { 3, 50, { -3957, -1401, 3426 } }, - { -1, 50, { -4730, -1215, 1795 } } }; +struct CutsceneSplinePoint sCcmOutsideCreditsSplineFocus[] = { + { 1, 50, { 958, -1481, 5262 } }, + { 2, 50, { -2123, -1600, 4391 } }, + { 3, 50, { -3957, -1401, 3426 } }, + { -1, 50, { -4730, -1215, 1795 } } +}; -void handle_cutscenes(struct LevelCamera *c) { +/** + * Play the current cutscene until either gCutsceneTimer reaches the max time, or c->cutscene is set to 0 + * + * Note that CAM_FLAG_SMOOTH_MOVEMENT is cleared while a cutscene is playing, so cutscenes set it for + * the duration they want the flag to be active. + */ +void play_cutscene(struct Camera *c) { UNUSED u32 pad[3]; - UNUSED s16 sp22; - s16 sp20; - u8 cutscene; + UNUSED s16 unusedYawFocToMario; + s16 cutsceneDuration; + u8 oldCutscene; - sp22 = sYawFocToMario; - cutscene = c->cutscene; - gCameraFlags2 &= ~CAM_FLAG_2_SMOOTH_MOVEMENT; - gCameraMovementFlags &= ~CAM_MOVE_INTO_C_UP; + unusedYawFocToMario = sAreaYaw; + oldCutscene = c->cutscene; + sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; + gCameraMovementFlags &= ~CAM_MOVING_INTO_MODE; -#define CUTSCENE_TABLE_JUMP(casenum, table) \ - case casenum: \ - sp20 = table[D_8033B6EA].unk4; \ - (table[D_8033B6EA].unk0)(c); \ +#define CUTSCENE(id, cutscene) \ + case id: \ + cutsceneDuration = cutscene[sCutsceneShot].duration; \ + cutscene[sCutsceneShot].shot(c); \ break; switch (c->cutscene) { - CUTSCENE_TABLE_JUMP(CUTSCENE_STAR_SPAWN, TableCutsceneStarSpawn) - CUTSCENE_TABLE_JUMP(CUTSCENE_SPECIAL_STAR_SPAWN, TableCutsceneSpecialStarSpawn) - CUTSCENE_TABLE_JUMP(CUTSCENE_PEACH_END, TableCutscenePeachEnd) - CUTSCENE_TABLE_JUMP(CUTSCENE_GRAND_STAR, TableCutsceneGrandStar) - CUTSCENE_TABLE_JUMP(CUTSCENE_DOOR_WARP, TableCutsceneDoorWarp) - CUTSCENE_TABLE_JUMP(CUTSCENE_DOOR_0, TableCutsceneDoor00) - CUTSCENE_TABLE_JUMP(CUTSCENE_DOOR_1, TableCutsceneDoor01) - CUTSCENE_TABLE_JUMP(CUTSCENE_DOOR_A, TableCutsceneDoor0A) - CUTSCENE_TABLE_JUMP(CUTSCENE_DOOR_B, TableCutsceneDoor0B) - CUTSCENE_TABLE_JUMP(CUTSCENE_ENTER_CANNON, TableCutsceneEnterCannon) - CUTSCENE_TABLE_JUMP(CUTSCENE_ENTER_PAINTING, TableCutsceneEnterPainting) - CUTSCENE_TABLE_JUMP(CUTSCENE_DEATH_EXIT, TableCutsceneDeathExit) - CUTSCENE_TABLE_JUMP(CUTSCENE_EXIT_PAINTING_SUCC, TableCutsceneExitPaintingSuccess) - CUTSCENE_TABLE_JUMP(CUTSCENE_11_TODO, TableCutscene11Todo) - CUTSCENE_TABLE_JUMP(CUTSCENE_INTRO_PEACH, TableCutsceneIntroPeach) - CUTSCENE_TABLE_JUMP(CUTSCENE_ENTER_BOWSER_ARENA, TableCutsceneEnterBowserPlatform) - CUTSCENE_TABLE_JUMP(CUTSCENE_STAR_DANCE_1_1, TableCutsceneStarDance1) - CUTSCENE_TABLE_JUMP(CUTSCENE_STAR_DANCE_1_2, TableCutsceneStarDance1) - CUTSCENE_TABLE_JUMP(CUTSCENE_STAR_DANCE_2, TableCutsceneStarDance2) - CUTSCENE_TABLE_JUMP(CUTSCENE_STAR_DANCE_3, TableCutsceneStarDance3) - CUTSCENE_TABLE_JUMP(CUTSCENE_KEY_DANCE, TableCutsceneKeyDance) - CUTSCENE_TABLE_JUMP(CUTSCENE_0F_TODO, TableCutscene0FTodo) - CUTSCENE_TABLE_JUMP(CUTSCENE_END_WAVING, TableCutsceneEndWaving) - CUTSCENE_TABLE_JUMP(CUTSCENE_CREDITS, TableCutsceneCredits) - CUTSCENE_TABLE_JUMP(CUTSCENE_CAP_SWITCH_PRESS, TableCutsceneCapSwitchPress) - CUTSCENE_TABLE_JUMP(CUTSCENE_SLIDING_DOORS_OPEN, TableCutsceneSlidingDoorsOpen) - CUTSCENE_TABLE_JUMP(CUTSCENE_PREPARE_CANNON, TableCutscenePrepareCannon) - CUTSCENE_TABLE_JUMP(CUTSCENE_UNLOCK_KEY_DOOR, TableCutsceneUnlockKeyDoor) - CUTSCENE_TABLE_JUMP(CUTSCENE_STANDING_DEATH, TableCutsceneStandingDeath) - CUTSCENE_TABLE_JUMP(CUTSCENE_ENTER_POOL, TableCutsceneEnterPool) - CUTSCENE_TABLE_JUMP(CUTSCENE_DEATH_2, TableCutsceneDeath2) - CUTSCENE_TABLE_JUMP(CUTSCENE_DEATH_ON_BACK, TableCutsceneDeathOnBack) - CUTSCENE_TABLE_JUMP(CUTSCENE_QUICKSAND_DEATH, TableCutsceneQuicksandDeath) - CUTSCENE_TABLE_JUMP(CUTSCENE_SUFFOCATION_DEATH, TableCutsceneSuffocationDeath) - CUTSCENE_TABLE_JUMP(CUTSCENE_EXIT_BOWSER_SUCC, TableCutsceneExitBowserSuccess) - CUTSCENE_TABLE_JUMP(CUTSCENE_1C_TODO, TableCutscene1CTodo) - CUTSCENE_TABLE_JUMP(CUTSCENE_EXIT_BBH_SUCC, TableCutsceneBBHExitSuccess) - CUTSCENE_TABLE_JUMP(CUTSCENE_EXIT_WATERFALL, TableCutsceneExitWaterfall) - CUTSCENE_TABLE_JUMP(CUTSCENE_EXIT_FALL_WMOTR, TableCutsceneFallToCastleGrounds) - CUTSCENE_TABLE_JUMP(CUTSCENE_NONPAINTING_DEATH, TableCutsceneNonPaintingDeath) - CUTSCENE_TABLE_JUMP(CUTSCENE_DIALOG_1, TableCutsceneDialog) - CUTSCENE_TABLE_JUMP(CUTSCENE_READ_MESSAGE, TableCutsceneReadMessage) - CUTSCENE_TABLE_JUMP(CUTSCENE_DIALOG_2, TableCutsceneDialog) - CUTSCENE_TABLE_JUMP(CUTSCENE_ENTER_PYRAMID_TOP, TableCutsceneEnterPyramidTop) - CUTSCENE_TABLE_JUMP(CUTSCENE_26_TODO, TableCutscene26Todo) + CUTSCENE(CUTSCENE_STAR_SPAWN, sCutsceneStarSpawn) + CUTSCENE(CUTSCENE_RED_COIN_STAR_SPAWN, sCutsceneRedCoinStarSpawn) + CUTSCENE(CUTSCENE_ENDING, sCutsceneEnding) + CUTSCENE(CUTSCENE_GRAND_STAR, sCutsceneGrandStar) + CUTSCENE(CUTSCENE_DOOR_WARP, sCutsceneDoorWarp) + CUTSCENE(CUTSCENE_DOOR_PULL, sCutsceneDoorPull) + CUTSCENE(CUTSCENE_DOOR_PUSH, sCutsceneDoorPush) + CUTSCENE(CUTSCENE_DOOR_PULL_MODE, sCutsceneDoorPullMode) + CUTSCENE(CUTSCENE_DOOR_PUSH_MODE, sCutsceneDoorPushMode) + CUTSCENE(CUTSCENE_ENTER_CANNON, sCutsceneEnterCannon) + CUTSCENE(CUTSCENE_ENTER_PAINTING, sCutsceneEnterPainting) + CUTSCENE(CUTSCENE_DEATH_EXIT, sCutsceneDeathExit) + CUTSCENE(CUTSCENE_EXIT_PAINTING_SUCC, sCutsceneExitPaintingSuccess) + CUTSCENE(CUTSCENE_UNUSED_EXIT, sCutsceneUnusedExit) + CUTSCENE(CUTSCENE_INTRO_PEACH, sCutsceneIntroPeach) + CUTSCENE(CUTSCENE_ENTER_BOWSER_ARENA, sCutsceneEnterBowserArena) + CUTSCENE(CUTSCENE_DANCE_ROTATE, sCutsceneDanceDefaultRotate) + CUTSCENE(CUTSCENE_DANCE_DEFAULT, sCutsceneDanceDefaultRotate) + CUTSCENE(CUTSCENE_DANCE_FLY_AWAY, sCutsceneDanceFlyAway) + CUTSCENE(CUTSCENE_DANCE_CLOSEUP, sCutsceneDanceCloseup) + CUTSCENE(CUTSCENE_KEY_DANCE, sCutsceneKeyDance) + CUTSCENE(CUTSCENE_0F_UNUSED, sCutsceneUnused) + CUTSCENE(CUTSCENE_END_WAVING, sCutsceneEndWaving) + CUTSCENE(CUTSCENE_CREDITS, sCutsceneCredits) + CUTSCENE(CUTSCENE_CAP_SWITCH_PRESS, sCutsceneCapSwitchPress) + CUTSCENE(CUTSCENE_SLIDING_DOORS_OPEN, sCutsceneSlidingDoorsOpen) + CUTSCENE(CUTSCENE_PREPARE_CANNON, sCutscenePrepareCannon) + CUTSCENE(CUTSCENE_UNLOCK_KEY_DOOR, sCutsceneUnlockKeyDoor) + CUTSCENE(CUTSCENE_STANDING_DEATH, sCutsceneStandingDeath) + CUTSCENE(CUTSCENE_ENTER_POOL, sCutsceneEnterPool) + CUTSCENE(CUTSCENE_DEATH_ON_STOMACH, sCutsceneDeathStomach) + CUTSCENE(CUTSCENE_DEATH_ON_BACK, sCutsceneDeathOnBack) + CUTSCENE(CUTSCENE_QUICKSAND_DEATH, sCutsceneQuicksandDeath) + CUTSCENE(CUTSCENE_SUFFOCATION_DEATH, sCutsceneSuffocation) + CUTSCENE(CUTSCENE_EXIT_BOWSER_SUCC, sCutsceneExitBowserSuccess) + CUTSCENE(CUTSCENE_EXIT_BOWSER_DEATH, sCutsceneExitBowserDeath) + CUTSCENE(CUTSCENE_EXIT_SPECIAL_SUCC, sCutsceneExitSpecialSuccess) + CUTSCENE(CUTSCENE_EXIT_WATERFALL, sCutsceneExitWaterfall) + CUTSCENE(CUTSCENE_EXIT_FALL_WMOTR, sCutsceneFallToCastleGrounds) + CUTSCENE(CUTSCENE_NONPAINTING_DEATH, sCutsceneNonPaintingDeath) + CUTSCENE(CUTSCENE_DIALOG, sCutsceneDialog) + CUTSCENE(CUTSCENE_READ_MESSAGE, sCutsceneReadMessage) + CUTSCENE(CUTSCENE_RACE_DIALOG, sCutsceneDialog) + CUTSCENE(CUTSCENE_ENTER_PYRAMID_TOP, sCutsceneEnterPyramidTop) + CUTSCENE(CUTSCENE_SSL_PYRAMID_EXPLODE, sCutscenePyramidTopExplode) } -#undef CUTSCENE_TABLE_JUMP +#undef CUTSCENE - if ((sp20 != 0) && ((gCutsceneTimer & 0x8000) == 0)) { + if ((cutsceneDuration != 0) && !(gCutsceneTimer & CUTSCENE_STOP)) { + //! @bug This should check for 0x7FFF (CUTSCENE_LOOP) + //! instead, cutscenes that last longer than 0x3FFF frames will never end on their own if (gCutsceneTimer < 0x3FFF) { gCutsceneTimer += 1; } - if (gCutsceneTimer == sp20) { - D_8033B6EA += 1; + //! Because gCutsceneTimer is often set to 0x7FFF (CUTSCENE_LOOP), this conditional can only + //! check for == due to overflow + if (gCutsceneTimer == cutsceneDuration) { + sCutsceneShot += 1; gCutsceneTimer = 0; } } else { - sMarioStatusForCamera->unk1C[1] = 0; - D_8033B6EA = 0; + sMarioCamState->cameraEvent = 0; + sCutsceneShot = 0; gCutsceneTimer = 0; } - D_8033B3EC = 0; + sAreaYawChange = 0; - if ((c->cutscene == 0) && (cutscene != 0)) { - gCutsceneNumber = cutscene; + // The cutscene just ended + if ((c->cutscene == 0) && (oldCutscene != 0)) { + gRecentCutscene = oldCutscene; } } -s32 call_cutscene_func_in_time_range(CameraCommandProc func, struct LevelCamera *c, s16 start, - s16 end) { +/** + * Call the event while `start` <= gCutsceneTimer <= `end` + * If `end` is -1, call for the rest of the shot. + */ +s32 cutscene_event(CameraEvent event, struct Camera *c, s16 start, s16 end) { if (start <= gCutsceneTimer) { - if ((end == -1) || (end >= gCutsceneTimer)) { - func(c); + if (end == -1 || end >= gCutsceneTimer) { + event(c); } } return 0; } -s32 set_cutscene_phase_at_frame(s32 phase, s16 frame) { +/** + * Set gCutsceneObjSpawn when gCutsceneTimer == `frame`. + * + * @see intro_scene.inc.c for details on which objects are spawned. + */ +s32 cutscene_spawn_obj(s32 obj, s16 frame) { if (frame == gCutsceneTimer) { - sCutscenePhase = phase; + gCutsceneObjSpawn = obj; } return 0; } -void func_80299C98(s16 a, s16 b, s16 c) { - if (a > D_8033B230.unk10) { - D_8033B230.unk10 = a; - D_8033B230.unk18 = b; - D_8033B230.unk16 = c; +/** + * Start shaking the camera's field of view. + * + * @param shakeSpeed How fast the shake should progress through its period. The shake offset is + * calculated from coss(), so this parameter can be thought of as an angular velocity. + */ +void set_fov_shake(s16 amplitude, s16 decay, s16 shakeSpeed) { + if (amplitude > sFOVState.shakeAmplitude) { + sFOVState.shakeAmplitude = amplitude; + sFOVState.decay = decay; + sFOVState.shakeSpeed = shakeSpeed; } } -void func_80299D00(s16 a, s16 b, s16 c, f32 d, f32 e, f32 f, f32 g) { - a = func_80289738(a, d, e, f, g); +/** + * Start shaking the camera's field of view, but reduce `amplitude` by distance from camera + */ +void set_fov_shake_from_point(s16 amplitude, s16 decay, s16 shakeSpeed, f32 maxDist, f32 posX, f32 posY, f32 posZ) { + amplitude = reduce_by_dist_from_camera(amplitude, maxDist, posX, posY, posZ); - if (a != 0) { - if (a > D_8033B230.unk10) // literally use the function above you silly nintendo, smh - { - D_8033B230.unk10 = a; - D_8033B230.unk18 = b; - D_8033B230.unk16 = c; + if (amplitude != 0) { + if (amplitude > sFOVState.shakeAmplitude) { // literally use the function above you silly nintendo, smh + sFOVState.shakeAmplitude = amplitude; + sFOVState.decay = decay; + sFOVState.shakeSpeed = shakeSpeed; } } } -void func_80299DB4(struct GraphNodePerspective *a) { - if (D_8033B230.unk10 != 0.f) { - D_8033B230.unk8 = coss(D_8033B230.unk14) * D_8033B230.unk10 / 256; - D_8033B230.unk14 += D_8033B230.unk16; - camera_approach_f32_symmetric_bool(&D_8033B230.unk10, 0.f, D_8033B230.unk18); - a->fov += D_8033B230.unk8; +/** + * Add a cyclic offset to the camera's field of view based on a cosine wave + */ +void shake_camera_fov(struct GraphNodePerspective *perspective) { + if (sFOVState.shakeAmplitude != 0.f) { + sFOVState.fovOffset = coss(sFOVState.shakePhase) * sFOVState.shakeAmplitude / 0x100; + sFOVState.shakePhase += sFOVState.shakeSpeed; + camera_approach_f32_symmetric_bool(&sFOVState.shakeAmplitude, 0.f, sFOVState.decay); + perspective->fov += sFOVState.fovOffset; } else { - D_8033B230.unk14 = 0; + sFOVState.shakePhase = 0; } } -static void unused_deactivate_sleeping_camera(UNUSED struct MarioState *m) { - gCameraFlags2 &= ~CAM_FLAG_2_SLEEPING; +static UNUSED void unused_deactivate_sleeping_camera(UNUSED struct MarioState *m) { + sStatusFlags &= ~CAM_FLAG_SLEEPING; } void set_fov_30(UNUSED struct MarioState *m) { - D_8033B230.fieldOfView = 30.f; + sFOVState.fov = 30.f; } void approach_fov_20(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 20.f, 0.3f); + camera_approach_f32_symmetric_bool(&sFOVState.fov, 20.f, 0.3f); } void set_fov_45(UNUSED struct MarioState *m) { - D_8033B230.fieldOfView = 45.f; + sFOVState.fov = 45.f; } void set_fov_29(UNUSED struct MarioState *m) { - D_8033B230.fieldOfView = 29.f; + sFOVState.fov = 29.f; } void zoom_fov_30(UNUSED struct MarioState *m) { - // Pretty sure approach_f32_exponential_bool would do a much nicer job here, but you do you, + // Pretty sure approach_f32_asymptotic_bool would do a much nicer job here, but you do you, // Nintendo. - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 30.f, - (30.f - D_8033B230.fieldOfView) / 60.f); + camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, (30.f - sFOVState.fov) / 60.f); } -void zoom_fov_for_sleep(struct MarioState *m) { - gCameraFlags2 &= ~CAM_FLAG_2_SLEEPING; +/** + * This is the default fov function. It makes fov approach 45 degrees, and it handles zooming in when + * mario falls a sleep. + */ +void fov_default(struct MarioState *m) { + sStatusFlags &= ~CAM_FLAG_SLEEPING; if ((m->action == ACT_SLEEPING) || (m->action == ACT_START_SLEEPING)) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 30.f, - (30.f - D_8033B230.fieldOfView) / 30.f); - gCameraFlags2 |= CAM_FLAG_2_SLEEPING; + camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, (30.f - sFOVState.fov) / 30.f); + sStatusFlags |= CAM_FLAG_SLEEPING; } else { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 45.f, - (45.f - D_8033B230.fieldOfView) / 30.f); - D_8033B230.unkC = 0; + camera_approach_f32_symmetric_bool(&sFOVState.fov, 45.f, (45.f - sFOVState.fov) / 30.f); + sFOVState.unusedIsSleeping = 0; } - if (m->area->camera->cutscene == CUTSCENE_0F_TODO) { - D_8033B230.fieldOfView = 45.f; + if (m->area->camera->cutscene == CUTSCENE_0F_UNUSED) { + sFOVState.fov = 45.f; } } -static void unused_8029A100(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 30.f, 1.f); +//??! Literally the exact same as below +static UNUSED void unused_approach_fov_30(UNUSED struct MarioState *m) { + camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, 1.f); } void approach_fov_30(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 30.f, 1.f); + camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, 1.f); } void approach_fov_60(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 60.f, 1.f); + camera_approach_f32_symmetric_bool(&sFOVState.fov, 60.f, 1.f); } void approach_fov_45(struct MarioState *m) { - f32 targetFoV = D_8033B230.fieldOfView; + f32 targetFoV = sFOVState.fov; - if ((m->area->camera->currPreset == CAMERA_PRESET_FIXED_REF_POINT) - && (m->area->camera->cutscene == 0)) { + if (m->area->camera->mode == CAMERA_MODE_FIXED && m->area->camera->cutscene == 0) { targetFoV = 45.f; } else { targetFoV = 45.f; } - D_8033B230.fieldOfView = approach_f32(D_8033B230.fieldOfView, targetFoV, 2.f, 2.f); + sFOVState.fov = approach_f32(sFOVState.fov, targetFoV, 2.f, 2.f); } void approach_fov_80(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&D_8033B230.fieldOfView, 80.f, 3.5f); + camera_approach_f32_symmetric_bool(&sFOVState.fov, 80.f, 3.5f); } -void func_8029A288(struct MarioState *m) { - f32 targetFoV = D_8033B230.fieldOfView; +/** + * Sets the fov in BBH. + * If there's a cutscene, sets fov to 45. Otherwise sets fov to 60. + */ +void set_fov_bbh(struct MarioState *m) { + f32 targetFoV = sFOVState.fov; - if ((m->area->camera->currPreset == CAMERA_PRESET_FIXED_REF_POINT) - && (m->area->camera->cutscene == 0)) { + if (m->area->camera->mode == CAMERA_MODE_FIXED && m->area->camera->cutscene == 0) { targetFoV = 60.f; } else { targetFoV = 45.f; } - D_8033B230.fieldOfView = approach_f32(D_8033B230.fieldOfView, targetFoV, 2.f, 2.f); + sFOVState.fov = approach_f32(sFOVState.fov, targetFoV, 2.f, 2.f); } -Gfx *geo_camera_fov(s32 a, struct GraphNode *b, UNUSED struct AllocOnlyPool *c) { - struct GraphNodePerspective *sp24 = (struct GraphNodePerspective *) b; +/** + * Sets the field of view for the GraphNodeCamera + */ +Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context) { + struct GraphNodePerspective *perspective = (struct GraphNodePerspective *) g; struct MarioState *marioState = &gMarioStates[0]; - u8 sp1F = D_8033B230.unk0; + u8 fovFunc = sFOVState.fovFunc; - if (a == 1) { - switch (sp1F) { - case 1: + if (callContext == GEO_CONTEXT_RENDER) { + switch (fovFunc) { + case CAM_FOV_SET_45: set_fov_45(marioState); break; - case 13: + case CAM_FOV_SET_29: set_fov_29(marioState); break; - case 12: + case CAM_FOV_ZOOM_30: zoom_fov_30(marioState); break; - case 2: - zoom_fov_for_sleep(marioState); + case CAM_FOV_DEFAULT: + fov_default(marioState); break; - case 7: - func_8029A288(marioState); + case CAM_FOV_BBH: + set_fov_bbh(marioState); break; - case 4: + case CAM_FOV_APP_45: approach_fov_45(marioState); break; - case 5: + case CAM_FOV_SET_30: set_fov_30(marioState); break; - case 6: + case CAM_FOV_APP_20: approach_fov_20(marioState); break; - case 9: + case CAM_FOV_APP_80: approach_fov_80(marioState); break; - case 10: + case CAM_FOV_APP_30: approach_fov_30(marioState); break; - case 11: + case CAM_FOV_APP_60: approach_fov_60(marioState); break; + //! No default case } } - sp24->fov = D_8033B230.fieldOfView; - func_80299DB4(sp24); + perspective->fov = sFOVState.fov; + shake_camera_fov(perspective); return NULL; } -void set_fov_function(u8 a) { - D_8033B230.unk0 = a; +/** + * Change the camera's FOV mode. + * + * @see geo_camera_fov + */ +void set_fov_function(u8 func) { + sFOVState.fovFunc = func; } -void func_8029A494(u8 a) { - switch (a) { +/** + * Start a preset fov shake. Used in cutscenes + */ +void cutscene_set_fov_shake_preset(u8 preset) { + switch (preset) { case 1: - func_80299C98(0x100, 0x30, -0x8000); + set_fov_shake(0x100, 0x30, 0x8000); break; case 2: - func_80299C98(0x400, 0x20, 0x4000); + set_fov_shake(0x400, 0x20, 0x4000); break; } } -void func_8029A514(u8 a, f32 b, f32 c, f32 d) { - switch (a) { - case 1: - func_80299D00(0x100, 0x30, -0x8000, 3000.f, b, c, d); +/** + * Start a preset fov shake that is reduced by the point's distance from the camera. + * Used in set_camera_shake_from_point + * + * @see set_camera_shake_from_point + */ +void set_fov_shake_from_point_preset(u8 preset, f32 posX, f32 posY, f32 posZ) { + switch (preset) { + case SHAKE_FOV_SMALL: + set_fov_shake_from_point(0x100, 0x30, 0x8000, 3000.f, posX, posY, posZ); break; - case 3: - func_80299D00(0x200, 0x30, -0x8000, 4000.f, b, c, d); + case SHAKE_FOV_MEDIUM: + set_fov_shake_from_point(0x200, 0x30, 0x8000, 4000.f, posX, posY, posZ); break; - case 4: - func_80299D00(0x300, 0x30, -0x8000, 6000.f, b, c, d); + case SHAKE_FOV_LARGE: + set_fov_shake_from_point(0x300, 0x30, 0x8000, 6000.f, posX, posY, posZ); break; - case 2: - func_80299D00(0x800, 0x20, 0x4000, 3000.f, b, c, d); + case SHAKE_FOV_UNUSED: + set_fov_shake_from_point(0x800, 0x20, 0x4000, 3000.f, posX, posY, posZ); break; } } -static void unused_8029A664(struct Object *o, f32 b, f32 c, f32 d) { - f32 sp1C = RandomFloat(); +/** + * Offset an object's position in a random direction within the given bounds. + */ +static UNUSED void unused_displace_obj_randomly(struct Object *o, f32 xRange, f32 yRange, f32 zRange) { + f32 rnd = RandomFloat(); - o->oPosX += (sp1C * b - b / 2.f); - o->oPosY += (sp1C * c - c / 2.f); - o->oPosZ += (sp1C * d - d / 2.f); + o->oPosX += (rnd * xRange - xRange / 2.f); + o->oPosY += (rnd * yRange - yRange / 2.f); + o->oPosZ += (rnd * zRange - zRange / 2.f); } -static void unused_8029A724(struct Object *o, f32 b, f32 c) { - f32 sp1C = RandomFloat(); +/** + * Rotate an object in a random direction within the given bounds. + */ +static UNUSED void unused_rotate_obj_randomly(struct Object *o, f32 pitchRange, f32 yawRange) { + f32 rnd = RandomFloat(); - o->oMoveAnglePitch += (s16)(sp1C * b - b / 2.f); - o->oMoveAngleYaw += (s16)(sp1C * c - c / 2.f); + o->oMoveAnglePitch += (s16)(rnd * pitchRange - pitchRange / 2.f); + o->oMoveAngleYaw += (s16)(rnd * yawRange - yawRange / 2.f); } -void func_8029A7DC(struct Object *o, Vec3f b, s16 c, s16 d, s16 e, s16 f) { - f32 sp34; - s16 sp32, sp30; - Vec3f sp24; +/** + * Rotate the object towards the point `point`. + */ +void obj_rotate_towards_point(struct Object *o, Vec3f point, s16 pitchOff, s16 yawOff, s16 pitchDiv, s16 yawDiv) { + f32 dist; + s16 pitch, yaw; + Vec3f oPos; - object_pos_to_vec3f(sp24, o); - vec3f_get_dist_and_angle(sp24, b, &sp34, &sp32, &sp30); - o->oMoveAnglePitch = approach_s16_exponential(o->oMoveAnglePitch, c - sp32, e); - o->oMoveAngleYaw = approach_s16_exponential(o->oMoveAngleYaw, sp30 + d, f); + object_pos_to_vec3f(oPos, o); + vec3f_get_dist_and_angle(oPos, point, &dist, &pitch, &yaw); + o->oMoveAnglePitch = approach_s16_asymptotic(o->oMoveAnglePitch, pitchOff - pitch, pitchDiv); + o->oMoveAngleYaw = approach_s16_asymptotic(o->oMoveAngleYaw, yaw + yawOff, yawDiv); } #include "behaviors/intro_peach.inc.c" diff --git a/src/game/camera.h b/src/game/camera.h index 38b9b42..ee48f91 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -8,21 +8,49 @@ #include "level_table.h" +/** + * @file camera.h + * Constants, defines, and structs used by the camera system. + * @see camera.inc.c + */ + #define ABS(x) ((x) > 0.f ? (x) : -(x)) #define ABS2(x) ((x) >= 0.f ? (x) : -(x)) +/** + * Converts an angle in degrees to sm64's s16 angle units. For example, DEGREES(90) == 0x4000 + * This should be used mainly to make camera code clearer at first glance. + */ +#define DEGREES(x) (x * 0x10000 / 360) + #define LEVEL_AREA_INDEX(levelNum, areaNum) ((levelNum << 4) + areaNum) +/** + * Helper macro for defining which areas of a level should zoom out the camera when the game is paused. + * Because a mask is used by two levels, the pattern will repeat when more than 4 areas are used by a level. + */ +#define ZOOMOUT_AREA_MASK(level1Area1, level1Area2, level1Area3, level1Area4, \ + level2Area1, level2Area2, level2Area3, level2Area4) \ + ((level2Area4) << 7 | \ + (level2Area3) << 6 | \ + (level2Area2) << 5 | \ + (level2Area1) << 4 | \ + (level1Area4) << 3 | \ + (level1Area3) << 2 | \ + (level1Area2) << 1 | \ + (level1Area1) << 0) + + #define AREA_BBH LEVEL_AREA_INDEX(LEVEL_BBH, 1) #define AREA_CCM_OUTSIDE LEVEL_AREA_INDEX(LEVEL_CCM, 1) #define AREA_CCM_SLIDE LEVEL_AREA_INDEX(LEVEL_CCM, 2) #define AREA_CASTLE_LOBBY LEVEL_AREA_INDEX(LEVEL_CASTLE, 1) #define AREA_CASTLE_TIPPY LEVEL_AREA_INDEX(LEVEL_CASTLE, 2) -#define AREA_CASTLE_BASTEMENT LEVEL_AREA_INDEX(LEVEL_CASTLE, 3) +#define AREA_CASTLE_BASEMENT LEVEL_AREA_INDEX(LEVEL_CASTLE, 3) #define AREA_HMC LEVEL_AREA_INDEX(LEVEL_HMC, 1) #define AREA_SSL_OUTSIDE LEVEL_AREA_INDEX(LEVEL_SSL, 1) #define AREA_SSL_PYRAMID LEVEL_AREA_INDEX(LEVEL_SSL, 2) -#define AREA_SSL_EYEROK LEVEL_AREA_INDEX(LEVEL_SSL, 3) +#define AREA_SSL_EYEROK LEVEL_AREA_INDEX(LEVEL_SSL, 3) #define AREA_BOB LEVEL_AREA_INDEX(LEVEL_BOB, 1) #define AREA_SL_OUTSIDE LEVEL_AREA_INDEX(LEVEL_SL, 1) #define AREA_SL_IGLOO LEVEL_AREA_INDEX(LEVEL_SL, 2) @@ -35,7 +63,7 @@ #define AREA_THI_WIGGLER LEVEL_AREA_INDEX(LEVEL_THI, 3) #define AREA_TTC LEVEL_AREA_INDEX(LEVEL_TTC, 1) #define AREA_RR LEVEL_AREA_INDEX(LEVEL_RR, 1) -#define AREA_OUTSIDE_CASTLE LEVEL_AREA_INDEX(LEVEL_CASTLE_GROUNDS, 1) +#define AREA_CASTLE_GROUNDS LEVEL_AREA_INDEX(LEVEL_CASTLE_GROUNDS, 1) #define AREA_BITDW LEVEL_AREA_INDEX(LEVEL_BITDW, 1) #define AREA_VCUTM LEVEL_AREA_INDEX(LEVEL_VCUTM, 1) #define AREA_BITFS LEVEL_AREA_INDEX(LEVEL_BITFS, 1) @@ -61,49 +89,72 @@ #define CAM_MODE_LAKITU_WAS_ZOOMED_OUT 0x02 #define CAM_MODE_MARIO_SELECTED 0x04 -#define CAM_ANGLE_LAKITU_MARIO 1 -#define CAM_ANGLE_LAKITU_FIXED 2 +#define CAM_SELECTION_MARIO 1 +#define CAM_SELECTION_FIXED 2 + +#define CAM_ANGLE_MARIO 1 +#define CAM_ANGLE_LAKITU 2 + +#define CAMERA_MODE_NONE 0x00 +#define CAMERA_MODE_RADIAL 0x01 +#define CAMERA_MODE_OUTWARD_RADIAL 0x02 +#define CAMERA_MODE_BEHIND_MARIO 0x03 +#define CAMERA_MODE_CLOSE 0x04 // Inside Castle / Big Boo's Haunt +#define CAMERA_MODE_C_UP 0x06 +#define CAMERA_MODE_WATER_SURFACE 0x08 +#define CAMERA_MODE_SLIDE_HOOT 0x09 +#define CAMERA_MODE_INSIDE_CANNON 0x0A +#define CAMERA_MODE_BOSS_FIGHT 0x0B +#define CAMERA_MODE_PARALLEL_TRACKING 0x0C +#define CAMERA_MODE_FIXED 0x0D +#define CAMERA_MODE_8_DIRECTIONS 0x0E // AKA Parallel Camera, Bowser Courses & Rainbow Road +#define CAMERA_MODE_FREE_ROAM 0x10 +#define CAMERA_MODE_SPIRAL_STAIRS 0x11 #define CAM_MOVE_RETURN_TO_MIDDLE 0x0001 #define CAM_MOVE_ZOOMED_OUT 0x0002 #define CAM_MOVE_ROTATE_RIGHT 0x0004 #define CAM_MOVE_ROTATE_LEFT 0x0008 -#define CAM_MOVE_UNKNOWN_5 0x0010 -#define CAM_MOVE_UNKNOWN_6 0x0020 -#define CAM_MOVE_UNKNOWN_7 0x0040 +#define CAM_MOVE_ENTERED_ROTATE_SURFACE 0x0010 +#define CAM_MOVE_METAL_BELOW_WATER 0x0020 +#define CAM_MOVE_FIX_IN_PLACE 0x0040 #define CAM_MOVE_UNKNOWN_8 0x0080 -#define CAM_MOVE_INTO_C_UP 0x0100 -#define CAM_MOVE_UNKNOWN_10 0x0200 +#define CAM_MOVING_INTO_MODE 0x0100 +#define CAM_MOVE_STARTED_EXITING_C_UP 0x0200 #define CAM_MOVE_UNKNOWN_11 0x0400 #define CAM_MOVE_INIT_CAMERA 0x0800 -#define CAM_MOVE_UNK1000 0x1000 +#define CAM_MOVE_ALREADY_ZOOMED_OUT 0x1000 #define CAM_MOVE_C_UP_MODE 0x2000 #define CAM_MOVE_SUBMERGED 0x4000 #define CAM_MOVE_PAUSE_SCREEN 0x8000 -#define CAM_FLAG_1_UNKNOWN_0 0x01 -#define CAM_FLAG_1_UNKNOWN_1 0x02 -#define CAM_FLAG_1_UNKNOWN_2 0x04 -#define CAM_FLAG_1_UNUSED_3 0x08 -#define CAM_FLAG_1_UNUSED_4 0x10 -#define CAM_FLAG_1_UNKNOWN_5 0x20 +#define CAM_MOVE_ROTATE /**/ (CAM_MOVE_ROTATE_RIGHT | CAM_MOVE_ROTATE_LEFT | CAM_MOVE_RETURN_TO_MIDDLE) +/// These flags force the camera to move a certain way +#define CAM_MOVE_RESTRICT /**/ (CAM_MOVE_ENTERED_ROTATE_SURFACE | CAM_MOVE_METAL_BELOW_WATER | CAM_MOVE_FIX_IN_PLACE | CAM_MOVE_UNKNOWN_8) -#define CAM_FLAG_2_SMOOTH_MOVEMENT 0x0001 -#define CAM_FLAG_2_UNKNOWN_1 0x0002 -#define CAM_FLAG_2_FRAME_AFTER_CAM_INIT 0x0004 -#define CAM_FLAG_2_UNKNOWN_3 0x0008 -#define CAM_FLAG_2_CCM_SLIDE_SHORTCUT 0x0010 -#define CAM_FLAG_2_COLLIDING_WITH_WALL 0x0020 -#define CAM_FLAG_2_SLEEPING 0x0040 -#define CAM_FLAG_2_UNUSED_7 0x0080 -#define CAM_FLAG_2_UNUSED_8 0x0100 -#define CAM_FLAG_2_UNKNOWN_9 0x0200 -#define CAM_FLAG_2_UNKNOWN_10 0x0400 -#define CAM_FLAG_2_UNKNOWN_11 0x0800 -#define CAM_FLAG_2_BLOCK_LEVEL_SPECIFIC_UPDATES 0x1000 -#define CAM_FLAG_2_UNUSED_13 0x2000 -#define CAM_FLAG_2_UNUSED_CUTSCENE_ACTIVE 0x4000 -#define CAM_FLAG_2_BEHIND_MARIO_POST_DOOR 0x8000 +#define CAM_SOUND_C_UP_PLAYED 0x01 +#define CAM_SOUND_MARIO_ACTIVE 0x02 +#define CAM_SOUND_NORMAL_ACTIVE 0x04 +#define CAM_SOUND_UNUSED_SELECT_MARIO 0x08 +#define CAM_SOUND_UNUSED_SELECT_FIXED 0x10 +#define CAM_SOUND_FIXED_ACTIVE 0x20 + +#define CAM_FLAG_SMOOTH_MOVEMENT 0x0001 +#define CAM_FLAG_BLOCK_SMOOTH_MOVEMENT 0x0002 +#define CAM_FLAG_FRAME_AFTER_CAM_INIT 0x0004 +#define CAM_FLAG_CHANGED_PARTRACK_INDEX 0x0008 +#define CAM_FLAG_CCM_SLIDE_SHORTCUT 0x0010 +#define CAM_FLAG_CAM_NEAR_WALL 0x0020 +#define CAM_FLAG_SLEEPING 0x0040 +#define CAM_FLAG_UNUSED_7 0x0080 +#define CAM_FLAG_UNUSED_8 0x0100 +#define CAM_FLAG_COLLIDED_WITH_WALL 0x0200 +#define CAM_FLAG_START_TRANSITION 0x0400 +#define CAM_FLAG_TRANSITION_OUT_OF_C_UP 0x0800 +#define CAM_FLAG_BLOCK_AREA_PROCESSING 0x1000 +#define CAM_FLAG_UNUSED_13 0x2000 +#define CAM_FLAG_UNUSED_CUTSCENE_ACTIVE 0x4000 +#define CAM_FLAG_BEHIND_MARIO_POST_DOOR 0x8000 #define CAM_STATUS_NONE 0 #define CAM_STATUS_MARIO 1 << 0 @@ -124,99 +175,170 @@ #define SHAKE_FALL_DAMAGE 9 #define SHAKE_SHOCK 10 -#define SHAKE_2_UNKNOWN_1 1 -#define SHAKE_2_UNKNOWN_2 2 -#define SHAKE_2_UNKNOWN_3 3 -#define SHAKE_2_UNKNOWN_5 5 -#define SHAKE_2_UNKNOWN_6 6 -#define SHAKE_2_UNKNOWN_7 7 -#define SHAKE_2_UNKNOWN_8 8 -#define SHAKE_2_JRB_SHIP_DRAIN 9 -#define SHAKE_2_FALLING_BITS_PLAT 10 +#define SHAKE_ENV_EXPLOSION 1 +#define SHAKE_ENV_BOWSER_THROW_BOUNCE 2 +#define SHAKE_ENV_BOWSER_JUMP 3 +#define SHAKE_ENV_UNUSED_5 5 +#define SHAKE_ENV_UNUSED_6 6 +#define SHAKE_ENV_UNUSED_7 7 +#define SHAKE_ENV_PYRAMID_EXPLODE 8 +#define SHAKE_ENV_JRB_SHIP_DRAIN 9 +#define SHAKE_ENV_FALLING_BITS_PLAT 10 -#define CUTSCENE_DOOR_0 130 -#define CUTSCENE_DOOR_1 131 -#define CUTSCENE_ENTER_CANNON 133 -#define CUTSCENE_ENTER_PAINTING 134 -#define CUTSCENE_DEATH_EXIT 135 -#define CUTSCENE_DOOR_WARP 139 -#define CUTSCENE_DOOR_A 140 -#define CUTSCENE_DOOR_B 141 -#define CUTSCENE_INTRO_PEACH 142 -#define CUTSCENE_STAR_DANCE_1_1 143 -#define CUTSCENE_ENTER_BOWSER_ARENA 144 -#define CUTSCENE_0F_TODO 145 -#define CUTSCENE_11_TODO 147 -#define CUTSCENE_SLIDING_DOORS_OPEN 149 -#define CUTSCENE_PREPARE_CANNON 150 -#define CUTSCENE_UNLOCK_KEY_DOOR 151 -#define CUTSCENE_STANDING_DEATH 152 -#define CUTSCENE_DEATH_2 153 -#define CUTSCENE_DEATH_ON_BACK 154 -#define CUTSCENE_QUICKSAND_DEATH 155 -#define CUTSCENE_SUFFOCATION_DEATH 156 -#define CUTSCENE_EXIT_BOWSER_SUCC 157 -#define CUTSCENE_1C_TODO 158 -#define CUTSCENE_WATER_DEATH 159 //Not in cutscene switch -#define CUTSCENE_EXIT_PAINTING_SUCC 160 -#define CUTSCENE_CAP_SWITCH_PRESS 161 -#define CUTSCENE_DIALOG_1 162 -#define CUTSCENE_DIALOG_2 163 -#define CUTSCENE_ENTER_PYRAMID_TOP 164 -#define CUTSCENE_STAR_DANCE_2 165 -#define CUTSCENE_STAR_DANCE_3 166 -#define CUTSCENE_KEY_DANCE 167 -#define CUTSCENE_26_TODO 168 -#define CUTSCENE_EXIT_BBH_SUCC 169 -#define CUTSCENE_NONPAINTING_DEATH 170 -#define CUTSCENE_READ_MESSAGE 171 -#define CUTSCENE_PEACH_END 172 -#define CUTSCENE_STAR_SPAWN 173 -#define CUTSCENE_GRAND_STAR 174 -#define CUTSCENE_STAR_DANCE_1_2 175 -#define CUTSCENE_SPECIAL_STAR_SPAWN 176 -#define CUTSCENE_END_WAVING 177 -#define CUTSCENE_CREDITS 178 -#define CUTSCENE_EXIT_WATERFALL 179 -#define CUTSCENE_EXIT_FALL_WMOTR 180 -#define CUTSCENE_ENTER_POOL 181 +#define SHAKE_FOV_SMALL 1 +#define SHAKE_FOV_UNUSED 2 +#define SHAKE_FOV_MEDIUM 3 +#define SHAKE_FOV_LARGE 4 -// sorted +#define SHAKE_POS_SMALL 1 +#define SHAKE_POS_MEDIUM 2 +#define SHAKE_POS_LARGE 3 +#define SHAKE_POS_BOWLING_BALL 4 -struct CameraPlayerStatus +#define CUTSCENE_DOOR_PULL 130 +#define CUTSCENE_DOOR_PUSH 131 +#define CUTSCENE_ENTER_CANNON 133 +#define CUTSCENE_ENTER_PAINTING 134 +#define CUTSCENE_DEATH_EXIT 135 +#define CUTSCENE_DOOR_WARP 139 +#define CUTSCENE_DOOR_PULL_MODE 140 +#define CUTSCENE_DOOR_PUSH_MODE 141 +#define CUTSCENE_INTRO_PEACH 142 +#define CUTSCENE_DANCE_ROTATE 143 +#define CUTSCENE_ENTER_BOWSER_ARENA 144 +#define CUTSCENE_0F_UNUSED 145 // Never activated, stub cutscene functions +#define CUTSCENE_UNUSED_EXIT 147 // Never activated +#define CUTSCENE_SLIDING_DOORS_OPEN 149 +#define CUTSCENE_PREPARE_CANNON 150 +#define CUTSCENE_UNLOCK_KEY_DOOR 151 +#define CUTSCENE_STANDING_DEATH 152 +#define CUTSCENE_DEATH_ON_STOMACH 153 +#define CUTSCENE_DEATH_ON_BACK 154 +#define CUTSCENE_QUICKSAND_DEATH 155 +#define CUTSCENE_SUFFOCATION_DEATH 156 +#define CUTSCENE_EXIT_BOWSER_SUCC 157 +#define CUTSCENE_EXIT_BOWSER_DEATH 158 // Never activated +#define CUTSCENE_WATER_DEATH 159 // Not in cutscene switch +#define CUTSCENE_EXIT_PAINTING_SUCC 160 +#define CUTSCENE_CAP_SWITCH_PRESS 161 +#define CUTSCENE_DIALOG 162 +#define CUTSCENE_RACE_DIALOG 163 +#define CUTSCENE_ENTER_PYRAMID_TOP 164 +#define CUTSCENE_DANCE_FLY_AWAY 165 +#define CUTSCENE_DANCE_CLOSEUP 166 +#define CUTSCENE_KEY_DANCE 167 +#define CUTSCENE_SSL_PYRAMID_EXPLODE 168 // Never activated +#define CUTSCENE_EXIT_SPECIAL_SUCC 169 +#define CUTSCENE_NONPAINTING_DEATH 170 +#define CUTSCENE_READ_MESSAGE 171 +#define CUTSCENE_ENDING 172 +#define CUTSCENE_STAR_SPAWN 173 +#define CUTSCENE_GRAND_STAR 174 +#define CUTSCENE_DANCE_DEFAULT 175 +#define CUTSCENE_RED_COIN_STAR_SPAWN 176 +#define CUTSCENE_END_WAVING 177 +#define CUTSCENE_CREDITS 178 +#define CUTSCENE_EXIT_WATERFALL 179 +#define CUTSCENE_EXIT_FALL_WMOTR 180 +#define CUTSCENE_ENTER_POOL 181 + +/** + * Stop the cutscene. + */ +#define CUTSCENE_STOP 0x8000 +/** + * Play the current cutscene shot indefinitely (until canceled). + */ +#define CUTSCENE_LOOP 0x7FFF + +#define HAND_CAM_SHAKE_OFF 0 +#define HAND_CAM_SHAKE_CUTSCENE 1 +#define HAND_CAM_SHAKE_UNUSED 2 +#define HAND_CAM_SHAKE_HANG_OWL 3 +#define HAND_CAM_SHAKE_HIGH 4 +#define HAND_CAM_SHAKE_STAR_DANCE 5 +#define HAND_CAM_SHAKE_LOW 6 + +#define DOOR_DEFAULT 0 +#define DOOR_LEAVING_SPECIAL 1 +#define DOOR_ENTER_LOBBY 2 + +// Might rename these to reflect what they are used for instead "SET_45" etc. +#define CAM_FOV_SET_45 1 +#define CAM_FOV_DEFAULT 2 +#define CAM_FOV_APP_45 4 +#define CAM_FOV_SET_30 5 +#define CAM_FOV_APP_20 6 +#define CAM_FOV_BBH 7 +#define CAM_FOV_APP_80 9 +#define CAM_FOV_APP_30 10 +#define CAM_FOV_APP_60 11 +#define CAM_FOV_ZOOM_30 12 +#define CAM_FOV_SET_29 13 + +#define CAM_EVENT_CANNON 1 +#define CAM_EVENT_SHOT_FROM_CANNON 2 +#define CAM_EVENT_UNUSED_3 3 +#define CAM_EVENT_BOWSER_INIT 4 +#define CAM_EVENT_DOOR_WARP 5 +#define CAM_EVENT_DOOR 6 +#define CAM_EVENT_BOWSER_JUMP 7 +#define CAM_EVENT_BOWSER_THROW_BOUNCE 8 +#define CAM_EVENT_START_INTRO 9 +#define CAM_EVENT_START_GRAND_STAR 10 +#define CAM_EVENT_START_ENDING 11 +#define CAM_EVENT_START_END_WAVING 12 +#define CAM_EVENT_START_CREDITS 13 + +/** + * A copy of player information that is relevant to the camera. + */ +struct PlayerCameraState { + /** + * Mario's action on this frame. + */ /*0x00*/ u32 action; /*0x04*/ Vec3f pos; /*0x10*/ Vec3s faceAngle; - /*0x16*/ Vec3s unk16; - /*0x1C*/ s16 unk1C[2]; //only unk1C[1] seems used, represents an effective cutscene + /*0x16*/ Vec3s headRotation; + /*0x1C*/ s16 unused; + /** + * Set to nonzero when an event, such as entering a door, starting the credits, or throwing bowser, + * has happened on this frame. + */ + /*0x1E*/ s16 cameraEvent; /*0x20*/ struct Object *usedObj; }; -struct TransitionCamera +/** + * Struct containing info that is used when transition_next_state() is called. Stores the intermediate + * distances and angular displacements from lakitu's goal position and focus. + */ +struct TransitionInfo { - /*0x00*/ s16 pitch1; - /*0x02*/ s16 yaw1; - /*0x04*/ f32 dist1; - /*0x08*/ s16 pitch2; - /*0x0A*/ s16 yaw2; - /*0x0C*/ f32 dist2; - /*0x10*/ s32 timer; + /*0x00*/ s16 posPitch; + /*0x02*/ s16 posYaw; + /*0x04*/ f32 posDist; + /*0x08*/ s16 focPitch; + /*0x0A*/ s16 focYaw; + /*0x0C*/ f32 focDist; + /*0x10*/ s32 framesLeft; /*0x14*/ Vec3f marioPos; /*0x20*/ u8 pad; // for the structs to align, there has to be an extra unused variable here. type is unknown. }; -struct Struct8033B2B8 +/** + * A point that's used in a spline, controls the direction to move the camera in + * during the shake effect. + */ +struct HandheldShakePoint { - /*0x00*/ s8 unk0; - union { - /*0x08*/ Vec3s unk8; - /*0x08*/ long long int force_structure_alignment; - } myUnion; + /*0x00*/ s8 index; // only set to -1 + /*0x04 (aligned)*/ u32 pad; + /*0x08*/ Vec3s point; }; // size = 0x10 -// unsorted - // Camera command procedures are marked as returning s32, but none of them // actually return a value. This causes undefined behavior, which we'd rather // avoid on modern GCC. Hence, typedef. Interestingly, the void vs s32 @@ -227,37 +349,85 @@ typedef void CmdRet; typedef s32 CmdRet; #endif -typedef CmdRet (*CameraCommandProc)(struct LevelCamera *a); +// These are the same type, but the name that is used depends on context. +/** + * A function that is called by CameraTriggers and cutscene shots. + * These are concurrent: multiple CameraEvents can occur on the same frame. + */ +typedef CmdRet (*CameraEvent)(struct Camera *c); +/** + * The same type as a CameraEvent, but because these are generally longer, and happen in sequential + * order, they're are called "shots," a term taken from cinematography. + * + * To further tell the difference: CutsceneShots usually call multiple CameraEvents at once, but only + * one CutsceneShot is ever called on a given frame. + */ +typedef CameraEvent CutsceneShot; -struct TableCamera +/** + * Defines a bounding box which activates an event while mario is inside + */ +struct CameraTrigger { + /** + * The area this should be checked in, or -1 if it should run in every area of the level. + * + * Triggers with area set to -1 are run by default, they don't care if mario is inside their bounds. + * However, they are only active if mario is not already inside an area-specific trigger's + * boundaries. + */ s8 area; - CameraCommandProc unk4; - s16 unk8; - s16 unkA; - s16 unkC; - s16 unkE; - s16 unk10; - s16 unk12; - s16 unk14; + /// A function that gets called while Mario is in the trigger bounds + CameraEvent event; + // The (x,y,z) position of the center of the bounding box + s16 centerX; + s16 centerY; + s16 centerZ; + // The max displacement in x, y, and z from the center for a point to be considered inside the + // bounding box + s16 boundsX; + s16 boundsY; + s16 boundsZ; + /// This angle rotates mario's offset from the box's origin, before it is checked for being inside. + s16 boundsYaw; }; -struct CutsceneTableEntry +/** + * A camera shot that is active for a number of frames. + * Together, a sequence of shots makes up a cutscene. + */ +struct Cutscene { - CameraCommandProc unk0; - s16 unk4; + /// The function that gets called. + CutsceneShot shot; + /// How long the shot lasts. + s16 duration; }; -struct Struct8033B230 +/** + * Info for the camera's field of view and the FOV shake effect. + */ +struct CameraFOVStatus { - /*0x00*/ u8 unk0; - /*0x04*/ f32 fieldOfView; - /*0x08*/ f32 unk8; - /*0x0C*/ u32 unkC; - /*0x10*/ f32 unk10; - /*0x14*/ s16 unk14; - /*0x16*/ s16 unk16; - /*0x18*/ s16 unk18; + /// The current function being used to set the camera's field of view (before any fov shake is applied). + /*0x00*/ u8 fovFunc; + /// The current field of view in degrees + /*0x04*/ f32 fov; + + // Fields used by shake_camera_fov() + + /// The amount to change the current fov by in the fov shake effect. + /*0x08*/ f32 fovOffset; + /// A bool set in fov_default() but unused otherwise + /*0x0C*/ u32 unusedIsSleeping; + /// The range in degrees to shake fov + /*0x10*/ f32 shakeAmplitude; + /// Used to calculate fovOffset, the phase through the shake's period. + /*0x14*/ s16 shakePhase; + /// How much to progress through the shake period + /*0x16*/ s16 shakeSpeed; + /// How much to decrease shakeAmplitude each frame. + /*0x18*/ s16 decay; }; /** @@ -274,6 +444,10 @@ struct CutsceneSplinePoint Vec3s point; }; +/** + * Struct containing the nearest floor and ceiling to the player, as well as the previous floor and + * ceilng. It also stores their distances from the player's position. + */ struct PlayerGeometry { /*0x00*/ struct Surface *currFloor; @@ -288,187 +462,280 @@ struct PlayerGeometry /*0x24*/ struct Surface *prevCeil; /*0x28*/ f32 prevCeilHeight; /*0x2C*/ s16 prevCeilType; + /// Unused, but recalculated every frame /*0x30*/ f32 waterHeight; }; -struct Struct8033B418_sub +/** + * Point used in transitioning between camera modes and C-Up. + */ +struct LinearTransitionPoint { - Vec3f unk0; - Vec3f unkC; - f32 unk18; - s16 unk1C; - s16 unk1E; + Vec3f focus; + Vec3f pos; + f32 dist; + s16 pitch; + s16 yaw; }; -struct Struct8033B418 +/** + * Info about transitioning between camera modes. + */ +struct ModeTransitionInfo { - s16 unk0; - s16 unk2; - s16 unk4; - s16 unk6; - struct Struct8033B418_sub unk8; - struct Struct8033B418_sub unk28; + s16 newMode; + s16 lastMode; + s16 max; + s16 frame; + struct LinearTransitionPoint transitionStart; + struct LinearTransitionPoint transitionEnd; }; -struct ParallelTrackingTable +/** + * A point in a path used by update_parallel_tracking_camera + */ +struct ParallelTrackingPoint { - s16 unk0; - Vec3f unk4; - f32 unk10; - f32 unk14; + /// Whether this point is the start of a path + s16 startOfPath; + /// Point used to define a line segment to follow + Vec3f pos; + /// The distance mario can move along the line before the camera should move + f32 distThresh; + /// The percentage that the camera should move from the line to mario + f32 zoom; }; -struct Struct8033B4B8 +/** + * Stores the camera's info + */ +struct CameraStoredInfo { /*0x00*/ Vec3f pos; /*0x0C*/ Vec3f focus; - /*0x18*/ f32 unk18; - /*0x1C*/ f32 unk1C; + /*0x18*/ f32 panDist; + /*0x1C*/ f32 cannonYOffset; }; -struct Struct8033B6F0 +/** + * Struct used to store cutscene info, like the camera's target position/focus. + * + * See the sCutsceneVars[] array in camera.c for more details. + */ +struct CutsceneVariable { - s32 unk0; - Vec3f unk4; - Vec3f unk10; - Vec3s unk1C; - s16 unk22; + /// Perhaps an index + s32 unused1; + Vec3f point; + Vec3f unusedPoint; + Vec3s angle; + /// Perhaps a boolean or an extra angle + s16 unused2; }; -struct CameraState +/** + * The main camera struct. Gets updated by the active camera mode and the current level/area. In + * update_lakitu, its pos and focus are used to calculate lakitu's next position and focus, which are + * then used to render the game. + */ +struct Camera { - /*0x00*/ Vec3f camFocAndPosCurrAndGoal[4]; + /*0x00*/ u8 mode; // What type of mode the camera uses (see defines above) + /*0x01*/ u8 defMode; + /** + * Determines what direction mario moves in when the analog stick is moved. + * + * @warning This is NOT the camera's xz-rotation in world space. This is the angle calculated from the + * camera's focus TO the camera's position, instead of the other way around like it should + * be. It's effectively the opposite of the camera's actual yaw. Use + * vec3f_get_dist_and_angle() if you need the camera's yaw. + */ + /*0x02*/ s16 yaw; + /*0x04*/ Vec3f focus; + /*0x10*/ Vec3f pos; + /*0x1C*/ Vec3f unusedVec1; + /// The x coordinate of the "center" of the area. The camera will rotate around this point. + /// For example, this is what makes the camera rotate around the hill in BoB + /*0x28*/ f32 areaCenX; + /// The z coordinate of the "center" of the area. The camera will rotate around this point. + /// For example, this is what makes the camera rotate around the hill in BoB + /*0x2C*/ f32 areaCenZ; + /*0x30*/ u8 cutscene; + /*0x31*/ u8 filler31[0x8]; + /*0x3A*/ s16 nextYaw; + /*0x3C*/ u8 filler3C[0x28]; + /*0x64*/ u8 doorStatus; + /// The y coordinate of the "center" of the area. Unlike areaCenX and areaCenZ, this is only used + /// when paused. See zoom_out_if_paused_and_outside + /*0x68*/ f32 areaCenY; +}; + +/** + * A struct containing info pertaining to lakitu, such as his position and focus, and what + * camera-related effects are happening to him, like camera shakes. + * + * This struct's pos and foc are what is actually used to render the game. + * + * @see update_lakitu() + */ +struct LakituState +{ + /** + * Lakitu's position, which (when CAM_FLAG_SMOOTH_MOVEMENT is set), approaches his goalPos every frame. + */ + /*0x00*/ Vec3f curFocus; + /** + * Lakitu's focus, which (when CAM_FLAG_SMOOTH_MOVEMENT is set), approaches his goalFocus every frame. + */ + /*0x0C*/ Vec3f curPos; + /** + * The focus point that lakitu turns towards every frame. + * If CAM_FLAG_SMOOTH_MOVEMENT is unset, this is the same as curFocus. + */ + /*0x18*/ Vec3f goalFocus; + /** + * The point that lakitu flies towards every frame. + * If CAM_FLAG_SMOOTH_MOVEMENT is unset, this is the same as curPos. + */ + /*0x24*/ Vec3f goalPos; + /*0x30*/ u8 filler30[12]; // extra unused Vec3f? - /*0x3C*/ u8 modeActive; - /*0x3D*/ u8 modeDefault; + + /// Copy of the active camera mode + /*0x3C*/ u8 mode; + /// Copy of the default camera mode + /*0x3D*/ u8 defMode; + /*0x3E*/ u8 filler3E[10]; - /*0x48*/ float focusDistance; //unused - /*0x4C*/ s16 pitch; //unused - /*0x4E*/ s16 yaw; //unused - /*0x50*/ u8 filler50[2]; + + /*0x48*/ f32 focusDistance; // unused + /*0x4C*/ s16 oldPitch; // unused + /*0x4E*/ s16 oldYaw; // unused + /*0x50*/ s16 oldRoll; // unused + + /// The angular offsets added to lakitu's pitch, yaw, and roll /*0x52*/ Vec3s shakeMagnitude; - /*0x58*/ s16 shakePitchOffset; - /*0x5A*/ s16 shakePitchIncrement; - /*0x5C*/ s16 shakePitchMagIncrement; - /*0x5E*/ u8 filler5E[2]; - /*0x60*/ Vec3f unk60; //unused - /*0x6C*/ Vec3s unk6C; //unused + + // shake pitch, yaw, and roll phase: The progression through the camera shake (a cosine wave). + // shake pitch, yaw, and roll vel: The speed of the camera shake + // shake pitch, yaw, and roll decay: The shake's deceleration. + /*0x58*/ s16 shakePitchPhase; + /*0x5A*/ s16 shakePitchVel; + /*0x5C*/ s16 shakePitchDecay; + + /*0x60*/ Vec3f unusedVec1; + /*0x6C*/ Vec3s unusedVec2; /*0x72*/ u8 filler72[8]; + + /// Used to rotate the screen when rendering. /*0x7A*/ s16 roll; - /*0x7C*/ s16 trueYaw; - /*0x7E*/ s16 storedYaw; + /// Copy of the camera's yaw + /*0x7C*/ s16 yaw; + /// Copy of the camera's next yaw + /*0x7E*/ s16 nextYaw; + /// The actual focus point the game uses to render. /*0x80*/ Vec3f focus; + /// The actual position the game is rendered from. /*0x8C*/ Vec3f pos; - /*0x98*/ s16 shakeRollOffset; - /*0x9A*/ s16 shakeRollIncrement; - /*0x9C*/ s16 shakeRollMagIncrement; - /*0x9E*/ s16 shakeYawOffset; - /*0xA0*/ s16 shakeYawIncrement; - /*0xA2*/ s16 shakeYawMagIncrement; - /*0xA4*/ float unkA4; - /*0xA8*/ float unkA8; - /*0xAC*/ float unkAC; - /*0xB0*/ float unkB0; - /*0xB4*/ s16 cameraKeyCutsceneRollOffset; + + // Shake variables: See above description + /*0x98*/ s16 shakeRollPhase; + /*0x9A*/ s16 shakeRollVel; + /*0x9C*/ s16 shakeRollDecay; + /*0x9E*/ s16 shakeYawPhase; + /*0xA0*/ s16 shakeYawVel; + /*0xA2*/ s16 shakeYawDecay; + + // focH,Vspeed: how fast lakitu turns towards his goalFocus. + /// By default HSpeed is 0.8, so lakitu turns 80% of the horz distance to his goal each frame. + /*0xA4*/ f32 focHSpeed; + /// By default VSpeed is 0.3, so lakitu turns 30% of the vert distance to his goal each frame. + /*0xA8*/ f32 focVSpeed; + + // posH,Vspeed: How fast lakitu flies towards his goalPos. + /// By default they are 0.3, so lakitu will fly 30% of the way towards his goal each frame. + /*0xAC*/ f32 posHSpeed; + /*0xB0*/ f32 posVSpeed; + + /// The roll offset applied during part of the key dance cutscene + /*0xB4*/ s16 keyDanceRoll; + /// Mario's action from the previous frame. Only used to determine if mario just finished a dive. /*0xB8*/ u32 lastFrameAction; - /*0xBC*/ s16 unkBC; + /*0xBC*/ s16 unused; }; // bss order hack to not affect BSS order. if possible, remove me, but it will be hard to match otherwise #ifndef INCLUDED_FROM_CAMERA_C // BSS -extern struct CameraPlayerStatus gPlayerStatusForCamera[2]; -extern s16 gCameraModeFlags; -extern s16 sCameraSideCFlags; -extern s16 gCameraFlags1; -extern u16 gCButtonsPressed; -extern struct CameraState gCameraStatus; +extern struct PlayerCameraState gPlayerCameraState[2]; +extern struct LakituState gLakituState; extern s16 gCameraMovementFlags; -extern s32 gCutsceneActive; -extern struct LevelCamera *gCurrLevelCamera; +extern s32 gObjCutsceneDone; +extern struct Camera *gCamera; #endif extern struct Object *gCutsceneFocus; extern struct Object *gSecondCameraFocus; // TODO: sort all of this extremely messy shit out after the split -// TODO: bring in some externs from camera.c -extern Vec3f sFixedPresetBasePosition; -extern u8 D_8032D0B8[]; - -extern void set_camera_shake(s16); -extern void set_camera_shake_2(s16); -extern void func_8027F440(s16, f32, f32, f32); -extern void operate_c_up_looking(struct LevelCamera *); // static (ASM) -extern void init_transitional_movement(UNUSED struct LevelCamera *, s16); -extern void func_80285BD8(struct LevelCamera *, s16, s16); -extern void update_camera(struct LevelCamera *); -extern void reset_camera(struct LevelCamera *); -extern void init_camera(struct LevelCamera *); +extern void set_camera_shake_from_hit(s16); +extern void set_environmental_camera_shake(s16); +extern void set_camera_shake_from_point(s16, f32, f32, f32); +extern void move_mario_head_c_up(struct Camera *); // static (ASM) +extern void transition_next_state(UNUSED struct Camera *c, s16 frames); +extern void set_camera_mode(struct Camera *, s16, s16); +extern void update_camera(struct Camera *); +extern void reset_camera(struct Camera *); +extern void init_camera(struct Camera *); extern void select_mario_cam_mode(void); -extern Gfx *geo_camera_preset_and_pos(s32 a, struct GraphNode *b, struct AllocOnlyPool *c); -extern void dummy_802877D8(struct LevelCamera *); -extern void dummy_802877EC(struct LevelCamera *); -extern void vec3f_sub(Vec3f, Vec3f); +extern Gfx *geo_camera_main(s32 callContext, struct GraphNode *g, void *context); +extern void dummy_802877D8(struct Camera *); +extern void dummy_802877EC(struct Camera *); +extern void vec3f_sub(Vec3f dst, Vec3f src); extern void object_pos_to_vec3f(Vec3f, struct Object *); extern void vec3f_to_object_pos(struct Object *, Vec3f); // static (ASM) extern s32 move_point_along_spline(Vec3f, struct CutsceneSplinePoint[], s16 *, f32 *); -extern s32 select_or_activate_mario_cam(s32 angle); -extern s32 test_or_set_mario_cam_active(s32); -extern void set_spline_values(u8); -extern void set_face_angle_from_spline(Vec3f, Vec3f); +extern s32 cam_select_alt_mode(s32 angle); +extern s32 set_cam_angle(s32); +extern void set_handheld_shake(u8); +extern void shake_camera_handheld(Vec3f, Vec3f); extern s32 find_c_buttons_pressed(u16, u16, u16); -extern s32 update_camera_status(struct LevelCamera *); -extern s32 find_and_return_count_wall_collisions(Vec3f, f32, f32); +extern s32 update_camera_hud_status(struct Camera *); +extern s32 collide_with_walls(Vec3f, f32, f32); extern s32 clamp_pitch(Vec3f a, Vec3f b, s16 c, s16 d); extern s32 is_within_100_units_of_mario(f32, f32, f32); -extern s32 set_or_approach_f32_exponential(f32 *, f32, f32); -extern s32 approach_f32_exponential_bool(f32 *, f32, f32); -extern f32 approach_f32_exponential(f32, f32, f32); // static (ASM) -extern s32 approach_s16_exponential_bool(s16 *, s16, s16); -extern s32 approach_s16_exponential(s16, s16, s16); // static (ASM) -extern void approach_vec3f_exponential(Vec3f, Vec3f, f32, f32, f32); // static (ASM) +extern s32 set_or_approach_f32_asymptotic(f32 *, f32, f32); +extern s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier); +extern f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier); // static (ASM) +extern s32 approach_s16_asymptotic_bool(s16 *current, s16 target, s16 multiplier); +extern s32 approach_s16_asymptotic(s16 current, s16 target, s16 multiplier); // static (ASM) +extern void approach_vec3f_asymptotic(Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul); // static (ASM) - - - -extern void set_or_approach_vec3f_exponential(Vec3f, Vec3f, f32, f32, f32); // postdefined -// extern ? approach_vec3s_exponential(?); -extern s32 camera_approach_s16_symmetric_bool(s16 *a, s16 b, s16 c); -// extern ? camera_approach_s16_symmetric(?); -extern s32 set_or_approach_s16_symmetric(s16 *a, s16 b, s16 c); // postdefined -extern s32 camera_approach_f32_symmetric_bool(f32 *, f32, f32); -extern f32 camera_approach_f32_symmetric(f32, f32, f32); -void random_vec3s(Vec3s a, s16 b, s16 c, s16 d); // postdefined -// extern ? func_80289738(?); -extern s32 clamp_positions_and_find_yaw_angle(Vec3f, Vec3f, f32, f32, f32, f32); -// extern ? func_80289A98(?); -// extern ? is_pos_less_than_bounds(?); -// extern ? is_behind_surface(?); -extern s32 func_8028A0D4(Vec3f a, Vec3f b, struct Surface *c, s16 d, s16 e); -// extern ? is_mario_behind_surface(?); -extern void scale_along_line(Vec3f, Vec3f, Vec3f, f32); -// extern ? check_if_vector_fits_in_bounds(?); -extern s16 calculate_verticle_angle(Vec3f, Vec3f); -extern s16 calculate_yaw(Vec3f, Vec3f); -extern void calculate_angles(Vec3f, Vec3f, s16 *, s16 *); -extern f32 calc_abs_dist(Vec3f, Vec3f); -extern f32 calc_hor_dist(Vec3f, Vec3f); -extern void rotate_in_xz(Vec3f, Vec3f, s16); -extern void rotate_in_yz(Vec3f, Vec3f, s16); -extern void set_camera_pitch_shake(s16, s16, s16); -extern void set_camera_yaw_shake(s16, s16, s16); -extern void set_camera_roll_shake(s16, s16, s16); -extern void func_8028AA80(s16, s16, s16, f32, f32, f32, f32); -// extern ? Unknown8028AB34(?); -// extern ? increment_shake_offset(?); +extern void set_or_approach_vec3f_asymptotic(Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul); // postdefined +extern s32 camera_approach_s16_symmetric_bool(s16 *current, s16 target, s16 increment); +extern s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment); // postdefined +extern s32 camera_approach_f32_symmetric_bool(f32 *current, f32 target, f32 increment); +extern f32 camera_approach_f32_symmetric(f32 value, f32 target, f32 increment); +extern void random_vec3s(Vec3s dst, s16 xRange, s16 yRange, s16 zRange); // postdefined +extern s32 clamp_positions_and_find_yaw(Vec3f, Vec3f, f32, f32, f32, f32); +extern s32 is_range_behind_surface(Vec3f from, Vec3f to, struct Surface *surf, s16 range, s16 surfType); +extern void scale_along_line(Vec3f dest, Vec3f from, Vec3f to, f32 scale); +extern s16 calculate_pitch(Vec3f from, Vec3f to); +extern s16 calculate_yaw(Vec3f from, Vec3f to); +extern void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw); +extern f32 calc_abs_dist(Vec3f a, Vec3f b); +extern f32 calc_hor_dist(Vec3f a, Vec3f b); +extern void rotate_in_xz(Vec3f dst, Vec3f src, s16 yaw); +extern void rotate_in_yz(Vec3f dst, Vec3f src, s16 pitch); +extern void set_camera_pitch_shake(s16 mag, s16 pitchMagInc, s16 pitchInc); +extern void set_camera_yaw_shake(s16 mag, s16 yawMagInc, s16 yawInc); +extern void set_camera_roll_shake(s16 mag, s16 rollMagInc, s16 rollInc); +extern void set_pitch_shake_from_point(s16 mag, s16 pitchMagInc, s16 pitchInc, f32 maxDist, f32 posX, f32 posY, f32 posZ); extern void shake_camera_pitch(); // postdefined extern void shake_camera_yaw(); // postdefined extern void shake_camera_roll(s16 *); // postdefined -extern s32 func_8028AF24(struct LevelCamera *a, s16 b); -// extern ? func_8028B13C(?); -// extern ? func_8028B16C(?); +extern s32 offset_yaw_outward_radial(struct Camera *a, s16 b); extern void play_camera_buzz_if_cdown(void); extern void play_camera_buzz_if_cbutton(void); extern void play_camera_buzz_if_c_sideways(void); @@ -477,394 +744,35 @@ extern void play_sound_cbutton_down(void); extern void play_sound_cbutton_side(void); extern void play_sound_button_change_blocked(void); // postdefined extern void play_sound_rbutton_changed(void); // postdefined -extern void func_8028B36C(void); // postdefined -extern s32 func_8028B3DC(struct LevelCamera *a, f32 b); -extern s32 stop_mario(s32); -extern void handle_c_button_movement(struct LevelCamera *); -// extern ? func_8028BA38(?); -extern void set_camera_cutscene_table(struct LevelCamera *a, u8 b); // postdefined -// extern ? determine_star_fadeout_cutscene_table(?); -// extern ? return_table_door_push_or_pull(?); -extern u8 return_cutscene_table(); // postdefined -extern void instant_warp_camera_update(f32, f32, f32); -extern void approach_camera_height(struct LevelCamera *, f32, f32); -// extern ? Unknown8028C3AC(?); -// extern ? set_focus_position(?); -// extern ? Unknown8028C508(?); -extern void set_pos_from_face_angle_and_vec3f(Vec3f, Vec3f, Vec3f, Vec3s); -// extern ? set_pos_from_face_angle_and_rel_coords(?); -// extern ? determine_pushing_or_pulling_door(?); -s16 func_8028C824(Vec3f a, Vec3f b, Vec3f c, Vec3f d, Vec3f e, Vec3f f, s16 g); // postdefined -// extern ? Unknown8028CE1C(?); -// extern ? set_camera_preset_fixed_ref_point(?); -// extern ? set_camera_preset_platform_level(?); -// extern ? set_camera_preset_boss_fight(?); -// extern ? set_camera_preset_close_cam(?); -// extern ? set_camera_preset_open_camera(?); -// extern ? parallel_tracking_init(?); +extern void play_sound_if_cam_switched_to_lakitu_or_mario(void); // postdefined +extern s32 radial_camera_input(struct Camera *a, f32 b); +extern s32 trigger_cutscene_dialog(s32); +extern void handle_c_button_movement(struct Camera *); +extern void start_cutscene(struct Camera *a, u8 cutscene); // postdefined +extern u8 get_cutscene_from_mario_status(); // postdefined +extern void warp_camera(f32 displacementX, f32 displacementY, f32 displacementZ); +extern void approach_camera_height(struct Camera *c, f32 goal, f32 inc); +extern void offset_rotated(Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation); +s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw); // postdefined extern void set_fixed_cam_axis_sa_lobby(s16 preset); // postdefined -// extern ? func_8028D32C(?); -// extern ? CameraRR00(?); -// extern ? CameraRR04(?); -// extern ? CameraRR02(?); -// extern ? CameraRR0305(?); -// extern ? CameraRR01(?); -// extern ? CameraCotMC00(?); -// extern ? CameraSL00(?); -// extern ? camera_change_set_free_roam_mode(?); -// extern ? camera_change_hmc_maze_entrance(?); -// extern ? CameraHMC02(?); -// extern ? CameraHMC03(?); -// extern ? CameraHMC04(?); -// extern ? CameraHMC05(?); -// extern ? CameraSSL00(?); -// extern ? CameraSSL0102(?); -// extern ? CameraSSL03(?); -// extern ? CameraTHI00(?); -// extern ? CameraTHI01(?); -// extern ? CameraRR07(?); -// extern ? CameraRR08(?); -// extern ? camera_change_hmc_cotmc_pool_entry(?); -// extern ? CameraInside20(?); -// extern ? CameraInside1E(?); -// extern ? CameraInside1F(?); -// extern ? CameraInside01(?); -// extern ? CameraInside1213(?); -// extern ? CameraUnused(?); -// extern ? CameraInside00(?); -// extern ? CameraInside0E(?); -// extern ? CameraInside0F(?); -// extern ? bbh_room_6_camera(?); -// extern ? CameraBBH24(?); -// extern ? CameraBBH2E2F(?); -// extern ? bbh_room_1_camera(?); -// extern ? CameraBBH01(?); -// extern ? bbh_room_2_lower_camera(?); -// extern ? bbh_room_4_camera(?); -// extern ? bbh_room_8_camera(?); -// extern ? bbh_room_5_library_camera(?); -// extern ? bbh_room_5_library_to_hidden_transition(?); -// extern ? bbh_room_5_hidden_to_library_transition(?); -// extern ? bbh_room_5_hidden_camera(?); -// extern ? bbh_room_3_camera(?); -// extern ? bbh_room_7_mr_i_camera(?); -// extern ? bbh_room_7_mr_i_to_coffins_transition(?); -// extern ? bbh_room_7_coffins_to_mr_i_transition(?); -// extern ? CameraBBH3033(?); -// extern ? CameraBBH34(?); -// extern ? CameraBBH38(?); -// extern ? bbh_room_12_upper_camera(?); -// extern ? CameraBBH00(?); -// extern ? bbh_room_2_library_camera(?); -// extern ? bbh_room_2_library_to_trapdoor_transition(?); -// extern ? bbh_room_2_trapdoor_camera(?); -// extern ? bbh_room_2_trapdoor_transition(?); -// extern ? bbh_room_9_attic_camera(?); -// extern ? bbh_room_9_attic_transition(?); -// extern ? bbh_room_9_mr_i_transition(?); -// extern ? bbh_room_13_balcony_camera(?); -// extern ? bbh_room_0_camera(?); -// extern ? camera_change_activate_ccm_slide_flag(?); -// extern ? camera_change_deactivate_ccm_slide_flag(?); -// extern ? surface_type_presets(?); -// extern ? set_preset_via_surface_or_input(?); -// extern ? surface_type_presets_thi(?); -extern s16 level_specific_camera_update(struct LevelCamera *); // postdefined +extern s16 camera_course_processing(struct Camera *); // postdefined extern void resolve_geometry_collisions(Vec3f, Vec3f); -extern s32 func_8028F2F0(struct LevelCamera *, Vec3f, s16 *, s16); -extern void find_mario_relative_geometry(struct PlayerGeometry *); // postdefined -// extern ? func_8028F800(?); -extern u8 func_8028F834(u8); +extern s32 rotate_camera_around_walls(struct Camera *, Vec3f, s16 *, s16); +extern void find_mario_floor_and_ceil(struct PlayerGeometry *); // postdefined +extern u8 start_object_cutscene_without_focus(u8); extern s16 cutscene_object_with_dialog(u8 cutsceneTable, struct Object *, s16); extern s16 cutscene_object_without_dialog(u8, struct Object *); -extern s16 cutscene_object(u8, struct Object *); -// extern ? set_cam_yaw_from_focus_and_pos(?); -// extern ? func_8028FABC(?); -// extern ? func_8028FAE0(?); -// extern ? cap_switch_save(?); -// extern ? func_8028FB80(?); -// extern ? func_8028FBD8(?); -// extern ? func_8028FD94(?); -// extern ? Unknown8028FDE8(?); -// extern ? Cutscene26Todo_0(?); -// extern ? Unknown8028FE50(?); -// extern ? CutsceneIntroPeach0_2(?); -// extern ? CutsceneIntroPeach2_1(?); -// extern ? func_8028FEDC(?); -// extern ? move_credits_camera(?); -// extern ? func_80290144(?); -// extern ? func_802901B4(?); -// extern ? func_80290224(?); -// extern ? func_802902A8(?); -// extern ? unused_vec3s_to_vec3f(?); -// extern ? unused_vec3f_to_vec3s(?); -// extern ? rotate_camera(?); -// extern ? CutsceneEnterSomething8029041C(?); -// extern ? Unknown80290450(?); -// extern ? rotate_and_move_vec3f(?); -// extern ? func_80290514(?); -// extern ? func_80290564(?); -// extern ? func_80290598(?); -// extern ? Unknown802905C8(?); -// extern ? Cutscene0FTodo_0(?); -// extern ? Cutscene0FTodo_1(?); -// extern ? CutscenePeachEnd80290604(?); -// extern ? CutscenePeachEnd8029065C(?); -// extern ? CutscenePeachEnd0(?); -// extern ? CutscenePeachEnd2(?); -// extern ? CutscenePeachEnd367_1(?); -// extern ? CutscenePeachEnd80290870(?); -// extern ? CutscenePeachEnd3(?); -// extern ? CutscenePeachEnd1(?); -// extern ? CutscenePeachEnd80290A34(?); -// extern ? CutscenePeachEnd4(?); -// extern ? CutscenePeachEnd80290B88(?); -// extern ? CutscenePeachEnd80290BC8(?); -// extern ? CutscenePeachEnd80290C3C(?); -// extern ? CutscenePeachEnd80290C78(?); -// extern ? CutscenePeachEnd5(?); -// extern ? CutscenePeachEnd6(?); -// extern ? CutscenePeachEnd80290E8C(?); -// extern ? CutscenePeachEnd7(?); -// extern ? CutscenePeachEnd8(?); -// extern ? CutscenePeachEnd80291014(?); -// extern ? CutscenePeachEnd80291078(?); -// extern ? CutscenePeachEnd9(?); -// extern ? CutscenePeachEnd802911A4(?); -// extern ? CutscenePeachEnd8029120C(?); -// extern ? CutscenePeachEndA(?); -// extern ? CutscenePeachEndB(?); -// extern ? CutsceneGrandStar80291324(?); -// extern ? CutsceneGrandStar8029139C(?); -// extern ? CutsceneGrandStar80291474(?); -// extern ? CutsceneGrandStar802914D8(?); -// extern ? CutsceneGrandStar80291528(?); -// extern ? CutsceneGrandStar802915B4(?); -// extern ? CutsceneGrandStar802915FC(?); -// extern ? CutsceneGrandStar0(?); -// extern ? CutsceneGrandStar80291770(?); -// extern ? CutsceneGrandStar80291844(?); -// extern ? CutsceneGrandStar802918D8(?); -// extern ? CutsceneGrandStar802919F8(?); -// extern ? CutsceneGrandStar1(?); -// extern ? func_80291BBC(?); -// extern ? CutsceneDance80291C4C(?); -// extern ? CutsceneStarDance80291CE4(?); -// extern ? CutsceneStarDance80291D30(?); -// extern ? CutsceneStarDance80291D78(?); -// extern ? Unknown80291DC0(?); -// extern ? CutsceneStarDance80291DD4(?); -// extern ? CutsceneStarDance80291E0C(?); -// extern ? CutsceneStarDance80291E44(?); -// extern ? CutsceneStarDance1(?); -// extern ? func_80291FE8(?); -// extern ? CutsceneStarDance8029209C(?); -// extern ? CutsceneStarDance80292190(?); -// extern ? CutsceneStarDance80292228(?); -// extern ? CutsceneStarDance80292334(?); -// extern ? CutsceneStarDance802923E0(?); -// extern ? CutsceneStarDance8029240C(?); -// extern ? CutsceneStarDance3(?); -// extern ? CutsceneStarDance802925C0(?); -// extern ? CutsceneStarDance80292740(?); -// extern ? CutsceneStarDance802927EC(?); -// extern ? func_80292884(?); -// extern ? CutsceneStarDance80292900(?); -// extern ? CutsceneStarDance80292958(?); -// extern ? CutsceneStarDance802929A4(?); -// extern ? CutsceneStarDance2(?); -// extern ? CutsceneKeyDance80292AB0(?); -// extern ? CutsceneKeyDance80292B24(?); -// extern ? CutsceneKeyDance80292B80(?); -// extern ? CutsceneKeyDance80292BE0(?); -// extern ? CutsceneKeyDance80292C4C(?); -// extern ? CutsceneKeyDance80292CB4(?); -// extern ? CutsceneKeyDance80292CE8(?); -// extern ? CutsceneKeyDance80292D14(?); -// extern ? CutsceneKeyDance(?); -// extern ? CutsceneEnterBowserPlatform80292E48(?); -// extern ? CutsceneEnterBowserPlatform80292E74(?); -// extern ? CutsceneEnterBowserPlatform80292E98(?); -// extern ? CutsceneEnterBowserPlatform80292F08(?); -// extern ? CutsceneEnterBowserPlatform80292FA0(?); -// extern ? CutsceneEnterBowserPlatform80292FE4(?); -// extern ? CutsceneEnterBowserPlatform8029305C(?); -// extern ? CutsceneEnterBowserPlatform8029309C(?); -// extern ? func_802930C8(?); -// extern ? CutsceneEnterBowserPlatform802930F4(?); -// extern ? CutsceneEnterBowserPlatform802931A8(?); -// extern ? CutsceneEnterBowserPlatform1(?); -// extern ? CutsceneEnterBowserPlatform2(?); -// extern ? CutsceneEnterBowserPlatform0(?); -// extern ? CutsceneStarSpawn8029347C(?); -// extern ? CutsceneStarSpawn802934A8(?); -// extern ? CutsceneStarSpawn80293530(?); -// extern ? CutsceneStarSpawn802935B4(?); -// extern ? CutsceneStarSpawn0(?); -// extern ? CutsceneStarSpawn1(?); -// extern ? CutsceneStarSpawn2(?); -// extern ? CutsceneExitWaterfall80293750(?); -// extern ? Cutscene80293794(?); -// extern ? CutsceneExitWaterfall0(?); -// extern ? CutsceneFallCommon1(?); -// extern ? CutsceneFallToCastleGrounds802938EC(?); -// extern ? CutsceneFallToCastleGrounds0(?); -// extern ? CutsceneSpecialStarSpawn8029398C(?); -// extern ? CutsceneSpecialStarSpawn802939E4(?); -// extern ? CutsceneSpecialStarSpawn80293A48(?); -// extern ? CutsceneSpecialStarSpawn80293A8C(?); -// extern ? CutsceneSpecialStarSpawn80293ACC(?); -// extern ? CutsceneSpecialStarSpawn80293C8C(?); -// extern ? CutsceneSpecialStarSpawn0(?); -// extern ? CutsceneSpecialStarSpawn1(?); -// extern ? func_80293DE8(?); -// extern ? CutscenePrepareCannon802940D8(?); -// extern ? CutscenePrepareCannon80294164(?); -// extern ? func_802941CC(?); -// extern ? CutscenePrepareCannon80294260(?); -// extern ? CutscenePrepareCannon0(?); -// extern ? CutscenePrepareCannon1(?); -// extern ? func_802944A8(?); -// extern ? func_80294538(?); -// extern ? CutsceneDeath80294574(?); -// extern ? CutsceneDeath802945E8(?); -// extern ? CutsceneDeath1(?); -// extern ? CutsceneDeath80294684(?); -// extern ? CutsceneDeath80294708(?); -// extern ? Unknown80294748(?); -// extern ? CutsceneDeath2(?); -// extern ? CutsceneBBHDeath802947E4(?); -// extern ? CutsceneBBHDeath80294868(?); -// extern ? CutsceneBBHDeath(?); -// extern ? CutsceneQuicksandDeath80294918(?); -// extern ? CutsceneQuicksandDeath80294954(?); -// extern ? CutsceneQuicksandDeath0(?); -// extern ? Cutscene1ATodo80294A70(?); -// extern ? Cutscene1ATodo80294B00(?); -// extern ? Cutscene1ATodo80294BB0(?); -// extern ? Cutscene1ATodo(?); -// extern ? CutsceneEnterPool80294CD0(?); -// extern ? CutsceneEnterPool80294D9C(?); -// extern ? CutsceneEnterPool0(?); -// extern ? Cutscene26Todo80294E40(?); -// extern ? Cutscene26Todo80294EAC(?); -// extern ? Cutscene26Todo80294ED8(?); -// extern ? Cutscene26Todo80294F40(?); -// extern ? Cutscene26Todo80295030(?); -// extern ? Cutscene26Todo80295100(?); -// extern ? Cutscene26Todo8029512C(?); -// extern ? Cutscene26Todo_1(?); -// extern ? Cutscene26Todo_2(?); -// extern ? CutsceneEnterPyramidTop80295294(?); -// extern ? CutsceneEnterPyramidTop0(?); -// extern ? Unknown8029538C(?); -// extern ? CutsceneDialog80295418(?); -// extern ? CutsceneDialog80295568(?); -// extern ? CutsceneDialog8029579C(?); -// extern ? CutsceneDialog0(?); -// extern ? CutsceneDialog1(?); -// extern ? CutsceneDialog2(?); -// extern ? CutsceneReadMessage80295998(?); -// extern ? Unknown80295A28(?); -// extern ? CutsceneReadMessage0(?); -// extern ? CutsceneReadMessage1(?); -// extern ? CutsceneReadMessage2(?); -// extern ? CutsceneExitSuccess1(?); -// extern ? CutsceneExitSuccess2(?); -// extern ? CutsceneExitSuccess4(?); -// extern ? CutsceneExitSuccess3(?); -// extern ? CutsceneExitBowserSuccess80296014(?); -// extern ? CutsceneExitSuccess5(?); -// extern ? CutsceneExitBowserSuccess0(?); -// extern ? CutsceneExitNonPainting1(?); -// extern ? CutsceneBBHExitSuccess02961D4(?); -// extern ? CutsceneBBHExitSuccess0(?); -// extern ? CutsceneNonPaintingDeath0_1(?); -// extern ? Cutscene1CTodo_0(?); -// extern ? CutsceneNonPaintingDeath0_2(?); -// extern ? CutsceneNonPaintingDeath0(?); -// extern ? CutsceneCapSwitchPress0_1(?); -// extern ? CutsceneCapSwitchPress0_4(?); -// extern ? CutsceneCapSwitchPress0_5(?); -// extern ? CutsceneCapSwitchPress0_2(?); -// extern ? CutsceneCapSwitchPress0_3(?); -// extern ? CutsceneCapSwitchPress0_6(?); -// extern ? Unknown802968E8(?); -// extern ? CutsceneCapSwitchPress(?); -// extern ? CutsceneUnlockKeyDoor80296AC0(?); -// extern ? CutsceneUnlockKeyDoor80296B84(?); -// extern ? CutsceneUnlockKeyDoor80296C08(?); -// extern ? CutsceneUnlockKeyDoor80296C64(?); -// extern ? CutsceneUnlockKeyDoor80296C78(?); -// extern ? CutsceneUnlockKeyDoor80296CFC(?); -// extern ? CutsceneUnlockKeyDoor0(?); -// extern ? func_80296DDC(?); -// extern ? peach_letter_text(?); -// extern ? CutsceneIntroPeachCommon(?); -// extern ? CutsceneIntroPeach4(?); -// extern ? CutsceneIntroPeach3_2(?); -// extern ? CutsceneIntroPeach2_2(?); -// extern ? CutsceneIntroPeach0_1(?); -// extern ? CutsceneIntroPeach3_1(?); -// extern ? CutsceneIntroPeach3_3(?); -// extern ? intro_pipe_exit_text(?); -// extern ? CutsceneIntroPeach2(?); -// extern ? CutsceneIntroPeach3(?); -// extern ? CutsceneIntroPeach1(?); -// extern ? CutsceneIntroPeach0(?); -// extern ? CutsceneEndWaving0_1(?); -// extern ? CutsceneEndWaving0(?); -// extern ? CutsceneCredits0_1(?); -// extern ? CutsceneCredits0(?); -// extern ? CutsceneSlidingDoorsOpen0_1(?); -// extern ? CutsceneSlidingDoorsOpen0_2(?); -// extern ? CutsceneSlidingDoorsOpen0_3(?); -// extern ? CutsceneSlidingDoorsOpen0_4(?); -// extern ? CutsceneSlidingDoorsOpen0_5(?); -// extern ? CutsceneSlidingDoorsOpen0(?); -// extern ? CutsceneDoubleDoorsOpen1(?); -// extern ? CutsceneEnterPainting0_1(?); -// extern ? CutsceneEnterPainting0(?); -// extern ? CutsceneExitPainting80298094(?); -// extern ? CutsceneExitPainting80298230(?); -// extern ? CutsceneExitPainting802982CC(?); -// extern ? CutsceneExitPainting0(?); -// extern ? Cutscene11Todo_0(?); -// extern ? Cutscene11Todo_1(?); -// extern ? CutsceneExitPainting1(?); -// extern ? CutsceneEnterCannon2(?); -// extern ? CutsceneEnterCannon1(?); -// extern ? CutsceneEnterCannon0(?); -// extern ? CutsceneDoor0(?); -// extern ? CutsceneDoor1(?); -// extern ? CutsceneDoorWarp1(?); -// extern ? CutsceneDoor2(?); -// extern ? CutsceneDoor3(?); -// extern ? CutsceneDoor4(?); -// extern ? CutsceneDoorAB_2(?); -extern void handle_cutscenes(struct LevelCamera *); -extern s32 call_cutscene_func_in_time_range(CameraCommandProc, struct LevelCamera *, s16, s16); -extern s32 set_cutscene_phase_at_frame(s32 phase, s16 frame); -extern void func_80299C98(s16, s16, s16); -// extern ? func_80299D00(?); +extern s16 cutscene_object(u8 cutscene, struct Object *o); +extern void play_cutscene(struct Camera *c); +extern s32 cutscene_event(CameraEvent event, struct Camera * c, s16 start, s16 end); +extern s32 cutscene_spawn_obj(s32 phase, s16 frame); +extern void set_fov_shake(s16 amplitude, s16 decay, s16 shakeSpeed); -extern void set_fov_function(u8); -extern void func_8029A494(u8); -extern void func_8029A514(u8, f32, f32, f32); -// extern ? Unknown8029A664(?); -// extern ? Unknown8029A724(?); -extern void func_8029A7DC(struct Object *, Vec3f, s16, s16, s16, s16); -// extern ? func_8029A87C(?); -// extern ? bhv_intro_peach_loop(?); -// extern ? func_8029AB70(?); -// extern ? func_8029AC3C(?); -// extern ? func_8029ACAC(?); -// extern ? bhv_intro_lakitu_loop(?); -// extern ? bhv_end_birds_1_loop(?); -// extern ? bhv_end_birds_2_loop(?); -// extern ? func_8029B964(?); -// extern ? bhv_intro_scene_loop(?); +extern void set_fov_function(u8 func); +extern void cutscene_set_fov_shake_preset(u8 preset); +extern void set_fov_shake_from_point_preset(u8 preset, f32 posX, f32 posY, f32 posZ); +extern void obj_rotate_towards_point(struct Object *, Vec3f, s16, s16, s16, s16); -extern Gfx *geo_camera_fov(s32 a, struct GraphNode *b, UNUSED struct AllocOnlyPool *c); +extern Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context); #endif /* _CAMERA_H */ diff --git a/src/game/envfx_bubbles.c b/src/game/envfx_bubbles.c index 9fbc6a8..4fd408e 100644 --- a/src/game/envfx_bubbles.c +++ b/src/game/envfx_bubbles.c @@ -347,8 +347,7 @@ s32 envfx_init_bubble(s32 mode) { break; } - gEnvFxBuffer = (struct EnvFxParticle *) mem_pool_alloc( - D_8033A124, sBubbleParticleCount * sizeof(struct EnvFxParticle)); + gEnvFxBuffer = mem_pool_alloc(gEffectsMemoryPool, sBubbleParticleCount * sizeof(struct EnvFxParticle)); if (!gEnvFxBuffer) { return 0; } diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c index 357d549..a26dc8c 100644 --- a/src/game/envfx_snow.c +++ b/src/game/envfx_snow.c @@ -79,8 +79,7 @@ s32 envfx_init_snow(s32 mode) { break; } - gEnvFxBuffer = (struct EnvFxParticle *) mem_pool_alloc( - D_8033A124, gSnowParticleMaxCount * sizeof(struct EnvFxParticle)); + gEnvFxBuffer = mem_pool_alloc(gEffectsMemoryPool, gSnowParticleMaxCount * sizeof(struct EnvFxParticle)); if (!gEnvFxBuffer) { return 0; } @@ -137,7 +136,7 @@ void envfx_update_snowflake_count(s32 mode, Vec3s marioPos) { void envfx_cleanup_snow(void *snowParticleArray) { if (gEnvFxMode) { if (snowParticleArray) { - mem_pool_free(D_8033A124, snowParticleArray); + mem_pool_free(gEffectsMemoryPool, snowParticleArray); } gEnvFxMode = ENVFX_MODE_NONE; } diff --git a/src/game/hud.c b/src/game/hud.c index 0643904..7ab1977 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -210,7 +210,7 @@ void handle_power_meter_actions(s16 numHealthWedges) { sPowerMeterStoredHealth = numHealthWedges; // If mario is swimming, keep showing power meter - if (gPlayerStatusForCamera->action & ACT_FLAG_SWIMMING) { + if (gPlayerCameraState->action & ACT_FLAG_SWIMMING) { if (sPowerMeterHUD.animation == POWER_METER_HIDDEN || sPowerMeterHUD.animation == POWER_METER_EMPHASIZED) { sPowerMeterHUD.animation = POWER_METER_DEEMPHASIZING; @@ -445,7 +445,7 @@ void render_hud(void) { create_dl_ortho_matrix(); #endif - if (gCurrentArea != NULL && gCurrentArea->camera->currPreset == CAMERA_PRESET_INSIDE_CANNON) { + if (gCurrentArea != NULL && gCurrentArea->camera->mode == CAMERA_MODE_INSIDE_CANNON) { render_hud_cannon_reticle(); } diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index b99030a..98709f9 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -446,10 +446,10 @@ void print_generic_string(s16 x, s16 y, const u8 *str) { render_lowercase_diacritic(&xCoord, &yCoord, DIALOG_CHAR_I_NO_DIA, str[strPos] & 0xF); break; #else // i.e. not EU - case DIALOG_CHAR_PREFIX_DAKUTEN: + case DIALOG_CHAR_DAKUTEN: mark = DIALOG_MARK_DAKUTEN; break; - case DIALOG_CHAR_PREFIX_HANDAKUTEN: + case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: mark = DIALOG_MARK_HANDAKUTEN; break; case DIALOG_CHAR_NEWLINE: @@ -457,9 +457,9 @@ void print_generic_string(s16 x, s16 y, const u8 *str) { create_dl_translation_matrix(MENU_MTX_PUSH, x, y - (lineNum * MAX_STRING_WIDTH), 0.0f); lineNum++; break; - case DIALOG_CHAR_HANDAKUTEN: + case DIALOG_CHAR_PERIOD: create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0.0f); - render_generic_char(DIALOG_CHAR_PREFIX_HANDAKUTEN); + render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); break; #endif @@ -656,10 +656,10 @@ void print_menu_generic_string(s16 x, s16 y, const u8 *str) { curX += gDialogCharWidths[str[strPos]]; break; #else - case DIALOG_CHAR_PREFIX_DAKUTEN: + case DIALOG_CHAR_DAKUTEN: mark = DIALOG_MARK_DAKUTEN; break; - case DIALOG_CHAR_PREFIX_HANDAKUTEN: + case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: mark = DIALOG_MARK_HANDAKUTEN; break; #endif @@ -806,8 +806,8 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) { //! EU checks for dakuten and handakuten despite dialog code unable to handle it if (str[strPos] == DIALOG_CHAR_SPACE) { spacesWidth += 1.0; - } else if (str[strPos] != DIALOG_CHAR_PREFIX_DAKUTEN - && str[strPos] != DIALOG_CHAR_PREFIX_HANDAKUTEN) { + } else if (str[strPos] != DIALOG_CHAR_DAKUTEN + && str[strPos] != DIALOG_CHAR_PERIOD_OR_HANDAKUTEN) { charsWidth += 1.0; } strPos++; @@ -936,7 +936,7 @@ void reset_dialog_render_state(void) { level_set_transition(0, 0); if (gDialogBoxType == DIALOG_TYPE_ZOOM) { - stop_mario(2); + trigger_cutscene_dialog(2); } gDialogBoxScale = 19.0f; @@ -1078,13 +1078,13 @@ void handle_dialog_scroll_page_state(s8 lineNum, s8 totalLines, s8 *pageState, s } #ifdef VERSION_JP -void adjust_handakuten_char_pos(s8 *xMatrix, s16 *linePos) { +void adjust_pos_and_print_period_char(s8 *xMatrix, s16 *linePos) { if (linePos[0] != 0) { create_dl_translation_matrix(MENU_MTX_NOPUSH, xMatrix[0] * 10, 0, 0); } create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0); - render_generic_char(DIALOG_CHAR_PREFIX_HANDAKUTEN); + render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); @@ -1336,10 +1336,10 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l render_dialog_lowercase_diacritic(dialog, DIALOG_CHAR_I_NO_DIA, strChar & 0xF); break; #else - case DIALOG_CHAR_PREFIX_DAKUTEN: + case DIALOG_CHAR_DAKUTEN: mark = DIALOG_MARK_DAKUTEN; break; - case DIALOG_CHAR_PREFIX_HANDAKUTEN: + case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: mark = DIALOG_MARK_HANDAKUTEN; break; #endif @@ -1359,8 +1359,8 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l #endif break; #ifdef VERSION_JP - case DIALOG_CHAR_HANDAKUTEN: - adjust_handakuten_char_pos(&xMatrix, &linePos); + case DIALOG_CHAR_PERIOD: + adjust_pos_and_print_period_char(&xMatrix, &linePos); break; #else case DIALOG_CHAR_SLASH: @@ -1439,8 +1439,8 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l #ifdef VERSION_JP if (linePos == 12) { - if (str[strIdx + 1] == DIALOG_CHAR_HANDAKUTEN) { - adjust_handakuten_char_pos(&xMatrix, &linePos); + if (str[strIdx + 1] == DIALOG_CHAR_PERIOD) { + adjust_pos_and_print_period_char(&xMatrix, &linePos); strIdx++; } @@ -1676,7 +1676,7 @@ u16 gCutsceneMsgFade = 0; s16 gCutsceneMsgIndex = -1; s16 gCutsceneMsgDuration = -1; s16 gCutsceneMsgTimer = 0; -s8 gDialogCameraAngleIndex = CAM_ANGLE_LAKITU_MARIO; +s8 gDialogCameraAngleIndex = CAM_SELECTION_MARIO; s8 gDialogCourseActNum = 1; #ifdef VERSION_JP @@ -1790,7 +1790,7 @@ void render_dialog_entries(void) { play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gDefaultSoundArgs); if (gDialogBoxType == DIALOG_TYPE_ZOOM) { - stop_mario(2); + trigger_cutscene_dialog(2); } gDialogResponse = gDialogLineNum; @@ -2112,10 +2112,10 @@ void reset_red_coins_collected(void) { } void change_dialog_camera_angle(void) { - if (select_or_activate_mario_cam(0) == CAM_ANGLE_LAKITU_MARIO) { - gDialogCameraAngleIndex = CAM_ANGLE_LAKITU_MARIO; + if (cam_select_alt_mode(0) == CAM_SELECTION_MARIO) { + gDialogCameraAngleIndex = CAM_SELECTION_MARIO; } else { - gDialogCameraAngleIndex = CAM_ANGLE_LAKITU_FIXED; + gDialogCameraAngleIndex = CAM_SELECTION_FIXED; } } @@ -2341,10 +2341,10 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { switch (index[0]) { case 1: - select_or_activate_mario_cam(1); + cam_select_alt_mode(1); break; case 2: - select_or_activate_mario_cam(2); + cam_select_alt_mode(2); break; } } diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index d2da586..85bca09 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -92,13 +92,13 @@ enum DialogSpecialChars { DIALOG_CHAR_MULTI_THE = 0xD1, // 'the' DIALOG_CHAR_MULTI_YOU = 0xD2, // 'you' #endif - DIALOG_CHAR_HANDAKUTEN = 0x6E, + DIALOG_CHAR_PERIOD = 0x6E, DIALOG_CHAR_COMMA = 0x6F, DIALOG_CHAR_SPACE = 0x9E, - DIALOG_CHAR_STAR_COUNT = 0xE0, // number of stars + DIALOG_CHAR_STAR_COUNT = 0xE0, // number of stars DIALOG_CHAR_UMLAUT = 0xE9, - DIALOG_CHAR_PREFIX_DAKUTEN = 0xF0, // prefix for kana or hira with dakuten - DIALOG_CHAR_PREFIX_HANDAKUTEN = 0xF1, // prefix for kana or hira with handakuten + DIALOG_CHAR_DAKUTEN = 0xF0, + DIALOG_CHAR_PERIOD_OR_HANDAKUTEN = 0xF1, DIALOG_CHAR_STAR_FILLED = 0xFA, DIALOG_CHAR_STAR_OPEN = 0xFD, DIALOG_CHAR_NEWLINE = 0xFE, diff --git a/src/game/interaction.c b/src/game/interaction.c index 17a906c..9fe163d 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -493,7 +493,7 @@ void bounce_off_object(struct MarioState *m, struct Object *o, f32 velY) { void hit_object_from_below(struct MarioState *m, UNUSED struct Object *o) { m->vel[1] = 0.0f; - set_camera_shake(SHAKE_HIT_FROM_BELOW); + set_camera_shake_from_hit(SHAKE_HIT_FROM_BELOW); } static u32 unused_determine_knockback_action(struct MarioState *m) { @@ -629,7 +629,7 @@ void bounce_back_from_attack(struct MarioState *m, u32 interaction) { mario_set_forward_vel(m, -48.0f); } - set_camera_shake(SHAKE_ATTACK); + set_camera_shake_from_hit(SHAKE_ATTACK); m->particleFlags |= 0x00040000; } @@ -669,7 +669,7 @@ u32 take_damage_from_interact_object(struct MarioState *m) { m->hurtCounter += 4 * damage; - set_camera_shake(shake); + set_camera_shake_from_hit(shake); return damage; } @@ -701,7 +701,7 @@ u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) { void reset_mario_pitch(struct MarioState *m) { if (m->action == ACT_WATER_JUMP || m->action == ACT_SHOT_FROM_CANNON || m->action == ACT_FLYING) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); m->faceAngle[0] = 0; } } @@ -714,7 +714,7 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object * if (COURSE_IS_MAIN_COURSE(gCurrCourseNum) && m->numCoins - o->oDamageOrCoinValue < 100 && m->numCoins >= 100) { - bhv_spawn_star_objects(6); + bhv_spawn_star_no_level_exit(6); } return FALSE; diff --git a/src/game/level_geo.c b/src/game/level_geo.c index 1bbee93..5a36383 100644 --- a/src/game/level_geo.c +++ b/src/game/level_geo.c @@ -26,12 +26,12 @@ Gfx *geo_enfvx_main(s32 callContext, struct GraphNode *node, f32 c[4][4]) { // casting to a local struct as necessary. if (GET_HIGH_U16_OF_32(*params) != gAreaUpdateCounter) { - UNUSED struct LevelCamera *sp2C = gCurGraphNodeCamera->config.levelCamera; + UNUSED struct Camera *sp2C = gCurGraphNodeCamera->config.camera; s32 snowMode = GET_LOW_U16_OF_32(*params); - vec3f_to_vec3s(camTo, gCurGraphNodeCamera->to); - vec3f_to_vec3s(camFrom, gCurGraphNodeCamera->from); - vec3f_to_vec3s(marioPos, gPlayerStatusForCamera->pos); + vec3f_to_vec3s(camTo, gCurGraphNodeCamera->focus); + vec3f_to_vec3s(camFrom, gCurGraphNodeCamera->pos); + vec3f_to_vec3s(marioPos, gPlayerCameraState->pos); particleList = envfx_update_particles(snowMode, marioPos, camTo, camFrom); if (particleList != NULL) { Mtx *mtx = alloc_display_list(sizeof(*mtx)); @@ -69,9 +69,9 @@ Gfx *geo_skybox_main(s32 callContext, struct GraphNode *node, UNUSED Mat4 *mtx) struct GraphNodePerspective *camFrustum = (struct GraphNodePerspective *) camNode->fnNode.node.parent; - gfx = create_skybox_facing_camera(0, backgroundNode->background, camFrustum->fov, gCameraStatus.pos[0], - gCameraStatus.pos[1], gCameraStatus.pos[2], gCameraStatus.focus[0], - gCameraStatus.focus[1], gCameraStatus.focus[2]); + gfx = create_skybox_facing_camera(0, backgroundNode->background, camFrustum->fov, gLakituState.pos[0], + gLakituState.pos[1], gLakituState.pos[2], gLakituState.focus[0], + gLakituState.focus[1], gLakituState.focus[2]); } return gfx; } diff --git a/src/game/level_update.c b/src/game/level_update.c index 6cdd6e7..179b3e2 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -533,15 +533,14 @@ void check_instant_warp(void) { gMarioState->marioObj->oPosY = gMarioState->pos[1]; gMarioState->marioObj->oPosZ = gMarioState->pos[2]; - cameraAngle = gMarioState->area->camera->trueYaw; + cameraAngle = gMarioState->area->camera->yaw; change_area(warp->area); gMarioState->area = gCurrentArea; - instant_warp_camera_update(warp->displacement[0], warp->displacement[1], - warp->displacement[2]); + warp_camera(warp->displacement[0], warp->displacement[1], warp->displacement[2]); - gMarioState->area->camera->trueYaw = cameraAngle; + gMarioState->area->camera->yaw = cameraAngle; } } } diff --git a/src/game/main.c b/src/game/main.c index a696f80..f677f6f 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -126,7 +126,7 @@ void AllocPool(void) { void *end = (void *) SEG_POOL_END; main_pool_init(start, end); - D_8033A124 = mem_pool_init(0x4000, MEMORY_POOL_LEFT); + gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); } void create_thread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri pri) { diff --git a/src/game/mario.c b/src/game/mario.c index ecdf566..a64a46c 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -718,19 +718,20 @@ s16 find_floor_slope(struct MarioState *m, s16 yawOffset) { */ void update_mario_sound_and_camera(struct MarioState *m) { u32 action = m->action; - s32 camPreset = m->area->camera->currPreset; + s32 camPreset = m->area->camera->mode; if (action == ACT_FIRST_PERSON) { func_80248CB8(2); gCameraMovementFlags &= ~CAM_MOVE_C_UP_MODE; - func_80285BD8(m->area->camera, -1, 1); + // Go back to the last camera mode + set_camera_mode(m->area->camera, -1, 1); } else if (action == ACT_SLEEPING) { func_80248CB8(2); } if (!(action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) { - if (camPreset == CAMERA_PRESET_BEHIND_MARIO || camPreset == CAMERA_PRESET_WATER_SURFACE) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + if (camPreset == CAMERA_MODE_BEHIND_MARIO || camPreset == CAMERA_MODE_WATER_SURFACE) { + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); } } } @@ -1159,7 +1160,7 @@ s32 check_common_hold_action_exits(struct MarioState *m) { * Transitions Mario from a submerged action to a walking action. */ s32 transition_submerged_to_walking(struct MarioState *m) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); vec3s_set(m->angleVel, 0, 0, 0); @@ -1188,8 +1189,8 @@ s32 set_water_plunge_action(struct MarioState *m) { m->faceAngle[0] = 0; } - if (m->area->camera->currPreset != CAMERA_PRESET_WATER_SURFACE) { - func_80285BD8(m->area->camera, CAMERA_PRESET_WATER_SURFACE, 1); + if (m->area->camera->mode != CAMERA_MODE_WATER_SURFACE) { + set_camera_mode(m->area->camera, CAMERA_MODE_WATER_SURFACE, 1); } return set_mario_action(m, ACT_WATER_PLUNGE, 0); @@ -1304,7 +1305,7 @@ void update_mario_joystick_inputs(struct MarioState *m) { } if (m->intendedMag > 0.0f) { - m->intendedYaw = atan2s(-controller->stickY, controller->stickX) + m->area->camera->trueYaw; + m->intendedYaw = atan2s(-controller->stickY, controller->stickX) + m->area->camera->yaw; m->input |= INPUT_NONZERO_ANALOG; } else { m->intendedYaw = m->faceAngle[1]; @@ -1424,19 +1425,19 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) { if ((m->action & ACT_GROUP_MASK) == ACT_GROUP_SUBMERGED) { heightBelowWater = (f32)(m->waterLevel - 80) - m->pos[1]; - camPreset = m->area->camera->currPreset; + camPreset = m->area->camera->mode; if ((m->action & ACT_FLAG_METAL_WATER)) { - if (camPreset != CAMERA_PRESET_CLOSE) { - func_80285BD8(m->area->camera, CAMERA_PRESET_CLOSE, 1); + if (camPreset != CAMERA_MODE_CLOSE) { + set_camera_mode(m->area->camera, CAMERA_MODE_CLOSE, 1); } } else { - if ((heightBelowWater > 800.0f) && (camPreset != CAMERA_PRESET_BEHIND_MARIO)) { - func_80285BD8(m->area->camera, CAMERA_PRESET_BEHIND_MARIO, 1); + if ((heightBelowWater > 800.0f) && (camPreset != CAMERA_MODE_BEHIND_MARIO)) { + set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1); } - if ((heightBelowWater < 400.0f) && (camPreset != CAMERA_PRESET_WATER_SURFACE)) { - func_80285BD8(m->area->camera, CAMERA_PRESET_WATER_SURFACE, 1); + if ((heightBelowWater < 400.0f) && (camPreset != CAMERA_MODE_WATER_SURFACE)) { + set_camera_mode(m->area->camera, CAMERA_MODE_WATER_SURFACE, 1); } if ((m->action & ACT_FLAG_INTANGIBLE) == 0) { @@ -1850,7 +1851,7 @@ void init_mario_from_save_file(void) { gMarioState->flags = 0; gMarioState->action = 0; gMarioState->spawnInfo = &gPlayerSpawnInfos[0]; - gMarioState->statusForCamera = &gPlayerStatusForCamera[0]; + gMarioState->statusForCamera = &gPlayerCameraState[0]; gMarioState->marioBodyState = &gBodyStates[0]; gMarioState->controller = &gControllers[0]; gMarioState->animation = &D_80339D10; diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index bea18fd..c151ce6 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -79,13 +79,13 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { if (m->vel[1] < -55.0f) { if (fallHeight > 3000.0f) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 16 : 24; - set_camera_shake(SHAKE_FALL_DAMAGE); + set_camera_shake_from_hit(SHAKE_FALL_DAMAGE); play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject); return drop_and_set_mario_action(m, hardFallAction, 4); } else if (fallHeight > damageHeight && !mario_floor_is_slippery(m)) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 8 : 12; m->squishTimer = 30; - set_camera_shake(SHAKE_FALL_DAMAGE); + set_camera_shake_from_hit(SHAKE_FALL_DAMAGE); play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject); } } @@ -798,7 +798,7 @@ s32 act_water_jump(struct MarioState *m) { switch (perform_air_step(m, AIR_STEP_CHECK_LEDGE_GRAB)) { case AIR_STEP_LANDED: set_mario_action(m, ACT_JUMP_LAND, 0); - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_WALL: @@ -810,7 +810,7 @@ s32 act_water_jump(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE); #endif set_mario_action(m, ACT_LEDGE_GRAB, 0); - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_LAVA_WALL: @@ -836,7 +836,7 @@ s32 act_hold_water_jump(struct MarioState *m) { switch (perform_air_step(m, 0)) { case AIR_STEP_LANDED: set_mario_action(m, ACT_HOLD_JUMP_LAND, 0); - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_WALL: @@ -931,7 +931,7 @@ s32 act_ground_pound(struct MarioState *m) { set_mario_action(m, ACT_GROUND_POUND_LAND, 0); } } - set_camera_shake(SHAKE_GROUND_POUND); + set_camera_shake_from_hit(SHAKE_GROUND_POUND); } else if (stepResult == AIR_STEP_HIT_WALL) { mario_set_forward_vel(m, -16.0f); if (m->vel[1] > 0.0f) { @@ -1601,8 +1601,8 @@ s32 act_jump_kick(struct MarioState *m) { } s32 act_shot_from_cannon(struct MarioState *m) { - if (m->area->camera->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - m->statusForCamera->unk1C[1] = 2; + if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) { + m->statusForCamera->cameraEvent = CAM_EVENT_SHOT_FROM_CANNON; } mario_set_forward_vel(m, m->forwardVel); @@ -1619,7 +1619,7 @@ s32 act_shot_from_cannon(struct MarioState *m) { case AIR_STEP_LANDED: set_mario_action(m, ACT_DIVE_SLIDE, 0); m->faceAngle[0] = 0; - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_WALL: @@ -1632,7 +1632,7 @@ s32 act_shot_from_cannon(struct MarioState *m) { m->particleFlags |= PARTICLE_1; set_mario_action(m, ACT_BACKWARD_AIR_KB, 0); - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_LAVA_WALL: @@ -1658,21 +1658,21 @@ s32 act_flying(struct MarioState *m) { s16 startPitch = m->faceAngle[0]; if (m->input & INPUT_Z_PRESSED) { - if (m->area->camera->currPreset == CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); } return set_mario_action(m, ACT_GROUND_POUND, 1); } if (!(m->flags & MARIO_WING_CAP)) { - if (m->area->camera->currPreset == CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); } return set_mario_action(m, ACT_FREEFALL, 0); } - if (m->area->camera->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, 3, 1); + if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1); } if (m->actionState == 0) { @@ -1712,7 +1712,7 @@ s32 act_flying(struct MarioState *m) { set_anim_to_frame(m, 7); m->faceAngle[0] = 0; - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); break; case AIR_STEP_HIT_WALL: @@ -1730,7 +1730,7 @@ s32 act_flying(struct MarioState *m) { m->particleFlags |= PARTICLE_1; set_mario_action(m, ACT_BACKWARD_AIR_KB, 0); - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); } else { if (m->actionTimer++ == 0) { play_sound(SOUND_ACTION_HIT, m->marioObj->header.gfx.cameraToObject); @@ -1804,8 +1804,8 @@ s32 act_riding_hoot(struct MarioState *m) { s32 act_flying_triple_jump(struct MarioState *m) { #ifndef VERSION_JP if (m->input & (INPUT_B_PRESSED | INPUT_Z_PRESSED)) { - if (m->area->camera->currPreset == CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, m->area->camera->defPreset, 1); + if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, m->area->camera->defMode, 1); } if (m->input & INPUT_B_PRESSED) { return set_mario_action(m, ACT_DIVE, 0); @@ -1842,8 +1842,8 @@ s32 act_flying_triple_jump(struct MarioState *m) { } if (m->vel[1] < 4.0f) { - if (m->area->camera->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, 3, 1); + if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1); } if (m->forwardVel < 32.0f) { @@ -1853,8 +1853,8 @@ s32 act_flying_triple_jump(struct MarioState *m) { set_mario_action(m, ACT_FLYING, 1); } - if (m->actionTimer++ == 10 && m->area->camera->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, 3, 1); + if (m->actionTimer++ == 10 && m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1); } update_air_without_turn(m); diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 35e1037..ea4fd54 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -186,7 +186,7 @@ s32 act_holding_pole(struct MarioState *m) { s32 act_climbing_pole(struct MarioState *m) { s32 sp24; struct Object *marioObj = m->marioObj; - s16 cameraAngle = m->area->camera->trueYaw; + s16 cameraAngle = m->area->camera->yaw; #ifndef VERSION_JP if (m->health < 0x100) { @@ -668,7 +668,7 @@ s32 act_in_cannon(struct MarioState *m) { m->marioObj->header.gfx.node.flags &= ~0x0001; m->usedObj->oInteractStatus = INT_STATUS_INTERACTED; - m->statusForCamera->unk1C[1] = 1; + m->statusForCamera->cameraEvent = CAM_EVENT_CANNON; m->statusForCamera->usedObj = m->usedObj; vec3f_set(m->vel, 0.0f, 0.0f, 0.0f); diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 8629524..0e54f94 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -511,7 +511,7 @@ s32 act_reading_sign(struct MarioState *m) { switch (m->actionState) { // start dialog case 0: - stop_mario(1); + trigger_cutscene_dialog(1); enable_time_stop(); // reading sign set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); @@ -531,7 +531,7 @@ s32 act_reading_sign(struct MarioState *m) { // in dialog case 2: // dialog finished - if (gCurrLevelCamera->cutscene == 0) { + if (gCamera->cutscene == 0) { disable_time_stop(); set_mario_action(m, ACT_IDLE, 0); } @@ -650,7 +650,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { } s32 act_star_dance(struct MarioState *m) { - m->faceAngle[1] = m->area->camera->trueYaw; + m->faceAngle[1] = m->area->camera->yaw; set_mario_animation(m, m->actionState == 2 ? MARIO_ANIM_RETURN_FROM_STAR_DANCE : MARIO_ANIM_STAR_DANCE); general_star_dance_handler(m, 0); @@ -662,7 +662,7 @@ s32 act_star_dance(struct MarioState *m) { } s32 act_star_dance_water(struct MarioState *m) { - m->faceAngle[1] = m->area->camera->trueYaw; + m->faceAngle[1] = m->area->camera->yaw; set_mario_animation(m, m->actionState == 2 ? MARIO_ANIM_RETURN_FROM_WATER_STAR_DANCE : MARIO_ANIM_WATER_STAR_DANCE); vec3f_copy(m->marioObj->header.gfx.pos, m->pos); @@ -1430,9 +1430,8 @@ s32 act_teleport_fade_in(struct MarioState *m) { if (m->actionTimer++ == 32) { if (m->pos[1] < m->waterLevel - 100) { // Check if the camera is not underwater. - if (m->area->camera->currPreset != CAMERA_PRESET_WATER_SURFACE) { - // camera related function? - func_80285BD8(m->area->camera, 8, 1); + if (m->area->camera->mode != CAMERA_MODE_WATER_SURFACE) { + set_camera_mode(m->area->camera, CAMERA_MODE_WATER_SURFACE, 1); } set_mario_action(m, ACT_WATER_IDLE, 0); } else { @@ -1449,7 +1448,7 @@ s32 act_teleport_fade_in(struct MarioState *m) { s32 act_shocked(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_ACTION_SOUND_PLAYED); play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject); - set_camera_shake(SHAKE_SHOCK); + set_camera_shake_from_hit(SHAKE_SHOCK); if (set_mario_animation(m, MARIO_ANIM_SHOCKED) == 0) { m->actionTimer++; @@ -1647,13 +1646,13 @@ static void advance_cutscene_step(struct MarioState *m) { static void intro_cutscene_hide_hud_and_mario(struct MarioState *m) { gHudDisplay.flags = HUD_DISPLAY_NONE; - m->statusForCamera->unk1C[1] = 9; + m->statusForCamera->cameraEvent = CAM_EVENT_START_INTRO; m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; advance_cutscene_step(m); } static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) { - if ((s16) m->statusForCamera->unk1C[1] != 9) { + if ((s16) m->statusForCamera->cameraEvent != CAM_EVENT_START_INTRO) { if (m->actionTimer++ == 37) { sIntroWarpPipeObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_CASTLE_GROUNDS_WARP_PIPE, @@ -1728,7 +1727,7 @@ static void intro_cutscene_lower_pipe(struct MarioState *m) { } static void intro_cutscene_set_mario_to_idle(struct MarioState *m) { - if (gCurrLevelCamera->cutscene == 0) { + if (gCamera->cutscene == 0) { gCameraMovementFlags &= ~CAM_MOVE_C_UP_MODE; set_mario_action(m, ACT_IDLE, 0); } @@ -1794,7 +1793,7 @@ static void jumbo_star_cutscene_falling(struct MarioState *m) { } else { set_mario_animation(m, MARIO_ANIM_GENERAL_LAND); if (is_anim_at_end(m)) { - m->statusForCamera->unk1C[1] = 10; + m->statusForCamera->cameraEvent = CAM_EVENT_START_GRAND_STAR; advance_cutscene_step(m); } } @@ -1962,7 +1961,7 @@ static f32 func_8025BC14(struct Object *o) { // make mario fall and soften wing cap gravity static void end_peach_cutscene_mario_falling(struct MarioState *m) { if (m->actionTimer == 1) { - m->statusForCamera->unk1C[1] = 11; + m->statusForCamera->cameraEvent = CAM_EVENT_START_ENDING; } m->input |= INPUT_A_DOWN; @@ -2444,11 +2443,11 @@ static s32 act_credits_cutscene(struct MarioState *m) { s32 width; s32 height; - m->statusForCamera->unk1C[1] = 13; + m->statusForCamera->cameraEvent = CAM_EVENT_START_CREDITS; // checks if mario is underwater (JRB, DDD, SA, etc.) if (m->pos[1] < m->waterLevel - 100) { - if (m->area->camera->currPreset != CAMERA_PRESET_BEHIND_MARIO) { - func_80285BD8(m->area->camera, 3, 1); + if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) { + set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1); } set_mario_animation(m, MARIO_ANIM_WATER_IDLE); vec3f_copy(m->marioObj->header.gfx.pos, m->pos); @@ -2499,7 +2498,7 @@ static s32 act_credits_cutscene(struct MarioState *m) { static s32 act_end_waving_cutscene(struct MarioState *m) { if (m->actionState == 0) { - m->statusForCamera->unk1C[1] = 12; + m->statusForCamera->cameraEvent = CAM_EVENT_START_END_WAVING; sEndPeachObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_PEACH, bhvEndPeach, 60, 906, -1180, 0, 0, 0); diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index d81c1cf..6c39c7b 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1062,20 +1062,21 @@ s32 act_first_person(struct MarioState *m) { sp1C = 0U < (m->input & (INPUT_UNKNOWN_10 | 0xC)); if (m->actionState == 0) { func_80248C28(2); - func_80285BD8(m->area->camera, 6, 0x10); + set_camera_mode(m->area->camera, CAMERA_MODE_C_UP, 0x10); m->actionState = 1; } else { if (!(m->input & INPUT_FIRST_PERSON) || sp1C) { func_80248CB8(2); - func_80285BD8(m->area->camera, -1, 1); + // Go back to the last camera mode + set_camera_mode(m->area->camera, -1, 1); return set_mario_action(m, ACT_IDLE, 0); } } if (m->floor->type == SURFACE_LOOK_UP_WARP) { if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) { - sp1A = m->statusForCamera->unk16[0]; - sp18 = ((m->statusForCamera->unk16[1] * 4) / 3) + m->faceAngle[1]; + sp1A = m->statusForCamera->headRotation[0]; + sp18 = ((m->statusForCamera->headRotation[1] * 4) / 3) + m->faceAngle[1]; if (sp1A == -0x1800) { if (sp18 < -0x6FFF || sp18 >= 0x7000) { level_trigger_warp(m, 1); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index b688c91..b18dd24 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -881,7 +881,7 @@ static s32 act_forward_water_kb(struct MarioState *m) { static s32 act_water_shocked(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_ACTION_SOUND_PLAYED); play_sound(SOUND_MOVING_SHOCKED, m->marioObj->header.gfx.cameraToObject); - set_camera_shake(SHAKE_SHOCK); + set_camera_shake_from_hit(SHAKE_SHOCK); if (set_mario_animation(m, MARIO_ANIM_SHOCKED) == 0) { m->actionTimer++; diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 5d5c013..12ff921 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -108,21 +108,21 @@ static void bhvToadMessage_opaque(void) { } static void bhvToadMessage_talking(void) { - if (obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG_1, gCurrentObject->oToadMessageDialogId) != 0) { + if (obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId) != 0) { gCurrentObject->oToadMessageRecentlyTalked = 1; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; switch (gCurrentObject->oToadMessageDialogId) { case TOAD_STAR_1_DIALOG: gCurrentObject->oToadMessageDialogId = TOAD_STAR_1_DIALOG_AFTER; - bhv_spawn_star_objects(0); + bhv_spawn_star_no_level_exit(0); break; case TOAD_STAR_2_DIALOG: gCurrentObject->oToadMessageDialogId = TOAD_STAR_2_DIALOG_AFTER; - bhv_spawn_star_objects(1); + bhv_spawn_star_no_level_exit(1); break; case TOAD_STAR_3_DIALOG: gCurrentObject->oToadMessageDialogId = TOAD_STAR_3_DIALOG_AFTER; - bhv_spawn_star_objects(2); + bhv_spawn_star_no_level_exit(2); break; } } @@ -370,11 +370,11 @@ Gfx *Geo18_802773A4(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { if (callContext == GEO_CONTEXT_RENDER) { struct GraphNodeRotation *sp20 = (struct GraphNodeRotation *) node->next; - u8 *sp1C = (u8 *) gCurGraphNodeCamera->config.levelCamera; + struct Camera *camera = gCurGraphNodeCamera->config.camera; - if (*sp1C == 6) { - sp20->rotation[0] = gPlayerStatusForCamera->unk16[1]; - sp20->rotation[2] = gPlayerStatusForCamera->unk16[0]; + if (camera->mode == CAMERA_MODE_C_UP) { + sp20->rotation[0] = gPlayerCameraState->headRotation[1]; + sp20->rotation[2] = gPlayerCameraState->headRotation[0]; } else if (action & 0x20000000) { sp20->rotation[0] = sp28->unk12[1]; sp20->rotation[1] = sp28->unk12[2]; diff --git a/src/game/memory.c b/src/game/memory.c index bac8699..b287d09 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -50,7 +50,11 @@ static u8 *sPoolEnd; static struct MainPoolBlock *sPoolListHeadL; static struct MainPoolBlock *sPoolListHeadR; -struct MemoryPool *D_8033A124; +/** + * Memory pool for small graphical effects that aren't connected to Objects. + * Used for colored text, paintings, and environmental snow and bubbles. + */ +struct MemoryPool *gEffectsMemoryPool; static struct MainPoolState *gMainPoolState = NULL; diff --git a/src/game/memory.h b/src/game/memory.h index 7555226..d47d247 100644 --- a/src/game/memory.h +++ b/src/game/memory.h @@ -20,7 +20,7 @@ struct MemoryPool; // Declaring this variable extern puts it in the wrong place in the bss order // when this file is included from memory.c (first instead of last). Hence, // ifdef hack. It was very likely subject to bss reordering originally. -extern struct MemoryPool *D_8033A124; +extern struct MemoryPool *gEffectsMemoryPool; #endif uintptr_t set_segment_base_addr(s32 segment, void *addr); diff --git a/src/game/moving_texture.c b/src/game/moving_texture.c index 9fcb8e9..1c6c380 100644 --- a/src/game/moving_texture.c +++ b/src/game/moving_texture.c @@ -656,7 +656,7 @@ Gfx *geo_movtex_draw_water_regions(s32 callContext, struct GraphNode *node, UNUS } asGenerated = (struct GraphNodeGenerated *) node; if (asGenerated->parameter == JRB_MOVTEX_INTIAL_MIST) { - if (gCameraStatus.camFocAndPosCurrAndGoal[3][1] < 1024.0) { // if camera under water + if (gLakituState.goalPos[1] < 1024.0) { // if camera under water return NULL; } if (save_file_get_star_flags(gCurrSaveFileNum - 1, 2) & 1) { // first level in JRB complete diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 92a66bc..bbf5d0b 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -693,7 +693,7 @@ s16 trigger_obj_dialog_when_facing(s32 *inDialog, s16 dialogID, f32 dist, s32 ac *inDialog = 1; if (set_mario_npc_dialog(actionArg) == 2) { //If Mario is speaking. - dialogueResponse = cutscene_object_with_dialog(CUTSCENE_DIALOG_1, o, dialogID); + dialogueResponse = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID); if (dialogueResponse != 0) { set_mario_npc_dialog(0); *inDialog = 0; diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c index f6b3f2c..9299047 100644 --- a/src/game/obj_behaviors_2.c +++ b/src/game/obj_behaviors_2.c @@ -142,7 +142,7 @@ static s16 obj_get_pitch_from_vel(void) { */ static s32 obj_update_race_proposition_dialog(s16 dialogID) { s32 dialogResponse = - obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0 | DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED, CUTSCENE_DIALOG_2, dialogID); + obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0 | DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED, CUTSCENE_RACE_DIALOG, dialogID); if (dialogResponse == 2) { set_mario_npc_dialog(0); diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 334465b..f74aecb 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1589,8 +1589,8 @@ void obj_shake_y(f32 amount) { } } -void func_802A11B4(UNUSED struct Object *a0, s32 a1) { - gPlayerStatusForCamera->unk1C[1] = (s16) a1; +void obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent) { + gPlayerCameraState->cameraEvent = (s16) cameraEvent; gSecondCameraFocus = o; } @@ -2352,7 +2352,7 @@ void obj_call_action_function(void (*actionFunctions[])(void)) { } static struct Object *func_802A36D8(s32 sp20, s32 sp24) { - struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvUnused080C); + struct Object *sp1C = spawn_object(o, MODEL_STAR, bhvSpawnedStarNoLevelExit); sp1C->oSparkleSpawnUnk1B0 = sp24; sp1C->oBehParams = o->oBehParams; sp1C->oBehParams2ndByte = sp20; @@ -2791,8 +2791,8 @@ s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ) { return TRUE; } -void ShakeScreen(s32 sp18) { - func_8027F440(sp18, o->oPosX, o->oPosY, o->oPosZ); +void ShakeScreen(s32 shake) { + set_camera_shake_from_point(shake, o->oPosX, o->oPosY, o->oPosZ); } s32 attack_collided_non_mario_object(struct Object *obj) { diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index ce9ecaa..d6b202c 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -290,7 +290,7 @@ extern f32 obj_lateral_dist_to_home(void); extern void obj_set_pos_to_home(void); void obj_set_pos_to_home_and_stop(void); extern void obj_shake_y(f32); -void func_802A11B4(struct Object*, s32); +void obj_start_cam_event(struct Object *obj, s32 cameraEvent); // extern ? Unknown802A11E4(?); void obj_set_billboard(struct Object *a0); void obj_set_hitbox_radius_and_height(f32,f32); diff --git a/src/game/object_helpers2.h b/src/game/object_helpers2.h index 8f735ec..8ae5f75 100644 --- a/src/game/object_helpers2.h +++ b/src/game/object_helpers2.h @@ -72,7 +72,7 @@ s32 obj_update_dialog_with_cutscene(s32 arg0, s32 dialogFlags, s32 cutsceneTable s32 obj_has_model(u16); extern void obj_align_gfx_with_floor(void); // extern ? mario_is_within_rectangle(?); -void ShakeScreen(s32); +void ShakeScreen(s32 shake); extern s32 attack_collided_non_mario_object(struct Object *obj); s32 obj_was_attacked_or_ground_pounded(void); void copy_object_behavior_params(struct Object*,struct Object*); diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h index 38d1685..f98183e 100644 --- a/src/game/object_list_processor.h +++ b/src/game/object_list_processor.h @@ -11,7 +11,7 @@ struct SpawnInfo; */ #define TIME_STOP_UNKNOWN_0 (1 << 0) #define TIME_STOP_ENABLED (1 << 1) -#define TIME_STOP_UNKNOWN_2 (1 << 2) +#define TIME_STOP_DIALOG (1 << 2) #define TIME_STOP_MARIO_AND_DOORS (1 << 3) #define TIME_STOP_ALL_OBJECTS (1 << 4) #define TIME_STOP_MARIO_OPENED_DOOR (1 << 5) diff --git a/src/game/paintings.c b/src/game/paintings.c index b3794a0..de350ea 100644 --- a/src/game/paintings.c +++ b/src/game/paintings.c @@ -15,7 +15,7 @@ s16 gPaintingMarioFloorType; float gPaintingMarioXPos, gPaintingMarioYPos, gPaintingMarioZPos; struct Thing *D_8035FFA0; -float (*D_8035FFA4)[3]; // TODO: Use struct +Vec3f *D_8035FFA4; struct Painting *ripplingPainting; s8 dddStatus; @@ -495,7 +495,7 @@ s16 painting_conditionally_calculate_point_ripple(struct Painting *painting, s16 void Print1(struct Painting *painting, s16 *b, s16 c) { s16 sp1E; - D_8035FFA0 = mem_pool_alloc(D_8033A124, c * sizeof(struct Thing)); + D_8035FFA0 = mem_pool_alloc(gEffectsMemoryPool, c * sizeof(struct Thing)); if (D_8035FFA0 == NULL) { } for (sp1E = 0; sp1E < c; sp1E++) { @@ -509,7 +509,7 @@ void Print1(struct Painting *painting, s16 *b, s16 c) { void Print2(s16 *a, s16 b, s16 c) { s16 sp46; - D_8035FFA4 = mem_pool_alloc(D_8033A124, c * 12U); // TODO: Make use sizeof(struct) + D_8035FFA4 = mem_pool_alloc(gEffectsMemoryPool, c * sizeof(Vec3f)); if (D_8035FFA4 == NULL) { } for (sp46 = 0; sp46 < c; sp46++) { @@ -753,8 +753,8 @@ Gfx *display_painting_rippling(struct Painting *painting) { sp28 = func_802D4874(painting); break; } - mem_pool_free(D_8033A124, D_8035FFA0); - mem_pool_free(D_8033A124, D_8035FFA4); + mem_pool_free(gEffectsMemoryPool, D_8035FFA0); + mem_pool_free(gEffectsMemoryPool, D_8035FFA4); return sp28; } diff --git a/src/game/paintings.h b/src/game/paintings.h index 3a2ce19..ba98221 100644 --- a/src/game/paintings.h +++ b/src/game/paintings.h @@ -94,8 +94,6 @@ struct Painting float vSize; }; -extern struct MemoryPool *D_8033A124; - extern struct Painting cotmc_painting; extern struct Painting bob_painting; @@ -128,7 +126,7 @@ struct Thing { //TODO: Give me a better name }; extern struct Thing *D_8035FFA0; -extern float (*D_8035FFA4)[3]; +extern Vec3f *D_8035FFA4; extern struct Painting *ripplingPainting; extern s8 dddStatus; diff --git a/src/game/print.c b/src/game/print.c index b8f2eca..6249691 100644 --- a/src/game/print.c +++ b/src/game/print.c @@ -185,7 +185,8 @@ void print_text_fmt_int(s32 x, s32 y, const char *str, s32 n) { s32 srcIndex = 0; // Don't continue if there is no memory to do so. - if ((sTextLabels[sTextLabelsCount] = (struct TextLabel *) mem_pool_alloc(D_8033A124, 60)) == NULL) { + if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, + sizeof(struct TextLabel))) == NULL) { return; } @@ -235,7 +236,8 @@ void print_text(s32 x, s32 y, const char *str) { s32 srcIndex = 0; // Don't continue if there is no memory to do so. - if ((sTextLabels[sTextLabelsCount] = (struct TextLabel *) mem_pool_alloc(D_8033A124, 60)) == NULL) { + if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, + sizeof(struct TextLabel))) == NULL) { return; } @@ -268,7 +270,8 @@ void print_text_centered(s32 x, s32 y, const char *str) { s32 srcIndex = 0; // Don't continue if there is no memory to do so. - if ((sTextLabels[sTextLabelsCount] = (struct TextLabel *) mem_pool_alloc(D_8033A124, 60)) == NULL) { + if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, + sizeof(struct TextLabel))) == NULL) { return; } @@ -454,7 +457,7 @@ void render_text_labels(void) { } } - mem_pool_free(D_8033A124, (void *) sTextLabels[i]); + mem_pool_free(gEffectsMemoryPool, sTextLabels[i]); } gSPDisplayList(gDisplayListHead++, dl_hud_img_end); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index a4e09a9..01ba06c 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -314,7 +314,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(rollMtx), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH); - mtxf_lookat(cameraTransform, node->from, node->to, node->roll); + mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll); mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]); gMatStackIndex++; mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); diff --git a/src/game/screen_transition.c b/src/game/screen_transition.c index aff4000..5fc9e63 100644 --- a/src/game/screen_transition.c +++ b/src/game/screen_transition.c @@ -9,6 +9,7 @@ #include "memory.h" #include "geo_misc.h" #include "segment2.h" +#include "camera.h" u8 sTransitionColorFadeCount[4] = { 0 }; u16 sTransitionTextureFadeCount[2] = { 0 }; @@ -271,7 +272,7 @@ Gfx *geo_cannon_circle_base(s32 callContext, struct GraphNode *node, UNUSED f32 Gfx *dlist = NULL; if (callContext == GEO_CONTEXT_RENDER && gCurrentArea != NULL - && gCurrentArea->camera->currPreset == CAMERA_PRESET_INSIDE_CANNON) { + && gCurrentArea->camera->mode == CAMERA_MODE_INSIDE_CANNON) { graphNode->fnNode.node.flags = (graphNode->fnNode.node.flags & 0xFF) | 0x500; dlist = render_cannon_circle_base(); } diff --git a/text/define_text.inc.c b/text/define_text.inc.c index 1a90a4d..9011b6c 100644 --- a/text/define_text.inc.c +++ b/text/define_text.inc.c @@ -5,20 +5,20 @@ // (this wasn't translated for US, and was removed in EU) static const u8 Debug0[] = { - _("STAGE SELECT\n" - " つづける?\n" - " 1 マウンテン\n" - " 2 ファイア-バブル\n" - " 3 スノ-スライダ-\n" - " 4 ウォ-タ-ランド\n" - " クッパ1ごう\n" - " もどる") + _("STAGE SELECT\n" + " つづける?\n" + " 1 マウンテン\n" + " 2 ファイアーバブル\n" + " 3 スノースライダー\n" + " 4 ウォーターランド\n" + "   クッパ1ごう\n" + " もどる") }; static const u8 Debug1[] = { - _("PAUSE \n" - " つづける?\n" - " やめる ?") + _("PAUSE    \n" + " つづける?\n" + " やめる ?") }; static const struct DialogEntry debug_text_entry_0 = { diff --git a/text/jp/courses.h b/text/jp/courses.h index 53e81ff..4590c3a 100644 --- a/text/jp/courses.h +++ b/text/jp/courses.h @@ -1,80 +1,80 @@ -COURSE_ACTS(COURSE_BOB, _(" 1 ボムへいの せんじょう"), - _("やまのうえの ボムキング") , _("はくねつ ノコノコレ-ス") , _("そらのしままで ぶっとべ"), - _("8まいの あかコイン") , _("そらにはばたけ はねマリオ") , _("ワンワンの いぬごやで")) +COURSE_ACTS(COURSE_BOB, _(" 1 ボムへいの せんじょう"), + _("やまのうえの ボムキング") , _("はくねつ ノコノコレース") , _("そらのしままで ぶっとべ"), + _("8まいの あかコイン") , _("そらにはばたけ はねマリオ") , _("ワンワンの いぬごやで")) -COURSE_ACTS(COURSE_WF, _(" 2 バッタンキングの とりで"), - _("いかりのバッタン キング") , _("とりでの てっぺんへ") , _("たいほうで ひとっとび"), - _("うきしまの 8まいコイン") , _("とりかごへ スト-ン") , _("たいほうで ぶっこわせ!")) +COURSE_ACTS(COURSE_WF, _(" 2 バッタンキングの とりで"), + _("いかりのバッタン キング") , _("とりでの てっぺんへ") , _("たいほうで ひとっとび"), + _("うきしまの 8まいコイン") , _("とりかごへ ストーン") , _("たいほうで ぶっこわせ!")) -COURSE_ACTS(COURSE_JRB, _(" 3 かいぞくの いりえ"), - _("ちんぼつせんの おたから") , _("でてこい きょだいウツボ") , _("かいていどうくつの おたから"), - _("うかんだフネの あかコイン") , _("いわのはしらへ ひとっとび") , _("ふきだす みずを くぐれ")) +COURSE_ACTS(COURSE_JRB, _(" 3 かいぞくの いりえ"), + _("ちんぼつせんの おたから") , _("でてこい きょだいウツボ") , _("かいていどうくつの おたから"), + _("うかんだフネの あかコイン") , _("いわのはしらへ ひとっとび") , _("ふきだす みずを くぐれ")) -COURSE_ACTS(COURSE_CCM, _(" 4 さむいさむい マウンテン"), - _("ス-パ-スノ-スライダ-") , _("まいごの こペンギン") , _("ペンギン チャンピオンレ-ス"), - _("すべって 8まいあかコイン") , _("ゴロゴロ ゆきダルマ") , _("かくれ ス-パ- カベキック")) +COURSE_ACTS(COURSE_CCM, _(" 4 さむいさむい マウンテン"), + _("スーパースノースライダー") , _("まいごの こペンギン") , _("ペンギン チャンピオンレース"), + _("すべって 8まいあかコイン") , _("ゴロゴロ ゆきダルマ") , _("かくれ スーパー カベキック")) -COURSE_ACTS(COURSE_BBH, _(" 5 テレサの ホラ-ハウス"), - _("おやかたテレサを さがせ") , _("テレサの メリ-ゴ-ランド") , _("ほんだなオバケの ナゾ"), - _("8まいコインは どこだ") , _("バルコニ-の ボステレサ") , _("かくしべやの おおめだま")) +COURSE_ACTS(COURSE_BBH, _(" 5 テレサの ホラーハウス"), + _("おやかたテレサを さがせ") , _("テレサの メリーゴーランド") , _("ほんだなオバケの ナゾ"), + _("8まいコインは どこだ") , _("バルコニーの ボステレサ") , _("かくしべやの おおめだま")) -COURSE_ACTS(COURSE_HMC, _(" 6 やみにとける どうくつ"), - _("ドッシ-のいる ちていこ") , _("そうさリフトの あかコイン") , _("メタルで ダッシュ"), - _("ケムリめいろを ぬけて") , _("ケムリめいろの ひじょうぐち") , _("ゴロゴロいわの ひみつ")) +COURSE_ACTS(COURSE_HMC, _(" 6 やみにとける どうくつ"), + _("ドッシーのいる ちていこ") , _("そうさリフトの あかコイン") , _("メタルで ダッシュ"), + _("ケムリめいろを ぬけて") , _("ケムリめいろの ひじょうぐち"), _("ゴロゴロいわの ひみつ")) -COURSE_ACTS(COURSE_LLL, _(" 7 ファイアバブル ランド"), - _("おとせ ボスどんけつ") , _("たたかえ!どんけつたい") , _("15パズルの 8まいコイン"), - _("コロコロ まるたわたり") , _("かざんの パワ-スタ-") , _("かざんの リフトツア-")) +COURSE_ACTS(COURSE_LLL, _(" 7 ファイアバブル ランド"), + _("おとせ ボスどんけつ") , _("たたかえ!どんけつたい") , _("15パズルの 8まいコイン"), + _("コロコロ まるたわたり") , _("かざんの パワースター") , _("かざんの リフトツアー")) -COURSE_ACTS(COURSE_SSL, _(" 8 あっちっち さばく"), - _("いたずらハゲたか ジャンゴ") , _("ピラミッドの てっぺんで") , _("きょだいピラミッドの ないぶ"), - _("4つのはしらに たつものへ") , _("とびまわれ 8まいコイン") , _("きょだいピラミッドのナゾ")) +COURSE_ACTS(COURSE_SSL, _(" 8 あっちっち さばく"), + _("いたずらハゲたか ジャンゴ") , _("ピラミッドの てっぺんで") , _("きょだいピラミッドの ないぶ"), + _("4つのはしらに たつものへ") , _("とびまわれ 8まいコイン") , _("きょだいピラミッドのナゾ")) -COURSE_ACTS(COURSE_DDD, _(" 9 ウォ-タ- ランド"), - _("クッパの せんすいかん") , _("うずしおの たからばこ") , _("にげたクッパの あかコイン"), - _("ふきだす みずを くぐれ") , _("マンタの おくりもの") , _("ボウシが そろったら")) +COURSE_ACTS(COURSE_DDD, _(" 9 ウォーター ランド"), + _("クッパの せんすいかん") , _("うずしおの たからばこ") , _("にげたクッパの あかコイン"), + _("ふきだす みずを くぐれ") , _("マンタの おくりもの") , _("ボウシが そろったら")) -COURSE_ACTS(COURSE_SL, _("10 スノ-マンズ ランド"), - _("おおゆきダルマの おでこ") , _("こおりのくにの どんけつ") , _("こおりの オブジェ"), - _("つめたい いけを こえて") , _("コウラにのって あかコイン") , _("フワフワさんの おうち")) +COURSE_ACTS(COURSE_SL, _("10 スノーマンズ ランド"), + _("おおゆきダルマの おでこ") , _("こおりのくにの どんけつ") , _("こおりの オブジェ"), + _("つめたい いけを こえて") , _("コウラにのって あかコイン") , _("フワフワさんの おうち")) -COURSE_ACTS(COURSE_WDW, _("11 みずびたシティ-"), - _("ビリビリの まめリフト") , _("トップオブ ザ シティ-") , _("あさせと そらのシ-クレット"), - _("いそげ!かなあみエレベ-タ-") , _("ダウンタウンの あかコイン") , _("ダウンタウンを かけろ")) +COURSE_ACTS(COURSE_WDW, _("11 みずびたシティー"), + _("ビリビリの まめリフト") , _("トップオブ ザ シティー") , _("あさせと そらのシークレット"), + _("いそげ!かなあみエレベーター"), _("ダウンタウンの あかコイン") , _("ダウンタウンを かけろ")) -COURSE_ACTS(COURSE_TTM, _("12 たかいたかいマウンテン"), - _("たかいたかい やまのうえ") , _("いたずらザル ウッキィのオリ") , _("おばけキノコの あかコイン"), - _("マウンテン スライダ-") , _("はしのうえから みわたせば") , _("ぶっとべ はなれキノコへ")) +COURSE_ACTS(COURSE_TTM, _("12 たかいたかいマウンテン"), + _("たかいたかい やまのうえ") , _("いたずらザル ウッキィのオリ"), _("おばけキノコの あかコイン"), + _("マウンテン スライダー") , _("はしのうえから みわたせば") , _("ぶっとべ はなれキノコへ")) -COURSE_ACTS(COURSE_THI, _("13 ちびでか アイランド"), - _("きょだいパックンフラワ-") , _("デカじまの てっぺんで") , _("ノコノコ リタ-ンマッチ"), - _("チビじまの 5シ-クレット") , _("ハナチャンの あかコイン") , _("イカリの ハナチャン")) +COURSE_ACTS(COURSE_THI, _("13 ちびでか アイランド"), + _("きょだいパックンフラワー") , _("デカじまの てっぺんで") , _("ノコノコ リターンマッチ"), + _("チビじまの 5シークレット") , _("ハナチャンの あかコイン") , _("イカリの ハナチャン")) -COURSE_ACTS(COURSE_TTC, _("14 チックタックロック"), - _("グルグル かごのなかへ") , _("ふりこの へや") , _("チックタックはりの うえ"), - _("えっへん てっぺん ドッスン") , _("つきだしを のりこえて") , _("00ふんの あかコイン")) +COURSE_ACTS(COURSE_TTC, _("14 チックタックロック"), + _("グルグル かごのなかへ") , _("ふりこの へや") , _("チックタックはりの うえ"), + _("えっへん てっぺん ドッスン"), _("つきだしを のりこえて") , _("00ふんの あかコイン")) -COURSE_ACTS(COURSE_RR, _("15 レインボ- クル-ズ"), - _("にじを わたる ふね") , _("てんくうの おやしき") , _("タテめいろの あかコイン"), - _("カゼきる きょだいブランコ") , _("おおぞら アスレチック") , _("にじの かなたの しま")) +COURSE_ACTS(COURSE_RR, _("15 レインボー クルーズ"), + _("にじを わたる ふね") , _("てんくうの おやしき") , _("タテめいろの あかコイン"), + _("カゼきる きょだいブランコ") , _("おおぞら アスレチック") , _("にじの かなたの しま")) -SECRET_STAR(COURSE_BITDW, _(" やみの せかいの クッパ")) -SECRET_STAR(COURSE_BITFS, _(" ほのおの うみの クッパ")) -SECRET_STAR(COURSE_BITS, _(" てんくうの たたかい!")) -SECRET_STAR(COURSE_PSS, _(" ピ-チのかくれスライダ-")) -SECRET_STAR(COURSE_COTMC, _(" メタルスイッチの たき")) -SECRET_STAR(COURSE_TOTWC, _(" はばたけ!はねスイッチへ")) -SECRET_STAR(COURSE_VCUTM, _(" おほりのとうめいスイッチ")) -SECRET_STAR(COURSE_WMOTR, _(" にじ かける はねマリオ")) -SECRET_STAR(COURSE_SA, _(" おさかなと いっしょ")) -SECRET_STAR(COURSE_CAKE_END, _(" おいしいケ-キ")) +SECRET_STAR(COURSE_BITDW, _("   やみの せかいの クッパ")) +SECRET_STAR(COURSE_BITFS, _("   ほのおの うみの クッパ")) +SECRET_STAR(COURSE_BITS, _("   てんくうの たたかい!")) +SECRET_STAR(COURSE_PSS, _("   ピーチのかくれスライダー")) +SECRET_STAR(COURSE_COTMC, _("   メタルスイッチの たき")) +SECRET_STAR(COURSE_TOTWC, _("   はばたけ!はねスイッチへ")) +SECRET_STAR(COURSE_VCUTM, _("   おほりのとうめいスイッチ")) +SECRET_STAR(COURSE_WMOTR, _("   にじ かける はねマリオ")) +SECRET_STAR(COURSE_SA, _("   おさかなと いっしょ")) +SECRET_STAR(COURSE_CAKE_END, _("   おいしいケーキ")) -CASTLE_SECRET_STARS(_(" おしろのかくれスタ-")) +CASTLE_SECRET_STARS(_("   おしろのかくれスター")) -EXTRA_TEXT(0, _("おしろのかくれスタ-")) -EXTRA_TEXT(1, _("100まいコインの スタ-")) -EXTRA_TEXT(2, _("マウンテンのへやが ひらく!")) -EXTRA_TEXT(3, _("みずとゆき2つのへやが ひらく!")) -EXTRA_TEXT(4, _("おおきなほしの ドアがひらく!")) -EXTRA_TEXT(5, _("クッパへの とびらがひらく!")) -EXTRA_TEXT(6, _("3がいへの とびらがひらく!")) +EXTRA_TEXT(0, _("おしろのかくれスター")) +EXTRA_TEXT(1, _("100まいコインの スター")) +EXTRA_TEXT(2, _("マウンテンのへやが ひらく!")) +EXTRA_TEXT(3, _("みずとゆき2つのへやが ひらく!")) +EXTRA_TEXT(4, _("おおきなほしの ドアがひらく!")) +EXTRA_TEXT(5, _("クッパへの とびらがひらく!")) +EXTRA_TEXT(6, _("3がいへの とびらがひらく!")) diff --git a/text/jp/dialogs.h b/text/jp/dialogs.h index 4a5821c..a190ab5 100644 --- a/text/jp/dialogs.h +++ b/text/jp/dialogs.h @@ -1,676 +1,676 @@ // Parameters: dialog enum ID, (unused), lines per box, left offset, width DEFINE_DIALOG(DIALOG_000, 1, 5, 30, 200, _("\ -おおっと,ここはキケンな\n\ -せんじょうの どまんなか。\n\ +おおっと、ここはキケンな\n\ +せんじょうの どまんなか。\n\ 『え』のなかのせかいには\n\ -クッパが ぬすんだ\n\ -パワ-スタ-がある。\n\ -まずは,あかいボムへいに\n\ -はなしかけてみるといい!\n\ -Bボタンではなしができる。\n\ -きっと,ちからになって\n\ +クッパが ぬすんだ\n\ +パワースターがある。\n\ +まずは、あかいボムへいに\n\ +はなしかけてみるといい!\n\ +Bボタンではなしができる。\n\ +きっと、ちからになって\n\ くれるはずだ。\n\ -カンバンを よむときも\n\ -たちどまって Bボタン!\n\ -AかBボタンですすめる!\n\ -まえにたつだけで はなし\n\ -かける,どうぶつもいます。")) +カンバンを よむときも\n\ +たちどまって Bボタン!\n\ +AかBボタンですすめる!\n\ +まえにたつだけで はなし\n\ +かける、どうぶつもいます。")) DEFINE_DIALOG(DIALOG_001, 1, 4, 95, 200, _("\ -あぶない あぶない!!\n\ -こんなところを うろうろ\n\ -してると,みずばくだんが\n\ +あぶない あぶない!!\n\ +こんなところを うろうろ\n\ +してると、みずばくだんが\n\ ふってきますよ。\n\ くろいボムへいたちは\n\ -たたかいが だいすきで,\n\ -いつも ぼくらを\n\ +たたかいが だいすきで、\n\ +いつも ぼくらを\n\ こうげきしてきます。\n\ -ボムキングという ボスが\n\ -スタ-を てにいれてから\n\ -ここは せんじょうに\n\ +ボムキングという ボスが\n\ +スターを てにいれてから\n\ +ここは せんじょうに\n\ なってしまいました。\n\ -ボムキングから スタ-を\n\ -とりあげてくれませんか?\n\ -このさきの はしをわたり\n\ -みちぞいにひだりにいけば,\n\ -ボムとりでの いりぐちに\n\ -つきます。キングのスタ-\n\ -を とりもどしたら また\n\ -あいに きてください。")) +ボムキングから スターを\n\ +とりあげてくれませんか?\n\ +このさきの はしをわたり\n\ +みちぞいにひだりにいけば、\n\ +ボムとりでの いりぐちに\n\ +つきます。キングのスター\n\ +を とりもどしたら また\n\ +あいに きてください。")) DEFINE_DIALOG(DIALOG_002, 1, 4, 95, 200, _("\ -ちょっと あなた!\n\ -このさきはキケンですよ!\n\ +ちょっと あなた!\n\ +このさきはキケンですよ!\n\ \n\ -そこで,アドバイスです。\n\ -そらから ふってくる\n\ -みずばくだんをよけて,\n\ -はしを『2つ』わたると\n\ +そこで、アドバイスです。\n\ +そらから ふってくる\n\ +みずばくだんをよけて、\n\ +はしを『2つ』わたると\n\ あちらの『じんち』です。\n\ やまのうえのボムキングは\n\ -すごく ちからもちです。\n\ +すごく ちからもちです。\n\ かつぎあげられないように\n\ きをつけてください。\n\ -ぼくら あかボムへいは\n\ +ぼくら あかボムへいは\n\ あなたのみかたです。\n\ -いつでも はなしかけて\n\ -きてくださいね!")) +いつでも はなしかけて\n\ +きてくださいね!")) DEFINE_DIALOG(DIALOG_003, 1, 5, 95, 200, _("\ -おかげで ボムキングは\n\ -おとなしくなりました!\n\ -でも,たたかいは おわり\n\ -ません。 かいぶつたちが\n\ -まだスタ-をもっています。\n\ -スタ-をいくつかとったら\n\ -あたらしい へやのドアを\n\ -ひらくことが できます。\n\ -つぎのへやの せかいへと\n\ -すすんでください!\n\ +おかげで ボムキングは\n\ +おとなしくなりました!\n\ +でも、たたかいは おわり\n\ +ません。 かいぶつたちが\n\ +まだスターをもっています。\n\ +スターをいくつかとったら\n\ +あたらしい へやのドアを\n\ +ひらくことが できます。\n\ +つぎのへやの せかいへと\n\ +すすんでください!\n\ ぼくらのなかまが\n\ おまちしています。\n\ -はなしかけて くださいね。\n\ -いつでも たいほうを\n\ +はなしかけて くださいね。\n\ +いつでも たいほうを\n\ じゅんびしますよ。")) DEFINE_DIALOG(DIALOG_004, 1, 3, 95, 200, _("\ -ぼくたちは へいわを\n\ -ねがっています。 だから\n\ -たいほうは つかいません。\n\ -けれど あなたをどこかに\n\ -とばすなら へいきです。\n\ -どうぞ つかってください。\n\ -このコ-スにあるすべての\n\ -あかボムぐん たいほうを\n\ -つかえるように します。")) +ぼくたちは へいわを\n\ +ねがっています。 だから\n\ +たいほうは つかいません。\n\ +けれど あなたをどこかに\n\ +とばすなら へいきです。\n\ +どうぞ つかってください。\n\ +このコースにあるすべての\n\ +あかボムぐん たいほうを\n\ +つかえるように します。")) DEFINE_DIALOG(DIALOG_005, 1, 4, 30, 200, _("\ -な-んだ,マリオさんじゃ\n\ -ないッスか!\n\ +なーんだ、マリオさんじゃ\n\ +ないッスか!\n\ ボムキングやっつけたって\n\ -ほんと-ッスか?\n\ -いや- すごいッス!\n\ -さっすが つよいし,\n\ -オイラほどではないけど,\n\ -あしも はやいッスよね!\n\ -ひとつオイラと,\n\ +ほんとーッスか?\n\ +いやー すごいッス!\n\ +さっすが つよいし、\n\ +オイラほどではないけど、\n\ +あしも はやいッスよね!\n\ +ひとつオイラと、\n\ ボムキングのヤツがいた\n\ おやまのちょうじょうまで\n\ -かけっこでもしませんか?\n\ -それでは オイラが,\n\ -『ドン!』といったら\n\ -スタ-ト ッスよ。\n\ +かけっこでもしませんか?\n\ +それでは オイラが、\n\ +『ドン!』といったら\n\ +スタート ッスよ。\n\ \n\ - ヨ---イ!\n\ + ヨーーーイ!\n\ \n\ - ドン! やめる")) +   ドン!  やめる")) DEFINE_DIALOG(DIALOG_006, 1, 4, 30, 200, _("\ -ははっ ズルッコは\n\ -なしッス! マリオさん。\n\ +ははっ ズルッコは\n\ +なしッス! マリオさん。\n\ またこんど\n\ あそびましょうね。")) DEFINE_DIALOG(DIALOG_007, 1, 6, 30, 200, _("\ -ハア ハア ハア\n\ -いや-まいったッス!\n\ -ほんと はえ-ッスね!\n\ -オイラに かったきねんに,\n\ -これ,あげるッス。\n\ -ホイ!")) +ハア ハア ハア\n\ +いやーまいったッス!\n\ +ほんと はえーッスね!\n\ +オイラに かったきねんに、\n\ +これ、あげるッス。\n\ +ホイ!")) DEFINE_DIALOG(DIALOG_008, 1, 5, 30, 200, _("\ -もうけんワンワン キケン\n\ -Cボタンの うえをおして\n\ +もうけんワンワン キケン\n\ +Cボタンの うえをおして\n\ 『マリオのちかく』から\n\ -ながめて ください。\n\ -とても コワイです。\n\ -クイのうえの あかコイン。\n\ -おなじコインを さがして\n\ -8まいあつめると,はしを\n\ +ながめて ください。\n\ +とても コワイです。\n\ +クイのうえの あかコイン。\n\ +おなじコインを さがして\n\ +8まいあつめると、はしを\n\ わたったひだりのはやしに\n\ -スタ-がでます。")) +スターがでます。")) DEFINE_DIALOG(DIALOG_009, 1, 5, 30, 200, _("\ -ひっさしぶりッス! いま\n\ -ちょ-どかえったとこッス。\n\ -パワ-スタ-のせいか\n\ -いちだんと はやくなった\n\ -ようッスね!\n\ -このまえは まけちゃって\n\ -ほ-んと くやしいッス。\n\ -ここは オイラのホ-ム\n\ -グランド!じしんあるッス。\n\ -もいちどやりましょうよ!\n\ -ゴ-ルはカゼふきのたに!\n\ -しってるッスよね!?\n\ +ひっさしぶりッス! いま\n\ +ちょーどかえったとこッス。\n\ +パワースターのせいか\n\ +いちだんと はやくなった\n\ +ようッスね!\n\ +このまえは まけちゃって\n\ +ほーんと くやしいッス。\n\ +ここは オイラのホーム\n\ +グランド!じしんあるッス。\n\ +もいちどやりましょうよ!\n\ +ゴールはカゼふきのたに!\n\ +しってるッスよね!?\n\ そんじゃ\n\ - ヨ---イ!\n\ - ドン! やめる")) + ヨーーーイ!\n\ +   ドン!  やめる")) DEFINE_DIALOG(DIALOG_010, 1, 3, 30, 200, _("\ -そらを じゆうにとべる\n\ +そらを じゆうにとべる\n\ 『はねのぼうし』の\n\ -スイッチを ふみました。\n\ +スイッチを ふみました。\n\ せかいじゅうにある\n\ -あかブロックから,はねの\n\ +あかブロックから、はねの\n\ ぼうしがとびだします。\n\ -ここまでをセ-ブする?\n\ +ここまでをセーブする?\n\ \n\ - はい いいえ")) +   はい   いいえ")) DEFINE_DIALOG(DIALOG_011, 1, 3, 30, 200, _("\ -むてきの からだになれる\n\ +むてきの からだになれる\n\ 『メタルのぼうし』の\n\ -スイッチを ふみました。\n\ -せかいじゅうの みどりの\n\ -ブロックから,メタルの\n\ -ぼうしが とびだします。\n\ -ここまでをセ-ブする?\n\ +スイッチを ふみました。\n\ +せかいじゅうの みどりの\n\ +ブロックから、メタルの\n\ +ぼうしが とびだします。\n\ +ここまでをセーブする?\n\ \n\ - はい いいえ")) +   はい   いいえ")) DEFINE_DIALOG(DIALOG_012, 1, 3, 30, 200, _("\ -すがたをけせる まほうの\n\ +すがたをけせる まほうの\n\ 『とうめいのぼうし』の\n\ -スイッチを ふみました。\n\ -せかいじゅうの あおい\n\ -ブロックから,とうめい\n\ -ぼうしが とびだします。\n\ -ここまでをセ-ブする?\n\ +スイッチを ふみました。\n\ +せかいじゅうの あおい\n\ +ブロックから、とうめい\n\ +ぼうしが とびだします。\n\ +ここまでをセーブする?\n\ \n\ - はい いいえ")) +   はい   いいえ")) DEFINE_DIALOG(DIALOG_013, 1, 5, 30, 200, _("\ -100まいコインの\n\ -スタ-を てにいれた!\n\ -おしろのパワ-が\n\ +100まいコインの\n\ +スターを てにいれた!\n\ +おしろのパワーが\n\ またひとつマリオに\n\ - ちからを あたえた。\n\ +  ちからを あたえた。\n\ \n\ -ここまでセ-ブしますか?\n\ +ここまでセーブしますか?\n\ \n\ - はい いいえ")) +   はい   いいえ")) DEFINE_DIALOG(DIALOG_014, 1, 5, 30, 200, _("\ おもわぬところで\n\ -スタ-をてにいれた。\n\ -そして おしろのパワ-が\n\ -またひとつ マリオに\n\ - ゆうきを あたえた。\n\ +スターをてにいれた。\n\ +そして おしろのパワーが\n\ +またひとつ マリオに\n\ +  ゆうきを あたえた。\n\ \n\ -ここまでセ-ブしますか?\n\ +ここまでセーブしますか?\n\ \n\ - はい いいえ")) +   はい   いいえ")) DEFINE_DIALOG(DIALOG_015, 1, 4, 30, 200, _("\ てきはパンチでたおせるよ。\n\ -Aボタンは『ジャンプ』\n\ -Bボタンは『パンチ』です。\n\ -AとBボタンで『キック』。\n\ +Aボタンは『ジャンプ』\n\ +Bボタンは『パンチ』です。\n\ +AとBボタンで『キック』。\n\ 『ものをもつ』ときも\n\ - Bボタン!\n\ -『なげる』は もういちど\n\ -Bボタンをおしてください。")) +       Bボタン!\n\ +『なげる』は もういちど\n\ +Bボタンをおしてください。")) DEFINE_DIALOG(DIALOG_016, 1, 4, 30, 200, _("\ キラキラひかったコウラに\n\ -のると,どんなところも\n\ -スイスイすすめる!\n\ -てきをけちらし すすめ!")) +のると、どんなところも\n\ +スイスイすすめる!\n\ +てきをけちらし すすめ!")) DEFINE_DIALOG(DIALOG_017, 1, 4, 30, 200, _("\ -ワシがボムキング,つまり\n\ -ばくだんの おうさまだ。\n\ +ワシがボムキング、つまり\n\ +ばくだんの おうさまだ。\n\ よくここまできた。その\n\ -ゆうきは ほめてやろう。\n\ -とはいえ,おまえにタダで\n\ -だいじな パワ-スタ-を\n\ -やるわけには いかん。\n\ -そこで チャンスをやろう。\n\ -パワ-スタ-がほしければ\n\ -ワシを なげとばしてみろ。\n\ -うしろから かつげるか?\n\ -さあ,かかってこい!")) +ゆうきは ほめてやろう。\n\ +とはいえ、おまえにタダで\n\ +だいじな パワースターを\n\ +やるわけには いかん。\n\ +そこで チャンスをやろう。\n\ +パワースターがほしければ\n\ +ワシを なげとばしてみろ。\n\ +うしろから かつげるか?\n\ +さあ、かかってこい!")) DEFINE_DIALOG(DIALOG_018, 1, 4, 30, 200, _("\ -ねむいので,ねています。\n\ -おこすと おこります。\n\ +ねむいので、ねています。\n\ +おこすと おこります。\n\ \n\ -しずかに あるきましょう。")) +しずかに あるきましょう。")) DEFINE_DIALOG(DIALOG_019, 1, 2, 30, 200, _("\ -ろうかは しずかに\n\ +ろうかは しずかに\n\ あるきましょう。")) DEFINE_DIALOG(DIALOG_020, 1, 5, 95, 150, _("\ -おしろへ あそびに\n\ +おしろへ あそびに\n\ きてください。\n\ -ケ-キを つくって\n\ +ケーキを つくって\n\ まってます。\n\ - -ピ-チより-")) +     -ピーチより-")) DEFINE_DIALOG(DIALOG_021, 1, 5, 95, 200, _("\ ようこそいらっしゃいませ\n\ -・・だれも いませんので\n\ +・・だれも いませんので\n\ とっとと\n\ - おかえりください。\n\ -ガハハハッ!")) +  おかえりください。\n\ +ガハハハッ!")) DEFINE_DIALOG(DIALOG_022, 1, 3, 95, 200, _("\ -カギが かかっている・・")) +カギが かかっている・・")) DEFINE_DIALOG(DIALOG_023, 1, 3, 95, 200, _("\ -・・・カギがあわない!\n\ +・・・カギがあわない!\n\ このカギは『ちか』への\n\ カギのようだ。")) DEFINE_DIALOG(DIALOG_024, 1, 3, 95, 200, _("\ クッパがとじたこのドアを\n\ -ひらくには,スタ-の\n\ -パワ-が ひつようです。\n\ +ひらくには、スターの\n\ +パワーが ひつようです。\n\ どこかのへやの『え』の\n\ -なかの モンスタ-から\n\ +なかの モンスターから\n\ とりもどしてきてください")) DEFINE_DIALOG(DIALOG_025, 1, 3, 95, 200, _("\ -このドアを ひらくには\n\ -スタ-3まいの パワ-が\n\ +このドアを ひらくには\n\ +スター3まいの パワーが\n\ ひつようです。\n\ -あと[%]まいの スタ-が\n\ +あと[%]まいの スターが\n\ ひつようです。")) DEFINE_DIALOG(DIALOG_026, 1, 3, 95, 200, _("\ -このドアを ひらくには\n\ -スタ-8まいの パワ-が\n\ +このドアを ひらくには\n\ +スター8まいの パワーが\n\ ひつようです。\n\ -あと[%]まいの スタ-が\n\ +あと[%]まいの スターが\n\ ひつようです。")) DEFINE_DIALOG(DIALOG_027, 1, 3, 95, 200, _("\ -このドアを ひらくには\n\ -スタ-30まいのパワ-が\n\ +このドアを ひらくには\n\ +スター30まいのパワーが\n\ ひつようです。\n\ -スタ-があと\n\ +スターがあと\n\ [%]まいひつようです。")) DEFINE_DIALOG(DIALOG_028, 1, 3, 95, 200, _("\ -このドアを ひらくには\n\ -スタ-50まいのパワ-が\n\ +このドアを ひらくには\n\ +スター50まいのパワーが\n\ ひつようです。\n\ -あと[%]まいの スタ-が\n\ +あと[%]まいの スターが\n\ ひつようです。")) DEFINE_DIALOG(DIALOG_029, 1, 4, 95, 200, _("\ -はてしない かいだんの\n\ -ドアを ひらくには\n\ -スタ-70まいのパワ-が\n\ +はてしない かいだんの\n\ +ドアを ひらくには\n\ +スター70まいのパワーが\n\ ひつようです・・・・・\n\ -あと[%]まいの スタ-が\n\ +あと[%]まいの スターが\n\ たりません・・・\n\ -ガハハッ!")) +ガハハッ!")) DEFINE_DIALOG(DIALOG_030, 1, 4, 30, 200, _("\ カメラマンのジュゲムです。\n\ -ちょっと アドバイス!\n\ +ちょっと アドバイス!\n\ しずかにあるきたいときは\n\ -ゆっくり あるくことです。\n\ -まわりを みたいときは\n\ -Cボタンのみぎとひだりで\n\ +ゆっくり あるくことです。\n\ +まわりを みたいときは\n\ +Cボタンのみぎとひだりで\n\ カメラをすこしまわせます。\n\ -Cのしたで とおくから。\n\ +Cのしたで とおくから。\n\ できないところでは\n\ -『ブ-ッ!』といいます。\n\ -よろしく!! \n\ - -ジュゲム")) +『ブーッ!』といいます。\n\ +よろしく!! \n\ +      -ジュゲム")) DEFINE_DIALOG(DIALOG_031, 1, 3, 30, 200, _("\ -またまた まけちゃったよ。\n\ -こんどはスッゴい じしん\n\ +またまた まけちゃったよ。\n\ +こんどはスッゴい じしん\n\ あったんッスけどね・・・\n\ -ほんと すごいッスね!\n\ -このスタ-も\n\ -あげちゃいます!")) +ほんと すごいッスね!\n\ +このスターも\n\ +あげちゃいます!")) DEFINE_DIALOG(DIALOG_032, 1, 4, 30, 200, _("\ -はねぼうしの あるひとは\n\ -3かいれんぞくでジャンプ\n\ -しよう。 おおぞらたかく\n\ +はねぼうしの あるひとは\n\ +3かいれんぞくでジャンプ\n\ +しよう。 おおぞらたかく\n\ とびあがれます。\n\ たいほうでとぶと\n\ -さらに たかくとべます。\n\ -まわりをみるのはCボタン。\n\ -おりたいときはZボタン。")) +さらに たかくとべます。\n\ +まわりをみるのはCボタン。\n\ +おりたいときはZボタン。")) DEFINE_DIALOG(DIALOG_033, 1, 4, 30, 200, _("\ -ワ-プどかんを\n\ -くぐりぬけ,\n\ -ピ-チの おしろに\n\ +ワープどかんを\n\ +くぐりぬけ、\n\ +ピーチの おしろに\n\ つきました。\n\ -そうさは カンタン。\n\ -Aボタンが ジャンプ!\n\ -Bボタンで こうげき!\n\ -カンバンも よめます。\n\ -マリオを うごかすのは\n\ -まんなかに ついてる\n\ -『3Dスティック』。\n\ -まずはおしろへ すすめ!")) +そうさは カンタン。\n\ +Aボタンが ジャンプ!\n\ +Bボタンで こうげき!\n\ +カンバンも よめます。\n\ +マリオを うごかすのは\n\ +まんなかに ついてる\n\ +『3Dスティック』。\n\ +まずはおしろへ すすめ!")) DEFINE_DIALOG(DIALOG_034, 1, 5, 30, 200, _("\ -こんにちは! \n\ +こんにちは! \n\ ぼくたちカメラマンの\n\ -ジュゲムブラザ-ズです。\n\ -これから,カメラをもって\n\ -あなたに ついていきます。\n\ -カメラは おすすめのいち\n\ -から さつえいしてます。\n\ -むきをかえるのはCボタン,\n\ -かえられない ときは\n\ -『ブ-ッ!』といいます。\n\ -ちょっと たちどまったら\n\ -Cボタンのうえ!\n\ -まわりを ながめられます。\n\ -ゲ-ムに もどすときは\n\ -『Aボタン』です。\n\ -『Rボタン』をつかうと\n\ -いろんなカメラモ-ドに\n\ +ジュゲムブラザーズです。\n\ +これから、カメラをもって\n\ +あなたに ついていきます。\n\ +カメラは おすすめのいち\n\ +から さつえいしてます。\n\ +むきをかえるのはCボタン、\n\ +かえられない ときは\n\ +『ブーッ!』といいます。\n\ +ちょっと たちどまったら\n\ +Cボタンのうえ!\n\ +まわりを ながめられます。\n\ +ゲームに もどすときは\n\ +『Aボタン』です。\n\ +『Rボタン』をつかうと\n\ +いろんなカメラモードに\n\ きりかえられます。\n\ -また,かんばんなどをみて\n\ -おぼえてください!\n\ -いじょう!! カメラマン\n\ -ジュゲムブラザ-ズからの\n\ +また、かんばんなどをみて\n\ +おぼえてください!\n\ +いじょう!! カメラマン\n\ +ジュゲムブラザーズからの\n\ おしらせでした。\n\ -それじゃ,きをつけて!")) +それじゃ、きをつけて!")) DEFINE_DIALOG(DIALOG_035, 1, 4, 30, 200, _("\ -きいろい4つの Cボタン。\n\ +きいろい4つの Cボタン。\n\ 『うえ』をおすと\n\ -3Dスティックで\n\ -まわりを みわたせます。\n\ +3Dスティックで\n\ +まわりを みわたせます。\n\ ふだんマリオをみてるのは\n\ おすすめのジュゲムカメラ。\n\ -Cボタンで すこし,\n\ -かくどが かえられます。\n\ -Rボタンをおすと\n\ -マリオの うしろからみる\n\ -マリオカメラに なります。\n\ +Cボタンで すこし、\n\ +かくどが かえられます。\n\ +Rボタンをおすと\n\ +マリオの うしろからみる\n\ +マリオカメラに なります。\n\ もどすときはもういちどR。\n\ 『ジュゲムカメラ』と\n\ 『マリオカメラ』どちらも\n\ -Cボタンの したをおすと,\n\ -とおくへ はなれます。\n\ +Cボタンの したをおすと、\n\ +とおくへ はなれます。\n\ いまつかっている\n\ -カメラを しりたいときは,\n\ -がめん みぎしたの\n\ -アイコンを みてください。")) +カメラを しりたいときは、\n\ +がめん みぎしたの\n\ +アイコンを みてください。")) DEFINE_DIALOG(DIALOG_036, 1, 5, 30, 200, _("\ - 『てんぼうだい』\n\ -Cボタンの うえをおすと,\n\ -まわりを みわたせます。\n\ -みえないところは よ-く\n\ -たしかめてからすすめ-!\n\ -Rボタンはマリオのカメラ。\n\ -いつも マリオのうしろを\n\ + 『てんぼうだい』\n\ +Cボタンの うえをおすと、\n\ +まわりを みわたせます。\n\ +みえないところは よーく\n\ +たしかめてからすすめー!\n\ +Rボタンはマリオのカメラ。\n\ +いつも マリオのうしろを\n\ ついていくぞ。ジュゲムに\n\ -もどすときは もういちど\n\ -Rボタンをおすこと。\n\ -ポ-ズがめんで モ-ドを\n\ -かえると,Rボタンを\n\ -おしてるあいだ カメラを\n\ -『とめる』こともできる!\n\ +もどすときは もういちど\n\ +Rボタンをおすこと。\n\ +ポーズがめんで モードを\n\ +かえると、Rボタンを\n\ +おしてるあいだ カメラを\n\ +『とめる』こともできる!\n\ ためしてみよう。\n\ -つかってるカメラモ-ドは\n\ +つかってるカメラモードは\n\ みぎしたのアイコンで\n\ たしかめよう。\n\ -マリオとの きょりは\n\ -きいろやじるしを みよう。")) +マリオとの きょりは\n\ +きいろやじるしを みよう。")) DEFINE_DIALOG(DIALOG_037, 1, 3, 30, 200, _("\ あたしの『かち』です。\n\ あなたの『まけ』です。\n\ -ははははは!!!\n\ -マリオさん,と-っても\n\ +ははははは!!!\n\ +マリオさん、とーっても\n\ おしかったですね。\n\ -また あそびましょう!")) +また あそびましょう!")) DEFINE_DIALOG(DIALOG_038, 1, 3, 95, 200, _("\ -パワ-スタ-の ちからで\n\ -つぎの せかいへのドアは\n\ +パワースターの ちからで\n\ +つぎの せかいへのドアは\n\ しずかにひらいた。")) DEFINE_DIALOG(DIALOG_039, 1, 5, 30, 200, _("\ --ボムとりで いりぐち-\n\ - だれも はいるな!\n\ +-ボムとりで いりぐち-\n\ +  だれも はいるな!\n\ \n\ -ワシのパワ-スタ-は\n\ -だれにも わたさぬ。\n\ +ワシのパワースターは\n\ +だれにも わたさぬ。\n\ クッパどのからいただいた\n\ -だいじな だいじな\n\ +だいじな だいじな\n\ たからものだ。\n\ -なんまいか かくしたが\n\ -ばしょは おしえぬ。\n\ -コ-スはじめの スタ-の\n\ -なまえを,ヒントにする\n\ -ぐらいなら ゆるす。\n\ +なんまいか かくしたが\n\ +ばしょは おしえぬ。\n\ +コースはじめの スターの\n\ +なまえを、ヒントにする\n\ +ぐらいなら ゆるす。\n\ \n\ おやまのうえのボムキング")) DEFINE_DIALOG(DIALOG_040, 1, 3, 30, 200, _("\ -このさき キケン!\n\ -リフトのたにぞこ です。")) +このさき キケン!\n\ +リフトのたにぞこ です。")) DEFINE_DIALOG(DIALOG_041, 1, 4, 30, 200, _("\ オイラがかっちゃいました。\n\ ハッハッハッ\n\ -たいしたことないッスね!\n\ -じゃ,またこんどね!")) +たいしたことないッスね!\n\ +じゃ、またこんどね!")) DEFINE_DIALOG(DIALOG_042, 1, 5, 30, 200, _("\ この『はし』せまい。\n\ -ゆっくりわたろう!\n\ +ゆっくりわたろう!\n\ ガケのカドにとびついたり\n\ -ゆっくりと おりると\n\ +ゆっくりと おりると\n\ ぶらさがれます。\n\ -『て』を はなすときは\n\ -Zボタンか スティックを\n\ +『て』を はなすときは\n\ +Zボタンか スティックを\n\ マリオのうしろへ。\n\ -のぼるときには まえへ\n\ +のぼるときには まえへ\n\ たおしてください。\n\ -ぶらさがって すぐに\n\ -Aボタンをおすと\n\ -すばやく あがれます。")) +ぶらさがって すぐに\n\ +Aボタンをおすと\n\ +すばやく あがれます。")) DEFINE_DIALOG(DIALOG_043, 1, 4, 30, 200, _("\ -ジャンプしてAボタンを\n\ -おしっぱなしに すると\n\ -ぶらさがれる ところが\n\ +ジャンプしてAボタンを\n\ +おしっぱなしに すると\n\ +ぶらさがれる ところが\n\ あります。\n\ 『とり』につかまるとき\n\ -と おなじです。")) +と おなじです。")) DEFINE_DIALOG(DIALOG_044, 1, 5, 95, 200, _("\ -だれだい! せっかく\n\ -いいきもちで ねてたのに。\n\ -あ- カラダがおもいな-\n\ -ちょ-どいいや!わたしと\n\ -ひと-っとび しません?\n\ +だれだい!  せっかく\n\ +いいきもちで ねてたのに。\n\ +あー カラダがおもいなー\n\ +ちょーどいいや!わたしと\n\ +ひとーっとび しません?\n\ ジャンプボタンを\n\ おしているあいだ\n\ -ぶらさがれますよ-。\n\ +ぶらさがれますよー。\n\ おりたいときに\n\ -はなせばい-です。\n\ -お-すきなところへ\n\ -おつれしま-す。\n\ -かげを よ-くみて\n\ -Aボタンで つかまって\n\ -くださいね-!")) +はなせばいーです。\n\ +おーすきなところへ\n\ +おつれしまーす。\n\ +かげを よーくみて\n\ +Aボタンで つかまって\n\ +くださいねー!")) DEFINE_DIALOG(DIALOG_045, 1, 5, 95, 200, _("\ -あ-あ,つかれた-・・\n\ -や-っぱり おもいな-。\n\ -きょうは このあたりで!\n\ -『もういちどAボタンを\n\ +あーあ、つかれたー・・\n\ +やーっぱり おもいなー。\n\ +きょうは このあたりで!\n\ +『もういちどAボタンを\n\ おしなおしてください。』\n\ -もうすこし とんだら\n\ -ほんとに てをはなしてね\n\ +もうすこし とんだら\n\ +ほんとに てをはなしてね\n\ \n\ -じゃあ,さよなら-!")) +じゃあ、さよならー!")) DEFINE_DIALOG(DIALOG_046, 1, 5, 30, 200, _("\ -ジャンプのワザ まとめて\n\ +ジャンプのワザ まとめて\n\ せいりしておきます。\n\ -とてもだいじな3つのワザ。\n\ -おぼえて つかって\n\ +とてもだいじな3つのワザ。\n\ +おぼえて つかって\n\ みてください。\n\ -タイミングよく つづけて\n\ -とぶと たかくとべます。\n\ -はやく はしっていると\n\ -さらに たかくとべます。\n\ -『3だんとび』です。\n\ -はしりながら Zボタンで\n\ +タイミングよく つづけて\n\ +とぶと たかくとべます。\n\ +はやく はしっていると\n\ +さらに たかくとべます。\n\ +『3だんとび』です。\n\ +はしりながら Zボタンで\n\ しゃがんでジャンプすると\n\ -とおくへ とべます。\n\ +とおくへ とべます。\n\ 『はばとび』です。\n\ とてもべんりです。\n\ -まっすぐたった カベに\n\ -むかって ジャンプして,\n\ -ぶつかった ところから\n\ -また ジャンプできます。\n\ +まっすぐたった カベに\n\ +むかって ジャンプして、\n\ +ぶつかった ところから\n\ +また ジャンプできます。\n\ 『カベキック』といいます。\n\ -だいじな テクニック\n\ -『3だんとび』\n\ +だいじな テクニック\n\ +『3だんとび』\n\ 『はばとび』\n\ 『カベキック』\n\ - わかった?")) +     わかった?")) DEFINE_DIALOG(DIALOG_047, 1, 3, 95, 200, _("\ -こんにちは!\n\ -たいほうの じゅんびに\n\ -かかります!・・・・・")) +こんにちは!\n\ +たいほうの じゅんびに\n\ +かかります!・・・・・")) DEFINE_DIALOG(DIALOG_048, 1, 4, 30, 200, _("\ -ここは ツルツルすべる\n\ -ゆきやまの ちょうじょう。\n\ +ここは ツルツルすべる\n\ +ゆきやまの ちょうじょう。\n\ まずはそこの\n\ -やまごやへ どうぞ。")) +やまごやへ どうぞ。")) DEFINE_DIALOG(DIALOG_049, 1, 5, 30, 200, _("\ ジャンプわざカベキックを\n\ -おぼえていますか?\n\ -たかいところへ あがる\n\ +おぼえていますか?\n\ +たかいところへ あがる\n\ とてもだいじなテクニック。\n\ -カベからカベへジャンプ!\n\ +カベからカベへジャンプ!\n\ スティックをつかって\n\ はねかえったほうに\n\ かそくする。\n\ -よ-く\n\ -れんしゅう しておこう!")) +よーく\n\ +れんしゅう しておこう!")) DEFINE_DIALOG(DIALOG_050, 1, 4, 30, 200, _("\ -Zボタンで しゃがめます。\n\ -『さか』では すべれます。\n\ -ジャンプの とちゅうなら\n\ -『ヒップドロップ』!!\n\ -とまって しゃがんでから\n\ +Zボタンで しゃがめます。\n\ +『さか』では すべれます。\n\ +ジャンプの とちゅうなら\n\ +『ヒップドロップ』!!\n\ +とまって しゃがんでから\n\ ジャンプすると\n\ -『バックちゅう』できる!\n\ -わかった? まだあります。\n\ -はしりながら しゃがんで\n\ -ジャンプで『はばとび』!\n\ -しゃがんでから あるくと\n\ +『バックちゅう』できる!\n\ +わかった? まだあります。\n\ +はしりながら しゃがんで\n\ +ジャンプで『はばとび』!\n\ +しゃがんでから あるくと\n\ ・・・ひみつです。")) DEFINE_DIALOG(DIALOG_051, 1, 5, 30, 200, _("\ 『き』や『ぼう』には\n\ -ジャンプで つかまれます。\n\ +ジャンプで つかまれます。\n\ 『のぼる』『おりる』は\n\ -スティックで,やめるのは\n\ -Zボタンで『て』をはなす。\n\ +スティックで、やめるのは\n\ +Zボタンで『て』をはなす。\n\ 『むきをかえる』ときは\n\ - 3Dスティックの\n\ - みぎ と ひだり。\n\ -Aボタンで『せなか』の\n\ + 3Dスティックの\n\ +   みぎ と ひだり。\n\ +Aボタンで『せなか』の\n\ ほうこうにジャンプします。\n\ -テッペンで もういちど\n\ -スティックを うえにいれ,\n\ +テッペンで もういちど\n\ +スティックを うえにいれ、\n\ 『さかだち』ができる。\n\ -むきをきめて せなかの\n\ -ほうこうに ジャンプだ!")) +むきをきめて せなかの\n\ +ほうこうに ジャンプだ!")) DEFINE_DIALOG(DIALOG_052, 1, 4, 30, 200, _("\ -Zボタンで しゃがめます。\n\ -とまって しゃがんでから\n\ -ジャンプすると,\n\ -『バックちゅう』できる!\n\ -すばやくユ-タ-ンを\n\ -しながら,ジャンプすると\n\ -『ちゅうがえり』!\n\ -どちらも たかくとべます。")) +Zボタンで しゃがめます。\n\ +とまって しゃがんでから\n\ +ジャンプすると、\n\ +『バックちゅう』できる!\n\ +すばやくユーターンを\n\ +しながら、ジャンプすると\n\ +『ちゅうがえり』!\n\ +どちらも たかくとべます。")) DEFINE_DIALOG(DIALOG_053, 1, 6, 30, 200, _("\ -コインリングや かくれた\n\ -シ-クレットポイントを\n\ -とおると あかいすうじが\n\ -でてきます。5こつづけて\n\ -とおると ひみつのスタ-\n\ -が あらわれます。")) +コインリングや かくれた\n\ +シークレットポイントを\n\ +とおると あかいすうじが\n\ +でてきます。5こつづけて\n\ +とおると ひみつのスター\n\ +が あらわれます。")) DEFINE_DIALOG(DIALOG_054, 1, 4, 30, 200, _("\ -スライダ-へようこそ!!\n\ -さかを すべりはじめたら\n\ -スティックまえで かそく,\n\ -うしろで げんそくできる。")) +スライダーへようこそ!!\n\ +さかを すべりはじめたら\n\ +スティックまえで かそく、\n\ +うしろで げんそくできる。")) DEFINE_DIALOG(DIALOG_055, 1, 5, 30, 200, _("\ -あたし,このスライダ-の\n\ -せかいチャンピオン!!!\n\ -からだ,デカイけど\n\ -とっても はやいよ!\n\ -あなたチャレンジします?\n\ -それでは!\n\ +あたし、このスライダーの\n\ +せかいチャンピオン!!!\n\ +からだ、デカイけど\n\ +とっても はやいよ!\n\ +あなたチャレンジします?\n\ +それでは!\n\ \n\ - レディ---・・・!\n\ - ・・・ \n\ - ゴ-!! やめとく")) + レディーーー・・・!\n\ +  ・・・ \n\ +   ゴー!! やめとく")) DEFINE_DIALOG(DIALOG_056, 1, 3, 30, 200, _("\ -ヒエ---ッ!!!\n\ -セカイきろくだよ!\n\ -スゴイよ!あなた!!\n\ -きんメダルの かわりに\n\ -コレ あげます!\n\ -いや--スゴイスゴイ!!")) +ヒエーーーッ!!!\n\ +セカイきろくだよ!\n\ +スゴイよ!あなた!!\n\ +きんメダルの かわりに\n\ +コレ あげます!\n\ +いやーースゴイスゴイ!!")) DEFINE_DIALOG(DIALOG_057, 1, 4, 30, 200, _("\ -どこかで うちのこどもを\n\ -みかけません でしたか?\n\ -・・・わたしんち こども\n\ -いっぱい いましてね・・\n\ -なんびき いたのかも\n\ +どこかで うちのこどもを\n\ +みかけません でしたか?\n\ +・・・わたしんち こども\n\ +いっぱい いましてね・・\n\ +なんびき いたのかも\n\ おぼえてなくて・・・・\n\ ほんとに・・\n\ -どこへ いったんでしょう。\n\ +どこへ いったんでしょう。\n\ だいてやると\n\ -とても いいこえで\n\ +とても いいこえで\n\ なくんですけどね・・・\n\ ヤレヤレ・・・・・")) DEFINE_DIALOG(DIALOG_058, 1, 5, 30, 200, _("\ -ああ--っ!!たしかに\n\ -うちの こどもです・・・\n\ -『こらっ! いつも\n\ -ちかくで あそびなさいと\n\ -いってるだろ!』\n\ -あなた とっても\n\ -いいひとです。 おれいに\n\ -これを さしあげます。\n\ -あったかくって とても\n\ -げんきに なりますよ。")) +ああーーっ!!たしかに\n\ +うちの こどもです・・・\n\ +『こらっ! いつも\n\ +ちかくで あそびなさいと\n\ +いってるだろ!』\n\ +あなた とっても\n\ +いいひとです。 おれいに\n\ +これを さしあげます。\n\ +あったかくって とても\n\ +げんきに なりますよ。")) DEFINE_DIALOG(DIALOG_059, 1, 5, 30, 200, _("\ -このこは うちのこじゃ-\n\ +このこは うちのこじゃー\n\ ないようだなあ・・・\n\ かわいそうに・・・\n\ おやはいったい\n\ @@ -679,432 +679,432 @@ DEFINE_DIALOG(DIALOG_059, 1, 5, 30, 200, _("\ DEFINE_DIALOG(DIALOG_060, 1, 4, 30, 200, _("\ -みずにはいるちゅうい-\n\ \n\ -もぐっていると しぬほど\n\ +もぐっていると しぬほど\n\ くるしくなってきます。\n\ -すいめんに あがるか\n\ +すいめんに あがるか\n\ アブクをみつけて\n\ さわってください。\n\ -ひといき つけます。\n\ -およぐときは Aボタン!\n\ -おしてるだけでも すすみ\n\ -タイミングよく おすと\n\ -スピ-ドがでます。\n\ +ひといき つけます。\n\ +およぐときは Aボタン!\n\ +おしてるだけでも すすみ\n\ +タイミングよく おすと\n\ +スピードがでます。\n\ もぐるときはスティックを\n\ -まえにたおして Aボタン。\n\ +まえにたおして Aボタン。\n\ うかぶときはスティックを\n\ -てまえにひいて Aボタン。\n\ -すいめんに いるときは\n\ +てまえにひいて Aボタン。\n\ +すいめんに いるときは\n\ ジャンプします。\n\ - 『じゅんびたいそう\n\ - わすれずに!!』")) + 『じゅんびたいそう\n\ +    わすれずに!!』")) DEFINE_DIALOG(DIALOG_061, 1, 6, 30, 200, _("\ -つめたいみず キケン!!\n\ -およいでは いけません!\n\ -この こおりのいけは\n\ +つめたいみず キケン!!\n\ +およいでは いけません!\n\ +この こおりのいけは\n\ とびあがるぐらい\n\ -つめたいです!\n\ - ペンギン")) +つめたいです!\n\ +        ペンギン")) DEFINE_DIALOG(DIALOG_062, 1, 5, 30, 200, _("\ -みどりの ブロックに\n\ +みどりの ブロックに\n\ かくされている\n\ -ふしぎな ふしぎな\n\ +ふしぎな ふしぎな\n\ 『メタルのぼうし』。\n\ \n\ ひをつけたってもえないし\n\ -てきのたまも はねかえす。\n\ -いきを とめても\n\ +てきのたまも はねかえす。\n\ +いきを とめても\n\ へいきです。\n\ こまったことにおよげない。")) DEFINE_DIALOG(DIALOG_063, 1, 4, 30, 200, _("\ あおいブロックには\n\ 『とうめいぼうし』。\n\ -メダマも ビックリ\n\ +メダマも ビックリ\n\ すがたをけせる。\n\ -テレサも まっさお\n\ +テレサも まっさお\n\ 『ひみつのカベ』を\n\ とおりぬけるぞ。")) DEFINE_DIALOG(DIALOG_064, 1, 4, 30, 200, _("\ あかいブロックのなかの\n\ -はねのぼうしを かぶると,\n\ -3かいジャンプで\n\ -そらたかく とびあがれる。\n\ -そうさはスティックで!\n\ -てまえにひくと あがる。\n\ -まえにたおすと さがる。\n\ -やめるときはZボタンで!")) +はねのぼうしを かぶると、\n\ +3かいジャンプで\n\ +そらたかく とびあがれる。\n\ +そうさはスティックで!\n\ +てまえにひくと あがる。\n\ +まえにたおすと さがる。\n\ +やめるときはZボタンで!")) DEFINE_DIALOG(DIALOG_065, 1, 5, 30, 200, _("\ -およぎかた おしえます。\n\ +およぎかた おしえます。\n\ \n\ みずにはいるとおよげます。\n\ ながいあいだ『もぐる』と\n\ くるしくなります。\n\ -すすむためには Aボタン。\n\ -タイミングよく おすと\n\ -スピ-ドが でます。\n\ -3Dスティックを まえに\n\ -たおすと もぐります。\n\ -すいめんに もどったり,\n\ -みずから あがるときは\n\ -てまえにひいて Aボタン。\n\ -すいめんでジャンプだ!\n\ +すすむためには Aボタン。\n\ +タイミングよく おすと\n\ +スピードが でます。\n\ +3Dスティックを まえに\n\ +たおすと もぐります。\n\ +すいめんに もどったり、\n\ +みずから あがるときは\n\ +てまえにひいて Aボタン。\n\ +すいめんでジャンプだ!\n\ \n\ -Aボタン おしっぱなしに\n\ -していても,およげます。\n\ +Aボタン おしっぱなしに\n\ +していても、およげます。\n\ らくちんです。\n\ およいでいるあいだは\n\ -ドアを あけられません。")) +ドアを あけられません。")) DEFINE_DIALOG(DIALOG_066, 1, 5, 30, 200, _("\ -マリオ! クッパのはく\n\ -ほのおに きをつけて!\n\ -クッパを こらしめるには\n\ -うしろにまわりBボタンで\n\ -シッポをつかむのよ!\n\ -なげとばす まえには\n\ -3Dスティックで\n\ +マリオ!  クッパのはく\n\ +ほのおに きをつけて!\n\ +クッパを こらしめるには\n\ +うしろにまわりBボタンで\n\ +シッポをつかむのよ!\n\ +なげとばす まえには\n\ +3Dスティックで\n\ グリグリふりまわすの。\n\ -はやく まわすほど\n\ -とおくまで とぶわ!\n\ -Cボタンで まわりを\n\ -よ-くみて!\n\ -なげとばした クッパは\n\ -4すみの バクダンに\n\ -ぶつけてやるの!\n\ +はやく まわすほど\n\ +とおくまで とぶわ!\n\ +Cボタンで まわりを\n\ +よーくみて!\n\ +なげとばした クッパは\n\ +4すみの バクダンに\n\ +ぶつけてやるの!\n\ ねらいを\n\ -よ-くさだめて・・・\n\ +よーくさだめて・・・\n\ \n\ -もういちどBボタンよ!")) +もういちどBボタンよ!")) DEFINE_DIALOG(DIALOG_067, 1, 4, 30, 200, _("\ -ざんねんだったなマリオ!\n\ -ここには ピ-チちゃんは\n\ +ざんねんだったなマリオ!\n\ +ここには ピーチちゃんは\n\ いませんでした。\n\ - ガハハッ!!\n\ -わがはいの うしろに\n\ -まわりこんで シッポを\n\ +    ガハハッ!!\n\ +わがはいの うしろに\n\ +まわりこんで シッポを\n\ つかめるものなら\n\ つかんでみるんだな。\n\ スティックでグリグリ\n\ -まわして なげるなど\n\ -できるわけが ない!!\n\ - ガハハッ!!")) +まわして なげるなど\n\ +できるわけが ない!!\n\ +  ガハハッ!!")) DEFINE_DIALOG(DIALOG_068, 1, 5, 30, 200, _("\ -ここは しゃくねつの\n\ -ファイアバブル ランド!\n\ -からだに ひがついても\n\ -おちないように あわてず\n\ +ここは しゃくねつの\n\ +ファイアバブル ランド!\n\ +からだに ひがついても\n\ +おちないように あわてず\n\ そうさしよう。\n\ -ほのおのいけに おちると\n\ -はねあがる! そうさは\n\ -できるので,おちついて。\n\ +ほのおのいけに おちると\n\ +はねあがる!  そうさは\n\ +できるので、おちついて。\n\ あまりうごきまわらないで\n\ -ガンバレ!")) +ガンバレ!")) DEFINE_DIALOG(DIALOG_069, 1, 3, 30, 200, _("\ 『え』のなかのカイブツの\n\ -せかいには,せかいの\n\ +せかいには、せかいの\n\ はてがあります。\n\ みえないカベにあたったら\n\ -きっと そこが\n\ +きっと そこが\n\ 『え』のせかいのはてです。\n\ -そらを とんでいるときも\n\ -そこから さきには\n\ +そらを とんでいるときも\n\ +そこから さきには\n\ すすめません。")) DEFINE_DIALOG(DIALOG_070, 1, 5, 30, 200, _("\ -かいぶつたちの すんでる\n\ -『え』のなかのせかいから,\n\ -おしろの いりぐちの\n\ -メインホ-ルに\n\ -いつでも もどれます。\n\ -かならず きちんと\n\ -たちどまってから!\n\ -スタ-トボタンでポ-ズし,\n\ -『コ-スからでる』を\n\ +かいぶつたちの すんでる\n\ +『え』のなかのせかいから、\n\ +おしろの いりぐちの\n\ +メインホールに\n\ +いつでも もどれます。\n\ +かならず きちんと\n\ +たちどまってから!\n\ +スタートボタンでポーズし、\n\ +『コースからでる』を\n\ えらんでください。\n\ -ひとつのせかいのスタ-は\n\ -ぜんぶ とらなくても,\n\ +ひとつのせかいのスターは\n\ +ぜんぶ とらなくても、\n\ つぎのせかいにすすめます。\n\ -じょうずになったら,また\n\ +じょうずになったら、また\n\ もどってきてください。\n\ -スタ-を1つ とるごとに\n\ -つぎのスタ-のヒントが\n\ -スタ-トがめんに でます。\n\ +スターを1つ とるごとに\n\ +つぎのスターのヒントが\n\ +スタートがめんに でます。\n\ えらんだヒントいがいの\n\ -スタ-をとってもOKです。")) +スターをとってもOKです。")) DEFINE_DIALOG(DIALOG_071, 1, 4, 30, 200, _("\ - -このさきキケン-\n\ - あやしいケムリに\n\ - ちゅうい!\n\ - いきができません!\n\ + -このさきキケン-\n\ +  あやしいケムリに\n\ +  ちゅうい!\n\ + いきができません!\n\ くるしくなったら\n\ -たかいところへ!\n\ +たかいところへ!\n\ まる・・・・・ひなんじょ\n\ やじるし・・・でいりぐち")) DEFINE_DIALOG(DIALOG_072, 1, 5, 30, 200, _("\ -カゼつよし! ぼうしは\n\ -しっかり かぶりましょう。\n\ -もし ぼうしをなくしても\n\ -ここでなくした ぼうしは\n\ -このやまで みつかります。")) +カゼつよし!  ぼうしは\n\ +しっかり かぶりましょう。\n\ +もし ぼうしをなくしても\n\ +ここでなくした ぼうしは\n\ +このやまで みつかります。")) DEFINE_DIALOG(DIALOG_073, 1, 5, 95, 200, _("\ -ただしい じゅんばんで\n\ -はこを ひらくこと。\n\ -こたえは だれにも\n\ +ただしい じゅんばんで\n\ +はこを ひらくこと。\n\ +こたえは だれにも\n\ おしえてやらない。\n\ - --せんちょう--")) +   --せんちょう--")) DEFINE_DIALOG(DIALOG_074, 1, 5, 30, 200, _("\ -ガケのカドに とびつくと\n\ +ガケのカドに とびつくと\n\ ぶらさがれます。\n\ おりるときはスティックを\n\ -マリオのうしろへいれるか,\n\ -Zボタンをおしてください。\n\ +マリオのうしろへいれるか、\n\ +Zボタンをおしてください。\n\ のぼるときはスティックを\n\ -まえに たおしてください。\n\ +まえに たおしてください。\n\ ぶらさがって\n\ -すぐに Aボタンをおすと\n\ -すばやく のぼれます!")) +すぐに Aボタンをおすと\n\ +すばやく のぼれます!")) DEFINE_DIALOG(DIALOG_075, 1, 5, 30, 200, _("\ -マリオ!!たいへんです。\n\ +マリオ!!たいへんです。\n\ クッパがまた・・・・\n\ -おしろの パワ-スタ-を\n\ -ぬすんで カベのなかへ!\n\ +おしろの パワースターを\n\ +ぬすんで カベのなかへ!\n\ わたしたちも・・・\n\ みんなカベのなかへ・・・\n\ すいこまれていくわ・・・\n\ 『カベ』や『え』のなか\n\ -から パワ-スタ-を\n\ -とりもどして!\n\ -クッパの ふさいだドアは\n\ -パワ-スタ-の ちからで\n\ -ひらくことが できるわ!\n\ -このへやには ひみつの\n\ +から パワースターを\n\ +とりもどして!\n\ +クッパの ふさいだドアは\n\ +パワースターの ちからで\n\ +ひらくことが できるわ!\n\ +このへやには ひみつの\n\ つうろがあるの。\n\ クッパにみつからなかった\n\ -かくしつうろの ひとつよ。\n\ -そこには おしろの\n\ -かくれスタ-が あるわ!\n\ -きっと やくにたつはずよ。")) +かくしつうろの ひとつよ。\n\ +そこには おしろの\n\ +かくれスターが あるわ!\n\ +きっと やくにたつはずよ。")) DEFINE_DIALOG(DIALOG_076, 1, 5, 30, 200, _("\ -パワ-スタ-のおかげで\n\ -おしろに,げんきが\n\ +パワースターのおかげで\n\ +おしろに、げんきが\n\ もどってきました。\n\ クッパなんか\n\ おいはらってください。\n\ -おやくに たつなら\n\ -おしろの はなしをします。\n\ +おやくに たつなら\n\ +おしろの はなしをします。\n\ 『カガミのへや』では\n\ カガミにうつらないものを\n\ よくみてください。\n\ -みずのまちへ いくときは,\n\ -『え』にとびこむ たかさ\n\ -によって,まちをすっかり\n\ -みずびたしに できます。\n\ -アッ,これ みつけました。")) +みずのまちへ いくときは、\n\ +『え』にとびこむ たかさ\n\ +によって、まちをすっかり\n\ +みずびたしに できます。\n\ +アッ、これ みつけました。")) DEFINE_DIALOG(DIALOG_077, 1, 3, 150, 200, _("\ -とびらを ひらくまえに\n\ -2つの はしらを\n\ -おしさげて おくこと。")) +とびらを ひらくまえに\n\ +2つの はしらを\n\ +おしさげて おくこと。")) DEFINE_DIALOG(DIALOG_078, 1, 5, 30, 200, _("\ あおコインのブロックを\n\ -ジャンプちゅうにZボタン\n\ +ジャンプちゅうにZボタン\n\ 『ヒップドロップ』で\n\ - ぶっつぶすと\n\ +      ぶっつぶすと\n\ あおコインがでてきます。\n\ -あおコイン1まいで\n\ -きいろコイン5まいぶん\n\ -とてもラッキ-!\n\ -でも じかんがたつと\n\ +あおコイン1まいで\n\ +きいろコイン5まいぶん\n\ +とてもラッキー!\n\ +でも じかんがたつと\n\ きえてしまう・・ザンネン")) DEFINE_DIALOG(DIALOG_079, 1, 5, 30, 200, _("\ -いててて!\n\ +いててて!\n\ はなしてくれよ。\n\ -ウッキッキ-!\n\ +ウッキッキー!\n\ チョットからかった\n\ -だけなのに!\n\ -はなしてくれたら,\n\ -いいもの あげるからさ。\n\ -ネ-ネ- はなしてくれよ。\n\ +だけなのに!\n\ +はなしてくれたら、\n\ +いいもの あげるからさ。\n\ +ネーネー はなしてくれよ。\n\ \n\ - はなす いやだ")) +   はなす  いやだ")) DEFINE_DIALOG(DIALOG_080, 1, 3, 30, 200, _("\ -ヘッヘッヘッ!")) +ヘッヘッヘッ!")) DEFINE_DIALOG(DIALOG_081, 1, 6, 30, 200, _("\ -ここは みずにみちたまち。\n\ -このまちは,あなたが\n\ -ここを おとずれるときの\n\ -たかさと,おなじだけの\n\ +ここは みずにみちたまち。\n\ +このまちは、あなたが\n\ +ここを おとずれるときの\n\ +たかさと、おなじだけの\n\ みずをもって\n\ あなたをむかえる。")) DEFINE_DIALOG(DIALOG_082, 1, 5, 30, 200, _("\ -ぼうしを なくすと\n\ -ダメ-ジがおおくなるので\n\ -だいじに してください。\n\ -なくしたら,なくした\n\ -コ-スで みつかります。\n\ -アア-どうしよう・・・\n\ -ピ-チひめは,カベに\n\ -ひきこまれた ままだし。\n\ -はやく クッパを\n\ +ぼうしを なくすと\n\ +ダメージがおおくなるので\n\ +だいじに してください。\n\ +なくしたら、なくした\n\ +コースで みつかります。\n\ +アアーどうしよう・・・\n\ +ピーチひめは、カベに\n\ +ひきこまれた ままだし。\n\ +はやく クッパを\n\ やっつけてください。\n\ えのほかにカベのなかにも\n\ -モンスタ-の せかいが\n\ -あります。 あっ!これ\n\ -もっていって ください。\n\ -かくして もってました。")) +モンスターの せかいが\n\ +あります。  あっ!これ\n\ +もっていって ください。\n\ +かくして もってました。")) DEFINE_DIALOG(DIALOG_083, 1, 4, 30, 200, _("\ -とけいがとても へんです。\n\ -とけいに はいるとき,\n\ -ながいはりの ばしょに\n\ -ちゅういしてください!\n\ -これ,とりもどしました。\n\ -もっていって ください。\n\ +とけいがとても へんです。\n\ +とけいに はいるとき、\n\ +ながいはりの ばしょに\n\ +ちゅういしてください!\n\ +これ、とりもどしました。\n\ +もっていって ください。\n\ かっこよく\n\ -うけとってくださいね!")) +うけとってくださいね!")) DEFINE_DIALOG(DIALOG_084, 1, 5, 30, 200, _("\ -イテテ らんぼうなひとだ。\n\ -このスタ-は クッパって\n\ -ヤツが くれたんだよ。\n\ -あんたのものだ なんて\n\ +イテテ らんぼうなひとだ。\n\ +このスターは クッパって\n\ +ヤツが くれたんだよ。\n\ +あんたのものだ なんて\n\ しらなかったよ。\n\ -かえすって,かえすってば,\n\ -かえせば いいんでしょ。\n\ +かえすって、かえすってば、\n\ +かえせば いいんでしょ。\n\ はなしてくれたら\n\ -スタ-ぐらい かえすから。\n\ -ホイ!!")) +スターぐらい かえすから。\n\ +ホイ!!")) DEFINE_DIALOG(DIALOG_085, 1, 4, 30, 200, _("\ -この やかたから\n\ - ぶじにでられたら\n\ +この やかたから\n\ +  ぶじにでられたら\n\ \n\ ・・・エライ。・・")) DEFINE_DIALOG(DIALOG_086, 1, 3, 30, 200, _("\ まわりをクルクルまわると\n\ -めをまわす ヤツがいます。")) +めをまわす ヤツがいます。")) DEFINE_DIALOG(DIALOG_087, 1, 5, 30, 200, _("\ -えんとつから はいるのは\n\ +えんとつから はいるのは\n\ サンタだけではありません。\n\ - ごえんりょなく\n\ - おはいりください。\n\ -スノ-マンハウスお-な-")) +  ごえんりょなく\n\ +  おはいりください。\n\ +スノーマンハウスおーなー")) DEFINE_DIALOG(DIALOG_088, 1, 5, 30, 200, _("\ -さぎょうリフトじょう-\n\ \n\ -ここから おりるひとは\n\ -ひだりのぼうにつかまって,\n\ -きをつけて おりること。")) +ここから おりるひとは\n\ +ひだりのぼうにつかまって、\n\ +きをつけて おりること。")) DEFINE_DIALOG(DIALOG_089, 1, 4, 95, 200, _("\ -どちらのみちも キケン!\n\ +どちらのみちも キケン!\n\ くらいあしもとにチュウイ。\n\ -はばとび できないひとは\n\ -みぎのみちを すすめ。\n\ +はばとび できないひとは\n\ +みぎのみちを すすめ。\n\ みぎ・・さぎょうリフト\n\ - ケムリめいろ\n\ +    ケムリめいろ\n\ ひだり・・やみのおおあな\n\ - ちていこ ヘ\n\ +     ちていこ ヘ\n\ あかまる\n\ - ・・2ごうエレベ-タ-\n\ - ちていこ へ\n\ + ・・2ごうエレベーター\n\ +      ちていこ へ\n\ やじるし・・げんざいち")) DEFINE_DIALOG(DIALOG_090, 1, 6, 30, 200, _("\ -ガハハッ!\n\ -ワナにはまったなマリオ!\n\ -また ジャマをしにきた\n\ -ようだが,ともだちからの\n\ +ガハハッ!\n\ +ワナにはまったなマリオ!\n\ +また ジャマをしにきた\n\ +ようだが、ともだちからの\n\ ちゅうこくだ。\n\ -あしもとには きをつけな。")) +あしもとには きをつけな。")) DEFINE_DIALOG(DIALOG_091, 1, 3, 30, 200, _("\ -つよいカゼに チュウイ!\n\ -でも,カゼにのると\n\ +つよいカゼに チュウイ!\n\ +でも、カゼにのると\n\ フワフワきもちいいです。")) DEFINE_DIALOG(DIALOG_092, 1, 3, 30, 200, _("\ -いいかげんにしろマリオ!\n\ -いつもいつも,わがはいの\n\ -ジャマをしおって!\n\ -せっかく かいぶつたちと\n\ +いいかげんにしろマリオ!\n\ +いつもいつも、わがはいの\n\ +ジャマをしおって!\n\ +せっかく かいぶつたちと\n\ たのしくやっているのに。\n\ -スタ-をかえすんだ!\n\ -カベのなかのヤツらには,\n\ -そいつが いるんだよ!!\n\ -ガハハッ!!")) +スターをかえすんだ!\n\ +カベのなかのヤツらには、\n\ +そいつが いるんだよ!!\n\ +ガハハッ!!")) DEFINE_DIALOG(DIALOG_093, 1, 4, 30, 200, _("\ -アララ!いつのまにきた?\n\ +アララ!いつのまにきた?\n\ ・・・・・・ムム\n\ -どちらにしろ わがはいの\n\ -ほのおの えじきだっ!\n\ -どれだけスタ-のちからを\n\ -かりても,わがはいには\n\ -かなうわけがないわ!\n\ -ガハハッ!! マリオ!\n\ -キサマの おともだちも\n\ -み-んな カベのなかさ。\n\ -ピ-チちゃんも わたさん\n\ -もんね! いくぞ!!")) +どちらにしろ わがはいの\n\ +ほのおの えじきだっ!\n\ +どれだけスターのちからを\n\ +かりても、わがはいには\n\ +かなうわけがないわ!\n\ +ガハハッ!! マリオ!\n\ +キサマの おともだちも\n\ +みーんな カベのなかさ。\n\ +ピーチちゃんも わたさん\n\ +もんね!  いくぞ!!")) DEFINE_DIALOG(DIALOG_094, 1, 3, 30, 200, _("\ -のぼりにくい さかみちは\n\ +のぼりにくい さかみちは\n\ じょそうをつけて\n\ -げんきよく のぼる!\n\ -はばとび おぼえてるか?\n\ -はしりながら Zボタンで\n\ -しゃがんで ジャンプだ!")) +げんきよく のぼる!\n\ +はばとび おぼえてるか?\n\ +はしりながら Zボタンで\n\ +しゃがんで ジャンプだ!")) DEFINE_DIALOG(DIALOG_095, 1, 3, 30, 200, _("\ -このように カンバンの\n\ -まえで Bボタンをおすと\n\ +このように カンバンの\n\ +まえで Bボタンをおすと\n\ よむことができます。\n\ -ノコノコや どうぶつたち\n\ -と はなすときは,まえに\n\ +ノコノコや どうぶつたち\n\ +と はなすときは、まえに\n\ たちどまってください。\n\ -このコ-スにあるクッパに\n\ -ぬすまれたパワ-スタ-を\n\ +このコースにあるクッパに\n\ +ぬすまれたパワースターを\n\ とりかえしてください。")) DEFINE_DIALOG(DIALOG_096, 1, 5, 30, 200, _("\ -このあたり みちせまし。\n\ -ゆっくり あるこう!\n\ -だれも ちょうじょうまで\n\ +このあたり みちせまし。\n\ +ゆっくり あるこう!\n\ +だれも ちょうじょうまで\n\ たどりつかせない。\n\ フフフ。\n\ きもちよくねているひとを\n\ -おこすと,とっても\n\ -ふきげんに なります。\n\ -ゆっくりと しずかに\n\ +おこすと、とっても\n\ +ふきげんに なります。\n\ +ゆっくりと しずかに\n\ あるきましょう。フフフ。")) DEFINE_DIALOG(DIALOG_097, 1, 4, 30, 200, _("\ -たいあたり されたら\n\ -たいあたりで かえせ!\n\ +たいあたり されたら\n\ +たいあたりで かえせ!\n\ ほのおのうみにつきおとす\n\ -1たい1のデスマッチだ!")) +1たい1のデスマッチだ!")) DEFINE_DIALOG(DIALOG_098, 1, 3, 95, 200, _("\ ここまでおいで・・・・\n\ @@ -1112,27 +1112,27 @@ DEFINE_DIALOG(DIALOG_098, 1, 3, 95, 200, _("\ DEFINE_DIALOG(DIALOG_099, 1, 3, 95, 200, _("\ クックック・・\n\ - とりついてやる。\n\ - ヒッヒッヒ!\n\ -カベも とおりぬけてやる。\n\ -こんなこと できるか?\n\ - ケッケッケ!")) + とりついてやる。\n\ +    ヒッヒッヒ!\n\ +カベも とおりぬけてやる。\n\ +こんなこと できるか?\n\ +     ケッケッケ!")) DEFINE_DIALOG(DIALOG_100, 1, 4, 95, 200, _("\ -ウッキッキ-\n\ - ワッキッキ-!\n\ - ホヨホヨ。\n\ -いっただき-。")) +ウッキッキー\n\ + ワッキッキー!\n\ +   ホヨホヨ。\n\ +いっただきー。")) DEFINE_DIALOG(DIALOG_101, 1, 5, 95, 200, _("\ -ヘッヘッヘッ!\n\ +ヘッヘッヘッ!\n\ つかまっちゃいました。\n\ きにいってたのになあ・・\n\ かえしますよ。\n\ - ウッキッキ-!!")) + ウッキッキー!!")) DEFINE_DIALOG(DIALOG_102, 1, 4, 30, 200, _("\ -テレサの たおしかた\n\ +テレサの たおしかた\n\ おしえます。\n\ はずかしがりやの\n\ テレサです。\n\ @@ -1143,205 +1143,205 @@ DEFINE_DIALOG(DIALOG_102, 1, 4, 30, 200, _("\ 『せなかをむける』と\n\ あらわれます。\n\ うしろにまわって\n\ -なぐると よわい。")) +なぐると よわい。")) DEFINE_DIALOG(DIALOG_103, 1, 4, 95, 200, _("\ -4ほんの はしらのうえに\n\ -たつものに,わたしは,\n\ -このやかたを おとずれる\n\ -しかくを あたえよう。")) +4ほんの はしらのうえに\n\ +たつものに、わたしは、\n\ +このやかたを おとずれる\n\ +しかくを あたえよう。")) DEFINE_DIALOG(DIALOG_104, 1, 6, 30, 200, _("\ -めのまえのブル-グレ-の\n\ -はんとうめいの ほしは\n\ -『パワ-スタ-のだい』だ。\n\ -あかコインを みつけて\n\ -8まいぜんぶ あつめると,\n\ -スタ-が あらわれる。")) +めのまえのブルーグレーの\n\ +はんとうめいの ほしは\n\ +『パワースターのだい』だ。\n\ +あかコインを みつけて\n\ +8まいぜんぶ あつめると、\n\ +スターが あらわれる。")) DEFINE_DIALOG(DIALOG_105, 1, 3, 95, 200, _("\ -じゅんび かんりょう!\n\ -そこの あなに\n\ +じゅんび かんりょう!\n\ +そこの あなに\n\ はいってみてください。\n\ -4つのたいほうをつかって\n\ -そらのしまにあるスタ-を\n\ +4つのたいほうをつかって\n\ +そらのしまにあるスターを\n\ とれるはずです。\n\ -スティックでねらいをつけ,\n\ -Aではっしゃ!とびながら\n\ -『き』にも つかまれます。")) +スティックでねらいをつけ、\n\ +Aではっしゃ!とびながら\n\ +『き』にも つかまれます。")) DEFINE_DIALOG(DIALOG_106, 1, 3, 95, 200, _("\ じゅんびが\n\ -かんりょう しました!\n\ -それでは,おきをつけて!")) +かんりょう しました!\n\ +それでは、おきをつけて!")) DEFINE_DIALOG(DIALOG_107, 1, 3, 95, 200, _("\ -おばけは し な な い\n\ +おばけは し な な い\n\ ケッケッケ・・\n\ -ぶじに でられるかな?")) +ぶじに でられるかな?")) DEFINE_DIALOG(DIALOG_108, 1, 3, 95, 200, _("\ -ぼよよ-ん\n\ -おやかたの おでましだ。\n\ +ぼよよーん\n\ +おやかたの おでましだ。\n\ カッカッカ・・")) DEFINE_DIALOG(DIALOG_109, 1, 4, 95, 200, _("\ -カラダが とけちゃったヨ。\n\ -いいカラダ いないかな-\n\ -なにか おちつかなくてネ。\n\ -ア- かおがつめたいな-")) +カラダが とけちゃったヨ。\n\ +いいカラダ いないかなー\n\ +なにか おちつかなくてネ。\n\ +アー かおがつめたいなー")) DEFINE_DIALOG(DIALOG_110, 1, 3, 95, 200, _("\ -しょうらい きっと\n\ +しょうらい きっと\n\ りっぱなカラダになろうと\n\ -おもってま-す!\n\ -いいアタマ いないかな-\n\ -もししっていたら そこへ\n\ -つれてってくれませんか?\n\ -まえを すべってくれれば\n\ -うしろをついていきま-す。\n\ - ヨロシク-!")) +おもってまーす!\n\ +いいアタマ いないかなー\n\ +もししっていたら そこへ\n\ +つれてってくれませんか?\n\ +まえを すべってくれれば\n\ +うしろをついていきまーす。\n\ + ヨロシクー!")) DEFINE_DIALOG(DIALOG_111, 1, 3, 95, 200, _("\ -ヤッリ-!\n\ -きぶんスッキリ!りっぱな\n\ -カラダが みつかった!\n\ -おれいに これあげます!\n\ -もっていって ください。\n\ +ヤッリー!\n\ +きぶんスッキリ!りっぱな\n\ +カラダが みつかった!\n\ +おれいに これあげます!\n\ +もっていって ください。\n\ とってもアッタカイですよ。")) DEFINE_DIALOG(DIALOG_112, 1, 4, 30, 200, _("\ コインいっぱいあつめよう。\n\ -ちからが かいふくする。\n\ -えのなかの15コ-スでは\n\ -きろくにも のこるよ。\n\ -あかいハ-トにさわっても\n\ -ちからが かいふくする。\n\ -はやく かけぬけるほど\n\ -たくさん かいふくする!")) +ちからが かいふくする。\n\ +えのなかの15コースでは\n\ +きろくにも のこるよ。\n\ +あかいハートにさわっても\n\ +ちからが かいふくする。\n\ +はやく かけぬけるほど\n\ +たくさん かいふくする!")) DEFINE_DIALOG(DIALOG_113, 1, 6, 30, 200, _("\ あか・あお・みどりの\n\ -ブロックには アイテムの\n\ -『ぼうし』が はいってる。\n\ -おしろの どこかにある\n\ -スイッチを ふんでくると\n\ -つかえるように なります。")) +ブロックには アイテムの\n\ +『ぼうし』が はいってる。\n\ +おしろの どこかにある\n\ +スイッチを ふんでくると\n\ +つかえるように なります。")) DEFINE_DIALOG(DIALOG_114, 1, 4, 95, 200, _("\ -ああ~ きにいらねえ!\n\ -おれたち,いしのおかげで\n\ +ああ~ きにいらねえ!\n\ +おれたち、いしのおかげで\n\ 『いえ』も『しろ』も\n\ -できてるって-のに。\n\ -いつも ふみつけるばっか\n\ -りで, ちった-ありがた\n\ -がったら どうなんでぃ!\n\ -おうおうっ!\n\ -おい! そこのニイサン!\n\ -ふらふらしてんじゃね-や。\n\ -きげんが わるいんでぃ!\n\ -おしつぶしちまうぞぉ!!\n\ -もんくが あんなら\n\ -ヒップドロップで この\n\ +できてるってーのに。\n\ +いつも ふみつけるばっか\n\ +りで、 ちったーありがた\n\ +がったら どうなんでぃ!\n\ +おうおうっ!\n\ +おい! そこのニイサン!\n\ +ふらふらしてんじゃねーや。\n\ +きげんが わるいんでぃ!\n\ +おしつぶしちまうぞぉ!!\n\ +もんくが あんなら\n\ +ヒップドロップで この\n\ バッタンキングさまを\n\ -ふみつけて みやがれっ!")) +ふみつけて みやがれっ!")) DEFINE_DIALOG(DIALOG_115, 1, 5, 95, 200, _("\ -ああ くやしいぞ!\n\ +ああ くやしいぞ!\n\ またまた\n\ -ふみつけられちまった!\n\ -しょせん いしは\n\ - いしなのか・・・\n\ -おめぇの かちでぇ!\n\ -これ もっていきやがれ!\n\ -ガクッ!")) +ふみつけられちまった!\n\ +しょせん いしは\n\ +    いしなのか・・・\n\ +おめぇの かちでぇ!\n\ +これ もっていきやがれ!\n\ +ガクッ!")) DEFINE_DIALOG(DIALOG_116, 1, 5, 95, 200, _("\ -おおっ!いてて! まわり\n\ -こみのはやさは まだまだ\n\ -だが,なかなか つよいな。\n\ -おまえのような けらいが\n\ +おおっ!いてて! まわり\n\ +こみのはやさは まだまだ\n\ +だが、なかなか つよいな。\n\ +おまえのような けらいが\n\ ほしかったぞ・・\n\ -はじめの やくそくどおり\n\ -パワ-スタ-をやろう。\n\ -また ワシにあいたいとき\n\ -このスタ-をメニュ-から\n\ +はじめの やくそくどおり\n\ +パワースターをやろう。\n\ +また ワシにあいたいとき\n\ +このスターをメニューから\n\ えらぶがよい。さらばじゃ")) DEFINE_DIALOG(DIALOG_117, 1, 3, 95, 200, _("\ -ジャジャジャ-ン!\n\ -どうだ!\n\ -おどろいたか??・・・\n\ -ムム・・・・ ならば\n\ -もっとオドロカセテやる!\n\ -イクゾ! カカッテコイ!")) +ジャジャジャーン!\n\ +どうだ!\n\ +おどろいたか??・・・\n\ +ムム・・・・ ならば\n\ +もっとオドロカセテやる!\n\ +イクゾ! カカッテコイ!")) DEFINE_DIALOG(DIALOG_118, 1, 5, 95, 200, _("\ オオオッ・・・\n\ -オマエ,いがいとツヨイ!\n\ -このヤカタは,きょうから\n\ +オマエ、いがいとツヨイ!\n\ +このヤカタは、きょうから\n\ オマエのものダッ・・\n\ -ジユウニつかエ。ガクッ!")) +ジユウニつかエ。ガクッ!")) DEFINE_DIALOG(DIALOG_119, 1, 4, 30, 200, _("\ -グウウッ! ちょっと\n\ -ゆだん しておったわ!\n\ +グウウッ!  ちょっと\n\ +ゆだん しておったわ!\n\ せっかくのケイカクが\n\ ぶちこわしだ・・・しかし\n\ -パワ-スタ-もピ-チも\n\ -わがはいの てのなかに\n\ -あるのだ。ガハハハ!\n\ -まだまだ まけてはおらん。\n\ -これいじょうスタ-は\n\ +パワースターもピーチも\n\ +わがはいの てのなかに\n\ +あるのだ。ガハハハ!\n\ +まだまだ まけてはおらん。\n\ +これいじょうスターは\n\ わたさんぞ。きょうはここ\n\ -らで かんべんしてやる!\n\ -おおぉ,おぼえてろよ!!")) +らで かんべんしてやる!\n\ +おおぉ、おぼえてろよ!!")) DEFINE_DIALOG(DIALOG_120, 1, 4, 30, 200, _("\ -グググッワッ!\n\ -こうも かんたんに\n\ -やられるとは,スタ-の\n\ -ちからが たりんのかな?\n\ -わがはいがゼッコ-チョ-\n\ -のときなら,キサマなんか\n\ +グググッワッ!\n\ +こうも かんたんに\n\ +やられるとは、スターの\n\ +ちからが たりんのかな?\n\ +わがはいがゼッコーチョー\n\ +のときなら、キサマなんか\n\ てきではない。\n\ -こんかいは ひきわけだっ\n\ -ピ-チに あいたければ,\n\ +こんかいは ひきわけだっ\n\ +ピーチに あいたければ、\n\ とうのてっぺんまで\n\ のぼってきてみろ。\n\ -まってるぞ!ガハハッ!!")) +まってるぞ!ガハハッ!!")) DEFINE_DIALOG(DIALOG_121, 1, 5, 30, 200, _("\ あああっ・・またこんども\n\ -キサマのかちか マリオ!\n\ -キサマはな,わがはいが\n\ -せかいで い-ちばん\n\ -まけたくないヤツなのに!\n\ -せっかく なかまにした\n\ -モンスタ-たちのちからも\n\ -なくなり このままでは\n\ -またまた,わがはいの\n\ -だ-いきらいな\n\ -へいわが もどってしまう\n\ -ではないか! \n\ +キサマのかちか マリオ!\n\ +キサマはな、わがはいが\n\ +せかいで いーちばん\n\ +まけたくないヤツなのに!\n\ +せっかく なかまにした\n\ +モンスターたちのちからも\n\ +なくなり このままでは\n\ +またまた、わがはいの\n\ +だーいきらいな\n\ +へいわが もどってしまう\n\ +ではないか! \n\ ムムムッ・・・・\n\ -しかし,このゲ-ムは\n\ -まだまだ おわらんぞ。\n\ -みんなで あつまって,\n\ +しかし、このゲームは\n\ +まだまだ おわらんぞ。\n\ +みんなで あつまって、\n\ なかよくエンディングでも\n\ -みるんだな!\n\ +みるんだな!\n\ \n\ -ガハハハッ!")) +ガハハハッ!")) DEFINE_DIALOG(DIALOG_122, 1, 6, 30, 200, _("\ -やみにとけるおおあな-\n\ \n\ みぎ・・・さぎょうリフト\n\ - ケムリめいろ\n\ +     ケムリめいろ\n\ ひだり・・ちていこ")) DEFINE_DIALOG(DIALOG_123, 1, 5, 30, 200, _("\ - -メタルのどうくつ-\n\ + -メタルのどうくつ-\n\ \n\ みぎ・・・ちじょうへ\n\ ひだり・・メタルスイッチ")) @@ -1349,539 +1349,539 @@ DEFINE_DIALOG(DIALOG_123, 1, 5, 30, 200, _("\ DEFINE_DIALOG(DIALOG_124, 1, 5, 30, 200, _("\ -さぎょうようリフト-\n\ \n\ - キケン!!\n\ - そうさほうほうを\n\ - よく よむこと。\n\ -ふんだ,やじるしのほうに\n\ +   キケン!!\n\ + そうさほうほうを\n\ + よく よむこと。\n\ +ふんだ、やじるしのほうに\n\ すすみつづけます。\n\ \n\ -おりると もとのばしょに\n\ +おりると もとのばしょに\n\ もどります。")) DEFINE_DIALOG(DIALOG_125, 1, 5, 30, 200, _("\ -ケムリめいろ・でぐち-\n\ \n\ -キケン! ヘイサちゅう。\n\ -ここからは はいれません。")) +キケン! ヘイサちゅう。\n\ +ここからは はいれません。")) DEFINE_DIALOG(DIALOG_126, 1, 6, 30, 200, _("\ -・1ごうエレベ-タ-・\n\ +・1ごうエレベーター・\n\ \n\ うえ・・やみのおおあな\n\ みぎ・・さぎょうリフト\n\ - ケムリめいろ")) +    ケムリめいろ")) DEFINE_DIALOG(DIALOG_127, 1, 5, 30, 200, _("\ - -ちていこ-\n\ +  -ちていこ-\n\ \n\ みぎ・・メタルのどうくつ\n\ ひだり・・はいこう\n\ - へいさちゅう\n\ -おとなしい かいりゅう\n\ -ドッシ-が すんでます\n\ +     へいさちゅう\n\ +おとなしい かいりゅう\n\ +ドッシーが すんでます\n\ せなかでヒップドロップを\n\ -すると,あたまをさげます。\n\ +すると、あたまをさげます。\n\ エサにならないでください。")) DEFINE_DIALOG(DIALOG_128, 1, 4, 95, 200, _("\ -おっとっと!じょうがいに\n\ -なげるのは はんそくだ!\n\ -リングのうえでフェア-に\n\ -たたかおうでは ないか!")) +おっとっと!じょうがいに\n\ +なげるのは はんそくだ!\n\ +リングのうえでフェアーに\n\ +たたかおうでは ないか!")) DEFINE_DIALOG(DIALOG_129, 1, 5, 30, 200, _("\ とうめいスイッチの\n\ - コ-スへ ようこそ!\n\ -あおいスイッチを ふむと\n\ -すべての あおブロックが\n\ +  コースへ ようこそ!\n\ +あおいスイッチを ふむと\n\ +すべての あおブロックが\n\ 『じったい』になる。\n\ とうめいぼうしで\n\ -とうめいに なると\n\ -いろんな ものを\n\ +とうめいに なると\n\ +いろんな ものを\n\ とおりぬけられます。\n\ -まずは おためしください。")) +まずは おためしください。")) DEFINE_DIALOG(DIALOG_130, 1, 5, 30, 200, _("\ メタルのスイッチの\n\ - コ-スヘ ようこそ!\n\ +  コースヘ ようこそ!\n\ みどりのスイッチを\n\ -ふめば みどりブロックが\n\ +ふめば みどりブロックが\n\ 『じったい』になる。\n\ メタルのぼうしで\n\ -メタルになれば,\n\ +メタルになれば、\n\ みずのなかでも\n\ あるけてしまう。\n\ -まずは おためしください。")) +まずは おためしください。")) DEFINE_DIALOG(DIALOG_131, 1, 5, 30, 200, _("\ はねのスイッチの\n\ - コ-スヘ ようこそ!\n\ +  コースヘ ようこそ!\n\ にじのリングのまんなかの\n\ -とうの うえにある\n\ -あかいスイッチを ふもう。\n\ -このせかいの すべての\n\ +とうの うえにある\n\ +あかいスイッチを ふもう。\n\ +このせかいの すべての\n\ あかいブロックが\n\ 『じったい』になる。\n\ -3だんとびで そらへとび,\n\ -Zボタンで ランディング。\n\ -そうさは ひこうきの\n\ -そうじゅうかん のように\n\ +3だんとびで そらへとび、\n\ +Zボタンで ランディング。\n\ +そうさは ひこうきの\n\ +そうじゅうかん のように\n\ まえにたおすと『さがる』\n\ てまえにひくと『あがる』\n\ -まずは おためしを!")) +まずは おためしを!")) DEFINE_DIALOG(DIALOG_132, 1, 5, 30, 200, _("\ -ダメダメ!\n\ -それは きていいはんです。\n\ -『しっか-く!』\n\ -こんどはフェア-に\n\ +ダメダメ!\n\ +それは きていいはんです。\n\ +『しっかーく!』\n\ +こんどはフェアーに\n\ いきましょう。")) DEFINE_DIALOG(DIALOG_133, 1, 5, 30, 200, _("\ ああよかった。\n\ -きてくれたんですね!\n\ -ピ-チひめも ぼくたちも\n\ +きてくれたんですね!\n\ +ピーチひめも ぼくたちも\n\ みんな『カベ』のなかに\n\ とじこめられちゃいました。\n\ -クッパは パワ-スタ-を\n\ +クッパは パワースターを\n\ つかって『カベ』や『え』\n\ のなかにカイブツのくにを\n\ -つくろうと しています。\n\ -スタ-をとりかえして!\n\ -『スタ-』をいくつか\n\ -とりかえしたら,クッパの\n\ -とじたドアが ひらきます。\n\ -1かいの 4つのへやを\n\ -さがし,すすんでください。\n\ -まずは,ヒダリがわの\n\ +つくろうと しています。\n\ +スターをとりかえして!\n\ +『スター』をいくつか\n\ +とりかえしたら、クッパの\n\ +とじたドアが ひらきます。\n\ +1かいの 4つのへやを\n\ +さがし、すすんでください。\n\ +まずは、ヒダリがわの\n\ ボムへいの『え』の\n\ -へやに はいれます。\n\ -このへやだけは クッパの\n\ -ふういんを のがれました。\n\ -8まい たまったら\n\ -おおきな ほしのドアを\n\ -ひらくことが できます。\n\ -きっと ピ-チひめは\n\ -そのなかです!")) +へやに はいれます。\n\ +このへやだけは クッパの\n\ +ふういんを のがれました。\n\ +8まい たまったら\n\ +おおきな ほしのドアを\n\ +ひらくことが できます。\n\ +きっと ピーチひめは\n\ +そのなかです!")) DEFINE_DIALOG(DIALOG_134, 1, 4, 30, 200, _("\ -コ-スのはじめにえらべる\n\ -スタ-のなまえは,\n\ -つぎに みつけられそうな\n\ -スタ-のヒントです。\n\ +コースのはじめにえらべる\n\ +スターのなまえは、\n\ +つぎに みつけられそうな\n\ +スターのヒントです。\n\ ヒントにでてくる\n\ -じゅんばんと,ちがう\n\ -スタ-を とりもどしても\n\ +じゅんばんと、ちがう\n\ +スターを とりもどしても\n\ かまわないですよ。\n\ -『スタ-』や『てき』や\n\ +『スター』や『てき』や\n\ 『アイテム』のなかには\n\ -そのスタ-をえらばないと\n\ -でないものも あります。\n\ -いくつか とりかえしたら\n\ -つぎのコ-スのドアへと\n\ +そのスターをえらばないと\n\ +でないものも あります。\n\ +いくつか とりかえしたら\n\ +つぎのコースのドアへと\n\ すすんでください。みんな\n\ -たすけを まっています!")) +たすけを まっています!")) DEFINE_DIALOG(DIALOG_135, 1, 5, 30, 200, _("\ -クッパがスタ-をもって\n\ +クッパがスターをもって\n\ いっちゃいました。\n\ ここにかくれてみてました。\n\ -スタ-はひとつのコ-スに\n\ -6こあるはずです。\n\ -でも アイテムスイッチを\n\ +スターはひとつのコースに\n\ +6こあるはずです。\n\ +でも アイテムスイッチを\n\ ぜんぶおしてからでないと\n\ -とれないスタ-もあります。\n\ -どんどん さきのコ-スへ\n\ +とれないスターもあります。\n\ +どんどん さきのコースへ\n\ すすんでください。\n\ -スタ-トがめんでスタ-の\n\ -なまえが みられます。\n\ -むかしのてきに あいたい\n\ -とき,そのほしをえらぶと\n\ -またあえる てきもいます。")) +スタートがめんでスターの\n\ +なまえが みられます。\n\ +むかしのてきに あいたい\n\ +とき、そのほしをえらぶと\n\ +またあえる てきもいます。")) DEFINE_DIALOG(DIALOG_136, 1, 4, 30, 200, _("\ -ワァすごい!もうそんなに\n\ -スタ-をもってるんですね。\n\ -もうすぐ ぼくらのことも\n\ -たすけだしてくれますね!\n\ -クッパたちは ひっしです。\n\ +ワァすごい!もうそんなに\n\ +スターをもってるんですね。\n\ +もうすぐ ぼくらのことも\n\ +たすけだしてくれますね!\n\ +クッパたちは ひっしです。\n\ きをつけてください。\n\ -コインをとると ちからが\n\ +コインをとると ちからが\n\ かいふくします。\n\ -あかコインは2まいぶん。\n\ -あおコインは5まいぶん。\n\ +あかコインは2まいぶん。\n\ +あおコインは5まいぶん。\n\ あおコインのブロックを\n\ -こわすと でてきます。\n\ +こわすと でてきます。\n\ たかいところからおちても\n\ -ちじょうの ちかくで\n\ +ちじょうの ちかくで\n\ 『ヒップドロップ』すると\n\ -ダメ-ジを ふせげます。")) +ダメージを ふせげます。")) DEFINE_DIALOG(DIALOG_137, 1, 5, 30, 200, _("\ -パワ-スタ-が もどって,\n\ +パワースターが もどって、\n\ おしろのちからが\n\ -かいふく してきました!\n\ -ありがとう。 クッパは\n\ -このさきに にげました。\n\ -そうだ!コインをあつめて\n\ -ますか?15のコ-スでは\n\ -コイン100まい とると\n\ -スペシャルスタ-が\n\ +かいふく してきました!\n\ +ありがとう。 クッパは\n\ +このさきに にげました。\n\ +そうだ!コインをあつめて\n\ +ますか?15のコースでは\n\ +コイン100まい とると\n\ +スペシャルスターが\n\ あらわれます。")) DEFINE_DIALOG(DIALOG_138, 1, 5, 30, 200, _("\ -・2ごうエレベ-タ-・\n\ +・2ごうエレベーター・\n\ した・・ちていこ\n\ ひだり・・やみのおおあな\n\ みぎ・・・ケムリめいろ\n\ - へいさちゅう!")) +     へいさちゅう!")) DEFINE_DIALOG(DIALOG_139, 1, 6, 30, 200, _("\ このうえ・・じどうリフト\n\ -じどうリフトは のると\n\ -じどうてきに うごきだし,\n\ -コ-スにそってすすみます。\n\ -おりて ほうっておくと\n\ +じどうリフトは のると\n\ +じどうてきに うごきだし、\n\ +コースにそってすすみます。\n\ +おりて ほうっておくと\n\ きえてしまいます。")) DEFINE_DIALOG(DIALOG_140, 1, 6, 30, 200, _("\ -そうさリフトじょう-\n\ みぎ・・・ケムリめいろ\n\ - いりぐち\n\ +     いりぐち\n\ ひだり・・やみのおおあな\n\ - 1ごうエレベ-タ-へ\n\ +  1ごうエレベーターへ\n\ やじるし・・げんざいち")) DEFINE_DIALOG(DIALOG_141, 1, 5, 150, 200, _("\ -ぬすまれたパワ-スタ-を\n\ -とりかえした!\n\ -クッパが とじてしまった\n\ -ドアを あけられるように\n\ -なったぞ!\n\ -2かいの ピ-チのへや,\n\ -1かいの とりでのへや,\n\ -2つのへやのドアがひらく。\n\ -つぎのスタ-をとりかえし\n\ -おしろのみんなをすくえ!\n\ -モンスタ-たちはどんどん\n\ -ちからを つけてきている。\n\ -いそげ マリオ!!\n\ -おしろの いちだいじだ!")) +ぬすまれたパワースターを\n\ +とりかえした!\n\ +クッパが とじてしまった\n\ +ドアを あけられるように\n\ +なったぞ!\n\ +2かいの ピーチのへや、\n\ +1かいの とりでのへや、\n\ +2つのへやのドアがひらく。\n\ +つぎのスターをとりかえし\n\ +おしろのみんなをすくえ!\n\ +モンスターたちはどんどん\n\ +ちからを つけてきている。\n\ +いそげ マリオ!!\n\ +おしろの いちだいじだ!")) DEFINE_DIALOG(DIALOG_142, 1, 5, 150, 200, _("\ -3このスタ-を\n\ -とりもどしたぞ! \n\ -そして スタ-に『3』の\n\ -すうじが ついたドアを\n\ -ひらけるように なった!\n\ -4つのへやの せかいを\n\ -じゆうに いききできる。\n\ +3このスターを\n\ +とりもどしたぞ! \n\ +そして スターに『3』の\n\ +すうじが ついたドアを\n\ +ひらけるように なった!\n\ +4つのへやの せかいを\n\ +じゆうに いききできる。\n\ あたらしいカイブツたちは\n\ -もっと てごわいぞ。\n\ -きをつけて すすめ!")) +もっと てごわいぞ。\n\ +きをつけて すすめ!")) DEFINE_DIALOG(DIALOG_143, 1, 6, 150, 200, _("\ -8このパワ-スタ-を\n\ -ぶじ とりもどし,\n\ -おおきな ほしのドアが\n\ +8このパワースターを\n\ +ぶじ とりもどし、\n\ +おおきな ほしのドアが\n\ ひらくようになった。\n\ -クッパは すぐそこだ!\n\ -ピ-チのこえがきこえる。")) +クッパは すぐそこだ!\n\ +ピーチのこえがきこえる。")) DEFINE_DIALOG(DIALOG_144, 1, 5, 150, 200, _("\ -30この パワ-スタ-を\n\ -とりもどし,\n\ -おおきなスタ-のドアが\n\ -ひらくようになった!\n\ -ここですこし てんけんだ。\n\ -2ほんのはしらを ヒップ\n\ -ドロップしてみたか?\n\ -ぼうしはなくしてないか?\n\ -さばくで なくしたなら\n\ +30この パワースターを\n\ +とりもどし、\n\ +おおきなスターのドアが\n\ +ひらくようになった!\n\ +ここですこし てんけんだ。\n\ +2ほんのはしらを ヒップ\n\ +ドロップしてみたか?\n\ +ぼうしはなくしてないか?\n\ +さばくで なくしたなら\n\ ハゲたかジャンゴをさがせ。\n\ -クッパは うみから\n\ +クッパは うみから\n\ このちかにせんにゅう\n\ したらしい。\n\ とうとうやつを\n\ -おいつめたぞ!")) +おいつめたぞ!")) DEFINE_DIALOG(DIALOG_145, 1, 4, 150, 200, _("\ -50このパワ-スタ-を\n\ -とりもどした!\n\ -3かいへの ほしのドアが\n\ -ひらくぞ!\n\ -クッパはすぐそこだ!\n\ +50このパワースターを\n\ +とりもどした!\n\ +3かいへの ほしのドアが\n\ +ひらくぞ!\n\ +クッパはすぐそこだ!\n\ アイテムスイッチは\n\ -ぜんぶおしてきたか?\n\ -かくにん しておこう。\n\ +ぜんぶおしてきたか?\n\ +かくにん しておこう。\n\ あか・あお・みどりの\n\ -3つのアイテムブロックは\n\ -とてもだいじな みかただ。\n\ -さあ『3かい』へすすめ!")) +3つのアイテムブロックは\n\ +とてもだいじな みかただ。\n\ +さあ『3かい』へすすめ!")) DEFINE_DIALOG(DIALOG_146, 1, 6, 150, 200, _("\ -70このパワ-スタ-を\n\ -とりもどした!\n\ -はてしない かいだんの\n\ +70このパワースターを\n\ +とりもどした!\n\ +はてしない かいだんの\n\ ナゾがとかれた。\n\ クッパはかなりあせってる。\n\ -さあ!さいごのたたかいだ。")) +さあ!さいごのたたかいだ。")) DEFINE_DIALOG(DIALOG_147, 1, 5, 30, 200, _("\ あか・あお・みどりの\n\ 『アイテムブロック』を\n\ -つかっていますか?\n\ -スタ-をとりもどすと\n\ -いりぐちがみつかる,\n\ -おしろのかくしコ-スで,\n\ -3つのスイッチを おすと\n\ +つかっていますか?\n\ +スターをとりもどすと\n\ +いりぐちがみつかる、\n\ +おしろのかくしコースで、\n\ +3つのスイッチを おすと\n\ そのいろのブロックが\n\ -『じったい』となり,\n\ +『じったい』となり、\n\ つかえるようになります。\n\ -あかは はねのぼうし\n\ -みどりは メタルのぼうし\n\ -あおは とうめいのぼうし\n\ +あかは はねのぼうし\n\ +みどりは メタルのぼうし\n\ +あおは とうめいのぼうし\n\ \n\ -とてもつよい みかたです。")) +とてもつよい みかたです。")) DEFINE_DIALOG(DIALOG_148, 1, 5, 30, 200, _("\ -このさきスノ-マンのやま\n\ -だれも はいるな!\n\ -アイスブロックシュ-タ-\n\ -を 3だんとびなどして\n\ -とびこえては イケマセン。\n\ -つめたい いけでは\n\ -はやく たいりょくが\n\ -へります!\n\ -かいふくも しません。\n\ - スノ-マン")) +このさきスノーマンのやま\n\ +だれも はいるな!\n\ +アイスブロックシューター\n\ +を 3だんとびなどして\n\ +とびこえては イケマセン。\n\ +つめたい いけでは\n\ +はやく たいりょくが\n\ +へります!\n\ +かいふくも しません。\n\ +      スノーマン")) DEFINE_DIALOG(DIALOG_149, 1, 5, 30, 200, _("\ -ピ-チのかくれスライダ-\n\ -へ ようこそ!\n\ -ここには クッパにみつけ\n\ -られなかった おしろの\n\ -かくれスタ-がのこってる。\n\ -さかを すべりはじめたら\n\ -スティックまえで かそく,\n\ -うしろで げんそくできる。\n\ -はやくすべれば スタ-が\n\ -みつかるはずだ!")) +ピーチのかくれスライダー\n\ +へ ようこそ!\n\ +ここには クッパにみつけ\n\ +られなかった おしろの\n\ +かくれスターがのこってる。\n\ +さかを すべりはじめたら\n\ +スティックまえで かそく、\n\ +うしろで げんそくできる。\n\ +はやくすべれば スターが\n\ +みつかるはずだ!")) DEFINE_DIALOG(DIALOG_150, 1, 5, 30, 200, _("\ -あ--ん,だれだい?\n\ -とつぜん ビショぬれに\n\ -なっちゃいました!\n\ -キチンと てんじょう\n\ +あーーん、だれだい?\n\ +とつぜん ビショぬれに\n\ +なっちゃいました!\n\ +キチンと てんじょう\n\ なおしてもらうです。")) DEFINE_DIALOG(DIALOG_151, 1, 4, 30, 200, _("\ -みずをかけられた つぎは\n\ +みずをかけられた つぎは\n\ ふんづけられました。\n\ -もう ほんと-に\n\ -おこったです!")) +もう ほんとーに\n\ +おこったです!")) DEFINE_DIALOG(DIALOG_152, 1, 5, 30, 200, _("\ -いててて!!!\n\ +いててて!!!\n\ らんぼうなひとだなあ。\n\ -なぜかイライラしてたけど,\n\ -まあ,そらがみえるのも\n\ +なぜかイライラしてたけど、\n\ +まあ、そらがみえるのも\n\ わるくはないです。\n\ -よるには いっぱいほしが\n\ -みえるしね!\n\ -このほしは かえします。\n\ -あ-,なんだか きもちが\n\ +よるには いっぱいほしが\n\ +みえるしね!\n\ +このほしは かえします。\n\ +あー、なんだか きもちが\n\ おちついてきたです。")) DEFINE_DIALOG(DIALOG_153, 1, 4, 30, 200, _("\ -わしの カラダに\n\ -のぼっては いか-ん!\n\ -そういうヤツは みんな\n\ -ふきっとばしちまうぞ-!")) +わしの カラダに\n\ +のぼっては いかーん!\n\ +そういうヤツは みんな\n\ +ふきっとばしちまうぞー!")) DEFINE_DIALOG(DIALOG_154, 1, 5, 30, 200, _("\ -ぼうしを なくすと\n\ -ダメ-ジがおおくなるので\n\ -だいじに してください。\n\ -なくしたら,なくした\n\ -コ-スで みつかります。\n\ -アア-どうしよう・・・\n\ -ピ-チひめは,カベに\n\ +ぼうしを なくすと\n\ +ダメージがおおくなるので\n\ +だいじに してください。\n\ +なくしたら、なくした\n\ +コースで みつかります。\n\ +アアーどうしよう・・・\n\ +ピーチひめは、カベに\n\ ひきこまれたままだし。\n\ -はやく クッパを\n\ +はやく クッパを\n\ やっつけてください。\n\ -ああ,そうだ!\n\ +ああ、そうだ!\n\ えのほかにカベのなかにも\n\ -モンスタ-の せかいが\n\ +モンスターの せかいが\n\ あります。\n\ -よ-く,しらべてください。")) +よーく、しらべてください。")) DEFINE_DIALOG(DIALOG_155, 1, 5, 30, 200, _("\ -パワ-スタ-のおかげで\n\ -おしろに,げんきが\n\ +パワースターのおかげで\n\ +おしろに、げんきが\n\ もどってきました。\n\ クッパなんか\n\ おいはらってください。\n\ -おやくに たつなら\n\ -おしろの はなしをします。\n\ +おやくに たつなら\n\ +おしろの はなしをします。\n\ 『カガミのへや』では\n\ カガミにうつらないものを\n\ よくみてください。\n\ -みずのまちへ いくときは,\n\ -『え』にとびこむ たかさ\n\ -によって,まちをすっかり\n\ -みずびたしに できます。")) +みずのまちへ いくときは、\n\ +『え』にとびこむ たかさ\n\ +によって、まちをすっかり\n\ +みずびたしに できます。")) DEFINE_DIALOG(DIALOG_156, 1, 4, 30, 200, _("\ -とけいがとても へんです。\n\ -とけいに はいるとき,\n\ -ながいはりの ばしょに\n\ -ちゅういしてください!")) +とけいがとても へんです。\n\ +とけいに はいるとき、\n\ +ながいはりの ばしょに\n\ +ちゅういしてください!")) DEFINE_DIALOG(DIALOG_157, 1, 5, 30, 200, _("\ ながれる『すな』に\n\ ながされないように\n\ -きをつけて!\n\ -からだが しずんで\n\ +きをつけて!\n\ +からだが しずんで\n\ ジャンプできません。\n\ あたままでしずむと\n\ -いきが できません。\n\ -くらいいろの ところは\n\ -とくに キケン!!\n\ -そこなしの じごくです!")) +いきが できません。\n\ +くらいいろの ところは\n\ +とくに キケン!!\n\ +そこなしの じごくです!")) DEFINE_DIALOG(DIALOG_158, 1, 5, 30, 200, _("\ ジャンプのテクニック\n\ -その1\n\ -タイミングよく,\n\ +その1\n\ +タイミングよく、\n\ れんぞくでジャンプすると\n\ -だんだん たかくとべる。\n\ -スピ-ドがはやいほど\n\ -たかく とびあがれる。\n\ -れんぞく3かいめに\n\ +だんだん たかくとべる。\n\ +スピードがはやいほど\n\ +たかく とびあがれる。\n\ +れんぞく3かいめに\n\ たかくとべるわざを\n\ -『3だんとび』といいます。\n\ -その2 カベにむかって\n\ -ジャンプして,そこから\n\ +『3だんとび』といいます。\n\ +その2  カベにむかって\n\ +ジャンプして、そこから\n\ もういちどジャンプできる。\n\ -『カベキック』といって,\n\ +『カベキック』といって、\n\ たかいところにのぼれます。")) DEFINE_DIALOG(DIALOG_159, 1, 5, 30, 200, _("\ ジャンプのテクニック\n\ -その3 Zボタンわざ\n\ -たちどまって しゃがんで\n\ -から ジャンプすると,\n\ +その3  Zボタンわざ\n\ +たちどまって しゃがんで\n\ +から ジャンプすると、\n\ 『バックちゅう』できます。\n\ はやくはしりながら\n\ しゃがんでジャンプすると\n\ -とおくまで とべる。\n\ +とおくまで とべる。\n\ 『はばとび』です。")) DEFINE_DIALOG(DIALOG_160, 1, 4, 30, 200, _("\ -はやく はしりながら\n\ -Bボタンをおすと\n\ +はやく はしりながら\n\ +Bボタンをおすと\n\ 『ボディアタック』が\n\ できます。\n\ おなかで\n\ -すべっているあいだは,\n\ -A・Bどちらのボタンでも\n\ +すべっているあいだは、\n\ +A・Bどちらのボタンでも\n\ おきあがることができます。")) DEFINE_DIALOG(DIALOG_161, 1, 5, 30, 200, _("\ -いや- すごいです!!\n\ -ここにいれば あえると\n\ -きいてたけど,ほんとに\n\ -あえてしまいました!!\n\ -でんごんが あります。\n\ -『これで,おしまいですが\n\ +いやー すごいです!!\n\ +ここにいれば あえると\n\ +きいてたけど、ほんとに\n\ +あえてしまいました!!\n\ +でんごんが あります。\n\ +『これで、おしまいですが\n\ もっとあそんでほしいので\n\ つまらないものですが\n\ -うけとって ください。』\n\ +うけとって ください。』\n\ -マリオ・スタッフより-")) DEFINE_DIALOG(DIALOG_162, 1, 5, 30, 200, _("\ -イテテ あいかわらず\n\ +イテテ あいかわらず\n\ らんぼうなひとだな。\n\ -このスタ-は べつに\n\ +このスターは べつに\n\ かくしてたわけじゃ\n\ -ないんだってば!\n\ -かえせば いいんでしょ。\n\ +ないんだってば!\n\ +かえせば いいんでしょ。\n\ はなしてくれたら\n\ -スタ-ぐらい かえすから。\n\ -これで ほんとに\n\ -さいごだよ! ホイ!")) +スターぐらい かえすから。\n\ +これで ほんとに\n\ +さいごだよ!  ホイ!")) DEFINE_DIALOG(DIALOG_163, 1, 5, 30, 200, _("\ あああっ・・またこんども\n\ -キサマのかちか マリオ!\n\ -キサマはな,わがはいが\n\ -せかいで い-ちばん\n\ -まけたくないヤツなのに!\n\ -ほんとうに やくにたたぬ\n\ -カイブツどもだ!\n\ +キサマのかちか マリオ!\n\ +キサマはな、わがはいが\n\ +せかいで いーちばん\n\ +まけたくないヤツなのに!\n\ +ほんとうに やくにたたぬ\n\ +カイブツどもだ!\n\ キサマごときに\n\ -パワ-スタ-をぜ-んぶ\n\ +パワースターをぜーんぶ\n\ とりもどされるとは・・・\n\ -ぜんぶで『120こ』も\n\ -あったのか!?\n\ -『しろ』に わがはいも\n\ -きづかなかったスタ-が\n\ -のこって おったとは・・\n\ -またまた わがはいの\n\ -だ-いきらいな へいわが,\n\ +ぜんぶで『120こ』も\n\ +あったのか!?\n\ +『しろ』に わがはいも\n\ +きづかなかったスターが\n\ +のこって おったとは・・\n\ +またまた わがはいの\n\ +だーいきらいな へいわが、\n\ もどってしまうではないか。\n\ -わがはいは くやし-ぞ!\n\ -きょうは ひきあげてやる。\n\ -だが,こんどあうときは\n\ -ぜ-ったい まけないぞ!\n\ -3Dスティックをみがいて\n\ -まってろよ!\n\ - ガハハッ!")) +わがはいは くやしーぞ!\n\ +きょうは ひきあげてやる。\n\ +だが、こんどあうときは\n\ +ぜーったい まけないぞ!\n\ +3Dスティックをみがいて\n\ +まってろよ!\n\ + ガハハッ!")) DEFINE_DIALOG(DIALOG_164, 1, 4, 30, 200, _("\ -しばらく やすんでたので\n\ -こんなにみごとに,\n\ +しばらく やすんでたので\n\ +こんなにみごとに、\n\ ふとっちゃいました。\n\ -ひさしぶりに やります?\n\ -では! いつものように,\n\ -レディ-!\n\ +ひさしぶりに やります?\n\ +では! いつものように、\n\ +レディー!\n\ \n\ - ゴ-!! やめとく")) +   ゴー!! やめとく")) DEFINE_DIALOG(DIALOG_165, 1, 4, 30, 200, _("\ -このクイの まわりを\n\ +このクイの まわりを\n\ クルクルまわって\n\ めをまわしても\n\ しりません。")) DEFINE_DIALOG(DIALOG_166, 1, 6, 30, 200, _("\ -きょうは トレ-ニングで\n\ -るすに してるッス!\n\ -オイラに ちょ-せん\n\ -したいひとは,またこんど\n\ -くるといいッス!\n\ - ノコノコ")) +きょうは トレーニングで\n\ +るすに してるッス!\n\ +オイラに ちょーせん\n\ +したいひとは、またこんど\n\ +くるといいッス!\n\ +       ノコノコ")) DEFINE_DIALOG(DIALOG_167, 1, 4, 30, 200, _("\ -『ピ-チの おしろ』\n\ - すぐそこ\n\ -Aボタン『ジャンプ』\n\ -Zボタン『しゃがむ』\n\ -Bボタン『カンバンよむ』\n\ - 『パンチ』\n\ - 『ものをもつ』\n\ +『ピーチの おしろ』\n\ +     すぐそこ\n\ +Aボタン『ジャンプ』\n\ +Zボタン『しゃがむ』\n\ +Bボタン『カンバンよむ』\n\ +    『パンチ』\n\ +    『ものをもつ』\n\ もういちどおす『なげる』")) DEFINE_DIALOG(DIALOG_168, 1, 4, 30, 200, _("\ -ア-ン,またまた \n\ +アーン、またまた \n\ ふんづけられちゃいました。\n\ -ハナチャン かんぜんに\n\ -おこったです!")) +ハナチャン かんぜんに\n\ +おこったです!")) DEFINE_DIALOG(DIALOG_169, 1, 5, 30, 200, _("\ -かってに はいるな!\n\ +かってに はいるな!\n\ この『どうくつ』に\n\ -むだんで はいるものには,\n\ -わざわいが おとずれる!\n\ - --せんちょうより")) +むだんで はいるものには、\n\ +わざわいが おとずれる!\n\ +  --せんちょうより")) diff --git a/tools/patch_libultra_math.c b/tools/patch_libultra_math.c index bf93cee..e6bdcc0 100644 --- a/tools/patch_libultra_math.c +++ b/tools/patch_libultra_math.c @@ -1,10 +1,126 @@ #include +#include +#include +#include -int main(int argc, char **argv) +/* from elf.h */ + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASS32 1 /* 32-bit objects */ + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ + +/* end from elf.h */ + +// This file will find all mips3 object files in an ar archive and set the ABI flags to O32 +// this allows gcc to link them with the mips2 object files. +// Irix CC doesn't set the elf e_flags properly. + +// the AR file is structured as followed +//"!" followed by 0x0A (linefeed) 8 characters +// then a file header that follows the following structure +// everything is represented using space padded characters +// the last two characters are alwos 0x60 0x0A +// then come the file contents +// you can find the location of the next header by adding file_size_in_bytes (after parsing) +// all file headers start at an even offset so if the file size in bytes is odd you have to add 1 +// the first two "files" are special. One is a symbol table with a pointer to the header of the file +// contaning the symbol the other is an extended list of filenames +struct ar_header { + char identifier[16]; + char file_modification_timestamp[12]; + char owner_id[6]; + char group_id[6]; + char file_mode[8]; + char file_size_in_bytes[10]; + char ending[2]; +}; + +//These constants found by inspecting output of objdump +#define FLAGS_MIPS3 0x20 +#define FLAGS_O32ABI 0x100000 +int main(int argc, char **argv) { FILE *f = fopen(argv[1], "r+"); - fseek(f, 0x24, SEEK_SET); - char byte = 0x10; - fwrite(&byte, sizeof(char), 1, f); + + if (f == NULL) { + printf("Failed to open file! %s\n", argv[1]); + return -1; + } + struct ar_header current_header; + fseek(f, 0x8, SEEK_SET); // skip header, this is safe enough given that we check to make sure the + // file header is valid + + while (1 == fread(¤t_header, sizeof(current_header), 1, f)) { + if (current_header.ending[0] != 0x60 && current_header.ending[1] != 0x0A) { + printf("Expected file header\n"); + return -1; + } + size_t filesize = atoi(current_header.file_size_in_bytes); + Elf32_Ehdr hdr; + if (filesize < sizeof(hdr) || (1 != fread(&hdr, sizeof(hdr), 1, f))) { + printf("Failed to read ELF header\n"); + return -1; + } + + if (strncmp((const char *) hdr.e_ident, ELFMAG, SELFMAG) == 0) { + // found an ELF file. + if (hdr.e_ident[EI_CLASS] != ELFCLASS32 || hdr.e_ident[EI_DATA] != ELFDATA2MSB) { + printf("Expected 32bit big endian object files\n"); + return -1; + } + + if ((hdr.e_flags & 0xFF) == FLAGS_MIPS3 && (hdr.e_flags & FLAGS_O32ABI) == 0) { + hdr.e_flags |= FLAGS_O32ABI; + fseek(f, -sizeof(hdr), SEEK_CUR); + if (1 != fwrite(&hdr, sizeof(hdr), 1, f)) { + printf("Failed to write back ELF header after patching.\n"); + return -1; + } + } + } + if (filesize % 2 == 1) + filesize++; + fseek(f, filesize - sizeof(hdr), SEEK_CUR); + } fclose(f); + return 0; }