commit f9982e0ef5891d2b3e4381c305c80f7d86166e85
parent ecd3d152fb7c6f658d18543c0f4e8147b50d5dde
Author: n64 <n64>
Date: Mon, 12 Jul 2021 23:17:27 -0400
Refresh 14
Diffstat:
255 files changed, 8292 insertions(+), 6554 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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/anim_0800401C.inc.c
@@ -1,54 +0,0 @@
-// 0x08003E30
-static const s16 amp_seg8_animvalue_08003E30[] = {
- 0x0000, 0x0000, 0x0D79, 0x1AF2, 0x286B, 0x35E4, 0x435D, 0x50D6,
- 0x5E50, 0x6BC9, 0x7942, 0x86BE, 0x9437, 0xA1B0, 0xAF2A, 0xBCA3,
- 0xCA1C, 0xD795, 0xE50E, 0xF287, 0x1872, 0x0000, 0x1AF2, 0x35E4,
- 0x50D6, 0x6BC9, 0x86BE, 0xA1B0, 0xBCA3, 0xD795, 0xF287, 0x0D79,
- 0x286B, 0x435D, 0x5E50, 0x7942, 0x9437, 0xAF2A, 0xCA1C, 0xE50E,
- 0x0000, 0x1AF2, 0x35E4, 0x50D6, 0x6BC9, 0x86BE, 0xA1B0, 0xBCA3,
- 0xD795, 0xF287, 0x0D79, 0x286B, 0x435D, 0x5E50, 0x7942, 0x9437,
- 0xAF2A, 0xCA1C, 0xE50E, 0x8001, 0x5793, 0x2F28, 0x06BC, 0xDE52,
- 0xB5E6, 0x8D7B, 0x650C, 0x3CA1, 0x1435, 0xEBCB, 0xC35F, 0x9AF4,
- 0x7285, 0x4A1A, 0x21AE, 0xF944, 0xD0D8, 0xA86D, 0x3FFF, 0x0000,
- 0x0D7C, 0x1AF9, 0x2876, 0x35F3, 0x4370, 0x50ED, 0x5E6A, 0x6BE7,
- 0x7964, 0x86E3, 0x9460, 0xA1DD, 0xAF5A, 0xBCD7, 0xCA54, 0xD7D1,
- 0xE54E, 0xF2CB, 0xC001, 0x3FFF, 0x0000, 0x0D7B, 0x1AF7, 0x2873,
- 0x35EF, 0x436B, 0x50E6, 0x5E62, 0x6BDE, 0x795A, 0x86D9, 0x9455,
- 0xA1D0, 0xAF4C, 0xBCC8, 0xCA44, 0xD7C0, 0xE53B, 0xF2B7, 0xC001,
- 0x3FFF, 0xC001, 0xCD7A, 0xDAF2, 0xE86B, 0xF5E3, 0x035B, 0x10D3,
- 0x1E4C, 0x2BC4, 0x393D, 0x46B5, 0x542E, 0x61A6, 0x6F1F, 0x7C97,
- 0x8A13, 0x978B, 0xA504, 0xB27D, 0xC001, 0x3FFF, 0x4D79, 0x5AF2,
- 0x686C, 0x75E5, 0x8362, 0x90DB, 0x9E55, 0xABCF, 0xB948, 0xC6C2,
- 0xD43B, 0xE1B5, 0xEF2F, 0xFCA8, 0x0A21, 0x179A, 0x2514, 0x328D,
- 0xC001, 0x3FFF,
-};
-
-// 0x08003F74
-static const u16 amp_seg8_animindex_08003F74[] = {
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x00A1,
- 0x0001, 0x0000, 0x0013, 0x008D, 0x0001, 0x00A0,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x0001,
- 0x0001, 0x0000, 0x0013, 0x0079, 0x0001, 0x008C,
- 0x0001, 0x0014, 0x0001, 0x0000, 0x0013, 0x0015,
- 0x0001, 0x0000, 0x0013, 0x0064, 0x0001, 0x0077,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x0028,
- 0x0001, 0x0000, 0x0013, 0x004F, 0x0001, 0x0062,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x003B,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0078,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0063,
- 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x004E,
-};
-
-// 0x0800401C
-static const struct Animation amp_seg8_anim_0800401C = {
- 0,
- 0,
- 0,
- 0,
- 0x13,
- ANIMINDEX_NUMPARTS(amp_seg8_animindex_08003F74),
- amp_seg8_animvalue_08003E30,
- amp_seg8_animindex_08003F74,
- 0,
-};
diff --git a/actors/amp/anims/animation.inc.c b/actors/amp/anims/animation.inc.c
@@ -0,0 +1,51 @@
+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,
+ 0x50D6, 0x6BC9, 0x86BE, 0xA1B0, 0xBCA3, 0xD795, 0xF287, 0x0D79,
+ 0x286B, 0x435D, 0x5E50, 0x7942, 0x9437, 0xAF2A, 0xCA1C, 0xE50E,
+ 0x0000, 0x1AF2, 0x35E4, 0x50D6, 0x6BC9, 0x86BE, 0xA1B0, 0xBCA3,
+ 0xD795, 0xF287, 0x0D79, 0x286B, 0x435D, 0x5E50, 0x7942, 0x9437,
+ 0xAF2A, 0xCA1C, 0xE50E, 0x8001, 0x5793, 0x2F28, 0x06BC, 0xDE52,
+ 0xB5E6, 0x8D7B, 0x650C, 0x3CA1, 0x1435, 0xEBCB, 0xC35F, 0x9AF4,
+ 0x7285, 0x4A1A, 0x21AE, 0xF944, 0xD0D8, 0xA86D, 0x3FFF, 0x0000,
+ 0x0D7C, 0x1AF9, 0x2876, 0x35F3, 0x4370, 0x50ED, 0x5E6A, 0x6BE7,
+ 0x7964, 0x86E3, 0x9460, 0xA1DD, 0xAF5A, 0xBCD7, 0xCA54, 0xD7D1,
+ 0xE54E, 0xF2CB, 0xC001, 0x3FFF, 0x0000, 0x0D7B, 0x1AF7, 0x2873,
+ 0x35EF, 0x436B, 0x50E6, 0x5E62, 0x6BDE, 0x795A, 0x86D9, 0x9455,
+ 0xA1D0, 0xAF4C, 0xBCC8, 0xCA44, 0xD7C0, 0xE53B, 0xF2B7, 0xC001,
+ 0x3FFF, 0xC001, 0xCD7A, 0xDAF2, 0xE86B, 0xF5E3, 0x035B, 0x10D3,
+ 0x1E4C, 0x2BC4, 0x393D, 0x46B5, 0x542E, 0x61A6, 0x6F1F, 0x7C97,
+ 0x8A13, 0x978B, 0xA504, 0xB27D, 0xC001, 0x3FFF, 0x4D79, 0x5AF2,
+ 0x686C, 0x75E5, 0x8362, 0x90DB, 0x9E55, 0xABCF, 0xB948, 0xC6C2,
+ 0xD43B, 0xE1B5, 0xEF2F, 0xFCA8, 0x0A21, 0x179A, 0x2514, 0x328D,
+ 0xC001, 0x3FFF,
+};
+
+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,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x0001,
+ 0x0001, 0x0000, 0x0013, 0x0079, 0x0001, 0x008C,
+ 0x0001, 0x0014, 0x0001, 0x0000, 0x0013, 0x0015,
+ 0x0001, 0x0000, 0x0013, 0x0064, 0x0001, 0x0077,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x0028,
+ 0x0001, 0x0000, 0x0013, 0x004F, 0x0001, 0x0062,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0013, 0x003B,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0078,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0063,
+ 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x004E,
+};
+
+static const struct Animation dAmpAnimation = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x13,
+ ANIMINDEX_NUMPARTS(dAmpAnimIndex),
+ dAmpAnimValue,
+ dAmpAnimIndex,
+ 0,
+};
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+#ifdef VERSION_EU
+ .ascii "P" /* PAL (Europe) */
+#elif defined(VERSION_US)
.ascii "E" /* NTSC-U (North America) */
-.elseif (VERSION_JP == 1 || VERSION_SH == 1)
+#else
.ascii "J" /* NTSC-J (Japan) */
-.else
- .ascii "P" /* PAL (Europe) */
-.endif
+#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) \
{ \
@@ -727,6 +751,28 @@ typedef short ENVMIX_STATE[40];
}
/*
+ * 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.
*
* Before this command, call:
@@ -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
@@ -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,8 +39,10 @@ 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
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_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_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_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -6,6 +6,7 @@
#include <ultra64.h>
#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+#ifdef VERSION_EU
+ BUILD_DIR/libultra.a:alBnkfNew.o(.text);
#endif
- BUILD_DIR/libultra.a:osAiGetLength.o(.text)
- BUILD_DIR/libultra.a:osAiSetNextBuffer.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)
+ 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)
+ 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:__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:__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*);
+#endif
BUILD_DIR/src/audio/heap.o(.data*);
-#ifndef VERSION_SH
BUILD_DIR/src/audio/load.o(.data*);
-#endif
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
@@ -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
+sequence_start:
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,4 +1,6 @@
+#ifndef VERSION_SH
#include <ultra64.h>
+#include <PR/os.h>
#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,13 +743,11 @@ 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
@@ -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
@@ -0,0 +1,1640 @@
+#ifdef VERSION_SH
+#include <ultra64.h>
+#include <PR/os.h>
+
+#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
@@ -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
@@ -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
@@ -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/port_sh.c b/src/audio/port_sh.c
@@ -0,0 +1,567 @@
+#ifdef VERSION_SH
+// TODO: merge this with port_eu.c?
+
+#include <ultra64.h>
+
+#include "data.h"
+#include "heap.h"
+#include "load.h"
+#include "synthesis.h"
+#include "internal.h"
+#include "seqplayer.h"
+
+#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80
+#define SAMPLES_TO_OVERPRODUCE 0x10
+
+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_8031D690(s32 playerIndex, s32 numFrames);
+void seq_player_fade_to_zero_volume(s32 arg0, s32 numFrames);
+void func_802ad7ec(u32 arg0);
+
+struct SPTask *create_next_audio_frame_task(void) {
+ u32 samplesRemainingInAI;
+ s32 writtenCmds;
+ s32 index;
+ OSTask_t *task;
+ s32 flags;
+ s16 *currAiBuffer;
+ s32 oldDmaCount;
+ s32 sp38;
+ s32 sp34;
+ s32 writtenCmdsCopy;
+
+ gAudioFrameCount++;
+ if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
+ if ((gAudioFrameCount % gAudioBufferParameters.presetUnk4) + 1 == gAudioBufferParameters.presetUnk4) {
+ return D_SH_80314FCC;
+ }
+ return NULL;
+ }
+ osSendMesg(D_SH_80350F38, (OSMesg) gAudioFrameCount, OS_MESG_NOBLOCK);
+
+ gAudioTaskIndex ^= 1;
+ gCurrAiBufferIndex++;
+ gCurrAiBufferIndex %= NUMAIBUFFERS;
+ index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
+ samplesRemainingInAI = osAiGetLength() / 4;
+
+ if (gAudioLoadLockSH < 0x10U) {
+ if (gAiBufferLengths[index] != 0) {
+ osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
+ }
+ }
+
+ oldDmaCount = gCurrAudioFrameDmaCount;
+ if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
+ }
+ gCurrAudioFrameDmaCount = 0;
+
+ decrease_sample_dma_ttls();
+ func_sh_802f41e4(gAudioResetStatus);
+ if (osRecvMesg(D_SH_80350F88, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) {
+ if (gAudioResetStatus == 0) {
+ gAudioResetStatus = 5;
+ }
+ gAudioResetPresetIdToLoad = (u8) sp38;
+ }
+
+ if (gAudioResetStatus != 0) {
+ if (audio_shut_down_and_reset_step() == 0) {
+ if (gAudioResetStatus == 0) {
+ osSendMesg(D_SH_80350FA8, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
+ }
+ D_SH_80314FCC = 0;
+ return NULL;
+ }
+ }
+ if (gAudioLoadLockSH >= 0x11U) {
+ return NULL;
+ }
+ if (gAudioLoadLockSH != 0) {
+ gAudioLoadLockSH++;
+ }
+
+ gAudioTask = &gAudioTasks[gAudioTaskIndex];
+ gAudioCmd = (u64 *) gAudioCmdBuffers[gAudioTaskIndex];
+ index = gCurrAiBufferIndex;
+ currAiBuffer = gAiBuffers[index];
+
+ gAiBufferLengths[index] = (s16) ((((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI) +
+ EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE);
+ if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
+ gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
+ }
+ if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
+ gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
+ }
+
+ if (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1) {
+ do {
+ func_802ad7ec(sp34);
+ } while (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1);
+ }
+
+ flags = 0;
+ gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
+ gAudioRandom = (u32) (osGetCount() * (gAudioRandom + gAudioFrameCount));
+ gAudioRandom = (u32) (gAiBuffers[index][gAudioFrameCount & 0xFF] + gAudioRandom);
+
+ index = gAudioTaskIndex;
+ gAudioTask->msgqueue = NULL;
+ gAudioTask->msg = NULL;
+
+ task = &gAudioTask->task.t;
+ task->type = M_AUDTASK;
+ task->flags = flags;
+ task->ucode_boot = rspF3DBootStart;
+ task->ucode_boot_size = (u8 *) rspF3DStart - (u8 *) rspF3DBootStart;
+ task->ucode = rspAspMainStart;
+ task->ucode_data = rspAspMainDataStart;
+ task->ucode_size = 0x1000;
+ task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
+ task->dram_stack = NULL;
+ task->dram_stack_size = 0;
+ task->output_buff = NULL;
+ task->output_buff_size = NULL;
+ task->data_ptr = gAudioCmdBuffers[index];
+ task->data_size = writtenCmds * sizeof(u64);
+ task->yield_data_ptr = NULL;
+ task->yield_data_size = 0;
+
+ writtenCmdsCopy = writtenCmds;
+ if (D_SH_80314FC8 < writtenCmdsCopy) {
+ D_SH_80314FC8 = writtenCmdsCopy;
+ }
+
+ if (gAudioBufferParameters.presetUnk4 == 1) {
+ return gAudioTask;
+ } else {
+ D_SH_80314FCC = gAudioTask;
+ return NULL;
+ }
+}
+
+void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
+ s32 i;
+ struct Note *note;
+ struct NoteSubEu *sub;
+
+ switch (cmd->u.s.op) {
+ case 0x81:
+ preload_sequence(cmd->u.s.arg2, 3);
+ break;
+
+ case 0x82:
+ case 0x88:
+ load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
+ func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
+ break;
+
+ case 0x83:
+ if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
+ if (cmd->u2.as_s32 == 0) {
+ sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
+ }
+ else {
+ seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32);
+ }
+ }
+ break;
+
+ case 0x84:
+ break;
+
+ case 0xf0:
+ gSoundMode = cmd->u2.as_s32;
+ break;
+
+ case 0xf1:
+ for (i = 0; i < 4; i++) {
+ gSequencePlayers[i].muted = TRUE;
+ gSequencePlayers[i].recalculateVolume = TRUE;
+ }
+ break;
+
+ case 0xf2:
+ if (cmd->u2.as_s32 == 1) {
+ for (i = 0; i < gMaxSimultaneousNotes; i++) {
+ note = &gNotes[i];
+ sub = ¬e->noteSubEu;
+ if (note->noteSubEu.enabled && note->unkSH34 == 0) {
+ if ((note->parentLayer->seqChannel->muteBehavior & 8) != 0) {
+ sub->finished = TRUE;
+ }
+ }
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ gSequencePlayers[i].muted = FALSE;
+ gSequencePlayers[i].recalculateVolume = TRUE;
+ }
+ break;
+
+ case 0xf3:
+ func_sh_802f3024(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
+ break;
+
+ case 0xf4:
+ func_sh_802f30f4(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
+ break;
+
+ case 0xf5:
+ func_sh_802f3158(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
+ break;
+
+ case 0xf6:
+ func_sh_802f3288(cmd->u.s.arg2);
+ break;
+ }
+}
+
+void seq_player_fade_to_zero_volume(s32 arg0, s32 fadeOutTime) {
+ struct SequencePlayer *player;
+
+ if (fadeOutTime == 0) {
+ fadeOutTime = 1;
+ }
+ player = &gSequencePlayers[arg0];
+ player->state = 2;
+ player->fadeRemainingFrames = fadeOutTime;
+ player->fadeVelocity = -(player->fadeVolume / (f32) fadeOutTime);
+}
+
+void func_8031D690(s32 playerIndex, s32 fadeInTime) {
+ struct SequencePlayer *player;
+
+ if (fadeInTime != 0) {
+ player = &gSequencePlayers[playerIndex];
+ player->state = 1;
+ player->fadeTimerUnkEu = fadeInTime;
+ player->fadeRemainingFrames = fadeInTime;
+ player->fadeVolume = 0.0f;
+ player->fadeVelocity = 0.0f;
+ }
+}
+
+void port_eu_init_queues(void) {
+ D_SH_80350F18 = 0;
+ D_SH_80350F19 = 0;
+ D_SH_80350F38 = &D_SH_80350F20;
+ D_SH_80350F68 = &D_SH_80350F50;
+ D_SH_80350F88 = &D_SH_80350F70;
+ D_SH_80350FA8 = &D_SH_80350F90;
+ osCreateMesgQueue(D_SH_80350F38, D_SH_80350F1C, 1);
+ osCreateMesgQueue(D_SH_80350F68, D_SH_80350F40, 4);
+ osCreateMesgQueue(D_SH_80350F88, D_SH_80350F6C, 1);
+ osCreateMesgQueue(D_SH_80350FA8, D_SH_80350F8C, 1);
+}
+
+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;
+ D_SH_80350F18++;
+ if (D_SH_80350F18 == D_SH_80350F19) {
+ D_SH_80350F18--;
+ }
+}
+
+void func_802ad728(u32 arg0, f32 arg1) {
+ func_802ad6f0(arg0, (s32 *) &arg1);
+}
+
+void func_802ad74c(u32 arg0, u32 arg1) {
+ func_802ad6f0(arg0, (s32 *) &arg1);
+}
+
+void func_802ad770(u32 arg0, s8 arg1) {
+ s32 sp1C = arg1 << 24;
+ func_802ad6f0(arg0, &sp1C);
+}
+
+char shindouDebugPrint133[] = "AudioSend: %d -> %d (%d)\n";
+
+void func_sh_802F64C8(void) {
+ static s32 D_SH_8031503C = 0;
+ s32 mesg;
+
+ if (((D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff) > D_SH_8031503C) {
+ D_SH_8031503C = (D_SH_80350F18 - D_SH_80350F19 + 0x100) & 0xff;
+ }
+ 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;
+}
+
+void func_sh_802f6540(void) {
+ D_SH_80350F19 = D_SH_80350F18;
+}
+
+void func_802ad7ec(u32 arg0) {
+ struct EuAudioCmd *cmd;
+ struct SequencePlayer *seqPlayer;
+ struct SequenceChannel *chan;
+ u8 end;
+
+ 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;
+
+ if (D_SH_8031509C == 0) {
+ D_SH_80315098 = (arg0 >> 8) & 0xff;
+ }
+
+ end = arg0 & 0xff;
+
+ for (;;) {
+ if (D_SH_80315098 == end) {
+ D_SH_8031509C = 0;
+ break;
+ }
+ cmd = &sAudioCmd[D_SH_80315098 & 0xff];
+ D_SH_80315098++;
+ if (cmd->u.s.op == 0xf8) {
+ D_SH_8031509C = 1;
+ break;
+ }
+ else if ((cmd->u.s.op & 0xf0) == 0xf0) {
+ 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) {
+ eu_process_audio_cmd(cmd);
+ }
+ else if ((cmd->u.s.op & 0x40) != 0) {
+ switch (cmd->u.s.op) {
+ case 0x41:
+ if (seqPlayer->fadeVolumeScale != cmd->u2.as_f32) {
+ seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
+ seqPlayer->recalculateVolume = TRUE;
+ }
+ break;
+
+ case 0x47:
+ seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
+ break;
+
+ case 0x49:
+ seqPlayer->tempoAdd = cmd->u2.as_s32 * TEMPO_SCALE;
+ break;
+
+ case 0x48:
+ seqPlayer->transposition = cmd->u2.as_s8;
+ break;
+
+ case 0x46:
+ seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
+ break;
+ }
+ }
+ else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
+ chan = seqPlayer->channels[cmd->u.s.arg2];
+ if (IS_SEQUENCE_CHANNEL_VALID(chan))
+ {
+ switch (cmd->u.s.op) {
+ case 1:
+ if (chan->volumeScale != cmd->u2.as_f32) {
+ chan->volumeScale = cmd->u2.as_f32;
+ chan->changes.as_bitfields.volume = TRUE;
+ }
+ break;
+ case 2:
+ if (chan->volume != cmd->u2.as_f32) {
+ chan->volume = cmd->u2.as_f32;
+ chan->changes.as_bitfields.volume = TRUE;
+ }
+ break;
+ case 3:
+ if (chan->newPan != cmd->u2.as_s8) {
+ chan->newPan = cmd->u2.as_s8;
+ chan->changes.as_bitfields.pan = TRUE;
+ }
+ break;
+ case 4:
+ if (chan->freqScale != cmd->u2.as_f32) {
+ chan->freqScale = cmd->u2.as_f32;
+ chan->changes.as_bitfields.freqScale = TRUE;
+ }
+ break;
+ case 5:
+ //! @bug u8 s8 comparison (but harmless)
+ if (chan->reverbVol != cmd->u2.as_s8) {
+ chan->reverbVol = cmd->u2.as_s8;
+ }
+ break;
+ case 6:
+ if (cmd->u.s.arg3 < 8) {
+ chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
+ }
+ break;
+ case 8:
+ chan->stopSomething2 = cmd->u2.as_s8;
+ break;
+ case 9:
+ chan->muteBehavior = cmd->u2.as_s8;
+ }
+ }
+ }
+ }
+
+ cmd->u.s.op = 0;
+ }
+}
+
+u32 func_sh_802f6878(s32 *arg0) {
+ u32 sp1C;
+
+ if (osRecvMesg(&gUnkQueue1, (OSMesg *) &sp1C, 0) == -1) {
+ *arg0 = 0;
+ return 0U;
+ }
+ *arg0 = (s32) (sp1C & 0xFFFFFF);
+ return sp1C >> 0x18;
+}
+
+u8 *func_sh_802f68e0(u32 index, u32 *a1) {
+ return func_sh_802f3220(index, a1);
+}
+
+s32 func_sh_802f6900(void) {
+ s32 ret;
+ s32 sp18;
+
+ ret = osRecvMesg(D_SH_80350FA8, (OSMesg *) &sp18, 0);
+
+ if (ret == -1) {
+ return 0;
+ }
+ if (sp18 != gAudioResetPresetIdToLoad) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+// TODO: (Scrub C)
+void func_sh_802f6958(OSMesg mesg) {
+ s32 a;
+ OSMesg recvMesg;
+
+ do {
+ a = -1;
+ } while (osRecvMesg(D_SH_80350FA8, &recvMesg, OS_MESG_NOBLOCK) != a);
+ func_sh_802f6540();
+ osSendMesg(D_SH_80350F88, mesg, OS_MESG_NOBLOCK);
+}
+
+void func_sh_802f69cc(void) {
+ gAudioLoadLockSH = 1;
+ func_sh_802f6958(0);
+ gAudioResetStatus = 0;
+}
+
+s32 func_sh_802f6a08(s32 playerIndex, s32 channelIndex, s32 soundScriptIOIndex) {
+ struct SequenceChannel *seqChannel;
+ struct SequencePlayer *player;
+
+ player = &gSequencePlayers[playerIndex];
+ if (player->enabled) {
+ seqChannel = player->channels[channelIndex];
+ if (IS_SEQUENCE_CHANNEL_VALID(seqChannel)) {
+ return seqChannel->soundScriptIO[soundScriptIOIndex];
+ }
+ }
+ return -1;
+}
+
+s8 func_sh_802f6a6c(s32 playerIndex, s32 index) {
+ return gSequencePlayers[playerIndex].seqVariationEu[index];
+}
+
+void port_eu_init(void) {
+ port_eu_init_queues();
+}
+
+char shindouDebugPrint138[] = "specchg conjunction error (Msg:%d Cur:%d)\n";
+char shindouDebugPrint139[] = "Error : Queue is not empty ( %x ) \n";
+char shindouDebugPrint140[] = "Audio: setvol: volume minus %f\n";
+char shindouDebugPrint141[] = "Audio: setvol: volume overflow %f\n";
+char shindouDebugPrint142[] = "Audio: setpitch: pitch zero or minus %f\n";
+char shindouDebugPrint143[] = "----------------------Double-Error CH: %x %f\n";
+char shindouDebugPrint144[] = "----------------------Double-Error NT: %x\n";
+char shindouDebugPrint145[] = "CAUTION:SUB IS SEPARATED FROM GROUP\n";
+char shindouDebugPrint146[] = "CAUTION:PAUSE EMERGENCY\n";
+char shindouDebugPrint147[] = "Error:Wait Track disappear\n";
+char shindouDebugPrint148[] = "Audio: voiceman: No bank error %d\n";
+char shindouDebugPrint149[] = "Audio: voiceman: progNo. overflow %d,%d\n";
+char shindouDebugPrint150[] = "ptr2 %x\n";
+char shindouDebugPrint151[] = "Audio: voiceman: progNo. undefined %d,%d\n";
+char shindouDebugPrint152[] = "Audio: voiceman: No bank error %d\n";
+char shindouDebugPrint153[] = "Audio: voiceman: Percussion Overflow %d,%d\n";
+char shindouDebugPrint154[] = "Audio: voiceman: Percussion table pointer (bank %d) is irregular %x.\n";
+char shindouDebugPrint155[] = "Audio: voiceman: Percpointer NULL %d,%d\n";
+char shindouDebugPrint156[] = "--4 %x\n";
+char shindouDebugPrint157[] = "NoteOff Comes during wait release %x (note %x)\n";
+char shindouDebugPrint158[] = "Slow Release Batting\n";
+u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 };
+char shindouDebugPrint159[] = "Audio:Wavemem: Bad voiceno (%d)\n";
+char shindouDebugPrint160[] = "Audio: C-Alloc : Dealloc voice is NULL\n";
+char shindouDebugPrint161[] = "Alloc Error:Dim voice-Alloc %d";
+char shindouDebugPrint162[] = "Error:Same List Add\n";
+char shindouDebugPrint163[] = "Already Cut\n";
+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; // file boundary
+
+// effects.c
+char shindouDebugPrint168[] = "Audio:Envp: overflow %f\n";
+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";
+char shindouDebugPrint172[] = "SEQID %d,BANKID %d\n";
+char shindouDebugPrint173[] = "ERR:SUBTRACK %d NOT ALLOCATED\n";
+char shindouDebugPrint174[] = "Stop Release\n";
+char shindouDebugPrint175[] = "Error:Same List Add\n";
+char shindouDebugPrint176[] = "Wait Time out!\n";
+char shindouDebugPrint177[] = "Macro Level Over Error!\n";
+char shindouDebugPrint178[] = "Macro Level Over Error!\n"; // Again
+char shindouDebugPrint179[] = "WARNING: NPRG: cannot change %d\n";
+char shindouDebugPrint180[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n";
+char shindouDebugPrint181[] = "Error: Subtrack no prg.\n";
+char shindouDebugPrint182[] = "ERR %x\n";
+char shindouDebugPrint183[] = "Note OverFlow %d\n";
+char shindouDebugPrint184[] = "trs %d , %d, %d\n";
+char shindouDebugPrint185[] = "Audio: Note:Velocity Error %d\n";
+char shindouDebugPrint186[] = "Audio:Track :Call Macro Level Over Error!\n";
+char shindouDebugPrint187[] = "Audio:Track :Loops Macro Level Over Error!\n";
+char shindouDebugPrint188[] = "SUB:ERR:BANK %d NOT CACHED.\n";
+char shindouDebugPrint189[] = "SUB:ERR:BANK %d NOT CACHED.\n";
+char shindouDebugPrint190[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n";
+char shindouDebugPrint191[] = "Set Noise %d\n";
+char shindouDebugPrint192[] = "[%2x] \n";
+char shindouDebugPrint193[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x";
+char shindouDebugPrint194[] = "VoiceLoad Error Bank:%d,Prog:%d\n";
+char shindouDebugPrint195[] = "Disappear Sequence or Bank %d\n";
+char shindouDebugPrint196[] = "[FIN] group.\n";
+char shindouDebugPrint197[] = "Macro Level Over Error!\n";
+char shindouDebugPrint198[] = "Macro Level Over Error!\n";
+char shindouDebugPrint199[] = "Group:Undefine upper C0h command (%x)\n";
+char shindouDebugPrint200[] = "Group:Undefined Command\n";
+
+#endif
diff --git 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
@@ -1,7 +1,14 @@
#include <ultra64.h>
#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
@@ -1,3 +1,4 @@
+#ifndef VERSION_SH
#include <ultra64.h>
#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) {
+#ifdef VERSION_EU
+ if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) {
leftRight = 1;
- } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) {
+ } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) {
leftRight = 2;
#else
- if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) {
+ if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) {
leftRight = 1;
- } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) {
+ } 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
@@ -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
@@ -0,0 +1,910 @@
+#ifdef VERSION_SH
+#include <ultra64.h>
+
+#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/audio/unk_shindou_audio_file.c b/src/audio/unk_shindou_audio_file.c
@@ -1,564 +0,0 @@
-#ifdef VERSION_SH
-
-#include <ultra64.h>
-
-#include "data.h"
-#include "heap.h"
-#include "load.h"
-#include "synthesis.h"
-#include "internal.h"
-
-#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80
-#define SAMPLES_TO_OVERPRODUCE 0x10
-
-extern s32 D_SH_80314FC8;
-extern struct SPTask *D_SH_80314FCC;
-extern u8 D_SH_80315098;
-extern u8 D_SH_8031509C;
-
-void func_sh_802f62e0(s32 playerIndex, s32 numFrames);
-void func_sh_802f6288(s32 arg0, s32 numFrames);
-void func_sh_802f6554(u32 arg0);
-
-struct SPTask *func_sh_802f5a80(void) {
- u32 samplesRemainingInAI;
- s32 writtenCmds;
- s32 index;
- OSTask_t *task;
- s32 flags;
- s16 *currAiBuffer;
- s32 oldDmaCount;
- s32 sp38;
- s32 sp34;
- s32 writtenCmdsCopy;
-
- gAudioFrameCount++;
- if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
- if ((gAudioFrameCount % gAudioBufferParameters.presetUnk4) + 1 == gAudioBufferParameters.presetUnk4) {
- return D_SH_80314FCC;
- }
- return NULL;
- }
- osSendMesg(D_SH_80350F38, (OSMesg) gAudioFrameCount, OS_MESG_NOBLOCK);
-
- gAudioTaskIndex ^= 1;
- gCurrAiBufferIndex++;
- gCurrAiBufferIndex %= NUMAIBUFFERS;
- index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
- samplesRemainingInAI = osAiGetLength() / 4;
-
- if (gAudioLoadLockSH < 0x10U) {
- if (gAiBufferLengths[index] != 0) {
- osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
- }
- }
-
- oldDmaCount = gCurrAudioFrameDmaCount;
- if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
- }
- gCurrAudioFrameDmaCount = 0;
-
- decrease_sample_dma_ttls();
- func_802f41e4(gAudioResetStatus);
- if (osRecvMesg(D_SH_80350F88, (OSMesg *) &sp38, OS_MESG_NOBLOCK) != -1) {
- if (gAudioResetStatus == 0) {
- gAudioResetStatus = 5;
- }
- gAudioResetPresetIdToLoad = (u8) sp38;
- }
-
- if (gAudioResetStatus != 0) {
- if (audio_shut_down_and_reset_step() == 0) {
- if (gAudioResetStatus == 0) {
- osSendMesg(D_SH_80350FA8, (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
- }
- D_SH_80314FCC = 0;
- return NULL;
- }
- }
- if (gAudioLoadLockSH >= 0x11U) {
- return NULL;
- }
- if (gAudioLoadLockSH != 0) {
- gAudioLoadLockSH++;
- }
-
- gAudioTask = &gAudioTasks[gAudioTaskIndex];
- gAudioCmd = (u64 *) gAudioCmdBuffers[gAudioTaskIndex];
- index = gCurrAiBufferIndex;
- currAiBuffer = gAiBuffers[index];
-
- gAiBufferLengths[index] = (s16) ((((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI) +
- EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE);
- if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
- gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
- }
- if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
- gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
- }
-
- if (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1) {
- do {
- func_sh_802f6554(sp34);
- } while (osRecvMesg(D_SH_80350F68, (OSMesg *) &sp34, 0) != -1);
- }
-
- flags = 0;
- gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
- gAudioRandom = (u32) (osGetCount() * (gAudioRandom + gAudioFrameCount));
- gAudioRandom = (u32) (gAiBuffers[index][gAudioFrameCount & 0xFF] + gAudioRandom);
-
- index = gAudioTaskIndex;
- gAudioTask->msgqueue = NULL;
- gAudioTask->msg = NULL;
-
- task = &gAudioTask->task.t;
- task->type = M_AUDTASK;
- task->flags = flags;
- task->ucode_boot = rspF3DBootStart;
- task->ucode_boot_size = (u8 *) rspF3DStart - (u8 *) rspF3DBootStart;
- task->ucode = rspAspMainStart;
- task->ucode_data = rspAspMainDataStart;
- task->ucode_size = 0x1000;
- task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
- task->dram_stack = NULL;
- task->dram_stack_size = 0;
- task->output_buff = NULL;
- task->output_buff_size = NULL;
- task->data_ptr = gAudioCmdBuffers[index];
- task->data_size = writtenCmds * sizeof(u64);
- task->yield_data_ptr = NULL;
- task->yield_data_size = 0;
-
- writtenCmdsCopy = writtenCmds;
- if (D_SH_80314FC8 < writtenCmdsCopy) {
- D_SH_80314FC8 = writtenCmdsCopy;
- }
-
- if (gAudioBufferParameters.presetUnk4 == 1) {
- return gAudioTask;
- } else {
- D_SH_80314FCC = gAudioTask;
- return NULL;
- }
-}
-
-void func_sh_802f5fb8(struct EuAudioCmd *cmd) {
- s32 i;
- struct Note *note;
- struct NoteSubEu *sub;
-
- switch (cmd->u.s.op) {
- case 0x81:
- preload_sequence(cmd->u.s.arg2, 3);
- break;
-
- 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);
- break;
-
- case 0x83:
- if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
- if (cmd->u2.as_s32 == 0) {
- sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
- }
- else {
- func_sh_802f6288(cmd->u.s.arg1, cmd->u2.as_s32);
- }
- }
- break;
-
- case 0x84:
- break;
-
- case 0xf0:
- gSoundMode = cmd->u2.as_s32;
- break;
-
- case 0xf1:
- for (i = 0; i < 4; i++) {
- gSequencePlayers[i].muted = TRUE;
- gSequencePlayers[i].recalculateVolume = TRUE;
- }
- break;
-
- case 0xf2:
- if (cmd->u2.as_s32 == 1) {
- for (i = 0; i < gMaxSimultaneousNotes; i++) {
- note = &gNotes[i];
- sub = ¬e->noteSubEu;
- if (note->noteSubEu.enabled && note->unkSH34 == 0) {
- if ((note->parentLayer->seqChannel->muteBehavior & 8) != 0) {
- sub->finished = TRUE;
- }
- }
- }
- }
- for (i = 0; i < 4; i++) {
- gSequencePlayers[i].muted = FALSE;
- gSequencePlayers[i].recalculateVolume = TRUE;
- }
- break;
-
- case 0xf3:
- func_sh_802f3024(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
- break;
-
- case 0xf4:
- func_sh_802f30f4(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
- break;
-
- case 0xf5:
- func_sh_802f3158(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3, &gUnkQueue1);
- break;
-
- case 0xf6:
- func_sh_802f3288(cmd->u.s.arg2);
- break;
- }
-}
-
-void func_sh_802f6288(s32 arg0, s32 numFrames) {
- struct SequencePlayer *player;
-
- if (numFrames == 0) {
- numFrames = 1;
- }
- player = &gSequencePlayers[arg0];
- player->state = 2;
- player->fadeRemainingFrames = numFrames;
- player->fadeVelocity = -(player->fadeVolume / (f32) numFrames);
-}
-
-void func_sh_802f62e0(s32 playerIndex, s32 numFrames) {
- struct SequencePlayer *player;
-
- if (numFrames != 0) {
- player = &gSequencePlayers[playerIndex];
- player->state = 1;
- player->fadeTimerUnkEu = numFrames;
- player->fadeRemainingFrames = numFrames;
- player->fadeVolume = 0.0f;
- player->fadeVelocity = 0.0f;
- }
-}
-
-void func_sh_802f6330(void) {
- D_SH_80350F18 = 0;
- D_SH_80350F19 = 0;
- D_SH_80350F38 = &D_SH_80350F20;
- D_SH_80350F68 = &D_SH_80350F50;
- D_SH_80350F88 = &D_SH_80350F70;
- D_SH_80350FA8 = &D_SH_80350F90;
- osCreateMesgQueue(D_SH_80350F38, D_SH_80350F1C, 1);
- osCreateMesgQueue(D_SH_80350F68, D_SH_80350F40, 4);
- osCreateMesgQueue(D_SH_80350F88, D_SH_80350F6C, 1);
- 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
- struct EuAudioCmd *cmd = &sAudioCmd[D_SH_80350F18 & 0xff];
- cmd->u.first = arg0;
- cmd->u2.as_u32 = *arg1;
- D_SH_80350F18++;
- if (D_SH_80350F18 == D_SH_80350F19) {
- D_SH_80350F18--;
- }
-}
-
-void func_802ad728(u32 arg0, f32 arg1) { // func_sh_802f6450
- func_802ad6f0(arg0, (s32 *) &arg1);
-}
-
-void func_802ad74c(u32 arg0, u32 arg1) { // func_sh_802f6474
- func_802ad6f0(arg0, (s32 *) &arg1);
-}
-
-void func_802ad770(u32 arg0, s8 arg1) { // func_sh_802f6498
- 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;
-
- if (D_SH_8031503C < a0) {
- D_SH_8031503C = a0;
- }
- a0 = ((D_SH_80350F19 & 0xff) << 8) | (D_SH_80350F18 & 0xFF);
- a1 = a0;
- a0 = D_SH_80350F68;
- osSendMesg(a0, a1, 0);
- D_SH_80350F19 = D_SH_80350F18;
-}
-
-void func_sh_802f6540(void) {
- D_SH_80350F19 = D_SH_80350F18;
-}
-
-void func_sh_802f6554(u32 arg0) {
- struct EuAudioCmd *cmd;
- struct SequencePlayer *seqPlayer;
- struct SequenceChannel *chan;
- u8 a0;
-
- 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";
-
- static u8 D_SH_80315098 = 0;
- static u8 D_SH_8031509C = 0;
-
- if (D_SH_8031509C == 0) {
- D_SH_80315098 = (arg0 >> 8) & 0xff;
- }
-
- a0 = arg0 & 0xff;
-
- for (;;) {
- if (D_SH_80315098 == a0) {
- D_SH_8031509C = 0;
- break;
- }
- cmd = &sAudioCmd[D_SH_80315098 & 0xff];
- D_SH_80315098++;
- if (cmd->u.s.op == 0xf8) {
- D_SH_8031509C = 1;
- break;
- }
- else if ((cmd->u.s.op & 0xf0) == 0xf0) {
- func_sh_802f5fb8(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);
- }
- else if ((cmd->u.s.op & 0x40) != 0) {
- switch (cmd->u.s.op) {
- case 0x41:
- if (seqPlayer->fadeVolumeScale != cmd->u2.as_f32) {
- seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
- seqPlayer->recalculateVolume = TRUE;
- }
- break;
-
- case 0x47:
- seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
- break;
-
- case 0x49:
- seqPlayer->tempoAdd = cmd->u2.as_s32 * TEMPO_SCALE;
- break;
-
- case 0x48:
- seqPlayer->transposition = cmd->u2.as_s8;
- break;
-
- case 0x46:
- seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
- break;
- }
- }
- else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
- chan = seqPlayer->channels[cmd->u.s.arg2];
- if (IS_SEQUENCE_CHANNEL_VALID(chan))
- {
- switch (cmd->u.s.op) {
- case 1:
- if (chan->volumeScale != cmd->u2.as_f32) {
- chan->volumeScale = cmd->u2.as_f32;
- chan->changes.as_bitfields.volume = TRUE;
- }
- break;
- case 2:
- if (chan->volume != cmd->u2.as_f32) {
- chan->volume = cmd->u2.as_f32;
- chan->changes.as_bitfields.volume = TRUE;
- }
- break;
- case 3:
- if (chan->newPan != cmd->u2.as_s8) {
- chan->newPan = cmd->u2.as_s8;
- chan->changes.as_bitfields.pan = TRUE;
- }
- break;
- case 4:
- if (chan->freqScale != cmd->u2.as_f32) {
- chan->freqScale = cmd->u2.as_f32;
- chan->changes.as_bitfields.freqScale = TRUE;
- }
- break;
- case 5:
- if (chan->reverb != cmd->u2.as_s8) {
- chan->reverb = cmd->u2.as_s8;
- }
- break;
- case 6:
- if (cmd->u.s.arg3 < 8) {
- chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
- }
- break;
- case 8:
- chan->stopSomething2 = cmd->u2.as_s8;
- break;
- case 9:
- chan->muteBehavior = cmd->u2.as_s8;
- }
- }
- }
- }
-
- cmd->u.s.op = 0;
- }
-}
-
-u32 func_sh_802f6878(s32 *arg0) {
- u32 sp1C;
-
- if (osRecvMesg(&gUnkQueue1, (OSMesg *) &sp1C, 0) == -1) {
- *arg0 = 0;
- return 0U;
- }
- *arg0 = (s32) (sp1C & 0xFFFFFF);
- return sp1C >> 0x18;
-}
-
-u8 *func_sh_802f68e0(u32 index, u32 *a1) {
- return func_sh_802f3220(index, a1);
-}
-
-s32 func_sh_802f6900(void) {
- s32 ret;
- s32 sp18;
-
- ret = osRecvMesg(D_SH_80350FA8, (OSMesg *) &sp18, 0);
-
- if (ret == -1) {
- return 0;
- }
- if (sp18 != gAudioResetPresetIdToLoad) {
- return 0;
- } else {
- return 1;
- }
-}
-
-// TODO: (Scrub C)
-void func_sh_802f6958(OSMesg mesg) {
- s32 a;
- OSMesg recvMesg;
-
- do {
- a = -1;
- } while (osRecvMesg(D_SH_80350FA8, &recvMesg, OS_MESG_NOBLOCK) != a);
- func_sh_802f6540();
- osSendMesg(D_SH_80350F88, mesg, OS_MESG_NOBLOCK);
-}
-
-void func_sh_802f69cc(void) {
- gAudioLoadLockSH = 1;
- func_sh_802f6958(0);
- gAudioResetStatus = 0;
-}
-
-s32 func_sh_802f6a08(s32 playerIndex, s32 channelIndex, s32 soundScriptIOIndex) {
- struct SequenceChannel *seqChannel;
- struct SequencePlayer *player;
-
- player = &gSequencePlayers[playerIndex];
- if (player->enabled) {
- seqChannel = player->channels[channelIndex];
- if (IS_SEQUENCE_CHANNEL_VALID(seqChannel)) {
- return seqChannel->soundScriptIO[soundScriptIOIndex];
- }
- }
- return -1;
-}
-
-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();
-}
-
-char shindouDebugPrint138[] = "specchg conjunction error (Msg:%d Cur:%d)\n";
-char shindouDebugPrint139[] = "Error : Queue is not empty ( %x ) \n";
-char shindouDebugPrint140[] = "Audio: setvol: volume minus %f\n";
-char shindouDebugPrint141[] = "Audio: setvol: volume overflow %f\n";
-char shindouDebugPrint142[] = "Audio: setpitch: pitch zero or minus %f\n";
-char shindouDebugPrint143[] = "----------------------Double-Error CH: %x %f\n";
-char shindouDebugPrint144[] = "----------------------Double-Error NT: %x\n";
-char shindouDebugPrint145[] = "CAUTION:SUB IS SEPARATED FROM GROUP\n";
-char shindouDebugPrint146[] = "CAUTION:PAUSE EMERGENCY\n";
-char shindouDebugPrint147[] = "Error:Wait Track disappear\n";
-char shindouDebugPrint148[] = "Audio: voiceman: No bank error %d\n";
-char shindouDebugPrint149[] = "Audio: voiceman: progNo. overflow %d,%d\n";
-char shindouDebugPrint150[] = "ptr2 %x\n";
-char shindouDebugPrint151[] = "Audio: voiceman: progNo. undefined %d,%d\n";
-char shindouDebugPrint152[] = "Audio: voiceman: No bank error %d\n";
-char shindouDebugPrint153[] = "Audio: voiceman: Percussion Overflow %d,%d\n";
-char shindouDebugPrint154[] = "Audio: voiceman: Percussion table pointer (bank %d) is irregular %x.\n";
-char shindouDebugPrint155[] = "Audio: voiceman: Percpointer NULL %d,%d\n";
-char shindouDebugPrint156[] = "--4 %x\n";
-char shindouDebugPrint157[] = "NoteOff Comes during wait release %x (note %x)\n";
-char shindouDebugPrint158[] = "Slow Release Batting\n";
-u8 euUnknownData_8030194c[4] = { 0x40, 0x20, 0x10, 0x08 };
-char shindouDebugPrint159[] = "Audio:Wavemem: Bad voiceno (%d)\n";
-char shindouDebugPrint160[] = "Audio: C-Alloc : Dealloc voice is NULL\n";
-char shindouDebugPrint161[] = "Alloc Error:Dim voice-Alloc %d";
-char shindouDebugPrint162[] = "Error:Same List Add\n";
-char shindouDebugPrint163[] = "Already Cut\n";
-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.
-char shindouDebugPrint168[] = "Audio:Envp: overflow %f\n";
-s32 D_SH_803154EC = 0; // Either an unused variable or a file boundary.
-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";
-char shindouDebugPrint172[] = "SEQID %d,BANKID %d\n";
-char shindouDebugPrint173[] = "ERR:SUBTRACK %d NOT ALLOCATED\n";
-char shindouDebugPrint174[] = "Stop Release\n";
-char shindouDebugPrint175[] = "Error:Same List Add\n";
-char shindouDebugPrint176[] = "Wait Time out!\n";
-char shindouDebugPrint177[] = "Macro Level Over Error!\n";
-char shindouDebugPrint178[] = "Macro Level Over Error!\n"; // Again
-char shindouDebugPrint179[] = "WARNING: NPRG: cannot change %d\n";
-char shindouDebugPrint180[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n";
-char shindouDebugPrint181[] = "Error: Subtrack no prg.\n";
-char shindouDebugPrint182[] = "ERR %x\n";
-char shindouDebugPrint183[] = "Note OverFlow %d\n";
-char shindouDebugPrint184[] = "trs %d , %d, %d\n";
-char shindouDebugPrint185[] = "Audio: Note:Velocity Error %d\n";
-char shindouDebugPrint186[] = "Audio:Track :Call Macro Level Over Error!\n";
-char shindouDebugPrint187[] = "Audio:Track :Loops Macro Level Over Error!\n";
-char shindouDebugPrint188[] = "SUB:ERR:BANK %d NOT CACHED.\n";
-char shindouDebugPrint189[] = "SUB:ERR:BANK %d NOT CACHED.\n";
-char shindouDebugPrint190[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n";
-char shindouDebugPrint191[] = "Set Noise %d\n";
-char shindouDebugPrint192[] = "[%2x] \n";
-char shindouDebugPrint193[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x";
-char shindouDebugPrint194[] = "VoiceLoad Error Bank:%d,Prog:%d\n";
-char shindouDebugPrint195[] = "Disappear Sequence or Bank %d\n";
-char shindouDebugPrint196[] = "[FIN] group.\n";
-char shindouDebugPrint197[] = "Macro Level Over Error!\n";
-char shindouDebugPrint198[] = "Macro Level Over Error!\n";
-char shindouDebugPrint199[] = "Group:Undefine upper C0h command (%x)\n";
-char shindouDebugPrint200[] = "Group:Undefined Command\n";
-
-#endif
diff --git a/src/buffers/buffers.c b/src/buffers/buffers.c
@@ -1,6 +1,7 @@
#include <ultra64.h>
#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,114 +1,177 @@
-// bowser.c.inc
+/**
+ * Behavior for Bowser and it's actions (Tail, Flame, Body)
+ */
+
+// Bowser's Tail
-void bowser_tail_anchor_act_0(void) {
+/**
+ * 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;
+ }
+ if (cur_obj_check_if_near_animation_end()) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
}
+/**
+ * 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(13);
- if (cur_obj_check_if_near_animation_end())
- return 1;
- else
- return 0;
+ cur_obj_init_animation_with_sound(BOWSER_ANIM_SLOW_GAIT);
+ if (cur_obj_check_if_near_animation_end()) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
}
-s32 bowser_set_anim_look_down(void) {
- cur_obj_init_animation_with_sound(14);
- if (cur_obj_check_anim_frame(20))
+/**
+ * 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 1;
- else
- return 0;
+ }
+ if (cur_obj_check_if_near_animation_end()) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
}
-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;
+
+/**
+ * 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;
+ }
}
-void bowser_act_text_wait(void) // not much
-{
+/**
+ * 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(12);
- bowser_initialize_action();
+ 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())
+ if (bowser_set_anim_look_up_and_walk()) {
o->oSubAction++;
+ }
+ // Then slowly walk
} else if (o->oSubAction == 1) {
- if (bowser_set_anim_slow_gait())
+ 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();
+ }
+ // 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();
}
}
-static void bowser_debug_actions(void) // unused
-{
+/**
+ * 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++;
+ // 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 {
+ // Keep walking
+ o->oAction = BOWSER_ACT_WALK_TO_MARIO;
+ }
+ o->oBowserIsReacting++;
} else {
- o->oBowserUnk110 = 0;
+ o->oBowserIsReacting = FALSE;
+ // Set starting Bowser level actions, randomly he can also start
+ // dancing after the introduction
#ifndef VERSION_JP
- if (!gCurrDemoInput) {
- if (rand < 0.1)
- o->oAction = 3; // rare 1/10 chance
- else
- o->oAction = 14; // common
+ 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 = 14; // ensure demo starts with action 14.
+ 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;
-}
-
-void bowser_set_act_jump(void) {
- o->oAction = 13;
-}
-
-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;
+ 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;
+ }
+}
+
+/**
+ * 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;
+}
+
+/**
+ * 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) {
+ // Keep walking slowly
if (bowser_set_anim_slow_gait()) {
- o->oBowserUnkF8++;
- if (o->oBowserUnkF4 & 0x20000) {
- if (o->oBowserUnkF8 > 4)
- o->oBowserUnkF4 &= ~0x20000;
- } else if (angleFromMario < 0x2000)
+ 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++;
+ }
}
- } else if (bowser_set_anim_look_down())
- o->oAction = 0;
+ // 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;
+ o->oSubAction = BOWSER_SUB_ACT_TELEPORT_STOP;
+ o->oMoveAngleYaw = o->oAngleToMario; // update angle
}
- if (abs_angle_diff(o->oMoveAngleYaw, o->oAngleToMario) > 0x4000)
+ //
+ 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);
+ }
+ }
+ // Return to default act once the animation is over
+ if (cur_obj_check_if_near_animation_end()) {
+ o->oAction = BOWSER_ACT_DEFAULT;
}
- if (cur_obj_check_if_near_animation_end())
- o->oAction = 0;
- o->oBowserUnkF4 |= 0x20000;
+ // 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;
+ 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 1:
+ case BOWSER_SUB_ACT_CHARGE_RUN:
+ // Set speed to run
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;
+ 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) {
+ }
+ // 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, dialogID, 0)) {
- cur_obj_set_model(MODEL_BOWSER2);
+ // 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;
-}
-
-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 } };
+ return FALSE;
+}
+
+/**
+ * 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;
-}
-
-#undef BITDW
-#undef BITFS
-#undef BITS
-
-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);
+ o->oAction = BOWSER_ACT_WAIT;
+ // Set eyes status
+ o->oBowserEyesTimer = 0;
+ o->oBowserEyesShut = FALSE;
+}
+
+Gfx *geo_update_body_rot_from_parent(s32 callContext, UNUSED struct GraphNode *node, Mat4 mtx) {
+ Mat4 mtx2;
+ struct Object *obj;
+
+ 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;
-
- 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);
- }
- 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;
+/**
+ * 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 (callContext == GEO_CONTEXT_RENDER) {
+ obj = (struct Object *) gCurGraphNodeObject;
+ graphNode = (struct GraphNodeGenerated *) node;
+ if (gCurGraphNodeHeldObject != 0) {
+ obj = gCurGraphNodeHeldObject->objNode;
}
- } else {
- cur_obj_become_tangible();
- if (o->oTimer > o->oFlameScale * 10 + 5.0f) {
- o->oFlameScale -= 0.15;
- if (o->oFlameScale <= 0)
- bowser_flame_despawn();
+ // 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);
}
- }
- 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);
+ gfx = gfxHead = alloc_display_list(2 * sizeof(Gfx));
+ // If TRUE, clear lighting to give rainbow color
+ if (obj->oBowserRainbowLight != 0) {
+ gSPClearGeometryMode(gfx++, G_LIGHTING);
}
- obj_mark_for_deletion(o);
+ gSPEndDisplayList(gfx);
}
-}
-
-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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,6 +1,7 @@
#include <ultra64.h>
#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
@@ -21,51 +21,71 @@
#include "rumble_init.h"
#include <prevent_bss_reordering.h>
-// 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) {
}
}
+// Game thread core
+// ----------------------------------------------------------------------------------------------------
+
+/**
+ * Setup main segments and framebuffers.
+ */
void setup_game_memory(void) {
- UNUSED u8 pad[8];
+ 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 ((u32)index < table->count) {
+ u8 *addr = table->srcAddr + table->anim[index].offset;
+ s32 size = table->anim[index].size;
- 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 (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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,76 +2656,87 @@ 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:
- //! 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 >= 0x0100) {
- gTimeStopState |= TIME_STOP_ENABLED;
- o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP;
- o->oDialogState++;
- o->oDialogResponse = 0;
- }
- break;
-#else
- 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 = 0;
+ 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.
+ if (gMarioState->health >= 0x0100) {
+ gTimeStopState |= TIME_STOP_ENABLED;
+ o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP;
+ o->oDialogState++;
+ o->oDialogResponse = DIALOG_RESPONSE_NONE;
+ }
+ break;
#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,7 +1,11 @@
#ifndef RUMBLE_INIT_H
#define RUMBLE_INIT_H
-#ifdef VERSION_SH
+#include <PR/ultratypes.h>
+
+#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.c b/src/menu/level_select_menu.c
@@ -1,217 +0,0 @@
-#include <PR/ultratypes.h>
-
-#include "audio/external.h"
-#include "engine/math_util.h"
-#include "game/area.h"
-#include "game/game_init.h"
-#include "game/level_update.h"
-#include "game/main.h"
-#include "game/memory.h"
-#include "game/print.h"
-#include "game/save_file.h"
-#include "game/sound_init.h"
-#include "game/rumble_init.h"
-#include "level_table.h"
-#include "seq_ids.h"
-#include "sm64.h"
-
-#define PRESS_START_DEMO_TIMER 800
-
-#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] = {
- #include "levels/level_defines.h"
-};
-#undef STUB_LEVEL
-#undef DEFINE_LEVEL
-
-static u16 gDemoCountdown = 0;
-#ifndef VERSION_JP
-static s16 D_U_801A7C34 = 1;
-static s16 gameOverNotPlayed = 1;
-#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.
-
-// 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) {
- gCurrDemoInput = NULL;
-
- if (timer == 0) {
- 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 Mario demo animation for the demo list.
- load_patchable_table(&gDemo, gDemoInputListID);
-
- // if the next demo sequence ID is the count limit, reset it back to
- // the first sequence.
- if (++gDemoInputListID == gDemo.animDmaTable->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;
- gCurrSaveFileNum = 1;
- gCurrActNum = 1;
- }
- } else { // activity was detected, so reset the demo countdown.
- gDemoCountdown = 0;
- }
- }
- return timer;
-}
-
-// 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) {
- s32 stageChanged = FALSE;
-
- // perform the ID updates per each button press.
- if (gPlayer1Controller->buttonPressed & A_BUTTON) {
- ++gCurrLevelNum, stageChanged = TRUE;
- }
- if (gPlayer1Controller->buttonPressed & B_BUTTON) {
- --gCurrLevelNum, stageChanged = TRUE;
- }
- if (gPlayer1Controller->buttonPressed & U_JPAD) {
- --gCurrLevelNum, stageChanged = TRUE;
- }
- if (gPlayer1Controller->buttonPressed & D_JPAD) {
- ++gCurrLevelNum, stageChanged = TRUE;
- }
- if (gPlayer1Controller->buttonPressed & L_JPAD) {
- gCurrLevelNum -= 10, stageChanged = TRUE;
- }
- if (gPlayer1Controller->buttonPressed & R_JPAD) {
- gCurrLevelNum += 10, stageChanged = TRUE;
- }
-
- // if the stage was changed, play the sound for changing a stage.
- if (stageChanged) {
- 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.
- }
-
- if (gCurrLevelNum < LEVEL_MIN) {
- gCurrLevelNum = LEVEL_MAX; // exceeded min. set to max.
- }
-
- gCurrSaveFileNum = 4; // file 4 is used for level select tests
- 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
-
-#define QUIT_LEVEL_SELECT_COMBO (Z_TRIG | START_BUTTON | L_CBUTTONS | R_CBUTTONS)
-
- // start being pressed signals the stage to be started. that is, unless...
- if (gPlayer1Controller->buttonPressed & START_BUTTON) {
- // ... the level select quit combo is being pressed, which uses START. If this
- // is the case, quit the menu instead.
- if (gPlayer1Controller->buttonDown == QUIT_LEVEL_SELECT_COMBO) {
- gDebugLevelSelect = FALSE;
- return -1;
- }
- play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
- return gCurrLevelNum;
- }
- return 0;
-}
-
-s32 intro_default(void) {
- s32 sp1C = 0;
-
-#ifndef VERSION_JP
- if (D_U_801A7C34 == 1) {
- if (gGlobalTimer < 0x81) {
- play_sound(SOUND_MARIO_HELLO, gGlobalSoundSource);
- } else {
- play_sound(SOUND_MARIO_PRESS_START_TO_PLAY, gGlobalSoundSource);
- }
- D_U_801A7C34 = 0;
- }
-#endif
- print_intro_text();
-
- if (gPlayer1Controller->buttonPressed & START_BUTTON) {
- play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
-#ifdef VERSION_SH
- queue_rumble_data(60, 70);
- func_sh_8024C89C(1);
-#endif
- sp1C = 100 + gDebugLevelSelect;
-#ifndef VERSION_JP
- D_U_801A7C34 = 1;
-#endif
- }
- return run_press_start_demo_timer(sp1C);
-}
-
-s32 intro_game_over(void) {
- s32 sp1C = 0;
-
-#ifndef VERSION_JP
- if (gameOverNotPlayed == 1) {
- play_sound(SOUND_MARIO_GAME_OVER, gGlobalSoundSource);
- gameOverNotPlayed = 0;
- }
-#endif
-
- print_intro_text();
-
- if (gPlayer1Controller->buttonPressed & START_BUTTON) {
- play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
-#ifdef VERSION_SH
- queue_rumble_data(60, 70);
- func_sh_8024C89C(1);
-#endif
- sp1C = 100 + gDebugLevelSelect;
-#ifndef VERSION_JP
- gameOverNotPlayed = 1;
-#endif
- }
- return run_press_start_demo_timer(sp1C);
-}
-
-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) {
- s32 retVar;
-
- switch (arg1) {
- case 0:
- retVar = intro_play_its_a_me_mario();
- break;
- case 1:
- retVar = intro_default();
- break;
- case 2:
- retVar = intro_game_over();
- break;
- case 3:
- retVar = level_select_input_loop();
- break;
- }
- return retVar;
-}
diff --git a/src/menu/level_select_menu.h b/src/menu/level_select_menu.h
@@ -1,10 +0,0 @@
-#ifndef LEVEL_SELECT_MENU_H
-#define LEVEL_SELECT_MENU_H
-
-#include <PR/ultratypes.h>
-
-#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
@@ -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/title_screen.c b/src/menu/title_screen.c
@@ -0,0 +1,249 @@
+#include <PR/ultratypes.h>
+
+#include "audio/external.h"
+#include "engine/math_util.h"
+#include "game/area.h"
+#include "game/game_init.h"
+#include "game/level_update.h"
+#include "game/main.h"
+#include "game/memory.h"
+#include "game/print.h"
+#include "game/save_file.h"
+#include "game/sound_init.h"
+#include "game/rumble_init.h"
+#include "level_table.h"
+#include "seq_ids.h"
+#include "sm64.h"
+#include "title_screen.h"
+
+/**
+ * @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 sLevelSelectStageNames[64][16] = {
+ #include "levels/level_defines.h"
+};
+#undef STUB_LEVEL
+#undef DEFINE_LEVEL
+
+static u16 sDemoCountdown = 0;
+#ifndef VERSION_JP
+static s16 sPlayMarioGreeting = TRUE;
+static s16 sPlayMarioGameOver = TRUE;
+#endif
+
+#define PRESS_START_DEMO_TIMER 800
+
+/**
+ * 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 (level == LEVEL_NONE) {
+ if (!gPlayer1Controller->buttonDown && !gPlayer1Controller->stickMag) {
+ // 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(&gDemoInputsBuf, gDemoInputListID);
+
+ // if the next demo sequence ID is the count limit, reset it back to
+ // the first sequence.
+ if (++gDemoInputListID == gDemoInputsBuf.dmaTable->count) {
+ gDemoInputListID = 0;
+ }
+
+ // 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.
+ sDemoCountdown = 0;
+ }
+ }
+ return level;
+}
+
+/**
+ * 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;
+ }
+ if (gPlayer1Controller->buttonPressed & B_BUTTON) {
+ --gCurrLevelNum, stageChanged = TRUE;
+ }
+ if (gPlayer1Controller->buttonPressed & U_JPAD) {
+ --gCurrLevelNum, stageChanged = TRUE;
+ }
+ if (gPlayer1Controller->buttonPressed & D_JPAD) {
+ ++gCurrLevelNum, stageChanged = TRUE;
+ }
+ if (gPlayer1Controller->buttonPressed & L_JPAD) {
+ gCurrLevelNum -= 10, stageChanged = TRUE;
+ }
+ if (gPlayer1Controller->buttonPressed & R_JPAD) {
+ gCurrLevelNum += 10, stageChanged = TRUE;
+ }
+
+ // if the stage was changed, play the sound for changing a stage.
+ if (stageChanged) {
+ play_sound(SOUND_GENERAL_LEVEL_SELECT_CHANGE, gGlobalSoundSource);
+ }
+
+ if (gCurrLevelNum > LEVEL_MAX) {
+ gCurrLevelNum = LEVEL_MIN; // exceeded max. set to min.
+ }
+
+ if (gCurrLevelNum < LEVEL_MIN) {
+ gCurrLevelNum = LEVEL_MAX; // exceeded min. set to max.
+ }
+
+ // 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, sLevelSelectStageNames[gCurrLevelNum - 1]); // print stage name
+
+#define QUIT_LEVEL_SELECT_COMBO (Z_TRIG | START_BUTTON | L_CBUTTONS | R_CBUTTONS)
+
+ // start being pressed signals the stage to be started. that is, unless...
+ if (gPlayer1Controller->buttonPressed & START_BUTTON) {
+ // ... the level select quit combo is being pressed, which uses START. If this
+ // is the case, quit the menu instead.
+ if (gPlayer1Controller->buttonDown == QUIT_LEVEL_SELECT_COMBO) {
+ gDebugLevelSelect = FALSE;
+ return -1;
+ }
+ play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
+ return gCurrLevelNum;
+ }
+ return 0;
+}
+
+/**
+ * Regular intro function that handles Mario's greeting voice and game start.
+ */
+s32 intro_regular(void) {
+ s32 level = LEVEL_NONE;
+
+#ifndef VERSION_JP
+ // 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);
+ }
+ sPlayMarioGreeting = FALSE;
+ }
+#endif
+ print_intro_text();
+
+ if (gPlayer1Controller->buttonPressed & START_BUTTON) {
+ play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
+#if ENABLE_RUMBLE
+ queue_rumble_data(60, 70);
+ func_sh_8024C89C(1);
+#endif
+ // 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
+ sPlayMarioGreeting = TRUE;
+#endif
+ }
+ 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 level = LEVEL_NONE;
+
+#ifndef VERSION_JP
+ if (sPlayMarioGameOver == TRUE) {
+ play_sound(SOUND_MARIO_GAME_OVER, gGlobalSoundSource);
+ sPlayMarioGameOver = FALSE;
+ }
+#endif
+
+ print_intro_text();
+
+ if (gPlayer1Controller->buttonPressed & START_BUTTON) {
+ play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
+#if ENABLE_RUMBLE
+ queue_rumble_data(60, 70);
+ func_sh_8024C89C(1);
+#endif
+ // same criteria as intro_regular
+ level = 100 + gDebugLevelSelect;
+#ifndef VERSION_JP
+ sPlayMarioGameOver = TRUE;
+#endif
+ }
+ 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;
+}
+
+/**
+ * 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 (arg) {
+ case LVL_INTRO_PLAY_ITS_A_ME_MARIO:
+ retVar = intro_play_its_a_me_mario();
+ break;
+ case LVL_INTRO_REGULAR:
+ retVar = intro_regular();
+ break;
+ case LVL_INTRO_GAME_OVER:
+ retVar = intro_game_over();
+ break;
+ 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
@@ -0,0 +1,17 @@
+#ifndef TITLE_SCREEN_H
+#define TITLE_SCREEN_H
+
+#include <PR/ultratypes.h>
+
+#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
@@ -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
@@ -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
@@ -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 <unistd.h>
#include <math.h>
#include <string.h>
diff --git 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
@@ -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 <stddef.h>")
print("")
diff --git 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
@@ -4,6 +4,7 @@
#include <string.h>
#include <inttypes.h>
+#include <algorithm>
#include <map>
#include <set>
#include <vector>
@@ -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));
- }
- 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;
+ 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<size_t>(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;
+ }
+ 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
@@ -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 <stddef.h>")
print("")
diff --git a/tools/output_level_headers.py b/tools/output_level_headers.py
@@ -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_elf_32bit.c b/tools/patch_elf_32bit.c
@@ -0,0 +1,161 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+
+/* from elf.h */
+
+/* Type for a 16-bit quantity. */
+typedef uint16_t Elf32_Half;
+
+/* Types for signed and unsigned 32-bit quantities. */
+typedef uint32_t Elf32_Word;
+
+/* Type of addresses. */
+typedef uint32_t Elf32_Addr;
+
+/* Type of file offsets. */
+typedef uint32_t Elf32_Off;
+
+/* The ELF file header. This appears at the start of every ELF file. */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf32_Half e_type; /* Object file type */
+ Elf32_Half e_machine; /* Architecture */
+ Elf32_Word e_version; /* Object file version */
+ Elf32_Addr e_entry; /* Entry point virtual address */
+ Elf32_Off e_phoff; /* Program header table file offset */
+ Elf32_Off e_shoff; /* Section header table file offset */
+ Elf32_Word e_flags; /* Processor-specific flags */
+ Elf32_Half e_ehsize; /* ELF header size in bytes */
+ Elf32_Half e_phentsize; /* Program header table entry size */
+ Elf32_Half e_phnum; /* Program header table entry count */
+ Elf32_Half e_shentsize; /* Section header table entry size */
+ Elf32_Half e_shnum; /* Section header table entry count */
+ Elf32_Half e_shstrndx; /* Section header string table index */
+} Elf32_Ehdr;
+
+/* Conglomeration of the identification bytes, for easy testing as a word. */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASS32 1 /* 32-bit objects */
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+
+/* end from elf.h */
+
+// This file will find all mips3 object files in an ar archive and set the ABI flags to O32
+// this allows gcc to link them with the mips2 object files.
+// Irix CC doesn't set the elf e_flags properly.
+
+// the AR file is structured as followed
+//"!<arch>" followed by 0x0A (linefeed) 8 characters
+// then a file header that follows the following structure
+// everything is represented using space padded characters
+// the last two characters are alwos 0x60 0x0A
+// then come the file contents
+// you can find the location of the next header by adding file_size_in_bytes (after parsing)
+// all file headers start at an even offset so if the file size in bytes is odd you have to add 1
+// the first two "files" are special. One is a symbol table with a pointer to the header of the file
+// contaning the symbol the other is an extended list of filenames
+struct ar_header {
+ char identifier[16];
+ char file_modification_timestamp[12];
+ char owner_id[6];
+ char group_id[6];
+ char file_mode[8];
+ char file_size_in_bytes[10];
+ char ending[2];
+};
+
+//These constants found by inspecting output of objdump
+#define FLAGS_MIPS3 0x20
+#define FLAGS_O32ABI 0x100000
+
+int 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
+
+ while (1 == fread(¤t_header, sizeof(current_header), 1, f)) {
+ if (current_header.ending[0] != 0x60 && current_header.ending[1] != 0x0A) {
+ printf("Expected file header\n");
+ return -1;
+ }
+ size_t filesize = atoi(current_header.file_size_in_bytes);
+ if (fix_mips_elf(f, filesize)) {
+ return -1;
+ }
+ if (filesize % 2 == 1)
+ filesize++;
+ fseek(f, filesize - sizeof(Elf32_Ehdr), SEEK_CUR);
+ }
+ 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/patch_libultra_math.c b/tools/patch_libultra_math.c
@@ -1,126 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-/* from elf.h */
-
-/* Type for a 16-bit quantity. */
-typedef uint16_t Elf32_Half;
-
-/* Types for signed and unsigned 32-bit quantities. */
-typedef uint32_t Elf32_Word;
-
-/* Type of addresses. */
-typedef uint32_t Elf32_Addr;
-
-/* Type of file offsets. */
-typedef uint32_t Elf32_Off;
-
-/* The ELF file header. This appears at the start of every ELF file. */
-
-#define EI_NIDENT (16)
-
-typedef struct
-{
- unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
- Elf32_Half e_type; /* Object file type */
- Elf32_Half e_machine; /* Architecture */
- Elf32_Word e_version; /* Object file version */
- Elf32_Addr e_entry; /* Entry point virtual address */
- Elf32_Off e_phoff; /* Program header table file offset */
- Elf32_Off e_shoff; /* Section header table file offset */
- Elf32_Word e_flags; /* Processor-specific flags */
- Elf32_Half e_ehsize; /* ELF header size in bytes */
- Elf32_Half e_phentsize; /* Program header table entry size */
- Elf32_Half e_phnum; /* Program header table entry count */
- Elf32_Half e_shentsize; /* Section header table entry size */
- Elf32_Half e_shnum; /* Section header table entry count */
- Elf32_Half e_shstrndx; /* Section header string table index */
-} Elf32_Ehdr;
-
-/* Conglomeration of the identification bytes, for easy testing as a word. */
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define EI_CLASS 4 /* File class byte index */
-#define ELFCLASS32 1 /* 32-bit objects */
-
-#define EI_DATA 5 /* Data encoding byte index */
-#define ELFDATA2MSB 2 /* 2's complement, big endian */
-
-/* end from elf.h */
-
-// This file will find all mips3 object files in an ar archive and set the ABI flags to O32
-// this allows gcc to link them with the mips2 object files.
-// Irix CC doesn't set the elf e_flags properly.
-
-// the AR file is structured as followed
-//"!<arch>" followed by 0x0A (linefeed) 8 characters
-// then a file header that follows the following structure
-// everything is represented using space padded characters
-// the last two characters are alwos 0x60 0x0A
-// then come the file contents
-// you can find the location of the next header by adding file_size_in_bytes (after parsing)
-// all file headers start at an even offset so if the file size in bytes is odd you have to add 1
-// the first two "files" are special. One is a symbol table with a pointer to the header of the file
-// contaning the symbol the other is an extended list of filenames
-struct ar_header {
- char identifier[16];
- char file_modification_timestamp[12];
- char owner_id[6];
- char group_id[6];
- char file_mode[8];
- char file_size_in_bytes[10];
- char ending[2];
-};
-
-//These constants found by inspecting output of objdump
-#define FLAGS_MIPS3 0x20
-#define FLAGS_O32ABI 0x100000
-int main(int argc, char **argv) {
- FILE *f = fopen(argv[1], "r+");
-
- if (f == NULL) {
- printf("Failed to open file! %s\n", argv[1]);
- return -1;
- }
- struct ar_header current_header;
- fseek(f, 0x8, SEEK_SET); // skip header, this is safe enough given that we check to make sure the
- // file header is valid
-
- while (1 == fread(¤t_header, sizeof(current_header), 1, f)) {
- if (current_header.ending[0] != 0x60 && current_header.ending[1] != 0x0A) {
- printf("Expected file header\n");
- return -1;
- }
- size_t filesize = atoi(current_header.file_size_in_bytes);
- Elf32_Ehdr hdr;
- if (filesize < sizeof(hdr) || (1 != fread(&hdr, sizeof(hdr), 1, f))) {
- printf("Failed to read ELF header\n");
- return -1;
- }
-
- if (strncmp((const char *) hdr.e_ident, ELFMAG, SELFMAG) == 0) {
- // found an ELF file.
- if (hdr.e_ident[EI_CLASS] != ELFCLASS32 || hdr.e_ident[EI_DATA] != ELFDATA2MSB) {
- printf("Expected 32bit big endian object files\n");
- return -1;
- }
-
- if ((hdr.e_flags & 0xFF) == FLAGS_MIPS3 && (hdr.e_flags & FLAGS_O32ABI) == 0) {
- hdr.e_flags |= FLAGS_O32ABI;
- fseek(f, -sizeof(hdr), SEEK_CUR);
- if (1 != fwrite(&hdr, sizeof(hdr), 1, f)) {
- printf("Failed to write back ELF header after patching.\n");
- return -1;
- }
- }
- }
- if (filesize % 2 == 1)
- filesize++;
- fseek(f, filesize - sizeof(hdr), SEEK_CUR);
- }
- fclose(f);
- return 0;
-}
diff --git 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")