From 9a801cb96d9d3198ce552ae71a06347ee95c1f68 Mon Sep 17 00:00:00 2001 From: n64 <> Date: Mon, 3 Feb 2020 00:51:26 -0500 Subject: [PATCH] refresh 6 --- CHANGES | 9 + Jenkinsfile | 23 +- Makefile | 23 +- actors/group5.h | 4 +- actors/mario/geo.inc.c | 146 +-- actors/tornado/geo.inc.c | 2 +- .../append_bubble_vertex_buffer.s} | 4 +- .../append_snowflake_vertex_buffer.s} | 4 +- .../eu/audio/alloc_bank_or_seq.s | 269 ++++ asm/non_matchings/eu/audio/func_eu_802e00d8.s | 88 ++ .../eu/audio/note_apply_headset_pan_effects.s | 263 ++++ .../eu/audio/prepare_reverb_ring_buffer.s | 179 +++ .../audio/seq_channel_layer_process_script.s | 781 ++++++++++++ .../eu/audio/sequence_channel_enable.s | 56 + .../audio/sequence_channel_process_script.s | 929 ++++++++++++++ .../audio/sequence_player_process_sequence.s | 698 +++++++++++ .../eu/audio/synthesis_do_one_audio_update.s | 331 +++++ .../eu/audio/synthesis_execute.s | 178 +++ .../eu/audio/synthesis_process_note.s | 657 ++++++++++ .../audio/synthesis_resample_and_mix_reverb.s | 220 ++++ .../handle_dialog_text_and_pages.s} | 58 +- asm/non_matchings/eu/libultra_unk_802aeeb0.s | 55 + asm/non_matchings/eu/libultra_unk_802aef80.s | 87 ++ asm/non_matchings/eu/play_sequence.s | 86 ++ .../eu/player_performed_grab_escape_action.s | 36 + asm/non_matchings/patch_audio_bank.s | 156 --- data/behavior_data.c | 8 +- enhancements/README.md | 54 +- enhancements/{record_demo => }/RecordDemo.js | 0 enhancements/crash.h | 29 - enhancements/crash.inc.c | 292 ----- enhancements/crash.inc.s | 158 --- enhancements/crash.patch | 529 ++++++++ enhancements/debug_box.h | 23 - enhancements/debug_box.inc.c | 248 ---- enhancements/debug_box.patch | 302 +++++ enhancements/dyn_light.inc.c | 172 --- enhancements/fps.inc.c | 59 - enhancements/fps.patch | 60 + enhancements/ique_support.patch | 312 +++++ enhancements/ique_support/README.md | 46 - enhancements/ique_support/consoleType.c | 11 - enhancements/ique_support/console_type.h | 7 - enhancements/ique_support/osEepromProbe.inc.c | 9 - enhancements/ique_support/osEepromRead.inc.c | 8 - enhancements/ique_support/osEepromWrite.inc.c | 8 - enhancements/ique_support/skGetId.s | 18 - enhancements/mem_error_screen.inc.c | 193 --- enhancements/mem_error_screen.patch | 298 +++++ enhancements/record_demo.patch | 177 +++ enhancements/record_demo/record_demo.inc.c | 163 --- extract_assets.py | 14 +- first-diff.py | 4 + include/PR/os_message.h | 1 + include/PR/os_misc.h | 2 +- include/PR/os_pi.h | 52 +- include/PR/os_thread.h | 2 +- include/audio_defines.h | 2 + include/behavior_data.h | 6 +- include/config.h | 6 +- include/macro_presets.h | 2 +- include/model_ids.h | 2 +- include/object_constants.h | 23 + include/object_fields.h | 6 +- include/segments.h | 9 + include/sm64.h | 4 +- include/text_strings.h.in | 179 +++ include/types.h | 24 +- levels/bbh/script.c | 2 +- levels/ending/geo.c | 3 + levels/intro/geo.c | 4 +- levels/menu/header.h | 5 + levels/menu/leveldata.c | 26 +- levels/scripts.c | 2 +- levels/sl/script.c | 1 + levels/ssl/script.c | 10 +- lib/PR/boot/F3D_boot_eu.bin | Bin 0 -> 204 bytes lib/PR/f3d/new/F3D_data_EU.bin | Bin 0 -> 2048 bytes lib/asm/__osExceptionPreamble.s | 474 ++++++- lib/asm/__os_eu_802ef550.s | 22 + lib/asm/osSetIntMask.s | 34 + lib/asm/parameters.s | 18 + lib/rsp.s | 9 + lib/src/D_802F4380.c | 147 +++ lib/src/EU_D_802f4330.c | 12 + lib/src/_Ldtob.c | 4 +- lib/src/__osDevMgrMain.c | 86 +- lib/src/__osGetCurrFaultedThread.c | 5 + lib/src/__osSyncPutChars.c | 1 + lib/src/__osViInit.c | 27 +- lib/src/func_802F4A20.c | 171 +++ lib/src/func_802F7140.c | 31 + lib/src/func_802F71A0.c | 36 + lib/src/func_802F71F0.c | 33 + lib/src/hardware.h | 42 + lib/src/kdebugserver.c | 2 +- lib/src/libultra_internal.h | 34 +- lib/src/new_func.h | 22 + lib/src/osContInit.c | 4 + lib/src/osCreatePiManager.c | 8 +- lib/src/osCreateThread.c | 2 +- lib/src/osCreateViManager.c | 1026 +-------------- lib/src/osEPiRawStartDma.c | 24 + lib/src/osInitialize.c | 32 + lib/src/osLeoDiskInit.c | 30 + lib/src/osPiRawStartDma.c | 27 + lib/src/osPiStartDma.c | 7 +- lib/src/osTimer.c | 5 +- lib/src/osViData.c | 76 ++ lib/src/osViTable.c | 975 +++++++++++++++ lib/src/unk_stack_data.c | 9 + sm64.ld | 278 ++++- src/audio/data.c | 266 +++- src/audio/data.h | 63 +- src/audio/effects.c | 265 +++- src/audio/effects.h | 4 + src/audio/external.c | 551 +++++++- src/audio/external.h | 6 +- src/audio/globals_end.c | 2 + src/audio/internal.h | 541 +++++--- src/audio/load.c | 466 +++++-- src/audio/load.h | 24 +- src/audio/memory.c | 357 +++++- src/audio/memory.h | 6 + src/audio/playback.c | 453 ++++++- src/audio/playback.h | 10 + src/audio/port_eu.c | 326 +++++ src/audio/seqplayer.c | 656 +++++++++- src/audio/synthesis.c | 674 +++++++++- src/audio/synthesis.h | 51 +- src/buffers/buffers.c | 33 +- src/engine/geo_layout.c | 2 +- src/engine/level_script.c | 8 + src/engine/math_util.c | 11 +- src/engine/surface_collision.c | 30 +- src/engine/surface_load.c | 17 +- src/game/area.c | 2 +- src/game/behavior_actions.c | 11 +- src/game/behavior_actions.h | 2 +- src/game/behaviors/activated_bf_plat.inc.c | 2 +- src/game/behaviors/bobomb.inc.c | 7 +- src/game/behaviors/boo.inc.c | 9 +- src/game/behaviors/bowser.inc.c | 8 +- src/game/behaviors/bully.inc.c | 4 +- src/game/behaviors/butterfly.inc.c | 2 +- src/game/behaviors/cap.inc.c | 10 +- src/game/behaviors/chain_chomp.inc.c | 2 +- src/game/behaviors/cloud.inc.c | 4 +- src/game/behaviors/coffin.inc.c | 140 ++- src/game/behaviors/coin.inc.c | 4 +- src/game/behaviors/door.inc.c | 16 +- src/game/behaviors/dorrie.inc.c | 10 +- src/game/behaviors/elevator.inc.c | 4 +- src/game/behaviors/enemy_lakitu.inc.c | 2 +- src/game/behaviors/fire_piranha_plant.inc.c | 6 +- src/game/behaviors/fish.inc.c | 20 +- src/game/behaviors/floating_platform.inc.c | 8 +- src/game/behaviors/goomba.inc.c | 3 +- src/game/behaviors/hoot.inc.c | 6 +- src/game/behaviors/intro_lakitu.inc.c | 4 + src/game/behaviors/klepto.inc.c | 2 +- src/game/behaviors/moneybag.inc.c | 2 +- src/game/behaviors/monty_mole.inc.c | 16 +- src/game/behaviors/mr_blizzard.inc.c | 34 +- src/game/behaviors/piranha_plant.inc.c | 2 +- src/game/behaviors/pokey.inc.c | 4 +- src/game/behaviors/rolling_log.inc.c | 4 +- src/game/behaviors/ttc_moving_bar.inc.c | 2 +- src/game/behaviors/ttc_treadmill.inc.c | 7 - src/game/behaviors/tuxie.inc.c | 2 +- src/game/behaviors/tweester.inc.c | 132 +- src/game/behaviors/water_bomb.inc.c | 18 +- src/game/behaviors/wiggler.inc.c | 29 +- src/game/camera.c | 1011 ++++++++------- src/game/camera.h | 16 +- src/game/crash_screen.c | 60 +- src/game/debug.c | 5 +- src/game/display.c | 13 +- src/game/envfx_bubbles.c | 54 +- src/game/envfx_snow.c | 14 +- src/game/game.c | 13 +- src/game/geo_misc.c | 5 +- src/game/geo_misc.h | 11 + src/game/ingame_menu.c | 58 +- src/game/interaction.c | 13 +- src/game/interaction.h | 2 +- src/game/level_update.c | 50 +- src/game/main.c | 12 +- src/game/mario.c | 13 +- src/game/mario_actions_airborne.c | 14 +- src/game/mario_actions_cutscene.c | 102 +- src/game/mario_actions_moving.c | 20 +- src/game/mario_actions_object.c | 6 +- src/game/mario_actions_stationary.c | 2 +- src/game/mario_actions_submerged.c | 22 +- src/game/mario_misc.c | 389 +++--- src/game/mario_misc.h | 15 +- src/game/mario_step.c | 6 +- src/game/memory.c | 31 +- src/game/moving_texture.c | 23 +- src/game/obj_behaviors.c | 15 +- src/game/obj_behaviors_2.c | 23 +- src/game/object_helpers.c | 122 +- src/game/object_helpers.h | 8 +- src/game/object_list_processor.c | 28 +- src/game/object_list_processor.h | 17 + src/game/paintings.c | 7 +- src/game/print.c | 8 +- src/game/room.c | 21 - src/game/room.h | 23 - src/game/save_file.c | 17 +- src/game/save_file.h | 12 +- src/game/segment7.h | 10 + src/game/shadow.c | 6 +- src/game/skybox.c | 7 +- src/game/spawn_object.c | 24 +- src/goddard/draw_objects.c | 1 - src/goddard/dynlist_proc.c | 1 - src/goddard/joints.c | 5 + src/goddard/renderer.c | 23 + src/goddard/shape_helper.c | 3 + src/menu/file_select.c | 1107 +++++++++++++---- src/menu/file_select.h | 23 +- src/menu/intro_geo.c | 14 +- src/menu/intro_geo.h | 10 +- src/menu/star_select.c | 95 +- text/define_courses.inc.c | 30 + text/define_text.inc.c | 33 +- text/us/dialogs.h | 51 +- tools/aiff_extract_codebook.c | 27 +- tools/apply_patch.sh | 27 + tools/create_patch.sh | 25 + tools/libmio0.c | 31 +- tools/patch_libmalloc.py | 58 + tools/revert_patch.sh | 28 + undefined_syms.txt | 9 +- 236 files changed, 17101 insertions(+), 4820 deletions(-) rename asm/non_matchings/{append_bubble_vertex_buffer_eu.s => eu/append_bubble_vertex_buffer.s} (98%) rename asm/non_matchings/{append_snowflake_vertex_buffer_eu.s => eu/append_snowflake_vertex_buffer.s} (99%) create mode 100644 asm/non_matchings/eu/audio/alloc_bank_or_seq.s create mode 100644 asm/non_matchings/eu/audio/func_eu_802e00d8.s create mode 100644 asm/non_matchings/eu/audio/note_apply_headset_pan_effects.s create mode 100644 asm/non_matchings/eu/audio/prepare_reverb_ring_buffer.s create mode 100644 asm/non_matchings/eu/audio/seq_channel_layer_process_script.s create mode 100644 asm/non_matchings/eu/audio/sequence_channel_enable.s create mode 100644 asm/non_matchings/eu/audio/sequence_channel_process_script.s create mode 100644 asm/non_matchings/eu/audio/sequence_player_process_sequence.s create mode 100644 asm/non_matchings/eu/audio/synthesis_do_one_audio_update.s create mode 100644 asm/non_matchings/eu/audio/synthesis_execute.s create mode 100644 asm/non_matchings/eu/audio/synthesis_process_note.s create mode 100644 asm/non_matchings/eu/audio/synthesis_resample_and_mix_reverb.s rename asm/non_matchings/{handle_dialog_text_and_pages_eu.s => eu/handle_dialog_text_and_pages.s} (99%) create mode 100644 asm/non_matchings/eu/libultra_unk_802aeeb0.s create mode 100644 asm/non_matchings/eu/libultra_unk_802aef80.s create mode 100644 asm/non_matchings/eu/play_sequence.s create mode 100644 asm/non_matchings/eu/player_performed_grab_escape_action.s delete mode 100644 asm/non_matchings/patch_audio_bank.s rename enhancements/{record_demo => }/RecordDemo.js (100%) delete mode 100644 enhancements/crash.h delete mode 100644 enhancements/crash.inc.c delete mode 100644 enhancements/crash.inc.s create mode 100644 enhancements/crash.patch delete mode 100644 enhancements/debug_box.h delete mode 100644 enhancements/debug_box.inc.c create mode 100644 enhancements/debug_box.patch delete mode 100644 enhancements/dyn_light.inc.c delete mode 100644 enhancements/fps.inc.c create mode 100644 enhancements/fps.patch create mode 100644 enhancements/ique_support.patch delete mode 100644 enhancements/ique_support/README.md delete mode 100644 enhancements/ique_support/consoleType.c delete mode 100644 enhancements/ique_support/console_type.h delete mode 100644 enhancements/ique_support/osEepromProbe.inc.c delete mode 100644 enhancements/ique_support/osEepromRead.inc.c delete mode 100644 enhancements/ique_support/osEepromWrite.inc.c delete mode 100644 enhancements/ique_support/skGetId.s delete mode 100644 enhancements/mem_error_screen.inc.c create mode 100644 enhancements/mem_error_screen.patch create mode 100644 enhancements/record_demo.patch delete mode 100644 enhancements/record_demo/record_demo.inc.c create mode 100644 lib/PR/boot/F3D_boot_eu.bin create mode 100644 lib/PR/f3d/new/F3D_data_EU.bin create mode 100644 lib/asm/__os_eu_802ef550.s create mode 100644 lib/asm/parameters.s create mode 100644 lib/src/D_802F4380.c create mode 100644 lib/src/EU_D_802f4330.c create mode 100644 lib/src/__osGetCurrFaultedThread.c create mode 100644 lib/src/func_802F4A20.c create mode 100644 lib/src/func_802F7140.c create mode 100644 lib/src/func_802F71A0.c create mode 100644 lib/src/func_802F71F0.c create mode 100644 lib/src/new_func.h create mode 100644 lib/src/osEPiRawStartDma.c create mode 100644 lib/src/osLeoDiskInit.c create mode 100644 lib/src/osViTable.c create mode 100644 lib/src/unk_stack_data.c create mode 100644 src/audio/port_eu.c delete mode 100644 src/game/room.c delete mode 100644 src/game/room.h create mode 100644 text/define_courses.inc.c create mode 100644 tools/apply_patch.sh create mode 100644 tools/create_patch.sh create mode 100644 tools/patch_libmalloc.py create mode 100644 tools/revert_patch.sh diff --git a/CHANGES b/CHANGES index 193c0b8..939b7cb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +Refresh #6 +1.) Make tools work on MinGW (#804) +2.) Document mario_misc (#628) +3.) add patch_libmalloc.py script to work around compiler crashes (#811) +4.) Label the coffins file. (#829) +5.) Convert enhancements into patches (#827) +6.) Document Tweester.inc.c (#840) +7.) EU OK and cleanup EU (#782) + Refresh #5 1.) mem_error_screen.inc.c updated for C (#775) 2.) updated patch_libultra_math to work directly on libultra.a (#781) diff --git a/Jenkinsfile b/Jenkinsfile index 2bb4d8f..eee93a9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -17,14 +17,33 @@ pipeline { sh './extract_assets.py jp us eu' } } + stage('Build U Source') { + steps { + sh 'make -j4 VERSION=us' + } + } + stage('Build E Source') { + steps { + sh 'make -j4 VERSION=eu' + } + } stage('Build J Source') { steps { sh 'make -j4 VERSION=jp' } } - stage('Build U Source') { + stage('Test Enhancements') { steps { - sh 'make -j4 VERSION=us' + sh ''' + set -e + for f in enhancements/*.patch + do + git clean -fd . + git checkout -- . + echo 'y' | tools/apply_patch.sh "$f" + make -j4 VERSION=us COMPARE=0 + done + ''' } } } diff --git a/Makefile b/Makefile index 26c76d3..dfe087e 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,6 @@ ifeq ($(VERSION),us) TARGET := sm64.us else ifeq ($(VERSION),eu) - $(warning Building EU is experimental and is prone to breaking. Try at your own risk.) VERSION_CFLAGS := -DVERSION_EU VERSION_ASFLAGS := --defsym VERSION_EU=1 GRUCODE_CFLAGS := -DF3D_NEW @@ -193,7 +192,7 @@ GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d # Files with GLOBAL_ASM blocks -GLOBAL_ASM_C_FILES != grep -rl 'GLOBAL_ASM(' $(wildcard src/audio/*.c) $(wildcard src/game/*.c) +GLOBAL_ASM_C_FILES != grep -rl 'GLOBAL_ASM(' $(wildcard src/**/*.c) GLOBAL_ASM_O_FILES = $(foreach file,$(GLOBAL_ASM_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) GLOBAL_ASM_DEP = $(BUILD_DIR)/src/audio/non_matching_dep @@ -316,10 +315,14 @@ $(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in ifeq ($(VERSION),eu) TEXT_DIRS := text/de text/us text/fr -# EU encoded text inserted into individual segment 0x19 files +# EU encoded text inserted into individual segment 0x19 files, +# and course data also duplicated in leveldata.c $(BUILD_DIR)/bin/eu/translation_en.o: $(BUILD_DIR)/text/us/define_text.inc.c $(BUILD_DIR)/bin/eu/translation_de.o: $(BUILD_DIR)/text/de/define_text.inc.c $(BUILD_DIR)/bin/eu/translation_fr.o: $(BUILD_DIR)/text/fr/define_text.inc.c +$(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/us/define_courses.inc.c +$(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/de/define_courses.inc.c +$(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/fr/define_courses.inc.c else TEXT_DIRS := text/$(VERSION) @@ -328,6 +331,10 @@ TEXT_DIRS := text/$(VERSION) $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c endif +$(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h + $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/ + $(TEXTCONV) charmap.txt $@ $@ + $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/ $(TEXTCONV) charmap.txt $@ $@ @@ -443,6 +450,9 @@ $(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/* # Source code +$(BUILD_DIR)/levels/%/leveldata.o: OPT_FLAGS := -g +$(BUILD_DIR)/actors/%.o: OPT_FLAGS := -g +$(BUILD_DIR)/bin/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1 $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 @@ -460,6 +470,13 @@ ifeq ($(VERSION),eu) $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 +$(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 + +# enable loop unrolling except for external.c (external.c might also have used +# unrolling, but it makes one loop harder to match) +$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 +$(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 +$(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 endif ifeq ($(NON_MATCHING),0) diff --git a/actors/group5.h b/actors/group5.h index 0eb83f8..9135cdb 100644 --- a/actors/group5.h +++ b/actors/group5.h @@ -77,9 +77,9 @@ extern const Gfx pokey_seg5_dl_05012808[]; extern const Gfx pokey_seg5_dl_05013078[]; extern const Gfx pokey_seg5_dl_050130B0[]; -// tornado +// tweester extern const Gfx tornado_seg5_dl_05014450[]; extern const Gfx tornado_seg5_dl_050145C0[]; -extern const GeoLayout tornado_seg5_geo_05014630[]; +extern const GeoLayout tweester_geo[]; #endif diff --git a/actors/mario/geo.inc.c b/actors/mario/geo.inc.c index 119f7f6..06978aa 100644 --- a/actors/mario/geo.inc.c +++ b/actors/mario/geo.inc.c @@ -2,7 +2,7 @@ // 0x170002E0 const GeoLayout mario_geo_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -32,7 +32,7 @@ const GeoLayout mario_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_cap_wings), // left @@ -40,7 +40,7 @@ const GeoLayout mario_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_cap_wings), // right @@ -56,7 +56,7 @@ const GeoLayout mario_geo_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_left_hand_closed), @@ -76,7 +76,7 @@ const GeoLayout mario_geo_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_right_hand_closed), @@ -106,7 +106,7 @@ const GeoLayout mario_geo_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_butt), // starts sharing solid color with mario_torso (blue) GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_torso), @@ -155,7 +155,7 @@ const GeoLayout mario_geo_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_right_foot), // stops sharing because foot has its solid color (brown) @@ -175,7 +175,7 @@ const GeoLayout mario_geo_medium_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_medium_poly_left_hand_closed), @@ -195,7 +195,7 @@ const GeoLayout mario_geo_medium_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_medium_poly_right_hand_closed), @@ -223,7 +223,7 @@ const GeoLayout mario_geo_medium_poly_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_medium_poly_butt), // starts sharing solid color with mario_torso (blue) GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_medium_poly_torso), @@ -272,7 +272,7 @@ const GeoLayout mario_geo_medium_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_medium_poly_right_foot), // stops sharing because foot has its solid color (brown) @@ -288,7 +288,7 @@ const GeoLayout mario_geo_medium_poly_body[] = { // 0x170009D4 const GeoLayout mario_geo_low_poly_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -318,7 +318,7 @@ const GeoLayout mario_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_cap_wings), // left @@ -326,7 +326,7 @@ const GeoLayout mario_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_cap_wings), // right @@ -342,7 +342,7 @@ const GeoLayout mario_geo_low_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_low_poly_left_hand_closed), @@ -362,7 +362,7 @@ const GeoLayout mario_geo_low_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_low_poly_right_hand_closed), @@ -390,7 +390,7 @@ const GeoLayout mario_geo_low_poly_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_low_poly_butt), // starts sharing solid color with mario_torso (blue) GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_low_poly_torso), @@ -439,7 +439,7 @@ const GeoLayout mario_geo_low_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_low_poly_right_foot), // stops sharing because foot has its solid color (brown) @@ -457,7 +457,7 @@ const GeoLayout mario_geo_low_poly_body[] = { // 0x17000DEC const GeoLayout mario_vanish_geo_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -487,7 +487,7 @@ const GeoLayout mario_vanish_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_cap_wings_transparent), @@ -495,7 +495,7 @@ const GeoLayout mario_vanish_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_cap_wings_transparent), @@ -511,7 +511,7 @@ const GeoLayout mario_vanish_geo_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_left_hand_closed), @@ -531,7 +531,7 @@ const GeoLayout mario_vanish_geo_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_right_hand_closed), @@ -561,7 +561,7 @@ const GeoLayout mario_vanish_geo_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_torso), @@ -610,7 +610,7 @@ const GeoLayout mario_vanish_geo_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_right_foot), @@ -630,7 +630,7 @@ const GeoLayout mario_vanish_geo_medium_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_medium_poly_left_hand_closed), @@ -650,7 +650,7 @@ const GeoLayout mario_vanish_geo_medium_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_medium_poly_right_hand_closed), @@ -678,7 +678,7 @@ const GeoLayout mario_vanish_geo_medium_poly_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_medium_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_medium_poly_torso), @@ -727,7 +727,7 @@ const GeoLayout mario_vanish_geo_medium_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_medium_poly_right_foot), @@ -743,7 +743,7 @@ const GeoLayout mario_vanish_geo_medium_poly_body[] = { // 0x170014E0 const GeoLayout mario_vanish_geo_low_poly_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -773,7 +773,7 @@ const GeoLayout mario_vanish_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_cap_wings_transparent), @@ -781,7 +781,7 @@ const GeoLayout mario_vanish_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_cap_wings_transparent), @@ -797,7 +797,7 @@ const GeoLayout mario_vanish_geo_low_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_low_poly_left_hand_closed), @@ -817,7 +817,7 @@ const GeoLayout mario_vanish_geo_low_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_low_poly_right_hand_closed), @@ -845,7 +845,7 @@ const GeoLayout mario_vanish_geo_low_poly_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_low_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_low_poly_torso), @@ -894,7 +894,7 @@ const GeoLayout mario_vanish_geo_low_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_low_poly_right_foot), @@ -912,7 +912,7 @@ const GeoLayout mario_vanish_geo_low_poly_body[] = { // 0x170018F8 const GeoLayout mario_metal_geo_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -922,7 +922,7 @@ const GeoLayout mario_metal_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_metal_cap_wings), // left @@ -930,7 +930,7 @@ const GeoLayout mario_metal_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_metal_cap_wings), // right @@ -946,7 +946,7 @@ const GeoLayout mario_metal_geo_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_left_hand_closed_shared_dl), @@ -966,7 +966,7 @@ const GeoLayout mario_metal_geo_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_right_hand_closed), @@ -996,7 +996,7 @@ const GeoLayout mario_metal_geo_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_metal_butt), // starts sharing metal texture with the dls below GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_metal_torso_shared_dl), @@ -1045,7 +1045,7 @@ const GeoLayout mario_metal_geo_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_right_foot), @@ -1065,7 +1065,7 @@ const GeoLayout mario_metal_geo_medium_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_medium_poly_left_hand_closed_shared_dl), @@ -1085,7 +1085,7 @@ const GeoLayout mario_metal_geo_medium_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_medium_poly_right_hand_closed), @@ -1113,7 +1113,7 @@ const GeoLayout mario_metal_geo_medium_poly_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_metal_medium_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_metal_medium_poly_torso), @@ -1162,7 +1162,7 @@ const GeoLayout mario_metal_geo_medium_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_medium_poly_right_foot), @@ -1178,7 +1178,7 @@ const GeoLayout mario_metal_geo_medium_poly_body[] = { // 0x17001F5C const GeoLayout mario_metal_geo_low_poly_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -1188,7 +1188,7 @@ const GeoLayout mario_metal_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_metal_cap_wings), @@ -1196,7 +1196,7 @@ const GeoLayout mario_metal_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_ALPHA, mario_metal_cap_wings), @@ -1212,7 +1212,7 @@ const GeoLayout mario_metal_geo_low_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_low_poly_left_hand_closed_shared_dl), @@ -1232,7 +1232,7 @@ const GeoLayout mario_metal_geo_low_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_low_poly_right_hand_closed), @@ -1260,7 +1260,7 @@ const GeoLayout mario_metal_geo_low_poly_body[] = { GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, mario_metal_low_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 68, 0, 0, mario_metal_low_poly_torso), @@ -1309,7 +1309,7 @@ const GeoLayout mario_metal_geo_low_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_OPAQUE, mario_metal_low_poly_right_foot), @@ -1327,7 +1327,7 @@ const GeoLayout mario_metal_geo_low_poly_body[] = { // 0x170022E4 const GeoLayout mario_metal_vanish_geo_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -1337,7 +1337,7 @@ const GeoLayout mario_metal_vanish_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_cap_wings_transparent), @@ -1345,7 +1345,7 @@ const GeoLayout mario_metal_vanish_geo_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_cap_wings_transparent), @@ -1361,7 +1361,7 @@ const GeoLayout mario_metal_vanish_geo_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_left_hand_closed_shared_dl), @@ -1381,7 +1381,7 @@ const GeoLayout mario_metal_vanish_geo_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_right_hand_closed), @@ -1411,7 +1411,7 @@ const GeoLayout mario_metal_vanish_geo_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_metal_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_metal_torso_shared_dl), @@ -1460,7 +1460,7 @@ const GeoLayout mario_metal_vanish_geo_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_right_foot), @@ -1480,7 +1480,7 @@ const GeoLayout mario_metal_vanish_geo_medium_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_medium_poly_left_hand_closed_shared_dl), @@ -1500,7 +1500,7 @@ const GeoLayout mario_metal_vanish_geo_medium_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_medium_poly_right_hand_closed), @@ -1528,7 +1528,7 @@ const GeoLayout mario_metal_vanish_geo_medium_poly_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_metal_medium_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_metal_medium_poly_torso), @@ -1580,7 +1580,7 @@ const GeoLayout mario_metal_vanish_geo_medium_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_medium_poly_right_foot), @@ -1596,7 +1596,7 @@ const GeoLayout mario_metal_vanish_geo_medium_poly_body[] = { // 0x17002958 const GeoLayout mario_metal_vanish_geo_low_poly_face_and_wings[] = { - GEO_ASM(0, Geo18_802773A4), + GEO_ASM(0, geo_mario_head_rotation), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_SWITCH_CASE(0, geo_switch_mario_cap_on_off), @@ -1606,7 +1606,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, -126, 22, -40, -135), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_80277824), + GEO_ASM(0, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_cap_wings_transparent), @@ -1614,7 +1614,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_face_and_wings[] = { GEO_CLOSE_NODE(), GEO_TRANSLATE_ROTATE(0, 142, -51, 126, -22, 40, -135), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_80277824), + GEO_ASM(1, geo_mario_rotate_wing_cap_wings), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_cap_wings_transparent), @@ -1630,7 +1630,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_left_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(1, Geo18_802775CC), + GEO_ASM(1, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_low_poly_left_hand_closed_shared_dl), @@ -1650,7 +1650,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_right_hand[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 60, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(0, Geo18_802775CC), + GEO_ASM(0, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_low_poly_right_hand_closed), @@ -1678,7 +1678,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_body[] = { GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, mario_metal_low_poly_butt), GEO_OPEN_NODE(), GEO_ASM(0, Geo18_802B1BB0), - GEO_ASM(0, Geo18_80277294), + GEO_ASM(0, geo_mario_tilt_torso), GEO_ROTATION_NODE(0x00, 0, 0, 0), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 68, 0, 0, mario_metal_low_poly_torso), @@ -1727,7 +1727,7 @@ const GeoLayout mario_metal_vanish_geo_low_poly_body[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 67, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802775CC), + GEO_ASM(2, geo_mario_hand_foot_scaler), GEO_SCALE(0x00, 65536), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, mario_metal_low_poly_right_foot), @@ -1812,7 +1812,7 @@ const GeoLayout mario_geo[] = { GEO_SCALE(0x00, 16384), GEO_OPEN_NODE(), GEO_ASM(0, geo_mirror_mario_backface_culling), - GEO_ASM(0, Geo18_802770A4), + GEO_ASM(0, geo_mirror_mario_set_alpha), GEO_SWITCH_CASE(0, geo_switch_mario_stand_run), GEO_OPEN_NODE(), GEO_BRANCH(1, mario_geo_load_body), diff --git a/actors/tornado/geo.inc.c b/actors/tornado/geo.inc.c index 7afa887..26f971c 100644 --- a/actors/tornado/geo.inc.c +++ b/actors/tornado/geo.inc.c @@ -1,5 +1,5 @@ // 0x05014630 -const GeoLayout tornado_seg5_geo_05014630[] = { +const GeoLayout tweester_geo[] = { GEO_CULLING_RADIUS(5000), GEO_OPEN_NODE(), GEO_DISPLAY_LIST(LAYER_TRANSPARENT, tornado_seg5_dl_050145C0), diff --git a/asm/non_matchings/append_bubble_vertex_buffer_eu.s b/asm/non_matchings/eu/append_bubble_vertex_buffer.s similarity index 98% rename from asm/non_matchings/append_bubble_vertex_buffer_eu.s rename to asm/non_matchings/eu/append_bubble_vertex_buffer.s index 39f9599..be164e8 100644 --- a/asm/non_matchings/append_bubble_vertex_buffer_eu.s +++ b/asm/non_matchings/eu/append_bubble_vertex_buffer.s @@ -53,14 +53,14 @@ glabel append_bubble_vertex_buffer /* 075AA4 802B62A4 0303C821 */ addu $t9, $t8, $v1 /* 075AA8 802B62A8 8F2E0004 */ lw $t6, 4($t9) /* 075AAC 802B62AC 17E00002 */ bnez $ra, .L802B62B8 -/* 075AB0 802B62B0 00000000 */ nop +/* 075AB0 802B62B0 00000000 */ nop /* 075AB4 802B62B4 0007000D */ break 7 .L802B62B8: /* 075AB8 802B62B8 2401FFFF */ li $at, -1 /* 075ABC 802B62BC 17E10004 */ bne $ra, $at, .L802B62D0 /* 075AC0 802B62C0 3C018000 */ lui $at, 0x8000 /* 075AC4 802B62C4 14C10002 */ bne $a2, $at, .L802B62D0 -/* 075AC8 802B62C8 00000000 */ nop +/* 075AC8 802B62C8 00000000 */ nop /* 075ACC 802B62CC 0006000D */ break 6 .L802B62D0: /* 075AD0 802B62D0 01EEC021 */ addu $t8, $t7, $t6 diff --git a/asm/non_matchings/append_snowflake_vertex_buffer_eu.s b/asm/non_matchings/eu/append_snowflake_vertex_buffer.s similarity index 99% rename from asm/non_matchings/append_snowflake_vertex_buffer_eu.s rename to asm/non_matchings/eu/append_snowflake_vertex_buffer.s index ad75e0d..7af0c77 100644 --- a/asm/non_matchings/append_snowflake_vertex_buffer_eu.s +++ b/asm/non_matchings/eu/append_snowflake_vertex_buffer.s @@ -57,14 +57,14 @@ glabel append_snowflake_vertex_buffer /* 074250 802B4A50 0303C821 */ addu $t9, $t8, $v1 /* 074254 802B4A54 8F2E0004 */ lw $t6, 4($t9) /* 074258 802B4A58 15800002 */ bnez $t4, .L802B4A64 -/* 07425C 802B4A5C 00000000 */ nop +/* 07425C 802B4A5C 00000000 */ nop /* 074260 802B4A60 0007000D */ break 7 .L802B4A64: /* 074264 802B4A64 2401FFFF */ li $at, -1 /* 074268 802B4A68 15810004 */ bne $t4, $at, .L802B4A7C /* 07426C 802B4A6C 3C018000 */ lui $at, 0x8000 /* 074270 802B4A70 14C10002 */ bne $a2, $at, .L802B4A7C -/* 074274 802B4A74 00000000 */ nop +/* 074274 802B4A74 00000000 */ nop /* 074278 802B4A78 0006000D */ break 6 .L802B4A7C: /* 07427C 802B4A7C 01EEC021 */ addu $t8, $t7, $t6 diff --git a/asm/non_matchings/eu/audio/alloc_bank_or_seq.s b/asm/non_matchings/eu/audio/alloc_bank_or_seq.s new file mode 100644 index 0000000..7935272 --- /dev/null +++ b/asm/non_matchings/eu/audio/alloc_bank_or_seq.s @@ -0,0 +1,269 @@ +glabel alloc_bank_or_seq +/* 0A1B94 802E2394 27BDFFA8 */ addiu $sp, $sp, -0x58 +/* 0A1B98 802E2398 AFB20020 */ sw $s2, 0x20($sp) +/* 0A1B9C 802E239C 00C09025 */ move $s2, $a2 +/* 0A1BA0 802E23A0 AFB1001C */ sw $s1, 0x1c($sp) +/* 0A1BA4 802E23A4 AFB00018 */ sw $s0, 0x18($sp) +/* 0A1BA8 802E23A8 00A08025 */ move $s0, $a1 +/* 0A1BAC 802E23AC 00808825 */ move $s1, $a0 +/* 0A1BB0 802E23B0 2406000C */ li $a2, 12 +/* 0A1BB4 802E23B4 AFBF0024 */ sw $ra, 0x24($sp) +/* 0A1BB8 802E23B8 8FA90068 */ lw $t1, 0x68($sp) +/* 0A1BBC 802E23BC 24080001 */ li $t0, 1 +.L80200850: +/* 0A1BC0 802E23C0 14E000AD */ bnez $a3, .L80200B08 +/* 0A1BC4 802E23C4 3C0E8022 */ lui $t6, %hi(gSeqLoadedPool) # $t6, 0x8022 +/* 0A1BC8 802E23C8 25CE2670 */ addiu $t6, %lo(gSeqLoadedPool) # addiu $t6, $t6, 0x2670 +/* 0A1BCC 802E23CC 162E0006 */ bne $s1, $t6, .L80200878 +/* 0A1BD0 802E23D0 26300194 */ addiu $s0, $s1, 0x194 +/* 0A1BD4 802E23D4 3C058022 */ lui $a1, %hi(gSeqLoadStatus) # $a1, 0x8022 +/* 0A1BD8 802E23D8 24A52C58 */ addiu $a1, %lo(gSeqLoadStatus) # addiu $a1, $a1, 0x2c58 +/* 0A1BDC 802E23DC AFA5003C */ sw $a1, 0x3c($sp) +/* 0A1BE0 802E23E0 10000009 */ b .L80200898 +/* 0A1BE4 802E23E4 A3A0003B */ sb $zero, 0x3b($sp) +.L80200878: +/* 0A1BE8 802E23E8 3C0F8022 */ lui $t7, %hi(gBankLoadedPool) # $t7, 0x8022 +/* 0A1BEC 802E23EC 25EF2840 */ addiu $t7, %lo(gBankLoadedPool) # addiu $t7, $t7, 0x2840 +/* 0A1BF0 802E23F0 162F0005 */ bne $s1, $t7, .L80200898 +/* 0A1BF4 802E23F4 3C058022 */ lui $a1, %hi(gBankLoadStatus) # $a1, 0x8022 +/* 0A1BF8 802E23F8 24A52C18 */ addiu $a1, %lo(gBankLoadStatus) # addiu $a1, $a1, 0x2c18 +/* 0A1BFC 802E23FC 240A0001 */ li $t2, 1 +/* 0A1C00 802E2400 A3AA003B */ sb $t2, 0x3b($sp) +/* 0A1C04 802E2404 AFA5003C */ sw $a1, 0x3c($sp) +.L80200898: +/* 0A1C08 802E2408 8E02001C */ lw $v0, 0x1c($s0) +/* 0A1C0C 802E240C 2407FFFF */ li $a3, -1 +/* 0A1C10 802E2410 8FA5003C */ lw $a1, 0x3c($sp) +/* 0A1C14 802E2414 14E20003 */ bne $a3, $v0, .L802008B4 +/* 0A1C18 802E2418 93AA003B */ lbu $t2, 0x3b($sp) +/* 0A1C1C 802E241C 10000003 */ b .L802008BC +/* 0A1C20 802E2420 00001825 */ move $v1, $zero +.L802008B4: +/* 0A1C24 802E2424 0045C021 */ addu $t8, $v0, $a1 +/* 0A1C28 802E2428 93030000 */ lbu $v1, ($t8) +.L802008BC: +/* 0A1C2C 802E242C 8E020028 */ lw $v0, 0x28($s0) +/* 0A1C30 802E2430 14E20003 */ bne $a3, $v0, .L802008D0 +/* 0A1C34 802E2434 0045C821 */ addu $t9, $v0, $a1 +/* 0A1C38 802E2438 10000002 */ b .L802008D4 +/* 0A1C3C 802E243C 00002025 */ move $a0, $zero +.L802008D0: +/* 0A1C40 802E2440 93240000 */ lbu $a0, ($t9) +.L802008D4: +/* 0A1C44 802E2444 14600003 */ bnez $v1, .L802008E4 +/* 0A1C48 802E2448 00601025 */ move $v0, $v1 +/* 0A1C4C 802E244C 1000001D */ b .L80200954 +/* 0A1C50 802E2450 AE000000 */ sw $zero, ($s0) +.L802008E4: +/* 0A1C54 802E2454 14800004 */ bnez $a0, .L802008F8 +/* 0A1C58 802E2458 00801825 */ move $v1, $a0 +/* 0A1C5C 802E245C 240B0001 */ li $t3, 1 +/* 0A1C60 802E2460 10000018 */ b .L80200954 +/* 0A1C64 802E2464 AE0B0000 */ sw $t3, ($s0) +.L802008F8: +/* 0A1C68 802E2468 24040003 */ li $a0, 3 +/* 0A1C6C 802E246C 14820003 */ bne $a0, $v0, .L8020090C +/* 0A1C70 802E2470 00000000 */ nop +/* 0A1C74 802E2474 50830014 */ beql $a0, $v1, .L80200958 +/* 0A1C78 802E2478 8E0E0000 */ lw $t6, ($s0) +.L8020090C: +/* 0A1C7C 802E247C 14820003 */ bne $a0, $v0, .L8020091C +/* 0A1C80 802E2480 00000000 */ nop +/* 0A1C84 802E2484 1000000F */ b .L80200954 +/* 0A1C88 802E2488 AE000000 */ sw $zero, ($s0) +.L8020091C: +/* 0A1C8C 802E248C 14830003 */ bne $a0, $v1, .L8020092C +/* 0A1C90 802E2490 240C0001 */ li $t4, 1 +/* 0A1C94 802E2494 1000000B */ b .L80200954 +/* 0A1C98 802E2498 AE0C0000 */ sw $t4, ($s0) +.L8020092C: +/* 0A1C9C 802E249C 11020003 */ beq $t0, $v0, .L8020093C +/* 0A1CA0 802E24A0 00000000 */ nop +/* 0A1CA4 802E24A4 10000007 */ b .L80200954 +/* 0A1CA8 802E24A8 AE000000 */ sw $zero, ($s0) +.L8020093C: +/* 0A1CAC 802E24AC 11030003 */ beq $t0, $v1, .L8020094C +/* 0A1CB0 802E24B0 240D0001 */ li $t5, 1 +/* 0A1CB4 802E24B4 10000003 */ b .L80200954 +/* 0A1CB8 802E24B8 AE0D0000 */ sw $t5, ($s0) +.L8020094C: +/* 0A1CBC 802E24BC 10000099 */ b .L80200BB4 +/* 0A1CC0 802E24C0 00001025 */ move $v0, $zero +.L80200954: +/* 0A1CC4 802E24C4 8E0E0000 */ lw $t6, ($s0) +.L80200958: +/* 0A1CC8 802E24C8 01C60019 */ multu $t6, $a2 +/* 0A1CCC 802E24CC 00007812 */ mflo $t7 +/* 0A1CD0 802E24D0 020FC021 */ addu $t8, $s0, $t7 +/* 0A1CD4 802E24D4 8F02001C */ lw $v0, 0x1c($t8) +/* 0A1CD8 802E24D8 10E20010 */ beq $a3, $v0, .L802009AC +/* 0A1CDC 802E24DC 00A2C821 */ addu $t9, $a1, $v0 +/* 0A1CE0 802E24E0 150A000E */ bne $t0, $t2, .L802009AC +/* 0A1CE4 802E24E4 A3200000 */ sb $zero, ($t9) +/* 0A1CE8 802E24E8 8E0B0000 */ lw $t3, ($s0) +/* 0A1CEC 802E24EC 01660019 */ multu $t3, $a2 +/* 0A1CF0 802E24F0 00006012 */ mflo $t4 +/* 0A1CF4 802E24F4 020C6821 */ addu $t5, $s0, $t4 +/* 0A1CF8 802E24F8 8DA4001C */ lw $a0, 0x1c($t5) +/* 0A1CFC 802E24FC A3AA003B */ sb $t2, 0x3b($sp) +/* 0A1D00 802E2500 AFA90068 */ sw $t1, 0x68($sp) +/* 0A1D04 802E2504 0C0B87A3 */ jal discard_bank +/* 0A1D08 802E2508 AFA5003C */ sw $a1, 0x3c($sp) +/* 0A1D0C 802E250C 8FA5003C */ lw $a1, 0x3c($sp) +/* 0A1D10 802E2510 24080001 */ li $t0, 1 +/* 0A1D14 802E2514 8FA90068 */ lw $t1, 0x68($sp) +/* 0A1D18 802E2518 93AA003B */ lbu $t2, 0x3b($sp) +.L802009AC: +/* 0A1D1C 802E251C 8E040000 */ lw $a0, ($s0) +/* 0A1D20 802E2520 24010001 */ li $at, 1 +/* 0A1D24 802E2524 26230198 */ addiu $v1, $s1, 0x198 +/* 0A1D28 802E2528 50800006 */ beql $a0, $zero, .L802009D4 +/* 0A1D2C 802E252C 8C6E0000 */ lw $t6, ($v1) +/* 0A1D30 802E2530 1081002B */ beq $a0, $at, .L80200A70 +/* 0A1D34 802E2534 26230198 */ addiu $v1, $s1, 0x198 +/* 0A1D38 802E2538 1000007A */ b .L80200BB4 +/* 0A1D3C 802E253C 00001025 */ move $v0, $zero +/* 0A1D40 802E2540 8C6E0000 */ lw $t6, ($v1) +.L802009D4: +/* 0A1D44 802E2544 AE09001C */ sw $t1, 0x1c($s0) +/* 0A1D48 802E2548 AE120018 */ sw $s2, 0x18($s0) +/* 0A1D4C 802E254C AE0E0014 */ sw $t6, 0x14($s0) +/* 0A1D50 802E2550 8C6F0000 */ lw $t7, ($v1) +/* 0A1D54 802E2554 01F21021 */ addu $v0, $t7, $s2 +/* 0A1D58 802E2558 AC620004 */ sw $v0, 4($v1) +/* 0A1D5C 802E255C 8E180020 */ lw $t8, 0x20($s0) +/* 0A1D60 802E2560 0302082B */ sltu $at, $t8, $v0 +/* 0A1D64 802E2564 50200019 */ beql $at, $zero, .L80200A5C +/* 0A1D68 802E2568 8E030014 */ lw $v1, 0x14($s0) +/* 0A1D6C 802E256C 8E190028 */ lw $t9, 0x28($s0) +/* 0A1D70 802E2570 00B95821 */ addu $t3, $a1, $t9 +/* 0A1D74 802E2574 11400005 */ beqz $t2, .L80200A1C +/* 0A1D78 802E2578 A1600000 */ sb $zero, ($t3) +/* 0A1D7C 802E257C 51480009 */ beql $t2, $t0, .L80200A34 +/* 0A1D80 802E2580 8E040028 */ lw $a0, 0x28($s0) +/* 0A1D84 802E2584 1000000B */ b .L80200A44 +/* 0A1D88 802E2588 240CFFFF */ li $t4, -1 +.L80200A1C: +/* 0A1D8C 802E258C 8E040028 */ lw $a0, 0x28($s0) +/* 0A1D90 802E2590 0C0B87DC */ jal discard_sequence +/* 0A1D94 802E2594 AFA3002C */ sw $v1, 0x2c($sp) +/* 0A1D98 802E2598 10000005 */ b .L80200A40 +/* 0A1D9C 802E259C 8FA3002C */ lw $v1, 0x2c($sp) +/* 0A1DA0 802E25A0 8E040028 */ lw $a0, 0x28($s0) +.L80200A34: +/* 0A1DA4 802E25A4 0C0B87A3 */ jal discard_bank +/* 0A1DA8 802E25A8 AFA3002C */ sw $v1, 0x2c($sp) +/* 0A1DAC 802E25AC 8FA3002C */ lw $v1, 0x2c($sp) +.L80200A40: +/* 0A1DB0 802E25B0 240CFFFF */ li $t4, -1 +.L80200A44: +/* 0A1DB4 802E25B4 AE0C0028 */ sw $t4, 0x28($s0) +/* 0A1DB8 802E25B8 8C6E0008 */ lw $t6, 8($v1) +/* 0A1DBC 802E25BC 8C6D0000 */ lw $t5, ($v1) +/* 0A1DC0 802E25C0 01AE7821 */ addu $t7, $t5, $t6 +/* 0A1DC4 802E25C4 AE0F0020 */ sw $t7, 0x20($s0) +/* 0A1DC8 802E25C8 8E030014 */ lw $v1, 0x14($s0) +.L80200A5C: +/* 0A1DCC 802E25CC 8E180000 */ lw $t8, ($s0) +/* 0A1DD0 802E25D0 00601025 */ move $v0, $v1 +/* 0A1DD4 802E25D4 3B190001 */ xori $t9, $t8, 1 +/* 0A1DD8 802E25D8 10000052 */ b .L80200BB4 +/* 0A1DDC 802E25DC AE190000 */ sw $t9, ($s0) +.L80200A70: +/* 0A1DE0 802E25E0 8C6B0000 */ lw $t3, ($v1) +/* 0A1DE4 802E25E4 8C6C0008 */ lw $t4, 8($v1) +/* 0A1DE8 802E25E8 AE090028 */ sw $t1, 0x28($s0) +/* 0A1DEC 802E25EC AE120024 */ sw $s2, 0x24($s0) +/* 0A1DF0 802E25F0 016C6821 */ addu $t5, $t3, $t4 +/* 0A1DF4 802E25F4 01B27023 */ subu $t6, $t5, $s2 +/* 0A1DF8 802E25F8 25C2FFF0 */ addiu $v0, $t6, -0x10 +/* 0A1DFC 802E25FC AE020020 */ sw $v0, 0x20($s0) +/* 0A1E00 802E2600 8C780004 */ lw $t8, 4($v1) +/* 0A1E04 802E2604 0058082B */ sltu $at, $v0, $t8 +/* 0A1E08 802E2608 10200017 */ beqz $at, .L80200AF8 +/* 0A1E0C 802E260C 00000000 */ nop +/* 0A1E10 802E2610 8E19001C */ lw $t9, 0x1c($s0) +/* 0A1E14 802E2614 00B95821 */ addu $t3, $a1, $t9 +/* 0A1E18 802E2618 11400005 */ beqz $t2, .L80200AC0 +/* 0A1E1C 802E261C A1600000 */ sb $zero, ($t3) +/* 0A1E20 802E2620 51480009 */ beql $t2, $t0, .L80200AD8 +/* 0A1E24 802E2624 8E04001C */ lw $a0, 0x1c($s0) +/* 0A1E28 802E2628 1000000B */ b .L80200AE8 +/* 0A1E2C 802E262C 240CFFFF */ li $t4, -1 +.L80200AC0: +/* 0A1E30 802E2630 8E04001C */ lw $a0, 0x1c($s0) +/* 0A1E34 802E2634 0C0B87DC */ jal discard_sequence +/* 0A1E38 802E2638 AFA3002C */ sw $v1, 0x2c($sp) +/* 0A1E3C 802E263C 10000005 */ b .L80200AE4 +/* 0A1E40 802E2640 8FA3002C */ lw $v1, 0x2c($sp) +/* 0A1E44 802E2644 8E04001C */ lw $a0, 0x1c($s0) +.L80200AD8: +/* 0A1E48 802E2648 0C0B87A3 */ jal discard_bank +/* 0A1E4C 802E264C AFA3002C */ sw $v1, 0x2c($sp) +/* 0A1E50 802E2650 8FA3002C */ lw $v1, 0x2c($sp) +.L80200AE4: +/* 0A1E54 802E2654 240CFFFF */ li $t4, -1 +.L80200AE8: +/* 0A1E58 802E2658 AE0C001C */ sw $t4, 0x1c($s0) +/* 0A1E5C 802E265C 8C6D0000 */ lw $t5, ($v1) +/* 0A1E60 802E2660 AC6D0004 */ sw $t5, 4($v1) +/* 0A1E64 802E2664 8E020020 */ lw $v0, 0x20($s0) +.L80200AF8: +/* 0A1E68 802E2668 1000FFD8 */ b .L80200A5C +/* 0A1E6C 802E266C 00401825 */ move $v1, $v0 +/* 0A1E70 802E2670 1000002C */ b .L80200BB4 +/* 0A1E74 802E2674 00001025 */ move $v0, $zero +.L80200B08: +/* 0A1E78 802E2678 02120019 */ multu $s0, $s2 +/* 0A1E7C 802E267C 26240004 */ addiu $a0, $s1, 4 +/* 0A1E80 802E2680 AFA70064 */ sw $a3, 0x64($sp) +/* 0A1E84 802E2684 AFA90068 */ sw $t1, 0x68($sp) +/* 0A1E88 802E2688 00002812 */ mflo $a1 +/* 0A1E8C 802E268C 0C0B87F8 */ jal soundAlloc +/* 0A1E90 802E2690 00000000 */ nop +/* 0A1E94 802E2694 8E2E0000 */ lw $t6, ($s1) +/* 0A1E98 802E2698 2406000C */ li $a2, 12 +/* 0A1E9C 802E269C 8FA70064 */ lw $a3, 0x64($sp) +/* 0A1EA0 802E26A0 01C60019 */ multu $t6, $a2 +/* 0A1EA4 802E26A4 8FA90068 */ lw $t1, 0x68($sp) +/* 0A1EA8 802E26A8 24080001 */ li $t0, 1 +/* 0A1EAC 802E26AC 24010002 */ li $at, 2 +/* 0A1EB0 802E26B0 00007812 */ mflo $t7 +/* 0A1EB4 802E26B4 022FC021 */ addu $t8, $s1, $t7 +/* 0A1EB8 802E26B8 14400009 */ bnez $v0, .L80200B70 +/* 0A1EBC 802E26BC AF020014 */ sw $v0, 0x14($t8) +/* 0A1EC0 802E26C0 10E80005 */ beq $a3, $t0, .L80200B68 +/* 0A1EC4 802E26C4 00000000 */ nop +/* 0A1EC8 802E26C8 54E10006 */ bnel $a3, $at, .L80200B74 +/* 0A1ECC 802E26CC 8E390000 */ lw $t9, ($s1) +/* 0A1ED0 802E26D0 1000FF3B */ b .L80200850 +/* 0A1ED4 802E26D4 00003825 */ move $a3, $zero +.L80200B68: +/* 0A1ED8 802E26D8 10000012 */ b .L80200BB4 +/* 0A1EDC 802E26DC 00001025 */ move $v0, $zero +.L80200B70: +/* 0A1EE0 802E26E0 8E390000 */ lw $t9, ($s1) +.L80200B74: +/* 0A1EE4 802E26E4 03260019 */ multu $t9, $a2 +/* 0A1EE8 802E26E8 00005812 */ mflo $t3 +/* 0A1EEC 802E26EC 022B6021 */ addu $t4, $s1, $t3 +/* 0A1EF0 802E26F0 AD89001C */ sw $t1, 0x1c($t4) +/* 0A1EF4 802E26F4 8E2D0000 */ lw $t5, ($s1) +/* 0A1EF8 802E26F8 01A60019 */ multu $t5, $a2 +/* 0A1EFC 802E26FC 00007012 */ mflo $t6 +/* 0A1F00 802E2700 022E7821 */ addu $t7, $s1, $t6 +/* 0A1F04 802E2704 ADF20018 */ sw $s2, 0x18($t7) +/* 0A1F08 802E2708 8E230000 */ lw $v1, ($s1) +/* 0A1F0C 802E270C 00660019 */ multu $v1, $a2 +/* 0A1F10 802E2710 246B0001 */ addiu $t3, $v1, 1 +/* 0A1F14 802E2714 0000C012 */ mflo $t8 +/* 0A1F18 802E2718 0238C821 */ addu $t9, $s1, $t8 +/* 0A1F1C 802E271C 8F220014 */ lw $v0, 0x14($t9) +/* 0A1F20 802E2720 AE2B0000 */ sw $t3, ($s1) +.L80200BB4: +/* 0A1F24 802E2724 8FBF0024 */ lw $ra, 0x24($sp) +/* 0A1F28 802E2728 8FB00018 */ lw $s0, 0x18($sp) +/* 0A1F2C 802E272C 8FB1001C */ lw $s1, 0x1c($sp) +/* 0A1F30 802E2730 8FB20020 */ lw $s2, 0x20($sp) +/* 0A1F34 802E2734 03E00008 */ jr $ra +/* 0A1F38 802E2738 27BD0058 */ addiu $sp, $sp, 0x58 diff --git a/asm/non_matchings/eu/audio/func_eu_802e00d8.s b/asm/non_matchings/eu/audio/func_eu_802e00d8.s new file mode 100644 index 0000000..740495c --- /dev/null +++ b/asm/non_matchings/eu/audio/func_eu_802e00d8.s @@ -0,0 +1,88 @@ +glabel func_eu_802e00d8 +/* 09F8D8 802E00D8 27BDFFD0 */ addiu $sp, $sp, -0x30 +/* 09F8DC 802E00DC AFA50034 */ sw $a1, 0x34($sp) +/* 09F8E0 802E00E0 87B80036 */ lh $t8, 0x36($sp) +/* 09F8E4 802E00E4 3C088022 */ lui $t0, %hi(gSynthesisReverbs) # $t0, 0x8022 +/* 09F8E8 802E00E8 2508C1B0 */ addiu $t0, %lo(gSynthesisReverbs) # addiu $t0, $t0, -0x3e50 +/* 09F8EC 802E00EC 0018C940 */ sll $t9, $t8, 5 +/* 09F8F0 802E00F0 0338C821 */ addu $t9, $t9, $t8 +/* 09F8F4 802E00F4 0019C8C0 */ sll $t9, $t9, 3 +/* 09F8F8 802E00F8 03281021 */ addu $v0, $t9, $t0 +/* 09F8FC 802E00FC 90490003 */ lbu $t1, 3($v0) +/* 09F900 802E0100 00067400 */ sll $t6, $a2, 0x10 +/* 09F904 802E0104 000E7C03 */ sra $t7, $t6, 0x10 +/* 09F908 802E0108 00095080 */ sll $t2, $t1, 2 +/* 09F90C 802E010C 01495023 */ subu $t2, $t2, $t1 +/* 09F910 802E0110 000A50C0 */ sll $t2, $t2, 3 +/* 09F914 802E0114 000F3880 */ sll $a3, $t7, 2 +/* 09F918 802E0118 01495021 */ addu $t2, $t2, $t1 +/* 09F91C 802E011C 904C0001 */ lbu $t4, 1($v0) +/* 09F920 802E0120 000A5080 */ sll $t2, $t2, 2 +/* 09F924 802E0124 00EF3821 */ addu $a3, $a3, $t7 +/* 09F928 802E0128 00073880 */ sll $a3, $a3, 2 +/* 09F92C 802E012C 004A5821 */ addu $t3, $v0, $t2 +/* 09F930 802E0130 AFB00020 */ sw $s0, 0x20($sp) +/* 09F934 802E0134 01671821 */ addu $v1, $t3, $a3 +/* 09F938 802E0138 00808025 */ move $s0, $a0 +/* 09F93C 802E013C AFBF0024 */ sw $ra, 0x24($sp) +/* 09F940 802E0140 AFA60038 */ sw $a2, 0x38($sp) +/* 09F944 802E0144 11800033 */ beqz $t4, .L80200BC4 +/* 09F948 802E0148 24630030 */ addiu $v1, $v1, 0x30 +/* 09F94C 802E014C 904D0004 */ lbu $t5, 4($v0) +/* 09F950 802E0150 24010001 */ li $at, 1 +/* 09F954 802E0154 3C190800 */ lui $t9, 0x800 +/* 09F958 802E0158 15A10018 */ bne $t5, $at, .L80200B6C +/* 09F95C 802E015C 3C080740 */ lui $t0, (0x07400280 >> 16) # lui $t0, 0x740 +/* 09F960 802E0160 87AE0036 */ lh $t6, 0x36($sp) +/* 09F964 802E0164 9466000E */ lhu $a2, 0xe($v1) +/* 09F968 802E0168 84670010 */ lh $a3, 0x10($v1) +/* 09F96C 802E016C AFA3002C */ sw $v1, 0x2c($sp) +/* 09F970 802E0170 24050740 */ li $a1, 1856 +/* 09F974 802E0174 0C0B7E65 */ jal synthesis_save_reverb_ring_buffer +/* 09F978 802E0178 AFAE0010 */ sw $t6, 0x10($sp) +/* 09F97C 802E017C 8FA3002C */ lw $v1, 0x2c($sp) +/* 09F980 802E0180 00408025 */ move $s0, $v0 +/* 09F984 802E0184 00402025 */ move $a0, $v0 +/* 09F988 802E0188 84670012 */ lh $a3, 0x12($v1) +/* 09F98C 802E018C 87B80036 */ lh $t8, 0x36($sp) +/* 09F990 802E0190 50E00021 */ beql $a3, $zero, .L80200BC8 +/* 09F994 802E0194 8FBF0024 */ lw $ra, 0x24($sp) +/* 09F998 802E0198 84650010 */ lh $a1, 0x10($v1) +/* 09F99C 802E019C AFB80010 */ sw $t8, 0x10($sp) +/* 09F9A0 802E01A0 00003025 */ move $a2, $zero +/* 09F9A4 802E01A4 24A50740 */ addiu $a1, $a1, 0x740 +/* 09F9A8 802E01A8 30AFFFFF */ andi $t7, $a1, 0xffff +/* 09F9AC 802E01AC 0C0B7E65 */ jal synthesis_save_reverb_ring_buffer +/* 09F9B0 802E01B0 01E02825 */ move $a1, $t7 +/* 09F9B4 802E01B4 10000017 */ b .L80200BC4 +/* 09F9B8 802E01B8 00408025 */ move $s0, $v0 +.L80200B6C: +/* 09F9BC 802E01BC 02001825 */ move $v1, $s0 +/* 09F9C0 802E01C0 26100008 */ addiu $s0, $s0, 8 +/* 09F9C4 802E01C4 35080280 */ ori $t0, (0x07400280 & 0xFFFF) # ori $t0, $t0, 0x280 +/* 09F9C8 802E01C8 AC680004 */ sw $t0, 4($v1) +/* 09F9CC 802E01CC AC790000 */ sw $t9, ($v1) +/* 09F9D0 802E01D0 02002025 */ move $a0, $s0 +/* 09F9D4 802E01D4 3C090600 */ lui $t1, 0x600 +/* 09F9D8 802E01D8 AC890000 */ sw $t1, ($a0) +/* 09F9DC 802E01DC 904A0003 */ lbu $t2, 3($v0) +/* 09F9E0 802E01E0 3C018000 */ lui $at, 0x8000 +/* 09F9E4 802E01E4 26100008 */ addiu $s0, $s0, 8 +/* 09F9E8 802E01E8 000A5880 */ sll $t3, $t2, 2 +/* 09F9EC 802E01EC 016A5823 */ subu $t3, $t3, $t2 +/* 09F9F0 802E01F0 000B58C0 */ sll $t3, $t3, 3 +/* 09F9F4 802E01F4 016A5821 */ addu $t3, $t3, $t2 +/* 09F9F8 802E01F8 000B5880 */ sll $t3, $t3, 2 +/* 09F9FC 802E01FC 004B6021 */ addu $t4, $v0, $t3 +/* 09FA00 802E0200 01876821 */ addu $t5, $t4, $a3 +/* 09FA04 802E0204 8DAE0034 */ lw $t6, 0x34($t5) +/* 09FA08 802E0208 01C17821 */ addu $t7, $t6, $at +/* 09FA0C 802E020C AC8F0004 */ sw $t7, 4($a0) +/* 09FA10 802E0210 A0400000 */ sb $zero, ($v0) +.L80200BC4: +/* 09FA14 802E0214 8FBF0024 */ lw $ra, 0x24($sp) +.L80200BC8: +/* 09FA18 802E0218 02001025 */ move $v0, $s0 +/* 09FA1C 802E021C 8FB00020 */ lw $s0, 0x20($sp) +/* 09FA20 802E0220 03E00008 */ jr $ra +/* 09FA24 802E0224 27BD0030 */ addiu $sp, $sp, 0x30 diff --git a/asm/non_matchings/eu/audio/note_apply_headset_pan_effects.s b/asm/non_matchings/eu/audio/note_apply_headset_pan_effects.s new file mode 100644 index 0000000..ec9f20a --- /dev/null +++ b/asm/non_matchings/eu/audio/note_apply_headset_pan_effects.s @@ -0,0 +1,263 @@ +glabel note_apply_headset_pan_effects +/* 0A0F98 802E1798 27BDFFD8 */ addiu $sp, $sp, -0x28 +/* 0A0F9C 802E179C 8FAE003C */ lw $t6, 0x3c($sp) +/* 0A0FA0 802E17A0 AFB00004 */ sw $s0, 4($sp) +/* 0A0FA4 802E17A4 24020001 */ li $v0, 1 +/* 0A0FA8 802E17A8 11C20006 */ beq $t6, $v0, .L80202174 +/* 0A0FAC 802E17AC 00C08025 */ move $s0, $a2 +/* 0A0FB0 802E17B0 24010002 */ li $at, 2 +/* 0A0FB4 802E17B4 11C10009 */ beq $t6, $at, .L8020218C +/* 0A0FB8 802E17B8 240A0600 */ li $t2, 1536 +/* 0A0FBC 802E17BC 100000E8 */ b .L80202510 +/* 0A0FC0 802E17C0 00801025 */ move $v0, $a0 +.L80202174: +/* 0A0FC4 802E17C4 90A60003 */ lbu $a2, 3($a1) +/* 0A0FC8 802E17C8 92080002 */ lbu $t0, 2($s0) +/* 0A0FCC 802E17CC 240A04C0 */ li $t2, 1216 +/* 0A0FD0 802E17D0 A2000003 */ sb $zero, 3($s0) +/* 0A0FD4 802E17D4 10000008 */ b .L802021A8 +/* 0A0FD8 802E17D8 A2060002 */ sb $a2, 2($s0) +.L8020218C: +/* 0A0FDC 802E17DC 90A60004 */ lbu $a2, 4($a1) +/* 0A0FE0 802E17E0 92080003 */ lbu $t0, 3($s0) +/* 0A0FE4 802E17E4 A2000002 */ sb $zero, 2($s0) +/* 0A0FE8 802E17E8 10000003 */ b .L802021A8 +/* 0A0FEC 802E17EC A2060003 */ sb $a2, 3($s0) +/* 0A0FF0 802E17F0 100000DB */ b .L80202510 +/* 0A0FF4 802E17F4 00801025 */ move $v0, $a0 +.L802021A8: +/* 0A0FF8 802E17F8 8FAF0038 */ lw $t7, 0x38($sp) +/* 0A0FFC 802E17FC 30E5FFFF */ andi $a1, $a3, 0xffff +/* 0A1000 802E1800 3C180A00 */ lui $t8, 0xa00 +/* 0A1004 802E1804 51E200A5 */ beql $t7, $v0, .L8020244C +/* 0A1008 802E1808 00801825 */ move $v1, $a0 +/* 0A100C 802E180C 15000047 */ bnez $t0, .L802022DC +/* 0A1010 802E1810 01002825 */ move $a1, $t0 +/* 0A1014 802E1814 00801825 */ move $v1, $a0 +/* 0A1018 802E1818 3C020A00 */ lui $v0, (0x0A000200 >> 16) # lui $v0, 0xa00 +/* 0A101C 802E181C 24840008 */ addiu $a0, $a0, 8 +/* 0A1020 802E1820 24180008 */ li $t8, 8 +/* 0A1024 802E1824 34420200 */ ori $v0, (0x0A000200 & 0xFFFF) # ori $v0, $v0, 0x200 +/* 0A1028 802E1828 AC780004 */ sw $t8, 4($v1) +/* 0A102C 802E182C 00805825 */ move $t3, $a0 +/* 0A1030 802E1830 3C190200 */ lui $t9, (0x02000008 >> 16) # lui $t9, 0x200 +/* 0A1034 802E1834 AC620000 */ sw $v0, ($v1) +/* 0A1038 802E1838 37390008 */ ori $t9, (0x02000008 & 0xFFFF) # ori $t9, $t9, 8 +/* 0A103C 802E183C 24840008 */ addiu $a0, $a0, 8 +/* 0A1040 802E1840 AD790000 */ sw $t9, ($t3) +/* 0A1044 802E1844 240E0008 */ li $t6, 8 +/* 0A1048 802E1848 00806025 */ move $t4, $a0 +/* 0A104C 802E184C AD6E0004 */ sw $t6, 4($t3) +/* 0A1050 802E1850 24840008 */ addiu $a0, $a0, 8 +/* 0A1054 802E1854 3C0F0010 */ lui $t7, (0x00100010 >> 16) # lui $t7, 0x10 +/* 0A1058 802E1858 35EF0010 */ ori $t7, (0x00100010 & 0xFFFF) # ori $t7, $t7, 0x10 +/* 0A105C 802E185C 00806825 */ move $t5, $a0 +/* 0A1060 802E1860 AD8F0004 */ sw $t7, 4($t4) +/* 0A1064 802E1864 AD820000 */ sw $v0, ($t4) +/* 0A1068 802E1868 24190020 */ li $t9, 32 +/* 0A106C 802E186C 3C180800 */ lui $t8, 0x800 +/* 0A1070 802E1870 ADB80000 */ sw $t8, ($t5) +/* 0A1074 802E1874 ADB90004 */ sw $t9, 4($t5) +/* 0A1078 802E1878 24840008 */ addiu $a0, $a0, 8 +/* 0A107C 802E187C AFA4000C */ sw $a0, 0xc($sp) +/* 0A1080 802E1880 8FAF000C */ lw $t7, 0xc($sp) +/* 0A1084 802E1884 3C0E0600 */ lui $t6, 0x600 +/* 0A1088 802E1888 3C098000 */ lui $t1, (0x80000090 >> 16) # lui $t1, 0x8000 +/* 0A108C 802E188C ADEE0000 */ sw $t6, ($t7) +/* 0A1090 802E1890 8E18000C */ lw $t8, 0xc($s0) +/* 0A1094 802E1894 35290090 */ ori $t1, (0x80000090 & 0xFFFF) # ori $t1, $t1, 0x90 +/* 0A1098 802E1898 00E67021 */ addu $t6, $a3, $a2 +/* 0A109C 802E189C 0309C821 */ addu $t9, $t8, $t1 +/* 0A10A0 802E18A0 0007C3C0 */ sll $t8, $a3, 0xf +/* 0A10A4 802E18A4 01C51823 */ subu $v1, $t6, $a1 +/* 0A10A8 802E18A8 ADF90004 */ sw $t9, 4($t7) +/* 0A10AC 802E18AC 24790008 */ addiu $t9, $v1, 8 +/* 0A10B0 802E18B0 0319001A */ div $zero, $t8, $t9 +/* 0A10B4 802E18B4 24840008 */ addiu $a0, $a0, 8 +/* 0A10B8 802E18B8 17200002 */ bnez $t9, .L80202274 +/* 0A10BC 802E18BC 00000000 */ nop +/* 0A10C0 802E18C0 0007000D */ break 7 +.L80202274: +/* 0A10C4 802E18C4 2401FFFF */ li $at, -1 +/* 0A10C8 802E18C8 17210004 */ bne $t9, $at, .L8020228C +/* 0A10CC 802E18CC 3C018000 */ lui $at, 0x8000 +/* 0A10D0 802E18D0 17010002 */ bne $t8, $at, .L8020228C +/* 0A10D4 802E18D4 00000000 */ nop +/* 0A10D8 802E18D8 0006000D */ break 6 +.L8020228C: +/* 0A10DC 802E18DC 00005812 */ mflo $t3 +/* 0A10E0 802E18E0 00806025 */ move $t4, $a0 +/* 0A10E4 802E18E4 316FFFFF */ andi $t7, $t3, 0xffff +/* 0A10E8 802E18E8 3C0E0800 */ lui $t6, (0x08000208 >> 16) # lui $t6, 0x800 +/* 0A10EC 802E18EC 35CE0208 */ ori $t6, (0x08000208 & 0xFFFF) # ori $t6, $t6, 0x208 +/* 0A10F0 802E18F0 24840008 */ addiu $a0, $a0, 8 +/* 0A10F4 802E18F4 3062FFFF */ andi $v0, $v1, 0xffff +/* 0A10F8 802E18F8 31F8FFFF */ andi $t8, $t7, 0xffff +/* 0A10FC 802E18FC 3C010500 */ lui $at, 0x500 +/* 0A1100 802E1900 AD820004 */ sw $v0, 4($t4) +/* 0A1104 802E1904 AD8E0000 */ sw $t6, ($t4) +/* 0A1108 802E1908 0301C825 */ or $t9, $t8, $at +/* 0A110C 802E190C 00806825 */ move $t5, $a0 +/* 0A1110 802E1910 01E05825 */ move $t3, $t7 +/* 0A1114 802E1914 ADB90000 */ sw $t9, ($t5) +/* 0A1118 802E1918 8E0F000C */ lw $t7, 0xc($s0) +/* 0A111C 802E191C 24840008 */ addiu $a0, $a0, 8 +/* 0A1120 802E1920 01E97021 */ addu $t6, $t7, $t1 +/* 0A1124 802E1924 10000038 */ b .L802023B8 +/* 0A1128 802E1928 ADAE0004 */ sw $t6, 4($t5) +.L802022DC: +/* 0A112C 802E192C 14C00014 */ bnez $a2, .L80202330 +/* 0A1130 802E1930 00C01025 */ move $v0, $a2 +/* 0A1134 802E1934 00E5C823 */ subu $t9, $a3, $a1 +/* 0A1138 802E1938 272FFFFC */ addiu $t7, $t9, -4 +/* 0A113C 802E193C 0007C3C0 */ sll $t8, $a3, 0xf +/* 0A1140 802E1940 030F001A */ div $zero, $t8, $t7 +/* 0A1144 802E1944 00005812 */ mflo $t3 +/* 0A1148 802E1948 316EFFFF */ andi $t6, $t3, 0xffff +/* 0A114C 802E194C 15E00002 */ bnez $t7, .L80202308 +/* 0A1150 802E1950 00000000 */ nop +/* 0A1154 802E1954 0007000D */ break 7 +.L80202308: +/* 0A1158 802E1958 2401FFFF */ li $at, -1 +/* 0A115C 802E195C 15E10004 */ bne $t7, $at, .L80202320 +/* 0A1160 802E1960 3C018000 */ lui $at, 0x8000 +/* 0A1164 802E1964 17010002 */ bne $t8, $at, .L80202320 +/* 0A1168 802E1968 00000000 */ nop +/* 0A116C 802E196C 0006000D */ break 6 +.L80202320: +/* 0A1170 802E1970 00E2C821 */ addu $t9, $a3, $v0 +/* 0A1174 802E1974 03251823 */ subu $v1, $t9, $a1 +/* 0A1178 802E1978 10000011 */ b .L80202370 +/* 0A117C 802E197C 01C05825 */ move $t3, $t6 +.L80202330: +/* 0A1180 802E1980 00E2C021 */ addu $t8, $a3, $v0 +/* 0A1184 802E1984 03051823 */ subu $v1, $t8, $a1 +/* 0A1188 802E1988 00077BC0 */ sll $t7, $a3, 0xf +/* 0A118C 802E198C 01E3001A */ div $zero, $t7, $v1 +/* 0A1190 802E1990 00005812 */ mflo $t3 +/* 0A1194 802E1994 316EFFFF */ andi $t6, $t3, 0xffff +/* 0A1198 802E1998 01C05825 */ move $t3, $t6 +/* 0A119C 802E199C 14600002 */ bnez $v1, .L80202358 +/* 0A11A0 802E19A0 00000000 */ nop +/* 0A11A4 802E19A4 0007000D */ break 7 +.L80202358: +/* 0A11A8 802E19A8 2401FFFF */ li $at, -1 +/* 0A11AC 802E19AC 14610004 */ bne $v1, $at, .L80202370 +/* 0A11B0 802E19B0 3C018000 */ lui $at, 0x8000 +/* 0A11B4 802E19B4 15E10002 */ bne $t7, $at, .L80202370 +/* 0A11B8 802E19B8 00000000 */ nop +/* 0A11BC 802E19BC 0006000D */ break 6 +.L80202370: +/* 0A11C0 802E19C0 00806025 */ move $t4, $a0 +/* 0A11C4 802E19C4 3C190800 */ lui $t9, (0x08000200 >> 16) # lui $t9, 0x800 +/* 0A11C8 802E19C8 37390200 */ ori $t9, (0x08000200 & 0xFFFF) # ori $t9, $t9, 0x200 +/* 0A11CC 802E19CC 24840008 */ addiu $a0, $a0, 8 +/* 0A11D0 802E19D0 3062FFFF */ andi $v0, $v1, 0xffff +/* 0A11D4 802E19D4 3178FFFF */ andi $t8, $t3, 0xffff +/* 0A11D8 802E19D8 3C010500 */ lui $at, 0x500 +/* 0A11DC 802E19DC AD820004 */ sw $v0, 4($t4) +/* 0A11E0 802E19E0 AD990000 */ sw $t9, ($t4) +/* 0A11E4 802E19E4 03017825 */ or $t7, $t8, $at +/* 0A11E8 802E19E8 00806825 */ move $t5, $a0 +/* 0A11EC 802E19EC ADAF0000 */ sw $t7, ($t5) +/* 0A11F0 802E19F0 8E0E000C */ lw $t6, 0xc($s0) +/* 0A11F4 802E19F4 3C098000 */ lui $t1, %hi(0x80000004) # $t1, 0x8000 +/* 0A11F8 802E19F8 35290090 */ ori $t1, (0x80000090 & 0xFFFF) # ori $t1, $t1, 0x90 +/* 0A11FC 802E19FC 01C9C821 */ addu $t9, $t6, $t1 +/* 0A1200 802E1A00 ADB90004 */ sw $t9, 4($t5) +/* 0A1204 802E1A04 24840008 */ addiu $a0, $a0, 8 +.L802023B8: +/* 0A1208 802E1A08 10A0001B */ beqz $a1, .L80202428 +/* 0A120C 802E1A0C 00801825 */ move $v1, $a0 +/* 0A1210 802E1A10 00801825 */ move $v1, $a0 +/* 0A1214 802E1A14 3C180800 */ lui $t8, (0x08000200 >> 16) # lui $t8, 0x800 +/* 0A1218 802E1A18 37180200 */ ori $t8, (0x08000200 & 0xFFFF) # ori $t8, $t8, 0x200 +/* 0A121C 802E1A1C 24840008 */ addiu $a0, $a0, 8 +/* 0A1220 802E1A20 310FFFFF */ andi $t7, $t0, 0xffff +/* 0A1224 802E1A24 AC6F0004 */ sw $t7, 4($v1) +/* 0A1228 802E1A28 AC780000 */ sw $t8, ($v1) +/* 0A122C 802E1A2C 00804825 */ move $t1, $a0 +/* 0A1230 802E1A30 3C0E0400 */ lui $t6, 0x400 +/* 0A1234 802E1A34 AD2E0000 */ sw $t6, ($t1) +/* 0A1238 802E1A38 8E19000C */ lw $t9, 0xc($s0) +/* 0A123C 802E1A3C 3C018000 */ lui $at, (0x800000B0 >> 16) # lui $at, 0x8000 +/* 0A1240 802E1A40 342100B0 */ ori $at, (0x800000B0 & 0xFFFF) # ori $at, $at, 0xb0 +/* 0A1244 802E1A44 0321C021 */ addu $t8, $t9, $at +/* 0A1248 802E1A48 AD380004 */ sw $t8, %lo(0x80000004)($t1) +/* 0A124C 802E1A4C 24840008 */ addiu $a0, $a0, 8 +/* 0A1250 802E1A50 00805825 */ move $t3, $a0 +/* 0A1254 802E1A54 24B90200 */ addiu $t9, $a1, 0x200 +/* 0A1258 802E1A58 3C0F0A00 */ lui $t7, 0xa00 +/* 0A125C 802E1A5C AD6F0000 */ sw $t7, ($t3) +/* 0A1260 802E1A60 0019C400 */ sll $t8, $t9, 0x10 +/* 0A1264 802E1A64 03027825 */ or $t7, $t8, $v0 +/* 0A1268 802E1A68 AD6F0004 */ sw $t7, 4($t3) +/* 0A126C 802E1A6C 24840008 */ addiu $a0, $a0, 8 +/* 0A1270 802E1A70 1000001C */ b .L80202494 +/* 0A1274 802E1A74 30E5FFFF */ andi $a1, $a3, 0xffff +.L80202428: +/* 0A1278 802E1A78 3C010200 */ lui $at, 0x200 +/* 0A127C 802E1A7C 0041C825 */ or $t9, $v0, $at +/* 0A1280 802E1A80 3C0E0A00 */ lui $t6, 0xa00 +/* 0A1284 802E1A84 AC6E0000 */ sw $t6, ($v1) +/* 0A1288 802E1A88 AC790004 */ sw $t9, 4($v1) +/* 0A128C 802E1A8C 24840008 */ addiu $a0, $a0, 8 +/* 0A1290 802E1A90 10000014 */ b .L80202494 +/* 0A1294 802E1A94 30E5FFFF */ andi $a1, $a3, 0xffff +/* 0A1298 802E1A98 00801825 */ move $v1, $a0 +.L8020244C: +/* 0A129C 802E1A9C 3C020A00 */ lui $v0, %hi(0x0A000004) # $v0, 0xa00 +/* 0A12A0 802E1AA0 24840008 */ addiu $a0, $a0, 8 +/* 0A12A4 802E1AA4 34420200 */ ori $v0, (0x0A000200 & 0xFFFF) # ori $v0, $v0, 0x200 +/* 0A12A8 802E1AA8 00804025 */ move $t0, $a0 +/* 0A12AC 802E1AAC AC620000 */ sw $v0, ($v1) +/* 0A12B0 802E1AB0 AC650004 */ sw $a1, 4($v1) +/* 0A12B4 802E1AB4 24CE0200 */ addiu $t6, $a2, 0x200 +/* 0A12B8 802E1AB8 000ECC00 */ sll $t9, $t6, 0x10 +/* 0A12BC 802E1ABC AD180000 */ sw $t8, ($t0) +/* 0A12C0 802E1AC0 24840008 */ addiu $a0, $a0, 8 +/* 0A12C4 802E1AC4 0325C025 */ or $t8, $t9, $a1 +/* 0A12C8 802E1AC8 00804825 */ move $t1, $a0 +/* 0A12CC 802E1ACC AD180004 */ sw $t8, 4($t0) +/* 0A12D0 802E1AD0 3C0F0200 */ lui $t7, (0x02000200 >> 16) # lui $t7, 0x200 +/* 0A12D4 802E1AD4 35EF0200 */ ori $t7, (0x02000200 & 0xFFFF) # ori $t7, $t7, 0x200 +/* 0A12D8 802E1AD8 AD2F0000 */ sw $t7, ($t1) +/* 0A12DC 802E1ADC AD260004 */ sw $a2, %lo(0x80000004)($t1) +/* 0A12E0 802E1AE0 24840008 */ addiu $a0, $a0, 8 +.L80202494: +/* 0A12E4 802E1AE4 10C00012 */ beqz $a2, .L802024E0 +/* 0A12E8 802E1AE8 00801025 */ move $v0, $a0 +/* 0A12EC 802E1AEC 3C0E0800 */ lui $t6, 0x800 +/* 0A12F0 802E1AF0 AC4E0000 */ sw $t6, ($v0) +/* 0A12F4 802E1AF4 24F80200 */ addiu $t8, $a3, 0x200 +/* 0A12F8 802E1AF8 00187C00 */ sll $t7, $t8, 0x10 +/* 0A12FC 802E1AFC 30CEFFFF */ andi $t6, $a2, 0xffff +/* 0A1300 802E1B00 01EEC825 */ or $t9, $t7, $t6 +/* 0A1304 802E1B04 24840008 */ addiu $a0, $a0, 8 +/* 0A1308 802E1B08 AC590004 */ sw $t9, %lo(0x0A000004)($v0) +/* 0A130C 802E1B0C 00801825 */ move $v1, $a0 +/* 0A1310 802E1B10 3C180600 */ lui $t8, 0x600 +/* 0A1314 802E1B14 AC780000 */ sw $t8, ($v1) +/* 0A1318 802E1B18 8E0F000C */ lw $t7, 0xc($s0) +/* 0A131C 802E1B1C 3C018000 */ lui $at, (0x800000B0 >> 16) # lui $at, 0x8000 +/* 0A1320 802E1B20 342100B0 */ ori $at, (0x800000B0 & 0xFFFF) # ori $at, $at, 0xb0 +/* 0A1324 802E1B24 01E17021 */ addu $t6, $t7, $at +/* 0A1328 802E1B28 AC6E0004 */ sw $t6, 4($v1) +/* 0A132C 802E1B2C 24840008 */ addiu $a0, $a0, 8 +.L802024E0: +/* 0A1330 802E1B30 24860008 */ addiu $a2, $a0, 8 +/* 0A1334 802E1B34 3C190800 */ lui $t9, 0x800 +/* 0A1338 802E1B38 AC990000 */ sw $t9, ($a0) +/* 0A133C 802E1B3C AC850004 */ sw $a1, 4($a0) +/* 0A1340 802E1B40 3C180C00 */ lui $t8, (0x0C007FFF >> 16) # lui $t8, 0xc00 +/* 0A1344 802E1B44 314FFFFF */ andi $t7, $t2, 0xffff +/* 0A1348 802E1B48 3C010200 */ lui $at, 0x200 +/* 0A134C 802E1B4C 01E17025 */ or $t6, $t7, $at +/* 0A1350 802E1B50 37187FFF */ ori $t8, (0x0C007FFF & 0xFFFF) # ori $t8, $t8, 0x7fff +/* 0A1354 802E1B54 ACD80000 */ sw $t8, ($a2) +/* 0A1358 802E1B58 ACCE0004 */ sw $t6, 4($a2) +/* 0A135C 802E1B5C 24C20008 */ addiu $v0, $a2, 8 +.L80202510: +/* 0A1360 802E1B60 8FB00004 */ lw $s0, 4($sp) +/* 0A1364 802E1B64 03E00008 */ jr $ra +/* 0A1368 802E1B68 27BD0028 */ addiu $sp, $sp, 0x28 diff --git a/asm/non_matchings/eu/audio/prepare_reverb_ring_buffer.s b/asm/non_matchings/eu/audio/prepare_reverb_ring_buffer.s new file mode 100644 index 0000000..70e5fe0 --- /dev/null +++ b/asm/non_matchings/eu/audio/prepare_reverb_ring_buffer.s @@ -0,0 +1,179 @@ +glabel prepare_reverb_ring_buffer +/* 09EE50 802DF650 00067140 */ sll $t6, $a2, 5 +/* 09EE54 802DF654 01C67021 */ addu $t6, $t6, $a2 +/* 09EE58 802DF658 3C0F8022 */ lui $t7, %hi(gSynthesisReverbs) # $t7, 0x8022 +/* 09EE5C 802DF65C 25EFC1B0 */ addiu $t7, %lo(gSynthesisReverbs) # addiu $t7, $t7, -0x3e50 +/* 09EE60 802DF660 000E70C0 */ sll $t6, $t6, 3 +/* 09EE64 802DF664 01CF3821 */ addu $a3, $t6, $t7 +/* 09EE68 802DF668 90F80004 */ lbu $t8, 4($a3) +/* 09EE6C 802DF66C 27BDFFC0 */ addiu $sp, $sp, -0x40 +/* 09EE70 802DF670 24010001 */ li $at, 1 +/* 09EE74 802DF674 AFBF0014 */ sw $ra, 0x14($sp) +/* 09EE78 802DF678 AFA40040 */ sw $a0, 0x40($sp) +/* 09EE7C 802DF67C 13010062 */ beq $t8, $at, .L802001B8 +/* 09EE80 802DF680 AFA50044 */ sw $a1, 0x44($sp) +/* 09EE84 802DF684 90F90002 */ lbu $t9, 2($a3) +/* 09EE88 802DF688 00056080 */ sll $t4, $a1, 2 +/* 09EE8C 802DF68C 01856021 */ addu $t4, $t4, $a1 +/* 09EE90 802DF690 5720005E */ bnezl $t9, .L802001BC +/* 09EE94 802DF694 90E90004 */ lbu $t1, 4($a3) +/* 09EE98 802DF698 90E80003 */ lbu $t0, 3($a3) +/* 09EE9C 802DF69C 000C6080 */ sll $t4, $t4, 2 +/* 09EEA0 802DF6A0 24050280 */ li $a1, 640 +/* 09EEA4 802DF6A4 00084880 */ sll $t1, $t0, 2 +/* 09EEA8 802DF6A8 01284823 */ subu $t1, $t1, $t0 +/* 09EEAC 802DF6AC 000948C0 */ sll $t1, $t1, 3 +/* 09EEB0 802DF6B0 01284821 */ addu $t1, $t1, $t0 +/* 09EEB4 802DF6B4 00094880 */ sll $t1, $t1, 2 +/* 09EEB8 802DF6B8 00E95021 */ addu $t2, $a3, $t1 +/* 09EEBC 802DF6BC 014C3021 */ addu $a2, $t2, $t4 +/* 09EEC0 802DF6C0 24C60030 */ addiu $a2, $a2, 0x30 +/* 09EEC4 802DF6C4 8CC40004 */ lw $a0, 4($a2) +/* 09EEC8 802DF6C8 AFA70018 */ sw $a3, 0x18($sp) +/* 09EECC 802DF6CC 0C0BC448 */ jal osInvalDCache +/* 09EED0 802DF6D0 AFA6003C */ sw $a2, 0x3c($sp) +/* 09EED4 802DF6D4 8FA6003C */ lw $a2, 0x3c($sp) +/* 09EED8 802DF6D8 8FA70018 */ lw $a3, 0x18($sp) +/* 09EEDC 802DF6DC 00002825 */ move $a1, $zero +/* 09EEE0 802DF6E0 84CD0010 */ lh $t5, 0x10($a2) +/* 09EEE4 802DF6E4 00002025 */ move $a0, $zero +/* 09EEE8 802DF6E8 05A10003 */ bgez $t5, .L802000A8 +/* 09EEEC 802DF6EC 000D7043 */ sra $t6, $t5, 1 +/* 09EEF0 802DF6F0 25A10001 */ addiu $at, $t5, 1 +/* 09EEF4 802DF6F4 00017043 */ sra $t6, $at, 1 +.L802000A8: +/* 09EEF8 802DF6F8 59C00023 */ blezl $t6, .L80200138 +/* 09EEFC 802DF6FC 84CE0012 */ lh $t6, 0x12($a2) +/* 09EF00 802DF700 00001025 */ move $v0, $zero +/* 09EF04 802DF704 8CCF0004 */ lw $t7, 4($a2) +.L802000B8: +/* 09EF08 802DF708 8CC9000C */ lw $t1, 0xc($a2) +/* 09EF0C 802DF70C 8CE80018 */ lw $t0, 0x18($a3) +/* 09EF10 802DF710 00051840 */ sll $v1, $a1, 1 +/* 09EF14 802DF714 01E3C021 */ addu $t8, $t7, $v1 +/* 09EF18 802DF718 87190000 */ lh $t9, ($t8) +/* 09EF1C 802DF71C 00095840 */ sll $t3, $t1, 1 +/* 09EF20 802DF720 010B5021 */ addu $t2, $t0, $t3 +/* 09EF24 802DF724 01426021 */ addu $t4, $t2, $v0 +/* 09EF28 802DF728 A5990000 */ sh $t9, ($t4) +/* 09EF2C 802DF72C 8CCD0008 */ lw $t5, 8($a2) +/* 09EF30 802DF730 8CC9000C */ lw $t1, 0xc($a2) +/* 09EF34 802DF734 8CF8001C */ lw $t8, 0x1c($a3) +/* 09EF38 802DF738 01A37021 */ addu $t6, $t5, $v1 +/* 09EF3C 802DF73C 85CF0000 */ lh $t7, ($t6) +/* 09EF40 802DF740 00094040 */ sll $t0, $t1, 1 +/* 09EF44 802DF744 03085821 */ addu $t3, $t8, $t0 +/* 09EF48 802DF748 01625021 */ addu $t2, $t3, $v0 +/* 09EF4C 802DF74C A54F0000 */ sh $t7, ($t2) +/* 09EF50 802DF750 84CC0010 */ lh $t4, 0x10($a2) +/* 09EF54 802DF754 90F90004 */ lbu $t9, 4($a3) +/* 09EF58 802DF758 24840001 */ addiu $a0, $a0, 1 +/* 09EF5C 802DF75C 24420002 */ addiu $v0, $v0, 2 +/* 09EF60 802DF760 00B92821 */ addu $a1, $a1, $t9 +/* 09EF64 802DF764 05810003 */ bgez $t4, .L80200124 +/* 09EF68 802DF768 000C6843 */ sra $t5, $t4, 1 +/* 09EF6C 802DF76C 25810001 */ addiu $at, $t4, 1 +/* 09EF70 802DF770 00016843 */ sra $t5, $at, 1 +.L80200124: +/* 09EF74 802DF774 008D082A */ slt $at, $a0, $t5 +/* 09EF78 802DF778 5420FFE3 */ bnezl $at, .L802000B8 +/* 09EF7C 802DF77C 8CCF0004 */ lw $t7, 4($a2) +/* 09EF80 802DF780 00002025 */ move $a0, $zero +/* 09EF84 802DF784 84CE0012 */ lh $t6, 0x12($a2) +.L80200138: +/* 09EF88 802DF788 05C10003 */ bgez $t6, .L80200148 +/* 09EF8C 802DF78C 000E4843 */ sra $t1, $t6, 1 +/* 09EF90 802DF790 25C10001 */ addiu $at, $t6, 1 +/* 09EF94 802DF794 00014843 */ sra $t1, $at, 1 +.L80200148: +/* 09EF98 802DF798 5920001C */ blezl $t1, .L802001BC +/* 09EF9C 802DF79C 90E90004 */ lbu $t1, 4($a3) +/* 09EFA0 802DF7A0 00001025 */ move $v0, $zero +/* 09EFA4 802DF7A4 8CD80004 */ lw $t8, 4($a2) +.L80200158: +/* 09EFA8 802DF7A8 00051840 */ sll $v1, $a1, 1 +/* 09EFAC 802DF7AC 8CEF0018 */ lw $t7, 0x18($a3) +/* 09EFB0 802DF7B0 03034021 */ addu $t0, $t8, $v1 +/* 09EFB4 802DF7B4 850B0000 */ lh $t3, ($t0) +/* 09EFB8 802DF7B8 01E25021 */ addu $t2, $t7, $v0 +/* 09EFBC 802DF7BC 24840001 */ addiu $a0, $a0, 1 +/* 09EFC0 802DF7C0 A54B0000 */ sh $t3, ($t2) +/* 09EFC4 802DF7C4 8CD90008 */ lw $t9, 8($a2) +/* 09EFC8 802DF7C8 8CEE001C */ lw $t6, 0x1c($a3) +/* 09EFCC 802DF7CC 03236021 */ addu $t4, $t9, $v1 +/* 09EFD0 802DF7D0 858D0000 */ lh $t5, ($t4) +/* 09EFD4 802DF7D4 01C24821 */ addu $t1, $t6, $v0 +/* 09EFD8 802DF7D8 24420002 */ addiu $v0, $v0, 2 +/* 09EFDC 802DF7DC A52D0000 */ sh $t5, ($t1) +/* 09EFE0 802DF7E0 84C80012 */ lh $t0, 0x12($a2) +/* 09EFE4 802DF7E4 90F80004 */ lbu $t8, 4($a3) +/* 09EFE8 802DF7E8 00B82821 */ addu $a1, $a1, $t8 +/* 09EFEC 802DF7EC 05010003 */ bgez $t0, .L802001AC +/* 09EFF0 802DF7F0 00087843 */ sra $t7, $t0, 1 +/* 09EFF4 802DF7F4 25010001 */ addiu $at, $t0, 1 +/* 09EFF8 802DF7F8 00017843 */ sra $t7, $at, 1 +.L802001AC: +/* 09EFFC 802DF7FC 008F082A */ slt $at, $a0, $t7 +/* 09F000 802DF800 5420FFE9 */ bnezl $at, .L80200158 +/* 09F004 802DF804 8CD80004 */ lw $t8, 4($a2) +.L802001B8: +/* 09F008 802DF808 90E90004 */ lbu $t1, 4($a3) +.L802001BC: +/* 09F00C 802DF80C 8FAD0040 */ lw $t5, 0x40($sp) +/* 09F010 802DF810 90EB0003 */ lbu $t3, 3($a3) +/* 09F014 802DF814 8FAC0044 */ lw $t4, 0x44($sp) +/* 09F018 802DF818 01A9001A */ div $zero, $t5, $t1 +/* 09F01C 802DF81C 000B5080 */ sll $t2, $t3, 2 +/* 09F020 802DF820 8CF8000C */ lw $t8, 0xc($a3) +/* 09F024 802DF824 014B5023 */ subu $t2, $t2, $t3 +/* 09F028 802DF828 8CEF0014 */ lw $t7, 0x14($a3) +/* 09F02C 802DF82C 000A50C0 */ sll $t2, $t2, 3 +/* 09F030 802DF830 00001012 */ mflo $v0 +/* 09F034 802DF834 014B5021 */ addu $t2, $t2, $t3 +/* 09F038 802DF838 000C7080 */ sll $t6, $t4, 2 +/* 09F03C 802DF83C 000A5080 */ sll $t2, $t2, 2 +/* 09F040 802DF840 01CC7021 */ addu $t6, $t6, $t4 +/* 09F044 802DF844 03024021 */ addu $t0, $t8, $v0 +/* 09F048 802DF848 000E7080 */ sll $t6, $t6, 2 +/* 09F04C 802DF84C 00EAC821 */ addu $t9, $a3, $t2 +/* 09F050 802DF850 010F1823 */ subu $v1, $t0, $t7 +/* 09F054 802DF854 032E3021 */ addu $a2, $t9, $t6 +/* 09F058 802DF858 24C60030 */ addiu $a2, $a2, 0x30 +/* 09F05C 802DF85C 15200002 */ bnez $t1, .L80200218 +/* 09F060 802DF860 00000000 */ nop +/* 09F064 802DF864 0007000D */ break 7 +.L80200218: +/* 09F068 802DF868 2401FFFF */ li $at, -1 +/* 09F06C 802DF86C 15210004 */ bne $t1, $at, .L80200230 +/* 09F070 802DF870 3C018000 */ lui $at, 0x8000 +/* 09F074 802DF874 15A10002 */ bne $t5, $at, .L80200230 +/* 09F078 802DF878 00000000 */ nop +/* 09F07C 802DF87C 0006000D */ break 6 +.L80200230: +/* 09F080 802DF880 00437023 */ subu $t6, $v0, $v1 +/* 09F084 802DF884 0461000A */ bgez $v1, .L80200260 +/* 09F088 802DF888 00034840 */ sll $t1, $v1, 1 +/* 09F08C 802DF88C 00025840 */ sll $t3, $v0, 1 +/* 09F090 802DF890 A4CB0010 */ sh $t3, 0x10($a2) +/* 09F094 802DF894 A4C00012 */ sh $zero, 0x12($a2) +/* 09F098 802DF898 8CEA000C */ lw $t2, 0xc($a3) +/* 09F09C 802DF89C ACCA000C */ sw $t2, 0xc($a2) +/* 09F0A0 802DF8A0 8CEC000C */ lw $t4, 0xc($a3) +/* 09F0A4 802DF8A4 0182C821 */ addu $t9, $t4, $v0 +/* 09F0A8 802DF8A8 10000007 */ b .L80200278 +/* 09F0AC 802DF8AC ACF9000C */ sw $t9, 0xc($a3) +.L80200260: +/* 09F0B0 802DF8B0 000E6840 */ sll $t5, $t6, 1 +/* 09F0B4 802DF8B4 A4CD0010 */ sh $t5, 0x10($a2) +/* 09F0B8 802DF8B8 A4C90012 */ sh $t1, 0x12($a2) +/* 09F0BC 802DF8BC 8CF8000C */ lw $t8, 0xc($a3) +/* 09F0C0 802DF8C0 ACD8000C */ sw $t8, 0xc($a2) +/* 09F0C4 802DF8C4 ACE3000C */ sw $v1, 0xc($a3) +.L80200278: +/* 09F0C8 802DF8C8 A4C20000 */ sh $v0, ($a2) +/* 09F0CC 802DF8CC 8FA80040 */ lw $t0, 0x40($sp) +/* 09F0D0 802DF8D0 A4C80002 */ sh $t0, 2($a2) +/* 09F0D4 802DF8D4 8FBF0014 */ lw $ra, 0x14($sp) +/* 09F0D8 802DF8D8 27BD0040 */ addiu $sp, $sp, 0x40 +/* 09F0DC 802DF8DC 03E00008 */ jr $ra +/* 09F0E0 802DF8E0 00000000 */ nop diff --git a/asm/non_matchings/eu/audio/seq_channel_layer_process_script.s b/asm/non_matchings/eu/audio/seq_channel_layer_process_script.s new file mode 100644 index 0000000..5afbfde --- /dev/null +++ b/asm/non_matchings/eu/audio/seq_channel_layer_process_script.s @@ -0,0 +1,781 @@ +.late_rodata +glabel jtbl_EU_803066A0 + .word L_EU_802E7960, L_EU_802E7B6C + .word L_EU_802E7B6C, L_EU_802E78F8 + .word L_EU_802E78C0, L_EU_802E7B6C + .word L_EU_802E7B6C, L_EU_802E7940 + .word L_EU_802E7880, L_EU_802E7B6C + .word L_EU_802E7B6C, L_EU_802E7848 + +glabel jtbl_EU_803066D0 + .word L_EU_802E7980, L_EU_802E79BC + .word L_EU_802E7A1C, L_EU_802E79E4 + .word L_EU_802E79E4, L_EU_802E7A30 + .word L_EU_802E7AA0, L_EU_802E7B28 + .word L_EU_802E79BC, L_EU_802E7980 + .word L_EU_802E7B30, L_EU_802E7B5C + +glabel jtbl_EU_80306700 + .word L_EU_802E7F48, L_EU_802E7F50 + .word L_EU_802E7F48, L_EU_802E7F50 + .word L_EU_802E7F48 + +.text +glabel seq_channel_layer_process_script +/* 0A6F08 802E7708 27BDFF90 */ addiu $sp, $sp, -0x70 +/* 0A6F0C 802E770C 240E0001 */ li $t6, 1 +/* 0A6F10 802E7710 AFBF002C */ sw $ra, 0x2c($sp) +/* 0A6F14 802E7714 AFB40028 */ sw $s4, 0x28($sp) +/* 0A6F18 802E7718 AFB30024 */ sw $s3, 0x24($sp) +/* 0A6F1C 802E771C AFB20020 */ sw $s2, 0x20($sp) +/* 0A6F20 802E7720 AFB1001C */ sw $s1, 0x1c($sp) +/* 0A6F24 802E7724 AFB00018 */ sw $s0, 0x18($sp) +/* 0A6F28 802E7728 AFAE0044 */ sw $t6, 0x44($sp) +/* 0A6F2C 802E772C 8C820000 */ lw $v0, ($a0) +/* 0A6F30 802E7730 00808825 */ move $s1, $a0 +/* 0A6F34 802E7734 00027FC2 */ srl $t7, $v0, 0x1f +/* 0A6F38 802E7738 51E0028E */ beql $t7, $zero, .L80202184 +/* 0A6F3C 802E773C 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A6F40 802E7740 84830038 */ lh $v1, 0x38($a0) +/* 0A6F44 802E7744 00024080 */ sll $t0, $v0, 2 +/* 0A6F48 802E7748 000278C0 */ sll $t7, $v0, 3 +/* 0A6F4C 802E774C 28610002 */ slti $at, $v1, 2 +/* 0A6F50 802E7750 1420000E */ bnez $at, .L8020179C +/* 0A6F54 802E7754 2478FFFF */ addiu $t8, $v1, -1 +/* 0A6F58 802E7758 05000285 */ bltz $t0, .L80202180 +/* 0A6F5C 802E775C A4980038 */ sh $t8, 0x38($a0) +/* 0A6F60 802E7760 8489003A */ lh $t1, 0x3a($a0) +/* 0A6F64 802E7764 848A0038 */ lh $t2, 0x38($a0) +/* 0A6F68 802E7768 012A082A */ slt $at, $t1, $t2 +/* 0A6F6C 802E776C 54200281 */ bnezl $at, .L80202184 +/* 0A6F70 802E7770 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A6F74 802E7774 0C0B95B3 */ jal seq_channel_layer_note_decay +/* 0A6F78 802E7778 00000000 */ nop +/* 0A6F7C 802E777C 922C0000 */ lbu $t4, ($s1) +/* 0A6F80 802E7780 358D0020 */ ori $t5, $t4, 0x20 +/* 0A6F84 802E7784 1000027A */ b .L80202180 +/* 0A6F88 802E7788 A22D0000 */ sb $t5, ($s1) +.L8020179C: +/* 0A6F8C 802E778C 05E20004 */ bltzl $t7, .L802017B0 +/* 0A6F90 802E7790 92220008 */ lbu $v0, 8($s1) +/* 0A6F94 802E7794 0C0B95B3 */ jal seq_channel_layer_note_decay +/* 0A6F98 802E7798 02202025 */ move $a0, $s1 +/* 0A6F9C 802E779C 92220008 */ lbu $v0, 8($s1) +.L802017B0: +/* 0A6FA0 802E77A0 2401FF7F */ li $at, -129 +/* 0A6FA4 802E77A4 0041C024 */ and $t8, $v0, $at +/* 0A6FA8 802E77A8 24010001 */ li $at, 1 +/* 0A6FAC 802E77AC 13010003 */ beq $t8, $at, .L802017CC +/* 0A6FB0 802E77B0 24010002 */ li $at, 2 +/* 0A6FB4 802E77B4 57010003 */ bnel $t8, $at, .L802017D4 +/* 0A6FB8 802E77B8 8E22004C */ lw $v0, 0x4c($s1) +.L802017CC: +/* 0A6FBC 802E77BC A2200008 */ sb $zero, 8($s1) +/* 0A6FC0 802E77C0 8E22004C */ lw $v0, 0x4c($s1) +.L802017D4: +/* 0A6FC4 802E77C4 92280000 */ lbu $t0, ($s1) +/* 0A6FC8 802E77C8 26300050 */ addiu $s0, $s1, 0x50 +/* 0A6FCC 802E77CC 8C540044 */ lw $s4, 0x44($v0) +/* 0A6FD0 802E77D0 35090004 */ ori $t1, $t0, 4 +/* 0A6FD4 802E77D4 A2290000 */ sb $t1, ($s1) +/* 0A6FD8 802E77D8 97B3004A */ lhu $s3, 0x4a($sp) +/* 0A6FDC 802E77DC AFA20068 */ sw $v0, 0x68($sp) +.L802017F0: +/* 0A6FE0 802E77E0 0C0B9DA0 */ jal m64_read_u8 +/* 0A6FE4 802E77E4 02002025 */ move $a0, $s0 +/* 0A6FE8 802E77E8 284100C1 */ slti $at, $v0, 0xc1 +/* 0A6FEC 802E77EC 305200FF */ andi $s2, $v0, 0xff +/* 0A6FF0 802E77F0 142000F7 */ bnez $at, .L80201BE0 +/* 0A6FF4 802E77F4 00402825 */ move $a1, $v0 +/* 0A6FF8 802E77F8 284100CD */ slti $at, $v0, 0xcd +/* 0A6FFC 802E77FC 1420000A */ bnez $at, .L80201838 +/* 0A7000 802E7800 24ABFF3F */ addiu $t3, $a1, -0xc1 +/* 0A7004 802E7804 244AFF0C */ addiu $t2, $v0, -0xf4 +/* 0A7008 802E7808 2D41000C */ sltiu $at, $t2, 0xc +/* 0A700C 802E780C 102000D7 */ beqz $at, .L_EU_802E7B6C +/* 0A7010 802E7810 000A5080 */ sll $t2, $t2, 2 +/* 0A7014 802E7814 3C018030 */ lui $at, %hi(jtbl_EU_803066A0) +/* 0A7018 802E7818 002A0821 */ addu $at, $at, $t2 +/* 0A701C 802E781C 8C2A66A0 */ lw $t2, %lo(jtbl_EU_803066A0)($at) +/* 0A7020 802E7820 01400008 */ jr $t2 +/* 0A7024 802E7824 00000000 */ nop +.L80201838: +/* 0A7028 802E7828 2D61000C */ sltiu $at, $t3, 0xc +/* 0A702C 802E782C 102000CF */ beqz $at, .L_EU_802E7B6C +/* 0A7030 802E7830 000B5880 */ sll $t3, $t3, 2 +/* 0A7034 802E7834 3C018030 */ lui $at, %hi(jtbl_EU_803066D0) +/* 0A7038 802E7838 002B0821 */ addu $at, $at, $t3 +/* 0A703C 802E783C 8C2B66D0 */ lw $t3, %lo(jtbl_EU_803066D0)($at) +/* 0A7040 802E7840 01600008 */ jr $t3 +/* 0A7044 802E7844 00000000 */ nop +glabel L_EU_802E7848 +/* 0A7048 802E7848 92030018 */ lbu $v1, 0x18($s0) +/* 0A704C 802E784C 14600005 */ bnez $v1, .L80201874 +/* 0A7050 802E7850 2462FFFF */ addiu $v0, $v1, -1 +/* 0A7054 802E7854 0C0B9C1E */ jal seq_channel_layer_disable +/* 0A7058 802E7858 02202025 */ move $a0, $s1 +/* 0A705C 802E785C 10000245 */ b .L80202184 +/* 0A7060 802E7860 8FBF002C */ lw $ra, 0x2c($sp) +.L80201874: +/* 0A7064 802E7864 304C00FF */ andi $t4, $v0, 0xff +/* 0A7068 802E7868 000C6880 */ sll $t5, $t4, 2 +/* 0A706C 802E786C 020D7021 */ addu $t6, $s0, $t5 +/* 0A7070 802E7870 A20C0018 */ sb $t4, 0x18($s0) +/* 0A7074 802E7874 8DCF0004 */ lw $t7, 4($t6) +/* 0A7078 802E7878 1000FFD9 */ b .L802017F0 +/* 0A707C 802E787C AE0F0000 */ sw $t7, ($s0) +glabel L_EU_802E7880 +/* 0A7080 802E7880 0C0B9DA5 */ jal m64_read_s16 +/* 0A7084 802E7884 02002025 */ move $a0, $s0 +/* 0A7088 802E7888 92190018 */ lbu $t9, 0x18($s0) +/* 0A708C 802E788C 8E180000 */ lw $t8, ($s0) +/* 0A7090 802E7890 304DFFFF */ andi $t5, $v0, 0xffff +/* 0A7094 802E7894 00194080 */ sll $t0, $t9, 2 +/* 0A7098 802E7898 02084821 */ addu $t1, $s0, $t0 +/* 0A709C 802E789C AD380004 */ sw $t8, 4($t1) +/* 0A70A0 802E78A0 920A0018 */ lbu $t2, 0x18($s0) +/* 0A70A4 802E78A4 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A70A8 802E78A8 254B0001 */ addiu $t3, $t2, 1 +/* 0A70AC 802E78AC A20B0018 */ sb $t3, 0x18($s0) +/* 0A70B0 802E78B0 8E8C0014 */ lw $t4, 0x14($s4) +/* 0A70B4 802E78B4 018D7021 */ addu $t6, $t4, $t5 +/* 0A70B8 802E78B8 1000FFC9 */ b .L802017F0 +/* 0A70BC 802E78BC AE0E0000 */ sw $t6, ($s0) +glabel L_EU_802E78C0 +/* 0A70C0 802E78C0 0C0B9DA0 */ jal m64_read_u8 +/* 0A70C4 802E78C4 02002025 */ move $a0, $s0 +/* 0A70C8 802E78C8 920F0018 */ lbu $t7, 0x18($s0) +/* 0A70CC 802E78CC 020FC821 */ addu $t9, $s0, $t7 +/* 0A70D0 802E78D0 A3220014 */ sb $v0, 0x14($t9) +/* 0A70D4 802E78D4 92180018 */ lbu $t8, 0x18($s0) +/* 0A70D8 802E78D8 8E080000 */ lw $t0, ($s0) +/* 0A70DC 802E78DC 00184880 */ sll $t1, $t8, 2 +/* 0A70E0 802E78E0 02095021 */ addu $t2, $s0, $t1 +/* 0A70E4 802E78E4 AD480004 */ sw $t0, 4($t2) +/* 0A70E8 802E78E8 920B0018 */ lbu $t3, 0x18($s0) +/* 0A70EC 802E78EC 256C0001 */ addiu $t4, $t3, 1 +/* 0A70F0 802E78F0 1000FFBB */ b .L802017F0 +/* 0A70F4 802E78F4 A20C0018 */ sb $t4, 0x18($s0) +glabel L_EU_802E78F8 +/* 0A70F8 802E78F8 920D0018 */ lbu $t5, 0x18($s0) +/* 0A70FC 802E78FC 020D1021 */ addu $v0, $s0, $t5 +/* 0A7100 802E7900 904E0013 */ lbu $t6, 0x13($v0) +/* 0A7104 802E7904 25CFFFFF */ addiu $t7, $t6, -1 +/* 0A7108 802E7908 A04F0013 */ sb $t7, 0x13($v0) +/* 0A710C 802E790C 92030018 */ lbu $v1, 0x18($s0) +/* 0A7110 802E7910 0203C821 */ addu $t9, $s0, $v1 +/* 0A7114 802E7914 93380013 */ lbu $t8, 0x13($t9) +/* 0A7118 802E7918 00602025 */ move $a0, $v1 +/* 0A711C 802E791C 00044880 */ sll $t1, $a0, 2 +/* 0A7120 802E7920 13000005 */ beqz $t8, .L80201948 +/* 0A7124 802E7924 246BFFFF */ addiu $t3, $v1, -1 +/* 0A7128 802E7928 02094021 */ addu $t0, $s0, $t1 +/* 0A712C 802E792C 8D0A0000 */ lw $t2, ($t0) +/* 0A7130 802E7930 1000FFAB */ b .L802017F0 +/* 0A7134 802E7934 AE0A0000 */ sw $t2, ($s0) +.L80201948: +/* 0A7138 802E7938 1000FFA9 */ b .L802017F0 +/* 0A713C 802E793C A20B0018 */ sb $t3, 0x18($s0) +glabel L_EU_802E7940 +/* 0A7140 802E7940 0C0B9DA5 */ jal m64_read_s16 +/* 0A7144 802E7944 02002025 */ move $a0, $s0 +/* 0A7148 802E7948 8E8C0014 */ lw $t4, 0x14($s4) +/* 0A714C 802E794C 304DFFFF */ andi $t5, $v0, 0xffff +/* 0A7150 802E7950 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7154 802E7954 018D7021 */ addu $t6, $t4, $t5 +/* 0A7158 802E7958 1000FFA1 */ b .L802017F0 +/* 0A715C 802E795C AE0E0000 */ sw $t6, ($s0) +glabel L_EU_802E7960 +/* 0A7160 802E7960 0C0B9DA0 */ jal m64_read_u8 +/* 0A7164 802E7964 02002025 */ move $a0, $s0 +/* 0A7168 802E7968 8E0F0000 */ lw $t7, ($s0) +/* 0A716C 802E796C 0002CE00 */ sll $t9, $v0, 0x18 +/* 0A7170 802E7970 0019C603 */ sra $t8, $t9, 0x18 +/* 0A7174 802E7974 01F84821 */ addu $t1, $t7, $t8 +/* 0A7178 802E7978 1000FF99 */ b .L802017F0 +/* 0A717C 802E797C AE090000 */ sw $t1, ($s0) +glabel L_EU_802E7980 +/* 0A7180 802E7980 8E030000 */ lw $v1, ($s0) +/* 0A7184 802E7984 240100C1 */ li $at, 193 +/* 0A7188 802E7988 90640000 */ lbu $a0, ($v1) +/* 0A718C 802E798C 24680001 */ addiu $t0, $v1, 1 +/* 0A7190 802E7990 14A10008 */ bne $a1, $at, .L802019C4 +/* 0A7194 802E7994 AE080000 */ sw $t0, ($s0) +/* 0A7198 802E7998 00840019 */ multu $a0, $a0 +/* 0A719C 802E799C 00005012 */ mflo $t2 +/* 0A71A0 802E79A0 448A2000 */ mtc1 $t2, $f4 +/* 0A71A4 802E79A4 00000000 */ nop +/* 0A71A8 802E79A8 468021A0 */ cvt.s.w $f6, $f4 +/* 0A71AC 802E79AC 1000FF8C */ b .L802017F0 +/* 0A71B0 802E79B0 E6260028 */ swc1 $f6, 0x28($s1) +.L802019C4: +/* 0A71B4 802E79B4 1000FF8A */ b .L802017F0 +/* 0A71B8 802E79B8 A2240005 */ sb $a0, 5($s1) +glabel L_EU_802E79BC +/* 0A71BC 802E79BC 8E030000 */ lw $v1, ($s0) +/* 0A71C0 802E79C0 240100C9 */ li $at, 201 +/* 0A71C4 802E79C4 90640000 */ lbu $a0, ($v1) +/* 0A71C8 802E79C8 246B0001 */ addiu $t3, $v1, 1 +/* 0A71CC 802E79CC 14A10003 */ bne $a1, $at, .L802019EC +/* 0A71D0 802E79D0 AE0B0000 */ sw $t3, ($s0) +/* 0A71D4 802E79D4 1000FF82 */ b .L802017F0 +/* 0A71D8 802E79D8 A2240003 */ sb $a0, 3($s1) +.L802019EC: +/* 0A71DC 802E79DC 1000FF80 */ b .L802017F0 +/* 0A71E0 802E79E0 A6240022 */ sh $a0, 0x22($s1) +glabel L_EU_802E79E4 +/* 0A71E4 802E79E4 240100C4 */ li $at, 196 +/* 0A71E8 802E79E8 54A10006 */ bnel $a1, $at, .L80201A14 +/* 0A71EC 802E79EC 92390000 */ lbu $t9, ($s1) +/* 0A71F0 802E79F0 922D0000 */ lbu $t5, ($s1) +/* 0A71F4 802E79F4 35AE0010 */ ori $t6, $t5, 0x10 +/* 0A71F8 802E79F8 10000004 */ b .L80201A1C +/* 0A71FC 802E79FC A22E0000 */ sb $t6, ($s1) +/* 0A7200 802E7A00 92390000 */ lbu $t9, ($s1) +.L80201A14: +/* 0A7204 802E7A04 332FFFEF */ andi $t7, $t9, 0xffef +/* 0A7208 802E7A08 A22F0000 */ sb $t7, ($s1) +.L80201A1C: +/* 0A720C 802E7A0C 0C0B95B3 */ jal seq_channel_layer_note_decay +/* 0A7210 802E7A10 02202025 */ move $a0, $s1 +/* 0A7214 802E7A14 1000FF72 */ b .L802017F0 +/* 0A7218 802E7A18 00000000 */ nop +glabel L_EU_802E7A1C +/* 0A721C 802E7A1C 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7220 802E7A20 02002025 */ move $a0, $s0 +/* 0A7224 802E7A24 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7228 802E7A28 1000FF6D */ b .L802017F0 +/* 0A722C 802E7A2C A6220034 */ sh $v0, 0x34($s1) +glabel L_EU_802E7A30 +/* 0A7230 802E7A30 0C0B9DA0 */ jal m64_read_u8 +/* 0A7234 802E7A34 02002025 */ move $a0, $s0 +/* 0A7238 802E7A38 2841007F */ slti $at, $v0, 0x7f +/* 0A723C 802E7A3C 305200FF */ andi $s2, $v0, 0xff +/* 0A7240 802E7A40 1420000D */ bnez $at, .L80201A88 +/* 0A7244 802E7A44 00402825 */ move $a1, $v0 +/* 0A7248 802E7A48 2401007F */ li $at, 127 +/* 0A724C 802E7A4C 54410004 */ bnel $v0, $at, .L80201A70 +/* 0A7250 802E7A50 A2220001 */ sb $v0, 1($s1) +/* 0A7254 802E7A54 10000003 */ b .L80201A74 +/* 0A7258 802E7A58 A2200001 */ sb $zero, 1($s1) +/* 0A725C 802E7A5C A2220001 */ sb $v0, 1($s1) +.L80201A70: +/* 0A7260 802E7A60 AE200044 */ sw $zero, 0x44($s1) +.L80201A74: +/* 0A7264 802E7A64 240100FF */ li $at, 255 +/* 0A7268 802E7A68 14A1FF5D */ bne $a1, $at, .L802017F0 +/* 0A726C 802E7A6C 00000000 */ nop +/* 0A7270 802E7A70 1000FF5B */ b .L802017F0 +/* 0A7274 802E7A74 A2200018 */ sb $zero, 0x18($s1) +.L80201A88: +/* 0A7278 802E7A78 8FA40068 */ lw $a0, 0x68($sp) +/* 0A727C 802E7A7C 324500FF */ andi $a1, $s2, 0xff +/* 0A7280 802E7A80 26260044 */ addiu $a2, $s1, 0x44 +/* 0A7284 802E7A84 0C0BA064 */ jal get_instrument +/* 0A7288 802E7A88 26270018 */ addiu $a3, $s1, 0x18 +/* 0A728C 802E7A8C 1440FF54 */ bnez $v0, .L802017F0 +/* 0A7290 802E7A90 A2220001 */ sb $v0, 1($s1) +/* 0A7294 802E7A94 241800FF */ li $t8, 255 +/* 0A7298 802E7A98 1000FF51 */ b .L802017F0 +/* 0A729C 802E7A9C A2380001 */ sb $t8, 1($s1) +glabel L_EU_802E7AA0 +/* 0A72A0 802E7AA0 0C0B9DA0 */ jal m64_read_u8 +/* 0A72A4 802E7AA4 02002025 */ move $a0, $s0 +/* 0A72A8 802E7AA8 A2220008 */ sb $v0, 8($s1) +/* 0A72AC 802E7AAC 0C0B9DA0 */ jal m64_read_u8 +/* 0A72B0 802E7AB0 02002025 */ move $a0, $s0 +/* 0A72B4 802E7AB4 8FA90068 */ lw $t1, 0x68($sp) +/* 0A72B8 802E7AB8 862B0022 */ lh $t3, 0x22($s1) +/* 0A72BC 802E7ABC 868D000C */ lh $t5, 0xc($s4) +/* 0A72C0 802E7AC0 8528001E */ lh $t0, 0x1e($t1) +/* 0A72C4 802E7AC4 00485021 */ addu $t2, $v0, $t0 +/* 0A72C8 802E7AC8 014B6021 */ addu $t4, $t2, $t3 +/* 0A72CC 802E7ACC 018D9021 */ addu $s2, $t4, $t5 +/* 0A72D0 802E7AD0 324E00FF */ andi $t6, $s2, 0xff +/* 0A72D4 802E7AD4 29C10080 */ slti $at, $t6, 0x80 +/* 0A72D8 802E7AD8 14200002 */ bnez $at, .L80201AF4 +/* 0A72DC 802E7ADC 01C09025 */ move $s2, $t6 +/* 0A72E0 802E7AE0 00009025 */ move $s2, $zero +.L80201AF4: +/* 0A72E4 802E7AE4 92390008 */ lbu $t9, 8($s1) +/* 0A72E8 802E7AE8 A2320004 */ sb $s2, 4($s1) +/* 0A72EC 802E7AEC 332F0080 */ andi $t7, $t9, 0x80 +/* 0A72F0 802E7AF0 11E00008 */ beqz $t7, .L80201B24 +/* 0A72F4 802E7AF4 00000000 */ nop +/* 0A72F8 802E7AF8 8E180000 */ lw $t8, ($s0) +/* 0A72FC 802E7AFC 93090000 */ lbu $t1, ($t8) +/* 0A7300 802E7B00 A6290020 */ sh $t1, 0x20($s1) +/* 0A7304 802E7B04 8E080000 */ lw $t0, ($s0) +/* 0A7308 802E7B08 250A0001 */ addiu $t2, $t0, 1 +/* 0A730C 802E7B0C 1000FF34 */ b .L802017F0 +/* 0A7310 802E7B10 AE0A0000 */ sw $t2, ($s0) +.L80201B24: +/* 0A7314 802E7B14 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7318 802E7B18 02002025 */ move $a0, $s0 +/* 0A731C 802E7B1C 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7320 802E7B20 1000FF2F */ b .L802017F0 +/* 0A7324 802E7B24 A6220020 */ sh $v0, 0x20($s1) +glabel L_EU_802E7B28 +/* 0A7328 802E7B28 1000FF2D */ b .L802017F0 +/* 0A732C 802E7B2C A2200008 */ sb $zero, 8($s1) +glabel L_EU_802E7B30 +/* 0A7330 802E7B30 0C0B9DA5 */ jal m64_read_s16 +/* 0A7334 802E7B34 02002025 */ move $a0, $s0 +/* 0A7338 802E7B38 8E8B0014 */ lw $t3, 0x14($s4) +/* 0A733C 802E7B3C 304CFFFF */ andi $t4, $v0, 0xffff +/* 0A7340 802E7B40 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7344 802E7B44 016C6821 */ addu $t5, $t3, $t4 +/* 0A7348 802E7B48 AE2D001C */ sw $t5, 0x1c($s1) +/* 0A734C 802E7B4C 0C0B9DA0 */ jal m64_read_u8 +/* 0A7350 802E7B50 02002025 */ move $a0, $s0 +/* 0A7354 802E7B54 1000FF22 */ b .L802017F0 +/* 0A7358 802E7B58 A2220018 */ sb $v0, 0x18($s1) +glabel L_EU_802E7B5C +/* 0A735C 802E7B5C 92390000 */ lbu $t9, ($s1) +/* 0A7360 802E7B60 372F0002 */ ori $t7, $t9, 2 +/* 0A7364 802E7B64 1000FF1E */ b .L802017F0 +/* 0A7368 802E7B68 A22F0000 */ sb $t7, ($s1) +glabel L_EU_802E7B6C +.L_EU_802E7B6C: +/* 0A736C 802E7B6C 30A300F0 */ andi $v1, $a1, 0xf0 +/* 0A7370 802E7B70 240100D0 */ li $at, 208 +/* 0A7374 802E7B74 10610005 */ beq $v1, $at, .L80201B9C +/* 0A7378 802E7B78 240100E0 */ li $at, 224 +/* 0A737C 802E7B7C 5061000F */ beql $v1, $at, .L80201BCC +/* 0A7380 802E7B80 8E8B0090 */ lw $t3, 0x90($s4) +/* 0A7384 802E7B84 1000FF16 */ b .L802017F0 +/* 0A7388 802E7B88 00000000 */ nop +.L80201B9C: +/* 0A738C 802E7B8C 8E98008C */ lw $t8, 0x8c($s4) +/* 0A7390 802E7B90 30A9000F */ andi $t1, $a1, 0xf +/* 0A7394 802E7B94 03094021 */ addu $t0, $t8, $t1 +/* 0A7398 802E7B98 91130000 */ lbu $s3, ($t0) +/* 0A739C 802E7B9C 02730019 */ multu $s3, $s3 +/* 0A73A0 802E7BA0 00005012 */ mflo $t2 +/* 0A73A4 802E7BA4 448A4000 */ mtc1 $t2, $f8 +/* 0A73A8 802E7BA8 00000000 */ nop +/* 0A73AC 802E7BAC 468042A0 */ cvt.s.w $f10, $f8 +/* 0A73B0 802E7BB0 1000FF0B */ b .L802017F0 +/* 0A73B4 802E7BB4 E62A0028 */ swc1 $f10, 0x28($s1) +/* 0A73B8 802E7BB8 8E8B0090 */ lw $t3, 0x90($s4) +.L80201BCC: +/* 0A73BC 802E7BBC 30AC000F */ andi $t4, $a1, 0xf +/* 0A73C0 802E7BC0 016C6821 */ addu $t5, $t3, $t4 +/* 0A73C4 802E7BC4 91AE0000 */ lbu $t6, ($t5) +/* 0A73C8 802E7BC8 1000FF05 */ b .L802017F0 +/* 0A73CC 802E7BCC A22E0003 */ sb $t6, 3($s1) +.L80201BE0: +/* 0A73D0 802E7BD0 240100C0 */ li $at, 192 +/* 0A73D4 802E7BD4 14A10008 */ bne $a1, $at, .L80201C08 +/* 0A73D8 802E7BD8 30A300C0 */ andi $v1, $a1, 0xc0 +/* 0A73DC 802E7BDC 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A73E0 802E7BE0 02002025 */ move $a0, $s0 +/* 0A73E4 802E7BE4 922F0000 */ lbu $t7, ($s1) +/* 0A73E8 802E7BE8 A6220038 */ sh $v0, 0x38($s1) +/* 0A73EC 802E7BEC 35F80020 */ ori $t8, $t7, 0x20 +/* 0A73F0 802E7BF0 10000125 */ b .L80202098 +/* 0A73F4 802E7BF4 A2380000 */ sb $t8, ($s1) +.L80201C08: +/* 0A73F8 802E7BF8 92290000 */ lbu $t1, ($s1) +/* 0A73FC 802E7BFC 24010001 */ li $at, 1 +/* 0A7400 802E7C00 3128FFDF */ andi $t0, $t1, 0xffdf +/* 0A7404 802E7C04 A2280000 */ sb $t0, ($s1) +/* 0A7408 802E7C08 8FAA0068 */ lw $t2, 0x68($sp) +/* 0A740C 802E7C0C 8D4B0000 */ lw $t3, ($t2) +/* 0A7410 802E7C10 000B6180 */ sll $t4, $t3, 6 +/* 0A7414 802E7C14 000C6FC2 */ srl $t5, $t4, 0x1f +/* 0A7418 802E7C18 15A10038 */ bne $t5, $at, .L80201D0C +/* 0A741C 802E7C1C 00000000 */ nop +/* 0A7420 802E7C20 30A300C0 */ andi $v1, $a1, 0xc0 +/* 0A7424 802E7C24 10600007 */ beqz $v1, .L80201C54 +/* 0A7428 802E7C28 24010040 */ li $at, 64 +/* 0A742C 802E7C2C 10610014 */ beq $v1, $at, .L80201C90 +/* 0A7430 802E7C30 24010080 */ li $at, 128 +/* 0A7434 802E7C34 1061001D */ beq $v1, $at, .L80201CBC +/* 0A7438 802E7C38 02602025 */ move $a0, $s3 +/* 0A743C 802E7C3C 10000026 */ b .L80201CE8 +/* 0A7440 802E7C40 8FA60034 */ lw $a2, 0x34($sp) +.L80201C54: +/* 0A7444 802E7C44 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7448 802E7C48 02002025 */ move $a0, $s0 +/* 0A744C 802E7C4C 8E030000 */ lw $v1, ($s0) +/* 0A7450 802E7C50 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7454 802E7C54 02602025 */ move $a0, $s3 +/* 0A7458 802E7C58 90660000 */ lbu $a2, ($v1) +/* 0A745C 802E7C5C 246E0001 */ addiu $t6, $v1, 1 +/* 0A7460 802E7C60 AE0E0000 */ sw $t6, ($s0) +/* 0A7464 802E7C64 91CF0000 */ lbu $t7, ($t6) +/* 0A7468 802E7C68 A22F0003 */ sb $t7, 3($s1) +/* 0A746C 802E7C6C 8E180000 */ lw $t8, ($s0) +/* 0A7470 802E7C70 27090001 */ addiu $t1, $t8, 1 +/* 0A7474 802E7C74 AE090000 */ sw $t1, ($s0) +/* 0A7478 802E7C78 10000017 */ b .L80201CE8 +/* 0A747C 802E7C7C A6220036 */ sh $v0, 0x36($s1) +.L80201C90: +/* 0A7480 802E7C80 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7484 802E7C84 02002025 */ move $a0, $s0 +/* 0A7488 802E7C88 8E030000 */ lw $v1, ($s0) +/* 0A748C 802E7C8C 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7490 802E7C90 02602025 */ move $a0, $s3 +/* 0A7494 802E7C94 90660000 */ lbu $a2, ($v1) +/* 0A7498 802E7C98 24680001 */ addiu $t0, $v1, 1 +/* 0A749C 802E7C9C AE080000 */ sw $t0, ($s0) +/* 0A74A0 802E7CA0 A2200003 */ sb $zero, 3($s1) +/* 0A74A4 802E7CA4 1000000C */ b .L80201CE8 +/* 0A74A8 802E7CA8 A6220036 */ sh $v0, 0x36($s1) +.L80201CBC: +/* 0A74AC 802E7CAC 8E030000 */ lw $v1, ($s0) +/* 0A74B0 802E7CB0 96330036 */ lhu $s3, 0x36($s1) +/* 0A74B4 802E7CB4 90660000 */ lbu $a2, ($v1) +/* 0A74B8 802E7CB8 246A0001 */ addiu $t2, $v1, 1 +/* 0A74BC 802E7CBC AE0A0000 */ sw $t2, ($s0) +/* 0A74C0 802E7CC0 914C0000 */ lbu $t4, ($t2) +/* 0A74C4 802E7CC4 02602025 */ move $a0, $s3 +/* 0A74C8 802E7CC8 A22C0003 */ sb $t4, 3($s1) +/* 0A74CC 802E7CCC 8E0D0000 */ lw $t5, ($s0) +/* 0A74D0 802E7CD0 25AE0001 */ addiu $t6, $t5, 1 +/* 0A74D4 802E7CD4 AE0E0000 */ sw $t6, ($s0) +.L80201CE8: +/* 0A74D8 802E7CD8 44868000 */ mtc1 $a2, $f16 +/* 0A74DC 802E7CDC 325900C0 */ andi $t9, $s2, 0xc0 +/* 0A74E0 802E7CE0 02599023 */ subu $s2, $s2, $t9 +/* 0A74E4 802E7CE4 46808020 */ cvt.s.w $f0, $f16 +/* 0A74E8 802E7CE8 324F00FF */ andi $t7, $s2, 0xff +/* 0A74EC 802E7CEC 01E09025 */ move $s2, $t7 +/* 0A74F0 802E7CF0 46000482 */ mul.s $f18, $f0, $f0 +/* 0A74F4 802E7CF4 10000018 */ b .L80201D68 +/* 0A74F8 802E7CF8 E6320028 */ swc1 $f18, 0x28($s1) +.L80201D0C: +/* 0A74FC 802E7CFC 10600007 */ beqz $v1, .L80201D2C +/* 0A7500 802E7D00 24010040 */ li $at, 64 +/* 0A7504 802E7D04 1061000B */ beq $v1, $at, .L80201D44 +/* 0A7508 802E7D08 24010080 */ li $at, 128 +/* 0A750C 802E7D0C 5061000D */ beql $v1, $at, .L80201D54 +/* 0A7510 802E7D10 96330036 */ lhu $s3, 0x36($s1) +/* 0A7514 802E7D14 1000000C */ b .L80201D58 +/* 0A7518 802E7D18 02602025 */ move $a0, $s3 +.L80201D2C: +/* 0A751C 802E7D1C 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7520 802E7D20 02002025 */ move $a0, $s0 +/* 0A7524 802E7D24 3053FFFF */ andi $s3, $v0, 0xffff +/* 0A7528 802E7D28 A6220036 */ sh $v0, 0x36($s1) +/* 0A752C 802E7D2C 10000006 */ b .L80201D58 +/* 0A7530 802E7D30 02602025 */ move $a0, $s3 +.L80201D44: +/* 0A7534 802E7D34 96330034 */ lhu $s3, 0x34($s1) +/* 0A7538 802E7D38 10000003 */ b .L80201D58 +/* 0A753C 802E7D3C 02602025 */ move $a0, $s3 +/* 0A7540 802E7D40 96330036 */ lhu $s3, 0x36($s1) +.L80201D54: +/* 0A7544 802E7D44 02602025 */ move $a0, $s3 +.L80201D58: +/* 0A7548 802E7D48 325800C0 */ andi $t8, $s2, 0xc0 +/* 0A754C 802E7D4C 02589023 */ subu $s2, $s2, $t8 +/* 0A7550 802E7D50 324900FF */ andi $t1, $s2, 0xff +/* 0A7554 802E7D54 01209025 */ move $s2, $t1 +.L80201D68: +/* 0A7558 802E7D58 92280003 */ lbu $t0, 3($s1) +/* 0A755C 802E7D5C A6240038 */ sh $a0, 0x38($s1) +/* 0A7560 802E7D60 01040019 */ multu $t0, $a0 +/* 0A7564 802E7D64 00005012 */ mflo $t2 +/* 0A7568 802E7D68 000A5A03 */ sra $t3, $t2, 8 +/* 0A756C 802E7D6C A62B003A */ sh $t3, 0x3a($s1) +/* 0A7570 802E7D70 8E8C0000 */ lw $t4, ($s4) +/* 0A7574 802E7D74 8FB90068 */ lw $t9, 0x68($sp) +/* 0A7578 802E7D78 8FA90068 */ lw $t1, 0x68($sp) +/* 0A757C 802E7D7C 000C7080 */ sll $t6, $t4, 2 +/* 0A7580 802E7D80 05C10005 */ bgez $t6, .L80201DA8 +/* 0A7584 802E7D84 8FAC0068 */ lw $t4, 0x68($sp) +/* 0A7588 802E7D88 932F0003 */ lbu $t7, 3($t9) +/* 0A758C 802E7D8C 31F80040 */ andi $t8, $t7, 0x40 +/* 0A7590 802E7D90 57000007 */ bnezl $t8, .L80201DC0 +/* 0A7594 802E7D94 922D0000 */ lbu $t5, ($s1) +.L80201DA8: +/* 0A7598 802E7D98 8D280000 */ lw $t0, ($t1) +/* 0A759C 802E7D9C 8FB90068 */ lw $t9, 0x68($sp) +/* 0A75A0 802E7DA0 000858C0 */ sll $t3, $t0, 3 +/* 0A75A4 802E7DA4 05630006 */ bgezl $t3, .L80201DD0 +/* 0A75A8 802E7DA8 92230001 */ lbu $v1, 1($s1) +/* 0A75AC 802E7DAC 922D0000 */ lbu $t5, ($s1) +.L80201DC0: +/* 0A75B0 802E7DB0 35AE0020 */ ori $t6, $t5, 0x20 +/* 0A75B4 802E7DB4 100000B4 */ b .L80202098 +/* 0A75B8 802E7DB8 A22E0000 */ sb $t6, ($s1) +/* 0A75BC 802E7DBC 92230001 */ lbu $v1, 1($s1) +.L80201DD0: +/* 0A75C0 802E7DC0 240100FF */ li $at, 255 +/* 0A75C4 802E7DC4 14610002 */ bne $v1, $at, .L80201DE0 +/* 0A75C8 802E7DC8 00601025 */ move $v0, $v1 +/* 0A75CC 802E7DCC 8722001C */ lh $v0, 0x1c($t9) +.L80201DE0: +/* 0A75D0 802E7DD0 5440001D */ bnezl $v0, .L80201E58 +/* 0A75D4 802E7DD4 868F000C */ lh $t7, 0xc($s4) +/* 0A75D8 802E7DD8 8FAF0068 */ lw $t7, 0x68($sp) +/* 0A75DC 802E7DDC 86280022 */ lh $t0, 0x22($s1) +/* 0A75E0 802E7DE0 85F8001E */ lh $t8, 0x1e($t7) +/* 0A75E4 802E7DE4 91E40006 */ lbu $a0, 6($t7) +/* 0A75E8 802E7DE8 02584821 */ addu $t1, $s2, $t8 +/* 0A75EC 802E7DEC 01289021 */ addu $s2, $t1, $t0 +/* 0A75F0 802E7DF0 0C0B93EE */ jal func_eu_802e4fb8 +/* 0A75F4 802E7DF4 324500FF */ andi $a1, $s2, 0xff +/* 0A75F8 802E7DF8 14400005 */ bnez $v0, .L80201E20 +/* 0A75FC 802E7DFC 24430004 */ addiu $v1, $v0, 4 +/* 0A7600 802E7E00 922C0000 */ lbu $t4, ($s1) +/* 0A7604 802E7E04 358D0020 */ ori $t5, $t4, 0x20 +/* 0A7608 802E7E08 1000009D */ b .L80202090 +/* 0A760C 802E7E0C A22D0000 */ sb $t5, ($s1) +.L80201E20: +/* 0A7610 802E7E10 8C4E000C */ lw $t6, 0xc($v0) +/* 0A7614 802E7E14 8E380000 */ lw $t8, ($s1) +/* 0A7618 802E7E18 AE2E001C */ sw $t6, 0x1c($s1) +/* 0A761C 802E7E1C 90590000 */ lbu $t9, ($v0) +/* 0A7620 802E7E20 00184180 */ sll $t0, $t8, 6 +/* 0A7624 802E7E24 05000003 */ bltz $t0, .L80201E44 +/* 0A7628 802E7E28 A2390018 */ sb $t9, 0x18($s1) +/* 0A762C 802E7E2C 904A0001 */ lbu $t2, 1($v0) +/* 0A7630 802E7E30 A22A0005 */ sb $t2, 5($s1) +.L80201E44: +/* 0A7634 802E7E34 AE230048 */ sw $v1, 0x48($s1) # AudioBankSound +/* 0A7638 802E7E38 C4640004 */ lwc1 $f4, 4($v1) # AudioBankSound.tuning +/* 0A763C 802E7E3C 10000090 */ b .L80202090 +/* 0A7640 802E7E40 E6240024 */ swc1 $f4, 0x24($s1) +/* 0A7644 802E7E44 868F000C */ lh $t7, 0xc($s4) +.L80201E58: +/* 0A7648 802E7E48 858D001E */ lh $t5, 0x1e($t4) +/* 0A764C 802E7E4C 86390022 */ lh $t9, 0x22($s1) +/* 0A7650 802E7E50 024F5821 */ addu $t3, $s2, $t7 +/* 0A7654 802E7E54 016D7021 */ addu $t6, $t3, $t5 +/* 0A7658 802E7E58 01D99021 */ addu $s2, $t6, $t9 +/* 0A765C 802E7E5C 324500FF */ andi $a1, $s2, 0xff # a1 = s2 & 0xff +/* 0A7660 802E7E60 28A10080 */ slti $at, $a1, 0x80 +/* 0A7664 802E7E64 14200005 */ bnez $at, .L80201E8C +/* 0A7668 802E7E68 00A09025 */ move $s2, $a1 +/* 0A766C 802E7E6C 92280000 */ lbu $t0, ($s1) +/* 0A7670 802E7E70 350A0020 */ ori $t2, $t0, 0x20 +/* 0A7674 802E7E74 10000082 */ b .L80202090 +/* 0A7678 802E7E78 A22A0000 */ sb $t2, ($s1) +.L80201E8C: +/* 0A767C 802E7E7C 240100FF */ li $at, 255 +/* 0A7680 802E7E80 14610003 */ bne $v1, $at, .L80201EA0 +/* 0A7684 802E7E84 8FAF0068 */ lw $t7, 0x68($sp) +/* 0A7688 802E7E88 10000002 */ b .L80201EA4 +/* 0A768C 802E7E8C 8DE40040 */ lw $a0, 0x40($t7) # SequenceChannel.Instrument +.L80201EA0: +/* 0A7690 802E7E90 8E240044 */ lw $a0, 0x44($s1) # SequenceChannelLayer.Instrument +.L80201EA4: +/* 0A7694 802E7E94 922C0008 */ lbu $t4, 8($s1) # SequenceChannelLayer.portamento +/* 0A7698 802E7E98 11800061 */ beqz $t4, .L80202030 +/* 0A769C 802E7E9C 00000000 */ nop +/* 0A76A0 802E7EA0 92220004 */ lbu $v0, 4($s1) # SequenceChannelLayer.portamentoTargetNote +/* 0A76A4 802E7EA4 0045082A */ slt $at, $v0, $a1 +/* 0A76A8 802E7EA8 10200003 */ beqz $at, .L80201EC8 +/* 0A76AC 802E7EAC 00403025 */ move $a2, $v0 # arg1 = min(portamentoTargetNote, a1) +/* 0A76B0 802E7EB0 10000001 */ b .L80201EC8 +/* 0A76B4 802E7EB4 00A03025 */ move $a2, $a1 +.L80201EC8: +/* 0A76B8 802E7EB8 1080000A */ beqz $a0, .L80201EF4 +/* 0A76BC 802E7EBC 3C013F80 */ li $at, 0x3F800000 # 1.000000 +/* 0A76C0 802E7EC0 0C0B9397 */ jal func_eu_802e4e5c +/* 0A76C4 802E7EC4 00C02825 */ move $a1, $a2 +/* 0A76C8 802E7EC8 8E2B0048 */ lw $t3, 0x48($s1) +/* 0A76CC 802E7ECC 004B6826 */ xor $t5, $v0, $t3 +/* 0A76D0 802E7ED0 2DAD0001 */ sltiu $t5, $t5, 1 +/* 0A76D4 802E7ED4 AFAD0044 */ sw $t5, 0x44($sp) +/* 0A76D8 802E7ED8 AE220048 */ sw $v0, 0x48($s1) +/* 0A76DC 802E7EDC 10000003 */ b .L80201EFC +/* 0A76E0 802E7EE0 C4400004 */ lwc1 $f0, 4($v0) +.L80201EF4: +/* 0A76E4 802E7EE4 44810000 */ mtc1 $at, $f0 +/* 0A76E8 802E7EE8 AE200048 */ sw $zero, 0x48($s1) +.L80201EFC: +/* 0A76EC 802E7EEC 3C038030 */ lui $v1, %hi(gNoteFrequencies) # $v1, 0x8030 +/* 0A76F0 802E7EF0 92380004 */ lbu $t8, 4($s1) +/* 0A76F4 802E7EF4 24630AE8 */ addiu $v1, %lo(gNoteFrequencies) # addiu $v1, $v1, 0xae8 +/* 0A76F8 802E7EF8 00127080 */ sll $t6, $s2, 2 +/* 0A76FC 802E7EFC 006EC821 */ addu $t9, $v1, $t6 +/* 0A7700 802E7F00 C7260000 */ lwc1 $f6, ($t9) +/* 0A7704 802E7F04 922A0008 */ lbu $t2, 8($s1) +/* 0A7708 802E7F08 00184880 */ sll $t1, $t8, 2 +/* 0A770C 802E7F0C 00694021 */ addu $t0, $v1, $t1 +/* 0A7710 802E7F10 C5080000 */ lwc1 $f8, ($t0) +/* 0A7714 802E7F14 46003082 */ mul.s $f2, $f6, $f0 +/* 0A7718 802E7F18 2401FF7F */ li $at, -129 +/* 0A771C 802E7F1C 01417824 */ and $t7, $t2, $at +/* 0A7720 802E7F20 25ECFFFF */ addiu $t4, $t7, -1 +/* 0A7724 802E7F24 2D810005 */ sltiu $at, $t4, 5 +/* 0A7728 802E7F28 46004302 */ mul.s $f12, $f8, $f0 +/* 0A772C 802E7F2C 10200008 */ beqz $at, .L_EU_802E7F50 +/* 0A7730 802E7F30 000C6080 */ sll $t4, $t4, 2 +/* 0A7734 802E7F34 3C018030 */ lui $at, %hi(jtbl_EU_80306700) +/* 0A7738 802E7F38 002C0821 */ addu $at, $at, $t4 +/* 0A773C 802E7F3C 8C2C6700 */ lw $t4, %lo(jtbl_EU_80306700)($at) +/* 0A7740 802E7F40 01800008 */ jr $t4 +/* 0A7744 802E7F44 00000000 */ nop +glabel L_EU_802E7F48 +/* 0A7748 802E7F48 10000002 */ b .L80201F64 +/* 0A774C 802E7F4C 46006006 */ mov.s $f0, $f12 +glabel L_EU_802E7F50 +.L_EU_802E7F50: +/* 0A7750 802E7F50 46001006 */ mov.s $f0, $f2 +.L80201F64: +/* 0A7754 802E7F54 46001283 */ div.s $f10, $f2, $f0 +/* 0A7758 802E7F58 3C013F80 */ li $at, 0x3F800000 # 1.000000 +/* 0A775C 802E7F5C 44818000 */ mtc1 $at, $f16 +/* 0A7760 802E7F60 26220008 */ addiu $v0, $s1, 8 +/* 0A7764 802E7F64 3C0146FE */ li $at, 0x46FE0000 # 32512.000000 +/* 0A7768 802E7F68 46105481 */ sub.s $f18, $f10, $f16 +/* 0A776C 802E7F6C E452000C */ swc1 $f18, 0xc($v0) +/* 0A7770 802E7F70 922B0008 */ lbu $t3, 8($s1) +/* 0A7774 802E7F74 316D0080 */ andi $t5, $t3, 0x80 +/* 0A7778 802E7F78 51A00017 */ beql $t5, $zero, .L80201FE8 +/* 0A777C 802E7F7C 96280020 */ lhu $t0, 0x20($s1) +/* 0A7780 802E7F80 968E0008 */ lhu $t6, 8($s4) +/* 0A7784 802E7F84 3C188023 */ lui $t8, %hi(gTempoInternalToExternal) # $t8, 0x8023 +/* 0A7788 802E7F88 8718980C */ lh $t8, %lo(gTempoInternalToExternal)($t8) +/* 0A778C 802E7F8C 448E2000 */ mtc1 $t6, $f4 +/* 0A7790 802E7F90 86390038 */ lh $t9, 0x38($s1) +/* 0A7794 802E7F94 44814000 */ mtc1 $at, $f8 +/* 0A7798 802E7F98 468021A0 */ cvt.s.w $f6, $f4 +/* 0A779C 802E7F9C 44982000 */ mtc1 $t8, $f4 +/* 0A77A0 802E7FA0 44998000 */ mtc1 $t9, $f16 +/* 0A77A4 802E7FA4 96290020 */ lhu $t1, 0x20($s1) +/* 0A77A8 802E7FA8 468084A0 */ cvt.s.w $f18, $f16 +/* 0A77AC 802E7FAC 46083282 */ mul.s $f10, $f6, $f8 +/* 0A77B0 802E7FB0 44898000 */ mtc1 $t1, $f16 +/* 0A77B4 802E7FB4 468021A0 */ cvt.s.w $f6, $f4 +/* 0A77B8 802E7FB8 46808120 */ cvt.s.w $f4, $f16 +/* 0A77BC 802E7FBC 46069202 */ mul.s $f8, $f18, $f6 +/* 0A77C0 802E7FC0 00000000 */ nop +/* 0A77C4 802E7FC4 46044482 */ mul.s $f18, $f8, $f4 +/* 0A77C8 802E7FC8 46125183 */ div.s $f6, $f10, $f18 +/* 0A77CC 802E7FCC 10000009 */ b .L80202004 +/* 0A77D0 802E7FD0 E4460008 */ swc1 $f6, 8($v0) +/* 0A77D4 802E7FD4 96280020 */ lhu $t0, 0x20($s1) +.L80201FE8: +/* 0A77D8 802E7FD8 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0A77DC 802E7FDC 44818000 */ mtc1 $at, $f16 +/* 0A77E0 802E7FE0 44884000 */ mtc1 $t0, $f8 +/* 0A77E4 802E7FE4 00000000 */ nop +/* 0A77E8 802E7FE8 46804120 */ cvt.s.w $f4, $f8 +/* 0A77EC 802E7FEC 46048283 */ div.s $f10, $f16, $f4 +/* 0A77F0 802E7FF0 E44A0008 */ swc1 $f10, 8($v0) +.L80202004: +/* 0A77F4 802E7FF4 44809000 */ mtc1 $zero, $f18 +/* 0A77F8 802E7FF8 2401FF7F */ li $at, -129 +/* 0A77FC 802E7FFC E4520004 */ swc1 $f18, 4($v0) +/* 0A7800 802E8000 922A0008 */ lbu $t2, 8($s1) +/* 0A7804 802E8004 E6200024 */ swc1 $f0, 0x24($s1) +/* 0A7808 802E8008 01417824 */ and $t7, $t2, $at +/* 0A780C 802E800C 24010005 */ li $at, 5 +/* 0A7810 802E8010 55E1001C */ bnel $t7, $at, .L80202094 +/* 0A7814 802E8014 86290038 */ lh $t1, 0x38($s1) +/* 0A7818 802E8018 10000019 */ b .L80202090 +/* 0A781C 802E801C A2320004 */ sb $s2, 4($s1) +.L80202030: +/* 0A7820 802E8020 10800011 */ beqz $a0, .L80202078 +/* 0A7824 802E8024 3C038030 */ lui $v1, %hi(gNoteFrequencies) +/* 0A7828 802E8028 0C0B9397 */ jal func_eu_802e4e5c +/* 0A782C 802E802C 00000000 */ nop +/* 0A7830 802E8030 8E2C0048 */ lw $t4, 0x48($s1) +/* 0A7834 802E8034 3C038030 */ lui $v1, %hi(gNoteFrequencies) # $v1, 0x8030 +/* 0A7838 802E8038 24630AE8 */ addiu $v1, %lo(gNoteFrequencies) # addiu $v1, $v1, 0xae8 +/* 0A783C 802E803C 004C5826 */ xor $t3, $v0, $t4 +/* 0A7840 802E8040 2D6B0001 */ sltiu $t3, $t3, 1 +/* 0A7844 802E8044 AFAB0044 */ sw $t3, 0x44($sp) +/* 0A7848 802E8048 AE220048 */ sw $v0, 0x48($s1) +/* 0A784C 802E804C 00126880 */ sll $t5, $s2, 2 +/* 0A7850 802E8050 006D7021 */ addu $t6, $v1, $t5 +/* 0A7854 802E8054 C5C60000 */ lwc1 $f6, ($t6) +/* 0A7858 802E8058 C4480004 */ lwc1 $f8, 4($v0) +/* 0A785C 802E805C 46083402 */ mul.s $f16, $f6, $f8 +/* 0A7860 802E8060 10000007 */ b .L80202090 +/* 0A7864 802E8064 E6300024 */ swc1 $f16, 0x24($s1) +.L80202078: +/* 0A7868 802E8068 24630AE8 */ addiu $v1, $v1, 0xae8 +/* 0A786C 802E806C 0012C880 */ sll $t9, $s2, 2 +/* 0A7870 802E8070 AE200048 */ sw $zero, 0x48($s1) +/* 0A7874 802E8074 0079C021 */ addu $t8, $v1, $t9 +/* 0A7878 802E8078 C7040000 */ lwc1 $f4, ($t8) +/* 0A787C 802E807C E6240024 */ swc1 $f4, 0x24($s1) +.L80202090: +/* 0A7880 802E8080 86290038 */ lh $t1, 0x38($s1) +.L80202094: +/* 0A7884 802E8084 A629003C */ sh $t1, 0x3c($s1) +.L80202098: +/* 0A7888 802E8088 8E220000 */ lw $v0, ($s1) +/* 0A788C 802E808C 24010001 */ li $at, 1 +/* 0A7890 802E8090 00024080 */ sll $t0, $v0, 2 +/* 0A7894 802E8094 000857C2 */ srl $t2, $t0, 0x1f +/* 0A7898 802E8098 1541000B */ bne $t2, $at, .L802020D8 +/* 0A789C 802E809C 000270C0 */ sll $t6, $v0, 3 +/* 0A78A0 802E80A0 8E2F0040 */ lw $t7, 0x40($s1) +/* 0A78A4 802E80A4 000258C0 */ sll $t3, $v0, 3 +/* 0A78A8 802E80A8 15E00003 */ bnez $t7, .L802020C8 +/* 0A78AC 802E80AC 00000000 */ nop +/* 0A78B0 802E80B0 05630030 */ bgezl $t3, .L80202184 +/* 0A78B4 802E80B4 8FBF002C */ lw $ra, 0x2c($sp) +.L802020C8: +/* 0A78B8 802E80B8 0C0B95B3 */ jal seq_channel_layer_note_decay +/* 0A78BC 802E80BC 02202025 */ move $a0, $s1 +/* 0A78C0 802E80C0 1000002C */ b .L80202184 +/* 0A78C4 802E80C4 8FBF002C */ lw $ra, 0x2c($sp) +.L802020D8: +/* 0A78C8 802E80C8 05C00003 */ bltz $t6, .L802020E8 +/* 0A78CC 802E80CC 00009025 */ move $s2, $zero +/* 0A78D0 802E80D0 1000001A */ b .L8020214C +/* 0A78D4 802E80D4 24120001 */ li $s2, 1 +.L802020E8: +/* 0A78D8 802E80D8 8E240040 */ lw $a0, 0x40($s1) +/* 0A78DC 802E80DC 10800005 */ beqz $a0, .L80202104 +/* 0A78E0 802E80E0 00000000 */ nop +/* 0A78E4 802E80E4 92390002 */ lbu $t9, 2($s1) +/* 0A78E8 802E80E8 8FB80044 */ lw $t8, 0x44($sp) +/* 0A78EC 802E80EC 17200003 */ bnez $t9, .L8020210C +/* 0A78F0 802E80F0 00000000 */ nop +.L80202104: +/* 0A78F4 802E80F4 10000011 */ b .L8020214C +/* 0A78F8 802E80F8 24120001 */ li $s2, 1 +.L8020210C: +/* 0A78FC 802E80FC 57000006 */ bnezl $t8, .L80202128 +/* 0A7900 802E8100 8C890044 */ lw $t1, 0x44($a0) +/* 0A7904 802E8104 0C0B95B3 */ jal seq_channel_layer_note_decay +/* 0A7908 802E8108 02202025 */ move $a0, $s1 +/* 0A790C 802E810C 1000000B */ b .L8020214C +/* 0A7910 802E8110 24120001 */ li $s2, 1 +/* 0A7914 802E8114 8C890044 */ lw $t1, 0x44($a0) +.L80202128: +/* 0A7918 802E8118 52290004 */ beql $s1, $t1, .L8020213C +/* 0A791C 802E811C 8E280048 */ lw $t0, 0x48($s1) +/* 0A7920 802E8120 10000006 */ b .L8020214C +/* 0A7924 802E8124 24120001 */ li $s2, 1 +/* 0A7928 802E8128 8E280048 */ lw $t0, 0x48($s1) +.L8020213C: +/* 0A792C 802E812C 15000003 */ bnez $t0, .L8020214C +/* 0A7930 802E8130 00000000 */ nop +/* 0A7934 802E8134 0C0B9604 */ jal init_synthetic_wave +/* 0A7938 802E8138 02202825 */ move $a1, $s1 +.L8020214C: +/* 0A793C 802E813C 52400005 */ beql $s2, $zero, .L80202164 +/* 0A7940 802E8140 8E240040 */ lw $a0, 0x40($s1) +/* 0A7944 802E8144 0C0B97FC */ jal alloc_note +/* 0A7948 802E8148 02202025 */ move $a0, $s1 +/* 0A794C 802E814C AE220040 */ sw $v0, 0x40($s1) +/* 0A7950 802E8150 8E240040 */ lw $a0, 0x40($s1) +.L80202164: +/* 0A7954 802E8154 50800007 */ beql $a0, $zero, .L80202184 +/* 0A7958 802E8158 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A795C 802E815C 8C8A0044 */ lw $t2, 0x44($a0) +/* 0A7960 802E8160 562A0004 */ bnel $s1, $t2, .L80202184 +/* 0A7964 802E8164 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A7968 802E8168 0C0B9AA0 */ jal note_vibrato_init +/* 0A796C 802E816C 00000000 */ nop +.L80202180: +/* 0A7970 802E8170 8FBF002C */ lw $ra, 0x2c($sp) +.L80202184: +/* 0A7974 802E8174 8FB00018 */ lw $s0, 0x18($sp) +/* 0A7978 802E8178 8FB1001C */ lw $s1, 0x1c($sp) +/* 0A797C 802E817C 8FB20020 */ lw $s2, 0x20($sp) +/* 0A7980 802E8180 8FB30024 */ lw $s3, 0x24($sp) +/* 0A7984 802E8184 8FB40028 */ lw $s4, 0x28($sp) +/* 0A7988 802E8188 03E00008 */ jr $ra +/* 0A798C 802E818C 27BD0070 */ addiu $sp, $sp, 0x70 diff --git a/asm/non_matchings/eu/audio/sequence_channel_enable.s b/asm/non_matchings/eu/audio/sequence_channel_enable.s new file mode 100644 index 0000000..898e3b9 --- /dev/null +++ b/asm/non_matchings/eu/audio/sequence_channel_enable.s @@ -0,0 +1,56 @@ +glabel sequence_channel_enable +/* 0A6BE8 802E73E8 27BDFFD8 */ addiu $sp, $sp, -0x28 +/* 0A6BEC 802E73EC 30AE00FF */ andi $t6, $a1, 0xff +/* 0A6BF0 802E73F0 000E7880 */ sll $t7, $t6, 2 +/* 0A6BF4 802E73F4 AFBF0024 */ sw $ra, 0x24($sp) +/* 0A6BF8 802E73F8 AFB30020 */ sw $s3, 0x20($sp) +/* 0A6BFC 802E73FC AFB2001C */ sw $s2, 0x1c($sp) +/* 0A6C00 802E7400 AFB10018 */ sw $s1, 0x18($sp) +/* 0A6C04 802E7404 AFB00014 */ sw $s0, 0x14($sp) +/* 0A6C08 802E7408 AFA5002C */ sw $a1, 0x2c($sp) +/* 0A6C0C 802E740C 008FC021 */ addu $t8, $a0, $t7 +/* 0A6C10 802E7410 8F120030 */ lw $s2, 0x30($t8) +/* 0A6C14 802E7414 3C198023 */ lui $t9, %hi(gSequenceChannelNone) # $t9, 0x8023 +/* 0A6C18 802E7418 27398748 */ addiu $t9, %lo(gSequenceChannelNone) # addiu $t9, $t9, -0x78b8 +/* 0A6C1C 802E741C 1659000A */ bne $s2, $t9, .L80201458 +/* 0A6C20 802E7420 00008025 */ move $s0, $zero +/* 0A6C24 802E7424 3C098022 */ lui $t1, %hi(gSequencePlayers) # $t1, 0x8022 +/* 0A6C28 802E7428 25293D68 */ addiu $t1, %lo(gSequencePlayers) # addiu $t1, $t1, 0x3d68 +/* 0A6C2C 802E742C 10890019 */ beq $a0, $t1, .L802014A4 +/* 0A6C30 802E7430 3C0A8022 */ lui $t2, %hi(gSequencePlayers + 0x148) # $t2, 0x8022 +/* 0A6C34 802E7434 254A3EB0 */ addiu $t2, %lo(gSequencePlayers + 0x148) # addiu $t2, $t2, 0x3eb0 +/* 0A6C38 802E7438 548A0017 */ bnel $a0, $t2, .L802014A8 +/* 0A6C3C 802E743C 8FBF0024 */ lw $ra, 0x24($sp) +/* 0A6C40 802E7440 10000015 */ b .L802014A8 +/* 0A6C44 802E7444 8FBF0024 */ lw $ra, 0x24($sp) +.L80201458: +/* 0A6C48 802E7448 924C0000 */ lbu $t4, ($s2) +/* 0A6C4C 802E744C A2400078 */ sb $zero, 0x78($s2) +/* 0A6C50 802E7450 AE460060 */ sw $a2, 0x60($s2) +/* 0A6C54 802E7454 358E0080 */ ori $t6, $t4, 0x80 +/* 0A6C58 802E7458 A24E0000 */ sb $t6, ($s2) +/* 0A6C5C 802E745C 31CF00BF */ andi $t7, $t6, 0xbf +/* 0A6C60 802E7460 A24F0000 */ sb $t7, ($s2) +/* 0A6C64 802E7464 A640001A */ sh $zero, 0x1a($s2) +/* 0A6C68 802E7468 02408825 */ move $s1, $s2 +/* 0A6C6C 802E746C 24130004 */ li $s3, 4 +.L80201480: +/* 0A6C70 802E7470 8E380048 */ lw $t8, 0x48($s1) +/* 0A6C74 802E7474 02402025 */ move $a0, $s2 +/* 0A6C78 802E7478 53000004 */ beql $t8, $zero, .L8020149C +/* 0A6C7C 802E747C 26100001 */ addiu $s0, $s0, 1 +/* 0A6C80 802E7480 0C0B9C2D */ jal seq_channel_layer_free +/* 0A6C84 802E7484 02002825 */ move $a1, $s0 +/* 0A6C88 802E7488 26100001 */ addiu $s0, $s0, 1 +.L8020149C: +/* 0A6C8C 802E748C 1613FFF8 */ bne $s0, $s3, .L80201480 +/* 0A6C90 802E7490 26310004 */ addiu $s1, $s1, 4 +.L802014A4: +/* 0A6C94 802E7494 8FBF0024 */ lw $ra, 0x24($sp) +.L802014A8: +/* 0A6C98 802E7498 8FB00014 */ lw $s0, 0x14($sp) +/* 0A6C9C 802E749C 8FB10018 */ lw $s1, 0x18($sp) +/* 0A6CA0 802E74A0 8FB2001C */ lw $s2, 0x1c($sp) +/* 0A6CA4 802E74A4 8FB30020 */ lw $s3, 0x20($sp) +/* 0A6CA8 802E74A8 03E00008 */ jr $ra +/* 0A6CAC 802E74AC 27BD0028 */ addiu $sp, $sp, 0x28 diff --git a/asm/non_matchings/eu/audio/sequence_channel_process_script.s b/asm/non_matchings/eu/audio/sequence_channel_process_script.s new file mode 100644 index 0000000..802f5b1 --- /dev/null +++ b/asm/non_matchings/eu/audio/sequence_channel_process_script.s @@ -0,0 +1,929 @@ +.late_rodata +.late_rodata_alignment 4 +glabel jtbl_EU_80306714 + .word L_EU_802E8650 + .word L_EU_802E85A0, L_EU_802E866C + .word L_EU_802E867C, L_EU_802E85BC + .word L_EU_802E8888, L_EU_802E88E4 + .word L_EU_802E891C, L_EU_802E891C + .word L_EU_802E8968, L_EU_802E8978 + .word L_EU_802E891C, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8998, L_EU_802E89BC + .word L_EU_802E89CC, L_EU_802E8714 + .word L_EU_802E8878, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E87E0 + .word L_EU_802E87C4, L_EU_802E87B4 + .word L_EU_802E8798, L_EU_802E8780 + .word L_EU_802E8764, L_EU_802E8748 + .word L_EU_802E86E0, L_EU_802E868C + .word L_EU_802E86B0, L_EU_802E8830 + .word L_EU_802E87FC, L_EU_802E8864 + .word L_EU_802E89EC, L_EU_802E89DC + .word L_EU_802E8A48, L_EU_802E8A58 + .word L_EU_802E8AC0, L_EU_802E8B60 + .word L_EU_802E83EC, L_EU_802E85F8 + .word L_EU_802E8B38, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8590, L_EU_802E8568 + .word L_EU_802E8520, L_EU_802E8520 + .word L_EU_802E8520, L_EU_802E84C8 + .word L_EU_802E84B8, L_EU_802E8470 + .word L_EU_802E8438, L_EU_802E84C8 + .word L_EU_802E84C8, L_EU_802E84C8 + .word L_EU_802E83FC, L_EU_802E83DC + .word L_EU_802E8D98, L_EU_802E83A4 + +glabel jtbl_EU_80306810 + .word L_EU_802E8B9C, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8CFC, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8D2C, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8D48, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8D70, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8C04, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8C20, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8BD4, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8BE4, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8C2C, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8C78, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8368, L_EU_802E8368 + .word L_EU_802E8C94 + +.text +glabel sequence_channel_process_script +/* 0A7AB8 802E82B8 27BDFFA0 */ addiu $sp, $sp, -0x60 +/* 0A7ABC 802E82BC AFBF002C */ sw $ra, 0x2c($sp) +/* 0A7AC0 802E82C0 AFB40028 */ sw $s4, 0x28($sp) +/* 0A7AC4 802E82C4 AFB30024 */ sw $s3, 0x24($sp) +/* 0A7AC8 802E82C8 AFB20020 */ sw $s2, 0x20($sp) +/* 0A7ACC 802E82CC AFB1001C */ sw $s1, 0x1c($sp) +/* 0A7AD0 802E82D0 AFB00018 */ sw $s0, 0x18($sp) +/* 0A7AD4 802E82D4 8C820000 */ lw $v0, ($a0) +/* 0A7AD8 802E82D8 00809025 */ move $s2, $a0 +/* 0A7ADC 802E82DC 000277C2 */ srl $t6, $v0, 0x1f +/* 0A7AE0 802E82E0 11C002B8 */ beqz $t6, .L080200BC4 +/* 0A7AE4 802E82E4 0002C080 */ sll $t8, $v0, 2 +/* 0A7AE8 802E82E8 0701000D */ bgez $t8, .L080200120 +/* 0A7AEC 802E82EC 00008025 */ move $s0, $zero +/* 0A7AF0 802E82F0 00808825 */ move $s1, $a0 +/* 0A7AF4 802E82F4 24120010 */ li $s2, 16 +.L0802000F8: +/* 0A7AF8 802E82F8 8E240048 */ lw $a0, 0x48($s1) +/* 0A7AFC 802E82FC 50800004 */ beql $a0, $zero, .L080200110 +/* 0A7B00 802E8300 26100004 */ addiu $s0, $s0, 4 +/* 0A7B04 802E8304 0C0B9DC2 */ jal seq_channel_layer_process_script +/* 0A7B08 802E8308 00000000 */ nop +/* 0A7B0C 802E830C 26100004 */ addiu $s0, $s0, 4 +.L080200110: +/* 0A7B10 802E8310 1612FFF9 */ bne $s0, $s2, .L0802000F8 +/* 0A7B14 802E8314 26310004 */ addiu $s1, $s1, 4 +/* 0A7B18 802E8318 100002AB */ b .L080200BC8 +/* 0A7B1C 802E831C 8FBF002C */ lw $ra, 0x2c($sp) +.L080200120: +/* 0A7B20 802E8320 8E540044 */ lw $s4, 0x44($s2) +/* 0A7B24 802E8324 8E990000 */ lw $t9, ($s4) +/* 0A7B28 802E8328 00195080 */ sll $t2, $t9, 2 +/* 0A7B2C 802E832C 05430006 */ bgezl $t2, .L080200148 +/* 0A7B30 802E8330 9643001A */ lhu $v1, 0x1a($s2) +/* 0A7B34 802E8334 924B0003 */ lbu $t3, 3($s2) +/* 0A7B38 802E8338 316C0080 */ andi $t4, $t3, 0x80 +/* 0A7B3C 802E833C 558002A2 */ bnezl $t4, .L080200BC8 +/* 0A7B40 802E8340 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A7B44 802E8344 9643001A */ lhu $v1, 0x1a($s2) +.L080200148: +/* 0A7B48 802E8348 26510060 */ addiu $s1, $s2, 0x60 +/* 0A7B4C 802E834C 10600004 */ beqz $v1, .L080200160 +/* 0A7B50 802E8350 00601025 */ move $v0, $v1 +/* 0A7B54 802E8354 246DFFFF */ addiu $t5, $v1, -1 +/* 0A7B58 802E8358 A64D001A */ sh $t5, 0x1a($s2) +/* 0A7B5C 802E835C 31A2FFFF */ andi $v0, $t5, 0xffff +.L080200160: +/* 0A7B60 802E8360 1440028D */ bnez $v0, .L_EU_802E8D98 +/* 0A7B64 802E8364 83B3004B */ lb $s3, 0x4b($sp) +glabel L_EU_802E8368 +.L_EU_802E8368: +/* 0A7B68 802E8368 0C0B9DA0 */ jal m64_read_u8 +/* 0A7B6C 802E836C 02202025 */ move $a0, $s1 +/* 0A7B70 802E8370 284100C1 */ slti $at, $v0, 0xc1 +/* 0A7B74 802E8374 305000FF */ andi $s0, $v0, 0xff +/* 0A7B78 802E8378 142001FD */ bnez $at, .L080200970 +/* 0A7B7C 802E837C 00401825 */ move $v1, $v0 +/* 0A7B80 802E8380 244EFF3F */ addiu $t6, $v0, -0xc1 +/* 0A7B84 802E8384 2DC1003F */ sltiu $at, $t6, 0x3f +/* 0A7B88 802E8388 1020FFF7 */ beqz $at, .L_EU_802E8368 +/* 0A7B8C 802E838C 000E7080 */ sll $t6, $t6, 2 +/* 0A7B90 802E8390 3C018030 */ lui $at, %hi(jtbl_EU_80306714) +/* 0A7B94 802E8394 002E0821 */ addu $at, $at, $t6 +/* 0A7B98 802E8398 8C2E6714 */ lw $t6, %lo(jtbl_EU_80306714)($at) +/* 0A7B9C 802E839C 01C00008 */ jr $t6 +/* 0A7BA0 802E83A0 00000000 */ nop +glabel L_EU_802E83A4 +/* 0A7BA4 802E83A4 92240018 */ lbu $a0, 0x18($s1) +/* 0A7BA8 802E83A8 14800005 */ bnez $a0, .L0802001C0 +/* 0A7BAC 802E83AC 2482FFFF */ addiu $v0, $a0, -1 +/* 0A7BB0 802E83B0 0C0B9C41 */ jal sequence_channel_disable +/* 0A7BB4 802E83B4 02402025 */ move $a0, $s2 +/* 0A7BB8 802E83B8 10000278 */ b .L080200B9C +/* 0A7BBC 802E83BC 02408825 */ move $s1, $s2 +.L0802001C0: +/* 0A7BC0 802E83C0 304F00FF */ andi $t7, $v0, 0xff +/* 0A7BC4 802E83C4 000FC080 */ sll $t8, $t7, 2 +/* 0A7BC8 802E83C8 0238C821 */ addu $t9, $s1, $t8 +/* 0A7BCC 802E83CC A22F0018 */ sb $t7, 0x18($s1) +/* 0A7BD0 802E83D0 8F290004 */ lw $t1, 4($t9) +/* 0A7BD4 802E83D4 1000FFE4 */ b .L_EU_802E8368 +/* 0A7BD8 802E83D8 AE290000 */ sw $t1, ($s1) +glabel L_EU_802E83DC +/* 0A7BDC 802E83DC 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A7BE0 802E83E0 02202025 */ move $a0, $s1 +/* 0A7BE4 802E83E4 1000026C */ b .L_EU_802E8D98 +/* 0A7BE8 802E83E8 A642001A */ sh $v0, 0x1a($s2) +glabel L_EU_802E83EC +/* 0A7BEC 802E83EC 924B0000 */ lbu $t3, ($s2) +/* 0A7BF0 802E83F0 356C0020 */ ori $t4, $t3, 0x20 +/* 0A7BF4 802E83F4 10000268 */ b .L_EU_802E8D98 +/* 0A7BF8 802E83F8 A24C0000 */ sb $t4, ($s2) +glabel L_EU_802E83FC +/* 0A7BFC 802E83FC 0C0B9DA5 */ jal m64_read_s16 +/* 0A7C00 802E8400 02202025 */ move $a0, $s1 +/* 0A7C04 802E8404 922E0018 */ lbu $t6, 0x18($s1) +/* 0A7C08 802E8408 8E2D0000 */ lw $t5, ($s1) +/* 0A7C0C 802E840C 304BFFFF */ andi $t3, $v0, 0xffff +/* 0A7C10 802E8410 000E7880 */ sll $t7, $t6, 2 +/* 0A7C14 802E8414 022FC021 */ addu $t8, $s1, $t7 +/* 0A7C18 802E8418 AF0D0004 */ sw $t5, 4($t8) +/* 0A7C1C 802E841C 92390018 */ lbu $t9, 0x18($s1) +/* 0A7C20 802E8420 27290001 */ addiu $t1, $t9, 1 +/* 0A7C24 802E8424 A2290018 */ sb $t1, 0x18($s1) +/* 0A7C28 802E8428 8E8A0014 */ lw $t2, 0x14($s4) +/* 0A7C2C 802E842C 014B6021 */ addu $t4, $t2, $t3 +/* 0A7C30 802E8430 1000FFCD */ b .L_EU_802E8368 +/* 0A7C34 802E8434 AE2C0000 */ sw $t4, ($s1) +glabel L_EU_802E8438 +/* 0A7C38 802E8438 0C0B9DA0 */ jal m64_read_u8 +/* 0A7C3C 802E843C 02202025 */ move $a0, $s1 +/* 0A7C40 802E8440 922E0018 */ lbu $t6, 0x18($s1) +/* 0A7C44 802E8444 022E7821 */ addu $t7, $s1, $t6 +/* 0A7C48 802E8448 A1E20014 */ sb $v0, 0x14($t7) +/* 0A7C4C 802E844C 92380018 */ lbu $t8, 0x18($s1) +/* 0A7C50 802E8450 8E2D0000 */ lw $t5, ($s1) +/* 0A7C54 802E8454 0018C880 */ sll $t9, $t8, 2 +/* 0A7C58 802E8458 02394821 */ addu $t1, $s1, $t9 +/* 0A7C5C 802E845C AD2D0004 */ sw $t5, 4($t1) +/* 0A7C60 802E8460 922A0018 */ lbu $t2, 0x18($s1) +/* 0A7C64 802E8464 254B0001 */ addiu $t3, $t2, 1 +/* 0A7C68 802E8468 1000FFBF */ b .L_EU_802E8368 +/* 0A7C6C 802E846C A22B0018 */ sb $t3, 0x18($s1) +glabel L_EU_802E8470 +/* 0A7C70 802E8470 922C0018 */ lbu $t4, 0x18($s1) +/* 0A7C74 802E8474 022C1021 */ addu $v0, $s1, $t4 +/* 0A7C78 802E8478 904E0013 */ lbu $t6, 0x13($v0) +/* 0A7C7C 802E847C 25CFFFFF */ addiu $t7, $t6, -1 +/* 0A7C80 802E8480 A04F0013 */ sb $t7, 0x13($v0) +/* 0A7C84 802E8484 92240018 */ lbu $a0, 0x18($s1) +/* 0A7C88 802E8488 0224C021 */ addu $t8, $s1, $a0 +/* 0A7C8C 802E848C 93190013 */ lbu $t9, 0x13($t8) +/* 0A7C90 802E8490 00801825 */ move $v1, $a0 +/* 0A7C94 802E8494 00036880 */ sll $t5, $v1, 2 +/* 0A7C98 802E8498 13200005 */ beqz $t9, .L0802002B0 +/* 0A7C9C 802E849C 248BFFFF */ addiu $t3, $a0, -1 +/* 0A7CA0 802E84A0 022D4821 */ addu $t1, $s1, $t5 +/* 0A7CA4 802E84A4 8D2A0000 */ lw $t2, ($t1) +/* 0A7CA8 802E84A8 1000FFAF */ b .L_EU_802E8368 +/* 0A7CAC 802E84AC AE2A0000 */ sw $t2, ($s1) +.L0802002B0: +/* 0A7CB0 802E84B0 1000FFAD */ b .L_EU_802E8368 +/* 0A7CB4 802E84B4 A22B0018 */ sb $t3, 0x18($s1) +glabel L_EU_802E84B8 +/* 0A7CB8 802E84B8 922C0018 */ lbu $t4, 0x18($s1) +/* 0A7CBC 802E84BC 258EFFFF */ addiu $t6, $t4, -1 +/* 0A7CC0 802E84C0 1000FFA9 */ b .L_EU_802E8368 +/* 0A7CC4 802E84C4 A22E0018 */ sb $t6, 0x18($s1) +glabel L_EU_802E84C8 +/* 0A7CC8 802E84C8 0C0B9DA5 */ jal m64_read_s16 +/* 0A7CCC 802E84CC 02202025 */ move $a0, $s1 +/* 0A7CD0 802E84D0 240100FA */ li $at, 250 +/* 0A7CD4 802E84D4 16010003 */ bne $s0, $at, .L0802002E4 +/* 0A7CD8 802E84D8 02001825 */ move $v1, $s0 +/* 0A7CDC 802E84DC 1660FFA2 */ bnez $s3, .L_EU_802E8368 +/* 0A7CE0 802E84E0 00000000 */ nop +.L0802002E4: +/* 0A7CE4 802E84E4 240100F9 */ li $at, 249 +/* 0A7CE8 802E84E8 54610004 */ bnel $v1, $at, .L0802002FC +/* 0A7CEC 802E84EC 240100F5 */ li $at, 245 +/* 0A7CF0 802E84F0 0661FF9D */ bgez $s3, .L_EU_802E8368 +/* 0A7CF4 802E84F4 00000000 */ nop +/* 0A7CF8 802E84F8 240100F5 */ li $at, 245 +.L0802002FC: +/* 0A7CFC 802E84FC 54610004 */ bnel $v1, $at, .L080200310 +/* 0A7D00 802E8500 8E8F0014 */ lw $t7, 0x14($s4) +/* 0A7D04 802E8504 0660FF98 */ bltz $s3, .L_EU_802E8368 +/* 0A7D08 802E8508 00000000 */ nop +/* 0A7D0C 802E850C 8E8F0014 */ lw $t7, 0x14($s4) +.L080200310: +/* 0A7D10 802E8510 3058FFFF */ andi $t8, $v0, 0xffff +/* 0A7D14 802E8514 01F8C821 */ addu $t9, $t7, $t8 +/* 0A7D18 802E8518 1000FF93 */ b .L_EU_802E8368 +/* 0A7D1C 802E851C AE390000 */ sw $t9, ($s1) +glabel L_EU_802E8520 +/* 0A7D20 802E8520 0C0B9DA0 */ jal m64_read_u8 +/* 0A7D24 802E8524 02202025 */ move $a0, $s1 +/* 0A7D28 802E8528 240100F3 */ li $at, 243 +/* 0A7D2C 802E852C 16010003 */ bne $s0, $at, .L08020033C +/* 0A7D30 802E8530 02001825 */ move $v1, $s0 +/* 0A7D34 802E8534 1660FF8C */ bnez $s3, .L_EU_802E8368 +/* 0A7D38 802E8538 00000000 */ nop +.L08020033C: +/* 0A7D3C 802E853C 240100F2 */ li $at, 242 +/* 0A7D40 802E8540 54610004 */ bnel $v1, $at, .L080200354 +/* 0A7D44 802E8544 8E2D0000 */ lw $t5, ($s1) +/* 0A7D48 802E8548 0661FF87 */ bgez $s3, .L_EU_802E8368 +/* 0A7D4C 802E854C 00000000 */ nop +/* 0A7D50 802E8550 8E2D0000 */ lw $t5, ($s1) +.L080200354: +/* 0A7D54 802E8554 00024E00 */ sll $t1, $v0, 0x18 +/* 0A7D58 802E8558 00095603 */ sra $t2, $t1, 0x18 +/* 0A7D5C 802E855C 01AA5821 */ addu $t3, $t5, $t2 +/* 0A7D60 802E8560 1000FF81 */ b .L_EU_802E8368 +/* 0A7D64 802E8564 AE2B0000 */ sw $t3, ($s1) +glabel L_EU_802E8568 +/* 0A7D68 802E8568 26500084 */ addiu $s0, $s2, 0x84 +/* 0A7D6C 802E856C 0C0B9671 */ jal note_pool_clear +/* 0A7D70 802E8570 02002025 */ move $a0, $s0 +/* 0A7D74 802E8574 0C0B9DA0 */ jal m64_read_u8 +/* 0A7D78 802E8578 02202025 */ move $a0, $s1 +/* 0A7D7C 802E857C 02002025 */ move $a0, $s0 +/* 0A7D80 802E8580 0C0B96C9 */ jal note_pool_fill +/* 0A7D84 802E8584 00402825 */ move $a1, $v0 +/* 0A7D88 802E8588 1000FF77 */ b .L_EU_802E8368 +/* 0A7D8C 802E858C 00000000 */ nop +glabel L_EU_802E8590 +/* 0A7D90 802E8590 0C0B9671 */ jal note_pool_clear +/* 0A7D94 802E8594 26440084 */ addiu $a0, $s2, 0x84 +/* 0A7D98 802E8598 1000FF73 */ b .L_EU_802E8368 +/* 0A7D9C 802E859C 00000000 */ nop +glabel L_EU_802E85A0 +/* 0A7DA0 802E85A0 0C0B9DA5 */ jal m64_read_s16 +/* 0A7DA4 802E85A4 02202025 */ move $a0, $s1 +/* 0A7DA8 802E85A8 8E8C0014 */ lw $t4, 0x14($s4) +/* 0A7DAC 802E85AC 304EFFFF */ andi $t6, $v0, 0xffff +/* 0A7DB0 802E85B0 018E7821 */ addu $t7, $t4, $t6 +/* 0A7DB4 802E85B4 1000FF6C */ b .L_EU_802E8368 +/* 0A7DB8 802E85B8 AE4F0034 */ sw $t7, 0x34($s2) +glabel L_EU_802E85BC +/* 0A7DBC 802E85BC 2401FFFF */ li $at, -1 +/* 0A7DC0 802E85C0 1261FF69 */ beq $s3, $at, .L_EU_802E8368 +/* 0A7DC4 802E85C4 00000000 */ nop +/* 0A7DC8 802E85C8 8E580034 */ lw $t8, 0x34($s2) +/* 0A7DCC 802E85CC 0013C840 */ sll $t9, $s3, 1 +/* 0A7DD0 802E85D0 8E8C0014 */ lw $t4, 0x14($s4) +/* 0A7DD4 802E85D4 03191821 */ addu $v1, $t8, $t9 +/* 0A7DD8 802E85D8 906D0000 */ lbu $t5, ($v1) +/* 0A7DDC 802E85DC 90690001 */ lbu $t1, 1($v1) +/* 0A7DE0 802E85E0 000D5200 */ sll $t2, $t5, 8 +/* 0A7DE4 802E85E4 012A3821 */ addu $a3, $t1, $t2 +/* 0A7DE8 802E85E8 30EBFFFF */ andi $t3, $a3, 0xffff +/* 0A7DEC 802E85EC 018B7021 */ addu $t6, $t4, $t3 +/* 0A7DF0 802E85F0 1000FF5D */ b .L_EU_802E8368 +/* 0A7DF4 802E85F4 AE4E0034 */ sw $t6, 0x34($s2) +glabel L_EU_802E85F8 +/* 0A7DF8 802E85F8 0C0B9DA0 */ jal m64_read_u8 +/* 0A7DFC 802E85FC 02202025 */ move $a0, $s1 +/* 0A7E00 802E8600 928F0004 */ lbu $t7, 4($s4) +/* 0A7E04 802E8604 3C038023 */ lui $v1, %hi(gAlBankSets) # $v1, 0x8023 +/* 0A7E08 802E8608 8C6397D0 */ lw $v1, %lo(gAlBankSets)($v1) +/* 0A7E0C 802E860C 000FC040 */ sll $t8, $t7, 1 +/* 0A7E10 802E8610 3C048022 */ lui $a0, %hi(gBankLoadedPool) # $a0, 0x8022 +/* 0A7E14 802E8614 0078C821 */ addu $t9, $v1, $t8 +/* 0A7E18 802E8618 97270000 */ lhu $a3, ($t9) +/* 0A7E1C 802E861C 24842840 */ addiu $a0, %lo(gBankLoadedPool) # addiu $a0, $a0, 0x2840 +/* 0A7E20 802E8620 24050002 */ li $a1, 2 +/* 0A7E24 802E8624 00E36821 */ addu $t5, $a3, $v1 +/* 0A7E28 802E8628 91A80000 */ lbu $t0, ($t5) +/* 0A7E2C 802E862C 00E84821 */ addu $t1, $a3, $t0 +/* 0A7E30 802E8630 01225023 */ subu $t2, $t1, $v0 +/* 0A7E34 802E8634 01435821 */ addu $t3, $t2, $v1 +/* 0A7E38 802E8638 91700000 */ lbu $s0, ($t3) +/* 0A7E3C 802E863C 0C0B89CF */ jal get_bank_or_seq +/* 0A7E40 802E8640 02003025 */ move $a2, $s0 +/* 0A7E44 802E8644 10400002 */ beqz $v0, .L_EU_802E8650 +/* 0A7E48 802E8648 00000000 */ nop +/* 0A7E4C 802E864C A2500006 */ sb $s0, 6($s2) +glabel L_EU_802E8650 +.L_EU_802E8650: +/* 0A7E50 802E8650 0C0B9DA0 */ jal m64_read_u8 +/* 0A7E54 802E8654 02202025 */ move $a0, $s1 +/* 0A7E58 802E8658 02402025 */ move $a0, $s2 +/* 0A7E5C 802E865C 0C0BA080 */ jal set_instrument +/* 0A7E60 802E8660 304500FF */ andi $a1, $v0, 0xff +/* 0A7E64 802E8664 1000FF40 */ b .L_EU_802E8368 +/* 0A7E68 802E8668 00000000 */ nop +glabel L_EU_802E866C +/* 0A7E6C 802E866C 924C0000 */ lbu $t4, ($s2) +/* 0A7E70 802E8670 318EFFFD */ andi $t6, $t4, 0xfffd +/* 0A7E74 802E8674 1000FF3C */ b .L_EU_802E8368 +/* 0A7E78 802E8678 A24E0000 */ sb $t6, ($s2) +glabel L_EU_802E867C +/* 0A7E7C 802E867C 92580000 */ lbu $t8, ($s2) +/* 0A7E80 802E8680 37190002 */ ori $t9, $t8, 2 +/* 0A7E84 802E8684 1000FF38 */ b .L_EU_802E8368 +/* 0A7E88 802E8688 A2590000 */ sb $t9, ($s2) +glabel L_EU_802E868C +/* 0A7E8C 802E868C 0C0B9DA0 */ jal m64_read_u8 +/* 0A7E90 802E8690 02202025 */ move $a0, $s1 +/* 0A7E94 802E8694 02402025 */ move $a0, $s2 +/* 0A7E98 802E8698 0C0BA0A5 */ jal sequence_channel_set_volume +/* 0A7E9C 802E869C 304500FF */ andi $a1, $v0, 0xff +/* 0A7EA0 802E86A0 92490001 */ lbu $t1, 1($s2) +/* 0A7EA4 802E86A4 352A0040 */ ori $t2, $t1, 0x40 +/* 0A7EA8 802E86A8 1000FF2F */ b .L_EU_802E8368 +/* 0A7EAC 802E86AC A24A0001 */ sb $t2, 1($s2) +glabel L_EU_802E86B0 +/* 0A7EB0 802E86B0 0C0B9DA0 */ jal m64_read_u8 +/* 0A7EB4 802E86B4 02202025 */ move $a0, $s1 +/* 0A7EB8 802E86B8 44822000 */ mtc1 $v0, $f4 +/* 0A7EBC 802E86BC 3C013C00 */ li $at, 0x3C000000 # 0.007812 +/* 0A7EC0 802E86C0 44814000 */ mtc1 $at, $f8 +/* 0A7EC4 802E86C4 468021A0 */ cvt.s.w $f6, $f4 +/* 0A7EC8 802E86C8 924C0001 */ lbu $t4, 1($s2) +/* 0A7ECC 802E86CC 358E0040 */ ori $t6, $t4, 0x40 +/* 0A7ED0 802E86D0 A24E0001 */ sb $t6, 1($s2) +/* 0A7ED4 802E86D4 46083282 */ mul.s $f10, $f6, $f8 +/* 0A7ED8 802E86D8 1000FF23 */ b .L_EU_802E8368 +/* 0A7EDC 802E86DC E64A0020 */ swc1 $f10, 0x20($s2) +glabel L_EU_802E86E0 +/* 0A7EE0 802E86E0 0C0B9DA5 */ jal m64_read_s16 +/* 0A7EE4 802E86E4 02202025 */ move $a0, $s1 +/* 0A7EE8 802E86E8 304FFFFF */ andi $t7, $v0, 0xffff +/* 0A7EEC 802E86EC 448F8000 */ mtc1 $t7, $f16 +/* 0A7EF0 802E86F0 3C014700 */ li $at, 0x47000000 # 32768.000000 +/* 0A7EF4 802E86F4 44812000 */ mtc1 $at, $f4 +/* 0A7EF8 802E86F8 468084A0 */ cvt.s.w $f18, $f16 +/* 0A7EFC 802E86FC 92590001 */ lbu $t9, 1($s2) +/* 0A7F00 802E8700 372D0080 */ ori $t5, $t9, 0x80 +/* 0A7F04 802E8704 A24D0001 */ sb $t5, 1($s2) +/* 0A7F08 802E8708 46049183 */ div.s $f6, $f18, $f4 +/* 0A7F0C 802E870C 1000FF16 */ b .L_EU_802E8368 +/* 0A7F10 802E8710 E6460030 */ swc1 $f6, 0x30($s2) +glabel L_EU_802E8714 +/* 0A7F14 802E8714 0C0B9DA0 */ jal m64_read_u8 +/* 0A7F18 802E8718 02202025 */ move $a0, $s1 +/* 0A7F1C 802E871C 2449007F */ addiu $t1, $v0, 0x7f +/* 0A7F20 802E8720 312A00FF */ andi $t2, $t1, 0xff +/* 0A7F24 802E8724 924E0001 */ lbu $t6, 1($s2) +/* 0A7F28 802E8728 000A5880 */ sll $t3, $t2, 2 +/* 0A7F2C 802E872C 3C018030 */ lui $at, %hi(gPitchBendFrequencyScale) +/* 0A7F30 802E8730 002B0821 */ addu $at, $at, $t3 +/* 0A7F34 802E8734 C42806E8 */ lwc1 $f8, %lo(gPitchBendFrequencyScale)($at) +/* 0A7F38 802E8738 35CF0080 */ ori $t7, $t6, 0x80 +/* 0A7F3C 802E873C A24F0001 */ sb $t7, 1($s2) +/* 0A7F40 802E8740 1000FF09 */ b .L_EU_802E8368 +/* 0A7F44 802E8744 E6480030 */ swc1 $f8, 0x30($s2) +glabel L_EU_802E8748 +/* 0A7F48 802E8748 0C0B9DA0 */ jal m64_read_u8 +/* 0A7F4C 802E874C 02202025 */ move $a0, $s1 +/* 0A7F50 802E8750 92590001 */ lbu $t9, 1($s2) +/* 0A7F54 802E8754 A2420009 */ sb $v0, 9($s2) +/* 0A7F58 802E8758 372D0020 */ ori $t5, $t9, 0x20 +/* 0A7F5C 802E875C 1000FF02 */ b .L_EU_802E8368 +/* 0A7F60 802E8760 A24D0001 */ sb $t5, 1($s2) +glabel L_EU_802E8764 +/* 0A7F64 802E8764 0C0B9DA0 */ jal m64_read_u8 +/* 0A7F68 802E8768 02202025 */ move $a0, $s1 +/* 0A7F6C 802E876C 924A0001 */ lbu $t2, 1($s2) +/* 0A7F70 802E8770 A242000A */ sb $v0, 0xa($s2) +/* 0A7F74 802E8774 354B0020 */ ori $t3, $t2, 0x20 +/* 0A7F78 802E8778 1000FEFB */ b .L_EU_802E8368 +/* 0A7F7C 802E877C A24B0001 */ sb $t3, 1($s2) +glabel L_EU_802E8780 +/* 0A7F80 802E8780 8E220000 */ lw $v0, ($s1) +/* 0A7F84 802E8784 80430000 */ lb $v1, ($v0) +/* 0A7F88 802E8788 244C0001 */ addiu $t4, $v0, 1 +/* 0A7F8C 802E878C AE2C0000 */ sw $t4, ($s1) +/* 0A7F90 802E8790 1000FEF5 */ b .L_EU_802E8368 +/* 0A7F94 802E8794 A643001E */ sh $v1, 0x1e($s2) +glabel L_EU_802E8798 +/* 0A7F98 802E8798 0C0B9DA5 */ jal m64_read_s16 +/* 0A7F9C 802E879C 02202025 */ move $a0, $s1 +/* 0A7FA0 802E87A0 8E8E0014 */ lw $t6, 0x14($s4) +/* 0A7FA4 802E87A4 304FFFFF */ andi $t7, $v0, 0xffff +/* 0A7FA8 802E87A8 01CFC021 */ addu $t8, $t6, $t7 +/* 0A7FAC 802E87AC 1000FEEE */ b .L_EU_802E8368 +/* 0A7FB0 802E87B0 AE580080 */ sw $t8, 0x80($s2) +glabel L_EU_802E87B4 +/* 0A7FB4 802E87B4 0C0B9DA0 */ jal m64_read_u8 +/* 0A7FB8 802E87B8 02202025 */ move $a0, $s1 +/* 0A7FBC 802E87BC 1000FEEA */ b .L_EU_802E8368 +/* 0A7FC0 802E87C0 A242007C */ sb $v0, 0x7c($s2) +glabel L_EU_802E87C4 +/* 0A7FC4 802E87C4 0C0B9DA0 */ jal m64_read_u8 +/* 0A7FC8 802E87C8 02202025 */ move $a0, $s1 +/* 0A7FCC 802E87CC 0002C8C0 */ sll $t9, $v0, 3 +/* 0A7FD0 802E87D0 A6590012 */ sh $t9, 0x12($s2) +/* 0A7FD4 802E87D4 A640000E */ sh $zero, 0xe($s2) +/* 0A7FD8 802E87D8 1000FEE3 */ b .L_EU_802E8368 +/* 0A7FDC 802E87DC A6400016 */ sh $zero, 0x16($s2) +glabel L_EU_802E87E0 +/* 0A7FE0 802E87E0 0C0B9DA0 */ jal m64_read_u8 +/* 0A7FE4 802E87E4 02202025 */ move $a0, $s1 +/* 0A7FE8 802E87E8 00021940 */ sll $v1, $v0, 5 +/* 0A7FEC 802E87EC A6430010 */ sh $v1, 0x10($s2) +/* 0A7FF0 802E87F0 A643000C */ sh $v1, 0xc($s2) +/* 0A7FF4 802E87F4 1000FEDC */ b .L_EU_802E8368 +/* 0A7FF8 802E87F8 A6400014 */ sh $zero, 0x14($s2) +glabel L_EU_802E87FC +/* 0A7FFC 802E87FC 0C0B9DA0 */ jal m64_read_u8 +/* 0A8000 802E8800 02202025 */ move $a0, $s1 +/* 0A8004 802E8804 000268C0 */ sll $t5, $v0, 3 +/* 0A8008 802E8808 A64D000E */ sh $t5, 0xe($s2) +/* 0A800C 802E880C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8010 802E8810 02202025 */ move $a0, $s1 +/* 0A8014 802E8814 000248C0 */ sll $t1, $v0, 3 +/* 0A8018 802E8818 A6490012 */ sh $t1, 0x12($s2) +/* 0A801C 802E881C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8020 802E8820 02202025 */ move $a0, $s1 +/* 0A8024 802E8824 00025100 */ sll $t2, $v0, 4 +/* 0A8028 802E8828 1000FECF */ b .L_EU_802E8368 +/* 0A802C 802E882C A64A0016 */ sh $t2, 0x16($s2) +glabel L_EU_802E8830 +/* 0A8030 802E8830 0C0B9DA0 */ jal m64_read_u8 +/* 0A8034 802E8834 02202025 */ move $a0, $s1 +/* 0A8038 802E8838 00025940 */ sll $t3, $v0, 5 +/* 0A803C 802E883C A64B000C */ sh $t3, 0xc($s2) +/* 0A8040 802E8840 0C0B9DA0 */ jal m64_read_u8 +/* 0A8044 802E8844 02202025 */ move $a0, $s1 +/* 0A8048 802E8848 00026140 */ sll $t4, $v0, 5 +/* 0A804C 802E884C A64C0010 */ sh $t4, 0x10($s2) +/* 0A8050 802E8850 0C0B9DA0 */ jal m64_read_u8 +/* 0A8054 802E8854 02202025 */ move $a0, $s1 +/* 0A8058 802E8858 00027100 */ sll $t6, $v0, 4 +/* 0A805C 802E885C 1000FEC2 */ b .L_EU_802E8368 +/* 0A8060 802E8860 A64E0014 */ sh $t6, 0x14($s2) +glabel L_EU_802E8864 +/* 0A8064 802E8864 0C0B9DA0 */ jal m64_read_u8 +/* 0A8068 802E8868 02202025 */ move $a0, $s1 +/* 0A806C 802E886C 00027900 */ sll $t7, $v0, 4 +/* 0A8070 802E8870 1000FEBD */ b .L_EU_802E8368 +/* 0A8074 802E8874 A64F0018 */ sh $t7, 0x18($s2) +glabel L_EU_802E8878 +/* 0A8078 802E8878 0C0B9DA0 */ jal m64_read_u8 +/* 0A807C 802E887C 02202025 */ move $a0, $s1 +/* 0A8080 802E8880 1000FEB9 */ b .L_EU_802E8368 +/* 0A8084 802E8884 A2420004 */ sb $v0, 4($s2) +glabel L_EU_802E8888 +/* 0A8088 802E8888 0C0B9DA0 */ jal m64_read_u8 +/* 0A808C 802E888C 02202025 */ move $a0, $s1 +/* 0A8090 802E8890 92980004 */ lbu $t8, 4($s4) +/* 0A8094 802E8894 3C038023 */ lui $v1, %hi(gAlBankSets) # $v1, 0x8023 +/* 0A8098 802E8898 8C6397D0 */ lw $v1, %lo(gAlBankSets)($v1) +/* 0A809C 802E889C 0018C840 */ sll $t9, $t8, 1 +/* 0A80A0 802E88A0 3C048022 */ lui $a0, %hi(gBankLoadedPool) # $a0, 0x8022 +/* 0A80A4 802E88A4 00796821 */ addu $t5, $v1, $t9 +/* 0A80A8 802E88A8 95A70000 */ lhu $a3, ($t5) +/* 0A80AC 802E88AC 24842840 */ addiu $a0, %lo(gBankLoadedPool) # addiu $a0, $a0, 0x2840 +/* 0A80B0 802E88B0 24050002 */ li $a1, 2 +/* 0A80B4 802E88B4 00E34821 */ addu $t1, $a3, $v1 +/* 0A80B8 802E88B8 91280000 */ lbu $t0, ($t1) +/* 0A80BC 802E88BC 00E85021 */ addu $t2, $a3, $t0 +/* 0A80C0 802E88C0 01425823 */ subu $t3, $t2, $v0 +/* 0A80C4 802E88C4 01636021 */ addu $t4, $t3, $v1 +/* 0A80C8 802E88C8 91900000 */ lbu $s0, ($t4) +/* 0A80CC 802E88CC 0C0B89CF */ jal get_bank_or_seq +/* 0A80D0 802E88D0 02003025 */ move $a2, $s0 +/* 0A80D4 802E88D4 1040FEA4 */ beqz $v0, .L_EU_802E8368 +/* 0A80D8 802E88D8 00000000 */ nop +/* 0A80DC 802E88DC 1000FEA2 */ b .L_EU_802E8368 +/* 0A80E0 802E88E0 A2500006 */ sb $s0, 6($s2) +glabel L_EU_802E88E4 +/* 0A80E4 802E88E4 326E00FF */ andi $t6, $s3, 0xff +/* 0A80E8 802E88E8 AFAE0034 */ sw $t6, 0x34($sp) +/* 0A80EC 802E88EC 0C0B9DA0 */ jal m64_read_u8 +/* 0A80F0 802E88F0 02202025 */ move $a0, $s1 +/* 0A80F4 802E88F4 305000FF */ andi $s0, $v0, 0xff +/* 0A80F8 802E88F8 0C0B9DA5 */ jal m64_read_s16 +/* 0A80FC 802E88FC 02202025 */ move $a0, $s1 +/* 0A8100 802E8900 8E8F0014 */ lw $t7, 0x14($s4) +/* 0A8104 802E8904 8FB90034 */ lw $t9, 0x34($sp) +/* 0A8108 802E8908 3058FFFF */ andi $t8, $v0, 0xffff +/* 0A810C 802E890C 01F81821 */ addu $v1, $t7, $t8 +/* 0A8110 802E8910 03306821 */ addu $t5, $t9, $s0 +/* 0A8114 802E8914 1000FE94 */ b .L_EU_802E8368 +/* 0A8118 802E8918 A06D0000 */ sb $t5, ($v1) +glabel L_EU_802E891C +/* 0A811C 802E891C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8120 802E8920 02202025 */ move $a0, $s1 +/* 0A8124 802E8924 240100C8 */ li $at, 200 +/* 0A8128 802E8928 16010005 */ bne $s0, $at, .L080200740 +/* 0A812C 802E892C 02001825 */ move $v1, $s0 +/* 0A8130 802E8930 02629823 */ subu $s3, $s3, $v0 +/* 0A8134 802E8934 00135E00 */ sll $t3, $s3, 0x18 +/* 0A8138 802E8938 1000FE8B */ b .L_EU_802E8368 +/* 0A813C 802E893C 000B9E03 */ sra $s3, $t3, 0x18 +.L080200740: +/* 0A8140 802E8940 240100CC */ li $at, 204 +/* 0A8144 802E8944 14610005 */ bne $v1, $at, .L08020075C +/* 0A8148 802E8948 02629824 */ and $s3, $s3, $v0 +/* 0A814C 802E894C 00029E00 */ sll $s3, $v0, 0x18 +/* 0A8150 802E8950 00137603 */ sra $t6, $s3, 0x18 +/* 0A8154 802E8954 1000FE84 */ b .L_EU_802E8368 +/* 0A8158 802E8958 01C09825 */ move $s3, $t6 +.L08020075C: +/* 0A815C 802E895C 0013CE00 */ sll $t9, $s3, 0x18 +/* 0A8160 802E8960 1000FE81 */ b .L_EU_802E8368 +/* 0A8164 802E8964 00199E03 */ sra $s3, $t9, 0x18 +glabel L_EU_802E8968 +/* 0A8168 802E8968 0C0B9DA0 */ jal m64_read_u8 +/* 0A816C 802E896C 02202025 */ move $a0, $s1 +/* 0A8170 802E8970 1000FE7D */ b .L_EU_802E8368 +/* 0A8174 802E8974 A2420003 */ sb $v0, 3($s2) +glabel L_EU_802E8978 +/* 0A8178 802E8978 0C0B9DA5 */ jal m64_read_s16 +/* 0A817C 802E897C 02202025 */ move $a0, $s1 +/* 0A8180 802E8980 8E890014 */ lw $t1, 0x14($s4) +/* 0A8184 802E8984 304AFFFF */ andi $t2, $v0, 0xffff +/* 0A8188 802E8988 01535821 */ addu $t3, $t2, $s3 +/* 0A818C 802E898C 012B6021 */ addu $t4, $t1, $t3 +/* 0A8190 802E8990 1000FE75 */ b .L_EU_802E8368 +/* 0A8194 802E8994 81930000 */ lb $s3, ($t4) +glabel L_EU_802E8998 +/* 0A8198 802E8998 0C0B9DA0 */ jal m64_read_u8 +/* 0A819C 802E899C 02202025 */ move $a0, $s1 +/* 0A81A0 802E89A0 92590000 */ lbu $t9, ($s2) +/* 0A81A4 802E89A4 00027880 */ sll $t7, $v0, 2 +/* 0A81A8 802E89A8 31F80004 */ andi $t8, $t7, 4 +/* 0A81AC 802E89AC 332DFFFB */ andi $t5, $t9, 0xfffb +/* 0A81B0 802E89B0 030D5025 */ or $t2, $t8, $t5 +/* 0A81B4 802E89B4 1000FE6C */ b .L_EU_802E8368 +/* 0A81B8 802E89B8 A24A0000 */ sb $t2, ($s2) +glabel L_EU_802E89BC +/* 0A81BC 802E89BC 0C0B9DA0 */ jal m64_read_u8 +/* 0A81C0 802E89C0 02202025 */ move $a0, $s1 +/* 0A81C4 802E89C4 1000FE68 */ b .L_EU_802E8368 +/* 0A81C8 802E89C8 A2420002 */ sb $v0, 2($s2) +glabel L_EU_802E89CC +/* 0A81CC 802E89CC 0C0B9DA0 */ jal m64_read_u8 +/* 0A81D0 802E89D0 02202025 */ move $a0, $s1 +/* 0A81D4 802E89D4 1000FE64 */ b .L_EU_802E8368 +/* 0A81D8 802E89D8 A242007D */ sb $v0, 0x7d($s2) +glabel L_EU_802E89DC +/* 0A81DC 802E89DC 0C0B9DA0 */ jal m64_read_u8 +/* 0A81E0 802E89E0 02202025 */ move $a0, $s1 +/* 0A81E4 802E89E4 1000FE60 */ b .L_EU_802E8368 +/* 0A81E8 802E89E8 A2420007 */ sb $v0, 7($s2) +glabel L_EU_802E89EC +/* 0A81EC 802E89EC 2401FFFF */ li $at, -1 +/* 0A81F0 802E89F0 1261FE5D */ beq $s3, $at, .L_EU_802E8368 +/* 0A81F4 802E89F4 00000000 */ nop +/* 0A81F8 802E89F8 92240018 */ lbu $a0, 0x18($s1) +/* 0A81FC 802E89FC 8E2B0000 */ lw $t3, ($s1) +/* 0A8200 802E8A00 8E490034 */ lw $t1, 0x34($s2) +/* 0A8204 802E8A04 00046080 */ sll $t4, $a0, 2 +/* 0A8208 802E8A08 022C7021 */ addu $t6, $s1, $t4 +/* 0A820C 802E8A0C ADCB0004 */ sw $t3, 4($t6) +/* 0A8210 802E8A10 922F0018 */ lbu $t7, 0x18($s1) +/* 0A8214 802E8A14 00131040 */ sll $v0, $s3, 1 +/* 0A8218 802E8A18 01221821 */ addu $v1, $t1, $v0 +/* 0A821C 802E8A1C 25F90001 */ addiu $t9, $t7, 1 +/* 0A8220 802E8A20 A2390018 */ sb $t9, 0x18($s1) +/* 0A8224 802E8A24 906D0000 */ lbu $t5, ($v1) +/* 0A8228 802E8A28 90780001 */ lbu $t8, 1($v1) +/* 0A822C 802E8A2C 8E8C0014 */ lw $t4, 0x14($s4) +/* 0A8230 802E8A30 000D5200 */ sll $t2, $t5, 8 +/* 0A8234 802E8A34 030A3821 */ addu $a3, $t8, $t2 +/* 0A8238 802E8A38 30E9FFFF */ andi $t1, $a3, 0xffff +/* 0A823C 802E8A3C 01895821 */ addu $t3, $t4, $t1 +/* 0A8240 802E8A40 1000FE49 */ b .L_EU_802E8368 +/* 0A8244 802E8A44 AE2B0000 */ sw $t3, ($s1) +glabel L_EU_802E8A48 +/* 0A8248 802E8A48 0C0B9DA0 */ jal m64_read_u8 +/* 0A824C 802E8A4C 02202025 */ move $a0, $s1 +/* 0A8250 802E8A50 1000FE45 */ b .L_EU_802E8368 +/* 0A8254 802E8A54 A2420008 */ sb $v0, 8($s2) +glabel L_EU_802E8A58 +/* 0A8258 802E8A58 0C0B9DA5 */ jal m64_read_s16 +/* 0A825C 802E8A5C 02202025 */ move $a0, $s1 +/* 0A8260 802E8A60 8E8E0014 */ lw $t6, 0x14($s4) +/* 0A8264 802E8A64 304FFFFF */ andi $t7, $v0, 0xffff +/* 0A8268 802E8A68 01CF1821 */ addu $v1, $t6, $t7 +/* 0A826C 802E8A6C 90790000 */ lbu $t9, ($v1) +/* 0A8270 802E8A70 24630007 */ addiu $v1, $v1, 7 +/* 0A8274 802E8A74 A2590003 */ sb $t9, 3($s2) +/* 0A8278 802E8A78 906DFFFA */ lbu $t5, -6($v1) +/* 0A827C 802E8A7C 92590001 */ lbu $t9, 1($s2) +/* 0A8280 802E8A80 A24D0002 */ sb $t5, 2($s2) +/* 0A8284 802E8A84 9078FFFB */ lbu $t8, -5($v1) +/* 0A8288 802E8A88 372D0020 */ ori $t5, $t9, 0x20 +/* 0A828C 802E8A8C A2580005 */ sb $t8, 5($s2) +/* 0A8290 802E8A90 806AFFFC */ lb $t2, -4($v1) +/* 0A8294 802E8A94 A64A001E */ sh $t2, 0x1e($s2) +/* 0A8298 802E8A98 9069FFFD */ lbu $t1, -3($v1) +/* 0A829C 802E8A9C A2490009 */ sb $t1, 9($s2) +/* 0A82A0 802E8AA0 906CFFFE */ lbu $t4, -2($v1) +/* 0A82A4 802E8AA4 A24C000A */ sb $t4, 0xa($s2) +/* 0A82A8 802E8AA8 906BFFFF */ lbu $t3, -1($v1) +/* 0A82AC 802E8AAC A24B0004 */ sb $t3, 4($s2) +/* 0A82B0 802E8AB0 906E0000 */ lbu $t6, ($v1) +/* 0A82B4 802E8AB4 A24D0001 */ sb $t5, 1($s2) +/* 0A82B8 802E8AB8 1000FE2B */ b .L_EU_802E8368 +/* 0A82BC 802E8ABC A24E0007 */ sb $t6, 7($s2) +glabel L_EU_802E8AC0 +/* 0A82C0 802E8AC0 0C0B9DA0 */ jal m64_read_u8 +/* 0A82C4 802E8AC4 02202025 */ move $a0, $s1 +/* 0A82C8 802E8AC8 A2420003 */ sb $v0, 3($s2) +/* 0A82CC 802E8ACC 0C0B9DA0 */ jal m64_read_u8 +/* 0A82D0 802E8AD0 02202025 */ move $a0, $s1 +/* 0A82D4 802E8AD4 A2420002 */ sb $v0, 2($s2) +/* 0A82D8 802E8AD8 0C0B9DA0 */ jal m64_read_u8 +/* 0A82DC 802E8ADC 02202025 */ move $a0, $s1 +/* 0A82E0 802E8AE0 A2420005 */ sb $v0, 5($s2) +/* 0A82E4 802E8AE4 0C0B9DA0 */ jal m64_read_u8 +/* 0A82E8 802E8AE8 02202025 */ move $a0, $s1 +/* 0A82EC 802E8AEC 0002C600 */ sll $t8, $v0, 0x18 +/* 0A82F0 802E8AF0 00185603 */ sra $t2, $t8, 0x18 +/* 0A82F4 802E8AF4 A64A001E */ sh $t2, 0x1e($s2) +/* 0A82F8 802E8AF8 0C0B9DA0 */ jal m64_read_u8 +/* 0A82FC 802E8AFC 02202025 */ move $a0, $s1 +/* 0A8300 802E8B00 A2420009 */ sb $v0, 9($s2) +/* 0A8304 802E8B04 0C0B9DA0 */ jal m64_read_u8 +/* 0A8308 802E8B08 02202025 */ move $a0, $s1 +/* 0A830C 802E8B0C A242000A */ sb $v0, 0xa($s2) +/* 0A8310 802E8B10 0C0B9DA0 */ jal m64_read_u8 +/* 0A8314 802E8B14 02202025 */ move $a0, $s1 +/* 0A8318 802E8B18 A2420004 */ sb $v0, 4($s2) +/* 0A831C 802E8B1C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8320 802E8B20 02202025 */ move $a0, $s1 +/* 0A8324 802E8B24 924C0001 */ lbu $t4, 1($s2) +/* 0A8328 802E8B28 A2420007 */ sb $v0, 7($s2) +/* 0A832C 802E8B2C 358B0020 */ ori $t3, $t4, 0x20 +/* 0A8330 802E8B30 1000FE0D */ b .L_EU_802E8368 +/* 0A8334 802E8B34 A24B0001 */ sb $t3, 1($s2) +glabel L_EU_802E8B38 +/* 0A8338 802E8B38 3C013F80 */ li $at, 0x3F800000 # 1.000000 +/* 0A833C 802E8B3C 44815000 */ mtc1 $at, $f10 +/* 0A8340 802E8B40 A6400012 */ sh $zero, 0x12($s2) +/* 0A8344 802E8B44 A640000E */ sh $zero, 0xe($s2) +/* 0A8348 802E8B48 A6400016 */ sh $zero, 0x16($s2) +/* 0A834C 802E8B4C A6400010 */ sh $zero, 0x10($s2) +/* 0A8350 802E8B50 A640000C */ sh $zero, 0xc($s2) +/* 0A8354 802E8B54 A6400014 */ sh $zero, 0x14($s2) +/* 0A8358 802E8B58 1000FE03 */ b .L_EU_802E8368 +/* 0A835C 802E8B5C E64A0030 */ swc1 $f10, 0x30($s2) +glabel L_EU_802E8B60 +/* 0A8360 802E8B60 0C0B9DA0 */ jal m64_read_u8 +/* 0A8364 802E8B64 02202025 */ move $a0, $s1 +/* 0A8368 802E8B68 1000FDFF */ b .L_EU_802E8368 +/* 0A836C 802E8B6C A2420005 */ sb $v0, 5($s2) +.L080200970: +/* 0A8370 802E8B70 306E00F0 */ andi $t6, $v1, 0xf0 +/* 0A8374 802E8B74 3064000F */ andi $a0, $v1, 0xf +/* 0A8378 802E8B78 2DC100B1 */ sltiu $at, $t6, 0xb1 +/* 0A837C 802E8B7C 1020FDFA */ beqz $at, .L_EU_802E8368 +/* 0A8380 802E8B80 308800FF */ andi $t0, $a0, 0xff +/* 0A8384 802E8B84 000E7080 */ sll $t6, $t6, 2 +/* 0A8388 802E8B88 3C018030 */ lui $at, %hi(jtbl_EU_80306810) +/* 0A838C 802E8B8C 002E0821 */ addu $at, $at, $t6 +/* 0A8390 802E8B90 8C2E6810 */ lw $t6, %lo(jtbl_EU_80306810)($at) +/* 0A8394 802E8B94 01C00008 */ jr $t6 +/* 0A8398 802E8B98 00000000 */ nop +glabel L_EU_802E8B9C +/* 0A839C 802E8B9C 308F00FF */ andi $t7, $a0, 0xff +/* 0A83A0 802E8BA0 000FC880 */ sll $t9, $t7, 2 +/* 0A83A4 802E8BA4 02596821 */ addu $t5, $s2, $t9 +/* 0A83A8 802E8BA8 8DA30048 */ lw $v1, 0x48($t5) +/* 0A83AC 802E8BAC 10600007 */ beqz $v1, .L0802009CC +/* 0A83B0 802E8BB0 00000000 */ nop +/* 0A83B4 802E8BB4 8C730000 */ lw $s3, ($v1) +/* 0A83B8 802E8BB8 0013C040 */ sll $t8, $s3, 1 +/* 0A83BC 802E8BBC 001857C2 */ srl $t2, $t8, 0x1f +/* 0A83C0 802E8BC0 000A4E00 */ sll $t1, $t2, 0x18 +/* 0A83C4 802E8BC4 1000FDE8 */ b .L_EU_802E8368 +/* 0A83C8 802E8BC8 00099E03 */ sra $s3, $t1, 0x18 +.L0802009CC: +/* 0A83CC 802E8BCC 1000FDE6 */ b .L_EU_802E8368 +/* 0A83D0 802E8BD0 2413FFFF */ li $s3, -1 +glabel L_EU_802E8BD4 +/* 0A83D4 802E8BD4 308B00FF */ andi $t3, $a0, 0xff +/* 0A83D8 802E8BD8 024B7021 */ addu $t6, $s2, $t3 +/* 0A83DC 802E8BDC 1000FDE2 */ b .L_EU_802E8368 +/* 0A83E0 802E8BE0 A1D30058 */ sb $s3, 0x58($t6) +glabel L_EU_802E8BE4 +/* 0A83E4 802E8BE4 308300FF */ andi $v1, $a0, 0xff +/* 0A83E8 802E8BE8 02432821 */ addu $a1, $s2, $v1 +/* 0A83EC 802E8BEC 28610004 */ slti $at, $v1, 4 +/* 0A83F0 802E8BF0 1020FDDD */ beqz $at, .L_EU_802E8368 +/* 0A83F4 802E8BF4 80B30058 */ lb $s3, 0x58($a1) +/* 0A83F8 802E8BF8 240FFFFF */ li $t7, -1 +/* 0A83FC 802E8BFC 1000FDDA */ b .L_EU_802E8368 +/* 0A8400 802E8C00 A0AF0058 */ sb $t7, 0x58($a1) +glabel L_EU_802E8C04 +/* 0A8404 802E8C04 309900FF */ andi $t9, $a0, 0xff +/* 0A8408 802E8C08 02596821 */ addu $t5, $s2, $t9 +/* 0A840C 802E8C0C 81B80058 */ lb $t8, 0x58($t5) +/* 0A8410 802E8C10 02789823 */ subu $s3, $s3, $t8 +/* 0A8414 802E8C14 00135600 */ sll $t2, $s3, 0x18 +/* 0A8418 802E8C18 1000FDD3 */ b .L_EU_802E8368 +/* 0A841C 802E8C1C 000A9E03 */ sra $s3, $t2, 0x18 +glabel L_EU_802E8C20 +/* 0A8420 802E8C20 308C00FF */ andi $t4, $a0, 0xff +/* 0A8424 802E8C24 1000005C */ b .L_EU_802E8D98 +/* 0A8428 802E8C28 A64C001A */ sh $t4, 0x1a($s2) +glabel L_EU_802E8C2C +/* 0A842C 802E8C2C 0C0B9DA5 */ jal m64_read_s16 +/* 0A8430 802E8C30 02202025 */ move $a0, $s1 +/* 0A8434 802E8C34 02003025 */ move $a2, $s0 +/* 0A8438 802E8C38 30C5000F */ andi $a1, $a2, 0xf +/* 0A843C 802E8C3C 00A03025 */ move $a2, $a1 +/* 0A8440 802E8C40 AFA50034 */ sw $a1, 0x34($sp) +/* 0A8444 802E8C44 02402025 */ move $a0, $s2 +/* 0A8448 802E8C48 0C0B9BDC */ jal seq_channel_set_layer +/* 0A844C 802E8C4C A7A20052 */ sh $v0, 0x52($sp) +/* 0A8450 802E8C50 8FA60034 */ lw $a2, 0x34($sp) +/* 0A8454 802E8C54 1440FDC4 */ bnez $v0, .L_EU_802E8368 +/* 0A8458 802E8C58 97A70052 */ lhu $a3, 0x52($sp) +/* 0A845C 802E8C5C 8E8E0014 */ lw $t6, 0x14($s4) +/* 0A8460 802E8C60 0006C880 */ sll $t9, $a2, 2 +/* 0A8464 802E8C64 02596821 */ addu $t5, $s2, $t9 +/* 0A8468 802E8C68 8DB80048 */ lw $t8, 0x48($t5) +/* 0A846C 802E8C6C 01C77821 */ addu $t7, $t6, $a3 +/* 0A8470 802E8C70 1000FDBD */ b .L_EU_802E8368 +/* 0A8474 802E8C74 AF0F0050 */ sw $t7, 0x50($t8) +glabel L_EU_802E8C78 +/* 0A8478 802E8C78 02002825 */ move $a1, $s0 +/* 0A847C 802E8C7C 30AA000F */ andi $t2, $a1, 0xf +/* 0A8480 802E8C80 01402825 */ move $a1, $t2 +/* 0A8484 802E8C84 0C0B9C2D */ jal seq_channel_layer_free +/* 0A8488 802E8C88 02402025 */ move $a0, $s2 +/* 0A848C 802E8C8C 1000FDB6 */ b .L_EU_802E8368 +/* 0A8490 802E8C90 00000000 */ nop +glabel L_EU_802E8C94 +/* 0A8494 802E8C94 2401FFFF */ li $at, -1 +/* 0A8498 802E8C98 1261FDB3 */ beq $s3, $at, .L_EU_802E8368 +/* 0A849C 802E8C9C 02402025 */ move $a0, $s2 +/* 0A84A0 802E8CA0 02003025 */ move $a2, $s0 +/* 0A84A4 802E8CA4 30C5000F */ andi $a1, $a2, 0xf +/* 0A84A8 802E8CA8 00A03025 */ move $a2, $a1 +/* 0A84AC 802E8CAC 0C0B9BDC */ jal seq_channel_set_layer +/* 0A84B0 802E8CB0 AFA50034 */ sw $a1, 0x34($sp) +/* 0A84B4 802E8CB4 2401FFFF */ li $at, -1 +/* 0A84B8 802E8CB8 1041FDAB */ beq $v0, $at, .L_EU_802E8368 +/* 0A84BC 802E8CBC 8FA60034 */ lw $a2, 0x34($sp) +/* 0A84C0 802E8CC0 8E4C0034 */ lw $t4, 0x34($s2) +/* 0A84C4 802E8CC4 00135840 */ sll $t3, $s3, 1 +/* 0A84C8 802E8CC8 8E980014 */ lw $t8, 0x14($s4) +/* 0A84CC 802E8CCC 018B1821 */ addu $v1, $t4, $t3 +/* 0A84D0 802E8CD0 90790000 */ lbu $t9, ($v1) +/* 0A84D4 802E8CD4 906E0001 */ lbu $t6, 1($v1) +/* 0A84D8 802E8CD8 00064880 */ sll $t1, $a2, 2 +/* 0A84DC 802E8CDC 00196A00 */ sll $t5, $t9, 8 +/* 0A84E0 802E8CE0 02496021 */ addu $t4, $s2, $t1 +/* 0A84E4 802E8CE4 01CD3821 */ addu $a3, $t6, $t5 +/* 0A84E8 802E8CE8 8D8B0048 */ lw $t3, 0x48($t4) +/* 0A84EC 802E8CEC 30EFFFFF */ andi $t7, $a3, 0xffff +/* 0A84F0 802E8CF0 030F5021 */ addu $t2, $t8, $t7 +/* 0A84F4 802E8CF4 1000FD9C */ b .L_EU_802E8368 +/* 0A84F8 802E8CF8 AD6A0050 */ sw $t2, 0x50($t3) +glabel L_EU_802E8CFC +/* 0A84FC 802E8CFC 0C0B9DA5 */ jal m64_read_s16 +/* 0A8500 802E8D00 02202025 */ move $a0, $s1 +/* 0A8504 802E8D04 8E8E0014 */ lw $t6, 0x14($s4) +/* 0A8508 802E8D08 02002825 */ move $a1, $s0 +/* 0A850C 802E8D0C 30B9000F */ andi $t9, $a1, 0xf +/* 0A8510 802E8D10 304DFFFF */ andi $t5, $v0, 0xffff +/* 0A8514 802E8D14 03202825 */ move $a1, $t9 +/* 0A8518 802E8D18 02802025 */ move $a0, $s4 +/* 0A851C 802E8D1C 0C0B9CFA */ jal sequence_channel_enable +/* 0A8520 802E8D20 01CD3021 */ addu $a2, $t6, $t5 +/* 0A8524 802E8D24 1000FD90 */ b .L_EU_802E8368 +/* 0A8528 802E8D28 00000000 */ nop +glabel L_EU_802E8D2C +/* 0A852C 802E8D2C 3218000F */ andi $t8, $s0, 0xf +/* 0A8530 802E8D30 00184880 */ sll $t1, $t8, 2 +/* 0A8534 802E8D34 02896021 */ addu $t4, $s4, $t1 +/* 0A8538 802E8D38 0C0B9C41 */ jal sequence_channel_disable +/* 0A853C 802E8D3C 8D840030 */ lw $a0, 0x30($t4) +/* 0A8540 802E8D40 1000FD89 */ b .L_EU_802E8368 +/* 0A8544 802E8D44 00000000 */ nop +glabel L_EU_802E8D48 +/* 0A8548 802E8D48 02202025 */ move $a0, $s1 +/* 0A854C 802E8D4C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8550 802E8D50 A3A80055 */ sb $t0, 0x55($sp) +/* 0A8554 802E8D54 93A80055 */ lbu $t0, 0x55($sp) +/* 0A8558 802E8D58 00085080 */ sll $t2, $t0, 2 +/* 0A855C 802E8D5C 028A5821 */ addu $t3, $s4, $t2 +/* 0A8560 802E8D60 8D790030 */ lw $t9, 0x30($t3) +/* 0A8564 802E8D64 03227021 */ addu $t6, $t9, $v0 +/* 0A8568 802E8D68 1000FD7F */ b .L_EU_802E8368 +/* 0A856C 802E8D6C A1D30058 */ sb $s3, 0x58($t6) +glabel L_EU_802E8D70 +/* 0A8570 802E8D70 02202025 */ move $a0, $s1 +/* 0A8574 802E8D74 0C0B9DA0 */ jal m64_read_u8 +/* 0A8578 802E8D78 A3A80055 */ sb $t0, 0x55($sp) +/* 0A857C 802E8D7C 93A80055 */ lbu $t0, 0x55($sp) +/* 0A8580 802E8D80 00086880 */ sll $t5, $t0, 2 +/* 0A8584 802E8D84 028D7821 */ addu $t7, $s4, $t5 +/* 0A8588 802E8D88 8DF80030 */ lw $t8, 0x30($t7) +/* 0A858C 802E8D8C 03024821 */ addu $t1, $t8, $v0 +/* 0A8590 802E8D90 1000FD75 */ b .L_EU_802E8368 +/* 0A8594 802E8D94 81330058 */ lb $s3, 0x58($t1) +glabel L_EU_802E8D98 +.L_EU_802E8D98: +/* 0A8598 802E8D98 02408825 */ move $s1, $s2 +.L080200B9C: +/* 0A859C 802E8D9C 24120010 */ li $s2, 16 +/* 0A85A0 802E8DA0 00008025 */ move $s0, $zero +.L080200BA4: +/* 0A85A4 802E8DA4 8E240048 */ lw $a0, 0x48($s1) +/* 0A85A8 802E8DA8 50800004 */ beql $a0, $zero, .L080200BBC +/* 0A85AC 802E8DAC 26100004 */ addiu $s0, $s0, 4 +/* 0A85B0 802E8DB0 0C0B9DC2 */ jal seq_channel_layer_process_script +/* 0A85B4 802E8DB4 00000000 */ nop +/* 0A85B8 802E8DB8 26100004 */ addiu $s0, $s0, 4 +.L080200BBC: +/* 0A85BC 802E8DBC 1612FFF9 */ bne $s0, $s2, .L080200BA4 +/* 0A85C0 802E8DC0 26310004 */ addiu $s1, $s1, 4 +.L080200BC4: +/* 0A85C4 802E8DC4 8FBF002C */ lw $ra, 0x2c($sp) +.L080200BC8: +/* 0A85C8 802E8DC8 8FB00018 */ lw $s0, 0x18($sp) +/* 0A85CC 802E8DCC 8FB1001C */ lw $s1, 0x1c($sp) +/* 0A85D0 802E8DD0 8FB20020 */ lw $s2, 0x20($sp) +/* 0A85D4 802E8DD4 8FB30024 */ lw $s3, 0x24($sp) +/* 0A85D8 802E8DD8 8FB40028 */ lw $s4, 0x28($sp) +/* 0A85DC 802E8DDC 03E00008 */ jr $ra +/* 0A85E0 802E8DE0 27BD0060 */ addiu $sp, $sp, 0x60 diff --git a/asm/non_matchings/eu/audio/sequence_player_process_sequence.s b/asm/non_matchings/eu/audio/sequence_player_process_sequence.s new file mode 100644 index 0000000..1d8440b --- /dev/null +++ b/asm/non_matchings/eu/audio/sequence_player_process_sequence.s @@ -0,0 +1,698 @@ +.late_rodata +.late_rodata_alignment 4 +glabel jtbl_EU_80306AD4 + .word L_EU_802E9530 + .word L_EU_802E9520, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9510 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9500 + .word L_EU_802E94D4, L_EU_802E94D4 + .word L_EU_802E94C4, L_EU_802E94B4 + .word L_EU_802E9488, L_EU_802E946C + .word L_EU_802E9450, L_EU_802E9024 + .word L_EU_802E9424, L_EU_802E9310 + .word L_EU_802E938C, L_EU_802E928C + .word L_EU_802E928C, L_EU_802E926C + .word L_EU_802E9268, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9258 + .word L_EU_802E9230, L_EU_802E91E8 + .word L_EU_802E91E8, L_EU_802E91E8 + .word L_EU_802E9190, L_EU_802E9024 + .word L_EU_802E9148, L_EU_802E9110 + .word L_EU_802E9190, L_EU_802E9190 + .word L_EU_802E9190, L_EU_802E90CC + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024 + +glabel jtbl_EU_80306BB4 + .word L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E95C0 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E95CC + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E95D4 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E95DC + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + .word L_EU_802E9024, L_EU_802E9024 + +.text +glabel sequence_player_process_sequence +/* 0A85E4 802E8DE4 27BDFFA0 */ addiu $sp, $sp, -0x60 +/* 0A85E8 802E8DE8 AFBF002C */ sw $ra, 0x2c($sp) +/* 0A85EC 802E8DEC AFB30028 */ sw $s3, 0x28($sp) +/* 0A85F0 802E8DF0 AFB20024 */ sw $s2, 0x24($sp) +/* 0A85F4 802E8DF4 AFB10020 */ sw $s1, 0x20($sp) +/* 0A85F8 802E8DF8 AFB0001C */ sw $s0, 0x1c($sp) +/* 0A85FC 802E8DFC 8C820000 */ lw $v0, ($a0) +/* 0A8600 802E8E00 00808825 */ move $s1, $a0 +/* 0A8604 802E8E04 24010001 */ li $at, 1 +/* 0A8608 802E8E08 000277C2 */ srl $t6, $v0, 0x1f +/* 0A860C 802E8E0C 11C00212 */ beqz $t6, .L080201458 +/* 0A8610 802E8E10 00027900 */ sll $t7, $v0, 4 +/* 0A8614 802E8E14 000FC7C2 */ srl $t8, $t7, 0x1f +/* 0A8618 802E8E18 17010039 */ bne $t8, $at, .L080200D00 +/* 0A861C 802E8E1C 000268C0 */ sll $t5, $v0, 3 +/* 0A8620 802E8E20 24900108 */ addiu $s0, $a0, 0x108 +/* 0A8624 802E8E24 02002025 */ move $a0, $s0 +/* 0A8628 802E8E28 00002825 */ move $a1, $zero +/* 0A862C 802E8E2C 0C0BBDE0 */ jal osRecvMesg +/* 0A8630 802E8E30 00003025 */ move $a2, $zero +/* 0A8634 802E8E34 2401FFFF */ li $at, -1 +/* 0A8638 802E8E38 50410208 */ beql $v0, $at, .L08020145C +/* 0A863C 802E8E3C 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A8640 802E8E40 8E390144 */ lw $t9, 0x144($s1) +/* 0A8644 802E8E44 3C128023 */ lui $s2, %hi(gCtlEntries) # $s2, 0x8023 +/* 0A8648 802E8E48 265297D8 */ addiu $s2, %lo(gCtlEntries) # addiu $s2, $s2, -0x6828 +/* 0A864C 802E8E4C 57200024 */ bnezl $t9, .L080200CE0 +/* 0A8650 802E8E50 262C0124 */ addiu $t4, $s1, 0x124 +/* 0A8654 802E8E54 92220006 */ lbu $v0, 6($s1) +/* 0A8658 802E8E58 2413000C */ li $s3, 12 +/* 0A865C 802E8E5C 92280000 */ lbu $t0, ($s1) +/* 0A8660 802E8E60 00530019 */ multu $v0, $s3 +/* 0A8664 802E8E64 3C0C8023 */ lui $t4, %hi(gAlTbl) # $t4, 0x8023 +/* 0A8668 802E8E68 3109FFF7 */ andi $t1, $t0, 0xfff7 +/* 0A866C 802E8E6C A2290000 */ sb $t1, ($s1) +/* 0A8670 802E8E70 8E4A0000 */ lw $t2, ($s2) +/* 0A8674 802E8E74 8D8C97CC */ lw $t4, %lo(gAlTbl)($t4) +/* 0A8678 802E8E78 000268C0 */ sll $t5, $v0, 3 +/* 0A867C 802E8E7C 018D7021 */ addu $t6, $t4, $t5 +/* 0A8680 802E8E80 8DC50004 */ lw $a1, 4($t6) +/* 0A8684 802E8E84 00005812 */ mflo $t3 +/* 0A8688 802E8E88 014B8021 */ addu $s0, $t2, $t3 +/* 0A868C 802E8E8C 8E040004 */ lw $a0, 4($s0) +/* 0A8690 802E8E90 92060001 */ lbu $a2, 1($s0) +/* 0A8694 802E8E94 92070002 */ lbu $a3, 2($s0) +/* 0A8698 802E8E98 0C0B8F0E */ jal patch_audio_bank +/* 0A869C 802E8E9C 2484FFFC */ addiu $a0, $a0, -4 +/* 0A86A0 802E8EA0 92380006 */ lbu $t8, 6($s1) +/* 0A86A4 802E8EA4 8E4F0000 */ lw $t7, ($s2) +/* 0A86A8 802E8EA8 3C038022 */ lui $v1, %hi(gBankLoadStatus) # $v1, 0x8022 +/* 0A86AC 802E8EAC 03130019 */ multu $t8, $s3 +/* 0A86B0 802E8EB0 24632C18 */ addiu $v1, %lo(gBankLoadStatus) # addiu $v1, $v1, 0x2c18 +/* 0A86B4 802E8EB4 24040002 */ li $a0, 2 +/* 0A86B8 802E8EB8 0000C812 */ mflo $t9 +/* 0A86BC 802E8EBC 01F98021 */ addu $s0, $t7, $t9 +/* 0A86C0 802E8EC0 8E080004 */ lw $t0, 4($s0) +/* 0A86C4 802E8EC4 8D09FFFC */ lw $t1, -4($t0) +/* 0A86C8 802E8EC8 AE090008 */ sw $t1, 8($s0) +/* 0A86CC 802E8ECC 922A0006 */ lbu $t2, 6($s1) +/* 0A86D0 802E8ED0 006A5821 */ addu $t3, $v1, $t2 +/* 0A86D4 802E8ED4 100001E0 */ b .L080201458 +/* 0A86D8 802E8ED8 A1640000 */ sb $a0, ($t3) +/* 0A86DC 802E8EDC 262C0124 */ addiu $t4, $s1, 0x124 +.L080200CE0: +/* 0A86E0 802E8EE0 AFAC0010 */ sw $t4, 0x10($sp) +/* 0A86E4 802E8EE4 26240140 */ addiu $a0, $s1, 0x140 +/* 0A86E8 802E8EE8 2625013C */ addiu $a1, $s1, 0x13c +/* 0A86EC 802E8EEC 26260144 */ addiu $a2, $s1, 0x144 +/* 0A86F0 802E8EF0 0C0B8CEA */ jal audio_dma_partial_copy_async +/* 0A86F4 802E8EF4 02003825 */ move $a3, $s0 +/* 0A86F8 802E8EF8 100001D8 */ b .L08020145C +/* 0A86FC 802E8EFC 8FBF002C */ lw $ra, 0x2c($sp) +.L080200D00: +/* 0A8700 802E8F00 000D77C2 */ srl $t6, $t5, 0x1f +/* 0A8704 802E8F04 24010001 */ li $at, 1 +/* 0A8708 802E8F08 15C1000E */ bne $t6, $at, .L080200D44 +/* 0A870C 802E8F0C 262400D4 */ addiu $a0, $s1, 0xd4 +/* 0A8710 802E8F10 00002825 */ move $a1, $zero +/* 0A8714 802E8F14 0C0BBDE0 */ jal osRecvMesg +/* 0A8718 802E8F18 00003025 */ move $a2, $zero +/* 0A871C 802E8F1C 2401FFFF */ li $at, -1 +/* 0A8720 802E8F20 104101CD */ beq $v0, $at, .L080201458 +/* 0A8724 802E8F24 24040002 */ li $a0, 2 +/* 0A8728 802E8F28 92380000 */ lbu $t8, ($s1) +/* 0A872C 802E8F2C 92390004 */ lbu $t9, 4($s1) +/* 0A8730 802E8F30 3C018022 */ lui $at, %hi(gSeqLoadStatus) +/* 0A8734 802E8F34 330FFFEF */ andi $t7, $t8, 0xffef +/* 0A8738 802E8F38 A22F0000 */ sb $t7, ($s1) +/* 0A873C 802E8F3C 00390821 */ addu $at, $at, $t9 +/* 0A8740 802E8F40 A0242C58 */ sb $a0, %lo(gSeqLoadStatus)($at) +.L080200D44: +/* 0A8744 802E8F44 92280004 */ lbu $t0, 4($s1) +/* 0A8748 802E8F48 3C098022 */ lui $t1, %hi(gSeqLoadStatus) # $t1, 0x8022 +/* 0A874C 802E8F4C 25292C58 */ addiu $t1, %lo(gSeqLoadStatus) # addiu $t1, $t1, 0x2c58 +/* 0A8750 802E8F50 01091021 */ addu $v0, $t0, $t1 +/* 0A8754 802E8F54 904A0000 */ lbu $t2, ($v0) +/* 0A8758 802E8F58 24040002 */ li $a0, 2 +/* 0A875C 802E8F5C 294B0002 */ slti $t3, $t2, 2 +/* 0A8760 802E8F60 15600009 */ bnez $t3, .L080200D88 +/* 0A8764 802E8F64 00000000 */ nop +/* 0A8768 802E8F68 922C0005 */ lbu $t4, 5($s1) +/* 0A876C 802E8F6C 3C038022 */ lui $v1, %hi(gBankLoadStatus) # $v1, 0x8022 +/* 0A8770 802E8F70 24632C18 */ addiu $v1, %lo(gBankLoadStatus) # addiu $v1, $v1, 0x2c18 +/* 0A8774 802E8F74 006C6821 */ addu $t5, $v1, $t4 +/* 0A8778 802E8F78 91AE0000 */ lbu $t6, ($t5) +/* 0A877C 802E8F7C 29D80002 */ slti $t8, $t6, 2 +/* 0A8780 802E8F80 53000006 */ beql $t8, $zero, .L080200D9C +/* 0A8784 802E8F84 A0440000 */ sb $a0, ($v0) +.L080200D88: +/* 0A8788 802E8F88 0C0B9D2C */ jal sequence_player_disable +/* 0A878C 802E8F8C 02202025 */ move $a0, $s1 +/* 0A8790 802E8F90 100001B2 */ b .L08020145C +/* 0A8794 802E8F94 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A8798 802E8F98 A0440000 */ sb $a0, ($v0) +.L080200D9C: +/* 0A879C 802E8F9C 922F0005 */ lbu $t7, 5($s1) +/* 0A87A0 802E8FA0 006FC821 */ addu $t9, $v1, $t7 +/* 0A87A4 802E8FA4 A3240000 */ sb $a0, ($t9) +/* 0A87A8 802E8FA8 8E280000 */ lw $t0, ($s1) +/* 0A87AC 802E8FAC 00085080 */ sll $t2, $t0, 2 +/* 0A87B0 802E8FB0 05430006 */ bgezl $t2, .L080200DCC +/* 0A87B4 802E8FB4 962D000A */ lhu $t5, 0xa($s1) +/* 0A87B8 802E8FB8 922B0003 */ lbu $t3, 3($s1) +/* 0A87BC 802E8FBC 316C0080 */ andi $t4, $t3, 0x80 +/* 0A87C0 802E8FC0 558001A6 */ bnezl $t4, .L08020145C +/* 0A87C4 802E8FC4 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A87C8 802E8FC8 962D000A */ lhu $t5, 0xa($s1) +.L080200DCC: +/* 0A87CC 802E8FCC 962E0008 */ lhu $t6, 8($s1) +/* 0A87D0 802E8FD0 3C038023 */ lui $v1, %hi(gTempoInternalToExternal) # $v1, 0x8023 +/* 0A87D4 802E8FD4 01AEC021 */ addu $t8, $t5, $t6 +/* 0A87D8 802E8FD8 A638000A */ sh $t8, 0xa($s1) +/* 0A87DC 802E8FDC 8463980C */ lh $v1, %lo(gTempoInternalToExternal)($v1) +/* 0A87E0 802E8FE0 3302FFFF */ andi $v0, $t8, 0xffff +/* 0A87E4 802E8FE4 0043082A */ slt $at, $v0, $v1 +/* 0A87E8 802E8FE8 5420019C */ bnezl $at, .L08020145C +/* 0A87EC 802E8FEC 8FBF002C */ lw $ra, 0x2c($sp) +/* 0A87F0 802E8FF0 9624000E */ lhu $a0, 0xe($s1) +/* 0A87F4 802E8FF4 0043C823 */ subu $t9, $v0, $v1 +/* 0A87F8 802E8FF8 A639000A */ sh $t9, 0xa($s1) +/* 0A87FC 802E8FFC 28810002 */ slti $at, $a0, 2 +/* 0A8800 802E9000 14200003 */ bnez $at, .L080200E10 +/* 0A8804 802E9004 2488FFFF */ addiu $t0, $a0, -1 +/* 0A8808 802E9008 10000180 */ b .L08020140C +/* 0A880C 802E900C A628000E */ sh $t0, 0xe($s1) +.L080200E10: +/* 0A8810 802E9010 922A0000 */ lbu $t2, ($s1) +/* 0A8814 802E9014 26300070 */ addiu $s0, $s1, 0x70 +/* 0A8818 802E9018 354B0004 */ ori $t3, $t2, 4 +/* 0A881C 802E901C A22B0000 */ sb $t3, ($s1) +/* 0A8820 802E9020 8FB30058 */ lw $s3, 0x58($sp) +glabel L_EU_802E9024 +.L_EU_802E9024: +/* 0A8824 802E9024 0C0B9DA0 */ jal m64_read_u8 +/* 0A8828 802E9028 02002025 */ move $a0, $s0 +/* 0A882C 802E902C 240100FF */ li $at, 255 +/* 0A8830 802E9030 1441000E */ bne $v0, $at, .L080200E6C +/* 0A8834 802E9034 305200FF */ andi $s2, $v0, 0xff +/* 0A8838 802E9038 92040018 */ lbu $a0, 0x18($s0) +/* 0A883C 802E903C 14800005 */ bnez $a0, .L080200E54 +/* 0A8840 802E9040 2483FFFF */ addiu $v1, $a0, -1 +/* 0A8844 802E9044 0C0B9D2C */ jal sequence_player_disable +/* 0A8848 802E9048 02202025 */ move $a0, $s1 +/* 0A884C 802E904C 1000016F */ b .L08020140C +/* 0A8850 802E9050 00000000 */ nop +.L080200E54: +/* 0A8854 802E9054 306C00FF */ andi $t4, $v1, 0xff +/* 0A8858 802E9058 000C6880 */ sll $t5, $t4, 2 +/* 0A885C 802E905C 020D7021 */ addu $t6, $s0, $t5 +/* 0A8860 802E9060 A20C0018 */ sb $t4, 0x18($s0) +/* 0A8864 802E9064 8DD80004 */ lw $t8, 4($t6) +/* 0A8868 802E9068 AE180000 */ sw $t8, ($s0) +.L080200E6C: +/* 0A886C 802E906C 304300FF */ andi $v1, $v0, 0xff +/* 0A8870 802E9070 240100FD */ li $at, 253 +/* 0A8874 802E9074 14610005 */ bne $v1, $at, .L080200E8C +/* 0A8878 802E9078 306200F0 */ andi $v0, $v1, 0xf0 +/* 0A887C 802E907C 0C0B9DB1 */ jal m64_read_compressed_u16 +/* 0A8880 802E9080 02002025 */ move $a0, $s0 +/* 0A8884 802E9084 10000161 */ b .L08020140C +/* 0A8888 802E9088 A622000E */ sh $v0, 0xe($s1) +.L080200E8C: +/* 0A888C 802E908C 240100FE */ li $at, 254 +/* 0A8890 802E9090 14610004 */ bne $v1, $at, .L080200EA4 +/* 0A8894 802E9094 2479FF38 */ addiu $t9, $v1, -0xc8 +/* 0A8898 802E9098 240F0001 */ li $t7, 1 +/* 0A889C 802E909C 1000015B */ b .L08020140C +/* 0A88A0 802E90A0 A62F000E */ sh $t7, 0xe($s1) +.L080200EA4: +/* 0A88A4 802E90A4 286100C0 */ slti $at, $v1, 0xc0 +/* 0A88A8 802E90A8 14200125 */ bnez $at, .L080201340 +/* 0A88AC 802E90AC 2F210038 */ sltiu $at, $t9, 0x38 +/* 0A88B0 802E90B0 1020FFDC */ beqz $at, .L_EU_802E9024 +/* 0A88B4 802E90B4 0019C880 */ sll $t9, $t9, 2 +/* 0A88B8 802E90B8 3C018030 */ lui $at, %hi(jtbl_EU_80306AD4) +/* 0A88BC 802E90BC 00390821 */ addu $at, $at, $t9 +/* 0A88C0 802E90C0 8C396AD4 */ lw $t9, %lo(jtbl_EU_80306AD4)($at) +/* 0A88C4 802E90C4 03200008 */ jr $t9 +/* 0A88C8 802E90C8 00000000 */ nop +glabel L_EU_802E90CC +/* 0A88CC 802E90CC 0C0B9DA5 */ jal m64_read_s16 +/* 0A88D0 802E90D0 02002025 */ move $a0, $s0 +/* 0A88D4 802E90D4 92090018 */ lbu $t1, 0x18($s0) +/* 0A88D8 802E90D8 8E080000 */ lw $t0, ($s0) +/* 0A88DC 802E90DC 3058FFFF */ andi $t8, $v0, 0xffff +/* 0A88E0 802E90E0 00095080 */ sll $t2, $t1, 2 +/* 0A88E4 802E90E4 020A5821 */ addu $t3, $s0, $t2 +/* 0A88E8 802E90E8 AD680004 */ sw $t0, 4($t3) +/* 0A88EC 802E90EC 920C0018 */ lbu $t4, 0x18($s0) +/* 0A88F0 802E90F0 258D0001 */ addiu $t5, $t4, 1 +/* 0A88F4 802E90F4 A20D0018 */ sb $t5, 0x18($s0) +/* 0A88F8 802E90F8 8E2E0014 */ lw $t6, 0x14($s1) +/* 0A88FC 802E90FC 01D87821 */ addu $t7, $t6, $t8 +/* 0A8900 802E9100 1000FFC8 */ b .L_EU_802E9024 +/* 0A8904 802E9104 AE0F0000 */ sw $t7, ($s0) +/* 0A8908 802E9108 1000FFC6 */ b .L_EU_802E9024 +/* 0A890C 802E910C 00000000 */ nop +glabel L_EU_802E9110 +/* 0A8910 802E9110 0C0B9DA0 */ jal m64_read_u8 +/* 0A8914 802E9114 02002025 */ move $a0, $s0 +/* 0A8918 802E9118 92190018 */ lbu $t9, 0x18($s0) +/* 0A891C 802E911C 02194821 */ addu $t1, $s0, $t9 +/* 0A8920 802E9120 A1220014 */ sb $v0, 0x14($t1) +/* 0A8924 802E9124 92080018 */ lbu $t0, 0x18($s0) +/* 0A8928 802E9128 8E0A0000 */ lw $t2, ($s0) +/* 0A892C 802E912C 00085880 */ sll $t3, $t0, 2 +/* 0A8930 802E9130 020B6021 */ addu $t4, $s0, $t3 +/* 0A8934 802E9134 AD8A0004 */ sw $t2, 4($t4) +/* 0A8938 802E9138 920D0018 */ lbu $t5, 0x18($s0) +/* 0A893C 802E913C 25AE0001 */ addiu $t6, $t5, 1 +/* 0A8940 802E9140 1000FFB8 */ b .L_EU_802E9024 +/* 0A8944 802E9144 A20E0018 */ sb $t6, 0x18($s0) +glabel L_EU_802E9148 +/* 0A8948 802E9148 92180018 */ lbu $t8, 0x18($s0) +/* 0A894C 802E914C 02181021 */ addu $v0, $s0, $t8 +/* 0A8950 802E9150 904F0013 */ lbu $t7, 0x13($v0) +/* 0A8954 802E9154 25F9FFFF */ addiu $t9, $t7, -1 +/* 0A8958 802E9158 A0590013 */ sb $t9, 0x13($v0) +/* 0A895C 802E915C 92040018 */ lbu $a0, 0x18($s0) +/* 0A8960 802E9160 02044821 */ addu $t1, $s0, $a0 +/* 0A8964 802E9164 91280013 */ lbu $t0, 0x13($t1) +/* 0A8968 802E9168 00801825 */ move $v1, $a0 +/* 0A896C 802E916C 00035880 */ sll $t3, $v1, 2 +/* 0A8970 802E9170 11000005 */ beqz $t0, .L080200F88 +/* 0A8974 802E9174 248DFFFF */ addiu $t5, $a0, -1 +/* 0A8978 802E9178 020B5021 */ addu $t2, $s0, $t3 +/* 0A897C 802E917C 8D4C0000 */ lw $t4, ($t2) +/* 0A8980 802E9180 1000FFA8 */ b .L_EU_802E9024 +/* 0A8984 802E9184 AE0C0000 */ sw $t4, ($s0) +.L080200F88: +/* 0A8988 802E9188 1000FFA6 */ b .L_EU_802E9024 +/* 0A898C 802E918C A20D0018 */ sb $t5, 0x18($s0) +glabel L_EU_802E9190 +/* 0A8990 802E9190 0C0B9DA5 */ jal m64_read_s16 +/* 0A8994 802E9194 02002025 */ move $a0, $s0 +/* 0A8998 802E9198 240100FA */ li $at, 250 +/* 0A899C 802E919C 16410003 */ bne $s2, $at, .L080200FAC +/* 0A89A0 802E91A0 02401825 */ move $v1, $s2 +/* 0A89A4 802E91A4 1660FF9F */ bnez $s3, .L_EU_802E9024 +/* 0A89A8 802E91A8 00000000 */ nop +.L080200FAC: +/* 0A89AC 802E91AC 240100F9 */ li $at, 249 +/* 0A89B0 802E91B0 54610004 */ bnel $v1, $at, .L080200FC4 +/* 0A89B4 802E91B4 240100F5 */ li $at, 245 +/* 0A89B8 802E91B8 0661FF9A */ bgez $s3, .L_EU_802E9024 +/* 0A89BC 802E91BC 00000000 */ nop +/* 0A89C0 802E91C0 240100F5 */ li $at, 245 +.L080200FC4: +/* 0A89C4 802E91C4 54610004 */ bnel $v1, $at, .L080200FD8 +/* 0A89C8 802E91C8 8E2E0014 */ lw $t6, 0x14($s1) +/* 0A89CC 802E91CC 0660FF95 */ bltz $s3, .L_EU_802E9024 +/* 0A89D0 802E91D0 00000000 */ nop +/* 0A89D4 802E91D4 8E2E0014 */ lw $t6, 0x14($s1) +.L080200FD8: +/* 0A89D8 802E91D8 3058FFFF */ andi $t8, $v0, 0xffff +/* 0A89DC 802E91DC 01D87821 */ addu $t7, $t6, $t8 +/* 0A89E0 802E91E0 1000FF90 */ b .L_EU_802E9024 +/* 0A89E4 802E91E4 AE0F0000 */ sw $t7, ($s0) +glabel L_EU_802E91E8 +/* 0A89E8 802E91E8 0C0B9DA0 */ jal m64_read_u8 +/* 0A89EC 802E91EC 02002025 */ move $a0, $s0 +/* 0A89F0 802E91F0 240100F3 */ li $at, 243 +/* 0A89F4 802E91F4 16410003 */ bne $s2, $at, .L080201004 +/* 0A89F8 802E91F8 02401825 */ move $v1, $s2 +/* 0A89FC 802E91FC 1660FF89 */ bnez $s3, .L_EU_802E9024 +/* 0A8A00 802E9200 00000000 */ nop +.L080201004: +/* 0A8A04 802E9204 240100F2 */ li $at, 242 +/* 0A8A08 802E9208 54610004 */ bnel $v1, $at, .L08020101C +/* 0A8A0C 802E920C 8E190000 */ lw $t9, ($s0) +/* 0A8A10 802E9210 0661FF84 */ bgez $s3, .L_EU_802E9024 +/* 0A8A14 802E9214 00000000 */ nop +/* 0A8A18 802E9218 8E190000 */ lw $t9, ($s0) +.L08020101C: +/* 0A8A1C 802E921C 00024E00 */ sll $t1, $v0, 0x18 +/* 0A8A20 802E9220 00094603 */ sra $t0, $t1, 0x18 +/* 0A8A24 802E9224 03285821 */ addu $t3, $t9, $t0 +/* 0A8A28 802E9228 1000FF7E */ b .L_EU_802E9024 +/* 0A8A2C 802E922C AE0B0000 */ sw $t3, ($s0) +glabel L_EU_802E9230 +/* 0A8A30 802E9230 26240094 */ addiu $a0, $s1, 0x94 +/* 0A8A34 802E9234 0C0B9671 */ jal note_pool_clear +/* 0A8A38 802E9238 AFA40038 */ sw $a0, 0x38($sp) +/* 0A8A3C 802E923C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8A40 802E9240 02002025 */ move $a0, $s0 +/* 0A8A44 802E9244 8FA40038 */ lw $a0, 0x38($sp) +/* 0A8A48 802E9248 0C0B96C9 */ jal note_pool_fill +/* 0A8A4C 802E924C 00402825 */ move $a1, $v0 +/* 0A8A50 802E9250 1000FF74 */ b .L_EU_802E9024 +/* 0A8A54 802E9254 00000000 */ nop +glabel L_EU_802E9258 +/* 0A8A58 802E9258 0C0B9671 */ jal note_pool_clear +/* 0A8A5C 802E925C 26240094 */ addiu $a0, $s1, 0x94 +/* 0A8A60 802E9260 1000FF70 */ b .L_EU_802E9024 +/* 0A8A64 802E9264 00000000 */ nop +glabel L_EU_802E9268 +/* 0A8A68 802E9268 A620000C */ sh $zero, 0xc($s1) +glabel L_EU_802E926C +/* 0A8A6C 802E926C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8A70 802E9270 02002025 */ move $a0, $s0 +/* 0A8A74 802E9274 862A000C */ lh $t2, 0xc($s1) +/* 0A8A78 802E9278 00026600 */ sll $t4, $v0, 0x18 +/* 0A8A7C 802E927C 000C6E03 */ sra $t5, $t4, 0x18 +/* 0A8A80 802E9280 014D7021 */ addu $t6, $t2, $t5 +/* 0A8A84 802E9284 1000FF67 */ b .L_EU_802E9024 +/* 0A8A88 802E9288 A62E000C */ sh $t6, 0xc($s1) +glabel L_EU_802E928C +/* 0A8A8C 802E928C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8A90 802E9290 02002025 */ move $a0, $s0 +/* 0A8A94 802E9294 240100DD */ li $at, 221 +/* 0A8A98 802E9298 16410007 */ bne $s2, $at, .L0802010B8 +/* 0A8A9C 802E929C 3C038023 */ lui $v1, %hi(gTempoInternalToExternal) # $v1, 0x8023 +/* 0A8AA0 802E92A0 305800FF */ andi $t8, $v0, 0xff +/* 0A8AA4 802E92A4 00187880 */ sll $t7, $t8, 2 +/* 0A8AA8 802E92A8 01F87823 */ subu $t7, $t7, $t8 +/* 0A8AAC 802E92AC 000F7900 */ sll $t7, $t7, 4 +/* 0A8AB0 802E92B0 10000009 */ b .L0802010D8 +/* 0A8AB4 802E92B4 A62F0008 */ sh $t7, 8($s1) +.L0802010B8: +/* 0A8AB8 802E92B8 0002CE00 */ sll $t9, $v0, 0x18 +/* 0A8ABC 802E92BC 00194603 */ sra $t0, $t9, 0x18 +/* 0A8AC0 802E92C0 96290008 */ lhu $t1, 8($s1) +/* 0A8AC4 802E92C4 00085880 */ sll $t3, $t0, 2 +/* 0A8AC8 802E92C8 01685823 */ subu $t3, $t3, $t0 +/* 0A8ACC 802E92CC 000B5900 */ sll $t3, $t3, 4 +/* 0A8AD0 802E92D0 012B6021 */ addu $t4, $t1, $t3 +/* 0A8AD4 802E92D4 A62C0008 */ sh $t4, 8($s1) +.L0802010D8: +/* 0A8AD8 802E92D8 8463980C */ lh $v1, %lo(gTempoInternalToExternal)($v1) +/* 0A8ADC 802E92DC 96220008 */ lhu $v0, 8($s1) +/* 0A8AE0 802E92E0 240E0001 */ li $t6, 1 +/* 0A8AE4 802E92E4 0062082A */ slt $at, $v1, $v0 +/* 0A8AE8 802E92E8 50200004 */ beql $at, $zero, .L0802010FC +/* 0A8AEC 802E92EC 00025400 */ sll $t2, $v0, 0x10 +/* 0A8AF0 802E92F0 A6230008 */ sh $v1, 8($s1) +/* 0A8AF4 802E92F4 3062FFFF */ andi $v0, $v1, 0xffff +/* 0A8AF8 802E92F8 00025400 */ sll $t2, $v0, 0x10 +.L0802010FC: +/* 0A8AFC 802E92FC 000A6C03 */ sra $t5, $t2, 0x10 +/* 0A8B00 802E9300 1DA0FF48 */ bgtz $t5, .L_EU_802E9024 +/* 0A8B04 802E9304 00000000 */ nop +/* 0A8B08 802E9308 1000FF46 */ b .L_EU_802E9024 +/* 0A8B0C 802E930C A62E0008 */ sh $t6, 8($s1) +glabel L_EU_802E9310 +/* 0A8B10 802E9310 0C0B9DA0 */ jal m64_read_u8 +/* 0A8B14 802E9314 02002025 */ move $a0, $s0 +/* 0A8B18 802E9318 305200FF */ andi $s2, $v0, 0xff +/* 0A8B1C 802E931C 0C0B9DA5 */ jal m64_read_s16 +/* 0A8B20 802E9320 02002025 */ move $a0, $s0 +/* 0A8B24 802E9324 12400008 */ beqz $s2, .L080201148 +/* 0A8B28 802E9328 02401825 */ move $v1, $s2 +/* 0A8B2C 802E932C 24010001 */ li $at, 1 +/* 0A8B30 802E9330 10610005 */ beq $v1, $at, .L080201148 +/* 0A8B34 802E9334 24010002 */ li $at, 2 +/* 0A8B38 802E9338 1061000A */ beq $v1, $at, .L080201164 +/* 0A8B3C 802E933C 304FFFFF */ andi $t7, $v0, 0xffff +/* 0A8B40 802E9340 1000FF38 */ b .L_EU_802E9024 +/* 0A8B44 802E9344 00000000 */ nop +.L080201148: +/* 0A8B48 802E9348 92380001 */ lbu $t8, 1($s1) +/* 0A8B4C 802E934C 24010002 */ li $at, 2 +/* 0A8B50 802E9350 1301FF34 */ beq $t8, $at, .L_EU_802E9024 +/* 0A8B54 802E9354 00000000 */ nop +/* 0A8B58 802E9358 A6220012 */ sh $v0, 0x12($s1) +/* 0A8B5C 802E935C 1000FF31 */ b .L_EU_802E9024 +/* 0A8B60 802E9360 A2320001 */ sb $s2, 1($s1) +.L080201164: +/* 0A8B64 802E9364 448F5000 */ mtc1 $t7, $f10 +/* 0A8B68 802E9368 44802000 */ mtc1 $zero, $f4 +/* 0A8B6C 802E936C C6260018 */ lwc1 $f6, 0x18($s1) +/* 0A8B70 802E9370 46805420 */ cvt.s.w $f16, $f10 +/* 0A8B74 802E9374 A6220010 */ sh $v0, 0x10($s1) +/* 0A8B78 802E9378 A2320001 */ sb $s2, 1($s1) +/* 0A8B7C 802E937C 46062201 */ sub.s $f8, $f4, $f6 +/* 0A8B80 802E9380 46104483 */ div.s $f18, $f8, $f16 +/* 0A8B84 802E9384 1000FF27 */ b .L_EU_802E9024 +/* 0A8B88 802E9388 E632001C */ swc1 $f18, 0x1c($s1) +glabel L_EU_802E938C +/* 0A8B8C 802E938C 0C0B9DA0 */ jal m64_read_u8 +/* 0A8B90 802E9390 02002025 */ move $a0, $s0 +/* 0A8B94 802E9394 92230001 */ lbu $v1, 1($s1) +/* 0A8B98 802E9398 24010001 */ li $at, 1 +/* 0A8B9C 802E939C 5060000B */ beql $v1, $zero, .L0802011CC +/* 0A8BA0 802E93A0 96230012 */ lhu $v1, 0x12($s1) +/* 0A8BA4 802E93A4 10610005 */ beq $v1, $at, .L0802011BC +/* 0A8BA8 802E93A8 24010002 */ li $at, 2 +/* 0A8BAC 802E93AC 1061FF1D */ beq $v1, $at, .L_EU_802E9024 +/* 0A8BB0 802E93B0 00000000 */ nop +/* 0A8BB4 802E93B4 1000FF1B */ b .L_EU_802E9024 +/* 0A8BB8 802E93B8 00000000 */ nop +.L0802011BC: +/* 0A8BBC 802E93BC 44802000 */ mtc1 $zero, $f4 +/* 0A8BC0 802E93C0 A2200001 */ sb $zero, 1($s1) +/* 0A8BC4 802E93C4 E6240018 */ swc1 $f4, 0x18($s1) +/* 0A8BC8 802E93C8 96230012 */ lhu $v1, 0x12($s1) +.L0802011CC: +/* 0A8BCC 802E93CC 1060000E */ beqz $v1, .L080201208 +/* 0A8BD0 802E93D0 A6230010 */ sh $v1, 0x10($s1) +/* 0A8BD4 802E93D4 44823000 */ mtc1 $v0, $f6 +/* 0A8BD8 802E93D8 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0A8BDC 802E93DC 44814000 */ mtc1 $at, $f8 +/* 0A8BE0 802E93E0 468032A0 */ cvt.s.w $f10, $f6 +/* 0A8BE4 802E93E4 3079FFFF */ andi $t9, $v1, 0xffff +/* 0A8BE8 802E93E8 44993000 */ mtc1 $t9, $f6 +/* 0A8BEC 802E93EC C6320018 */ lwc1 $f18, 0x18($s1) +/* 0A8BF0 802E93F0 46085403 */ div.s $f16, $f10, $f8 +/* 0A8BF4 802E93F4 468032A0 */ cvt.s.w $f10, $f6 +/* 0A8BF8 802E93F8 46128101 */ sub.s $f4, $f16, $f18 +/* 0A8BFC 802E93FC 460A2203 */ div.s $f8, $f4, $f10 +/* 0A8C00 802E9400 1000FF08 */ b .L_EU_802E9024 +/* 0A8C04 802E9404 E628001C */ swc1 $f8, 0x1c($s1) +.L080201208: +/* 0A8C08 802E9408 44828000 */ mtc1 $v0, $f16 +/* 0A8C0C 802E940C 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0A8C10 802E9410 44813000 */ mtc1 $at, $f6 +/* 0A8C14 802E9414 468084A0 */ cvt.s.w $f18, $f16 +/* 0A8C18 802E9418 46069103 */ div.s $f4, $f18, $f6 +/* 0A8C1C 802E941C 1000FF01 */ b .L_EU_802E9024 +/* 0A8C20 802E9420 E6240018 */ swc1 $f4, 0x18($s1) +glabel L_EU_802E9424 +/* 0A8C24 802E9424 0C0B9DA0 */ jal m64_read_u8 +/* 0A8C28 802E9428 02002025 */ move $a0, $s0 +/* 0A8C2C 802E942C 00024600 */ sll $t0, $v0, 0x18 +/* 0A8C30 802E9430 00084E03 */ sra $t1, $t0, 0x18 +/* 0A8C34 802E9434 44895000 */ mtc1 $t1, $f10 +/* 0A8C38 802E9438 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0A8C3C 802E943C 44818000 */ mtc1 $at, $f16 +/* 0A8C40 802E9440 46805220 */ cvt.s.w $f8, $f10 +/* 0A8C44 802E9444 46104483 */ div.s $f18, $f8, $f16 +/* 0A8C48 802E9448 1000FEF6 */ b .L_EU_802E9024 +/* 0A8C4C 802E944C E6320028 */ swc1 $f18, 0x28($s1) +glabel L_EU_802E9450 +/* 0A8C50 802E9450 0C0B9DA5 */ jal m64_read_s16 +/* 0A8C54 802E9454 02002025 */ move $a0, $s0 +/* 0A8C58 802E9458 02202025 */ move $a0, $s1 +/* 0A8C5C 802E945C 0C0B9C7B */ jal sequence_player_init_channels +/* 0A8C60 802E9460 3045FFFF */ andi $a1, $v0, 0xffff +/* 0A8C64 802E9464 1000FEEF */ b .L_EU_802E9024 +/* 0A8C68 802E9468 00000000 */ nop +glabel L_EU_802E946C +/* 0A8C6C 802E946C 0C0B9DA5 */ jal m64_read_s16 +/* 0A8C70 802E9470 02002025 */ move $a0, $s0 +/* 0A8C74 802E9474 02202025 */ move $a0, $s1 +/* 0A8C78 802E9478 0C0B9CC6 */ jal sequence_player_disable_channels +/* 0A8C7C 802E947C 3045FFFF */ andi $a1, $v0, 0xffff +/* 0A8C80 802E9480 1000FEE8 */ b .L_EU_802E9024 +/* 0A8C84 802E9484 00000000 */ nop +glabel L_EU_802E9488 +/* 0A8C88 802E9488 0C0B9DA0 */ jal m64_read_u8 +/* 0A8C8C 802E948C 02002025 */ move $a0, $s0 +/* 0A8C90 802E9490 00025E00 */ sll $t3, $v0, 0x18 +/* 0A8C94 802E9494 000B6603 */ sra $t4, $t3, 0x18 +/* 0A8C98 802E9498 448C3000 */ mtc1 $t4, $f6 +/* 0A8C9C 802E949C 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0A8CA0 802E94A0 44815000 */ mtc1 $at, $f10 +/* 0A8CA4 802E94A4 46803120 */ cvt.s.w $f4, $f6 +/* 0A8CA8 802E94A8 460A2203 */ div.s $f8, $f4, $f10 +/* 0A8CAC 802E94AC 1000FEDD */ b .L_EU_802E9024 +/* 0A8CB0 802E94B0 E6280024 */ swc1 $f8, 0x24($s1) +glabel L_EU_802E94B4 +/* 0A8CB4 802E94B4 922D0000 */ lbu $t5, ($s1) +/* 0A8CB8 802E94B8 35AE0020 */ ori $t6, $t5, 0x20 +/* 0A8CBC 802E94BC 1000FED9 */ b .L_EU_802E9024 +/* 0A8CC0 802E94C0 A22E0000 */ sb $t6, ($s1) +glabel L_EU_802E94C4 +/* 0A8CC4 802E94C4 0C0B9DA0 */ jal m64_read_u8 +/* 0A8CC8 802E94C8 02002025 */ move $a0, $s0 +/* 0A8CCC 802E94CC 1000FED5 */ b .L_EU_802E9024 +/* 0A8CD0 802E94D0 A2220003 */ sb $v0, 3($s1) +glabel L_EU_802E94D4 +/* 0A8CD4 802E94D4 0C0B9DA5 */ jal m64_read_s16 +/* 0A8CD8 802E94D8 02002025 */ move $a0, $s0 +/* 0A8CDC 802E94DC 8E380014 */ lw $t8, 0x14($s1) +/* 0A8CE0 802E94E0 304FFFFF */ andi $t7, $v0, 0xffff +/* 0A8CE4 802E94E4 240100D2 */ li $at, 210 +/* 0A8CE8 802E94E8 16410003 */ bne $s2, $at, .L0802012F8 +/* 0A8CEC 802E94EC 030F1821 */ addu $v1, $t8, $t7 +/* 0A8CF0 802E94F0 1000FECC */ b .L_EU_802E9024 +/* 0A8CF4 802E94F4 AE23008C */ sw $v1, 0x8c($s1) +.L0802012F8: +/* 0A8CF8 802E94F8 1000FECA */ b .L_EU_802E9024 +/* 0A8CFC 802E94FC AE230090 */ sw $v1, 0x90($s1) +glabel L_EU_802E9500 +/* 0A8D00 802E9500 0C0B9DA0 */ jal m64_read_u8 +/* 0A8D04 802E9504 02002025 */ move $a0, $s0 +/* 0A8D08 802E9508 1000FEC6 */ b .L_EU_802E9024 +/* 0A8D0C 802E950C A2220002 */ sb $v0, 2($s1) +glabel L_EU_802E9510 +/* 0A8D10 802E9510 0C0B9DA0 */ jal m64_read_u8 +/* 0A8D14 802E9514 02002025 */ move $a0, $s0 +/* 0A8D18 802E9518 1000FEC2 */ b .L_EU_802E9024 +/* 0A8D1C 802E951C 00409825 */ move $s3, $v0 +glabel L_EU_802E9520 +/* 0A8D20 802E9520 0C0B9DA0 */ jal m64_read_u8 +/* 0A8D24 802E9524 02002025 */ move $a0, $s0 +/* 0A8D28 802E9528 1000FEBE */ b .L_EU_802E9024 +/* 0A8D2C 802E952C 02629824 */ and $s3, $s3, $v0 +glabel L_EU_802E9530 +/* 0A8D30 802E9530 0C0B9DA0 */ jal m64_read_u8 +/* 0A8D34 802E9534 02002025 */ move $a0, $s0 +/* 0A8D38 802E9538 1000FEBA */ b .L_EU_802E9024 +/* 0A8D3C 802E953C 02629823 */ subu $s3, $s3, $v0 +.L080201340: +/* 0A8D40 802E9540 28410011 */ slti $at, $v0, 0x11 +/* 0A8D44 802E9544 14200010 */ bnez $at, .L080201388 +/* 0A8D48 802E9548 28410021 */ slti $at, $v0, 0x21 +/* 0A8D4C 802E954C 14200009 */ bnez $at, .L080201374 +/* 0A8D50 802E9550 2459FFC0 */ addiu $t9, $v0, -0x40 +/* 0A8D54 802E9554 2F210061 */ sltiu $at, $t9, 0x61 +/* 0A8D58 802E9558 1020FEB2 */ beqz $at, .L_EU_802E9024 +/* 0A8D5C 802E955C 0019C880 */ sll $t9, $t9, 2 +/* 0A8D60 802E9560 3C018030 */ lui $at, %hi(jtbl_EU_80306BB4) +/* 0A8D64 802E9564 00390821 */ addu $at, $at, $t9 +/* 0A8D68 802E9568 8C396BB4 */ lw $t9, %lo(jtbl_EU_80306BB4)($at) +/* 0A8D6C 802E956C 03200008 */ jr $t9 +/* 0A8D70 802E9570 00000000 */ nop +.L080201374: +/* 0A8D74 802E9574 24010020 */ li $at, 32 +/* 0A8D78 802E9578 1041FEAA */ beq $v0, $at, .L_EU_802E9024 +/* 0A8D7C 802E957C 00000000 */ nop +/* 0A8D80 802E9580 1000FEA8 */ b .L_EU_802E9024 +/* 0A8D84 802E9584 00000000 */ nop +.L080201388: +/* 0A8D88 802E9588 10400006 */ beqz $v0, .L0802013A4 +/* 0A8D8C 802E958C 3069000F */ andi $t1, $v1, 0xf +/* 0A8D90 802E9590 24010010 */ li $at, 16 +/* 0A8D94 802E9594 1041FEA3 */ beq $v0, $at, .L_EU_802E9024 +/* 0A8D98 802E9598 00000000 */ nop +/* 0A8D9C 802E959C 1000FEA1 */ b .L_EU_802E9024 +/* 0A8DA0 802E95A0 00000000 */ nop +.L0802013A4: +/* 0A8DA4 802E95A4 00095880 */ sll $t3, $t1, 2 +/* 0A8DA8 802E95A8 022B6021 */ addu $t4, $s1, $t3 +/* 0A8DAC 802E95AC 8D8A0030 */ lw $t2, 0x30($t4) +/* 0A8DB0 802E95B0 8D530000 */ lw $s3, ($t2) +/* 0A8DB4 802E95B4 00136840 */ sll $t5, $s3, 1 +/* 0A8DB8 802E95B8 1000FE9A */ b .L_EU_802E9024 +/* 0A8DBC 802E95BC 000D9FC2 */ srl $s3, $t5, 0x1f +glabel L_EU_802E95C0 +/* 0A8DC0 802E95C0 82380007 */ lb $t8, 7($s1) +/* 0A8DC4 802E95C4 1000FE97 */ b .L_EU_802E9024 +/* 0A8DC8 802E95C8 02789823 */ subu $s3, $s3, $t8 +glabel L_EU_802E95CC +/* 0A8DCC 802E95CC 1000FE95 */ b .L_EU_802E9024 +/* 0A8DD0 802E95D0 A2330007 */ sb $s3, 7($s1) +glabel L_EU_802E95D4 +/* 0A8DD4 802E95D4 1000FE93 */ b .L_EU_802E9024 +/* 0A8DD8 802E95D8 82330007 */ lb $s3, 7($s1) +glabel L_EU_802E95DC +/* 0A8DDC 802E95DC 0C0B9DA5 */ jal m64_read_s16 +/* 0A8DE0 802E95E0 02002025 */ move $a0, $s0 +/* 0A8DE4 802E95E4 8E390014 */ lw $t9, 0x14($s1) +/* 0A8DE8 802E95E8 02402825 */ move $a1, $s2 +/* 0A8DEC 802E95EC 30AF000F */ andi $t7, $a1, 0xf +/* 0A8DF0 802E95F0 3048FFFF */ andi $t0, $v0, 0xffff +/* 0A8DF4 802E95F4 01E02825 */ move $a1, $t7 +/* 0A8DF8 802E95F8 02202025 */ move $a0, $s1 +/* 0A8DFC 802E95FC 0C0B9CFA */ jal sequence_channel_enable +/* 0A8E00 802E9600 03283021 */ addu $a2, $t9, $t0 +/* 0A8E04 802E9604 1000FE87 */ b .L_EU_802E9024 +/* 0A8E08 802E9608 00000000 */ nop +.L08020140C: +/* 0A8E0C 802E960C 3C108023 */ lui $s0, %hi(gSequenceChannelNone) # $s0, 0x8023 +/* 0A8E10 802E9610 02201825 */ move $v1, $s1 +/* 0A8E14 802E9614 24110040 */ li $s1, 64 +/* 0A8E18 802E9618 26108748 */ addiu $s0, %lo(gSequenceChannelNone) # addiu $s0, $s0, -0x78b8 +/* 0A8E1C 802E961C 00001025 */ move $v0, $zero +.L080201420: +/* 0A8E20 802E9620 8C640030 */ lw $a0, 0x30($v1) +/* 0A8E24 802E9624 24010001 */ li $at, 1 +/* 0A8E28 802E9628 02044826 */ xor $t1, $s0, $a0 +/* 0A8E2C 802E962C 0009482B */ sltu $t1, $zero, $t1 +/* 0A8E30 802E9630 55210007 */ bnel $t1, $at, .L080201450 +/* 0A8E34 802E9634 24420004 */ addiu $v0, $v0, 4 +/* 0A8E38 802E9638 AFA20034 */ sw $v0, 0x34($sp) +/* 0A8E3C 802E963C 0C0BA0AE */ jal sequence_channel_process_script +/* 0A8E40 802E9640 AFA30030 */ sw $v1, 0x30($sp) +/* 0A8E44 802E9644 8FA20034 */ lw $v0, 0x34($sp) +/* 0A8E48 802E9648 8FA30030 */ lw $v1, 0x30($sp) +/* 0A8E4C 802E964C 24420004 */ addiu $v0, $v0, 4 +.L080201450: +/* 0A8E50 802E9650 1451FFF3 */ bne $v0, $s1, .L080201420 +/* 0A8E54 802E9654 24630004 */ addiu $v1, $v1, 4 +.L080201458: +/* 0A8E58 802E9658 8FBF002C */ lw $ra, 0x2c($sp) +.L08020145C: +/* 0A8E5C 802E965C 8FB0001C */ lw $s0, 0x1c($sp) +/* 0A8E60 802E9660 8FB10020 */ lw $s1, 0x20($sp) +/* 0A8E64 802E9664 8FB20024 */ lw $s2, 0x24($sp) +/* 0A8E68 802E9668 8FB30028 */ lw $s3, 0x28($sp) +/* 0A8E6C 802E966C 03E00008 */ jr $ra +/* 0A8E70 802E9670 27BD0060 */ addiu $sp, $sp, 0x60 diff --git a/asm/non_matchings/eu/audio/synthesis_do_one_audio_update.s b/asm/non_matchings/eu/audio/synthesis_do_one_audio_update.s new file mode 100644 index 0000000..04a57ef --- /dev/null +++ b/asm/non_matchings/eu/audio/synthesis_do_one_audio_update.s @@ -0,0 +1,331 @@ +glabel synthesis_do_one_audio_update +/* 09FA28 802E0228 27BDFF40 */ addiu $sp, $sp, -0xc0 +/* 09FA2C 802E022C 3C0A8022 */ lui $t2, %hi(gNumSynthesisReverbs) # $t2, 0x8022 +/* 09FA30 802E0230 254AC5E3 */ addiu $t2, %lo(gNumSynthesisReverbs) # addiu $t2, $t2, -0x3a1d +/* 09FA34 802E0234 81480000 */ lb $t0, ($t2) +/* 09FA38 802E0238 AFBE0040 */ sw $fp, 0x40($sp) +/* 09FA3C 802E023C AFB40030 */ sw $s4, 0x30($sp) +/* 09FA40 802E0240 AFB20028 */ sw $s2, 0x28($sp) +/* 09FA44 802E0244 00C0A025 */ move $s4, $a2 +/* 09FA48 802E0248 00E0F025 */ move $fp, $a3 +/* 09FA4C 802E024C AFBF0044 */ sw $ra, 0x44($sp) +/* 09FA50 802E0250 AFB7003C */ sw $s7, 0x3c($sp) +/* 09FA54 802E0254 AFB60038 */ sw $s6, 0x38($sp) +/* 09FA58 802E0258 AFB50034 */ sw $s5, 0x34($sp) +/* 09FA5C 802E025C AFB3002C */ sw $s3, 0x2c($sp) +/* 09FA60 802E0260 AFB10024 */ sw $s1, 0x24($sp) +/* 09FA64 802E0264 AFB00020 */ sw $s0, 0x20($sp) +/* 09FA68 802E0268 AFA400C0 */ sw $a0, 0xc0($sp) +/* 09FA6C 802E026C AFA500C4 */ sw $a1, 0xc4($sp) +/* 09FA70 802E0270 1500001D */ bnez $t0, .L80200C98 +/* 09FA74 802E0274 00009025 */ move $s2, $zero +/* 09FA78 802E0278 3C048023 */ lui $a0, %hi(gMaxSimultaneousNotes) # $a0, 0x8023 +/* 09FA7C 802E027C 8C849808 */ lw $a0, %lo(gMaxSimultaneousNotes)($a0) +/* 09FA80 802E0280 00008825 */ move $s1, $zero +/* 09FA84 802E0284 18800016 */ blez $a0, .L80200C90 +/* 09FA88 802E0288 00000000 */ nop +/* 09FA8C 802E028C 00870019 */ multu $a0, $a3 +/* 09FA90 802E0290 3C0E8022 */ lui $t6, %hi(gNoteSubsEu) # $t6, 0x8022 +/* 09FA94 802E0294 8DCEC5E4 */ lw $t6, %lo(gNoteSubsEu)($t6) +/* 09FA98 802E0298 27A50084 */ addiu $a1, $sp, 0x84 +/* 09FA9C 802E029C 00007812 */ mflo $t7 +/* 09FAA0 802E02A0 000FC100 */ sll $t8, $t7, 4 +/* 09FAA4 802E02A4 01D81021 */ addu $v0, $t6, $t8 +.L80200C58: +/* 09FAA8 802E02A8 8C590000 */ lw $t9, ($v0) +/* 09FAAC 802E02AC 00B26021 */ addu $t4, $a1, $s2 +/* 09FAB0 802E02B0 00195FC2 */ srl $t3, $t9, 0x1f +/* 09FAB4 802E02B4 51600006 */ beql $t3, $zero, .L80200C80 +/* 09FAB8 802E02B8 26310001 */ addiu $s1, $s1, 1 +/* 09FABC 802E02BC 26520001 */ addiu $s2, $s2, 1 +/* 09FAC0 802E02C0 00126C00 */ sll $t5, $s2, 0x10 +/* 09FAC4 802E02C4 000D9403 */ sra $s2, $t5, 0x10 +/* 09FAC8 802E02C8 A1910000 */ sb $s1, ($t4) +/* 09FACC 802E02CC 26310001 */ addiu $s1, $s1, 1 +.L80200C80: +/* 09FAD0 802E02D0 0224082A */ slt $at, $s1, $a0 +/* 09FAD4 802E02D4 1420FFF4 */ bnez $at, .L80200C58 +/* 09FAD8 802E02D8 24420010 */ addiu $v0, $v0, 0x10 +/* 09FADC 802E02DC 00008825 */ move $s1, $zero +.L80200C90: +/* 09FAE0 802E02E0 10000049 */ b .L80200DB8 +/* 09FAE4 802E02E4 00009825 */ move $s3, $zero +.L80200C98: +/* 09FAE8 802E02E8 19000026 */ blez $t0, .L80200D34 +/* 09FAEC 802E02EC 00009825 */ move $s3, $zero +/* 09FAF0 802E02F0 3C048023 */ lui $a0, %hi(gMaxSimultaneousNotes) # $a0, 0x8023 +/* 09FAF4 802E02F4 8C849808 */ lw $a0, %lo(gMaxSimultaneousNotes)($a0) +/* 09FAF8 802E02F8 27A50084 */ addiu $a1, $sp, 0x84 +.L80200CAC: +/* 09FAFC 802E02FC 1880001A */ blez $a0, .L80200D18 +/* 09FB00 802E0300 00008825 */ move $s1, $zero +/* 09FB04 802E0304 009E0019 */ multu $a0, $fp +/* 09FB08 802E0308 3C098022 */ lui $t1, %hi(gNoteSubsEu) # $t1, 0x8022 +/* 09FB0C 802E030C 8D29C5E4 */ lw $t1, %lo(gNoteSubsEu)($t1) +/* 09FB10 802E0310 00001812 */ mflo $v1 +/* 09FB14 802E0314 00000000 */ nop +/* 09FB18 802E0318 00000000 */ nop +.L80200CCC: +/* 09FB1C 802E031C 00037100 */ sll $t6, $v1, 4 +/* 09FB20 802E0320 01C91021 */ addu $v0, $t6, $t1 +/* 09FB24 802E0324 8C580000 */ lw $t8, ($v0) +/* 09FB28 802E0328 0018CFC2 */ srl $t9, $t8, 0x1f +/* 09FB2C 802E032C 5320000B */ beql $t9, $zero, .L80200D0C +/* 09FB30 802E0330 26310001 */ addiu $s1, $s1, 1 +/* 09FB34 802E0334 904B0001 */ lbu $t3, 1($v0) +/* 09FB38 802E0338 00B26821 */ addu $t5, $a1, $s2 +/* 09FB3C 802E033C 000B6142 */ srl $t4, $t3, 5 +/* 09FB40 802E0340 566C0006 */ bnel $s3, $t4, .L80200D0C +/* 09FB44 802E0344 26310001 */ addiu $s1, $s1, 1 +/* 09FB48 802E0348 26520001 */ addiu $s2, $s2, 1 +/* 09FB4C 802E034C 00127C00 */ sll $t7, $s2, 0x10 +/* 09FB50 802E0350 000F9403 */ sra $s2, $t7, 0x10 +/* 09FB54 802E0354 A1B10000 */ sb $s1, ($t5) +/* 09FB58 802E0358 26310001 */ addiu $s1, $s1, 1 +.L80200D0C: +/* 09FB5C 802E035C 0224082A */ slt $at, $s1, $a0 +/* 09FB60 802E0360 1420FFEE */ bnez $at, .L80200CCC +/* 09FB64 802E0364 24630001 */ addiu $v1, $v1, 1 +.L80200D18: +/* 09FB68 802E0368 26730001 */ addiu $s3, $s3, 1 +/* 09FB6C 802E036C 0013C400 */ sll $t8, $s3, 0x10 +/* 09FB70 802E0370 00189C03 */ sra $s3, $t8, 0x10 +/* 09FB74 802E0374 0268082A */ slt $at, $s3, $t0 +/* 09FB78 802E0378 1420FFE0 */ bnez $at, .L80200CAC +/* 09FB7C 802E037C 00000000 */ nop +/* 09FB80 802E0380 00009825 */ move $s3, $zero +.L80200D34: +/* 09FB84 802E0384 3C048023 */ lui $a0, %hi(gMaxSimultaneousNotes) # $a0, 0x8023 +/* 09FB88 802E0388 8C849808 */ lw $a0, %lo(gMaxSimultaneousNotes)($a0) +/* 09FB8C 802E038C 27A50084 */ addiu $a1, $sp, 0x84 +/* 09FB90 802E0390 00008825 */ move $s1, $zero +/* 09FB94 802E0394 5880001D */ blezl $a0, .L80200DBC +/* 09FB98 802E0398 02801025 */ move $v0, $s4 +/* 09FB9C 802E039C 009E0019 */ multu $a0, $fp +/* 09FBA0 802E03A0 3C098022 */ lui $t1, %hi(gNoteSubsEu) # $t1, 0x8022 +/* 09FBA4 802E03A4 8D29C5E4 */ lw $t1, %lo(gNoteSubsEu)($t1) +/* 09FBA8 802E03A8 00001812 */ mflo $v1 +/* 09FBAC 802E03AC 00000000 */ nop +/* 09FBB0 802E03B0 00000000 */ nop +.L80200D64: +/* 09FBB4 802E03B4 00035900 */ sll $t3, $v1, 4 +/* 09FBB8 802E03B8 01691021 */ addu $v0, $t3, $t1 +/* 09FBBC 802E03BC 8C4C0000 */ lw $t4, ($v0) +/* 09FBC0 802E03C0 000C6FC2 */ srl $t5, $t4, 0x1f +/* 09FBC4 802E03C4 51A0000C */ beql $t5, $zero, .L80200DA8 +/* 09FBC8 802E03C8 26310001 */ addiu $s1, $s1, 1 +/* 09FBCC 802E03CC 904F0001 */ lbu $t7, 1($v0) +/* 09FBD0 802E03D0 00B2C021 */ addu $t8, $a1, $s2 +/* 09FBD4 802E03D4 000F7142 */ srl $t6, $t7, 5 +/* 09FBD8 802E03D8 01C8082A */ slt $at, $t6, $t0 +/* 09FBDC 802E03DC 54200006 */ bnezl $at, .L80200DA8 +/* 09FBE0 802E03E0 26310001 */ addiu $s1, $s1, 1 +/* 09FBE4 802E03E4 26520001 */ addiu $s2, $s2, 1 +/* 09FBE8 802E03E8 0012CC00 */ sll $t9, $s2, 0x10 +/* 09FBEC 802E03EC 00199403 */ sra $s2, $t9, 0x10 +/* 09FBF0 802E03F0 A3110000 */ sb $s1, ($t8) +/* 09FBF4 802E03F4 26310001 */ addiu $s1, $s1, 1 +.L80200DA8: +/* 09FBF8 802E03F8 0224082A */ slt $at, $s1, $a0 +/* 09FBFC 802E03FC 1420FFED */ bnez $at, .L80200D64 +/* 09FC00 802E0400 24630001 */ addiu $v1, $v1, 1 +/* 09FC04 802E0404 00008825 */ move $s1, $zero +.L80200DB8: +/* 09FC08 802E0408 02801025 */ move $v0, $s4 +.L80200DBC: +/* 09FC0C 802E040C 3C0C0200 */ lui $t4, (0x020004C0 >> 16) # lui $t4, 0x200 +/* 09FC10 802E0410 358C04C0 */ ori $t4, (0x020004C0 & 0xFFFF) # ori $t4, $t4, 0x4c0 +/* 09FC14 802E0414 240D0280 */ li $t5, 640 +/* 09FC18 802E0418 AC4D0004 */ sw $t5, 4($v0) +/* 09FC1C 802E041C AC4C0000 */ sw $t4, ($v0) +/* 09FC20 802E0420 814F0000 */ lb $t7, ($t2) +/* 09FC24 802E0424 3C178022 */ lui $s7, %hi(gNotes) # $s7, 0x8022 +/* 09FC28 802E0428 26940008 */ addiu $s4, $s4, 8 +/* 09FC2C 802E042C 19E00053 */ blez $t7, .L80200F2C +/* 09FC30 802E0430 26F73D60 */ addiu $s7, %lo(gNotes) # addiu $s7, $s7, 0x3d60 +/* 09FC34 802E0434 3C158022 */ lui $s5, %hi(gNoteSubsEu) # $s5, 0x8022 +/* 09FC38 802E0438 26B5C5E4 */ addiu $s5, %lo(gNoteSubsEu) # addiu $s5, $s5, -0x3a1c +/* 09FC3C 802E043C 241600C0 */ li $s6, 192 +/* 09FC40 802E0440 00137140 */ sll $t6, $s3, 5 +.L80200DF4: +/* 09FC44 802E0444 01D37021 */ addu $t6, $t6, $s3 +/* 09FC48 802E0448 3C188022 */ lui $t8, %hi(gSynthesisReverbs) # $t8, 0x8022 +/* 09FC4C 802E044C 2718C1B0 */ addiu $t8, %lo(gSynthesisReverbs) # addiu $t8, $t8, -0x3e50 +/* 09FC50 802E0450 000E70C0 */ sll $t6, $t6, 3 +/* 09FC54 802E0454 01D8C821 */ addu $t9, $t6, $t8 +/* 09FC58 802E0458 AFB90060 */ sw $t9, 0x60($sp) +/* 09FC5C 802E045C 932B0001 */ lbu $t3, 1($t9) +/* 09FC60 802E0460 3C018022 */ lui $at, %hi(gUseReverb) # $at, 0x8022 +/* 09FC64 802E0464 02802025 */ move $a0, $s4 +/* 09FC68 802E0468 000B6600 */ sll $t4, $t3, 0x18 +/* 09FC6C 802E046C 000C6E03 */ sra $t5, $t4, 0x18 +/* 09FC70 802E0470 11A0000A */ beqz $t5, .L80200E4C +/* 09FC74 802E0474 A02BC5E2 */ sb $t3, %lo(gUseReverb)($at) +/* 09FC78 802E0478 00133400 */ sll $a2, $s3, 0x10 +/* 09FC7C 802E047C 001E3C00 */ sll $a3, $fp, 0x10 +/* 09FC80 802E0480 00077403 */ sra $t6, $a3, 0x10 +/* 09FC84 802E0484 00067C03 */ sra $t7, $a2, 0x10 +/* 09FC88 802E0488 01E03025 */ move $a2, $t7 +/* 09FC8C 802E048C 01C03825 */ move $a3, $t6 +/* 09FC90 802E0490 0C0B7F60 */ jal synthesis_resample_and_mix_reverb +/* 09FC94 802E0494 8FA500C4 */ lw $a1, 0xc4($sp) +/* 09FC98 802E0498 0040A025 */ move $s4, $v0 +.L80200E4C: +/* 09FC9C 802E049C 0232082A */ slt $at, $s1, $s2 +/* 09FCA0 802E04A0 10200022 */ beqz $at, .L80200EDC +/* 09FCA4 802E04A4 27B80084 */ addiu $t8, $sp, 0x84 +/* 09FCA8 802E04A8 02388021 */ addu $s0, $s1, $t8 +.L80200E5C: +/* 09FCAC 802E04AC 3C198023 */ lui $t9, %hi(gMaxSimultaneousNotes) # $t9, 0x8023 +/* 09FCB0 802E04B0 8F399808 */ lw $t9, %lo(gMaxSimultaneousNotes)($t9) +/* 09FCB4 802E04B4 92030000 */ lbu $v1, ($s0) +/* 09FCB8 802E04B8 8EA90000 */ lw $t1, ($s5) +/* 09FCBC 802E04BC 03D90019 */ multu $fp, $t9 +/* 09FCC0 802E04C0 00035900 */ sll $t3, $v1, 4 +/* 09FCC4 802E04C4 012B6021 */ addu $t4, $t1, $t3 +/* 09FCC8 802E04C8 00001012 */ mflo $v0 +/* 09FCCC 802E04CC 00026900 */ sll $t5, $v0, 4 +/* 09FCD0 802E04D0 018D7821 */ addu $t7, $t4, $t5 +/* 09FCD4 802E04D4 91EE0001 */ lbu $t6, 1($t7) +/* 09FCD8 802E04D8 000EC142 */ srl $t8, $t6, 5 +/* 09FCDC 802E04DC 56780014 */ bnel $s3, $t8, .L80200EE0 +/* 09FCE0 802E04E0 8FAE0060 */ lw $t6, 0x60($sp) +/* 09FCE4 802E04E4 00760019 */ multu $v1, $s6 +/* 09FCE8 802E04E8 8EEB0000 */ lw $t3, ($s7) +/* 09FCEC 802E04EC 8FAF00C4 */ lw $t7, 0xc4($sp) +/* 09FCF0 802E04F0 00626021 */ addu $t4, $v1, $v0 +/* 09FCF4 802E04F4 000C6900 */ sll $t5, $t4, 4 +/* 09FCF8 802E04F8 01A92821 */ addu $a1, $t5, $t1 +/* 09FCFC 802E04FC 8FA700C0 */ lw $a3, 0xc0($sp) +/* 09FD00 802E0500 AFB40014 */ sw $s4, 0x14($sp) +/* 09FD04 802E0504 AFAF0010 */ sw $t7, 0x10($sp) +/* 09FD08 802E0508 0000C812 */ mflo $t9 +/* 09FD0C 802E050C 032B2021 */ addu $a0, $t9, $t3 +/* 09FD10 802E0510 0C0B81BC */ jal synthesis_process_note +/* 09FD14 802E0514 24860010 */ addiu $a2, $a0, 0x10 +/* 09FD18 802E0518 26310001 */ addiu $s1, $s1, 1 +/* 09FD1C 802E051C 0232082A */ slt $at, $s1, $s2 +/* 09FD20 802E0520 0040A025 */ move $s4, $v0 +/* 09FD24 802E0524 1420FFE1 */ bnez $at, .L80200E5C +/* 09FD28 802E0528 26100001 */ addiu $s0, $s0, 1 +.L80200EDC: +/* 09FD2C 802E052C 8FAE0060 */ lw $t6, 0x60($sp) +.L80200EE0: +/* 09FD30 802E0530 00132C00 */ sll $a1, $s3, 0x10 +/* 09FD34 802E0534 0005CC03 */ sra $t9, $a1, 0x10 +/* 09FD38 802E0538 91D80001 */ lbu $t8, 1($t6) +/* 09FD3C 802E053C 03202825 */ move $a1, $t9 +/* 09FD40 802E0540 02802025 */ move $a0, $s4 +/* 09FD44 802E0544 13000005 */ beqz $t8, .L80200F0C +/* 09FD48 802E0548 001E3400 */ sll $a2, $fp, 0x10 +/* 09FD4C 802E054C 00065C03 */ sra $t3, $a2, 0x10 +/* 09FD50 802E0550 0C0B8036 */ jal func_eu_802e00d8 +/* 09FD54 802E0554 01603025 */ move $a2, $t3 +/* 09FD58 802E0558 0040A025 */ move $s4, $v0 +.L80200F0C: +/* 09FD5C 802E055C 3C0F8022 */ lui $t7, %hi(gNumSynthesisReverbs) # $t7, 0x8022 +/* 09FD60 802E0560 81EFC5E3 */ lb $t7, %lo(gNumSynthesisReverbs)($t7) +/* 09FD64 802E0564 26730001 */ addiu $s3, $s3, 1 +/* 09FD68 802E0568 00136400 */ sll $t4, $s3, 0x10 +/* 09FD6C 802E056C 000C9C03 */ sra $s3, $t4, 0x10 +/* 09FD70 802E0570 026F082A */ slt $at, $s3, $t7 +/* 09FD74 802E0574 5420FFB3 */ bnezl $at, .L80200DF4 +/* 09FD78 802E0578 00137140 */ sll $t6, $s3, 5 +.L80200F2C: +/* 09FD7C 802E057C 3C158022 */ lui $s5, %hi(gNoteSubsEu) # $s5, 0x8022 +/* 09FD80 802E0580 3C178022 */ lui $s7, %hi(gNotes) # $s7, 0x8022 +/* 09FD84 802E0584 0232082A */ slt $at, $s1, $s2 +/* 09FD88 802E0588 26F73D60 */ addiu $s7, %lo(gNotes) # addiu $s7, $s7, 0x3d60 +/* 09FD8C 802E058C 26B5C5E4 */ addiu $s5, %lo(gNoteSubsEu) # addiu $s5, $s5, -0x3a1c +/* 09FD90 802E0590 1020002E */ beqz $at, .L80200FFC +/* 09FD94 802E0594 241600C0 */ li $s6, 192 +/* 09FD98 802E0598 27AE0084 */ addiu $t6, $sp, 0x84 +/* 09FD9C 802E059C 022E8021 */ addu $s0, $s1, $t6 +/* 09FDA0 802E05A0 24130001 */ li $s3, 1 +.L80200F54: +/* 09FDA4 802E05A4 3C188023 */ lui $t8, %hi(gMaxSimultaneousNotes) # $t8, 0x8023 +/* 09FDA8 802E05A8 8F189808 */ lw $t8, %lo(gMaxSimultaneousNotes)($t8) +/* 09FDAC 802E05AC 92030000 */ lbu $v1, ($s0) +/* 09FDB0 802E05B0 8EA90000 */ lw $t1, ($s5) +/* 09FDB4 802E05B4 03D80019 */ multu $fp, $t8 +/* 09FDB8 802E05B8 0003C900 */ sll $t9, $v1, 4 +/* 09FDBC 802E05BC 01395821 */ addu $t3, $t1, $t9 +/* 09FDC0 802E05C0 3C0F8022 */ lui $t7, %hi(gBankLoadStatus) +/* 09FDC4 802E05C4 3C011000 */ lui $at, 0x1000 +/* 09FDC8 802E05C8 00001012 */ mflo $v0 +/* 09FDCC 802E05CC 00026100 */ sll $t4, $v0, 4 +/* 09FDD0 802E05D0 016C6821 */ addu $t5, $t3, $t4 +/* 09FDD4 802E05D4 91A40002 */ lbu $a0, 2($t5) +/* 09FDD8 802E05D8 01E47821 */ addu $t7, $t7, $a0 +/* 09FDDC 802E05DC 91EF2C18 */ lbu $t7, %lo(gBankLoadStatus)($t7) +/* 09FDE0 802E05E0 29EE0002 */ slti $t6, $t7, 2 +/* 09FDE4 802E05E4 39CE0001 */ xori $t6, $t6, 1 +/* 09FDE8 802E05E8 166E0010 */ bne $s3, $t6, .L80200FDC +/* 09FDEC 802E05EC 00117A00 */ sll $t7, $s1, 8 +/* 09FDF0 802E05F0 00760019 */ multu $v1, $s6 +/* 09FDF4 802E05F4 8EF90000 */ lw $t9, ($s7) +/* 09FDF8 802E05F8 8FAD00C4 */ lw $t5, 0xc4($sp) +/* 09FDFC 802E05FC 00625821 */ addu $t3, $v1, $v0 +/* 09FE00 802E0600 000B6100 */ sll $t4, $t3, 4 +/* 09FE04 802E0604 01892821 */ addu $a1, $t4, $t1 +/* 09FE08 802E0608 8FA700C0 */ lw $a3, 0xc0($sp) +/* 09FE0C 802E060C AFB40014 */ sw $s4, 0x14($sp) +/* 09FE10 802E0610 AFAD0010 */ sw $t5, 0x10($sp) +/* 09FE14 802E0614 0000C012 */ mflo $t8 +/* 09FE18 802E0618 03192021 */ addu $a0, $t8, $t9 +/* 09FE1C 802E061C 0C0B81BC */ jal synthesis_process_note +/* 09FE20 802E0620 24860010 */ addiu $a2, $a0, 0x10 +/* 09FE24 802E0624 10000005 */ b .L80200FEC +/* 09FE28 802E0628 0040A025 */ move $s4, $v0 +.L80200FDC: +/* 09FE2C 802E062C 008F7021 */ addu $t6, $a0, $t7 +/* 09FE30 802E0630 01C1C021 */ addu $t8, $t6, $at +/* 09FE34 802E0634 3C018023 */ lui $at, %hi(gAudioErrorFlags) # $at, 0x8023 +/* 09FE38 802E0638 AC3898F0 */ sw $t8, %lo(gAudioErrorFlags)($at) +.L80200FEC: +/* 09FE3C 802E063C 26310001 */ addiu $s1, $s1, 1 +/* 09FE40 802E0640 0232082A */ slt $at, $s1, $s2 +/* 09FE44 802E0644 1420FFD7 */ bnez $at, .L80200F54 +/* 09FE48 802E0648 26100001 */ addiu $s0, $s0, 1 +.L80200FFC: +/* 09FE4C 802E064C 3C080800 */ lui $t0, 0x800 +/* 09FE50 802E0650 02802025 */ move $a0, $s4 +/* 09FE54 802E0654 AC880000 */ sw $t0, ($a0) +/* 09FE58 802E0658 8FA300C4 */ lw $v1, 0xc4($sp) +/* 09FE5C 802E065C 26940008 */ addiu $s4, $s4, 8 +/* 09FE60 802E0660 02802825 */ move $a1, $s4 +/* 09FE64 802E0664 0003C840 */ sll $t9, $v1, 1 +/* 09FE68 802E0668 332BFFFF */ andi $t3, $t9, 0xffff +/* 09FE6C 802E066C AC8B0004 */ sw $t3, 4($a0) +/* 09FE70 802E0670 26940008 */ addiu $s4, $s4, 8 +/* 09FE74 802E0674 3C0D04C0 */ lui $t5, (0x04C00600 >> 16) # lui $t5, 0x4c0 +/* 09FE78 802E0678 35AD0600 */ ori $t5, (0x04C00600 & 0xFFFF) # ori $t5, $t5, 0x600 +/* 09FE7C 802E067C 3C0C0D00 */ lui $t4, 0xd00 +/* 09FE80 802E0680 02803025 */ move $a2, $s4 +/* 09FE84 802E0684 ACAC0000 */ sw $t4, ($a1) +/* 09FE88 802E0688 ACAD0004 */ sw $t5, 4($a1) +/* 09FE8C 802E068C 00197840 */ sll $t7, $t9, 1 +/* 09FE90 802E0690 31EEFFFF */ andi $t6, $t7, 0xffff +/* 09FE94 802E0694 26940008 */ addiu $s4, $s4, 8 +/* 09FE98 802E0698 ACCE0004 */ sw $t6, 4($a2) +/* 09FE9C 802E069C ACC80000 */ sw $t0, ($a2) +/* 09FEA0 802E06A0 02803825 */ move $a3, $s4 +/* 09FEA4 802E06A4 3C180600 */ lui $t8, 0x600 +/* 09FEA8 802E06A8 ACF80000 */ sw $t8, ($a3) +/* 09FEAC 802E06AC 8FB900C0 */ lw $t9, 0xc0($sp) +/* 09FEB0 802E06B0 3C018000 */ lui $at, 0x8000 +/* 09FEB4 802E06B4 26820008 */ addiu $v0, $s4, 8 +/* 09FEB8 802E06B8 03215821 */ addu $t3, $t9, $at +/* 09FEBC 802E06BC ACEB0004 */ sw $t3, 4($a3) +/* 09FEC0 802E06C0 8FBF0044 */ lw $ra, 0x44($sp) +/* 09FEC4 802E06C4 8FBE0040 */ lw $fp, 0x40($sp) +/* 09FEC8 802E06C8 8FB7003C */ lw $s7, 0x3c($sp) +/* 09FECC 802E06CC 8FB60038 */ lw $s6, 0x38($sp) +/* 09FED0 802E06D0 8FB50034 */ lw $s5, 0x34($sp) +/* 09FED4 802E06D4 8FB40030 */ lw $s4, 0x30($sp) +/* 09FED8 802E06D8 8FB3002C */ lw $s3, 0x2c($sp) +/* 09FEDC 802E06DC 8FB20028 */ lw $s2, 0x28($sp) +/* 09FEE0 802E06E0 8FB10024 */ lw $s1, 0x24($sp) +/* 09FEE4 802E06E4 8FB00020 */ lw $s0, 0x20($sp) +/* 09FEE8 802E06E8 03E00008 */ jr $ra +/* 09FEEC 802E06EC 27BD00C0 */ addiu $sp, $sp, 0xc0 diff --git a/asm/non_matchings/eu/audio/synthesis_execute.s b/asm/non_matchings/eu/audio/synthesis_execute.s new file mode 100644 index 0000000..4b1fd3e --- /dev/null +++ b/asm/non_matchings/eu/audio/synthesis_execute.s @@ -0,0 +1,178 @@ +glabel synthesis_execute +/* 09F2FC 802DFAFC 27BDFFA0 */ addiu $sp, $sp, -0x60 +/* 09F300 802DFB00 AFB60030 */ sw $s6, 0x30($sp) +/* 09F304 802DFB04 3C168023 */ lui $s6, %hi(gAudioBufferParameters) # $s6, 0x8023 +/* 09F308 802DFB08 26D697E0 */ addiu $s6, %lo(gAudioBufferParameters) # addiu $s6, $s6, -0x6820 +/* 09F30C 802DFB0C AFB40028 */ sw $s4, 0x28($sp) +/* 09F310 802DFB10 86D4000C */ lh $s4, 0xc($s6) +/* 09F314 802DFB14 AFB70034 */ sw $s7, 0x34($sp) +/* 09F318 802DFB18 AFB1001C */ sw $s1, 0x1c($sp) +/* 09F31C 802DFB1C 00C08825 */ move $s1, $a2 +/* 09F320 802DFB20 00E0B825 */ move $s7, $a3 +/* 09F324 802DFB24 AFBF003C */ sw $ra, 0x3c($sp) +/* 09F328 802DFB28 AFBE0038 */ sw $fp, 0x38($sp) +/* 09F32C 802DFB2C AFB5002C */ sw $s5, 0x2c($sp) +/* 09F330 802DFB30 AFB30024 */ sw $s3, 0x24($sp) +/* 09F334 802DFB34 AFB20020 */ sw $s2, 0x20($sp) +/* 09F338 802DFB38 AFB00018 */ sw $s0, 0x18($sp) +/* 09F33C 802DFB3C AFA40060 */ sw $a0, 0x60($sp) +/* 09F340 802DFB40 1A800009 */ blez $s4, .L80200518 +/* 09F344 802DFB44 AFA50064 */ sw $a1, 0x64($sp) +.L802004F8: +/* 09F348 802DFB48 2690FFFF */ addiu $s0, $s4, -1 +/* 09F34C 802DFB4C 0C0BA59D */ jal process_sequences +/* 09F350 802DFB50 02002025 */ move $a0, $s0 +/* 09F354 802DFB54 86CE000C */ lh $t6, 0xc($s6) +/* 09F358 802DFB58 0C0B7E91 */ jal synthesis_load_note_subs_eu +/* 09F35C 802DFB5C 01D42023 */ subu $a0, $t6, $s4 +/* 09F360 802DFB60 1E00FFF9 */ bgtz $s0, .L802004F8 +/* 09F364 802DFB64 0200A025 */ move $s4, $s0 +.L80200518: +/* 09F368 802DFB68 8FAF0060 */ lw $t7, 0x60($sp) +/* 09F36C 802DFB6C 3C190700 */ lui $t9, 0x700 +/* 09F370 802DFB70 0220F025 */ move $fp, $s1 +/* 09F374 802DFB74 25F80008 */ addiu $t8, $t7, 8 +/* 09F378 802DFB78 AFB80048 */ sw $t8, 0x48($sp) +/* 09F37C 802DFB7C ADE00004 */ sw $zero, 4($t7) +/* 09F380 802DFB80 ADF90000 */ sw $t9, ($t7) +/* 09F384 802DFB84 86D4000C */ lh $s4, 0xc($s6) +/* 09F388 802DFB88 8FB50040 */ lw $s5, 0x40($sp) +/* 09F38C 802DFB8C 01E01025 */ move $v0, $t7 +/* 09F390 802DFB90 1A800056 */ blez $s4, .L8020069C +.L80200544: +/* 09F394 802DFB94 24010001 */ li $at, 1 +/* 09F398 802DFB98 86D2000C */ lh $s2, 0xc($s6) +/* 09F39C 802DFB9C 1681000B */ bne $s4, $at, .L8020057C +/* 09F3A0 802DFBA0 00008825 */ move $s1, $zero +/* 09F3A4 802DFBA4 3C098022 */ lui $t1, %hi(gLeftVolRampings) # $t1, 0x8022 +/* 09F3A8 802DFBA8 3C0B8022 */ lui $t3, %hi(gRightVolRampings) # $t3, 0x8022 +/* 09F3AC 802DFBAC 256BF5E8 */ addiu $t3, %lo(gRightVolRampings) # addiu $t3, $t3, -0xa18 +/* 09F3B0 802DFBB0 2529C5E8 */ addiu $t1, %lo(gLeftVolRampings) # addiu $t1, $t1, -0x3a18 +/* 09F3B4 802DFBB4 00154300 */ sll $t0, $s5, 0xc +/* 09F3B8 802DFBB8 00155300 */ sll $t2, $s5, 0xc +/* 09F3BC 802DFBBC 014B2021 */ addu $a0, $t2, $t3 +/* 09F3C0 802DFBC0 01091821 */ addu $v1, $t0, $t1 +/* 09F3C4 802DFBC4 10000026 */ b .L80200610 +/* 09F3C8 802DFBC8 02E09825 */ move $s3, $s7 +.L8020057C: +/* 09F3CC 802DFBCC 02F4001A */ div $zero, $s7, $s4 +/* 09F3D0 802DFBD0 16800002 */ bnez $s4, .L8020058C +/* 09F3D4 802DFBD4 00000000 */ nop +/* 09F3D8 802DFBD8 0007000D */ break 7 +.L8020058C: +/* 09F3DC 802DFBDC 2401FFFF */ li $at, -1 +/* 09F3E0 802DFBE0 16810004 */ bne $s4, $at, .L802005A4 +/* 09F3E4 802DFBE4 3C018000 */ lui $at, 0x8000 +/* 09F3E8 802DFBE8 16E10002 */ bne $s7, $at, .L802005A4 +/* 09F3EC 802DFBEC 00000000 */ nop +/* 09F3F0 802DFBF0 0006000D */ break 6 +.L802005A4: +/* 09F3F4 802DFBF4 86C50010 */ lh $a1, 0x10($s6) +/* 09F3F8 802DFBF8 00001012 */ mflo $v0 +/* 09F3FC 802DFBFC 24150002 */ li $s5, 2 +/* 09F400 802DFC00 0045082A */ slt $at, $v0, $a1 +/* 09F404 802DFC04 14200006 */ bnez $at, .L802005D0 +/* 09F408 802DFC08 00A09825 */ move $s3, $a1 +/* 09F40C 802DFC0C 3C038022 */ lui $v1, %hi(gLeftVolRampings + 0x2000) # $v1, 0x8022 +/* 09F410 802DFC10 3C048022 */ lui $a0, %hi(gRightVolRampings + 0x2000) # $a0, 0x8022 +/* 09F414 802DFC14 248415E8 */ addiu $a0, %lo(gRightVolRampings + 0x2000) # addiu $a0, $a0, 0x15e8 +/* 09F418 802DFC18 10000011 */ b .L80200610 +/* 09F41C 802DFC1C 2463E5E8 */ addiu $v1, %lo(gLeftVolRampings + 0x2000) # addiu $v1, $v1, -0x1a18 +.L802005D0: +/* 09F420 802DFC20 86C50012 */ lh $a1, 0x12($s6) +/* 09F424 802DFC24 3C038022 */ lui $v1, %hi(gLeftVolRampings + 0x1000) # $v1, 0x8022 +/* 09F428 802DFC28 2463D5E8 */ addiu $v1, %lo(gLeftVolRampings + 0x1000) # addiu $v1, $v1, -0x2a18 +/* 09F42C 802DFC2C 00A2082A */ slt $at, $a1, $v0 +/* 09F430 802DFC30 14200008 */ bnez $at, .L80200604 +/* 09F434 802DFC34 24150001 */ li $s5, 1 +/* 09F438 802DFC38 3C038022 */ lui $v1, %hi(gLeftVolRampings) # $v1, 0x8022 +/* 09F43C 802DFC3C 3C048022 */ lui $a0, %hi(gRightVolRampings) # $a0, 0x8022 +/* 09F440 802DFC40 2484F5E8 */ addiu $a0, %lo(gRightVolRampings) # addiu $a0, $a0, -0xa18 +/* 09F444 802DFC44 2463C5E8 */ addiu $v1, %lo(gLeftVolRampings) # addiu $v1, $v1, -0x3a18 +/* 09F448 802DFC48 00A09825 */ move $s3, $a1 +/* 09F44C 802DFC4C 10000004 */ b .L80200610 +/* 09F450 802DFC50 0000A825 */ move $s5, $zero +.L80200604: +/* 09F454 802DFC54 3C048022 */ lui $a0, %hi(gRightVolRampings + 0x1000) # $a0, 0x8022 +/* 09F458 802DFC58 248405E8 */ addiu $a0, %lo(gRightVolRampings + 0x1000) # addiu $a0, $a0, 0x5e8 +/* 09F45C 802DFC5C 86D3000E */ lh $s3, 0xe($s6) +.L80200610: +/* 09F460 802DFC60 3C028022 */ lui $v0, %hi(gNumSynthesisReverbs) # $v0, 0x8022 +/* 09F464 802DFC64 8042C5E3 */ lb $v0, %lo(gNumSynthesisReverbs)($v0) +/* 09F468 802DFC68 3C018022 */ lui $at, %hi(gCurrentLeftVolRamping) # $at, 0x8022 +/* 09F46C 802DFC6C AC2325E8 */ sw $v1, %lo(gCurrentLeftVolRamping)($at) +/* 09F470 802DFC70 3C018022 */ lui $at, %hi(gCurrentRightVolRamping) # $at, 0x8022 +/* 09F474 802DFC74 18400011 */ blez $v0, .L8020066C +/* 09F478 802DFC78 AC2425EC */ sw $a0, %lo(gCurrentRightVolRamping)($at) +/* 09F47C 802DFC7C 3C108022 */ lui $s0, %hi(gSynthesisReverbs) # $s0, 0x8022 +/* 09F480 802DFC80 2610C1B0 */ addiu $s0, %lo(gSynthesisReverbs) # addiu $s0, $s0, -0x3e50 +.L80200634: +/* 09F484 802DFC84 920C0001 */ lbu $t4, 1($s0) +/* 09F488 802DFC88 02602025 */ move $a0, $s3 +/* 09F48C 802DFC8C 02542823 */ subu $a1, $s2, $s4 +/* 09F490 802DFC90 51800007 */ beql $t4, $zero, .L80200660 +/* 09F494 802DFC94 26310001 */ addiu $s1, $s1, 1 +/* 09F498 802DFC98 0C0B7D94 */ jal prepare_reverb_ring_buffer +/* 09F49C 802DFC9C 02203025 */ move $a2, $s1 +/* 09F4A0 802DFCA0 3C028022 */ lui $v0, %hi(gNumSynthesisReverbs) # $v0, 0x8022 +/* 09F4A4 802DFCA4 8042C5E3 */ lb $v0, %lo(gNumSynthesisReverbs)($v0) +/* 09F4A8 802DFCA8 86D2000C */ lh $s2, 0xc($s6) +/* 09F4AC 802DFCAC 26310001 */ addiu $s1, $s1, 1 +.L80200660: +/* 09F4B0 802DFCB0 0222082A */ slt $at, $s1, $v0 +/* 09F4B4 802DFCB4 1420FFF3 */ bnez $at, .L80200634 +/* 09F4B8 802DFCB8 26100108 */ addiu $s0, $s0, 0x108 +.L8020066C: +/* 09F4BC 802DFCBC 03C02025 */ move $a0, $fp +/* 09F4C0 802DFCC0 02602825 */ move $a1, $s3 +/* 09F4C4 802DFCC4 8FA60048 */ lw $a2, 0x48($sp) +/* 09F4C8 802DFCC8 0C0B808A */ jal synthesis_do_one_audio_update +/* 09F4CC 802DFCCC 02543823 */ subu $a3, $s2, $s4 +/* 09F4D0 802DFCD0 2694FFFF */ addiu $s4, $s4, -1 +/* 09F4D4 802DFCD4 00136880 */ sll $t5, $s3, 2 +/* 09F4D8 802DFCD8 AFA20048 */ sw $v0, 0x48($sp) +/* 09F4DC 802DFCDC 02F3B823 */ subu $s7, $s7, $s3 +/* 09F4E0 802DFCE0 1E80FFAC */ bgtz $s4, .L80200544 +/* 09F4E4 802DFCE4 03CDF021 */ addu $fp, $fp, $t5 +/* 09F4E8 802DFCE8 AFB50040 */ sw $s5, 0x40($sp) +.L8020069C: +/* 09F4EC 802DFCEC 3C028022 */ lui $v0, %hi(gNumSynthesisReverbs) # $v0, 0x8022 +/* 09F4F0 802DFCF0 8042C5E3 */ lb $v0, %lo(gNumSynthesisReverbs)($v0) +/* 09F4F4 802DFCF4 3C0E8022 */ lui $t6, %hi(gSynthesisReverbs) +/* 09F4F8 802DFCF8 25D0C1B0 */ addiu $s0, $t6, %lo(gSynthesisReverbs) +/* 09F4FC 802DFCFC 1840000E */ blez $v0, .L802006E8 +/* 09F500 802DFD00 00027940 */ sll $t7, $v0, 5 +/* 09F504 802DFD04 01E27821 */ addu $t7, $t7, $v0 +/* 09F508 802DFD08 000F78C0 */ sll $t7, $t7, 3 +/* 09F50C 802DFD0C 01F01821 */ addu $v1, $t7, $s0 +.L802006C0: +/* 09F510 802DFD10 92020002 */ lbu $v0, 2($s0) +/* 09F514 802DFD14 10400002 */ beqz $v0, .L802006D0 +/* 09F518 802DFD18 2458FFFF */ addiu $t8, $v0, -1 +/* 09F51C 802DFD1C A2180002 */ sb $t8, 2($s0) +.L802006D0: +/* 09F520 802DFD20 92190003 */ lbu $t9, 3($s0) +/* 09F524 802DFD24 26100108 */ addiu $s0, $s0, 0x108 +/* 09F528 802DFD28 0203082B */ sltu $at, $s0, $v1 +/* 09F52C 802DFD2C 3B280001 */ xori $t0, $t9, 1 +/* 09F530 802DFD30 1420FFF7 */ bnez $at, .L802006C0 +/* 09F534 802DFD34 A208FEFB */ sb $t0, -0x105($s0) +.L802006E8: +/* 09F538 802DFD38 8FA20048 */ lw $v0, 0x48($sp) +/* 09F53C 802DFD3C 8FAA0060 */ lw $t2, 0x60($sp) +/* 09F540 802DFD40 8FAD0064 */ lw $t5, 0x64($sp) +/* 09F544 802DFD44 004A5823 */ subu $t3, $v0, $t2 +/* 09F548 802DFD48 000B60C3 */ sra $t4, $t3, 3 +/* 09F54C 802DFD4C ADAC0000 */ sw $t4, ($t5) +/* 09F550 802DFD50 8FBF003C */ lw $ra, 0x3c($sp) +/* 09F554 802DFD54 8FBE0038 */ lw $fp, 0x38($sp) +/* 09F558 802DFD58 8FB70034 */ lw $s7, 0x34($sp) +/* 09F55C 802DFD5C 8FB60030 */ lw $s6, 0x30($sp) +/* 09F560 802DFD60 8FB5002C */ lw $s5, 0x2c($sp) +/* 09F564 802DFD64 8FB40028 */ lw $s4, 0x28($sp) +/* 09F568 802DFD68 8FB30024 */ lw $s3, 0x24($sp) +/* 09F56C 802DFD6C 8FB20020 */ lw $s2, 0x20($sp) +/* 09F570 802DFD70 8FB1001C */ lw $s1, 0x1c($sp) +/* 09F574 802DFD74 8FB00018 */ lw $s0, 0x18($sp) +/* 09F578 802DFD78 03E00008 */ jr $ra +/* 09F57C 802DFD7C 27BD0060 */ addiu $sp, $sp, 0x60 diff --git a/asm/non_matchings/eu/audio/synthesis_process_note.s b/asm/non_matchings/eu/audio/synthesis_process_note.s new file mode 100644 index 0000000..11415a3 --- /dev/null +++ b/asm/non_matchings/eu/audio/synthesis_process_note.s @@ -0,0 +1,657 @@ +glabel synthesis_process_note +/* 09FEF0 802E06F0 27BDFEB8 */ addiu $sp, $sp, -0x148 +/* 09FEF4 802E06F4 AFBF004C */ sw $ra, 0x4c($sp) +/* 09FEF8 802E06F8 AFBE0048 */ sw $fp, 0x48($sp) +/* 09FEFC 802E06FC AFB70044 */ sw $s7, 0x44($sp) +/* 09FF00 802E0700 AFB60040 */ sw $s6, 0x40($sp) +/* 09FF04 802E0704 AFB5003C */ sw $s5, 0x3c($sp) +/* 09FF08 802E0708 AFB40038 */ sw $s4, 0x38($sp) +/* 09FF0C 802E070C AFB30034 */ sw $s3, 0x34($sp) +/* 09FF10 802E0710 AFB20030 */ sw $s2, 0x30($sp) +/* 09FF14 802E0714 AFB1002C */ sw $s1, 0x2c($sp) +/* 09FF18 802E0718 AFB00028 */ sw $s0, 0x28($sp) +/* 09FF1C 802E071C AFA40148 */ sw $a0, 0x148($sp) +/* 09FF20 802E0720 AFA70154 */ sw $a3, 0x154($sp) +/* 09FF24 802E0724 AFA00130 */ sw $zero, 0x130($sp) +/* 09FF28 802E0728 8C8F00B0 */ lw $t7, 0xb0($a0) +/* 09FF2C 802E072C 00A08825 */ move $s1, $a1 +/* 09FF30 802E0730 00C0B825 */ move $s7, $a2 +/* 09FF34 802E0734 000FC7C2 */ srl $t8, $t7, 0x1f +/* 09FF38 802E0738 57000004 */ bnezl $t8, .L802010FC +/* 09FF3C 802E073C 8E390000 */ lw $t9, ($s1) +/* 09FF40 802E0740 1000023E */ b .L802019EC +/* 09FF44 802E0744 8FA2015C */ lw $v0, 0x15c($sp) +/* 09FF48 802E0748 8E390000 */ lw $t9, ($s1) +.L802010FC: +/* 09FF4C 802E074C 24130001 */ li $s3, 1 +/* 09FF50 802E0750 00001825 */ move $v1, $zero +/* 09FF54 802E0754 00197040 */ sll $t6, $t9, 1 +/* 09FF58 802E0758 000E7FC2 */ srl $t7, $t6, 0x1f +/* 09FF5C 802E075C 166F0009 */ bne $s3, $t7, .L80201134 +/* 09FF60 802E0760 02202825 */ move $a1, $s1 +/* 09FF64 802E0764 02601825 */ move $v1, $s3 +/* 09FF68 802E0768 A2E00000 */ sb $zero, ($s7) +/* 09FF6C 802E076C AEE00008 */ sw $zero, 8($s7) +/* 09FF70 802E0770 A6E00004 */ sh $zero, 4($s7) +/* 09FF74 802E0774 A6F30010 */ sh $s3, 0x10($s7) +/* 09FF78 802E0778 A6F30012 */ sh $s3, 0x12($s7) +/* 09FF7C 802E077C A2E00002 */ sb $zero, 2($s7) +/* 09FF80 802E0780 A2E00003 */ sb $zero, 3($s7) +.L80201134: +/* 09FF84 802E0784 9638000A */ lhu $t8, 0xa($s1) +/* 09FF88 802E0788 02E03025 */ move $a2, $s7 +/* 09FF8C 802E078C A7B8011A */ sh $t8, 0x11a($sp) +/* 09FF90 802E0790 96390000 */ lhu $t9, ($s1) +/* 09FF94 802E0794 3318FFFF */ andi $t8, $t8, 0xffff +/* 09FF98 802E0798 332E0001 */ andi $t6, $t9, 1 +/* 09FF9C 802E079C 8FB90158 */ lw $t9, 0x158($sp) +/* 09FFA0 802E07A0 25CF0001 */ addiu $t7, $t6, 1 +/* 09FFA4 802E07A4 AFAF00BC */ sw $t7, 0xbc($sp) +/* 09FFA8 802E07A8 03190019 */ multu $t8, $t9 +/* 09FFAC 802E07AC 96F80004 */ lhu $t8, 4($s7) +/* 09FFB0 802E07B0 00007012 */ mflo $t6 +/* 09FFB4 802E07B4 000E7840 */ sll $t7, $t6, 1 +/* 09FFB8 802E07B8 01F81021 */ addu $v0, $t7, $t8 +/* 09FFBC 802E07BC A6E20004 */ sh $v0, 4($s7) +/* 09FFC0 802E07C0 8E270000 */ lw $a3, ($s1) +/* 09FFC4 802E07C4 8FA4015C */ lw $a0, 0x15c($sp) +/* 09FFC8 802E07C8 00028402 */ srl $s0, $v0, 0x10 +/* 09FFCC 802E07CC 00077B80 */ sll $t7, $a3, 0xe +/* 09FFD0 802E07D0 05E3000D */ bgezl $t7, .L802011B8 +/* 09FFD4 802E07D4 8E2F000C */ lw $t7, 0xc($s1) +/* 09FFD8 802E07D8 0C0B841B */ jal load_wave_samples +/* 09FFDC 802E07DC 02003825 */ move $a3, $s0 +/* 09FFE0 802E07E0 8EE60008 */ lw $a2, 8($s7) +/* 09FFE4 802E07E4 0006C040 */ sll $t8, $a2, 1 +/* 09FFE8 802E07E8 27190180 */ addiu $t9, $t8, 0x180 +/* 09FFEC 802E07EC A7B900AA */ sh $t9, 0xaa($sp) +/* 09FFF0 802E07F0 00D07021 */ addu $t6, $a2, $s0 +/* 09FFF4 802E07F4 AEEE0008 */ sw $t6, 8($s7) +/* 09FFF8 802E07F8 8E270000 */ lw $a3, ($s1) +/* 09FFFC 802E07FC 100001D4 */ b .L80201900 +/* 0A0000 802E0800 AFA2015C */ sw $v0, 0x15c($sp) +/* 0A0004 802E0804 8E2F000C */ lw $t7, 0xc($s1) +.L802011B8: +/* 0A0008 802E0808 241F0009 */ li $ra, 9 +/* 0A000C 802E080C 3C0D8000 */ lui $t5, 0x8000 +/* 0A0010 802E0810 8DF80000 */ lw $t8, ($t7) +/* 0A0014 802E0814 AFB80138 */ sw $t8, 0x138($sp) +/* 0A0018 802E0818 8F0E0008 */ lw $t6, 8($t8) +/* 0A001C 802E081C AFAE0134 */ sw $t6, 0x134($sp) +/* 0A0020 802E0820 8DCF0004 */ lw $t7, 4($t6) +/* 0A0024 802E0824 8FAE00BC */ lw $t6, 0xbc($sp) +/* 0A0028 802E0828 AFAF00E4 */ sw $t7, 0xe4($sp) +/* 0A002C 802E082C 8F180004 */ lw $t8, 4($t8) +/* 0A0030 802E0830 AFA000AC */ sw $zero, 0xac($sp) +/* 0A0034 802E0834 AFA000B8 */ sw $zero, 0xb8($sp) +/* 0A0038 802E0838 19C001C5 */ blez $t6, .L80201900 +/* 0A003C 802E083C AFB800F4 */ sw $t8, 0xf4($sp) +/* 0A0040 802E0840 00027C02 */ srl $t7, $v0, 0x10 +/* 0A0044 802E0844 AFAF0050 */ sw $t7, 0x50($sp) +/* 0A0048 802E0848 AFA3011C */ sw $v1, 0x11c($sp) +/* 0A004C 802E084C AFB1014C */ sw $s1, 0x14c($sp) +/* 0A0050 802E0850 8FB2015C */ lw $s2, 0x15c($sp) +.L80201204: +/* 0A0054 802E0854 8FB90138 */ lw $t9, 0x138($sp) +/* 0A0058 802E0858 8FB800BC */ lw $t8, 0xbc($sp) +/* 0A005C 802E085C 24010001 */ li $at, 1 +/* 0A0060 802E0860 8F24000C */ lw $a0, 0xc($t9) +/* 0A0064 802E0864 0000F025 */ move $fp, $zero +/* 0A0068 802E0868 0000A025 */ move $s4, $zero +/* 0A006C 802E086C 17010003 */ bne $t8, $at, .L8020122C +/* 0A0070 802E0870 24850008 */ addiu $a1, $a0, 8 +/* 0A0074 802E0874 1000000B */ b .L80201254 +/* 0A0078 802E0878 8FAC0050 */ lw $t4, 0x50($sp) +.L8020122C: +/* 0A007C 802E087C 8FAE0050 */ lw $t6, 0x50($sp) +/* 0A0080 802E0880 8FB800B8 */ lw $t8, 0xb8($sp) +/* 0A0084 802E0884 8FAC0050 */ lw $t4, 0x50($sp) +/* 0A0088 802E0888 31CF0001 */ andi $t7, $t6, 1 +/* 0A008C 802E088C 11E00005 */ beqz $t7, .L80201254 +/* 0A0090 802E0890 2401FFFE */ li $at, -2 +/* 0A0094 802E0894 01C1C824 */ and $t9, $t6, $at +/* 0A0098 802E0898 00187840 */ sll $t7, $t8, 1 +/* 0A009C 802E089C 10000001 */ b .L80201254 +/* 0A00A0 802E08A0 032F6021 */ addu $t4, $t9, $t7 +.L80201254: +/* 0A00A4 802E08A4 8FAE0130 */ lw $t6, 0x130($sp) +/* 0A00A8 802E08A8 51C5001A */ beql $t6, $a1, .L802012C4 +/* 0A00AC 802E08AC 0007C2C0 */ sll $t8, $a3, 0xb +/* 0A00B0 802E08B0 AFA50130 */ sw $a1, 0x130($sp) +/* 0A00B4 802E08B4 8C980000 */ lw $t8, ($a0) +/* 0A00B8 802E08B8 8C8F0004 */ lw $t7, 4($a0) +/* 0A00BC 802E08BC 3C0100FF */ lui $at, (0x00FFFFFF >> 16) # lui $at, 0xff +/* 0A00C0 802E08C0 0018C900 */ sll $t9, $t8, 4 +/* 0A00C4 802E08C4 032F0019 */ multu $t9, $t7 +/* 0A00C8 802E08C8 3421FFFF */ ori $at, (0x00FFFFFF & 0xFFFF) # ori $at, $at, 0xffff +/* 0A00CC 802E08CC 8FA6014C */ lw $a2, 0x14c($sp) +/* 0A00D0 802E08D0 02401025 */ move $v0, $s2 +/* 0A00D4 802E08D4 26520008 */ addiu $s2, $s2, 8 +/* 0A00D8 802E08D8 00001812 */ mflo $v1 +/* 0A00DC 802E08DC 00617024 */ and $t6, $v1, $at +/* 0A00E0 802E08E0 3C010B00 */ lui $at, 0xb00 +/* 0A00E4 802E08E4 01C1C025 */ or $t8, $t6, $at +/* 0A00E8 802E08E8 AC580000 */ sw $t8, ($v0) +/* 0A00EC 802E08EC 8CD90000 */ lw $t9, ($a2) +/* 0A00F0 802E08F0 00197AC0 */ sll $t7, $t9, 0xb +/* 0A00F4 802E08F4 8FB90130 */ lw $t9, 0x130($sp) +/* 0A00F8 802E08F8 000F7742 */ srl $t6, $t7, 0x1d +/* 0A00FC 802E08FC 000EC040 */ sll $t8, $t6, 1 +/* 0A0100 802E0900 03197821 */ addu $t7, $t8, $t9 +/* 0A0104 802E0904 01ED7021 */ addu $t6, $t7, $t5 +/* 0A0108 802E0908 AC4E0004 */ sw $t6, 4($v0) +/* 0A010C 802E090C 8CC70000 */ lw $a3, ($a2) +/* 0A0110 802E0910 0007C2C0 */ sll $t8, $a3, 0xb +.L802012C4: +/* 0A0114 802E0914 0018CF42 */ srl $t9, $t8, 0x1d +/* 0A0118 802E0918 13200003 */ beqz $t9, .L802012D8 +/* 0A011C 802E091C 3C0F8030 */ lui $t7, %hi(euUnknownData_80301950) # $t7, 0x8030 +/* 0A0120 802E0920 25EF1970 */ addiu $t7, %lo(euUnknownData_80301950) # addiu $t7, $t7, 0x1970 +/* 0A0124 802E0924 AFAF0130 */ sw $t7, 0x130($sp) +.L802012D8: +/* 0A0128 802E0928 51800108 */ beql $t4, $zero, .L802016FC +/* 0A012C 802E092C 8FA400BC */ lw $a0, 0xbc($sp) +/* 0A0130 802E0930 8EE60008 */ lw $a2, 8($s7) +.L802012E4: +/* 0A0134 802E0934 8FAE00E4 */ lw $t6, 0xe4($sp) +/* 0A0138 802E0938 019E2023 */ subu $a0, $t4, $fp +/* 0A013C 802E093C 30D3000F */ andi $s3, $a2, 0xf +/* 0A0140 802E0940 00004825 */ move $t1, $zero +/* 0A0144 802E0944 00005025 */ move $t2, $zero +/* 0A0148 802E0948 00805825 */ move $t3, $a0 +/* 0A014C 802E094C 16600005 */ bnez $s3, .L80201314 +/* 0A0150 802E0950 01C61823 */ subu $v1, $t6, $a2 +/* 0A0154 802E0954 92F80000 */ lbu $t8, ($s7) +/* 0A0158 802E0958 57000003 */ bnezl $t8, .L80201318 +/* 0A015C 802E095C 24190010 */ li $t9, 16 +/* 0A0160 802E0960 24130010 */ li $s3, 16 +.L80201314: +/* 0A0164 802E0964 24190010 */ li $t9, 16 +.L80201318: +/* 0A0168 802E0968 03332823 */ subu $a1, $t9, $s3 +/* 0A016C 802E096C 0083082A */ slt $at, $a0, $v1 +/* 0A0170 802E0970 1020000C */ beqz $at, .L80201354 +/* 0A0174 802E0974 00A0A825 */ move $s5, $a1 +/* 0A0178 802E0978 00851023 */ subu $v0, $a0, $a1 +/* 0A017C 802E097C 2442000F */ addiu $v0, $v0, 0xf +/* 0A0180 802E0980 04410003 */ bgez $v0, .L80201340 +/* 0A0184 802E0984 00027903 */ sra $t7, $v0, 4 +/* 0A0188 802E0988 2441000F */ addiu $at, $v0, 0xf +/* 0A018C 802E098C 00017903 */ sra $t7, $at, 4 +.L80201340: +/* 0A0190 802E0990 000F8900 */ sll $s1, $t7, 4 +/* 0A0194 802E0994 00B17021 */ addu $t6, $a1, $s1 +/* 0A0198 802E0998 01E04025 */ move $t0, $t7 +/* 0A019C 802E099C 10000013 */ b .L8020139C +/* 0A01A0 802E09A0 01C4B023 */ subu $s6, $t6, $a0 +.L80201354: +/* 0A01A4 802E09A4 00658823 */ subu $s1, $v1, $a1 +/* 0A01A8 802E09A8 1E200003 */ bgtz $s1, .L80201368 +/* 0A01AC 802E09AC 0000B025 */ move $s6, $zero +/* 0A01B0 802E09B0 00008825 */ move $s1, $zero +/* 0A01B4 802E09B4 0060A825 */ move $s5, $v1 +.L80201368: +/* 0A01B8 802E09B8 8FB90134 */ lw $t9, 0x134($sp) +/* 0A01BC 802E09BC 2628000F */ addiu $t0, $s1, 0xf +/* 0A01C0 802E09C0 05010003 */ bgez $t0, .L80201380 +/* 0A01C4 802E09C4 0008C103 */ sra $t8, $t0, 4 +/* 0A01C8 802E09C8 2501000F */ addiu $at, $t0, 0xf +/* 0A01CC 802E09CC 0001C103 */ sra $t8, $at, 4 +.L80201380: +/* 0A01D0 802E09D0 8F2F0008 */ lw $t7, 8($t9) +/* 0A01D4 802E09D4 03004025 */ move $t0, $t8 +/* 0A01D8 802E09D8 51E00004 */ beql $t7, $zero, .L8020139C +/* 0A01DC 802E09DC 24090001 */ li $t1, 1 +/* 0A01E0 802E09E0 10000002 */ b .L8020139C +/* 0A01E4 802E09E4 240A0001 */ li $t2, 1 +/* 0A01E8 802E09E8 24090001 */ li $t1, 1 +.L8020139C: +/* 0A01EC 802E09EC 1100003C */ beqz $t0, .L80201490 +/* 0A01F0 802E09F0 8FB80138 */ lw $t8, 0x138($sp) +/* 0A01F4 802E09F4 00D31023 */ subu $v0, $a2, $s3 +/* 0A01F8 802E09F8 24420010 */ addiu $v0, $v0, 0x10 +/* 0A01FC 802E09FC 93190001 */ lbu $t9, 1($t8) +/* 0A0200 802E0A00 04410003 */ bgez $v0, .L802013C0 +/* 0A0204 802E0A04 00027103 */ sra $t6, $v0, 4 +/* 0A0208 802E0A08 2441000F */ addiu $at, $v0, 0xf +/* 0A020C 802E0A0C 00017103 */ sra $t6, $at, 4 +.L802013C0: +/* 0A0210 802E0A10 24010081 */ li $at, 129 +/* 0A0214 802E0A14 17210009 */ bne $t9, $at, .L802013EC +/* 0A0218 802E0A18 01C01025 */ move $v0, $t6 +/* 0A021C 802E0A1C 01DF0019 */ multu $t6, $ra +/* 0A0220 802E0A20 8FAE00F4 */ lw $t6, 0xf4($sp) +/* 0A0224 802E0A24 000880C0 */ sll $s0, $t0, 3 +/* 0A0228 802E0A28 02088021 */ addu $s0, $s0, $t0 +/* 0A022C 802E0A2C 00007812 */ mflo $t7 +/* 0A0230 802E0A30 01EE2821 */ addu $a1, $t7, $t6 +/* 0A0234 802E0A34 10000019 */ b .L8020144C +/* 0A0238 802E0A38 30A8000F */ andi $t0, $a1, 0xf +.L802013EC: +/* 0A023C 802E0A3C 005F0019 */ multu $v0, $ra +/* 0A0240 802E0A40 8FB900F4 */ lw $t9, 0xf4($sp) +/* 0A0244 802E0A44 8FA6011C */ lw $a2, 0x11c($sp) +/* 0A0248 802E0A48 26E70001 */ addiu $a3, $s7, 1 +/* 0A024C 802E0A4C AFA90124 */ sw $t1, 0x124($sp) +/* 0A0250 802E0A50 AFAA0120 */ sw $t2, 0x120($sp) +/* 0A0254 802E0A54 AFAB00E0 */ sw $t3, 0xe0($sp) +/* 0A0258 802E0A58 AFAC00EC */ sw $t4, 0xec($sp) +/* 0A025C 802E0A5C 0000C012 */ mflo $t8 +/* 0A0260 802E0A60 03192021 */ addu $a0, $t8, $t9 +/* 0A0264 802E0A64 00000000 */ nop +/* 0A0268 802E0A68 011F0019 */ multu $t0, $ra +/* 0A026C 802E0A6C 00008012 */ mflo $s0 +/* 0A0270 802E0A70 02002825 */ move $a1, $s0 +/* 0A0274 802E0A74 0C0B8D57 */ jal dma_sample_data +/* 0A0278 802E0A78 00000000 */ nop +/* 0A027C 802E0A7C 8FA90124 */ lw $t1, 0x124($sp) +/* 0A0280 802E0A80 8FAA0120 */ lw $t2, 0x120($sp) +/* 0A0284 802E0A84 8FAB00E0 */ lw $t3, 0xe0($sp) +/* 0A0288 802E0A88 8FAC00EC */ lw $t4, 0xec($sp) +/* 0A028C 802E0A8C 3C0D8000 */ lui $t5, 0x8000 +/* 0A0290 802E0A90 241F0009 */ li $ra, 9 +/* 0A0294 802E0A94 00402825 */ move $a1, $v0 +/* 0A0298 802E0A98 30A8000F */ andi $t0, $a1, 0xf +.L8020144C: +/* 0A029C 802E0A9C 02401825 */ move $v1, $s2 +/* 0A02A0 802E0AA0 3C0F0800 */ lui $t7, (0x080003F0 >> 16) # lui $t7, 0x800 +/* 0A02A4 802E0AA4 35EF03F0 */ ori $t7, (0x080003F0 & 0xFFFF) # ori $t7, $t7, 0x3f0 +/* 0A02A8 802E0AA8 02087021 */ addu $t6, $s0, $t0 +/* 0A02AC 802E0AAC 31D8FFFF */ andi $t8, $t6, 0xffff +/* 0A02B0 802E0AB0 AC6F0000 */ sw $t7, ($v1) +/* 0A02B4 802E0AB4 26520008 */ addiu $s2, $s2, 8 +/* 0A02B8 802E0AB8 AC780004 */ sw $t8, 4($v1) +/* 0A02BC 802E0ABC 02402025 */ move $a0, $s2 +/* 0A02C0 802E0AC0 00A87823 */ subu $t7, $a1, $t0 +/* 0A02C4 802E0AC4 01ED7021 */ addu $t6, $t7, $t5 +/* 0A02C8 802E0AC8 3C190400 */ lui $t9, 0x400 +/* 0A02CC 802E0ACC AC990000 */ sw $t9, ($a0) +/* 0A02D0 802E0AD0 AC8E0004 */ sw $t6, 4($a0) +/* 0A02D4 802E0AD4 92E60000 */ lbu $a2, ($s7) +/* 0A02D8 802E0AD8 10000004 */ b .L8020149C +/* 0A02DC 802E0ADC 26520008 */ addiu $s2, $s2, 8 +.L80201490: +/* 0A02E0 802E0AE0 00008825 */ move $s1, $zero +/* 0A02E4 802E0AE4 00004025 */ move $t0, $zero +/* 0A02E8 802E0AE8 92E60000 */ lbu $a2, ($s7) +.L8020149C: +/* 0A02EC 802E0AEC 10C0000D */ beqz $a2, .L802014D4 +/* 0A02F0 802E0AF0 02401025 */ move $v0, $s2 +/* 0A02F4 802E0AF4 3C180F00 */ lui $t8, 0xf00 +/* 0A02F8 802E0AF8 AC580000 */ sw $t8, ($v0) +/* 0A02FC 802E0AFC 8FB90138 */ lw $t9, 0x138($sp) +/* 0A0300 802E0B00 3C018000 */ lui $at, (0x80000010 >> 16) # lui $at, 0x8000 +/* 0A0304 802E0B04 34210010 */ ori $at, (0x80000010 & 0xFFFF) # ori $at, $at, 0x10 +/* 0A0308 802E0B08 8F2F0008 */ lw $t7, 8($t9) +/* 0A030C 802E0B0C 24180002 */ li $t8, 2 +/* 0A0310 802E0B10 26520008 */ addiu $s2, $s2, 8 +/* 0A0314 802E0B14 01E17021 */ addu $t6, $t7, $at +/* 0A0318 802E0B18 AC4E0004 */ sw $t6, 4($v0) +/* 0A031C 802E0B1C AFB8011C */ sw $t8, 0x11c($sp) +/* 0A0320 802E0B20 A2E00000 */ sb $zero, ($s7) +.L802014D4: +/* 0A0324 802E0B24 17C0001D */ bnez $fp, .L8020154C +/* 0A0328 802E0B28 02401825 */ move $v1, $s2 +/* 0A032C 802E0B2C 251903F0 */ addiu $t9, $t0, 0x3f0 +/* 0A0330 802E0B30 332FFFFF */ andi $t7, $t9, 0xffff +/* 0A0334 802E0B34 3C010800 */ lui $at, 0x800 +/* 0A0338 802E0B38 01E17025 */ or $t6, $t7, $at +/* 0A033C 802E0B3C 00113040 */ sll $a2, $s1, 1 +/* 0A0340 802E0B40 30D8FFFF */ andi $t8, $a2, 0xffff +/* 0A0344 802E0B44 3C010180 */ lui $at, 0x180 +/* 0A0348 802E0B48 02401025 */ move $v0, $s2 +/* 0A034C 802E0B4C 0301C825 */ or $t9, $t8, $at +/* 0A0350 802E0B50 AC590004 */ sw $t9, 4($v0) +/* 0A0354 802E0B54 AC4E0000 */ sw $t6, ($v0) +/* 0A0358 802E0B58 8FAF011C */ lw $t7, 0x11c($sp) +/* 0A035C 802E0B5C 26520008 */ addiu $s2, $s2, 8 +/* 0A0360 802E0B60 3C010100 */ lui $at, 0x100 +/* 0A0364 802E0B64 31EE00FF */ andi $t6, $t7, 0xff +/* 0A0368 802E0B68 000EC400 */ sll $t8, $t6, 0x10 +/* 0A036C 802E0B6C 0301C825 */ or $t9, $t8, $at +/* 0A0370 802E0B70 02401825 */ move $v1, $s2 +/* 0A0374 802E0B74 AC790000 */ sw $t9, ($v1) +/* 0A0378 802E0B78 8EEF000C */ lw $t7, 0xc($s7) +/* 0A037C 802E0B7C 0235C821 */ addu $t9, $s1, $s5 +/* 0A0380 802E0B80 0013C040 */ sll $t8, $s3, 1 +/* 0A0384 802E0B84 01ED7021 */ addu $t6, $t7, $t5 +/* 0A0388 802E0B88 AC6E0004 */ sw $t6, 4($v1) +/* 0A038C 802E0B8C 26520008 */ addiu $s2, $s2, 8 +/* 0A0390 802E0B90 AFB80104 */ sw $t8, 0x104($sp) +/* 0A0394 802E0B94 1000002F */ b .L80201604 +/* 0A0398 802E0B98 03363823 */ subu $a3, $t9, $s6 +.L8020154C: +/* 0A039C 802E0B9C 250F03F0 */ addiu $t7, $t0, 0x3f0 +/* 0A03A0 802E0BA0 31EEFFFF */ andi $t6, $t7, 0xffff +/* 0A03A4 802E0BA4 3C010800 */ lui $at, 0x800 +/* 0A03A8 802E0BA8 01C1C025 */ or $t8, $t6, $at +/* 0A03AC 802E0BAC 2401FFE0 */ li $at, -32 +/* 0A03B0 802E0BB0 2682001F */ addiu $v0, $s4, 0x1f +/* 0A03B4 802E0BB4 0041C824 */ and $t9, $v0, $at +/* 0A03B8 802E0BB8 272E0180 */ addiu $t6, $t9, 0x180 +/* 0A03BC 802E0BBC 03201025 */ move $v0, $t9 +/* 0A03C0 802E0BC0 AC780000 */ sw $t8, ($v1) +/* 0A03C4 802E0BC4 00113040 */ sll $a2, $s1, 1 +/* 0A03C8 802E0BC8 30D9FFFF */ andi $t9, $a2, 0xffff +/* 0A03CC 802E0BCC 000EC400 */ sll $t8, $t6, 0x10 +/* 0A03D0 802E0BD0 03197825 */ or $t7, $t8, $t9 +/* 0A03D4 802E0BD4 AC6F0004 */ sw $t7, 4($v1) +/* 0A03D8 802E0BD8 8FAE011C */ lw $t6, 0x11c($sp) +/* 0A03DC 802E0BDC 26520008 */ addiu $s2, $s2, 8 +/* 0A03E0 802E0BE0 3C010100 */ lui $at, 0x100 +/* 0A03E4 802E0BE4 31D800FF */ andi $t8, $t6, 0xff +/* 0A03E8 802E0BE8 0018CC00 */ sll $t9, $t8, 0x10 +/* 0A03EC 802E0BEC 03217825 */ or $t7, $t9, $at +/* 0A03F0 802E0BF0 02402025 */ move $a0, $s2 +/* 0A03F4 802E0BF4 AC8F0000 */ sw $t7, ($a0) +/* 0A03F8 802E0BF8 8EEE000C */ lw $t6, 0xc($s7) +/* 0A03FC 802E0BFC 0013C840 */ sll $t9, $s3, 1 +/* 0A0400 802E0C00 00597821 */ addu $t7, $v0, $t9 +/* 0A0404 802E0C04 01CDC021 */ addu $t8, $t6, $t5 +/* 0A0408 802E0C08 3C0100FF */ lui $at, (0x00FFFFFF >> 16) # lui $at, 0xff +/* 0A040C 802E0C0C AC980004 */ sw $t8, 4($a0) +/* 0A0410 802E0C10 3421FFFF */ ori $at, (0x00FFFFFF & 0xFFFF) # ori $at, $at, 0xffff +/* 0A0414 802E0C14 25EE0180 */ addiu $t6, $t7, 0x180 +/* 0A0418 802E0C18 01C1C024 */ and $t8, $t6, $at +/* 0A041C 802E0C1C 3C010A00 */ lui $at, 0xa00 +/* 0A0420 802E0C20 26520008 */ addiu $s2, $s2, 8 +/* 0A0424 802E0C24 0301C825 */ or $t9, $t8, $at +/* 0A0428 802E0C28 02357821 */ addu $t7, $s1, $s5 +/* 0A042C 802E0C2C 01F63823 */ subu $a3, $t7, $s6 +/* 0A0430 802E0C30 02402825 */ move $a1, $s2 +/* 0A0434 802E0C34 ACB90000 */ sw $t9, ($a1) +/* 0A0438 802E0C38 00077840 */ sll $t7, $a3, 1 +/* 0A043C 802E0C3C 26980180 */ addiu $t8, $s4, 0x180 +/* 0A0440 802E0C40 0018CC00 */ sll $t9, $t8, 0x10 +/* 0A0444 802E0C44 31EEFFFF */ andi $t6, $t7, 0xffff +/* 0A0448 802E0C48 032EC025 */ or $t8, $t9, $t6 +/* 0A044C 802E0C4C ACB80004 */ sw $t8, 4($a1) +/* 0A0450 802E0C50 26520008 */ addiu $s2, $s2, 8 +.L80201604: +/* 0A0454 802E0C54 8FAF011C */ lw $t7, 0x11c($sp) +/* 0A0458 802E0C58 24010001 */ li $at, 1 +/* 0A045C 802E0C5C 03C7F021 */ addu $fp, $fp, $a3 +/* 0A0460 802E0C60 11E10005 */ beq $t7, $at, .L80201628 +/* 0A0464 802E0C64 39E20002 */ xori $v0, $t7, 2 +/* 0A0468 802E0C68 10400007 */ beqz $v0, .L80201638 +/* 0A046C 802E0C6C AFA0011C */ sw $zero, 0x11c($sp) +/* 0A0470 802E0C70 10000008 */ b .L80201644 +/* 0A0474 802E0C74 00077040 */ sll $t6, $a3, 1 +.L80201628: +/* 0A0478 802E0C78 AFA00104 */ sw $zero, 0x104($sp) +/* 0A047C 802E0C7C 00D4A021 */ addu $s4, $a2, $s4 +/* 0A0480 802E0C80 1000000B */ b .L80201660 +/* 0A0484 802E0C84 AFA0011C */ sw $zero, 0x11c($sp) +.L80201638: +/* 0A0488 802E0C88 0007C840 */ sll $t9, $a3, 1 +/* 0A048C 802E0C8C 10000008 */ b .L80201660 +/* 0A0490 802E0C90 0334A021 */ addu $s4, $t9, $s4 +.L80201644: +/* 0A0494 802E0C94 52800004 */ beql $s4, $zero, .L80201658 +/* 0A0498 802E0C98 0267A021 */ addu $s4, $s3, $a3 +/* 0A049C 802E0C9C 10000004 */ b .L80201660 +/* 0A04A0 802E0CA0 01D4A021 */ addu $s4, $t6, $s4 +/* 0A04A4 802E0CA4 0267A021 */ addu $s4, $s3, $a3 +.L80201658: +/* 0A04A8 802E0CA8 0014C040 */ sll $t8, $s4, 1 +/* 0A04AC 802E0CAC 0300A025 */ move $s4, $t8 +.L80201660: +/* 0A04B0 802E0CB0 11200019 */ beqz $t1, .L802016C8 +/* 0A04B4 802E0CB4 24190001 */ li $t9, 1 +/* 0A04B8 802E0CB8 3C0100FF */ lui $at, (0x00FFFFFF >> 16) # lui $at, 0xff +/* 0A04BC 802E0CBC 3421FFFF */ ori $at, (0x00FFFFFF & 0xFFFF) # ori $at, $at, 0xffff +/* 0A04C0 802E0CC0 268F0180 */ addiu $t7, $s4, 0x180 +/* 0A04C4 802E0CC4 01E1C824 */ and $t9, $t7, $at +/* 0A04C8 802E0CC8 8FA3014C */ lw $v1, 0x14c($sp) +/* 0A04CC 802E0CCC 8FA60148 */ lw $a2, 0x148($sp) +/* 0A04D0 802E0CD0 3C010200 */ lui $at, 0x200 +/* 0A04D4 802E0CD4 02401025 */ move $v0, $s2 +/* 0A04D8 802E0CD8 019EC023 */ subu $t8, $t4, $fp +/* 0A04DC 802E0CDC 00187840 */ sll $t7, $t8, 1 +/* 0A04E0 802E0CE0 03217025 */ or $t6, $t9, $at +/* 0A04E4 802E0CE4 AC4E0000 */ sw $t6, ($v0) +/* 0A04E8 802E0CE8 AC4F0004 */ sw $t7, 4($v0) +/* 0A04EC 802E0CEC 906E0000 */ lbu $t6, ($v1) +/* 0A04F0 802E0CF0 26520008 */ addiu $s2, $s2, 8 +/* 0A04F4 802E0CF4 35D80020 */ ori $t8, $t6, 0x20 +/* 0A04F8 802E0CF8 A0780000 */ sb $t8, ($v1) +/* 0A04FC 802E0CFC 90D900B0 */ lbu $t9, 0xb0($a2) +/* 0A0500 802E0D00 372E0020 */ ori $t6, $t9, 0x20 +/* 0A0504 802E0D04 A0CE00B0 */ sb $t6, 0xb0($a2) +/* 0A0508 802E0D08 90D800B0 */ lbu $t8, 0xb0($a2) +/* 0A050C 802E0D0C 330FFF7F */ andi $t7, $t8, 0xff7f +/* 0A0510 802E0D10 1000000D */ b .L802016F8 +/* 0A0514 802E0D14 A0CF00B0 */ sb $t7, 0xb0($a2) +.L802016C8: +/* 0A0518 802E0D18 51400007 */ beql $t2, $zero, .L802016E8 +/* 0A051C 802E0D1C 8EEF0008 */ lw $t7, 8($s7) +/* 0A0520 802E0D20 A2F90000 */ sb $t9, ($s7) +/* 0A0524 802E0D24 8FAE0134 */ lw $t6, 0x134($sp) +/* 0A0528 802E0D28 8DD80000 */ lw $t8, ($t6) +/* 0A052C 802E0D2C 10000004 */ b .L802016F0 +/* 0A0530 802E0D30 AEF80008 */ sw $t8, 8($s7) +/* 0A0534 802E0D34 8EEF0008 */ lw $t7, 8($s7) +.L802016E8: +/* 0A0538 802E0D38 01EBC821 */ addu $t9, $t7, $t3 +/* 0A053C 802E0D3C AEF90008 */ sw $t9, 8($s7) +.L802016F0: +/* 0A0540 802E0D40 57CCFEFC */ bnel $fp, $t4, .L802012E4 +/* 0A0544 802E0D44 8EE60008 */ lw $a2, 8($s7) +.L802016F8: +/* 0A0548 802E0D48 8FA400BC */ lw $a0, 0xbc($sp) +.L802016FC: +/* 0A054C 802E0D4C 24010001 */ li $at, 1 +/* 0A0550 802E0D50 8FA3014C */ lw $v1, 0x14c($sp) +/* 0A0554 802E0D54 10810009 */ beq $a0, $at, .L8020172C +/* 0A0558 802E0D58 8FB80104 */ lw $t8, 0x104($sp) +/* 0A055C 802E0D5C 24010002 */ li $at, 2 +/* 0A0560 802E0D60 1081000D */ beq $a0, $at, .L80201748 +/* 0A0564 802E0D64 8FAE00B8 */ lw $t6, 0xb8($sp) +/* 0A0568 802E0D68 8C670000 */ lw $a3, ($v1) +/* 0A056C 802E0D6C 00072880 */ sll $a1, $a3, 2 +/* 0A0570 802E0D70 000577C2 */ srl $t6, $a1, 0x1f +/* 0A0574 802E0D74 1000006A */ b .L802018D0 +/* 0A0578 802E0D78 01C02825 */ move $a1, $t6 +.L8020172C: +/* 0A057C 802E0D7C 270F0180 */ addiu $t7, $t8, 0x180 +/* 0A0580 802E0D80 A7AF00AA */ sh $t7, 0xaa($sp) +/* 0A0584 802E0D84 8C670000 */ lw $a3, ($v1) +/* 0A0588 802E0D88 00072880 */ sll $a1, $a3, 2 +/* 0A058C 802E0D8C 0005CFC2 */ srl $t9, $a1, 0x1f +/* 0A0590 802E0D90 10000063 */ b .L802018D0 +/* 0A0594 802E0D94 03202825 */ move $a1, $t9 +.L80201748: +/* 0A0598 802E0D98 11C00009 */ beqz $t6, .L80201770 +/* 0A059C 802E0D9C 8FA6014C */ lw $a2, 0x14c($sp) +/* 0A05A0 802E0DA0 24010001 */ li $at, 1 +/* 0A05A4 802E0DA4 11C10036 */ beq $t6, $at, .L80201830 +/* 0A05A8 802E0DA8 02401025 */ move $v0, $s2 +/* 0A05AC 802E0DAC 8C670000 */ lw $a3, ($v1) +/* 0A05B0 802E0DB0 00072880 */ sll $a1, $a3, 2 +/* 0A05B4 802E0DB4 0005C7C2 */ srl $t8, $a1, 0x1f +/* 0A05B8 802E0DB8 10000059 */ b .L802018D0 +/* 0A05BC 802E0DBC 03002825 */ move $a1, $t8 +.L80201770: +/* 0A05C0 802E0DC0 8FAF0104 */ lw $t7, 0x104($sp) +/* 0A05C4 802E0DC4 3C010800 */ lui $at, 0x800 +/* 0A05C8 802E0DC8 02401025 */ move $v0, $s2 +/* 0A05CC 802E0DCC 25F90180 */ addiu $t9, $t7, 0x180 +/* 0A05D0 802E0DD0 332EFFFF */ andi $t6, $t9, 0xffff +/* 0A05D4 802E0DD4 01C1C025 */ or $t8, $t6, $at +/* 0A05D8 802E0DD8 25840004 */ addiu $a0, $t4, 4 +/* 0A05DC 802E0DDC 308FFFFF */ andi $t7, $a0, 0xffff +/* 0A05E0 802E0DE0 3C010020 */ lui $at, 0x20 +/* 0A05E4 802E0DE4 01E1C825 */ or $t9, $t7, $at +/* 0A05E8 802E0DE8 26520008 */ addiu $s2, $s2, 8 +/* 0A05EC 802E0DEC 3C0E0501 */ lui $t6, (0x0501FF60 >> 16) # lui $t6, 0x501 +/* 0A05F0 802E0DF0 AC590004 */ sw $t9, 4($v0) +/* 0A05F4 802E0DF4 AC580000 */ sw $t8, ($v0) +/* 0A05F8 802E0DF8 35CEFF60 */ ori $t6, (0x0501FF60 & 0xFFFF) # ori $t6, $t6, 0xff60 +/* 0A05FC 802E0DFC 02401825 */ move $v1, $s2 +/* 0A0600 802E0E00 AC6E0000 */ sw $t6, ($v1) +/* 0A0604 802E0E04 8EF8000C */ lw $t8, 0xc($s7) +/* 0A0608 802E0E08 3C018000 */ lui $at, (0x800000F0 >> 16) # lui $at, 0x8000 +/* 0A060C 802E0E0C 342100F0 */ ori $at, (0x800000F0 & 0xFFFF) # ori $at, $at, 0xf0 +/* 0A0610 802E0E10 03017821 */ addu $t7, $t8, $at +/* 0A0614 802E0E14 AC6F0004 */ sw $t7, 4($v1) +/* 0A0618 802E0E18 24190024 */ li $t9, 36 +/* 0A061C 802E0E1C AFA400AC */ sw $a0, 0xac($sp) +/* 0A0620 802E0E20 A7B900AA */ sh $t9, 0xaa($sp) +/* 0A0624 802E0E24 8CC70000 */ lw $a3, ($a2) +/* 0A0628 802E0E28 26520008 */ addiu $s2, $s2, 8 +/* 0A062C 802E0E2C 02401025 */ move $v0, $s2 +/* 0A0630 802E0E30 00072880 */ sll $a1, $a3, 2 +/* 0A0634 802E0E34 000577C2 */ srl $t6, $a1, 0x1f +/* 0A0638 802E0E38 11C0000F */ beqz $t6, .L80201828 +/* 0A063C 802E0E3C 01C02825 */ move $a1, $t6 +/* 0A0640 802E0E40 3C0100FF */ lui $at, (0x00FFFFFF >> 16) # lui $at, 0xff +/* 0A0644 802E0E44 3421FFFF */ ori $at, (0x00FFFFFF & 0xFFFF) # ori $at, $at, 0xffff +/* 0A0648 802E0E48 24980020 */ addiu $t8, $a0, 0x20 +/* 0A064C 802E0E4C 03017824 */ and $t7, $t8, $at +/* 0A0650 802E0E50 3C010200 */ lui $at, 0x200 +/* 0A0654 802E0E54 01E1C825 */ or $t9, $t7, $at +/* 0A0658 802E0E58 258E0010 */ addiu $t6, $t4, 0x10 +/* 0A065C 802E0E5C AC4E0004 */ sw $t6, 4($v0) +/* 0A0660 802E0E60 AC590000 */ sw $t9, ($v0) +/* 0A0664 802E0E64 8CC70000 */ lw $a3, ($a2) +/* 0A0668 802E0E68 26520008 */ addiu $s2, $s2, 8 +/* 0A066C 802E0E6C 00072880 */ sll $a1, $a3, 2 +/* 0A0670 802E0E70 0005C7C2 */ srl $t8, $a1, 0x1f +/* 0A0674 802E0E74 03002825 */ move $a1, $t8 +.L80201828: +/* 0A0678 802E0E78 10000029 */ b .L802018D0 +/* 0A067C 802E0E7C 8FA400BC */ lw $a0, 0xbc($sp) +.L80201830: +/* 0A0680 802E0E80 8FAF0104 */ lw $t7, 0x104($sp) +/* 0A0684 802E0E84 3C010800 */ lui $at, 0x800 +/* 0A0688 802E0E88 26520008 */ addiu $s2, $s2, 8 +/* 0A068C 802E0E8C 25F90180 */ addiu $t9, $t7, 0x180 +/* 0A0690 802E0E90 332EFFFF */ andi $t6, $t9, 0xffff +/* 0A0694 802E0E94 01C1C025 */ or $t8, $t6, $at +/* 0A0698 802E0E98 258F0008 */ addiu $t7, $t4, 8 +/* 0A069C 802E0E9C 31F9FFFF */ andi $t9, $t7, 0xffff +/* 0A06A0 802E0EA0 AC580000 */ sw $t8, ($v0) +/* 0A06A4 802E0EA4 3C010160 */ lui $at, 0x160 +/* 0A06A8 802E0EA8 03217025 */ or $t6, $t9, $at +/* 0A06AC 802E0EAC 3C180501 */ lui $t8, (0x0501FF60 >> 16) # lui $t8, 0x501 +/* 0A06B0 802E0EB0 AC4E0004 */ sw $t6, 4($v0) +/* 0A06B4 802E0EB4 3718FF60 */ ori $t8, (0x0501FF60 & 0xFFFF) # ori $t8, $t8, 0xff60 +/* 0A06B8 802E0EB8 02401825 */ move $v1, $s2 +/* 0A06BC 802E0EBC AC780000 */ sw $t8, ($v1) +/* 0A06C0 802E0EC0 8EEF000C */ lw $t7, 0xc($s7) +/* 0A06C4 802E0EC4 3C018000 */ lui $at, (0x800000F0 >> 16) # lui $at, 0x8000 +/* 0A06C8 802E0EC8 342100F0 */ ori $at, (0x800000F0 & 0xFFFF) # ori $at, $at, 0xf0 +/* 0A06CC 802E0ECC 26520008 */ addiu $s2, $s2, 8 +/* 0A06D0 802E0ED0 3C0E0A00 */ lui $t6, (0x0A000164 >> 16) # lui $t6, 0xa00 +/* 0A06D4 802E0ED4 01E1C821 */ addu $t9, $t7, $at +/* 0A06D8 802E0ED8 AC790004 */ sw $t9, 4($v1) +/* 0A06DC 802E0EDC 35CE0164 */ ori $t6, (0x0A000164 & 0xFFFF) # ori $t6, $t6, 0x164 +/* 0A06E0 802E0EE0 02402025 */ move $a0, $s2 +/* 0A06E4 802E0EE4 AC8E0000 */ sw $t6, ($a0) +/* 0A06E8 802E0EE8 8FB800AC */ lw $t8, 0xac($sp) +/* 0A06EC 802E0EEC 26520008 */ addiu $s2, $s2, 8 +/* 0A06F0 802E0EF0 27190020 */ addiu $t9, $t8, 0x20 +/* 0A06F4 802E0EF4 25980004 */ addiu $t8, $t4, 4 +/* 0A06F8 802E0EF8 330FFFFF */ andi $t7, $t8, 0xffff +/* 0A06FC 802E0EFC 00197400 */ sll $t6, $t9, 0x10 +/* 0A0700 802E0F00 01CFC825 */ or $t9, $t6, $t7 +/* 0A0704 802E0F04 AC990004 */ sw $t9, 4($a0) +/* 0A0708 802E0F08 8FB8014C */ lw $t8, 0x14c($sp) +/* 0A070C 802E0F0C 8FA400BC */ lw $a0, 0xbc($sp) +/* 0A0710 802E0F10 8F070000 */ lw $a3, ($t8) +/* 0A0714 802E0F14 00072880 */ sll $a1, $a3, 2 +/* 0A0718 802E0F18 000577C2 */ srl $t6, $a1, 0x1f +/* 0A071C 802E0F1C 01C02825 */ move $a1, $t6 +.L802018D0: +/* 0A0720 802E0F20 10A00005 */ beqz $a1, .L802018E8 +/* 0A0724 802E0F24 8FA200B8 */ lw $v0, 0xb8($sp) +/* 0A0728 802E0F28 AFB2015C */ sw $s2, 0x15c($sp) +/* 0A072C 802E0F2C 24130001 */ li $s3, 1 +/* 0A0730 802E0F30 10000007 */ b .L80201900 +/* 0A0734 802E0F34 8FB1014C */ lw $s1, 0x14c($sp) +.L802018E8: +/* 0A0738 802E0F38 24420001 */ addiu $v0, $v0, 1 +/* 0A073C 802E0F3C 1444FE45 */ bne $v0, $a0, .L80201204 +/* 0A0740 802E0F40 AFA200B8 */ sw $v0, 0xb8($sp) +/* 0A0744 802E0F44 AFB2015C */ sw $s2, 0x15c($sp) +/* 0A0748 802E0F48 24130001 */ li $s3, 1 +/* 0A074C 802E0F4C 8FB1014C */ lw $s1, 0x14c($sp) +.L80201900: +/* 0A0750 802E0F50 00077840 */ sll $t7, $a3, 1 +/* 0A0754 802E0F54 000FCFC2 */ srl $t9, $t7, 0x1f +/* 0A0758 802E0F58 8FB2015C */ lw $s2, 0x15c($sp) +/* 0A075C 802E0F5C 16790005 */ bne $s3, $t9, .L80201924 +/* 0A0760 802E0F60 00001825 */ move $v1, $zero +/* 0A0764 802E0F64 92380000 */ lbu $t8, ($s1) +/* 0A0768 802E0F68 24030001 */ li $v1, 1 +/* 0A076C 802E0F6C 330EFFBF */ andi $t6, $t8, 0xffbf +/* 0A0770 802E0F70 A22E0000 */ sb $t6, ($s1) +.L80201924: +/* 0A0774 802E0F74 8FB30158 */ lw $s3, 0x158($sp) +/* 0A0778 802E0F78 97B900AA */ lhu $t9, 0xaa($sp) +/* 0A077C 802E0F7C 02402025 */ move $a0, $s2 +/* 0A0780 802E0F80 00133040 */ sll $a2, $s3, 1 +/* 0A0784 802E0F84 00C09825 */ move $s3, $a2 +/* 0A0788 802E0F88 02E02825 */ move $a1, $s7 +/* 0A078C 802E0F8C 97A7011A */ lhu $a3, 0x11a($sp) +/* 0A0790 802E0F90 AFA30014 */ sw $v1, 0x14($sp) +/* 0A0794 802E0F94 AFA3011C */ sw $v1, 0x11c($sp) +/* 0A0798 802E0F98 0C0B8449 */ jal final_resample +/* 0A079C 802E0F9C AFB90010 */ sw $t9, 0x10($sp) +/* 0A07A0 802E0FA0 92380003 */ lbu $t8, 3($s1) +/* 0A07A4 802E0FA4 00409025 */ move $s2, $v0 +/* 0A07A8 802E0FA8 8FB4011C */ lw $s4, 0x11c($sp) +/* 0A07AC 802E0FAC 17000004 */ bnez $t8, .L80201970 +/* 0A07B0 802E0FB0 02402025 */ move $a0, $s2 +/* 0A07B4 802E0FB4 92EE0002 */ lbu $t6, 2($s7) +/* 0A07B8 802E0FB8 51C00004 */ beql $t6, $zero, .L8020197C +/* 0A07BC 802E0FBC 922F0004 */ lbu $t7, 4($s1) +.L80201970: +/* 0A07C0 802E0FC0 1000000A */ b .L8020199C +/* 0A07C4 802E0FC4 24100001 */ li $s0, 1 +/* 0A07C8 802E0FC8 922F0004 */ lbu $t7, 4($s1) +.L8020197C: +/* 0A07CC 802E0FCC 15E00005 */ bnez $t7, .L80201994 +/* 0A07D0 802E0FD0 00000000 */ nop +/* 0A07D4 802E0FD4 92F90003 */ lbu $t9, 3($s7) +/* 0A07D8 802E0FD8 00008025 */ move $s0, $zero +/* 0A07DC 802E0FDC 13200003 */ beqz $t9, .L8020199C +/* 0A07E0 802E0FE0 00000000 */ nop +.L80201994: +/* 0A07E4 802E0FE4 10000001 */ b .L8020199C +/* 0A07E8 802E0FE8 24100002 */ li $s0, 2 +.L8020199C: +/* 0A07EC 802E0FEC 02202825 */ move $a1, $s1 +/* 0A07F0 802E0FF0 02E03025 */ move $a2, $s7 +/* 0A07F4 802E0FF4 8FA70158 */ lw $a3, 0x158($sp) +/* 0A07F8 802E0FF8 AFA00010 */ sw $zero, 0x10($sp) +/* 0A07FC 802E0FFC AFB00014 */ sw $s0, 0x14($sp) +/* 0A0800 802E1000 0C0B8460 */ jal process_envelope +/* 0A0804 802E1004 AFB40018 */ sw $s4, 0x18($sp) +/* 0A0808 802E1008 92380000 */ lbu $t8, ($s1) +/* 0A080C 802E100C 00409025 */ move $s2, $v0 +/* 0A0810 802E1010 00402025 */ move $a0, $v0 +/* 0A0814 802E1014 330E0001 */ andi $t6, $t8, 1 +/* 0A0818 802E1018 11C00007 */ beqz $t6, .L802019E8 +/* 0A081C 802E101C 02202825 */ move $a1, $s1 +/* 0A0820 802E1020 02E03025 */ move $a2, $s7 +/* 0A0824 802E1024 02603825 */ move $a3, $s3 +/* 0A0828 802E1028 AFB40010 */ sw $s4, 0x10($sp) +/* 0A082C 802E102C 0C0B85E6 */ jal note_apply_headset_pan_effects +/* 0A0830 802E1030 AFB00014 */ sw $s0, 0x14($sp) +/* 0A0834 802E1034 00409025 */ move $s2, $v0 +.L802019E8: +/* 0A0838 802E1038 02401025 */ move $v0, $s2 +.L802019EC: +/* 0A083C 802E103C 8FBF004C */ lw $ra, 0x4c($sp) +/* 0A0840 802E1040 8FB00028 */ lw $s0, 0x28($sp) +/* 0A0844 802E1044 8FB1002C */ lw $s1, 0x2c($sp) +/* 0A0848 802E1048 8FB20030 */ lw $s2, 0x30($sp) +/* 0A084C 802E104C 8FB30034 */ lw $s3, 0x34($sp) +/* 0A0850 802E1050 8FB40038 */ lw $s4, 0x38($sp) +/* 0A0854 802E1054 8FB5003C */ lw $s5, 0x3c($sp) +/* 0A0858 802E1058 8FB60040 */ lw $s6, 0x40($sp) +/* 0A085C 802E105C 8FB70044 */ lw $s7, 0x44($sp) +/* 0A0860 802E1060 8FBE0048 */ lw $fp, 0x48($sp) +/* 0A0864 802E1064 03E00008 */ jr $ra +/* 0A0868 802E1068 27BD0148 */ addiu $sp, $sp, 0x148 diff --git a/asm/non_matchings/eu/audio/synthesis_resample_and_mix_reverb.s b/asm/non_matchings/eu/audio/synthesis_resample_and_mix_reverb.s new file mode 100644 index 0000000..46b68a8 --- /dev/null +++ b/asm/non_matchings/eu/audio/synthesis_resample_and_mix_reverb.s @@ -0,0 +1,220 @@ +glabel synthesis_resample_and_mix_reverb +/* 09F580 802DFD80 27BDFFA0 */ addiu $sp, $sp, -0x60 +/* 09F584 802DFD84 AFB10020 */ sw $s1, 0x20($sp) +/* 09F588 802DFD88 00068C00 */ sll $s1, $a2, 0x10 +/* 09F58C 802DFD8C 00117403 */ sra $t6, $s1, 0x10 +/* 09F590 802DFD90 000EC940 */ sll $t9, $t6, 5 +/* 09F594 802DFD94 032EC821 */ addu $t9, $t9, $t6 +/* 09F598 802DFD98 3C0D8022 */ lui $t5, %hi(gSynthesisReverbs) # $t5, 0x8022 +/* 09F59C 802DFD9C 25ADC1B0 */ addiu $t5, %lo(gSynthesisReverbs) # addiu $t5, $t5, -0x3e50 +/* 09F5A0 802DFDA0 0019C8C0 */ sll $t9, $t9, 3 +/* 09F5A4 802DFDA4 01C08825 */ move $s1, $t6 +/* 09F5A8 802DFDA8 032D1821 */ addu $v1, $t9, $t5 +/* 09F5AC 802DFDAC 906E0003 */ lbu $t6, 3($v1) +/* 09F5B0 802DFDB0 AFA7006C */ sw $a3, 0x6c($sp) +/* 09F5B4 802DFDB4 00077C00 */ sll $t7, $a3, 0x10 +/* 09F5B8 802DFDB8 000F3C03 */ sra $a3, $t7, 0x10 +/* 09F5BC 802DFDBC 000E7880 */ sll $t7, $t6, 2 +/* 09F5C0 802DFDC0 01EE7823 */ subu $t7, $t7, $t6 +/* 09F5C4 802DFDC4 000F78C0 */ sll $t7, $t7, 3 +/* 09F5C8 802DFDC8 01EE7821 */ addu $t7, $t7, $t6 +/* 09F5CC 802DFDCC AFBF0024 */ sw $ra, 0x24($sp) +/* 09F5D0 802DFDD0 AFB0001C */ sw $s0, 0x1c($sp) +/* 09F5D4 802DFDD4 AFA50064 */ sw $a1, 0x64($sp) +/* 09F5D8 802DFDD8 AFA60068 */ sw $a2, 0x68($sp) +/* 09F5DC 802DFDDC 3C0D0200 */ lui $t5, (0x02000740 >> 16) # lui $t5, 0x200 +/* 09F5E0 802DFDE0 000F7880 */ sll $t7, $t7, 2 +/* 09F5E4 802DFDE4 35AD0740 */ ori $t5, (0x02000740 & 0xFFFF) # ori $t5, $t5, 0x740 +/* 09F5E8 802DFDE8 240E0280 */ li $t6, 640 +/* 09F5EC 802DFDEC 006FC021 */ addu $t8, $v1, $t7 +/* 09F5F0 802DFDF0 0007C880 */ sll $t9, $a3, 2 +/* 09F5F4 802DFDF4 AC8E0004 */ sw $t6, 4($a0) +/* 09F5F8 802DFDF8 AC8D0000 */ sw $t5, ($a0) +/* 09F5FC 802DFDFC 906F0004 */ lbu $t7, 4($v1) +/* 09F600 802DFE00 0327C821 */ addu $t9, $t9, $a3 +/* 09F604 802DFE04 0019C880 */ sll $t9, $t9, 2 +/* 09F608 802DFE08 03194021 */ addu $t0, $t8, $t9 +/* 09F60C 802DFE0C 24010001 */ li $at, 1 +/* 09F610 802DFE10 25080030 */ addiu $t0, $t0, 0x30 +/* 09F614 802DFE14 15E10033 */ bne $t7, $at, .L80200894 +/* 09F618 802DFE18 24900008 */ addiu $s0, $a0, 8 +/* 09F61C 802DFE1C 9506000E */ lhu $a2, 0xe($t0) +/* 09F620 802DFE20 85070010 */ lh $a3, 0x10($t0) +/* 09F624 802DFE24 AFA8005C */ sw $t0, 0x5c($sp) +/* 09F628 802DFE28 AFA30028 */ sw $v1, 0x28($sp) +/* 09F62C 802DFE2C AFB10010 */ sw $s1, 0x10($sp) +/* 09F630 802DFE30 02002025 */ move $a0, $s0 +/* 09F634 802DFE34 0C0B7E39 */ jal synthesis_load_reverb_ring_buffer +/* 09F638 802DFE38 24050740 */ li $a1, 1856 +/* 09F63C 802DFE3C 8FA8005C */ lw $t0, 0x5c($sp) +/* 09F640 802DFE40 00408025 */ move $s0, $v0 +/* 09F644 802DFE44 8FA30028 */ lw $v1, 0x28($sp) +/* 09F648 802DFE48 85070012 */ lh $a3, 0x12($t0) +/* 09F64C 802DFE4C 02002025 */ move $a0, $s0 +/* 09F650 802DFE50 00003025 */ move $a2, $zero +/* 09F654 802DFE54 50E0000A */ beql $a3, $zero, .L80200830 +/* 09F658 802DFE58 3C0A0800 */ lui $t2, 0x800 +/* 09F65C 802DFE5C 85050010 */ lh $a1, 0x10($t0) +/* 09F660 802DFE60 AFA30028 */ sw $v1, 0x28($sp) +/* 09F664 802DFE64 AFB10010 */ sw $s1, 0x10($sp) +/* 09F668 802DFE68 24A50740 */ addiu $a1, $a1, 0x740 +/* 09F66C 802DFE6C 30B8FFFF */ andi $t8, $a1, 0xffff +/* 09F670 802DFE70 0C0B7E39 */ jal synthesis_load_reverb_ring_buffer +/* 09F674 802DFE74 03002825 */ move $a1, $t8 +/* 09F678 802DFE78 8FA30028 */ lw $v1, 0x28($sp) +/* 09F67C 802DFE7C 3C0A0800 */ lui $t2, 0x800 +.L80200830: +/* 09F680 802DFE80 24500008 */ addiu $s0, $v0, 8 +/* 09F684 802DFE84 24190280 */ li $t9, 640 +/* 09F688 802DFE88 AC590004 */ sw $t9, 4($v0) +/* 09F68C 802DFE8C AC4A0000 */ sw $t2, ($v0) +/* 09F690 802DFE90 02002825 */ move $a1, $s0 +/* 09F694 802DFE94 3C0D0C00 */ lui $t5, (0x0C007FFF >> 16) # lui $t5, 0xc00 +/* 09F698 802DFE98 3C0E0740 */ lui $t6, (0x074004C0 >> 16) # lui $t6, 0x740 +/* 09F69C 802DFE9C 35CE04C0 */ ori $t6, (0x074004C0 & 0xFFFF) # ori $t6, $t6, 0x4c0 +/* 09F6A0 802DFEA0 35AD7FFF */ ori $t5, (0x0C007FFF & 0xFFFF) # ori $t5, $t5, 0x7fff +/* 09F6A4 802DFEA4 ACAD0000 */ sw $t5, ($a1) +/* 09F6A8 802DFEA8 ACAE0004 */ sw $t6, 4($a1) +/* 09F6AC 802DFEAC 946F0008 */ lhu $t7, 8($v1) +/* 09F6B0 802DFEB0 34018000 */ li $at, 32768 +/* 09F6B4 802DFEB4 26100008 */ addiu $s0, $s0, 8 +/* 09F6B8 802DFEB8 01E1C021 */ addu $t8, $t7, $at +/* 09F6BC 802DFEBC 3319FFFF */ andi $t9, $t8, 0xffff +/* 09F6C0 802DFEC0 3C010C00 */ lui $at, 0xc00 +/* 09F6C4 802DFEC4 02003025 */ move $a2, $s0 +/* 09F6C8 802DFEC8 3C0E0740 */ lui $t6, (0x07400740 >> 16) # lui $t6, 0x740 +/* 09F6CC 802DFECC 35CE0740 */ ori $t6, (0x07400740 & 0xFFFF) # ori $t6, $t6, 0x740 +/* 09F6D0 802DFED0 03216825 */ or $t5, $t9, $at +/* 09F6D4 802DFED4 ACCD0000 */ sw $t5, ($a2) +/* 09F6D8 802DFED8 ACCE0004 */ sw $t6, 4($a2) +/* 09F6DC 802DFEDC 10000078 */ b .L80200A70 +/* 09F6E0 802DFEE0 26100008 */ addiu $s0, $s0, 8 +.L80200894: +/* 09F6E4 802DFEE4 8D02000C */ lw $v0, 0xc($t0) +/* 09F6E8 802DFEE8 850D0010 */ lh $t5, 0x10($t0) +/* 09F6EC 802DFEEC 2401FFF0 */ li $at, -16 +/* 09F6F0 802DFEF0 304F0007 */ andi $t7, $v0, 7 +/* 09F6F4 802DFEF4 000FC440 */ sll $t8, $t7, 0x11 +/* 09F6F8 802DFEF8 0018CC03 */ sra $t9, $t8, 0x10 +/* 09F6FC 802DFEFC 032D5021 */ addu $t2, $t9, $t5 +/* 09F700 802DFF00 254A000F */ addiu $t2, $t2, 0xf +/* 09F704 802DFF04 03204825 */ move $t1, $t9 +/* 09F708 802DFF08 314EFFF0 */ andi $t6, $t2, 0xfff0 +/* 09F70C 802DFF0C 000E7C00 */ sll $t7, $t6, 0x10 +/* 09F710 802DFF10 000FC403 */ sra $t8, $t7, 0x10 +/* 09F714 802DFF14 03005025 */ move $t2, $t8 +/* 09F718 802DFF18 A7AA0058 */ sh $t2, 0x58($sp) +/* 09F71C 802DFF1C A7A9005A */ sh $t1, 0x5a($sp) +/* 09F720 802DFF20 AFA8005C */ sw $t0, 0x5c($sp) +/* 09F724 802DFF24 AFA30028 */ sw $v1, 0x28($sp) +/* 09F728 802DFF28 AFB10010 */ sw $s1, 0x10($sp) +/* 09F72C 802DFF2C 02002025 */ move $a0, $s0 +/* 09F730 802DFF30 24050020 */ li $a1, 32 +/* 09F734 802DFF34 05210003 */ bgez $t1, .L802008F4 +/* 09F738 802DFF38 0009C843 */ sra $t9, $t1, 1 +/* 09F73C 802DFF3C 25210001 */ addiu $at, $t1, 1 +/* 09F740 802DFF40 0001C843 */ sra $t9, $at, 1 +.L802008F4: +/* 09F744 802DFF44 00593023 */ subu $a2, $v0, $t9 +/* 09F748 802DFF48 30CDFFFF */ andi $t5, $a2, 0xffff +/* 09F74C 802DFF4C 01A03025 */ move $a2, $t5 +/* 09F750 802DFF50 0C0B7E39 */ jal synthesis_load_reverb_ring_buffer +/* 09F754 802DFF54 24070140 */ li $a3, 320 +/* 09F758 802DFF58 8FA8005C */ lw $t0, 0x5c($sp) +/* 09F75C 802DFF5C 00408025 */ move $s0, $v0 +/* 09F760 802DFF60 8FA30028 */ lw $v1, 0x28($sp) +/* 09F764 802DFF64 850E0012 */ lh $t6, 0x12($t0) +/* 09F768 802DFF68 87A9005A */ lh $t1, 0x5a($sp) +/* 09F76C 802DFF6C 87AA0058 */ lh $t2, 0x58($sp) +/* 09F770 802DFF70 11C0000D */ beqz $t6, .L80200958 +/* 09F774 802DFF74 02002025 */ move $a0, $s0 +/* 09F778 802DFF78 25450020 */ addiu $a1, $t2, 0x20 +/* 09F77C 802DFF7C 30AFFFFF */ andi $t7, $a1, 0xffff +/* 09F780 802DFF80 24180140 */ li $t8, 320 +/* 09F784 802DFF84 030A3823 */ subu $a3, $t8, $t2 +/* 09F788 802DFF88 01E02825 */ move $a1, $t7 +/* 09F78C 802DFF8C 00003025 */ move $a2, $zero +/* 09F790 802DFF90 AFB10010 */ sw $s1, 0x10($sp) +/* 09F794 802DFF94 AFA30028 */ sw $v1, 0x28($sp) +/* 09F798 802DFF98 0C0B7E39 */ jal synthesis_load_reverb_ring_buffer +/* 09F79C 802DFF9C A7A9005A */ sh $t1, 0x5a($sp) +/* 09F7A0 802DFFA0 8FA30028 */ lw $v1, 0x28($sp) +/* 09F7A4 802DFFA4 87A9005A */ lh $t1, 0x5a($sp) +.L80200958: +/* 09F7A8 802DFFA8 25390020 */ addiu $t9, $t1, 0x20 +/* 09F7AC 802DFFAC 3C0A0800 */ lui $t2, 0x800 +/* 09F7B0 802DFFB0 332DFFFF */ andi $t5, $t9, 0xffff +/* 09F7B4 802DFFB4 01AA7025 */ or $t6, $t5, $t2 +/* 09F7B8 802DFFB8 AC4E0000 */ sw $t6, ($v0) +/* 09F7BC 802DFFBC 8FA50064 */ lw $a1, 0x64($sp) +/* 09F7C0 802DFFC0 3C010740 */ lui $at, 0x740 +/* 09F7C4 802DFFC4 3C0B0500 */ lui $t3, 0x500 +/* 09F7C8 802DFFC8 00057840 */ sll $t7, $a1, 1 +/* 09F7CC 802DFFCC 31E5FFFF */ andi $a1, $t7, 0xffff +/* 09F7D0 802DFFD0 00A1C825 */ or $t9, $a1, $at +/* 09F7D4 802DFFD4 AC590004 */ sw $t9, 4($v0) +/* 09F7D8 802DFFD8 90790000 */ lbu $t9, ($v1) +/* 09F7DC 802DFFDC 946E000A */ lhu $t6, 0xa($v1) +/* 09F7E0 802DFFE0 24500008 */ addiu $s0, $v0, 8 +/* 09F7E4 802DFFE4 00196C00 */ sll $t5, $t9, 0x10 +/* 09F7E8 802DFFE8 01CB7825 */ or $t7, $t6, $t3 +/* 09F7EC 802DFFEC 01ED7025 */ or $t6, $t7, $t5 +/* 09F7F0 802DFFF0 02003025 */ move $a2, $s0 +/* 09F7F4 802DFFF4 ACCE0000 */ sw $t6, ($a2) +/* 09F7F8 802DFFF8 8C780020 */ lw $t8, 0x20($v1) +/* 09F7FC 802DFFFC 3C0C8000 */ lui $t4, 0x8000 +/* 09F800 802E0000 26100008 */ addiu $s0, $s0, 8 +/* 09F804 802E0004 252F0160 */ addiu $t7, $t1, 0x160 +/* 09F808 802E0008 030CC821 */ addu $t9, $t8, $t4 +/* 09F80C 802E000C ACD90004 */ sw $t9, 4($a2) +/* 09F810 802E0010 31EDFFFF */ andi $t5, $t7, 0xffff +/* 09F814 802E0014 02003825 */ move $a3, $s0 +/* 09F818 802E0018 3C010880 */ lui $at, 0x880 +/* 09F81C 802E001C 00A1C025 */ or $t8, $a1, $at +/* 09F820 802E0020 01AA7025 */ or $t6, $t5, $t2 +/* 09F824 802E0024 ACEE0000 */ sw $t6, ($a3) +/* 09F828 802E0028 ACF80004 */ sw $t8, 4($a3) +/* 09F82C 802E002C 90780000 */ lbu $t8, ($v1) +/* 09F830 802E0030 946F000A */ lhu $t7, 0xa($v1) +/* 09F834 802E0034 26100008 */ addiu $s0, $s0, 8 +/* 09F838 802E0038 0018CC00 */ sll $t9, $t8, 0x10 +/* 09F83C 802E003C 01EB6825 */ or $t5, $t7, $t3 +/* 09F840 802E0040 01B97825 */ or $t7, $t5, $t9 +/* 09F844 802E0044 02004025 */ move $t0, $s0 +/* 09F848 802E0048 AD0F0000 */ sw $t7, ($t0) +/* 09F84C 802E004C 8C6E0024 */ lw $t6, 0x24($v1) +/* 09F850 802E0050 26100008 */ addiu $s0, $s0, 8 +/* 09F854 802E0054 02001025 */ move $v0, $s0 +/* 09F858 802E0058 01CCC021 */ addu $t8, $t6, $t4 +/* 09F85C 802E005C AD180004 */ sw $t8, 4($t0) +/* 09F860 802E0060 26100008 */ addiu $s0, $s0, 8 +/* 09F864 802E0064 240D0280 */ li $t5, 640 +/* 09F868 802E0068 AC4D0004 */ sw $t5, 4($v0) +/* 09F86C 802E006C AC4A0000 */ sw $t2, ($v0) +/* 09F870 802E0070 02002025 */ move $a0, $s0 +/* 09F874 802E0074 3C0F0740 */ lui $t7, (0x074004C0 >> 16) # lui $t7, 0x740 +/* 09F878 802E0078 3C190C00 */ lui $t9, (0x0C007FFF >> 16) # lui $t9, 0xc00 +/* 09F87C 802E007C 37397FFF */ ori $t9, (0x0C007FFF & 0xFFFF) # ori $t9, $t9, 0x7fff +/* 09F880 802E0080 35EF04C0 */ ori $t7, (0x074004C0 & 0xFFFF) # ori $t7, $t7, 0x4c0 +/* 09F884 802E0084 AC8F0004 */ sw $t7, 4($a0) +/* 09F888 802E0088 AC990000 */ sw $t9, ($a0) +/* 09F88C 802E008C 946E0008 */ lhu $t6, 8($v1) +/* 09F890 802E0090 34018000 */ li $at, 32768 +/* 09F894 802E0094 26100008 */ addiu $s0, $s0, 8 +/* 09F898 802E0098 01C1C021 */ addu $t8, $t6, $at +/* 09F89C 802E009C 02002825 */ move $a1, $s0 +/* 09F8A0 802E00A0 330DFFFF */ andi $t5, $t8, 0xffff +/* 09F8A4 802E00A4 3C010C00 */ lui $at, 0xc00 +/* 09F8A8 802E00A8 3C0F0740 */ lui $t7, (0x07400740 >> 16) # lui $t7, 0x740 +/* 09F8AC 802E00AC 35EF0740 */ ori $t7, (0x07400740 & 0xFFFF) # ori $t7, $t7, 0x740 +/* 09F8B0 802E00B0 01A1C825 */ or $t9, $t5, $at +/* 09F8B4 802E00B4 ACB90000 */ sw $t9, ($a1) +/* 09F8B8 802E00B8 ACAF0004 */ sw $t7, 4($a1) +/* 09F8BC 802E00BC 26100008 */ addiu $s0, $s0, 8 +.L80200A70: +/* 09F8C0 802E00C0 8FBF0024 */ lw $ra, 0x24($sp) +/* 09F8C4 802E00C4 02001025 */ move $v0, $s0 +/* 09F8C8 802E00C8 8FB0001C */ lw $s0, 0x1c($sp) +/* 09F8CC 802E00CC 8FB10020 */ lw $s1, 0x20($sp) +/* 09F8D0 802E00D0 03E00008 */ jr $ra +/* 09F8D4 802E00D4 27BD0060 */ addiu $sp, $sp, 0x60 diff --git a/asm/non_matchings/handle_dialog_text_and_pages_eu.s b/asm/non_matchings/eu/handle_dialog_text_and_pages.s similarity index 99% rename from asm/non_matchings/handle_dialog_text_and_pages_eu.s rename to asm/non_matchings/eu/handle_dialog_text_and_pages.s index 9efe447..1e15402 100644 --- a/asm/non_matchings/handle_dialog_text_and_pages_eu.s +++ b/asm/non_matchings/eu/handle_dialog_text_and_pages.s @@ -1,35 +1,35 @@ .late_rodata .late_rodata_alignment 8 glabel jtbl_803059A0 -.word L_EU_802AFB00, L_EU_802AFB18, L_EU_802AFB50, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFB88, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFB9C, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AF99C, L_EU_802AF990 +.word L_EU_802AFB00, L_EU_802AFB18, L_EU_802AFB50, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFB88, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFB9C, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AF99C, L_EU_802AF990 glabel jtbl_80305A60 -.word L_EU_802AF9CC, L_EU_802AF9CC, L_EU_802AF9CC, L_EU_802AFBD0 -.word L_EU_802AF9EC, L_EU_802AF9EC, L_EU_802AF9EC, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFA0C, L_EU_802AFA0C, L_EU_802AFA0C, L_EU_802AFA0C -.word L_EU_802AFA2C, L_EU_802AFA2C, L_EU_802AFA2C, L_EU_802AFA2C -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFA4C, L_EU_802AFA4C, L_EU_802AFA4C, L_EU_802AFBD0 -.word L_EU_802AFA6C, L_EU_802AFA6C, L_EU_802AFA6C, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFA8C, L_EU_802AFA8C, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFAAC, L_EU_802AFAAC, L_EU_802AFBD0 -.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AF9CC, L_EU_802AF9CC, L_EU_802AF9CC, L_EU_802AFBD0 +.word L_EU_802AF9EC, L_EU_802AF9EC, L_EU_802AF9EC, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFA0C, L_EU_802AFA0C, L_EU_802AFA0C, L_EU_802AFA0C +.word L_EU_802AFA2C, L_EU_802AFA2C, L_EU_802AFA2C, L_EU_802AFA2C +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFA4C, L_EU_802AFA4C, L_EU_802AFA4C, L_EU_802AFBD0 +.word L_EU_802AFA6C, L_EU_802AFA6C, L_EU_802AFA6C, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFA8C, L_EU_802AFA8C, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFAAC, L_EU_802AFAAC, L_EU_802AFBD0 +.word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFBD0 .word L_EU_802AFBD0, L_EU_802AFBD0, L_EU_802AFAEC, L_EU_802AFBD0 .word L_EU_802AFBD0, L_EU_802AFACC, L_EU_802AFACC @@ -127,7 +127,7 @@ glabel handle_dialog_text_and_pages # EU: func_802AF808 /* 06F15C 802AF95C 002E0821 */ addu $at, $at, $t6 /* 06F160 802AF960 8C2E59A0 */ lw $t6, %lo(jtbl_803059A0)($at) # 0x59a0($at) /* 06F164 802AF964 01C00008 */ jr $t6 -/* 06F168 802AF968 00000000 */ nop +/* 06F168 802AF968 00000000 */ nop .L802AF96C: /* 06F16C 802AF96C 244FFFA0 */ addiu $t7, $v0, -0x60 /* 06F170 802AF970 2DE10043 */ sltiu $at, $t7, 0x43 @@ -137,7 +137,7 @@ glabel handle_dialog_text_and_pages # EU: func_802AF808 /* 06F180 802AF980 002F0821 */ addu $at, $at, $t7 /* 06F184 802AF984 8C2F5A60 */ lw $t7, %lo(jtbl_80305A60)($at) # 0x5a60($at) /* 06F188 802AF988 01E00008 */ jr $t7 -/* 06F18C 802AF98C 00000000 */ nop +/* 06F18C 802AF98C 00000000 */ nop glabel L_EU_802AF990 /* 06F190 802AF990 24180002 */ li $t8, 2 /* 06F194 802AF994 1000009D */ b .L802AFC0C diff --git a/asm/non_matchings/eu/libultra_unk_802aeeb0.s b/asm/non_matchings/eu/libultra_unk_802aeeb0.s new file mode 100644 index 0000000..825fbb5 --- /dev/null +++ b/asm/non_matchings/eu/libultra_unk_802aeeb0.s @@ -0,0 +1,55 @@ + +glabel func_802aeeb0 +/* 0AEEB0 80200000 27BDFFE0 */ addiu $sp, $sp, -0x20 +/* 0AEEB4 80200004 AFBF0014 */ sw $ra, 0x14($sp) +/* 0AEEB8 80200008 0C0BD400 */ jal __osDisableInt +/* 0AEEBC 8020000C AFA40020 */ sw $a0, 0x20($sp) +/* 0AEEC0 80200010 3C0F8030 */ lui $t7, %hi(D_80334914) # $t7, 0x8030 +/* 0AEEC4 80200014 8DEF2EE4 */ lw $t7, %lo(D_80334914)($t7) +/* 0AEEC8 80200018 8FAE0020 */ lw $t6, 0x20($sp) +/* 0AEECC 8020001C AFA2001C */ sw $v0, 0x1c($sp) +/* 0AEED0 80200020 3C188030 */ lui $t8, %hi(D_80334914) # $t8, 0x8030 +/* 0AEED4 80200024 ADEE0004 */ sw $t6, 4($t7) +/* 0AEED8 80200028 8F182EE4 */ lw $t8, %lo(D_80334914)($t8) +/* 0AEEDC 8020002C 97190000 */ lhu $t9, ($t8) +/* 0AEEE0 80200030 37280010 */ ori $t0, $t9, 0x10 +/* 0AEEE4 80200034 A7080000 */ sh $t0, ($t8) +/* 0AEEE8 80200038 0C0BD408 */ jal __osRestoreInt +/* 0AEEEC 8020003C 8FA4001C */ lw $a0, 0x1c($sp) +/* 0AEEF0 80200040 8FBF0014 */ lw $ra, 0x14($sp) +/* 0AEEF4 80200044 27BD0020 */ addiu $sp, $sp, 0x20 +/* 0AEEF8 80200048 03E00008 */ jr $ra +/* 0AEEFC 8020004C 00000000 */ nop + +glabel func_802aef00 +/* 0AEF00 80200050 3C028030 */ lui $v0, %hi(D_8033489C) +/* 0AEF04 80200054 03E00008 */ jr $ra +/* 0AEF08 80200058 8C422EFC */ lw $v0, %lo(D_8033489C)($v0) + +glabel func_802aef0c +/* 0AEF0C 8020005C 00000000 */ nop +/* 0AEF10 80200060 27BDFFD8 */ addiu $sp, $sp, -0x28 +/* 0AEF14 80200064 AFBF001C */ sw $ra, 0x1c($sp) +/* 0AEF18 80200068 AFA40028 */ sw $a0, 0x28($sp) +/* 0AEF1C 8020006C AFA5002C */ sw $a1, 0x2c($sp) +/* 0AEF20 80200070 AFA60030 */ sw $a2, 0x30($sp) +/* 0AEF24 80200074 0C0BD400 */ jal __osDisableInt +/* 0AEF28 80200078 AFB00018 */ sw $s0, 0x18($sp) +/* 0AEF2C 8020007C 8FAE0028 */ lw $t6, 0x28($sp) +/* 0AEF30 80200080 3C188033 */ lui $t8, %hi(D_80363830) # $t8, 0x8033 +/* 0AEF34 80200084 8FA8002C */ lw $t0, 0x2c($sp) +/* 0AEF38 80200088 271836D0 */ addiu $t8, %lo(D_80363830) # addiu $t8, $t8, 0x36d0 +/* 0AEF3C 8020008C 000E78C0 */ sll $t7, $t6, 3 +/* 0AEF40 80200090 01F8C821 */ addu $t9, $t7, $t8 +/* 0AEF44 80200094 AFB90020 */ sw $t9, 0x20($sp) +/* 0AEF48 80200098 AF280000 */ sw $t0, ($t9) +/* 0AEF4C 8020009C 8FAA0020 */ lw $t2, 0x20($sp) +/* 0AEF50 802000A0 8FA90030 */ lw $t1, 0x30($sp) +/* 0AEF54 802000A4 00408025 */ move $s0, $v0 +/* 0AEF58 802000A8 02002025 */ move $a0, $s0 +/* 0AEF5C 802000AC 0C0BD408 */ jal __osRestoreInt +/* 0AEF60 802000B0 AD490004 */ sw $t1, 4($t2) +/* 0AEF64 802000B4 8FBF001C */ lw $ra, 0x1c($sp) +/* 0AEF68 802000B8 8FB00018 */ lw $s0, 0x18($sp) +/* 0AEF6C 802000BC 27BD0028 */ addiu $sp, $sp, 0x28 +/* 0AEF70 802000C0 03E00008 */ jr $ra diff --git a/asm/non_matchings/eu/libultra_unk_802aef80.s b/asm/non_matchings/eu/libultra_unk_802aef80.s new file mode 100644 index 0000000..5d7aa55 --- /dev/null +++ b/asm/non_matchings/eu/libultra_unk_802aef80.s @@ -0,0 +1,87 @@ +glabel func_802aef80 +/* 0AEF80 80200000 27BDFFD8 */ addiu $sp, $sp, -0x28 +/* 0AEF84 80200004 AFBF001C */ sw $ra, 0x1c($sp) +/* 0AEF88 80200008 AFA40028 */ sw $a0, 0x28($sp) +/* 0AEF8C 8020000C AFA5002C */ sw $a1, 0x2c($sp) +/* 0AEF90 80200010 AFA60030 */ sw $a2, 0x30($sp) +/* 0AEF94 80200014 AFB10018 */ sw $s1, 0x18($sp) +/* 0AEF98 80200018 0C0BD400 */ jal __osDisableInt +/* 0AEF9C 8020001C AFB00014 */ sw $s0, 0x14($sp) +/* 0AEFA0 80200020 8FAE0028 */ lw $t6, 0x28($sp) +/* 0AEFA4 80200024 00408025 */ move $s0, $v0 +/* 0AEFA8 80200028 8DCF0008 */ lw $t7, 8($t6) +/* 0AEFAC 8020002C 15E00012 */ bnez $t7, .L80200078 +/* 0AEFB0 80200030 00000000 */ nop +.L80200034: +/* 0AEFB4 80200034 8FB80030 */ lw $t8, 0x30($sp) +/* 0AEFB8 80200038 17000005 */ bnez $t8, .L80200050 +/* 0AEFBC 8020003C 00000000 */ nop +/* 0AEFC0 80200040 0C0BD408 */ jal __osRestoreInt +/* 0AEFC4 80200044 02002025 */ move $a0, $s0 +/* 0AEFC8 80200048 10000036 */ b .L80200124 +/* 0AEFCC 8020004C 2402FFFF */ li $v0, -1 +.L80200050: +/* 0AEFD0 80200050 3C088030 */ lui $t0, %hi(D_803348A0) # $t0, 0x8030 +/* 0AEFD4 80200054 8D082F00 */ lw $t0, %lo(D_803348A0)($t0) +/* 0AEFD8 80200058 24190008 */ li $t9, 8 +/* 0AEFDC 8020005C A5190010 */ sh $t9, 0x10($t0) +/* 0AEFE0 80200060 0C0BCFC3 */ jal __osEnqueueAndYield +/* 0AEFE4 80200064 8FA40028 */ lw $a0, 0x28($sp) +/* 0AEFE8 80200068 8FA90028 */ lw $t1, 0x28($sp) +/* 0AEFEC 8020006C 8D2A0008 */ lw $t2, 8($t1) +/* 0AEFF0 80200070 1140FFF0 */ beqz $t2, .L80200034 +/* 0AEFF4 80200074 00000000 */ nop +.L80200078: +/* 0AEFF8 80200078 8FAB002C */ lw $t3, 0x2c($sp) +/* 0AEFFC 8020007C 11600008 */ beqz $t3, .L802000A0 +/* 0AF000 80200080 00000000 */ nop +/* 0AF004 80200084 8FAC0028 */ lw $t4, 0x28($sp) +/* 0AF008 80200088 8D8E000C */ lw $t6, 0xc($t4) +/* 0AF00C 8020008C 8D8D0014 */ lw $t5, 0x14($t4) +/* 0AF010 80200090 000E7880 */ sll $t7, $t6, 2 +/* 0AF014 80200094 01AFC021 */ addu $t8, $t5, $t7 +/* 0AF018 80200098 8F190000 */ lw $t9, ($t8) +/* 0AF01C 8020009C AD790000 */ sw $t9, ($t3) +.L802000A0: +/* 0AF020 802000A0 8FA80028 */ lw $t0, 0x28($sp) +/* 0AF024 802000A4 8D09000C */ lw $t1, 0xc($t0) +/* 0AF028 802000A8 8D0C0010 */ lw $t4, 0x10($t0) +/* 0AF02C 802000AC 252A0001 */ addiu $t2, $t1, 1 +/* 0AF030 802000B0 014C001A */ div $zero, $t2, $t4 +/* 0AF034 802000B4 00007010 */ mfhi $t6 +/* 0AF038 802000B8 AD0E000C */ sw $t6, 0xc($t0) +/* 0AF03C 802000BC 8FAD0028 */ lw $t5, 0x28($sp) +/* 0AF040 802000C0 15800002 */ bnez $t4, .L802000CC +/* 0AF044 802000C4 00000000 */ nop +/* 0AF048 802000C8 0007000D */ break 7 +.L802000CC: +/* 0AF04C 802000CC 2401FFFF */ li $at, -1 +/* 0AF050 802000D0 15810004 */ bne $t4, $at, .L802000E4 +/* 0AF054 802000D4 3C018000 */ lui $at, 0x8000 +/* 0AF058 802000D8 15410002 */ bne $t2, $at, .L802000E4 +/* 0AF05C 802000DC 00000000 */ nop +/* 0AF060 802000E0 0006000D */ break 6 +.L802000E4: +/* 0AF064 802000E4 8DAF0008 */ lw $t7, 8($t5) +/* 0AF068 802000E8 25F8FFFF */ addiu $t8, $t7, -1 +/* 0AF06C 802000EC ADB80008 */ sw $t8, 8($t5) +/* 0AF070 802000F0 8FB90028 */ lw $t9, 0x28($sp) +/* 0AF074 802000F4 8F2B0004 */ lw $t3, 4($t9) +/* 0AF078 802000F8 8D690000 */ lw $t1, ($t3) +/* 0AF07C 802000FC 11200006 */ beqz $t1, .L80200118 +/* 0AF080 80200100 00000000 */ nop +/* 0AF084 80200104 0C0BD015 */ jal __osPopThread +/* 0AF088 80200108 27240004 */ addiu $a0, $t9, 4 +/* 0AF08C 8020010C 00408825 */ move $s1, $v0 +/* 0AF090 80200110 0C0BBEA0 */ jal osStartThread +/* 0AF094 80200114 02202025 */ move $a0, $s1 +.L80200118: +/* 0AF098 80200118 0C0BD408 */ jal __osRestoreInt +/* 0AF09C 8020011C 02002025 */ move $a0, $s0 +/* 0AF0A0 80200120 00001025 */ move $v0, $zero +.L80200124: +/* 0AF0A4 80200124 8FBF001C */ lw $ra, 0x1c($sp) +/* 0AF0A8 80200128 8FB00014 */ lw $s0, 0x14($sp) +/* 0AF0AC 8020012C 8FB10018 */ lw $s1, 0x18($sp) +/* 0AF0B0 80200130 03E00008 */ jr $ra +/* 0AF0B4 80200134 27BD0028 */ addiu $sp, $sp, 0x28 diff --git a/asm/non_matchings/eu/play_sequence.s b/asm/non_matchings/eu/play_sequence.s new file mode 100644 index 0000000..e806d0f --- /dev/null +++ b/asm/non_matchings/eu/play_sequence.s @@ -0,0 +1,86 @@ +glabel play_sequence +/* 0AB0E8 80200000 27BDFFD0 */ addiu $sp, $sp, -0x30 +/* 0AB0EC 80200004 AFA50034 */ sw $a1, 0x34($sp) +/* 0AB0F0 80200008 308700FF */ andi $a3, $a0, 0xff +/* 0AB0F4 8020000C 30AE00FF */ andi $t6, $a1, 0xff +/* 0AB0F8 80200010 01C02825 */ move $a1, $t6 +/* 0AB0FC 80200014 AFBF0014 */ sw $ra, 0x14($sp) +/* 0AB100 80200018 AFA40030 */ sw $a0, 0x30($sp) +/* 0AB104 8020001C AFA60038 */ sw $a2, 0x38($sp) +/* 0AB108 80200020 14E0000C */ bnez $a3, .L480200054 +/* 0AB10C 80200024 00E04025 */ move $t0, $a3 +/* 0AB110 80200028 31CF007F */ andi $t7, $t6, 0x7f +/* 0AB114 8020002C 3C018030 */ lui $at, %hi(sPlayer0CurSeqId) # $at, 0x8030 +/* 0AB118 80200030 A02F04CC */ sb $t7, %lo(sPlayer0CurSeqId)($at) +/* 0AB11C 80200034 240200FF */ li $v0, 255 +/* 0AB120 80200038 3C018030 */ lui $at, %hi(sBackgroundMusicForDynamics) # $at, 0x8030 +/* 0AB124 8020003C A02202E0 */ sb $v0, %lo(sBackgroundMusicForDynamics)($at) +/* 0AB128 80200040 3C018030 */ lui $at, %hi(sCurrentMusicDynamic) # $at, 0x8030 +/* 0AB12C 80200044 A02202DC */ sb $v0, %lo(sCurrentMusicDynamic)($at) +/* 0AB130 80200048 3C018030 */ lui $at, %hi(sMusicDynamicDelay) # $at, 0x8030 +/* 0AB134 8020004C 24180002 */ li $t8, 2 +/* 0AB138 80200050 A03804D0 */ sb $t8, %lo(sMusicDynamicDelay)($at) +.L480200054: +/* 0AB13C 80200054 3C0A8033 */ lui $t2, %hi(D_80360928) # $t2, 0x8033 +/* 0AB140 80200058 254AFF40 */ addiu $t2, %lo(D_80360928) # addiu $t2, $t2, -0xc0 +/* 0AB144 8020005C 0007CA00 */ sll $t9, $a3, 8 +/* 0AB148 80200060 032A1821 */ addu $v1, $t9, $t2 +/* 0AB14C 80200064 00001025 */ move $v0, $zero +/* 0AB150 80200068 00A03025 */ move $a2, $a1 +/* 0AB154 8020006C 30A9007F */ andi $t1, $a1, 0x7f +.L480200070: +/* 0AB158 80200070 00025900 */ sll $t3, $v0, 4 +/* 0AB15C 80200074 24420001 */ addiu $v0, $v0, 1 +/* 0AB160 80200078 304D00FF */ andi $t5, $v0, 0xff +/* 0AB164 8020007C 29A10010 */ slti $at, $t5, 0x10 +/* 0AB168 80200080 006B6021 */ addu $t4, $v1, $t3 +/* 0AB16C 80200084 01A01025 */ move $v0, $t5 +/* 0AB170 80200088 1420FFF9 */ bnez $at, .L480200070 +/* 0AB174 8020008C A580000C */ sh $zero, 0xc($t4) +/* 0AB178 80200090 30E200FF */ andi $v0, $a3, 0xff +/* 0AB17C 80200094 00027400 */ sll $t6, $v0, 0x10 +/* 0AB180 80200098 30C50080 */ andi $a1, $a2, 0x80 +/* 0AB184 8020009C 00057E00 */ sll $t7, $a1, 0x18 +/* 0AB188 802000A0 3C014600 */ lui $at, 0x4600 +/* 0AB18C 802000A4 01C12025 */ or $a0, $t6, $at +/* 0AB190 802000A8 000F2E03 */ sra $a1, $t7, 0x18 +/* 0AB194 802000AC 01C01025 */ move $v0, $t6 +/* 0AB198 802000B0 AFAE001C */ sw $t6, 0x1c($sp) +/* 0AB19C 802000B4 AFA80028 */ sw $t0, 0x28($sp) +/* 0AB1A0 802000B8 0C0BB7DC */ jal func_802ad770 +/* 0AB1A4 802000BC AFA90020 */ sw $t1, 0x20($sp) +/* 0AB1A8 802000C0 8FA90020 */ lw $t1, 0x20($sp) +/* 0AB1AC 802000C4 8FA2001C */ lw $v0, 0x1c($sp) +/* 0AB1B0 802000C8 3C018200 */ lui $at, 0x8200 +/* 0AB1B4 802000CC 312A00FF */ andi $t2, $t1, 0xff +/* 0AB1B8 802000D0 000A5A00 */ sll $t3, $t2, 8 +/* 0AB1BC 802000D4 0041C825 */ or $t9, $v0, $at +/* 0AB1C0 802000D8 032B2025 */ or $a0, $t9, $t3 +/* 0AB1C4 802000DC 0C0BB7D3 */ jal func_802ad74c +/* 0AB1C8 802000E0 97A5003A */ lhu $a1, 0x3a($sp) +/* 0AB1CC 802000E4 8FA80028 */ lw $t0, 0x28($sp) +/* 0AB1D0 802000E8 55000013 */ bnezl $t0, .L480200138 +/* 0AB1D4 802000EC 8FBF0014 */ lw $ra, 0x14($sp) +/* 0AB1D8 802000F0 0C0BB0F2 */ jal func_803200E4 +/* 0AB1DC 802000F4 00002025 */ move $a0, $zero +/* 0AB1E0 802000F8 240100FF */ li $at, 255 +/* 0AB1E4 802000FC 5041000E */ beql $v0, $at, .L480200138 +/* 0AB1E8 80200100 8FBF0014 */ lw $ra, 0x14($sp) +/* 0AB1EC 80200104 44822000 */ mtc1 $v0, $f4 +/* 0AB1F0 80200108 3C014F80 */ li $at, 0x4F800000 # 4294967296.000000 +/* 0AB1F4 8020010C 04410004 */ bgez $v0, .L480200120 +/* 0AB1F8 80200110 468021A0 */ cvt.s.w $f6, $f4 +/* 0AB1FC 80200114 44814000 */ mtc1 $at, $f8 +/* 0AB200 80200118 00000000 */ nop +/* 0AB204 8020011C 46083180 */ add.s $f6, $f6, $f8 +.L480200120: +/* 0AB208 80200120 3C0142FE */ li $at, 0x42FE0000 # 127.000000 +/* 0AB20C 80200124 44815000 */ mtc1 $at, $f10 +/* 0AB210 80200128 3C018022 */ lui $at, %hi(gSequencePlayers + 0x28) # $at, 0x8022 +/* 0AB214 8020012C 460A3403 */ div.s $f16, $f6, $f10 +/* 0AB218 80200130 E4303D90 */ swc1 $f16, %lo(gSequencePlayers + 0x28)($at) +/* 0AB21C 80200134 8FBF0014 */ lw $ra, 0x14($sp) +.L480200138: +/* 0AB220 80200138 27BD0030 */ addiu $sp, $sp, 0x30 +/* 0AB224 8020013C 03E00008 */ jr $ra +/* 0AB228 80200140 00000000 */ nop diff --git a/asm/non_matchings/eu/player_performed_grab_escape_action.s b/asm/non_matchings/eu/player_performed_grab_escape_action.s new file mode 100644 index 0000000..ce1c054 --- /dev/null +++ b/asm/non_matchings/eu/player_performed_grab_escape_action.s @@ -0,0 +1,36 @@ +glabel player_performed_grab_escape_action +/* 0D8190 80200000 3C028030 */ lui $v0, %hi(gPlayer1Controller) # $v0, 0x8030 +/* 0D8194 80200004 8C429794 */ lw $v0, %lo(gPlayer1Controller)($v0) +/* 0D8198 80200008 3C0141F0 */ li $at, 0x41F00000 # 30.000000 +/* 0D819C 8020000C 44812000 */ mtc1 $at, $f4 +/* 0D81A0 80200010 C440000C */ lwc1 $f0, 0xc($v0) +/* 0D81A4 80200014 00001825 */ move $v1, $zero +/* 0D81A8 80200018 3C018039 */ lui $at, %hi(sGrabReleaseState) # $at, 0x8039 +/* 0D81AC 8020001C 4604003C */ c.lt.s $f0, $f4 +/* 0D81B0 80200020 3C0E8039 */ lui $t6, %hi(sGrabReleaseState) # $t6, 0x8039 +/* 0D81B4 80200024 45000002 */ bc1f .L81_80200030 +/* 0D81B8 80200028 00000000 */ nop +/* 0D81BC 8020002C AC209C70 */ sw $zero, %lo(sGrabReleaseState)($at) +.L81_80200030: +/* 0D81C0 80200030 8DCE9C70 */ lw $t6, %lo(sGrabReleaseState)($t6) +/* 0D81C4 80200034 3C014220 */ li $at, 0x42200000 # 40.000000 +/* 0D81C8 80200038 55C0000B */ bnezl $t6, .L81_80200068 +/* 0D81CC 8020003C 94580012 */ lhu $t8, 0x12($v0) +/* 0D81D0 80200040 44813000 */ mtc1 $at, $f6 +/* 0D81D4 80200044 3C018039 */ lui $at, %hi(sGrabReleaseState) # $at, 0x8039 +/* 0D81D8 80200048 240F0001 */ li $t7, 1 +/* 0D81DC 8020004C 4600303C */ c.lt.s $f6, $f0 +/* 0D81E0 80200050 00000000 */ nop +/* 0D81E4 80200054 45020004 */ bc1fl .L81_80200068 +/* 0D81E8 80200058 94580012 */ lhu $t8, 0x12($v0) +/* 0D81EC 8020005C AC2F9C70 */ sw $t7, %lo(sGrabReleaseState)($at) +/* 0D81F0 80200060 24030001 */ li $v1, 1 +/* 0D81F4 80200064 94580012 */ lhu $t8, 0x12($v0) +.L81_80200068: +/* 0D81F8 80200068 33198000 */ andi $t9, $t8, 0x8000 +/* 0D81FC 8020006C 13200002 */ beqz $t9, .L81_80200078 +/* 0D8200 80200070 00000000 */ nop +/* 0D8204 80200074 24030001 */ li $v1, 1 +.L81_80200078: +/* 0D8208 80200078 03E00008 */ jr $ra +/* 0D820C 8020007C 00601025 */ move $v0, $v1 diff --git a/asm/non_matchings/patch_audio_bank.s b/asm/non_matchings/patch_audio_bank.s deleted file mode 100644 index 87850f1..0000000 --- a/asm/non_matchings/patch_audio_bank.s +++ /dev/null @@ -1,156 +0,0 @@ -glabel patch_audio_bank -/* 0D284C 8031784C 27ADFFF0 */ addiu $t5, $sp, -0x10 -/* 0D2850 80317850 ADA60018 */ sw $a2, 0x18($t5) -/* 0D2854 80317854 8C820000 */ lw $v0, ($a0) -/* 0D2858 80317858 01A0E825 */ move $sp, $t5 -/* 0D285C 8031785C 50400030 */ beql $v0, $zero, .L80317920 -/* 0D2860 80317860 8DB80018 */ lw $t8, 0x18($t5) -/* 0D2864 80317864 10E0002D */ beqz $a3, .L8031791C -/* 0D2868 80317868 00447021 */ addu $t6, $v0, $a0 -/* 0D286C 8031786C 10E0002B */ beqz $a3, .L8031791C -/* 0D2870 80317870 AC8E0000 */ sw $t6, ($a0) -/* 0D2874 80317874 10E00029 */ beqz $a3, .L8031791C -/* 0D2878 80317878 00001825 */ move $v1, $zero -/* 0D287C 8031787C 00004025 */ move $t0, $zero -/* 0D2880 80317880 24020001 */ li $v0, 1 -.L80317884: -/* 0D2884 80317884 8C8F0000 */ lw $t7, ($a0) -/* 0D2888 80317888 24630001 */ addiu $v1, $v1, 1 -/* 0D288C 8031788C 01E84821 */ addu $t1, $t7, $t0 -/* 0D2890 80317890 8D260000 */ lw $a2, ($t1) -/* 0D2894 80317894 10C0001F */ beqz $a2, .L80317914 -/* 0D2898 80317898 00C43021 */ addu $a2, $a2, $a0 -/* 0D289C 8031789C AD260000 */ sw $a2, ($t1) -/* 0D28A0 803178A0 90D80002 */ lbu $t8, 2($a2) -/* 0D28A4 803178A4 00C05025 */ move $t2, $a2 -/* 0D28A8 803178A8 1700001A */ bnez $t8, .L80317914 -/* 0D28AC 803178AC 00000000 */ nop -/* 0D28B0 803178B0 8CD90004 */ lw $t9, 4($a2) -/* 0D28B4 803178B4 24C90004 */ addiu $t1, $a2, 4 -/* 0D28B8 803178B8 53200013 */ beql $t9, $zero, .L80317908 -/* 0D28BC 803178BC 8CC6000C */ lw $a2, 0xc($a2) -/* 0D28C0 803178C0 8D2E0000 */ lw $t6, ($t1) -/* 0D28C4 803178C4 01C45821 */ addu $t3, $t6, $a0 -/* 0D28C8 803178C8 AD2B0000 */ sw $t3, ($t1) -/* 0D28CC 803178CC 916F0001 */ lbu $t7, 1($t3) -/* 0D28D0 803178D0 01606025 */ move $t4, $t3 -/* 0D28D4 803178D4 55E0000C */ bnezl $t7, .L80317908 -/* 0D28D8 803178D8 8CC6000C */ lw $a2, 0xc($a2) -/* 0D28DC 803178DC 8D780004 */ lw $t8, 4($t3) -/* 0D28E0 803178E0 8D990008 */ lw $t9, 8($t4) -/* 0D28E4 803178E4 8D8E000C */ lw $t6, 0xc($t4) -/* 0D28E8 803178E8 03055821 */ addu $t3, $t8, $a1 -/* 0D28EC 803178EC AD8B0004 */ sw $t3, 4($t4) -/* 0D28F0 803178F0 03245821 */ addu $t3, $t9, $a0 -/* 0D28F4 803178F4 AD8B0008 */ sw $t3, 8($t4) -/* 0D28F8 803178F8 01C45821 */ addu $t3, $t6, $a0 -/* 0D28FC 803178FC AD8B000C */ sw $t3, 0xc($t4) -/* 0D2900 80317900 A1820001 */ sb $v0, 1($t4) -/* 0D2904 80317904 8CC6000C */ lw $a2, 0xc($a2) -.L80317908: -/* 0D2908 80317908 A1420002 */ sb $v0, 2($t2) -/* 0D290C 8031790C 00867821 */ addu $t7, $a0, $a2 -/* 0D2910 80317910 AD4F000C */ sw $t7, 0xc($t2) -.L80317914: -/* 0D2914 80317914 1467FFDB */ bne $v1, $a3, .L80317884 -/* 0D2918 80317918 25080004 */ addiu $t0, $t0, 4 -.L8031791C: -/* 0D291C 8031791C 8DB80018 */ lw $t8, 0x18($t5) -.L80317920: -/* 0D2920 80317920 24020001 */ li $v0, 1 -/* 0D2924 80317924 2F190001 */ sltiu $t9, $t8, 1 -/* 0D2928 80317928 3B390001 */ xori $t9, $t9, 1 -/* 0D292C 8031792C 13200054 */ beqz $t9, .L80317A80 -/* 0D2930 80317930 00000000 */ nop -/* 0D2934 80317934 13200052 */ beqz $t9, .L80317A80 -/* 0D2938 80317938 24830004 */ addiu $v1, $a0, 4 -/* 0D293C 8031793C 00187080 */ sll $t6, $t8, 2 -/* 0D2940 80317940 01C45021 */ addu $t2, $t6, $a0 -/* 0D2944 80317944 254A0004 */ addiu $t2, $t2, 4 -/* 0D2948 80317948 8C660000 */ lw $a2, ($v1) -.L8031794C: -/* 0D294C 8031794C 10C00049 */ beqz $a2, .L80317A74 -/* 0D2950 80317950 00C47821 */ addu $t7, $a2, $a0 -/* 0D2954 80317954 AC6F0000 */ sw $t7, ($v1) -/* 0D2958 80317958 91F90000 */ lbu $t9, ($t7) -/* 0D295C 8031795C 01E03825 */ move $a3, $t7 -/* 0D2960 80317960 57200045 */ bnezl $t9, .L80317A78 -/* 0D2964 80317964 24630004 */ addiu $v1, $v1, 4 -/* 0D2968 80317968 8DF80008 */ lw $t8, 8($t7) -/* 0D296C 8031796C 25E60008 */ addiu $a2, $t7, 8 -/* 0D2970 80317970 53000013 */ beql $t8, $zero, .L803179C0 -/* 0D2974 80317974 8CEF0010 */ lw $t7, 0x10($a3) -/* 0D2978 80317978 8CCE0000 */ lw $t6, ($a2) -/* 0D297C 8031797C 01C44021 */ addu $t0, $t6, $a0 -/* 0D2980 80317980 ACC80000 */ sw $t0, ($a2) -/* 0D2984 80317984 910F0001 */ lbu $t7, 1($t0) -/* 0D2988 80317988 01004825 */ move $t1, $t0 -/* 0D298C 8031798C 55E0000C */ bnezl $t7, .L803179C0 -/* 0D2990 80317990 8CEF0010 */ lw $t7, 0x10($a3) -/* 0D2994 80317994 8D190004 */ lw $t9, 4($t0) -/* 0D2998 80317998 8D380008 */ lw $t8, 8($t1) -/* 0D299C 8031799C 8D2E000C */ lw $t6, 0xc($t1) -/* 0D29A0 803179A0 03254021 */ addu $t0, $t9, $a1 -/* 0D29A4 803179A4 AD280004 */ sw $t0, 4($t1) -/* 0D29A8 803179A8 03044021 */ addu $t0, $t8, $a0 -/* 0D29AC 803179AC AD280008 */ sw $t0, 8($t1) -/* 0D29B0 803179B0 01C44021 */ addu $t0, $t6, $a0 -/* 0D29B4 803179B4 AD28000C */ sw $t0, 0xc($t1) -/* 0D29B8 803179B8 A1220001 */ sb $v0, 1($t1) -/* 0D29BC 803179BC 8CEF0010 */ lw $t7, 0x10($a3) -.L803179C0: -/* 0D29C0 803179C0 24E60010 */ addiu $a2, $a3, 0x10 -/* 0D29C4 803179C4 51E00013 */ beql $t7, $zero, .L80317A14 -/* 0D29C8 803179C8 8CF80018 */ lw $t8, 0x18($a3) -/* 0D29CC 803179CC 8CD90000 */ lw $t9, ($a2) -/* 0D29D0 803179D0 03244021 */ addu $t0, $t9, $a0 -/* 0D29D4 803179D4 ACC80000 */ sw $t0, ($a2) -/* 0D29D8 803179D8 91180001 */ lbu $t8, 1($t0) -/* 0D29DC 803179DC 01004825 */ move $t1, $t0 -/* 0D29E0 803179E0 5700000C */ bnezl $t8, .L80317A14 -/* 0D29E4 803179E4 8CF80018 */ lw $t8, 0x18($a3) -/* 0D29E8 803179E8 8D0E0004 */ lw $t6, 4($t0) -/* 0D29EC 803179EC 8D2F0008 */ lw $t7, 8($t1) -/* 0D29F0 803179F0 8D39000C */ lw $t9, 0xc($t1) -/* 0D29F4 803179F4 01C54021 */ addu $t0, $t6, $a1 -/* 0D29F8 803179F8 AD280004 */ sw $t0, 4($t1) -/* 0D29FC 803179FC 01E44021 */ addu $t0, $t7, $a0 -/* 0D2A00 80317A00 AD280008 */ sw $t0, 8($t1) -/* 0D2A04 80317A04 03244021 */ addu $t0, $t9, $a0 -/* 0D2A08 80317A08 AD28000C */ sw $t0, 0xc($t1) -/* 0D2A0C 80317A0C A1220001 */ sb $v0, 1($t1) -/* 0D2A10 80317A10 8CF80018 */ lw $t8, 0x18($a3) -.L80317A14: -/* 0D2A14 80317A14 24E60018 */ addiu $a2, $a3, 0x18 -/* 0D2A18 80317A18 53000013 */ beql $t8, $zero, .L80317A68 -/* 0D2A1C 80317A1C 8CE60004 */ lw $a2, 4($a3) -/* 0D2A20 80317A20 8CCE0000 */ lw $t6, ($a2) -/* 0D2A24 80317A24 01C44021 */ addu $t0, $t6, $a0 -/* 0D2A28 80317A28 ACC80000 */ sw $t0, ($a2) -/* 0D2A2C 80317A2C 910F0001 */ lbu $t7, 1($t0) -/* 0D2A30 80317A30 01004825 */ move $t1, $t0 -/* 0D2A34 80317A34 55E0000C */ bnezl $t7, .L80317A68 -/* 0D2A38 80317A38 8CE60004 */ lw $a2, 4($a3) -/* 0D2A3C 80317A3C 8D190004 */ lw $t9, 4($t0) -/* 0D2A40 80317A40 8D380008 */ lw $t8, 8($t1) -/* 0D2A44 80317A44 8D2E000C */ lw $t6, 0xc($t1) -/* 0D2A48 80317A48 03254021 */ addu $t0, $t9, $a1 -/* 0D2A4C 80317A4C AD280004 */ sw $t0, 4($t1) -/* 0D2A50 80317A50 03044021 */ addu $t0, $t8, $a0 -/* 0D2A54 80317A54 AD280008 */ sw $t0, 8($t1) -/* 0D2A58 80317A58 01C44021 */ addu $t0, $t6, $a0 -/* 0D2A5C 80317A5C AD28000C */ sw $t0, 0xc($t1) -/* 0D2A60 80317A60 A1220001 */ sb $v0, 1($t1) -/* 0D2A64 80317A64 8CE60004 */ lw $a2, 4($a3) -.L80317A68: -/* 0D2A68 80317A68 A0E20000 */ sb $v0, ($a3) -/* 0D2A6C 80317A6C 00867821 */ addu $t7, $a0, $a2 -/* 0D2A70 80317A70 ACEF0004 */ sw $t7, 4($a3) -.L80317A74: -/* 0D2A74 80317A74 24630004 */ addiu $v1, $v1, 4 -.L80317A78: -/* 0D2A78 80317A78 5543FFB4 */ bnel $t2, $v1, .L8031794C -/* 0D2A7C 80317A7C 8C660000 */ lw $a2, ($v1) -.L80317A80: -/* 0D2A80 80317A80 03E00008 */ jr $ra -/* 0D2A84 80317A84 25BD0010 */ addiu $sp, $t5, 0x10 diff --git a/data/behavior_data.c b/data/behavior_data.c index 73bb9ae..a9742a2 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -2842,7 +2842,7 @@ const BehaviorScript bhvInitializeChangingWaterLevel[] = { END_LOOP(), }; -const BehaviorScript bhvTornadoSandParticle[] = { +const BehaviorScript bhvTweesterSandParticle[] = { BEGIN(OBJ_LIST_UNIMPORTANT), OR_INT(oFlags, (OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), BILLBOARD(), @@ -2851,7 +2851,7 @@ const BehaviorScript bhvTornadoSandParticle[] = { END_LOOP(), }; -const BehaviorScript bhvTornado[] = { +const BehaviorScript bhvTweester[] = { BEGIN(OBJ_LIST_POLELIKE), 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), @@ -5869,12 +5869,12 @@ const BehaviorScript bhvPenguinRaceShortcutCheck[] = { END_LOOP(), }; -const BehaviorScript bhvCoffinManager[] = { +const BehaviorScript bhvCoffinSpawner[] = { BEGIN(OBJ_LIST_SURFACE), OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), CALL_NATIVE(bhv_init_room), BEGIN_LOOP(), - CALL_NATIVE(bhv_coffin_manager_loop), + CALL_NATIVE(bhv_coffin_spawner_loop), END_LOOP(), }; diff --git a/enhancements/README.md b/enhancements/README.md index e7553c9..241d82f 100644 --- a/enhancements/README.md +++ b/enhancements/README.md @@ -1,3 +1,53 @@ -# IMPORTANT NOTICE ABOUT THIS FOLDER +# Super Mario 64 Enhancements -Everything in this folder is non-canon to the source code in the rest of the repository. As such, it is not to be considered when looking for more information on Super Mario 64's functionality. +This directory contains unofficial patches to the source code that provide various features +and enhancements. + +To apply a patch, run `tools/apply_patch.sh [patch]` where `[patch]` is the name of the +.patch file you wish to apply. This will perform all of the patch's changes +to the source code. + +Likewise, to undo the changes from a patch you applied, run +`tools/revert_patch.sh` with the name of the .patch file you wish to undo. + +To create your own enhancement patch, switch to the `master` Git +branch, make your changes to the code (but do not commit), then run `tools/create_patch.sh`. Your changes will be stored in the .patch file you specify. + +The following enhancements are included in this directory: + +## Crash Screen - `crash.patch` + +This enhancement provides a crash screen that is displayed when the code throws a hardware exception. This may be useful for diagnosing crashes in game code. + +## Debug Box - `debug_box.patch` + +This allows you to draw 3D boxes for debugging purposes. + +Call the `debug_box` function 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. + +## FPS Counter - `fps.patch` + +This patch provides an in-game FPS counter to measure the frame rate. + +## iQue Player Support - `ique_support.patch` + +This enhancement allows the same ROM to work on both the Nintendo 64 and the iQue Player. + +## Memory Expansion Pak Error Screen - `mem_error_screen.patch` + +Use this patch if your game requires over 4 MB of memory and requires the +Expansion Pak. If the Expansion Pak is not present, an error message will be +shown on startup. + +## Demo Input Recorder - `record_demo.patch` + +This patch allows you to record gameplay demos for the attract screen. It requires the latest nightly versions of Project64, and uses the Project64 JavaScript API to dump the demo input data from RAM and write it to a file. + +Place the `enhancements/RecordDemo.js` file in the `/Scripts/` folder in the Project64 directory. + +In the Scripts window, double click on "RecordDemo" on the list on the left side. + +When this is done, it should turn green which lets you know that it has started. + +When your demo has been recorded, it will be dumped to the newly created `/SM64_DEMOS/` folder within the Project64 directory. diff --git a/enhancements/record_demo/RecordDemo.js b/enhancements/RecordDemo.js similarity index 100% rename from enhancements/record_demo/RecordDemo.js rename to enhancements/RecordDemo.js diff --git a/enhancements/crash.h b/enhancements/crash.h deleted file mode 100644 index da4e011..0000000 --- a/enhancements/crash.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _CRASH_H_ -#define _CRASH_H_ - -#include - -#define CRASH_SCREEN_INCLUDED 1 - -extern u32 cop0_get_cause(void); -extern u32 cop0_get_epc(void); -extern u32 cop0_get_badvaddr(void); - -extern void _n64_assert(const char* pFile, int nLine, const char *pExpression, int nStopProgram); - -extern u8 __crash_handler_entry[]; - -void generate_exception_preambles(void *entryPoint); -void show_crash_screen_and_hang(void); -u8 ascii_to_idx(char c); -void fb_set_address(void *address); -void fb_swap(void); -void fb_fill(int baseX, int baseY, int width, int height); -void fb_draw_char(int x, int y, u8 idx); -void fb_draw_char_shaded(int x, int y, u8 idx); -int fb_print_str(int x, int y, const char *str); -int fb_print_uint(int x, int y, u32 value); -void fb_print_int_hex(int x, int y, u32 value, int nbits); -void fb_print_gpr_states(int x, int y, const char* regStrs[], u32 *regContext); - -#endif /* _CRASH_H_ */ diff --git a/enhancements/crash.inc.c b/enhancements/crash.inc.c deleted file mode 100644 index 930c96a..0000000 --- a/enhancements/crash.inc.c +++ /dev/null @@ -1,292 +0,0 @@ -/* SM64 Crash Handler */ -/* See Readme in crash.inc.s for details. */ - -#include - -#include "crash.h" - -extern u32 exceptionRegContext[]; - -extern char *pAssertFile; -extern int nAssertLine; -extern char *pAssertExpression; -extern int nAssertStopProgram; - -u16 fbFillColor = 0xFFFF; -u16 fbShadeColor = 0x0000; -u16 *fbAddress = NULL; - -extern u8 crashFont[]; - -const char *szErrCodes[] = { - "INTERRUPT", - "TLB MOD", - "UNMAPPED LOAD ADDR", - "UNMAPPED STORE ADDR", - "BAD LOAD ADDR", - "BAD STORE ADDR", - "BUS ERR ON INSTR FETCH", - "BUS ERR ON LOADSTORE", - "SYSCALL", - "BREAKPOINT", - "UNKNOWN INSTR", - "COP UNUSABLE", - "ARITHMETIC OVERFLOW", - "TRAP EXC", - "VIRTUAL COHERENCY INSTR", - "FLOAT EXC", -}; - -const char *szGPRegisters1[] = { "R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3", - "T0", "T1", "T2", "T3", "T4", "T5", "T6", NULL }; - -const char *szGPRegisters2[] = { "T7", "S0", "S1", "S2", "S3", "S4", - "S5", "S6", "S7", "T8", "T9", /*"K0", "K1",*/ - "GP", "SP", "FP", "RA", NULL }; - -/* - Generates new preamble code at the exception vectors (0x000, 0x180) - - eg: generate_exception_preambles(crash_handler_entry); - - 000: lui k0, hi(crash_handler_entry) - 004: addiu k0, k0, lo(crash_handler_entry) - 008: jr k0 - 00C: nop -*/ -void generate_exception_preambles(void *entryPoint) { - u8 *mem = (u8 *) 0xA0000000; - int offs = 0; - int i; - - u16 hi = (u32) entryPoint >> 16; - u16 lo = (u32) entryPoint & 0xFFFF; - - if (lo & 0x8000) { - hi++; - } - - for (i = 0; i < 2; i++) { - *(u32 *) &mem[offs + 0x00] = 0x3C1A0000 | hi; - *(u32 *) &mem[offs + 0x04] = 0x275A0000 | lo; - *(u32 *) &mem[offs + 0x08] = 0x03400008; - *(u32 *) &mem[offs + 0x0C] = 0x00000000; - offs += 0x180; - } -} - -int crash_strlen(char *str) { - int len = 0; - while (*str++) { - len++; - } - return len; -} - -void show_crash_screen_and_hang(void) { - u32 cause; - u32 epc; - u8 errno; - - fb_set_address((void *) (*(u32 *) 0xA4400004 | 0x80000000)); // replace me - - cause = cop0_get_cause(); - epc = cop0_get_epc(); - - errno = (cause >> 2) & 0x1F; - - if (nAssertStopProgram == 0) { - fbFillColor = 0x6253; - fb_fill(10, 10, 300, 220); - - fb_print_str(80, 20, "AN ERROR HAS OCCURRED!"); - fb_print_int_hex(80, 30, errno, 8); - fb_print_str(107, 30, szErrCodes[errno]); - - if (errno >= 2 && errno <= 5) { - /* - 2 UNMAPPED LOAD ADDR - 3 UNMAPPED STORE ADDR - 4 BAD LOAD ADDR - 5 BAD STORE ADDR - */ - u32 badvaddr = cop0_get_badvaddr(); - - fb_print_str(188, 50, "VA"); - fb_print_int_hex(215, 50, badvaddr, 32); - } - } else { - int afterFileX; - int exprBoxWidth; - fbFillColor = 0x5263; - fb_fill(10, 10, 300, 220); - - fb_print_str(80, 20, "ASSERTION FAILED!"); - - afterFileX = fb_print_str(80, 30, pAssertFile); - fb_print_str(afterFileX, 30, ":"); - fb_print_uint(afterFileX + 5, 30, nAssertLine); - - exprBoxWidth = (crash_strlen(pAssertExpression) * 5) + 2; - fbFillColor = 0x0001; - fb_fill(80 - 1, 40 - 1, exprBoxWidth, 10); - fb_print_str(80, 40, pAssertExpression); - } - - fb_print_str(80, 50, "PC"); - fb_print_int_hex(95, 50, epc, 32); - - fb_print_gpr_states(80, 70, szGPRegisters1, &exceptionRegContext[6 + 0]); - fb_print_gpr_states(145, 70, szGPRegisters2, &exceptionRegContext[6 + 15 * 2]); - - fb_swap(); - osWritebackDCacheAll(); - - while (1) // hang forever - { - UNUSED volatile int t = 0; // keep pj64 happy - } -} - -u8 ascii_to_idx(char c) { - return c - 0x20; -} - -void fb_set_address(void *address) { - fbAddress = (u16 *) address; -} - -void fb_swap() { - // update VI frame buffer register - // todo other registers - *(u32 *) (0xA4400004) = (u32) fbAddress & 0x00FFFFFF; -} - -void fb_fill(int baseX, int baseY, int width, int height) { - int y, x; - - for (y = baseY; y < baseY + height; y++) { - for (x = baseX; x < baseX + width; x++) { - fbAddress[y * 320 + x] = fbFillColor; - } - } -} - -void fb_draw_char(int x, int y, u8 idx) { - u16 *out = &fbAddress[y * 320 + x]; - const u8 *in = &crashFont[idx * 3]; - int nbyte; - int nrow; - int ncol; - - for (nbyte = 0; nbyte < 3; nbyte++) { - u8 curbyte = in[nbyte]; - for (nrow = 0; nrow < 2; nrow++) { - for (ncol = 0; ncol < 4; ncol++) { - u8 px = curbyte & (1 << 7 - (nrow * 4 + ncol)); - if (px != 0) { - out[ncol] = fbFillColor; - } - } - out += 320; - } - } -} - -void fb_draw_char_shaded(int x, int y, u8 idx) { - fbFillColor = 0x0001; - fb_draw_char(x - 1, y + 1, idx); - - fbFillColor = 0xFFFF; - fb_draw_char(x, y, idx); -} - -int fb_print_str(int x, int y, const char *str) { - while (1) { - int yoffs = 0; - u8 idx; - char c = *str++; - - if (c == '\0') { - break; - } - - if (c == ' ') { - x += 5; - continue; - } - - switch (c) { - case 'j': - case 'g': - case 'p': - case 'q': - case 'y': - case 'Q': - yoffs = 1; - break; - case ',': - yoffs = 2; - break; - } - - idx = ascii_to_idx(c); - fb_draw_char_shaded(x, y + yoffs, idx); - x += 5; - } - - return x; -} - -void fb_print_int_hex(int x, int y, u32 value, int nbits) { - nbits -= 4; - - while (nbits >= 0) { - int nib = ((value >> nbits) & 0xF); - u8 idx; - - if (nib > 9) { - idx = ('A' - 0x20) + (nib - 0xa); - } else { - idx = ('0' - 0x20) + nib; - } - - fb_draw_char_shaded(x, y, idx); - x += 5; - - nbits -= 4; - } -} - -int fb_print_uint(int x, int y, u32 value) { - int nchars = 0; - - int v = value; - int i; - while (v /= 10) { - nchars++; - } - - x += nchars * 5; - - for (i = nchars; i >= 0; i--) { - fb_draw_char_shaded(x, y, ('0' - 0x20) + (value % 10)); - value /= 10; - x -= 5; - } - - return (x + nchars * 5); -} - -void fb_print_gpr_states(int x, int y, const char *regNames[], u32 *regContext) { - int i; - for (i = 0;; i++) { - if (regNames[i] == NULL) { - break; - } - - fb_print_str(x, y, regNames[i]); - fb_print_int_hex(x + 15, y, regContext[i * 2 + 1], 32); - y += 10; - } -} diff --git a/enhancements/crash.inc.s b/enhancements/crash.inc.s deleted file mode 100644 index f336315..0000000 --- a/enhancements/crash.inc.s +++ /dev/null @@ -1,158 +0,0 @@ -# SM64 Crash Handler -# See Readme below. - -.set COP0_CAUSE, 13 -.set COP0_EPC, 14 -.set COP0_BADVADDR, 8 - -/* --------------------------------------------------------------- - * IMPORTANT README: - * --------------------------------------------------------------- - * To use this crash screen, in lib/__osExceptionPreamble.s, change - * the function to use the following assembly: - * - * lui $k0, %hi(__crash_handler_entry) - * addiu $k0, $k0, %lo(__crash_handler_entry) - * jr $k0 - * nop - * - * Doing just a jal __crash_handler_entry will cause mupen recompiler - * errors, so be sure to use the original exception style assembly - * above! - * - * Be sure to add #include "../../enhancements/crash.inc.c" to - * the top of game.c. Add .include "../enhancements/crash.inc.s" to - * the bottom of asm/decompress.s. Add "../enhancements/crash.h" to - * the top of sm64.h, above the CRASH_SCREEN_INCLUDED condition. - * - * See the DEBUG_ASSERT macro on how to call the crash screen for - * detected exceptions. - */ - -glabel crashFont - .incbin "enhancements/crash_font.bin" - .align 4 - -glabel exceptionRegContext - .fill 0x108 - -glabel pAssertFile - .dword 0 -glabel nAssertLine - .dword 0 -glabel pAssertExpression - .dword 0 -glabel nAssertStopProgram - .dword 0 - -glabel _n64_assert - lui $at, %hi(pAssertFile) - sw $a0, %lo(pAssertFile)($at) - lui $at, %hi(nAssertLine) - sw $a1, %lo(nAssertLine)($at) - lui $at, %hi(pAssertExpression) - sw $a2, %lo(pAssertExpression)($at) - lui $at, %hi(nAssertStopProgram) - sw $a3, %lo(nAssertStopProgram)($at) - beqz $a3, .end_2 - nop - syscall # trigger crash screen -.end_2: - jr $ra - nop - -glabel cop0_get_cause - jr $ra - mfc0 $v0, $13 # COP0_CAUSE - -glabel cop0_get_epc - jr $ra - mfc0 $v0, $14 # COP0_EPC - -glabel cop0_get_badvaddr - jr $ra - mfc0 $v0, $8 # COP0_BADVADDR - -# If the error code field of cop0's cause register is non-zero, -# draw crash details to the screen and hang -# -# If there wasn't an error, continue to the original handler - -glabel __crash_handler_entry - la $k0, exceptionRegContext - sd $zero, 0x018 ($k0) - sd $at, 0x020 ($k0) - sd $v0, 0x028 ($k0) - sd $v1, 0x030 ($k0) - sd $a0, 0x038 ($k0) - sd $a1, 0x040 ($k0) - sd $a2, 0x048 ($k0) - sd $a3, 0x050 ($k0) - sd $t0, 0x058 ($k0) - sd $t1, 0x060 ($k0) - sd $t2, 0x068 ($k0) - sd $t3, 0x070 ($k0) - sd $t4, 0x078 ($k0) - sd $t5, 0x080 ($k0) - sd $t6, 0x088 ($k0) - sd $t7, 0x090 ($k0) - sd $s0, 0x098 ($k0) - sd $s1, 0x0A0 ($k0) - sd $s2, 0x0A8 ($k0) - sd $s3, 0x0B0 ($k0) - sd $s4, 0x0B8 ($k0) - sd $s5, 0x0C0 ($k0) - sd $s6, 0x0C8 ($k0) - sd $s7, 0x0D0 ($k0) - sd $t8, 0x0D8 ($k0) - sd $t9, 0x0E0 ($k0) - sd $gp, 0x0E8 ($k0) - sd $sp, 0x0F0 ($k0) - sd $s8, 0x0F8 ($k0) - sd $ra, 0x100 ($k0) - mfc0 $t0, $13 # COP0_CAUSE - srl $t0, $t0, 2 - andi $t0, $t0, 0x1F - beqz $t0, .end - nop - # cop unusable exception fired twice on startup so we'll ignore it for now - li $at, 0x0B - beq $t0, $at, .end - nop - jal show_crash_screen_and_hang - nop - .end: - ld $zero, 0x018 ($k0) - ld $at, 0x020 ($k0) - ld $v0, 0x028 ($k0) - ld $v1, 0x030 ($k0) - ld $a0, 0x038 ($k0) - ld $a1, 0x040 ($k0) - ld $a2, 0x048 ($k0) - ld $a3, 0x050 ($k0) - ld $t0, 0x058 ($k0) - ld $t1, 0x060 ($k0) - ld $t2, 0x068 ($k0) - ld $t3, 0x070 ($k0) - ld $t4, 0x078 ($k0) - ld $t5, 0x080 ($k0) - ld $t6, 0x088 ($k0) - ld $t7, 0x090 ($k0) - ld $s0, 0x098 ($k0) - ld $s1, 0x0A0 ($k0) - ld $s2, 0x0A8 ($k0) - ld $s3, 0x0B0 ($k0) - ld $s4, 0x0B8 ($k0) - ld $s5, 0x0C0 ($k0) - ld $s6, 0x0C8 ($k0) - ld $s7, 0x0D0 ($k0) - ld $t8, 0x0D8 ($k0) - ld $t9, 0x0E0 ($k0) - ld $gp, 0x0E8 ($k0) - ld $sp, 0x0F0 ($k0) - ld $s8, 0x0F8 ($k0) - ld $ra, 0x100 ($k0) - lui $k0, %hi(__osException) - addiu $k0, $k0, %lo(__osException) - jr $k0 # run the original handler - nop diff --git a/enhancements/crash.patch b/enhancements/crash.patch new file mode 100644 index 0000000..1ff6fd4 --- /dev/null +++ b/enhancements/crash.patch @@ -0,0 +1,529 @@ +diff --git a/asm/crash.s b/asm/crash.s +new file mode 100644 +index 00000000..870b7e2c +--- /dev/null ++++ b/asm/crash.s +@@ -0,0 +1,160 @@ ++# SM64 Crash Handler ++# See Readme below. ++ ++.include "macros.inc" ++ ++.set COP0_CAUSE, 13 ++.set COP0_EPC, 14 ++.set COP0_BADVADDR, 8 ++ ++/* --------------------------------------------------------------- ++ * IMPORTANT README: ++ * --------------------------------------------------------------- ++ * To use this crash screen, in lib/__osExceptionPreamble.s, change ++ * the function to use the following assembly: ++ * ++ * lui $k0, %hi(__crash_handler_entry) ++ * addiu $k0, $k0, %lo(__crash_handler_entry) ++ * jr $k0 ++ * nop ++ * ++ * Doing just a jal __crash_handler_entry will cause mupen recompiler ++ * errors, so be sure to use the original exception style assembly ++ * above! ++ * ++ * Be sure to add #include "../../enhancements/crash.inc.c" to ++ * the top of game.c. Add .include "../enhancements/crash.inc.s" to ++ * the bottom of asm/decompress.s. Add "../enhancements/crash.h" to ++ * the top of sm64.h, above the CRASH_SCREEN_INCLUDED condition. ++ * ++ * See the DEBUG_ASSERT macro on how to call the crash screen for ++ * detected exceptions. ++ */ ++ ++glabel crashFont ++ .incbin "enhancements/crash_font.bin" ++ .align 4 ++ ++glabel exceptionRegContext ++ .fill 0x108 ++ ++glabel pAssertFile ++ .dword 0 ++glabel nAssertLine ++ .dword 0 ++glabel pAssertExpression ++ .dword 0 ++glabel nAssertStopProgram ++ .dword 0 ++ ++glabel _n64_assert ++ lui $at, %hi(pAssertFile) ++ sw $a0, %lo(pAssertFile)($at) ++ lui $at, %hi(nAssertLine) ++ sw $a1, %lo(nAssertLine)($at) ++ lui $at, %hi(pAssertExpression) ++ sw $a2, %lo(pAssertExpression)($at) ++ lui $at, %hi(nAssertStopProgram) ++ sw $a3, %lo(nAssertStopProgram)($at) ++ beqz $a3, .end_2 ++ nop ++ syscall # trigger crash screen ++.end_2: ++ jr $ra ++ nop ++ ++glabel cop0_get_cause ++ jr $ra ++ mfc0 $v0, $13 # COP0_CAUSE ++ ++glabel cop0_get_epc ++ jr $ra ++ mfc0 $v0, $14 # COP0_EPC ++ ++glabel cop0_get_badvaddr ++ jr $ra ++ mfc0 $v0, $8 # COP0_BADVADDR ++ ++# If the error code field of cop0's cause register is non-zero, ++# draw crash details to the screen and hang ++# ++# If there wasn't an error, continue to the original handler ++ ++glabel __crash_handler_entry ++ la $k0, exceptionRegContext ++ sd $zero, 0x018 ($k0) ++ sd $at, 0x020 ($k0) ++ sd $v0, 0x028 ($k0) ++ sd $v1, 0x030 ($k0) ++ sd $a0, 0x038 ($k0) ++ sd $a1, 0x040 ($k0) ++ sd $a2, 0x048 ($k0) ++ sd $a3, 0x050 ($k0) ++ sd $t0, 0x058 ($k0) ++ sd $t1, 0x060 ($k0) ++ sd $t2, 0x068 ($k0) ++ sd $t3, 0x070 ($k0) ++ sd $t4, 0x078 ($k0) ++ sd $t5, 0x080 ($k0) ++ sd $t6, 0x088 ($k0) ++ sd $t7, 0x090 ($k0) ++ sd $s0, 0x098 ($k0) ++ sd $s1, 0x0A0 ($k0) ++ sd $s2, 0x0A8 ($k0) ++ sd $s3, 0x0B0 ($k0) ++ sd $s4, 0x0B8 ($k0) ++ sd $s5, 0x0C0 ($k0) ++ sd $s6, 0x0C8 ($k0) ++ sd $s7, 0x0D0 ($k0) ++ sd $t8, 0x0D8 ($k0) ++ sd $t9, 0x0E0 ($k0) ++ sd $gp, 0x0E8 ($k0) ++ sd $sp, 0x0F0 ($k0) ++ sd $s8, 0x0F8 ($k0) ++ sd $ra, 0x100 ($k0) ++ mfc0 $t0, $13 # COP0_CAUSE ++ srl $t0, $t0, 2 ++ andi $t0, $t0, 0x1F ++ beqz $t0, .end ++ nop ++ # cop unusable exception fired twice on startup so we'll ignore it for now ++ li $at, 0x0B ++ beq $t0, $at, .end ++ nop ++ jal show_crash_screen_and_hang ++ nop ++ .end: ++ ld $zero, 0x018 ($k0) ++ ld $at, 0x020 ($k0) ++ ld $v0, 0x028 ($k0) ++ ld $v1, 0x030 ($k0) ++ ld $a0, 0x038 ($k0) ++ ld $a1, 0x040 ($k0) ++ ld $a2, 0x048 ($k0) ++ ld $a3, 0x050 ($k0) ++ ld $t0, 0x058 ($k0) ++ ld $t1, 0x060 ($k0) ++ ld $t2, 0x068 ($k0) ++ ld $t3, 0x070 ($k0) ++ ld $t4, 0x078 ($k0) ++ ld $t5, 0x080 ($k0) ++ ld $t6, 0x088 ($k0) ++ ld $t7, 0x090 ($k0) ++ ld $s0, 0x098 ($k0) ++ ld $s1, 0x0A0 ($k0) ++ ld $s2, 0x0A8 ($k0) ++ ld $s3, 0x0B0 ($k0) ++ ld $s4, 0x0B8 ($k0) ++ ld $s5, 0x0C0 ($k0) ++ ld $s6, 0x0C8 ($k0) ++ ld $s7, 0x0D0 ($k0) ++ ld $t8, 0x0D8 ($k0) ++ ld $t9, 0x0E0 ($k0) ++ ld $gp, 0x0E8 ($k0) ++ ld $sp, 0x0F0 ($k0) ++ ld $s8, 0x0F8 ($k0) ++ ld $ra, 0x100 ($k0) ++ lui $k0, %hi(__osException) ++ addiu $k0, $k0, %lo(__osException) ++ jr $k0 # run the original handler ++ nop +diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s +index fdc36c8b..ccbf4ecc 100644 +--- a/lib/asm/__osExceptionPreamble.s ++++ b/lib/asm/__osExceptionPreamble.s +@@ -8,12 +8,11 @@ + .section .text, "ax" + + glabel __osExceptionPreamble +- lui $k0, %hi(__osException) # $k0, 0x8032 +- addiu $k0, %lo(__osException) # addiu $k0, $k0, 0x66d0 ++ lui $k0, %hi(__crash_handler_entry) # $k0, 0x8032 ++ addiu $k0, %lo(__crash_handler_entry) # addiu $k0, $k0, 0x66d0 + jr $k0 + nop + +- + glabel __osException + lui $k0, %hi(gInterruptedThread) # $k0, 0x8036 + addiu $k0, %lo(gInterruptedThread) # addiu $k0, $k0, 0x5f40 +diff --git a/sm64.ld b/sm64.ld +index dea5c8bd..22fff2d8 100755 +--- a/sm64.ld ++++ b/sm64.ld +@@ -112,6 +112,7 @@ SECTIONS + BUILD_DIR/src/game/rendering_graph_node.o(.text); + BUILD_DIR/src/game/profiler.o(.text); + BUILD_DIR/asm/decompress.o(.text); ++ BUILD_DIR/asm/crash.o(.text); + BUILD_DIR/src/game/camera.o(.text); + BUILD_DIR/src/game/debug_course.o(.text); + BUILD_DIR/src/game/object_list_processor.o(.text); +diff --git a/src/game/crash.c b/src/game/crash.c +new file mode 100644 +index 00000000..587ac86d +--- /dev/null ++++ b/src/game/crash.c +@@ -0,0 +1,291 @@ ++/* SM64 Crash Handler */ ++ ++#include ++ ++#include "crash.h" ++ ++extern u32 exceptionRegContext[]; ++ ++extern char *pAssertFile; ++extern int nAssertLine; ++extern char *pAssertExpression; ++extern int nAssertStopProgram; ++ ++u16 fbFillColor = 0xFFFF; ++u16 fbShadeColor = 0x0000; ++u16 *fbAddress = NULL; ++ ++extern u8 crashFont[]; ++ ++const char *szErrCodes[] = { ++ "INTERRUPT", ++ "TLB MOD", ++ "UNMAPPED LOAD ADDR", ++ "UNMAPPED STORE ADDR", ++ "BAD LOAD ADDR", ++ "BAD STORE ADDR", ++ "BUS ERR ON INSTR FETCH", ++ "BUS ERR ON LOADSTORE", ++ "SYSCALL", ++ "BREAKPOINT", ++ "UNKNOWN INSTR", ++ "COP UNUSABLE", ++ "ARITHMETIC OVERFLOW", ++ "TRAP EXC", ++ "VIRTUAL COHERENCY INSTR", ++ "FLOAT EXC", ++}; ++ ++const char *szGPRegisters1[] = { "R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3", ++ "T0", "T1", "T2", "T3", "T4", "T5", "T6", NULL }; ++ ++const char *szGPRegisters2[] = { "T7", "S0", "S1", "S2", "S3", "S4", ++ "S5", "S6", "S7", "T8", "T9", /*"K0", "K1",*/ ++ "GP", "SP", "FP", "RA", NULL }; ++ ++/* ++ Generates new preamble code at the exception vectors (0x000, 0x180) ++ ++ eg: generate_exception_preambles(crash_handler_entry); ++ ++ 000: lui k0, hi(crash_handler_entry) ++ 004: addiu k0, k0, lo(crash_handler_entry) ++ 008: jr k0 ++ 00C: nop ++*/ ++void generate_exception_preambles(void *entryPoint) { ++ u8 *mem = (u8 *) 0xA0000000; ++ int offs = 0; ++ int i; ++ ++ u16 hi = (u32) entryPoint >> 16; ++ u16 lo = (u32) entryPoint & 0xFFFF; ++ ++ if (lo & 0x8000) { ++ hi++; ++ } ++ ++ for (i = 0; i < 2; i++) { ++ *(u32 *) &mem[offs + 0x00] = 0x3C1A0000 | hi; ++ *(u32 *) &mem[offs + 0x04] = 0x275A0000 | lo; ++ *(u32 *) &mem[offs + 0x08] = 0x03400008; ++ *(u32 *) &mem[offs + 0x0C] = 0x00000000; ++ offs += 0x180; ++ } ++} ++ ++int crash_strlen(char *str) { ++ int len = 0; ++ while (*str++) { ++ len++; ++ } ++ return len; ++} ++ ++void show_crash_screen_and_hang(void) { ++ u32 cause; ++ u32 epc; ++ u8 errno; ++ ++ fb_set_address((void *) (*(u32 *) 0xA4400004 | 0x80000000)); // replace me ++ ++ cause = cop0_get_cause(); ++ epc = cop0_get_epc(); ++ ++ errno = (cause >> 2) & 0x1F; ++ ++ if (nAssertStopProgram == 0) { ++ fbFillColor = 0x6253; ++ fb_fill(10, 10, 300, 220); ++ ++ fb_print_str(80, 20, "AN ERROR HAS OCCURRED!"); ++ fb_print_int_hex(80, 30, errno, 8); ++ fb_print_str(107, 30, szErrCodes[errno]); ++ ++ if (errno >= 2 && errno <= 5) { ++ /* ++ 2 UNMAPPED LOAD ADDR ++ 3 UNMAPPED STORE ADDR ++ 4 BAD LOAD ADDR ++ 5 BAD STORE ADDR ++ */ ++ u32 badvaddr = cop0_get_badvaddr(); ++ ++ fb_print_str(188, 50, "VA"); ++ fb_print_int_hex(215, 50, badvaddr, 32); ++ } ++ } else { ++ int afterFileX; ++ int exprBoxWidth; ++ fbFillColor = 0x5263; ++ fb_fill(10, 10, 300, 220); ++ ++ fb_print_str(80, 20, "ASSERTION FAILED!"); ++ ++ afterFileX = fb_print_str(80, 30, pAssertFile); ++ fb_print_str(afterFileX, 30, ":"); ++ fb_print_uint(afterFileX + 5, 30, nAssertLine); ++ ++ exprBoxWidth = (crash_strlen(pAssertExpression) * 5) + 2; ++ fbFillColor = 0x0001; ++ fb_fill(80 - 1, 40 - 1, exprBoxWidth, 10); ++ fb_print_str(80, 40, pAssertExpression); ++ } ++ ++ fb_print_str(80, 50, "PC"); ++ fb_print_int_hex(95, 50, epc, 32); ++ ++ fb_print_gpr_states(80, 70, szGPRegisters1, &exceptionRegContext[6 + 0]); ++ fb_print_gpr_states(145, 70, szGPRegisters2, &exceptionRegContext[6 + 15 * 2]); ++ ++ fb_swap(); ++ osWritebackDCacheAll(); ++ ++ while (1) // hang forever ++ { ++ UNUSED volatile int t = 0; // keep pj64 happy ++ } ++} ++ ++u8 ascii_to_idx(char c) { ++ return c - 0x20; ++} ++ ++void fb_set_address(void *address) { ++ fbAddress = (u16 *) address; ++} ++ ++void fb_swap() { ++ // update VI frame buffer register ++ // todo other registers ++ *(u32 *) (0xA4400004) = (u32) fbAddress & 0x00FFFFFF; ++} ++ ++void fb_fill(int baseX, int baseY, int width, int height) { ++ int y, x; ++ ++ for (y = baseY; y < baseY + height; y++) { ++ for (x = baseX; x < baseX + width; x++) { ++ fbAddress[y * 320 + x] = fbFillColor; ++ } ++ } ++} ++ ++void fb_draw_char(int x, int y, u8 idx) { ++ u16 *out = &fbAddress[y * 320 + x]; ++ const u8 *in = &crashFont[idx * 3]; ++ int nbyte; ++ int nrow; ++ int ncol; ++ ++ for (nbyte = 0; nbyte < 3; nbyte++) { ++ u8 curbyte = in[nbyte]; ++ for (nrow = 0; nrow < 2; nrow++) { ++ for (ncol = 0; ncol < 4; ncol++) { ++ u8 px = curbyte & (1 << 7 - (nrow * 4 + ncol)); ++ if (px != 0) { ++ out[ncol] = fbFillColor; ++ } ++ } ++ out += 320; ++ } ++ } ++} ++ ++void fb_draw_char_shaded(int x, int y, u8 idx) { ++ fbFillColor = 0x0001; ++ fb_draw_char(x - 1, y + 1, idx); ++ ++ fbFillColor = 0xFFFF; ++ fb_draw_char(x, y, idx); ++} ++ ++int fb_print_str(int x, int y, const char *str) { ++ while (1) { ++ int yoffs = 0; ++ u8 idx; ++ char c = *str++; ++ ++ if (c == '\0') { ++ break; ++ } ++ ++ if (c == ' ') { ++ x += 5; ++ continue; ++ } ++ ++ switch (c) { ++ case 'j': ++ case 'g': ++ case 'p': ++ case 'q': ++ case 'y': ++ case 'Q': ++ yoffs = 1; ++ break; ++ case ',': ++ yoffs = 2; ++ break; ++ } ++ ++ idx = ascii_to_idx(c); ++ fb_draw_char_shaded(x, y + yoffs, idx); ++ x += 5; ++ } ++ ++ return x; ++} ++ ++void fb_print_int_hex(int x, int y, u32 value, int nbits) { ++ nbits -= 4; ++ ++ while (nbits >= 0) { ++ int nib = ((value >> nbits) & 0xF); ++ u8 idx; ++ ++ if (nib > 9) { ++ idx = ('A' - 0x20) + (nib - 0xa); ++ } else { ++ idx = ('0' - 0x20) + nib; ++ } ++ ++ fb_draw_char_shaded(x, y, idx); ++ x += 5; ++ ++ nbits -= 4; ++ } ++} ++ ++int fb_print_uint(int x, int y, u32 value) { ++ int nchars = 0; ++ ++ int v = value; ++ int i; ++ while (v /= 10) { ++ nchars++; ++ } ++ ++ x += nchars * 5; ++ ++ for (i = nchars; i >= 0; i--) { ++ fb_draw_char_shaded(x, y, ('0' - 0x20) + (value % 10)); ++ value /= 10; ++ x -= 5; ++ } ++ ++ return (x + nchars * 5); ++} ++ ++void fb_print_gpr_states(int x, int y, const char *regNames[], u32 *regContext) { ++ int i; ++ for (i = 0;; i++) { ++ if (regNames[i] == NULL) { ++ break; ++ } ++ ++ fb_print_str(x, y, regNames[i]); ++ fb_print_int_hex(x + 15, y, regContext[i * 2 + 1], 32); ++ y += 10; ++ } ++} +diff --git a/src/game/crash.h b/src/game/crash.h +new file mode 100644 +index 00000000..da4e011e +--- /dev/null ++++ b/src/game/crash.h +@@ -0,0 +1,29 @@ ++#ifndef _CRASH_H_ ++#define _CRASH_H_ ++ ++#include ++ ++#define CRASH_SCREEN_INCLUDED 1 ++ ++extern u32 cop0_get_cause(void); ++extern u32 cop0_get_epc(void); ++extern u32 cop0_get_badvaddr(void); ++ ++extern void _n64_assert(const char* pFile, int nLine, const char *pExpression, int nStopProgram); ++ ++extern u8 __crash_handler_entry[]; ++ ++void generate_exception_preambles(void *entryPoint); ++void show_crash_screen_and_hang(void); ++u8 ascii_to_idx(char c); ++void fb_set_address(void *address); ++void fb_swap(void); ++void fb_fill(int baseX, int baseY, int width, int height); ++void fb_draw_char(int x, int y, u8 idx); ++void fb_draw_char_shaded(int x, int y, u8 idx); ++int fb_print_str(int x, int y, const char *str); ++int fb_print_uint(int x, int y, u32 value); ++void fb_print_int_hex(int x, int y, u32 value, int nbits); ++void fb_print_gpr_states(int x, int y, const char* regStrs[], u32 *regContext); ++ ++#endif /* _CRASH_H_ */ diff --git a/enhancements/debug_box.h b/enhancements/debug_box.h deleted file mode 100644 index ae70a02..0000000 --- a/enhancements/debug_box.h +++ /dev/null @@ -1,23 +0,0 @@ -#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 deleted file mode 100644 index 1f13054..0000000 --- a/enhancements/debug_box.inc.c +++ /dev/null @@ -1,248 +0,0 @@ -#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/debug_box.patch b/enhancements/debug_box.patch new file mode 100644 index 0000000..4fba40e --- /dev/null +++ b/enhancements/debug_box.patch @@ -0,0 +1,302 @@ +diff --git a/src/game/area.c b/src/game/area.c +index 240605d8..88c1a314 100644 +--- a/src/game/area.c ++++ b/src/game/area.c +@@ -19,6 +19,7 @@ + #include "level_update.h" + #include "engine/geo_layout.h" + #include "save_file.h" ++#include "debug_box.h" + + struct SpawnInfo gPlayerSpawnInfos[1]; + struct GraphNode *D_8033A160[0x100]; +@@ -352,6 +353,8 @@ void render_game(void) { + if (gCurrentArea != NULL && !gWarpTransition.pauseRendering) { + geo_process_root(gCurrentArea->unk04, D_8032CE74, D_8032CE78, gFBSetColor); + ++ render_debug_boxes(); ++ + gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&D_8032CF00)); + + gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, +diff --git a/src/game/debug_box.c b/src/game/debug_box.c +new file mode 100644 +index 00000000..0ee87ec7 +--- /dev/null ++++ b/src/game/debug_box.c +@@ -0,0 +1,244 @@ ++#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.c ++ * Draws 3D boxes for debugging purposes. ++ * ++ * How to use: ++ * ++ * In render_game() in area.c, 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(void) ++{ ++ 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/src/game/debug_box.h b/src/game/debug_box.h +new file mode 100644 +index 00000000..cdb3dc9d +--- /dev/null ++++ b/src/game/debug_box.h +@@ -0,0 +1,25 @@ ++#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); ++ ++void render_debug_boxes(void); ++ ++#endif /* _DEBUG_DRAW_CUBE_H */ diff --git a/enhancements/dyn_light.inc.c b/enhancements/dyn_light.inc.c deleted file mode 100644 index c661dd2..0000000 --- a/enhancements/dyn_light.inc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file demonstrates how to manipulate display list data from C. * - * To use it, #include "../../enhancements/dyn_light.inc.c" and hook it on to a function that is called - * once per frame. - */ - -#ifndef _DYNLIGHTS_H -#define _DYNLIGHTS_H - -#include "../src/game/area.h" /* Get level info */ -#include "../src/game/level_update.h" /* gMarioState */ -#include "../src/game/memory.h" -#include "../src/game/print.h" - -/* - * Common values for shading, which are manipulated with the SHADE_* defines - * in combination with the set_mario_shade_light function. - */ - -/* Shading levels for Mario */ - -#define SHADE_100 1 -#define SHADE_75 0.75 -#define SHADE_50 0.50 -#define SHADE_25 0.25 - -/* Mario light values */ - -#define VAL1 0x7F -#define VAL2 0x39 -#define VAL3 0X0E -#define VAL4 0x07 -#define VAL5 0x3C -#define VAL6 0x60 -#define VAL7 0x03 - -/* Custom structs used for setting light values. */ - -typedef struct /* Normal shade lights */ -{ - unsigned char byte[7]; -} Light2; - -typedef struct /* Ambient lights */ -{ - unsigned char byte[15]; -} Light3; - -/* ! GLABEL THESE: actors/mario/model.s ! */ - -extern Light2 *mario_amb_light_group1; -extern Light2 *mario_amb_light_group2; -extern Light2 *mario_amb_light_group3; -extern Light2 *mario_amb_light_group4; -extern Light2 *mario_amb_light_group6; - -/* OPTIONAL: Add level lights here--just like Mario they have to be glabel'd. */ - -/* Used to set mario's shading to one of the four predetermined modes. */ - -void set_mario_shade_light(f32 mode) { - Light2 *ptr; - ptr = segmented_to_virtual(&mario_amb_light_group1); - ptr->byte[2] = VAL1 * mode; - ptr->byte[6] = VAL1 * mode; - ptr = segmented_to_virtual(&mario_amb_light_group2); - ptr->byte[0] = VAL1 * mode; - ptr->byte[4] = VAL1 * mode; - ptr = segmented_to_virtual(&mario_amb_light_group3); - ptr->byte[0] = VAL1 * mode; - ptr->byte[1] = VAL1 * mode; - ptr->byte[2] = VAL1 * mode; - ptr->byte[4] = VAL1 * mode; - ptr->byte[5] = VAL1 * mode; - ptr->byte[6] = VAL1 * mode; - ptr = segmented_to_virtual(&mario_amb_light_group4); - ptr->byte[0] = VAL2 * mode; - ptr->byte[1] = VAL3 * mode; - ptr->byte[2] = VAL4 * mode; - ptr->byte[4] = VAL2 * mode; - ptr->byte[5] = VAL3 * mode; - ptr->byte[6] = VAL4 * mode; - ptr = segmented_to_virtual(&mario_amb_light_group6); - ptr->byte[0] = VAL2 * mode; - ptr->byte[1] = VAL7 * mode; - ptr->byte[4] = VAL2 * mode; - ptr->byte[5] = VAL7 * mode; -} - -/* Creates a point light with its origin at x, y, and z. */ - -void point_light(s16 x, s16 y, s16 z, s16 size, f32 shade, s16 size1, f32 shade1) { - /* Outer region */ - - if (gMarioState->pos[0] >= (x - size1) && gMarioState->pos[0] <= x + size1 - && gMarioState->pos[1] >= (y - size1) && gMarioState->pos[1] <= y + size1 - && gMarioState->pos[2] >= (z - size1) && gMarioState->pos[2] <= z + size1) { - set_mario_shade_light(shade1); - } - - /* Inner region */ - - if (gMarioState->pos[0] >= (x - size) && gMarioState->pos[0] <= x + size - && gMarioState->pos[1] >= (y - size) && gMarioState->pos[1] <= y + size - && gMarioState->pos[2] >= (z - size) && gMarioState->pos[2] <= z + size) { - set_mario_shade_light(shade); - } -} - -/* - * Sets up the automatic shading for levels and sets up point lights. - * BBH is already done for you. - */ - -void set_level_shading(void) { -#ifdef DEBUG - print_text_fmt_int(40, 80, "AREA: %d", gCurrAreaIndex); - print_text_fmt_int(40, 60, "X: %d", gMarioState->pos[0]); - print_text_fmt_int(40, 40, "Y: %d", gMarioState->pos[1]); - print_text_fmt_int(40, 20, "Z: %d", gMarioState->pos[2]); -#endif - switch (gCurrLevelNum) { - case LEVEL_BBH: - set_mario_shade_light(SHADE_25); - - point_light(200, 0, 2300, 200, SHADE_100, 400, SHADE_50); - point_light(1000, 0, 2300, 200, SHADE_100, 400, SHADE_50); - - point_light(200, 0, 1500, 150, SHADE_75, 200, SHADE_50); - point_light(200, 0, 700, 150, SHADE_75, 200, SHADE_50); - - point_light(450, 0, 300, 150, SHADE_75, 200, SHADE_50); - point_light(1550, 0, 300, 150, SHADE_75, 200, SHADE_50); - point_light(1800, 0, 1500, 150, SHADE_75, 200, SHADE_50); - - point_light(1500, 0, 1750, 100, SHADE_50, 150, SHADE_25); /* Window moonlight */ - break; - case LEVEL_HMC: - set_mario_shade_light(SHADE_25); - break; - case LEVEL_CASTLE: - set_mario_shade_light(SHADE_75); - if (gCurrAreaIndex == 3) { - set_mario_shade_light(SHADE_50); - } - break; - case LEVEL_SSL: - set_mario_shade_light(SHADE_100); - if (gCurrAreaIndex == 2 || gCurrAreaIndex == 3) { /* Both pyramid areas */ - set_mario_shade_light(SHADE_25); - } - break; - case LEVEL_JRB: - case LEVEL_DDD: - case LEVEL_SA: - set_mario_shade_light(SHADE_50); - break; - case LEVEL_CCM: - case LEVEL_SL: - case LEVEL_PSS: - set_mario_shade_light(SHADE_75); - if (gCurrAreaIndex == 2) { - set_mario_shade_light(SHADE_50); - } - break; - default: - set_mario_shade_light(SHADE_100); - break; - } -} - -#endif diff --git a/enhancements/fps.inc.c b/enhancements/fps.inc.c deleted file mode 100644 index 687596c..0000000 --- a/enhancements/fps.inc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Framerate counter - * - * Calculates the game's current framerate by using osGetTime() and - * prints it out on the lower left side of the screen. - * - * HOW TO USE: - * - * Add this include statement to the top of game.c - * - * #include "../../enhancements/fps.inc.c" - * - * Then, at the end of the while(1) loop in the function thread5_game_loop() - * add the function call render_fps() - * - * That's it! Build the rom file and press L when the game boots up - * to toggle the FPS counter. - */ - -// SDK states that 1 cycle takes about 21.33 nanoseconds -#define SECONDS_PER_CYCLE 0.00000002133f - -#define FPS_COUNTER_X_POS 24 -#define FPS_COUNTER_Y_POS 190 - -OSTime gLastOSTime = 0; -float gFrameTime = 0.0f; -u16 gFrames = 0; -u16 gFPS = 0; -u8 gRenderFPS = FALSE; - -void calculate_frameTime_from_OSTime(OSTime diff) { - gFrameTime += diff * SECONDS_PER_CYCLE; - gFrames++; -} - -void render_fps(void) { - // Toggle rendering framerate with the L button. - if (gPlayer1Controller->buttonPressed & L_TRIG) { - gRenderFPS ^= 1; - } - - if (gRenderFPS) { - OSTime newTime = osGetTime(); - - calculate_frameTime_from_OSTime(newTime - gLastOSTime); - - // If frame time is longer or equal to a second, update FPS counter. - if (gFrameTime >= 1.0f) { - gFPS = gFrames; - gFrames = 0; - gFrameTime -= 1.0f; - } - - print_text_fmt_int(FPS_COUNTER_X_POS, FPS_COUNTER_Y_POS, "FPS %d", gFPS); - - gLastOSTime = newTime; - } -} diff --git a/enhancements/fps.patch b/enhancements/fps.patch new file mode 100644 index 0000000..43de4a0 --- /dev/null +++ b/enhancements/fps.patch @@ -0,0 +1,60 @@ +diff --git a/src/game/game.c b/src/game/game.c +index ad800839..4a37549b 100644 +--- a/src/game/game.c ++++ b/src/game/game.c +@@ -52,6 +52,47 @@ struct DemoInput *gCurrDemoInput = NULL; // demo input sequence + u16 gDemoInputListID = 0; + struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check + ++// SDK states that 1 cycle takes about 21.33 nanoseconds ++#define SECONDS_PER_CYCLE 0.00000002133f ++ ++#define FPS_COUNTER_X_POS 24 ++#define FPS_COUNTER_Y_POS 190 ++ ++static OSTime gLastOSTime = 0; ++static float gFrameTime = 0.0f; ++static u16 gFrames = 0; ++static u16 gFPS = 0; ++static u8 gRenderFPS = FALSE; ++ ++static void calculate_frameTime_from_OSTime(OSTime diff) { ++ gFrameTime += diff * SECONDS_PER_CYCLE; ++ gFrames++; ++} ++ ++static void render_fps(void) { ++ // Toggle rendering framerate with the L button. ++ if (gPlayer1Controller->buttonPressed & L_TRIG) { ++ gRenderFPS ^= 1; ++ } ++ ++ if (gRenderFPS) { ++ OSTime newTime = osGetTime(); ++ ++ calculate_frameTime_from_OSTime(newTime - gLastOSTime); ++ ++ // If frame time is longer or equal to a second, update FPS counter. ++ if (gFrameTime >= 1.0f) { ++ gFPS = gFrames; ++ gFrames = 0; ++ gFrameTime -= 1.0f; ++ } ++ ++ print_text_fmt_int(FPS_COUNTER_X_POS, FPS_COUNTER_Y_POS, "FPS %d", gFPS); ++ ++ gLastOSTime = newTime; ++ } ++} ++ + // this function records distinct inputs over a 255-frame interval to RAM locations and was likely + // used to record the demo sequences seen in the final game. This function is unused. + static void record_demo(void) { +@@ -334,5 +375,7 @@ void thread5_game_loop(UNUSED void *arg) { + // amount of free space remaining. + print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead); + } ++ ++ render_fps(); + } + } diff --git a/enhancements/ique_support.patch b/enhancements/ique_support.patch new file mode 100644 index 0000000..05b474b --- /dev/null +++ b/enhancements/ique_support.patch @@ -0,0 +1,312 @@ +diff --git a/include/PR/console_type.h b/include/PR/console_type.h +new file mode 100644 +index 00000000..e60550ab +--- /dev/null ++++ b/include/PR/console_type.h +@@ -0,0 +1,7 @@ ++enum ConsoleType { ++ CONSOLE_N64, ++ CONSOLE_IQUE ++}; ++ ++extern enum ConsoleType gConsoleType; ++extern enum ConsoleType get_console_type(void); +diff --git a/lib/asm/skGetId.s b/lib/asm/skGetId.s +new file mode 100644 +index 00000000..8fb4c449 +--- /dev/null ++++ b/lib/asm/skGetId.s +@@ -0,0 +1,18 @@ ++# Code by stuckpixel ++ ++.set noreorder ++.set gp=64 ++ ++.include "macros.inc" ++ ++glabel skGetId ++ li $v0, 0 ++ li $t0, 0xA4300014 ++ lw $t1, 0x00($t0) ++ nop ++ jr $ra ++ nop ++ nop ++ nop ++ nop ++ nop +diff --git a/lib/src/__osViSwapContext.c b/lib/src/__osViSwapContext.c +index d7741994..9aced7cf 100644 +--- a/lib/src/__osViSwapContext.c ++++ b/lib/src/__osViSwapContext.c +@@ -52,7 +52,9 @@ void __osViSwapContext() { + HW_REG(VI_INTR_REG, u32) = s0->fldRegs[field].vIntr; + HW_REG(VI_X_SCALE_REG, u32) = s1->unk20; + HW_REG(VI_Y_SCALE_REG, u32) = s1->unk2c; +- HW_REG(VI_CONTROL_REG, u32) = s1->features; ++ /* Make sure bit 13 is cleared. Otherwise, graphics will be corrupted on ++ * iQue Player. This has no effect on N64. */ ++ HW_REG(VI_CONTROL_REG, u32) = s1->features & ~(1 << 13); + D_80334914 = D_80334910; + D_80334910 = s1; + *D_80334914 = *D_80334910; +diff --git a/lib/src/consoleType.c b/lib/src/consoleType.c +new file mode 100644 +index 00000000..ef08d1ef +--- /dev/null ++++ b/lib/src/consoleType.c +@@ -0,0 +1,12 @@ ++#include "libultra_internal.h" ++#include ++ ++enum ConsoleType gConsoleType; ++ ++void skGetId(u32 *out); ++ ++enum ConsoleType get_console_type(void) { ++ u32 id = 0; ++ skGetId(&id); ++ return (id == 0) ? CONSOLE_N64 : CONSOLE_IQUE; ++} +diff --git a/lib/src/osEepromProbe.c b/lib/src/osEepromProbe.c +index d550b846..bbaf2bcc 100644 +--- a/lib/src/osEepromProbe.c ++++ b/lib/src/osEepromProbe.c +@@ -1,4 +1,5 @@ + #include "libultra_internal.h" ++#include + + // TODO: merge with osEepromWrite + typedef struct { +@@ -13,11 +14,23 @@ s32 osEepromProbe(OSMesgQueue *mq) { + unkStruct sp18; + + __osSiGetAccess(); +- status = __osEepStatus(mq, &sp18); +- if (status == 0 && (sp18.unk00 & 0x8000) != 0) { +- status = 1; +- } else { +- status = 0; ++ if (gConsoleType == CONSOLE_N64) { ++ status = __osEepStatus(mq, &sp18); ++ if (status == 0 && (sp18.unk00 & 0x8000) != 0) { ++ status = 1; ++ } else { ++ status = 0; ++ } ++ } else if (gConsoleType == CONSOLE_IQUE) { ++ s32 __osBbEepromSize = * (s32*) 0x80000360; ++ ++ if (__osBbEepromSize == 0x200) { ++ status = 1; ++ } ++ ++ if (__osBbEepromSize == 0x800) { ++ status = 2; ++ } + } + __osSiRelAccess(); + return status; +diff --git a/lib/src/osEepromRead.c b/lib/src/osEepromRead.c +index 905eff74..23f34dd5 100644 +--- a/lib/src/osEepromRead.c ++++ b/lib/src/osEepromRead.c +@@ -1,4 +1,5 @@ + #include "libultra_internal.h" ++#include + + extern u32 D_80365E00[15]; + extern u32 D_80365E3C; +@@ -44,33 +45,44 @@ s32 osEepromRead(OSMesgQueue *mq, u8 address, u8 *buffer) { + return -1; + } + __osSiGetAccess(); +- sp34 = __osEepStatus(mq, &sp28); +- if (sp34 != 0 || sp28.unk00 != 0x8000) { ++ if (gConsoleType == CONSOLE_N64) { ++ sp34 = __osEepStatus(mq, &sp28); ++ if (sp34 != 0 || sp28.unk00 != 0x8000) { + +- return 8; +- } +- while (sp28.unk02 & 0x80) { +- __osEepStatus(mq, &sp28); +- } +- __osPackEepReadData(address); +- sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00); +- osRecvMesg(mq, NULL, OS_MESG_BLOCK); +- for (sp30 = 0; sp30 < 0x10; sp30++) { +- (D_80365E00)[sp30] = 255; +- } +- D_80365E3C = 0; +- sp34 = __osSiRawStartDma(OS_READ, D_80365E00); +- D_80365D20 = 4; +- osRecvMesg(mq, NULL, OS_MESG_BLOCK); +- for (sp30 = 0; sp30 < 4; sp30++) { +- sp2c++; +- } +- sp20 = *(unkStruct2 *) sp2c; +- sp34 = (sp20.unk01 & 0xc0) >> 4; +- if (sp34 == 0) { +- for (sp30 = 0; sp30 < 8; sp30++) { +- *buffer++ = ((u8 *) &sp20.unk04)[sp30]; ++ return 8; ++ } ++ while (sp28.unk02 & 0x80) { ++ __osEepStatus(mq, &sp28); ++ } ++ __osPackEepReadData(address); ++ sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00); ++ osRecvMesg(mq, NULL, OS_MESG_BLOCK); ++ for (sp30 = 0; sp30 < 0x10; sp30++) { ++ (D_80365E00)[sp30] = 255; + } ++ D_80365E3C = 0; ++ sp34 = __osSiRawStartDma(OS_READ, D_80365E00); ++ D_80365D20 = 4; ++ osRecvMesg(mq, NULL, OS_MESG_BLOCK); ++ for (sp30 = 0; sp30 < 4; sp30++) { ++ sp2c++; ++ } ++ sp20 = *(unkStruct2 *) sp2c; ++ sp34 = (sp20.unk01 & 0xc0) >> 4; ++ if (sp34 == 0) { ++ for (sp30 = 0; sp30 < 8; sp30++) { ++ *buffer++ = ((u8 *) &sp20.unk04)[sp30]; ++ } ++ } ++ } else if (gConsoleType == CONSOLE_IQUE) { ++ u8 *__osBbEepromAddress = * (u8**) 0x8000035C; ++ s32 i; ++ ++ for (i = 0; i < 8; i++) { ++ buffer[i] = __osBbEepromAddress[(address << 3) + i]; ++ } ++ ++ sp34 = 0; + } + __osSiRelAccess(); + return sp34; +diff --git a/lib/src/osEepromWrite.c b/lib/src/osEepromWrite.c +index 71d0b7d6..c855cc20 100644 +--- a/lib/src/osEepromWrite.c ++++ b/lib/src/osEepromWrite.c +@@ -1,5 +1,6 @@ + #include "libultra_internal.h" + #include "osContInternal.h" ++#include + + u32 D_80365E00[0x3c >> 2]; + u32 D_80365E3C; +@@ -46,36 +47,47 @@ s32 osEepromWrite(OSMesgQueue *mq, u8 address, u8 *buffer) { + } + + __osSiGetAccess(); +- sp34 = __osEepStatus(mq, &sp1c); ++ if (gConsoleType == CONSOLE_N64) { ++ sp34 = __osEepStatus(mq, &sp1c); + +- if (sp34 != 0 || sp1c.unk00 != 0x8000) { +- return 8; +- } ++ if (sp34 != 0 || sp1c.unk00 != 0x8000) { ++ return 8; ++ } + +- while (sp1c.unk02 & 0x80) { +- __osEepStatus(mq, &sp1c); +- } ++ while (sp1c.unk02 & 0x80) { ++ __osEepStatus(mq, &sp1c); ++ } + +- __osPackEepWriteData(address, buffer); ++ __osPackEepWriteData(address, buffer); + +- sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00); +- osRecvMesg(mq, NULL, OS_MESG_BLOCK); ++ sp34 = __osSiRawStartDma(OS_WRITE, &D_80365E00); ++ osRecvMesg(mq, NULL, OS_MESG_BLOCK); + +- for (sp30 = 0; sp30 < 0x10; sp30++) { +- (D_80365E00)[sp30] = 255; +- } ++ for (sp30 = 0; sp30 < 0x10; sp30++) { ++ (D_80365E00)[sp30] = 255; ++ } + +- D_80365E3C = 0; +- sp34 = __osSiRawStartDma(OS_READ, D_80365E00); +- D_80365D20 = 5; +- osRecvMesg(mq, NULL, OS_MESG_BLOCK); ++ D_80365E3C = 0; ++ sp34 = __osSiRawStartDma(OS_READ, D_80365E00); ++ D_80365D20 = 5; ++ osRecvMesg(mq, NULL, OS_MESG_BLOCK); + +- for (sp30 = 0; sp30 < 4; sp30++) { +- sp2c++; +- } ++ for (sp30 = 0; sp30 < 4; sp30++) { ++ sp2c++; ++ } ++ ++ sp20 = *(unkStruct2 *) sp2c; ++ sp34 = (sp20.unk01 & 0xc0) >> 4; ++ } else if (gConsoleType == CONSOLE_N64) { ++ u8 *__osBbEepromAddress = * (u8**) 0x8000035C; ++ s32 i; + +- sp20 = *(unkStruct2 *) sp2c; +- sp34 = (sp20.unk01 & 0xc0) >> 4; ++ for (i = 0; i < 8; i++) { ++ __osBbEepromAddress[(address << 3) + i] = buffer[i]; ++ } ++ ++ sp34 = 0; ++ } + __osSiRelAccess(); + return sp34; + } +diff --git a/lib/src/osInitialize.c b/lib/src/osInitialize.c +index 0b9f7128..660d1991 100644 +--- a/lib/src/osInitialize.c ++++ b/lib/src/osInitialize.c +@@ -1,6 +1,7 @@ + #include "libultra_internal.h" + #include "hardware.h" + #include ++#include + + #define PIF_ADDR_START (void *) 0x1FC007FC + +@@ -46,6 +47,7 @@ void osInitialize(void) { + UNUSED u32 eu_sp30; + #endif + UNUSED u32 sp2c; ++ gConsoleType = get_console_type(); + D_80365CD0 = TRUE; + __osSetSR(__osGetSR() | 0x20000000); + __osSetFpcCsr(0x01000800); +diff --git a/sm64.ld b/sm64.ld +index 59a5a2a6..c8976649 100755 +--- a/sm64.ld ++++ b/sm64.ld +@@ -256,6 +256,8 @@ SECTIONS + BUILD_DIR/libultra.a:func_802F7140.o(.text) + BUILD_DIR/libultra.a:func_802F71A0.o(.text) + BUILD_DIR/libultra.a:func_802F71F0.o(.text) ++ BUILD_DIR/libultra.a:consoleType.o(.text) ++ BUILD_DIR/libultra.a:skGetId.o(.text) + + BUILD_DIR/lib/rsp.o(.text); + +@@ -369,6 +371,8 @@ SECTIONS + BUILD_DIR/libultra.a:__osGetCause.o(.text); + BUILD_DIR/libultra.a:__osAtomicDec.o(.text); + BUILD_DIR/libultra.a:guLookAtRef.o(.text); /* Fast3DEX2 only */ ++ BUILD_DIR/libultra.a:consoleType.o(.text); ++ BUILD_DIR/libultra.a:skGetId.o(.text); + BUILD_DIR/lib/rsp.o(.text); + #endif + diff --git a/enhancements/ique_support/README.md b/enhancements/ique_support/README.md deleted file mode 100644 index f22f0c0..0000000 --- a/enhancements/ique_support/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# iQue Player Support Enhancement - -This enhancement allows the same ROM to work on both the N64 and the iQue Player. - -## Instructions - -### Fix video corruption - -In `lib/src/__osViSwapContext.c`, change the line -```c -HW_REG(VI_CONTROL_REG, u32) = s1->features; -``` -to -```c -HW_REG(VI_CONTROL_REG, u32) = s1->features & ~(1 << 13); -``` -This has no effect on the N64, but prevents video corruption on iQue. Games will be unplayable on iQue unless you do this modification. - -### Add console detection - -Copy `enhancements/ique_support/skGetId.s` into `lib/asm/`. -Copy `enhancements/ique_support/consoleType.c` into `lib/src/`. -Copy `enhancements/ique_support/console_type.h` into `include/PR/`. - -Add the line `#include ` to the bottom of the block of `#include`s in `include/ultra64.h`. -Add the line `gConsoleType = get_console_type();` as the first line of code in `osInitialize()` in `lib/src/osInitialize.c` (i.e. right before the line `D_80365CD0 = TRUE;`) - -### Patch libultra EEPROM functions - -Console detection needs to be added for this modification. - -In `lib/src/osEepromRead.c`, `lib/src/osEepromWrite.c`, and `lib/src/osEepromProbe.c`: - -Add -```c -if (gConsoleType == CONSOLE_N64) { -``` -directly after the `__osSiGetAccess` call. - -Add -```c -} else if (gConsoleType == CONSOLE_IQUE) { -#include "../../enhancements/ique_support/FILENAME.inc.c" -} -``` -directly before the `__osSiRelAccess` call; replace `FILENAME` with the filename, i.e. if `lib/src/osEepromRead.c` put `#include "../../enhancements/ique_support/osEepromRead.inc.c"`. diff --git a/enhancements/ique_support/consoleType.c b/enhancements/ique_support/consoleType.c deleted file mode 100644 index 630cf2a..0000000 --- a/enhancements/ique_support/consoleType.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "libultra_internal.h" - -enum ConsoleType gConsoleType; - -void skGetId(u32 *out); - -enum ConsoleType get_console_type(void) { - u32 id = 0; - skGetId(&id); - return (id == 0) ? CONSOLE_N64 : CONSOLE_IQUE; -} diff --git a/enhancements/ique_support/console_type.h b/enhancements/ique_support/console_type.h deleted file mode 100644 index e60550a..0000000 --- a/enhancements/ique_support/console_type.h +++ /dev/null @@ -1,7 +0,0 @@ -enum ConsoleType { - CONSOLE_N64, - CONSOLE_IQUE -}; - -extern enum ConsoleType gConsoleType; -extern enum ConsoleType get_console_type(void); diff --git a/enhancements/ique_support/osEepromProbe.inc.c b/enhancements/ique_support/osEepromProbe.inc.c deleted file mode 100644 index 5858f90..0000000 --- a/enhancements/ique_support/osEepromProbe.inc.c +++ /dev/null @@ -1,9 +0,0 @@ -s32 __osBbEepromSize = * (s32*) 0x80000360; - -if (__osBbEepromSize == 0x200) { - status = 1; -} - -if (__osBbEepromSize == 0x800) { - status = 2; -} diff --git a/enhancements/ique_support/osEepromRead.inc.c b/enhancements/ique_support/osEepromRead.inc.c deleted file mode 100644 index 2da0f1d..0000000 --- a/enhancements/ique_support/osEepromRead.inc.c +++ /dev/null @@ -1,8 +0,0 @@ -u8 *__osBbEepromAddress = * (u8**) 0x8000035C; -s32 i; - -for (i = 0; i < 8; i++) { - buffer[i] = __osBbEepromAddress[(address << 3) + i]; -} - -sp34 = 0; diff --git a/enhancements/ique_support/osEepromWrite.inc.c b/enhancements/ique_support/osEepromWrite.inc.c deleted file mode 100644 index fdf0fda..0000000 --- a/enhancements/ique_support/osEepromWrite.inc.c +++ /dev/null @@ -1,8 +0,0 @@ -u8 *__osBbEepromAddress = * (u8**) 0x8000035C; -s32 i; - -for (i = 0; i < 8; i++) { - __osBbEepromAddress[(address << 3) + i] = buffer[i]; -} - -sp34 = 0; diff --git a/enhancements/ique_support/skGetId.s b/enhancements/ique_support/skGetId.s deleted file mode 100644 index 8fb4c44..0000000 --- a/enhancements/ique_support/skGetId.s +++ /dev/null @@ -1,18 +0,0 @@ -# Code by stuckpixel - -.set noreorder -.set gp=64 - -.include "macros.inc" - -glabel skGetId - li $v0, 0 - li $t0, 0xA4300014 - lw $t1, 0x00($t0) - nop - jr $ra - nop - nop - nop - nop - nop diff --git a/enhancements/mem_error_screen.inc.c b/enhancements/mem_error_screen.inc.c deleted file mode 100644 index 68b80a3..0000000 --- a/enhancements/mem_error_screen.inc.c +++ /dev/null @@ -1,193 +0,0 @@ -/* clang-format off */ -/* - * mem_error_screen.inc.c - * - * This enhancement should be used for ROM hacks that require the expansion pak. - * - * ----- Setup ----- - * - * Make sure that USE_EXT_RAM is defined in include/segments.h - #define USE_EXT_RAM - * - * 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.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" - * - * In the function AllocPool(), add these lines above main_pool_init(): - // Detect memory size - if(does_pool_end_lie_out_of_bounds(end)) - { - end = (void *)SEG_POOL_END_4MB; - } - * - * Then in thread3_main(), replace the create_thread for thread 5 with this if/else statement: - if(!gNotEnoughMemory) - { - create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10); - } - else - { - create_thread(&gGameLoopThread, 5, thread5_mem_error_message_loop, NULL, gThread5Stack + 0x2000, 10); - } - * - * In src/engine/level_script.h, add this line below 'extern u8 level_script_entry[];' - extern u8 level_script_entry_error_screen[]; - * - * In include/text_strings.h.in, add these 3 lines at the top. You can also add more strings if you want. - #define TEXT_CONSOLE_8MB _("If you're using an N64 console, then you will need to buy an\nExpansion Pak to play this ROM hack.") - #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.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.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(), - - FREE_LEVEL_POOL(), - LOAD_AREA(1), - SLEEP(32767), - EXIT_AND_EXECUTE(0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen), - }; - * - * 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 */ - -// Ensure that USE_EXT_RAM is defined. -#ifndef USE_EXT_RAM -#error You have to define USE_EXT_RAM in 'include/segments.h' -#endif - -#include -#include -#include "../src/game/display.h" -#include "../src/game/print.h" -#include "../src/game/ingame_menu.h" -#include "../src/game/segment2.h" -#include "../src/engine/level_script.h" - -// Require 8 MB of RAM, even if the pool doesn't go into extended memory. -// Change the '8' to whatever MB limit you want. -// Note: only special emulators allow for RAM sizes above 8 MB. -#define REQUIRED_MIN_MEM_SIZE 1048576 * 8 - -u8 gNotEnoughMemory = FALSE; -u8 gDelayForErrorMessage = 0; - -u8 does_pool_end_lie_out_of_bounds(void *end) { - u32 endPhy = ((u32) end) & 0x1FFFFFFF; - u32 memSize = *((u32 *) 0x80000318); - - if (endPhy > memSize) { - gNotEnoughMemory = TRUE; - return TRUE; - } else { - if (memSize < REQUIRED_MIN_MEM_SIZE) { - gNotEnoughMemory = TRUE; - } - return FALSE; - } -} - -// If you're using an N64 console, then you will need to buy an\nexpansion pak to play this ROM hack. -u8 text_console_8mb[] = { TEXT_CONSOLE_8MB }; - -// If you are using PJ64 1.6, go to: Options ► Settings ► Rom Settings Tab ► Memory Size then select 8 -// MB from the drop-down box. -u8 text_pj64[] = { TEXT_PJ64 }; - -// If you are using PJ64 2.X, go to: Options ► Settings ► Config: ► Memory Size, select 8 MB -u8 text_pj64_2[] = { TEXT_PJ64_2 }; - -Gfx *geo18_display_error_message(u32 run, UNUSED struct GraphNode *sp44, UNUSED u32 sp48) { - if (run) { - if (gDelayForErrorMessage > 0) { - // Draw color text title. - print_text(10, 210, "ERROR Need more memory"); - - // Init generic text rendering - create_dl_ortho_matrix(); - gSPDisplayList(gDisplayListHead++, - dl_ia_text_begin); // Init rendering stuff for generic text - - // Set text color to white - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - - print_generic_string(8, 170, text_console_8mb); - print_generic_string(8, 120, text_pj64); - print_generic_string(8, 54, text_pj64_2); - - // Cleanup - gSPDisplayList(gDisplayListHead++, - dl_ia_text_end); // Reset back to default render settings. - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - } else { - gDelayForErrorMessage += 1; - } - } - - return 0; -} - -// Basic main loop for the error screen. Note that controllers are not enabled here. -void thread5_mem_error_message_loop(UNUSED void *arg) { - struct LevelCommand *addr; - - setup_game_memory(); - set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1); - - addr = segmented_to_virtual(level_script_entry_error_screen); - - func_80247ED8(); - - while (1) { - func_80247FAC(); - addr = level_script_execute(addr); - display_and_vsync(); - } -} diff --git a/enhancements/mem_error_screen.patch b/enhancements/mem_error_screen.patch new file mode 100644 index 0000000..3dfe2ac --- /dev/null +++ b/enhancements/mem_error_screen.patch @@ -0,0 +1,298 @@ +diff --git a/Makefile b/Makefile +index 26c76d3d..bfc8bb18 100644 +--- a/Makefile ++++ b/Makefile +@@ -341,6 +341,7 @@ $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h + $(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h + $(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h + $(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h ++$(BUILD_DIR)/src/game/mem_error_screen.o: $(BUILD_DIR)/include/text_strings.h + + ################################################################ + # TEXTURE GENERATION # +diff --git a/include/segments.h b/include/segments.h +index ccc989aa..e54c3eab 100644 +--- a/include/segments.h ++++ b/include/segments.h +@@ -1,6 +1,9 @@ + #ifndef _SEGMENTS_H + #define _SEGMENTS_H + ++/* Use expansion pack RAM */ ++#define USE_EXT_RAM 1 ++ + /* + * Memory addresses for segments. Ideally, this header file would not be + * needed, and the addresses would be defined in sm64.ld and linker-inserted +diff --git a/include/text_strings.h.in b/include/text_strings.h.in +index 2fda11d7..8ba0a1c9 100644 +--- a/include/text_strings.h.in ++++ b/include/text_strings.h.in +@@ -25,6 +25,11 @@ + #define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses + #define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses + ++// Memory Expansion Error Screen ++#define TEXT_CONSOLE_8MB _("If you're using an N64 console, then you will need to buy an\nExpansion Pak to play this ROM hack.") ++#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") ++ + #ifdef VERSION_JP + + /** +diff --git a/levels/entry.c b/levels/entry.c +index 015eeb6b..cc010ca1 100644 +--- a/levels/entry.c ++++ b/levels/entry.c +@@ -15,3 +15,12 @@ const LevelScript level_script_entry[] = { + EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_1), + JUMP(/*target*/ level_script_entry), + }; ++ ++const LevelScript level_script_entry_error_screen[] = { ++ INIT_LEVEL(), ++ SLEEP(/*frames*/ 2), ++ BLACKOUT(/*active*/ FALSE), ++ SET_REG(/*value*/ 0), ++ EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_error_screen), ++ JUMP(/*target*/ level_script_entry_error_screen), ++}; +diff --git a/levels/intro/geo.c b/levels/intro/geo.c +index 7fbee0c5..e7effd85 100644 +--- a/levels/intro/geo.c ++++ b/levels/intro/geo.c +@@ -13,6 +13,24 @@ + + #include "levels/intro/header.h" + ++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(), ++}; ++ + // 0x0E0002D0 + const GeoLayout intro_geo_0002D0[] = { + GEO_NODE_SCREEN_AREA(0, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2), +diff --git a/levels/intro/header.h b/levels/intro/header.h +index e0f6292d..8f77fb26 100644 +--- a/levels/intro/header.h ++++ b/levels/intro/header.h +@@ -26,4 +26,8 @@ extern const LevelScript script_intro_L3[]; + extern const LevelScript script_intro_L4[]; + extern const LevelScript script_intro_L5[]; + ++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); ++ + #endif +diff --git a/levels/intro/script.c b/levels/intro/script.c +index 3ffd7859..b8c3ae41 100644 +--- a/levels/intro/script.c ++++ b/levels/intro/script.c +@@ -18,6 +18,21 @@ + #include "make_const_nonconst.h" + #include "levels/intro/header.h" + ++const LevelScript level_intro_entry_error_screen[] = { ++ INIT_LEVEL(), ++ FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd), ++ LOAD_MIO0(/*seg*/ 0x07, _intro_segment_7SegmentRomStart, _intro_segment_7SegmentRomEnd), ++ ALLOC_LEVEL_POOL(), ++ ++ AREA(/*index*/ 1, intro_geo_error_screen), ++ END_AREA(), ++ ++ FREE_LEVEL_POOL(), ++ LOAD_AREA(/*area*/ 1), ++ SLEEP(/*frames*/ 32767), ++ EXIT_AND_EXECUTE(/*seg*/ 0x14, _introSegmentRomStart, _introSegmentRomEnd, level_intro_entry_error_screen), ++}; ++ + const LevelScript level_intro_entry_1[] = { + INIT_LEVEL(), + FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd), +diff --git a/src/engine/level_script.h b/src/engine/level_script.h +index 89bfb4ed..0ea607c5 100644 +--- a/src/engine/level_script.h ++++ b/src/engine/level_script.h +@@ -4,5 +4,6 @@ + struct LevelCommand *level_script_execute(struct LevelCommand *cmd); + + extern u8 level_script_entry[]; ++extern u8 level_script_entry_error_screen[]; + + #endif /* _LEVEL_SCRIPT_H */ +diff --git a/src/game/main.c b/src/game/main.c +index f677f6f9..a164beb1 100644 +--- a/src/game/main.c ++++ b/src/game/main.c +@@ -12,6 +12,7 @@ + #include "buffers/buffers.h" + #include "segments.h" + #include "main.h" ++#include "mem_error_screen.h" + + // Message IDs + #define MESG_SP_COMPLETE 100 +@@ -125,6 +126,10 @@ void AllocPool(void) { + void *start = (void *) SEG_POOL_START; + void *end = (void *) SEG_POOL_END; + ++ // Detect memory size ++ if (does_pool_end_lie_out_of_bounds(end)) ++ end = (void *)SEG_POOL_END_4MB; ++ + main_pool_init(start, end); + gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); + } +@@ -314,7 +319,10 @@ void thread3_main(UNUSED void *arg) { + create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20); + osStartThread(&gSoundThread); + +- create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10); ++ if (!gNotEnoughMemory) ++ create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10); ++ else ++ create_thread(&gGameLoopThread, 5, thread5_mem_error_message_loop, NULL, gThread5Stack + 0x2000, 10); + osStartThread(&gGameLoopThread); + + while (1) { +diff --git a/src/game/mem_error_screen.c b/src/game/mem_error_screen.c +new file mode 100644 +index 00000000..20eeef8f +--- /dev/null ++++ b/src/game/mem_error_screen.c +@@ -0,0 +1,105 @@ ++/* clang-format off */ ++/* ++ * mem_error_screen.inc.c ++ * ++ * This enhancement should be used for ROM hacks that require the expansion pak. ++ * ++ */ ++/* clang-format on */ ++ ++#include ++#include "segments.h" ++#include "text_strings.h" ++#include "game.h" ++#include "main.h" ++#include "display.h" ++#include "print.h" ++#include "ingame_menu.h" ++#include "segment2.h" ++#include "../engine/level_script.h" ++ ++// Ensure that USE_EXT_RAM is defined. ++#ifndef USE_EXT_RAM ++#error You have to define USE_EXT_RAM in 'include/segments.h' ++#endif ++ ++// Require 8 MB of RAM, even if the pool doesn't go into extended memory. ++// Change the '8' to whatever MB limit you want. ++// Note: only special emulators allow for RAM sizes above 8 MB. ++#define REQUIRED_MIN_MEM_SIZE 1048576 * 8 ++ ++u8 gNotEnoughMemory = FALSE; ++u8 gDelayForErrorMessage = 0; ++ ++u8 does_pool_end_lie_out_of_bounds(void *end) { ++ u32 endPhy = ((u32) end) & 0x1FFFFFFF; ++ u32 memSize = *((u32 *) 0x80000318); ++ ++ if (endPhy > memSize) { ++ gNotEnoughMemory = TRUE; ++ return TRUE; ++ } else { ++ if (memSize < REQUIRED_MIN_MEM_SIZE) { ++ gNotEnoughMemory = TRUE; ++ } ++ return FALSE; ++ } ++} ++ ++// If you're using an N64 console, then you will need to buy an\nexpansion pak to play this ROM hack. ++u8 text_console_8mb[] = { TEXT_CONSOLE_8MB }; ++ ++// If you are using PJ64 1.6, go to: Options ► Settings ► Rom Settings Tab ► Memory Size then select 8 ++// MB from the drop-down box. ++u8 text_pj64[] = { TEXT_PJ64 }; ++ ++// If you are using PJ64 2.X, go to: Options ► Settings ► Config: ► Memory Size, select 8 MB ++u8 text_pj64_2[] = { TEXT_PJ64_2 }; ++ ++Gfx *geo18_display_error_message(u32 run, UNUSED struct GraphNode *sp44, UNUSED u32 sp48) { ++ if (run) { ++ if (gDelayForErrorMessage > 0) { ++ // Draw color text title. ++ print_text(10, 210, "ERROR Need more memory"); ++ ++ // Init generic text rendering ++ create_dl_ortho_matrix(); ++ gSPDisplayList(gDisplayListHead++, ++ dl_ia_text_begin); // Init rendering stuff for generic text ++ ++ // Set text color to white ++ gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); ++ ++ print_generic_string(8, 170, text_console_8mb); ++ print_generic_string(8, 120, text_pj64); ++ print_generic_string(8, 54, text_pj64_2); ++ ++ // Cleanup ++ gSPDisplayList(gDisplayListHead++, ++ dl_ia_text_end); // Reset back to default render settings. ++ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); ++ } else { ++ gDelayForErrorMessage += 1; ++ } ++ } ++ ++ return 0; ++} ++ ++// Basic main loop for the error screen. Note that controllers are not enabled here. ++void thread5_mem_error_message_loop(UNUSED void *arg) { ++ struct LevelCommand *addr; ++ ++ setup_game_memory(); ++ set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1); ++ ++ addr = segmented_to_virtual(level_script_entry_error_screen); ++ ++ func_80247ED8(); ++ ++ while (1) { ++ func_80247FAC(); ++ addr = level_script_execute(addr); ++ display_and_vsync(); ++ } ++} +diff --git a/src/game/mem_error_screen.h b/src/game/mem_error_screen.h +new file mode 100644 +index 00000000..9fbff34c +--- /dev/null ++++ b/src/game/mem_error_screen.h +@@ -0,0 +1,8 @@ ++#ifndef MEM_ERROR_SCREEN_H ++#define MEM_ERROR_SCREEN_H ++ ++extern u8 gNotEnoughMemory; ++void thread5_mem_error_message_loop(UNUSED void *arg); ++u8 does_pool_end_lie_out_of_bounds(void *end); ++ ++#endif diff --git a/enhancements/record_demo.patch b/enhancements/record_demo.patch new file mode 100644 index 0000000..f7edd5f --- /dev/null +++ b/enhancements/record_demo.patch @@ -0,0 +1,177 @@ +diff --git a/src/game/game.c b/src/game/game.c +index ad800839..810e2ba3 100644 +--- a/src/game/game.c ++++ b/src/game/game.c +@@ -52,6 +52,45 @@ struct DemoInput *gCurrDemoInput = NULL; // demo input sequence + u16 gDemoInputListID = 0; + struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check + ++/* ++ * This enhancement allows you to record gameplay demos for the mario head screen. ++ * ++ * Note: ++ * This enhancement does require the lastest versions of PJ64 from the nightly builds, ++ * because it uses the javascript API to automatically dump the demo files from RAM ++ * once the demo is completed. See enhancements/RecordDemo.js for more info ++ * ++*/ ++ ++#include "../src/game/mario.h" ++ ++#define DEMOREC_STATUS_NOT_RECORDING 0 ++#define DEMOREC_STATUS_PREPARING 1 ++#define DEMOREC_STATUS_RECORDING 2 ++#define DEMOREC_STATUS_STOPPING 3 ++#define DEMOREC_STATUS_DONE 4 ++ ++#define DEMOREC_PRINT_X 10 ++#define DEMOREC_PRINT_Y 10 ++ ++#define DEMOREC_DONE_DELAY 60 // Show "DONE" message for 2 seconds. ++ ++#define DEMOREC_MAX_INPUTS 1025 // Max number of recorded inputs. ++ ++/* ++ DO NOT REMOVE, MODIFY, OR MAKE A COPY OF THIS EXACT STRING! ++ This is here so that the js dump script can find the control variables easily. ++*/ ++char gDemoRecTag[] = "DEMORECVARS"; ++ ++// Control variables. It is easier if they are each 4 byte aligned, which is why they are u32. ++u32 gRecordingStatus = DEMOREC_STATUS_NOT_RECORDING; ++u32 gDoneDelay = 0; ++u32 gNumOfRecordedInputs = 0; ++struct DemoInput gRecordedInputs[DEMOREC_MAX_INPUTS]; ++struct DemoInput* gRecordedInputsPtr = (struct DemoInput*)gRecordedInputs; ++struct DemoInput gRecordedDemoInputCopy; ++ + // this function records distinct inputs over a 255-frame interval to RAM locations and was likely + // used to record the demo sequences seen in the final game. This function is unused. + static void record_demo(void) { +@@ -85,6 +124,118 @@ static void record_demo(void) { + gRecordedDemoInput.timer++; + } + ++void record_new_demo_input(void) { ++ if(gRecordedDemoInput.timer == 1 && gRecordedDemoInputCopy.timer > 0) { ++ gRecordedInputs[gNumOfRecordedInputs].timer = gRecordedDemoInputCopy.timer; ++ gRecordedInputs[gNumOfRecordedInputs + 1].timer = 0; ++ gRecordedInputs[gNumOfRecordedInputs].rawStickX = gRecordedDemoInputCopy.rawStickX; ++ gRecordedInputs[gNumOfRecordedInputs + 1].rawStickX = gRecordedDemoInputCopy.rawStickX; ++ gRecordedInputs[gNumOfRecordedInputs].rawStickY = gRecordedDemoInputCopy.rawStickY; ++ gRecordedInputs[gNumOfRecordedInputs + 1].rawStickY = gRecordedDemoInputCopy.rawStickY; ++ gRecordedInputs[gNumOfRecordedInputs].buttonMask = gRecordedDemoInputCopy.buttonMask; ++ gRecordedInputs[gNumOfRecordedInputs + 1].buttonMask = gRecordedDemoInputCopy.buttonMask; ++ gNumOfRecordedInputs++; ++ } ++} ++ ++// Self explanitory ++void copy_gRecordedDemoInput(void) { ++ gRecordedDemoInputCopy.timer = gRecordedDemoInput.timer; ++ gRecordedDemoInputCopy.rawStickX = gRecordedDemoInput.rawStickX; ++ gRecordedDemoInputCopy.rawStickY = gRecordedDemoInput.rawStickY; ++ gRecordedDemoInputCopy.buttonMask = gRecordedDemoInput.buttonMask; ++} ++ ++// Runs when the demo is recording. ++void recording(void) { ++ ++ // Force-stop when someone makes too many inputs. ++ if(gNumOfRecordedInputs + 1 > DEMOREC_MAX_INPUTS) { ++ gRecordingStatus = DEMOREC_STATUS_STOPPING; ++ return; ++ } ++ ++ copy_gRecordedDemoInput(); ++ record_demo(); // Defined in game.c ++ record_new_demo_input(); ++} ++ ++// Makes sure the last demo input is zeroed out, to make it look more clean. ++void record_cleanup(void) { ++ gRecordedInputs[gNumOfRecordedInputs].timer = 0; ++ gRecordedInputs[gNumOfRecordedInputs].rawStickX = 0; ++ gRecordedInputs[gNumOfRecordedInputs].rawStickY = 0; ++ gRecordedInputs[gNumOfRecordedInputs].buttonMask = 0; ++ ++ // Make sure the done delay is reset before moving to DONE status. ++ gDoneDelay = 0; ++} ++ ++void record_run(void) { ++ switch(gRecordingStatus) { ++ case DEMOREC_STATUS_NOT_RECORDING: ++ break; ++ case DEMOREC_STATUS_PREPARING: ++ if(gMarioObject != NULL && gCurrLevelNum >= 5) { // If the game is in an active level ++ gRecordingStatus = DEMOREC_STATUS_RECORDING; ++ ++ // A bit of a hack, but it works. ++ gNumOfRecordedInputs = 1; ++ gRecordedInputs[0].timer = gCurrLevelNum; ++ gRecordedInputs[0].rawStickX = 0; ++ gRecordedInputs[0].rawStickY = 0; ++ gRecordedInputs[0].buttonMask = 0; ++ } ++ break; ++ case DEMOREC_STATUS_RECORDING: ++ recording(); ++ break; ++ case DEMOREC_STATUS_DONE: ++ if(gDoneDelay > DEMOREC_DONE_DELAY) ++ gRecordingStatus = DEMOREC_STATUS_NOT_RECORDING; ++ else ++ gDoneDelay++; ++ break; ++ } ++} ++ ++// Prints the status on the bottom-left side of the screen in colorful text. ++void print_status(void) { ++ switch(gRecordingStatus) { ++ case DEMOREC_STATUS_PREPARING: ++ print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "READY"); ++ break; ++ case DEMOREC_STATUS_RECORDING: ++ print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "REC"); ++ break; ++ case DEMOREC_STATUS_STOPPING: ++ print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "WAIT"); ++ break; ++ case DEMOREC_STATUS_DONE: ++ print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "DONE"); ++ break; ++ } ++} ++ ++// Main function that should be called from thread5_game_loop() ++void recordingDemo(void) { ++ // Mario needs to enter directly into a level and not from a warp, ++ // so the debug level select is used for that. ++ gDebugLevelSelect = TRUE; ++ ++ if(gPlayer1Controller->buttonPressed & L_TRIG) { ++ if(gRecordingStatus == DEMOREC_STATUS_NOT_RECORDING) { ++ gRecordingStatus = DEMOREC_STATUS_PREPARING; ++ } else if (gRecordingStatus == DEMOREC_STATUS_RECORDING) { ++ gRecordingStatus = DEMOREC_STATUS_STOPPING; ++ record_cleanup(); ++ } ++ } ++ ++ record_run(); ++ print_status(); ++} ++ + // take the updated controller struct and calculate + // the new x, y, and distance floats. + void adjust_analog_stick(struct Controller *controller) { +@@ -325,6 +476,7 @@ void thread5_game_loop(UNUSED void *arg) { + audio_game_loop_tick(); + func_80247FAC(); + read_controller_inputs(); ++ recordingDemo(); + addr = level_script_execute(addr); + display_and_vsync(); + diff --git a/enhancements/record_demo/record_demo.inc.c b/enhancements/record_demo/record_demo.inc.c deleted file mode 100644 index f829636..0000000 --- a/enhancements/record_demo/record_demo.inc.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This enhancement allows you to record gameplay demos for the mario head screen. - * - * Note: - * This enhancement does require the lastest versions of PJ64 from the nightly builds, - * because it uses the javascript API to automatically dump the demo files from RAM - * once the demo is completed. See RecordDemo.js for more info - * - * SETUP: - * - * First add the following above the 'thread5_game_loop' function in src/game/game.c - #include "../enhancements/record_demo/record_demo.inc.c" - * - * Then, inside thread5_game_loop(), add the recordingDemo function call RIGHT AFTER - * read_controller_inputs like so: - func_802494A8(); - func_80247FAC(); - read_controller_inputs(); - recordingDemo(); - addr = level_script_execute(addr); - display_and_vsync(); -*/ - -#include "../src/game/mario.h" - -#define DEMOREC_STATUS_NOT_RECORDING 0 -#define DEMOREC_STATUS_PREPARING 1 -#define DEMOREC_STATUS_RECORDING 2 -#define DEMOREC_STATUS_STOPPING 3 -#define DEMOREC_STATUS_DONE 4 - -#define DEMOREC_PRINT_X 10 -#define DEMOREC_PRINT_Y 10 - -#define DEMOREC_DONE_DELAY 60 // Show "DONE" message for 2 seconds. - -#define DEMOREC_MAX_INPUTS 1025 // Max number of recorded inputs. - -/* - DO NOT REMOVE, MODIFY, OR MAKE A COPY OF THIS EXACT STRING! - This is here so that the js dump script can find the control variables easily. -*/ -char gDemoRecTag[] = "DEMORECVARS"; - -// Control variables. It is easier if they are each 4 byte aligned, which is why they are u32. -u32 gRecordingStatus = DEMOREC_STATUS_NOT_RECORDING; -u32 gDoneDelay = 0; -u32 gNumOfRecordedInputs = 0; -struct DemoInput gRecordedInputs[DEMOREC_MAX_INPUTS]; -struct DemoInput* gRecordedInputsPtr = (struct DemoInput*)gRecordedInputs; -struct DemoInput gRecordedDemoInputCopy; - -void record_new_demo_input(void) { - if(gRecordedDemoInput.timer == 1 && gRecordedDemoInputCopy.timer > 0) { - gRecordedInputs[gNumOfRecordedInputs].timer = gRecordedDemoInputCopy.timer; - gRecordedInputs[gNumOfRecordedInputs + 1].timer = 0; - gRecordedInputs[gNumOfRecordedInputs].rawStickX = gRecordedDemoInputCopy.rawStickX; - gRecordedInputs[gNumOfRecordedInputs + 1].rawStickX = gRecordedDemoInputCopy.rawStickX; - gRecordedInputs[gNumOfRecordedInputs].rawStickY = gRecordedDemoInputCopy.rawStickY; - gRecordedInputs[gNumOfRecordedInputs + 1].rawStickY = gRecordedDemoInputCopy.rawStickY; - gRecordedInputs[gNumOfRecordedInputs].button = gRecordedDemoInputCopy.button; - gRecordedInputs[gNumOfRecordedInputs + 1].button = gRecordedDemoInputCopy.button; - gNumOfRecordedInputs++; - } -} - -// Self explanitory -void copy_gRecordedDemoInput(void) { - gRecordedDemoInputCopy.timer = gRecordedDemoInput.timer; - gRecordedDemoInputCopy.rawStickX = gRecordedDemoInput.rawStickX; - gRecordedDemoInputCopy.rawStickY = gRecordedDemoInput.rawStickY; - gRecordedDemoInputCopy.button = gRecordedDemoInput.button; -} - -// Runs when the demo is recording. -void recording(void) { - - // Force-stop when someone makes too many inputs. - if(gNumOfRecordedInputs + 1 > DEMOREC_MAX_INPUTS) { - gRecordingStatus = DEMOREC_STATUS_STOPPING; - return; - } - - copy_gRecordedDemoInput(); - record_demo(); // Defined in game.c - record_new_demo_input(); -} - -// Makes sure the last demo input is zeroed out, to make it look more clean. -void record_cleanup(void) { - gRecordedInputs[gNumOfRecordedInputs].timer = 0; - gRecordedInputs[gNumOfRecordedInputs].rawStickX = 0; - gRecordedInputs[gNumOfRecordedInputs].rawStickY = 0; - gRecordedInputs[gNumOfRecordedInputs].button = 0; - - // Make sure the done delay is reset before moving to DONE status. - gDoneDelay = 0; -} - -void record_run(void) { - switch(gRecordingStatus) { - case DEMOREC_STATUS_NOT_RECORDING: - break; - case DEMOREC_STATUS_PREPARING: - if(gMarioObject != NULL && gCurrLevelNum >= 5) { // If the game is in an active level - gRecordingStatus = DEMOREC_STATUS_RECORDING; - - // A bit of a hack, but it works. - gNumOfRecordedInputs = 1; - gRecordedInputs[0].timer = gCurrLevelNum; - gRecordedInputs[0].rawStickX = 0; - gRecordedInputs[0].rawStickY = 0; - gRecordedInputs[0].button = 0; - } - break; - case DEMOREC_STATUS_RECORDING: - recording(); - break; - case DEMOREC_STATUS_DONE: - if(gDoneDelay > DEMOREC_DONE_DELAY) - gRecordingStatus = DEMOREC_STATUS_NOT_RECORDING; - else - gDoneDelay++; - break; - } -} - -// Prints the status on the bottom-left side of the screen in colorful text. -void print_status(void) { - switch(gRecordingStatus) { - case DEMOREC_STATUS_PREPARING: - print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "READY"); - break; - case DEMOREC_STATUS_RECORDING: - print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "REC"); - break; - case DEMOREC_STATUS_STOPPING: - print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "WAIT"); - break; - case DEMOREC_STATUS_DONE: - print_text(DEMOREC_PRINT_X, DEMOREC_PRINT_Y, "DONE"); - break; - } -} - -// Main function that should be called from thread5_game_loop() -void recordingDemo(void) { - // Mario needs to enter directly into a level and not from a warp, - // so the debug level select is used for that. - gDebugLevelSelect = TRUE; - - if(gPlayer1Controller->buttonPressed & L_TRIG) { - if(gRecordingStatus == DEMOREC_STATUS_NOT_RECORDING) { - gRecordingStatus = DEMOREC_STATUS_PREPARING; - } else if (gRecordingStatus == DEMOREC_STATUS_RECORDING) { - gRecordingStatus = DEMOREC_STATUS_STOPPING; - record_cleanup(); - } - } - - record_run(); - print_status(); -} diff --git a/extract_assets.py b/extract_assets.py index 512767d..91e5dd5 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -164,15 +164,17 @@ def main(): assets = todo[key] lang, mio0 = key if mio0 == "@sound": - with tempfile.NamedTemporaryFile(prefix="ctl") as ctl_file: - with tempfile.NamedTemporaryFile(prefix="tbl") as tbl_file: + with tempfile.NamedTemporaryFile(prefix="ctl", delete=False) as ctl_file: + with tempfile.NamedTemporaryFile(prefix="tbl", delete=False) as tbl_file: rom = roms[lang] size, locs = asset_map["@sound ctl " + lang] offset = locs[lang][0] ctl_file.write(rom[offset : offset + size]) + ctl_file.close() size, locs = asset_map["@sound tbl " + lang] offset = locs[lang][0] tbl_file.write(rom[offset : offset + size]) + tbl_file.close() args = [ "python3", "tools/disassemble_sound.py", @@ -183,7 +185,11 @@ def main(): for (asset, pos, size, meta) in assets: print("extracting", asset) args.append(asset + ":" + str(pos)) - subprocess.run(args, check=True) + try: + subprocess.run(args, check=True) + finally: + os.unlink(ctl_file.name) + os.unlink(tbl_file.name) continue if mio0 is not None: @@ -194,7 +200,7 @@ def main(): "-o", str(mio0), "baserom." + lang + ".z64", - "/dev/stdout", + "-", ], check=True, stdout=subprocess.PIPE, diff --git a/first-diff.py b/first-diff.py index 4201dae..4840e2a 100755 --- a/first-diff.py +++ b/first-diff.py @@ -50,6 +50,10 @@ if len(mybin) != len(basebin): print("Modified ROM has different size...") exit(1) +if mybin == basebin: + print("No differences!") + exit(0) + def search_map(rom_addr): ram_offset = None last_ram = 0 diff --git a/include/PR/os_message.h b/include/PR/os_message.h index 5bc565e..71e7698 100644 --- a/include/PR/os_message.h +++ b/include/PR/os_message.h @@ -35,6 +35,7 @@ extern "C" { #endif #include +#include #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) diff --git a/include/PR/os_misc.h b/include/PR/os_misc.h index 6b7f6e6..71e111f 100644 --- a/include/PR/os_misc.h +++ b/include/PR/os_misc.h @@ -1,6 +1,6 @@ #ifndef _ULTRA64_OS_MISC_H_ #define _ULTRA64_OS_MISC_H_ - +#include /* Miscellaneous OS functions */ void osInitialize(void); diff --git a/include/PR/os_pi.h b/include/PR/os_pi.h index 1d4176f..b0f0cb2 100644 --- a/include/PR/os_pi.h +++ b/include/PR/os_pi.h @@ -5,9 +5,10 @@ /* Types */ -typedef struct -{ +typedef struct { +#ifndef VERSION_EU u32 errStatus; +#endif void *dramAddr; void *C2Addr; u32 sectorSize; @@ -15,20 +16,21 @@ typedef struct u32 C1ErrSector[4]; } __OSBlockInfo; -typedef struct -{ - u32 cmdType; - u16 transferMode; - u16 blockNum; - s32 sectorNum; - uintptr_t devAddr; - u32 bmCtlShadow; - u32 seqCtlShadow; - __OSBlockInfo block[2]; +typedef struct { + u32 cmdType; // 0 + u16 transferMode; // 4 + u16 blockNum; // 6 + s32 sectorNum; // 8 + uintptr_t devAddr; // c +#ifdef VERSION_EU + u32 unk10; //error status added moved to blockinfo +#endif + u32 bmCtlShadow; // 10 + u32 seqCtlShadow; // 14 + __OSBlockInfo block[2]; // 18 } __OSTranxInfo; -typedef struct OSPiHandle_s -{ +typedef struct OSPiHandle_s { struct OSPiHandle_s *next; u8 type; u8 latency; @@ -41,27 +43,26 @@ typedef struct OSPiHandle_s __OSTranxInfo transferInfo; } OSPiHandle; -typedef struct -{ +typedef struct { u8 type; uintptr_t address; } OSPiInfo; -typedef struct -{ +typedef struct { u16 type; u8 pri; u8 status; OSMesgQueue *retQueue; } OSIoMesgHdr; -typedef struct -{ +typedef struct { /*0x00*/ OSIoMesgHdr hdr; /*0x08*/ void *dramAddr; /*0x0C*/ uintptr_t devAddr; /*0x10*/ size_t size; - //OSPiHandle *piHandle; //from the official definition +#ifdef VERSION_EU + OSPiHandle *piHandle; // from the official definition +#endif } OSIoMesg; /* Definitions */ @@ -74,12 +75,13 @@ typedef struct /* Functions */ -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, - uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *mq); -void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, - s32 cmdMsgCnt); +s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, + size_t nbytes, OSMesgQueue *mq); +void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgCnt); OSMesgQueue *osPiGetCmdQueue(void); s32 osPiWriteIo(uintptr_t devAddr, u32 data); s32 osPiReadIo(uintptr_t devAddr, u32 *data); +s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size); +s32 osEPiRawStartDma(OSPiHandle *piHandle, s32 dir, u32 cart_addr, void *dram_addr, size_t size); #endif diff --git a/include/PR/os_thread.h b/include/PR/os_thread.h index 791701c..76e528b 100644 --- a/include/PR/os_thread.h +++ b/include/PR/os_thread.h @@ -1,6 +1,6 @@ #ifndef _ULTRA64_THREAD_H_ #define _ULTRA64_THREAD_H_ - +#include "ultratypes.h" /* Recommended priorities for system threads */ #define OS_PRIORITY_MAX 255 #define OS_PRIORITY_VIMGR 254 diff --git a/include/audio_defines.h b/include/audio_defines.h index 2dcb8a1..15ac318 100644 --- a/include/audio_defines.h +++ b/include/audio_defines.h @@ -254,6 +254,8 @@ #define SOUND_GENERAL_BOWSER_BOMB_EXPLOSION SOUND_ARG_LOAD(3, 1, 0x2F, 0x00, 8) /* not verified */ #define SOUND_GENERAL_COIN_SPURT SOUND_ARG_LOAD(3, 0, 0x30, 0x00, 8) /* not verified */ #define SOUND_GENERAL_COIN_SPURT_2 SOUND_ARG_LOAD(3, 8, 0x30, 0x00, 8) +/* not verified */ #define SOUND_GENERAL_COIN_SPURT_EU SOUND_ARG_LOAD(3, 8, 0x30, 0x20, 8) + /* not verified */ #define SOUND_GENERAL_EXPLOSION6 0x3031 /* not verified */ #define SOUND_GENERAL_UNK32 0x3032 /* not verified */ #define SOUND_GENERAL_BOAT_TILT1 SOUND_ARG_LOAD(3, 0, 0x34, 0x40, 8) diff --git a/include/behavior_data.h b/include/behavior_data.h index d347d09..83f1f1e 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -246,8 +246,8 @@ extern const BehaviorScript bhvOpenableCageDoor[]; extern const BehaviorScript bhvOpenableGrill[]; extern const BehaviorScript bhvWaterLevelDiamond[]; extern const BehaviorScript bhvInitializeChangingWaterLevel[]; -extern const BehaviorScript bhvTornadoSandParticle[]; -extern const BehaviorScript bhvTornado[]; +extern const BehaviorScript bhvTweesterSandParticle[]; +extern const BehaviorScript bhvTweester[]; extern const BehaviorScript bhvMerryGoRoundBooManager[]; extern const BehaviorScript bhvPlaysMusicTrackWhenTouched[]; extern const BehaviorScript bhvAnimatedTexture[]; @@ -524,7 +524,7 @@ extern const BehaviorScript bhvBird[]; extern const BehaviorScript bhvRacingPenguin[]; extern const BehaviorScript bhvPenguinRaceFinishLine[]; extern const BehaviorScript bhvPenguinRaceShortcutCheck[]; -extern const BehaviorScript bhvCoffinManager[]; +extern const BehaviorScript bhvCoffinSpawner[]; extern const BehaviorScript bhvCoffin[]; extern const BehaviorScript bhvClamShell[]; extern const BehaviorScript bhvSkeeter[]; diff --git a/include/config.h b/include/config.h index 795bed9..cb6449f 100644 --- a/include/config.h +++ b/include/config.h @@ -19,7 +19,7 @@ /// player exits their activation radius. #define BUGFIX_PIRANHA_PLANT_STATE_RESET (0 || VERSION_US || VERSION_EU) /// Fixes bug where sleeping Piranha Plants damage players that bump into them -#define BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE (0 || VERSION_US || VERSION_EU) +#define BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE (0 || VERSION_US) /// Fixes bug where it shows a star when you grab a key in bowser battle stages #define BUGFIX_STAR_BOWSER_KEY (0 || VERSION_US || VERSION_EU) @@ -28,6 +28,10 @@ #define SCREEN_HEIGHT 240 // Border Height Define for NTSC Versions +#ifndef VERSION_EU #define BORDER_HEIGHT 8 +#else +#define BORDER_HEIGHT 1 +#endif #endif diff --git a/include/macro_presets.h b/include/macro_presets.h index 09c963e..f8f5f6b 100644 --- a/include/macro_presets.h +++ b/include/macro_presets.h @@ -151,7 +151,7 @@ struct MacroPreset MacroObjectPresets[] = { {bhvYellowCoin, MODEL_YELLOW_COIN, 0}, {bhvYellowCoin, MODEL_YELLOW_COIN, 0}, {bhvStaticObject, MODEL_KLEPTO, 0}, // unused - {bhvTornado, MODEL_TORNADO, 0}, // unused + {bhvTweester, MODEL_TWEESTER, 0}, // unused {bhvPokey, MODEL_NONE, 0}, {bhvPokey, MODEL_NONE, 0}, // unused {bhvToxBox, MODEL_SSL_TOX_BOX, 0}, // unused diff --git a/include/model_ids.h b/include/model_ids.h index 6b7a3d3..e3b3c93 100644 --- a/include/model_ids.h +++ b/include/model_ids.h @@ -360,7 +360,7 @@ // group 5 #define MODEL_POKEY_HEAD 0x54 // pokey_head_geo #define MODEL_POKEY_BODY_PART 0x55 // pokey_body_part_geo -#define MODEL_TORNADO 0x56 // tornado_seg5_geo_05014630 +#define MODEL_TWEESTER 0x56 // tweester_geo #define MODEL_KLEPTO 0x57 // klepto_geo #define MODEL_EYEROK_LEFT_HAND 0x58 // eyerok_left_hand_geo #define MODEL_EYEROK_RIGHT_HAND 0x59 // eyerok_right_hand_geo diff --git a/include/object_constants.h b/include/object_constants.h index 0f538c5..51f45fa 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -382,6 +382,18 @@ #define BBH_DYNAMIC_SURFACE_ROOM 0 #define BBH_OUTSIDE_ROOM 13 +/* Coffin Spawner */ + /* oAction */ + #define COFFIN_SPAWNER_ACT_COFFINS_UNLOADED 0 + +/* Coffin */ + /* oAction */ + #define COFFIN_ACT_IDLE 0 + #define COFFIN_ACT_STAND_UP 1 + + /* oBehParams2ndByte */ + #define COFFIN_BP_STATIC 0 + /* WDW Arrow Lift */ /* oAction */ #define ARROW_LIFT_ACT_IDLE 0 @@ -853,6 +865,17 @@ #define SKEETER_ACT_LUNGE 1 #define SKEETER_ACT_WALK 2 +/* Tweester */ + /* oAction */ + #define TWEESTER_ACT_IDLE 0 + #define TWEESTER_ACT_CHASE 1 + #define TWEESTER_ACT_HIDE 2 + + /* oSubAction */ + #define TWEESTER_SUB_ACT_WAIT 0 + + #define TWEESTER_SUB_ACT_CHASE 0 + /* Triplet butterfly */ /* oAction */ #define TRIPLET_BUTTERFLY_ACT_INIT 0 diff --git a/include/object_fields.h b/include/object_fields.h index e9faf2d..bff69be 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -132,7 +132,7 @@ #define /*0x1B4*/ oWallAngle OBJECT_FIELD_U32(0x4B) #define /*0x1B8*/ oFloorType OBJECT_FIELD_S16(0x4C, 0) #define /*0x1BA*/ oFloorRoom OBJECT_FIELD_S16(0x4C, 1) -#define /*0x1BC*/ oUnk1BC OBJECT_FIELD_S32(0x4D) +#define /*0x1BC*/ oAngleToHome OBJECT_FIELD_S32(0x4D) #define /*0x1C0*/ oFloor OBJECT_FIELD_SURFACE(0x4E) #define /*0x1C4*/ oDeathSound OBJECT_FIELD_S32(0x4F) @@ -1042,8 +1042,8 @@ #define /*0x0F4*/ oTumblingBridgeUnkF4 OBJECT_FIELD_S32(0x1B) /* Tweester */ -#define /*0x0F4*/ oTweesterUnkF4 OBJECT_FIELD_S32(0x1B) -#define /*0x0F8*/ oTweesterUnkF8 OBJECT_FIELD_S32(0x1C) +#define /*0x0F4*/ oTweesterScaleTimer OBJECT_FIELD_S32(0x1B) +#define /*0x0F8*/ oTweesterUnused OBJECT_FIELD_S32(0x1C) /* Ukiki */ #define /*0x0F4*/ oUkikiTauntCounter OBJECT_FIELD_S16(0x1B, 0) diff --git a/include/segments.h b/include/segments.h index ccc989a..a3fd2ee 100644 --- a/include/segments.h +++ b/include/segments.h @@ -15,14 +15,23 @@ #define SEG_POOL_START 0x8005C000 #define SEG_POOL_END SEG_BUFFERS + #define SEG_GODDARD 0x8016F000 + #define SEG_BUFFERS 0x801C1000 + #ifdef VERSION_EU #define SEG_MAIN 0x80241800 // TODO: Investigate why it's different? #else #define SEG_MAIN 0x80246000 #endif + +#ifdef VERSION_EU +#define SEG_ENGINE 0x8036FF00 +#else #define SEG_ENGINE 0x80378800 +#endif + #define SEG_FRAMEBUFFERS 0x8038F800 #else /* Use Expansion Pak space for pool. */ diff --git a/include/sm64.h b/include/sm64.h index b607fff..0f1358f 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -164,8 +164,8 @@ #define ACT_FLAG_CONTROL_JUMP_HEIGHT /* 0x02000000 */ (1 << 25) #define ACT_FLAG_ALLOW_FIRST_PERSON /* 0x04000000 */ (1 << 26) #define ACT_FLAG_PAUSE_EXIT /* 0x08000000 */ (1 << 27) -#define ACT_FLAG_SWIMMING_OR_FLYING /* 0x10000000 */ (1 << 28) // not checked by game -#define ACT_FLAG_WATER_OR_TEXT /* 0x20000000 */ (1 << 29) // not checked by game +#define ACT_FLAG_SWIMMING_OR_FLYING /* 0x10000000 */ (1 << 28) +#define ACT_FLAG_WATER_OR_TEXT /* 0x20000000 */ (1 << 29) #define ACT_FLAG_THROWING /* 0x80000000 */ (1 << 31) #define ACT_UNINITIALIZED 0x00000000 // (0x000) diff --git a/include/text_strings.h.in b/include/text_strings.h.in index 2fda11d..3166597 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -226,6 +226,102 @@ #ifdef VERSION_EU +/** + * File Select Text + */ +#define TEXT_RETURN_FR _("RETOUR") +#define TEXT_RETURN_DE _("ZURÜCK") + +#define TEXT_CHECK_SCORE_FR _("SCORE") +#define TEXT_CHECK_SCORE_DE _("LEISTUNG") + +#define TEXT_COPY_FILE_FR _("COPIER") +#define TEXT_COPY_FILE_DE _("KOPIEREN") + +#define TEXT_ERASE_FILE_FR _("EFFACER") +#define TEXT_ERASE_FILE_DE _("LÖSCHEN") + +#define TEXT_SELECT_FILE_FR _("CHOISIR FICHIER") +#define TEXT_SELECT_FILE_DE _("WwHLE SPIEL") + +#define TEXT_SCORE_FR _("SCORE") +#define TEXT_SCORE_DE _("LEISTUNG") + +#define TEXT_COPY_FR _("COPIER") +#define TEXT_COPY_DE _("KOPIEREN") + +#define TEXT_ERASE_FR _("EFFACER") +#define TEXT_ERASE_DE _("LÖSCHEN") + +#define TEXT_OPTION _("OPTION") // new in EU +#define TEXT_OPTION_FR _("OPTION") +#define TEXT_OPTION_DE _("OPTIONEN") + +#define TEXT_CHECK_FILE_FR _("VOIR SCORE") +#define TEXT_CHECK_FILE_DE _("VON WELCHEM SPIEL") + +#define TEXT_NO_SAVED_DATA_EXISTS_FR _("AUCUNE SAUVEGARDE DISPONIBLE") +#define TEXT_NO_SAVED_DATA_EXISTS_DE _("KEIN SPIEL VORHANDEN") + +#define TEXT_COPY_FILE_BUTTON_FR _("COPIER FICHIER") +#define TEXT_COPY_FILE_BUTTON_DE _("SPIEL KOPIEREN") + +#define TEXT_COPY_IT_TO_WHERE_FR _("COPIER SUR?") +#define TEXT_COPY_IT_TO_WHERE_DE _("WOHIN KOPIEREN?") + +#define TEXT_COPYING_COMPLETED_FR _("COPIE ACHEVEÉ") +#define TEXT_COPYING_COMPLETED_DE _("SPIEL KOPIERT") + +#define TEXT_SAVED_DATA_EXISTS_FR _("SAVEGARDE EXISTANTE") +#define TEXT_SAVED_DATA_EXISTS_DE _("BEREITS BELEGT") + +#define TEXT_NO_FILE_TO_COPY_FROM_FR _("AUCUN FICHIER VIDE") +#define TEXT_NO_FILE_TO_COPY_FROM_DE _("KEIN PLATZ VORHANDEN") + +#define TEXT_YES_FR _("OUI") +#define TEXT_YES_DE _("JA") + +#define TEXT_NO_FR _("NON") +#define TEXT_NO_DE _("NEIN") + +#define TEXT_ERASE_FILE_BUTTON_FR _("EFFACER FICHIER") +#define TEXT_ERASE_FILE_BUTTON_DE _("SPIEL LxSCHEN") + +#define TEXT_SURE_FR _("OK?") +#define TEXT_SURE_DE _("SICHER?") + +#define TEXT_FILE_MARIO_A_JUST_ERASED_FR _("MARIO A EFFACÉ") +#define TEXT_FILE_MARIO_A_JUST_ERASED_DE _("MARIO A GELÖSCHT") + +#define TEXT_SOUND_SELECT_FR _("SON") +#define TEXT_SOUND_SELECT_DE _("SOUND") + +#define TEXT_LANGUAGE_SELECT _("LANGUAGE SELECT") // new in EU +#define TEXT_LANGUAGE_SELECT_FR _("SELECTION LANGUE") +#define TEXT_LANGUAGE_SELECT_DE _("WwHLE SPRACHE") + +#define TEXT_STEREO_FR _("STÉRÉO") +#define TEXT_MONO_FR _("MONO") +#define TEXT_HEADSET_FR _("CASQUE") + +#define TEXT_STEREO_DE _("STEREO") +#define TEXT_MONO_DE _("MONO") +#define TEXT_HEADSET_DE _("PHONES") + +#define TEXT_ENGLISH _("ENGLISH") +#define TEXT_FRENCH _("FRANÇAIS") +#define TEXT_GERMAN _("DEUTSCH") + +#define TEXT_HI_SCORE_FR _("MEILLEUR SCORE") +#define TEXT_HI_SCORE_DE _("BESTLEISTUNG") + +#define TEXT_MY_SCORE_FR _("MON SCORE") +#define TEXT_MY_SCORE_DE _("LEISTUNG") + +#define TEXT_NEW_FR _("VIDE") +#define TEXT_NEW_DE _("FREI") + + /** * Menus Text (Pause, Course Completed) */ @@ -291,6 +387,89 @@ #define TEXT_LETS_HAVE_CAKE_DE _("Laßt uns einen leckeren Kuchen backen...") #define TEXT_FOR_MARIO_DE _("...für Mario...") +/** + * Course Table names for Score Menu Save view + */ +#define TEXT_MENU_BOB _(" 1 BOB-OMB BATTLEFIELD") +#define TEXT_MENU_WF _(" 2 WHOMP'S FORTRESS") +#define TEXT_MENU_JRB _(" 3 JOLLY ROGER BAY") +#define TEXT_MENU_CCM _(" 4 COOL, COOL MOUNTAIN") +#define TEXT_MENU_BBH _(" 5 BIG BOO'S HAUNT") +#define TEXT_MENU_HMC _(" 6 HAZY MAZE CAVE") +#define TEXT_MENU_LLL _(" 7 LETHAL LAVA LAND") +#define TEXT_MENU_SSL _(" 8 SHIFTING SAND LAND") +#define TEXT_MENU_DDD _(" 9 DIRE, DIRE DOCKS") +#define TEXT_MENU_SL _("10 SNOWMAN'S LAND") +#define TEXT_MENU_WDW _("11 WET-DRY WORLD") +#define TEXT_MENU_TTM _("12 TALL, TALL MOUNTAIN") +#define TEXT_MENU_THI _("13 TINY-HUGE ISLAND") +#define TEXT_MENU_TTC _("14 TICK TOCK CLOCK") +#define TEXT_MENU_RR _("15 RAINBOW RIDE") +#define TEXT_MENU_BITDW _(" BOWSER IN THE DARK WORLD") +#define TEXT_MENU_BITFS _(" BOWSER IN THE FIRE SEA") +#define TEXT_MENU_BITS _(" BOWSER IN THE SKY") +#define TEXT_MENU_PSS _(" THE PRINCESS'S SECRET SLIDE") +#define TEXT_MENU_COTMC _(" CAVERN OF THE METAL CAP") +#define TEXT_MENU_TOTWC _(" TOWER OF THE WING CAP") +#define TEXT_MENU_VCUTM _(" VANISH CAP UNDER THE MOAT") +#define TEXT_MENU_WMOTR _(" WING MARIO OVER THE RAINBOW") +#define TEXT_MENU_SA _(" THE SECRET AQUARIUM") +#define TEXT_MENU_NONE _("") +#define TEXT_MENU_STARS _(" CASTLE SECRET STARS") + +#define TEXT_MENU_BOB_FR _(" 1 BATAILLE DE BOB-OMB") +#define TEXT_MENU_WF_FR _(" 2 FORTERESSE DE WHOMP") +#define TEXT_MENU_JRB_FR _(" 3 BAIE DES PIRATES") +#define TEXT_MENU_CCM_FR _(" 4 MONTAGNE GLA-GLA") +#define TEXT_MENU_BBH_FR _(" 5 MANOIR DE BIG BOO") +#define TEXT_MENU_HMC_FR _(" 6 CAVERNE BRUMEUSE") +#define TEXT_MENU_LLL_FR _(" 7 LAVES FATALES") +#define TEXT_MENU_SSL_FR _(" 8 SABLES TROP MOUVANTS") +#define TEXT_MENU_DDD_FR _(" 9 AFFREUX BASSIN") +#define TEXT_MENU_SL_FR _("10 CHEZ LE ROI DES NEIGES") +#define TEXT_MENU_WDW_FR _("11 MONDE TREMPE-SECHE") +#define TEXT_MENU_TTM_FR _("12 TROP HAUTE MONTAGNE") +#define TEXT_MENU_THI_FR _("13 ILE GRANDS-PETITS") +#define TEXT_MENU_TTC_FR _("14 HORLOGE TIC-TAC") +#define TEXT_MENU_RR_FR _("15 COURSE ARC-EN-CIEL") +#define TEXT_MENU_BITDW_FR _(" BOWSER DES TENEBRES") +#define TEXT_MENU_BITFS_FR _(" BOWSER DES LAVES") +#define TEXT_MENU_BITS_FR _(" BOWSER DES CIEUX") +#define TEXT_MENU_PSS_FR _(" GLISSADE DE LA PRINCESSE") +#define TEXT_MENU_COTMC_FR _(" MINE DES CASQUETTES-METAL") +#define TEXT_MENU_TOTWC_FR _(" INTERRUPTEUR DE LA TOUR AILEE") +#define TEXT_MENU_VCUTM_FR _(" INVISIBLE SOUS LES DOUVES") +#define TEXT_MENU_WMOTR_FR _(" AU-DELA DE L'ARC-EN-CIEL") +#define TEXT_MENU_SA_FR _(" AQUARIUM SECRET") +#define TEXT_MENU_NONE_FR _("") +#define TEXT_MENU_STARS_FR _(" ETOILES SECRETES") + +#define TEXT_MENU_BOB_DE _(" 1 BOB-OMBS BOMBENBERG") +#define TEXT_MENU_WF_DE _(" 2 WUMMPS WUCHTWALL") +#define TEXT_MENU_JRB_DE _(" 3 PIRATENBUCHT PANIK") +#define TEXT_MENU_CCM_DE _(" 4 BIBBERBERG BOB") +#define TEXT_MENU_BBH_DE _(" 5 BIG BOOS BURG") +#define TEXT_MENU_HMC_DE _(" 6 GRÜNE GIFTGROTTE") +#define TEXT_MENU_LLL_DE _(" 7 LAVA LAGUNE") +#define TEXT_MENU_SSL_DE _(" 8 WOBIWABA WÜSTE") +#define TEXT_MENU_DDD_DE _(" 9 WILDE WASSERWERFT") +#define TEXT_MENU_SL_DE _("10 FROSTBEULEN FRUST") +#define TEXT_MENU_WDW_DE _("11 ATLANTIS AQUARIA") +#define TEXT_MENU_TTM_DE _("12 FLIEGENPILZ FIASKO") +#define TEXT_MENU_THI_DE _("13 GULLIVER GUMBA") +#define TEXT_MENU_TTC_DE _("14 TICK TACK TRAUMA") +#define TEXT_MENU_RR_DE _("15 REGENBOGEN RASEREI") +#define TEXT_MENU_BITDW_DE _(" BOWSERS SCHATTENWELT") +#define TEXT_MENU_BITFS_DE _(" BOWSERS LAVASEE") +#define TEXT_MENU_BITS_DE _(" BOWSERS LUFTSCHLOSS") +#define TEXT_MENU_PSS_DE _(" TOADSTOOLS RUTSCHBAHN") +#define TEXT_MENU_COTMC_DE _(" GRÜNER SCHALTERPALAST") +#define TEXT_MENU_TOTWC_DE _(" ROTER SCHALTERPALAST") +#define TEXT_MENU_VCUTM_DE _(" BLAUER SCHALTERPALAST") +#define TEXT_MENU_WMOTR_DE _(" REGENBOGEN FEUERWERK") +#define TEXT_MENU_SA_DE _(" VERSTECKTES AQUARIUM") +#define TEXT_MENU_NONE_DE _("") +#define TEXT_MENU_STARS_DE _(" GEHEIME STERNE") #endif #endif diff --git a/include/types.h b/include/types.h index a66afef..ab289fc 100644 --- a/include/types.h +++ b/include/types.h @@ -7,6 +7,18 @@ #include #include "macros.h" + +// Certain functions are marked as having return values, but do not +// actually return a value. This causes undefined behavior, which we'd rather +// avoid on modern GCC. This only impacts -O2 and can matter for both the function +// itself and functions that call it. +#ifdef AVOID_UB + #define BAD_RETURN(cmd) void +#else + #define BAD_RETURN(cmd) cmd +#endif + + struct Controller { /*0x00*/ s16 rawStickX; // @@ -233,16 +245,16 @@ struct Surface struct MarioBodyState { /*0x00*/ u32 action; - /*0x04*/ s8 capState; + /*0x04*/ s8 capState; /// see MarioCapGSCId /*0x05*/ s8 eyeState; /*0x06*/ s8 handState; - /*0x07*/ s8 unk07; + /*0x07*/ s8 wingFlutter; /// whether Mario's wing cap wings are fluttering /*0x08*/ s16 modelState; /*0x0A*/ s8 grabPos; - /*0x0B*/ u8 unk0B; - /*0x0C*/ Vec3s unkC; - /*0x12*/ Vec3s unk12; - /*0x18*/ Vec3f unk18; + /*0x0B*/ u8 punchState; /// 2 bits for type of punch, 6 bits for punch animation timer + /*0x0C*/ Vec3s torsoAngle; + /*0x12*/ Vec3s headAngle; + /*0x18*/ Vec3f heldObjLastPosition; /// also known as HOLP u8 padding[4]; }; diff --git a/levels/bbh/script.c b/levels/bbh/script.c index 6895663..9c400b6 100644 --- a/levels/bbh/script.c +++ b/levels/bbh/script.c @@ -33,7 +33,7 @@ static const LevelScript script_func_local_2[] = { OBJECT(/*model*/ MODEL_BBH_MOVING_BOOKSHELF, /*pos*/ -1994, 819, 213, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvHauntedBookshelf), OBJECT(/*model*/ MODEL_BBH_MESH_ELEVATOR, /*pos*/ -2985, -205, 5400, /*angle*/ 0, -45, 0, /*behParam*/ 0x00000000, /*beh*/ bhvMeshElevator), OBJECT(/*model*/ MODEL_BBH_MERRY_GO_ROUND, /*pos*/ -205, -2560, 205, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvMerryGoRound), - OBJECT(/*model*/ MODEL_NONE, /*pos*/ 2200, 819, -800, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvCoffinManager), + OBJECT(/*model*/ MODEL_NONE, /*pos*/ 2200, 819, -800, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvCoffinSpawner), RETURN(), }; diff --git a/levels/ending/geo.c b/levels/ending/geo.c index fafda47..bb76634 100644 --- a/levels/ending/geo.c +++ b/levels/ending/geo.c @@ -19,6 +19,9 @@ const GeoLayout ending_geo_000050[] = { GEO_OPEN_NODE(), GEO_NODE_ORTHO(100), GEO_OPEN_NODE(), +#ifdef VERSION_EU + GEO_BACKGROUND_COLOR(0x0001), +#endif GEO_ASM(0, geo_exec_cake_end_screen), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), diff --git a/levels/intro/geo.c b/levels/intro/geo.c index e9fca85..7fbee0c 100644 --- a/levels/intro/geo.c +++ b/levels/intro/geo.c @@ -57,7 +57,7 @@ const GeoLayout intro_geo_00035C[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM(45, 128, 16384), GEO_OPEN_NODE(), - GEO_ASM(2, Geo18_802764B0), + GEO_ASM(2, geo_draw_mario_head_goddard), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), @@ -79,7 +79,7 @@ const GeoLayout intro_geo_0003B8[] = { GEO_OPEN_NODE(), GEO_CAMERA_FRUSTUM(45, 128, 16384), GEO_OPEN_NODE(), - GEO_ASM(3, Geo18_802764B0), + GEO_ASM(3, geo_draw_mario_head_goddard), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), diff --git a/levels/menu/header.h b/levels/menu/header.h index f072277..170c16c 100644 --- a/levels/menu/header.h +++ b/levels/menu/header.h @@ -39,6 +39,11 @@ extern const Gfx dl_menu_texture_course_upper[]; extern const Gfx dl_menu_texture_niveau_upper[]; extern const Gfx dl_menu_texture_kurs_upper[]; extern const Collision main_menu_seg7_collision[]; +#ifdef VERSION_EU +extern const u8 eu_course_strings_en_table[]; +extern const u8 eu_course_strings_fr_table[]; +extern const u8 eu_course_strings_de_table[]; +#endif // script extern const LevelScript level_main_menu_entry_1[]; diff --git a/levels/menu/leveldata.c b/levels/menu/leveldata.c index e529278..4ccfea8 100644 --- a/levels/menu/leveldata.c +++ b/levels/menu/leveldata.c @@ -6,7 +6,9 @@ #include "macro_preset_names.h" #include "special_preset_names.h" #include "textures.h" - +#ifdef VERSION_EU +#include "text_strings.h" +#endif #include "make_const_nonconst.h" // 0x07000000 - 0x07000018 @@ -1777,6 +1779,8 @@ const Gfx dl_menu_rgba16_wood_course[] = { gsDPSetRenderMode(G_RM_AA_TEX_EDGE, G_RM_AA_TEX_EDGE2), #ifdef VERSION_EU gsSPEndDisplayList(), +}; +const Gfx dl_menu_rgba16_wood_course_end[] = { #else gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, texture_menu_course_upper), #endif @@ -1835,3 +1839,23 @@ const Collision main_menu_seg7_collision[] = { COL_TRI_STOP(), COL_END(), }; + +#ifdef VERSION_EU + +// Duplicate course name tables; the main menu needs all languages loaded at +// once since it switches language, so the copies in segment 19 aren't good +// enough. + +#define COURSE_TABLE eu_course_strings_en_table +#include "text/us/define_courses.inc.c" +#undef COURSE_TABLE + +#define COURSE_TABLE eu_course_strings_fr_table +#include "text/fr/define_courses.inc.c" +#undef COURSE_TABLE + +#define COURSE_TABLE eu_course_strings_de_table +#include "text/de/define_courses.inc.c" +#undef COURSE_TABLE + +#endif diff --git a/levels/scripts.c b/levels/scripts.c index 9ab97aa..1a94174 100644 --- a/levels/scripts.c +++ b/levels/scripts.c @@ -230,7 +230,7 @@ const LevelScript script_func_global_5[] = { const LevelScript script_func_global_6[] = { LOAD_MODEL_FROM_GEO(MODEL_POKEY_HEAD, pokey_head_geo), LOAD_MODEL_FROM_GEO(MODEL_POKEY_BODY_PART, pokey_body_part_geo), - LOAD_MODEL_FROM_GEO(MODEL_TORNADO, tornado_seg5_geo_05014630), + LOAD_MODEL_FROM_GEO(MODEL_TWEESTER, tweester_geo), LOAD_MODEL_FROM_GEO(MODEL_KLEPTO, klepto_geo), LOAD_MODEL_FROM_GEO(MODEL_EYEROK_LEFT_HAND, eyerok_left_hand_geo), LOAD_MODEL_FROM_GEO(MODEL_EYEROK_RIGHT_HAND, eyerok_right_hand_geo), diff --git a/levels/sl/script.c b/levels/sl/script.c index dc4bc57..ea90a9f 100644 --- a/levels/sl/script.c +++ b/levels/sl/script.c @@ -15,6 +15,7 @@ #include "make_const_nonconst.h" #include "levels/sl/header.h" + static const LevelScript script_func_local_1[] = { OBJECT_WITH_ACTS(/*model*/ MODEL_STAR, /*pos*/ 700, 4500, 690, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvStar, /*acts*/ ALL_ACTS), OBJECT_WITH_ACTS(/*model*/ MODEL_STAR, /*pos*/ 4350, 1350, 4350, /*angle*/ 0, 0, 0, /*behParam*/ 0x02000000, /*beh*/ bhvStar, /*acts*/ ALL_ACTS), diff --git a/levels/ssl/script.c b/levels/ssl/script.c index 4497751..684dc9b 100644 --- a/levels/ssl/script.c +++ b/levels/ssl/script.c @@ -24,11 +24,11 @@ static const LevelScript script_func_local_2[] = { OBJECT(/*model*/ MODEL_SSL_TOX_BOX, /*pos*/ -1284, 0, -5895, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvToxBox), OBJECT(/*model*/ MODEL_SSL_TOX_BOX, /*pos*/ 1283, 0, -4865, /*angle*/ 0, 0, 0, /*behParam*/ 0x00010000, /*beh*/ bhvToxBox), OBJECT(/*model*/ MODEL_SSL_TOX_BOX, /*pos*/ 4873, 0, -3335, /*angle*/ 0, 0, 0, /*behParam*/ 0x00020000, /*beh*/ bhvToxBox), - OBJECT(/*model*/ MODEL_TORNADO, /*pos*/ -3600, -200, 2940, /*angle*/ 0, 0, 0, /*behParam*/ 0x00120000, /*beh*/ bhvTornado), - OBJECT_WITH_ACTS(/*model*/ MODEL_TORNADO, /*pos*/ 1017, -200, 3832, /*angle*/ 0, 0, 0, /*behParam*/ 0x00190000, /*beh*/ bhvTornado, /*acts*/ ACT_4 | ACT_5 | ACT_6), - OBJECT_WITH_ACTS(/*model*/ MODEL_TORNADO, /*pos*/ 3066, -200, 400, /*angle*/ 0, 0, 0, /*behParam*/ 0x00190000, /*beh*/ bhvTornado, /*acts*/ ACT_4 | ACT_5 | ACT_6), - OBJECT_WITH_ACTS(/*model*/ MODEL_KLEPTO, /*pos*/ 2200, 1174, -2820, /*angle*/ 0, 0, 0, /*behParam*/ 0x00010000, /*beh*/ bhvKlepto, /*acts*/ ACT_1), - OBJECT_WITH_ACTS(/*model*/ MODEL_KLEPTO, /*pos*/ -5963, 573, -4784, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvKlepto, /*acts*/ ACT_2 | ACT_3 | ACT_4 | ACT_5 | ACT_6), + OBJECT(/*model*/ MODEL_TWEESTER, /*pos*/ -3600, -200, 2940, /*angle*/ 0, 0, 0, /*behParam*/ 0x00120000, /*beh*/ bhvTweester), + OBJECT_WITH_ACTS(/*model*/ MODEL_TWEESTER, /*pos*/ 1017, -200, 3832, /*angle*/ 0, 0, 0, /*behParam*/ 0x00190000, /*beh*/ bhvTweester, /*acts*/ ACT_4 | ACT_5 | ACT_6), + OBJECT_WITH_ACTS(/*model*/ MODEL_TWEESTER, /*pos*/ 3066, -200, 400, /*angle*/ 0, 0, 0, /*behParam*/ 0x00190000, /*beh*/ bhvTweester, /*acts*/ ACT_4 | ACT_5 | ACT_6), + OBJECT_WITH_ACTS(/*model*/ MODEL_KLEPTO, /*pos*/ 2200, 1174, -2820, /*angle*/ 0, 0, 0, /*behParam*/ 0x00010000, /*beh*/ bhvKlepto, /*acts*/ ACT_1), + OBJECT_WITH_ACTS(/*model*/ MODEL_KLEPTO, /*pos*/ -5963, 573, -4784, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvKlepto, /*acts*/ ACT_2 | ACT_3 | ACT_4 | ACT_5 | ACT_6), RETURN(), }; diff --git a/lib/PR/boot/F3D_boot_eu.bin b/lib/PR/boot/F3D_boot_eu.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eb44776299c793a87e5dba32323874a7c7993ba GIT binary patch literal 204 zcmaKmF%H5o6hqxKQq!SI1`r@s=nEFcATcmnJpvOu2O)w1h90U%;R0NN(2&mj!C!i^ zY}e2$DeTa1;H0!ysa)U#;LU({2WpR5h#!pCK-={3f?+s@}2LlI#1A{^X1LK)9XBZg&{|Bl7LMY9|fC?F*W`N8AVK5)47R(3J zKo*Quc75Lh96Ltuqyh-iwy3ULF0 z6(A^FBitZd0;FSveS~#{E(o0vS|ZdV6d)`h#3Q~({D6dngpOp2c#HS~fe4`8NC0B@ zdk!9mZ;@mgz;;6f96-*X184x+0m5+50AvAiJzM|>gP;ObeGeGr|1+>KFn~Ob;c--@ z6!C(B0~CV86~a=BiZk=`tQ3s&3|w>+3`}$l40SEd7=qnB6++ES6x`h+K*~Z~9eu47 zf)yO|Qh*xr^K^i0=ft8S9R&{s=Zw_6bR7k61)tL5l2o8jkb-Z1eo?B9f}cV_etu4B zrH+E5LU2)LUS?Thabg}9*xk$uj2jp)Fn(YXU@~9|U@Bmmz_fws0;2`<2Nnhv0pNfK$0t(;3#)A1V%$(Gz5lV2mk;t5_G)) literal 0 HcmV?d00001 diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s index fdc36c8..e042bc3 100644 --- a/lib/asm/__osExceptionPreamble.s +++ b/lib/asm/__osExceptionPreamble.s @@ -15,6 +15,7 @@ glabel __osExceptionPreamble glabel __osException +.ifndef VERSION_EU lui $k0, %hi(gInterruptedThread) # $k0, 0x8036 addiu $k0, %lo(gInterruptedThread) # addiu $k0, $k0, 0x5f40 sd $at, 0x20($k0) @@ -28,6 +29,7 @@ glabel __osException sd $t2, 0x68($k0) sw $zero, 0x18($k0) mfc0 $t0, $13 + andi $t1, $t0, 0x7c li $t2, 0 bne $t1, $t2, .L80326750 @@ -52,6 +54,7 @@ glabel __osException lui $at, %hi(D_80334934) # $at, 0x8033 sw $zero, %lo(D_80334934)($at) lui $at, %hi(D_80334938) # $at, 0x8033 + move $t0, $k0 sw $zero, %lo(D_80334938)($at) lui $k0, %hi(D_803348A0) # $k0, 0x8033 @@ -95,7 +98,43 @@ glabel __osException sd $sp, 0xf0($k0) sd $fp, 0xf8($k0) sd $ra, 0x100($k0) +.ifndef VERSION_EU sd $t0, 0x110($k0) +.else + beqz $t1, .L802F3A18 + sd $t0, 0x110($k0) + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t0, ($t0) + li $at, -1 + xor $t0, $t0, $at + lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff + andi $t0, $t0, 0xff00 + ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff + or $t1, $t1, $t0 + and $k1, $k1, $at + or $k1, $k1, $t1 + sw $k1, 0x118($k0) +.L802F3A18: + lui $t1, %hi(D_A430000C) # $t1, 0xa430 + lw $t1, %lo(D_A430000C)($t1) + beqz $t1, .L802F3A50 + nop + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t0, ($t0) + lw $t4, 0x128($k0) + li $at, -1 + srl $t0, $t0, 0x10 + xor $t0, $t0, $at + andi $t0, $t0, 0x3f + and $t0, $t0, $t4 + or $t1, $t1, $t0 +.L802F3A50: + sw $t1, 0x128($k0) +.endif + + mfc0 $t0, $14 sw $t0, 0x11c($k0) lw $t0, 0x18($k0) @@ -385,6 +424,365 @@ glabel L80326BE8 li $a0, 96 j __osDispatchThread nop +.else + lui $k0, %hi(gInterruptedThread) # $k0, 0x8033 + addiu $k0, %lo(gInterruptedThread) # addiu $k0, $k0, 0x6ce0 + sd $at, 0x20($k0) + mfc0 $k1, $12 + sw $k1, 0x118($k0) + li $at, -4 + and $k1, $k1, $at + mtc0 $k1, $12 + sd $t0, 0x58($k0) + sd $t1, 0x60($k0) + sd $t2, 0x68($k0) + sw $zero, 0x18($k0) + mfc0 $t0, $13 + move $t0, $k0 + lui $k0, %hi(D_803348A0) # $k0, 0x8030 + lw $k0, %lo(D_803348A0)($k0) + ld $t1, 0x20($t0) + sd $t1, 0x20($k0) + ld $t1, 0x118($t0) + sd $t1, 0x118($k0) + ld $t1, 0x58($t0) + sd $t1, 0x58($k0) + ld $t1, 0x60($t0) + sd $t1, 0x60($k0) + ld $t1, 0x68($t0) + sd $t1, 0x68($k0) + lw $k1, 0x118($k0) + mflo $t0 + sd $t0, 0x108($k0) + mfhi $t0 + andi $t1, $k1, 0xff00 + sd $v0, 0x28($k0) + sd $v1, 0x30($k0) + sd $a0, 0x38($k0) + sd $a1, 0x40($k0) + sd $a2, 0x48($k0) + sd $a3, 0x50($k0) + sd $t3, 0x70($k0) + sd $t4, 0x78($k0) + sd $t5, 0x80($k0) + sd $t6, 0x88($k0) + sd $t7, 0x90($k0) + sd $s0, 0x98($k0) + sd $s1, 0xa0($k0) + sd $s2, 0xa8($k0) + sd $s3, 0xb0($k0) + sd $s4, 0xb8($k0) + sd $s5, 0xc0($k0) + sd $s6, 0xc8($k0) + sd $s7, 0xd0($k0) + sd $t8, 0xd8($k0) + sd $t9, 0xe0($k0) + sd $gp, 0xe8($k0) + sd $sp, 0xf0($k0) + sd $fp, 0xf8($k0) + sd $ra, 0x100($k0) + beqz $t1, .L802F3A18 + sd $t0, 0x110($k0) + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t0, ($t0) + li $at, -1 + xor $t0, $t0, $at + lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff + andi $t0, $t0, 0xff00 + ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff + or $t1, $t1, $t0 + and $k1, $k1, $at + or $k1, $k1, $t1 + sw $k1, 0x118($k0) +.L802F3A18: + lui $t1, %hi(D_A430000C) # $t1, 0xa430 + lw $t1, %lo(D_A430000C)($t1) + beqz $t1, .L802F3A50 + nop + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t0, ($t0) + lw $t4, 0x128($k0) + li $at, -1 + srl $t0, $t0, 0x10 + xor $t0, $t0, $at + andi $t0, $t0, 0x3f + and $t0, $t0, $t4 + or $t1, $t1, $t0 +.L802F3A50: + sw $t1, 0x128($k0) + mfc0 $t0, $14 + sw $t0, 0x11c($k0) + lw $t0, 0x18($k0) + beqz $t0, .L802F3AB4 + nop + cfc1 $t0, $31 + nop + sw $t0, 0x12c($k0) + sdc1 $f0, 0x130($k0) + sdc1 $f2, 0x138($k0) + sdc1 $f4, 0x140($k0) + sdc1 $f6, 0x148($k0) + sdc1 $f8, 0x150($k0) + sdc1 $f10, 0x158($k0) + sdc1 $f12, 0x160($k0) + sdc1 $f14, 0x168($k0) + sdc1 $f16, 0x170($k0) + sdc1 $f18, 0x178($k0) + sdc1 $f20, 0x180($k0) + sdc1 $f22, 0x188($k0) + sdc1 $f24, 0x190($k0) + sdc1 $f26, 0x198($k0) + sdc1 $f28, 0x1a0($k0) + sdc1 $f30, 0x1a8($k0) +.L802F3AB4: + mfc0 $t0, $13 + sw $t0, 0x120($k0) + li $t1, 2 + sh $t1, 0x10($k0) + andi $t1, $t0, 0x7c + li $t2, 36 + beq $t1, $t2, .L802F3D90 + nop + li $t2, 44 + beq $t1, $t2, .L80326CCC + nop + li $t2, 0 + bne $t1, $t2, .L80326BE8 + nop + and $s0, $k1, $t0 +.L802F3AF0: + andi $t1, $s0, 0xff00 + srl $t2, $t1, 0xc + bnez $t2, .L802F3B08 + nop + srl $t2, $t1, 8 + addi $t2, $t2, 0x10 +.L802F3B08: + lui $at, %hi(D_80338610) + addu $at, $at, $t2 + lbu $t2, %lo(D_80338610)($at) + lui $at, %hi(jtbl_80338630) + addu $at, $at, $t2 + lw $t2, %lo(jtbl_80338630)($at) + jr $t2 + nop + li $at, -8193 + b .L802F3AF0 + and $s0, $s0, $at + li $at, -16385 + b .L802F3AF0 + and $s0, $s0, $at +glabel L80326964 #probably not right... + mfc0 $t1, $11 + mtc0 $t1, $11 + jal send_mesg + li $a0, 24 + lui $at, (0xFFFF7FFF >> 16) # lui $at, 0xffff + ori $at, (0xFFFF7FFF & 0xFFFF) # ori $at, $at, 0x7fff + b .L802F3AF0 + and $s0, $s0, $at +glabel L80326984 #possibly wrong + li $at, -2049 + and $s0, $s0, $at + li $t2, 4 + lui $at, %hi(D_80334920) + addu $at, $at, $t2 + lw $t2, %lo(D_80334920)($at) + lui $sp, %hi(D_80365E40) # $sp, 0x8033 #.bss stack for D_802F4380 + addiu $sp, %lo(D_80365E40) # addiu $sp, $sp, 0x5c20 + li $a0, 16 + beqz $t2, .L802F3BA4 + addiu $sp, $sp, 0xff0 + jalr $t2 + nop + beqz $v0, .L802F3BA4 + nop + b .L802F3DA8 + nop +.L802F3BA4: + jal send_mesg + nop + b .L802F3AF0 + nop +glabel L803269B8 + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t0, ($t0) + lui $s1, %hi(D_A4300008) # $s1, 0xa430 + lw $s1, %lo(D_A4300008)($s1) + srl $t0, $t0, 0x10 + and $s1, $s1, $t0 + andi $t1, $s1, 1 + beqz $t1, .L802F3C24 + nop + lui $t4, %hi(D_A4040010) # $t4, 0xa404 + lw $t4, %lo(D_A4040010)($t4) + li $t1, 8 + lui $at, %hi(D_A4040010) # $at, 0xa404 + andi $t4, $t4, 0x300 + andi $s1, $s1, 0x3e + beqz $t4, .L802F3C14 + sw $t1, %lo(D_A4040010)($at) + jal send_mesg + li $a0, 32 + beqz $s1, .L802F3CE8 + nop + b .L802F3C24 + nop +.L802F3C14: + jal send_mesg + li $a0, 88 + beqz $s1, .L802F3CE8 + nop +.L802F3C24: + andi $t1, $s1, 8 + beqz $t1, .L802F3C48 + lui $at, %hi(D_A4400010) # $at, 0xa440 + andi $s1, $s1, 0x37 + sw $zero, %lo(D_A4400010)($at) + jal send_mesg + li $a0, 56 + beqz $s1, .L802F3CE8 + nop +.L802F3C48: + andi $t1, $s1, 4 + beqz $t1, .L802F3C74 + nop + li $t1, 1 + lui $at, %hi(D_A450000C) # $at, 0xa450 + andi $s1, $s1, 0x3b + sw $t1, %lo(D_A450000C)($at) + jal send_mesg + li $a0, 48 + beqz $s1, .L802F3CE8 + nop +.L802F3C74: + andi $t1, $s1, 2 + beqz $t1, .L802F3C98 + lui $at, %hi(D_A4800018) # $at, 0xa480 + andi $s1, $s1, 0x3d + sw $zero, %lo(D_A4800018)($at) + jal send_mesg + li $a0, 40 + beqz $s1, .L802F3CE8 + nop +.L802F3C98: + andi $t1, $s1, 0x10 + beqz $t1, .L802F3CC4 + nop + li $t1, 2 + lui $at, %hi(D_A4600010) # $at, 0xa460 + andi $s1, $s1, 0x2f + sw $t1, %lo(D_A4600010)($at) + jal send_mesg + li $a0, 64 + beqz $s1, .L802F3CE8 + nop +.L802F3CC4: + andi $t1, $s1, 0x20 + beqz $t1, .L802F3CE8 + nop + li $t1, 2048 + lui $at, 0xa430 + andi $s1, $s1, 0x1f + sw $t1, ($at) + jal send_mesg + li $a0, 72 +.L802F3CE8: + li $at, -1025 + b .L802F3AF0 + and $s0, $s0, $at +glabel L80326AE8 + lw $k1, 0x118($k0) + li $at, -4097 + lui $t1, %hi(D_80334808) # $t1, 0x8030 + and $k1, $k1, $at + sw $k1, 0x118($k0) + addiu $t1, %lo(D_80334808) # addiu $t1, $t1, 0x2088 + lw $t2, ($t1) + beqz $t2, .L802F3D20 + li $at, -4097 + b .L802F3DA8 + and $s0, $s0, $at +.L802F3D20: + li $t2, 1 + sw $t2, ($t1) + jal send_mesg + li $a0, 112 + lui $t2, %hi(D_80334898) # $t2, 0x8030 + lw $t2, %lo(D_80334898)($t2) + li $at, -4097 + and $s0, $s0, $at + lw $k1, 0x118($t2) + and $k1, $k1, $at + b .L802F3DA8 + sw $k1, 0x118($t2) +glabel L80326B44 + li $at, -513 + and $t0, $t0, $at + mtc0 $t0, $13 + jal send_mesg + li $a0, 8 + li $at, -513 + b .L802F3AF0 + and $s0, $s0, $at +glabel L80326B64 + li $at, -257 + and $t0, $t0, $at + mtc0 $t0, $13 + jal send_mesg + li $a0, 0 + li $at, -257 + b .L802F3AF0 + and $s0, $s0, $at +.L802F3D90: + li $t1, 1 + sh $t1, 0x12($k0) + jal send_mesg + li $a0, 80 + b .L802F3DA8 + nop +.L802F3DA8: +glabel L80326B9C + lui $t2, %hi(D_80334898) # $t2, 0x8030 + lw $t2, %lo(D_80334898)($t2) + lw $t1, 4($k0) + lw $t3, 4($t2) + slt $at, $t1, $t3 + beqz $at, .L80326BD0 + nop + lui $a0, %hi(D_80334898) # $a0, 0x8030 + move $a1, $k0 + jal __osEnqueueThread + addiu $a0, %lo(D_80334898) # addiu $a0, $a0, 0x2ef8 + j __osDispatchThread + nop + +.L80326BD0: + lui $t1, %hi(D_80334898) # $t1, 0x8030 + addiu $t1, %lo(D_80334898) # addiu $t1, $t1, 0x2ef8 + lw $t2, ($t1) + sw $t2, ($k0) + j __osDispatchThread + sw $k0, ($t1) + +.L80326BE8: +glabel L80326BE8 + lui $at, %hi(D_803348A4) # $at, 0x8030 + sw $k0, %lo(D_803348A4)($at) + li $t1, 1 + sh $t1, 0x10($k0) + li $t1, 2 + sh $t1, 0x12($k0) + mfc0 $t2, $8 + sw $t2, 0x124($k0) + jal send_mesg + li $a0, 96 + j __osDispatchThread + nop +.endif glabel send_mesg lui $t2, %hi(D_80363830) # $t2, 0x8036 @@ -470,7 +868,11 @@ glabel __osEnqueueAndYield sd $sp, 0xf0($a1) sd $fp, 0xf8($a1) sd $ra, 0x100($a1) +.ifdef VERSION_EU + beqz $k1, .L802F3F7C +.else beqz $k1, .L80326D70 +.endif sw $ra, 0x11c($a1) cfc1 $k1, $31 sdc1 $f20, 0x180($a1) @@ -480,9 +882,49 @@ glabel __osEnqueueAndYield sdc1 $f28, 0x1a0($a1) sdc1 $f30, 0x1a8($a1) sw $k1, 0x12c($a1) + +.ifdef VERSION_EU +.L802F3F7C: +/* 0B377C 802F3F7C 8CBB0118 */ lw $k1, 0x118($a1) +/* 0B3780 802F3F80 3369FF00 */ andi $t1, $k1, 0xff00 +/* 0B3784 802F3F84 1120000D */ beqz $t1, .L802F3FBC +/* 0B3788 802F3F88 00000000 */ nop +/* 0B378C 802F3F8C 3C088030 */ lui $t0, %hi(D_8030208C) # $t0, 0x8030 +/* 0B3790 802F3F90 2508208C */ addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c +/* 0B3794 802F3F94 8D080000 */ lw $t0, ($t0) +/* 0B3798 802F3F98 2401FFFF */ li $at, -1 +/* 0B379C 802F3F9C 01014026 */ xor $t0, $t0, $at +/* 0B37A0 802F3FA0 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff +/* 0B37A4 802F3FA4 3108FF00 */ andi $t0, $t0, 0xff00 +/* 0B37A8 802F3FA8 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff +/* 0B37AC 802F3FAC 01284825 */ or $t1, $t1, $t0 +/* 0B37B0 802F3FB0 0361D824 */ and $k1, $k1, $at +/* 0B37B4 802F3FB4 0369D825 */ or $k1, $k1, $t1 +/* 0B37B8 802F3FB8 ACBB0118 */ sw $k1, 0x118($a1) +.L802F3FBC: +/* 0B37BC 802F3FBC 3C1BA430 */ lui $k1, %hi(D_A430000C) # $k1, 0xa430 +/* 0B37C0 802F3FC0 8F7B000C */ lw $k1, %lo(D_A430000C)($k1) +/* 0B37C4 802F3FC4 1360000B */ beqz $k1, .L802F3FF4 +/* 0B37C8 802F3FC8 00000000 */ nop +/* 0B37CC 802F3FCC 3C1A8030 */ lui $k0, %hi(D_8030208C) # $k0, 0x8030 +/* 0B37D0 802F3FD0 275A208C */ addiu $k0, %lo(D_8030208C) # addiu $k0, $k0, 0x208c +/* 0B37D4 802F3FD4 8F5A0000 */ lw $k0, ($k0) +/* 0B37D8 802F3FD8 8CA80128 */ lw $t0, 0x128($a1) +/* 0B37DC 802F3FDC 2401FFFF */ li $at, -1 +/* 0B37E0 802F3FE0 001AD402 */ srl $k0, $k0, 0x10 +/* 0B37E4 802F3FE4 0341D026 */ xor $k0, $k0, $at +/* 0B37E8 802F3FE8 335A003F */ andi $k0, $k0, 0x3f +/* 0B37EC 802F3FEC 0348D024 */ and $k0, $k0, $t0 +/* 0B37F0 802F3FF0 037AD825 */ or $k1, $k1, $k0 +.L802F3FF4: +.endif + + .L80326D70: +.ifndef VERSION_EU lui $k1, %hi(D_A430000C) # $k1, 0xa430 lw $k1, %lo(D_A430000C)($k1) +.endif beqz $a0, .L80326D88 sw $k1, 0x128($a1) jal __osEnqueueThread @@ -530,6 +972,22 @@ glabel __osDispatchThread li $t0, 4 sh $t0, 0x10($v0) move $k0, $v0 + +.ifdef VERSION_EU + +/* 0B3884 802F4084 3C088030 */ lui $t0, %hi(D_8030208C) # $t0, 0x8030 +/* 0B3888 802F4088 8F5B0118 */ lw $k1, 0x118($k0) +/* 0B388C 802F408C 2508208C */ addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c +/* 0B3890 802F4090 8D080000 */ lw $t0, ($t0) +/* 0B3894 802F4094 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff +/* 0B3898 802F4098 3369FF00 */ andi $t1, $k1, 0xff00 +/* 0B389C 802F409C 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff +/* 0B38A0 802F40A0 3108FF00 */ andi $t0, $t0, 0xff00 +/* 0B38A4 802F40A4 01284824 */ and $t1, $t1, $t0 +/* 0B38A8 802F40A8 0361D824 */ and $k1, $k1, $at +/* 0B38AC 802F40AC 0369D825 */ or $k1, $k1, $t1 +/* 0B38B0 802F40B0 409B6000 */ mtc0 $k1, $12 +.endif .L80326E08: ld $k1, 0x108($k0) ld $at, 0x20($k0) @@ -566,8 +1024,10 @@ glabel __osDispatchThread ld $ra, 0x100($k0) lw $k1, 0x11c($k0) mtc0 $k1, $14 +.ifndef VERSION_EU lw $k1, 0x118($k0) mtc0 $k1, $12 +.endif lw $k1, 0x18($k0) beqz $k1, .L80326EF0 nop @@ -591,6 +1051,13 @@ glabel __osDispatchThread ldc1 $f30, 0x1a8($k0) .L80326EF0: lw $k1, 0x128($k0) +.ifdef VERSION_EU +/* 0B3998 802F4198 3C1A8030 */ lui $k0, %hi(D_8030208C) # $k0, 0x8030 +/* 0B399C 802F419C 275A208C */ addiu $k0, %lo(D_8030208C) # addiu $k0, $k0, 0x208c +/* 0B39A0 802F41A0 8F5A0000 */ lw $k0, ($k0) +/* 0B39A4 802F41A4 001AD402 */ srl $k0, $k0, 0x10 +/* 0B39A8 802F41A8 037AD824 */ and $k1, $k1, $k0 +.endif sll $k1, $k1, 1 lui $k0, %hi(D_803386D0) # $k0, 0x8034 addiu $k0, %lo(D_803386D0) # addiu $k0, $k0, -0x7930 @@ -624,8 +1091,6 @@ glabel D_80334938 .word 0 .word 0 - - .section .rodata glabel D_80338610 @@ -638,8 +1103,13 @@ glabel jtbl_80338630 .word L803269B8 .word L80326984 .word L80326AE8 +.ifdef VERSION_EU + .word 0x802f3b28 + .word 0x802f3b34 +.else .word L80326BE8 .word L80326BE8 +.endif .word L80326964 .word 0 .word 0 diff --git a/lib/asm/__os_eu_802ef550.s b/lib/asm/__os_eu_802ef550.s new file mode 100644 index 0000000..99b328e --- /dev/null +++ b/lib/asm/__os_eu_802ef550.s @@ -0,0 +1,22 @@ +.set noreorder # don't insert nops after branches +.set gp=64 +.set noat + +.include "macros.inc" + + +.section .text, "ax" +# cache related +glabel __os_eu_802ef550 + lui $t0,0x8000 + li $t2,0x2000 + addu $t1,$t0,$t2 + addiu $t1,$t1,-0x10 +.L: cache 0x1,0($t0) + sltu $at,$t0,$t1 + bnez $at,.L + addiu $t0,$t0,0x10 + jr $ra + nop + nop + nop diff --git a/lib/asm/osSetIntMask.s b/lib/asm/osSetIntMask.s index b6d147f..ccce609 100644 --- a/lib/asm/osSetIntMask.s +++ b/lib/asm/osSetIntMask.s @@ -9,14 +9,38 @@ .section .text, "ax" glabel osSetIntMask +.ifndef VERSION_EU mfc0 $t1, $12 andi $v0, $t1, 0xff01 +.else + mfc0 $t4, $12 + andi $v0, $t4, 0xff01 + lui $t0, %hi(D_8030208C) # $t0, 0x8030 + addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c + lw $t3, ($t0) + li $at, -1 + xor $t0, $t3, $at + andi $t0, $t0, 0xff00 + or $v0, $v0, $t0 +.endif lui $t2, %hi(MI_INTR_MASK_REG) # $t2, 0xa430 lw $t2, %lo(MI_INTR_MASK_REG)($t2) +.ifdef VERSION_EU + beqz $t2, .L80200074 + srl $t1, $t3, 0x10 + li $at, -1 + xor $t1, $t1, $at + andi $t1, $t1, 0x3f + or $t2, $t2, $t1 +.L80200074: +.endif sll $t2, $t2, 0x10 or $v0, $v0, $t2 lui $at, 0x3f and $t0, $a0, $at +.ifdef VERSION_EU + and $t0, $t0, $t3 +.endif srl $t0, $t0, 0xf lui $t2, %hi(D_803386D0) addu $t2, $t2, $t0 @@ -24,11 +48,21 @@ glabel osSetIntMask lui $at, %hi(MI_INTR_MASK_REG) # $at, 0xa430 sw $t2, %lo(MI_INTR_MASK_REG)($at) andi $t0, $a0, 0xff01 +.ifdef VERSION_EU + andi $t1, $t3, 0xff00 + and $t0, $t0, $t1 +.endif lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff +.ifndef VERSION_EU and $t1, $t1, $at or $t1, $t1, $t0 mtc0 $t1, $12 +.else + and $t4, $t4, $at + or $t4, $t4, $t0 + mtc0 $t4, $12 +.endif nop nop jr $ra diff --git a/lib/asm/parameters.s b/lib/asm/parameters.s new file mode 100644 index 0000000..d5106bf --- /dev/null +++ b/lib/asm/parameters.s @@ -0,0 +1,18 @@ +.macro gsymbol sym addr +.global \sym +.set \sym, \addr +.ifndef VERSION_JP +nop +nop +.endif +.endm + +.text +gsymbol osTvType 0x80000300 +gsymbol osRomType 0x80000304 +gsymbol osRomBase 0x80000308 +gsymbol osResetType 0x8000030C +gsymbol osCiCId 0x80000310 +gsymbol osVersion 0x80000314 +gsymbol osMemSize 0x80000318 +gsymbol osAppNmiBuffer 0x8000031C diff --git a/lib/rsp.s b/lib/rsp.s index dddc6d2..a1284e1 100644 --- a/lib/rsp.s +++ b/lib/rsp.s @@ -5,7 +5,12 @@ .balign 16 glabel rspF3DBootStart + .ifndef VERSION_EU .incbin "lib/PR/boot/F3D_boot.bin" + .else + .incbin "lib/PR/boot/F3D_boot_eu.bin" + .half 0 + .endif glabel rspF3DBootEnd .balign 16 @@ -131,7 +136,11 @@ glabel rspS2DEXEnd .ifndef F3DEX_GBI_SHARED /* Use regular Fast3D data (default) */ glabel rspF3DDataStart .ifndef F3D_OLD /* OS 2.0H (J2 and IQ) */ + .ifdef VERSION_EU + .incbin "lib/PR/f3d/new/F3D_data_EU.bin" + .else .incbin "lib/PR/f3d/new/F3D_data.bin" + .endif .else /* OS 2.0D (US and JP) */ .incbin "lib/PR/f3d/old/F3D_data.bin" .endif diff --git a/lib/src/D_802F4380.c b/lib/src/D_802F4380.c new file mode 100644 index 0000000..4da7dd2 --- /dev/null +++ b/lib/src/D_802F4380.c @@ -0,0 +1,147 @@ +#include "libultra_internal.h" +#include "hardware.h" +#include "new_func.h" +#include "macros.h" +#ifdef VERSION_EU +u32 D_802F4380() { + u32 sp3c; + u32 sp38; + u32 sp34; + __OSTranxInfo *sp30; + __OSBlockInfo *sp2c; + u32 sp28; + UNUSED __OSBlockInfo *sp24; + if (!EU_D_80302090) { + return 0; + } + sp30 = &__osDiskHandle->transferInfo; + sp2c = &sp30->block[sp30->blockNum]; + sp38 = HW_REG(PI_STATUS_REG, u32); + if (sp38 & PI_STATUS_BUSY) { + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_RESET_CONTROLLER | PI_STATUS_CLEAR_INTR; + WAIT_ON_IOBUSY(sp38); + sp3c = HW_REG(ASIC_STATUS, u32); + if (sp3c & MECHANIC_INTERRUPT) { + WAIT_ON_IOBUSY(sp38); + HW_REG(ASIC_BM_CTL, u32) = sp30->bmCtlShadow | MECHANIC_INTERRUPT_RESET; + } + sp30->unk10 = 75; + func_802F4A20(); + return 1; + } + WAIT_ON_IOBUSY(sp38); + sp3c = HW_REG(ASIC_STATUS, u32); + if (sp3c & MECHANIC_INTERRUPT) { + WAIT_ON_IOBUSY(sp38); + HW_REG(ASIC_BM_CTL, u32) = sp30->bmCtlShadow | MECHANIC_INTERRUPT_RESET; + sp30->unk10 = 0; + return 0; + } + if (sp3c & BUFFER_MANAGER_ERROR) { + sp30->unk10 = 3; + func_802F4A20(); + return 1; + } + if (sp30->cmdType == 1) { + if ((sp3c & DATA_REQUEST) == 0) { + if (sp30->sectorNum + 1 != sp30->transferMode * 85) { + sp30->unk10 = 6; + func_802F4A20(); + return 1; + } + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLEAR_INTR; + D_8030208C |= 0x00100401; + sp30->unk10 = 0; + func_802F4B08(); + return 1; + } + sp2c->dramAddr = (void *) ((u32) sp2c->dramAddr + sp2c->sectorSize); + sp30->sectorNum += 1; + osEPiRawStartDma(__osDiskHandle, 1, 0x05000400, sp2c->dramAddr, sp2c->sectorSize); + return 1; + } + if (sp30->cmdType == 0) { + if (sp30->transferMode == 3) { + if ((s32)(sp2c->C1ErrNum + 17) < sp30->sectorNum) { + sp30->unk10 = 0; + func_802F4A20(); + return 1; + } + if ((sp3c & DATA_REQUEST) == 0) { + sp30->unk10 = 17; + func_802F4A20(); + return 1; + } + } else { + sp2c->dramAddr = (void *) ((u32) sp2c->dramAddr + sp2c->sectorSize); + } + sp34 = HW_REG(ASIC_BM_STATUS, u32); + if (((C1_SINGLE & sp34) && (C1_DOUBLE & sp34)) || (sp34 & MICRO_STATUS)) + { + if (sp2c->C1ErrNum > 3) { + if (sp30->transferMode != 3 || sp30->sectorNum > 0x52) { + sp30->unk10 = 17; + func_802F4A20(); + return 1; + } + } else { + sp28 = sp2c->C1ErrNum; + sp2c->C1ErrSector[sp28] = sp30->sectorNum + 1; + } + sp2c->C1ErrNum += 1; + } + if (sp3c & C2_TRANSFER) { + if (sp30->sectorNum != 87) { + sp30->unk10 = 6; + func_802F4A20(); + } + if (sp30->transferMode == 2 && sp30->blockNum == 0) { + sp30->blockNum = 1; + sp30->sectorNum = -1; + sp30->block[1].dramAddr = + (void *) ((u32) sp30->block[1].dramAddr - sp30->block[1].sectorSize); + } else { + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLEAR_INTR; + D_8030208C |= 0x00100401; + } + osEPiRawStartDma(__osDiskHandle, 0, 0x5000000, sp2c->C2Addr, sp2c->sectorSize * 4); + sp30->unk10 = 0; + return 1; + } + + if (sp30->sectorNum == -1 && sp30->transferMode == 2 && sp30->blockNum == 1) { + sp24 = &sp30->block[0]; + if (sp30->block[0].C1ErrNum == 0) { + if (((u32 *) sp30->block[0].C2Addr)[0] | ((u32 *) sp30->block[0].C2Addr)[1] + | ((u32 *) sp30->block[0].C2Addr)[2] | ((u32 *) sp30->block[0].C2Addr)[3]) { + sp30->unk10 = 6; + func_802F4A20(); + return 1; + } + } + sp30->unk10 = 0; + func_802F4B08(); + } + sp30->sectorNum += 1; + if (sp3c & DATA_REQUEST) { + if (sp30->sectorNum > 0x54) { + sp30->unk10 = 6; + func_802F4A20(); + return 1; + } + osEPiRawStartDma(__osDiskHandle, 0, 0x05000400, sp2c->dramAddr, sp2c->sectorSize); + sp30->unk10 = 0; + return 1; + } + if (sp30->sectorNum <= 0x54) { + sp30->unk10 = 6; + func_802F4A20(); + return 1; + } + return 1; + } + sp30->unk10 = 75; + func_802F4A20(); + return 1; +} +#endif diff --git a/lib/src/EU_D_802f4330.c b/lib/src/EU_D_802f4330.c new file mode 100644 index 0000000..a67673d --- /dev/null +++ b/lib/src/EU_D_802f4330.c @@ -0,0 +1,12 @@ +#include "libultra_internal.h" + +// an array of pointers to functions taking no arguments and returning u32... +// this is only referenced in the exception handler and here. this function is called with a0=1 and +// then the same memory address is loaded. it's definitely an array access though.. +extern u32 (*D_80334920[8])() ; + +void EU_D_802f4330(u32 a0, u32 a1(void)) { + register u32 int_disabled = __osDisableInt(); + D_80334920[a0] = a1; + __osRestoreInt(int_disabled); +} diff --git a/lib/src/_Ldtob.c b/lib/src/_Ldtob.c index f456802..3656bd4 100644 --- a/lib/src/_Ldtob.c +++ b/lib/src/_Ldtob.c @@ -99,9 +99,7 @@ void _Ldtob(printf_struct *args, u8 type) { if (exp > 0) { factor = 1; exp &= ~3; - n = exp; - - for (i = 0; n > 0; n >>= 1, i++) { + for (n = exp, i = 0; n > 0; n >>= 1, i++) { if ((n & 1) != 0) { factor *= D_80338670[i]; } diff --git a/lib/src/__osDevMgrMain.c b/lib/src/__osDevMgrMain.c index c45c17c..3cfe19b 100644 --- a/lib/src/__osDevMgrMain.c +++ b/lib/src/__osDevMgrMain.c @@ -1,5 +1,88 @@ #include "libultra_internal.h" - +#include "macros.h" +#if defined(VERSION_EU) +#include "new_func.h" +void __osDevMgrMain(void *args) { + OSIoMesg *sp44; + OSMesg sp40; + OSMesg sp3c; + s32 sp38; + OSMgrArgs *sp34; + UNUSED u32 sp30; + u32 sp2c; + __OSBlockInfo *sp28; + __OSTranxInfo *sp24; + sp30 = 0; + sp2c = 0; + sp44 = NULL; + sp38 = 0; + sp34 = (OSMgrArgs *) args; + while (1) { + osRecvMesg(sp34->unk08, (OSMesg) &sp44, OS_MESG_BLOCK); + if (sp44->piHandle != NULL && sp44->piHandle->type == 2 + && (sp44->piHandle->transferInfo.cmdType == 0 + || sp44->piHandle->transferInfo.cmdType == 1)) { + sp24 = &sp44->piHandle->transferInfo; + sp28 = &sp24->block[sp24->blockNum]; + sp24->sectorNum = -1; + if (sp24->transferMode != 3) { + sp28->dramAddr = (void *) ((u32) sp28->dramAddr - sp28->sectorSize); + } + if (sp24->transferMode == 2 && sp44->piHandle->transferInfo.cmdType == 0) + sp2c = 1; + else + sp2c = 0; + osRecvMesg(sp34->unk10, &sp3c, OS_MESG_BLOCK); + func_802F7140(0x00100401); // remove magic constant! + func_802F71A0(sp44->piHandle, 0x05000510, (sp24->bmCtlShadow | 0x80000000)); + while (1) { + osRecvMesg(sp34->unk0c, &sp40, OS_MESG_BLOCK); + sp30 = osSendMesg(sp44->hdr.retQueue, sp44, OS_MESG_NOBLOCK); + if (sp2c != 1 || sp44->piHandle->transferInfo.unk10 != 0) + break; + sp2c = 0; + } + osSendMesg(sp34->unk10, NULL, OS_MESG_NOBLOCK); + if (sp44->piHandle->transferInfo.blockNum == 1) + func_802F71F0(); + } else { + switch (sp44->hdr.type) { + case 11: + osRecvMesg(sp34->unk10, &sp3c, OS_MESG_BLOCK); + sp38 = sp34->dma_func(OS_READ, sp44->devAddr, sp44->dramAddr, sp44->size); + break; + case 12: + osRecvMesg(sp34->unk10, &sp3c, OS_MESG_BLOCK); + sp38 = sp34->dma_func(OS_WRITE, sp44->devAddr, sp44->dramAddr, sp44->size); + break; + case 15: + osRecvMesg(sp34->unk10, &sp3c, OS_MESG_BLOCK); + sp38 = sp34->edma_func(sp44->piHandle, OS_READ, sp44->devAddr, sp44->dramAddr, + sp44->size); + break; + case 16: + osRecvMesg(sp34->unk10, &sp3c, OS_MESG_BLOCK); + sp38 = sp34->edma_func(sp44->piHandle, OS_WRITE, sp44->devAddr, sp44->dramAddr, + sp44->size); + break; + case 10: + osSendMesg(sp44->hdr.retQueue, sp44, OS_MESG_NOBLOCK); + sp38 = -1; + break; + break; + default: + sp38 = -1; + break; + } + if (sp38 == 0) { + osRecvMesg(sp34->unk0c, &sp40, OS_MESG_BLOCK); + sp30 = osSendMesg(sp44->hdr.retQueue, sp44, OS_MESG_NOBLOCK); + osSendMesg(sp34->unk10, NULL, OS_MESG_NOBLOCK); + } + } + } +} +#else void __osDevMgrMain(void *args) { OSIoMesg *sp34; OSMesg sp30; @@ -35,3 +118,4 @@ void __osDevMgrMain(void *args) { } } } +#endif diff --git a/lib/src/__osGetCurrFaultedThread.c b/lib/src/__osGetCurrFaultedThread.c new file mode 100644 index 0000000..f5b7f60 --- /dev/null +++ b/lib/src/__osGetCurrFaultedThread.c @@ -0,0 +1,5 @@ +#include "libultra_internal.h" +extern OSThread* D_8033489C; +OSThread *__osGetCurrFaultedThread() { + return D_8033489C; // 80302efc +} diff --git a/lib/src/__osSyncPutChars.c b/lib/src/__osSyncPutChars.c index 96254c3..a27ef60 100644 --- a/lib/src/__osSyncPutChars.c +++ b/lib/src/__osSyncPutChars.c @@ -6,6 +6,7 @@ typedef struct { u8 unk01 : 2; u8 unk2[3]; } unkStruct; + u32 D_80334A40 = 0; u32 D_80334A44 = 1; diff --git a/lib/src/__osViInit.c b/lib/src/__osViInit.c index 3c88d8d..92d6495 100644 --- a/lib/src/__osViInit.c +++ b/lib/src/__osViInit.c @@ -8,14 +8,23 @@ extern u32 osTvType; OSViContext D_803348B0[2] = { 0 }; OSViContext *D_80334910 = &D_803348B0[0]; OSViContext *D_80334914 = &D_803348B0[1]; +#ifdef VERSION_EU +u32 D_8033491C = 0x02E6D354; +u32 D_80334918 = TV_TYPE_PAL; +#else u32 D_80334918 = TV_TYPE_NTSC; u32 D_8033491C = 0x02E6D354; +#endif extern OSViMode D_80334990; extern OSViMode D_803349E0; +#ifdef VERSION_EU +extern OSViMode D_80302FD0; +#endif + void __osViInit(void) { //#ifdef VERSION_JP -#ifndef VERSION_JP +#ifdef VERSION_US D_80334918 = osTvType; #endif bzero(D_803348B0, sizeof(D_803348B0)); @@ -23,6 +32,21 @@ void __osViInit(void) { D_80334914 = &D_803348B0[1]; D_80334914->retraceCount = 1; D_80334910->retraceCount = 1; + +#ifdef VERSION_EU + + if (osTvType == TV_TYPE_PAL) { + D_80334914->unk08 = &D_80334990; + D_8033491C = 0x02F5B2D2; + } else if (osTvType == TV_TYPE_MPAL) { + D_80334914->unk08 = &D_803349E0; + D_8033491C = 0x02E6025C; + } else { + D_80334914->unk08 = &D_80302FD0; + D_8033491C = 0x02E6D354; + } + +#else #ifdef VERSION_JP if (D_80334918 != TV_TYPE_PAL) #else @@ -39,6 +63,7 @@ void __osViInit(void) { D_8033491C = 0x02E6025C; #endif } +#endif D_80334914->unk00 = 32; D_80334914->features = D_80334914->unk08->comRegs.ctrl; #ifndef VERSION_JP diff --git a/lib/src/func_802F4A20.c b/lib/src/func_802F4A20.c new file mode 100644 index 0000000..985cdcd --- /dev/null +++ b/lib/src/func_802F4A20.c @@ -0,0 +1,171 @@ +#include "new_func.h" + +extern OSThread *D_80334898; +void func_802F4A20() { + __OSTranxInfo *sp1c; + volatile u32 sp18; + // lui $t6, %hi(__osDiskHandle) # $t6, 0x8033 + // lw $t6, %lo(__osDiskHandle)($t6) + // addiu $sp, $sp, -0x20 + // sw $ra, 0x14($sp) + // addiu $t7, $t6, 0x14 + // sw $t7, 0x1c($sp) + sp1c = &__osDiskHandle->transferInfo; + // lui $t8, %hi(D_A4600010) # $t8, 0xa460 + // lw $t9, %lo(D_A4600010)($t8) + // sw $t9, 0x18($sp) + // sp18 = HW_REG(PI_STATUS_REG, u32); + // while(sp18 & 0x2) sp18 = HW_REG(PI_STATUS_REG, u32); + WAIT_ON_IOBUSY(sp18); + // lw $t0, 0x18($sp) + // andi $t1, $t0, 2 + // beqz $t1, .L802F4A70 + // nop + // L802F4A54: + // lui $t2, %hi(D_A4600010) # $t2, 0xa460 + // lw $t3, %lo(D_A4600010)($t2) + // sw $t3, 0x18($sp) + // lw $t4, 0x18($sp) + // andi $t5, $t4, 2 + // bnez $t5, .L802F4A54 + // nop + + // L802F4A70: + // lw $t6, 0x1c($sp) + // lui $at, 0x1000 + // lui $t9, %hi(D_A5000510) # $t9, 0xa500 + // lw $t7, 0x14($t6) + // lui $t0, %hi(D_A4600010) # $t0, 0xa460 + // or $t8, $t7, $at + // sw $t8, %lo(D_A5000510)($t9) + HW_REG(ASIC_BM_CTL, u32) = BUFFER_MANAGER_RESET | sp1c->bmCtlShadow; //should be unk10?? + // lw $t1, %lo(D_A4600010)($t0) + // sw $t1, 0x18($sp) + // lw $t2, 0x18($sp) + // andi $t3, $t2, 2 + // beqz $t3, .L802F4AC0 + // nop + WAIT_ON_IOBUSY(sp18); + // L802F4AA4: + // lui $t4, %hi(D_A4600010) # $t4, 0xa460 + // lw $t5, %lo(D_A4600010)($t4) + // sw $t5, 0x18($sp) + // lw $t6, 0x18($sp) + // andi $t7, $t6, 2 + // bnez $t7, .L802F4AA4 + // nop + // L802F4AC0: + + // lw $t8, 0x1c($sp) + // lui $t0, %hi(D_A5000510) # $t0, 0xa500 + // lw $t9, 0x14($t8) + // jal func_802F4B08 + // sw $t9, %lo(D_A5000510)($t0) + HW_REG(ASIC_BM_CTL, u32) = sp1c->bmCtlShadow; + func_802F4B08(); + // li $t1, 2 + // lui $t2, %hi(D_A4600010) # $t2, 0xa460 + // sw $t1, %lo(D_A4600010)($t2) + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLEAR_INTR; + // lui $t3, %hi(D_8030208C) # $t3, 0x8030 + // lw $t3, %lo(D_8030208C)($t3) + // lui $at, (0x00100401 >> 16) # lui $at, 0x10 + // lw $ra, 0x14($sp) + // ori $at, (0x00100401 & 0xFFFF) # ori $at, $at, 0x401 + // or $t4, $t3, $at + // lui $at, %hi(D_8030208C) # $at, 0x8030 + // sw $t4, %lo(D_8030208C)($at) + D_8030208C |= 0x00100401; //TODO: fix magic numbers + // jr $ra + // addiu $sp, $sp, 0x20 +} + +typedef struct OSEventMessageStruct_0_s { + OSMesgQueue *queue; + OSMesg msg; +} OSEventMessageStruct_0; + +extern OSEventMessageStruct_0 D_80363830[16]; // should be OS_NUM_EVENTS + 1 I think +void func_802F4B08() { + OSEventMessageStruct_0 *sp2c; + OSMesgQueue *sp28; + u32 sp24; + register OSThread *s0; + // addiu $sp, $sp, -0x30 + // lui $t6, %hi(D_80363830) # $t6, 0x8033 + // addiu $t6, %lo(D_80363830) # addiu $t6, $t6, 0x36d0 + // addiu $t7, $t6, 0x40 + // sw $ra, 0x1c($sp) + // sw $s0, 0x18($sp) + // sw $t7, 0x2c($sp) + sp2c = &D_80363830[OS_EVENT_PI]; + // lw $t8, 0x40($t6) + // beqz $t8, .L802F4BE0 + // sw $t8, 0x28($sp) + sp28 = sp2c->queue; + // lw $t9, 8($t8) + // lw $t0, 0x10($t8) + // slt $at, $t9, $t0 + // beqz $at, .L802F4BE0 + // nop + if (!sp28 || sp28->validCount >= sp28->msgCount) + return; + // lw $t1, 0x28($sp) + // lw $t6, 0x2c($sp) + // lw $t2, 0xc($t1) + // lw $t3, 8($t1) + // lw $t5, 0x10($t1) + // addu $t4, $t2, $t3 + // div $zero, $t4, $t5 + // mfhi $t7 + // sw $t7, 0x24($sp) + sp24 = (sp28->first + sp28->validCount) % sp28->msgCount; + // lw $t0, 0x14($t1) + // lw $t8, 4($t6) + // sll $t9, $t7, 2 + // addu $t2, $t0, $t9 + // sw $t8, ($t2) + sp28->msg[sp24] = sp2c->msg; + // lw $t3, 0x28($sp) + // bnez $t5, .L802F4B8C + // nop + // break 7 + // L802F4B8C: + // li $at, -1 + // bne $t5, $at, .L802F4BA4 + // lui $at, 0x8000 + // bne $t4, $at, .L802F4BA4 + // nop + // break 6 + // L802F4BA4: + // lw $t4, 8($t3) + // addiu $t5, $t4, 1 + // sw $t5, 8($t3) + sp28->validCount += 1; + // lw $t6, 0x28($sp) + // lw $t7, ($t6) + // lw $t1, ($t7) + // beqz $t1, .L802F4BE0 + // nop + // jal __osPopThread + // move $a0, $t6 + if (sp28->mtqueue->next != NULL) { + s0 = __osPopThread(&sp28->mtqueue); + // move $s0, $v0 + // lui $a0, %hi(D_80334898) # $a0, 0x8030 + // addiu $a0, %lo(D_80334898) # addiu $a0, $a0, 0x2ef8 + // jal __osEnqueueThread + // move $a1, $s0 + __osEnqueueThread(&D_80334898, s0); + } + // L802F4BE0: + // lw $ra, 0x1c($sp) + // lw $s0, 0x18($sp) + // addiu $sp, $sp, 0x30 + // jr $ra + // nop + + // nop + // nop + // nop +} diff --git a/lib/src/func_802F7140.c b/lib/src/func_802F7140.c new file mode 100644 index 0000000..3c328c6 --- /dev/null +++ b/lib/src/func_802F7140.c @@ -0,0 +1,31 @@ +#include "libultra_internal.h" +extern u32 D_8030208C; +void func_802F7140(u32 a0) { + register u32 s0; + s0 = __osDisableInt(); + D_8030208C &= ~(-0x402 & a0); + __osRestoreInt(s0); +} +/* +/ 0B6940 802F7140 27BDFFD8 / addiu $sp, $sp, -0x28 +/ 0B6944 802F7144 AFBF001C / sw $ra, 0x1c($sp) +/ 0B6948 802F7148 AFA40028 / sw $a0, 0x28($sp) +/ 0B694C 802F714C 0C0BD400 / jal __osDisableInt +/ 0B6950 802F7150 AFB00018 / sw $s0, 0x18($sp) +/ 0B6954 802F7154 8FAF0028 / lw $t7, 0x28($sp) +/ 0B6958 802F7158 3C0E8030 / lui $t6, %hi(D_8030208C) # $t6, 0x8030 +/ 0B695C 802F715C 8DCE208C / lw $t6, %lo(D_8030208C)($t6) +/ 0B6960 802F7160 2401FBFE / li $at, -1026 +/ 0B6964 802F7164 01E1C024 / and $t8, $t7, $at +/ 0B6968 802F7168 0300C827 / not $t9, $t8 +/ 0B696C 802F716C 00408025 / move $s0, $v0 +/ 0B6970 802F7170 3C018030 / lui $at, %hi(D_8030208C) # $at, 0x8030 +/ 0B6974 802F7174 01D94024 / and $t0, $t6, $t9 +/ 0B6978 802F7178 AC28208C / sw $t0, %lo(D_8030208C)($at) +/ 0B697C 802F717C 0C0BD408 / jal __osRestoreInt +/ 0B6980 802F7180 02002025 / move $a0, $s0 +/ 0B6984 802F7184 8FBF001C / lw $ra, 0x1c($sp) +/ 0B6988 802F7188 8FB00018 / lw $s0, 0x18($sp) +/ 0B698C 802F718C 27BD0028 / addiu $sp, $sp, 0x28 +/ 0B6990 802F7190 03E00008 / jr $ra +/ 0B6994 802F7194 00000000 / nop */ diff --git a/lib/src/func_802F71A0.c b/lib/src/func_802F71A0.c new file mode 100644 index 0000000..fd80dd1 --- /dev/null +++ b/lib/src/func_802F71A0.c @@ -0,0 +1,36 @@ + +#include "libultra_internal.h" +#include "hardware.h" +//possibly osEpiWriteIo +s32 func_802F71A0(OSPiHandle *a0, u32 a1, u32 a2) { + register u32 a3 = HW_REG(PI_STATUS_REG, u32); + while (a3 & PI_STATUS_ERROR) + a3 = HW_REG(PI_STATUS_REG, u32); + HW_REG(a0->baseAddress | a1, u32) = a2; + return 0; +} +/* +/ 0B69A0 802F71A0 3C0EA460 / lui $t6, %hi(D_A4600010) # $t6, 0xa460 +/ 0B69A4 802F71A4 8DC70010 / lw $a3, %lo(D_A4600010)($t6) +/ 0B69A8 802F71A8 27BDFFF8 / addiu $sp, $sp, -8 +/ 0B69AC 802F71AC 30EF0003 / andi $t7, $a3, 3 + +/ 0B69B0 802F71B0 11E00006 / beqz $t7, .L802F71CC +/ 0B69B4 802F71B4 00000000 / nop +.L802F71B8: +/ 0B69B8 802F71B8 3C18A460 / lui $t8, %hi(D_A4600010) # $t8, 0xa460 +/ 0B69BC 802F71BC 8F070010 / lw $a3, %lo(D_A4600010)($t8) +/ 0B69C0 802F71C0 30F90003 / andi $t9, $a3, 3 +/ 0B69C4 802F71C4 1720FFFC / bnez $t9, .L802F71B8 +/ 0B69C8 802F71C8 00000000 / nop +.L802F71CC: +/ 0B69CC 802F71CC 8C88000C / lw $t0, 0xc($a0) +/ 0B69D0 802F71D0 3C01A000 / lui $at, 0xa000 +/ 0B69D4 802F71D4 27BD0008 / addiu $sp, $sp, 8 +/ 0B69D8 802F71D8 01054825 / or $t1, $t0, $a1 +/ 0B69DC 802F71DC 01215025 / or $t2, $t1, $at +/ 0B69E0 802F71E0 AD460000 / sw $a2, ($t2) +/ 0B69E4 802F71E4 03E00008 / jr $ra +/ 0B69E8 802F71E8 00001025 / move $v0, $zero + +/ 0B69EC 802F71EC 00000000 / nop */ diff --git a/lib/src/func_802F71F0.c b/lib/src/func_802F71F0.c new file mode 100644 index 0000000..a7aea2a --- /dev/null +++ b/lib/src/func_802F71F0.c @@ -0,0 +1,33 @@ +#include "libultra_internal.h" + +extern OSThread *D_803348A0; +extern OSThread *D_80334898; +void func_802F71F0() { + register u32 s0 = __osDisableInt(); + D_803348A0->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&D_80334898); + __osRestoreInt(s0); +} +/* +/ 0B69F0 802F71F0 27BDFFD8 / addiu $sp, $sp, -0x28 +/ 0B69F4 802F71F4 AFBF001C / sw $ra, 0x1c($sp) +/ 0B69F8 802F71F8 0C0BD400 / jal __osDisableInt +/ 0B69FC 802F71FC AFB00018 / sw $s0, 0x18($sp) +/ 0B6A00 802F7200 3C0F8030 / lui $t7, %hi(D_803348A0) # $t7, 0x8030 +/ 0B6A04 802F7204 8DEF2F00 / lw $t7, %lo(D_803348A0)($t7) +/ 0B6A08 802F7208 240E0002 / li $t6, 2 +/ 0B6A0C 802F720C 3C048030 / lui $a0, %hi(D_80334898) # $a0, 0x8030 +/ 0B6A10 802F7210 00408025 / move $s0, $v0 +/ 0B6A14 802F7214 24842EF8 / addiu $a0, %lo(D_80334898) # addiu $a0, $a0, 0x2ef8 +/ 0B6A18 802F7218 0C0BCFC3 / jal __osEnqueueAndYield +/ 0B6A1C 802F721C A5EE0010 / sh $t6, 0x10($t7) + +/ 0B6A20 802F7220 0C0BD408 / jal __osRestoreInt +/ 0B6A24 802F7224 02002025 / move $a0, $s0 +/ 0B6A28 802F7228 8FBF001C / lw $ra, 0x1c($sp) +/ 0B6A2C 802F722C 8FB00018 / lw $s0, 0x18($sp) +/ 0B6A30 802F7230 27BD0028 / addiu $sp, $sp, 0x28 +/ 0B6A34 802F7234 03E00008 / jr $ra +/ 0B6A38 802F7238 00000000 / nop + +/ 0B6A3C 802F723C 00000000 / nop */ diff --git a/lib/src/hardware.h b/lib/src/hardware.h index c207335..14848ca 100644 --- a/lib/src/hardware.h +++ b/lib/src/hardware.h @@ -66,6 +66,9 @@ #define PI_STATUS_IOBUSY 0x2 #define PI_STATUS_ERROR 0x3 +#define PI_STATUS_RESET_CONTROLLER 0x1 +#define PI_STATUS_CLEAR_INTR 0x2 + #define SI_DRAM_ADDR_REG 0x04800000 #define SI_PIF_ADDR_RD64B_REG 0x04800004 #define SI_PIF_ADDR_WR64B_REG 0x04800010 @@ -82,4 +85,43 @@ #define MI_INTR_REG 0x04300008 #define MI_INTR_MASK_REG 0x0430000C +//https://github.com/LuigiBlood/64dd/wiki/Registers +#define ASIC_STATUS 0x05000508 + +#define DATA_REQUEST 0x40000000 +#define C2_TRANSFER 0x10000000 +#define BUFFER_MANAGER_ERROR 0x08000000 +#define BUFFER_MANAGER_INTERRUPT 0x04000000 +#define MECHANIC_INTERRUPT 0x02000000 +#define DISK_PRESENT 0x01000000 +#define BUSY_STATE 0x00800000 +#define RESET_STATE 0x00400000 +#define MOTOR_NOT_SPINNING 0x00100000 +#define HEAD_RETRACTED 0x00080000 +#define WRITE_PROTECT_ERROR 0x00040000 +#define MECHANIC_ERROR 0x00020000 +#define DISK_CHANGE 0x00010000 + +#define _64DD_PRESENT_MASK 0xFFFF + + +//ro +#define ASIC_BM_STATUS 0x05000510 + +#define MICRO_STATUS 0x02000000 +#define C1_DOUBLE 0x00400000 +#define C1_SINGLE 0x00200000 + +//wo +#define ASIC_BM_CTL 0x05000510 +#define BUFFER_MANAGER_RESET 0x10000000 +#define MECHANIC_INTERRUPT_RESET 0x01000000 +/*- Start Buffer Manager (0x80000000) +- Buffer Manager Mode (0x40000000) +- BM Interrupt Mask (0x20000000) +- Buffer Manager Reset (0x10000000) +- Disable OR Check? (0x08000000) +- Disable C1 Correction (0x04000000) +- Block Transfer (0x02000000) +- Mechanic Interrupt Reset (0x01000000)*/ #endif diff --git a/lib/src/kdebugserver.c b/lib/src/kdebugserver.c index 747cc7d..9674333 100644 --- a/lib/src/kdebugserver.c +++ b/lib/src/kdebugserver.c @@ -13,7 +13,7 @@ u32 D_80334A30 = 0; u32 D_80334A34 = 0; s32 D_80334A38 = 0; -u8 D_80365E40[0x100]; +extern u8 D_80365E40[0x1000]; OSThread gInterruptedThread; diff --git a/lib/src/libultra_internal.h b/lib/src/libultra_internal.h index 5dc8492..1216401 100644 --- a/lib/src/libultra_internal.h +++ b/lib/src/libultra_internal.h @@ -2,44 +2,48 @@ #define _LIBULTRA_INTERNAL_H_ #include -typedef struct -{ - u32 initialized; //probably something like initialized? +typedef struct { + u32 initialized; // probably something like initialized? OSThread *mgrThread; OSMesgQueue *unk08; OSMesgQueue *unk0c; OSMesgQueue *unk10; - s32 (*dma_func)(s32,u32,void*,size_t); + s32 (*dma_func)(s32, u32, void *, size_t); +#ifdef VERSION_EU + s32 (*edma_func)(OSPiHandle*, s32, u32, void *, size_t); +#else u64 force_align; +#endif } OSMgrArgs; s32 __osDisableInt(); void __osRestoreInt(s32); -void __osEnqueueAndYield(OSThread**); -void __osDequeueThread(OSThread**, OSThread*); -void __osEnqueueThread(OSThread**, OSThread*); -OSThread* __osPopThread(OSThread**); -s32 __osSiRawStartDma(s32, void*); +void __osEnqueueAndYield(OSThread **); +void __osDequeueThread(OSThread **, OSThread *); +void __osEnqueueThread(OSThread **, OSThread *); +OSThread *__osPopThread(OSThread **); +s32 __osSiRawStartDma(s32, void *); void __osSiCreateAccessQueue(); void __osSiGetAccess(); void __osSiRelAccess(); -u32 __osProbeTLB(void*); +u32 __osProbeTLB(void *); void __osPiCreateAccessQueue(); void __osPiGetAccess(); void __osSetSR(u32); u32 __osGetSR(); void __osSetFpcCsr(u32); -s32 __osSiRawReadIo(void*, u32*); -s32 __osSiRawWriteIo(void*, u32); +s32 __osSiRawReadIo(void *, u32 *); +s32 __osSiRawWriteIo(void *, u32); s32 osPiRawReadIo(u32 a0, u32 *a1); void __osSpSetStatus(u32); u32 __osSpGetStatus(); -s32 __osSpSetPc(void*); +s32 __osSpSetPc(void *); s32 __osSpDeviceBusy(); s32 __osSiDeviceBusy(); s32 __osSpRawStartDma(u32 dir, void *sp_ptr, void *dram_ptr, size_t size); void __osViInit(); -OSViContext * __osViGetCurrentContext(); +OSViContext *__osViGetCurrentContext(); +OSViContext *__osViGetCurrentContext2(); void __osViSwapContext(); void __osSetTimerIntr(u64); u64 __osInsertTimer(OSTimer *); @@ -47,5 +51,5 @@ void __osSetCompare(u32); s32 __osAiDeviceBusy(); void __osDispatchThread(); u32 __osGetCause(); -s32 __osAtomicDec(u32*); +s32 __osAtomicDec(u32 *); #endif diff --git a/lib/src/new_func.h b/lib/src/new_func.h new file mode 100644 index 0000000..3453925 --- /dev/null +++ b/lib/src/new_func.h @@ -0,0 +1,22 @@ +#ifndef NEW_FUNC_H +#define NEW_FUNC_H +#include "libultra_internal.h" +#include "hardware.h" + +#define WAIT_ON_IOBUSY(var) \ + var = HW_REG(PI_STATUS_REG, u32); \ + while (var & PI_STATUS_IOBUSY) \ + var = HW_REG(PI_STATUS_REG, u32); + +extern u32 EU_D_80302090; + +extern OSPiHandle *__osDiskHandle; //possibly __osPiTable + +extern volatile u32 D_8030208C; +s32 osEPiRawStartDma(OSPiHandle *arg0, s32 dir, u32 cart_addr, void *dram_addr, u32 size); +void func_802F4B08(); +void func_802F4A20(); +void func_802F7140(u32); +void func_802F71A0(OSPiHandle*, u32, u32); //osEPi something +void func_802F71F0(); +#endif diff --git a/lib/src/osContInit.c b/lib/src/osContInit.c index dce651c..d155b6b 100644 --- a/lib/src/osContInit.c +++ b/lib/src/osContInit.c @@ -43,7 +43,11 @@ s32 osContInit(OSMesgQueue *mq, u8 *a1, OSContStatus *status) { sp78 = __osSiRawStartDma(0, D_80365CE0); osRecvMesg(mq, &mesg, OS_MESG_BLOCK); __osContGetInitData(a1, status); +#ifdef VERSION_EU + D_80365D20 = 0; +#else D_80365D20 = 255; +#endif __osSiCreateAccessQueue(); osCreateMesgQueue(&_osContMesgQueue, _osContMesgBuff, 1); return sp78; diff --git a/lib/src/osCreatePiManager.c b/lib/src/osCreatePiManager.c index dfd97b4..5b3d286 100644 --- a/lib/src/osCreatePiManager.c +++ b/lib/src/osCreatePiManager.c @@ -3,11 +3,14 @@ #define OS_PI_MGR_MESG_BUFF_SIZE 1 OSMgrArgs piMgrArgs = { 0 }; +#ifdef VERSION_EU +OSPiHandle *D_80302DFC = NULL; +#endif OSThread piMgrThread; u32 piMgrStack[0x400]; // stack bottom OSMesgQueue __osPiMesgQueue; OSMesg piMgrMesgBuff[OS_PI_MGR_MESG_BUFF_SIZE + 1]; -s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size); + extern u32 gOsPiAccessQueueCreated; extern OSMesgQueue gOsPiMessageQueue; void __osDevMgrMain(void *); @@ -37,6 +40,9 @@ void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgC piMgrArgs.unk0c = &__osPiMesgQueue; piMgrArgs.unk10 = &gOsPiMessageQueue; piMgrArgs.dma_func = osPiRawStartDma; +#ifdef VERSION_EU + piMgrArgs.edma_func = osEPiRawStartDma; +#endif osCreateThread(&piMgrThread, 0, __osDevMgrMain, (void *) &piMgrArgs, &piMgrStack[0x400], pri); osStartThread(&piMgrThread); __osRestoreInt(int_disabled); diff --git a/lib/src/osCreateThread.c b/lib/src/osCreateThread.c index e7be5bd..7a89168 100644 --- a/lib/src/osCreateThread.c +++ b/lib/src/osCreateThread.c @@ -18,7 +18,7 @@ void osCreateThread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, thread->context.a0 = (u64) arg; thread->context.sp = (u64) sp - 16; thread->context.ra = (u64) __osCleanupThread; - tmp = 0x003FFF01; + tmp = OS_IM_ALL; thread->context.sr = 65283; thread->context.rcp = (tmp & 0x3f0000) >> 16; thread->context.fpcsr = (u32) 0x01000800; diff --git a/lib/src/osCreateViManager.c b/lib/src/osCreateViManager.c index bf5a3f9..65e10d1 100644 --- a/lib/src/osCreateViManager.c +++ b/lib/src/osCreateViManager.c @@ -1,1003 +1,21 @@ #include "libultra_internal.h" -OSViMode osViModeTable[] = { - /*osViModeNtscLpn1*/ - { /*type*/ 0, - /*comRegs*/ - { /*ctrl*/ 12814, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpf1*/ - { /*type*/ 1, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLan1*/ - { /*type*/ 2, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLaf1*/ - { /*type*/ 3, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpn2*/ - { /*type*/ 4, - /*comRegs*/ - { /*ctrl*/ 13071, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLpf2*/ - { /*type*/ 5, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLan2*/ - { /*type*/ 6, - /*comRegs*/ - { /*ctrl*/ 12319, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 525, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscLaf2*/ - { /*type*/ 7, - /*comRegs*/ - { /*ctrl*/ 12383, - /*width*/ 320, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpn1*/ - { /*type*/ 8, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpf1*/ - { /*type*/ 9, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHan1*/ - { /*type*/ 10, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHaf1*/ - { /*type*/ 11, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpn2*/ - { /*type*/ 12, - /*comRegs*/ - { /*ctrl*/ 13135, - /*width*/ 1280, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModeNtscHpf2*/ - { /*type*/ 13, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 640, - /*burst*/ 65348153, - /*vSync*/ 524, - /*hSync*/ 3093, - /*leap*/ 202705941, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - -#ifdef VERSION_JP - /*osViModePalLpn1*/ - { /*type*/ 14, - /*comRegs*/ - { /*ctrl*/ 12814, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 625, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLpf1*/ - { /*type*/ 15, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLan1*/ - { /*type*/ 16, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 625, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLaf1*/ - { /*type*/ 17, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLpn2*/ - { /*type*/ 18, - /*comRegs*/ - { /*ctrl*/ 13071, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 625, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLpf2*/ - { /*type*/ 19, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalLan2*/ - { /*type*/ 20, - /*comRegs*/ - { /*ctrl*/ 12319, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 625, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 590443, - /*vIntr*/ 2 } } }, - /*osViModePalLaf2*/ - { /*type*/ 21, - /*comRegs*/ - { /*ctrl*/ 12383, - /*width*/ 320, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpn1*/ - { /*type*/ 22, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 1280, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpf1*/ - { /*type*/ 23, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 640, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHan1*/ - { /*type*/ 24, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 1280, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHaf1*/ - { /*type*/ 25, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 640, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpn2*/ - { /*type*/ 26, - /*comRegs*/ - { /*ctrl*/ 13135, - /*width*/ 1280, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, - /*osViModePalHpf2*/ - { /*type*/ 27, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 640, - /*burst*/ 67380026, - /*vSync*/ 624, - /*hSync*/ 1379433, - /*leap*/ 208604270, - /*hStart*/ 8389376, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 6095415, - /*vBurst*/ 590443, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 6226489, - /*vBurst*/ 852585, - /*vIntr*/ 2 } } }, -#else - /*osViModePalLpn1*/ - { /*type*/ 28, - /*comRegs*/ - { /*ctrl*/ 12814, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpf1*/ - { /*type*/ 29, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLan1*/ - { /*type*/ 30, - /*comRegs*/ - { /*ctrl*/ 12574, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLaf1*/ - { /*type*/ 31, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 640, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 640, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpn2*/ - { /*type*/ 32, - /*comRegs*/ - { /*ctrl*/ 13071, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLpf2*/ - { /*type*/ 33, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLan2*/ - { /*type*/ 34, - /*comRegs*/ - { /*ctrl*/ 12319, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 525, - /*hSync*/ 265233, - /*leap*/ 202968090, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalLaf2*/ - { /*type*/ 35, - /*comRegs*/ - { /*ctrl*/ 12383, - /*width*/ 320, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 512, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 16778240, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 1280, - /*yScale*/ 50332672, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpn1*/ - { /*type*/ 36, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpf1*/ - { /*type*/ 37, - /*comRegs*/ - { /*ctrl*/ 12878, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHan1*/ - { /*type*/ 38, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHaf1*/ - { /*type*/ 39, - /*comRegs*/ - { /*ctrl*/ 12382, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 1280, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpn2*/ - { /*type*/ 40, - /*comRegs*/ - { /*ctrl*/ 13135, - /*width*/ 1280, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 1024, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 1024, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } }, - /*osViModePalHpf2*/ - { /*type*/ 41, - /*comRegs*/ - { /*ctrl*/ 12879, - /*width*/ 640, - /*burst*/ 73735737, - /*vSync*/ 524, - /*hSync*/ 3088, - /*leap*/ 203164700, - /*hStart*/ 7078636, - /*xScale*/ 1024, - /*vCurrent*/ 0 }, - /*fldRegs*/ - { { /*origin*/ 2560, - /*yScale*/ 33556480, - /*vStart*/ 2294269, - /*vBurst*/ 721410, - /*vIntr*/ 2 }, - { /*origin*/ 5120, - /*yScale*/ 33556480, - /*vStart*/ 2425343, - /*vBurst*/ 918020, - /*vIntr*/ 2 } } } -#endif -}; - #define OS_VI_MANAGER_MESSAGE_BUFF_SIZE 5 -OSMgrArgs viMgrMainArgs = { 0 }; -OSThread viMgrThread; -u32 viMgrStack[0x400]; // stack bottom -OSMesgQueue __osViMesgQueue; -OSMesg viMgrMesgBuff[OS_VI_MANAGER_MESSAGE_BUFF_SIZE + 1]; +static OSMgrArgs viMgrMainArgs = { 0 }; +static OSThread viMgrThread; +static u32 viMgrStack[0x400]; // stack bottom +static OSMesgQueue __osViMesgQueue; +static OSMesg viMgrMesgBuff[OS_VI_MANAGER_MESSAGE_BUFF_SIZE]; -typedef struct { - u16 unk00; - u8 unk02; - u32 unk04; - u8 pad[0xc]; - u16 unk14; - u16 unk16; -} viMesgStruct; - -viMesgStruct viEventViMesg; -viMesgStruct viEventCounterMesg; +static OSIoMesg viEventViMesg; +static OSIoMesg viEventCounterMesg; extern void __osTimerServicesInit(void); extern void __osTimerInterrupt(void); extern OSTime _osCurrentTime; extern u32 D_80365DA8; -extern u32 D_80365DAC; +extern u32 __osViIntrCount; void viMgrMain(void *); void osCreateViManager(OSPri pri) { @@ -1007,12 +25,12 @@ void osCreateViManager(OSPri pri) { if (!viMgrMainArgs.initialized) { __osTimerServicesInit(); osCreateMesgQueue(&__osViMesgQueue, &viMgrMesgBuff[0], OS_VI_MANAGER_MESSAGE_BUFF_SIZE); - viEventViMesg.unk00 = 13; - viEventViMesg.unk02 = 0; - viEventViMesg.unk04 = 0; - viEventCounterMesg.unk00 = 14; - viEventCounterMesg.unk02 = 0; - viEventCounterMesg.unk04 = 0; + viEventViMesg.hdr.type = 13; + viEventViMesg.hdr.pri = 0; + viEventViMesg.hdr.retQueue = 0; + viEventCounterMesg.hdr.type = 14; + viEventCounterMesg.hdr.pri = 0; + viEventCounterMesg.hdr.retQueue = 0; osSetEventMesg(OS_EVENT_VI, &__osViMesgQueue, &viEventViMesg); osSetEventMesg(OS_EVENT_COUNTER, &__osViMesgQueue, &viEventCounterMesg); newPri = -1; @@ -1028,6 +46,10 @@ void osCreateViManager(OSPri pri) { viMgrMainArgs.unk0c = &__osViMesgQueue; viMgrMainArgs.unk10 = NULL; viMgrMainArgs.dma_func = NULL; +#ifdef VERSION_EU + viMgrMainArgs.edma_func = NULL; +#endif + osCreateThread(&viMgrThread, 0, viMgrMain, (void *) &viMgrMainArgs, &viMgrStack[0x400], pri); __osViInit(); osStartThread(&viMgrThread); @@ -1037,8 +59,8 @@ void osCreateViManager(OSPri pri) { } } } - void viMgrMain(void *vargs) { + static u16 retrace; OSViContext *context; OSMgrArgs *args; OSMesg mesg; @@ -1048,8 +70,8 @@ void viMgrMain(void *vargs) { sp28 = FALSE; context = __osViGetCurrentContext(); - if ((viEventCounterMesg.unk14 = context->retraceCount) == 0) { - viEventCounterMesg.unk14 = 1; + if ((retrace = context->retraceCount) == 0) { + retrace = 1; } args = (OSMgrArgs *) vargs; @@ -1059,14 +81,14 @@ void viMgrMain(void *vargs) { switch (*(u16 *) mesg) { case 13: __osViSwapContext(); - if (!--viEventCounterMesg.unk14) { + if (!--retrace) { context = __osViGetCurrentContext(); if (context->mq != NULL) { osSendMesg(context->mq, context->msg, OS_MESG_NOBLOCK); } - viEventCounterMesg.unk14 = context->retraceCount; + retrace = context->retraceCount; } - D_80365DAC++; + __osViIntrCount++; if (sp28) { sp24 = osGetCount(); _osCurrentTime = sp24; diff --git a/lib/src/osEPiRawStartDma.c b/lib/src/osEPiRawStartDma.c new file mode 100644 index 0000000..236d42f --- /dev/null +++ b/lib/src/osEPiRawStartDma.c @@ -0,0 +1,24 @@ +#include "libultra_internal.h" +#include "hardware.h" +#include "new_func.h" + +s32 osEPiRawStartDma(OSPiHandle *arg0, s32 dir, u32 cart_addr, void *dram_addr, u32 size) { + register int status; + status = HW_REG(PI_STATUS_REG, u32); + while (status & PI_STATUS_ERROR) + status = HW_REG(PI_STATUS_REG, u32); + HW_REG(PI_DRAM_ADDR_REG, void *) = (void *) osVirtualToPhysical(dram_addr); + HW_REG(PI_CART_ADDR_REG, void *) = (void *) (((uintptr_t) arg0->baseAddress | cart_addr) & 0x1fffffff); + + switch (dir) { + case OS_READ: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; + break; + case OS_WRITE: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; + break; + default: + return -1; + } + return 0; +} diff --git a/lib/src/osInitialize.c b/lib/src/osInitialize.c index d003542..0b9f712 100644 --- a/lib/src/osInitialize.c +++ b/lib/src/osInitialize.c @@ -1,4 +1,5 @@ #include "libultra_internal.h" +#include "hardware.h" #include #define PIF_ADDR_START (void *) 0x1FC007FC @@ -10,10 +11,24 @@ typedef struct { u32 instr03; } exceptionPreamble; +#ifdef VERSION_EU +extern u32 EU_D_802f4330(u32, void (*)); +extern void D_802F4380(); + +#endif u32 D_80365CD0; // maybe initialized? u64 osClockRate = 62500000; u32 D_80334808 = 0; +#ifdef VERSION_EU +u32 EU_D_80336C40; +u32 EU_D_80336C44; + +u32 D_8030208C = OS_IM_ALL; +u32 EU_D_80302090 = 0; +u8 EU_unusedZeroes[8] = { 0 }; +#endif + #define EXCEPTION_TLB_MISS 0x80000000 #define EXCEPTION_XTLB_MISS 0x80000080 #define EXCEPTION_CACHE_ERROR 0x80000100 @@ -25,6 +40,11 @@ extern exceptionPreamble __osExceptionPreamble; void osInitialize(void) { u32 sp34; u32 sp30 = 0; + +#ifdef VERSION_EU + UNUSED u32 eu_sp34; + UNUSED u32 eu_sp30; +#endif UNUSED u32 sp2c; D_80365CD0 = TRUE; __osSetSR(__osGetSR() | 0x20000000); @@ -53,4 +73,16 @@ void osInitialize(void) { if (osResetType == RESET_TYPE_COLD_RESET) { bzero(osAppNmiBuffer, sizeof(osAppNmiBuffer)); } +#ifdef VERSION_EU + eu_sp30 = HW_REG(PI_STATUS_REG, u32); + while (eu_sp30 & PI_STATUS_ERROR) { + eu_sp30 = HW_REG(PI_STATUS_REG, u32); + }; + if (!((eu_sp34 = HW_REG(ASIC_STATUS, u32)) & _64DD_PRESENT_MASK)) { + EU_D_80302090 = 1; + EU_D_802f4330(1, D_802F4380); + } else { + EU_D_80302090 = 0; + } +#endif } diff --git a/lib/src/osLeoDiskInit.c b/lib/src/osLeoDiskInit.c new file mode 100644 index 0000000..ee8e868 --- /dev/null +++ b/lib/src/osLeoDiskInit.c @@ -0,0 +1,30 @@ +#include "libultra_internal.h" +#include "hardware.h" +// this file must include some globally referenced data because it is not called anywhere +// data, comes shortly before _Ldtob I think, before crash_screen + +extern OSPiHandle *D_80302DFC; +// bss +OSPiHandle LeoDiskHandle; +OSPiHandle *__osDiskHandle; +// some kind of piHandle init function, maybe osDriveRomInit or osCartRomInit +OSPiHandle *osLeoDiskInit() { + s32 sp1c; + LeoDiskHandle.type = 2; + LeoDiskHandle.baseAddress = (0xa0000000 | 0x05000000); + LeoDiskHandle.latency = 3; + LeoDiskHandle.pulse = 6; + LeoDiskHandle.pageSize = 6; + LeoDiskHandle.relDuration = 2; + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = LeoDiskHandle.latency; + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = LeoDiskHandle.pulse; + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = LeoDiskHandle.pageSize; + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = LeoDiskHandle.relDuration; + bzero(&LeoDiskHandle.transferInfo, sizeof(__OSTranxInfo)); + sp1c = __osDisableInt(); + LeoDiskHandle.next = D_80302DFC; + D_80302DFC = &LeoDiskHandle; + __osDiskHandle = &LeoDiskHandle; + __osRestoreInt(sp1c); + return &LeoDiskHandle; +} diff --git a/lib/src/osPiRawStartDma.c b/lib/src/osPiRawStartDma.c index 4b74786..ca6044e 100644 --- a/lib/src/osPiRawStartDma.c +++ b/lib/src/osPiRawStartDma.c @@ -27,3 +27,30 @@ s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size) { } return 0; } + +#ifdef VERSION_EU +/*s32 osPiRawStartDma_2(s32 dir, u32 cart_addr, void *dram_addr, size_t size) { + register int status; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) { + status = HW_REG(PI_STATUS_REG, u32); + } + + HW_REG(PI_DRAM_ADDR_REG, void *) = (void *) osVirtualToPhysical(dram_addr); + + HW_REG(PI_CART_ADDR_REG, void *) = (void *) (((uintptr_t) osRomBase | cart_addr) & 0x1fffffff); + + switch (dir) { + case 0: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; + break; + case 1: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; + break; + default: + return -1; + break; + } + return 0; +}*/ +#endif diff --git a/lib/src/osPiStartDma.c b/lib/src/osPiStartDma.c index df73d43..7227f83 100644 --- a/lib/src/osPiStartDma.c +++ b/lib/src/osPiStartDma.c @@ -2,8 +2,8 @@ extern OSMgrArgs piMgrArgs; -s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, size_t nbytes, - OSMesgQueue *mq) { +s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, void *vAddr, + size_t nbytes, OSMesgQueue *mq) { register s32 result; register OSMesgQueue *cmdQueue; if (!piMgrArgs.initialized) { @@ -22,6 +22,9 @@ s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, uintptr_t devAddr, v mb->dramAddr = vAddr; mb->devAddr = devAddr; mb->size = nbytes; +#ifdef VERSION_EU + mb->piHandle = NULL; +#endif if (priority == OS_MESG_PRI_HIGH) { cmdQueue = osPiGetCmdQueue(); diff --git a/lib/src/osTimer.c b/lib/src/osTimer.c index 5271ac7..cd770c6 100644 --- a/lib/src/osTimer.c +++ b/lib/src/osTimer.c @@ -1,16 +1,17 @@ #include "libultra_internal.h" + // TODO: document OSTimer D_80365D80; OSTimer *D_80334830 = &D_80365D80; OSTime _osCurrentTime; u32 D_80365DA8; -u32 D_80365DAC; +u32 __osViIntrCount; u32 D_80365DB0; void __osTimerServicesInit() { _osCurrentTime = 0; D_80365DA8 = 0; - D_80365DAC = 0; + __osViIntrCount = 0; D_80334830->prev = D_80334830; D_80334830->next = D_80334830->prev; D_80334830->remaining = 0; diff --git a/lib/src/osViData.c b/lib/src/osViData.c index 131e0b0..7a58e66 100644 --- a/lib/src/osViData.c +++ b/lib/src/osViData.c @@ -1,4 +1,79 @@ #include "libultra_internal.h" +#ifdef VERSION_EU +OSViMode D_80334990 = { + /*type*/ 16, + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 625, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 } } +}; +OSViMode D_803349E0 = { + /*type*/ 30, //osViModePalLan1 + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 525, + /*hSync*/ 265233, + /*leap*/ 202968090, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } +}; +OSViMode D_80302FD0 = { + /*type*/ 2, + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 525, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } +}; + +#else OSViMode D_80334990 = { /*type*/ 2, @@ -48,3 +123,4 @@ OSViMode D_803349E0 = { /*vBurst*/ 590443, /*vIntr*/ 2 } } }; +#endif diff --git a/lib/src/osViTable.c b/lib/src/osViTable.c new file mode 100644 index 0000000..775dbfe --- /dev/null +++ b/lib/src/osViTable.c @@ -0,0 +1,975 @@ +#include "libultra_internal.h" + +OSViMode osViModeTable[] = { + /*osViModeNtscLpn1*/ + { /*type*/ 0, + /*comRegs*/ + { /*ctrl*/ 12814, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 525, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLpf1*/ + { /*type*/ 1, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLan1*/ + { /*type*/ 2, + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 525, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLaf1*/ + { /*type*/ 3, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLpn2*/ + { /*type*/ 4, + /*comRegs*/ + { /*ctrl*/ 13071, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 525, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLpf2*/ + { /*type*/ 5, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLan2*/ + { /*type*/ 6, + /*comRegs*/ + { /*ctrl*/ 12319, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 525, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscLaf2*/ + { /*type*/ 7, + /*comRegs*/ + { /*ctrl*/ 12383, + /*width*/ 320, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHpn1*/ + { /*type*/ 8, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 1280, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHpf1*/ + { /*type*/ 9, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 640, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHan1*/ + { /*type*/ 10, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 1280, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHaf1*/ + { /*type*/ 11, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 640, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHpn2*/ + { /*type*/ 12, + /*comRegs*/ + { /*ctrl*/ 13135, + /*width*/ 1280, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModeNtscHpf2*/ + { /*type*/ 13, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 640, + /*burst*/ 65348153, + /*vSync*/ 524, + /*hSync*/ 3093, + /*leap*/ 202705941, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + +#if !defined(VERSION_US) + /*osViModePalLpn1*/ + { /*type*/ 14, + /*comRegs*/ + { /*ctrl*/ 12814, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 625, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 } } }, + /*osViModePalLpf1*/ + { /*type*/ 15, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalLan1*/ + { /*type*/ 16, + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 625, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 } } }, + /*osViModePalLaf1*/ + { /*type*/ 17, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalLpn2*/ + { /*type*/ 18, + /*comRegs*/ + { /*ctrl*/ 13071, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 625, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 } } }, + /*osViModePalLpf2*/ + { /*type*/ 19, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalLan2*/ + { /*type*/ 20, + /*comRegs*/ + { /*ctrl*/ 12319, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 625, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 590443, + /*vIntr*/ 2 } } }, + /*osViModePalLaf2*/ + { /*type*/ 21, + /*comRegs*/ + { /*ctrl*/ 12383, + /*width*/ 320, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHpn1*/ + { /*type*/ 22, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 1280, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHpf1*/ + { /*type*/ 23, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 640, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHan1*/ + { /*type*/ 24, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 1280, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHaf1*/ + { /*type*/ 25, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 640, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHpn2*/ + { /*type*/ 26, + /*comRegs*/ + { /*ctrl*/ 13135, + /*width*/ 1280, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 1024, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, + /*osViModePalHpf2*/ + { /*type*/ 27, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 640, + /*burst*/ 67380026, + /*vSync*/ 624, + /*hSync*/ 1379433, + /*leap*/ 208604270, + /*hStart*/ 8389376, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 6095415, + /*vBurst*/ 590443, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 33556480, + /*vStart*/ 6226489, + /*vBurst*/ 852585, + /*vIntr*/ 2 } } }, +#endif +#if !defined(VERSION_JP) + /*osViModePalLpn1*/ + { /*type*/ 28, + /*comRegs*/ + { /*ctrl*/ 12814, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 525, + /*hSync*/ 265233, + /*leap*/ 202968090, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLpf1*/ + { /*type*/ 29, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLan1*/ + { /*type*/ 30, + /*comRegs*/ + { /*ctrl*/ 12574, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 525, + /*hSync*/ 265233, + /*leap*/ 202968090, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLaf1*/ + { /*type*/ 31, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 640, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 640, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLpn2*/ + { /*type*/ 32, + /*comRegs*/ + { /*ctrl*/ 13071, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 525, + /*hSync*/ 265233, + /*leap*/ 202968090, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLpf2*/ + { /*type*/ 33, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLan2*/ + { /*type*/ 34, + /*comRegs*/ + { /*ctrl*/ 12319, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 525, + /*hSync*/ 265233, + /*leap*/ 202968090, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalLaf2*/ + { /*type*/ 35, + /*comRegs*/ + { /*ctrl*/ 12383, + /*width*/ 320, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 512, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 16778240, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 1280, + /*yScale*/ 50332672, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHpn1*/ + { /*type*/ 36, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 1280, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHpf1*/ + { /*type*/ 37, + /*comRegs*/ + { /*ctrl*/ 12878, + /*width*/ 640, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHan1*/ + { /*type*/ 38, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 1280, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHaf1*/ + { /*type*/ 39, + /*comRegs*/ + { /*ctrl*/ 12382, + /*width*/ 640, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 1280, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHpn2*/ + { /*type*/ 40, + /*comRegs*/ + { /*ctrl*/ 13135, + /*width*/ 1280, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 1024, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 1024, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } }, + /*osViModePalHpf2*/ + { /*type*/ 41, + /*comRegs*/ + { /*ctrl*/ 12879, + /*width*/ 640, + /*burst*/ 73735737, + /*vSync*/ 524, + /*hSync*/ 3088, + /*leap*/ 203164700, + /*hStart*/ 7078636, + /*xScale*/ 1024, + /*vCurrent*/ 0 }, + /*fldRegs*/ + { { /*origin*/ 2560, + /*yScale*/ 33556480, + /*vStart*/ 2294269, + /*vBurst*/ 721410, + /*vIntr*/ 2 }, + { /*origin*/ 5120, + /*yScale*/ 33556480, + /*vStart*/ 2425343, + /*vBurst*/ 918020, + /*vIntr*/ 2 } } } +#endif +}; diff --git a/lib/src/unk_stack_data.c b/lib/src/unk_stack_data.c new file mode 100644 index 0000000..84d5fce --- /dev/null +++ b/lib/src/unk_stack_data.c @@ -0,0 +1,9 @@ +#include "libultra_internal.h" + + +// only referenced in kdebugserver... +#ifdef VERSION_EU +u8 D_80365E40[0x1000]; +#else +u8 D_80365E40[0x100]; +#endif diff --git a/sm64.ld b/sm64.ld index dea5c8b..59a5a2a 100755 --- a/sm64.ld +++ b/sm64.ld @@ -115,25 +115,15 @@ SECTIONS BUILD_DIR/src/game/camera.o(.text); BUILD_DIR/src/game/debug_course.o(.text); BUILD_DIR/src/game/object_list_processor.o(.text); -#if VERSION_EU - BUILD_DIR/src/game/behavior_actions.o(.text); - BUILD_DIR/src/game/platform_displacement.o(.text); - BUILD_DIR/src/game/spawn_sound.o(.text); - BUILD_DIR/src/game/debug.o(.text); - BUILD_DIR/src/game/screen_transition.o(.text); - BUILD_DIR/src/game/shadow.o(.text); - BUILD_DIR/src/game/skybox.o(.text); - BUILD_DIR/src/game/moving_texture.o(.text); - BUILD_DIR/src/game/geo_misc.o(.text); - BUILD_DIR/src/game/paintings.o(.text); - BUILD_DIR/src/game/print.o(.text); - BUILD_DIR/src/game/ingame_menu.o(.text); -#else +#ifndef VERSION_EU BUILD_DIR/src/game/object_helpers.o(.text); +#endif BUILD_DIR/src/game/behavior_actions.o(.text); BUILD_DIR/src/game/platform_displacement.o(.text); +#ifndef VERSION_EU BUILD_DIR/src/game/object_collision.o(.text); BUILD_DIR/src/game/spawn_object.o(.text); +#endif BUILD_DIR/src/game/spawn_sound.o(.text); BUILD_DIR/src/game/debug.o(.text); BUILD_DIR/src/game/screen_transition.o(.text); @@ -144,7 +134,6 @@ SECTIONS BUILD_DIR/src/game/paintings.o(.text); BUILD_DIR/src/game/print.o(.text); BUILD_DIR/src/game/ingame_menu.o(.text); -#endif BUILD_DIR/src/game/envfx_snow.o(.text); BUILD_DIR/src/game/envfx_bubbles.o(.text); BUILD_DIR/src/game/macro_special_objects.o(.text); @@ -158,17 +147,122 @@ SECTIONS BUILD_DIR/src/audio/effects.o(.text); BUILD_DIR/src/audio/seqplayer.o(.text); BUILD_DIR/src/audio/external.o(.text); + BUILD_DIR/src/audio/port_eu.o(.text); #ifdef VERSION_EU - // UNSORTED (find where these are) - BUILD_DIR/src/game/object_helpers.o(.text); - BUILD_DIR/src/game/object_collision.o(.text); - BUILD_DIR/src/game/spawn_object.o(.text); -#endif + BUILD_DIR/libultra.a:string.o(.text); + BUILD_DIR/libultra.a:_Printf.o(.text); + BUILD_DIR/libultra.a:llmuldiv.o(.text); + BUILD_DIR/libultra.a:osInitialize.o(.text); + BUILD_DIR/libultra.a:osSetTime.o(.text); + BUILD_DIR/libultra.a:osGetTime.o(.text); + BUILD_DIR/libultra.a:osWritebackDCacheAll.o(.text); + BUILD_DIR/libultra.a:osViBlack.o(.text); + BUILD_DIR/libultra.a:osViSwapBuffer.o(.text); + BUILD_DIR/libultra.a:__osGetCurrFaultedThread.o(.text); + BUILD_DIR/libultra.a:osSetEventMesg.o(.text); + BUILD_DIR/libultra.a:osRecvMesg.o(.text); + BUILD_DIR/libultra.a:parameters.o(.text); + BUILD_DIR/libultra.a:osCreateMesgQueue.o(.text); + BUILD_DIR/libultra.a:osCreateThread.o(.text); + BUILD_DIR/libultra.a:osStartThread.o(.text); + BUILD_DIR/libultra.a:osMapTLB.o(.text); + BUILD_DIR/libultra.a:osUnmapTLBAll.o(.text); + BUILD_DIR/libultra.a:sprintf.o(.text); + BUILD_DIR/libultra.a:osViSetEvent.o(.text); + BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.text); + BUILD_DIR/libultra.a:osSpTaskYield.o(.text); + BUILD_DIR/libultra.a:osSendMesg.o(.text); + BUILD_DIR/libultra.a:osSpTaskYielded.o(.text); + BUILD_DIR/libultra.a:osCreateViManager.o(.text); + BUILD_DIR/libultra.a:osViSetMode.o(.text); + BUILD_DIR/libultra.a:osViSetSpecialFeatures.o(.text); + BUILD_DIR/libultra.a:osCreatePiManager.o(.text); + BUILD_DIR/libultra.a:osSetThreadPri.o(.text); + BUILD_DIR/libultra.a:osViSwapBuffer.o(.text); + BUILD_DIR/libultra.a:sqrtf.o(.text); + BUILD_DIR/libultra.a:osContStartReadData.o(.text); + BUILD_DIR/libultra.a:osContInit.o(.text); + BUILD_DIR/libultra.a:osEepromProbe.o(.text); + BUILD_DIR/libultra.a:osInvalDCache.o(.text); + BUILD_DIR/libultra.a:osPiStartDma.o(.text); + BUILD_DIR/libultra.a:bzero.o(.text) + BUILD_DIR/libultra.a:osInvalICache.o(.text) + BUILD_DIR/libultra.a:osEepromLongRead.o(.text) + BUILD_DIR/libultra.a:osEepromLongWrite.o(.text) + BUILD_DIR/libultra.a:bcopy.o(.text) + BUILD_DIR/libultra.a:guOrthoF.o(.text) + BUILD_DIR/libultra.a:guPerspectiveF.o(.text) + BUILD_DIR/libultra.a:llconv.o(.text) + BUILD_DIR/libultra.a:cosf.o(.text) + BUILD_DIR/libultra.a:sinf.o(.text) + BUILD_DIR/libultra.a:guTranslateF.o(.text) + BUILD_DIR/libultra.a:guRotateF.o(.text) + BUILD_DIR/libultra.a:guScaleF.o(.text) + BUILD_DIR/libultra.a:osAiSetFrequency.o(.text) + BUILD_DIR/libultra.a:alBnkfNew.o(.text) + BUILD_DIR/libultra.a:osAiGetLength.o(.text) + BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text) + BUILD_DIR/libultra.a:_Litob.o(.text) + BUILD_DIR/libultra.a:_Ldtob.o(.text) + BUILD_DIR/libultra.a:__osSetSR.o(.text) + BUILD_DIR/libultra.a:__osGetSR.o(.text) + BUILD_DIR/libultra.a:__osSetFpcCsr.o(.text) + BUILD_DIR/libultra.a:__osSiRawReadIo.o(.text) + BUILD_DIR/libultra.a:__osSiRawWriteIo.o(.text) + BUILD_DIR/libultra.a:__osExceptionPreamble.o(.text) + BUILD_DIR/libultra.a:osWritebackDCache.o(.text) + BUILD_DIR/libultra.a:osMapTLBRdb.o(.text) + BUILD_DIR/libultra.a:osPiRawReadIo.o(.text) + BUILD_DIR/libultra.a:EU_D_802f4330.o(.text) + BUILD_DIR/libultra.a:D_802F4380.o(.text) + BUILD_DIR/libultra.a:func_802F4A20.o(.text) + BUILD_DIR/libultra.a:osTimer.o(.text) + BUILD_DIR/libultra.a:__osDisableInt.o(.text) + BUILD_DIR/libultra.a:__osRestoreInt.o(.text) + BUILD_DIR/libultra.a:osGetCount.o(.text) + BUILD_DIR/libultra.a:__osViInit.o(.text) + BUILD_DIR/libultra.a:__osDequeueThread.o(.text) + BUILD_DIR/libultra.a:osVirtualToPhysical.o(.text) + BUILD_DIR/libultra.a:__osSpSetStatus.o(.text) + BUILD_DIR/libultra.a:__osSpSetPc.o(.text) + BUILD_DIR/libultra.a:__osSpRawStartDma.o(.text) + BUILD_DIR/libultra.a:__osSpDeviceBusy.o(.text) + BUILD_DIR/libultra.a:__osSpGetStatus.o(.text) + BUILD_DIR/libultra.a:osGetThreadPri.o(.text) + BUILD_DIR/libultra.a:__osViGetCurrentContext.o(.text); + BUILD_DIR/libultra.a:__osViSwapContext.o(.text) + BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.text) + BUILD_DIR/libultra.a:osPiRawStartDma.o(.text) + BUILD_DIR/libultra.a:osEPiRawStartDma.o(.text) + BUILD_DIR/libultra.a:__osDevMgrMain.o(.text) + BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.text) + BUILD_DIR/libultra.a:__osSiRawStartDma.o(.text) + BUILD_DIR/libultra.a:osSetTimer.o(.text) + BUILD_DIR/libultra.a:osEepromWrite.o(.text) + BUILD_DIR/libultra.a:osJamMesg.o(.text) + BUILD_DIR/libultra.a:osPiGetCmdQueue.o(.text) + BUILD_DIR/libultra.a:osEepromRead.o(.text) + BUILD_DIR/libultra.a:guMtxF2L.o(.text) + BUILD_DIR/libultra.a:guNormalize.o(.text) + BUILD_DIR/libultra.a:__osAiDeviceBusy.o(.text); + BUILD_DIR/libultra.a:ldiv.o(.text) + BUILD_DIR/libultra.a:__osSiDeviceBusy.o(.text); + BUILD_DIR/libultra.a:osSetIntMask.o(.text) + BUILD_DIR/libultra.a:osDestroyThread.o(.text) + BUILD_DIR/libultra.a:osLeoDiskInit.o(.text) + BUILD_DIR/libultra.a:__osSetCompare.o(.text) + BUILD_DIR/libultra.a:__osProbeTLB.o(.text) + BUILD_DIR/libultra.a:__osDequeueThread.o(.text) + BUILD_DIR/libultra.a:func_802F7140.o(.text) + BUILD_DIR/libultra.a:func_802F71A0.o(.text) + BUILD_DIR/libultra.a:func_802F71F0.o(.text) + + BUILD_DIR/lib/rsp.o(.text); + +#else BUILD_DIR/src/game*.o(.text); BUILD_DIR/src/audio*.o(.text); -#if VERSION_US - . += 0x40; -#endif + BUILD_DIR/libultra.a:parameters.o(.text); BUILD_DIR/libultra.a:osSetTime.o(.text); BUILD_DIR/libultra.a:osMapTLB.o(.text); BUILD_DIR/libultra.a:osUnmapTLBAll.o(.text); @@ -213,7 +307,9 @@ SECTIONS BUILD_DIR/libultra.a:guTranslateF.o(.text); BUILD_DIR/libultra.a:guRotateF.o(.text); BUILD_DIR/libultra.a:guScaleF.o(.text); +#ifndef VERSION_EU BUILD_DIR/libultra.a:osAiSetFrequency.o(.text); +#endif BUILD_DIR/libultra.a:alBnkfNew.o(.text); BUILD_DIR/libultra.a:osWritebackDCache.o(.text); BUILD_DIR/libultra.a:osAiGetLength.o(.text); @@ -273,8 +369,9 @@ SECTIONS BUILD_DIR/libultra.a:__osGetCause.o(.text); BUILD_DIR/libultra.a:__osAtomicDec.o(.text); BUILD_DIR/libultra.a:guLookAtRef.o(.text); /* Fast3DEX2 only */ - BUILD_DIR/libultra.a:*.o(.text); BUILD_DIR/lib/rsp.o(.text); +#endif + /* data */ BUILD_DIR/src/game/crash_screen.o(.data*); BUILD_DIR/src/game/main.o(.data*); @@ -297,7 +394,9 @@ SECTIONS BUILD_DIR/src/game/profiler.o(.data*); BUILD_DIR/src/game/camera.o(.data*); BUILD_DIR/src/game/object_list_processor.o(.data*); +#ifndef VERSION_EU BUILD_DIR/src/game/object_helpers.o(.data*); +#endif BUILD_DIR/src/game/behavior_actions.o(.data*); BUILD_DIR/src/game/platform_displacement.o(.data*); BUILD_DIR/src/game/spawn_sound.o(.data*); @@ -316,10 +415,40 @@ SECTIONS BUILD_DIR/src/game/hud.o(.data*); BUILD_DIR/src/game/obj_behaviors.o(.data*); BUILD_DIR/src/game/obj_behaviors_2.o(.data*); +#ifndef VERSION_EU + /* wildcard doesn't work on EU due to files being moved to engine/ */ BUILD_DIR/src/game*.o(.data*); +#endif BUILD_DIR/src/audio/external.o(.data*); + BUILD_DIR/src/audio/port_eu.o(.data*); BUILD_DIR/src/audio/data.o(.data*); BUILD_DIR/src/audio*.o(.data*); + +#ifdef VERSION_EU + + BUILD_DIR/libultra.a:_Printf.o(.data*); + BUILD_DIR/libultra.a:osInitialize.o(.data*); + BUILD_DIR/libultra.a:osCreateViManager.o(.data*); + BUILD_DIR/libultra.a:osViTable.o(.data*); + BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); + BUILD_DIR/libultra.a:osContInit.o(.data*); + BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); + + BUILD_DIR/libultra.a:_Litob.o(.data*); + + BUILD_DIR/libultra.a:__osExceptionPreamble.o(.data*); + + BUILD_DIR/libultra.a:osTimer.o(.data*); + BUILD_DIR/libultra.a:__osViInit.o(.data*); + BUILD_DIR/libultra.a:__osDequeueThread.o(.data*); // ffff... + + BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.data*); + BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.data*); + BUILD_DIR/libultra.a:osViData.o(.data*); + +#else + + BUILD_DIR/libultra.a:osViTable.o(.data*); BUILD_DIR/libultra.a:osCreateViManager.o(.data*); BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); BUILD_DIR/libultra.a:osInitialize.o(.data*); @@ -339,6 +468,10 @@ SECTIONS BUILD_DIR/libultra.a:__osSyncPutChars.o(.data*); BUILD_DIR/libultra.a:guRotateF.o(.data*); BUILD_DIR/libultra.a:*.o(.data*); + +#endif + + /* rodata */ BUILD_DIR/src/game/crash_screen.o(.rodata*); BUILD_DIR/src/game/main.o(.rodata*); @@ -360,10 +493,14 @@ SECTIONS BUILD_DIR/src/game/rendering_graph_node.o(.rodata*); BUILD_DIR/src/game/camera.o(.rodata*); BUILD_DIR/src/game/object_list_processor.o(.rodata*); +#ifndef VERSION_EU BUILD_DIR/src/game/object_helpers.o(.rodata*); +#endif BUILD_DIR/src/game/behavior_actions.o(.rodata*); +#ifndef VERSION_EU BUILD_DIR/src/game/object_collision.o(.rodata*); BUILD_DIR/src/game/spawn_object.o(.rodata*); +#endif BUILD_DIR/src/game/spawn_sound.o(.rodata*); BUILD_DIR/src/game/debug.o(.rodata*); BUILD_DIR/src/game/screen_transition.o(.rodata*); @@ -380,14 +517,36 @@ SECTIONS BUILD_DIR/src/game/hud.o(.rodata*); BUILD_DIR/src/game/obj_behaviors.o(.rodata*); BUILD_DIR/src/game/obj_behaviors_2.o(.rodata*); +#ifndef VERSION_EU BUILD_DIR/src/game*.o(.rodata*); +#endif BUILD_DIR/src/audio/synthesis.o(.rodata*); BUILD_DIR/src/audio/memory.o(.rodata*); + BUILD_DIR/src/audio/load.o(.rodata*); BUILD_DIR/src/audio/playback.o(.rodata*); BUILD_DIR/src/audio/effects.o(.rodata*); BUILD_DIR/src/audio/seqplayer.o(.rodata*); BUILD_DIR/src/audio/external.o(.rodata*); + BUILD_DIR/src/audio/port_eu.o(.rodata*); BUILD_DIR/src/audio*.o(.rodata*); + +#ifdef VERSION_EU + BUILD_DIR/libultra.a:_Printf.o(.rodata*); + + BUILD_DIR/libultra.a:guPerspectiveF.o(.rodata*); + BUILD_DIR/libultra.a:llconv.o(.rodata*); + BUILD_DIR/libultra.a:cosf.o(.rodata*); + BUILD_DIR/libultra.a:sinf.o(.rodata*); + BUILD_DIR/libultra.a:guRotateF.o(.rodata*); + + BUILD_DIR/libultra.a:_Litob.o(.rodata*); + BUILD_DIR/libultra.a:_Ldtob.o(.rodata*); + + BUILD_DIR/libultra.a:__osExceptionPreamble.o(.rodata*); + BUILD_DIR/libultra.a:__osDevMgrMain.o(.rodata*); + + BUILD_DIR/libultra.a:NaN.o(.rodata*); +#else BUILD_DIR/libultra.a:guPerspectiveF.o(.rodata*); BUILD_DIR/libultra.a:llconv.o(.rodata*); BUILD_DIR/libultra.a:cosf.o(.rodata*); @@ -398,9 +557,12 @@ SECTIONS BUILD_DIR/libultra.a:NaN.o(.rodata*); BUILD_DIR/libultra.a:_Litob.o(.rodata*); BUILD_DIR/libultra.a:_Ldtob.o(.rodata*); +#endif BUILD_DIR/libultra.a:osSetIntMask.o(.rodata*); BUILD_DIR/libultra.a:guLookAtRef.o(.rodata*); /* Fast3DEX2 only */ +#ifndef VERSION_EU BUILD_DIR/libultra.a:*.o(.rodata*); +#endif BUILD_DIR/lib/rsp.o(.rodata*); } END_SEG(main) @@ -424,8 +586,9 @@ SECTIONS BUILD_DIR/src/game/profiler.o(.bss*); BUILD_DIR/src/game/camera.o(.bss*); BUILD_DIR/src/game/object_list_processor.o(.bss*); - BUILD_DIR/src/game/room.o(.bss*); +#ifndef VERSION_EU BUILD_DIR/src/game/object_helpers.o(.bss*); +#endif BUILD_DIR/src/game/behavior_actions.o(.bss*); BUILD_DIR/src/game/debug.o(.bss*); BUILD_DIR/src/game/shadow.o(.bss*); @@ -441,8 +604,39 @@ SECTIONS BUILD_DIR/src/game/hud.o(.bss*); BUILD_DIR/src/game/obj_behaviors.o(.bss*); BUILD_DIR/src/game/obj_behaviors_2.o(.bss*); +#ifndef VERSION_EU BUILD_DIR/src/game*.o(.bss*); +#endif BUILD_DIR/src/audio/external.o(.bss*); + BUILD_DIR/src/audio/port_eu.o(.bss*); + +#ifdef VERSION_EU + BUILD_DIR/libultra.a:osInitialize.o(.bss*); + + BUILD_DIR/libultra.a:osSetEventMesg.o(.bss*); + BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.bss*); + BUILD_DIR/libultra.a:osCreateViManager.o(.bss*); + + BUILD_DIR/libultra.a:osCreatePiManager.o(.bss*); + BUILD_DIR/libultra.a:osContStartReadData.o(.bss*); + BUILD_DIR/libultra.a:osContInit.o(.bss*); + + BUILD_DIR/libultra.a:guRotateF.o(.bss*); + + BUILD_DIR/libultra.a:unk_stack_data.o(.bss*); + BUILD_DIR/libultra.a:osTimer.o(.bss*); + BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); + BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); + BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); + + BUILD_DIR/libultra.a:kdebugserver.o(.bss*); + BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*) + + BUILD_DIR/libultra.a:_Printf.o(.bss*); + BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.bss*); + BUILD_DIR/libultra.a:EU_D_802f4330.o(.bss*); + +#else BUILD_DIR/libultra.a:osSetEventMesg.o(.bss*); BUILD_DIR/libultra.a:osSpTaskLoadGo.o(.bss*); BUILD_DIR/libultra.a:osCreateViManager.o(.bss*); @@ -456,8 +650,10 @@ SECTIONS BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); + BUILD_DIR/libultra.a:unk_stack_data.o(.bss*); BUILD_DIR/libultra.a:kdebugserver.o(.bss*); BUILD_DIR/libultra.a:*.o(.bss*); +#endif } END_NOLOAD(main) _mainSegmentNoloadSizeLo = SIZEOF (.main.noload) & 0xffff; @@ -475,6 +671,11 @@ SECTIONS BUILD_DIR/src/engine/surface_collision.o(.text); BUILD_DIR/src/engine/surface_load.o(.text); BUILD_DIR/src/engine/behavior_script.o(.text); +#ifdef VERSION_EU + BUILD_DIR/src/game/object_collision.o(.text); + BUILD_DIR/src/game/spawn_object.o(.text); + BUILD_DIR/src/game/object_helpers.o(.text); +#endif BUILD_DIR/src/engine*.o(.text); /* data */ BUILD_DIR/src/engine/graph_node.o(.data*); @@ -483,12 +684,22 @@ SECTIONS BUILD_DIR/src/engine/geo_layout.o(.data*); BUILD_DIR/src/engine/level_script.o(.data*); BUILD_DIR/src/engine/behavior_script.o(.data*); +#ifdef VERSION_EU + BUILD_DIR/src/game/object_collision.o(.data*); + BUILD_DIR/src/game/spawn_object.o(.data*); + BUILD_DIR/src/game/object_helpers.o(.data*); +#endif BUILD_DIR/src/engine*.o(.data*); /* rodata */ BUILD_DIR/src/engine/math_util.o(.rodata*); BUILD_DIR/src/engine/level_script.o(.rodata*); BUILD_DIR/src/engine/surface_collision.o(.rodata*); BUILD_DIR/src/engine/surface_load.o(.rodata*); +#ifdef VERSION_EU + BUILD_DIR/src/game/object_collision.o(.rodata*); + BUILD_DIR/src/game/spawn_object.o(.rodata*); + BUILD_DIR/src/game/object_helpers.o(.rodata*); +#endif BUILD_DIR/src/engine*.o(.rodata*); } END_SEG(engine) @@ -500,11 +711,16 @@ SECTIONS BUILD_DIR/src/engine/surface_collision.o(.bss*); BUILD_DIR/src/engine/surface_load.o(.bss*); BUILD_DIR/src/engine/behavior_script.o(.bss*); +#ifdef VERSION_EU + BUILD_DIR/src/game/object_collision.o(.bss*); + BUILD_DIR/src/game/spawn_object.o(.bss*); + BUILD_DIR/src/game/object_helpers.o(.bss*); +#endif BUILD_DIR/src/engine*.o(.bss*); } END_NOLOAD(engine) - ASSERT((. <= SEG_FRAMEBUFFERS), "Error: engine segment extended into framebuffers.") + // ASSERT((. <= SEG_FRAMEBUFFERS), "Error: engine segment extended into framebuffers.") . = SEG_FRAMEBUFFERS; BEGIN_NOLOAD(framebuffers) @@ -656,14 +872,22 @@ SECTIONS { BUILD_DIR/src/buffers/buffers.o(.bss*); BUILD_DIR/src/audio/globals_start.o(.bss*); + BUILD_DIR/src/audio/synthesis.o(.bss*); BUILD_DIR/src/audio/memory.o(.bss*); BUILD_DIR/src/audio/load.o(.bss*); BUILD_DIR/src/audio/data.o(.bss*); BUILD_DIR/src/audio/globals_end.o(.bss*); - BUILD_DIR/src/audio*.o(.bss*); +#ifdef VERSION_EU + . += 0x4f0; +#endif + +#ifndef VERSION_EU . = ALIGN(0x1000); +#endif BUILD_DIR/src/buffers/gfx_output_buffer.o(.bss*); + + BUILD_DIR/src/audio*.o(.bss*); } END_NOLOAD(buffers) diff --git a/src/audio/data.c b/src/audio/data.c index 23331e9..b1ab8b1 100644 --- a/src/audio/data.c +++ b/src/audio/data.c @@ -4,6 +4,40 @@ #include "data.h" #include "effects.h" +extern struct OSMesgQueue *OSMesgQueue0; +extern struct OSMesgQueue *OSMesgQueue1; +extern struct OSMesgQueue *OSMesgQueue2; +extern struct OSMesgQueue *OSMesgQueue3; + +#ifdef VERSION_EU +struct ReverbSettingsEU sReverbSettings[] = { + { 0x04, 0x0c, 0x2fff }, + { 0x04, 0x0a, 0x47ff }, + { 0x04, 0x10, 0x2fff }, + { 0x04, 0x0e, 0x3fff }, + { 0x04, 0x0c, 0x4fff }, + { 0x04, 0x0a, 0x37ff } +}; +struct AudioSessionSettingsEU gAudioSessionPresets[] = { + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[2], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[3], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[4], 0x7fff, 0x0000, 0x00003a40, 0x00006d00, + 0x00004400, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[0], 0x7fff, 0x0000, 0x00004000, 0x00006e00, + 0x00003f00, 0x00002a00 }, + { 0x00007d00, 0x01, 0x10, 0x01, 0x00, &sReverbSettings[1], 0x7fff, 0x0000, 0x00004100, 0x00006e00, + 0x00004400, 0x00002a80 }, + { 0x00007d00, 0x01, 0x14, 0x01, 0x00, &sReverbSettings[5], 0x7fff, 0x0000, 0x00003500, 0x00006280, + 0x00004000, 0x00001b00 } +}; +#endif + // Format: // - frequency // - max number of simultaneous notes @@ -15,6 +49,7 @@ // - memory used for persistent banks // - memory used for temporary sequences // - memory used for temporary banks +#ifndef VERSION_EU struct AudioSessionSettings gAudioSessionPresets[18] = { #ifdef VERSION_JP { 32000, 16, 1, 0x0800, 0x2FFF, 0x7FFF, 0x3900, 0x6000, 0x4400, 0x2A00 }, @@ -46,8 +81,9 @@ struct AudioSessionSettings gAudioSessionPresets[18] = { { 32000, 8, 1, 0x0800, 0x2FFF, 0x7FFF, 0x2500, 0x5500, 0x7400, 0x2400 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; - +#endif // gAudioCosineTable[k] = round((2**15 - 1) * cos(pi/2 * k / 127)). Unused. +#ifndef VERSION_EU u16 gAudioCosineTable[128] = { 0x7FFF, 32764, 32757, 32744, 32727, 32704, 32677, 32644, 32607, 32564, 32517, 32464, 32407, 32344, 32277, 32205, 32127, 32045, 31958, 31866, 31770, 31668, 31561, 31450, 31334, 31213, @@ -60,11 +96,17 @@ u16 gAudioCosineTable[128] = { 9196, 8806, 8415, 8023, 7630, 7235, 6839, 6442, 6044, 5646, 5246, 4845, 4444, 4042, 3640, 3237, 2833, 2429, 2025, 1620, 1216, 810, 405, 0, }; +#endif // Transforms a pitch scale factor in -127..127 into a frequency scale factor // between -1 and +1 octave. // gPitchBendFrequencyScale[k] = 0.5 * 2^(k/127) +#ifdef VERSION_EU +f32 gPitchBendFrequencyScale[256] = { + 0.5f, +#else f32 gPitchBendFrequencyScale[255] = { +#endif 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, 0.551614f, 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, @@ -127,15 +169,176 @@ u8 gDefaultShortNoteDurationTable[16] = { 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, }; +#ifndef VERSION_EU // gVibratoCurve[k] = k*8 s8 gVibratoCurve[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }; +#endif struct AdsrEnvelope gDefaultEnvelope[] = { { BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms { BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds - { BSWAP16(ADSR_HANG), 0 } // then continue staying there + { BSWAP16(ADSR_HANG), 0 } // then continue staying there }; +#ifdef VERSION_EU +struct NoteSubEu gZeroNoteSub = { 0 }; +struct NoteSubEu gDefaultNoteSub = { 1, 1 }; + +s16 sSawtoothWaves[256] = { + 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, + 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, + 22527, 23551, 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, -0x7FFF, + -31743, -30719, -29695, -28671, -27647, -26623, -25599, -24575, -23551, -22527, -21503, + -0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239, + -9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, + 0, 0x7FF, 0xFFF, 0x17FF, 0x1FFF, 0x27FF, 0x2FFF, 0x37FF, 0x3FFF, 0x47FF, 0x4FFF, + 0x57FF, 0x5FFF, 0x67FF, 0x6FFF, 0x77FF, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, + 0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801, 0x0000, + 0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff, + 0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001, + 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, 0xe001, 0xe801, 0xf001, 0xf801, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x8001, 0xa001, 0xc001, 0xe001 +}; +s16 sTriangleWaves[256] = { + 0x0000, 0x07ff, 0x0fff, 0x17ff, 0x1fff, 0x27ff, 0x2fff, 0x37ff, 0x3fff, 0x47ff, 0x4fff, 0x57ff, + 0x5fff, 0x67ff, 0x6fff, 0x77ff, 0x7fff, 0x77ff, 0x6fff, 0x67ff, 0x5fff, 0x57ff, 0x4fff, 0x47ff, + 0x3fff, 0x37ff, 0x2fff, 0x27ff, 0x1fff, 0x17ff, 0x0fff, 0x07ff, 0x0000, 0xf801, 0xf001, 0xe801, + 0xe001, 0xd801, 0xd001, 0xc801, 0xc001, 0xb801, 0xb001, 0xa801, 0xa001, 0x9801, 0x9001, 0x8801, + 0x8001, 0x8801, 0x9001, 0x9801, 0xa001, 0xa801, 0xb001, 0xb801, 0xc001, 0xc801, 0xd001, 0xd801, + 0xe001, 0xe801, 0xf001, 0xf801, 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, + 0x7fff, 0x6fff, 0x5fff, 0x4fff, 0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001, + 0xc001, 0xb001, 0xa001, 0x9001, 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, + 0x0000, 0x0fff, 0x1fff, 0x2fff, 0x3fff, 0x4fff, 0x5fff, 0x6fff, 0x7fff, 0x6fff, 0x5fff, 0x4fff, + 0x3fff, 0x2fff, 0x1fff, 0x0fff, 0x0000, 0xf001, 0xe001, 0xd001, 0xc001, 0xb001, 0xa001, 0x9001, + 0x8001, 0x9001, 0xa001, 0xb001, 0xc001, 0xd001, 0xe001, 0xf001, 0x0000, 0x1fff, 0x3fff, 0x5fff, + 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, + 0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff, 0x7fff, 0x5fff, 0x3fff, 0x1fff, + 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, 0x0000, 0x1fff, 0x3fff, 0x5fff, + 0x7fff, 0x5fff, 0x3fff, 0x1fff, 0x0000, 0xe001, 0xc001, 0xa001, 0x8001, 0xa001, 0xc001, 0xe001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, + 0x0000, 0x3fff, 0x7fff, 0x3fff, 0x0000, 0xc001, 0x8001, 0xc001, 0x0000, 0x3fff, 0x7fff, 0x3fff, + 0x0000, 0xc001, 0x8001, 0xc001, +}; +s16 sSineWaves[256] = { + 0x0000, 0x0c8b, 0x18f8, 0x2527, 0x30fb, 0x3c56, 0x471c, 0x5133, 0x5a81, 0x62f1, 0x6a6c, 0x70e1, + 0x7640, 0x7a7c, 0x7d89, 0x7f61, 0x7fff, 0x7f61, 0x7d89, 0x7a7c, 0x7640, 0x70e1, 0x6a6c, 0x62f1, + 0x5a81, 0x5133, 0x471c, 0x3c56, 0x30fb, 0x2527, 0x18f8, 0x0c8b, 0x0000, 0xf375, 0xe708, 0xdad9, + 0xcf05, 0xc3aa, 0xb8e4, 0xaecd, 0xa57f, 0x9d0f, 0x9594, 0x8f1f, 0x89c0, 0x8584, 0x8277, 0x809f, + 0x8001, 0x809f, 0x8277, 0x8584, 0x89c0, 0x8f1f, 0x9594, 0x9d0f, 0xa57f, 0xaecd, 0xb8e4, 0xc3aa, + 0xcf05, 0xdad9, 0xe708, 0xf375, 0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89, + 0x7fff, 0x7d89, 0x7640, 0x6a6c, 0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4, + 0xa57f, 0x9594, 0x89c0, 0x8277, 0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708, + 0x0000, 0x18f8, 0x30fb, 0x471c, 0x5a81, 0x6a6c, 0x7640, 0x7d89, 0x7fff, 0x7d89, 0x7640, 0x6a6c, + 0x5a81, 0x471c, 0x30fb, 0x18f8, 0x0000, 0xe708, 0xcf05, 0xb8e4, 0xa57f, 0x9594, 0x89c0, 0x8277, + 0x8001, 0x8277, 0x89c0, 0x9594, 0xa57f, 0xb8e4, 0xcf05, 0xe708, 0x0000, 0x30fb, 0x5a81, 0x7640, + 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, + 0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, + 0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640, 0x7fff, 0x7640, 0x5a81, 0x30fb, + 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, 0x0000, 0x30fb, 0x5a81, 0x7640, + 0x7fff, 0x7640, 0x5a81, 0x30fb, 0x0000, 0xcf05, 0xa57f, 0x89c0, 0x8001, 0x89c0, 0xa57f, 0xcf05, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, + 0x0000, 0x5a81, 0x7fff, 0x5a81, 0x0000, 0xa57f, 0x8001, 0xa57f, 0x0000, 0x5a81, 0x7fff, 0x5a81, + 0x0000, 0xa57f, 0x8001, 0xa57f, +}; +s16 sSquareWaves[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x8001, 0x8001, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, + 0x0000, 0x0000, 0x7fff, 0x7fff, 0x0000, 0x0000, 0x8001, 0x8001, 0x0000, 0x0000, 0x7fff, 0x7fff, + 0x0000, 0x0000, 0x8001, 0x8001, +}; +s16 sEuUnknownWave6[256] = { + 0x0000, 0x9ba7, 0x9b41, 0x6c9b, 0x9450, 0xadda, 0x569e, 0x189a, 0x69bf, 0xb79d, 0x6fe9, 0x08ec, + 0x0d34, 0x1aea, 0xce76, 0xad86, 0x2710, 0xa038, 0x7e28, 0x2fd8, 0x3af8, 0x3bfa, 0xd10b, 0x84c7, + 0xcd7f, 0x18f4, 0xd4c8, 0x76f8, 0x8994, 0xaa11, 0x73fb, 0x6c01, 0x0000, 0x93ff, 0x8c05, 0x55ef, + 0x766c, 0x8907, 0x2b38, 0xe70d, 0x3281, 0x7b38, 0x2ef5, 0xc407, 0xc508, 0xd027, 0x81d8, 0x5fc9, + 0xd8f0, 0x5279, 0x318a, 0xe517, 0xf2cc, 0xf713, 0x9017, 0x4864, 0x9641, 0xe765, 0xa962, 0x5227, + 0x6bb0, 0x9364, 0x64bf, 0x645a, 0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76, + 0x2710, 0x7e28, 0x3af8, 0xd10b, 0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38, + 0x3281, 0x2ef5, 0xc508, 0x81d8, 0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf, + 0x0000, 0x9b41, 0x9450, 0x569e, 0x69bf, 0x6fe9, 0x0d34, 0xce76, 0x2710, 0x7e28, 0x3af8, 0xd10b, + 0xcd7f, 0xd4c8, 0x8994, 0x73fb, 0x0000, 0x8c05, 0x766c, 0x2b38, 0x3281, 0x2ef5, 0xc508, 0x81d8, + 0xd8f0, 0x318a, 0xf2cc, 0x9017, 0x9641, 0xa962, 0x6bb0, 0x64bf, 0x0000, 0x9450, 0x69bf, 0x0d34, + 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, + 0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, + 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34, 0x2710, 0x3af8, 0xcd7f, 0x8994, + 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, 0x0000, 0x9450, 0x69bf, 0x0d34, + 0x2710, 0x3af8, 0xcd7f, 0x8994, 0x0000, 0x766c, 0x3281, 0xc508, 0xd8f0, 0xf2cc, 0x9641, 0x6bb0, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, + 0x0000, 0x69bf, 0x2710, 0xcd7f, 0x0000, 0x3281, 0xd8f0, 0x9641, 0x0000, 0x69bf, 0x2710, 0xcd7f, + 0x0000, 0x3281, 0xd8f0, 0x9641, +}; +s16 gEuUnknownWave7[256] = { + 0x0000, 0x3fbc, 0x4eb4, 0x4f21, 0x6a49, 0x806f, 0x7250, 0x6a7b, 0x8d2e, 0xac0a, 0x98d6, 0x7832, + 0x7551, 0x71ca, 0x4eee, 0x3731, 0x4e20, 0x644d, 0x4a50, 0x23ba, 0x1b09, 0x119a, 0xe914, 0xccbe, + 0xe14e, 0xf8a3, 0xe47e, 0xc937, 0xd181, 0xde39, 0xcfc6, 0xcf94, 0x0000, 0x306c, 0x303a, 0x21c7, + 0x2e7f, 0x36c8, 0x1b82, 0x075e, 0x1eb2, 0x3341, 0x16ec, 0xee67, 0xe4f7, 0xdc45, 0xb5b0, 0x9bb4, + 0xb1e0, 0xc8ce, 0xb112, 0x8e37, 0x8aaf, 0x87cd, 0x672a, 0x53f7, 0x72d2, 0x9584, 0x8db0, 0x7f92, + 0x95b7, 0xb0de, 0xb14c, 0xc045, 0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee, + 0x4e20, 0x4a50, 0x1b09, 0xe914, 0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82, + 0x1eb2, 0x16ec, 0xe4f7, 0xb5b0, 0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c, + 0x0000, 0x4eb4, 0x6a49, 0x7250, 0x8d2e, 0x98d6, 0x7551, 0x4eee, 0x4e20, 0x4a50, 0x1b09, 0xe914, + 0xe14e, 0xe47e, 0xd181, 0xcfc6, 0x0000, 0x303a, 0x2e7f, 0x1b82, 0x1eb2, 0x16ec, 0xe4f7, 0xb5b0, + 0xb1e0, 0xb112, 0x8aaf, 0x672a, 0x72d2, 0x8db0, 0x95b7, 0xb14c, 0x0000, 0x6a49, 0x8d2e, 0x7551, + 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, + 0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, + 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551, 0x4e20, 0x1b09, 0xe14e, 0xd181, + 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, 0x0000, 0x6a49, 0x8d2e, 0x7551, + 0x4e20, 0x1b09, 0xe14e, 0xd181, 0x0000, 0x2e7f, 0x1eb2, 0xe4f7, 0xb1e0, 0x8aaf, 0x72d2, 0x95b7, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, + 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, + 0x0000, 0x1eb2, 0xb1e0, 0x72d2, +}; +// u8 buffer_remove2[764] = { 0 }; +s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 }; +#endif + +#ifndef VERSION_EU s16 sSineWave[0x40] = { 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897, @@ -144,6 +347,7 @@ s16 sSineWave[0x40] = { -30272, -31356, -32137, -32609, -0x7FFF, -32609, -32137, -31356, -30272, -28897, -27244, -25329, -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, }; + s16 sSquareWave[0x40] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, @@ -160,6 +364,7 @@ s16 sTriangleWave[0x40] = { -24575, -26623, -28671, -30719, -0x7FFF, -30719, -28671, -26623, -24575, -22527, -0x4FFF, -0x47FF, -0x3FFF, -0x37FF, -0x2FFF, -0x27FF, -0x1FFF, -0x17FF, -0xFFF, -0x7FF, }; + s16 sSawtoothWave[0x40] = { 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, 11263, 0x2FFF, 13311, 0x37FF, 15359, 0x3FFF, 17407, 0x47FF, 19455, 0x4FFF, 21503, @@ -168,10 +373,21 @@ s16 sSawtoothWave[0x40] = { -0x4FFF, -19455, -0x47FF, -17407, -0x3FFF, -15359, -0x37FF, -13311, -0x2FFF, -11263, -10239, -9215, -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, }; - s16 *gWaveSamples[4] = { sSawtoothWave, sTriangleWave, sSineWave, sSquareWave }; +#endif +#ifdef VERSION_EU +u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 }; +u16 gHeadsetPanQuantization[0x10] = { + 0x40, 0x40, 0x30, 0x30, 0x20, 0x20, 0x10, 0, 0, 0, +}; +s32 euUnknownData_80301950[32] = { //maybe envelope of some kind? + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 500, 0, 0, 0, 500, 0, 0, 0, 500, 0, 0, 0, 500, 0, 0, +}; +#else u16 gHeadsetPanQuantization[10] = { 0x40, 0x30, 0x20, 0x10, 0, 0, 0, 0, 0, 0 }; +#endif // Linearly interpolated between // f(0/2 * 127) = 1 @@ -238,6 +454,7 @@ f32 gDefaultPanVolume[128] = { 0.012368f, 0.0f }; +#ifndef VERSION_EU // gVolRampingLhs136[k] = 2^16 * max(1, (256*k)^(1/17) f32 gVolRampingLhs136[128] = { 65536.0f, 90811.555f, 94590.766f, 96873.96f, 98527.26f, 99829.06f, 100905.47f, @@ -363,29 +580,31 @@ f32 gVolRampingRhs128[128] = { 0.525077f, 0.524798f, 0.524522f, 0.524247f, 0.523975f, 0.523706f, 0.523439f, 0.523174f, 0.522911f, 0.522651f, 0.522393f }; +#endif s16 gTatumsPerBeat = TATUMS_PER_BEAT; -s8 gUnusedCount80333EE8 = 16; -s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(0x31150); -s32 D_80333EF0 = DOUBLE_SIZE_ON_64_BIT(0x2500); +s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8; +s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE); +s32 D_80333EF0 = DOUBLE_SIZE_ON_64_BIT(D_80333EF0_VAL); volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; +#ifdef VERSION_EU +u8 bufferDelete2[12] = { 0 }; +u8 D_EU_80302010 = 0; +u8 D_EU_80302014 = 0; +struct OSMesgQueue *OSMesgQueues[4] = { &OSMesgQueue0, &OSMesgQueue1, &OSMesgQueue2, &OSMesgQueue3 }; // { 0x80332e40, 0x80332e58, 0x80332e70, 0x80332e88 }; +#else s8 sUnused8033EF8 = 24; +#endif // .bss -struct CtlEntry *gCtlEntries; -s32 gAiFrequency; -u32 D_80226D68; -s32 gMaxAudioCmds; - -s32 gMaxSimultaneousNotes; -s32 gSamplesPerFrameTarget; -s32 gMinAiBufferLength; -s16 gTempoInternalToExternal; -s8 gAudioUpdatesPerFrame; -s8 gSoundMode; volatile s32 gAudioFrameCount; + +#ifdef VERSION_EU +s32 gCurrAudioFrameDmaCount; +#else volatile s32 gCurrAudioFrameDmaCount; +#endif s32 gAudioTaskIndex; s32 gCurrAiBufferIndex; @@ -396,10 +615,23 @@ u64 *gAudioCmd; struct SPTask *gAudioTask; struct SPTask gAudioTasks[2]; +#ifdef VERSION_EU +f32 D_EU_802298D0; +s32 gRefreshRate; +#endif + u16 *gAiBuffers[NUMAIBUFFERS]; s16 gAiBufferLengths[NUMAIBUFFERS]; +#ifdef VERSION_EU +u32 gAudioRandom; +s32 gAudioErrorFlags; +u64 gAudioGlobalsEndMarker; +#endif + +#ifndef VERSION_EU u32 gUnused80226E58[0x10]; u16 gUnused80226E98[0x10]; u32 gAudioRandom; +#endif diff --git a/src/audio/data.h b/src/audio/data.h index f88901b..62a3392 100644 --- a/src/audio/data.h +++ b/src/audio/data.h @@ -10,10 +10,18 @@ #define NUMAIBUFFERS 3 // constant .data +#ifdef VERSION_EU +extern struct AudioSessionSettingsEU gAudioSessionPresets[]; +#else extern struct AudioSessionSettings gAudioSessionPresets[18]; +#endif extern u16 D_80332388[128]; // unused +#ifdef VERSION_EU +extern f32 gPitchBendFrequencyScale[256]; +#else extern f32 gPitchBendFrequencyScale[255]; +#endif extern f32 gNoteFrequencies[128]; extern u8 gDefaultShortNoteVelocityTable[16]; @@ -21,9 +29,22 @@ extern u8 gDefaultShortNoteDurationTable[16]; extern s8 gVibratoCurve[16]; extern struct AdsrEnvelope gDefaultEnvelope[3]; +#ifdef VERSION_EU +extern s16 gEuUnknownWave7[256]; +extern s16 *gWaveSamples[6]; +#else extern s16 *gWaveSamples[4]; +#endif +#ifdef VERSION_EU +extern u8 euUnknownData_8030194c[4]; +extern u16 gHeadsetPanQuantization[0x10]; +extern s32 euUnknownData_80301950[32]; +extern struct NoteSubEu gZeroNoteSub; +extern struct NoteSubEu gDefaultNoteSub; +#else extern u16 gHeadsetPanQuantization[10]; +#endif extern f32 gHeadsetPanVolume[128]; extern f32 gStereoPanVolume[128]; extern f32 gDefaultPanVolume[128]; @@ -43,20 +64,14 @@ extern s32 D_80333EF0; // amount of heap designated to gAudioInitPool, 0x2500 extern volatile s32 gAudioLoadLock; // .bss -extern struct CtlEntry *gCtlEntries; -extern s32 gAiFrequency; -extern u32 D_80226D68; -extern s32 gMaxAudioCmds; - -extern s32 gMaxSimultaneousNotes; -extern s32 gSamplesPerFrameTarget; -extern s32 gMinAiBufferLength; -extern s16 gTempoInternalToExternal; -extern s8 gAudioUpdatesPerFrame; // = 4 -extern s8 gSoundMode; - extern volatile s32 gAudioFrameCount; -extern volatile s32 gCurrAudioFrameDmaCount; // number of DMAs performed during this frame + +// number of DMAs performed during this frame +#ifdef VERSION_EU +extern s32 gCurrAudioFrameDmaCount; +#else +extern volatile s32 gCurrAudioFrameDmaCount; +#endif extern s32 gAudioTaskIndex; extern s32 gCurrAiBufferIndex; @@ -67,12 +82,34 @@ extern u64 *gAudioCmd; extern struct SPTask *gAudioTask; extern struct SPTask gAudioTasks[2]; +#ifdef VERSION_EU +extern f32 D_EU_802298D0; +extern s32 gRefreshRate; +#endif + extern u16 *gAiBuffers[NUMAIBUFFERS]; extern s16 gAiBufferLengths[NUMAIBUFFERS]; +#ifdef VERSION_EU +#define AIBUFFER_LEN (0xa0 * 17) +#else +#define AIBUFFER_LEN (0xa0 * 16) +#endif extern u32 gUnused80226E58[0x10]; extern u16 gUnused80226E98[0x10]; extern u32 gAudioRandom; +//make my life easier +#ifdef VERSION_EU +#define UNUSED_COUNT_80333EE8 24 +#define AUDIO_HEAP_SIZE 0x2c500 +#define D_80333EF0_VAL 0x2c00 +#else +#define UNUSED_COUNT_80333EE8 16 +#define AUDIO_HEAP_SIZE 0x31150 +#define D_80333EF0_VAL 0x2500 +#endif + + #endif /* AUDIO_DATA_H */ diff --git a/src/audio/effects.c b/src/audio/effects.c index 6c1e999..4ace804 100644 --- a/src/audio/effects.c +++ b/src/audio/effects.c @@ -12,14 +12,59 @@ #define US_FLOAT2(x) x #endif +#ifdef VERSION_EU +void sequence_channel_process_sound(struct SequenceChannel *seqChannel, s32 arg1) { + f32 weight; + s32 i; + + if (seqChannel->unk1.as_bitfields.unk0b40 || arg1) { + weight = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->unkEu2C; + if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) { + weight = seqChannel->seqPlayer->muteVolumeScale * weight; + } + seqChannel->panChannelWeight = weight; + } + + if (seqChannel->unk1.as_bitfields.unk0b20) { + seqChannel->pan = seqChannel->unk9 * seqChannel->unkA; + } + + for (i = 0; i < 4; ++i) { + struct SequenceChannelLayer *layer = seqChannel->layers[i]; + if (layer && layer->enabled && layer->note) { + if (layer->unkEu0b4) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + layer->noteVelocity = layer->velocitySquare * seqChannel->panChannelWeight; + layer->notePan = (seqChannel->pan + layer->euUnk5 * (0x80 - seqChannel->unkA)) >> 7; + layer->unkEu0b4 = 0; + } else { + if (seqChannel->unk1.as_bitfields.unk0b80) { + layer->noteFreqScale = layer->freqScale * seqChannel->freqScale; + } + if (seqChannel->unk1.as_bitfields.unk0b40 || arg1) { + layer->noteVelocity = layer->velocitySquare * seqChannel->panChannelWeight; + } + if (seqChannel->unk1.as_bitfields.unk0b20) { + layer->notePan = (seqChannel->pan + layer->euUnk5 * (0x80 - seqChannel->unkA)) >> 7; + } + } + } + } + seqChannel->unk1.as_u8 = 0; +} +#else void func_80319E70(void) { } +#endif void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { s32 i; if (seqPlayer->fadeTimer != 0) { seqPlayer->fadeVolume += seqPlayer->fadeVelocity; +#ifdef VERSION_EU + seqPlayer->unk_eu = TRUE; +#endif if (seqPlayer->fadeVolume > US_FLOAT2(1)) { seqPlayer->fadeVolume = US_FLOAT2(1); @@ -29,6 +74,12 @@ void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { } if (--seqPlayer->fadeTimer == 0) { +#ifdef VERSION_EU + if (seqPlayer->state == 2) { + sequence_player_disable(seqPlayer); + return; + } +#else switch (seqPlayer->state) { case SEQUENCE_PLAYER_STATE_FADE_OUT: sequence_player_disable(seqPlayer); @@ -42,13 +93,23 @@ void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { case SEQUENCE_PLAYER_STATE_4: break; } +#endif } } +#ifdef VERSION_EU + if (seqPlayer->unk_eu) { + seqPlayer->unkEu2C = seqPlayer->fadeVolume * seqPlayer->unkEu28; + } +#endif + // Process channels for (i = 0; i < CHANNELS_MAX; i++) { if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE && seqPlayer->channels[i]->enabled == TRUE) { +#ifdef VERSION_EU + sequence_channel_process_sound(seqPlayer->channels[i], seqPlayer->unk_eu); +#else f32 channelVolume; f32 panLayerWeight; f32 panFromChannel; @@ -72,28 +133,52 @@ void sequence_player_process_sound(struct SequencePlayer *seqPlayer) { seqLayer->notePan = (seqLayer->pan * panLayerWeight) + panFromChannel; } } +#endif } } + +#ifdef VERSION_EU + seqPlayer->unk_eu = FALSE; +#endif } f32 get_portamento_freq_scale(struct Portamento *p) { u32 v0; f32 result; +#ifndef VERSION_EU if (p->mode == 0) { return 1.0f; } +#endif p->cur += p->speed; v0 = (u32) p->cur; - if (v0 >= 127) { +#ifdef VERSION_EU + if (v0 > 127) +#else + if (v0 >= 127) +#endif + { v0 = 127; } +#ifdef VERSION_EU + result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 128] - US_FLOAT(1.0)); +#else result = US_FLOAT(1.0) + p->extent * (gPitchBendFrequencyScale[v0 + 127] - US_FLOAT(1.0)); +#endif return result; } +#ifdef VERSION_EU +s16 get_vibrato_pitch_change(struct VibratoState *vib) { + s32 index; + vib->time += (s32) vib->rate; + index = (vib->time >> 10) & 0x3F; + return vib->curve[index] >> 8; +} +#else s8 get_vibrato_pitch_change(struct VibratoState *vib) { s32 index; vib->time += vib->rate; @@ -118,9 +203,10 @@ s8 get_vibrato_pitch_change(struct VibratoState *vib) { return -vib->curve[index]; } +#endif f32 get_vibrato_freq_scale(struct VibratoState *vib) { - s8 pitchChange; + s32 pitchChange; f32 extent; f32 result; @@ -131,37 +217,47 @@ f32 get_vibrato_freq_scale(struct VibratoState *vib) { if (vib->extentChangeTimer) { if (vib->extentChangeTimer == 1) { - vib->extent = vib->seqChannel->vibratoExtentTarget; + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; } else { vib->extent += - (vib->seqChannel->vibratoExtentTarget - vib->extent) / vib->extentChangeTimer; + ((s32) vib->seqChannel->vibratoExtentTarget - vib->extent) / (s32) vib->extentChangeTimer; } vib->extentChangeTimer--; - } else { - if (vib->extent != vib->seqChannel->vibratoExtentTarget) { - vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay; - if (vib->extentChangeTimer == 0) { - vib->extent = vib->seqChannel->vibratoExtentTarget; - } +#ifdef VERSION_EU + } else if ((s32) vib->extent != (*vib).seqChannel->vibratoExtentTarget) { + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; } +#else + } else if ((s32) vib->extent != vib->seqChannel->vibratoExtentTarget) { + vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay; + if (vib->extentChangeTimer == 0) { + vib->extent = (s32) vib->seqChannel->vibratoExtentTarget; + } +#endif } if (vib->rateChangeTimer) { if (vib->rateChangeTimer == 1) { - vib->rate = vib->seqChannel->vibratoRateTarget; + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; } else { - vib->rate += (vib->seqChannel->vibratoRateTarget - vib->rate) / vib->rateChangeTimer; + vib->rate += ((s32) vib->seqChannel->vibratoRateTarget - vib->rate) / (s32) vib->rateChangeTimer; } vib->rateChangeTimer--; - } else { - if (vib->rate != vib->seqChannel->vibratoRateTarget) { - vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay; - if (vib->rateChangeTimer == 0) { - vib->rate = vib->seqChannel->vibratoRateTarget; - } +#ifdef VERSION_EU + } else if ((s32) vib->rate != (*vib).seqChannel->vibratoRateTarget) { + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; } +#else + } else if ((s32) vib->rate != vib->seqChannel->vibratoRateTarget) { + vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay; + if (vib->rateChangeTimer == 0) { + vib->rate = (s32) vib->seqChannel->vibratoRateTarget; + } +#endif } if (vib->extent == 0) { @@ -171,39 +267,76 @@ f32 get_vibrato_freq_scale(struct VibratoState *vib) { pitchChange = get_vibrato_pitch_change(vib); extent = (f32) vib->extent / US_FLOAT(4096.0); +#ifdef VERSION_EU + result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 128] - US_FLOAT(1.0)); +#else result = US_FLOAT(1.0) + extent * (gPitchBendFrequencyScale[pitchChange + 127] - US_FLOAT(1.0)); +#endif return result; } void note_vibrato_update(struct Note *note) { +#ifdef VERSION_EU + if (note->portamento.mode != 0) { + note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); + } + if (note->vibratoState.active && note->parentLayer != NO_LAYER) { + note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); + } +#else if (note->vibratoState.active) { note->portamentoFreqScale = get_portamento_freq_scale(¬e->portamento); if (note->parentLayer != NO_LAYER) { note->vibratoFreqScale = get_vibrato_freq_scale(¬e->vibratoState); } } +#endif } void note_vibrato_init(struct Note *note) { struct VibratoState *vib; - struct SequenceChannel *seqChannel; + UNUSED struct SequenceChannel *seqChannel; +#ifdef VERSION_EU + struct NotePlaybackState *seqPlayerState = (struct NotePlaybackState *) ¬e->priority; +#endif + note->vibratoFreqScale = 1.0f; note->portamentoFreqScale = 1.0f; vib = ¬e->vibratoState; +#ifndef VERSION_EU if (note->parentLayer->seqChannel->vibratoExtentStart == 0 && note->parentLayer->seqChannel->vibratoExtentTarget == 0 && note->parentLayer->portamento.mode == 0) { vib->active = FALSE; return; } +#endif vib->active = TRUE; vib->time = 0; + +#ifdef VERSION_EU + vib->curve = gWaveSamples[2]; + vib->seqChannel = note->parentLayer->seqChannel; + if ((vib->extentChangeTimer = vib->seqChannel->vibratoExtentChangeDelay) == 0) { + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentTarget); + } else { + vib->extent = FLOAT_CAST(vib->seqChannel->vibratoExtentStart); + } + + if ((vib->rateChangeTimer = vib->seqChannel->vibratoRateChangeDelay) == 0) { + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateTarget); + } else { + vib->rate = FLOAT_CAST(vib->seqChannel->vibratoRateStart); + } + vib->delay = vib->seqChannel->vibratoDelay; + + seqPlayerState->portamento = seqPlayerState->parentLayer->portamento; +#else vib->curve = gVibratoCurve; vib->seqChannel = note->parentLayer->seqChannel; - seqChannel = vib->seqChannel; vib->extentChangeTimer = seqChannel->vibratoExtentChangeDelay; @@ -219,40 +352,64 @@ void note_vibrato_init(struct Note *note) { } else { vib->rate = seqChannel->vibratoRateStart; } - vib->delay = seqChannel->vibratoDelay; + note->portamento = note->parentLayer->portamento; +#endif } -void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut) { +void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, UNUSED s16 *volOut) { adsr->action = 0; adsr->state = ADSR_STATE_DISABLED; +#ifdef VERSION_EU + adsr->delay = 0; + adsr->envelope = envelope; + adsr->current = 0.0f; +#else adsr->initial = 0; adsr->delay = 0; adsr->velocity = 0; adsr->envelope = envelope; adsr->volOut = volOut; +#endif } +#ifdef VERSION_EU +f32 adsr_update(struct AdsrState *adsr) { +#else s32 adsr_update(struct AdsrState *adsr) { +#endif u8 action = adsr->action; +#ifdef VERSION_EU + u8 state = adsr->state; + switch (state) { +#else switch (adsr->state) { +#endif case ADSR_STATE_DISABLED: return 0; case ADSR_STATE_INITIAL: { +#ifndef VERSION_EU adsr->current = adsr->initial; adsr->target = adsr->initial; +#endif if (action & ADSR_ACTION_HANG) { adsr->state = ADSR_STATE_HANG; +#ifdef VERSION_EU + break; +#else goto CONT; +#endif } // fallthrough } case ADSR_STATE_START_LOOP: adsr->envIndex = 0; +#ifndef VERSION_EU adsr->currentHiRes = adsr->current << 0x10; +#endif adsr->state = ADSR_STATE_LOOP; // fallthrough @@ -273,45 +430,89 @@ s32 adsr_update(struct AdsrState *adsr) { break; default: +#ifdef VERSION_EU + if (adsr->delay >= 4) { + adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame / 4; + } + adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0; + adsr->target = adsr->target * adsr->target; + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; +#else adsr->target = BSWAP16(adsr->envelope[adsr->envIndex].arg); adsr->velocity = ((adsr->target - adsr->current) << 0x10) / adsr->delay; +#endif adsr->state = ADSR_STATE_FADE; adsr->envIndex++; break; } if (adsr->state != ADSR_STATE_FADE) { +#ifdef VERSION_EU + break; +#else goto CONT; +#endif } // fallthrough case ADSR_STATE_FADE: +#ifdef VERSION_EU + adsr->current += adsr->velocity; +#else adsr->currentHiRes += adsr->velocity; adsr->current = adsr->currentHiRes >> 0x10; +#endif if (--adsr->delay <= 0) { adsr->state = ADSR_STATE_LOOP; } // fallthrough case ADSR_STATE_HANG: +#ifdef VERSION_EU + break; +#else goto CONT; +#endif case ADSR_STATE_DECAY: case ADSR_STATE_RELEASE: { adsr->current -= adsr->fadeOutVel; +#ifdef VERSION_EU + if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { +#else if (adsr->sustain != 0 && adsr->state == ADSR_STATE_DECAY) { +#endif if (adsr->current < adsr->sustain) { adsr->current = adsr->sustain; +#ifdef VERSION_EU + adsr->delay = 128; +#else adsr->delay = adsr->sustain / 16; +#endif adsr->state = ADSR_STATE_SUSTAIN; } +#ifdef VERSION_EU + break; +#else goto CONT; +#endif } +#ifdef VERSION_EU + if (adsr->current < 0) { + adsr->current = 0.0f; + adsr->state = ADSR_STATE_DISABLED; + } +#else if (adsr->current < 100) { adsr->current = 0; adsr->state = ADSR_STATE_DISABLED; } +#endif +#ifdef VERSION_EU + break; +#else goto CONT; +#endif } case ADSR_STATE_SUSTAIN: @@ -319,10 +520,16 @@ s32 adsr_update(struct AdsrState *adsr) { if (adsr->delay == 0) { adsr->state = ADSR_STATE_RELEASE; } +#ifdef VERSION_EU + break; +#else goto CONT; +#endif } +#ifndef VERSION_EU CONT: +#endif if ((action & ADSR_ACTION_DECAY)) { adsr->state = ADSR_STATE_DECAY; @@ -331,9 +538,23 @@ CONT: if ((action & ADSR_ACTION_RELEASE)) { adsr->state = ADSR_STATE_RELEASE; +#ifdef VERSION_EU + adsr->action = action & ~ADSR_ACTION_RELEASE; +#else adsr->action = action & ~(ADSR_ACTION_RELEASE | ADSR_ACTION_DECAY); +#endif } +#ifdef VERSION_EU + if (adsr->current < 0.0f) { + return 0.0f; + } + if (adsr->current > 1.0f) { + return 1.0f; + } + return adsr->current; +#else *adsr->volOut = adsr->current; return 0; +#endif } diff --git a/src/audio/effects.h b/src/audio/effects.h index e64d42d..bb842c7 100644 --- a/src/audio/effects.h +++ b/src/audio/effects.h @@ -35,6 +35,10 @@ void sequence_player_process_sound(struct SequencePlayer *seqPlayer); void note_vibrato_update(struct Note *note); void note_vibrato_init(struct Note *note); void adsr_init(struct AdsrState *adsr, struct AdsrEnvelope *envelope, s16 *volOut); +#ifdef VERSION_EU +f32 adsr_update(struct AdsrState *adsr); +#else s32 adsr_update(struct AdsrState *adsr); +#endif #endif /* AUDIO_EFFECTS_H */ diff --git a/src/audio/external.c b/src/audio/external.c index a195aba..70c57d2 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -1,5 +1,4 @@ #include - #include "sm64.h" #include "memory.h" #include "load.h" @@ -11,12 +10,152 @@ #include "game/mario.h" #include "game/level_update.h" #include "game/area.h" -#include "game/room.h" +#include "game/object_list_processor.h" #include "game/camera.h" #include "seq_ids.h" #include "dialog_ids.h" #include "level_table.h" +#ifdef VERSION_EU +#define EU_FLOAT(x) x ## f +#else +#define EU_FLOAT(x) x +#endif + +#ifndef __sgi +#define GLOBAL_ASM(...) +#endif + +#ifdef VERSION_EU +u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n"; +u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n"; +u8 audioString3[] = "Warning:Kill Note %x \n"; +u8 audioString4[] = "Kill Voice %d (ID %d) %d\n"; +u8 audioString5[] = "Warning: Running Sequence's data disappear!\n"; +u8 audioString6[] = "Heap OverFlow : Not Allocate %d!\n"; +u8 audioString7[] = "DataHeap Not Allocate \n"; +u8 audioString8[] = "StayHeap Not Allocate %d\n"; +u8 audioString9[] = "AutoHeap Not Allocate %d\n"; +u8 audioString10[] = "WARNING: NO FREE AUTOSEQ AREA.\n"; +u8 audioString11[] = "WARNING: NO STOP AUTO AREA.\n"; +u8 audioString12[] = " AND TRY FORCE TO STOP SIDE \n"; +u8 audioString13[] = "TWO SIDES ARE LOADING... ALLOC CANCELED.\n"; +u8 audioString14[] = "WARNING: Before Area Overlaid After."; +u8 audioString15[] = "WARNING: After Area Overlaid Before."; +u8 audioString16[] = "MEMORY:SzHeapAlloc ERROR: sza->side %d\n"; +u8 audioString17[] = "MEMORY:StayHeap OVERFLOW."; +u8 audioString18[] = "MEMORY:StayHeap OVERFLOW (REQ:%d)"; +u8 audioString19[] = "Auto Heap Unhit for ID %d\n"; +u8 audioString20[] = "Cache hit %d at stay %d\n"; +u8 audioString20_[] = "%d "; +u8 audioString20__[] = "\n"; +u8 audioString20___[] = "%d "; +u8 audioString20____[] = "\n"; +u8 audioString21[] = "Heap Reconstruct Start %x\n"; +u8 audioString22[] = "SFrame Sample %d %d %d\n"; +u8 audioString23[] = "AHPBASE %x\n"; +u8 audioString24[] = "AHPCUR %x\n"; +u8 audioString25[] = "HeapTop %x\n"; +u8 audioString26[] = "SynoutRate %d / %d \n"; +u8 audioString27[] = "FXSIZE %d\n"; +u8 audioString28[] = "FXCOMP %d\n"; +u8 audioString29[] = "FXDOWN %d\n"; +u8 audioString30[] = "WaveCacheLen: %d\n"; +u8 audioString31[] = "SpecChange Finished\n"; +u8 audioString31_[] = ""; +u8 audioString32[] = "Romcopy %x -> %x ,size %x\n"; +u8 audioString33[] = "Romcopyend\n"; +u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d"; +u8 audioString35[] = "BASE %x %x\n"; +u8 audioString36[] = "LOAD %x %x %x\n"; +u8 audioString37[] = "INSTTOP %x\n"; +u8 audioString38[] = "INSTMAP[0] %x\n"; +u8 audioString39[] = "already flags %d\n"; +u8 audioString40[] = "already flags %d\n"; +u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n"; +u8 audioString42[] = "ERR:SLOW DMA BUSY\n"; +u8 audioString43[] = "Check %d bank %d\n"; +u8 audioString44[] = "Cache Check\n"; +u8 audioString45[] = "NO BANK ERROR\n"; +u8 audioString46[] = "BANK %d LOADING START\n"; +u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n"; +u8 audioString48[] = "BANK %d ALREADY CACHED\n"; +u8 audioString49[] = "BANK LOAD MISS! FOR %d\n"; +u8 audioString50[] = "Seq %d Loading Start\n"; +u8 audioString51[] = "Heap Overflow Error\n"; +u8 audioString52[] = "SEQ %d ALREADY CACHED\n"; +u8 audioString53[] = "Ok,one bank slow load Start \n"; +u8 audioString54[] = "Sorry,too many %d bank is none.fast load Start \n"; +u8 audioString55[] = "Seq %d:Default Load Id is %d\n"; +u8 audioString56[] = "Seq Loading Start\n"; +u8 audioString57[] = "Error:Before Sequence-SlowDma remain.\n"; +u8 audioString58[] = " Cancel Seq Start.\n"; +u8 audioString59[] = "SEQ %d ALREADY CACHED\n"; +u8 audioString60[] = "Clear Workarea %x -%x size %x \n"; +u8 audioString61[] = "AudioHeap is %x\n"; +u8 audioString62[] = "Heap reset.Synth Change %x \n"; +u8 audioString63[] = "Heap %x %x %x\n"; +u8 audioString64[] = "Main Heap Initialize.\n"; +u8 audioString65[] = "---------- Init Completed. ------------\n"; +u8 audioString66[] = " Syndrv :[%6d]\n"; +u8 audioString67[] = " Seqdrv :[%6d]\n"; +u8 audioString68[] = " audiodata :[%6d]\n"; +u8 audioString69[] = "---------------------------------------\n"; +u8 audioString69_[] = ""; +u8 audioString70[] = "Audio: setvol: volume minus %f\n"; +u8 audioString71[] = "Audio: setvol: volume overflow %f\n"; +u8 audioString72[] = "Audio: setpitch: pitch minus %f\n"; +u8 audioString73[] = "Audio: voiceman: No bank error %d\n"; +u8 audioString74[] = "Audio: voiceman: progNo. overflow %d,%d\n"; +u8 audioString75[] = "Audio: voiceman: progNo. undefined %d,%d\n"; +u8 audioString76[] = "Audio: voiceman: BAD Voicepointer %x,%d,%d\n"; +u8 audioString77[] = "Audio: voiceman: Percussion Overflow %d,%d\n"; +u8 audioString78[] = "Percussion Pointer Error\n"; +u8 audioString79[] = "Audio: voiceman: Percpointer NULL %d,%d\n"; +u8 audioString80[] = "CAUTION:SUB IS SEPARATED FROM GROUP"; +u8 audioString81[] = "Error:Wait Track disappear\n"; +u8 audioString82[] = "Slow Release Batting\n"; +u8 audioString83[] = "Audio:Wavemem: Bad voiceno (%d)\n"; +u8 audioString84[] = "Audio: C-Alloc : Dealloc voice is NULL\n"; +u8 audioString85[] = "Alloc Error:Dim voice-Alloc %d"; +u8 audioString86[] = "Error:Same List Add\n"; +u8 audioString87[] = "Already Cut\n"; +u8 audioString88[] = "Audio: C-Alloc : lowerPrio is NULL\n"; +u8 audioString89[] = "Sub Limited Warning: Drop Voice"; +u8 audioString90[] = "Warning: Drop Voice"; +u8 audioString91[] = "Warning: Drop Voice"; +u8 audioString92[] = "Warning: Drop Voice"; +u8 audioString93[] = "Audio:Envp: overflow %f\n"; +u8 audioString93_[] = ""; +u8 audioString94[] = "Audio:Track:Warning: No Free Notetrack\n"; +u8 audioString95[] = "SUBTRACK DIM\n"; +u8 audioString96[] = "Audio:Track: Warning SUBTRACK PARENT CHANGED\n"; +u8 audioString97[] = "GROUP 0:"; +u8 audioString98[] = "GROUP 1:"; +u8 audioString99[] = "SEQID %d,BANKID %d\n"; +u8 audioString100[] = "ERR:SUBTRACK %d NOT ALLOCATED\n"; +u8 audioString101[] = "Error:Same List Add\n"; +u8 audioString102[] = "Macro Level Over Error!\n"; +u8 audioString103[] = "Macro Level Over Error!\n"; +u8 audioString104[] = "WARNING: NPRG: cannot change %d\n"; +u8 audioString105[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n"; +u8 audioString106[] = "Audio: Note:Velocity Error %d\n"; +u8 audioString107[] = "Error: Your assignchannel is stolen.\n"; +u8 audioString108[] = "Audio:Track :Call Macro Level Over Error!\n"; +u8 audioString109[] = "Audio:Track :Loops Macro Level Over Error!\n"; +u8 audioString110[] = "SUB:ERR:BANK %d NOT CACHED.\n"; +u8 audioString111[] = "SUB:ERR:BANK %d NOT CACHED.\n"; +u8 audioString112[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n"; +u8 audioString113[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x"; +u8 audioString114[] = "Disappear Sequence or Bank %d\n"; +u8 audioString115[] = "Macro Level Over Error!\n"; +u8 audioString116[] = "Macro Level Over Error!\n"; +u8 audioString117[] = "Group:Undefine upper C0h command (%x)\n"; +u8 audioString118[] = "Group:Undefined Command\n"; +u8 audioString118_[] = ""; +u8 audioString118__[] = ""; +#endif + // N.B. sound banks are different from the audio banks referred to in other // files. We should really fix our naming to be less ambiguous... #define MAX_BG_MUSIC_QUEUE_SIZE 6 @@ -68,7 +207,12 @@ struct SequenceQueueItem { }; // size = 0x2 // data +#ifdef VERSION_EU +// moved to bss in data.c +s32 gAudioErrorFlags2 = 0; +#else s32 gAudioErrorFlags = 0; +#endif s32 sGameLoopTicked = 0; // Dialog sounds @@ -118,7 +262,7 @@ u8 sDialogSpeaker[] = { #undef _ STATIC_ASSERT(ARRAY_COUNT(sDialogSpeaker) == DIALOG_COUNT, "change this array if you are adding dialogs"); -s32 sDialogSpeakerVoice[15] = { +s32 sDialogSpeakerVoice[] = { SOUND_OBJ_UKIKI_CHATTER_LONG, SOUND_OBJ_BIG_PENGUIN_YELL, SOUND_OBJ_BOWSER_INTRO_LAUGH, @@ -130,10 +274,12 @@ s32 sDialogSpeakerVoice[15] = { SOUND_OBJ2_BOSS_DIALOG_GRUNT, SOUND_OBJ_WIGGLER_TALK, SOUND_GENERAL_YOSHI_TALK, +#ifndef VERSION_EU NO_SOUND, NO_SOUND, NO_SOUND, NO_SOUND, +#endif }; u8 sNumProcessedSoundRequests = 0; @@ -158,9 +304,9 @@ u8 sSoundRequestCount = 0; #define MARIO_IS_IN_ROOM 7 #define DYN1(cond1, val1, res) (s16)(1 << (15 - cond1) | res), val1 -#define DYN2(cond1, val1, cond2, val2, res) \ +#define DYN2(cond1, val1, cond2, val2, res) \ (s16)(1 << (15 - cond1) | 1 << (15 - cond2) | res), val1, val2 -#define DYN3(cond1, val1, cond2, val2, cond3, val3, res) \ +#define DYN3(cond1, val1, cond2, val2, cond3, val3, res) \ (s16)(1 << (15 - cond1) | 1 << (15 - cond2) | 1 << (15 - cond3) | res), val1, val2, val3 s16 sDynBbh[] = { @@ -246,7 +392,7 @@ struct MusicDynamic sMusicDynamics[8] = { u8 gAreaEchoLevel[LEVEL_COUNT][3] = { { 0x00, 0x00, 0x00 }, // LEVEL_NONE - #include "levels/level_defines.h" +#include "levels/level_defines.h" }; #undef STUB_LEVEL #undef DEFINE_LEVEL @@ -335,15 +481,24 @@ u16 sUnused80332118 = 0; // never read, set to 0 u8 D_8033211C = 0; u8 D_80332120 = 0; u8 D_80332124 = 0; + +#ifdef VERSION_EU +u8 D_EU_80300558 = 0; +#endif + u8 sBackgroundMusicQueueSize = 0; + #ifndef VERSION_JP u8 sUnused8033323C = 0; // never read, set to 0 #endif // bss +#ifndef VERSION_EU u16 *gCurrAiBuffer; +#endif struct Sound sSoundRequests[0x100]; -struct ChannelVolumeScaleFade D_80360928[SEQUENCE_PLAYERS][CHANNELS_MAX]; +// Curiously, this has size 3, despite SEQUENCE_PLAYERS == 4 on EU +struct ChannelVolumeScaleFade D_80360928[3][CHANNELS_MAX]; u8 sUsedChannelsForSoundBank[SOUND_BANK_COUNT]; u8 sCurrentSound[SOUND_BANK_COUNT][MAX_CHANNELS_PER_SOUND]; // index into gSoundBanks // list item memory for D_803320A4 and D_803320B0 @@ -353,13 +508,35 @@ u8 D_80363812; static u8 sCapVolumeTo40; struct SequenceQueueItem sBackgroundMusicQueue[MAX_BG_MUSIC_QUEUE_SIZE]; +#ifdef VERSION_EU +s32 unk; +OSMesgQueue OSMesgQueue0; +OSMesgQueue OSMesgQueue1; +OSMesgQueue OSMesgQueue2; +OSMesgQueue OSMesgQueue3; +extern OSMesgQueue *OSMesgQueues[]; +struct EuAudioCmd sAudioCmd[0x100]; +OSMesg OSMesg0; +s32 pad1; // why is there 1 s32 here +OSMesg OSMesg1; +s32 pad2[2]; // it's not just that the struct is bigger than we think, because there are 2 here +OSMesg OSMesg2; // and none here. wth nintendo +OSMesg OSMesg3; +#endif + + #ifdef VERSION_JP typedef u16 FadeT; #else typedef s32 FadeT; #endif -static void func_8031E0E4(u8 bankIndex, u8 item); +// some sort of main thread -> sound thread dispatchers +extern void func_802ad728(u32 bits, f32 arg); +extern void func_802ad74c(u32 bits, u32 arg); +extern void func_802ad770(u32 bits, s8 arg); + +void func_8031E0E4(u8 bankIndex, u8 item); // Local functions that could be static but are defined in/called from GLOBAL_ASM blocks, // or not part of the large block of static functions. @@ -441,10 +618,31 @@ void unused_8031E568(void) { } #endif +#ifdef VERSION_EU +const char unusedErrorStr1[] = "Error : Queue is not empty ( %x ) \n"; +const char unusedErrorStr2[] = "specchg error\n"; +#endif + + /** * Fade out a sequence player */ -static void sequence_player_fade_out_internal(s32 player, FadeT fadeOutTime) { +#if defined(VERSION_EU) + +void audio_reset_session_eu(s32 presetId) { + OSMesg mesg; + + osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_NOBLOCK); + osSendMesg(OSMesgQueues[2], (OSMesg) presetId, OS_MESG_NOBLOCK); + osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_BLOCK); + if ((s32) mesg != presetId) { + osRecvMesg(OSMesgQueues[3], &mesg, OS_MESG_BLOCK); + } +} + +#else + +void sequence_player_fade_out_internal(s32 player, FadeT fadeOutTime) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; #ifndef VERSION_JP if (fadeOutTime == 0) { @@ -457,7 +655,7 @@ static void sequence_player_fade_out_internal(s32 player, FadeT fadeOutTime) { seqPlayer->fadeTimer = fadeOutTime; } -static void func_8031D690(s32 player, FadeT fadeInTime) { +void func_8031D690(s32 player, FadeT fadeInTime) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; if (fadeInTime == 0 || seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) { @@ -469,16 +667,23 @@ static void func_8031D690(s32 player, FadeT fadeInTime) { seqPlayer->fadeVolume = 0.0f; seqPlayer->fadeVelocity = 0.0f; } +#endif -static void func_8031D6E4(s32 player, FadeT fadeTimer, u8 fadePercentage) { +void func_8031D6E4(s32 player, FadeT fadeTimer, u8 fadePercentage) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; f32 fadeVolume; +#ifdef VERSION_EU + if (seqPlayer->state == 2) { + return; + } +#else if (seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) { return; } +#endif - fadeVolume = (FLOAT_CAST(fadePercentage) / 100.0 * seqPlayer->fadeVolume); + fadeVolume = (FLOAT_CAST(fadePercentage) / EU_FLOAT(100.0) * seqPlayer->fadeVolume); seqPlayer->volume = seqPlayer->fadeVolume; seqPlayer->fadeTimer = 0; if (fadeTimer == 0) { @@ -486,16 +691,26 @@ static void func_8031D6E4(s32 player, FadeT fadeTimer, u8 fadePercentage) { return; } seqPlayer->fadeVelocity = (fadeVolume - seqPlayer->fadeVolume) / fadeTimer; +#ifdef VERSION_EU + seqPlayer->state = 0; +#else seqPlayer->state = SEQUENCE_PLAYER_STATE_4; +#endif seqPlayer->fadeTimer = fadeTimer; } -static void func_8031D7B0(s32 player, FadeT fadeTimer) { +void func_8031D7B0(s32 player, FadeT fadeTimer) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; +#ifdef VERSION_EU + if (seqPlayer->state == 2) { + return; + } +#else if (seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) { return; } +#endif seqPlayer->fadeTimer = 0; if (fadeTimer == 0) { @@ -503,28 +718,58 @@ static void func_8031D7B0(s32 player, FadeT fadeTimer) { return; } seqPlayer->fadeVelocity = (seqPlayer->volume - seqPlayer->fadeVolume) / fadeTimer; +#ifdef VERSION_EU + seqPlayer->state = 0; +#else seqPlayer->state = SEQUENCE_PLAYER_STATE_2; +#endif seqPlayer->fadeTimer = fadeTimer; } -static void func_8031D838(s32 player, FadeT fadeInTime, u8 targetVolume) { +void func_8031D838(s32 player, FadeT fadeInTime, u8 targetVolume) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; +#ifndef VERSION_EU if (seqPlayer->state == SEQUENCE_PLAYER_STATE_FADE_OUT) { return; } +#endif seqPlayer->fadeTimer = 0; if (fadeInTime == 0) { - seqPlayer->fadeVolume = (FLOAT_CAST(targetVolume) / 127.0); + seqPlayer->fadeVolume = (FLOAT_CAST(targetVolume) / EU_FLOAT(127.0)); return; } seqPlayer->fadeVelocity = - (((f32)(FLOAT_CAST(targetVolume) / 127.0) - seqPlayer->fadeVolume) / (f32) fadeInTime); + (((f32)(FLOAT_CAST(targetVolume) / EU_FLOAT(127.0)) - seqPlayer->fadeVolume) / (f32) fadeInTime); +#ifdef VERSION_EU + seqPlayer->state = 0; +#else seqPlayer->state = SEQUENCE_PLAYER_STATE_4; +#endif seqPlayer->fadeTimer = fadeInTime; } +#ifdef VERSION_EU +extern void func_802ad7a0(void); + +void maybe_tick_game_sound(void) +{ + if (sGameLoopTicked != 0) + { + update_game_sound(); + sGameLoopTicked = 0; + } + func_802ad7a0(); +} + +void func_eu_802e9bec(s32 player, s32 channel, s32 arg2) { + // chan->stopSomething2 = arg2? + func_802ad770(0x08000000 | (player & 0xff) << 16 | (channel & 0xff) << 8, (s8) arg2); +} + +#else + struct SPTask *create_next_audio_frame_task(void) { u32 samplesRemainingInAI; s32 writtenCmds; @@ -591,7 +836,6 @@ struct SPTask *create_next_audio_frame_task(void) { // For the function to match we have to preserve some arbitrary variable // across this function call. flags = 0; - gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, gCurrAiBuffer, gAiBufferLengths[index]); gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount); @@ -628,6 +872,7 @@ struct SPTask *create_next_audio_frame_task(void) { decrease_sample_dma_ttls(); return gAudioTask; } +#endif void play_sound(s32 soundBits, f32 *pos) { sSoundRequests[sSoundRequestCount].soundBits = soundBits; @@ -635,7 +880,7 @@ void play_sound(s32 soundBits, f32 *pos) { sSoundRequestCount++; } -static void process_sound_request(u32 bits, f32 *pos) { +void process_sound_request(u32 bits, f32 *pos) { u8 bankIndex; u8 index; u8 counter = 0; @@ -696,7 +941,7 @@ static void process_sound_request(u32 bits, f32 *pos) { /** * Processes all sound requests */ -static void process_all_sound_requests(void) { +void process_all_sound_requests(void) { struct Sound *sound; while (sSoundRequestCount != sNumProcessedSoundRequests) { @@ -706,7 +951,7 @@ static void process_all_sound_requests(void) { } } -static void func_8031DFE8(u8 bankIndex, u8 item) { +void func_8031DFE8(u8 bankIndex, u8 item) { // move item from list D_803320A4 to list D_803320B0 if (D_803320A4[bankIndex] == item) { D_803320A4[bankIndex] = gSoundBanks[bankIndex][item].prev; @@ -722,14 +967,14 @@ static void func_8031DFE8(u8 bankIndex, u8 item) { D_803320B0[bankIndex] = item; } -static void func_8031E0E4(u8 bankIndex, u8 item) { +void func_8031E0E4(u8 bankIndex, u8 item) { if (gSoundBanks[bankIndex][item].soundBits & SOUND_LO_BITFLAG_UNK1) { D_80332110 &= (1 << bankIndex) ^ 0xffff; func_803200E4(50); } } -static void func_8031E16C(u8 bankIndex) { +void func_8031E16C(u8 bankIndex) { u32 val2; u8 spDB; u8 i; @@ -879,7 +1124,7 @@ static void func_8031E16C(u8 bankIndex) { * 0.5 - center pan * 1.0 - fully right */ -static f32 get_sound_pan(f32 x, f32 z) { +f32 get_sound_pan(f32 x, f32 z) { f32 absX; f32 absZ; f32 pan; @@ -916,7 +1161,7 @@ static f32 get_sound_pan(f32 x, f32 z) { return pan; } -static f32 get_sound_dynamics(u8 bankIndex, u8 item, f32 arg2) { +f32 get_sound_dynamics(u8 bankIndex, u8 item, f32 arg2) { f32 f0; f32 intensity; #ifndef VERSION_JP @@ -963,7 +1208,7 @@ static f32 get_sound_dynamics(u8 bankIndex, u8 item, f32 arg2) { return arg2 * intensity * intensity + 1.0f - arg2; } -static f32 get_sound_freq_scale(u8 bankIndex, u8 item) { +f32 get_sound_freq_scale(u8 bankIndex, u8 item) { f32 f2; if (!(gSoundBanks[bankIndex][item].soundBits & SOUND_PL_BITFLAG_UNK8)) { @@ -976,13 +1221,12 @@ static f32 get_sound_freq_scale(u8 bankIndex, u8 item) { } return f2 / US_FLOAT(15.0) + US_FLOAT(1.0); } - #ifdef VERSION_JP #define VAL 48.0 #else #define VAL 40.0f #endif -static u8 get_sound_reverb(UNUSED u8 bankIndex, UNUSED u8 item, u8 channelIndex) { +u8 get_sound_reverb(UNUSED u8 bankIndex, UNUSED u8 item, u8 channelIndex) { u8 area; u8 level; u8 reverb; @@ -1001,10 +1245,9 @@ static u8 get_sound_reverb(UNUSED u8 bankIndex, UNUSED u8 item, u8 channelIndex) #ifndef VERSION_JP } #endif - reverb = (u8)((u8) gSequencePlayers[2].channels[channelIndex]->soundScriptIO[5] + gAreaEchoLevel[level][area] - + (US_FLOAT(1.0) - gSequencePlayers[2].channels[channelIndex]->volume) * VAL); + + (US_FLOAT(1.0) - gSequencePlayers[2].channels[channelIndex]->volume) * VAL); if (reverb > 0x7f) { reverb = 0x7f; @@ -1018,6 +1261,9 @@ static void noop_8031EEC8(void) { void audio_signal_game_loop_tick(void) { sGameLoopTicked = 1; +#ifdef VERSION_EU + maybe_tick_game_sound(); +#endif noop_8031EEC8(); } @@ -1031,12 +1277,14 @@ void audio_signal_game_loop_tick(void) { void update_game_sound(void) { u8 soundStatus; + u8 j; u8 soundId; u8 bankIndex; - u8 j; u8 channelIndex = 0; u8 index; +#ifndef VERSION_EU f32 ret; +#endif process_all_sound_requests(); process_level_music_dynamics(); @@ -1067,39 +1315,91 @@ void update_game_sound(void) { case 1: if (!(gSoundBanks[bankIndex][index].soundBits & SOUND_PL_BITFLAG_UNK8)) { if (D_80363808[bankIndex] > 8) { +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1)); +#else ret = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->volume = ret; +#endif } else { +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1) * + ((D_80363808[bankIndex] + 8.0f) / 16)); +#else ret = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->volume = (D_80363808[bankIndex] + 8.0f) / 16 * ret; +#endif } +#ifdef VERSION_EU + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z)); +#else gSequencePlayers[2].channels[channelIndex]->pan = get_sound_pan( *gSoundBanks[bankIndex][index].x, *gSoundBanks[bankIndex][index].z); +#endif if ((gSoundBanks[bankIndex][index].soundBits & SOUNDARGS_MASK_SOUNDID) == (SOUND_MOVING_FLYING & SOUNDARGS_MASK_SOUNDID)) { +#ifdef VERSION_EU + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index) + + ((f32) D_80363808[bankIndex] / US_FLOAT(80.0))); +#else ret = get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->freqScale = ((f32) D_80363808[bankIndex] / US_FLOAT(80.0)) + ret; +#endif } else { +#ifdef VERSION_EU + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index) + + ((f32) D_80363808[bankIndex] / US_FLOAT(400.0))); +#else ret = get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->freqScale = ((f32) D_80363808[bankIndex] / US_FLOAT(400.0)) + ret; +#endif } +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); +#else gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); +#endif break; } // fallthrough case 7: +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), 1); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), 64); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->volume = 1.0f; gSequencePlayers[2].channels[channelIndex]->pan = 0.5f; gSequencePlayers[2].channels[channelIndex]->freqScale = 1.0f; +#endif break; case 0: case 2: +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1)); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z) * 127.0f + 0.5f); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->volume = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->pan = get_sound_pan( @@ -1108,6 +1408,7 @@ void update_game_sound(void) { get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); +#endif break; case 3: case 4: @@ -1115,6 +1416,17 @@ void update_game_sound(void) { case 6: case 8: case 9: +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL2)); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z) * 127.0f + 0.5f); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); gSequencePlayers[2].channels[channelIndex]->volume = @@ -1123,6 +1435,7 @@ void update_game_sound(void) { *gSoundBanks[bankIndex][index].x, *gSoundBanks[bankIndex][index].z); gSequencePlayers[2].channels[channelIndex]->freqScale = get_sound_freq_scale(bankIndex, index); +#endif break; } } @@ -1159,39 +1472,91 @@ void update_game_sound(void) { case 1: if (!(gSoundBanks[bankIndex][index].soundBits & SOUND_PL_BITFLAG_UNK8)) { if (D_80363808[bankIndex] > 8) { +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1)); +#else ret = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->volume = ret; +#endif } else { +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1) * + ((D_80363808[bankIndex] + 8.0f) / 16)); +#else ret = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->volume = (D_80363808[bankIndex] + 8.0f) / 16 * ret; +#endif } +#ifdef VERSION_EU + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z)); +#else gSequencePlayers[2].channels[channelIndex]->pan = get_sound_pan( *gSoundBanks[bankIndex][index].x, *gSoundBanks[bankIndex][index].z); +#endif if ((gSoundBanks[bankIndex][index].soundBits & SOUNDARGS_MASK_SOUNDID) == (SOUND_MOVING_FLYING & SOUNDARGS_MASK_SOUNDID)) { +#ifdef VERSION_EU + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index) + + ((f32) D_80363808[bankIndex] / US_FLOAT(80.0))); +#else ret = get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->freqScale = ((f32) D_80363808[bankIndex] / US_FLOAT(80.0)) + ret; +#endif } else { +#ifdef VERSION_EU + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index) + + ((f32) D_80363808[bankIndex] / US_FLOAT(400.0))); +#else ret = get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->freqScale = ((f32) D_80363808[bankIndex] / US_FLOAT(400.0)) + ret; +#endif } +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); +#else gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); +#endif break; } // fallthrough case 7: +#ifdef VERSION_EU + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), 1); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), 64); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->volume = 1.0f; gSequencePlayers[2].channels[channelIndex]->pan = 0.5f; gSequencePlayers[2].channels[channelIndex]->freqScale = 1.0f; +#endif break; case 0: case 2: +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL1)); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z) * 127.0f + 0.5f); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->volume = get_sound_dynamics(bankIndex, index, ARG2_VAL1); gSequencePlayers[2].channels[channelIndex]->pan = get_sound_pan( @@ -1200,6 +1565,7 @@ void update_game_sound(void) { get_sound_freq_scale(bankIndex, index); gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); +#endif break; case 3: case 4: @@ -1207,6 +1573,17 @@ void update_game_sound(void) { case 6: case 8: case 9: +#ifdef VERSION_EU + func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), + get_sound_reverb(bankIndex, index, channelIndex)); + func_802ad728(0x02020000 | ((channelIndex & 0xff) << 8), + get_sound_dynamics(bankIndex, index, ARG2_VAL2)); + func_802ad770(0x03020000 | ((channelIndex & 0xff) << 8), + get_sound_pan(*gSoundBanks[bankIndex][index].x, + *gSoundBanks[bankIndex][index].z) * 127.0f + 0.5f); + func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), + get_sound_freq_scale(bankIndex, index)); +#else gSequencePlayers[2].channels[channelIndex]->reverb = get_sound_reverb(bankIndex, index, channelIndex); gSequencePlayers[2].channels[channelIndex]->volume = @@ -1215,6 +1592,7 @@ void update_game_sound(void) { *gSoundBanks[bankIndex][index].x, *gSoundBanks[bankIndex][index].z); gSequencePlayers[2].channels[channelIndex]->freqScale = get_sound_freq_scale(bankIndex, index); +#endif break; } } @@ -1226,10 +1604,15 @@ void update_game_sound(void) { channelIndex += sMaxChannelsForSoundBank[bankIndex] - sUsedChannelsForSoundBank[bankIndex]; } } - #undef ARG2_VAL1 #undef ARG2_VAL2 +#if defined(VERSION_EU) && !defined(NON_MATCHING) +// Just regalloc differences +void play_sequence(u8 player, u8 seqId, u16 fadeTimer); +GLOBAL_ASM("asm/non_matchings/eu/play_sequence.s") +#else + void play_sequence(u8 player, u8 seqId, u16 fadeTimer) { u8 temp_ret; u8 i; @@ -1245,8 +1628,20 @@ void play_sequence(u8 player, u8 seqId, u16 fadeTimer) { D_80360928[player][i].remDuration = 0; } +#ifdef VERSION_EU + func_802ad770(0x46000000 | (player & 0xff) << 16, seqId & 0x80); + func_802ad74c(0x82000000 | (player & 0xff) << 16 | ((seqId & 0x7f) & 0xff) << 8, fadeTimer); + + if (player == 0) { + temp_ret = func_803200E4(0); + if (temp_ret != 0xff) { + gSequencePlayers[0].unkEu28 = (f32) temp_ret / US_FLOAT(127.0); + } + } +#else gSequencePlayers[player].seqVariation = seqId & 0x80; load_sequence(player, seqId & 0x7f, 0); + if (player == 0) { temp_ret = func_803200E4(0); if (temp_ret != 0xff) { @@ -1256,13 +1651,22 @@ void play_sequence(u8 player, u8 seqId, u16 fadeTimer) { } else { func_8031D690(player, fadeTimer); } +#endif } +#endif void sequence_player_fade_out(u8 player, u16 fadeTimer) { +#ifdef VERSION_EU + if (!player) { + sPlayer0CurSeqId = SEQUENCE_NONE; + } + func_802ad74c(0x83000000 | (player & 0xff) << 16, fadeTimer); +#else if (player == 0) { sPlayer0CurSeqId = SEQUENCE_NONE; } sequence_player_fade_out_internal(player, fadeTimer); +#endif } void fade_volume_scale(u8 player, u8 targetScale, u16 fadeTimer) { @@ -1294,11 +1698,20 @@ void func_8031F96C(u8 player) { if (gSequencePlayers[player].channels[i] != &gSequenceChannelNone && D_80360928[player][i].remDuration != 0) { D_80360928[player][i].current += D_80360928[player][i].velocity; +#ifdef VERSION_EU + func_802ad728(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, D_80360928[player][i].current); +#else gSequencePlayers[player].channels[i]->volumeScale = D_80360928[player][i].current; +#endif D_80360928[player][i].remDuration--; if (D_80360928[player][i].remDuration == 0) { +#ifdef VERSION_EU + func_802ad728(0x01000000 | (player & 0xff) << 16 | (i & 0xff) << 8, + FLOAT_CAST(D_80360928[player][i].target) / 127.0); +#else gSequencePlayers[player].channels[i]->volumeScale = D_80360928[player][i].target / 127.0f; +#endif } } } @@ -1336,7 +1749,7 @@ void process_level_music_dynamics(void) { musicDynIndex = sLevelDynamics[gCurrLevelNum][1] & 0xff; i = 2; while (conditionBits & 0xff00) { - for (j = 0, condIndex = 0, bit = 0x8000; j < 8; j++, bit = bit >> 1) { + for (j = 0, condIndex = 0, bit = 0x8000; j<8; j++, bit = bit>> 1) { if (conditionBits & bit) { conditionValues[condIndex] = sLevelDynamics[gCurrLevelNum][i++]; conditionTypes[condIndex] = j; @@ -1384,13 +1797,13 @@ void process_level_music_dynamics(void) { break; } case MARIO_IS_IN_AREA: { - //s16 temp = gCurrAreaIndex; + // s16 temp = gCurrAreaIndex; if (gCurrAreaIndex != conditionValues[j]) j = condIndex + 1; break; } case MARIO_IS_IN_ROOM: { - //s16 temp = gMarioCurrentRoom; + // s16 temp = gMarioCurrentRoom; if (gMarioCurrentRoom != conditionValues[j]) j = condIndex + 1; break; @@ -1518,7 +1931,9 @@ u8 func_803200E4(u16 fadeTimer) { if (vol != 0xff) { func_8031D838(0, fadeTimer, vol); } else { +#if defined(VERSION_JP) || defined(VERSION_US) gSequencePlayers[0].volume = sBackgroundMusicDefaultVolume[sPlayer0CurSeqId] / 127.0f; +#endif func_8031D7B0(0, fadeTimer); } } @@ -1529,7 +1944,14 @@ void set_sound_disabled(u8 disabled) { u8 i; for (i = 0; i < SEQUENCE_PLAYERS; i++) { +#ifdef VERSION_EU + if (disabled) + func_802ad74c(0xf1000000, 0); + else + func_802ad74c(0xf2000000, 0); +#else gSequencePlayers[i].muted = disabled; +#endif } } @@ -1564,7 +1986,7 @@ void sound_init(void) { gSoundBanks[i][j].next = 0xff; } - for (j = 0; j < SEQUENCE_PLAYERS; j++) { + for (j = 0; j < 3; j++) { for (i = 0; i < CHANNELS_MAX; i++) { D_80360928[j][i].remDuration = 0; } @@ -1672,7 +2094,7 @@ void sound_banks_disable(UNUSED u8 player, u16 bankMask) { } } -static void disable_all_sequence_players(void) { +void disable_all_sequence_players(void) { u8 i; for (i = 0; i < SEQUENCE_PLAYERS; i++) { @@ -1728,7 +2150,7 @@ void play_dialog_sound(u8 dialogID) { #endif } -void play_music(u8 player, u16 seqArgs, s16 fadeTimer) { +void play_music(u8 player, u16 seqArgs, u16 fadeTimer) { u8 seqId = seqArgs & 0xff; u8 priority = seqArgs >> 8; u8 i; @@ -1848,7 +2270,15 @@ u16 get_current_background_music(void) { } void func_80320ED8(void) { +#ifdef VERSION_EU + if (D_EU_80300558 != 0) { + D_EU_80300558--; + } + + if (gSequencePlayers[1].enabled || D_8033211C == 0 || D_EU_80300558 != 0) { +#else if (gSequencePlayers[1].enabled || D_8033211C == 0) { +#endif return; } @@ -1907,10 +2337,18 @@ void func_803210D4(u16 fadeOutTime) { } if (gSequencePlayers[0].enabled == TRUE) { +#ifdef VERSION_EU + func_802ad74c(0x83000000, fadeOutTime); +#else sequence_player_fade_out_internal(0, fadeOutTime); +#endif } if (gSequencePlayers[1].enabled == TRUE) { +#ifdef VERSION_EU + func_802ad74c(0x83010000, fadeOutTime); +#else sequence_player_fade_out_internal(1, fadeOutTime); +#endif } for (i = 0; i < SOUND_BANK_COUNT; i++) { @@ -1924,12 +2362,18 @@ void func_803210D4(u16 fadeOutTime) { void play_course_clear(void) { play_sequence(1, SEQ_EVENT_CUTSCENE_COLLECT_STAR, 0); D_8033211C = 0x80 | 0; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } void play_peachs_jingle(void) { play_sequence(1, SEQ_EVENT_PEACH_MESSAGE, 0); D_8033211C = 0x80 | 0; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } @@ -1941,12 +2385,18 @@ void play_peachs_jingle(void) { void play_puzzle_jingle(void) { play_sequence(1, SEQ_EVENT_SOLVE_PUZZLE, 0); D_8033211C = 0x80 | 20; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } void play_star_fanfare(void) { play_sequence(1, SEQ_EVENT_HIGH_SCORE, 0); D_8033211C = 0x80 | 20; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } @@ -1956,40 +2406,53 @@ void play_power_star_jingle(u8 arg0) { } play_sequence(1, SEQ_EVENT_CUTSCENE_STAR_SPAWN, 0); D_8033211C = 0x80 | 20; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } void play_race_fanfare(void) { play_sequence(1, SEQ_EVENT_RACE, 0); D_8033211C = 0x80 | 20; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } void play_toads_jingle(void) { play_sequence(1, SEQ_EVENT_TOAD_MESSAGE, 0); D_8033211C = 0x80 | 20; +#ifdef VERSION_EU + D_EU_80300558 = 2; +#endif func_803200E4(50); } -void sound_reset(u8 arg0) { +void sound_reset(u8 presetId) { #ifndef VERSION_JP - if (arg0 >= 8) { - arg0 = 0; + if (presetId >= 8) { + presetId = 0; sUnused8033323C = 0; } #endif sGameLoopTicked = 0; disable_all_sequence_players(); sound_init(); - audio_reset_session(&gAudioSessionPresets[arg0]); +#if defined(VERSION_JP) || defined(VERSION_US) + audio_reset_session(&gAudioSessionPresets[presetId]); +#else + audio_reset_session_eu(presetId); +#endif osWritebackDCacheAll(); - if (arg0 != 7) { + if (presetId != 7) { preload_sequence(SEQ_EVENT_SOLVE_PUZZLE, PRELOAD_BANKS | PRELOAD_SEQUENCE); preload_sequence(SEQ_EVENT_PEACH_MESSAGE, PRELOAD_BANKS | PRELOAD_SEQUENCE); preload_sequence(SEQ_EVENT_CUTSCENE_STAR_SPAWN, PRELOAD_BANKS | PRELOAD_SEQUENCE); } play_sequence(2, SEQ_SOUND_PLAYER, 0); - D_80332108 = (D_80332108 & 0xf0) + arg0; + D_80332108 = (D_80332108 & 0xf0) + presetId; gSoundMode = D_80332108 >> 4; sHasStartedFadeOut = FALSE; } @@ -1999,8 +2462,10 @@ void audio_set_sound_mode(u8 soundMode) { gSoundMode = soundMode; } +#ifndef VERSION_EU void unused_80321460(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s32 arg3) { } void unused_80321474(UNUSED s32 arg0) { } +#endif diff --git a/src/audio/external.h b/src/audio/external.h index 9667da0..7193a96 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -33,7 +33,7 @@ void sound_banks_disable(u8 player, u16 bankMask); void sound_banks_enable(u8 player, u16 bankMask); void func_80320A4C(u8 bankIndex, u8 arg1); void play_dialog_sound(u8 dialogID); -void play_music(u8 player, u16 seqArgs, s16 fadeTimer); +void play_music(u8 player, u16 seqArgs, u16 fadeTimer); void stop_background_music(u16 seqId); void fadeout_background_music(u16 arg0, u16 fadeOut); void drop_queued_background_music(void); @@ -53,4 +53,8 @@ void audio_set_sound_mode(u8 arg0); void audio_init(void); // in load.c +#ifdef VERSION_EU +struct SPTask *unused_80321460(); +#endif + #endif /* AUDIO_EXTERNAL_H */ diff --git a/src/audio/globals_end.c b/src/audio/globals_end.c index 3fa5af0..7f5b089 100644 --- a/src/audio/globals_end.c +++ b/src/audio/globals_end.c @@ -1,3 +1,5 @@ #include +#ifndef VERSION_EU u64 gAudioGlobalsEndMarker; +#endif diff --git a/src/audio/internal.h b/src/audio/internal.h index 859f58b..ff09828 100644 --- a/src/audio/internal.h +++ b/src/audio/internal.h @@ -5,7 +5,20 @@ #include "types.h" +#ifdef VERSION_EU +#define SEQUENCE_PLAYERS 4 +#define SEQUENCE_CHANNELS 48 +#define SEQUENCE_LAYERS 64 +#else #define SEQUENCE_PLAYERS 3 +#define SEQUENCE_CHANNELS 32 +#ifdef VERSION_JP +#define SEQUENCE_LAYERS 48 +#else +#define SEQUENCE_LAYERS 52 +#endif +#endif + #define LAYERS_MAX 4 #define CHANNELS_MAX 16 @@ -34,6 +47,7 @@ #define TEMPO_SCALE TATUMS_PER_BEAT #endif +// TODO: US_FLOAT should probably be renamed to JP_DOUBLE since eu seems to use floats too #ifdef VERSION_JP #define US_FLOAT(x) x #else @@ -78,16 +92,24 @@ struct NotePool }; struct VibratoState { - struct SequenceChannel *seqChannel; - u32 time; - s8 *curve; - u8 active; - u16 rate; - u16 extent; - u16 rateChangeTimer; - u16 extentChangeTimer; - u16 delay; -}; // size = 0x18 + /*0x00, 0x00*/ struct SequenceChannel *seqChannel; + /*0x04, 0x04*/ u32 time; +#ifdef VERSION_EU + /* , 0x08*/ s16 *curve; + /* , 0x0C*/ f32 extent; + /* , 0x10*/ f32 rate; + /* , 0x14*/ u8 active; +#endif +#ifndef VERSION_EU + /*0x08, */ s8 *curve; + /*0x0C, */ u8 active; + /*0x0E, */ u16 rate; + /*0x10, */ u16 extent; +#endif + /*0x12, 0x16*/ u16 rateChangeTimer; + /*0x14, 0x18*/ u16 extentChangeTimer; + /*0x16, 0x1A*/ u16 delay; +}; // size = 0x18, 0x1C on EU // Pitch sliding by up to one octave in the positive direction. Negative // direction is "supported" by setting extent to be negative. The code @@ -182,161 +204,329 @@ struct M64ScriptState { struct SequencePlayer { - /*0x000*/ volatile u8 enabled : 1; - /*0x000*/ u8 finished : 1; // never read - /*0x000*/ u8 muted : 1; - /*0x000*/ u8 seqDmaInProgress : 1; - /*0x000*/ u8 bankDmaInProgress : 1; - /*0x001*/ s8 seqVariation; - /*0x002*/ u8 state; - /*0x003*/ u8 noteAllocPolicy; - /*0x004*/ u8 muteBehavior; - /*0x005*/ u8 seqId; - /*0x006*/ u8 defaultBank[1]; // must be an array to get a comparison + /*US/JP, EU */ +#ifdef VERSION_EU + /*0x000, 0x000*/ u8 enabled : 1; +#else + /*0x000, 0x000*/ volatile u8 enabled : 1; +#endif + /*0x000, 0x000*/ u8 finished : 1; // never read + /*0x000, 0x000*/ u8 muted : 1; + /*0x000, 0x000*/ u8 seqDmaInProgress : 1; + /*0x000, 0x000*/ u8 bankDmaInProgress : 1; +#ifdef VERSION_EU + /* 0x000*/ u8 unk_eu : 1; +#endif +#ifndef VERSION_EU + /*0x001 */ s8 seqVariation; +#endif + /*0x002, 0x001*/ u8 state; + /*0x003, 0x002*/ u8 noteAllocPolicy; + /*0x004, 0x003*/ u8 muteBehavior; + /*0x005, 0x004*/ u8 seqId; + /*0x006, 0x005*/ u8 defaultBank[1]; // must be an array to get a comparison // to match; other u8's might also be part of that array - /*0x007*/ u8 loadingBankId; - /*0x008*/ u8 loadingBankNumInstruments; - /*0x009*/ u8 loadingBankNumDrums; - /*0x00A*/ u16 tempo; // beats per minute in JP, tatums per minute in US - /*0x00C*/ u16 tempoAcc; - /*0x00E*/ u16 fadeTimer; - /*0x010*/ s16 transposition; - /*0x012*/ u16 delay; - /*0x014*/ u8 *seqData; // buffer of some sort - /*0x018*/ f32 fadeVolume; // set to 1.0f - /*0x01C*/ f32 fadeVelocity; // set to 0.0f - /*0x020*/ f32 volume; // set to 0.0f - /*0x024*/ f32 muteVolumeScale; // set to 0.5f - /* */ u8 pad1[4]; - /*0x02C*/ struct SequenceChannel *channels[CHANNELS_MAX]; - /*0x06C*/ struct M64ScriptState scriptState; - /*0x088*/ u8 *shortNoteVelocityTable; - /*0x08C*/ u8 *shortNoteDurationTable; - /*0x090*/ struct NotePool notePool; - /*0x0D0*/ OSMesgQueue seqDmaMesgQueue; - /*0x0E8*/ OSMesg seqDmaMesg; - /*0x0EC*/ OSIoMesg seqDmaIoMesg; - /*0x100*/ OSMesgQueue bankDmaMesgQueue; - /*0x118*/ OSMesg bankDmaMesg; - /*0x11C*/ OSIoMesg bankDmaIoMesg; - /*0x130*/ u8 *bankDmaCurrMemAddr; - /*0x134*/ struct AudioBank *loadingBank; - /*0x138*/ uintptr_t bankDmaCurrDevAddr; - /*0x13C*/ ssize_t bankDmaRemaining; -}; // size = 0x140 + /*0x007, 0x006*/ u8 loadingBankId; +#ifndef VERSION_EU + /*0x008, ?????*/ u8 loadingBankNumInstruments; + /*0x009, ?????*/ u8 loadingBankNumDrums; +#endif +#ifdef VERSION_EU + /* , 0x007*/ s8 seqVariationEu[1]; +#endif + /*0x00A, 0x008*/ u16 tempo; // beats per minute in JP, tatums per minute in US/EU + /*0x00C, 0x00A*/ u16 tempoAcc; +#ifndef VERSION_EU + /*0x00E, 0x010*/ u16 fadeTimer; +#endif + /*0x010, 0x00C*/ s16 transposition; + /*0x012, 0x00E*/ u16 delay; +#ifdef VERSION_EU + /*0x00E, 0x010*/ u16 fadeTimer; + /* , 0x012*/ u16 fadeTimerUnkEu; +#endif + /*0x014, 0x014*/ u8 *seqData; // buffer of some sort + /*0x018, 0x018*/ f32 fadeVolume; // set to 1.0f + /*0x01C, 0x01C*/ f32 fadeVelocity; // set to 0.0f + /*0x020, 0x020*/ f32 volume; // set to 0.0f + /*0x024, 0x024*/ f32 muteVolumeScale; // set to 0.5f +#ifdef VERSION_EU + /* , 0x028*/ f32 unkEu28; + /* , 0x02C*/ f32 unkEu2C; +#else + /* */ u8 pad2[4]; +#endif + /*0x02C, 0x030*/ struct SequenceChannel *channels[CHANNELS_MAX]; + /*0x06C, 0x070*/ struct M64ScriptState scriptState; + /*0x088, 0x08C*/ u8 *shortNoteVelocityTable; + /*0x08C, 0x090*/ u8 *shortNoteDurationTable; + /*0x090, 0x094*/ struct NotePool notePool; + /*0x0D0, 0x0D4*/ OSMesgQueue seqDmaMesgQueue; + /*0x0E8, 0x0EC*/ OSMesg seqDmaMesg; + /*0x0EC, 0x0F0*/ OSIoMesg seqDmaIoMesg; + /*0x100, 0x108*/ OSMesgQueue bankDmaMesgQueue; + /*0x118, 0x120*/ OSMesg bankDmaMesg; + /*0x11C, 0x124*/ OSIoMesg bankDmaIoMesg; + /*0x130, 0x13C*/ u8 *bankDmaCurrMemAddr; +#ifndef VERSION_EU + /*0x134, ?????*/ struct AudioBank *loadingBank; +#endif + /*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr; + /*0x13C, 0x144*/ ssize_t bankDmaRemaining; +}; // size = 0x140, 0x148 on EU struct AdsrSettings { u8 releaseRate; +#ifdef VERSION_EU + u8 sustain; +#else u16 sustain; // sustain level, 2^16 = max +#endif struct AdsrEnvelope *envelope; }; // size = 0x8 struct AdsrState { - u8 action; - u8 state; - s16 initial; // always 0 - s16 target; - s16 current; - s16 envIndex; - s16 delay; - s16 sustain; - s16 fadeOutVel; - s32 velocity; - s32 currentHiRes; - s16 *volOut; - struct AdsrEnvelope *envelope; -}; // size = 0x20 + /*0x00, 0x00*/ u8 action; + /*0x01, 0x01*/ u8 state; +#ifndef VERSION_EU + /*0x02, */ s16 initial; // always 0 + /*0x04, */ s16 target; + /*0x06, */ s16 current; +#endif + /*0x08, 0x02*/ s16 envIndex; + /*0x0A, 0x04*/ s16 delay; +#ifdef VERSION_EU + /* , 0x08*/ f32 sustain; + /* , 0x0C*/ f32 velocity; + /* , 0x10*/ f32 fadeOutVel; + /* , 0x14*/ f32 current; + /* , 0x18*/ f32 target; + s32 pad1C; +#else + /*0x0C, */ s16 sustain; + /*0x0E, */ s16 fadeOutVel; + /*0x10, */ s32 velocity; + /*0x14, */ s32 currentHiRes; + /*0x18, */ s16 *volOut; +#endif + /*0x1C, 0x20*/ struct AdsrEnvelope *envelope; +}; // size = 0x20, 0x24 in EU struct NoteAttributes { s8 reverb; +#ifdef VERSION_EU + u8 pan; +#endif f32 freqScale; f32 velocity; +#ifndef VERSION_EU f32 pan; +#endif }; // size = 0x10 struct SequenceChannel { - /*0x00*/ u8 enabled : 1; - /*0x00*/ u8 finished : 1; - /*0x00*/ u8 stopScript : 1; - /*0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething - /*0x00*/ u8 hasInstrument : 1; - /*0x00*/ u8 stereoHeadsetEffects : 1; - /*0x00*/ u8 largeNotes : 1; // notes specify duration and velocity - /*0x00*/ u8 unused : 1; // never read, set to 0 - /*0x01*/ u8 noteAllocPolicy; - /*0x02*/ u8 muteBehavior; - /*0x03*/ u8 reverb; // or dry/wet mix - /*0x04*/ u8 notePriority; // 0-3 - /*0x05*/ u8 bankId; - /*0x06*/ u8 updatesPerFrameUnused; // never read - /*0x08*/ u16 vibratoRateStart; // initially 0x800 - /*0x0A*/ u16 vibratoExtentStart; - /*0x0C*/ u16 vibratoRateTarget; // initially 0x800 - /*0x0E*/ u16 vibratoExtentTarget; - /*0x10*/ u16 vibratoRateChangeDelay; - /*0x12*/ u16 vibratoExtentChangeDelay; - /*0x14*/ u16 vibratoDelay; - /*0x16*/ u16 delay; - /*0x18*/ s16 instOrWave; // either 0 (none), instrument index + 1, or + /* U/J, EU */ + /*0x00, 0x00*/ u8 enabled : 1; + /*0x00, 0x00*/ u8 finished : 1; + /*0x00, 0x00*/ u8 stopScript : 1; + /*0x00, 0x00*/ u8 stopSomething2 : 1; // sets SequenceChannelLayer.stopSomething + /*0x00, 0x00*/ u8 hasInstrument : 1; + /*0x00, 0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00, ????*/ u8 largeNotes : 1; // notes specify duration and velocity + /*0x00, ????*/ u8 unused : 1; // never read, set to 0 +#ifdef VERSION_EU + /* , 0x01*/ union { + struct { + u8 unk0b80 : 1; + u8 unk0b40 : 1; + u8 unk0b20 : 1; + } as_bitfields; + u8 as_u8; + } unk1; +#endif + /*0x01, 0x02*/ u8 noteAllocPolicy; + /*0x02, 0x03*/ u8 muteBehavior; + /*0x03, 0x04*/ u8 reverb; // or dry/wet mix + /*0x04, ????*/ u8 notePriority; // 0-3 + /*0x05, 0x06*/ u8 bankId; +#ifdef VERSION_EU + /* , 0x07*/ u8 reverbIndex; + /* , 0x08*/ u8 unk8; + /* , 0x09*/ u8 unk9; + /* , 0x0A*/ u8 unkA; +#else + /*0x06, */ u8 updatesPerFrameUnused; +#endif + /*0x08, 0x0C*/ u16 vibratoRateStart; // initially 0x800 + /*0x0A, 0x0E*/ u16 vibratoExtentStart; + /*0x0C, 0x10*/ u16 vibratoRateTarget; // initially 0x800 + /*0x0E, 0x12*/ u16 vibratoExtentTarget; + /*0x10, 0x14*/ u16 vibratoRateChangeDelay; + /*0x12, 0x16*/ u16 vibratoExtentChangeDelay; + /*0x14, 0x18*/ u16 vibratoDelay; + /*0x16, 0x1A*/ u16 delay; + /*0x18, 0x1C*/ s16 instOrWave; // either 0 (none), instrument index + 1, or // 0x80..0x83 for sawtooth/triangle/sine/square waves. - /*0x1A*/ s16 transposition; - /*0x1C*/ f32 volumeScale; - /*0x20*/ f32 volume; - /*0x24*/ f32 pan; - /*0x28*/ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1) - /*0x2C*/ f32 freqScale; - /*0x30*/ u8 (*dynTable)[][2]; - /*0x34*/ struct Note *noteUnused; // never read - /*0x38*/ struct SequenceChannelLayer *layerUnused; // never read - /*0x3C*/ struct Instrument *instrument; - /*0x40*/ struct SequencePlayer *seqPlayer; - /*0x44*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; - /*0x54*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, + /*0x1A, 0x1E*/ s16 transposition; + /*0x1C, 0x20*/ f32 volumeScale; + /*0x20, 0x24*/ f32 volume; +#ifndef VERSION_EU + /*0x24, 0x28*/ f32 pan; +#else + /*0x24, 0x28*/ s32 pan; +#endif + /*0x28, 0x2C*/ f32 panChannelWeight; // proportion of pan that comes from the channel (0..1) + /*0x2C, 0x30*/ f32 freqScale; + /*0x30, 0x34*/ u8 (*dynTable)[][2]; + /*0x34, ????*/ struct Note *noteUnused; // never read + /*0x38, ????*/ struct SequenceChannelLayer *layerUnused; // never read + /*0x3C, 0x40*/ struct Instrument *instrument; + /*0x40, 0x44*/ struct SequencePlayer *seqPlayer; + /*0x44, 0x48*/ struct SequenceChannelLayer *layers[LAYERS_MAX]; + /*0x54, 0x58*/ s8 soundScriptIO[8]; // bridge between sound script and audio lib. For player 2, // [0] contains enabled, [4] contains sound ID, [5] contains reverb adjustment - /*0x5C*/ struct M64ScriptState scriptState; - /*0x78*/ struct AdsrSettings adsr; - /*0x80*/ struct NotePool notePool; -}; // size = 0xC0 + /*0x5C, 0x60*/ struct M64ScriptState scriptState; + /*0x78, 0x7C*/ struct AdsrSettings adsr; + /*0x80, 0x84*/ struct NotePool notePool; +}; // size = 0xC0, 0xC4 in EU struct SequenceChannelLayer // Maybe SequenceTrack? { - /*0x00*/ u8 enabled : 1; - /*0x00*/ u8 finished : 1; - /*0x00*/ u8 stopSomething : 1; // ? - /*0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound - /*0x01*/ u8 status; - /*0x02*/ u8 noteDuration; // set to 0x80 - /*0x03*/ u8 portamentoTargetNote; - /*0x04*/ struct Portamento portamento; - /*0x14*/ struct AdsrSettings adsr; - /*0x1C*/ u16 portamentoTime; - /*0x1E*/ s16 transposition; // #semitones added to play commands + /* U/J, EU */ + /*0x00, 0x00*/ u8 enabled : 1; + /*0x00, 0x00*/ u8 finished : 1; + /*0x00, 0x00*/ u8 stopSomething : 1; // ? + /*0x00, 0x00*/ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound +#ifdef VERSION_EU + /* , 0x00*/ u8 unkEu0b8 : 1; + /* , 0x00*/ u8 unkEu0b4 : 1; + /* , 0x00*/ u8 unkEu0b2 : 1; + /* , 0x01*/ u8 euUnk1; // euInstOrWave? +#endif + /*0x01, 0x02*/ u8 status; + /*0x02, 0x03*/ u8 noteDuration; // set to 0x80 + /*0x03, 0x04*/ u8 portamentoTargetNote; +#ifdef VERSION_EU + /* , 0x05*/ u8 euUnk5; // contains US/JP pan * 128.0f + /* , 0x06*/ u8 notePan; +#endif + /*0x04, 0x08*/ struct Portamento portamento; + /*0x14, 0x18*/ struct AdsrSettings adsr; + /*0x1C, 0x20*/ u16 portamentoTime; + /*0x1E, 0x22*/ s16 transposition; // #semitones added to play commands // (m64 instruction encoding only allows referring to the limited range // 0..0x3f; this makes 0x40..0x7f accessible as well) - /*0x20*/ f32 freqScale; - /*0x24*/ f32 velocitySquare; + /*0x20, 0x24*/ f32 freqScale; + /*0x24, 0x28*/ f32 velocitySquare; +#ifndef VERSION_EU /*0x28*/ f32 pan; - /*0x2C*/ f32 noteVelocity; +#endif + /*0x2C, 0x2C*/ f32 noteVelocity; +#ifndef VERSION_EU /*0x30*/ f32 notePan; - /*0x34*/ f32 noteFreqScale; - /*0x38*/ s16 shortNoteDefaultPlayPercentage; - /*0x3A*/ s16 playPercentage; // it's not really a percentage... - /*0x3C*/ s16 delay; - /*0x3E*/ s16 duration; - /*0x40*/ s16 delayUnused; // set to 'delay', never read - /*0x44*/ struct Note *note; - /*0x48*/ struct Instrument *instrument; - /*0x4C*/ struct AudioBankSound *sound; - /*0x50*/ struct SequenceChannel *seqChannel; - /*0x54*/ struct M64ScriptState scriptState; - /*0x70*/ struct AudioListItem listItem; +#endif + /*0x34, 0x30*/ f32 noteFreqScale; + /*0x38, 0x34*/ s16 shortNoteDefaultPlayPercentage; + /*0x3A, 0x36*/ s16 playPercentage; // it's not really a percentage... + /*0x3C, 0x38*/ s16 delay; + /*0x3E, 0x3A*/ s16 duration; + /*0x40, 0x3C*/ s16 delayUnused; // set to 'delay', never read + /*0x44, 0x40*/ struct Note *note; + /*0x48, 0x44*/ struct Instrument *instrument; + /*0x4C, 0x48*/ struct AudioBankSound *sound; + /*0x50, 0x4C*/ struct SequenceChannel *seqChannel; + /*0x54, 0x50*/ struct M64ScriptState scriptState; + /*0x70, 0x6C*/ struct AudioListItem listItem; +#ifdef VERSION_EU + u8 pad2[4]; +#endif }; // size = 0x80 +#ifdef VERSION_EU +struct NoteSynthesisState +{ + /*0x00*/ u8 restart; + /*0x01*/ u8 sampleDmaIndex; + /*0x02*/ u8 prevHeadsetPanRight; + /*0x03*/ u8 prevHeadsetPanLeft; + /* */ u16 samplePosFrac; //? + /*0x08*/ s32 samplePosInt; + /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; + /*0x10*/ s16 curVolLeft; + /*0x12*/ s16 curVolRight; +}; +struct NotePlaybackState +{ + /* U/J, EU */ + /*0x04, 0x00*/ u8 priority; + /* 0x01*/ u8 waveId; + /* 0x02*/ u8 sampleCountIndex; + /*0x08, 0x04*/ s16 adsrVolScale; + /*0x18, 0x08*/ f32 portamentoFreqScale; + /*0x1C, 0x0C*/ f32 vibratoFreqScale; + /*0x28, 0x10*/ struct SequenceChannelLayer *prevParentLayer; + /*0x2C, 0x14*/ struct SequenceChannelLayer *parentLayer; + /*0x30, 0x18*/ struct SequenceChannelLayer *wantedParentLayer; + /* , 0x1C*/ struct NoteAttributes attributes; + /*0x54, 0x28*/ struct AdsrState adsr; + /*0x74, 0x4C*/ struct Portamento portamento; + /*0x84, 0x5C*/ struct VibratoState vibratoState; +}; +struct NoteSubEu +{ + /*0x00*/ volatile u8 enabled : 1; + /*0x00*/ u8 needsInit : 1; + /*0x00*/ u8 finished : 1; + /*0x00*/ u8 envMixerNeedsInit : 1; + /*0x00*/ u8 stereoStrongRight : 1; + /*0x00*/ u8 stereoStrongLeft : 1; + /*0x00*/ u8 stereoHeadsetEffects : 1; + /*0x00*/ u8 usesHeadsetPanEffects : 1; + /*0x01*/ u8 unk1b567 : 3; + /*0x01*/ u8 unk1b234 : 3; + /*0x01*/ u8 isSyntheticWave : 1; + /*0x01*/ u8 hasTwoAdpcmParts : 1; + /*0x02*/ u8 bankId; + /*0x03*/ u8 headsetPanRight; + /*0x04*/ u8 headsetPanLeft; + /*0x05*/ u8 reverbVol; + /*0x06*/ u16 targetVolLeft; + /*0x08*/ u16 targetVolRight; + /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 + /*0x0C*/ union { + s16 *samples; + struct AudioBankSound *audioBankSound; + } sound; +}; struct Note { + /* U/J, EU */ + /*0xA4, 0x00*/ struct AudioListItem listItem; + /* 0x10*/ struct NoteSynthesisState synthesisState; + u8 pad0[12]; + /*0x04, 0x30*/ u8 priority; + /* 0x31*/ u8 waveId; + /* 0x32*/ u8 sampleCountIndex; + /*0x08, 0x34*/ s16 adsrVolScale; + /*0x18, 0x38*/ f32 portamentoFreqScale; + /*0x1C, 0x3C*/ f32 vibratoFreqScale; + /*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer; + /*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer; + /*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; + /* , 0x4C*/ struct NoteAttributes attributes; + /*0x54, 0x58*/ struct AdsrState adsr; + /*0x74, 0x7C*/ struct Portamento portamento; + /*0x84, 0x8C*/ struct VibratoState vibratoState; + u8 pad3[8]; + /* , 0xB0*/ struct NoteSubEu noteSubEu; +}; // size = 0xC0 +#else +struct Note +{ + /* U/J, EU */ /*0x00*/ u8 enabled : 1; /*0x00*/ u8 needsInit : 1; /*0x00*/ u8 restart : 1; @@ -348,24 +538,24 @@ struct Note /*0x01*/ u8 usesHeadsetPanEffects; /*0x02*/ u8 unk2; /*0x03*/ u8 sampleDmaIndex; - /*0x04*/ u8 priority; + /*0x04, 0x30*/ u8 priority; /*0x05*/ u8 sampleCount; // 0, 8, 16, 32 or 64 /*0x06*/ u8 instOrWave; - /*0x07*/ u8 bankId; + /*0x07*/ u8 bankId; // in NoteSubEu on EU /*0x08*/ s16 adsrVolScale; /* */ u8 pad1[2]; - /*0x0C*/ u16 headsetPanRight; - /*0x0E*/ u16 headsetPanLeft; + /*0x0C, 0xB3*/ u16 headsetPanRight; + /*0x0E, 0xB4*/ u16 headsetPanLeft; /*0x10*/ u16 prevHeadsetPanRight; /*0x12*/ u16 prevHeadsetPanLeft; /*0x14*/ s32 samplePosInt; - /*0x18*/ f32 portamentoFreqScale; - /*0x1C*/ f32 vibratoFreqScale; + /*0x18, 0x38*/ f32 portamentoFreqScale; + /*0x1C, 0x3C*/ f32 vibratoFreqScale; /*0x20*/ u16 samplePosFrac; /*0x24*/ struct AudioBankSound *sound; - /*0x28*/ struct SequenceChannelLayer *prevParentLayer; - /*0x2C*/ struct SequenceChannelLayer *parentLayer; - /*0x30*/ struct SequenceChannelLayer *wantedParentLayer; + /*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer; + /*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer; + /*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; /*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers; /*0x38*/ f32 frequency; /*0x3C*/ u16 targetVolLeft; @@ -373,16 +563,17 @@ struct Note /*0x40*/ u8 reverb; /*0x41*/ u8 unused1; // never read, set to 0x3f /*0x44*/ struct NoteAttributes attributes; - /*0x54*/ struct AdsrState adsr; - /*0x74*/ struct Portamento portamento; - /*0x84*/ struct VibratoState vibratoState; + /*0x54, 0x58*/ struct AdsrState adsr; + /*0x74, 0x7C*/ struct Portamento portamento; + /*0x84, 0x8C*/ struct VibratoState vibratoState; /*0x9C*/ s16 curVolLeft; /*0x9E*/ s16 curVolRight; /*0xA0*/ s16 reverbVol; /*0xA2*/ s16 unused2; // never read, set to 0 - /*0xA4*/ struct AudioListItem listItem; - /* */ u8 pad2[0xc]; + /*0xA4, 0x00*/ struct AudioListItem listItem; + /* */ u8 pad2[0xc]; }; // size = 0xC0 +#endif struct NoteSynthesisBuffers { @@ -392,7 +583,32 @@ struct NoteSynthesisBuffers s16 panResampleState[0x10]; s16 panSamplesBuffer[0x20]; s16 dummyResampleState[0x10]; +#ifndef VERSION_EU s16 samples[0x40]; +#endif +}; + +struct ReverbSettingsEU +{ + u8 downsampleRate; + u8 windowSize; // To be multiplied by 64 + u16 gain; +}; + +struct AudioSessionSettingsEU +{ + u32 frequency; + u8 unk1; // always 1 + u8 maxSimultaneousNotes; + u8 numReverbs; // always 1 + u8 unk2; // always 0 + struct ReverbSettingsEU *reverbSettings; + u16 volume; + u16 unk3; // always 0 + u32 persistentSeqMem; + u32 persistentBankMem; + u32 temporarySeqMem; + u32 temporaryBankMem; }; struct AudioSessionSettings @@ -409,4 +625,39 @@ struct AudioSessionSettings /*0x18*/ u32 temporaryBankMem; }; // size = 0x1C +struct AudioBufferParametersEU { + /*0x00*/ s16 presetUnk4; // audio frames per vsync? + /*0x02*/ u16 frequency; + /*0x04*/ u16 aiFrequency; // ?16 + /*0x06*/ s16 samplesPerFrameTarget; + /*0x08*/ s16 maxAiBufferLength; + /*0x0A*/ s16 minAiBufferLength; + /*0x0C*/ s16 updatesPerFrame; + /*0x0E*/ s16 samplesPerUpdate; + /*0x10*/ s16 samplesPerUpdateMax; + /*0x12*/ s16 samplesPerUpdateMin; + /*0x14*/ f32 resampleRate; // contains 32000.0f / frequency + /*0x18*/ f32 updatesPerFrameInv; // 1.0f / updatesPerFrame + /*0x1C*/ f32 unkUpdatesPerFrameScaled; // 3.0f / (1280.0f * updatesPerFrame) +}; + +struct EuAudioCmd { + union { + struct { + u8 op; + u8 arg1; + u8 arg2; + u8 arg3; + } s; + s32 first; + } u; + union { + s32 as_s32; + u32 as_u32; + f32 as_f32; + u8 as_u8; + s8 as_s8; + } u2; +}; + #endif /* AUDIO_INTERNAL_H */ diff --git a/src/audio/load.c b/src/audio/load.c index c67feeb..6cbad7b 100644 --- a/src/audio/load.c +++ b/src/audio/load.c @@ -18,16 +18,20 @@ struct SharedDma { /*0xE*/ u8 ttl; // duration after which the DMA can be discarded }; // size = 0x10 -struct Note *gNotes; -struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; -struct SequenceChannel gSequenceChannels[32]; +// EU only +void func_802ada64(void); +s32 func_eu_802E2AA0(void); -#ifdef VERSION_JP -struct SequenceChannelLayer gSequenceLayers[48]; -#else -struct SequenceChannelLayer gSequenceLayers[52]; +struct Note *gNotes; + +#ifdef VERSION_EU +static u8 pad[4]; #endif +struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; +struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; + struct SequenceChannel gSequenceChannelNone; struct AudioListItem gLayerFreeList; struct NotePool gNoteFreeLists; @@ -35,6 +39,7 @@ struct NotePool gNoteFreeLists; OSMesgQueue gCurrAudioFrameDmaQueue; OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; + OSMesgQueue gAudioDmaMesgQueue; OSMesg gAudioDmaMesg; OSIoMesg gAudioDmaIoMesg; @@ -52,12 +57,44 @@ u8 sSampleDmaReuseQueueTail2; u8 sSampleDmaReuseQueueHead1; u8 sSampleDmaReuseQueueHead2; +// bss correct up to here + ALSeqFile *gSeqFileHeader; ALSeqFile *gAlCtlHeader; ALSeqFile *gAlTbl; u8 *gAlBankSets; u16 gSequenceCount; +struct CtlEntry *gCtlEntries; + +#ifdef VERSION_EU +u32 padEuBss1; +struct AudioBufferParametersEU gAudioBufferParameters; +#else +s32 gAiFrequency; +#endif + +u32 D_80226D68; +s32 gMaxAudioCmds; +s32 gMaxSimultaneousNotes; + +#ifdef VERSION_EU +s16 gTempoInternalToExternal; +#else +s32 gSamplesPerFrameTarget; +s32 gMinAiBufferLength; + +s16 gTempoInternalToExternal; + +s8 gAudioUpdatesPerFrame; +#endif + +s8 gSoundMode; + +#ifdef VERSION_EU +s8 gAudioUpdatesPerFrame; +#endif + extern u64 gAudioGlobalsStartMarker; extern u64 gAudioGlobalsEndMarker; @@ -66,6 +103,7 @@ extern u8 gSoundDataRaw[]; // sound_data.tbl extern u8 gMusicData[]; // sequences.s extern u8 gBankSetsData[]; // bank_sets.s + /** * Performs an immediate DMA copy */ @@ -88,9 +126,12 @@ void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQ * Performs a partial asynchronous (normal priority) DMA copy. This is limited * to 0x1000 bytes transfer at once. */ -void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, - OSIoMesg *mesg) { +void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { +#ifdef VERSION_EU + ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); +#else ssize_t transfer = (*remaining < 0x1000 ? *remaining : 0x1000); +#endif *remaining -= transfer; osInvalDCache(*vAddr, transfer); osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, *devAddr, *vAddr, transfer, queue); @@ -102,7 +143,11 @@ void decrease_sample_dma_ttls() { u32 i; for (i = 0; i < sSampleDmaListSize1; i++) { +#ifdef VERSION_EU + struct SharedDma *temp = &sSampleDmas[i]; +#else struct SharedDma *temp = sSampleDmas + i; +#endif if (temp->ttl != 0) { temp->ttl--; if (temp->ttl == 0) { @@ -113,7 +158,11 @@ void decrease_sample_dma_ttls() { } for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { +#ifdef VERSION_EU + struct SharedDma *temp = &sSampleDmas[i]; +#else struct SharedDma *temp = sSampleDmas + i; +#endif if (temp->ttl != 0) { temp->ttl--; if (temp->ttl == 0) { @@ -138,7 +187,11 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { if (arg2 != 0 || *arg3 >= sSampleDmaListSize1) { for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { +#ifdef VERSION_EU + dma = &sSampleDmas[i]; +#else dma = sSampleDmas + i; +#endif bufferPos = devAddr - dma->source; if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { // We already have a DMA request for this memory range. @@ -155,7 +208,11 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { } dma->ttl = 60; *arg3 = (u8) i; +#ifdef VERSION_EU + return &dma->buffer[(devAddr - dma->source)]; +#else return (devAddr - dma->source) + dma->buffer; +#endif } } @@ -168,7 +225,12 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { hasDma = TRUE; } } else { +#ifdef VERSION_EU + dma = sSampleDmas; + dma += *arg3; +#else dma = sSampleDmas + *arg3; +#endif bufferPos = devAddr - dma->source; if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { // We already have DMA for this memory range. @@ -176,6 +238,10 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { // Move the DMA out of the reuse queue, by swapping it with the // tail, and then incrementing the tail. if (dma->reuseIndex != sSampleDmaReuseQueueTail1) { +#ifdef VERSION_EU + if (1) { + } +#endif sSampleDmaReuseQueue1[dma->reuseIndex] = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]; sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex = @@ -184,7 +250,11 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { sSampleDmaReuseQueueTail1++; } dma->ttl = 2; +#ifdef VERSION_EU + return dma->buffer + (devAddr - dma->source); +#else return (devAddr - dma->source) + dma->buffer; +#endif } } @@ -201,26 +271,45 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3) { dma->ttl = 2; dma->source = dmaDevAddr; dma->sizeUnused = transfer; -#ifndef VERSION_JP +#ifdef VERSION_US osInvalDCache(dma->buffer, transfer); #endif +#ifdef VERSION_EU + osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, + OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); + *arg3 = dmaIndex; + return (devAddr - dmaDevAddr) + dma->buffer; +#else gCurrAudioFrameDmaCount++; osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount - 1], OS_MESG_PRI_NORMAL, OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); *arg3 = dmaIndex; return dma->buffer + (devAddr - dmaDevAddr); +#endif } -// called from sound_reset void init_sample_dma_buffers(UNUSED s32 arg0) { s32 i; +#ifdef VERSION_EU +#define j i +#else s32 j; +#endif +#ifdef VERSION_EU + D_80226D68 = 0x400; + for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) { +#else D_80226D68 = 144 * 9; for (i = 0; i < gMaxSimultaneousNotes * 3; i++) { +#endif sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, D_80226D68); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { +#ifdef VERSION_EU + break; +#else goto out1; +#endif } sSampleDmas[gSampleDmaNumListItems].source = 0; sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; @@ -229,7 +318,9 @@ void init_sample_dma_buffers(UNUSED s32 arg0) { sSampleDmas[gSampleDmaNumListItems].bufSize = D_80226D68; gSampleDmaNumListItems++; } +#ifndef VERSION_EU out1: +#endif for (i = 0; (u32) i < gSampleDmaNumListItems; i++) { sSampleDmaReuseQueue1[i] = (u8) i; @@ -244,11 +335,19 @@ out1: sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; sSampleDmaListSize1 = gSampleDmaNumListItems; +#ifdef VERSION_EU + D_80226D68 = 0x200; +#else D_80226D68 = 160 * 9; +#endif for (i = 0; i < gMaxSimultaneousNotes; i++) { sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, D_80226D68); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { +#ifdef VERSION_EU + break; +#else goto out2; +#endif } sSampleDmas[gSampleDmaNumListItems].source = 0; sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; @@ -257,7 +356,9 @@ out1: sSampleDmas[gSampleDmaNumListItems].bufSize = D_80226D68; gSampleDmaNumListItems++; } +#ifndef VERSION_EU out2: +#endif for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) { sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i; @@ -272,6 +373,9 @@ out2: sSampleDmaReuseQueueTail2 = 0; sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; +#ifdef VERSION_EU +#undef j +#endif } #ifndef static @@ -279,122 +383,177 @@ out2: #undef static #endif -static void unused_80317844(void) { - // With -O2 -framepointer, this never-invoked static function gets *almost* - // optimized out, regardless of contents, leaving only "jr $ra, nop". - // If not declared as static, it unnecessarily moves the stack pointer up - // and down by 8. -} +#ifndef VERSION_EU +// This function gets optimized out on US due to being static and never called +static +#endif -#ifdef NON_MATCHING -void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { - // Make pointers into real pointers rather than indices - struct Instrument *instrument; - struct Instrument **itInstrs; - u32 i; - uintptr_t memBase = (uintptr_t) mem; - uintptr_t offsetBase = (uintptr_t) offset; +void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) { + struct AudioBankSample *sample; + void *patched; + UNUSED u8 *mem; // unused on US -#define INIT_SOUND(sound) \ - { \ - struct AudioBankSample **itSample = &sound.sample; \ - if ((*itSample) != 0) { \ - /* Making these volatile gives correct codegen further down; it makes \ - * lw/addiu/sw's happen in source order, and uses two registers... \ - * It looks odd, though, so maybe they should not be volatile. \ - * It might also be causing the extra register use. \ - * Presumably sample and sample2 ought to have different types, \ - * but that doesn't matter for codegen. */ \ - volatile struct AudioBankSample *sample, *sample2; \ - *itSample = (void *) (memBase + (uintptr_t)(*itSample)); \ - sample = *itSample; \ - sample2 = *itSample; \ - if (sample2->loaded == FALSE) { \ - void *a = sample2->sampleAddr; \ - void *b = sample->loop; \ - void *c = sample->book; \ - sample->sampleAddr = (void *) (offsetBase + (uintptr_t) a); \ - sample->loop = (void *) (memBase + (uintptr_t) b); \ - sample->book = (void *) (memBase + (uintptr_t) c); \ - sample->loaded = TRUE; \ - } \ - } \ +#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) + + if (sound->sample != NULL) { + sample = sound->sample = PATCH(sound->sample, memBase); + if (sample->loaded == 0) { + sample->sampleAddr = PATCH(sample->sampleAddr, offsetBase); + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + sample->loaded = 1; + } +#ifdef VERSION_EU + else if (sample->loaded == 0x80) { + PATCH(sample->sampleAddr, offsetBase); + mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); + if (mem == NULL) { + sample->sampleAddr = patched; + sample->loaded = 1; + } else { + audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize); + sample->loaded = 0x81; + sample->sampleAddr = mem; + } + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + } +#endif } - if (mem->drums != NULL) { - if (numDrums != 0) { - mem->drums = (struct Drum **) (memBase + (uintptr_t) mem->drums); - if (numDrums != 0) { - for (i = 0; i < numDrums; i++) { -#if 0 - // This doesn't work: Taking the address to mem->drums[i] - // does an sll to figure out the lower loop limit. - volatile struct Drum *drum, *drum2; - struct Drum **h = &mem->drums[i]; - if (*h == 0) continue; - { - *h = (void *)(memBase + (uintptr_t)*h); - drum = *h; - drum2 = *h; - if (drum2->loaded == FALSE) - { - void *d; - INIT_SOUND(((struct Drum *)drum2)->sound); - d = drum2->envelope; - drum->loaded = TRUE; - drum->envelope = (void *) (memBase + (uintptr_t)d); - } - } -#else - // Neither does this: Using mem->drums[i] directly - // deduplicates it -- drum and drum2 end up in the same - // register. - struct Drum **drums = mem->drums; - uintptr_t h = (uintptr_t) drums[i]; - if (h != 0) { - volatile struct Drum *drum, *drum2; - drums[i] = (struct Drum *) (memBase + h); - drum = drums[i]; - drum2 = drums[i]; - if (drum->loaded == FALSE) { - void *d; - INIT_SOUND(((struct Drum *) drum)->sound); - d = drum->envelope; - drum2->loaded = TRUE; - drum2->envelope = (void *) (memBase + (uintptr_t) d); - } - } +#undef PATCH +} + +#ifndef VERSION_EU +#define PATCH_SOUND(_sound, mem, offset) \ +{ \ + struct AudioBankSound *sound = _sound; \ + struct AudioBankSample *sample; \ + void *patched; \ + if ((*sound).sample != (void *) 0) \ + { \ + patched = (void *)(((unsigned int)(*sound).sample) + ((unsigned int)((unsigned char *) mem))); \ + (*sound).sample = patched; \ + sample = (*sound).sample; \ + if ((*sample).loaded == 0) \ + { \ + patched = (void *)(((unsigned int)(*sample).sampleAddr) + ((unsigned int) offset)); \ + (*sample).sampleAddr = patched; \ + patched = (void *)(((unsigned int)(*sample).loop) + ((unsigned int)((unsigned char *) mem))); \ + (*sample).loop = patched; \ + patched = (void *)(((unsigned int)(*sample).book) + ((unsigned int)((unsigned char *) mem))); \ + (*sample).book = patched; \ + (*sample).loaded = 1; \ + } \ + } \ +} #endif + +// on US/JP this inlines patch_sound, using some -sopt compiler flag +void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { + struct Instrument *instrument; + struct Instrument **itInstrs; + struct Instrument **end; + struct AudioBank *temp; + u32 i; + void *patched; + struct Drum *drum; + struct Drum **drums; +#ifdef VERSION_EU + u32 numDrums2; +#endif + +#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) +#define PATCH_MEM(x) x = PATCH(x, mem) + + drums = mem->drums; +#ifndef VERSION_EU + if (drums != NULL && numDrums > 0) { + mem->drums = (void *)((unsigned int) drums + (unsigned int) mem); + if (numDrums > 0) //! unneeded when -sopt is enabled + for (i = 0; i < numDrums; i++) { +#else + numDrums2 = numDrums; + if (drums != NULL && numDrums2 > 0) { + mem->drums = PATCH(drums, mem); + for (i = 0; i < numDrums2; i++) { +#endif + patched = mem->drums[i]; + if (patched != NULL) { + drum = PATCH(patched, mem); + mem->drums[i] = drum; + if (drum->loaded == 0) { +#ifndef VERSION_EU + //! copt replaces drum with 'patched' for these two lines + PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset); + patched = (*(struct Drum *)patched).envelope; + drum->envelope = (void *)((uintptr_t) mem + (uintptr_t) patched); +#else + patch_sound(&drum->sound, (u8 *) mem, offset); + patched = drum->envelope; + drum->envelope = (void *)((uintptr_t) patched + (uintptr_t) mem); +#endif + drum->loaded = 1; } + } } } - if ((numInstruments >= 1) && (numInstruments >= 1) != 0) { - itInstrs = mem->instruments; + //! Doesn't affect EU, but required for US/JP + temp = &*mem; +#ifndef VERSION_EU + if (numInstruments >= 1) +#endif + if (numInstruments > 0) { + //! Doesn't affect EU, but required for US/JP + struct Instrument **tempInst; + itInstrs = temp->instruments; + tempInst = temp->instruments; + end = numInstruments + tempInst; + +#ifndef VERSION_EU +l2: +#else do { - if (*itInstrs) { - *itInstrs = (void *) (memBase + (uintptr_t) *itInstrs); +#endif + if (*itInstrs != NULL) { + *itInstrs = (void *)((uintptr_t) *itInstrs + (uintptr_t) mem); instrument = *itInstrs; - if (instrument->loaded == FALSE) { - INIT_SOUND(instrument->lowNotesSound); - INIT_SOUND(instrument->normalNotesSound); - INIT_SOUND(instrument->highNotesSound); - - instrument->loaded = TRUE; - instrument->envelope = (void *) (memBase + (uintptr_t) instrument->envelope); + if (instrument->loaded == 0) { +#ifndef VERSION_EU + PATCH_SOUND(&instrument->lowNotesSound, (u8 *) mem, offset); + PATCH_SOUND(&instrument->normalNotesSound, (u8 *) mem, offset); + PATCH_SOUND(&instrument->highNotesSound, (u8 *) mem, offset); +#else + patch_sound(&instrument->lowNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->normalNotesSound, (u8 *) mem, offset); + patch_sound(&instrument->highNotesSound, (u8 *) mem, offset); +#endif + patched = instrument->envelope; +#ifndef VERSION_EU + instrument->envelope = (void *)((uintptr_t) mem + (uintptr_t) patched); +#else + instrument->envelope = (void *)((uintptr_t) patched + (uintptr_t) mem); +#endif + instrument->loaded = 1; } } itInstrs++; - } while (itInstrs != &mem->instruments[numInstruments]); - } -#undef INIT_SOUND -} - +#ifndef VERSION_EU + //! goto generated by copt, required to match US/JP + if (end != itInstrs) { + goto l2; + } #else -GLOBAL_ASM("asm/non_matchings/patch_audio_bank.s") + } while (end != itInstrs); #endif + } +#undef PATCH_MEM +#undef PATCH +#undef PATCH_SOUND +} struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { UNUSED u32 pad1[4]; @@ -437,6 +596,9 @@ struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *s struct AudioBank *ret; u8 *ctlData; OSMesgQueue *mesgQueue; +#ifdef VERSION_EU + UNUSED u32 pad3; +#endif alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; alloc = ALIGN16(alloc); @@ -451,15 +613,29 @@ struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *s numInstruments = buf[0]; numDrums = buf[1]; seqPlayer->loadingBankId = (u8) bankId; +#ifdef VERSION_EU + gCtlEntries[bankId].numInstruments = numInstruments; + gCtlEntries[bankId].numDrums = numDrums; + gCtlEntries[bankId].instruments = ret->instruments; + gCtlEntries[bankId].drums = 0; + seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; + seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); + seqPlayer->bankDmaRemaining = alloc; + if (1) { + } +#else seqPlayer->loadingBankNumInstruments = numInstruments; seqPlayer->loadingBankNumDrums = numDrums; seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; seqPlayer->loadingBank = ret; seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); seqPlayer->bankDmaRemaining = alloc; +#endif mesgQueue = &seqPlayer->bankDmaMesgQueue; osCreateMesgQueue(mesgQueue, &seqPlayer->bankDmaMesg, 1); +#ifndef VERSION_EU seqPlayer->bankDmaMesg = NULL; +#endif seqPlayer->bankDmaInProgress = TRUE; audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, &seqPlayer->bankDmaRemaining, mesgQueue, &seqPlayer->bankDmaIoMesg); @@ -502,12 +678,16 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) if (seqLength <= 0x40) { // Immediately load short sequenece audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); + if (1) { gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; + } } else { audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40); mesgQueue = &seqPlayer->seqDmaMesgQueue; osCreateMesgQueue(mesgQueue, &seqPlayer->seqDmaMesg, 1); +#ifndef VERSION_EU seqPlayer->seqDmaMesg = NULL; +#endif seqPlayer->seqDmaInProgress = TRUE; audio_dma_copy_async((uintptr_t)(seqData + 0x40), (u8 *) ptr + 0x40, seqLength - 0x40, mesgQueue, &seqPlayer->seqDmaIoMesg); @@ -525,13 +705,23 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { *nullCount = 0; *nonNullCount = 0; +#ifdef VERSION_EU + offset = ((u16 *) gAlBankSets)[seqId]; + for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { + bankId = gAlBankSets[offset++]; +#else offset = ((u16 *) gAlBankSets)[seqId] + 1; for (i = gAlBankSets[offset - 1], ret = 0; i != 0; i--) { offset++; bankId = gAlBankSets[offset - 1]; +#endif if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { +#ifdef VERSION_EU + temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId); +#else temp = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); +#endif } else { temp = NULL; } @@ -553,13 +743,23 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *arg1) { u16 offset; u8 i; +#ifdef VERSION_EU + offset = ((u16 *) gAlBankSets)[seqId]; + for (i = gAlBankSets[offset++]; i != 0; i--) { + bankId = gAlBankSets[offset++]; +#else offset = ((u16 *) gAlBankSets)[seqId] + 1; for (i = gAlBankSets[offset - 1]; i != 0; i--) { offset++; bankId = gAlBankSets[offset - 1]; +#endif if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { +#ifdef VERSION_EU + ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId); +#else ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); +#endif } else { ret = NULL; } @@ -670,10 +870,20 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { } void audio_init() { +#ifdef VERSION_EU + UNUSED s8 pad[16]; +#else UNUSED s8 pad[32]; u8 buf[0x10]; +#endif s32 i, j, k; - s32 lim1, lim2, lim3; + UNUSED s32 lim1; // lim1 unused in EU +#ifdef VERSION_EU + u8 buf[0x10]; + s32 UNUSED lim2, lim3; +#else + s32 lim2, lim3; +#endif u32 size; u64 *ptr64; void *data; @@ -681,6 +891,7 @@ void audio_init() { gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; +#ifndef VERSION_EU lim1 = gUnusedCount80333EE8; for (i = 0; i < lim1; i++) { gUnused80226E58[i] = 0; @@ -699,9 +910,26 @@ void audio_init() { i++; ptr64[i] = 0; } +#else + for (i = 0; i < gAudioHeapSize / 8; i++) { + ((u64 *) gAudioHeap)[i] = 0; + } + + lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; + ptr64 = &gAudioGlobalsStartMarker; + for (k = lim3; k >= 0; k--) { + *ptr64++ = 0; + } + + D_EU_802298D0 = 20.03042f; + gRefreshRate = 50; + func_802ada64(); + if (k) { + } +#endif for (i = 0; i < NUMAIBUFFERS; i++) { - gAiBufferLengths[i] = 0x00a0; + gAiBufferLengths[i] = 0xa0; } gAudioFrameCount = 0; @@ -720,21 +948,32 @@ void audio_init() { sound_init_main_pools(D_80333EF0); for (i = 0; i < NUMAIBUFFERS; i++) { - gAiBuffers[i] = soundAlloc(&gAudioInitPool, 0xa00); + gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN); - for (j = 0; j < 0x500; j++) { + for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { gAiBuffers[i][j] = 0; } } +#ifdef VERSION_EU + gAudioResetPresetIdToLoad = 0; + gAudioResetStatus = 1; + func_eu_802E2AA0(); +#else audio_reset_session(&gAudioSessionPresets[0]); +#endif // Load header for sequence data (assets/music_data.sbk.s) gSeqFileHeader = (ALSeqFile *) buf; data = gMusicData; audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); gSequenceCount = gSeqFileHeader->seqCount; +#ifdef VERSION_EU + size = gSequenceCount * sizeof(ALSeqData) + 4; + size = ALIGN16(size); +#else size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4); +#endif gSeqFileHeader = soundAlloc(&gAudioInitPool, size); audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); alSeqFileNew(gSeqFileHeader, data); @@ -766,3 +1005,4 @@ void audio_init() { init_sequence_players(); gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; } + diff --git a/src/audio/load.h b/src/audio/load.h index 933a9c6..5632f52 100644 --- a/src/audio/load.h +++ b/src/audio/load.h @@ -18,13 +18,8 @@ extern struct Note *gNotes; // gSequencePlayers[2] is sound extern struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; -extern struct SequenceChannel gSequenceChannels[32]; - -#ifdef VERSION_JP -extern struct SequenceChannelLayer gSequenceLayers[48]; -#else -extern struct SequenceChannelLayer gSequenceLayers[52]; -#endif +extern struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +extern struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; extern struct SequenceChannel gSequenceChannelNone; @@ -36,6 +31,21 @@ extern u32 gSampleDmaNumListItems; extern ALSeqFile *gAlTbl; extern u8 *gAlBankSets; +extern struct CtlEntry *gCtlEntries; +#ifdef VERSION_EU +extern struct AudioBufferParametersEU gAudioBufferParameters; +#endif +extern s32 gAiFrequency; +extern u32 D_80226D68; +extern s32 gMaxAudioCmds; + +extern s32 gMaxSimultaneousNotes; +extern s32 gSamplesPerFrameTarget; +extern s32 gMinAiBufferLength; +extern s16 gTempoInternalToExternal; +extern s8 gAudioUpdatesPerFrame; // = 4 +extern s8 gSoundMode; + void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg); void decrease_sample_dma_ttls(void); void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *arg3); diff --git a/src/audio/memory.c b/src/audio/memory.c index 73a68af..e1a37dd 100644 --- a/src/audio/memory.c +++ b/src/audio/memory.c @@ -22,9 +22,11 @@ struct PoolSplit2 { u32 wantTemporary; }; // size = 0x8 +#ifndef VERSION_EU s16 gVolume; s8 gReverbDownsampleRate; u8 sReverbDownsampleRateLog; // never read +#endif struct SoundAllocPool gAudioSessionPool; struct SoundAllocPool gAudioInitPool; @@ -33,6 +35,7 @@ u8 sAudioMemoryPad[0x20]; // probably two unused pools struct SoundAllocPool gSeqAndBankPool; struct SoundAllocPool gPersistentCommonPool; struct SoundAllocPool gTemporaryCommonPool; + struct SoundMultiPool gSeqLoadedPool; struct SoundMultiPool gBankLoadedPool; struct SoundMultiPool gUnusedLoadedPool; @@ -45,10 +48,108 @@ struct PoolSplit sTemporaryCommonPoolSplit; u8 gBankLoadStatus[0x40]; u8 gSeqLoadStatus[0x100]; +#ifdef VERSION_EU +volatile u8 gAudioResetStatus; +u8 gAudioResetPresetIdToLoad; +s32 gAudioResetFadeOutFramesLeft; +#endif + u8 gAudioUnusedBuffer[0x1000]; extern s32 gMaxAudioCmds; +#ifdef VERSION_EU +/** + * Assuming 'k' in [9, 24], + * Computes a newton's method step for f(x) = x^k - d + */ +f64 root_newton_step(f64 x, s32 k, f64 d) +{ + f64 deg2 = x * x; + f64 deg4 = deg2 * deg2; + f64 deg8 = deg4 * deg4; + s32 degree = k - 9; + f64 fx; + + f64 deriv = deg8; + if (degree & 1) { + deriv *= x; + } + if (degree & 2) { + deriv *= deg2; + } + if (degree & 4) { + deriv *= deg4; + } + if (degree & 8) { + deriv *= deg8; + } + fx = deriv * x - d; + deriv = k * deriv; + return x - fx / deriv; +} + +/** + * Assuming 'k' in [9, 24], + * Computes d ^ (1/k) + * + * @return the root, or 1.0 if d is 0 + */ +f64 kth_root(f64 d, s32 k) +{ + f64 root = 1.5; + f64 next; + f64 diff; + s32 i; + if (d == 0.0) { + root = 1.0; + } else { + for (i = 0; i < 64; i++) { + if (1) { + } + next = root_newton_step(root, k, d); + diff = next - root; + + if (diff < 0) { + diff = -diff; + } + + if (diff < 1e-07) { + root = next; + break; + } else { + root = next; + } + } + } + + return root; +} +#endif + +#ifdef VERSION_EU +void func_eu_802e1cd0(s32 UNUSED unused, s32 len) { + s32 i; + s32 step; + s32 d; + s32 k = len / 8; + + for (step = 0, i = 0; i < 0x400; step += 32, i++) { + d = step; + if (step == 0) { + d = 1; + } + + gLeftVolRampings[0][i] = kth_root( d, k - 1); + gRightVolRampings[0][i] = kth_root(1.0 / d, k - 1) * 65536.0; + gLeftVolRampings[1][i] = kth_root( d, k); + gRightVolRampings[1][i] = kth_root(1.0 / d, k) * 65536.0; + gLeftVolRampings[2][i] = kth_root( d, k + 1); + gRightVolRampings[2][i] = kth_root(1.0 / d, k + 1) * 65536.0; + } +} +#endif + void reset_bank_and_seq_load_status(void) { s32 i; @@ -67,7 +168,11 @@ void discard_bank(s32 bankId) { for (i = 0; i < gMaxSimultaneousNotes; i++) { struct Note *note = &gNotes[i]; +#ifdef VERSION_EU + if (note->noteSubEu.bankId == bankId) { +#else if (note->bankId == bankId) { +#endif if (note->priority >= NOTE_PRIORITY_MIN) { note->parentLayer->enabled = FALSE; note->parentLayer->finished = TRUE; @@ -84,15 +189,35 @@ void discard_sequence(s32 seqId) { for (i = 0; i < SEQUENCE_PLAYERS; i++) { if (gSequencePlayers[i].enabled && gSequencePlayers[i].seqId == seqId) { +#ifdef VERSION_EU + sequence_player_disable(&gSequencePlayers[i]); +#else sequence_player_disable(gSequencePlayers + i); +#endif } } } void *soundAlloc(struct SoundAllocPool *pool, u32 size) { +#ifdef VERSION_EU + u8 *start; + u8 *pos; + u32 alignedSize = ALIGN16(size); + + start = pool->cur; + if (start + alignedSize <= pool->start + pool->size) { + pool->cur += alignedSize; + for (pos = start; pos < pool->cur; pos++) { + *pos = 0; + } + } else { + return NULL; + } + return start; +#else + u8 *start; s32 last; s32 i; - u8 *start; if ((pool->cur + ALIGN16(size) <= pool->size + pool->start)) { start = pool->cur; @@ -104,8 +229,8 @@ void *soundAlloc(struct SoundAllocPool *pool, u32 size) { } else { return NULL; } - return start; +#endif } void sound_alloc_pool_init(struct SoundAllocPool *pool, void *memAddr, u32 size) { @@ -125,7 +250,11 @@ void temporary_pool_clear(struct TemporaryPool *temporary) { temporary->pool.cur = temporary->pool.start; temporary->nextSide = 0; temporary->entries[0].ptr = temporary->pool.start; +#ifdef VERSION_EU + temporary->entries[1].ptr = temporary->pool.start + temporary->pool.size; +#else temporary->entries[1].ptr = temporary->pool.size + temporary->pool.start; +#endif temporary->entries[0].id = -1; temporary->entries[1].id = -1; } @@ -174,8 +303,14 @@ void temporary_pools_init(struct PoolSplit *a) { temporary_pool_clear(&gUnusedLoadedPool.temporary); } +#ifndef VERSION_EU static void unused_803163D4() { } +#endif + +#if defined(VERSION_EU) && !defined(NON_MATCHING) +GLOBAL_ASM("asm/non_matchings/eu/audio/alloc_bank_or_seq.s") +#else #ifdef NON_MATCHING void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { @@ -332,10 +467,11 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg #else GLOBAL_ASM("asm/non_matchings/alloc_bank_or_seq.s") #endif +#endif void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) { u32 i; - void *ret; + UNUSED void *ret; struct TemporaryPool *temporary = &arg0->temporary; if (arg1 == 0) { @@ -357,19 +493,118 @@ void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) { } if (arg1 == 2) { +#ifdef VERSION_EU + return get_bank_or_seq(arg0, 0, id); +#else // Prevent tail call optimization by using a temporary. // (Did they compile with -Wo,-notail?) ret = get_bank_or_seq(arg0, 0, id); return ret; +#endif } return NULL; } } +#ifdef VERSION_EU +void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) { + s32 i; + f32 tmp[16]; + + tmp[0] = (f32) (arg1 * 262159.0f); + tmp[8] = (f32) (arg0 * 262159.0f); + tmp[1] = (f32) ((arg1 * arg0) * 262159.0f); + tmp[9] = (f32) (((arg0 * arg0) + arg1) * 262159.0f); + + for (i = 2; i < 8; i++) { + //! @bug they probably meant to store the value to tmp[i] and tmp[8 + i] + arg2[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1]; + arg2[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i]; + } + + for (i = 0; i < 16; i++) { + arg2[i] = tmp[i]; + } + + for (i = 0; i < 8; i++) { + } + + for (i = 8; i < 16; i += 4) { + } +} +#endif + +#ifdef VERSION_EU +void decrease_reverb_gain(void) { + s32 i; + for (i = 0; i < gNumSynthesisReverbs; i++) { + gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8; + } +} +#else void decrease_reverb_gain(void) { gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4; } +#endif +#ifdef VERSION_EU +s32 func_eu_802E2AA0(void) { + s32 i; + s32 j; + switch (gAudioResetStatus) { + case 5: + for (i = 0; i < SEQUENCE_PLAYERS; i++) { + sequence_player_disable(&gSequencePlayers[i]); + } + gAudioResetFadeOutFramesLeft = 4; + gAudioResetStatus--; + break; + case 4: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + decrease_reverb_gain(); + } else { + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if (gNotes[i].noteSubEu.enabled && gNotes[i].adsr.state != ADSR_STATE_DISABLED) { + gNotes[i].adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + gNotes[i].adsr.action |= ADSR_ACTION_RELEASE; + } + } + gAudioResetFadeOutFramesLeft = 16; + gAudioResetStatus--; + } + break; + case 3: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + decrease_reverb_gain(); + } else { + for (i = 0; i < NUMAIBUFFERS; i++) { + for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { + gAiBuffers[i][j] = 0; + } + } + gAudioResetFadeOutFramesLeft = 4; + gAudioResetStatus--; + } + break; + case 2: + if (gAudioResetFadeOutFramesLeft != 0) { + gAudioResetFadeOutFramesLeft--; + } else { + gAudioResetStatus--; + } + break; + case 1: + audio_reset_session(); + gAudioResetStatus = 0; + } + if (gAudioResetStatus < 3) { + return 0; + } + return 1; +} +#else /** * Waits until a specified number of audio frames have been created */ @@ -380,21 +615,37 @@ void wait_for_audio_frames(s32 frames) { // spin } } +#endif +#ifndef VERSION_EU void audio_reset_session(struct AudioSessionSettings *preset) { - s8 updatesPerFrame; +#else +void audio_reset_session(void) { + // TODO: verify compilation again and try to match better + struct AudioSessionSettingsEU *preset = &gAudioSessionPresets[gAudioResetPresetIdToLoad]; + struct ReverbSettingsEU *reverbSettings; +#endif s16 *mem; +#ifndef VERSION_EU + s8 updatesPerFrame; s32 reverbWindowSize; + s32 k; +#endif s32 i; s32 j; - s32 k; s32 persistentMem; s32 temporaryMem; s32 totalMem; s32 wantMisc; +#ifndef VERSION_EU s32 frames; s32 remainingDmas; +#endif +#ifdef VERSION_EU + struct SynthesisReverb *reverb; +#endif +#ifndef VERSION_EU if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { decrease_reverb_gain(); for (i = 0; i < gMaxSimultaneousNotes; i++) { @@ -445,13 +696,40 @@ void audio_reset_session(struct AudioSessionSettings *preset) { gCurrAudioFrameDmaCount = 0; for (j = 0; j < NUMAIBUFFERS; j++) { - for (k = 0; k < 0x500; k++) { + for (k = 0; k < (s32) (AIBUFFER_LEN / sizeof(s16)); k++) { gAiBuffers[j][k] = 0; } } } +#endif gSampleDmaNumListItems = 0; +#ifdef VERSION_EU + gAudioBufferParameters.frequency = preset->frequency; + gAudioBufferParameters.aiFrequency = osAiSetFrequency(gAudioBufferParameters.frequency); + gAudioBufferParameters.samplesPerFrameTarget = ALIGN16(gAudioBufferParameters.frequency / gRefreshRate); + gAudioBufferParameters.minAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget - 0x10; + gAudioBufferParameters.maxAiBufferLength = gAudioBufferParameters.samplesPerFrameTarget + 0x10; + gAudioBufferParameters.updatesPerFrame = (gAudioBufferParameters.samplesPerFrameTarget + 0x10) / 160 + 1; + gAudioBufferParameters.samplesPerUpdate = (gAudioBufferParameters.samplesPerFrameTarget / gAudioBufferParameters.updatesPerFrame) & 0xfff8; + gAudioBufferParameters.samplesPerUpdateMax = gAudioBufferParameters.samplesPerUpdate + 8; + gAudioBufferParameters.samplesPerUpdateMin = gAudioBufferParameters.samplesPerUpdate - 8; + gAudioBufferParameters.resampleRate = 32000.0f / FLOAT_CAST(gAudioBufferParameters.frequency); + gAudioBufferParameters.unkUpdatesPerFrameScaled = (3.0f / 1280.0f) / gAudioBufferParameters.updatesPerFrame; + gAudioBufferParameters.updatesPerFrameInv = 1.0f / gAudioBufferParameters.updatesPerFrame; + + gMaxSimultaneousNotes = preset->maxSimultaneousNotes; + gVolume = preset->volume; + gTempoInternalToExternal = (u32) (gAudioBufferParameters.updatesPerFrame * 2880000.0f / gTatumsPerBeat / D_EU_802298D0); + + gAudioBufferParameters.presetUnk4 = preset->unk1; + gAudioBufferParameters.samplesPerFrameTarget *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.maxAiBufferLength *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.minAiBufferLength *= gAudioBufferParameters.presetUnk4; + gAudioBufferParameters.updatesPerFrame *= gAudioBufferParameters.presetUnk4; + + gMaxAudioCmds = gMaxSimultaneousNotes * 0x10 * gAudioBufferParameters.updatesPerFrame + preset->numReverbs * 0x20 + 0x300; +#else reverbWindowSize = preset->reverbWindowSize; gAiFrequency = osAiSetFrequency(preset->frequency); gMaxSimultaneousNotes = preset->maxSimultaneousNotes; @@ -492,10 +770,16 @@ void audio_reset_session(struct AudioSessionSettings *preset) { #else gTempoInternalToExternal = (u32)(updatesPerFrame * 2880000.0f / gTatumsPerBeat / 16.713f); #endif - gMaxAudioCmds = gMaxSimultaneousNotes * 20 * updatesPerFrame + 320; +#endif + +#ifdef VERSION_EU + persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentSeqMem + preset->persistentBankMem); + temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporarySeqMem + preset->temporaryBankMem); +#else persistentMem = DOUBLE_SIZE_ON_64_BIT(preset->persistentBankMem + preset->persistentSeqMem); temporaryMem = DOUBLE_SIZE_ON_64_BIT(preset->temporaryBankMem + preset->temporarySeqMem); +#endif totalMem = persistentMem + temporaryMem; wantMisc = gAudioSessionPool.size - totalMem - 0x100; sSessionPoolSplit.wantSeq = wantMisc; @@ -514,14 +798,60 @@ void audio_reset_session(struct AudioSessionSettings *preset) { temporary_pools_init(&sTemporaryCommonPoolSplit); reset_bank_and_seq_load_status(); +#ifndef VERSION_EU for (j = 0; j < 2; j++) { gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64)); } +#endif gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note)); note_init_all(); init_note_free_list(); +#ifdef VERSION_EU + gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, (gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes) * sizeof(struct NoteSubEu)); + + for (j = 0; j != 2; j++) { + gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64)); + } + + for (j = 0; j < 4; j++) { + gSynthesisReverbs[j].useReverb = 0; + } + gNumSynthesisReverbs = preset->numReverbs; + for (j = 0; j < gNumSynthesisReverbs; j++) { + reverb = &gSynthesisReverbs[j]; + reverbSettings = &preset->reverbSettings[j]; + reverb->windowSize = reverbSettings->windowSize * 64; + reverb->downsampleRate = reverbSettings->downsampleRate; + reverb->reverbGain = reverbSettings->gain; + reverb->useReverb = 8; + reverb->ringBuffer.left = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); + reverb->ringBuffer.right = soundAlloc(&gNotesAndBuffersPool, reverb->windowSize * 2); + reverb->nextRingBufferPos = 0; + reverb->unkC = 0; + reverb->curFrame = 0; + reverb->bufSizePerChannel = reverb->windowSize; + reverb->framesLeftToIgnore = 2; + if (reverb->downsampleRate != 1) { + reverb->resampleFlags = A_INIT; + reverb->resampleRate = 0x8000 / reverb->downsampleRate; + reverb->resampleStateLeft = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->resampleStateRight = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->unk24 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + reverb->unk28 = soundAlloc(&gNotesAndBuffersPool, 16 * sizeof(s16)); + for (i = 0; i < gAudioBufferParameters.updatesPerFrame; i++) { + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + reverb->items[0][i].toDownsampleLeft = mem; + reverb->items[0][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); + reverb->items[1][i].toDownsampleLeft = mem; + reverb->items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); + } + } + } + +#else if (reverbWindowSize == 0) { gSynthesisReverb.useReverb = 0; } else { @@ -544,17 +874,26 @@ void audio_reset_session(struct AudioSessionSettings *preset) { for (i = 0; i < gAudioUpdatesPerFrame; i++) { mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); gSynthesisReverb.items[0][i].toDownsampleLeft = mem; - gSynthesisReverb.items[0][i].toDownsampleRight = mem + 0xA0; + gSynthesisReverb.items[0][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); mem = soundAlloc(&gNotesAndBuffersPool, DEFAULT_LEN_2CH); gSynthesisReverb.items[1][i].toDownsampleLeft = mem; - gSynthesisReverb.items[1][i].toDownsampleRight = mem + 0xA0; + gSynthesisReverb.items[1][i].toDownsampleRight = mem + DEFAULT_LEN_1CH / sizeof(s16); } } } +#endif init_sample_dma_buffers(gMaxSimultaneousNotes); + +#ifdef VERSION_EU + func_eu_802e1cd0(0, gAudioBufferParameters.samplesPerUpdate); +#endif + osWritebackDCacheAll(); + +#ifndef VERSION_EU if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; } +#endif } diff --git a/src/audio/memory.h b/src/audio/memory.h index 0786499..141c5d4 100644 --- a/src/audio/memory.h +++ b/src/audio/memory.h @@ -55,11 +55,17 @@ extern struct SoundMultiPool gSeqLoadedPool; extern struct SoundMultiPool gBankLoadedPool; extern u8 gBankLoadStatus[64]; extern u8 gSeqLoadStatus[256]; +extern volatile u8 gAudioResetStatus; +extern u8 gAudioResetPresetIdToLoad; void *soundAlloc(struct SoundAllocPool *pool, u32 size); void sound_init_main_pools(s32 sizeForAudioInitPool); void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id); void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 arg2); +#ifdef VERSION_EU +void audio_reset_session(void); +#else void audio_reset_session(struct AudioSessionSettings *preset); +#endif #endif /* AUDIO_MEMORY_H */ diff --git a/src/audio/playback.c b/src/audio/playback.c index 9856bc6..445b3ce 100644 --- a/src/audio/playback.c +++ b/src/audio/playback.c @@ -8,8 +8,166 @@ #include "playback.h" #include "synthesis.h" #include "effects.h" +#include "external.h" +#ifdef VERSION_EU +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb) { + struct NoteSubEu *sub = ¬e->noteSubEu; + f32 volRight, volLeft; + u16 unkMask = ~0x80; + + pan &= unkMask; + if (sub->stereoHeadsetEffects && gSoundMode == SOUND_MODE_HEADSET) { + s32 smallPanIndex = pan >> 3; + if (smallPanIndex > 0xf) { + smallPanIndex = 0xf; + } + + sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; + sub->headsetPanRight = gHeadsetPanQuantization[15 - smallPanIndex]; + sub->stereoStrongRight = FALSE; + sub->stereoStrongLeft = FALSE; + sub->usesHeadsetPanEffects = TRUE; + + volLeft = gHeadsetPanVolume[pan]; + volRight = gHeadsetPanVolume[127 - pan]; + } else if (sub->stereoHeadsetEffects && gSoundMode == SOUND_MODE_STEREO) { + u8 strongLeft = FALSE; + u8 strongRight = FALSE; + sub->headsetPanLeft = 0; + sub->headsetPanRight = 0; + sub->usesHeadsetPanEffects = FALSE; + + volLeft = gStereoPanVolume[pan]; + volRight = gStereoPanVolume[127 - pan]; + if (pan < 0x20) { + strongLeft = TRUE; + } else if (pan > 0x60) { + strongRight = TRUE; + } + + sub->stereoStrongRight = strongRight; + sub->stereoStrongLeft = strongLeft; + } else if (gSoundMode == SOUND_MODE_MONO) { + volLeft = 0.707f; + volRight = 0.707f; + } else { + volLeft = gDefaultPanVolume[pan]; + volRight = gDefaultPanVolume[127 - pan]; + } + + velocity = MAX(0.0f, velocity); + velocity = MIN(32767.f, velocity); + + sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5; + sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5; + + if (sub->reverbVol != reverb) { + sub->reverbVol = reverb; + sub->envMixerNeedsInit = TRUE; + return; + } + + if (sub->needsInit) { + sub->envMixerNeedsInit = TRUE; + } else { + sub->envMixerNeedsInit = FALSE; + } +} + +void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) { + f32 resamplingRate = 0.0f; + struct NoteSubEu *tempSub = ¬e->noteSubEu; + + if (resamplingRateInput < 0.0f) { + resamplingRateInput = 0.0f; + } + if (resamplingRateInput < 2.0f) { + tempSub->hasTwoAdpcmParts = 0; + + if (1.99996f < resamplingRateInput) { + resamplingRate = 1.99996f; + } else { + resamplingRate = resamplingRateInput; + } + + } else { + tempSub->hasTwoAdpcmParts = 1; + if (3.99992f < resamplingRateInput) { + resamplingRate = 1.99996f; + } else { + resamplingRate = resamplingRateInput * 0.5f; + } + } + note->noteSubEu.resamplingRateFixedPoint = (s32) (resamplingRate * 32768.0f); +} + +struct AudioBankSound *func_eu_802e4e5c(struct Instrument *instrument, s32 semitone) { + struct AudioBankSound *sound; + if (semitone < instrument->normalRangeLo) { + sound = &instrument->lowNotesSound; + } else if (semitone <= instrument->normalRangeHi) { + sound = &instrument->normalNotesSound; + } else { + sound = &instrument->highNotesSound; + } + return sound; +} + +struct Instrument *func_eu_802e4e98(s32 bankId, s32 instId) { + struct Instrument *inst; + + if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { + gAudioErrorFlags = bankId + 0x10000000; + return NULL; + } + + if (instId >= gCtlEntries[bankId].numInstruments) { + gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000; + return NULL; + } + + inst = gCtlEntries[bankId].instruments[instId]; + if (inst == NULL) { + gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000; + return inst; + } + + if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start + + gBankLoadedPool.persistent.pool.size)) + || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst + && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start + + gBankLoadedPool.temporary.pool.size))) { + return inst; + } + + gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000; + return NULL; +} + +struct Drum *func_eu_802e4fb8(s32 bankId, s32 drumId) { + struct Drum *drum; + if (drumId >= gCtlEntries[bankId].numDrums) { + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000; + return 0; + } + if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) { + return 0; + } + drum = gCtlEntries[bankId].drums[drumId]; + if (drum == NULL) { + gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000; + } + return drum; +} +#endif // VERSION_EU + +#ifdef VERSION_EU +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); +#else s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer); +#endif void note_init(struct Note *note) { if (note->parentLayer->adsr.releaseRate == 0) { @@ -18,24 +176,59 @@ void note_init(struct Note *note) { adsr_init(¬e->adsr, note->parentLayer->adsr.envelope, ¬e->adsrVolScale); } note->adsr.state = ADSR_STATE_INITIAL; +#ifdef VERSION_EU + note->noteSubEu = gDefaultNoteSub; +#else note_init_volume(note); note_enable(note); +#endif } +#ifdef VERSION_EU +#define note_disable2 note_disable +void note_disable(struct Note *note) { + if (note->noteSubEu.needsInit == TRUE) { + note->noteSubEu.needsInit = FALSE; + } else { + note_set_vel_pan_reverb(note, 0, 0x40, 0); + } + note->priority = NOTE_PRIORITY_DISABLED; + note->parentLayer = NO_LAYER; + note->prevParentLayer = NO_LAYER; + note->noteSubEu.enabled = FALSE; + note->noteSubEu.finished = FALSE; +} +#else void note_disable2(struct Note *note) { note_disable(note); } +#endif // VERSION_EU void process_notes(void) { f32 scale; f32 frequency; +#ifndef VERSION_EU u8 reverb; +#endif f32 velocity; +#ifndef VERSION_EU f32 pan; f32 cap; +#endif struct Note *note; +#ifdef VERSION_EU + struct NotePlaybackState *playbackState; + struct NoteSubEu *noteSubEu; + UNUSED u8 pad[12]; + u8 reverb; + UNUSED u8 pad3; + u8 pan; + u8 unk; +#endif struct NoteAttributes *attributes; +#ifndef VERSION_EU struct AudioListItem *it; +#endif s32 i; // Macro versions of audio_list_push_front and audio_list_remove @@ -52,6 +245,100 @@ void process_notes(void) { for (i = 0; i < gMaxSimultaneousNotes; i++) { note = &gNotes[i]; +#ifdef VERSION_EU + playbackState = (struct NotePlaybackState *) ¬e->priority; + if (note->parentLayer != NO_LAYER) { + if ((uintptr_t) playbackState->parentLayer < 0x7fffffffU) { + continue; + } + if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) { + goto c; + } else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) { + sequence_channel_disable(playbackState->parentLayer->seqChannel); + playbackState->priority = NOTE_PRIORITY_STOPPING; + continue; + } else if (playbackState->parentLayer->seqChannel->seqPlayer->muted) { + if ((playbackState->parentLayer->seqChannel->muteBehavior + & (MUTE_BEHAVIOR_STOP_SCRIPT | MUTE_BEHAVIOR_STOP_NOTES))) { + goto c; + } + } + goto d; + if (1) { + c: + seq_channel_layer_note_release(playbackState->parentLayer); + audio_list_remove(¬e->listItem); + audio_list_push_front(¬e->listItem.pool->decaying, ¬e->listItem); + playbackState->priority = NOTE_PRIORITY_STOPPING; + } + } else if (playbackState->priority >= NOTE_PRIORITY_MIN) { + continue; + } + d: + if (playbackState->priority != NOTE_PRIORITY_DISABLED) { + noteSubEu = ¬e->noteSubEu; + if (playbackState->priority == NOTE_PRIORITY_STOPPING || noteSubEu->finished) { + if (playbackState->adsr.state == ADSR_STATE_DISABLED || noteSubEu->finished) { + if (playbackState->wantedParentLayer != NO_LAYER) { + note_disable(note); + if (playbackState->wantedParentLayer->seqChannel != NULL) { + note_init_for_layer(note, playbackState->wantedParentLayer); + note_vibrato_init(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->active, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + // don't skip + } else { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + goto skip; + } + } else { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; + } + } + if (1) { + } + } else if (playbackState->adsr.state == ADSR_STATE_DISABLED) { + note_disable(note); + audio_list_remove(¬e->listItem); + audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem); + goto skip; + } + + scale = adsr_update(&playbackState->adsr); + note_vibrato_update(note); + attributes = &playbackState->attributes; + if (playbackState->priority == NOTE_PRIORITY_STOPPING) { + frequency = attributes->freqScale; + velocity = attributes->velocity; + pan = attributes->pan; + reverb = attributes->reverb; + if (1) { + } + unk = noteSubEu->unk1b234; + } else { + frequency = playbackState->parentLayer->noteFreqScale; + velocity = playbackState->parentLayer->noteVelocity; + pan = playbackState->parentLayer->notePan; + reverb = playbackState->parentLayer->seqChannel->reverb; + unk = playbackState->parentLayer->seqChannel->unk8 & 0x7; // bitfield? + } + + frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; + frequency *= gAudioBufferParameters.resampleRate; + velocity = velocity * scale * scale; + note_set_resampling_rate(note, frequency); + note_set_vel_pan_reverb(note, velocity, pan, reverb); + noteSubEu->unk1b234 = unk; + skip:; + } +#else if (note->priority != NOTE_PRIORITY_DISABLED) { if (note->priority == NOTE_PRIORITY_STOPPING || note->finished) { if (note->adsrVolScale == 0 || note->finished) { @@ -116,6 +403,7 @@ void process_notes(void) { note_set_vel_pan_reverb(note, velocity, pan, reverb); continue; } +#endif } #undef PREPEND #undef POP @@ -132,15 +420,23 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa note = seqLayer->note; attributes = ¬e->attributes; +#ifndef VERSION_EU if (seqLayer->seqChannel != NULL && seqLayer->seqChannel->noteAllocPolicy == 0) { seqLayer->note = NULL; } +#endif if (note->wantedParentLayer == seqLayer) { note->wantedParentLayer = NO_LAYER; } if (note->parentLayer != seqLayer) { +#ifdef VERSION_EU + if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) { + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; + note->adsr.action |= ADSR_ACTION_RELEASE; + } +#endif return; } @@ -156,16 +452,29 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa note->prevParentLayer = note->parentLayer; note->parentLayer = NO_LAYER; if (target == ADSR_STATE_RELEASE) { +#ifdef VERSION_EU + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; +#else note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; +#endif note->adsr.action |= ADSR_ACTION_RELEASE; } else { note->adsr.action |= ADSR_ACTION_DECAY; +#ifdef VERSION_EU + if (seqLayer->adsr.releaseRate == 0) { + note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; + } else { + note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * gAudioBufferParameters.unkUpdatesPerFrameScaled; + } + note->adsr.sustain = (FLOAT_CAST(seqLayer->seqChannel->adsr.sustain) * note->adsr.current) / 256.0f; +#else if (seqLayer->adsr.releaseRate == 0) { note->adsr.fadeOutVel = seqLayer->seqChannel->adsr.releaseRate * 24; } else { note->adsr.fadeOutVel = seqLayer->adsr.releaseRate * 24; } note->adsr.sustain = (note->adsr.current * seqLayer->seqChannel->adsr.sustain) / 0x10000; +#endif } } @@ -183,6 +492,43 @@ void seq_channel_layer_note_release(struct SequenceChannelLayer *seqLayer) { seq_channel_layer_decay_release_internal(seqLayer, ADSR_STATE_RELEASE); } + +#ifdef VERSION_EU +s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer, s32 waveId) { + f32 freqScale; + f32 ratio; + u8 sampleCountIndex; + + if (waveId < 128) { + waveId = 128; + } + + freqScale = seqLayer->freqScale; + if (seqLayer->portamento.mode != 0 && 0.0f < seqLayer->portamento.extent) { + freqScale *= (seqLayer->portamento.extent + 1.0f); + } + if (freqScale < 1.0f) { + sampleCountIndex = 0; + ratio = 1.0465f; + } else if (freqScale < 2.0f) { + sampleCountIndex = 1; + ratio = 0.52325f; + } else if (freqScale < 4.0f) { + sampleCountIndex = 2; + ratio = 0.26263f; + } else { + sampleCountIndex = 3; + ratio = 0.13081f; + } + seqLayer->freqScale *= ratio; + note->waveId = waveId; + note->sampleCountIndex = sampleCountIndex; + + note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64]; + + return sampleCountIndex; +} +#else void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { s32 i; s32 j; @@ -237,8 +583,20 @@ void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLay osWritebackDCache(note->synthesisBuffers->samples, sizeof(note->synthesisBuffers->samples)); } +#endif void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { +#ifdef VERSION_EU + s32 sampleCountIndex; + s32 waveSampleCountIndex; + s32 waveId = seqLayer->euUnk1; + if (waveId == 0xff) { + waveId = seqLayer->seqChannel->instOrWave; + } + sampleCountIndex = note->sampleCountIndex; + waveSampleCountIndex = build_synthetic_wave(note, seqLayer, waveId); + note->synthesisState.samplePosInt = note->synthesisState.samplePosInt * euUnknownData_8030194c[waveSampleCountIndex] / euUnknownData_8030194c[sampleCountIndex]; +#else s32 sampleCount = note->sampleCount; build_synthetic_wave(note, seqLayer); if (sampleCount != 0) { @@ -246,6 +604,7 @@ void init_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye } else { note->samplePosInt = 0; } +#endif } void init_note_list(struct AudioListItem *list) { @@ -281,7 +640,7 @@ void note_pool_clear(struct NotePool *pool) { struct AudioListItem *source; struct AudioListItem *cur; struct AudioListItem *dest; - s32 j; + UNUSED s32 j; // unused in EU for (i = 0; i < 4; i++) { switch (i) { @@ -306,6 +665,16 @@ void note_pool_clear(struct NotePool *pool) { break; } +#ifdef VERSION_EU + for (;;) { + cur = source->next; + if (cur == source || cur == NULL) { + break; + } + audio_list_remove(cur); + audio_list_push_back(dest, cur); + } +#else j = 0; do { cur = source->next; @@ -316,6 +685,7 @@ void note_pool_clear(struct NotePool *pool) { audio_list_push_back(dest, cur); j++; } while (j <= gMaxSimultaneousNotes); +#endif } } @@ -402,14 +772,60 @@ struct Note *pop_node_with_value_less_equal(struct AudioListItem *list, s32 limi } } +#ifdef VERSION_EU + if (best == NULL) { + return NULL; + } + + if (limit <= ((struct Note *) best->u.value)->priority) { + return NULL; + } +#else if (limit < ((struct Note *) best->u.value)->priority) { return NULL; } +#endif audio_list_remove(best); return best->u.value; } +#if defined(VERSION_EU) +void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { + UNUSED s32 pad[4]; + s16 instId; + struct NoteSubEu *sub = ¬e->noteSubEu; + + note->prevParentLayer = NO_LAYER; + note->parentLayer = seqLayer; + note->priority = seqLayer->seqChannel->notePriority; + seqLayer->unkEu0b4 = TRUE; + seqLayer->status = SOUND_LOAD_STATUS_DISCARDABLE; // "loaded" + seqLayer->note = note; + seqLayer->seqChannel->noteUnused = note; + seqLayer->seqChannel->layerUnused = seqLayer; + seqLayer->noteVelocity = 0.0f; + note_init(note); + instId = seqLayer->euUnk1; + if (instId == 0xff) { + instId = seqLayer->seqChannel->instOrWave; + } + sub->sound.audioBankSound = seqLayer->sound; + + if (instId >= 0x80) { + sub->isSyntheticWave = TRUE; + } else { + sub->isSyntheticWave = FALSE; + } + + if (sub->isSyntheticWave) { + build_synthetic_wave(note, seqLayer, instId); + } + sub->bankId = seqLayer->seqChannel->bankId; + sub->stereoHeadsetEffects = seqLayer->seqChannel->stereoHeadsetEffects; + sub->unk1b567 = seqLayer->seqChannel->reverbIndex & 3; +} +#else s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer) { note->prevParentLayer = NO_LAYER; note->parentLayer = seqLayer; @@ -431,6 +847,7 @@ s32 note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLayer note_init(note); return FALSE; } +#endif void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { seq_channel_layer_note_release(note->parentLayer); @@ -440,18 +857,25 @@ void func_80319728(struct Note *note, struct SequenceChannelLayer *seqLayer) { void note_release_and_take_ownership(struct Note *note, struct SequenceChannelLayer *seqLayer) { note->wantedParentLayer = seqLayer; note->priority = NOTE_PRIORITY_STOPPING; +#ifdef VERSION_EU + note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; +#else note->adsr.fadeOutVel = 0x8000 / gAudioUpdatesPerFrame; +#endif note->adsr.action |= ADSR_ACTION_RELEASE; } struct Note *alloc_note_from_disabled(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { struct Note *note = audio_list_pop_back(&pool->disabled); if (note != NULL) { +#ifdef VERSION_EU + note_init_for_layer(note, seqLayer); +#else if (note_init_for_layer(note, seqLayer) == TRUE) { audio_list_push_front(&gNoteFreeLists.disabled, ¬e->listItem); return NULL; } - +#endif audio_list_push_front(&pool->active, ¬e->listItem); } return note; @@ -482,10 +906,18 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { if (policy & NOTE_ALLOC_LAYER) { ret = seqLayer->note; - if (ret != NULL && ret->prevParentLayer == seqLayer) { + if (ret != NULL && ret->prevParentLayer == seqLayer +#ifdef VERSION_EU + && ret->wantedParentLayer == NO_LAYER +#endif + ) { note_release_and_take_ownership(ret, seqLayer); audio_list_remove(&ret->listItem); +#ifdef VERSION_EU + audio_list_push_back(&ret->listItem.pool->releasing, &ret->listItem); +#else audio_list_push_back(&gNoteFreeLists.releasing, &ret->listItem); +#endif return ret; } } @@ -538,6 +970,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) { return ret; } +#ifndef VERSION_EU void reclaim_notes(void) { struct Note *note; s32 i; @@ -574,6 +1007,8 @@ void reclaim_notes(void) { } } } +#endif + void note_init_all(void) { struct Note *note; @@ -581,14 +1016,21 @@ void note_init_all(void) { for (i = 0; i < gMaxSimultaneousNotes; i++) { note = &gNotes[i]; +#ifdef VERSION_EU + note->noteSubEu = gZeroNoteSub; +#else note->enabled = FALSE; note->stereoStrongRight = FALSE; note->stereoStrongLeft = FALSE; note->stereoHeadsetEffects = FALSE; +#endif note->priority = NOTE_PRIORITY_DISABLED; note->parentLayer = NO_LAYER; note->wantedParentLayer = NO_LAYER; note->prevParentLayer = NO_LAYER; +#ifdef VERSION_EU + note->waveId = 0; +#else note->reverb = 0; note->usesHeadsetPanEffects = FALSE; note->sampleCount = 0; @@ -597,6 +1039,7 @@ void note_init_all(void) { note->targetVolRight = 0; note->frequency = 0.0f; note->unused1 = 0x3f; +#endif note->attributes.velocity = 0.0f; note->adsrVolScale = 0; note->adsr.state = ADSR_STATE_DISABLED; @@ -604,6 +1047,10 @@ void note_init_all(void) { note->vibratoState.active = FALSE; note->portamento.cur = 0.0f; note->portamento.speed = 0.0f; +#ifdef VERSION_EU + note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); +#else note->synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers)); +#endif } } diff --git a/src/audio/playback.h b/src/audio/playback.h index 7cd1782..b69665d 100644 --- a/src/audio/playback.h +++ b/src/audio/playback.h @@ -28,5 +28,15 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer); void reclaim_notes(void); void note_init_all(void); +#ifdef VERSION_EU +struct AudioBankSound *func_eu_802e4e5c(struct Instrument *instrument, s32 semitone); +struct Drum *func_eu_802e4fb8(s32 bankId, s32 drumId); +void note_init_volume(struct Note *note); +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb); +void note_set_frequency(struct Note *note, f32 frequency); +void note_enable(struct Note *note); +void note_disable(struct Note *note); +#endif + #endif /* _AUDIO_PLAYBACK_H */ diff --git a/src/audio/port_eu.c b/src/audio/port_eu.c new file mode 100644 index 0000000..539f66b --- /dev/null +++ b/src/audio/port_eu.c @@ -0,0 +1,326 @@ +#include +#include "internal.h" +#include "load.h" +#include "data.h" +#include "seqplayer.h" +#include "synthesis.h" + +#ifdef VERSION_EU + +#ifdef __sgi +#define stubbed_printf +#else +#define stubbed_printf(...) +#endif + +#define SAMPLES_TO_OVERPRODUCE 0x10 +#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40 + +#ifdef VERSION_JP +typedef u16 FadeT; +#else +typedef s32 FadeT; +#endif + +extern volatile u8 gAudioResetStatus; +extern u8 gAudioResetPresetIdToLoad; +extern OSMesgQueue *OSMesgQueues[]; +extern struct EuAudioCmd sAudioCmd[0x100]; + +void func_8031D690(s32 player, FadeT fadeInTime); +void sequence_player_fade_out_internal(s32 player, FadeT fadeOutTime); +void func_802ad668(void); +void decrease_sample_dma_ttls(void); +s32 func_eu_802E2AA0(void); +void func_802ad7ec(u32); + +struct SPTask *create_next_audio_frame_task(void) { + u32 samplesRemainingInAI; + s32 writtenCmds; + s32 index; + OSTask_t *task; + s32 flags; + u16 *currAiBuffer; + s32 oldDmaCount; + OSMesg sp30; + OSMesg sp2C; + + gAudioFrameCount++; + if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) { + stubbed_printf("DAC:Lost 1 Frame.\n"); + return NULL; + } + + osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0); + + gAudioTaskIndex ^= 1; + gCurrAiBufferIndex++; + gCurrAiBufferIndex %= NUMAIBUFFERS; + index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS; + samplesRemainingInAI = osAiGetLength() / 4; + + if (gAiBufferLengths[index] != 0) { + osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4); + } + + oldDmaCount = gCurrAudioFrameDmaCount; + if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) { + stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount); + } + gCurrAudioFrameDmaCount = 0; + + decrease_sample_dma_ttls(); + if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) { + gAudioResetPresetIdToLoad = (u8) (s32) sp30; + gAudioResetStatus = 5; + } + + if (gAudioResetStatus != 0) { + if (func_eu_802E2AA0() == 0) { + if (gAudioResetStatus == 0) { + osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK); + } + return NULL; + } + } + + gAudioTask = &gAudioTasks[gAudioTaskIndex]; + gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex]; + index = gCurrAiBufferIndex; + currAiBuffer = gAiBuffers[index]; + + gAiBufferLengths[index] = ((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI + + EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE; + if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) { + gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength; + } + if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) { + gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength; + } + + if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) { + func_802ad7ec((u32) sp2C); + } + + flags = 0; + gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]); + gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount); + gAudioRandom = gAudioRandom + writtenCmds / 8; + + index = gAudioTaskIndex; + gAudioTask->msgqueue = NULL; + gAudioTask->msg = NULL; + + task = &gAudioTask->task.t; + task->type = M_AUDTASK; + task->flags = flags; + task->ucode_boot = rspF3DBootStart; + task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart; + task->ucode = rspAspMainStart; + task->ucode_data = rspAspMainDataStart; + task->ucode_size = 0x800; // (this size is ignored) + task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64); + task->dram_stack = NULL; + task->dram_stack_size = 0; + task->output_buff = NULL; + task->output_buff_size = NULL; + task->data_ptr = gAudioCmdBuffers[index]; + task->data_size = writtenCmds * sizeof(u64); + task->yield_data_ptr = NULL; + task->yield_data_size = 0; + return gAudioTask; +} + +void eu_process_audio_cmd(struct EuAudioCmd *cmd) { + s32 i; + + switch (cmd->u.s.op) { + case 0x81: + preload_sequence(cmd->u.s.arg2, 3); + break; + + case 0x82: + case 0x88: + // load_sequence(arg1, arg2, 0); + load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3); + func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32); + break; + + case 0x83: + if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) { + if (cmd->u2.as_s32 == 0) { + sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]); + } + else { + sequence_player_fade_out_internal(cmd->u.s.arg1, cmd->u2.as_s32); + } + } + break; + + case 0xf0: + gSoundMode = cmd->u2.as_s32; + break; + + case 0xf1: + for (i = 0; i < 4; i++) { + gSequencePlayers[i].muted = TRUE; + gSequencePlayers[i].unk_eu = TRUE; + } + break; + + case 0xf2: + for (i = 0; i < 4; i++) { + gSequencePlayers[i].muted = FALSE; + gSequencePlayers[i].unk_eu = TRUE; + } + break; + } +} + +const char undefportcmd[] = "Undefined Port Command %d\n"; + +extern OSMesgQueue *OSMesgQueues[]; +extern u8 D_EU_80302010; +extern u8 D_EU_80302014; +extern OSMesg OSMesg0; +extern OSMesg OSMesg1; +extern OSMesg OSMesg2; +extern OSMesg OSMesg3; + +void sequence_player_fade_out_internal(s32 player, FadeT fadeOutTime) { + if (fadeOutTime == 0) { + fadeOutTime = 1; + } + gSequencePlayers[player].fadeVelocity = -(gSequencePlayers[player].fadeVolume / fadeOutTime); + gSequencePlayers[player].state = 2; + gSequencePlayers[player].fadeTimer = fadeOutTime; + +} + +void func_8031D690(s32 player, FadeT fadeInTime) { + if (fadeInTime != 0) { + gSequencePlayers[player].state = 1; + gSequencePlayers[player].fadeTimerUnkEu = fadeInTime; + gSequencePlayers[player].fadeTimer = fadeInTime; + gSequencePlayers[player].fadeVolume = 0.0f; + gSequencePlayers[player].fadeVelocity = 0.0f; + } +} + +void func_802ad668(void) { + D_EU_80302010 = 0; + D_EU_80302014 = 0; + osCreateMesgQueue(OSMesgQueues[0], &OSMesg0, 1); + osCreateMesgQueue(OSMesgQueues[1], &OSMesg1, 4); + osCreateMesgQueue(OSMesgQueues[2], &OSMesg2, 1); + osCreateMesgQueue(OSMesgQueues[3], &OSMesg3, 1); +} + +void func_802ad6f0(s32 arg0, s32 *arg1) { + struct EuAudioCmd *cmd = &sAudioCmd[D_EU_80302010 & 0xff]; + cmd->u.first = arg0; + cmd->u2.as_u32 = *arg1; + D_EU_80302010++; +} + +void func_802ad728(u32 arg0, f32 arg1) { + func_802ad6f0(arg0, (s32*) &arg1); +} + +void func_802ad74c(u32 arg0, u32 arg1) { + func_802ad6f0(arg0, (s32*) &arg1); +} + +void func_802ad770(u32 arg0, s8 arg1) { + s32 sp1C = arg1 << 24; + func_802ad6f0(arg0, &sp1C); +} + +void func_802ad7a0(void) { + osSendMesg(OSMesgQueues[1], + (OSMesg)(u32)((D_EU_80302014 & 0xff) << 8 | (D_EU_80302010 & 0xff)), + OS_MESG_NOBLOCK); + D_EU_80302014 = D_EU_80302010; +} + +void func_802ad7ec(u32 arg0) { + struct EuAudioCmd *cmd; + struct SequencePlayer *seqPlayer; + struct SequenceChannel *chan; + u8 end = arg0 & 0xff; + u8 i = (arg0 >> 8) & 0xff; + + for (;;) { + if (i == end) break; + cmd = &sAudioCmd[i++ & 0xff]; + + if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) { + seqPlayer = &gSequencePlayers[cmd->u.s.arg1]; + if ((cmd->u.s.op & 0x80) != 0) { + eu_process_audio_cmd(cmd); + } + else if ((cmd->u.s.op & 0x40) != 0) { + switch (cmd->u.s.op) { + case 0x41: + seqPlayer->unkEu28 = cmd->u2.as_f32; + seqPlayer->unk_eu = TRUE; + break; + + case 0x47: + seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT; + break; + + case 0x48: + seqPlayer->transposition = cmd->u2.as_s8; + break; + + case 0x46: + seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8; + break; + } + } + else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) { + chan = seqPlayer->channels[cmd->u.s.arg2]; + if (IS_SEQUENCE_CHANNEL_VALID(chan)) + { + switch (cmd->u.s.op) { + case 1: + chan->volumeScale = cmd->u2.as_f32; + chan->unk1.as_bitfields.unk0b40 = TRUE; + break; + case 2: + chan->volume = cmd->u2.as_f32; + chan->unk1.as_bitfields.unk0b40 = TRUE; + break; + case 3: + chan->unk9 = cmd->u2.as_s8; + chan->unk1.as_bitfields.unk0b20 = TRUE; + break; + case 4: + chan->freqScale = cmd->u2.as_f32; + chan->unk1.as_bitfields.unk0b80 = TRUE; + break; + case 5: + chan->reverb = cmd->u2.as_s8; + break; + case 6: + if (cmd->u.s.arg3 < 8) { + chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8; + } + break; + case 8: + chan->stopSomething2 = cmd->u2.as_s8; + } + } + } + } + + cmd->u.s.op = 0; + } +} + +void func_802ada64(void) { + func_802ad668(); +} + +#endif diff --git a/src/audio/seqplayer.c b/src/audio/seqplayer.c index 7d2e177..c6fb651 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/seqplayer.c @@ -18,6 +18,8 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer); void sequence_channel_process_script(struct SequenceChannel *seqChannel); +u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, + struct AdsrSettings *adsr); void sequence_channel_init(struct SequenceChannel *seqChannel) { s32 i; @@ -30,6 +32,15 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->stereoHeadsetEffects = FALSE; seqChannel->transposition = 0; seqChannel->largeNotes = FALSE; +#ifdef VERSION_EU + seqChannel->unk8 = 0; + seqChannel->unk1.as_u8 = 0xff; + seqChannel->scriptState.depth = 0; + seqChannel->unk9 = 0x40; + seqChannel->unkA = 0x80; + seqChannel->noteUnused = NULL; + seqChannel->reverbIndex = 0; +#else seqChannel->scriptState.depth = 0; seqChannel->volume = 1.0f; seqChannel->volumeScale = 1.0f; @@ -37,13 +48,16 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->pan = 0.5f; seqChannel->panChannelWeight = 1.0f; seqChannel->noteUnused = NULL; +#endif seqChannel->reverb = 0; seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; seqChannel->delay = 0; seqChannel->adsr.envelope = gDefaultEnvelope; seqChannel->adsr.releaseRate = 0x20; seqChannel->adsr.sustain = 0; +#ifndef VERSION_EU seqChannel->updatesPerFrameUnused = gAudioUpdatesPerFrame; +#endif seqChannel->vibratoRateTarget = 0x800; seqChannel->vibratoRateStart = 0x800; seqChannel->vibratoExtentTarget = 0; @@ -51,6 +65,11 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->vibratoRateChangeDelay = 0; seqChannel->vibratoExtentChangeDelay = 0; seqChannel->vibratoDelay = 0; +#ifdef VERSION_EU + seqChannel->volume = 1.0f; + seqChannel->volumeScale = 1.0f; + seqChannel->freqScale = 1.0f; +#endif for (i = 0; i < 8; i++) { seqChannel->soundScriptIO[i] = -1; @@ -64,6 +83,9 @@ s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { struct SequenceChannelLayer *layer; if (seqChannel->layers[layerIndex] == NULL) { +#ifdef VERSION_EU + struct SequenceChannelLayer *layer; +#endif layer = audio_list_pop_back(&gLayerFreeList); seqChannel->layers[layerIndex] = layer; if (layer == NULL) { @@ -82,18 +104,30 @@ s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { layer->stopSomething = FALSE; layer->continuousNotes = FALSE; layer->finished = FALSE; +#ifdef VERSION_EU + layer->unkEu0b2 = FALSE; +#endif layer->portamento.mode = 0; layer->scriptState.depth = 0; layer->status = SOUND_LOAD_STATUS_NOT_LOADED; layer->noteDuration = 0x80; +#ifdef VERSION_EU + layer->euUnk5 = 0x40; +#endif layer->transposition = 0; layer->delay = 0; layer->duration = 0; layer->delayUnused = 0; layer->note = NULL; layer->instrument = NULL; +#ifdef VERSION_EU + layer->freqScale = 1.0f; + layer->velocitySquare = 0.0f; + layer->euUnk1 = 0xff; +#else layer->velocitySquare = 0.0f; layer->pan = 0.5f; +#endif return 0; } @@ -107,13 +141,13 @@ void seq_channel_layer_disable(struct SequenceChannelLayer *layer) { void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) { struct SequenceChannelLayer *layer = seqChannel->layers[layerIndex]; - struct AudioListItem *item; if (layer != NULL) { - // push to end of list - item = &layer->listItem; +#ifdef VERSION_EU + audio_list_push_back(&gLayerFreeList, &layer->listItem); +#else + struct AudioListItem *item = &layer->listItem; if (item->prev == NULL) { - // TODO: probably a macro? gLayerFreeList.prev->next = item; item->prev = gLayerFreeList.prev; item->next = &gLayerFreeList; @@ -121,6 +155,7 @@ void seq_channel_layer_free(struct SequenceChannel *seqChannel, s32 layerIndex) gLayerFreeList.u.count++; item->pool = gLayerFreeList.pool; } +#endif seq_channel_layer_disable(layer); seqChannel->layers[layerIndex] = NULL; } @@ -141,7 +176,11 @@ struct SequenceChannel *allocate_sequence_channel(void) { s32 i; for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { if (gSequenceChannels[i].seqPlayer == NULL) { +#ifdef VERSION_EU + return &gSequenceChannels[i]; +#else return gSequenceChannels + i; +#endif } } return &gSequenceChannelNone; @@ -171,7 +210,11 @@ void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channel seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; } } +#ifdef VERSION_EU + channelBits = channelBits >> 1; +#else channelBits >>= 1; +#endif } } @@ -187,18 +230,37 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan sequence_channel_disable(seqChannel); seqChannel->seqPlayer = NULL; } +#ifdef VERSION_EU + if (0) {} +#endif seqPlayer->channels[i] = &gSequenceChannelNone; } } +#ifdef VERSION_EU + channelBits = channelBits >> 1; +#else channelBits >>= 1; +#endif } } +#if defined(VERSION_EU) && !defined(NON_MATCHING) +GLOBAL_ASM("asm/non_matchings/eu/audio/sequence_channel_enable.s") +#else void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *arg2) { struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; s32 i; +#ifdef VERSION_EU + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + // not matching exactly, but this is the logic at least (stubbed printfs?) + if (seqPlayer == &gSequencePlayers[0]) { + } else if (seqPlayer == &gSequencePlayers[1]) { + } + } else { +#else if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) != FALSE) { +#endif seqChannel->enabled = TRUE; seqChannel->finished = FALSE; seqChannel->scriptState.depth = 0; @@ -211,6 +273,7 @@ void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, } } } +#endif void sequence_player_disable(struct SequencePlayer *seqPlayer) { sequence_player_disable_channels(seqPlayer, 0xffff); @@ -229,11 +292,19 @@ void sequence_player_disable(struct SequencePlayer *seqPlayer) { // (Note that if this is called from alloc_bank_or_seq, the side will get swapped // later in that function. Thus, we signal that we want to load into the slot // of the bank that we no longer need.) +#ifdef VERSION_EU + if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[0].id) { + gBankLoadedPool.temporary.nextSide = 1; + } else if (seqPlayer->defaultBank[0] == gBankLoadedPool.temporary.entries[1].id) { + gBankLoadedPool.temporary.nextSide = 0; + } +#else if (gBankLoadedPool.temporary.entries[0].id == seqPlayer->defaultBank[0]) { gBankLoadedPool.temporary.nextSide = 1; } else if (gBankLoadedPool.temporary.entries[1].id == seqPlayer->defaultBank[0]) { gBankLoadedPool.temporary.nextSide = 0; } +#endif } /** @@ -274,15 +345,23 @@ void init_layer_freelist(void) { gLayerFreeList.pool = NULL; for (i = 0; i < ARRAY_COUNT(gSequenceLayers); i++) { +#ifdef VERSION_EU + gSequenceLayers[i].listItem.u.value = &gSequenceLayers[i]; +#else gSequenceLayers[i].listItem.u.value = gSequenceLayers + i; +#endif gSequenceLayers[i].listItem.prev = NULL; audio_list_push_back(&gLayerFreeList, &gSequenceLayers[i].listItem); } } u8 m64_read_u8(struct M64ScriptState *state) { +#ifdef VERSION_EU + return *(state->pc++); +#else u8 *midiArg = state->pc++; return *midiArg; +#endif } s16 m64_read_s16(struct M64ScriptState *state) { @@ -305,24 +384,43 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { struct SequencePlayer *seqPlayer; // sp5C, t4 struct SequenceChannel *seqChannel; // sp58, t5 struct M64ScriptState *state; // v0 +#ifndef VERSION_EU struct AdsrSettings *adsr; // v0 +#endif struct Portamento *portamento; // v0 +#ifndef VERSION_EU struct Instrument **instOut; // a1 struct Instrument *inst; // a0 +#endif struct AudioBankSound *sound; // v0 struct Instrument *instrument; // v1 struct Drum *drum; +#ifdef VERSION_EU + s32 sameSound; +#else u8 sameSound; // sp3F +#endif u8 cmd; // a0 u8 allocNewNote; // sp3D, t0 u8 loBits; u16 sp3A; // t2, a0, a1 s32 vel; // sp30, t3 +#ifdef VERSION_EU + f32 velFloat; +#endif f32 freqScale; // sp28, f0 +#ifndef VERSION_EU f32 sp24; +#endif +#ifdef VERSION_EU + s8 temp8; +#else u8 temp8; +#endif +#ifndef VERSION_EU u8 *old; u8 *old2; +#endif u8 semitone; // v0 u8 usedSemitone; // a1 f32 temp_f12; @@ -332,7 +430,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { s32 cmdBase; // t1 u8 temp_a0_6; u8 portamentoTargetNote; // t7 +#ifndef VERSION_EU s32 bankId; // a3 +#endif u8 instId; // v0 s32 cmdSemitone; // v1 f32 tuning; // f0 @@ -363,11 +463,19 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { seqChannel = layer->seqChannel; seqPlayer = seqChannel->seqPlayer; +#ifdef VERSION_EU + layer->unkEu0b4 = TRUE; +#endif + for (;;) { // (Moving state outside the loop improves initial regalloc, but is wrong) state = &layer->scriptState; +#ifdef VERSION_EU + cmd = m64_read_u8(state); +#else old2 = state->pc++; cmd = *old2; +#endif if (cmd <= 0xc0) { break; } @@ -388,18 +496,28 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { // it's inlining m64_read_s16, but it lacks a s16 cast. // Maybe they did macro-based inlining since there are more layers // than channels or sequences, making the code hotter. +#ifdef VERSION_EU + sp3A = m64_read_s16(state); + state->stack[state->depth++] = state->pc; +#else sp3A = *(state->pc++) << 8; sp3A = *(state->pc++) | sp3A; state->depth++; state->stack[state->depth - 1] = state->pc; +#endif state->pc = seqPlayer->seqData + sp3A; break; case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) +#ifdef VERSION_EU + state->remLoopIters[state->depth] = m64_read_u8(state); + state->stack[state->depth++] = state->pc; +#else old = state->pc++; state->remLoopIters[state->depth] = *old; state->depth++; state->stack[state->depth - 1] = state->pc; +#endif break; case 0xf7: // layer_loopend @@ -412,18 +530,33 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { break; case 0xfb: // layer_jump +#ifdef VERSION_EU + sp3A = m64_read_s16(state); +#else sp3A = *(state->pc++) << 8; sp3A = *(state->pc++) | sp3A; +#endif state->pc = seqPlayer->seqData + sp3A; break; +#ifdef VERSION_EU + case 0xf4: + temp8 = m64_read_u8(state); + state->pc += temp8; + break; +#endif + case 0xc1: // layer_setshortnotevelocity case 0xca: // layer_setpan temp_a0_5 = *(state->pc++); if (cmd == 0xc1) { layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); } else { +#ifdef VERSION_EU + layer->euUnk5 = temp_a0_5; +#else layer->pan = (f32) temp_a0_5 / US_FLOAT(128.0); +#endif } break; @@ -439,12 +572,20 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { case 0xc4: // layer_somethingon case 0xc5: // layer_somethingoff +#ifdef VERSION_EU + if (cmd == 0xc4) { + layer->continuousNotes = TRUE; + } else { + layer->continuousNotes = FALSE; + } +#else if (cmd == 0xc4) { temp8 = TRUE; } else { temp8 = FALSE; } layer->continuousNotes = temp8; +#endif seq_channel_layer_note_decay(layer); break; @@ -453,17 +594,25 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { // (it's falsely preserved until after the loop), but maybe there's // also inlining going on, with sp3A as a temp variable being used // for no good reason? Or it could just be a macro. +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif layer->shortNoteDefaultPlayPercentage = sp3A; break; case 0xc6: // layer_setinstr +#ifdef VERSION_EU + instId = m64_read_u8(state); +#else old = state->pc++; instId = *old; +#endif // The rest of this case is identical to // if (instId < 0x7f) { // get_instrument(seqChannel, instId, &layer->instrument, &layer->adsr); @@ -473,9 +622,30 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { // which I think wouldn't be the case with __inline (maybe if they // both inline a common helper?) if (instId >= 0x7f) { +#ifdef VERSION_EU + if (instId == 0x7f) { + layer->euUnk1 = 0; + } else { + layer->euUnk1 = instId; + layer->instrument = NULL; + } + if (instId != 0xff) { + break; + } + layer->adsr.releaseRate = 0; +#endif break; } +#ifdef VERSION_EU + instId = get_instrument(seqChannel, instId, &layer->instrument, &layer->adsr); + layer->euUnk1 = instId; + if (instId == 0) { + layer->euUnk1 = 0xff; + } + //layer->euUnk1 = instId == 0 ? 0xff : instId; + break; +#else bankId = seqChannel->bankId; // maybe a temp, to match get_instrument if (instId >= gCtlEntries[bankId].numInstruments) { instId = gCtlEntries[bankId].numInstruments; @@ -512,14 +682,21 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { gAudioErrorFlags = instId + 0x20000; *instOut = NULL; } +#endif break; case 0xc7: // layer_portamento +#ifdef VERSION_EU + layer->portamento.mode = m64_read_u8(state); + portamentoTargetNote = m64_read_u8(state) + seqChannel->transposition + + layer->transposition + seqPlayer->transposition; +#else old = state->pc++; layer->portamento.mode = *old; old = state->pc++; portamentoTargetNote = *old + seqChannel->transposition + layer->transposition + seqPlayer->transposition; +#endif if (portamentoTargetNote >= 0x80) { portamentoTargetNote = 0; } @@ -531,11 +708,15 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { break; } +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif layer->portamentoTime = sp3A; break; @@ -543,6 +724,18 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { layer->portamento.mode = 0; break; +#ifdef VERSION_EU + case 0xcb: + sp3A = m64_read_s16(state); + layer->adsr.envelope = (struct AdsrEnvelope *) (seqPlayer->seqData + sp3A); + layer->adsr.releaseRate = m64_read_u8(state); + break; + + case 0xcc: + layer->unkEu0b2 = TRUE; + break; +#endif + default: loBits = cmd & 0xf; switch (cmd & 0xf0) { @@ -560,11 +753,15 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { state = &layer->scriptState; if (cmd == 0xc0) // layer_delay { +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif layer->delay = sp3A; layer->stopSomething = TRUE; } else { @@ -577,22 +774,30 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { state = &layer->scriptState; switch (cmdBase) { case 0x00: // layer_note0 (play percentage, velocity, duration) +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif vel = *(state->pc++); layer->noteDuration = *(state->pc++); layer->playPercentage = sp3A; break; case 0x40: // layer_note1 (play percentage, velocity) +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif vel = *(state->pc++); layer->noteDuration = 0; layer->playPercentage = sp3A; @@ -605,8 +810,14 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { break; } +#ifdef VERSION_EU + velFloat = (f32) vel; + layer->velocitySquare = velFloat * velFloat; + cmdSemitone = (cmd - (cmd & 0xc0)) & 0xff; +#else layer->velocitySquare = vel * vel; cmdSemitone = cmd - cmdBase; +#endif } else { cmdBase = cmd & 0xc0; @@ -615,11 +826,15 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { // phi_a0_3 = sp3A; switch (cmdBase) { case 0x00: // play note, type 0 (play percentage) +#ifdef VERSION_EU + sp3A = m64_read_compressed_u16(state); +#else sp3A = *(state->pc++); if (sp3A & 0x80) { sp3A = (sp3A << 8) & 0x7f00; sp3A = *(state->pc++) | sp3A; } +#endif layer->playPercentage = sp3A; break; @@ -632,15 +847,32 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { break; } +#ifdef VERSION_EU + cmdSemitone = (cmd - (cmd & 0xc0)) & 0xff; +#else cmdSemitone = cmd - cmdBase; +#endif } layer->delay = sp3A; +#ifdef VERSION_EU + layer->duration = layer->noteDuration * sp3A >> 8; +#else layer->duration = layer->noteDuration * sp3A / 256; +#endif if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) - || seqChannel->stopSomething2 || !seqChannel->hasInstrument) { + || seqChannel->stopSomething2 +#ifndef VERSION_EU + || !seqChannel->hasInstrument +#endif + ) { layer->stopSomething = TRUE; } else { +#ifdef VERSION_EU + if ((layer->euUnk1 == 0xff ? seqChannel->instOrWave : layer->euUnk1) == 0) { + drumIndex = cmdSemitone + seqChannel->transposition + layer->transposition; + drum = func_eu_802e4fb8(seqChannel->bankId, drumIndex); +#else if (seqChannel->instOrWave == 0) { // drum drumIndex = cmdSemitone + seqChannel->transposition + layer->transposition; if (drumIndex >= gCtlEntries[seqChannel->bankId].numDrums) { @@ -654,27 +886,43 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } drum = gCtlEntries[seqChannel->bankId].drums[drumIndex]; +#endif if (drum == NULL) { layer->stopSomething = TRUE; } else { layer->adsr.envelope = drum->envelope; layer->adsr.releaseRate = drum->releaseRate; - +#ifdef VERSION_EU + if (!layer->unkEu0b2) { + layer->euUnk5 = drum->pan; + } +#else layer->pan = FLOAT_CAST(drum->pan) / US_FLOAT(128.0); +#endif layer->sound = &drum->sound; layer->freqScale = layer->sound->tuning; } +#ifndef VERSION_EU skip:; +#endif } else { // instrument semitone = cmdSemitone + seqPlayer->transposition + seqChannel->transposition + layer->transposition; if (semitone >= 0x80) { layer->stopSomething = TRUE; } else { +#ifdef VERSION_EU + if (layer->euUnk1 == 0xff) { + instrument = seqChannel->instrument; + } else { + instrument = layer->instrument; + } +#else instrument = layer->instrument; if (layer->instrument == NULL) { instrument = seqChannel->instrument; } +#endif if (layer->portamento.mode != 0) { usedSemitone = layer->portamentoTargetNote; @@ -682,6 +930,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { usedSemitone = semitone; } if (instrument != NULL) { +#ifdef VERSION_EU + sound = func_eu_802e4e5c(instrument, usedSemitone); +#else if (usedSemitone < instrument->normalRangeLo) { sound = &instrument->lowNotesSound; } else if (usedSemitone <= instrument->normalRangeHi) { @@ -689,6 +940,7 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } else { sound = &instrument->highNotesSound; } +#endif sameSound = (sound == layer->sound); layer->sound = sound; tuning = sound->tuning; @@ -705,17 +957,25 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { case PORTAMENTO_MODE_1: case PORTAMENTO_MODE_3: case PORTAMENTO_MODE_5: +#ifndef VERSION_EU sp24 = temp_f2; +#endif freqScale = temp_f12; break; case PORTAMENTO_MODE_2: case PORTAMENTO_MODE_4: +#ifndef VERSION_EU sp24 = temp_f12; +#endif freqScale = temp_f2; break; } +#ifdef VERSION_EU + portamento->extent = temp_f2 / freqScale - 1.0f; +#else portamento->extent = sp24 / freqScale - US_FLOAT(1.0); +#endif if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST(seqPlayer->tempo) / ((f32) layer->delay * (f32) gTempoInternalToExternal @@ -729,6 +989,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { layer->portamentoTargetNote = semitone; } } else if (instrument != NULL) { +#ifdef VERSION_EU + sound = func_eu_802e4e5c(instrument, semitone); +#else if (semitone < instrument->normalRangeLo) { sound = &instrument->lowNotesSound; } else if (semitone <= instrument->normalRangeHi) { @@ -736,6 +999,7 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } else { sound = &instrument->highNotesSound; } +#endif sameSound = (sound == layer->sound); layer->sound = sound; layer->freqScale = sound->tuning * gNoteFrequencies[semitone]; @@ -763,6 +1027,10 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } else if (sameSound == FALSE) { seq_channel_layer_note_decay(layer); allocNewNote = TRUE; +#ifdef VERSION_EU + } else if (layer != layer->note->parentLayer) { + allocNewNote = TRUE; +#endif } else { allocNewNote = FALSE; if (layer->sound == NULL) { @@ -779,15 +1047,33 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { } } +#elif defined(VERSION_EU) +GLOBAL_ASM("asm/non_matchings/eu/audio/seq_channel_layer_process_script.s") #elif defined(VERSION_JP) GLOBAL_ASM("asm/non_matchings/seq_channel_layer_process_script_jp.s") #else GLOBAL_ASM("asm/non_matchings/seq_channel_layer_process_script_us.s") #endif +struct Instrument *func_eu_802e4e98(s32 bankId, s32 instId); + u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, - struct AdsrSettings *adsr) { + struct AdsrSettings *adsr) +{ struct Instrument *inst; +#ifdef VERSION_EU + inst = func_eu_802e4e98(seqChannel->bankId, instId); + if (inst == NULL) + { + *instOut = NULL; + return 0; + } + adsr->envelope = inst->envelope; + adsr->releaseRate = inst->releaseRate; + *instOut = inst; + instId++; + return instId; +#else UNUSED u32 pad; if (instId >= gCtlEntries[seqChannel->bankId].numInstruments) { @@ -827,6 +1113,7 @@ u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrume gAudioErrorFlags = instId + 0x20000; *instOut = NULL; return 0; +#endif } void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { @@ -837,9 +1124,15 @@ void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { seqChannel->instOrWave = 0; seqChannel->instrument = (struct Instrument *) 1; } else { +#ifdef VERSION_EU + if ((seqChannel->instOrWave = + get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr)) == 0) +#else seqChannel->instOrWave = get_instrument(seqChannel, instId, &seqChannel->instrument, &seqChannel->adsr); - if (seqChannel->instOrWave == 0) { + if (seqChannel->instOrWave == 0) +#endif + { seqChannel->hasInstrument = FALSE; return; } @@ -865,6 +1158,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { s32 offset; s32 i; u8 temp2; +#ifdef VERSION_EU + u8 *arr; +#endif if (!seqChannel->enabled) { return; @@ -892,6 +1188,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (seqChannel->delay == 0) { for (;;) { cmd = m64_read_u8(state); +#ifndef VERSION_EU if (cmd == 0xff) // chan_end { // This fixes a reordering in 'case 0x90', somehow @@ -916,20 +1213,50 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqChannel->stopScript = TRUE; break; } +#endif // (new_var = cmd fixes order of s1/s2, but causes a reordering // towards the bottom of the function) if (cmd > 0xc0) { switch (cmd) { +#ifdef VERSION_EU + case 0xff: // chan_end + if (state->depth == 0) { + sequence_channel_disable(seqChannel); + goto out; + } else { + state->depth--, state->pc = state->stack[state->depth]; + } + break; + + case 0xfe: // chan_delay1 + goto out; + + case 0xfd: // chan_delay + seqChannel->delay = m64_read_compressed_u16(state); + goto out; + + case 0xea: + seqChannel->stopScript = TRUE; + goto out; +#endif case 0xfc: // chan_call sp5A = m64_read_s16(state); +#ifdef VERSION_EU + state->stack[state->depth++] = state->pc; +#else state->depth++, state->stack[state->depth - 1] = state->pc; +#endif state->pc = seqPlayer->seqData + sp5A; break; case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0) state->remLoopIters[state->depth] = m64_read_u8(state); +#ifdef VERSION_EU + state->stack[state->depth++] = state->pc; +#else state->depth++, state->stack[state->depth - 1] = state->pc; +#endif break; case 0xf7: // chan_loopend @@ -959,14 +1286,35 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { state->pc = seqPlayer->seqData + sp5A; break; +#ifdef VERSION_EU + case 0xf4: + case 0xf3: + case 0xf2: + tempSigned = m64_read_u8(state); + if (cmd == 0xf3 && value != 0) + break; + if (cmd == 0xf2 && value >= 0) + break; + state->pc += tempSigned; + break; +#endif + +#ifdef VERSION_EU + case 0xf1: // chan_reservenotes +#else case 0xf2: // chan_reservenotes +#endif // seqChannel->notePool should live in a saved register note_pool_clear(&seqChannel->notePool); temp = m64_read_u8(state); note_pool_fill(&seqChannel->notePool, temp); break; +#ifdef VERSION_EU + case 0xf0: // chan_unreservenotes +#else case 0xf1: // chan_unreservenotes +#endif note_pool_clear(&seqChannel->notePool); break; @@ -983,6 +1331,22 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } break; +#ifdef VERSION_EU + case 0xeb: + temp = m64_read_u8(state); + // Switch to the temp's (0-indexed) bank in this sequence's + // bank set. Note that in the binary format (not in the JSON!) + // the banks are listed backwards, so we counts from the back. + // (gAlBankSets[offset] is number of banks) + offset = ((u16 *) gAlBankSets)[seqPlayer->seqId]; + temp = gAlBankSets[offset + gAlBankSets[offset] - temp]; + // temp should be in a saved register across this call + if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) { + seqChannel->bankId = temp; + } + // fallthrough +#endif + case 0xc1: // chan_setinstr ("set program"?) set_instrument(seqChannel, m64_read_u8(state)); break; @@ -997,14 +1361,23 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xdf: // chan_setvol sequence_channel_set_volume(seqChannel, m64_read_u8(state)); +#ifdef VERSION_EU + seqChannel->unk1.as_bitfields.unk0b40 = TRUE; +#endif break; case 0xe0: // chan_setvolscale seqChannel->volumeScale = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); +#ifdef VERSION_EU + seqChannel->unk1.as_bitfields.unk0b40 = TRUE; +#endif break; case 0xde: // chan_freqscale; pitch bend using raw frequency multiplier N/2^15 (N is u16) sp5A = m64_read_s16(state); +#ifdef VERSION_EU + seqChannel->unk1.as_bitfields.unk0b80 = TRUE; +#endif seqChannel->freqScale = FLOAT_CAST(sp5A) / US_FLOAT(32768.0); break; @@ -1012,14 +1385,27 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { // (m64_read_u8(state) is really s8 here) temp = m64_read_u8(state) + 127; seqChannel->freqScale = gPitchBendFrequencyScale[temp]; +#ifdef VERSION_EU + seqChannel->unk1.as_bitfields.unk0b80 = TRUE; +#endif break; case 0xdd: // chan_setpan +#ifdef VERSION_EU + seqChannel->unk9 = m64_read_u8(state); + seqChannel->unk1.as_bitfields.unk0b20 = TRUE; +#else seqChannel->pan = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); +#endif break; case 0xdc: // chan_setpanmix; set proportion of pan to come from channel (0..128) +#ifdef VERSION_EU + seqChannel->unkA = m64_read_u8(state); + seqChannel->unk1.as_bitfields.unk0b20 = TRUE; +#else seqChannel->panChannelWeight = FLOAT_CAST(m64_read_u8(state)) / US_FLOAT(128.0); +#endif break; case 0xdb: // chan_transpose; set transposition in semitones @@ -1065,6 +1451,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqChannel->vibratoDelay = m64_read_u8(state) * 16; break; +#ifndef VERSION_EU case 0xd6: // chan_setupdatesperframe_unimplemented temp = m64_read_u8(state); if (temp == 0) { @@ -1072,6 +1459,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } seqChannel->updatesPerFrameUnused = temp; break; +#endif case 0xd4: // chan_setreverb seqChannel->reverb = m64_read_u8(state); @@ -1130,17 +1518,75 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { break; case 0xd2: // chan_setsustain +#ifdef VERSION_EU + seqChannel->adsr.sustain = m64_read_u8(state); +#else seqChannel->adsr.sustain = m64_read_u8(state) << 8; +#endif break; - +#ifdef VERSION_EU + case 0xe5: + seqChannel->reverbIndex = m64_read_u8(state); + break; +#endif case 0xe4: // chan_dyncall if (value != -1) { u8(*thingy)[2] = *seqChannel->dynTable; +#ifdef VERSION_EU + state->stack[state->depth++] = state->pc; +#else state->depth++, state->stack[state->depth - 1] = state->pc; +#endif sp5A = thingy[value][1] + (thingy[value][0] << 8); state->pc = seqPlayer->seqData + sp5A; } break; + +#ifdef VERSION_EU + case 0xe6: + seqChannel->unk8 = m64_read_u8(state); + break; + + case 0xe7: + sp5A = m64_read_s16(state); + arr = seqPlayer->seqData + sp5A; + seqChannel->muteBehavior = *arr++; + seqChannel->noteAllocPolicy = *arr++; + seqChannel->notePriority = *arr++; + seqChannel->transposition = (s8) *arr++; + seqChannel->unk9 = *arr++; + seqChannel->unkA = *arr++; + seqChannel->reverb = *arr++; + seqChannel->reverbIndex = *arr++; // reverb index? + seqChannel->unk1.as_bitfields.unk0b20 = TRUE; + break; + + case 0xe8: + seqChannel->muteBehavior = m64_read_u8(state); + seqChannel->noteAllocPolicy = m64_read_u8(state); + seqChannel->notePriority = m64_read_u8(state); + seqChannel->transposition = (s8) m64_read_u8(state); + seqChannel->unk9 = m64_read_u8(state); + seqChannel->unkA = m64_read_u8(state); + seqChannel->reverb = m64_read_u8(state); + seqChannel->reverbIndex = m64_read_u8(state); + seqChannel->unk1.as_bitfields.unk0b20 = TRUE; + break; + + case 0xec: + seqChannel->vibratoExtentTarget = 0; + seqChannel->vibratoExtentStart = 0; + seqChannel->vibratoExtentChangeDelay = 0; + seqChannel->vibratoRateTarget = 0; + seqChannel->vibratoRateStart = 0; + seqChannel->vibratoRateChangeDelay = 0; + seqChannel->freqScale = 1.0f; + break; + + case 0xe9: + seqChannel->notePriority = m64_read_u8(state); + break; +#endif } } else { // loBits is recomputed a lot @@ -1151,6 +1597,11 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (seqChannel->layers[loBits] != NULL) { value = seqChannel->layers[loBits]->finished; } +#ifdef VERSION_EU + else { + value = -1; + } +#endif break; case 0x70: // chan_iowriteval; write data back to audio lib @@ -1168,6 +1619,12 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { value -= seqChannel->soundScriptIO[loBits]; break; +#ifdef VERSION_EU + case 0x60: + seqChannel->delay = loBits; + goto out; +#endif + case 0x90: // chan_setlayer sp5A = m64_read_s16(state); if (seq_channel_set_layer(seqChannel, loBits) == 0) { @@ -1181,15 +1638,17 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0xb0: // chan_dynsetlayer if (value != -1 && seq_channel_set_layer(seqChannel, loBits) != -1) { - temp = (*seqChannel->dynTable)[value][0] - + ((*seqChannel->dynTable)[value][1] << 8); - seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + temp; + sp5A = ((*seqChannel->dynTable)[value][0] << 8) + + (*seqChannel->dynTable)[value][1]; + seqChannel->layers[loBits]->scriptState.pc = seqPlayer->seqData + sp5A; } break; +#ifndef VERSION_EU case 0x60: // chan_setnotepriority (arg must be >= 2) seqChannel->notePriority = loBits; break; +#endif case 0x10: // chan_startchannel sp5A = m64_read_s16(state); @@ -1211,6 +1670,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } } } +#ifdef VERSION_EU + out: +#endif for (i = 0; i < LAYERS_MAX; i++) { if (seqChannel->layers[i] != 0) { @@ -1219,12 +1681,17 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } } +#elif defined(VERSION_EU) +GLOBAL_ASM("asm/non_matchings/eu/audio/sequence_channel_process_script.s") #elif defined(VERSION_JP) GLOBAL_ASM("asm/non_matchings/sequence_channel_process_script_jp.s") #else GLOBAL_ASM("asm/non_matchings/sequence_channel_process_script_us.s") #endif +#if defined(VERSION_EU) && !defined(NON_MATCHING) +GLOBAL_ASM("asm/non_matchings/eu/audio/sequence_player_process_sequence.s") +#else void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { u8 cmd; u8 loBits; @@ -1235,12 +1702,34 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { u16 u16v; u8 *tempPtr; struct M64ScriptState *state; +#ifdef VERSION_EU + s32 temp32; +#endif if (seqPlayer->enabled == FALSE) { return; } if (seqPlayer->bankDmaInProgress == TRUE) { +#ifdef VERSION_EU + if (osRecvMesg(&seqPlayer->bankDmaMesgQueue, NULL, 0) == -1) { + return; + } + if (seqPlayer->bankDmaRemaining == 0) { + seqPlayer->bankDmaInProgress = FALSE; + patch_audio_bank((struct AudioBank *)(gCtlEntries[seqPlayer->loadingBankId].instruments - 1), + gAlTbl->seqArray[seqPlayer->loadingBankId].offset, + gCtlEntries[seqPlayer->loadingBankId].numInstruments, + gCtlEntries[seqPlayer->loadingBankId].numDrums); + gCtlEntries[seqPlayer->loadingBankId].drums = + ((struct AudioBank *)(gCtlEntries[seqPlayer->loadingBankId].instruments - 1))->drums; + gBankLoadStatus[seqPlayer->loadingBankId] = SOUND_LOAD_STATUS_COMPLETE; + } else { + audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, + &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, + &seqPlayer->bankDmaIoMesg); + } +#else if (seqPlayer->bankDmaMesg == NULL) { return; } @@ -1260,13 +1749,20 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { &seqPlayer->bankDmaRemaining, &seqPlayer->bankDmaMesgQueue, &seqPlayer->bankDmaIoMesg); } +#endif return; } if (seqPlayer->seqDmaInProgress == TRUE) { +#ifdef VERSION_EU + if (osRecvMesg(&seqPlayer->seqDmaMesgQueue, NULL, 0) == -1) { + return; + } +#else if (seqPlayer->seqDmaMesg == NULL) { return; } +#endif seqPlayer->seqDmaInProgress = FALSE; gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_COMPLETE; } @@ -1297,6 +1793,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { if (seqPlayer->delay > 1) { seqPlayer->delay--; } else { +#ifdef VERSION_EU + seqPlayer->unk_eu = 1; +#endif for (;;) { cmd = m64_read_u8(state); if (cmd == 0xff) // seq_end @@ -1327,13 +1826,21 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { case 0xfc: // seq_call u16v = m64_read_s16(state); +#ifdef VERSION_EU + state->stack[state->depth++] = state->pc; +#else state->depth++, state->stack[state->depth - 1] = state->pc; +#endif state->pc = seqPlayer->seqData + u16v; break; case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0) state->remLoopIters[state->depth] = m64_read_u8(state); +#ifdef VERSION_EU + state->stack[state->depth++] = state->pc; +#else state->depth++, state->stack[state->depth - 1] = state->pc; +#endif break; case 0xf7: // seq_loopend @@ -1362,12 +1869,35 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { state->pc = seqPlayer->seqData + u16v; break; +#ifdef VERSION_EU + case 0xf4: + case 0xf3: + case 0xf2: + tempSigned = m64_read_u8(state); + if (cmd == 0xf3 && value != 0) { + break; + } + if (cmd == 0xf2 && value >= 0) { + break; + } + state->pc += tempSigned; + break; +#endif + +#ifdef VERSION_EU + case 0xf1: // seq_reservenotes +#else case 0xf2: // seq_reservenotes +#endif note_pool_clear(&seqPlayer->notePool); note_pool_fill(&seqPlayer->notePool, m64_read_u8(state)); break; +#ifdef VERSION_EU + case 0xf0: // seq_unreservenotes +#else case 0xf1: // seq_unreservenotes +#endif note_pool_clear(&seqPlayer->notePool); break; @@ -1397,6 +1927,45 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { } break; +#ifdef VERSION_EU + case 0xda: + temp = m64_read_u8(state); + u16v = m64_read_s16(state); + switch (temp) { + case SEQUENCE_PLAYER_STATE_0: + case SEQUENCE_PLAYER_STATE_FADE_OUT: + if (seqPlayer->state != SEQUENCE_PLAYER_STATE_2) { + seqPlayer->fadeTimerUnkEu = u16v; + seqPlayer->state = temp; + } + break; + case SEQUENCE_PLAYER_STATE_2: + seqPlayer->fadeTimer = u16v; + seqPlayer->state = temp; + seqPlayer->fadeVelocity = (0.0f - seqPlayer->fadeVolume) / (s32) u16v; + break; + } + break; + + case 0xdb: + temp32 = m64_read_u8(state); + switch (seqPlayer->state) { + case SEQUENCE_PLAYER_STATE_2: + break; + case SEQUENCE_PLAYER_STATE_FADE_OUT: + seqPlayer->state = SEQUENCE_PLAYER_STATE_0; + seqPlayer->fadeVolume = 0.0f; + // fallthrough + case SEQUENCE_PLAYER_STATE_0: + seqPlayer->fadeTimer = seqPlayer->fadeTimerUnkEu; + if (seqPlayer->fadeTimerUnkEu != 0) { + seqPlayer->fadeVelocity = (temp32 / 127.0f - seqPlayer->fadeVolume) / FLOAT_CAST(seqPlayer->fadeTimer); + } else { + seqPlayer->fadeVolume = temp32 / 127.0f; + } + } + break; +#else case 0xdb: // seq_setvol temp = m64_read_u8(state); switch (seqPlayer->state) { @@ -1423,6 +1992,14 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { seqPlayer->fadeVolume = seqPlayer->fadeVolume + (f32) tempSigned / US_FLOAT(127.0); break; +#endif + +#ifdef VERSION_EU + case 0xd9: + tempSigned = m64_read_u8(state); + seqPlayer->unkEu28 = tempSigned / 127.0f; + break; +#endif case 0xd7: // seq_initchannels u16v = m64_read_s16(state); @@ -1467,7 +2044,11 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { break; case 0xc9: // seq_bitand +#ifdef VERSION_EU + value &= m64_read_u8(state); +#else value = m64_read_u8(state) & value; +#endif break; case 0xc8: // seq_subtract @@ -1478,9 +2059,13 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { loBits = cmd & 0xf; switch (cmd & 0xf0) { case 0x00: // seq_testchdisabled +#ifdef VERSION_EU + value = seqPlayer->channels[loBits]->finished; +#else if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[loBits]) == TRUE) { value = seqPlayer->channels[loBits]->finished; } +#endif break; case 0x10: break; @@ -1489,15 +2074,27 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { case 0x40: break; case 0x50: // seq_subvariation +#ifdef VERSION_EU + value -= seqPlayer->seqVariationEu[0]; +#else value -= seqPlayer->seqVariation; +#endif break; case 0x60: break; case 0x70: // seq_setvariation +#ifdef VERSION_EU + seqPlayer->seqVariationEu[0] = value; +#else seqPlayer->seqVariation = value; +#endif break; case 0x80: // seq_getvariation +#ifdef VERSION_EU + value = seqPlayer->seqVariationEu[0]; +#else value = seqPlayer->seqVariation; +#endif break; case 0x90: // seq_startchannel u16v = m64_read_s16(state); @@ -1505,41 +2102,67 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { break; case 0xa0: break; +#ifndef VERSION_EU case 0xd8: // (this makes no sense) break; case 0xd9: break; +#endif } } } } for (i = 0; i < CHANNELS_MAX; i++) { +#ifdef VERSION_EU + if (IS_SEQUENCE_CHANNEL_VALID(seqPlayer->channels[i]) == TRUE) { + sequence_channel_process_script(seqPlayer->channels[i]); + } +#else if (seqPlayer->channels[i] != &gSequenceChannelNone) { sequence_channel_process_script(seqPlayer->channels[i]); } +#endif } } +#endif // This runs 240 times per second. void process_sequences(UNUSED s32 iterationsRemaining) { s32 i; for (i = 0; i < SEQUENCE_PLAYERS; i++) { if (gSequencePlayers[i].enabled == TRUE) { +#ifdef VERSION_EU + sequence_player_process_sequence(&gSequencePlayers[i]); + sequence_player_process_sound(&gSequencePlayers[i]); +#else sequence_player_process_sequence(gSequencePlayers + i); sequence_player_process_sound(gSequencePlayers + i); +#endif } } +#ifndef VERSION_EU reclaim_notes(); +#endif process_notes(); } void init_sequence_player(u32 player) { struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; +#ifdef VERSION_EU + sequence_player_disable(seqPlayer); +#endif seqPlayer->muted = FALSE; seqPlayer->delay = 0; +#ifdef VERSION_EU + seqPlayer->state = 1; +#else seqPlayer->state = SEQUENCE_PLAYER_STATE_0; +#endif seqPlayer->fadeTimer = 0; +#ifdef VERSION_EU + seqPlayer->fadeTimerUnkEu = 0; +#endif seqPlayer->tempoAcc = 0; seqPlayer->tempo = 120 * TEMPO_SCALE; // 120 BPM seqPlayer->transposition = 0; @@ -1548,6 +2171,9 @@ void init_sequence_player(u32 player) { seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; seqPlayer->shortNoteDurationTable = gDefaultShortNoteDurationTable; seqPlayer->fadeVolume = 1.0f; +#ifdef VERSION_EU + seqPlayer->unkEu28 = 1.0f; +#endif seqPlayer->fadeVelocity = 0.0f; seqPlayer->volume = 0.0f; seqPlayer->muteVolumeScale = 0.5f; @@ -1560,9 +2186,11 @@ void init_sequence_players(void) { for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { gSequenceChannels[i].seqPlayer = NULL; gSequenceChannels[i].enabled = FALSE; +#ifndef VERSION_EU } for (i = 0; i < ARRAY_COUNT(gSequenceChannels); i++) { +#endif // @bug Size of wrong array. Zeroes out second half of gSequenceChannels[0], // all of gSequenceChannels[1..31], and part of gSequenceLayers[0]. // However, this is only called at startup, so it's harmless. @@ -1588,7 +2216,11 @@ void init_sequence_players(void) { gSequencePlayers[i].channels[j] = &gSequenceChannelNone; } +#ifdef VERSION_EU + gSequencePlayers[i].seqVariationEu[0] = -1; +#else gSequencePlayers[i].seqVariation = -1; +#endif gSequencePlayers[i].bankDmaInProgress = FALSE; gSequencePlayers[i].seqDmaInProgress = FALSE; init_note_lists(&gSequencePlayers[i].notePool); diff --git a/src/audio/synthesis.c b/src/audio/synthesis.c index ec869f8..5d1f7e3 100644 --- a/src/audio/synthesis.c +++ b/src/audio/synthesis.c @@ -8,6 +8,7 @@ #include "seqplayer.h" #include "external.h" + #define DMEM_ADDR_TEMP 0x0 #define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180 #define DMEM_ADDR_ADPCM_RESAMPLED 0x20 @@ -35,9 +36,6 @@ #define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1)) -struct SynthesisReverb gSynthesisReverb; -u8 sAudioSynthesisPad[0x20]; - struct VolumeChange { u16 sourceLeft; u16 sourceRight; @@ -46,6 +44,13 @@ struct VolumeChange { }; u64 *synthesis_do_one_audio_update(u16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateIndex); +#ifdef VERSION_EU +u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, u16 *aiBuf, s32 bufLen, u64 *cmd); +u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad); +u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags); +u64 *process_envelope(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings); +u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight); +#else u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd); u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad); u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags); @@ -54,7 +59,89 @@ u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, struct VolumeChange *vol); u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight); +#endif +#ifdef VERSION_EU +struct SynthesisReverb gSynthesisReverbs[4]; +u8 sAudioSynthesisPad[0x10]; +s16 gVolume; +s8 gUseReverb; +s8 gNumSynthesisReverbs; +struct NoteSubEu *gNoteSubsEu; +f32 gLeftVolRampings[3][1024]; +f32 gRightVolRampings[3][1024]; +f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above +f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above +#else +struct SynthesisReverb gSynthesisReverb; +#endif + +#ifndef VERSION_EU +u8 sAudioSynthesisPad[0x20]; +#endif + +#if defined(VERSION_EU) +#ifndef NON_MATCHING +GLOBAL_ASM("asm/non_matchings/eu/audio/prepare_reverb_ring_buffer.s") +#else +// Equivalent functionality as the US/JP version, +// just that the reverb structure is chosen from an array with index +void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) { + struct SynthesisReverb *reverb = &gSynthesisReverbs[reverbIndex]; + struct ReverbRingBufferItem *item; + s32 srcPos; + s32 dstPos; + s32 nSamples; + //s32 numSamplesAfterDownsampling; + s32 excessiveSamples; + if (reverb->downsampleRate != 1) { + if (reverb->framesLeftToIgnore == 0) { + // Now that the RSP has finished, downsample the samples produced two frames ago by skipping + // samples. + item = &reverb->items[reverb->curFrame][updateIndex]; + + // Touches both left and right since they are adjacent in memory + osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH); + + for (srcPos = 0, dstPos = 0; dstPos < item->lengths[0] / 2; + srcPos += reverb->downsampleRate, dstPos++) { + reverb->ringBuffer.left[dstPos + item->startPos] = + item->toDownsampleLeft[srcPos]; + reverb->ringBuffer.right[dstPos + item->startPos] = + item->toDownsampleRight[srcPos]; + } + for (dstPos = 0; dstPos < item->lengths[1] / 2; srcPos += reverb->downsampleRate, dstPos++) { + reverb->ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; + reverb->ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; + } + } + } + + //numSamplesAfterDownsampling = + nSamples = chunkLen / reverb->downsampleRate; + excessiveSamples = + (nSamples + reverb->nextRingBufferPos) - reverb->bufSizePerChannel; + item = &reverb->items[reverb->curFrame][updateIndex]; + if (excessiveSamples < 0) { + // There is space in the ring buffer before it wraps around + item->lengths[0] = nSamples * 2; + item->lengths[1] = 0; + item->startPos = (s32) reverb->nextRingBufferPos; + reverb->nextRingBufferPos += nSamples; + } else { + // Ring buffer wrapped around + //nSamples = numSamplesAfterDownsampling - excessiveSamples; + item->lengths[0] = (nSamples - excessiveSamples) * 2; + item->lengths[1] = excessiveSamples * 2; + item->startPos = reverb->nextRingBufferPos; + reverb->nextRingBufferPos = excessiveSamples; + } + // These fields are never read later + item->numSamplesAfterDownsampling = nSamples; + item->chunkLen = chunkLen; +} +#endif +#else void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { struct ReverbRingBufferItem *item; s32 srcPos; @@ -107,7 +194,50 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { item->numSamplesAfterDownsampling = numSamplesAfterDownsampling; item->chunkLen = chunkLen; } +#endif +#ifdef VERSION_EU +u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 len, s32 reverbIndex) { + // aSetBuffer, aLoadBuffer, aSetBuffer, aLoadBuffer + aSetBuffer(cmd++, 0, addr, 0, len); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[srcOffset])); + + aSetBuffer(cmd++, 0, addr + DEFAULT_LEN_1CH, 0, len); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[srcOffset])); + + return cmd; +} + + +u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 len, s32 reverbIndex) { + aSetBuffer(cmd++, 0, 0, addr, len); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[destOffset])); + + aSetBuffer(cmd++, 0, 0, addr + DEFAULT_LEN_1CH, len); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[destOffset])); + + return cmd; +} + +void synthesis_load_note_subs_eu(s32 updateIndex) { + struct NoteSubEu *src; + struct NoteSubEu *dest; + s32 i; + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + src = &gNotes[i].noteSubEu; + dest = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i]; + if (src->enabled) { + *dest = *src; + src->needsInit = 0; + } else { + dest->enabled = 0; + } + } +} +#endif + +#ifndef VERSION_EU s32 get_volume_ramping(u16 sourceVol, u16 targetVol, s32 arg2) { // This roughly computes 2^16 * (targetVol / sourceVol) ^ (8 / arg2), // but with discretizations of targetVol, sourceVol and arg2. @@ -128,7 +258,77 @@ s32 get_volume_ramping(u16 sourceVol, u16 targetVol, s32 arg2) { } return ret; } +#endif +#ifdef VERSION_EU +#ifndef NON_MATCHING +GLOBAL_ASM("asm/non_matchings/eu/audio/synthesis_execute.s") +#else +u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, u16 *aiBuf, s32 bufLen) { + s32 nextVolRampTable; + s32 temp; + s32 i; + s32 remaining; + f32 *leftVolRamp; + f32 *rightVolRamp; + s32 chunkLen; + s32 j; + u32 *aiBufPtr; + u64 *cmd = cmdBuf; + + for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { + process_sequences(i - 1); + synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - i); + } + aSegment(cmd++, 0, 0); + remaining = bufLen; + aiBufPtr = (u32 *) aiBuf; + for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { + if (i == 1) { + leftVolRamp = gLeftVolRampings[nextVolRampTable]; + rightVolRamp = gRightVolRampings[nextVolRampTable]; + chunkLen = remaining; + } else { + temp = remaining / i; + if (temp >= gAudioBufferParameters.samplesPerUpdateMax) { + leftVolRamp = gLeftVolRampings[2]; + rightVolRamp = gRightVolRampings[2]; + chunkLen = gAudioBufferParameters.samplesPerUpdateMax; + nextVolRampTable = 2; + } else if (temp <= gAudioBufferParameters.samplesPerUpdateMin) { + leftVolRamp = gLeftVolRampings[0]; + rightVolRamp = gRightVolRampings[0]; + chunkLen = gAudioBufferParameters.samplesPerUpdateMin; + nextVolRampTable = 0; + } else { + leftVolRamp = gLeftVolRampings[1]; + rightVolRamp = gRightVolRampings[1]; + chunkLen = gAudioBufferParameters.samplesPerUpdate; + nextVolRampTable = 1; + } + } + gCurrentLeftVolRamping = leftVolRamp; + gCurrentRightVolRamping = rightVolRamp; + for (j = 0; j < gNumSynthesisReverbs; j++) { + if (gSynthesisReverbs[j].useReverb != 0) { + prepare_reverb_ring_buffer(chunkLen, gAudioBufferParameters.updatesPerFrame - i, j); + } + } + cmd = synthesis_do_one_audio_update((u16 *) aiBufPtr, chunkLen, cmd, gAudioBufferParameters.updatesPerFrame - i); + remaining -= chunkLen; + aiBufPtr += chunkLen; + } + for (i = 0; i < gNumSynthesisReverbs; i++) { + if (gSynthesisReverbs[i].framesLeftToIgnore != 0) { + gSynthesisReverbs[i].framesLeftToIgnore--; + } + gSynthesisReverbs[i].curFrame ^= 1; + } + *writtenCmds = cmd - cmdBuf; + return cmd; +} +#endif +#else // bufLen will be divisible by 16 u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, u16 *aiBuf, s32 bufLen) { s32 chunkLen; @@ -168,7 +368,176 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, u16 *aiBuf, s32 bufLen) { *writtenCmds = cmd - cmdBuf; return cmd; } +#endif + +#ifdef VERSION_EU +#ifndef NON_MATCHING +GLOBAL_ASM("asm/non_matchings/eu/audio/synthesis_resample_and_mix_reverb.s") +u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex); +#else +u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { + struct ReverbRingBufferItem *item; // sp5C + s16 temp_t9; // sp5a + s16 sp58; // sp58 + struct SynthesisReverb *reverb; + + reverb = &gSynthesisReverbs[reverbIndex]; + item = &reverb->items[reverb->curFrame][updateIndex]; + + aClearBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + if (reverb->downsampleRate == 1) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengths[0], reverbIndex); + if (item->lengths[1] != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengths[0], 0, item->lengths[1], reverbIndex); + } + aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); + aMix(cmd++, 0, 0x7fff, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH); + aMix(cmd++, 0, 0x8000 + reverb->reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH); + } else { + temp_t9 = (item->startPos & 7) * 2; + sp58 = ALIGN(temp_t9 + item->lengths[0], 4); + cmd = synthesis_load_reverb_ring_buffer(cmd, 0x20, (item->startPos - temp_t9 / 2), DEFAULT_LEN_1CH, reverbIndex); + if (item->lengths[1] != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, 0x20 + sp58, 0, DEFAULT_LEN_1CH - sp58, reverbIndex); + } + + aSetBuffer(cmd++, 0, temp_t9 + DMEM_ADDR_ADPCM_RESAMPLED, DMEM_ADDR_WET_LEFT_CH, bufLen * 2); + aResample(cmd++, reverb->resampleFlags, reverb->resampleRate, VIRTUAL_TO_PHYSICAL2(reverb->resampleStateLeft)); + + aSetBuffer(cmd++, 0, temp_t9 + DMEM_ADDR_ADPCM_RESAMPLED2, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2); + aResample(cmd++, reverb->resampleFlags, reverb->resampleRate, VIRTUAL_TO_PHYSICAL2(reverb->resampleStateRight)); + + aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); + aMix(cmd++, 0, 0x7fff, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH); + aMix(cmd++, 0, 0x8000 + reverb->reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH); + } + return cmd; +} +#endif + +#ifndef NON_MATCHING +GLOBAL_ASM("asm/non_matchings/eu/audio/func_eu_802e00d8.s") +u64 *func_eu_802e00d8(u64 *cmd, s16 reverbIndex, s16 updateIndex); +#else +u64 *func_eu_802e00d8(u64 *cmd, s16 reverbIndex, s16 updateIndex) { + struct SynthesisReverb *reverb; + struct ReverbRingBufferItem *item; + + reverb = &gSynthesisReverbs[reverbIndex]; + item = &reverb->items[reverb->curFrame][updateIndex]; + if (reverb->useReverb != 0) { + if (reverb->downsampleRate == 1) { + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengths[0], reverbIndex); + if (item->lengths[1] != 0) { + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengths[0], 0, item->lengths[1], reverbIndex); + } + } else { + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(reverb->items[reverb->curFrame][updateIndex].toDownsampleLeft)); + reverb->resampleFlags = 0; + } + } + return cmd; +} +#endif +#endif + +#ifdef VERSION_EU +#ifndef NON_MATCHING +GLOBAL_ASM("asm/non_matchings/eu/audio/synthesis_do_one_audio_update.s") +#else +u64 *synthesis_do_one_audio_update(u16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateIndex) { + u8 sp84[60]; + struct SynthesisReverb *sp60; + s32 temp_lo; + s32 temp_lo_2; + u8 temp_v1; + u8 temp_v1_2; + struct NoteSubEu *temp_t5; + struct NoteSubEu *temp_v0; + s32 phi_s1; + s16 phi_s2; + s16 phi_s3; + s32 phi_s1_2; + s32 phi_v1_2; + s32 phi_s1_3; + s16 phi_s3_2; + s32 phi_s1_4; + u8 *phi_s0_2; + s32 bufLen2; + + if (gNumSynthesisReverbs == 0) { + phi_s2 = 0; + for (phi_s1 = 0; phi_s1 < gMaxSimultaneousNotes; phi_s1++) { + if (gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + phi_s1].enabled) { + sp84[phi_s2++] = phi_s1; + } + } + } else { + phi_s2 = 0; + for (phi_s3 = 0; phi_s3 < gNumSynthesisReverbs; phi_s3++) { + for (phi_s1_2 = 0; phi_s1_2 < gMaxSimultaneousNotes; phi_s1_2++) { + temp_v0 = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + phi_s1_2]; + if (temp_v0->enabled) { + if (phi_s3 == temp_v0->unk1b567) { + sp84[phi_s2++] = phi_s1_2; + } + } + } + } + phi_v1_2 = gMaxSimultaneousNotes * updateIndex; + for (phi_s1_3 = 0; phi_s1_3 < gMaxSimultaneousNotes; phi_s1_3++) { + if (gNoteSubsEu[phi_v1_2].enabled) { + if (temp_v0->unk1b567 >= gNumSynthesisReverbs) { + sp84[phi_s2++] = phi_s1_3; + } + } + phi_v1_2++; + } + } + aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + phi_s1_4 = 0; + for (phi_s3_2 = 0; phi_s3_2 < gNumSynthesisReverbs; phi_s3_2++) { + sp60 = &gSynthesisReverbs[phi_s3_2]; + gUseReverb = sp60->useReverb; + if (gUseReverb != 0) { + cmd = synthesis_resample_and_mix_reverb(cmd, bufLen, phi_s3_2, (s16) updateIndex); + } + for (; phi_s1_4 < phi_s2; phi_s1_4++) { + temp_v1 = sp84[phi_s1_4]; + temp_lo = updateIndex * gMaxSimultaneousNotes; + if (phi_s3_2 == gNoteSubsEu[temp_v1 + temp_lo].unk1b567) { + cmd = synthesis_process_note(&gNotes[temp_v1], &gNoteSubsEu[temp_v1 + temp_lo], &gNotes[temp_v1].synthesisState, aiBuf, bufLen, cmd); + } else { + break; + } + } + if (sp60->useReverb != 0) { + cmd = func_eu_802e00d8(cmd, phi_s3_2, (s16) updateIndex); + } + } + phi_s0_2 = &sp84[phi_s1_4]; + for (; phi_s1_4 < phi_s2; phi_s1_4++) { + temp_v1_2 = *phi_s0_2; + temp_lo_2 = updateIndex * gMaxSimultaneousNotes; + temp_t5 = &gNoteSubsEu[temp_v1_2 + temp_lo_2]; + if (IS_BANK_LOAD_COMPLETE(temp_t5->bankId) == TRUE) { + cmd = synthesis_process_note(&gNotes[temp_v1_2], &gNoteSubsEu[temp_v1_2 + temp_lo_2], &gNotes[temp_v1_2].synthesisState, aiBuf, bufLen, cmd); + } else { + gAudioErrorFlags = (temp_t5->bankId + (phi_s1_4 << 8)) + 0x10000000; + } + phi_s0_2++; + } + bufLen2 = bufLen * 2; + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, bufLen2); + aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH); + aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, bufLen2 * 2); + aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); + return cmd; +} +#endif +#else u64 *synthesis_do_one_audio_update(u16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateIndex) { UNUSED s32 pad1[1]; s16 ra; @@ -241,11 +610,17 @@ u64 *synthesis_do_one_audio_update(u16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateI } return cmd; } +#endif #ifdef NON_MATCHING +#ifdef VERSION_EU +// Processes just one note, not all +u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED u16 *aiBuf, s32 bufLen, u64 *cmd) { +#else u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { s32 noteIndex; // sp174 struct Note *note; // s7 +#endif struct AudioBankSample *audioBookSample; // sp164 struct AdpcmLoop *loopInfo; // sp160 s16 *curLoadedBook; // sp15C @@ -284,28 +659,56 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { u32 samplesLenFixedPoint; // v1_1 s32 nSamplesInThisIteration; // v1_2 u32 a3; +#ifndef VERSION_EU s32 t9; +#endif u8 *v0_2; +#ifndef VERSION_EU f32 resamplingRate; // f12 +#endif UNUSED s32 temp; +#ifdef VERSION_EU + curLoadedBook = NULL; +#endif + + +#ifndef VERSION_EU for (noteIndex = 0, curLoadedBook = NULL; noteIndex < gMaxSimultaneousNotes; noteIndex++) { note = &gNotes[noteIndex]; if (IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { gAudioErrorFlags = (note->bankId << 8) + noteIndex + 0x1000000; } else if (note->enabled) { +#else + if (noteSubEu->enabled) { +#endif // This matches much much better if enabled is volatile... but that // breaks other functions (e.g. note_enable). Can we achieve the // volatile effect in some other way? flags = 0; +#ifdef VERSION_EU + if (noteSubEu->needsInit == TRUE) { +#else if (note->needsInit == TRUE) { +#endif flags = A_INIT; +#ifndef VERSION_EU note->samplePosInt = 0; note->samplePosFrac = 0; +#else + synthesisState->restart = FALSE; + synthesisState->samplePosInt = 0; + synthesisState->samplePosFrac = 0; + synthesisState->curVolLeft = 1; + synthesisState->curVolRight = 1; + synthesisState->prevHeadsetPanRight = 0; + synthesisState->prevHeadsetPanLeft = 0; +#endif } +#ifndef VERSION_EU if (note->frequency < US_FLOAT(2.0)) { nParts = 1; if (note->frequency > US_FLOAT(1.99996)) { @@ -324,7 +727,21 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { resamplingRateFixedPoint = (u16)(s32)(resamplingRate * 32768.0f); samplesLenFixedPoint = note->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2; note->samplePosFrac = samplesLenFixedPoint; // 16-bit store, can't reuse +#else + resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; + nParts = noteSubEu->hasTwoAdpcmParts + 1; + samplesLenFixedPoint = synthesisState->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2; + synthesisState->samplePosFrac = samplesLenFixedPoint; +#endif +#ifdef VERSION_EU + if (noteSubEu->isSyntheticWave) { + noteSamplesDmemAddrBeforeResampling = + DMEM_ADDR_UNCOMPRESSED_NOTE + synthesisState->samplePosInt * 2; + synthesisState->samplePosInt += (samplesLenFixedPoint >> 10); + cmd = load_wave_samples(cmd, noteSubEu, synthesisState, samplesLenFixedPoint >> 10); + } +#else if (note->sound == NULL) { // A wave synthesis note (not ADPCM) // samplesLenFixedPoint >> 0x10 stored in s0 @@ -333,10 +750,16 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { DMEM_ADDR_UNCOMPRESSED_NOTE + note->samplePosInt * 2; note->samplePosInt += (samplesLenFixedPoint >> 0x10); flags = 0; - } else { + } +#endif + else { // ADPCM note +#ifdef VERSION_EU + audioBookSample = noteSubEu->sound.audioBankSound->sample; +#else audioBookSample = note->sound->sample; +#endif // sp58 is a low-numbered register, so possibly a temporary. // Should it be used for samplesLenFixedPoint >> 0x10 above as well? But then @@ -378,6 +801,12 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { aLoadADPCM(cmd++, nEntries * 16, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); } +#ifdef VERSION_EU + if (noteSubEu->unk1b234) { + curLoadedBook = (s16 *) &euUnknownData_80301950; // what's this? never read + } +#endif + while (nAdpcmSamplesProcessed != samplesLenAdjusted) { s32 samplesRemaining; // v1 s32 s0; @@ -385,12 +814,23 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { noteFinished = FALSE; restart = FALSE; nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; +#ifdef VERSION_EU + s2 = synthesisState->samplePosInt & 0xf; + samplesRemaining = endPos - synthesisState->samplePosInt; +#else s2 = note->samplePosInt & 0xf; samplesRemaining = endPos - note->samplePosInt; +#endif +#ifdef VERSION_EU + if (s2 == 0 && !synthesisState->restart) { + s2 = 16; + } +#else if (s2 == 0 && !note->restart) { s2 = 16; } +#endif s6 = 16 - s2; // a1 if (nSamplesToProcess < samplesRemaining) { @@ -419,9 +859,20 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { if (t0 != 0) { // maybe keep a var for t0 * 9? +#ifdef VERSION_EU + if (audioBookSample->loaded == 0x81) { + v0_2 = sampleAddr + (synthesisState->samplePosInt - s2 + 0x10) / 16 * 9; + } else { + v0_2 = dma_sample_data( + (uintptr_t) (sampleAddr + (synthesisState->samplePosInt - s2 + 0x10) / 16 * 9), + t0 * 9, flags, &synthesisState->sampleDmaIndex); + a3 = (u32)((uintptr_t) v0_2 & 0xf); + } +#else v0_2 = dma_sample_data( (uintptr_t) (sampleAddr + (note->samplePosInt - s2 + 0x10) / 16 * 9), t0 * 9, flags, ¬e->sampleDmaIndex); +#endif a3 = (u32)((uintptr_t) v0_2 & 0xf); aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA, 0, t0 * 9 + a3); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3)); @@ -430,6 +881,28 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { a3 = 0; } +#ifdef VERSION_EU + if (synthesisState->restart != FALSE) { + aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); + flags = A_LOOP; // = 2 + synthesisState->restart = FALSE; + } + + if (nAdpcmSamplesProcessed == 0) { + aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, + DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); + aADPCMdec(cmd++, flags, + VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + sp130 = s2 * 2; + } else { + aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, + DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5), s0 * 2); + aADPCMdec(cmd++, flags, + VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), + DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (s0 + s6_2 - s3) * 2); + } +#else if (note->restart != FALSE) { aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); flags = A_LOOP; // = 2 @@ -450,6 +923,7 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (s0 + s6_2 - s3) * 2); } +#endif nAdpcmSamplesProcessed = nAdpcmSamplesProcessed + s0 + s6_2 - s3; nSamplesInThisIteration = s0 + s6_2 - s3; @@ -476,17 +950,32 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { if (noteFinished) { aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); +#ifdef VERSION_EU + noteSubEu->finished = 1; + noteSubEu->finished = 1; + noteSubEu->enabled = 0; +#else note->samplePosInt = 0; note->finished = 1; note->enabled = 0; +#endif break; // goto? doesn't matter, though } +#ifdef VERSION_EU + if (restart) { + synthesisState->restart = TRUE; + synthesisState->samplePosInt = loopInfo->start; + } else { + synthesisState->samplePosInt += nSamplesToProcess; + } +#else if (restart) { note->restart = TRUE; note->samplePosInt = loopInfo->start; } else { note->samplePosInt += nSamplesToProcess; } +#endif } switch (nParts) { @@ -499,14 +988,24 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { case 0: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_ADPCM_RESAMPLED, samplesLenAdjusted + 4); +#ifdef VERSION_EU + aResample(cmd++, A_INIT, 0xff60, + VIRTUAL_TO_PHYSICAL2( + synthesisState->synthesisBuffers->dummyResampleState)); +#else aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( note->synthesisBuffers->dummyResampleState)); +#endif resampledTempLen = samplesLenAdjusted + 4; noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_ADPCM_RESAMPLED + 4; +#ifdef VERSION_EU + if (noteSubEu->finished != 0) { +#else if (note->finished != 0) { +#endif aClearBuffer(cmd++, - DMEM_ADDR_ADPCM_RESAMPLED + samplesLenAdjusted + 4, + DMEM_ADDR_ADPCM_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); } break; @@ -514,9 +1013,15 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { case 1: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_ADPCM_RESAMPLED2, samplesLenAdjusted + 8); +#ifdef VERSION_EU + aResample(cmd++, A_INIT, 0xff60, + VIRTUAL_TO_PHYSICAL2( + synthesisState->synthesisBuffers->dummyResampleState)); +#else aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( note->synthesisBuffers->dummyResampleState)); +#endif aDMEMMove(cmd++, DMEM_ADDR_ADPCM_RESAMPLED2 + 4, DMEM_ADDR_ADPCM_RESAMPLED + resampledTempLen, samplesLenAdjusted + 4); @@ -524,7 +1029,11 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { } } +#ifdef VERSION_EU + if (noteSubEu->finished != 0) { +#else if (note->finished != 0) { +#endif // ("break;" doesn't match) flags = 0; goto out; @@ -535,6 +1044,12 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { } out: +#ifdef VERSION_EU + if (noteSubEu->needsInit == TRUE) { + flags = A_INIT; + noteSubEu->needsInit = FALSE; + } +#else if (note->needsInit == TRUE) { flags = A_INIT; note->needsInit = FALSE; @@ -542,20 +1057,42 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { cmd = final_resample(cmd, note, bufLen * 2, resamplingRateFixedPoint, noteSamplesDmemAddrBeforeResampling, flags); +#endif +#ifndef VERSION_EU if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { s0 = 1; } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { s0 = 2; +#else + if (note->noteSubEu.headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { + s0 = 1; + } else if (note->noteSubEu.headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { + s0 = 2; +#endif } else { s0 = 0; } +#ifdef VERSION_EU + cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint, + noteSamplesDmemAddrBeforeResampling, flags); + cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0, s0); +#else cmd = process_envelope(cmd, note, bufLen, 0, s0, flags); +#endif + +#ifdef VERSION_EU + if (noteSubEu->usesHeadsetPanEffects) { + cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, s0); + } +#else if (note->usesHeadsetPanEffects) { cmd = note_apply_headset_pan_effects(cmd, note, bufLen * 2, flags, s0); } +#endif } +#ifndef VERSION_EU } t9 = bufLen * 2; @@ -564,20 +1101,44 @@ u64 *synthesis_process_notes(u16 *aiBuf, s32 bufLen, u64 *cmd) { t9 *= 2; aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); - return cmd; -} - -#elif defined(VERSION_JP) -GLOBAL_ASM("asm/non_matchings/synthesis_process_notes_jp.s") -#else -GLOBAL_ASM("asm/non_matchings/synthesis_process_notes_us.s") #endif + return cmd; +} +#elif defined(VERSION_JP) +GLOBAL_ASM("asm/non_matchings/synthesis_process_notes_jp.s") +#elif defined(VERSION_US) +GLOBAL_ASM("asm/non_matchings/synthesis_process_notes_us.s") +#elif defined(VERSION_EU) +GLOBAL_ASM("asm/non_matchings/eu/audio/synthesis_process_note.s") +#endif + +#ifdef VERSION_EU +u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { + s32 a3; + s32 i; + s32 repeats; + aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, /*count*/ 128); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples)); + synthesisState->samplePosInt &= 0x3f; + a3 = 64 - synthesisState->samplePosInt; + if (a3 < nSamplesToLoad) { + repeats = (nSamplesToLoad - a3 + 63) / 64; + for (i = 0; i < repeats; i++) { + aDMEMMove(cmd++, + /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, + /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * 128, + /*count*/ 128); + } + } + return cmd; +} +#else u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { s32 a3; s32 i; aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, - /*count*/ sizeof(note->synthesisBuffers->samples)); // interesting that it's 128... + /*count*/ sizeof(note->synthesisBuffers->samples)); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->samples)); note->samplePosInt = (note->sampleCount - 1) & note->samplePosInt; a3 = 64 - note->samplePosInt; @@ -592,13 +1153,23 @@ u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { } return cmd; } +#endif +#ifdef VERSION_EU +u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { + aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ 0, count); + aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); + return cmd; +} +#else u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags) { aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ 0, count); aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->finalResampleState)); return cmd; } +#endif +#ifndef VERSION_EU u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) { UNUSED u8 pad[16]; @@ -618,6 +1189,31 @@ u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf u8 mixerFlags; UNUSED u8 pad2[8]; s32 rampLeft, rampRight; +#else +u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings) { + UNUSED u8 pad1[20]; + u16 sourceRight; + u16 sourceLeft; + UNUSED u8 pad2[4]; + u16 targetLeft; + u16 targetRight; + s32 mixerFlags; + s32 rampLeft; + s32 rampRight; + + sourceLeft = synthesisState->curVolLeft; + sourceRight = synthesisState->curVolRight; + targetLeft = (note->targetVolLeft << 5); + targetRight = (note->targetVolRight << 5); + if (targetLeft == 0) { + targetLeft++; + } + if (targetRight == 0) { + targetRight++; + } + synthesisState->curVolLeft = targetLeft; + synthesisState->curVolRight = targetRight; +#endif // For aEnvMixer, five buffers and count are set using aSetBuffer. // in, dry left, count without A_AUX flag. @@ -663,24 +1259,49 @@ u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf } } +#ifdef VERSION_EU + if (targetLeft == sourceLeft && targetRight == sourceRight && !note->envMixerNeedsInit) { +#else if (vol->sourceLeft == vol->targetLeft && vol->sourceRight == vol->targetRight && !note->envMixerNeedsInit) { +#endif mixerFlags = A_CONTINUE; } else { mixerFlags = A_INIT; + +#ifdef VERSION_EU + rampLeft = gCurrentLeftVolRamping[targetLeft >> 5] * gCurrentRightVolRamping[sourceLeft >> 5]; + rampRight = gCurrentLeftVolRamping[targetRight >> 5] * gCurrentRightVolRamping[sourceRight >> 5]; +#else rampLeft = get_volume_ramping(vol->sourceLeft, vol->targetLeft, nSamples); rampRight = get_volume_ramping(vol->sourceRight, vol->targetRight, nSamples); +#endif // The operation's parameters change meanings depending on flags +#ifdef VERSION_EU + aSetVolume(cmd++, A_VOL | A_LEFT, sourceLeft, 0, 0); + aSetVolume(cmd++, A_VOL | A_RIGHT, sourceRight, 0, 0); + aSetVolume32(cmd++, A_RATE | A_LEFT, targetLeft, rampLeft); + aSetVolume32(cmd++, A_RATE | A_RIGHT, targetRight, rampRight); + aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVol << 8); +#else aSetVolume(cmd++, A_VOL | A_LEFT, vol->sourceLeft, 0, 0); aSetVolume(cmd++, A_VOL | A_RIGHT, vol->sourceRight, 0, 0); aSetVolume32(cmd++, A_RATE | A_LEFT, vol->targetLeft, rampLeft); aSetVolume32(cmd++, A_RATE | A_RIGHT, vol->targetRight, rampRight); aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVol); +#endif } + +#ifdef VERSION_EU + if (gUseReverb && note->reverbVol != 0) { + aEnvMixer(cmd++, mixerFlags | A_AUX, + VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->mixEnvelopeState)); +#else if (gSynthesisReverb.useReverb && note->reverb) { aEnvMixer(cmd++, mixerFlags | A_AUX, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); +#endif if (note->stereoStrongRight) { aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); // 0x8000 is -100%, so subtract sound instead of adding... @@ -696,7 +1317,11 @@ u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf /*out*/ DMEM_ADDR_WET_RIGHT_CH); } } else { +#ifdef VERSION_EU + aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->mixEnvelopeState)); +#else aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); +#endif if (note->stereoStrongRight) { aSetBuffer(cmd++, 0, 0, 0, nSamples * 2); aMix(cmd++, 0, /*gain*/ 0x8000, /*in*/ DMEM_ADDR_STEREO_STRONG_TEMP_DRY, @@ -710,25 +1335,43 @@ u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf return cmd; } +#if defined(VERSION_EU) && !defined(NON_MATCHING) +GLOBAL_ASM("asm/non_matchings/eu/audio/note_apply_headset_pan_effects.s") +#else +#ifdef VERSION_EU +u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight) { +#else u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight) { +#endif u16 dest; u16 prevPanShift; u16 panShift; u16 pitch; // t2 +#ifndef VERSION_EU UNUSED s32 padding[11]; +#endif switch (leftRight) { case 1: dest = DMEM_ADDR_LEFT_CH; note->prevHeadsetPanLeft = 0; +#ifndef VERSION_EU panShift = note->headsetPanRight; +#else + panShift = noteSubEu->headsetPanRight; +#endif prevPanShift = note->prevHeadsetPanRight; note->prevHeadsetPanRight = panShift; break; case 2: dest = DMEM_ADDR_RIGHT_CH; note->prevHeadsetPanRight = 0; +#ifndef VERSION_EU panShift = note->headsetPanLeft; +#else + panShift = noteSubEu->headsetPanLeft; +#endif + prevPanShift = note->prevHeadsetPanLeft; note->prevHeadsetPanLeft = panShift; break; @@ -787,6 +1430,10 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 return cmd; } +#endif + +#if !defined(VERSION_EU) +// Moved to playback.c in EU void note_init_volume(struct Note *note) { note->targetVolLeft = 0; @@ -899,3 +1546,4 @@ void note_disable(struct Note *note) { note->parentLayer = NO_LAYER; note->prevParentLayer = NO_LAYER; } +#endif diff --git a/src/audio/synthesis.h b/src/audio/synthesis.h index 16f6be9..c6c751b 100644 --- a/src/audio/synthesis.h +++ b/src/audio/synthesis.h @@ -6,7 +6,11 @@ #define DEFAULT_LEN_1CH 0x140 #define DEFAULT_LEN_2CH 0x280 +#ifdef VERSION_EU +#define MAX_UPDATES_PER_FRAME 5 +#else #define MAX_UPDATES_PER_FRAME 4 +#endif struct ReverbRingBufferItem { @@ -20,33 +24,52 @@ struct ReverbRingBufferItem struct SynthesisReverb { - u8 resampleFlags; - u8 useReverb; - u8 framesLeftToIgnore; - u8 curFrame; - u16 reverbGain; - u16 resampleRate; - s32 nextRingBufferPos; - s32 unkC; // never read - s32 bufSizePerChannel; + /*0x00, 0x00*/ u8 resampleFlags; + /*0x01, 0x01*/ u8 useReverb; + /*0x02, 0x02*/ u8 framesLeftToIgnore; + /*0x03, 0x03*/ u8 curFrame; +#ifdef VERSION_EU + /* 0x04*/ u8 downsampleRate; + /* 0x06*/ u16 windowSize; // same as bufSizePerChannel +#endif + /*0x04, 0x08*/ u16 reverbGain; + /*0x06, 0x0A*/ u16 resampleRate; + /*0x08, 0x0C*/ s32 nextRingBufferPos; + /*0x0C, 0x10*/ s32 unkC; // never read + /*0x10, 0x14*/ s32 bufSizePerChannel; struct { s16 *left; s16 *right; } ringBuffer; - s16 *resampleStateLeft; - s16 *resampleStateRight; - s16 *unk24; // never read - s16 *unk28; // never read - struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME]; + /*0x1C, 0x20*/ s16 *resampleStateLeft; + /*0x20, 0x24*/ s16 *resampleStateRight; + /*0x24, 0x28*/ s16 *unk24; // never read + /*0x28, 0x2C*/ s16 *unk28; // never read + /*0x2C, 0x30*/ struct ReverbRingBufferItem items[2][MAX_UPDATES_PER_FRAME]; +#ifdef VERSION_EU + u8 pad[16]; +#endif }; // 0xCC <= size <= 0x100 +#if defined(VERSION_EU) +extern struct SynthesisReverb gSynthesisReverbs[4]; +extern s8 gNumSynthesisReverbs; +extern struct NoteSubEu *gNoteSubsEu; +extern f32 gLeftVolRampings[3][1024]; +extern f32 gRightVolRampings[3][1024]; +extern f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above +extern f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above +#else extern struct SynthesisReverb gSynthesisReverb; +#endif u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, u16 *aiBuf, s32 bufLen); +#ifndef VERSION_EU void note_init_volume(struct Note *note); void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverb); void note_set_frequency(struct Note *note, f32 frequency); void note_enable(struct Note *note); void note_disable(struct Note *note); +#endif #endif /* AUDIO_SYNTHESIS_H */ diff --git a/src/buffers/buffers.c b/src/buffers/buffers.c index a5a9bb0..4184397 100644 --- a/src/buffers/buffers.c +++ b/src/buffers/buffers.c @@ -3,8 +3,25 @@ #include "buffers.h" ALIGNED8 u8 gDecompressionHeap[0xD000]; - +#ifdef VERSION_EU +ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200) - 0x3800]; +#else ALIGNED16 u8 gAudioHeap[DOUBLE_SIZE_ON_64_BIT(0x31200)]; +#endif + +ALIGNED8 u8 gIdleThreadStack[0x800]; +ALIGNED8 u8 gThread3Stack[0x2000]; +ALIGNED8 u8 gThread4Stack[0x2000]; +ALIGNED8 u8 gThread5Stack[0x2000]; +// 0x400 bytes +ALIGNED8 u8 gGfxSPTaskStack[SP_DRAM_STACK_SIZE8]; +// 0xc00 bytes for f3dex, 0x900 otherwise +ALIGNED8 u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; +// 0x200 bytes +ALIGNED8 struct SaveBuffer gSaveBuffer; +// 0x190a0 bytes +struct GfxPool gGfxPools[2]; + // Yield buffer for audio, 0x400 bytes. Stubbed out post-JP since the audio // task never yields. @@ -14,23 +31,11 @@ ALIGNED8 u8 gAudioSPTaskYieldBuffer[OS_YIELD_AUDIO_SIZE]; // Probably Thread 2 stack space. Unreferenced, and stubbed out with f3dex to // avoid an overflowing .buffers segment. -#ifndef F3DEX_GBI_SHARED +#if !defined(F3DEX_GBI_SHARED) && !defined(VERSION_EU) ALIGNED8 u8 gUnusedThread2Stack[0x1400]; #endif -ALIGNED8 u8 gIdleThreadStack[0x800]; -ALIGNED8 u8 gThread3Stack[0x2000]; -ALIGNED8 u8 gThread4Stack[0x2000]; -ALIGNED8 u8 gThread5Stack[0x2000]; -// 0xc00 bytes for f3dex, 0x900 otherwise -ALIGNED8 u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; -// 0x200 bytes -ALIGNED8 struct SaveBuffer gSaveBuffer; -// 0x400 bytes -ALIGNED8 u8 gGfxSPTaskStack[SP_DRAM_STACK_SIZE8]; -// 0x190a0 bytes -struct GfxPool gGfxPools[2]; diff --git a/src/engine/geo_layout.c b/src/engine/geo_layout.c index 3f450fd..ce36617 100644 --- a/src/engine/geo_layout.c +++ b/src/engine/geo_layout.c @@ -44,6 +44,7 @@ GeoLayoutCommandProc GeoLayoutJumpTable[] = { geo_layout_cmd_node_culling_radius, }; +struct GraphNode gObjParentGraphNode; struct AllocOnlyPool *gGraphNodePool; struct GraphNode *gCurRootGraphNode; @@ -98,7 +99,6 @@ s16 gGeoLayoutStackIndex; // similar to SP register in MIPS UNUSED s16 D_8038BD7C; s16 gGeoLayoutReturnIndex; // similar to RA register in MIPS u8 *gGeoLayoutCommand; -struct GraphNode gObjParentGraphNode; u32 unused_8038B894[3] = { 0 }; diff --git a/src/engine/level_script.c b/src/engine/level_script.c index bad25cf..328b672 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -372,7 +372,11 @@ static void level_cmd_end_area(void) { static void level_cmd_load_model_from_dl(void) { s16 val1 = CMD_GET(s16, 2) & 0x0FFF; +#ifdef VERSION_EU + s16 val2 = (CMD_GET(s16, 2) & 0xFFFF) >> 12; +#else s16 val2 = CMD_GET(u16, 2) >> 12; +#endif void *val3 = CMD_GET(void *, 4); if (val1 < 256) { @@ -401,7 +405,11 @@ static void level_cmd_23(void) { } arg2; s16 model = CMD_GET(s16, 2) & 0x0FFF; +#ifdef VERSION_EU + s16 arg0H = (CMD_GET(s16, 2) & 0xFFFF) >> 12; +#else s16 arg0H = CMD_GET(u16, 2) >> 12; +#endif void *arg1 = CMD_GET(void *, 4); // load an f32, but using an integer load instruction for some reason (hence the union) arg2.i = CMD_GET(s32, 8); diff --git a/src/engine/math_util.c b/src/engine/math_util.c index beb60c5..61a095d 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -159,17 +159,12 @@ void mtxf_copy(Mat4 dest, Mat4 src) { void mtxf_identity(Mat4 mtx) { register s32 i; register f32 *dest; - + // Note: These loops need to be on one line to match on PAL // initialize everything except the first and last cells to 0 - // (this need to be on one line to match on PAL) - for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) { - *dest = 0; - } + for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0; // initialize the diagonal cells to 1 - for (dest = (f32 *) mtx, i = 0; i < 4; dest += 5, i++) { - *dest = 1; - } + for (dest = (f32 *) mtx, i = 0; i < 4; dest += 5, i++) *dest = 1; } /** diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index f746373..10c46b5 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -9,7 +9,6 @@ #include "surface_collision.h" #include "surface_load.h" #include "game/object_list_processor.h" -#include "game/room.h" /************************************************** * WALLS * @@ -21,6 +20,9 @@ */ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, struct WallCollisionData *data) { +#ifdef VERSION_EU + UNUSED u8 pad; +#endif register f32 offset; register f32 radius = data->radius; register struct Surface *surf; @@ -60,12 +62,8 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, // the fact they are floating point, certain floating point positions // along the seam of two walls may collide with neither wall or both walls. if (surf->flags & SURFACE_FLAG_X_PROJECTION) { - w1 = -surf->vertex1[2]; - w2 = -surf->vertex2[2]; - w3 = -surf->vertex3[2]; - y1 = surf->vertex1[1]; - y2 = surf->vertex2[1]; - y3 = surf->vertex3[1]; + w1 = -surf->vertex1[2]; w2 = -surf->vertex2[2]; w3 = -surf->vertex3[2]; + y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1]; if (surf->normal.x > 0.0f) { if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) > 0.0f) { @@ -89,12 +87,8 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, } } } else { - w1 = surf->vertex1[0]; - w2 = surf->vertex2[0]; - w3 = surf->vertex3[0]; - y1 = surf->vertex1[1]; - y2 = surf->vertex2[1]; - y3 = surf->vertex3[1]; + w1 = surf->vertex1[0]; w2 = surf->vertex2[0]; w3 = surf->vertex3[0]; + y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1]; if (surf->normal.z > 0.0f) { if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) > 0.0f) { @@ -370,7 +364,7 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) { /** * Find the height of the highest floor below an object. */ -static f32 unused_obj_find_floor_height(struct Object *obj) { +f32 unused_obj_find_floor_height(struct Object *obj) { struct Surface *floor; f32 floorHeight = find_floor(obj->oPosX, obj->oPosY, obj->oPosZ, &floor); return floorHeight; @@ -496,7 +490,7 @@ f32 find_floor_height(f32 x, f32 y, f32 z) { * Find the highest dynamic floor under a given position. Perhaps originally static and * and dynamic floors were checked separately. */ -static f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) { +f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) { struct SurfaceNode *surfaceList; struct Surface *floor; f32 floorHeight = -11000.0f; @@ -749,10 +743,12 @@ void debug_surface_list_info(f32 xPos, f32 zPos) { * An unused function that finds and interacts with any type of surface. * Perhaps an original implementation of surfaces before they were more specialized. */ -static s32 unused_resolve_floor_or_ceil_collisions(s32 checkCeil, f32 *px, f32 *py, f32 *pz, f32 radius, +s32 unused_resolve_floor_or_ceil_collisions(s32 checkCeil, f32 *px, f32 *py, f32 *pz, f32 radius, struct Surface **psurface, f32 *surfaceHeight) { f32 nx, ny, nz, oo; - f32 x = *px, y = *py, z = *pz; + f32 x = *px; + f32 y = *py; + f32 z = *pz; f32 offset, distance; *psurface = NULL; diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 757692b..32a6a24 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -13,7 +13,6 @@ #include "surface_collision.h" #include "game/mario.h" #include "game/object_list_processor.h" -#include "game/room.h" #include "surface_load.h" s32 unused8038BE90; @@ -601,17 +600,19 @@ static void unused_80383604(void) { /** * Applies an object's tranformation to the object's vertices. */ -static void transform_object_vertices(s16 **data, s16 *vertexData) { +void transform_object_vertices(s16 **data, s16 *vertexData) { register s16 *vertices; + +#ifdef VERSION_EU + register f32 vx, vy, vz; register s32 numVertices; - - register f32 vx; - register f32 vy; - register f32 vz; +#else + register s32 numVertices; + register f32 vx, vy, vz; +#endif Mat4 *objectTransform; Mat4 m; - UNUSED s16 unused; objectTransform = &gCurrentObject->transform; @@ -646,7 +647,7 @@ static void transform_object_vertices(s16 **data, s16 *vertexData) { * Load in the surfaces for the gCurrentObject. This includes setting the flags, * exertion, and room. */ -static void load_object_surfaces(s16 **data, s16 *vertexData) { +void load_object_surfaces(s16 **data, s16 *vertexData) { s32 surfaceType; s32 i; s32 numSurfaces; diff --git a/src/game/area.c b/src/game/area.c index 240605d..126bca4 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -106,7 +106,7 @@ void print_intro_text(void) { #endif } else { #ifdef VERSION_EU - print_text_centered(20, 20, "START"); + print_text(20, 20, "START"); #else print_text_centered(60, 38, "PRESS"); print_text_centered(60, 20, "START"); diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index 5975679..028530e 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -35,7 +35,6 @@ #include "platform_displacement.h" #include "interaction.h" #include "ingame_menu.h" -#include "room.h" #include "rendering_graph_node.h" #include "level_table.h" @@ -211,10 +210,8 @@ Gfx *Geo18_802B1BB0(s32 run, UNUSED struct GraphNode *node, Mat4 mtx) { #include "behaviors/boo_cage.inc.c" // not in behavior file -void func_802B2328( - s32 n, s32 a1, s32 a2, - s32 r) // n is the number of objects to spawn, r if the rate of change of phase (frequency?) -{ +// n is the number of objects to spawn, r if the rate of change of phase (frequency?) +void func_802B2328(s32 n, s32 a1, s32 a2, s32 r) { s32 i; s16 separation = 0x10000 / n; // Evenly spread around a circle for (i = 0; i < n; i++) { @@ -222,6 +219,10 @@ void func_802B2328( coss(D_8035FF10 + i * separation) * a1, o, MODEL_NONE, bhvSparkleSpawn); } + if (1) + { + } + D_8035FF10 += r * 0x100; } diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index b6b1d2a..5e6989c 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -525,7 +525,7 @@ void bhv_racing_penguin_init(void); void bhv_racing_penguin_update(void); void bhv_penguin_race_finish_line_update(void); void bhv_penguin_race_shortcut_check_update(void); -void bhv_coffin_manager_loop(void); +void bhv_coffin_spawner_loop(void); void bhv_coffin_loop(void); void bhv_clam_loop(void); void bhv_skeeter_update(void); diff --git a/src/game/behaviors/activated_bf_plat.inc.c b/src/game/behaviors/activated_bf_plat.inc.c index cef1535..9a8fd49 100644 --- a/src/game/behaviors/activated_bf_plat.inc.c +++ b/src/game/behaviors/activated_bf_plat.inc.c @@ -58,7 +58,7 @@ void bhv_activated_back_and_forth_platform_init(void) { } /** - * Activated back-and-forth platform update function. + * Activated back-and-forth platform update function. */ void bhv_activated_back_and_forth_platform_update(void) { UNUSED s32 unused[3]; diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c index 5a257ad..f5510f0 100644 --- a/src/game/behaviors/bobomb.inc.c +++ b/src/game/behaviors/bobomb.inc.c @@ -99,7 +99,7 @@ void BobombChaseMarioLoop(void) { void BobombLaunchedLoop(void) { s16 collisionFlags = 0; collisionFlags = object_step(); - if ((collisionFlags & 0x1) == 1) + if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) == OBJ_COL_FLAG_GROUNDED) o->oAction = BOBOMB_ACT_EXPLODE; /* bit 0 */ } @@ -307,7 +307,7 @@ void BobombBuddyIdleLoop(void) { /** * Function for the Bob-omb Buddy cannon guy. - * dialogFirstText is the first dialogID called when Bob-omb Buddy + * dialogFirstText is the first dialogID called when Bob-omb Buddy * starts to talk to Mario to prepare the cannon(s) for him. * Then the camera goes to the nearest cannon, to play the "prepare cannon" cutscene * dialogSecondText is called after Bob-omb Buddy has the cannon(s) ready and @@ -361,7 +361,8 @@ void BobombBuddyTalkLoop(void) { switch (o->oBobombBuddyRole) { case BOBOMB_BUDDY_ROLE_ADVICE: - if (cutscene_object_with_dialog(CUTSCENE_DIALOG, 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/boo.inc.c b/src/game/behaviors/boo.inc.c index 1b9aaf6..71cc885 100644 --- a/src/game/behaviors/boo.inc.c +++ b/src/game/behaviors/boo.inc.c @@ -541,14 +541,11 @@ static void ActionBooGivingStar1(void) { f32 sp1C; if (o->oHealth == 3) { - sp22 = 0x180; - sp1C = 0.5f; + sp22 = 0x180; sp1C = 0.5f; } else if (o->oHealth == 2) { - sp22 = 0x240; - sp1C = 0.6f; + sp22 = 0x240; sp1C = 0.6f; } else { - sp22 = 0x300; - sp1C = 0.8f; + sp22 = 0x300; sp1C = 0.8f; } boo_chase_mario(-100.0f, sp22, sp1C); diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index fe75441..2f4fb51 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -831,9 +831,9 @@ s32 func_802B5F20(void) { void func_802B60B8(void) { obj_scale(0); - o->oForwardVel = 0.0f; - o->oVelY = 0.0f; - o->oGravity = 0.0f; + o->oForwardVel = 0; + o->oVelY = 0; + o->oGravity = 0; } s32 func_802B6120(void) { @@ -1448,7 +1448,7 @@ void bhv_flame_bowser_loop(void) { obj_become_tangible(); if (o->oTimer > o->oFlameUnkF4 * 10 + 5.0f) { o->oFlameUnkF4 -= 0.15; - if (o->oFlameUnkF4 <= 0.0f) + if (o->oFlameUnkF4 <= 0) func_802B7A58(); } } diff --git a/src/game/behaviors/bully.inc.c b/src/game/behaviors/bully.inc.c index e06de12..8e3df29 100644 --- a/src/game/behaviors/bully.inc.c +++ b/src/game/behaviors/bully.inc.c @@ -177,8 +177,10 @@ void BullyStep(void) { void BullySpawnCoin(void) { struct Object *coin = spawn_object(o, MODEL_YELLOW_COIN, bhvMovingYellowCoin); -#ifdef VERSION_JP +#ifdef VERSION_JP //TODO: maybe move this ifdef logic to the header? PlaySound2(SOUND_GENERAL_COIN_SPURT); +#elif VERSION_EU + PlaySound2(SOUND_GENERAL_COIN_SPURT_EU); #else PlaySound2(SOUND_GENERAL_COIN_SPURT_2); #endif diff --git a/src/game/behaviors/butterfly.inc.c b/src/game/behaviors/butterfly.inc.c index dcb3555..94421e3 100644 --- a/src/game/behaviors/butterfly.inc.c +++ b/src/game/behaviors/butterfly.inc.c @@ -27,7 +27,7 @@ void ButterflyStep(s32 speed) { o->oPosZ += o->oVelZ; if (o->oAction == BUTTERFLY_ACT_FOLLOW_MARIO) - o->oPosY -= o->oVelY + coss((s32)(yPhase * 655.36)) * 20.0f / 4.0f; + o->oPosY -= o->oVelY + coss((s32)(yPhase * 655.36)) * 20.0f / 4; else o->oPosY -= o->oVelY; diff --git a/src/game/behaviors/cap.inc.c b/src/game/behaviors/cap.inc.c index 3287247..fb8c14c 100644 --- a/src/game/behaviors/cap.inc.c +++ b/src/game/behaviors/cap.inc.c @@ -50,18 +50,26 @@ void func_802F09C0(void) { case SURFACE_MOVING_QUICKSAND: o->oAction = 11; o->oMoveAngleYaw = (sObjFloor->force & 0xFF) << 8; +#if defined(VERSION_EU) && !defined(NON_MATCHING) + o->oForwardVel = 8 - ((sObjFloor->force & 0xff00) >> 8) * 2; +#else o->oForwardVel = -((sObjFloor->force & 0xff00) >> 8) * 2 + 8; +#endif break; case SURFACE_INSTANT_QUICKSAND: o->oAction = 12; - o->oForwardVel = 0; + o->oForwardVel = 0.0f; break; case SURFACE_INSTANT_MOVING_QUICKSAND: o->oAction = 13; o->oMoveAngleYaw = (sObjFloor->force & 0xFF) << 8; +#if defined(VERSION_EU) && !defined(NON_MATCHING) + o->oForwardVel = 8 - ((sObjFloor->force & 0xff00) >> 8) * 2; +#else o->oForwardVel = -((sObjFloor->force & 0xff00) >> 8) * 2 + 8; +#endif break; } } diff --git a/src/game/behaviors/chain_chomp.inc.c b/src/game/behaviors/chain_chomp.inc.c index 6763402..c28db1c 100644 --- a/src/game/behaviors/chain_chomp.inc.c +++ b/src/game/behaviors/chain_chomp.inc.c @@ -298,7 +298,7 @@ static void chain_chomp_released_lunge_around(void) { o->oHomeX = 1450.0f; o->oHomeZ = 562.0f; o->oMoveAngleYaw = obj_angle_to_home(); - o->oForwardVel = obj_lateral_dist_to_home() / 8.0f; + o->oForwardVel = obj_lateral_dist_to_home() / 8; o->oVelY = 50.0f; } } diff --git a/src/game/behaviors/cloud.inc.c b/src/game/behaviors/cloud.inc.c index dab6f71..addfa20 100644 --- a/src/game/behaviors/cloud.inc.c +++ b/src/game/behaviors/cloud.inc.c @@ -129,7 +129,7 @@ static void cloud_act_main(void) { cloud_fwoosh_update(); } - localOffset = 2.0f * coss(localOffsetPhase) * o->header.gfx.scale[0]; + localOffset = 2 * coss(localOffsetPhase) * o->header.gfx.scale[0]; o->oPosX = o->oCloudCenterX + localOffset; o->oPosY = o->oCloudCenterY + localOffset + 12.0f * o->header.gfx.scale[0]; @@ -193,7 +193,7 @@ void bhv_cloud_part_update(void) { } // Move back and forth along (1, 1, 1) - localOffset = 2.0f * coss(localOffsetPhase) * size; + localOffset = 2 * coss(localOffsetPhase) * size; cloudRadius = 25.0f * size; diff --git a/src/game/behaviors/coffin.inc.c b/src/game/behaviors/coffin.inc.c index 1e4f99b..ff8d575 100644 --- a/src/game/behaviors/coffin.inc.c +++ b/src/game/behaviors/coffin.inc.c @@ -1,80 +1,112 @@ -// coffin.inc.c +/** + * Behavior for bhvCoffinSpawner and bhvCoffin. + * The coffins are spawned by a singular spawner, + * with half being able to stand up. + * Coffins unload after leaving the room. + */ -struct Struct80331C00 { - s16 unk00; - s16 unk02; +/** + * Struct with s16 values for a horizontal position. + */ +struct LateralPosition { + s16 x; + s16 z; }; -struct Struct80331C00 D_80331C00[] = { - { 0x019C, 0xFF6A }, { 0x02FA, 0xFF6A }, { 0x0458, 0xFF6A }, - { 0x019C, 0x0096 }, { 0x02FA, 0x0096 }, { 0x0458, 0x0096 }, +/** + * Array of positions for all coffins relative to their spawner. + */ +struct LateralPosition coffinRelativePos[] = { + { 412, -150 }, { 762, -150 }, { 1112, -150 }, + { 412, 150 }, { 762, 150 }, { 1112, 150 }, }; -void bhv_coffin_manager_loop(void) { - struct Object *val0C; - s32 val08; - s16 val06; +/** + * Loop behavior for the object that spawns the six coffins in BBH. + * Loads the coffins when in the room, they unload themselves. + */ +void bhv_coffin_spawner_loop(void) { + struct Object *coffin; + s32 i; + s16 relativeZ; - if (o->oAction == 0) { - if (!(o->activeFlags & 0x0008)) { - for (val08 = 0; val08 < 6; val08++) { - val06 = D_80331C00[val08].unk02; + if (o->oAction == COFFIN_SPAWNER_ACT_COFFINS_UNLOADED) { + if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { + for (i = 0; i < 6; i++) { + relativeZ = coffinRelativePos[i].z; - val0C = spawn_object_relative(val08 & 0x00000001, D_80331C00[val08].unk00, 0, val06, o, + // Behavior param of 0 for all even i, 1 for all odd + coffin = spawn_object_relative(i & 1, coffinRelativePos[i].x, 0, relativeZ, o, MODEL_BBH_WOODEN_TOMB, bhvCoffin); - if (val0C != NULL) { - if (val06 > 0) { - val0C->oFaceAngleYaw = 0x8000; + + // Never true, game would enter a while(1) before it could. + // Possible a remnant of days this didn't happen. + if (coffin != NULL) { + // Rotate the coffin 180 degrees if its on the other side of the room. + if (relativeZ > 0) { + coffin->oFaceAngleYaw = 0x8000; } } } o->oAction += 1; } - } else if (o->activeFlags & 0x0008) { - o->oAction = 0; + } else if (o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) { + o->oAction = COFFIN_SPAWNER_ACT_COFFINS_UNLOADED; } } -void coffin_act_0(void) { - f32 val14; - f32 val10; - f32 val0C; - f32 val08; - f32 val04; - f32 val00; +/** + * The main action for the coffins. Coffins with COFFIN_BP_STATIC skip the behavior, while + * the other coffins will enter a standing action when Mario is near. + * Also controls laying the coffin down after it has stood up. + */ +void coffin_act_idle(void) { + f32 yawCos; + f32 yawSin; + f32 dx; + f32 dz; + f32 distForwards; + f32 distSideways; - if (o->oBehParams2ndByte != 0) { + if (o->oBehParams2ndByte != COFFIN_BP_STATIC) { + // Lay down if standing if (o->oFaceAnglePitch != 0) { o->oAngleVelPitch = approach_s16_symmetric(o->oAngleVelPitch, -2000, 200); + // If the coffin landed... if (obj_face_pitch_approach(0, -o->oAngleVelPitch)) { PlaySound2(SOUND_GENERAL_ELEVATOR_MOVE_2); - obj_perform_position_op(0); - o->oMoveAngleYaw = o->oFaceAngleYaw - 0x4000; + // This bit changes the coffin's position, + // spawns dust there, then resets the position. + obj_perform_position_op(POS_OP_SAVE_POSITION); + o->oMoveAngleYaw = o->oFaceAngleYaw - 0x4000; obj_set_dist_from_home(200.0f); func_802ADA94(); - obj_perform_position_op(2); + obj_perform_position_op(POS_OP_RESTORE_POSITION); } o->oTimer = 0; } else { - val14 = coss(o->oFaceAngleYaw); - val10 = sins(o->oFaceAngleYaw); + // Yaw never changes and is aligned, so yawCos = 1 or -1, yawSin = 0 + yawCos = coss(o->oFaceAngleYaw); + yawSin = sins(o->oFaceAngleYaw); - val0C = gMarioObject->oPosX - o->oPosX; - val08 = gMarioObject->oPosZ - o->oPosZ; + dx = gMarioObject->oPosX - o->oPosX; + dz = gMarioObject->oPosZ - o->oPosZ; - val04 = val0C * val14 + val08 * val10; - val00 = val08 * val14 - val0C * val10; + distForwards = dx * yawCos + dz * yawSin; + distSideways = dz * yawCos - dx * yawSin; + // This checks a box around the coffin and if it has been a bit since it stood up. + // It also checks in the case Mario is squished, so he doesn't get permanently squished. if (o->oTimer > 60 && (o->oDistanceToMario > 100.0f || gMarioState->action == ACT_SQUISHED)) { - if (gMarioObject->oPosY - o->oPosY < 200.0f && absf(val04) < 140.0f) { - if (val00 < 150.0f && val00 > -450.0f) { + if (gMarioObject->oPosY - o->oPosY < 200.0f && absf(distForwards) < 140.0f) { + if (distSideways < 150.0f && distSideways > -450.0f) { PlaySound2(SOUND_GENERAL_BUTTON_PRESS_2_LOWPRIO); - o->oAction = 1; + o->oAction = COFFIN_ACT_STAND_UP; } } } @@ -84,18 +116,24 @@ void coffin_act_0(void) { } } -void coffin_act_1(void) { +/** + * Stand up the coffin and keep it standing until the timer hits 60. + */ +void coffin_act_stand_up(void) { + // Stand up if (o->oFaceAnglePitch != 0x4000) { o->oAngleVelPitch = approach_s16_symmetric(o->oAngleVelPitch, 1000, 200); obj_face_pitch_approach(0x4000, o->oAngleVelPitch); } else { + // Stay standing if (o->oTimer > 60) { - o->oAction = 0; + o->oAction = COFFIN_ACT_IDLE; o->oFaceAngleRoll = 0; } else if (o->oTimer > 30) { if (gGlobalTimer % 4 == 0) { PlaySound2(SOUND_GENERAL_ELEVATOR_MOVE_2); } + // Shake the coffin while its standing o->oFaceAngleRoll = 400 * (gGlobalTimer % 2) - 200; } @@ -103,18 +141,24 @@ void coffin_act_1(void) { } } +/** + * Main behavior for each coffin. Unloads the coffin if the spawner enters + * that action. + */ void bhv_coffin_loop(void) { - if (o->parentObj->oAction == 0) { + // Gotta save those 6 object slots + if (o->parentObj->oAction == COFFIN_SPAWNER_ACT_COFFINS_UNLOADED) { mark_object_for_deletion(o); } else { + // Scale the coffin vertically? Must have thought it was too short? o->header.gfx.scale[1] = 1.1f; switch (o->oAction) { - case 0: - coffin_act_0(); + case COFFIN_ACT_IDLE: + coffin_act_idle(); break; - case 1: - coffin_act_1(); + case COFFIN_ACT_STAND_UP: + coffin_act_stand_up(); break; } diff --git a/src/game/behaviors/coin.inc.c b/src/game/behaviors/coin.inc.c index 74d74fc..e593ba7 100644 --- a/src/game/behaviors/coin.inc.c +++ b/src/game/behaviors/coin.inc.c @@ -75,8 +75,10 @@ void bhv_coin_loop(void) { } } if (o->oTimer == 0) -#ifndef VERSION_JP +#ifdef VERSION_US PlaySound2(SOUND_GENERAL_COIN_SPURT_2); +#elif VERSION_EU + PlaySound2(SOUND_GENERAL_COIN_SPURT_EU); #else PlaySound2(SOUND_GENERAL_COIN_SPURT); #endif diff --git a/src/game/behaviors/door.inc.c b/src/game/behaviors/door.inc.c index a9cf4b9..a174bee 100644 --- a/src/game/behaviors/door.inc.c +++ b/src/game/behaviors/door.inc.c @@ -1,6 +1,12 @@ // door.c.inc -s32 D_8032F300[][2] = { { 0x40000, 3 }, { 0x80000, 4 }, { 0x10000, 1 }, { 0x20000, 2 }, { -1, 0 }, }; +struct DoorAction +{ + u32 flag; + s32 action; +}; + +struct DoorAction D_8032F300[] = { { 0x40000, 3 }, { 0x80000, 4 }, { 0x10000, 1 }, { 0x20000, 2 }, { -1, 0 }, }; s32 D_8032F328[] = { SOUND_GENERAL_OPEN_WOOD_DOOR, SOUND_GENERAL_OPEN_IRON_DOOR }; @@ -39,13 +45,15 @@ void func_802AC1CC(void) { void bhv_door_loop(void) { s32 sp1C = 0; - while (D_8032F300[sp1C][0] != -1) { - if (obj_clear_interact_status_flag(D_8032F300[sp1C][0])) { + + while (D_8032F300[sp1C].flag != (u32)~0) { + if (obj_clear_interact_status_flag(D_8032F300[sp1C].flag)) { func_802AC0B8(); - obj_change_action(D_8032F300[sp1C][1]); + obj_change_action(D_8032F300[sp1C].action); } sp1C++; } + switch (o->oAction) { case 0: set_obj_animation_and_sound_state(0); diff --git a/src/game/behaviors/dorrie.inc.c b/src/game/behaviors/dorrie.inc.c index 9a78a4c..08b4371 100644 --- a/src/game/behaviors/dorrie.inc.c +++ b/src/game/behaviors/dorrie.inc.c @@ -1,5 +1,5 @@ -static void dorrie_raise_head(void) { +void dorrie_raise_head(void) { s16 startAngle; f32 xzDisp; f32 yDisp; @@ -15,7 +15,7 @@ static void dorrie_raise_head(void) { gMarioObject->oPosZ + xzDisp * coss(o->oMoveAngleYaw)); } -static void dorrie_act_move(void) { +void dorrie_act_move(void) { s16 startYaw; s16 targetYaw; s16 targetSpeed; @@ -54,13 +54,13 @@ static void dorrie_act_move(void) { o->oAngleVelYaw = o->oMoveAngleYaw - startYaw; } -static void dorrie_begin_head_raise(s32 liftingMario) { +void dorrie_begin_head_raise(s32 liftingMario) { o->oDorrieLiftingMario = liftingMario; o->oAction = DORRIE_ACT_RAISE_HEAD; o->oDorrieHeadRaiseSpeed = 0; } -static void dorrie_act_lower_head(void) { +void dorrie_act_lower_head(void) { if (func_802F92EC(2, 35)) { func_8029F6F0(); @@ -92,7 +92,7 @@ static void dorrie_act_lower_head(void) { } } -static void dorrie_act_raise_head(void) { +void dorrie_act_raise_head(void) { o->collisionData = segmented_to_virtual(dorrie_seg6_collision_0600F644); if (func_8029F788()) { o->oAction = DORRIE_ACT_MOVE; diff --git a/src/game/behaviors/elevator.inc.c b/src/game/behaviors/elevator.inc.c index 6782c2c..cd899ad 100644 --- a/src/game/behaviors/elevator.inc.c +++ b/src/game/behaviors/elevator.inc.c @@ -88,12 +88,12 @@ void bhv_elevator_init(void) { if (sp1C == 0) { o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3]; o->oElevatorUnkF8 = o->oHomeY; - o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2.0f; + o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2; o->oElevatorUnk100 = obj_has_behavior(bhvRrElevatorPlatform); } else { o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3]; o->oElevatorUnkF8 = D_8032F38C[o->oBehParams2ndByte * 3 + 1]; - o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2.0f; + o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2; o->oElevatorUnk100 = 2; } } diff --git a/src/game/behaviors/enemy_lakitu.inc.c b/src/game/behaviors/enemy_lakitu.inc.c index 00c6a20..8ac298f 100644 --- a/src/game/behaviors/enemy_lakitu.inc.c +++ b/src/game/behaviors/enemy_lakitu.inc.c @@ -83,7 +83,7 @@ static void enemy_lakitu_update_speed_and_angle(void) { } // Change move angle toward mario faster when farther from mario - turnSpeed = (s16)(distToMario * 2.0f); + turnSpeed = (s16)(distToMario * 2); clamp_s16(&turnSpeed, 0xC8, 0xFA0); obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed); } diff --git a/src/game/behaviors/fire_piranha_plant.inc.c b/src/game/behaviors/fire_piranha_plant.inc.c index 0a6c0a2..cb9ff34 100644 --- a/src/game/behaviors/fire_piranha_plant.inc.c +++ b/src/game/behaviors/fire_piranha_plant.inc.c @@ -44,9 +44,7 @@ void bhv_fire_piranha_plant_init(void) { o->oNumLootCoins = 2; } } - - sNumKilledFirePiranhaPlants = 0; - sNumActiveFirePiranhaPlants = 0; + sNumActiveFirePiranhaPlants = sNumKilledFirePiranhaPlants = 0; } static void fire_piranha_plant_act_hide(void) { @@ -114,7 +112,7 @@ static void fire_piranha_plant_act_grow(void) { } } } - } else if (o->oFirePiranhaPlantScale > o->oFirePiranhaPlantNeutralScale / 2.0f) { + } else if (o->oFirePiranhaPlantScale > o->oFirePiranhaPlantNeutralScale / 2) { obj_become_tangible(); } } diff --git a/src/game/behaviors/fish.inc.c b/src/game/behaviors/fish.inc.c index 541d00d..8549fe3 100644 --- a/src/game/behaviors/fish.inc.c +++ b/src/game/behaviors/fish.inc.c @@ -9,28 +9,16 @@ void ActionFish0(void) { struct Object *sp28; switch (o->oBehParams2ndByte) { case 0: - model = MODEL_FISH; - sp38 = 20; - sp30 = 1500.0f; - sp2C = blue_fish_seg3_anims_0301C2B0; + model = MODEL_FISH; sp38 = 20; sp30 = 1500.0f; sp2C = blue_fish_seg3_anims_0301C2B0; break; case 1: - model = MODEL_FISH; - sp38 = 5; - sp30 = 1500.0f; - sp2C = blue_fish_seg3_anims_0301C2B0; + model = MODEL_FISH; sp38 = 5; sp30 = 1500.0f; sp2C = blue_fish_seg3_anims_0301C2B0; break; case 2: - model = MODEL_CYAN_FISH; - sp38 = 20; - sp30 = 1500.0f; - sp2C = cyan_fish_seg6_anims_0600E264; + model = MODEL_CYAN_FISH; sp38 = 20; sp30 = 1500.0f; sp2C = cyan_fish_seg6_anims_0600E264; break; case 3: - model = MODEL_CYAN_FISH; - sp38 = 5; - sp30 = 1500.0f; - sp2C = cyan_fish_seg6_anims_0600E264; + model = MODEL_CYAN_FISH; sp38 = 5; sp30 = 1500.0f; sp2C = cyan_fish_seg6_anims_0600E264; break; } if (o->oDistanceToMario < sp30 || gCurrLevelNum == LEVEL_SA) { diff --git a/src/game/behaviors/floating_platform.inc.c b/src/game/behaviors/floating_platform.inc.c index 20ceff2..7cf4aef 100644 --- a/src/game/behaviors/floating_platform.inc.c +++ b/src/game/behaviors/floating_platform.inc.c @@ -17,10 +17,10 @@ f32 func_802F54F8(void) { } void func_802F55CC(void) { - s16 sp6 = (gMarioObject->header.gfx.pos[0] - o->oPosX) * coss(-o->oMoveAngleYaw) - + (gMarioObject->header.gfx.pos[2] - o->oPosZ) * sins(-o->oMoveAngleYaw); - s16 sp4 = (gMarioObject->header.gfx.pos[2] - o->oPosZ) * coss(-o->oMoveAngleYaw) - - (gMarioObject->header.gfx.pos[0] - o->oPosX) * sins(-o->oMoveAngleYaw); + s16 sp6 = (gMarioObject->header.gfx.pos[0] - o->oPosX) * coss(-1*o->oMoveAngleYaw) + + (gMarioObject->header.gfx.pos[2] - o->oPosZ) * sins(-1*o->oMoveAngleYaw); + s16 sp4 = (gMarioObject->header.gfx.pos[2] - o->oPosZ) * coss(-1*o->oMoveAngleYaw) + - (gMarioObject->header.gfx.pos[0] - o->oPosX) * sins(-1*o->oMoveAngleYaw); if (gMarioObject->platform == o) { o->oFaceAnglePitch = sp4 * 2; diff --git a/src/game/behaviors/goomba.inc.c b/src/game/behaviors/goomba.inc.c index afcfc34..71f5723 100644 --- a/src/game/behaviors/goomba.inc.c +++ b/src/game/behaviors/goomba.inc.c @@ -85,8 +85,7 @@ void bhv_goomba_triplet_spawner_update(void) { 0x10000 / (((o->oBehParams2ndByte & GOOMBA_TRIPLET_SPAWNER_BP_EXTRA_GOOMBAS_MASK) >> 2) + 3); - goombaFlag = 1 << 8; - for (angle = 0; angle < 0xFFFF; angle += dAngle, goombaFlag <<= 1) { + for (angle = 0, goombaFlag = 1 << 8; angle < 0xFFFF; angle += dAngle, goombaFlag <<= 1) { // Only spawn goombas which haven't been killed yet if (!(o->oBehParams & goombaFlag)) { dx = 500.0f * coss(angle); diff --git a/src/game/behaviors/hoot.inc.c b/src/game/behaviors/hoot.inc.c index 551a763..6441965 100644 --- a/src/game/behaviors/hoot.inc.c +++ b/src/game/behaviors/hoot.inc.c @@ -61,9 +61,9 @@ void HootFreeStep(s16 fastOscY, s32 speed) { o->oPosX += o->oVelX; if (fastOscY == 0) - o->oPosY -= o->oVelY + coss((s32)(sp26 * 3276.8)) * 50.0f / 4.0f; + o->oPosY -= o->oVelY + coss((s32)(sp26 * 3276.8)) * 50.0f / 4; else - o->oPosY -= o->oVelY + coss((s32)(sp26 * 6553.6)) * 50.0f / 4.0f; + o->oPosY -= o->oVelY + coss((s32)(sp26 * 6553.6)) * 50.0f / 4; o->oPosZ += o->oVelZ; find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &sp2c); @@ -104,7 +104,7 @@ void HootCarryStep(s32 speed, UNUSED f32 xPrev, UNUSED f32 zPrev) { o->oVelZ = coss(yaw) * hSpeed; o->oPosX += o->oVelX; - o->oPosY -= o->oVelY + coss((s32)(sp22 * 6553.6)) * 50.0f / 4.0f; + o->oPosY -= o->oVelY + coss((s32)(sp22 * 6553.6)) * 50.0f / 4; o->oPosZ += o->oVelZ; if (sp22 == 0) diff --git a/src/game/behaviors/intro_lakitu.inc.c b/src/game/behaviors/intro_lakitu.inc.c index b117fec..8b06a04 100644 --- a/src/game/behaviors/intro_lakitu.inc.c +++ b/src/game/behaviors/intro_lakitu.inc.c @@ -118,7 +118,11 @@ void bhv_intro_lakitu_loop(void) { #endif break; case 2: +#ifdef VERSION_EU + if (gCutsceneTimer > 599) { +#else if (gCutsceneTimer > 720) { +#endif gCurrentObject->oAction += 1; gCurrentObject->oIntroLakituUnk100 = 1400.f; gCurrentObject->oIntroLakituUnk104 = -4096.f; diff --git a/src/game/behaviors/klepto.inc.c b/src/game/behaviors/klepto.inc.c index f9a57a7..94dfdab 100644 --- a/src/game/behaviors/klepto.inc.c +++ b/src/game/behaviors/klepto.inc.c @@ -121,7 +121,7 @@ static void klepto_change_target(void) { o->oHomeY = sKleptoTargetPositions[o->oKleptoTargetNumber][1] + o->oKleptoUnkF8; o->oHomeZ = sKleptoTargetPositions[o->oKleptoTargetNumber][2]; - o->oKleptoUnkFC = obj_lateral_dist_to_home() / 2.0f; + o->oKleptoUnkFC = obj_lateral_dist_to_home() / 2; } static void klepto_circle_target(f32 radius, f32 targetSpeed) { diff --git a/src/game/behaviors/moneybag.inc.c b/src/game/behaviors/moneybag.inc.c index 169ebbf..674a557 100644 --- a/src/game/behaviors/moneybag.inc.c +++ b/src/game/behaviors/moneybag.inc.c @@ -127,7 +127,7 @@ void MoneybagMoveAroundLoop(void) { MoneybagCheckMarioCollision(); if (!is_point_within_radius_of_mario(o->oHomeX, o->oHomeY, o->oHomeZ, 800) - && ((collisionFlags & 0x9) == 9)) + && ((collisionFlags & OBJ_COL_FLAGS_LANDED) == OBJ_COL_FLAGS_LANDED)) o->oAction = MONEYBAG_ACT_RETURN_HOME; } diff --git a/src/game/behaviors/monty_mole.inc.c b/src/game/behaviors/monty_mole.inc.c index 8e0b03a..87c1b39 100644 --- a/src/game/behaviors/monty_mole.inc.c +++ b/src/game/behaviors/monty_mole.inc.c @@ -178,11 +178,25 @@ void bhv_monty_mole_hole_update(void) { /** * Spawn dirt particles when rising out of the ground. + * + * TODO: (Scrub C) monty_mole_spawn_dirt_particles, water_bomb_spawn_explode_particles, and + * func_80306ED4 all have similar issues with their functions, none of which match legitimately. */ -static void monty_mole_spawn_dirt_particles(s8 offsetY, s8 velYBase) { +void monty_mole_spawn_dirt_particles(s8 offsetY, s8 velYBase) { +#if defined(VERSION_JP) || defined(VERSION_US) sMontyMoleRiseFromGroundParticles.offsetY = offsetY; sMontyMoleRiseFromGroundParticles.velYBase = velYBase; obj_spawn_particles(&sMontyMoleRiseFromGroundParticles); +#else + s8 tempVelYBase = velYBase; + s8 tempOffsetY = offsetY; + + do { + sMontyMoleRiseFromGroundParticles.offsetY = tempOffsetY; + sMontyMoleRiseFromGroundParticles.velYBase = tempVelYBase; + obj_spawn_particles(&sMontyMoleRiseFromGroundParticles); + } while (0); +#endif } /** diff --git a/src/game/behaviors/mr_blizzard.inc.c b/src/game/behaviors/mr_blizzard.inc.c index ed06f84..826a6bd 100644 --- a/src/game/behaviors/mr_blizzard.inc.c +++ b/src/game/behaviors/mr_blizzard.inc.c @@ -1,4 +1,3 @@ - struct ObjectHitbox sMrBlizzardHitbox = { /* interactType: */ INTERACT_MR_BLIZZARD, /* downOffset: */ 24, @@ -38,13 +37,34 @@ struct ObjectHitbox sMrBlizzardSnowballHitbox = { /* hurtboxHeight: */ 25, }; -static void func_80306ED4(s8 arg0, s8 arg1, s8 arg2, s8 arg3, s8 arg4) { - D_80331A00.count = arg0; - D_80331A00.offsetY = arg1; - D_80331A00.forwardVelBase = arg2; - D_80331A00.velYBase = arg3; - D_80331A00.sizeBase = arg4; +/** + * TODO: (Scrub C) monty_mole_spawn_dirt_particles, water_bomb_spawn_explode_particles, and + * func_80306ED4 all have similar issues with their functions, none of which match legitimately. + */ +void func_80306ED4(s8 count, s8 offsetY, s8 forwardVelBase, s8 velYBase, s8 sizeBase) { +#if defined(VERSION_JP) || defined(VERSION_US) + D_80331A00.count = count; + D_80331A00.offsetY = offsetY; + D_80331A00.forwardVelBase = forwardVelBase; + D_80331A00.velYBase = velYBase; + D_80331A00.sizeBase = sizeBase; obj_spawn_particles(&D_80331A00); +#else + s8 tempSizeBase = sizeBase; + s8 tempVelYBase = velYBase; + s8 tempForwardVelBase = forwardVelBase; + s8 tempOffsetY = offsetY; + s8 tempCount = count; + + do { + D_80331A00.count = tempCount; + D_80331A00.offsetY = tempOffsetY; + D_80331A00.forwardVelBase = tempForwardVelBase; + D_80331A00.velYBase = tempVelYBase; + D_80331A00.sizeBase = tempSizeBase; + obj_spawn_particles(&D_80331A00); + } while (0); +#endif } void bhv_mr_blizzard_init(void) { diff --git a/src/game/behaviors/piranha_plant.inc.c b/src/game/behaviors/piranha_plant.inc.c index 66b1cc4..4fe0f18 100644 --- a/src/game/behaviors/piranha_plant.inc.c +++ b/src/game/behaviors/piranha_plant.inc.c @@ -106,7 +106,7 @@ void piranha_plant_act_sleeping(void) { * to the biting state. */ void piranha_plant_act_woken_up(void) { -#if BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE +#if BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE || defined(VERSION_EU) /** * Make Piranha Plants damage the player while awake. This call is only * necessary in the US version because it is set to 3 by default and is diff --git a/src/game/behaviors/pokey.inc.c b/src/game/behaviors/pokey.inc.c index a0ef3a0..beb284e 100644 --- a/src/game/behaviors/pokey.inc.c +++ b/src/game/behaviors/pokey.inc.c @@ -64,7 +64,7 @@ void bhv_pokey_body_part_update(void) { o->parentObj->oPokeyAliveBodyPartFlags | 1 << (o->oBehParams2ndByte - 1); o->parentObj->oPokeyAliveBodyPartFlags = - o->parentObj->oPokeyAliveBodyPartFlags & ((1 << o->oBehParams2ndByte) ^ 0xFFFFFFFF); + o->parentObj->oPokeyAliveBodyPartFlags & ((1 << o->oBehParams2ndByte) ^ ~0); o->oBehParams2ndByte -= 1; } @@ -118,7 +118,7 @@ void bhv_pokey_body_part_update(void) { } o->parentObj->oPokeyAliveBodyPartFlags = - o->parentObj->oPokeyAliveBodyPartFlags & ((1 << o->oBehParams2ndByte) ^ 0xFFFFFFFF); + o->parentObj->oPokeyAliveBodyPartFlags & ((1 << o->oBehParams2ndByte) ^ ~0); } else if (o->parentObj->oPokeyHeadWasKilled) { obj_become_intangible(); diff --git a/src/game/behaviors/rolling_log.inc.c b/src/game/behaviors/rolling_log.inc.c index 473e499..4d11918 100644 --- a/src/game/behaviors/rolling_log.inc.c +++ b/src/game/behaviors/rolling_log.inc.c @@ -22,8 +22,8 @@ void func_802F238C(void) { f32 sp24; if (gMarioObject->platform == o) { - sp24 = (gMarioObject->header.gfx.pos[2] - o->oPosZ) * coss(-o->oMoveAngleYaw) - - (gMarioObject->header.gfx.pos[0] - o->oPosX) * sins(-o->oMoveAngleYaw); + sp24 = (gMarioObject->header.gfx.pos[2] - o->oPosZ) * coss(-1*o->oMoveAngleYaw) + - (gMarioObject->header.gfx.pos[0] - o->oPosX) * sins(-1*o->oMoveAngleYaw); if (sp24 > 0) o->oAngleVelPitch += 0x10; else diff --git a/src/game/behaviors/ttc_moving_bar.inc.c b/src/game/behaviors/ttc_moving_bar.inc.c index 2b4641c..d0d9a73 100644 --- a/src/game/behaviors/ttc_moving_bar.inc.c +++ b/src/game/behaviors/ttc_moving_bar.inc.c @@ -100,7 +100,7 @@ static void ttc_moving_bar_act_extend(void) { && o->oTTCMovingBarSpeed > -8.0f && o->oTTCMovingBarSpeed < 8.0f) { // Begin retracting o->oAction = TTC_MOVING_BAR_ACT_RETRACT; - o->oTTCMovingBarSpeed = 0; + o->oTTCMovingBarSpeed = 0.0f; } else { f32 accel; diff --git a/src/game/behaviors/ttc_treadmill.inc.c b/src/game/behaviors/ttc_treadmill.inc.c index 79546d4..2f24d8b 100644 --- a/src/game/behaviors/ttc_treadmill.inc.c +++ b/src/game/behaviors/ttc_treadmill.inc.c @@ -21,13 +21,6 @@ static s16 sTTCTreadmillSpeeds[] = { /* TTC_SPEED_STOPPED */ 0, }; -// TODO: bss - -/** - * The treadmill that plays sounds and controls the others on random setting. - */ -struct Object *sMasterTreadmill; - extern s16 ttc_movtex_tris_big_surface_treadmill[]; extern s16 ttc_movtex_tris_small_surface_treadmill[]; diff --git a/src/game/behaviors/tuxie.inc.c b/src/game/behaviors/tuxie.inc.c index 89f2d0f..776113e 100644 --- a/src/game/behaviors/tuxie.inc.c +++ b/src/game/behaviors/tuxie.inc.c @@ -26,7 +26,7 @@ void ActionTuxiesMother2(void) { f32 sp24; UNUSED s32 unused; struct Object *sp1C = obj_find_nearest_object_with_behavior(bhvSmallPenguin, &sp24); - UNUSED s32 unused2; + if (obj_find_nearby_held_actor(bhvUnused20E0, 1000.0f) != NULL) { if (o->oSubAction == 0) { set_obj_animation_and_sound_state(0); diff --git a/src/game/behaviors/tweester.inc.c b/src/game/behaviors/tweester.inc.c index 3b7db63..a5b99be 100644 --- a/src/game/behaviors/tweester.inc.c +++ b/src/game/behaviors/tweester.inc.c @@ -1,102 +1,156 @@ -// tweester.c.inc +/** + * Behavior file for bhvTweester and bhvTweesterSandParticle + * Tweester swaps between twhree action- an idle action, a chasing + * Mario action, and an action that hides it. At certain times the + * Tweester spawns the sand particles also in this file. + */ struct ObjectHitbox sTweesterHitbox = { - /* interactType: */ INTERACT_TORNADO, - /* downOffset: */ 0, + /* interactType: */ INTERACT_TORNADO, + /* downOffset: */ 0, /* damageOrCoinValue: */ 0, - /* health: */ 0, - /* numLootCoins: */ 0, - /* radius: */ 1500, - /* height: */ 4000, - /* hurtboxRadius: */ 0, - /* hurtboxHeight: */ 0, + /* health: */ 0, + /* numLootCoins: */ 0, + /* radius: */ 1500, + /* height: */ 4000, + /* hurtboxRadius: */ 0, + /* hurtboxHeight: */ 0, }; -void func_802C231C(f32 a0) { - s16 sp6 = 0x2C00; - f32 sp0 = a0 * 0.4; - o->header.gfx.scale[0] = (((coss(o->oTweesterUnkF4) + 1.0) * 0.5 * 0.3) + 1.0) * sp0; - o->header.gfx.scale[1] = (((-coss(o->oTweesterUnkF4) + 1.0) * 0.5 * 0.5) + 0.5) * sp0; - o->header.gfx.scale[2] = (((coss(o->oTweesterUnkF4) + 1.0) * 0.5 * 0.3) + 1.0) * sp0; - o->oTweesterUnkF4 += 0x200; +/** + * Controls the scaling of the tweester as well as + * its forward velocity. + */ +void tweester_scale_and_move(f32 preScale) { + s16 dYaw = 0x2C00; + f32 scale = preScale * 0.4; + + o->header.gfx.scale[0] + = (( coss(o->oTweesterScaleTimer) + 1.0) * 0.5 * 0.3 + 1.0) * scale; + o->header.gfx.scale[1] + = ((-coss(o->oTweesterScaleTimer) + 1.0) * 0.5 * 0.5 + 0.5) * scale; + o->header.gfx.scale[2] + = (( coss(o->oTweesterScaleTimer) + 1.0) * 0.5 * 0.3 + 1.0) * scale; + + o->oTweesterScaleTimer += 0x200; o->oForwardVel = 14.0f; - o->oFaceAngleYaw += sp6; + o->oFaceAngleYaw += dYaw; } -void ActionTweester0(void) { - if (o->oSubAction == 0) { +/** + * Tweester's idle action. Basically stays in active until Mario enters a 1500 + * radius, at which point it appears and grows for 60 frames at which point it + * it enters the chasing action. + */ +void tweester_act_idle(void) { + if (o->oSubAction == TWEESTER_SUB_ACT_WAIT) { obj_become_tangible(); obj_set_pos_to_home(); obj_scale(0); - o->oTweesterUnkF8 = 0; + + // Hard to have any idea of this purpose, only set here. + o->oTweesterUnused = 0; + + // If Mario is within range, change to the growth sub-action. if (o->oDistanceToMario < 1500.0f) o->oSubAction++; + o->oTimer = 0; } else { PlaySound(SOUND_ENV_WIND1); - func_802C231C(o->oTimer / 60.0f); + tweester_scale_and_move(o->oTimer / 60.0f); if (o->oTimer > 59) - o->oAction = 1; + o->oAction = TWEESTER_ACT_CHASE; } } -void ActionTweester1(void) { - f32 sp1C = o->oBehParams2ndByte * 0x64; - o->oUnk1BC = obj_angle_to_home(); +/** + * Action where the tweester "chases" Mario. + * After Mario is twirling, then return home. + */ +void tweester_act_chase(void) { + f32 activationRadius = o->oBehParams2ndByte * 100; + + o->oAngleToHome = obj_angle_to_home(); PlaySound(SOUND_ENV_WIND1); - if (obj_lateral_dist_from_mario_to_home() < sp1C && o->oSubAction == 0) { + + if (obj_lateral_dist_from_mario_to_home() < activationRadius + && o->oSubAction == TWEESTER_SUB_ACT_CHASE) { + o->oForwardVel = 20.0f; obj_rotate_yaw_toward(o->oAngleToMario, 0x200); print_debug_top_down_objectinfo("off ", 0); + if (gMarioStates->action == ACT_TWIRLING) o->oSubAction++; } else { o->oForwardVel = 20.0f; - obj_rotate_yaw_toward(o->oUnk1BC, 0x200); + obj_rotate_yaw_toward(o->oAngleToHome, 0x200); + if (obj_lateral_dist_to_home() < 200.0f) - o->oAction = 2; + o->oAction = TWEESTER_ACT_HIDE; } + if (o->oDistanceToMario > 3000.0f) - o->oAction = 2; + o->oAction = TWEESTER_ACT_HIDE; + obj_update_floor_and_walls(); - if (o->oMoveFlags & 0x200) + if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) o->oMoveAngleYaw = o->oWallAngle; + obj_move_standard(60); - func_802C231C(1.0f); - spawn_object(o, MODEL_SAND_DUST, bhvTornadoSandParticle); + tweester_scale_and_move(1.0f); + spawn_object(o, MODEL_SAND_DUST, bhvTweesterSandParticle); } -void ActionTweester2(void) { - f32 sp1C = 60.0f - o->oTimer; - if (sp1C >= 0.0f) - func_802C231C(sp1C / 60.0f); +/** + * Shrinks the tweester until it is invisible, then returns to the idle + * action if Mario is 2500 units away or 12 seconds passed. + */ +void tweester_act_hide(void) { + f32 shrinkTimer = 60.0f - o->oTimer; + + if (shrinkTimer >= 0.0f) + tweester_scale_and_move(shrinkTimer / 60.0f); else { obj_become_intangible(); if (obj_lateral_dist_from_mario_to_home() > 2500.0f) - o->oAction = 0; + o->oAction = TWEESTER_ACT_IDLE; if (o->oTimer > 360) - o->oAction = 0; + o->oAction = TWEESTER_ACT_IDLE; } } -void (*sTweesterActions[])(void) = { ActionTweester0, ActionTweester1, ActionTweester2 }; +// Array of Tweester action functions. +void (*sTweesterActions[])(void) = { tweester_act_idle, tweester_act_chase, tweester_act_hide }; +/** + * Loop behavior for Tweester. + * Loads the hitbox and calls its relevant action. + */ void bhv_tweester_loop(void) { set_object_hitbox(o, &sTweesterHitbox); obj_call_action_function(sTweesterActions); o->oInteractStatus = 0; } +/** + * Loop behavior for the particles Tweesters create. + * Floats upwards semi-randomly. + */ void bhv_tweester_sand_particle_loop(void) { o->oMoveAngleYaw += 0x3700; o->oForwardVel += 15.0f; o->oPosY += 22.0f; + obj_scale(RandomFloat() + 1.0); + if (o->oTimer == 0) { translate_object_xz_random(o, 100.0f); o->oFaceAnglePitch = RandomU16(); o->oFaceAngleYaw = RandomU16(); } + if (o->oTimer > 15) mark_object_for_deletion(o); } diff --git a/src/game/behaviors/water_bomb.inc.c b/src/game/behaviors/water_bomb.inc.c index be79408..7674dca 100644 --- a/src/game/behaviors/water_bomb.inc.c +++ b/src/game/behaviors/water_bomb.inc.c @@ -96,12 +96,28 @@ void bhv_water_bomb_spawner_update(void) { /** * Spawn particles when the water bomb explodes. + * + * TODO: (Scrub C) monty_mole_spawn_dirt_particles, water_bomb_spawn_explode_particles, and + * func_80306ED4 all have similar issues with their functions, none of which match legitimately. */ -static void water_bomb_spawn_explode_particles(s8 offsetY, s8 forwardVelRange, s8 velYBase) { +void water_bomb_spawn_explode_particles(s8 offsetY, s8 forwardVelRange, s8 velYBase) { +#if defined(VERSION_JP) || defined(VERSION_US) sWaterBombExplodeParticles.offsetY = offsetY; sWaterBombExplodeParticles.forwardVelRange = forwardVelRange; sWaterBombExplodeParticles.velYBase = velYBase; obj_spawn_particles(&sWaterBombExplodeParticles); +#else + s8 tempVelYBase = velYBase; + s8 tempForwardVelRange = forwardVelRange; + s8 tempOffsetY = offsetY; + + do { + sWaterBombExplodeParticles.offsetY = tempOffsetY; + sWaterBombExplodeParticles.forwardVelRange = tempForwardVelRange; + sWaterBombExplodeParticles.velYBase = tempVelYBase; + obj_spawn_particles(&sWaterBombExplodeParticles); + } while (0); +#endif } /** diff --git a/src/game/behaviors/wiggler.inc.c b/src/game/behaviors/wiggler.inc.c index b0eba77..a94631b 100644 --- a/src/game/behaviors/wiggler.inc.c +++ b/src/game/behaviors/wiggler.inc.c @@ -115,7 +115,7 @@ void bhv_wiggler_body_part_update(void) { /** * Initialize the segment data and spawn the body part objects. */ -static void wiggler_init_segments(void) { +void wiggler_init_segments(void) { s32 i; struct ChainSegment *segments; struct Object *bodyPart; @@ -127,14 +127,14 @@ static void wiggler_init_segments(void) { // represents body part i. o->oWigglerSegments = segments; for (i = 0; i <= 3; i++) { - chain_segment_init(&segments[i]); + chain_segment_init(segments + i); - segments[i].posX = o->oPosX; - segments[i].posY = o->oPosY; - segments[i].posZ = o->oPosZ; + (segments + i)->posX = o->oPosX; + (segments + i)->posY = o->oPosY; + (segments + i)->posZ = o->oPosZ; - segments[i].pitch = o->oFaceAnglePitch; - segments[i].yaw = o->oFaceAngleYaw; + (segments + i)->pitch = o->oFaceAnglePitch; + (segments + i)->yaw = o->oFaceAngleYaw; } o->header.gfx.unk38.animFrame = -1; @@ -152,6 +152,10 @@ static void wiggler_init_segments(void) { o->oAction = WIGGLER_ACT_WALK; obj_unhide(); } + +#if defined(VERSION_EU) || defined(AVOID_UB) + o->oHealth = 4; // This fixes Wiggler reading UB on his first frame of his acceleration, as his health is not set. +#endif } /** @@ -161,7 +165,7 @@ static void wiggler_init_segments(void) { * for a body part to get stuck on geometry and separate from the rest of the * body. */ -static void wiggler_update_segments(void) { + void wiggler_update_segments(void) { struct ChainSegment *prevBodyPart; struct ChainSegment *bodyPart; f32 dx; @@ -230,8 +234,8 @@ static void wiggler_act_walk(void) { } else { //! Every object's health is initially 2048, and wiggler's doesn't change // to 4 until after this runs the first time. It indexes out of bounds - // and uses the value 113762.3 for one frame on US. This is fixed down - // below in bhv_wiggler_update if AVOID_UB is defined. + // and uses the value 113762.3 for one frame on US. This is fixed up + // in wiggler_init_segments if AVOID_UB is defined. obj_forward_vel_approach(sWigglerSpeeds[o->oHealth - 1], 1.0f); if (o->oWigglerWalkAwayFromWallTimer != 0) { @@ -280,7 +284,6 @@ static void wiggler_act_walk(void) { } } } - /** * Squish and unsquish, then show text and enter either the walking or shrinking * action. @@ -399,10 +402,6 @@ void bhv_wiggler_update(void) { // PARTIAL_UPDATE if (o->oAction == WIGGLER_ACT_UNINITIALIZED) { -#ifdef AVOID_UB - // See comment in wiggler_act_walk - o->oHealth = 4; -#endif wiggler_init_segments(); } else { if (o->oAction == WIGGLER_ACT_FALL_THROUGH_FLOOR) { diff --git a/src/game/camera.c b/src/game/camera.c index af8dc34..ed3428b 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -18,7 +18,6 @@ #include "ingame_menu.h" #include "mario_actions_cutscene.h" #include "save_file.h" -#include "room.h" #include "object_helpers.h" #include "object_helpers2.h" #include "print.h" @@ -27,7 +26,6 @@ #include "behavior_data.h" #include "object_list_processor.h" #include "paintings.h" -#include "prevent_bss_reordering.h" #include "engine/graph_node.h" #include "level_table.h" @@ -78,12 +76,6 @@ */ // BSS - -/** - * 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() */ @@ -92,6 +84,11 @@ Vec3f sOldPosition; * Stores lakitu's focus from the last frame, used for transitioning in next_lakitu_state() */ Vec3f sOldFocus; +/** + * Global array of PlayerCameraState. + * L is real. + */ +struct PlayerCameraState gPlayerCameraState[2]; /** * Direction controlled by player 2, moves the focus during the credits. */ @@ -109,16 +106,107 @@ s16 sCreditsPlayer2Yaw; */ u8 sFramesPaused; +#ifndef VERSION_EU +extern struct CameraFOVStatus sFOVState; +extern struct TransitionInfo sModeTransition; +extern struct PlayerGeometry sMarioGeometry; +extern s16 unusedFreeRoamWallYaw; +extern s16 sAvoidYawVel; +extern s16 sCameraYawAfterDoorCutscene; +extern s16 unusedSplinePitch; +extern s16 unusedSplineYaw; +extern struct HandheldShakePoint sHandheldShakeSpline[4]; +extern s16 sHandheldShakeMag; +extern f32 sHandheldShakeTimer; +extern f32 sHandheldShakeInc; +extern s16 sHandheldShakePitch; +extern s16 sHandheldShakeYaw; +extern s16 sHandheldShakeRoll; +extern u32 unused8033B30C; +extern u32 unused8033B310; +extern s16 sSelectionFlags; +extern s16 unused8033B316; +extern s16 s2ndRotateFlags; +extern s16 unused8033B31A; +extern s16 sCameraSoundFlags; +extern u16 sCButtonsPressed; +extern s16 sCutsceneDialogID; +extern struct LakituState gLakituState; +extern s16 unused8033B3E8; +extern s16 sAreaYaw; +extern s16 sAreaYawChange; +extern s16 sLakituDist; +extern s16 sLakituPitch; +extern f32 sZoomAmount; +extern s16 sCSideButtonYaw; +extern s16 sBehindMarioSoundTimer; +extern f32 sZeroZoomDist; +extern s16 sCUpCameraPitch; +extern s16 sModeOffsetYaw; +extern s16 sSpiralStairsYawOffset; +extern s16 s8DirModeBaseYaw; +extern s16 s8DirModeYawOffset; +extern f32 sPanDistance; +extern f32 sCannonYOffset; +extern struct ModeTransitionInfo sModeInfo; +extern Vec3f sCastleEntranceOffset; +extern u32 sParTrackIndex; +extern struct ParallelTrackingPoint *sParTrackPath; +extern struct CameraStoredInfo sParTrackTransOff; +extern struct CameraStoredInfo sCameraStoreCUp; +extern struct CameraStoredInfo sCameraStoreCutscene; +extern s16 gCameraMovementFlags; +extern s16 sStatusFlags; +extern struct CutsceneSplinePoint sCurCreditsSplinePos[32]; +extern struct CutsceneSplinePoint sCurCreditsSplineFocus[32]; +extern s16 sCutsceneSplineSegment; +extern f32 sCutsceneSplineSegmentProgress; +extern s16 unused8033B6E8; +extern s16 sCutsceneShot; +extern s16 gCutsceneTimer; +extern struct CutsceneVariable sCutsceneVars[10]; +extern s32 gObjCutsceneDone; +extern u32 gCutsceneObjSpawn; +extern struct Camera *gCamera; +#endif + +/** + * Lakitu's position and focus. + * @see LakituState + */ +struct LakituState gLakituState; struct CameraFOVStatus sFOVState; struct TransitionInfo sModeTransition; struct PlayerGeometry sMarioGeometry; +struct Camera *gCamera; s16 unusedFreeRoamWallYaw; s16 sAvoidYawVel; s16 sCameraYawAfterDoorCutscene; +/** + * 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]; s16 unusedSplinePitch; s16 unusedSplineYaw; +/** + * The progress (from 0 to 1) through the current spline segment. + * When it becomes >= 1, 1.0 is subtracted from it and sCutsceneSplineSegment is increased. + */ +f32 sCutsceneSplineSegmentProgress; + +/** + * The current segment of the CutsceneSplinePoint[] being used. + */ +s16 sCutsceneSplineSegment; +s16 unused8033B6E8; + // Shaky Hand-held Camera effect variables struct HandheldShakePoint sHandheldShakeSpline[4]; s16 sHandheldShakeMag; @@ -128,13 +216,36 @@ s16 sHandheldShakePitch; s16 sHandheldShakeYaw; s16 sHandheldShakeRoll; +/** + * Controls which object to spawn in the intro and ending cutscenes. + */ +u32 gCutsceneObjSpawn; +/** + * Controls when an object-based cutscene should end. It's only used in the star spawn cutscenes, but + * yoshi also toggles this. + */ +s32 gObjCutsceneDone; + u32 unused8033B30C; u32 unused8033B310; + /** * Determines which R-Trigger mode is selected in the pause menu. */ s16 sSelectionFlags; + +/** + * Flags that determine what movements the camera should start / do this frame. + */ +s16 gCameraMovementFlags; s16 unused8033B316; + +/** + * 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; /** * 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. @@ -154,11 +265,17 @@ u16 sCButtonsPressed; */ s16 sCutsceneDialogID; /** - * Lakitu's position and focus. - * @see LakituState + * The currently playing shot in the cutscene. */ -struct LakituState gLakituState; +s16 sCutsceneShot; +/** + * The current frame of the cutscene shot. + */ +s16 gCutsceneTimer; s16 unused8033B3E8; +#ifdef VERSION_EU +s16 unused8033B3E82; +#endif /** * The angle of the direction vector from the area's center to mario's position. */ @@ -231,8 +348,13 @@ f32 sPanDistance; * This is used to make the camera start up and rotate down, like the cannon. */ f32 sCannonYOffset; +/** + * 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]; struct ModeTransitionInfo sModeInfo; - /** * Offset added to sFixedModeBasePosition when mario is inside, near the castle lobby entrance */ @@ -267,65 +389,6 @@ struct CameraStoredInfo sCameraStoreCUp; */ struct CameraStoredInfo sCameraStoreCutscene; -/** - * Flags that determine what movements the camera should start / do this frame. - */ -s16 gCameraMovementFlags; - -/** - * 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. - */ -s16 sCutsceneSplineSegment; - -/** - * The progress (from 0 to 1) through the current spline segment. - * When it becomes >= 1, 1.0 is subtracted from it and sCutsceneSplineSegment is increased. - */ -f32 sCutsceneSplineSegmentProgress; -s16 unused8033B6E8; -/** - * The currently playing shot in the cutscene. - */ -s16 sCutsceneShot; -/** - * The current frame of the cutscene shot. - */ -s16 gCutsceneTimer; - -/** - * 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 unused8032CFC0 = 0; struct Object *gCutsceneFocus = NULL; @@ -598,8 +661,9 @@ void unused_set_camera_pitch_shake_env(s16 shake) { * 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 + *! Doesn't return anything, but required to match EU */ -void calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 focMul, f32 focBound) { +f32 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; @@ -1305,7 +1369,7 @@ s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { pathAngle[1] = pathYaw; //! No effect // make marioOffset[2] == distance from the start of the path - marioOffset[2] = pathLength / 2.f - marioOffset[2]; + marioOffset[2] = pathLength / 2 - marioOffset[2]; pathAngle[1] = pathYaw + DEGREES(180); pathAngle[2] = 0; @@ -1315,7 +1379,7 @@ s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { 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]; + focOffset[2] = pathLength / 2 - focOffset[2]; offset_rotated(c->focus, path[0], focOffset, pathAngle); // Changing paths, update the stored position offset @@ -1351,12 +1415,12 @@ s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { // 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); + 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); + 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) { @@ -1387,7 +1451,7 @@ s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) { Vec3s faceAngle; struct Surface *ceiling; Vec3f basePos; - UNUSED u8 filler[16]; + UNUSED u8 filler[12]; play_camera_buzz_if_c_sideways(); @@ -1548,10 +1612,9 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { } } + //! Must be same line to match EU // Prevent the camera from going to the ground in the outside boss fight - if (gCurrLevelNum == LEVEL_BBH) { - pos[1] = 2047.f; - } + if (gCurrLevelNum == LEVEL_BBH) { pos[1] = 2047.f; } // Rotate from C-Button input if (sCSideButtonYaw < 0) { @@ -1644,7 +1707,7 @@ struct ParallelTrackingPoint sBBHLibraryParTrackPath[] = { s32 unused_update_mode_5_camera(UNUSED struct Camera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { } -void unused_80282678(UNUSED s32 unused) { +static void unused_80282678(UNUSED s32 unused) { } void mode_boss_fight_camera(struct Camera *c) { @@ -2660,7 +2723,7 @@ void move_into_c_up(struct Camera *c) { * The main update function for C-Up mode */ s32 mode_c_up_camera(struct Camera *c) { - UNUSED u8 unused[16]; + UNUSED u8 unused[12]; // Play a sound when entering C-Up mode if (!(sCameraSoundFlags & CAM_SOUND_C_UP_PLAYED)) { @@ -2725,8 +2788,8 @@ void mode_cannon_camera(struct Camera *c) { 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; + sPanDistance = 0.f; + sCannonYOffset = 0.f; sStatusFlags &= ~CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; } else { sCannonYOffset = approach_f32(sCannonYOffset, 0.f, 100.f, 100.f); @@ -3394,11 +3457,11 @@ void zoom_out_if_paused_and_outside(struct GraphNodeCamera *camera) { areaBit = 0; } if (gCameraMovementFlags & CAM_MOVE_PAUSE_SCREEN) { - if (sFramesPaused > 1) { + if (sFramesPaused >= 2) { if (sZoomOutAreaMasks[areaMaskIndex] & areaBit) { camera->focus[0] = gCamera->areaCenX; - camera->focus[1] = (sMarioCamState->pos[1] + gCamera->areaCenY) / 2.f; + camera->focus[1] = (sMarioCamState->pos[1] + gCamera->areaCenY) / 2; 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); @@ -4216,8 +4279,8 @@ s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 p 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; + //! Must be same line to match EU + pitch -= goalPitch; yaw -= goalYaw; dist -= 2000.f; if (dist < 0.f) { dist = 0.f; @@ -5507,9 +5570,9 @@ void parallel_tracking_init(struct Camera *c, struct ParallelTrackingPoint *path 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; + c->pos[0] = (sParTrackPath[0].pos[0] + sParTrackPath[1].pos[0]) / 2; + c->pos[1] = (sParTrackPath[0].pos[1] + sParTrackPath[1].pos[1]) / 2; + c->pos[2] = (sParTrackPath[0].pos[2] + sParTrackPath[1].pos[2]) / 2; sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; c->mode = CAMERA_MODE_PARALLEL_TRACKING; } @@ -5556,12 +5619,12 @@ void check_blocking_area_processing(const u8 *mode) { } } -CmdRet cam_rr_exit_building_side(struct Camera *c) { +BAD_RETURN(s32) cam_rr_exit_building_side(struct Camera *c) { set_camera_mode_8_directions(c); s8DirModeBaseYaw = DEGREES(90); } -CmdRet cam_rr_exit_building_top(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -5571,13 +5634,13 @@ CmdRet cam_rr_exit_building_top(struct Camera *c) { } } -CmdRet cam_rr_enter_building_window(struct Camera *c) { +BAD_RETURN(s32) cam_rr_enter_building_window(struct Camera *c) { if (c->mode != CAMERA_MODE_FIXED) { set_camera_mode_fixed(c, -2974, 478, -3975); } } -CmdRet cam_rr_enter_building(struct Camera *c) { +BAD_RETURN(s32) cam_rr_enter_building(struct Camera *c) { if (c->mode != CAMERA_MODE_FIXED) { set_camera_mode_fixed(c, -2953, 798, -3943); } @@ -5587,7 +5650,7 @@ CmdRet cam_rr_enter_building(struct Camera *c) { } } -CmdRet cam_rr_enter_building_side(struct Camera *c) { +BAD_RETURN(s32) cam_rr_enter_building_side(struct Camera *c) { if (c->mode != CAMERA_MODE_FIXED) { sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; c->mode = CAMERA_MODE_FIXED; @@ -5597,7 +5660,7 @@ CmdRet cam_rr_enter_building_side(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) cam_cotmc_exit_waterfall(UNUSED struct Camera *c) { gCameraMovementFlags |= CAM_MOVE_FIX_IN_PLACE; } @@ -5605,7 +5668,7 @@ CmdRet cam_cotmc_exit_waterfall(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) 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; @@ -5615,7 +5678,7 @@ CmdRet cam_sl_snowman_head_8dir(struct Camera *c) { * 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) { +BAD_RETURN(s32) cam_sl_free_roam(struct Camera *c) { transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 60); } @@ -5633,7 +5696,7 @@ void move_camera_through_floor_while_descending(struct Camera *c, f32 height) { } } -CmdRet cam_hmc_enter_maze(struct Camera *c) { +BAD_RETURN(s32) cam_hmc_enter_maze(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -5649,26 +5712,26 @@ CmdRet cam_hmc_enter_maze(struct Camera *c) { } } -CmdRet cam_hmc_elevator_black_hole(struct Camera *c) { +BAD_RETURN(s32) cam_hmc_elevator_black_hole(struct Camera *c) { move_camera_through_floor_while_descending(c, 1536.f); } -CmdRet cam_hmc_elevator_maze_emergency_exit(struct Camera *c) { +BAD_RETURN(s32) cam_hmc_elevator_maze_emergency_exit(struct Camera *c) { move_camera_through_floor_while_descending(c, 2355.f); } -CmdRet cam_hmc_elevator_lake(struct Camera *c) { +BAD_RETURN(s32) cam_hmc_elevator_lake(struct Camera *c) { move_camera_through_floor_while_descending(c, 1843.f); } -CmdRet cam_hmc_elevator_maze(struct Camera *c) { +BAD_RETURN(s32) cam_hmc_elevator_maze(struct Camera *c) { move_camera_through_floor_while_descending(c, 1843.f); } /** * Starts the "Enter Pyramid Top" cutscene. */ -CmdRet cam_ssl_enter_pyramid_top(UNUSED struct Camera *c) { +BAD_RETURN(s32) cam_ssl_enter_pyramid_top(UNUSED struct Camera *c) { start_object_cutscene_without_focus(CUTSCENE_ENTER_PYRAMID_TOP); } @@ -5676,7 +5739,7 @@ CmdRet cam_ssl_enter_pyramid_top(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) cam_ssl_pyramid_center(struct Camera *c) { sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; transition_to_camera_mode(c, CAMERA_MODE_CLOSE, 90); } @@ -5684,7 +5747,7 @@ CmdRet cam_ssl_pyramid_center(struct Camera *c) { /** * Changes the mode back to outward radial in the boss room inside the pyramid. */ -CmdRet cam_ssl_boss_room(struct Camera *c) { +BAD_RETURN(s32) cam_ssl_boss_room(struct Camera *c) { sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; transition_to_camera_mode(c, CAMERA_MODE_OUTWARD_RADIAL, 90); } @@ -5692,7 +5755,7 @@ CmdRet cam_ssl_boss_room(struct Camera *c) { /** * Moves the camera to through the tunnel by forcing sModeOffsetYaw */ -CmdRet cam_thi_move_cam_through_tunnel(UNUSED struct Camera *c) { +BAD_RETURN(s32) cam_thi_move_cam_through_tunnel(UNUSED struct Camera *c) { if (sModeOffsetYaw < DEGREES(60)) { sModeOffsetYaw = DEGREES(60); } @@ -5701,7 +5764,7 @@ CmdRet cam_thi_move_cam_through_tunnel(UNUSED struct Camera *c) { /** * Aligns the camera to look through the tunnel */ -CmdRet cam_thi_look_through_tunnel(UNUSED struct Camera *c) { +BAD_RETURN(s32) cam_thi_look_through_tunnel(UNUSED struct Camera *c) { // ~82.5 degrees if (sModeOffsetYaw > 0x3AAA) { sModeOffsetYaw = 0x3AAA; @@ -5713,7 +5776,7 @@ CmdRet cam_thi_look_through_tunnel(UNUSED struct Camera *c) { * * @see sCamBOB for bounds. */ -CmdRet cam_bob_tower(struct Camera *c) { +BAD_RETURN(s32) cam_bob_tower(struct Camera *c) { sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; transition_to_camera_mode(c, CAMERA_MODE_RADIAL, 90); } @@ -5726,7 +5789,7 @@ CmdRet cam_bob_tower(struct Camera *c) { * * @see sCamBOB */ -CmdRet cam_bob_default_free_roam(struct Camera *c) { +BAD_RETURN(s32) cam_bob_default_free_roam(struct Camera *c) { transition_to_camera_mode(c, CAMERA_MODE_FREE_ROAM, 90); } @@ -5734,7 +5797,7 @@ CmdRet cam_bob_default_free_roam(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -5745,7 +5808,7 @@ CmdRet cam_castle_hmc_start_pool_cutscene(struct Camera *c) { * 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) { +BAD_RETURN(s32) cam_castle_lobby_entrance(UNUSED struct Camera *c) { vec3f_set(sCastleEntranceOffset, -813.f - sFixedModeBasePosition[0], 378.f - sFixedModeBasePosition[1], 1103.f - sFixedModeBasePosition[2]); } @@ -5753,7 +5816,7 @@ CmdRet cam_castle_lobby_entrance(UNUSED struct Camera *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) { +BAD_RETURN(s32) cam_castle_look_upstairs(struct Camera *c) { struct Surface *floor; f32 floorHeight = find_floor(c->pos[0], c->pos[1], c->pos[2], &floor); @@ -5767,7 +5830,7 @@ CmdRet cam_castle_look_upstairs(struct Camera *c) { /** * Make the camera look down the stairs towards the basement star door */ -CmdRet cam_castle_basement_look_downstairs(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -5781,7 +5844,7 @@ CmdRet cam_castle_basement_look_downstairs(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -5792,7 +5855,7 @@ CmdRet cam_castle_enter_lobby(struct Camera *c) { /** * Starts spiral stairs mode. */ -CmdRet cam_castle_enter_spiral_stairs(struct Camera *c) { +BAD_RETURN(s32) cam_castle_enter_spiral_stairs(struct Camera *c) { transition_to_camera_mode(c, CAMERA_MODE_SPIRAL_STAIRS, 20); } @@ -5800,7 +5863,7 @@ CmdRet cam_castle_enter_spiral_stairs(struct Camera *c) { * 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) { +static UNUSED BAD_RETURN(s32) 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 { @@ -5812,7 +5875,7 @@ static UNUSED CmdRet cam_castle_leave_spiral_stairs(struct Camera *c) { * 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) { +BAD_RETURN(s32) cam_castle_close_mode(struct Camera *c) { set_camera_mode_close_cam(&c->mode); } @@ -5820,7 +5883,7 @@ CmdRet cam_castle_close_mode(struct Camera *c) { * 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) { +BAD_RETURN(s32) cam_castle_leave_lobby_sliding_door(struct Camera *c) { cam_castle_close_mode(c); c->doorStatus = DOOR_ENTER_LOBBY; } @@ -5828,19 +5891,19 @@ CmdRet cam_castle_leave_lobby_sliding_door(struct Camera *c) { /** * Just calls cam_castle_enter_lobby */ -CmdRet cam_castle_enter_lobby_sliding_door(struct Camera *c) { +BAD_RETURN(s32) cam_castle_enter_lobby_sliding_door(struct Camera *c) { cam_castle_enter_lobby(c); } -CmdRet cam_bbh_room_6(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_6(struct Camera *c) { parallel_tracking_init(c, sBBHLibraryParTrackPath); } -CmdRet cam_bbh_fall_off_roof(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_fall_off_roof(struct Camera *c) { set_camera_mode_close_cam(&c->mode); } -CmdRet cam_bbh_fall_into_pool(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -5850,24 +5913,24 @@ CmdRet cam_bbh_fall_into_pool(struct Camera *c) { sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet cam_bbh_room_1(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_1(struct Camera *c) { set_camera_mode_fixed(c, 956, 440, 1994); } -CmdRet cam_bbh_leave_front_door(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_leave_front_door(struct Camera *c) { c->doorStatus = DOOR_LEAVING_SPECIAL; cam_bbh_room_1(c); } -CmdRet cam_bbh_room_2_lower(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_2_lower(struct Camera *c) { set_camera_mode_fixed(c, 2591, 400, 1284); } -CmdRet cam_bbh_room_4(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_4(struct Camera *c) { set_camera_mode_fixed(c, 3529, 340, -1384); } -CmdRet cam_bbh_room_8(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_8(struct Camera *c) { set_camera_mode_fixed(c, -500, 740, -1306); } @@ -5875,7 +5938,7 @@ CmdRet cam_bbh_room_8(struct Camera *c) { * In BBH's room 5's library (the first floor room with the vanish cap/boo painting) * set the camera mode to fixed and position to (-2172, 200, 675) */ -CmdRet cam_bbh_room_5_library(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_5_library(struct Camera *c) { set_camera_mode_fixed(c, -2172, 200, 675); } @@ -5884,53 +5947,53 @@ CmdRet cam_bbh_room_5_library(struct Camera *c) { * set the camera mode to to the hidden room's position * if coming from the library. */ -CmdRet cam_bbh_room_5_library_to_hidden_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_5_hidden_to_library_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_5_hidden(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_5_hidden(struct Camera *c) { c->doorStatus = DOOR_LEAVING_SPECIAL; set_camera_mode_fixed(c, -1542, 320, -307); } -CmdRet cam_bbh_room_3(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_3(struct Camera *c) { set_camera_mode_fixed(c, -1893, 320, 2327); } -CmdRet cam_bbh_room_7_mr_i(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_7_mr_i(struct Camera *c) { set_camera_mode_fixed(c, 1371, 360, -1302); } -CmdRet cam_bbh_room_7_mr_i_to_coffins_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_7_coffins_to_mr_i_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_elevator_room_lower(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_elevator_room_lower(struct Camera *c) { c->doorStatus = DOOR_LEAVING_SPECIAL; set_camera_mode_close_cam(&c->mode); } -CmdRet cam_bbh_room_0_back_entrance(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_0_back_entrance(struct Camera *c) { set_camera_mode_close_cam(&c->mode); } -CmdRet cam_bbh_elevator(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_elevator(struct Camera *c) { if (c->mode == CAMERA_MODE_FIXED) { set_camera_mode_close_cam(&c->mode); c->pos[1] = -405.f; @@ -5938,65 +6001,65 @@ CmdRet cam_bbh_elevator(struct Camera *c) { } } -CmdRet cam_bbh_room_12_upper(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_12_upper(struct Camera *c) { c->doorStatus = DOOR_LEAVING_SPECIAL; set_camera_mode_fixed(c, -2932, 296, 4429); } -CmdRet cam_bbh_enter_front_door(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_enter_front_door(struct Camera *c) { set_camera_mode_close_cam(&c->mode); } -CmdRet cam_bbh_room_2_library(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_2_library(struct Camera *c) { set_camera_mode_fixed(c, 3493, 440, 617); } -CmdRet cam_bbh_room_2_library_to_trapdoor_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_2_trapdoor(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_2_trapdoor(struct Camera *c) { set_camera_mode_fixed(c, 3502, 440, 1217); } -CmdRet cam_bbh_room_2_trapdoor_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_9_attic(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_9_attic(struct Camera *c) { set_camera_mode_fixed(c, -670, 460, 372); } -CmdRet cam_bbh_room_9_attic_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_9_mr_i_transition(struct Camera *c) { +BAD_RETURN(s32) 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 cam_bbh_room_13_balcony(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_13_balcony(struct Camera *c) { set_camera_mode_fixed(c, 210, 420, 3109); } -CmdRet cam_bbh_room_0(struct Camera *c) { +BAD_RETURN(s32) cam_bbh_room_0(struct Camera *c) { c->doorStatus = DOOR_LEAVING_SPECIAL; set_camera_mode_fixed(c, -204, 807, 204); } -CmdRet cam_ccm_enter_slide_shortcut(UNUSED struct Camera *c) { +BAD_RETURN(s32) cam_ccm_enter_slide_shortcut(UNUSED struct Camera *c) { sStatusFlags |= CAM_FLAG_CCM_SLIDE_SHORTCUT; } -CmdRet cam_ccm_leave_slide_shortcut(UNUSED struct Camera *c) { +BAD_RETURN(s32) cam_ccm_leave_slide_shortcut(UNUSED struct Camera *c) { sStatusFlags &= ~CAM_FLAG_CCM_SLIDE_SHORTCUT; } @@ -6353,6 +6416,15 @@ struct CutsceneSplinePoint sIntroPipeToDialogPosition[] = { /** * Describes the spline that the camera's focus follows, during the same part of the intro as the above. */ +#ifdef VERSION_EU +struct CutsceneSplinePoint sIntroPipeToDialogFocus[] = { + { 0, 25, { -1248, 450, 4596 } }, { 1, 71, { -1258, 485, 4606 } }, { 2, 71, { -1379, 344, 4769 } }, + { 3, 22, { -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 } }, + { 9, 21, { -1321, 346, 4098 } }, { 0, 0, { -1328, 385, 4354 } }, { 0, 0, { -1328, 385, 4354 } }, + { 0, 0, { -1328, 385, 4354 } }, { -1, 0, { -1328, 385, 4354 } } +}; +#else 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 } }, @@ -6360,6 +6432,7 @@ struct CutsceneSplinePoint sIntroPipeToDialogFocus[] = { { 9, 21, { -1321, 346, 4098 } }, { 0, 0, { -1328, 385, 4354 } }, { 0, 0, { -1328, 385, 4354 } }, { 0, 0, { -1328, 385, 4354 } }, { -1, 0, { -1328, 385, 4354 } } }; +#endif struct CutsceneSplinePoint sEndingFlyToWindowPos[] = { { 0, 0, { -86, 876, 640 } }, { 1, 0, { -86, 876, 610 } }, { 2, 0, { -66, 945, 393 } }, @@ -6404,7 +6477,11 @@ struct CutsceneSplinePoint sEndingLookUpAtCastle[] = { }; struct CutsceneSplinePoint sEndingLookAtSkyFocus[] = { +#ifdef VERSION_EU + { 0, 50, { 484, 1368, -868 } }, { 0, 72, { 479, 1372, -872 } }, { 0, 50, { 351, 1817, -918 } }, +#else { 0, 50, { 484, 1368, -888 } }, { 0, 72, { 479, 1372, -892 } }, { 0, 50, { 351, 1817, -918 } }, +#endif { 0, 50, { 351, 1922, -598 } }, { 0, 0, { 636, 2027, -415 } }, { 0, 0, { 636, 2027, -415 } }, { -1, 0, { 636, 2027, -415 } } }; @@ -6890,7 +6967,6 @@ void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSpline init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point); i += 1; - do { do { init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point); @@ -6900,10 +6976,10 @@ void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSpline } while (j > 16); // 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); + do { init_spline_point(&dst[i], 0, src[j].speed, src[j].point); } while (0); + do { init_spline_point(&dst[i + 1], 0, 0, src[j].point); } while (0); + do { init_spline_point(&dst[i + 2], 0, 0, src[j].point); } while (0); + do { init_spline_point(&dst[i + 3], -1, 0, src[j].point); } while (0); } /** @@ -6930,7 +7006,7 @@ static UNUSED void unused_cutscene_mario_dialog_looking_down(UNUSED struct Camer /** * Cause mario to enter the normal dialog state. */ -static CmdRet cutscene_mario_dialog(UNUSED struct Camera *c) { +static BAD_RETURN(s32) cutscene_mario_dialog(UNUSED struct Camera *c) { gCutsceneTimer = cutscene_common_set_dialog_state(1); } @@ -6942,7 +7018,7 @@ static UNUSED void unused_cutscene_mario_dialog_looking_up(UNUSED struct Camera /** * Lower the volume (US only) and start the peach letter background music */ -CmdRet cutscene_intro_peach_start_letter_music(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_start_letter_music(UNUSED struct Camera *c) { #ifdef VERSION_US func_8031FFB4(0, 60, 40); #endif @@ -6952,7 +7028,7 @@ CmdRet cutscene_intro_peach_start_letter_music(UNUSED struct Camera *c) { /** * Raise the volume (not in JP) and start the flying music. */ -CmdRet cutscene_intro_peach_start_flying_music(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_start_flying_music(UNUSED struct Camera *c) { #ifndef VERSION_JP sequence_player_unlower(0, 60); #endif @@ -6964,7 +7040,7 @@ CmdRet cutscene_intro_peach_start_flying_music(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_intro_peach_eu_lower_volume(UNUSED struct Camera *c) { func_8031FFB4(0, 60, 40); } #endif @@ -6985,8 +7061,12 @@ void player2_rotate_cam(struct Camera *c, s16 minPitch, s16 maxPitch, s16 minYaw approach_s16_asymptotic_bool(&sCreditsPlayer2Pitch, -(s16)(gPlayer2Controller->stickY * 265.f), 4); vec3f_get_dist_and_angle(c->pos, c->focus, &distCamToFocus, &pitch, &yaw); +#ifdef VERSION_EU + if ((pitchCap = 0x3800 - pitch) < 0) { +#else pitchCap = 0x3800 - pitch; if (pitchCap < 0) { +#endif pitchCap = 0; } if (maxPitch > pitchCap) { @@ -7081,15 +7161,13 @@ void pan_camera(struct Camera *c, s16 incPitch, s16 incYaw) { UNUSED Vec3f unused1; f32 distCamToFocus; s16 pitch, yaw; - UNUSED f32 unused2; vec3f_get_dist_and_angle(c->pos, c->focus, &distCamToFocus, &pitch, &yaw); - pitch += incPitch; - yaw += incYaw; + pitch += incPitch; yaw += incYaw; vec3f_set_dist_and_angle(c->pos, c->focus, distCamToFocus, pitch, yaw); } -CmdRet cutscene_shake_explosion(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_shake_explosion(UNUSED struct Camera *c) { set_environmental_camera_shake(SHAKE_ENV_EXPLOSION); cutscene_set_fov_shake_preset(1); } @@ -7128,19 +7206,19 @@ void cutscene_unsoften_music(UNUSED struct Camera *c) { sequence_player_unlower(0, 60); } -void unused_802905C8(UNUSED struct Camera *c) { +static void unused_802905C8(UNUSED struct Camera *c) { } -CmdRet cutscene_unused_start(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_unused_start(UNUSED struct Camera *c) { } -CmdRet cutscene_unused_loop(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_unused_loop(UNUSED struct Camera *c) { } /** * Set the camera position and focus for when mario falls from the sky. */ -CmdRet cutscene_ending_mario_fall_start(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7148,7 +7226,7 @@ CmdRet cutscene_ending_mario_fall_start(struct Camera *c) { /** * Focus on mario when he's falling from the sky. */ -CmdRet cutscene_ending_mario_fall_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_mario_fall_focus_mario(struct Camera *c) { Vec3f offset; vec3f_set(offset, 0.f, 80.f, 0.f); @@ -7163,7 +7241,7 @@ CmdRet cutscene_ending_mario_fall_focus_mario(struct Camera *c) { /** * Mario falls from the sky after the grand star cutscene. */ -CmdRet cutscene_ending_mario_fall(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7172,7 +7250,7 @@ CmdRet cutscene_ending_mario_fall(struct Camera *c) { /** * Closeup of mario as the wing cap fades and mario looks up. */ -CmdRet cutscene_ending_mario_land_closeup(struct Camera *c) { +BAD_RETURN(s32) 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); player2_rotate_cam(c, -0x2000, 0x2000, -0x2000, 0x2000); @@ -7181,7 +7259,7 @@ CmdRet cutscene_ending_mario_land_closeup(struct Camera *c) { /** * Reset the spline progress and cvar9. */ -CmdRet cutscene_ending_reset_spline(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_reset_spline(UNUSED struct Camera *c) { sCutsceneVars[9].point[0] = 0.f; cutscene_reset_spline(); } @@ -7189,7 +7267,7 @@ CmdRet cutscene_ending_reset_spline(UNUSED struct Camera *c) { /** * Follow sEndingFlyToWindowPos/Focus up to the window. */ -CmdRet cutscene_ending_fly_up_to_window(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7197,7 +7275,7 @@ CmdRet cutscene_ending_fly_up_to_window(struct Camera *c) { /** * Move the camera up to the window as the star power frees peach. */ -CmdRet cutscene_ending_stars_free_peach(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7206,7 +7284,7 @@ CmdRet cutscene_ending_stars_free_peach(struct Camera *c) { /** * Move the camera to the ground as mario lands. */ -CmdRet cutscene_ending_mario_land(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7215,7 +7293,7 @@ CmdRet cutscene_ending_mario_land(struct Camera *c) { /** * Move the camera closer to peach appearing. */ -CmdRet cutscene_ending_peach_appear_closeup(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7224,7 +7302,7 @@ CmdRet cutscene_ending_peach_appear_closeup(struct Camera *c) { /** * Peach fades in, the camera focuses on her. */ -CmdRet cutscene_ending_peach_appears(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7234,7 +7312,7 @@ CmdRet cutscene_ending_peach_appears(struct Camera *c) { /** * Reset spline progress, set cvar2 y offset. */ -CmdRet cutscene_ending_peach_descends_start(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_peach_descends_start(UNUSED struct Camera *c) { cutscene_reset_spline(); sCutsceneVars[2].point[1] = 150.f; } @@ -7242,7 +7320,7 @@ CmdRet cutscene_ending_peach_descends_start(UNUSED struct Camera *c) { /** * Follow the sEndingPeachDescentCamPos spline, which rotates around peach. */ -CmdRet cutscene_ending_follow_peach_descent(struct Camera *c) { +BAD_RETURN(s32) 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]; } @@ -7250,14 +7328,14 @@ CmdRet cutscene_ending_follow_peach_descent(struct Camera *c) { /** * Decrease cvar2's y offset while the camera flies backwards to mario. */ -CmdRet cutscene_ending_peach_descent_lower_focus(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_peach_descent_lower_focus(UNUSED struct Camera *c) { camera_approach_f32_symmetric_bool(&(sCutsceneVars[2].point[1]), 90.f, 0.5f); } /** * Keep following the sEndingPeachDescentCamPos spline, which leads back to mario. */ -CmdRet cutscene_ending_peach_descent_back_to_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_peach_descent_back_to_mario(struct Camera *c) { Vec3f pos; move_point_along_spline(pos, sEndingPeachDescentCamPos, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); @@ -7270,7 +7348,7 @@ CmdRet cutscene_ending_peach_descent_back_to_mario(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -7284,7 +7362,7 @@ CmdRet cutscene_ending_peach_descends(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -7294,19 +7372,25 @@ CmdRet cutscene_ending_mario_to_peach(struct Camera *c) { /** * Make the focus follow the sEndingLookUpAtCastle spline. */ -CmdRet cutscene_ending_look_up_at_castle(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_look_up_at_castle(UNUSED struct Camera *c) { move_point_along_spline(c->focus, sEndingLookUpAtCastle, &sCutsceneSplineSegment, &sCutsceneSplineSegmentProgress); } /** * Peach opens her eyes and the camera looks at the castle window again. */ -CmdRet cutscene_ending_peach_wakeup(struct Camera *c) { +BAD_RETURN(s32) 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); +#ifdef VERSION_EU + cutscene_event(cutscene_ending_look_up_at_castle, c, 265, -1); + cutscene_spawn_obj(7, 315); + cutscene_spawn_obj(9, 355); +#else cutscene_event(cutscene_ending_look_up_at_castle, c, 250, -1); cutscene_spawn_obj(7, 300); cutscene_spawn_obj(9, 340); +#endif vec3f_set(c->pos, -163.f, 978.f, -1082.f); player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } @@ -7314,7 +7398,7 @@ CmdRet cutscene_ending_peach_wakeup(struct Camera *c) { /** * Side view of peach and mario. Peach thanks mario for saving her. */ -CmdRet cutscene_ending_dialog(struct Camera *c) { +BAD_RETURN(s32) 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); player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); @@ -7323,7 +7407,7 @@ CmdRet cutscene_ending_dialog(struct Camera *c) { /** * Zoom in and move the camera close to mario and peach. */ -CmdRet cutscene_ending_kiss_closeup(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7332,7 +7416,7 @@ CmdRet cutscene_ending_kiss_closeup(struct Camera *c) { /** * Fly back and zoom out for mario's spin after the kiss. */ -CmdRet cutscene_ending_kiss_here_we_go(struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_kiss_here_we_go(struct Camera *c) { Vec3f pos, foc; set_fov_function(CAM_FOV_DEFAULT); @@ -7346,16 +7430,20 @@ CmdRet cutscene_ending_kiss_here_we_go(struct Camera *c) { /** * Peach kisses mario on the nose. */ -CmdRet cutscene_ending_kiss(struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_kiss(struct Camera *c) { cutscene_event(cutscene_ending_kiss_closeup, c, 0, 0); +#ifdef VERSION_EU + cutscene_event(cutscene_ending_kiss_here_we_go, c, 185, -1); +#else cutscene_event(cutscene_ending_kiss_here_we_go, c, 155, -1); +#endif player2_rotate_cam(c, -0x800, 0x2000, -0x2000, 0x2000); } /** * Make the focus follow sEndingLookAtSkyFocus. */ -CmdRet cutscene_ending_look_at_sky(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7364,14 +7452,14 @@ CmdRet cutscene_ending_look_at_sky(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_ending_zoom_fov(UNUSED struct Camera *c) { sFOVState.fov = 37.f; } /** * 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) { +BAD_RETURN(s32) 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); @@ -7385,7 +7473,7 @@ CmdRet cutscene_ending_cake_for_mario(struct Camera *c) { /** * Stop the ending cutscene, reset the fov. */ -CmdRet cutscene_ending_stop(struct Camera *c) { +BAD_RETURN(s32) cutscene_ending_stop(struct Camera *c) { set_fov_function(CAM_FOV_SET_45); c->cutscene = 0; gCutsceneTimer = CUTSCENE_STOP; @@ -7396,7 +7484,7 @@ CmdRet cutscene_ending_stop(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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; @@ -7405,7 +7493,7 @@ CmdRet cutscene_grand_star_start(UNUSED struct Camera *c) { /** * Make the camera fly to the front of mario. */ -CmdRet cutscene_grand_star_front_of_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_grand_star_front_of_mario(struct Camera *c) { f32 goalDist; s16 goalPitch, goalYaw; f32 dist; @@ -7422,7 +7510,7 @@ CmdRet cutscene_grand_star_front_of_mario(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) 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); } @@ -7430,7 +7518,7 @@ CmdRet cutscene_grand_star_mario_jump(UNUSED struct Camera *c) { /** * Accelerate cvar2 to point back and to the left (relative to the camera). */ -CmdRet cutscene_grand_star_accel_cvar2(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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; } @@ -7438,7 +7526,7 @@ CmdRet cutscene_grand_star_accel_cvar2(UNUSED struct Camera *c) { /** * Decrease cvar2 offset, follow mario by directly updating the camera's pos. */ -CmdRet cutscene_grand_star_approach_mario(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7449,11 +7537,11 @@ CmdRet cutscene_grand_star_approach_mario(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_grand_star_move_cvar2(struct Camera *c) { offset_rotated(c->pos, c->pos, sCutsceneVars[2].point, sCutsceneVars[0].angle); } -CmdRet cutscene_grand_star_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_grand_star_focus_mario(struct Camera *c) { Vec3f foc; vec3f_set(foc, sMarioCamState->pos[0], (sMarioCamState->pos[1] - 307.f) * 0.5f + 407.f, sMarioCamState->pos[2]); @@ -7463,7 +7551,7 @@ CmdRet cutscene_grand_star_focus_mario(struct Camera *c) { /** * The first part of the grand star cutscene, after mario has collected the grand star. */ -CmdRet cutscene_grand_star(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7477,7 +7565,7 @@ CmdRet cutscene_grand_star(struct Camera *c) { /** * Zero the cvars that are used when mario is flying. */ -CmdRet cutscene_grand_star_fly_start(struct Camera *c) { +BAD_RETURN(s32) 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 @@ -7491,7 +7579,7 @@ CmdRet cutscene_grand_star_fly_start(struct Camera *c) { /** * Decrease the cvar offsets so that lakitu flies closer to mario. */ -CmdRet cutscene_grand_star_fly_move_to_mario(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_grand_star_fly_move_to_mario(UNUSED struct Camera *c) { Vec3f posOff; vec3f_set(posOff, -600.f, 0.f, -400.f); @@ -7507,7 +7595,7 @@ CmdRet cutscene_grand_star_fly_move_to_mario(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) 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(&sCutsceneVars[4].point[0], -2000.f, sCutsceneVars[8].point[0]); @@ -7515,7 +7603,7 @@ CmdRet cutscene_grand_star_fly_mario_offscreen(UNUSED struct Camera *c) { camera_approach_f32_symmetric_bool(&sCutsceneVars[4].point[2], 1000.f, sCutsceneVars[8].point[0] / 10.f); 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[1], 1200.f, sCutsceneVars[8].point[0] / 2); camera_approach_f32_symmetric_bool(&sCutsceneVars[5].point[2], 1000.f, sCutsceneVars[8].point[0] / 1.5f); } @@ -7524,7 +7612,7 @@ CmdRet cutscene_grand_star_fly_mario_offscreen(UNUSED struct Camera *c) { * cvar4 is the position offset. * cvar5 is the focus offset. */ -CmdRet cutscene_grand_star_fly_app_cvars(struct Camera *c) { +BAD_RETURN(s32) cutscene_grand_star_fly_app_cvars(struct Camera *c) { Vec3f goalPos, goalFoc; f32 dist; s16 pitch, yaw; @@ -7551,7 +7639,7 @@ CmdRet cutscene_grand_star_fly_app_cvars(struct Camera *c) { * * cvar8.point[2] is lakitu's speed. */ -CmdRet cutscene_grand_star_fly(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7579,7 +7667,7 @@ void focus_in_front_of_mario(struct Camera *c, f32 dist, f32 speed) { * 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) { +BAD_RETURN(s32) cutscene_dance_move_to_mario(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -7589,39 +7677,39 @@ CmdRet cutscene_dance_move_to_mario(struct Camera *c) { vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet cutscene_dance_rotate(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_rotate(struct Camera *c) { rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, 0, 0x200); } -CmdRet cutscene_dance_rotate_move_back(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_rotate_move_back(struct Camera *c) { rotate_and_move_vec3f(c->pos, sMarioCamState->pos, -15.f, 0, 0); } -CmdRet cutscene_dance_rotate_move_towards_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_rotate_move_towards_mario(struct Camera *c) { rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 20.f, 0, 0); } /** * Speculated to be dance-related due to its proximity to the other dance functions */ -CmdRet cutscene_dance_unused(UNUSED struct Camera *c) { +static BAD_RETURN(s32) cutscene_dance_unused(UNUSED struct Camera *c) { } /** * Slowly turn to the point 100 units in front of mario */ -CmdRet cutscene_dance_default_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_default_focus_mario(struct Camera *c) { focus_in_front_of_mario(c, -100.f, 0.2f); } /** * Focus twice as far away as default dance, and move faster. */ -CmdRet cutscene_dance_rotate_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_rotate_focus_mario(struct Camera *c) { focus_in_front_of_mario(c, -200.f, 0.03f); } -CmdRet cutscene_dance_shake_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_shake_fov(UNUSED struct Camera *c) { set_fov_shake(0x200, 0x28, 0x8000); } @@ -7630,7 +7718,7 @@ CmdRet cutscene_dance_shake_fov(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_dance_default_rotate(struct Camera *c) { sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; sYawSpeed = 0; set_fov_function(CAM_FOV_DEFAULT); @@ -7661,7 +7749,7 @@ CmdRet cutscene_dance_default_rotate(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) star_dance_bound_yaw(struct Camera *c, s16 absYaw, s16 yawMax) { s16 dummyPitch, yaw; f32 distCamToMario; s16 yawFromAbs; @@ -7684,7 +7772,7 @@ CmdRet star_dance_bound_yaw(struct Camera *c, s16 absYaw, s16 yawMax) { * 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) { +BAD_RETURN(s32) cutscene_dance_closeup_start(struct Camera *c) { UNUSED s32 pad[2]; if ((gLastCompletedStarNum == 4) && (gCurrCourseNum == COURSE_JRB)) { @@ -7705,7 +7793,7 @@ CmdRet cutscene_dance_closeup_start(struct Camera *c) { /** * Focus the camera on mario eye height. */ -CmdRet cutscene_dance_closeup_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_closeup_focus_mario(struct Camera *c) { Vec3f marioPos; vec3f_set(marioPos, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); @@ -7716,7 +7804,7 @@ CmdRet cutscene_dance_closeup_focus_mario(struct Camera *c) { /** * Fly above mario, looking down. */ -CmdRet cutscene_dance_closeup_fly_above(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_closeup_fly_above(struct Camera *c) { s16 pitch, yaw; f32 dist; s16 goalPitch = 0x1800; @@ -7736,7 +7824,7 @@ CmdRet cutscene_dance_closeup_fly_above(struct Camera *c) { /** * Fly closer right when mario gives the peace sign. */ -CmdRet cutscene_dance_closeup_fly_closer(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_closeup_fly_closer(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -7750,21 +7838,21 @@ CmdRet cutscene_dance_closeup_fly_closer(struct Camera *c) { /** * Zoom in by increasing fov to 80 degrees. Most dramatic zoom in the game. */ -CmdRet cutscene_dance_closeup_zoom(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_closeup_zoom(UNUSED struct Camera *c) { set_fov_function(CAM_FOV_APP_80); } /** * Shake fov, starts on the first frame mario has the peace sign up. */ -CmdRet cutscene_dance_closeup_shake_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_closeup_shake_fov(UNUSED struct Camera *c) { set_fov_shake(0x300, 0x30, 0x8000); } /** * 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) { +BAD_RETURN(s32) cutscene_dance_closeup(struct Camera *c) { sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; if (sMarioCamState->action == ACT_STAR_DANCE_WATER) { @@ -7789,7 +7877,7 @@ CmdRet cutscene_dance_closeup(struct Camera *c) { /** * cvar8.point[2] is the amount to increase distance from mario */ -CmdRet cutscene_dance_fly_away_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_fly_away_start(struct Camera *c) { Vec3f areaCenter; vec3f_copy(sCutsceneVars[9].point, c->focus); @@ -7816,7 +7904,7 @@ CmdRet cutscene_dance_fly_away_start(struct Camera *c) { } } -CmdRet cutscene_dance_fly_away_approach_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_fly_away_approach_mario(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -7827,7 +7915,7 @@ CmdRet cutscene_dance_fly_away_approach_mario(struct Camera *c) { vec3f_set_dist_and_angle(sMarioCamState->pos, c->pos, dist, pitch, yaw); } -CmdRet cutscene_dance_fly_away_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_fly_away_focus_mario(struct Camera *c) { Vec3f marioPos; vec3f_set(marioPos, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); @@ -7848,7 +7936,7 @@ void cutscene_pan_cvar9(struct Camera *c) { /** * Move backwards and rotate slowly around mario. */ -CmdRet cutscene_dance_fly_rotate_around_mario(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7856,18 +7944,18 @@ CmdRet cutscene_dance_fly_rotate_around_mario(struct Camera *c) { /** * Rotate quickly while lakitu flies up. */ -CmdRet cutscene_dance_fly_away_rotate_while_flying(struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_fly_away_rotate_while_flying(struct Camera *c) { rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, 0, 0x80); } -CmdRet cutscene_dance_fly_away_shake_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_dance_fly_away_shake_fov(UNUSED struct Camera *c) { set_fov_shake(0x400, 0x30, 0x8000); } /** * After collecting the star, lakitu flies upwards out of the course. */ -CmdRet cutscene_dance_fly_away(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7883,7 +7971,7 @@ CmdRet cutscene_dance_fly_away(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); } @@ -7891,7 +7979,7 @@ CmdRet cutscene_key_dance_jump_cvar(struct Camera *c) { /** * Jump to a closeup view of mario and the key. */ -CmdRet cutscene_key_dance_jump_closeup(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7899,7 +7987,7 @@ CmdRet cutscene_key_dance_jump_closeup(UNUSED struct Camera *c) { /** * Jump to a view from the lower left (mario's right). */ -CmdRet cutscene_key_dance_jump_lower_left(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -7907,7 +7995,7 @@ CmdRet cutscene_key_dance_jump_lower_left(UNUSED struct Camera *c) { /** * Jump to a rotated view from above. */ -CmdRet cutscene_key_dance_jump_above(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); @@ -7916,21 +8004,21 @@ CmdRet cutscene_key_dance_jump_above(UNUSED struct Camera *c) { /** * Finally, jump to a further view, slightly to mario's left. */ -CmdRet cutscene_key_dance_jump_last(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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 cutscene_key_dance_shake_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_key_dance_shake_fov(UNUSED struct Camera *c) { set_fov_shake(0x180, 0x30, 0x8000); } -CmdRet cutscene_key_dance_handheld_shake(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_key_dance_handheld_shake(UNUSED struct Camera *c) { set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } -CmdRet cutscene_key_dance_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_key_dance_focus_mario(struct Camera *c) { focus_in_front_of_mario(c, 0, 0.2f); } @@ -7938,7 +8026,7 @@ CmdRet cutscene_key_dance_focus_mario(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -7950,14 +8038,14 @@ CmdRet cutscene_key_dance(struct Camera *c) { cutscene_event(cutscene_key_dance_handheld_shake, c, 52, -1); } -CmdRet cutscene_bowser_area_shake_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_area_shake_fov(UNUSED struct Camera *c) { cutscene_set_fov_shake_preset(2); } /** * Set oBowserUnk88 to 1, which causes bowser to start walking. */ -CmdRet cutscene_bowser_area_start_bowser_walking(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_area_start_bowser_walking(UNUSED struct Camera *c) { gSecondCameraFocus->oBowserUnk88 = 1; } @@ -7966,7 +8054,7 @@ CmdRet cutscene_bowser_area_start_bowser_walking(UNUSED struct Camera *c) { * @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) { +BAD_RETURN(s32) 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, @@ -7977,7 +8065,7 @@ CmdRet cutscene_bowser_arena_set_pos(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_bowser_arena_focus_sine(UNUSED struct Camera *c) { //! unused initialization f32 yOff = 150.0f; @@ -7990,7 +8078,7 @@ CmdRet cutscene_bowser_arena_focus_sine(UNUSED struct Camera *c) { /** * Set the camera focus according to cvar0 and cvar2. */ -CmdRet cutscene_bowser_arena_set_focus(struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena_set_focus(struct Camera *c) { offset_rotated(c->focus, sCutsceneVars[2].point, sCutsceneVars[0].point, sCutsceneVars[2].angle); } @@ -7998,7 +8086,7 @@ CmdRet cutscene_bowser_arena_set_focus(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -8007,14 +8095,14 @@ CmdRet cutscene_bowser_arena_adjust_offsets(UNUSED struct Camera *c) { /** * Decrease cvar0's z offset, making the camera focus pan left towards bowser. */ -CmdRet cutscene_bowser_arena_pan_left(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena_pan_left(UNUSED struct Camera *c) { approach_f32_asymptotic_bool(&sCutsceneVars[0].point[2], 0.f, 0.05f); } /** * Duplicate of cutscene_mario_dialog(). */ -CmdRet cutscene_bowser_arena_mario_dialog(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena_mario_dialog(UNUSED struct Camera *c) { cutscene_common_set_dialog_state(1); } @@ -8029,7 +8117,7 @@ void cutscene_stop_dialog(UNUSED struct Camera *c) { * * cvar0 is the focus offset from bowser */ -CmdRet cutscene_bowser_arena_start(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -8050,7 +8138,7 @@ CmdRet cutscene_bowser_arena_start(struct Camera *c) { /** * Create the dialog box depending on which bowser fight mario is in. */ -CmdRet bowser_fight_intro_dialog(UNUSED struct Camera *c) { +BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) { s16 dialog; switch (gCurrLevelNum) { @@ -8070,7 +8158,7 @@ CmdRet bowser_fight_intro_dialog(UNUSED struct Camera *c) { /** * Create the dialog box and wait until it's gone. */ -CmdRet cutscene_bowser_arena_dialog(struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena_dialog(struct Camera *c) { cutscene_event(bowser_fight_intro_dialog, c, 0, 0); if (get_dialog_id() == -1) { @@ -8081,7 +8169,7 @@ CmdRet cutscene_bowser_arena_dialog(struct Camera *c) { /** * End the bowser arena cutscene. */ -CmdRet cutscene_bowser_arena_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena_end(struct Camera *c) { cutscene_stop_dialog(c); c->cutscene = 0; transition_next_state(c, 20); @@ -8094,7 +8182,7 @@ CmdRet cutscene_bowser_arena_end(struct Camera *c) { /** * Cutscene that plays when mario enters a bowser fight. */ -CmdRet cutscene_bowser_arena(struct Camera *c) { +BAD_RETURN(s32) cutscene_bowser_arena(struct Camera *c) { //! This does nothing, but may have been used in development cutscene_spawn_obj(2, 0); @@ -8115,14 +8203,14 @@ CmdRet cutscene_bowser_arena(struct Camera *c) { } } -CmdRet cutscene_star_spawn_store_info(struct Camera *c) { +BAD_RETURN(s32) cutscene_star_spawn_store_info(struct Camera *c) { store_info_star(c); } /** * Focus on the top of the star. */ -CmdRet cutscene_star_spawn_focus_star(struct Camera *c) { +BAD_RETURN(s32) cutscene_star_spawn_focus_star(struct Camera *c) { UNUSED f32 hMul; Vec3f starPos; UNUSED f32 vMul; @@ -8137,7 +8225,7 @@ CmdRet cutscene_star_spawn_focus_star(struct Camera *c) { /** * Use boss fight mode's update function to move the focus back. */ -CmdRet cutscene_star_spawn_update_boss_fight(struct Camera *c) { +BAD_RETURN(s32) cutscene_star_spawn_update_boss_fight(struct Camera *c) { Vec3f pos, focus; update_boss_fight_camera(c, focus, pos); @@ -8148,7 +8236,7 @@ CmdRet cutscene_star_spawn_update_boss_fight(struct Camera *c) { /** * Fly back to the camera's previous pos and focus. */ -CmdRet cutscene_star_spawn_fly_back(struct Camera *c) { +BAD_RETURN(s32) cutscene_star_spawn_fly_back(struct Camera *c) { retrieve_info_star(c); transition_next_state(c, 15); } @@ -8156,7 +8244,7 @@ CmdRet cutscene_star_spawn_fly_back(struct Camera *c) { /** * Plays when a star spawns (ie from a box). */ -CmdRet cutscene_star_spawn(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -8170,7 +8258,7 @@ CmdRet cutscene_star_spawn(struct Camera *c) { /** * Move the camera back to mario. */ -CmdRet cutscene_star_spawn_back(struct Camera *c) { +BAD_RETURN(s32) 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 { @@ -8181,13 +8269,13 @@ CmdRet cutscene_star_spawn_back(struct Camera *c) { sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } -CmdRet cutscene_star_spawn_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_star_spawn_end(struct Camera *c) { sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; } -CmdRet cutscene_exit_waterfall_warp(struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_waterfall_warp(struct Camera *c) { //! hardcoded position vec3f_set(c->pos, -3899.f, 39.f, -5671.f); } @@ -8195,7 +8283,7 @@ CmdRet cutscene_exit_waterfall_warp(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) 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); @@ -8204,7 +8292,7 @@ CmdRet cutscene_exit_to_castle_grounds_focus_mario(struct Camera *c) { /** * Cutscene that plays when mario leaves CotMC through the waterfall. */ -CmdRet cutscene_exit_waterfall(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8213,14 +8301,14 @@ CmdRet cutscene_exit_waterfall(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) cutscene_exit_to_castle_grounds_end(struct Camera *c) { sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; update_camera_yaw(c); } -CmdRet cutscene_exit_fall_to_castle_grounds_warp(struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_fall_to_castle_grounds_warp(struct Camera *c) { //! hardcoded position vec3f_set(c->pos, 5830.f, 32.f, 3985.f); } @@ -8228,7 +8316,7 @@ CmdRet cutscene_exit_fall_to_castle_grounds_warp(struct Camera *c) { /** * Cutscene that plays when mario falls from WMOTR. */ -CmdRet cutscene_exit_fall_to_castle_grounds(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8237,7 +8325,7 @@ CmdRet cutscene_exit_fall_to_castle_grounds(struct Camera *c) { /** * Start the red coin star spawning cutscene. */ -CmdRet cutscene_red_coin_star_start(struct Camera *c) { +BAD_RETURN(s32) 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 @@ -8247,7 +8335,7 @@ CmdRet cutscene_red_coin_star_start(struct Camera *c) { /** * Look towards the star's x and z position */ -CmdRet cutscene_red_coin_star_focus_xz(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -8255,21 +8343,21 @@ CmdRet cutscene_red_coin_star_focus_xz(struct Camera *c) { /** * Look towards the star's y position. Only active before the camera warp. */ -CmdRet cutscene_red_coin_star_focus_y(struct Camera *c) { +BAD_RETURN(s32) cutscene_red_coin_star_focus_y(struct Camera *c) { approach_f32_asymptotic_bool(&c->focus[1], gCutsceneFocus->oPosY, 0.1f); } /** * Look 80% up towards the star. Only active after the camera warp. */ -CmdRet cutscene_red_coin_star_look_up_at_star(struct Camera *c) { +BAD_RETURN(s32) 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; } /** * Warp the camera near the star's spawn point */ -CmdRet cutscene_red_coin_star_warp(struct Camera *c) { +BAD_RETURN(s32) cutscene_red_coin_star_warp(struct Camera *c) { f32 dist; s16 pitch, yaw, posYaw; struct Object *o = gCutsceneFocus; @@ -8292,11 +8380,11 @@ CmdRet cutscene_red_coin_star_warp(struct Camera *c) { /** * Zoom out while looking at the star. */ -CmdRet cutscene_red_coin_star_set_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_red_coin_star_set_fov(UNUSED struct Camera *c) { sFOVState.fov = 60.f; } -CmdRet cutscene_red_coin_star(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8314,7 +8402,7 @@ CmdRet cutscene_red_coin_star(struct Camera *c) { /** * End the red coin star spawning cutscene */ -CmdRet cutscene_red_coin_star_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_red_coin_star_end(struct Camera *c) { retrieve_info_star(c); gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; @@ -8340,7 +8428,7 @@ void cutscene_goto_cvar_pos(struct Camera *c, f32 goalDist, s16 goalPitch, s16 r s16 cannonPitch, cannonYaw; f32 curDist; s16 curPitch, curYaw; - UNUSED f32 unused2, unused3; + UNUSED f64 unused2; 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)) { @@ -8390,7 +8478,7 @@ void cutscene_goto_cvar_pos(struct Camera *c, f32 goalDist, s16 goalPitch, s16 r /** * Store the camera's pos and focus, and copy the cannon's position to cvars. */ -CmdRet cutscene_prepare_cannon_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_prepare_cannon_start(struct Camera *c) { store_info_cannon(c); vec3f_copy(sCutsceneVars[0].point, c->focus); sCutsceneVars[2].point[0] = 30.f; @@ -8402,7 +8490,7 @@ CmdRet cutscene_prepare_cannon_start(struct Camera *c) { /** * Fly towards the cannon door. */ -CmdRet cutscene_prepare_cannon_fly_to_cannon(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8419,7 +8507,7 @@ void cannon_approach_prev(f32 *value, f32 target) { /** * Fly or warp back to the previous pos and focus, stored in sCameraStoreCutscene. */ -CmdRet cutscene_prepare_cannon_fly_back(struct Camera *c) { +BAD_RETURN(s32) cutscene_prepare_cannon_fly_back(struct Camera *c) { f32 distToPrevPos = calc_abs_dist(c->pos, sCameraStoreCutscene.pos); if (distToPrevPos < 8000.f) { @@ -8443,7 +8531,7 @@ CmdRet cutscene_prepare_cannon_fly_back(struct Camera *c) { /** * Cutscene that plays when the cannon is opened. */ -CmdRet cutscene_prepare_cannon(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8453,7 +8541,7 @@ CmdRet cutscene_prepare_cannon(struct Camera *c) { /** * Stop the cannon opening cutscene. */ -CmdRet cutscene_prepare_cannon_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_prepare_cannon_end(struct Camera *c) { gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; retrieve_info_cannon(c); @@ -8481,7 +8569,7 @@ void death_goto_mario(struct Camera *c) { cutscene_goto_cvar_pos(c, 400.f, 0x1000, 0x300, 0); } -CmdRet cutscene_death_standing_start(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -8490,7 +8578,7 @@ CmdRet cutscene_death_standing_start(struct Camera *c) { /** * Fly to mario and turn on handheld shake. */ -CmdRet cutscene_death_standing_goto_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_death_standing_goto_mario(struct Camera *c) { death_goto_mario(c); set_handheld_shake(HAND_CAM_SHAKE_HIGH); } @@ -8498,20 +8586,20 @@ CmdRet cutscene_death_standing_goto_mario(struct Camera *c) { /** * Cutscene that plays when mario dies while standing. */ -CmdRet cutscene_death_standing(struct Camera *c) { +BAD_RETURN(s32) 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 cutscene_death_stomach_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_death_stomach_start(struct Camera *c) { Vec3f offset = { 0, 40.f, -60.f }; offset_rotated(sCutsceneVars[3].point, sMarioCamState->pos, offset, sMarioCamState->faceAngle); vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet cutscene_death_stomach_goto_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_death_stomach_goto_mario(struct Camera *c) { cutscene_goto_cvar_pos(c, 400.f, 0x1800, 0, -0x400); } @@ -8525,28 +8613,28 @@ static void unused_water_death_move_to_side_of_mario(struct Camera *c) { /** * Cutscene that plays when mario dies on his stomach. */ -CmdRet cutscene_death_stomach(struct Camera *c) { +BAD_RETURN(s32) 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 cutscene_bbh_death_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_bbh_death_start(struct Camera *c) { Vec3f dir = { 0, 40.f, 60.f }; offset_rotated(sCutsceneVars[3].point, sMarioCamState->pos, dir, sMarioCamState->faceAngle); vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet cutscene_bbh_death_goto_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_bbh_death_goto_mario(struct Camera *c) { cutscene_goto_cvar_pos(c, 400.f, 0x1800, 0, 0x400); } /** * Cutscene that plays when mario dies in BBH. */ -CmdRet cutscene_bbh_death(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -8556,14 +8644,14 @@ CmdRet cutscene_bbh_death(struct Camera *c) { /** * Copy the camera's focus to cvar0 */ -CmdRet cutscene_quicksand_death_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_quicksand_death_start(struct Camera *c) { vec3f_copy(sCutsceneVars[0].point, c->focus); } /** * Fly closer to mario. In WATER_DEATH, move to mario's side. */ -CmdRet cutscene_quicksand_death_goto_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_quicksand_death_goto_mario(struct Camera *c) { cutscene_goto_cvar_pos(c, 400.f, 0x2800, 0x200, 0); if (c->cutscene == CUTSCENE_WATER_DEATH) { @@ -8574,7 +8662,7 @@ CmdRet cutscene_quicksand_death_goto_mario(struct Camera *c) { /** * Cutscene that plays when mario dies in quicksand. */ -CmdRet cutscene_quicksand_death(struct Camera *c) { +BAD_RETURN(s32) 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]; @@ -8588,7 +8676,7 @@ CmdRet cutscene_quicksand_death(struct Camera *c) { /** * Fly away from mario near the end of the cutscene. */ -CmdRet cutscene_suffocation_fly_away(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_suffocation_fly_away(UNUSED struct Camera *c) { Vec3f target; Vec3f offset = { 0, 20.f, 120.f }; @@ -8599,7 +8687,7 @@ CmdRet cutscene_suffocation_fly_away(UNUSED struct Camera *c) { /** * Keep lakitu above the gas level. */ -CmdRet cutscene_suffocation_stay_above_gas(struct Camera *c) { +BAD_RETURN(s32) cutscene_suffocation_stay_above_gas(struct Camera *c) { UNUSED f32 unused1; f32 gasLevel; UNUSED f32 unused2; @@ -8617,7 +8705,7 @@ CmdRet cutscene_suffocation_stay_above_gas(struct Camera *c) { /** * Quickly rotate around mario. */ -CmdRet cutscene_suffocation_rotate(struct Camera *c) { +BAD_RETURN(s32) cutscene_suffocation_rotate(struct Camera *c) { f32 dist; s16 pitch, yaw; @@ -8629,7 +8717,7 @@ CmdRet cutscene_suffocation_rotate(struct Camera *c) { /** * Cutscene that plays when mario dies from suffocation (ie due to HMC gas). */ -CmdRet cutscene_suffocation(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8638,7 +8726,7 @@ CmdRet cutscene_suffocation(struct Camera *c) { set_handheld_shake(HAND_CAM_SHAKE_HIGH); } -CmdRet cutscene_enter_pool_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_pool_start(struct Camera *c) { vec3f_copy(sCutsceneVars[3].point, sMarioCamState->pos); if (gCurrLevelNum == LEVEL_CASTLE) { // entering HMC @@ -8651,13 +8739,13 @@ CmdRet cutscene_enter_pool_start(struct Camera *c) { vec3f_copy(sCutsceneVars[0].point, c->focus); } -CmdRet cutscene_enter_pool_loop(struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_pool_loop(struct Camera *c) { UNUSED u32 pad[2]; cutscene_goto_cvar_pos(c, 1200.f, 0x2000, 0x200, 0); } -CmdRet cutscene_enter_pool(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -8667,7 +8755,7 @@ CmdRet cutscene_enter_pool(struct Camera *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) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_start(struct Camera *c) { reset_pan_distance(c); store_info_cannon(c); @@ -8678,14 +8766,14 @@ CmdRet cutscene_pyramid_top_explode_start(struct Camera *c) { /** * Zoom in on the pyramid. */ -CmdRet cutscene_pyramid_top_explode_zoom_in(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_zoom_in(UNUSED struct Camera *c) { set_fov_function(CAM_FOV_APP_30); } /** * Look at the pyramid top. */ -CmdRet cutscene_pyramid_top_explode_focus(struct Camera *c) { +BAD_RETURN(s32) 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; } @@ -8693,7 +8781,7 @@ CmdRet cutscene_pyramid_top_explode_focus(struct Camera *c) { /** * Store the old pos and focus, then warp to the pyramid top. */ -CmdRet cutscene_pyramid_top_explode_warp(struct Camera *c) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_warp(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -8712,7 +8800,7 @@ CmdRet cutscene_pyramid_top_explode_warp(struct Camera *c) { /** * Close up view of the spinning pyramid top as it rises. */ -CmdRet cutscene_pyramid_top_explode_closeup(struct Camera *c) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_closeup(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -8729,14 +8817,14 @@ CmdRet cutscene_pyramid_top_explode_closeup(struct Camera *c) { /** * Shake the camera during the closeup. */ -CmdRet cutscene_pyramid_top_explode_cam_shake(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_cam_shake(UNUSED struct Camera *c) { set_environmental_camera_shake(SHAKE_ENV_PYRAMID_EXPLODE); } /** * Warp back to the old position, and start a heavy camera shake. */ -CmdRet cutscene_pyramid_top_explode_warp_back(struct Camera *c) { +BAD_RETURN(s32) cutscene_pyramid_top_explode_warp_back(struct Camera *c) { UNUSED u32 pad[2]; vec3f_copy(c->pos, sCutsceneVars[4].point); @@ -8747,7 +8835,7 @@ CmdRet cutscene_pyramid_top_explode_warp_back(struct Camera *c) { /** * An unused cutscene for when the pyramid explodes. */ -CmdRet cutscene_pyramid_top_explode(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8760,7 +8848,7 @@ CmdRet cutscene_pyramid_top_explode(struct Camera *c) { /** * End the pyramid top explosion cutscene. */ -CmdRet cutscene_pyramid_top_explode_end(struct Camera *c) { +BAD_RETURN(s32) 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 @@ -8770,7 +8858,7 @@ CmdRet cutscene_pyramid_top_explode_end(struct Camera *c) { /** * Store the camera focus in cvar0, and store the top of the pyramid in cvar3. */ -CmdRet cutscene_enter_pyramid_top_start(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -8778,7 +8866,7 @@ CmdRet cutscene_enter_pyramid_top_start(struct Camera *c) { /** * Cutscene that plays when mario enters the top of the pyramid. */ -CmdRet cutscene_enter_pyramid_top(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8806,7 +8894,7 @@ static void unused_cutscene_goto_cvar(struct Camera *c) { * cvar9.point is gCutsceneFocus's position * cvar9.angle[1] is the yaw between mario and the gCutsceneFocus */ -CmdRet cutscene_dialog_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_dialog_start(struct Camera *c) { UNUSED f32 unused1; UNUSED s16 unused2; s16 yaw; @@ -8848,7 +8936,7 @@ CmdRet cutscene_dialog_start(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_dialog_move_mario_shoulder(struct Camera *c) { f32 dist; s16 pitch, yaw; Vec3f focus, pos; @@ -8882,7 +8970,7 @@ CmdRet cutscene_dialog_move_mario_shoulder(struct Camera *c) { /** * Create the dialog with sCutsceneDialogID */ -CmdRet cutscene_dialog_create_dialog_box(struct Camera *c) { +BAD_RETURN(s32) cutscene_dialog_create_dialog_box(struct Camera *c) { if (c->cutscene == CUTSCENE_RACE_DIALOG) { create_dialog_box_with_response(sCutsceneDialogID); } else { @@ -8896,7 +8984,7 @@ CmdRet cutscene_dialog_create_dialog_box(struct Camera *c) { /** * Cutscene that plays when mario talks to an object. */ -CmdRet cutscene_dialog(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -8922,14 +9010,14 @@ CmdRet cutscene_dialog(struct Camera *c) { /** * Sets the CAM_FLAG_UNUSED_CUTSCENE_ACTIVE flag, which does nothing. */ -CmdRet cutscene_dialog_set_flag(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_dialog_set_flag(UNUSED struct Camera *c) { sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } /** * Ends the dialog cutscene. */ -CmdRet cutscene_dialog_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_dialog_end(struct Camera *c) { sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; c->cutscene = 0; clear_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); @@ -8940,7 +9028,7 @@ CmdRet cutscene_dialog_end(struct Camera *c) { * * In this cutscene, cvar0.angle[0] is used as a state variable. */ -CmdRet cutscene_read_message_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_read_message_start(struct Camera *c) { cutscene_soften_music(c); transition_next_state(c, 30); reset_pan_distance(c); @@ -8964,7 +9052,7 @@ static void unused_cam_to_mario(struct Camera *c) { /** * Cutscene that plays when mario is reading a message (a sign or message on the wall) */ -CmdRet cutscene_read_message(struct Camera *c) { +BAD_RETURN(s32) cutscene_read_message(struct Camera *c) { UNUSED u32 pad[2]; cutscene_event(cutscene_read_message_start, c, 0, 0); @@ -9003,14 +9091,14 @@ CmdRet cutscene_read_message(struct Camera *c) { /** * Set CAM_FLAG_UNUSED_CUTSCENE_ACTIVE, which does nothing. */ -CmdRet cutscene_read_message_set_flag(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_read_message_set_flag(UNUSED struct Camera *c) { sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; } /** * End the message cutscene. */ -CmdRet cutscene_read_message_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_read_message_end(struct Camera *c) { sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; c->cutscene = 0; } @@ -9021,7 +9109,7 @@ CmdRet cutscene_read_message_end(struct Camera *c) { * cvar6 is the focus offset * cvar5 is the position offset */ -CmdRet cutscene_exit_succ_start(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9031,7 +9119,7 @@ CmdRet cutscene_exit_succ_start(UNUSED struct Camera *c) { /** * Set the camera pos depending on which level mario exited. */ -CmdRet cutscene_non_painting_set_cam_pos(struct Camera *c) { +BAD_RETURN(s32) cutscene_non_painting_set_cam_pos(struct Camera *c) { UNUSED u32 unused1; struct Surface *floor; UNUSED Vec3f unused2; @@ -9063,7 +9151,7 @@ CmdRet cutscene_non_painting_set_cam_pos(struct Camera *c) { /** * Update the camera focus depending on which level mario exited. */ -CmdRet cutscene_non_painting_set_cam_focus(struct Camera *c) { +BAD_RETURN(s32) 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) @@ -9079,7 +9167,7 @@ CmdRet cutscene_non_painting_set_cam_focus(struct Camera *c) { /** * Focus slightly left of mario. Perhaps to keep the bowser painting in view? */ -CmdRet cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *c) { approach_f32_asymptotic_bool(&sCutsceneVars[6].point[0], -24.f, 0.05f); } @@ -9087,7 +9175,7 @@ CmdRet cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *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) { +BAD_RETURN(s32) 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); @@ -9097,14 +9185,14 @@ CmdRet cutscene_exit_bowser_key_toss_shake(struct Camera *c) { /** * Start a camera shake when mario lands on the ground. */ -CmdRet cutscene_exit_succ_shake_landing(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_succ_shake_landing(UNUSED struct Camera *c) { set_environmental_camera_shake(SHAKE_ENV_EXPLOSION); } /** * Cutscene that plays when mario beats bowser and exits the level. */ -CmdRet cutscene_exit_bowser_succ(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9116,7 +9204,7 @@ CmdRet cutscene_exit_bowser_succ(struct Camera *c) { /** * End a non-painting exit cutscene. Used by BBH and bowser courses. */ -CmdRet cutscene_non_painting_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_non_painting_end(struct Camera *c) { c->cutscene = 0; if (c->defMode == CAMERA_MODE_CLOSE) { @@ -9134,14 +9222,14 @@ CmdRet cutscene_non_painting_end(struct Camera *c) { /** * Override the position offset. */ -CmdRet cutscene_exit_non_painting_succ_override_cvar(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_non_painting_succ_override_cvar(UNUSED struct Camera *c) { vec3f_set(sCutsceneVars[5].point, 137.f, 246.f, 1115.f); } /** * 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) { +BAD_RETURN(s32) 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); @@ -9156,7 +9244,7 @@ CmdRet cutscene_exit_non_painting_succ(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -9172,7 +9260,7 @@ CmdRet cutscene_non_painting_death_start(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); @@ -9182,7 +9270,7 @@ CmdRet cutscene_exit_bowser_death(struct Camera *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) { +BAD_RETURN(s32) cutscene_non_painting_death_override_offset(UNUSED struct Camera *c) { switch (gPrevLevel) { case LEVEL_HMC: vec3f_set(sCutsceneVars[5].point, 187.f, 369.f, -197.f); @@ -9199,7 +9287,7 @@ CmdRet cutscene_non_painting_death_override_offset(UNUSED struct Camera *c) { /** * Cutscene played when mario dies in a non-painting course, like HMC or BBH. */ -CmdRet cutscene_non_painting_death(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9215,7 +9303,7 @@ CmdRet cutscene_non_painting_death(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_cap_switch_press_start(struct Camera *c) { UNUSED s16 unused1; s16 yaw; UNUSED u32 pad[2]; @@ -9231,7 +9319,7 @@ CmdRet cutscene_cap_switch_press_start(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_cap_switch_press_rotate_around_mario(struct Camera *c) { f32 dist; s16 pitch, yaw; UNUSED s16 unusedYaw = sMarioCamState->faceAngle[1] + 0x1000; @@ -9257,14 +9345,14 @@ CmdRet cutscene_cap_switch_press_rotate_around_mario(struct Camera *c) { /** * Move the camera slightly downwards. */ -CmdRet cutscene_cap_switch_press_lower_cam(struct Camera *c) { +BAD_RETURN(s32) cutscene_cap_switch_press_lower_cam(struct Camera *c) { rotate_and_move_vec3f(c->pos, sMarioCamState->pos, 0, -0x20, 0); } /** * Move the camera closer to mario. */ -CmdRet cutscene_cap_switch_press_approach_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_cap_switch_press_approach_mario(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -9281,7 +9369,7 @@ CmdRet cutscene_cap_switch_press_approach_mario(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) 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(&sCutsceneVars[0].angle[1], 0x800, 0x20); @@ -9291,11 +9379,11 @@ CmdRet cutscene_cap_switch_press_pan_left(struct Camera *c) { /** * Create a dialog box with the cap switch's text. */ -CmdRet cutscene_cap_switch_press_create_dialog(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_cap_switch_press_create_dialog(UNUSED struct Camera *c) { create_dialog_box_with_response(gCutsceneFocus->oBehParams2ndByte + DIALOG_010); } -static UNUSED CmdRet unused_cap_switch_retrieve_info(struct Camera *c) { +static UNUSED BAD_RETURN(s32) unused_cap_switch_retrieve_info(struct Camera *c) { retrieve_info_star(c); transition_next_state(c, 30); } @@ -9303,7 +9391,7 @@ static UNUSED CmdRet unused_cap_switch_retrieve_info(struct Camera *c) { /** * Cutscene that plays when mario presses a cap switch. */ -CmdRet cutscene_cap_switch_press(struct Camera *c) { +BAD_RETURN(s32) cutscene_cap_switch_press(struct Camera *c) { f32 dist; s16 pitch, yaw; @@ -9339,7 +9427,7 @@ CmdRet cutscene_cap_switch_press(struct Camera *c) { * cvar2 is the goal position * cvar3 is the goal focus */ -CmdRet cutscene_unlock_key_door_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_unlock_key_door_start(struct Camera *c) { Vec3f posOff, focusOff; vec3f_copy(sCutsceneVars[0].point, c->pos); @@ -9354,7 +9442,7 @@ CmdRet cutscene_unlock_key_door_start(struct Camera *c) { * 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) { +BAD_RETURN(s32) 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); } @@ -9362,17 +9450,17 @@ CmdRet cutscene_unlock_key_door_approach_mario(struct Camera *c) { /** * 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) { +BAD_RETURN(s32) 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 cutscene_unlock_key_door_stub(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_unlock_key_door_stub(UNUSED struct Camera *c) { } /** * Move back to the previous pos and focus, stored in cvar0 and cvar1. */ -CmdRet cutscene_unlock_key_door_fly_back(struct Camera *c) { +BAD_RETURN(s32) 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); } @@ -9380,14 +9468,14 @@ CmdRet cutscene_unlock_key_door_fly_back(struct Camera *c) { /** * Shake the camera's fov when the key is put in the lock. */ -CmdRet cutscene_unlock_key_door_fov_shake(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_unlock_key_door_fov_shake(UNUSED struct Camera *c) { cutscene_set_fov_shake_preset(1); } /** * Cutscene that plays when mario unlocks a key door. */ -CmdRet cutscene_unlock_key_door(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9430,12 +9518,12 @@ s32 intro_peach_move_camera_start_to_pipe(struct Camera *c, struct CutsceneSplin /** * Create a dialog box with the letter text */ -CmdRet peach_letter_text(UNUSED struct Camera *c) { +BAD_RETURN(s32) peach_letter_text(UNUSED struct Camera *c) { create_dialog_box(DIALOG_020); } #ifndef VERSION_JP -CmdRet play_sound_peach_reading_letter(UNUSED struct Camera *c) { +BAD_RETURN(s32) play_sound_peach_reading_letter(UNUSED struct Camera *c) { play_sound(SOUND_PEACH_DEAR_MARIO, gDefaultSoundArgs); } #endif @@ -9444,7 +9532,7 @@ CmdRet play_sound_peach_reading_letter(UNUSED struct Camera *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) { +BAD_RETURN(s32) 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 = CUTSCENE_LOOP; @@ -9454,7 +9542,7 @@ CmdRet cutscene_intro_peach_start_to_pipe_spline(struct Camera *c) { /** * Loop the cutscene until mario exits the dialog. */ -CmdRet cutscene_intro_peach_dialog(struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_dialog(struct Camera *c) { if (get_dialog_id() == -1) { vec3f_copy(gLakituState.goalPos, c->pos); vec3f_copy(gLakituState.goalFocus, c->focus); @@ -9464,19 +9552,19 @@ CmdRet cutscene_intro_peach_dialog(struct Camera *c) { } } -CmdRet cutscene_intro_peach_follow_pipe_spline(struct Camera *c) { +BAD_RETURN(s32) 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 cutscene_intro_peach_clear_cutscene_status(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_clear_cutscene_status(UNUSED struct Camera *c) { sMarioCamState->cameraEvent = 0; } /** * Set fov to 8 degrees, then zoom out to 30. */ -CmdRet cutscene_intro_peach_zoom_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_zoom_fov(UNUSED struct Camera *c) { sFOVState.fov = 8.f; set_fov_function(CAM_FOV_ZOOM_30); } @@ -9484,7 +9572,7 @@ CmdRet cutscene_intro_peach_zoom_fov(UNUSED struct Camera *c) { /** * Reset the spline progress, turn on handheld shake. */ -CmdRet cutscene_intro_peach_reset_spline(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_reset_spline(UNUSED struct Camera *c) { sCutsceneSplineSegment = 0; sCutsceneSplineSegmentProgress = 0.1f; //! @bug since this event is only called for one frame, this handheld shake is turned off on the @@ -9496,16 +9584,16 @@ CmdRet cutscene_intro_peach_reset_spline(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_intro_peach_handheld_shake_off(UNUSED struct Camera *c) { set_handheld_shake(HAND_CAM_SHAKE_OFF); } -CmdRet intro_pipe_exit_text(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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 Camera *c) { +BAD_RETURN(s32) play_sound_intro_turn_on_hud(UNUSED struct Camera *c) { play_sound_rbutton_changed(); } #endif @@ -9513,14 +9601,20 @@ CmdRet play_sound_intro_turn_on_hud(UNUSED struct Camera *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 +BAD_RETURN(s32) cutscene_intro_peach_fly_to_pipe(struct Camera *c) { +#ifdef VERSION_US cutscene_event(play_sound_intro_turn_on_hud, c, 818, 818); +#elif VERSION_EU + cutscene_event(play_sound_intro_turn_on_hud, c, 673, 673); #endif 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); +#ifdef VERSION_EU + cutscene_event(cutscene_intro_peach_clear_cutscene_status, c, 572, 572); +#else cutscene_event(cutscene_intro_peach_clear_cutscene_status, c, 717, 717); +#endif clamp_pitch(c->pos, c->focus, 0x3B00, -0x3B00); sCutsceneVars[1].point[1] = 400.f; } @@ -9528,7 +9622,7 @@ CmdRet cutscene_intro_peach_fly_to_pipe(struct Camera *c) { /** * Lakitu flies around the warp pipe, then mario jumps out. */ -CmdRet cutscene_intro_peach_mario_appears(struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_mario_appears(struct Camera *c) { UNUSED u32 pad[2]; sMarioCamState->cameraEvent = 0; @@ -9551,14 +9645,14 @@ CmdRet cutscene_intro_peach_mario_appears(struct Camera *c) { /** * Reset the fov. This gives the effect of peach zooming out as she fades. */ -CmdRet cutscene_intro_peach_reset_fov(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_intro_peach_reset_fov(UNUSED struct Camera *c) { set_fov_function(CAM_FOV_DEFAULT); } /** * Peach reads the letter to mario. */ -CmdRet cutscene_intro_peach_letter(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9582,7 +9676,7 @@ CmdRet cutscene_intro_peach_letter(struct Camera *c) { /** * Reset the spline progress. */ -CmdRet cutscene_end_waving_start(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_end_waving_start(UNUSED struct Camera *c) { cutscene_reset_spline(); } @@ -9629,7 +9723,7 @@ struct CutsceneSplinePoint gEndWavingFocus[] = { { 0, 0, { -156, 1718, 5086 } }, { 0, 0, { -156, 1718, 5086 } }, { 0, 0, { -156, 1718, 5086 } } }; -CmdRet cutscene_end_waving(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9639,7 +9733,7 @@ CmdRet cutscene_end_waving(struct Camera *c) { /** * Called on the first frame of the credits. Resets the spline progress. */ -CmdRet cutscene_credits_reset_spline(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_credits_reset_spline(UNUSED struct Camera *c) { cutscene_reset_spline(); } @@ -9687,37 +9781,88 @@ extern struct CutsceneSplinePoint sCcmOutsideCreditsSplineFocus[]; /** * Follow splines through the courses of the game. */ -CmdRet cutscene_credits(struct Camera *c) { +BAD_RETURN(s32) cutscene_credits(struct Camera *c) { struct CutsceneSplinePoint *focus, *pos; cutscene_event(cutscene_credits_reset_spline, c, 0, 0); -#define SET_CREDITS_SPLINE(casenum, spline) \ - case casenum: \ - pos = spline ## Positions; \ - focus = spline ## Focus; \ - break; - switch (gCurrLevelArea) { - 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_BOB: + pos = sBobCreditsSplinePositions; + focus = sBobCreditsSplineFocus; + break; + case AREA_WF: + pos = sWfCreditsSplinePositions; + focus = sWfCreditsSplineFocus; + break; + case AREA_JRB_MAIN: + pos = sJrbCreditsSplinePositions; + focus = sJrbCreditsSplineFocus; + break; + case AREA_CCM_SLIDE: + pos = sCcmSlideCreditsSplinePositions; + focus = sCcmSlideCreditsSplineFocus; + break; + case AREA_BBH: + pos = sBbhCreditsSplinePositions; + focus = sBbhCreditsSplineFocus; + break; + case AREA_HMC: + pos = sHmcCreditsSplinePositions; + focus = sHmcCreditsSplineFocus; + break; + case AREA_THI_WIGGLER: + pos = sThiWigglerCreditsSplinePositions; + focus = sThiWigglerCreditsSplineFocus; + break; + case AREA_LLL_VOLCANO: + pos = sVolcanoCreditsSplinePositions; + focus = sVolcanoCreditsSplineFocus; + break; + case AREA_SSL_OUTSIDE: + pos = sSslCreditsSplinePositions; + focus = sSslCreditsSplineFocus; + break; + case AREA_DDD_WHIRLPOOL: + pos = sDddCreditsSplinePositions; + focus = sDddCreditsSplineFocus; + break; + case AREA_SL_OUTSIDE: + pos = sSlCreditsSplinePositions; + focus = sSlCreditsSplineFocus; + break; + case AREA_WDW_MAIN: + pos = sWdwCreditsSplinePositions; + focus = sWdwCreditsSplineFocus; + break; + case AREA_TTM_OUTSIDE: + pos = sTtmCreditsSplinePositions; + focus = sTtmCreditsSplineFocus; + break; + case AREA_THI_HUGE: + pos = sThiHugeCreditsSplinePositions; + focus = sThiHugeCreditsSplineFocus; + break; + case AREA_TTC: + pos = sTtcCreditsSplinePositions; + focus = sTtcCreditsSplineFocus; + break; + case AREA_RR: + pos = sRrCreditsSplinePositions; + focus = sRrCreditsSplineFocus; + break; + case AREA_SA: + pos = sSaCreditsSplinePositions; + focus = sSaCreditsSplineFocus; + break; + case AREA_COTMC: + pos = sCotmcCreditsSplinePositions; + focus = sCotmcCreditsSplineFocus; + break; + case AREA_DDD_SUB: + pos = sDddSubCreditsSplinePositions; + focus = sDddSubCreditsSplineFocus; + break; 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 @@ -9734,7 +9879,6 @@ CmdRet cutscene_credits(struct Camera *c) { pos = sCcmOutsideCreditsSplinePositions; focus = sCcmOutsideCreditsSplineFocus; } -#undef SET_CREDITS_SPLINE copy_spline_segment(sCurCreditsSplinePos, pos); copy_spline_segment(sCurCreditsSplineFocus, focus); @@ -9746,7 +9890,7 @@ CmdRet cutscene_credits(struct Camera *c) { /** * Set the camera pos relative to mario. */ -CmdRet cutscene_sliding_doors_open_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_sliding_doors_open_start(struct Camera *c) { f32 dist; s16 pitch, yaw; @@ -9767,7 +9911,7 @@ CmdRet cutscene_sliding_doors_open_start(struct Camera *c) { * cvar0.angle: mario's angle * cvar0.point: offset from mario */ -CmdRet cutscene_sliding_doors_open_set_cvars(UNUSED struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9777,23 +9921,23 @@ CmdRet cutscene_sliding_doors_open_set_cvars(UNUSED struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_sliding_doors_go_under_doorway(UNUSED struct Camera *c) { camera_approach_f32_symmetric_bool(&sCutsceneVars[0].point[1], 75.f, 10.f); } /** * Approach a y offset of 125 again. */ -CmdRet cutscene_sliding_doors_fly_back_up(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_sliding_doors_fly_back_up(UNUSED struct Camera *c) { camera_approach_f32_symmetric_bool(&sCutsceneVars[0].point[1], 125.f, 10.f); } /** * Follow mario through the door, by approaching cvar1.point. */ -CmdRet cutscene_sliding_doors_follow_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_sliding_doors_follow_mario(struct Camera *c) { Vec3f pos; - UNUSED u32 pad[4]; + UNUSED u32 pad[5]; vec3f_copy(pos, c->pos); // Update cvar1 with mario's position (the y value doesn't change) @@ -9818,7 +9962,7 @@ CmdRet cutscene_sliding_doors_follow_mario(struct Camera *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) { +BAD_RETURN(s32) cutscene_sliding_doors_open(struct Camera *c) { UNUSED u32 pad[2]; reset_pan_distance(c); @@ -9832,20 +9976,20 @@ CmdRet cutscene_sliding_doors_open(struct Camera *c) { /** * Ends the double door cutscene. */ -CmdRet cutscene_double_doors_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_double_doors_end(struct Camera *c) { set_flag_post_door(c); c->cutscene = 0; sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; } -CmdRet cutscene_enter_painting_stub(UNUSED struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_painting_stub(UNUSED struct Camera *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) { +BAD_RETURN(s32) cutscene_enter_painting(struct Camera *c) { struct Surface *floor, *highFloor; Vec3f paintingPos, focus, focusOffset; Vec3s paintingAngle; @@ -9861,7 +10005,7 @@ CmdRet cutscene_enter_painting(struct Camera *c) { paintingAngle[1] = (s32)((ripplingPainting->vYRotation / 360.f) * 65536.f); // convert degrees to IAU paintingAngle[2] = 0; - focusOffset[0] = ripplingPainting->vSize / 2.0f; + focusOffset[0] = ripplingPainting->vSize / 2; focusOffset[1] = focusOffset[0]; focusOffset[2] = 0; @@ -9871,7 +10015,7 @@ CmdRet cutscene_enter_painting(struct Camera *c) { 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); + focusOffset[2] = -(((ripplingPainting->vSize * 1000.f) / 2) / 307.f); offset_rotated(focus, paintingPos, focusOffset, paintingAngle); floorHeight = find_floor(focus[0], focus[1] + 500.f, focus[2], &highFloor) + 125.f; @@ -9905,7 +10049,7 @@ CmdRet cutscene_enter_painting(struct Camera *c) { * 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) { +BAD_RETURN(s32) cutscene_exit_painting_start(struct Camera *c) { struct Surface *floor; f32 floorHeight; @@ -9934,7 +10078,7 @@ CmdRet cutscene_exit_painting_start(struct Camera *c) { /** * Decrease cvar2's x and z offset, moving closer to mario. */ -CmdRet cutscene_exit_painting_move_to_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_painting_move_to_mario(struct Camera *c) { Vec3f pos; //! Tricky math: Since offset_rotated() flips Z offsets, you'd expect a positive Z offset to move @@ -9953,7 +10097,7 @@ CmdRet cutscene_exit_painting_move_to_mario(struct Camera *c) { /** * Move the camera down to the floor mario lands on. */ -CmdRet cutscene_exit_painting_move_to_floor(struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_painting_move_to_floor(struct Camera *c) { struct Surface *floor; Vec3f floorHeight; @@ -9973,7 +10117,7 @@ CmdRet cutscene_exit_painting_move_to_floor(struct Camera *c) { /** * Cutscene played when mario leaves a painting, either due to death or collecting a star. */ -CmdRet cutscene_exit_painting(struct Camera *c) { +BAD_RETURN(s32) 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); @@ -9989,7 +10133,7 @@ CmdRet cutscene_exit_painting(struct Camera *c) { /** * Unused. Warp the camera to mario. */ -CmdRet cutscene_unused_exit_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_unused_exit_start(struct Camera *c) { UNUSED Vec3f unused1; UNUSED Vec3s unused2; Vec3f offset; @@ -10004,7 +10148,7 @@ CmdRet cutscene_unused_exit_start(struct Camera *c) { /** * Unused. Focus on mario as he exits. */ -CmdRet cutscene_unused_exit_focus_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_unused_exit_focus_mario(struct Camera *c) { Vec3f focus; vec3f_set(focus, sMarioCamState->pos[0], sMarioCamState->pos[1] + 125.f, sMarioCamState->pos[2]); @@ -10016,7 +10160,7 @@ CmdRet cutscene_unused_exit_focus_mario(struct Camera *c) { /** * Give control back to the player. */ -CmdRet cutscene_exit_painting_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_exit_painting_end(struct Camera *c) { c->mode = CAMERA_MODE_CLOSE; c->cutscene = 0; gCutsceneTimer = CUTSCENE_STOP; @@ -10028,7 +10172,7 @@ CmdRet cutscene_exit_painting_end(struct Camera *c) { /** * End the cutscene, starting cannon mode. */ -CmdRet cutscene_enter_cannon_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_cannon_end(struct Camera *c) { sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; sStatusFlags |= CAM_FLAG_BLOCK_SMOOTH_MOVEMENT; c->mode = CAMERA_MODE_INSIDE_CANNON; @@ -10039,7 +10183,7 @@ CmdRet cutscene_enter_cannon_end(struct Camera *c) { /** * Rotate around the cannon as it rises out of the hole. */ -CmdRet cutscene_enter_cannon_raise(struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_cannon_raise(struct Camera *c) { struct Object *o; UNUSED u32 pad[2]; f32 floorHeight; @@ -10084,7 +10228,7 @@ CmdRet cutscene_enter_cannon_raise(struct Camera *c) { /** * Start the cannon entering cutscene */ -CmdRet cutscene_enter_cannon_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_enter_cannon_start(struct Camera *c) { UNUSED u32 cvar3Start; UNUSED u32 cvar4Start; struct Object *o; @@ -10113,7 +10257,7 @@ CmdRet cutscene_enter_cannon_start(struct Camera *c) { /** * Store the camera's pos and focus for the door cutscene */ -CmdRet cutscene_door_start(struct Camera *c) { +BAD_RETURN(s32) cutscene_door_start(struct Camera *c) { vec3f_copy(sCutsceneVars[0].point, c->pos); vec3f_copy(sCutsceneVars[1].point, c->focus); } @@ -10121,7 +10265,7 @@ CmdRet cutscene_door_start(struct Camera *c) { /** * Fix the camera in place while the door opens. */ -CmdRet cutscene_door_fix_cam(struct Camera *c) { +BAD_RETURN(s32) cutscene_door_fix_cam(struct Camera *c) { vec3f_copy(c->pos, sCutsceneVars[0].point); vec3f_copy(c->focus, sCutsceneVars[1].point); } @@ -10129,7 +10273,7 @@ CmdRet cutscene_door_fix_cam(struct Camera *c) { /** * Loop until mario is no longer using the door. */ -CmdRet cutscene_door_loop(struct Camera *c) { +BAD_RETURN(s32) 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; @@ -10140,7 +10284,7 @@ CmdRet cutscene_door_loop(struct Camera *c) { /** * Warp the camera behind mario. */ -CmdRet cutscene_door_move_behind_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_door_move_behind_mario(struct Camera *c) { Vec3f camOffset; s16 doorRotation; @@ -10162,7 +10306,7 @@ CmdRet cutscene_door_move_behind_mario(struct Camera *c) { /** * Follow mario through the door. */ -CmdRet cutscene_door_follow_mario(struct Camera *c) { +BAD_RETURN(s32) cutscene_door_follow_mario(struct Camera *c) { s16 pitch, yaw; f32 dist; @@ -10176,7 +10320,7 @@ CmdRet cutscene_door_follow_mario(struct Camera *c) { /** * Ends the door cutscene. Sets the camera mode to close mode unless the default is free roam. */ -CmdRet cutscene_door_end(struct Camera *c) { +BAD_RETURN(s32) cutscene_door_end(struct Camera *c) { if (c->defMode == CAMERA_MODE_FREE_ROAM) { c->mode = CAMERA_MODE_FREE_ROAM; } else { @@ -10194,7 +10338,7 @@ CmdRet cutscene_door_end(struct Camera *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) { +BAD_RETURN(s32) cutscene_door_mode(struct Camera *c) { UNUSED u32 pad[2]; reset_pan_distance(c); @@ -10228,6 +10372,16 @@ CmdRet cutscene_door_mode(struct Camera *c) { struct Cutscene sCutsceneEnding[] = { { cutscene_ending_mario_fall, 170 }, { cutscene_ending_mario_land, 70 }, +#ifdef VERSION_EU + { cutscene_ending_mario_land_closeup, 0x44 }, + { cutscene_ending_stars_free_peach, 0x15c }, + { cutscene_ending_peach_appears, 0x6d }, + { cutscene_ending_peach_descends, 0x212 }, + { cutscene_ending_mario_to_peach, 0x69 }, + { cutscene_ending_peach_wakeup, 0x1a4 }, + { cutscene_ending_dialog, 0x114 }, + { cutscene_ending_kiss, 0x10b }, +#else { cutscene_ending_mario_land_closeup, 75 }, { cutscene_ending_stars_free_peach, 386 }, { cutscene_ending_peach_appears, 139 }, @@ -10236,6 +10390,7 @@ struct Cutscene sCutsceneEnding[] = { { cutscene_ending_peach_wakeup, 425 }, { cutscene_ending_dialog, 236 }, { cutscene_ending_kiss, 245 }, +#endif { cutscene_ending_cake_for_mario, CUTSCENE_LOOP }, { cutscene_ending_stop, 0 } }; @@ -10379,7 +10534,11 @@ struct Cutscene sCutsceneUnusedExit[] = { struct Cutscene sCutsceneIntroPeach[] = { { cutscene_intro_peach_letter, CUTSCENE_LOOP }, { cutscene_intro_peach_reset_fov, 35 }, +#ifdef VERSION_EU + { cutscene_intro_peach_fly_to_pipe, 675 }, +#else { cutscene_intro_peach_fly_to_pipe, 820 }, +#endif { cutscene_intro_peach_mario_appears, 270 }, { cutscene_intro_peach_dialog, CUTSCENE_LOOP } }; diff --git a/src/game/camera.h b/src/game/camera.h index ee48f91..4f0c509 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -339,22 +339,12 @@ struct HandheldShakePoint /*0x08*/ Vec3s point; }; // size = 0x10 -// 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 -// difference doesn't affect -g codegen, only -O2. -#ifdef AVOID_UB -typedef void CmdRet; -#else -typedef s32 CmdRet; -#endif - // 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); +typedef BAD_RETURN(s32) (*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. @@ -667,6 +657,10 @@ struct LakituState // 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 s16 sSelectionFlags; +extern s16 sCameraSideCFlags; +extern s16 sCameraSoundFlags; +extern u16 sCButtonsPressed; extern struct PlayerCameraState gPlayerCameraState[2]; extern struct LakituState gLakituState; extern s16 gCameraMovementFlags; diff --git a/src/game/crash_screen.c b/src/game/crash_screen.c index deea5dc..ee75250 100644 --- a/src/game/crash_screen.c +++ b/src/game/crash_screen.c @@ -8,33 +8,7 @@ s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args); -const char *const gCauseDesc[18] = { - "Interrupt", - "TLB modification", - "TLB exception on load", - "TLB exception on store", - "Address error on load", - "Address error on store", - "Bus error on inst.", - "Bus error on data", - "System call exception", - "Breakpoint exception", - "Reserved instruction", - "Coprocessor unusable", - "Arithmetic overflow", - "Trap exception", - "Virtual coherency on inst.", - "Floating point exception", - "Watchpoint exception", - "Virtual coherency on data", -}; - -const char *const gFpcsrDesc[6] = { - "Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", - "Inexact operation", -}; - -const u8 gCrashScreenCharToGlyph[128] = { +u8 gCrashScreenCharToGlyph[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, 43, -1, -1, 37, 38, -1, 42, -1, 39, 44, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 36, -1, -1, -1, -1, 40, -1, 10, @@ -44,7 +18,7 @@ const u8 gCrashScreenCharToGlyph[128] = { }; // Bit-compressed font. '#' = 1, '.' = 0 -const u32 gCrashScreenFont[7 * 9] = { +u32 gCrashScreenFont[7 * 9 + 1] = { 0x70871c30, // .###.. ..#... .###.. .###.. ..##.. .. 0x8988a250, // #...#. .##... #...#. #...#. .#.#.. .. 0x88808290, // #...#. ..#... ....#. ....#. #..#.. .. @@ -116,8 +90,38 @@ const u32 gCrashScreenFont[7 * 9] = { 0x20821000, // ..#... ..#... ..#... .#.... ...... .. 0x00022200, // ...... ...... ..#... #...#. ...... .. 0x20800020, // ..#... ..#... ...... ...... ..#... .. + 0x00000000, }; + +char *gCauseDesc[18] = { + "Interrupt", + "TLB modification", + "TLB exception on load", + "TLB exception on store", + "Address error on load", + "Address error on store", + "Bus error on inst.", + "Bus error on data", + "System call exception", + "Breakpoint exception", + "Reserved instruction", + "Coprocessor unusable", + "Arithmetic overflow", + "Trap exception", + "Virtual coherency on inst.", + "Floating point exception", + "Watchpoint exception", + "Virtual coherency on data", +}; + +char *gFpcsrDesc[6] = { + "Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", + "Inexact operation", +}; + + + extern u64 osClockRate; struct { diff --git a/src/game/debug.c b/src/game/debug.c index 153e4c0..76edcd5 100644 --- a/src/game/debug.c +++ b/src/game/debug.c @@ -11,7 +11,6 @@ #include "main.h" #include "debug.h" #include "object_list_processor.h" -#include "room.h" #include "behavior_data.h" #define DEBUG_INFO_NOFLAGS (0 << 0) @@ -205,7 +204,7 @@ void print_mapinfo(void) { struct Surface *pfloor; UNUSED f32 bgY; UNUSED f32 water; - // s32 area; + UNUSED s32 area; // s32 angY; // // angY = gCurrentObject->oMoveAngleYaw / 182.044000; @@ -523,6 +522,7 @@ void try_do_mario_debug_object_spawn(void) { // TODO: figure out what this is static void Unknown802CA8B4(void) { +#ifndef VERSION_EU if (gCurrentObject->oMoveFlags & OBJ_MOVE_LANDED) { print_debug_top_down_objectinfo("BOUND %x", gCurrentObject->oMoveFlags); } @@ -550,6 +550,7 @@ static void Unknown802CA8B4(void) { if (gCurrentObject->oMoveFlags & OBJ_MOVE_8) { print_debug_top_down_objectinfo("OUT SCOPE %x", gCurrentObject->oMoveFlags); } +#endif } // unused, what is this? diff --git a/src/game/display.c b/src/game/display.c index a42e20c..257f63d 100644 --- a/src/game/display.c +++ b/src/game/display.c @@ -175,9 +175,17 @@ void create_task_structure(void) { gGfxSPTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE; gGfxSPTask->task.t.dram_stack = (u64 *) gGfxSPTaskStack; gGfxSPTask->task.t.dram_stack_size = SP_DRAM_STACK_SIZE8; + #ifdef VERSION_EU + // terrible hack + gGfxSPTask->task.t.output_buff = + (u64 *)((u8 *) gGfxSPTaskOutputBuffer - 0x670 + 0x280); + gGfxSPTask->task.t.output_buff_size = + (u64 *)((u8 *) gGfxSPTaskOutputBuffer+ 0x280 + 0x17790); + #else gGfxSPTask->task.t.output_buff = gGfxSPTaskOutputBuffer; gGfxSPTask->task.t.output_buff_size = (u64 *)((u8 *) gGfxSPTaskOutputBuffer + sizeof(gGfxSPTaskOutputBuffer)); + #endif gGfxSPTask->task.t.data_ptr = (u64 *) &gGfxPool->buffer; gGfxSPTask->task.t.data_size = entries * sizeof(Gfx); gGfxSPTask->task.t.yield_data_ptr = (u64 *) gGfxSPTaskYieldBuffer; @@ -223,9 +231,8 @@ void func_80247D84(void) { sp18 += D_8032C648++ * (SCREEN_WIDTH / 4); for (sp24 = 0; sp24 < ((SCREEN_HEIGHT / 16) + 1); sp24++) { - for (sp20 = 0; sp20 < (SCREEN_WIDTH / 4); sp20++) { - *sp18++ = 0; - } + // Must be on one line to match -O2 + for (sp20 = 0; sp20 < (SCREEN_WIDTH / 4); sp20++) *sp18++ = 0; sp18 += ((SCREEN_WIDTH / 4) * 14); } } diff --git a/src/game/envfx_bubbles.c b/src/game/envfx_bubbles.c index 4fd408e..6d1d912 100644 --- a/src/game/envfx_bubbles.c +++ b/src/game/envfx_bubbles.c @@ -381,54 +381,30 @@ void envfx_bubbles_update_switch(s32 mode, Vec3s camTo, Vec3s vertex1, Vec3s ver switch (mode) { case ENVFX_FLOWERS: envfx_update_flower(camTo); - vertex1[0] = 50; - vertex1[1] = 0; - vertex1[2] = 0; - vertex2[0] = 0; - vertex2[1] = 75; - vertex2[2] = 0; - vertex3[0] = -50; - vertex3[1] = 0; - vertex3[2] = 0; + vertex1[0] = 50; vertex1[1] = 0; vertex1[2] = 0; + vertex2[0] = 0; vertex2[1] = 75; vertex2[2] = 0; + vertex3[0] = -50; vertex3[1] = 0; vertex3[2] = 0; break; case ENVFX_LAVA_BUBBLES: envfx_update_lava(camTo); - vertex1[0] = 100; - vertex1[1] = 0; - vertex1[2] = 0; - vertex2[0] = 0; - vertex2[1] = 150; - vertex2[2] = 0; - vertex3[0] = -100; - vertex3[1] = 0; - vertex3[2] = 0; + vertex1[0] = 100; vertex1[1] = 0; vertex1[2] = 0; + vertex2[0] = 0; vertex2[1] = 150; vertex2[2] = 0; + vertex3[0] = -100; vertex3[1] = 0; vertex3[2] = 0; break; case ENVFX_WHIRLPOOL_BUBBLES: envfx_update_whirlpool(); - vertex1[0] = 40; - vertex1[1] = 0; - vertex1[2] = 0; - vertex2[0] = 0; - vertex2[1] = 60; - vertex2[2] = 0; - vertex3[0] = -40; - vertex3[1] = 0; - vertex3[2] = 0; + vertex1[0] = 40; vertex1[1] = 0; vertex1[2] = 0; + vertex2[0] = 0; vertex2[1] = 60; vertex2[2] = 0; + vertex3[0] = -40; vertex3[1] = 0; vertex3[2] = 0; break; case ENVFX_JETSTREAM_BUBBLES: envfx_update_jetstream(); - vertex1[0] = 40; - vertex1[1] = 0; - vertex1[2] = 0; - vertex2[0] = 0; - vertex2[1] = 60; - vertex2[2] = 0; - vertex3[0] = -40; - vertex3[1] = 0; - vertex3[2] = 0; + vertex1[0] = 40; vertex1[1] = 0; vertex1[2] = 0; + vertex2[0] = 0; vertex2[1] = 60; vertex2[2] = 0; + vertex3[0] = -40; vertex3[1] = 0; vertex3[2] = 0; break; } } @@ -441,7 +417,7 @@ void envfx_bubbles_update_switch(s32 mode, Vec3s camTo, Vec3s vertex1, Vec3s ver #if defined(VERSION_EU) && !defined(NON_MATCHING) void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, Vtx *template); -GLOBAL_ASM("asm/non_matchings/append_bubble_vertex_buffer_eu.s") +GLOBAL_ASM("asm/non_matchings/eu/append_bubble_vertex_buffer.s") #else void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, Vtx *template) { @@ -518,8 +494,8 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro Gfx *gfxStart; - gfxStart = alloc_display_list( - ((sBubbleParticleMaxCount / 5) * 10 + sBubbleParticleMaxCount + 3) * sizeof(Gfx)); + gfxStart = alloc_display_list(((sBubbleParticleMaxCount / 5) * 10 + sBubbleParticleMaxCount + 3) + * sizeof(Gfx)); if (gfxStart == NULL) { return NULL; } diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c index a26dc8c..4d3c223 100644 --- a/src/game/envfx_snow.c +++ b/src/game/envfx_snow.c @@ -219,11 +219,7 @@ void envfx_update_snow_normal(s32 snowCylinderX, s32 snowCylinderY, s32 snowCyli (gEnvFxBuffer + i)->isAlive = 1; } else { (gEnvFxBuffer + i)->xPos += RandomFloat() * 2 - 1.0f + (s16)(deltaX / 1.2); -#ifdef VERSION_EU - (gEnvFxBuffer + i)->yPos -= (s16)(deltaY * 0.8) + 2; -#else - (gEnvFxBuffer + i)->yPos -= -(s16)(deltaY * 0.8) + 2; -#endif + (gEnvFxBuffer + i)->yPos -= 2 -(s16)(deltaY * 0.8); (gEnvFxBuffer + i)->zPos += RandomFloat() * 2 - 1.0f + (s16)(deltaZ / 1.2); } } @@ -257,11 +253,7 @@ void envfx_update_snow_blizzard(s32 snowCylinderX, s32 snowCylinderY, s32 snowCy (gEnvFxBuffer + i)->isAlive = 1; } else { (gEnvFxBuffer + i)->xPos += RandomFloat() * 2 - 1.0f + (s16)(deltaX / 1.2) + 20.0f; -#ifdef VERSION_EU - (gEnvFxBuffer + i)->yPos -= (s16)(deltaY * 0.8) + 5; -#else - (gEnvFxBuffer + i)->yPos -= -(s16)(deltaY * 0.8) + 5; -#endif + (gEnvFxBuffer + i)->yPos -= 5 -(s16)(deltaY * 0.8); (gEnvFxBuffer + i)->zPos += RandomFloat() * 2 - 1.0f + (s16)(deltaZ / 1.2); } } @@ -351,7 +343,7 @@ void rotate_triangle_vertices(Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, s16 p */ #if defined(VERSION_EU) && !defined(NON_MATCHING) void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3); -GLOBAL_ASM("asm/non_matchings/append_snowflake_vertex_buffer_eu.s") +GLOBAL_ASM("asm/non_matchings/eu/append_snowflake_vertex_buffer.s") #else void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3) { s32 i = 0; diff --git a/src/game/game.c b/src/game/game.c index ad80083..a80a10c 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -21,8 +21,14 @@ // FIXME: I'm not sure all of these variables belong in this file, but I don't // know of a good way to split them struct Controller gControllers[3]; +struct SPTask *gGfxSPTask; +Gfx *gDisplayListHead; +u8 *gGfxPoolEnd; +struct GfxPool *gGfxPool; OSContStatus gControllerStatuses[4]; OSContPad gControllerPads[4]; +u8 gControllerBits; +s8 gEepromProbe; OSMesgQueue gGameVblankQueue; OSMesgQueue D_80339CB8; OSMesg D_80339CD0; @@ -32,13 +38,6 @@ uintptr_t gPhysicalFrameBuffers[3]; uintptr_t gPhysicalZBuffer; void *D_80339CF0; void *D_80339CF4; -struct SPTask *gGfxSPTask; -Gfx *gDisplayListHead; -u8 *gGfxPoolEnd; -struct GfxPool *gGfxPool; -u8 gControllerBits; -s8 gEepromProbe; - struct MarioAnimation D_80339D10; struct MarioAnimation gDemo; UNUSED u8 filler80339D30[0x90]; diff --git a/src/game/geo_misc.c b/src/game/geo_misc.c index 6d4b3c4..d0d4227 100644 --- a/src/game/geo_misc.c +++ b/src/game/geo_misc.c @@ -210,8 +210,11 @@ Gfx *geo_exec_cake_end_screen(s32 callContext, struct GraphNode *node, UNUSED f3 displayListHead = displayList; generatedNode->fnNode.node.flags = (generatedNode->fnNode.node.flags & 0xFF) | 0x100; - +#ifdef VERSION_EU + gSPDisplayList(displayListHead++, dl_cake_end_screen); +#else gSPDisplayList(displayListHead++, dl_proj_mtx_fullscreen); +#endif #ifdef VERSION_EU switch (eu_get_language()) { case LANGUAGE_ENGLISH: diff --git a/src/game/geo_misc.h b/src/game/geo_misc.h index d44975b..faa5b26 100644 --- a/src/game/geo_misc.h +++ b/src/game/geo_misc.h @@ -22,4 +22,15 @@ extern Gfx *geo_exec_flying_carpet_timer_update(s32 callContext, struct GraphNod extern Gfx *geo_exec_flying_carpet_create(s32 callContext, struct GraphNode *node, f32 mtx[4][4]); extern Gfx *geo_exec_cake_end_screen(s32 callContext, struct GraphNode *node, f32 mtx[4][4]); +#define gLoadBlockTexture(dl, width, height, format, image) \ +{ \ + gDPSetTextureImage((dl), (format), G_IM_SIZ_16b, 1, (image)); \ + gDPTileSync((dl)); \ + gDPSetTile((dl), (format), G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, \ + G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); \ + gDPLoadSync((dl)); \ + gDPLoadBlock((dl), G_TX_LOADTILE, 0, 0, (width) * (height) - 1, CALC_DXT((width), G_IM_SIZ_16b_BYTES)) \ +} + + #endif /* _TRANSPARENT_TEXTURE_H */ diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 98709f9..1b6cd96 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -35,6 +35,10 @@ u16 gDialogColorFadeTimer; s8 gLastDialogLineNum; s32 gDialogVariable; u16 gDialogTextAlpha; +#ifdef VERSION_EU +s16 gDialogX; // D_8032F69A +s16 gDialogY; // D_8032F69C +#endif s16 gCutsceneMsgXOffset; s16 gCutsceneMsgYOffset; s8 gRedCoinsCollected; @@ -106,18 +110,15 @@ s8 gDialogBoxType = DIALOG_TYPE_ROTATE; s16 gDialogID = -1; s16 gLastDialogPageStrPos = 0; s16 gDialogTextPos = 0; // EU: D_802FD64C +#ifdef VERSION_EU +s32 gInGameLanguage = 0; +#endif s8 gDialogLineNum = 1; s8 gLastDialogResponse = 0; u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; s32 gDialogResponse = 0; -#ifdef VERSION_EU -// TODO: where do these belong? -s16 gDialogX; // D_8032F69A -s16 gDialogY; // D_8032F69C -s32 gInGameLanguage; -#endif void create_dl_identity_matrix(void) { Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); @@ -126,26 +127,10 @@ void create_dl_identity_matrix(void) { return; } - matrix->m[0][0] = 0x00010000; - matrix->m[1][0] = 0x00000000; - matrix->m[2][0] = 0x00000000; - matrix->m[3][0] = 0x00000000; - - matrix->m[0][1] = 0x00000000; - matrix->m[1][1] = 0x00010000; - matrix->m[2][1] = 0x00000000; - matrix->m[3][1] = 0x00000000; - - matrix->m[0][2] = 0x00000001; - matrix->m[1][2] = 0x00000000; - matrix->m[2][2] = 0x00000000; - matrix->m[3][2] = 0x00000000; - - matrix->m[0][3] = 0x00000000; - matrix->m[1][3] = 0x00000001; - matrix->m[2][3] = 0x00000000; - matrix->m[3][3] = 0x00000000; - + matrix->m[0][0] = 0x00010000; matrix->m[1][0] = 0x00000000; matrix->m[2][0] = 0x00000000; matrix->m[3][0] = 0x00000000; + matrix->m[0][1] = 0x00000000; matrix->m[1][1] = 0x00010000; matrix->m[2][1] = 0x00000000; matrix->m[3][1] = 0x00000000; + matrix->m[0][2] = 0x00000001; matrix->m[1][2] = 0x00000000; matrix->m[2][2] = 0x00000000; matrix->m[3][2] = 0x00000000; + matrix->m[0][3] = 0x00000000; matrix->m[1][3] = 0x00000001; matrix->m[2][3] = 0x00000000; matrix->m[3][3] = 0x00000000; gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); } @@ -877,8 +862,7 @@ void int_to_str(s32 num, u8 *dst) { s8 pos = 0; if (num > 999) { - dst[0] = 0x00; - dst[1] = DIALOG_CHAR_TERMINATOR; + dst[0] = 0x00; dst[1] = DIALOG_CHAR_TERMINATOR; return; } @@ -1212,7 +1196,7 @@ u32 ensure_nonnegative(s16 value) { #if defined(VERSION_EU) && !defined(NON_MATCHING) // TODO: EU is not quite matching void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 lowerBound); -GLOBAL_ASM("asm/non_matchings/handle_dialog_text_and_pages_eu.s") +GLOBAL_ASM("asm/non_matchings/eu/handle_dialog_text_and_pages.s") #else #ifdef VERSION_JP void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog) @@ -1833,9 +1817,15 @@ void render_dialog_entries(void) { if (gLastDialogPageStrPos == -1 && gLastDialogResponse == 1) { render_dialog_triangle_choice(); } - + #ifdef VERSION_EU + #undef BORDER_HEIGHT + #define BORDER_HEIGHT 8 + #endif gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 2, 2, SCREEN_WIDTH - BORDER_HEIGHT/2, SCREEN_HEIGHT - BORDER_HEIGHT/2); - + #ifdef VERSION_EU + #undef BORDER_HEIGHT + #define BORDER_HEIGHT 1 + #endif if (gLastDialogPageStrPos != -1 && gDialogBoxState == DIALOG_STATE_VERTICAL) { render_dialog_string_color(dialog->linesPerBox); } @@ -1943,11 +1933,11 @@ void do_cutscene_handler(void) { break; case LANGUAGE_FRENCH: x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex + 8]); + print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex]); break; case LANGUAGE_GERMAN: x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex + 16]); + print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex]); break; } #else @@ -2806,7 +2796,7 @@ void render_course_complete_lvl_info_and_hud_str(void) { u8 textCatch[] = { TEXT_CATCH }; u8 textClear[] = { TEXT_CLEAR }; #elif defined(VERSION_EU) - UNUSED u8 textClear[] = { TEXT_CLEAR }; // unused in EU + UNUSED u8 textCatch[] = { TEXT_CATCH }; // unused in EU u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; #define textCourse gTextCourseArr[gInGameLanguage] #else diff --git a/src/game/interaction.c b/src/game/interaction.c index 9fe163d..94d539b 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -273,9 +273,12 @@ void mario_drop_held_object(struct MarioState *m) { set_object_held_state(m->heldObj, bhvCarrySomething4); - m->heldObj->oPosX = m->marioBodyState->unk18[0]; + // ! When dropping an object instead of throwing it, it will be put at Mario's + // y-positon instead of the HOLP's y-position. This fact is often exploited when + // cloning objects. + m->heldObj->oPosX = m->marioBodyState->heldObjLastPosition[0]; m->heldObj->oPosY = m->pos[1]; - m->heldObj->oPosZ = m->marioBodyState->unk18[2]; + m->heldObj->oPosZ = m->marioBodyState->heldObjLastPosition[2]; m->heldObj->oMoveAngleYaw = m->faceAngle[1]; @@ -291,9 +294,9 @@ void mario_throw_held_object(struct MarioState *m) { set_object_held_state(m->heldObj, bhvCarrySomething5); - m->heldObj->oPosX = m->marioBodyState->unk18[0] + 32.0f * sins(m->faceAngle[1]); - m->heldObj->oPosY = m->marioBodyState->unk18[1]; - m->heldObj->oPosZ = m->marioBodyState->unk18[2] + 32.0f * coss(m->faceAngle[1]); + m->heldObj->oPosX = m->marioBodyState->heldObjLastPosition[0] + 32.0f * sins(m->faceAngle[1]); + m->heldObj->oPosY = m->marioBodyState->heldObjLastPosition[1]; + m->heldObj->oPosZ = m->marioBodyState->heldObjLastPosition[2] + 32.0f * coss(m->faceAngle[1]); m->heldObj->oMoveAngleYaw = m->faceAngle[1]; diff --git a/src/game/interaction.h b/src/game/interaction.h index 19571da..113a5ce 100644 --- a/src/game/interaction.h +++ b/src/game/interaction.h @@ -120,7 +120,7 @@ extern u32 mario_check_object_grab(struct MarioState *); extern u32 get_door_save_file_flag(struct Object *); extern void mario_process_interactions(struct MarioState *); extern void mario_handle_special_floors(struct MarioState *); -extern void init_bully_collision_data( +extern BAD_RETURN(s32) init_bully_collision_data( struct BullyCollisionData *data, f32 posX, f32 posZ, diff --git a/src/game/level_update.c b/src/game/level_update.c index 179b3e2..8713bbb 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -83,6 +83,7 @@ const char *credits06[] = { "2COURSE DIRECTORS", "YOICHI YAMADA", "YASUHISA YAMA const char *credits07[] = { "2COURSE DESIGNERS", "KENTA USUI", "NAOKI MORI" }; const char *credits08[] = { "3COURSE DESIGNERS", "YOSHIKI HARUHANA", "MAKOTO MIYANAGA", "KATSUHIKO KANNO" }; +#ifdef VERSION_US const char *credits09[] = { "1SOUND COMPOSER", "KOJI KONDO" }; const char *credits10[] = { "4SOUND EFFECTS", "SOUND PROGRAMMER", "YOJI INAGAKI", "HIDEAKI SHIMIZU" }; // as well as sound effects and sound programmer @@ -93,13 +94,33 @@ const char *credits14[] = { "1TECHNICAL SUPPORT", "SGI N64 PROJECT STAFF" }; const char *credits15[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" }; const char *credits16[] = { "5SCREEN TEXT WRITER", "TRANSLATION", "LESLIE SWAN", "MINA AKINO", "HIRO YAMADA" }; // ...in order to make room for these 2 new lines +#else // VERSION_EU +const char *credits09[] = { "7SOUND COMPOSER", "SOUND EFFECTS", "SOUND PROGRAMMER", "KOJI KONDO", + "YOJI INAGAKI", "HIDEAKI SHIMIZU" }; +const char *credits10[] = { "63-D ANIMATORS", "ADDITIONAL GRAPHICS", "YOSHIAKI KOIZUMI", "SATORU TAKIZAWA", + "MASANAO ARIMOTO" }; +const char *credits11[] = { "3TECHNICAL SUPPORT", "TAKAO SAWANO", "HIROHITO YOSHIMOTO", "HIROTO YADA" }; +const char *credits12[] = { "1TECHNICAL SUPPORT", "SGI N64 PROJECT STAFF" }; +const char *credits13[] = { "2PROGRESS MANAGEMENT", "KIMIYOSHI FUKUI", "KEIZO KATO" }; +const char *credits14[] = { "5SCREEN TEXT WRITER", "ENGLISH TRANSLATION", "LESLIE SWAN", "MINA AKINO", + "HIRO YAMADA" }; +const char *credits15[] = { "4SCREEN TEXT WRITER", "FRENCH TRANSLATION", "JULIEN BARDAKOFF", + "KENJI HARAGUCHI" }; +const char *credits16[] = { "4SCREEN TEXT WRITER", "GERMAN TRANSLATION", "THOMAS GOERG", + "THOMAS SPINDLER" }; +#endif const char *credits17[] = { "4MARIO VOICE", "PEACH VOICE", "CHARLES MARTINET", "LESLIE SWAN" }; const char *credits18[] = { "3SPECIAL THANKS TO", "EAD STAFF", "ALL NINTENDO PERSONNEL", - "MARIO CLUB STAFF" }; +#ifdef VERSION_US + "MARIO CLUB STAFF" }; +#else // VERSION_EU + "SUPER MARIO CLUB STAFF" }; +#endif const char *credits19[] = { "1PRODUCER", "SHIGERU MIYAMOTO" }; const char *credits20[] = { "1EXECUTIVE PRODUCER", "HIROSHI YAMAUCHI" }; #endif + struct CreditsEntry sCreditsSequence[] = { { LEVEL_CASTLE_GROUNDS, 1, 1, -128, { 0, 8000, 0 }, NULL }, { LEVEL_BOB, 1, 1, 117, { 713, 3918, -3889 }, credits01 }, @@ -127,36 +148,31 @@ struct CreditsEntry sCreditsSequence[] = { }; struct MarioState gMarioStates[1]; -struct MarioState *gMarioState = &gMarioStates[0]; - -u8 unused1[4] = { 0 }; - -s8 D_8032C9E0 = 0; - +struct HudDisplay gHudDisplay; s16 sCurrPlayMode; u16 D_80339ECA; - s16 sTransitionTimer; void (*sTransitionUpdate)(s16 *); - -u8 unused3[4]; - struct WarpDest sWarpDest; - s16 D_80339EE0; - s16 sDelayedWarpOp; s16 sDelayedWarpTimer; s16 sSourceWarpNodeId; s32 sDelayedWarpArg; +#ifdef VERSION_EU +s16 unusedEULevelUpdateBss1; +#endif +s8 sTimerRunning; +s8 gShouldNotPlayCastleMusic; +struct MarioState *gMarioState = &gMarioStates[0]; +u8 unused1[4] = { 0 }; +s8 D_8032C9E0 = 0; +u8 unused3[4]; u8 unused4[2]; -s8 sTimerRunning; -struct HudDisplay gHudDisplay; -s8 gShouldNotPlayCastleMusic; void basic_update(s16 *arg); @@ -685,7 +701,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { switch (warpOp) { case WARP_OP_DEMO_NEXT: case WARP_OP_DEMO_END: - sDelayedWarpTimer = 20; + do {sDelayedWarpTimer = 20;} while (0); sSourceWarpNodeId = WARP_NODE_F0; gSavedCourseNum = 0; val04 = FALSE; diff --git a/src/game/main.c b/src/game/main.c index f677f6f..dd3f8f6 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -25,6 +25,10 @@ OSThread gIdleThread; OSThread gMainThread; OSThread gGameLoopThread; OSThread gSoundThread; +OSIoMesg gDmaIoMesg; +OSMesg D_80339BEC; +OSMesgQueue gDmaMesgQueue; +OSMesgQueue gSIEventMesgQueue; OSMesgQueue gPIMesgQueue; OSMesgQueue gIntrMesgQueue; OSMesgQueue gSPTaskMesgQueue; @@ -33,10 +37,6 @@ OSMesg gPIMesgBuf[32]; OSMesg gSIEventMesgBuf[1]; OSMesg gIntrMesgBuf[16]; OSMesg gUnknownMesgBuf[16]; -OSIoMesg gDmaIoMesg; -OSMesg D_80339BEC; -OSMesgQueue gDmaMesgQueue; -OSMesgQueue gSIEventMesgQueue; struct VblankHandler *gVblankHandler1 = NULL; struct VblankHandler *gVblankHandler2 = NULL; @@ -408,8 +408,10 @@ void thread1_idle(UNUSED void *arg) { } else { osViSetMode(&osViModeTable[OS_VI_PAL_LAN1]); } -#else +#elif defined(VERSION_JP) osViSetMode(&osViModeTable[OS_VI_NTSC_LAN1]); +#else // VERSION_EU + osViSetMode(&osViModeTable[OS_VI_PAL_LAN1]); #endif osViBlack(TRUE); osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON); diff --git a/src/game/mario.c b/src/game/mario.c index a64a46c..3e18342 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -350,7 +350,8 @@ void play_mario_heavy_landing_sound_once(struct MarioState *m, u32 soundBits) { void play_mario_sound(struct MarioState *m, s32 actionSound, s32 marioSound) { if (actionSound == SOUND_ACTION_TERRAIN_JUMP) { play_mario_action_sound( - m, (m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_JUMP : SOUND_ACTION_TERRAIN_JUMP, 1); + m, (m->flags & MARIO_METAL_CAP) ? (s32)SOUND_ACTION_METAL_JUMP + : (s32)SOUND_ACTION_TERRAIN_JUMP, 1); } else { play_sound_if_no_flag(m, actionSound, MARIO_ACTION_SOUND_PLAYED); } @@ -1214,7 +1215,7 @@ void squish_mario_model(struct MarioState *m) { } // If timer is less than 16, rubber-band Mario's size scale up and down. else if (m->squishTimer <= 16) { - m->squishTimer--; + m->squishTimer -= 1; m->marioObj->header.gfx.scale[1] = 1.0f - ((sSquishScaleOverTime[15 - m->squishTimer] * 0.6f) / 100.0f); @@ -1223,7 +1224,7 @@ void squish_mario_model(struct MarioState *m) { m->marioObj->header.gfx.scale[2] = m->marioObj->header.gfx.scale[0]; } else { - m->squishTimer--; + m->squishTimer -= 1; vec3f_set(m->marioObj->header.gfx.scale, 1.4f, 0.4f, 1.4f); } @@ -1525,7 +1526,7 @@ void mario_reset_bodystate(struct MarioState *m) { bodyState->eyeState = MARIO_EYES_BLINK; bodyState->handState = MARIO_HAND_FISTS; bodyState->modelState = 0; - bodyState->unk07 = 0; + bodyState->wingFlutter = FALSE; m->flags &= ~MARIO_METAL_SHOCK; } @@ -1650,7 +1651,7 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) { if ((m->flags & MARIO_TELEPORTING) && (m->fadeWarpOpacity != 0xFF)) { bodyState->modelState &= ~0xFF; - bodyState->modelState |= (m->fadeWarpOpacity | 0x100); + bodyState->modelState |= (0x100 | m->fadeWarpOpacity); } } @@ -1820,7 +1821,7 @@ void init_mario(void) { mario_reset_bodystate(gMarioState); update_mario_info_for_cam(gMarioState); - gMarioState->marioBodyState->unk0B = 0; + gMarioState->marioBodyState->punchState = 0; gMarioState->marioObj->oPosX = gMarioState->pos[0]; gMarioState->marioObj->oPosY = gMarioState->pos[1]; diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index c151ce6..8b8da4e 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -442,13 +442,9 @@ s32 act_jump(struct MarioState *m) { } s32 act_double_jump(struct MarioState *m) { - s32 animation; - - if (m->vel[1] >= 0.0f) { - animation = MARIO_ANIM_DOUBLE_JUMP_RISE; - } else { - animation = MARIO_ANIM_DOUBLE_JUMP_FALL; - } + s32 animation = (m->vel[1] >= 0.0f) + ? MARIO_ANIM_DOUBLE_JUMP_RISE + : MARIO_ANIM_DOUBLE_JUMP_FALL; if (check_kick_or_dive_in_air(m)) { return TRUE; @@ -906,7 +902,7 @@ s32 act_ground_pound(struct MarioState *m) { play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); } - m->actionTimer += 1; + m->actionTimer++; if (m->actionTimer >= m->marioObj->header.gfx.unk38.curAnim->unk08 + 4) { play_sound(SOUND_MARIO_GROUND_POUND_WAH, m->marioObj->header.gfx.cameraToObject); m->actionState = 1; @@ -1577,7 +1573,7 @@ s32 act_jump_kick(struct MarioState *m) { animFrame = m->marioObj->header.gfx.unk38.animFrame; if (animFrame == 0) { - m->marioBodyState->unk0B = 0x86; + m->marioBodyState->punchState = (2 << 6) | 6; } if (animFrame >= 0 && animFrame < 8) { m->flags |= MARIO_KICKING; diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 0e54f94..216d96b 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -1,5 +1,5 @@ #include - +#include "prevent_bss_reordering.h" #include "sm64.h" #include "game.h" #include "sound_init.h" @@ -418,7 +418,7 @@ s32 act_reading_npc_dialog(struct MarioState *m) { } vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); - vec3s_set(m->marioBodyState->unk12, m->actionTimer, 0, 0); + vec3s_set(m->marioBodyState->headAngle, m->actionTimer, 0, 0); if (m->actionState != 8) { m->actionState++; @@ -499,7 +499,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { } } // apply head turn - vec3s_set(m->marioBodyState->unk12, m->actionTimer, 0, 0); + vec3s_set(m->marioBodyState->headAngle, m->actionTimer, 0, 0); return FALSE; } @@ -1651,9 +1651,15 @@ static void intro_cutscene_hide_hud_and_mario(struct MarioState *m) { advance_cutscene_step(m); } +#ifdef VERSION_EU + #define TIMER_SPAWN_PIPE 47 +#else + #define TIMER_SPAWN_PIPE 37 +#endif + static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) { if ((s16) m->statusForCamera->cameraEvent != CAM_EVENT_START_INTRO) { - if (m->actionTimer++ == 37) { + if (m->actionTimer++ == TIMER_SPAWN_PIPE) { sIntroWarpPipeObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_CASTLE_GROUNDS_WARP_PIPE, bhvStaticObject, -1328, 60, 4664, 0, 180, 0); @@ -1661,6 +1667,13 @@ static void intro_cutscene_peach_lakitu_scene(struct MarioState *m) { } } } +#undef TIMER_SPAWN_PIPE + +#ifdef VERSION_EU + #define TIMER_RAISE_PIPE 28 +#else + #define TIMER_RAISE_PIPE 38 +#endif static void intro_cutscene_raise_pipe(struct MarioState *m) { sIntroWarpPipeObj->oPosY = camera_approach_f32_symmetric(sIntroWarpPipeObj->oPosY, 260.0f, 10.0f); @@ -1669,11 +1682,12 @@ static void intro_cutscene_raise_pipe(struct MarioState *m) { play_sound(SOUND_MENU_EXIT_PIPE, sIntroWarpPipeObj->header.gfx.cameraToObject); } - if (m->actionTimer++ == 38) { + if (m->actionTimer++ == TIMER_RAISE_PIPE) { m->vel[1] = 60.0f; advance_cutscene_step(m); } } +#undef TIMER_RAISE_PIPE static void intro_cutscene_jump_out_of_pipe(struct MarioState *m) { if (m->actionTimer == 25) { @@ -1683,9 +1697,15 @@ static void intro_cutscene_jump_out_of_pipe(struct MarioState *m) { if (m->actionTimer++ >= 118) { m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; - play_sound_if_no_flag(m, SOUND_MARIO_YAHOO, MARIO_MARIO_SOUND_PLAYED); -#ifndef VERSION_JP +#ifdef VERSION_EU + // For some reason these calls were swapped. play_sound_if_no_flag(m, SOUND_ACTION_HIT_3, MARIO_ACTION_SOUND_PLAYED); + play_sound_if_no_flag(m, SOUND_MARIO_YAHOO, MARIO_MARIO_SOUND_PLAYED); +#else + play_sound_if_no_flag(m, SOUND_MARIO_YAHOO, MARIO_MARIO_SOUND_PLAYED); + #ifndef VERSION_JP + play_sound_if_no_flag(m, SOUND_ACTION_HIT_3, MARIO_ACTION_SOUND_PLAYED); + #endif #endif set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP); @@ -1920,10 +1940,15 @@ static s32 act_jumbo_star_cutscene(struct MarioState *m) { return FALSE; } +// TODO: (Scrub C) This function almost certainly has a version that matches for both -g and -O2 static void generate_yellow_sparkles(s16 x, s16 y, s16 z, f32 radius) { s16 offsetX = radius * coss(sSparkleGenTheta) * sins(sSparkleGenPhi); s16 offsetY = radius * sins(sSparkleGenTheta); s16 offsetZ = radius * coss(sSparkleGenTheta) * coss(sSparkleGenPhi); +#ifdef VERSION_EU + s16 dTheta = 0x3800; + s16 dPhi = 0x6000; +#endif spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x + offsetX, y + offsetY, z + offsetZ, 0, 0, 0); @@ -1936,10 +1961,16 @@ static void generate_yellow_sparkles(s16 x, s16 y, s16 z, f32 radius) { spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x - offsetX, y - offsetY, z - offsetZ, 0, 0, 0); +#ifdef VERSION_EU + sSparkleGenTheta += dTheta; + sSparkleGenPhi += dPhi; +#else sSparkleGenTheta += 0x3800; sSparkleGenPhi += 0x6000; +#endif } + // not sure what this does, returns the height of the floor, but idk about the // other stuff (animation related?) static f32 func_8025BC14(struct Object *o) { @@ -2012,6 +2043,14 @@ static void end_peach_cutscene_summon_jumbo_star(struct MarioState *m) { play_sound(SOUND_AIR_PEACH_TWINKLE, sEndJumboStarObj->header.gfx.cameraToObject); } +#ifdef VERSION_EU + #define TIMER_FADE_IN_PEACH 201 + #define TIMER_DESCEND_PEACH 280 +#else + #define TIMER_FADE_IN_PEACH 276 + #define TIMER_DESCEND_PEACH 355 +#endif + // free peach from the stained glass window static void end_peach_cutscene_spawn_peach(struct MarioState *m) { if (m->actionTimer == 1) { @@ -2046,13 +2085,15 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) { sEndToadAnims[0] = 4; sEndToadAnims[1] = 5; } - if (m->actionTimer >= 276) { + + if (m->actionTimer >= TIMER_FADE_IN_PEACH) { sEndPeachObj->oOpacity = camera_approach_f32_symmetric(sEndPeachObj->oOpacity, 255.0f, 2.0f); } if (m->actionTimer >= 40) { generate_yellow_sparkles(0, 2628, -1300, 150.0f); } - if (m->actionTimer == 355) { + + if (m->actionTimer == TIMER_DESCEND_PEACH) { advance_cutscene_step(m); } // probably added sounds later and missed the previous >= 40 check @@ -2061,6 +2102,12 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) { } } +#ifdef VERSION_EU + #define TIMER_RUN_TO_PEACH 531 +#else + #define TIMER_RUN_TO_PEACH 584 +#endif + // descend peach static void end_peach_cutscene_descend_peach(struct MarioState *m) { generate_yellow_sparkles(0, sEndPeachObj->oPosY, -1300, 150.0f); @@ -2082,11 +2129,13 @@ static void end_peach_cutscene_descend_peach(struct MarioState *m) { play_sound(SOUND_AIR_PEACH_TWINKLE, sEndPeachObj->header.gfx.cameraToObject); - if (m->actionTimer >= 584) { + if (m->actionTimer >= TIMER_RUN_TO_PEACH) { advance_cutscene_step(m); } } +#undef TIMER_RUN_TO_PEACH + // mario runs to peach static void end_peach_cutscene_run_to_peach(struct MarioState *m) { struct Surface *surf; @@ -2170,6 +2219,14 @@ static void end_peach_cutscene_dialog_1(struct MarioState *m) { } } +#ifdef VERSION_EU + #define TIMER_SOMETHING_SPECIAL 150 + #define TIMER_PEACH_KISS 260 +#else + #define TIMER_SOMETHING_SPECIAL 130 + #define TIMER_PEACH_KISS 200 +#endif + // dialog 2 // "...and it's all thanks to you!" // "Thank you Mario!" @@ -2196,19 +2253,22 @@ static void end_peach_cutscene_dialog_2(struct MarioState *m) { #endif break; - case 130: + case TIMER_SOMETHING_SPECIAL: set_cutscene_message(160, 227, 4, 40); #ifndef VERSION_JP play_sound(SOUND_PEACH_SOMETHING_SPECIAL, sEndPeachObj->header.gfx.cameraToObject); #endif break; - case 200: + case TIMER_PEACH_KISS: advance_cutscene_step(m); break; } } +#undef TIMER_SOMETHING_SPECIAL +#undef TIMER_PEACH_KISS + static void end_peach_cutscene_kiss_from_peach(struct MarioState *m) { sEndPeachAnimation = 10; @@ -2439,6 +2499,16 @@ static s32 act_end_peach_cutscene(struct MarioState *m) { return FALSE; } +#ifdef VERSION_EU + #define TIMER_CREDITS_SHOW 51 + #define TIMER_CREDITS_PROGRESS 80 + #define TIMER_CREDITS_WARP 160 +#else + #define TIMER_CREDITS_SHOW 61 + #define TIMER_CREDITS_PROGRESS 90 + #define TIMER_CREDITS_WARP 200 +#endif + static s32 act_credits_cutscene(struct MarioState *m) { s32 width; s32 height; @@ -2461,7 +2531,7 @@ static s32 act_credits_cutscene(struct MarioState *m) { } } - if (m->actionTimer >= 61) { + if (m->actionTimer >= TIMER_CREDITS_SHOW) { if (m->actionState < 40) { m->actionState += 2; } @@ -2479,15 +2549,15 @@ static s32 act_credits_cutscene(struct MarioState *m) { func_8027A220(&sEndCutsceneVp, 0, 0, 0, 0); } - if (m->actionTimer == 90) { + if (m->actionTimer == TIMER_CREDITS_PROGRESS) { reset_cutscene_msg_fade(); } - if (m->actionTimer >= 90) { + if (m->actionTimer >= TIMER_CREDITS_PROGRESS) { sDispCreditsEntry = gCurrCreditsEntry; } - if (m->actionTimer++ == 200) { + if (m->actionTimer++ == TIMER_CREDITS_WARP) { level_trigger_warp(m, 24); } diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 210630e..48f4b23 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -738,12 +738,12 @@ void func_80265C28(struct MarioState *m, s16 startYaw) { val00 = 0; } - val0C->unkC[2] = approach_s32(val0C->unkC[2], val02, 0x400, 0x400); - val0C->unkC[0] = approach_s32(val0C->unkC[0], val00, 0x400, 0x400); + val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val02, 0x400, 0x400); + val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val00, 0x400, 0x400); ; } else { - val0C->unkC[2] = 0; - val0C->unkC[0] = 0; + val0C->torsoAngle[2] = 0; + val0C->torsoAngle[0] = 0; } } @@ -771,11 +771,11 @@ void func_80265DBC(struct MarioState *m, s16 startYaw) { val02 = 0; } - val0C->unkC[2] = approach_s32(val0C->unkC[2], val04, 0x200, 0x200); - val0C->unkC[0] = approach_s32(val0C->unkC[0], val02, 0x200, 0x200); - val0C->unk12[2] = -val0C->unkC[2]; + val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val04, 0x200, 0x200); + val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val02, 0x200, 0x200); + val0C->headAngle[2] = -val0C->torsoAngle[2]; - marioObj->header.gfx.angle[2] = val0C->unkC[2]; + marioObj->header.gfx.angle[2] = val0C->torsoAngle[2]; marioObj->header.gfx.pos[1] += 45.0f; } @@ -1351,8 +1351,8 @@ s32 act_burning_ground(struct MarioState *m) { void func_80267814(struct MarioState *m) { s16 intendedDYaw = m->intendedYaw - m->faceAngle[1]; - m->marioBodyState->unkC[0] = (s32)(5461.3335f * m->intendedMag / 32.0f * coss(intendedDYaw)); - m->marioBodyState->unkC[2] = (s32)(-(5461.3335f * m->intendedMag / 32.0f * sins(intendedDYaw))); + m->marioBodyState->torsoAngle[0] = (s32)(5461.3335f * m->intendedMag / 32.0f * coss(intendedDYaw)); + m->marioBodyState->torsoAngle[2] = (s32)(-(5461.3335f * m->intendedMag / 32.0f * sins(intendedDYaw))); } void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation) { diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index 749ae59..a2d4345 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -55,7 +55,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) { } if (m->actionArg == 2) { - m->marioBodyState->unk0B = 4; + m->marioBodyState->punchState = (0 << 6) | 4; } break; @@ -91,7 +91,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) { } if (m->actionArg == 5) { - m->marioBodyState->unk0B = 68; + m->marioBodyState->punchState = (1 << 6) | 4; } break; @@ -114,7 +114,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) { play_mario_action_sound(m, SOUND_MARIO_PUNCH_HOO, 1); animFrame = set_mario_animation(m, MARIO_ANIM_GROUND_KICK); if (animFrame == 0) { - m->marioBodyState->unk0B = 134; + m->marioBodyState->punchState = (2 << 6) | 6; } if (animFrame >= 0 && animFrame < 8) { diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 6c39c7b..4a550dc 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1059,7 +1059,7 @@ s32 act_first_person(struct MarioState *m) { s16 sp1A; s16 sp18; - sp1C = 0U < (m->input & (INPUT_UNKNOWN_10 | 0xC)); + sp1C = 0 != (m->input & (INPUT_UNKNOWN_10 | 0xC)); if (m->actionState == 0) { func_80248C28(2); set_camera_mode(m->area->camera, CAMERA_MODE_C_UP, 0x10); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index b18dd24..18a2a15 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -193,7 +193,7 @@ static u32 perform_water_step(struct MarioState *m) { return stepResult; } -static void func_80270504(struct MarioState *m) { +static BAD_RETURN(u32) func_80270504(struct MarioState *m) { struct Object *marioObj = m->marioObj; if (marioObj->header.gfx.angle[0] > 0) { @@ -302,7 +302,7 @@ static void update_swimming_pitch(struct MarioState *m) { } static void common_idle_step(struct MarioState *m, s32 animation, s32 arg) { - s16 *val = &m->marioBodyState->unk12[0]; + s16 *val = &m->marioBodyState->headAngle[0]; update_swimming_yaw(m); update_swimming_pitch(m); @@ -472,7 +472,7 @@ static void common_swimming_step(struct MarioState *m, s16 swimStrength) { } func_80270504(m); - m->marioBodyState->unk12[0] = approach_s32(m->marioBodyState->unk12[0], 0, 0x200, 0x200); + m->marioBodyState->headAngle[0] = approach_s32(m->marioBodyState->headAngle[0], 0, 0x200, 0x200); func_802710CC(m); set_swimming_at_surface_particles(m, PARTICLE_10); @@ -482,9 +482,7 @@ static void func_802713A8(struct MarioState *m) { s16 animFrame = m->marioObj->header.gfx.unk38.animFrame; // (this need to be on one line to match on PAL) - if (animFrame == 0 || animFrame == 12) { - play_sound(SOUND_ACTION_UNKNOWN434, m->marioObj->header.gfx.cameraToObject); - } + if (animFrame == 0 || animFrame == 12) play_sound(SOUND_ACTION_UNKNOWN434, m->marioObj->header.gfx.cameraToObject); } static s32 check_water_jump(struct MarioState *m) { @@ -793,7 +791,7 @@ static s32 act_water_throw(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_WATER_THROW_OBJ); play_sound_if_no_flag(m, SOUND_ACTION_SWIM, MARIO_ACTION_SOUND_PLAYED); - m->marioBodyState->unk12[0] = approach_s32(m->marioBodyState->unk12[0], 0, 0x200, 0x200); + m->marioBodyState->headAngle[0] = approach_s32(m->marioBodyState->headAngle[0], 0, 0x200, 0x200); if (m->actionTimer++ == 5) { mario_throw_held_object(m); @@ -817,7 +815,7 @@ static s32 act_water_punch(struct MarioState *m) { perform_water_step(m); func_80270504(m); - m->marioBodyState->unk12[0] = approach_s32(m->marioBodyState->unk12[0], 0, 0x200, 0x200); + m->marioBodyState->headAngle[0] = approach_s32(m->marioBodyState->headAngle[0], 0, 0x200, 0x200); play_sound_if_no_flag(m, SOUND_ACTION_SWIM, MARIO_ACTION_SOUND_PLAYED); @@ -857,7 +855,7 @@ static void common_water_knockback_step(struct MarioState *m, s32 animation, u32 perform_water_step(m); set_mario_animation(m, animation); - m->marioBodyState->unk12[0] = 0; + m->marioBodyState->headAngle[0] = 0; if (is_anim_at_end(m)) { if (arg3 > 0) { @@ -895,7 +893,7 @@ static s32 act_water_shocked(struct MarioState *m) { stationary_slow_down(m); perform_water_step(m); - m->marioBodyState->unk12[0] = 0; + m->marioBodyState->headAngle[0] = 0; return FALSE; } @@ -1513,8 +1511,8 @@ s32 mario_execute_submerged_action(struct MarioState *m) { m->quicksandDepth = 0.0f; - m->marioBodyState->unk12[1] = 0; - m->marioBodyState->unk12[2] = 0; + m->marioBodyState->headAngle[1] = 0; + m->marioBodyState->headAngle[2] = 0; /* clang-format off */ switch (m->action) { diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 12ff921..2557e9e 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -52,11 +52,26 @@ enum UnlockDoorStarStates { UNLOCK_DOOR_STAR_DONE }; -static s8 D_8032CDF0[7] = { 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x01 }; -static s8 D_8032CDF8[] = { 0x0a, 0x0c, 0x10, 0x18, 0x0a, 0x0a, 0x0a, 0x0e, 0x14, 0x1e, - 0x0a, 0x0a, 0x0a, 0x10, 0x14, 0x1a, 0x1a, 0x14, 0x00, 0x00 }; -struct GraphNodeObject D_80339FE0; +/** + * The eye texture on succesive frames of Mario's blink animation. + * He intentionally blinks twice each time. + */ +static s8 gMarioBlinkAnimation[7] = { 1, 2, 1, 0, 1, 2, 1 }; + +/** + * The scale values per frame for Mario's foot/hand for his attack animation + * There are 3 scale animations in groups of 6 frames. + * The first animation starts at frame index 3 and goes down, the others start at frame index 5. + * The values get divided by 10 before assigning, so e.g. 12 gives a scale factor 1.2. + * All combined, this means e.g. the first animation scales Mario's fist by {2.4, 1.6, 1.2, 1.0} on + * succesive frames. + */ +static s8 gMarioAttackScaleAnimation[3 * 6] = { + 10, 12, 16, 24, 10, 10, 10, 14, 20, 30, 10, 10, 10, 16, 20, 26, 26, 20, +}; + struct MarioBodyState gBodyStates[2]; // 2nd is never accessed in practice, most likely Luigi related +struct GraphNodeObject gMirrorMario; // copy of Mario's geo node for drawing mirror Mario // This whole file is weirdly organized. It has to be the same file due // to rodata boundries and function aligns, which means the programmer @@ -64,23 +79,25 @@ struct MarioBodyState gBodyStates[2]; // 2nd is never accessed in practice, most // (message NPC related things, the mario head geo, and mario geo // functions) -// mario head geo -Gfx *Geo18_802764B0(s32 callContext, struct GraphNode *node, Mat4 *c) { - Gfx *sp24 = NULL; - s16 sp22 = 0; - struct GraphNodeGenerated *sp1C = (struct GraphNodeGenerated *) node; - UNUSED Mat4 *sp18 = c; +/** + * Geo node script that draws Mario's head on the title screen. + */ +Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *c) { + Gfx *gfx = NULL; + s16 sfx = 0; + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + UNUSED Mat4 *transform = c; if (callContext == GEO_CONTEXT_RENDER) { if (gPlayer1Controller->controllerData != NULL && gWarpTransition.isActive == 0) { gd_copy_p1_contpad(gPlayer1Controller->controllerData); } - sp24 = (Gfx *) PHYSICAL_TO_VIRTUAL(gdm_gettestdl(sp1C->parameter)); + gfx = (Gfx *) PHYSICAL_TO_VIRTUAL(gdm_gettestdl(asGenerated->parameter)); D_8032C6A0 = gd_vblank; - sp22 = gd_sfx_to_play(); - play_menu_sounds(sp22); + sfx = gd_sfx_to_play(); + play_menu_sounds(sfx); } - return sp24; + return gfx; } static void bhvToadMessage_faded(void) { @@ -108,7 +125,8 @@ static void bhvToadMessage_opaque(void) { } static void bhvToadMessage_talking(void) { - if (obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG, 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) { @@ -141,7 +159,7 @@ static void bhvToadMessage_fading(void) { } void bhvToadMessage_loop(void) { - if (gCurrentObject->header.gfx.node.flags & 1) { + if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { gCurrentObject->oInteractionSubtype = 0; switch (gCurrentObject->oToadMessageState) { case TOAD_MESSAGE_FADED: @@ -279,174 +297,219 @@ void bhvUnlockDoorStar_loop(void) { } } -static Gfx *func_802769E0(struct GraphNodeGenerated *node, s16 b) { - Gfx *sp2C; - Gfx *sp28 = NULL; +/** + * Generate a display list that sets the correct blend mode and color for + * mirror Mario. + */ +static Gfx *make_gfx_mario_alpha(struct GraphNodeGenerated *node, s16 alpha) { + Gfx *gfx; + Gfx *gfxHead = NULL; - if (b == 255) { - node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | 0x100; - sp28 = alloc_display_list(2 * sizeof(*sp28)); - sp2C = sp28; + if (alpha == 255) { + node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | (LAYER_OPAQUE << 8); + gfxHead = alloc_display_list(2 * sizeof(*gfxHead)); + gfx = gfxHead; } else { - node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | 0x500; - sp28 = alloc_display_list(3 * sizeof(*sp28)); - sp2C = sp28; - gDPSetAlphaCompare(sp2C++, G_AC_DITHER); + node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | (LAYER_TRANSPARENT << 8); + gfxHead = alloc_display_list(3 * sizeof(*gfxHead)); + gfx = gfxHead; + gDPSetAlphaCompare(gfx++, G_AC_DITHER); } - gDPSetEnvColor(sp2C++, 255, 255, 255, b); - gSPEndDisplayList(sp2C); - return sp28; + gDPSetEnvColor(gfx++, 255, 255, 255, alpha); + gSPEndDisplayList(gfx); + return gfxHead; } -Gfx *Geo18_802770A4(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { +/** + * Sets the correct blend mode and color for mirror Mario. + */ +Gfx *geo_mirror_mario_set_alpha(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { UNUSED u8 unused1[4]; - Gfx *sp28 = NULL; - struct GraphNodeGenerated *sp24 = (struct GraphNodeGenerated *) node; - struct MarioBodyState *sp20 = &gBodyStates[sp24->parameter]; - s16 sp1E; + Gfx *gfx = NULL; + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + struct MarioBodyState *bodyState = &gBodyStates[asGenerated->parameter]; + s16 alpha; UNUSED u8 unused2[4]; if (callContext == GEO_CONTEXT_RENDER) { - sp1E = (sp20->modelState & 0x100) ? (sp20->modelState & 0xFF) : 255; - sp28 = func_802769E0(sp24, sp1E); + alpha = (bodyState->modelState & 0x100) ? (bodyState->modelState & 0xFF) : 255; + gfx = make_gfx_mario_alpha(asGenerated, alpha); } - return sp28; + return gfx; } +/** + * Determines if Mario is standing or running for the level of detail of his model. + * If Mario is standing still, he is always high poly. If he is running, + * his level of detail depends on the distance to the camera. + */ Gfx *geo_switch_mario_stand_run(s32 callContext, struct GraphNode *node, UNUSED Mat4 *mtx) { struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - struct MarioBodyState *sp0 = &gBodyStates[switchCase->numCases]; + struct MarioBodyState *bodyState = &gBodyStates[switchCase->numCases]; if (callContext == GEO_CONTEXT_RENDER) { // assign result. 0 if moving, 1 if stationary. - switchCase->selectedCase = ((sp0->action & ACT_FLAG_STATIONARY) == FALSE); + switchCase->selectedCase = ((bodyState->action & ACT_FLAG_STATIONARY) == FALSE); } return NULL; } +/** + * Geo node script that makes Mario blink + */ Gfx *geo_switch_mario_eyes(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - struct MarioBodyState *sp8 = &gBodyStates[switchCase->numCases]; - s16 sp6; + struct MarioBodyState *bodyState = &gBodyStates[switchCase->numCases]; + s16 blinkFrame; if (callContext == GEO_CONTEXT_RENDER) { - if (sp8->eyeState == 0) { - sp6 = ((switchCase->numCases * 32 + gAreaUpdateCounter) >> 1) & 0x1F; - if (sp6 < 7) { - switchCase->selectedCase = D_8032CDF0[sp6]; + if (bodyState->eyeState == 0) { + blinkFrame = ((switchCase->numCases * 32 + gAreaUpdateCounter) >> 1) & 0x1F; + if (blinkFrame < 7) { + switchCase->selectedCase = gMarioBlinkAnimation[blinkFrame]; } else { switchCase->selectedCase = 0; } } else { - switchCase->selectedCase = sp8->eyeState - 1; + switchCase->selectedCase = bodyState->eyeState - 1; } } return NULL; } -Gfx *Geo18_80277294(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - struct GraphNodeGenerated *sp24 = (struct GraphNodeGenerated *) node; - struct MarioBodyState *sp20 = &gBodyStates[sp24->parameter]; - s32 action = sp20->action; +/** + * Makes Mario's upper body tilt depending on the rotation stored in his bodyState + */ +Gfx *geo_mario_tilt_torso(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + struct MarioBodyState *bodyState = &gBodyStates[asGenerated->parameter]; + s32 action = bodyState->action; if (callContext == GEO_CONTEXT_RENDER) { - struct GraphNodeRotation *sp18 = (struct GraphNodeRotation *) node->next; + struct GraphNodeRotation *rotNode = (struct GraphNodeRotation *) node->next; - if (action != 0x00840452 && action != 0x00840454 && action != 0x04000440 - && action != 0x20810446) { - vec3s_copy(sp20->unkC, gVec3sZero); + if (action != ACT_BUTT_SLIDE && action != ACT_HOLD_BUTT_SLIDE && action != ACT_WALKING + && action != ACT_RIDING_SHELL_GROUND) { + vec3s_copy(bodyState->torsoAngle, gVec3sZero); } - sp18->rotation[0] = sp20->unkC[1]; - sp18->rotation[1] = sp20->unkC[2]; - sp18->rotation[2] = sp20->unkC[0]; + rotNode->rotation[0] = bodyState->torsoAngle[1]; + rotNode->rotation[1] = bodyState->torsoAngle[2]; + rotNode->rotation[2] = bodyState->torsoAngle[0]; } return NULL; } -Gfx *Geo18_802773A4(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - struct GraphNodeGenerated *sp2C = (struct GraphNodeGenerated *) node; - struct MarioBodyState *sp28 = &gBodyStates[sp2C->parameter]; - s32 action = sp28->action; +/** + * Makes Mario's head rotate with the camera angle when in C-up mode + */ +Gfx *geo_mario_head_rotation(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + struct MarioBodyState *bodyState = &gBodyStates[asGenerated->parameter]; + s32 action = bodyState->action; if (callContext == GEO_CONTEXT_RENDER) { - struct GraphNodeRotation *sp20 = (struct GraphNodeRotation *) node->next; + struct GraphNodeRotation *rotNode = (struct GraphNodeRotation *) node->next; struct Camera *camera = gCurGraphNodeCamera->config.camera; 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]; - sp20->rotation[2] = sp28->unk12[0]; + rotNode->rotation[0] = gPlayerCameraState->headRotation[1]; + rotNode->rotation[2] = gPlayerCameraState->headRotation[0]; + } else if (action & ACT_FLAG_WATER_OR_TEXT) { + rotNode->rotation[0] = bodyState->headAngle[1]; + rotNode->rotation[1] = bodyState->headAngle[2]; + rotNode->rotation[2] = bodyState->headAngle[0]; } else { - vec3s_set(sp28->unk12, 0, 0, 0); - vec3s_set(sp20->rotation, 0, 0, 0); + vec3s_set(bodyState->headAngle, 0, 0, 0); + vec3s_set(rotNode->rotation, 0, 0, 0); } } return NULL; } +/** + * Switch between hand models. + * Possible options are described in the MarioHandGSCId enum. + */ Gfx *geo_switch_mario_hand(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - struct MarioBodyState *sp0 = &gBodyStates[0]; + struct MarioBodyState *bodyState = &gBodyStates[0]; if (callContext == GEO_CONTEXT_RENDER) { - if (sp0->handState == 0) { - switchCase->selectedCase = ((sp0->action & ACT_FLAG_SWIMMING_OR_FLYING) != 0); + if (bodyState->handState == MARIO_HAND_FISTS) { + // switch between fists (0) and open (1) + switchCase->selectedCase = ((bodyState->action & ACT_FLAG_SWIMMING_OR_FLYING) != 0); } else { if (switchCase->numCases == 0) { - switchCase->selectedCase = (sp0->handState < 5) ? sp0->handState : 1; + switchCase->selectedCase = + (bodyState->handState < 5) ? bodyState->handState : MARIO_HAND_OPEN; } else { - switchCase->selectedCase = (sp0->handState < 2) ? sp0->handState : 0; + switchCase->selectedCase = + (bodyState->handState < 2) ? bodyState->handState : MARIO_HAND_FISTS; } } } return NULL; } -Gfx *Geo18_802775CC(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - static s16 D_8032CE0C = 0; - struct GraphNodeGenerated *spC = (struct GraphNodeGenerated *) node; - struct GraphNodeScale *sp8 = (struct GraphNodeScale *) node->next; - struct MarioBodyState *sp4 = &gBodyStates[0]; +/** + * Increase Mario's hand / foot size when he punches / kicks. + * Since animation geo nodes only support rotation, this scaling animation + * was scripted separately. The node with this script should be placed before + * a scaling node containing the hand / foot geo layout. + * ! Since the animation gets updated in GEO_CONTEXT_RENDER, drawing Mario multiple times + * (such as in the mirror room) results in a faster and desynced punch / kick animation. + */ +Gfx *geo_mario_hand_foot_scaler(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { + static s16 sMarioAttackAnimCounter = 0; + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + struct GraphNodeScale *scaleNode = (struct GraphNodeScale *) node->next; + struct MarioBodyState *bodyState = &gBodyStates[0]; if (callContext == GEO_CONTEXT_RENDER) { - sp8->scale = 1.0f; - if (spC->parameter == sp4->unk0B >> 6) { - if (D_8032CE0C != gAreaUpdateCounter && (sp4->unk0B & 0x3F) > 0) { - sp4->unk0B -= 1; - D_8032CE0C = gAreaUpdateCounter; + scaleNode->scale = 1.0f; + if (asGenerated->parameter == bodyState->punchState >> 6) { + if (sMarioAttackAnimCounter != gAreaUpdateCounter && (bodyState->punchState & 0x3F) > 0) { + bodyState->punchState -= 1; + sMarioAttackAnimCounter = gAreaUpdateCounter; } - sp8->scale = D_8032CDF8[spC->parameter * 6 + (sp4->unk0B & 0x3F)] / 10.0f; + scaleNode->scale = + gMarioAttackScaleAnimation[asGenerated->parameter * 6 + (bodyState->punchState & 0x3F)] + / 10.0f; } } return NULL; } +/** + * Switch between normal cap, wing cap, vanish cap and metal cap. + */ Gfx *geo_switch_mario_cap_effect(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - struct MarioBodyState *sp0 = &gBodyStates[switchCase->numCases]; + struct MarioBodyState *bodyState = &gBodyStates[switchCase->numCases]; if (callContext == GEO_CONTEXT_RENDER) { - switchCase->selectedCase = sp0->modelState >> 8; + switchCase->selectedCase = bodyState->modelState >> 8; } return NULL; } +/** + * Determine whether Mario's head is drawn with or without a cap on. + * Also sets the visibility of the wing cap wings on or off. + */ Gfx *geo_switch_mario_cap_on_off(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { struct GraphNode *next = node->next; struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - struct MarioBodyState *sp4 = &gBodyStates[switchCase->numCases]; + struct MarioBodyState *bodyState = &gBodyStates[switchCase->numCases]; if (callContext == GEO_CONTEXT_RENDER) { - switchCase->selectedCase = sp4->capState & 1; + switchCase->selectedCase = bodyState->capState & 1; while (next != node) { - if (next->type == 21) { - if (sp4->capState & 2) { - next->flags |= 1; + if (next->type == GRAPH_NODE_TYPE_TRANSLATION_ROTATION) { + if (bodyState->capState & 2) { + next->flags |= GRAPH_RENDER_ACTIVE; } else { - next->flags &= ~1; + next->flags &= ~GRAPH_RENDER_ACTIVE; } } next = next->next; @@ -455,117 +518,139 @@ Gfx *geo_switch_mario_cap_on_off(s32 callContext, struct GraphNode *node, UNUSED return NULL; } -Gfx *Geo18_80277824(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - s16 spE; - struct GraphNodeGenerated *sp8 = (struct GraphNodeGenerated *) node; +/** + * Geo node script that makes the wings on Mario's wing cap flap. + * Should be placed before a rotation node. + */ +Gfx *geo_mario_rotate_wing_cap_wings(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { + s16 rotX; + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; if (callContext == GEO_CONTEXT_RENDER) { - struct GraphNodeRotation *sp4 = (struct GraphNodeRotation *) node->next; + struct GraphNodeRotation *rotNode = (struct GraphNodeRotation *) node->next; - if (gBodyStates[sp8->parameter >> 1].unk07 == 0) { - spE = (coss((gAreaUpdateCounter & 0xF) << 12) + 1.0f) * 4096.0f; + if (gBodyStates[asGenerated->parameter >> 1].wingFlutter == FALSE) { + rotX = (coss((gAreaUpdateCounter & 0xF) << 12) + 1.0f) * 4096.0f; } else { - spE = (coss((gAreaUpdateCounter & 7) << 13) + 1.0f) * 6144.0f; + rotX = (coss((gAreaUpdateCounter & 7) << 13) + 1.0f) * 6144.0f; } - if (!(sp8->parameter & 1)) { - sp4->rotation[0] = -spE; + if (!(asGenerated->parameter & 1)) { + rotNode->rotation[0] = -rotX; } else { - sp4->rotation[0] = spE; + rotNode->rotation[0] = rotX; } } return NULL; } -Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 *c) { - struct GraphNodeHeldObject *sp2C = (struct GraphNodeHeldObject *) b; - Mat4 *sp28 = c; - struct MarioState *sp24 = &gMarioStates[sp2C->playerIndex]; +/** + * Geo node that updates the held object node and the HOLP. + */ +Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 *mtx) { + struct GraphNodeHeldObject *asHeldObj = (struct GraphNodeHeldObject *) b; + Mat4 *curTransform = mtx; + struct MarioState *marioState = &gMarioStates[asHeldObj->playerIndex]; if (callContext == GEO_CONTEXT_RENDER) { - sp2C->objNode = NULL; - if (sp24->heldObj != NULL) { - sp2C->objNode = sp24->heldObj; - switch (sp24->marioBodyState->grabPos) { + asHeldObj->objNode = NULL; + if (marioState->heldObj != NULL) { + asHeldObj->objNode = marioState->heldObj; + switch (marioState->marioBodyState->grabPos) { case GRAB_POS_LIGHT_OBJ: - if (sp24->action & ACT_FLAG_THROWING) { - vec3s_set(sp2C->translation, 50, 0, 0); + if (marioState->action & ACT_FLAG_THROWING) { + vec3s_set(asHeldObj->translation, 50, 0, 0); } else { - vec3s_set(sp2C->translation, 50, 0, 110); + vec3s_set(asHeldObj->translation, 50, 0, 110); } break; case GRAB_POS_HEAVY_OBJ: - vec3s_set(sp2C->translation, 145, -173, 180); + vec3s_set(asHeldObj->translation, 145, -173, 180); break; case GRAB_POS_BOWSER: - vec3s_set(sp2C->translation, 80, -270, 1260); + vec3s_set(asHeldObj->translation, 80, -270, 1260); break; } } } else if (callContext == GEO_CONTEXT_HELD_OBJ) { - get_pos_from_transform_mtx(sp24->marioBodyState->unk18, *sp28, gCurGraphNodeCamera->matrixPtr); + // ! The HOLP is set here, which is why it only updates when the held object is drawn. + // This is why it won't update during a pause buffered hitstun or when the camera is very far + // away. + get_pos_from_transform_mtx(marioState->marioBodyState->heldObjLastPosition, *curTransform, + gCurGraphNodeCamera->matrixPtr); } return NULL; } +// X position of the mirror +#define MIRROR_X 4331.53 + +/** + * Geo node that creates a clone of Mario's geo node and updates it to becomes + * a mirror image of the player. + */ Gfx *geo_render_mirror_mario(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - f32 sp34; - struct Object *sp30 = gMarioStates->marioObj; + f32 mirroredX; + struct Object *mario = gMarioStates->marioObj; switch (callContext) { case GEO_CONTEXT_CREATE: - init_graph_node_object(NULL, &D_80339FE0, NULL, gVec3fZero, gVec3sZero, gVec3fOne); + init_graph_node_object(NULL, &gMirrorMario, NULL, gVec3fZero, gVec3sZero, gVec3fOne); break; case GEO_CONTEXT_AREA_LOAD: - geo_add_child(node, &D_80339FE0.node); + geo_add_child(node, &gMirrorMario.node); break; case GEO_CONTEXT_AREA_UNLOAD: - geo_remove_child(&D_80339FE0.node); + geo_remove_child(&gMirrorMario.node); break; case GEO_CONTEXT_RENDER: - if (sp30->header.gfx.pos[0] > 1700.0f) { + if (mario->header.gfx.pos[0] > 1700.0f) { // TODO: Is this a geo layout copy or a graph node copy? - D_80339FE0.sharedChild = sp30->header.gfx.sharedChild; - D_80339FE0.unk18 = sp30->header.gfx.unk18; - vec3s_copy(D_80339FE0.angle, sp30->header.gfx.angle); - vec3f_copy(D_80339FE0.pos, sp30->header.gfx.pos); - vec3f_copy(D_80339FE0.scale, sp30->header.gfx.scale); + gMirrorMario.sharedChild = mario->header.gfx.sharedChild; + gMirrorMario.unk18 = mario->header.gfx.unk18; + vec3s_copy(gMirrorMario.angle, mario->header.gfx.angle); + vec3f_copy(gMirrorMario.pos, mario->header.gfx.pos); + vec3f_copy(gMirrorMario.scale, mario->header.gfx.scale); // FIXME: why does this set unk38, an inline struct, to a ptr to another one? wrong // GraphNode types again? - D_80339FE0.unk38 = *(struct GraphNodeObject_sub *) &sp30->header.gfx.unk38.animID; - sp34 = 4331.53 - D_80339FE0.pos[0]; - D_80339FE0.pos[0] = sp34 + 4331.53; - D_80339FE0.angle[1] = -D_80339FE0.angle[1]; - D_80339FE0.scale[0] *= -1.0f; + gMirrorMario.unk38 = *(struct GraphNodeObject_sub *) &mario->header.gfx.unk38.animID; + mirroredX = MIRROR_X - gMirrorMario.pos[0]; + gMirrorMario.pos[0] = mirroredX + MIRROR_X; + gMirrorMario.angle[1] = -gMirrorMario.angle[1]; + gMirrorMario.scale[0] *= -1.0f; // FIXME: Why doesn't this match? - // D_80339FE0.node.flags |= 1; - ((s16 *) &D_80339FE0)[1] |= 1; + // gMirrorMario.node.flags |= 1; + ((s16 *) &gMirrorMario)[1] |= 1; } else { // FIXME: Why doesn't this match? - // D_80339FE0.node.flags &= ~1; - ((s16 *) &D_80339FE0)[1] &= ~1; + // gMirrorMario.node.flags &= ~1; + ((s16 *) &gMirrorMario)[1] &= ~1; } break; } return NULL; } +/** + * Since Mirror Mario has an x scale of -1, the mesh becomes inside out. + * This node corrects that by changing the culling mode accordingly. + */ Gfx *geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c) { - struct GraphNodeGenerated *sp34 = (struct GraphNodeGenerated *) node; - Gfx *sp30 = NULL; + struct GraphNodeGenerated *asGenerated = (struct GraphNodeGenerated *) node; + Gfx *gfx = NULL; - if (callContext == GEO_CONTEXT_RENDER && gCurGraphNodeObject == &D_80339FE0) { - sp30 = alloc_display_list(3 * sizeof(*sp30)); + if (callContext == GEO_CONTEXT_RENDER && gCurGraphNodeObject == &gMirrorMario) { + gfx = alloc_display_list(3 * sizeof(*gfx)); - if (sp34->parameter == 0) { - gSPClearGeometryMode(&sp30[0], G_CULL_BACK); - gSPSetGeometryMode(&sp30[1], G_CULL_FRONT); - gSPEndDisplayList(&sp30[2]); + if (asGenerated->parameter == 0) { + gSPClearGeometryMode(&gfx[0], G_CULL_BACK); + gSPSetGeometryMode(&gfx[1], G_CULL_FRONT); + gSPEndDisplayList(&gfx[2]); } else { - gSPClearGeometryMode(&sp30[0], G_CULL_FRONT); - gSPSetGeometryMode(&sp30[1], G_CULL_BACK); - gSPEndDisplayList(&sp30[2]); + gSPClearGeometryMode(&gfx[0], G_CULL_FRONT); + gSPSetGeometryMode(&gfx[1], G_CULL_BACK); + gSPEndDisplayList(&gfx[2]); } - sp34->fnNode.node.flags = (sp34->fnNode.node.flags & 0xFF) | 0x100; + asGenerated->fnNode.node.flags = (asGenerated->fnNode.node.flags & 0xFF) | (LAYER_OPAQUE << 8); } - return sp30; + return gfx; } diff --git a/src/game/mario_misc.h b/src/game/mario_misc.h index f8858bc..2465ac9 100644 --- a/src/game/mario_misc.h +++ b/src/game/mario_misc.h @@ -3,26 +3,25 @@ #include "types.h" -extern struct GraphNodeObject D_80339FE0; +extern struct GraphNodeObject gMirrorMario; extern struct MarioBodyState gBodyStates[2]; -extern Gfx *Geo18_802764B0(s32 a, struct GraphNode *b, Mat4 *c); +extern Gfx *geo_draw_mario_head_goddard(s32 a, struct GraphNode *b, Mat4 *c); extern void bhvToadMessage_loop(void); extern void bhvToadMessage_init(void); extern void bhvUnlockDoorStar_init(void); extern void bhvUnlockDoorStar_loop(void); -extern Gfx *Geo18_802770A4(s32 a, struct GraphNode *b, UNUSED Mat4 *c); +extern Gfx *geo_mirror_mario_set_alpha(s32 a, struct GraphNode *b, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_stand_run(s32 run, struct GraphNode *node, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_eyes(s32 run, struct GraphNode *node, UNUSED Mat4 *c); -extern Gfx *Geo18_80277294(s32 a, struct GraphNode *b, UNUSED Mat4 *c); -extern Gfx *Geo18_802773A4(s32 a, struct GraphNode *b, UNUSED Mat4 *c); +extern Gfx *geo_mario_tilt_torso(s32 a, struct GraphNode *b, UNUSED Mat4 *c); +extern Gfx *geo_mario_head_rotation(s32 a, struct GraphNode *b, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_hand(s32 run, struct GraphNode *node, UNUSED Mat4 *c); -extern Gfx *Geo18_802775CC(s32 a, struct GraphNode *b, UNUSED Mat4 *c); +extern Gfx *geo_mario_hand_foot_scaler(s32 a, struct GraphNode *b, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_cap_effect(s32 run, struct GraphNode *node, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_cap_on_off(s32 run, struct GraphNode *node, UNUSED Mat4 *c); -extern Gfx *Geo18_80277824(s32 a, struct GraphNode *b, UNUSED Mat4 *c); +extern Gfx *geo_mario_rotate_wing_cap_wings(s32 a, struct GraphNode *b, UNUSED Mat4 *c); extern Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 *c); -extern Gfx *Geo1C_8027795C(s32 a, struct GraphNode *b, Mat4 *c); extern Gfx *geo_render_mirror_mario(s32 a, struct GraphNode *b, UNUSED Mat4 *c); extern Gfx *geo_mirror_mario_backface_culling(s32 a, struct GraphNode *b, UNUSED Mat4 *c); diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 949b3de..e3f5e58 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -71,8 +71,8 @@ void transfer_bully_speed(struct BullyCollisionData *obj1, struct BullyCollision //! Bully battery } -void init_bully_collision_data(struct BullyCollisionData *data, f32 posX, f32 posZ, f32 forwardVel, - s16 yaw, f32 conversionRatio, f32 radius) { +BAD_RETURN(s32) init_bully_collision_data(struct BullyCollisionData *data, f32 posX, f32 posZ, + f32 forwardVel, s16 yaw, f32 conversionRatio, f32 radius) { if (forwardVel < 0.0f) { forwardVel *= -1.0f; yaw += 0x8000; @@ -564,7 +564,7 @@ void apply_gravity(struct MarioState *m) { m->vel[1] = -16.0f; } } else if ((m->flags & MARIO_WING_CAP) && m->vel[1] < 0.0f && (m->input & INPUT_A_DOWN)) { - m->marioBodyState->unk07 = 1; + m->marioBodyState->wingFlutter = TRUE; m->vel[1] -= 2.0f; if (m->vel[1] < -37.5f) { diff --git a/src/game/memory.c b/src/game/memory.c index b287d09..00ad881 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -42,13 +42,13 @@ struct MemoryBlock { u32 size; }; -static uintptr_t sSegmentTable[32]; +extern uintptr_t sSegmentTable[32]; +extern u32 sPoolFreeSpace; +extern u8 *sPoolStart; +extern u8 *sPoolEnd; +extern struct MainPoolBlock *sPoolListHeadL; +extern struct MainPoolBlock *sPoolListHeadR; -static u32 sPoolFreeSpace; -static u8 *sPoolStart; -static u8 *sPoolEnd; -static struct MainPoolBlock *sPoolListHeadL; -static struct MainPoolBlock *sPoolListHeadR; /** * Memory pool for small graphical effects that aren't connected to Objects. @@ -56,6 +56,14 @@ static struct MainPoolBlock *sPoolListHeadR; */ struct MemoryPool *gEffectsMemoryPool; +uintptr_t sSegmentTable[32]; +u32 sPoolFreeSpace; +u8 *sPoolStart; +u8 *sPoolEnd; +struct MainPoolBlock *sPoolListHeadL; +struct MainPoolBlock *sPoolListHeadR; + + static struct MainPoolState *gMainPoolState = NULL; uintptr_t set_segment_base_addr(s32 segment, void *addr) { @@ -151,14 +159,14 @@ u32 main_pool_free(void *addr) { } sPoolListHeadL = block; sPoolListHeadL->next = NULL; - sPoolFreeSpace += (u8 *) oldListHead - (u8 *) sPoolListHeadL; + sPoolFreeSpace += (uintptr_t) oldListHead - (uintptr_t) sPoolListHeadL; } else { while (oldListHead->prev != NULL) { oldListHead = oldListHead->prev; } sPoolListHeadR = block->next; sPoolListHeadR->prev = NULL; - sPoolFreeSpace += (u8 *) sPoolListHeadR - (u8 *) oldListHead; + sPoolFreeSpace += (uintptr_t) sPoolListHeadR - (uintptr_t) oldListHead; } return sPoolFreeSpace; } @@ -537,9 +545,10 @@ s32 func_80278AD4(struct MarioAnimation *a, u32 index) { u32 size; if (index < sp20->count) { - addr = sp20->srcAddr + sp20->anim[index].offset; - size = sp20->anim[index].size; - + do { + addr = sp20->srcAddr + sp20->anim[index].offset; + size = sp20->anim[index].size; + } while (0); if (a->currentAnimAddr != addr) { dma_read((u8 *) a->targetAnim, addr, addr + size); a->currentAnimAddr = addr; diff --git a/src/game/moving_texture.c b/src/game/moving_texture.c index 1c6c380..29b56c9 100644 --- a/src/game/moving_texture.c +++ b/src/game/moving_texture.c @@ -12,7 +12,7 @@ #include "engine/surface_collision.h" #include "geo_misc.h" #include "rendering_graph_node.h" -#include "room.h" +#include "object_list_processor.h" /** * This file contains functions for generating display lists with moving textures @@ -448,19 +448,9 @@ Gfx *movtex_gen_from_quad(s16 y, struct MovtexQuad *quad) { if (textureId == TEXTURE_MIST) { // an ia16 texture if (0) { } - gDPSetTextureImage(gfx++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, gMovtexIdToTexture[textureId]); - gDPTileSync(gfx++); - gDPSetTile(gfx++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, - G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadSync(gfx++); - gDPLoadBlock(gfx++, G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)); + gLoadBlockTexture(gfx++, 32, 32, G_IM_FMT_IA, gMovtexIdToTexture[textureId]); } else { // any rgba16 texture - gDPSetTextureImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gMovtexIdToTexture[textureId]); - gDPTileSync(gfx++); - gDPSetTile(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, - G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadSync(gfx++); - gDPLoadBlock(gfx++, G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)); + gLoadBlockTexture(gfx++, 32, 32, G_IM_FMT_RGBA, gMovtexIdToTexture[textureId]); if (0) { } } @@ -830,12 +820,7 @@ Gfx *movtex_gen_list(s16 *movtexVerts, struct MovtexObject *movtexList, s8 attrL } gSPDisplayList(gfx++, movtexList->beginDl); - gDPSetTextureImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gMovtexIdToTexture[movtexList->textureId]); - gDPTileSync(gfx++); - gDPSetTile(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, - G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadSync(gfx++); - gDPLoadBlock(gfx++, G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)); + gLoadBlockTexture(gfx++, 32, 32, G_IM_FMT_RGBA, gMovtexIdToTexture[movtexList->textureId]); gSPVertex(gfx++, VIRTUAL_TO_PHYSICAL2(verts), movtexList->vtx_count, 0); gSPDisplayList(gfx++, movtexList->triDl); gSPDisplayList(gfx++, movtexList->endDl); diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index bbf5d0b..acc0669 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -23,7 +23,6 @@ #include "behavior_actions.h" #include "spawn_object.h" #include "spawn_sound.h" -#include "room.h" #include "envfx_bubbles.h" #include "ingame_menu.h" #include "interaction.h" @@ -148,7 +147,7 @@ s32 obj_find_wall(f32 objNewX, f32 objY, f32 objNewZ, f32 objVelX, f32 objVelZ) hitbox.x = objNewX; hitbox.y = objY; hitbox.z = objNewZ; - hitbox.offsetY = o->hitboxHeight / 2.0f; + hitbox.offsetY = o->hitboxHeight / 2; hitbox.radius = o->hitboxRadius; if (find_wall_collisions(&hitbox) != 0) { @@ -275,7 +274,7 @@ void calc_new_obj_vel_and_pos_y(struct Surface *objFloor, f32 objFloorY, f32 obj // Bounces an object if the ground is hit fast enough. if (o->oVelY < -17.5) { - o->oVelY = -(o->oVelY / 2.0f); + o->oVelY = -(o->oVelY / 2); } else { o->oVelY = 0; } @@ -413,7 +412,7 @@ void obj_splash(s32 waterY, s32 objY) { * Generic object move function. Handles walls, water, floors, and gravity. * Returns flags for certain interactions. */ -s32 object_step(void) { +s16 object_step(void) { f32 objX = o->oPosX; f32 objY = o->oPosY; f32 objZ = o->oPosZ; @@ -463,15 +462,9 @@ s32 object_step(void) { /** * Takes an object step but does not orient with the object's floor. * Used for boulders, falling pillars, and the rolling snowman body. - * - * TODO: Fix fake EU matching. */ -s32 object_step_without_floor_orient(void) { -#ifdef VERSION_EU - s32 collisionFlags = 0; -#else +s16 object_step_without_floor_orient(void) { s16 collisionFlags = 0; -#endif sOrientObjWithFloor = FALSE; collisionFlags = object_step(); sOrientObjWithFloor = TRUE; diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c index 9299047..5040c03 100644 --- a/src/game/obj_behaviors_2.c +++ b/src/game/obj_behaviors_2.c @@ -28,7 +28,6 @@ #include "spawn_sound.h" #include "geo_misc.h" #include "save_file.h" -#include "room.h" #include "level_table.h" extern struct Animation *wiggler_seg5_anims_0500C874[]; @@ -113,6 +112,12 @@ extern struct Animation *spiny_seg5_anims_05016EAC[]; #define o gCurrentObject +/** + * The treadmill that plays sounds and controls the others on random setting. + */ +struct Object *sMasterTreadmill; + + f32 sObjSavedPosX; f32 sObjSavedPosY; f32 sObjSavedPosZ; @@ -165,7 +170,9 @@ static s32 obj_is_near_to_and_facing_mario(f32 maxDist, s16 maxAngleDiff) { return FALSE; } -static void obj_perform_position_op(s32 op) { +//! Although having no return value, this function +//! must be u32 to match other functions on -O2. +static BAD_RETURN(u32) obj_perform_position_op(s32 op) { switch (op) { case POS_OP_SAVE_POSITION: sObjSavedPosX = o->oPosX; @@ -655,17 +662,27 @@ static s32 obj_resolve_collisions_and_turn(s16 targetYaw, s16 turnSpeed) { } } +// TODO Likely scrub C, needs true matching code. static void obj_die_if_health_non_positive(void) { +#ifdef VERSION_EU + s32 new_var; +#endif + if (o->oHealth <= 0) { if (o->oDeathSound == 0) { func_802A3034(SOUND_OBJ_DEFAULT_DEATH); } else if (o->oDeathSound > 0) { +#ifdef VERSION_EU + new_var = o->oDeathSound; + func_802A3034(new_var); +#else func_802A3034(o->oDeathSound); +#endif } else { func_802A3004(); } - if (o->oNumLootCoins < 0) { + if ((s32)o->oNumLootCoins < 0) { spawn_object(o, MODEL_BLUE_COIN, bhvMrIBlueCoin); } else { spawn_object_loot_yellow_coins(o, o->oNumLootCoins, 20.0f); diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index f74aecb..838360d 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -23,7 +23,6 @@ #include "obj_behaviors.h" #include "interaction.h" #include "object_list_processor.h" -#include "room.h" #include "level_table.h" #include "dialog_ids.h" @@ -396,10 +395,8 @@ s16 angle_to_object(struct Object *obj1, struct Object *obj2) { f32 z1, x1, z2, x2; s16 angle; - z1 = obj1->oPosZ; - z2 = obj2->oPosZ; - x1 = obj1->oPosX; - x2 = obj2->oPosX; + z1 = obj1->oPosZ; z2 = obj2->oPosZ; //ordering of instructions.. + x1 = obj1->oPosX; x2 = obj2->oPosX; angle = atan2s(z2 - z1, x2 - x1); return angle; @@ -982,19 +979,17 @@ void func_8029F684(f32 f12, f32 f14) { } } -void func_8029F6F0(void) { +BAD_RETURN(s16) func_8029F6F0(void) { if (o->header.gfx.unk38.animFrame >= 0) { o->header.gfx.unk38.animFrame--; } } -void func_8029F728(void) { +BAD_RETURN(s32) func_8029F728(void) { s32 sp4 = o->header.gfx.unk38.animFrame; s32 sp0 = o->header.gfx.unk38.curAnim->unk08 - 2; - - if (sp4 == sp0) { - o->header.gfx.unk38.animFrame--; - } + + if (sp4 == sp0) o->header.gfx.unk38.animFrame--; } s32 func_8029F788(void) { @@ -1203,19 +1198,19 @@ struct Surface *obj_update_floor_height_and_get_floor(void) { static void apply_drag_to_value(f32 *value, f32 dragStrength) { f32 decel; - if (*value != 0.0f) { + if (*value != 0) { //! Can overshoot if |*value| > 1/(dragStrength * 0.0001) decel = (*value) * (*value) * (dragStrength * 0.0001L); if (*value > 0) { *value -= decel; if (*value < 0.001L) { - *value = 0.0f; + *value = 0; } } else { *value += decel; if (*value > -0.001L) { - *value = 0.0f; + *value = 0; } } } @@ -1828,8 +1823,9 @@ void obj_move_standard(s16 steepSlopeAngleDegrees) { // Objects that do this will be marked with //PARTIAL_UPDATE. if (!(o->activeFlags & (ACTIVE_FLAG_FAR_AWAY | ACTIVE_FLAG_IN_DIFFERENT_ROOM))) { if (steepSlopeAngleDegrees < 0) { - careAboutEdgesAndSteepSlopes = TRUE; - steepSlopeAngleDegrees = -steepSlopeAngleDegrees; + // clang-format off + careAboutEdgesAndSteepSlopes = TRUE; steepSlopeAngleDegrees = -steepSlopeAngleDegrees; + // clang-format on } steepSlopeNormalY = coss(steepSlopeAngleDegrees * (0x10000 / 360)); @@ -2065,7 +2061,7 @@ void chain_segment_init(struct ChainSegment *segment) { } f32 random_f32_around_zero(f32 diameter) { - return RandomFloat() * diameter - diameter / 2.0f; + return RandomFloat() * diameter - diameter / 2; } void scale_object_random(struct Object *obj, f32 rangeLength, f32 minScale) { @@ -2102,10 +2098,75 @@ void func_802A2A38(void) { o->oPosZ += o->oVelZ; } +#if defined(VERSION_EU) +//this is a test to see if object is possibly built wrong +//it matches +struct Object_test +{ + /*0x000*/ struct ObjectNode header; + /*0x068*/ struct Object *parentObj; + /*0x06C*/ struct Object *prevObj; + /*0x070*/ u32 collidedObjInteractTypes; + /*0x074*/ s16 activeFlags; + /*0x076*/ s16 numCollidedObjs; + /*0x078*/ struct Object *collidedObjs[4]; + /*0x088*/ + union + { + struct { + u8 pad[0xF*4]; + s32 MoveAnglePitch; + s32 MoveAngleYaw; + s32 MoveAngleRoll; + u8 pad2[0x4B*4-0xF*4-3*4]; + struct { + u32 WallAngle; + } special; + } moving; + // Object fields. See object_fields.h. + u32 asU32[0x50]; + s32 asS32[0x50]; + s16 asS16[0x50][2]; + f32 asF32[0x50]; + s16 *asS16P[0x50]; + s32 *asS32P[0x50]; + struct Animation **asAnims[0x50]; + struct Waypoint *asWaypoint[0x50]; + struct ChainSegment *asChainSegment[0x50]; + struct Object *asObject[0x50]; + struct Surface *asSurface[0x50]; + void *asVoidPtr[0x50]; + const void *asConstVoidPtr[0x50]; + } rawData; + /*0x1C8*/ u32 unused1; + /*0x1CC*/ const BehaviorScript *behScript; + /*0x1D0*/ u32 stackIndex; + /*0x1D4*/ uintptr_t stack[8]; + /*0x1F4*/ s16 unk1F4; + /*0x1F6*/ s16 respawnInfoType; + /*0x1F8*/ f32 hitboxRadius; + /*0x1FC*/ f32 hitboxHeight; + /*0x200*/ f32 hurtboxRadius; + /*0x204*/ f32 hurtboxHeight; + /*0x208*/ f32 hitboxDownOffset; + /*0x20C*/ const BehaviorScript *behavior; + /*0x210*/ u32 unused2; + /*0x214*/ struct Object *platform; + /*0x218*/ void *collisionData; + /*0x21C*/ Mat4 transform; + /*0x25C*/ void *respawnInfo; +}; + +s16 obj_reflect_move_angle_off_wall(void) { + s16 angle = ((struct Object_test*)o)->rawData.moving.special.WallAngle - (s16) ((struct Object_test*)o)->rawData.moving.MoveAngleYaw + (s16) ((struct Object_test*)o)->rawData.moving.special.WallAngle +0x8000; + return angle; +} +#else s16 obj_reflect_move_angle_off_wall(void) { s16 angle = o->oWallAngle - ((s16) o->oMoveAngleYaw - (s16) o->oWallAngle) + 0x8000; return angle; } +#endif void obj_spawn_particles(struct SpawnParticlesInfo *info) { struct Object *particle; @@ -2285,7 +2346,7 @@ s32 func_802A32E0(void) { return spF; } -static void nop_802A3380(UNUSED s32 sp0, UNUSED s32 sp4) { +void nop_802A3380(UNUSED s32 sp0, UNUSED s32 sp4) { } void func_802A3398(s32 a0, s32 a1, f32 sp10, f32 sp14) { @@ -2312,7 +2373,7 @@ void func_802A3470(void) { obj_scale(gDebugInfo[5][3] / 100.0f + 1.0l); } -static void nop_802A3544(void) { +void nop_802A3544(void) { } s32 obj_is_mario_on_platform(void) { @@ -2860,6 +2921,28 @@ s32 obj_check_grabbed_mario(void) { return FALSE; } +#if defined(VERSION_EU) // Fake match +s32 player_performed_grab_escape_action(void) { + s32 result = FALSE; + s32 grabEscape = TRUE; + // using register here causes less differences with non-EU versions + register f32 stickMag = gPlayer1Controller->stickMag; + if (stickMag < 30.0f) { + sGrabReleaseState = 0; + } + + if (sGrabReleaseState == 0 && stickMag > 40.0f) { + sGrabReleaseState = grabEscape; + result = TRUE; + } + + if (gPlayer1Controller->buttonPressed & A_BUTTON) { + result = TRUE; + } + + return result; +} +#else s32 player_performed_grab_escape_action(void) { s32 result = FALSE; @@ -2878,6 +2961,7 @@ s32 player_performed_grab_escape_action(void) { return result; } +#endif void obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 sound) { if (obj_check_anim_frame(animFrame1) || obj_check_anim_frame(animFrame2)) { diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index d6b202c..b2eee9a 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -74,7 +74,7 @@ extern struct GraphNode **gLoadedGraphNodes; // extern ? D_8032F134; // extern const char* D_803366B0; // extern ? sKingBobombActions; -extern s16 gMarioShotFromCannon; +// extern s16 gMarioShotFromCannon; // extern ? sOpenedCannonActions; // extern ? D_803366B4; // extern ? D_803366BC; @@ -88,7 +88,7 @@ extern s16 gMarioShotFromCannon; // extern ? D_8032F284; // extern ? D_8032F294; // extern ? sCoinInsideBooActions; -extern s16 D_8035FEE4; +// extern s16 D_8035FEE4; // extern ? sGrindelThwompActions; // extern ? sTumblingBridgeParams; // extern ? sTumblingBridgeActions; @@ -240,8 +240,8 @@ struct Object* obj_find_nearby_held_actor(const BehaviorScript *,f32); // extern ? obj_reset_timer_and_subaction(?); void obj_change_action(s32); void func_8029F684(f32,f32); -void func_8029F6F0(void); -extern void func_8029F728(void); +BAD_RETURN(s16) func_8029F6F0(void); +extern BAD_RETURN(s32) func_8029F728(void); extern s32 func_8029F788(void); extern s32 func_8029F828(void); extern s32 obj_check_anim_frame(s32); diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 23febdd..f5e3d34 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -17,14 +17,9 @@ #include "object_helpers.h" #include "platform_displacement.h" #include "engine/surface_load.h" -#include "room.h" #include "object_list_processor.h" #include "mario.h" -/** - * Nodes used to represent the doubly linked object lists. - */ -struct ObjectNode gObjectListArray[16]; /** * Flags controlling what debug info is displayed. @@ -148,6 +143,29 @@ s32 gNumStaticSurfaces; */ struct MemoryPool *gObjectMemoryPool; + +s16 gCheckingSurfaceCollisionsForCamera; +s16 gFindFloorIncludeSurfaceIntangible; +s16 *gEnvironmentRegions; +s32 gEnvironmentLevels[20]; +s8 gDoorAdjacentRooms[60][2]; +s16 gMarioCurrentRoom; +s16 D_8035FEE2; +s16 D_8035FEE4; +s16 gTHIWaterDrained; +s16 gTTCSpeedSetting; +s16 gMarioShotFromCannon; +s16 gCCMEnteredSlide; +s16 gNumRoomedObjectsInMarioRoom; +s16 gNumRoomedObjectsNotInMarioRoom; +s16 gWDWWaterLevelChanging; +s16 gMarioOnMerryGoRound; + +/** + * Nodes used to represent the doubly linked object lists. + */ +struct ObjectNode gObjectListArray[16]; + /** * The order that object lists are processed in a frame. */ diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h index f98183e..c75647c 100644 --- a/src/game/object_list_processor.h +++ b/src/game/object_list_processor.h @@ -96,6 +96,23 @@ extern s32 gNumStaticSurfaces; extern struct MemoryPool *gObjectMemoryPool; +extern s16 gCheckingSurfaceCollisionsForCamera; +extern s16 gFindFloorIncludeSurfaceIntangible; +extern s16 *gEnvironmentRegions; +extern s32 gEnvironmentLevels[20]; +extern s8 gDoorAdjacentRooms[60][2]; +extern s16 gMarioCurrentRoom; +extern s16 D_8035FEE2; +extern s16 D_8035FEE4; +extern s16 gTHIWaterDrained; +extern s16 gTTCSpeedSetting; +extern s16 gMarioShotFromCannon; +extern s16 gCCMEnteredSlide; +extern s16 gNumRoomedObjectsInMarioRoom; +extern s16 gNumRoomedObjectsNotInMarioRoom; +extern s16 gWDWWaterLevelChanging; +extern s16 gMarioOnMerryGoRound; + void bhv_mario_update(void); void set_object_respawn_info_bits(struct Object *obj, u8 bits); diff --git a/src/game/paintings.c b/src/game/paintings.c index de350ea..f34a0ed 100644 --- a/src/game/paintings.c +++ b/src/game/paintings.c @@ -605,12 +605,7 @@ void *func_802D3CF0(u8 *img, s16 tWidth, s16 tHeight, s16 *d, s16 e, s16 f, u8 g if (verts == NULL || sp80 == NULL) { } - gDPSetTextureImage(sp7C++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, img); - gDPTileSync(sp7C++); - gDPSetTile(sp7C++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, - G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadSync(sp7C++); - gDPLoadBlock(sp7C++, G_TX_LOADTILE, 0, 0, tWidth * tHeight - 1, CALC_DXT(tWidth, G_IM_SIZ_16b_BYTES)) + gLoadBlockTexture(sp7C++, tWidth, tHeight, G_IM_FMT_RGBA, img); for (sp9E = 0; sp9E < sp90; sp9E++) { sp9A = e * 3 + sp9E * 15 + 2; diff --git a/src/game/print.c b/src/game/print.c index 6249691..363b4bc 100644 --- a/src/game/print.c +++ b/src/game/print.c @@ -83,9 +83,7 @@ void format_integer(s32 n, s32 base, char *dest, s32 *totalLength, u8 width, s8 // Add leading pad to fit width. if (width > numDigits) { - for (len = 0; len < width - numDigits; len++) { - dest[len] = pad; - } + for (len = 0; len < width - numDigits; len++) dest[len] = pad; // Needs 1 length to print negative prefix. if (negative == TRUE) { @@ -117,9 +115,7 @@ void format_integer(s32 n, s32 base, char *dest, s32 *totalLength, u8 width, s8 { numDigits = 1; if (width > numDigits) { - for (len = 0; len < width - numDigits; len++) { - dest[len] = pad; - } + for (len = 0; len < width - numDigits; len++) dest[len] = pad; } dest[len] = '0'; } diff --git a/src/game/room.c b/src/game/room.c deleted file mode 100644 index 5a4d933..0000000 --- a/src/game/room.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include "sm64.h" -#include "room.h" - -s16 gCheckingSurfaceCollisionsForCamera; -s16 gFindFloorIncludeSurfaceIntangible; -s16 *gEnvironmentRegions; -s32 gEnvironmentLevels[20]; -s8 gDoorAdjacentRooms[60][2]; -s16 gMarioCurrentRoom; -s16 D_8035FEE2; -s16 D_8035FEE4; -s16 gTHIWaterDrained; -s16 gTTCSpeedSetting; -s16 gMarioShotFromCannon; -s16 gCCMEnteredSlide; -s16 gNumRoomedObjectsInMarioRoom; -s16 gNumRoomedObjectsNotInMarioRoom; -s16 gWDWWaterLevelChanging; -s16 gMarioOnMerryGoRound; diff --git a/src/game/room.h b/src/game/room.h deleted file mode 100644 index 231c41c..0000000 --- a/src/game/room.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ROOM_H -#define ROOM_H - -#include "types.h" - -extern s16 gCheckingSurfaceCollisionsForCamera; -extern s16 gFindFloorIncludeSurfaceIntangible; -extern s16 *gEnvironmentRegions; -extern s32 gEnvironmentLevels[20]; -extern s8 gDoorAdjacentRooms[60][2]; -extern s16 gMarioCurrentRoom; -extern s16 D_8035FEE2; -extern s16 D_8035FEE4; -extern s16 gTHIWaterDrained; -extern s16 gTTCSpeedSetting; -extern s16 gMarioShotFromCannon; -extern s16 gCCMEnteredSlide; -extern s16 gNumRoomedObjectsInMarioRoom; -extern s16 gNumRoomedObjectsNotInMarioRoom; -extern s16 gWDWWaterLevelChanging; -extern s16 gMarioOnMerryGoRound; - -#endif /* ROOM_H */ diff --git a/src/game/save_file.c b/src/game/save_file.c index 15ae6a4..2fd6311 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -96,7 +96,7 @@ static s32 write_eeprom_data(void *buffer, s32 size) { * Sum the bytes in data to data + size - 2. The last two bytes are ignored * because that is where the checksum is stored. */ -static s32 calc_checksum(u8 *data, s32 size) { +static u16 calc_checksum(u8 *data, s32 size) { u16 chksum = 0; while (size-- > 2) { @@ -262,7 +262,8 @@ void save_file_erase(s32 fileIndex) { save_file_do_save(fileIndex); } -void save_file_copy(s32 srcFileIndex, s32 destFileIndex) { +//! Needs to be s32 to match on -O2, despite no return value. +BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex) { UNUSED s32 pad; touch_high_score_ages(destFileIndex); @@ -448,18 +449,18 @@ s32 save_file_get_total_star_count(s32 fileIndex, s32 minCourse, s32 maxCourse) return save_file_get_course_star_count(fileIndex, -1) + count; } -void save_file_set_flags(s32 flags) { +void save_file_set_flags(u32 flags) { gSaveBuffer.files[gCurrSaveFileNum - 1][0].flags |= (flags | SAVE_FLAG_FILE_EXISTS); gSaveFileModified = TRUE; } -void save_file_clear_flags(s32 flags) { +void save_file_clear_flags(u32 flags) { gSaveBuffer.files[gCurrSaveFileNum - 1][0].flags &= ~flags; gSaveBuffer.files[gCurrSaveFileNum - 1][0].flags |= SAVE_FLAG_FILE_EXISTS; gSaveFileModified = TRUE; } -s32 save_file_get_flags(void) { +u32 save_file_get_flags(void) { if (gCurrCreditsEntry != 0 || gCurrDemoInput != NULL) { return 0; } @@ -470,8 +471,8 @@ s32 save_file_get_flags(void) { * Return the bitset of obtained stars in the specified course. * If course is -1, return the bitset of obtained castle secret stars. */ -s32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) { - s32 starFlags; +u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) { + u32 starFlags; if (courseIndex == -1) { starFlags = (gSaveBuffer.files[fileIndex][0].flags >> 24) & 0x7F; @@ -486,7 +487,7 @@ s32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) { * Add to the bitset of obtained stars in the specified course. * If course is -1, add ot the bitset of obtained castle secret stars. */ -void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, s32 starFlags) { +void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags) { if (courseIndex == -1) { gSaveBuffer.files[fileIndex][0].flags |= starFlags << 24; } else { diff --git a/src/game/save_file.h b/src/game/save_file.h index 18eafc2..413ed44 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -123,7 +123,7 @@ extern s8 gSaveFileModified; void save_file_do_save(s32 fileIndex); void save_file_erase(s32 fileIndex); -void save_file_copy(s32 srcFileIndex, s32 destFileIndex); +BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex); void save_file_load_all(void); void save_file_reload(void); void save_file_collect_star_or_key(s16 coinScore, s16 starIndex); @@ -131,11 +131,11 @@ s32 save_file_exists(s32 fileIndex); u32 save_file_get_max_coin_score(s32 courseIndex); s32 save_file_get_course_star_count(s32 fileIndex, s32 courseIndex); s32 save_file_get_total_star_count(s32 fileIndex, s32 minCourse, s32 maxCourse); -void save_file_set_flags(s32 flags); -void save_file_clear_flags(s32 flags); -s32 save_file_get_flags(void); -s32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex); -void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, s32 starFlags); +void save_file_set_flags(u32 flags); +void save_file_clear_flags(u32 flags); +u32 save_file_get_flags(void); +u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex); +void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags); s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex); s32 save_file_is_cannon_unlocked(void); void save_file_set_cannon_unlocked(void); diff --git a/src/game/segment7.h b/src/game/segment7.h index a43c5a1..7c93e19 100644 --- a/src/game/segment7.h +++ b/src/game/segment7.h @@ -11,6 +11,16 @@ extern u8 menu_font_lut[]; extern u8 dl_menu_ia8_text_begin[]; extern u8 dl_menu_ia8_text_end[]; extern u8 dl_menu_rgba16_wood_course[]; +#ifdef VERSION_EU +extern u8 dl_menu_rgba16_wood_course_end[]; +extern u8 dl_menu_texture_course_upper[]; +extern u8 dl_menu_texture_niveau_upper[]; +extern u8 dl_menu_texture_kurs_upper[]; + +extern const u8 eu_course_strings_en_table[]; +extern const u8 eu_course_strings_fr_table[]; +extern const u8 eu_course_strings_de_table[]; +#endif // from intro_segment7 extern Gfx *intro_seg7_dl_0700B3A0; diff --git a/src/game/shadow.c b/src/game/shadow.c index 4b06580..5b74545 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -12,7 +12,7 @@ #include "mario.h" #include "memory.h" #include "rendering_graph_node.h" -#include "room.h" +#include "object_list_processor.h" #include "segment2.h" #include "save_file.h" #include "geo_misc.h" @@ -106,10 +106,10 @@ shadowRectangle rectangles[2] = { }; // See shadow.h for documentation. -s8 sMarioOnFlyingCarpet; -s16 sSurfaceTypeBelowShadow; s8 gShadowAboveWaterOrLava; s8 gMarioOnIceOrCarpet; +s8 sMarioOnFlyingCarpet; +s16 sSurfaceTypeBelowShadow; /** * Let (oldZ, oldX) be the relative coordinates of a point on a rectangle, diff --git a/src/game/skybox.c b/src/game/skybox.c index 4f48665..85ec123 100644 --- a/src/game/skybox.c +++ b/src/game/skybox.c @@ -227,12 +227,7 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex) (*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex]; Vtx *vertices = make_skybox_rect(tileIndex, colorIndex); - gDPSetTextureImage((*dlist)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, texture); - gDPTileSync((*dlist)++); - gDPSetTile((*dlist)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, - G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadSync((*dlist)++); - gDPLoadBlock((*dlist)++, G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)); + gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture); gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0); gSPDisplayList((*dlist)++, dl_draw_quad_verts_0123); } diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index c5772f7..b50db3e 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -27,7 +27,7 @@ struct LinkedList { * a list, and return this list in pFreeList. * Appears to have been replaced by init_free_object_list. */ -static void unused_init_free_list(struct LinkedList *usedList, struct LinkedList **pFreeList, +void unused_init_free_list(struct LinkedList *usedList, struct LinkedList **pFreeList, struct LinkedList *pool, s32 itemSize, s32 poolLength) { s32 i; struct LinkedList *node = pool; @@ -54,7 +54,7 @@ static void unused_init_free_list(struct LinkedList *usedList, struct LinkedList * freeList is empty. * Appears to have been replaced by try_allocate_object. */ -static struct LinkedList *unused_try_allocate(struct LinkedList *destList, +struct LinkedList *unused_try_allocate(struct LinkedList *destList, struct LinkedList *freeList) { struct LinkedList *node = freeList->next; @@ -77,7 +77,7 @@ static struct LinkedList *unused_try_allocate(struct LinkedList *destList, * to the end of destList (doubly linked). Return the object, or NULL if * freeList is empty. */ -static struct Object *try_allocate_object(struct ObjectNode *destList, struct ObjectNode *freeList) { +struct Object *try_allocate_object(struct ObjectNode *destList, struct ObjectNode *freeList) { struct ObjectNode *nextObj; if ((nextObj = freeList->next) != NULL) { @@ -104,7 +104,7 @@ static struct Object *try_allocate_object(struct ObjectNode *destList, struct Ob * singly linked freeList. * This function seems to have been replaced by deallocate_object. */ -static void unused_deallocate(struct LinkedList *freeList, struct LinkedList *node) { +void unused_deallocate(struct LinkedList *freeList, struct LinkedList *node) { // Remove from doubly linked list node->next->prev = node->prev; node->prev->next = node->next; @@ -113,7 +113,6 @@ static void unused_deallocate(struct LinkedList *freeList, struct LinkedList *no node->next = freeList->next; freeList->next = node; } - /** * Remove the given object from the object list that it's currently in, and * insert it at the beginning of the free list (singly linked). @@ -165,6 +164,9 @@ void clear_object_lists(struct ObjectNode *objLists) { * This function looks broken, but it appears to attempt to delete the leaf * graph nodes under obj and obj's siblings. */ +#ifdef VERSION_EU +struct Object *unused_delete_leaf_nodes() {} +#else static void unused_delete_leaf_nodes(struct Object *obj) { struct Object *children; struct Object *sibling; @@ -183,6 +185,7 @@ static void unused_delete_leaf_nodes(struct Object *obj) { obj = (struct Object *) sibling->header.gfx.node.next; } } +#endif /** * Free the given object. @@ -207,7 +210,7 @@ void unload_object(struct Object *obj) { * an unimportant object if necessary. If this is not possible, hang using an * infinite loop. */ -static struct Object *allocate_object(struct ObjectNode *objList) { +struct Object *allocate_object(struct ObjectNode *objList) { s32 i; struct Object *obj = try_allocate_object(objList, &gFreeObjectList); @@ -244,12 +247,15 @@ static struct Object *allocate_object(struct ObjectNode *objList) { obj->collidedObjInteractTypes = 0; obj->numCollidedObjs = 0; - for (i = 0; i < 0x50; i++) { - obj->rawData.asU32[i] = 0; #if IS_64_BIT + for (i = 0; i < 0x50; i++) { + obj->rawData.asS32[i] = 0; obj->ptrData.asVoidPtr[i] = NULL; -#endif } +#else + // -O2 needs everything until = on the same line + for (i = 0; i < 0x50; i++) obj->rawData.asS32[i] = 0; +#endif obj->unused1 = 0; obj->stackIndex = 0; diff --git a/src/goddard/draw_objects.c b/src/goddard/draw_objects.c index d39f51e..9abbd0c 100644 --- a/src/goddard/draw_objects.c +++ b/src/goddard/draw_objects.c @@ -12,7 +12,6 @@ #include "gd_math.h" #include "shape_helper.h" #include "renderer.h" -#include "prevent_bss_reordering.h" #include "draw_objects.h" /** diff --git a/src/goddard/dynlist_proc.c b/src/goddard/dynlist_proc.c index 931f34d..93818f8 100644 --- a/src/goddard/dynlist_proc.c +++ b/src/goddard/dynlist_proc.c @@ -3,7 +3,6 @@ #include #include "gd_types.h" #include "bad_declarations.h" -#include "prevent_bss_reordering.h" #include "gd_main.h" #include "draw_objects.h" diff --git a/src/goddard/joints.c b/src/goddard/joints.c index 3c897d5..b814f7b 100644 --- a/src/goddard/joints.c +++ b/src/goddard/joints.c @@ -1,5 +1,10 @@ #include #include + +#ifdef VERSION_EU +#include "prevent_bss_reordering.h" +#endif + #include "gd_types.h" #include "gd_macros.h" #include "joints.h" diff --git a/src/goddard/renderer.c b/src/goddard/renderer.c index 6e60445..3c4fcf7 100644 --- a/src/goddard/renderer.c +++ b/src/goddard/renderer.c @@ -3,7 +3,9 @@ #include #include +#ifndef VERSION_EU #include "prevent_bss_reordering.h" +#endif #include "gd_types.h" #include "gd_macros.h" #include "dynlists/dynlists.h" @@ -80,6 +82,25 @@ struct DynListBankInfo { }; // bss +#ifdef VERSION_EU +static OSMesgQueue D_801BE830; // controller msg queue +static OSMesg D_801BE848[10]; +u8 EUpad1[0x40]; +static OSMesgQueue D_801BE8B0; +static OSMesgQueue sGdDMAQueue; // @ 801BE8C8 +// static u32 unref_801be870[16]; +// static u32 unref_801be8e0[25]; +// static u32 unref_801be948[13]; +u8 EUpad2[0x64]; +static OSMesg sGdMesgBuf[1]; // @ 801BE944 +u8 EUpad3[0x34]; +static OSMesg D_801BE97C; // msg buf for D_801BE8B0 queue +static OSIoMesg D_801BE980; +static struct ObjView *D_801BE994; // store if View flag 0x40 set + +u8 EUpad4[0x88]; +#endif + static OSContStatus D_801BAE60[4]; static OSContPad sGdContPads[4]; // @ 801BAE70 static OSContPad sPrevFrameCont[4]; // @ 801BAE88 @@ -142,6 +163,7 @@ static s32 sPickBufPosition; // @ 801BE784 static s16 *sPickBuf; // @ 801BE788 static LookAt D_801BE790[2]; static LookAt D_801BE7D0[3]; +#ifndef VERSION_EU static OSMesgQueue D_801BE830; // controller msg queue static OSMesg D_801BE848[10]; static u32 unref_801be870[16]; @@ -153,6 +175,7 @@ static u32 unref_801be948[13]; static OSMesg D_801BE97C; // msg buf for D_801BE8B0 queue static OSIoMesg D_801BE980; static struct ObjView *D_801BE994; // store if View flag 0x40 set +#endif // data static u32 unref_801a8670 = 0; diff --git a/src/goddard/shape_helper.c b/src/goddard/shape_helper.c index db034ad..a696dca 100644 --- a/src/goddard/shape_helper.c +++ b/src/goddard/shape_helper.c @@ -16,7 +16,10 @@ #include "dynlists/dynlists.h" #include "dynlists/dynlist_macros.h" + +#ifndef VERSION_EU #include +#endif // types struct UnkData { diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 1f10360..06b80d3 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -27,20 +27,50 @@ * special menu messages and phases, button states and button clicked checks. */ + +#ifdef VERSION_US // The current sound mode is automatically centered on US due to // the large length difference between options. -#ifndef VERSION_JP +// sSoundTextY unused (EU supports its existance). static s16 sSoundTextX; +static s16 sSoundTextY; +#endif + +//! @Bug (UB Array Access) For PAL, more buttons were added than the array was extended. +//! This causes no currently known issues on console (as the other variables are not changed +//! while this is used) but can cause issues with other compilers. +#ifdef VERSION_EU + #ifdef AVOID_UB + #define NUM_BUTTONS 36 + #else + #define NUM_BUTTONS 34 + #endif +#else +#define NUM_BUTTONS 32 #endif // Amount of main menu buttons defined in the code called by spawn_object_rel_with_rot. // See file_select.h for the names in MenuButtonTypes. -static struct Object *sMainMenuButtons[32]; +static struct Object *sMainMenuButtons[NUM_BUTTONS]; + +#ifdef VERSION_EU +// The current sound mode is automatically centered on US due to +// the large length difference between options. +// sSoundTextY unused +static s16 sSoundTextX; +static s16 sSoundTextY; +#endif // Used to defined yes/no fade colors after a file is selected in the erase menu. // sYesNoColor[0]: YES | sYesNoColor[1]: NO static u8 sYesNoColor[2]; +// Unused variable that is written to for the centered X value for some strings. +#ifdef VERSION_EU +static s16 sCenteredX; +#endif + + // The button that is selected when it is clicked. static s8 sSelectedButtonID = MENU_BUTTON_NONE; @@ -83,6 +113,19 @@ static s16 sMainMenuTimer = 0; // 0: gSoundMode = 0 (Stereo) | 1: gSoundMode = 3 (Mono) | 2: gSoundMode = 1 (Headset) static s8 sSoundMode = 0; +// PAL changes most text to arrays for each language. This define allows these +// differences to be combined. +#ifdef VERSION_EU + #define LANGUAGE_ARRAY(cmd) cmd[sLanguageMode] +#else + #define LANGUAGE_ARRAY(cmd) cmd +#endif + +// Active language for PAL arrays. +#ifdef VERSION_EU +static s8 sLanguageMode = LANGUAGE_EN; +#endif + // Tracks which button will be pressed in the erase confirmation prompt (yes/no). static s8 sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE; @@ -98,32 +141,170 @@ static s8 sSelectedFileNum = 0; // coin high score, 1 for high score across all files. static s8 sScoreFileCoinScoreMode = 0; +// If no save file exists, open the language menu so the user can find it. +#ifdef VERSION_EU +static s8 sOpenLangSettings = FALSE; +#endif + +#ifndef VERSION_EU static unsigned char textReturn[] = { TEXT_RETURN }; +#else +static unsigned char textReturn[][8] = {{ TEXT_RETURN }, { TEXT_RETURN_FR }, { TEXT_RETURN_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textViewScore[] = { TEXT_CHECK_SCORE }; +#else +static unsigned char textViewScore[][12] = {{ TEXT_CHECK_SCORE }, {TEXT_CHECK_SCORE_FR}, {TEXT_CHECK_SCORE_DE}}; +#endif + +#ifndef VERSION_EU static unsigned char textCopyFileButton[] = { TEXT_COPY_FILE_BUTTON }; +#else +static unsigned char textCopyFileButton[][15] = {{ TEXT_COPY_FILE }, { TEXT_COPY_FILE_FR }, { TEXT_COPY_FILE_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textEraseFileButton[] = { TEXT_ERASE_FILE_BUTTON }; +#else +static unsigned char textEraseFileButton[][16] = { {TEXT_ERASE_FILE}, {TEXT_ERASE_FILE_FR}, {TEXT_ERASE_FILE_DE} }; +#endif + +#ifndef VERSION_EU static unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET } }; +#endif + static unsigned char textMarioA[] = { TEXT_FILE_MARIO_A }; static unsigned char textMarioB[] = { TEXT_FILE_MARIO_B }; static unsigned char textMarioC[] = { TEXT_FILE_MARIO_C }; static unsigned char textMarioD[] = { TEXT_FILE_MARIO_D }; + +#ifndef VERSION_EU static unsigned char textNew[] = { TEXT_NEW }; static unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE }; static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; +#endif + +#ifndef VERSION_EU static unsigned char textSelectFile[] = { TEXT_SELECT_FILE }; +#else +static unsigned char textSelectFile[][17] = {{ TEXT_SELECT_FILE }, { TEXT_SELECT_FILE_FR }, { TEXT_SELECT_FILE_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textScore[] = { TEXT_SCORE }; +#else +static unsigned char textScore[][9] = {{ TEXT_SCORE }, { TEXT_SCORE_FR }, { TEXT_SCORE_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textCopy[] = { TEXT_COPY }; +#else +static unsigned char textCopy[][9] = {{ TEXT_COPY }, { TEXT_COPY_FR }, { TEXT_COPY_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textErase[] = { TEXT_ERASE }; +#else +static unsigned char textErase[][8] = {{ TEXT_ERASE }, { TEXT_ERASE_FR }, { TEXT_ERASE_DE }}; +#endif + +#ifdef VERSION_EU +static unsigned char textOption[][9] = {{ TEXT_OPTION }, { TEXT_OPTION_FR }, { TEXT_OPTION_DE } }; +#endif + +#ifndef VERSION_EU static unsigned char textCheckFile[] = { TEXT_CHECK_FILE }; +#else +static unsigned char textCheckFile[][18] = {{ TEXT_CHECK_FILE }, { TEXT_CHECK_FILE_FR }, { TEXT_CHECK_FILE_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS }; +#else +static unsigned char textNoSavedDataExists[][30] = {{ TEXT_NO_SAVED_DATA_EXISTS }, { TEXT_NO_SAVED_DATA_EXISTS_FR }, { TEXT_NO_SAVED_DATA_EXISTS_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textCopyFile[] = { TEXT_COPY_FILE }; +#else +static unsigned char textCopyFile[][16] = {{ TEXT_COPY_FILE_BUTTON }, { TEXT_COPY_FILE_BUTTON_FR }, { TEXT_COPY_FILE_BUTTON_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textCopyItToWhere[] = { TEXT_COPY_IT_TO_WHERE }; +#else +static unsigned char textCopyItToWhere[][18] = {{ TEXT_COPY_IT_TO_WHERE }, { TEXT_COPY_IT_TO_WHERE_FR }, { TEXT_COPY_IT_TO_WHERE_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textNoSavedDataExistsCopy[] = { TEXT_NO_SAVED_DATA_EXISTS }; +#endif + +#ifndef VERSION_EU static unsigned char textCopyCompleted[] = { TEXT_COPYING_COMPLETED }; +#else +static unsigned char textCopyCompleted[][18] = {{ TEXT_COPYING_COMPLETED }, { TEXT_COPYING_COMPLETED_FR }, { TEXT_COPYING_COMPLETED_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS }; +#else +static unsigned char textSavedDataExists[][20] = {{ TEXT_SAVED_DATA_EXISTS }, { TEXT_SAVED_DATA_EXISTS_FR }, { TEXT_SAVED_DATA_EXISTS_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textNoFileToCopyFrom[] = { TEXT_NO_FILE_TO_COPY_FROM }; +#else +static unsigned char textNoFileToCopyFrom[][21] = {{ TEXT_NO_FILE_TO_COPY_FROM }, { TEXT_NO_FILE_TO_COPY_FROM_FR }, { TEXT_NO_FILE_TO_COPY_FROM_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textYes[] = { TEXT_YES }; +#else +static unsigned char textYes[][4] = {{ TEXT_YES }, { TEXT_YES_FR }, { TEXT_YES_DE }}; +#endif + +#ifndef VERSION_EU static unsigned char textNo[] = { TEXT_NO }; +#else +static unsigned char textNo[][5] = {{ TEXT_NO }, { TEXT_NO_FR }, { TEXT_NO_DE }}; +#endif + +#ifdef VERSION_EU +// TODO: Should the following should be data local to functions? +static unsigned char textEraseFile[][17] = { + { TEXT_ERASE_FILE_BUTTON }, { TEXT_ERASE_FILE_BUTTON_FR }, { TEXT_ERASE_FILE_BUTTON_DE } +}; +static unsigned char textSure[][8] = {{ TEXT_SURE }, { TEXT_SURE_FR }, { TEXT_SURE_DE }}; +static unsigned char textMarioAJustErased[][20] = { + { TEXT_FILE_MARIO_A_JUST_ERASED }, { TEXT_FILE_MARIO_A_JUST_ERASED_FR }, { TEXT_FILE_MARIO_A_JUST_ERASED_DE } +}; + +static unsigned char textSoundSelect[][13] = { + { TEXT_SOUND_SELECT }, { TEXT_SOUND_SELECT_FR }, { TEXT_SOUND_SELECT_DE } +}; + +static unsigned char textLanguageSelect[][17] = { + { TEXT_LANGUAGE_SELECT }, { TEXT_LANGUAGE_SELECT_FR }, { TEXT_LANGUAGE_SELECT_DE } +}; + +static unsigned char textSoundModes[][10] = { + { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET }, + { TEXT_STEREO_FR }, { TEXT_MONO_FR }, { TEXT_HEADSET_FR }, + { TEXT_STEREO_DE }, { TEXT_MONO_DE }, { TEXT_HEADSET_DE } +}; + +static unsigned char textLanguage[][9] = {{ TEXT_ENGLISH }, { TEXT_FRENCH }, { TEXT_GERMAN }}; + +static unsigned char textMario[] = { TEXT_MARIO }; +static unsigned char textHiScore[][15] = {{ TEXT_HI_SCORE }, { TEXT_HI_SCORE_FR }, { TEXT_HI_SCORE_DE }}; +static unsigned char textMyScore2[][10] = {{ TEXT_MY_SCORE }, { TEXT_MY_SCORE_FR }, { TEXT_MY_SCORE_DE }}; + +static unsigned char textNew[][5] = {{ TEXT_NEW }, { TEXT_NEW_FR }, { TEXT_NEW_DE }}; +static unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE }; +static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; +#endif /** * Yellow Background Menu Initial Action @@ -147,10 +328,10 @@ void beh_yellow_background_menu_loop(void) { * Check if a button was clicked. * depth = 200.0 for main menu, 22.0 for submenus. */ -static s32 check_clicked_button(s16 x, s16 y, f32 depth) { +s32 check_clicked_button(s16 x, s16 y, f32 depth) { f32 a = 52.4213; f32 newX = ((f32) x * 160.0) / (a * depth); - f32 newY = ((f32) y * 120.0) / (a * 3.0f / 4.0f * depth); + f32 newY = ((f32) y * 120.0) / (a * 3 / 4 * depth); s16 maxX = newX + 25.0f; s16 minX = newX - 25.0f; s16 maxY = newY + 21.0f; @@ -383,7 +564,7 @@ void bhv_menu_button_loop(void) { /** * Handles how to exit the score file menu using button states. */ -static void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 scoreButtonID) { +void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 scoreButtonID) { // Begin exit if (scoreFileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN && sCursorClickingTimer == 2) { @@ -403,7 +584,7 @@ static void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 sco * Render buttons for the score menu. * Also check if the save file exists to render a different Mario button. */ -static void render_score_menu_buttons(struct Object *scoreButton) { +void render_score_menu_buttons(struct Object *scoreButton) { // File A if (save_file_exists(SAVE_FILE_A) == TRUE) { sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A] = @@ -459,10 +640,16 @@ static void render_score_menu_buttons(struct Object *scoreButton) { sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]->oMenuButtonScale = 0.11111111f; } +#ifdef VERSION_EU + #define SCORE_TIMER 46 +#else + #define SCORE_TIMER 31 +#endif + /** * In the score menu, checks if a button was clicked to play a sound, button state and other functions. */ -static void check_score_menu_clicked_buttons(struct Object *scoreButton) { +void check_score_menu_clicked_buttons(struct Object *scoreButton) { if (scoreButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { s32 buttonID; // Configure score menu button group @@ -470,7 +657,7 @@ static void check_score_menu_clicked_buttons(struct Object *scoreButton) { s16 buttonX = sMainMenuButtons[buttonID]->oPosX; s16 buttonY = sMainMenuButtons[buttonID]->oPosY; - if (check_clicked_button(buttonX, buttonY, 22.0f) == TRUE && sMainMenuTimer >= 31) { + if (check_clicked_button(buttonX, buttonY, 22.0f) == TRUE && sMainMenuTimer >= SCORE_TIMER) { // If menu button clicked, select it if (buttonID == MENU_BUTTON_SCORE_RETURN || buttonID == MENU_BUTTON_SCORE_COPY_FILE || buttonID == MENU_BUTTON_SCORE_ERASE_FILE) { @@ -479,7 +666,7 @@ static void check_score_menu_clicked_buttons(struct Object *scoreButton) { sSelectedButtonID = buttonID; } else { // Check if a save file is clicked - if (sMainMenuTimer >= 31) { + if (sMainMenuTimer >= SCORE_TIMER) { // If clicked in a existing save file, select it too see it's score if (save_file_exists(buttonID - MENU_BUTTON_SCORE_MIN) == TRUE) { play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); @@ -491,7 +678,7 @@ static void check_score_menu_clicked_buttons(struct Object *scoreButton) { play_sound(SOUND_MENU_CAMERA_BUZZ, gDefaultSoundArgs); sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; - if (sMainMenuTimer >= 31) { + if (sMainMenuTimer >= SCORE_TIMER) { sFadeOutText = TRUE; sMainMenuTimer = 0; } @@ -504,12 +691,13 @@ static void check_score_menu_clicked_buttons(struct Object *scoreButton) { } } } +#undef SCORE_TIMER /** * Render buttons for the copy menu. * Also check if the save file exists to render a different Mario button. */ -static void render_copy_menu_buttons(struct Object *copyButton) { +void render_copy_menu_buttons(struct Object *copyButton) { // File A if (save_file_exists(SAVE_FILE_A) == TRUE) { sMainMenuButtons[MENU_BUTTON_COPY_FILE_A] = @@ -563,10 +751,16 @@ static void render_copy_menu_buttons(struct Object *copyButton) { sMainMenuButtons[MENU_BUTTON_COPY_ERASE_FILE]->oMenuButtonScale = 0.11111111f; } +#ifdef VERSION_EU + #define BUZZ_TIMER 36 +#else + #define BUZZ_TIMER 21 +#endif + /** * Copy Menu phase actions that handles what to do when a file button is clicked. */ -static void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { +void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { switch (copyButton->oMenuButtonActionPhase) { case COPY_PHASE_MAIN: // Copy Menu Main Phase if (sAllFilesExist == TRUE) { // Don't enable copy if all save files exists @@ -584,7 +778,7 @@ static void copy_action_file_button(struct Object *copyButton, s32 copyFileButto // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gDefaultSoundArgs); sMainMenuButtons[copyFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; - if (sMainMenuTimer >= 21) { + if (sMainMenuTimer >= BUZZ_TIMER) { sFadeOutText = TRUE; sMainMenuTimer = 0; } @@ -599,10 +793,17 @@ static void copy_action_file_button(struct Object *copyButton, s32 copyFileButto sFadeOutText = TRUE; sMainMenuTimer = 0; save_file_copy(sSelectedFileIndex, copyFileButtonID - MENU_BUTTON_COPY_MIN); + #ifdef VERSION_EU sMainMenuButtons[copyFileButtonID]->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE]; sMainMenuButtons[copyFileButtonID - MENU_BUTTON_COPY_MIN]->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE]; + #else + sMainMenuButtons[copyFileButtonID]->header.gfx.sharedChild = + gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE]; + sMainMenuButtons[copyFileButtonID - MENU_BUTTON_COPY_MIN]->header.gfx.sharedChild = + gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE]; + #endif } else { // If clicked in a existing save file, play buzz sound if (MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex == copyFileButtonID) { @@ -613,7 +814,7 @@ static void copy_action_file_button(struct Object *copyButton, s32 copyFileButto sFadeOutText = TRUE; return; } - if (sMainMenuTimer >= 21) { + if (sMainMenuTimer >= BUZZ_TIMER) { sFadeOutText = TRUE; sMainMenuTimer = 0; } @@ -622,10 +823,18 @@ static void copy_action_file_button(struct Object *copyButton, s32 copyFileButto } } +#ifdef VERSION_EU + #define ACTION_TIMER 41 + #define MAIN_RETURN_TIMER 36 +#else + #define ACTION_TIMER 31 + #define MAIN_RETURN_TIMER 31 +#endif + /** * In the copy menu, checks if a button was clicked to play a sound, button state and other functions. */ -static void check_copy_menu_clicked_buttons(struct Object *copyButton) { +void check_copy_menu_clicked_buttons(struct Object *copyButton) { if (copyButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { s32 buttonID; // Configure copy menu button group @@ -646,7 +855,7 @@ static void check_copy_menu_clicked_buttons(struct Object *copyButton) { else { // Check if a file button is clicked to play a copy action if (sMainMenuButtons[buttonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT - && sMainMenuTimer >= 31) { + && sMainMenuTimer >= ACTION_TIMER) { copy_action_file_button(copyButton, buttonID); } } @@ -654,8 +863,10 @@ static void check_copy_menu_clicked_buttons(struct Object *copyButton) { break; } } + // After copy is complete, return to main copy phase - if (copyButton->oMenuButtonActionPhase == COPY_PHASE_COPY_COMPLETE && sMainMenuTimer >= 31) { + if (copyButton->oMenuButtonActionPhase == COPY_PHASE_COPY_COMPLETE + && sMainMenuTimer >= MAIN_RETURN_TIMER) { copyButton->oMenuButtonActionPhase = COPY_PHASE_MAIN; sMainMenuButtons[MENU_BUTTON_COPY_MIN + sSelectedFileIndex]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_OUT; @@ -667,7 +878,7 @@ static void check_copy_menu_clicked_buttons(struct Object *copyButton) { * Render buttons for the erase menu. * Also check if the save file exists to render a different Mario button. */ -static void render_erase_menu_buttons(struct Object *eraseButton) { +void render_erase_menu_buttons(struct Object *eraseButton) { // File A if (save_file_exists(SAVE_FILE_A) == TRUE) { sMainMenuButtons[MENU_BUTTON_ERASE_FILE_A] = @@ -726,7 +937,7 @@ static void render_erase_menu_buttons(struct Object *eraseButton) { /** * Erase Menu phase actions that handles what to do when a file button is clicked. */ -static void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) { +void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) { switch (eraseButton->oMenuButtonActionPhase) { case ERASE_PHASE_MAIN: // Erase Menu Main Phase if (save_file_exists(eraseFileButtonID - MENU_BUTTON_ERASE_MIN) == TRUE) { @@ -741,7 +952,8 @@ static void erase_action_file_button(struct Object *eraseButton, s32 eraseFileBu // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gDefaultSoundArgs); sMainMenuButtons[eraseFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; - if (sMainMenuTimer >= 21) { + + if (sMainMenuTimer >= BUZZ_TIMER) { sFadeOutText = TRUE; sMainMenuTimer = 0; } @@ -761,11 +973,12 @@ static void erase_action_file_button(struct Object *eraseButton, s32 eraseFileBu break; } } +#undef BUZZ_TIMER /** * In the erase menu, checks if a button was clicked to play a sound, button state and other functions. */ -static void check_erase_menu_clicked_buttons(struct Object *eraseButton) { +void check_erase_menu_clicked_buttons(struct Object *eraseButton) { if (eraseButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { s32 buttonID; // Configure erase menu button group @@ -785,7 +998,7 @@ static void check_erase_menu_clicked_buttons(struct Object *eraseButton) { } else { // Check if a file button is clicked to play an erase action - if (sMainMenuTimer >= 31) { + if (sMainMenuTimer >= ACTION_TIMER) { erase_action_file_button(eraseButton, buttonID); } } @@ -794,42 +1007,73 @@ static void check_erase_menu_clicked_buttons(struct Object *eraseButton) { } } // After erase is complete, return to main erase phase - if (eraseButton->oMenuButtonActionPhase == ERASE_PHASE_MARIO_ERASED && sMainMenuTimer >= 31) { + if (eraseButton->oMenuButtonActionPhase == ERASE_PHASE_MARIO_ERASED + && sMainMenuTimer >= MAIN_RETURN_TIMER) { eraseButton->oMenuButtonActionPhase = ERASE_PHASE_MAIN; sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_OUT; } } } +#undef ACTION_TIMER +#undef MAIN_RETURN_TIMER + +#ifdef VERSION_EU + #define SOUND_Y 388 +#else + #define SOUND_Y 0 +#endif /** * Render buttons for the sound mode menu. */ -static void render_sound_mode_menu_buttons(struct Object *soundModeButton) { +void render_sound_mode_menu_buttons(struct Object *soundModeButton) { // Stereo option button sMainMenuButtons[MENU_BUTTON_STEREO] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, 0, -100, 0, -0x8000, 0); + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, SOUND_Y, -100, 0, -0x8000, 0); sMainMenuButtons[MENU_BUTTON_STEREO]->oMenuButtonScale = 0.11111111f; // Mono option button sMainMenuButtons[MENU_BUTTON_MONO] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, 0, -100, 0, -0x8000, 0); + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, SOUND_Y, -100, 0, -0x8000, 0); sMainMenuButtons[MENU_BUTTON_MONO]->oMenuButtonScale = 0.11111111f; // Headset option button sMainMenuButtons[MENU_BUTTON_HEADSET] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, 0, -100, 0, -0x8000, 0); + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, SOUND_Y, -100, 0, -0x8000, 0); sMainMenuButtons[MENU_BUTTON_HEADSET]->oMenuButtonScale = 0.11111111f; + +#ifdef VERSION_EU + // English option button + sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH] = spawn_object_rel_with_rot( + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, -111, -100, 0, -0x8000, 0); + sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH]->oMenuButtonScale = 0.11111111f; + // French option button + sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH] = spawn_object_rel_with_rot( + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, -111, -100, 0, -0x8000, 0); + sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH]->oMenuButtonScale = 0.11111111f; + // German option button + sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN] = spawn_object_rel_with_rot( + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, -111, -100, 0, -0x8000, 0); + sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN]->oMenuButtonScale = 0.11111111f; + + // Return button + sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN] = spawn_object_rel_with_rot( + soundModeButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 0, -533, -100, 0, -0x8000, 0); + sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]->oMenuButtonScale = 0.11111111f; +#else // Zoom in current selection - sMainMenuButtons[MENU_BUTTON_SOUND_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; + sMainMenuButtons[MENU_BUTTON_OPTION_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; +#endif } +#undef SOUND_Y /** * In the sound mode menu, checks if a button was clicked to change sound mode & button state. */ -static void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { +void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { if (soundModeButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { s32 buttonID; // Configure sound mode menu button group - for (buttonID = MENU_BUTTON_SOUND_MIN; buttonID < MENU_BUTTON_SOUND_MAX; buttonID++) { + for (buttonID = MENU_BUTTON_OPTION_MIN; buttonID < MENU_BUTTON_OPTION_MAX; buttonID++) { s16 buttonX = sMainMenuButtons[buttonID]->oPosX; s16 buttonY = sMainMenuButtons[buttonID]->oPosY; @@ -841,12 +1085,31 @@ static void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs); sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; +#ifndef VERSION_EU sSelectedButtonID = buttonID; - sSoundMode = buttonID - MENU_BUTTON_SOUND_MIN; +#endif + sSoundMode = buttonID - MENU_BUTTON_OPTION_MIN; save_file_set_sound_mode(sSoundMode); } } +#ifdef VERSION_EU + if (buttonID == MENU_BUTTON_LANGUAGE_ENGLISH || buttonID == MENU_BUTTON_LANGUAGE_FRENCH + || buttonID == MENU_BUTTON_LANGUAGE_GERMAN) { + if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { + play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs); + sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; + sLanguageMode = buttonID - MENU_BUTTON_LANGUAGE_MIN; + eu_set_language(sLanguageMode); + } + } + if (buttonID == MENU_BUTTON_LANGUAGE_RETURN) { + play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs); + sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; + sSelectedButtonID = buttonID; + } +#endif sCurrentMenuLevel = MENU_LAYER_SUBMENU; + break; } } @@ -857,7 +1120,7 @@ static void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton * Loads a save file selected after it goes into a full screen state * retuning sSelectedFileNum to a save value defined in fileNum. */ -static void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { +void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { sSelectedFileNum = fileNum; } @@ -867,7 +1130,7 @@ static void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { * Returns from the previous menu back to the main menu using * the return button (or sound mode) as source button. */ -static void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButton) { +void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButton) { s32 buttonID; // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu @@ -897,7 +1160,7 @@ static void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButto } } if (prevMenuButtonID == MENU_BUTTON_SOUND_MODE) { - for (buttonID = MENU_BUTTON_SOUND_MIN; buttonID < MENU_BUTTON_SOUND_MAX; buttonID++) { + for (buttonID = MENU_BUTTON_OPTION_MIN; buttonID < MENU_BUTTON_OPTION_MAX; buttonID++) { mark_obj_for_deletion(sMainMenuButtons[buttonID]); } } @@ -907,7 +1170,7 @@ static void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButto /** * Loads score menu from the previous menu using "CHECK SCORE" as source button. */ -static void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { +void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { s32 buttonID; // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu @@ -948,7 +1211,7 @@ static void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *so /** * Loads copy menu from the previous menu using "COPY FILE" as source button. */ -static void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { +void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { s32 buttonID; // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu @@ -989,7 +1252,7 @@ static void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sou /** * Loads erase menu from the previous menu using "ERASE FILE" as source button. */ -static void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { +void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { s32 buttonID; // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu @@ -1097,71 +1360,84 @@ void bhv_menu_button_manager_init(void) { } #ifdef VERSION_JP -#define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND + #define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND #else -#define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND_OKEY_DOKEY + #define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND_OKEY_DOKEY #endif /** * In the main menu, check if a button was clicked to play it's button growing state. * Also play a sound and/or render buttons depending of the button ID selected. */ -static void check_main_menu_clicked_buttons(void) { - // Sound mode menu is handled separately because the button ID for it - // is not grouped with the IDs of the other submenus. - if (check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX, - sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosY, 200.0f) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - sSelectedButtonID = MENU_BUTTON_SOUND_MODE; - } else { - // Main Menu buttons - s8 buttonID; - // Configure Main Menu button group - for (buttonID = MENU_BUTTON_MAIN_MIN; buttonID < MENU_BUTTON_MAIN_MAX; buttonID++) { - s16 buttonX = sMainMenuButtons[buttonID]->oPosX; - s16 buttonY = sMainMenuButtons[buttonID]->oPosY; +void check_main_menu_clicked_buttons(void) { +#ifdef VERSION_EU + if (sMainMenuTimer >= 5) { +#endif + // Sound mode menu is handled separately because the button ID for it + // is not grouped with the IDs of the other submenus. + if (check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX, + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosY, 200.0f) == TRUE) { + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = MENU_BUTTON_SOUND_MODE; + } else { + // Main Menu buttons + s8 buttonID; + // Configure Main Menu button group + for (buttonID = MENU_BUTTON_MAIN_MIN; buttonID < MENU_BUTTON_MAIN_MAX; buttonID++) { + s16 buttonX = sMainMenuButtons[buttonID]->oPosX; + s16 buttonY = sMainMenuButtons[buttonID]->oPosY; - if (check_clicked_button(buttonX, buttonY, 200.0f) == TRUE) { - // If menu button clicked, select it - sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - sSelectedButtonID = buttonID; - break; + if (check_clicked_button(buttonX, buttonY, 200.0f) == TRUE) { + // If menu button clicked, select it + sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = buttonID; + break; + } } } - } +#ifdef VERSION_EU + if (sOpenLangSettings == TRUE){ + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = MENU_BUTTON_SOUND_MODE; + sOpenLangSettings = FALSE; + } +#endif - // Play sound of the save file clicked - switch (sSelectedButtonID) { - case MENU_BUTTON_PLAY_FILE_A: - play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); - break; - case MENU_BUTTON_PLAY_FILE_B: - play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); - break; - case MENU_BUTTON_PLAY_FILE_C: - play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); - break; - case MENU_BUTTON_PLAY_FILE_D: - play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); - break; - // Play sound of the button clicked and render buttons of that menu. - case MENU_BUTTON_SCORE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); - render_score_menu_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); - break; - case MENU_BUTTON_COPY: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); - render_copy_menu_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); - break; - case MENU_BUTTON_ERASE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); - render_erase_menu_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); - break; - case MENU_BUTTON_SOUND_MODE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); - render_sound_mode_menu_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); - break; + // Play sound of the save file clicked + switch (sSelectedButtonID) { + case MENU_BUTTON_PLAY_FILE_A: + play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); + break; + case MENU_BUTTON_PLAY_FILE_B: + play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); + break; + case MENU_BUTTON_PLAY_FILE_C: + play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); + break; + case MENU_BUTTON_PLAY_FILE_D: + play_sound(SAVE_FILE_SOUND, gDefaultSoundArgs); + break; + // Play sound of the button clicked and render buttons of that menu. + case MENU_BUTTON_SCORE: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); + render_score_menu_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); + break; + case MENU_BUTTON_COPY: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); + render_copy_menu_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); + break; + case MENU_BUTTON_ERASE: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); + render_erase_menu_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); + break; + case MENU_BUTTON_SOUND_MODE: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); + render_sound_mode_menu_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); + break; + } +#ifdef VERSION_EU } +#endif } #undef SAVE_FILE_SOUND @@ -1265,6 +1541,12 @@ void bhv_menu_button_manager_loop(void) { case MENU_BUTTON_SOUND_MODE: check_sound_mode_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); break; + +#ifdef VERSION_EU + case MENU_BUTTON_LANGUAGE_RETURN: + return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]); + break; +#else case MENU_BUTTON_STEREO: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_STEREO]); break; @@ -1274,6 +1556,7 @@ void bhv_menu_button_manager_loop(void) { case MENU_BUTTON_HEADSET: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_HEADSET]); break; +#endif } sClickPos[0] = -10000; @@ -1284,12 +1567,17 @@ void bhv_menu_button_manager_loop(void) { * Cursor function that handles button inputs. * If the cursor is clicked, sClickPos uses the same value as sCursorPos. */ -static void handle_cursor_button_input(void) { +void handle_cursor_button_input(void) { // If scoring a file, pressing A just changes the coin score mode. if (sSelectedButtonID == MENU_BUTTON_SCORE_FILE_A || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_B || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_C || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_D) { - if (gPlayer3Controller->buttonPressed & (B_BUTTON | START_BUTTON)) { + if (gPlayer3Controller->buttonPressed +#ifdef VERSION_EU + & (B_BUTTON | START_BUTTON | Z_TRIG)) { +#else + & (B_BUTTON | START_BUTTON)) { +#endif sClickPos[0] = sCursorPos[0]; sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; @@ -1298,7 +1586,12 @@ static void handle_cursor_button_input(void) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gDefaultSoundArgs); } } else { // If cursor is clicked - if (gPlayer3Controller->buttonPressed & (A_BUTTON | B_BUTTON | START_BUTTON)) { + if (gPlayer3Controller->buttonPressed +#ifdef VERSION_EU + & (A_BUTTON | B_BUTTON | START_BUTTON | Z_TRIG)) { +#else + & (A_BUTTON | B_BUTTON | START_BUTTON)) { +#endif sClickPos[0] = sCursorPos[0]; sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; @@ -1309,7 +1602,7 @@ static void handle_cursor_button_input(void) { /** * Cursor function that handles analog stick input and button presses with a function near the end. */ -static void handle_controller_cursor_input(void) { +void handle_controller_cursor_input(void) { s16 rawStickX = gPlayer3Controller->rawStickX; s16 rawStickY = gPlayer3Controller->rawStickY; @@ -1350,7 +1643,7 @@ static void handle_controller_cursor_input(void) { * and loads it's controller inputs in handle_controller_cursor_input * to be usable on the file select. */ -static void print_menu_cursor(void) { +void print_menu_cursor(void) { handle_controller_cursor_input(); create_dl_translation_matrix(MENU_MTX_PUSH, sCursorPos[0] + 160.0f - 5.0, sCursorPos[1] + 120.0f - 25.0, 0.0f); // Get the right graphic to use for the cursor. @@ -1373,7 +1666,7 @@ static void print_menu_cursor(void) { /** * Prints a hud string depending of the hud table list defined with text fade properties. */ -static void print_hud_lut_string_fade(s8 hudLUT, s16 x, s16 y, const unsigned char *text) { +void print_hud_lut_string_fade(s8 hudLUT, s16 x, s16 y, const unsigned char *text) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha - sTextFadeAlpha); print_hud_lut_string(hudLUT, x, y, text); @@ -1383,7 +1676,7 @@ static void print_hud_lut_string_fade(s8 hudLUT, s16 x, s16 y, const unsigned ch /** * Prints a generic white string with text fade properties. */ -static void print_generic_string_fade(s16 x, s16 y, const unsigned char *text) { +void print_generic_string_fade(s16 x, s16 y, const unsigned char *text) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha - sTextFadeAlpha); print_generic_string(x, y, text); @@ -1393,7 +1686,7 @@ static void print_generic_string_fade(s16 x, s16 y, const unsigned char *text) { /** * Updates text fade at the top of a menu. */ -static s32 update_text_fade_out(void) { +s32 update_text_fade_out(void) { if (sFadeOutText == TRUE) { sTextFadeAlpha += 50; if (sTextFadeAlpha == 250) { @@ -1412,7 +1705,7 @@ static s32 update_text_fade_out(void) { * Prints the amount of stars of a save file. * If a save doesn't exist, print "NEW" instead. */ -static void print_save_file_star_count(s8 fileIndex, s16 x, s16 y) { +void print_save_file_star_count(s8 fileIndex, s16 x, s16 y) { u8 starCountText[4]; s8 offset = 0; s16 starCount; @@ -1432,38 +1725,60 @@ static void print_save_file_star_count(s8 fileIndex, s16 x, s16 y) { print_hud_lut_string(HUD_LUT_GLOBAL, x + offset + 16, y, starCountText); } else { // Print "new" text - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, textNew); + print_hud_lut_string(HUD_LUT_GLOBAL, x, y, LANGUAGE_ARRAY(textNew)); } } #ifdef VERSION_JP -#define SELECT_FILE_X 96 -#define SCORE_X 50 -#define COPY_X 115 -#define ERASE_X 180 -#define SOUNDMODE_X1 235 -#else -#define SELECT_FILE_X 93 -#define SCORE_X 52 -#define COPY_X 117 -#define ERASE_X 177 -#define SOUNDMODE_X1 sSoundTextX + #define SELECT_FILE_X 96 + #define SCORE_X 50 + #define COPY_X 115 + #define ERASE_X 180 + #define SOUNDMODE_X1 235 + #define SAVEFILE_X1 92 + #define SAVEFILE_X2 209 + #define MARIOTEXT_X1 92 + #define MARIOTEXT_X2 207 +#elif VERSION_US + #define SELECT_FILE_X 93 + #define SCORE_X 52 + #define COPY_X 117 + #define ERASE_X 177 + #define SOUNDMODE_X1 sSoundTextX + #define SAVEFILE_X1 92 + #define SAVEFILE_X2 209 + #define MARIOTEXT_X1 92 + #define MARIOTEXT_X2 207 +#elif VERSION_EU + #define SELECT_FILE_X 93 + #define SCORE_X 52 + #define COPY_X 117 + #define ERASE_X 177 + #define SOUNDMODE_X1 sSoundTextX + #define SAVEFILE_X1 97 + #define SAVEFILE_X2 204 + #define MARIOTEXT_X1 97 + #define MARIOTEXT_X2 204 #endif /** * Prints main menu strings that shows on the yellow background menu screen. + * Does not print the strings of text for EU, only the symbols. */ -static void print_main_menu_strings(void) { +void print_main_menu_strings(void) { // Print "SELECT FILE" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); +#ifndef VERSION_EU print_hud_lut_string(HUD_LUT_DIFF, SELECT_FILE_X, 35, textSelectFile); +#endif // Print file star counts - print_save_file_star_count(SAVE_FILE_A, 92, 78); - print_save_file_star_count(SAVE_FILE_B, 209, 78); - print_save_file_star_count(SAVE_FILE_C, 92, 118); - print_save_file_star_count(SAVE_FILE_D, 209, 118); + print_save_file_star_count(SAVE_FILE_A, SAVEFILE_X1, 78); + print_save_file_star_count(SAVE_FILE_B, SAVEFILE_X2, 78); + print_save_file_star_count(SAVE_FILE_C, SAVEFILE_X1, 118); + print_save_file_star_count(SAVE_FILE_D, SAVEFILE_X2, 118); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); +#ifndef VERSION_EU // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1475,17 +1790,56 @@ static void print_main_menu_strings(void) { #endif print_generic_string(SOUNDMODE_X1, 39, textSoundModes[sSoundMode]); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); +#endif // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_menu_generic_string(92, 65, textMarioA); - print_menu_generic_string(207, 65, textMarioB); - print_menu_generic_string(92, 105, textMarioC); - print_menu_generic_string(207, 105, textMarioD); + print_menu_generic_string(MARIOTEXT_X1, 65, textMarioA); + print_menu_generic_string(MARIOTEXT_X2, 65, textMarioB); + print_menu_generic_string(MARIOTEXT_X1, 105, textMarioC); + print_menu_generic_string(MARIOTEXT_X2, 105, textMarioD); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); } -#ifdef VERSION_JP +#ifdef VERSION_EU +/** + * Prints main menu strings that shows on the yellow background menu screen with language switching. + * Calls print_main_menu_strings to print the other symbols. + */ +void print_lang_strings(void) { + s16 centeredX; + + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + centeredX = get_str_x_pos_from_center_scale(0xa0, textSelectFile[sLanguageMode], 12.0f); + sCenteredX = centeredX; + print_hud_lut_string(2, centeredX, 35, textSelectFile[sLanguageMode]); + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); + + gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + centeredX = get_str_x_pos_from_center(0x4C, textScore[sLanguageMode], 10.0f); + sCenteredX = centeredX; + print_generic_string(centeredX, 0x27, textScore[sLanguageMode]); + centeredX = get_str_x_pos_from_center(0x83, textCopy[sLanguageMode], 10.0f); + sCenteredX = centeredX; + print_generic_string(centeredX, 0x27, textCopy[sLanguageMode]); + centeredX = get_str_x_pos_from_center(0xbd, textErase[sLanguageMode], 10.0f); + sCenteredX = centeredX; + print_generic_string(centeredX, 0x27, textErase[sLanguageMode]); + centeredX = get_str_x_pos_from_center(0xf5, textOption[sLanguageMode], 10.0f); + sCenteredX = centeredX; + print_generic_string(centeredX, 0x27, textOption[sLanguageMode]); + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); + + print_main_menu_strings(); +} +#endif + +#ifdef VERSION_EU +#define CHECK_FILE_X checkFileX +#define NOSAVE_DATA_X1 noSaveDataX +#elif VERSION_JP #define CHECK_FILE_X 90 #define NOSAVE_DATA_X1 90 #else @@ -1496,33 +1850,57 @@ static void print_main_menu_strings(void) { /** * Defines IDs for the top message of the score menu and displays it if the ID is called in messageID. */ -static void score_menu_display_message(s8 messageID) { +void score_menu_display_message(s8 messageID) { +#ifdef VERSION_EU + s16 checkFileX, noSaveDataX; +#endif + switch (messageID) { case SCORE_MSG_CHECK_FILE: - print_hud_lut_string_fade(HUD_LUT_DIFF, CHECK_FILE_X, 35, textCheckFile); +#ifdef VERSION_EU + checkFileX = get_str_x_pos_from_center_scale(160, LANGUAGE_ARRAY(textCheckFile), 12.0f); +#endif + print_hud_lut_string_fade(HUD_LUT_DIFF, CHECK_FILE_X, 35, LANGUAGE_ARRAY(textCheckFile)); break; case SCORE_MSG_NOSAVE_DATA: - print_generic_string_fade(NOSAVE_DATA_X1, 190, textNoSavedDataExists); +#ifdef VERSION_EU + noSaveDataX = get_str_x_pos_from_center(160, LANGUAGE_ARRAY(textNoSavedDataExists), 10.0f); +#endif + print_generic_string_fade(NOSAVE_DATA_X1, 190, LANGUAGE_ARRAY(textNoSavedDataExists)); break; } } #ifdef VERSION_JP -#define RETURN_X 45 -#define COPYFILE_X1 128 -#define ERASEFILE_X1 228 + #define RETURN_X 45 + #define COPYFILE_X1 128 + #define ERASEFILE_X1 228 +#elif VERSION_EU + #define RETURN_X centeredX + #define COPYFILE_X1 centeredX + #define ERASEFILE_X1 centeredX #else -#define RETURN_X 44 -#define COPYFILE_X1 135 -#define ERASEFILE_X1 231 + #define RETURN_X 44 + #define COPYFILE_X1 135 + #define ERASEFILE_X1 231 +#endif + +#ifdef VERSION_EU + #define FADEOUT_TIMER 35 +#else + #define FADEOUT_TIMER 20 #endif /** * Prints score menu strings that shows on the green background menu screen. */ -static void print_score_menu_strings(void) { +void print_score_menu_strings(void) { +#ifdef VERSION_EU + s16 centeredX; +#endif + // Update and print the message at the top of the menu. - if (sMainMenuTimer == 20) { + if (sMainMenuTimer == FADEOUT_TIMER) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1534,6 +1912,8 @@ static void print_score_menu_strings(void) { } // Print messageID called above score_menu_display_message(sStatusMessageID); + +#ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1542,13 +1922,28 @@ static void print_score_menu_strings(void) { print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); +#endif + // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_generic_string(RETURN_X, 35, textReturn); - print_generic_string(COPYFILE_X1, 35, textCopyFileButton); - print_generic_string(ERASEFILE_X1, 35, textEraseFileButton); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); +#endif + print_generic_string(RETURN_X, 35, LANGUAGE_ARRAY(textReturn)); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(159, textCopyFileButton[sLanguageMode], 10.0f); +#endif + print_generic_string(COPYFILE_X1, 35, LANGUAGE_ARRAY(textCopyFileButton)); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(249, textEraseFileButton[sLanguageMode], 10.0f); +#endif + print_generic_string(ERASEFILE_X1, 35, LANGUAGE_ARRAY(textEraseFileButton)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); + +#ifdef VERSION_EU + print_main_menu_strings(); +#else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1557,47 +1952,79 @@ static void print_score_menu_strings(void) { print_menu_generic_string(89, 105, textMarioC); print_menu_generic_string(211, 105, textMarioD); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); +#endif } #ifdef VERSION_JP -#define NOFILE_COPY_X 90 -#define COPY_FILE_X 90 -#define COPYIT_WHERE_X 90 -#define NOSAVE_DATA_X2 90 -#define COPYCOMPLETE_X 90 -#define SAVE_EXISTS_X1 90 + #define NOFILE_COPY_X 90 + #define COPY_FILE_X 90 + #define COPYIT_WHERE_X 90 + #define NOSAVE_DATA_X2 90 + #define COPYCOMPLETE_X 90 + #define SAVE_EXISTS_X1 90 +#elif VERSION_EU + #define NOFILE_COPY_X centeredX + #define COPY_FILE_X centeredX + #define COPYIT_WHERE_X centeredX + #define NOSAVE_DATA_X2 centeredX + #define COPYCOMPLETE_X centeredX + #define SAVE_EXISTS_X1 centeredX #else -#define NOFILE_COPY_X 119 -#define COPY_FILE_X 104 -#define COPYIT_WHERE_X 109 -#define NOSAVE_DATA_X2 101 -#define COPYCOMPLETE_X 110 -#define SAVE_EXISTS_X1 110 + #define NOFILE_COPY_X 119 + #define COPY_FILE_X 104 + #define COPYIT_WHERE_X 109 + #define NOSAVE_DATA_X2 101 + #define COPYCOMPLETE_X 110 + #define SAVE_EXISTS_X1 110 #endif /** * Defines IDs for the top message of the copy menu and displays it if the ID is called in messageID. */ -static void copy_menu_display_message(s8 messageID) { +void copy_menu_display_message(s8 messageID) { +#ifdef VERSION_EU + s16 centeredX; +#endif + switch (messageID) { case COPY_MSG_MAIN_TEXT: if (sAllFilesExist == TRUE) { - print_generic_string_fade(NOFILE_COPY_X, 190, textNoFileToCopyFrom); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textNoFileToCopyFrom[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(NOFILE_COPY_X, 190, LANGUAGE_ARRAY(textNoFileToCopyFrom)); } else { - print_hud_lut_string_fade(HUD_LUT_DIFF, COPY_FILE_X, 35, textCopyFile); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center_scale(160, textCopyFile[sLanguageMode], 12.0f); +#endif + print_hud_lut_string_fade(HUD_LUT_DIFF, COPY_FILE_X, 35, LANGUAGE_ARRAY(textCopyFile)); } break; case COPY_MSG_COPY_WHERE: - print_generic_string_fade(COPYIT_WHERE_X, 190, textCopyItToWhere); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textCopyItToWhere[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(COPYIT_WHERE_X, 190, LANGUAGE_ARRAY(textCopyItToWhere)); break; case COPY_MSG_NOSAVE_EXISTS: +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textNoSavedDataExists[sLanguageMode], 10.0f); + print_generic_string_fade(NOSAVE_DATA_X2, 190, textNoSavedDataExists[sLanguageMode]); +#else print_generic_string_fade(NOSAVE_DATA_X2, 190, textNoSavedDataExistsCopy); +#endif break; case COPY_MSG_COPY_COMPLETE: - print_generic_string_fade(COPYCOMPLETE_X, 190, textCopyCompleted); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textCopyCompleted[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(COPYCOMPLETE_X, 190, LANGUAGE_ARRAY(textCopyCompleted)); break; case COPY_MSG_SAVE_EXISTS: - print_generic_string_fade(SAVE_EXISTS_X1, 190, textSavedDataExists); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textSavedDataExists[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(SAVE_EXISTS_X1, 190, LANGUAGE_ARRAY(textSavedDataExists)); break; } } @@ -1605,10 +2032,10 @@ static void copy_menu_display_message(s8 messageID) { /** * Updates messageIDs of the copy menu depending of the copy phase value defined. */ -static void copy_menu_update_message(void) { +void copy_menu_update_message(void) { switch (sMainMenuButtons[MENU_BUTTON_COPY]->oMenuButtonActionPhase) { case COPY_PHASE_MAIN: - if (sMainMenuTimer == 20) { + if (sMainMenuTimer == FADEOUT_TIMER) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1620,7 +2047,8 @@ static void copy_menu_update_message(void) { } break; case COPY_PHASE_COPY_WHERE: - if (sMainMenuTimer == 20 && sStatusMessageID == COPY_MSG_SAVE_EXISTS) { + if (sMainMenuTimer == FADEOUT_TIMER + && sStatusMessageID == COPY_MSG_SAVE_EXISTS) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1632,7 +2060,7 @@ static void copy_menu_update_message(void) { } break; case COPY_PHASE_COPY_COMPLETE: - if (sMainMenuTimer == 20) { + if (sMainMenuTimer == FADEOUT_TIMER) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1647,21 +2075,29 @@ static void copy_menu_update_message(void) { } #ifdef VERSION_JP -#define VIEWSCORE_X1 133 -#define ERASEFILE_X2 220 + #define VIEWSCORE_X1 133 + #define ERASEFILE_X2 220 +#elif VERSION_EU + #define VIEWSCORE_X1 centeredX + #define ERASEFILE_X2 centeredX #else -#define VIEWSCORE_X1 128 -#define ERASEFILE_X2 230 + #define VIEWSCORE_X1 128 + #define ERASEFILE_X2 230 #endif /** * Prints copy menu strings that shows on the blue background menu screen. */ -static void print_copy_menu_strings(void) { +void print_copy_menu_strings(void) { +#ifdef VERSION_EU + s16 centeredX; +#endif + // Update and print the message at the top of the menu. copy_menu_update_message(); // Print messageID called inside a copy_menu_update_message case copy_menu_display_message(sStatusMessageID); +#ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1670,13 +2106,26 @@ static void print_copy_menu_strings(void) { print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); +#endif // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_generic_string(RETURN_X, 35, textReturn); - print_generic_string(VIEWSCORE_X1, 35, textViewScore); - print_generic_string(ERASEFILE_X2, 35, textEraseFileButton); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); +#endif + print_generic_string(RETURN_X, 35, LANGUAGE_ARRAY(textReturn)); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(159, textViewScore[sLanguageMode], 10.0f); +#endif + print_generic_string(VIEWSCORE_X1, 35, LANGUAGE_ARRAY(textViewScore)); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(249, textEraseFileButton[sLanguageMode], 10.0f); +#endif + print_generic_string(ERASEFILE_X2, 35, LANGUAGE_ARRAY(textEraseFileButton)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); +#ifdef VERSION_EU + print_main_menu_strings(); +#else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1685,16 +2134,17 @@ static void print_copy_menu_strings(void) { print_menu_generic_string(89, 105, textMarioC); print_menu_generic_string(211, 105, textMarioD); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); +#endif } #ifdef VERSION_JP -#define CURSOR_X 160.0f -#define MENU_ERASE_YES_MIN_X 0x91 -#define MENU_ERASE_YES_MAX_X 0xA4 + #define CURSOR_X 160.0f + #define MENU_ERASE_YES_MIN_X 0x91 + #define MENU_ERASE_YES_MAX_X 0xA4 #else -#define CURSOR_X (x + 0x46) -#define MENU_ERASE_YES_MIN_X 0x8C -#define MENU_ERASE_YES_MAX_X 0xA9 + #define CURSOR_X (x + 0x46) + #define MENU_ERASE_YES_MIN_X 0x8C + #define MENU_ERASE_YES_MAX_X 0xA9 #endif #define MENU_ERASE_YES_NO_MIN_Y 0xBF @@ -1705,7 +2155,7 @@ static void print_copy_menu_strings(void) { /** * Prints the "YES NO" prompt and checks if one of the prompts are hovered to do it's functions. */ -static void print_erase_menu_prompt(s16 x, s16 y) { +void print_erase_menu_prompt(s16 x, s16 y) { s16 colorFade = gGlobalTimer << 12; s16 cursorX = sCursorPos[0] + CURSOR_X; @@ -1754,56 +2204,81 @@ static void print_erase_menu_prompt(s16 x, s16 y) { sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE; } } + // Print "YES NO" strings gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, sYesNoColor[0], sYesNoColor[0], sYesNoColor[0], sTextBaseAlpha); - print_generic_string(x + 56, y, textYes); + print_generic_string(x + 56, y, LANGUAGE_ARRAY(textYes)); gDPSetEnvColor(gDisplayListHead++, sYesNoColor[1], sYesNoColor[1], sYesNoColor[1], sTextBaseAlpha); - print_generic_string(x + 98, y, textNo); + print_generic_string(x + 98, y, LANGUAGE_ARRAY(textNo)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } #ifdef VERSION_JP -#define ERASE_FILE_X 96 -#define NOSAVE_DATA_X3 90 -#define MARIO_ERASED_VAR 3 -#define MARIO_ERASED_X 90 -#define SAVE_EXISTS_X2 90 + #define ERASE_FILE_X 96 + #define NOSAVE_DATA_X3 90 + #define MARIO_ERASED_VAR 3 + #define MARIO_ERASED_X 90 + #define SAVE_EXISTS_X2 90 +#elif VERSION_EU + #define ERASE_FILE_X centeredX + #define NOSAVE_DATA_X3 centeredX + #define MARIO_ERASED_VAR 6 + #define MARIO_ERASED_X centeredX + #define SAVE_EXISTS_X2 centeredX #else -#define ERASE_FILE_X 98 -#define NOSAVE_DATA_X3 100 -#define MARIO_ERASED_VAR 6 -#define MARIO_ERASED_X 100 -#define SAVE_EXISTS_X2 100 + #define ERASE_FILE_X 98 + #define NOSAVE_DATA_X3 100 + #define MARIO_ERASED_VAR 6 + #define MARIO_ERASED_X 100 + #define SAVE_EXISTS_X2 100 #endif /** * Defines IDs for the top message of the erase menu and displays it if the ID is called in messageID. */ -static void erase_menu_display_message(s8 messageID) { +void erase_menu_display_message(s8 messageID) { +#ifdef VERSION_EU + s16 centeredX; +#endif + +#ifndef VERSION_EU unsigned char textEraseFile[] = { TEXT_ERASE_FILE }; unsigned char textSure[] = { TEXT_SURE }; unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS }; unsigned char textMarioAJustErased[] = { TEXT_FILE_MARIO_A_JUST_ERASED }; unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS }; +#endif switch (messageID) { case ERASE_MSG_MAIN_TEXT: - print_hud_lut_string_fade(HUD_LUT_DIFF, ERASE_FILE_X, 35, textEraseFile); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center_scale(160, textEraseFile[sLanguageMode], 12.0f); +#endif + print_hud_lut_string_fade(HUD_LUT_DIFF, ERASE_FILE_X, 35, LANGUAGE_ARRAY(textEraseFile)); break; case ERASE_MSG_PROMPT: - print_generic_string_fade(90, 190, textSure); + print_generic_string_fade(90, 190, LANGUAGE_ARRAY(textSure)); print_erase_menu_prompt(90, 190); // YES NO, has functions for it too break; case ERASE_MSG_NOSAVE_EXISTS: - print_generic_string_fade(NOSAVE_DATA_X3, 190, textNoSavedDataExists); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textNoSavedDataExists[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(NOSAVE_DATA_X3, 190, LANGUAGE_ARRAY(textNoSavedDataExists)); break; case ERASE_MSG_MARIO_ERASED: - textMarioAJustErased[MARIO_ERASED_VAR] = sSelectedFileIndex + 10; - print_generic_string_fade(MARIO_ERASED_X, 190, textMarioAJustErased); + LANGUAGE_ARRAY(textMarioAJustErased)[MARIO_ERASED_VAR] = sSelectedFileIndex + 10; +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textMarioAJustErased[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(MARIO_ERASED_X, 190, LANGUAGE_ARRAY(textMarioAJustErased)); break; case ERASE_MSG_SAVE_EXISTS: // unused - print_generic_string_fade(SAVE_EXISTS_X2, 190, textSavedDataExists); +#ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(160, textSavedDataExists[sLanguageMode], 10.0f); +#endif + print_generic_string_fade(SAVE_EXISTS_X2, 190, LANGUAGE_ARRAY(textSavedDataExists)); break; } } @@ -1811,10 +2286,11 @@ static void erase_menu_display_message(s8 messageID) { /** * Updates messageIDs of the erase menu depending of the erase phase value defined. */ -static void erase_menu_update_message(void) { +void erase_menu_update_message(void) { switch (sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonActionPhase) { case ERASE_PHASE_MAIN: - if (sMainMenuTimer == 20 && sStatusMessageID == ERASE_MSG_NOSAVE_EXISTS) { + if (sMainMenuTimer == FADEOUT_TIMER + && sStatusMessageID == ERASE_MSG_NOSAVE_EXISTS) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1835,7 +2311,7 @@ static void erase_menu_update_message(void) { } break; case ERASE_PHASE_MARIO_ERASED: - if (sMainMenuTimer == 20) { + if (sMainMenuTimer == FADEOUT_TIMER) { sFadeOutText = TRUE; } if (update_text_fade_out() == TRUE) { @@ -1860,11 +2336,18 @@ static void erase_menu_update_message(void) { /** * Prints erase menu strings that shows on the red background menu screen. */ -static void print_erase_menu_strings(void) { +void print_erase_menu_strings(void) { +#ifdef VERSION_EU + s16 centeredX; +#endif + // Update and print the message at the top of the menu. erase_menu_update_message(); + // Print messageID called inside a erase_menu_update_message case erase_menu_display_message(sStatusMessageID); + + #ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1873,13 +2356,28 @@ static void print_erase_menu_strings(void) { print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); + #endif + // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + #ifdef VERSION_EU + centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); + print_generic_string(centeredX, 35, textReturn[sLanguageMode]); + centeredX = get_str_x_pos_from_center(159, textViewScore[sLanguageMode], 10.0f); + print_generic_string(centeredX, 35, textViewScore[sLanguageMode]); + centeredX = get_str_x_pos_from_center(249, textCopyFileButton[sLanguageMode], 10.0f); + print_generic_string(centeredX, 35, textCopyFileButton[sLanguageMode]); + #else print_generic_string(RETURN_X, 35, textReturn); print_generic_string(VIEWSCORE_X2, 35, textViewScore); print_generic_string(COPYFILE_X2, 35, textCopyFileButton); + #endif gSPDisplayList(gDisplayListHead++, dl_ia_text_end); + + #ifdef VERSION_EU + print_main_menu_strings(); + #else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); @@ -1888,73 +2386,125 @@ static void print_erase_menu_strings(void) { print_menu_generic_string(89, 105, textMarioC); print_menu_generic_string(211, 105, textMarioD); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); + #endif } #ifdef VERSION_JP -#define SOUND_SELECT_X 96 -#define SOUNDMODE_X2 mode * 74 + 67 -#else -#define SOUND_SELECT_X 88 -#define SOUNDMODE_X2 textX + #define SOUND_HUD_X 96 +#elif VERSION_US + #define SOUND_HUD_X 88 #endif /** * Prints sound mode menu strings that shows on the purple background menu screen. */ -static void print_sound_mode_menu_strings(void) { +void print_sound_mode_menu_strings(void) { s32 mode; -#ifndef VERSION_JP + +#ifdef VERSION_US s16 textX; +#elif VERSION_EU + s32 textX; #endif + +#ifndef VERSION_EU unsigned char textSoundSelect[] = { TEXT_SOUND_SELECT }; +#endif + // Print "SOUND SELECT" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_hud_lut_string(HUD_LUT_DIFF, SOUND_SELECT_X, 35, textSoundSelect); + +#ifdef VERSION_EU + print_hud_lut_string(HUD_LUT_DIFF, 47, 32, textSoundSelect[sLanguageMode]); + print_hud_lut_string(HUD_LUT_DIFF, 47, 101, textLanguageSelect[sLanguageMode]); +#else + print_hud_lut_string(HUD_LUT_DIFF, SOUND_HUD_X, 35, textSoundSelect); +#endif + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); - // Print mode names + + // Print sound mode names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); +#ifdef VERSION_EU + for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) { + if (mode == sSoundMode) { + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + } else { + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); + } + print_generic_string( + get_str_x_pos_from_center(textX, textSoundModes[sLanguageMode * 3 + mode], 10.0f), + 141, textSoundModes[sLanguageMode * 3 + mode]); + } + + // EU also prints language names in this menu + for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) { + if (mode == sLanguageMode) { + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + } else { + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); + } + print_generic_string( + get_str_x_pos_from_center(textX, textLanguage[mode], 10.0f), + 72, textLanguage[mode]); + } +#else for (mode = 0; mode < 3; mode++) { if (mode == sSoundMode) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); } else { gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); } -#ifdef VERSION_US - // Mode names are centered correctly on US - textX = get_str_x_pos_from_center(mode * 74 + 87, textSoundModes[mode], 10.0f); -#endif - print_generic_string(SOUNDMODE_X2, 87, textSoundModes[mode]); + #ifdef VERSION_US + // Mode names are centered correctly on US + textX = get_str_x_pos_from_center(mode * 74 + 87, textSoundModes[mode], 10.0f); + print_generic_string(textX, 87, textSoundModes[mode]); + #elif VERSION_JP + print_generic_string(mode * 74 + 67, 87, textSoundModes[mode]); + #endif } +#endif + +#ifdef VERSION_EU + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + print_generic_string(182, 29, textReturn[sLanguageMode]); +#endif + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } -static unsigned char textStarX[] = { TEXT_STAR_X }; + +unsigned char textStarX[] = { TEXT_STAR_X }; /** * Prints castle secret stars collected in a score menu save file. */ -static void print_score_file_castle_secret_stars(s8 fileIndex, s16 x, s16 y) { +void print_score_file_castle_secret_stars(s8 fileIndex, s16 x, s16 y) { unsigned char secretStarsText[20]; // Print "[star] x" print_menu_generic_string(x, y, textStarX); // Print number of castle secret stars int_to_str(save_file_get_total_star_count(fileIndex, 15, 24), secretStarsText); +#ifdef VERSION_EU + print_menu_generic_string(x + 20, y, secretStarsText); +#else print_menu_generic_string(x + 16, y, secretStarsText); +#endif } /** * Prints course coins collected in a score menu save file. */ -static void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { +void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { unsigned char coinScoreText[20]; u8 stars = save_file_get_star_flags(fileIndex, courseIndex); unsigned char textCoinX[] = { TEXT_COIN_X }; unsigned char textStar[] = { TEXT_STAR }; #ifdef VERSION_JP -#define LENGTH 5 + #define LENGTH 5 #else -#define LENGTH 8 + #define LENGTH 8 #endif unsigned char fileNames[][LENGTH] = { { TEXT_4DASHES }, // huh? @@ -2000,7 +2550,7 @@ static void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s1 /** * Prints stars collected in a score menu save file. */ -static void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { +void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { s16 i = 0; unsigned char starScoreText[20]; // unknown length u8 stars = save_file_get_star_flags(fileIndex, courseIndex); @@ -2019,45 +2569,67 @@ static void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s1 } #ifdef VERSION_JP -#define MARIO_X 28 -#define FILE_LETTER_X 86 -#define LEVEL_NAME_X 23 -#define SECRET_STARS_X 152 -#define MYSCORE_X 237 -#define HISCORE_X 237 + #define MARIO_X 28 + #define FILE_LETTER_X 86 + #define LEVEL_NAME_X 23 + #define SECRET_STARS_X 152 + #define MYSCORE_X 237 + #define HISCORE_X 237 #else -#define MARIO_X 25 -#define FILE_LETTER_X 95 -#define LEVEL_NAME_X 29 -#define SECRET_STARS_X 171 -#define MYSCORE_X 238 -#define HISCORE_X 231 + #define MARIO_X 25 + #define FILE_LETTER_X 95 + #define LEVEL_NAME_X 29 + #define SECRET_STARS_X 171 + #define MYSCORE_X 238 + #define HISCORE_X 231 +#endif + +#ifdef VERSION_EU +#include "game/segment7.h" #endif /** * Prints save file score strings that shows when a save file is chosen inside the score menu. */ -static void print_save_file_scores(s8 fileIndex) { -// TODO: EU relocates level name table to translation segment 0x19 -#ifndef VERSION_EU - unsigned char textMario[] = { TEXT_MARIO }; -#ifdef VERSION_JP + void print_save_file_scores(s8 fileIndex) { + // TODO: This beginning decl-order stuff can be simplified by moving the + // static declarations here. +#ifdef VERSION_EU unsigned char textFileLetter[] = { TEXT_ZERO }; - void **levelNameTable = segmented_to_virtual(seg2_course_name_table); -#endif + void **levelNameTable; + switch (sLanguageMode) { + case LANGUAGE_EN: + levelNameTable = segmented_to_virtual(eu_course_strings_en_table); + break; + case LANGUAGE_FR: + levelNameTable = segmented_to_virtual(eu_course_strings_fr_table); + break; + case LANGUAGE_DE: + levelNameTable = segmented_to_virtual(eu_course_strings_de_table); + break; + } +#else + unsigned char textMario[] = { TEXT_MARIO }; + #ifdef VERSION_JP + unsigned char textFileLetter[] = { TEXT_ZERO }; + void **levelNameTable = segmented_to_virtual(seg2_course_name_table); + #endif unsigned char textHiScore[] = { TEXT_HI_SCORE }; unsigned char textMyScore[] = { TEXT_MY_SCORE }; -#ifdef VERSION_US - unsigned char textFileLetter[] = { TEXT_ZERO }; - void **levelNameTable = segmented_to_virtual(seg2_course_name_table); + #ifdef VERSION_US + unsigned char textFileLetter[] = { TEXT_ZERO }; + void **levelNameTable = segmented_to_virtual(seg2_course_name_table); + #endif #endif textFileLetter[0] = fileIndex + ASCII_TO_DIALOG('A'); // get letter of file selected + // Print file name at top gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); print_hud_lut_string(HUD_LUT_DIFF, MARIO_X, 15, textMario); print_hud_lut_string(HUD_LUT_GLOBAL, FILE_LETTER_X, 15, textFileLetter); + // Print save file star count at top print_save_file_star_count(fileIndex, 124, 15); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); @@ -2069,19 +2641,18 @@ static void print_save_file_scores(s8 fileIndex) { // PADCHAR is used to difference an x position value between // JP and US when the course number is only one digit. #ifdef VERSION_JP -#define PADCHAR 0 -#define PRINT_COURSE_SCORES(courseIndex, pad) \ - print_menu_generic_string(23 + (pad * 3), 23 + 12 * courseIndex, segmented_to_virtual(levelNameTable[courseIndex - 1])); \ - print_score_file_star_score(fileIndex, courseIndex - 1, 152, 23 + 12 * courseIndex); \ - print_score_file_course_coin_score(fileIndex, courseIndex - 1, 213, 23 + 12 * courseIndex); + #define PADCHAR 0 + #define PRINT_COURSE_SCORES(courseIndex, pad) \ + print_menu_generic_string(23 + (pad * 3), 23 + 12 * courseIndex, segmented_to_virtual(levelNameTable[courseIndex - 1])); \ + print_score_file_star_score(fileIndex, courseIndex - 1, 152, 23 + 12 * courseIndex); \ + print_score_file_course_coin_score(fileIndex, courseIndex - 1, 213, 23 + 12 * courseIndex); #else -#define PADCHAR 1 -#define PRINT_COURSE_SCORES(courseIndex, pad) \ - print_menu_generic_string(23 + (pad * 3), 23 + 12 * courseIndex, segmented_to_virtual(levelNameTable[courseIndex - 1])); \ - print_score_file_star_score(fileIndex, courseIndex - 1, 171, 23 + 12 * courseIndex); \ - print_score_file_course_coin_score(fileIndex, courseIndex - 1, 213, 23 + 12 * courseIndex); + #define PADCHAR 1 + #define PRINT_COURSE_SCORES(courseIndex, pad) \ + print_menu_generic_string(23 + (pad * 3), 23 + 12 * courseIndex, segmented_to_virtual(levelNameTable[courseIndex - 1])); \ + print_score_file_star_score(fileIndex, courseIndex - 1, 171, 23 + 12 * courseIndex); \ + print_score_file_course_coin_score(fileIndex, courseIndex - 1, 213, 23 + 12 * courseIndex); #endif - // Course values are indexed, from Bob-omb Battlefield to Rainbow Ride PRINT_COURSE_SCORES(COURSE_BOB, PADCHAR) // BOB PRINT_COURSE_SCORES(COURSE_WF, PADCHAR) // WF @@ -2098,7 +2669,6 @@ static void print_save_file_scores(s8 fileIndex) { PRINT_COURSE_SCORES(COURSE_THI, 0) // THI PRINT_COURSE_SCORES(COURSE_TTC, 0) // TTC PRINT_COURSE_SCORES(COURSE_RR, 0) // RR - #undef PRINT_COURSE_SCORES #undef PADCHAR @@ -2106,15 +2676,30 @@ static void print_save_file_scores(s8 fileIndex) { print_menu_generic_string(LEVEL_NAME_X, 215, segmented_to_virtual(levelNameTable[25])); // Print castle secret stars print_score_file_castle_secret_stars(fileIndex, SECRET_STARS_X, 215); + +#ifdef VERSION_EU + if (sScoreFileCoinScoreMode == 0) { + print_menu_generic_string( + get_str_x_pos_from_center(257, textMyScore2[sLanguageMode], 10.0f), + 24, + textMyScore2[sLanguageMode] + ); + } else { + print_menu_generic_string( + get_str_x_pos_from_center(257, textHiScore[sLanguageMode], 10.0f), + 24, + textHiScore[sLanguageMode] + ); + } +#else // Print current coin score mode if (sScoreFileCoinScoreMode == 0) { print_menu_generic_string(MYSCORE_X, 24, textMyScore); } else { print_menu_generic_string(HISCORE_X, 24, textHiScore); } - +#endif gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -#endif // !VERSION_EU } /** @@ -2128,7 +2713,12 @@ static void print_file_select_strings(void) { create_dl_ortho_matrix(); switch (sSelectedButtonID) { case MENU_BUTTON_NONE: +#ifdef VERSION_EU + // Ultimately calls print_main_menu_strings, but prints strings first. + print_lang_strings(); +#else print_main_menu_strings(); +#endif break; case MENU_BUTTON_SCORE: print_score_menu_strings(); @@ -2189,6 +2779,9 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap * either completing a course choosing "SAVE & QUIT" or having a game over. */ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { +#ifdef VERSION_EU + s8 fileNum; +#endif sSelectedButtonID = MENU_BUTTON_NONE; sCurrentMenuLevel = MENU_LAYER_MAIN; sTextBaseAlpha = 0; @@ -2225,6 +2818,18 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE; sSoundMode = save_file_get_sound_mode(); +#ifdef VERSION_EU + sLanguageMode = eu_get_language(); + for (fileNum = 0; fileNum < 4; fileNum++) { + if (save_file_exists(fileNum) == TRUE) { + sOpenLangSettings = FALSE; + break; + } else { + sOpenLangSettings = TRUE; + } + } +#endif + //! no return value #ifdef AVOID_UB return 0; diff --git a/src/menu/file_select.h b/src/menu/file_select.h index 971f440..72ab6e8 100644 --- a/src/menu/file_select.h +++ b/src/menu/file_select.h @@ -68,12 +68,23 @@ enum MenuButtonTypes { MENU_BUTTON_ERASE_MAX, // Sound Mode Menu (SOUND SELECT) + // This menu includes language settings on PAL MENU_BUTTON_SOUND_MODE = MENU_BUTTON_ERASE_MAX, - MENU_BUTTON_SOUND_MIN, - MENU_BUTTON_STEREO = MENU_BUTTON_SOUND_MIN, + MENU_BUTTON_OPTION_MIN, + MENU_BUTTON_STEREO = MENU_BUTTON_OPTION_MIN, MENU_BUTTON_MONO, MENU_BUTTON_HEADSET, - MENU_BUTTON_SOUND_MAX + +#ifdef VERSION_EU + // Language Menu + MENU_BUTTON_LANGUAGE_MIN, + MENU_BUTTON_LANGUAGE_ENGLISH = MENU_BUTTON_LANGUAGE_MIN, + MENU_BUTTON_LANGUAGE_FRENCH, + MENU_BUTTON_LANGUAGE_GERMAN, + MENU_BUTTON_LANGUAGE_RETURN, +#endif + + MENU_BUTTON_OPTION_MAX }; enum ScoreMenuMessageID { @@ -113,6 +124,12 @@ enum SoundModeMenuActionPhase { SOUND_MODE_PHASE_MAIN }; +enum Languages { + LANGUAGE_EN, + LANGUAGE_FR, + LANGUAGE_DE +}; + extern u32 gGlobalTimer; extern void beh_yellow_background_menu_init(void); diff --git a/src/menu/intro_geo.c b/src/menu/intro_geo.c index 8dc3a87..0d6850a 100644 --- a/src/menu/intro_geo.c +++ b/src/menu/intro_geo.c @@ -34,8 +34,8 @@ extern const u8 *const mario_title_texture_table[]; extern const u8 *const game_over_texture_table[]; // intro geo bss -int gGameOverFrameCounter; -int gGameOverTableIndex; +s32 gGameOverFrameCounter; +s32 gGameOverTableIndex; s16 gTitleZoomCounter; s32 gTitleFadeCounter; @@ -77,7 +77,7 @@ s8 gameOverBackgroundTable[] = { s8 gameOverBackgroundFlipOrder[] = { 0x00, 0x01, 0x02, 0x03, 0x07, 0x0B, 0x0a, 0x09, 0x08, 0x04, 0x05, 0x06 }; -Gfx *geo18_title_screen(u32 sp50, struct GraphNode *sp54, UNUSED void *context) { +Gfx *geo18_title_screen(s32 sp50, struct GraphNode *sp54, UNUSED void *context) { struct GraphNode *graphNode; // sp4c Gfx *displayList; // sp48 Gfx *displayListIter; // sp44 @@ -127,7 +127,7 @@ Gfx *geo18_title_screen(u32 sp50, struct GraphNode *sp54, UNUSED void *context) return displayList; } -Gfx *geo18_fade_transition(u32 sp40, struct GraphNode *sp44, UNUSED void *context) { +Gfx *geo18_fade_transition(s32 sp40, struct GraphNode *sp44, UNUSED void *context) { struct GraphNode *graphNode = sp44; // sp3c Gfx *displayList = NULL; // sp38 Gfx *displayListIter = NULL; // sp34 @@ -161,7 +161,7 @@ Gfx *geo18_fade_transition(u32 sp40, struct GraphNode *sp44, UNUSED void *contex return displayList; } -Gfx *intro_backdrop_one_image(u32 index, s8 *backgroundTable) { +Gfx *intro_backdrop_one_image(s32 index, s8 *backgroundTable) { Mtx *mtx; // sp5c Gfx *displayList; // sp58 Gfx *displayListIter; // sp54 @@ -184,7 +184,7 @@ Gfx *intro_backdrop_one_image(u32 index, s8 *backgroundTable) { return displayList; } -Gfx *geo18_intro_backdrop(u32 sp48, struct GraphNode *sp4c, UNUSED void *context) { +Gfx *geo18_intro_backdrop(s32 sp48, struct GraphNode *sp4c, UNUSED void *context) { struct GraphNodeMore *graphNode; // sp44 s32 index; // sp40 s8 *backgroundTable; // sp3c @@ -211,7 +211,7 @@ Gfx *geo18_intro_backdrop(u32 sp48, struct GraphNode *sp4c, UNUSED void *context return displayList; } -Gfx *geo18_game_over_tile(u32 sp40, struct GraphNode *sp44, UNUSED void *context) { +Gfx *geo18_game_over_tile(s32 sp40, struct GraphNode *sp44, UNUSED void *context) { struct GraphNode *graphNode; // sp3c Gfx *displayList; // sp38 Gfx *displayListIter; // sp34 diff --git a/src/menu/intro_geo.h b/src/menu/intro_geo.h index f455ff4..30689e0 100644 --- a/src/menu/intro_geo.h +++ b/src/menu/intro_geo.h @@ -3,10 +3,10 @@ #include "engine/graph_node.h" -Gfx *geo18_title_screen(u32 a0, struct GraphNode *a1, UNUSED void *context); -Gfx *geo18_fade_transition(u32 a0, struct GraphNode *a1, UNUSED void *context); -Gfx *intro_backdrop_one_image(u32 index, s8 *backdrop_table); -Gfx *geo18_intro_backdrop(u32 a0, struct GraphNode *a1, UNUSED void *context); -Gfx *geo18_game_over_tile(u32 a0, struct GraphNode *a1, UNUSED void *context); +Gfx *geo18_title_screen(s32 a0, struct GraphNode *a1, UNUSED void *context); +Gfx *geo18_fade_transition(s32 a0, struct GraphNode *a1, UNUSED void *context); +Gfx *intro_backdrop_one_image(s32 index, s8 *backdrop_table); +Gfx *geo18_intro_backdrop(s32 a0, struct GraphNode *a1, UNUSED void *context); +Gfx *geo18_game_over_tile(s32 a0, struct GraphNode *a1, UNUSED void *context); #endif /* _INTRO_GEO_H */ diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 78824f3..cf4f08c 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -17,6 +17,7 @@ #include "behavior_data.h" #include "text_strings.h" #include "star_select.h" +#include "game/eu_translation.h" /** * @file star_select.c @@ -201,12 +202,33 @@ void bhv_act_selector_loop(void) { /** * Print the course number selected with the wood rgba16 course texture. */ -static void print_course_number(void) { +#ifdef VERSION_EU +void print_course_number(s16 language) { +#else +void print_course_number(void) { +#endif u8 courseNum[4]; create_dl_translation_matrix(MENU_MTX_PUSH, 158.0f, 81.0f, 0.0f); gSPDisplayList(gDisplayListHead++, dl_menu_rgba16_wood_course); + +#ifdef VERSION_EU + switch (language) { + case 0: + gSPDisplayList(gDisplayListHead++, dl_menu_texture_course_upper); + break; + case 1: + gSPDisplayList(gDisplayListHead++, dl_menu_texture_niveau_upper); + break; + case 2: + gSPDisplayList(gDisplayListHead++, dl_menu_texture_kurs_upper); + break; + } + + gSPDisplayList(gDisplayListHead++, dl_menu_rgba16_wood_course_end); +#endif + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); @@ -231,21 +253,53 @@ static void print_course_number(void) { /** * Print act selector strings, some with special checks. */ -static void print_act_selector_strings(void) { -// TODO: EU relocates level and act name tables to translation segment 0x19 -#ifndef VERSION_EU +void print_act_selector_strings(void) { +#ifdef VERSION_EU + unsigned char myScore[][10] = { {TEXT_MYSCORE}, {TEXT_MY_SCORE_FR}, {TEXT_MY_SCORE_DE} }; +#else unsigned char myScore[] = { TEXT_MYSCORE }; +#endif unsigned char starNumbers[] = { TEXT_ZERO }; + +#ifdef VERSION_EU + u8 **levelNameTbl; + u8 *currLevelName; + u8 **actNameTbl; +#else u8 **levelNameTbl = segmented_to_virtual(seg2_course_name_table); u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]); u8 **actNameTbl = segmented_to_virtual(seg2_act_name_table); +#endif u8 *selectedActName; +#ifndef VERSION_EU s16 lvlNameX; s16 actNameX; +#endif s8 i; +#ifdef VERSION_EU + s16 language = eu_get_language(); +#endif create_dl_ortho_matrix(); +#ifdef VERSION_EU + switch (language) { + case 0: + actNameTbl = segmented_to_virtual(act_name_table_eu_en); + levelNameTbl = segmented_to_virtual(course_name_table_eu_en); + break; + case 1: + actNameTbl = segmented_to_virtual(act_name_table_eu_fr); + levelNameTbl = segmented_to_virtual(course_name_table_eu_fr); + break; + case 2: + actNameTbl = segmented_to_virtual(act_name_table_eu_de); + levelNameTbl = segmented_to_virtual(course_name_table_eu_de); + break; + } + currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]); +#endif + // Print the coin highscore. gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); @@ -256,33 +310,56 @@ static void print_act_selector_strings(void) { gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); // Print the "MY SCORE" text if the coin score is more than 0 if (save_file_get_course_coin_score(gCurrSaveFileNum - 1, gCurrCourseNum - 1) != 0) { +#ifdef VERSION_EU + print_generic_string(95, 118, myScore[language]); +#else print_generic_string(102, 118, myScore); +#endif } // Print the level name; add 3 to skip the number and spacing to get to the actual string to center. + // TODO: There has to be a way to merge these, but US seems to need lvlNameX and EU doesn't + // TODO: allow it to be declared. +#ifdef VERSION_EU + print_generic_string(get_str_x_pos_from_center(160, currLevelName + 3, 10.0f), 33, currLevelName + 3); +#else lvlNameX = get_str_x_pos_from_center(160, currLevelName + 3, 10.0f); print_generic_string(lvlNameX, 33, currLevelName + 3); +#endif + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); +#ifdef VERSION_EU + print_course_number((u32)language); +#else print_course_number(); +#endif gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); // Print the name of the selected act. if (sVisibleStars != 0) { selectedActName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + sSelectedActIndex]); +// TODO: Same merge issues as levelNameX above. +#ifdef VERSION_EU + print_menu_generic_string(get_str_x_pos_from_center(ACT_NAME_X, selectedActName, 8.0f), 81, selectedActName); +#else actNameX = get_str_x_pos_from_center(ACT_NAME_X, selectedActName, 8.0f); print_menu_generic_string(actNameX, 81, selectedActName); +#endif } // Print the numbers above each star. for (i = 1; i <= sVisibleStars; i++) { starNumbers[0] = i; +#ifdef VERSION_EU + print_menu_generic_string(143 - sVisibleStars * 15 + i * 30 , 38, starNumbers); +#else print_menu_generic_string(i * 34 - sVisibleStars * 17 + 139, 38, starNumbers); +#endif } gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -#endif // !VERSION_EU -} + } /** * Geo function that Print act selector strings. @@ -330,15 +407,19 @@ s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused) { s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused) { if (sActSelectorMenuTimer >= 11) { // If any of these buttons are pressed, play sound and go to course act +#ifndef VERSION_EU if ((gPlayer3Controller->buttonPressed & A_BUTTON) || (gPlayer3Controller->buttonPressed & START_BUTTON) || (gPlayer3Controller->buttonPressed & B_BUTTON)) { +#else + if ((gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | B_BUTTON | Z_TRIG))) { +#endif #ifdef VERSION_JP play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs); #else play_sound(SOUND_MENU_STAR_SOUND_LETS_A_GO, gDefaultSoundArgs); #endif - if (sInitSelectedActNum > sSelectedActIndex) { + if (sInitSelectedActNum >= sSelectedActIndex + 1) { sLoadedActNum = sSelectedActIndex + 1; } else { sLoadedActNum = sInitSelectedActNum; diff --git a/text/define_courses.inc.c b/text/define_courses.inc.c new file mode 100644 index 0000000..3a67c53 --- /dev/null +++ b/text/define_courses.inc.c @@ -0,0 +1,30 @@ +#define COURSE_ACTS(id, name, a,b,c,d,e,f) \ + static const u8 GLUE2(COURSE_TABLE, _ ## id)[] = { name }; + +#define SECRET_STAR(id, name) \ + static const u8 GLUE2(COURSE_TABLE, _ ## id)[] = { name }; + +#define CASTLE_SECRET_STARS(str) \ + static const u8 GLUE2(COURSE_TABLE, _castle_secret_stars)[] = { str }; + +#define EXTRA_TEXT(id, str) + +#include "courses.h" + +#undef COURSE_ACTS +#undef SECRET_STAR +#undef CASTLE_SECRET_STARS + +#define COURSE_ACTS(id, name, a,b,c,d,e,f) GLUE2(COURSE_TABLE, _ ## id), +#define SECRET_STAR(id, name) GLUE2(COURSE_TABLE, _ ## id), +#define CASTLE_SECRET_STARS(str) GLUE2(COURSE_TABLE, _castle_secret_stars), + +const u8 *const COURSE_TABLE[] = { +#include "courses.h" + NULL +}; + +#undef COURSE_ACTS +#undef SECRET_STAR +#undef CASTLE_SECRET_STARS + diff --git a/text/define_text.inc.c b/text/define_text.inc.c index 9011b6c..d33031f 100644 --- a/text/define_text.inc.c +++ b/text/define_text.inc.c @@ -63,36 +63,11 @@ const struct DialogEntry *const seg2_dialog_table[] = { // == courses == // (defines en_course_name_table etc.) +// The game duplicates this in levels/menu/leveldata.c in EU, so we split +// it out into a separate include file. -#define COURSE_ACTS(id, name, a,b,c,d,e,f) \ - static const u8 course_name_ ## id[] = { name }; - -#define SECRET_STAR(id, name) \ - static const u8 course_name_ ## id[] = { name }; - -#define CASTLE_SECRET_STARS(str) \ - static const u8 course_name_castle_secret_stars[] = { str }; - -#define EXTRA_TEXT(id, str) - -#include "courses.h" - -#undef COURSE_ACTS -#undef SECRET_STAR -#undef CASTLE_SECRET_STARS - -#define COURSE_ACTS(id, name, a,b,c,d,e,f) course_name_ ## id, -#define SECRET_STAR(id, name) course_name_ ## id, -#define CASTLE_SECRET_STARS(str) course_name_castle_secret_stars, - -const u8 *const seg2_course_name_table[] = { -#include "courses.h" - NULL -}; - -#undef COURSE_ACTS -#undef SECRET_STAR -#undef CASTLE_SECRET_STARS +#define COURSE_TABLE seg2_course_name_table +#include "define_courses.inc.c" // == acts == // (defines en_act_name_table etc.) diff --git a/text/us/dialogs.h b/text/us/dialogs.h index 7b9a790..34a18b2 100644 --- a/text/us/dialogs.h +++ b/text/us/dialogs.h @@ -1,5 +1,21 @@ // Parameters: dialog enum ID, (unused), lines per box, left offset, width +#ifdef VERSION_EU +#define COMRADES "friends" +#define PLASTERED "splattered" +#define SCAM_ME "cheat!\n" +#define SCRAM "get lost" +#define YOU_CANT_SWIM_IN_IT "Its too heavy to swim\nwith." +#define GIVE_UP "give up" +#else +#define COMRADES "comrades" +#define PLASTERED "plastered" +#define SCAM_ME "scam\nME. " +#define SCRAM "scram--" +#define YOU_CANT_SWIM_IN_IT "You can't swim in it." +#define GIVE_UP "give" +#endif + DEFINE_DIALOG(DIALOG_000, 1, 6, 30, 200, _("\ Wow! You're smack in the\n\ middle of the battlefield.\n\ @@ -11,7 +27,7 @@ First, talk to the\n\ Bob-omb Buddy. (Press [B]\n\ to talk.) He'll certainly\n\ help you out, and so will\n\ -his comrades in other\n\ +his " COMRADES " in other\n\ areas.\n\ To read signs, stop, face\n\ them and press [B]. Press [A]\n\ @@ -23,7 +39,7 @@ and pressing [B].")) DEFINE_DIALOG(DIALOG_001, 1, 4, 95, 200, _("\ Watch out! If you wander\n\ around here, you're liable\n\ -to be plastered by a\n\ +to be " PLASTERED " by a\n\ water bomb!\n\ Those enemy Bob-ombs love\n\ to fight, and they're\n\ @@ -107,8 +123,8 @@ Ready....\n\ //Go!////Don't Go")) DEFINE_DIALOG(DIALOG_006, 1, 3, 30, 200, _("\ -Hey!!! Don't try to scam\n\ -ME. You've gotta run\n\ +Hey!!! Don't try to " SCAM_ME +"You've gotta run\n\ the whole course.\n\ Later. Look me up when\n\ you want to race for\n\ @@ -269,7 +285,7 @@ Princess Toadstool")) DEFINE_DIALOG(DIALOG_021, 1, 5, 95, 200, _("\ Welcome.\n\ No one's home!\n\ -Now scram--\n\ +Now " SCRAM "\n\ and don't come back!\n\ Gwa ha ha!")) @@ -768,8 +784,8 @@ by enemy attacks.\n\ You don't even have to\n\ breathe while wearing it.\n\ \n\ -The only problem:\n\ -You can't swim in it.")) +The only problem:\n" +YOU_CANT_SWIM_IN_IT)) DEFINE_DIALOG(DIALOG_063, 1, 5, 30, 200, _("\ The Vanish Cap is inside\n\ @@ -1850,7 +1866,7 @@ Waaaaaaaaaaaaaaaaa!!!")) DEFINE_DIALOG(DIALOG_152, 1, 3, 30, 200, _("\ Owwch! Uncle! Uncle!\n\ -Okay, I give. Take this\n\ +Okay, I " GIVE_UP ". Take this\n\ Star!\n\ Whew! I feel better now.\n\ I don't really need it\n\ @@ -1953,6 +1969,17 @@ fast to do a Body Slide\n\ attack. To stand while\n\ sliding, press [A] or [B].")) +#ifdef VERSION_EU +#define KEEP_ON_PLAYING ".." +#else +#define KEEP_ON_PLAYING "\n\ +We want you to keep on\n\ +playing, so we have a\n\ +little something for you.\n\ +We hope that you like it!\n\ +Enjoy!!!" +#endif + DEFINE_DIALOG(DIALOG_161, 1, 4, 30, 200, _("\ Mario!!!\n\ It that really you???\n\ @@ -1973,12 +2000,8 @@ message for you.\n\ 『Thanks for playing Super\n\ Mario 64! This is the\n\ end of the game, but not\n\ -the end of the fun.\n\ -We want you to keep on\n\ -playing, so we have a\n\ -little something for you.\n\ -We hope that you like it!\n\ -Enjoy!!!』\n\ +the end of the fun." \ +KEEP_ON_PLAYING "』\n\ \n\ The Super Mario 64 Team")) diff --git a/tools/aiff_extract_codebook.c b/tools/aiff_extract_codebook.c index cdbef01..78864e3 100644 --- a/tools/aiff_extract_codebook.c +++ b/tools/aiff_extract_codebook.c @@ -169,32 +169,7 @@ int main(int argc, char **argv) fclose(ifile); if (coefTable == NULL) { - // Missing codebook, execute tabledesign instead - const char *procDirs[] = { - "/proc/self/exe", // Linux - "/proc/curproc/exe", // FreeBSD - "/proc/self/path/a.out", // Solaris - }; - char buf[0x1000 + 0x100]; - s32 bufSize = 0x1000, found = 0; - for (s32 i = 0; i < 3; i++) { - ssize_t ret = readlink(procDirs[i], buf, bufSize); - if (ret > 0 && ret < bufSize) { - found = 1; - break; - } - } - if (!found) { - // Not able to determine filename, let's guess - strcpy(buf, "./tools/"); - } - char *sep = strrchr(buf, '/'); - if (sep == NULL) { - sep = buf + strlen(buf); - } - *sep++ = '/'; - strcpy(sep, "tabledesign"); - execl(buf, "tabledesign", "-s", "1", infilename, NULL); + execl("./tools/tabledesign", "tabledesign", "-s", "1", infilename, NULL); } else { printf("%d\n%d\n", order, npredictors); for (s32 i = 0; i < npredictors; i++) { diff --git a/tools/apply_patch.sh b/tools/apply_patch.sh new file mode 100644 index 0000000..1ab8ed2 --- /dev/null +++ b/tools/apply_patch.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# apply_patch.sh - Applies an enhancement patch +# + +if [ "$#" -ne 1 ] +then + echo "Usage: $0 patch_file" + echo ' Applies a patch file to the current directory' + exit 1 +fi + +read -p "Do you wish to apply the patch '$1'? [Y/N] " response +case "$response" in + Y|y) + patch -p1 < "$1" + ;; + N|n) + echo 'Quit' + exit 1 + ;; + *) + echo "Invalid response '$response'." + exit 1 + ;; +esac + diff --git a/tools/create_patch.sh b/tools/create_patch.sh new file mode 100644 index 0000000..ea75d9c --- /dev/null +++ b/tools/create_patch.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# create_patch.sh - Creates an enhancement patch based on the current Git changes +# + +if [ "$#" -ne 1 ] +then + echo "Usage: $0 patch_file" + echo ' Creates a patch file based on the changes made to the current directory' + exit 1 +fi + +# Make sure this is a git repository +if [ ! -d .git ] +then + echo 'Error: The current directory is not a Git repository.' + exit 1 +fi + +# 'git diff' is stupid and doesn't show new untracked files, so we must add them first. +git add . +# Generate the patch. +git diff -p --staged > "$1" +# Undo the 'git add'. +git reset diff --git a/tools/libmio0.c b/tools/libmio0.c index b106b34..2c7a493 100644 --- a/tools/libmio0.c +++ b/tools/libmio0.c @@ -1,6 +1,10 @@ #include #include #include +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#endif #include "libmio0.h" #include "utils.h" @@ -291,6 +295,17 @@ int mio0_encode(const unsigned char *in, unsigned int length, unsigned char *out return bytes_written; } +static FILE *mio0_open_out_file(const char *out_file) { + if (strcmp(out_file, "-") == 0) { +#if defined(_WIN32) || defined(_WIN64) + _setmode(_fileno(stdout), _O_BINARY); +#endif + return stdout; + } else { + return fopen(out_file, "wb"); + } +} + int mio0_decode_file(const char *in_file, unsigned long offset, const char *out_file) { mio0_header_t head; @@ -339,7 +354,7 @@ int mio0_decode_file(const char *in_file, unsigned long offset, const char *out_ } // open output file - out = fopen(out_file, "wb"); + out = mio0_open_out_file(out_file); if (out == NULL) { ret_val = 4; goto free_all; @@ -352,7 +367,9 @@ int mio0_decode_file(const char *in_file, unsigned long offset, const char *out_ } // clean up - fclose(out); + if (out != stdout) { + fclose(out); + } free_all: if (out_buf) { free(out_buf); @@ -402,7 +419,7 @@ int mio0_encode_file(const char *in_file, const char *out_file) bytes_encoded = mio0_encode(in_buf, file_size, out_buf); // open output file - out = fopen(out_file, "wb"); + out = mio0_open_out_file(out_file); if (out == NULL) { ret_val = 4; goto free_all; @@ -415,7 +432,9 @@ int mio0_encode_file(const char *in_file, const char *out_file) } // clean up - fclose(out); + if (out != stdout) { + fclose(out); + } free_all: if (out_buf) { free(out_buf); @@ -459,7 +478,7 @@ static void print_usage(void) "\n" "File arguments:\n" " FILE input file\n" - " [OUTPUT] output file (default: FILE.out)\n"); + " [OUTPUT] output file (default: FILE.out), \"-\" for stdout\n"); exit(1); } @@ -473,7 +492,7 @@ static void parse_arguments(int argc, char *argv[], arg_config *config) exit(1); } for (i = 1; i < argc; i++) { - if (argv[i][0] == '-') { + if (argv[i][0] == '-' && argv[i][1] != '\0') { switch (argv[i][1]) { case 'c': config->compress = 1; diff --git a/tools/patch_libmalloc.py b/tools/patch_libmalloc.py new file mode 100644 index 0000000..582504b --- /dev/null +++ b/tools/patch_libmalloc.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Patches the malloc() function in libmalloc.so to allocate more than the +# specified number of bytes. This is needed to work around issues with the +# compiler occasionally crashing. +# +# This script replaces the "move a1, a0" (00 80 28 25) instruction with +# "addiu a1, a0, n" (24 85 nn nn), which causes the malloc function to add n to +# the size parameter that was passed in. + +import hashlib +import os.path +import sys + +# file to patch +filename = 'tools/ido5.3_compiler/lib/libmalloc.so' +# Expected (unpatched) hash of file +filehash = 'adde672b5d79b52ca3cce9a47c7cb648' +# location in file to patch +address = 0xAB4 + +# Get parameter +if len(sys.argv) != 2: + print('Usage: ' + sys.argv[0] + ' n\n where n is the number of extra bytes to allocate in malloc()') + exit(1) +n = int(sys.argv[1]) + +# Original instruction "move a1, a0" +oldinsn = bytearray([0x00, 0x80, 0x28, 0x25]) + +# New instruction "addiu a1, a0, n" +newinsn = bytearray([0x24, 0x85, (n >> 8) & 0xFF, (n & 0xFF)]) + +# Patch the file +try: + with open(filename, 'rb+') as f: + # Read file contents + contents = bytearray(f.read()) + + # Unpatch the file by restoring original instruction + contents[address:address+4] = oldinsn + + # Verify the (unpatched) hash of the file + md5 = hashlib.md5() + md5.update(contents) + if md5.hexdigest() != filehash: + print('Error: ' + filename + ' does not appear to be the correct version.') + exit(1) + + # Patch the file + if n != 0: + contents[address:address+4] = newinsn + + # Write file + f.seek(0, os.SEEK_SET) + f.write(contents) +except IOError as e: + print('Error: Could not open library file for writing: ' + str(e)) diff --git a/tools/revert_patch.sh b/tools/revert_patch.sh new file mode 100644 index 0000000..af19abd --- /dev/null +++ b/tools/revert_patch.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# revert_patch.sh - Reverts an enhancement patch +# + +if [ "$#" -ne 1 ] +then + echo "Usage: $0 patch_file" + echo ' Reverts the changes made by an enhancement patch' + exit 1 +fi + +read -p "Do you wish to revert the patch '$1'? [Y/N] " response +case "$response" in + Y|y) + patch -p1 -R < "$1" + ;; + N|n) + echo 'Quit' + exit 1 + ;; + *) + echo "Invalid response '$response'." + exit 1 + ;; +esac + + diff --git a/undefined_syms.txt b/undefined_syms.txt index a9504c9..3ecb5d4 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1,11 +1,7 @@ /* libultra OS symbols */ -osTvType = 0x80000300; -osRomBase = 0x80000308; -osResetType = 0x8000030C; -osMemSize = 0x80000318; -osAppNmiBuffer = 0x8000031C; /* boot and osException symbols */ +/* most of these should be in hardware.h */ D_80000000 = 0x80000000; D_A4000000 = 0xA4000000; D_A40004C0 = 0xA40004C0; @@ -32,6 +28,3 @@ D_B0000014 = 0xB0000014; D_C0000000 = 0xC0000000; D_C0000008 = 0xC0000008; D_C000000C = 0xC000000C; - -/* EU symbols */ -__osGetCurrFaultedThread = 0x802EF700;