diff --git a/CHANGES b/CHANGES index 67053301..4713fe88 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,49 @@ +Refresh 14 + +1.) Label whomp and some object fields (#1174) +2.) Generate MIO0 object files using binutils `ld` instead of `as` (#1173) +3.) Bowser documentation (#1166) +4.) Fix comment syntax in 00_sound_player.0 (#1172) +5.) Rename in-game menu variables (#1163) +6.) Document double red coin sound and JP sound glitch (#1170) +7.) Document different bug in external.c (#1168) +8.) updated names/types of octagonal platform data (#1164) +9.) Label a number of unnamed variables. (#1169) +10.) Document JP PU sound glitch (#1167) +11.) Set model ids to spawn_triangle_break_particles (#1165) +12.) Fix borders in clear_frame_buffer (#1162) +13.) Fix seq header files for 64-bit (#1161) +14.) Game_init.c remaining doc (#1158) +15.) Label a couple static variables in sound_init.c (#1159) +16.) Properly define dialog values (status, flags, cutscenes) (#1153) +17.) Label all of amp's assets. (#1018) +18.) Split audio/synthesis.c into Shindou/non-Shindou files (#1144) +19.) Avoid CC_CHECK warnings when using gcc (#1157) +20.) level_select_menu.c => title_screen.c (#1152) +21.) Use C preprocessor on assembly files (#1126) +22.) Replace output_level_headers.py with sed equivalent (#1109) +23.) Fix CC_CHECK warnings related to unused symbols and UB (#1155) +24.) Define remaining floor lower limit values (#1147) +25.) use r+b mode for libultra.a patch tool (#1148) +26.) Use proper values for gPrevFrameObjectCount ifs (#1146) +27.) Some minor bowser.inc.c labelling. (#1150) +28.) fix king bob-omb texture pointers (#1145) +29.) Split audio/load.c into Shindou/non-Shindou files (#1143) +30.) Small Shindou audio cleanups (#1142) +31.) Fix endians in ALSeqData (#1141) +32.) Document S8 decoder rsp operation and some more (#1139) +33.) Fix Shindou synthesis_process_note fake match (#1140) +34.) More audio documentation, for the new rsp code and other fixes (#1138) +35.) Build fixes for macOS: cpp, clang, recomp, aiff_extract_codebook (#1135) +36.) Add ENABLE_RUMBLE to config.h (#1122) +37.) Reduce recomp memory consumption by using smaller disassembly blocks (#1128) +38.) Makefile fixes (#1123) +39.) Update README.md +40.) Update README.md +41.) Reflect current decompilation status +42.) Allow both archives and ELF objects to be patched (#1127) +43.) Remove WIP mention in README for sh version. + Refresh 13 2 - No more nonmatchings remain for all builds including Shindou. diff --git a/Makefile b/Makefile index ae68f648..5373691a 100644 --- a/Makefile +++ b/Makefile @@ -304,12 +304,6 @@ else COPT := $(IDO_ROOT)/copt endif endif -# Prefer gcc's cpp if installed on the system -ifneq (,$(call find-command,cpp-10)) - CPP := cpp-10 -else - CPP := cpp -endif LD := $(CROSS)ld AR := $(CROSS)ar OBJDUMP := $(CROSS)objdump @@ -328,6 +322,15 @@ endif C_DEFINES := $(foreach d,$(DEFINES),-D$(d)) DEF_INC_CFLAGS := $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(C_DEFINES) +# Prefer clang as C preprocessor if installed on the system +ifneq (,$(call find-command,clang)) + CPP := clang + CPPFLAGS := -E -P -x c -Wno-trigraphs $(DEF_INC_CFLAGS) +else + CPP := cpp + CPPFLAGS := -P -Wno-trigraphs $(DEF_INC_CFLAGS) +endif + # Check code syntax with host compiler CC_CHECK := gcc CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(CC_CFLAGS) $(TARGET_CFLAGS) -std=gnu90 -Wall -Wextra -Wno-format-security -Wno-main -DNON_MATCHING -DAVOID_UB $(DEF_INC_CFLAGS) @@ -343,9 +346,6 @@ endif ASFLAGS := -march=vr4300 -mabi=32 $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(foreach d,$(DEFINES),--defsym $(d)) RSPASMFLAGS := $(foreach d,$(DEFINES),-definelabel $(subst =, ,$(d))) -# C preprocessor flags -CPPFLAGS := -P -Wno-trigraphs $(DEF_INC_CFLAGS) - ifeq ($(shell getconf LONG_BIT), 32) # Work around memory allocation bug in QEMU export QEMU_GUEST_BASE := 1 @@ -437,7 +437,7 @@ $(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl.inc.c $(SO $(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h ifeq ($(VERSION),sh) - $(BUILD_DIR)/src/audio/load.o: $(SOUND_BIN_DIR)/bank_sets.inc.c $(SOUND_BIN_DIR)/sequences_header.inc.c $(SOUND_BIN_DIR)/ctl_header.inc.c $(SOUND_BIN_DIR)/tbl_header.inc.c + $(BUILD_DIR)/src/audio/load_sh.o: $(SOUND_BIN_DIR)/bank_sets.inc.c $(SOUND_BIN_DIR)/sequences_header.inc.c $(SOUND_BIN_DIR)/ctl_header.inc.c $(SOUND_BIN_DIR)/tbl_header.inc.c endif $(CRASH_TEXTURE_C_FILES): TEXTURE_ENCODING := u32 @@ -521,11 +521,11 @@ $(BUILD_DIR)/levels/%/leveldata.elf: $(BUILD_DIR)/levels/%/leveldata.o $(BUILD_D $(V)$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map --just-symbols=$(BUILD_DIR)/bin/$(TEXTURE_BIN).elf -o $@ $< $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf - $(call print,Extracting compressionable data from:,$<,$@) + $(call print,Extracting compressible data from:,$<,$@) $(V)$(EXTRACT_DATA_FOR_MIO) $< $@ $(BUILD_DIR)/levels/%/leveldata.bin: $(BUILD_DIR)/levels/%/leveldata.elf - $(call print,Extracting compressionable data from:,$<,$@) + $(call print,Extracting compressible data from:,$<,$@) $(V)$(EXTRACT_DATA_FOR_MIO) $< $@ # Compress binary file @@ -536,7 +536,7 @@ $(BUILD_DIR)/%.mio0: $(BUILD_DIR)/%.bin # convert binary mio0 to object file $(BUILD_DIR)/%.mio0.o: $(BUILD_DIR)/%.mio0 $(call print,Converting MIO0 to ELF:,$<,$@) - $(V)printf ".section .data\n\n.incbin \"$<\"\n" | $(AS) $(ASFLAGS) -o $@ + $(V)$(LD) -r -b binary $< -o $@ #==============================================================================# @@ -548,7 +548,7 @@ $(BUILD_DIR)/%.table: %.aiff $(V)$(AIFF_EXTRACT_CODEBOOK) $< >$@ $(BUILD_DIR)/%.aifc: $(BUILD_DIR)/%.table %.aiff - $(call print,Encoding VADPCM:,$<,$@) + $(call print,Encoding ADPCM:,$(word 2,$^),$@) $(V)$(VADPCM_ENC) -c $^ $@ $(ENDIAN_BITWIDTH): $(TOOLS_DIR)/determine-endian-bitwidth.c @@ -556,8 +556,8 @@ $(ENDIAN_BITWIDTH): $(TOOLS_DIR)/determine-endian-bitwidth.c $(V)$(CC) -c $(CFLAGS) -o $@.dummy2 $< 2>$@.dummy1; true $(V)grep -o 'msgbegin --endian .* --bitwidth .* msgend' $@.dummy1 > $@.dummy2 $(V)head -n1 <$@.dummy2 | cut -d' ' -f2-5 > $@ - @$(RM) $@.dummy1 - @$(RM) $@.dummy2 + $(V)$(RM) $@.dummy1 + $(V)$(RM) $@.dummy2 $(SOUND_BIN_DIR)/sound_data.ctl: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) $(ENDIAN_BITWIDTH) @$(PRINT) "$(GREEN)Generating: $(BLUE)$@ $(NO_COL)\n" @@ -593,7 +593,7 @@ $(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o # Convert binary file to a comma-separated list of byte values for inclusion in C code $(BUILD_DIR)/%.inc.c: $(BUILD_DIR)/% - $(call print,Piping:,$<,$@) + $(call print,Converting to C:,$<,$@) $(V)hexdump -v -e '1/1 "0x%X,"' $< > $@ $(V)echo >> $@ @@ -624,7 +624,7 @@ $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h t # Level headers $(BUILD_DIR)/include/level_headers.h: levels/level_headers.h.in $(call print,Preprocessing level headers:,$<,$@) - $(V)$(CPP) $(CPPFLAGS) -I . levels/level_headers.h.in | $(PYTHON) $(TOOLS_DIR)/output_level_headers.py > $(BUILD_DIR)/include/level_headers.h + $(V)$(CPP) $(CPPFLAGS) -I . $< | sed -E 's|(.+)|#include "\1"|' > $@ # Run asm_processor on files that have NON_MATCHING code ifeq ($(NON_MATCHING),0) @@ -667,46 +667,36 @@ ifeq ($(COMPILER),ido) $(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2 $(BUILD_DIR)/lib/src/gu%.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/al%.o: OPT_FLAGS := -O3 - # For the asm-processor, since it doesn't support -O3. Probably not actually compiled with these flags. + ifeq ($(VERSION),sh) - $(BUILD_DIR)/lib/src/unk_shindou_file.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/func_sh_80304D20.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/contramread.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/osPfsIsPlug.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/osAiSetFrequency.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/contramwrite.o: OPT_FLAGS := -O1 - $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3 - $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3 + $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3 + $(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3 + $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 + $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/osDriveRomInit.o: OPT_FLAGS := -g endif 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/_Litob.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). # For all audio files other than external.c and port_eu.c, put string literals # in .data. (In Shindou, the port_eu.c string literals also moved to .data.) $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -use_readwrite_const $(BUILD_DIR)/src/audio/port_eu.o: OPT_FLAGS := -O2 - $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 endif ifeq ($(VERSION_JP_US),true) $(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 - $(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0 - endif - ifeq ($(VERSION_JP_US),true) + $(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -framepointer # The source-to-source optimizer copt is enabled for audio. This makes it use # acpp, which needs -Wp,-+ to handle C++-style comments. # All other files than external.c should really use copt, but only a few have # been matched so far. $(BUILD_DIR)/src/audio/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+ - $(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -sopt,-scalaroptimize=1 -Wp,-+ + $(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-scalaroptimize=1 -Wp,-+ endif + $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 # Add a target for build/eu/src/audio/*.copt to make it easier to see debug $(BUILD_DIR)/src/audio/%.acpp: src/audio/%.c @@ -720,7 +710,7 @@ endif # Assemble assembly code $(BUILD_DIR)/%.o: %.s $(call print,Assembling:,$<,$@) - $(V)$(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $< + $(V)$(CPP) $(CPPFLAGS) $< | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ # Assemble RSP assembly code $(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin: rsp/%.s @@ -736,7 +726,7 @@ $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) $(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES) @$(PRINT) "$(GREEN)Linking libultra: $(BLUE)$@ $(NO_COL)\n" $(V)$(AR) rcs -o $@ $(ULTRA_O_FILES) - $(V)$(TOOLS_DIR)/patch_libultra_math $@ + $(V)$(TOOLS_DIR)/patch_elf_32bit $@ # Link libgoddard $(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES) diff --git a/Makefile.split b/Makefile.split index 05036119..4aa49d82 100644 --- a/Makefile.split +++ b/Makefile.split @@ -161,8 +161,8 @@ endef ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),distclean) $(BUILD_DIR)/level_rules.mk: levels/level_rules.mk levels/level_defines.h - @$(PRINT) "$(GREEN)Preprocessing level make rules: $(BLUE)$@ $(NO_COL)\n" - @$(CPP) $(VERSION_CFLAGS) -I . -o $@ $< + $(call print,Preprocessing level make rules:,$<,$@) + $(V)$(CPP) $(CPPFLAGS) $(VERSION_CFLAGS) -I . -o $@ $< include $(BUILD_DIR)/level_rules.mk endif endif @@ -179,11 +179,11 @@ $(eval $(call level_rules,menu,generic)) # Menu (File Select) # Ending cake textures are generated in a special way $(BUILD_DIR)/levels/ending/cake_eu.inc.c: levels/ending/cake_eu.png - @$(PRINT) "$(GREEN)Splitting $(YELLOW)$< $(GREEN)to: $(BLUE)$@ $(NO_COL)\n" - @$(SKYCONV) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending + $(call print,Splitting:,$<,$@) + $(V)$(SKYCONV) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending $(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png - @$(PRINT) "$(GREEN)Splitting $(YELLOW)$< $(GREEN)to: $(BLUE)$@ $(NO_COL)\n" - @$(SKYCONV) --type cake --split $^ $(BUILD_DIR)/levels/ending + $(call print,Splitting:,$<,$@) + $(V)$(SKYCONV) --type cake --split $^ $(BUILD_DIR)/levels/ending # -------------------------------------- # Texture Bin Rules @@ -250,8 +250,8 @@ $(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 # -------------------------------------- $(BUILD_DIR)/bin/%_skybox.c: textures/skyboxes/%.png - @$(PRINT) "$(GREEN)Splitting $(YELLOW)$< $(GREEN)to: $(BLUE)$@ $(NO_COL)\n" - @$(SKYCONV) --type sky --split $^ $(BUILD_DIR)/bin + $(call print,Splitting:,$<,$@) + $(V)$(SKYCONV) --type sky --split $^ $(BUILD_DIR)/bin $(BUILD_DIR)/bin/%_skybox.elf: SEGMENT_ADDRESS := 0x0A000000 diff --git a/README.md b/README.md index 4cd8159a..5bd36006 100644 --- a/README.md +++ b/README.md @@ -95,10 +95,10 @@ Resulting artifacts can be found in the `build` directory. The full list of configurable variables are listed below, with the default being the first listed: -* ``VERSION``: ``us``, ``jp``, ``eu``, ``sh`` (WIP) +* ``VERSION``: ``us``, ``jp``, ``eu``, ``sh`` * ``GRUCODE``: ``f3d_old``, ``f3d_new``, ``f3dex``, ``f3dex2``, ``f3dzex`` * ``COMPARE``: ``1`` (compare ROM hash), ``0`` (do not compare ROM hash) -* ``NON_MATCHING``: Use functionally equivalent C implementations for non-matchings (Currently there aren't any non-matchings, but this will apply to Shindou and iQue). Also will avoid instances of undefined behavior. +* ``NON_MATCHING``: Use functionally equivalent C implementations for non-matchings (Currently there aren't any non-matchings, but this will apply to iQue). Also will avoid instances of undefined behavior. * ``CROSS``: Cross-compiler tool prefix (Example: ``mips64-elf-``). ### macOS @@ -111,7 +111,7 @@ With macOS, you may either use Homebrew or [Docker](#docker-installation). Install [Homebrew](https://brew.sh) and the following dependencies: ``` brew update -brew install capstone coreutils gcc make pkg-config tehzz/n64-dev/mips64-elf-binutils +brew install capstone coreutils make pkg-config tehzz/n64-dev/mips64-elf-binutils ``` #### Step 2: Copy baserom(s) for asset extraction diff --git a/actors/amp/anims/anim_0800401C.inc.c b/actors/amp/anims/animation.inc.c similarity index 87% rename from actors/amp/anims/anim_0800401C.inc.c rename to actors/amp/anims/animation.inc.c index f114dcfc..2763f4dc 100644 --- a/actors/amp/anims/anim_0800401C.inc.c +++ b/actors/amp/anims/animation.inc.c @@ -1,5 +1,4 @@ -// 0x08003E30 -static const s16 amp_seg8_animvalue_08003E30[] = { +static const s16 dAmpAnimValue[] = { 0x0000, 0x0000, 0x0D79, 0x1AF2, 0x286B, 0x35E4, 0x435D, 0x50D6, 0x5E50, 0x6BC9, 0x7942, 0x86BE, 0x9437, 0xA1B0, 0xAF2A, 0xBCA3, 0xCA1C, 0xD795, 0xE50E, 0xF287, 0x1872, 0x0000, 0x1AF2, 0x35E4, @@ -23,8 +22,7 @@ static const s16 amp_seg8_animvalue_08003E30[] = { 0xC001, 0x3FFF, }; -// 0x08003F74 -static const u16 amp_seg8_animindex_08003F74[] = { +static const u16 dAmpAnimIndex[] = { 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x00A1, 0x0001, 0x0000, 0x0013, 0x008D, 0x0001, 0x00A0, @@ -40,15 +38,14 @@ static const u16 amp_seg8_animindex_08003F74[] = { 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x004E, }; -// 0x0800401C -static const struct Animation amp_seg8_anim_0800401C = { +static const struct Animation dAmpAnimation = { 0, 0, 0, 0, 0x13, - ANIMINDEX_NUMPARTS(amp_seg8_animindex_08003F74), - amp_seg8_animvalue_08003E30, - amp_seg8_animindex_08003F74, + ANIMINDEX_NUMPARTS(dAmpAnimIndex), + dAmpAnimValue, + dAmpAnimIndex, 0, }; diff --git a/actors/amp/anims/data.inc.c b/actors/amp/anims/data.inc.c index ad33202f..ed31deb4 100644 --- a/actors/amp/anims/data.inc.c +++ b/actors/amp/anims/data.inc.c @@ -1 +1 @@ -#include "anim_0800401C.inc.c" +#include "animation.inc.c" diff --git a/actors/amp/anims/table.inc.c b/actors/amp/anims/table.inc.c index 77485e89..33e67941 100644 --- a/actors/amp/anims/table.inc.c +++ b/actors/amp/anims/table.inc.c @@ -1,4 +1,3 @@ -// 0x08004034 -const struct Animation *const amp_seg8_anims_08004034[] = { - &_seg8_anim_0800401C, +const struct Animation *const dAmpAnimsList[] = { + &dAmpAnimation, }; diff --git a/actors/amp/geo.inc.c b/actors/amp/geo.inc.c index 378a84bb..9c9e1d69 100644 --- a/actors/amp/geo.inc.c +++ b/actors/amp/geo.inc.c @@ -1,19 +1,18 @@ -// 0x0F000028 -const GeoLayout amp_geo[] = { +const GeoLayout dAmpGeo[] = { GEO_SHADOW(SHADOW_CIRCLE_4_VERTS, 0xC8, 100), GEO_OPEN_NODE(), GEO_SCALE(0x00, 16384), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), GEO_OPEN_NODE(), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002C88), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpEyeDl), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), GEO_OPEN_NODE(), GEO_SWITCH_CASE(2, geo_switch_anim_state), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpElectricityDl), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), @@ -21,7 +20,7 @@ const GeoLayout amp_geo[] = { GEO_SWITCH_CASE(2, geo_switch_anim_state), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpElectricityDl), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), @@ -29,7 +28,7 @@ const GeoLayout amp_geo[] = { GEO_SWITCH_CASE(2, geo_switch_anim_state), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpElectricityDl), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), @@ -37,16 +36,16 @@ const GeoLayout amp_geo[] = { GEO_SWITCH_CASE(2, geo_switch_anim_state), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpElectricityDl), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), - GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002D70), + GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, dAmpMouthDl), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, NULL), GEO_OPEN_NODE(), GEO_BILLBOARD(), GEO_OPEN_NODE(), - GEO_DISPLAY_LIST(LAYER_ALPHA, amp_seg8_dl_08002E58), + GEO_DISPLAY_LIST(LAYER_ALPHA, dAmpBodyDl), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), diff --git a/actors/amp/model.inc.c b/actors/amp/model.inc.c index 15745bd0..67185c8f 100644 --- a/actors/amp/model.inc.c +++ b/actors/amp/model.inc.c @@ -1,27 +1,22 @@ // Amp -// 0x08000F18 -ALIGNED8 static const Texture amp_seg8_texture_08000F18[] = { +ALIGNED8 static const Texture dAmpElectricityTexture[] = { #include "actors/amp/amp_electricity.rgba16.inc.c" }; -// 0x08001318 -ALIGNED8 static const Texture amp_seg8_texture_08001318[] = { +ALIGNED8 static const Texture dAmpEyesTexture[] = { #include "actors/amp/amp_eyes.rgba16.inc.c" }; -// 0x08001B18 -ALIGNED8 static const Texture amp_seg8_texture_08001B18[] = { +ALIGNED8 static const Texture dAmpBodyTexture[] = { #include "actors/amp/amp_body.rgba16.inc.c" }; -// 0x08002318 -ALIGNED8 static const Texture amp_seg8_texture_08002318[] = { +ALIGNED8 static const Texture dAmpMouthTexture[] = { #include "actors/amp/amp_mouth.rgba16.inc.c" }; -// 0x08002B18 -static const Vtx amp_seg8_vertex_08002B18[] = { +static const Vtx dAmpElectricityVertices[] = { {{{ 224, 0, -89}, 0, { 0, 480}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 187, 149, 0}, 0, { 223, 1078}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 224, 0, 90}, 0, { 479, 478}, {0xff, 0xff, 0xff, 0xff}}}, @@ -29,18 +24,16 @@ static const Vtx amp_seg8_vertex_08002B18[] = { {{{ 224, 0, -89}, 0, { 0, 478}, {0xff, 0xff, 0xff, 0xff}}}, }; -// 0x08002B68 - 0x08002BA0 -const Gfx amp_seg8_dl_08002B68[] = { - gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08000F18), +const Gfx dAmpElectricitySubDl[] = { + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dAmpElectricityTexture), gsDPLoadSync(), gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 16 * 32 - 1, CALC_DXT(16, G_IM_SIZ_16b_BYTES)), - gsSPVertex(amp_seg8_vertex_08002B18, 5, 0), + gsSPVertex(dAmpElectricityVertices, 5, 0), gsSP2Triangles( 0, 1, 2, 0x0, 2, 3, 4, 0x0), gsSPEndDisplayList(), }; -// 0x08002BA0 - 0x08002C10 -const Gfx amp_seg8_dl_08002BA0[] = { +const Gfx dAmpElectricityDl[] = { gsDPPipeSync(), gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA), gsSPClearGeometryMode(G_LIGHTING | G_CULL_BACK), @@ -49,7 +42,7 @@ const Gfx amp_seg8_dl_08002BA0[] = { gsDPTileSync(), gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 4, G_TX_NOLOD), gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPDisplayList(amp_seg8_dl_08002B68), + gsSPDisplayList(dAmpElectricitySubDl), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -57,26 +50,23 @@ const Gfx amp_seg8_dl_08002BA0[] = { gsSPEndDisplayList(), }; -// 0x08002C10 -static const Vtx amp_seg8_vertex_08002C10[] = { +static const Vtx dAmpEyeVertices[] = { {{{ 68, 72, 158}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -27, -71, 164}, 0, { 990, 990}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 68, -71, 158}, 0, { 990, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -27, 72, 164}, 0, { 0, 990}, {0xff, 0xff, 0xff, 0xff}}}, }; -// 0x08002C50 - 0x08002C88 -const Gfx amp_seg8_dl_08002C50[] = { - gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08001318), +const Gfx dAmpEyeSubDl[] = { + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dAmpEyesTexture), gsDPLoadSync(), gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)), - gsSPVertex(amp_seg8_vertex_08002C10, 4, 0), + gsSPVertex(dAmpEyeVertices, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0), gsSPEndDisplayList(), }; -// 0x08002C88 - 0x08002CF8 -const Gfx amp_seg8_dl_08002C88[] = { +const Gfx dAmpEyeDl[] = { gsDPPipeSync(), gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA), gsSPClearGeometryMode(G_LIGHTING), @@ -85,7 +75,7 @@ const Gfx amp_seg8_dl_08002C88[] = { gsDPTileSync(), gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD), gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPDisplayList(amp_seg8_dl_08002C50), + gsSPDisplayList(dAmpEyeSubDl), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -93,26 +83,23 @@ const Gfx amp_seg8_dl_08002C88[] = { gsSPEndDisplayList(), }; -// 0x08002CF8 -static const Vtx amp_seg8_vertex_08002CF8[] = { +static const Vtx dAmpMouthVertices[] = { {{{ -29, 72, 164}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -124, -71, 121}, 0, { 990, 990}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -29, -71, 164}, 0, { 990, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -124, 72, 121}, 0, { 0, 990}, {0xff, 0xff, 0xff, 0xff}}}, }; -// 0x08002D38 - 0x08002D70 -const Gfx amp_seg8_dl_08002D38[] = { - gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08002318), +const Gfx dAmpMouthSubDl[] = { + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dAmpMouthTexture), gsDPLoadSync(), gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)), - gsSPVertex(amp_seg8_vertex_08002CF8, 4, 0), + gsSPVertex(dAmpMouthVertices, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0), gsSPEndDisplayList(), }; -// 0x08002D70 - 0x08002DE0 -const Gfx amp_seg8_dl_08002D70[] = { +const Gfx dAmpMouthDl[] = { gsDPPipeSync(), gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA), gsSPClearGeometryMode(G_LIGHTING), @@ -121,7 +108,7 @@ const Gfx amp_seg8_dl_08002D70[] = { gsDPTileSync(), gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD), gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPDisplayList(amp_seg8_dl_08002D38), + gsSPDisplayList(dAmpMouthSubDl), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -129,26 +116,23 @@ const Gfx amp_seg8_dl_08002D70[] = { gsSPEndDisplayList(), }; -// 0x08002DE0 -static const Vtx amp_seg8_vertex_08002DE0[] = { +static const Vtx dAmpBodyVertices[] = { {{{ -39, -39, 0}, 0, { 0, 990}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 40, 40, 0}, 0, { 990, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -39, 40, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 40, -39, 0}, 0, { 990, 990}, {0xff, 0xff, 0xff, 0xff}}}, }; -// 0x08002E20 - 0x08002E58 -const Gfx amp_seg8_dl_08002E20[] = { - gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08001B18), +const Gfx dAmpBodySubDl[] = { + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dAmpBodyTexture), gsDPLoadSync(), gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)), - gsSPVertex(amp_seg8_vertex_08002DE0, 4, 0), + gsSPVertex(dAmpBodyVertices, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0), gsSPEndDisplayList(), }; -// 0x08002E58 - 0x08002EC8 -const Gfx amp_seg8_dl_08002E58[] = { +const Gfx dAmpBodyDl[] = { gsDPPipeSync(), gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA), gsSPClearGeometryMode(G_LIGHTING), @@ -157,7 +141,7 @@ const Gfx amp_seg8_dl_08002E58[] = { gsDPTileSync(), gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD), gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPDisplayList(amp_seg8_dl_08002E20), + gsSPDisplayList(dAmpBodySubDl), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), gsDPPipeSync(), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), @@ -165,15 +149,18 @@ const Gfx amp_seg8_dl_08002E58[] = { gsSPEndDisplayList(), }; -// 0x08002EC8 -static const Lights1 amp_seg8_lights_08002EC8 = gdSPDefLights1( +/** + * Everything beyond this point is unused, and seems to be an attempt at a 3D modelled + * amp. The model and attempt are overall slightly buggy, with misread lights and a slightly + * broken model. + */ + +UNUSED static const Lights1 dAmpUnused3DLights = gdSPDefLights1( 0x33, 0x3f, 0x00, 0xcf, 0xff, 0x00, 0x28, 0x28, 0x28 ); -// //! Another malformed entry: Vertex interpreted as light -// 0x08002EE0 -static const Vtx amp_seg8_vertex_08002EE0[] = { +UNUSED static const Vtx dAmpUnused3DVtx01[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 240, -160, 0}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 280, 0, -35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, @@ -182,8 +169,7 @@ static const Vtx amp_seg8_vertex_08002EE0[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0xff}}}, }; -// 0x08002F40 -static const Vtx amp_seg8_vertex_08002F40[] = { +UNUSED static const Vtx dAmpUnused3DVtx02[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 240, -160, 0}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 280, 0, -35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, @@ -192,8 +178,7 @@ static const Vtx amp_seg8_vertex_08002F40[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0xff}}}, }; -// 0x08002FA0 -static const Vtx amp_seg8_vertex_08002FA0[] = { +UNUSED static const Vtx dAmpUnused3DVtx03[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 240, -160, 0}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, {{{ 280, 0, -35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0x00}}}, @@ -202,8 +187,7 @@ static const Vtx amp_seg8_vertex_08002FA0[] = { {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0xff}}}, }; -// 0x08003000 -static const Vtx amp_seg8_vertex_08003000[] = { +UNUSED static const Vtx dAmpUnused3DVtx04[] = { {{{ 280, 0, -35}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0x00}}}, {{{ 240, 160, 0}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0x00}}}, {{{ 280, 0, 35}, 0, { 0, 0}, {0x7b, 0x1e, 0x00, 0x00}}}, @@ -212,8 +196,7 @@ static const Vtx amp_seg8_vertex_08003000[] = { {{{ 280, 0, -35}, 0, { 0, 0}, {0x7b, 0xe2, 0x00, 0xff}}}, }; -// 0x08003060 -static const Vtx amp_seg8_vertex_08003060[] = { +UNUSED static const Vtx dAmpUnused3DVtx05[] = { {{{ -184, -54, -54}, 0, { 0, 0}, {0x8b, 0xde, 0xde, 0x00}}}, {{{ -184, -76, 0}, 0, { 0, 0}, {0x8b, 0xd0, 0x00, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -232,8 +215,7 @@ static const Vtx amp_seg8_vertex_08003060[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003160 -static const Vtx amp_seg8_vertex_08003160[] = { +UNUSED static const Vtx dAmpUnused3DVtx06[] = { {{{ -184, 0, -76}, 0, { 0, 0}, {0x8b, 0x00, 0xd0, 0xff}}}, {{{ -184, -54, -54}, 0, { 0, 0}, {0x8b, 0xde, 0xde, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -252,8 +234,7 @@ static const Vtx amp_seg8_vertex_08003160[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003260 -static const Vtx amp_seg8_vertex_08003260[] = { +UNUSED static const Vtx dAmpUnused3DVtx07[] = { {{{ -184, 54, -54}, 0, { 0, 0}, {0x8b, 0x22, 0xde, 0xff}}}, {{{ -184, 0, -76}, 0, { 0, 0}, {0x8b, 0x00, 0xd0, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -272,8 +253,7 @@ static const Vtx amp_seg8_vertex_08003260[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003360 -static const Vtx amp_seg8_vertex_08003360[] = { +UNUSED static const Vtx dAmpUnused3DVtx08[] = { {{{ -184, 76, 0}, 0, { 0, 0}, {0x8b, 0x30, 0x00, 0xff}}}, {{{ -184, 54, -54}, 0, { 0, 0}, {0x8b, 0x22, 0xde, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -292,8 +272,7 @@ static const Vtx amp_seg8_vertex_08003360[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003460 -static const Vtx amp_seg8_vertex_08003460[] = { +UNUSED static const Vtx dAmpUnused3DVtx09[] = { {{{ -184, 54, 54}, 0, { 0, 0}, {0x8b, 0x22, 0x22, 0xff}}}, {{{ -184, 76, 0}, 0, { 0, 0}, {0x8b, 0x30, 0x00, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -312,8 +291,7 @@ static const Vtx amp_seg8_vertex_08003460[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003560 -static const Vtx amp_seg8_vertex_08003560[] = { +UNUSED static const Vtx dAmpUnused3DVtx10[] = { {{{ -184, 0, 76}, 0, { 0, 0}, {0x8b, 0x00, 0x30, 0xff}}}, {{{ -184, 54, 54}, 0, { 0, 0}, {0x8b, 0x22, 0x22, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -332,8 +310,7 @@ static const Vtx amp_seg8_vertex_08003560[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003660 -static const Vtx amp_seg8_vertex_08003660[] = { +UNUSED static const Vtx dAmpUnused3DVtx11[] = { {{{ -184, -54, 54}, 0, { 0, 0}, {0x8b, 0xde, 0x22, 0xff}}}, {{{ -184, 0, 76}, 0, { 0, 0}, {0x8b, 0x00, 0x30, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -352,8 +329,7 @@ static const Vtx amp_seg8_vertex_08003660[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003760 -static const Vtx amp_seg8_vertex_08003760[] = { +UNUSED static const Vtx dAmpUnused3DVtx12[] = { {{{ -184, -76, 0}, 0, { 0, 0}, {0x8b, 0xd0, 0x00, 0xff}}}, {{{ -184, -54, 54}, 0, { 0, 0}, {0x8b, 0xde, 0x22, 0x00}}}, {{{ -200, 0, 0}, 0, { 0, 0}, {0x81, 0x00, 0x00, 0x00}}}, @@ -372,70 +348,63 @@ static const Vtx amp_seg8_vertex_08003760[] = { {{{ 200, 0, 0}, 0, { 0, 0}, {0x7f, 0x00, 0x00, 0xff}}}, }; -// 0x08003860 -static const Vtx amp_seg8_vertex_08003860[] = { +UNUSED static const Vtx dAmpUnused3DVtx13[] = { {{{ -37, 90, 205}, 0, { 0, 0}, {0xcc, 0x00, 0x73, 0x00}}}, {{{ -129, 90, 163}, 0, { 0, 0}, {0xcc, 0x00, 0x73, 0x00}}}, {{{ -129, -90, 163}, 0, { 0, 0}, {0xcc, 0x00, 0x73, 0x00}}}, {{{ -37, -90, 205}, 0, { 0, 0}, {0xcc, 0x00, 0x73, 0xff}}}, }; -// 0x080038A0 -static const Vtx amp_seg8_vertex_080038A0[] = { +UNUSED static const Vtx dAmpUnused3DVtx14[] = { {{{ 112, -7, 182}, 0, { 0, 0}, {0x4c, 0xd8, 0x5c, 0x00}}}, {{{ 66, -139, 162}, 0, { 0, 0}, {0x4c, 0xd8, 0x5c, 0x00}}}, {{{ 175, -77, 98}, 0, { 0, 0}, {0x4c, 0xd8, 0x5c, 0x00}}}, }; -// 0x080038D0 -static const Vtx amp_seg8_vertex_080038D0[] = { +UNUSED static const Vtx dAmpUnused3DVtx15[] = { {{{ 63, 90, 198}, 0, { 0, 0}, {0x08, 0x00, 0x7e, 0x00}}}, {{{ -35, 90, 205}, 0, { 0, 0}, {0x08, 0x00, 0x7e, 0x00}}}, {{{ -35, -90, 205}, 0, { 0, 0}, {0x08, 0x00, 0x7e, 0x00}}}, {{{ 63, -90, 198}, 0, { 0, 0}, {0x08, 0x00, 0x7e, 0xff}}}, }; -// 0x08003910 - 0x08003940 -const Gfx amp_seg8_dl_08003910[] = { - gsSPLight(&_seg8_lights_08002EC8.l, 1), - gsSPLight(&_seg8_lights_08002EC8.a, 2), - gsSPVertex(amp_seg8_vertex_08002EE0, 6, 0), +UNUSED const Gfx dAmpUnused3DElectricDl1[] = { + gsSPLight(&dAmpUnused3DLights.l, 1), + gsSPLight(&dAmpUnused3DLights.a, 2), + gsSPVertex(dAmpUnused3DVtx01, 6, 0), gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0), gsSPEndDisplayList(), }; -// 0x08003940 - 0x08003970 -const Gfx amp_seg8_dl_08003940[] = { - gsSPLight(&_seg8_lights_08002EC8.l, 1), - gsSPLight(&_seg8_lights_08002EC8.a, 2), - gsSPVertex(amp_seg8_vertex_08002F40, 6, 0), +UNUSED const Gfx dAmpUnused3DElectricDl2[] = { + gsSPLight(&dAmpUnused3DLights.l, 1), + gsSPLight(&dAmpUnused3DLights.a, 2), + gsSPVertex(dAmpUnused3DVtx02, 6, 0), gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0), gsSPEndDisplayList(), }; -// 0x08003970 - 0x080039A0 -const Gfx amp_seg8_dl_08003970[] = { - gsSPLight(&_seg8_lights_08002EC8.l, 1), - gsSPLight(&_seg8_lights_08002EC8.a, 2), - gsSPVertex(amp_seg8_vertex_08002FA0, 6, 0), +UNUSED const Gfx dAmpUnused3DElectricDl3[] = { + gsSPLight(&dAmpUnused3DLights.l, 1), + gsSPLight(&dAmpUnused3DLights.a, 2), + gsSPVertex(dAmpUnused3DVtx03, 6, 0), gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0), gsSPEndDisplayList(), }; -// 0x080039A0 - 0x080039D0 -const Gfx amp_seg8_dl_080039A0[] = { - gsSPLight(&_seg8_lights_08002EC8.l, 1), - gsSPLight(&_seg8_lights_08002EC8.a, 2), - gsSPVertex(amp_seg8_vertex_08003000, 6, 0), +UNUSED const Gfx dAmpUnused3DElectricDl4[] = { + gsSPLight(&dAmpUnused3DLights.l, 1), + gsSPLight(&dAmpUnused3DLights.a, 2), + gsSPVertex(dAmpUnused3DVtx04, 6, 0), gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0), gsSPEndDisplayList(), }; -// 0x080039D0 - 0x08003DA8 -const Gfx amp_seg8_dl_080039D0[] = { - gsSPLight((const u8*)amp_seg8_vertex_08002EE0 + 0x8, 1), - gsSPLight((const u8*)amp_seg8_vertex_08002EE0, 2), - gsSPVertex(amp_seg8_vertex_08003060, 16, 0), +UNUSED const Gfx dAmpUnused3DModelDl[] = { + //! Vertex interpreted as light + gsSPLight((const u8*)dAmpUnused3DVtx01 + 0x8, 1), + gsSPLight((const u8*)dAmpUnused3DVtx01, 2), + gsSPVertex(dAmpUnused3DVtx05, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -443,7 +412,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003160, 16, 0), + gsSPVertex(dAmpUnused3DVtx06, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -451,7 +420,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003260, 16, 0), + gsSPVertex(dAmpUnused3DVtx07, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -459,7 +428,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003360, 16, 0), + gsSPVertex(dAmpUnused3DVtx08, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -467,7 +436,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003460, 16, 0), + gsSPVertex(dAmpUnused3DVtx09, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -475,7 +444,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003560, 16, 0), + gsSPVertex(dAmpUnused3DVtx10, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -483,7 +452,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003660, 16, 0), + gsSPVertex(dAmpUnused3DVtx11, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -491,7 +460,7 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSP2Triangles( 8, 9, 10, 0x0, 10, 9, 11, 0x0), gsSP2Triangles(10, 11, 12, 0x0, 12, 11, 13, 0x0), gsSP2Triangles(12, 13, 14, 0x0, 14, 13, 15, 0x0), - gsSPVertex(amp_seg8_vertex_08003760, 16, 0), + gsSPVertex(dAmpUnused3DVtx12, 16, 0), gsSP2Triangles( 0, 1, 2, 0x0, 1, 0, 3, 0x0), gsSP2Triangles( 1, 3, 4, 0x0, 4, 3, 5, 0x0), gsSP2Triangles( 4, 5, 6, 0x0, 6, 5, 7, 0x0), @@ -502,29 +471,29 @@ const Gfx amp_seg8_dl_080039D0[] = { gsSPEndDisplayList(), }; -// 0x08003DA8 - 0x08003DD8 -const Gfx amp_seg8_dl_08003DA8[] = { - gsSPLight((const u8*)amp_seg8_vertex_08002EE0 + 0x8, 1), - gsSPLight((const u8*)amp_seg8_vertex_08002EE0, 2), - gsSPVertex(amp_seg8_vertex_08003860, 4, 0), +UNUSED const Gfx dAmpUnused3DElectricDl5[] = { + //! Vertex interpreted as light + gsSPLight((const u8*)dAmpUnused3DVtx01 + 0x8, 1), + gsSPLight((const u8*)dAmpUnused3DVtx01, 2), + gsSPVertex(dAmpUnused3DVtx13, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), gsSPEndDisplayList(), }; -// 0x08003DD8 - 0x08003E00 -const Gfx amp_seg8_dl_08003DD8[] = { - gsSPLight((const u8*)amp_seg8_vertex_08002EE0 + 0x8, 1), - gsSPLight((const u8*)amp_seg8_vertex_08002EE0, 2), - gsSPVertex(amp_seg8_vertex_080038A0, 3, 0), +UNUSED const Gfx dAmpUnused3DElectricDl6[] = { + //! Vertex interpreted as light + gsSPLight((const u8*)dAmpUnused3DVtx01 + 0x8, 1), + gsSPLight((const u8*)dAmpUnused3DVtx01, 2), + gsSPVertex(dAmpUnused3DVtx14, 3, 0), gsSP1Triangle( 0, 1, 2, 0x0), gsSPEndDisplayList(), }; -// 0x08003E00 - 0x08003E30 -const Gfx amp_seg8_dl_08003E00[] = { - gsSPLight((const u8*)amp_seg8_vertex_08002EE0 + 0x8, 1), - gsSPLight((const u8*)amp_seg8_vertex_08002EE0, 2), - gsSPVertex(amp_seg8_vertex_080038D0, 4, 0), +UNUSED const Gfx dAmpUnused3DElectricDl7[] = { + //! Vertex interpreted as light + gsSPLight((const u8*)dAmpUnused3DVtx01 + 0x8, 1), + gsSPLight((const u8*)dAmpUnused3DVtx01, 2), + gsSPVertex(dAmpUnused3DVtx15, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), gsSPEndDisplayList(), }; diff --git a/actors/bowser/flames_data.inc.c b/actors/bowser/flames_data.inc.c new file mode 100644 index 00000000..1ba334ab --- /dev/null +++ b/actors/bowser/flames_data.inc.c @@ -0,0 +1,98 @@ +// 0x060576FC + +const s16 dBowserFlamesOrientationValues[] = { +// posX, posY, posZ, rotY, rotX + 0, 280, 80, 0x00E9, 0x1A96, + 0, 278, 83, 0x00EC, 0x1C7F, + 0, 273, 92, 0x00F9, 0x20BF, + 0, 268, 102, 0x010F, 0x2519, + 0, 263, 109, 0x011D, 0x2751, + 0, 263, 110, 0x011C, 0x2714, + 0, 265, 106, 0x0112, 0x2601, + 0, 268, 102, 0x0109, 0x24C0, + 0, 271, 96, 0x00FF, 0x2358, + 0, 274, 90, 0x00F7, 0x21CB, + 0, 277, 84, 0x00EE, 0x201C, + 0, 280, 78, 0x00E7, 0x1E4E, + 0, 284, 71, 0x00DF, 0x1C64, + 0, 288, 63, 0x00D9, 0x1A61, + 0, 291, 56, 0x00D3, 0x184B, + 0, 295, 48, 0x00CF, 0x1622, + 0, 298, 40, 0x00CA, 0x13E9, + 0, 301, 32, 0x00C7, 0x11A5, + 0, 304, 23, 0x00C4, 0x0F59, + 0, 308, 15, 0x00C1, 0x0D08, + 0, 311, 7, 0x00C0, 0x0AB5, + 0, 313, 0, 0x00C0, 0x0863, + 0, 315, -8, 0x00BF, 0x0615, + 0, 317, -15, 0x00CE, 0x03A3, + 0, 319, -22, 0x00F8, 0x00ED, + 0, 320, -29, 0x0131, 0xFFFF, + 0, 322, -36, 0x0172, 0xFFFF, + 0, 322, -40, 0x01B5, 0xFFFF, + 0, 323, -45, 0x01ED, 0xFFFF, + 0, 323, -48, 0x0213, 0xFFFF, + 0, 323, -51, 0x0219, 0xFFFF, + 0, 323, -52, 0x01F2, 0xFFFF, + 0, 323, -51, 0x018F, 0xFFFF, + 0, 323, -49, 0x00E5, 0xFFFF, + 0, 322, -45, 0xFFFF, 0xFFFF, + 0, 320, -35, 0xFFFF, 0xFFFF, + 0, 317, -23, 0xFFFF, 0xFFFF, + 0, 312, -7, 0xFFFF, 0xFFFF, + 0, 306, 11, 0xFFFF, 0xFFFF, + 0, 299, 31, 0xFFFF, 0xFFFF, + 0, 288, 51, 0xFFFF, 0xFFFF, + 0, 278, 70, 0xFFFF, 0xFFFF, + 0, 267, 89, 0xFFFF, 0xFFFF, + 0, 256, 106, 0xFFFF, 0x023A, + 0, 244, 120, 0xFFFF, 0x04AA, + 0, 236, 132, 0xFFFF, 0x069F, + 0, 229, 139, 0xFFFF, 0x0803, + 0, 224, 144, 0xFFFF, 0x08C0, + 0, 222, 147, 0xFFFF, 0x0928, + 0, 221, 148, 0xFFFF, 0x099D, + 0, 221, 149, 0xFFFF, 0x0A16, + 0, 221, 150, 0xFFFF, 0x0A8D, + 0, 221, 150, 0xFFFF, 0x0AF6, + 0, 222, 150, 0xFFFF, 0x0B4A, + 0, 222, 150, 0xFFFF, 0x0B84, + 0, 222, 149, 0x020A, 0x0BA0, + 0, 223, 149, 0x0524, 0x0B9E, + 0, 225, 148, 0x07EC, 0x0B84, + 0, 226, 147, 0x0A3F, 0x0B57, + 0, 227, 145, 0x0BFB, 0x0B1F, + 0, 228, 144, 0x0D00, 0x0AE5, + 0, 230, 142, 0x0D6F, 0x0AA0, + 0, 232, 140, 0x0D8B, 0x0A48, + 0, 233, 138, 0x0D5D, 0x09DE, + 0, 236, 136, 0x0CED, 0x096A, + 0, 238, 134, 0x0C49, 0x08EA, + 0, 239, 132, 0x0B76, 0x0863, + 0, 241, 130, 0x0A80, 0x07D9, + 0, 244, 128, 0x0970, 0x074E, + 0, 246, 125, 0x084E, 0x06C7, + 0, 248, 122, 0x0723, 0x0649, + 0, 251, 120, 0x05F8, 0x05D7, + 0, 253, 117, 0x04D6, 0x0579, + 0, 254, 114, 0x03C3, 0x0532, + 0, 256, 111, 0x02C9, 0x0509, + 0, 259, 108, 0x01F0, 0x0504, + 0, 261, 105, 0x0141, 0x0525, + 0, 262, 103, 0x00C3, 0x0572, + 0, 264, 100, 0x006E, 0x0619, + 0, 267, 97, 0x0032, 0x0734, + 0, 268, 95, 0x000C, 0x08AF, + 0, 269, 93, 0xFFFF, 0x0A74, + 0, 272, 90, 0xFFFF, 0x0C70, + 0, 273, 88, 0xFFFF, 0x0E8E, + 0, 274, 86, 0x0014, 0x10B6, + 0, 275, 84, 0x0032, 0x12DA, + 0, 277, 82, 0x0056, 0x14E1, + 0, 277, 82, 0x007E, 0x16B9, + 0, 278, 80, 0x00A4, 0x184B, + 0, 278, 80, 0x00C6, 0x1983, + 0, 279, 80, 0x00DF, 0x1A4D, + 0, 280, 80, 0x00E9, 0x1A96, + 0, 0, 0, 0x0000, 0x0000, +}; diff --git a/actors/bowser/flames_pos.inc.c b/actors/bowser/flames_pos.inc.c deleted file mode 100644 index 25bddc3e..00000000 --- a/actors/bowser/flames_pos.inc.c +++ /dev/null @@ -1,96 +0,0 @@ -// 0x060576FC -const s16 bowser_seg6_unkmoveshorts_060576FC[] = { - 0x0000, 0x0118, 0x0050, 0x00E9, 0x1A96, - 0x0000, 0x0116, 0x0053, 0x00EC, 0x1C7F, - 0x0000, 0x0111, 0x005C, 0x00F9, 0x20BF, - 0x0000, 0x010C, 0x0066, 0x010F, 0x2519, - 0x0000, 0x0107, 0x006D, 0x011D, 0x2751, - 0x0000, 0x0107, 0x006E, 0x011C, 0x2714, - 0x0000, 0x0109, 0x006A, 0x0112, 0x2601, - 0x0000, 0x010C, 0x0066, 0x0109, 0x24C0, - 0x0000, 0x010F, 0x0060, 0x00FF, 0x2358, - 0x0000, 0x0112, 0x005A, 0x00F7, 0x21CB, - 0x0000, 0x0115, 0x0054, 0x00EE, 0x201C, - 0x0000, 0x0118, 0x004E, 0x00E7, 0x1E4E, - 0x0000, 0x011C, 0x0047, 0x00DF, 0x1C64, - 0x0000, 0x0120, 0x003F, 0x00D9, 0x1A61, - 0x0000, 0x0123, 0x0038, 0x00D3, 0x184B, - 0x0000, 0x0127, 0x0030, 0x00CF, 0x1622, - 0x0000, 0x012A, 0x0028, 0x00CA, 0x13E9, - 0x0000, 0x012D, 0x0020, 0x00C7, 0x11A5, - 0x0000, 0x0130, 0x0017, 0x00C4, 0x0F59, - 0x0000, 0x0134, 0x000F, 0x00C1, 0x0D08, - 0x0000, 0x0137, 0x0007, 0x00C0, 0x0AB5, - 0x0000, 0x0139, 0x0000, 0x00C0, 0x0863, - 0x0000, 0x013B, 0xFFF8, 0x00BF, 0x0615, - 0x0000, 0x013D, 0xFFF1, 0x00CE, 0x03A3, - 0x0000, 0x013F, 0xFFEA, 0x00F8, 0x00ED, - 0x0000, 0x0140, 0xFFE3, 0x0131, 0xFFFF, - 0x0000, 0x0142, 0xFFDC, 0x0172, 0xFFFF, - 0x0000, 0x0142, 0xFFD8, 0x01B5, 0xFFFF, - 0x0000, 0x0143, 0xFFD3, 0x01ED, 0xFFFF, - 0x0000, 0x0143, 0xFFD0, 0x0213, 0xFFFF, - 0x0000, 0x0143, 0xFFCD, 0x0219, 0xFFFF, - 0x0000, 0x0143, 0xFFCC, 0x01F2, 0xFFFF, - 0x0000, 0x0143, 0xFFCD, 0x018F, 0xFFFF, - 0x0000, 0x0143, 0xFFCF, 0x00E5, 0xFFFF, - 0x0000, 0x0142, 0xFFD3, 0xFFFF, 0xFFFF, - 0x0000, 0x0140, 0xFFDD, 0xFFFF, 0xFFFF, - 0x0000, 0x013D, 0xFFE9, 0xFFFF, 0xFFFF, - 0x0000, 0x0138, 0xFFF9, 0xFFFF, 0xFFFF, - 0x0000, 0x0132, 0x000B, 0xFFFF, 0xFFFF, - 0x0000, 0x012B, 0x001F, 0xFFFF, 0xFFFF, - 0x0000, 0x0120, 0x0033, 0xFFFF, 0xFFFF, - 0x0000, 0x0116, 0x0046, 0xFFFF, 0xFFFF, - 0x0000, 0x010B, 0x0059, 0xFFFF, 0xFFFF, - 0x0000, 0x0100, 0x006A, 0xFFFF, 0x023A, - 0x0000, 0x00F4, 0x0078, 0xFFFF, 0x04AA, - 0x0000, 0x00EC, 0x0084, 0xFFFF, 0x069F, - 0x0000, 0x00E5, 0x008B, 0xFFFF, 0x0803, - 0x0000, 0x00E0, 0x0090, 0xFFFF, 0x08C0, - 0x0000, 0x00DE, 0x0093, 0xFFFF, 0x0928, - 0x0000, 0x00DD, 0x0094, 0xFFFF, 0x099D, - 0x0000, 0x00DD, 0x0095, 0xFFFF, 0x0A16, - 0x0000, 0x00DD, 0x0096, 0xFFFF, 0x0A8D, - 0x0000, 0x00DD, 0x0096, 0xFFFF, 0x0AF6, - 0x0000, 0x00DE, 0x0096, 0xFFFF, 0x0B4A, - 0x0000, 0x00DE, 0x0096, 0xFFFF, 0x0B84, - 0x0000, 0x00DE, 0x0095, 0x020A, 0x0BA0, - 0x0000, 0x00DF, 0x0095, 0x0524, 0x0B9E, - 0x0000, 0x00E1, 0x0094, 0x07EC, 0x0B84, - 0x0000, 0x00E2, 0x0093, 0x0A3F, 0x0B57, - 0x0000, 0x00E3, 0x0091, 0x0BFB, 0x0B1F, - 0x0000, 0x00E4, 0x0090, 0x0D00, 0x0AE5, - 0x0000, 0x00E6, 0x008E, 0x0D6F, 0x0AA0, - 0x0000, 0x00E8, 0x008C, 0x0D8B, 0x0A48, - 0x0000, 0x00E9, 0x008A, 0x0D5D, 0x09DE, - 0x0000, 0x00EC, 0x0088, 0x0CED, 0x096A, - 0x0000, 0x00EE, 0x0086, 0x0C49, 0x08EA, - 0x0000, 0x00EF, 0x0084, 0x0B76, 0x0863, - 0x0000, 0x00F1, 0x0082, 0x0A80, 0x07D9, - 0x0000, 0x00F4, 0x0080, 0x0970, 0x074E, - 0x0000, 0x00F6, 0x007D, 0x084E, 0x06C7, - 0x0000, 0x00F8, 0x007A, 0x0723, 0x0649, - 0x0000, 0x00FB, 0x0078, 0x05F8, 0x05D7, - 0x0000, 0x00FD, 0x0075, 0x04D6, 0x0579, - 0x0000, 0x00FE, 0x0072, 0x03C3, 0x0532, - 0x0000, 0x0100, 0x006F, 0x02C9, 0x0509, - 0x0000, 0x0103, 0x006C, 0x01F0, 0x0504, - 0x0000, 0x0105, 0x0069, 0x0141, 0x0525, - 0x0000, 0x0106, 0x0067, 0x00C3, 0x0572, - 0x0000, 0x0108, 0x0064, 0x006E, 0x0619, - 0x0000, 0x010B, 0x0061, 0x0032, 0x0734, - 0x0000, 0x010C, 0x005F, 0x000C, 0x08AF, - 0x0000, 0x010D, 0x005D, 0xFFFF, 0x0A74, - 0x0000, 0x0110, 0x005A, 0xFFFF, 0x0C70, - 0x0000, 0x0111, 0x0058, 0xFFFF, 0x0E8E, - 0x0000, 0x0112, 0x0056, 0x0014, 0x10B6, - 0x0000, 0x0113, 0x0054, 0x0032, 0x12DA, - 0x0000, 0x0115, 0x0052, 0x0056, 0x14E1, - 0x0000, 0x0115, 0x0052, 0x007E, 0x16B9, - 0x0000, 0x0116, 0x0050, 0x00A4, 0x184B, - 0x0000, 0x0116, 0x0050, 0x00C6, 0x1983, - 0x0000, 0x0117, 0x0050, 0x00DF, 0x1A4D, - 0x0000, 0x0118, 0x0050, 0x00E9, 0x1A96, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; diff --git a/actors/bowser/geo.inc.c b/actors/bowser/geo.inc.c index 06d2f13a..b59e23a6 100644 --- a/actors/bowser/geo.inc.c +++ b/actors/bowser/geo.inc.c @@ -110,10 +110,10 @@ const GeoLayout bowser_geo_0000D8[] = { const GeoLayout bowser_geo_000424[] = { GEO_SHADOW(SHADOW_CIRCLE_9_VERTS, 0x9B, 400), GEO_OPEN_NODE(), -#ifdef VERSION_JP - GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040210), -#else +#if BUGFIX_BOWSER_FADING_OUT GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040358), +#else + GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040210), #endif GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, -89, -2, -18, NULL), @@ -200,10 +200,10 @@ const GeoLayout bowser_geo_000424[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603A4E8), GEO_CLOSE_NODE(), -#ifdef VERSION_JP - GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B8D0), -#else +#if BUGFIX_BOWSER_FADING_OUT GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B948), +#else + GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B8D0), #endif GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), @@ -226,10 +226,10 @@ const GeoLayout bowser_geo_000424[] = { const GeoLayout bowser_geo_000770[] = { GEO_NODE_START(), GEO_OPEN_NODE(), -#ifdef VERSION_JP - GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040210), -#else +#if BUGFIX_BOWSER_FADING_OUT GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040358), +#else + GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_06040210), #endif GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, -89, -2, -18, NULL), @@ -316,10 +316,10 @@ const GeoLayout bowser_geo_000770[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603A4E8), GEO_CLOSE_NODE(), -#ifdef VERSION_JP - GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B8D0), -#else +#if BUGFIX_BOWSER_FADING_OUT GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B948), +#else + GEO_ANIMATED_PART(LAYER_TRANSPARENT, 0, 0, 0, bowser_seg6_dl_0603B8D0), #endif GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), @@ -341,7 +341,7 @@ const GeoLayout bowser_geo_000770[] = { #ifndef VERSION_JP // 0x0D000AB8 const GeoLayout bowser_shadow_geo[] = { - GEO_SHADOW(0x00, 0x9B, 400), + GEO_SHADOW(SHADOW_CIRCLE_9_VERTS, 0x9B, 400), GEO_RETURN(), }; #endif @@ -351,11 +351,10 @@ const GeoLayout bowser_geo[] = { GEO_NODE_START(), GEO_OPEN_NODE(), GEO_ASM(0, geo_update_layer_transparency), -#ifdef VERSION_JP - GEO_SWITCH_CASE(2, geo_switch_anim_state), -#endif #ifndef VERSION_JP GEO_SWITCH_CASE(3, geo_switch_anim_state), +#else + GEO_SWITCH_CASE(2, geo_switch_anim_state), #endif GEO_OPEN_NODE(), GEO_NODE_START(), @@ -384,19 +383,16 @@ const GeoLayout bowser_geo[] = { }; // 0x0D000B18 / 0B40 -const GeoLayout bowser2_geo[] = { +const GeoLayout bowser_geo_no_shadow[] = { GEO_NODE_START(), GEO_OPEN_NODE(), GEO_ASM(0, geo_update_layer_transparency), - -#ifdef VERSION_JP - GEO_SWITCH_CASE(2, geo_switch_anim_state), -#endif #ifndef VERSION_JP GEO_SWITCH_CASE(3, geo_switch_anim_state), +#else + GEO_SWITCH_CASE(2, geo_switch_anim_state), #endif GEO_OPEN_NODE(), - GEO_NODE_START(), GEO_OPEN_NODE(), GEO_ASM(0, geo_bits_bowser_coloring), diff --git a/actors/bowser/model.inc.c b/actors/bowser/model.inc.c index 69a0b083..24ba7c59 100644 --- a/actors/bowser/model.inc.c +++ b/actors/bowser/model.inc.c @@ -1184,7 +1184,7 @@ const Gfx bowser_seg6_dl_0603B8D0[] = { gsSPEndDisplayList(), }; -#ifndef VERSION_JP +#if BUGFIX_BOWSER_FADING_OUT // 0x0603B948 - 0x0603B9C8 const Gfx bowser_seg6_dl_0603B948[] = { gsDPPipeSync(), @@ -2870,7 +2870,7 @@ const Gfx bowser_seg6_dl_06040210[] = { gsSPEndDisplayList(), }; -#ifndef VERSION_JP +#if BUGFIX_BOWSER_FADING_OUT // 0x06040358 - 0x06040428 const Gfx bowser_seg6_dl_06040358[] = { gsDPPipeSync(), diff --git a/actors/common0.h b/actors/common0.h index f4a791db..53c7f396 100644 --- a/actors/common0.h +++ b/actors/common0.h @@ -4,24 +4,12 @@ #include "types.h" // amp -extern const GeoLayout amp_geo[]; -extern const Gfx amp_seg8_dl_08002B68[]; -extern const Gfx amp_seg8_dl_08002BA0[]; -extern const Gfx amp_seg8_dl_08002C50[]; -extern const Gfx amp_seg8_dl_08002C88[]; -extern const Gfx amp_seg8_dl_08002D38[]; -extern const Gfx amp_seg8_dl_08002D70[]; -extern const Gfx amp_seg8_dl_08002E20[]; -extern const Gfx amp_seg8_dl_08002E58[]; -extern const Gfx amp_seg8_dl_08003910[]; -extern const Gfx amp_seg8_dl_08003940[]; -extern const Gfx amp_seg8_dl_08003970[]; -extern const Gfx amp_seg8_dl_080039A0[]; -extern const Gfx amp_seg8_dl_080039D0[]; -extern const Gfx amp_seg8_dl_08003DA8[]; -extern const Gfx amp_seg8_dl_08003DD8[]; -extern const Gfx amp_seg8_dl_08003E00[]; -extern const struct Animation *const amp_seg8_anims_08004034[]; +extern const GeoLayout dAmpGeo[]; +extern const Gfx dAmpElectricityDl[]; +extern const Gfx dAmpEyeDl[]; +extern const Gfx dAmpMouthDl[]; +extern const Gfx dAmpBodyDl[]; +extern const struct Animation *const dAmpAnimsList[]; // blue_coin_switch extern const GeoLayout blue_coin_switch_geo[]; diff --git a/actors/group12.c b/actors/group12.c index b6ed0af7..ece6a0bd 100644 --- a/actors/group12.c +++ b/actors/group12.c @@ -18,7 +18,7 @@ UNUSED static const u64 binid_2 = 2; #include "bowser/model.inc.c" #include "bowser/anims/data.inc.c" #include "bowser/anims/table.inc.c" -#include "bowser/flames_pos.inc.c" +#include "bowser/flames_data.inc.c" UNUSED static const u64 binid_3 = 3; #include "bomb/model.inc.c" diff --git a/actors/group12.h b/actors/group12.h index 2a73af21..02258c86 100644 --- a/actors/group12.h +++ b/actors/group12.h @@ -17,7 +17,7 @@ extern const GeoLayout bowser_geo_000424[]; extern const GeoLayout bowser_geo_000770[]; extern const GeoLayout bowser_shadow_geo[]; extern const GeoLayout bowser_geo[]; -extern const GeoLayout bowser2_geo[]; +extern const GeoLayout bowser_geo_no_shadow[]; extern const Gfx bowser_seg6_dl_06039110[]; extern const Gfx bowser_seg6_dl_060391C8[]; extern const Gfx bowser_seg6_dl_06039260[]; @@ -90,7 +90,7 @@ extern const Gfx bowser_seg6_dl_06043548[]; extern const Gfx bowser_seg6_dl_06043648[]; extern const Gfx bowser_seg6_dl_06043698[]; extern const struct Animation *const bowser_seg6_anims_06057690[]; -extern const s16 bowser_seg6_unkmoveshorts_060576FC[]; +extern const s16 dBowserFlamesOrientationValues[]; // bowser_flame extern const GeoLayout bowser_flames_geo[]; diff --git a/actors/king_bobomb/model.inc.c b/actors/king_bobomb/model.inc.c index 3065684c..fb933b86 100644 --- a/actors/king_bobomb/model.inc.c +++ b/actors/king_bobomb/model.inc.c @@ -55,6 +55,11 @@ ALIGNED8 static const Texture king_bobomb_seg5_texture_05004878[] = { #include "actors/king_bobomb/king_bob-omb_eyes.rgba16.inc.c" }; +// 0x05005078 - Unused +ALIGNED8 static const Texture king_bobomb_seg5_texture_05005078[] = { +#include "actors/king_bobomb/king_bob-omb_eyes_blink.rgba16.inc.c" +}; + // 0x05005878 ALIGNED8 static const Texture king_bobomb_seg5_texture_05005878[] = { #include "actors/king_bobomb/king_bob-omb_hand.rgba16.inc.c" diff --git a/asm/boot.s b/asm/boot.s index be12ff0a..17a0ace7 100644 --- a/asm/boot.s +++ b/asm/boot.s @@ -1,21 +1,21 @@ -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +// assembler directives +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" -# 0xA0000000-0xBFFFFFFF: KSEG1 direct map non-cache mirror of 0x00000000 -# 0xA4000000-0xA4000FFF: RSP DMEM +// 0xA0000000-0xBFFFFFFF: KSEG1 direct map non-cache mirror of 0x00000000 +// 0xA4000000-0xA4000FFF: RSP DMEM -# 0xA4000000-0xA400003F: ROM header +// 0xA4000000-0xA400003F: ROM header .section .text, "ax" -# 0xA4000040-0xA4000B6F: IPL3 +// 0xA4000040-0xA4000B6F: IPL3 -# IPL3 entry point jumped to from IPL2 -glabel ipl3_entry # 0xA4000040 +// IPL3 entry point jumped to from IPL2 +glabel ipl3_entry // 0xA4000040 mtc0 $zero, $13 mtc0 $zero, $9 mtc0 $zero, $11 @@ -797,7 +797,7 @@ func_A4000AD0: nop nop -# 0xA4000B70-0xA4000FFF: IPL3 Font +// 0xA4000B70-0xA4000FFF: IPL3 Font glabel ipl3_font .incbin "textures/ipl3_raw/ipl3_font_00.ia1" .incbin "textures/ipl3_raw/ipl3_font_01.ia1" diff --git a/asm/decompress.s b/asm/decompress.s index 1399179d..4c1733e4 100644 --- a/asm/decompress.s +++ b/asm/decompress.s @@ -1,61 +1,17 @@ -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +// assembler directives +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" -# This file is handwritten. +// This file is handwritten. glabel decompress -.if VERSION_SH == 1 - lw $a3, 8($a0) - lw $t9, 0xc($a0) - lw $t8, 4($a0) - add $a3, $a3, $a0 - add $t9, $t9, $a0 - move $a2, $zero - addi $a0, $a0, 0x10 - add $t8, $t8, $a1 -.L802772C0: - bnel $a2, $zero, .L802772D8 - slt $t1, $t0, $zero - lw $t0, ($a0) - li $a2, 32 - addi $a0, $a0, 4 - slt $t1, $t0, $zero -.L802772D8: - beql $t1, $zero, .L802772F8 - lhu $t2, ($a3) - lb $t2, ($t9) - addi $t9, $t9, 1 - addi $a1, $a1, 1 - b .L80277324 - sb $t2, -1($a1) - lhu $t2, ($a3) -.L802772F8: - addi $a3, $a3, 2 - srl $t3, $t2, 0xc - andi $t2, $t2, 0xfff - sub $t1, $a1, $t2 - addi $t3, $t3, 3 -.L8027730C: - lb $t2, -1($t1) - addi $t3, $t3, -1 - addi $t1, $t1, 1 - addi $a1, $a1, 1 - bnez $t3, .L8027730C - sb $t2, -1($a1) -.L80277324: - sll $t0, $t0, 1 - bne $a1, $t8, .L802772C0 - addi $a2, $a2, -1 - jr $ra - nop -.elseif VERSION_EU == 1 +#if defined(VERSION_EU) || defined(VERSION_SH) lw $a3, 8($a0) lw $t9, 0xc($a0) lw $t8, 4($a0) @@ -99,7 +55,7 @@ glabel decompress addi $a2, $a2, -1 jr $ra nop -.else +#else lw $t8, 4($a0) lw $a3, 8($a0) lw $t9, 0xc($a0) @@ -146,4 +102,4 @@ glabel decompress nop jr $ra nop -.endif +#endif diff --git a/asm/entry.s b/asm/entry.s index 755e1b4b..fa95d8e1 100644 --- a/asm/entry.s +++ b/asm/entry.s @@ -1,29 +1,29 @@ -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +// assembler directives +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" glabel entry_point - lui $t0, %hi(_mainSegmentNoloadStart) # $t0, 0x8034 - lui $t1, %lo(_mainSegmentNoloadSizeHi) # lui $t1, 2 - addiu $t0, %lo(_mainSegmentNoloadStart) # addiu $t0, $t0, -0x6df0 - ori $t1, %lo(_mainSegmentNoloadSizeLo) # ori $t1, $t1, 0xcee0 + lui $t0, %hi(_mainSegmentNoloadStart) // $t0, 0x8034 + lui $t1, %lo(_mainSegmentNoloadSizeHi) // lui $t1, 2 + addiu $t0, %lo(_mainSegmentNoloadStart) // addiu $t0, $t0, -0x6df0 + ori $t1, %lo(_mainSegmentNoloadSizeLo) // ori $t1, $t1, 0xcee0 .L80246010: addi $t1, $t1, -8 sw $zero, ($t0) sw $zero, 4($t0) bnez $t1, .L80246010 addi $t0, $t0, 8 - lui $t2, %hi(main_func) # $t2, 0x8024 - lui $sp, %hi(gIdleThreadStack) # $sp, 0x8020 - addiu $t2, %lo(main_func) # addiu $t2, $t2, 0x6dc4 + lui $t2, %hi(main_func) // $t2, 0x8024 + lui $sp, %hi(gIdleThreadStack) // $sp, 0x8020 + addiu $t2, %lo(main_func) // addiu $t2, $t2, 0x6dc4 jr $t2 - addiu $sp, %lo(gIdleThreadStack) # addiu $sp, $sp, 0xa00 + addiu $sp, %lo(gIdleThreadStack) // addiu $sp, $sp, 0xa00 nop nop nop diff --git a/asm/rom_header.s b/asm/rom_header.s index c056acdb..af8b9afd 100644 --- a/asm/rom_header.s +++ b/asm/rom_header.s @@ -8,38 +8,39 @@ .word entry_point /* Entrypoint */ /* Revision */ -.if VERSION_SH == 1 +#ifdef VERSION_SH .word 0x00001448 -.elseif VERSION_EU == 1 +#elif defined(VERSION_EU) .word 0x00001446 -.else /* NTSC-U and NTSC-J 1.0 */ +#else /* NTSC-U and NTSC-J 1.0 */ .word 0x00001444 -.endif +#endif .word 0x4EAA3D0E /* Checksum 1 */ .word 0x74757C24 /* Checksum 2 */ .word 0x00000000 /* Unknown */ .word 0x00000000 /* Unknown */ -.if VERSION_SH == 1 +#ifdef VERSION_SH .ascii "SUPERMARIO64 " /* Internal ROM name */ -.else +#else .ascii "SUPER MARIO 64 " /* Internal ROM name */ -.endif +#endif .word 0x00000000 /* Unknown */ .word 0x0000004E /* Cartridge */ .ascii "SM" /* Cartridge ID */ /* Region */ -.if VERSION_US == 1 - .ascii "E" /* NTSC-U (North America) */ -.elseif (VERSION_JP == 1 || VERSION_SH == 1) - .ascii "J" /* NTSC-J (Japan) */ -.else +#ifdef VERSION_EU .ascii "P" /* PAL (Europe) */ -.endif +#elif defined(VERSION_US) + .ascii "E" /* NTSC-U (North America) */ +#else + .ascii "J" /* NTSC-J (Japan) */ +#endif -.if VERSION_SH == 1 + +#ifdef VERSION_SH .byte 0x03 /* Version (Shindou) */ -.else +#else .byte 0x00 /* Version */ -.endif +#endif diff --git a/assets.json b/assets.json index dd27f39f..691735f2 100644 --- a/assets.json +++ b/assets.json @@ -266,8 +266,9 @@ "actors/king_bobomb/king_bob-omb_arm.rgba16.png": [32,32,2048,{"jp":[1257760,8312],"us":[1264928,8312],"eu":[1136896,8312],"sh":[1113408,8312]}], "actors/king_bobomb/king_bob-omb_body_unused.rgba16.png": [64,64,8192,{"jp":[1257760,10360],"us":[1264928,10360],"eu":[1136896,10360],"sh":[1113408,10360]}], "actors/king_bobomb/king_bob-omb_crown_rim.rgba16.png": [32,16,1024,{"jp":[1257760,24696],"us":[1264928,24696],"eu":[1136896,24696],"sh":[1113408,24696]}], -"actors/king_bobomb/king_bob-omb_eyes.rgba16.png": [32,64,4096,{"jp":[1257760,18552],"us":[1264928,18552],"eu":[1136896,18552],"sh":[1113408,18552]}], -"actors/king_bobomb/king_bob-omb_hand.rgba16.png": [32,32,2048,{"jp":[1215456,64],"us":[1222624,64],"eu":[1094592,64],"sh":[1071104,64]}], +"actors/king_bobomb/king_bob-omb_eyes.rgba16.png": [32,32,2048,{"jp":[1257760,18552],"us":[1264928,18552],"eu":[1136896,18552],"sh":[1113408,18552]}], +"actors/king_bobomb/king_bob-omb_eyes_blink.rgba16.png": [32,32,2048,{"jp":[1257760,20600],"us":[1264928,20600],"eu":[1136896,20600],"sh":[1113408,20600]}], +"actors/king_bobomb/king_bob-omb_hand.rgba16.png": [32,32,2048,{"jp":[1257760,22648],"us":[1264928,22648],"eu":[1136896,22648],"sh":[1113408,22648]}], "actors/king_bobomb/king_bob-omb_left_side.rgba16.png": [32,64,4096,{"jp":[1257760,33912],"us":[1264928,33912],"eu":[1136896,33912],"sh":[1113408,33912]}], "actors/king_bobomb/king_bob-omb_right_side.rgba16.png": [32,64,4096,{"jp":[1257760,38008],"us":[1264928,38008],"eu":[1136896,38008],"sh":[1113408,38008]}], "actors/klepto/klepto_beak.rgba16.png": [32,64,4096,{"jp":[1327760,4104],"us":[1334928,4104],"eu":[1206896,4104],"sh":[1183408,4104]}], diff --git a/bin/segment2.c b/bin/segment2.c index eb2bdb3a..35f0a130 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -2498,7 +2498,7 @@ const Texture texture_waterbox_lava[] = { }; // Unreferenced light group -static const Lights1 segment2_lights_unused = gdSPDefLights1( +UNUSED static const Lights1 segment2_lights_unused = gdSPDefLights1( 0x40, 0x40, 0x40, 0xff, 0xff, 0xff, 0x28, 0x28, 0x28 ); diff --git a/data/behavior_data.c b/data/behavior_data.c index 9d11492b..379fb2af 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -1965,6 +1965,7 @@ const BehaviorScript bhvBowser[] = { SPAWN_CHILD(/*Model*/ MODEL_NONE, /*Behavior*/ bhvBowserBodyAnchor), SPAWN_CHILD(/*Model*/ MODEL_BOWSER_BOMB_CHILD_OBJ, /*Behavior*/ bhvBowserFlameSpawn), SPAWN_OBJ(/*Model*/ MODEL_NONE, /*Behavior*/ bhvBowserTailAnchor), + // Beta leftover that spawn 50 coins when Bowser is defeated SET_INT(oNumLootCoins, 50), SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 0, /*Gravity*/ -400, /*Bounciness*/ -70, /*Drag strength*/ 1000, /*Friction*/ 1000, /*Buoyancy*/ 200, /*Unused*/ 0, 0), SET_HOME(), @@ -3023,7 +3024,7 @@ const BehaviorScript bhvHiddenStaircaseStep[] = { END_LOOP(), }; -const BehaviorScript bhvBooBossSpawnedBridge[] = { +const BehaviorScript bhvBooStaircase[] = { BEGIN(OBJ_LIST_SURFACE), OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), LOAD_COLLISION_DATA(bbh_seg7_collision_staircase_step), @@ -3031,7 +3032,7 @@ const BehaviorScript bhvBooBossSpawnedBridge[] = { SET_FLOAT(oCollisionDistance, 1000), SET_HOME(), BEGIN_LOOP(), - CALL_NATIVE(bhv_boo_boss_spawned_bridge_loop), + CALL_NATIVE(bhv_boo_staircase), CALL_NATIVE(load_object_collision_model), END_LOOP(), }; @@ -3141,7 +3142,7 @@ const BehaviorScript bhvUnusedFakeStar[] = { }; // What is this? -static const BehaviorScript unused_1[] = { +UNUSED static const BehaviorScript unused_1[] = { BREAK(), BREAK(), BREAK(), @@ -3851,7 +3852,7 @@ const BehaviorScript bhvSignOnWall[] = { const BehaviorScript bhvHomingAmp[] = { BEGIN(OBJ_LIST_GENACTOR), OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - LOAD_ANIMATIONS(oAnimations, amp_seg8_anims_08004034), + LOAD_ANIMATIONS(oAnimations, dAmpAnimsList), ANIMATE(0), SET_FLOAT(oGraphYOffset, 40), SET_INT(oIntangibleTimer, 0), @@ -3864,7 +3865,7 @@ const BehaviorScript bhvHomingAmp[] = { const BehaviorScript bhvCirclingAmp[] = { BEGIN(OBJ_LIST_GENACTOR), OR_INT(oFlags, (OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_MOVE_XZ_USING_FVEL | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), - LOAD_ANIMATIONS(oAnimations, amp_seg8_anims_08004034), + LOAD_ANIMATIONS(oAnimations, dAmpAnimsList), ANIMATE(0), SET_FLOAT(oGraphYOffset, 40), SET_INT(oIntangibleTimer, 0), diff --git a/enhancements/crash.patch b/enhancements/crash.patch index c3c8b537..87c5c8f9 100644 --- a/enhancements/crash.patch +++ b/enhancements/crash.patch @@ -1,13 +1,13 @@ diff --git a/asm/crash.s b/asm/crash.s new file mode 100644 -index 00000000..0b2a5574 +index 00000000..033bf952 --- /dev/null +++ b/asm/crash.s @@ -0,0 +1,153 @@ -+# SM64 Crash Handler -+# See Readme below. ++// SM64 Crash Handler ++// See Readme below. + -+.include "macros.inc" ++#include "macros.inc" + +/* --------------------------------------------------------------- + * IMPORTANT README: @@ -58,7 +58,7 @@ index 00000000..0b2a5574 + sw $a3, %lo(nAssertStopProgram)($at) + beqz $a3, .end_2 + nop -+ syscall # trigger crash screen ++ syscall // trigger crash screen +.end_2: + jr $ra + nop @@ -75,15 +75,15 @@ index 00000000..0b2a5574 + jr $ra + mfc0 $v0, 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 ++// 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 + mfc0 $k1, COP0_CAUSE + andi $k1, $k1, (0x1F << 2) -+ beqzl $k1, .end2 # exit if ExCode is 0 ++ beqzl $k1, .end2 // exit if ExCode is 0 + lui $k0, %hi(__osException) + la $k0, exceptionRegContext + sd $zero, 0x018 ($k0) @@ -116,7 +116,7 @@ index 00000000..0b2a5574 + sd $sp, 0x0F0 ($k0) + sd $fp, 0x0F8 ($k0) + sd $ra, 0x100 ($k0) -+ # cop unusable exception fired twice on startup so we'll ignore it for now ++ // cop unusable exception fired twice on startup so we'll ignore it for now + li $t0, (0x0B << 2) + beq $k1, $t0, .end + nop @@ -155,14 +155,14 @@ index 00000000..0b2a5574 + lui $k0, %hi(__osException) + .end2: + addiu $k0, $k0, %lo(__osException) -+ jr $k0 # run the original handler ++ jr $k0 // run the original handler + nop diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s -index e14928ce..4d12129e 100644 +index c3b97993..c552a485 100644 --- a/lib/asm/__osExceptionPreamble.s +++ b/lib/asm/__osExceptionPreamble.s -@@ -18,8 +18,8 @@ - .endif +@@ -11,8 +11,8 @@ + #endif glabel __osExceptionPreamble - lui $k0, %hi(__osException) @@ -173,10 +173,10 @@ index e14928ce..4d12129e 100644 nop diff --git a/sm64.ld b/sm64.ld -index f80f5b4d..569344bc 100755 +index 7d9b5b4a..c7bb81b9 100755 --- a/sm64.ld +++ b/sm64.ld -@@ -116,6 +116,7 @@ SECTIONS +@@ -117,6 +117,7 @@ SECTIONS BUILD_DIR/src/game/rendering_graph_node.o(.text); BUILD_DIR/src/game/profiler.o(.text); BUILD_DIR/asm/decompress.o(.text); diff --git a/enhancements/debug_box.patch b/enhancements/debug_box.patch index f51cedfb..12623828 100644 --- a/enhancements/debug_box.patch +++ b/enhancements/debug_box.patch @@ -2,10 +2,10 @@ diff --git a/src/game/area.c b/src/game/area.c index af9d0156..c68a7f6e 100644 --- a/src/game/area.c +++ b/src/game/area.c -@@ -21,6 +21,7 @@ - #include "engine/geo_layout.h" +@@ -22,6 +22,7 @@ #include "save_file.h" #include "level_table.h" + #include "dialog_ids.h" +#include "debug_box.h" struct SpawnInfo gPlayerSpawnInfos[1]; diff --git a/enhancements/fps.patch b/enhancements/fps.patch index ad8bfaa0..e5e1acca 100644 --- a/enhancements/fps.patch +++ b/enhancements/fps.patch @@ -1,10 +1,10 @@ diff --git a/src/game/game_init.c b/src/game/game_init.c -index b6334688..62ed106c 100644 +index b961ca52..531231cf 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c -@@ -59,6 +59,47 @@ struct DemoInput *gCurrDemoInput = NULL; // demo input sequence - u16 gDemoInputListID = 0; - struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check +@@ -82,6 +82,47 @@ struct DemoInput gRecordedDemoInput = { 0 }; + // Display + // ---------------------------------------------------------------------------------------------------- +// SDK states that 1 cycle takes about 21.33 nanoseconds +#define SECONDS_PER_CYCLE 0.00000002133f @@ -48,9 +48,9 @@ index b6334688..62ed106c 100644 +} + /** - * Initializes the Reality Display Processor (RDP). - * This function initializes settings such as texture filtering mode, -@@ -633,5 +674,7 @@ void thread5_game_loop(UNUSED void *arg) { + * Sets the initial RDP (Reality Display Processor) rendering settings. + */ +@@ -694,5 +735,7 @@ void thread5_game_loop(UNUSED void *arg) { // amount of free space remaining. print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead); } diff --git a/enhancements/ique_support.patch b/enhancements/ique_support.patch index ed2a508c..8487c48e 100644 --- a/enhancements/ique_support.patch +++ b/enhancements/ique_support.patch @@ -13,16 +13,16 @@ index 00000000..e60550ab +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 +index 00000000..58e7d4f9 --- /dev/null +++ b/lib/asm/skGetId.s @@ -0,0 +1,18 @@ -+# Code by stuckpixel ++// Code by stuckpixel + +.set noreorder +.set gp=64 + -+.include "macros.inc" ++#include "macros.inc" + +glabel skGetId + li $v0, 0 @@ -36,10 +36,10 @@ index 00000000..8fb4c449 + nop + nop diff --git a/lib/src/__osViSwapContext.c b/lib/src/__osViSwapContext.c -index b9d364b1..fa149b5d 100644 +index 990cb11f..22756e91 100644 --- a/lib/src/__osViSwapContext.c +++ b/lib/src/__osViSwapContext.c -@@ -52,7 +52,9 @@ void __osViSwapContext() { +@@ -54,7 +54,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; @@ -269,7 +269,7 @@ index 1a86477b..a94f8721 100644 return sp34; } diff --git a/lib/src/osInitialize.c b/lib/src/osInitialize.c -index ea247636..4adb45cb 100644 +index ba73024b..6deaf407 100644 --- a/lib/src/osInitialize.c +++ b/lib/src/osInitialize.c @@ -1,6 +1,7 @@ @@ -280,7 +280,7 @@ index ea247636..4adb45cb 100644 #define PIF_ADDR_START (void *) 0x1FC007FC -@@ -54,6 +55,7 @@ void osInitialize(void) { +@@ -51,6 +52,7 @@ void osInitialize(void) { UNUSED u32 eu_sp30; #endif UNUSED u32 sp2c; @@ -289,24 +289,24 @@ index ea247636..4adb45cb 100644 __osSetSR(__osGetSR() | 0x20000000); __osSetFpcCsr(0x01000800); diff --git a/sm64.ld b/sm64.ld -index f80f5b4d..e53d4e40 100755 +index 7d9b5b4a..be853a3b 100755 --- a/sm64.ld +++ b/sm64.ld -@@ -300,6 +300,8 @@ SECTIONS - #ifdef VERSION_SH - BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text) +@@ -306,6 +306,8 @@ SECTIONS + #if ENABLE_RUMBLE + BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text); #endif + BUILD_DIR/libultra.a:consoleType.o(.text) + BUILD_DIR/libultra.a:skGetId.o(.text) BUILD_DIR/lib/rsp.o(.text); #else BUILD_DIR/src/game*.o(.text); -@@ -410,6 +412,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); +@@ -428,6 +430,8 @@ SECTIONS + #if ENABLE_RUMBLE + BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text); + #endif ++ 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/mem_error_screen.patch b/enhancements/mem_error_screen.patch index b4a82e0b..3941e328 100644 --- a/enhancements/mem_error_screen.patch +++ b/enhancements/mem_error_screen.patch @@ -1,8 +1,8 @@ diff --git a/Makefile b/Makefile -index f81fd27b..318140f2 100644 +index f50b7622..124c7ec6 100644 --- a/Makefile +++ b/Makefile -@@ -419,6 +419,7 @@ $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h +@@ -478,6 +478,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 @@ -11,12 +11,12 @@ index f81fd27b..318140f2 100644 #==============================================================================# diff --git a/include/segments.h b/include/segments.h -index a8c1bf97..84c3d7a4 100644 +index a97d6ee8..186c968e 100644 --- a/include/segments.h +++ b/include/segments.h -@@ -1,6 +1,9 @@ - #ifndef SEGMENTS_H - #define SEGMENTS_H +@@ -3,6 +3,9 @@ + + #include "config.h" +/* Use expansion pack RAM */ +#define USE_EXT_RAM 1 @@ -58,7 +58,7 @@ index 17c773ed..677a5ae9 100644 + JUMP(/*target*/ level_script_entry_error_screen), +}; diff --git a/levels/intro/geo.c b/levels/intro/geo.c -index 7a297fe7..71b16442 100644 +index 30a87806..6bf7b79a 100644 --- a/levels/intro/geo.c +++ b/levels/intro/geo.c @@ -15,6 +15,24 @@ @@ -100,7 +100,7 @@ index 99277e86..04797cd7 100644 + #endif diff --git a/levels/intro/script.c b/levels/intro/script.c -index a130cc04..926c0d09 100644 +index 04b8fc4c..ca9058c4 100644 --- a/levels/intro/script.c +++ b/levels/intro/script.c @@ -18,6 +18,21 @@ @@ -138,7 +138,7 @@ index d41a91c8..7d047236 100644 struct LevelCommand *level_script_execute(struct LevelCommand *cmd); diff --git a/src/game/main.c b/src/game/main.c -index 9615f25a..e2d7b3d4 100644 +index 1a9d9e7e..f4f7a9e5 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -11,6 +11,7 @@ @@ -149,7 +149,7 @@ index 9615f25a..e2d7b3d4 100644 // Message IDs #define MESG_SP_COMPLETE 100 -@@ -127,6 +128,10 @@ void alloc_pool(void) { +@@ -131,6 +132,10 @@ void alloc_pool(void) { void *start = (void *) SEG_POOL_START; void *end = (void *) SEG_POOL_END; @@ -160,7 +160,7 @@ index 9615f25a..e2d7b3d4 100644 main_pool_init(start, end); gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); } -@@ -332,7 +337,10 @@ void thread3_main(UNUSED void *arg) { +@@ -336,7 +341,10 @@ void thread3_main(UNUSED void *arg) { create_thread(&gSoundThread, 4, thread4_sound, NULL, gThread4Stack + 0x2000, 20); osStartThread(&gSoundThread); @@ -174,7 +174,7 @@ index 9615f25a..e2d7b3d4 100644 while (TRUE) { diff --git a/src/game/mem_error_screen.c b/src/game/mem_error_screen.c new file mode 100644 -index 00000000..81efaf91 +index 00000000..f432927c --- /dev/null +++ b/src/game/mem_error_screen.c @@ -0,0 +1,104 @@ @@ -274,15 +274,14 @@ index 00000000..81efaf91 + + addr = segmented_to_virtual(level_script_entry_error_screen); + -+ rendering_init(); ++ render_init(); + + while (1) { -+ config_gfx_pool(); ++ select_gfx_pool(); + addr = level_script_execute(addr); + display_and_vsync(); + } +} -\ No newline at end of file diff --git a/src/game/mem_error_screen.h b/src/game/mem_error_screen.h new file mode 100644 index 00000000..9fbff34c diff --git a/enhancements/record_demo.patch b/enhancements/record_demo.patch index 5e90000c..a02b9f17 100644 --- a/enhancements/record_demo.patch +++ b/enhancements/record_demo.patch @@ -1,5 +1,5 @@ diff --git a/src/game/game_init.c b/src/game/game_init.c -index b6334688..9363074b 100644 +index b961ca52..adfde049 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -11,6 +11,7 @@ @@ -10,9 +10,9 @@ index b6334688..9363074b 100644 #include "profiler.h" #include "save_file.h" #include "seq_ids.h" -@@ -335,6 +336,45 @@ void display_and_vsync(void) { - gGlobalTimer++; - } +@@ -386,6 +387,45 @@ void display_and_vsync(void) { + // Controls + // ---------------------------------------------------------------------------------------------------- +/* + * This enhancement allows you to record gameplay demos for the mario head screen. @@ -24,7 +24,7 @@ index b6334688..9363074b 100644 + * +*/ + -+#include "../src/game/mario.h" ++#include "mario.h" + +#define DEMOREC_STATUS_NOT_RECORDING 0 +#define DEMOREC_STATUS_PREPARING 1 @@ -53,15 +53,15 @@ index b6334688..9363074b 100644 +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) { -@@ -368,6 +408,118 @@ static void record_demo(void) { + /** + * 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. +@@ -420,6 +460,118 @@ UNUSED static void record_demo(void) { gRecordedDemoInput.timer++; } +void record_new_demo_input(void) { -+ if(gRecordedDemoInput.timer == 1 && gRecordedDemoInputCopy.timer > 0) { ++ if (gRecordedDemoInput.timer == 1 && gRecordedDemoInputCopy.timer > 0) { + gRecordedInputs[gNumOfRecordedInputs].timer = gRecordedDemoInputCopy.timer; + gRecordedInputs[gNumOfRecordedInputs + 1].timer = 0; + gRecordedInputs[gNumOfRecordedInputs].rawStickX = gRecordedDemoInputCopy.rawStickX; @@ -86,13 +86,13 @@ index b6334688..9363074b 100644 +void recording(void) { + + // Force-stop when someone makes too many inputs. -+ if(gNumOfRecordedInputs + 1 > DEMOREC_MAX_INPUTS) { ++ if (gNumOfRecordedInputs + 1 > DEMOREC_MAX_INPUTS) { + gRecordingStatus = DEMOREC_STATUS_STOPPING; + return; + } + + copy_gRecordedDemoInput(); -+ record_demo(); // Defined in game.c ++ record_demo(); + record_new_demo_input(); +} + @@ -112,10 +112,10 @@ index b6334688..9363074b 100644 + case DEMOREC_STATUS_NOT_RECORDING: + break; + case DEMOREC_STATUS_PREPARING: -+ if(gMarioObject != NULL && gCurrLevelNum >= 5) { // If the game is in an active level ++ if (gMarioObject != NULL && gCurrLevelNum != LEVEL_NONE) { // If the game is in an active level + gRecordingStatus = DEMOREC_STATUS_RECORDING; + -+ // A bit of a hack, but it works. ++ // First 4 values in demo inputs are used to define level ID + gNumOfRecordedInputs = 1; + gRecordedInputs[0].timer = gCurrLevelNum; + gRecordedInputs[0].rawStickX = 0; @@ -127,7 +127,7 @@ index b6334688..9363074b 100644 + recording(); + break; + case DEMOREC_STATUS_DONE: -+ if(gDoneDelay > DEMOREC_DONE_DELAY) ++ if (gDoneDelay > DEMOREC_DONE_DELAY) + gRecordingStatus = DEMOREC_STATUS_NOT_RECORDING; + else + gDoneDelay++; @@ -159,8 +159,8 @@ index b6334688..9363074b 100644 + // so the debug level select is used for that. + gDebugLevelSelect = TRUE; + -+ if(gPlayer1Controller->buttonPressed & L_TRIG) { -+ if(gRecordingStatus == DEMOREC_STATUS_NOT_RECORDING) { ++ 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; @@ -172,12 +172,12 @@ index b6334688..9363074b 100644 + print_status(); +} + - // take the updated controller struct and calculate - // the new x, y, and distance floats. - void adjust_analog_stick(struct Controller *controller) { -@@ -623,6 +775,7 @@ void thread5_game_loop(UNUSED void *arg) { + /** + * Take the updated controller struct and calculate the new x, y, and distance floats. + */ +@@ -684,6 +836,7 @@ void thread5_game_loop(UNUSED void *arg) { audio_game_loop_tick(); - config_gfx_pool(); + select_gfx_pool(); read_controller_inputs(); + recordingDemo(); addr = level_script_execute(addr); diff --git a/extract_assets.py b/extract_assets.py index 3b6427e3..bde5ef21 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -20,6 +20,8 @@ def read_local_asset_list(f): def asset_needs_update(asset, version): + if version <= 6 and asset in ["actors/king_bobomb/king_bob-omb_eyes.rgba16.png", "actors/king_bobomb/king_bob-omb_hand.rgba16.png"]: + return True if version <= 5 and asset == "textures/spooky/bbh_textures.00800.rgba16.png": return True if version <= 4 and asset in ["textures/mountain/ttm_textures.01800.rgba16.png", "textures/mountain/ttm_textures.05800.rgba16.png"]: @@ -59,7 +61,7 @@ def clean_assets(local_asset_file): def main(): # In case we ever need to change formats of generated files, we keep a # revision ID in the local asset file. - new_version = 6 + new_version = 7 try: local_asset_file = open(".assets-local.txt") diff --git a/include/PR/abi.h b/include/PR/abi.h index 2631214f..b73cb726 100644 --- a/include/PR/abi.h +++ b/include/PR/abi.h @@ -56,13 +56,14 @@ #define A_ADDMIXER 4 #define A_RESAMPLE_ZOH 6 -#define A_INTERL 17 +#define A_DMEMMOVE2 16 +#define A_DOWNSAMPLE_HALF 17 #define A_ENVSETUP1 18 #define A_ENVMIXER 19 #define A_LOADBUFF 20 #define A_SAVEBUFF 21 #define A_ENVSETUP2 22 -#define A_UNK_23 23 +#define A_S8DEC 23 #define A_HILOGAIN 24 #define A_UNK_25 25 #define A_DUPLICATE 26 @@ -306,6 +307,8 @@ typedef short ENVMIX_STATE[40]; * address is later used as parameter, the 8 high bits will be an index * to the segment table and the lower 24 bits are added to the base address * stored in the segment table for this entry. The result is the physical address. + * With the newer rsp audio code, this segment table is not used. The address is + * used directly instead. * * Transfers to/from DRAM are executed using DMA and hence follow these restrictions: * All DRAM addresses should be aligned by 8 bytes, or they will be @@ -349,14 +352,6 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = (uintptr_t)(s); \ } -#define aADPCM_23(pkt, f, s) \ -{ \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_UNK_23, 24, 8) | _SHIFTL(f, 16, 8); \ - _a->words.w1 = (uintptr_t)(s); \ -} - /* * Not used in SM64. */ @@ -570,15 +565,6 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ } -#define aInterl(pkt, f, i, o, c) \ -{ \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_INTERL, 24, 8) | _SHIFTL(f, 16, 8) | \ - _SHIFTL(i, 0, 16)); \ - _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ -} - /* * Sets internal volume parameters. * See aEnvMixer for more info. @@ -663,12 +649,50 @@ typedef short ENVMIX_STATE[40]; #undef aEnvMixer #undef aInterleave +// New or modified operations in the new audio microcode below + +/** + * Decompresses S8 data. + * Possible flags: A_INIT and A_LOOP. + * + * First set up internal data in DMEM: + * aSetLoop(cmd++, physicalAddressOfLoopState) (if A_LOOP is set) + * + * Then before this command, call: + * aSetBuffer(cmd++, 0, in, out, count) + * + * Note: count will be rounded up to the nearest multiple of 32 bytes. + * + * S8 decompression works by expanding s8 bytes into s16 numbers, + * by performing a left shift of 8 steps. + * + * Before the algorithm starts, the previous 16 samples are loaded according to flag: + * A_INIT: all zeros + * A_LOOP: the address set by aSetLoop + * no flags: the DRAM address in the s parameter + * These 16 samples are immediately copied to the destination address. + * + * The result of "count" bytes will be written after these 16 initial samples. + * The last 16 samples written to the destination will also be written to + * the state address in DRAM. + */ +#define aS8Dec(pkt, f, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_S8DEC, 24, 8) | _SHIFTL(f, 16, 8); \ + _a->words.w1 = (uintptr_t)(s); \ +} + /* * Mix two tracks by simple clamped addition. * * s: DMEM source track 1 * d: DMEM source track 2 and destination - * c: number of bytes to write (rounded down to 16 byte alignment) + * c: number of bytes to write + * + * Note: count is first rounded down to the nearest multiple of 16 bytes + * and then rounded up to the nearest multiple of 64 bytes. */ #define aAddMixer(pkt, s, d, c) \ { \ @@ -726,6 +750,28 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = (_SHIFTL(d, 16, 16) | _SHIFTL(0x80, 0, 16)); \ } +/* + * Copies memory in DMEM, second version. + * + * Copies t * c bytes from address i to address o. + * + * Note: count is first rounded up to the nearest multiple of 32 bytes, + * before the multiplication by t. + * + * Note: This acts as memcpy where 32 bytes are moved at a time, therefore + * if input and output overlap, output address should be less than input address. + * + * Not used in SM64. + */ +#define aDMEMMove2(pkt, t, i, o, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_DMEMMOVE2, 24, 8) | \ + _SHIFTL(t, 16, 8) | _SHIFTL(i, 0, 16); \ + _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ +} + /* * Fast resample. * @@ -734,14 +780,37 @@ typedef short ENVMIX_STATE[40]; * * This works like the other resample command but just takes the "nearest" sample, * instead of a function of the four nearest samples. + * + * Initially the current position is calculated as (in << 16) + startFract. + * For every sample to create, the value is simply taken from the sample + * at address ((position >> 17) << 1). Then the current position is incremented + * by (pitch << 2). + * + * Note: count represents the number of output bytes to create, and is + * rounded up to the nearest multiple of 8 bytes. */ -#define aResampleZoh(pkt, pitch, start_fract) \ +#define aResampleZoh(pkt, pitch, startFract) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_RESAMPLE_ZOH, 24, 8) | \ _SHIFTL(pitch, 0, 16)); \ - _a->words.w1 = _SHIFTL(start_fract, 0, 16); \ + _a->words.w1 = _SHIFTL(startFract, 0, 16); \ +} + +/* + * Fast downsampling by taking every other sample, discarding others. + * + * Note: nSamples refers to the number of output samples to create, and + * is first rounded up to the nearest multiple of 8. + */ +#define aDownsampleHalf(pkt, nSamples, i, o) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_DOWNSAMPLE_HALF, 24, 8) | \ + _SHIFTL(nSamples, 0, 16)); \ + _a->words.w1 = _SHIFTL(i, 16, 16) | _SHIFTL(o, 0, 16); \ } /* @@ -764,39 +833,87 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = _SHIFTL(i, 16, 16) | _SHIFTL(o, 0, 16); \ } -#define aEnvSetup1(pkt, a, b, c, d) \ +/* + * See aEnvMixer for more info. + */ +#define aEnvSetup1(pkt, initialVolReverb, rampReverb, rampLeft, rampRight) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_ENVSETUP1, 24, 8) | \ - _SHIFTL(a, 16, 8) | _SHIFTL(b, 0, 16)); \ - _a->words.w1 = _SHIFTL(c, 16, 16) | _SHIFTL(d, 0, 16); \ + _SHIFTL(initialVolReverb, 16, 8) | \ + _SHIFTL(rampReverb, 0, 16)); \ + _a->words.w1 = _SHIFTL(rampLeft, 16, 16) | \ + _SHIFTL(rampRight, 0, 16); \ } -#define aEnvSetup2(pkt, volLeft, volRight) \ +/* + * See aEnvMixer for more info. + */ +#define aEnvSetup2(pkt, initialVolLeft, initialVolRight) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = _SHIFTL(A_ENVSETUP2, 24, 8); \ - _a->words.w1 = _SHIFTL(volLeft, 16, 16) | \ - _SHIFTL(volRight, 0, 16); \ + _a->words.w1 = _SHIFTL(initialVolLeft, 16, 16) | \ + _SHIFTL(initialVolRight, 0, 16); \ } -#define aEnvMixer(pkt, inBuf, nSamples, bit1, bit2, bit3, dryLeft, dryRight, wetLeft, wetRight) \ +/* + * Mixes an envelope with mono sound into 4 channels. + * + * To allow for many parameters, a sequence of aEnvSetup1, aEnvSetup2, + * aEnvMixer shall always be called. + * + * The function works in blocks of 8 samples. + * However, nSamples is rounded up to the nearest multiple of 16 samples. + * + * For each sample in a block: + * 1. sampleLeft = in * volLeft * (negLeft ? -1 : 1) + * 2. sampleRight = in * volRight * (negRight ? -1 : 1) + * 3. dryLeft += sampleLeft + * 4. dryRight += sampleRight + * 5. if swapReverb: swap sampleLeft and sampleRight + * 6. wetLeft += sampleLeft * volReverb + * 7. wetRight += sampleRight * volReverb + * + * After each block, all vol variables are added by their corresponding + * ramp value. + * + * Each volume variable is treated as a UQ0.16 number. Make sure + * the ramp additions don't overflow, or wrapping will occur. + * The initialVolReverb parameter is only 8 bits, but will be left + * shifted 8 bits by the rsp. + */ +#define aEnvMixer(pkt, inBuf, nSamples, swapReverb, negLeft, negRight, \ + dryLeft, dryRight, wetLeft, wetRight) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_ENVMIXER, 24, 8) | \ _SHIFTL((inBuf) >> 4, 16, 8) | \ _SHIFTL(nSamples, 8, 8)) | \ - _SHIFTL(bit1, 2, 1) | _SHIFTL(bit2, 1, 1) | \ - _SHIFTL(bit3, 0, 1); \ + _SHIFTL(swapReverb, 2, 1) | _SHIFTL(negLeft, 1, 1) |\ + _SHIFTL(negRight, 0, 1); \ _a->words.w1 = _SHIFTL((dryLeft) >> 4, 24, 8) | \ _SHIFTL((dryRight) >> 4, 16, 8) | \ _SHIFTL((wetLeft) >> 4, 8, 8) | \ _SHIFTL((wetRight) >> 4, 0, 8); \ } +/* + * Interleaves two mono channels into stereo. + * + * The count refers to the size of each input. Hence 2 * count bytes + * will be written out. + * + * A left sample will be placed before the right sample. + * All addresses (output, left, right) are DMEM addresses. + * + * Note: count will be rounded up to the nearest multiple of 8 bytes. + * The previous version of this function rounded up to the nearest + * multiple of 16 bytes. + */ #define aInterleave(pkt, o, l, r, c) \ { \ Acmd *_a = (Acmd *)pkt; \ @@ -806,7 +923,26 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = _SHIFTL(l, 16, 16) | _SHIFTL(r, 0, 16); \ } -// countOrBuf meaning depends on flag +/* + * Linear filter function. + * + * Calculates out[i] = sum all elements in the vector in[i..i-7] * filter[0..7], + * where "*" represents dot multiplication. The input/output contains s16 + * samples and filter contains Q1.15 signed fixed point numbers. + * Every result sample is rounded and clamped. + * + * First initiate by calling with the flag f set to 2, countOrBuf contains + * the length in bytes that shall be processed in the next call. The addr + * parameter shall contain the DRAM address to the filter table (16 bytes). + * The count will be rounded up to the nearest multiple of 16 bytes. + * + * The aFilter function shall then be called in direct succession, with flag + * set to either 0 or 1. The countOrBuf parameter shall contain the DMEM + * address for the input/output. The addr parameter shall contain the DRAM + * address for the state, containing the last previous 8 input samples. + * The state is always written to upon exit, but is only read at entry if + * the flag is 0 (otherwise all-zero samples are used instead). + */ #define aFilter(pkt, f, countOrBuf, addr) \ { \ Acmd *_a = (Acmd *)pkt; \ @@ -816,22 +952,41 @@ typedef short ENVMIX_STATE[40]; _a->words.w1 = (uintptr_t)(addr); \ } -#define aHilogain(pkt, id, buflen, i) \ +/* + * Modifies the volume of samples using a simple UQ4.4 gain multiplier. + * + * Performs the following: + * + * 1. Count c is rounded up to 32 byte alignment + * 2. g is a u8 that contains a UQ4.4 number + * 3. Modify each sample s, so that s = clamp_s16(s * g >> 4) + */ +#define aHiLoGain(pkt, g, buflen, i) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = _SHIFTL(A_HILOGAIN, 24, 8) | \ - _SHIFTL((id), 16, 8) | _SHIFTL((buflen), 0, 16); \ + _SHIFTL((g), 16, 8) | _SHIFTL((buflen), 0, 16); \ _a->words.w1 = _SHIFTL((i), 16, 16); \ } -#define aUnknown25(pkt, f, g, i, o) \ +/* + * Performs the following: + * + * 1. Count c is rounded up to 64 byte alignment + * 2. f is added to i + * 3. i and o are from now treated as s16 pointers + * 4. 32 s16 samples are loaded from i to tbl + * 5. for (u32 idx = 0; idx * sizeof(s16) < c; idx++) + * o[idx] = clamp_s16((s32)o[idx] * (s32)tbl[idx % 32]); + */ +#define aUnknown25(pkt, f, c, o, i) \ { \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_UNK_25, 24, 8) | \ - _SHIFTL((f), 16, 8) | _SHIFTL((g), 0, 16)); \ - _a->words.w1 = _SHIFTL((i), 16, 16) | _SHIFTL((o), 0, 16); \ + _SHIFTL((f), 16, 8) | _SHIFTL((c), 0, 16)); \ + _a->words.w1 = _SHIFTL((o), 16, 16) | _SHIFTL((i), 0, 16); \ } #endif diff --git a/include/PR/libaudio.h b/include/PR/libaudio.h index 3fffe9c0..cb7a5b19 100644 --- a/include/PR/libaudio.h +++ b/include/PR/libaudio.h @@ -8,7 +8,8 @@ typedef struct u8 *offset; s32 len; #ifdef VERSION_SH - s8 magic[2]; // tbl: 0x0204, otherwise: 0x0203 + s8 medium; + s8 magic; // tbl: 0x04, otherwise: 0x03 // for ctl (else zeros): union { @@ -38,7 +39,9 @@ typedef struct #ifdef VERSION_SH s16 unk2; u8 *data; +#if !IS_64_BIT s32 pad[2]; +#endif #endif ALSeqData seqArray[1]; } ALSeqFile; diff --git a/lib/src/os.h b/include/PR/os.h similarity index 100% rename from lib/src/os.h rename to include/PR/os.h diff --git a/include/behavior_data.h b/include/behavior_data.h index 7acb3309..66c410b7 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -261,7 +261,7 @@ extern const BehaviorScript bhvBoo[]; extern const BehaviorScript bhvMerryGoRoundBoo[]; extern const BehaviorScript bhvGhostHuntBoo[]; extern const BehaviorScript bhvHiddenStaircaseStep[]; -extern const BehaviorScript bhvBooBossSpawnedBridge[]; +extern const BehaviorScript bhvBooStaircase[]; extern const BehaviorScript bhvBbhTiltingTrapPlatform[]; extern const BehaviorScript bhvHauntedBookshelf[]; extern const BehaviorScript bhvMeshElevator[]; diff --git a/include/config.h b/include/config.h index 211a086a..a9f685ea 100644 --- a/include/config.h +++ b/include/config.h @@ -8,7 +8,7 @@ */ // Bug Fixes -// --| US Version Nintendo Bug Fixes +// --| Post-JP Version Nintendo Bug Fixes /// Fixes bug where obtaining over 999 coins sets the number of lives to 999 (or -25) #define BUGFIX_MAX_LIVES (0 || VERSION_US || VERSION_EU || VERSION_SH) /// Fixes bug where the Boss music won't fade out after defeating King Bob-omb @@ -22,6 +22,17 @@ #define BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE (0 || VERSION_US || VERSION_SH) /// 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 || VERSION_SH) +/// Fixes bug that enables Mario in time stop even if is not ready to speak +#define BUGFIX_DIALOG_TIME_STOP (0 || VERSION_US || VERSION_EU || VERSION_SH) +/// Fixes bug that causes Mario to still collide with Bowser in BITS after his defeat +#define BUGFIX_BOWSER_COLLIDE_BITS_DEAD (0 || VERSION_US || VERSION_EU || VERSION_SH) +/// Fixes bug where Bowser wouldn't reset his speed when fallen off (and adds missing checks) +#define BUGFIX_BOWSER_FALLEN_OFF_STAGE (0 || VERSION_US || VERSION_EU || VERSION_SH) +/// Fixes bug where Bowser would look weird while fading out +#define BUGFIX_BOWSER_FADING_OUT (0 || VERSION_US || VERSION_EU || VERSION_SH) + +// Support Rumble Pak +#define ENABLE_RUMBLE (0 || VERSION_SH) // Screen Size Defines #define SCREEN_WIDTH 320 diff --git a/include/dialog_ids.h b/include/dialog_ids.h index 6feadafb..2d9a2410 100644 --- a/include/dialog_ids.h +++ b/include/dialog_ids.h @@ -2,6 +2,7 @@ #define DIALOG_IDS_H enum DialogId { + DIALOG_NONE = -1, DIALOG_000, DIALOG_001, DIALOG_002, diff --git a/include/macros.inc b/include/macros.inc index f642978a..3cb002a3 100644 --- a/include/macros.inc +++ b/include/macros.inc @@ -1,4 +1,4 @@ -# Assembly Macros +// Assembly Macros .set K0BASE, 0x80000000 .set K1BASE, 0xA0000000 diff --git a/include/model_ids.h b/include/model_ids.h index 1cd0a253..3e7c8845 100644 --- a/include/model_ids.h +++ b/include/model_ids.h @@ -410,12 +410,12 @@ // second set of actor bins, (0x64-0x73) // group 12 -#define MODEL_BOWSER 0x64 // bowser_geo - 2nd geo loaded is bowser_geo_000424, starts with shadow command +#define MODEL_BOWSER 0x64 // bowser_geo #define MODEL_BOWSER_BOMB_CHILD_OBJ 0x65 // bowser_bomb_geo - Spawns as a chill object in bowser's behavior command, causing an explosion if it touches a bomb #define MODEL_BOWSER_SMOKE 0x66 // bowser_impact_smoke_geo #define MODEL_BOWSER_FLAMES 0x67 // bowser_flames_geo #define MODEL_BOWSER_WAVE 0x68 // invisible_bowser_accessory_geo -#define MODEL_BOWSER2 0x69 // bowser2_geo - 2nd geo loaded is bowser_geo_000770, starts with node command, only difference +#define MODEL_BOWSER_NO_SHADOW 0x69 // bowser_geo_no_shadow // group 13 #define MODEL_BUB 0x64 // cheep_cheep_geo @@ -531,7 +531,7 @@ #define MODEL_KOOPA_WITHOUT_SHELL 0xBF // koopa_without_shell_geo #define MODEL_GOOMBA 0xC0 // goomba_geo #define MODEL_SEAWEED 0xC1 // seaweed_geo -#define MODEL_AMP 0xC2 // amp_geo +#define MODEL_AMP 0xC2 // dAmpGeo #define MODEL_BOBOMB_BUDDY 0xC3 // bobomb_buddy_geo // find me // find me diff --git a/include/object_constants.h b/include/object_constants.h index 95f5ce53..76664b23 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -53,23 +53,18 @@ #define HELD_DROPPED 3 /* oDialogState */ -#define DIALOG_UNK1_ENABLE_TIME_STOP 0 -#define DIALOG_UNK1_INTERRUPT_MARIO_ACTION 1 -#define DIALOG_UNK1_BEGIN_DIALOG 2 -#define DIALOG_UNK1_AWAIT_DIALOG 3 -#define DIALOG_UNK1_DISABLE_TIME_STOP 4 +#define DIALOG_STATUS_ENABLE_TIME_STOP 0 +#define DIALOG_STATUS_INTERRUPT 1 +#define DIALOG_STATUS_START_DIALOG 2 +#define DIALOG_STATUS_STOP_DIALOG 3 +#define DIALOG_STATUS_DISABLE_TIME_STOP 4 -#define DIALOG_UNK1_FLAG_DEFAULT (1 << 1) // 0x02 -#define DIALOG_UNK1_FLAG_RESPONSE (1 << 2) // 0x04 -#define DIALOG_UNK1_FLAG_4 (1 << 4) // 0x10 - -#define DIALOG_UNK2_ENABLE_TIME_STOP 0 -#define DIALOG_UNK2_TURN_AND_INTERRUPT_MARIO_ACTION 1 -#define DIALOG_UNK2_AWAIT_DIALOG 2 -#define DIALOG_UNK2_END_DIALOG 3 - -#define DIALOG_UNK2_FLAG_0 (1 << 0) // 0x01 -#define DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED (1 << 4) // 0x10 +#define DIALOG_FLAG_NONE 0 +#define DIALOG_FLAG_TURN_TO_MARIO (1 << 0) // 0x01 // cutscene only +#define DIALOG_FLAG_TEXT_DEFAULT (1 << 1) // 0x02 +#define DIALOG_FLAG_TEXT_RESPONSE (1 << 2) // 0x04 // non-cutscene only +#define DIALOG_FLAG_UNK_CAPSWITCH (1 << 3) // 0x08 // not defined +#define DIALOG_FLAG_TIME_STOP_ENABLED (1 << 4) // 0x10 /* oMoveFlags */ #define OBJ_MOVE_LANDED (1 << 0) // 0x0001 @@ -191,6 +186,112 @@ #define BOBOMB_BUDDY_HAS_NOT_TALKED 0 #define BOBOMB_BUDDY_HAS_TALKED 2 +/* Bowser */ + /* Tail oAction */ + #define BOWSER_ACT_TAIL_DEFAULT 0 + #define BOWSER_ACT_TAIL_THROWN 1 + #define BOWSER_ACT_TAIL_TOUCHED_MARIO 2 + /* oAction */ + #define BOWSER_ACT_DEFAULT 0 + #define BOWSER_ACT_THROWN 1 + #define BOWSER_ACT_JUMP_ONTO_STAGE 2 + #define BOWSER_ACT_DANCE 3 + #define BOWSER_ACT_DEAD 4 + #define BOWSER_ACT_WAIT 5 + #define BOWSER_ACT_INTRO_WALK 6 + #define BOWSER_ACT_CHARGE_MARIO 7 + #define BOWSER_ACT_SPIT_FIRE_INTO_SKY 8 + #define BOWSER_ACT_SPIT_FIRE_ONTO_FLOOR 9 + #define BOWSER_ACT_HIT_EDGE 10 + #define BOWSER_ACT_TURN_FROM_EDGE 11 + #define BOWSER_ACT_HIT_MINE 12 + #define BOWSER_ACT_BIG_JUMP 13 + #define BOWSER_ACT_WALK_TO_MARIO 14 + #define BOWSER_ACT_BREATH_FIRE 15 + #define BOWSER_ACT_TELEPORT 16 + #define BOWSER_ACT_QUICK_JUMP 17 + #define BOWSER_ACT_UNUSED_SLOW_WALK 18 + #define BOWSER_ACT_TILT_LAVA_PLATFORM 19 + /* Animations */ + #define BOWSER_ANIM_STAND_UP 0 + #define BOWSER_ANIM_STAND_UP_UNUSED 1 // slightly different + #define BOWSER_ANIM_SHAKING 2 + #define BOWSER_ANIM_GRABBED 3 + #define BOWSER_ANIM_BROKEN 4 // broken animation + #define BOWSER_ANIM_FALL_DOWN 5 // unused + #define BOWSER_ANIM_BREATH 6 + #define BOWSER_ANIM_JUMP 7 // unused, short jump, replaced by start/stop + #define BOWSER_ANIM_JUMP_STOP 8 + #define BOWSER_ANIM_JUMP_START 9 + #define BOWSER_ANIM_DANCE 10 + #define BOWSER_ANIM_BREATH_UP 11 + #define BOWSER_ANIM_IDLE 12 + #define BOWSER_ANIM_SLOW_GAIT 13 + #define BOWSER_ANIM_LOOK_DOWN_STOP_WALK 14 + #define BOWSER_ANIM_LOOK_UP_START_WALK 15 + #define BOWSER_ANIM_FLIP_DOWN 16 + #define BOWSER_ANIM_LAY_DOWN 17 + #define BOWSER_ANIM_RUN_START 18 + #define BOWSER_ANIM_RUN 19 + #define BOWSER_ANIM_RUN_STOP 20 + #define BOWSER_ANIM_RUN_SLIP 21 + #define BOWSER_ANIM_BREATH_QUICK 22 + #define BOWSER_ANIM_EDGE_MOVE 23 + #define BOWSER_ANIM_EDGE_STOP 24 + #define BOWSER_ANIM_FLIP 25 + #define BOWSER_ANIM_STAND_UP_FROM_FLIP 26 + /* oBehParams2ndByte */ + #define BOWSER_BP_BITDW 0 + #define BOWSER_BP_BITFS 1 + #define BOWSER_BP_BITS 2 + /* oBowserCamAct */ + #define BOWSER_CAM_ACT_IDLE 0 + #define BOWSER_CAM_ACT_WALK 1 + #define BOWSER_CAM_ACT_END 2 + /* oBowserStatus */ + #define BOWSER_STATUS_ANGLE_MARIO (1 << 1) // 0x00000002 + #define BOWSER_STATUS_ANGLE_CENTRE (1 << 2) // 0x00000004 + #define BOWSER_STATUS_DIST_MARIO (1 << 3) // 0x00000008 + #define BOWSER_STATUS_DIST_CENTRE (1 << 4) // 0x00000010 + #define BOWSER_STATUS_BIG_JUMP (1 << 16) // 0x00010000 + #define BOWSER_STATUS_FIRE_SKY (1 << 17) // 0x00020000 + /* oBowserGrabbedStatus */ + #define BOWSER_GRAB_STATUS_NONE 0 + #define BOWSER_GRAB_STATUS_GRABBED 1 + #define BOWSER_GRAB_STATUS_HOLDING 2 + /* oSubAction */ + #define BOWSER_SUB_ACT_DEAD_FLY_BACK 0 + #define BOWSER_SUB_ACT_DEAD_BOUNCE 1 + #define BOWSER_SUB_ACT_DEAD_WAIT 2 + #define BOWSER_SUB_ACT_DEAD_DEFAULT_END 3 + #define BOWSER_SUB_ACT_DEAD_DEFAULT_END_OVER 4 + #define BOWSER_SUB_ACT_DEAD_FINAL_END 10 + #define BOWSER_SUB_ACT_DEAD_FINAL_END_OVER 11 + + #define BOWSER_SUB_ACT_CHARGE_START 0 + #define BOWSER_SUB_ACT_CHARGE_RUN 1 + #define BOWSER_SUB_ACT_CHARGE_END 2 + #define BOWSER_SUB_ACT_CHARGE_SLIP 3 + + #define BOWSER_SUB_ACT_TELEPORT_START 0 + #define BOWSER_SUB_ACT_TELEPORT_MOVE 1 + #define BOWSER_SUB_ACT_TELEPORT_STOP 2 + + #define BOWSER_SUB_ACT_HIT_MINE_START 0 + #define BOWSER_SUB_ACT_HIT_MINE_FALL 1 + #define BOWSER_SUB_ACT_HIT_MINE_STOP 2 + + #define BOWSER_SUB_ACT_JUMP_ON_STAGE_IDLE 0 + #define BOWSER_SUB_ACT_JUMP_ON_STAGE_START 1 + #define BOWSER_SUB_ACT_JUMP_ON_STAGE_LAND 2 + #define BOWSER_SUB_ACT_JUMP_ON_STAGE_STOP 3 + +/* Bowser Bits Platform*/ + /* oAction */ + #define BOWSER_BITS_PLAT_ACT_START 0 + #define BOWSER_BITS_PLAT_ACT_CHECK 1 + #define BOWSER_BITS_PLAT_ACT_FALL 2 + /* Fish Spawer */ /* oAction */ #define FISH_SPAWNER_ACT_SPAWN 0 diff --git a/include/object_fields.h b/include/object_fields.h index 89939cc2..d9dda336 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -65,8 +65,8 @@ #define /*0x0B4*/ oVelZ OBJECT_FIELD_F32(0x0B) #define /*0x0B8*/ oForwardVel OBJECT_FIELD_F32(0x0C) #define /*0x0B8*/ oForwardVelS32 OBJECT_FIELD_S32(0x0C) -#define /*0x0BC*/ oUnkBC OBJECT_FIELD_F32(0x0D) -#define /*0x0C0*/ oUnkC0 OBJECT_FIELD_F32(0x0E) +#define /*0x0BC*/ oLeftVel OBJECT_FIELD_F32(0x0D) +#define /*0x0C0*/ oUpVel OBJECT_FIELD_F32(0x0E) #define /*0x0C4*/ O_MOVE_ANGLE_INDEX 0x0F #define /*0x0C4*/ O_MOVE_ANGLE_PITCH_INDEX (O_MOVE_ANGLE_INDEX + 0) #define /*0x0C4*/ O_MOVE_ANGLE_YAW_INDEX (O_MOVE_ANGLE_INDEX + 1) @@ -274,24 +274,24 @@ #define /*0x0FC*/ oBBallSpawnerPeriodMinus1 OBJECT_FIELD_S32(0x1D) /* Bowser */ -#define /*0x088*/ oBowserUnk88 OBJECT_FIELD_S32(0x00) -#define /*0x0F4*/ oBowserUnkF4 OBJECT_FIELD_S32(0x1B) -#define /*0x0F8*/ oBowserUnkF8 OBJECT_FIELD_S32(0x1C) +#define /*0x088*/ oBowserCamAct OBJECT_FIELD_S32(0x00) +#define /*0x0F4*/ oBowserStatus OBJECT_FIELD_S32(0x1B) +#define /*0x0F8*/ oBowserTimer OBJECT_FIELD_S32(0x1C) #define /*0x0FC*/ oBowserDistToCentre OBJECT_FIELD_F32(0x1D) -#define /*0x106*/ oBowserUnk106 OBJECT_FIELD_S16(0x1F, 1) -#define /*0x108*/ oBowserUnk108 OBJECT_FIELD_S16(0x20, 0) +#define /*0x106*/ oBowserBitsJustJump OBJECT_FIELD_S16(0x1F, 1) +#define /*0x108*/ oBowserRandSplitFloor OBJECT_FIELD_S16(0x20, 0) #define /*0x10A*/ oBowserHeldAnglePitch OBJECT_FIELD_S16(0x20, 1) #define /*0x10D*/ oBowserHeldAngleVelYaw OBJECT_FIELD_S16(0x21, 0) -#define /*0x10E*/ oBowserUnk10E OBJECT_FIELD_S16(0x21, 1) -#define /*0x110*/ oBowserUnk110 OBJECT_FIELD_S16(0x22, 0) +#define /*0x10E*/ oBowserGrabbedStatus OBJECT_FIELD_S16(0x21, 1) +#define /*0x110*/ oBowserIsReacting OBJECT_FIELD_S16(0x22, 0) #define /*0x112*/ oBowserAngleToCentre OBJECT_FIELD_S16(0x22, 1) -#define /*0x1AC*/ oBowserUnk1AC OBJECT_FIELD_S16(0x49, 0) -#define /*0x1AE*/ oBowserUnk1AE OBJECT_FIELD_S16(0x49, 1) +#define /*0x1AC*/ oBowserTargetOpacity OBJECT_FIELD_S16(0x49, 0) +#define /*0x1AE*/ oBowserEyesTimer OBJECT_FIELD_S16(0x49, 1) #define /*0x1B0*/ oBowserEyesShut OBJECT_FIELD_S16(0x4A, 0) -#define /*0x1B2*/ oBowserUnk1B2 OBJECT_FIELD_S16(0x4A, 1) +#define /*0x1B2*/ oBowserRainbowLight OBJECT_FIELD_S16(0x4A, 1) /* Bowser Shockwave */ -#define /*0x0F4*/ oBowserShockWaveUnkF4 OBJECT_FIELD_F32(0x1B) +#define /*0x0F4*/ oBowserShockWaveScale OBJECT_FIELD_F32(0x1B) /* Black Smoke Bowser */ #define /*0x0F4*/ oBlackSmokeBowserUnkF4 OBJECT_FIELD_F32(0x1B) @@ -497,7 +497,7 @@ /* Flame */ #define /*0x0F4*/ oFlameScale OBJECT_FIELD_F32(0x1B) #define /*0x0F8*/ oFlameSpeedTimerOffset OBJECT_FIELD_S32(0x1C) -#define /*0x0FC*/ oFlameUnkFC OBJECT_FIELD_F32(0x1D) +#define /*0x0FC*/ oFlameUnusedRand OBJECT_FIELD_F32(0x1D) #define /*0x100*/ oFlameBowser OBJECT_FIELD_OBJ(0x1E) /* Blue Flame */ @@ -626,7 +626,7 @@ #define /*0x0F4*/ oKoopaRaceEndpointRaceBegun OBJECT_FIELD_S32(0x1B) #define /*0x0F8*/ oKoopaRaceEndpointKoopaFinished OBJECT_FIELD_S32(0x1C) #define /*0x0FC*/ oKoopaRaceEndpointRaceStatus OBJECT_FIELD_S32(0x1D) -#define /*0x100*/ oKoopaRaceEndpointUnk100 OBJECT_FIELD_S32(0x1E) +#define /*0x100*/ oKoopaRaceEndpointDialog OBJECT_FIELD_S32(0x1E) #define /*0x104*/ oKoopaRaceEndpointRaceEnded OBJECT_FIELD_S32(0x1F) /* Koopa Shell Flame */ @@ -770,10 +770,14 @@ #define /*0x0F8*/ oPitouneUnkF8 OBJECT_FIELD_F32(0x1C) #define /*0x0FC*/ oPitouneUnkFC OBJECT_FIELD_F32(0x1D) -/* Platform */ -#define /*0x0F4*/ oPlatformTimer OBJECT_FIELD_S32(0x1B) -#define /*0x0F8*/ oPlatformUnkF8 OBJECT_FIELD_OBJ(0x1C) -#define /*0x0FC*/ oPlatformUnkFC OBJECT_FIELD_S32(0x1D) +/* Falling Rising Bitfs Platform */ +#define /*0x0F4*/ oBitfsPlatformTimer OBJECT_FIELD_S32(0x1B) + +/* Falling Bowser Bits Platform */ +#define /*0x0F8*/ oBitsPlatformBowser OBJECT_FIELD_OBJ(0x1C) +#define /*0x0FC*/ oBitsPlatformTimer OBJECT_FIELD_S32(0x1D) + +/* WF Platform */ #define /*0x10C*/ oPlatformUnk10C OBJECT_FIELD_F32(0x21) #define /*0x110*/ oPlatformUnk110 OBJECT_FIELD_F32(0x22) @@ -877,7 +881,7 @@ // 0x1D-0x21 reserved for pathing /* Snowman's Head */ -#define /*0x0F4*/ oSnowmansHeadUnkF4 OBJECT_FIELD_S32(0x1B) +#define /*0x0F4*/ oSnowmansHeadDialogActive OBJECT_FIELD_S32(0x1B) /* Snowman Wind Blowing */ #define /*0x0F4*/ oSLSnowmanWindOriginalYaw OBJECT_FIELD_S32(0x1B) diff --git a/include/segments.h b/include/segments.h index a8c1bf97..a97d6ee8 100644 --- a/include/segments.h +++ b/include/segments.h @@ -1,6 +1,8 @@ #ifndef SEGMENTS_H #define SEGMENTS_H +#include "config.h" + /* * Memory addresses for segments. Ideally, this header file would not be * needed, and the addresses would be defined in sm64.ld and linker-inserted @@ -20,10 +22,10 @@ #define SEG_BUFFERS 0x801C1000 -#ifdef VERSION_EU -#define SEG_MAIN 0x80241800 // TODO: Investigate why it's different? -#elif defined(VERSION_SH) +#if defined(VERSION_SH) || ENABLE_RUMBLE #define SEG_MAIN 0x80249000 +#elif defined(VERSION_EU) +#define SEG_MAIN 0x80241800 // TODO: Investigate why it's different? #else #define SEG_MAIN 0x80246000 #endif diff --git a/include/seq_ids.h b/include/seq_ids.h index 0aec73d1..8166de64 100644 --- a/include/seq_ids.h +++ b/include/seq_ids.h @@ -6,6 +6,8 @@ #define SEQ_BASE_ID 0x7f #define SEQ_VARIATION 0x80 +#define SEQ_MENU_GAME_OVER (SEQ_MENU_TITLE_SCREEN | SEQ_VARIATION) + enum SeqId { SEQ_SOUND_PLAYER, // 0x00 SEQ_EVENT_CUTSCENE_COLLECT_STAR, // 0x01 diff --git a/include/seq_macros.inc b/include/seq_macros.inc index e0633acb..d73d9923 100644 --- a/include/seq_macros.inc +++ b/include/seq_macros.inc @@ -1,7 +1,7 @@ -# Macros for disassembled sequence files. This file was automatically generated by seq_decoder.py. -# To regenerate it, run: ./tools/seq_decoder.py --emit-asm-macros >seq_macros.inc +// Macros for disassembled sequence files. This file was automatically generated by seq_decoder.py. +// To regenerate it, run: ./tools/seq_decoder.py --emit-asm-macros > include/seq_macros.inc -# seq commands +// seq commands .macro seq_testchdisabled a .byte 0x0 + \a @@ -155,7 +155,7 @@ .byte 0xff .endm -.ifdef VERSION_SH +#ifdef VERSION_SH .macro seq_unreservenotes .byte 0xf0 @@ -166,9 +166,9 @@ .byte \a .endm -.else +#else -.ifdef VERSION_EU +#ifdef VERSION_EU .macro seq_unreservenotes .byte 0xf0 @@ -179,7 +179,7 @@ .byte \a .endm -.else +#else .macro seq_unreservenotes .byte 0xf1 @@ -190,11 +190,11 @@ .byte \a .endm -.endif +#endif -.endif +#endif -# chan commands +// chan commands .macro chan_startchannel a, b .byte 0x10 + \a @@ -462,7 +462,7 @@ var_long \a .endm -.ifdef VERSION_SH +#ifdef VERSION_SH .macro chan_setnotepriority a .byte 0xe9 @@ -495,7 +495,7 @@ .byte 0x90 + \a .endm -.else +#else .macro chan_testlayerfinished a .byte 0x0 + \a @@ -514,7 +514,7 @@ .byte 0xa0 + \a .endm -.ifdef VERSION_EU +#ifdef VERSION_EU .macro chan_setnotepriority a .byte 0xe9 @@ -530,7 +530,7 @@ .byte \a .endm -.else +#else .macro chan_setnotepriority a .byte 0x60 + \a @@ -545,11 +545,11 @@ .byte \a .endm -.endif +#endif -.endif +#endif -# layer commands +// layer commands .macro layer_note0 a, b, c, d .byte 0x0 + \a @@ -659,7 +659,7 @@ .byte \c .endm -# envelope commands +// envelope commands .macro envelope_disable a .byte 0x0, 0x0 @@ -686,7 +686,7 @@ .byte \b >> 8, \b & 0xff .endm -# other commands +// other commands .macro var_long x .byte (0x80 | (\x & 0x7f00) >> 8), (\x & 0xff) diff --git a/include/sm64.h b/include/sm64.h index 34bfec22..88446c92 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -59,7 +59,7 @@ #define INPUT_A_DOWN 0x0080 #define INPUT_IN_POISON_GAS 0x0100 #define INPUT_IN_WATER 0x0200 -#define INPUT_UNKNOWN_10 0x0400 +#define INPUT_STOMPED 0x0400 #define INPUT_INTERACT_OBJ_GRABBABLE 0x0800 #define INPUT_UNKNOWN_12 0x1000 #define INPUT_B_PRESSED 0x2000 diff --git a/include/sounds.h b/include/sounds.h index a734a103..f3a5f555 100644 --- a/include/sounds.h +++ b/include/sounds.h @@ -386,7 +386,7 @@ #define SOUND_ENV_UNK12 /* 0x40120000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x12, 0x00, 0) // unverified, unused #define SOUND_ENV_SLIDING /* 0x40130000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x13, 0x00, 0) // unverified #define SOUND_ENV_STAR /* 0x40140010 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x14, 0x00, SOUND_LOWER_BACKGROUND_MUSIC) // unverified -#define SOUND_ENV_UNKNOWN4 /* 0x41150000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x15, 0x00, SOUND_NO_VOLUME_LOSS) // unverified +#define SOUND_ENV_MOVING_BIG_PLATFORM /* 0x41150000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x15, 0x00, SOUND_NO_VOLUME_LOSS) // unverified #define SOUND_ENV_WATER_DRAIN /* 0x41160000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x16, 0x00, SOUND_NO_VOLUME_LOSS) // unverified #define SOUND_ENV_METAL_BOX_PUSH /* 0x40178000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x17, 0x80, 0) // unverified #define SOUND_ENV_SINK_QUICKSAND /* 0x40188000 */ SOUND_ARG_LOAD(SOUND_BANK_ENV, 0x18, 0x80, 0) // unverified diff --git a/include/types.h b/include/types.h index c6e801e1..5b092bb0 100644 --- a/include/types.h +++ b/include/types.h @@ -6,6 +6,7 @@ #include #include "macros.h" +#include "config.h" // Certain functions are marked as having return values, but do not @@ -30,8 +31,8 @@ struct Controller /*0x12*/ u16 buttonPressed; /*0x14*/ OSContStatus *statusData; /*0x18*/ OSContPad *controllerData; -#ifdef VERSION_SH - /*0x1C*/ int port; +#if ENABLE_RUMBLE + /*0x1C*/ s32 port; #endif }; @@ -261,27 +262,6 @@ struct MarioBodyState u8 padding[4]; }; -struct OffsetSizePair -{ - u32 offset; - u32 size; -}; - -struct MarioAnimDmaRelatedThing -{ - u32 count; - u8 *srcAddr; - struct OffsetSizePair anim[1]; // dynamic size -}; - -struct MarioAnimation -{ - struct MarioAnimDmaRelatedThing *animDmaTable; - u8 *currentAnimAddr; - struct Animation *targetAnim; - u8 padding[4]; -}; - struct MarioState { /*0x00*/ u16 unk00; @@ -327,7 +307,7 @@ struct MarioState /*0x94*/ struct PlayerCameraState *statusForCamera; /*0x98*/ struct MarioBodyState *marioBodyState; /*0x9C*/ struct Controller *controller; - /*0xA0*/ struct MarioAnimation *animation; + /*0xA0*/ struct DmaHandlerList *animList; /*0xA4*/ u32 collidedObjInteractTypes; /*0xA8*/ s16 numCoins; /*0xAA*/ s16 numStars; diff --git a/levels/intro/script.c b/levels/intro/script.c index a130cc04..04b8fc4c 100644 --- a/levels/intro/script.c +++ b/levels/intro/script.c @@ -8,7 +8,7 @@ #include "game/area.h" #include "game/level_update.h" -#include "menu/level_select_menu.h" +#include "menu/title_screen.h" #include "levels/scripts.h" #include "levels/menu/header.h" @@ -33,7 +33,7 @@ const LevelScript level_intro_splash_screen[] = { // Start animation LOAD_AREA(/*area*/ 1), - CALL(/*arg*/ 0, /*func*/ lvl_intro_update), + CALL(/*arg*/ LVL_INTRO_PLAY_ITS_A_ME_MARIO, /*func*/ lvl_intro_update), SLEEP(/*frames*/ 75), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0x00, 0x00, 0x00), SLEEP(/*frames*/ 16), @@ -59,10 +59,10 @@ const LevelScript level_intro_mario_head_regular[] = { SLEEP(/*frames*/ 2), BLACKOUT(/*active*/ FALSE), LOAD_AREA(/*area*/ 1), - SET_MENU_MUSIC(/*seq*/ 0x0002), + SET_MENU_MUSIC(/*seq*/ SEQ_MENU_TITLE_SCREEN), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_STAR, /*time*/ 20, /*color*/ 0x00, 0x00, 0x00), SLEEP(/*frames*/ 20), - CALL_LOOP(/*arg*/ 1, /*func*/ lvl_intro_update), + CALL_LOOP(/*arg*/ LVL_INTRO_REGULAR, /*func*/ lvl_intro_update), JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1), JUMP_IF(/*op*/ OP_EQ, /*arg*/ 101, script_intro_L2), JUMP(script_intro_L4), @@ -84,10 +84,10 @@ const LevelScript level_intro_mario_head_dizzy[] = { SLEEP(/*frames*/ 2), BLACKOUT(/*active*/ FALSE), LOAD_AREA(/*area*/ 1), - SET_MENU_MUSIC(/*seq*/ 0x0082), + SET_MENU_MUSIC(/*seq*/ SEQ_MENU_GAME_OVER), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_STAR, /*time*/ 20, /*color*/ 0x00, 0x00, 0x00), SLEEP(/*frames*/ 20), - CALL_LOOP(/*arg*/ 2, /*func*/ lvl_intro_update), + CALL_LOOP(/*arg*/ LVL_INTRO_GAME_OVER, /*func*/ lvl_intro_update), JUMP_IF(/*op*/ OP_EQ, /*arg*/ 100, script_intro_L1), JUMP_IF(/*op*/ OP_EQ, /*arg*/ 101, script_intro_L2), JUMP(script_intro_L4), @@ -106,10 +106,10 @@ const LevelScript level_intro_entry_4[] = { FREE_LEVEL_POOL(), LOAD_AREA(/*area*/ 1), - SET_MENU_MUSIC(/*seq*/ 0x0002), + SET_MENU_MUSIC(/*seq*/ SEQ_MENU_TITLE_SCREEN), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF), SLEEP(/*frames*/ 16), - CALL_LOOP(/*arg*/ 3, /*func*/ lvl_intro_update), + CALL_LOOP(/*arg*/ LVL_INTRO_LEVEL_SELECT, /*func*/ lvl_intro_update), JUMP_IF(/*op*/ OP_EQ, /*arg*/ -1, script_intro_L5), JUMP(script_intro_L3), }; diff --git a/levels/menu/script.c b/levels/menu/script.c index f6db65c9..25c31f00 100644 --- a/levels/menu/script.c +++ b/levels/menu/script.c @@ -43,7 +43,7 @@ const LevelScript level_main_menu_entry_1[] = { FREE_LEVEL_POOL(), LOAD_AREA(/*area*/ 1), - SET_MENU_MUSIC(/*seq*/ 0x0021), + SET_MENU_MUSIC(/*seq*/ SEQ_MENU_FILE_SELECT), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF), CALL(/*arg*/ 0, /*func*/ lvl_init_menu_values_and_cursor_pos), CALL_LOOP(/*arg*/ 0, /*func*/ lvl_update_obj_and_load_file_selected), diff --git a/levels/scripts.c b/levels/scripts.c index 3067162c..248fb83c 100644 --- a/levels/scripts.c +++ b/levels/scripts.c @@ -171,7 +171,7 @@ static const LevelScript script_exec_ ## folder [] = { \ const LevelScript script_func_global_1[] = { LOAD_MODEL_FROM_GEO(MODEL_BLUE_COIN_SWITCH, blue_coin_switch_geo), - LOAD_MODEL_FROM_GEO(MODEL_AMP, amp_geo), + LOAD_MODEL_FROM_GEO(MODEL_AMP, dAmpGeo), LOAD_MODEL_FROM_GEO(MODEL_PURPLE_SWITCH, purple_switch_geo), LOAD_MODEL_FROM_GEO(MODEL_CHECKERBOARD_PLATFORM, checkerboard_platform_geo), LOAD_MODEL_FROM_GEO(MODEL_BREAKABLE_BOX, breakable_box_geo), @@ -297,7 +297,7 @@ const LevelScript script_func_global_13[] = { LOAD_MODEL_FROM_GEO(MODEL_BOWSER_SMOKE, bowser_impact_smoke_geo), LOAD_MODEL_FROM_GEO(MODEL_BOWSER_FLAMES, bowser_flames_geo), LOAD_MODEL_FROM_GEO(MODEL_BOWSER_WAVE, invisible_bowser_accessory_geo), - LOAD_MODEL_FROM_GEO(MODEL_BOWSER2, bowser2_geo), + LOAD_MODEL_FROM_GEO(MODEL_BOWSER_NO_SHADOW, bowser_geo_no_shadow), RETURN(), }; diff --git a/lib/asm/__osDisableInt.s b/lib/asm/__osDisableInt.s index 4c759b4c..b19b8481 100644 --- a/lib/asm/__osDisableInt.s +++ b/lib/asm/__osDisableInt.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s index e14928ce..c3b97993 100644 --- a/lib/asm/__osExceptionPreamble.s +++ b/lib/asm/__osExceptionPreamble.s @@ -1,21 +1,14 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" - -.ifdef VERSION_EU -.set VERSION_EU_SH, 1 -.endif -.ifdef VERSION_SH -.set VERSION_EU_SH, 1 -.endif +#include "macros.inc" .section .text, "ax" -.ifdef AVOID_UB +#ifdef AVOID_UB .set D_80334890, D_80334890_fix -.endif +#endif glabel __osExceptionPreamble lui $k0, %hi(__osException) @@ -37,7 +30,7 @@ glabel __osException sd $t2, 0x68($k0) sw $zero, 0x18($k0) mfc0 $t0, $13 -.ifndef VERSION_EU_SH +#if !defined(VERSION_EU) && !defined(VERSION_SH) andi $t1, $t0, 0x7c li $t2, 0 bne $t1, $t2, .L80326750 @@ -62,11 +55,11 @@ glabel __osException lui $at, %hi(D_80334934) sw $zero, %lo(D_80334934)($at) lui $at, %hi(D_80334938) -.endif +#endif move $t0, $k0 -.ifndef VERSION_EU_SH +#if !defined(VERSION_EU) && !defined(VERSION_SH) sw $zero, %lo(D_80334938)($at) -.endif +#endif lui $k0, %hi(D_80334890 + 0x10) lw $k0, %lo(D_80334890 + 0x10)($k0) ld $t1, 0x20($t0) @@ -79,17 +72,17 @@ glabel __osException sd $t1, 0x60($k0) ld $t1, 0x68($t0) sd $t1, 0x68($k0) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lw $k1, 0x118($k0) -.else +#else .L80326794: -.endif +#endif mflo $t0 sd $t0, 0x108($k0) mfhi $t0 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) andi $t1, $k1, 0xff00 -.endif +#endif sd $v0, 0x28($k0) sd $v1, 0x30($k0) sd $a0, 0x38($k0) @@ -115,31 +108,31 @@ glabel __osException sd $sp, 0xf0($k0) sd $fp, 0xf8($k0) sd $ra, 0x100($k0) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) beqz $t1, .L802F3A18 sd $t0, 0x110($k0) lui $t0, %hi(__OSGlobalIntMask) addiu $t0, %lo(__OSGlobalIntMask) lw $t0, ($t0) li $at, -1 -.ifdef VERSION_EU +#ifdef VERSION_EU xor $t0, $t0, $at -.else +#else xor $t2, $t0, $at -.endif +#endif lui $at, (0xFFFF00FF >> 16) -.ifdef VERSION_EU +#ifdef VERSION_EU andi $t0, $t0, 0xFF00 -.else +#else andi $t2, $t2, 0xFF00 -.endif +#endif ori $at, (0xFFFF00FF & 0xFFFF) -.ifdef VERSION_EU +#ifdef VERSION_EU or $t1, $t1, $t0 and $k1, $k1, $at or $k1, $k1, $t1 sw $k1, 0x118($k0) -.else +#else or $t4, $t1, $t2 and $t3, $k1, $at andi $t0, $t0, 0xFF00 @@ -148,7 +141,7 @@ glabel __osException and $k1, $k1, $at sw $t3, 0x118($k0) or $k1, $k1, $t1 -.endif +#endif .L802F3A18: lui $t1, %hi(MI_INTR_MASK_REG) @@ -167,9 +160,9 @@ glabel __osException or $t1, $t1, $t0 .L802F3A50: sw $t1, 0x128($k0) -.else +#else sd $t0, 0x110($k0) -.endif +#endif mfc0 $t0, $14 sw $t0, 0x11c($k0) lw $t0, 0x18($k0) @@ -197,14 +190,14 @@ glabel __osException .L80326868: mfc0 $t0, $13 sw $t0, 0x120($k0) -.ifndef VERSION_EU_SH +#if !defined(VERSION_EU) && !defined(VERSION_SH) lui $t1, %hi(MI_INTR_MASK_REG) lw $t1, %lo(MI_INTR_MASK_REG)($t1) sw $t1, 0x128($k0) -.endif +#endif li $t1, 2 sh $t1, 0x10($k0) -.ifndef VERSION_EU_SH +#if !defined(VERSION_EU) && !defined(VERSION_SH) lui $t1, %hi(D_80334934) lw $t1, %lo(D_80334934)($t1) beqz $t1, .L803268B4 @@ -239,7 +232,7 @@ glabel __osException b .L80326E08 sw $t1, %lo(D_80334A44)($at) .L80326900: -.endif +#endif andi $t1, $t0, 0x7c li $t2, 36 beq $t1, $t2, .L80326B84 @@ -267,7 +260,7 @@ glabel __osException lw $t2, %lo(jtbl_80338630)($at) jr $t2 nop -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) glabel L802F3B28 li $at, -8193 b .L8032692C @@ -276,7 +269,7 @@ glabel L802F3B34 li $at, -16385 b .L8032692C and $s0, $s0, $at -.endif +#endif glabel L80326964 mfc0 $t1, $11 mtc0 $t1, $11 @@ -287,62 +280,62 @@ glabel L80326964 b .L8032692C and $s0, $s0, $at glabel L80326984 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) li $at, -2049 and $s0, $s0, $at -.endif +#endif li $t2, 4 lui $at, %hi(D_80334920) addu $at, $at, $t2 lw $t2, %lo(D_80334920)($at) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lui $sp, %hi(leoDiskStack) addiu $sp, %lo(leoDiskStack) li $a0, 16 beqz $t2, .L803269A4 addiu $sp, $sp, 0xff0 -.else +#else beqz $t2, .L803269A4 nop -.endif +#endif jalr $t2 nop -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) beqz $v0, .L803269A4 -.ifdef VERSION_SH +#ifdef VERSION_SH li $a0, 0x10 -.else +#else nop -.endif +#endif b .L80326B9C nop -.endif +#endif .L803269A4: jal send_mesg -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) nop b .L8032692C nop -.else +#else li $a0, 16 li $at, -2049 b .L8032692C and $s0, $s0, $at -.endif +#endif glabel L803269B8 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lui $t0, %hi(__OSGlobalIntMask) addiu $t0, %lo(__OSGlobalIntMask) lw $t0, ($t0) -.endif +#endif lui $s1, %hi(MI_INTR_REG) lw $s1, %lo(MI_INTR_REG)($s1) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) srl $t0, $t0, 0x10 and $s1, $s1, $t0 -.else +#else andi $s1, $s1, 0x3f -.endif +#endif andi $t1, $s1, 1 beqz $t1, .L80326A18 nop @@ -609,7 +602,7 @@ glabel __osEnqueueAndYield sw $k1, 0x12c($a1) .L80326D70: -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lw $k1, 0x118($a1) andi $t1, $k1, 0xff00 beqz $t1, .L802F3FBC @@ -627,10 +620,10 @@ glabel __osEnqueueAndYield or $k1, $k1, $t1 sw $k1, 0x118($a1) .L802F3FBC: -.endif +#endif lui $k1, %hi(MI_INTR_MASK_REG) lw $k1, %lo(MI_INTR_MASK_REG)($k1) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) beqz $k1, .L802F3FF4 nop lui $k0, %hi(__OSGlobalIntMask) @@ -644,7 +637,7 @@ glabel __osEnqueueAndYield and $k0, $k0, $t0 or $k1, $k1, $k0 .L802F3FF4: -.endif +#endif beqz $a0, .L80326D88 sw $k1, 0x128($a1) jal __osEnqueueThread @@ -653,7 +646,7 @@ glabel __osEnqueueAndYield j __osDispatchThread nop -#enqueue and pop look like compiled functions? but there's no easy way to extract them +// enqueue and pop look like compiled functions? but there's no easy way to extract them glabel __osEnqueueThread lw $t8, ($a0) lw $t7, 4($a1) @@ -691,7 +684,7 @@ glabel __osDispatchThread li $t0, 4 sh $t0, 0x10($v0) move $k0, $v0 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lui $t0, %hi(__OSGlobalIntMask) lw $k1, 0x118($k0) addiu $t0, %lo(__OSGlobalIntMask) @@ -704,7 +697,7 @@ glabel __osDispatchThread and $k1, $k1, $at or $k1, $k1, $t1 mtc0 $k1, $12 -.endif +#endif .L80326E08: ld $k1, 0x108($k0) ld $at, 0x20($k0) @@ -741,10 +734,10 @@ glabel __osDispatchThread ld $ra, 0x100($k0) lw $k1, 0x11c($k0) mtc0 $k1, $14 -.ifndef VERSION_EU_SH +#if !defined(VERSION_EU) && !defined(VERSION_SH) lw $k1, 0x118($k0) mtc0 $k1, $12 -.endif +#endif lw $k1, 0x18($k0) beqz $k1, .L80326EF0 nop @@ -768,13 +761,13 @@ glabel __osDispatchThread ldc1 $f30, 0x1a8($k0) .L80326EF0: lw $k1, 0x128($k0) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) lui $k0, %hi(__OSGlobalIntMask) addiu $k0, %lo(__OSGlobalIntMask) lw $k0, ($k0) srl $k0, $k0, 0x10 and $k1, $k1, $k0 -.endif +#endif sll $k1, $k1, 1 lui $k0, %hi(D_803386D0) addiu $k0, %lo(D_803386D0) @@ -820,13 +813,13 @@ glabel jtbl_80338630 .word L803269B8 .word L80326984 .word L80326AE8 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) .word L802F3B28 .word L802F3B34 -.else +#else .word L80326BE8 .word L80326BE8 -.endif +#endif .word L80326964 .word 0 .word 0 diff --git a/lib/asm/__osGetCause.s b/lib/asm/__osGetCause.s index 13fff167..56371707 100644 --- a/lib/asm/__osGetCause.s +++ b/lib/asm/__osGetCause.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osGetSR.s b/lib/asm/__osGetSR.s index e2f74c76..0ed57883 100644 --- a/lib/asm/__osGetSR.s +++ b/lib/asm/__osGetSR.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osProbeTLB.s b/lib/asm/__osProbeTLB.s index fe83ea16..5f955bc9 100644 --- a/lib/asm/__osProbeTLB.s +++ b/lib/asm/__osProbeTLB.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" @@ -44,8 +44,8 @@ glabel __osProbeTLB andi $t5, $v0, 2 beqz $t5, .L8032A0D8 nop - lui $at, (0x3FFFFFC0 >> 16) # lui $at, 0x3fff - ori $at, (0x3FFFFFC0 & 0xFFFF) # ori $at, $at, 0xffc0 + lui $at, (0x3FFFFFC0 >> 16) // lui $at, 0x3fff + ori $at, (0x3FFFFFC0 & 0xFFFF) // ori $at, $at, 0xffc0 and $v0, $v0, $at sll $v0, $v0, 6 and $t5, $a0, $t3 diff --git a/lib/asm/__osRestoreInt.s b/lib/asm/__osRestoreInt.s index f6ab98ef..9b2c80ff 100644 --- a/lib/asm/__osRestoreInt.s +++ b/lib/asm/__osRestoreInt.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osSetCompare.s b/lib/asm/__osSetCompare.s index a1dab931..2df90585 100644 --- a/lib/asm/__osSetCompare.s +++ b/lib/asm/__osSetCompare.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osSetFpcCsr.s b/lib/asm/__osSetFpcCsr.s index e644bc74..0d5e75bc 100644 --- a/lib/asm/__osSetFpcCsr.s +++ b/lib/asm/__osSetFpcCsr.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__osSetSR.s b/lib/asm/__osSetSR.s index 3fba3e66..00544244 100644 --- a/lib/asm/__osSetSR.s +++ b/lib/asm/__osSetSR.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/__os_eu_802ef550.s b/lib/asm/__os_eu_802ef550.s index 99b328e2..4f723ddb 100644 --- a/lib/asm/__os_eu_802ef550.s +++ b/lib/asm/__os_eu_802ef550.s @@ -1,12 +1,12 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 .set noat -.include "macros.inc" +#include "macros.inc" .section .text, "ax" -# cache related +// cache related glabel __os_eu_802ef550 lui $t0,0x8000 li $t2,0x2000 diff --git a/lib/asm/bcopy.s b/lib/asm/bcopy.s index 953a3d3c..e4f26909 100644 --- a/lib/asm/bcopy.s +++ b/lib/asm/bcopy.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/bzero.s b/lib/asm/bzero.s index 37053b7e..1e073acb 100644 --- a/lib/asm/bzero.s +++ b/lib/asm/bzero.s @@ -1,9 +1,9 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" -#this file is probably handwritten +// this file is probably handwritten .section .text, "ax" diff --git a/lib/asm/llmuldiv_gcc.s b/lib/asm/llmuldiv_gcc.s index cf604929..1582f878 100644 --- a/lib/asm/llmuldiv_gcc.s +++ b/lib/asm/llmuldiv_gcc.s @@ -1,9 +1,9 @@ -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +// assembler directives +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osGetCount.s b/lib/asm/osGetCount.s index 58bd3629..b47b66ae 100644 --- a/lib/asm/osGetCount.s +++ b/lib/asm/osGetCount.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osInvalDCache.s b/lib/asm/osInvalDCache.s index 452c4dd3..dca94af6 100644 --- a/lib/asm/osInvalDCache.s +++ b/lib/asm/osInvalDCache.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osInvalICache.s b/lib/asm/osInvalICache.s index 8b8a03f0..fd9ea6a7 100644 --- a/lib/asm/osInvalICache.s +++ b/lib/asm/osInvalICache.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osMapTLB.s b/lib/asm/osMapTLB.s index b9ee4364..1910cd9d 100644 --- a/lib/asm/osMapTLB.s +++ b/lib/asm/osMapTLB.s @@ -1,14 +1,14 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" -# This file is handwritten +// This file is handwritten -#void osMapTLB(s32 index, OSPageMask pm, void *vaddr, u32 evenpaddr, u32 oddpaddr, s32 asid); +// void osMapTLB(s32 index, OSPageMask pm, void *vaddr, u32 evenpaddr, u32 oddpaddr, s32 asid); glabel osMapTLB mfc0 $t0, $10 mtc0 $a0, $0 diff --git a/lib/asm/osMapTLBRdb.s b/lib/asm/osMapTLBRdb.s index 6753280d..4bcba1d1 100644 --- a/lib/asm/osMapTLBRdb.s +++ b/lib/asm/osMapTLBRdb.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osSetIntMask.s b/lib/asm/osSetIntMask.s index ce1c884d..6ea380e5 100644 --- a/lib/asm/osSetIntMask.s +++ b/lib/asm/osSetIntMask.s @@ -1,38 +1,31 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .eqv MI_INTR_MASK_REG, 0xA430000C -.ifdef VERSION_EU -.set VERSION_EU_SH, 1 -.endif -.ifdef VERSION_SH -.set VERSION_EU_SH, 1 -.endif - .section .text, "ax" glabel osSetIntMask -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) mfc0 $t4, $12 andi $v0, $t4, 0xff01 - lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8030 - addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, 0x208c + lui $t0, %hi(__OSGlobalIntMask) // $t0, 0x8030 + addiu $t0, %lo(__OSGlobalIntMask) // addiu $t0, $t0, 0x208c lw $t3, ($t0) li $at, -1 xor $t0, $t3, $at andi $t0, $t0, 0xff00 or $v0, $v0, $t0 -.else +#else mfc0 $t1, $12 andi $v0, $t1, 0xff01 -.endif - lui $t2, %hi(MI_INTR_MASK_REG) # $t2, 0xa430 +#endif + lui $t2, %hi(MI_INTR_MASK_REG) // $t2, 0xa430 lw $t2, %lo(MI_INTR_MASK_REG)($t2) -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) beqz $t2, .L80200074 srl $t1, $t3, 0x10 li $at, -1 @@ -40,36 +33,36 @@ glabel osSetIntMask andi $t1, $t1, 0x3f or $t2, $t2, $t1 .L80200074: -.endif +#endif sll $t2, $t2, 0x10 or $v0, $v0, $t2 lui $at, 0x3f and $t0, $a0, $at -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) and $t0, $t0, $t3 -.endif +#endif srl $t0, $t0, 0xf lui $t2, %hi(D_803386D0) addu $t2, $t2, $t0 lhu $t2, %lo(D_803386D0)($t2) - lui $at, %hi(MI_INTR_MASK_REG) # $at, 0xa430 + lui $at, %hi(MI_INTR_MASK_REG) // $at, 0xa430 sw $t2, %lo(MI_INTR_MASK_REG)($at) andi $t0, $a0, 0xff01 -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) andi $t1, $t3, 0xff00 and $t0, $t0, $t1 -.endif - lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff - ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -.ifdef VERSION_EU_SH +#endif + lui $at, (0xFFFF00FF >> 16) // lui $at, 0xffff + ori $at, (0xFFFF00FF & 0xFFFF) // ori $at, $at, 0xff +#if defined(VERSION_EU) || defined(VERSION_SH) and $t4, $t4, $at or $t4, $t4, $t0 mtc0 $t4, $12 -.else +#else and $t1, $t1, $at or $t1, $t1, $t0 mtc0 $t1, $12 -.endif +#endif nop nop jr $ra diff --git a/lib/asm/osUnmapTLBAll.s b/lib/asm/osUnmapTLBAll.s index 0bd9ad27..1548c162 100644 --- a/lib/asm/osUnmapTLBAll.s +++ b/lib/asm/osUnmapTLBAll.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/osWritebackDCache.s b/lib/asm/osWritebackDCache.s index 8e870168..e4a2ab0c 100644 --- a/lib/asm/osWritebackDCache.s +++ b/lib/asm/osWritebackDCache.s @@ -1,7 +1,7 @@ -.set noreorder # don't insert nops after branches +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" @@ -34,6 +34,6 @@ glabel osWritebackDCache .L80324E4C: cache 1, ($t0) bltu $t0, $t1, .L80324E4C - addiu $t0, 0x10 # addiu $t0, $t0, 0x10 + addiu $t0, 0x10 // addiu $t0, $t0, 0x10 jr $ra nop diff --git a/lib/asm/osWritebackDCacheAll.s b/lib/asm/osWritebackDCacheAll.s index 88707604..bb5fa41d 100644 --- a/lib/asm/osWritebackDCacheAll.s +++ b/lib/asm/osWritebackDCacheAll.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/asm/parameters.s b/lib/asm/parameters.s index 0314d41f..5b402250 100644 --- a/lib/asm/parameters.s +++ b/lib/asm/parameters.s @@ -1,10 +1,10 @@ .macro gsymbol sym addr .global \sym .set \sym, \addr -.ifndef VERSION_JP +#ifndef VERSION_JP nop nop -.endif +#endif .endm .text @@ -16,7 +16,7 @@ gsymbol osCiCId 0x80000310 gsymbol osVersion 0x80000314 gsymbol osMemSize 0x80000318 gsymbol osAppNmiBuffer 0x8000031C -.ifdef VERSION_SH +#ifdef VERSION_SH nop nop nop @@ -25,4 +25,4 @@ nop nop nop nop -.endif \ No newline at end of file +#endif diff --git a/lib/asm/sqrtf.s b/lib/asm/sqrtf.s index a3ce7756..70984e56 100644 --- a/lib/asm/sqrtf.s +++ b/lib/asm/sqrtf.s @@ -1,8 +1,8 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches +.set noat // allow manual use of $at +.set noreorder // don't insert nops after branches .set gp=64 -.include "macros.inc" +#include "macros.inc" .section .text, "ax" diff --git a/lib/rsp.s b/lib/rsp.s index bfc59875..a315b445 100644 --- a/lib/rsp.s +++ b/lib/rsp.s @@ -1,4 +1,4 @@ -.include "macros.inc" +#include "macros.inc" .set UCODE_SIZE, 0x800 .section .text @@ -10,22 +10,22 @@ glabel rspF3DBootStart glabel rspF3DBootEnd .balign 16 -.ifndef F3DEX_GBI_SHARED +#ifndef F3DEX_GBI_SHARED glabel rspF3DStart /* Use regular Fast3D bins (default) */ .incbin "rsp/fast3d.bin" glabel rspF3DEnd -.else /* Use one of the Fast3DEX series grucodes. */ +#else /* Use one of the Fast3DEX series grucodes. */ glabel rspF3DStart - .if F3DZEX_GBI_2 == 1 + #ifdef F3DZEX_GBI_2 .incbin "lib/PR/f3dex2/F3DZEX_NoN.bin" - .elseif F3DEX_GBI == 1 + #elif defined(F3DEX_GBI) .incbin "lib/PR/f3dex/F3DEX.bin" - .elseif F3DEX_GBI_2 == 1 + #elif defined(F3DEX_GBI_2) .incbin "lib/PR/f3dex2/F3DEX2.bin" - .endif + #endif glabel rspF3DEnd -.endif +#endif /* Audio Bins */ @@ -40,107 +40,107 @@ glabel rspAspMainEnd */ /* Fast3DEX NoN Text */ -.ifdef F3DEX_NON_GBI +#ifdef F3DEX_NON_GBI glabel rspF3DEXNoNStart .balign 16 .incbin "lib/PR/f3dex/F3DEX_NoN.bin" glabel rspF3DEXNoNEnd -.endif +#endif /* Fast3DLX Text */ -.ifdef F3DLX_GBI +#ifdef F3DLX_GBI glabel rspF3DLXStart .incbin "lib/PR/f3dex/F3DLX.bin" glabel rspF3DLXEnd -.endif +#endif /* Fast3DLX NoN Text */ -.ifdef F3DLX_NON_GBI +#ifdef F3DLX_NON_GBI glabel rspF3DLXNoNStart .balign 16 .incbin "lib/PR/f3dex/F3DLX_NoN.bin" glabel rspF3DLXNoNEnd -.endif +#endif /* Fast3DLX Rej Text */ -.ifdef F3DLX_REJ_GBI +#ifdef F3DLX_REJ_GBI glabel rspF3DLXRejStart .balign 16 .incbin "lib/PR/f3dex/F3DLX_Rej.bin" glabel rspF3DLXRejEnd -.endif +#endif /* Line3DEX Text */ -.ifdef L3DEX_GBI +#ifdef L3DEX_GBI glabel rspL3DEXStart .balign 16 .incbin "lib/PR/f3dex/L3DEX.bin" glabel rspL3DEXEnd -.endif +#endif /* S2DEX Text */ -.ifdef S2DEX_GBI +#ifdef S2DEX_GBI glabel rspS2DEXStart .balign 16 .incbin "lib/PR/s2dex/S2DEX.bin" glabel rspS2DEXEnd -.endif +#endif /* Fast3DEX2 series */ /* Fast3DEX2 NoN Text */ -.ifdef F3DEX2_NON_GBI +#ifdef F3DEX2_NON_GBI .balign 16 glabel rspF3DEX2NoNStart .incbin "lib/PR/f3dex2/F3DEX2_NoN.bin" glabel rspF3DEX2NoNEnd -.endif +#endif /* Fast3DEX2 Rej Text */ -.ifdef F3DEX2_REJ_GBI +#ifdef F3DEX2_REJ_GBI .balign 16 glabel rspF3DEX2RejStart .incbin "lib/PR/f3dex2/F3DEX2_Rej.bin" glabel rspF3DEX2RejEnd -.endif +#endif /* Line3DEX2 Text */ -.ifdef L3DEX2_GBI +#ifdef L3DEX2_GBI .balign 16 glabel rspL3DEX2Start .incbin "lib/PR/f3dex2/L3DEX2.bin" glabel rspL3DEX2End -.endif +#endif /* S2DEX2 Text */ -.ifdef S2DEX_GBI_2 +#ifdef S2DEX_GBI_2 .balign 16 glabel rspS2DEXStart .incbin "lib/PR/s2dex/S2DEX2.bin" glabel rspS2DEXEnd -.endif +#endif /* DATA SECTION START */ .section .rodata .balign 16 -.ifndef F3DEX_GBI_SHARED /* Use regular Fast3D data (default) */ +#ifndef F3DEX_GBI_SHARED /* Use regular Fast3D data (default) */ glabel rspF3DDataStart .incbin "rsp/fast3d_data.bin" glabel rspF3DDataEnd -.else /* Using one of the Fast3DEX series grucodes */ +#else /* Using one of the Fast3DEX series grucodes */ glabel rspF3DDataStart - .if F3DZEX_GBI_2 == 1 + #ifdef F3DZEX_GBI_2 .incbin "lib/PR/f3dex2/F3DZEX_NoN_data.bin" - .elseif F3DEX_GBI == 1 + #elseif F3DEX_GBI .incbin "lib/PR/f3dex/F3DEX_data.bin" - .elseif F3DEX_GBI_2 == 1 + #elseif F3DEX_GBI_2 .incbin "lib/PR/f3dex2/F3DEX2_data.bin" - .endif + #endif glabel rspF3DDataEnd -.endif +#endif /* Audio Data */ @@ -154,83 +154,83 @@ glabel rspAspMainDataEnd /* Fast3DEX Series */ /* Fast3DEX NoN Data */ -.ifdef F3DEX_NON_GBI +#ifdef F3DEX_NON_GBI .balign 16 glabel rspF3DEXNoNDataStart .incbin "lib/PR/f3dex/F3DEX_NoN_data.bin" glabel rspF3DEXNoNDataEnd -.endif +#endif /* Fast3DLX Data */ -.ifdef F3DLX_GBI +#ifdef F3DLX_GBI .balign 16 glabel rspF3DLXDataStart .incbin "lib/PR/f3dex/F3DLX_data.bin" glabel rspF3DLXDataEnd -.endif +#endif /* Fast3DLX NoN Data */ -.ifdef F3DLX_NON_GBI +#ifdef F3DLX_NON_GBI .balign 16 glabel rspF3DLXNoNDataStart .incbin "lib/PR/f3dex/F3DLX_NoN_data.bin" glabel rspF3DLXNoNDataEnd -.endif +#endif /* Fast3DLX Rej Data */ -.ifdef F3DLX_REJ_GBI +#ifdef F3DLX_REJ_GBI .balign 16 glabel rspF3DLXRejDataStart .incbin "lib/PR/f3dex/F3DLX_Rej_data.bin" glabel rspF3DLXRejDataEnd -.endif +#endif /* Line3DEX Data */ -.ifdef L3DEX_GBI +#ifdef L3DEX_GBI .balign 16 glabel rspL3DEXDataStart .incbin "lib/PR/f3dex/L3DEX_data.bin" glabel rspL3DEXDataEnd -.endif +#endif /* S2DEX Data */ -.ifdef S2DEX_GBI +#ifdef S2DEX_GBI .balign 16 glabel rspS2DEXDataStart .incbin "lib/PR/s2dex/S2DEX_data.bin" glabel rspS2DEXDataEnd -.endif +#endif /* Fast3DEX2 Series */ /* Fast3DEX2 NoN Data */ -.ifdef F3DEX2_NON_GBI +#ifdef F3DEX2_NON_GBI .balign 16 glabel rspF3DEX2NoNStart .incbin "lib/PR/f3dex2/F3DEX2_NoN_data.bin" glabel rspF3DEX2NoNEnd -.endif +#endif /* Fast3DEX2 Rej Data */ -.ifdef F3DEX2_REJ_GBI +#ifdef F3DEX2_REJ_GBI .balign 16 glabel rspF3DEX2RejStart .incbin "lib/PR/f3dex2/F3DEX2_Rej_data.bin" glabel rspF3DEX2RejEnd -.endif +#endif /* Line3DEX2 Data */ -.ifdef L3DEX2_GBI +#ifdef L3DEX2_GBI .balign 16 glabel rspL3DEX2Start .incbin "lib/PR/f3dex2/L3DEX2_data.bin" glabel rspL3DEX2End -.endif +#endif /* S2DEX2 Data */ -.ifdef S2DEX_GBI_2 +#ifdef S2DEX_GBI_2 .balign 16 glabel rspS2DEXStart .incbin "lib/PR/s2dex/S2DEX2_data.bin" glabel rspS2DEXEnd -.endif +#endif diff --git a/lib/src/__osDevMgrMain.c b/lib/src/__osDevMgrMain.c index 3f48e8fc..e31bdaa3 100644 --- a/lib/src/__osDevMgrMain.c +++ b/lib/src/__osDevMgrMain.c @@ -10,7 +10,7 @@ void __osDevMgrMain(void *args) { OSMesg dummy; s32 ret; OSMgrArgs *sp34; -#ifndef VERSION_SH +#ifdef VERSION_EU UNUSED u32 sp30; #endif u32 sp2c; @@ -19,7 +19,7 @@ void __osDevMgrMain(void *args) { #ifdef VERSION_SH u32 tmp; #endif -#ifndef VERSION_SH +#ifdef VERSION_EU sp30 = 0; #endif sp2c = 0; @@ -108,7 +108,7 @@ void __osDevMgrMain(void *args) { } if (ret == 0) { osRecvMesg(sp34->eventQueue, &em, OS_MESG_BLOCK); -#ifndef VERSION_SH +#ifdef VERSION_EU sp30 = #endif osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK); diff --git a/lib/src/contramread.c b/lib/src/contramread.c index 3043f71a..cd74bb24 100644 --- a/lib/src/contramread.c +++ b/lib/src/contramread.c @@ -2,7 +2,6 @@ #include "PR/rcp.h" #include "controller.h" -#ifdef VERSION_SH extern s32 func_8030A5C0(OSMesgQueue *, s32); void __osPackRamReadData(int channel, u16 address); @@ -87,4 +86,3 @@ void __osPackRamReadData(int channel, u16 address) { ptr += sizeof(__OSContRamReadFormat); ptr[0] = CONT_CMD_END; } -#endif diff --git a/lib/src/contramwrite.c b/lib/src/contramwrite.c index 6b83dae3..f72d6ffd 100644 --- a/lib/src/contramwrite.c +++ b/lib/src/contramwrite.c @@ -2,7 +2,6 @@ #include "PR/rcp.h" #include "controller.h" -#ifdef VERSION_SH extern s32 func_8030A5C0(OSMesgQueue *, s32); void __osPackRamWriteData(int channel, u16 address, u8 *buffer); @@ -87,4 +86,3 @@ void __osPackRamWriteData(int channel, u16 address, u8 *buffer) { ptr += sizeof(__OSContRamReadFormat); ptr[0] = CONT_CMD_END; } -#endif diff --git a/lib/src/controller.h b/lib/src/controller.h index 67182b41..518b113e 100644 --- a/lib/src/controller.h +++ b/lib/src/controller.h @@ -1,7 +1,7 @@ #ifndef _CONTROLLER_H #define _CONTROLLER_H #include "PR/os_internal.h" -#include "os.h" +#include "PR/os.h" #include "PR/rcp.h" //should go somewhere else but diff --git a/lib/src/crc.c b/lib/src/crc.c index f18dc632..f7fd3f29 100644 --- a/lib/src/crc.c +++ b/lib/src/crc.c @@ -1,6 +1,5 @@ #include "libultra_internal.h" -#ifdef VERSION_SH u8 __osContAddressCrc(u16 addr) { u8 temp; u8 temp2; @@ -45,4 +44,3 @@ u8 __osContDataCrc(u8 *data) { } return temp; } -#endif diff --git a/lib/src/epidma.c b/lib/src/epidma.c index cc46a4d4..3aa76f17 100644 --- a/lib/src/epidma.c +++ b/lib/src/epidma.c @@ -1,4 +1,5 @@ #ifdef VERSION_SH + #include "PR/os_internal.h" #include "piint.h" @@ -21,4 +22,5 @@ s32 osEPiStartDma(OSPiHandle *pihandle, OSIoMesg *mb, s32 direction) { } return ret; } + #endif diff --git a/lib/src/hardware.h b/lib/src/hardware.h index 14848ca8..564e814c 100644 --- a/lib/src/hardware.h +++ b/lib/src/hardware.h @@ -1,7 +1,7 @@ #ifndef _HARDWARE_H_ #define _HARDWARE_H_ -#define HW_REG(reg, type) *(volatile type *)(uintptr_t)(reg | 0xa0000000) +#define HW_REG(reg, type) *(volatile type *)(uintptr_t)((reg) | 0xa0000000) #define AI_DRAM_ADDR_REG 0x04500000 #define AI_LEN_REG 0x04500004 diff --git a/lib/src/kdebugserver_stack.c b/lib/src/kdebugserver_stack.c index 148e0d3f..62dd6151 100644 --- a/lib/src/kdebugserver_stack.c +++ b/lib/src/kdebugserver_stack.c @@ -1,5 +1,5 @@ #include "libultra_internal.h" -#if !defined(VERSION_SH) && !defined(VERSION_EU) +#if defined(VERSION_JP) || defined(VERSION_US) u8 D_80365E40[0x100]; #endif diff --git a/lib/src/leointerrupt.c b/lib/src/leointerrupt.c index 2aeea1e5..ee66cf0b 100644 --- a/lib/src/leointerrupt.c +++ b/lib/src/leointerrupt.c @@ -4,9 +4,10 @@ #include "piint.h" #include "osint.h" -u8 leoDiskStack[OS_PIM_STACKSIZE]; //technically should have a OS_LEO_STACKSIZE or something.. +u8 leoDiskStack[OS_PIM_STACKSIZE]; // technically should have a OS_LEO_STACKSIZE or something.. #ifdef VERSION_SH + // TODO: so many magic constants :'( static void __osLeoResume(void); static void __osLeoAbnormalResume(void); @@ -179,4 +180,5 @@ static void __osLeoResume(void) { __osEnqueueThread(&D_80334898, __osPopThread(&mq->mtqueue)); } } + #endif diff --git a/lib/src/osAiSetFrequency.c b/lib/src/osAiSetFrequency.c index 4b32658e..5cc8bc93 100644 --- a/lib/src/osAiSetFrequency.c +++ b/lib/src/osAiSetFrequency.c @@ -1,6 +1,7 @@ #include "libultra_internal.h" #include "osAi.h" #include "hardware.h" +#include "macros.h" extern s32 osViClock; @@ -29,9 +30,9 @@ s32 osAiSetFrequency(u32 freq) { #ifndef VERSION_SH // put some extra jr $ra's down there please -static void filler1(void) { +UNUSED static void filler1(void) { } -static void filler2(void) { +UNUSED static void filler2(void) { } #endif diff --git a/lib/src/osCartRomInit.c b/lib/src/osCartRomInit.c index 51602f69..84ea3b63 100644 --- a/lib/src/osCartRomInit.c +++ b/lib/src/osCartRomInit.c @@ -2,9 +2,9 @@ #include "PR/R4300.h" #include "PR/rcp.h" #include "PR/os_pi.h" -#include "os.h" +#include "PR/os.h" +#include "libultra_internal.h" -#ifdef VERSION_SH OSPiHandle CartRomHandle; OSPiHandle *osCartRomInit(void) { @@ -36,4 +36,3 @@ OSPiHandle *osCartRomInit(void) { return &CartRomHandle; } -#endif diff --git a/lib/src/osCreatePiManager.c b/lib/src/osCreatePiManager.c index 7e182b74..890cfe32 100644 --- a/lib/src/osCreatePiManager.c +++ b/lib/src/osCreatePiManager.c @@ -12,7 +12,7 @@ OSMgrArgs __osPiDevMgr = { 0 }; OSPiHandle *__osPiTable = NULL; #endif #ifdef VERSION_SH -OSPiHandle *__osCurrentHandle[2] = { &CartRomHandle, &LeoDiskHandle }; +OSPiHandle **__osCurrentHandle[2] = { &CartRomHandle, &LeoDiskHandle }; #endif OSThread piMgrThread; u32 piMgrStack[0x400]; // stack bottom diff --git a/lib/src/osDriveRomInit.c b/lib/src/osDriveRomInit.c index 930e5613..9bfc1de4 100644 --- a/lib/src/osDriveRomInit.c +++ b/lib/src/osDriveRomInit.c @@ -7,7 +7,7 @@ extern OSPiHandle *__osPiTable; extern OSPiHandle DriveRomHandle; -OSPiHandle *osDriveRomInit() { // Why is this compiled with -g??? +OSPiHandle *osDriveRomInit(void) { // Why is this compiled with -g??? UNUSED s32 sp1c = 0; u32 saveMask; @@ -32,4 +32,3 @@ OSPiHandle *osDriveRomInit() { // Why is this compiled with -g??? return &DriveRomHandle; } - diff --git a/lib/src/osEepromRead.c b/lib/src/osEepromRead.c index ea784b2c..7f3a0292 100644 --- a/lib/src/osEepromRead.c +++ b/lib/src/osEepromRead.c @@ -96,4 +96,7 @@ s32 __osPackEepReadData(u8 address) { *(unkStruct2 *) sp14 = sp8; sp14 += 0xc; *sp14 = 254; +#ifdef AVOID_UB + return 0; +#endif } diff --git a/lib/src/osEepromWrite.c b/lib/src/osEepromWrite.c index 1a86477b..67c42a59 100644 --- a/lib/src/osEepromWrite.c +++ b/lib/src/osEepromWrite.c @@ -108,6 +108,9 @@ s32 __osPackEepWriteData(u8 address, u8 *buffer) { *(unkStruct2 *) sp14 = sp8; sp14 += 0xc; *sp14 = 254; +#ifdef AVOID_UB + return 0; +#endif } s32 __osEepStatus(OSMesgQueue *a0, unkStruct *a1) { diff --git a/lib/src/osLeoDiskInit.c b/lib/src/osLeoDiskInit.c index 0507de6a..066aab8a 100644 --- a/lib/src/osLeoDiskInit.c +++ b/lib/src/osLeoDiskInit.c @@ -9,7 +9,6 @@ extern OSPiHandle *__osPiTable; OSPiHandle LeoDiskHandle; OSPiHandle *__osDiskHandle; -// some kind of piHandle init function, maybe osDriveRomInit or osCartRomInit OSPiHandle *osLeoDiskInit(void) { s32 sp1c; LeoDiskHandle.type = 2; diff --git a/lib/src/osPfsIsPlug.c b/lib/src/osPfsIsPlug.c index 9611c977..6165e329 100644 --- a/lib/src/osPfsIsPlug.c +++ b/lib/src/osPfsIsPlug.c @@ -1,8 +1,7 @@ #include "PR/os_pi.h" +#include "libultra_internal.h" #include "controller.h" -//#include "siint.h" -#ifdef VERSION_SH OSPifRam __osPfsPifRam; s32 osPfsIsPlug(OSMesgQueue *queue, u8 *pattern) { @@ -94,4 +93,3 @@ void __osPfsGetInitData(u8 *pattern, OSContStatus *data) { } *pattern = bits; } -#endif diff --git a/lib/src/osSpTaskLoadGo.c b/lib/src/osSpTaskLoadGo.c index 88392c0b..2843b442 100644 --- a/lib/src/osSpTaskLoadGo.c +++ b/lib/src/osSpTaskLoadGo.c @@ -31,7 +31,7 @@ void osSpTaskLoad(OSTask *task) { task->t.flags &= ~M_TASK_FLAG0; #ifdef VERSION_SH if (physicalTask->t.flags & M_TASK_FLAG2) { - physicalTask->t.ucode = HW_REG((uintptr_t)task->t.yield_data_ptr + 0xBFC, u64*); + physicalTask->t.ucode = (u64*)HW_REG((uintptr_t)task->t.yield_data_ptr + 0xBFC, u64*); } #endif } diff --git a/lib/src/piint.h b/lib/src/piint.h index b3fee34e..f2793962 100644 --- a/lib/src/piint.h +++ b/lib/src/piint.h @@ -3,7 +3,7 @@ #include "PR/os_internal.h" #include "PR/rcp.h" #include "PR/os_pi.h" -#include "os.h" +#include "PR/os.h" //https://github.com/LuigiBlood/64dd/wiki/Memory-Map diff --git a/lib/src/unk_shindou_file_3.c b/lib/src/unk_shindou_file_3.c index 318e4068..d18e7b3c 100644 --- a/lib/src/unk_shindou_file_3.c +++ b/lib/src/unk_shindou_file_3.c @@ -1,7 +1,6 @@ #include "libultra_internal.h" #include "controller.h" -#ifdef VERSION_SH s32 func_8030A5C0(OSMesgQueue *arg0, s32 arg1) { // TODO: This is almost certainly __osPfsGetStatus. s32 sp34 = 0; OSMesg sp30; @@ -25,4 +24,3 @@ s32 func_8030A5C0(OSMesgQueue *arg0, s32 arg1) { // TODO: This is almost certain return sp34; } -#endif diff --git a/rename_sym.sh b/rename_sym.sh index 326dcb2e..639105b6 100755 --- a/rename_sym.sh +++ b/rename_sym.sh @@ -10,4 +10,4 @@ fi #echo "Replace $1 with $2?" #read -grep -rl "$1" text/**/*.{c,h} assets/**/*.c enhancements/*.patch lib/**/*.{c,h,s} asm/**/*.s bin/**/*.c data/*.c levels/**/*.{c,h} actors/**/*.c src/**/*.{c,h} include/**/*.{h,in} undefined_syms.txt | xargs sed -i "s/\b$1\b/$2/g" +grep -rl "$1" text/**/*.{c,h} assets/**/*.c enhancements/*.patch lib/**/*.{c,h,s} asm/**/*.s bin/**/*.c data/*.c levels/**/*.{c,h} actors/**/*.{c,h} src/**/*.{c,h} include/**/*.{h,in} undefined_syms.txt | xargs sed -i "s/\b$1\b/$2/g" diff --git a/rsp/audio.s b/rsp/audio.s index b10e8dbd..901a7d0d 100644 --- a/rsp/audio.s +++ b/rsp/audio.s @@ -53,15 +53,15 @@ dispatchTable: jumpTableEntry cmd_SPNOOP jumpTableEntry cmd_SETLOOP - jumpTableEntry cmd_17e4 - jumpTableEntry cmd_INTERL + jumpTableEntry cmd_DMEMMOVE2 + jumpTableEntry cmd_DOWNSAMPLE_HALF jumpTableEntry cmd_ENVSETUP1 jumpTableEntry cmd_ENVMIXER jumpTableEntry cmd_LOADBUFF jumpTableEntry cmd_SAVEBUFF jumpTableEntry cmd_ENVSETUP2 - jumpTableEntry cmd_1b78 + jumpTableEntry cmd_S8DEC jumpTableEntry cmd_HILOGAIN jumpTableEntry cmd_1c7c @@ -938,12 +938,12 @@ cmd_RESAMPLE: .endif addi $8, $8, -8 .ifdef VERSION_SH - sdv $v16[0], 0x00($8) + sdv $v16[0], 0x00($8) .endif @@audio_c410c: lsv $v23[14], 0x08($23) // saved pitch_accumulator .ifdef VERSION_SH - ldv $v16[0], 0x00($8) + ldv $v16[0], 0x00($8) .else ldv $v16[0], 0x00($23) // saved next 4 unprocessed samples sdv $v16[0], 0x00($8) // store them before the input samples @@ -1100,8 +1100,8 @@ cmd_RESAMPLE: mtc0 $zero, SP_SEMAPHORE .ifdef VERSION_SH -cmd_17e4: - srl $t7, $k0, 16 +cmd_DMEMMOVE2: + srl $t7, $k0, 16 andi $t7, $t7, 0xff andi $t5, $k0, 0xffff srl $t6, $t9, 0x10 @@ -1150,7 +1150,7 @@ cmd_DUPLICATE: j cmd_SPNOOP nop -cmd_INTERL: +cmd_DOWNSAMPLE_HALF: andi $t4, $k0, 0xffff andi $t6, $t9, 0xffff srl $t5, $t9, 0x10 @@ -1606,24 +1606,24 @@ cmd_MIXER: j cmd_SPNOOP nop -cmd_1b78: - lhu $13, 0x0(r24) +cmd_S8DEC: + lhu $13, (audio_in_buf)(r24) vxor $v2, $v2, $v2 - lhu $14, 0x2(r24) + lhu $14, (audio_out_buf)(r24) vxor $v3, $v3, $v3 - lhu $12, 0x4(r24) + lhu $12, (audio_count)(r24) sll $17, $25, 8 - srl $17, $17, 8 - sqv $v2[0], 0x0(r14) + srl $17, $17, 8 // state addr + sqv $v2[0], 0x0(r14) // store 0 to first 16 samples if A_INIT sqv $v3[0], 0x10(r14) srl $1, $26, 16 andi $1, $1, 0x1 - bgtz $1, @audio_4001bd8 + bgtz $1, @audio_4001bd8 // A_INIT srl $1, $26, 16 andi $1, $1, 0x2 - beq $0, $1, @audio_4001bbc + beq $0, $1, @audio_4001bbc // A_LOOP addi $2, $17, 0x0 - lw $2, 0x10(r24) + lw $2, (audio_loop_value)(r24) @audio_4001bbc: addi $1, $14, 0x0 jal dma_read_start @@ -1635,10 +1635,10 @@ cmd_1b78: mtc0 $0, sp_semaphore @audio_4001bd8: addi $14, $14, 0x20 - beq $12, $0, @audio_4001c04 + beq $12, $0, @audio_4001c04 // this of very few ops allows count=0 nop @audio_4001be4: - lpv $v2[0], 0x0(r13) + lpv $v2[0], 0x0(r13) // load each byte to upper 8 bits per elem lpv $v3[0], 0x8(r13) addi $13, $13, 0x10 addi $12, $12, 0xffe0 @@ -1647,7 +1647,7 @@ cmd_1b78: bgtz $12, @audio_4001be4 addi $14, $14, 0x20 @audio_4001c04: - addi $1, $14, 0xffe0 + addi $1, $14, 0xffe0 // write last 16 samples to the state addi $2, $17, 0x0 jal dma_write_start addi $3, $0, 0x1f diff --git a/sm64.ld b/sm64.ld index f9d769db..250de7a5 100755 --- a/sm64.ld +++ b/sm64.ld @@ -3,6 +3,7 @@ OUTPUT_ARCH (mips) /* include/segments.h defines SEG_POOL_START, SEG_POOL_END, SEG_BUFFERS, * SEG_GODDARD, SEG_MAIN, SEG_ENGINE, SEG_FRAMEBUFFERS */ #include "segments.h" +#include "config.h" #define BEGIN_SEG(name, addr) \ _##name##SegmentStart = ADDR(.name); \ @@ -94,7 +95,7 @@ SECTIONS BUILD_DIR/src/game/main.o(.text); BUILD_DIR/src/game/game_init.o(.text); BUILD_DIR/src/game/sound_init.o(.text); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/src/game/rumble_init.o(.text); #endif BUILD_DIR/src/game/level_update.o(.text); @@ -144,11 +145,16 @@ SECTIONS BUILD_DIR/src/game/hud.o(.text); BUILD_DIR/src/game/obj_behaviors.o(.text); BUILD_DIR/src/game/obj_behaviors_2.o(.text); +#ifdef VERSION_SH + BUILD_DIR/src/audio/synthesis_sh.o(.text); +#else BUILD_DIR/src/audio/synthesis.o(.text); +#endif BUILD_DIR/src/audio/heap.o(.text); BUILD_DIR/src/audio/load.o(.text); #ifdef VERSION_SH - BUILD_DIR/src/audio/unk_shindou_audio_file.o(.text); + BUILD_DIR/src/audio/load_sh.o(.text); + BUILD_DIR/src/audio/port_sh.o(.text); #endif BUILD_DIR/src/audio/playback.o(.text); BUILD_DIR/src/audio/effects.o(.text); @@ -194,114 +200,115 @@ SECTIONS BUILD_DIR/libultra.a:osContStartReadData.o(.text); BUILD_DIR/libultra.a:osContInit.o(.text); BUILD_DIR/libultra.a:osEepromProbe.o(.text); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/libultra.a:motor.o(.text); #endif 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: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); #ifdef VERSION_SH - BUILD_DIR/libultra.a:osCartRomInit.o(.text) - BUILD_DIR/libultra.a:epidma.o(.text) -#else - BUILD_DIR/libultra.a:alBnkfNew.o(.text) + BUILD_DIR/libultra.a:osCartRomInit.o(.text); + BUILD_DIR/libultra.a:epidma.o(.text); #endif - BUILD_DIR/libultra.a:osAiGetLength.o(.text) - BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text) -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osGetCount.o(.text) - BUILD_DIR/libultra.a:__osDisableInt.o(.text) - BUILD_DIR/libultra.a:__osRestoreInt.o(.text) -#endif - 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) #ifdef VERSION_EU - 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:alBnkfNew.o(.text); #endif - 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:osAiGetLength.o(.text); + BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.text); +#ifdef VERSION_SH + BUILD_DIR/libultra.a:osGetCount.o(.text); + BUILD_DIR/libultra.a:__osDisableInt.o(.text); + BUILD_DIR/libultra.a:__osRestoreInt.o(.text); +#endif + 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); +#ifdef VERSION_EU + BUILD_DIR/libultra.a:__osDisableInt.o(.text); + BUILD_DIR/libultra.a:__osRestoreInt.o(.text); + BUILD_DIR/libultra.a:osGetCount.o(.text); +#endif + 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:__osViSwapContext.o(.text); #ifdef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.text) + BUILD_DIR/libultra.a:osLeoDiskInit.o(.text); #endif - 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) -#ifdef VERSION_SH - BUILD_DIR/libultra.a:osPfsIsPlug.o(.text) - BUILD_DIR/libultra.a:crc.o(.text) - BUILD_DIR/libultra.a:contramwrite.o(.text) - BUILD_DIR/libultra.a:contramread.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); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:osPfsIsPlug.o(.text); + BUILD_DIR/libultra.a:crc.o(.text); + BUILD_DIR/libultra.a:contramwrite.o(.text); + BUILD_DIR/libultra.a:contramread.o(.text); #endif - 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: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:ldiv.o(.text); BUILD_DIR/libultra.a:__osSiDeviceBusy.o(.text); #ifdef VERSION_SH - BUILD_DIR/libultra.a:leointerrupt.o(.text) + BUILD_DIR/libultra.a:leointerrupt.o(.text); #endif - BUILD_DIR/libultra.a:osSetIntMask.o(.text) - BUILD_DIR/libultra.a:osDestroyThread.o(.text) -#ifndef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.text) + BUILD_DIR/libultra.a:osSetIntMask.o(.text); + BUILD_DIR/libultra.a:osDestroyThread.o(.text); +#ifdef VERSION_EU + BUILD_DIR/libultra.a:osLeoDiskInit.o(.text); #endif - BUILD_DIR/libultra.a:__osSetCompare.o(.text) - BUILD_DIR/libultra.a:__osDequeueThread.o(.text) - BUILD_DIR/libultra.a:__osProbeTLB.o(.text) - BUILD_DIR/libultra.a:__osResetGlobalIntMask.o(.text) - BUILD_DIR/libultra.a:__osEPiRawWriteIo.o(.text) + BUILD_DIR/libultra.a:__osSetCompare.o(.text); + BUILD_DIR/libultra.a:__osDequeueThread.o(.text); + BUILD_DIR/libultra.a:__osProbeTLB.o(.text); + BUILD_DIR/libultra.a:__osResetGlobalIntMask.o(.text); + BUILD_DIR/libultra.a:__osEPiRawWriteIo.o(.text); #ifdef VERSION_SH - BUILD_DIR/libultra.a:__osEPiRawReadIo.o(.text) - BUILD_DIR/libultra.a:__osSetGlobalIntMask.o(.text) + BUILD_DIR/libultra.a:__osEPiRawReadIo.o(.text); + BUILD_DIR/libultra.a:__osSetGlobalIntMask.o(.text); #endif - BUILD_DIR/libultra.a:func_802F71F0.o(.text) -#ifdef VERSION_SH - BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text) + BUILD_DIR/libultra.a:func_802F71F0.o(.text); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text); #endif BUILD_DIR/lib/rsp.o(.text); #else @@ -335,6 +342,9 @@ SECTIONS BUILD_DIR/libultra.a:osContStartReadData.o(.text); BUILD_DIR/libultra.a:osContInit.o(.text); BUILD_DIR/libultra.a:osEepromProbe.o(.text); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:motor.o(.text); +#endif BUILD_DIR/libultra.a:llmuldiv.o(.text); BUILD_DIR/libultra.a:llmuldiv_gcc.o(.text); BUILD_DIR/libultra.a:osInvalDCache.o(.text); @@ -393,6 +403,12 @@ SECTIONS BUILD_DIR/libultra.a:__osSiRawStartDma.o(.text); BUILD_DIR/libultra.a:osSetTimer.o(.text); BUILD_DIR/libultra.a:osEepromWrite.o(.text); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:osPfsIsPlug.o(.text); + BUILD_DIR/libultra.a:crc.o(.text); + BUILD_DIR/libultra.a:contramwrite.o(.text); + BUILD_DIR/libultra.a:contramread.o(.text); +#endif BUILD_DIR/libultra.a:osJamMesg.o(.text); BUILD_DIR/libultra.a:osPiGetCmdQueue.o(.text); BUILD_DIR/libultra.a:osEepromRead.o(.text); @@ -413,6 +429,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 */ +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:unk_shindou_file_3.o(.text); +#endif BUILD_DIR/lib/rsp.o(.text); #endif @@ -421,7 +440,7 @@ SECTIONS BUILD_DIR/src/game/main.o(.data*); BUILD_DIR/src/game/game_init.o(.data*); BUILD_DIR/src/game/sound_init.o(.data*); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/src/game/rumble_init.o(.data*); #endif BUILD_DIR/src/game/level_update.o(.data*); @@ -465,18 +484,20 @@ SECTIONS /* wildcard doesn't match on EU due to files being moved to engine/ */ BUILD_DIR/src/game*.o(.data*); #endif +#ifdef VERSION_SH + BUILD_DIR/src/audio/synthesis_sh.o(.data*); +#else BUILD_DIR/src/audio/synthesis.o(.data*); - BUILD_DIR/src/audio/heap.o(.data*); -#ifndef VERSION_SH - BUILD_DIR/src/audio/load.o(.data*); #endif + BUILD_DIR/src/audio/heap.o(.data*); + BUILD_DIR/src/audio/load.o(.data*); BUILD_DIR/src/audio/playback.o(.data*); BUILD_DIR/src/audio/effects.o(.data*); BUILD_DIR/src/audio/seqplayer.o(.data*); #ifdef VERSION_SH BUILD_DIR/src/audio/data.o(.data*); BUILD_DIR/src/audio/shindou_debug_prints.o(.data*); - BUILD_DIR/src/audio/unk_shindou_audio_file.o(.data*); + BUILD_DIR/src/audio/port_sh.o(.data*); BUILD_DIR/src/audio/external.o(.data*); BUILD_DIR/src/audio/audio_session_presets_sh.o(.data*); #else @@ -492,7 +513,7 @@ SECTIONS BUILD_DIR/libultra.a:osViTable.o(.data*); BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); BUILD_DIR/libultra.a:osContInit.o(.data*); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/libultra.a:motor.o(.data*); #endif BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); @@ -510,6 +531,9 @@ SECTIONS BUILD_DIR/libultra.a:osCreatePiManager.o(.data*); BUILD_DIR/libultra.a:osInitialize.o(.data*); BUILD_DIR/libultra.a:osContInit.o(.data*); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:motor.o(.data*); +#endif BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.data*); BUILD_DIR/libultra.a:osTimer.o(.data*); BUILD_DIR/libultra.a:_Printf.o(.data*); @@ -556,8 +580,8 @@ SECTIONS BUILD_DIR/src/game/object_collision.o(.rodata*); BUILD_DIR/src/game/spawn_object.o(.rodata*); #endif - BUILD_DIR/libultra.a:__osDisableInt.o(.text) - BUILD_DIR/libultra.a:__osRestoreInt.o(.text) + BUILD_DIR/libultra.a:__osDisableInt.o(.text); + BUILD_DIR/libultra.a:__osRestoreInt.o(.text); BUILD_DIR/src/game/spawn_sound.o(.rodata*); BUILD_DIR/src/game/debug.o(.rodata*); BUILD_DIR/src/game/screen_transition.o(.rodata*); @@ -577,11 +601,15 @@ SECTIONS #if defined(VERSION_JP) || defined(VERSION_US) BUILD_DIR/src/game*.o(.rodata*); #endif +#ifdef VERSION_SH + BUILD_DIR/src/audio/synthesis_sh.o(.rodata*); + BUILD_DIR/src/audio/heap.o(.rodata*); + BUILD_DIR/src/audio/load_sh.o(.rodata*); + BUILD_DIR/src/audio/port_sh.o(.rodata*); +#else BUILD_DIR/src/audio/synthesis.o(.rodata*); BUILD_DIR/src/audio/heap.o(.rodata*); BUILD_DIR/src/audio/load.o(.rodata*); -#ifdef VERSION_SH - BUILD_DIR/src/audio/unk_shindou_audio_file.o(.rodata*); #endif BUILD_DIR/src/audio/playback.o(.rodata*); BUILD_DIR/src/audio/effects.o(.rodata*); @@ -619,8 +647,9 @@ SECTIONS #ifndef VERSION_EU BUILD_DIR/libultra.a:*.o(.rodata*); #endif + /* audio blobs, should really be moved into a separate file */ #ifdef VERSION_SH - BUILD_DIR/src/audio/load.o(.data*); + BUILD_DIR/src/audio/load_sh.o(.data*); #endif BUILD_DIR/lib/rsp.o(.rodata*); } @@ -631,7 +660,7 @@ SECTIONS BUILD_DIR/src/game/main.o(.bss*); BUILD_DIR/src/game/game_init.o(.bss*); BUILD_DIR/src/game/sound_init.o(.bss*); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/src/game/rumble_init.o(.bss*); #endif BUILD_DIR/src/game/level_update.o(.bss*); @@ -662,7 +691,7 @@ SECTIONS BUILD_DIR/src/game/ingame_menu.o(.bss*); BUILD_DIR/src/game/envfx_snow.o(.bss*); BUILD_DIR/src/game/envfx_bubbles.o(.bss*); - BUILD_DIR/src/game/macro_special_objects.o(.bss*) + BUILD_DIR/src/game/macro_special_objects.o(.bss*); BUILD_DIR/src/game/hud.o(.bss*); BUILD_DIR/src/game/obj_behaviors.o(.bss*); BUILD_DIR/src/game/obj_behaviors_2.o(.bss*); @@ -675,9 +704,9 @@ SECTIONS #endif #ifdef VERSION_SH BUILD_DIR/src/audio/globals_start.o(.bss*); - BUILD_DIR/src/audio/synthesis.o(.bss*); + BUILD_DIR/src/audio/synthesis_sh.o(.bss*); BUILD_DIR/src/audio/heap.o(.bss*); - BUILD_DIR/src/audio/load.o(.bss*); + BUILD_DIR/src/audio/load_sh.o(.bss*); BUILD_DIR/src/audio/data.o(.bss*); #endif @@ -689,23 +718,23 @@ SECTIONS BUILD_DIR/libultra.a:osCreatePiManager.o(.bss*); BUILD_DIR/libultra.a:osContStartReadData.o(.bss*); BUILD_DIR/libultra.a:osContInit.o(.bss*); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/libultra.a:motor.o(.bss*); #endif BUILD_DIR/libultra.a:guRotateF.o(.bss*); #ifdef VERSION_SH BUILD_DIR/libultra.a:osCartRomInit.o(.bss*); #endif -#ifndef VERSION_SH +#ifdef VERSION_EU BUILD_DIR/libultra.a:leointerrupt.o(.bss*); #endif BUILD_DIR/libultra.a:osTimer.o(.bss*); #ifdef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*) + BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*); #endif BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); -#ifdef VERSION_SH +#if ENABLE_RUMBLE BUILD_DIR/libultra.a:osPfsIsPlug.o(.bss*); #endif BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); @@ -713,8 +742,8 @@ SECTIONS #ifdef VERSION_SH BUILD_DIR/libultra.a:leointerrupt.o(.bss*); #endif -#ifndef VERSION_SH - BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*) +#ifdef VERSION_EU + BUILD_DIR/libultra.a:osLeoDiskInit.o(.bss*); #endif BUILD_DIR/libultra.a:_Printf.o(.bss*); BUILD_DIR/libultra.a:osAiSetNextBuffer.o(.bss*); @@ -727,11 +756,17 @@ SECTIONS BUILD_DIR/libultra.a:osInitialize.o(.bss*); BUILD_DIR/libultra.a:osContStartReadData.o(.bss*); BUILD_DIR/libultra.a:osContInit.o(.bss*); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:motor.o(.bss*); +#endif BUILD_DIR/libultra.a:guRotateF.o(.bss*); BUILD_DIR/libultra.a:osTimer.o(.bss*); BUILD_DIR/libultra.a:_Printf.o(.bss*); BUILD_DIR/libultra.a:__osPiCreateAccessQueue.o(.bss*); BUILD_DIR/libultra.a:__osSiCreateAccessQueue.o(.bss*); +#if ENABLE_RUMBLE + BUILD_DIR/libultra.a:osPfsIsPlug.o(.bss*); +#endif BUILD_DIR/libultra.a:osEepromWrite.o(.bss*); BUILD_DIR/libultra.a:kdebugserver_stack.o(.bss*); BUILD_DIR/libultra.a:kdebugserver.o(.bss*); @@ -816,7 +851,6 @@ SECTIONS __expansionRamStart = 0x80400000; ASSERT((. <= __expansionRamStart), "Error: RDRAM expanded into Expansion RAM, despite Expansion RAM not being defined.") - BEGIN_SEG(entry, 0x10000000) { BUILD_DIR/levels/entry.o(.data); @@ -867,7 +901,7 @@ SECTIONS /* 0x8016F000 21D7D0-255EC0 [386F0] */ BEGIN_SEG(goddard, SEG_GODDARD) { - BUILD_DIR/src/menu/level_select_menu.o(.text); + BUILD_DIR/src/menu/title_screen.o(.text); BUILD_DIR/src/menu/intro_geo.o(.text); BUILD_DIR/src/menu/file_select.o(.text); BUILD_DIR/src/menu/star_select.o(.text); @@ -889,8 +923,8 @@ SECTIONS BUILD_DIR/libgoddard.a:renderer.o(.text); BUILD_DIR/libgoddard.a:*.o(.text); /* data, rodata, per file */ - BUILD_DIR/src/menu/level_select_menu.o(.data*); - BUILD_DIR/src/menu/level_select_menu.o(.rodata*); + BUILD_DIR/src/menu/title_screen.o(.data*); + BUILD_DIR/src/menu/title_screen.o(.rodata*); BUILD_DIR/src/menu/intro_geo.o(.data*); BUILD_DIR/src/menu/file_select.o(.data*); BUILD_DIR/src/menu/file_select.o(.rodata*); @@ -956,14 +990,12 @@ SECTIONS { BUILD_DIR/src/buffers/buffers.o(.bss*); BUILD_DIR/src/audio/globals_start.o(.bss*); -#ifndef VERSION_SH +#ifdef VERSION_SH + BUILD_DIR/src/audio/port_sh.o(.bss*); +#else BUILD_DIR/src/audio/synthesis.o(.bss*); BUILD_DIR/src/audio/heap.o(.bss*); -#endif BUILD_DIR/src/audio/load.o(.bss*); -#ifdef VERSION_SH - BUILD_DIR/src/audio/unk_shindou_audio_file.o(.bss*); -#else BUILD_DIR/src/audio/data.o(.bss*); #endif BUILD_DIR/src/audio*.o(.bss*); @@ -974,15 +1006,14 @@ SECTIONS . = ALIGN(0x1000); #endif #ifdef VERSION_SH - . = . + 0xB000; + . += 0xB000; #endif BUILD_DIR/src/buffers/gfx_output_buffer.o(.bss*); } END_NOLOAD(buffers) -#ifndef VERSION_SH ASSERT((. <= SEG_MAIN), "Error: buffers segment extended into main") -#endif + /* 0x268020 0x268020-0 [0] */ BEGIN_SEG(intro, 0x14000000) { @@ -1094,5 +1125,3 @@ SECTIONS *(*); } } -EXTERN(osPfsIsPlug) -EXTERN(__osLeoInterrupt) diff --git a/sound/sequences/00_sound_player.s b/sound/sequences/00_sound_player.s index 68502f9c..1d1e0173 100644 --- a/sound/sequences/00_sound_player.s +++ b/sound/sequences/00_sound_player.s @@ -1,22 +1,16 @@ -.include "seq_macros.inc" +#include "seq_macros.inc" + .section .rodata .align 0 + sequence_start: - -.ifdef VERSION_SH - .set VERSION_EU_SH, 1 -.endif -.ifdef VERSION_EU - .set VERSION_EU_SH, 1 -.endif - seq_setmutebhv 0x60 seq_setmutescale 0 -.ifdef VERSION_SH +#ifdef VERSION_SH seq_setvol 100 -.else +#else seq_setvol 127 -.endif +#endif seq_settempo 120 seq_initchannels 0x3ff seq_startchannel 0, .channel0 @@ -77,7 +71,7 @@ chan_stereoheadseteffects 1 chan_setdyntable .channel59_table chan_jump .main_loop_023589 -# Main loop for standard, non-continuous sound effects +// Main loop for standard, non-continuous sound effects .main_loop_023589: chan_delay1 chan_ioreadval 0 @@ -91,17 +85,17 @@ chan_iowriteval 5 chan_ioreadval 4 chan_dyncall -# keep looping until layer 0 finishes or we are told to stop or to play something else +// keep looping until layer 0 finishes or we are told to stop or to play something else .poll_023589: chan_delay1 chan_ioreadval 0 -chan_bltz .skip_023589 # if we have a signal: - chan_beqz .force_stop_023589 # told to stop - chan_jump .start_playing_023589 # told to play something else +chan_bltz .skip_023589 // if we have a signal: + chan_beqz .force_stop_023589 // told to stop + chan_jump .start_playing_023589 // told to play something else .skip_023589: chan_testlayerfinished 0 -chan_beqz .poll_023589 # if layer 0 hasn't finished, keep polling -chan_jump .main_loop_023589 # otherwise go back to the main loop +chan_beqz .poll_023589 // if layer 0 hasn't finished, keep polling +chan_jump .main_loop_023589 // otherwise go back to the main loop .force_stop_023589: chan_freelayer 0 chan_freelayer 1 @@ -144,7 +138,7 @@ chan_stereoheadseteffects 1 chan_setdyntable .channel6_table chan_jump .main_loop_146 -# Main loop for moving, env and air sound effects, which play continuously +// Main loop for moving, env and air sound effects, which play continuously .main_loop_146: chan_delay1 chan_ioreadval 0 @@ -159,7 +153,7 @@ chan_iowriteval 5 chan_ioreadval 4 chan_dyncall -# keep looping until we are told to stop or to play something else +// keep looping until we are told to stop or to play something else .poll_146: chan_delay1 chan_ioreadval 0 @@ -181,7 +175,7 @@ chan_iowriteval 5 chan_stereoheadseteffects 1 chan_setdyntable .channel7_table -# Loop for menu sound effects +// Loop for menu sound effects .main_loop_7: chan_delay1 chan_ioreadval 0 @@ -198,19 +192,19 @@ chan_setpanmix 127 chan_ioreadval 4 chan_dyncall -# keep looping until layer 0 finishes or we are told to stop or to play something else +// keep looping until layer 0 finishes or we are told to stop or to play something else .poll_7: chan_delay1 chan_ioreadval 0 -chan_bltz .skip_7 # if we have a signal: - chan_beqz .force_stop_7 # told to stop +chan_bltz .skip_7 // if we have a signal: + chan_beqz .force_stop_7 // told to stop chan_unreservenotes - chan_jump .start_playing_7 # told to play something else + chan_jump .start_playing_7 // told to play something else .skip_7: chan_testlayerfinished 0 -chan_beqz .poll_7 # if layer 0 hasn't finished, keep polling +chan_beqz .poll_7 // if layer 0 hasn't finished, keep polling chan_unreservenotes -chan_jump .main_loop_7 # otherwise go back to the main loop +chan_jump .main_loop_7 // otherwise go back to the main loop .force_stop_7: chan_freelayer 0 chan_freelayer 1 @@ -218,7 +212,7 @@ chan_freelayer 2 chan_unreservenotes chan_jump .main_loop_7 -# Delay for a number of ticks (1-255) in an interruptible manner. +// Delay for a number of ticks (1-255) in an interruptible manner. .delay: chan_writeseq_nextinstr 0, 1 chan_loop 20 @@ -233,15 +227,15 @@ chan_end chan_setpanmix 127 chan_setvolscale 127 chan_setvibratoextent 0 -chan_ioreadval 1 # IO slots 0-3 are reset to -1 when read; restore the value +chan_ioreadval 1 // IO slots 0-3 are reset to -1 when read; restore the value chan_iowriteval 0 -chan_break # break out of the loop -chan_break # force the caller to return immediately +chan_break // break out of the loop +chan_break // force the caller to return immediately chan_end -# Set reverb in way that takes area echo level and volume into account. This -# is done by writing to IO slot 5 and letting get_sound_reverb in external.c -# do the necessary math. +// Set reverb in way that takes area echo level and volume into account. This +// is done by writing to IO slot 5 and letting get_sound_reverb in external.c +// do the necessary math. .set_reverb: chan_writeseq_nextinstr 0, 1 chan_setreverb 10 @@ -342,15 +336,15 @@ sound_ref .sound_action_bounce_off_object sound_ref .chan_7ED sound_ref .sound_action_read_sign sound_ref .chan_810 -.ifdef VERSION_JP +#ifdef VERSION_JP sound_ref .sound_action_jump_default sound_ref .sound_action_jump_default sound_ref .sound_action_jump_default -.else +#else sound_ref .chan_828 sound_ref .sound_action_intro_unk45e sound_ref .sound_action_intro_unk45f -.endif +#endif sound_ref .sound_action_heavy_landing_default sound_ref .sound_action_heavy_landing_grass sound_ref .sound_action_heavy_landing_water @@ -988,7 +982,7 @@ layer_portamento 0x81, 42, 255 layer_note1 37, 0x1e, 105 layer_end -.sound_action_climb_down_tree: # unused +.sound_action_climb_down_tree: // unused chan_setbank 0 chan_setinstr 1 chan_setlayer 0, .layer_579 @@ -999,7 +993,7 @@ layer_portamento 0x81, 44, 255 layer_note1 40, 0xb4, 100 layer_end -.chan_582: # unused +.chan_582: // unused chan_setbank 0 chan_setinstr 2 chan_setlayer 0, .layer_58A @@ -1418,8 +1412,8 @@ layer_note1 39, 0xa, 127 layer_note1 42, 0x8, 127 layer_end -.ifndef VERSION_JP - .chan_828: # unused +#ifndef VERSION_JP + .chan_828: // unused chan_setbank 7 chan_setinstr 3 chan_setlayer 0, .layer_83C @@ -1464,7 +1458,7 @@ layer_end .layer_871: layer_transpose 8 layer_jump .layer_776 -.endif +#endif .sound_action_heavy_landing_default: chan_call .heavy_landing_common @@ -2029,7 +2023,7 @@ sound_ref .sound_mario_punch_wah sound_ref .sound_mario_uh sound_ref .sound_mario_hrmm sound_ref .sound_mario_wah2 -.ifdef VERSION_JP +#ifdef VERSION_JP sound_ref .sound_mario_jump_hoo sound_ref .sound_mario_jump_hoo sound_ref .sound_mario_jump_hoo @@ -2046,7 +2040,7 @@ sound_ref .sound_mario_wah2 sound_ref .sound_mario_jump_hoo sound_ref .sound_mario_jump_hoo sound_ref .sound_mario_jump_hoo -.else +#else sound_ref .sound_peach_dear_mario sound_ref .sound_mario_jump_hoo sound_ref .sound_mario_jump_hoo @@ -2071,7 +2065,7 @@ sound_ref .sound_mario_wah2 sound_ref .sound_peach_bake_a_cake sound_ref .sound_peach_for_mario sound_ref .sound_peach_mario2 -.endif +#endif .sound_mario_jump_hoo: chan_setbank 8 @@ -2080,9 +2074,9 @@ chan_setlayer 0, .layer_C3C chan_end .layer_C3C: -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) layer_transpose 2 -.endif +#endif layer_portamento 0x82, 41, 127 layer_note1 37, 0x14, 127 layer_end @@ -2119,9 +2113,9 @@ chan_setlayer 0, .layer_C6C chan_end .layer_C6C: -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) layer_transpose 1 -.endif +#endif layer_portamento 0x82, 44, 200 layer_note1 39, 0x30, 127 layer_end @@ -2482,7 +2476,7 @@ chan_end layer_transpose -1 layer_jump .layer_C4E -.ifndef VERSION_JP +#ifndef VERSION_JP .sound_peach_dear_mario: chan_setbank 10 chan_setinstr 15 @@ -2697,9 +2691,9 @@ layer_jump .layer_C4E .layer_F8A: layer_note1 39, 0x50, 127 layer_end -.endif +#endif -.ifdef VERSION_EU_SH +#if defined(VERSION_EU) || defined(VERSION_SH) .chan_unused_F9A_eu: chan_setbank 8 chan_setinstr 0 @@ -2709,7 +2703,7 @@ layer_jump .layer_C4E .layer_FA2_eu: layer_delay 0x5 layer_end -.endif +#endif .channel38_table: sound_ref .sound_general_activate_cap_switch @@ -2830,7 +2824,7 @@ sound_ref .sound_general_boing3 sound_ref .sound_general_grand_star sound_ref .sound_general_grand_star_jump sound_ref .sound_general_boat_rock -.ifdef VERSION_JP +#ifdef VERSION_JP sound_ref .sound_menu_enter_hole sound_ref .sound_menu_enter_hole sound_ref .sound_menu_enter_hole @@ -2841,7 +2835,7 @@ sound_ref .sound_general_boat_rock sound_ref .sound_general_bubbles sound_ref .sound_menu_enter_hole sound_ref .sound_menu_enter_hole -.else +#else sound_ref .sound_general_vanish_sfx sound_ref .sound_menu_enter_hole sound_ref .sound_general_red_coin @@ -2852,7 +2846,7 @@ sound_ref .sound_general_boat_rock sound_ref .sound_general_boing2 sound_ref .sound_general_yoshi_walk sound_ref .sound_general_enemy_alert1 -.endif +#endif .sound_general_activate_cap_switch: chan_setbank 5 @@ -3408,17 +3402,17 @@ chan_setbank 9 chan_setinstr 3 chan_setval 40 chan_call .set_reverb -.ifdef VERSION_SH +#ifdef VERSION_SH chan_setreverb 40 -.endif +#endif chan_setlayer 0, .layer_141A chan_end .layer_141A: layer_transpose 24 -.ifdef VERSION_SH +#ifdef VERSION_SH layer_note1 51, 0xc, 90 -.endif +#endif layer_note1 39, 0x4, 90 layer_note1 51, 0xc, 90 layer_note1 39, 0x4, 50 @@ -3487,18 +3481,18 @@ layer_end .sound_general_chain_chomp2: chan_setbank 7 -.ifdef VERSION_JP +#ifdef VERSION_JP chan_setinstr 8 -.else +#else chan_setinstr 14 -.endif +#endif chan_setval 15 chan_call .set_reverb chan_setlayer 0, .layer_14C6 chan_setlayer 1, .layer_14E3 -.ifndef VERSION_JP +#ifndef VERSION_JP chan_setlayer 2, .layer_14E3 -.endif +#endif chan_setval 1 chan_call .delay chan_setenvelope .envelope_3368 @@ -3507,11 +3501,11 @@ chan_setinstr 7 chan_setval 13 chan_call .delay chan_setbank 7 -.ifdef VERSION_JP +#ifdef VERSION_JP chan_setinstr 8 -.else +#else chan_setinstr 14 -.endif +#endif chan_end .layer_14C6: @@ -3527,12 +3521,12 @@ layer_end .layer_14E3: layer_loop 2 -.ifdef VERSION_JP +#ifdef VERSION_JP layer_portamento 0x81, 36, 255 layer_note1 24, 0x18, 127 -.else +#else layer_note1 34, 0x19, 100 -.endif +#endif layer_loopend layer_end @@ -4154,24 +4148,27 @@ layer_note1 31, 0x14, 127 layer_end .sound_general_red_coin: -.ifdef VERSION_JP +#ifdef VERSION_JP chan_setbank 9 chan_setinstr 3 chan_setlayer 0, .layer_1909 chan_setlayer 1, .layer_1902 chan_setlayer 2, .layer_1907 -.else - .ifdef VERSION_EU_SH +#else + #if defined(VERSION_EU) || defined(VERSION_SH) chan_setbank 9 chan_setinstr 3 - .else + #else chan_setinstr 128 - .endif + #endif chan_setenvelope .envelope_3378 + // Small bugfix: .main_loop_023589 expects layer 0 to live the longest. + // I don't think this actually makes any audible difference given the + // silence at the end. chan_setlayer 0, .layer_1907 chan_setlayer 1, .layer_1902 chan_setlayer 2, .layer_1909 -.endif +#endif chan_end .layer_1902: @@ -4191,6 +4188,12 @@ layer_note0 58, 0x10, 100, 80 layer_note0 58, 0x10, 60, 80 layer_note0 58, 0x10, 40, 80 layer_note0 58, 0x10, 25, 80 +// This small delay should not have any effect, but decreases the probability of +// encountering double red coin glitch. Without it, layer 0 finishes in 1.04 +// seconds, and with some bad luck around scheduling/lag the sound spawner with +// a lifetime of 30 frames that creates the sound may deactivate on the same +// frame. That leads to double sound glitch on JP, see src/audio/external.c. +// With the delay, the same thing can still happen but requires more CPU lag. layer_delay 0xa layer_end @@ -4422,7 +4425,7 @@ layer_portamento 0x81, 36, 40 layer_note1 41, 0xc, 127 layer_end -.ifdef VERSION_JP +#ifdef VERSION_JP .sound_general_boat_rock: chan_setbank 9 chan_setinstr 0 @@ -4438,7 +4441,7 @@ layer_end layer_portamento 0x1, 32, 0x7f layer_note1 60, 0x28, 100 layer_end -.else +#else .sound_general_boat_rock: chan_setbank 4 chan_setinstr 2 @@ -4476,7 +4479,7 @@ layer_end layer_portamento 0x81, 19, 255 layer_note1 31, 0x32, 115 layer_end -.endif +#endif .channel4_table: sound_ref .sound_env_waterfall1 @@ -4525,21 +4528,21 @@ chan_setbank 5 chan_setinstr 1 chan_setval 25 chan_call .set_reverb -.ifdef VERSION_JP +#ifdef VERSION_JP chan_setenvelope .envelope_32E4 -.else +#else chan_setenvelope .envelope_32C4 -.endif +#endif chan_setlayer 0, .layer_1B53 chan_end .layer_1B53: layer_somethingon -.ifdef VERSION_JP +#ifdef VERSION_JP layer_delay 0x6 -.else +#else layer_delay 0x4 -.endif +#endif .layer_1B56: layer_note1 41, 0x12c, 95 layer_jump .layer_1B56 @@ -4694,11 +4697,11 @@ chan_end .layer_1C69: layer_portamento 0x81, 15, 255 -.ifdef VERSION_JP +#ifdef VERSION_JP layer_note1 11, 0x1f4, 100 -.else +#else layer_note1 11, 0x1f4, 127 -.endif +#endif layer_end .sound_env_elevator3: @@ -5374,11 +5377,11 @@ chan_end .layer_20D2: layer_portamento 0x81, 44, 255 -.ifdef VERSION_JP +#ifdef VERSION_JP layer_note1 36, 0x18, 90 -.else +#else layer_note1 36, 0x18, 115 -.endif +#endif layer_delay 0x32 layer_end @@ -5398,13 +5401,13 @@ layer_note1 31, 0x26, 127 layer_end .layer_20F4: -.ifdef VERSION_JP +#ifdef VERSION_JP layer_note1 38, 0x8, 120 layer_note1 33, 0x1e, 120 -.else +#else layer_note1 38, 0x8, 127 layer_note1 33, 0x1e, 127 -.endif +#endif layer_end .sound_obj_bully_metal: @@ -6989,7 +6992,7 @@ sound_ref .sound_menu_thank_you_playing_my_game sound_ref .sound_menu_read_a_sign sound_ref .sound_menu_exit_a_sign sound_ref .sound_menu_mario_castle_warp2 -.ifdef VERSION_JP +#ifdef VERSION_JP sound_ref .sound_menu_message_next_page sound_ref .sound_menu_coin_its_a_me_mario sound_ref .sound_menu_yoshi_gain_lives @@ -7003,7 +7006,7 @@ sound_ref .sound_menu_mario_castle_warp2 sound_ref .sound_menu_mario_castle_warp sound_ref .sound_menu_star_sound sound_ref .sound_menu_change_select -.else +#else sound_ref .sound_menu_star_sound_okey_dokey sound_ref .sound_menu_star_sound_lets_a_go sound_ref .sound_menu_yoshi_gain_lives @@ -7033,7 +7036,7 @@ sound_ref .sound_menu_mario_castle_warp2 sound_ref .sound_menu_power_meter sound_ref .sound_menu_camera_buzz sound_ref .sound_menu_camera_turn -.endif +#endif .sound_menu_change_select: chan_setbank 9 @@ -7506,13 +7509,13 @@ layer_end chan_reservenotes 4 chan_setbank 9 chan_setinstr 2 -.ifdef VERSION_SH +#ifdef VERSION_SH chan_setval 15 .set EXIT_PIPE_NOTE_VELOCITY, 106 -.else +#else chan_setval 30 .set EXIT_PIPE_NOTE_VELOCITY, 126 -.endif +#endif chan_call .set_reverb chan_setenvelope .envelope_3464 chan_setdecayrelease 220 @@ -7774,7 +7777,7 @@ chan_setlayer 0, .layer_3041 chan_setlayer 1, .layer_2FC9 chan_end -.ifndef VERSION_JP +#ifndef VERSION_JP .sound_menu_star_sound_okey_dokey: chan_setbank 4 chan_setinstr 14 @@ -7828,33 +7831,33 @@ chan_end .layer_3146: layer_delay 0x6 - .ifdef VERSION_SH + #ifdef VERSION_SH .set RED_COIN_NOTE_VELOCITY_SUB, 10 - .else + #else .set RED_COIN_NOTE_VELOCITY_SUB, 0 - .endif + #endif .layer_3148: layer_call .transpose_by_coin_index - layer_note0 46, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 45, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 46, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 58, 0x10, 80 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 58, 0x10, 45 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 58, 0x10, 20 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 58, 0x10, 15 - RED_COIN_NOTE_VELOCITY_SUB, 80 + layer_note0 46, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 45, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 46, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 58, 0x10, (80 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 58, 0x10, (45 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 58, 0x10, (20 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 58, 0x10, (15 - RED_COIN_NOTE_VELOCITY_SUB), 80 layer_end .layer_3168: layer_call .transpose_by_coin_index - layer_note0 41, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 40, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 41, 0xc, 75 - RED_COIN_NOTE_VELOCITY_SUB, 20 - layer_note0 53, 0x10, 80 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 53, 0x10, 45 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 53, 0x10, 20 - RED_COIN_NOTE_VELOCITY_SUB, 80 - layer_note0 53, 0x10, 15 - RED_COIN_NOTE_VELOCITY_SUB, 80 + layer_note0 41, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 40, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 41, 0xc, (75 - RED_COIN_NOTE_VELOCITY_SUB), 20 + layer_note0 53, 0x10, (80 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 53, 0x10, (45 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 53, 0x10, (20 - RED_COIN_NOTE_VELOCITY_SUB), 80 + layer_note0 53, 0x10, (15 - RED_COIN_NOTE_VELOCITY_SUB), 80 layer_end .transpose_by_coin_index: @@ -7877,7 +7880,7 @@ chan_end layer_transpose 0 layer_note1 32, 0x7f, 115 layer_end -.endif +#endif .sound_general_bird_chirp2: chan_setbank 5 @@ -8084,14 +8087,14 @@ envelope_line 1 32700 envelope_line 10 0 envelope_goto 2 -.ifndef VERSION_JP +#ifndef VERSION_JP .envelope_3378: envelope_line 3 32700 envelope_line 10 30000 envelope_line 10 10000 envelope_line 100 0 envelope_goto 3 -.endif +#endif .envelope_338C: envelope_line 1 32700 @@ -8150,11 +8153,11 @@ envelope_goto 2 .envelope_341C: envelope_line 25 32760 envelope_line 60 10000 -.ifdef VERSION_SH +#ifdef VERSION_SH envelope_hang -.else +#else envelope_goto 2 -.endif +#endif .envelope_3428: envelope_line 1 10000 diff --git a/src/audio/data.c b/src/audio/data.c index 3817c7ab..f8495bbb 100644 --- a/src/audio/data.c +++ b/src/audio/data.c @@ -877,12 +877,6 @@ u16 unk_sh_data_4[] = { 0x5FFF, 0x9001, 0x7FFF, 0x8001 }; - -char shindouDebugPrint1[] = "Terminate-Canceled Channel %d,Phase %d\n"; -char shindouDebugPrint2[] = "S->W\n"; -char shindouDebugPrint3[] = "W->S\n"; -char shindouDebugPrint4[] = "S-Resample Pitch %x (old %d -> delay %d)\n"; -// These debug prints are continued in shindou_debug_prints_1.c. #endif #ifndef VERSION_SH diff --git a/src/audio/external.c b/src/audio/external.c index eb5c3d7e..a5edb5be 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -485,15 +485,9 @@ void unused_8031E4F0(void) { stubbed_printf("\n"); stubbed_printf("BNK "); -#ifdef VERSION_SH -#define count 1 -#else -#define count 4 -#endif - for (i = 0; i < 40; i += count) { + for (i = 0; i < 40; i += 4) { stubbed_printf("%1x", 0); } -#undef count stubbed_printf("\n"); stubbed_printf("FIXHEAP "); @@ -1157,8 +1151,8 @@ static void select_current_sounds(u8 bank) { } /** - * Given an x and z coordinates, return the pan. This is a value between 0 and - * 1 that represents the audio direction. + * Given x and z coordinates, return the pan. This is a value nominally between + * 0 and 1 that represents the audio direction. * * Pan: * 0.0 - fully left @@ -1192,12 +1186,17 @@ static f32 get_sound_pan(f32 x, f32 z) { pan = US_FLOAT(0.5); } else if (x >= US_FLOAT(0.0) && absX >= absZ) { // far right pan - pan = US_FLOAT(1.0) - (US_FLOAT(44000.0) - absX) / (US_FLOAT(3.0) * (US_FLOAT(44000.0) - absZ)); + pan = US_FLOAT(1.0) - (2 * AUDIO_MAX_DISTANCE - absX) / (US_FLOAT(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); } else if (x < 0 && absX > absZ) { // far left pan - pan = (US_FLOAT(44000.0) - absX) / (US_FLOAT(3.0) * (US_FLOAT(44000.0) - absZ)); + pan = (2 * AUDIO_MAX_DISTANCE - absX) / (US_FLOAT(3.0) * (2 * AUDIO_MAX_DISTANCE - absZ)); } else { // center pan + //! @bug (JP PU sound glitch) If |x|, |z| > AUDIO_MAX_DISTANCE, we'll + // end up in this case, and pan may be set to something outside of [0,1] + // since x is not clamped. On JP, this can lead to an out-of-bounds + // float read in note_set_vel_pan_reverb when x is highly negative, + // causing console crashes when that float is a nan or denormal. pan = 0.5 + x / (US_FLOAT(6.0) * absZ); } @@ -1243,6 +1242,8 @@ static f32 get_sound_volume(u8 bank, u8 soundIndex, f32 volumeRange) { if (sSoundBanks[bank][soundIndex].soundBits & SOUND_VIBRATO) { #ifdef VERSION_JP + //! @bug Intensity is 0 when the sound is far away. Due to the subtraction below, it is possible to end up with a negative intensity. + // When it is, objects with a volumeRange of 1 can still occasionally be lightly heard. if (intensity != 0.0) #else if (intensity >= 0.08f) @@ -1444,7 +1445,7 @@ static void update_game_sound(void) { func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); #else - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); #endif @@ -1485,7 +1486,7 @@ static void update_game_sound(void) { *sSoundBanks[bank][soundIndex].z); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = get_sound_freq_scale(bank, soundIndex); - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); #endif break; @@ -1508,7 +1509,7 @@ static void update_game_sound(void) { func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK2); @@ -1524,6 +1525,13 @@ static void update_game_sound(void) { #ifdef VERSION_JP // If the sound was marked for deletion (bits set to NO_SOUND), then stop playing it // and delete it + // @bug (JP double red coin sound) If the sound finished within the same frame as + // being marked for deletion, the signal to stop playing will be interpreted as a + // signal to *start* playing, as .main_loop_023589 in 00_sound_player does not check + // for soundScriptIO[0] being zero. This happens most commonly for red coin sounds + // whose sound spawners deactivate 30 frames after the sound starts to play, while + // the sound itself runs for 1.20 seconds. With enough lag these may coincide. + // Fixed on US by checking that layer0->finished is FALSE. else if (soundStatus == SOUND_STATUS_STOPPED) { update_background_music_after_sound(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[0] = 0; @@ -1535,17 +1543,19 @@ static void update_game_sound(void) { sSoundBanks[bank][soundIndex].soundStatus = SOUND_STATUS_STOPPED; delete_sound_from_bank(bank, soundIndex); } else if (soundStatus == SOUND_STATUS_STOPPED - && gSequencePlayers[SEQ_PLAYER_SFX] - .channels[channelIndex] - ->layers[0] - ->finished - == FALSE) { + && gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex] + ->layers[0]->finished == FALSE) { update_background_music_after_sound(bank, soundIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[0] = 0; delete_sound_from_bank(bank, soundIndex); } #endif // If sound has finished playing, then delete it + // @bug (JP sound glitch) On JP, ...->layers[0] has not been checked for null, + // so this access can crash if an earlier layer allocation failed due to too + // many sounds playing at once. This crash is comparatively common; RTA + // speedrunners even have a setup for avoiding it within the SSL pyramid: + // https://www.youtube.com/watch?v=QetyTgbQxcw else if (gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->layers[0]->enabled == FALSE) { update_background_music_after_sound(bank, soundIndex); @@ -1619,7 +1629,7 @@ static void update_game_sound(void) { func_802ad770(0x05020000 | ((channelIndex & 0xff) << 8), get_sound_reverb(bank, soundIndex, channelIndex)); #else - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); #endif @@ -1660,7 +1670,7 @@ static void update_game_sound(void) { *sSoundBanks[bank][soundIndex].z); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->freqScale = get_sound_freq_scale(bank, soundIndex); - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); #endif break; @@ -1683,7 +1693,7 @@ static void update_game_sound(void) { func_802ad728(0x04020000 | ((channelIndex & 0xff) << 8), get_sound_freq_scale(bank, soundIndex)); #else - gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverb = + gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->reverbVol = get_sound_reverb(bank, soundIndex, channelIndex); gSequencePlayers[SEQ_PLAYER_SFX].channels[channelIndex]->volume = get_sound_volume(bank, soundIndex, VOLUME_RANGE_UNK2); diff --git a/src/audio/external.h b/src/audio/external.h index ea33ceb7..d2e59b1a 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -27,9 +27,6 @@ extern u32 gAudioRandom; extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP struct SPTask *create_next_audio_frame_task(void); -#ifdef VERSION_SH -struct SPTask *func_sh_802f5a80(void); -#endif void play_sound(s32 soundBits, f32 *pos); void audio_signal_game_loop_tick(void); void seq_player_fade_out(u8 player, u16 fadeDuration); diff --git a/src/audio/heap.c b/src/audio/heap.c index 357855f3..08db2ead 100644 --- a/src/audio/heap.c +++ b/src/audio/heap.c @@ -206,8 +206,6 @@ void discard_bank(s32 bankId) { #if defined(VERSION_EU) if (note->noteSubEu.bankId == bankId) { -#elif defined(VERSION_SH) - if (note->unkSH33 == bankId) { #else if (note->bankId == bankId) { #endif @@ -384,7 +382,7 @@ void temporary_pools_init(struct PoolSplit *a) { #undef SOUND_ALLOC_FUNC #if defined(VERSION_JP) || defined(VERSION_US) -static void unused_803163D4(void) { +UNUSED static void unused_803163D4(void) { } #endif @@ -512,7 +510,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg if (poolIdx == 1) { if (firstVal == SOUND_LOAD_STATUS_4) { for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].unkSH33 == tp->entries[0].id && gNotes[i].noteSubEu.enabled) { + if (gNotes[i].bankId == tp->entries[0].id && gNotes[i].noteSubEu.enabled) { break; } } @@ -525,7 +523,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } if (secondVal == SOUND_LOAD_STATUS_4) { for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].unkSH33 == tp->entries[1].id && gNotes[i].noteSubEu.enabled) { + if (gNotes[i].bankId == tp->entries[1].id && gNotes[i].noteSubEu.enabled) { break; } } @@ -591,7 +589,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } else if (poolIdx == 1) { if (firstVal == SOUND_LOAD_STATUS_COMPLETE) { for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].unkSH33 == tp->entries[0].id && gNotes[i].noteSubEu.enabled) { + if (gNotes[i].bankId == tp->entries[0].id && gNotes[i].noteSubEu.enabled) { break; } } @@ -602,7 +600,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg } if (secondVal == SOUND_LOAD_STATUS_COMPLETE) { for (i = 0; i < gMaxSimultaneousNotes; i++) { - if (gNotes[i].unkSH33 == tp->entries[1].id && gNotes[i].noteSubEu.enabled) { + if (gNotes[i].bankId == tp->entries[1].id && gNotes[i].noteSubEu.enabled) { break; } } @@ -1681,7 +1679,7 @@ void func_sh_802f23ec(void) { s32 i; s32 idx; s32 seqCount; - u32 bankId1; // non symmetric fake match? can also change 0xff to 0xffU for same effect + s32 bankId1; s32 bankId2; s32 instId; s32 drumId; @@ -1694,7 +1692,7 @@ void func_sh_802f23ec(void) { for (idx = 0; idx < seqCount; idx++) { bankId1 = gCtlEntries[idx].bankId1; bankId2 = gCtlEntries[idx].bankId2; - if ((bankId1 != 0xff && entry->bankId == bankId1) || (bankId2 != 0xff && entry->bankId == bankId2) || entry->bankId == 0) { + if ((bankId1 != 0xffu && entry->bankId == bankId1) || (bankId2 != 0xff && entry->bankId == bankId2) || entry->bankId == 0) { if (get_bank_or_seq(1, 3, idx) != NULL) { if (IS_BANK_LOAD_COMPLETE(idx) != FALSE) { for (i = 0; i < gUnkPool2.numEntries; i++) { diff --git a/src/audio/heap.h b/src/audio/heap.h index e01dc8d4..4bc73bd3 100644 --- a/src/audio/heap.h +++ b/src/audio/heap.h @@ -131,12 +131,14 @@ void audio_reset_session(void); #else void audio_reset_session(struct AudioSessionSettings *preset); #endif +void discard_bank(s32 bankId); #ifdef VERSION_SH void fill_filter(s16 filter[8], s32 arg1, s32 arg2); u8 *func_sh_802f1d40(u32 size, s32 bank, u8 *arg2, s8 medium); u8 *func_sh_802f1d90(u32 size, s32 bank, u8 *arg2, s8 medium); void *unk_pool1_lookup(s32 poolIdx, s32 id); +void *unk_pool1_alloc(s32 poolIndex, s32 arg1, u32 size); #endif #endif // AUDIO_HEAP_H diff --git a/src/audio/internal.h b/src/audio/internal.h index a834532f..0924e073 100644 --- a/src/audio/internal.h +++ b/src/audio/internal.h @@ -41,6 +41,11 @@ #define TATUMS_PER_BEAT 48 +// abi.h contains more details about the ADPCM and S8 codecs, "skip" skips codec processing +#define CODEC_ADPCM 0 +#define CODEC_S8 1 +#define CODEC_SKIP 2 + #ifdef VERSION_JP #define TEMPO_SCALE 1 #else @@ -373,8 +378,8 @@ union ReverbBits { /* 0x00 */ u8 asByte; }; struct ReverbInfo { - u8 reverb; - u8 bankId; + u8 reverbVol; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 u8 pan; union ReverbBits reverbBits; f32 freqScale; @@ -385,9 +390,9 @@ struct ReverbInfo { struct NoteAttributes { - u8 reverb; + u8 reverbVol; #ifdef VERSION_SH - u8 unk1; + u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 #endif #if defined(VERSION_EU) || defined(VERSION_SH) u8 pan; @@ -430,7 +435,7 @@ struct SequenceChannel #endif /*0x01, 0x02*/ u8 noteAllocPolicy; /*0x02, 0x03, 0x03*/ u8 muteBehavior; - /*0x03, 0x04, 0x04*/ u8 reverb; // or dry/wet mix + /*0x03, 0x04, 0x04*/ u8 reverbVol; // until EU: Q1.7, after EU: UQ0.8 /*0x04, ????*/ u8 notePriority; // 0-3 #ifdef VERSION_SH u8 unkSH06; // some priority @@ -445,7 +450,7 @@ struct SequenceChannel /*0x06, */ u8 updatesPerFrameUnused; #endif #ifdef VERSION_SH - /* 0x0C*/ u8 unkSH0C; // bankId + /* 0x0C*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 #endif /*0x08, 0x0C, 0x0E*/ u16 vibratoRateStart; // initially 0x800 /*0x0A, 0x0E, 0x10*/ u16 vibratoExtentStart; @@ -521,7 +526,7 @@ struct SequenceChannelLayer // 0..0x3f; this makes 0x40..0x7f accessible as well) /*0x20, 0x24, 0x24*/ f32 freqScale; #ifdef VERSION_SH - /* 0x28*/ f32 unkSH28; + /* 0x28*/ f32 freqScaleMultiplier; #endif /*0x24, 0x28, 0x2C*/ f32 velocitySquare; #if defined(VERSION_JP) || defined(VERSION_US) @@ -562,8 +567,8 @@ struct NoteSynthesisState /*0x04, 0x06*/ u16 samplePosFrac; /*0x08*/ s32 samplePosInt; /*0x0C*/ struct NoteSynthesisBuffers *synthesisBuffers; - /*0x10*/ s16 curVolLeft; - /*0x12*/ s16 curVolRight; + /*0x10*/ s16 curVolLeft; // UQ0.16 (EU Q1.15) + /*0x12*/ s16 curVolRight; // UQ0.16 (EU Q1.15) }; struct NotePlaybackState { @@ -572,7 +577,7 @@ struct NotePlaybackState /* 0x01, 0x01*/ u8 waveId; /* 0x02, 0x02*/ u8 sampleCountIndex; #ifdef VERSION_SH - /* 0x03*/ u8 unkSH33; // bankId? + /* 0x03*/ u8 bankId; /* 0x04*/ u8 unkSH34; #endif /*0x08, 0x04, 0x06*/ s16 adsrVolScale; @@ -600,12 +605,16 @@ struct NoteSubEu /*0x01*/ u8 bookOffset : 3; /*0x01*/ u8 isSyntheticWave : 1; /*0x01*/ u8 hasTwoAdpcmParts : 1; +#ifdef VERSION_EU /*0x02*/ u8 bankId; +#else + /*0x02*/ u8 synthesisVolume; // UQ4.4, although 0 <= x < 1 is rounded up to 1 +#endif /*0x03*/ u8 headsetPanRight; /*0x04*/ u8 headsetPanLeft; - /*0x05*/ u8 reverbVol; - /*0x06*/ u16 targetVolLeft; - /*0x08*/ u16 targetVolRight; + /*0x05*/ u8 reverbVol; // UQ0.7 (EU Q1.7) + /*0x06*/ u16 targetVolLeft; // UQ0.12 (EU UQ0.10) + /*0x08*/ u16 targetVolRight; // UQ0.12 (EU UQ0.10) /*0x0A*/ u16 resamplingRateFixedPoint; // stored as signed but loaded as u16 /*0x0C*/ union { s16 *samples; @@ -633,7 +642,7 @@ struct Note /* 0x31, 0x31*/ u8 waveId; /* 0x32, 0x32*/ u8 sampleCountIndex; #ifdef VERSION_SH - /* 0x33*/ u8 unkSH33; // bankId? + /* 0x33*/ u8 bankId; /* 0x34*/ u8 unkSH34; #endif /*0x08, 0x34, 0x36*/ s16 adsrVolScale; @@ -691,17 +700,17 @@ struct Note /*0x30, 0x48*/ struct SequenceChannelLayer *wantedParentLayer; /*0x34*/ struct NoteSynthesisBuffers *synthesisBuffers; /*0x38*/ f32 frequency; - /*0x3C*/ u16 targetVolLeft; - /*0x3E*/ u16 targetVolRight; - /*0x40*/ u8 reverb; + /*0x3C*/ u16 targetVolLeft; // Q1.15, but will always be non-negative + /*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative + /*0x40*/ u8 reverbVol; // Q1.7 /*0x41*/ u8 unused1; // never read, set to 0x3f /*0x44*/ struct NoteAttributes attributes; /*0x54, 0x58*/ struct AdsrState adsr; /*0x74, 0x7C*/ struct Portamento portamento; /*0x84, 0x8C*/ struct VibratoState vibratoState; - /*0x9C*/ s16 curVolLeft; - /*0x9E*/ s16 curVolRight; - /*0xA0*/ s16 reverbVol; + /*0x9C*/ s16 curVolLeft; // Q1.15, but will always be non-negative + /*0x9E*/ s16 curVolRight; // Q1.15, but will always be non-negative + /*0xA0*/ s16 reverbVolShifted; // Q1.15 /*0xA2*/ s16 unused2; // never read, set to 0 /*0xA4, 0x00*/ struct AudioListItem listItem; /* */ u8 pad2[0xc]; diff --git a/src/audio/load.c b/src/audio/load.c index 24a2424f..9766b455 100644 --- a/src/audio/load.c +++ b/src/audio/load.c @@ -1,4 +1,6 @@ +#ifndef VERSION_SH #include +#include #include "data.h" #include "external.h" @@ -20,16 +22,11 @@ struct SharedDma { // EU only void port_eu_init(void); -// SH only -#if defined(VERSION_SH) -void func_sh_802f6a9c(void); -void func_sh_802f51d4(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo); -#endif struct Note *gNotes; -#if defined(VERSION_EU) || defined(VERSION_SH) -static u8 pad[4]; +#if defined(VERSION_EU) +UNUSED static u8 pad[4]; #endif struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; @@ -40,35 +37,6 @@ struct SequenceChannel gSequenceChannelNone; struct AudioListItem gLayerFreeList; struct NotePool gNoteFreeLists; -#ifdef VERSION_SH -struct AudioBankSample *D_SH_8034EA88[0x80]; -struct UnkStructSH8034EC88 D_SH_8034EC88[0x80]; -s32 D_SH_8034F688; // index into D_SH_8034EA88 -s32 D_SH_8034F68C; // index or size for D_SH_8034EC88 - -struct PendingDmaAudioBank { - s8 inProgress; - s8 timer; - s8 medium; - struct AudioBank *audioBank; - uintptr_t devAddr; - void *vAddr; - u32 remaining; - u32 transferSize; - u32 encodedInfo; - OSMesgQueue *retQueue; - OSMesgQueue dmaRetQueue; - OSMesg mesgs[1]; - OSIoMesg ioMesg; -}; -struct PendingDmaAudioBank D_SH_8034F690[16]; - -OSMesgQueue gUnkQueue1; -OSMesg gUnkMesgBufs1[0x10]; -OSMesgQueue gUnkQueue2; -OSMesg gUnkMesgBufs2[0x10]; -#endif - OSMesgQueue gCurrAudioFrameDmaQueue; OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; @@ -77,11 +45,7 @@ OSMesgQueue gAudioDmaMesgQueue; OSMesg gAudioDmaMesg; OSIoMesg gAudioDmaIoMesg; -#ifdef VERSION_SH -struct SharedDma *sSampleDmas; // sh: 0x803503D0 -#else struct SharedDma sSampleDmas[0x60]; -#endif u32 gSampleDmaNumListItems; // sh: 0x803503D4 u32 sSampleDmaListSize1; // sh: 0x803503D8 u32 sUnused80226B40; // set to 0, never read, sh: 0x803503DC @@ -111,14 +75,11 @@ struct AudioBufferParametersEU gAudioBufferParameters; s32 gAiFrequency; #endif -#ifdef VERSION_SH -struct AudioBufferParametersEU gAudioBufferParameters; -#endif u32 sDmaBufSize; s32 gMaxAudioCmds; s32 gMaxSimultaneousNotes; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) s16 gTempoInternalToExternal; #else s32 gSamplesPerFrameTarget; @@ -131,7 +92,7 @@ s8 gAudioUpdatesPerFrame; s8 gSoundMode; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) s8 gAudioUpdatesPerFrame; #endif @@ -145,27 +106,9 @@ extern u8 gBankSetsData[]; // bank_sets.s ALSeqFile *get_audio_file_header(s32 arg0); -#ifdef VERSION_SH -void *func_sh_802f3688(s32 arg0); -void *get_bank_or_seq_wrapper(s32 arg0, s32 arg1); -void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); -void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium); -void func_sh_802f4a4c(s32 audioResetStatus); -void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len); -void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); -struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo); -void func_sh_802f4dcc(s32 audioResetStatus); -void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus); -void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len); -void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); -s32 func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3); -void *func_sh_802F3564(s32 arg0); -#endif - /** * Performs an immediate DMA copy */ -#if !defined(VERSION_SH) void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); osInvalDCache(vAddr, nbytes); @@ -174,7 +117,6 @@ void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK); eu_stubbed_printf_0("Romcopyend\n"); } -#endif #ifdef VERSION_EU u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d"; @@ -198,18 +140,15 @@ u8 audioString49[] = "BANK LOAD MISS! FOR %d\n"; /** * Performs an asynchronus (normal priority) DMA copy */ -#if !defined(VERSION_SH) void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) { osInvalDCache(vAddr, nbytes); osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, nbytes, queue); } -#endif /** * Performs a partial asynchronous (normal priority) DMA copy. This is limited * to 0x1000 bytes transfer at once. */ -#ifndef VERSION_SH void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { #if defined(VERSION_EU) ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); @@ -222,13 +161,12 @@ void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remai *devAddr += transfer; *vAddr += transfer; } -#endif void decrease_sample_dma_ttls() { u32 i; for (i = 0; i < sSampleDmaListSize1; i++) { -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) struct SharedDma *temp = &sSampleDmas[i]; #else struct SharedDma *temp = sSampleDmas + i; @@ -243,7 +181,7 @@ void decrease_sample_dma_ttls() { } for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) struct SharedDma *temp = &sSampleDmas[i]; #else struct SharedDma *temp = sSampleDmas + i; @@ -260,40 +198,19 @@ void decrease_sample_dma_ttls() { sUnused80226B40 = 0; } -extern char shindouDebugPrint62[]; -#ifdef VERSION_SH -void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium) { - UNUSED s32 sp60; -#else void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { -#endif -#ifdef VERSION_SH - struct SharedDma *dma; - s32 hasDma = FALSE; -#else s32 hasDma = FALSE; struct SharedDma *dma; -#endif uintptr_t dmaDevAddr; -#ifdef VERSION_SH - UNUSED u32 pad; - u32 dmaIndex; - u32 transfer; -#else u32 transfer; u32 i; u32 dmaIndex; -#endif ssize_t bufferPos; -#ifdef VERSION_SH - u32 i; -#else UNUSED u32 pad; -#endif if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) { for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) dma = &sSampleDmas[i]; #else dma = sSampleDmas + i; @@ -314,7 +231,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { } dma->ttl = 60; *dmaIndexRef = (u8) i; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) return &dma->buffer[(devAddr - dma->source)]; #else return (devAddr - dma->source) + dma->buffer; @@ -356,7 +273,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { sSampleDmaReuseQueueTail1++; } dma->ttl = 2; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) return dma->buffer + (devAddr - dma->source); #else return (devAddr - dma->source) + dma->buffer; @@ -365,9 +282,6 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { } if (!hasDma) { -#ifdef VERSION_SH - if (1) {} -#endif // Allocate a DMA from reuse queue 1. This queue will hopefully never // be empty, since TTL 2 is so small. dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++]; @@ -388,11 +302,6 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); *dmaIndexRef = dmaIndex; return (devAddr - dmaDevAddr) + dma->buffer; -#elif defined (VERSION_SH) - func_sh_802f3dd0(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ, - dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue, medium, shindouDebugPrint62); - *dmaIndexRef = dmaIndex; - return (devAddr - dmaDevAddr) + dma->buffer; #else gCurrAudioFrameDmaCount++; osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount - 1], OS_MESG_PRI_NORMAL, @@ -405,7 +314,7 @@ void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { void init_sample_dma_buffers(UNUSED s32 arg0) { s32 i; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) #define j i #else s32 j; @@ -413,25 +322,16 @@ void init_sample_dma_buffers(UNUSED s32 arg0) { #if defined(VERSION_EU) sDmaBufSize = 0x400; -#elif defined(VERSION_SH) - sDmaBufSize = 0x2D0; - sSampleDmas = sound_alloc_uninitialized(&gNotesAndBuffersPool, - gMaxSimultaneousNotes * 4 * sizeof(struct SharedDma) * gAudioBufferParameters.presetUnk4); #else sDmaBufSize = 144 * 9; #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) #else for (i = 0; i < gMaxSimultaneousNotes * 3; i++) #endif { -#if defined(VERSION_SH) - if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) { - break; - } -#else sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { #if defined(VERSION_EU) @@ -440,7 +340,6 @@ void init_sample_dma_buffers(UNUSED s32 arg0) { goto out1; #endif } -#endif sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; sSampleDmas[gSampleDmaNumListItems].source = 0; sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; @@ -465,19 +364,12 @@ out1: sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; sSampleDmaListSize1 = gSampleDmaNumListItems; -#if defined(VERSION_SH) - sDmaBufSize = 0x2D0; -#elif defined(VERSION_EU) +#if defined(VERSION_EU) sDmaBufSize = 0x200; #else sDmaBufSize = 160 * 9; #endif for (i = 0; i < gMaxSimultaneousNotes; i++) { -#if defined(VERSION_SH) - if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) { - break; - } -#else sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { #if defined(VERSION_EU) @@ -486,17 +378,11 @@ out1: goto out2; #endif } -#endif -#if defined(VERSION_SH) sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; -#endif sSampleDmas[gSampleDmaNumListItems].source = 0; sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; sSampleDmas[gSampleDmaNumListItems].unused2 = 0; sSampleDmas[gSampleDmaNumListItems].ttl = 0; -#ifndef VERSION_SH - sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; -#endif gSampleDmaNumListItems++; } #if defined(VERSION_JP) || defined(VERSION_US) @@ -516,68 +402,15 @@ out2: sSampleDmaReuseQueueTail2 = 0; sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) #undef j #endif } -#ifndef static -// Keep supporting the good old "#define static" hack. -#undef static -#endif - -#if defined(VERSION_SH) -void patch_seq_file(ALSeqFile *seqFile, u8 *data, u16 arg2) { - ALSeqFile *phi_a2; - s32 i; - - seqFile->unk2 = arg2; - seqFile->data = data; - for (i = 0; i < seqFile->seqCount; i++) { - if (seqFile->seqArray[i].len != 0 && seqFile->seqArray[i].magic[0] == 2) { - seqFile->seqArray[i].offset += (uintptr_t)data; - } - } -} - -void *func_sh_802f2e24(s32 arg0, s32 *arg1) { - s32 phi_s2; - s32 phi_s0; - s32 phi_s1; - void *sp28; - - phi_s0 = ((u16 *)gAlBankSets)[func_sh_802f39a0(0, arg0)]; - phi_s1 = gAlBankSets[phi_s0++]; - phi_s2 = 0xFF; - while (phi_s1 > 0) { - phi_s2 = gAlBankSets[phi_s0++]; - phi_s2 = (s32) phi_s2; - sp28 = func_sh_802f3688(phi_s2); - phi_s1--; - } - *arg1 = phi_s2; - return sp28; -} -#endif - #if defined(VERSION_JP) || defined(VERSION_US) // This function gets optimized out on US due to being static and never called -static +UNUSED static #endif -#if defined(VERSION_SH) -void preload_sequence(s32 arg0, s32 arg1) { - UNUSED s32 pad; - s32 sp18; - - arg0 = func_sh_802f39a0(0, arg0); - if (arg1 & PRELOAD_BANKS) { - func_sh_802f2e24(arg0, &sp18); - } - if (arg1 & PRELOAD_SEQUENCE) { - func_sh_802F3564(arg0); - } -} -#else void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) { struct AudioBankSample *sample; void *patched; @@ -613,9 +446,11 @@ void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED #undef PATCH } -#endif -#if defined(VERSION_JP) || defined(VERSION_US) +#ifdef VERSION_EU +#define PATCH_SOUND patch_sound +#else +// copt inline of the above #define PATCH_SOUND(_sound, mem, offset) \ { \ struct AudioBankSound *sound = _sound; \ @@ -640,457 +475,40 @@ void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED } #endif -#if defined(VERSION_SH) -s32 func_sh_802f2f38(struct AudioBankSample *sample, s32 bankId) { - u8 *sp24; - - if (sample->isPatched == TRUE && sample->medium != 0) { - sp24 = func_sh_802f1d90(sample->size, bankId, sample->sampleAddr, sample->medium); - if (sp24 == NULL) { - return -1; - } - if (sample->medium == 1) { - func_sh_802f3d78(sample->sampleAddr, sp24, sample->size, gAlTbl->unk2); - } else { - func_sh_802f3c38(sample->sampleAddr, sp24, sample->size, sample->medium); - } - sample->medium = 0; - sample->sampleAddr = sp24; - } -} - -s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2) { - struct Instrument *instr; - struct Drum *drum; - - if (instId < 0x7F) { - instr = get_instrument_inner(bankId, instId); - if (instr == NULL) { - return -1; - } - if (instr->normalRangeLo != 0) { - func_sh_802f2f38(instr->lowNotesSound.sample, bankId); - } - func_sh_802f2f38(instr->normalNotesSound.sample, bankId); - if (instr->normalRangeHi != 0x7F) { - func_sh_802f2f38(instr->highNotesSound.sample, bankId); - } - //! missing return - } else if (instId == 0x7F) { - drum = get_drum(bankId, arg2); - if (drum == NULL) { - return -1; - } - func_sh_802f2f38(drum->sound.sample, bankId); - return 0; - } -} - -void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3) { - if (func_802f3f08(2, func_sh_802f39a0(2, arg0), arg1, arg2, arg3) == 0) { - osSendMesg(arg3, 0, 0); - } -} - -void func_sh_802f3158(s32 index, s32 numChunks, s32 arg2, OSMesgQueue *retQueue) { - s32 val; - s32 v; - - val = ((u16 *) gAlBankSets)[func_sh_802f39a0(0, index)]; - v = gAlBankSets[val++]; - - while (v > 0) { - func_802f3f08(1, func_sh_802f39a0(1, gAlBankSets[val++]), numChunks, arg2, retQueue); - v--; - } -} - -u8 *func_sh_802f3220(u32 index, u32 *a1) { - s32 val; - - val = ((u16 *) gAlBankSets)[func_sh_802f39a0(0, index)]; - *a1 = gAlBankSets[val++]; - if (*a1 == 0) { - return NULL; - } - return &gAlBankSets[val]; -} - -void func_sh_802f3288(s32 idx) { - s32 s0; - s32 s2; - - idx = ((u16*)gAlBankSets)[func_sh_802f39a0(0, idx)]; - s2 = gAlBankSets[idx++]; - while (s2 > 0) { - s2--; - s0 = func_sh_802f39a0(1, gAlBankSets[idx++]); - - if (unk_pool1_lookup(1, s0) == 0) { - func_sh_802f3368(s0); - if (gBankLoadStatus[s0] != 5) { - gBankLoadStatus[s0] = 0; - } - - continue; - } - - } -} - -s32 func_sh_802f3368(s32 arg0) { - struct SoundMultiPool *pool = &gBankLoadedPool; - struct TemporaryPool *temporary = &pool->temporary; - struct PersistentPool *persistent; - u32 i; - - if (temporary->entries[0].id == arg0) { - temporary->entries[0].id = -1; - } else if (arg0 == temporary->entries[1].id) { - temporary->entries[1].id = -1; - } - - persistent = &pool->persistent; - for (i = 0; i < persistent->numEntries; i++) { - if (persistent->entries[i].id == arg0) { - persistent->entries[i].id = -1; - } - - } - - discard_bank(arg0); -} - - -void func_sh_802F3430(s32 arg0, s32 arg1, s32 arg2); -void func_sh_802F3410(s32 arg0, s32 arg1, s32 arg2) { - func_sh_802F3430(arg0, arg1, arg2); -} - -void func_sh_802F3430(s32 arg0, s32 arg1, s32 arg2) { - struct SequencePlayer *seqPlayer; - u8 *seqData; - u32 temp; - u32 s0; - s32 s1; - u8 bank; - u32 id; - - seqPlayer = &gSequencePlayers[arg0]; - - temp = func_sh_802f39a0(0, arg1); - sequence_player_disable(seqPlayer); - id = temp; - - s0 = ((u16 *) gAlBankSets)[id]; - s1 = gAlBankSets[s0++]; - bank = 0xff; - - while (s1 > 0) { - bank = gAlBankSets[s0++]; - func_sh_802f3688(bank); - s1--; - } - - seqData = func_sh_802F3564(id); - init_sequence_player(arg0); - seqPlayer->seqId = id; - seqPlayer->defaultBank[0] = bank; - seqPlayer->enabled = 1; - seqPlayer->seqData = seqData; - seqPlayer->scriptState.pc = seqData; - seqPlayer->scriptState.depth = 0; - seqPlayer->delay = 0; - seqPlayer->finished = 0; - - if (id) { - } - - for (id = 0; id < 0x10; id++) { - } - -} - -void *func_sh_802F3564(s32 arg0) { - void *a = func_sh_802f39a0(0, arg0); - s32 b; - return func_sh_802f3764(0, a, &b); -} - -extern u8 gUnkLoadStatus[0x40]; - -void *func_sh_802f3598(s32 idx, s32 *medium) { - void *ret; - ALSeqFile *f; - s32 temp; - s32 sp28; - - f = get_audio_file_header(2); - idx = func_sh_802f39a0(2, idx); - ret = get_bank_or_seq_wrapper(2, idx); - if (ret != NULL) { - if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) { - gUnkLoadStatus[idx] = SOUND_LOAD_STATUS_COMPLETE; - } - - *medium = 0; - return ret; - } - - temp = f->seqArray[idx].magic[1]; - if (temp == 4) { - *medium = f->seqArray[idx].magic[0]; - return f->seqArray[idx].offset; - } else { - ret = func_sh_802f3764(2, idx, &sp28); - if (ret != 0) { - *medium = 0; - return ret; - } - - *medium = f->seqArray[idx].magic[0]; - } - return f->seqArray[idx].offset; - -} - -void *func_sh_802f3688(s32 idx) { - void *ret; - s32 bankId1; - s32 bankId2; - s32 sp38; - struct PatchStruct patchInfo; - - idx = func_sh_802f39a0(1, idx); - bankId1 = gCtlEntries[idx].bankId1; - bankId2 = gCtlEntries[idx].bankId2; - - patchInfo.bankId1 = bankId1; - patchInfo.bankId2 = bankId2; - - if (patchInfo.bankId1 != 0xFF) { - patchInfo.baseAddr1 = func_sh_802f3598(patchInfo.bankId1, &patchInfo.medium1); - } else { - patchInfo.baseAddr1 = NULL; - } - - if (bankId2 != 0xFF) { - patchInfo.baseAddr2 = func_sh_802f3598(bankId2, &patchInfo.medium2); - } else { - patchInfo.baseAddr2 = NULL; - } - - if ((ret = func_sh_802f3764(1, idx, &sp38)) == NULL) { - return NULL; - } - - if (sp38 == 1) { - func_sh_802f5310(idx, ret, &patchInfo, 0); - } - - return ret; -} - -void *func_sh_802f3764(s32 poolIdx, s32 idx, s32 *arg2) { - s32 size; - ALSeqFile *f; - void *vAddr; - s32 sp30; - UNUSED u32 pad2; - u8 *devAddr; - s8 loadStatus; - s32 sp18; - - vAddr = get_bank_or_seq_wrapper(poolIdx, idx); - if (vAddr != NULL) { - *arg2 = 0; - loadStatus = SOUND_LOAD_STATUS_COMPLETE; - } else { - f = get_audio_file_header(poolIdx); - size = f->seqArray[idx].len; - size = ALIGN16(size); - sp30 = f->seqArray[idx].magic[0]; - sp18 = f->seqArray[idx].magic[1]; - devAddr = f->seqArray[idx].offset; - - - switch (sp18) - { - case 0: - vAddr = unk_pool1_alloc(poolIdx, idx, size); - if (vAddr == NULL) { - return vAddr; - } - break; - case 1: - vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - case 2: - vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - - case 3: - case 4: - vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - } - - *arg2 = 1; - if (sp30 == 1) { - func_sh_802f3d78((uintptr_t) devAddr, vAddr, size, f->unk2); - } else { - func_sh_802f3c38((uintptr_t) devAddr, vAddr, size, sp30); - } - - switch (sp18) - { - case 0: - loadStatus = SOUND_LOAD_STATUS_5; - break; - - default: - loadStatus = SOUND_LOAD_STATUS_COMPLETE; - break; - } - } - - switch (poolIdx) - { - case 0: - if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) { - gSeqLoadStatus[idx] = loadStatus; - } - break; - - case 1: - if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) { - gBankLoadStatus[idx] = loadStatus; - } - break; - - case 2: - if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) { - gUnkLoadStatus[idx] = loadStatus; - } - break; - } - - return vAddr; -} - -s32 func_sh_802f39a0(s32 arg0, s32 idx) { - ALSeqFile *f; - - f = get_audio_file_header(arg0); - if (f->seqArray[idx].len == 0) { - idx = (s32) f->seqArray[idx].offset; // TODO: something doesn't seem right here... - } - return idx; -} - -void *get_bank_or_seq_wrapper(s32 poolIdx, s32 id) { - void *ret; - - ret = unk_pool1_lookup(poolIdx, id); - if (ret != NULL) { - return ret; - } - ret = get_bank_or_seq(poolIdx, 2, id); - if (ret != 0) { - return ret; - } - return NULL; -} - -ALSeqFile *get_audio_file_header(s32 index) { - ALSeqFile *ret; - switch(index) { - default: - ret = NULL; - break; - case 0: - ret = gSeqFileHeader; - break; - case 1: - ret = gAlCtlHeader; - break; - case 2: - ret = gAlTbl; - break; - } - return ret; -} -#endif - // on US/JP this inlines patch_sound, using some -sopt compiler flag -#if defined(VERSION_SH) -void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo) { -#else void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { -#endif struct Instrument *instrument; -#if defined(VERSION_SH) - void **itInstrs; -#else struct Instrument **itInstrs; -#endif struct Instrument **end; -#if defined(VERSION_SH) - s32 i; -#else - struct AudioBank *temp; // Maybe Shindou also has this; I'm not sure. + struct AudioBank *temp; u32 i; -#endif void *patched; struct Drum *drum; -#ifndef VERSION_SH struct Drum **drums; -#endif #if defined(VERSION_EU) u32 numDrums2; -#elif defined(VERSION_SH) - s32 numDrums2; - s32 numInstruments2; #endif -#define BASE_OFFSET(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) -#define PATCH(x, base) (patched = BASE_OFFSET(x, base)) +#define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) +#define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base)) #define PATCH_MEM(x) x = PATCH(x, mem) -#if defined(VERSION_SH) - numDrums2 = gCtlEntries[bankId].numDrums; - numInstruments2 = gCtlEntries[bankId].numInstruments; - itInstrs = mem->drums; - if (mem->drums) { - } +#if defined(VERSION_JP) || defined(VERSION_US) +#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(x, base) #else - drums = mem->drums; +#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x) #endif + + drums = mem->drums; #if defined(VERSION_JP) || defined(VERSION_US) if (drums != NULL && numDrums > 0) { mem->drums = (void *)((uintptr_t) drums + (uintptr_t) mem); if (numDrums > 0) //! unneeded when -sopt is enabled for (i = 0; i < numDrums; i++) { #else -#if defined(VERSION_EU) numDrums2 = numDrums; if (drums != NULL && numDrums2 > 0) { mem->drums = PATCH(drums, mem); -#elif defined(VERSION_SH) - if (itInstrs != NULL && numDrums2 != 0) { - if (1) { - mem->drums = PATCH(itInstrs, mem); - } -#endif for (i = 0; i < numDrums2; i++) { #endif patched = mem->drums[i]; @@ -1102,16 +520,11 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 //! copt replaces drum with 'patched' for these two lines PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset); patched = (*(struct Drum *)patched).envelope; - drum->envelope = BASE_OFFSET(mem, patched); #else -#if defined(VERSION_EU) patch_sound(&drum->sound, (u8 *) mem, offset); -#elif defined(VERSION_SH) - func_sh_802f51d4(&drum->sound, mem, patchInfo); -#endif patched = drum->envelope; - drum->envelope = BASE_OFFSET(patched, mem); #endif + drum->envelope = BASE_OFFSET(mem, patched); drum->loaded = 1; } @@ -1119,25 +532,17 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 } } -#ifndef VERSION_SH //! Doesn't affect EU, but required for US/JP temp = &*mem; -#endif #if defined(VERSION_JP) || defined(VERSION_US) if (numInstruments >= 1) #endif -#if defined(VERSION_SH) - if (numInstruments2 > 0) { - itInstrs = mem->instruments; - end = numInstruments2 + (struct Instrument **) itInstrs; -#else if (numInstruments > 0) { //! Doesn't affect EU, but required for US/JP struct Instrument **tempInst; itInstrs = temp->instruments; tempInst = temp->instruments; end = numInstruments + tempInst; -#endif #if defined(VERSION_JP) || defined(VERSION_US) l2: @@ -1145,144 +550,35 @@ l2: do { #endif if (*itInstrs != NULL) { -#ifdef VERSION_SH - *itInstrs = BASE_OFFSET(mem, *itInstrs); -#else *itInstrs = BASE_OFFSET(*itInstrs, mem); -#endif instrument = *itInstrs; if (instrument->loaded == 0) { -#if defined(VERSION_JP) || defined(VERSION_US) PATCH_SOUND(&instrument->lowNotesSound, (u8 *) mem, offset); PATCH_SOUND(&instrument->normalNotesSound, (u8 *) mem, offset); PATCH_SOUND(&instrument->highNotesSound, (u8 *) mem, offset); -#elif defined(VERSION_EU) - patch_sound(&instrument->lowNotesSound, (u8 *) mem, offset); - patch_sound(&instrument->normalNotesSound, (u8 *) mem, offset); - patch_sound(&instrument->highNotesSound, (u8 *) mem, offset); -#elif defined(VERSION_SH) - if (instrument->normalRangeLo != 0) { - func_sh_802f51d4(&instrument->lowNotesSound, mem, patchInfo); - } - func_sh_802f51d4(&instrument->normalNotesSound, mem, patchInfo); - if (instrument->normalRangeHi != 0x7F) { - func_sh_802f51d4(&instrument->highNotesSound, mem, patchInfo); - } -#endif patched = instrument->envelope; - -#if defined(VERSION_JP) || defined(VERSION_US) instrument->envelope = BASE_OFFSET(mem, patched); instrument->loaded = 1; -#else - instrument->envelope = BASE_OFFSET(patched, mem); - instrument->loaded = 1; -#endif } } -#ifndef VERSION_SH itInstrs++; -#else - itInstrs = ((struct Instrument **) itInstrs) + 1; -#endif #if defined(VERSION_JP) || defined(VERSION_US) //! goto generated by copt, required to match US/JP if (end != itInstrs) { goto l2; } #else -#ifdef VERSION_EU } while (end != itInstrs); -#else - } while ((struct Instrument **) itInstrs != (0, end)); //! This is definitely fake -#endif #endif } -#if defined(VERSION_SH) - gCtlEntries[bankId].drums = mem->drums; - gCtlEntries[bankId].instruments = mem->instruments; -#endif #undef PATCH_MEM #undef PATCH +#undef BASE_OFFSET_REAL #undef BASE_OFFSET #undef PATCH_SOUND } -#if defined(VERSION_SH) -void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes); - -extern char shindouDebugPrint81[]; -extern char shindouDebugPrint82[]; -void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium) { - nbytes = ALIGN16(nbytes); - osInvalDCache(vAddr, nbytes); - -lock: - if (gAudioLoadLockSH != 0) { - goto lock; - } - - if (nbytes >= 0x400U) { - func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, 0x400, &gAudioDmaMesgQueue, medium, shindouDebugPrint81); - osRecvMesg(&gAudioDmaMesgQueue, NULL, 1); - nbytes = nbytes - 0x400; - devAddr = devAddr + 0x400; - vAddr = (u8*)vAddr + 0x400; - goto lock; - } - - if (nbytes != 0) { - func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, nbytes, &gAudioDmaMesgQueue, medium, shindouDebugPrint82); - osRecvMesg(&gAudioDmaMesgQueue, NULL, 1); - } -} - -void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { - uintptr_t sp1C; - - sp1C = devAddr; - osInvalDCache(vAddr, nbytes); - func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); -} - -s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr, void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, const char *arg8) { - OSPiHandle *handle; - if (gAudioLoadLockSH >= 0x11U) { - return -1; - } - switch (medium) { - case 2: - handle = osCartRomInit(); - break; - case 3: - handle = osDriveRomInit(); - break; - default: - return 0; - } - if ((size & 0xf) != 0) { - size = ALIGN16(size); - } - m->hdr.pri = pri; - m->hdr.retQueue = retQueue; - m->dramAddr = dramAddr; - m->devAddr = devAddr; - m->size = size; - handle->transferInfo.cmdType = 2; - osEPiStartDma(handle, m, direction); - return 0; -} - -s32 func_sh_802f3ec4(UNUSED s32 arg0, UNUSED uintptr_t *arg1) { - return 0; -} - -void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes) { -} -#endif - -#ifndef VERSION_SH struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { UNUSED u32 pad1[4]; u32 buf[4]; @@ -1314,9 +610,7 @@ struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE; return ret; } -#endif -#ifndef VERSION_SH struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *seqPlayer) { u32 numInstruments, numDrums; UNUSED u32 pad1[2]; @@ -1372,9 +666,7 @@ struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *s gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_IN_PROGRESS; return ret; } -#endif -#ifndef VERSION_SH void *sequence_dma_immediate(s32 seqId, s32 arg1) { s32 seqLength; void *ptr; @@ -1392,9 +684,7 @@ void *sequence_dma_immediate(s32 seqId, s32 arg1) { gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; return ptr; } -#endif -#ifndef VERSION_SH void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) { s32 seqLength; void *ptr; @@ -1431,9 +721,7 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) } return ptr; } -#endif -#ifndef VERSION_SH u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { void *temp; u32 bankId; @@ -1443,7 +731,7 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { *nullCount = 0; *nonNullCount = 0; -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) offset = ((u16 *) gAlBankSets)[seqId]; for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { bankId = gAlBankSets[offset++]; @@ -1455,12 +743,10 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { #endif if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { -#ifndef VERSION_SH -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId); #else temp = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); -#endif #endif } else { temp = NULL; @@ -1476,10 +762,8 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { return ret; } -#endif -#ifndef VERSION_SH -struct AudioBank *load_banks_immediate(s32 seqId, u8 *arg1) { +struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { void *ret; u32 bankId; u16 offset; @@ -1510,12 +794,10 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *arg1) { ret = bank_load_immediate(bankId, 2); } } - *arg1 = bankId; + *outDefaultBank = bankId; return ret; } -#endif -#ifndef VERSION_SH void preload_sequence(u32 seqId, u8 preloadMask) { void *sequenceData; u8 temp; @@ -1545,9 +827,7 @@ void preload_sequence(u32 seqId, u8 preloadMask) { gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; } -#endif -#ifndef VERSION_SH void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync); void load_sequence(u32 player, u32 seqId, s32 loadAsync) { @@ -1559,9 +839,7 @@ void load_sequence(u32 player, u32 seqId, s32 loadAsync) { gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; } } -#endif -#ifndef VERSION_SH void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { void *sequenceData; struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; @@ -1575,26 +853,16 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { if (loadAsync) { s32 numMissingBanks = 0; s32 dummy = 0; -#ifdef VERSION_SH - s32 bankId = 0xBA17; // dummy code to avoid problems -#else s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks); -#endif if (numMissingBanks == 1) { -#ifndef VERSION_SH eu_stubbed_printf_0("Ok,one bank slow load Start \n"); if (bank_load_async(bankId, 2, seqPlayer) == NULL) { return; } -#endif // @bug This should set the last bank (i.e. the first in the JSON) // as default, not the missing one. This code path never gets // taken, though -- all sequence loading is synchronous. seqPlayer->defaultBank[0] = bankId; -#ifdef VERSION_SH - } - } -#else } else { eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks); if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { @@ -1604,29 +872,23 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { } else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { return; } -#endif eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]); eu_stubbed_printf_0("Seq Loading Start\n"); seqPlayer->seqId = seqId; -#ifndef VERSION_SH sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); -#endif if (sequenceData == NULL) { if (seqPlayer->seqDmaInProgress) { eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n"); eu_stubbed_printf_0(" Cancel Seq Start.\n"); return; } -#ifndef VERSION_SH if (loadAsync) { sequenceData = sequence_dma_async(seqId, 2, seqPlayer); } else { - sequenceData = sequence_dma_immediate(seqId, 2); } -#endif if (sequenceData == NULL) { return; @@ -1641,142 +903,11 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { seqPlayer->seqData = sequenceData; seqPlayer->scriptState.pc = sequenceData; } -#endif -#if defined(VERSION_SH) -void *func_sh_802f3ee8(uintptr_t devAddr, void *vAddr) { - s32 b; - return func_sh_802f3764(devAddr, vAddr, &b); -} - -void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue) { - s32 size; - ALSeqFile *f; - void *vAddr; - s32 medium; - s32 sp18; - uintptr_t devAddr; - s32 loadStatus; - - switch (poolIdx) { - case 0: - if (gSeqLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { - return 0; - } - break; - case 1: - if (gBankLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { - return 0; - } - break; - case 2: - if (gUnkLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { - return 0; - } - break; - - } - vAddr = get_bank_or_seq_wrapper(poolIdx, idx); - if (vAddr != NULL) { - loadStatus = 2; - osSendMesg(retQueue, (OSMesg) (arg3 << 0x18), 0); - } else { - f = get_audio_file_header(poolIdx); - size = f->seqArray[idx].len; - size = ALIGN16(size); - medium = f->seqArray[idx].magic[0]; - sp18 = f->seqArray[idx].magic[1]; - devAddr = (uintptr_t) f->seqArray[idx].offset; - loadStatus = 2; - - switch (sp18) { - case 0: - vAddr = unk_pool1_alloc(poolIdx, idx, size); - if (vAddr == NULL) { - return vAddr; - } - loadStatus = 5; - break; - case 1: - vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - case 2: - vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - - case 4: - case 3: - vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx); - if (vAddr == NULL) { - return vAddr; - } - break; - } - - func_sh_802f4cb4(devAddr, vAddr, size, medium, numChunks, retQueue, (arg3 << 0x18) | (poolIdx << 0x10) | (idx << 8) | loadStatus); - loadStatus = SOUND_LOAD_STATUS_IN_PROGRESS; - } - - switch (poolIdx) { - case 0: - if (gSeqLoadStatus[idx] != 5) { - gSeqLoadStatus[idx] = loadStatus; - } - break; - - case 1: - if (gBankLoadStatus[idx] != 5) { - gBankLoadStatus[idx] = loadStatus; - } - break; - - case 2: - if (gUnkLoadStatus[idx] != 5) { - gUnkLoadStatus[idx] = loadStatus; - } - break; - } - - return vAddr; -} - -void func_802f41e4(s32 audioResetStatus) { - func_sh_802f4a4c(audioResetStatus); - func_sh_802f573c(audioResetStatus); - func_sh_802f4dcc(audioResetStatus); -} -#endif - -#if defined(VERSION_SH) -u8 gShindouSoundBanksHeader[] = { -#include "sound/ctl_header.inc.c" -}; - -u8 gBankSetsData[] = { -#include "sound/bank_sets.inc.c" -}; - -u8 gShindouSampleBanksHeader[] = { -#include "sound/tbl_header.inc.c" -}; - -u8 gShindouSequencesHeader[] = { -#include "sound/sequences_header.inc.c" -}; -#endif - -// (void) must be omitted from parameters +// (void) must be omitted from parameters to fix stack with -framepointer void audio_init() { #if defined(VERSION_EU) UNUSED s8 pad[16]; -#elif defined(VERSION_SH) - UNUSED s8 pad[24]; #else UNUSED s8 pad[32]; #endif @@ -1785,7 +916,7 @@ void audio_init() { #endif s32 i, j, k; UNUSED s32 lim1; // lim1 unused in EU -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) UNUSED u8 buf[0x10]; s32 UNUSED lim2, lim3; #else @@ -1795,15 +926,8 @@ void audio_init() { UNUSED u64 *ptr64; void *data; UNUSED s32 pad2; -#ifdef VERSION_SH - s32 seqCount; -#endif -#ifdef VERSION_SH - gAudioLoadLockSH = 0; -#else gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; -#endif #if defined(VERSION_JP) || defined(VERSION_US) lim1 = gUnusedCount80333EE8; @@ -1842,17 +966,11 @@ void audio_init() { } #endif -#ifdef VERSION_EU D_EU_802298D0 = 20.03042f; gRefreshRate = 50; port_eu_init(); if (k) { } -#else - D_EU_802298D0 = 16.713f; - gRefreshRate = 60; - func_sh_802f6a9c(); -#endif #endif #ifdef TARGET_N64 @@ -1879,28 +997,20 @@ void audio_init() { osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1); osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs, ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs)); -#ifdef VERSION_SH - osCreateMesgQueue(&gUnkQueue1, gUnkMesgBufs1, 0x10); - osCreateMesgQueue(&gUnkQueue2, gUnkMesgBufs2, 0x10); -#endif gCurrAudioFrameDmaCount = 0; gSampleDmaNumListItems = 0; sound_init_main_pools(gAudioInitPoolSize); for (i = 0; i < NUMAIBUFFERS; i++) { -#ifdef VERSION_SH - gAiBuffers[i] = sound_alloc_uninitialized(&gAudioInitPool, AIBUFFER_LEN); -#else gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN); -#endif for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { gAiBuffers[i][j] = 0; } } -#if defined(VERSION_EU) || defined(VERSION_SH) +#if defined(VERSION_EU) gAudioResetPresetIdToLoad = 0; gAudioResetStatus = 1; audio_shut_down_and_reset_step(); @@ -1913,31 +1023,7 @@ void audio_init() { eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0); eu_stubbed_printf_0("Main Heap Initialize.\n"); - // Load header for sequence data (assets/music_data.sbk.s) -#ifdef VERSION_SH - gSeqFileHeader = (ALSeqFile *) gShindouSequencesHeader; - gAlCtlHeader = (ALSeqFile *) gShindouSoundBanksHeader; - gAlTbl = (ALSeqFile *) gShindouSampleBanksHeader; - gAlBankSets = gBankSetsData; - gSequenceCount = (s16) gSeqFileHeader->seqCount; - patch_seq_file(gSeqFileHeader, gMusicData, D_SH_80315EF4); - patch_seq_file(gAlCtlHeader, gSoundDataADSR, D_SH_80315EF8); - patch_seq_file(gAlTbl, gSoundDataRaw, D_SH_80315EFC); - seqCount = gAlCtlHeader->seqCount; - gCtlEntries = sound_alloc_uninitialized(&gAudioInitPool, seqCount * sizeof(struct CtlEntry)); - for (i = 0; i < seqCount; i++) { - gCtlEntries[i].bankId1 = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf >> 8) & 0xff); - gCtlEntries[i].bankId2 = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf & 0xff); - gCtlEntries[i].numInstruments = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums >> 8) & 0xff); - gCtlEntries[i].numDrums = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums & 0xff); - } - data = sound_alloc_uninitialized(&gAudioInitPool, D_SH_80315EF0); - if (data == NULL) { - D_SH_80315EF0 = 0; - } - sound_alloc_pool_init(&gUnkPool1.pool, data, D_SH_80315EF0); - init_sequence_players(); -#else + // Load headers for sounds and sequences gSeqFileHeader = (ALSeqFile *) buf; data = gMusicData; audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); @@ -1952,7 +1038,7 @@ void audio_init() { audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); alSeqFileNew(gSeqFileHeader, data); - // Load header for CTL (assets/sound_data.ctl.s, i.e. ADSR) + // Load header for CTL (instrument metadata) gAlCtlHeader = (ALSeqFile *) buf; data = gSoundDataADSR; audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10); @@ -1963,7 +1049,7 @@ void audio_init() { audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size); alSeqFileNew(gAlCtlHeader, data); - // Load header for TBL (assets/sound_data.tbl.s, i.e. raw data) + // Load header for TBL (raw sound data) gAlTbl = (ALSeqFile *) buf; audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10); size = gAlTbl->seqCount * sizeof(ALSeqData) + 4; @@ -1972,7 +1058,7 @@ void audio_init() { audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size); alSeqFileNew(gAlTbl, gSoundDataRaw); - // Load bank sets for each sequence (assets/bank_sets.s) + // Load bank sets for each sequence gAlBankSets = soundAlloc(&gAudioInitPool, 0x100); audio_dma_copy_immediate((uintptr_t) gBankSetsData, gAlBankSets, 0x100); @@ -1985,535 +1071,5 @@ void audio_init() { eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw eu_stubbed_printf_0("---------------------------------------\n"); -#endif -} - -#if defined(VERSION_SH) -s32 func_802f47c8(s32 bankId, u8 idx, s8 *io) { - struct AudioBankSample *sample = func_sh_802f4978(bankId, idx); - struct PendingDmaSample *temp; - if (sample == NULL) { - *io = 0; - return -1; - } - if (sample->medium == 0) { - *io = 2; - return 0; - } - temp = &D_SH_80343D00.arr[D_SH_80343D00.someIndex]; - if (temp->state == 3) { - temp->state = 0; - } - temp->sample = *sample; - temp->io = io; - temp->vAddr = func_sh_802f1d40(sample->size, bankId, sample->sampleAddr, sample->medium); - if (temp->vAddr == NULL) { - if (sample->medium == 1 || sample->codec == 2) { - *io = 0; - return -1; - } else { - *io = 3; - return -1; - } - } - temp->state = 1; - temp->remaining = ALIGN16(sample->size); - temp->resultSampleAddr = (u8 *) temp->vAddr; - temp->devAddr = (uintptr_t) sample->sampleAddr; - temp->medium = sample->medium; - temp->bankId = bankId; - temp->idx = idx; - D_SH_80343D00.someIndex ^= 1; - return 0; -} - -struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx) { - struct Drum *drum; - struct Instrument *inst; - struct AudioBankSample *ret; - - if (idx < 128) { - inst = get_instrument_inner(bankId, idx); - if (inst == 0) { - return NULL; - } - ret = inst->normalNotesSound.sample; - } else { - drum = get_drum(bankId, idx - 128); - if (drum == 0) { - return NULL; - } - ret = drum->sound.sample; - } - return ret; -} -void stub_sh_802f49dc(void) { - -} - -void func_sh_802f49e4(struct PendingDmaSample *arg0) { - struct AudioBankSample *sample = func_sh_802f4978(arg0->bankId, arg0->idx); - if (sample != NULL) { - arg0->sample = *sample; - sample->sampleAddr = arg0->resultSampleAddr; - sample->medium = 0; - } -} - -void func_sh_802f4a4c(s32 audioResetStatus) { - ALSeqFile *alTbl; - struct PendingDmaSample *entry; - - s32 i; - - alTbl = gAlTbl; - - for (i = 0; i < 2; i++) { - entry = &D_SH_80343D00.arr[i]; - switch (entry->state) { - case 2: - osRecvMesg(&entry->queue, NULL, 1); - if (audioResetStatus != 0) { - entry->state = 3; - break; - } - // fallthrough - case 1: - entry->state = 2; - if (entry->remaining == 0) { - func_sh_802f49e4(entry); - entry->state = 3; - *entry->io = 1; - } else if (entry->remaining < 0x1000) { - if (1 == entry->medium) { - func_sh_802f4c5c(entry->devAddr, entry->vAddr, entry->remaining, alTbl->unk2); - } else { - func_sh_802f4bd8(entry, entry->remaining); - } - entry->remaining = 0; - } else { - if (1 == entry->medium) { - func_sh_802f4c5c(entry->devAddr, entry->vAddr, 0x1000, alTbl->unk2); - } else { - func_sh_802f4bd8(entry, 0x1000); - } - entry->remaining = (s32) (entry->remaining - 0x1000); - entry->vAddr = (u8 *) entry->vAddr + 0x1000; - entry->devAddr = entry->devAddr + 0x1000; - } - break; - } - } -} - -extern char shindouDebugPrint102[]; -void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len) { // len must be signed - osInvalDCache(arg0->vAddr, len); - osCreateMesgQueue(&arg0->queue, arg0->mesgs, 1); - func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->queue, arg0->medium, shindouDebugPrint102); -} - -void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { - uintptr_t sp1C; - - sp1C = devAddr; - osInvalDCache(vAddr, nbytes); - func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); -} - -struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo) { - struct PendingDmaAudioBank *item; - s32 i; - - for (i = 0; i < ARRAY_COUNT(D_SH_8034F690); i++) { - if (D_SH_8034F690[i].inProgress == 0) { - item = &D_SH_8034F690[i]; - break; - } - } - if (i == ARRAY_COUNT(D_SH_8034F690)) { - return NULL; - } - - item->inProgress = 1; - item->devAddr = devAddr; - item->audioBank = vAddr; - item->vAddr = vAddr; - item->remaining = size; - if (numChunks == 0) { - item->transferSize = 0x1000; - } else { - item->transferSize = ((size / numChunks) + 0xFF) & ~0xFF; - if (item->transferSize < 0x100) { - item->transferSize = 0x100; - } - } - item->retQueue = retQueue; - item->timer = 3; - item->medium = medium; - item->encodedInfo = encodedInfo; - osCreateMesgQueue(&item->dmaRetQueue, item->mesgs, 1); - return item; -} - -void func_sh_802f4dcc(s32 audioResetStatus) { - s32 i; - - if (gAudioLoadLockSH != 1) { - for (i = 0; i < ARRAY_COUNT(D_SH_8034F690); i++) { - if (D_SH_8034F690[i].inProgress == 1) { - func_sh_802f4e50(&D_SH_8034F690[i], audioResetStatus); - } - } - } -} - -void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus) { - ALSeqFile *alSeqFile; - u32 *encodedInfo; - OSMesg mesg; - u32 temp; - u32 seqId; - s32 bankId1; - s32 bankId2; - struct PatchStruct patchStruct; - alSeqFile = gAlTbl; - if (audioBank->timer >= 2) { - audioBank->timer--; - return; - } - if (audioBank->timer == 1) { - audioBank->timer = 0; - } else { - if (audioResetStatus != 0) { - osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_BLOCK); - audioBank->inProgress = 0; - return; - } - if (osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_NOBLOCK) == -1) { - return; - } - } - - encodedInfo = &audioBank->encodedInfo; - if (audioBank->remaining == 0) { - mesg = (OSMesg) audioBank->encodedInfo; - mesg = mesg; //! needs an extra read from mesg here to match... - temp = *encodedInfo; - seqId = (temp >> 8) & 0xFF; - switch ((u8) (temp >> 0x10)) { - case 0: - if (gSeqLoadStatus[seqId] != 5) { - gSeqLoadStatus[seqId] = (u8) (temp & 0xFF); - } - break; - case 2: - if (gUnkLoadStatus[seqId] != 5) { - gUnkLoadStatus[seqId] = (u8) (temp & 0xFF); - } - break; - case 1: - if (gBankLoadStatus[seqId] != 5) { - gBankLoadStatus[seqId] = (u8) (temp & 0xFF); - } - bankId1 = gCtlEntries[seqId].bankId1; - bankId2 = gCtlEntries[seqId].bankId2; - patchStruct.bankId1 = bankId1; - patchStruct.bankId2 = bankId2; - if (bankId1 != 0xFF) { - patchStruct.baseAddr1 = func_sh_802f3598(bankId1, &patchStruct.medium1); - } else { - patchStruct.baseAddr1 = NULL; - } - if (bankId2 != 0xFF) { - patchStruct.baseAddr2 = func_sh_802f3598(bankId2, &patchStruct.medium2); - } else { - patchStruct.baseAddr2 = NULL; - } - - func_sh_802f5310(seqId, audioBank->audioBank, &patchStruct, 1); - break; - } - mesg = (OSMesg) audioBank->encodedInfo; - audioBank->inProgress = 0; - osSendMesg(audioBank->retQueue, mesg, OS_MESG_NOBLOCK); - } else if (audioBank->remaining < audioBank->transferSize) { - if (audioBank->medium == 1) { - func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->remaining, alSeqFile->unk2); - } else { - func_sh_802f50ec(audioBank, audioBank->remaining); - } - - audioBank->remaining = 0; - } else { - if (audioBank->medium == 1) { - func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->transferSize, alSeqFile->unk2); - } else { - func_sh_802f50ec(audioBank, audioBank->transferSize); - } - - audioBank->remaining -= audioBank->transferSize; - audioBank->devAddr += audioBank->transferSize; - audioBank->vAddr = ((u8 *) audioBank->vAddr) + audioBank->transferSize; - } -} - -extern char shindouDebugPrint110[]; -void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len) { - len += 0xf; - len &= ~0xf; - osInvalDCache(arg0->vAddr, len); - osCreateMesgQueue(&arg0->dmaRetQueue, arg0->mesgs, 1); - func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->dmaRetQueue, arg0->medium, shindouDebugPrint110); -} - - -void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { - uintptr_t sp1C; - - sp1C = devAddr; - osInvalDCache(vAddr, nbytes); - func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); -} - -void func_sh_802f51d4(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo) { - struct AudioBankSample *sample; - void *patched; - -#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) - - if ((uintptr_t) sound->sample <= 0x80000000) { - sample = sound->sample = PATCH(sound->sample, memBase); - if (sample->size != 0 && sample->isPatched != TRUE) { - sample->loop = PATCH(sample->loop, memBase); - sample->book = PATCH(sample->book, memBase); - switch (sample->medium) { - case 0: - sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr1); - sample->medium = patchInfo->medium1; - break; - case 1: - sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr2); - sample->medium = patchInfo->medium2; - break; - - case 2: - case 3: - break; - } - sample->isPatched = TRUE; - if (sample->bit1 && sample->medium != 0) { - D_SH_8034EA88[D_SH_8034F688++] = sample; - } - } - } -#undef PATCH -} - -s32 func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3) { - UNUSED u32 pad[2]; - u8 *addr; - UNUSED u32 pad1[3]; - s32 sp4C; - struct AudioBankSample *temp_s0; - s32 i; - s32 count; - s32 temp; - - sp4C = 0; - if (D_SH_8034F68C != 0) { - sp4C = 1; - } else { - D_SH_80343CF0 = 0; - } - D_SH_8034F688 = 0; - patch_audio_bank(bankId, mem, patchInfo); - - count = 0; - for (i = 0; i < D_SH_8034F688; i++) { - count += ALIGN16(D_SH_8034EA88[i]->size); - } - - for (i = 0; i < D_SH_8034F688; i++) { - if (D_SH_8034F68C != 0x78) { - temp_s0 = D_SH_8034EA88[i]; - switch (arg3) { - case 0: - temp = temp_s0->medium = patchInfo->medium1; - if (temp != 0) { - if (temp_s0->size) { - } - addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium); - } else { - temp = temp_s0->medium = patchInfo->medium2; - if (temp != 0) { - addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium); - } - } - break; - - case 1: - temp = temp_s0->medium = patchInfo->medium1; - if (temp != 0) { - addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium); - } else { - temp = temp_s0->medium = patchInfo->medium2; - if (temp != 0) { - addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium); - } - } - break; - } - switch ((uintptr_t) addr) { - case 0: - break; - default: - switch (arg3) { - case 0: - if (temp_s0->medium == 1) { - func_sh_802f3d78((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, gAlTbl->unk2); - temp_s0->sampleAddr = addr; - temp_s0->medium = 0; - } else { - func_sh_802f3c38((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, temp_s0->medium); - temp_s0->sampleAddr = addr; - temp_s0->medium = 0; - } - break; - - case 1: - D_SH_8034EC88[D_SH_8034F68C].sample = temp_s0; - D_SH_8034EC88[D_SH_8034F68C].ramAddr = addr; - D_SH_8034EC88[D_SH_8034F68C].encodedInfo = (D_SH_8034F68C << 24) | 0xffffff; - D_SH_8034EC88[D_SH_8034F68C].isFree = FALSE; - D_SH_8034EC88[D_SH_8034F68C].endAndMediumIdentification = temp_s0->sampleAddr + temp_s0->size + temp_s0->medium; - D_SH_8034F68C++; - break; - } - } - continue; - } - break; - } - - D_SH_8034F688 = 0; - if (D_SH_8034F68C != 0 && sp4C == 0) { - temp_s0 = D_SH_8034EC88[D_SH_8034F68C - 1].sample; - temp = (temp_s0->size >> 12); - temp += 1; - count = (uintptr_t) temp_s0->sampleAddr; - func_sh_802f4cb4( - count, - D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, - temp_s0->size, - temp_s0->medium, - temp, - &gUnkQueue2, - D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo); - } -} - -s32 func_sh_802f573c(s32 audioResetStatus) { - struct AudioBankSample *sample; - u32 idx; - u8 *sampleAddr; - u32 size; - s32 unk; - u8 *added; - - if (D_SH_8034F68C > 0) { - if (audioResetStatus != 0) { - if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK)){ - } - D_SH_8034F68C = 0; - return 0; - } - if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK) == -1) { - return 0; - } - idx >>= 0x18; - if (D_SH_8034EC88[idx].isFree == FALSE) { - sample = D_SH_8034EC88[idx].sample; - added = (sample->sampleAddr + sample->size + sample->medium); - if (added == D_SH_8034EC88[idx].endAndMediumIdentification) { - sample->sampleAddr = D_SH_8034EC88[idx].ramAddr; - sample->medium = 0; - } - D_SH_8034EC88[idx].isFree = TRUE; - } - - next: - if (D_SH_8034F68C > 0) { - if (D_SH_8034EC88[D_SH_8034F68C - 1].isFree == TRUE) { - D_SH_8034F68C--; - goto next; - } - sample = D_SH_8034EC88[D_SH_8034F68C - 1].sample; - sampleAddr = sample->sampleAddr; - size = sample->size; - unk = size >> 0xC; - unk += 1; - added = ((sampleAddr + size) + sample->medium); - if (added != D_SH_8034EC88[D_SH_8034F68C - 1].endAndMediumIdentification) { - D_SH_8034EC88[D_SH_8034F68C - 1].isFree = TRUE; - D_SH_8034F68C--; - goto next; - } - size = sample->size; - func_sh_802f4cb4(sampleAddr, D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, size, sample->medium, - unk, &gUnkQueue2, D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo); - } - } - return 1; -} - -s32 func_sh_802f5900(struct AudioBankSample *sample, s32 numLoaded, struct AudioBankSample *arg2[]) { - s32 i; - - for (i = 0; i < numLoaded; i++) { - if (sample->sampleAddr == arg2[i]->sampleAddr) { - break; - } - } - if (i == numLoaded) { - arg2[numLoaded++] = sample; - } - return numLoaded; -} - -s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) { - s32 i; - struct Drum *drum; - struct Instrument *inst; - s32 numLoaded; - s32 numDrums; - s32 numInstruments; - - numLoaded = 0; - numDrums = gCtlEntries[bankId].numDrums; - numInstruments = gCtlEntries[bankId].numInstruments; - - for (i = 0; i < numDrums; i++) { - drum = get_drum(bankId, i); - if (drum == NULL) { - continue; - } - numLoaded = func_sh_802f5900(drum->sound.sample, numLoaded, list); - } - for (i = 0; i < numInstruments; i++) { - inst = get_instrument_inner(bankId, i); - if (inst == NULL) { - continue; - - } - if (inst->normalRangeLo != 0) { - numLoaded = func_sh_802f5900(inst->lowNotesSound.sample, numLoaded, list); - } - if (inst->normalRangeHi != 127) { - numLoaded = func_sh_802f5900(inst->highNotesSound.sample, numLoaded, list); - } - numLoaded = func_sh_802f5900(inst->normalNotesSound.sample, numLoaded, list); - } - return numLoaded; } #endif diff --git a/src/audio/load.h b/src/audio/load.h index d96f27b7..63379d21 100644 --- a/src/audio/load.h +++ b/src/audio/load.h @@ -89,18 +89,25 @@ void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *pat #else void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums); #endif -#ifndef VERSION_SH +#ifdef VERSION_SH +void preload_sequence(u32 seqId, s32 preloadMask); +#else void preload_sequence(u32 seqId, u8 preloadMask); #endif void load_sequence(u32 player, u32 seqId, s32 loadAsync); #ifdef VERSION_SH -void func_sh_802f3158(s32 index, s32 arg1, s32 arg2, OSMesgQueue *retQueue); -u8 *func_sh_802f3220(u32 index, u32 *a1); +void func_sh_802f3158(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue *retQueue); +u8 *func_sh_802f3220(u32 seqId, u32 *a1); struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx); -void *func_802f3f08(s32 poolIdx, s32 arg1, s32 arg2, s32 arg3, OSMesgQueue *retQueue); -s32 func_sh_802f3368(s32 arg0); +s32 func_sh_802f47c8(s32 bankId, u8 idx, s8 *io); +void *func_sh_802f3f08(s32 poolIdx, s32 arg1, s32 arg2, s32 arg3, OSMesgQueue *retQueue); +void func_sh_802f41e4(s32 audioResetStatus); +BAD_RETURN(s32) func_sh_802f3368(s32 bankId); void *func_sh_802f3764(s32 arg0, s32 idx, s32 *arg2); +s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2); +void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3); +void func_sh_802f3288(s32 idx); #endif diff --git a/src/audio/load_sh.c b/src/audio/load_sh.c new file mode 100644 index 00000000..5e79df1f --- /dev/null +++ b/src/audio/load_sh.c @@ -0,0 +1,1640 @@ +#ifdef VERSION_SH +#include +#include + +#include "data.h" +#include "external.h" +#include "heap.h" +#include "load.h" +#include "seqplayer.h" + +#define ALIGN16(val) (((val) + 0xF) & ~0xF) + +struct SharedDma { + /*0x0*/ u8 *buffer; // target, points to pre-allocated buffer + /*0x4*/ uintptr_t source; // device address + /*0x8*/ u16 sizeUnused; // set to bufSize, never read + /*0xA*/ u16 bufSize; // size of buffer + /*0xC*/ u8 unused2; // set to 0, never read + /*0xD*/ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0 + /*0xE*/ u8 ttl; // duration after which the DMA can be discarded +}; // size = 0x10 + +void port_eu_init(void); +void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo); +void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue); + +struct Note *gNotes; + +UNUSED static u32 pad; + +struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; +struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; +struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; + +struct SequenceChannel gSequenceChannelNone; +struct AudioListItem gLayerFreeList; +struct NotePool gNoteFreeLists; + +struct AudioBankSample *D_SH_8034EA88[0x80]; +struct UnkStructSH8034EC88 D_SH_8034EC88[0x80]; +s32 D_SH_8034F688; // index into D_SH_8034EA88 +s32 D_SH_8034F68C; // index or size for D_SH_8034EC88 + +struct PendingDmaAudioBank { + s8 inProgress; + s8 timer; + s8 medium; + struct AudioBank *audioBank; + uintptr_t devAddr; + void *vAddr; + u32 remaining; + u32 transferSize; + u32 encodedInfo; + OSMesgQueue *retQueue; + OSMesgQueue dmaRetQueue; + OSMesg mesgs[1]; + OSIoMesg ioMesg; +}; +struct PendingDmaAudioBank sPendingDmaAudioBanks[16]; + +OSMesgQueue gUnkQueue1; +OSMesg gUnkMesgBufs1[0x10]; +OSMesgQueue gUnkQueue2; +OSMesg gUnkMesgBufs2[0x10]; + +OSMesgQueue gCurrAudioFrameDmaQueue; +OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; +OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; + +OSMesgQueue gAudioDmaMesgQueue; +OSMesg gAudioDmaMesg; +OSIoMesg gAudioDmaIoMesg; + +struct SharedDma *sSampleDmas; +u32 gSampleDmaNumListItems; +u32 sSampleDmaListSize1; +u32 sUnused80226B40; // set to 0, never read + +// Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256. +u8 sSampleDmaReuseQueue1[256]; +u8 sSampleDmaReuseQueue2[256]; +u8 sSampleDmaReuseQueueTail1; +u8 sSampleDmaReuseQueueTail2; +u8 sSampleDmaReuseQueueHead1; +u8 sSampleDmaReuseQueueHead2; + +ALSeqFile *gSeqFileHeader; +ALSeqFile *gAlCtlHeader; +ALSeqFile *gAlTbl; +u8 *gAlBankSets; +u16 gSequenceCount; + +struct CtlEntry *gCtlEntries; + +struct AudioBufferParametersEU gAudioBufferParameters; +u32 sDmaBufSize; +s32 gMaxAudioCmds; +s32 gMaxSimultaneousNotes; + +s16 gTempoInternalToExternal; + +s8 gSoundMode; + +s8 gAudioUpdatesPerFrame; + +extern u64 gAudioGlobalsStartMarker; +extern u64 gAudioGlobalsEndMarker; + +extern u8 gSoundDataADSR[]; // ctl +extern u8 gSoundDataRaw[]; // tbl +extern u8 gMusicData[]; // sequences + +ALSeqFile *get_audio_file_header(s32 arg0); + +void *func_sh_802f3688(s32 bankId); +void *get_bank_or_seq_wrapper(s32 arg0, s32 arg1); +void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); +void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium); +s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr, + void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason); +void func_sh_802f4a4c(s32 audioResetStatus); +void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len); +void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); +struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, + s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo); +void func_sh_802f4dcc(s32 audioResetStatus); +void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus); +void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len); +void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3); +BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3); +s32 func_sh_802f573c(s32 audioResetStatus); +void *func_sh_802f3564(s32 seqId); +s32 func_sh_802f3ec4(s32 arg0, uintptr_t *arg1); +void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes); + +s32 canonicalize_index(s32 poolIdx, s32 idx); + +void decrease_sample_dma_ttls() { + u32 i; + + for (i = 0; i < sSampleDmaListSize1; i++) { + struct SharedDma *temp = &sSampleDmas[i]; + if (temp->ttl != 0) { + temp->ttl--; + if (temp->ttl == 0) { + temp->reuseIndex = sSampleDmaReuseQueueHead1; + sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i; + } + } + } + + for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { + struct SharedDma *temp = &sSampleDmas[i]; + if (temp->ttl != 0) { + temp->ttl--; + if (temp->ttl == 0) { + temp->reuseIndex = sSampleDmaReuseQueueHead2; + sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i; + } + } + } + + sUnused80226B40 = 0; +} + +extern char shindouDebugPrint62[]; // "SUPERDMA" +void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium) { + UNUSED s32 sp60; + struct SharedDma *dma; + s32 hasDma = FALSE; + uintptr_t dmaDevAddr; + UNUSED u32 pad; + u32 dmaIndex; + u32 transfer; + ssize_t bufferPos; + u32 i; + + if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) { + for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { + dma = &sSampleDmas[i]; + bufferPos = devAddr - dma->source; + if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { + // We already have a DMA request for this memory range. + if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) { + // Move the DMA out of the reuse queue, by swapping it with the + // tail, and then incrementing the tail. + if (dma->reuseIndex != sSampleDmaReuseQueueTail2) { + sSampleDmaReuseQueue2[dma->reuseIndex] = + sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; + sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex = + dma->reuseIndex; + } + sSampleDmaReuseQueueTail2++; + } + dma->ttl = 60; + *dmaIndexRef = (u8) i; + return &dma->buffer[(devAddr - dma->source)]; + } + } + + if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) { + // Allocate a DMA from reuse queue 2. This queue can be empty, since + // TTL 60 is pretty large. + dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; + sSampleDmaReuseQueueTail2++; + dma = sSampleDmas + dmaIndex; + hasDma = TRUE; + } + } else { + dma = sSampleDmas + *dmaIndexRef; + bufferPos = devAddr - dma->source; + if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { + // We already have DMA for this memory range. + if (dma->ttl == 0) { + // Move the DMA out of the reuse queue, by swapping it with the + // tail, and then incrementing the tail. + if (dma->reuseIndex != sSampleDmaReuseQueueTail1) { + sSampleDmaReuseQueue1[dma->reuseIndex] = + sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]; + sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex = + dma->reuseIndex; + } + sSampleDmaReuseQueueTail1++; + } + dma->ttl = 2; + return dma->buffer + (devAddr - dma->source); + } + } + + if (!hasDma) { + if (1) {} + // Allocate a DMA from reuse queue 1. This queue will hopefully never + // be empty, since TTL 2 is so small. + dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++]; + dma = sSampleDmas + dmaIndex; + hasDma = TRUE; + } + + transfer = dma->bufSize; + dmaDevAddr = devAddr & ~0xF; + dma->ttl = 2; + dma->source = dmaDevAddr; + dma->sizeUnused = transfer; + func_sh_802f3dd0(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ, + dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue, medium, shindouDebugPrint62); + *dmaIndexRef = dmaIndex; + return (devAddr - dmaDevAddr) + dma->buffer; +} + +void init_sample_dma_buffers(UNUSED s32 arg0) { + s32 i; + + sDmaBufSize = 0x2D0; + sSampleDmas = sound_alloc_uninitialized(&gNotesAndBuffersPool, + gMaxSimultaneousNotes * 4 * sizeof(struct SharedDma) * gAudioBufferParameters.presetUnk4); + + for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) + { + if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) { + break; + } + sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; + sSampleDmas[gSampleDmaNumListItems].source = 0; + sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; + sSampleDmas[gSampleDmaNumListItems].unused2 = 0; + sSampleDmas[gSampleDmaNumListItems].ttl = 0; + gSampleDmaNumListItems++; + } + + for (i = 0; (u32) i < gSampleDmaNumListItems; i++) { + sSampleDmaReuseQueue1[i] = (u8) i; + sSampleDmas[i].reuseIndex = (u8) i; + } + + for (i = gSampleDmaNumListItems; i < 0x100; i++) { + sSampleDmaReuseQueue1[i] = 0; + } + + sSampleDmaReuseQueueTail1 = 0; + sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; + sSampleDmaListSize1 = gSampleDmaNumListItems; + + sDmaBufSize = 0x2D0; + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) { + break; + } + sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; + sSampleDmas[gSampleDmaNumListItems].source = 0; + sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; + sSampleDmas[gSampleDmaNumListItems].unused2 = 0; + sSampleDmas[gSampleDmaNumListItems].ttl = 0; + gSampleDmaNumListItems++; + } + + for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) { + sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i; + sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1); + } + + // This probably meant to touch the range size1..size2 as well... but it + // doesn't matter, since these values are never read anyway. + for (i = gSampleDmaNumListItems; i < 0x100; i++) { + sSampleDmaReuseQueue2[i] = sSampleDmaListSize1; + } + + sSampleDmaReuseQueueTail2 = 0; + sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; +} + +void patch_seq_file(ALSeqFile *seqFile, u8 *data, u16 arg2) { + s32 i; + + seqFile->unk2 = arg2; + seqFile->data = data; + for (i = 0; i < seqFile->seqCount; i++) { + if (seqFile->seqArray[i].len != 0 && seqFile->seqArray[i].medium == 2) { + seqFile->seqArray[i].offset += (uintptr_t)data; + } + } +} + +struct AudioBank *load_banks_immediate(s32 seqId, s32 *outDefaultBank) { + u8 bank; + s32 offset; + s32 i; + void *ret; + + offset = ((u16 *)gAlBankSets)[canonicalize_index(0, seqId)]; + bank = 0xFF; + for (i = gAlBankSets[offset++]; i > 0; i--) { + bank = gAlBankSets[offset++]; + ret = func_sh_802f3688(bank); + } + *outDefaultBank = bank; + return ret; +} + +void preload_sequence(u32 seqId, s32 preloadMask) { + UNUSED s32 pad; + s32 temp; + + seqId = canonicalize_index(0, seqId); + if (preloadMask & PRELOAD_BANKS) { + load_banks_immediate(seqId, &temp); + } + if (preloadMask & PRELOAD_SEQUENCE) { + func_sh_802f3564(seqId); + } +} + +s32 func_sh_802f2f38(struct AudioBankSample *sample, s32 bankId) { + u8 *sp24; + + if (sample->isPatched == TRUE && sample->medium != 0) { + sp24 = func_sh_802f1d90(sample->size, bankId, sample->sampleAddr, sample->medium); + if (sp24 == NULL) { + return -1; + } + if (sample->medium == 1) { + func_sh_802f3d78((uintptr_t) sample->sampleAddr, sp24, sample->size, gAlTbl->unk2); + } else { + func_sh_802f3c38((uintptr_t) sample->sampleAddr, sp24, sample->size, sample->medium); + } + sample->medium = 0; + sample->sampleAddr = sp24; + } +#ifdef AVOID_UB + return 0; +#endif +} + +s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2) { + struct Instrument *instr; + struct Drum *drum; + + if (instId < 0x7F) { + instr = get_instrument_inner(bankId, instId); + if (instr == NULL) { + return -1; + } + if (instr->normalRangeLo != 0) { + func_sh_802f2f38(instr->lowNotesSound.sample, bankId); + } + func_sh_802f2f38(instr->normalNotesSound.sample, bankId); + if (instr->normalRangeHi != 0x7F) { + func_sh_802f2f38(instr->highNotesSound.sample, bankId); + } + //! @bug missing return + } else if (instId == 0x7F) { + drum = get_drum(bankId, arg2); + if (drum == NULL) { + return -1; + } + func_sh_802f2f38(drum->sound.sample, bankId); + return 0; + } +#ifdef AVOID_UB + return 0; +#endif +} + +void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3) { + if (func_802f3f08(2, canonicalize_index(2, arg0), arg1, arg2, arg3) == 0) { + osSendMesg(arg3, 0, 0); + } +} + +void func_sh_802f3158(s32 seqId, s32 numChunks, s32 arg2, OSMesgQueue *retQueue) { + s32 val; + s32 v; + + val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)]; + v = gAlBankSets[val++]; + + while (v > 0) { + func_802f3f08(1, canonicalize_index(1, gAlBankSets[val++]), numChunks, arg2, retQueue); + v--; + } +} + +u8 *func_sh_802f3220(u32 seqId, u32 *a1) { + s32 val; + + val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)]; + *a1 = gAlBankSets[val++]; + if (*a1 == 0) { + return NULL; + } + return &gAlBankSets[val]; +} + +void func_sh_802f3288(s32 idx) { + s32 bankId; + s32 s2; + + idx = ((u16*)gAlBankSets)[canonicalize_index(0, idx)]; + s2 = gAlBankSets[idx++]; + while (s2 > 0) { + s2--; + bankId = canonicalize_index(1, gAlBankSets[idx++]); + + if (unk_pool1_lookup(1, bankId) == NULL) { + func_sh_802f3368(bankId); + if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) { + gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_NOT_LOADED; + } + + continue; + } + + } +} + +BAD_RETURN(s32) func_sh_802f3368(s32 bankId) { + struct SoundMultiPool *pool = &gBankLoadedPool; + struct TemporaryPool *temporary = &pool->temporary; + struct PersistentPool *persistent; + u32 i; + + if (temporary->entries[0].id == bankId) { + temporary->entries[0].id = -1; + } else if (temporary->entries[1].id == bankId) { + temporary->entries[1].id = -1; + } + + persistent = &pool->persistent; + for (i = 0; i < persistent->numEntries; i++) { + if (persistent->entries[i].id == bankId) { + persistent->entries[i].id = -1; + } + + } + + discard_bank(bankId); +} + + +void load_sequence_internal(s32 player, s32 seqId, s32 loadAsync); +void load_sequence(u32 player, u32 seqId, s32 loadAsync) { + load_sequence_internal(player, seqId, loadAsync); +} + +void load_sequence_internal(s32 player, s32 seqId, UNUSED s32 loadAsync) { + struct SequencePlayer *seqPlayer; + u8 *sequenceData; + u32 s0; + s32 count; + u8 bank; + s32 i; + + seqPlayer = &gSequencePlayers[player]; + + seqId = canonicalize_index(0, seqId); + sequence_player_disable(seqPlayer); + + s0 = ((u16 *) gAlBankSets)[seqId]; + count = gAlBankSets[s0++]; + bank = 0xff; + + while (count > 0) { + bank = gAlBankSets[s0++]; + func_sh_802f3688(bank); + count--; + } + + sequenceData = func_sh_802f3564(seqId); + init_sequence_player(player); + seqPlayer->seqId = seqId; + seqPlayer->defaultBank[0] = bank; + seqPlayer->enabled = 1; + seqPlayer->seqData = sequenceData; + seqPlayer->scriptState.pc = sequenceData; + seqPlayer->scriptState.depth = 0; + seqPlayer->delay = 0; + seqPlayer->finished = 0; + + for (i = 0; i < 0x10; i++) { + } +} + +void *func_sh_802f3564(s32 seqId) { + s32 seqId2 = canonicalize_index(0, seqId); + s32 temp; + return func_sh_802f3764(0, seqId2, &temp); +} + +extern u8 gUnkLoadStatus[0x40]; + +void *func_sh_802f3598(s32 idx, s32 *medium) { + void *ret; + ALSeqFile *f; + s32 temp; + s32 sp28; + + f = get_audio_file_header(2); + idx = canonicalize_index(2, idx); + ret = get_bank_or_seq_wrapper(2, idx); + if (ret != NULL) { + if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gUnkLoadStatus[idx] = SOUND_LOAD_STATUS_COMPLETE; + } + + *medium = 0; + return ret; + } + + temp = f->seqArray[idx].magic; + if (temp == 4) { + *medium = f->seqArray[idx].medium; + return f->seqArray[idx].offset; + } else { + ret = func_sh_802f3764(2, idx, &sp28); + if (ret != 0) { + *medium = 0; + return ret; + } + + *medium = f->seqArray[idx].medium; + } + return f->seqArray[idx].offset; + +} + +void *func_sh_802f3688(s32 bankId) { + void *ret; + s32 bankId1; + s32 bankId2; + s32 sp38; + struct PatchStruct patchInfo; + + bankId = canonicalize_index(1, bankId); + bankId1 = gCtlEntries[bankId].bankId1; + bankId2 = gCtlEntries[bankId].bankId2; + + patchInfo.bankId1 = bankId1; + patchInfo.bankId2 = bankId2; + + if (patchInfo.bankId1 != 0xFF) { + patchInfo.baseAddr1 = func_sh_802f3598(patchInfo.bankId1, &patchInfo.medium1); + } else { + patchInfo.baseAddr1 = NULL; + } + + if (bankId2 != 0xFF) { + patchInfo.baseAddr2 = func_sh_802f3598(bankId2, &patchInfo.medium2); + } else { + patchInfo.baseAddr2 = NULL; + } + + if ((ret = func_sh_802f3764(1, bankId, &sp38)) == NULL) { + return NULL; + } + + if (sp38 == 1) { + func_sh_802f5310(bankId, ret, &patchInfo, 0); + } + + return ret; +} + +void *func_sh_802f3764(s32 poolIdx, s32 idx, s32 *arg2) { + s32 size; + ALSeqFile *f; + void *vAddr; + s32 medium; + UNUSED u32 pad2; + u8 *devAddr; + s8 loadStatus; + s32 sp18; + + vAddr = get_bank_or_seq_wrapper(poolIdx, idx); + if (vAddr != NULL) { + *arg2 = 0; + loadStatus = SOUND_LOAD_STATUS_COMPLETE; + } else { + f = get_audio_file_header(poolIdx); + size = f->seqArray[idx].len; + size = ALIGN16(size); + medium = f->seqArray[idx].medium; + sp18 = f->seqArray[idx].magic; + devAddr = f->seqArray[idx].offset; + + + switch (sp18) + { + case 0: + vAddr = unk_pool1_alloc(poolIdx, idx, size); + if (vAddr == NULL) { + return vAddr; + } + break; + case 1: + vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + case 2: + vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + + case 3: + case 4: + vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + } + + *arg2 = 1; + if (medium == 1) { + func_sh_802f3d78((uintptr_t) devAddr, vAddr, size, f->unk2); + } else { + func_sh_802f3c38((uintptr_t) devAddr, vAddr, size, medium); + } + + switch (sp18) { + case 0: + loadStatus = SOUND_LOAD_STATUS_5; + break; + + default: + loadStatus = SOUND_LOAD_STATUS_COMPLETE; + break; + } + } + + switch (poolIdx) { + case 0: + if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gSeqLoadStatus[idx] = loadStatus; + } + break; + + case 1: + if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gBankLoadStatus[idx] = loadStatus; + } + break; + + case 2: + if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gUnkLoadStatus[idx] = loadStatus; + } + break; + } + + return vAddr; +} + +s32 canonicalize_index(s32 poolIdx, s32 idx) { + ALSeqFile *f; + + f = get_audio_file_header(poolIdx); + if (f->seqArray[idx].len == 0) { + idx = (s32) (uintptr_t) f->seqArray[idx].offset; + } + return idx; +} + +void *get_bank_or_seq_wrapper(s32 poolIdx, s32 id) { + void *ret; + + ret = unk_pool1_lookup(poolIdx, id); + if (ret != NULL) { + return ret; + } + ret = get_bank_or_seq(poolIdx, 2, id); + if (ret != 0) { + return ret; + } + return NULL; +} + +ALSeqFile *get_audio_file_header(s32 poolIdx) { + ALSeqFile *ret; + switch (poolIdx) { + default: + ret = NULL; + break; + case 0: + ret = gSeqFileHeader; + break; + case 1: + ret = gAlCtlHeader; + break; + case 2: + ret = gAlTbl; + break; + } + return ret; +} + +void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo) { + struct Instrument *instrument; + void **itInstrs; + struct Instrument **end; + s32 i; + void *patched; + struct Drum *drum; + s32 numDrums; + s32 numInstruments; + +#define BASE_OFFSET(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) +#define PATCH(x, base) (patched = BASE_OFFSET(x, base)) +#define PATCH_MEM(x) x = PATCH(x, mem) + + numDrums = gCtlEntries[bankId].numDrums; + numInstruments = gCtlEntries[bankId].numInstruments; + itInstrs = (void **) mem->drums; + if (mem->drums) { + } + if (itInstrs != NULL && numDrums != 0) { + if (1) { + mem->drums = PATCH(itInstrs, mem); + } + for (i = 0; i < numDrums; i++) { + patched = mem->drums[i]; + if (patched != NULL) { + drum = PATCH(patched, mem); + mem->drums[i] = drum; + if (drum->loaded == 0) { + patch_sound(&drum->sound, mem, patchInfo); + patched = drum->envelope; + drum->envelope = BASE_OFFSET(patched, mem); + drum->loaded = 1; + } + + } + } + } + + if (numInstruments > 0) { + itInstrs = (void **) mem->instruments; + end = numInstruments + (struct Instrument **) itInstrs; + + do { + if (*itInstrs != NULL) { + *itInstrs = BASE_OFFSET(*itInstrs, mem); + instrument = *itInstrs; + + if (instrument->loaded == 0) { + if (instrument->normalRangeLo != 0) { + patch_sound(&instrument->lowNotesSound, mem, patchInfo); + } + patch_sound(&instrument->normalNotesSound, mem, patchInfo); + if (instrument->normalRangeHi != 0x7F) { + patch_sound(&instrument->highNotesSound, mem, patchInfo); + } + patched = instrument->envelope; + + instrument->envelope = BASE_OFFSET(patched, mem); + instrument->loaded = 1; + } + } + itInstrs = (void **) ((struct Instrument **) itInstrs) + 1; + } while ((struct Instrument **) itInstrs != ((void) 0, end)); //! This is definitely fake + } + gCtlEntries[bankId].drums = mem->drums; + gCtlEntries[bankId].instruments = mem->instruments; +#undef PATCH_MEM +#undef PATCH +#undef BASE_OFFSET +} + +extern char shindouDebugPrint81[]; // "FastCopy" +extern char shindouDebugPrint82[]; // "FastCopy" +void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium) { + nbytes = ALIGN16(nbytes); + osInvalDCache(vAddr, nbytes); + +again: + if (gAudioLoadLockSH != 0) { + goto again; + } + + if (nbytes >= 0x400U) { + func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, 0x400, &gAudioDmaMesgQueue, medium, shindouDebugPrint81); + osRecvMesg(&gAudioDmaMesgQueue, NULL, 1); + nbytes = nbytes - 0x400; + devAddr = devAddr + 0x400; + vAddr = (u8*)vAddr + 0x400; + goto again; + } + + if (nbytes != 0) { + func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, nbytes, &gAudioDmaMesgQueue, medium, shindouDebugPrint82); + osRecvMesg(&gAudioDmaMesgQueue, NULL, 1); + } +} + +void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { + uintptr_t sp1C; + + sp1C = devAddr; + osInvalDCache(vAddr, nbytes); + func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); +} + +s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr, void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason) { + OSPiHandle *handle; + if (gAudioLoadLockSH >= 0x11U) { + return -1; + } + switch (medium) { + case 2: + handle = osCartRomInit(); + break; + case 3: + handle = osDriveRomInit(); + break; + default: + return 0; + } + if ((size & 0xf) != 0) { + size = ALIGN16(size); + } + m->hdr.pri = pri; + m->hdr.retQueue = retQueue; + m->dramAddr = dramAddr; + m->devAddr = devAddr; + m->size = size; + handle->transferInfo.cmdType = 2; + osEPiStartDma(handle, m, direction); + return 0; +} + +s32 func_sh_802f3ec4(UNUSED s32 arg0, UNUSED uintptr_t *arg1) { + return 0; +} + +void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes) { +} + +void *func_sh_802f3ee8(s32 poolIdx, s32 idx) { + s32 temp; + return func_sh_802f3764(poolIdx, idx, &temp); +} + +void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue) { + s32 size; + ALSeqFile *f; + void *vAddr; + s32 medium; + s32 sp18; + uintptr_t devAddr; + s32 loadStatus; + + switch (poolIdx) { + case 0: + if (gSeqLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { + return 0; + } + break; + case 1: + if (gBankLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { + return 0; + } + break; + case 2: + if (gUnkLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) { + return 0; + } + break; + + } + vAddr = get_bank_or_seq_wrapper(poolIdx, idx); + if (vAddr != NULL) { + loadStatus = 2; + osSendMesg(retQueue, (OSMesg) (arg3 << 0x18), 0); + } else { + f = get_audio_file_header(poolIdx); + size = f->seqArray[idx].len; + size = ALIGN16(size); + medium = f->seqArray[idx].medium; + sp18 = f->seqArray[idx].magic; + devAddr = (uintptr_t) f->seqArray[idx].offset; + loadStatus = 2; + + switch (sp18) { + case 0: + vAddr = unk_pool1_alloc(poolIdx, idx, size); + if (vAddr == NULL) { + return vAddr; + } + loadStatus = SOUND_LOAD_STATUS_5; + break; + case 1: + vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + case 2: + vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + + case 4: + case 3: + vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx); + if (vAddr == NULL) { + return vAddr; + } + break; + } + + func_sh_802f4cb4(devAddr, vAddr, size, medium, numChunks, retQueue, (arg3 << 0x18) | (poolIdx << 0x10) | (idx << 8) | loadStatus); + loadStatus = SOUND_LOAD_STATUS_IN_PROGRESS; + } + + switch (poolIdx) { + case 0: + if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gSeqLoadStatus[idx] = loadStatus; + } + break; + + case 1: + if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gBankLoadStatus[idx] = loadStatus; + } + break; + + case 2: + if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) { + gUnkLoadStatus[idx] = loadStatus; + } + break; + } + + return vAddr; +} + +void func_sh_802f41e4(s32 audioResetStatus) { + func_sh_802f4a4c(audioResetStatus); + func_sh_802f573c(audioResetStatus); + func_sh_802f4dcc(audioResetStatus); +} + +#if defined(VERSION_SH) +u8 gShindouSoundBanksHeader[] = { +#include "sound/ctl_header.inc.c" +}; + +u8 gBankSetsData[] = { +#include "sound/bank_sets.inc.c" +}; + +u8 gShindouSampleBanksHeader[] = { +#include "sound/tbl_header.inc.c" +}; + +u8 gShindouSequencesHeader[] = { +#include "sound/sequences_header.inc.c" +}; +#endif + +// (void) must be omitted from parameters +void audio_init() { + UNUSED s8 pad[0x34]; + s32 i, j, k; + s32 lim; + u64 *ptr64; + void *data; + UNUSED u8 pad2[4]; + s32 seqCount; + + gAudioLoadLockSH = 0; + + for (i = 0; i < gAudioHeapSize / 8; i++) { + ((u64 *) gAudioHeap)[i] = 0; + } + +#ifdef TARGET_N64 + // It seems boot.s doesn't clear the .bss area for audio, so do it here. + lim = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; + ptr64 = &gAudioGlobalsStartMarker; + for (k = lim; k >= 0; k--) { + *ptr64++ = 0; + } +#endif + + D_EU_802298D0 = 16.713f; + gRefreshRate = 60; + port_eu_init(); + +#ifdef TARGET_N64 + eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n", + (uintptr_t) &gAudioGlobalsStartMarker, + (uintptr_t) &gAudioGlobalsEndMarker, + (uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker + ); +#endif + + eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize); + + for (i = 0; i < NUMAIBUFFERS; i++) { + gAiBufferLengths[i] = 0xa0; + } + + gAudioFrameCount = 0; + gAudioTaskIndex = 0; + gCurrAiBufferIndex = 0; + gSoundMode = 0; + gAudioTask = NULL; + gAudioTasks[0].task.t.data_size = 0; + gAudioTasks[1].task.t.data_size = 0; + osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1); + osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs, + ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs)); + osCreateMesgQueue(&gUnkQueue1, gUnkMesgBufs1, 0x10); + osCreateMesgQueue(&gUnkQueue2, gUnkMesgBufs2, 0x10); + gCurrAudioFrameDmaCount = 0; + gSampleDmaNumListItems = 0; + + sound_init_main_pools(gAudioInitPoolSize); + + for (i = 0; i < NUMAIBUFFERS; i++) { + gAiBuffers[i] = sound_alloc_uninitialized(&gAudioInitPool, AIBUFFER_LEN); + + for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { + gAiBuffers[i][j] = 0; + } + } + + gAudioResetPresetIdToLoad = 0; + gAudioResetStatus = 1; + audio_shut_down_and_reset_step(); + + // Not sure about these prints + eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0); + eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0); + eu_stubbed_printf_0("Main Heap Initialize.\n"); + + // Load headers for sounds and sequences + gSeqFileHeader = (ALSeqFile *) gShindouSequencesHeader; + gAlCtlHeader = (ALSeqFile *) gShindouSoundBanksHeader; + gAlTbl = (ALSeqFile *) gShindouSampleBanksHeader; + gAlBankSets = gBankSetsData; + gSequenceCount = (s16) gSeqFileHeader->seqCount; + patch_seq_file(gSeqFileHeader, gMusicData, D_SH_80315EF4); + patch_seq_file(gAlCtlHeader, gSoundDataADSR, D_SH_80315EF8); + patch_seq_file(gAlTbl, gSoundDataRaw, D_SH_80315EFC); + seqCount = gAlCtlHeader->seqCount; + gCtlEntries = sound_alloc_uninitialized(&gAudioInitPool, seqCount * sizeof(struct CtlEntry)); + for (i = 0; i < seqCount; i++) { + gCtlEntries[i].bankId1 = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf >> 8) & 0xff); + gCtlEntries[i].bankId2 = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf & 0xff); + gCtlEntries[i].numInstruments = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums >> 8) & 0xff); + gCtlEntries[i].numDrums = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums & 0xff); + } + data = sound_alloc_uninitialized(&gAudioInitPool, D_SH_80315EF0); + if (data == NULL) { + D_SH_80315EF0 = 0; + } + sound_alloc_pool_init(&gUnkPool1.pool, data, D_SH_80315EF0); + init_sequence_players(); +} + +s32 func_sh_802f47c8(s32 bankId, u8 idx, s8 *io) { + struct AudioBankSample *sample = func_sh_802f4978(bankId, idx); + struct PendingDmaSample *temp; + if (sample == NULL) { + *io = 0; + return -1; + } + if (sample->medium == 0) { + *io = 2; + return 0; + } + temp = &D_SH_80343D00.arr[D_SH_80343D00.someIndex]; + if (temp->state == 3) { + temp->state = 0; + } + temp->sample = *sample; + temp->io = io; + temp->vAddr = func_sh_802f1d40(sample->size, bankId, sample->sampleAddr, sample->medium); + if (temp->vAddr == NULL) { + if (sample->medium == 1 || sample->codec == CODEC_SKIP) { + *io = 0; + return -1; + } else { + *io = 3; + return -1; + } + } + temp->state = 1; + temp->remaining = ALIGN16(sample->size); + temp->resultSampleAddr = (u8 *) temp->vAddr; + temp->devAddr = (uintptr_t) sample->sampleAddr; + temp->medium = sample->medium; + temp->bankId = bankId; + temp->idx = idx; + D_SH_80343D00.someIndex ^= 1; + return 0; +} + +struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx) { + struct Drum *drum; + struct Instrument *inst; + struct AudioBankSample *ret; + + if (idx < 128) { + inst = get_instrument_inner(bankId, idx); + if (inst == 0) { + return NULL; + } + ret = inst->normalNotesSound.sample; + } else { + drum = get_drum(bankId, idx - 128); + if (drum == 0) { + return NULL; + } + ret = drum->sound.sample; + } + return ret; +} + +void stub_sh_802f49dc(void) { +} + +void func_sh_802f49e4(struct PendingDmaSample *arg0) { + struct AudioBankSample *sample = func_sh_802f4978(arg0->bankId, arg0->idx); + if (sample != NULL) { + arg0->sample = *sample; + sample->sampleAddr = arg0->resultSampleAddr; + sample->medium = 0; + } +} + +void func_sh_802f4a4c(s32 audioResetStatus) { + ALSeqFile *alTbl; + struct PendingDmaSample *entry; + + s32 i; + + alTbl = gAlTbl; + + for (i = 0; i < 2; i++) { + entry = &D_SH_80343D00.arr[i]; + switch (entry->state) { + case 2: + osRecvMesg(&entry->queue, NULL, 1); + if (audioResetStatus != 0) { + entry->state = 3; + break; + } + // fallthrough + case 1: + entry->state = 2; + if (entry->remaining == 0) { + func_sh_802f49e4(entry); + entry->state = 3; + *entry->io = 1; + } else if (entry->remaining < 0x1000) { + if (entry->medium == 1) { + func_sh_802f4c5c(entry->devAddr, entry->vAddr, entry->remaining, alTbl->unk2); + } else { + func_sh_802f4bd8(entry, entry->remaining); + } + entry->remaining = 0; + } else { + if (entry->medium == 1) { + func_sh_802f4c5c(entry->devAddr, entry->vAddr, 0x1000, alTbl->unk2); + } else { + func_sh_802f4bd8(entry, 0x1000); + } + entry->remaining = (s32) (entry->remaining - 0x1000); + entry->vAddr = (u8 *) entry->vAddr + 0x1000; + entry->devAddr = entry->devAddr + 0x1000; + } + break; + } + } +} + +extern char shindouDebugPrint102[]; // "SLOWCOPY" +void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len) { // len must be signed + osInvalDCache(arg0->vAddr, len); + osCreateMesgQueue(&arg0->queue, arg0->mesgs, 1); + func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->queue, arg0->medium, shindouDebugPrint102); +} + +void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { + uintptr_t sp1C; + + sp1C = devAddr; + osInvalDCache(vAddr, nbytes); + func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); +} + +struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo) { + struct PendingDmaAudioBank *item; + s32 i; + + for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) { + if (sPendingDmaAudioBanks[i].inProgress == 0) { + item = &sPendingDmaAudioBanks[i]; + break; + } + } + if (i == ARRAY_COUNT(sPendingDmaAudioBanks)) { + return NULL; + } + + item->inProgress = 1; + item->devAddr = devAddr; + item->audioBank = vAddr; + item->vAddr = vAddr; + item->remaining = size; + if (numChunks == 0) { + item->transferSize = 0x1000; + } else { + item->transferSize = ((size / numChunks) + 0xFF) & ~0xFF; + if (item->transferSize < 0x100) { + item->transferSize = 0x100; + } + } + item->retQueue = retQueue; + item->timer = 3; + item->medium = medium; + item->encodedInfo = encodedInfo; + osCreateMesgQueue(&item->dmaRetQueue, item->mesgs, 1); + return item; +} + +void func_sh_802f4dcc(s32 audioResetStatus) { + s32 i; + + if (gAudioLoadLockSH != 1) { + for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) { + if (sPendingDmaAudioBanks[i].inProgress == 1) { + func_sh_802f4e50(&sPendingDmaAudioBanks[i], audioResetStatus); + } + } + } +} + +void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus) { + ALSeqFile *alSeqFile; + u32 *encodedInfo; + OSMesg mesg; + u32 temp; + u32 bankId; + s32 bankId1; + s32 bankId2; + struct PatchStruct patchStruct; + alSeqFile = gAlTbl; + if (audioBank->timer >= 2) { + audioBank->timer--; + return; + } + if (audioBank->timer == 1) { + audioBank->timer = 0; + } else { + if (audioResetStatus != 0) { + osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_BLOCK); + audioBank->inProgress = 0; + return; + } + if (osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_NOBLOCK) == -1) { + return; + } + } + + encodedInfo = &audioBank->encodedInfo; + if (audioBank->remaining == 0) { + mesg = (OSMesg) audioBank->encodedInfo; +#pragma GCC diagnostic push +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wself-assign" +#endif + mesg = mesg; //! needs an extra read from mesg here to match... +#pragma GCC diagnostic pop + temp = *encodedInfo; + bankId = (temp >> 8) & 0xFF; + switch ((u8) (temp >> 0x10)) { + case 0: + if (gSeqLoadStatus[bankId] != SOUND_LOAD_STATUS_5) { + gSeqLoadStatus[bankId] = (u8) (temp & 0xFF); + } + break; + case 2: + if (gUnkLoadStatus[bankId] != SOUND_LOAD_STATUS_5) { + gUnkLoadStatus[bankId] = (u8) (temp & 0xFF); + } + break; + case 1: + if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) { + gBankLoadStatus[bankId] = (u8) (temp & 0xFF); + } + bankId1 = gCtlEntries[bankId].bankId1; + bankId2 = gCtlEntries[bankId].bankId2; + patchStruct.bankId1 = bankId1; + patchStruct.bankId2 = bankId2; + if (bankId1 != 0xFF) { + patchStruct.baseAddr1 = func_sh_802f3598(bankId1, &patchStruct.medium1); + } else { + patchStruct.baseAddr1 = NULL; + } + if (bankId2 != 0xFF) { + patchStruct.baseAddr2 = func_sh_802f3598(bankId2, &patchStruct.medium2); + } else { + patchStruct.baseAddr2 = NULL; + } + + func_sh_802f5310(bankId, audioBank->audioBank, &patchStruct, 1); + break; + } + mesg = (OSMesg) audioBank->encodedInfo; + audioBank->inProgress = 0; + osSendMesg(audioBank->retQueue, mesg, OS_MESG_NOBLOCK); + } else if (audioBank->remaining < audioBank->transferSize) { + if (audioBank->medium == 1) { + func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->remaining, alSeqFile->unk2); + } else { + func_sh_802f50ec(audioBank, audioBank->remaining); + } + + audioBank->remaining = 0; + } else { + if (audioBank->medium == 1) { + func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->transferSize, alSeqFile->unk2); + } else { + func_sh_802f50ec(audioBank, audioBank->transferSize); + } + + audioBank->remaining -= audioBank->transferSize; + audioBank->devAddr += audioBank->transferSize; + audioBank->vAddr = ((u8 *) audioBank->vAddr) + audioBank->transferSize; + } +} + +extern char shindouDebugPrint110[]; // "BGCOPY" +void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len) { + len += 0xf; + len &= ~0xf; + osInvalDCache(arg0->vAddr, len); + osCreateMesgQueue(&arg0->dmaRetQueue, arg0->mesgs, 1); + func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->dmaRetQueue, arg0->medium, shindouDebugPrint110); +} + + +void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) { + uintptr_t sp1C; + + sp1C = devAddr; + osInvalDCache(vAddr, nbytes); + func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes); +} + +void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo) { + struct AudioBankSample *sample; + void *patched; + +#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) + + if ((uintptr_t) sound->sample <= 0x80000000) { + sample = sound->sample = PATCH(sound->sample, memBase); + if (sample->size != 0 && sample->isPatched != TRUE) { + sample->loop = PATCH(sample->loop, memBase); + sample->book = PATCH(sample->book, memBase); + switch (sample->medium) { + case 0: + sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr1); + sample->medium = patchInfo->medium1; + break; + case 1: + sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr2); + sample->medium = patchInfo->medium2; + break; + + case 2: + case 3: + break; + } + sample->isPatched = TRUE; + if (sample->bit1 && sample->medium != 0) { + D_SH_8034EA88[D_SH_8034F688++] = sample; + } + } + } +#undef PATCH +} + +BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3) { + UNUSED u32 pad[2]; + u8 *addr; + UNUSED u32 pad1[3]; + s32 sp4C; + struct AudioBankSample *temp_s0; + s32 i; + uintptr_t count; + s32 temp; + + sp4C = 0; + if (D_SH_8034F68C != 0) { + sp4C = 1; + } else { + D_SH_80343CF0 = 0; + } + D_SH_8034F688 = 0; + patch_audio_bank(bankId, mem, patchInfo); + + count = 0; + for (i = 0; i < D_SH_8034F688; i++) { + count += ALIGN16(D_SH_8034EA88[i]->size); + } + + for (i = 0; i < D_SH_8034F688; i++) { + if (D_SH_8034F68C != 0x78) { + temp_s0 = D_SH_8034EA88[i]; + switch (arg3) { + case 0: + temp = temp_s0->medium = patchInfo->medium1; + if (temp != 0) { + if (temp_s0->size) { + } + addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium); + } else { + temp = temp_s0->medium = patchInfo->medium2; + if (temp != 0) { + addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium); + } + } + break; + + case 1: + temp = temp_s0->medium = patchInfo->medium1; + if (temp != 0) { + addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium); + } else { + temp = temp_s0->medium = patchInfo->medium2; + if (temp != 0) { + addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium); + } + } + break; + } + switch ((uintptr_t) addr) { + case 0: + break; + default: + switch (arg3) { + case 0: + if (temp_s0->medium == 1) { + func_sh_802f3d78((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, gAlTbl->unk2); + temp_s0->sampleAddr = addr; + temp_s0->medium = 0; + } else { + func_sh_802f3c38((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, temp_s0->medium); + temp_s0->sampleAddr = addr; + temp_s0->medium = 0; + } + break; + + case 1: + D_SH_8034EC88[D_SH_8034F68C].sample = temp_s0; + D_SH_8034EC88[D_SH_8034F68C].ramAddr = addr; + D_SH_8034EC88[D_SH_8034F68C].encodedInfo = (D_SH_8034F68C << 24) | 0xffffff; + D_SH_8034EC88[D_SH_8034F68C].isFree = FALSE; + D_SH_8034EC88[D_SH_8034F68C].endAndMediumIdentification = temp_s0->sampleAddr + temp_s0->size + temp_s0->medium; + D_SH_8034F68C++; + break; + } + } + continue; + } + break; + } + + D_SH_8034F688 = 0; + if (D_SH_8034F68C != 0 && sp4C == 0) { + temp_s0 = D_SH_8034EC88[D_SH_8034F68C - 1].sample; + temp = (temp_s0->size >> 12); + temp += 1; + count = (uintptr_t) temp_s0->sampleAddr; + func_sh_802f4cb4( + count, + D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, + temp_s0->size, + temp_s0->medium, + temp, + &gUnkQueue2, + D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo); + } +} + +s32 func_sh_802f573c(s32 audioResetStatus) { + struct AudioBankSample *sample; + u32 idx; + u8 *sampleAddr; + u32 size; + s32 unk; + u8 *added; + + if (D_SH_8034F68C > 0) { + if (audioResetStatus != 0) { + if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK)){ + } + D_SH_8034F68C = 0; + return 0; + } + if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK) == -1) { + return 0; + } + idx >>= 0x18; + if (D_SH_8034EC88[idx].isFree == FALSE) { + sample = D_SH_8034EC88[idx].sample; + added = (sample->sampleAddr + sample->size + sample->medium); + if (added == D_SH_8034EC88[idx].endAndMediumIdentification) { + sample->sampleAddr = D_SH_8034EC88[idx].ramAddr; + sample->medium = 0; + } + D_SH_8034EC88[idx].isFree = TRUE; + } + +next: + if (D_SH_8034F68C > 0) { + if (D_SH_8034EC88[D_SH_8034F68C - 1].isFree == TRUE) { + D_SH_8034F68C--; + goto next; + } + sample = D_SH_8034EC88[D_SH_8034F68C - 1].sample; + sampleAddr = sample->sampleAddr; + size = sample->size; + unk = size >> 0xC; + unk += 1; + added = ((sampleAddr + size) + sample->medium); + if (added != D_SH_8034EC88[D_SH_8034F68C - 1].endAndMediumIdentification) { + D_SH_8034EC88[D_SH_8034F68C - 1].isFree = TRUE; + D_SH_8034F68C--; + goto next; + } + size = sample->size; + func_sh_802f4cb4((uintptr_t) sampleAddr, D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, size, sample->medium, + unk, &gUnkQueue2, D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo); + } + } + return 1; +} + +s32 func_sh_802f5900(struct AudioBankSample *sample, s32 numLoaded, struct AudioBankSample *arg2[]) { + s32 i; + + for (i = 0; i < numLoaded; i++) { + if (sample->sampleAddr == arg2[i]->sampleAddr) { + break; + } + } + if (i == numLoaded) { + arg2[numLoaded++] = sample; + } + return numLoaded; +} + +s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) { + s32 i; + struct Drum *drum; + struct Instrument *inst; + s32 numLoaded; + s32 numDrums; + s32 numInstruments; + + numLoaded = 0; + numDrums = gCtlEntries[bankId].numDrums; + numInstruments = gCtlEntries[bankId].numInstruments; + + for (i = 0; i < numDrums; i++) { + drum = get_drum(bankId, i); + if (drum == NULL) { + continue; + } + numLoaded = func_sh_802f5900(drum->sound.sample, numLoaded, list); + } + for (i = 0; i < numInstruments; i++) { + inst = get_instrument_inner(bankId, i); + if (inst == NULL) { + continue; + + } + if (inst->normalRangeLo != 0) { + numLoaded = func_sh_802f5900(inst->lowNotesSound.sample, numLoaded, list); + } + if (inst->normalRangeHi != 127) { + numLoaded = func_sh_802f5900(inst->highNotesSound.sample, numLoaded, list); + } + numLoaded = func_sh_802f5900(inst->normalNotesSound.sample, numLoaded, list); + } + return numLoaded; +} +#endif diff --git a/src/audio/playback.c b/src/audio/playback.c index dc07fd78..ff42e765 100644 --- a/src/audio/playback.c +++ b/src/audio/playback.c @@ -15,7 +15,7 @@ void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput); #ifdef VERSION_SH void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo) #else -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb) +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol) #endif { struct NoteSubEu *sub = ¬e->noteSubEu; @@ -30,7 +30,7 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb) UNUSED u32 pad1; f32 velocity; u8 pan; - u8 reverb; + u8 reverbVol; struct ReverbBitsData reverbBits; #endif @@ -38,7 +38,7 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb) note_set_resampling_rate(note, reverbInfo->freqScale); velocity = reverbInfo->velocity; pan = reverbInfo->pan; - reverb = reverbInfo->reverb; + reverbVol = reverbInfo->reverbVol; reverbBits = reverbInfo->reverbBits.s; pan &= 0x7f; #else @@ -119,7 +119,7 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb) } #ifdef VERSION_SH -if (velocity < 0.0f) { + if (velocity < 0.0f) { velocity = 0.0f; } if (velocity > 1.0f) { @@ -128,7 +128,7 @@ if (velocity < 0.0f) { sub->targetVolLeft = ((s32) (velocity * volLeft * 4095.999f)); sub->targetVolRight = ((s32) (velocity * volRight * 4095.999f)); - sub->bankId = reverbInfo->bankId; + sub->synthesisVolume = reverbInfo->synthesisVolume; sub->filter = reverbInfo->filter; #else if (velocity < 0.0f) { @@ -144,11 +144,12 @@ if (velocity < 0.0f) { sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5; #endif - if (sub->reverbVol != reverb) { + //! @bug for the change to UQ0.7, the if statement should also have been changed accordingly + if (sub->reverbVol != reverbVol) { #ifdef VERSION_SH - sub->reverbVol = reverb >> 1; + sub->reverbVol = reverbVol >> 1; #else - sub->reverbVol = reverb; + sub->reverbVol = reverbVol; #endif sub->envMixerNeedsInit = TRUE; return; @@ -345,7 +346,7 @@ void process_notes(void) { #ifndef VERSION_SH f32 frequency; #if defined(VERSION_JP) || defined(VERSION_US) - u8 reverb; + u8 reverbVol; #endif f32 velocity; #if defined(VERSION_JP) || defined(VERSION_US) @@ -359,11 +360,11 @@ void process_notes(void) { struct NoteSubEu *noteSubEu; #ifndef VERSION_SH UNUSED u8 pad[12]; - u8 reverb; + u8 reverbVol; UNUSED u8 pad3; u8 pan; #else - u8 pad[8]; + UNUSED u8 pad[8]; struct ReverbInfo reverbInfo; #endif u8 bookOffset; @@ -508,9 +509,9 @@ void process_notes(void) { reverbInfo.freqScale = attributes->freqScale; reverbInfo.velocity = attributes->velocity; reverbInfo.pan = attributes->pan; - reverbInfo.reverb = attributes->reverb; + reverbInfo.reverbVol = attributes->reverbVol; reverbInfo.reverbBits = attributes->reverbBits; - reverbInfo.bankId = attributes->unk1; + reverbInfo.synthesisVolume = attributes->synthesisVolume; reverbInfo.filter = attributes->filter; bookOffset = noteSubEu->bookOffset; } else { @@ -518,8 +519,8 @@ void process_notes(void) { reverbInfo.velocity = playbackState->parentLayer->noteVelocity; reverbInfo.pan = playbackState->parentLayer->notePan; reverbInfo.reverbBits = playbackState->parentLayer->reverbBits; - reverbInfo.reverb = playbackState->parentLayer->seqChannel->reverb; - reverbInfo.bankId = playbackState->parentLayer->seqChannel->unkSH0C; + reverbInfo.reverbVol = playbackState->parentLayer->seqChannel->reverbVol; + reverbInfo.synthesisVolume = playbackState->parentLayer->seqChannel->synthesisVolume; reverbInfo.filter = playbackState->parentLayer->seqChannel->filter; bookOffset = playbackState->parentLayer->seqChannel->bookOffset & 0x7; if (playbackState->parentLayer->seqChannel->seqPlayer->muted @@ -538,7 +539,7 @@ void process_notes(void) { frequency = attributes->freqScale; velocity = attributes->velocity; pan = attributes->pan; - reverb = attributes->reverb; + reverbVol = attributes->reverbVol; if (1) { } bookOffset = noteSubEu->bookOffset; @@ -546,7 +547,7 @@ void process_notes(void) { frequency = playbackState->parentLayer->noteFreqScale; velocity = playbackState->parentLayer->noteVelocity; pan = playbackState->parentLayer->notePan; - reverb = playbackState->parentLayer->seqChannel->reverb; + reverbVol = playbackState->parentLayer->seqChannel->reverbVol; bookOffset = playbackState->parentLayer->seqChannel->bookOffset & 0x7; } @@ -554,7 +555,7 @@ void process_notes(void) { frequency *= gAudioBufferParameters.resampleRate; velocity = velocity * scale * scale; note_set_resampling_rate(note, frequency); - note_set_vel_pan_reverb(note, velocity, pan, reverb); + note_set_vel_pan_reverb(note, velocity, pan, reverbVol); #endif noteSubEu->bookOffset = bookOffset; skip:; @@ -603,12 +604,12 @@ void process_notes(void) { frequency = attributes->freqScale; velocity = attributes->velocity; pan = attributes->pan; - reverb = attributes->reverb; + reverbVol = attributes->reverbVol; } else { frequency = note->parentLayer->noteFreqScale; velocity = note->parentLayer->noteVelocity; pan = note->parentLayer->notePan; - reverb = note->parentLayer->seqChannel->reverb; + reverbVol = note->parentLayer->seqChannel->reverbVol; } scale = note->adsrVolScale; @@ -621,7 +622,7 @@ void process_notes(void) { scale *= 4.3498e-5f; // ~1 / 23000 velocity = velocity * scale * scale; note_set_frequency(note, frequency); - note_set_vel_pan_reverb(note, velocity, pan, reverb); + note_set_vel_pan_reverb(note, velocity, pan, reverbVol); continue; } #endif @@ -746,9 +747,9 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa attributes->reverbBits = seqLayer->reverbBits; #endif if (seqLayer->seqChannel != NULL) { - attributes->reverb = seqLayer->seqChannel->reverb; + attributes->reverbVol = seqLayer->seqChannel->reverbVol; #ifdef VERSION_SH - attributes->unk1 = seqLayer->seqChannel->unkSH0C; + attributes->synthesisVolume = seqLayer->seqChannel->synthesisVolume; attributes->filter = seqLayer->seqChannel->filter; if (seqLayer->seqChannel->seqPlayer->muted && (seqLayer->seqChannel->muteBehavior & 8) != 0) { note->noteSubEu.finished = TRUE; @@ -1159,7 +1160,7 @@ void note_init_for_layer(struct Note *note, struct SequenceChannelLayer *seqLaye build_synthetic_wave(note, seqLayer, instId); } #ifdef VERSION_SH - note->unkSH33 = seqLayer->seqChannel->bankId; + note->bankId = seqLayer->seqChannel->bankId; #else sub->bankId = seqLayer->seqChannel->bankId; #endif @@ -1444,7 +1445,7 @@ void note_init_all(void) { #if defined(VERSION_EU) || defined(VERSION_SH) note->waveId = 0; #else - note->reverb = 0; + note->reverbVol = 0; note->usesHeadsetPanEffects = FALSE; note->sampleCount = 0; note->instOrWave = 0; diff --git a/src/audio/playback.h b/src/audio/playback.h index d0eaf2ba..e2e15bf9 100644 --- a/src/audio/playback.h +++ b/src/audio/playback.h @@ -33,7 +33,7 @@ void note_init_all(void); #if defined(VERSION_SH) void note_set_vel_pan_reverb(struct Note *note, struct ReverbInfo *reverbInfo); #elif defined(VERSION_EU) -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb); +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverbVol); #endif #if defined(VERSION_EU) || defined(VERSION_SH) diff --git a/src/audio/port_eu.c b/src/audio/port_eu.c index 636d0143..525ddd37 100644 --- a/src/audio/port_eu.c +++ b/src/audio/port_eu.c @@ -29,7 +29,6 @@ extern struct EuAudioCmd sAudioCmd[0x100]; void func_8031D690(s32 player, FadeT fadeInTime); void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime); -void port_eu_init_queues(void); void decrease_sample_dma_ttls(void); s32 audio_shut_down_and_reset_step(void); void func_802ad7ec(u32); @@ -300,7 +299,7 @@ void func_802ad7ec(u32 arg0) { chan->changes.as_bitfields.freqScale = TRUE; break; case 5: - chan->reverb = cmd->u2.as_s8; + chan->reverbVol = cmd->u2.as_s8; break; case 6: if (cmd->u.s.arg3 < 8) { diff --git a/src/audio/unk_shindou_audio_file.c b/src/audio/port_sh.c similarity index 87% rename from src/audio/unk_shindou_audio_file.c rename to src/audio/port_sh.c index c2ed3159..8c657b65 100644 --- a/src/audio/unk_shindou_audio_file.c +++ b/src/audio/port_sh.c @@ -1,4 +1,5 @@ #ifdef VERSION_SH +// TODO: merge this with port_eu.c? #include @@ -7,6 +8,7 @@ #include "load.h" #include "synthesis.h" #include "internal.h" +#include "seqplayer.h" #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80 #define SAMPLES_TO_OVERPRODUCE 0x10 @@ -15,12 +17,13 @@ extern s32 D_SH_80314FC8; extern struct SPTask *D_SH_80314FCC; extern u8 D_SH_80315098; extern u8 D_SH_8031509C; +extern OSMesgQueue *D_SH_80350F68; -void func_sh_802f62e0(s32 playerIndex, s32 numFrames); -void func_sh_802f6288(s32 arg0, s32 numFrames); -void func_sh_802f6554(u32 arg0); +void func_8031D690(s32 playerIndex, s32 numFrames); +void seq_player_fade_to_zero_volume(s32 arg0, s32 numFrames); +void func_802ad7ec(u32 arg0); -struct SPTask *func_sh_802f5a80(void) { +struct SPTask *create_next_audio_frame_task(void) { u32 samplesRemainingInAI; s32 writtenCmds; s32 index; @@ -59,7 +62,7 @@ struct SPTask *func_sh_802f5a80(void) { gCurrAudioFrameDmaCount = 0; decrease_sample_dma_ttls(); - func_802f41e4(gAudioResetStatus); + func_sh_802f41e4(gAudioResetStatus); if (osRecvMesg(D_SH_80350F88, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) { if (gAudioResetStatus == 0) { gAudioResetStatus = 5; @@ -99,7 +102,7 @@ struct SPTask *func_sh_802f5a80(void) { if (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1) { do { - func_sh_802f6554(sp34); + func_802ad7ec(sp34); } while (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1); } @@ -143,7 +146,7 @@ struct SPTask *func_sh_802f5a80(void) { } } -void func_sh_802f5fb8(struct EuAudioCmd *cmd) { +void eu_process_audio_cmd(struct EuAudioCmd *cmd) { s32 i; struct Note *note; struct NoteSubEu *sub; @@ -155,8 +158,8 @@ void func_sh_802f5fb8(struct EuAudioCmd *cmd) { case 0x82: case 0x88: - func_sh_802F3410(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3); - func_sh_802f62e0(cmd->u.s.arg1, cmd->u2.as_s32); + 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: @@ -165,7 +168,7 @@ void func_sh_802f5fb8(struct EuAudioCmd *cmd) { sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]); } else { - func_sh_802f6288(cmd->u.s.arg1, cmd->u2.as_s32); + seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32); } } break; @@ -220,32 +223,32 @@ void func_sh_802f5fb8(struct EuAudioCmd *cmd) { } } -void func_sh_802f6288(s32 arg0, s32 numFrames) { +void seq_player_fade_to_zero_volume(s32 arg0, s32 fadeOutTime) { struct SequencePlayer *player; - if (numFrames == 0) { - numFrames = 1; + if (fadeOutTime == 0) { + fadeOutTime = 1; } player = &gSequencePlayers[arg0]; player->state = 2; - player->fadeRemainingFrames = numFrames; - player->fadeVelocity = -(player->fadeVolume / (f32) numFrames); + player->fadeRemainingFrames = fadeOutTime; + player->fadeVelocity = -(player->fadeVolume / (f32) fadeOutTime); } -void func_sh_802f62e0(s32 playerIndex, s32 numFrames) { +void func_8031D690(s32 playerIndex, s32 fadeInTime) { struct SequencePlayer *player; - if (numFrames != 0) { + if (fadeInTime != 0) { player = &gSequencePlayers[playerIndex]; player->state = 1; - player->fadeTimerUnkEu = numFrames; - player->fadeRemainingFrames = numFrames; + player->fadeTimerUnkEu = fadeInTime; + player->fadeRemainingFrames = fadeInTime; player->fadeVolume = 0.0f; player->fadeVelocity = 0.0f; } } -void func_sh_802f6330(void) { +void port_eu_init_queues(void) { D_SH_80350F18 = 0; D_SH_80350F19 = 0; D_SH_80350F38 = &D_SH_80350F20; @@ -258,8 +261,8 @@ void func_sh_802f6330(void) { osCreateMesgQueue(D_SH_80350FA8, D_SH_80350F8C, 1); } -extern struct EuAudioCmd sAudioCmd[0x100]; // sAudioCmd, maybe? -void func_802ad6f0(s32 arg0, s32 *arg1) { // func_sh_802f63f8 +extern struct EuAudioCmd sAudioCmd[0x100]; +void func_802ad6f0(s32 arg0, s32 *arg1) { struct EuAudioCmd *cmd = &sAudioCmd[D_SH_80350F18 & 0xff]; cmd->u.first = arg0; cmd->u2.as_u32 = *arg1; @@ -269,34 +272,30 @@ void func_802ad6f0(s32 arg0, s32 *arg1) { // func_sh_802f63f8 } } -void func_802ad728(u32 arg0, f32 arg1) { // func_sh_802f6450 +void func_802ad728(u32 arg0, f32 arg1) { func_802ad6f0(arg0, (s32 *) &arg1); } -void func_802ad74c(u32 arg0, u32 arg1) { // func_sh_802f6474 +void func_802ad74c(u32 arg0, u32 arg1) { func_802ad6f0(arg0, (s32 *) &arg1); } -void func_802ad770(u32 arg0, s8 arg1) { // func_sh_802f6498 +void func_802ad770(u32 arg0, s8 arg1) { s32 sp1C = arg1 << 24; func_802ad6f0(arg0, &sp1C); } char shindouDebugPrint133[] = "AudioSend: %d -> %d (%d)\n"; -extern OSMesgQueue *D_SH_80350F68; void func_sh_802F64C8(void) { static s32 D_SH_8031503C = 0; - s32 a0 = (D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff; - s32 a1; + s32 mesg; - if (D_SH_8031503C < a0) { - D_SH_8031503C = a0; + if (((D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff) > D_SH_8031503C) { + D_SH_8031503C = (D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff; } - a0 = ((D_SH_80350F19 & 0xff) << 8) | (D_SH_80350F18 & 0xFF); - a1 = a0; - a0 = D_SH_80350F68; - osSendMesg(a0, a1, 0); + mesg = ((D_SH_80350F19 & 0xff) << 8) | (D_SH_80350F18 & 0xff); + osSendMesg(D_SH_80350F68, (OSMesg)mesg, OS_MESG_NOBLOCK); D_SH_80350F19 = D_SH_80350F18; } @@ -304,16 +303,16 @@ void func_sh_802f6540(void) { D_SH_80350F19 = D_SH_80350F18; } -void func_sh_802f6554(u32 arg0) { +void func_802ad7ec(u32 arg0) { struct EuAudioCmd *cmd; struct SequencePlayer *seqPlayer; struct SequenceChannel *chan; - u8 a0; + u8 end; - static char shindouDebugPrint134[] = "Continue Port\n"; - static char shindouDebugPrint135[] = "%d -> %d\n"; - static char shindouDebugPrint136[] = "Sync-Frame Break. (Remain %d)\n"; - static char shindouDebugPrint137[] = "Undefined Port Command %d\n"; + UNUSED static char shindouDebugPrint134[] = "Continue Port\n"; + UNUSED static char shindouDebugPrint135[] = "%d -> %d\n"; + UNUSED static char shindouDebugPrint136[] = "Sync-Frame Break. (Remain %d)\n"; + UNUSED static char shindouDebugPrint137[] = "Undefined Port Command %d\n"; static u8 D_SH_80315098 = 0; static u8 D_SH_8031509C = 0; @@ -322,10 +321,10 @@ void func_sh_802f6554(u32 arg0) { D_SH_80315098 = (arg0 >> 8) & 0xff; } - a0 = arg0 & 0xff; + end = arg0 & 0xff; for (;;) { - if (D_SH_80315098 == a0) { + if (D_SH_80315098 == end) { D_SH_8031509C = 0; break; } @@ -336,12 +335,12 @@ void func_sh_802f6554(u32 arg0) { break; } else if ((cmd->u.s.op & 0xf0) == 0xf0) { - func_sh_802f5fb8(cmd); + eu_process_audio_cmd(cmd); } else if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) { seqPlayer = &gSequencePlayers[cmd->u.s.arg1]; if ((cmd->u.s.op & 0x80) != 0) { - func_sh_802f5fb8(cmd); + eu_process_audio_cmd(cmd); } else if ((cmd->u.s.op & 0x40) != 0) { switch (cmd->u.s.op) { @@ -399,8 +398,9 @@ void func_sh_802f6554(u32 arg0) { } break; case 5: - if (chan->reverb != cmd->u2.as_s8) { - chan->reverb = cmd->u2.as_s8; + //! @bug u8 s8 comparison (but harmless) + if (chan->reverbVol != cmd->u2.as_s8) { + chan->reverbVol = cmd->u2.as_s8; } break; case 6: @@ -489,9 +489,8 @@ s8 func_sh_802f6a6c(s32 playerIndex, s32 index) { return gSequencePlayers[playerIndex].seqVariationEu[index]; } -void func_sh_802f6a9c(void) { - // creates a bunch of os message queues - func_sh_802f6330(); +void port_eu_init(void) { + port_eu_init_queues(); } char shindouDebugPrint138[] = "specchg conjunction error (Msg:%d Cur:%d)\n"; @@ -525,9 +524,13 @@ char shindouDebugPrint164[] = "Audio: C-Alloc : lowerPrio is NULL\n"; char shindouDebugPrint165[] = "Intterupt UseStop %d (Kill %d)\n"; char shindouDebugPrint166[] = "Intterupt RelWait %d (Kill %d)\n"; char shindouDebugPrint167[] = "Drop Voice (Prio %x)\n"; -s32 D_SH_803154CC = 0; // Either an unused variable or a file boundary. +s32 D_SH_803154CC = 0; // file boundary + +// effects.c char shindouDebugPrint168[] = "Audio:Envp: overflow %f\n"; -s32 D_SH_803154EC = 0; // Either an unused variable or a file boundary. +s32 D_SH_803154EC = 0; // file boundary + +// seqplayer.c char shindouDebugPrint169[] = "Audio:Track:Warning: No Free Notetrack\n"; char shindouDebugPrint170[] = "SUBTRACK DIM\n"; char shindouDebugPrint171[] = "Audio:Track: Warning :SUBTRACK had been stolen by other Group.\n"; diff --git a/src/audio/seqplayer.c b/src/audio/seqplayer.c index a5a92b84..90551603 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/seqplayer.c @@ -55,9 +55,9 @@ void sequence_channel_init(struct SequenceChannel *seqChannel) { seqChannel->panChannelWeight = 1.0f; seqChannel->noteUnused = NULL; #endif - seqChannel->reverb = 0; + seqChannel->reverbVol = 0; #ifdef VERSION_SH - seqChannel->unkSH0C = 0; + seqChannel->synthesisVolume = 0; #endif seqChannel->notePriority = NOTE_PRIORITY_DEFAULT; #ifdef VERSION_SH @@ -142,7 +142,7 @@ s32 seq_channel_set_layer(struct SequenceChannel *seqChannel, s32 layerIndex) { layer->freqScale = 1.0f; layer->velocitySquare = 0.0f; #ifdef VERSION_SH - layer->unkSH28 = 1.0f; + layer->freqScaleMultiplier = 1.0f; #endif layer->instOrWave = 0xff; #else @@ -989,7 +989,7 @@ void seq_channel_layer_process_script_part1(struct SequenceChannelLayer *layer) } s32 seq_channel_layer_process_script_part5(struct SequenceChannelLayer *layer, s32 cmd) { - if (!layer->stopSomething && layer->sound != NULL && layer->sound->sample->codec == 2 && + if (!layer->stopSomething && layer->sound != NULL && layer->sound->sample->codec == CODEC_SKIP && layer->sound->sample->medium != 0) { layer->stopSomething = TRUE; return -1; @@ -1176,7 +1176,7 @@ s32 seq_channel_layer_process_script_part2(struct SequenceChannelLayer *layer) { case 0xce: cmd = m64_read_u8(state) + 0x80; - layer->unkSH28 = unk_sh_data_1[cmd]; + layer->freqScaleMultiplier = unk_sh_data_1[cmd]; // missing break :) default: @@ -1320,7 +1320,7 @@ s32 seq_channel_layer_process_script_part4(struct SequenceChannelLayer *layer, s } } layer->delayUnused = layer->delay; - layer->freqScale *= layer->unkSH28; + layer->freqScale *= layer->freqScaleMultiplier; return sameSound; } @@ -1828,7 +1828,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { #endif case 0xd4: // chan_setreverb - seqChannel->reverb = m64_read_u8(state); + seqChannel->reverbVol = m64_read_u8(state); break; case 0xc6: // chan_setbank; switch bank within set @@ -1972,8 +1972,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqChannel->transposition = (s8) *seqData++; seqChannel->newPan = *seqData++; seqChannel->panChannelWeight = *seqData++; - seqChannel->reverb = *seqData++; - seqChannel->reverbIndex = *seqData++; // reverb index? + seqChannel->reverbVol = *seqData++; + seqChannel->reverbIndex = *seqData++; seqChannel->changes.as_bitfields.pan = TRUE; break; @@ -1984,7 +1984,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { seqChannel->transposition = (s8) m64_read_u8(state); seqChannel->newPan = m64_read_u8(state); seqChannel->panChannelWeight = m64_read_u8(state); - seqChannel->reverb = m64_read_u8(state); + seqChannel->reverbVol = m64_read_u8(state); seqChannel->reverbIndex = m64_read_u8(state); seqChannel->changes.as_bitfields.pan = TRUE; break; @@ -2016,7 +2016,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { #endif #ifdef VERSION_SH case 0xed: - seqChannel->unkSH0C = m64_read_u8(state); + seqChannel->synthesisVolume = m64_read_u8(state); break; case 0xef: @@ -2112,7 +2112,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { case 0x10: seqChannel->soundScriptIO[loBits] = -1; - if (func_802f47c8(seqChannel->bankId, (u8)value, &seqChannel->soundScriptIO[loBits]) == -1) { + if (func_sh_802f47c8(seqChannel->bankId, (u8)value, &seqChannel->soundScriptIO[loBits]) == -1) { } break; #else diff --git a/src/audio/shindou_debug_prints.c b/src/audio/shindou_debug_prints.c index 5f85e24a..261d4521 100644 --- a/src/audio/shindou_debug_prints.c +++ b/src/audio/shindou_debug_prints.c @@ -1,7 +1,14 @@ #include #ifdef VERSION_SH -// The first four debug prints are in data.c. +// synthesis.c +char shindouDebugPrint1[] = "Terminate-Canceled Channel %d,Phase %d\n"; +char shindouDebugPrint2[] = "S->W\n"; +char shindouDebugPrint3[] = "W->S\n"; +char shindouDebugPrint4[] = "S-Resample Pitch %x (old %d -> delay %d)\n"; +s32 shindouDebugPrintPadding1[] = {0,0,0}; + +// heap.c char shindouDebugPrint5[] = "Warning:Kill Note %x \n"; char shindouDebugPrint6[] = "Kill Voice %d (ID %d) %d\n"; char shindouDebugPrint7[] = "Warning: Running Sequence's data disappear!\n"; @@ -58,8 +65,9 @@ char shindouDebugPrint57[] = "Request--------Single-Stay, %d\n"; char shindouDebugPrint58[] = "Try Kill %d \n"; char shindouDebugPrint59[] = "Try Kill %x %x\n"; char shindouDebugPrint60[] = "Try Kill %x %x %x\n"; -// Zero padding here. These aren't used variables, so they could be either unused variables or a file boundary. s32 shindouDebugPrintPadding[] = {0, 0, 0}; + +// load.c char shindouDebugPrint61[] = "CAUTION:WAVE CACHE FULL %d"; char shindouDebugPrint62[] = "SUPERDMA"; char shindouDebugPrint63[] = "Bank Change... top %d lba %d\n"; @@ -124,6 +132,8 @@ char shindouDebugPrint121[] = "N start %d\n"; char shindouDebugPrint122[] = "============Error: Magic is Broken: %x\n"; char shindouDebugPrint123[] = "Error: No Handle.\n"; char shindouDebugPrint124[] = "Success: %x\n"; + +// port_eu.c char shindouDebugPrint125[] = "DAC:Lost 1 Frame.\n"; char shindouDebugPrint126[] = "DMA: Request queue over.( %d )\n"; char shindouDebugPrint127[] = "Spec Change Override. %d -> %d\n"; diff --git a/src/audio/synthesis.c b/src/audio/synthesis.c index b9f73753..224a0007 100644 --- a/src/audio/synthesis.c +++ b/src/audio/synthesis.c @@ -1,3 +1,4 @@ +#ifndef VERSION_SH #include #include "synthesis.h" @@ -9,7 +10,6 @@ #include "external.h" -#ifndef VERSION_SH #define DMEM_ADDR_TEMP 0x0 #define DMEM_ADDR_RESAMPLED 0x20 #define DMEM_ADDR_RESAMPLED2 0x160 @@ -22,18 +22,6 @@ #define DMEM_ADDR_RIGHT_CH 0x600 #define DMEM_ADDR_WET_LEFT_CH 0x740 #define DMEM_ADDR_WET_RIGHT_CH 0x880 -#else -#define DMEM_ADDR_TEMP 0x450 -#define DMEM_ADDR_RESAMPLED 0x470 -#define DMEM_ADDR_RESAMPLED2 0x5f0 -#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x5f0 -#define DMEM_ADDR_NOTE_PAN_TEMP 0x650 -#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x990 -#define DMEM_ADDR_LEFT_CH 0x990 -#define DMEM_ADDR_RIGHT_CH 0xb10 -#define DMEM_ADDR_WET_LEFT_CH 0xc90 -#define DMEM_ADDR_WET_RIGHT_CH 0xe10 -#endif #define aSetLoadBufferPair(pkt, c, off) \ aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \ @@ -57,12 +45,8 @@ struct VolumeChange { }; u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); -#if defined(VERSION_EU) || defined(VERSION_SH) -#ifdef VERSION_SH -u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, u16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); -#else -u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, u16 *aiBuf, s32 bufLen, u64 *cmd); -#endif +#ifdef VERSION_EU +u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *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, u32 flags); @@ -78,7 +62,7 @@ u64 *process_envelope_inner(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 flags, s32 leftRight); #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU struct SynthesisReverb gSynthesisReverbs[4]; u8 sAudioSynthesisPad[0x10]; #else @@ -86,13 +70,10 @@ struct SynthesisReverb gSynthesisReverb; u8 sAudioSynthesisPad[0x20]; #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU s16 gVolume; s8 gUseReverb; s8 gNumSynthesisReverbs; -#ifdef VERSION_SH -s16 D_SH_803479B4; // contains 4096 -#endif struct NoteSubEu *gNoteSubsEu; #endif @@ -106,7 +87,7 @@ u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n"; u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n"; #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU // 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) { @@ -215,59 +196,31 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { } #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 len, s32 reverbIndex) { -#ifdef VERSION_SH - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[srcOffset]), - addr, len); - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[srcOffset]), - addr + DEFAULT_LEN_1CH, len); -#else 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])); -#endif return cmd; } #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 len, s32 reverbIndex) { -#ifdef VERSION_SH - aSaveBuffer(cmd++, addr, - VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[destOffset]), len); - aSaveBuffer(cmd++, addr + DEFAULT_LEN_1CH, - VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[destOffset]), len); -#else 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])); -#endif return cmd; } #endif -#if defined(VERSION_SH) -void func_sh_802ed644(s32 updateIndexStart, s32 noteIndex) { - s32 i; - - for (i = updateIndexStart + 1; i < gAudioBufferParameters.updatesPerFrame; i++) { - if (!gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].needsInit) { - gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].enabled = FALSE; - } else { - break; - } - } -} -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU void synthesis_load_note_subs_eu(s32 updateIndex) { struct NoteSubEu *src; struct NoteSubEu *dest; @@ -286,7 +239,7 @@ void synthesis_load_note_subs_eu(s32 updateIndex) { } #endif -#if defined(VERSION_JP) || defined(VERSION_US) +#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. @@ -309,46 +262,32 @@ s32 get_volume_ramping(u16 sourceVol, u16 targetVol, s32 arg2) { } #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU // TODO: (Scrub C) pointless mask and whitespace u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { s32 i, j; -#ifndef VERSION_SH f32 *leftVolRamp; f32 *rightVolRamp; -#endif u32 *aiBufPtr; u64 *cmd = cmdBuf; s32 chunkLen; -#ifndef VERSION_SH s32 nextVolRampTable; -#endif for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { process_sequences(i - 1); synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - i); } -#ifndef VERSION_SH aSegment(cmd++, 0, 0); -#endif aiBufPtr = (u32 *) aiBuf; for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { -#ifdef VERSION_SH - if (i == 1) { - chunkLen = bufLen; - } else { - if (bufLen / i >= gAudioBufferParameters.samplesPerUpdateMax) { - chunkLen = gAudioBufferParameters.samplesPerUpdateMax; - } else if (bufLen / i <= gAudioBufferParameters.samplesPerUpdateMin) { - chunkLen = gAudioBufferParameters.samplesPerUpdateMin; - } else { - chunkLen = gAudioBufferParameters.samplesPerUpdate; - } - } -#else if (i == 1) { +#pragma GCC diagnostic push +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wself-assign" +#endif // self-assignment has no affect when added here, could possibly simplify a macro definition chunkLen = bufLen; nextVolRampTable = nextVolRampTable; leftVolRamp = gLeftVolRampings[nextVolRampTable]; rightVolRamp = gRightVolRampings[nextVolRampTable & 0xFFFFFFFF]; +#pragma GCC diagnostic pop } else { if (bufLen / i >= gAudioBufferParameters.samplesPerUpdateMax) { chunkLen = gAudioBufferParameters.samplesPerUpdateMax; nextVolRampTable = 2; leftVolRamp = gLeftVolRampings[2]; rightVolRamp = gRightVolRampings[2]; @@ -360,7 +299,6 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { } gCurrentLeftVolRamping = leftVolRamp; gCurrentRightVolRamping = rightVolRamp; -#endif for (j = 0; j < gNumSynthesisReverbs; j++) { if (gSynthesisReverbs[j].useReverb != 0) { prepare_reverb_ring_buffer(chunkLen, gAudioBufferParameters.updatesPerFrame - i, j); @@ -422,7 +360,7 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; s16 startPad; @@ -430,22 +368,15 @@ u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s1 item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; -#ifndef VERSION_SH aClearBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); -#endif if (gSynthesisReverbs[reverbIndex].downsampleRate == 1) { cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); if (item->lengthB != 0) { cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); } -#ifdef VERSION_SH - aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); - aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); -#else 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 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH); -#endif } else { startPad = (item->startPos % 8u) * 2; paddedLengthA = ALIGN(startPad + item->lengthA, 4); @@ -461,45 +392,13 @@ u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s1 aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED2 + startPad, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2); aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateRight)); -#ifdef VERSION_SH - aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); - aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); -#else 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 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH); -#endif - } -#ifdef VERSION_SH - if (gSynthesisReverbs[reverbIndex].panRight != 0 || gSynthesisReverbs[reverbIndex].panLeft != 0) { - // Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan) - aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_1CH); - aMix(cmd++, gSynthesisReverbs[reverbIndex].panRight, DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_1CH); - aMix(cmd++, gSynthesisReverbs[reverbIndex].panLeft, DMEM_ADDR_RESAMPLED, DMEM_ADDR_WET_RIGHT_CH, DEFAULT_LEN_1CH); - } -#endif - return cmd; -} -#endif - -#if defined(VERSION_SH) -u64 *synthesis_load_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { - struct ReverbRingBufferItem *item; - struct SynthesisReverb *reverb; - - reverb = &gSynthesisReverbs[reverbIndex]; - item = &reverb->items[reverb->curFrame][updateIndex]; - // Get the oldest samples in the ring buffer into the wet channels - cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex); - if (item->lengthB != 0) { - // Ring buffer wrapped - cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex); } return cmd; } -#endif -#if defined(VERSION_EU) u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; @@ -516,8 +415,8 @@ u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { break; default: - // Downsampling is done later by CPU when RSP is done, therefore we need to have double - // buffering. Left and right buffers are adjacent in memory. + // Downsampling is done later by CPU when RSP is done, therefore we need to have double + // buffering. Left and right buffers are adjacent in memory. aSetBuffer(cmd++, 0, 0, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex].toDownsampleLeft)); gSynthesisReverbs[reverbIndex].resampleFlags = 0; @@ -526,50 +425,9 @@ u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { } return cmd; } -#elif defined(VERSION_SH) -u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { - struct ReverbRingBufferItem *item; - - item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; - switch (gSynthesisReverbs[reverbIndex].downsampleRate) { - case 1: - // Put the oldest samples in the ring buffer into the wet channels - cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); - if (item->lengthB != 0) { - // Ring buffer wrapped - cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); - } - break; - - default: - // Downsampling is done later by CPU when RSP is done, therefore we need to have double - // buffering. Left and right buffers are adjacent in memory. - aSaveBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH, - VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex].toDownsampleLeft), DEFAULT_LEN_2CH); - break; - } - gSynthesisReverbs[reverbIndex].resampleFlags = 0; - return cmd; -} - -u64 *func_sh_802EDF24(u64 *cmd, s16 reverbIndex, s16 updateIndex) { - struct ReverbRingBufferItem *item; - struct SynthesisReverb *reverb; - - reverb = &gSynthesisReverbs[reverbIndex]; - item = &reverb->items[reverb->curFrame][updateIndex]; - // Put the oldest samples in the ring buffer into the wet channels - cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex); - if (item->lengthB != 0) { - // Ring buffer wrapped - cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex); - } - return cmd; -} - #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { struct NoteSubEu *noteSubEu; u8 noteIndices[56]; @@ -611,53 +469,20 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI for (; i < notePos; i++) { temp = updateIndex * gMaxSimultaneousNotes; if (j == gNoteSubsEu[temp + noteIndices[i]].reverbIndex) { -#ifdef VERSION_SH - cmd = synthesis_process_note(noteIndices[i], - &gNoteSubsEu[temp + noteIndices[i]], - &gNotes[noteIndices[i]].synthesisState, - aiBuf, bufLen, cmd, updateIndex); -#else cmd = synthesis_process_note(&gNotes[noteIndices[i]], &gNoteSubsEu[temp + noteIndices[i]], &gNotes[noteIndices[i]].synthesisState, aiBuf, bufLen, cmd); -#endif continue; } else { break; } } if (gSynthesisReverbs[j].useReverb != 0) { -#ifdef VERSION_SH - if (gSynthesisReverbs[j].unk100 != NULL) { - aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk100); - aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_LEFT_CH, gSynthesisReverbs[j].unk108); - } - if (gSynthesisReverbs[j].unk104 != NULL) { - aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk104); - aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_RIGHT_CH, gSynthesisReverbs[j].unk10C); - } -#endif cmd = synthesis_save_reverb_samples(cmd, j, updateIndex); -#ifdef VERSION_SH - if (gSynthesisReverbs[j].unk5 != -1) { - if (gSynthesisReverbs[gSynthesisReverbs[j].unk5].downsampleRate == 1) { - cmd = synthesis_load_reverb_samples(cmd, gSynthesisReverbs[j].unk5, updateIndex); - aMix(cmd++, gSynthesisReverbs[j].unk08, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_2CH); - cmd = func_sh_802EDF24(cmd++, gSynthesisReverbs[j].unk5, updateIndex); - } - } -#endif } } for (; i < notePos; i++) { -#ifdef VERSION_SH - struct NoteSubEu *noteSubEu2 = &gNoteSubsEu[updateIndex * gMaxSimultaneousNotes + noteIndices[i]]; - cmd = synthesis_process_note(noteIndices[i], - noteSubEu2, - &gNotes[noteIndices[i]].synthesisState, - aiBuf, bufLen, cmd, updateIndex); -#else temp = updateIndex * gMaxSimultaneousNotes; if (IS_BANK_LOAD_COMPLETE(gNoteSubsEu[temp + noteIndices[i]].bankId) == TRUE) { cmd = synthesis_process_note(&gNotes[noteIndices[i]], @@ -667,22 +492,16 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI } else { gAudioErrorFlags = (gNoteSubsEu[temp + noteIndices[i]].bankId + (i << 8)) + 0x10000000; } -#endif } temp = bufLen * 2; -#ifdef VERSION_SH - aInterleave(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH, temp); - aSaveBuffer(cmd++, DMEM_ADDR_TEMP, VIRTUAL_TO_PHYSICAL2(aiBuf), temp * 2); -#else aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, temp); aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH); aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, temp * 2); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); -#endif return cmd; } -#elif defined(VERSION_JP) || defined(VERSION_US) +#else u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { UNUSED s32 pad1[1]; s16 ra; @@ -758,10 +577,9 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI } #endif -#ifndef VERSION_SH -#if defined(VERSION_EU) +#ifdef VERSION_EU // Processes just one note, not all -u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, u16 *aiBuf, s32 bufLen, u64 *cmd) { +u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED s16 *aiBuf, s32 bufLen, u64 *cmd) { UNUSED s32 pad0[3]; #else u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { @@ -772,22 +590,22 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { struct AudioBankSample *audioBookSample; // sp164, sp138 struct AdpcmLoop *loopInfo; // sp160, sp134 s16 *curLoadedBook = NULL; // sp154, sp130 -#if defined(VERSION_EU) +#ifdef VERSION_EU UNUSED u8 padEU[0x04]; #endif UNUSED u8 pad8[0x04]; -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU u16 resamplingRateFixedPoint; // sp5c, sp11A #endif s32 noteFinished; // 150 t2, sp124 s32 restart; // 14c t3, sp120 s32 flags; // sp148, sp11C -#if defined(VERSION_EU) +#ifdef VERSION_EU u16 resamplingRateFixedPoint; // sp5c, sp11A #endif UNUSED u8 pad7[0x0c]; // sp100 UNUSED s32 tempBufLen; -#if defined(VERSION_EU) +#ifdef VERSION_EU s32 sp130; //sp128, sp104 UNUSED u32 pad9; #else @@ -796,7 +614,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { #endif s32 nAdpcmSamplesProcessed; // signed required for US s32 t0; -#if defined(VERSION_EU) +#ifdef VERSION_EU u8 *sampleAddr; // sp120, spF4 s32 s6; #else @@ -804,7 +622,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { u8 *sampleAddr; // sp120, spF4 #endif -#if defined(VERSION_EU) +#ifdef VERSION_EU s32 samplesLenAdjusted; // 108, spEC // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange // behavior with the break near the end of the loop, causing US and JP to need a goto instead @@ -829,26 +647,26 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { u32 samplesLenFixedPoint; // v1_1 s32 nSamplesInThisIteration; // v1_2 u32 a3; -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU s32 t9; #endif u8 *v0_2; s32 nParts; // spE8, spBC s32 curPart; // spE4, spB8 -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU f32 resamplingRate; // f12 #endif s32 temp; -#if defined(VERSION_EU) +#ifdef VERSION_EU s32 s5Aligned; #endif s32 resampledTempLen; // spD8, spAC u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU for (noteIndex = 0; noteIndex < gMaxSimultaneousNotes; noteIndex++) { note = &gNotes[noteIndex]; #ifdef VERSION_US @@ -866,17 +684,17 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } else { #endif flags = 0; -#if defined(VERSION_EU) +#ifdef VERSION_EU tempBufLen = bufLen; #endif -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->needsInit == TRUE) { #else if (note->needsInit == TRUE) { #endif flags = A_INIT; -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU note->samplePosInt = 0; note->samplePosFrac = 0; #else @@ -890,7 +708,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { #endif } -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU if (note->frequency < US_FLOAT(2.0)) { nParts = 1; if (note->frequency > US_FLOAT(1.99996)) { @@ -916,7 +734,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; #endif -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->isSyntheticWave) { cmd = load_wave_samples(cmd, noteSubEu, synthesisState, samplesLenFixedPoint >> 0x10); noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE; @@ -935,7 +753,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { else { // ADPCM note -#if defined(VERSION_EU) +#ifdef VERSION_EU audioBookSample = noteSubEu->sound.audioBankSound->sample; #else audioBookSample = note->sound->sample; @@ -961,7 +779,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { if (curLoadedBook != audioBookSample->book->book) { u32 nEntries; // v1 curLoadedBook = audioBookSample->book->book; -#if defined(VERSION_EU) +#ifdef VERSION_EU nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors; aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook + noteSubEu->bookOffset)); #else @@ -970,7 +788,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { #endif } -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->bookOffset) { curLoadedBook = euUnknownData_80301950; // what's this? never read } @@ -983,7 +801,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { noteFinished = FALSE; restart = FALSE; nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; -#if defined(VERSION_EU) +#ifdef VERSION_EU s2 = synthesisState->samplePosInt & 0xf; samplesRemaining = endPos - synthesisState->samplePosInt; #else @@ -991,7 +809,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { samplesRemaining = endPos - note->samplePosInt; #endif -#if defined(VERSION_EU) +#ifdef VERSION_EU if (s2 == 0 && synthesisState->restart == FALSE) { s2 = 16; } @@ -1007,7 +825,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { s0 = t0 * 16; s3 = s6 + s0 - nSamplesToProcess; } else { -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU s0 = samplesRemaining + s2 - 0x10; #else s0 = samplesRemaining - s6; @@ -1027,7 +845,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } if (t0 != 0) { -#if defined(VERSION_EU) +#ifdef VERSION_EU temp = (synthesisState->samplePosInt - s2 + 0x10) / 16; if (audioBookSample->loaded == 0x81) { v0_2 = sampleAddr + temp * 9; @@ -1050,7 +868,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { a3 = 0; } -#if defined(VERSION_EU) +#ifdef VERSION_EU if (synthesisState->restart != FALSE) { aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); flags = A_LOOP; // = 2 @@ -1065,7 +883,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { #endif nSamplesInThisIteration = s0 + s6 - s3; -#if defined(VERSION_EU) +#ifdef VERSION_EU if (nAdpcmSamplesProcessed == 0) { aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); @@ -1118,7 +936,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { if (noteFinished) { aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); -#if defined(VERSION_EU) +#ifdef VERSION_EU noteSubEu->finished = 1; note->noteSubEu.finished = 1; note->noteSubEu.enabled = 0; @@ -1129,7 +947,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { #endif break; } -#if defined(VERSION_EU) +#ifdef VERSION_EU if (restart) { synthesisState->restart = TRUE; synthesisState->samplePosInt = loopInfo->start; @@ -1155,14 +973,14 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { switch (curPart) { case 0: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4); -#if defined(VERSION_EU) +#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_RESAMPLED + 4; -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->finished != FALSE) { #else if (note->finished != FALSE) { @@ -1175,7 +993,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED2, samplesLenAdjusted + 8); -#if defined(VERSION_EU) +#ifdef VERSION_EU aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( synthesisState->synthesisBuffers->dummyResampleState)); @@ -1191,7 +1009,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } } -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->finished != FALSE) { #else if (note->finished != FALSE) { @@ -1203,7 +1021,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { flags = 0; -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->needsInit == TRUE) { flags = A_INIT; noteSubEu->needsInit = FALSE; @@ -1221,28 +1039,28 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { noteSamplesDmemAddrBeforeResampling, flags); #endif -#if defined(VERSION_JP) || defined(VERSION_US) - if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { - leftRight = 1; - } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { - leftRight = 2; -#else +#ifdef VERSION_EU if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { leftRight = 1; } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { leftRight = 2; +#else + if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { + leftRight = 1; + } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { + leftRight = 2; #endif } else { leftRight = 0; } -#if defined(VERSION_EU) +#ifdef VERSION_EU cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0, leftRight, flags); #else cmd = process_envelope(cmd, note, bufLen, 0, leftRight, flags); #endif -#if defined(VERSION_EU) +#ifdef VERSION_EU if (noteSubEu->usesHeadsetPanEffects) { cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight); } @@ -1252,7 +1070,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } #endif } -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU } t9 = bufLen * 2; @@ -1265,389 +1083,25 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { return cmd; } -#else // VERSION_SH -u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED u16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { - UNUSED s32 pad0[3]; - struct AudioBankSample *audioBookSample; // sp164, sp138 - struct AdpcmLoop *loopInfo; // sp160, sp134 - s16 *curLoadedBook; // sp154, sp130 - UNUSED u8 padEU[0x04]; - UNUSED u8 pad8[0x04]; - s32 noteFinished; // 150 t2, sp124 - s32 restart; // 14c t3, sp120 - s32 flags; // sp148, sp11C, t8 - u16 resamplingRateFixedPoint; // sp5c, sp11A - s32 nSamplesToLoad; //s0, Ec - UNUSED u8 pad7[0x0c]; // sp100 - s32 sp130; //sp128, sp104 - UNUSED s32 tempBufLen; - UNUSED u32 pad9; - s32 t0; - u8 *sampleAddr; // sp120, spF4 - s32 s6; - s32 samplesLenAdjusted; // 108, spEC - s32 nAdpcmSamplesProcessed; // signed required for US // spc0 - s32 endPos; // sp110, spE4 - s32 nSamplesToProcess; // sp10c/a0, spE0 - // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange - // behavior with the break near the end of the loop, causing US and JP to need a goto instead - UNUSED s32 samplesLenInt; - s32 s2; - s32 leftRight; //s0 - s32 s5; //s4 - u32 samplesLenFixedPoint; // v1_1 - s32 s3; // spA0 - s32 nSamplesInThisIteration; // v1_2 - u32 a3; - u8 *v0_2; - s32 unk_s6; // sp90 - s32 s5Aligned; - s32 sp88; - s32 sp84; - u32 temp; - s32 nParts; // spE8, spBC - s32 curPart; // spE4, spB8 - s32 aligned; - UNUSED u32 padSH1; - s32 resampledTempLen; // spD8, spAC, sp6c - u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA, sp6a -- 6C - UNUSED u32 padSH2; - UNUSED u32 padSH3; - UNUSED u32 padSH4; - struct Note *note; // sp58 - u16 sp56; // sp56 - u16 addr; - u8 bankId; - curLoadedBook = NULL; - note = &gNotes[noteIndex]; - flags = 0; - if (noteSubEu->needsInit == TRUE) { - flags = A_INIT; - synthesisState->restart = 0; - synthesisState->samplePosInt = 0; - synthesisState->samplePosFrac = 0; - synthesisState->curVolLeft = 0; - synthesisState->curVolRight = 0; - synthesisState->prevHeadsetPanRight = 0; - synthesisState->prevHeadsetPanLeft = 0; - synthesisState->reverbVol = noteSubEu->reverbVol; - synthesisState->unk5 = 0; - note->noteSubEu.finished = 0; - } - - resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; - nParts = noteSubEu->hasTwoAdpcmParts + 1; - samplesLenFixedPoint = (resamplingRateFixedPoint * bufLen * 2) + synthesisState->samplePosFrac; - nSamplesToLoad = (samplesLenFixedPoint >> 0x10); - synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; - - if ((synthesisState->unk5 == 1) && (nParts == 2)) { - nSamplesToLoad += 2; - sp56 = 2; - } else if ((synthesisState->unk5 == 2) && (nParts == 1)) { - nSamplesToLoad -= 4; - sp56 = 4; - } else { - sp56 = 0; - } - - - synthesisState->unk5 = nParts; - - if (noteSubEu->isSyntheticWave) { - cmd = load_wave_samples(cmd, noteSubEu, synthesisState, nSamplesToLoad); - noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE; - synthesisState->samplePosInt += nSamplesToLoad; - } else { - // ADPCM note - audioBookSample = noteSubEu->sound.audioBankSound->sample; - loopInfo = audioBookSample->loop; - endPos = loopInfo->end; - sampleAddr = audioBookSample->sampleAddr; - resampledTempLen = 0; - for (curPart = 0; curPart < nParts; curPart++) { - nAdpcmSamplesProcessed = 0; // s8 - s5 = 0; // s4 - - if (nParts == 1) { - samplesLenAdjusted = nSamplesToLoad; - } else if (nSamplesToLoad & 1) { - samplesLenAdjusted = (nSamplesToLoad & ~1) + (curPart * 2); - } else { - samplesLenAdjusted = nSamplesToLoad; - } - - if (audioBookSample->codec == 0) { - if (curLoadedBook != (*audioBookSample->book).book) { - u32 nEntries; - switch (noteSubEu->bookOffset) { - case 1: - curLoadedBook = euUnknownData_80301950 + 1; - break; - case 2: - curLoadedBook = euUnknownData_80301950 + 2; - break; - case 3: - default: - curLoadedBook = audioBookSample->book->book; - break; - } - nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors; - aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); - } - } - - while (nAdpcmSamplesProcessed != samplesLenAdjusted) { - s32 samplesRemaining; // v1 - s32 s0; - - noteFinished = FALSE; - restart = FALSE; - s2 = synthesisState->samplePosInt & 0xf; - samplesRemaining = endPos - synthesisState->samplePosInt; - nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; - - if (s2 == 0 && synthesisState->restart == FALSE) { - s2 = 16; - } - s6 = 16 - s2; // a1 - if (nSamplesToProcess < samplesRemaining) { - t0 = (nSamplesToProcess - s6 + 0xf) / 16; - s0 = t0 * 16; - s3 = s6 + s0 - nSamplesToProcess; - } else { - s0 = samplesRemaining - s6; - s3 = 0; - if (s0 <= 0) { - s0 = 0; - s6 = samplesRemaining; - } - t0 = (s0 + 0xf) / 16; - if (loopInfo->count != 0) { - // Loop around and restart - restart = 1; - } else { - noteFinished = 1; - } - } - switch (audioBookSample->codec) { - case 0: - unk_s6 = 9; - sp88 = 0x10; - sp84 = 0; - break; - case 1: - unk_s6 = 0x10; - sp88 = 0x10; - sp84 = 0; - break; - case 2: goto skip; - } - if (t0 != 0) { - temp = (synthesisState->samplePosInt + sp88 - s2) / 16; - if (audioBookSample->medium == 0) { - v0_2 = sp84 + (temp * unk_s6) + sampleAddr; - } else { - v0_2 = dma_sample_data((uintptr_t)(sp84 + (temp * unk_s6) + sampleAddr), - ALIGN(t0 * unk_s6 + 16, 4), flags, &synthesisState->sampleDmaIndex, audioBookSample->medium); - } - - a3 = ((uintptr_t)v0_2 & 0xf); - addr = DMEM_ADDR_COMPRESSED_ADPCM_DATA; - addr -= ALIGN(t0 * unk_s6 + 16, 4); - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3), addr & 0xffff, ALIGN(t0 * unk_s6 + 16, 4)); - } else { - s0 = 0; - a3 = 0; - } - if (synthesisState->restart != FALSE) { - aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); - flags = A_LOOP; // = 2 - synthesisState->restart = FALSE; - } - nSamplesInThisIteration = s0 + s6 - s3; - if (nAdpcmSamplesProcessed == 0) { - switch (audioBookSample->codec) { - case 0: - aligned = ALIGN(t0 * unk_s6 + 16, 4); - //! I have no idea. - addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff; - addr += a3; - aSetBuffer(cmd++, 0, addr, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); - aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - break; - case 1: - aligned = ALIGN(t0 * unk_s6 + 16, 4); - addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff; - addr += a3; - aSetBuffer(cmd++, 0, addr, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); - aADPCM_23(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - break; - } - sp130 = s2 * 2; - } else { - s5Aligned = ALIGN(s5 + 16, 4); - switch (audioBookSample->codec) { - case 0: - aligned = ALIGN(t0 * unk_s6 + 16, 4); - addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff; - addr += a3; - aSetBuffer(cmd++, 0, addr, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2); - aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - break; - case 1: - aligned = ALIGN(t0 * unk_s6 + 16, 4); - addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff & 0xffff; - addr += a3; - aSetBuffer(cmd++, 0, addr, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2); - aADPCM_23(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - - break; - } - aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); - } - nAdpcmSamplesProcessed += nSamplesInThisIteration; - switch (flags) { - case A_INIT: // = 1 - sp130 = 0x20; - s5 = (s0 + 0x10) * 2; - break; - case A_LOOP: // = 2 - s5 = (nSamplesInThisIteration) * 2 + s5; - break; - default: - if (s5 != 0) { - s5 = (nSamplesInThisIteration) * 2 + s5; - } else { - s5 = (s2 + (nSamplesInThisIteration)) * 2; - } - break; - } - flags = 0; -skip: - if (noteFinished) { - aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, - (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); - noteSubEu->finished = 1; - note->noteSubEu.finished = 1; - func_sh_802ed644(updateIndex, noteIndex); - break; - } - if (restart != 0) { - synthesisState->restart = TRUE; - synthesisState->samplePosInt = loopInfo->start; - } else { - synthesisState->samplePosInt += nSamplesToProcess; - } - } - - switch (nParts) { - case 1: - noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + sp130; - break; - case 2: - switch (curPart) { - case 0: - aInterl(cmd++, 0, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED); - resampledTempLen = samplesLenAdjusted; - noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED; - if (noteSubEu->finished != FALSE) { - aClearBuffer(cmd++, noteSamplesDmemAddrBeforeResampling + resampledTempLen, samplesLenAdjusted + 0x10); - } - break; - case 1: - aInterl(cmd++, 0, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, resampledTempLen + DMEM_ADDR_RESAMPLED); - break; - } - } - if (noteSubEu->finished != FALSE) { - break; - } - } - } - flags = 0; - if (noteSubEu->needsInit == TRUE) { - flags = A_INIT; - noteSubEu->needsInit = FALSE; - } - flags = flags | sp56; - cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint, - noteSamplesDmemAddrBeforeResampling, flags); - if ((flags & 1) != 0) { - flags = 1; - } - - if (noteSubEu->filter) { - aFilter(cmd++, 0x02, bufLen * 2, noteSubEu->filter); - aFilter(cmd++, flags, DMEM_ADDR_TEMP, synthesisState->synthesisBuffers->filterBuffer); - - } - - if (noteSubEu->bookOffset == 3) { - aUnknown25(cmd++, 0, bufLen * 2, DMEM_ADDR_TEMP, DMEM_ADDR_TEMP); - } - - bankId = noteSubEu->bankId; - if (bankId != 0) { - if (bankId < 0x10) { - bankId = 0x10; - } - - aHilogain(cmd++, bankId, (bufLen + 0x10) * 2, DMEM_ADDR_TEMP); - } - - if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { - leftRight = 1; - } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { - leftRight = 2; - } else { - leftRight = 0; - } - cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0x450, leftRight, flags); - if (noteSubEu->usesHeadsetPanEffects) { - if ((flags & 1) == 0) { - flags = 0; - } - cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight); - } - - return cmd; -} -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { s32 a3; s32 repeats; -#ifndef VERSION_SH s32 i; aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, /*count*/ 128); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples)); -#else - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples), - DMEM_ADDR_UNCOMPRESSED_NOTE, 128); -#endif synthesisState->samplePosInt &= 0x3f; a3 = 64 - synthesisState->samplePosInt; if (a3 < nSamplesToLoad) { repeats = (nSamplesToLoad - a3 + 63) / 64; -#ifndef VERSION_SH for (i = 0; i < repeats; i++) { aDMEMMove(cmd++, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * 128, /*count*/ 128); } -#else - if (repeats != 0) { - aDuplicate(cmd++, - /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, - /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + 128, - /*copies*/ repeats); - } -#endif } return cmd; } @@ -1669,18 +1123,10 @@ u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { } #endif -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { -#ifdef VERSION_SH - if (pitch == 0) { - aClearBuffer(cmd++, DMEM_ADDR_TEMP, count); - } else { -#endif - aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); - aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); -#ifdef VERSION_SH - } -#endif + aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); + aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); return cmd; } #else @@ -1691,8 +1137,7 @@ u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemI } #endif -#ifndef VERSION_SH -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) { UNUSED u8 pad[16]; @@ -1782,7 +1227,7 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat } } -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU if (targetLeft == sourceLeft && targetRight == sourceRight && !note->envMixerNeedsInit) { #else if (vol->targetLeft == vol->sourceLeft && vol->targetRight == vol->sourceRight @@ -1792,7 +1237,7 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat } else { mixerFlags = A_INIT; -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU rampLeft = gCurrentLeftVolRamping[targetLeft >> 5] * gCurrentRightVolRamping[sourceLeft >> 5]; rampRight = gCurrentLeftVolRamping[targetRight >> 5] * gCurrentRightVolRamping[sourceRight >> 5]; #else @@ -1801,7 +1246,7 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat #endif // The operation's parameters change meanings depending on flags -#if defined(VERSION_EU) || defined(VERSION_SH) +#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); @@ -1812,16 +1257,16 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat 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); + aSetVolume(cmd++, A_AUX, gVolume, 0, note->reverbVolShifted); #endif } -#if defined(VERSION_EU) || defined(VERSION_SH) +#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) { + if (gSynthesisReverb.useReverb && note->reverbVol != 0) { aEnvMixer(cmd++, mixerFlags | A_AUX, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); #endif @@ -1840,7 +1285,7 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat /*out*/ DMEM_ADDR_WET_RIGHT_CH); } } else { -#if defined(VERSION_EU) || defined(VERSION_SH) +#ifdef VERSION_EU aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->mixEnvelopeState)); #else aEnvMixer(cmd++, mixerFlags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->mixEnvelopeState)); @@ -1858,123 +1303,29 @@ u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisStat return cmd; } -#elif defined(VERSION_SH) -u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) { - u16 sourceRight; - u16 sourceLeft; - u16 targetLeft; - u16 targetRight; - s16 rampLeft; - s16 rampRight; - s32 sourceReverbVol; - s16 reverbVol; - s32 temp = 0; - - sourceLeft = synthesisState->curVolLeft; - sourceRight = synthesisState->curVolRight; - targetLeft = note->targetVolLeft; - targetRight = note->targetVolRight; - targetLeft <<= 4; - targetRight <<= 4; - - if (targetLeft != sourceLeft) { - rampLeft = (targetLeft - sourceLeft) / (nSamples >> 3); - } else { - rampLeft = 0; - } - if (targetRight != sourceRight) { - rampRight = (targetRight - sourceRight) / (nSamples >> 3); - } else { - rampRight = 0; - } - - sourceReverbVol = synthesisState->reverbVol; - if (note->reverbVol != sourceReverbVol) { - temp = ((note->reverbVol & 0x7f) - (sourceReverbVol & 0x7f)) << 9; - reverbVol = temp / (nSamples >> 3); - synthesisState->reverbVol = note->reverbVol; - } else { - reverbVol = 0; - } - synthesisState->curVolLeft = sourceLeft + rampLeft * (nSamples >> 3); - synthesisState->curVolRight = sourceRight + rampRight * (nSamples >> 3); - - if (note->usesHeadsetPanEffects) { - aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DEFAULT_LEN_1CH); - aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, reverbVol, rampLeft, rampRight); - aEnvSetup2(cmd++, sourceLeft, sourceRight); - - switch (headsetPanSettings) { - case 1: - aEnvMixer(cmd++, - inBuf, nSamples, - (sourceReverbVol & 0x80) >> 7, - note->stereoStrongRight, note->stereoStrongLeft, - DMEM_ADDR_NOTE_PAN_TEMP, - DMEM_ADDR_RIGHT_CH, - DMEM_ADDR_WET_LEFT_CH, - DMEM_ADDR_WET_RIGHT_CH); - break; - case 2: - aEnvMixer(cmd++, - inBuf, nSamples, - (sourceReverbVol & 0x80) >> 7, - note->stereoStrongRight, note->stereoStrongLeft, - DMEM_ADDR_LEFT_CH, - DMEM_ADDR_NOTE_PAN_TEMP, - DMEM_ADDR_WET_LEFT_CH, - DMEM_ADDR_WET_RIGHT_CH); - break; - default: - aEnvMixer(cmd++, - inBuf, nSamples, - (sourceReverbVol & 0x80) >> 7, - note->stereoStrongRight, note->stereoStrongLeft, - DMEM_ADDR_LEFT_CH, - DMEM_ADDR_RIGHT_CH, - DMEM_ADDR_WET_LEFT_CH, - DMEM_ADDR_WET_RIGHT_CH); - break; - } - } else { - aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, reverbVol, rampLeft, rampRight); - aEnvSetup2(cmd++, sourceLeft, sourceRight); - aEnvMixer(cmd++, - inBuf, nSamples, - (sourceReverbVol & 0x80) >> 7, - note->stereoStrongRight, note->stereoStrongLeft, - DMEM_ADDR_LEFT_CH, - DMEM_ADDR_RIGHT_CH, - DMEM_ADDR_WET_LEFT_CH, - DMEM_ADDR_WET_RIGHT_CH); - } - return cmd; -} -#endif - -#if defined(VERSION_EU) || defined(VERSION_SH) +#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 pitch; -#if defined(VERSION_JP) || defined(VERSION_US) - u16 prevPanShift; - u16 panShift; -#else +#ifdef VERSION_EU u8 prevPanShift; u8 panShift; UNUSED u8 unkDebug; +#else + u16 prevPanShift; + u16 panShift; #endif switch (leftRight) { case 1: dest = DMEM_ADDR_LEFT_CH; -#if defined(VERSION_JP) || defined(VERSION_US) - panShift = note->headsetPanRight; -#else +#ifdef VERSION_EU panShift = noteSubEu->headsetPanRight; +#else + panShift = note->headsetPanRight; #endif note->prevHeadsetPanLeft = 0; prevPanShift = note->prevHeadsetPanRight; @@ -1982,10 +1333,10 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 break; case 2: dest = DMEM_ADDR_RIGHT_CH; -#if defined(VERSION_JP) || defined(VERSION_US) - panShift = note->headsetPanLeft; -#else +#ifdef VERSION_EU panShift = noteSubEu->headsetPanLeft; +#else + panShift = note->headsetPanLeft; #endif note->prevHeadsetPanRight = 0; @@ -1996,26 +1347,8 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 return cmd; } - if (flags != 1) // A_INIT? - { + if (flags != 1) { // A_INIT? // Slightly adjust the sample rate in order to fit a change in pan shift -#ifdef VERSION_SH - if (panShift != prevPanShift) { - pitch = (((bufLen << 0xf) / 2) - 1) / ((bufLen + panShift - prevPanShift - 2) / 2); - aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, (bufLen + panShift) - prevPanShift); - aResampleZoh(cmd++, pitch, 0); - } else { - aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen); - } - - if (prevPanShift != 0) { - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), - DMEM_ADDR_NOTE_PAN_TEMP, ALIGN(prevPanShift, 4)); - aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + prevPanShift, bufLen + panShift - prevPanShift); - } else { - aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP, bufLen + panShift); - } -#else if (prevPanShift == 0) { // Kind of a hack that moves the first samples into the resample state aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, 8); @@ -2026,7 +1359,7 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, 32); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panResampleState)); -#if defined(VERSION_EU) +#ifdef VERSION_EU pitch = (bufLen << 0xf) / (bufLen + panShift - prevPanShift + 8); if (pitch) { } @@ -2057,58 +1390,48 @@ u64 *note_apply_headset_pan_effects(u64 *cmd, struct Note *note, s32 bufLen, s32 } else { aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP, panShift + bufLen - prevPanShift); } -#endif } else { // Just shift right aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen); -#ifdef VERSION_SH - aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, panShift); - aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + panShift, bufLen); -#else aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + panShift, bufLen); aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, panShift); -#endif } if (panShift) { // Save excessive samples for next iteration -#ifdef VERSION_SH - aSaveBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP + bufLen, - VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), ALIGN(panShift, 4)); -#else aSetBuffer(cmd++, 0, 0, DMEM_ADDR_NOTE_PAN_TEMP + bufLen, panShift); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer)); -#endif } -#ifdef VERSION_SH - aAddMixer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, dest, (bufLen + 0x3f) & 0xffc0); -#else aSetBuffer(cmd++, 0, 0, 0, bufLen); aMix(cmd++, 0, /*gain*/ 0x7fff, /*in*/ DMEM_ADDR_NOTE_PAN_TEMP, /*out*/ dest); -#endif return cmd; } -#if defined(VERSION_JP) || defined(VERSION_US) +#ifndef VERSION_EU // Moved to playback.c in EU void note_init_volume(struct Note *note) { note->targetVolLeft = 0; note->targetVolRight = 0; - note->reverb = 0; note->reverbVol = 0; + note->reverbVolShifted = 0; note->unused2 = 0; note->curVolLeft = 1; note->curVolRight = 1; note->frequency = 0.0f; } -void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverb) { +void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol) { s32 panIndex; f32 volLeft; f32 volRight; + // Anding with 127 avoids out-of-bounds reads when pan is outside of [0, 1]. + // This can occur during PU movement -- see the bug comment in get_sound_pan + // in external.c. An out-of-bounds read by itself doesn't crash, but if the + // resulting value is a nan or denormal, performing arithmetic on it crashes + // on console. #ifdef VERSION_JP panIndex = MIN((s32)(pan * 127.5), 127); #else @@ -2170,9 +1493,9 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverb if (note->targetVolRight == 0) { note->targetVolRight++; } - if (note->reverb != reverb) { - note->reverb = reverb; - note->reverbVol = reverb << 8; + if (note->reverbVol != reverbVol) { + note->reverbVol = reverbVol; + note->reverbVolShifted = reverbVol << 8; note->envMixerNeedsInit = TRUE; return; } @@ -2215,3 +1538,4 @@ void note_disable(struct Note *note) { note->prevParentLayer = NO_LAYER; } #endif +#endif diff --git a/src/audio/synthesis.h b/src/audio/synthesis.h index 244fc4a8..9ca86439 100644 --- a/src/audio/synthesis.h +++ b/src/audio/synthesis.h @@ -90,7 +90,7 @@ extern s16 D_SH_803479B4; u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen); #if defined(VERSION_JP) || defined(VERSION_US) 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_vel_pan_reverb(struct Note *note, f32 velocity, f32 pan, u8 reverbVol); void note_set_frequency(struct Note *note, f32 frequency); void note_enable(struct Note *note); void note_disable(struct Note *note); diff --git a/src/audio/synthesis_sh.c b/src/audio/synthesis_sh.c new file mode 100644 index 00000000..d27df362 --- /dev/null +++ b/src/audio/synthesis_sh.c @@ -0,0 +1,910 @@ +#ifdef VERSION_SH +#include + +#include "synthesis.h" +#include "heap.h" +#include "data.h" +#include "load.h" +#include "seqplayer.h" +#include "internal.h" +#include "external.h" + + +#define DMEM_ADDR_TEMP 0x450 +#define DMEM_ADDR_RESAMPLED 0x470 +#define DMEM_ADDR_RESAMPLED2 0x5f0 +#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x5f0 +#define DMEM_ADDR_NOTE_PAN_TEMP 0x650 +#define DMEM_ADDR_COMPRESSED_ADPCM_DATA 0x990 +#define DMEM_ADDR_LEFT_CH 0x990 +#define DMEM_ADDR_RIGHT_CH 0xb10 +#define DMEM_ADDR_WET_LEFT_CH 0xc90 +#define DMEM_ADDR_WET_RIGHT_CH 0xe10 + +#define aSetLoadBufferPair(pkt, c, off) \ + aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \ + aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \ + aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_RIGHT_CH, 0, DEFAULT_LEN_1CH - c); \ + aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off))) + +#define aSetSaveBufferPair(pkt, c, d, off) \ + aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_LEFT_CH, d); \ + aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \ + aSetBuffer(pkt, 0, 0, c + DMEM_ADDR_WET_RIGHT_CH, d); \ + aSaveBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off))); + +#define ALIGN(val, amnt) (((val) + (1 << amnt) - 1) & ~((1 << amnt) - 1)) + +struct VolumeChange { + u16 sourceLeft; + u16 sourceRight; + u16 targetLeft; + u16 targetRight; +}; + +u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); +u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex); +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, u32 flags); +u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight); + +struct SynthesisReverb gSynthesisReverbs[4]; +u8 sAudioSynthesisPad[0x10]; + +s16 gVolume; +s8 gUseReverb; +s8 gNumSynthesisReverbs; +s16 D_SH_803479B4; // contains 4096 +struct NoteSubEu *gNoteSubsEu; + +// Equivalent functionality as the US/JP version, +// just that the reverb structure is chosen from an array with index +// Identical in EU. +void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) { + struct ReverbRingBufferItem *item; + struct SynthesisReverb *reverb = &gSynthesisReverbs[reverbIndex]; + s32 srcPos; + s32 dstPos; + s32 nSamples; + s32 excessiveSamples; + s32 UNUSED pad[3]; + 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->lengthA / 2; + srcPos += reverb->downsampleRate, dstPos++) { + reverb->ringBuffer.left[item->startPos + dstPos] = + item->toDownsampleLeft[srcPos]; + reverb->ringBuffer.right[item->startPos + dstPos] = + item->toDownsampleRight[srcPos]; + } + for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += reverb->downsampleRate, dstPos++) { + reverb->ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; + reverb->ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; + } + } + } + + item = &reverb->items[reverb->curFrame][updateIndex]; + nSamples = chunkLen / reverb->downsampleRate; + excessiveSamples = (nSamples + reverb->nextRingBufferPos) - reverb->bufSizePerChannel; + if (excessiveSamples < 0) { + // There is space in the ring buffer before it wraps around + item->lengthA = nSamples * 2; + item->lengthB = 0; + item->startPos = (s32) reverb->nextRingBufferPos; + reverb->nextRingBufferPos += nSamples; + } else { + // Ring buffer wrapped around + item->lengthA = (nSamples - excessiveSamples) * 2; + item->lengthB = excessiveSamples * 2; + item->startPos = reverb->nextRingBufferPos; + reverb->nextRingBufferPos = excessiveSamples; + } + // These fields are never read later + item->numSamplesAfterDownsampling = nSamples; + item->chunkLen = chunkLen; +} + +u64 *synthesis_load_reverb_ring_buffer(u64 *cmd, u16 addr, u16 srcOffset, s32 len, s32 reverbIndex) { + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[srcOffset]), + addr, len); + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[srcOffset]), + addr + DEFAULT_LEN_1CH, len); + return cmd; +} + +u64 *synthesis_save_reverb_ring_buffer(u64 *cmd, u16 addr, u16 destOffset, s32 len, s32 reverbIndex) { + aSaveBuffer(cmd++, addr, + VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.left[destOffset]), len); + aSaveBuffer(cmd++, addr + DEFAULT_LEN_1CH, + VIRTUAL_TO_PHYSICAL2(&gSynthesisReverbs[reverbIndex].ringBuffer.right[destOffset]), len); + return cmd; +} + +void func_sh_802ed644(s32 updateIndexStart, s32 noteIndex) { + s32 i; + + for (i = updateIndexStart + 1; i < gAudioBufferParameters.updatesPerFrame; i++) { + if (!gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].needsInit) { + gNoteSubsEu[gMaxSimultaneousNotes * i + noteIndex].enabled = FALSE; + } else { + break; + } + } +} + +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 = FALSE; + } else { + dest->enabled = FALSE; + } + } +} + +// TODO: (Scrub C) pointless mask and whitespace +u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { + s32 i, j; + u32 *aiBufPtr; + u64 *cmd = cmdBuf; + s32 chunkLen; + + for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { + process_sequences(i - 1); + synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - i); + } + aiBufPtr = (u32 *) aiBuf; + for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) { + if (i == 1) { + chunkLen = bufLen; + } else { + if (bufLen / i >= gAudioBufferParameters.samplesPerUpdateMax) { + chunkLen = gAudioBufferParameters.samplesPerUpdateMax; + } else if (bufLen / i <= gAudioBufferParameters.samplesPerUpdateMin) { + chunkLen = gAudioBufferParameters.samplesPerUpdateMin; + } else { + chunkLen = gAudioBufferParameters.samplesPerUpdate; + } + } + 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((s16 *) aiBufPtr, chunkLen, cmd, gAudioBufferParameters.updatesPerFrame - i); + bufLen -= chunkLen; + aiBufPtr += chunkLen; + } + + for (j = 0; j < gNumSynthesisReverbs; j++) { + if (gSynthesisReverbs[j].framesLeftToIgnore != 0) { + gSynthesisReverbs[j].framesLeftToIgnore--; + } + gSynthesisReverbs[j].curFrame ^= 1; + } + *writtenCmds = cmd - cmdBuf; + return cmd; +} + +u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { + struct ReverbRingBufferItem *item; + s16 startPad; + s16 paddedLengthA; + + item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; + + if (gSynthesisReverbs[reverbIndex].downsampleRate == 1) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); + } + aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + } else { + startPad = (item->startPos % 8u) * 2; + paddedLengthA = ALIGN(startPad + item->lengthA, 4); + + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, (item->startPos - startPad / 2), DEFAULT_LEN_1CH, reverbIndex); + if (item->lengthB != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + paddedLengthA, 0, DEFAULT_LEN_1CH - paddedLengthA, reverbIndex); + } + + aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED + startPad, DMEM_ADDR_WET_LEFT_CH, bufLen * 2); + aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateLeft)); + + aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED2 + startPad, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2); + aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateRight)); + + aAddMixer(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + aMix(cmd++, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); + } + if (gSynthesisReverbs[reverbIndex].panRight != 0 || gSynthesisReverbs[reverbIndex].panLeft != 0) { + // Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan) + aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_1CH); + aMix(cmd++, gSynthesisReverbs[reverbIndex].panRight, DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_1CH); + aMix(cmd++, gSynthesisReverbs[reverbIndex].panLeft, DMEM_ADDR_RESAMPLED, DMEM_ADDR_WET_RIGHT_CH, DEFAULT_LEN_1CH); + } + return cmd; +} + +u64 *synthesis_load_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { + struct ReverbRingBufferItem *item; + struct SynthesisReverb *reverb; + + reverb = &gSynthesisReverbs[reverbIndex]; + item = &reverb->items[reverb->curFrame][updateIndex]; + // Get the oldest samples in the ring buffer into the wet channels + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { + // Ring buffer wrapped + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex); + } + return cmd; +} + +u64 *synthesis_save_reverb_samples(u64 *cmd, s16 reverbIndex, s16 updateIndex) { + struct ReverbRingBufferItem *item; + + item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; + switch (gSynthesisReverbs[reverbIndex].downsampleRate) { + case 1: + // Put the oldest samples in the ring buffer into the wet channels + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { + // Ring buffer wrapped + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); + } + break; + + default: + // Downsampling is done later by CPU when RSP is done, therefore we need to have double + // buffering. Left and right buffers are adjacent in memory. + aSaveBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH, + VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex].toDownsampleLeft), DEFAULT_LEN_2CH); + break; + } + gSynthesisReverbs[reverbIndex].resampleFlags = 0; + return cmd; +} + +u64 *func_sh_802EDF24(u64 *cmd, s16 reverbIndex, s16 updateIndex) { + struct ReverbRingBufferItem *item; + struct SynthesisReverb *reverb; + + reverb = &gSynthesisReverbs[reverbIndex]; + item = &reverb->items[reverb->curFrame][updateIndex]; + // Put the oldest samples in the ring buffer into the wet channels + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { + // Ring buffer wrapped + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + item->lengthA, 0, item->lengthB, reverbIndex); + } + return cmd; +} + +u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { + struct NoteSubEu *noteSubEu; + u8 noteIndices[56]; + s32 temp; + s32 i; + s16 j; + s16 notePos = 0; + + if (gNumSynthesisReverbs == 0) { + for (i = 0; i < gMaxSimultaneousNotes; i++) { + if (gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i].enabled) { + noteIndices[notePos++] = i; + } + } + } else { + for (j = 0; j < gNumSynthesisReverbs; j++) { + for (i = 0; i < gMaxSimultaneousNotes; i++) { + noteSubEu = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i]; + if (noteSubEu->enabled && j == noteSubEu->reverbIndex) { + noteIndices[notePos++] = i; + } + } + } + + for (i = 0; i < gMaxSimultaneousNotes; i++) { + noteSubEu = &gNoteSubsEu[gMaxSimultaneousNotes * updateIndex + i]; + if (noteSubEu->enabled && noteSubEu->reverbIndex >= gNumSynthesisReverbs) { + noteIndices[notePos++] = i; + } + } + } + aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); + i = 0; + for (j = 0; j < gNumSynthesisReverbs; j++) { + gUseReverb = gSynthesisReverbs[j].useReverb; + if (gUseReverb != 0) { + cmd = synthesis_resample_and_mix_reverb(cmd, bufLen, j, updateIndex); + } + for (; i < notePos; i++) { + temp = updateIndex * gMaxSimultaneousNotes; + if (j == gNoteSubsEu[temp + noteIndices[i]].reverbIndex) { + cmd = synthesis_process_note(noteIndices[i], + &gNoteSubsEu[temp + noteIndices[i]], + &gNotes[noteIndices[i]].synthesisState, + aiBuf, bufLen, cmd, updateIndex); + continue; + } else { + break; + } + } + if (gSynthesisReverbs[j].useReverb != 0) { + if (gSynthesisReverbs[j].unk100 != NULL) { + aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk100); + aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_LEFT_CH, gSynthesisReverbs[j].unk108); + } + if (gSynthesisReverbs[j].unk104 != NULL) { + aFilter(cmd++, 0x02, bufLen * 2, gSynthesisReverbs[j].unk104); + aFilter(cmd++, gSynthesisReverbs[j].resampleFlags, DMEM_ADDR_WET_RIGHT_CH, gSynthesisReverbs[j].unk10C); + } + cmd = synthesis_save_reverb_samples(cmd, j, updateIndex); + if (gSynthesisReverbs[j].unk5 != -1) { + if (gSynthesisReverbs[gSynthesisReverbs[j].unk5].downsampleRate == 1) { + cmd = synthesis_load_reverb_samples(cmd, gSynthesisReverbs[j].unk5, updateIndex); + aMix(cmd++, gSynthesisReverbs[j].unk08, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_RESAMPLED, DEFAULT_LEN_2CH); + cmd = func_sh_802EDF24(cmd++, gSynthesisReverbs[j].unk5, updateIndex); + } + } + } + } + for (; i < notePos; i++) { + struct NoteSubEu *noteSubEu2 = &gNoteSubsEu[updateIndex * gMaxSimultaneousNotes + noteIndices[i]]; + cmd = synthesis_process_note(noteIndices[i], + noteSubEu2, + &gNotes[noteIndices[i]].synthesisState, + aiBuf, bufLen, cmd, updateIndex); + } + + temp = bufLen * 2; + aInterleave(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH, temp); + aSaveBuffer(cmd++, DMEM_ADDR_TEMP, VIRTUAL_TO_PHYSICAL2(aiBuf), temp * 2); + return cmd; +} + +u64 *synthesis_process_note(s32 noteIndex, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, UNUSED s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { + UNUSED s32 pad0[3]; + struct AudioBankSample *audioBookSample; // sp164, sp138 + struct AdpcmLoop *loopInfo; // sp160, sp134 + s16 *curLoadedBook; // sp154, sp130 + UNUSED u8 padEU[0x04]; + UNUSED u8 pad8[0x04]; + s32 noteFinished; // 150 t2, sp124 + s32 restart; // 14c t3, sp120 + s32 flags; // sp148, sp11C, t8 + u16 resamplingRateFixedPoint; // sp5c, sp11A + s32 nSamplesToLoad; //s0, Ec + UNUSED u8 pad7[0x0c]; // sp100 + s32 sp130; //sp128, sp104 + UNUSED s32 tempBufLen; + UNUSED u32 pad9; + s32 t0; + u8 *sampleAddr; // sp120, spF4 + s32 s6; + s32 samplesLenAdjusted; // 108, spEC + s32 nAdpcmSamplesProcessed; // signed required for US // spc0 + s32 endPos; // sp110, spE4 + s32 nSamplesToProcess; // sp10c/a0, spE0 + // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange + // behavior with the break near the end of the loop, causing US and JP to need a goto instead + UNUSED s32 samplesLenInt; + s32 s2; + s32 leftRight; //s0 + s32 s5; //s4 + u32 samplesLenFixedPoint; // v1_1 + s32 s3; // spA0 + s32 nSamplesInThisIteration; // v1_2 + u32 a3; + u8 *v0_2; + s32 unk_s6; // sp90 + s32 s5Aligned; + s32 sp88; + s32 sp84; + u32 temp; + s32 nParts; // spE8, spBC + s32 curPart; // spE4, spB8 + s32 aligned; + UNUSED u32 padSH1; + s32 resampledTempLen; // spD8, spAC, sp6c + u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA, sp6a -- 6C + UNUSED u32 padSH2; + UNUSED u32 padSH3; + UNUSED u32 padSH4; + struct Note *note; // sp58 + u16 sp56; // sp56 + u16 addr; + u8 synthesisVolume; + + curLoadedBook = NULL; + note = &gNotes[noteIndex]; + flags = 0; + if (noteSubEu->needsInit == TRUE) { + flags = A_INIT; + synthesisState->restart = 0; + synthesisState->samplePosInt = 0; + synthesisState->samplePosFrac = 0; + synthesisState->curVolLeft = 0; + synthesisState->curVolRight = 0; + synthesisState->prevHeadsetPanRight = 0; + synthesisState->prevHeadsetPanLeft = 0; + synthesisState->reverbVol = noteSubEu->reverbVol; + synthesisState->unk5 = 0; + note->noteSubEu.finished = 0; + } + + resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; + nParts = noteSubEu->hasTwoAdpcmParts + 1; + samplesLenFixedPoint = (resamplingRateFixedPoint * bufLen * 2) + synthesisState->samplePosFrac; + nSamplesToLoad = (samplesLenFixedPoint >> 0x10); + synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; + + if ((synthesisState->unk5 == 1) && (nParts == 2)) { + nSamplesToLoad += 2; + sp56 = 2; + } else if ((synthesisState->unk5 == 2) && (nParts == 1)) { + nSamplesToLoad -= 4; + sp56 = 4; + } else { + sp56 = 0; + } + + + synthesisState->unk5 = nParts; + + if (noteSubEu->isSyntheticWave) { + cmd = load_wave_samples(cmd, noteSubEu, synthesisState, nSamplesToLoad); + noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE; + synthesisState->samplePosInt += nSamplesToLoad; + } else { + // ADPCM note + audioBookSample = noteSubEu->sound.audioBankSound->sample; + loopInfo = audioBookSample->loop; + endPos = loopInfo->end; + sampleAddr = audioBookSample->sampleAddr; + resampledTempLen = 0; + for (curPart = 0; curPart < nParts; curPart++) { + nAdpcmSamplesProcessed = 0; // s8 + s5 = 0; // s4 + + if (nParts == 1) { + samplesLenAdjusted = nSamplesToLoad; + } else if (nSamplesToLoad & 1) { + samplesLenAdjusted = (nSamplesToLoad & ~1) + (curPart * 2); + } else { + samplesLenAdjusted = nSamplesToLoad; + } + + if (audioBookSample->codec == CODEC_ADPCM) { + if (curLoadedBook != (*audioBookSample->book).book) { + u32 nEntries; + switch (noteSubEu->bookOffset) { + case 1: + curLoadedBook = euUnknownData_80301950 + 1; + break; + case 2: + curLoadedBook = euUnknownData_80301950 + 2; + break; + case 3: + default: + curLoadedBook = audioBookSample->book->book; + break; + } + nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors; + aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); + } + } + + while (nAdpcmSamplesProcessed != samplesLenAdjusted) { + s32 samplesRemaining; // v1 + s32 s0; + + noteFinished = FALSE; + restart = FALSE; + s2 = synthesisState->samplePosInt & 0xf; + samplesRemaining = endPos - synthesisState->samplePosInt; + nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; + + if (s2 == 0 && synthesisState->restart == FALSE) { + s2 = 16; + } + s6 = 16 - s2; // a1 + if (nSamplesToProcess < samplesRemaining) { + t0 = (nSamplesToProcess - s6 + 0xf) / 16; + s0 = t0 * 16; + s3 = s6 + s0 - nSamplesToProcess; + } else { + s0 = samplesRemaining - s6; + s3 = 0; + if (s0 <= 0) { + s0 = 0; + s6 = samplesRemaining; + } + t0 = (s0 + 0xf) / 16; + if (loopInfo->count != 0) { + // Loop around and restart + restart = 1; + } else { + noteFinished = 1; + } + } + switch (audioBookSample->codec) { + case CODEC_ADPCM: + unk_s6 = 9; + sp88 = 0x10; + sp84 = 0; + break; + case CODEC_S8: + unk_s6 = 0x10; + sp88 = 0x10; + sp84 = 0; + break; + case CODEC_SKIP: goto skip; + } + if (t0 != 0) { + temp = (synthesisState->samplePosInt + sp88 - s2) / 16; + if (audioBookSample->medium == 0) { + v0_2 = sp84 + (temp * unk_s6) + sampleAddr; + } else { + v0_2 = dma_sample_data((uintptr_t)(sp84 + (temp * unk_s6) + sampleAddr), + ALIGN(t0 * unk_s6 + 16, 4), flags, &synthesisState->sampleDmaIndex, audioBookSample->medium); + } + + a3 = ((uintptr_t)v0_2 & 0xf); + aligned = ALIGN(t0 * unk_s6 + 16, 4); + addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff; + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3), addr, ALIGN(t0 * unk_s6 + 16, 4)); + } else { + s0 = 0; + a3 = 0; + } + if (synthesisState->restart != FALSE) { + aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); + flags = A_LOOP; // = 2 + synthesisState->restart = FALSE; + } + nSamplesInThisIteration = s0 + s6 - s3; + if (nAdpcmSamplesProcessed == 0) { + switch (audioBookSample->codec) { + case CODEC_ADPCM: + aligned = ALIGN(t0 * unk_s6 + 16, 4); + addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff; + aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); + aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + break; + case CODEC_S8: + aligned = ALIGN(t0 * unk_s6 + 16, 4); + addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff; + aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); + aS8Dec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + break; + } + sp130 = s2 * 2; + } else { + s5Aligned = ALIGN(s5 + 16, 4); + switch (audioBookSample->codec) { + case CODEC_ADPCM: + aligned = ALIGN(t0 * unk_s6 + 16, 4); + addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff; + aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2); + aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + break; + case CODEC_S8: + aligned = ALIGN(t0 * unk_s6 + 16, 4); + addr = (DMEM_ADDR_COMPRESSED_ADPCM_DATA - aligned) & 0xffff; + aSetBuffer(cmd++, 0, addr + a3, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2); + aS8Dec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); + break; + } + aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); + } + nAdpcmSamplesProcessed += nSamplesInThisIteration; + switch (flags) { + case A_INIT: // = 1 + sp130 = 0x20; + s5 = (s0 + 0x10) * 2; + break; + case A_LOOP: // = 2 + s5 = (nSamplesInThisIteration) * 2 + s5; + break; + default: + if (s5 != 0) { + s5 = (nSamplesInThisIteration) * 2 + s5; + } else { + s5 = (s2 + (nSamplesInThisIteration)) * 2; + } + break; + } + flags = 0; +skip: + if (noteFinished) { + aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, + (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); + noteSubEu->finished = 1; + note->noteSubEu.finished = 1; + func_sh_802ed644(updateIndex, noteIndex); + break; + } + if (restart != 0) { + synthesisState->restart = TRUE; + synthesisState->samplePosInt = loopInfo->start; + } else { + synthesisState->samplePosInt += nSamplesToProcess; + } + } + + switch (nParts) { + case 1: + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + sp130; + break; + case 2: + switch (curPart) { + case 0: + aDownsampleHalf(cmd++, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED); + resampledTempLen = samplesLenAdjusted; + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED; + if (noteSubEu->finished != FALSE) { + aClearBuffer(cmd++, noteSamplesDmemAddrBeforeResampling + resampledTempLen, samplesLenAdjusted + 0x10); + } + break; + case 1: + aDownsampleHalf(cmd++, ALIGN(samplesLenAdjusted / 2, 3), DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, resampledTempLen + DMEM_ADDR_RESAMPLED); + break; + } + } + if (noteSubEu->finished != FALSE) { + break; + } + } + } + flags = 0; + if (noteSubEu->needsInit == TRUE) { + flags = A_INIT; + noteSubEu->needsInit = FALSE; + } + flags = flags | sp56; + cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint, + noteSamplesDmemAddrBeforeResampling, flags); + if ((flags & 1) != 0) { + flags = 1; + } + + if (noteSubEu->filter) { + aFilter(cmd++, 0x02, bufLen * 2, noteSubEu->filter); + aFilter(cmd++, flags, DMEM_ADDR_TEMP, synthesisState->synthesisBuffers->filterBuffer); + + } + + if (noteSubEu->bookOffset == 3) { + aUnknown25(cmd++, 0, bufLen * 2, DMEM_ADDR_TEMP, DMEM_ADDR_TEMP); + } + + synthesisVolume = noteSubEu->synthesisVolume; + if (synthesisVolume != 0) { + if (synthesisVolume < 0x10) { + synthesisVolume = 0x10; + } + + aHiLoGain(cmd++, synthesisVolume, (bufLen + 0x10) * 2, DMEM_ADDR_TEMP); + } + + if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { + leftRight = 1; + } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { + leftRight = 2; + } else { + leftRight = 0; + } + cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, DMEM_ADDR_TEMP, leftRight, flags); + if (noteSubEu->usesHeadsetPanEffects) { + if ((flags & 1) == 0) { + flags = 0; + } + cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight); + } + + return cmd; +} + +u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { + s32 a3; + s32 repeats; + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples), + DMEM_ADDR_UNCOMPRESSED_NOTE, 128); + + synthesisState->samplePosInt &= 0x3f; + a3 = 64 - synthesisState->samplePosInt; + if (a3 < nSamplesToLoad) { + repeats = (nSamplesToLoad - a3 + 63) / 64; + if (repeats != 0) { + aDuplicate(cmd++, + /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, + /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + 128, + /*copies*/ repeats); + } + } + return cmd; +} + +u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { + if (pitch == 0) { + aClearBuffer(cmd++, DMEM_ADDR_TEMP, count); + } else { + aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); + aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); + } + return cmd; +} + +u64 *process_envelope(u64 *cmd, struct NoteSubEu *note, struct NoteSynthesisState *synthesisState, s32 nSamples, u16 inBuf, s32 headsetPanSettings, UNUSED u32 flags) { + u16 sourceRight; + u16 sourceLeft; + u16 targetLeft; + u16 targetRight; + s16 rampLeft; + s16 rampRight; + s32 sourceReverbVol; + s16 rampReverb; + s32 reverbVolDiff = 0; + + sourceLeft = synthesisState->curVolLeft; + sourceRight = synthesisState->curVolRight; + targetLeft = note->targetVolLeft; + targetRight = note->targetVolRight; + targetLeft <<= 4; + targetRight <<= 4; + + if (targetLeft != sourceLeft) { + rampLeft = (targetLeft - sourceLeft) / (nSamples >> 3); + } else { + rampLeft = 0; + } + if (targetRight != sourceRight) { + rampRight = (targetRight - sourceRight) / (nSamples >> 3); + } else { + rampRight = 0; + } + + sourceReverbVol = synthesisState->reverbVol; + if (note->reverbVol != sourceReverbVol) { + reverbVolDiff = ((note->reverbVol & 0x7f) - (sourceReverbVol & 0x7f)) << 9; + rampReverb = reverbVolDiff / (nSamples >> 3); + synthesisState->reverbVol = note->reverbVol; + } else { + rampReverb = 0; + } + synthesisState->curVolLeft = sourceLeft + rampLeft * (nSamples >> 3); + synthesisState->curVolRight = sourceRight + rampRight * (nSamples >> 3); + + if (note->usesHeadsetPanEffects) { + aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DEFAULT_LEN_1CH); + aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, rampReverb, rampLeft, rampRight); + aEnvSetup2(cmd++, sourceLeft, sourceRight); + + switch (headsetPanSettings) { + case 1: + aEnvMixer(cmd++, + inBuf, nSamples, + (sourceReverbVol & 0x80) >> 7, + note->stereoStrongRight, note->stereoStrongLeft, + DMEM_ADDR_NOTE_PAN_TEMP, + DMEM_ADDR_RIGHT_CH, + DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + case 2: + aEnvMixer(cmd++, + inBuf, nSamples, + (sourceReverbVol & 0x80) >> 7, + note->stereoStrongRight, note->stereoStrongLeft, + DMEM_ADDR_LEFT_CH, + DMEM_ADDR_NOTE_PAN_TEMP, + DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + default: + aEnvMixer(cmd++, + inBuf, nSamples, + (sourceReverbVol & 0x80) >> 7, + note->stereoStrongRight, note->stereoStrongLeft, + DMEM_ADDR_LEFT_CH, + DMEM_ADDR_RIGHT_CH, + DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + break; + } + } else { + aEnvSetup1(cmd++, (sourceReverbVol & 0x7f) * 2, rampReverb, rampLeft, rampRight); + aEnvSetup2(cmd++, sourceLeft, sourceRight); + aEnvMixer(cmd++, + inBuf, nSamples, + (sourceReverbVol & 0x80) >> 7, + note->stereoStrongRight, note->stereoStrongLeft, + DMEM_ADDR_LEFT_CH, + DMEM_ADDR_RIGHT_CH, + DMEM_ADDR_WET_LEFT_CH, + DMEM_ADDR_WET_RIGHT_CH); + } + return cmd; +} + +u64 *note_apply_headset_pan_effects(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *note, s32 bufLen, s32 flags, s32 leftRight) { + u16 dest; + u16 pitch; + u8 prevPanShift; + u8 panShift; + UNUSED u8 unkDebug; + + switch (leftRight) { + case 1: + dest = DMEM_ADDR_LEFT_CH; + panShift = noteSubEu->headsetPanRight; + note->prevHeadsetPanLeft = 0; + prevPanShift = note->prevHeadsetPanRight; + note->prevHeadsetPanRight = panShift; + break; + case 2: + dest = DMEM_ADDR_RIGHT_CH; + panShift = noteSubEu->headsetPanLeft; + note->prevHeadsetPanRight = 0; + + prevPanShift = note->prevHeadsetPanLeft; + note->prevHeadsetPanLeft = panShift; + break; + default: + return cmd; + } + + if (flags != 1) { // A_INIT? + // Slightly adjust the sample rate in order to fit a change in pan shift + if (panShift != prevPanShift) { + pitch = (((bufLen << 0xf) / 2) - 1) / ((bufLen + panShift - prevPanShift - 2) / 2); + aSetBuffer(cmd++, 0, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, (bufLen + panShift) - prevPanShift); + aResampleZoh(cmd++, pitch, 0); + } else { + aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen); + } + + if (prevPanShift != 0) { + aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), + DMEM_ADDR_NOTE_PAN_TEMP, ALIGN(prevPanShift, 4)); + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + prevPanShift, bufLen + panShift - prevPanShift); + } else { + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP, bufLen + panShift); + } + } else { + // Just shift right + aDMEMMove(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, DMEM_ADDR_TEMP, bufLen); + aClearBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, panShift); + aDMEMMove(cmd++, DMEM_ADDR_TEMP, DMEM_ADDR_NOTE_PAN_TEMP + panShift, bufLen); + } + + if (panShift) { + // Save excessive samples for next iteration + aSaveBuffer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP + bufLen, + VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->panSamplesBuffer), ALIGN(panShift, 4)); + } + + aAddMixer(cmd++, DMEM_ADDR_NOTE_PAN_TEMP, dest, (bufLen + 0x3f) & 0xffc0); + + return cmd; +} +#endif diff --git a/src/buffers/buffers.c b/src/buffers/buffers.c index 72b031bc..527fce94 100644 --- a/src/buffers/buffers.c +++ b/src/buffers/buffers.c @@ -1,6 +1,7 @@ #include #include "buffers.h" +#include "config.h" ALIGNED8 u8 gDecompressionHeap[0xD000]; #if defined(VERSION_EU) @@ -15,7 +16,7 @@ ALIGNED8 u8 gIdleThreadStack[0x800]; ALIGNED8 u8 gThread3Stack[0x2000]; ALIGNED8 u8 gThread4Stack[0x2000]; ALIGNED8 u8 gThread5Stack[0x2000]; -#ifdef VERSION_SH +#if ENABLE_RUMBLE ALIGNED8 u8 gThread6Stack[0x2000]; #endif // 0x400 bytes diff --git a/src/buffers/buffers.h b/src/buffers/buffers.h index b9abbf6b..92c97c93 100644 --- a/src/buffers/buffers.h +++ b/src/buffers/buffers.h @@ -5,6 +5,7 @@ #include "game/save_file.h" #include "game/game_init.h" +#include "config.h" extern u8 gDecompressionHeap[]; @@ -18,7 +19,7 @@ extern u8 gIdleThreadStack[]; extern u8 gThread3Stack[]; extern u8 gThread4Stack[]; extern u8 gThread5Stack[]; -#ifdef VERSION_SH +#if ENABLE_RUMBLE extern u8 gThread6Stack[]; #endif diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index cc39e5a2..5617e5b9 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -31,7 +31,7 @@ static u16 gRandomSeed16; // Unused function that directly jumps to a behavior command and resets the object's stack index. -static void goto_behavior_unused(const BehaviorScript *bhvAddr) { +UNUSED static void goto_behavior_unused(const BehaviorScript *bhvAddr) { gCurBhvCommand = segmented_to_virtual(bhvAddr); gCurrentObject->bhvStackIndex = 0; } @@ -107,7 +107,7 @@ static uintptr_t cur_obj_bhv_stack_pop(void) { return bhvAddr; } -static void stub_behavior_script_1(void) { +UNUSED static void stub_behavior_script_1(void) { for (;;) { ; } @@ -687,7 +687,7 @@ static s32 bhv_cmd_begin(void) { // It cannot be simply re-added to the table, as unlike all other bhv commands it takes a parameter. // Theoretically this command would have been of variable size. // Included below is a modified/repaired version of this function that would work properly. -static void bhv_cmd_set_int_random_from_table(s32 tableSize) { +UNUSED static void bhv_cmd_set_int_random_from_table(s32 tableSize) { u8 field = BHV_CMD_GET_2ND_U8(0); s32 table[16]; s32 i; diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 884e9b45..e6bd3c20 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -827,7 +827,7 @@ struct LevelCommand *level_script_execute(struct LevelCommand *cmd) { } profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - init_render_image(); + init_rcp(); render_game(); end_master_display_list(); alloc_display_list(0); diff --git a/src/engine/math_util.c b/src/engine/math_util.c index e5d59d8b..72fa6259 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -15,7 +15,14 @@ int gSplineState; // These functions have bogus return values. // Disable the compiler warning. #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-local-addr" + +#ifdef __GNUC__ +#if defined(__clang__) + #pragma GCC diagnostic ignored "-Wreturn-stack-address" +#else + #pragma GCC diagnostic ignored "-Wreturn-local-addr" +#endif +#endif /// Copy vector 'src' to 'dest' void *vec3f_copy(Vec3f dest, Vec3f src) { diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 9a01f8bb..318a8043 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -369,7 +369,7 @@ f32 unused_obj_find_floor_height(struct Object *obj) { */ struct FloorGeometry sFloorGeo; -static u8 unused8038BE50[0x40]; +UNUSED static u8 unused8038BE50[0x40]; /** * Return the floor height underneath (xPos, yPos, zPos) and populate `floorGeo` diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index b5113901..74ee5e7f 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -291,7 +291,7 @@ static void add_surface(struct Surface *surface, s32 dynamic) { } } -static void stub_surface_load_1(void) { +UNUSED static void stub_surface_load_1(void) { } /** @@ -653,7 +653,7 @@ void clear_dynamic_surfaces(void) { } } -static void unused_80383604(void) { +UNUSED static void unused_80383604(void) { } /** diff --git a/src/game/area.c b/src/game/area.c index af9d0156..fc2b7b69 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -21,6 +21,7 @@ #include "engine/geo_layout.h" #include "save_file.h" #include "level_table.h" +#include "dialog_ids.h" struct SpawnInfo gPlayerSpawnInfos[1]; struct GraphNode *D_8033A160[0x100]; @@ -32,7 +33,7 @@ s16 gCurrCourseNum; s16 gCurrActNum; s16 gCurrAreaIndex; s16 gSavedCourseNum; -s16 gPauseScreenMode; +s16 gMenuOptSelectIndex; s16 gSaveOptSelectIndex; struct SpawnInfo *gMarioSpawnInfo = &gPlayerSpawnInfos[0]; @@ -196,8 +197,8 @@ void clear_areas(void) { gAreaData[i].unused28 = NULL; gAreaData[i].whirlpools[0] = NULL; gAreaData[i].whirlpools[1] = NULL; - gAreaData[i].dialog[0] = 255; - gAreaData[i].dialog[1] = 255; + gAreaData[i].dialog[0] = DIALOG_NONE; + gAreaData[i].dialog[1] = DIALOG_NONE; gAreaData[i].musicParam = 0; gAreaData[i].musicParam2 = 0; } @@ -373,19 +374,20 @@ void render_game(void) { render_text_labels(); do_cutscene_handler(); print_displaying_credits_entry(); + gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT); - gPauseScreenMode = render_menus_and_dialogs(); - - if (gPauseScreenMode != 0) { - gSaveOptSelectIndex = gPauseScreenMode; + gMenuOptSelectIndex = render_menus_and_dialogs(); + if (gMenuOptSelectIndex != MENU_OPT_NONE) { + gSaveOptSelectIndex = gMenuOptSelectIndex; } if (D_8032CE78 != NULL) { make_viewport_clip_rect(D_8032CE78); - } else + } else { gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT); + } if (gWarpTransition.isActive) { if (gWarpTransDelay == 0) { diff --git a/src/game/area.h b/src/game/area.h index d746caa7..60010a70 100644 --- a/src/game/area.h +++ b/src/game/area.h @@ -118,6 +118,24 @@ struct WarpTransition /*0x04*/ struct WarpTransitionData data; }; +enum MenuOption { + MENU_OPT_NONE, + MENU_OPT_1, + MENU_OPT_2, + MENU_OPT_3, + MENU_OPT_DEFAULT = MENU_OPT_1, + + // Course Pause Menu + MENU_OPT_CONTINUE = MENU_OPT_1, + MENU_OPT_EXIT_COURSE = MENU_OPT_2, + MENU_OPT_CAMERA_ANGLE_R = MENU_OPT_3, + + // Save Menu + MENU_OPT_SAVE_AND_CONTINUE = MENU_OPT_1, + MENU_OPT_SAVE_AND_QUIT = MENU_OPT_2, + MENU_OPT_CONTINUE_DONT_SAVE = MENU_OPT_3 +}; + extern struct GraphNode **gLoadedGraphNodes; extern struct SpawnInfo gPlayerSpawnInfos[]; extern struct GraphNode *D_8033A160[]; @@ -127,7 +145,7 @@ extern s16 gCurrCourseNum; extern s16 gCurrActNum; extern s16 gCurrAreaIndex; extern s16 gSavedCourseNum; -extern s16 gPauseScreenMode; +extern s16 gMenuOptSelectIndex; extern s16 gSaveOptSelectIndex; extern struct SpawnInfo *gMarioSpawnInfo; diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index 03dbaa1d..a42849a5 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -23,6 +23,7 @@ #include "level_table.h" #include "level_update.h" #include "levels/bob/header.h" +#include "levels/bowser_3/header.h" #include "levels/castle_inside/header.h" #include "levels/hmc/header.h" #include "main.h" @@ -61,14 +62,6 @@ struct Struct8032F34C { const void *segAddr; }; -struct Struct8032F698 { - void *unk0; - s16 unk1; - s16 unk2; - s16 unk3; - s16 unk4; -}; - struct Struct802C0DF0 { u8 unk0; u8 unk1; @@ -89,10 +82,10 @@ struct OpenableGrill { const Collision *collision; }; -s32 D_8032F0C0[] = { SAVE_FLAG_HAVE_WING_CAP, SAVE_FLAG_HAVE_METAL_CAP, SAVE_FLAG_HAVE_VANISH_CAP }; +static s32 sCapSaveFlags[] = { SAVE_FLAG_HAVE_WING_CAP, SAVE_FLAG_HAVE_METAL_CAP, SAVE_FLAG_HAVE_VANISH_CAP }; // Boo Roll -s16 D_8032F0CC[] = { 6047, 5664, 5292, 4934, 4587, 4254, 3933, 3624, 3329, 3046, 2775, +static s16 sBooHitRotations[] = { 6047, 5664, 5292, 4934, 4587, 4254, 3933, 3624, 3329, 3046, 2775, 2517, 2271, 2039, 1818, 1611, 1416, 1233, 1063, 906, 761, 629, 509, 402, 308, 226, 157, 100, 56, 25, 4, 0 }; @@ -115,21 +108,21 @@ s16 D_8032F0CC[] = { 6047, 5664, 5292, 4934, 4587, 4254, 3933, 3624, 3329, 3046, #include "behaviors/white_puff_explode.inc.c" // not in behavior file -struct SpawnParticlesInfo D_8032F270 = { 2, 20, MODEL_MIST, 0, 40, 5, 30, 20, 252, 30, 330.0f, 10.0f }; +struct SpawnParticlesInfo sMistParticles = { 2, 20, MODEL_MIST, 0, 40, 5, 30, 20, 252, 30, 330.0f, 10.0f }; // generate_wind_puffs/dust (something like that) void spawn_mist_particles_variable(s32 count, s32 offsetY, f32 size) { - D_8032F270.sizeBase = size; - D_8032F270.sizeRange = size / 20.0; - D_8032F270.offsetY = offsetY; + sMistParticles.sizeBase = size; + sMistParticles.sizeRange = size / 20.0; + sMistParticles.offsetY = offsetY; if (count == 0) { - D_8032F270.count = 20; + sMistParticles.count = 20; } else if (count > 20) { - D_8032F270.count = count; + sMistParticles.count = count; } else { - D_8032F270.count = 4; + sMistParticles.count = 4; } - cur_obj_spawn_particles(&D_8032F270); + cur_obj_spawn_particles(&sMistParticles); } #include "behaviors/sparkle_spawn_star.inc.c" @@ -205,6 +198,8 @@ void spawn_sparkle_particles(s32 n, s32 a1, s32 a2, s32 r) { #include "behaviors/bowser_key.inc.c" #include "behaviors/bullet_bill.inc.c" #include "behaviors/bowser.inc.c" +#include "behaviors/bowser_falling_platform.inc.c" +#include "behaviors/bowser_flame.inc.c" #include "behaviors/blue_fish.inc.c" // Not in behavior file, duplicate of vec3f_copy except without bad return. diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index d068492e..97939170 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -231,7 +231,7 @@ void bhv_big_boo_loop(void); void bhv_courtyard_boo_triplet_init(void); void obj_set_secondary_camera_focus(void); void bhv_boo_loop(void); -void bhv_boo_boss_spawned_bridge_loop(void); +void bhv_boo_staircase(void); void bhv_bbh_tilting_trap_platform_loop(void); void bhv_haunted_bookshelf_loop(void); void bhv_merry_go_round_loop(void); diff --git a/src/game/behaviors/beta_boo_key.inc.c b/src/game/behaviors/beta_boo_key.inc.c index 27a85dee..472aa0fb 100644 --- a/src/game/behaviors/beta_boo_key.inc.c +++ b/src/game/behaviors/beta_boo_key.inc.c @@ -87,14 +87,14 @@ static void beta_boo_key_dropped_loop(void) { if (obj_check_if_collided_with_object(o, gMarioObject)) { // This interaction status is 0x01, the first interaction status flag. // It was only used for Hoot in the final game, but it seems it could've - // done something else or held some special meaning in beta. + // treated as a TRUE/FALSE statement or held some special meaning in beta. // Earlier, in beta_boo_key_drop (called when the parent boo is killed), // o->parentObj is set to the parent boo's parentObj. This means that // here, the parentObj is actually the parent of the old parent boo. // One theory about this code is that there was a boo spawner, which // spawned "false" boos and one "true" boo with the key, and the player // was intended to find the one with the key to progress. - o->parentObj->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; + o->parentObj->oInteractStatus = TRUE; // Delete the object and spawn sparkles obj_mark_for_deletion(o); diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c index 2e3a314c..1f6124e4 100644 --- a/src/game/behaviors/bobomb.inc.c +++ b/src/game/behaviors/bobomb.inc.c @@ -46,7 +46,7 @@ void bobomb_check_interactions(void) { obj_set_hitbox(o, &sBobombHitbox); if ((o->oInteractStatus & INT_STATUS_INTERACTED) != 0) { - if ((o->oInteractStatus & INT_STATUS_MARIO_UNK1) != 0) + if ((o->oInteractStatus & INT_STATUS_MARIO_KNOCKBACK_DMG) != 0) { o->oMoveAngleYaw = gMarioObject->header.gfx.angle[1]; o->oForwardVel = 25.0; @@ -344,7 +344,7 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) { break; case BOBOMB_BUDDY_CANNON_STOP_TALKING: - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; o->oBobombBuddyHasTalkedToMario = BOBOMB_BUDDY_HAS_TALKED; @@ -356,14 +356,14 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) { } void bobomb_buddy_act_talk(void) { - if (set_mario_npc_dialog(1) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_FRONT) == MARIO_DIALOG_STATUS_SPEAK) { o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; switch (o->oBobombBuddyRole) { case BOBOMB_BUDDY_ROLE_ADVICE: if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, o->oBehParams2ndByte) != BOBOMB_BUDDY_BP_STYPE_GENERIC) { - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; o->oBobombBuddyHasTalkedToMario = BOBOMB_BUDDY_HAS_TALKED; diff --git a/src/game/behaviors/boo.inc.c b/src/game/behaviors/boo.inc.c index 32c01894..24a11420 100644 --- a/src/game/behaviors/boo.inc.c +++ b/src/game/behaviors/boo.inc.c @@ -197,8 +197,8 @@ static void boo_move_during_hit(s32 roll, f32 fVel) { o->oMoveAngleYaw = o->oBooMoveYawDuringHit; if (roll != FALSE) { - o->oFaceAngleYaw += D_8032F0CC[o->oTimer]; - o->oFaceAngleRoll += D_8032F0CC[o->oTimer]; + o->oFaceAngleYaw += sBooHitRotations[o->oTimer]; + o->oFaceAngleRoll += sBooHitRotations[o->oTimer]; } } @@ -223,7 +223,7 @@ static s32 boo_update_after_bounced_on(f32 a0) { } if (o->oTimer < 32) { - boo_move_during_hit(FALSE, D_8032F0CC[o->oTimer]/5000.0f * a0); + boo_move_during_hit(FALSE, sBooHitRotations[o->oTimer]/5000.0f * a0); } else { cur_obj_become_tangible(); boo_reset_after_hit(); @@ -243,7 +243,7 @@ static s32 big_boo_update_during_nonlethal_hit(f32 a0) { } if (o->oTimer < 32) { - boo_move_during_hit(TRUE, D_8032F0CC[o->oTimer]/5000.0f * a0); + boo_move_during_hit(TRUE, sBooHitRotations[o->oTimer]/5000.0f * a0); } else if (o->oTimer < 48) { big_boo_shake_after_hit(); } else { @@ -464,7 +464,7 @@ static void boo_act_4(void) { dialogID = DIALOG_107; } - if (cur_obj_update_dialog(2, 2, dialogID, 0)) { + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_TEXT_DEFAULT, dialogID, 0)) { create_sound_spawner(SOUND_OBJ_DYING_ENEMY1); obj_mark_for_deletion(o); @@ -644,9 +644,9 @@ static void big_boo_act_4(void) { if (o->oTimer > 60 && o->oDistanceToMario < 600.0f) { obj_set_pos(o, 973, 0, 717); - spawn_object_relative(0, 0, 0, 0, o, MODEL_BBH_STAIRCASE_STEP, bhvBooBossSpawnedBridge); - spawn_object_relative(1, 0, 0, -200, o, MODEL_BBH_STAIRCASE_STEP, bhvBooBossSpawnedBridge); - spawn_object_relative(2, 0, 0, 200, o, MODEL_BBH_STAIRCASE_STEP, bhvBooBossSpawnedBridge); + spawn_object_relative(0, 0, 0, 0, o, MODEL_BBH_STAIRCASE_STEP, bhvBooStaircase); + spawn_object_relative(1, 0, 0, -200, o, MODEL_BBH_STAIRCASE_STEP, bhvBooStaircase); + spawn_object_relative(2, 0, 0, 200, o, MODEL_BBH_STAIRCASE_STEP, bhvBooStaircase); obj_mark_for_deletion(o); } @@ -863,7 +863,7 @@ void bhv_boo_in_castle_loop(void) { cur_obj_move_using_fvel_and_gravity(); } -void bhv_boo_boss_spawned_bridge_loop(void) { +void bhv_boo_staircase(void) { f32 targetY; switch (o->oBehParams2ndByte) { @@ -898,7 +898,7 @@ void bhv_boo_boss_spawned_bridge_loop(void) { cur_obj_play_sound_2(SOUND_GENERAL_UNKNOWN4_LOWPRIO); } - if (cur_obj_move_up_and_down(o->oTimer)) { + if (jiggle_bbh_stair(o->oTimer)) { o->oAction++; } diff --git a/src/game/behaviors/bowling_ball.inc.c b/src/game/behaviors/bowling_ball.inc.c index f1e16cb1..0b9a139b 100644 --- a/src/game/behaviors/bowling_ball.inc.c +++ b/src/game/behaviors/bowling_ball.inc.c @@ -79,6 +79,9 @@ void bowling_ball_set_waypoints(void) { void bhv_bowling_ball_roll_loop(void) { s16 collisionFlags; s32 sp18; +#ifdef AVOID_UB + sp18 = 0; +#endif bowling_ball_set_waypoints(); collisionFlags = object_step(); @@ -109,6 +112,9 @@ void bhv_bowling_ball_roll_loop(void) { void bhv_bowling_ball_initializeLoop(void) { s32 sp1c; +#ifdef AVOID_UB + sp1c = 0; +#endif bowling_ball_set_waypoints(); diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index 97cba2af..4c29cce6 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -1,114 +1,177 @@ -// bowser.c.inc +/** + * Behavior for Bowser and it's actions (Tail, Flame, Body) + */ -void bowser_tail_anchor_act_0(void) { +// Bowser's Tail + +/** + * Checks whenever the Bowser and his tail should be intangible or not + * By default it starts tangible + */ +void bowser_tail_anchor_act_default(void) { struct Object *bowser = o->parentObj; cur_obj_become_tangible(); cur_obj_scale(1.0f); - if (bowser->oAction == 19) + + if (bowser->oAction == BOWSER_ACT_TILT_LAVA_PLATFORM) { + // Bowser cannot be touched when he tilts BITFS platform bowser->oIntangibleTimer = -1; - else if (obj_check_if_collided_with_object(o, gMarioObject)) { + } else if (obj_check_if_collided_with_object(o, gMarioObject)) { + // When Mario collides his tail, it now gets + // intangible so he can grab it through bowser->oIntangibleTimer = 0; - o->oAction = 2; - } else + o->oAction = BOWSER_ACT_TAIL_TOUCHED_MARIO; + } else { bowser->oIntangibleTimer = -1; + } } -void bowser_tail_anchor_act_1(void) { - if (o->oTimer > 30) - o->oAction = 0; +/** + * While Bowser get's thrown, wait 30 frames then + * return to the default tail action check + */ +void bowser_tail_anchor_thrown(void) { + if (o->oTimer > 30) { + o->oAction = BOWSER_ACT_TAIL_DEFAULT; + } } -void bowser_tail_anchor_act_2(void) { - if (o->parentObj->oAction == 19) { +/** + * Makes the tail intangible so Mario can grab it + */ +void bowser_tail_anchor_act_touched_mario(void) { + // Return to main action when Bowser tilts BITFS platform + if (o->parentObj->oAction == BOWSER_ACT_TILT_LAVA_PLATFORM) { o->parentObj->oIntangibleTimer = -1; - o->oAction = 0; + o->oAction = BOWSER_ACT_TAIL_DEFAULT; } cur_obj_become_intangible(); } -void (*sBowserTailAnchorActions[])(void) = { bowser_tail_anchor_act_0, bowser_tail_anchor_act_1, - bowser_tail_anchor_act_2 }; -s8 D_8032F4FC[] = { 7, 8, 9, 12, 13, 14, 15, 4, 3, 16, 17, 19, 3, 3, 3, 3 }; -s16 D_8032F50C[] = { 60, 0 }; -s16 D_8032F510[] = { 50, 0 }; -s8 D_8032F514[] = { 24, 42, 60, -1 }; -s16 sBowserDefeatedDialogText[3] = { DIALOG_119, DIALOG_120, DIALOG_121 }; -s16 D_8032F520[][3] = { { 1, 10, 40 }, { 0, 0, 74 }, { -1, -10, 114 }, { 1, -20, 134 }, - { -1, 20, 154 }, { 1, 40, 164 }, { -1, -40, 174 }, { 1, -80, 179 }, - { -1, 80, 184 }, { 1, 160, 186 }, { -1, -160, 186 }, { 1, 0, 0 }, }; +void (*sBowserTailAnchorActions[])(void) = { + bowser_tail_anchor_act_default, + bowser_tail_anchor_thrown, + bowser_tail_anchor_act_touched_mario, +}; +/** + * Bowser's tail main loop + */ void bhv_bowser_tail_anchor_loop(void) { + // Call its actions cur_obj_call_action_function(sBowserTailAnchorActions); + // Position the tail o->oParentRelativePosX = 90.0f; - if (o->parentObj->oAction == 4) + + // Make it intangible while Bowser is dead + if (o->parentObj->oAction == BOWSER_ACT_DEAD) { o->parentObj->oIntangibleTimer = -1; + } + o->oInteractStatus = 0; } +// Bowser's Flame + +/** + * Bowser's Flame spawn main loop + */ void bhv_bowser_flame_spawn_loop(void) { struct Object *bowser = o->parentObj; - s32 sp30; - f32 sp2C; - f32 sp28; - f32 sp24 = coss(bowser->oMoveAngleYaw); - f32 sp20 = sins(bowser->oMoveAngleYaw); - s16 *sp1C = segmented_to_virtual(bowser_seg6_unkmoveshorts_060576FC); - if (bowser->oSoundStateID == 6) { - sp30 = bowser->header.gfx.animInfo.animFrame + 1.0f; - if (bowser->header.gfx.animInfo.curAnim->loopEnd == sp30) - sp30 = 0; - if (sp30 > 45 && sp30 < 85) { + s32 animFrame; + f32 posX; + f32 posZ; + f32 cossYaw = coss(bowser->oMoveAngleYaw); + f32 sinsYaw = sins(bowser->oMoveAngleYaw); + s16 *data = segmented_to_virtual(dBowserFlamesOrientationValues); + + // Check for Bowser breathing animation + if (bowser->oSoundStateID == BOWSER_ANIM_BREATH) { + + // Start counting anim frames then reset it when it ends + animFrame = bowser->header.gfx.animInfo.animFrame + 1.0f; + if (bowser->header.gfx.animInfo.curAnim->loopEnd == animFrame) { + animFrame = 0; + } + + // Bowser is breathing, play sound and adjust flame position + // each animFrame based off the orientantion data + if (animFrame > 45 && animFrame < 85) { cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE); - sp2C = sp1C[5 * sp30]; - sp28 = sp1C[5 * sp30 + 2]; - o->oPosX = bowser->oPosX + (sp28 * sp20 + sp2C * sp24); - o->oPosY = bowser->oPosY + sp1C[5 * sp30 + 1]; - o->oPosZ = bowser->oPosZ + (sp28 * sp24 - sp2C * sp20); - o->oMoveAnglePitch = sp1C[5 * sp30 + 4] + 0xC00; - o->oMoveAngleYaw = sp1C[5 * sp30 + 3] + (s16) bowser->oMoveAngleYaw; - if (!(sp30 & 1)) + posX = data[5 * animFrame]; + posZ = data[5 * animFrame + 2]; + o->oPosX = bowser->oPosX + (posZ * sinsYaw + posX * cossYaw); + o->oPosY = bowser->oPosY + data[5 * animFrame + 1]; + o->oPosZ = bowser->oPosZ + (posZ * cossYaw - posX * sinsYaw); + o->oMoveAnglePitch = data[5 * animFrame + 4] + 0xC00; + o->oMoveAngleYaw = data[5 * animFrame + 3] + (s16) bowser->oMoveAngleYaw; + // Spawns the flames on a non-odd animFrame value + if (!(animFrame & 1)) { spawn_object(o, MODEL_RED_FLAME, bhvFlameMovingForwardGrowing); + } } } } +/** + * Bowser's Body main loop + */ void bhv_bowser_body_anchor_loop(void) { + // Copy position and angles from Bowser itself obj_copy_pos_and_angle(o, o->parentObj); - if (o->parentObj->oAction == 4) { -#ifndef VERSION_JP - if (o->parentObj->oSubAction == 11) + // If Bowser is dead, set interaction type to text + // so that he can be ready to speak his dialog + if (o->parentObj->oAction == BOWSER_ACT_DEAD) { +#if BUGFIX_BOWSER_COLLIDE_BITS_DEAD + // Clear interaction type at the last sub action in BITS + // Fixes collision coliding after defeating him + if (o->parentObj->oSubAction == BOWSER_SUB_ACT_DEAD_FINAL_END_OVER) { o->oInteractType = 0; - else - o->oInteractType = 0x800000; + } else { + o->oInteractType = INTERACT_TEXT; + } #else - o->oInteractType = 0x800000; + o->oInteractType = INTERACT_TEXT; #endif } else { - o->oInteractType = 8; - if (o->parentObj->oOpacity < 100) + // Do damage if Mario touches Bowser + o->oInteractType = INTERACT_DAMAGE; + // Make body intangible while is transparent + // in BITFS (Teleporting) + if (o->parentObj->oOpacity < 100) { cur_obj_become_intangible(); - else + } else { cur_obj_become_tangible(); + } } - if (o->parentObj->oHeldState != HELD_FREE) + // Make body intangible while Bowser is getting grabbed + if (o->parentObj->oHeldState != HELD_FREE) { cur_obj_become_intangible(); + } o->oInteractStatus = 0; } +/** + * Bowser's shockwave attack, spawns only in BITS + */ s32 bowser_spawn_shockwave(void) { struct Object *wave; - if (o->oBehParams2ndByte == 2) { + if (o->oBehParams2ndByte == BOWSER_BP_BITS) { wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave); wave->oPosY = o->oFloorHeight; - return 1; + return TRUE; } - return 0; + return FALSE; } -void bowser_bounce(s32 *a) { +/** + * Misc effects that Bowser plays when he lands with drastic actions + * Plays step sound, spawns particles and changes camera event + */ +void bowser_bounce_effects(s32 *timer) { if (o->oMoveFlags & OBJ_MOVE_LANDED) { - a[0]++; - if (a[0] < 4) { + (*timer)++; + if (*timer < 4) { cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_THROW_BOUNCE); spawn_mist_particles_variable(0, 0, 60.0f); cur_obj_play_sound_2(SOUND_OBJ_BOWSER_WALK); @@ -116,175 +179,272 @@ void bowser_bounce(s32 *a) { } } -#define BITDW (o->oBehParams2ndByte == 0) -#define BITFS (o->oBehParams2ndByte == 1) -#define BITS (o->oBehParams2ndByte == 2) - +/** + * Makes Bowser look up and walk on an specific animation frame + * Returns TRUE if the animation is almost over + */ s32 bowser_set_anim_look_up_and_walk(void) { - cur_obj_init_animation_with_sound(15); - if (cur_obj_check_anim_frame(21)) + cur_obj_init_animation_with_sound(BOWSER_ANIM_LOOK_UP_START_WALK); + if (cur_obj_check_anim_frame(21)) { o->oForwardVel = 3.0f; - if (cur_obj_check_if_near_animation_end()) - return 1; - else - return 0; -} - -s32 bowser_set_anim_slow_gait(void) { - o->oForwardVel = 3.0f; - cur_obj_init_animation_with_sound(13); - if (cur_obj_check_if_near_animation_end()) - return 1; - else - return 0; -} - -s32 bowser_set_anim_look_down(void) { - cur_obj_init_animation_with_sound(14); - if (cur_obj_check_anim_frame(20)) - o->oForwardVel = 0.0f; - if (cur_obj_check_if_near_animation_end()) - return 1; - else - return 0; -} - -void bowser_initialize_action(void) { - if (o->oBowserUnk88 == 0) - o->oAction = 5; - else if (o->oBowserUnk88 == 1) - o->oAction = 6; - else if (o->oBehParams2ndByte == 1) - o->oAction = 13; - else - o->oAction = 0; -} - -void bowser_act_text_wait(void) // not much -{ - o->oForwardVel = 0.0f; - cur_obj_init_animation_with_sound(12); - bowser_initialize_action(); -} - -void bowser_act_intro_walk(void) { - if (o->oSubAction == 0) { - if (bowser_set_anim_look_up_and_walk()) - o->oSubAction++; - } else if (o->oSubAction == 1) { - if (bowser_set_anim_slow_gait()) - o->oSubAction++; - } else if (bowser_set_anim_look_down()) { - if (o->oBowserUnk88 == 1) - o->oBowserUnk88 = 0; - bowser_initialize_action(); + } + if (cur_obj_check_if_near_animation_end()) { + return TRUE; + } else { + return FALSE; } } -static void bowser_debug_actions(void) // unused -{ +/** + * Makes Bowser do a slow gait (or slow walk) + * Returns TRUE if the animation is almost over + */ +s32 bowser_set_anim_slow_gait(void) { + o->oForwardVel = 3.0f; + cur_obj_init_animation_with_sound(BOWSER_ANIM_SLOW_GAIT); + if (cur_obj_check_if_near_animation_end()) { + return TRUE; + } else { + return FALSE; + } +} + +/** + * Makes Bowser look down and stop on an specific animation frame + * Returns TRUE if the animation is almost over + */ +s32 bowser_set_anim_look_down_stop_walk(void) { + cur_obj_init_animation_with_sound(BOWSER_ANIM_LOOK_DOWN_STOP_WALK); + if (cur_obj_check_anim_frame(20)) { + o->oForwardVel = 0.0f; + } + if (cur_obj_check_if_near_animation_end()) { + return TRUE; + } else { + return FALSE; + } +} + + +/** + * Set Bowser an action depending of the CamAct value + * CamAct changes value on the cutscene itself (cutscene_bowser_arena) + */ +void bowser_init_camera_actions(void) { + if (o->oBowserCamAct == BOWSER_CAM_ACT_IDLE) { + o->oAction = BOWSER_ACT_WAIT; + } else if (o->oBowserCamAct == BOWSER_CAM_ACT_WALK) { + o->oAction = BOWSER_ACT_INTRO_WALK; + // Start with a big jump in BITFS to do a platform tilt + } else if (o->oBehParams2ndByte == BOWSER_BP_BITFS) { + o->oAction = BOWSER_ACT_BIG_JUMP; + } else { + o->oAction = BOWSER_ACT_DEFAULT; + } +} + +/** + * Bowser's idle action that plays when he is initialized + * or the CamAct gets in idle mode + */ +void bowser_act_wait(void) { + o->oForwardVel = 0.0f; + cur_obj_init_animation_with_sound(BOWSER_ANIM_IDLE); + bowser_init_camera_actions(); +} + +/** + * Bowser's cutscene walk that last a few seconds to introduce itself + * Do subactions until the animation ends, then go to next subaction + */ +void bowser_act_intro_walk(void) { + // First look up and walk + if (o->oSubAction == 0) { + if (bowser_set_anim_look_up_and_walk()) { + o->oSubAction++; + } + // Then slowly walk + } else if (o->oSubAction == 1) { + if (bowser_set_anim_slow_gait()) { + o->oSubAction++; + } + // And finally stop, and set to wait mode + } else if (bowser_set_anim_look_down_stop_walk()) { + if (o->oBowserCamAct == BOWSER_CAM_ACT_WALK) { + o->oBowserCamAct = BOWSER_CAM_ACT_IDLE; + } + bowser_init_camera_actions(); + } +} + +/** + * List of actions to debug Bowser + */ +s8 sBowserDebugActions[] = { + BOWSER_ACT_CHARGE_MARIO, + BOWSER_ACT_SPIT_FIRE_INTO_SKY, + BOWSER_ACT_SPIT_FIRE_ONTO_FLOOR, + BOWSER_ACT_HIT_MINE, + BOWSER_ACT_BIG_JUMP, + BOWSER_ACT_WALK_TO_MARIO, + BOWSER_ACT_BREATH_FIRE, + BOWSER_ACT_DEAD, + BOWSER_ACT_DANCE, + BOWSER_ACT_TELEPORT, + BOWSER_ACT_QUICK_JUMP, + BOWSER_ACT_TILT_LAVA_PLATFORM, + BOWSER_ACT_DANCE, + BOWSER_ACT_DANCE, + BOWSER_ACT_DANCE, + BOWSER_ACT_DANCE, +}; + +/** + * Debug function that allows to change Bowser's actions (most of them) + */ +UNUSED static void bowser_debug_actions(void) { if (gDebugInfo[5][1] != 0) { - o->oAction = D_8032F4FC[gDebugInfo[5][2] & 0xf]; + o->oAction = sBowserDebugActions[gDebugInfo[5][2] & 0xf]; gDebugInfo[5][1] = 0; } } -void bowser_bitdw_act_controller(void) { +/** + * Set actions (and attacks) for Bowser in "Bowser in the Dark World" + */ +void bowser_bitdw_actions(void) { + // Generate random float f32 rand = random_float(); - if (o->oBowserUnk110 == 0) { - if (o->oBowserUnkF4 & 2) { - if (o->oDistanceToMario < 1500.0f) - o->oAction = 15; // nearby - else - o->oAction = 17; // far away - } else - o->oAction = 14; - o->oBowserUnk110++; - } else { - o->oBowserUnk110 = 0; -#ifndef VERSION_JP - if (!gCurrDemoInput) { - if (rand < 0.1) - o->oAction = 3; // rare 1/10 chance - else - o->oAction = 14; // common + // Set attacks when Bowser Reacts + if (o->oBowserIsReacting == FALSE) { + if (o->oBowserStatus & BOWSER_STATUS_ANGLE_MARIO) { + if (o->oDistanceToMario < 1500.0f) { + o->oAction = BOWSER_ACT_BREATH_FIRE; // nearby + } else { + o->oAction = BOWSER_ACT_QUICK_JUMP; // far away + } } else { - o->oAction = 14; // ensure demo starts with action 14. + // Keep walking + o->oAction = BOWSER_ACT_WALK_TO_MARIO; + } + o->oBowserIsReacting++; + } else { + o->oBowserIsReacting = FALSE; + // Set starting Bowser level actions, randomly he can also start + // dancing after the introduction +#ifndef VERSION_JP + if (!gCurrDemoInput) { // demo check because entry exits post JP + if (rand < 0.1) { + o->oAction = BOWSER_ACT_DANCE; // 10% chance + } else { + o->oAction = BOWSER_ACT_WALK_TO_MARIO; // common + } + } else { + o->oAction = BOWSER_ACT_WALK_TO_MARIO; } #else - if (rand < 0.1) - o->oAction = 3; // rare 1/10 chance - else - o->oAction = 14; // common + if (rand < 0.1) { + o->oAction = BOWSER_ACT_DANCE; // 10% chance + } else { + o->oAction = BOWSER_ACT_WALK_TO_MARIO; // common + } #endif } } -void bowser_bitfs_act_controller(void) { +/** + * Set actions (and attacks) for Bowser in "Bowser in the Fire Sea" + */ +void bowser_bitfs_actions(void) { + // Generate random float f32 rand = random_float(); - if (o->oBowserUnk110 == 0) { - if (o->oBowserUnkF4 & 2) { - if (o->oDistanceToMario < 1300.0f) // nearby - { - if (rand < 0.5) // 50/50 - o->oAction = 16; - else - o->oAction = 9; - } else // far away - { - o->oAction = 7; + // Set attacks when Bowser Reacts + if (o->oBowserIsReacting == FALSE) { + if (o->oBowserStatus & BOWSER_STATUS_ANGLE_MARIO) { + if (o->oDistanceToMario < 1300.0f) { // nearby + if (rand < 0.5) { // 50% chance + o->oAction = BOWSER_ACT_TELEPORT; + } else { + o->oAction = BOWSER_ACT_SPIT_FIRE_ONTO_FLOOR; + } + } else { // far away + o->oAction = BOWSER_ACT_CHARGE_MARIO; if (500.0f < o->oBowserDistToCentre && o->oBowserDistToCentre < 1500.0f - && rand < 0.5) // away from centre and good luck - o->oAction = 13; + && rand < 0.5) { // 50% chance + o->oAction = BOWSER_ACT_BIG_JUMP; + } } - } else - o->oAction = 14; - o->oBowserUnk110++; + } else { + // Keep walking + o->oAction = BOWSER_ACT_WALK_TO_MARIO; + } + o->oBowserIsReacting++; } else { - o->oBowserUnk110 = 0; - o->oAction = 14; + // Keep walking + o->oBowserIsReacting = FALSE; + o->oAction = BOWSER_ACT_WALK_TO_MARIO; } } -void bowser_general_bits_act_controller(void) { +/** + * List of actions (and attacks) for "Bowser in the Sky" + */ +void bowser_bits_action_list(void) { f32 rand = random_float(); - if (o->oBowserUnkF4 & 2) { - if (o->oDistanceToMario < 1000.0f) { - if (rand < 0.4) - o->oAction = 9; - else if (rand < 0.8) - o->oAction = 8; - else - o->oAction = 15; - } else if (rand < 0.5) - o->oAction = 13; - else - o->oAction = 7; - } else - o->oAction = 14; + if (o->oBowserStatus & BOWSER_STATUS_ANGLE_MARIO) { + if (o->oDistanceToMario < 1000.0f) { // nearby + if (rand < 0.4) { + o->oAction = BOWSER_ACT_SPIT_FIRE_ONTO_FLOOR; // 40% chance + } else if (rand < 0.8) { + o->oAction = BOWSER_ACT_SPIT_FIRE_INTO_SKY; // 80% chance + } else { + o->oAction = BOWSER_ACT_BREATH_FIRE; + } // far away + } else if (rand < 0.5) { + o->oAction = BOWSER_ACT_BIG_JUMP; // 50% chance + } else { + o->oAction = BOWSER_ACT_CHARGE_MARIO; + } + } else { + // Keep walking + o->oAction = BOWSER_ACT_WALK_TO_MARIO; + } } -void bowser_set_act_jump(void) { - o->oAction = 13; +/** + * Sets big jump action, not much to say + * Never gets called since oBowserBitsJustJump is always FALSE + */ +void bowser_set_act_big_jump(void) { + o->oAction = BOWSER_ACT_BIG_JUMP; } -void bowser_bits_act_controller(void) { - switch (o->oBowserUnk110) { - case 0: - if (o->oBowserUnk106 == 0) - bowser_general_bits_act_controller(); - else - bowser_set_act_jump(); - o->oBowserUnk110 = 1; +/** + * Set actions (and attacks) for Bowser in "Bowser in the Sky" + */ +void bowser_bits_actions(void) { + switch (o->oBowserIsReacting) { + case FALSE: + // oBowserBitsJustJump never changes value, + // so its always FALSE, maybe a debug define + if (o->oBowserBitsJustJump == FALSE) { + bowser_bits_action_list(); + } else { + bowser_set_act_big_jump(); + } + o->oBowserIsReacting = TRUE; break; - case 1: - o->oBowserUnk110 = 0; - o->oAction = 14; + case TRUE: + o->oBowserIsReacting = FALSE; + o->oAction = BOWSER_ACT_WALK_TO_MARIO; break; } } -#ifndef VERSION_JP +/** + * Reset Bowser position and speed if he wasn't able to land properly on stage + */ +#if BUGFIX_BOWSER_FALLEN_OFF_STAGE void bowser_reset_fallen_off_stage(void) { if (o->oVelY < 0 && o->oPosY < (o->oHomeY - 300.0f)) { o->oPosX = o->oPosZ = 0; @@ -295,378 +455,562 @@ void bowser_reset_fallen_off_stage(void) { } #endif -void bowser_act_unused_slow_walk(void) // unused? -{ - if (cur_obj_init_animation_and_check_if_near_end(12)) - o->oAction = 0; +/** + * Unused, makes Bowser be in idle and after it returns to default action + */ +void bowser_act_idle(void) { + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_IDLE)) { + o->oAction = BOWSER_ACT_DEFAULT; + } } -void bowser_act_default(void) // only lasts one frame -{ - o->oBowserEyesShut = 0; - cur_obj_init_animation_with_sound(12); - // stop him still +/** + * Default Bowser act that doesn't last very long + */ +void bowser_act_default(void) { + // Set eye state + o->oBowserEyesShut = FALSE; + // Set idle animation + cur_obj_init_animation_with_sound(BOWSER_ANIM_IDLE); + // Stop him still o->oAngleVelYaw = 0; o->oForwardVel = 0.0f; o->oVelY = 0.0f; - if (BITDW) - bowser_bitdw_act_controller(); - else if (BITFS) - bowser_bitfs_act_controller(); - else - bowser_bits_act_controller(); - // Action 14 commonly follows + // Set level specific actions + if (o->oBehParams2ndByte == BOWSER_BP_BITDW) { + bowser_bitdw_actions(); + } else if (o->oBehParams2ndByte == BOWSER_BP_BITFS) { + bowser_bitfs_actions(); + } else { // BOWSER_BP_BITS + bowser_bits_actions(); + } } +/** + * Makes Bowser play breath animation and sound effect + * The actual breath attack is in bhv_bowser_flame_spawn_loop + * called as a child obj behavior in Bowser + */ void bowser_act_breath_fire(void) { o->oForwardVel = 0.0f; - if (o->oTimer == 0) + if (o->oTimer == 0) { cur_obj_play_sound_2(SOUND_OBJ_BOWSER_INHALING); - if (cur_obj_init_animation_and_check_if_near_end(6)) - o->oAction = 0; + } + // Init animation and return to default act after it ends + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_BREATH)) { + o->oAction = BOWSER_ACT_DEFAULT; + } } -void bowser_act_walk_to_mario(void) // turn towards Mario -{ +/** + * Makes Bowser walk towards Mario + */ +void bowser_act_walk_to_mario(void) { UNUSED s32 facing; // is Bowser facing Mario? s16 turnSpeed; s16 angleFromMario = abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario); - if (BITFS) + + // Set turning speed depending of the health + // Also special case for BITFS + if (o->oBehParams2ndByte == BOWSER_BP_BITFS) { turnSpeed = 0x400; - else if (o->oHealth > 2) + } else if (o->oHealth > 2) { turnSpeed = 0x400; - else if (o->oHealth == 2) + } else if (o->oHealth == 2) { turnSpeed = 0x300; - else + } else { // 1 health (BITFS-BITS) turnSpeed = 0x200; + } facing = cur_obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed); if (o->oSubAction == 0) { - o->oBowserUnkF8 = 0; - if (bowser_set_anim_look_up_and_walk()) + o->oBowserTimer = 0; + // Start walking + if (bowser_set_anim_look_up_and_walk()) { o->oSubAction++; - } else if (o->oSubAction == 1) { - if (bowser_set_anim_slow_gait()) { - o->oBowserUnkF8++; - if (o->oBowserUnkF4 & 0x20000) { - if (o->oBowserUnkF8 > 4) - o->oBowserUnkF4 &= ~0x20000; - } else if (angleFromMario < 0x2000) - o->oSubAction++; } - } else if (bowser_set_anim_look_down()) - o->oAction = 0; + } else if (o->oSubAction == 1) { + // Keep walking slowly + if (bowser_set_anim_slow_gait()) { + o->oBowserTimer++; + // Reset fire sky status + if (o->oBowserStatus & BOWSER_STATUS_FIRE_SKY) { + if (o->oBowserTimer > 4) { + o->oBowserStatus &= ~BOWSER_STATUS_FIRE_SKY; + } + // Do subaction below if angles is less than 0x2000 + } else if (angleFromMario < 0x2000) { + o->oSubAction++; + } + } + // Stop walking and set to default action + } else if (bowser_set_anim_look_down_stop_walk()) { + o->oAction = BOWSER_ACT_DEFAULT; + } } +/** + * Makes Bowser teleport while invisible + */ void bowser_act_teleport(void) { switch (o->oSubAction) { - case 0: + // Set opacity target to invisible and become intangible + case BOWSER_SUB_ACT_TELEPORT_START: cur_obj_become_intangible(); - o->oBowserUnk1AC = 0; - o->oBowserUnkF8 = 30; - if (o->oTimer == 0) + o->oBowserTargetOpacity = 0; + o->oBowserTimer = 30; // set timer value + // Play sound effect + if (o->oTimer == 0) { cur_obj_play_sound_2(SOUND_OBJ2_BOWSER_TELEPORT); + } + // Bowser is invisible, move angle to face Mario if (o->oOpacity == 0) { o->oSubAction++; o->oMoveAngleYaw = o->oAngleToMario; } break; - case 1: - if (o->oBowserUnkF8--) + case BOWSER_SUB_ACT_TELEPORT_MOVE: + // reduce timer and set velocity teleport while at it + if (o->oBowserTimer--) { o->oForwardVel = 100.0f; - else { - o->oSubAction = 2; - o->oMoveAngleYaw = o->oAngleToMario; } - if (abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario) > 0x4000) + else { + o->oSubAction = BOWSER_SUB_ACT_TELEPORT_STOP; + o->oMoveAngleYaw = o->oAngleToMario; // update angle + } + // + if (abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario) > 0x4000) { if (o->oDistanceToMario > 500.0f) { - o->oSubAction = 2; - o->oMoveAngleYaw = o->oAngleToMario; // large change in angle? + o->oSubAction = BOWSER_SUB_ACT_TELEPORT_STOP; + o->oMoveAngleYaw = o->oAngleToMario; // update angle cur_obj_play_sound_2(SOUND_OBJ2_BOWSER_TELEPORT); } + } break; - case 2: - o->oForwardVel = 0.0f; - o->oBowserUnk1AC = 0xFF; - if (o->oOpacity == 0xFF) - o->oAction = 0; + // Set opacity target to visible and become tangible + case BOWSER_SUB_ACT_TELEPORT_STOP: + o->oForwardVel = 0.0f; // reset velocity + o->oBowserTargetOpacity = 0xFF; + // Set to default action once visible + if (o->oOpacity == 0xFF) { + o->oAction = BOWSER_ACT_DEFAULT; + } cur_obj_become_tangible(); break; } } -void bowser_act_spit_fire_into_sky(void) // only in sky -{ +/** + * Makes Bowser do a fire split into the sky + */ +void bowser_act_spit_fire_into_sky(void) { s32 frame; - cur_obj_init_animation_with_sound(11); + // Play animation + cur_obj_init_animation_with_sound(BOWSER_ANIM_BREATH_UP); + // Set frames frame = o->header.gfx.animInfo.animFrame; + // Spawn flames in the middle of the animation if (frame > 24 && frame < 36) { cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE); - if (frame == 35) + if (frame == 35) { // Spawns Blue flames at this frame spawn_object_relative(1, 0, 0x190, 0x64, o, MODEL_RED_FLAME, bhvBlueBowserFlame); - else + } else { // Spawns Red flames spawn_object_relative(0, 0, 0x190, 0x64, o, MODEL_RED_FLAME, bhvBlueBowserFlame); + } } - if (cur_obj_check_if_near_animation_end()) - o->oAction = 0; - o->oBowserUnkF4 |= 0x20000; + // Return to default act once the animation is over + if (cur_obj_check_if_near_animation_end()) { + o->oAction = BOWSER_ACT_DEFAULT; + } + // Set fire sky status + o->oBowserStatus |= BOWSER_STATUS_FIRE_SKY; } +/** + * Flips Bowser back on stage if he hits a mine with more than 1 health + */ void bowser_act_hit_mine(void) { + // Similar vel values from bowser_fly_back_dead if (o->oTimer == 0) { o->oForwardVel = -400.0f; o->oVelY = 100.0f; o->oMoveAngleYaw = o->oBowserAngleToCentre + 0x8000; - o->oBowserEyesShut = 1; + o->oBowserEyesShut = TRUE; // close eyes } - if (o->oSubAction == 0) { - cur_obj_init_animation_with_sound(25); + // Play flip animation + if (o->oSubAction == BOWSER_SUB_ACT_HIT_MINE_START) { + cur_obj_init_animation_with_sound(BOWSER_ANIM_FLIP); o->oSubAction++; - o->oBowserUnkF8 = 0; - } else if (o->oSubAction == 1) { - cur_obj_init_animation_with_sound(25); + o->oBowserTimer = 0; + // Play flip animation again, extend it and play bounce effects + } else if (o->oSubAction == BOWSER_SUB_ACT_HIT_MINE_FALL) { + cur_obj_init_animation_with_sound(BOWSER_ANIM_FLIP); cur_obj_extend_animation_if_at_end(); - bowser_bounce(&o->oBowserUnkF8); - if ((o->oBowserUnkF8 > 2)) { - cur_obj_init_animation_with_sound(26); + bowser_bounce_effects(&o->oBowserTimer); + // Reset vel and stand up + if (o->oBowserTimer > 2) { + cur_obj_init_animation_with_sound(BOWSER_ANIM_STAND_UP_FROM_FLIP); o->oVelY = 0.0f; o->oForwardVel = 0.0f; o->oSubAction++; } - } else if (o->oSubAction == 2) { + // Play these actions once he is stand up + } else if (o->oSubAction == BOWSER_SUB_ACT_HIT_MINE_STOP) { if (cur_obj_check_if_near_animation_end()) { - if (o->oHealth == 1) - o->oAction = 3; - else - o->oAction = 0; - o->oBowserEyesShut = 0; + // Makes Bowser dance at one health (in BITS) + if (o->oHealth == 1) { + o->oAction = BOWSER_ACT_DANCE; + } else { + o->oAction = BOWSER_ACT_DEFAULT; + } + o->oBowserEyesShut = FALSE; // open eyes } } else { } } -s32 bowser_set_anim_in_air(void) { - cur_obj_init_animation_with_sound(9); - if (cur_obj_check_anim_frame(11)) - return 1; - else - return 0; +/** + * Makes Bowser do his jump start animation + * Returns TRUE on the middle of the jump + */ +s32 bowser_set_anim_jump(void) { + cur_obj_init_animation_with_sound(BOWSER_ANIM_JUMP_START); + if (cur_obj_check_anim_frame(11)) { + return TRUE; + } else { + return FALSE; + } } +/** + * Reset speed, play jump stop animation and do attacks in BITDW + * Returns TRUE when Bowser lands + */ s32 bowser_land(void) { if (o->oMoveFlags & OBJ_MOVE_LANDED) { o->oForwardVel = 0; o->oVelY = 0; spawn_mist_particles_variable(0, 0, 60.0f); - cur_obj_init_animation_with_sound(8); + cur_obj_init_animation_with_sound(BOWSER_ANIM_JUMP_STOP); o->header.gfx.animInfo.animFrame = 0; cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_JUMP); - if (BITDW) { - if (o->oDistanceToMario < 850.0f) - gMarioObject->oInteractStatus |= INT_STATUS_MARIO_UNK1; - else - gMarioObject->oInteractStatus |= INT_STATUS_HOOT_GRABBED_BY_MARIO; // hmm... + // Set status attacks in BITDW since the other levels + // have different attacks defined + if (o->oBehParams2ndByte == BOWSER_BP_BITDW) { + if (o->oDistanceToMario < 850.0f) { + gMarioObject->oInteractStatus |= INT_STATUS_MARIO_KNOCKBACK_DMG; + } else { + gMarioObject->oInteractStatus |= INT_STATUS_MARIO_STUNNED; + } } - return 1; - } else - return 0; + return TRUE; + } else { + return FALSE; + } } +/** + * Makes Bowser do a second hop speed only in BITS + */ void bowser_short_second_hop(void) { - if (BITS && o->oBowserUnkF4 & 0x10000) - if (o->oBowserDistToCentre > 1000.0f) + if (o->oBehParams2ndByte == BOWSER_BP_BITS && o->oBowserStatus & BOWSER_STATUS_BIG_JUMP) { + if (o->oBowserDistToCentre > 1000.0f) { o->oForwardVel = 60.0f; + } + } } -void bowser_act_jump(void) { +/** + * Makes Bowser do a big jump + */ +void bowser_act_big_jump(void) { UNUSED s32 unused; if (o->oSubAction == 0) { - if (bowser_set_anim_in_air()) { - if (BITS && o->oBowserUnkF4 & 0x10000) + // Set jump animation + if (bowser_set_anim_jump()) { + // Set vel depending of the stage and status + if (o->oBehParams2ndByte == BOWSER_BP_BITS && o->oBowserStatus & BOWSER_STATUS_BIG_JUMP) { o->oVelY = 70.0f; - else + } else { o->oVelY = 80.0f; - o->oBowserUnkF8 = 0; + } + o->oBowserTimer = 0; bowser_short_second_hop(); o->oSubAction++; } } else if (o->oSubAction == 1) { -#ifndef VERSION_JP - if (o->oBehParams2ndByte == 2 && o->oBowserUnkF4 & 0x10000) +#if BUGFIX_BOWSER_FALLEN_OFF_STAGE + // Reset Bowser back on stage in BITS if he doesn't land properly + if (o->oBehParams2ndByte == BOWSER_BP_BITS && o->oBowserStatus & BOWSER_STATUS_BIG_JUMP) { bowser_reset_fallen_off_stage(); + } #endif + // Land on stage, reset status jump and velocity if (bowser_land()) { - o->oBowserUnkF4 &= ~0x10000; + o->oBowserStatus &= ~BOWSER_STATUS_BIG_JUMP; o->oForwardVel = 0.0f; o->oSubAction++; + // Spawn shockwave (BITS only) if is not on a platform bowser_spawn_shockwave(); - if (BITFS) - o->oAction = 19; + // Tilt platform in BITFS + if (o->oBehParams2ndByte == BOWSER_BP_BITFS) { + o->oAction = BOWSER_ACT_TILT_LAVA_PLATFORM; + } } else { } - } else if (cur_obj_check_if_near_animation_end()) - o->oAction = 0; + // Set to default action when the animation is over + } else if (cur_obj_check_if_near_animation_end()) { + o->oAction = BOWSER_ACT_DEFAULT; + } } -void bowser_act_jump_towards_mario(void) { - f32 sp1C = D_8032F50C[0]; - f32 sp18 = D_8032F510[0]; +/** + * Fixed values for the quick jump action + */ +s16 sBowserVelYAir[] = { 60 }; +s16 sBowserFVelAir[] = { 50 }; + +/** + * Makes Bowser do a "quick" jump in BITDW + */ +void bowser_act_quick_jump(void) { + f32 velY = sBowserVelYAir[0]; + f32 fVel = sBowserFVelAir[0]; if (o->oSubAction == 0) { - if (bowser_set_anim_in_air()) { - o->oVelY = sp1C; - o->oForwardVel = sp18; - o->oBowserUnkF8 = 0; + // Set fixed val positions while jumping + if (bowser_set_anim_jump()) { + o->oVelY = velY; + o->oForwardVel = fVel; + o->oBowserTimer = 0; o->oSubAction++; } + // Lands then quickly returns to default action } else if (o->oSubAction == 1) { - if (bowser_land()) + if (bowser_land()) { o->oSubAction++; - } else if (cur_obj_check_if_near_animation_end()) - o->oAction = 0; + } + } else if (cur_obj_check_if_near_animation_end()) { + o->oAction = BOWSER_ACT_DEFAULT; + } } +/** + * Makes Bowser moving around if he is on an edge floor + */ void bowser_act_hit_edge(void) { + // Reset speed and timer o->oForwardVel = 0.0f; - if (o->oTimer == 0) - o->oBowserUnkF8 = 0; + if (o->oTimer == 0) { + o->oBowserTimer = 0; + } switch (o->oSubAction) { case 0: - cur_obj_init_animation_with_sound(23); - if (cur_obj_check_if_near_animation_end()) - o->oBowserUnkF8++; - if (o->oBowserUnkF8 > 0) + // Move on the edge + cur_obj_init_animation_with_sound(BOWSER_ANIM_EDGE_MOVE); + if (cur_obj_check_if_near_animation_end()) { + o->oBowserTimer++; + } + if (o->oBowserTimer > 0) { o->oSubAction++; + } break; case 1: - cur_obj_init_animation_with_sound(24); - if (cur_obj_check_if_near_animation_end()) - o->oAction = 11; + // Stop moving on the edge + cur_obj_init_animation_with_sound(BOWSER_ANIM_EDGE_STOP); + // Turn around once the animation ends + if (cur_obj_check_if_near_animation_end()) { + o->oAction = BOWSER_ACT_TURN_FROM_EDGE; + } break; } } +/** + * Makes Bowser do a fire split attack + */ void bowser_act_spit_fire_onto_floor(void) { - if (gHudDisplay.wedges < 4) - o->oBowserUnk108 = 3; - else - o->oBowserUnk108 = random_float() * 3.0f + 1.0f; - cur_obj_init_animation_with_sound(22); - if (cur_obj_check_anim_frame(5)) + // Set fixed rand value if Mario is low health + if (gHudDisplay.wedges < 4) { + o->oBowserRandSplitFloor = 3; + } else { + o->oBowserRandSplitFloor = random_float() * 3.0f + 1.0f; + } + + // Play animation and split fire at a specific frame + cur_obj_init_animation_with_sound(BOWSER_ANIM_BREATH_QUICK); + if (cur_obj_check_anim_frame(5)) { obj_spit_fire(0, 200, 180, 7.0f, MODEL_RED_FLAME, 30.0f, 10.0f, 0x1000); - if (cur_obj_check_if_near_animation_end()) + } + // Use subaction as a timer when the animation is over + if (cur_obj_check_if_near_animation_end()) { o->oSubAction++; - if (o->oSubAction >= o->oBowserUnk108) - o->oAction = 0; + } + // Return to default act once we get past rand value + if (o->oSubAction >= o->oBowserRandSplitFloor) { + o->oAction = BOWSER_ACT_DEFAULT; + } } -s32 bowser_turn_on_timer(s32 a0, s16 a1) { +/** + * Turns around Bowser from an specific yaw angle + * Returns TRUE once the timer is bigger than the time set + */ +s32 bowser_turn_on_timer(s32 time, s16 yaw) { if (o->oSubAction == 0) { - if (cur_obj_init_animation_and_check_if_near_end(15)) + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_LOOK_UP_START_WALK)) { o->oSubAction++; + } } else if (o->oSubAction == 1) { - if (cur_obj_init_animation_and_check_if_near_end(14)) + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_LOOK_DOWN_STOP_WALK)) { o->oSubAction++; - } else - cur_obj_init_animation_with_sound(12); + } + } else { + cur_obj_init_animation_with_sound(BOWSER_ANIM_IDLE); + } o->oForwardVel = 0.0f; - o->oMoveAngleYaw += a1; - if (o->oTimer >= a0) - return 1; - else - return 0; + o->oMoveAngleYaw += yaw; + if (o->oTimer >= time) { + return TRUE; + } else { + return FALSE; + } } +/** + * Makes Bowser turn around after hitting the edge + */ void bowser_act_turn_from_edge(void) { - if (bowser_turn_on_timer(63, 0x200)) - o->oAction = 0; + if (bowser_turn_on_timer(63, 0x200)) { + o->oAction = BOWSER_ACT_DEFAULT; + } } +/** + * Makes Bowser charge (run) to Mario + */ void bowser_act_charge_mario(void) { - s32 sp34; - if (o->oTimer == 0) + s32 time; + // Reset Speed to prepare charge + if (o->oTimer == 0) { o->oForwardVel = 0.0f; + } + switch (o->oSubAction) { - case 0: - o->oBowserUnkF8 = 0; - if (cur_obj_init_animation_and_check_if_near_end(18)) - o->oSubAction = 1; - break; - case 1: - o->oForwardVel = 50.0f; - if (cur_obj_init_animation_and_check_if_near_end(0x13) != 0) { - o->oBowserUnkF8++; - if (o->oBowserUnkF8 >= 6) - o->oSubAction = 3; - if (o->oBowserUnkF8 >= 2) - if (abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw) > 0x2000) - o->oSubAction = 3; + case BOWSER_SUB_ACT_CHARGE_START: + // Start running + o->oBowserTimer = 0; + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_RUN_START)) { + o->oSubAction = BOWSER_SUB_ACT_CHARGE_RUN; } + break; + case BOWSER_SUB_ACT_CHARGE_RUN: + // Set speed to run + o->oForwardVel = 50.0f; + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_RUN)) { + o->oBowserTimer++; + // Split if 6 timer frames has passed + if (o->oBowserTimer >= 6) { + o->oSubAction = BOWSER_SUB_ACT_CHARGE_SLIP; + } + // Slip if Mario has a differentiable angle and 2 timer frames has passed + if (o->oBowserTimer >= 2) { + if (abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw) > 0x2000) { + o->oSubAction = BOWSER_SUB_ACT_CHARGE_SLIP; + } + } + } + // Rotate to Mario cur_obj_rotate_yaw_toward(o->oAngleToMario, 0x200); break; - case 3: - o->oBowserUnkF8 = 0; - cur_obj_init_animation_with_sound(21); + case BOWSER_SUB_ACT_CHARGE_SLIP: + // Spawn smoke puff while slipping + o->oBowserTimer = 0; + cur_obj_init_animation_with_sound(BOWSER_ANIM_RUN_SLIP); spawn_object_relative_with_scale(0, 100, -50, 0, 3.0f, o, MODEL_SMOKE, bhvWhitePuffSmoke2); spawn_object_relative_with_scale(0, -100, -50, 0, 3.0f, o, MODEL_SMOKE, bhvWhitePuffSmoke2); - if (approach_f32_signed(&o->oForwardVel, 0, -1.0f)) - o->oSubAction = 2; + // End Charge once Bowser stops running + if (approach_f32_signed(&o->oForwardVel, 0, -1.0f)) { + o->oSubAction = BOWSER_SUB_ACT_CHARGE_END; + } cur_obj_extend_animation_if_at_end(); break; - case 2: + case BOWSER_SUB_ACT_CHARGE_END: + // Stop running o->oForwardVel = 0.0f; - cur_obj_init_animation_with_sound(20); + cur_obj_init_animation_with_sound(BOWSER_ANIM_RUN_STOP); if (cur_obj_check_if_near_animation_end()) { - if (BITS) - sp34 = 10; - else - sp34 = 30; - if (o->oBowserUnkF8 > sp34) - o->oAction = 0; - o->oBowserUnkF8++; + // Set time delay to go to default action + if (o->oBehParams2ndByte == BOWSER_BP_BITS) { + time = 10; + } else { + time = 30; + } + if (o->oBowserTimer > time) { + o->oAction = BOWSER_ACT_DEFAULT; + } + o->oBowserTimer++; } cur_obj_extend_animation_if_at_end(); break; } - if (o->oMoveFlags & OBJ_MOVE_HIT_EDGE) - o->oAction = 10; + // Bowser is close to falling so set hit edge action + if (o->oMoveFlags & OBJ_MOVE_HIT_EDGE) { + o->oAction = BOWSER_ACT_HIT_EDGE; + } } +/** + * Checks if Bowser hits a mine from a distance, returns TRUE if so + */ s32 bowser_check_hit_mine(void) { struct Object *mine; - f32 sp18; - mine = cur_obj_find_nearest_object_with_behavior(bhvBowserBomb, &sp18); - if (mine != NULL && sp18 < 800.0f) { + f32 dist; + + mine = cur_obj_find_nearest_object_with_behavior(bhvBowserBomb, &dist); + if (mine != NULL && dist < 800.0f) { mine->oInteractStatus |= INT_STATUS_HIT_MINE; - return 1; + return TRUE; } - return 0; + + return FALSE; } -void bowser_act_thrown_dropped(void) -{ +/** + * Bowser's thrown act that gets called after Mario releases him + */ +void bowser_act_thrown(void) { UNUSED s32 unused; + // Keep Bowser's timer at 0 unless he lands if (o->oTimer < 2) - o->oBowserUnkF8 = 0; + o->oBowserTimer = 0; if (o->oSubAction == 0) { - cur_obj_init_animation_with_sound(2); - bowser_bounce(&o->oBowserUnkF8); + // Play shake animations and do bounce effects + cur_obj_init_animation_with_sound(BOWSER_ANIM_SHAKING); + bowser_bounce_effects(&o->oBowserTimer); + // Reset speed when he moves on ground if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oForwardVel = 0.0f; - o->oSubAction++; + o->oSubAction++; // stops this current subaction } - } else if (cur_obj_init_animation_and_check_if_near_end(0)) - o->oAction = 0; + // Stand up and after play, set to default act + } else if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_STAND_UP)) + o->oAction = BOWSER_ACT_DEFAULT; + // Hit mine check, reduce health and set specific action depending of it if (bowser_check_hit_mine()) { o->oHealth--; - if (o->oHealth <= 0) - o->oAction = 4; - else - o->oAction = 12; + if (o->oHealth <= 0) { + o->oAction = BOWSER_ACT_DEAD; + } else { + o->oAction = BOWSER_ACT_HIT_MINE; + } } } +/** + * Set Bowser invisible and stops him (after falling) + */ void bowser_set_goal_invisible(void) { - o->oBowserUnk1AC = 0; + o->oBowserTargetOpacity = 0; if (o->oOpacity == 0) { o->oForwardVel = 0.0f; o->oVelY = 0.0f; @@ -674,60 +1018,83 @@ void bowser_set_goal_invisible(void) { } } +/** + * Makes Bowser jump back on stage after falling + */ void bowser_act_jump_onto_stage(void) { - s32 sp2C; + s32 onDynamicFloor; UNUSED s32 unused; - struct Surface *sp24 = o->oFloor; - if (sp24 != NULL && sp24->flags & 1) - sp2C = 1; - else - sp2C = 0; - o->oBowserUnkF4 |= 0x10000; + struct Surface *floor = o->oFloor; + + // Set dynamic floor check (Object platforms) + if (floor != NULL && floor->flags & SURFACE_FLAG_DYNAMIC) { + onDynamicFloor = TRUE; + } else { + onDynamicFloor = FALSE; + } + // Set status Jump + o->oBowserStatus |= BOWSER_STATUS_BIG_JUMP; + switch (o->oSubAction) { - case 0: + // Stops Bowser and makes him invisible + case BOWSER_SUB_ACT_JUMP_ON_STAGE_IDLE: if (o->oTimer == 0) { o->oFaceAnglePitch = 0; o->oFaceAngleRoll = 0; } //? missing else o->oFaceAnglePitch += 0x800; o->oFaceAngleRoll += 0x800; - if (!(o->oFaceAnglePitch & 0xFFFF)) + if (!(o->oFaceAnglePitch & 0xFFFF)) { o->oSubAction++; + } bowser_set_goal_invisible(); break; - case 1: - cur_obj_init_animation_with_sound(9); + // Start jump animation and make him visible after an animation frame + case BOWSER_SUB_ACT_JUMP_ON_STAGE_START: + cur_obj_init_animation_with_sound(BOWSER_ANIM_JUMP_START); if (cur_obj_check_anim_frame(11)) { o->oMoveAngleYaw = o->oBowserAngleToCentre; o->oVelY = 150.0f; - o->oBowserUnk1AC = 0xFF; - o->oBowserUnkF8 = 0; + o->oBowserTargetOpacity = 0xFF; + o->oBowserTimer = 0; o->oSubAction++; - } else + } else { bowser_set_goal_invisible(); + } break; - case 2: + // Approach him back on stage + case BOWSER_SUB_ACT_JUMP_ON_STAGE_LAND: if (o->oPosY > o->oHomeY) { o->oDragStrength = 0.0f; if (o->oBowserDistToCentre < 2500.0f) { - if (absf(o->oFloorHeight - o->oHomeY) < 100.0f) + if (absf(o->oFloorHeight - o->oHomeY) < 100.0f) { approach_f32_signed(&o->oForwardVel, 0, -5.0f); - else + } else { cur_obj_forward_vel_approach_upward(150.0f, 2.0f); + } } else cur_obj_forward_vel_approach_upward(150.0f, 2.0f); } + // Land on stage if (bowser_land()) { o->oDragStrength = 10.0f; o->oSubAction++; - if (sp2C == 0) + // Spawn shockwave (BITS only) if is not on a platform + if (onDynamicFloor == FALSE) { bowser_spawn_shockwave(); - else if (BITS) - o->oAction = 13; - if (BITFS) - o->oAction = 19; + // If is on a dynamic floor in BITS, then jump + // because of the falling platform + } else if (o->oBehParams2ndByte == BOWSER_BP_BITS) { + o->oAction = BOWSER_ACT_BIG_JUMP; + } + // If is on a dynamic floor in BITFS, then tilt platform + if (o->oBehParams2ndByte == BOWSER_BP_BITFS) { + o->oAction = BOWSER_ACT_TILT_LAVA_PLATFORM; + } } -#ifndef VERSION_JP + // Reset him back on stage if he still didn't landed yet + // Post-JP made this check as a separate function +#if BUGFIX_BOWSER_FALLEN_OFF_STAGE bowser_reset_fallen_off_stage(); #else if (o->oVelY < 0.0f && o->oPosY < o->oHomeY - 300.0f) { @@ -737,10 +1104,11 @@ void bowser_act_jump_onto_stage(void) { } #endif break; - case 3: + // Bowser landed, so reset action after he's done jumping + case BOWSER_SUB_ACT_JUMP_ON_STAGE_STOP: if (cur_obj_check_if_near_animation_end()) { - o->oAction = 0; - o->oBowserUnkF4 &= ~0x10000; + o->oAction = BOWSER_ACT_DEFAULT; + o->oBowserStatus &= ~BOWSER_STATUS_BIG_JUMP; cur_obj_extend_animation_if_at_end(); } break; @@ -748,77 +1116,123 @@ void bowser_act_jump_onto_stage(void) { print_debug_bottom_up("sp %d", o->oForwardVel); } +/** + * The frames of the Bowser's timer on which to play a "stomp" sound + */ +s8 sBowserDanceStepNoises[] = { 24, 42, 60, -1 }; + +/** + * Makes Bowser's dance as a "taunt" + */ void bowser_act_dance(void) { - if (is_item_in_array(o->oTimer, D_8032F514)) + // Play a stomp sound effect on certain frames + if (is_item_in_array(o->oTimer, sBowserDanceStepNoises)) { cur_obj_play_sound_2(SOUND_OBJ_BOWSER_WALK); - if (cur_obj_init_animation_and_check_if_near_end(10)) - o->oAction = 0; + } + // Play dance animation and after that return to default action + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_DANCE)) { + o->oAction = BOWSER_ACT_DEFAULT; + } } -void bowser_spawn_grand_star_key(void) { - if (BITS) +/** + * Spawn collectable that Bowser spawns after despawning + * Spawns a Key in BITDW/BITFS or Grand Star in BITS + */ +void bowser_spawn_collectable(void) { + if (o->oBehParams2ndByte == BOWSER_BP_BITS) { gSecondCameraFocus = spawn_object(o, MODEL_STAR, bhvGrandStar); - else { + } else { gSecondCameraFocus = spawn_object(o, MODEL_BOWSER_KEY, bhvBowserKey); cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_KEY); } gSecondCameraFocus->oAngleVelYaw = o->oAngleVelYaw; } +/** + * Makes Bowser fly back on stage defeated + */ void bowser_fly_back_dead(void) { - cur_obj_init_animation_with_sound(16); - if (BITS) + cur_obj_init_animation_with_sound(BOWSER_ANIM_FLIP_DOWN); + // More knockback in BITS + if (o->oBehParams2ndByte == BOWSER_BP_BITS) { o->oForwardVel = -400.0f; - else + } else { o->oForwardVel = -200.0f; + } o->oVelY = 100.0f; o->oMoveAngleYaw = o->oBowserAngleToCentre + 0x8000; - o->oBowserUnkF8 = 0; - o->oSubAction++; + o->oBowserTimer = 0; + o->oSubAction++; // BOWSER_SUB_ACT_DEAD_BOUNCE } +/** + * Plays bounce effects after landing upside down + */ void bowser_dead_bounce(void) { - o->oBowserEyesShut = 1; - bowser_bounce(&o->oBowserUnkF8); - if (o->oMoveFlags & OBJ_MOVE_LANDED) + o->oBowserEyesShut = TRUE; // close eyes + bowser_bounce_effects(&o->oBowserTimer); + if (o->oMoveFlags & OBJ_MOVE_LANDED) { cur_obj_play_sound_2(SOUND_OBJ_BOWSER_WALK); + } if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oForwardVel = 0.0f; - o->oSubAction++; + o->oSubAction++; // BOWSER_SUB_ACT_DEAD_WAIT } } +/** + * Wait for Mario to get close while Bowser is defeated + * Returns TRUE if he is close enough + */ s32 bowser_dead_wait_for_mario(void) { - s32 ret = 0; + s32 ret = FALSE; cur_obj_become_intangible(); - if (cur_obj_init_animation_and_check_if_near_end(17) && o->oDistanceToMario < 700.0f - && abs_angle_diff(gMarioObject->oMoveAngleYaw, o->oAngleToMario) > 0x6000) - ret = 1; + if (cur_obj_init_animation_and_check_if_near_end(BOWSER_ANIM_LAY_DOWN) && o->oDistanceToMario < 700.0f + && abs_angle_diff(gMarioObject->oMoveAngleYaw, o->oAngleToMario) > 0x6000) { + ret = TRUE; + } cur_obj_extend_animation_if_at_end(); - o->oBowserUnkF8 = 0; + o->oBowserTimer = 0; return ret; } -s32 bowser_dead_twirl_into_trophy(void) { - s32 ret = 0; - if (o->header.gfx.scale[0] < 0.8) +/** + * Makes Bowser twirl up by changing his scale + * Returns TRUE once done + */ +s32 bowser_dead_twirl_up(void) { + s32 ret = FALSE; + // Set angle rotation once he has low X scale value + if (o->header.gfx.scale[0] < 0.8) { o->oAngleVelYaw += 0x80; + } + // Slowly scale down his X and Z value if (o->header.gfx.scale[0] > 0.2) { o->header.gfx.scale[0] = o->header.gfx.scale[0] - 0.02; o->header.gfx.scale[2] = o->header.gfx.scale[2] - 0.02; } else { + // Now scale down his Y value (and send Bowser up) o->header.gfx.scale[1] = o->header.gfx.scale[1] - 0.01; o->oVelY = 20.0f; o->oGravity = 0.0f; } - if (o->header.gfx.scale[1] < 0.5) - ret = 1; + // At half Y scale value, he is high enough, so we are done + if (o->header.gfx.scale[1] < 0.5) { + ret = TRUE; + } + // Copy angle rotation to moving rotation o->oMoveAngleYaw += o->oAngleVelYaw; - if (o->oOpacity >= 3) + // Slowly fade out + if (o->oOpacity >= 3) { o->oOpacity -= 2; + } return ret; } +/** + * Hides Bowser after his death sequence is done + */ void bowser_dead_hide(void) { cur_obj_scale(0); o->oForwardVel = 0; @@ -826,288 +1240,446 @@ void bowser_dead_hide(void) { o->oGravity = 0; } -s32 bowser_dead_not_bits_end(void) { - s32 ret = 0; - if (o->oBowserUnkF8 < 2) { - if (o->oBowserUnkF8 == 0) { +/** + * Dialog values that are set on each stage Bowser's is defeated + */ +s16 sBowserDefeatedDialogText[3] = { DIALOG_119, DIALOG_120, DIALOG_121 }; + +/** + * Bowser's dead sequence that plays in BITDW/BITFS + * Returns TRUE once done + */ +s32 bowser_dead_default_stage_ending(void) { + s32 ret = FALSE; + if (o->oBowserTimer < 2) { + // Lower music volume + if (o->oBowserTimer == 0) { seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); - o->oBowserUnkF8++; + o->oBowserTimer++; } - if (cur_obj_update_dialog(2, 18, sBowserDefeatedDialogText[o->oBehParams2ndByte], 0)) { - o->oBowserUnkF8++; + // Play Bowser defeated dialog + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, + (DIALOG_FLAG_TEXT_DEFAULT | DIALOG_FLAG_TIME_STOP_ENABLED), + sBowserDefeatedDialogText[o->oBehParams2ndByte], 0)) { + // Dialog is done, fade out music and play explode sound effect + o->oBowserTimer++; cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_EXPLODE); seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); seq_player_fade_out(SEQ_PLAYER_LEVEL, 1); } - } else if (bowser_dead_twirl_into_trophy()) { + // Hide Bowser and spawn collectable once done twirling + } else if (bowser_dead_twirl_up()) { bowser_dead_hide(); - spawn_triangle_break_particles(20, 116, 1.0f, 0); - bowser_spawn_grand_star_key(); - set_mario_npc_dialog(0); - ret = 1; + spawn_triangle_break_particles(20, MODEL_YELLOW_COIN, 1.0f, 0); + bowser_spawn_collectable(); + set_mario_npc_dialog(MARIO_DIALOG_STOP); + ret = TRUE; } return ret; } -s32 bowser_dead_bits_end(void) { +/** + * Bowser's dead sequence that plays in BITS + * Returns TRUE once done + */ +s32 bowser_dead_final_stage_ending(void) { UNUSED s32 unused; - s32 ret = 0; + s32 ret = FALSE; s32 dialogID; - if (o->oBowserUnkF8 < 2) { - if (gHudDisplay.stars < 120) + if (o->oBowserTimer < 2) { + // Set dialog whenever you have 120 stars or not + if (gHudDisplay.stars < 120) { dialogID = DIALOG_121; - else + } else { dialogID = DIALOG_163; - if (o->oBowserUnkF8 == 0) { - seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); - o->oBowserUnkF8++; } - if (cur_obj_update_dialog(2, 18, dialogID, 0)) { - cur_obj_set_model(MODEL_BOWSER2); + // Lower music volume + if (o->oBowserTimer == 0) { + seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); + o->oBowserTimer++; + } + // Play Bowser defeated dialog + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, + (DIALOG_FLAG_TEXT_DEFAULT | DIALOG_FLAG_TIME_STOP_ENABLED), dialogID, 0)) { + // Dialog is done, fade out music and spawn grand star + cur_obj_set_model(MODEL_BOWSER_NO_SHADOW); seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); seq_player_fade_out(SEQ_PLAYER_LEVEL, 1); - bowser_spawn_grand_star_key(); - o->oBowserUnkF8++; + bowser_spawn_collectable(); + o->oBowserTimer++; } + // Slowly fade him out } else if (o->oOpacity > 4) o->oOpacity -= 4; else { + // And at last, hide him bowser_dead_hide(); - ret = 1; + ret = TRUE; } return ret; } +/** + * Bowser's dead action, plays when he has no health left + * This action is divided in subaction functions + */ void bowser_act_dead(void) { switch (o->oSubAction) { - case 0: + case BOWSER_SUB_ACT_DEAD_FLY_BACK: bowser_fly_back_dead(); break; - case 1: + case BOWSER_SUB_ACT_DEAD_BOUNCE: bowser_dead_bounce(); break; - case 2: + case BOWSER_SUB_ACT_DEAD_WAIT: + // Check if Mario is close to Bowser if (bowser_dead_wait_for_mario()) { - o->oBowserUnkF8 = 0; - if (BITS) - o->oSubAction = 10; - else { + o->oBowserTimer = 0; + // Set different (final) subaction in BITS + // Non-BITS Bowser uses default subaction and sets dithering + if (o->oBehParams2ndByte == BOWSER_BP_BITS) { + o->oSubAction = BOWSER_SUB_ACT_DEAD_FINAL_END; + } else { o->activeFlags |= ACTIVE_FLAG_DITHERED_ALPHA; - o->oSubAction++; + o->oSubAction++; // BOWSER_SUB_ACT_DEAD_DEFAULT_END } } break; - case 3: - if (bowser_dead_not_bits_end()) - o->oSubAction++; + case BOWSER_SUB_ACT_DEAD_DEFAULT_END: + if (bowser_dead_default_stage_ending()) { + o->oSubAction++; // BOWSER_SUB_ACT_DEAD_DEFAULT_END_OVER + } break; - case 4: + case BOWSER_SUB_ACT_DEAD_DEFAULT_END_OVER: break; - case 10: - if (bowser_dead_bits_end()) - o->oSubAction++; + case BOWSER_SUB_ACT_DEAD_FINAL_END: + if (bowser_dead_final_stage_ending()) { + o->oSubAction++; // BOWSER_SUB_ACT_DEAD_FINAL_END_OVER + } break; - case 11: + case BOWSER_SUB_ACT_DEAD_FINAL_END_OVER: break; } } -void bowser_tilt_platform(struct Object *platform, s16 a1) { +/** + * Sets values for the BITFS platform to tilt + */ +void bowser_tilt_platform(struct Object *platform, s16 angSpeed) { s16 angle; angle = o->oBowserAngleToCentre + 0x8000; - platform->oAngleVelPitch = coss(angle) * a1; - platform->oAngleVelRoll = -sins(angle) * a1; + platform->oAngleVelPitch = coss(angle) * angSpeed; + platform->oAngleVelRoll = -sins(angle) * angSpeed; } -void bowser_act_ride_tilting_platform(void) { +/** + * Struct for the BITFS tilt platform + */ +struct BowserTiltPlatformInfo { + // Flag value to make sure platform moves smoothly + // 0 = Don't move + // 1 = Move angle behind Bowser + // -1 = Move angle in front of Bowser + s16 flag; + // Sets platform's tilt angle speed (pattern: positive then negative) + s16 angSpeed; + // Sets how much time the platform can tilt, increases each move + s16 time; +}; + +/** + * Data for the BITFS tilt Platform + */ +struct BowserTiltPlatformInfo sBowsertiltPlatformData[] = { + { 1, 10, 40 }, + { 0, 0, 74 }, + { -1, -10, 114 }, + { 1, -20, 134 }, + { -1, 20, 154 }, + { 1, 40, 164 }, + { -1, -40, 174 }, + { 1, -80, 179 }, + { -1, 80, 184 }, + { 1, 160, 186 }, + { -1, -160, 186 }, + { 1, 0, 0 }, +}; + +/** + * Makes the platform in BITFS tilt from left to right + */ +void bowser_act_tilt_lava_platform(void) { + // Set platform object struct Object *platform = cur_obj_nearest_object_with_behavior(bhvTiltingBowserLavaPlatform); - UNUSED s16 sp2A = o->oBowserAngleToCentre + 0x8000; - s16 sp28; + UNUSED s16 angle = o->oBowserAngleToCentre + 0x8000; + s16 angSpeed; UNUSED s32 unused; s32 i; - s32 sp1C; - if (platform == NULL) - o->oAction = 0; - else { + s32 isNotTilting; + // If there's not platform, return to default action + if (platform == NULL) { + o->oAction = BOWSER_ACT_DEFAULT; + } else { i = 0; - sp1C = 1; - while (D_8032F520[i][2] != 0) { - if (o->oTimer < D_8032F520[i][2]) { - sp28 = D_8032F520[i][1]; - if (D_8032F520[i][0] > 0) - sp28 = (D_8032F520[i][2] - o->oTimer - 1) * sp28; - else - sp28 = (o->oTimer - D_8032F520[i - 1][2]) * sp28; - bowser_tilt_platform(platform, sp28); - if (sp28 != 0) - play_sound(SOUND_ENV_UNKNOWN4, platform->header.gfx.cameraToObject); - sp1C = 0; + isNotTilting = TRUE; + // Active platform tilting if the timer is not 0 + while (sBowsertiltPlatformData[i].time != 0) { + // Move if the time values is more than the timer + if (o->oTimer < sBowsertiltPlatformData[i].time) { + // Set angle speed + angSpeed = sBowsertiltPlatformData[i].angSpeed; + // Move angle behind Bowser + if (sBowsertiltPlatformData[i].flag > 0) { + angSpeed = (sBowsertiltPlatformData[i].time - o->oTimer - 1) * angSpeed; + } else { // Move angle in front of Bowser + angSpeed = (o->oTimer - sBowsertiltPlatformData[i - 1].time) * angSpeed; + } + // Set angle values to the platform + bowser_tilt_platform(platform, angSpeed); + // Play sound effect + if (angSpeed != 0) { + play_sound(SOUND_ENV_MOVING_BIG_PLATFORM, platform->header.gfx.cameraToObject); + } + isNotTilting = FALSE; break; } i++; } - if (sp1C) { - o->oAction = 0; + // If Bowser is done tilting, reset platform angles + // and set Bowser to default action + if (isNotTilting) { + o->oAction = BOWSER_ACT_DEFAULT; platform->oAngleVelPitch = 0; platform->oAngleVelRoll = 0; platform->oFaceAnglePitch = 0; platform->oFaceAngleRoll = 0; } } + // Extend "idle" animation cur_obj_extend_animation_if_at_end(); } -s32 bowser_check_fallen_off_stage(void) // bowser off stage? -{ - if (o->oAction != 2 && o->oAction != 19) { +/** + * Check if Bowser is offstage from a large distance or landed on a lethal floor + */ +s32 bowser_check_fallen_off_stage(void) { + if (o->oAction != BOWSER_ACT_JUMP_ONTO_STAGE && o->oAction != BOWSER_ACT_TILT_LAVA_PLATFORM) { if (o->oPosY < o->oHomeY - 1000.0f) - return 1; + return TRUE; if (o->oMoveFlags & OBJ_MOVE_LANDED) { - if (o->oFloorType == SURFACE_BURNING) - return 1; - if (o->oFloorType == SURFACE_DEATH_PLANE) - return 1; + // Check for Fire Sea + if (o->oFloorType == SURFACE_BURNING) { + return TRUE; + } + // Check for Dark World - Sky + if (o->oFloorType == SURFACE_DEATH_PLANE) { + return TRUE; + } } } - return 0; + return FALSE; } -void (*sBowserActions[])(void) = { bowser_act_default, bowser_act_thrown_dropped, bowser_act_jump_onto_stage, bowser_act_dance, - bowser_act_dead, bowser_act_text_wait, bowser_act_intro_walk, bowser_act_charge_mario, - bowser_act_spit_fire_into_sky, bowser_act_spit_fire_onto_floor, bowser_act_hit_edge, bowser_act_turn_from_edge, - bowser_act_hit_mine, bowser_act_jump, bowser_act_walk_to_mario, bowser_act_breath_fire, - bowser_act_teleport, bowser_act_jump_towards_mario, bowser_act_unused_slow_walk, bowser_act_ride_tilting_platform }; -struct SoundState D_8032F5B8[] = { { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 1, 0, -1, SOUND_OBJ_BOWSER_WALK }, - { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR }, - { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 1, 20, 40, SOUND_OBJ_BOWSER_WALK }, - { 1, 20, -1, SOUND_OBJ_BOWSER_WALK }, - { 1, 20, 40, SOUND_OBJ_BOWSER_WALK }, - { 1, 0, -1, SOUND_OBJ_BOWSER_TAIL_PICKUP }, - { 1, 0, -1, SOUND_OBJ_BOWSER_DEFEATED }, - { 1, 8, -1, SOUND_OBJ_BOWSER_WALK }, - { 1, 8, 17, SOUND_OBJ_BOWSER_WALK }, - { 1, 8, -10, SOUND_OBJ_BOWSER_WALK }, - { 0, 0, 0, NO_SOUND }, - { 1, 5, -1, SOUND_OBJ_FLAME_BLOWN }, - { 0, 0, 0, NO_SOUND }, - { 0, 0, 0, NO_SOUND }, - { 1, 0, -1, SOUND_OBJ_BOWSER_TAIL_PICKUP }, - { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR } }; -s8 D_8032F690[4] = { 0, 0, 1, 0 }; -s8 D_8032F694[4] = { 1, 1, 3, 0 }; -extern u8 bowser_3_seg7_collision_07004B94[]; -extern u8 bowser_3_seg7_collision_07004C18[]; -extern u8 bowser_3_seg7_collision_07004C9C[]; -extern u8 bowser_3_seg7_collision_07004D20[]; -extern u8 bowser_3_seg7_collision_07004DA4[]; -extern u8 bowser_3_seg7_collision_07004E28[]; -extern u8 bowser_3_seg7_collision_07004EAC[]; -extern u8 bowser_3_seg7_collision_07004F30[]; -extern u8 bowser_3_seg7_collision_07004FB4[]; -extern u8 bowser_3_seg7_collision_07005038[]; -struct Struct8032F698 D_8032F698[] = { { NULL, 0, 0, 0, 0 }, - { bowser_3_seg7_collision_07004B94, -800, -1000, -20992, 0 }, - { bowser_3_seg7_collision_07004C18, -1158, 390, -18432, 0 }, - { bowser_3_seg7_collision_07004C9C, -1158, 390, -7680, 0 }, - { bowser_3_seg7_collision_07004D20, 0, 1240, -6144, 0 }, - { bowser_3_seg7_collision_07004DA4, 0, 1240, 6144, 0 }, - { bowser_3_seg7_collision_07004E28, 1158, 390, 7680, 0 }, - { bowser_3_seg7_collision_07004EAC, 1158, 390, 18432, 0 }, - { bowser_3_seg7_collision_07004F30, 800, -1000, 20992, 0 }, - { bowser_3_seg7_collision_07004FB4, 800, -1000, -31744, 0 }, - { bowser_3_seg7_collision_07005038, -800, -1000, 31744, 0 } }; +/** + * Set Bowser's actions + */ +void (*sBowserActions[])(void) = { + bowser_act_default, + bowser_act_thrown, + bowser_act_jump_onto_stage, + bowser_act_dance, + bowser_act_dead, + bowser_act_wait, + bowser_act_intro_walk, + bowser_act_charge_mario, + bowser_act_spit_fire_into_sky, + bowser_act_spit_fire_onto_floor, + bowser_act_hit_edge, + bowser_act_turn_from_edge, + bowser_act_hit_mine, + bowser_act_big_jump, + bowser_act_walk_to_mario, + bowser_act_breath_fire, + bowser_act_teleport, + bowser_act_quick_jump, + bowser_act_idle, + bowser_act_tilt_lava_platform +}; +/** + * Set Bowser's sound animations + */ +struct SoundState sBowserSoundStates[] = { + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 1, 0, -1, SOUND_OBJ_BOWSER_WALK }, + { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR }, + { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 1, 20, 40, SOUND_OBJ_BOWSER_WALK }, + { 1, 20, -1, SOUND_OBJ_BOWSER_WALK }, + { 1, 20, 40, SOUND_OBJ_BOWSER_WALK }, + { 1, 0, -1, SOUND_OBJ_BOWSER_TAIL_PICKUP }, + { 1, 0, -1, SOUND_OBJ_BOWSER_DEFEATED }, + { 1, 8, -1, SOUND_OBJ_BOWSER_WALK }, + { 1, 8, 17, SOUND_OBJ_BOWSER_WALK }, + { 1, 8, -10, SOUND_OBJ_BOWSER_WALK }, + { 0, 0, 0, NO_SOUND }, + { 1, 5, -1, SOUND_OBJ_FLAME_BLOWN }, + { 0, 0, 0, NO_SOUND }, + { 0, 0, 0, NO_SOUND }, + { 1, 0, -1, SOUND_OBJ_BOWSER_TAIL_PICKUP }, + { 1, 0, -1, SOUND_OBJ2_BOWSER_ROAR }, +}; + +/** + * Set whenever Bowser should have rainbow light or not on each stage + */ +s8 sBowserRainbowLight[] = { FALSE, FALSE, TRUE }; + +/** + * Set how much health Bowser has on each stage + */ +s8 sBowserHealth[] = { 1, 1, 3 }; + +/** + * Update Bowser's actions when he's hands free + */ void bowser_free_update(void) { struct Surface *floor; struct Object *platform; UNUSED f32 floorHeight; - if ((platform = o->platform) != NULL) + + // Platform displacement check (for BITFS) + if ((platform = o->platform) != NULL) { apply_platform_displacement(FALSE, platform); - o->oBowserUnk10E = 0; + } + // Reset grabbed status + o->oBowserGrabbedStatus = BOWSER_GRAB_STATUS_NONE; + // Update positions and actions (default action) cur_obj_update_floor_and_walls(); cur_obj_call_action_function(sBowserActions); cur_obj_move_standard(-78); - if (bowser_check_fallen_off_stage()) - o->oAction = 2; // bowser go home? + // Jump on stage if Bowser has fallen off + if (bowser_check_fallen_off_stage()) { + o->oAction = BOWSER_ACT_JUMP_ONTO_STAGE; + } + // Check floor height and platform floorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); - if ((floor != NULL) && (floor->object != 0)) + if ((floor != NULL) && (floor->object != NULL)) { o->platform = floor->object; - else + } else { o->platform = NULL; - exec_anim_sound_state(D_8032F5B8); + } + // Sound states for Bowser Animations + exec_anim_sound_state(sBowserSoundStates); } +/** + * Update Bowser's actions when he's getting held + */ void bowser_held_update(void) { - o->oBowserUnkF4 &= ~0x20000; + // Reset fire sky status and make him intangible + o->oBowserStatus &= ~BOWSER_STATUS_FIRE_SKY; cur_obj_become_intangible(); - switch (o->oBowserUnk10E) { - case 0: + switch (o->oBowserGrabbedStatus) { + // Play pickup sound, start grabbed animation, and set throw action + // Throw action won't be played until he's actually released + case BOWSER_GRAB_STATUS_NONE: cur_obj_play_sound_2(SOUND_OBJ_BOWSER_TAIL_PICKUP); - cur_obj_unrender_and_reset_state(3, 1); - o->oBowserUnk10E++; + cur_obj_unrender_set_action_and_anim(BOWSER_ANIM_GRABBED, BOWSER_ACT_THROWN); + o->oBowserGrabbedStatus++; break; - case 1: + // After the grabbed animation ends, play shaking animation in a loop + case BOWSER_GRAB_STATUS_GRABBED: if (cur_obj_check_if_near_animation_end()) { - cur_obj_init_animation_with_sound(2); - o->oBowserUnk10E++; + cur_obj_init_animation_with_sound(BOWSER_ANIM_SHAKING); + o->oBowserGrabbedStatus++; } break; - case 2: + case BOWSER_GRAB_STATUS_HOLDING: break; } + // Reset move flags o->oMoveFlags = 0; + // Copy angle values from Mario o->oBowserHeldAnglePitch = gMarioObject->oMoveAnglePitch; o->oBowserHeldAngleVelYaw = gMarioObject->oAngleVelYaw; o->oMoveAngleYaw = gMarioObject->oMoveAngleYaw; } +/** + * Update Bowser's actions when he's thrown and dropped + */ void bowser_thrown_dropped_update(void) { - f32 sp1C; - o->oBowserUnk10E = 0; - cur_obj_get_thrown_or_placed(1.0f, 1.0f, 1); - sp1C = o->oBowserHeldAngleVelYaw / 3000.0 * 70.0f; - if (sp1C < 0.0f) - sp1C = -sp1C; - if (sp1C > 90.0f) - sp1C *= 2.5; // > 90 => get bigger? - o->oForwardVel = coss(o->oBowserHeldAnglePitch) * sp1C; - o->oVelY = -sins(o->oBowserHeldAnglePitch) * sp1C; + f32 swingSpd; + // Reset grabbed status + o->oBowserGrabbedStatus = BOWSER_GRAB_STATUS_NONE; + // Set throw action and vel values + cur_obj_get_thrown_or_placed(1.0f, 1.0f, BOWSER_ACT_THROWN); + // Set swing speed based of angle + swingSpd = o->oBowserHeldAngleVelYaw / 3000.0 * 70.0f; + // If less than 0, reduce speed + if (swingSpd < 0.0f) { + swingSpd = -swingSpd; + } + // If more than 90, increase speed + if (swingSpd > 90.0f) { + swingSpd *= 2.5; + } + // Set distance speed when throwing + o->oForwardVel = coss(o->oBowserHeldAnglePitch) * swingSpd; + o->oVelY = -sins(o->oBowserHeldAnglePitch) * swingSpd; cur_obj_become_intangible(); - o->prevObj->oAction = 1; // not sure what prevObj is + + // Reset timer and subactions + o->prevObj->oAction = BOWSER_ACT_TAIL_THROWN; // prevObj is Bowser's Tail o->prevObj->oTimer = 0; - o->prevObj->oSubAction = 0; + o->prevObj->oSubAction = 0; //! Tail doesn't have sub actions + o->oTimer = 0; o->oSubAction = 0; } +/** + * Bowser's main loop + */ void bhv_bowser_loop(void) { - s16 angleToMario; // AngleToMario from Bowser's perspective + s16 angleToMario; // AngleToMario from Bowser's perspective s16 angleToCentre; // AngleToCentre from Bowser's perspective + // Set distance/angle values o->oBowserDistToCentre = sqrtf(o->oPosX * o->oPosX + o->oPosZ * o->oPosZ); o->oBowserAngleToCentre = atan2s(0.0f - o->oPosZ, 0.0f - o->oPosX); angleToMario = abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario); angleToCentre = abs_angle_diff(o->oMoveAngleYaw, o->oBowserAngleToCentre); - o->oBowserUnkF4 &= ~0xFF; - if (angleToMario < 0x2000) - o->oBowserUnkF4 |= 2; - if (angleToCentre < 0x3800) - o->oBowserUnkF4 |= 4; - if (o->oBowserDistToCentre < 1000.0f) - o->oBowserUnkF4 |= 0x10; - if (o->oDistanceToMario < 850.0f) - o->oBowserUnkF4 |= 8; + + // Reset Status + o->oBowserStatus &= ~0xFF; + + // Set bitflag status for distance/angle values + // Only the first one is used + if (angleToMario < 0x2000) { + o->oBowserStatus |= BOWSER_STATUS_ANGLE_MARIO; + } + if (angleToCentre < 0x3800) { + o->oBowserStatus |= BOWSER_STATUS_ANGLE_CENTRE; // unused + } + if (o->oBowserDistToCentre < 1000.0f) { + o->oBowserStatus |= BOWSER_STATUS_DIST_CENTRE; // unused + } + if (o->oDistanceToMario < 850.0f) { + o->oBowserStatus |= BOWSER_STATUS_DIST_MARIO; // unused + } + + // Update Held state actions switch (o->oHeldState) { case HELD_FREE: bowser_free_update(); @@ -1122,465 +1694,220 @@ void bhv_bowser_loop(void) { bowser_thrown_dropped_update(); break; } + // Adjust model to the floor cur_obj_align_gfx_with_floor(); - if (o->oAction != 4) - if (o->oBowserUnk1AC != o->oOpacity) { - if (o->oBowserUnk1AC > o->oOpacity) { + + // Adjust opacity (when not dead) + // Mostly for the teleport action in BITFS + if (o->oAction != BOWSER_ACT_DEAD) { + if (o->oBowserTargetOpacity != o->oOpacity) { + // increase opacity when oBowserTargetOpacity is 0xFF + if (o->oBowserTargetOpacity > o->oOpacity) { o->oOpacity += 20; - if (o->oOpacity >= 0x100) + if (o->oOpacity >= 0x100) { o->oOpacity = 0xFF; + } + // reduce opacity when oBowserTargetOpacity is 0 } else { o->oOpacity -= 20; - if (o->oOpacity < 0) + if (o->oOpacity < 0) { o->oOpacity = 0; + } } } + } } +/** + * Bowser's initial values and actions + */ void bhv_bowser_init(void) { - s32 level; // 0 is dw, 1 is fs, 2 is sky - o->oBowserUnk110 = 1; + s32 level; + // Set "reaction" value + // It goes true when Bowser is a non-walking state + o->oBowserIsReacting = TRUE; + // Set no transparency opacity o->oOpacity = 0xFF; - o->oBowserUnk1AC = 0xFF; - if (gCurrLevelNum == LEVEL_BOWSER_2) - level = 1; - else if (gCurrLevelNum == LEVEL_BOWSER_3) - level = 2; - else - level = 0; + o->oBowserTargetOpacity = 0xFF; + // Set Bowser B-param depending of the stage + if (gCurrLevelNum == LEVEL_BOWSER_2) { + level = BOWSER_BP_BITFS; + } else if (gCurrLevelNum == LEVEL_BOWSER_3) { + level = BOWSER_BP_BITS; + } else { // LEVEL_BOWSER_1 + level = BOWSER_BP_BITDW; + } o->oBehParams2ndByte = level; - o->oBowserUnk1B2 = D_8032F690[level]; - o->oHealth = D_8032F694[level]; + // Set health and rainbow light depending of the level + o->oBowserRainbowLight = sBowserRainbowLight[level]; + o->oHealth = sBowserHealth[level]; + // Start camera event, this event is not defined so maybe + // the "start arena" cutscene was originally called this way cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_INIT); - o->oAction = 5; - o->oBowserUnk1AE = 0; - o->oBowserEyesShut = 0; + o->oAction = BOWSER_ACT_WAIT; + // Set eyes status + o->oBowserEyesTimer = 0; + o->oBowserEyesShut = FALSE; } -#undef BITDW -#undef BITFS -#undef BITS +Gfx *geo_update_body_rot_from_parent(s32 callContext, UNUSED struct GraphNode *node, Mat4 mtx) { + Mat4 mtx2; + struct Object *obj; -Gfx *geo_update_body_rot_from_parent(s32 run, UNUSED struct GraphNode *node, Mat4 mtx) { - Mat4 sp20; - struct Object *sp1C; - - if (run == TRUE) { - sp1C = (struct Object *) gCurGraphNodeObject; - if (sp1C->prevObj != NULL) { - create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); - obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); - obj_set_gfx_pos_from_pos(sp1C->prevObj); + if (callContext == GEO_CONTEXT_RENDER) { + obj = (struct Object *) gCurGraphNodeObject; + if (obj->prevObj != NULL) { + create_transformation_from_matrices(mtx2, mtx, *gCurGraphNodeCamera->matrixPtr); + obj_update_pos_from_parent_transformation(mtx2, obj->prevObj); + obj_set_gfx_pos_from_pos(obj->prevObj); } } return NULL; } -void bowser_open_eye_switch(struct Object *a0, struct GraphNodeSwitchCase *switchCase) { - s32 sp1C; - s16 sp1A; - sp1A = abs_angle_diff(a0->oMoveAngleYaw, a0->oAngleToMario); - sp1C = switchCase->selectedCase; - switch (sp1C) { - case 0: - if (sp1A > 0x2000) { - if (a0->oAngleVelYaw > 0) - switchCase->selectedCase = 5; - if (a0->oAngleVelYaw < 0) - switchCase->selectedCase = 3; +/** + * Bowser's eyes Geo-Switch-Case IDs, defined from Mario's POV + */ +enum BowserEyesGSCId +{ + /*0x00*/ BOWSER_EYES_OPEN, + /*0x01*/ BOWSER_EYES_HALF_CLOSED, + /*0x02*/ BOWSER_EYES_CLOSED, + /*0x03*/ BOWSER_EYES_LEFT, + /*0x04*/ BOWSER_EYES_FAR_LEFT, + /*0x05*/ BOWSER_EYES_RIGHT, + /*0x06*/ BOWSER_EYES_FAR_RIGHT, + /*0x07*/ BOWSER_EYES_DERP, // unused + /*0x08*/ BOWSER_EYES_CROSS, // unused + /*0x08*/ BOWSER_EYES_RESET // set eyes back to open +}; + +/** + * Controls Bowser's eye open stage, including blinking and look directions + */ +void bowser_open_eye_switch(struct Object *obj, struct GraphNodeSwitchCase *switchCase) { + s32 eyeCase; + s16 angleFromMario; + angleFromMario = abs_angle_diff(obj->oMoveAngleYaw, obj->oAngleToMario); + eyeCase = switchCase->selectedCase; + switch (eyeCase) { + case BOWSER_EYES_OPEN: + // Mario is in Bowser's field of view + if (angleFromMario > 0x2000) { + if (obj->oAngleVelYaw > 0) + switchCase->selectedCase = BOWSER_EYES_RIGHT; + if (obj->oAngleVelYaw < 0) + switchCase->selectedCase = BOWSER_EYES_LEFT; } - if (a0->oBowserUnk1AE > 50) - switchCase->selectedCase = 1; + // Half close, start blinking + if (obj->oBowserEyesTimer > 50) + switchCase->selectedCase = BOWSER_EYES_HALF_CLOSED; break; - case 1: - if (a0->oBowserUnk1AE > 2) - switchCase->selectedCase = 2; + case BOWSER_EYES_HALF_CLOSED: + // Close, blinking + if (obj->oBowserEyesTimer > 2) + switchCase->selectedCase = BOWSER_EYES_CLOSED; break; - case 2: - if (a0->oBowserUnk1AE > 2) - switchCase->selectedCase = 9; + case BOWSER_EYES_CLOSED: + // Reset blinking + if (obj->oBowserEyesTimer > 2) + switchCase->selectedCase = BOWSER_EYES_RESET; break; - case 9: - if (a0->oBowserUnk1AE > 2) - switchCase->selectedCase = 0; + case BOWSER_EYES_RESET: + // Open, no longer blinking + if (obj->oBowserEyesTimer > 2) + switchCase->selectedCase = BOWSER_EYES_OPEN; break; - case 5: - if (a0->oBowserUnk1AE > 2) { - switchCase->selectedCase = 6; - if (a0->oAngleVelYaw <= 0) - switchCase->selectedCase = 0; + case BOWSER_EYES_RIGHT: + // Look more on the right if angle didn't change + // Otherwise, look at the center (open) + if (obj->oBowserEyesTimer > 2) { + switchCase->selectedCase = BOWSER_EYES_FAR_RIGHT; + if (obj->oAngleVelYaw <= 0) + switchCase->selectedCase = BOWSER_EYES_OPEN; } break; - case 6: - if (a0->oAngleVelYaw <= 0) - switchCase->selectedCase = 5; + case BOWSER_EYES_FAR_RIGHT: + // Look close right if angle was drastically changed + if (obj->oAngleVelYaw <= 0) + switchCase->selectedCase = BOWSER_EYES_RIGHT; break; - case 3: - if (a0->oBowserUnk1AE > 2) { - switchCase->selectedCase = 4; - if (a0->oAngleVelYaw >= 0) - switchCase->selectedCase = 0; + case BOWSER_EYES_LEFT: + // Look more on the left if angle didn't change + // Otherwise, look at the center (open) + if (obj->oBowserEyesTimer > 2) { + switchCase->selectedCase = BOWSER_EYES_FAR_LEFT; + if (obj->oAngleVelYaw >= 0) + switchCase->selectedCase = BOWSER_EYES_OPEN; } break; - case 4: - if (a0->oAngleVelYaw >= 0) - switchCase->selectedCase = 3; + case BOWSER_EYES_FAR_LEFT: + // Look close left if angle was drastically changed + if (obj->oAngleVelYaw >= 0) + switchCase->selectedCase = BOWSER_EYES_LEFT; break; default: - switchCase->selectedCase = 0; + switchCase->selectedCase = BOWSER_EYES_OPEN; + } + // Reset timer if eye case has changed + if (switchCase->selectedCase != eyeCase) { + obj->oBowserEyesTimer = -1; } - if (switchCase->selectedCase != sp1C) - a0->oBowserUnk1AE = -1; } -/** Geo switch for controlling the state of bowser's eye direction and open/closed +/** + * Geo switch for controlling the state of Bowser's eye direction and open/closed * state. Checks whether oBowserEyesShut is TRUE and closes eyes if so and processes * direction otherwise. */ -Gfx *geo_switch_bowser_eyes(s32 run, struct GraphNode *node, UNUSED Mat4 *mtx) { - UNUSED s16 sp36; +Gfx *geo_switch_bowser_eyes(s32 callContext, struct GraphNode *node, UNUSED Mat4 *mtx) { + UNUSED s16 eyeShut; UNUSED s32 unused; struct Object *obj = (struct Object *) gCurGraphNodeObject; struct GraphNodeSwitchCase *switchCase = (struct GraphNodeSwitchCase *) node; - if (run == TRUE) { + if (callContext == GEO_CONTEXT_RENDER) { if (gCurGraphNodeHeldObject != NULL) obj = gCurGraphNodeHeldObject->objNode; - switch (sp36 = obj->oBowserEyesShut) { - case 0: // eyes open, handle eye looking direction + switch (eyeShut = obj->oBowserEyesShut) { + case FALSE: // eyes open, handle eye looking direction bowser_open_eye_switch(obj, switchCase); break; - case 1: // eyes closed, blinking - switchCase->selectedCase = 2; + case TRUE: // eyes closed, blinking + switchCase->selectedCase = BOWSER_EYES_CLOSED; break; } - obj->oBowserUnk1AE++; + obj->oBowserEyesTimer++; } return NULL; } -Gfx *geo_bits_bowser_coloring(s32 run, struct GraphNode *node, UNUSED s32 a2) { - Gfx *sp2C = NULL; - Gfx *sp28; - struct Object *sp24; - struct GraphNodeGenerated *sp20; +/** + * Geo switch that sets Bowser's Rainbow coloring (in BITS) + */ +Gfx *geo_bits_bowser_coloring(s32 callContext, struct GraphNode *node, UNUSED s32 context) { + Gfx *gfxHead = NULL; + Gfx *gfx; + struct Object *obj; + struct GraphNodeGenerated *graphNode; - if (run == 1) { - sp24 = (struct Object *) gCurGraphNodeObject; - sp20 = (struct GraphNodeGenerated *) node; - if (gCurGraphNodeHeldObject != 0) - sp24 = gCurGraphNodeHeldObject->objNode; - if (sp24->oOpacity == 0xFF) - sp20->fnNode.node.flags = (sp20->fnNode.node.flags & 0xFF) | GRAPH_NODE_TYPE_FUNCTIONAL; - else - sp20->fnNode.node.flags = (sp20->fnNode.node.flags & 0xFF) | (GRAPH_NODE_TYPE_FUNCTIONAL | GRAPH_NODE_TYPE_400); - sp28 = sp2C = alloc_display_list(2 * sizeof(Gfx)); - - if (sp24->oBowserUnk1B2 != 0) { - gSPClearGeometryMode(sp28++, G_LIGHTING); + if (callContext == GEO_CONTEXT_RENDER) { + obj = (struct Object *) gCurGraphNodeObject; + graphNode = (struct GraphNodeGenerated *) node; + if (gCurGraphNodeHeldObject != 0) { + obj = gCurGraphNodeHeldObject->objNode; } - gSPEndDisplayList(sp28); - } - return sp2C; -} - -void falling_bowser_plat_act_0(void) { - o->oPlatformUnkF8 = cur_obj_nearest_object_with_behavior(bhvBowser); - obj_set_collision_data(o, D_8032F698[o->oBehParams2ndByte].unk0); - if (o->oPlatformUnkF8 != 0) - o->oAction = 1; -} - -void falling_bowser_plat_act_1(void) { - UNUSED s32 unused; - struct Object *sp0 = o->oPlatformUnkF8; - if (sp0->platform == o) - if (sp0->oAction == 13 && sp0->oBowserUnkF4 & 0x10000) - o->oAction = 2; - if (sp0->oHealth == 1 && (sp0->oAction == 3 || sp0->oHeldState != HELD_FREE)) - o->oSubAction = 1; - if (o->oSubAction == 0) - o->oPlatformUnkFC = 0; - else { - if ((gDebugInfo[4][6] + 20) * (o->oBehParams2ndByte - 1) < o->oPlatformUnkFC) - o->oAction = 2; - o->oPlatformUnkFC++; - } -} - -void falling_bowser_plat_act_2(void) { - Vec3f sp24; - s16 sp22; - f32 sp1C; - UNUSED struct Object *sp18 = o->oPlatformUnkF8; - if (o->oTimer == 0 || o->oTimer == 22) - cur_obj_play_sound_2(SOUND_GENERAL_BOWSER_PLATFORM_2); - if (o->oTimer < 22) { - set_environmental_camera_shake(SHAKE_ENV_FALLING_BITS_PLAT); - o->oVelY = 8.0f; - o->oGravity = 0.0f; - } else - o->oGravity = -4.0f; - if ((o->oTimer & 1) == 0 && o->oTimer < 14) { - sp22 = D_8032F698[o->oBehParams2ndByte].unk3 + (gDebugInfo[4][1] << 8); - sp1C = -(o->oTimer / 2) * 290 + 1740; - vec3f_copy_2(sp24, &o->oPosX); - o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 + 5296) * sp1C; - o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 + 5296) * sp1C; - o->oPosY = 307.0f; - spawn_mist_particles_variable(4, 0, 100.0f); - o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 - 5296) * sp1C; - o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 - 5296) * sp1C; - spawn_mist_particles_variable(4, 0, 100); - vec3f_copy_2(&o->oPosX, sp24); - } - cur_obj_move_using_fvel_and_gravity(); - if (o->oTimer > 300) - obj_mark_for_deletion(o); -} - -void (*sFallingBowserPlatformActions[])(void) = { falling_bowser_plat_act_0, - falling_bowser_plat_act_1, - falling_bowser_plat_act_2 }; - -struct ObjectHitbox sGrowingBowserFlameHitbox = { - /* interactType: */ INTERACT_FLAME, - /* downOffset: */ 20, - /* damageOrCoinValue: */ 1, - /* health: */ 0, - /* numLootCoins: */ 0, - /* radius: */ 10, - /* height: */ 40, - /* hurtboxRadius: */ 0, - /* hurtboxHeight: */ 0, -}; - -struct ObjectHitbox sBowserFlameHitbox = { - /* interactType: */ INTERACT_FLAME, - /* downOffset: */ 0, - /* damageOrCoinValue: */ 1, - /* health: */ 0, - /* numLootCoins: */ 0, - /* radius: */ 10, - /* height: */ 40, - /* hurtboxRadius: */ 0, - /* hurtboxHeight: */ 0, -}; - -f32 D_8032F748[] = { -8.0f, -6.0f, -3.0f }; - -void bhv_falling_bowser_platform_loop(void) { - cur_obj_call_action_function(sFallingBowserPlatformActions); -} - -void bowser_flame_despawn(void) { - obj_mark_for_deletion(o); - spawn_object_with_scale(o, MODEL_NONE, bhvBlackSmokeUpward, 1.0f); - if (random_float() < 0.1) - spawn_object(o, MODEL_YELLOW_COIN, bhvTemporaryYellowCoin); -} - -s32 bowser_flame_should_despawn(s32 maxTime) { - if (maxTime < o->oTimer) - return 1; - if (o->oFloorType == SURFACE_BURNING) - return 1; - if (o->oFloorType == SURFACE_DEATH_PLANE) - return 1; - return 0; -} - -void bhv_flame_bowser_init(void) { - o->oAnimState = (s32)(random_float() * 10.0f); - o->oMoveAngleYaw = random_u16(); - if (random_float() < 0.2) - o->oVelY = 80.0f; - else - o->oVelY = 20.0f; - o->oForwardVel = 10.0f; - o->oGravity = -1.0f; - o->oFlameScale = random_float() + 1.0f; -} - -void bhv_flame_large_burning_out_init(void) { - o->oAnimState = (s32)(random_float() * 10.0f); - o->oMoveAngleYaw = random_u16(); - o->oVelY = 10.0f; - o->oForwardVel = 0.0f; - o->oFlameScale = 7.0f; -} - -void bowser_flame_move(void) { - s32 sp4; - sp4 = ((o->oFlameSpeedTimerOffset + gGlobalTimer) & 0x3F) << 10; - o->oPosX += sins(o->oMoveAngleYaw) * sins(sp4) * 4.0f; - o->oPosZ += coss(o->oMoveAngleYaw) * sins(sp4) * 4.0f; -} - -void bhv_flame_bowser_loop(void) { - cur_obj_update_floor_and_walls(); - cur_obj_move_standard(78); - if (o->oVelY < -4.0f) - o->oVelY = -4.0f; - if (o->oAction == 0) { - cur_obj_become_intangible(); - bowser_flame_move(); - if (o->oMoveFlags & OBJ_MOVE_LANDED) { - o->oAction++; - if (cur_obj_has_behavior(bhvFlameLargeBurningOut)) - o->oFlameScale = 8.0f; - else - o->oFlameScale = random_float() * 2 + 6.0f; - o->oForwardVel = 0; - o->oVelY = 0; - o->oGravity = 0; + // Set layers if object is transparent or not + if (obj->oOpacity == 0xFF) { + graphNode->fnNode.node.flags = (graphNode->fnNode.node.flags & 0xFF) | (LAYER_OPAQUE << 8); + } else { + graphNode->fnNode.node.flags = (graphNode->fnNode.node.flags & 0xFF) | (LAYER_TRANSPARENT << 8); } - } else { - cur_obj_become_tangible(); - if (o->oTimer > o->oFlameScale * 10 + 5.0f) { - o->oFlameScale -= 0.15; - if (o->oFlameScale <= 0) - bowser_flame_despawn(); + gfx = gfxHead = alloc_display_list(2 * sizeof(Gfx)); + // If TRUE, clear lighting to give rainbow color + if (obj->oBowserRainbowLight != 0) { + gSPClearGeometryMode(gfx++, G_LIGHTING); } + gSPEndDisplayList(gfx); } - cur_obj_scale(o->oFlameScale); - o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; - obj_set_hitbox(o, &sBowserFlameHitbox); -} - -void bhv_flame_moving_forward_growing_init(void) { - o->oForwardVel = 30.0f; - obj_translate_xz_random(o, 80.0f); - o->oAnimState = (s32)(random_float() * 10.0f); - o->oFlameScale = 3.0f; -} - -void bhv_flame_moving_forward_growing_loop(void) { - UNUSED s32 unused; - UNUSED struct Object *sp18; - obj_set_hitbox(o, &sGrowingBowserFlameHitbox); - o->oFlameScale = o->oFlameScale + 0.5; - cur_obj_scale(o->oFlameScale); - if (o->oMoveAnglePitch > 0x800) - o->oMoveAnglePitch -= 0x200; - cur_obj_set_pos_via_transform(); - cur_obj_update_floor_height(); - if (o->oFlameScale > 30.0f) - obj_mark_for_deletion(o); - if (o->oPosY < o->oFloorHeight) { - o->oPosY = o->oFloorHeight; - sp18 = spawn_object(o, MODEL_RED_FLAME, bhvFlameBowser); - obj_mark_for_deletion(o); - } -} - -void bhv_flame_floating_landing_init(void) { - o->oAnimState = (s32)(random_float() * 10.0f); - o->oMoveAngleYaw = random_u16(); - if (o->oBehParams2ndByte != 0) - o->oForwardVel = random_float() * 5.0f; - else - o->oForwardVel = random_float() * 70.0f; - o->oVelY = random_float() * 20.0f; - o->oGravity = -1.0f; - o->oFlameSpeedTimerOffset = random_float() * 64.0f; -} - -void bhv_flame_floating_landing_loop(void) { - UNUSED s32 unused; - cur_obj_update_floor_and_walls(); - cur_obj_move_standard(0x4e); - bowser_flame_move(); - if (bowser_flame_should_despawn(900)) - obj_mark_for_deletion(o); - if (o->oVelY < D_8032F748[o->oBehParams2ndByte]) - o->oVelY = D_8032F748[o->oBehParams2ndByte]; - if (o->oMoveFlags & OBJ_MOVE_LANDED) { - if (o->oBehParams2ndByte == 0) - spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut); - else - spawn_object(o, MODEL_NONE, bhvBlueFlamesGroup); //? wonder if they meant MODEL_BLUE_FLAME? - obj_mark_for_deletion(o); - } - o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; -} - -void bhv_blue_bowser_flame_init(void) { - obj_translate_xz_random(o, 80.0f); - o->oAnimState = (s32)(random_float() * 10.0f); - o->oVelY = 7.0f; - o->oForwardVel = 35.0f; - o->oFlameScale = 3.0f; - o->oFlameUnkFC = random_float() * 0.5; - o->oGravity = 1.0f; - o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f); -} - -void bhv_blue_bowser_flame_loop(void) { - s32 i; - obj_set_hitbox(o, &sGrowingBowserFlameHitbox); - if (o->oFlameScale < 16.0f) - o->oFlameScale = o->oFlameScale + 0.5; - cur_obj_scale(o->oFlameScale); - cur_obj_update_floor_and_walls(); - cur_obj_move_standard(0x4e); - if (o->oTimer > 0x14) { - if (o->oBehParams2ndByte == 0) - for (i = 0; i < 3; i++) - spawn_object_relative_with_scale(0, 0, 0, 0, 5.0f, o, MODEL_RED_FLAME, - bhvFlameFloatingLanding); - else { - spawn_object_relative_with_scale(1, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, - bhvFlameFloatingLanding); - spawn_object_relative_with_scale(2, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, - bhvFlameFloatingLanding); - } - obj_mark_for_deletion(o); - } -} - -void bhv_flame_bouncing_init(void) { - o->oAnimState = (s32)(random_float() * 10.0f); - o->oVelY = 30.0f; - o->oForwardVel = 20.0f; - o->oFlameScale = o->header.gfx.scale[0]; - o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f); -} - -void bhv_flame_bouncing_loop(void) { - struct Object *bowser; - if (o->oTimer == 0) - o->oFlameBowser = cur_obj_nearest_object_with_behavior(bhvBowser); - bowser = o->oFlameBowser; - o->oForwardVel = 15.0f; - o->oBounciness = -1.0f; - cur_obj_scale(o->oFlameScale); - obj_set_hitbox(o, &sGrowingBowserFlameHitbox); - cur_obj_update_floor_and_walls(); - cur_obj_move_standard(78); - if (bowser_flame_should_despawn(300)) - obj_mark_for_deletion(o); - if (bowser != NULL) - if (bowser->oHeldState == 0) - if (lateral_dist_between_objects(o, bowser) < 300.0f) - obj_mark_for_deletion(o); -} - -void bhv_blue_flames_group_loop(void) { - struct Object *flame; - s32 i; - if (o->oTimer == 0) { - o->oMoveAngleYaw = obj_angle_to_object(o, gMarioObject); - o->oBlueFlameNextScale = 5.0f; - } - if (o->oTimer < 16) { - if ((o->oTimer & 1) == 0) { - for (i = 0; i < 3; i++) { - flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing); - flame->oMoveAngleYaw += i * 0x5555; - flame->header.gfx.scale[0] = o->oBlueFlameNextScale; - } - o->oBlueFlameNextScale -= 0.5; - } - } else - obj_mark_for_deletion(o); + return gfxHead; } diff --git a/src/game/behaviors/bowser_falling_platform.inc.c b/src/game/behaviors/bowser_falling_platform.inc.c new file mode 100644 index 00000000..0d1e0e43 --- /dev/null +++ b/src/game/behaviors/bowser_falling_platform.inc.c @@ -0,0 +1,90 @@ +struct BowserFallingPlatformData { + const Collision *collision; + s16 posX; + s16 posZ; + s16 angle; +}; + +struct BowserFallingPlatformData sBowserFallingPlatform[] = { + { NULL, 0, 0, 0 }, + { bowser_3_seg7_collision_07004B94, -800, -1000, -20992 }, + { bowser_3_seg7_collision_07004C18, -1158, 390, -18432 }, + { bowser_3_seg7_collision_07004C9C, -1158, 390, -7680 }, + { bowser_3_seg7_collision_07004D20, 0, 1240, -6144 }, + { bowser_3_seg7_collision_07004DA4, 0, 1240, 6144 }, + { bowser_3_seg7_collision_07004E28, 1158, 390, 7680 }, + { bowser_3_seg7_collision_07004EAC, 1158, 390, 18432 }, + { bowser_3_seg7_collision_07004F30, 800, -1000, 20992 }, + { bowser_3_seg7_collision_07004FB4, 800, -1000, -31744 }, + { bowser_3_seg7_collision_07005038, -800, -1000, 31744 } +}; + +void falling_bowser_plat_act_start(void) { + o->oBitsPlatformBowser = cur_obj_nearest_object_with_behavior(bhvBowser); + obj_set_collision_data(o, sBowserFallingPlatform[o->oBehParams2ndByte].collision); + if (o->oBitsPlatformBowser != 0) + o->oAction = BOWSER_BITS_PLAT_ACT_CHECK; +} + +void falling_bowser_plat_act_check(void) { + UNUSED s32 unused; + struct Object *bowser = o->oBitsPlatformBowser; + if (bowser->platform == o) { + if (bowser->oAction == BOWSER_ACT_BIG_JUMP && bowser->oBowserStatus & BOWSER_STATUS_BIG_JUMP) { + o->oAction = BOWSER_BITS_PLAT_ACT_FALL; + } + } + if (bowser->oHealth == 1 && (bowser->oAction == BOWSER_ACT_DANCE || bowser->oHeldState != HELD_FREE)) { + o->oSubAction = 1; + } + if (o->oSubAction == 0) { + o->oBitsPlatformTimer = 0; + } else { + if ((gDebugInfo[4][6] + 20) * (o->oBehParams2ndByte - 1) < o->oBitsPlatformTimer) + o->oAction = BOWSER_BITS_PLAT_ACT_FALL; + o->oBitsPlatformTimer++; + } +} + +void falling_bowser_plat_act_fall(void) { + Vec3f pos; + s16 angle; + f32 val; + UNUSED struct Object *bowser = o->oBitsPlatformBowser; + if (o->oTimer == 0 || o->oTimer == 22) { + cur_obj_play_sound_2(SOUND_GENERAL_BOWSER_PLATFORM_2); + } + if (o->oTimer < 22) { + set_environmental_camera_shake(SHAKE_ENV_FALLING_BITS_PLAT); + o->oVelY = 8.0f; + o->oGravity = 0.0f; + } else + o->oGravity = -4.0f; + if ((o->oTimer & 1) == 0 && o->oTimer < 14) { + angle = sBowserFallingPlatform[o->oBehParams2ndByte].angle + (gDebugInfo[4][1] << 8); + val = -(o->oTimer / 2) * 290 + 1740; + vec3f_copy_2(pos, &o->oPosX); + o->oPosX = sBowserFallingPlatform[o->oBehParams2ndByte].posX + sins(angle + 0x14B0) * val; + o->oPosZ = sBowserFallingPlatform[o->oBehParams2ndByte].posZ + coss(angle + 0x14B0) * val; + o->oPosY = 307.0f; + spawn_mist_particles_variable(4, 0, 100.0f); + o->oPosX = sBowserFallingPlatform[o->oBehParams2ndByte].posX + sins(angle - 0x14B0) * val; + o->oPosZ = sBowserFallingPlatform[o->oBehParams2ndByte].posZ + coss(angle - 0x14B0) * val; + spawn_mist_particles_variable(4, 0, 100); + vec3f_copy_2(&o->oPosX, pos); + } + cur_obj_move_using_fvel_and_gravity(); + if (o->oTimer > 300) { + obj_mark_for_deletion(o); + } +} + +void (*sFallingBowserPlatformActions[])(void) = { + falling_bowser_plat_act_start, + falling_bowser_plat_act_check, + falling_bowser_plat_act_fall, +}; + +void bhv_falling_bowser_platform_loop(void) { + cur_obj_call_action_function(sFallingBowserPlatformActions); +} diff --git a/src/game/behaviors/bowser_flame.inc.c b/src/game/behaviors/bowser_flame.inc.c new file mode 100644 index 00000000..4501d977 --- /dev/null +++ b/src/game/behaviors/bowser_flame.inc.c @@ -0,0 +1,263 @@ +struct ObjectHitbox sGrowingBowserFlameHitbox = { + /* interactType: */ INTERACT_FLAME, + /* downOffset: */ 20, + /* damageOrCoinValue: */ 1, + /* health: */ 0, + /* numLootCoins: */ 0, + /* radius: */ 10, + /* height: */ 40, + /* hurtboxRadius: */ 0, + /* hurtboxHeight: */ 0, +}; + +struct ObjectHitbox sBowserFlameHitbox = { + /* interactType: */ INTERACT_FLAME, + /* downOffset: */ 0, + /* damageOrCoinValue: */ 1, + /* health: */ 0, + /* numLootCoins: */ 0, + /* radius: */ 10, + /* height: */ 40, + /* hurtboxRadius: */ 0, + /* hurtboxHeight: */ 0, +}; + +void bowser_flame_despawn(void) { + obj_mark_for_deletion(o); + spawn_object_with_scale(o, MODEL_NONE, bhvBlackSmokeUpward, 1.0f); + if (random_float() < 0.1) { + spawn_object(o, MODEL_YELLOW_COIN, bhvTemporaryYellowCoin); + } +} + +s32 bowser_flame_should_despawn(s32 maxTime) { + if (maxTime < o->oTimer) { + return TRUE; + } + + // Flames should despawn if they fall off the arena. + if (o->oFloorType == SURFACE_BURNING) { + return TRUE; + } + if (o->oFloorType == SURFACE_DEATH_PLANE) { + return TRUE; + } + + return FALSE; +} + +void bhv_flame_bowser_init(void) { + o->oAnimState = (s32)(random_float() * 10.0f); + o->oMoveAngleYaw = random_u16(); + if (random_float() < 0.2) { + o->oVelY = 80.0f; + } else { + o->oVelY = 20.0f; + } + o->oForwardVel = 10.0f; + o->oGravity = -1.0f; + o->oFlameScale = random_float() + 1.0f; +} + +void bhv_flame_large_burning_out_init(void) { + o->oAnimState = (s32)(random_float() * 10.0f); + o->oMoveAngleYaw = random_u16(); + o->oVelY = 10.0f; + o->oForwardVel = 0.0f; + o->oFlameScale = 7.0f; +} + +void bowser_flame_move(void) { + s32 timer; + timer = ((o->oFlameSpeedTimerOffset + gGlobalTimer) & 0x3F) << 10; + o->oPosX += sins(o->oMoveAngleYaw) * sins(timer) * 4.0f; + o->oPosZ += coss(o->oMoveAngleYaw) * sins(timer) * 4.0f; +} + +void bhv_flame_bowser_loop(void) { + cur_obj_update_floor_and_walls(); + cur_obj_move_standard(78); + if (o->oVelY < -4.0f) { + o->oVelY = -4.0f; + } + if (o->oAction == 0) { + cur_obj_become_intangible(); + bowser_flame_move(); + if (o->oMoveFlags & OBJ_MOVE_LANDED) { + o->oAction++; + if (cur_obj_has_behavior(bhvFlameLargeBurningOut)) { + o->oFlameScale = 8.0f; + } else { + o->oFlameScale = random_float() * 2 + 6.0f; + } + o->oForwardVel = 0; + o->oVelY = 0; + o->oGravity = 0; + } + } else { + cur_obj_become_tangible(); + if (o->oTimer > o->oFlameScale * 10 + 5.0f) { + o->oFlameScale -= 0.15; + if (o->oFlameScale <= 0) { + bowser_flame_despawn(); + } + } + } + cur_obj_scale(o->oFlameScale); + o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; + obj_set_hitbox(o, &sBowserFlameHitbox); +} + +void bhv_flame_moving_forward_growing_init(void) { + o->oForwardVel = 30.0f; + obj_translate_xz_random(o, 80.0f); + o->oAnimState = (s32)(random_float() * 10.0f); + o->oFlameScale = 3.0f; +} + +void bhv_flame_moving_forward_growing_loop(void) { + UNUSED s32 unused; + UNUSED struct Object *flame; + obj_set_hitbox(o, &sGrowingBowserFlameHitbox); + o->oFlameScale = o->oFlameScale + 0.5; + cur_obj_scale(o->oFlameScale); + if (o->oMoveAnglePitch > 0x800) { + o->oMoveAnglePitch -= 0x200; + } + cur_obj_set_pos_via_transform(); + cur_obj_update_floor_height(); + if (o->oFlameScale > 30.0f) { + obj_mark_for_deletion(o); + } + if (o->oPosY < o->oFloorHeight) { + o->oPosY = o->oFloorHeight; + flame = spawn_object(o, MODEL_RED_FLAME, bhvFlameBowser); + obj_mark_for_deletion(o); + } +} + +void bhv_flame_floating_landing_init(void) { + o->oAnimState = (s32)(random_float() * 10.0f); + o->oMoveAngleYaw = random_u16(); + if (o->oBehParams2ndByte != 0) { + o->oForwardVel = random_float() * 5.0f; + } else { + o->oForwardVel = random_float() * 70.0f; + } + o->oVelY = random_float() * 20.0f; + o->oGravity = -1.0f; + o->oFlameSpeedTimerOffset = random_float() * 64.0f; +} + +f32 sFlameFloatingYLimit[] = { -8.0f, -6.0f, -3.0f }; + +void bhv_flame_floating_landing_loop(void) { + UNUSED s32 unused; + cur_obj_update_floor_and_walls(); + cur_obj_move_standard(78); + bowser_flame_move(); + if (bowser_flame_should_despawn(900)) { + obj_mark_for_deletion(o); + } + if (o->oVelY < sFlameFloatingYLimit[o->oBehParams2ndByte]) { + o->oVelY = sFlameFloatingYLimit[o->oBehParams2ndByte]; + } + if (o->oMoveFlags & OBJ_MOVE_LANDED) { + if (o->oBehParams2ndByte == 0) { + spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut); + } else { + spawn_object(o, MODEL_NONE, bhvBlueFlamesGroup); //? wonder if they meant MODEL_BLUE_FLAME? + } + obj_mark_for_deletion(o); + } + o->oGraphYOffset = o->header.gfx.scale[1] * 14.0f; +} + +void bhv_blue_bowser_flame_init(void) { + obj_translate_xz_random(o, 80.0f); + o->oAnimState = (s32)(random_float() * 10.0f); + o->oVelY = 7.0f; + o->oForwardVel = 35.0f; + o->oFlameScale = 3.0f; + o->oFlameUnusedRand = random_float() * 0.5; + o->oGravity = 1.0f; + o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f); +} + +void bhv_blue_bowser_flame_loop(void) { + s32 i; + obj_set_hitbox(o, &sGrowingBowserFlameHitbox); + if (o->oFlameScale < 16.0f) { + o->oFlameScale = o->oFlameScale + 0.5; + } + cur_obj_scale(o->oFlameScale); + cur_obj_update_floor_and_walls(); + cur_obj_move_standard(78); + if (o->oTimer > 0x14) { + if (o->oBehParams2ndByte == 0) { + for (i = 0; i < 3; i++) { + spawn_object_relative_with_scale(0, 0, 0, 0, 5.0f, o, MODEL_RED_FLAME, + bhvFlameFloatingLanding); + } + } else { + spawn_object_relative_with_scale(1, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, + bhvFlameFloatingLanding); + spawn_object_relative_with_scale(2, 0, 0, 0, 8.0f, o, MODEL_BLUE_FLAME, + bhvFlameFloatingLanding); + } + obj_mark_for_deletion(o); + } +} + +void bhv_flame_bouncing_init(void) { + o->oAnimState = (s32)(random_float() * 10.0f); + o->oVelY = 30.0f; + o->oForwardVel = 20.0f; + o->oFlameScale = o->header.gfx.scale[0]; + o->oFlameSpeedTimerOffset = (s32)(random_float() * 64.0f); +} + +void bhv_flame_bouncing_loop(void) { + struct Object *bowser; + if (o->oTimer == 0) { + o->oFlameBowser = cur_obj_nearest_object_with_behavior(bhvBowser); + } + bowser = o->oFlameBowser; + o->oForwardVel = 15.0f; + o->oBounciness = -1.0f; + cur_obj_scale(o->oFlameScale); + obj_set_hitbox(o, &sGrowingBowserFlameHitbox); + cur_obj_update_floor_and_walls(); + cur_obj_move_standard(78); + if (bowser_flame_should_despawn(300)) { + obj_mark_for_deletion(o); + } + if (bowser != NULL) { + if (bowser->oHeldState == HELD_FREE) { + if (lateral_dist_between_objects(o, bowser) < 300.0f) { + obj_mark_for_deletion(o); + } + } + } +} + +void bhv_blue_flames_group_loop(void) { + struct Object *flame; + s32 i; + if (o->oTimer == 0) { + o->oMoveAngleYaw = obj_angle_to_object(o, gMarioObject); + o->oBlueFlameNextScale = 5.0f; + } + if (o->oTimer < 16) { + if ((o->oTimer & 1) == 0) { + for (i = 0; i < 3; i++) { + flame = spawn_object(o, MODEL_BLUE_FLAME, bhvFlameBouncing); + flame->oMoveAngleYaw += i * 0x5555; + flame->header.gfx.scale[0] = o->oBlueFlameNextScale; + } + o->oBlueFlameNextScale -= 0.5; + } + } else { + obj_mark_for_deletion(o); + } +} diff --git a/src/game/behaviors/break_particles.inc.c b/src/game/behaviors/break_particles.inc.c index a5a6a069..c7160ecd 100644 --- a/src/game/behaviors/break_particles.inc.c +++ b/src/game/behaviors/break_particles.inc.c @@ -11,7 +11,7 @@ void spawn_triangle_break_particles(s16 numTris, s16 triModel, f32 triSize, s16 triangle->oFaceAngleYaw = triangle->oMoveAngleYaw; triangle->oFaceAnglePitch = random_u16(); triangle->oVelY = random_f32_around_zero(50.0f); - if (triModel == 138 || triModel == 56) { + if (triModel == MODEL_DIRT_ANIMATION || triModel == MODEL_SL_CRACKED_ICE_CHUNK) { triangle->oAngleVelPitch = 0xF00; triangle->oAngleVelYaw = 0x500; triangle->oForwardVel = 30.0f; diff --git a/src/game/behaviors/breakable_box_small.inc.c b/src/game/behaviors/breakable_box_small.inc.c index bb9a4edd..fe962bf0 100644 --- a/src/game/behaviors/breakable_box_small.inc.c +++ b/src/game/behaviors/breakable_box_small.inc.c @@ -43,7 +43,7 @@ void small_breakable_box_act_move(void) { if (sp1E & 2) { spawn_mist_particles(); - spawn_triangle_break_particles(20, 138, 0.7f, 3); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 0.7f, 3); obj_spawn_yellow_coins(o, 3); create_sound_spawner(SOUND_GENERAL_BREAK_BOX); o->activeFlags = ACTIVE_FLAG_DEACTIVATED; diff --git a/src/game/behaviors/camera_lakitu.inc.c b/src/game/behaviors/camera_lakitu.inc.c index c3e7f441..2b66cff3 100644 --- a/src/game/behaviors/camera_lakitu.inc.c +++ b/src/game/behaviors/camera_lakitu.inc.c @@ -32,7 +32,7 @@ static void camera_lakitu_intro_act_trigger_cutscene(void) { && gMarioObject->oPosZ > -2000.0f && gMarioObject->oPosZ < -177.0f && gMarioObject->oPosZ < -177.0f) // always double check your conditions { - if (set_mario_npc_dialog(2) == 1) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_START) { o->oAction = CAMERA_LAKITU_INTRO_ACT_SPAWN_CLOUD; } } @@ -42,7 +42,7 @@ static void camera_lakitu_intro_act_trigger_cutscene(void) { * Warp up into the air and spawn cloud, then enter the TODO action. */ static void camera_lakitu_intro_act_spawn_cloud(void) { - if (set_mario_npc_dialog(2) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK) { o->oAction = CAMERA_LAKITU_INTRO_ACT_UNK2; o->oPosX = 1800.0f; @@ -63,6 +63,10 @@ static void camera_lakitu_intro_act_spawn_cloud(void) { static void camera_lakitu_intro_act_show_dialog(void) { s16 targetMovePitch; s16 targetMoveYaw; +#ifdef AVOID_UB + targetMovePitch = 0; + targetMoveYaw = 0; +#endif cur_obj_play_sound_1(SOUND_AIR_LAKITU_FLY); @@ -115,7 +119,8 @@ static void camera_lakitu_intro_act_show_dialog(void) { } } } - } else if (cur_obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0, CUTSCENE_DIALOG, DIALOG_034) != 0) { + } else if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_034)) { o->oCameraLakituFinishedDialog = TRUE; } } diff --git a/src/game/behaviors/cannon.inc.c b/src/game/behaviors/cannon.inc.c index 5f55ca83..6a18f18d 100644 --- a/src/game/behaviors/cannon.inc.c +++ b/src/game/behaviors/cannon.inc.c @@ -107,10 +107,6 @@ void (*sOpenedCannonActions[])(void) = { opened_cannon_act_0, opened_cannon_act_ opened_cannon_act_3, opened_cannon_act_4, opened_cannon_act_5, opened_cannon_act_6 }; -u8 unused0EA1FC[] = { 2, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0, 65, 32, 0, 0, - 63, 128, 0, 0, 2, 0, 0, 0, 65, 160, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0, - 65, 160, 0, 0, 63, 128, 0, 0, 8, 0, 0, 0, 65, 32, 0, 0, 63, 128, 0, 0 }; - void bhv_cannon_base_loop(void) { cur_obj_call_action_function(sOpenedCannonActions); if (o->oCannonUnkF8) diff --git a/src/game/behaviors/capswitch.inc.c b/src/game/behaviors/capswitch.inc.c index 65ae62d2..4aa69dbc 100644 --- a/src/game/behaviors/capswitch.inc.c +++ b/src/game/behaviors/capswitch.inc.c @@ -1,12 +1,14 @@ // capswitch.c.inc +UNUSED u8 sCapSwitchText[] = { DIALOG_010, DIALOG_011, DIALOG_012 }; + void cap_switch_act_0(void) { o->oAnimState = o->oBehParams2ndByte; cur_obj_scale(0.5f); o->oPosY += 71.0f; spawn_object_relative_with_scale(0, 0, -71, 0, 0.5f, o, MODEL_CAP_SWITCH_BASE, bhvCapSwitchBase); if (gCurrLevelNum != LEVEL_UNKNOWN_32) { - if (save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte]) { + if (save_file_get_flags() & sCapSaveFlags[o->oBehParams2ndByte]) { o->oAction = 3; o->header.gfx.scale[1] = 0.1f; } else @@ -17,7 +19,7 @@ void cap_switch_act_0(void) { void cap_switch_act_1(void) { if (cur_obj_is_mario_on_platform()) { - save_file_set_flags(D_8032F0C0[o->oBehParams2ndByte]); + save_file_set_flags(sCapSaveFlags[o->oBehParams2ndByte]); o->oAction = 2; cur_obj_play_sound_2(SOUND_GENERAL_ACTIVATE_CAP_SWITCH); } @@ -30,13 +32,17 @@ void cap_switch_act_2(void) { if (o->oTimer == 4) { cur_obj_shake_screen(SHAKE_POS_SMALL); spawn_mist_particles(); - spawn_triangle_break_particles(60, 139, 0.3f, o->oBehParams2ndByte); -#ifdef VERSION_SH + spawn_triangle_break_particles(60, MODEL_CARTOON_STAR, 0.3f, o->oBehParams2ndByte); +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif } } else { - sp1C = cur_obj_update_dialog_with_cutscene(1, 0x0C, CUTSCENE_CAP_SWITCH_PRESS, 0); + //! Neither of these flags are defined in this function so they do nothing. + // On an extra note, there's a specific check for this cutscene and + // there's no dialog defined since the cutscene itself calls the dialog. + sp1C = cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_FRONT, + (DIALOG_FLAG_TEXT_RESPONSE | DIALOG_FLAG_UNK_CAPSWITCH), CUTSCENE_CAP_SWITCH_PRESS, 0); if (sp1C) o->oAction = 3; } diff --git a/src/game/behaviors/chain_chomp.inc.c b/src/game/behaviors/chain_chomp.inc.c index 382be8d7..57afa831 100644 --- a/src/game/behaviors/chain_chomp.inc.c +++ b/src/game/behaviors/chain_chomp.inc.c @@ -256,8 +256,8 @@ static void chain_chomp_released_trigger_cutscene(void) { //! Can delay this if we get into a cutscene-unfriendly action after the // last post ground pound and before this - if (set_mario_npc_dialog(2) == 2 && (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) - && cutscene_object(CUTSCENE_STAR_SPAWN, o) == 1) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK + && (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) && cutscene_object(CUTSCENE_STAR_SPAWN, o) == 1) { o->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_LUNGE_AROUND; o->oTimer = 0; } @@ -342,7 +342,7 @@ static void chain_chomp_released_jump_away(void) { */ static void chain_chomp_released_end_cutscene(void) { if (cutscene_object(CUTSCENE_STAR_SPAWN, o) == -1) { - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN; } } @@ -536,7 +536,7 @@ void bhv_chain_chomp_gate_update(void) { spawn_mist_particles_with_sound(SOUND_GENERAL_WALL_EXPLOSION); set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); spawn_mist_particles_variable(0, 0x7F, 200.0f); - spawn_triangle_break_particles(30, 0x8A, 3.0f, 4); + spawn_triangle_break_particles(30, MODEL_DIRT_ANIMATION, 3.0f, 4); obj_mark_for_deletion(o); } } diff --git a/src/game/behaviors/chuckya.inc.c b/src/game/behaviors/chuckya.inc.c index f9e5dac0..e74fe9c1 100644 --- a/src/game/behaviors/chuckya.inc.c +++ b/src/game/behaviors/chuckya.inc.c @@ -1,5 +1,17 @@ // chuckya.c.inc +struct UnusedChuckyaData { + u8 unk0; + f32 unk4; + f32 unk8; +}; + +struct UnusedChuckyaData sUnusedChuckyaData[] = { { 2, 0.f, 1.f }, + { 2, 10.f, 1.f }, + { 2, 20.f, 1.f }, + { 2, 20.f, 1.f }, + { 8, 10.f, 1.f }}; + void common_anchor_mario_behavior(f32 sp28, f32 sp2C, s32 sp30) { switch (o->parentObj->oChuckyaUnk88) { case 0: @@ -72,6 +84,9 @@ s32 approach_forward_vel(f32 *arr, f32 spC, f32 sp10) { void chuckya_act_0(void) { s32 sp3C; +#ifdef AVOID_UB + sp3C = 0; +#endif UNUSED u8 pad[16]; s32 sp28; if (o->oTimer == 0) @@ -197,7 +212,7 @@ void bhv_chuckya_loop(void) { chuckya_move(); break; case HELD_HELD: - cur_obj_unrender_and_reset_state(2, 0); + cur_obj_unrender_set_action_and_anim(2, 0); break; case HELD_THROWN: case HELD_DROPPED: diff --git a/src/game/behaviors/coin.inc.c b/src/game/behaviors/coin.inc.c index 2aeebca8..ea6b84cd 100644 --- a/src/game/behaviors/coin.inc.c +++ b/src/game/behaviors/coin.inc.c @@ -12,7 +12,7 @@ struct ObjectHitbox sYellowCoinHitbox = { /* hurtboxHeight: */ 0, }; -s16 D_8032F2A4[][2] = { { 0, -150 }, { 0, -50 }, { 0, 50 }, { 0, 150 }, +s16 sCoinArrowPositions[][2] = { { 0, -150 }, { 0, -50 }, { 0, 50 }, { 0, 150 }, { -50, 100 }, { -100, 50 }, { 50, 100 }, { 100, 50 } }; s32 bhv_coin_sparkles_init(void) { @@ -161,8 +161,8 @@ void spawn_coin_in_formation(s32 sp50, s32 sp54) { sp40[1] = sins(sp50 << 13) * 200.0f + 200.0f; break; case 4: - sp40[0] = D_8032F2A4[sp50][0]; - sp40[2] = D_8032F2A4[sp50][1]; + sp40[0] = sCoinArrowPositions[sp50][0]; + sp40[2] = sCoinArrowPositions[sp50][1]; break; } if (sp54 & 0x10) diff --git a/src/game/behaviors/collide_particles.inc.c b/src/game/behaviors/collide_particles.inc.c index ff93a511..9b013699 100644 --- a/src/game/behaviors/collide_particles.inc.c +++ b/src/game/behaviors/collide_particles.inc.c @@ -1,10 +1,10 @@ // collide_particles.c.inc -s16 D_8032F2CC[] = { 0xD000, 0, 0x3000, 0, 0xDE67, 0x2199, - 0x2199, 0x2199, 0xDE67, 0xDE67, 0x2199, 0xDE67 }; +static s16 sTinyTriMovementParams[] = { 0xD000, 0, 0x3000, 0, 0xDE67, 0x2199, + 0x2199, 0x2199, 0xDE67, 0xDE67, 0x2199, 0xDE67 }; -s16 D_8032F2E4[] = { 0xE000, 0, 0, 0, 0x2000, 0, 0xE99A, - 0x1666, 0x1666, 0x1666, 0xE99A, 0xE99A, 0x1666, 0xE99A }; +static s16 sTinyStarMovementParams[] = { 0xE000, 0, 0, 0, 0x2000, 0, 0xE99A, + 0x1666, 0x1666, 0x1666, 0xE99A, 0xE99A, 0x1666, 0xE99A }; void bhv_punch_tiny_triangle_loop(void) { s16 sp1E; @@ -28,9 +28,9 @@ void bhv_punch_tiny_triangle_init(void) { struct Object *triangle; for (i = 0; i < 6; i++) { triangle = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPunchTinyTriangle); - triangle->oMoveAngleYaw = gMarioObject->oMoveAngleYaw + D_8032F2CC[2 * i] + 0x8000; - triangle->oVelY = sins(D_8032F2CC[2 * i + 1]) * 25.0f; - triangle->oForwardVel = coss(D_8032F2CC[2 * i + 1]) * 25.0f; + triangle->oMoveAngleYaw = gMarioObject->oMoveAngleYaw + sTinyTriMovementParams[2 * i] + 0x8000; + triangle->oVelY = sins(sTinyTriMovementParams[2 * i + 1]) * 25.0f; + triangle->oForwardVel = coss(sTinyTriMovementParams[2 * i + 1]) * 25.0f; } } @@ -54,9 +54,9 @@ void bhv_tiny_star_particles_init(void) { struct Object *particle; for (i = 0; i < 7; i++) { particle = spawn_object(o, MODEL_CARTOON_STAR, bhvWallTinyStarParticle); - particle->oMoveAngleYaw = gMarioObject->oMoveAngleYaw + D_8032F2E4[2 * i] + 0x8000; - particle->oVelY = sins(D_8032F2E4[2 * i + 1]) * 25.0f; - particle->oForwardVel = coss(D_8032F2E4[2 * i + 1]) * 25.0f; + particle->oMoveAngleYaw = gMarioObject->oMoveAngleYaw + sTinyStarMovementParams[2 * i] + 0x8000; + particle->oVelY = sins(sTinyStarMovementParams[2 * i + 1]) * 25.0f; + particle->oForwardVel = coss(sTinyStarMovementParams[2 * i + 1]) * 25.0f; } } diff --git a/src/game/behaviors/controllable_platform.inc.c b/src/game/behaviors/controllable_platform.inc.c index 17e8beee..c22fe64d 100644 --- a/src/game/behaviors/controllable_platform.inc.c +++ b/src/game/behaviors/controllable_platform.inc.c @@ -79,7 +79,7 @@ void controllable_platform_hit_wall(s8 sp1B) { D_80331694 = 5; cur_obj_play_sound_2(SOUND_GENERAL_QUIET_POUND1); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(50, 80); #endif } diff --git a/src/game/behaviors/door.inc.c b/src/game/behaviors/door.inc.c index db48e4f9..695e5996 100644 --- a/src/game/behaviors/door.inc.c +++ b/src/game/behaviors/door.inc.c @@ -6,11 +6,11 @@ struct DoorAction s32 action; }; -struct DoorAction D_8032F300[] = { { 0x40000, 3 }, { 0x80000, 4 }, { 0x10000, 1 }, { 0x20000, 2 }, { -1, 0 }, }; +static struct DoorAction sDoorActions[] = { { 0x40000, 3 }, { 0x80000, 4 }, { 0x10000, 1 }, { 0x20000, 2 }, { -1, 0 }, }; -s32 D_8032F328[] = { SOUND_GENERAL_OPEN_WOOD_DOOR, SOUND_GENERAL_OPEN_IRON_DOOR }; +static s32 sDoorOpenSounds[] = { SOUND_GENERAL_OPEN_WOOD_DOOR, SOUND_GENERAL_OPEN_IRON_DOOR }; -s32 D_8032F330[] = { SOUND_GENERAL_CLOSE_WOOD_DOOR, SOUND_GENERAL_CLOSE_IRON_DOOR }; +static s32 sDoorCloseSounds[] = { SOUND_GENERAL_CLOSE_WOOD_DOOR, SOUND_GENERAL_CLOSE_IRON_DOOR }; void door_animation_and_reset(s32 sp18) { cur_obj_init_animation_with_sound(sp18); @@ -29,27 +29,27 @@ void set_door_camera_event(void) { void play_door_open_noise(void) { s32 sp1C = cur_obj_has_model(MODEL_HMC_METAL_DOOR); if (o->oTimer == 0) { - cur_obj_play_sound_2(D_8032F328[sp1C]); + cur_obj_play_sound_2(sDoorOpenSounds[sp1C]); gTimeStopState |= TIME_STOP_MARIO_OPENED_DOOR; } if (o->oTimer == 70) { - cur_obj_play_sound_2(D_8032F330[sp1C]); + cur_obj_play_sound_2(sDoorCloseSounds[sp1C]); } } void play_warp_door_open_noise(void) { s32 sp1C = cur_obj_has_model(MODEL_HMC_METAL_DOOR); if (o->oTimer == 30) - cur_obj_play_sound_2(D_8032F330[sp1C]); + cur_obj_play_sound_2(sDoorCloseSounds[sp1C]); } void bhv_door_loop(void) { s32 sp1C = 0; - while (D_8032F300[sp1C].flag != (u32)~0) { - if (cur_obj_clear_interact_status_flag(D_8032F300[sp1C].flag)) { + while (sDoorActions[sp1C].flag != (u32)~0) { + if (cur_obj_clear_interact_status_flag(sDoorActions[sp1C].flag)) { set_door_camera_event(); - cur_obj_change_action(D_8032F300[sp1C].action); + cur_obj_change_action(sDoorActions[sp1C].action); } sp1C++; } diff --git a/src/game/behaviors/dorrie.inc.c b/src/game/behaviors/dorrie.inc.c index 3eb3c04e..d6d3c8c2 100644 --- a/src/game/behaviors/dorrie.inc.c +++ b/src/game/behaviors/dorrie.inc.c @@ -68,7 +68,8 @@ void dorrie_act_lower_head(void) { if (o->oTimer > 150) { dorrie_begin_head_raise(FALSE); } else if (gMarioObject->platform == o) { - if (o->oDorrieForwardDistToMario > 830.0f && set_mario_npc_dialog(2) == 1) { + if (o->oDorrieForwardDistToMario > 830.0f + && set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_START) { dorrie_begin_head_raise(TRUE); } else if (o->oDorrieForwardDistToMario > 320.0f) { o->oTimer = 0; @@ -77,7 +78,7 @@ void dorrie_act_lower_head(void) { #else if (gMarioObject->platform == o) { if (o->oDorrieOffsetY == -17.0f && o->oDorrieForwardDistToMario > 780.0f - && set_mario_npc_dialog(2) == 1) { + && set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_START) { dorrie_begin_head_raise(TRUE); } else if (o->oDorrieForwardDistToMario > 320.0f) { o->oTimer = 0; @@ -97,10 +98,10 @@ void dorrie_act_raise_head(void) { if (cur_obj_check_if_near_animation_end()) { o->oAction = DORRIE_ACT_MOVE; } else if (o->oDorrieLiftingMario && o->header.gfx.animInfo.animFrame < 74) { - if (set_mario_npc_dialog(2) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK) { o->oDorrieHeadRaiseSpeed += 0x1CC; if (cur_obj_check_anim_frame(73)) { - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); } dorrie_raise_head(); } else { diff --git a/src/game/behaviors/elevator.inc.c b/src/game/behaviors/elevator.inc.c index f9df6856..34369071 100644 --- a/src/game/behaviors/elevator.inc.c +++ b/src/game/behaviors/elevator.inc.c @@ -1,5 +1,13 @@ // elevator.c.inc +static s16 sElevatorHeights[] = { -51, 0, 0, + -461, 0, 0, + -512, 0, 0, + -2611, 0, 0, + -2360, 0, 0, + 214, 0, 0, + -50, 1945, 1 }; + void elevator_starting_shake(void) { cur_obj_play_sound_2(SOUND_GENERAL_QUIET_POUND1); cur_obj_shake_screen(SHAKE_POS_SMALL); @@ -84,15 +92,15 @@ void elevator_act_3(void) // nearly identical to action 2 } void bhv_elevator_init(void) { - s32 sp1C = D_8032F38C[o->oBehParams2ndByte * 3 + 2]; + s32 sp1C = sElevatorHeights[o->oBehParams2ndByte * 3 + 2]; if (sp1C == 0) { - o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3]; + o->oElevatorUnkF4 = sElevatorHeights[o->oBehParams2ndByte * 3]; o->oElevatorUnkF8 = o->oHomeY; o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2; o->oElevatorUnk100 = cur_obj_has_behavior(bhvRrElevatorPlatform); } else { - o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3]; - o->oElevatorUnkF8 = D_8032F38C[o->oBehParams2ndByte * 3 + 1]; + o->oElevatorUnkF4 = sElevatorHeights[o->oBehParams2ndByte * 3]; + o->oElevatorUnkF8 = sElevatorHeights[o->oBehParams2ndByte * 3 + 1]; o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2; o->oElevatorUnk100 = 2; } @@ -101,15 +109,6 @@ void bhv_elevator_init(void) { void (*sElevatorActions[])(void) = { elevator_act_0, elevator_act_1, elevator_act_2, elevator_act_3, elevator_act_4 }; -struct SpawnParticlesInfo D_8032F3CC = { 3, 20, MODEL_MIST, 20, 10, 5, 0, 0, 0, 30, 30.0f, 1.5f }; - -struct SpawnParticlesInfo D_8032F3E0 = { 0, 5, MODEL_SAND_DUST, 0, 0, 20, 20, 0, 252, 30, 5.0f, 2.0f }; - -s16 D_8032F3F4[] = { 2, -8, 1, 4 }; - -struct SpawnParticlesInfo D_8032F3FC = { 0, 5, MODEL_WHITE_PARTICLE_DL, 0, 0, 20, 20, 0, 252, 30, - 2.0f, 2.0f }; - void bhv_elevator_loop(void) { cur_obj_call_action_function(sElevatorActions); } diff --git a/src/game/behaviors/exclamation_box.inc.c b/src/game/behaviors/exclamation_box.inc.c index 86486c35..eed6df0e 100644 --- a/src/game/behaviors/exclamation_box.inc.c +++ b/src/game/behaviors/exclamation_box.inc.c @@ -38,7 +38,7 @@ void bhv_rotating_exclamation_box_loop(void) { void exclamation_box_act_0(void) { if (o->oBehParams2ndByte < 3) { o->oAnimState = o->oBehParams2ndByte; - if ((save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte]) + if ((save_file_get_flags() & sCapSaveFlags[o->oBehParams2ndByte]) || ((o->oBehParams >> 24) & 0xFF) != 0) o->oAction = 2; else @@ -55,7 +55,7 @@ void exclamation_box_act_1(void) { spawn_object(o, MODEL_EXCLAMATION_POINT, bhvRotatingExclamationMark); cur_obj_set_model(MODEL_EXCLAMATION_BOX_OUTLINE); } - if ((save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte]) + if ((save_file_get_flags() & sCapSaveFlags[o->oBehParams2ndByte]) || ((o->oBehParams >> 24) & 0xFF) != 0) { o->oAction = 2; cur_obj_set_model(MODEL_EXCLAMATION_BOX); @@ -78,7 +78,7 @@ void exclamation_box_act_2(void) { o->oGravity = -8.0f; o->oFloorHeight = o->oPosY; o->oAction = 3; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif } @@ -124,7 +124,7 @@ void exclamation_box_spawn_contents(struct Struct802C0DF0 *a0, u8 a1) { void exclamation_box_act_4(void) { exclamation_box_spawn_contents(sExclamationBoxContents, o->oBehParams2ndByte); spawn_mist_particles_variable(0, 0, 46.0f); - spawn_triangle_break_particles(20, 139, 0.3f, o->oAnimState); + spawn_triangle_break_particles(20, MODEL_CARTOON_STAR, 0.3f, o->oAnimState); create_sound_spawner(SOUND_GENERAL_BREAK_BOX); if (o->oBehParams2ndByte < 3) { o->oAction = 5; diff --git a/src/game/behaviors/eyerok.inc.c b/src/game/behaviors/eyerok.inc.c index 473d7475..b22cff34 100644 --- a/src/game/behaviors/eyerok.inc.c +++ b/src/game/behaviors/eyerok.inc.c @@ -63,7 +63,7 @@ static void eyerok_boss_act_wake_up(void) { } static void eyerok_boss_act_show_intro_text(void) { - if (cur_obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_117)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_NONE, CUTSCENE_DIALOG, DIALOG_117)) { o->oAction = EYEROK_BOSS_ACT_FIGHT; } } @@ -117,7 +117,7 @@ static void eyerok_boss_act_fight(void) { static void eyerok_boss_act_die(void) { if (o->oTimer == 60) { - if (cur_obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_118)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_NONE, CUTSCENE_DIALOG, DIALOG_118)) { spawn_default_star(0.0f, -900.0f, -3700.0f); } else { o->oTimer -= 1; diff --git a/src/game/behaviors/falling_rising_platform.inc.c b/src/game/behaviors/falling_rising_platform.inc.c index 4bd7ecd5..faddc2f4 100644 --- a/src/game/behaviors/falling_rising_platform.inc.c +++ b/src/game/behaviors/falling_rising_platform.inc.c @@ -1,15 +1,15 @@ // falling_rising_platform.c.inc void bhv_squishable_platform_loop(void) { - o->header.gfx.scale[1] = (sins(o->oPlatformTimer) + 1.0) * 0.3 + 0.4; - o->oPlatformTimer += 0x80; + o->header.gfx.scale[1] = (sins(o->oBitfsPlatformTimer) + 1.0) * 0.3 + 0.4; + o->oBitfsPlatformTimer += 0x80; } void bhv_bitfs_sinking_platform_loop(void) { o->oPosY -= - sins(o->oPlatformTimer) + sins(o->oBitfsPlatformTimer) * 0.58; //! f32 double conversion error accumulates on Wii VC causing the platform to rise up - o->oPlatformTimer += 0x100; + o->oBitfsPlatformTimer += 0x100; } // TODO: Named incorrectly. fix @@ -21,8 +21,8 @@ void bhv_bitfs_sinking_cage_platform_loop(void) { if (o->oBehParams2ndByte != 0) { if (o->oTimer == 0) o->oPosY -= 300.0f; - o->oPosY += sins(o->oPlatformTimer) * 7.0f; + o->oPosY += sins(o->oBitfsPlatformTimer) * 7.0f; } else - o->oPosY -= sins(o->oPlatformTimer) * 3.0f; - o->oPlatformTimer += 0x100; + o->oPosY -= sins(o->oBitfsPlatformTimer) * 3.0f; + o->oBitfsPlatformTimer += 0x100; } diff --git a/src/game/behaviors/grand_star.inc.c b/src/game/behaviors/grand_star.inc.c index afdf0855..29c71c49 100644 --- a/src/game/behaviors/grand_star.inc.c +++ b/src/game/behaviors/grand_star.inc.c @@ -51,7 +51,7 @@ void bhv_grand_star_loop(void) { o->oPosY = o->oHomeY + 200.0f; grand_star_zero_velocity(); gObjCutsceneDone = 1; - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); o->oAction++; o->oInteractStatus = 0; cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR_JUMP); diff --git a/src/game/behaviors/ground_particles.inc.c b/src/game/behaviors/ground_particles.inc.c index 26dd285a..c7259311 100644 --- a/src/game/behaviors/ground_particles.inc.c +++ b/src/game/behaviors/ground_particles.inc.c @@ -1,25 +1,34 @@ // ground_particles.c.inc +static struct SpawnParticlesInfo sGlobalMistParticles = { 3, 20, MODEL_MIST, 20, 10, 5, 0, 0, 0, 30, 30.0f, 1.5f }; + +static struct SpawnParticlesInfo sSandParticles = { 0, 5, MODEL_SAND_DUST, 0, 0, 20, 20, 0, 252, 30, 5.0f, 2.0f }; + +static s16 sSmokeMovementParams[] = { 2, -8, 1, 4 }; + +static struct SpawnParticlesInfo sSnowParticles = { 0, 5, MODEL_WHITE_PARTICLE_DL, 0, 0, 20, 20, 0, 252, 30, + 2.0f, 2.0f }; + void bhv_pound_white_puffs_init(void) { clear_particle_flags(0x8000); spawn_mist_from_global(); } void spawn_mist_from_global(void) { - cur_obj_spawn_particles(&D_8032F3CC); + cur_obj_spawn_particles(&sGlobalMistParticles); } void bhv_ground_sand_init(void) { clear_particle_flags(0x4000); - cur_obj_spawn_particles(&D_8032F3E0); + cur_obj_spawn_particles(&sSandParticles); } void spawn_smoke_with_velocity(void) { struct Object *smoke = spawn_object_with_scale(o, MODEL_SMOKE, bhvWhitePuffSmoke2, 1.0f); - smoke->oForwardVel = D_8032F3F4[0]; - smoke->oVelY = D_8032F3F4[1]; - smoke->oGravity = D_8032F3F4[2]; - obj_translate_xyz_random(smoke, D_8032F3F4[3]); + smoke->oForwardVel = sSmokeMovementParams[0]; + smoke->oVelY = sSmokeMovementParams[1]; + smoke->oGravity = sSmokeMovementParams[2]; + obj_translate_xyz_random(smoke, sSmokeMovementParams[3]); } // TODO Fix name @@ -29,5 +38,5 @@ void clear_particle_flags(u32 flags) { void bhv_ground_snow_init(void) { clear_particle_flags(1 << 16); - cur_obj_spawn_particles(&D_8032F3FC); + cur_obj_spawn_particles(&sSnowParticles); } diff --git a/src/game/behaviors/heave_ho.inc.c b/src/game/behaviors/heave_ho.inc.c index 9afe9c58..74daefeb 100644 --- a/src/game/behaviors/heave_ho.inc.c +++ b/src/game/behaviors/heave_ho.inc.c @@ -111,7 +111,7 @@ void bhv_heave_ho_loop(void) { heave_ho_move(); break; case HELD_HELD: - cur_obj_unrender_and_reset_state(0, 0); + cur_obj_unrender_set_action_and_anim(0, 0); break; case HELD_THROWN: cur_obj_get_dropped(); diff --git a/src/game/behaviors/hoot.inc.c b/src/game/behaviors/hoot.inc.c index f43f0ffd..95692e58 100644 --- a/src/game/behaviors/hoot.inc.c +++ b/src/game/behaviors/hoot.inc.c @@ -225,7 +225,7 @@ void hoot_turn_to_home(void) { } void hoot_awake_loop(void) { - if (o->oInteractStatus == INT_STATUS_HOOT_GRABBED_BY_MARIO) { + if (o->oInteractStatus == TRUE) { //! Note: Not a flag, treated as a TRUE/FALSE statement hoot_action_loop(); cur_obj_init_animation(1); } else { @@ -254,8 +254,9 @@ void bhv_hoot_loop(void) { case HOOT_AVAIL_WANTS_TO_TALK: hoot_awake_loop(); - if (set_mario_npc_dialog(2) == 2 && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_044)) { - set_mario_npc_dialog(0); + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK + && cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_044)) { + set_mario_npc_dialog(MARIO_DIALOG_STOP); cur_obj_become_tangible(); diff --git a/src/game/behaviors/intro_peach.inc.c b/src/game/behaviors/intro_peach.inc.c index 2838a910..37b40301 100644 --- a/src/game/behaviors/intro_peach.inc.c +++ b/src/game/behaviors/intro_peach.inc.c @@ -40,7 +40,7 @@ void bhv_intro_peach_loop(void) { case 2: intro_peach_set_pos_and_opacity(gCurrentObject, 255.f, 3.f); - if ((gCurrentObject->oTimer > 100) && (get_dialog_id() == -1)) + if ((gCurrentObject->oTimer > 100) && (get_dialog_id() == DIALOG_NONE)) gCurrentObject->oAction += 1; break; case 3: diff --git a/src/game/behaviors/jumping_box.inc.c b/src/game/behaviors/jumping_box.inc.c index 287d7377..5c86169d 100644 --- a/src/game/behaviors/jumping_box.inc.c +++ b/src/game/behaviors/jumping_box.inc.c @@ -52,7 +52,7 @@ void bhv_jumping_box_loop(void) { case HELD_HELD: obj_copy_pos(o, gMarioObject); cur_obj_set_model(MODEL_BREAKABLE_BOX_SMALL); - cur_obj_unrender_and_reset_state(-1, 0); + cur_obj_unrender_set_action_and_anim(-1, 0); break; case HELD_THROWN: cur_obj_get_thrown_or_placed(40.0f, 20.0f, 1); diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index b8a54aa6..7741c64b 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -35,7 +35,8 @@ void king_bobomb_act_0(void) { o->oSubAction++; seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); } - } else if (cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_017)) { + } else if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_017)) { o->oAction = 2; o->oFlags |= OBJ_FLAG_HOLDABLE; } @@ -170,12 +171,13 @@ void king_bobomb_act_6(void) { void king_bobomb_act_7(void) { cur_obj_init_animation_with_sound(2); - if (cur_obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG, DIALOG_116)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TEXT_DEFAULT, CUTSCENE_DIALOG, DIALOG_116)) { create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH); cur_obj_hide(); cur_obj_become_intangible(); spawn_mist_particles_variable(0, 0, 200.0f); - spawn_triangle_break_particles(20, 138, 3.0f, 4); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 3.0f, 4); cur_obj_shake_screen(SHAKE_POS_SMALL); #ifndef VERSION_JP cur_obj_spawn_star_at_y_offset(2000.0f, 4500.0f, -4500.0f, 200.0f); @@ -262,7 +264,8 @@ void king_bobomb_act_5(void) { // bobomb returns home o->oSubAction++; break; case 4: - if (cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_128)) + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_128)) o->oAction = 2; break; } @@ -311,7 +314,7 @@ void bhv_king_bobomb_loop(void) { king_bobomb_move(); break; case HELD_HELD: - cur_obj_unrender_and_reset_state(6, 1); + cur_obj_unrender_set_action_and_anim(6, 1); break; case HELD_THROWN: case HELD_DROPPED: diff --git a/src/game/behaviors/koopa.inc.c b/src/game/behaviors/koopa.inc.c index 49c1c2dc..8e3e8779 100644 --- a/src/game/behaviors/koopa.inc.c +++ b/src/game/behaviors/koopa.inc.c @@ -482,7 +482,7 @@ s32 obj_begin_race(s32 noTimer) { } // Unfreeze mario and disable time stop to begin the race - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); disable_time_stop_including_mario(); } else if (o->oTimer > 50) { return TRUE; @@ -518,7 +518,7 @@ static void koopa_the_quick_act_show_init_text(void) { s32 response = obj_update_race_proposition_dialog( sKoopaTheQuickProperties[o->oKoopaTheQuickRaceIndex].initText); - if (response == 1) { + if (response == DIALOG_RESPONSE_YES) { UNUSED s32 unused; gMarioShotFromCannon = FALSE; @@ -531,7 +531,7 @@ static void koopa_the_quick_act_show_init_text(void) { o->oKoopaTurningAwayFromWall = FALSE; o->oFlags |= OBJ_FLAG_ACTIVE_FROM_AFAR; - } else if (response == 2) { + } else if (response == DIALOG_RESPONSE_NO) { o->oAction = KOOPA_THE_QUICK_ACT_WAIT_BEFORE_RACE; o->oKoopaTheQuickInitTextboxCooldown = 60; } @@ -707,7 +707,7 @@ static void koopa_the_quick_act_stop(void) { static void koopa_the_quick_act_after_race(void) { cur_obj_init_animation_with_sound(7); - if (o->parentObj->oKoopaRaceEndpointUnk100 == 0) { + if (o->parentObj->oKoopaRaceEndpointDialog == 0) { if (cur_obj_can_mario_activate_textbox_2(400.0f, 400.0f)) { stop_background_music(SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE)); @@ -717,23 +717,24 @@ static void koopa_the_quick_act_after_race(void) { if (o->parentObj->oKoopaRaceEndpointRaceStatus < 0) { // Mario cheated o->parentObj->oKoopaRaceEndpointRaceStatus = 0; - o->parentObj->oKoopaRaceEndpointUnk100 = DIALOG_006; + o->parentObj->oKoopaRaceEndpointDialog = DIALOG_006; } else { // Mario won - o->parentObj->oKoopaRaceEndpointUnk100 = + o->parentObj->oKoopaRaceEndpointDialog = sKoopaTheQuickProperties[o->oKoopaTheQuickRaceIndex].winText; } } else { // KtQ won - o->parentObj->oKoopaRaceEndpointUnk100 = DIALOG_041; + o->parentObj->oKoopaRaceEndpointDialog = DIALOG_041; } o->oFlags &= ~OBJ_FLAG_ACTIVE_FROM_AFAR; } - } else if (o->parentObj->oKoopaRaceEndpointUnk100 > 0) { - s32 dialogResponse = cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, o->parentObj->oKoopaRaceEndpointUnk100); + } else if (o->parentObj->oKoopaRaceEndpointDialog > 0) { + s32 dialogResponse = cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, o->parentObj->oKoopaRaceEndpointDialog); if (dialogResponse != 0) { - o->parentObj->oKoopaRaceEndpointUnk100 = -1; + o->parentObj->oKoopaRaceEndpointDialog = DIALOG_NONE; o->oTimer = 0; } } else if (o->parentObj->oKoopaRaceEndpointRaceStatus != 0) { diff --git a/src/game/behaviors/koopa_shell_underwater.inc.c b/src/game/behaviors/koopa_shell_underwater.inc.c index ff0eef70..7d670ab5 100644 --- a/src/game/behaviors/koopa_shell_underwater.inc.c +++ b/src/game/behaviors/koopa_shell_underwater.inc.c @@ -22,7 +22,7 @@ void bhv_koopa_shell_underwater_loop(void) { set_koopa_shell_underwater_hitbox(); break; case HELD_HELD: - cur_obj_unrender_and_reset_state(-1, 0); + cur_obj_unrender_set_action_and_anim(-1, 0); break; case HELD_THROWN: case HELD_DROPPED: diff --git a/src/game/behaviors/manta_ray.inc.c b/src/game/behaviors/manta_ray.inc.c index 4b79abc3..5e1c27ff 100644 --- a/src/game/behaviors/manta_ray.inc.c +++ b/src/game/behaviors/manta_ray.inc.c @@ -43,6 +43,9 @@ void bhv_manta_ray_init(void) { static void manta_ray_move(void) { s16 animFrame; s32 pathStatus; +#ifdef AVOID_UB + pathStatus = 0; +#endif animFrame = o->header.gfx.animInfo.animFrame; gCurrentObject->oPathedStartWaypoint = (struct Waypoint *) sMantaRayTraj; @@ -53,7 +56,7 @@ static void manta_ray_move(void) { o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oMantaTargetYaw, 0x80); o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, o->oMantaTargetPitch, 0x80); - + // This causes the ray to tilt as it turns. if ((s16) o->oMantaTargetYaw != (s16) o->oMoveAngleYaw) { o->oMoveAngleRoll -= 91; diff --git a/src/game/behaviors/mips.inc.c b/src/game/behaviors/mips.inc.c index 980457eb..461e9f2a 100644 --- a/src/game/behaviors/mips.inc.c +++ b/src/game/behaviors/mips.inc.c @@ -113,6 +113,9 @@ void bhv_mips_act_follow_path(void) { s32 followStatus; struct Waypoint **pathBase; struct Waypoint *waypoint; +#ifdef AVOID_UB + followStatus = 0; +#endif // Retrieve current waypoint. pathBase = segmented_to_virtual(&inside_castle_seg7_trajectory_mips); @@ -239,13 +242,13 @@ void bhv_mips_held(void) { else dialogID = DIALOG_162; - if (set_mario_npc_dialog(1) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_FRONT) == MARIO_DIALOG_STATUS_SPEAK) { o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID)) { o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; o->oMipsStarStatus = MIPS_STAR_STATUS_SHOULD_SPAWN_STAR; - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); } } } diff --git a/src/game/behaviors/mushroom_1up.inc.c b/src/game/behaviors/mushroom_1up.inc.c index 1466802d..aac7c98d 100644 --- a/src/game/behaviors/mushroom_1up.inc.c +++ b/src/game/behaviors/mushroom_1up.inc.c @@ -7,7 +7,7 @@ void bhv_1up_interact(void) { play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); gMarioState->numLives++; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif } diff --git a/src/game/behaviors/purple_switch.inc.c b/src/game/behaviors/purple_switch.inc.c index 912f7c00..a90483aa 100644 --- a/src/game/behaviors/purple_switch.inc.c +++ b/src/game/behaviors/purple_switch.inc.c @@ -32,7 +32,7 @@ void bhv_purple_switch_loop(void) { cur_obj_play_sound_2(SOUND_GENERAL2_PURPLE_SWITCH); o->oAction = PURPLE_SWITCH_TICKING; cur_obj_shake_screen(SHAKE_POS_SMALL); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif } diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c index 5aeeb257..a287229d 100644 --- a/src/game/behaviors/racing_penguin.inc.c +++ b/src/game/behaviors/racing_penguin.inc.c @@ -27,7 +27,7 @@ static void racing_penguin_act_wait_for_mario(void) { static void racing_penguin_act_show_init_text(void) { s32 response = obj_update_race_proposition_dialog(sRacingPenguinData[o->oBehParams2ndByte].text); - if (response == 1) { + if (response == DIALOG_RESPONSE_YES) { struct Object *child; child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine); @@ -42,7 +42,7 @@ static void racing_penguin_act_show_init_text(void) { o->oAction = RACING_PENGUIN_ACT_PREPARE_FOR_RACE; o->oVelY = 60.0f; - } else if (response == 2) { + } else if (response == DIALOG_RESPONSE_NO) { o->oAction = RACING_PENGUIN_ACT_WAIT_FOR_MARIO; o->oRacingPenguinInitTextCooldown = 60; } @@ -143,7 +143,8 @@ static void racing_penguin_act_show_final_text(void) { o->oForwardVel = 4.0f; } } else if (o->oRacingPenguinFinalTextbox > 0) { - if ((textResult = cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, o->oRacingPenguinFinalTextbox)) != 0) { + if ((textResult = cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, o->oRacingPenguinFinalTextbox))) { o->oRacingPenguinFinalTextbox = -1; o->oTimer = 0; } diff --git a/src/game/behaviors/rotating_octagonal_plat.inc.c b/src/game/behaviors/rotating_octagonal_plat.inc.c index 86d758c8..2126c944 100644 --- a/src/game/behaviors/rotating_octagonal_plat.inc.c +++ b/src/game/behaviors/rotating_octagonal_plat.inc.c @@ -1,15 +1,15 @@ // rotating_octagonal_plat.inc.c -void const *D_80331A44[] = { +static const Collision *sOctagonalPlatformCollision[] = { bits_seg7_collision_0701AA84, rr_seg7_collision_07029508, }; -s16 D_80331A4C[] = { 300, -300, 600, -600 }; +static s16 sOctagonalPlatformAngularVelocities[] = { 300, -300, 600, -600 }; void bhv_rotating_octagonal_plat_init(void) { - o->collisionData = segmented_to_virtual(D_80331A44[(u8)(o->oBehParams >> 16)]); - o->oAngleVelYaw = D_80331A4C[(u8)(o->oBehParams >> 24)]; + o->collisionData = segmented_to_virtual(sOctagonalPlatformCollision[(u8)(o->oBehParams >> 16)]); + o->oAngleVelYaw = sOctagonalPlatformAngularVelocities[(u8)(o->oBehParams >> 24)]; } void bhv_rotating_octagonal_plat_loop(void) { diff --git a/src/game/behaviors/shock_wave.inc.c b/src/game/behaviors/shock_wave.inc.c index c714e91a..9665f997 100644 --- a/src/game/behaviors/shock_wave.inc.c +++ b/src/game/behaviors/shock_wave.inc.c @@ -1,25 +1,38 @@ // shock_wave.c.inc -f32 D_8032F420[] = { 1.9f, 2.4f, 4.0f, 4.8f }; +/** + * Shockwave scale distance hit points + */ +f32 sBowserShockwaveHitPoints[] = { 1.9f, 2.4f, 4.0f, 4.8f }; +/** + * Bowser's shockwave attack main loop + */ void bhv_bowser_shock_wave_loop(void) { - f32 sp2C, sp28, sp24, sp20; - s16 sp1E = 70; - o->oBowserShockWaveUnkF4 = o->oTimer * 10; - cur_obj_scale(o->oBowserShockWaveUnkF4); + f32 distMin1, distMax1, distMin2, distMax2; + s16 fadeFrames = 70; + // Scale shockwave as the timer goes on + o->oBowserShockWaveScale = o->oTimer * 10; + cur_obj_scale(o->oBowserShockWaveScale); + // Slightly reduce opacity each 3 frames if (gGlobalTimer % 3) o->oOpacity -= 1; - if (o->oTimer > sp1E) + // Reduce opacity faster after 70 frames have passed + if (o->oTimer > fadeFrames) o->oOpacity -= 5; + // Delete object when it's fully transparent if (o->oOpacity <= 0) obj_mark_for_deletion(o); - if (o->oTimer < sp1E && mario_is_in_air_action() == 0) { - sp2C = o->oBowserShockWaveUnkF4 * D_8032F420[0]; - sp28 = o->oBowserShockWaveUnkF4 * D_8032F420[1]; - sp24 = o->oBowserShockWaveUnkF4 * D_8032F420[2]; - sp20 = o->oBowserShockWaveUnkF4 * D_8032F420[3]; - if ((sp2C < o->oDistanceToMario && o->oDistanceToMario < sp28) - || (sp24 < o->oDistanceToMario && o->oDistanceToMario < sp20)) - gMarioObject->oInteractStatus |= INT_STATUS_HIT_BY_SHOCKWAVE; + // If object times is less than 70 frame and Mario is not in the air... + if (o->oTimer < fadeFrames && mario_is_in_air_action() == 0) { + // ..define distance values depending of the scale multiplied by hit points + distMin1 = o->oBowserShockWaveScale * sBowserShockwaveHitPoints[0]; + distMax1 = o->oBowserShockWaveScale * sBowserShockwaveHitPoints[1]; + distMin2 = o->oBowserShockWaveScale * sBowserShockwaveHitPoints[2]; + distMax2 = o->oBowserShockWaveScale * sBowserShockwaveHitPoints[3]; + // If Mario is in between distMin and distMax values, shock him + if ((distMin1 < o->oDistanceToMario && o->oDistanceToMario < distMax1) + || (distMin2 < o->oDistanceToMario && o->oDistanceToMario < distMax2)) + gMarioObject->oInteractStatus |= INT_STATUS_MARIO_SHOCKWAVE; } } diff --git a/src/game/behaviors/sl_snowman_wind.inc.c b/src/game/behaviors/sl_snowman_wind.inc.c index 7d84258b..508615ab 100644 --- a/src/game/behaviors/sl_snowman_wind.inc.c +++ b/src/game/behaviors/sl_snowman_wind.inc.c @@ -21,7 +21,7 @@ void bhv_sl_snowman_wind_loop(void) { // Mario has come close, begin dialog. } else if (o->oSubAction == SL_SNOWMAN_WIND_ACT_TALKING) { - if (cur_obj_update_dialog(2, 2, DIALOG_153, 0)) + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_TEXT_DEFAULT, DIALOG_153, 0)) o->oSubAction++; // Blowing, spawn wind particles (SL_SNOWMAN_WIND_ACT_BLOWING) diff --git a/src/game/behaviors/snowman.inc.c b/src/game/behaviors/snowman.inc.c index 97374f93..2d532efe 100644 --- a/src/game/behaviors/snowman.inc.c +++ b/src/game/behaviors/snowman.inc.c @@ -54,6 +54,9 @@ void snowmans_bottom_act_1(void) { UNUSED s16 sp26; s32 sp20; UNUSED s16 sp1E; +#ifdef AVOID_UB + sp20 = 0; +#endif o->oPathedStartWaypoint = segmented_to_virtual(&ccm_seg7_trajectory_snowman); sp26 = object_step_without_floor_orient(); @@ -125,12 +128,12 @@ void bhv_snowmans_bottom_loop(void) { switch (o->oAction) { case 0: if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 400) == 1 - && set_mario_npc_dialog(1) == 2) { + && set_mario_npc_dialog(MARIO_DIALOG_LOOK_FRONT) == MARIO_DIALOG_STATUS_SPEAK) { sp1E = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_110); if (sp1E) { o->oForwardVel = 10.0f; o->oAction = 1; - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); } } break; @@ -191,7 +194,7 @@ void bhv_snowmans_head_loop(void) { switch (o->oAction) { case 0: - if (trigger_obj_dialog_when_facing(&o->oSnowmansHeadUnkF4, DIALOG_109, 400.0f, 1)) + if (trigger_obj_dialog_when_facing(&o->oSnowmansHeadDialogActive, DIALOG_109, 400.0f, MARIO_DIALOG_LOOK_FRONT)) o->oAction = 1; break; @@ -215,7 +218,7 @@ void bhv_snowmans_head_loop(void) { break; case 4: - if (trigger_obj_dialog_when_facing(&o->oSnowmansHeadUnkF4, DIALOG_111, 700.0f, 2)) { + if (trigger_obj_dialog_when_facing(&o->oSnowmansHeadDialogActive, DIALOG_111, 700.0f, MARIO_DIALOG_LOOK_UP)) { spawn_mist_particles(); spawn_default_star(-4700.0f, -1024.0f, 1890.0f); o->oAction = 1; diff --git a/src/game/behaviors/spawn_star.inc.c b/src/game/behaviors/spawn_star.inc.c index 9a194a5c..b48c3e47 100644 --- a/src/game/behaviors/spawn_star.inc.c +++ b/src/game/behaviors/spawn_star.inc.c @@ -123,18 +123,27 @@ struct Object *spawn_star(struct Object *sp30, f32 sp34, f32 sp38, f32 sp3C) { void spawn_default_star(f32 sp20, f32 sp24, f32 sp28) { struct Object *sp1C; +#ifdef AVOID_UB + sp1C = 0; +#endif sp1C = spawn_star(sp1C, sp20, sp24, sp28); sp1C->oBehParams2ndByte = 0; } void spawn_red_coin_cutscene_star(f32 sp20, f32 sp24, f32 sp28) { struct Object *sp1C; +#ifdef AVOID_UB + sp1C = 0; +#endif sp1C = spawn_star(sp1C, sp20, sp24, sp28); sp1C->oBehParams2ndByte = 1; } void spawn_no_exit_star(f32 sp20, f32 sp24, f32 sp28) { struct Object *sp1C; +#ifdef AVOID_UB + sp1C = 0; +#endif sp1C = spawn_star(sp1C, sp20, sp24, sp28); sp1C->oBehParams2ndByte = 1; sp1C->oInteractionSubtype |= INT_SUBTYPE_NO_EXIT; diff --git a/src/game/behaviors/star_door.inc.c b/src/game/behaviors/star_door.inc.c index 2d7dad1f..67f52701 100644 --- a/src/game/behaviors/star_door.inc.c +++ b/src/game/behaviors/star_door.inc.c @@ -1,8 +1,8 @@ // star_door.c.inc void star_door_update_pos(void) { - o->oVelX = (o->oUnkBC) * coss(o->oMoveAngleYaw); - o->oVelZ = (o->oUnkBC) * -sins(o->oMoveAngleYaw); + o->oVelX = (o->oLeftVel) * coss(o->oMoveAngleYaw); + o->oVelZ = (o->oLeftVel) * -sins(o->oMoveAngleYaw); o->oPosX += o->oVelX; o->oPosZ += o->oVelZ; } @@ -22,12 +22,12 @@ void bhv_star_door_loop(void) { case 1: if (o->oTimer == 0 && (s16)(o->oMoveAngleYaw) >= 0) { cur_obj_play_sound_2(SOUND_GENERAL_STAR_DOOR_OPEN); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(35, 30); #endif } cur_obj_become_intangible(); - o->oUnkBC = -8.0f; + o->oLeftVel = -8.0f; star_door_update_pos(); if (o->oTimer >= 16) o->oAction++; @@ -39,11 +39,11 @@ void bhv_star_door_loop(void) { case 3: if (o->oTimer == 0 && (s16)(o->oMoveAngleYaw) >= 0) { cur_obj_play_sound_2(SOUND_GENERAL_STAR_DOOR_CLOSE); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(35, 30); #endif } - o->oUnkBC = 8.0f; + o->oLeftVel = 8.0f; star_door_update_pos(); if (o->oTimer >= 16) o->oAction++; diff --git a/src/game/behaviors/switch_hidden_objects.inc.c b/src/game/behaviors/switch_hidden_objects.inc.c index e159700f..09875866 100644 --- a/src/game/behaviors/switch_hidden_objects.inc.c +++ b/src/game/behaviors/switch_hidden_objects.inc.c @@ -54,7 +54,7 @@ void hidden_breakable_box_actions(void) { o->oAction = 0; if (cur_obj_was_attacked_or_ground_pounded()) { spawn_mist_particles(); - spawn_triangle_break_particles(30, 138, 3.0f, 4); + spawn_triangle_break_particles(30, MODEL_DIRT_ANIMATION, 3.0f, 4); o->oAction++; cur_obj_play_sound_2(SOUND_GENERAL_BREAK_BOX); } diff --git a/src/game/behaviors/thi_top.inc.c b/src/game/behaviors/thi_top.inc.c index 23c97a06..727020d0 100644 --- a/src/game/behaviors/thi_top.inc.c +++ b/src/game/behaviors/thi_top.inc.c @@ -1,11 +1,9 @@ // thi_top.c.inc -struct SpawnParticlesInfo D_8032F134 = { +struct SpawnParticlesInfo sThiTopPuffs = { 0, 30, MODEL_WHITE_PARTICLE_SMALL, 0, 40, 0, 20, 40, 252, 30, 20.0f, 0.0f }; -UNUSED u8 unused8032F134[] = { 10, 11, 12 }; - void bhv_thi_huge_island_top_loop(void) { if (gTHIWaterDrained & 1) { if (o->oTimer == 0) @@ -21,8 +19,8 @@ void bhv_thi_tiny_island_top_loop(void) { if (o->oDistanceToMario < 500.0f) if (gMarioStates[0].action == ACT_GROUND_POUND_LAND) { o->oAction++; - cur_obj_spawn_particles(&D_8032F134); - spawn_triangle_break_particles(20, 138, 0.3f, 3); + cur_obj_spawn_particles(&sThiTopPuffs); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 0.3f, 3); cur_obj_play_sound_2(SOUND_GENERAL_ACTIVATE_CAP_SWITCH); cur_obj_hide(); } diff --git a/src/game/behaviors/tox_box.inc.c b/src/game/behaviors/tox_box.inc.c index 2bbb40bf..1b50d26e 100644 --- a/src/game/behaviors/tox_box.inc.c +++ b/src/game/behaviors/tox_box.inc.c @@ -17,7 +17,7 @@ void tox_box_move(f32 forwardVel, f32 a1, s16 deltaPitch, s16 deltaRoll) { o->oPosY = 99.41124 * sins((f32)(o->oTimer + 1) / 8 * 0x8000) + o->oHomeY + 3.0f; o->oForwardVel = forwardVel; - o->oUnkC0 = a1; + o->oUpVel = a1; o->oFaceAnglePitch += deltaPitch; if ((s16) o->oFaceAnglePitch < 0) deltaRoll = -deltaRoll; diff --git a/src/game/behaviors/treasure_chest.inc.c b/src/game/behaviors/treasure_chest.inc.c index 938a7581..34b855e9 100644 --- a/src/game/behaviors/treasure_chest.inc.c +++ b/src/game/behaviors/treasure_chest.inc.c @@ -136,7 +136,7 @@ void bhv_treasure_chest_ship_loop(void) { gEnvironmentRegions[6] = -335; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers_2(2); #endif } diff --git a/src/game/behaviors/tree_particles.inc.c b/src/game/behaviors/tree_particles.inc.c index 6c5587ff..31ae803a 100644 --- a/src/game/behaviors/tree_particles.inc.c +++ b/src/game/behaviors/tree_particles.inc.c @@ -10,11 +10,11 @@ void bhv_tree_snow_or_leaf_loop(void) { } if (o->oPosY < o->oFloorHeight) obj_mark_for_deletion(o); - if (o->oFloorHeight < -11000.0f) + if (o->oFloorHeight < FLOOR_LOWER_LIMIT) obj_mark_for_deletion(o); if (o->oTimer > 100) obj_mark_for_deletion(o); - if (gPrevFrameObjectCount > 212) + if (gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY - 28)) obj_mark_for_deletion(o); o->oFaceAnglePitch += o->oAngleVelPitch; o->oFaceAngleRoll += o->oAngleVelRoll; diff --git a/src/game/behaviors/tumbling_bridge.inc.c b/src/game/behaviors/tumbling_bridge.inc.c index ffe02a12..0879e7c4 100644 --- a/src/game/behaviors/tumbling_bridge.inc.c +++ b/src/game/behaviors/tumbling_bridge.inc.c @@ -104,9 +104,6 @@ void tumbling_bridge_act_0(void) { void (*sTumblingBridgeActions[])(void) = { tumbling_bridge_act_0, tumbling_bridge_act_1, tumbling_bridge_act_2, tumbling_bridge_act_3 }; -s16 D_8032F38C[] = { -51, 0, 0, -461, 0, 0, -512, 0, 0, -2611, 0, - 0, -2360, 0, 0, 214, 0, 0, -50, 1945, 1, 0 }; - void bhv_tumbling_bridge_loop(void) { cur_obj_call_action_function(sTumblingBridgeActions); } diff --git a/src/game/behaviors/tuxie.inc.c b/src/game/behaviors/tuxie.inc.c index 1dae5850..d0713644 100644 --- a/src/game/behaviors/tuxie.inc.c +++ b/src/game/behaviors/tuxie.inc.c @@ -54,7 +54,8 @@ void tuxies_mother_act_1(void) { dialogID = DIALOG_058; else dialogID = DIALOG_059; - if (cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, dialogID)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, dialogID)) { if (dialogID == DIALOG_058) o->oSubAction = 1; else @@ -117,7 +118,8 @@ void tuxies_mother_act_0(void) { o->oSubAction++; break; case 1: - if (cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_057)) + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_057)) o->oSubAction++; break; case 2: @@ -260,7 +262,7 @@ void bhv_small_penguin_loop(void) { small_penguin_free_actions(); break; case HELD_HELD: - cur_obj_unrender_and_reset_state(0, 0); + cur_obj_unrender_set_action_and_anim(0, 0); if (cur_obj_has_behavior(bhvPenguinBaby)) obj_set_behavior(o, bhvSmallPenguin); obj_copy_pos(o, gMarioObject); diff --git a/src/game/behaviors/ukiki.inc.c b/src/game/behaviors/ukiki.inc.c index 2e6ce836..fc5d00c9 100644 --- a/src/game/behaviors/ukiki.inc.c +++ b/src/game/behaviors/ukiki.inc.c @@ -383,7 +383,8 @@ void ukiki_act_go_to_cage(void) { case UKIKI_SUB_ACT_CAGE_TALK_TO_MARIO: cur_obj_init_animation_with_sound(UKIKI_ANIM_HANDSTAND); - if (cur_obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG, DIALOG_080)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_DOWN, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_080)) { o->oSubAction++; } break; @@ -501,7 +502,7 @@ void ukiki_free_loop(void) { * * Possibly unused so AnimState could be used for wearing a cap? */ -static void ukiki_blink_timer(void) { +UNUSED static void ukiki_blink_timer(void) { if (gGlobalTimer % 50 < 7) { o->oAnimState = UKIKI_ANIM_STATE_EYE_CLOSED; } else { @@ -516,16 +517,16 @@ void cage_ukiki_held_loop(void) { if (o->oPosY - o->oHomeY > -100.0f) { switch(o->oUkikiTextState) { case UKIKI_TEXT_DEFAULT: - if (set_mario_npc_dialog(2) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_UP) == MARIO_DIALOG_STATUS_SPEAK) { create_dialog_box_with_response(DIALOG_079); o->oUkikiTextState = UKIKI_TEXT_CAGE_TEXTBOX; } break; case UKIKI_TEXT_CAGE_TEXTBOX: - if (gDialogResponse != 0) { - set_mario_npc_dialog(0); - if (gDialogResponse == 1) { + if (gDialogResponse != DIALOG_RESPONSE_NONE) { + set_mario_npc_dialog(MARIO_DIALOG_STOP); + if (gDialogResponse == DIALOG_RESPONSE_YES) { o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->oUkikiTextState = UKIKI_TEXT_GO_TO_CAGE; } else { @@ -567,7 +568,7 @@ void cap_ukiki_held_loop(void) { break; case UKIKI_TEXT_STEAL_CAP: - if (cur_obj_update_dialog(2, 2, DIALOG_100, 0)) { + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_TEXT_DEFAULT, DIALOG_100, 0)) { o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->oUkikiTextState = UKIKI_TEXT_STOLE_CAP; } @@ -577,9 +578,10 @@ void cap_ukiki_held_loop(void) { break; case UKIKI_TEXT_HAS_CAP: - if (cur_obj_update_dialog(2, 18, DIALOG_101, 0)) { + if (cur_obj_update_dialog(MARIO_DIALOG_LOOK_UP, + (DIALOG_FLAG_TEXT_DEFAULT | DIALOG_FLAG_TIME_STOP_ENABLED), DIALOG_101, 0)) { mario_retrieve_cap(); - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); o->oUkikiHasCap &= ~UKIKI_CAP_ON; o->oUkikiTextState = UKIKI_TEXT_GAVE_CAP_BACK; } @@ -617,7 +619,7 @@ void bhv_ukiki_loop(void) { break; case HELD_HELD: - cur_obj_unrender_and_reset_state(UKIKI_ANIM_HELD, 0); + cur_obj_unrender_set_action_and_anim(UKIKI_ANIM_HELD, 0); obj_copy_pos(o, gMarioObject); if (o->oBehParams2ndByte == UKIKI_CAP) { diff --git a/src/game/behaviors/ukiki_cage.inc.c b/src/game/behaviors/ukiki_cage.inc.c index 68a64e8a..2acce450 100644 --- a/src/game/behaviors/ukiki_cage.inc.c +++ b/src/game/behaviors/ukiki_cage.inc.c @@ -36,7 +36,7 @@ void bhv_ukiki_cage_star_loop(void) { case UKIKI_CAGE_STAR_ACT_SPAWN_STAR: obj_mark_for_deletion(o); spawn_mist_particles(); - spawn_triangle_break_particles(20, 138, 0.7, 3); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 0.7, 3); spawn_default_star(2500.0f, -1200.0f, 1300.0f); break; } diff --git a/src/game/behaviors/unused_poundable_platform.inc.c b/src/game/behaviors/unused_poundable_platform.inc.c index 23816905..0e2feb08 100644 --- a/src/game/behaviors/unused_poundable_platform.inc.c +++ b/src/game/behaviors/unused_poundable_platform.inc.c @@ -18,7 +18,7 @@ void bhv_unused_poundable_platform(void) { if (o->oAction == 0) { if (cur_obj_is_mario_ground_pounding_platform()) { spawn_mist_particles(); - spawn_triangle_break_particles(20, 56, 3.0f, 0); + spawn_triangle_break_particles(20, MODEL_SL_CRACKED_ICE_CHUNK, 3.0f, 0); o->oAction++; } } else if (o->oTimer > 7) { diff --git a/src/game/behaviors/water_pillar.inc.c b/src/game/behaviors/water_pillar.inc.c index 60920c73..bd414724 100644 --- a/src/game/behaviors/water_pillar.inc.c +++ b/src/game/behaviors/water_pillar.inc.c @@ -40,7 +40,7 @@ void water_level_pillar_undrained(void) { (s32) approach_f32_symmetric(gEnvironmentLevels[2], -2450.0f, 5.0f); gEnvironmentLevels[0] = (s32) approach_f32_symmetric(gEnvironmentLevels[0], -2450.0f, 5.0f); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers_2(2); #endif } else diff --git a/src/game/behaviors/wdw_water_level.inc.c b/src/game/behaviors/wdw_water_level.inc.c index 6a8a346b..c077ee2c 100644 --- a/src/game/behaviors/wdw_water_level.inc.c +++ b/src/game/behaviors/wdw_water_level.inc.c @@ -49,7 +49,7 @@ void bhv_water_level_diamond_loop(void) { cur_obj_play_sound_1(SOUND_ENV_WATER_DRAIN); // same as above } o->oAngleVelYaw = 0x800; -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers_2(2); #endif } diff --git a/src/game/behaviors/whomp.inc.c b/src/game/behaviors/whomp.inc.c index 138e1753..b8ab613a 100644 --- a/src/game/behaviors/whomp.inc.c +++ b/src/game/behaviors/whomp.inc.c @@ -1,20 +1,20 @@ // whomp.c.inc void whomp_play_sfx_from_pound_animation(void) { - UNUSED s32 sp2C = o->header.gfx.animInfo.animFrame; - s32 sp28 = 0; + UNUSED s32 animFrame = o->header.gfx.animInfo.animFrame; + s32 playSound = 0; if (o->oForwardVel < 5.0f) { - sp28 = cur_obj_check_anim_frame(0); - sp28 |= cur_obj_check_anim_frame(23); + playSound = cur_obj_check_anim_frame(0); + playSound |= cur_obj_check_anim_frame(23); } else { - sp28 = cur_obj_check_anim_frame_in_range(0, 3); - sp28 |= cur_obj_check_anim_frame_in_range(23, 3); + playSound = cur_obj_check_anim_frame_in_range(0, 3); + playSound |= cur_obj_check_anim_frame_in_range(23, 3); } - if (sp28) + if (playSound) cur_obj_play_sound_2(SOUND_OBJ_POUNDING1); } -void whomp_act_0(void) { +void whomp_init(void) { cur_obj_init_animation_with_accel_and_sound(0, 1.0f); cur_obj_set_pos_to_home(); if (o->oBehParams2ndByte != 0) { @@ -28,14 +28,15 @@ void whomp_act_0(void) { cur_obj_set_pos_to_home(); o->oHealth = 3; } - } else if (cur_obj_update_dialog_with_cutscene(2, 1, CUTSCENE_DIALOG, DIALOG_114)) + } else if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, DIALOG_114)) o->oAction = 2; } else if (o->oDistanceToMario < 500.0f) o->oAction = 1; whomp_play_sfx_from_pound_animation(); } -void whomp_act_7(void) { +void whomp_turn(void) { if (o->oSubAction == 0) { o->oForwardVel = 0.0f; cur_obj_init_animation_with_accel_and_sound(0, 1.0f); @@ -51,21 +52,24 @@ void whomp_act_7(void) { whomp_play_sfx_from_pound_animation(); } -void whomp_act_1(void) { - s16 sp26; - f32 sp20; - f32 sp1C; - sp26 = abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw); - sp20 = cur_obj_lateral_dist_to_home(); +void whomp_patrol(void) { + s16 marioAngle; + f32 distWalked; + f32 patrolDist; + + marioAngle = abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw); + distWalked = cur_obj_lateral_dist_to_home(); if (gCurrLevelNum == LEVEL_BITS) - sp1C = 200.0f; + patrolDist = 200.0f; else - sp1C = 700.0f; + patrolDist = 700.0f; + cur_obj_init_animation_with_accel_and_sound(0, 1.0f); o->oForwardVel = 3.0f; - if (sp20 > sp1C) + + if (distWalked > patrolDist) o->oAction = 7; - else if (sp26 < 0x2000) { + else if (marioAngle < 0x2000) { if (o->oDistanceToMario < 1500.0f) { o->oForwardVel = 9.0f; cur_obj_init_animation_with_accel_and_sound(0, 3.0f); @@ -76,14 +80,15 @@ void whomp_act_1(void) { whomp_play_sfx_from_pound_animation(); } -void whomp_act_2(void) { - s16 sp1E; +void king_whomp_chase(void) { + s16 marioAngle; cur_obj_init_animation_with_accel_and_sound(0, 1.0f); o->oForwardVel = 3.0f; cur_obj_rotate_yaw_toward(o->oAngleToMario, 0x200); + if (o->oTimer > 30) { - sp1E = abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw); - if (sp1E < 0x2000) { + marioAngle = abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw); + if (marioAngle < 0x2000) { if (o->oDistanceToMario < 1500.0f) { o->oForwardVel = 9.0f; cur_obj_init_animation_with_accel_and_sound(0, 3.0f); @@ -92,6 +97,7 @@ void whomp_act_2(void) { o->oAction = 3; } } + whomp_play_sfx_from_pound_animation(); if (mario_is_far_below_object(1000.0f)) { o->oAction = 0; @@ -99,14 +105,14 @@ void whomp_act_2(void) { } } -void whomp_act_3(void) { +void whomp_prepare_jump(void) { o->oForwardVel = 0.0f; cur_obj_init_animation_with_accel_and_sound(1, 1.0f); if (cur_obj_check_if_near_animation_end()) o->oAction = 4; } -void whomp_act_4(void) { +void whomp_jump(void) { if (o->oTimer == 0) o->oVelY = 40.0f; if (o->oTimer < 8) { @@ -121,7 +127,7 @@ void whomp_act_4(void) { } } -void whomp_act_5(void) { +void whomp_land(void) { if (o->oSubAction == 0 && o->oMoveFlags & OBJ_MOVE_LANDED) { cur_obj_play_sound_2(SOUND_OBJ_WHOMP_LOWPRIO); cur_obj_shake_screen(SHAKE_POS_SMALL); @@ -145,7 +151,7 @@ void king_whomp_on_ground(void) { vec3f_copy_2(pos, &o->oPosX); vec3f_copy_2(&o->oPosX, &gMarioObject->oPosX); spawn_mist_particles_variable(0, 0, 100.0f); - spawn_triangle_break_particles(20, 138, 3.0f, 4); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 3.0f, 4); cur_obj_shake_screen(SHAKE_POS_SMALL); vec3f_copy_2(&o->oPosX, pos); } @@ -180,12 +186,13 @@ void whomp_on_ground(void) { o->oSubAction = 0; } -void whomp_act_6(void) { +void whomp_on_ground_general(void) { if (o->oSubAction != 10) { o->oForwardVel = 0.0f; o->oAngleVelPitch = 0; o->oAngleVelYaw = 0; o->oAngleVelRoll = 0; + if (o->oBehParams2ndByte != 0) king_whomp_on_ground(); else @@ -207,14 +214,15 @@ void whomp_act_6(void) { } } -void whomp_act_8(void) { +void whomp_die(void) { if (o->oBehParams2ndByte != 0) { - if (cur_obj_update_dialog_with_cutscene(2, 2, CUTSCENE_DIALOG, DIALOG_115)) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_TEXT_DEFAULT, CUTSCENE_DIALOG, DIALOG_115)) { obj_set_angle(o, 0, 0, 0); cur_obj_hide(); cur_obj_become_intangible(); spawn_mist_particles_variable(0, 0, 200.0f); - spawn_triangle_break_particles(20, 138, 3.0f, 4); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 3.0f, 4); cur_obj_shake_screen(SHAKE_POS_SMALL); o->oPosY += 100.0f; spawn_default_star(180.0f, 3880.0f, 340.0f); @@ -223,21 +231,21 @@ void whomp_act_8(void) { } } else { spawn_mist_particles_variable(0, 0, 100.0f); - spawn_triangle_break_particles(20, 138, 3.0f, 4); + spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 3.0f, 4); cur_obj_shake_screen(SHAKE_POS_SMALL); create_sound_spawner(SOUND_OBJ_THWOMP); obj_mark_for_deletion(o); } } -void whomp_act_9(void) { +void king_whomp_stop_music(void) { if (o->oTimer == 60) stop_background_music(SEQUENCE_ARGS(4, SEQ_EVENT_BOSS)); } void (*sWhompActions[])(void) = { - whomp_act_0, whomp_act_1, whomp_act_2, whomp_act_3, whomp_act_4, - whomp_act_5, whomp_act_6, whomp_act_7, whomp_act_8, whomp_act_9 + whomp_init, whomp_patrol, king_whomp_chase, whomp_prepare_jump, whomp_jump, + whomp_land, whomp_on_ground_general, whomp_turn, whomp_die, king_whomp_stop_music }; // MM diff --git a/src/game/behaviors/wiggler.inc.c b/src/game/behaviors/wiggler.inc.c index 3d27856b..9bdc0e1e 100644 --- a/src/game/behaviors/wiggler.inc.c +++ b/src/game/behaviors/wiggler.inc.c @@ -228,7 +228,8 @@ static void wiggler_act_walk(void) { // If Mario is positioned below the wiggler, assume he entered through the // lower cave entrance, so don't display text. - if (gMarioObject->oPosY < o->oPosY || cur_obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_150) != 0) { + if (gMarioObject->oPosY < o->oPosY || cur_obj_update_dialog_with_cutscene( + MARIO_DIALOG_LOOK_UP, DIALOG_FLAG_NONE, CUTSCENE_DIALOG, DIALOG_150)) { o->oWigglerTextStatus = WIGGLER_TEXT_STATUS_COMPLETED_DIALOG; } } else { @@ -304,7 +305,8 @@ static void wiggler_act_jumped_on(void) { // defeated) or go back to walking if (o->header.gfx.scale[1] >= 4.0f) { if (o->oTimer > 30) { - if (cur_obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, attackText[o->oHealth - 2]) != 0) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + DIALOG_FLAG_NONE, CUTSCENE_DIALOG, attackText[o->oHealth - 2])) { // Because we don't want the wiggler to disappear after being // defeated, we leave its health at 1 if (--o->oHealth == 1) { diff --git a/src/game/behaviors/yoshi.inc.c b/src/game/behaviors/yoshi.inc.c index c588d311..3a56cf8b 100644 --- a/src/game/behaviors/yoshi.inc.c +++ b/src/game/behaviors/yoshi.inc.c @@ -76,7 +76,7 @@ void yoshi_idle_loop(void) { void yoshi_talk_loop(void) { if ((s16) o->oMoveAngleYaw == (s16) o->oAngleToMario) { cur_obj_init_animation(0); - if (set_mario_npc_dialog(1) == 2) { + if (set_mario_npc_dialog(MARIO_DIALOG_LOOK_FRONT) == MARIO_DIALOG_STATUS_SPEAK) { o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, DIALOG_161)) { o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; @@ -123,7 +123,7 @@ void yoshi_finish_jumping_and_despawn_loop(void) { obj_move_xyz_using_fvel_and_yaw(o); o->oVelY -= 2.0; if (o->oPosY < 2100.0f) { - set_mario_npc_dialog(0); + set_mario_npc_dialog(MARIO_DIALOG_STOP); gObjCutsceneDone = TRUE; sYoshiDead = TRUE; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; diff --git a/src/game/camera.c b/src/game/camera.c index 2ae110ce..e2fb1754 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -390,9 +390,13 @@ struct CameraStoredInfo sCameraStoreCutscene; // first iteration of data u32 unused8032CFC0 = 0; struct Object *gCutsceneFocus = NULL; -// other camera focuses? + u32 unused8032CFC8 = 0; u32 unused8032CFCC = 0; + +/** + * The information of a second focus camera used by some objects + */ struct Object *gSecondCameraFocus = NULL; /** @@ -431,7 +435,7 @@ u8 sFramesSinceCutsceneEnded = 0; * 2 = No * 3 = Dialog doesn't have a response */ -u8 sCutsceneDialogResponse = 0; +u8 sCutsceneDialogResponse = DIALOG_RESPONSE_NONE; struct PlayerCameraState *sMarioCamState = &gPlayerCameraState[0]; struct PlayerCameraState *sLuigiCamState = &gPlayerCameraState[1]; u32 unused8032D008 = 0; @@ -1703,9 +1707,12 @@ struct ParallelTrackingPoint sBBHLibraryParTrackPath[] = { }; s32 unused_update_mode_5_camera(UNUSED struct Camera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { +#ifdef AVOID_UB + return 0; +#endif } -static void stub_camera_1(UNUSED s32 unused) { +UNUSED static void stub_camera_1(UNUSED s32 unused) { } void mode_boss_fight_camera(struct Camera *c) { @@ -2028,6 +2035,9 @@ void mode_behind_mario_camera(struct Camera *c) { } s32 nop_update_water_camera(UNUSED struct Camera *c, UNUSED Vec3f focus, UNUSED Vec3f pos) { +#ifdef AVOID_UB + return 0; +#endif } /** @@ -2226,7 +2236,7 @@ s16 update_default_camera(struct Camera *c) { if ((closeToMario & 1) && avoidStatus != 0) { yawVel = 0; } - if (yawVel != 0 && get_dialog_id() == -1) { + if (yawVel != 0 && get_dialog_id() == DIALOG_NONE) { camera_approach_s16_symmetric_bool(&yaw, yawGoal, yawVel); } } @@ -3327,12 +3337,18 @@ void init_camera(struct Camera *c) { // Set the camera's starting position or start a cutscene for certain levels switch (gCurrLevelNum) { + // Calls the initial cutscene when you enter Bowser battle levels + // Note: This replaced an "old" way to call these cutscenes using + // a camEvent value: CAM_EVENT_BOWSER_INIT case LEVEL_BOWSER_1: #ifndef VERSION_JP + // Since Bowser 1 has a demo entry, check for it + // If it is, then set CamAct to the end to directly activate Bowser + // If it isn't, then start cutscene if (gCurrDemoInput == NULL) { start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); } else if (gSecondCameraFocus != NULL) { - gSecondCameraFocus->oBowserUnk88 = 2; + gSecondCameraFocus->oBowserCamAct = BOWSER_CAM_ACT_END; } #else start_cutscene(c, CUTSCENE_ENTER_BOWSER_ARENA); @@ -4848,6 +4864,9 @@ void play_sound_if_cam_switched_to_lakitu_or_mario(void) { */ s32 radial_camera_input(struct Camera *c, UNUSED f32 unused) { s16 dummy; +#ifdef AVOID_UB + dummy = 0; +#endif if ((gCameraMovementFlags & CAM_MOVE_ENTERED_ROTATE_SURFACE) || !(gCameraMovementFlags & CAM_MOVE_ROTATE)) { @@ -5315,7 +5334,7 @@ void set_focus_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, f32 forwBack * @param forwBack offset to Mario's front/back, relative to his faceAngle * @param yawOff offset to Mario's faceAngle, changes the direction of `leftRight` and `forwBack` */ -static void unused_set_pos_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, f32 forwBack, s16 yawOff) { +UNUSED static void unused_set_pos_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, f32 forwBack, s16 yawOff) { u16 yaw = sMarioCamState->faceAngle[1] + yawOff; c->pos[0] = sMarioCamState->pos[0] + forwBack * sins(yaw) + leftRight * coss(yaw); @@ -5364,7 +5383,7 @@ void determine_pushing_or_pulling_door(s16 *rotation) { if (sMarioCamState->action == ACT_PULLING_DOOR) { *rotation = 0; } else { - *rotation = DEGREES(180); + *rotation = DEGREES(-180); } } @@ -6863,31 +6882,31 @@ void start_object_cutscene(u8 cutscene, struct Object *o) { */ u8 start_object_cutscene_without_focus(u8 cutscene) { sObjectCutscene = cutscene; - sCutsceneDialogResponse = 0; + sCutsceneDialogResponse = DIALOG_RESPONSE_NONE; return 0; } -s32 unused_dialog_cutscene_response(u8 cutscene) { +s16 unused_dialog_cutscene_response(u8 cutscene) { // if not in a cutscene, start this one if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { sObjectCutscene = cutscene; } // if playing this cutscene and Mario responded, return the response - if ((gCamera->cutscene == cutscene) && (sCutsceneDialogResponse != 0)) { - return (s16) sCutsceneDialogResponse; + if ((gCamera->cutscene == cutscene) && (sCutsceneDialogResponse)) { + return sCutsceneDialogResponse; } else { return 0; } } s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID) { - s16 response = 0; + s16 response = DIALOG_RESPONSE_NONE; if ((gCamera->cutscene == 0) && (sObjectCutscene == 0)) { if (gRecentCutscene != cutscene) { start_object_cutscene(cutscene, o); - if (dialogID != -1) { + if (dialogID != DIALOG_NONE) { sCutsceneDialogID = dialogID; } else { sCutsceneDialogID = DIALOG_001; @@ -6902,7 +6921,7 @@ s16 cutscene_object_with_dialog(u8 cutscene, struct Object *o, s16 dialogID) { } s16 cutscene_object_without_dialog(u8 cutscene, struct Object *o) { - s16 response = cutscene_object_with_dialog(cutscene, o, -1); + s16 response = cutscene_object_with_dialog(cutscene, o, DIALOG_NONE); return response; } @@ -6987,7 +7006,7 @@ void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSpline s16 cutscene_common_set_dialog_state(s32 state) { s16 timer = gCutsceneTimer; // If the dialog ended, return CUTSCENE_LOOP, which would end the cutscene shot - if (set_mario_npc_dialog(state) == 2) { + if (set_mario_npc_dialog(state) == MARIO_DIALOG_STATUS_SPEAK) { timer = CUTSCENE_LOOP; } return timer; @@ -6995,19 +7014,19 @@ s16 cutscene_common_set_dialog_state(s32 state) { /// Unused SSL cutscene? static UNUSED void unused_cutscene_mario_dialog_looking_down(UNUSED struct Camera *c) { - gCutsceneTimer = cutscene_common_set_dialog_state(3); + gCutsceneTimer = cutscene_common_set_dialog_state(MARIO_DIALOG_LOOK_DOWN); } /** * Cause Mario to enter the normal dialog state. */ static BAD_RETURN(s32) cutscene_mario_dialog(UNUSED struct Camera *c) { - gCutsceneTimer = cutscene_common_set_dialog_state(1); + gCutsceneTimer = cutscene_common_set_dialog_state(MARIO_DIALOG_LOOK_FRONT); } /// Unused SSL cutscene? static UNUSED void unused_cutscene_mario_dialog_looking_up(UNUSED struct Camera *c) { - gCutsceneTimer = cutscene_common_set_dialog_state(2); + gCutsceneTimer = cutscene_common_set_dialog_state(MARIO_DIALOG_LOOK_UP); } /** @@ -7196,7 +7215,7 @@ void cutscene_unsoften_music(UNUSED struct Camera *c) { seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); } -static void stub_camera_5(UNUSED struct Camera *c) { +UNUSED static void stub_camera_5(UNUSED struct Camera *c) { } BAD_RETURN(s32) cutscene_unused_start(UNUSED struct Camera *c) { @@ -7682,7 +7701,7 @@ BAD_RETURN(s32) cutscene_dance_rotate_move_towards_mario(struct Camera *c) { /** * Speculated to be dance-related due to its proximity to the other dance functions */ -static BAD_RETURN(s32) cutscene_dance_unused(UNUSED struct Camera *c) { +UNUSED static BAD_RETURN(s32) cutscene_dance_unused(UNUSED struct Camera *c) { } /** @@ -8033,10 +8052,10 @@ BAD_RETURN(s32) cutscene_bowser_area_shake_fov(UNUSED struct Camera *c) { } /** - * Set oBowserUnk88 to 1, which causes bowser to start walking. + * Set oBowserCamAct to 1, which causes bowser to start walking. */ BAD_RETURN(s32) cutscene_bowser_area_start_bowser_walking(UNUSED struct Camera *c) { - gSecondCameraFocus->oBowserUnk88 = 1; + gSecondCameraFocus->oBowserCamAct = BOWSER_CAM_ACT_WALK; } /** @@ -8093,11 +8112,11 @@ BAD_RETURN(s32) cutscene_bowser_arena_pan_left(UNUSED struct Camera *c) { * Duplicate of cutscene_mario_dialog(). */ BAD_RETURN(s32) cutscene_bowser_arena_mario_dialog(UNUSED struct Camera *c) { - cutscene_common_set_dialog_state(1); + cutscene_common_set_dialog_state(MARIO_DIALOG_LOOK_FRONT); } void cutscene_stop_dialog(UNUSED struct Camera *c) { - cutscene_common_set_dialog_state(0); + cutscene_common_set_dialog_state(MARIO_DIALOG_STOP); } /** @@ -8138,7 +8157,7 @@ BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED struct Camera *c) { case LEVEL_BOWSER_2: dialog = DIALOG_092; break; - default: + default: // LEVEL_BOWSER_3 dialog = DIALOG_093; } @@ -8151,7 +8170,7 @@ BAD_RETURN(s32) bowser_fight_intro_dialog(UNUSED 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) { + if (get_dialog_id() == DIALOG_NONE) { gCutsceneTimer = CUTSCENE_LOOP; } } @@ -8165,7 +8184,7 @@ BAD_RETURN(s32) cutscene_bowser_arena_end(struct Camera *c) { transition_next_state(c, 20); sStatusFlags |= CAM_FLAG_UNUSED_CUTSCENE_ACTIVE; sModeOffsetYaw = sMarioCamState->faceAngle[1] + DEGREES(90); - gSecondCameraFocus->oBowserUnk88 = 2; + gSecondCameraFocus->oBowserCamAct = BOWSER_CAM_ACT_END; } /** @@ -8595,7 +8614,7 @@ BAD_RETURN(s32) cutscene_death_stomach_goto_mario(struct Camera *c) { /** * Ah, yes */ -static void unused_water_death_move_to_side_of_mario(struct Camera *c) { +UNUSED static void unused_water_death_move_to_side_of_mario(struct Camera *c) { water_death_move_to_mario_side(c); } @@ -8869,7 +8888,7 @@ BAD_RETURN(s32) cutscene_enter_pyramid_top(struct Camera *c) { } } -static void unused_cutscene_goto_cvar(struct Camera *c) { +UNUSED static void unused_cutscene_goto_cvar(struct Camera *c) { f32 dist; dist = calc_abs_dist(sCutsceneVars[3].point, sMarioCamState->pos); @@ -8967,7 +8986,7 @@ BAD_RETURN(s32) cutscene_dialog_create_dialog_box(struct Camera *c) { } //! Unused. This may have been used before sCutsceneDialogResponse was implemented. - sCutsceneVars[8].angle[0] = 3; + sCutsceneVars[8].angle[0] = DIALOG_RESPONSE_NOT_DEFINED; } /** @@ -8979,13 +8998,13 @@ BAD_RETURN(s32) cutscene_dialog(struct Camera *c) { cutscene_event(cutscene_dialog_create_dialog_box, c, 10, 10); sStatusFlags |= CAM_FLAG_SMOOTH_MOVEMENT; - if (gDialogResponse != 0) { + if (gDialogResponse != DIALOG_RESPONSE_NONE) { sCutsceneDialogResponse = gDialogResponse; } - if ((get_dialog_id() == -1) && (sCutsceneVars[8].angle[0] != 0)) { + if ((get_dialog_id() == DIALOG_NONE) && (sCutsceneVars[8].angle[0] != 0)) { if (c->cutscene != CUTSCENE_RACE_DIALOG) { - sCutsceneDialogResponse = 3; + sCutsceneDialogResponse = DIALOG_RESPONSE_NOT_DEFINED; } gCutsceneTimer = CUTSCENE_LOOP; @@ -9030,7 +9049,7 @@ BAD_RETURN(s32) cutscene_read_message_start(struct Camera *c) { sCutsceneVars[0].angle[0] = 0; } -static void unused_cam_to_mario(struct Camera *c) { +UNUSED static void unused_cam_to_mario(struct Camera *c) { Vec3s dir; vec3s_set(dir, 0, sMarioCamState->faceAngle[1], 0); @@ -9050,7 +9069,7 @@ BAD_RETURN(s32) cutscene_read_message(struct Camera *c) { switch (sCutsceneVars[0].angle[0]) { // Do nothing until message is gone. case 0: - if (get_dialog_id() != -1) { + if (get_dialog_id() != DIALOG_NONE) { sCutsceneVars[0].angle[0] += 1; set_time_stop_flags(TIME_STOP_ENABLED | TIME_STOP_DIALOG); } @@ -9062,7 +9081,7 @@ BAD_RETURN(s32) cutscene_read_message(struct Camera *c) { // This could cause softlocks. If a message starts one frame after another one closes, the // cutscene will never end. - if (get_dialog_id() == -1) { + if (get_dialog_id() == DIALOG_NONE) { gCutsceneTimer = CUTSCENE_LOOP; retrieve_info_star(c); transition_next_state(c, 15); @@ -9395,11 +9414,11 @@ BAD_RETURN(s32) cutscene_cap_switch_press(struct Camera *c) { cutscene_event(cutscene_cap_switch_press_create_dialog, c, 10, 10); vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); - if (gDialogResponse != 0) { + if (gDialogResponse != DIALOG_RESPONSE_NONE) { sCutsceneVars[4].angle[0] = gDialogResponse; } - if ((get_dialog_id() == -1) && (sCutsceneVars[4].angle[0] != 0)) { + if ((get_dialog_id() == DIALOG_NONE) && (sCutsceneVars[4].angle[0] != 0)) { sCutsceneDialogResponse = sCutsceneVars[4].angle[0]; if (sCutsceneVars[4].angle[0] == 1) { cap_switch_save(gCutsceneFocus->oBehParams2ndByte); @@ -9493,8 +9512,8 @@ s32 intro_peach_move_camera_start_to_pipe(struct Camera *c, struct CutsceneSplin // The two splines used by this function are reflected in the horizontal plane for some reason, // so they are rotated every frame. Why do this, Nintendo? - rotate_in_xz(c->focus, c->focus, DEGREES(180)); - rotate_in_xz(c->pos, c->pos, DEGREES(180)); + rotate_in_xz(c->focus, c->focus, DEGREES(-180)); + rotate_in_xz(c->pos, c->pos, DEGREES(-180)); vec3f_set(offset, -1328.f, 260.f, 4664.f); vec3f_add(c->focus, offset); @@ -9532,7 +9551,7 @@ BAD_RETURN(s32) cutscene_intro_peach_start_to_pipe_spline(struct Camera *c) { * Loop the cutscene until Mario exits the dialog. */ BAD_RETURN(s32) cutscene_intro_peach_dialog(struct Camera *c) { - if (get_dialog_id() == -1) { + if (get_dialog_id() == DIALOG_NONE) { vec3f_copy(gLakituState.goalPos, c->pos); vec3f_copy(gLakituState.goalFocus, c->focus); sStatusFlags |= (CAM_FLAG_SMOOTH_MOVEMENT | CAM_FLAG_UNUSED_CUTSCENE_ACTIVE); @@ -9654,7 +9673,7 @@ BAD_RETURN(s32) cutscene_intro_peach_letter(struct Camera *c) { cutscene_event(play_sound_peach_reading_letter, c, 83, 83); #endif - if ((gCutsceneTimer > 120) && (get_dialog_id() == -1)) { + if ((gCutsceneTimer > 120) && (get_dialog_id() == DIALOG_NONE)) { // Start the next scene gCutsceneTimer = CUTSCENE_LOOP; } diff --git a/src/game/debug.c b/src/game/debug.c index e735035d..060002bb 100644 --- a/src/game/debug.c +++ b/src/game/debug.c @@ -337,7 +337,7 @@ void reset_debug_objectinfo(void) { * C Right) and then toggles the debug flags from FF to 2; 2 is unused, * despite so this has no effect, being called. (unused) */ -static void check_debug_button_seq(void) { +UNUSED static void check_debug_button_seq(void) { s16 *buttonArr; s16 cButtonMask; @@ -367,7 +367,7 @@ static void check_debug_button_seq(void) { * Poll the debug info flags and controller for appropriate presses that * control sDebugPage's range. (unused) */ -static void try_change_debug_page(void) { +UNUSED static void try_change_debug_page(void) { if (gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) { if ((gPlayer1Controller->buttonPressed & L_JPAD) && (gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG))) { @@ -392,8 +392,8 @@ static void try_change_debug_page(void) { * sDebugSysCursor. This is used to adjust enemy and effect behaviors * on the fly. (unused) */ -#ifndef VERSION_SH -static +#ifdef VERSION_EU +UNUSED static #endif void try_modify_debug_controls(void) { s32 sp4; @@ -525,9 +525,6 @@ void try_do_mario_debug_object_spawn(void) { } // TODO: figure out what this is -#ifndef VERSION_SH -static -#endif void debug_print_obj_move_flags(void) { #ifndef VERSION_EU // TODO: Is there a better way to diff this? static EU doesn't seem to work. if (gCurrentObject->oMoveFlags & OBJ_MOVE_LANDED) { diff --git a/src/game/envfx_snow.c b/src/game/envfx_snow.c index 192219db..5686da78 100644 --- a/src/game/envfx_snow.c +++ b/src/game/envfx_snow.c @@ -1,6 +1,7 @@ #include #include "sm64.h" +#include "dialog_ids.h" #include "game_init.h" #include "memory.h" #include "ingame_menu.h" @@ -272,7 +273,7 @@ void envfx_update_snow_blizzard(s32 snowCylinderX, s32 snowCylinderY, s32 snowCy * find it. The radius of 3000 units is quite large for that though, covering * more than half of the mirror room. */ -static s32 is_in_mystery_snow_area(s32 x, UNUSED s32 y, s32 z) { +UNUSED static s32 is_in_mystery_snow_area(s32 x, UNUSED s32 y, s32 z) { if (sqr(x - 3380) + sqr(z + 520) < sqr(3000)) { return 1; } @@ -463,7 +464,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo) Gfx *envfx_update_particles(s32 mode, Vec3s marioPos, Vec3s camTo, Vec3s camFrom) { Gfx *gfx; - if (get_dialog_id() != -1) { + if (get_dialog_id() != DIALOG_NONE) { return NULL; } diff --git a/src/game/game_init.c b/src/game/game_init.c index b6334688..72c2fb8e 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -21,51 +21,71 @@ #include "rumble_init.h" #include -// 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 +// First 3 controller slots struct Controller gControllers[3]; + +// Gfx handlers struct SPTask *gGfxSPTask; Gfx *gDisplayListHead; u8 *gGfxPoolEnd; struct GfxPool *gGfxPool; + +// OS Controllers OSContStatus gControllerStatuses[4]; OSContPad gControllerPads[4]; u8 gControllerBits; -s8 gEepromProbe; +s8 gEepromProbe; // Save Data Probe + +// OS Messages OSMesgQueue gGameVblankQueue; -OSMesgQueue D_80339CB8; -OSMesg D_80339CD0; -OSMesg D_80339CD4; +OSMesgQueue gGfxVblankQueue; +OSMesg gGameMesgBuf[1]; +OSMesg gGfxMesgBuf[1]; + +// Vblank Handler struct VblankHandler gGameVblankHandler; + +// Buffers uintptr_t gPhysicalFrameBuffers[3]; uintptr_t gPhysicalZBuffer; -void *D_80339CF0; -void *D_80339CF4; -struct MarioAnimation D_80339D10; -struct MarioAnimation gDemo; -UNUSED u8 filler80339D30[0x90]; -s32 unused8032C690 = 0; +// Mario Anims and Demo allocation +void *gMarioAnimsMemAlloc; +void *gDemoInputsMemAlloc; +struct DmaHandlerList gMarioAnimsBuf; +struct DmaHandlerList gDemoInputsBuf; + +// fillers +UNUSED static u8 sfillerGameInit[0x90]; +static s32 sUnusedGameInitValue = 0; + +// General timer that runs as the game starts u32 gGlobalTimer = 0; -static u16 sCurrFBNum = 0; -u16 frameBufferIndex = 0; +// Framebuffer rendering values (max 3) +u16 sRenderedFramebuffer = 0; +u16 sRenderingFrameBuffer = 0; + +// Goddard Vblank Function Caller void (*gGoddardVblankCallback)(void) = NULL; + +// Defined controller slots struct Controller *gPlayer1Controller = &gControllers[0]; struct Controller *gPlayer2Controller = &gControllers[1]; -// probably debug only, see note below -struct Controller *gPlayer3Controller = &gControllers[2]; -struct DemoInput *gCurrDemoInput = NULL; // demo input sequence +struct Controller *gPlayer3Controller = &gControllers[2]; // Probably debug only, see note below + +// Title Screen Demo Handler +struct DemoInput *gCurrDemoInput = NULL; u16 gDemoInputListID = 0; -struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check +struct DemoInput gRecordedDemoInput = { 0 }; + +// Display +// ---------------------------------------------------------------------------------------------------- /** - * Initializes the Reality Display Processor (RDP). - * This function initializes settings such as texture filtering mode, - * scissoring, and render mode (although keep in mind that this render - * mode is not used in-game, where it is set in render_graph_node.c). + * Sets the initial RDP (Reality Display Processor) rendering settings. */ -void my_rdp_init(void) { +void init_rdp(void) { gDPPipeSync(gDisplayListHead++); gDPPipelineMode(gDisplayListHead++, G_PM_1PRIMITIVE); @@ -92,11 +112,9 @@ void my_rdp_init(void) { } /** - * Initializes the RSP's built-in geometry and lighting engines. - * Most of these (with the notable exception of gSPNumLights), are - * almost immediately overwritten. + * Sets the initial RSP (Reality Signal Processor) settings. */ -void my_rsp_init(void) { +void init_rsp(void) { gSPClearGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD); @@ -105,17 +123,17 @@ void my_rsp_init(void) { gSPNumLights(gDisplayListHead++, NUMLIGHTS_1); gSPTexture(gDisplayListHead++, 0, 0, 0, G_TX_RENDERTILE, G_OFF); - // @bug Nintendo did not explicitly define the clipping ratio. - // For Fast3DEX2, this causes the dreaded warped vertices issue - // unless the clipping ratio is changed back to the intended value, - // as Fast3DEX2 uses a different initial value than Fast3D(EX). + // @bug Failing to set the clip ratio will result in warped triangles in F3DEX2 + // without this change: https://jrra.zone/n64/doc/n64man/gsp/gSPClipRatio.htm #ifdef F3DEX_GBI_2 gSPClipRatio(gDisplayListHead++, FRUSTRATIO_1); #endif } -/** Clear the Z buffer. */ -void clear_z_buffer(void) { +/** + * Initialize the z buffer for the current frame. + */ +void init_z_buffer(void) { gDPPipeSync(gDisplayListHead++); gDPSetDepthSource(gDisplayListHead++, G_ZS_PIXEL); @@ -129,18 +147,23 @@ void clear_z_buffer(void) { SCREEN_HEIGHT - 1 - BORDER_HEIGHT); } -/** Sets up the final framebuffer image. */ -void display_frame_buffer(void) { +/** + * Tells the RDP which of the three framebuffers it shall draw to. + */ +void select_frame_buffer(void) { gDPPipeSync(gDisplayListHead++); gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); gDPSetColorImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, - gPhysicalFrameBuffers[frameBufferIndex]); + gPhysicalFrameBuffers[sRenderingFrameBuffer]); gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT); } -/** Clears the framebuffer, allowing it to be overwritten. */ +/** + * Clear the framebuffer and fill it with a 32-bit color. + * Information about the color argument: https://jrra.zone/n64/doc/n64man/gdp/gDPSetFillColor.htm + */ void clear_frame_buffer(s32 color) { gDPPipeSync(gDisplayListHead++); @@ -157,7 +180,9 @@ void clear_frame_buffer(s32 color) { gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); } -/** Clears and initializes the viewport. */ +/** + * Resets the viewport, readying it for the final image. + */ void clear_viewport(Vp *viewport, s32 color) { s16 vpUlx = (viewport->vp.vtrans[0] - viewport->vp.vscale[0]) / 4 + 1; s16 vpUly = (viewport->vp.vtrans[1] - viewport->vp.vscale[1]) / 4 + 1; @@ -182,7 +207,9 @@ void clear_viewport(Vp *viewport, s32 color) { gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); } -/** Draws the horizontal screen borders */ +/** + * Draw the horizontal screen borders. + */ void draw_screen_borders(void) { gDPPipeSync(gDisplayListHead++); @@ -201,6 +228,10 @@ void draw_screen_borders(void) { #endif } +/** + * Defines the viewport scissoring rectangle. + * Scissoring: https://jrra.zone/n64/doc/pro-man/pro12/12-03.htm#01 + */ void make_viewport_clip_rect(Vp *viewport) { s16 vpUlx = (viewport->vp.vtrans[0] - viewport->vp.vscale[0]) / 4 + 1; s16 vpPly = (viewport->vp.vtrans[1] - viewport->vp.vscale[1]) / 4 + 1; @@ -211,14 +242,13 @@ void make_viewport_clip_rect(Vp *viewport) { } /** - * Loads the F3D microcodes. - * Refer to this function if you would like to load - * other microcodes (i.e. S2DEX). + * Initializes the Fast3D OSTask structure. + * If you plan on using gSPLoadUcode, make sure to add OS_TASK_LOADABLE to the flags member. */ -void create_task_structure(void) { +void create_gfx_task_structure(void) { s32 entries = gDisplayListHead - gGfxPool->buffer; - gGfxSPTask->msgqueue = &D_80339CB8; + gGfxSPTask->msgqueue = &gGfxVblankQueue; gGfxSPTask->msg = (OSMesg) 2; gGfxSPTask->task.t.type = M_GFXTASK; gGfxSPTask->task.t.ucode_boot = rspF3DBootStart; @@ -239,16 +269,20 @@ void create_task_structure(void) { gGfxSPTask->task.t.yield_data_size = OS_YIELD_DATA_SIZE; } -/** Starts rendering the scene. */ -void init_render_image(void) { +/** + * Set default RCP (Reality Co-Processor) settings. + */ +void init_rcp(void) { move_segment_table_to_dmem(); - my_rdp_init(); - my_rsp_init(); - clear_z_buffer(); - display_frame_buffer(); + init_rdp(); + init_rsp(); + init_z_buffer(); + select_frame_buffer(); } -/** Ends the master display list. */ +/** + * End the master display list and initialize the graphics task structure for the next frame to be rendered. + */ void end_master_display_list(void) { draw_screen_borders(); if (gShowProfiler) { @@ -258,94 +292,113 @@ void end_master_display_list(void) { gDPFullSync(gDisplayListHead++); gSPEndDisplayList(gDisplayListHead++); - create_task_structure(); + create_gfx_task_structure(); } +/** + * Draw the bars that appear when the N64 is soft reset. + */ void draw_reset_bars(void) { - s32 sp24; - s32 sp20; + s32 width, height; s32 fbNum; - u64 *sp18; + u64 *fbPtr; - if (gResetTimer != 0 && D_8032C648 < 15) { - if (sCurrFBNum == 0) { + if (gResetTimer != 0 && gNmiResetBarsTimer < 15) { + if (sRenderedFramebuffer == 0) { fbNum = 2; } else { - fbNum = sCurrFBNum - 1; + fbNum = sRenderedFramebuffer - 1; } - sp18 = (u64 *) PHYSICAL_TO_VIRTUAL(gPhysicalFrameBuffers[fbNum]); - sp18 += D_8032C648++ * (SCREEN_WIDTH / 4); + fbPtr = (u64 *) PHYSICAL_TO_VIRTUAL(gPhysicalFrameBuffers[fbNum]); + fbPtr += gNmiResetBarsTimer++ * (SCREEN_WIDTH / 4); - for (sp24 = 0; sp24 < ((SCREEN_HEIGHT / 16) + 1); sp24++) { + for (width = 0; width < ((SCREEN_HEIGHT / 16) + 1); width++) { // Loop must be one line to match on -O2 - for (sp20 = 0; sp20 < (SCREEN_WIDTH / 4); sp20++) *sp18++ = 0; - sp18 += ((SCREEN_WIDTH / 4) * 14); + for (height = 0; height < (SCREEN_WIDTH / 4); height++) *fbPtr++ = 0; + fbPtr += ((SCREEN_WIDTH / 4) * 14); } } osWritebackDCacheAll(); - osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK); - osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK); + osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); + osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); } -void rendering_init(void) { +/** + * Initial settings for the first rendered frame. + */ +void render_init(void) { gGfxPool = &gGfxPools[0]; set_segment_base_addr(1, gGfxPool->buffer); gGfxSPTask = &gGfxPool->spTask; gDisplayListHead = gGfxPool->buffer; - gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE); - init_render_image(); + gGfxPoolEnd = (u8 *)(gGfxPool->buffer + GFX_POOL_SIZE); + init_rcp(); clear_frame_buffer(0); end_master_display_list(); - send_display_list(&gGfxPool->spTask); + exec_display_list(&gGfxPool->spTask); - frameBufferIndex++; + sRenderingFrameBuffer++; gGlobalTimer++; } -void config_gfx_pool(void) { - gGfxPool = &gGfxPools[gGlobalTimer % 2]; +/** + * Selects the location of the F3D output buffer (gDisplayListHead). + */ +void select_gfx_pool(void) { + gGfxPool = &gGfxPools[gGlobalTimer % ARRAY_COUNT(gGfxPools)]; set_segment_base_addr(1, gGfxPool->buffer); gGfxSPTask = &gGfxPool->spTask; gDisplayListHead = gGfxPool->buffer; gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE); } -/** Handles vsync. */ +/** + * This function: + * - Sends the current master display list out to be rendered. + * - Tells the VI which color framebuffer to be displayed. + * - Yields to the VI framerate twice, locking the game at 30 FPS. + * - Selects which framebuffer will be rendered and displayed to next time. + */ void display_and_vsync(void) { profiler_log_thread5_time(BEFORE_DISPLAY_LISTS); - osRecvMesg(&D_80339CB8, &D_80339BEC, OS_MESG_BLOCK); + osRecvMesg(&gGfxVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); if (gGoddardVblankCallback != NULL) { gGoddardVblankCallback(); gGoddardVblankCallback = NULL; } - send_display_list(&gGfxPool->spTask); + exec_display_list(&gGfxPool->spTask); profiler_log_thread5_time(AFTER_DISPLAY_LISTS); - osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK); - osViSwapBuffer((void *) PHYSICAL_TO_VIRTUAL(gPhysicalFrameBuffers[sCurrFBNum])); + osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); + osViSwapBuffer((void *) PHYSICAL_TO_VIRTUAL(gPhysicalFrameBuffers[sRenderedFramebuffer])); profiler_log_thread5_time(THREAD5_END); - osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK); - if (++sCurrFBNum == 3) { - sCurrFBNum = 0; + osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); + if (++sRenderedFramebuffer == 3) { + sRenderedFramebuffer = 0; } - if (++frameBufferIndex == 3) { - frameBufferIndex = 0; + if (++sRenderingFrameBuffer == 3) { + sRenderingFrameBuffer = 0; } gGlobalTimer++; } -// 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) { - // record the player's button mask and current rawStickX and rawStickY. +// Controls +// ---------------------------------------------------------------------------------------------------- + +/** + * 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. + */ +UNUSED static void record_demo(void) { + // Record the player's button mask and current rawStickX and rawStickY. u8 buttonMask = ((gPlayer1Controller->buttonDown & (A_BUTTON | B_BUTTON | Z_TRIG | START_BUTTON)) >> 8) | (gPlayer1Controller->buttonDown & (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS)); s8 rawStickX = gPlayer1Controller->rawStickX; s8 rawStickY = gPlayer1Controller->rawStickY; - // if the stick is in deadzone, set its value to 0 to + // If the stick is in deadzone, set its value to 0 to // nullify the effects. We do not record deadzone inputs. if (rawStickX > -8 && rawStickX < 8) { rawStickX = 0; @@ -355,9 +408,8 @@ static void record_demo(void) { rawStickY = 0; } - // record the distinct input and timer so long as they - // are unique. If the timer hits 0xFF, reset the timer - // for the next demo input. + // Rrecord the distinct input and timer so long as they are unique. + // If the timer hits 0xFF, reset the timer for the next demo input. if (gRecordedDemoInput.timer == 0xFF || buttonMask != gRecordedDemoInput.buttonMask || rawStickX != gRecordedDemoInput.rawStickX || rawStickY != gRecordedDemoInput.rawStickY) { gRecordedDemoInput.timer = 0; @@ -368,16 +420,17 @@ static void record_demo(void) { gRecordedDemoInput.timer++; } -// take the updated controller struct and calculate -// the new x, y, and distance floats. +/** + * Take the updated controller struct and calculate the new x, y, and distance floats. + */ void adjust_analog_stick(struct Controller *controller) { UNUSED u8 pad[8]; - // reset the controller's x and y floats. + // Reset the controller's x and y floats. controller->stickX = 0; controller->stickY = 0; - // modulate the rawStickX and rawStickY to be the new f32 values by adding/subtracting 6. + // Modulate the rawStickX and rawStickY to be the new f32 values by adding/subtracting 6. if (controller->rawStickX <= -8) { controller->stickX = controller->rawStickX + 6; } @@ -394,12 +447,12 @@ void adjust_analog_stick(struct Controller *controller) { controller->stickY = controller->rawStickY - 6; } - // calculate f32 magnitude from the center by vector length. + // Calculate f32 magnitude from the center by vector length. controller->stickMag = sqrtf(controller->stickX * controller->stickX + controller->stickY * controller->stickY); - // magnitude cannot exceed 64.0f: if it does, modify the values appropriately to - // flatten the values down to the allowed maximum value. + // Magnitude cannot exceed 64.0f: if it does, modify the values + // appropriately to flatten the values down to the allowed maximum value. if (controller->stickMag > 64) { controller->stickX *= 64 / controller->stickMag; controller->stickY *= 64 / controller->stickMag; @@ -407,64 +460,56 @@ void adjust_analog_stick(struct Controller *controller) { } } -// if a demo sequence exists, this will run the demo -// input list until it is complete. called every frame. +/** + * If a demo sequence exists, this will run the demo input list until it is complete. + */ void run_demo_inputs(void) { - // eliminate the unused bits. + // Eliminate the unused bits. gControllers[0].controllerData->button &= VALID_BUTTONS; - /* - Check if a demo inputs list - exists and if so, run the - active demo input list. - */ + // Check if a demo inputs list exists and if so, + // run the active demo input list. if (gCurrDemoInput != NULL) { - /* - clear player 2's inputs if they exist. Player 2's controller - cannot be used to influence a demo. At some point, Nintendo - may have planned for there to be a demo where 2 players moved - around instead of just one, so clearing player 2's influence from - the demo had to have been necessary to perform this. Co-op mode, perhaps? - */ + // Clear player 2's inputs if they exist. Player 2's controller + // cannot be used to influence a demo. At some point, Nintendo + // may have planned for there to be a demo where 2 players moved + // around instead of just one, so clearing player 2's influence from + // the demo had to have been necessary to perform this. Co-op mode, perhaps? if (gControllers[1].controllerData != NULL) { gControllers[1].controllerData->stick_x = 0; gControllers[1].controllerData->stick_y = 0; gControllers[1].controllerData->button = 0; } - // the timer variable being 0 at the current input means the demo is over. - // set the button to the END_DEMO mask to end the demo. + // The timer variable being 0 at the current input means the demo is over. + // Set the button to the END_DEMO mask to end the demo. if (gCurrDemoInput->timer == 0) { gControllers[0].controllerData->stick_x = 0; gControllers[0].controllerData->stick_y = 0; gControllers[0].controllerData->button = END_DEMO; } else { - // backup the start button if it is pressed, since we don't want the + // Backup the start button if it is pressed, since we don't want the // demo input to override the mask where start may have been pressed. u16 startPushed = gControllers[0].controllerData->button & START_BUTTON; - // perform the demo inputs by assigning the current button mask and the stick inputs. + // Perform the demo inputs by assigning the current button mask and the stick inputs. gControllers[0].controllerData->stick_x = gCurrDemoInput->rawStickX; gControllers[0].controllerData->stick_y = gCurrDemoInput->rawStickY; - /* - to assign the demo input, the button information is stored in - an 8-bit mask rather than a 16-bit mask. this is because only - A, B, Z, Start, and the C-Buttons are used in a demo, as bits - in that order. In order to assign the mask, we need to take the - upper 4 bits (A, B, Z, and Start) and shift then left by 8 to - match the correct input mask. We then add this to the masked - lower 4 bits to get the correct button mask. - */ + // To assign the demo input, the button information is stored in + // an 8-bit mask rather than a 16-bit mask. this is because only + // A, B, Z, Start, and the C-Buttons are used in a demo, as bits + // in that order. In order to assign the mask, we need to take the + // upper 4 bits (A, B, Z, and Start) and shift then left by 8 to + // match the correct input mask. We then add this to the masked + // lower 4 bits to get the correct button mask. gControllers[0].controllerData->button = ((gCurrDemoInput->buttonMask & 0xF0) << 8) + ((gCurrDemoInput->buttonMask & 0xF)); - // if start was pushed, put it into the demo sequence being input to - // end the demo. + // If start was pushed, put it into the demo sequence being input to end the demo. gControllers[0].controllerData->button |= startPushed; - // run the current demo input's timer down. if it hits 0, advance the - // demo input list. + // Run the current demo input's timer down. if it hits 0, advance the demo input list. if (--gCurrDemoInput->timer == 0) { gCurrDemoInput++; } @@ -472,16 +517,17 @@ void run_demo_inputs(void) { } } -// update the controller struct with available inputs if present. +/** + * Update the controller struct with available inputs if present. + */ void read_controller_inputs(void) { s32 i; - // if any controllers are plugged in, update the - // controller information. + // If any controllers are plugged in, update the controller information. if (gControllerBits) { - osRecvMesg(&gSIEventMesgQueue, &D_80339BEC, OS_MESG_BLOCK); + osRecvMesg(&gSIEventMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); osContGetReadData(&gControllerPads[0]); -#ifdef VERSION_SH +#if ENABLE_RUMBLE release_rumble_pak_control(); #endif } @@ -490,8 +536,7 @@ void read_controller_inputs(void) { for (i = 0; i < 2; i++) { struct Controller *controller = &gControllers[i]; - // if we're receiving inputs, update the controller struct - // with the new button info. + // if we're receiving inputs, update the controller struct with the new button info. if (controller->controllerData != NULL) { controller->rawStickX = controller->controllerData->stick_x; controller->rawStickY = controller->controllerData->stick_y; @@ -512,9 +557,9 @@ void read_controller_inputs(void) { } } - // For some reason, player 1's inputs are copied to player 3's port. This - // potentially may have been a way the developers "recorded" the inputs - // for demos, despite record_demo existing. + // For some reason, player 1's inputs are copied to player 3's port. + // This potentially may have been a way the developers "recorded" + // the inputs for demos, despite record_demo existing. gPlayer3Controller->rawStickX = gPlayer1Controller->rawStickX; gPlayer3Controller->rawStickY = gPlayer1Controller->rawStickY; gPlayer3Controller->stickX = gPlayer1Controller->stickX; @@ -524,33 +569,35 @@ void read_controller_inputs(void) { gPlayer3Controller->buttonDown = gPlayer1Controller->buttonDown; } -// initialize the controller structs to point at the OSCont information. +/** + * Initialize the controller structs to point at the OSCont information. + */ void init_controllers(void) { s16 port, cont; - // set controller 1 to point to the set of status/pads for input 1 and + // Set controller 1 to point to the set of status/pads for input 1 and // init the controllers. gControllers[0].statusData = &gControllerStatuses[0]; gControllers[0].controllerData = &gControllerPads[0]; osContInit(&gSIEventMesgQueue, &gControllerBits, &gControllerStatuses[0]); - // strangely enough, the EEPROM probe for save data is done in this function. - // save pak detection? + // Strangely enough, the EEPROM probe for save data is done in this function. + // Save Pak detection? gEepromProbe = osEepromProbe(&gSIEventMesgQueue); - // loop over the 4 ports and link the controller structs to the appropriate + // Loop over the 4 ports and link the controller structs to the appropriate // status and pad. Interestingly, although there are pointers to 3 controllers, // only 2 are connected here. The third seems to have been reserved for debug // purposes and was never connected in the retail ROM, thus gPlayer3Controller // cannot be used, despite being referenced in various code. for (cont = 0, port = 0; port < 4 && cont < 2; port++) { - // is controller plugged in? + // Is controller plugged in? if (gControllerBits & (1 << port)) { - // the game allows you to have just 1 controller plugged + // The game allows you to have just 1 controller plugged // into any port in order to play the game. this was probably // so if any of the ports didn't work, you can have controllers // plugged into any of them and it will work. -#ifdef VERSION_SH +#if ENABLE_RUMBLE gControllers[cont].port = port; #endif gControllers[cont].statusData = &gControllerStatuses[port]; @@ -559,69 +606,83 @@ void init_controllers(void) { } } -void setup_game_memory(void) { - UNUSED u8 pad[8]; +// Game thread core +// ---------------------------------------------------------------------------------------------------- +/** + * Setup main segments and framebuffers. + */ +void setup_game_memory(void) { + UNUSED u64 padding; + + // Setup general Segment 0 set_segment_base_addr(0, (void *) 0x80000000); - osCreateMesgQueue(&D_80339CB8, &D_80339CD4, 1); - osCreateMesgQueue(&gGameVblankQueue, &D_80339CD0, 1); + // Create Mesg Queues + osCreateMesgQueue(&gGfxVblankQueue, gGfxMesgBuf, ARRAY_COUNT(gGfxMesgBuf)); + osCreateMesgQueue(&gGameVblankQueue, gGameMesgBuf, ARRAY_COUNT(gGameMesgBuf)); + // Setup z buffer and framebuffer gPhysicalZBuffer = VIRTUAL_TO_PHYSICAL(gZBuffer); gPhysicalFrameBuffers[0] = VIRTUAL_TO_PHYSICAL(gFrameBuffer0); gPhysicalFrameBuffers[1] = VIRTUAL_TO_PHYSICAL(gFrameBuffer1); gPhysicalFrameBuffers[2] = VIRTUAL_TO_PHYSICAL(gFrameBuffer2); - D_80339CF0 = main_pool_alloc(0x4000, MEMORY_POOL_LEFT); - set_segment_base_addr(17, (void *) D_80339CF0); - func_80278A78(&D_80339D10, gMarioAnims, D_80339CF0); - D_80339CF4 = main_pool_alloc(2048, MEMORY_POOL_LEFT); - set_segment_base_addr(24, (void *) D_80339CF4); - func_80278A78(&gDemo, gDemoInputs, D_80339CF4); + // Setup Mario Animations + gMarioAnimsMemAlloc = main_pool_alloc(0x4000, MEMORY_POOL_LEFT); + set_segment_base_addr(17, (void *) gMarioAnimsMemAlloc); + setup_dma_table_list(&gMarioAnimsBuf, gMarioAnims, gMarioAnimsMemAlloc); + // Setup Demo Inputs List + gDemoInputsMemAlloc = main_pool_alloc(0x800, MEMORY_POOL_LEFT); + set_segment_base_addr(24, (void *) gDemoInputsMemAlloc); + setup_dma_table_list(&gDemoInputsBuf, gDemoInputs, gDemoInputsMemAlloc); + // Setup Level Script Entry load_segment(0x10, _entrySegmentRomStart, _entrySegmentRomEnd, MEMORY_POOL_LEFT); + // Setup Segment 2 (Fonts, Text, etc) load_segment_decompress(2, _segment2_mio0SegmentRomStart, _segment2_mio0SegmentRomEnd); } -// main game loop thread. runs forever as long as the game -// continues. +/** + * Main game loop thread. Runs forever as long as the game continues. + */ void thread5_game_loop(UNUSED void *arg) { struct LevelCommand *addr; setup_game_memory(); -#ifdef VERSION_SH +#if ENABLE_RUMBLE init_rumble_pak_scheduler_queue(); #endif init_controllers(); -#ifdef VERSION_SH +#if ENABLE_RUMBLE create_thread_6(); #endif save_file_load_all(); set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1); - // point addr to the entry point into the level script data. + // Point address to the entry point into the level script data. addr = segmented_to_virtual(level_script_entry); play_music(SEQ_PLAYER_SFX, SEQUENCE_ARGS(0, SEQ_SOUND_PLAYER), 0); set_sound_mode(save_file_get_sound_mode()); - rendering_init(); + render_init(); while (TRUE) { - // if the reset timer is active, run the process to reset the game. + // If the reset timer is active, run the process to reset the game. if (gResetTimer) { draw_reset_bars(); continue; } profiler_log_thread5_time(THREAD5_START); - // if any controllers are plugged in, start read the data for when + // If any controllers are plugged in, start read the data for when // read_controller_inputs is called later. if (gControllerBits) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE block_until_rumble_pak_free(); #endif osContStartReadData(&gSIEventMesgQueue); } audio_game_loop_tick(); - config_gfx_pool(); + select_gfx_pool(); read_controller_inputs(); addr = level_script_execute(addr); diff --git a/src/game/game_init.h b/src/game/game_init.h index 454686ad..1640723b 100644 --- a/src/game/game_init.h +++ b/src/game/game_init.h @@ -9,7 +9,7 @@ #include "types.h" #include "memory.h" -#define GFX_POOL_SIZE 6400 +#define GFX_POOL_SIZE 6400 // Size of how large the master display list (gDisplayListHead) can be struct GfxPool { Gfx buffer[GFX_POOL_SIZE]; @@ -28,14 +28,14 @@ extern struct Controller gControllers[3]; extern OSContStatus gControllerStatuses[4]; extern OSContPad gControllerPads[4]; extern OSMesgQueue gGameVblankQueue; -extern OSMesgQueue D_80339CB8; -extern OSMesg D_80339CD0; -extern OSMesg D_80339CD4; +extern OSMesgQueue gGfxVblankQueue; +extern OSMesg gGameMesgBuf[1]; +extern OSMesg gGfxMesgBuf[1]; extern struct VblankHandler gGameVblankHandler; extern uintptr_t gPhysicalFrameBuffers[3]; extern uintptr_t gPhysicalZBuffer; -extern void *D_80339CF0; -extern void *D_80339CF4; +extern void *gMarioAnimsMemAlloc; +extern void *gDemoInputsMemAlloc; extern struct SPTask *gGfxSPTask; extern Gfx *gDisplayListHead; extern u8 *gGfxPoolEnd; @@ -53,13 +53,13 @@ extern struct DemoInput gRecordedDemoInput; // this area is the demo input + the header. when the demo is loaded in, there is a header the size // of a single word next to the input list. this word is the current ID count. -extern struct MarioAnimation D_80339D10; -extern struct MarioAnimation gDemo; +extern struct DmaHandlerList gMarioAnimsBuf; +extern struct DmaHandlerList gDemoInputsBuf; extern u8 gMarioAnims[]; extern u8 gDemoInputs[]; -extern u16 frameBufferIndex; +extern u16 sRenderingFrameBuffer; extern u32 gGlobalTimer; void setup_game_memory(void); @@ -67,10 +67,10 @@ void thread5_game_loop(UNUSED void *arg); void clear_frame_buffer(s32 color); void clear_viewport(Vp *viewport, s32 color); void make_viewport_clip_rect(Vp *viewport); -void init_render_image(void); +void init_rcp(void); void end_master_display_list(void); -void rendering_init(void); -void config_gfx_pool(void); +void render_init(void); +void select_gfx_pool(void); void display_and_vsync(void); #endif // GAME_INIT_H diff --git a/src/game/hud.c b/src/game/hud.c index 8d4daa54..8c7de524 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -53,7 +53,7 @@ static struct PowerMeterHUD sPowerMeterHUD = { // when the power meter is hidden. s32 sPowerMeterVisibleTimer = 0; -static struct UnusedHUDStruct sUnusedHUDValues = { 0x00, 0x0A, 0x00 }; +UNUSED static struct UnusedHUDStruct sUnusedHUDValues = { 0x00, 0x0A, 0x00 }; static struct CameraHUD sCameraHUD = { CAM_STATUS_NONE }; diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 8190f88d..6bf16738 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -99,7 +99,7 @@ f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE; f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE; s16 gDialogScrollOffsetY = 0; s8 gDialogBoxType = DIALOG_TYPE_ROTATE; -s16 gDialogID = -1; +s16 gDialogID = DIALOG_NONE; s16 gLastDialogPageStrPos = 0; s16 gDialogTextPos = 0; #ifdef VERSION_EU @@ -109,7 +109,7 @@ s8 gDialogLineNum = 1; s8 gLastDialogResponse = 0; u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; -s32 gDialogResponse = 0; +s32 gDialogResponse = DIALOG_RESPONSE_NONE; void create_dl_identity_matrix(void) { @@ -197,6 +197,9 @@ void create_dl_ortho_matrix(void) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH) } +#if !defined(VERSION_JP) && !defined(VERSION_SH) +UNUSED +#endif static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { s32 inPos; u16 bitMask; @@ -878,14 +881,14 @@ s16 get_dialog_id(void) { } void create_dialog_box(s16 dialog) { - if (gDialogID == -1) { + if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogBoxType = DIALOG_TYPE_ROTATE; } } void create_dialog_box_with_var(s16 dialog, s32 dialogVar) { - if (gDialogID == -1) { + if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogVariable = dialogVar; gDialogBoxType = DIALOG_TYPE_ROTATE; @@ -893,14 +896,14 @@ void create_dialog_box_with_var(s16 dialog, s32 dialogVar) { } void create_dialog_inverted_box(s16 dialog) { - if (gDialogID == -1) { + if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogBoxType = DIALOG_TYPE_ZOOM; } } void create_dialog_box_with_response(s16 dialog) { - if (gDialogID == -1) { + if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogBoxType = DIALOG_TYPE_ROTATE; gLastDialogResponse = 1; @@ -917,11 +920,11 @@ void reset_dialog_render_state(void) { gDialogBoxScale = 19.0f; gDialogBoxOpenTimer = 90.0f; gDialogBoxState = DIALOG_STATE_OPENING; - gDialogID = -1; + gDialogID = DIALOG_NONE; gDialogTextPos = 0; gLastDialogResponse = 0; gLastDialogPageStrPos = 0; - gDialogResponse = 0; + gDialogResponse = DIALOG_RESPONSE_NONE; } #if defined(VERSION_JP) || defined(VERSION_SH) @@ -1527,18 +1530,18 @@ void render_dialog_string_color(s8 linesPerBox) { void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order // King Bob-omb (Start), Whomp (Start), King Bob-omb (throw him out), Eyerock (Start), Wiggler (Start) - s16 dialogBossStart[] = { 17, 114, 128, 117, 150 }; + s16 dialogBossStart[] = { DIALOG_017, DIALOG_114, DIALOG_128, DIALOG_117, DIALOG_150 }; // Koopa the Quick (BOB), Koopa the Quick (THI), Penguin Race, Fat Penguin Race (120 stars) - s16 dialogRaceSound[] = { 5, 9, 55, 164 }; + s16 dialogRaceSound[] = { DIALOG_005, DIALOG_009, DIALOG_055, DIALOG_164 }; // Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star - s16 dialogStarSound[] = { 10, 11, 12, 13, 14 }; + s16 dialogStarSound[] = { DIALOG_010, DIALOG_011, DIALOG_012, DIALOG_013, DIALOG_014 }; // King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated) #if BUGFIX_KING_BOB_OMB_FADE_MUSIC - s16 dialogBossStop[] = { 17, 115, 116, 118, 152 }; + s16 dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_116, DIALOG_118, DIALOG_152 }; #else - //! @bug JP misses King Bob-omb defeated dialog "116", meaning that the boss music will still + //! @bug JP misses King Bob-omb defeated DIALOG_116, meaning that the boss music will still //! play after King Bob-omb is defeated until BOB loads it's music after the star cutscene - s16 dialogBossStop[] = { 17, 115, 118, 152 }; + s16 dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_118, DIALOG_152 }; #endif s16 i; @@ -1572,7 +1575,7 @@ void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order } } -s16 gMenuMode = -1; +s16 gMenuMode = MENU_MODE_NONE; u8 gEndCutsceneStrEn0[] = { TEXT_FILE_MARIO_EXCLAMATION }; u8 gEndCutsceneStrEn1[] = { TEXT_POWER_STARS_RESTORED }; @@ -1701,7 +1704,7 @@ void render_dialog_entries(void) { // if the dialog entry is invalid, set the ID to -1. if (segmented_to_virtual(NULL) == dialog) { - gDialogID = -1; + gDialogID = DIALOG_NONE; return; } @@ -1779,11 +1782,11 @@ void render_dialog_entries(void) { if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { gDialogBoxState = DIALOG_STATE_OPENING; - gDialogID = -1; + gDialogID = DIALOG_NONE; gDialogTextPos = 0; gLastDialogResponse = 0; gLastDialogPageStrPos = 0; - gDialogResponse = 0; + gDialogResponse = DIALOG_RESPONSE_NONE; } #if !defined(VERSION_JP) lowerBound = 1; @@ -1841,7 +1844,7 @@ void render_dialog_entries(void) { // Calls a gMenuMode value defined by render_menus_and_dialogs cases void set_menu_mode(s16 mode) { - if (gMenuMode == -1) { + if (gMenuMode == MENU_MODE_NONE) { gMenuMode = mode; } } @@ -2062,7 +2065,7 @@ void print_peach_letter_message(void) { if (gCutsceneMsgTimer > (PEACH_MESSAGE_TIMER + 20)) { gCutsceneMsgIndex = -1; gCutsceneMsgFade = 0; //! uselessly reset since the next execution will just set it to 0 again. - gDialogID = -1; + gDialogID = DIALOG_NONE; gCutsceneMsgTimer = 0; return; // return to avoid incrementing the timer } @@ -2336,17 +2339,17 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { print_generic_string(x + TXT2_X, y - 13, textNormalFixed); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, ((index[0] - 1) * xIndex) + x, y + Y_VAL7, 0); + create_dl_translation_matrix(MENU_MTX_PUSH, ((*index - 1) * xIndex) + x, y + Y_VAL7, 0); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - switch (index[0]) { - case 1: - cam_select_alt_mode(1); + switch (*index) { + case CAM_SELECTION_MARIO: + cam_select_alt_mode(CAM_SELECTION_MARIO); break; - case 2: - cam_select_alt_mode(2); + case CAM_SELECTION_FIXED: + cam_select_alt_mode(CAM_SELECTION_FIXED); break; } } @@ -2393,18 +2396,18 @@ void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { print_generic_string(x + 10, y - 2, textContinue); print_generic_string(x + 10, y - 17, textExitCourse); - if (index[0] != 3) { + if (*index != MENU_OPT_CAMERA_ANGLE_R) { print_generic_string(x + 10, y - 33, textCameraAngleR); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((index[0] - 1) * yIndex)) - Y_VAL8, 0); + create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((*index - 1) * yIndex)) - Y_VAL8, 0); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } - if (index[0] == 3) { + if (*index == MENU_OPT_CAMERA_ANGLE_R) { render_pause_camera_options(x - 42, y - 42, &gDialogCameraAngleIndex, 110); } } @@ -2597,7 +2600,7 @@ s32 gCourseCompleteCoins = 0; s8 gHudFlash = 0; s16 render_pause_courses_and_castle(void) { - s16 num; + s16 index; #ifdef VERSION_EU gInGameLanguage = eu_get_language(); @@ -2605,7 +2608,7 @@ s16 render_pause_courses_and_castle(void) { switch (gDialogBoxState) { case DIALOG_STATE_OPENING: - gDialogLineNum = 1; + gDialogLineNum = MENU_OPT_DEFAULT; gDialogTextAlpha = 0; level_set_transition(-1, NULL); #ifdef VERSION_JP @@ -2641,15 +2644,15 @@ s16 render_pause_courses_and_castle(void) { level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_2, gGlobalSoundSource); gDialogBoxState = DIALOG_STATE_OPENING; - gMenuMode = -1; + gMenuMode = MENU_MODE_NONE; - if (gDialogLineNum == 2) { - num = gDialogLineNum; - } else { - num = 1; + if (gDialogLineNum == MENU_OPT_EXIT_COURSE) { + index = gDialogLineNum; + } else { // MENU_OPT_CONTINUE or MENU_OPT_CAMERA_ANGLE_R + index = MENU_OPT_DEFAULT; } - return num; + return index; } break; case DIALOG_STATE_HORIZONTAL: @@ -2667,10 +2670,10 @@ s16 render_pause_courses_and_castle(void) { { level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_2, gGlobalSoundSource); - gMenuMode = -1; + gMenuMode = MENU_MODE_NONE; gDialogBoxState = DIALOG_STATE_OPENING; - return 1; + return MENU_OPT_DEFAULT; } break; } @@ -2679,7 +2682,7 @@ s16 render_pause_courses_and_castle(void) { gDialogTextAlpha += 25; } - return 0; + return MENU_OPT_NONE; } #if defined(VERSION_JP) @@ -2770,7 +2773,7 @@ void print_hud_course_complete_coins(s16 x, s16 y) { if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) { play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); - gMarioState[0].numLives++; + gMarioState->numLives++; } } @@ -2976,7 +2979,7 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 sp6e) gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL9, y - ((index[0] - 1) * sp6e), 0); + create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL9, y - ((*index - 1) * sp6e), 0); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); @@ -2985,7 +2988,7 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 sp6e) } s16 render_course_complete_screen(void) { - s16 num; + s16 index; #ifdef VERSION_EU gInGameLanguage = eu_get_language(); #endif @@ -2997,7 +3000,7 @@ s16 render_course_complete_screen(void) { gDialogBoxState = DIALOG_STATE_VERTICAL; level_set_transition(-1, NULL); gDialogTextAlpha = 0; - gDialogLineNum = 1; + gDialogLineNum = MENU_OPT_DEFAULT; } break; case DIALOG_STATE_VERTICAL: @@ -3019,14 +3022,14 @@ s16 render_course_complete_screen(void) { level_set_transition(0, NULL); play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); gDialogBoxState = DIALOG_STATE_OPENING; - gMenuMode = -1; - num = gDialogLineNum; + gMenuMode = MENU_MODE_NONE; + index = gDialogLineNum; gCourseDoneMenuTimer = 0; gCourseCompleteCoins = 0; gCourseCompleteCoinsEqual = 0; gHudFlash = 0; - return num; + return index; } break; } @@ -3037,41 +3040,40 @@ s16 render_course_complete_screen(void) { gCourseDoneMenuTimer++; - return 0; + return MENU_OPT_NONE; } -// Only case 1 and 2 are used s16 render_menus_and_dialogs(void) { - s16 mode = 0; + s16 index = MENU_OPT_NONE; create_dl_ortho_matrix(); - if (gMenuMode != -1) { + if (gMenuMode != MENU_MODE_NONE) { switch (gMenuMode) { - case 0: - mode = render_pause_courses_and_castle(); + case MENU_MODE_UNUSED_0: + index = render_pause_courses_and_castle(); break; - case 1: - mode = render_pause_courses_and_castle(); + case MENU_MODE_RENDER_PAUSE_SCREEN: + index = render_pause_courses_and_castle(); break; - case 2: - mode = render_course_complete_screen(); + case MENU_MODE_RENDER_COURSE_COMPLETE_SCREEN: + index = render_course_complete_screen(); break; - case 3: - mode = render_course_complete_screen(); + case MENU_MODE_UNUSED_3: + index = render_course_complete_screen(); break; } gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000; - } else if (gDialogID != -1) { + } else if (gDialogID != DIALOG_NONE) { // The Peach "Dear Mario" message needs to be repositioned separately - if (gDialogID == 20) { + if (gDialogID == DIALOG_020) { print_peach_letter_message(); - return mode; + return index; } render_dialog_entries(); gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000; } - return mode; + return index; } diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index c68e37ba..63920c8e 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -27,9 +27,13 @@ #define HUD_LUT_DIFF HUD_LUT_GLOBAL #endif -#define RENDER_PAUSE_SCREEN 1 -#define RENDER_COURSE_DONE_SCREEN 2 - +enum MenuMode { + MENU_MODE_NONE = -1, + MENU_MODE_UNUSED_0, + MENU_MODE_RENDER_PAUSE_SCREEN, + MENU_MODE_RENDER_COURSE_COMPLETE_SCREEN, + MENU_MODE_UNUSED_3 +}; extern s8 gDialogCourseActNum; extern s8 gHudFlash; @@ -105,6 +109,14 @@ enum DialogSpecialChars { DIALOG_CHAR_TERMINATOR = 0xFF }; +// gDialogResponse +enum DialogResponseDefines { + DIALOG_RESPONSE_NONE, + DIALOG_RESPONSE_YES, + DIALOG_RESPONSE_NO, + DIALOG_RESPONSE_NOT_DEFINED +}; + extern s32 gDialogResponse; extern u16 gDialogColorFadeTimer; extern s8 gLastDialogLineNum; diff --git a/src/game/interaction.c b/src/game/interaction.c index 1ae0b24e..0d00061d 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -336,7 +336,7 @@ void mario_stop_riding_and_holding(struct MarioState *m) { mario_stop_riding_object(m); if (m->action == ACT_RIDING_HOOT) { - m->usedObj->oInteractStatus = 0; + m->usedObj->oInteractStatus = FALSE; m->usedObj->oHootMarioReleaseTime = gGlobalTimer; } } @@ -526,7 +526,7 @@ void hit_object_from_below(struct MarioState *m, UNUSED struct Object *o) { set_camera_shake_from_hit(SHAKE_HIT_FROM_BELOW); } -static u32 unused_determine_knockback_action(struct MarioState *m) { +UNUSED static u32 unused_determine_knockback_action(struct MarioState *m) { u32 bonkAction; s16 angleToObject = mario_obj_angle_to_object(m, m->interactObj); s16 facingDYaw = angleToObject - m->faceAngle[1]; @@ -699,7 +699,7 @@ u32 take_damage_from_interact_object(struct MarioState *m) { m->hurtCounter += 4 * damage; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif set_camera_shake_from_hit(shake); @@ -750,7 +750,7 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object * && m->numCoins >= 100) { bhv_spawn_star_no_level_exit(6); } -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (o->oDamageOrCoinValue >= 2) { queue_rumble_data(5, 80); } @@ -773,7 +773,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O if (m->health >= 0x100) { mario_stop_riding_and_holding(m); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif @@ -876,7 +876,7 @@ u32 interact_warp(struct MarioState *m, UNUSED u32 interactType, struct Object * m->interactObj = o; m->usedObj = o; -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (o->collisionData == segmented_to_virtual(warp_pipe_seg3_collision_03009AC8)) { play_sound(SOUND_MENU_ENTER_PIPE, m->marioObj->header.gfx.cameraToObject); queue_rumble_data(15, 80); @@ -1100,7 +1100,7 @@ u32 interact_tornado(struct MarioState *m, UNUSED u32 interactType, struct Objec marioObj->oMarioTornadoPosY = m->pos[1] - o->oPosY; play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(30, 60); #endif return set_mario_action(m, ACT_TORNADO_TWIRLING, m->action == ACT_TWIRLING); @@ -1123,7 +1123,7 @@ u32 interact_whirlpool(struct MarioState *m, UNUSED u32 interactType, struct Obj marioObj->oMarioWhirlpoolPosY = m->pos[1] - o->oPosY; play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(30, 60); #endif return set_mario_action(m, ACT_CAUGHT_IN_WHIRLPOOL, 0); @@ -1159,7 +1159,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP) && !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif o->oInteractStatus = INT_STATUS_INTERACTED; @@ -1238,7 +1238,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object m->interactObj = o; if (interaction & INT_ATTACK_NOT_FROM_BELOW) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif push_mario_out_of_object(m, o, 5.0f); @@ -1263,7 +1263,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object push_mario_out_of_object(m, o, 5.0f); drop_and_set_mario_action(m, bully_knock_back_mario(m), 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return TRUE; @@ -1282,7 +1282,7 @@ u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object take_damage_from_interact_object(m); play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(70, 60); #endif @@ -1301,7 +1301,7 @@ u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object return FALSE; } -static u32 interact_stub(UNUSED struct MarioState *m, UNUSED u32 interactType, struct Object *o) { +UNUSED static u32 interact_stub(UNUSED struct MarioState *m, UNUSED u32 interactType, struct Object *o) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { sDelayInvincTimer = TRUE; } @@ -1331,7 +1331,7 @@ u32 interact_hit_from_below(struct MarioState *m, UNUSED u32 interactType, struc } if (interaction & INT_ANY_ATTACK) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif attack_object(o, interaction); @@ -1373,7 +1373,7 @@ u32 interact_bounce_top(struct MarioState *m, UNUSED u32 interactType, struct Ob } if (interaction & INT_ATTACK_NOT_FROM_BELOW) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif attack_object(o, interaction); @@ -1495,7 +1495,7 @@ u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struc update_mario_sound_and_camera(m); play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return set_mario_action(m, ACT_GRABBED, 0); @@ -1546,7 +1546,7 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object * marioObj->oMarioPoleYawVel = (s32)(m->forwardVel * 0x100 + 0x1000); #endif reset_mario_pitch(m); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return set_mario_action(m, ACT_GRAB_POLE_FAST, 0); @@ -1564,11 +1564,12 @@ u32 interact_hoot(struct MarioState *m, UNUSED u32 interactType, struct Object * if (actionId >= 0x080 && actionId < 0x098 && (gGlobalTimer - m->usedObj->oHootMarioReleaseTime > 30)) { mario_stop_riding_and_holding(m); - o->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; + + o->oInteractStatus = TRUE; //! Note: Not a flag, treated as a TRUE/FALSE statement m->interactObj = o; m->usedObj = o; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif update_mario_sound_and_camera(m); @@ -1781,7 +1782,7 @@ void mario_process_interactions(struct MarioState *m) { if (!(m->action & ACT_FLAG_INTANGIBLE) && m->collidedObjInteractTypes != 0) { s32 i; - for (i = 0; i < 31; i++) { + for (i = 0; i < ARRAY_COUNT(sInteractionHandlers); i++) { u32 interactType = sInteractionHandlers[i].interactType; if (m->collidedObjInteractTypes & interactType) { struct Object *object = mario_get_collided_object(m, interactType); diff --git a/src/game/interaction.h b/src/game/interaction.h index dd27aad8..3f9e5b9b 100644 --- a/src/game/interaction.h +++ b/src/game/interaction.h @@ -80,14 +80,17 @@ #define INT_STATUS_ATTACK_MASK 0x000000FF -#define INT_STATUS_HOOT_GRABBED_BY_MARIO (1 << 0) /* 0x00000001 */ -#define INT_STATUS_MARIO_UNK1 (1 << 1) /* 0x00000002 */ +// Mario Interaction Status +#define INT_STATUS_MARIO_STUNNED (1 << 0) /* 0x00000001 */ +#define INT_STATUS_MARIO_KNOCKBACK_DMG (1 << 1) /* 0x00000002 */ #define INT_STATUS_MARIO_UNK2 (1 << 2) /* 0x00000004 */ #define INT_STATUS_MARIO_DROP_OBJECT (1 << 3) /* 0x00000008 */ -#define INT_STATUS_HIT_BY_SHOCKWAVE (1 << 4) /* 0x00000010 */ +#define INT_STATUS_MARIO_SHOCKWAVE (1 << 4) /* 0x00000010 */ #define INT_STATUS_MARIO_UNK5 (1 << 5) /* 0x00000020 */ #define INT_STATUS_MARIO_UNK6 (1 << 6) /* 0x00000040 */ #define INT_STATUS_MARIO_UNK7 (1 << 7) /* 0x00000080 */ + +// Object Interaction Status #define INT_STATUS_GRABBED_MARIO (1 << 11) /* 0x00000800 */ #define INT_STATUS_ATTACKED_MARIO (1 << 13) /* 0x00002000 */ #define INT_STATUS_WAS_ATTACKED (1 << 14) /* 0x00004000 */ diff --git a/src/game/level_update.c b/src/game/level_update.c index 4ecb9024..907a0120 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -212,10 +212,10 @@ u16 level_control_timer(s32 timerOp) { } u32 pressed_pause(void) { - u32 val4 = get_dialog_id() >= 0; + u32 dialogActive = get_dialog_id() >= 0; u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0; - if (!intangible && !val4 && !gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE + if (!intangible && !dialogActive && !gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE && (gPlayer1Controller->buttonPressed & START_BUTTON)) { return TRUE; } @@ -266,7 +266,7 @@ void load_level_init_text(u32 arg) { gotAchievement = save_file_get_flags() & SAVE_FLAG_HAVE_WING_CAP; break; - case 255: + case (u8)DIALOG_NONE: // 255, cast value to u8 to match (-1) gotAchievement = TRUE; break; @@ -689,7 +689,7 @@ void initiate_painting_warp(void) { play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); fadeout_music(398); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(80, 70); func_sh_8024C89C(1); #endif @@ -1004,7 +1004,7 @@ s32 play_mode_normal(void) { set_play_mode(PLAY_MODE_CHANGE_AREA); } else if (pressed_pause()) { lower_background_noise(1); -#ifdef VERSION_SH +#if ENABLE_RUMBLE cancel_rumble(); #endif gCameraMovementFlags |= CAM_MOVE_PAUSE_SCREEN; @@ -1016,15 +1016,13 @@ s32 play_mode_normal(void) { } s32 play_mode_paused(void) { - if (gPauseScreenMode == 0) { - set_menu_mode(RENDER_PAUSE_SCREEN); - } else if (gPauseScreenMode == 1) { + if (gMenuOptSelectIndex == MENU_OPT_NONE) { + set_menu_mode(MENU_MODE_RENDER_PAUSE_SCREEN); + } else if (gMenuOptSelectIndex == MENU_OPT_DEFAULT) { raise_background_noise(1); gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; set_play_mode(PLAY_MODE_NORMAL); - } else { - // Exit level - + } else { // MENU_OPT_EXIT_COURSE if (gDebugLevelSelect) { fade_into_special_warp(-9, 1); } else { @@ -1118,7 +1116,7 @@ s32 play_mode_change_level(void) { /** * Unused play mode. Doesn't call transition update and doesn't reset transition at the end. */ -static s32 play_mode_unused(void) { +UNUSED static s32 play_mode_unused(void) { if (--sTransitionTimer == -1) { gHudDisplay.flags = HUD_DISPLAY_NONE; @@ -1217,7 +1215,7 @@ s32 init_level(void) { set_background_music(gCurrentArea->musicParam, gCurrentArea->musicParam2, 0); } } -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (gCurrDemoInput == NULL) { cancel_rumble(); } diff --git a/src/game/macro_special_objects.c b/src/game/macro_special_objects.c index a0ef16ae..cdb5e378 100644 --- a/src/game/macro_special_objects.c +++ b/src/game/macro_special_objects.c @@ -79,7 +79,7 @@ void spawn_macro_abs_special(s32 model, const BehaviorScript *behavior, s16 x, s newObj->oMacroUnk110 = (f32) unkC; } -static void spawn_macro_coin_unknown(const BehaviorScript *behavior, s16 a1[]) { +UNUSED static void spawn_macro_coin_unknown(const BehaviorScript *behavior, s16 a1[]) { struct Object *sp3C; s16 model; @@ -203,7 +203,7 @@ void spawn_macro_objects_hardcoded(s16 areaIndex, s16 *macroObjList) { // However, BBH doesn't use this function so this might just be an early test? switch (macroObjPreset) { case 0: - spawn_macro_abs_yrot_2params(MODEL_NONE, bhvBooBossSpawnedBridge, macroObjX, macroObjY, + spawn_macro_abs_yrot_2params(MODEL_NONE, bhvBooStaircase, macroObjX, macroObjY, macroObjZ, macroObjRY, 0); break; case 1: diff --git a/src/game/main.c b/src/game/main.c index 9615f25a..1a9d9e7e 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -26,7 +26,7 @@ OSThread gGameLoopThread; OSThread gSoundThread; OSIoMesg gDmaIoMesg; -OSMesg D_80339BEC; +OSMesg gMainReceivedMesg; OSMesgQueue gDmaMesgQueue; OSMesgQueue gSIEventMesgQueue; @@ -50,7 +50,7 @@ struct SPTask *sNextDisplaySPTask = NULL; s8 sAudioEnabled = TRUE; u32 gNumVblanks = 0; s8 gResetTimer = 0; -s8 D_8032C648 = 0; +s8 gNmiResetBarsTimer = 0; s8 gDebugLevelSelect = FALSE; s8 D_8032C650 = 0; @@ -89,6 +89,10 @@ void unknown_main_func(void) { // uninitialized OSTime time; u32 b; +#ifdef AVOID_UB + time = 0; + b = 0; +#endif osSetTime(time); osMapTLB(0, b, NULL, 0, 0, 0); @@ -143,7 +147,7 @@ extern void func_sh_802f69cc(void); void handle_nmi_request(void) { gResetTimer = 1; - D_8032C648 = 0; + gNmiResetBarsTimer = 0; stop_sounds_in_continuous_banks(); sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_BACKGROUND); fadeout_music(90); @@ -253,7 +257,7 @@ void handle_vblank(void) { start_sptask(M_GFXTASK); } } -#ifdef VERSION_SH +#if ENABLE_RUMBLE rumble_thread_update_vi(); #endif @@ -386,7 +390,7 @@ void dispatch_audio_sptask(struct SPTask *spTask) { } } -void send_display_list(struct SPTask *spTask) { +void exec_display_list(struct SPTask *spTask) { if (spTask != NULL) { osWritebackDCacheAll(); spTask->state = SPTASK_STATE_NOT_STARTED; diff --git a/src/game/main.h b/src/game/main.h index 58bd659e..91f99015 100644 --- a/src/game/main.h +++ b/src/game/main.h @@ -1,6 +1,8 @@ #ifndef MAIN_H #define MAIN_H +#include "config.h" + struct RumbleData { u8 unk00; u8 unk01; @@ -24,7 +26,7 @@ extern OSThread gIdleThread; extern OSThread gMainThread; extern OSThread gGameLoopThread; extern OSThread gSoundThread; -#ifdef VERSION_SH +#if ENABLE_RUMBLE extern OSThread gRumblePakThread; extern s32 gRumblePakPfs; // Actually an OSPfs but we don't have that header yet @@ -33,7 +35,7 @@ extern s32 gRumblePakPfs; // Actually an OSPfs but we don't have that header yet extern OSMesgQueue gPIMesgQueue; extern OSMesgQueue gIntrMesgQueue; extern OSMesgQueue gSPTaskMesgQueue; -#ifdef VERSION_SH +#if ENABLE_RUMBLE extern OSMesgQueue gRumblePakSchedulerMesgQueue; extern OSMesgQueue gRumbleThreadVIMesgQueue; #endif @@ -43,10 +45,10 @@ extern OSMesg gSIEventMesgBuf[1]; extern OSMesg gIntrMesgBuf[16]; extern OSMesg gUnknownMesgBuf[16]; extern OSIoMesg gDmaIoMesg; -extern OSMesg D_80339BEC; +extern OSMesg gMainReceivedMesg; extern OSMesgQueue gDmaMesgQueue; extern OSMesgQueue gSIEventMesgQueue; -#ifdef VERSION_SH +#if ENABLE_RUMBLE extern OSMesg gRumblePakSchedulerMesgBuf[1]; extern OSMesg gRumbleThreadVIMesgBuf[1]; @@ -59,7 +61,7 @@ extern struct VblankHandler *gVblankHandler2; extern struct SPTask *gActiveSPTask; extern u32 gNumVblanks; extern s8 gResetTimer; -extern s8 D_8032C648; +extern s8 gNmiResetBarsTimer; extern s8 gDebugLevelSelect; extern s8 D_8032C650; extern s8 gShowProfiler; @@ -67,6 +69,6 @@ extern s8 gShowDebugText; void set_vblank_handler(s32 index, struct VblankHandler *handler, OSMesgQueue *queue, OSMesg *msg); void dispatch_audio_sptask(struct SPTask *spTask); -void send_display_list(struct SPTask *spTask); +void exec_display_list(struct SPTask *spTask); #endif // MAIN_H diff --git a/src/game/mario.c b/src/game/mario.c index 96df7938..634d3ecc 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -63,9 +63,9 @@ s32 is_anim_past_end(struct MarioState *m) { */ s16 set_mario_animation(struct MarioState *m, s32 targetAnimID) { struct Object *o = m->marioObj; - struct Animation *targetAnim = m->animation->targetAnim; + struct Animation *targetAnim = m->animList->bufTarget; - if (load_patchable_table(m->animation, targetAnimID)) { + if (load_patchable_table(m->animList, targetAnimID)) { targetAnim->values = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->values); targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index); } @@ -96,9 +96,9 @@ s16 set_mario_animation(struct MarioState *m, s32 targetAnimID) { */ s16 set_mario_anim_with_accel(struct MarioState *m, s32 targetAnimID, s32 accel) { struct Object *o = m->marioObj; - struct Animation *targetAnim = m->animation->targetAnim; + struct Animation *targetAnim = m->animList->bufTarget; - if (load_patchable_table(m->animation, targetAnimID)) { + if (load_patchable_table(m->animList, targetAnimID)) { targetAnim->values = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->values); targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index); } @@ -1393,10 +1393,11 @@ void update_mario_inputs(struct MarioState *m) { if (!(m->input & (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED))) { m->input |= INPUT_UNKNOWN_5; } - + + // These 3 flags are defined by Bowser stomping attacks if (m->marioObj->oInteractStatus - & (INT_STATUS_HOOT_GRABBED_BY_MARIO | INT_STATUS_MARIO_UNK1 | INT_STATUS_HIT_BY_SHOCKWAVE)) { - m->input |= INPUT_UNKNOWN_10; + & (INT_STATUS_MARIO_STUNNED | INT_STATUS_MARIO_KNOCKBACK_DMG | INT_STATUS_MARIO_SHOCKWAVE)) { + m->input |= INPUT_STOMPED; } // This function is located near other unused trampoline functions, @@ -1495,8 +1496,8 @@ void update_mario_health(struct MarioState *m) { // Play a noise to alert the player when Mario is close to drowning. if (((m->action & ACT_GROUP_MASK) == ACT_GROUP_SUBMERGED) && (m->health < 0x300)) { play_sound(SOUND_MOVING_ALMOST_DROWNING, gGlobalSoundSource); -#ifdef VERSION_SH - if (!gRumblePakTimer) { +#if ENABLE_RUMBLE + if (gRumblePakTimer == 0) { gRumblePakTimer = 36; if (is_rumble_finished_and_queue_empty()) { queue_rumble_data(3, 30); @@ -1661,7 +1662,7 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) { * An unused and possibly a debug function. Z + another button input * sets Mario with a different cap. */ -static void debug_update_mario_cap(u16 button, s32 flags, u16 capTimer, u16 capMusic) { +UNUSED static void debug_update_mario_cap(u16 button, s32 flags, u16 capTimer, u16 capMusic) { // This checks for Z_TRIG instead of Z_DOWN flag // (which is also what other debug functions do), // so likely debug behavior rather than unused behavior. @@ -1677,7 +1678,7 @@ static void debug_update_mario_cap(u16 button, s32 flags, u16 capTimer, u16 capM } } -#ifdef VERSION_SH +#if ENABLE_RUMBLE void func_sh_8025574C(void) { if (gMarioState->particleFlags & PARTICLE_HORIZONTAL_STAR) { queue_rumble_data(5, 80); @@ -1770,7 +1771,7 @@ s32 execute_mario_action(UNUSED struct Object *o) { play_infinite_stairs_music(); gMarioState->marioObj->oInteractStatus = 0; -#ifdef VERSION_SH +#if ENABLE_RUMBLE func_sh_8025574C(); #endif @@ -1875,7 +1876,7 @@ void init_mario_from_save_file(void) { gMarioState->statusForCamera = &gPlayerCameraState[0]; gMarioState->marioBodyState = &gBodyStates[0]; gMarioState->controller = &gControllers[0]; - gMarioState->animation = &D_80339D10; + gMarioState->animList = &gMarioAnimsBuf; gMarioState->numCoins = 0; gMarioState->numStars = diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 34090a55..387e202c 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -65,7 +65,11 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { fallHeight = m->peakHeight - m->pos[1]; #pragma GCC diagnostic push +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wtype-limits" +#endif //! Never true if (m->actionState == ACT_GROUND_POUND) { @@ -80,7 +84,7 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { if (m->vel[1] < -55.0f) { if (fallHeight > 3000.0f) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 16 : 24; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif set_camera_shake_from_hit(SHAKE_FALL_DAMAGE); @@ -89,7 +93,7 @@ s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { } else if (fallHeight > damageHeight && !mario_floor_is_slippery(m)) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 8 : 12; m->squishTimer = 30; -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif set_camera_shake_from_hit(SHAKE_FALL_DAMAGE); @@ -133,7 +137,7 @@ s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) { #endif m->particleFlags |= PARTICLE_MIST_CIRCLE; drop_and_set_mario_action(m, ACT_FEET_STUCK_IN_GROUND, 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return TRUE; @@ -385,7 +389,7 @@ u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, set_mario_animation(m, animation); if (m->forwardVel > 16.0f) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 40); #endif mario_bonk_reflection(m, FALSE); @@ -493,7 +497,7 @@ s32 act_triple_jump(struct MarioState *m) { #endif common_air_action_step(m, ACT_TRIPLE_JUMP_LAND, MARIO_ANIM_TRIPLE_JUMP, 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->action == ACT_TRIPLE_JUMP_LAND) { queue_rumble_data(5, 40); } @@ -509,7 +513,7 @@ s32 act_backflip(struct MarioState *m) { play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAH_WAH_HOO); common_air_action_step(m, ACT_BACKFLIP_LAND, MARIO_ANIM_BACKFLIP, 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->action == ACT_BACKFLIP_LAND) { queue_rumble_data(5, 40); } @@ -641,7 +645,7 @@ s32 act_long_jump(struct MarioState *m) { } common_air_action_step(m, ACT_LONG_JUMP_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->action == ACT_LONG_JUMP_LAND) { queue_rumble_data(5, 40); } @@ -712,7 +716,7 @@ s32 act_twirling(struct MarioState *m) { } m->marioObj->header.gfx.angle[1] += m->twirlYaw; -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -749,7 +753,7 @@ s32 act_dive(struct MarioState *m) { case AIR_STEP_LANDED: if (should_get_stuck_in_ground(m) && m->faceAngle[0] == -0x2AAA) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif #ifdef VERSION_JP @@ -947,7 +951,7 @@ s32 act_ground_pound(struct MarioState *m) { stepResult = perform_air_step(m, 0); if (stepResult == AIR_STEP_LANDED) { if (should_get_stuck_in_ground(m)) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif #ifdef VERSION_JP @@ -998,7 +1002,7 @@ s32 act_burning_jump(struct MarioState *m) { if (m->health < 0x100) { m->health = 0xFF; } -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1020,7 +1024,7 @@ s32 act_burning_fall(struct MarioState *m) { if (m->health < 0x100) { m->health = 0xFF; } -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1071,7 +1075,7 @@ s32 act_crazy_box_bounce(struct MarioState *m) { m->heldObj = NULL; set_mario_action(m, ACT_STOMACH_SLIDE, 0); } -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif m->particleFlags |= PARTICLE_MIST_CIRCLE; @@ -1103,7 +1107,7 @@ u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFall break; case AIR_STEP_LANDED: -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->action != ACT_SOFT_BONK) { queue_rumble_data(5, 40); } @@ -1505,13 +1509,13 @@ s32 act_hold_butt_slide_air(struct MarioState *m) { } s32 act_lava_boost(struct MarioState *m) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (!(m->flags & MARIO_MARIO_SOUND_PLAYED)) { +#endif play_sound_if_no_flag(m, SOUND_MARIO_ON_FIRE, MARIO_MARIO_SOUND_PLAYED); +#if ENABLE_RUMBLE queue_rumble_data(5, 80); } -#else - play_sound_if_no_flag(m, SOUND_MARIO_ON_FIRE, MARIO_MARIO_SOUND_PLAYED); #endif if (!(m->input & INPUT_NONZERO_ANALOG)) { @@ -1529,7 +1533,7 @@ s32 act_lava_boost(struct MarioState *m) { } m->vel[1] = 84.0f; play_sound(SOUND_MARIO_ON_FIRE, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif } else { @@ -1567,7 +1571,7 @@ s32 act_lava_boost(struct MarioState *m) { } m->marioBodyState->eyeState = MARIO_EYES_DEAD; -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1679,7 +1683,7 @@ s32 act_shot_from_cannon(struct MarioState *m) { set_mario_action(m, ACT_DIVE_SLIDE, 0); m->faceAngle[0] = 0; set_camera_mode(m->area->camera, m->area->camera->defMode, 1); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif break; @@ -1713,7 +1717,7 @@ s32 act_shot_from_cannon(struct MarioState *m) { if (m->vel[1] > 0.0f) { m->particleFlags |= PARTICLE_DUST; } -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1778,7 +1782,7 @@ s32 act_flying(struct MarioState *m) { m->faceAngle[0] = 0; set_camera_mode(m->area->camera, m->area->camera->defMode, 1); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 60); #endif break; @@ -1833,7 +1837,7 @@ s32 act_flying(struct MarioState *m) { play_sound(SOUND_MARIO_YAHOO_WAHA_YIPPEE + ((gAudioRandom % 5) << 16), m->marioObj->header.gfx.cameraToObject); #endif -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(50, 40); #endif } @@ -1849,7 +1853,7 @@ s32 act_riding_hoot(struct MarioState *m) { m->usedObj->oHootMarioReleaseTime = gGlobalTimer; play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(4, 40); #endif return set_mario_action(m, ACT_FREEFALL, 0); @@ -1907,7 +1911,7 @@ s32 act_flying_triple_jump(struct MarioState *m) { if (is_anim_past_end(m)) { set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(8, 80); #endif m->actionState = 1; @@ -1970,7 +1974,7 @@ s32 act_vertical_wind(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP); if (m->marioObj->header.gfx.animInfo.animFrame == 1) { play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(8, 80); #endif } diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 22690873..35460063 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -171,7 +171,7 @@ s32 act_holding_pole(struct MarioState *m) { } } play_climbing_sounds(m, 2); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif set_sound_moving_speed(SOUND_BANK_MOVING, marioObj->oMarioPoleYawVel / 0x100 * 2); @@ -385,7 +385,7 @@ void update_hang_stationary(struct MarioState *m) { } s32 act_start_hanging(struct MarioState *m) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->actionTimer++ == 0) { queue_rumble_data(5, 80); } @@ -470,7 +470,7 @@ s32 act_hang_moving(struct MarioState *m) { if (m->marioObj->header.gfx.animInfo.animFrame == 12) { play_sound(SOUND_ACTION_HANGING_STEP, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(1, 30); #endif } @@ -563,8 +563,8 @@ s32 act_ledge_grab(struct MarioState *m) { return set_mario_action(m, ACT_LEDGE_CLIMB_FAST, 0); } - if (m->input & INPUT_UNKNOWN_10) { - if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK1) { + if (m->input & INPUT_STOMPED) { + if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_KNOCKBACK_DMG) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18; } return let_go_of_ledge(m); @@ -662,7 +662,7 @@ s32 act_grabbed(struct MarioState *m) { m->faceAngle[1] = m->usedObj->oMoveAngleYaw; vec3f_copy(m->pos, m->marioObj->header.gfx.pos); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 60); #endif @@ -744,14 +744,14 @@ s32 act_in_cannon(struct MarioState *m) { m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; set_mario_action(m, ACT_SHOT_FROM_CANNON, 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); #endif m->usedObj->oAction = 2; return FALSE; } else if (m->faceAngle[0] != startFacePitch || m->faceAngle[1] != startFaceYaw) { play_sound(SOUND_MOVING_AIM_CANNON, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers_2(0); #endif } @@ -838,7 +838,7 @@ s32 act_tornado_twirling(struct MarioState *m) { vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1] + m->twirlYaw, 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index e2cbbb6b..ad95b9a8 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -18,6 +18,7 @@ #include "level_table.h" #include "level_update.h" #include "mario.h" +#include "mario_actions_cutscene.h" #include "mario_actions_moving.h" #include "mario_step.h" #include "moving_texture.h" @@ -28,9 +29,6 @@ #include "sound_init.h" #include "rumble_init.h" -// TODO: put this elsewhere -enum SaveOption { SAVE_OPT_SAVE_AND_CONTINUE = 1, SAVE_OPT_SAVE_AND_QUIT, SAVE_OPT_CONTINUE_DONT_SAVE }; - static struct Object *sIntroWarpPipeObj; static struct Object *sEndPeachObj; static struct Object *sEndRightToadObj; @@ -216,9 +214,9 @@ s32 geo_switch_peach_eyes(s32 run, struct GraphNode *node, UNUSED s32 a2) { } // unused -static void stub_is_textbox_active(u16 *a0) { - if (get_dialog_id() == -1) { - *a0 = 0; +UNUSED static void stub_is_textbox_active(u16 *arg) { + if (get_dialog_id() == DIALOG_NONE) { + *arg = 0; } } @@ -250,23 +248,23 @@ s32 get_star_collection_dialog(struct MarioState *m) { void handle_save_menu(struct MarioState *m) { s32 dialogID; // wait for the menu to show up - if (is_anim_past_end(m) && gSaveOptSelectIndex != 0) { + if (is_anim_past_end(m) && gSaveOptSelectIndex != MENU_OPT_NONE) { // save and continue / save and quit - if (gSaveOptSelectIndex == SAVE_OPT_SAVE_AND_CONTINUE || gSaveOptSelectIndex == SAVE_OPT_SAVE_AND_QUIT) { + if (gSaveOptSelectIndex == MENU_OPT_SAVE_AND_CONTINUE || gSaveOptSelectIndex == MENU_OPT_SAVE_AND_QUIT) { save_file_do_save(gCurrSaveFileNum - 1); - if (gSaveOptSelectIndex == SAVE_OPT_SAVE_AND_QUIT) { + if (gSaveOptSelectIndex == MENU_OPT_SAVE_AND_QUIT) { fade_into_special_warp(-2, 0); // reset game } } // not quitting - if (gSaveOptSelectIndex != SAVE_OPT_SAVE_AND_QUIT) { + if (gSaveOptSelectIndex != MENU_OPT_SAVE_AND_QUIT) { disable_time_stop(); m->faceAngle[1] += 0x8000; // figure out what dialog to show, if we should dialogID = get_star_collection_dialog(m); - if (dialogID != 0) { + if (dialogID) { play_peachs_jingle(); // look up for dialog set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, dialogID); @@ -345,24 +343,24 @@ s32 mario_ready_to_speak(void) { // 1 = starting dialog // 2 = speaking s32 set_mario_npc_dialog(s32 actionArg) { - s32 dialogState = 0; + s32 dialogState = MARIO_DIALOG_STATUS_NONE; // in dialog if (gMarioState->action == ACT_READING_NPC_DIALOG) { if (gMarioState->actionState < 8) { - dialogState = 1; // starting dialog + dialogState = MARIO_DIALOG_STATUS_START; // starting dialog } if (gMarioState->actionState == 8) { - if (actionArg == 0) { + if (actionArg == MARIO_DIALOG_STOP) { gMarioState->actionState++; // exit dialog } else { - dialogState = 2; + dialogState = MARIO_DIALOG_STATUS_SPEAK; } } } else if (actionArg != 0 && mario_ready_to_speak()) { gMarioState->usedObj = gCurrentObject; set_mario_action(gMarioState, ACT_READING_NPC_DIALOG, actionArg); - dialogState = 1; // starting dialog + dialogState = MARIO_DIALOG_STATUS_START; // starting dialog } return dialogState; @@ -381,10 +379,10 @@ s32 act_reading_npc_dialog(struct MarioState *m) { s32 headTurnAmount = 0; s16 angleToNPC; - if (m->actionArg == 2) { + if (m->actionArg == MARIO_DIALOG_LOOK_UP) { headTurnAmount = -1024; } - if (m->actionArg == 3) { + if (m->actionArg == MARIO_DIALOG_LOOK_DOWN) { headTurnAmount = 384; } @@ -621,8 +619,8 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { } break; } - } else if (m->actionState == 1 && gDialogResponse) { - if (gDialogResponse == 1) { + } else if (m->actionState == 1 && gDialogResponse != DIALOG_RESPONSE_NONE) { + if (gDialogResponse == DIALOG_RESPONSE_YES) { save_file_do_save(gCurrSaveFileNum - 1); } m->actionState = 2; @@ -630,7 +628,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { disable_time_stop(); enable_background_sound(); dialogID = get_star_collection_dialog(m); - if (dialogID != 0) { + if (dialogID) { // look up for dialog set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, dialogID); } else { @@ -1087,8 +1085,8 @@ s32 act_exit_land_save_dialog(struct MarioState *m) { enable_time_stop(); } - set_menu_mode(RENDER_COURSE_DONE_SCREEN); - gSaveOptSelectIndex = 0; + set_menu_mode(MENU_MODE_RENDER_COURSE_COMPLETE_SCREEN); + gSaveOptSelectIndex = MENU_OPT_NONE; m->actionState = 3; // star exit with cap if (!(m->flags & MARIO_CAP_ON_HEAD)) { @@ -1163,7 +1161,7 @@ s32 act_death_exit(struct MarioState *m) { #else play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject); #endif -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif m->numLives--; @@ -1198,7 +1196,7 @@ s32 act_falling_death_exit(struct MarioState *m) { #else play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject); #endif -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif m->numLives--; @@ -1245,7 +1243,7 @@ s32 act_special_death_exit(struct MarioState *m) { } if (launch_mario_until_land(m, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -24.0f)) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif m->numLives--; @@ -1331,7 +1329,7 @@ s32 act_bbh_enter_spin(struct MarioState *m) { m->flags &= ~MARIO_UNKNOWN_08; if (perform_air_step(m, 0) == AIR_STEP_LANDED) { level_trigger_warp(m, WARP_OP_UNKNOWN_02); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(15, 80); #endif m->actionState = 4; @@ -1399,7 +1397,7 @@ s32 act_teleport_fade_out(struct MarioState *m) { set_mario_animation(m, m->prevAction == ACT_CROUCHING ? MARIO_ANIM_CROUCHING : MARIO_ANIM_FIRST_PERSON); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->actionTimer == 0) { queue_rumble_data(30, 70); func_sh_8024C89C(2); @@ -1425,7 +1423,7 @@ s32 act_teleport_fade_in(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_ACTION_TELEPORT, MARIO_ACTION_SOUND_PLAYED); set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->actionTimer == 0) { queue_rumble_data(30, 70); func_sh_8024C89C(2); @@ -1518,7 +1516,7 @@ s32 act_squished(struct MarioState *m) { // Both of the 1.8's are really floats, but one of them has to // be written as a double for this to match on -O2. vec3f_set(m->marioObj->header.gfx.scale, 1.8, 0.05f, 1.8f); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(10, 80); #endif m->actionState = 1; @@ -1622,7 +1620,7 @@ void stuck_in_ground_handler(struct MarioState *m, s32 animation, s32 unstuckFra if (animFrame == -1) { play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STUCK_IN_GROUND, 1); } else if (animFrame == unstuckFrame) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif play_sound_and_spawn_particles(m, SOUND_ACTION_UNSTUCK_FROM_GROUND, 1); diff --git a/src/game/mario_actions_cutscene.h b/src/game/mario_actions_cutscene.h index 276826cf..31a8b5d3 100644 --- a/src/game/mario_actions_cutscene.h +++ b/src/game/mario_actions_cutscene.h @@ -6,6 +6,17 @@ #include "macros.h" #include "types.h" +// set_mario_npc_dialog +// actionArg +#define MARIO_DIALOG_STOP 0 +#define MARIO_DIALOG_LOOK_FRONT 1 // no head turn +#define MARIO_DIALOG_LOOK_UP 2 +#define MARIO_DIALOG_LOOK_DOWN 3 +// dialogState +#define MARIO_DIALOG_STATUS_NONE 0 +#define MARIO_DIALOG_STATUS_START 1 +#define MARIO_DIALOG_STATUS_SPEAK 2 + void print_displaying_credits_entry(void); void bhv_end_peach_loop(void); void bhv_end_toad_loop(void); diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 8b8e8e1b..be7dd107 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -1238,7 +1238,7 @@ s32 act_riding_shell_ground(struct MarioState *m) { } adjust_sound_for_speed(m); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1344,7 +1344,7 @@ s32 act_burning_ground(struct MarioState *m) { } m->marioBodyState->eyeState = MARIO_EYES_DEAD; -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif return FALSE; @@ -1362,7 +1362,7 @@ void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 vec3f_copy(pos, m->pos); play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif @@ -1488,7 +1488,7 @@ s32 act_crouch_slide(struct MarioState *m) { s32 act_slide_kick_slide(struct MarioState *m) { if (m->input & INPUT_A_PRESSED) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return set_jumping_action(m, ACT_FORWARD_ROLLOUT, 0); @@ -1520,7 +1520,7 @@ s32 act_slide_kick_slide(struct MarioState *m) { s32 stomach_slide_action(struct MarioState *m, u32 stopAction, u32 airAction, s32 animation) { if (m->actionTimer == 5) { if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return drop_and_set_mario_action( @@ -1556,7 +1556,7 @@ s32 act_hold_stomach_slide(struct MarioState *m) { s32 act_dive_slide(struct MarioState *m) { if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif return set_mario_action(m, m->forwardVel > 0.0f ? ACT_FORWARD_ROLLOUT : ACT_BACKWARD_ROLLOUT, @@ -1955,7 +1955,7 @@ s32 check_common_moving_cancels(struct MarioState *m) { return set_water_plunge_action(m); } - if (!(m->action & ACT_FLAG_INVULNERABLE) && (m->input & INPUT_UNKNOWN_10)) { + if (!(m->action & ACT_FLAG_INVULNERABLE) && (m->input & INPUT_STOMPED)) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index fabc3635..82c49c1d 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -145,7 +145,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) { } s32 act_punching(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -173,7 +173,7 @@ s32 act_punching(struct MarioState *m) { } s32 act_picking_up(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -211,7 +211,7 @@ s32 act_picking_up(struct MarioState *m) { } s32 act_dive_picking_up(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -231,7 +231,7 @@ s32 act_dive_picking_up(struct MarioState *m) { } s32 act_placing_down(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -252,7 +252,7 @@ s32 act_throwing(struct MarioState *m) { return set_mario_action(m, ACT_PLACING_DOWN, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -264,7 +264,7 @@ s32 act_throwing(struct MarioState *m) { mario_throw_held_object(m); play_sound_if_no_flag(m, SOUND_MARIO_WAH2, MARIO_MARIO_SOUND_PLAYED); play_sound_if_no_flag(m, SOUND_ACTION_THROW, MARIO_ACTION_SOUND_PLAYED); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(3, 50); #endif } @@ -274,7 +274,7 @@ s32 act_throwing(struct MarioState *m) { } s32 act_heavy_throw(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -286,7 +286,7 @@ s32 act_heavy_throw(struct MarioState *m) { mario_drop_held_object(m); play_sound_if_no_flag(m, SOUND_MARIO_WAH2, MARIO_MARIO_SOUND_PLAYED); play_sound_if_no_flag(m, SOUND_ACTION_THROW, MARIO_ACTION_SOUND_PLAYED); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(3, 50); #endif } @@ -296,7 +296,7 @@ s32 act_heavy_throw(struct MarioState *m) { } s32 act_stomach_slide_stop(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -318,7 +318,7 @@ s32 act_picking_up_bowser(struct MarioState *m) { m->angleVel[1] = 0; m->marioBodyState->grabPos = GRAB_POS_BOWSER; mario_grab_used_object(m); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif play_sound(SOUND_MARIO_HRMM, m->marioObj->header.gfx.cameraToObject); @@ -396,13 +396,13 @@ s32 act_holding_bowser(struct MarioState *m) { // play sound on overflow if (m->angleVel[1] <= -0x100 && spin < m->faceAngle[1]) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(4, 20); #endif play_sound(SOUND_OBJ_BOWSER_SPINNING, m->marioObj->header.gfx.cameraToObject); } if (m->angleVel[1] >= 0x100 && spin > m->faceAngle[1]) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(4, 20); #endif play_sound(SOUND_OBJ_BOWSER_SPINNING, m->marioObj->header.gfx.cameraToObject); @@ -421,12 +421,12 @@ s32 act_holding_bowser(struct MarioState *m) { s32 act_releasing_bowser(struct MarioState *m) { if (++m->actionTimer == 1) { if (m->actionArg == 0) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 50); #endif mario_throw_held_object(m); } else { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(4, 50); #endif mario_drop_held_object(m); diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 580d2544..6475e1f8 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -23,7 +23,7 @@ s32 check_common_idle_cancels(struct MarioState *m) { return mario_push_off_steep_floor(m, ACT_FREEFALL, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -70,7 +70,7 @@ s32 check_common_hold_idle_cancels(struct MarioState *m) { return set_mario_action(m, ACT_PLACING_DOWN, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -257,7 +257,7 @@ s32 act_sleeping(struct MarioState *m) { s32 animFrame; if (m->input & (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE - | INPUT_FIRST_PERSON | INPUT_UNKNOWN_10 | INPUT_B_PRESSED | INPUT_Z_PRESSED)) { + | INPUT_FIRST_PERSON | INPUT_STOMPED | INPUT_B_PRESSED | INPUT_Z_PRESSED)) { return set_mario_action(m, ACT_WAKING_UP, m->actionState); } @@ -333,7 +333,7 @@ s32 act_waking_up(struct MarioState *m) { raise_background_noise(2); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -361,7 +361,7 @@ s32 act_waking_up(struct MarioState *m) { s32 act_shivering(struct MarioState *m) { s32 animFrame; - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -375,7 +375,7 @@ s32 act_shivering(struct MarioState *m) { if (m->input & (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE - | INPUT_FIRST_PERSON | INPUT_UNKNOWN_10 | INPUT_B_PRESSED | INPUT_Z_PRESSED)) { + | INPUT_FIRST_PERSON | INPUT_STOMPED | INPUT_B_PRESSED | INPUT_Z_PRESSED)) { m->actionState = 2; } @@ -459,7 +459,7 @@ s32 act_hold_idle(struct MarioState *m) { } s32 act_hold_heavy_idle(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -485,7 +485,7 @@ s32 act_hold_heavy_idle(struct MarioState *m) { } s32 act_standing_against_wall(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -526,7 +526,7 @@ s32 act_in_quicksand(struct MarioState *m) { } s32 act_crouching(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -564,7 +564,7 @@ s32 act_crouching(struct MarioState *m) { } s32 act_panting(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -591,7 +591,7 @@ s32 act_hold_panting_unused(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_PANTING, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -618,7 +618,7 @@ void stopping_step(struct MarioState *m, s32 animID, u32 action) { } s32 act_braking_stop(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -640,7 +640,7 @@ s32 act_braking_stop(struct MarioState *m) { } s32 act_butt_slide_stop(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -661,7 +661,7 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_IDLE, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -678,7 +678,7 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) { } s32 act_slide_kick_slide_stop(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -691,7 +691,7 @@ s32 act_slide_kick_slide_stop(struct MarioState *m) { } s32 act_start_crouching(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -716,7 +716,7 @@ s32 act_start_crouching(struct MarioState *m) { } s32 act_stop_crouching(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -749,7 +749,7 @@ s32 act_start_crawling(struct MarioState *m) { return set_mario_action(m, ACT_FREEFALL, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -767,7 +767,7 @@ s32 act_start_crawling(struct MarioState *m) { } s32 act_stop_crawling(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -791,18 +791,18 @@ s32 act_shockwave_bounce(struct MarioState *m) { s16 sp1E; f32 sp18; - if (m->marioObj->oInteractStatus & INT_STATUS_HIT_BY_SHOCKWAVE) { -#ifdef VERSION_SH + if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_SHOCKWAVE) { +#if ENABLE_RUMBLE queue_rumble_data(70, 40); #endif return hurt_and_set_mario_action(m, ACT_SHOCKED, 0, 4); } if (m->actionTimer == 0) { -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(70, 40); #endif - if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK1) { + if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_KNOCKBACK_DMG) { return hurt_and_set_mario_action(m, ACT_BACKWARD_GROUND_KB, 0, 0xc); } } @@ -837,7 +837,7 @@ s32 landing_step(struct MarioState *m, s32 arg1, u32 action) { } s32 check_common_landing_cancels(struct MarioState *m, u32 action) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -951,7 +951,7 @@ s32 act_hold_jump_land_stop(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_IDLE, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -972,7 +972,7 @@ s32 act_hold_freefall_land_stop(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_IDLE, 0); } - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -988,7 +988,7 @@ s32 act_hold_freefall_land_stop(struct MarioState *m) { } s32 act_air_throw_land(struct MarioState *m) { - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -1006,7 +1006,7 @@ s32 act_air_throw_land(struct MarioState *m) { s32 act_twirl_land(struct MarioState *m) { m->actionState = 1; - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -1036,7 +1036,7 @@ s32 act_twirl_land(struct MarioState *m) { s32 act_ground_pound_land(struct MarioState *m) { m->actionState = 1; - if (m->input & INPUT_UNKNOWN_10) { + if (m->input & INPUT_STOMPED) { return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); } @@ -1053,7 +1053,7 @@ s32 act_ground_pound_land(struct MarioState *m) { } s32 act_first_person(struct MarioState *m) { - s32 sp1C = (m->input & (INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE | INPUT_UNKNOWN_10)) != 0; + s32 sp1C = (m->input & (INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE | INPUT_STOMPED)) != 0; if (m->actionState == 0) { lower_background_noise(2); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 2db01580..9aef4caa 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -24,9 +24,9 @@ static s16 sWasAtSurface = FALSE; static s16 sSwimStrength = MIN_SWIM_STRENGTH; static s16 sWaterCurrentSpeeds[] = { 28, 12, 8, 4 }; -static s16 D_80339FD0; -static s16 D_80339FD2; -static f32 D_80339FD4; +static s16 sBobTimer; +static s16 sBobIncrement; +static f32 sBobHeight; static void set_swimming_at_surface_particles(struct MarioState *m, u32 particleFlag) { s16 atSurface = m->pos[1] >= m->waterLevel - 130; @@ -416,21 +416,24 @@ static s32 act_hold_water_action_end(struct MarioState *m) { return FALSE; } -static void reset_float_globals(struct MarioState *m) { - D_80339FD0 = 0; - D_80339FD2 = 0x800; - D_80339FD4 = m->faceAngle[0] / 256.0f + 20.0f; +static void reset_bob_variables(struct MarioState *m) { + sBobTimer = 0; + sBobIncrement = 0x800; + sBobHeight = m->faceAngle[0] / 256.0f + 20.0f; } -static void float_surface_gfx(struct MarioState *m) { - if (D_80339FD2 != 0 && m->pos[1] > m->waterLevel - 85 && m->faceAngle[0] >= 0) { - if ((D_80339FD0 += D_80339FD2) >= 0) { - m->marioObj->header.gfx.pos[1] += D_80339FD4 * sins(D_80339FD0); +/** + * Controls the bobbing that happens when you swim near the surface. + */ +static void surface_swim_bob(struct MarioState *m) { + if (sBobIncrement != 0 && m->pos[1] > m->waterLevel - 85 && m->faceAngle[0] >= 0) { + if ((sBobTimer += sBobIncrement) >= 0) { + m->marioObj->header.gfx.pos[1] += sBobHeight * sins(sBobTimer); return; } } - D_80339FD2 = 0; + sBobIncrement = 0; } static void common_swimming_step(struct MarioState *m, s16 swimStrength) { @@ -475,7 +478,7 @@ static void common_swimming_step(struct MarioState *m, s16 swimStrength) { update_water_pitch(m); m->marioBodyState->headAngle[0] = approach_s32(m->marioBodyState->headAngle[0], 0, 0x200, 0x200); - float_surface_gfx(m); + surface_swim_bob(m); set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL); } @@ -551,10 +554,10 @@ static s32 act_breaststroke(struct MarioState *m) { if (m->actionTimer == 1) { play_sound(sSwimStrength == MIN_SWIM_STRENGTH ? SOUND_ACTION_SWIM : SOUND_ACTION_SWIM_FAST, m->marioObj->header.gfx.cameraToObject); - reset_float_globals(m); + reset_bob_variables(m); } -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->actionTimer < 6) { func_sh_8024CA04(); } @@ -675,7 +678,7 @@ static s32 act_hold_breaststroke(struct MarioState *m) { if (m->actionTimer == 1) { play_sound(SOUND_ACTION_SWIM, m->marioObj->header.gfx.cameraToObject); - reset_float_globals(m); + reset_bob_variables(m); } set_mario_animation(m, MARIO_ANIM_SWIM_WITH_OBJ_PART1); @@ -802,7 +805,7 @@ static s32 act_water_throw(struct MarioState *m) { if (m->actionTimer++ == 5) { mario_throw_held_object(m); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(3, 50); #endif } @@ -978,7 +981,7 @@ static s32 act_water_plunge(struct MarioState *m) { m->particleFlags |= PARTICLE_WATER_SPLASH; m->actionState = 1; -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (m->prevAction & ACT_FLAG_AIR) { queue_rumble_data(5, 80); } @@ -1006,7 +1009,7 @@ static s32 act_water_plunge(struct MarioState *m) { set_mario_action(m, ACT_HOLD_METAL_WATER_FALLING, 0); break; } - D_80339FD2 = 0; + sBobIncrement = 0; } switch (stateFlags) { @@ -1087,7 +1090,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_GENERAL_FALL); vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); -#ifdef VERSION_SH +#if ENABLE_RUMBLE reset_rumble_timers(); #endif diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 5184a807..56e1a0a1 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -15,6 +15,7 @@ #include "goddard/renderer.h" #include "interaction.h" #include "level_update.h" +#include "mario_actions_cutscene.h" #include "mario_misc.h" #include "memory.h" #include "object_helpers.h" @@ -122,8 +123,8 @@ static void toad_message_opaque(void) { } static void toad_message_talking(void) { - if (cur_obj_update_dialog_with_cutscene(3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId) - != 0) { + if (cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_DOWN, + DIALOG_FLAG_TURN_TO_MARIO, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId)) { gCurrentObject->oToadMessageRecentlyTalked = TRUE; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; switch (gCurrentObject->oToadMessageDialogId) { diff --git a/src/game/memory.c b/src/game/memory.c index 5f3b329d..dcc9223d 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -252,7 +252,7 @@ static void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd) { osPiStartDma(&gDmaIoMesg, OS_MESG_PRI_NORMAL, OS_READ, (uintptr_t) srcStart, dest, copySize, &gDmaMesgQueue); - osRecvMesg(&gDmaMesgQueue, &D_80339BEC, OS_MESG_BLOCK); + osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); dest += copySize; srcStart += copySize; @@ -532,41 +532,37 @@ void *alloc_display_list(u32 size) { return ptr; } -static struct MarioAnimDmaRelatedThing *func_802789F0(u8 *srcAddr) { - struct MarioAnimDmaRelatedThing *sp1C = dynamic_dma_read(srcAddr, srcAddr + sizeof(u32), +static struct DmaTable *load_dma_table_address(u8 *srcAddr) { + struct DmaTable *table = dynamic_dma_read(srcAddr, srcAddr + sizeof(u32), MEMORY_POOL_LEFT); - u32 size = sizeof(u32) + (sizeof(u8 *) - sizeof(u32)) + sizeof(u8 *) + - sp1C->count * sizeof(struct OffsetSizePair); - main_pool_free(sp1C); + u32 size = table->count * sizeof(struct OffsetSizePair) + + sizeof(struct DmaTable) - sizeof(struct OffsetSizePair); + main_pool_free(table); - sp1C = dynamic_dma_read(srcAddr, srcAddr + size, MEMORY_POOL_LEFT); - sp1C->srcAddr = srcAddr; - return sp1C; + table = dynamic_dma_read(srcAddr, srcAddr + size, MEMORY_POOL_LEFT); + table->srcAddr = srcAddr; + return table; } -void func_80278A78(struct MarioAnimation *a, void *b, struct Animation *target) { - if (b != NULL) { - a->animDmaTable = func_802789F0(b); +void setup_dma_table_list(struct DmaHandlerList *list, void *srcAddr, void *buffer) { + if (srcAddr != NULL) { + list->dmaTable = load_dma_table_address(srcAddr); } - a->currentAnimAddr = NULL; - a->targetAnim = target; + list->currentAddr = NULL; + list->bufTarget = buffer; } -// TODO: (Scrub C) -s32 load_patchable_table(struct MarioAnimation *a, u32 index) { +s32 load_patchable_table(struct DmaHandlerList *list, s32 index) { s32 ret = FALSE; - struct MarioAnimDmaRelatedThing *sp20 = a->animDmaTable; - u8 *addr; - u32 size; + struct DmaTable *table = list->dmaTable; - if (index < sp20->count) { - 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; + if ((u32)index < table->count) { + u8 *addr = table->srcAddr + table->anim[index].offset; + s32 size = table->anim[index].size; + + if (list->currentAddr != addr) { + dma_read(list->bufTarget, addr, addr + size); + list->currentAddr = addr; ret = TRUE; } } diff --git a/src/game/memory.h b/src/game/memory.h index 7a51e590..1c2da465 100644 --- a/src/game/memory.h +++ b/src/game/memory.h @@ -8,7 +8,6 @@ #define MEMORY_POOL_LEFT 0 #define MEMORY_POOL_RIGHT 1 - struct AllocOnlyPool { s32 totalSpace; @@ -19,6 +18,26 @@ struct AllocOnlyPool struct MemoryPool; +struct OffsetSizePair +{ + u32 offset; + u32 size; +}; + +struct DmaTable +{ + u32 count; + u8 *srcAddr; + struct OffsetSizePair anim[1]; // dynamic size +}; + +struct DmaHandlerList +{ + struct DmaTable *dmaTable; + void *currentAddr; + void *bufTarget; +}; + #ifndef INCLUDED_FROM_MEMORY_C // Declaring this variable extern puts it in the wrong place in the bss order // when this file is included from memory.c (first instead of last). Hence, @@ -63,7 +82,7 @@ void *mem_pool_alloc(struct MemoryPool *pool, u32 size); void mem_pool_free(struct MemoryPool *pool, void *addr); void *alloc_display_list(u32 size); -void func_80278A78(struct MarioAnimation *a, void *b, struct Animation *target); -s32 load_patchable_table(struct MarioAnimation *a, u32 b); +void setup_dma_table_list(struct DmaHandlerList *list, void *srcAddr, void *buffer); +s32 load_patchable_table(struct DmaHandlerList *list, s32 index); #endif // MEMORY_H diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 64bb141e..fdfc70fa 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -685,14 +685,14 @@ s16 trigger_obj_dialog_when_facing(s32 *inDialog, s16 dialogID, f32 dist, s32 ac if ((is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, (s32) dist) == TRUE && obj_check_if_facing_toward_angle(o->oFaceAngleYaw, gMarioObject->header.gfx.angle[1] + 0x8000, 0x1000) == TRUE && obj_check_if_facing_toward_angle(o->oMoveAngleYaw, o->oAngleToMario, 0x1000) == TRUE) - || (*inDialog == 1)) { - *inDialog = 1; + || (*inDialog == TRUE)) { + *inDialog = TRUE; - if (set_mario_npc_dialog(actionArg) == 2) { //If Mario is speaking. + if (set_mario_npc_dialog(actionArg) == MARIO_DIALOG_STATUS_SPEAK) { //If Mario is speaking. dialogueResponse = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID); - if (dialogueResponse != 0) { - set_mario_npc_dialog(0); - *inDialog = 0; + if (dialogueResponse) { + set_mario_npc_dialog(MARIO_DIALOG_STOP); + *inDialog = FALSE; return dialogueResponse; } return 0; diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c index 056d178a..ae01edce 100644 --- a/src/game/obj_behaviors_2.c +++ b/src/game/obj_behaviors_2.c @@ -15,6 +15,7 @@ #include "engine/surface_load.h" #include "game_init.h" #include "geo_misc.h" +#include "ingame_menu.h" #include "interaction.h" #include "level_table.h" #include "level_update.h" @@ -98,10 +99,11 @@ static s16 obj_get_pitch_from_vel(void) { */ static s32 obj_update_race_proposition_dialog(s16 dialogID) { s32 dialogResponse = - cur_obj_update_dialog_with_cutscene(2, DIALOG_UNK2_FLAG_0 | DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED, CUTSCENE_RACE_DIALOG, dialogID); + cur_obj_update_dialog_with_cutscene(MARIO_DIALOG_LOOK_UP, + (DIALOG_FLAG_TURN_TO_MARIO | DIALOG_FLAG_TIME_STOP_ENABLED), CUTSCENE_RACE_DIALOG, dialogID); - if (dialogResponse == 2) { - set_mario_npc_dialog(0); + if (dialogResponse == DIALOG_RESPONSE_NO) { + set_mario_npc_dialog(MARIO_DIALOG_STOP); disable_time_stop_including_mario(); } @@ -640,7 +642,7 @@ static void obj_die_if_health_non_positive(void) { } } -static void obj_unused_die(void) { +UNUSED static void obj_unused_die(void) { o->oHealth = 0; obj_die_if_health_non_positive(); } diff --git a/src/game/object_collision.c b/src/game/object_collision.c index c8d867ae..cf77768a 100644 --- a/src/game/object_collision.c +++ b/src/game/object_collision.c @@ -57,6 +57,9 @@ s32 detect_object_hitbox_overlap(struct Object *a, struct Object *b) { } //! no return value +#ifdef AVOID_UB + return 0; +#endif } s32 detect_object_hurtbox_overlap(struct Object *a, struct Object *b) { @@ -89,6 +92,9 @@ s32 detect_object_hurtbox_overlap(struct Object *a, struct Object *b) { } //! no return value +#ifdef AVOID_UB + return 0; +#endif } void clear_object_collision(struct Object *a) { diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 0d86000b..0f0c707b 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -27,8 +27,8 @@ #include "spawn_object.h" #include "spawn_sound.h" -s8 D_8032F0A0[] = { -8, 8, -4, 4 }; -s16 D_8032F0A4[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +static s8 sBbhStairJiggleOffsets[] = { -8, 8, -4, 4 }; +static s16 sPowersOfTwo[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; static s8 sLevelsWithRooms[] = { LEVEL_BBH, LEVEL_CASTLE, LEVEL_HMC, -1 }; static s32 clear_move_flag(u32 *, s32); @@ -790,7 +790,7 @@ void cur_obj_unused_init_on_floor(void) { cur_obj_enable_rendering(); o->oPosY = find_floor_height(o->oPosX, o->oPosY, o->oPosZ); - if (o->oPosY < -10000.0f) { + if (o->oPosY < FLOOR_LOWER_LIMIT_MISC) { cur_obj_set_pos_relative_to_parent(0, 0, -70); o->oPosY = find_floor_height(o->oPosX, o->oPosY, o->oPosZ); } @@ -1048,20 +1048,21 @@ s32 mario_is_dive_sliding(void) { } } -void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C) { - o->oVelY = sp18; - cur_obj_init_animation_with_sound(sp1C); +void cur_obj_set_y_vel_and_animation(f32 yVel, s32 animIndex) { + o->oVelY = yVel; + cur_obj_init_animation_with_sound(animIndex); } -void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C) { +void cur_obj_unrender_set_action_and_anim(s32 animIndex, s32 action) { cur_obj_become_intangible(); cur_obj_disable_rendering(); - - if (sp18 >= 0) { - cur_obj_init_animation_with_sound(sp18); + + // only set animation if non-negative value + if (animIndex >= 0) { + cur_obj_init_animation_with_sound(animIndex); } - o->oAction = sp1C; + o->oAction = action; } static void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY) { @@ -1070,7 +1071,7 @@ static void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY) { if (o->oFloorHeight > o->oPosY) { o->oPosY = o->oFloorHeight; - } else if (o->oFloorHeight < -10000.0f) { + } else if (o->oFloorHeight < FLOOR_LOWER_LIMIT_MISC) { //! OoB failsafe obj_copy_pos(o, gMarioObject); o->oFloorHeight = find_floor_height(o->oPosX, o->oPosY, o->oPosZ); @@ -1218,7 +1219,7 @@ static s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlop } } - if (intendedFloorHeight < -10000.0f) { + if (intendedFloorHeight < FLOOR_LOWER_LIMIT_MISC) { // Don't move into OoB o->oMoveFlags |= OBJ_MOVE_HIT_EDGE; return FALSE; @@ -1318,7 +1319,7 @@ static f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy) { o->oPosY += o->oVelY; if (o->activeFlags & ACTIVE_FLAG_UNK10) { - waterLevel = -11000.0f; + waterLevel = FLOOR_LOWER_LIMIT; } else { waterLevel = find_water_level(o->oPosX, o->oPosZ); } @@ -1376,7 +1377,7 @@ void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy) { } } -static void stub_obj_helpers_1(void) { +UNUSED static void stub_obj_helpers_1(void) { } static s32 clear_move_flag(u32 *bitSet, s32 flag) { @@ -1566,9 +1567,10 @@ void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent) { gSecondCameraFocus = o; } -void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8) { - if (o->oDistanceToMario < sp8) { - gMarioObject->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; +// unused, self explanatory, maybe oInteractStatus originally had TRUE/FALSE statements +void set_mario_interact_true_if_in_range(UNUSED s32 arg0, UNUSED s32 arg1, f32 range) { + if (o->oDistanceToMario < range) { + gMarioObject->oInteractStatus = TRUE; } } @@ -1675,7 +1677,7 @@ static s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees) { intendedFloorHeight = find_floor(intendedX, o->oPosY, intendedZ, &intendedFloor); deltaFloorHeight = intendedFloorHeight - o->oFloorHeight; - if (intendedFloorHeight < -10000.0f) { + if (intendedFloorHeight < FLOOR_LOWER_LIMIT_MISC) { o->oWallAngle = o->oMoveAngleYaw + 0x8000; return 2; } else if (intendedFloor->normal.y < steepNormalY && deltaFloorHeight > 0 @@ -2057,14 +2059,15 @@ void obj_translate_xz_random(struct Object *obj, f32 rangeLength) { obj->oPosZ += random_float() * rangeLength - rangeLength * 0.5f; } -static void obj_build_vel_from_transform(struct Object *a0) { - f32 spC = a0->oUnkC0; - f32 sp8 = a0->oUnkBC; - f32 sp4 = a0->oForwardVel; +static void obj_build_vel_from_transform(struct Object *obj) { + f32 up = obj->oUpVel; + f32 left = obj->oLeftVel; + f32 forward = obj->oForwardVel; - a0->oVelX = a0->transform[0][0] * spC + a0->transform[1][0] * sp8 + a0->transform[2][0] * sp4; - a0->oVelY = a0->transform[0][1] * spC + a0->transform[1][1] * sp8 + a0->transform[2][1] * sp4; - a0->oVelZ = a0->transform[0][2] * spC + a0->transform[1][2] * sp8 + a0->transform[2][2] * sp4; + //! Typo, up and left should be swapped + obj->oVelX = obj->transform[0][0] * up + obj->transform[1][0] * left + obj->transform[2][0] * forward; + obj->oVelY = obj->transform[0][1] * up + obj->transform[1][1] * left + obj->transform[2][1] * forward; + obj->oVelZ = obj->transform[0][2] * up + obj->transform[1][2] * left + obj->transform[2][2] * forward; } void cur_obj_set_pos_via_transform(void) { @@ -2087,13 +2090,13 @@ void cur_obj_spawn_particles(struct SpawnParticlesInfo *info) { s32 numParticles = info->count; // If there are a lot of objects already, limit the number of particles - if (gPrevFrameObjectCount > 150 && numParticles > 10) { + if ((gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY - 90)) && numParticles > 10) { numParticles = 10; } // We're close to running out of object slots, so don't spawn particles at // all - if (gPrevFrameObjectCount > 210) { + if (gPrevFrameObjectCount > (OBJECT_POOL_CAPACITY - 30)) { numParticles = 0; } @@ -2232,7 +2235,7 @@ void bhv_dust_smoke_loop(void) { o->oSmokeTimer++; } -static void stub_obj_helpers_2(void) { +UNUSED static void stub_obj_helpers_2(void) { } s32 cur_obj_set_direction_table(s8 *a0) { @@ -2310,12 +2313,12 @@ s32 cur_obj_shake_y_until(s32 cycles, s32 amount) { } } -s32 cur_obj_move_up_and_down(s32 a0) { +s32 jiggle_bbh_stair(s32 a0) { if (a0 >= 4 || a0 < 0) { return TRUE; } - o->oPosY += D_8032F0A0[a0]; + o->oPosY += sBbhStairJiggleOffsets[a0]; return FALSE; } @@ -2340,7 +2343,7 @@ void spawn_base_star_with_no_lvl_exit(void) { } s32 bit_shift_left(s32 a0) { - return D_8032F0A4[a0]; + return sPowersOfTwo[a0]; } s32 cur_obj_mario_far_away(void) { @@ -2380,7 +2383,7 @@ s32 is_item_in_array(s8 item, s8 *array) { return FALSE; } -static void stub_obj_helpers_5(void) { +UNUSED static void stub_obj_helpers_5(void) { } void bhv_init_room(void) { @@ -2461,7 +2464,7 @@ s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deat void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C) { spawn_mist_particles_variable(0, 0, sp18); - spawn_triangle_break_particles(30, 138, 3.0f, 4); + spawn_triangle_break_particles(30, MODEL_DIRT_ANIMATION, 3.0f, 4); obj_mark_for_deletion(o); if (sp1C == 1) { @@ -2562,29 +2565,18 @@ static void cur_obj_end_dialog(s32 dialogFlags, s32 dialogResult) { o->oDialogResponse = dialogResult; o->oDialogState++; - if (!(dialogFlags & DIALOG_UNK1_FLAG_4)) { - set_mario_npc_dialog(0); + if (!(dialogFlags & DIALOG_FLAG_TIME_STOP_ENABLED)) { + set_mario_npc_dialog(MARIO_DIALOG_STOP); } } s32 cur_obj_update_dialog(s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s32 unused) { - s32 dialogResponse = 0; + s32 dialogResponse = DIALOG_RESPONSE_NONE; UNUSED s32 doneTurning = TRUE; switch (o->oDialogState) { -#ifdef VERSION_JP - case DIALOG_UNK1_ENABLE_TIME_STOP: - //! We enable time stop even if Mario is not ready to speak. This - // allows us to move during time stop as long as Mario never enters - // an action that can be interrupted with text. - if (gMarioState->health >= 0x100) { - gTimeStopState |= TIME_STOP_ENABLED; - o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; - o->oDialogState++; - } - break; -#else - case DIALOG_UNK1_ENABLE_TIME_STOP: +#if BUGFIX_DIALOG_TIME_STOP + case DIALOG_STATUS_ENABLE_TIME_STOP: // Patched :( // Wait for Mario to be ready to speak, and then enable time stop if (mario_ready_to_speak() || gMarioState->action == ACT_READING_NPC_DIALOG) { @@ -2596,48 +2588,67 @@ s32 cur_obj_update_dialog(s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s } // Fall through so that Mario's action is interrupted immediately // after time is stopped +#else + case DIALOG_STATUS_ENABLE_TIME_STOP: + //! We enable time stop even if Mario is not ready to speak. This + // allows us to move during time stop as long as Mario never enters + // an action that can be interrupted with text. + if (gMarioState->health >= 0x100) { + gTimeStopState |= TIME_STOP_ENABLED; + o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; + o->oDialogState++; + } + break; #endif - - case DIALOG_UNK1_INTERRUPT_MARIO_ACTION: - if (set_mario_npc_dialog(actionArg) == 2) { + case DIALOG_STATUS_INTERRUPT: + // Interrupt until Mario is actually speaking with the NPC + if (set_mario_npc_dialog(actionArg) == MARIO_DIALOG_STATUS_SPEAK) { o->oDialogState++; } break; - case DIALOG_UNK1_BEGIN_DIALOG: - if (dialogFlags & DIALOG_UNK1_FLAG_RESPONSE) { + case DIALOG_STATUS_START_DIALOG: + // Starts dialog, depending of the flag defined, it calls + // a default dialog or a dialog with response. + if (dialogFlags & DIALOG_FLAG_TEXT_RESPONSE) { create_dialog_box_with_response(dialogID); - } else if (dialogFlags & DIALOG_UNK1_FLAG_DEFAULT) { + } else if (dialogFlags & DIALOG_FLAG_TEXT_DEFAULT) { create_dialog_box(dialogID); } o->oDialogState++; break; - case DIALOG_UNK1_AWAIT_DIALOG: - if (dialogFlags & DIALOG_UNK1_FLAG_RESPONSE) { - if (gDialogResponse != 0) { + case DIALOG_STATUS_STOP_DIALOG: + // Stops dialog, if the flag dialog response was called + // then it defines the value to let the object do the rest. + if (dialogFlags & DIALOG_FLAG_TEXT_RESPONSE) { + if (gDialogResponse != DIALOG_RESPONSE_NONE) { cur_obj_end_dialog(dialogFlags, gDialogResponse); } - } else if (dialogFlags & DIALOG_UNK1_FLAG_DEFAULT) { - if (get_dialog_id() == -1) { - cur_obj_end_dialog(dialogFlags, 3); + } else if (dialogFlags & DIALOG_FLAG_TEXT_DEFAULT) { + if (get_dialog_id() == DIALOG_NONE) { + cur_obj_end_dialog(dialogFlags, DIALOG_RESPONSE_NOT_DEFINED); } } else { - cur_obj_end_dialog(dialogFlags, 3); + cur_obj_end_dialog(dialogFlags, DIALOG_RESPONSE_NOT_DEFINED); } break; - case DIALOG_UNK1_DISABLE_TIME_STOP: - if (gMarioState->action != ACT_READING_NPC_DIALOG || (dialogFlags & DIALOG_UNK1_FLAG_4)) { + case DIALOG_STATUS_DISABLE_TIME_STOP: + // We disable time stop for a few seconds when Mario is no longer + // speaking or the flag is defined, then we enable it again. + // Usually, an object disables time stop using a separate function + // after a certain condition is met. + if (gMarioState->action != ACT_READING_NPC_DIALOG || (dialogFlags & DIALOG_FLAG_TIME_STOP_ENABLED)) { gTimeStopState &= ~TIME_STOP_ENABLED; o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; dialogResponse = o->oDialogResponse; - o->oDialogState = DIALOG_UNK1_ENABLE_TIME_STOP; + o->oDialogState = DIALOG_STATUS_ENABLE_TIME_STOP; } break; default: - o->oDialogState = DIALOG_UNK1_ENABLE_TIME_STOP; + o->oDialogState = DIALOG_STATUS_ENABLE_TIME_STOP; break; } @@ -2645,12 +2656,25 @@ s32 cur_obj_update_dialog(s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s } s32 cur_obj_update_dialog_with_cutscene(s32 actionArg, s32 dialogFlags, s32 cutsceneTable, s32 dialogID) { - s32 dialogResponse = 0; + s32 dialogResponse = DIALOG_RESPONSE_NONE; s32 doneTurning = TRUE; switch (o->oDialogState) { -#ifdef VERSION_JP - case DIALOG_UNK2_ENABLE_TIME_STOP: +#if BUGFIX_DIALOG_TIME_STOP + case DIALOG_STATUS_ENABLE_TIME_STOP: + // Wait for Mario to be ready to speak, and then enable time stop + if (mario_ready_to_speak() || gMarioState->action == ACT_READING_NPC_DIALOG) { + gTimeStopState |= TIME_STOP_ENABLED; + o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; + o->oDialogState++; + o->oDialogResponse = DIALOG_RESPONSE_NONE; + } else { + break; + } + // Fall through so that Mario's action is interrupted immediately + // after time is stopped +#else + case DIALOG_STATUS_ENABLE_TIME_STOP: //! We enable time stop even if Mario is not ready to speak. This // allows us to move during time stop as long as Mario never enters // an action that can be interrupted with text. @@ -2658,63 +2682,61 @@ s32 cur_obj_update_dialog_with_cutscene(s32 actionArg, s32 dialogFlags, s32 cuts gTimeStopState |= TIME_STOP_ENABLED; o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; o->oDialogState++; - o->oDialogResponse = 0; + o->oDialogResponse = DIALOG_RESPONSE_NONE; } break; -#else - case DIALOG_UNK2_ENABLE_TIME_STOP: - // Wait for Mario to be ready to speak, and then enable time stop - if (mario_ready_to_speak() || gMarioState->action == ACT_READING_NPC_DIALOG) { - gTimeStopState |= TIME_STOP_ENABLED; - o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; - o->oDialogState++; - o->oDialogResponse = 0; - } else { - break; - } - // Fall through so that Mario's action is interrupted immediately - // after time is stopped #endif - - case DIALOG_UNK2_TURN_AND_INTERRUPT_MARIO_ACTION: - if (dialogFlags & DIALOG_UNK2_FLAG_0) { + case DIALOG_STATUS_INTERRUPT: + // Additional flag that makes the NPC rotate towards to Mario + if (dialogFlags & DIALOG_FLAG_TURN_TO_MARIO) { doneTurning = cur_obj_rotate_yaw_toward(obj_angle_to_object(o, gMarioObject), 0x800); + // Failsafe just in case it takes more than 33 frames somehow if (o->oDialogResponse >= 33) { doneTurning = TRUE; } } - - if (set_mario_npc_dialog(actionArg) == 2 && doneTurning) { + // Interrupt status until Mario is actually speaking with the NPC and if the + // object is done turning to Mario + if (set_mario_npc_dialog(actionArg) == MARIO_DIALOG_STATUS_SPEAK && doneTurning) { o->oDialogResponse = 0; o->oDialogState++; } else { - o->oDialogResponse++; + o->oDialogResponse++; // treated as a timer for the failsafe } break; - case DIALOG_UNK2_AWAIT_DIALOG: + case DIALOG_STATUS_START_DIALOG: + // Special check for Cap Switch cutscene since the cutscene itself + // handles what dialog should use if (cutsceneTable == CUTSCENE_CAP_SWITCH_PRESS) { - if ((o->oDialogResponse = cutscene_object_without_dialog(cutsceneTable, o)) != 0) { + if ((o->oDialogResponse = cutscene_object_without_dialog(cutsceneTable, o))) { o->oDialogState++; } } else { - if ((o->oDialogResponse = cutscene_object_with_dialog(cutsceneTable, o, dialogID)) != 0) { + // General dialog cutscene function, most of the time + // the "CUTSCENE_DIALOG" cutscene is called + if ((o->oDialogResponse = cutscene_object_with_dialog(cutsceneTable, o, dialogID))) { o->oDialogState++; } } break; - case DIALOG_UNK2_END_DIALOG: - if (dialogFlags & DIALOG_UNK2_LEAVE_TIME_STOP_ENABLED) { + case DIALOG_STATUS_STOP_DIALOG: + // If flag defined, keep time stop enabled until the object + // decided to disable it independently + if (dialogFlags & DIALOG_FLAG_TIME_STOP_ENABLED) { dialogResponse = o->oDialogResponse; - o->oDialogState = DIALOG_UNK2_ENABLE_TIME_STOP; + o->oDialogState = DIALOG_STATUS_ENABLE_TIME_STOP; } else if (gMarioState->action != ACT_READING_NPC_DIALOG) { + // Disable time stop, then enable time stop for a frame + // until the set_mario_npc_dialog function disables it gTimeStopState &= ~TIME_STOP_ENABLED; o->activeFlags &= ~ACTIVE_FLAG_INITIATED_TIME_STOP; dialogResponse = o->oDialogResponse; - o->oDialogState = DIALOG_UNK2_ENABLE_TIME_STOP; + o->oDialogState = DIALOG_STATUS_ENABLE_TIME_STOP; } else { - set_mario_npc_dialog(0); + // And finally stop Mario dialog status + set_mario_npc_dialog(MARIO_DIALOG_STOP); } break; } diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 895604fc..6ae66dc1 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -154,7 +154,7 @@ s32 cur_obj_check_frame_prior_current_frame(s16 *a0); s32 mario_is_in_air_action(void); s32 mario_is_dive_sliding(void); void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C); -void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C); +void cur_obj_unrender_set_action_and_anim(s32 sp18, s32 sp1C); void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction); void cur_obj_get_dropped(void); void cur_obj_set_model(s32 modelID); @@ -186,7 +186,7 @@ void cur_obj_set_pos_to_home(void); void cur_obj_set_pos_to_home_and_stop(void); void cur_obj_shake_y(f32 amount); void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent); -void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8); +void set_mario_interact_true_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8); void obj_set_billboard(struct Object *obj); void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height); void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height); @@ -252,7 +252,7 @@ void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4); void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14); void cur_obj_set_pos_to_home_with_debug(void); s32 cur_obj_is_mario_on_platform(void); -s32 cur_obj_move_up_and_down(s32 a0); +s32 jiggle_bbh_stair(s32 a0); void cur_obj_call_action_function(void (*actionFunctions[])(void)); void spawn_base_star_with_no_lvl_exit(void); s32 bit_shift_left(s32 a0); diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index d01f5eb4..3e970c02 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -602,7 +602,7 @@ void unload_deactivated_objects(void) { /** * Unused profiling function. */ -static u16 unused_get_elapsed_time(u64 *cycleCounts, s32 index) { +UNUSED static u16 unused_get_elapsed_time(u64 *cycleCounts, s32 index) { u16 time; f64 cycles; diff --git a/src/game/paintings.c b/src/game/paintings.c index 83bd2ce9..d98ea9aa 100644 --- a/src/game/paintings.c +++ b/src/game/paintings.c @@ -254,6 +254,9 @@ f32 painting_ripple_y(struct Painting *painting, s8 ySource) { return painting->size / 2.0; // some concentric ripples don't care about Mario break; } +#ifdef AVOID_UB + return 0.0f; +#endif } /** @@ -279,6 +282,9 @@ f32 painting_nearest_4th(struct Painting *painting) { } else if (painting->floorEntered & ENTER_RIGHT) { return thirdQuarter; } +#ifdef AVOID_UB + return 0.0f; +#endif } /** @@ -310,6 +316,9 @@ f32 painting_ripple_x(struct Painting *painting, s8 xSource) { return painting->size / 2.0; break; } +#ifdef AVOID_UB + return 0.0f; +#endif } /** diff --git a/src/game/rumble_init.c b/src/game/rumble_init.c index a708a5c1..6c89f86f 100644 --- a/src/game/rumble_init.c +++ b/src/game/rumble_init.c @@ -4,8 +4,9 @@ #include "buffers/buffers.h" #include "main.h" #include "rumble_init.h" +#include "config.h" -#ifdef VERSION_SH +#if ENABLE_RUMBLE OSThread gRumblePakThread; @@ -21,8 +22,8 @@ OSMesgQueue gRumbleThreadVIMesgQueue; struct RumbleData gRumbleDataQueue[3]; struct StructSH8031D9B0 gCurrRumbleSettings; -s32 sRumblePakThreadActive = 0; -s32 sRumblePakActive = 0; +s32 sRumblePakThreadActive = FALSE; +s32 sRumblePakActive = FALSE; s32 sRumblePakErrorCount = 0; s32 gRumblePakTimer = 0; @@ -290,7 +291,7 @@ void create_thread_6(void) { } void rumble_thread_update_vi(void) { - if (sRumblePakThreadActive == FALSE) { + if (!sRumblePakThreadActive) { return; } diff --git a/src/game/rumble_init.h b/src/game/rumble_init.h index 67aca829..cc47d75b 100644 --- a/src/game/rumble_init.h +++ b/src/game/rumble_init.h @@ -1,7 +1,11 @@ #ifndef RUMBLE_INIT_H #define RUMBLE_INIT_H -#ifdef VERSION_SH +#include + +#include "config.h" + +#if ENABLE_RUMBLE extern s32 gRumblePakTimer; @@ -18,6 +22,6 @@ void cancel_rumble(void); void create_thread_6(void); void rumble_thread_update_vi(void); -#endif // VERSION_SH +#endif // ENABLE_RUMBLE #endif // RUMBLE_INIT_H diff --git a/src/game/save_file.c b/src/game/save_file.c index 9cc97a5f..02e5bdc8 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -64,12 +64,12 @@ static s32 read_eeprom_data(void *buffer, s32 size) { u32 offset = (u32)((u8 *) buffer - (u8 *) &gSaveBuffer) / 8; do { -#ifdef VERSION_SH +#if ENABLE_RUMBLE block_until_rumble_pak_free(); #endif triesLeft--; status = osEepromLongRead(&gSIEventMesgQueue, offset, buffer, size); -#ifdef VERSION_SH +#if ENABLE_RUMBLE release_rumble_pak_control(); #endif } while (triesLeft > 0 && status != 0); @@ -92,12 +92,12 @@ static s32 write_eeprom_data(void *buffer, s32 size) { u32 offset = (u32)((u8 *) buffer - (u8 *) &gSaveBuffer) >> 3; do { -#ifdef VERSION_SH +#if ENABLE_RUMBLE block_until_rumble_pak_free(); #endif triesLeft--; status = osEepromLongWrite(&gSIEventMesgQueue, offset, buffer, size); -#ifdef VERSION_SH +#if ENABLE_RUMBLE release_rumble_pak_control(); #endif } while (triesLeft > 0 && status != 0); diff --git a/src/game/screen_transition.c b/src/game/screen_transition.c index 190a436d..b9fa99b5 100644 --- a/src/game/screen_transition.c +++ b/src/game/screen_transition.c @@ -239,6 +239,9 @@ s32 render_screen_transition(s8 fadeTimer, s8 transType, u8 transTime, struct Wa return render_textured_transition(fadeTimer, transTime, transData, TEX_TRANS_BOWSER, TRANS_TYPE_MIRROR); break; } +#ifdef AVOID_UB + return 0; +#endif } Gfx *render_cannon_circle_base(void) { diff --git a/src/game/shadow.c b/src/game/shadow.c index e8605075..69145cff 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -187,6 +187,9 @@ f32 get_water_level_below_shadow(struct Shadow *s) { } //! @bug Missing return statement. This compiles to return `waterLevel` //! incidentally. +#ifdef AVOID_UB + return waterLevel; +#endif } /** diff --git a/src/game/sound_init.c b/src/game/sound_init.c index 49122920..c4bad21c 100644 --- a/src/game/sound_init.c +++ b/src/game/sound_init.c @@ -23,13 +23,15 @@ static OSMesgQueue sSoundMesgQueue; static OSMesg sSoundMesgBuf[1]; static struct VblankHandler sSoundVblankHandler; -static u8 D_8032C6C0 = 0; -static u8 D_8032C6C4 = 0; +// Only written to, never read. +static u8 sMusicVolume = 0; + +static u8 sBgMusicDisabled = FALSE; static u16 sCurrentMusic = MUSIC_NONE; static u16 sCurrentShellMusic = MUSIC_NONE; static u16 sCurrentCapMusic = MUSIC_NONE; static u8 sPlayingInfiniteStairs = FALSE; -static u8 unused8032C6D8[16] = { 0 }; +UNUSED static u8 unused8032C6D8[16] = { 0 }; static s16 sSoundMenuModeToSoundMode[] = { SOUND_MODE_STEREO, SOUND_MODE_MONO, SOUND_MODE_HEADSET }; // Only the 20th array element is used. static u32 sMenuSoundsExtra[] = { @@ -78,7 +80,7 @@ void play_menu_sounds_extra(s32 a, void *b); * Called from threads: thread5_game_loop */ void reset_volume(void) { - D_8032C6C0 = 0; + sMusicVolume = 0; } /** @@ -93,7 +95,7 @@ void lower_background_noise(s32 a) { seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); break; } - D_8032C6C0 |= a; + sMusicVolume |= a; } /** @@ -108,15 +110,15 @@ void raise_background_noise(s32 a) { seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); break; } - D_8032C6C0 &= ~a; + sMusicVolume &= ~a; } /** * Called from threads: thread5_game_loop */ void disable_background_sound(void) { - if (D_8032C6C4 == 0) { - D_8032C6C4 = 1; + if (sBgMusicDisabled == FALSE) { + sBgMusicDisabled = TRUE; sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_BACKGROUND); } } @@ -125,8 +127,8 @@ void disable_background_sound(void) { * Called from threads: thread5_game_loop */ void enable_background_sound(void) { - if (D_8032C6C4 == 1) { - D_8032C6C4 = 0; + if (sBgMusicDisabled == TRUE) { + sBgMusicDisabled = FALSE; sound_banks_enable(SEQ_PLAYER_SFX, SOUND_BANKS_BACKGROUND); } } @@ -169,7 +171,7 @@ void play_menu_sounds(s16 soundMenuFlags) { if (soundMenuFlags & 0x100) { play_menu_sounds_extra(20, NULL); } -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (soundMenuFlags & SOUND_MENU_FLAG_LETGOMARIOFACE) { queue_rumble_data(10, 60); } @@ -347,11 +349,7 @@ void thread4_sound(UNUSED void *arg) { if (gResetTimer < 25) { struct SPTask *spTask; profiler_log_thread4_time(); -#ifdef VERSION_SH - spTask = func_sh_802f5a80(); // The function was probably just moved to a different file. Don't kill me. -#else spTask = create_next_audio_frame_task(); -#endif if (spTask != NULL) { dispatch_audio_sptask(spTask); } diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index b670751b..4cc1636b 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -163,7 +163,7 @@ 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. */ -static void unused_delete_leaf_nodes(struct Object *obj) { +UNUSED static void unused_delete_leaf_nodes(struct Object *obj) { struct Object *children; struct Object *sibling; struct Object *obj0 = obj; diff --git a/src/game/spawn_sound.c b/src/game/spawn_sound.c index a59767d6..18168b59 100644 --- a/src/game/spawn_sound.c +++ b/src/game/spawn_sound.c @@ -68,7 +68,7 @@ void cur_obj_play_sound_1(s32 soundMagic) { void cur_obj_play_sound_2(s32 soundMagic) { if (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) { play_sound(soundMagic, gCurrentObject->header.gfx.cameraToObject); -#ifdef VERSION_SH +#if ENABLE_RUMBLE if (soundMagic == SOUND_OBJ_BOWSER_WALK) { queue_rumble_data(3, 60); } diff --git a/src/goddard/debug_utils.c b/src/goddard/debug_utils.c index 3bd2d2fd..6e957539 100644 --- a/src/goddard/debug_utils.c +++ b/src/goddard/debug_utils.c @@ -488,7 +488,11 @@ void fatal_printf(const char *fmt, ...) { gd_printf("%s", va_arg(vl, char *)); break; case 'c': +#ifdef AVOID_UB + gd_printf("%c", (char)va_arg(vl, int)); +#else gd_printf("%c", va_arg(vl, char)); +#endif break; case 'x': gd_printf("%x", va_arg(vl, s32)); diff --git a/src/goddard/draw_objects.c b/src/goddard/draw_objects.c index 095f1e1e..abb7bcd3 100644 --- a/src/goddard/draw_objects.c +++ b/src/goddard/draw_objects.c @@ -59,7 +59,7 @@ static struct GdColour sClrYellow = { 1.0, 1.0, 0.0 }; // @ 801A80DC static struct GdColour sLightColours[1] = { { 1.0, 1.0, 0.0 } }; // @ 801A80E8 static struct GdColour *sSelectedColour = &sClrRed; // @ 801A80F4 struct ObjCamera *gViewUpdateCamera = NULL; // @ 801A80F8 -static void *sUnref801A80FC = NULL; +UNUSED static void *sUnref801A80FC = NULL; static s32 sUnreadShapeFlag = 0; // @ 801A8100 struct GdColour *sColourPalette[5] = { // @ 801A8104 &sClrWhite, &sClrYellow, &sClrRed, &sClrBlack, &sClrBlack @@ -69,20 +69,20 @@ struct GdColour *sWhiteBlack[2] = { &sClrWhite, &sClrBlack, }; -static Mat4f sUnref801A8120 = { +UNUSED static Mat4f sUnref801A8120 = { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 1.0 } }; -static Mat4f sUnrefIden801A8160 = { +UNUSED static Mat4f sUnrefIden801A8160 = { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 1.0 } }; static s32 sLightDlCounter = 1; // @ 801A81A0 -static s32 sUnref801A81A4[4] = { 0 }; +UNUSED static s32 sUnref801A81A4[4] = { 0 }; // bss u8 gUnref_801B9B30[0x88]; struct ObjGroup *gGdLightGroup; // @ 801B9BB8; is this the main light group? only light group? -static u8 sUnref_801B9BBC[0x40]; +UNUSED static u8 sUnref_801B9BBC[0x40]; static enum SceneType sSceneProcessType; // @ 801B9C00 static s32 sUseSelectedColor; // @ 801B9C04 static s16 sPickBuffer[100]; ///< buffer of objects near click diff --git a/src/goddard/gd_main.c b/src/goddard/gd_main.c index e515b328..225eb319 100644 --- a/src/goddard/gd_main.c +++ b/src/goddard/gd_main.c @@ -14,11 +14,11 @@ // data s32 gGdMoveScene = TRUE; // @ 801A8050 -static s32 sUnref801A8054 = TRUE; +UNUSED static s32 sUnref801A8054 = TRUE; f32 D_801A8058 = -600.0f; s32 gGdUseVtxNormal = TRUE; // @ 801A805C; instead of face normals -static s32 sUnrefScnWidth = 320; -static s32 sUnrefScnHeight = 240; +UNUSED static s32 sUnrefScnWidth = 320; +UNUSED static s32 sUnrefScnHeight = 240; // bss struct GdControl gGdCtrl; // @ 801B9920; processed controller info diff --git a/src/goddard/old_menu.c b/src/goddard/old_menu.c index 7d4751cb..3587d182 100644 --- a/src/goddard/old_menu.c +++ b/src/goddard/old_menu.c @@ -23,7 +23,7 @@ // bss static char sDefSettingsMenuStr[0x100]; static struct GdVec3f sStaticVec; -static struct GdVec3f unusedVec; +UNUSED static struct GdVec3f unusedVec; static struct ObjGadget *sCurGadgetPtr; // forward declarations diff --git a/src/goddard/particles.c b/src/goddard/particles.c index 26b3cb86..64b2d9d0 100644 --- a/src/goddard/particles.c +++ b/src/goddard/particles.c @@ -27,7 +27,7 @@ struct Connection { }; // data -static void *sUnused801A81D0 = NULL; +UNUSED static void *sUnused801A81D0 = NULL; static s32 D_801A81D4[25] = { /* ID? X Y Z */ 9, 3, 12, -14, 25, 5, 16, -25, 42, 4, 15, -39, 55, diff --git a/src/goddard/renderer.c b/src/goddard/renderer.c index e569b6d8..64e4bb79 100644 --- a/src/goddard/renderer.c +++ b/src/goddard/renderer.c @@ -113,10 +113,10 @@ static u8 D_801BAEA0; static struct ObjGadget *sTimerGadgets[GD_NUM_TIMERS]; // @ 801BAEA8 static u32 D_801BAF28; // RAM addr offset? static s16 sTriangleBuf[13][8]; // [[s16; 8]; 13]? vert indices? -static u32 unref_801bb000[3]; +UNUSED static u32 unref_801bb000[3]; static u8 *sMemBlockPoolBase; // @ 801BB00C static u32 sAllocMemory; // @ 801BB010; malloc-ed bytes -static u32 unref_801bb014; +UNUSED static u32 unref_801bb014; static s32 D_801BB018; static s32 D_801BB01C; static void *sLoadedTextures[0x10]; // texture pointers @@ -136,11 +136,11 @@ static s32 sVertexBufStartIndex; // Vtx start in GD Dl static struct ObjView *sCarSceneView; // @ 801BB0D0 static s32 sUpdateYoshiScene; // @ 801BB0D4; update dl Vtx from ObjVertex? static s32 sUpdateMarioScene; // @ 801BB0D8; update dl Vtx from ObjVertex? -static u32 unref_801bb0dc; +UNUSED static u32 unref_801bb0dc; static s32 sUpdateCarScene; // @ 801BB0E0; guess, not really used -static u32 unref_801bb0e4; +UNUSED static u32 unref_801bb0e4; static struct GdVec3f sTextDrawPos; // position to draw text? only set in one function, never used -static u32 unref_801bb0f8[2]; +UNUSED static u32 unref_801bb0f8[2]; static Mtx sIdnMtx; // @ 801BB100 static Mat4f sInitIdnMat4; // @ 801BB140 static s8 sVtxCvrtNormBuf[3]; // @ 801BB180 @@ -170,21 +170,21 @@ static LookAt D_801BE7D0[3]; #if defined(VERSION_JP) || defined(VERSION_US) static OSMesgQueue D_801BE830; // controller msg queue static OSMesg D_801BE848[10]; -static u32 unref_801be870[16]; +UNUSED static u32 unref_801be870[16]; static OSMesgQueue D_801BE8B0; static OSMesgQueue sGdDMAQueue; // @ 801BE8C8 -static u32 unref_801be8e0[25]; +UNUSED static u32 unref_801be8e0[25]; static OSMesg sGdMesgBuf[1]; // @ 801BE944 -static u32 unref_801be948[13]; +UNUSED static u32 unref_801be948[13]; static OSMesg sGdDMACompleteMsg; // msg buf for D_801BE8B0 queue static OSIoMesg sGdDMAReqMesg; static struct ObjView *D_801BE994; // store if View flag 0x40 set #endif // data -static u32 unref_801a8670 = 0; +UNUSED static u32 unref_801a8670 = 0; static s32 D_801A8674 = 0; -static u32 unref_801a8678 = 0; +UNUSED static u32 unref_801a8678 = 0; static s32 D_801A867C = 0; static s32 D_801A8680 = 0; static f32 sTracked1FrameTime = 0.0f; // @ 801A8684 @@ -199,11 +199,11 @@ static struct GdTimer *D_801A86A4 = NULL; // timer for dlgen, dynamics, or rcp static struct GdTimer *D_801A86A8 = NULL; // timer for dlgen, dynamics, or rcp static struct GdTimer *D_801A86AC = NULL; // timer for dlgen, dynamics, or rcp s32 gGdFrameBufNum = 0; // @ 801A86B0 -static u32 unref_801a86B4 = 0; +UNUSED static u32 unref_801a86B4 = 0; static struct ObjShape *sHandShape = NULL; // @ 801A86B8 static s32 D_801A86BC = 1; static s32 D_801A86C0 = 0; // gd_dl id for something? -static u32 unref_801a86C4 = 10; +UNUSED static u32 unref_801a86C4 = 10; static s32 sMtxParamType = G_MTX_PROJECTION; static struct GdVec3f D_801A86CC = { 1.0f, 1.0f, 1.0f }; static struct ObjView *sActiveView = NULL; // @ 801A86D8 current view? used when drawing dl @@ -214,7 +214,7 @@ static struct ObjView *sMenuView = NULL; // @ 801A86E8 static u32 sItemsInMenu = 0; // @ 801A86EC static s32 sDebugViewsCount = 0; // number of elements in the sDebugViews array static s32 sCurrDebugViewIndex = 0; // @ 801A86F4; timing activate cool down counter? -static u32 unref_801a86F8 = 0; +UNUSED static u32 unref_801a86F8 = 0; static struct GdDisplayList *sCurrentGdDl = NULL; // @ 801A86FC static u32 sGdDlCount = 0; // @ 801A8700 static struct DynListBankInfo sDynLists[] = { // @ 801A8704 @@ -225,7 +225,7 @@ static struct DynListBankInfo sDynLists[] = { // @ 801A8704 }; // textures and display list data -static Gfx gd_texture1_dummy_aligner1[] = { // @ 801A8728 +UNUSED static Gfx gd_texture1_dummy_aligner1[] = { // @ 801A8728 gsSPEndDisplayList(), }; @@ -233,7 +233,7 @@ ALIGNED8 static Texture gd_texture_hand_open[] = { #include "textures/intro_raw/hand_open.rgba16.inc.c" }; -static Gfx gd_texture2_dummy_aligner1[] = { +UNUSED static Gfx gd_texture2_dummy_aligner1[] = { gsSPEndDisplayList() }; @@ -494,7 +494,7 @@ ALIGNED8 static Texture gd_texture_sparkle_4[] = { //! No reference to this texture. Two DL's uses the same previous texture // instead of using this texture. -ALIGNED8 static Texture gd_texture_sparkle_5[] = { +UNUSED ALIGNED8 static Texture gd_texture_sparkle_5[] = { #include "textures/intro_raw/sparkle_5.rgba16.inc.c" }; @@ -649,7 +649,7 @@ static Gfx *gd_silver_sparkle_dl_array[] = { gd_dl_silver_sparkle_4_dup, }; -static Gfx gd_texture3_dummy_aligner1[] = { +UNUSED static Gfx gd_texture3_dummy_aligner1[] = { gsSPEndDisplayList(), }; @@ -694,13 +694,13 @@ static Gfx gd_dl_rdp_init[] = { gsSPEndDisplayList(), }; -static u32 gd_unused_pad1 = 0; +UNUSED static u32 gd_unused_pad1 = 0; float sGdPerspTimer = 1.0; -static u32 gd_unused_pad2 = 0; +UNUSED static u32 gd_unused_pad2 = 0; -static Gfx gd_texture4_dummy_aligner1[] = { +UNUSED static Gfx gd_texture4_dummy_aligner1[] = { gsDPPipeSync(), gsSPEndDisplayList(), }; @@ -717,7 +717,7 @@ static Vtx_t gd_unused_mesh_vertex_group2[] = { {{ 3, -7, 0}, 0, { 0, 0}, { 0xFF, 0x00, 0x00, 0xFF}}, }; -static Gfx gd_dl_unused_mesh[] = { +UNUSED static Gfx gd_dl_unused_mesh[] = { gsDPPipeSync(), gsDPSetRenderMode(G_RM_OPA_SURF, G_RM_OPA_SURF2), gsSPClearGeometryMode(0xFFFFFFFF), @@ -2837,6 +2837,9 @@ void stub_renderer_6(UNUSED struct GdObj *obj) { */ long defpup(UNUSED const char *menufmt, ...) { //! @bug no return; function was stubbed +#ifdef AVOID_UB + return 0; +#endif } /** diff --git a/src/goddard/shape_helper.c b/src/goddard/shape_helper.c index a0cd7ff0..cb8ff4f0 100644 --- a/src/goddard/shape_helper.c +++ b/src/goddard/shape_helper.c @@ -35,24 +35,24 @@ static struct GdAnimTransform unusedAnimData1[] = { { {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }, }; -static struct AnimDataInfo unusedAnim1 = { ARRAY_COUNT(unusedAnimData1), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData1 }; +UNUSED static struct AnimDataInfo unusedAnim1 = { ARRAY_COUNT(unusedAnimData1), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData1 }; static struct GdAnimTransform unusedAnimData2[] = { { {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }, }; -static struct AnimDataInfo unusedAnim2 = { ARRAY_COUNT(unusedAnimData2), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData2 }; +UNUSED static struct AnimDataInfo unusedAnim2 = { ARRAY_COUNT(unusedAnimData2), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData2 }; static struct GdAnimTransform unusedAnimData3[] = { { {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0} }, }; -static struct AnimDataInfo unusedAnim3 = { ARRAY_COUNT(unusedAnimData3), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData3 }; +UNUSED static struct AnimDataInfo unusedAnim3 = { ARRAY_COUNT(unusedAnimData3), GD_ANIM_SCALE3F_ROT3F_POS3F_2, unusedAnimData3 }; -static s32 sUnref801A838C[6] = { 0 }; +UNUSED static s32 sUnref801A838C[6] = { 0 }; struct ObjShape *sSimpleShape = NULL; -static s32 sUnref801A83A8[31] = { 0 }; -static struct DynList sSimpleDylist[8] = { // unused +UNUSED static s32 sUnref801A83A8[31] = { 0 }; +UNUSED static struct DynList sSimpleDylist[8] = { // unused BeginList(), StartGroup("simpleg"), MakeDynObj(D_NET, "simple"), @@ -67,17 +67,17 @@ static struct DynList sDynlist801A84E4[3] = { SetFlag(0x1800), EndList(), }; -static struct DynList sDynlist801A85B3[5] = { +UNUSED static struct DynList sDynlist801A85B3[5] = { BeginList(), CallList(sDynlist801A84E4), SetFlag(0x400), SetFriction(0.04, 0.01, 0.01), EndList(), }; -static struct DynList sDynlist801A85A4[4] = { +UNUSED static struct DynList sDynlist801A85A4[4] = { BeginList(), CallList(sDynlist801A84E4), SetFriction(0.04, 0.01, 0.01), EndList(), }; -static struct DynList sDynlist801A8604[4] = { +UNUSED static struct DynList sDynlist801A8604[4] = { BeginList(), CallList(sDynlist801A84E4), SetFriction(0.005, 0.005, 0.005), @@ -86,35 +86,35 @@ static struct DynList sDynlist801A8604[4] = { static f64 D_801A8668 = 0.0; // bss -static u8 sUnrefSpaceB00[0x2C]; // @ 801BAB00 +UNUSED static u8 sUnrefSpaceB00[0x2C]; // @ 801BAB00 static struct ObjGroup *sCubeShapeGroup; // @ 801BAB2C -static u8 sUnrefSpaceB30[0xC]; // @ 801BAB30 +UNUSED static u8 sUnrefSpaceB30[0xC]; // @ 801BAB30 static struct ObjShape *sCubeShape; // @ 801BAB3C -static u8 sUnrefSpaceB40[0x8]; // @ 801BAB40 +UNUSED static u8 sUnrefSpaceB40[0x8]; // @ 801BAB40 static char sGdLineBuf[0x100]; // @ 801BAB48 static s32 sGdLineBufCsr; // @ 801BAC48 static struct GdFile *sGdShapeFile; // @ 801BAC4C static struct ObjShape *sGdShapeListHead; // @ 801BAC50 static u32 sGdShapeCount; // @ 801BAC54 -static u8 sUnrefSpaceC58[0x8]; // @ 801BAC58 +UNUSED static u8 sUnrefSpaceC58[0x8]; // @ 801BAC58 static struct GdVec3f D_801BAC60; -static u32 sUnrefSpaceC6C; // @ 801BAC6C -static u32 sUnrefSpaceC70; // @ 801BAC70 +UNUSED static u32 sUnrefSpaceC6C; // @ 801BAC6C +UNUSED static u32 sUnrefSpaceC70; // @ 801BAC70 static struct ObjPlane *D_801BAC74; static struct ObjPlane *D_801BAC78; // sShapeNetHead? -static u8 sUnrefSpaceC80[0x1C]; // @ 801BAC80 +UNUSED static u8 sUnrefSpaceC80[0x1C]; // @ 801BAC80 static struct ObjFace *D_801BAC9C; static struct ObjFace *D_801BACA0; -static u8 sUnrefSpaceCA8[0x10]; // @ 801BACA8 +UNUSED static u8 sUnrefSpaceCA8[0x10]; // @ 801BACA8 /// factor for scaling vertices in an `ObjShape` when calling `scale_verts_in_shape()` static struct GdVec3f sVertexScaleFactor; /// factor for translating vertices in an `ObjShape` when calling `translate_verts_in_shape()` static struct GdVec3f sVertexTranslateOffset; -static u8 sUnrefSpaceCD8[0x30]; // @ 801BACD8 +UNUSED static u8 sUnrefSpaceCD8[0x30]; // @ 801BACD8 static struct ObjGroup *D_801BAD08; // group of planes from make_netfromshape -static u8 sUnrefSpaceD10[0x20]; // @ 801BAD10 +UNUSED static u8 sUnrefSpaceD10[0x20]; // @ 801BAD10 static struct GdVec3f sShapeCenter; // printed with "c=" -static u8 sUnrefSpaceD40[0x120]; // @ 801BAD40 +UNUSED static u8 sUnrefSpaceD40[0x120]; // @ 801BAD40 // Forward Declarations struct ObjMaterial *find_or_add_new_mtl(struct ObjGroup *, s32, f32, f32, f32); diff --git a/src/menu/file_select.c b/src/menu/file_select.c index c8947978..9437dcc6 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -548,7 +548,7 @@ void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 scoreButto if (scoreFileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN && sCursorClickingTimer == 2) { play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif scoreFileButton->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; @@ -643,7 +643,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { if (buttonID == MENU_BUTTON_SCORE_RETURN || buttonID == MENU_BUTTON_SCORE_COPY_FILE || buttonID == MENU_BUTTON_SCORE_ERASE_FILE) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -654,7 +654,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { // 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, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; @@ -663,7 +663,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = @@ -759,7 +759,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { if (save_file_exists(copyFileButtonID - MENU_BUTTON_COPY_MIN) == TRUE) { // If clicked in a existing save file, ask where it wants to copy play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[copyFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; @@ -770,7 +770,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { } else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[copyFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -785,7 +785,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { if (save_file_exists(copyFileButtonID - MENU_BUTTON_COPY_MIN) == FALSE) { // If clicked in a non-existing save file, copy the file play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif copyButton->oMenuButtonActionPhase = COPY_PHASE_COPY_COMPLETE; @@ -800,7 +800,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { // If clicked in a existing save file, play buzz sound if (MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex == copyFileButtonID) { play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex]->oMenuButtonState = @@ -843,7 +843,7 @@ void check_copy_menu_clicked_buttons(struct Object *copyButton) { || buttonID == MENU_BUTTON_COPY_ERASE_FILE) { if (copyButton->oMenuButtonActionPhase == COPY_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -941,7 +941,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) if (save_file_exists(eraseFileButtonID - MENU_BUTTON_ERASE_MIN) == TRUE) { // If clicked in a existing save file, ask if it wants to delete it play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[eraseFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; @@ -952,7 +952,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) } else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[eraseFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -969,7 +969,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) // Note: The prompt functions are actually called when the ERASE_MSG_PROMPT // message is displayed with print_erase_menu_prompt play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = @@ -999,7 +999,7 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) { || buttonID == MENU_BUTTON_ERASE_COPY_FILE) { if (eraseButton->oMenuButtonActionPhase == ERASE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -1094,7 +1094,7 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { || buttonID == MENU_BUTTON_HEADSET) { if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -1425,28 +1425,28 @@ void check_main_menu_clicked_buttons(void) { switch (sSelectedButtonID) { case MENU_BUTTON_PLAY_FILE_A: play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif break; case MENU_BUTTON_PLAY_FILE_B: play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif break; case MENU_BUTTON_PLAY_FILE_C: play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif break; case MENU_BUTTON_PLAY_FILE_D: play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif @@ -1454,28 +1454,28 @@ void check_main_menu_clicked_buttons(void) { // Play sound of the button clicked and render buttons of that menu. case MENU_BUTTON_SCORE: play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif render_score_menu_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); break; case MENU_BUTTON_COPY: play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif render_copy_menu_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); break; case MENU_BUTTON_ERASE: play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif render_erase_menu_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); break; case MENU_BUTTON_SOUND_MODE: play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif render_sound_mode_menu_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); @@ -2248,7 +2248,7 @@ void print_erase_menu_prompt(s16 x, s16 y) { // ..and is hovering "YES", delete file if (sEraseYesNoHoverState == MENU_ERASE_HOVER_YES) { play_sound(SOUND_MARIO_WAAAOOOW, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonActionPhase = ERASE_PHASE_MARIO_ERASED; @@ -2263,7 +2263,7 @@ void print_erase_menu_prompt(s16 x, s16 y) { // ..and is hovering "NO", return back to main phase } else if (sEraseYesNoHoverState == MENU_ERASE_HOVER_NO) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = diff --git a/src/menu/intro_geo.c b/src/menu/intro_geo.c index e2e5bb92..48d53f8b 100644 --- a/src/menu/intro_geo.c +++ b/src/menu/intro_geo.c @@ -348,7 +348,7 @@ u16 *intro_sample_frame_buffer(s32 imageW, s32 imageH, s32 sampleW, s32 sampleH) s32 xOffset = 120; s32 yOffset = 80; - fb = sFrameBuffers[frameBufferIndex]; + fb = sFrameBuffers[sRenderingFrameBuffer]; image = alloc_display_list(imageW * imageH * sizeof(u16)); if (image == NULL) { @@ -439,6 +439,10 @@ Gfx *geo_intro_rumble_pak_graphic(s32 state, struct GraphNode *node, UNUSED void Gfx *dl; s32 introContext; s8 backgroundTileSix; +#ifdef AVOID_UB + dl = NULL; + backgroundTileSix = 0; +#endif if (state != 1) { dl = NULL; diff --git a/src/menu/level_select_menu.h b/src/menu/level_select_menu.h deleted file mode 100644 index fcb2b9ac..00000000 --- a/src/menu/level_select_menu.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LEVEL_SELECT_MENU_H -#define LEVEL_SELECT_MENU_H - -#include - -#include "macros.h" - -s32 lvl_intro_update(s16 arg1, UNUSED s32 arg2); - -#endif // LEVEL_SELECT_MENU_H diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 025dbf24..07610faa 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -421,7 +421,7 @@ s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused #else play_sound(SOUND_MENU_STAR_SOUND_LETS_A_GO, gGlobalSoundSource); #endif -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif diff --git a/src/menu/level_select_menu.c b/src/menu/title_screen.c similarity index 55% rename from src/menu/level_select_menu.c rename to src/menu/title_screen.c index 2b1010b3..071714f0 100644 --- a/src/menu/level_select_menu.c +++ b/src/menu/title_screen.c @@ -14,71 +14,81 @@ #include "level_table.h" #include "seq_ids.h" #include "sm64.h" +#include "title_screen.h" -#define PRESS_START_DEMO_TIMER 800 +/** + * @file title_screen.c + * This file implements how title screen functions. + * That includes playing demo sequences, introduction screens + * and a level select used for testing purposes. + */ #define STUB_LEVEL(textname, _1, _2, _3, _4, _5, _6, _7, _8) textname, #define DEFINE_LEVEL(textname, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) textname, -static char gLevelSelect_StageNamesText[64][16] = { +static char sLevelSelectStageNames[64][16] = { #include "levels/level_defines.h" }; #undef STUB_LEVEL #undef DEFINE_LEVEL -static u16 gDemoCountdown = 0; +static u16 sDemoCountdown = 0; #ifndef VERSION_JP -static s16 D_U_801A7C34 = 1; -static s16 gameOverNotPlayed = 1; +static s16 sPlayMarioGreeting = TRUE; +static s16 sPlayMarioGameOver = TRUE; #endif -// run the demo timer on the PRESS START screen. -// this function will return a non-0 timer once -// the demo starts, signaling to the subsystem that -// the demo needs to be ran. +#define PRESS_START_DEMO_TIMER 800 -// don't shift this function from being the first function in the segment. -// the level scripts assume this function is the first, so it cant be moved. -s32 run_press_start_demo_timer(s32 timer) { +/** + * Run the demo timer on the PRESS START screen after a number of frames. + * This function returns the level ID from the first byte of a demo file. + * It also returns the level ID from intro_regular (file select or level select menu) + */ +s32 run_level_id_or_demo(s32 level) { gCurrDemoInput = NULL; - if (timer == 0) { + if (level == LEVEL_NONE) { if (!gPlayer1Controller->buttonDown && !gPlayer1Controller->stickMag) { - if ((++gDemoCountdown) == PRESS_START_DEMO_TIMER) { - // start the demo. 800 frames has passed while - // player is idle on PRESS START screen. + // start the demo. 800 frames has passed while + // player is idle on PRESS START screen. + if ((++sDemoCountdown) == PRESS_START_DEMO_TIMER) { // start the Mario demo animation for the demo list. - load_patchable_table(&gDemo, gDemoInputListID); + load_patchable_table(&gDemoInputsBuf, gDemoInputListID); // if the next demo sequence ID is the count limit, reset it back to // the first sequence. - if (++gDemoInputListID == gDemo.animDmaTable->count) { + if (++gDemoInputListID == gDemoInputsBuf.dmaTable->count) { gDemoInputListID = 0; } - // add 1 (+4) to the pointer to skip the demoID. - gCurrDemoInput = ((struct DemoInput *) gDemo.targetAnim) + 1; - timer = (s8)((struct DemoInput *) gDemo.targetAnim)->timer; + // add 1 (+4) to the pointer to skip the first 4 bytes + // Use the first 4 bytes to store level ID, + // then use the rest of the values for inputs + gCurrDemoInput = ((struct DemoInput *) gDemoInputsBuf.bufTarget) + 1; + level = (s8)((struct DemoInput *) gDemoInputsBuf.bufTarget)->timer; gCurrSaveFileNum = 1; gCurrActNum = 1; } } else { // activity was detected, so reset the demo countdown. - gDemoCountdown = 0; + sDemoCountdown = 0; } } - return timer; + return level; } -// input loop for the level select menu. updates the selected stage -// count if an input was received. signals the stage to be started -// or the level select to be exited if start or the quit combo is -// pressed. - -s16 level_select_input_loop(void) { +/** + * Level select intro function, updates the selected stage + * count if an input was received. signals the stage to be started + * or the level select to be exited if start or the quit combo is pressed. + */ +s16 intro_level_select(void) { s32 stageChanged = FALSE; // perform the ID updates per each button press. + // runs into a loop so after a button is pressed + // stageChanged goes back to FALSE if (gPlayer1Controller->buttonPressed & A_BUTTON) { ++gCurrLevelNum, stageChanged = TRUE; } @@ -103,7 +113,6 @@ s16 level_select_input_loop(void) { play_sound(SOUND_GENERAL_LEVEL_SELECT_CHANGE, gGlobalSoundSource); } - // TODO: enum counts for the stage lists if (gCurrLevelNum > LEVEL_MAX) { gCurrLevelNum = LEVEL_MIN; // exceeded max. set to min. } @@ -112,12 +121,14 @@ s16 level_select_input_loop(void) { gCurrLevelNum = LEVEL_MAX; // exceeded min. set to max. } - gCurrSaveFileNum = 4; // file 4 is used for level select tests + // Use file 4 and last act as a test + gCurrSaveFileNum = 4; gCurrActNum = 6; + print_text_centered(160, 80, "SELECT STAGE"); print_text_centered(160, 30, "PRESS START BUTTON"); print_text_fmt_int(40, 60, "%2d", gCurrLevelNum); - print_text(80, 60, gLevelSelect_StageNamesText[gCurrLevelNum - 1]); // print stage name + print_text(80, 60, sLevelSelectStageNames[gCurrLevelNum - 1]); // print stage name #define QUIT_LEVEL_SELECT_COMBO (Z_TRIG | START_BUTTON | L_CBUTTONS | R_CBUTTONS) @@ -135,42 +146,55 @@ s16 level_select_input_loop(void) { return 0; } -s32 intro_default(void) { - s32 sp1C = 0; +/** + * Regular intro function that handles Mario's greeting voice and game start. + */ +s32 intro_regular(void) { + s32 level = LEVEL_NONE; #ifndef VERSION_JP - if (D_U_801A7C34 == 1) { - if (gGlobalTimer < 0x81) { + // When the game stars, gGlobalTimer is less than 129 frames, + // so Mario greets the player. After that, he will always say + // "press start to play" when it goes back to the title screen + // (using SAVE AND QUIT) + if (sPlayMarioGreeting == TRUE) { + if (gGlobalTimer < 129) { play_sound(SOUND_MARIO_HELLO, gGlobalSoundSource); } else { play_sound(SOUND_MARIO_PRESS_START_TO_PLAY, gGlobalSoundSource); } - D_U_801A7C34 = 0; + sPlayMarioGreeting = FALSE; } #endif print_intro_text(); if (gPlayer1Controller->buttonPressed & START_BUTTON) { play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif - sp1C = 100 + gDebugLevelSelect; + // calls level ID 100 (or 101 adding level select bool value) + // defined in level_intro_mario_head_regular JUMP_IF commands + // 100 is File Select - 101 is Level Select + level = 100 + gDebugLevelSelect; #ifndef VERSION_JP - D_U_801A7C34 = 1; + sPlayMarioGreeting = TRUE; #endif } - return run_press_start_demo_timer(sp1C); + return run_level_id_or_demo(level); } +/** + * Game over intro function that handles Mario's game over voice and game start. + */ s32 intro_game_over(void) { - s32 sp1C = 0; + s32 level = LEVEL_NONE; #ifndef VERSION_JP - if (gameOverNotPlayed == 1) { + if (sPlayMarioGameOver == TRUE) { play_sound(SOUND_MARIO_GAME_OVER, gGlobalSoundSource); - gameOverNotPlayed = 0; + sPlayMarioGameOver = FALSE; } #endif @@ -178,39 +202,47 @@ s32 intro_game_over(void) { if (gPlayer1Controller->buttonPressed & START_BUTTON) { play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); -#ifdef VERSION_SH +#if ENABLE_RUMBLE queue_rumble_data(60, 70); func_sh_8024C89C(1); #endif - sp1C = 100 + gDebugLevelSelect; + // same criteria as intro_regular + level = 100 + gDebugLevelSelect; #ifndef VERSION_JP - gameOverNotPlayed = 1; + sPlayMarioGameOver = TRUE; #endif } - return run_press_start_demo_timer(sp1C); + return run_level_id_or_demo(level); } +/** + * Plays the casual "It's a me mario" when the game stars. + */ s32 intro_play_its_a_me_mario(void) { set_background_music(0, SEQ_SOUND_PLAYER, 0); play_sound(SOUND_MENU_COIN_ITS_A_ME_MARIO, gGlobalSoundSource); return 1; } -s32 lvl_intro_update(s16 arg1, UNUSED s32 arg2) { +/** + * Update intro functions to handle title screen actions. + * Returns a level ID after their criteria is met. + */ +s32 lvl_intro_update(s16 arg, UNUSED s32 unusedArg) { s32 retVar; - switch (arg1) { - case 0: + switch (arg) { + case LVL_INTRO_PLAY_ITS_A_ME_MARIO: retVar = intro_play_its_a_me_mario(); break; - case 1: - retVar = intro_default(); + case LVL_INTRO_REGULAR: + retVar = intro_regular(); break; - case 2: + case LVL_INTRO_GAME_OVER: retVar = intro_game_over(); break; - case 3: - retVar = level_select_input_loop(); + case LVL_INTRO_LEVEL_SELECT: + retVar = intro_level_select(); break; } return retVar; diff --git a/src/menu/title_screen.h b/src/menu/title_screen.h new file mode 100644 index 00000000..4893158f --- /dev/null +++ b/src/menu/title_screen.h @@ -0,0 +1,17 @@ +#ifndef TITLE_SCREEN_H +#define TITLE_SCREEN_H + +#include + +#include "macros.h" + +enum LevelScriptIntroArgs { + LVL_INTRO_PLAY_ITS_A_ME_MARIO, + LVL_INTRO_REGULAR, + LVL_INTRO_GAME_OVER, + LVL_INTRO_LEVEL_SELECT +}; + +s32 lvl_intro_update(s16 arg, UNUSED s32 unusedArg); + +#endif // TITLE_SCREEN_H diff --git a/tools/.gitignore b/tools/.gitignore index 469b3062..7be0668f 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -6,7 +6,7 @@ /n64cksum /n64graphics /n64graphics_ci -/patch_libultra_math +/patch_elf_32bit /skyconv /tabledesign /textconv diff --git a/tools/Makefile b/tools/Makefile index ef5a9909..92a39168 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,7 +7,7 @@ CC := gcc CXX := g++ CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -O2 -s LDFLAGS := -lm -ALL_PROGRAMS := armips n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv +ALL_PROGRAMS := armips n64graphics n64graphics_ci mio0 n64cksum textconv patch_elf_32bit aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv LIBAUDIOFILE := audiofile/libaudiofile.a # Only build armips from tools if it is not found on the system @@ -32,7 +32,7 @@ n64cksum_CFLAGS := -DN64CKSUM_STANDALONE textconv_SOURCES := textconv.c utf8.c hashtable.c -patch_libultra_math_SOURCES := patch_libultra_math.c +patch_elf_32bit_SOURCES := patch_elf_32bit.c aifc_decode_SOURCES := aifc_decode.c diff --git a/tools/aiff_extract_codebook.c b/tools/aiff_extract_codebook.c index 78864e38..c229139a 100644 --- a/tools/aiff_extract_codebook.c +++ b/tools/aiff_extract_codebook.c @@ -2,7 +2,6 @@ * Create an ADPCM codebook either by extracting it from an AIFF section, or * by executing tabledesign. */ -#define _XOPEN_SOURCE 500 #include #include #include diff --git a/tools/assemble_sound.py b/tools/assemble_sound.py index 9c6598f1..f4a81d26 100755 --- a/tools/assemble_sound.py +++ b/tools/assemble_sound.py @@ -659,7 +659,7 @@ def serialize_ctl(bank, base_ser, is_shindou): base_ser.add(ser.finish()) return pack( - "BBBB", bank.sample_bank.index, 0xFF, len(json["instrument_list"]), len(drums) + "hh", (bank.sample_bank.index << 8) | 0xFF, (len(json["instrument_list"]) << 8) | len(drums) ) @@ -704,7 +704,8 @@ def serialize_seqfile( ser = ReserveSerializer() ser.add(pack("H", len(entries))) ser.align(16) - sh_magic = 0x0204 if magic == TYPE_TBL else 0x0203 + medium = 0x02 # cartridge + sh_magic = 0x04 if magic == TYPE_TBL else 0x03 # Ignore entry_list and loop over all entries instead. This makes a # difference for sample banks, where US/JP/EU doesn't use a normal @@ -712,9 +713,9 @@ def serialize_seqfile( # sample bank offset/length. Shindou uses a normal header and makes the # mapping part of the sound bank header instead (part of entry_meta). for i in range(len(entries)): - ser.add(pack("PIH", entry_offsets[i], entry_lens[i], sh_magic)) + ser.add(pack("PIbb", entry_offsets[i], entry_lens[i], medium, sh_magic)) ser.add(entry_meta[i] or b"\0\0\0\0") - ser.align(16) + ser.align(WORD_BYTES) if out_header_filename: with open(out_header_filename, "wb") as f: diff --git a/tools/demo_data_converter.py b/tools/demo_data_converter.py index ab656bd7..86ea94c5 100755 --- a/tools/demo_data_converter.py +++ b/tools/demo_data_converter.py @@ -62,7 +62,7 @@ def main(): structdef.append("u8 " + item["name"] + "[" + str(len(demobytes)) + "];") structobj.append("{" + ",".join(hex(x) for x in demobytes) + "},") - print("#include \"types.h\"") + print("#include \"game/memory.h\"") print("#include ") print("") diff --git a/tools/ido5.3_recomp/libc_impl.c b/tools/ido5.3_recomp/libc_impl.c index 929d58fa..af4ca713 100644 --- a/tools/ido5.3_recomp/libc_impl.c +++ b/tools/ido5.3_recomp/libc_impl.c @@ -177,13 +177,13 @@ static char bin_dir[PATH_MAX + 1]; #endif static int g_file_max = 3; -#ifdef __CYGWIN__ +#if defined(__CYGWIN__) || defined(__APPLE__) static size_t g_Pagesize; #endif static uint8_t *memory_map(size_t length) { -#ifdef __CYGWIN__ +#if defined(__CYGWIN__) || defined(__APPLE__) uint8_t *mem = mmap(0, length, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); g_Pagesize = sysconf(_SC_PAGESIZE); assert(((uintptr_t)mem & (g_Pagesize-1)) == 0); @@ -201,7 +201,7 @@ static void memory_allocate(uint8_t *mem, uint32_t start, uint32_t end) { assert(start >= MEM_REGION_START); assert(end <= MEM_REGION_START + MEM_REGION_SIZE); -#ifdef __CYGWIN__ +#if defined(__CYGWIN__) || defined(__APPLE__) uintptr_t _start = ((uintptr_t)mem + start) & ~(g_Pagesize-1); uintptr_t _end = ((uintptr_t)mem + end + (g_Pagesize-1)) & ~(g_Pagesize-1); diff --git a/tools/ido5.3_recomp/recomp.cpp b/tools/ido5.3_recomp/recomp.cpp index 59543056..2bf6e132 100644 --- a/tools/ido5.3_recomp/recomp.cpp +++ b/tools/ido5.3_recomp/recomp.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -21,9 +22,6 @@ #define LABELS_64_BIT 1 -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - #define u32be(x) (uint32_t)(((x & 0xff) << 24) + ((x & 0xff00) << 8) + ((x & 0xff0000) >> 8) + ((uint32_t)(x) >> 24)) #define u16be(x) (uint16_t)(((x & 0xff) << 8) + ((x & 0xff00) >> 8)) #define read_u32_be(buf) (uint32_t)(((buf)[0] << 24) + ((buf)[1] << 16) + ((buf)[2] << 8) + ((buf)[3])) @@ -280,24 +278,31 @@ static const struct { static void disassemble(void) { csh handle; cs_insn *disasm; - static size_t disasm_size; + size_t disasm_size = 0; assert(cs_open(CS_ARCH_MIPS, (cs_mode)(CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN), &handle) == CS_ERR_OK); cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); - disasm_size = cs_disasm(handle, text_section, text_section_len, text_vaddr, 0, &disasm); - for (size_t i = 0; i < disasm_size; i++) { - insns.push_back(Insn()); - Insn& insn = insns.back(); - insn.id = disasm[i].id; - insn.mnemonic = disasm[i].mnemonic; - insn.op_str = disasm[i].op_str; - if (disasm[i].detail != nullptr && disasm[i].detail->mips.op_count > 0) { - insn.op_count = disasm[i].detail->mips.op_count; - memcpy(insn.operands, disasm[i].detail->mips.operands, sizeof(insn.operands)); + insns.reserve(1 + text_section_len / sizeof(uint32_t)); // +1 for dummy instruction + while (text_section_len > disasm_size * sizeof(uint32_t)) { + size_t disasm_len = disasm_size * sizeof(uint32_t); + size_t remaining = text_section_len - disasm_len; + size_t current_len = std::min(remaining, 1024); + size_t cur_disasm_size = cs_disasm(handle, &text_section[disasm_len], current_len, text_vaddr + disasm_len, 0, &disasm); + disasm_size += cur_disasm_size; + for (size_t i = 0; i < cur_disasm_size; i++) { + insns.push_back(Insn()); + Insn& insn = insns.back(); + insn.id = disasm[i].id; + insn.mnemonic = disasm[i].mnemonic; + insn.op_str = disasm[i].op_str; + if (disasm[i].detail != nullptr && disasm[i].detail->mips.op_count > 0) { + insn.op_count = disasm[i].detail->mips.op_count; + memcpy(insn.operands, disasm[i].detail->mips.operands, sizeof(insn.operands)); + } + insn.is_jump = cs_insn_group(handle, &disasm[i], MIPS_GRP_JUMP) || insn.id == MIPS_INS_JAL || insn.id == MIPS_INS_BAL || insn.id == MIPS_INS_JALR; + insn.linked_insn = -1; } - insn.is_jump = cs_insn_group(handle, &disasm[i], MIPS_GRP_JUMP) || insn.id == MIPS_INS_JAL || insn.id == MIPS_INS_BAL || insn.id == MIPS_INS_JALR; - insn.linked_insn = -1; + cs_free(disasm, cur_disasm_size); } - cs_free(disasm, disasm_size); cs_close(&handle); { @@ -334,7 +339,7 @@ static void link_with_lui(int offset, uint32_t reg, int mem_imm) #define MAX_LOOKBACK 128 // don't attempt to compute addresses for zero offset // end search after some sane max number of instructions - int end_search = MAX(0, offset - MAX_LOOKBACK); + int end_search = std::max(0, offset - MAX_LOOKBACK); for (int search = offset - 1; search >= end_search; search--) { // use an `if` instead of `case` block to allow breaking out of the `for` loop if (insns[search].id == MIPS_INS_LUI) { @@ -421,7 +426,7 @@ static void link_with_lui(int offset, uint32_t reg, int mem_imm) static void link_with_jalr(int offset) { // end search after some sane max number of instructions - int end_search = MAX(0, offset - MAX_LOOKBACK); + int end_search = std::max(0, offset - MAX_LOOKBACK); for (int search = offset - 1; search >= end_search; search--) { if (insns[search].operands[0].reg == MIPS_REG_T9) { if (insns[search].id == MIPS_INS_LW || insns[search].id == MIPS_INS_LI) { @@ -2332,16 +2337,16 @@ static void dump_c(void) { uint32_t max_addr = 0; if (data_section_len > 0) { - min_addr = MIN(min_addr, data_vaddr); - max_addr = MAX(max_addr, data_vaddr + data_section_len); + min_addr = std::min(min_addr, data_vaddr); + max_addr = std::max(max_addr, data_vaddr + data_section_len); } if (rodata_section_len > 0) { - min_addr = MIN(min_addr, rodata_vaddr); - max_addr = MAX(max_addr, rodata_vaddr + rodata_section_len); + min_addr = std::min(min_addr, rodata_vaddr); + max_addr = std::max(max_addr, rodata_vaddr + rodata_section_len); } if (bss_section_len) { - min_addr = MIN(min_addr, bss_vaddr); - max_addr = MAX(max_addr, bss_vaddr + bss_section_len); + min_addr = std::min(min_addr, bss_vaddr); + max_addr = std::max(max_addr, bss_vaddr + bss_section_len); } min_addr = min_addr & ~0xfff; diff --git a/tools/mario_anims_converter.py b/tools/mario_anims_converter.py index 361662ae..fcf92a54 100755 --- a/tools/mario_anims_converter.py +++ b/tools/mario_anims_converter.py @@ -136,7 +136,7 @@ try: structdef.append("{} {}[{}];".format(type, name, len(arr))) structobj.append("{" + ",".join(arr) + "},") - print("#include \"types.h\"") + print("#include \"game/memory.h\"") print("#include ") print("") diff --git a/tools/output_level_headers.py b/tools/output_level_headers.py deleted file mode 100644 index a1ea4aa0..00000000 --- a/tools/output_level_headers.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python3 -import sys -for line in sys.stdin: - if line.strip(): - print('#include "{}"'.format(line.strip())) diff --git a/tools/patch_libultra_math.c b/tools/patch_elf_32bit.c similarity index 68% rename from tools/patch_libultra_math.c rename to tools/patch_elf_32bit.c index e6bdcc0c..8e529520 100644 --- a/tools/patch_libultra_math.c +++ b/tools/patch_elf_32bit.c @@ -3,6 +3,9 @@ #include #include +#define ARMAG "!\n" +#define SARMAG 8 + /* from elf.h */ /* Type for a 16-bit quantity. */ @@ -78,13 +81,36 @@ struct ar_header { //These constants found by inspecting output of objdump #define FLAGS_MIPS3 0x20 #define FLAGS_O32ABI 0x100000 -int main(int argc, char **argv) { - FILE *f = fopen(argv[1], "r+"); - if (f == NULL) { - printf("Failed to open file! %s\n", argv[1]); +int fix_mips_elf(FILE *f, size_t filesize) +{ + Elf32_Ehdr hdr; + if (filesize < sizeof(hdr) || (1 != fread(&hdr, sizeof(hdr), 1, f))) { + printf("Failed to read ELF header\n"); return -1; } + + if (strncmp((const char *) hdr.e_ident, ELFMAG, SELFMAG) == 0) { + // found an ELF file. + if (hdr.e_ident[EI_CLASS] != ELFCLASS32 || hdr.e_ident[EI_DATA] != ELFDATA2MSB) { + printf("Expected 32bit big endian object files\n"); + return -1; + } + + if ((hdr.e_flags & 0xFF) == FLAGS_MIPS3 && (hdr.e_flags & FLAGS_O32ABI) == 0) { + hdr.e_flags |= FLAGS_O32ABI; + fseek(f, -(long)sizeof(hdr), SEEK_CUR); + if (1 != fwrite(&hdr, sizeof(hdr), 1, f)) { + printf("Failed to write back ELF header after patching.\n"); + return -1; + } + } + } + return 0; +} + +int fix_mips_ar(FILE *f) +{ struct ar_header current_header; fseek(f, 0x8, SEEK_SET); // skip header, this is safe enough given that we check to make sure the // file header is valid @@ -95,32 +121,41 @@ int main(int argc, char **argv) { return -1; } size_t filesize = atoi(current_header.file_size_in_bytes); - Elf32_Ehdr hdr; - if (filesize < sizeof(hdr) || (1 != fread(&hdr, sizeof(hdr), 1, f))) { - printf("Failed to read ELF header\n"); + if (fix_mips_elf(f, filesize)) { return -1; } - - if (strncmp((const char *) hdr.e_ident, ELFMAG, SELFMAG) == 0) { - // found an ELF file. - if (hdr.e_ident[EI_CLASS] != ELFCLASS32 || hdr.e_ident[EI_DATA] != ELFDATA2MSB) { - printf("Expected 32bit big endian object files\n"); - return -1; - } - - if ((hdr.e_flags & 0xFF) == FLAGS_MIPS3 && (hdr.e_flags & FLAGS_O32ABI) == 0) { - hdr.e_flags |= FLAGS_O32ABI; - fseek(f, -sizeof(hdr), SEEK_CUR); - if (1 != fwrite(&hdr, sizeof(hdr), 1, f)) { - printf("Failed to write back ELF header after patching.\n"); - return -1; - } - } - } if (filesize % 2 == 1) filesize++; - fseek(f, filesize - sizeof(hdr), SEEK_CUR); + fseek(f, filesize - sizeof(Elf32_Ehdr), SEEK_CUR); } - fclose(f); return 0; } + +int main(int argc, char **argv) { + FILE *f = fopen(argv[1], "r+b"); + uint8_t magic[8]; + int status = 0; + + if (f == NULL) { + printf("Failed to open file! %s\n", argv[1]); + return -1; + } + if (1 != fread(&magic, sizeof(magic), 1, f)) { + printf("Failed to read file magic\n"); + return -1; + } + rewind(f); + if (!memcmp(ARMAG, magic, SARMAG)) { + status = fix_mips_ar(f); + } else if (!memcmp(ELFMAG, magic, SELFMAG)) { + fseek(f, 0, SEEK_END); + size_t filesize = ftell(f); + rewind(f); + status = fix_mips_elf(f, filesize); + } else { + printf("Unknown file magic: %02x%02x%02X%02X\n", magic[0], magic[1], magic[2], magic[3]); + status = -1; + } + fclose(f); + return status; +} diff --git a/tools/seq_decoder.py b/tools/seq_decoder.py index ce238209..9329e702 100755 --- a/tools/seq_decoder.py +++ b/tools/seq_decoder.py @@ -162,8 +162,8 @@ if len(sys.argv) != 2: sys.exit(0) if sys.argv[1] == "--emit-asm-macros": - print("# Macros for disassembled sequence files. This file was automatically generated by seq_decoder.py.") - print("# To regenerate it, run: ./tools/seq_decoder.py --emit-asm-macros >seq_macros.inc") + print("// Macros for disassembled sequence files. This file was automatically generated by seq_decoder.py.") + print("// To regenerate it, run: ./tools/seq_decoder.py --emit-asm-macros > include/seq_macros.inc") print() def print_hword(x): print(f" .byte {x} >> 8, {x} & 0xff") @@ -219,7 +219,7 @@ if sys.argv[1] == "--emit-asm-macros": print(".endm\n") for key in ['seq', 'chan', 'layer']: - print(f"# {key} commands\n") + print(f"// {key} commands\n") if key == 'layer': cmds = commands['layer_large'] for op in sorted(commands['layer_small'].keys()): @@ -267,31 +267,31 @@ if sys.argv[1] == "--emit-asm-macros": emit_cmd(key, 0xc0, ['delay_long', 'var_long']) emit_cmd(key, 0x40, ['note1_long', 'bits:4', 'var_long', 'u8']) if eu_sh or us_jp or sh or non_sh: - print(".ifdef VERSION_SH\n") + print("#ifdef VERSION_SH\n") for (op, cmd) in eu_sh: emit_cmd(key, op, cmd) for (op, cmd) in sh: emit_cmd(key, op, cmd) - print(".else\n") + print("#else\n") for (op, cmd) in non_sh: emit_cmd(key, op, cmd) - print(".ifdef VERSION_EU\n") + print("#ifdef VERSION_EU\n") for (op, cmd) in eu_sh: emit_cmd(key, op, cmd) - print(".else\n") + print("#else\n") for (op, cmd) in us_jp: emit_cmd(key, op, cmd) - print(".endif\n") - print(".endif\n") + print("#endif\n") + print("#endif\n") - print("# envelope commands\n") + print("// envelope commands\n") emit_env_cmd(0, ['disable', 'u16']) emit_env_cmd(2**16-1, ['hang', 'u16:ign']) emit_env_cmd(2**16-2, ['goto', 'u16']) emit_env_cmd(2**16-3, ['restart', 'u16:ign']) emit_env_cmd(None, ['line', 'u16', 'u16']) - print("# other commands\n") + print("// other commands\n") print(".macro var_long x") print(" .byte (0x80 | (\\x & 0x7f00) >> 8), (\\x & 0xff)") print(".endm\n")